diff --git a/tests/kernel/pipe/pipe/CMakeLists.txt b/tests/kernel/pipe/deprecated/pipe/CMakeLists.txt similarity index 100% rename from tests/kernel/pipe/pipe/CMakeLists.txt rename to tests/kernel/pipe/deprecated/pipe/CMakeLists.txt diff --git a/tests/kernel/pipe/pipe/prj.conf b/tests/kernel/pipe/deprecated/pipe/prj.conf similarity index 100% rename from tests/kernel/pipe/pipe/prj.conf rename to tests/kernel/pipe/deprecated/pipe/prj.conf diff --git a/tests/kernel/pipe/pipe/src/main.c b/tests/kernel/pipe/deprecated/pipe/src/main.c similarity index 100% rename from tests/kernel/pipe/pipe/src/main.c rename to tests/kernel/pipe/deprecated/pipe/src/main.c diff --git a/tests/kernel/pipe/pipe/src/test_pipe.c b/tests/kernel/pipe/deprecated/pipe/src/test_pipe.c similarity index 100% rename from tests/kernel/pipe/pipe/src/test_pipe.c rename to tests/kernel/pipe/deprecated/pipe/src/test_pipe.c diff --git a/tests/kernel/pipe/pipe/testcase.yaml b/tests/kernel/pipe/deprecated/pipe/testcase.yaml similarity index 74% rename from tests/kernel/pipe/pipe/testcase.yaml rename to tests/kernel/pipe/deprecated/pipe/testcase.yaml index 9d3382e44873dc5..76658b6757d4264 100644 --- a/tests/kernel/pipe/pipe/testcase.yaml +++ b/tests/kernel/pipe/deprecated/pipe/testcase.yaml @@ -1,5 +1,5 @@ tests: - kernel.pipe: + kernel.deprecated.pipe: tags: - kernel - userspace diff --git a/tests/kernel/pipe/deprecated/pipe_api/CMakeLists.txt b/tests/kernel/pipe/deprecated/pipe_api/CMakeLists.txt new file mode 100644 index 000000000000000..fbaf5f15e118074 --- /dev/null +++ b/tests/kernel/pipe/deprecated/pipe_api/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(pipe_api) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/kernel/pipe/deprecated/pipe_api/prj.conf b/tests/kernel/pipe/deprecated/pipe_api/prj.conf new file mode 100644 index 000000000000000..d080e2fbdbd8293 --- /dev/null +++ b/tests/kernel/pipe/deprecated/pipe_api/prj.conf @@ -0,0 +1,7 @@ +CONFIG_ZTEST=y +CONFIG_IRQ_OFFLOAD=y +CONFIG_TEST_USERSPACE=y +CONFIG_DYNAMIC_OBJECTS=y +CONFIG_MP_MAX_NUM_CPUS=1 +CONFIG_ZTEST_FATAL_HOOK=y +CONFIG_PIPES=y diff --git a/tests/kernel/pipe/pipe_api/src/main.c b/tests/kernel/pipe/deprecated/pipe_api/src/main.c similarity index 100% rename from tests/kernel/pipe/pipe_api/src/main.c rename to tests/kernel/pipe/deprecated/pipe_api/src/main.c diff --git a/tests/kernel/pipe/pipe_api/src/test_pipe_avail.c b/tests/kernel/pipe/deprecated/pipe_api/src/test_pipe_avail.c similarity index 100% rename from tests/kernel/pipe/pipe_api/src/test_pipe_avail.c rename to tests/kernel/pipe/deprecated/pipe_api/src/test_pipe_avail.c diff --git a/tests/kernel/pipe/pipe_api/src/test_pipe_contexts.c b/tests/kernel/pipe/deprecated/pipe_api/src/test_pipe_contexts.c similarity index 100% rename from tests/kernel/pipe/pipe_api/src/test_pipe_contexts.c rename to tests/kernel/pipe/deprecated/pipe_api/src/test_pipe_contexts.c diff --git a/tests/kernel/pipe/pipe_api/src/test_pipe_fail.c b/tests/kernel/pipe/deprecated/pipe_api/src/test_pipe_fail.c similarity index 100% rename from tests/kernel/pipe/pipe_api/src/test_pipe_fail.c rename to tests/kernel/pipe/deprecated/pipe_api/src/test_pipe_fail.c diff --git a/tests/kernel/pipe/deprecated/pipe_api/testcase.yaml b/tests/kernel/pipe/deprecated/pipe_api/testcase.yaml new file mode 100644 index 000000000000000..1564321cb7339f1 --- /dev/null +++ b/tests/kernel/pipe/deprecated/pipe_api/testcase.yaml @@ -0,0 +1,5 @@ +tests: + kernel.deprecated.pipe.api: + tags: + - kernel + - userspace diff --git a/tests/kernel/pipe/pipe_api/CMakeLists.txt b/tests/kernel/pipe/pipe_api/CMakeLists.txt index fbaf5f15e118074..7f0e871daba43b8 100644 --- a/tests/kernel/pipe/pipe_api/CMakeLists.txt +++ b/tests/kernel/pipe/pipe_api/CMakeLists.txt @@ -1,8 +1,12 @@ -# SPDX-License-Identifier: Apache-2.0 +cmake_minimum_required(VERSION 3.13.1) -cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(pipe_api) -FILE(GLOB app_sources src/*.c) -target_sources(app PRIVATE ${app_sources}) +project(app) + +target_sources(app + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/src/basic.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/stress.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/concurrency.c +) diff --git a/tests/kernel/pipe/pipe_api/prj.conf b/tests/kernel/pipe/pipe_api/prj.conf index d080e2fbdbd8293..238fe5eacc59362 100644 --- a/tests/kernel/pipe/pipe_api/prj.conf +++ b/tests/kernel/pipe/pipe_api/prj.conf @@ -1,7 +1,9 @@ CONFIG_ZTEST=y -CONFIG_IRQ_OFFLOAD=y -CONFIG_TEST_USERSPACE=y -CONFIG_DYNAMIC_OBJECTS=y -CONFIG_MP_MAX_NUM_CPUS=1 -CONFIG_ZTEST_FATAL_HOOK=y -CONFIG_PIPES=y +CONFIG_ZTRESS=y + +CONFIG_ZTEST_STACK_SIZE=4096 +CONFIG_HEAP_MEM_POOL_SIZE=2048 +CONFIG_MAIN_STACK_SIZE=4096 + +CONFIG_ENTROPY_GENERATOR=y +CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/kernel/pipe/pipe_api/src/basic.c b/tests/kernel/pipe/pipe_api/src/basic.c new file mode 100644 index 000000000000000..f980f2a5ee56335 --- /dev/null +++ b/tests/kernel/pipe/pipe_api/src/basic.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2024 Måns Ansgariusson + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include + +ZTEST_SUITE(k_pipe_basic, NULL, NULL, NULL, NULL, NULL); + +static void mkrandom(uint8_t *buffer, size_t size) +{ + sys_rand_get(buffer, size); +} + +K_PIPE_DEFINE(test_define, 256, 4); + +ZTEST(k_pipe_basic, test_init) +{ + struct k_pipe pipe; + uint8_t buffer[10]; + + k_pipe_init(&pipe, buffer, sizeof(buffer)); + zassert_true(pipe.flags == PIPE_FLAG_OPEN, "pipe.flags should be k_pipe_FLAG_OPEN"); +} + +ZTEST(k_pipe_basic, test_write_read_one) +{ + struct k_pipe pipe; + uint8_t buffer[10]; + uint8_t data = 0x55; + uint8_t read_data; + + k_pipe_init(&pipe, buffer, sizeof(buffer)); + zassert_true(k_pipe_write(&pipe, &data, 1, K_NO_WAIT) == 1, "k_pipe_write should return 1"); + zassert_true(k_pipe_read(&pipe, &read_data, 1, K_NO_WAIT) == 1, + "k_pipe_read should return 1"); + zassert_true(read_data == data, "read_data should be equal to data"); +} + +ZTEST(k_pipe_basic, test_write_read_multiple) +{ + struct k_pipe pipe; + uint8_t buffer[10]; + uint8_t data = 0x55; + uint8_t read_data; + + k_pipe_init(&pipe, buffer, sizeof(buffer)); + zassert_true(k_pipe_write(&pipe, &data, 1, K_NO_WAIT) == 1, "k_pipe_write should return 1"); + zassert_true(k_pipe_write(&pipe, &data, 1, K_NO_WAIT) == 1, "k_pipe_write should return 1"); + zassert_true(k_pipe_read(&pipe, &read_data, 1, K_NO_WAIT) == 1, + "k_pipe_read should return 1"); + zassert_true(read_data == data, "read_data should be equal to data"); + zassert_true(k_pipe_read(&pipe, &read_data, 1, K_NO_WAIT) == 1, + "k_pipe_read should return 1"); + zassert_true(read_data == data, "read_data should be equal to data"); +} + +ZTEST(k_pipe_basic, test_write_full) +{ + struct k_pipe pipe; + uint8_t buffer[10]; + uint8_t data[10]; + + k_pipe_init(&pipe, buffer, sizeof(buffer)); + zassert_true(k_pipe_write(&pipe, data, sizeof(data), K_NO_WAIT) == 10, + "k_pipe_write should return 10"); + zassert_true(k_pipe_write(&pipe, data, sizeof(data), K_MSEC(1000)) == -EAGAIN, + "k_pipe_write should return 0"); +} + +ZTEST(k_pipe_basic, test_read_empty) +{ + struct k_pipe pipe; + uint8_t buffer[10]; + uint8_t read_data; + + k_pipe_init(&pipe, buffer, sizeof(buffer)); + zassert_true(k_pipe_read(&pipe, &read_data, 1, K_MSEC(1000)) == -EAGAIN, + "k_pipe_read should return 0"); +} + +ZTEST(k_pipe_basic, test_read_write_full) +{ + struct k_pipe pipe; + uint8_t buffer[10]; + uint8_t input[10]; + uint8_t res[10]; + + mkrandom(input, sizeof(input)); + k_pipe_init(&pipe, buffer, sizeof(buffer)); + zassert_true(k_pipe_write(&pipe, input, sizeof(input), K_NO_WAIT) == sizeof(input), + "k_pipe_write should return sizeof input"); + zassert_true(k_pipe_read(&pipe, res, sizeof(res), K_NO_WAIT) == sizeof(res), + "k_pipe_read should return sizeof res"); + zassert_true(memcmp(input, res, sizeof(input)) == 0, "input and res should be equal"); +} + +ZTEST(k_pipe_basic, test_read_write_wrapp_around) +{ + struct k_pipe pipe; + uint8_t buffer[12]; + uint8_t input[8]; + uint8_t res[16]; + + mkrandom(input, sizeof(input)); + k_pipe_init(&pipe, buffer, sizeof(buffer)); + zassert_true(k_pipe_write(&pipe, input, sizeof(input), K_NO_WAIT) == sizeof(input), + "k_pipe_write should return sizeof input"); + zassert_true(k_pipe_read(&pipe, res, 5, K_NO_WAIT) == 5, + "k_pipe_read should return sizeof res"); + zassert_true(memcmp(input, res, 5) == 0, "input and res should be equal"); + + zassert_true(k_pipe_write(&pipe, input, sizeof(input), K_NO_WAIT) == sizeof(input), + "k_pipe_write should return sizeof input"); + zassert_true(k_pipe_read(&pipe, res, sizeof(input) * 2 - 5, K_NO_WAIT) == + sizeof(input) * 2 - 5, + "read failed"); + + zassert_true(memcmp(&input[5], res, sizeof(input) - 5) == 0, + "input and res should be equal"); + zassert_true(memcmp(input, &res[sizeof(input) - 5], sizeof(input)) == 0, + "input and res should be equal"); +} + +ZTEST(k_pipe_basic, test_close) +{ + struct k_pipe pipe; + uint8_t buffer[12]; + uint8_t input[8]; + uint8_t res[16]; + + mkrandom(input, sizeof(input)); + k_pipe_init(&pipe, buffer, sizeof(buffer)); + zassert_true(k_pipe_write(&pipe, input, sizeof(input), K_NO_WAIT) == sizeof(input), + "k_pipe_write should return sizeof input"); + k_pipe_close(&pipe); + + zassert_true(k_pipe_write(&pipe, input, sizeof(input), K_NO_WAIT) == -EPIPE, + "k_pipe_write should return sizeof input"); + zassert_true(k_pipe_read(&pipe, res, 5, K_NO_WAIT) == 5, "k_pipe_read should return 0"); + zassert_true(memcmp(input, res, 5) == 0, "input and res should be equal"); + zassert_true(k_pipe_read(&pipe, res, 5, K_NO_WAIT) == 3, "k_pipe_read should return 0"); + zassert_true(k_pipe_read(&pipe, res, 5, K_NO_WAIT) == -EPIPE, + "k_pipe_read should return 0"); +} diff --git a/tests/kernel/pipe/pipe_api/src/concurrency.c b/tests/kernel/pipe/pipe_api/src/concurrency.c new file mode 100644 index 000000000000000..1abed18055826cc --- /dev/null +++ b/tests/kernel/pipe/pipe_api/src/concurrency.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2024 Måns Ansgariusson + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(k_pipe_concurrency, LOG_LEVEL_DBG); +ZTEST_SUITE(k_pipe_concurrency, NULL, NULL, NULL, NULL, NULL); + +#define STACK_SIZE 1024 + +static struct k_thread close_thread; +static K_THREAD_STACK_DEFINE(close_stack, STACK_SIZE); +static struct k_thread flush_thread; +static K_THREAD_STACK_DEFINE(flush_stack, STACK_SIZE); + +static void thread_close(void *arg1, void *arg2, void *arg3) +{ + k_pipe_close((struct k_pipe *)arg1); +} + +static void thread_flush(void *arg1, void *arg2, void *arg3) +{ + k_pipe_flush((struct k_pipe *)arg1); +} + +ZTEST(k_pipe_concurrency, test_close_on_read) +{ + k_tid_t tid; + struct k_pipe pipe; + uint8_t buffer[10]; + uint8_t res; + + k_pipe_init(&pipe, buffer, sizeof(buffer)); + tid = k_thread_create(&close_thread, close_stack, K_THREAD_STACK_SIZEOF(close_stack), + thread_close, &pipe, NULL, NULL, K_PRIO_COOP(0), 0, K_MSEC(100)); + zassert_true(tid, "k_thread_create failed"); + zassert_true(k_pipe_read(&pipe, &res, sizeof(res), K_MSEC(1000)) == -EPIPE, + "close_on_read should return -EPIPE"); + k_thread_join(&close_thread, K_FOREVER); +} + +ZTEST(k_pipe_concurrency, test_close_on_write) +{ + k_tid_t tid; + struct k_pipe pipe; + uint8_t buffer[10]; + uint8_t trash[10]; + + k_pipe_init(&pipe, buffer, sizeof(buffer)); + zassert_true(sizeof(trash) == k_pipe_write(&pipe, trash, sizeof(trash), K_MSEC(1000)), + "k_k_pipe_write should return number of bytes written"); + + tid = k_thread_create(&close_thread, close_stack, K_THREAD_STACK_SIZEOF(close_stack), + thread_close, &pipe, NULL, NULL, K_PRIO_COOP(0), 0, K_MSEC(100)); + zassert_true(tid, "k_thread_create failed"); + zassert_true(k_pipe_write(&pipe, trash, sizeof(trash), K_MSEC(1000)) == -EPIPE, + "close_on_write should return -EPIPE"); + k_thread_join(&close_thread, K_FOREVER); +} + +ZTEST(k_pipe_concurrency, test_flush_on_read) +{ + k_tid_t tid; + struct k_pipe pipe; + uint8_t buffer[10]; + uint8_t res; + + k_pipe_init(&pipe, buffer, sizeof(buffer)); + + tid = k_thread_create(&flush_thread, flush_stack, K_THREAD_STACK_SIZEOF(flush_stack), + thread_flush, &pipe, NULL, NULL, K_PRIO_COOP(0), 0, K_MSEC(100)); + zassert_true(tid, "k_thread_create failed"); + zassert_true(k_pipe_read(&pipe, &res, sizeof(res), K_MSEC(1000)) == -ECANCELED, + "flush on read should return -ECANCELED"); + k_thread_join(&flush_thread, K_FOREVER); +} + +ZTEST(k_pipe_concurrency, test_flush_on_write) +{ + k_tid_t tid; + struct k_pipe pipe; + uint8_t buffer[10]; + uint8_t trash[10]; + + k_pipe_init(&pipe, buffer, sizeof(buffer)); + zassert_true(sizeof(trash) == k_pipe_write(&pipe, trash, sizeof(trash), K_MSEC(1000)), + "k_k_pipe_write should return number of bytes written"); + + tid = k_thread_create(&flush_thread, flush_stack, K_THREAD_STACK_SIZEOF(flush_stack), + thread_flush, &pipe, NULL, NULL, K_PRIO_COOP(0), 0, K_MSEC(100)); + zassert_true(tid, "k_thread_create failed"); + zassert_true(k_pipe_write(&pipe, trash, sizeof(trash), K_MSEC(1000)) == -ECANCELED, + "flush on write should return -ECANCELED"); + k_thread_join(&flush_thread, K_FOREVER); +} diff --git a/tests/kernel/pipe/pipe_api/src/stress.c b/tests/kernel/pipe/pipe_api/src/stress.c new file mode 100644 index 000000000000000..4ac019b03c984a6 --- /dev/null +++ b/tests/kernel/pipe/pipe_api/src/stress.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2024 Måns Ansgariusson + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(k_k_pipe_stress, LOG_LEVEL_INF); + +ZTEST_SUITE(k_pipe_stress, NULL, NULL, NULL, NULL, NULL); + +ZTEST(k_pipe_stress, test_write) +{ + int rc; + struct k_pipe pipe; + size_t len = 512; + uint8_t buffer[len]; + uint8_t buf[len]; + size_t sent; + uint32_t start_cycles, end_cycles; + + k_pipe_init(&pipe, buffer, sizeof(buffer)); + start_cycles = k_uptime_get_32(); + sent = 0; + while (sent < len) { + rc = k_pipe_write(&pipe, &buf[sent], len - sent, K_FOREVER); + zassert_true(rc > 0, "k_k_pipe_write failed"); + sent += rc; + } + end_cycles = k_uptime_get_32(); + LOG_INF("Elapsed cycles: %u\n", end_cycles - start_cycles); +} + +ZTEST(k_pipe_stress, test_read) +{ + int rc; + struct k_pipe pipe; + size_t len = 512; + uint8_t buffer[len]; + uint8_t buf[len]; + size_t sent, read; + uint32_t start_cycles, end_cycles; + + k_pipe_init(&pipe, buffer, sizeof(buffer)); + start_cycles = k_uptime_get_32(); + for (int i = 0; i < 100000; i++) { + sent = 0; + while (sent < len) { + rc = k_pipe_write(&pipe, &buf[sent], len - sent, K_FOREVER); + zassert_true(rc > 0, "k_k_pipe_write failed"); + sent += rc; + } + read = 0; + while (read < len) { + rc = k_pipe_read(&pipe, &buf[read], len - read, K_FOREVER); + zassert_true(rc > 0, "k_k_pipe_write failed"); + read += rc; + } + } + end_cycles = k_uptime_get_32(); + LOG_INF("Elapsed cycles: %u\n", end_cycles - start_cycles); +}