• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/bash
2#
3#  Copyright (c) 2024, 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# Test basic functionality of otbr-agent under NCP mode.
30#
31# Usage:
32#   ./ncp_mode
33set -euxo pipefail
34
35SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
36readonly SCRIPT_DIR
37EXPECT_SCRIPT_DIR="${SCRIPT_DIR}/expect"
38readonly EXPECT_SCRIPT_DIR
39
40#---------------------------------------
41# Configurations
42#---------------------------------------
43OT_CLI="${OT_CLI:-ot-cli-ftd}"
44readonly OT_CLI
45
46OT_NCP="${OT_NCP:-ot-ncp-ftd}"
47readonly OT_NCP
48
49OTBR_DOCKER_IMAGE="${OTBR_DOCKER_IMAGE:-otbr-ncp}"
50readonly OTBR_DOCKER_IMAGE
51
52ABS_TOP_BUILDDIR="$(cd "${top_builddir:-"${SCRIPT_DIR}"/../../}" && pwd)"
53readonly ABS_TOP_BUILDDIR
54
55ABS_TOP_SRCDIR="$(cd "${top_srcdir:-"${SCRIPT_DIR}"/../../}" && pwd)"
56readonly ABS_TOP_SRCDIR
57
58ABS_TOP_OT_SRCDIR="${ABS_TOP_SRCDIR}/third_party/openthread/repo"
59readonly ABS_TOP_OT_SRCDIR
60
61ABS_TOP_OT_BUILDDIR="${ABS_TOP_BUILDDIR}/../simulation"
62readonly ABS_TOP_BUILDDIR
63
64OTBR_COLOR_PASS='\033[0;32m'
65readonly OTBR_COLOR_PASS
66
67OTBR_COLOR_FAIL='\033[0;31m'
68readonly OTBR_COLOR_FAIL
69
70OTBR_COLOR_NONE='\033[0m'
71readonly OTBR_COLOR_NONE
72
73readonly OTBR_VERBOSE="${OTBR_VERBOSE:-0}"
74
75#----------------------------------------
76# Helper functions
77#----------------------------------------
78die()
79{
80    exit_message="$*"
81    echo " *** ERROR: $*"
82    exit 1
83}
84
85exists_or_die()
86{
87    [[ -f $1 ]] || die "Missing file: $1"
88}
89
90executable_or_die()
91{
92    [[ -x $1 ]] || die "Missing executable: $1"
93}
94
95write_syslog()
96{
97    logger -s -p syslog.alert "OTBR_TEST: $*"
98}
99
100#----------------------------------------
101# Test constants
102#----------------------------------------
103TEST_BASE=/tmp/test-otbr
104readonly TEST_BASE
105
106OTBR_AGENT=otbr-agent
107readonly OTBR_AGENT
108
109STAGE_DIR="${TEST_BASE}/stage"
110readonly STAGE_DIR
111
112BUILD_DIR="${TEST_BASE}/build"
113readonly BUILD_DIR
114
115OTBR_DBUS_CONF="${ABS_TOP_BUILDDIR}/src/agent/otbr-agent.conf"
116readonly OTBR_DBUS_CONF
117
118OTBR_AGENT_PATH="${ABS_TOP_BUILDDIR}/src/agent/${OTBR_AGENT}"
119readonly OTBR_AGENT_PATH
120
121# The node ids
122LEADER_NODE_ID=1
123readonly LEADER_NODE_ID
124
125# The TUN device for OpenThread border router.
126TUN_NAME=wpan0
127readonly TUN_NAME
128
129#----------------------------------------
130# Test steps
131#----------------------------------------
132do_build_ot_simulation()
133{
134    sudo rm -rf "${ABS_TOP_OT_BUILDDIR}/ncp"
135    sudo rm -rf "${ABS_TOP_OT_BUILDDIR}/cli"
136    OT_CMAKE_BUILD_DIR=${ABS_TOP_OT_BUILDDIR}/ncp "${ABS_TOP_OT_SRCDIR}"/script/cmake-build simulation \
137        -DOT_MTD=OFF -DOT_RCP=OFF -DOT_APP_CLI=OFF -DOT_APP_RCP=OFF \
138        -DOT_BORDER_ROUTING=ON -DOT_NCP_INFRA_IF=ON -DOT_SIMULATION_INFRA_IF=OFF \
139        -DOT_SRP_SERVER=ON -DOT_SRP_ADV_PROXY=ON -DOT_PLATFORM_DNSSD=ON -DOT_SIMULATION_DNSSD=OFF -DOT_NCP_DNSSD=ON \
140        -DBUILD_TESTING=OFF
141    OT_CMAKE_BUILD_DIR=${ABS_TOP_OT_BUILDDIR}/cli "${ABS_TOP_OT_SRCDIR}"/script/cmake-build simulation \
142        -DOT_MTD=OFF -DOT_RCP=OFF -DOT_APP_NCP=OFF -DOT_APP_RCP=OFF \
143        -DOT_BORDER_ROUTING=OFF \
144        -DBUILD_TESTING=OFF
145}
146
147do_build_otbr_docker()
148{
149    otbr_docker_options=(
150        "-DOT_THREAD_VERSION=1.4"
151        "-DOTBR_DBUS=ON"
152        "-DOTBR_FEATURE_FLAGS=ON"
153        "-DOTBR_TELEMETRY_DATA_API=ON"
154        "-DOTBR_TREL=ON"
155        "-DOTBR_LINK_METRICS_TELEMETRY=ON"
156        "-DOTBR_SRP_ADVERTISING_PROXY=ON"
157    )
158    sudo docker build -t "${OTBR_DOCKER_IMAGE}" \
159        -f ./etc/docker/Dockerfile . \
160        --build-arg NAT64=0 \
161        --build-arg NAT64_SERVICE=0 \
162        --build-arg DNS64=0 \
163        --build-arg WEB_GUI=0 \
164        --build-arg REST_API=0 \
165        --build-arg FIREWALL=0 \
166        --build-arg OTBR_OPTIONS="${otbr_docker_options[*]}"
167}
168
169setup_infraif()
170{
171    if ! ip link show backbone1 >/dev/null 2>&1; then
172        echo "Creating backbone1 with Docker..."
173        docker network create --driver bridge --ipv6 --subnet 9101::/64 -o "com.docker.network.bridge.name"="backbone1" backbone1
174    else
175        echo "backbone1 already exists."
176    fi
177    sudo sysctl -w net.ipv6.conf.backbone1.accept_ra=2
178    sudo sysctl -w net.ipv6.conf.backbone1.accept_ra_rt_info_max_plen=64
179}
180
181test_setup()
182{
183    executable_or_die "${OTBR_AGENT_PATH}"
184
185    # Remove flashes
186    sudo rm -vrf "${TEST_BASE}/tmp"
187    # OPENTHREAD_POSIX_DAEMON_SOCKET_LOCK
188    sudo rm -vf "/tmp/openthread.lock"
189
190    ot_cli=$(find "${ABS_TOP_OT_BUILDDIR}" -name "${OT_CLI}")
191    ot_ncp=$(find "${ABS_TOP_OT_BUILDDIR}" -name "${OT_NCP}")
192    executable_or_die "${ot_cli}"
193    executable_or_die "${ot_ncp}"
194
195    export EXP_OTBR_AGENT_PATH="${OTBR_AGENT_PATH}"
196    export EXP_OT_CLI_PATH="${ot_cli}"
197    export EXP_OT_NCP_PATH="${ot_ncp}"
198
199    # We will be creating a lot of log information
200    # Rotate logs so we have a clean and empty set of logs uncluttered with other stuff
201    if [[ -f /etc/logrotate.conf ]]; then
202        sudo logrotate -f /etc/logrotate.conf || true
203    fi
204
205    # Preparation for otbr-agent
206    exists_or_die "${OTBR_DBUS_CONF}"
207    sudo cp "${OTBR_DBUS_CONF}" /etc/dbus-1/system.d
208
209    write_syslog "AGENT: kill old"
210    sudo killall "${OTBR_AGENT}" || true
211
212    setup_infraif
213
214    # From now on - all exits are TRAPPED
215    # When they occur, we call the function: output_logs'.
216    trap test_teardown EXIT
217}
218
219test_teardown()
220{
221    # Capture the exit code so we can return it below
222    EXIT_CODE=$?
223    readonly EXIT_CODE
224    write_syslog "EXIT ${EXIT_CODE} - output logs"
225
226    sudo pkill -f "${OTBR_AGENT}" || true
227    sudo pkill -f "${OT_CLI}" || true
228    sudo pkill -f "${OT_NCP}" || true
229    wait
230
231    echo 'clearing all'
232    sudo rm /etc/dbus-1/system.d/otbr-agent.conf || true
233    sudo rm -rf "${STAGE_DIR}" || true
234    sudo rm -rf "${BUILD_DIR}" || true
235
236    exit_message="Test teardown"
237    echo "EXIT ${EXIT_CODE}: MESSAGE: ${exit_message}"
238    exit ${EXIT_CODE}
239}
240
241otbr_exec_expect_script()
242{
243    local log_file="tmp/log_expect"
244
245    for script in "$@"; do
246        echo -e "\n${OTBR_COLOR_PASS}EXEC${OTBR_COLOR_NONE} ${script}"
247        sudo killall ot-rcp || true
248        sudo killall ot-cli || true
249        sudo killall ot-cli-ftd || true
250        sudo killall ot-cli-mtd || true
251        sudo killall ot-ncp-ftd || true
252        sudo killall ot-ncp-mtd || true
253        sudo rm -rf tmp
254        mkdir tmp
255        {
256            sudo -E expect -df "${script}" 2>"${log_file}"
257        } || {
258            local EXIT_CODE=$?
259
260            echo -e "\n${OTBR_COLOR_FAIL}FAIL${OTBR_COLOR_NONE} ${script}"
261            cat "${log_file}" >&2
262            return "${EXIT_CODE}"
263        }
264        echo -e "\n${OTBR_COLOR_PASS}PASS${OTBR_COLOR_NONE} ${script}"
265        if [[ ${OTBR_VERBOSE} == 1 ]]; then
266            cat "${log_file}" >&2
267        fi
268    done
269}
270
271do_expect()
272{
273    if [[ $# != 0 ]]; then
274        otbr_exec_expect_script "$@"
275    else
276        mapfile -t test_files < <(find "${EXPECT_SCRIPT_DIR}" -type f -name "ncp_*.exp")
277        otbr_exec_expect_script "${test_files[@]}" || die "ncp expect script failed!"
278    fi
279
280    exit 0
281}
282
283print_usage()
284{
285    cat <<EOF
286USAGE: $0 COMMAND
287
288COMMAND:
289    build_ot_sim         Build simulated ot-cli-ftd and ot-ncp-ftd for testing.
290    build_otbr_docker    Build otbr docker image for testing.
291    expect               Run expect tests for otbr NCP mode.
292    help                 Print this help.
293
294EXAMPLES:
295    $0 build_ot_sim build_otbr_docker expect
296EOF
297    exit 0
298}
299
300main()
301{
302    if [[ $# == 0 ]]; then
303        print_usage
304    fi
305
306    export EXP_TUN_NAME="${TUN_NAME}"
307    export EXP_LEADER_NODE_ID="${LEADER_NODE_ID}"
308    export EXP_OTBR_DOCKER_IMAGE="${OTBR_DOCKER_IMAGE}"
309
310    while [[ $# != 0 ]]; do
311        case "$1" in
312            build_ot_sim)
313                do_build_ot_simulation
314                ;;
315            build_otbr_docker)
316                do_build_otbr_docker
317                ;;
318            expect)
319                shift
320                test_setup
321                do_expect "$@"
322                ;;
323            help)
324                print_usage
325                ;;
326            *)
327                echo
328                echo -e "${OTBR_COLOR_FAIL}Warning:${OTBR_COLOR_NONE} Ignoring: '$1'"
329                ;;
330        esac
331        shift
332    done
333}
334
335main "$@"
336