diff options
| author | Frédéric Desbiens <[email protected]> | 2026-10-02 10:42:44 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-10-02 10:42:44 -0400 |
| commit | 93387b0a60382a29579bbad5045c68328e3751df (patch) | |
| tree | 42be790d602cb76f55090e5a7c418df7ea2b3428 /test/freertos/cmake | |
| parent | 44d7c95c582d415c4ad84527180b29c93c3bf664 (diff) | |
| parent | 28281cd5647d4671236ca08d19bd18ed15b2265a (diff) | |
Merge pull request #783 from eclipse-threadx/devv6.5.2.202603_rel
Merged changes ahead of the v6.5.2.202603 release
Diffstat (limited to 'test/freertos/cmake')
| -rw-r--r-- | test/freertos/cmake/CMakeLists.txt | 78 | ||||
| -rw-r--r-- | test/freertos/cmake/regression/CMakeLists.txt | 84 | ||||
| -rwxr-xr-x | test/freertos/cmake/run.sh | 135 |
3 files changed, 297 insertions, 0 deletions
diff --git a/test/freertos/cmake/CMakeLists.txt b/test/freertos/cmake/CMakeLists.txt new file mode 100644 index 00000000..a8c07d8d --- /dev/null +++ b/test/freertos/cmake/CMakeLists.txt @@ -0,0 +1,78 @@ +############################################################################## +# Copyright (C) 2026 Eclipse ThreadX contributors +# +# This program and the accompanying materials are made available under the +# terms of the MIT License which is available at +# https://opensource.org/licenses/MIT. +# +# AI Disclosure: This file was largely AI-generated by Claude Code (Opus 5). +# The AI-generated portions may be considered public domain (CC0-1.0) +# and not subject to the project's licence. The human contributor has +# reviewed and verified that the code is correct. +# +# SPDX-License-Identifier: MIT and CC0-1.0 +############################################################################## + +cmake_minimum_required(VERSION 3.13 FATAL_ERROR) +cmake_policy(SET CMP0054 NEW) +cmake_policy(SET CMP0057 NEW) + +project(threadx_freertos_test LANGUAGES C) + +set(CMAKE_C_STANDARD 99) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS OFF) + +# The suite intercepts the ThreadX entry points with the linker's --wrap, which +# is a GNU ld and lld feature. There is no MSVC equivalent, so the suite is +# built on Linux only and the build stops early elsewhere rather than failing +# later with confusing link errors. +if(NOT CMAKE_C_COMPILER_ID MATCHES "GNU|Clang") + message(FATAL_ERROR + "The FreeRTOS compatibility layer tests require GNU ld or lld for " + "--wrap support and are supported on Linux only.") +endif() + +set(BUILD_CONFIGURATIONS default_build) +set(CMAKE_CONFIGURATION_TYPES + ${BUILD_CONFIGURATIONS} + CACHE STRING "list of supported configuration types" FORCE) +set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + ${CMAKE_CONFIGURATION_TYPES}) +list(GET CMAKE_CONFIGURATION_TYPES 0 BUILD_TYPE) +if((NOT CMAKE_BUILD_TYPE) OR (NOT ("${CMAKE_BUILD_TYPE}" IN_LIST + CMAKE_CONFIGURATION_TYPES))) + set(CMAKE_BUILD_TYPE + "${BUILD_TYPE}" + CACHE STRING "Build Type of the project" FORCE) +endif() + +message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") +message(STATUS "Using toolchain file: ${CMAKE_TOOLCHAIN_FILE}.") + +# Built 32 bit, as the ThreadX and SMP suites are. This is not incidental for +# this suite: the Linux port defines ULONG as unsigned int on x86_64, while the +# compatibility layer passes pointers through ULONG arguments, for instance the +# task argument and the timer identifier. A 64 bit build therefore truncates +# those pointers, which the compiler reports as -Wpointer-to-int-cast and which +# would crash the timer callback wrapper. +add_compile_options(-m32) +add_link_options(-m32) + +# Applied to everything, including the ThreadX build pulled in below. The +# strict warning set is applied to the test code alone, in the regression +# CMakeLists, since neither ThreadX nor the layer under test builds clean +# under -Wextra today and that is not this suite's to fix. +add_compile_options(-ggdb -g3 -fdiagnostics-color) + +enable_testing() + +# The compatibility layer stores a back pointer in each thread control block, +# so ThreadX has to be built with the matching user extension. +set(TX_USER_FILE + ${CMAKE_CURRENT_LIST_DIR}/../fixtures/tx_user.h + CACHE FILEPATH "tx_user.h used for the FreeRTOS layer tests" FORCE) + +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../../.. threadx) + +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/regression) diff --git a/test/freertos/cmake/regression/CMakeLists.txt b/test/freertos/cmake/regression/CMakeLists.txt new file mode 100644 index 00000000..21da2a6d --- /dev/null +++ b/test/freertos/cmake/regression/CMakeLists.txt @@ -0,0 +1,84 @@ +############################################################################## +# Copyright (C) 2026 Eclipse ThreadX contributors +# +# This program and the accompanying materials are made available under the +# terms of the MIT License which is available at +# https://opensource.org/licenses/MIT. +# +# AI Disclosure: This file was largely AI-generated by Claude Code (Opus 5). +# The AI-generated portions may be considered public domain (CC0-1.0) +# and not subject to the project's licence. The human contributor has +# reviewed and verified that the code is correct. +# +# SPDX-License-Identifier: MIT and CC0-1.0 +############################################################################## + +cmake_minimum_required(VERSION 3.13 FATAL_ERROR) +cmake_policy(SET CMP0057 NEW) + +project(freertos_regression_test LANGUAGES C) + +set(SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/../../regression) +set(FIXTURE_DIR ${CMAKE_CURRENT_LIST_DIR}/../../fixtures) +set(REPO_ROOT ${CMAKE_CURRENT_LIST_DIR}/../../../..) +set(LAYER_SOURCE ${REPO_ROOT}/utility/rtos_compatibility_layers/FreeRTOS/tx_freertos.c) +set(LAYER_INCLUDE_DIR ${REPO_ROOT}/utility/rtos_compatibility_layers/FreeRTOS) + +set(freertos_test_cases + ${SOURCE_DIR}/txfr_queue_create_test.c + ${SOURCE_DIR}/txfr_task_create_test.c + ${SOURCE_DIR}/txfr_sync_create_test.c) + +# tx_api.h maps the public API onto the error checking entry points, so those +# are the symbols that exist at link time and the ones the harness wraps. A +# name that does not resolve is silently ignored by the linker, so this list +# must be kept in step with the __wrap_ functions in txfr_test_harness.c. +set(wrapped_symbols + _txe_byte_allocate + _txe_byte_release + _txe_semaphore_create + _txe_semaphore_delete + _txe_mutex_create + _txe_mutex_delete + _txe_event_flags_create + _txe_event_flags_delete + _txe_timer_create + _txe_timer_delete + _txe_thread_create + _txe_thread_delete + _txe_thread_resume) + +set(wrap_link_options "") +foreach(symbol ${wrapped_symbols}) + list(APPEND wrap_link_options "-Wl,--wrap=${symbol}") +endforeach() + +# The layer is compiled from source into each test rather than linked from the +# freertos-threadx target, so that the test's FreeRTOSConfig.h applies. +add_library(freertos_layer_under_test OBJECT ${LAYER_SOURCE}) +target_include_directories(freertos_layer_under_test + PUBLIC ${LAYER_INCLUDE_DIR} ${FIXTURE_DIR}) +target_link_libraries(freertos_layer_under_test PUBLIC azrtos::threadx) + +set(test_warning_options -Wall -Wextra -Werror) + +add_library(freertos_test_harness OBJECT ${SOURCE_DIR}/txfr_test_harness.c) +target_include_directories(freertos_test_harness + PUBLIC ${SOURCE_DIR} ${LAYER_INCLUDE_DIR} ${FIXTURE_DIR}) +target_link_libraries(freertos_test_harness PUBLIC azrtos::threadx) +target_compile_options(freertos_test_harness PRIVATE ${test_warning_options}) + +foreach(test_case ${freertos_test_cases}) + get_filename_component(test_name ${test_case} NAME_WE) + + add_executable(${test_name} ${test_case} + $<TARGET_OBJECTS:freertos_test_harness> + $<TARGET_OBJECTS:freertos_layer_under_test>) + target_include_directories(${test_name} + PRIVATE ${SOURCE_DIR} ${LAYER_INCLUDE_DIR} ${FIXTURE_DIR}) + target_link_libraries(${test_name} PRIVATE azrtos::threadx) + target_link_options(${test_name} PRIVATE ${wrap_link_options}) + target_compile_options(${test_name} PRIVATE ${test_warning_options}) + + add_test(${CMAKE_BUILD_TYPE}::${test_name} ${test_name}) +endforeach() diff --git a/test/freertos/cmake/run.sh b/test/freertos/cmake/run.sh new file mode 100755 index 00000000..896a5c37 --- /dev/null +++ b/test/freertos/cmake/run.sh @@ -0,0 +1,135 @@ +#!/bin/bash +############################################################################## +# Copyright (C) 2026 Eclipse ThreadX contributors +# +# This program and the accompanying materials are made available under the +# terms of the MIT License which is available at +# https://opensource.org/licenses/MIT. +# +# AI Disclosure: This file was largely AI-generated by Claude Code (Opus 5). +# The AI-generated portions may be considered public domain (CC0-1.0) +# and not subject to the project's licence. The human contributor has +# reviewed and verified that the code is correct. +# +# SPDX-License-Identifier: MIT and CC0-1.0 +############################################################################## + +# Builds and runs the FreeRTOS compatibility layer regression suite. The +# interface matches test/tx/cmake/run.sh so that the shared CI template can +# drive it: "run.sh build all" then "run.sh test all". + +set -e + +function help() { + echo "Usage: $0 [build|test] [all|<build_configuration> <build_configuration>...]" + echo "Available build_configuration:" + for build in ${build_configurations[*]}; do + echo " $build" + done + exit 1 +} + +function validate() { + for build in ${build_configurations[*]}; do + if [ "$1" == "$build" ]; then + return + fi + done + help +} + +function generate() { + build=$1 + cmake -Bbuild/$build -GNinja -DCMAKE_TOOLCHAIN_FILE=$(dirname $(realpath $0))/../../../cmake/linux.cmake -DCMAKE_BUILD_TYPE=$build . +} + +function build() { + # -k 0 keeps Ninja going after a target fails, so one broken target no + # longer decides whether the targets after it exist. ctest reports a + # missing binary as a failing test, which turned a single link error into + # a failure count that varied with build scheduling order. + cmake --build build/$1 -- -k 0 +} + +function test() { + # Guard the pushd: with the caller capturing this function's status, set -e + # no longer aborts here, so a missing build directory would otherwise let + # ctest run in the source tree and report "no tests" as success. + pushd build/$1 || return 1 + [ -z "${CTEST_PARALLEL_LEVEL}" ] && parallel="-j$2" + if [ -z "${CTEST_REPEAT_FAIL}" ]; + then + repeat_fail=2 + else + repeat_fail=${CTEST_REPEAT_FAIL} + fi + # ctest's status is captured and returned past the popd and the summary + # steps, which all succeed. Without this the function would return 0 and a + # failing configuration would be reported as a pass. + local status=0 + ctest $parallel --timeout 300 -O $1.txt -T test --no-compress-output --test-output-size-passed 4194304 --test-output-size-failed 4194304 --output-on-failure --repeat until-pass:${repeat_fail} --output-junit $1.xml || status=$? + popd + # Tolerated: this is a summary for humans, and a ctest that died early + # enough to leave no matching line must not mask its own status. + grep -E "^(\s*[0-9]+|Total)" build/$1/$1.txt >build/$1.txt || true + sed -i "s/\x1B\[[0-9;]*[JKmsu]//g" build/$1.txt + return $status +} + +cd $(dirname $0) + +result=$(sed -n "/(BUILD_CONFIGURATIONS/,/)/p" CMakeLists.txt|sed ':label;N;s/\n/ /;b label'|grep -Pzo "[a-zA-Z0-9_]*build[a-zA-Z0-9_]*\s*"| tr -d '\0') +IFS=' ' +read -ra build_configurations <<< "$result" + +if [ $# -lt 1 ]; then + help +fi + +command=$1 +shift + +if [ "$#" == "0" ]; then + builds=${build_configurations[0]} +elif [ "$*" == "all" ]; then + builds=${build_configurations[@]} +else + for item in $*; do + validate $item + done + builds=$* +fi + +if [ "$command" == "build" ]; then + for item in $builds; do + generate $item + echo "" + done + + # A failing configuration must not stop the ones after it: under set -e + # the loop would abort and leave them unbuilt, which then reads as a wall + # of missing-binary test failures. The status is accumulated and returned. + build_status=0 + for item in $builds; do + echo "Building $item" + build $item || build_status=$? + echo "" + done + [ $build_status -eq 0 ] || exit $build_status +elif [ "$command" == "test" ]; then + cores=$(nproc) + if [ -z "${CTEST_PARALLEL_LEVEL}" ]; + then + parallel_jobs=$(($cores + 2)) + fi + # ctest's status is accumulated rather than allowed to abort the loop, so + # a failing configuration does not leave the ones after it untested. + exit_code=0 + for item in $builds; do + echo "Testing $item" + test $item $parallel_jobs || exit_code=$? + done + exit $exit_code +else + help +fi |
