blob: 8847cbca7832f9685585d5f0ae77064d87bd450d [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
29export tfut_root="${tfut_root:-$workspace/tfut}"
30
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
70# Cleanup actions
71trap_with_sig cleanup SIGINT SIGHUP SIGTERM EXIT
Juan Pablo Conde6eb0d1e2023-12-08 13:52:21 -060072
73run_test() {
74 test="${1:?}"
75 echo "Running test $test..."
76 "./$@"
77}
78
79export -f run_test
80
81# Accept BIN_MODE from environment, or default to release. If bin_mode is set
82# and non-empty (intended to be set from command line), that takes precedence.
83pkg_bin_mode="${BIN_MODE:-release}"
84bin_mode="${bin_mode:-$pkg_bin_mode}"
85
86# Change directory so that all binaries can be accessed realtive to where they
87# lie
88run_cwd="$artefacts/$bin_mode"
89cd "$run_cwd"
90
91run_sh="$run_root/run.sh"
92
93#Generate run.sh file
94echo "echo \"Running unit tests\"" > "$run_sh"
95echo "pwd" >> "$run_sh"
96cat "tfut_artefacts.txt" | while read test; do
97 if upon "$test_run"; then
98 echo "run_test $test \$@" >> "$run_sh"
Juan Pablo Conde3b0380c2024-01-13 13:40:59 -060099 else
100 echo "name=\"$test\" launch run_test $test \$@ " \
101 "&> \"$run_root/${test}_output.txt\" &" >> "$run_sh"
Juan Pablo Conde6eb0d1e2023-12-08 13:52:21 -0600102 fi
103done
104chmod +x "$run_sh"
105
106# Run the unit tests directly
107if upon "$test_run"; then
108 echo
109 "$run_sh" "$@" -v -c
110 exit 0
111fi
Juan Pablo Conde3b0380c2024-01-13 13:40:59 -0600112
113# For an automated run, export a known variable so that we can identify stale
114# processes spawned by Trusted Firmware CI by inspecting its environment.
115export TRUSTED_FIRMWARE_CI="1"
116
117# Otherwise, run tests in background and monitor them.
118if upon "$jenkins_run"; then
119 "$run_sh" "$@" -ojunit -v
120else
121 "$run_sh" "$@" -c -v
122fi
123batch_pid=$!
124
125# Wait for all children. Note that the wait below is *not* a timed wait.
126result=0
127
128set +e
129pushd "$pid_dir"
130
131timeout=3600
132
133echo
134
135while :; do
136 readarray -d '' all < <(find "${pid_dir}" -name '*.pid' -print0)
137 readarray -d '' succeeded < <(find "${pid_dir}" -name '*.success' -print0)
138 readarray -d '' failed < <(find "${pid_dir}" -name '*.fail' -print0)
139
140 all=("${all[@]##${pid_dir}/}")
141 all=("${all[@]%%.pid}")
142
143 succeeded=("${succeeded[@]##${pid_dir}/}")
144 succeeded=("${succeeded[@]%%.success}")
145
146 failed=("${failed[@]##${pid_dir}/}")
147 failed=("${failed[@]%%.fail}")
148
149 completed=("${succeeded[@]}" "${failed[@]}")
150
151 readarray -t remaining < <( \
152 comm -23 \
153 <(printf '%s\n' "${all[@]}" | sort) \
154 <(printf '%s\n' "${completed[@]}" | sort) \
155 )
156
157 if [ ${#remaining[@]} = 0 ]; then
158 break
159 fi
160
161 if [ ${timeout} = 0 ]; then
162 echo "- Timeout exceeded! Killing all processes..."
163
164 cleanup
165 fi
166
167 timeout=$((${timeout} - 5)) && sleep 5
168done
169
170echo
171
172if [ ${#failed[@]} != 0 ]; then
173 echo "${#failed[@]} tests failed:"
174 echo
175
176 for test in "${failed[@]}"; do
177 echo " - Test ${test}: ${test}_output.txt"
178 done
179
180 echo
181
182 result=1
183fi
184
185popd
186
187if [ "$result" -eq 0 ]; then
188 echo "Unit testing success!"
189else
190 echo "Unit testing failed!"
191fi
192
193if upon "$jenkins_run"; then
194 echo
195 echo "Artefacts location: $BUILD_URL."
196 echo
197fi
198
199exit "$result"