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