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