From 1ab2d7328122e5905bca9c8d73059201923c9d7a Mon Sep 17 00:00:00 2001 From: CYFS <2805686936@qq.com> Date: Fri, 17 Apr 2026 15:32:45 +0800 Subject: [PATCH] [action][utest]:Expand kernel auto-run matrix and sync test configs --- .github/workflows/utest_auto_run.yml | 98 ++++++++++++++----- examples/utest/configs/kernel/ipc.cfg | 3 + .../utest/configs/kernel/kernel_basic.cfg | 2 + src/utest/object_tc.c | 25 ++++- src/utest/perf/thread_mbox_tc.c | 1 - src/utest/thread_overflow_tc.c | 39 +++++--- 6 files changed, 129 insertions(+), 39 deletions(-) diff --git a/.github/workflows/utest_auto_run.yml b/.github/workflows/utest_auto_run.yml index df56f699d5b..f614652d231 100644 --- a/.github/workflows/utest_auto_run.yml +++ b/.github/workflows/utest_auto_run.yml @@ -59,14 +59,51 @@ jobs: - "default.cfg" include: - # only run on qemu-vexpress-a9 + # run kernel utest set on all QEMU boards - platform: { UTEST: "A9", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", SD_FILE: "sd.bin", KERNEL: "standard", "SMP_RUN":"" } config_file: "kernel/kernel_basic.cfg" - platform: { UTEST: "A9", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", SD_FILE: "sd.bin", KERNEL: "standard", "SMP_RUN":"" } config_file: "kernel/ipc.cfg" - platform: { UTEST: "A9", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", SD_FILE: "sd.bin", KERNEL: "standard", "SMP_RUN":"" } config_file: "kernel/mem.cfg" - + - platform: { UTEST: "A9-rtsmart", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", SD_FILE: "sd.bin", KERNEL: "rtsmart", "SMP_RUN":"" } + config_file: "kernel/kernel_basic.cfg" + - platform: { UTEST: "A9-rtsmart", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", SD_FILE: "sd.bin", KERNEL: "rtsmart", "SMP_RUN":"" } + config_file: "kernel/ipc.cfg" + - platform: { UTEST: "A9-rtsmart", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", SD_FILE: "sd.bin", KERNEL: "rtsmart", "SMP_RUN":"" } + config_file: "kernel/mem.cfg" + - platform: { UTEST: "A9-smp", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", SD_FILE: "sd.bin", KERNEL: "standard", "SMP_RUN":"smp" } + config_file: "kernel/kernel_basic.cfg" + - platform: { UTEST: "A9-smp", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", SD_FILE: "sd.bin", KERNEL: "standard", "SMP_RUN":"smp" } + config_file: "kernel/ipc.cfg" + - platform: { UTEST: "A9-smp", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", SD_FILE: "sd.bin", KERNEL: "standard", "SMP_RUN":"smp" } + config_file: "kernel/mem.cfg" + - platform: { UTEST: "RISCV", RTT_BSP: "bsp/qemu-virt64-riscv", QEMU_ARCH: "riscv64", QEMU_MACHINE: "virt", SD_FILE: "None", KERNEL: "standard", "SMP_RUN":"" } + config_file: "kernel/kernel_basic.cfg" + - platform: { UTEST: "RISCV", RTT_BSP: "bsp/qemu-virt64-riscv", QEMU_ARCH: "riscv64", QEMU_MACHINE: "virt", SD_FILE: "None", KERNEL: "standard", "SMP_RUN":"" } + config_file: "kernel/ipc.cfg" + - platform: { UTEST: "RISCV", RTT_BSP: "bsp/qemu-virt64-riscv", QEMU_ARCH: "riscv64", QEMU_MACHINE: "virt", SD_FILE: "None", KERNEL: "standard", "SMP_RUN":"" } + config_file: "kernel/mem.cfg" + - platform: { UTEST: "RISCV-rtsmart", RTT_BSP: "bsp/qemu-virt64-riscv", QEMU_ARCH: "riscv64", QEMU_MACHINE: "virt", SD_FILE: "None", KERNEL: "rtsmart", "SMP_RUN":"" } + config_file: "kernel/kernel_basic.cfg" + - platform: { UTEST: "RISCV-rtsmart", RTT_BSP: "bsp/qemu-virt64-riscv", QEMU_ARCH: "riscv64", QEMU_MACHINE: "virt", SD_FILE: "None", KERNEL: "rtsmart", "SMP_RUN":"" } + config_file: "kernel/ipc.cfg" + - platform: { UTEST: "RISCV-rtsmart", RTT_BSP: "bsp/qemu-virt64-riscv", QEMU_ARCH: "riscv64", QEMU_MACHINE: "virt", SD_FILE: "None", KERNEL: "rtsmart", "SMP_RUN":"" } + config_file: "kernel/mem.cfg" + - platform: { UTEST: "XUANTIE-rtsmart", RTT_BSP: "bsp/xuantie/virt64/c906", QEMU_ARCH: "riscv64", QEMU_MACHINE: "virt", SD_FILE: "sd.bin", KERNEL: "rtsmart", "SMP_RUN":"" } + config_file: "kernel/kernel_basic.cfg" + - platform: { UTEST: "XUANTIE-rtsmart", RTT_BSP: "bsp/xuantie/virt64/c906", QEMU_ARCH: "riscv64", QEMU_MACHINE: "virt", SD_FILE: "sd.bin", KERNEL: "rtsmart", "SMP_RUN":"" } + config_file: "kernel/ipc.cfg" + - platform: { UTEST: "XUANTIE-rtsmart", RTT_BSP: "bsp/xuantie/virt64/c906", QEMU_ARCH: "riscv64", QEMU_MACHINE: "virt", SD_FILE: "sd.bin", KERNEL: "rtsmart", "SMP_RUN":"" } + config_file: "kernel/mem.cfg" + - platform: { UTEST: "RISCV-smp", RTT_BSP: "bsp/qemu-virt64-riscv", QEMU_ARCH: "riscv64", QEMU_MACHINE: "virt", SD_FILE: "None", KERNEL: "standard", "SMP_RUN":"smp" } + config_file: "kernel/mem.cfg" + - platform: { UTEST: "AARCH64", RTT_BSP: "bsp/qemu-virt64-aarch64", QEMU_ARCH: "aarch64", QEMU_MACHINE: "virt", SD_FILE: "sd.bin", KERNEL: "standard", "SMP_RUN":"" } + config_file: "kernel/mem.cfg" + - platform: { UTEST: "AARCH64-rtsmart", RTT_BSP: "bsp/qemu-virt64-aarch64", QEMU_ARCH: "aarch64", QEMU_MACHINE: "virt", SD_FILE: "sd.bin", KERNEL: "rtsmart", "SMP_RUN":"" } + config_file: "kernel/mem.cfg" + - platform: { UTEST: "AARCH64-smp", RTT_BSP: "bsp/qemu-virt64-aarch64", QEMU_ARCH: "aarch64", QEMU_MACHINE: "virt", SD_FILE: "sd.bin", KERNEL: "standard", "SMP_RUN":"smp" } + config_file: "kernel/mem.cfg" - platform: { UTEST: "A9", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", SD_FILE: "sd.bin", KERNEL: "standard", "SMP_RUN":"" } config_file: "kernel/atomic_c11.cfg" - platform: { UTEST: "RISCV", RTT_BSP: "bsp/qemu-virt64-riscv", QEMU_ARCH: "riscv64", QEMU_MACHINE: "virt", SD_FILE: "None", KERNEL: "standard", "SMP_RUN":"" } @@ -273,38 +310,55 @@ jobs: - name: Monitor qemu log if: ${{ env.TOOLCHAIN_INSTALLED != '' && success() }} + timeout-minutes: 20 run: | FAILURE_DETECTED=false ERROR_LOGS="" + export FAILURE_DETECTED ERROR_LOGS echo "==========================================================================================" echo " || || " echo " || Start automatic running of Utest || " echo " VV VV " echo "==========================================================================================" - tail -n 0 -f qemu_output_$TEST_QEMU_ARCH.log | while read line; do - echo $line - if [[ "$line" == *"[ FAILED ] [ result ]"* ]]; then - ERROR_LOGS="$ERROR_LOGS$line"$'\n' - FAILURE_DETECTED=true - fi - - if [[ "$line" == *"[==========] [ utest ] finished"* ]]; then - if $FAILURE_DETECTED; then + timeout 20m bash -c ' + tail -n 0 -f "qemu_output_${TEST_QEMU_ARCH}.log" | while IFS= read -r line; do + echo "$line" + if [[ "$line" == *"[ FAILED ] [ result ]"* ]]; then + ERROR_LOGS="${ERROR_LOGS}${line}"$'\''\n'\'' + FAILURE_DETECTED=true + fi + + if [[ "$line" == *"[==========] [ utest ] finished"* ]]; then + if [[ "$FAILURE_DETECTED" == "true" ]]; then + echo "==========================================================================================" + echo " || || " + echo " || Error: Failures detected in logs. Below are the failure details... || " + echo " VV VV " + echo "==========================================================================================" + echo "$ERROR_LOGS" + exit 1 + fi echo "==========================================================================================" - echo " || || " - echo " || Error: Failures detected in logs. Below are the failure details... || " - echo " VV VV " + echo " Successed: Utest run completed. Exiting log monitoring " echo "==========================================================================================" - echo "$ERROR_LOGS" - exit 1 + break fi - echo "==========================================================================================" - echo " Successed: Utest run completed. Exiting log monitoring " - echo "==========================================================================================" - break - fi - done + done + ' + monitor_status=$? + + if [[ $monitor_status -eq 124 ]]; then + echo "==========================================================================================" + echo " || || " + echo " || Error: Utest run timed out after 20 minutes. Exiting... || " + echo " VV VV " + echo "==========================================================================================" + pkill -f "qemu-system-${TEST_QEMU_ARCH}.*${TEST_BSP_ROOT}/rtthread.bin" || true + exit 1 + fi + + exit $monitor_status # # Post CI status to PR comment # post-ci-status: # needs: test diff --git a/examples/utest/configs/kernel/ipc.cfg b/examples/utest/configs/kernel/ipc.cfg index 3db6e14f8c9..7ad79b0e259 100644 --- a/examples/utest/configs/kernel/ipc.cfg +++ b/examples/utest/configs/kernel/ipc.cfg @@ -9,6 +9,9 @@ CONFIG_RT_UTEST_SIGNAL=y CONFIG_RT_UTEST_MUTEX=y CONFIG_RT_UTEST_MAILBOX=y +CONFIG_RT_UTEST_COMPLETION=y +CONFIG_RT_UTEST_WORKQUEUE=y + CONFIG_RT_USING_SEMAPHORE=y CONFIG_RT_USING_EVENT=y CONFIG_RT_USING_MESSAGEQUEUE=y diff --git a/examples/utest/configs/kernel/kernel_basic.cfg b/examples/utest/configs/kernel/kernel_basic.cfg index d378e0ac7fa..ee153e35869 100644 --- a/examples/utest/configs/kernel/kernel_basic.cfg +++ b/examples/utest/configs/kernel/kernel_basic.cfg @@ -2,6 +2,8 @@ CONFIG_RT_CONSOLEBUF_SIZE=1024 CONFIG_RT_USING_CI_ACTION=y +CONFIG_RT_UTEST_TIMER=y +CONFIG_RT_UTEST_TC_USING_KLIBC=y CONFIG_RT_UTEST_OBJECT=y CONFIG_RT_UTEST_IRQ=y CONFIG_RT_UTEST_THREAD=y diff --git a/src/utest/object_tc.c b/src/utest/object_tc.c index 2ec54950758..cabacd2610a 100644 --- a/src/utest/object_tc.c +++ b/src/utest/object_tc.c @@ -77,6 +77,7 @@ #define TEST_RT_NAME_MAX RT_NAME_MAX #define OBJECT_STRESS_BATCH 24 #define OBJECT_STRESS_ROUNDS 3 +#define OBJECT_THREAD_STACK_SIZE 1024 #ifndef ARRAY_SIZE #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) @@ -140,6 +141,16 @@ static rt_err_t generate_unique_name(char *buf, return -RT_ENOMEM; } +static void object_find_test_thread_entry(void *parameter) +{ + RT_UNUSED(parameter); + + while (1) + { + rt_thread_mdelay(10); + } +} + static void test_object_name_handling(void) { struct rt_object static_obj; @@ -187,6 +198,7 @@ static void test_object_find_operations(void) rt_thread_t found_thread; rt_object_t found; char missing_name[] = "object.not.exists"; + rt_err_t ret; uassert_true(generate_unique_name(name, sizeof(name), "sobj", RT_Object_Class_Thread) == RT_EOK); rt_object_init(&static_obj, RT_Object_Class_Thread, name); @@ -197,14 +209,21 @@ static void test_object_find_operations(void) rt_object_detach(&static_obj); uassert_true(generate_unique_name(name, sizeof(name), "thr", RT_Object_Class_Thread) == RT_EOK); - thread = rt_thread_create(name, RT_NULL, RT_NULL, 512, RT_THREAD_PRIORITY_MAX / 2, 10); + thread = rt_thread_create(name, object_find_test_thread_entry, RT_NULL, + OBJECT_THREAD_STACK_SIZE, RT_THREAD_PRIORITY_MAX / 2, 10); uassert_not_null(thread); + ret = rt_thread_startup(thread); + uassert_int_equal(ret, RT_EOK); found_thread = rt_thread_find(name); uassert_not_null(found_thread); uassert_ptr_equal(found_thread, thread); uassert_str_equal(found_thread->parent.name, name); - rt_thread_delete(thread); - rt_thread_mdelay(10); + ret = rt_thread_delete(thread); + uassert_int_equal(ret, RT_EOK); + for (int i = 0; i < 10 && rt_thread_find(name) != RT_NULL; i++) + { + rt_thread_mdelay(100); + } uassert_null(rt_thread_find(name)); #ifdef RT_USING_DEVICE diff --git a/src/utest/perf/thread_mbox_tc.c b/src/utest/perf/thread_mbox_tc.c index 8ad021c5314..4b39451b530 100644 --- a/src/utest/perf/thread_mbox_tc.c +++ b/src/utest/perf/thread_mbox_tc.c @@ -81,7 +81,6 @@ static void perf_thread_mbox1(void *parameter) static void perf_thread_mbox2(void *parameter) { rt_perf_t *perf = (rt_perf_t *)parameter; - rt_err_t ret = RT_EOK; while (1) { if (perf->count >= RT_UTEST_SYS_PERF_TC_COUNT) diff --git a/src/utest/thread_overflow_tc.c b/src/utest/thread_overflow_tc.c index f769e6e5615..520cf891608 100644 --- a/src/utest/thread_overflow_tc.c +++ b/src/utest/thread_overflow_tc.c @@ -12,7 +12,7 @@ #include "utest.h" #define UTEST_NAME "thread_overflow_tc" -#define TEST_STACK_SIZE 512 +#define TEST_STACK_SIZE UTEST_THR_STACK_SIZE /* Test thread stack overflow */ static rt_thread_t test_thread = RT_NULL; @@ -34,7 +34,7 @@ static rt_err_t stack_overflow_hook(struct rt_thread *thread) static void stack_usage_test(void) { rt_thread_t current_thread; - rt_uint32_t total_stack, used_stack; + rt_uintptr_t total_stack, used_stack; current_thread = rt_thread_self(); uassert_not_null(current_thread); @@ -49,10 +49,10 @@ static void stack_usage_test(void) #ifdef ARCH_CPU_STACK_GROWS_UPWARD /* For upward growing stacks */ - used_stack = (rt_uint32_t)current_thread->sp - (rt_uint32_t)current_thread->stack_addr; + used_stack = (rt_uintptr_t)current_thread->sp - (rt_uintptr_t)current_thread->stack_addr; #else /* For downward growing stacks (most common) */ - used_stack = (rt_uint32_t)current_thread->stack_addr + total_stack - (rt_uint32_t)current_thread->sp; + used_stack = (rt_uintptr_t)current_thread->stack_addr + total_stack - (rt_uintptr_t)current_thread->sp; #endif rt_kprintf("Used stack: %d bytes (%d%%)\n", @@ -142,11 +142,11 @@ static void stack_overflow_hook_test(void) /* Fake thread test entry function */ static void fake_thread_entry(void *parameter) { - /* This function should never actually run */ - rt_kprintf("Fake thread is running - this should not happen!\n"); + RT_UNUSED(parameter); + while (1) { - rt_thread_mdelay(1000); + rt_thread_mdelay(100); } } @@ -178,14 +178,18 @@ static void fake_thread_stack_overflow_test(void) } rt_kprintf("Fake thread created successfully\n"); + uassert_int_equal(rt_thread_startup(fake_thread), RT_EOK); + rt_thread_mdelay(10); - rt_kprintf("Corrupting fake thread stack with pattern 0x11...\n"); - rt_memset(fake_thread->stack_addr, 0x11, fake_thread->stack_size); - - /* Also corrupt the magic number area if stack checking is enabled */ + rt_kprintf("Corrupting fake thread stack sentinel...\n"); #ifdef RT_USING_OVERFLOW_CHECK - /* For downward growing stacks, magic is typically at the beginning */ - rt_memset(fake_thread->stack_addr, 0x11, 4); /* Corrupt first 4 bytes */ + /* Only corrupt the sentinel bytes used by overflow detection. */ +#ifdef ARCH_CPU_STACK_GROWS_UPWARD + rt_memset((rt_uint8_t *)fake_thread->stack_addr + fake_thread->stack_size - sizeof(rt_ubase_t), + 0x11, sizeof(rt_ubase_t)); +#else + rt_memset(fake_thread->stack_addr, 0x11, sizeof(rt_ubase_t)); +#endif rt_kprintf("Stack magic number area corrupted\n"); #endif @@ -204,6 +208,11 @@ static void fake_thread_stack_overflow_test(void) if (fake_thread != RT_NULL) { rt_thread_delete(fake_thread); + for (int i = 0; i < 10 && rt_thread_find("fake_thread") != RT_NULL; i++) + { + rt_thread_mdelay(10); + } + uassert_null(rt_thread_find("fake_thread")); fake_thread = RT_NULL; rt_kprintf("Fake thread deleted\n"); } @@ -250,6 +259,10 @@ static rt_err_t utest_tc_cleanup(void) if (fake_thread != RT_NULL) { rt_thread_delete(fake_thread); + for (int i = 0; i < 10 && rt_thread_find("fake_thread") != RT_NULL; i++) + { + rt_thread_mdelay(10); + } fake_thread = RT_NULL; }