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