blob: 42d22aafc78dd0fc5c2106d5c0664a2494419059 [file] [log] [blame]
Leonardo Sandoval9dfdd1b2020-08-06 17:08:11 -05001#!/usr/bin/env bash
Fathi Boudra422bf772019-12-02 11:10:16 +02002#
laurenw-armafdc3bc2022-09-14 15:31:42 -05003# Copyright (c) 2019-2022, Arm Limited. All rights reserved.
Fathi Boudra422bf772019-12-02 11:10:16 +02004#
5# SPDX-License-Identifier: BSD-3-Clause
6#
7
8set -e
9
10in_red() {
11 echo "$(tput setaf 1)${1:?}$(tput sgr0)"
12}
13export -f in_red
14
15in_green() {
16 echo "$(tput setaf 2)${1:?}$(tput sgr0)"
17}
18export -f in_green
19
20in_yellow() {
21 echo "$(tput setaf 3)${1:?}$(tput sgr0)"
22}
23export -f in_yellow
24
25print_success() {
26 in_green "$1: SUCCESS"
27}
28export -f print_success
29
30print_failure() {
31 in_red "$1: FAILURE"
32}
33export -f print_failure
34
35print_unstable() {
36 in_yellow "$1: UNSTABLE"
37}
38export -f print_unstable
39
40gen_makefile() {
41 local num="$(find -name "*.test" -type f | wc -l)"
42 local i=0
43
44 cat <<EOF >Makefile
45SHELL=/bin/bash
46
47all:
48
49EOF
50
Juan Pablo Conde6eb0d1e2023-12-08 13:52:21 -060051 # If we're using local checkouts for either TF-A or TFTF, we must
52 # serialise builds
Fathi Boudra422bf772019-12-02 11:10:16 +020053 while [ "$i" -lt "$num" ]; do
54 {
Sandrine Bailleux4694fd32022-04-15 14:04:35 +020055 printf "all: %04d_run %04d_build\n" "$i" "$i"
Fathi Boudra422bf772019-12-02 11:10:16 +020056 if upon "$serialize_builds" && [ "$i" -gt 0 ]; then
Sandrine Bailleux4694fd32022-04-15 14:04:35 +020057 printf "%04d_build: %04d_build\n" "$i" "$((i - 1))"
Fathi Boudra422bf772019-12-02 11:10:16 +020058 fi
59 echo
60 } >>Makefile
61 let "++i"
62 done
63
64 cat <<EOF >>Makefile
65
66%_run: %_build
67 @run_one_test "\$@"
68
69%_build:
70 @run_one_test "\$@"
71EOF
72}
73
74# This function is invoked from the Makefile. Descriptor 5 points to the active
75# terminal.
76run_one_test() {
Juan Pablo Conde6eb0d1e2023-12-08 13:52:21 -060077 source "$ci_root/utils.sh"
78
Fathi Boudra422bf772019-12-02 11:10:16 +020079 id="${1%%_*}"
80 action="${1##*_}"
Boyan Karatotevd5090322025-10-01 10:06:37 +010081 # Subdirectories could change while traversing but all our files are in
82 # the top level directory.
83 test_file="$(find -maxdepth 1 -name "$id*.test" -printf "%f\n")"
Fathi Boudra422bf772019-12-02 11:10:16 +020084
85 mkdir -p "$id"
86
87 # Copy the test_file into the workspace directory with the name
88 # TEST_DESC, just like Jenkins would.
89 export TEST_DESC="$(basename "$test_file")"
90 cp "$test_file" "$id/TEST_DESC"
91
Zelalem219df412020-05-17 19:21:20 -050092 workspace="$id" test_desc="$test_file" cc_enable="$cc_enable" "$ci_root/script/parse_test.sh"
Fathi Boudra422bf772019-12-02 11:10:16 +020093
94 set -a
95 source "$id/env"
96 set +a
97
Juan Pablo Conde6eb0d1e2023-12-08 13:52:21 -060098 run_config_tfa="$(echo "$RUN_CONFIG" | awk -F, '{print $1}')"
99 run_config_tfut="$(echo "$RUN_CONFIG" | awk -F, '{print $2}')"
100
Fathi Boudra422bf772019-12-02 11:10:16 +0200101 # Makefiles don't like commas and colons in file names. We therefore
102 # replace them with _
103 config_subst="$(echo "$TEST_CONFIG" | tr ',:' '_')"
104 config_string="$id: $TEST_GROUP/$TEST_CONFIG"
105 workspace="$workspace/$TEST_GROUP/$config_subst"
106 mkdir -p "$workspace"
107
108 log_file="$workspace/artefacts/build.log"
Boyan Karatotev49106802025-05-02 10:08:43 +0100109 # fd 5 is the terminal where run_local_ci.sh is running. *Only* status
110 # of the run is printed as this is shared for all jobs and this may
111 # happen in parallel.
112 # Each job has its own verbose output as well. This will be progress
113 # messages but also any debugging prints. This is the default and it
114 # gets redirected to a file per job for archiving and disambiguation
115 # when running in parallel.
Boyan Karatotevf2e145b2025-08-27 15:51:46 +0100116 console_file="$workspace/console.log"
Fathi Boudra422bf772019-12-02 11:10:16 +0200117 if [ "$parallel" -gt 1 ]; then
Boyan Karatotev49106802025-05-02 10:08:43 +0100118 exec >> $console_file 2>&1
Fathi Boudra422bf772019-12-02 11:10:16 +0200119 else
Boyan Karatotev49106802025-05-02 10:08:43 +0100120 # when running in serial, no scrambling is possible so print to
121 # stdout
Boyan Karatotevf2e145b2025-08-27 15:51:46 +0100122 exec > >(tee $console_file >&5) 2>&1
Fathi Boudra422bf772019-12-02 11:10:16 +0200123 fi
124
125 # Unset make flags for build script
126 MAKEFLAGS=
127
Zelalem219df412020-05-17 19:21:20 -0500128 if [ $import_cc -eq 1 ]; then
129 # Path to plugin if there is no local reference
130 cc_path_spec=$workspace/cc_plugin
131 fi
132
Fathi Boudra422bf772019-12-02 11:10:16 +0200133 case "$action" in
134 "build")
135 echo "building: $config_string" >&5
Boyan Karatotev49106802025-05-02 10:08:43 +0100136 if ! ccpathspec="$cc_path_spec" bash $minus_x "$ci_root/script/build_package.sh"; then {
137 print_failure "$config_string (build)" >&5
Fathi Boudra422bf772019-12-02 11:10:16 +0200138 if [ "$console_file" ]; then
139 echo " see $console_file"
140 fi
141 } >&5
142 exit 1
143 fi
144 ;;
145
146 "run")
Juan Pablo Conde6eb0d1e2023-12-08 13:52:21 -0600147 #Run unit tests (TFUT)
Boyan Karatotev56d72ea2025-08-27 15:11:16 +0100148 if config_valid "$run_config_tfut"; then
Juan Pablo Conde6eb0d1e2023-12-08 13:52:21 -0600149 echo "running TFUT: $config_string" >&5
Boyan Karatotev56d72ea2025-08-27 15:11:16 +0100150
151 if upon "$skip_tfut_runs"; then
152 #No run config for TFUT
153 if grep -q -e "--BUILD UNSTABLE--" "$log_file"; then
154 print_unstable "$config_string (tfut) (not run)" >&5
155 else
156 print_success "$config_string (tfut) (not run)" >&5
157 fi
158 exit 0
159 fi
160
Juan Pablo Conde6eb0d1e2023-12-08 13:52:21 -0600161 if bash $minus_x "$ci_root/script/run_unit_tests.sh"; then
162 if grep -q -e "--BUILD UNSTABLE--" \
163 "$log_file"; then
164 print_unstable "$config_string (tfut)" >&5
165 else
166 print_success "$config_string (tfut)" >&5
167 fi
Boyan Karatotev56d72ea2025-08-27 15:11:16 +0100168 exit 0
Juan Pablo Conde6eb0d1e2023-12-08 13:52:21 -0600169 else
170 {
171 print_failure "$config_string (tfut) (run)" >&5
172 if [ "$console_file" ]; then
173 echo " see $console_file"
174 fi
175 } >&5
176 exit 1
177 fi
Juan Pablo Conde6eb0d1e2023-12-08 13:52:21 -0600178 fi
179
180 #Run TF-A
181 if echo "$run_config_tfa" | grep -q "^\(fvp\|qemu\)" && \
Fathi Boudra422bf772019-12-02 11:10:16 +0200182 not_upon "$skip_runs"; then
Juan Pablo Conde6eb0d1e2023-12-08 13:52:21 -0600183 # Local runs for FVP, QEMU, or arm_fpga unless asked not to
184 echo "running TF-A: $config_string" >&5
Zelalem219df412020-05-17 19:21:20 -0500185 if [ -n "$cc_enable" ]; then
186 # Enable of code coverage during run
187 if cc_enable="$cc_enable" trace_file_prefix=tr \
188 coverage_trace_plugin=$cc_path_spec/scripts/tools/code_coverage/fastmodel_baremetal/bmcov/model-plugin/CoverageTrace.so \
Boyan Karatotev49106802025-05-02 10:08:43 +0100189 bash $minus_x "$ci_root/script/run_package.sh"; then
Zelalem219df412020-05-17 19:21:20 -0500190 if grep -q -e "--BUILD UNSTABLE--" \
Fathi Boudra422bf772019-12-02 11:10:16 +0200191 "$log_file"; then
Zelalem219df412020-05-17 19:21:20 -0500192 print_unstable "$config_string" >&5
193 else
194 print_success "$config_string" >&5
195 if [ -d "$workspace/artefacts/release" ] && \
laurenw-armafdc3bc2022-09-14 15:31:42 -0500196 [ -f "$workspace/artefacts/release/tr-FVP_Base_RevC_2xAEMvA.cluster0.cpu0.log" ]; then
Zelalem219df412020-05-17 19:21:20 -0500197 cp $workspace/artefacts/release/*.log $workspace/artefacts/debug
198 fi
199 # Setting environmental variables for run of code coverage
200 OBJDUMP=$TOOLCHAIN/bin/aarch64-none-elf-objdump \
201 READELF=$TOOLCHAIN/bin/aarch64-none-elf-readelf \
202 ELF_FOLDER=$workspace/artefacts/debug \
203 TRACE_FOLDER=$workspace/artefacts/debug \
204 workspace=$workspace \
205 TRACE_PREFIX=tr python \
206 $cc_path_spec/scripts/tools/code_coverage/fastmodel_baremetal/bmcov/report/gen-coverage-report.py --config \
207 $cc_path_spec/scripts/tools/code_coverage/fastmodel_baremetal/bmcov/report/config_atf.py
208 fi
209 exit 0
Fathi Boudra422bf772019-12-02 11:10:16 +0200210 else
Zelalem219df412020-05-17 19:21:20 -0500211 {
Boyan Karatotev49106802025-05-02 10:08:43 +0100212 print_failure "$config_string (run)" >&5
Zelalem219df412020-05-17 19:21:20 -0500213 if [ "$console_file" ]; then
214 echo " see $console_file"
215 fi
216 } >&5
217 exit 1
Fathi Boudra422bf772019-12-02 11:10:16 +0200218 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200219 else
Boyan Karatotev49106802025-05-02 10:08:43 +0100220 if bash $minus_x "$ci_root/script/run_package.sh"; then
Zelalem219df412020-05-17 19:21:20 -0500221 if grep -q -e "--BUILD UNSTABLE--" \
222 "$log_file"; then
223 print_unstable "$config_string" >&5
224 else
225 print_success "$config_string" >&5
226 fi
227 exit 0
228 else
229 {
Boyan Karatotev49106802025-05-02 10:08:43 +0100230 print_failure "$config_string (run)" >&5
Zelalem219df412020-05-17 19:21:20 -0500231 if [ "$console_file" ]; then
232 echo " see $console_file"
233 fi
234 } >&5
235 exit 1
Fathi Boudra422bf772019-12-02 11:10:16 +0200236 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200237 fi
238 else
Javier Almansa Sobrino412d3612020-05-22 17:53:12 +0100239 # Local runs for arm_fpga platform
Juan Pablo Conde6eb0d1e2023-12-08 13:52:21 -0600240 if echo "$run_config_tfa" | grep -q "^arm_fpga" && \
Javier Almansa Sobrino412d3612020-05-22 17:53:12 +0100241 not_upon "$skip_runs"; then
242 echo "running: $config_string" >&5
Boyan Karatotev49106802025-05-02 10:08:43 +0100243 if bash $minus_x "$ci_root/script/test_fpga_payload.sh"; then
Javier Almansa Sobrino412d3612020-05-22 17:53:12 +0100244 if grep -q -e "--BUILD UNSTABLE--" \
245 "$log_file"; then
246 print_unstable "$config_string" >&5
247 else
248 print_success "$config_string" >&5
249 fi
250 exit 0
251 else
252 {
Boyan Karatotev49106802025-05-02 10:08:43 +0100253 print_failure "$config_string (run)" >&5
Javier Almansa Sobrino412d3612020-05-22 17:53:12 +0100254 if [ "$console_file" ]; then
255 echo " see $console_file"
256 fi
257 } >&5
258 exit 1
259 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200260 else
Javier Almansa Sobrino412d3612020-05-22 17:53:12 +0100261 if grep -q -e "--BUILD UNSTABLE--" \
262 "$log_file"; then
263 print_unstable "$config_string (not run)" >&5
264 else
265 print_success "$config_string (not run)" >&5
266 fi
267 exit 0
Fathi Boudra422bf772019-12-02 11:10:16 +0200268 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200269 fi
270 ;;
271
272 *)
273 in_red "Invalid action: $action!" >&5
274 exit 1
275 ;;
276 esac
277}
278export -f run_one_test
279
280workspace="${workspace:?}"
Boyan Karatotev51800062025-05-01 16:55:44 +0100281if [[ "$retain_paths" -eq 0 ]]; then
Jayanth Dodderi Chidanand985bb2f2025-04-09 17:02:39 +0100282 gcc_space="${gcc_space:?Environment variable 'gcc_space' must be set}"
283fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200284ci_root="$(readlink -f "$(dirname "$0")/..")"
285
286# If this script was invoked with bash -x, have subsequent build/run invocations
287# to use -x as well.
288if echo "$-" | grep -q "x"; then
289 export minus_x="-x"
290fi
291
Leonardo Sandoval8f9cea62020-07-10 11:08:55 -0500292# if test_groups variable is not present, check if it can be formed at least from 'test_group' and 'tf_config'
293# environment variables
294if [ -z "${test_groups}" ]; then
295 if [ -n "${test_group}" -a -n "${tf_config}" ]; then
296
297 # default the rest to nil if not present
298 tftf_config="${tftf_config:-nil}"
Manish Pandeyb466cf22021-02-12 13:15:40 +0000299 spm_config="${spm_config:-nil}"
Leonardo Sandoval8f9cea62020-07-10 11:08:55 -0500300 run_config="${run_config:-nil}"
301
Manish Pandeyb466cf22021-02-12 13:15:40 +0000302 # construct the 'long form' so it takes into account all possible configurations
Chris Kay4f7846a2025-08-04 19:56:35 +0100303 if echo ${test_group} | grep -q '^spm-'; then
304 tg=$(printf "%s/%s,%s,%s:%s" "${test_group}" "${spm_config}" "${tf_config}" "${tftf_config}" "${run_config}")
Manish V Badarkhe5248c7f2025-04-11 13:22:16 +0100305 elif echo ${test_group} | grep -q '^rmm-'; then
Chris Kay4f7846a2025-08-04 19:56:35 +0100306 tg=$(printf "%s/%s,%s,%s,%s:%s" "${test_group}" "${rmm_config}" "${tf_config}" "${tftf_config}" "${spm_config}" "${run_config}")
Manish Pandeyb466cf22021-02-12 13:15:40 +0000307 else
Chris Kay4f7846a2025-08-04 19:56:35 +0100308 tg=$(printf "%s/%s,%s,%s:%s" "${test_group}" "${tf_config}" "${tftf_config}" "${spm_config}" "${run_config}")
Manish Pandeyb466cf22021-02-12 13:15:40 +0000309 fi
Leonardo Sandoval8f9cea62020-07-10 11:08:55 -0500310
311 # trim any ',nil:' from it
Manish Pandeyb466cf22021-02-12 13:15:40 +0000312 tg="${tg/,nil:/:}" tg="${tg/,nil:/:}"; tg="${tg/,nil:/:}"; tg="${tg/,nil:/:}"
Leonardo Sandoval8f9cea62020-07-10 11:08:55 -0500313
314 # finally exported
315 export test_groups="${tg}"
316 fi
317fi
318
Fathi Boudra422bf772019-12-02 11:10:16 +0200319# For a local run, when some variables as specified as "?", launch zenity to
320# prompt for test config via. GUI. If it's "??", then choose a directory.
321if [ "$test_groups" = "?" -o "$test_groups" = "??" ]; then
322 zenity_opts=(
323 --file-selection
324 --filename="$ci_root/group/README"
325 --multiple
326 --title "Choose test config"
327 )
328
329 if [ "$test_groups" = "??" ]; then
330 zenity_opts+=("--directory")
331 fi
332
333 # In case of multiple selections, zenity returns absolute paths of files
334 # separated by '|'. We remove the pipe characters, and make the paths
335 # relative to the group directory.
336 selections="$(cd "$ci_root"; zenity ${zenity_opts[*]})"
337 test_groups="$(echo "$selections" | tr '|' ' ')"
338 test_groups="$(echo "$test_groups" | sed "s#$ci_root/group/##g")"
339fi
340
341test_groups="${test_groups:?}"
342local_count=0
343
344if [ -z "$tf_root" ]; then
Juan Pablo Conde6eb0d1e2023-12-08 13:52:21 -0600345 in_red "NOTE: NOT using local work tree for TF-A"
Fathi Boudra422bf772019-12-02 11:10:16 +0200346else
347 tf_root="$(readlink -f $tf_root)"
348 tf_refspec=
Juan Pablo Conde6eb0d1e2023-12-08 13:52:21 -0600349 in_green "Using local work tree for TF-A"
Fathi Boudra422bf772019-12-02 11:10:16 +0200350 let "++local_count"
351fi
352
353if [ -z "$tftf_root" ]; then
354 in_red "NOTE: NOT using local work tree for TFTF"
355 tforg_user="${tforg_user:?}"
356else
357 tftf_root="$(readlink -f $tftf_root)"
Zelalem219df412020-05-17 19:21:20 -0500358 tftf_refspec=
Fathi Boudra422bf772019-12-02 11:10:16 +0200359 in_green "Using local work tree for TFTF"
360 let "++local_count"
361fi
362
Zelalem219df412020-05-17 19:21:20 -0500363if [ -n "$cc_enable" ]; then
364 in_green "Code Coverage enabled"
365 if [ -z "$TOOLCHAIN" ]; then
366 in_red "TOOLCHAIN not set for code coverage: ex: export TOOLCHAIN=<path to toolchain>/gcc-arm-<gcc version>-x86_64-aarch64-none-elf"
367 exit 1
368 fi
369 if [ -n "$cc_path" ]; then
370 in_green "Code coverage plugin path specified"
371 cc_path_spec=$cc_path
372 import_cc=0
373 else
374 in_red "Code coverage plugin path not specified"
375 cc_path_spec="$workspace/cc_plugin"
376 import_cc=1
377 fi
Jimmy Brisson4347d8a2020-07-24 10:26:16 -0500378else
379 in_green "Code coverage disabled"
380 import_cc=1
Zelalem219df412020-05-17 19:21:20 -0500381fi
382
Olivier Deprezf1d1fcd2019-12-16 14:09:43 +0100383if [ -z "$spm_root" ]; then
384 in_red "NOTE: NOT using local work tree for SPM"
385else
386 spm_root="$(readlink -f $spm_root)"
387 spm_refspec=
388 in_green "Using local work tree for SPM"
389 let "++local_count"
390fi
391
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000392if [ -z "$rmm_root" ]; then
393 in_red "NOTE: NOT using local work tree for RMM"
394else
395 rmm_root="$(readlink -f $rmm_root)"
396 rmm_refspec=
397 in_green "Using local work tree for RMM"
398 let "++local_count"
399fi
400
401if [ -z "$tfm_tests_root" ]; then
402 in_red "NOTE: NOT using local work tree for TF-M-TESTS"
403else
404 tfm_tests_root="$(readlink -f $tfm_tests_root)"
405 tfm_tests_refspec=
406 in_green "Using local work tree for TF-M-TESTS"
407 let "++local_count"
408fi
409
410if [ -z "$tfm_extras_root" ]; then
411 in_red "NOTE: NOT using local work tree for TF-M-EXTRAS"
412else
413 tfm_extras_root="$(readlink -f $tfm_extras_root)"
414 tfm_extras_refspec=
415 in_green "Using local work tree for TF-M-EXTRAS"
416 let "++local_count"
417fi
418
Fathi Boudra422bf772019-12-02 11:10:16 +0200419# User preferences
Javier Almansa Sobrinoe8363182020-11-10 16:40:53 +0000420[ "$connect_debugger" ] && [ "$connect_debugger" -eq 1 ] && user_connect_debugger=1
421user_test_run="${user_connect_debugger:-$test_run}"
Fathi Boudra422bf772019-12-02 11:10:16 +0200422user_keep_going="$keep_going"
423user_primary_live="$primary_live"
Javier Almansa Sobrinoe8363182020-11-10 16:40:53 +0000424user_connect_debugger="${user_connect_debugger:-0}"
Fathi Boudra422bf772019-12-02 11:10:16 +0200425
426export ci_root
Boyan Karatotevffedd182025-10-02 08:47:45 +0100427export dont_clean="${dont_clean:-0}"
Fathi Boudra422bf772019-12-02 11:10:16 +0200428export local_ci=1
429export parallel
430export test_run=0
431export primary_live=0
Zelalem219df412020-05-17 19:21:20 -0500432export cc_path_spec
433export import_cc
Javier Almansa Sobrinoe8363182020-11-10 16:40:53 +0000434export connect_debugger="$user_connect_debugger"
Fathi Boudra422bf772019-12-02 11:10:16 +0200435
Fathi Boudra422bf772019-12-02 11:10:16 +0200436source "$ci_root/utils.sh"
437
Boyan Karatotevffedd182025-10-02 08:47:45 +0100438if not_upon "$dont_clean"; then
439 rm -rf "$workspace"
440fi
441mkdir -p "$workspace"
442
Zelalem219df412020-05-17 19:21:20 -0500443# Enable of code coverage and whether there is a local plugin
444if upon "$cc_enable" && not_upon "$cc_path"; then
445 no_cc_t=1
446else
447 no_cc_t=0
448fi
449
450# Use clone_repos.sh to clone and share repositories that aren't local.
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000451no_tf="$tf_root" no_tftf="$tftf_root" no_spm="$spm_root" no_rmm="$rmm_root" \
452no_ci="$ci_root" no_cc="$import_cc" no_tfm_tests="$tfm_tests_root" no_tfm_extras="$tfm_extras_root" \
Fathi Boudra422bf772019-12-02 11:10:16 +0200453 bash $minus_x "$ci_root/script/clone_repos.sh"
454
455set -a
456source "$workspace/env"
457set +a
458
Fathi Boudra422bf772019-12-02 11:10:16 +0200459export -f upon not_upon
460
461# Generate test descriptions
462"$ci_root/script/gen_test_desc.py"
463
464# Iterate through test files in workspace
465pushd "$workspace"
466
467if not_upon "$parallel" || echo "$parallel" | grep -vq "[0-9]"; then
468 parallel=1
469 test_run="$user_test_run"
Fathi Boudra422bf772019-12-02 11:10:16 +0200470 primary_live="$user_primary_live"
471fi
472
473if [ "$parallel" -gt 1 ]; then
474 msg="Running at most $parallel jobs in parallel"
475 if upon "$serialize_builds"; then
476 msg+=" (builds serialized)"
477 fi
478 msg+="..."
479fi
480
481# Generate Makefile
482gen_makefile
483
484if upon "$msg"; then
485 echo "$msg"
486 echo
487fi
488
489keep_going="${user_keep_going:-1}"
490if not_upon "$keep_going"; then
491 keep_going=
492fi
493
Boyan Karatotev49106802025-05-02 10:08:43 +0100494MAKEFLAGS= make -r -j "$parallel" ${keep_going+-k} 5>&1 |& tee "make.log"