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