From ca67f51170a53f32ff9c0769d085fcbc47b905da Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Mon, 11 Nov 2024 14:35:30 +0200 Subject: [PATCH] tests: coap_client: Improve socket stubs * Use sys_rand_get() and seed the CoAP library, so our MIDs are random. * Set socket events per socket, so we don't accidentally receive on wrong socket * Reply with correct tokens Signed-off-by: Seppo Takalo --- tests/net/lib/coap_client/prj.conf | 1 + tests/net/lib/coap_client/src/main.c | 91 +++++++++++++++++++-------- tests/net/lib/coap_client/src/stubs.c | 20 +++--- tests/net/lib/coap_client/src/stubs.h | 7 +-- 4 files changed, 77 insertions(+), 42 deletions(-) diff --git a/tests/net/lib/coap_client/prj.conf b/tests/net/lib/coap_client/prj.conf index c7265029a21..8405a56f800 100644 --- a/tests/net/lib/coap_client/prj.conf +++ b/tests/net/lib/coap_client/prj.conf @@ -1,3 +1,4 @@ #Testing CONFIG_ZTEST=y CONFIG_ZTEST_STACK_SIZE=4096 +CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/net/lib/coap_client/src/main.c b/tests/net/lib/coap_client/src/main.c index f06a0ce646c..e066f86bae6 100644 --- a/tests/net/lib/coap_client/src/main.c +++ b/tests/net/lib/coap_client/src/main.c @@ -11,7 +11,7 @@ #include "stubs.h" -LOG_MODULE_REGISTER(coap_client_test); +LOG_MODULE_REGISTER(coap_client_test, LOG_LEVEL_DBG); DEFINE_FFF_GLOBALS; #define FFF_FAKES_LIST(FAKE) @@ -23,11 +23,14 @@ DEFINE_FFF_GLOBALS; (CONFIG_COAP_INIT_ACK_TIMEOUT_MS + CONFIG_COAP_INIT_ACK_TIMEOUT_MS / 2) #define VALID_MESSAGE_ID BIT(31) +#define TOKEN_OFFSET 4 static int16_t last_response_code; static const char *test_path = "test"; static uint32_t messages_needing_response[2]; +static uint8_t last_token[2][COAP_TOKEN_MAX_LEN]; +static const uint8_t empty_token[COAP_TOKEN_MAX_LEN] = {0}; static struct coap_client client; @@ -61,6 +64,27 @@ static void set_next_pending_message_id(uint16_t id) } } +static void store_token(uint8_t *buf) +{ + for (int i = 0; i < ARRAY_SIZE(last_token); i++) { + if (memcmp(last_token[i], empty_token, 8) == 0) { + memcpy(last_token[i], buf + TOKEN_OFFSET, COAP_TOKEN_MAX_LEN); + return; + } + } +} + +static void restore_token(uint8_t *buf) +{ + for (int i = 0; i < ARRAY_SIZE(last_token); i++) { + if (memcmp(last_token[i], empty_token, 8) != 0) { + memcpy(buf + TOKEN_OFFSET, last_token[i], COAP_TOKEN_MAX_LEN); + memset(last_token[i], 0, COAP_TOKEN_MAX_LEN); + return; + } + } +} + static ssize_t z_impl_zsock_recvfrom_custom_fake(int sock, void *buf, size_t max_len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) { @@ -74,10 +98,11 @@ static ssize_t z_impl_zsock_recvfrom_custom_fake(int sock, void *buf, size_t max ack_data[2] = (uint8_t)(last_message_id >> 8); ack_data[3] = (uint8_t)last_message_id; + restore_token(ack_data); memcpy(buf, ack_data, sizeof(ack_data)); - clear_socket_events(ZSOCK_POLLIN); + clear_socket_events(sock, ZSOCK_POLLIN); return sizeof(ack_data); } @@ -90,14 +115,14 @@ static ssize_t z_impl_zsock_sendto_custom_fake(int sock, void *buf, size_t len, last_message_id |= ((uint8_t *)buf)[2] << 8; last_message_id |= ((uint8_t *)buf)[3]; - type = (((uint8_t *)buf)[0] & 0x30) >> 4; + store_token(buf); set_next_pending_message_id(last_message_id); LOG_INF("Latest message ID: %d", last_message_id); if (type == 0) { - set_socket_events(ZSOCK_POLLIN); + set_socket_events(sock, ZSOCK_POLLIN); } return 1; @@ -111,6 +136,7 @@ static ssize_t z_impl_zsock_sendto_custom_fake_no_reply(int sock, void *buf, siz last_message_id |= ((uint8_t *)buf)[2] << 8; last_message_id |= ((uint8_t *)buf)[3]; + store_token(buf); set_next_pending_message_id(last_message_id); LOG_INF("Latest message ID: %d", last_message_id); @@ -128,6 +154,7 @@ static ssize_t z_impl_zsock_sendto_custom_fake_echo(int sock, void *buf, size_t last_message_id |= ((uint8_t *)buf)[2] << 8; last_message_id |= ((uint8_t *)buf)[3]; + store_token(buf); set_next_pending_message_id(last_message_id); LOG_INF("Latest message ID: %d", last_message_id); @@ -144,7 +171,7 @@ static ssize_t z_impl_zsock_sendto_custom_fake_echo(int sock, void *buf, size_t z_impl_zsock_sendto_fake.custom_fake = z_impl_zsock_sendto_custom_fake; - set_socket_events(ZSOCK_POLLIN); + set_socket_events(sock, ZSOCK_POLLIN); return 1; } @@ -160,6 +187,7 @@ static ssize_t z_impl_zsock_sendto_custom_fake_echo_next_req(int sock, void *buf last_message_id |= ((uint8_t *)buf)[2] << 8; last_message_id |= ((uint8_t *)buf)[3]; + store_token(buf); set_next_pending_message_id(last_message_id); LOG_INF("Latest message ID: %d", last_message_id); @@ -184,7 +212,7 @@ static ssize_t z_impl_zsock_sendto_custom_fake_echo_next_req(int sock, void *buf z_impl_zsock_sendto_fake.custom_fake = z_impl_zsock_sendto_custom_fake; - set_socket_events(ZSOCK_POLLIN); + set_socket_events(sock, ZSOCK_POLLIN); return 1; } @@ -202,10 +230,11 @@ static ssize_t z_impl_zsock_recvfrom_custom_fake_response(int sock, void *buf, s ack_data[2] = (uint8_t)(last_message_id >> 8); ack_data[3] = (uint8_t)last_message_id; + restore_token(ack_data); memcpy(buf, ack_data, sizeof(ack_data)); - clear_socket_events(ZSOCK_POLLIN); + clear_socket_events(sock, ZSOCK_POLLIN); return sizeof(ack_data); } @@ -216,7 +245,7 @@ static ssize_t z_impl_zsock_recvfrom_custom_fake_empty_ack(int sock, void *buf, { uint16_t last_message_id = 0; - static uint8_t ack_data[] = {0x68, 0x00, 0x00, 0x00, 0x00, 0x00, + static uint8_t ack_data[] = {0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; last_message_id = get_next_pending_message_id(); @@ -247,7 +276,7 @@ static ssize_t z_impl_zsock_recvfrom_custom_fake_unmatching(int sock, void *buf, memcpy(buf, ack_data, sizeof(ack_data)); - clear_socket_events(ZSOCK_POLLIN); + clear_socket_events(sock, ZSOCK_POLLIN); return sizeof(ack_data); } @@ -267,13 +296,14 @@ static ssize_t z_impl_zsock_recvfrom_custom_fake_echo(int sock, void *buf, size_ ack_data[2] = (uint8_t)(last_message_id >> 8); ack_data[3] = (uint8_t)last_message_id; + restore_token(ack_data); memcpy(buf, ack_data, sizeof(ack_data)); z_impl_zsock_recvfrom_fake.custom_fake = z_impl_zsock_recvfrom_custom_fake_response; z_impl_zsock_sendto_fake.custom_fake = z_impl_zsock_sendto_custom_fake_echo; - clear_socket_events(ZSOCK_POLLIN); + clear_socket_events(sock, ZSOCK_POLLIN); return sizeof(ack_data); } @@ -293,19 +323,23 @@ static ssize_t z_impl_zsock_recvfrom_custom_fake_echo_next_req(int sock, void *b ack_data[2] = (uint8_t)(last_message_id >> 8); ack_data[3] = (uint8_t)last_message_id; + restore_token(ack_data); memcpy(buf, ack_data, sizeof(ack_data)); z_impl_zsock_recvfrom_fake.custom_fake = z_impl_zsock_recvfrom_custom_fake_response; z_impl_zsock_sendto_fake.custom_fake = z_impl_zsock_sendto_custom_fake_echo_next_req; - clear_socket_events(ZSOCK_POLLIN); + clear_socket_events(sock, ZSOCK_POLLIN); return sizeof(ack_data); } +extern void net_coap_init(void); + static void *suite_setup(void) { + net_coap_init(); coap_client_init(&client, NULL); return NULL; @@ -315,6 +349,8 @@ static void test_setup(void *data) { int i; + k_mutex_lock(&client.lock, K_FOREVER); + /* Register resets */ DO_FOREACH_FAKE(RESET_FAKE); /* reset common FFF internal structures */ @@ -322,13 +358,19 @@ static void test_setup(void *data) z_impl_zsock_recvfrom_fake.custom_fake = z_impl_zsock_recvfrom_custom_fake; z_impl_zsock_sendto_fake.custom_fake = z_impl_zsock_sendto_custom_fake; - clear_socket_events(ZSOCK_POLLIN | ZSOCK_POLLOUT | ZSOCK_POLLERR); + clear_socket_events(0, ZSOCK_POLLIN | ZSOCK_POLLOUT | ZSOCK_POLLERR); + clear_socket_events(1, ZSOCK_POLLIN | ZSOCK_POLLOUT | ZSOCK_POLLERR); for (i = 0; i < ARRAY_SIZE(messages_needing_response); i++) { messages_needing_response[i] = 0; } + memset(&client.requests, 0, sizeof(client.requests)); + memset(last_token, 0, sizeof(last_token)); + last_response_code = 0; + + k_mutex_unlock(&client.lock); } void coap_callback(int16_t code, size_t offset, const uint8_t *payload, size_t len, bool last_block, @@ -396,7 +438,7 @@ ZTEST(coap_client, test_resend_request) ret = coap_client_req(&client, 0, &address, &client_request, NULL); zassert_true(ret >= 0, "Sending request failed, %d", ret); k_sleep(K_MSEC(MORE_THAN_ACK_TIMEOUT_MS)); - set_socket_events(ZSOCK_POLLIN | ZSOCK_POLLOUT); + set_socket_events(client.fd, ZSOCK_POLLIN | ZSOCK_POLLOUT); k_sleep(K_MSEC(MORE_THAN_EXCHANGE_LIFETIME_MS)); zassert_equal(last_response_code, COAP_RESPONSE_CODE_OK, "Unexpected response"); @@ -551,7 +593,7 @@ ZTEST(coap_client, test_no_response) client_request.len = strlen(short_payload); z_impl_zsock_sendto_fake.custom_fake = z_impl_zsock_sendto_custom_fake_no_reply; - set_socket_events(ZSOCK_POLLOUT); + set_socket_events(client.fd, ZSOCK_POLLOUT); k_sleep(K_MSEC(1)); @@ -628,7 +670,7 @@ ZTEST(coap_client, test_multiple_requests) ret = coap_client_req(&client, 0, &address, &req2, NULL); zassert_true(ret >= 0, "Sending request failed, %d", ret); - set_socket_events(ZSOCK_POLLIN); + set_socket_events(client.fd, ZSOCK_POLLIN); while (last_response_code == 0 && retry > 0) { retry--; k_sleep(K_MSEC(1)); @@ -636,7 +678,7 @@ ZTEST(coap_client, test_multiple_requests) zassert_equal(last_response_code, COAP_RESPONSE_CODE_OK, "Unexpected response"); last_response_code = 0; - set_socket_events(ZSOCK_POLLIN); + set_socket_events(client.fd, ZSOCK_POLLIN); zassert_ok(k_sem_take(&sem1, K_MSEC(MORE_THAN_EXCHANGE_LIFETIME_MS))); zassert_ok(k_sem_take(&sem2, K_MSEC(MORE_THAN_EXCHANGE_LIFETIME_MS))); zassert_equal(last_response_code, COAP_RESPONSE_CODE_OK, "Unexpected response"); @@ -665,7 +707,7 @@ ZTEST(coap_client, test_unmatching_tokens) client_request.len = strlen(short_payload); z_impl_zsock_recvfrom_fake.custom_fake = z_impl_zsock_recvfrom_custom_fake_unmatching; - set_socket_events(ZSOCK_POLLIN | ZSOCK_POLLOUT); + set_socket_events(client.fd, ZSOCK_POLLIN | ZSOCK_POLLOUT); k_sleep(K_MSEC(1)); @@ -681,9 +723,6 @@ ZTEST(coap_client, test_multiple_clients) { int ret; int retry = MORE_THAN_EXCHANGE_LIFETIME_MS; - static struct coap_client client2 = { - .fd = 2, - }; struct k_sem sem1, sem2; struct sockaddr address = {0}; struct coap_client_request req1 = { @@ -710,17 +749,17 @@ ZTEST(coap_client, test_multiple_clients) k_sleep(K_MSEC(1)); LOG_INF("Sending requests"); - ret = coap_client_req(&client, 1, &address, &req1, NULL); + ret = coap_client_req(&client, client.fd, &address, &req1, NULL); zassert_true(ret >= 0, "Sending request failed, %d", ret); - ret = coap_client_req(&client2, 2, &address, &req2, NULL); + ret = coap_client_req(&client2, client2.fd, &address, &req2, NULL); zassert_true(ret >= 0, "Sending request failed, %d", ret); while (last_response_code == 0 && retry > 0) { retry--; k_sleep(K_MSEC(1)); } - set_socket_events(ZSOCK_POLLIN); + set_socket_events(client2.fd, ZSOCK_POLLIN); k_sleep(K_SECONDS(1)); @@ -746,7 +785,7 @@ ZTEST(coap_client, test_poll_err) }; z_impl_zsock_sendto_fake.custom_fake = z_impl_zsock_sendto_custom_fake_no_reply; - set_socket_events(ZSOCK_POLLERR); + set_socket_events(client.fd, ZSOCK_POLLERR); k_sleep(K_MSEC(1)); @@ -776,7 +815,7 @@ ZTEST(coap_client, test_poll_err_after_response) zassert_ok(k_sem_init(&sem1, 0, 1)); z_impl_zsock_sendto_fake.custom_fake = z_impl_zsock_sendto_custom_fake_no_reply; - set_socket_events(ZSOCK_POLLIN); + set_socket_events(client.fd, ZSOCK_POLLIN); k_sleep(K_MSEC(1)); @@ -787,6 +826,6 @@ ZTEST(coap_client, test_poll_err_after_response) zassert_ok(k_sem_take(&sem1, K_MSEC(MORE_THAN_EXCHANGE_LIFETIME_MS))); zassert_equal(last_response_code, COAP_RESPONSE_CODE_OK, "Unexpected response"); - set_socket_events(ZSOCK_POLLERR); + set_socket_events(client.fd, ZSOCK_POLLERR); zassert_not_ok(k_sem_take(&sem1, K_MSEC(MORE_THAN_EXCHANGE_LIFETIME_MS))); } diff --git a/tests/net/lib/coap_client/src/stubs.c b/tests/net/lib/coap_client/src/stubs.c index d698248b050..8d251157ac1 100644 --- a/tests/net/lib/coap_client/src/stubs.c +++ b/tests/net/lib/coap_client/src/stubs.c @@ -10,7 +10,6 @@ LOG_MODULE_DECLARE(coap_client_test); DEFINE_FAKE_VALUE_FUNC(uint32_t, z_impl_sys_rand32_get); -DEFINE_FAKE_VOID_FUNC(z_impl_sys_rand_get, void *, size_t); DEFINE_FAKE_VALUE_FUNC(ssize_t, z_impl_zsock_recvfrom, int, void *, size_t, int, struct sockaddr *, socklen_t *); DEFINE_FAKE_VALUE_FUNC(ssize_t, z_impl_zsock_sendto, int, void *, size_t, int, @@ -22,21 +21,17 @@ struct zvfs_pollfd { short revents; }; -static short my_events; +static short my_events[NUM_FD]; -void set_socket_events(short events) +void set_socket_events(int fd, short events) { - my_events |= events; + __ASSERT_NO_MSG(fd < NUM_FD); + my_events[fd] |= events; } -void clear_socket_events(short events) +void clear_socket_events(int fd, short events) { - my_events &= ~events; -} - -int z_impl_zsock_socket(int family, int type, int proto) -{ - return 0; + my_events[fd] &= ~events; } int z_impl_zvfs_poll(struct zvfs_pollfd *fds, int nfds, int poll_timeout) @@ -44,7 +39,8 @@ int z_impl_zvfs_poll(struct zvfs_pollfd *fds, int nfds, int poll_timeout) int events = 0; k_sleep(K_MSEC(1)); for (int i = 0; i < nfds; i++) { - fds[i].revents = my_events & (fds[i].events | ZSOCK_POLLERR | ZSOCK_POLLHUP); + fds[i].revents = + my_events[fds[i].fd] & (fds[i].events | ZSOCK_POLLERR | ZSOCK_POLLHUP); if (fds[i].revents) { events++; } diff --git a/tests/net/lib/coap_client/src/stubs.h b/tests/net/lib/coap_client/src/stubs.h index 9a9f929ce76..c3024536b54 100644 --- a/tests/net/lib/coap_client/src/stubs.h +++ b/tests/net/lib/coap_client/src/stubs.h @@ -36,12 +36,12 @@ #define ZSOCK_POLLNVAL 0x20 /** @} */ +#define NUM_FD 2 -void set_socket_events(short events); -void clear_socket_events(short events); +void set_socket_events(int fd, short events); +void clear_socket_events(int fd, short events); DECLARE_FAKE_VALUE_FUNC(uint32_t, z_impl_sys_rand32_get); -DECLARE_FAKE_VOID_FUNC(z_impl_sys_rand_get, void *, size_t); DECLARE_FAKE_VALUE_FUNC(ssize_t, z_impl_zsock_recvfrom, int, void *, size_t, int, struct sockaddr *, socklen_t *); DECLARE_FAKE_VALUE_FUNC(ssize_t, z_impl_zsock_sendto, int, void*, size_t, int, @@ -50,7 +50,6 @@ DECLARE_FAKE_VALUE_FUNC(ssize_t, z_impl_zsock_sendto, int, void*, size_t, int, #define DO_FOREACH_FAKE(FUNC) \ do { \ FUNC(z_impl_sys_rand32_get) \ - FUNC(z_impl_sys_rand_get) \ FUNC(z_impl_zsock_recvfrom) \ FUNC(z_impl_zsock_sendto) \ } while (0)