Skip to content

Commit

Permalink
[test] introduce Nexus test framework and platform (openthread#10533)
Browse files Browse the repository at this point in the history
This commit introduces a new test framework named Nexus. The
framework includes the Nexus platform implementation that emulates
platform behavior, allowing multiple nodes running the OpenThread
core stack to be simulated and interact with each other within the
same process.

Unlike the simulation platform, where nodes run in separate processes
and interact via POSIX sockets, Nexus nodes are simulated within a
single process. Nexus tests can interact directly with the C++ or C
OT core APIs, providing more control than the simulation platform's
CLI-based interactions. The flow of time in Nexus tests is directly
controlled by the test itself, allowing for quick time interval
advancement.

This model allows for faster and more scalable simulations, enabling
quick simulation of larger networks for longer durations.

This commit introduces the basic platform implementation, including:
- `nexus_alarm`, `nexus_radio`, and `nexus_settings` modules.
- Logging support, allowing logs to be distinguished per emulated
  node.
  • Loading branch information
abtink authored Oct 9, 2024
1 parent a79ca11 commit 287dbfa
Show file tree
Hide file tree
Showing 23 changed files with 2,152 additions and 2 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/toranj.yml
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,30 @@ jobs:
run: |
./tests/toranj/build.sh posix-15.4
nexus:
name: nexus
runs-on: ubuntu-20.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs

- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
submodules: true
- name: Bootstrap
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
run: |
sudo apt-get update
sudo apt-get --no-install-recommends install -y clang-10 clang++-10 ninja-build llvm lcov
sudo apt-get --no-install-recommends install -y g++-multilib
- name: Build & Run
run: |
./tests/nexus/build.sh
ninja test
upload-coverage:
needs:
- toranj-cli
Expand Down
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,11 @@ if(OT_PLATFORM STREQUAL "posix")
add_subdirectory("${PROJECT_SOURCE_DIR}/src/posix/platform")
elseif(OT_PLATFORM STREQUAL "external")
# skip in this case
elseif(OT_PLATFORM STREQUAL "nexus")
if (OT_APP_CLI OR OT_APP_NCP OR OT_APP_RCP)
message(FATAL_ERROR "no app (cli/ncp/rcp) should be enabled with nexus simulation platform")
endif()
target_compile_definitions(ot-config INTERFACE OPENTHREAD_PLATFORM_NEXUS=1)
else()
target_include_directories(ot-config INTERFACE ${PROJECT_SOURCE_DIR}/examples/platforms/${OT_PLATFORM})
add_subdirectory("${PROJECT_SOURCE_DIR}/examples/platforms/${OT_PLATFORM}")
Expand Down
2 changes: 1 addition & 1 deletion etc/cmake/options.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ message(STATUS "- - - - - - - - - - - - - - - - ")
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Get a list of the available platforms and output as a list to the 'arg_platforms' argument
function(ot_get_platforms arg_platforms)
list(APPEND result "NO" "posix" "external")
list(APPEND result "NO" "posix" "external" "nexus")
set(platforms_dir "${PROJECT_SOURCE_DIR}/examples/platforms")
file(GLOB platforms RELATIVE "${platforms_dir}" "${platforms_dir}/*")
foreach(platform IN LISTS platforms)
Expand Down
23 changes: 23 additions & 0 deletions src/core/instance/instance.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,15 @@ class Instance : public otInstance, private NonCopyable
*/
uint32_t GetId(void) const { return mId; }

#if OPENTHREAD_PLATFORM_NEXUS
/**
* Sets the instance identifier.
*
* @param[in] aId The identifier to assign to the `Instance`.
*/
void SetId(uint32_t aId) { mId = aId; }
#endif

/**
* Indicates whether or not the instance is valid/initialized and not yet finalized.
*
Expand Down Expand Up @@ -412,9 +421,23 @@ class Instance : public otInstance, private NonCopyable
*/
template <typename Type> inline Type &Get(void);

#if OPENTHREAD_PLATFORM_NEXUS
/**
* Constructor to initialize an `Instance`
*/
Instance(void);

/**
* Called after constructor initialization.
*/
void AfterInit(void);
#endif

private:
#if !OPENTHREAD_PLATFORM_NEXUS
Instance(void);
void AfterInit(void);
#endif

// Order of variables (their initialization in `Instance`)
// is important.
Expand Down
6 changes: 5 additions & 1 deletion tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

option(OT_BUILD_GTEST "enable gtest")

if(OT_FTD AND BUILD_TESTING)
if(OT_FTD AND BUILD_TESTING AND (NOT OT_PLATFORM STREQUAL "nexus"))
add_subdirectory(unit)
if(OT_BUILD_GTEST)
add_subdirectory(gtest)
Expand All @@ -40,3 +40,7 @@ option(OT_FUZZ_TARGETS "enable fuzz targets" OFF)
if(OT_FUZZ_TARGETS)
add_subdirectory(fuzz)
endif()

if(OT_PLATFORM STREQUAL "nexus")
add_subdirectory(nexus)
endif()
112 changes: 112 additions & 0 deletions tests/nexus/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#
# Copyright (c) 2024, 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(COMMON_INCLUDES
${PROJECT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/src
${PROJECT_SOURCE_DIR}/src/core
${PROJECT_SOURCE_DIR}/tests/nexus/platform
)

set(COMMON_COMPILE_OPTIONS
-DOPENTHREAD_FTD=1
-DOPENTHREAD_MTD=0
-DOPENTHREAD_RADIO=0
)

add_library(ot-nexus-platform
platform/nexus_alarm.cpp
platform/nexus_core.cpp
platform/nexus_misc.cpp
platform/nexus_node.cpp
platform/nexus_radio.cpp
platform/nexus_settings.cpp
)

target_include_directories(ot-nexus-platform
PRIVATE
${COMMON_INCLUDES}
)

target_compile_options(ot-nexus-platform
PRIVATE
${COMMON_COMPILE_OPTIONS}
)

target_link_libraries(ot-nexus-platform
PRIVATE
ot-config
${OT_MBEDTLS}
)

set(COMMON_LIBS
ot-nexus-platform
openthread-ftd
ot-nexus-platform
${OT_MBEDTLS}
ot-config
openthread-ftd
)

#----------------------------------------------------------------------------------------------------------------------

macro(ot_nexus_test name)

# Macro to add an OpenThread nexus test.
#
# Nexus test name will be `nexus_{name}`. Test source file of
# `test_{name}.cpp` is used. Optional extra arguments can be
# passed to provide additional source files.

add_executable(nexus_${name}
test_${name}.cpp ${ARGN}
)

target_include_directories(nexus_${name}
PRIVATE
${COMMON_INCLUDES}
)

target_link_libraries(nexus_${name}
PRIVATE
${COMMON_LIBS}
)

target_compile_options(nexus_${name}
PRIVATE
${COMMON_COMPILE_OPTIONS}
)

add_test(NAME nexus_${name} COMMAND nexus_${name})
endmacro()


#----------------------------------------------------------------------------------------------------------------------

ot_nexus_test(form_join)
ot_nexus_test(large_network)
29 changes: 29 additions & 0 deletions tests/nexus/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Nexus test framework

Nexus is a test framework for OpenThread testing.

### Design Goals

- **Faster and more scalable network simulation**: Enable faster and more efficient simulations of OpenThread networks involving a large number of nodes over extended durations.
- **Enhanced control**: Achieve greater control and scalability over simulated tests.

### Features

- Includes the Nexus platform implementation that emulates platform behavior, allowing multiple nodes running the OpenThread core stack to be simulated and interact with each other within the same process.
- Unlike the simulation platform (under `examples/platforms/simulation`), where nodes run in separate processes and interact via POSIX sockets, Nexus nodes are simulated within a single process.
- Nexus tests can interact directly with the C++ or C OT core APIs, providing more control than the simulation platform's CLI-based interactions.
- The flow of time in Nexus tests is directly controlled by the test itself, allowing for quick time interval advancement.

### How to build and run tests

To build Nexus test cases, the `build.sh` script can be used:

```bash
./tests/nexus/build.sh
```

Afterwards, each test can be run directly:

```bash
./tests/nexus/nexus_form_join
```
66 changes: 66 additions & 0 deletions tests/nexus/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/bin/bash
#
# Copyright (c) 2024, 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.
#

display_usage()
{
echo ""
echo "Nexus build script "
echo ""
echo ""
}

die()
{
echo " *** ERROR: " "$*"
exit 1
}

cd "$(dirname "$0")" || die "cd failed"
cd ../.. || die "cd failed"

if [ -n "${top_builddir}" ]; then
top_srcdir=$(pwd)
mkdir -p "${top_builddir}"
else
top_srcdir=.
top_builddir=.
fi

echo "===================================================================================================="
echo "Building OpenThread Nexus test platform"
echo "===================================================================================================="
cd "${top_builddir}" || die "cd failed"
cmake -GNinja -DOT_PLATFORM=nexus -DOT_COMPILE_WARNING_AS_ERROR=ON \
-DOT_MULTIPLE_INSTANCE=ON \
-DOT_THREAD_VERSION=1.4 -DOT_APP_CLI=OFF -DOT_APP_NCP=OFF -DOT_APP_RCP=OFF \
-DOT_PROJECT_CONFIG=../tests/nexus/openthread-core-nexus-config.h \
"${top_srcdir}" || die
ninja || die

exit 0
Loading

0 comments on commit 287dbfa

Please sign in to comment.