Files
my-os-project2/kernel/picotcp/test/unit/modunit_pico_sntp_client.c
2025-10-29 14:29:06 +01:00

429 lines
12 KiB
C

#include "pico_sntp_client.h"
#include "modules/pico_sntp_client.c"
#include "check.h"
#include "pico_socket.h"
/* Mocking functions, variables, ... */
volatile pico_time pico_tick = 0ull;
volatile pico_err_t pico_err = 0;
Suite *pico_suite(void);
void cb_synced(pico_err_t status);
/* Used in pico_sntp_sync_start */
struct pico_socket *pico_socket_open(uint16_t net, uint16_t proto, void (*wakeup)(uint16_t ev, struct pico_socket *s))
{
struct pico_socket *sock = PICO_ZALLOC(sizeof(struct pico_socket));
(void) net;
(void) proto;
(void) wakeup;
fail_unless (sock != NULL);
return sock;
}
/* Used in pico_sntp_sync_start */
int pico_socket_bind(struct pico_socket *s, void *local_addr, uint16_t *port)
{
(void) s;
(void) local_addr;
(void) port;
return 0;
}
/* Used in pico_sntp_sync_start */
int pico_socket_close(struct pico_socket *s)
{
(void) s;
return 0;
}
/* Used in pico_sntp_send */
int8_t pico_socket_del(struct pico_socket *s)
{
(void) s;
return 0;
}
/* Used in dnsCallback */
int pico_string_to_ipv4(const char *ipstr, uint32_t *ip)
{
(void) ipstr;
(void) ip;
return 0;
}
/* Used in dnsCallback */
int pico_string_to_ipv6(const char *ipstr, uint8_t *ip)
{
(void) ipstr;
(void) ip;
return 0;
}
/* Used in pico_sntp_sync_start_ipv4 */
int pico_ipv4_to_string(char* ipbuf, const uint32_t ip)
{
(void) ipbuf;
(void) ip;
return 0;
}
/* Used in pico_sntp_sync_start_ipv6 */
int pico_ipv6_to_string(char* ipbuf, const uint8_t ip[PICO_SIZE_IP6])
{
(void) ipbuf;
(void) ip;
return 0;
}
/* Used in pico_sntp_client_wakeup */
int pico_socket_recvfrom(struct pico_socket *s, void *buf, int len, void *orig, uint16_t *remote_port)
{
(void) s;
(void) buf;
(void) len;
(void) orig;
(void) remote_port;
return 0;
}
/* Used in pico_sntp_send */
int pico_socket_sendto(struct pico_socket *s, const void *buf, int len, void *dst, uint16_t remote_port)
{
(void) s;
(void) buf;
(void) len;
(void) dst;
(void) remote_port;
return 0;
}
/* Used in pico_sntp_sync_start_dns_ipv4, not tested */
int pico_dns_client_getaddr(const char *url, void (*callback)(char *ip, void *arg), void *arg)
{
(void) url;
(void) callback;
(void) arg;
return 0;
}
/* Used in pico_sntp_sync_start_dns_ipv6, not tested */
int pico_dns_client_getaddr6(const char *url, void (*callback)(char *, void *), void *arg)
{
(void) url;
(void) callback;
(void) arg;
return 0;
}
/* Used in pico_sntp_parse */
void cb_synced(pico_err_t status)
{
(void) status;
}
/* Used in pico_sntp_send */
static uint32_t timers_added = 0;
uint32_t pico_timer_add(pico_time expire, void (*timer)(pico_time, void *), void *arg)
{
(void) expire;
(void) timer;
(void) arg;
return ++timers_added;
}
/* Used in pico_sntp_cleanup */
void pico_timer_cancel(uint32_t t)
{
IGNORE_PARAMETER(t);
}
START_TEST(tc_timestamp_convert)
{
struct pico_sntp_ts ts;
struct pico_timeval tv;
pico_time delay = 0ull;
int ret = 0;
/* Input is all zero */
ts.sec = long_be(0ul);
ts.frac = long_be(0ul);
ret = timestamp_convert(&ts, &tv, delay);
ck_assert(ret == -1);
ck_assert(tv.tv_sec == 0);
ck_assert(tv.tv_msec == 0);
/* Minimum input*/
ts.sec = long_be(SNTP_UNIX_OFFSET + 1390000000ul);
ts.frac = long_be(4310344ul); /* MIN value: 1msec */
ret = timestamp_convert(&ts, &tv, delay);
ck_assert(ret == 0);
fail_unless(tv.tv_sec == 1390000000);
fail_unless(tv.tv_msec == 1);
/* Intermediate input */
ts.sec = long_be(SNTP_UNIX_OFFSET + 1390000000ul);
ts.frac = long_be(3865470566ul); /* value: 899msec */
ret = timestamp_convert(&ts, &tv, delay);
ck_assert(ret == 0);
fail_unless(tv.tv_sec == 1390000000);
fail_unless(tv.tv_msec == 900);
/* Maximum input */
ts.sec = long_be(SNTP_UNIX_OFFSET + 1390000000ul);
ts.frac = long_be(4294967295ul); /* MAX value: 999msec */
ret = timestamp_convert(&ts, &tv, delay);
ck_assert(ret == 0);
fail_unless(tv.tv_sec == 1390000001);
fail_unless(tv.tv_msec == 0);
/* Intermediate input with delay */
ts.sec = long_be(SNTP_UNIX_OFFSET + 1390000000ul);
ts.frac = long_be(3865470566ul); /* value: 899msec */
delay = 200ull;
ret = timestamp_convert(&ts, &tv, delay);
ck_assert(ret == 0);
fail_unless(tv.tv_sec == 1390000001);
fail_unless(tv.tv_msec == 100);
}
END_TEST
START_TEST(tc_pico_sntp_cleanup)
{
struct sntp_server_ns_cookie *ck;
struct pico_socket *sock;
ck = PICO_ZALLOC(sizeof(struct sntp_server_ns_cookie));
fail_unless (ck != NULL);
ck->hostname = PICO_ZALLOC(sizeof(char) * 5);
fail_unless (ck->hostname != NULL);
ck->stamp = 0ull;
ck->cb_synced = cb_synced;
sock = pico_socket_open(0, 0, &pico_sntp_client_wakeup);
ck->sock = sock;
sock->priv = ck;
pico_sntp_cleanup(ck, PICO_ERR_NOERR);
}
END_TEST
START_TEST(tc_pico_sntp_parse)
{
/* TODO: test this: static void pico_sntp_parse(char *buf, struct sntp_server_ns_cookie *ck) */
struct sntp_server_ns_cookie *ck;
struct pico_socket *sock;
struct pico_sntp_header header = {
0
};
ck = PICO_ZALLOC(sizeof(struct sntp_server_ns_cookie));
fail_unless (ck != NULL);
ck->hostname = PICO_ZALLOC(sizeof(char) * 5);
fail_unless (ck->hostname != NULL);
ck->stamp = 0ull;
ck->cb_synced = cb_synced;
sock = pico_socket_open(0, 0, &pico_sntp_client_wakeup);
ck->sock = sock;
sock->priv = ck;
header.mode = 4; /* server mode */
header.vn = 4; /* sntp version 4 */
header.stratum = 1; /* primary reference */
header.trs_ts.sec = long_be(SNTP_UNIX_OFFSET + 1390000000ul);
header.trs_ts.frac = long_be(3865470566ul); /* value: 899msec */
fail_if(pico_sntp_parse((char *) &header, NULL) == 0);
fail_if(pico_sntp_parse((char *) &header, ck) != 0);
}
END_TEST
START_TEST(tc_pico_sntp_client_wakeup)
{
/* TODO: test this: static void pico_sntp_client_wakeup(uint16_t ev, struct pico_socket *s) */
uint16_t event = PICO_SOCK_EV_ERR;
struct sntp_server_ns_cookie *ck;
struct pico_socket *sock;
ck = PICO_ZALLOC(sizeof(struct sntp_server_ns_cookie));
fail_unless (ck != NULL);
ck->hostname = PICO_ZALLOC(sizeof(char) * 5);
fail_unless (ck->hostname != NULL);
ck->stamp = 0ull;
ck->cb_synced = cb_synced;
sock = pico_socket_open(0, 0, &pico_sntp_client_wakeup);
ck->sock = sock;
sock->priv = ck;
ck->cb_synced = cb_synced;
printf("Started wakeup unit test\n");
pico_sntp_client_wakeup(event, sock);
}
END_TEST
START_TEST(tc_sntp_receive_timeout)
{
struct sntp_server_ns_cookie *ck;
struct pico_socket *sock;
ck = PICO_ZALLOC(sizeof(struct sntp_server_ns_cookie));
fail_unless (ck != NULL);
ck->hostname = PICO_ZALLOC(sizeof(char) * 5);
fail_unless (ck->hostname != NULL);
ck->stamp = 0ull;
ck->cb_synced = cb_synced;
sock = pico_socket_open(0, 0, &pico_sntp_client_wakeup);
ck->sock = sock;
sock->priv = ck;
sntp_receive_timeout(0ull, ck);
}
END_TEST
START_TEST(tc_pico_sntp_send)
{
/* TODO: test this: static void pico_sntp_send(struct pico_socket *sock, union pico_address *dst) */
struct pico_socket sock = {
0
};
union pico_address dst;
struct sntp_server_ns_cookie ck = {
0
};
sock.priv = &ck;
pico_sntp_send(&sock, &dst);
}
END_TEST
START_TEST(tc_dnsCallback)
{
/* TODO: test this: static void dnsCallback(char *ip, void *arg) */
char ip[] = "198.123.30.132";
struct sntp_server_ns_cookie *ck;
ck = PICO_ZALLOC(sizeof(struct sntp_server_ns_cookie));
dnsCallback(ip, ck);
}
END_TEST
START_TEST(tc_pico_sntp_sync)
{
const char *sntp_server= "ntp.nasa.gov";
fail_if(pico_sntp_sync(NULL, cb_synced) == 0);
fail_if(pico_err != PICO_ERR_EINVAL);
fail_if(pico_sntp_sync(sntp_server, NULL) == 0);
fail_if(pico_err != PICO_ERR_EINVAL);
fail_if(pico_sntp_sync(sntp_server, cb_synced) != 0);
}
END_TEST
START_TEST(tc_pico_sntp_sync_ip)
{
union pico_address sntp_addr = { .ip4.addr = 0ul };
fail_if(pico_sntp_sync_ip(NULL, cb_synced) == 0);
fail_if(pico_err != PICO_ERR_EINVAL);
fail_if(pico_sntp_sync_ip(&sntp_addr, NULL) == 0);
fail_if(pico_err != PICO_ERR_EINVAL);
fail_if(pico_sntp_sync_ip(&sntp_addr, cb_synced) != 0);
}
END_TEST
START_TEST(tc_pico_sntp_sync_start)
{
struct sntp_server_ns_cookie ck = { 0 };
union pico_address sntp_addr = { .ip4.addr= 0ul };
fail_if(pico_sntp_sync_start(&ck, &sntp_addr) != 0);
}
END_TEST
START_TEST(tc_pico_sntp_sync_start_dns_ipv4)
{
const char *sntp_server = "ntp.nasa.gov";
fail_if(pico_sntp_sync_start_dns_ipv4(sntp_server, cb_synced) != 0);
}
END_TEST
START_TEST(tc_pico_sntp_sync_start_dns_ipv6)
{
const char *sntp_server = "ntp.nasa.gov";
fail_if(pico_sntp_sync_start_dns_ipv6(sntp_server, cb_synced) != 0);
}
END_TEST
START_TEST(tc_pico_sntp_sync_start_ipv4)
{
union pico_address sntp_addr = { .ip4.addr = 0};
fail_if(pico_sntp_sync_start_ipv4(&sntp_addr, cb_synced) != 0);
}
END_TEST
START_TEST(tc_pico_sntp_sync_start_ipv6)
{
union pico_address sntp_addr = { .ip6.addr = { 0 } };
fail_if(pico_sntp_sync_start_ipv6(&sntp_addr, cb_synced) != 0);
}
END_TEST
Suite *pico_suite(void)
{
Suite *s = suite_create("PicoTCP");
TCase *TCase_timestamp_convert = tcase_create("Unit test for pico_timeval");
TCase *TCase_pico_sntp_cleanup = tcase_create("Unit test for pico_sntp_cleanup");
TCase *TCase_pico_sntp_send = tcase_create("Unit test for pico_sntp_send");
TCase *TCase_pico_sntp_parse = tcase_create("Unit test for pico_sntp_parse");
TCase *TCase_pico_sntp_client_wakeup = tcase_create("Unit test for pico_sntp_client_wakeup");
TCase *TCase_sntp_receive_timeout = tcase_create("Unit test for sntp_receive_timeout");
TCase *TCase_dnsCallback = tcase_create("Unit test for dnsCallback");
TCase *TCase_pico_sntp_sync = tcase_create("Unit test for pico_sntp_sync");
TCase *TCase_pico_sntp_sync_ip = tcase_create("Unit test for pico_sntp_sync_ip");
TCase *TCase_pico_sntp_sync_start = tcase_create("Unit test for pico_sntp_sync_start");
TCase *TCase_pico_sntp_sync_start_dns_ipv4 = tcase_create("Unit test for pico_sntp_sync_start_dns_ipv4");
TCase *TCase_pico_sntp_sync_start_dns_ipv6 = tcase_create("Unit test for pico_sntp_sync_start_dns_ipv6");
TCase *TCase_pico_sntp_sync_start_ipv4 = tcase_create("Unit test for pico_sntp_sync_start_ipv4");
TCase *TCase_pico_sntp_sync_start_ipv6 = tcase_create("Unit test for pico_sntp_sync_start_ipv6");
tcase_add_test(TCase_timestamp_convert, tc_timestamp_convert);
suite_add_tcase(s, TCase_timestamp_convert);
tcase_add_test(TCase_pico_sntp_cleanup, tc_pico_sntp_cleanup);
suite_add_tcase(s, TCase_pico_sntp_cleanup);
tcase_add_test(TCase_pico_sntp_parse, tc_pico_sntp_parse);
suite_add_tcase(s, TCase_pico_sntp_parse);
tcase_add_test(TCase_pico_sntp_client_wakeup, tc_pico_sntp_client_wakeup);
suite_add_tcase(s, TCase_pico_sntp_client_wakeup);
tcase_add_test(TCase_sntp_receive_timeout, tc_sntp_receive_timeout);
suite_add_tcase(s, TCase_sntp_receive_timeout);
tcase_add_test(TCase_pico_sntp_send, tc_pico_sntp_send);
suite_add_tcase(s, TCase_pico_sntp_send);
tcase_add_test(TCase_dnsCallback, tc_dnsCallback);
suite_add_tcase(s, TCase_dnsCallback);
tcase_add_test(TCase_pico_sntp_sync, tc_pico_sntp_sync);
suite_add_tcase(s, TCase_pico_sntp_sync);
tcase_add_test(TCase_pico_sntp_sync_ip, tc_pico_sntp_sync_ip);
suite_add_tcase(s, TCase_pico_sntp_sync_ip);
tcase_add_test(TCase_pico_sntp_sync_start, tc_pico_sntp_sync_start);
suite_add_tcase(s, TCase_pico_sntp_sync_start);
tcase_add_test(TCase_pico_sntp_sync_start_dns_ipv4, tc_pico_sntp_sync_start_dns_ipv4);
suite_add_tcase(s, TCase_pico_sntp_sync_start_dns_ipv4);
tcase_add_test(TCase_pico_sntp_sync_start_dns_ipv6, tc_pico_sntp_sync_start_dns_ipv6);
suite_add_tcase(s, TCase_pico_sntp_sync_start_dns_ipv6);
tcase_add_test(TCase_pico_sntp_sync_start_ipv4, tc_pico_sntp_sync_start_ipv4);
suite_add_tcase(s, TCase_pico_sntp_sync_start_ipv4);
tcase_add_test(TCase_pico_sntp_sync_start_ipv6, tc_pico_sntp_sync_start_ipv6);
suite_add_tcase(s, TCase_pico_sntp_sync_start_ipv6);
return s;
}
int main(void)
{
int fails;
Suite *s = pico_suite();
SRunner *sr = srunner_create(s);
srunner_run_all(sr, CK_NORMAL);
fails = srunner_ntests_failed(sr);
srunner_free(sr);
return fails;
}