blob: 56fa81c6a0eb870370b8dedb4e2327bda13d2d1e [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
Boyan Karatotev9b70ac92025-03-06 15:30:45 +000051 # If serialized builds were requested
Fathi Boudra422bf772019-12-02 11:10:16 +020052 while [ "$i" -lt "$num" ]; do
53 {
Sandrine Bailleux4694fd32022-04-15 14:04:35 +020054 printf "all: %04d_run %04d_build\n" "$i" "$i"
Fathi Boudra422bf772019-12-02 11:10:16 +020055 if upon "$serialize_builds" && [ "$i" -gt 0 ]; then
Sandrine Bailleux4694fd32022-04-15 14:04:35 +020056 printf "%04d_build: %04d_build\n" "$i" "$((i - 1))"
Fathi Boudra422bf772019-12-02 11:10:16 +020057 fi
58 echo
59 } >>Makefile
60 let "++i"
61 done
62
63 cat <<EOF >>Makefile
64
65%_run: %_build
66 @run_one_test "\$@"
67
68%_build:
69 @run_one_test "\$@"
70EOF
71}
72
73# This function is invoked from the Makefile. Descriptor 5 points to the active
74# terminal.
75run_one_test() {
76 id="${1%%_*}"
77 action="${1##*_}"
78 test_file="$(find -name "$id*.test" -printf "%f\n")"
79
80 mkdir -p "$id"
81
82 # Copy the test_file into the workspace directory with the name
83 # TEST_DESC, just like Jenkins would.
84 export TEST_DESC="$(basename "$test_file")"
85 cp "$test_file" "$id/TEST_DESC"
86
Zelalem219df412020-05-17 19:21:20 -050087 workspace="$id" test_desc="$test_file" cc_enable="$cc_enable" "$ci_root/script/parse_test.sh"
Fathi Boudra422bf772019-12-02 11:10:16 +020088
89 set -a
90 source "$id/env"
91 set +a
92
93 # Makefiles don't like commas and colons in file names. We therefore
94 # replace them with _
95 config_subst="$(echo "$TEST_CONFIG" | tr ',:' '_')"
96 config_string="$id: $TEST_GROUP/$TEST_CONFIG"
97 workspace="$workspace/$TEST_GROUP/$config_subst"
98 mkdir -p "$workspace"
99
100 log_file="$workspace/artefacts/build.log"
Boyan Karatotev49106802025-05-02 10:08:43 +0100101 # fd 5 is the terminal where run_local_ci.sh is running. *Only* status
102 # of the run is printed as this is shared for all jobs and this may
103 # happen in parallel.
104 # Each job has its own verbose output as well. This will be progress
105 # messages but also any debugging prints. This is the default and it
106 # gets redirected to a file per job for archiving and disambiguation
107 # when running in parallel.
Fathi Boudra422bf772019-12-02 11:10:16 +0200108 if [ "$parallel" -gt 1 ]; then
109 console_file="$workspace/console.log"
Boyan Karatotev49106802025-05-02 10:08:43 +0100110 exec >> $console_file 2>&1
Fathi Boudra422bf772019-12-02 11:10:16 +0200111 else
Boyan Karatotev49106802025-05-02 10:08:43 +0100112 # when running in serial, no scrambling is possible so print to
113 # stdout
114 exec >&5 2>&1
Fathi Boudra422bf772019-12-02 11:10:16 +0200115 fi
116
117 # Unset make flags for build script
118 MAKEFLAGS=
119
Zelalem219df412020-05-17 19:21:20 -0500120 if [ $import_cc -eq 1 ]; then
121 # Path to plugin if there is no local reference
122 cc_path_spec=$workspace/cc_plugin
123 fi
124
Fathi Boudra422bf772019-12-02 11:10:16 +0200125 case "$action" in
126 "build")
127 echo "building: $config_string" >&5
Boyan Karatotev49106802025-05-02 10:08:43 +0100128 if ! ccpathspec="$cc_path_spec" bash $minus_x "$ci_root/script/build_package.sh"; then {
129 print_failure "$config_string (build)" >&5
Fathi Boudra422bf772019-12-02 11:10:16 +0200130 if [ "$console_file" ]; then
131 echo " see $console_file"
132 fi
133 } >&5
134 exit 1
135 fi
136 ;;
137
138 "run")
Harrison Mutaia197d5d2022-09-15 13:45:21 +0100139 # Local runs for FVP, QEMU, or arm_fpga unless asked not to
140 if echo "$RUN_CONFIG" | grep -q "^\(fvp\|qemu\)" && \
Fathi Boudra422bf772019-12-02 11:10:16 +0200141 not_upon "$skip_runs"; then
142 echo "running: $config_string" >&5
Zelalem219df412020-05-17 19:21:20 -0500143 if [ -n "$cc_enable" ]; then
144 # Enable of code coverage during run
145 if cc_enable="$cc_enable" trace_file_prefix=tr \
146 coverage_trace_plugin=$cc_path_spec/scripts/tools/code_coverage/fastmodel_baremetal/bmcov/model-plugin/CoverageTrace.so \
Boyan Karatotev49106802025-05-02 10:08:43 +0100147 bash $minus_x "$ci_root/script/run_package.sh"; then
Zelalem219df412020-05-17 19:21:20 -0500148 if grep -q -e "--BUILD UNSTABLE--" \
Fathi Boudra422bf772019-12-02 11:10:16 +0200149 "$log_file"; then
Zelalem219df412020-05-17 19:21:20 -0500150 print_unstable "$config_string" >&5
151 else
152 print_success "$config_string" >&5
153 if [ -d "$workspace/artefacts/release" ] && \
laurenw-armafdc3bc2022-09-14 15:31:42 -0500154 [ -f "$workspace/artefacts/release/tr-FVP_Base_RevC_2xAEMvA.cluster0.cpu0.log" ]; then
Zelalem219df412020-05-17 19:21:20 -0500155 cp $workspace/artefacts/release/*.log $workspace/artefacts/debug
156 fi
157 # Setting environmental variables for run of code coverage
158 OBJDUMP=$TOOLCHAIN/bin/aarch64-none-elf-objdump \
159 READELF=$TOOLCHAIN/bin/aarch64-none-elf-readelf \
160 ELF_FOLDER=$workspace/artefacts/debug \
161 TRACE_FOLDER=$workspace/artefacts/debug \
162 workspace=$workspace \
163 TRACE_PREFIX=tr python \
164 $cc_path_spec/scripts/tools/code_coverage/fastmodel_baremetal/bmcov/report/gen-coverage-report.py --config \
165 $cc_path_spec/scripts/tools/code_coverage/fastmodel_baremetal/bmcov/report/config_atf.py
166 fi
167 exit 0
Fathi Boudra422bf772019-12-02 11:10:16 +0200168 else
Zelalem219df412020-05-17 19:21:20 -0500169 {
Boyan Karatotev49106802025-05-02 10:08:43 +0100170 print_failure "$config_string (run)" >&5
Zelalem219df412020-05-17 19:21:20 -0500171 if [ "$console_file" ]; then
172 echo " see $console_file"
173 fi
174 } >&5
175 exit 1
Fathi Boudra422bf772019-12-02 11:10:16 +0200176 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200177 else
Boyan Karatotev49106802025-05-02 10:08:43 +0100178 if bash $minus_x "$ci_root/script/run_package.sh"; then
Zelalem219df412020-05-17 19:21:20 -0500179 if grep -q -e "--BUILD UNSTABLE--" \
180 "$log_file"; then
181 print_unstable "$config_string" >&5
182 else
183 print_success "$config_string" >&5
184 fi
185 exit 0
186 else
187 {
Boyan Karatotev49106802025-05-02 10:08:43 +0100188 print_failure "$config_string (run)" >&5
Zelalem219df412020-05-17 19:21:20 -0500189 if [ "$console_file" ]; then
190 echo " see $console_file"
191 fi
192 } >&5
193 exit 1
Fathi Boudra422bf772019-12-02 11:10:16 +0200194 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200195 fi
196 else
Javier Almansa Sobrino412d3612020-05-22 17:53:12 +0100197 # Local runs for arm_fpga platform
198 if echo "$RUN_CONFIG" | grep -q "^arm_fpga" && \
199 not_upon "$skip_runs"; then
200 echo "running: $config_string" >&5
Boyan Karatotev49106802025-05-02 10:08:43 +0100201 if bash $minus_x "$ci_root/script/test_fpga_payload.sh"; then
Javier Almansa Sobrino412d3612020-05-22 17:53:12 +0100202 if grep -q -e "--BUILD UNSTABLE--" \
203 "$log_file"; then
204 print_unstable "$config_string" >&5
205 else
206 print_success "$config_string" >&5
207 fi
208 exit 0
209 else
210 {
Boyan Karatotev49106802025-05-02 10:08:43 +0100211 print_failure "$config_string (run)" >&5
Javier Almansa Sobrino412d3612020-05-22 17:53:12 +0100212 if [ "$console_file" ]; then
213 echo " see $console_file"
214 fi
215 } >&5
216 exit 1
217 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200218 else
Javier Almansa Sobrino412d3612020-05-22 17:53:12 +0100219 if grep -q -e "--BUILD UNSTABLE--" \
220 "$log_file"; then
221 print_unstable "$config_string (not run)" >&5
222 else
223 print_success "$config_string (not run)" >&5
224 fi
225 exit 0
Fathi Boudra422bf772019-12-02 11:10:16 +0200226 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200227 fi
228 ;;
229
230 *)
231 in_red "Invalid action: $action!" >&5
232 exit 1
233 ;;
234 esac
235}
236export -f run_one_test
237
238workspace="${workspace:?}"
Boyan Karatotev51800062025-05-01 16:55:44 +0100239if [[ "$retain_paths" -eq 0 ]]; then
Jayanth Dodderi Chidanand985bb2f2025-04-09 17:02:39 +0100240 gcc_space="${gcc_space:?Environment variable 'gcc_space' must be set}"
241fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200242ci_root="$(readlink -f "$(dirname "$0")/..")"
243
244# If this script was invoked with bash -x, have subsequent build/run invocations
245# to use -x as well.
246if echo "$-" | grep -q "x"; then
247 export minus_x="-x"
248fi
249
Leonardo Sandoval8f9cea62020-07-10 11:08:55 -0500250# if test_groups variable is not present, check if it can be formed at least from 'test_group' and 'tf_config'
251# environment variables
252if [ -z "${test_groups}" ]; then
253 if [ -n "${test_group}" -a -n "${tf_config}" ]; then
254
255 # default the rest to nil if not present
256 tftf_config="${tftf_config:-nil}"
Manish Pandeyb466cf22021-02-12 13:15:40 +0000257 spm_config="${spm_config:-nil}"
Leonardo Sandoval8f9cea62020-07-10 11:08:55 -0500258 run_config="${run_config:-nil}"
259
Manish Pandeyb466cf22021-02-12 13:15:40 +0000260 # construct the 'long form' so it takes into account all possible configurations
Chris Kay4f7846a2025-08-04 19:56:35 +0100261 if echo ${test_group} | grep -q '^spm-'; then
262 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 +0100263 elif echo ${test_group} | grep -q '^rmm-'; then
Chris Kay4f7846a2025-08-04 19:56:35 +0100264 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 +0000265 else
Chris Kay4f7846a2025-08-04 19:56:35 +0100266 tg=$(printf "%s/%s,%s,%s:%s" "${test_group}" "${tf_config}" "${tftf_config}" "${spm_config}" "${run_config}")
Manish Pandeyb466cf22021-02-12 13:15:40 +0000267 fi
Leonardo Sandoval8f9cea62020-07-10 11:08:55 -0500268
269 # trim any ',nil:' from it
Manish Pandeyb466cf22021-02-12 13:15:40 +0000270 tg="${tg/,nil:/:}" tg="${tg/,nil:/:}"; tg="${tg/,nil:/:}"; tg="${tg/,nil:/:}"
Leonardo Sandoval8f9cea62020-07-10 11:08:55 -0500271
272 # finally exported
273 export test_groups="${tg}"
274 fi
275fi
276
Fathi Boudra422bf772019-12-02 11:10:16 +0200277# For a local run, when some variables as specified as "?", launch zenity to
278# prompt for test config via. GUI. If it's "??", then choose a directory.
279if [ "$test_groups" = "?" -o "$test_groups" = "??" ]; then
280 zenity_opts=(
281 --file-selection
282 --filename="$ci_root/group/README"
283 --multiple
284 --title "Choose test config"
285 )
286
287 if [ "$test_groups" = "??" ]; then
288 zenity_opts+=("--directory")
289 fi
290
291 # In case of multiple selections, zenity returns absolute paths of files
292 # separated by '|'. We remove the pipe characters, and make the paths
293 # relative to the group directory.
294 selections="$(cd "$ci_root"; zenity ${zenity_opts[*]})"
295 test_groups="$(echo "$selections" | tr '|' ' ')"
296 test_groups="$(echo "$test_groups" | sed "s#$ci_root/group/##g")"
297fi
298
299test_groups="${test_groups:?}"
300local_count=0
301
302if [ -z "$tf_root" ]; then
303 in_red "NOTE: NOT using local work tree for TF"
304else
305 tf_root="$(readlink -f $tf_root)"
306 tf_refspec=
307 in_green "Using local work tree for TF"
308 let "++local_count"
309fi
310
311if [ -z "$tftf_root" ]; then
312 in_red "NOTE: NOT using local work tree for TFTF"
313 tforg_user="${tforg_user:?}"
314else
315 tftf_root="$(readlink -f $tftf_root)"
Zelalem219df412020-05-17 19:21:20 -0500316 tftf_refspec=
Fathi Boudra422bf772019-12-02 11:10:16 +0200317 in_green "Using local work tree for TFTF"
318 let "++local_count"
319fi
320
Zelalem219df412020-05-17 19:21:20 -0500321if [ -n "$cc_enable" ]; then
322 in_green "Code Coverage enabled"
323 if [ -z "$TOOLCHAIN" ]; then
324 in_red "TOOLCHAIN not set for code coverage: ex: export TOOLCHAIN=<path to toolchain>/gcc-arm-<gcc version>-x86_64-aarch64-none-elf"
325 exit 1
326 fi
327 if [ -n "$cc_path" ]; then
328 in_green "Code coverage plugin path specified"
329 cc_path_spec=$cc_path
330 import_cc=0
331 else
332 in_red "Code coverage plugin path not specified"
333 cc_path_spec="$workspace/cc_plugin"
334 import_cc=1
335 fi
Jimmy Brisson4347d8a2020-07-24 10:26:16 -0500336else
337 in_green "Code coverage disabled"
338 import_cc=1
Zelalem219df412020-05-17 19:21:20 -0500339fi
340
Olivier Deprezf1d1fcd2019-12-16 14:09:43 +0100341if [ -z "$spm_root" ]; then
342 in_red "NOTE: NOT using local work tree for SPM"
343else
344 spm_root="$(readlink -f $spm_root)"
345 spm_refspec=
346 in_green "Using local work tree for SPM"
347 let "++local_count"
348fi
349
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000350if [ -z "$rmm_root" ]; then
351 in_red "NOTE: NOT using local work tree for RMM"
352else
353 rmm_root="$(readlink -f $rmm_root)"
354 rmm_refspec=
355 in_green "Using local work tree for RMM"
356 let "++local_count"
357fi
358
359if [ -z "$tfm_tests_root" ]; then
360 in_red "NOTE: NOT using local work tree for TF-M-TESTS"
361else
362 tfm_tests_root="$(readlink -f $tfm_tests_root)"
363 tfm_tests_refspec=
364 in_green "Using local work tree for TF-M-TESTS"
365 let "++local_count"
366fi
367
368if [ -z "$tfm_extras_root" ]; then
369 in_red "NOTE: NOT using local work tree for TF-M-EXTRAS"
370else
371 tfm_extras_root="$(readlink -f $tfm_extras_root)"
372 tfm_extras_refspec=
373 in_green "Using local work tree for TF-M-EXTRAS"
374 let "++local_count"
375fi
376
Fathi Boudra422bf772019-12-02 11:10:16 +0200377# User preferences
Javier Almansa Sobrinoe8363182020-11-10 16:40:53 +0000378[ "$connect_debugger" ] && [ "$connect_debugger" -eq 1 ] && user_connect_debugger=1
379user_test_run="${user_connect_debugger:-$test_run}"
Fathi Boudra422bf772019-12-02 11:10:16 +0200380user_dont_clean="$dont_clean"
381user_keep_going="$keep_going"
382user_primary_live="$primary_live"
Javier Almansa Sobrinoe8363182020-11-10 16:40:53 +0000383user_connect_debugger="${user_connect_debugger:-0}"
Fathi Boudra422bf772019-12-02 11:10:16 +0200384
385export ci_root
386export dont_clean=0
387export local_ci=1
388export parallel
389export test_run=0
390export primary_live=0
Zelalem219df412020-05-17 19:21:20 -0500391export cc_path_spec
392export import_cc
Javier Almansa Sobrinoe8363182020-11-10 16:40:53 +0000393export connect_debugger="$user_connect_debugger"
Fathi Boudra422bf772019-12-02 11:10:16 +0200394
395rm -rf "$workspace"
396mkdir -p "$workspace"
397
398source "$ci_root/utils.sh"
399
Zelalem219df412020-05-17 19:21:20 -0500400# Enable of code coverage and whether there is a local plugin
401if upon "$cc_enable" && not_upon "$cc_path"; then
402 no_cc_t=1
403else
404 no_cc_t=0
405fi
406
407# Use clone_repos.sh to clone and share repositories that aren't local.
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000408no_tf="$tf_root" no_tftf="$tftf_root" no_spm="$spm_root" no_rmm="$rmm_root" \
409no_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 +0200410 bash $minus_x "$ci_root/script/clone_repos.sh"
411
412set -a
413source "$workspace/env"
414set +a
415
Fathi Boudra422bf772019-12-02 11:10:16 +0200416export -f upon not_upon
417
418# Generate test descriptions
419"$ci_root/script/gen_test_desc.py"
420
421# Iterate through test files in workspace
422pushd "$workspace"
423
424if not_upon "$parallel" || echo "$parallel" | grep -vq "[0-9]"; then
425 parallel=1
426 test_run="$user_test_run"
427 dont_clean="$user_dont_clean"
428 primary_live="$user_primary_live"
429fi
430
431if [ "$parallel" -gt 1 ]; then
432 msg="Running at most $parallel jobs in parallel"
433 if upon "$serialize_builds"; then
434 msg+=" (builds serialized)"
435 fi
436 msg+="..."
437fi
438
439# Generate Makefile
440gen_makefile
441
442if upon "$msg"; then
443 echo "$msg"
444 echo
445fi
446
447keep_going="${user_keep_going:-1}"
448if not_upon "$keep_going"; then
449 keep_going=
450fi
451
Boyan Karatotev49106802025-05-02 10:08:43 +0100452MAKEFLAGS= make -r -j "$parallel" ${keep_going+-k} 5>&1 |& tee "make.log"