-
Notifications
You must be signed in to change notification settings - Fork 6.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tests: kernel: pipe: Add new test cases for pipe API rework
This commit adds new test cases for the pipe API rework. * pipe_basic.c: Sanity check for pipe operations. * pipe_concurrency.c: Test pipe operations with multiple threads. * pipe_stress.c: Test pipe operations under stress conditions. And moves the old pipe test cases to the deprecated folder. Signed-off-by: Måns Ansgariusson <[email protected]>
- Loading branch information
1 parent
ceeed22
commit c1f63fa
Showing
17 changed files
with
355 additions
and
12 deletions.
There are no files selected for viewing
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion
2
tests/kernel/pipe/pipe/testcase.yaml → ...kernel/pipe/deprecated/pipe/testcase.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
tests: | ||
kernel.pipe: | ||
kernel.deprecated.pipe: | ||
tags: | ||
- kernel | ||
- userspace | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.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}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
tests: | ||
kernel.deprecated.pipe.api: | ||
tags: | ||
- kernel | ||
- userspace |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
/* | ||
* Copyright (c) 2024 Måns Ansgariusson <[email protected]> | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
#include <stdint.h> | ||
#include <zephyr/kernel.h> | ||
#include <zephyr/ztest.h> | ||
#include <zephyr/random/random.h> | ||
|
||
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"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
/* | ||
* Copyright (c) 2024 Måns Ansgariusson <[email protected]> | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
#include <stdint.h> | ||
#include <zephyr/kernel.h> | ||
#include <zephyr/ztest.h> | ||
#include <zephyr/random/random.h> | ||
#include <zephyr/logging/log.h> | ||
|
||
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); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/* | ||
* Copyright (c) 2024 Måns Ansgariusson <[email protected]> | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
#include <stdint.h> | ||
#include <zephyr/ztest.h> | ||
#include <zephyr/kernel.h> | ||
#include <zephyr/ztress.h> | ||
#include <zephyr/logging/log.h> | ||
#include <zephyr/random/random.h> | ||
#include <zephyr/timing/timing.h> | ||
|
||
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); | ||
} |