Skip to content

Commit

Permalink
tests: socket: socketpair: tests for socketpair(2) syscall
Browse files Browse the repository at this point in the history
Tests for issue #24366

Signed-off-by: Christopher Friedt <chrisfriedt@gmail.com>
  • Loading branch information
cfriedt authored and carlescufi committed May 10, 2020
1 parent 09f957c commit 3bfc765
Show file tree
Hide file tree
Showing 14 changed files with 1,224 additions and 3 deletions.
1 change: 1 addition & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,7 @@
/tests/net/lib/http_header_fields/ @jukkar @tbursztyka
/tests/net/lib/mqtt_packet/ @jukkar @tbursztyka
/tests/net/lib/coap/ @rveerama1
/tests/net/socket/socketpair/ @cfriedt
/tests/net/socket/ @jukkar @tbursztyka @pfalcon
/tests/subsys/fs/ @nashif @wentongwu
/tests/subsys/settings/ @nvlsianpu
Expand Down
5 changes: 2 additions & 3 deletions subsys/net/lib/sockets/socketpair.c
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ static ssize_t spair_write(void *obj, const void *buffer, size_t count)
*/
static ssize_t spair_read(void *obj, void *buffer, size_t count)
{
ssize_t res;
int res;

bool is_connected;
size_t avail;
Expand Down Expand Up @@ -783,7 +783,7 @@ static int zsock_poll_update_ctx(struct spair *const spair,
if (pfd->events & ZSOCK_POLLOUT) {
if (!sock_is_connected(spair)) {
pfd->revents |= ZSOCK_POLLHUP;
goto check_pollin;
goto pollout_done;
}

remote = z_get_fd_obj(spair->remote,
Expand Down Expand Up @@ -850,7 +850,6 @@ static int zsock_poll_update_ctx(struct spair *const spair,

(*pev)++;

out:
if (remote != NULL && have_remote_sem) {
k_sem_give(&remote->sem);
}
Expand Down
8 changes: 8 additions & 0 deletions tests/net/socket/socketpair/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.13.1)
find_package(Zephyr HINTS $ENV{ZEPHYR_BASE})
project(socketpair)

FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})
34 changes: 34 additions & 0 deletions tests/net/socket/socketpair/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
CONFIG_MP_NUM_CPUS=1

# General config
CONFIG_NEWLIB_LIBC=y

# Networking config
CONFIG_NETWORKING=y
CONFIG_NET_TEST=y
CONFIG_NET_LOOPBACK=y
CONFIG_NET_IPV4=y
CONFIG_NET_IPV6=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETPAIR=y
CONFIG_NET_SOCKETPAIR_BUFFER_SIZE=64
CONFIG_NET_SOCKETS_POSIX_NAMES=y
# Defines fd_set size
CONFIG_POSIX_MAX_FDS=33

# Network driver config
CONFIG_TEST_RANDOM_GENERATOR=y

# Network address config
CONFIG_NET_CONFIG_SETTINGS=y
CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1"
CONFIG_NET_CONFIG_MY_IPV6_ADDR="2001:db8::1"

CONFIG_MAIN_STACK_SIZE=2048
CONFIG_ZTEST=y

# User mode requirements
CONFIG_TEST_USERSPACE=y
CONFIG_HEAP_MEM_POOL_SIZE=2048

CONFIG_QEMU_TICKLESS_WORKAROUND=y
93 changes: 93 additions & 0 deletions tests/net/socket/socketpair/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* Copyright (c) 2020 Friedt Professional Engineering Services, Inc
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <ztest.h>

/* in happy_path.c */
extern void test_socketpair_AF_LOCAL__SOCK_STREAM__0(void);
extern void test_socketpair_AF_UNIX__SOCK_STREAM__0(void);

/* in nonblock.c */
extern void test_socketpair_write_nonblock(void);
extern void test_socketpair_read_nonblock(void);

/* in block.c */
extern void test_socketpair_write_block(void);
extern void test_socketpair_read_block(void);

/* in closed_ends.c */
extern void test_socketpair_close_one_end_and_write_to_the_other(void);
extern void test_socketpair_close_one_end_and_read_from_the_other(void);

/* in expected_failures.c */
extern void test_socketpair_expected_failures(void);

/* in unsupported_calls.c */
extern void test_socketpair_unsupported_calls(void);

/* in fcntl.c */
extern void test_socketpair_fcntl(void);

/* in poll.c */
extern void test_socketpair_poll_timeout(void);
extern void test_socketpair_poll_timeout_nonblocking(void);
extern void test_socketpair_poll_close_remote_end_POLLIN(void);
extern void test_socketpair_poll_close_remote_end_POLLOUT(void);
extern void test_socketpair_poll_immediate_data(void);
extern void test_socketpair_poll_delayed_data(void);

void test_main(void)
{
k_thread_system_pool_assign(k_current_get());

ztest_test_suite(
socketpair,
ztest_user_unit_test(test_socketpair_AF_LOCAL__SOCK_STREAM__0),
ztest_user_unit_test(test_socketpair_AF_UNIX__SOCK_STREAM__0),

ztest_user_unit_test(test_socketpair_write_nonblock),
ztest_user_unit_test(test_socketpair_read_nonblock),

ztest_user_unit_test(
test_socketpair_close_one_end_and_write_to_the_other),
ztest_user_unit_test(
test_socketpair_close_one_end_and_read_from_the_other),

ztest_user_unit_test(test_socketpair_expected_failures),

ztest_user_unit_test(test_socketpair_unsupported_calls),

ztest_user_unit_test(test_socketpair_fcntl),

ztest_user_unit_test(test_socketpair_poll_timeout),
ztest_user_unit_test(
test_socketpair_poll_timeout_nonblocking),
ztest_user_unit_test(test_socketpair_poll_immediate_data)
);

ztest_run_test_suite(socketpair);

/* 20200509: @cfriedt: experiencing some issues with userspace thread
* / memory permissions that will require some sorting out. Currently
* these tests succeeed for native_posix_64.
*
* This feature is experimental at present.
*/
#if 0
ztest_test_suite(
socketpair_only_kernel,
ztest_user_unit_test(test_socketpair_write_block),
ztest_user_unit_test(test_socketpair_read_block),
ztest_user_unit_test(test_socketpair_poll_delayed_data),
ztest_user_unit_test(
test_socketpair_poll_close_remote_end_POLLIN),
ztest_user_unit_test(
test_socketpair_poll_close_remote_end_POLLOUT)
);

ztest_run_test_suite(socketpair_only_kernel);
#endif
}
194 changes: 194 additions & 0 deletions tests/net/socket/socketpair/src/test_socketpair_block.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
/*
* Copyright (c) 2020 Friedt Professional Engineering Services, Inc
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <fcntl.h>
#include <string.h>

#include <logging/log.h>
LOG_MODULE_REGISTER(net_test, CONFIG_NET_SOCKETS_LOG_LEVEL);

#include <net/socket.h>
#include <sys/util.h>
#include <posix/unistd.h>

#include <ztest_assert.h>

#undef read
#define read(fd, buf, len) zsock_recv(fd, buf, len, 0)

#undef write
#define write(fd, buf, len) zsock_send(fd, buf, len, 0)

#define TIMEOUT K_FOREVER

struct ctx {
/* true if test is write_block(), false if test is read_block() */
bool write;
/* the secondary-side socket of the socketpair */
int fd;
/* the count of the main thread */
atomic_t m;
/* the count of the secondary thread */
size_t n;
/* true when secondary thread is done */
bool done;
/* true if both main and secondary thread should immediately quit */
bool fail;
/* thread id of the secondary thread */
k_tid_t tid;
};
ZTEST_BMEM struct ctx ctx;
#define STACK_SIZE 512
/* thread structure for secondary thread */
ZTEST_BMEM struct k_thread th;
/* stack for the secondary thread */
static K_THREAD_STACK_DEFINE(th_stack, STACK_SIZE);

static void th_fun(void *arg0, void *arg1, void *arg2)
{
(void) arg0;
(void) arg1;
(void) arg2;

int res;
char c = '\0';

LOG_DBG("secondary thread running");

while (true) {
if (ctx.write) {
LOG_DBG("ctx.m: %u", ctx.m);
if (atomic_get(&ctx.m)
< CONFIG_NET_SOCKETPAIR_BUFFER_SIZE) {
continue;
}
LOG_DBG("ready to read!");
} else {
LOG_DBG("sleeping for 100ms..");
k_sleep(K_MSEC(100));
LOG_DBG("ready to write!");
}
break;
}

LOG_DBG("%sing 1 byte %s fd %d", ctx.write ? "read" : "write",
ctx.write ? "from" : "to", ctx.fd);
if (ctx.write) {
res = read(ctx.fd, &c, 1);
} else {
res = write(ctx.fd, "x", 1);
}
if (-1 == res || 1 != res) {
LOG_DBG("%s(2) failed: %d", ctx.write ? "read" : "write",
errno);
goto out;
}
LOG_DBG("%s 1 byte", ctx.write ? "read" : "wrote");
ctx.n = 1;

out:
ctx.done = true;

LOG_DBG("terminating..");
}

void test_socketpair_write_block(void)
{
int res;
int sv[2] = {-1, -1};

LOG_DBG("creating socketpair..");
res = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
zassert_equal(res, 0, "socketpair(2) failed: %d", errno);

for (size_t i = 0; i < 2; ++i) {

LOG_DBG("data direction %d -> %d", sv[i], sv[(!i) & 1]);

LOG_DBG("setting up context");
memset(&ctx, 0, sizeof(ctx));
ctx.write = true;
ctx.fd = sv[(!i) & 1];

LOG_DBG("creating secondary thread");
ctx.tid = k_thread_create(&th, th_stack,
STACK_SIZE, th_fun,
NULL, NULL, NULL,
CONFIG_MAIN_THREAD_PRIORITY,
K_INHERIT_PERMS, K_NO_WAIT);
LOG_DBG("created secondary thread %p", ctx.tid);

/* fill up the buffer */
for (ctx.m = 0; atomic_get(&ctx.m)
< CONFIG_NET_SOCKETPAIR_BUFFER_SIZE;) {

res = write(sv[i], "x", 1);
zassert_not_equal(res, -1, "write(2) failed: %d",
errno);
zassert_equal(res, 1, "wrote %d bytes instead of 1",
res);

atomic_inc(&ctx.m);
LOG_DBG("have written %u bytes", ctx.m);
}

/* try to write one more byte */
LOG_DBG("writing to fd %d", sv[i]);
res = write(sv[i], "x", 1);
zassert_not_equal(res, -1, "write(2) failed: %d", errno);
zassert_equal(res, 1, "wrote %d bytes instead of 1", res);

LOG_DBG("success!");

k_thread_join(&th, K_MSEC(1000));
}

close(sv[0]);
close(sv[1]);
}

void test_socketpair_read_block(void)
{
int res;
int sv[2] = {-1, -1};
char x;

LOG_DBG("creating socketpair..");
res = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
zassert_equal(res, 0, "socketpair(2) failed: %d", errno);

for (size_t i = 0; i < 2; ++i) {

LOG_DBG("data direction %d -> %d", sv[i], sv[(!i) & 1]);

LOG_DBG("setting up context");
memset(&ctx, 0, sizeof(ctx));
ctx.write = false;
ctx.fd = sv[(!i) & 1];

LOG_DBG("creating secondary thread");
ctx.tid = k_thread_create(&th, th_stack,
STACK_SIZE, th_fun,
NULL, NULL, NULL,
CONFIG_MAIN_THREAD_PRIORITY,
K_INHERIT_PERMS, K_NO_WAIT);
LOG_DBG("created secondary thread %p", ctx.tid);

/* try to read one byte */
LOG_DBG("reading from fd %d", sv[i]);
x = '\0';
res = read(sv[i], &x, 1);
zassert_not_equal(res, -1, "read(2) failed: %d", errno);
zassert_equal(res, 1, "read %d bytes instead of 1", res);

LOG_DBG("success!");

k_thread_join(&th, K_MSEC(1000));
}

close(sv[0]);
close(sv[1]);
}
Loading

0 comments on commit 3bfc765

Please sign in to comment.