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