forked from zephyrproject-rtos/zephyr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrun_ci.sh
executable file
·307 lines (266 loc) · 7.99 KB
/
run_ci.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
#!/bin/bash
# Copyright (c) 2017 Linaro Limited
# Copyright (c) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
# Author: Anas Nashif
#
# This script is run in CI and support both pull request and commit modes. So
# it can be used also on commits to the tree or on tags.
# The following options are supports:
# -p start the script for pull requests
# -m matrix node number, for example 3 on a 5 node matrix
# -M total number of nodes in the matrix
# -b base branch
# -r the remote to rebase on
#
# The script can be run locally using for exmaple:
# ./scripts/ci/run_ci.sh -b master -r origin -l -R <commit range>
set -xe
SANITYCHECK_OPTIONS=" --inline-logs --enable-coverage -N"
SANITYCHECK_OPTIONS_RETRY="${SANITYCHECK_OPTIONS} --only-failed --outdir=out-2nd-pass"
SANITYCHECK_OPTIONS_RETRY_2="${SANITYCHECK_OPTIONS} --only-failed --outdir=out-3nd-pass"
export BSIM_OUT_PATH="${BSIM_OUT_PATH:-/opt/bsim/}"
export BSIM_COMPONENTS_PATH="${BSIM_OUT_PATH}/components/"
BSIM_BT_TEST_RESULTS_FILE="./bsim_bt_out/bsim_results.xml"
WEST_COMMANDS_RESULTS_FILE="./pytest_out/west_commands.xml"
MATRIX_BUILDS=1
MATRIX=1
while getopts ":p:m:b:r:M:cfslR:" opt; do
case $opt in
c)
echo "Execute CI" >&2
MAIN_CI=1
;;
l)
echo "Executing script locally" >&2
LOCAL_RUN=1
MAIN_CI=1
;;
s)
echo "Success" >&2
SUCCESS=1
;;
f)
echo "Failure" >&2
FAILURE=1
;;
p)
echo "Testing a Pull Request: $OPTARG." >&2
PULL_REQUEST_NR=$OPTARG
;;
m)
echo "Running on Matrix $OPTARG" >&2
MATRIX=$OPTARG
;;
M)
echo "Running a matrix of $OPTARG slaves" >&2
MATRIX_BUILDS=$OPTARG
;;
b)
echo "Base Branch: $OPTARG" >&2
BRANCH=$OPTARG
;;
r)
echo "Remote: $OPTARG" >&2
REMOTE=$OPTARG
;;
R)
echo "Range: $OPTARG" >&2
RANGE=$OPTARG
;;
\?)
echo "Invalid option: -$OPTARG" >&2
;;
esac
done
DOC_MATRIX=${MATRIX_BUILDS}
if [ -n "$MAIN_CI" ]; then
# West handling
pushd ..
if [ ! -d .west ]; then
west init -l zephyr
west update
fi
popd
if [ -z "$BRANCH" ]; then
echo "No base branch given"
exit 1
else
COMMIT_RANGE=$REMOTE/${BRANCH}..HEAD
echo "Commit range:" ${COMMIT_RANGE}
fi
if [ -n "$RANGE" ]; then
COMMIT_RANGE=$RANGE
fi
source zephyr-env.sh
SANITYCHECK="${ZEPHYR_BASE}/scripts/sanitycheck"
# Possibly the only record of what exact version is being tested:
short_git_log='git log -n 5 --oneline --decorate --abbrev=12 '
if [ -n "$PULL_REQUEST_NR" ]; then
$short_git_log $REMOTE/${BRANCH}
# Now let's pray this script is being run from a
# different location
# https://stackoverflow.com/questions/3398258/edit-shell-script-while-its-running
git rebase $REMOTE/${BRANCH};
fi
$short_git_log
fi
function handle_coverage() {
# this is for shippable coverage reports
echo "Calling gcovr"
gcovr -r ${ZEPHYR_BASE} -x > shippable/codecoverage/coverage.xml;
# Upload to codecov.io only on merged builds or if CODECOV_IO variable
# is set.
if [ -n "${CODECOV_IO}" -o -z "${PULL_REQUEST_NR}" ]; then
# Capture data
echo "Running lcov --capture ..."
lcov --capture \
--directory sanity-out/native_posix/ \
--directory sanity-out/nrf52_bsim/ \
--directory sanity-out/unit_testing/ \
--directory bsim_bt_out/ \
--output-file lcov.pre.info -q --rc lcov_branch_coverage=1;
# Remove noise
echo "Exclude data from coverage report..."
lcov -q \
--remove lcov.pre.info mylib.c \
--remove lcov.pre.info tests/\* \
--remove lcov.pre.info samples/\* \
--remove lcov.pre.info ext/\* \
--remove lcov.pre.info *generated* \
-o lcov.info --rc lcov_branch_coverage=1;
# Cleanup
rm lcov.pre.info;
rm -rf sanity-out out-2nd-pass;
# Upload to codecov.io
echo "Upload coverage reports to codecov.io"
bash <(curl -s https://codecov.io/bash) -f "lcov.info" -X coveragepy -X fixes;
rm -f lcov.info;
fi
rm -rf sanity-out out-2nd-pass;
}
function handle_compiler_cache() {
# Give more details in case we fail because of compiler cache
if [ -f "$HOME/.cache/zephyr/ToolchainCapabilityDatabase.cmake" ]; then
echo "Dumping the capability database in case we are affected by #9992"
cat $HOME/.cache/zephyr/ToolchainCapabilityDatabase.cmake
fi;
}
function on_complete() {
source zephyr-env.sh
if [ "$1" == "failure" ]; then
handle_compiler_cache
fi
rm -rf ccache $HOME/.cache/zephyr
mkdir -p shippable/testresults
mkdir -p shippable/codecoverage
if [ -e compliance.xml ]; then
echo "Copy compliance.xml"
cp compliance.xml shippable/testresults/;
fi;
if [ -e ./scripts/sanity_chk/last_sanity.xml ]; then
echo "Copy ./scripts/sanity_chk/last_sanity.xml"
cp ./scripts/sanity_chk/last_sanity.xml shippable/testresults/;
fi;
if [ -e ${BSIM_BT_TEST_RESULTS_FILE} ]; then
echo "Copy ${BSIM_BT_TEST_RESULTS_FILE}"
cp ${BSIM_BT_TEST_RESULTS_FILE} shippable/testresults/;
fi;
if [ -e ${WEST_COMMANDS_RESULTS_FILE} ]; then
echo "Copy ${WEST_COMMANDS_RESULTS_FILE}"
cp ${WEST_COMMANDS_RESULTS_FILE} shippable/testresults;
fi;
if [ "$MATRIX" = "1" ]; then
echo "Handle coverage data..."
handle_coverage
else
rm -rf sanity-out out-2nd-pass;
fi;
}
function build_btsim() {
NRF_HW_MODELS_VERSION=`cat boards/posix/nrf52_bsim/hw_models_version`
pushd . ;
cd ${BSIM_COMPONENTS_PATH} ;
if [ -d ext_NRF52_hw_models ]; then
cd ext_NRF52_hw_models
git describe --tags --abbrev=0 ${NRF52_HW_MODELS_TAG}\
> /dev/null ||
(
echo "`pwd` seems to contain the nRF52 HW\
models but they are out of date"
exit 1;
)
else
git clone -b ${NRF_HW_MODELS_VERSION} \
https://github.com/BabbleSim/ext_NRF52_hw_models.git
fi
cd ${BSIM_OUT_PATH}
make everything -j 8 -s
popd ;
}
function run_bsim_bt_tests() {
WORK_DIR=${ZEPHYR_BASE}/bsim_bt_out tests/bluetooth/bsim_bt/compile.sh
RESULTS_FILE=${ZEPHYR_BASE}/${BSIM_BT_TEST_RESULTS_FILE} \
SEARCH_PATH=tests/bluetooth/bsim_bt/bsim_test_app/tests_scripts \
tests/bluetooth/bsim_bt/run_parallel.sh
}
function get_tests_to_run() {
./scripts/ci/get_modified_tests.py --commits ${COMMIT_RANGE} > modified_tests.args;
./scripts/ci/get_modified_boards.py --commits ${COMMIT_RANGE} > modified_boards.args;
if [ -s modified_boards.args ]; then
${SANITYCHECK} ${SANITYCHECK_OPTIONS} +modified_boards.args --save-tests test_file.txt || exit 1;
fi
if [ -s modified_tests.args ]; then
${SANITYCHECK} ${SANITYCHECK_OPTIONS} +modified_tests.args --save-tests test_file.txt || exit 1;
fi
rm -f modified_tests.args modified_boards.args;
}
if [ -n "$MAIN_CI" ]; then
if [ -n "${BSIM_OUT_PATH}" -a -d "${BSIM_OUT_PATH}" ]; then
echo "Build BT simulator tests"
# Build BT Simulator
build_btsim
# Run BLE tests in simulator on the 1st CI instance:
if [ "$MATRIX" = "1" ]; then
run_bsim_bt_tests
fi
else
echo "Skipping BT simulator tests"
fi
if [ "$MATRIX" = "1" ]; then
# Run pytest-based testing for Python in matrix
# builder 1. For now, this is just done for the west
# extension commands, but additional directories which
# run pytest could go here too.
PYTEST=$(type -p pytest-3 || echo "pytest")
mkdir -p $(dirname ${WEST_COMMANDS_RESULTS_FILE})
WEST_SRC=$(west list --format='{abspath}' west)/src
PYTHONPATH=./scripts/west_commands:$WEST_SRC "${PYTEST}" \
--junitxml=${WEST_COMMANDS_RESULTS_FILE} \
./scripts/west_commands/tests
else
echo "Skipping west command tests"
fi
# In a pull-request see if we have changed any tests or board definitions
if [ -n "${PULL_REQUEST_NR}" -o -n "${LOCAL_RUN}" ]; then
get_tests_to_run
fi
# Save list of tests to be run
${SANITYCHECK} ${SANITYCHECK_OPTIONS} --save-tests test_file.txt || exit 1
# Run a subset of tests based on matrix size
${SANITYCHECK} ${SANITYCHECK_OPTIONS} --load-tests test_file.txt \
--subset ${MATRIX}/${MATRIX_BUILDS} || \
( sleep 10; ${SANITYCHECK} ${SANITYCHECK_OPTIONS_RETRY} ) || \
( sleep 10; ${SANITYCHECK} ${SANITYCHECK_OPTIONS_RETRY_2}; )
# sleep 10 to let the host settle down
# cleanup
rm -f test_file.txt
elif [ -n "$FAILURE" ]; then
on_complete failure
elif [ -n "$SUCCESS" ]; then
on_complete
else
echo "Nothing to do"
fi