blob: 0dbf8c53845ffd2cde2da56e1d4df5074e5b76b3 [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
51 # If we're using local checkouts for either TF or TFTF, we must
52 # serialise builds
53 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() {
77 id="${1%%_*}"
78 action="${1##*_}"
79 test_file="$(find -name "$id*.test" -printf "%f\n")"
80
81 mkdir -p "$id"
82
83 # Copy the test_file into the workspace directory with the name
84 # TEST_DESC, just like Jenkins would.
85 export TEST_DESC="$(basename "$test_file")"
86 cp "$test_file" "$id/TEST_DESC"
87
Zelalem219df412020-05-17 19:21:20 -050088 workspace="$id" test_desc="$test_file" cc_enable="$cc_enable" "$ci_root/script/parse_test.sh"
Fathi Boudra422bf772019-12-02 11:10:16 +020089
90 set -a
91 source "$id/env"
92 set +a
93
94 # Makefiles don't like commas and colons in file names. We therefore
95 # replace them with _
96 config_subst="$(echo "$TEST_CONFIG" | tr ',:' '_')"
97 config_string="$id: $TEST_GROUP/$TEST_CONFIG"
98 workspace="$workspace/$TEST_GROUP/$config_subst"
99 mkdir -p "$workspace"
100
101 log_file="$workspace/artefacts/build.log"
Boyan Karatotev49106802025-05-02 10:08:43 +0100102 # fd 5 is the terminal where run_local_ci.sh is running. *Only* status
103 # of the run is printed as this is shared for all jobs and this may
104 # happen in parallel.
105 # Each job has its own verbose output as well. This will be progress
106 # messages but also any debugging prints. This is the default and it
107 # gets redirected to a file per job for archiving and disambiguation
108 # when running in parallel.
Fathi Boudra422bf772019-12-02 11:10:16 +0200109 if [ "$parallel" -gt 1 ]; then
110 console_file="$workspace/console.log"
Boyan Karatotev49106802025-05-02 10:08:43 +0100111 exec >> $console_file 2>&1
Fathi Boudra422bf772019-12-02 11:10:16 +0200112 else
Boyan Karatotev49106802025-05-02 10:08:43 +0100113 # when running in serial, no scrambling is possible so print to
114 # stdout
115 exec >&5 2>&1
Fathi Boudra422bf772019-12-02 11:10:16 +0200116 fi
117
118 # Unset make flags for build script
119 MAKEFLAGS=
120
Zelalem219df412020-05-17 19:21:20 -0500121 if [ $import_cc -eq 1 ]; then
122 # Path to plugin if there is no local reference
123 cc_path_spec=$workspace/cc_plugin
124 fi
125
Fathi Boudra422bf772019-12-02 11:10:16 +0200126 case "$action" in
127 "build")
128 echo "building: $config_string" >&5
Boyan Karatotev49106802025-05-02 10:08:43 +0100129 if ! ccpathspec="$cc_path_spec" bash $minus_x "$ci_root/script/build_package.sh"; then {
130 print_failure "$config_string (build)" >&5
Fathi Boudra422bf772019-12-02 11:10:16 +0200131 if [ "$console_file" ]; then
132 echo " see $console_file"
133 fi
134 } >&5
135 exit 1
136 fi
137 ;;
138
139 "run")
Harrison Mutaia197d5d2022-09-15 13:45:21 +0100140 # Local runs for FVP, QEMU, or arm_fpga unless asked not to
141 if echo "$RUN_CONFIG" | grep -q "^\(fvp\|qemu\)" && \
Fathi Boudra422bf772019-12-02 11:10:16 +0200142 not_upon "$skip_runs"; then
143 echo "running: $config_string" >&5
Zelalem219df412020-05-17 19:21:20 -0500144 if [ -n "$cc_enable" ]; then
145 # Enable of code coverage during run
146 if cc_enable="$cc_enable" trace_file_prefix=tr \
147 coverage_trace_plugin=$cc_path_spec/scripts/tools/code_coverage/fastmodel_baremetal/bmcov/model-plugin/CoverageTrace.so \
Boyan Karatotev49106802025-05-02 10:08:43 +0100148 bash $minus_x "$ci_root/script/run_package.sh"; then
Zelalem219df412020-05-17 19:21:20 -0500149 if grep -q -e "--BUILD UNSTABLE--" \
Fathi Boudra422bf772019-12-02 11:10:16 +0200150 "$log_file"; then
Zelalem219df412020-05-17 19:21:20 -0500151 print_unstable "$config_string" >&5
152 else
153 print_success "$config_string" >&5
154 if [ -d "$workspace/artefacts/release" ] && \
laurenw-armafdc3bc2022-09-14 15:31:42 -0500155 [ -f "$workspace/artefacts/release/tr-FVP_Base_RevC_2xAEMvA.cluster0.cpu0.log" ]; then
Zelalem219df412020-05-17 19:21:20 -0500156 cp $workspace/artefacts/release/*.log $workspace/artefacts/debug
157 fi
158 # Setting environmental variables for run of code coverage
159 OBJDUMP=$TOOLCHAIN/bin/aarch64-none-elf-objdump \
160 READELF=$TOOLCHAIN/bin/aarch64-none-elf-readelf \
161 ELF_FOLDER=$workspace/artefacts/debug \
162 TRACE_FOLDER=$workspace/artefacts/debug \
163 workspace=$workspace \
164 TRACE_PREFIX=tr python \
165 $cc_path_spec/scripts/tools/code_coverage/fastmodel_baremetal/bmcov/report/gen-coverage-report.py --config \
166 $cc_path_spec/scripts/tools/code_coverage/fastmodel_baremetal/bmcov/report/config_atf.py
167 fi
168 exit 0
Fathi Boudra422bf772019-12-02 11:10:16 +0200169 else
Zelalem219df412020-05-17 19:21:20 -0500170 {
Boyan Karatotev49106802025-05-02 10:08:43 +0100171 print_failure "$config_string (run)" >&5
Zelalem219df412020-05-17 19:21:20 -0500172 if [ "$console_file" ]; then
173 echo " see $console_file"
174 fi
175 } >&5
176 exit 1
Fathi Boudra422bf772019-12-02 11:10:16 +0200177 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200178 else
Boyan Karatotev49106802025-05-02 10:08:43 +0100179 if bash $minus_x "$ci_root/script/run_package.sh"; then
Zelalem219df412020-05-17 19:21:20 -0500180 if grep -q -e "--BUILD UNSTABLE--" \
181 "$log_file"; then
182 print_unstable "$config_string" >&5
183 else
184 print_success "$config_string" >&5
185 fi
186 exit 0
187 else
188 {
Boyan Karatotev49106802025-05-02 10:08:43 +0100189 print_failure "$config_string (run)" >&5
Zelalem219df412020-05-17 19:21:20 -0500190 if [ "$console_file" ]; then
191 echo " see $console_file"
192 fi
193 } >&5
194 exit 1
Fathi Boudra422bf772019-12-02 11:10:16 +0200195 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200196 fi
197 else
Javier Almansa Sobrino412d3612020-05-22 17:53:12 +0100198 # Local runs for arm_fpga platform
199 if echo "$RUN_CONFIG" | grep -q "^arm_fpga" && \
200 not_upon "$skip_runs"; then
201 echo "running: $config_string" >&5
Boyan Karatotev49106802025-05-02 10:08:43 +0100202 if bash $minus_x "$ci_root/script/test_fpga_payload.sh"; then
Javier Almansa Sobrino412d3612020-05-22 17:53:12 +0100203 if grep -q -e "--BUILD UNSTABLE--" \
204 "$log_file"; then
205 print_unstable "$config_string" >&5
206 else
207 print_success "$config_string" >&5
208 fi
209 exit 0
210 else
211 {
Boyan Karatotev49106802025-05-02 10:08:43 +0100212 print_failure "$config_string (run)" >&5
Javier Almansa Sobrino412d3612020-05-22 17:53:12 +0100213 if [ "$console_file" ]; then
214 echo " see $console_file"
215 fi
216 } >&5
217 exit 1
218 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200219 else
Javier Almansa Sobrino412d3612020-05-22 17:53:12 +0100220 if grep -q -e "--BUILD UNSTABLE--" \
221 "$log_file"; then
222 print_unstable "$config_string (not run)" >&5
223 else
224 print_success "$config_string (not run)" >&5
225 fi
226 exit 0
Fathi Boudra422bf772019-12-02 11:10:16 +0200227 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200228 fi
229 ;;
230
231 *)
232 in_red "Invalid action: $action!" >&5
233 exit 1
234 ;;
235 esac
236}
237export -f run_one_test
238
239workspace="${workspace:?}"
Boyan Karatotev51800062025-05-01 16:55:44 +0100240if [[ "$retain_paths" -eq 0 ]]; then
Jayanth Dodderi Chidanand985bb2f2025-04-09 17:02:39 +0100241 gcc_space="${gcc_space:?Environment variable 'gcc_space' must be set}"
242fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200243ci_root="$(readlink -f "$(dirname "$0")/..")"
244
245# If this script was invoked with bash -x, have subsequent build/run invocations
246# to use -x as well.
247if echo "$-" | grep -q "x"; then
248 export minus_x="-x"
249fi
250
Leonardo Sandoval8f9cea62020-07-10 11:08:55 -0500251# if test_groups variable is not present, check if it can be formed at least from 'test_group' and 'tf_config'
252# environment variables
253if [ -z "${test_groups}" ]; then
254 if [ -n "${test_group}" -a -n "${tf_config}" ]; then
255
256 # default the rest to nil if not present
257 tftf_config="${tftf_config:-nil}"
258 scp_config="${scp_config:-nil}"
259 scp_tools="${scp_tools:-nil}"
Manish Pandeyb466cf22021-02-12 13:15:40 +0000260 spm_config="${spm_config:-nil}"
Leonardo Sandoval8f9cea62020-07-10 11:08:55 -0500261 run_config="${run_config:-nil}"
262
Manish Pandeyb466cf22021-02-12 13:15:40 +0000263 # construct the 'long form' so it takes into account all possible configurations
Leonardo Sandoval07733aa2021-02-23 13:57:08 -0600264 if echo ${test_group} | grep -q '^scp-'; then
Manish Pandeyb466cf22021-02-12 13:15:40 +0000265 tg=$(printf "%s/%s,%s,%s,%s:%s" "${test_group}" "${scp_config}" "${tf_config}" "${tftf_config}" "${scp_tools}" "${run_config}")
Leonardo Sandoval07733aa2021-02-23 13:57:08 -0600266 elif echo ${test_group} | grep -q '^spm-'; then
Manish Pandeyb466cf22021-02-12 13:15:40 +0000267 tg=$(printf "%s/%s,%s,%s,%s,%s:%s" "${test_group}" "${spm_config}" "${tf_config}" "${tftf_config}" "${scp_config}" "${scp_tools}" "${run_config}")
Manish V Badarkhe5248c7f2025-04-11 13:22:16 +0100268 elif echo ${test_group} | grep -q '^rmm-'; then
269 tg=$(printf "%s/%s,%s,%s,%s,%s,%s:%s" "${test_group}" "${rmm_config}" "${tf_config}" "${tftf_config}" "${spm_config}" "${scp_config}" "${scp_tools}" "${run_config}")
Manish Pandeyb466cf22021-02-12 13:15:40 +0000270 else
271 tg=$(printf "%s/%s,%s,%s,%s,%s:%s" "${test_group}" "${tf_config}" "${tftf_config}" "${scp_config}" "${scp_tools}" "${spm_config}" "${run_config}")
272 fi
Leonardo Sandoval8f9cea62020-07-10 11:08:55 -0500273
274 # trim any ',nil:' from it
Manish Pandeyb466cf22021-02-12 13:15:40 +0000275 tg="${tg/,nil:/:}" tg="${tg/,nil:/:}"; tg="${tg/,nil:/:}"; tg="${tg/,nil:/:}"
Leonardo Sandoval8f9cea62020-07-10 11:08:55 -0500276
277 # finally exported
278 export test_groups="${tg}"
279 fi
280fi
281
Fathi Boudra422bf772019-12-02 11:10:16 +0200282# For a local run, when some variables as specified as "?", launch zenity to
283# prompt for test config via. GUI. If it's "??", then choose a directory.
284if [ "$test_groups" = "?" -o "$test_groups" = "??" ]; then
285 zenity_opts=(
286 --file-selection
287 --filename="$ci_root/group/README"
288 --multiple
289 --title "Choose test config"
290 )
291
292 if [ "$test_groups" = "??" ]; then
293 zenity_opts+=("--directory")
294 fi
295
296 # In case of multiple selections, zenity returns absolute paths of files
297 # separated by '|'. We remove the pipe characters, and make the paths
298 # relative to the group directory.
299 selections="$(cd "$ci_root"; zenity ${zenity_opts[*]})"
300 test_groups="$(echo "$selections" | tr '|' ' ')"
301 test_groups="$(echo "$test_groups" | sed "s#$ci_root/group/##g")"
302fi
303
304test_groups="${test_groups:?}"
305local_count=0
306
307if [ -z "$tf_root" ]; then
308 in_red "NOTE: NOT using local work tree for TF"
309else
310 tf_root="$(readlink -f $tf_root)"
311 tf_refspec=
312 in_green "Using local work tree for TF"
313 let "++local_count"
314fi
315
316if [ -z "$tftf_root" ]; then
317 in_red "NOTE: NOT using local work tree for TFTF"
318 tforg_user="${tforg_user:?}"
319else
320 tftf_root="$(readlink -f $tftf_root)"
Zelalem219df412020-05-17 19:21:20 -0500321 tftf_refspec=
Fathi Boudra422bf772019-12-02 11:10:16 +0200322 in_green "Using local work tree for TFTF"
323 let "++local_count"
324fi
325
326if [ -z "$scp_root" ]; then
327 in_red "NOTE: NOT using local work tree for SCP"
328else
329 scp_root="$(readlink -f $scp_root)"
330 scp_refspec=
331 in_green "Using local work tree for SCP"
332 let "++local_count"
333fi
334
Zelalem219df412020-05-17 19:21:20 -0500335if [ -n "$cc_enable" ]; then
336 in_green "Code Coverage enabled"
337 if [ -z "$TOOLCHAIN" ]; then
338 in_red "TOOLCHAIN not set for code coverage: ex: export TOOLCHAIN=<path to toolchain>/gcc-arm-<gcc version>-x86_64-aarch64-none-elf"
339 exit 1
340 fi
341 if [ -n "$cc_path" ]; then
342 in_green "Code coverage plugin path specified"
343 cc_path_spec=$cc_path
344 import_cc=0
345 else
346 in_red "Code coverage plugin path not specified"
347 cc_path_spec="$workspace/cc_plugin"
348 import_cc=1
349 fi
Jimmy Brisson4347d8a2020-07-24 10:26:16 -0500350else
351 in_green "Code coverage disabled"
352 import_cc=1
Zelalem219df412020-05-17 19:21:20 -0500353fi
354
Olivier Deprezf1d1fcd2019-12-16 14:09:43 +0100355if [ -z "$spm_root" ]; then
356 in_red "NOTE: NOT using local work tree for SPM"
357else
358 spm_root="$(readlink -f $spm_root)"
359 spm_refspec=
360 in_green "Using local work tree for SPM"
361 let "++local_count"
362fi
363
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000364if [ -z "$rmm_root" ]; then
365 in_red "NOTE: NOT using local work tree for RMM"
366else
367 rmm_root="$(readlink -f $rmm_root)"
368 rmm_refspec=
369 in_green "Using local work tree for RMM"
370 let "++local_count"
371fi
372
373if [ -z "$tfm_tests_root" ]; then
374 in_red "NOTE: NOT using local work tree for TF-M-TESTS"
375else
376 tfm_tests_root="$(readlink -f $tfm_tests_root)"
377 tfm_tests_refspec=
378 in_green "Using local work tree for TF-M-TESTS"
379 let "++local_count"
380fi
381
382if [ -z "$tfm_extras_root" ]; then
383 in_red "NOTE: NOT using local work tree for TF-M-EXTRAS"
384else
385 tfm_extras_root="$(readlink -f $tfm_extras_root)"
386 tfm_extras_refspec=
387 in_green "Using local work tree for TF-M-EXTRAS"
388 let "++local_count"
389fi
390
Fathi Boudra422bf772019-12-02 11:10:16 +0200391# User preferences
Javier Almansa Sobrinoe8363182020-11-10 16:40:53 +0000392[ "$connect_debugger" ] && [ "$connect_debugger" -eq 1 ] && user_connect_debugger=1
393user_test_run="${user_connect_debugger:-$test_run}"
Fathi Boudra422bf772019-12-02 11:10:16 +0200394user_dont_clean="$dont_clean"
395user_keep_going="$keep_going"
396user_primary_live="$primary_live"
Javier Almansa Sobrinoe8363182020-11-10 16:40:53 +0000397user_connect_debugger="${user_connect_debugger:-0}"
Fathi Boudra422bf772019-12-02 11:10:16 +0200398
399export ci_root
400export dont_clean=0
401export local_ci=1
402export parallel
403export test_run=0
404export primary_live=0
Zelalem219df412020-05-17 19:21:20 -0500405export cc_path_spec
406export import_cc
Javier Almansa Sobrinoe8363182020-11-10 16:40:53 +0000407export connect_debugger="$user_connect_debugger"
Fathi Boudra422bf772019-12-02 11:10:16 +0200408
409rm -rf "$workspace"
410mkdir -p "$workspace"
411
412source "$ci_root/utils.sh"
413
414# SCP is not cloned by default
415export clone_scp
416export scp_root
417if not_upon "$scp_root" && upon "$clone_scp"; then
418 clone_scp=1
419else
420 clone_scp=0
421fi
422
Zelalem219df412020-05-17 19:21:20 -0500423# Enable of code coverage and whether there is a local plugin
424if upon "$cc_enable" && not_upon "$cc_path"; then
425 no_cc_t=1
426else
427 no_cc_t=0
428fi
429
430# Use clone_repos.sh to clone and share repositories that aren't local.
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000431no_tf="$tf_root" no_tftf="$tftf_root" no_spm="$spm_root" no_rmm="$rmm_root" \
432no_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 +0200433 bash $minus_x "$ci_root/script/clone_repos.sh"
434
435set -a
436source "$workspace/env"
437set +a
438
439if [ "$local_count" -gt 0 ]; then
440 # At least one repository is local
441 serialize_builds=1
442else
443 dont_clean=0
444fi
445
446export -f upon not_upon
447
448# Generate test descriptions
449"$ci_root/script/gen_test_desc.py"
450
451# Iterate through test files in workspace
452pushd "$workspace"
453
454if not_upon "$parallel" || echo "$parallel" | grep -vq "[0-9]"; then
455 parallel=1
456 test_run="$user_test_run"
457 dont_clean="$user_dont_clean"
458 primary_live="$user_primary_live"
459fi
460
461if [ "$parallel" -gt 1 ]; then
462 msg="Running at most $parallel jobs in parallel"
463 if upon "$serialize_builds"; then
464 msg+=" (builds serialized)"
465 fi
466 msg+="..."
467fi
468
469# Generate Makefile
470gen_makefile
471
472if upon "$msg"; then
473 echo "$msg"
474 echo
475fi
476
477keep_going="${user_keep_going:-1}"
478if not_upon "$keep_going"; then
479 keep_going=
480fi
481
Boyan Karatotev49106802025-05-02 10:08:43 +0100482MAKEFLAGS= make -r -j "$parallel" ${keep_going+-k} 5>&1 |& tee "make.log"