blob: 7d4384d5cf358e46cbb370aa3d565f094129ba7d [file] [log] [blame]
Juan Pablo Conde6eb0d1e2023-12-08 13:52:21 -06001#!/usr/bin/env bash
2#
3# Copyright (c) 2024 Arm Limited. All rights reserved.
4#
5# SPDX-License-Identifier: BSD-3-Clause
6#
7
8# Runs the built unit tests
9
10set -e
11
12ci_root="$(readlink -f "$(dirname "$0")/..")"
13source "$ci_root/script/run_common.sh"
14source "$ci_root/utils.sh"
15
Juan Pablo Conde3b0380c2024-01-13 13:40:59 -060016export -f launch
17
Juan Pablo Conde6eb0d1e2023-12-08 13:52:21 -060018artefacts="${artefacts-$workspace/artefacts}"
19
20run_root="$workspace/unit_tests/run"
Juan Pablo Conde3b0380c2024-01-13 13:40:59 -060021pid_dir="$workspace/unit_tests/pids"
Juan Pablo Conde6eb0d1e2023-12-08 13:52:21 -060022
23mkdir -p "$run_root"
Juan Pablo Conde3b0380c2024-01-13 13:40:59 -060024mkdir -p "$pid_dir"
Juan Pablo Conde6eb0d1e2023-12-08 13:52:21 -060025
26export run_root
Juan Pablo Conde3b0380c2024-01-13 13:40:59 -060027export pid_dir
Juan Pablo Conde6eb0d1e2023-12-08 13:52:21 -060028
Edward Potapovdb31e702025-06-30 16:28:40 -050029export tfut_root="${tfut_root:-$workspace/tf-a-unit-tests}"
Juan Pablo Conde6eb0d1e2023-12-08 13:52:21 -060030
Juan Pablo Conde3b0380c2024-01-13 13:40:59 -060031kill_and_reap() {
32 local gid
33 # Kill an active process. Ignore errors
34 [ "$1" ] || return 0
35 kill -0 "$1" &>/dev/null || return 0
36
37 # Kill the children
38 kill -- "-$1" &>/dev/null || true
39 # Kill the group
40 { gid="$(awk '{print $5}' < /proc/$1/stat)";} 2>/dev/null || return
41 kill -SIGTERM -- "-$gid" &>/dev/null || true
42 wait "$gid" &>/dev/null || true
43}
44
45# Perform clean up and ignore errors
46cleanup() {
47 local pid
48 local sig
49
50 pushd "$pid_dir"
51 set +e
52
53 sig=${1:-SIGINT}
54 echo "signal received: $sig"
55
56 if [ "$sig" != "EXIT" ]; then
57 # Kill all background processes so far and wait for them
58 while read pid; do
59 pid="$(cat $pid)"
60 echo $pid
61
62 kill_and_reap "$pid"
63
64 done < <(find -name '*.pid')
65 fi
66
67 popd
68}
69
Edward Potapovdb31e702025-06-30 16:28:40 -050070# Check coverage and make reports
71run_coverage() {
72 if [ -f "tfut_coverage.txt" ]; then
73 COVERAGE="ON"
74 else
75 COVERAGE="OFF"
76 fi
77
78 # Switch to the tfut root directory to check for coverage
79 pushd "$tfut_root/build"
80 if [ "$COVERAGE" = "ON" ]; then
81 echo "Generating coverage report..."
82 make coverage_report
83 cp -r ./tf-a-unit-tests-coverage "$workspace/unit_tests/"
84 cp -r ./trusted-firmware-a-coverage "$workspace/unit_tests/"
85 mkdir "$workspace/trace_report/"
86 cp -r ./trusted-firmware-a-coverage/* "$workspace/trace_report/"
87 cp ./coverage.info "$workspace/trace_report/"
88 cat > "$workspace/config_file.json" <<EOF
89{
90 "configuration": {
91 "sources": [
92 {
93 "type": "git",
94 "URL": "https://review.trustedfirmware.org/TF-A/trusted-firmware-a",
95 "LOCATION": "trusted-firmware-a"
96 }
97 ]
98 }
99}
100EOF
101 else
102 echo "Code coverage is disabled."
103 fi
104 popd
105}
106
Juan Pablo Conde3b0380c2024-01-13 13:40:59 -0600107# Cleanup actions
108trap_with_sig cleanup SIGINT SIGHUP SIGTERM EXIT
Juan Pablo Conde6eb0d1e2023-12-08 13:52:21 -0600109
110run_test() {
111 test="${1:?}"
112 echo "Running test $test..."
113 "./$@"
114}
115
116export -f run_test
117
118# Accept BIN_MODE from environment, or default to release. If bin_mode is set
119# and non-empty (intended to be set from command line), that takes precedence.
120pkg_bin_mode="${BIN_MODE:-release}"
121bin_mode="${bin_mode:-$pkg_bin_mode}"
122
123# Change directory so that all binaries can be accessed realtive to where they
124# lie
125run_cwd="$artefacts/$bin_mode"
126cd "$run_cwd"
127
128run_sh="$run_root/run.sh"
129
130#Generate run.sh file
131echo "echo \"Running unit tests\"" > "$run_sh"
132echo "pwd" >> "$run_sh"
133cat "tfut_artefacts.txt" | while read test; do
134 if upon "$test_run"; then
135 echo "run_test $test \$@" >> "$run_sh"
Juan Pablo Conde3b0380c2024-01-13 13:40:59 -0600136 else
137 echo "name=\"$test\" launch run_test $test \$@ " \
138 "&> \"$run_root/${test}_output.txt\" &" >> "$run_sh"
Juan Pablo Conde6eb0d1e2023-12-08 13:52:21 -0600139 fi
140done
141chmod +x "$run_sh"
142
143# Run the unit tests directly
144if upon "$test_run"; then
145 echo
146 "$run_sh" "$@" -v -c
Edward Potapovdb31e702025-06-30 16:28:40 -0500147 run_coverage
Juan Pablo Conde6eb0d1e2023-12-08 13:52:21 -0600148 exit 0
149fi
Juan Pablo Conde3b0380c2024-01-13 13:40:59 -0600150
151# For an automated run, export a known variable so that we can identify stale
152# processes spawned by Trusted Firmware CI by inspecting its environment.
153export TRUSTED_FIRMWARE_CI="1"
154
155# Otherwise, run tests in background and monitor them.
156if upon "$jenkins_run"; then
157 "$run_sh" "$@" -ojunit -v
158else
159 "$run_sh" "$@" -c -v
160fi
Edward Potapovdb31e702025-06-30 16:28:40 -0500161run_coverage
Juan Pablo Conde3b0380c2024-01-13 13:40:59 -0600162batch_pid=$!
163
164# Wait for all children. Note that the wait below is *not* a timed wait.
165result=0
166
167set +e
168pushd "$pid_dir"
169
170timeout=3600
171
172echo
173
174while :; do
175 readarray -d '' all < <(find "${pid_dir}" -name '*.pid' -print0)
176 readarray -d '' succeeded < <(find "${pid_dir}" -name '*.success' -print0)
177 readarray -d '' failed < <(find "${pid_dir}" -name '*.fail' -print0)
178
179 all=("${all[@]##${pid_dir}/}")
180 all=("${all[@]%%.pid}")
181
182 succeeded=("${succeeded[@]##${pid_dir}/}")
183 succeeded=("${succeeded[@]%%.success}")
184
185 failed=("${failed[@]##${pid_dir}/}")
186 failed=("${failed[@]%%.fail}")
187
188 completed=("${succeeded[@]}" "${failed[@]}")
189
190 readarray -t remaining < <( \
191 comm -23 \
192 <(printf '%s\n' "${all[@]}" | sort) \
193 <(printf '%s\n' "${completed[@]}" | sort) \
194 )
195
196 if [ ${#remaining[@]} = 0 ]; then
197 break
198 fi
199
200 if [ ${timeout} = 0 ]; then
201 echo "- Timeout exceeded! Killing all processes..."
202
203 cleanup
204 fi
205
206 timeout=$((${timeout} - 5)) && sleep 5
207done
208
209echo
210
211if [ ${#failed[@]} != 0 ]; then
212 echo "${#failed[@]} tests failed:"
213 echo
214
215 for test in "${failed[@]}"; do
216 echo " - Test ${test}: ${test}_output.txt"
217 done
218
219 echo
220
221 result=1
222fi
223
224popd
225
226if [ "$result" -eq 0 ]; then
227 echo "Unit testing success!"
228else
229 echo "Unit testing failed!"
230fi
231
232if upon "$jenkins_run"; then
233 echo
234 echo "Artefacts location: $BUILD_URL."
235 echo
236fi
237
238exit "$result"