[nexus] add script to run tests and verify results (#12359)

This script provides a unified entry point for executing Nexus C++
simulations and their corresponding Python packet verification scripts.
It supports running individual test cases or a default suite, handles
PCAP logging, and ensures proper error propagation.
This commit is contained in:
Jonathan Hui
2026-02-03 16:24:02 -08:00
committed by GitHub
parent d97ec73c3f
commit daf7fa615e
+150
View File
@@ -0,0 +1,150 @@
#!/bin/bash
#
# Copyright (c) 2026, The OpenThread Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. Neither the name of the copyright holder nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
set -euo pipefail
# Determine the temporary directory
TEMP_DIR="${TMPDIR:-/tmp}"
# Determine the repository root
REPO_ROOT="$(cd "$(dirname "$0")"/../.. && pwd)"
# Determine the build directory
if [[ -z ${top_builddir:-} ]]; then
BUILD_DIR="build"
else
BUILD_DIR="$top_builddir"
fi
if [[ $BUILD_DIR != /* ]]; then
BUILD_DIR="${REPO_ROOT}/${BUILD_DIR}"
fi
NEXUS_BIN_DIR="${BUILD_DIR}/tests/nexus"
# Default test list if no arguments are provided
DEFAULT_TESTS=(
"5_1_1"
)
# Use provided arguments or the default test list
if [[ $# -eq 0 ]]; then
TESTS_TO_RUN=("${DEFAULT_TESTS[@]}")
else
TESTS_TO_RUN=("$@")
fi
failed_tests=()
run_test()
{
local test_base="$1"
# Strip 'nexus_' prefix if present
test_base="${test_base#nexus_}"
local test_name="nexus_${test_base}"
local json_file="test_${test_base}.json"
local pcap_file="test_${test_base}.pcap"
local verify_script="${REPO_ROOT}/tests/nexus/verify_${test_base}.py"
local nexus_bin="${NEXUS_BIN_DIR}/${test_name}"
printf "========================================================================================\n"
printf "Running %s...\n" "$test_name"
printf "========================================================================================\n"
if [[ ! -x $nexus_bin ]]; then
printf "Error: %s not found or not executable in %s. Did you build the tests?\n" "$test_name" "$NEXUS_BIN_DIR" >&2
return 1
fi
# Create a temporary directory for test artifacts
local work_dir
work_dir=$(mktemp -d "${TEMP_DIR}/nexus_test_${test_base}.XXXXXX")
# Run the Nexus C++ test and verification in a subshell to isolate the working directory
(
cd "$work_dir"
# 1. Run the Nexus C++ test
export OT_NEXUS_PCAP_FILE="$pcap_file"
if ! "$nexus_bin"; then
printf "C++ test %s FAILED\n" "$test_name" >&2
exit 1
fi
# 2. Run the verification script if it exists
if [[ -f $verify_script ]]; then
printf "\n"
printf "Running verification script %s...\n" "$verify_script"
if [[ ! -f $json_file ]]; then
printf "Error: %s not generated by %s.\n" "$json_file" "$test_name" >&2
exit 1
fi
if ! python3 "$verify_script" "$json_file"; then
printf "Verification for %s FAILED\n" "$test_name" >&2
exit 1
fi
else
printf "\n"
printf "No verification script found for %s (%s), skipping verification.\n" "$test_name" "$verify_script"
fi
)
local exit_code="$?"
if [[ $exit_code -eq 0 ]]; then
printf "\n"
printf "%s PASSED\n" "$test_name"
if [[ -d $work_dir && $work_dir == "${TEMP_DIR}/"* ]]; then
rm -rf "$work_dir"
fi
return 0
else
printf "\n"
printf "%s FAILED. Artifacts preserved in: %s\n" "$test_name" "$work_dir" >&2
return 1
fi
}
for t in "${TESTS_TO_RUN[@]}"; do
if ! run_test "$t"; then
failed_tests+=("$t")
fi
done
printf "========================================================================================\n"
if [[ ${#failed_tests[@]} -eq 0 ]]; then
printf "All tests passed successfully.\n"
exit 0
else
printf "The following tests FAILED:\n" >&2
for f in "${failed_tests[@]}"; do
printf " - %s\n" "$f" >&2
done
exit 1
fi