• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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