tests: lib: ringbuffer: Update test to use ztress
Updated test to use stress testing framework instead of implementing own framework. Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
parent
4433953e34
commit
902cff3d62
3 changed files with 102 additions and 273 deletions
|
@ -1,4 +1,8 @@
|
|||
CONFIG_ZTEST=y
|
||||
CONFIG_ZTRESS=y
|
||||
CONFIG_TEST_EXTRA_STACKSIZE=1024
|
||||
CONFIG_IRQ_OFFLOAD=y
|
||||
CONFIG_RING_BUFFER=y
|
||||
CONFIG_TEST_RANDOM_GENERATOR=y
|
||||
CONFIG_ENTROPY_GENERATOR=y
|
||||
CONFIG_XOSHIRO_RANDOM_GENERATOR=y
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <ztest.h>
|
||||
#include <ztress.h>
|
||||
#include <sys/ring_buffer.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <random/rand32.h>
|
||||
|
@ -22,29 +23,12 @@
|
|||
#define VALUE 0xb
|
||||
#define TYPE 0xc
|
||||
|
||||
#define RINGBUFFER_API_ITEM 0
|
||||
#define RINGBUFFER_API_CPY 1
|
||||
#define RINGBUFFER_API_NOCPY 2
|
||||
|
||||
static K_THREAD_STACK_DEFINE(thread_low_stack, STACKSIZE);
|
||||
static struct k_thread thread_low_data;
|
||||
static K_THREAD_STACK_DEFINE(thread_high_stack, STACKSIZE);
|
||||
static struct k_thread thread_high_data;
|
||||
|
||||
static ZTEST_BMEM SYS_MUTEX_DEFINE(mutex);
|
||||
RING_BUF_ITEM_DECLARE_SIZE(ringbuf, RINGBUFFER);
|
||||
static uint32_t output[LENGTH];
|
||||
static uint32_t databuffer1[LENGTH];
|
||||
static uint32_t databuffer2[LENGTH];
|
||||
|
||||
static volatile int preempt_cnt;
|
||||
static volatile bool in_task;
|
||||
|
||||
typedef void (*test_ringbuf_action_t)(struct ring_buf *rbuf, bool reset);
|
||||
static test_ringbuf_action_t produce_fn;
|
||||
static test_ringbuf_action_t consume_fn;
|
||||
volatile int test_microdelay_cnt;
|
||||
|
||||
static void data_write(uint32_t *input)
|
||||
{
|
||||
sys_mutex_lock(&mutex, K_FOREVER);
|
||||
|
@ -75,27 +59,23 @@ static void data_read(uint32_t *output)
|
|||
}
|
||||
}
|
||||
|
||||
static void thread_entry_t1(void *p1, void *p2, void *p3)
|
||||
static bool user_handler(void *user_data, uint32_t iter_cnt, bool last, int prio)
|
||||
{
|
||||
for (int i = 0; i < LENGTH; i++) {
|
||||
databuffer1[i] = 1;
|
||||
uintptr_t id = (uintptr_t)user_data;
|
||||
uint32_t *buffer = id ? databuffer2 : databuffer1;
|
||||
|
||||
if (iter_cnt == 0) {
|
||||
for (int i = 0; i < LENGTH; i++) {
|
||||
buffer[i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Try to write data into the ringbuffer */
|
||||
data_write(databuffer1);
|
||||
data_write(buffer);
|
||||
/* Try to get data from the ringbuffer and check */
|
||||
data_read(output);
|
||||
}
|
||||
|
||||
static void thread_entry_t2(void *p1, void *p2, void *p3)
|
||||
{
|
||||
for (int i = 0; i < LENGTH; i++) {
|
||||
databuffer2[i] = 2;
|
||||
}
|
||||
/* Try to write data into the ringbuffer */
|
||||
data_write(databuffer2);
|
||||
/* Try to get data from the ringbuffer and check */
|
||||
data_read(output);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -111,124 +91,111 @@ static void thread_entry_t2(void *p1, void *p2, void *p3)
|
|||
*/
|
||||
void test_ringbuffer_concurrent(void)
|
||||
{
|
||||
int old_prio = k_thread_priority_get(k_current_get());
|
||||
int prio = 10;
|
||||
|
||||
k_thread_priority_set(k_current_get(), prio);
|
||||
|
||||
k_thread_create(&thread_high_data, thread_high_stack, STACKSIZE,
|
||||
thread_entry_t1,
|
||||
NULL, NULL, NULL,
|
||||
prio + 2, 0, K_NO_WAIT);
|
||||
k_thread_create(&thread_low_data, thread_low_stack, STACKSIZE,
|
||||
thread_entry_t2,
|
||||
NULL, NULL, NULL,
|
||||
prio + 2, 0, K_NO_WAIT);
|
||||
k_sleep(K_MSEC(10));
|
||||
|
||||
/* Wait for thread exiting */
|
||||
k_thread_join(&thread_low_data, K_FOREVER);
|
||||
k_thread_join(&thread_high_data, K_FOREVER);
|
||||
|
||||
|
||||
/* Revert priority of the main thread */
|
||||
k_thread_priority_set(k_current_get(), old_prio);
|
||||
ztress_set_timeout(K_MSEC(1000));
|
||||
ZTRESS_EXECUTE(ZTRESS_THREAD(user_handler, (void *)0, 0, 0, Z_TIMEOUT_TICKS(20)),
|
||||
ZTRESS_THREAD(user_handler, (void *)1, 0, 10, Z_TIMEOUT_TICKS(20)));
|
||||
}
|
||||
|
||||
static void produce_cpy(struct ring_buf *rbuf, bool reset)
|
||||
static bool produce_cpy(void *user_data, uint32_t iter_cnt, bool last, int prio)
|
||||
{
|
||||
static int cnt;
|
||||
uint8_t buf[3];
|
||||
uint32_t len;
|
||||
|
||||
if (reset) {
|
||||
if (iter_cnt == 0) {
|
||||
cnt = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < sizeof(buf); i++) {
|
||||
buf[i] = (uint8_t)cnt++;
|
||||
}
|
||||
|
||||
len = ring_buf_put(rbuf, buf, sizeof(buf));
|
||||
len = ring_buf_put(&ringbuf, buf, sizeof(buf));
|
||||
cnt -= (sizeof(buf) - len);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void consume_cpy(struct ring_buf *rbuf, bool reset)
|
||||
static bool consume_cpy(void *user_data, uint32_t iter_cnt, bool last, int prio)
|
||||
{
|
||||
static int cnt;
|
||||
uint8_t buf[3];
|
||||
uint32_t len;
|
||||
|
||||
if (reset) {
|
||||
if (iter_cnt == 0) {
|
||||
cnt = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
len = ring_buf_get(rbuf, buf, sizeof(buf));
|
||||
len = ring_buf_get(&ringbuf, buf, sizeof(buf));
|
||||
for (int i = 0; i < len; i++) {
|
||||
zassert_equal(buf[i], (uint8_t)cnt, NULL);
|
||||
cnt++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void produce_item(struct ring_buf *rbuf, bool reset)
|
||||
static bool produce_item(void *user_data, uint32_t cnt, bool last, int prio)
|
||||
{
|
||||
int err;
|
||||
static uint16_t cnt;
|
||||
static uint32_t pcnt;
|
||||
uint32_t buf[2];
|
||||
|
||||
if (reset) {
|
||||
cnt = 0;
|
||||
return;
|
||||
if (cnt == 0) {
|
||||
pcnt = 0;
|
||||
}
|
||||
|
||||
err = ring_buf_item_put(rbuf, cnt++, VALUE, buf, 2);
|
||||
(void)err;
|
||||
err = ring_buf_item_put(&ringbuf, (uint16_t)pcnt, VALUE, buf, 2);
|
||||
if (err == 0) {
|
||||
pcnt++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void consume_item(struct ring_buf *rbuf, bool reset)
|
||||
static bool consume_item(void *user_data, uint32_t cnt, bool last, int prio)
|
||||
{
|
||||
int err;
|
||||
static uint16_t cnt;
|
||||
static uint32_t pcnt;
|
||||
uint32_t data[2];
|
||||
uint16_t type;
|
||||
uint8_t value;
|
||||
uint8_t size32 = ARRAY_SIZE(data);
|
||||
|
||||
if (reset) {
|
||||
cnt = 0;
|
||||
return;
|
||||
if (cnt == 0) {
|
||||
pcnt = 0;
|
||||
}
|
||||
|
||||
err = ring_buf_item_get(rbuf, &type, &value, data, &size32);
|
||||
err = ring_buf_item_get(&ringbuf, &type, &value, data, &size32);
|
||||
if (err == 0) {
|
||||
zassert_equal(type, cnt++, NULL);
|
||||
zassert_equal(value, VALUE, NULL);
|
||||
zassert_equal(type, (uint16_t)pcnt, NULL);
|
||||
pcnt++;
|
||||
} else if (err == -EMSGSIZE) {
|
||||
zassert_true(false, NULL);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void produce(struct ring_buf *rbuf, bool reset)
|
||||
static bool produce(void *user_data, uint32_t iter_cnt, bool last, int prio)
|
||||
{
|
||||
static int cnt;
|
||||
static int wr = 8;
|
||||
uint32_t len;
|
||||
uint8_t *data;
|
||||
|
||||
if (reset) {
|
||||
if (iter_cnt == 0) {
|
||||
cnt = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
len = ring_buf_put_claim(rbuf, &data, wr);
|
||||
len = ring_buf_put_claim(&ringbuf, &data, wr);
|
||||
if (len == 0) {
|
||||
len = ring_buf_put_claim(rbuf, &data, wr);
|
||||
len = ring_buf_put_claim(&ringbuf, &data, wr);
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
|
@ -240,30 +207,31 @@ static void produce(struct ring_buf *rbuf, bool reset)
|
|||
wr = 8;
|
||||
}
|
||||
|
||||
int err = ring_buf_put_finish(rbuf, len);
|
||||
int err = ring_buf_put_finish(&ringbuf, len);
|
||||
|
||||
zassert_equal(err, 0, "cnt: %d", cnt);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void consume(struct ring_buf *rbuf, bool reset)
|
||||
static bool consume(void *user_data, uint32_t iter_cnt, bool last, int prio)
|
||||
{
|
||||
static int rd = 8;
|
||||
static int cnt;
|
||||
uint32_t len;
|
||||
uint8_t *data;
|
||||
|
||||
if (reset) {
|
||||
if (iter_cnt == 0) {
|
||||
cnt = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
len = ring_buf_get_claim(rbuf, &data, rd);
|
||||
len = ring_buf_get_claim(&ringbuf, &data, rd);
|
||||
if (len == 0) {
|
||||
len = ring_buf_get_claim(rbuf, &data, rd);
|
||||
len = ring_buf_get_claim(&ringbuf, &data, rd);
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
|
@ -277,209 +245,72 @@ static void consume(struct ring_buf *rbuf, bool reset)
|
|||
rd = 8;
|
||||
}
|
||||
|
||||
int err = ring_buf_get_finish(rbuf, len);
|
||||
int err = ring_buf_get_finish(&ringbuf, len);
|
||||
|
||||
zassert_equal(err, 0, NULL);
|
||||
}
|
||||
|
||||
|
||||
static void produce_timeout(struct k_timer *timer)
|
||||
{
|
||||
struct ring_buf *rbuf = k_timer_user_data_get(timer);
|
||||
|
||||
if (in_task) {
|
||||
preempt_cnt++;
|
||||
}
|
||||
|
||||
produce_fn(rbuf, false);
|
||||
}
|
||||
|
||||
static void consume_timeout(struct k_timer *timer)
|
||||
{
|
||||
struct ring_buf *rbuf = k_timer_user_data_get(timer);
|
||||
|
||||
if (in_task) {
|
||||
preempt_cnt++;
|
||||
}
|
||||
|
||||
consume_fn(rbuf, false);
|
||||
}
|
||||
|
||||
static void microdelay(int delay)
|
||||
{
|
||||
for (int i = 0; i < delay; i++) {
|
||||
test_microdelay_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Test is running 2 parts of ring buffer operations (producing, consuming) in
|
||||
* two different contexts. One is the thread context and second is k_timer
|
||||
* timeout interrupt which can preempt thread. The goal of this test is to
|
||||
* provoke cases when one operation is preempted by another at multiple locations.
|
||||
* It is achieved by starting a timer and then busywaiting for similar time
|
||||
* before starting an operation in the thread context. Number of thread context
|
||||
* preemptions is counted and test is considered valid if certain amount of
|
||||
* preemptions occurred.
|
||||
*
|
||||
* Ring buffer claims that it is thread safe and requires no additional locking
|
||||
* in single producer, single consumer case and this test aims to prove that.
|
||||
*
|
||||
* Depending on input parameter @p p2 thread context is used for producing or
|
||||
* consuming.
|
||||
*/
|
||||
static void thread_entry_spsc(void *p1, void *p2, void *p3)
|
||||
{
|
||||
struct ring_buf *rbuf = p1;
|
||||
uint32_t timeout = 6000;
|
||||
bool high_producer = (bool)p2;
|
||||
uint32_t start = k_uptime_get_32();
|
||||
struct k_timer timer;
|
||||
int i = 0;
|
||||
int backoff_us = MAX(100, 3 * (1000000 / CONFIG_SYS_CLOCK_TICKS_PER_SEC));
|
||||
k_timeout_t t = K_USEC(backoff_us);
|
||||
|
||||
k_timer_init(&timer,
|
||||
high_producer ? produce_timeout : consume_timeout,
|
||||
NULL);
|
||||
k_timer_user_data_set(&timer, rbuf);
|
||||
|
||||
preempt_cnt = 0;
|
||||
consume_fn(rbuf, true);
|
||||
produce_fn(rbuf, true);
|
||||
|
||||
while (k_uptime_get_32() < (start + timeout)) {
|
||||
int r = sys_rand32_get() % 200;
|
||||
|
||||
k_timer_start(&timer, t, K_NO_WAIT);
|
||||
k_busy_wait(backoff_us - 50 + i);
|
||||
microdelay(r);
|
||||
|
||||
in_task = true;
|
||||
if (high_producer) {
|
||||
consume_fn(rbuf, false);
|
||||
} else {
|
||||
produce_fn(rbuf, false);
|
||||
}
|
||||
in_task = false;
|
||||
|
||||
i++;
|
||||
if (i > 60) {
|
||||
i = 0;
|
||||
}
|
||||
|
||||
k_timer_status_sync(&timer);
|
||||
}
|
||||
|
||||
PRINT("preempted: %d\n", preempt_cnt);
|
||||
/* Test is tailored for qemu_x86 to generate enough number of preemptions
|
||||
* to validate that ring buffer is safe to be used without any locks in
|
||||
* single producer single consumer scenario.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_BOARD_QEMU_X86)) {
|
||||
zassert_true(preempt_cnt > 1500, "If thread operation was not preempted "
|
||||
"multiple times then we cannot have confidance that it "
|
||||
"validated the module properly. Platform should not be "
|
||||
"used in that case");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
extern uint32_t test_rewind_threshold;
|
||||
|
||||
/* Single producer, single consumer test */
|
||||
static void test_ringbuffer_spsc(bool higher_producer, int api_type)
|
||||
static void test_ztress(ztress_handler high_handler,
|
||||
ztress_handler low_handler,
|
||||
bool item_mode)
|
||||
{
|
||||
int old_prio = k_thread_priority_get(k_current_get());
|
||||
int prio = 10;
|
||||
uint32_t old_rewind_threshold = test_rewind_threshold;
|
||||
uint8_t buf[32];
|
||||
uint32_t buf32[32];
|
||||
uint32_t old_rewind_threshold = test_rewind_threshold;
|
||||
k_timeout_t timeout;
|
||||
|
||||
if (CONFIG_SYS_CLOCK_TICKS_PER_SEC < 100000) {
|
||||
ztest_test_skip();
|
||||
}
|
||||
|
||||
test_rewind_threshold = 64;
|
||||
|
||||
switch (api_type) {
|
||||
case RINGBUFFER_API_ITEM:
|
||||
test_rewind_threshold = 256;
|
||||
if (item_mode) {
|
||||
ring_buf_init(&ringbuf, ARRAY_SIZE(buf32), buf32);
|
||||
consume_fn = consume_item;
|
||||
produce_fn = produce_item;
|
||||
break;
|
||||
case RINGBUFFER_API_NOCPY:
|
||||
} else {
|
||||
ring_buf_init(&ringbuf, ARRAY_SIZE(buf), buf);
|
||||
consume_fn = consume;
|
||||
produce_fn = produce;
|
||||
break;
|
||||
case RINGBUFFER_API_CPY:
|
||||
ring_buf_init(&ringbuf, ARRAY_SIZE(buf), buf);
|
||||
consume_fn = consume_cpy;
|
||||
produce_fn = produce_cpy;
|
||||
break;
|
||||
default:
|
||||
zassert_true(false, NULL);
|
||||
}
|
||||
|
||||
k_thread_priority_set(k_current_get(), prio);
|
||||
/* Timeout after 5 seconds. */
|
||||
timeout = (CONFIG_SYS_CLOCK_TICKS_PER_SEC < 10000) ? K_MSEC(1000) : K_MSEC(10000);
|
||||
|
||||
k_thread_create(&thread_high_data, thread_high_stack, STACKSIZE,
|
||||
thread_entry_spsc,
|
||||
&ringbuf, (void *)higher_producer, NULL,
|
||||
prio + 1, 0, K_NO_WAIT);
|
||||
k_sleep(K_MSEC(10));
|
||||
|
||||
/* Wait for thread exiting */
|
||||
k_thread_join(&thread_high_data, K_FOREVER);
|
||||
|
||||
|
||||
/* Revert priority of the main thread */
|
||||
k_thread_priority_set(k_current_get(), old_prio);
|
||||
ztress_set_timeout(timeout);
|
||||
ZTRESS_EXECUTE(ZTRESS_THREAD(high_handler, NULL, 0, 0, Z_TIMEOUT_TICKS(20)),
|
||||
ZTRESS_THREAD(low_handler, NULL, 0, 2000, Z_TIMEOUT_TICKS(20)));
|
||||
test_rewind_threshold = old_rewind_threshold;
|
||||
|
||||
}
|
||||
|
||||
/* Zero-copy API. Test is validating single producer, single consumer where
|
||||
* producer has higher priority context which can preempt consumer.
|
||||
*/
|
||||
void test_ringbuffer_shpsc(void)
|
||||
void test_ringbuffer_stress(ztress_handler produce_handler,
|
||||
ztress_handler consume_handler,
|
||||
bool item_mode)
|
||||
{
|
||||
test_ringbuffer_spsc(true, RINGBUFFER_API_NOCPY);
|
||||
PRINT("Producing interrupts consuming\n");
|
||||
test_ztress(produce_handler, consume_handler, item_mode);
|
||||
|
||||
PRINT("Consuming interrupts producing\n");
|
||||
test_ztress(consume_handler, produce_handler, item_mode);
|
||||
}
|
||||
|
||||
/* Zero-copy API. Test is validating single producer, single consumer where
|
||||
* consumer has higher priority context which can preempt producer.
|
||||
/* Zero-copy API. Test is validating single producer, single consumer from
|
||||
* different priorities.
|
||||
*/
|
||||
void test_ringbuffer_spshc(void)
|
||||
void test_ringbuffer_zerocpy_stress(void)
|
||||
{
|
||||
test_ringbuffer_spsc(false, RINGBUFFER_API_NOCPY);
|
||||
test_ringbuffer_stress(produce, consume, false);
|
||||
}
|
||||
|
||||
/* Copy API. Test is validating single producer, single consumer where
|
||||
* producer has higher priority context which can preempt consumer.
|
||||
/* Copy API. Test is validating single producer, single consumer from
|
||||
* different priorities.
|
||||
*/
|
||||
void test_ringbuffer_cpy_shpsc(void)
|
||||
void test_ringbuffer_cpy_stress(void)
|
||||
{
|
||||
test_ringbuffer_spsc(true, RINGBUFFER_API_CPY);
|
||||
test_ringbuffer_stress(produce_cpy, consume_cpy, false);
|
||||
}
|
||||
|
||||
/* Copy API. Test is validating single producer, single consumer where
|
||||
* consumer has higher priority context which can preempt producer.
|
||||
/* Item API. Test is validating single producer, single consumer from
|
||||
* different priorities.
|
||||
*/
|
||||
void test_ringbuffer_cpy_spshc(void)
|
||||
void test_ringbuffer_item_stress(void)
|
||||
{
|
||||
test_ringbuffer_spsc(false, RINGBUFFER_API_CPY);
|
||||
}
|
||||
/* Item API. Test is validating single producer, single consumer where producer
|
||||
* has higher priority context which can preempt consumer.
|
||||
*/
|
||||
void test_ringbuffer_item_shpsc(void)
|
||||
{
|
||||
test_ringbuffer_spsc(true, RINGBUFFER_API_ITEM);
|
||||
}
|
||||
|
||||
/* Item API. Test is validating single producer, single consumer where consumer
|
||||
* has higher priority context which can preempt producer.
|
||||
*/
|
||||
void test_ringbuffer_item_spshc(void)
|
||||
{
|
||||
test_ringbuffer_spsc(false, RINGBUFFER_API_ITEM);
|
||||
test_ringbuffer_stress(produce_item, consume_item, true);
|
||||
}
|
||||
|
|
|
@ -53,12 +53,9 @@ RING_BUF_ITEM_DECLARE_POW2(ring_buf1, 8);
|
|||
#define DATA_MAX_SIZE 3
|
||||
#define POW 2
|
||||
extern void test_ringbuffer_concurrent(void);
|
||||
extern void test_ringbuffer_shpsc(void);
|
||||
extern void test_ringbuffer_spshc(void);
|
||||
extern void test_ringbuffer_cpy_shpsc(void);
|
||||
extern void test_ringbuffer_cpy_spshc(void);
|
||||
extern void test_ringbuffer_item_shpsc(void);
|
||||
extern void test_ringbuffer_item_spshc(void);
|
||||
extern void test_ringbuffer_zerocpy_stress(void);
|
||||
extern void test_ringbuffer_cpy_stress(void);
|
||||
extern void test_ringbuffer_item_stress(void);
|
||||
/**
|
||||
* @brief Test APIs of ring buffer
|
||||
*
|
||||
|
@ -1058,12 +1055,9 @@ void test_main(void)
|
|||
ztest_unit_test(test_reset),
|
||||
ztest_unit_test(test_ringbuffer_performance),
|
||||
ztest_unit_test(test_ringbuffer_concurrent),
|
||||
ztest_unit_test(test_ringbuffer_shpsc),
|
||||
ztest_unit_test(test_ringbuffer_spshc),
|
||||
ztest_unit_test(test_ringbuffer_cpy_shpsc),
|
||||
ztest_unit_test(test_ringbuffer_cpy_spshc),
|
||||
ztest_unit_test(test_ringbuffer_item_shpsc),
|
||||
ztest_unit_test(test_ringbuffer_item_spshc)
|
||||
ztest_unit_test(test_ringbuffer_zerocpy_stress),
|
||||
ztest_unit_test(test_ringbuffer_cpy_stress),
|
||||
ztest_unit_test(test_ringbuffer_item_stress)
|
||||
);
|
||||
ztest_run_test_suite(test_ringbuffer_api);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue