summaryrefslogtreecommitdiff
path: root/test/freertos/cmake/run.sh
blob: 896a5c37a4ab05f0a66f66d3adfd2efa85011ee1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
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