1#!/bin/bash 2# 3# Copyright (c) 2018, The OpenThread Authors. 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions are met: 8# 1. Redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer. 10# 2. Redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution. 13# 3. Neither the name of the copyright holder nor the 14# names of its contributors may be used to endorse or promote products 15# derived from this software without specific prior written permission. 16# 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27# POSSIBILITY OF SUCH DAMAGE. 28# 29# Description: 30# This file runs various tests of OpenThread. 31# 32 33set -euo pipefail 34 35OT_BUILDDIR="${OT_BUILDDIR:-${PWD}/build}" 36readonly OT_BUILDDIR 37 38OT_SRCDIR="${PWD}" 39readonly OT_SRCDIR 40 41OT_COLOR_PASS='\033[0;32m' 42readonly OT_COLOR_PASS 43 44OT_COLOR_FAIL='\033[0;31m' 45readonly OT_COLOR_FAIL 46 47OT_COLOR_SKIP='\033[0;33m' 48readonly OT_COLOR_SKIP 49 50OT_COLOR_NONE='\033[0m' 51readonly OT_COLOR_NONE 52 53OT_NODE_TYPE="${OT_NODE_TYPE:-cli}" 54readonly OT_NODE_TYPE 55 56OT_NATIVE_IP="${OT_NATIVE_IP:-0}" 57readonly OT_NATIVE_IP 58 59THREAD_VERSION="${THREAD_VERSION:-1.3}" 60readonly THREAD_VERSION 61 62INTER_OP="${INTER_OP:-0}" 63readonly INTER_OP 64 65VERBOSE="${VERBOSE:-0}" 66readonly VERBOSE 67 68BORDER_ROUTING="${BORDER_ROUTING:-1}" 69readonly BORDER_ROUTING 70 71NAT64="${NAT64:-0}" 72readonly NAT64 73 74NAT64_SERVICE="${NAT64_SERVICE:-openthread}" 75readonly NAT64_SERVICE 76 77INTER_OP_BBR="${INTER_OP_BBR:-0}" 78readonly INTER_OP_BBR 79 80OT_COREDUMP_DIR="${PWD}/ot-core-dump" 81readonly OT_COREDUMP_DIR 82 83FULL_LOGS=${FULL_LOGS:-0} 84readonly FULL_LOGS 85 86TREL=${TREL:-0} 87readonly TREL 88 89LOCAL_OTBR_DIR=${LOCAL_OTBR_DIR:-""} 90readonly LOCAL_OTBR_DIR 91 92build_simulation() 93{ 94 local version="$1" 95 local options=( 96 "-DBUILD_TESTING=ON" 97 "-DOT_ANYCAST_LOCATOR=ON" 98 "-DOT_DNS_CLIENT=ON" 99 "-DOT_DNS_DSO=ON" 100 "-DOT_DNSSD_SERVER=ON" 101 "-DOT_ECDSA=ON" 102 "-DOT_EXTERNAL_HEAP=ON" 103 "-DOT_HISTORY_TRACKER=ON" 104 "-DOT_MESSAGE_USE_HEAP=OFF" 105 "-DOT_NETDATA_PUBLISHER=ON" 106 "-DOT_PING_SENDER=ON" 107 "-DOT_REFERENCE_DEVICE=ON" 108 "-DOT_SERVICE=ON" 109 "-DOT_SRP_CLIENT=ON" 110 "-DOT_SRP_SERVER=ON" 111 "-DOT_UPTIME=ON" 112 "-DOT_THREAD_VERSION=${version}" 113 ) 114 115 if [[ ${FULL_LOGS} == 1 ]]; then 116 options+=("-DOT_FULL_LOGS=ON") 117 fi 118 119 if [[ ${version} != "1.1" ]]; then 120 options+=("-DOT_DUA=ON") 121 options+=("-DOT_MLR=ON") 122 fi 123 124 if [[ ${VIRTUAL_TIME} == 1 ]]; then 125 options+=("-DOT_SIMULATION_VIRTUAL_TIME=ON") 126 fi 127 128 if [[ ${version} != "1.1" ]]; then 129 options+=("-DOT_CSL_RECEIVER=ON") 130 options+=("-DOT_LINK_METRICS_INITIATOR=ON") 131 options+=("-DOT_LINK_METRICS_SUBJECT=ON") 132 options+=("-DOT_LINK_METRICS_MANAGER=ON") 133 fi 134 135 if [[ ${OT_NODE_TYPE} == cli* ]]; then 136 # Only enable OT_PLATFORM_BOOTLOADER_MODE when testing cli. 137 # This is intended to test that the "reset bootloader" CLI command returns a "NotCapable" error 138 139 # Note: Setting this option to ON for all OT_NODE_TYPEs will cause the posix/expects CI check to fail. 140 # This is because the simulation RCP will have the SPINEL_CAP_RCP_RESET_TO_BOOTLOADER capability, 141 # causing the ot-cli POSIX app to send the reset to simulation RCP successfully instead of printing 142 # the expected error. 143 options+=("-DOT_PLATFORM_BOOTLOADER_MODE=ON") 144 fi 145 146 if [[ ${ot_extra_options[*]+x} ]]; then 147 options+=("${ot_extra_options[@]}") 148 fi 149 150 OT_CMAKE_BUILD_DIR="${OT_BUILDDIR}/openthread-simulation-${version}" "${OT_SRCDIR}"/script/cmake-build simulation "${options[@]}" 151 152 if [[ ${VIRTUAL_TIME} == 1 ]] && [[ ${OT_NODE_TYPE} == rcp* ]]; then 153 OT_CMAKE_NINJA_TARGET=ot-rcp OT_CMAKE_BUILD_DIR="${OT_BUILDDIR}/openthread-simulation-${version}" "${OT_SRCDIR}"/script/cmake-build simulation "${options[@]}" "-DOT_SIMULATION_VIRTUAL_TIME_UART=ON" 154 fi 155 156 if [[ ${version} != "1.1" && ${INTER_OP_BBR} == 1 ]]; then 157 158 options+=("-DOT_BACKBONE_ROUTER=ON") 159 160 OT_CMAKE_BUILD_DIR="${OT_BUILDDIR}/openthread-simulation-${version}-bbr" "${OT_SRCDIR}"/script/cmake-build simulation "${options[@]}" 161 162 if [[ ${VIRTUAL_TIME} == 1 ]] && [[ ${OT_NODE_TYPE} == rcp* ]]; then 163 OT_CMAKE_NINJA_TARGET=ot-rcp OT_CMAKE_BUILD_DIR="${OT_BUILDDIR}/openthread-simulation-${version}-bbr" "${OT_SRCDIR}"/script/cmake-build simulation "${options[@]}" "-DOT_SIMULATION_VIRTUAL_TIME_UART=ON" 164 fi 165 166 fi 167} 168 169build_posix() 170{ 171 local version="$1" 172 local options=( 173 "-DBUILD_TESTING=ON" 174 "-DOT_MESSAGE_USE_HEAP=ON" 175 "-DOT_PLATFORM_BOOTLOADER_MODE=ON" 176 "-DOT_THREAD_VERSION=${version}" 177 ) 178 179 if [[ ${version} != "1.1" ]]; then 180 options+=("-DOT_DUA=ON") 181 options+=("-DOT_MLR=ON") 182 options+=("-DOT_LINK_METRICS_INITIATOR=ON") 183 options+=("-DOT_LINK_METRICS_SUBJECT=ON") 184 options+=("-DOT_LINK_METRICS_MANAGER=ON") 185 fi 186 187 if [[ ${FULL_LOGS} == 1 ]]; then 188 options+=("-DOT_FULL_LOGS=ON") 189 fi 190 191 if [[ ${VIRTUAL_TIME} == 1 ]]; then 192 options+=("-DOT_POSIX_VIRTUAL_TIME=ON") 193 fi 194 195 if [[ ${OT_NATIVE_IP} == 1 ]]; then 196 options+=("-DOT_PLATFORM_UDP=ON" "-DOT_PLATFORM_NETIF=ON") 197 fi 198 199 if [[ ${ot_extra_options[*]+x} ]]; then 200 options+=("${ot_extra_options[@]}") 201 fi 202 203 OT_CMAKE_BUILD_DIR="${OT_BUILDDIR}/openthread-posix-${version}" "${OT_SRCDIR}"/script/cmake-build posix "${options[@]}" 204 205 if [[ ${version} != "1.1" && ${INTER_OP_BBR} == 1 ]]; then 206 207 options+=("-DOT_BACKBONE_ROUTER=ON") 208 209 OT_CMAKE_BUILD_DIR="${OT_BUILDDIR}/openthread-posix-${version}-bbr" "${OT_SRCDIR}"/script/cmake-build posix "${options[@]}" 210 fi 211} 212 213build_for_one_version() 214{ 215 local version="$1" 216 217 build_simulation "${version}" 218 219 if [[ ${OT_NODE_TYPE} == rcp* ]]; then 220 build_posix "${version}" 221 fi 222} 223 224do_build() 225{ 226 build_for_one_version "${THREAD_VERSION}" 227 228 if [[ ${THREAD_VERSION} != "1.1" && ${INTER_OP} == "1" ]]; then 229 build_for_one_version 1.1 230 fi 231} 232 233do_clean() 234{ 235 ./script/gcda-tool clean 236 rm -rfv "${OT_BUILDDIR}" || sudo rm -rfv "${OT_BUILDDIR}" 237} 238 239do_unit_version() 240{ 241 local version=$1 242 local builddir="${OT_BUILDDIR}/openthread-simulation-${version}" 243 244 if [[ ! -d ${builddir} ]]; then 245 echo "Cannot find build directory: ${builddir}" 246 exit 1 247 fi 248 249 ( 250 cd "${builddir}" 251 ninja test 252 ) 253} 254 255do_unit() 256{ 257 do_unit_version "${THREAD_VERSION}" 258 259 if [[ ${THREAD_VERSION} != "1.1" && ${INTER_OP_BBR} == 1 ]]; then 260 do_unit_version "1.3-bbr" 261 fi 262} 263 264do_cert() 265{ 266 export top_builddir="${OT_BUILDDIR}/openthread-simulation-${THREAD_VERSION}" 267 export top_srcdir="${OT_SRCDIR}" 268 269 case "${OT_NODE_TYPE}" in 270 rcp | rcp-cli | cli) 271 export NODE_TYPE=sim 272 ;; 273 rcp-ncp | ncp) 274 export NODE_TYPE=ncp-sim 275 ;; 276 esac 277 278 if [[ ${THREAD_VERSION} != "1.1" ]]; then 279 export top_builddir_1_3_bbr="${OT_BUILDDIR}/openthread-simulation-1.3-bbr" 280 if [[ ${INTER_OP} == "1" ]]; then 281 export top_builddir_1_1="${OT_BUILDDIR}/openthread-simulation-1.1" 282 fi 283 fi 284 285 export PYTHONPATH=tests/scripts/thread-cert 286 287 [[ ! -d tmp ]] || rm -rvf tmp 288 PYTHONUNBUFFERED=1 "$@" 289 exit 0 290} 291 292do_cert_suite() 293{ 294 export top_builddir="${OT_BUILDDIR}/openthread-simulation-${THREAD_VERSION}" 295 export top_srcdir="${OT_SRCDIR}" 296 297 if [[ ${THREAD_VERSION} != "1.1" ]]; then 298 export top_builddir_1_3_bbr="${OT_BUILDDIR}/openthread-simulation-1.3-bbr" 299 if [[ ${INTER_OP} == "1" ]]; then 300 export top_builddir_1_1="${OT_BUILDDIR}/openthread-simulation-1.1" 301 fi 302 fi 303 304 export PYTHONPATH=tests/scripts/thread-cert 305 export VIRTUAL_TIME 306 307 sudo modprobe ip6table_filter 308 309 mkdir -p ot_testing 310 ./tests/scripts/thread-cert/run_cert_suite.py --run-directory ot_testing --multiply "${MULTIPLY:-1}" "$@" 311 exit 0 312} 313 314do_get_thread_wireshark() 315{ 316 echo "Downloading thread-wireshark from https://github.com/openthread/wireshark/releases ..." 317 local download_url=https://github.com/openthread/wireshark/releases/download/ot-pktverify-20200727/thread-wireshark.tar.gz 318 local save_file=/tmp/thread-wireshark.tar.gz 319 320 rm -rf /tmp/thread-wireshark || true 321 rm -rf "${save_file}" || true 322 curl -L "${download_url}" -o "${save_file}" 323 tar -C /tmp -xvzf "${save_file}" 324 325 LD_LIBRARY_PATH=/tmp/thread-wireshark /tmp/thread-wireshark/tshark -v 326 LD_LIBRARY_PATH=/tmp/thread-wireshark /tmp/thread-wireshark/dumpcap -v 327 rm -rf "${save_file}" 328} 329 330do_build_otbr_docker() 331{ 332 echo "Building OTBR Docker ..." 333 local otdir 334 local otbrdir 335 local otbr_options=( 336 "-DOT_ANYCAST_LOCATOR=ON" 337 "-DOT_COVERAGE=ON" 338 "-DOT_DNS_CLIENT=ON" 339 "-DOT_DUA=ON" 340 "-DOT_MLR=ON" 341 "-DOT_NETDATA_PUBLISHER=ON" 342 "-DOT_SLAAC=ON" 343 "-DOT_SRP_CLIENT=ON" 344 "-DOT_FULL_LOGS=ON" 345 "-DOT_UPTIME=ON" 346 "-DOTBR_DNS_UPSTREAM_QUERY=ON" 347 "-DOTBR_DUA_ROUTING=ON" 348 ) 349 local args=( 350 "BORDER_ROUTING=${BORDER_ROUTING}" 351 "INFRA_IF_NAME=eth0" 352 "BACKBONE_ROUTER=1" 353 "REFERENCE_DEVICE=1" 354 "OT_BACKBONE_CI=1" 355 "NAT64=${NAT64}" 356 "NAT64_SERVICE=${NAT64_SERVICE}" 357 "DNS64=${NAT64}" 358 "REST_API=0" 359 "WEB_GUI=0" 360 "MDNS=${OTBR_MDNS:-mDNSResponder}" 361 "FIREWALL=${FIREWALL:-1}" 362 ) 363 364 if [[ ${NAT64} != 1 ]]; then 365 # We are testing upstream DNS forwarding in the NAT64 tests, and OPENTHREAD_CONFIG_DNSSD_SERVER_BIND_UNSPECIFIED_NETIF will block OpenThread's DNSSD server since we already have bind9 running. 366 otbr_options+=("-DCMAKE_CXX_FLAGS='-DOPENTHREAD_CONFIG_DNSSD_SERVER_BIND_UNSPECIFIED_NETIF=1'") 367 fi 368 369 if [[ ${TREL} == 1 ]]; then 370 otbr_options+=("-DOTBR_TREL=ON") 371 else 372 otbr_options+=("-DOTBR_TREL=OFF") 373 fi 374 375 local otbr_docker_image=${OTBR_DOCKER_IMAGE:-otbr-ot12-backbone-ci} 376 local docker_build_args=() 377 378 for arg in "${args[@]}"; do 379 docker_build_args+=("--build-arg" "$arg") 380 done 381 382 otbrdir=$(mktemp -d -t otbr_XXXXXX) 383 otdir=$(pwd) 384 385 ( 386 if [[ -z ${LOCAL_OTBR_DIR} ]]; then 387 ./script/git-tool clone https://github.com/openthread/ot-br-posix.git --depth 1 "${otbrdir}" 388 else 389 rsync -r \ 390 --exclude=third_party/openthread/repo \ 391 --exclude=.git \ 392 --exclude=build \ 393 "${LOCAL_OTBR_DIR}/." \ 394 "${otbrdir}" 395 fi 396 397 cd "${otbrdir}" 398 rm -rf third_party/openthread/repo 399 rsync -r \ 400 --exclude=build \ 401 --exclude=ot_testing \ 402 --exclude=__pycache__ \ 403 "${otdir}/." \ 404 third_party/openthread/repo 405 rm -rf .git 406 407 docker build -t "${otbr_docker_image}" -f etc/docker/Dockerfile . \ 408 "${docker_build_args[@]}" \ 409 --build-arg OTBR_OPTIONS="${otbr_options[*]}" 410 ) 411 412 rm -rf "${otbrdir}" 413} 414 415do_pktverify() 416{ 417 ./tests/scripts/thread-cert/pktverify/verify.py "$1" 418} 419 420ot_exec_expect_script() 421{ 422 local log_file="tmp/log_expect" 423 424 for script in "$@"; do 425 echo -e "\n${OT_COLOR_PASS}EXEC${OT_COLOR_NONE} ${script}" 426 sudo killall ot-rcp || true 427 sudo killall ot-cli || true 428 sudo killall ot-cli-ftd || true 429 sudo killall ot-cli-mtd || true 430 sudo rm -rf tmp 431 mkdir tmp 432 { 433 if [[ ${OT_NATIVE_IP} == 1 ]]; then 434 sudo -E expect -df "${script}" 2>"${log_file}" 435 else 436 expect -df "${script}" 2>"${log_file}" 437 fi 438 } || { 439 local EXIT_CODE=$? 440 441 # The exit status 77 for skipping is inherited from automake's test driver for script-based testsuites 442 if [[ ${EXIT_CODE} == 77 ]]; then 443 echo -e "\n${OT_COLOR_SKIP}SKIP${OT_COLOR_NONE} ${script}" 444 return 0 445 else 446 echo -e "\n${OT_COLOR_FAIL}FAIL${OT_COLOR_NONE} ${script}" 447 cat "${log_file}" >&2 448 return "${EXIT_CODE}" 449 fi 450 } 451 echo -e "\n${OT_COLOR_PASS}PASS${OT_COLOR_NONE} ${script}" 452 if [[ ${VERBOSE} == 1 ]]; then 453 cat "${log_file}" >&2 454 fi 455 done 456} 457 458do_expect() 459{ 460 local test_patterns 461 462 if [[ ${OT_NODE_TYPE} == rcp* ]]; then 463 if [[ ${OT_NATIVE_IP} == 1 ]]; then 464 test_patterns=(-name 'tun-*.exp') 465 else 466 test_patterns=(-name 'posix-*.exp' -o -name 'cli-*.exp') 467 if [[ ${THREAD_VERSION} != "1.1" ]]; then 468 test_patterns+=(-o -name 'v1_2-*.exp') 469 fi 470 fi 471 else 472 test_patterns=(-name 'cli-*.exp' -o -name 'simulation-*.exp' -o -name 'cli_non_rcp-*.exp') 473 fi 474 475 if [[ $# != 0 ]]; then 476 ot_exec_expect_script "$@" 477 else 478 export OT_COLOR_PASS OT_COLOR_FAIL OT_COLOR_SKIP OT_COLOR_NONE OT_NATIVE_IP VERBOSE 479 export -f ot_exec_expect_script 480 481 find tests/scripts/expect -type f -perm "$([[ $OSTYPE == darwin* ]] && echo '+' || echo '/')"111 \( "${test_patterns[@]}" \) -exec bash -c 'set -euo pipefail;ot_exec_expect_script "$@"' _ {} + 482 fi 483 484 exit 0 485} 486 487print_usage() 488{ 489 echo "USAGE: [ENVIRONMENTS] $0 COMMANDS 490 491ENVIRONMENTS: 492 OT_NODE_TYPE 'cli' for CLI simulation, 'ncp' for NCP simulation. 493 'rcp' or 'rcp-cli' for CLI on POSIX platform. 494 'rcp-ncp' for NCP on POSIX platform. 495 The default is 'cli'. 496 OT_NATIVE_IP 1 to enable platform UDP and netif on POSIX platform. The default is 0. 497 OT_BUILDDIR The output directory for cmake build. By default the directory is './build'. For example, 498 'OT_BUILDDIR=\${PWD}/my_awesome_build ./script/test clean build'. 499 VERBOSE 1 to build or test verbosely. The default is 0. 500 VIRTUAL_TIME 1 for virtual time, otherwise real time. The default value is 0 when running expect tests, 501 otherwise default value is 1. 502 THREAD_VERSION 1.1 for Thread 1.1 stack, 1.3 for Thread 1.3 stack. The default is 1.3. 503 INTER_OP 1 to build 1.1 together. Only works when THREAD_VERSION is 1.3. The default is 0. 504 INTER_OP_BBR 1 to build bbr version together. Only works when THREAD_VERSION is 1.3. The default is 1. 505 506COMMANDS: 507 clean Clean built files to prepare for new build. 508 build Build project for running tests. This can be used to rebuild the project for changes. 509 cert Run a single thread-cert test. ENVIRONMENTS should be the same as those given to build or update. 510 cert_suite Run a batch of thread-cert tests and summarize the test results. Only echo logs for failing tests. 511 unit Run all the unit tests. This should be called after simulation is built. 512 expect Run expect tests. 513 help Print this help. 514 515EXAMPLES: 516 # Test CLI with default settings 517 $0 clean build cert tests/scripts/thread-cert/Cert_5_1_01_RouterAttach.py 518 $0 cert tests/scripts/thread-cert/Cert_5_1_02_ChildAddressTimeout.py 519 520 # Test NCP with default settings 521 $0 clean build cert tests/scripts/thread-cert/Cert_5_1_01_RouterAttach.py 522 $0 cert tests/scripts/thread-cert/Cert_5_1_02_ChildAddressTimeout.py 523 524 # Test CLI with radio only 525 $0 clean build cert tests/scripts/thread-cert/Cert_5_1_01_RouterAttach.py 526 $0 cert tests/scripts/thread-cert/Cert_5_1_02_ChildAddressTimeout.py 527 528 # Test CLI with real time 529 VIRTUAL_TIME=0 $0 clean build cert tests/scripts/thread-cert/Cert_5_1_01_RouterAttach.py 530 VIRTUAL_TIME=0 $0 cert tests/scripts/thread-cert/Cert_5_1_02_ChildAddressTimeout.py 531 532 # Test Thread 1.1 CLI with real time 533 THREAD_VERSION=1.1 VIRTUAL_TIME=0 $0 clean build cert tests/scripts/thread-cert/Cert_5_1_01_RouterAttach.py 534 THREAD_VERSION=1.1 VIRTUAL_TIME=0 $0 cert tests/scripts/thread-cert/Cert_5_1_02_ChildAddressTimeout.py 535 536 # Test Thread 1.3 with real time, use 'INTER_OP=1' when the case needs both versions. 537 VIRTUAL_TIME=0 $0 clean build cert tests/scripts/thread-cert/v1_2_test_enhanced_keep_alive.py 538 INTER_OP=1 VIRTUAL_TIME=0 $0 clean build cert tests/scripts/thread-cert/v1_2_router_5_1_1.py 539 INTER_OP=1 VIRTUAL_TIME=0 $0 clean build cert_suite tests/scripts/thread-cert/v1_2_* 540 541 # Run a single expect test 542 $0 clean build expect tests/scripts/expect/cli-log-level.exp 543 544 # Run all expect tests 545 $0 clean build expect 546 " 547 548 exit "$1" 549} 550 551do_prepare_coredump_upload() 552{ 553 echo "$OT_COREDUMP_DIR/corefile-%e-%p-%t" | sudo tee /proc/sys/kernel/core_pattern 554 rm -rf "$OT_COREDUMP_DIR" 555 mkdir -p "$OT_COREDUMP_DIR" 556} 557 558do_copy_so_lib() 559{ 560 mkdir -p "$OT_COREDUMP_DIR/so-lib" 561 cp /lib/x86_64-linux-gnu/libgcc_s.so.1 "$OT_COREDUMP_DIR/so-lib" 562 cp /lib/x86_64-linux-gnu/libc.so.6 "$OT_COREDUMP_DIR/so-lib" 563 cp /lib64/ld-linux-x86-64.so.2 "$OT_COREDUMP_DIR/so-lib" 564} 565 566do_check_crash() 567{ 568 shopt -s nullglob 569 570 # Scan core dumps and collect binaries which crashed 571 declare -A bin_list=([dummy]='') 572 for f in "$OT_COREDUMP_DIR"/core*; do 573 bin=$(file "$f" | grep -E -o "execfn: '(.*')," | sed -r "s/execfn: '(.*)',/\1/") 574 bin_list[$bin]='' 575 done 576 577 for key in "${!bin_list[@]}"; do 578 if [ "$key" != "dummy" ]; then 579 # Add postfix for binaries to avoid conflicts caused by different Thread version 580 postfix="" 581 if [[ $key =~ openthread-(simulation|posix)-([0-9]\.[0-9]) ]]; then 582 postfix="-$(echo "$key" | sed -r "s/.*openthread-(simulation|posix)-([0-9]\.[0-9]).*/\2/")" 583 fi 584 bin_name=$(basename "$key") 585 cp "$key" "$OT_COREDUMP_DIR"/"$bin_name""$postfix" 586 fi 587 done 588 589 # echo 1 and copy so libs if crash found, echo 0 otherwise 590 [[ ${#bin_list[@]} -gt 1 ]] && ( 591 echo 1 592 do_copy_so_lib 593 ) || echo 0 594} 595 596do_generate_coverage() 597{ 598 mkdir -p tmp/ 599 sudo chmod 777 tmp/ 600 rm -f tmp/coverage.lcov 601 if [[ $1 == "llvm" ]]; then 602 local llvm_gcov 603 llvm_gcov="$(mktemp -d)/llvm-gcov" 604 echo '#!/bin/bash' >>"$llvm_gcov" 605 echo 'exec llvm-cov gcov "$@"' >>"$llvm_gcov" 606 chmod +x "$llvm_gcov" 607 lcov --gcov-tool "$llvm_gcov" --directory . --capture --output-file tmp/coverage.info 608 else 609 ./script/gcda-tool collect 610 ./script/gcda-tool install 611 612 lcov --directory . --capture --output-file tmp/coverage.info 613 fi 614 lcov --list tmp/coverage.info 615 lcov --extract tmp/coverage.info "$PWD/src/core/common/message.cpp" | c++filt 616} 617 618do_combine_coverage() 619{ 620 ls -R coverage/ 621 622 readarray -d '' files < <(find coverage/ -type f -name 'coverage*.info' -print0) 623 624 local args=() 625 for i in "${files[@]}"; do 626 args+=('-a') 627 args+=("$i") 628 done 629 lcov "${args[@]}" -o final.info 630} 631 632envsetup() 633{ 634 export THREAD_VERSION 635 636 if [[ ${OT_NODE_TYPE} == rcp* ]]; then 637 export RADIO_DEVICE="${OT_BUILDDIR}/openthread-simulation-${THREAD_VERSION}/examples/apps/ncp/ot-rcp" 638 export OT_CLI_PATH="${OT_BUILDDIR}/openthread-posix-${THREAD_VERSION}/src/posix/ot-cli" 639 640 if [[ ${THREAD_VERSION} != "1.1" ]]; then 641 export RADIO_DEVICE_1_1="${OT_BUILDDIR}/openthread-simulation-1.1/examples/apps/ncp/ot-rcp" 642 export OT_CLI_PATH_1_1="${OT_BUILDDIR}/openthread-posix-1.1/src/posix/ot-cli" 643 export OT_CLI_PATH_BBR="${OT_BUILDDIR}/openthread-posix-1.3-bbr/src/posix/ot-cli" 644 fi 645 fi 646 647 export OT_SIMULATION_APPS="${OT_BUILDDIR}/openthread-simulation-${THREAD_VERSION}/examples/apps" 648 export OT_POSIX_APPS="${OT_BUILDDIR}/openthread-posix-${THREAD_VERSION}/src/posix" 649 650 if [[ ! ${VIRTUAL_TIME+x} ]]; then 651 # All expect tests only works in real time mode. 652 VIRTUAL_TIME=1 653 for arg in "$@"; do 654 if [[ $arg == expect ]]; then 655 VIRTUAL_TIME=0 656 break 657 fi 658 done 659 fi 660 661 readonly VIRTUAL_TIME 662 export OT_NODE_TYPE VIRTUAL_TIME 663 664 # CMake always works in verbose mode if VERBOSE exists in environments. 665 if [[ ${VERBOSE} == 1 ]]; then 666 export VERBOSE 667 else 668 export -n VERBOSE 669 fi 670 671 if [[ ${OT_OPTIONS+x} ]]; then 672 read -r -a ot_extra_options <<<"${OT_OPTIONS}" 673 else 674 ot_extra_options=() 675 fi 676} 677 678main() 679{ 680 envsetup "$@" 681 682 if [[ -z ${1-} ]]; then 683 print_usage 1 684 fi 685 686 [[ ${VIRTUAL_TIME} == 1 ]] && echo "Using virtual time" || echo "Using real time" 687 [[ ${THREAD_VERSION} != "1.1" ]] && echo "Using Thread 1.3 stack" || echo "Using Thread 1.1 stack" 688 689 while [[ $# != 0 ]]; do 690 case "$1" in 691 clean) 692 do_clean 693 ;; 694 build) 695 do_build 696 ;; 697 cert) 698 shift 699 do_cert "$@" 700 shift $# 701 ;; 702 cert_suite) 703 shift 704 do_cert_suite "$@" 705 shift $# 706 ;; 707 get_thread_wireshark) 708 do_get_thread_wireshark 709 ;; 710 build_otbr_docker) 711 do_build_otbr_docker 712 ;; 713 pktverify) 714 shift 715 do_pktverify "$1" 716 ;; 717 unit) 718 do_unit 719 ;; 720 help) 721 print_usage 722 ;; 723 package) 724 ./script/package "${ot_extra_options[@]}" 725 ;; 726 expect) 727 shift 728 do_expect "$@" 729 ;; 730 prepare_coredump_upload) 731 do_prepare_coredump_upload 732 ;; 733 check_crash) 734 do_check_crash 735 ;; 736 generate_coverage) 737 shift 738 do_generate_coverage "$1" 739 ;; 740 combine_coverage) 741 do_combine_coverage 742 ;; 743 *) 744 echo 745 echo -e "${OT_COLOR_FAIL}Warning:${OT_COLOR_NONE} Ignoring: '$1'" 746 ;; 747 esac 748 shift 749 done 750} 751 752main "$@" 753