summaryrefslogtreecommitdiff
path: root/test/smp/cmake
diff options
context:
space:
mode:
authorFrédéric Desbiens <[email protected]>2026-10-02 10:42:44 -0400
committerGitHub <[email protected]>2026-10-02 10:42:44 -0400
commit93387b0a60382a29579bbad5045c68328e3751df (patch)
tree42be790d602cb76f55090e5a7c418df7ea2b3428 /test/smp/cmake
parent44d7c95c582d415c4ad84527180b29c93c3bf664 (diff)
parent28281cd5647d4671236ca08d19bd18ed15b2265a (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/smp/cmake')
-rw-r--r--test/smp/cmake/CMakeLists.txt16
-rwxr-xr-xtest/smp/cmake/coverage.sh146
-rw-r--r--test/smp/cmake/regression/CMakeLists.txt24
-rw-r--r--test/smp/cmake/threadx_smp/CMakeLists.txt1
-rw-r--r--test/smp/cmake/threadx_smp/common_smp/CMakeLists.txt1
-rw-r--r--test/smp/cmake/threadx_smp/ports_smp/linux/gnu/CMakeLists.txt1
-rw-r--r--test/smp/cmake/threadx_smp/ports_smp/win64/vs_2022/CMakeLists.txt1
7 files changed, 185 insertions, 5 deletions
diff --git a/test/smp/cmake/CMakeLists.txt b/test/smp/cmake/CMakeLists.txt
index e2ca8627..3a0d9638 100644
--- a/test/smp/cmake/CMakeLists.txt
+++ b/test/smp/cmake/CMakeLists.txt
@@ -64,7 +64,21 @@ add_subdirectory(regression)
add_subdirectory(samples)
# Coverage
-if(CMAKE_BUILD_TYPE MATCHES ".*_coverage")
+#
+# The gate here used to be the build type alone, and only one of the five
+# configurations -- default_build_coverage -- has a name matching "*_coverage".
+# So four configurations built and ran every test and their coverage was thrown
+# away. That is not redundancy discarded: each configuration selects a different
+# set of TX_ feature macros, so the code the other four compile is *absent from
+# the denominator* rather than reported as uncovered. A figure taken from one of
+# them is the executable-line count of one configuration, not of the kernel.
+#
+# TX_COVERAGE instruments a build regardless of its name. It defaults to OFF and
+# the build-type match is kept, so configuring a single configuration by hand
+# behaves exactly as it did before; the regression run turns it on for all five
+# and merges the results.
+option(TX_COVERAGE "Instrument this build for coverage regardless of build type" OFF)
+if(TX_COVERAGE OR CMAKE_BUILD_TYPE MATCHES ".*_coverage")
if(NOT MSVC)
target_compile_options(threadx_smp PRIVATE -fprofile-arcs -ftest-coverage)
target_link_options(threadx_smp PRIVATE -fprofile-arcs -ftest-coverage)
diff --git a/test/smp/cmake/coverage.sh b/test/smp/cmake/coverage.sh
index d35284f5..88de4f04 100755
--- a/test/smp/cmake/coverage.sh
+++ b/test/smp/cmake/coverage.sh
@@ -14,7 +14,145 @@
set -e
cd $(dirname $0)
-threadx_smp=$(realpath ../../../common_smp/src)
-mkdir -p coverage_report/$1
-gcovr --object-directory=build/$1/threadx_smp/CMakeFiles/threadx_smp.dir/$threadx_smp -r build/$1 -f ../../../common_smp/src --xml-pretty --output coverage_report/$1.xml
-gcovr --object-directory=build/$1/threadx_smp/CMakeFiles/threadx_smp.dir/$threadx_smp -r build/$1 -f ../../../common_smp/src --html --html-details --output coverage_report/$1/index.html
+
+# gcov reads a data format tied to the compiler that produced it, so gcov has to match
+# the gcc that built the objects. Since cmake/linux.cmake began honouring CC, taking
+# whatever gcov happens to be first on PATH is no longer safe: building with gcc-14 and
+# reading with gcov-13 gives "version 'B42*', prefer 'B33*'" from gcov, and gcovr turns
+# that into "GCOV returncode was 3" and exits 64. The tests pass and then the coverage
+# step fails with a Python traceback, which reads like a coverage bug rather than a
+# toolchain mismatch.
+#
+# So derive gcov from CC rather than asking the caller to remember both. GCOV still
+# overrides, for a toolchain that does not follow the gcc/gcov naming.
+: "${CC:=gcc}"
+if [ -z "${GCOV:-}" ]; then
+ cc_base=$(basename "$CC")
+ case "$cc_base" in
+ gcc*) GCOV="gcov${cc_base#gcc}" ;;
+ *) GCOV="gcov" ;;
+ esac
+fi
+
+if ! command -v "$GCOV" >/dev/null 2>&1; then
+ echo "coverage.sh: '$GCOV' not found, derived from CC='$CC'." >&2
+ echo "Install it, or set GCOV to the gcov matching that compiler." >&2
+ exit 1
+fi
+
+# The repository root, needed by every mode below. It has to be absolute: see the
+# note on the per-configuration paths further down.
+repo_root=$(cd ../../.. && pwd)
+filter=$repo_root/common_smp/src
+
+# --merge unions the per-configuration reports into the one number that means
+# something. Each configuration writes an intermediate JSON beside its XML, and
+# this pass adds them all together.
+#
+# Reporting five separate percentages instead would invite a reader to average
+# them, and an average is not a coverage figure -- a line covered only by
+# trace_build is covered, and only the union says so.
+#
+# Do not be alarmed when the merged percentage is lower than the single
+# configuration this used to report. That is the point: the denominator now
+# includes code the old report never counted at all, because it was compiled out
+# of the only instrumented build.
+if [ "$1" = "--merge" ]; then
+ shopt -s nullglob
+ tracefiles=(coverage_report/per_configuration/*.json)
+ shopt -u nullglob
+ if [ ${#tracefiles[@]} -eq 0 ]; then
+ echo "coverage.sh --merge: no JSON in coverage_report/per_configuration/." >&2
+ echo "Run the suites with TX_COVERAGE=ON first." >&2
+ exit 1
+ fi
+
+ add_args=()
+ for t in "${tracefiles[@]}"; do
+ add_args+=(--add-tracefile "$t")
+ done
+
+ mkdir -p coverage_report/merged
+ gcovr -r "$repo_root" "${add_args[@]}" --xml-pretty --output coverage_report/merged.xml
+ gcovr -r "$repo_root" "${add_args[@]}" --html --html-details --output coverage_report/merged/index.html
+
+ if ! grep -q "<class " coverage_report/merged.xml; then
+ echo "coverage.sh --merge: the merged report contains no files." >&2
+ exit 1
+ fi
+
+ # Named, not just counted. coverage_report/ is not cleaned between runs, so a
+ # tracefile left by an earlier run of a different set of configurations would
+ # otherwise be merged in without anything saying so.
+ echo "coverage.sh --merge: SMP, ${#tracefiles[@]} configuration(s):"
+ for t in "${tracefiles[@]}"; do
+ echo " $(basename "$t" .json)"
+ done
+ exit 0
+fi
+
+# gcovr is given three paths below, and each of them has to be absolute, for a
+# different reason.
+#
+# -r is the repository root rather than the build directory, so the report names
+# files the way the repository does -- "common_smp/src/tx_block_allocate.c"
+# instead of "/home/runner/work/threadx/threadx/common_smp/src/tx_block_allocate.c".
+# With -r inside build/, gcovr cannot express the sources relative to it, because
+# they are outside it, and falls back to absolute paths. Those paths then differ
+# on every machine and disagree with the <source> element written beside them in
+# the same file, so anything that maps coverage back to the repository -- PR
+# annotations, Codecov, SonarQube -- cannot follow them.
+#
+# Both -r and -f must be absolute. "-r ../../.. -f common_smp/src" produces a
+# report containing zero files and exits 0, which is the worst failure mode
+# available here: a green run carrying an empty report. Measured, not assumed.
+repo_root=$(cd ../../.. && pwd)
+
+# This is what actually scopes the report to one build configuration, and it is
+# the positional search path -- not --object-directory, which used to be here
+# and was doing nothing at all. That flag tells gcovr how to get from a gcda
+# file back to the compiler's working directory; it does not restrict which gcda
+# files are found. Pointed at an empty directory it still produced the full
+# report, because gcovr searches -r as well.
+#
+# That matters more now than it did before. While -r was build/$1 it happened to
+# constrain the search to this configuration by accident. -r is the repository
+# root now, and every configuration's gcda lies somewhere under it, so without
+# an explicit search path the report would silently merge all five.
+#
+# The odd shape of this path is CMake's, not ours: common_smp/src sits outside
+# this directory's source tree, so CMake mangles each source file's absolute
+# path into the object path, minus the leading slash. Hence the concatenation
+# rather than a join -- $repo_root already begins with one.
+objdir=$PWD/build/$1/threadx_smp/CMakeFiles/threadx_smp.dir$repo_root/common_smp/src
+
+# The Linux port's own sources are deliberately outside -f. gcno files exist for
+# two directories -- common_smp/src and ports_smp/linux/gnu/src -- and only the
+# first is reported. The kernel is what this suite is here to cover; the
+# architecture ports are validated functionally rather than structurally, and
+# linux/gnu is a development host port that nothing ships on. Written down
+# because a filter argument on its own is not a decision the next reader can see.
+
+# Per-configuration output is kept in a subdirectory of its own, and the merged
+# report sits alongside it at the top. That is not tidiness: the Pages deploy
+# uploads coverage_report wholesale and merges the ThreadX and SMP artifacts
+# into one tree, and every configuration directory has the same name in both
+# suites. Left at the top level, default_build_coverage/ from one suite would
+# overwrite the other's on the published site. Nested here, the top level still
+# holds exactly the one suite directory the deploy expects.
+mkdir -p coverage_report/per_configuration/$1
+gcovr --gcov-executable "$GCOV" -r "$repo_root" -f "$filter" "$objdir" \
+ --json coverage_report/per_configuration/$1.json \
+ --xml-pretty --output coverage_report/per_configuration/$1.xml
+gcovr --gcov-executable "$GCOV" -r "$repo_root" -f "$filter" "$objdir" --html --html-details --output coverage_report/per_configuration/$1/index.html
+
+# An empty report is not an error as far as gcovr is concerned: it warns and
+# exits 0. Worse, it advertises line-rate="1.0" alongside lines-valid="0", so
+# every downstream consumer reads "no data at all" as "100% covered". A coverage
+# threshold cannot catch that, because an empty report passes any threshold. So
+# the assertion belongs here, next to the paths that would cause it.
+if ! grep -q "<class " coverage_report/per_configuration/$1.xml; then
+ echo "coverage.sh: the report for '$1' contains no files." >&2
+ echo "Expected gcda files under $objdir." >&2
+ exit 1
+fi
diff --git a/test/smp/cmake/regression/CMakeLists.txt b/test/smp/cmake/regression/CMakeLists.txt
index b448ae3e..cdf0c585 100644
--- a/test/smp/cmake/regression/CMakeLists.txt
+++ b/test/smp/cmake/regression/CMakeLists.txt
@@ -25,6 +25,7 @@ set(regression_test_cases
${SOURCE_DIR}/threadx_block_memory_thread_terminate_test.c
${SOURCE_DIR}/threadx_byte_memory_basic_test.c
${SOURCE_DIR}/threadx_byte_memory_information_test.c
+ ${SOURCE_DIR}/threadx_byte_memory_long_search_test.c
${SOURCE_DIR}/threadx_byte_memory_prioritize_test.c
${SOURCE_DIR}/threadx_byte_memory_suspension_test.c
${SOURCE_DIR}/threadx_byte_memory_suspension_timeout_test.c
@@ -52,6 +53,7 @@ set(regression_test_cases
${SOURCE_DIR}/threadx_mutex_proritize_test.c
${SOURCE_DIR}/threadx_mutex_suspension_timeout_test.c
${SOURCE_DIR}/threadx_mutex_thread_terminate_test.c
+ ${SOURCE_DIR}/threadx_object_delete_suspension_test.c
${SOURCE_DIR}/threadx_queue_basic_eight_word_test.c
${SOURCE_DIR}/threadx_queue_basic_four_word_test.c
${SOURCE_DIR}/threadx_queue_basic_one_word_test.c
@@ -84,6 +86,7 @@ set(regression_test_cases
${SOURCE_DIR}/threadx_smp_random_resume_suspend_exclusion_test.c
${SOURCE_DIR}/threadx_smp_random_resume_suspend_test.c
${SOURCE_DIR}/threadx_smp_rebalance_exclusion_test.c
+ ${SOURCE_DIR}/threadx_smp_relinquish_rebalance_test.c
${SOURCE_DIR}/threadx_smp_relinquish_test.c
${SOURCE_DIR}/threadx_smp_resume_suspend_ascending_order_test.c
${SOURCE_DIR}/threadx_smp_resume_suspend_descending_order_test.c
@@ -95,6 +98,7 @@ set(regression_test_cases
${SOURCE_DIR}/threadx_thread_create_preemption_threshold_test.c
${SOURCE_DIR}/threadx_thread_delayed_suspension_test.c
${SOURCE_DIR}/threadx_thread_information_test.c
+ ${SOURCE_DIR}/threadx_thread_misaligned_stack_test.c
${SOURCE_DIR}/threadx_thread_multi_level_preemption_threshold_test.c
${SOURCE_DIR}/threadx_thread_multiple_non_current_test.c
${SOURCE_DIR}/threadx_thread_multiple_sleep_test.c
@@ -111,7 +115,10 @@ set(regression_test_cases
${SOURCE_DIR}/threadx_thread_sleep_for_100ticks_test.c
${SOURCE_DIR}/threadx_thread_sleep_terminate_test.c
${SOURCE_DIR}/threadx_thread_stack_checking_test.c
+ ${SOURCE_DIR}/threadx_thread_stack_fill_value_test.c
${SOURCE_DIR}/threadx_thread_terminate_delete_test.c
+ ${SOURCE_DIR}/threadx_thread_exit_callback_transition_test.c
+ ${SOURCE_DIR}/threadx_smp_thread_exit_callback_remote_test.c
${SOURCE_DIR}/threadx_thread_time_slice_change_test.c
${SOURCE_DIR}/threadx_thread_wait_abort_and_isr_test.c
${SOURCE_DIR}/threadx_thread_wait_abort_test.c
@@ -124,6 +131,7 @@ set(regression_test_cases
${SOURCE_DIR}/threadx_timer_multiple_test.c
${SOURCE_DIR}/threadx_timer_simple_test.c
${SOURCE_DIR}/threadx_trace_basic_test.c
+ ${SOURCE_DIR}/threadx_trace_entry_update_test.c
${SOURCE_DIR}/threadx_initialize_kernel_setup_test.c)
add_custom_command(
@@ -162,3 +170,19 @@ foreach(test_case ${regression_test_cases})
target_link_libraries(${test_name} PRIVATE azrtos::threadx_smp)
add_test(${CMAKE_BUILD_TYPE}::${test_name} ${test_name})
endforeach()
+
+add_executable(threadx_smp_execution_profile_get_test
+ ${SOURCE_DIR}/threadx_smp_execution_profile_get_test.c
+ ${REPO_ROOT}/utility/execution_profile_kit/smp_version/tx_execution_profile.c)
+target_include_directories(threadx_smp_execution_profile_get_test
+ PRIVATE
+ ${SOURCE_DIR}/execution_profile_test
+ ${REPO_ROOT}/utility/execution_profile_kit/smp_version)
+target_compile_definitions(threadx_smp_execution_profile_get_test
+ PRIVATE CTEST BATCH_TEST TEST_STACK_SIZE_PRINTF=4096)
+if(NOT MSVC)
+ target_compile_options(threadx_smp_execution_profile_get_test PRIVATE -m64)
+ target_link_options(threadx_smp_execution_profile_get_test PRIVATE -m64)
+endif()
+add_test(${CMAKE_BUILD_TYPE}::threadx_smp_execution_profile_get_test
+ threadx_smp_execution_profile_get_test)
diff --git a/test/smp/cmake/threadx_smp/CMakeLists.txt b/test/smp/cmake/threadx_smp/CMakeLists.txt
index 568fece4..a2e17636 100644
--- a/test/smp/cmake/threadx_smp/CMakeLists.txt
+++ b/test/smp/cmake/threadx_smp/CMakeLists.txt
@@ -45,6 +45,7 @@ else()
endif()
configure_file(${TX_USER_FILE} ${CUSTOM_INC_DIR}/tx_user.h COPYONLY)
target_include_directories(${PROJECT_NAME}
+ SYSTEM
PUBLIC
${CUSTOM_INC_DIR}
)
diff --git a/test/smp/cmake/threadx_smp/common_smp/CMakeLists.txt b/test/smp/cmake/threadx_smp/common_smp/CMakeLists.txt
index 646b200b..770379af 100644
--- a/test/smp/cmake/threadx_smp/common_smp/CMakeLists.txt
+++ b/test/smp/cmake/threadx_smp/common_smp/CMakeLists.txt
@@ -214,6 +214,7 @@ target_sources(${PROJECT_NAME}
# Add the Common/inc directory to the project include list
target_include_directories(${PROJECT_NAME}
+ SYSTEM
PUBLIC
${CURRENT_DIR}/inc
)
diff --git a/test/smp/cmake/threadx_smp/ports_smp/linux/gnu/CMakeLists.txt b/test/smp/cmake/threadx_smp/ports_smp/linux/gnu/CMakeLists.txt
index 9c51522c..64d97255 100644
--- a/test/smp/cmake/threadx_smp/ports_smp/linux/gnu/CMakeLists.txt
+++ b/test/smp/cmake/threadx_smp/ports_smp/linux/gnu/CMakeLists.txt
@@ -25,6 +25,7 @@ target_sources(${PROJECT_NAME}
)
target_include_directories(${PROJECT_NAME}
+ SYSTEM
PUBLIC
${CURRENT_DIR}/inc
)
diff --git a/test/smp/cmake/threadx_smp/ports_smp/win64/vs_2022/CMakeLists.txt b/test/smp/cmake/threadx_smp/ports_smp/win64/vs_2022/CMakeLists.txt
index 6b219bb2..8635647a 100644
--- a/test/smp/cmake/threadx_smp/ports_smp/win64/vs_2022/CMakeLists.txt
+++ b/test/smp/cmake/threadx_smp/ports_smp/win64/vs_2022/CMakeLists.txt
@@ -24,6 +24,7 @@ target_sources(${PROJECT_NAME}
)
target_include_directories(${PROJECT_NAME}
+ SYSTEM
PUBLIC
${CURRENT_DIR}/inc
)