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 <seppo.takalo@nordicsemi.no>
This commit is contained in:
parent
0be5dcd25d
commit
ca67f51170
4 changed files with 77 additions and 42 deletions
|
@ -1,3 +1,4 @@
|
|||
#Testing
|
||||
CONFIG_ZTEST=y
|
||||
CONFIG_ZTEST_STACK_SIZE=4096
|
||||
CONFIG_TEST_RANDOM_GENERATOR=y
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue