summaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
authorCYFS <[email protected]>2026-06-11 14:41:40 +0800
committerRbb666 <[email protected]>2026-06-12 14:22:53 +0800
commit103d4c1d92f3844dfcf4473957593af3449bec06 (patch)
treefce4bd78b90e2eddb7f34958f18a134ee3637fb4 /components
parent23187dedaa0994960dc03e08c38a70fa4ca4d0d4 (diff)
utest: move lwp testcases to components/lwp
Signed-off-by: CYFS <[email protected]>
Diffstat (limited to 'components')
-rw-r--r--components/lwp/SConscript1
-rw-r--r--components/lwp/utest/Kconfig8
-rw-r--r--components/lwp/utest/SConscript13
-rw-r--r--components/lwp/utest/condvar_broadcast_tc.c190
-rw-r--r--components/lwp/utest/condvar_signal_tc.c156
-rw-r--r--components/lwp/utest/condvar_timedwait_tc.c108
6 files changed, 476 insertions, 0 deletions
diff --git a/components/lwp/SConscript b/components/lwp/SConscript
index 56279cb998..1c97444e51 100644
--- a/components/lwp/SConscript
+++ b/components/lwp/SConscript
@@ -57,4 +57,5 @@ if not GetDepend(['LWP_USING_RUNTIME']):
group = DefineGroup('lwProcess', src, depend = ['RT_USING_SMART'], CPPPATH = CPPPATH)
group = group + SConscript(os.path.join('vdso', 'SConscript'))
+group = group + SConscript(os.path.join('utest', 'SConscript'))
Return('group')
diff --git a/components/lwp/utest/Kconfig b/components/lwp/utest/Kconfig
new file mode 100644
index 0000000000..ac2900d93a
--- /dev/null
+++ b/components/lwp/utest/Kconfig
@@ -0,0 +1,8 @@
+menu "LWP Testcase"
+
+config RT_UTEST_LWP
+ bool "Enable LWP condvar test"
+ depends on RT_USING_SMART
+ default n
+
+endmenu
diff --git a/components/lwp/utest/SConscript b/components/lwp/utest/SConscript
new file mode 100644
index 0000000000..c7890d6be7
--- /dev/null
+++ b/components/lwp/utest/SConscript
@@ -0,0 +1,13 @@
+Import('rtconfig')
+from building import *
+
+cwd = GetCurrentDir()
+src = []
+CPPPATH = [cwd]
+
+if GetDepend(['RT_UTEST_LWP', 'RT_USING_SMART']):
+ src += ['condvar_timedwait_tc.c', 'condvar_broadcast_tc.c', 'condvar_signal_tc.c']
+
+group = DefineGroup('utestcases', src, depend = ['RT_USING_UTESTCASES'], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/components/lwp/utest/condvar_broadcast_tc.c b/components/lwp/utest/condvar_broadcast_tc.c
new file mode 100644
index 0000000000..234ae697a1
--- /dev/null
+++ b/components/lwp/utest/condvar_broadcast_tc.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2023-11-20 Shell add test suites
+ * 2026-03-19 cl2t Add standardized utest documentation block
+ */
+
+/**
+ * Test Case Name: Condition Variable Broadcast Test
+ *
+ * Test Objectives:
+ * - Verify that rt_condvar_broadcast() correctly wakes up all threads
+ * waiting on a condition variable.
+ * - Test core APIs: rt_condvar_broadcast(), rt_condvar_timedwait(),
+ * rt_mutex_take(), rt_mutex_release(), rt_mutex_get_owner().
+ *
+ * Test Scenarios:
+ * - Creates 8 worker threads, each acquiring a mutex and then waiting on
+ * a condition variable via rt_condvar_timedwait().
+ * - The main thread calls rt_condvar_broadcast() to wake all waiters.
+ * - Each woken thread verifies it re-acquired the mutex, increments a
+ * counter, and releases the mutex.
+ * - The main thread verifies all 8 threads were successfully woken.
+ *
+ * Verification Metrics:
+ * - All waiting threads must be woken after broadcast (waken_num == THREAD_NUM).
+ * - Each woken thread must hold the mutex (verified via rt_mutex_get_owner()).
+ * - rt_condvar_timedwait() must return 0 on successful wake.
+ * - Mutex release must succeed for each woken thread.
+ *
+ * Dependencies:
+ * - Software configuration: RT_USING_SMART must be enabled.
+ * - Environmental assumptions: The platform must support multi-threading
+ * with at least 8 concurrent threads.
+ *
+ * Expected Results:
+ * - Final output: "[ PASSED ] [ result ] testcase (testcases.ipc.condvar.broadcast)"
+ * - No assertion failures during test execution.
+ */
+
+#include "common.h"
+#include "rtconfig.h"
+#include "utest_assert.h"
+
+#include <rtdevice.h>
+#include <rtdef.h>
+
+static struct rt_mutex _local_mtx;
+static struct rt_condvar _local_cv;
+#define THREAD_NUM 8
+#define STACK_SIZE (0x2000)
+
+static volatile int start_num;
+static volatile int waken_num;
+
+static void thr_func(void *arg)
+{
+ int rc;
+ rt_mutex_t mutex = &_local_mtx;
+ rt_condvar_t cond = &_local_cv;
+ rt_mutex_take(mutex, RT_WAITING_FOREVER);
+
+ start_num++;
+ rc = rt_condvar_timedwait(cond, mutex, RT_KILLABLE, RT_WAITING_FOREVER);
+ if (rc != 0)
+ {
+ LOG_E("cond_wait returned %d\n", rc);
+ uassert_false(1);
+ return;
+ }
+
+ if (rt_mutex_get_owner(mutex) != rt_thread_self())
+ {
+ LOG_E("Should not be able to lock the mutex again");
+ uassert_false(1);
+ return;
+ }
+ else
+ {
+ uassert_true(1);
+ }
+ LOG_I("Thread was wakened and acquired the mutex again");
+ waken_num++;
+
+ if (rt_mutex_release(mutex) != 0)
+ {
+ LOG_E("Failed to release the mutex");
+ uassert_false(1);
+ return;
+ }
+ else
+ {
+ uassert_true(1);
+ }
+
+ return ;
+}
+
+static void *stack_addr[THREAD_NUM];
+
+static void condvar_broadcast_tc(void)
+{
+ rt_mutex_t mutex = &_local_mtx;
+ rt_condvar_t cond = &_local_cv;
+ struct rt_thread thread[THREAD_NUM];
+
+ for (size_t i = 0; i < THREAD_NUM; i++)
+ {
+ if (rt_thread_init(&thread[i], "utest", thr_func, RT_NULL,
+ stack_addr[i], STACK_SIZE, 25, 100) != 0)
+ {
+ LOG_E("Fail to create thread[%d]\n", i);
+ return;
+ }
+ rt_thread_startup(&thread[i]);
+ }
+
+ while (start_num < THREAD_NUM)
+ rt_thread_mdelay(1);
+
+ rt_mutex_take(mutex, RT_WAITING_FOREVER);
+ if (rt_condvar_broadcast(cond))
+ {
+ uassert_false(1);
+ return ;
+ }
+ rt_mutex_release(mutex);
+
+ rt_thread_mdelay(1);
+
+ if (waken_num < THREAD_NUM)
+ {
+ LOG_E("[Main thread] Not all waiters were wakened\n");
+ uassert_false(1);
+ return ;
+ }
+ else
+ {
+ utest_int_equal(waken_num, THREAD_NUM);
+ }
+ LOG_I("[Main thread] all waiters were wakened\n");
+
+ return;
+}
+
+static rt_err_t utest_tc_init(void)
+{
+ start_num = 0;
+ waken_num = 0;
+ if (rt_mutex_init(&_local_mtx, "utest", RT_IPC_FLAG_PRIO) != 0)
+ {
+ perror("pthread_mutex_init() error");
+ uassert_false(1);
+ return -1;
+ }
+
+ rt_condvar_init(&_local_cv, NULL);
+
+ for (size_t i = 0; i < THREAD_NUM; i++)
+ {
+ stack_addr[i] =
+ rt_pages_alloc_ext(rt_page_bits(STACK_SIZE), PAGE_ANY_AVAILABLE);
+ utest_int_not_equal(stack_addr[i], RT_NULL);
+ }
+ return RT_EOK;
+}
+
+static rt_err_t utest_tc_cleanup(void)
+{
+ rt_mutex_detach(&_local_mtx);
+ rt_condvar_detach(&_local_cv);
+
+ for (size_t i = 0; i < THREAD_NUM; i++)
+ {
+ rt_pages_free(stack_addr[i], rt_page_bits(STACK_SIZE));
+ stack_addr[i] = 0;
+ }
+ return RT_EOK;
+}
+
+static void testcase(void)
+{
+ UTEST_UNIT_RUN(condvar_broadcast_tc);
+}
+UTEST_TC_EXPORT(testcase, "testcases.ipc.condvar.broadcast", utest_tc_init,
+ utest_tc_cleanup, 10);
diff --git a/components/lwp/utest/condvar_signal_tc.c b/components/lwp/utest/condvar_signal_tc.c
new file mode 100644
index 0000000000..82129560eb
--- /dev/null
+++ b/components/lwp/utest/condvar_signal_tc.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2023-11-20 Shell add test suites
+ * 2026-03-19 cl2t Add standardized utest documentation block
+ */
+
+/**
+ * Test Case Name: Condition Variable Signal Test
+ *
+ * Test Objectives:
+ * - Verify that rt_condvar_signal() correctly wakes up a single thread
+ * waiting on a condition variable.
+ * - Test core APIs: rt_condvar_signal(), rt_condvar_timedwait(),
+ * rt_mutex_take(), rt_mutex_release(), rt_thread_create().
+ *
+ * Test Scenarios:
+ * - The main thread acquires a mutex, creates a waker thread, then waits
+ * on a condition variable with a 100-tick timeout.
+ * - The waker thread acquires the mutex and calls rt_condvar_signal() to
+ * wake the main thread.
+ * - The main thread verifies it was woken successfully and releases the
+ * mutex.
+ *
+ * Verification Metrics:
+ * - rt_condvar_signal() must return 0 on success.
+ * - rt_condvar_timedwait() must return 0 when signaled before timeout.
+ * - Timeout (-ETIMEDOUT) or interrupt (-EINTR) are acceptable non-fatal
+ * outcomes.
+ * - Mutex acquire and release must succeed without errors.
+ *
+ * Dependencies:
+ * - Software configuration: RT_USING_SMART must be enabled.
+ * - Environmental assumptions: The platform must support multi-threading.
+ *
+ * Expected Results:
+ * - Final output: "[ PASSED ] [ result ] testcase (testcases.ipc.condvar.signal)"
+ * - No assertion failures during test execution.
+ */
+
+#include "common.h"
+#include "utest_assert.h"
+
+#include <rtdevice.h>
+#include <rtdef.h>
+#define STACK_SIZE (0x2000)
+
+static struct rt_mutex _local_mtx;
+static struct rt_condvar _local_cv;
+
+static void waker_thr(void *param)
+{
+ int err;
+ rt_mutex_t mutex = &_local_mtx;
+ rt_condvar_t cond = &_local_cv;
+ rt_mutex_take(mutex, RT_WAITING_FOREVER);
+ err = rt_condvar_signal(cond);
+
+ if (err != 0)
+ {
+ LOG_E("errno=%d, ret=%d\n", errno, err);
+ LOG_E("rt_condvar_signal() error");
+ uassert_false(1);
+ }
+ else
+ {
+ uassert_false(0);
+ }
+ rt_mutex_release(mutex);
+
+ return;
+}
+
+static void condvar_signal_tc(void)
+{
+ rt_thread_t waker;
+ rt_mutex_t mutex = &_local_mtx;
+ rt_condvar_t cond = &_local_cv;
+ int err;
+
+ waker = rt_thread_create("waker", waker_thr, 0, STACK_SIZE, 25, 50);
+ uassert_not_null(waker);
+
+ if (rt_mutex_take(mutex, RT_WAITING_FOREVER) != 0)
+ {
+ LOG_E("pthread_mutex_lock() error");
+ uassert_false(1);
+ return;
+ }
+ else
+ {
+ uassert_false(0);
+ }
+
+ rt_thread_startup(waker);
+
+ err = rt_condvar_timedwait(cond, mutex, RT_KILLABLE, 100);
+ if (err != 0)
+ {
+ if (err == -EINTR || err == -ETIMEDOUT)
+ {
+ puts("wait timed out");
+ uassert_false(0);
+ }
+ else
+ {
+ LOG_E("errno=%d, ret=%d\n", errno, err);
+ LOG_E("pthread_cond_timedwait() error");
+ uassert_false(1);
+ }
+ }
+
+ err = rt_mutex_release(mutex);
+ if (err != 0)
+ {
+ LOG_E("errno=%d, ret=%d\n", errno, err);
+ LOG_E("rt_mutex_release() error");
+ uassert_false(1);
+ }
+ else
+ {
+ uassert_false(0);
+ }
+
+ return ;
+}
+
+static rt_err_t utest_tc_init(void)
+{
+ if (rt_mutex_init(&_local_mtx, "utest", RT_IPC_FLAG_PRIO) != 0)
+ {
+ perror("pthread_mutex_init() error");
+ uassert_false(1);
+ return -1;
+ }
+
+ rt_condvar_init(&_local_cv, NULL);
+ return RT_EOK;
+}
+
+static rt_err_t utest_tc_cleanup(void)
+{
+ rt_mutex_detach(&_local_mtx);
+ rt_condvar_detach(&_local_cv);
+ return RT_EOK;
+}
+
+static void testcase(void)
+{
+ UTEST_UNIT_RUN(condvar_signal_tc);
+}
+UTEST_TC_EXPORT(testcase, "testcases.ipc.condvar.signal", utest_tc_init, utest_tc_cleanup, 10);
diff --git a/components/lwp/utest/condvar_timedwait_tc.c b/components/lwp/utest/condvar_timedwait_tc.c
new file mode 100644
index 0000000000..43cfceb695
--- /dev/null
+++ b/components/lwp/utest/condvar_timedwait_tc.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2023-11-20 Shell add test suites
+ * 2026-03-19 cl2t Add standardized utest documentation block
+ */
+
+/**
+ * Test Case Name: Condition Variable Timed Wait Test
+ *
+ * Test Objectives:
+ * - Verify that rt_condvar_timedwait() correctly times out when no signal
+ * is received within the specified timeout period.
+ * - Test core APIs: rt_condvar_timedwait(), rt_mutex_take(),
+ * rt_mutex_init(), rt_condvar_init().
+ *
+ * Test Scenarios:
+ * - The main thread acquires a mutex and calls rt_condvar_timedwait()
+ * with a 100-tick timeout.
+ * - Since no other thread signals the condition variable, the call is
+ * expected to time out with -ETIMEDOUT or be interrupted with -EINTR.
+ *
+ * Verification Metrics:
+ * - rt_condvar_timedwait() must return -ETIMEDOUT or -EINTR when no
+ * signal is received.
+ * - Any other non-zero return value indicates a test failure.
+ * - Mutex initialization and acquisition must succeed.
+ *
+ * Dependencies:
+ * - Software configuration: RT_USING_SMART must be enabled.
+ * - Environmental assumptions: The platform must support condition
+ * variables and mutexes.
+ *
+ * Expected Results:
+ * - Final output: "[ PASSED ] [ result ] testcase (testcases.ipc.condvar.timedwait)"
+ * - No assertion failures during test execution.
+ */
+
+#include "common.h"
+#include "utest_assert.h"
+
+#include <rtdevice.h>
+#include <rtdef.h>
+
+static struct rt_mutex _local_mtx;
+static struct rt_condvar _local_cv;
+
+static void condvar_timedwait_tc(void)
+{
+ rt_mutex_t mutex = &_local_mtx;
+ rt_condvar_t cond = &_local_cv;
+ int err;
+
+ if (rt_mutex_take(mutex, RT_WAITING_FOREVER) != 0)
+ {
+ LOG_E("pthread_mutex_lock() error");
+ uassert_false(1);
+ return;
+ }
+
+ err = rt_condvar_timedwait(cond, mutex, RT_KILLABLE, 100);
+ if (err != 0)
+ {
+ if (err == -EINTR || err == -ETIMEDOUT)
+ {
+ puts("wait timed out");
+ uassert_false(0);
+ }
+ else
+ {
+ LOG_E("errno=%d, ret=%d\n", errno, err);
+ LOG_E("pthread_cond_timedwait() error");
+ uassert_false(1);
+ }
+ }
+
+ return ;
+}
+
+static rt_err_t utest_tc_init(void)
+{
+ if (rt_mutex_init(&_local_mtx, "utest", RT_IPC_FLAG_PRIO) != 0)
+ {
+ perror("pthread_mutex_init() error");
+ uassert_false(1);
+ return -1;
+ }
+
+ rt_condvar_init(&_local_cv, NULL);
+ return RT_EOK;
+}
+
+static rt_err_t utest_tc_cleanup(void)
+{
+ rt_mutex_detach(&_local_mtx);
+ rt_condvar_detach(&_local_cv);
+ return RT_EOK;
+}
+
+static void testcase(void)
+{
+ UTEST_UNIT_RUN(condvar_timedwait_tc);
+}
+UTEST_TC_EXPORT(testcase, "testcases.ipc.condvar.timedwait", utest_tc_init, utest_tc_cleanup, 10);