1#include "pico_sntp_client.h" 2#include "modules/pico_sntp_client.c" 3#include "check.h" 4#include "pico_socket.h" 5/* Mocking functions, variables, ... */ 6volatile pico_time pico_tick = 0ull; 7volatile pico_err_t pico_err = 0; 8 9Suite *pico_suite(void); 10void cb_synced(pico_err_t status); 11 12/* Used in pico_sntp_sync_start */ 13struct pico_socket *pico_socket_open(uint16_t net, uint16_t proto, void (*wakeup)(uint16_t ev, struct pico_socket *s)) 14{ 15 struct pico_socket *sock = PICO_ZALLOC(sizeof(struct pico_socket)); 16 (void) net; 17 (void) proto; 18 (void) wakeup; 19 fail_unless (sock != NULL); 20 return sock; 21} 22 23/* Used in pico_sntp_sync_start */ 24int pico_socket_bind(struct pico_socket *s, void *local_addr, uint16_t *port) 25{ 26 (void) s; 27 (void) local_addr; 28 (void) port; 29 return 0; 30} 31 32/* Used in pico_sntp_sync_start */ 33int pico_socket_close(struct pico_socket *s) 34{ 35 (void) s; 36 return 0; 37} 38 39/* Used in pico_sntp_send */ 40int8_t pico_socket_del(struct pico_socket *s) 41{ 42 (void) s; 43 return 0; 44} 45 46/* Used in dnsCallback */ 47int pico_string_to_ipv4(const char *ipstr, uint32_t *ip) 48{ 49 (void) ipstr; 50 (void) ip; 51 return 0; 52} 53 54/* Used in dnsCallback */ 55int pico_string_to_ipv6(const char *ipstr, uint8_t *ip) 56{ 57 (void) ipstr; 58 (void) ip; 59 return 0; 60} 61 62/* Used in pico_sntp_sync_start_ipv4 */ 63int pico_ipv4_to_string(char* ipbuf, const uint32_t ip) 64{ 65 (void) ipbuf; 66 (void) ip; 67 return 0; 68} 69 70/* Used in pico_sntp_sync_start_ipv6 */ 71int pico_ipv6_to_string(char* ipbuf, const uint8_t ip[PICO_SIZE_IP6]) 72{ 73 (void) ipbuf; 74 (void) ip; 75 return 0; 76} 77 78/* Used in pico_sntp_client_wakeup */ 79int pico_socket_recvfrom(struct pico_socket *s, void *buf, int len, void *orig, uint16_t *remote_port) 80{ 81 (void) s; 82 (void) buf; 83 (void) len; 84 (void) orig; 85 (void) remote_port; 86 return 0; 87} 88 89/* Used in pico_sntp_send */ 90int pico_socket_sendto(struct pico_socket *s, const void *buf, int len, void *dst, uint16_t remote_port) 91{ 92 (void) s; 93 (void) buf; 94 (void) len; 95 (void) dst; 96 (void) remote_port; 97 return 0; 98} 99 100/* Used in pico_sntp_sync_start_dns_ipv4, not tested */ 101int pico_dns_client_getaddr(const char *url, void (*callback)(char *ip, void *arg), void *arg) 102{ 103 (void) url; 104 (void) callback; 105 (void) arg; 106 return 0; 107} 108 109/* Used in pico_sntp_sync_start_dns_ipv6, not tested */ 110int pico_dns_client_getaddr6(const char *url, void (*callback)(char *, void *), void *arg) 111{ 112 (void) url; 113 (void) callback; 114 (void) arg; 115 return 0; 116} 117 118/* Used in pico_sntp_parse */ 119void cb_synced(pico_err_t status) 120{ 121 (void) status; 122 123} 124 125/* Used in pico_sntp_send */ 126static uint32_t timers_added = 0; 127uint32_t pico_timer_add(pico_time expire, void (*timer)(pico_time, void *), void *arg) 128{ 129 (void) expire; 130 (void) timer; 131 (void) arg; 132 return ++timers_added; 133} 134 135/* Used in pico_sntp_cleanup */ 136void pico_timer_cancel(uint32_t t) 137{ 138 IGNORE_PARAMETER(t); 139} 140 141START_TEST(tc_timestamp_convert) 142{ 143 struct pico_sntp_ts ts; 144 struct pico_timeval tv; 145 pico_time delay = 0ull; 146 int ret = 0; 147 148 /* Input is all zero */ 149 ts.sec = long_be(0ul); 150 ts.frac = long_be(0ul); 151 ret = timestamp_convert(&ts, &tv, delay); 152 ck_assert(ret == -1); 153 ck_assert(tv.tv_sec == 0); 154 ck_assert(tv.tv_msec == 0); 155 156 /* Minimum input*/ 157 ts.sec = long_be(SNTP_UNIX_OFFSET + 1390000000ul); 158 ts.frac = long_be(4310344ul); /* MIN value: 1msec */ 159 ret = timestamp_convert(&ts, &tv, delay); 160 ck_assert(ret == 0); 161 fail_unless(tv.tv_sec == 1390000000); 162 fail_unless(tv.tv_msec == 1); 163 164 /* Intermediate input */ 165 ts.sec = long_be(SNTP_UNIX_OFFSET + 1390000000ul); 166 ts.frac = long_be(3865470566ul); /* value: 899msec */ 167 ret = timestamp_convert(&ts, &tv, delay); 168 ck_assert(ret == 0); 169 fail_unless(tv.tv_sec == 1390000000); 170 fail_unless(tv.tv_msec == 900); 171 172 /* Maximum input */ 173 ts.sec = long_be(SNTP_UNIX_OFFSET + 1390000000ul); 174 ts.frac = long_be(4294967295ul); /* MAX value: 999msec */ 175 ret = timestamp_convert(&ts, &tv, delay); 176 ck_assert(ret == 0); 177 fail_unless(tv.tv_sec == 1390000001); 178 fail_unless(tv.tv_msec == 0); 179 180 /* Intermediate input with delay */ 181 ts.sec = long_be(SNTP_UNIX_OFFSET + 1390000000ul); 182 ts.frac = long_be(3865470566ul); /* value: 899msec */ 183 delay = 200ull; 184 ret = timestamp_convert(&ts, &tv, delay); 185 ck_assert(ret == 0); 186 fail_unless(tv.tv_sec == 1390000001); 187 fail_unless(tv.tv_msec == 100); 188} 189END_TEST 190START_TEST(tc_pico_sntp_cleanup) 191{ 192 struct sntp_server_ns_cookie *ck; 193 struct pico_socket *sock; 194 ck = PICO_ZALLOC(sizeof(struct sntp_server_ns_cookie)); 195 fail_unless (ck != NULL); 196 ck->hostname = PICO_ZALLOC(sizeof(char) * 5); 197 fail_unless (ck->hostname != NULL); 198 ck->stamp = 0ull; 199 ck->cb_synced = cb_synced; 200 201 sock = pico_socket_open(0, 0, &pico_sntp_client_wakeup); 202 ck->sock = sock; 203 sock->priv = ck; 204 205 206 pico_sntp_cleanup(ck, PICO_ERR_NOERR); 207} 208END_TEST 209START_TEST(tc_pico_sntp_parse) 210{ 211 /* TODO: test this: static void pico_sntp_parse(char *buf, struct sntp_server_ns_cookie *ck) */ 212 struct sntp_server_ns_cookie *ck; 213 struct pico_socket *sock; 214 struct pico_sntp_header header = { 215 0 216 }; 217 218 ck = PICO_ZALLOC(sizeof(struct sntp_server_ns_cookie)); 219 fail_unless (ck != NULL); 220 ck->hostname = PICO_ZALLOC(sizeof(char) * 5); 221 fail_unless (ck->hostname != NULL); 222 ck->stamp = 0ull; 223 ck->cb_synced = cb_synced; 224 225 sock = pico_socket_open(0, 0, &pico_sntp_client_wakeup); 226 ck->sock = sock; 227 sock->priv = ck; 228 229 header.mode = 4; /* server mode */ 230 header.vn = 4; /* sntp version 4 */ 231 header.stratum = 1; /* primary reference */ 232 header.trs_ts.sec = long_be(SNTP_UNIX_OFFSET + 1390000000ul); 233 header.trs_ts.frac = long_be(3865470566ul); /* value: 899msec */ 234 235 fail_if(pico_sntp_parse((char *) &header, NULL) == 0); 236 fail_if(pico_sntp_parse((char *) &header, ck) != 0); 237} 238END_TEST 239START_TEST(tc_pico_sntp_client_wakeup) 240{ 241 /* TODO: test this: static void pico_sntp_client_wakeup(uint16_t ev, struct pico_socket *s) */ 242 uint16_t event = PICO_SOCK_EV_ERR; 243 struct sntp_server_ns_cookie *ck; 244 struct pico_socket *sock; 245 ck = PICO_ZALLOC(sizeof(struct sntp_server_ns_cookie)); 246 fail_unless (ck != NULL); 247 ck->hostname = PICO_ZALLOC(sizeof(char) * 5); 248 fail_unless (ck->hostname != NULL); 249 ck->stamp = 0ull; 250 ck->cb_synced = cb_synced; 251 252 sock = pico_socket_open(0, 0, &pico_sntp_client_wakeup); 253 ck->sock = sock; 254 sock->priv = ck; 255 256 ck->cb_synced = cb_synced; 257 printf("Started wakeup unit test\n"); 258 259 pico_sntp_client_wakeup(event, sock); 260} 261END_TEST 262START_TEST(tc_sntp_receive_timeout) 263{ 264 struct sntp_server_ns_cookie *ck; 265 struct pico_socket *sock; 266 ck = PICO_ZALLOC(sizeof(struct sntp_server_ns_cookie)); 267 fail_unless (ck != NULL); 268 ck->hostname = PICO_ZALLOC(sizeof(char) * 5); 269 fail_unless (ck->hostname != NULL); 270 ck->stamp = 0ull; 271 ck->cb_synced = cb_synced; 272 273 sock = pico_socket_open(0, 0, &pico_sntp_client_wakeup); 274 ck->sock = sock; 275 sock->priv = ck; 276 sntp_receive_timeout(0ull, ck); 277 278} 279END_TEST 280START_TEST(tc_pico_sntp_send) 281{ 282 /* TODO: test this: static void pico_sntp_send(struct pico_socket *sock, union pico_address *dst) */ 283 struct pico_socket sock = { 284 0 285 }; 286 union pico_address dst; 287 struct sntp_server_ns_cookie ck = { 288 0 289 }; 290 sock.priv = &ck; 291 292 pico_sntp_send(&sock, &dst); 293} 294END_TEST 295START_TEST(tc_dnsCallback) 296{ 297 /* TODO: test this: static void dnsCallback(char *ip, void *arg) */ 298 char ip[] = "198.123.30.132"; 299 struct sntp_server_ns_cookie *ck; 300 ck = PICO_ZALLOC(sizeof(struct sntp_server_ns_cookie)); 301 302 dnsCallback(ip, ck); 303} 304END_TEST 305START_TEST(tc_pico_sntp_sync) 306{ 307 const char *sntp_server= "ntp.nasa.gov"; 308 309 fail_if(pico_sntp_sync(NULL, cb_synced) == 0); 310 fail_if(pico_err != PICO_ERR_EINVAL); 311 312 fail_if(pico_sntp_sync(sntp_server, NULL) == 0); 313 fail_if(pico_err != PICO_ERR_EINVAL); 314 315 fail_if(pico_sntp_sync(sntp_server, cb_synced) != 0); 316} 317END_TEST 318START_TEST(tc_pico_sntp_sync_ip) 319{ 320 union pico_address sntp_addr = { .ip4.addr = 0ul }; 321 322 fail_if(pico_sntp_sync_ip(NULL, cb_synced) == 0); 323 fail_if(pico_err != PICO_ERR_EINVAL); 324 325 fail_if(pico_sntp_sync_ip(&sntp_addr, NULL) == 0); 326 fail_if(pico_err != PICO_ERR_EINVAL); 327 328 fail_if(pico_sntp_sync_ip(&sntp_addr, cb_synced) != 0); 329} 330END_TEST 331START_TEST(tc_pico_sntp_sync_start) 332{ 333 struct sntp_server_ns_cookie ck = { 0 }; 334 union pico_address sntp_addr = { .ip4.addr= 0ul }; 335 336 fail_if(pico_sntp_sync_start(&ck, &sntp_addr) != 0); 337} 338END_TEST 339START_TEST(tc_pico_sntp_sync_start_dns_ipv4) 340{ 341 const char *sntp_server = "ntp.nasa.gov"; 342 343 fail_if(pico_sntp_sync_start_dns_ipv4(sntp_server, cb_synced) != 0); 344} 345END_TEST 346START_TEST(tc_pico_sntp_sync_start_dns_ipv6) 347{ 348 const char *sntp_server = "ntp.nasa.gov"; 349 350 fail_if(pico_sntp_sync_start_dns_ipv6(sntp_server, cb_synced) != 0); 351} 352END_TEST 353START_TEST(tc_pico_sntp_sync_start_ipv4) 354{ 355 union pico_address sntp_addr = { .ip4.addr = 0}; 356 357 fail_if(pico_sntp_sync_start_ipv4(&sntp_addr, cb_synced) != 0); 358} 359END_TEST 360START_TEST(tc_pico_sntp_sync_start_ipv6) 361{ 362 union pico_address sntp_addr = { .ip6.addr = { 0 } }; 363 364 fail_if(pico_sntp_sync_start_ipv6(&sntp_addr, cb_synced) != 0); 365} 366END_TEST 367 368Suite *pico_suite(void) 369{ 370 Suite *s = suite_create("PicoTCP"); 371 372 TCase *TCase_timestamp_convert = tcase_create("Unit test for pico_timeval"); 373 TCase *TCase_pico_sntp_cleanup = tcase_create("Unit test for pico_sntp_cleanup"); 374 TCase *TCase_pico_sntp_send = tcase_create("Unit test for pico_sntp_send"); 375 TCase *TCase_pico_sntp_parse = tcase_create("Unit test for pico_sntp_parse"); 376 TCase *TCase_pico_sntp_client_wakeup = tcase_create("Unit test for pico_sntp_client_wakeup"); 377 TCase *TCase_sntp_receive_timeout = tcase_create("Unit test for sntp_receive_timeout"); 378 TCase *TCase_dnsCallback = tcase_create("Unit test for dnsCallback"); 379 TCase *TCase_pico_sntp_sync = tcase_create("Unit test for pico_sntp_sync"); 380 TCase *TCase_pico_sntp_sync_ip = tcase_create("Unit test for pico_sntp_sync_ip"); 381 TCase *TCase_pico_sntp_sync_start = tcase_create("Unit test for pico_sntp_sync_start"); 382 TCase *TCase_pico_sntp_sync_start_dns_ipv4 = tcase_create("Unit test for pico_sntp_sync_start_dns_ipv4"); 383 TCase *TCase_pico_sntp_sync_start_dns_ipv6 = tcase_create("Unit test for pico_sntp_sync_start_dns_ipv6"); 384 TCase *TCase_pico_sntp_sync_start_ipv4 = tcase_create("Unit test for pico_sntp_sync_start_ipv4"); 385 TCase *TCase_pico_sntp_sync_start_ipv6 = tcase_create("Unit test for pico_sntp_sync_start_ipv6"); 386 387 388 tcase_add_test(TCase_timestamp_convert, tc_timestamp_convert); 389 suite_add_tcase(s, TCase_timestamp_convert); 390 tcase_add_test(TCase_pico_sntp_cleanup, tc_pico_sntp_cleanup); 391 suite_add_tcase(s, TCase_pico_sntp_cleanup); 392 tcase_add_test(TCase_pico_sntp_parse, tc_pico_sntp_parse); 393 suite_add_tcase(s, TCase_pico_sntp_parse); 394 tcase_add_test(TCase_pico_sntp_client_wakeup, tc_pico_sntp_client_wakeup); 395 suite_add_tcase(s, TCase_pico_sntp_client_wakeup); 396 tcase_add_test(TCase_sntp_receive_timeout, tc_sntp_receive_timeout); 397 suite_add_tcase(s, TCase_sntp_receive_timeout); 398 tcase_add_test(TCase_pico_sntp_send, tc_pico_sntp_send); 399 suite_add_tcase(s, TCase_pico_sntp_send); 400 tcase_add_test(TCase_dnsCallback, tc_dnsCallback); 401 suite_add_tcase(s, TCase_dnsCallback); 402 tcase_add_test(TCase_pico_sntp_sync, tc_pico_sntp_sync); 403 suite_add_tcase(s, TCase_pico_sntp_sync); 404 tcase_add_test(TCase_pico_sntp_sync_ip, tc_pico_sntp_sync_ip); 405 suite_add_tcase(s, TCase_pico_sntp_sync_ip); 406 tcase_add_test(TCase_pico_sntp_sync_start, tc_pico_sntp_sync_start); 407 suite_add_tcase(s, TCase_pico_sntp_sync_start); 408 tcase_add_test(TCase_pico_sntp_sync_start_dns_ipv4, tc_pico_sntp_sync_start_dns_ipv4); 409 suite_add_tcase(s, TCase_pico_sntp_sync_start_dns_ipv4); 410 tcase_add_test(TCase_pico_sntp_sync_start_dns_ipv6, tc_pico_sntp_sync_start_dns_ipv6); 411 suite_add_tcase(s, TCase_pico_sntp_sync_start_dns_ipv6); 412 tcase_add_test(TCase_pico_sntp_sync_start_ipv4, tc_pico_sntp_sync_start_ipv4); 413 suite_add_tcase(s, TCase_pico_sntp_sync_start_ipv4); 414 tcase_add_test(TCase_pico_sntp_sync_start_ipv6, tc_pico_sntp_sync_start_ipv6); 415 suite_add_tcase(s, TCase_pico_sntp_sync_start_ipv6); 416 return s; 417} 418 419int main(void) 420{ 421 int fails; 422 Suite *s = pico_suite(); 423 SRunner *sr = srunner_create(s); 424 srunner_run_all(sr, CK_NORMAL); 425 fails = srunner_ntests_failed(sr); 426 srunner_free(sr); 427 return fails; 428} 429