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