tests: net: websocket: Add TX unit tests for websocket API
Add simple tests for testing sent and received websocket data. Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
parent
86b688d43f
commit
b957581391
2 changed files with 154 additions and 2 deletions
|
@ -48,6 +48,10 @@ static struct k_sem contexts_lock;
|
||||||
extern const struct socket_op_vtable sock_fd_op_vtable;
|
extern const struct socket_op_vtable sock_fd_op_vtable;
|
||||||
static const struct socket_op_vtable websocket_fd_op_vtable;
|
static const struct socket_op_vtable websocket_fd_op_vtable;
|
||||||
|
|
||||||
|
#if defined(CONFIG_NET_TEST)
|
||||||
|
int verify_sent_and_received_msg(struct msghdr *msg, bool split_msg);
|
||||||
|
#endif
|
||||||
|
|
||||||
static const char *opcode2str(enum websocket_opcode opcode)
|
static const char *opcode2str(enum websocket_opcode opcode)
|
||||||
{
|
{
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
|
@ -465,8 +469,15 @@ static int websocket_prepare_and_send(struct websocket_context *ctx,
|
||||||
LOG_HEXDUMP_DBG(payload, payload_len, "Payload");
|
LOG_HEXDUMP_DBG(payload, payload_len, "Payload");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_NET_TEST)
|
||||||
|
/* Simulate a case where the payload is split to two. The unit test
|
||||||
|
* does not set mask bit in this case.
|
||||||
|
*/
|
||||||
|
return verify_sent_and_received_msg(&msg, !(header[1] & BIT(7)));
|
||||||
|
#else
|
||||||
return sendmsg(ctx->real_sock, &msg,
|
return sendmsg(ctx->real_sock, &msg,
|
||||||
timeout == K_NO_WAIT ? MSG_DONTWAIT : 0);
|
timeout == K_NO_WAIT ? MSG_DONTWAIT : 0);
|
||||||
|
#endif /* CONFIG_NET_TEST */
|
||||||
}
|
}
|
||||||
|
|
||||||
int websocket_send_msg(int ws_sock, const u8_t *payload, size_t payload_len,
|
int websocket_send_msg(int ws_sock, const u8_t *payload, size_t payload_len,
|
||||||
|
@ -487,6 +498,12 @@ int websocket_send_msg(int ws_sock, const u8_t *payload, size_t payload_len,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_NET_TEST)
|
||||||
|
/* Websocket unit test does not use socket layer but feeds
|
||||||
|
* the data directly here when testing this function.
|
||||||
|
*/
|
||||||
|
ctx = INT_TO_POINTER(ws_sock);
|
||||||
|
#else
|
||||||
ctx = z_get_fd_obj(ws_sock, NULL, 0);
|
ctx = z_get_fd_obj(ws_sock, NULL, 0);
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
return -EBADF;
|
return -EBADF;
|
||||||
|
@ -495,6 +512,7 @@ int websocket_send_msg(int ws_sock, const u8_t *payload, size_t payload_len,
|
||||||
if (!PART_OF_ARRAY(contexts, ctx)) {
|
if (!PART_OF_ARRAY(contexts, ctx)) {
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_NET_TEST */
|
||||||
|
|
||||||
NET_DBG("[%p] Len %zd %s/%d/%s", ctx, payload_len, opcode2str(opcode),
|
NET_DBG("[%p] Len %zd %s/%d/%s", ctx, payload_len, opcode2str(opcode),
|
||||||
mask, final ? "final" : "more");
|
mask, final ? "final" : "more");
|
||||||
|
|
|
@ -15,8 +15,33 @@ LOG_MODULE_REGISTER(net_test, CONFIG_NET_WEBSOCKET_LOG_LEVEL);
|
||||||
|
|
||||||
#include "websocket_internal.h"
|
#include "websocket_internal.h"
|
||||||
|
|
||||||
|
/* Generated by http://www.lipsum.com/
|
||||||
|
* 2 paragraphs, 178 words, 1160 bytes of Lorem Ipsum
|
||||||
|
*/
|
||||||
|
static const char lorem_ipsum[] =
|
||||||
|
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
|
||||||
|
"Vestibulum ultricies sapien tellus, ac viverra dolor bibendum "
|
||||||
|
"lacinia. Vestibulum et nisl tristique tellus finibus gravida "
|
||||||
|
"vitae sit amet nunc. Suspendisse maximus justo mi, vitae porta "
|
||||||
|
"risus suscipit vitae. Curabitur ut fringilla velit. Donec ac nisi "
|
||||||
|
"in dui semper lobortis sed nec ante. Sed nec luctus dui. Sed ut "
|
||||||
|
"ante nisi. Mauris congue euismod felis, et maximus ex pellentesque "
|
||||||
|
"nec. Proin nibh nisl, semper at nunc in, mattis pharetra metus. Nam "
|
||||||
|
"turpis risus, pulvinar sit amet varius ac, pellentesque quis purus."
|
||||||
|
" "
|
||||||
|
"Nam consequat purus in lacinia fringilla. Morbi volutpat, tellus "
|
||||||
|
"nec tempus dapibus, ante sem aliquam dui, eu feugiat libero diam "
|
||||||
|
"at leo. Sed suscipit egestas orci in ultrices. Integer in elementum "
|
||||||
|
"ligula, vel sollicitudin velit. Nullam sit amet eleifend libero. "
|
||||||
|
"Proin sit amet consequat tellus, vel vulputate arcu. Curabitur quis "
|
||||||
|
"lobortis lacus. Sed faucibus vestibulum enim vel elementum. Vivamus "
|
||||||
|
"enim nunc, auctor in purus at, aliquet pulvinar eros. Cras dapibus "
|
||||||
|
"nec quam laoreet sagittis. Quisque dictum ante odio, at imperdiet "
|
||||||
|
"est convallis a. Morbi mattis ut orci vitae volutpat."
|
||||||
|
"\n";
|
||||||
|
|
||||||
#define MAX_RECV_BUF_LEN 256
|
#define MAX_RECV_BUF_LEN 256
|
||||||
static u8_t recv_buf[MAX_RECV_BUF_LEN];
|
static u8_t recv_buf[MAX(sizeof(lorem_ipsum), MAX_RECV_BUF_LEN)];
|
||||||
|
|
||||||
/* We need to allocate bigger buffer for the websocket data we receive so that
|
/* We need to allocate bigger buffer for the websocket data we receive so that
|
||||||
* the websocket header fits into it.
|
* the websocket header fits into it.
|
||||||
|
@ -25,6 +50,7 @@ static u8_t recv_buf[MAX_RECV_BUF_LEN];
|
||||||
|
|
||||||
static u8_t temp_recv_buf[MAX_RECV_BUF_LEN + EXTRA_BUF_SPACE];
|
static u8_t temp_recv_buf[MAX_RECV_BUF_LEN + EXTRA_BUF_SPACE];
|
||||||
static u8_t feed_buf[MAX_RECV_BUF_LEN + EXTRA_BUF_SPACE];
|
static u8_t feed_buf[MAX_RECV_BUF_LEN + EXTRA_BUF_SPACE];
|
||||||
|
static size_t test_msg_len;
|
||||||
|
|
||||||
struct test_data {
|
struct test_data {
|
||||||
u8_t *input_buf;
|
u8_t *input_buf;
|
||||||
|
@ -121,6 +147,8 @@ static void test_recv(int count)
|
||||||
&ctx, &msg_type, &remaining,
|
&ctx, &msg_type, &remaining,
|
||||||
recv_buf + total_read,
|
recv_buf + total_read,
|
||||||
sizeof(recv_buf) - total_read);
|
sizeof(recv_buf) - total_read);
|
||||||
|
zassert_true(ret <= (sizeof(recv_buf) - total_read),
|
||||||
|
"Invalid number of bytes read (%d)", ret);
|
||||||
total_read += ret;
|
total_read += ret;
|
||||||
zassert_equal(total_read, sizeof(frame1) - FRAME1_HDR_SIZE,
|
zassert_equal(total_read, sizeof(frame1) - FRAME1_HDR_SIZE,
|
||||||
"Invalid amount of data read (%d)", ret);
|
"Invalid amount of data read (%d)", ret);
|
||||||
|
@ -241,6 +269,110 @@ static void test_recv_two_msg(void)
|
||||||
test_recv_2(sizeof(frame1) + FRAME1_HDR_SIZE / 2);
|
test_recv_2(sizeof(frame1) + FRAME1_HDR_SIZE / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int verify_sent_and_received_msg(struct msghdr *msg, bool split_msg)
|
||||||
|
{
|
||||||
|
static struct websocket_context ctx;
|
||||||
|
u32_t msg_type = -1;
|
||||||
|
u64_t remaining = -1;
|
||||||
|
size_t split_len = 0, total_read = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
memset(&ctx, 0, sizeof(ctx));
|
||||||
|
|
||||||
|
ctx.tmp_buf = temp_recv_buf;
|
||||||
|
ctx.tmp_buf_len = sizeof(temp_recv_buf);
|
||||||
|
|
||||||
|
/* Read first the header */
|
||||||
|
ret = test_recv_buf(msg->msg_iov[0].iov_base,
|
||||||
|
msg->msg_iov[0].iov_len,
|
||||||
|
&ctx, &msg_type, &remaining,
|
||||||
|
recv_buf, sizeof(recv_buf));
|
||||||
|
zassert_equal(ret, -EAGAIN, "Msg header not found");
|
||||||
|
|
||||||
|
/* Then the first split if it is enabled */
|
||||||
|
if (split_msg) {
|
||||||
|
split_len = msg->msg_iov[1].iov_len / 2;
|
||||||
|
|
||||||
|
ret = test_recv_buf(msg->msg_iov[1].iov_base,
|
||||||
|
split_len,
|
||||||
|
&ctx, &msg_type, &remaining,
|
||||||
|
recv_buf, sizeof(recv_buf));
|
||||||
|
zassert_true(ret > 0, "Cannot read data (%d)", ret);
|
||||||
|
|
||||||
|
total_read = ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Then the data */
|
||||||
|
while (remaining > 0) {
|
||||||
|
ret = test_recv_buf((u8_t *)msg->msg_iov[1].iov_base +
|
||||||
|
total_read,
|
||||||
|
msg->msg_iov[1].iov_len - total_read,
|
||||||
|
&ctx, &msg_type, &remaining,
|
||||||
|
recv_buf, sizeof(recv_buf));
|
||||||
|
zassert_true(ret > 0, "Cannot read data (%d)", ret);
|
||||||
|
|
||||||
|
if (memcmp(recv_buf, lorem_ipsum + total_read, ret) != 0) {
|
||||||
|
LOG_HEXDUMP_ERR(lorem_ipsum + total_read, ret,
|
||||||
|
"Received message should be");
|
||||||
|
LOG_HEXDUMP_ERR(recv_buf, ret, "but it was instead");
|
||||||
|
zassert_true(false, "Invalid received message "
|
||||||
|
"after %d bytes", total_read);
|
||||||
|
}
|
||||||
|
|
||||||
|
total_read += ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
zassert_equal(total_read, test_msg_len,
|
||||||
|
"Msg body not valid, received %d instead of %zd",
|
||||||
|
total_read, test_msg_len);
|
||||||
|
|
||||||
|
NET_DBG("Received %zd header and %zd body",
|
||||||
|
msg->msg_iov[0].iov_len, total_read);
|
||||||
|
|
||||||
|
return msg->msg_iov[0].iov_len + total_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_send_and_recv_lorem_ipsum(void)
|
||||||
|
{
|
||||||
|
static struct websocket_context ctx;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
memset(&ctx, 0, sizeof(ctx));
|
||||||
|
|
||||||
|
ctx.tmp_buf = temp_recv_buf;
|
||||||
|
ctx.tmp_buf_len = sizeof(temp_recv_buf);
|
||||||
|
|
||||||
|
test_msg_len = sizeof(lorem_ipsum) - 1;
|
||||||
|
|
||||||
|
ret = websocket_send_msg(POINTER_TO_INT(&ctx),
|
||||||
|
lorem_ipsum, test_msg_len,
|
||||||
|
WEBSOCKET_OPCODE_DATA_TEXT, true, true,
|
||||||
|
K_FOREVER);
|
||||||
|
zassert_equal(ret, test_msg_len,
|
||||||
|
"Should have sent %zd bytes but sent %d instead",
|
||||||
|
test_msg_len, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_recv_two_large_split_msg(void)
|
||||||
|
{
|
||||||
|
static struct websocket_context ctx;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
memset(&ctx, 0, sizeof(ctx));
|
||||||
|
|
||||||
|
ctx.tmp_buf = temp_recv_buf;
|
||||||
|
ctx.tmp_buf_len = sizeof(temp_recv_buf);
|
||||||
|
|
||||||
|
test_msg_len = sizeof(lorem_ipsum) - 1;
|
||||||
|
|
||||||
|
ret = websocket_send_msg(POINTER_TO_INT(&ctx), lorem_ipsum,
|
||||||
|
test_msg_len, WEBSOCKET_OPCODE_DATA_TEXT,
|
||||||
|
false, true, K_FOREVER);
|
||||||
|
zassert_equal(ret, test_msg_len,
|
||||||
|
"1st should have sent %zd bytes but sent %d instead",
|
||||||
|
test_msg_len, ret);
|
||||||
|
}
|
||||||
|
|
||||||
void test_main(void)
|
void test_main(void)
|
||||||
{
|
{
|
||||||
k_thread_system_pool_assign(k_current_get());
|
k_thread_system_pool_assign(k_current_get());
|
||||||
|
@ -256,7 +388,9 @@ void test_main(void)
|
||||||
ztest_unit_test(test_recv_10_byte),
|
ztest_unit_test(test_recv_10_byte),
|
||||||
ztest_unit_test(test_recv_12_byte),
|
ztest_unit_test(test_recv_12_byte),
|
||||||
ztest_unit_test(test_recv_whole_msg),
|
ztest_unit_test(test_recv_whole_msg),
|
||||||
ztest_unit_test(test_recv_two_msg)
|
ztest_unit_test(test_recv_two_msg),
|
||||||
|
ztest_unit_test(test_send_and_recv_lorem_ipsum),
|
||||||
|
ztest_unit_test(test_recv_two_large_split_msg)
|
||||||
);
|
);
|
||||||
|
|
||||||
ztest_run_test_suite(websocket);
|
ztest_run_test_suite(websocket);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue