• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# `toranj-cli`
2
3`toranj-cli` is a test framework for OpenThread using its CLI interface.
4
5`toranj` features:
6
7- It is developed in Python.
8- It can be used to simulate multiple nodes forming complex network topologies.
9- It allows testing of network interactions between many nodes.
10- `toranj` in CLI mode runs `ot-cli-ftd` on simulation platform (real-time).
11
12## Setup
13
14To build OpenThread with `toranj` configuration, the `test/toranj/build.sh` script can be used:
15
16```bash
17$ ./tests/toranj/build.sh cmake
18====================================================================================================
19Building OpenThread (NCP/CLI for FTD/MTD/RCP mode) with simulation platform using cmake
20====================================================================================================
21-- OpenThread Source Directory: /Users/abtink/GitHub/openthread
22-- OpenThread CMake build type: Debug
23-- Package Name: OPENTHREAD
24...
25
26```
27
28Or to build using autoconf/make we can use:
29
30```bash
31$ ./tests/toranj/build.sh cli
32====================================================================================================
33Building OpenThread (NCP/CLI for FTD/MTD/RCP mode) with simulation platform using cmake
34====================================================================================================
35-- OpenThread Source Directory: /Users/abtink/GitHub/openthread
36-- OpenThread CMake build type: Debug
37-- Package Name: OPENTHREAD
38...
39
40```
41
42The `toranj-cli` tests are included in `tests/toranj/cli` folder. Each test-case has its own script following naming model `test-nnn-name.py` (e.g., `test-001-get-set.py`).
43
44To run a specific test:
45
46```bash
47$ cd tests/toranj/cli
48$ python3 test-001-get-set.py
49```
50
51To run all CLI tests, `start` script can be used. This script will build OpenThread with proper configuration options and starts running all tests.
52
53```bash
54# From OpenThread repo root folder
55$ top_builddir=($pwd) TORANJ_CLI=1 ./tests/toranj/start.sh
56```
57
58## `toranj-cli` Components
59
60`cli` python module defines the `toranj-cli` test components.
61
62### `cli.Node()` Class
63
64`cli.Node()` class creates a Thread node instance. It creates a sub-process to run `ot-cli-ftd` and provides methods to control the node and issue CLI commands.
65
66```python
67>>> import cli
68>>> node1 = cli.Node()
69>>> node1
70Node (index=1)
71>>> node2 = cli.Node()
72>>> node2
73Node (index=2)
74```
75
76Note: You may need to run as `sudo` to allow log file to be written (i.e., use `sudo python` or `sudo python3`).
77
78### `cli.Node` methods
79
80`cli.Node()` provides methods matching different CLI commands, in addition to some helper methods for common operations.
81
82Example:
83
84```python
85>>> node.get_state()
86'disabled'
87>>> node.get_channel()
88'11'
89>>> node.set_channel(12)
90>>> node.get_channel()
91'12'
92>>> node.set_network_key('11223344556677889900aabbccddeeff')
93>>> node.get_network_key()
94'11223344556677889900aabbccddeeff'
95```
96
97Common network operations:
98
99```python
100    # Form a Thread network with all the given parameters.
101    node.form(network_name=None, network_key=None, channel=None, panid=0x1234, xpanid=None):
102
103    # Try to join an existing network as specified by `another_node`.
104    # `type` can be `JOIN_TYPE_ROUTER`, `JOIN_TYPE_END_DEVICE, or `JOIN_TYPE_SLEEPY_END_DEVICE`
105    node.join(another_node, type=JOIN_TYPE_ROUTER):
106```
107
108A direct CLI command can be issued using `node.cli(command)` with a given `command` string.
109
110```python
111>>> node.cli('uptime')
112['00:36:18.778']
113```
114
115Method `allowlist_node()` can be used to add a given node to the allowlist of the device and enables allowlisting:
116
117```python
118    # `node2` is added to the allowlist of `node1` and allowlisting is enabled on `node1`
119    node1.allowlist_node(node2)
120```
121
122#### Example (simple 3-node topology)
123
124Script below shows how to create a 3-node network topology with `node1` and `node2` being routers, and `node3` an end-device connected to `node2`:
125
126```python
127>>> import cli
128>>> node1 = cli.Node()
129>>> node2 = cli.Node()
130>>> node3 = cli.Node()
131
132>>> node1.form('test')
133>>> node1.get_state()
134'leader'
135
136>>> node1.allowlist_node(node2)
137>>> node1.allowlist_node(node3)
138
139>>> node2.join(node1, cli.JOIN_TYPE_ROUTER)
140>>> node2.get_state()
141'router'
142
143>>> node3.join(node1, cli.JOIN_TYPE_END_DEVICE)
144>>> node3.get_state()
145'child'
146
147>>> node1.cli('neighbor list')
148['0x1c01 0x0400 ']
149```
150
151### Logs and Verbose mode
152
153Every `cli.Node()` instance will save its corresponding logs. By default the logs are saved in a file `ot-logs<node_index>.log`.
154
155When `start.sh` script is used to run all test-cases, if any test fails, to help with debugging of the issue, the last 30 lines of logs of every node involved in the test-case are dumped to `stdout`.
156
157A `cli.Node()` instance can also provide additional logs and info as the test-cases are run (verbose mode). It can be enabled for a node instance when it is created:
158
159```python
160>>> import cli
161>>> node = cli.Node(verbose=True)
162$ Node1.__init__() cmd: `../../../examples/apps/cli/ot-cli-ftd --time-speed=1 1`
163
164>>> node.get_state()
165$ Node1.cli('state') -> disabled
166'disabled'
167
168>>> node.form('test')
169$ Node1.cli('networkname test')
170$ Node1.cli('panid 4660')
171$ Node1.cli('ifconfig up')
172$ Node1.cli('thread start')
173$ Node1.cli('state') -> detached
174$ Node1.cli('state') -> detached
175...
176$ Node1.cli('state') -> leader
177```
178
179Alternatively, `cli.Node._VERBOSE` settings can be changed to enable verbose logging for all nodes. The default value of `cli.Node._VERBOSE` is determined from environment variable `TORANJ_VERBOSE` (verbose mode is enabled when env variable is set to any of `1`, `True`, `Yes`, `Y`, `On` (case-insensitive)), otherwise it is disabled.
180
181## `toranj-cli` and `thread-cert` test framework
182
183`toranj-cli` uses CLI commands to test the behavior of OpenThread with simulation platform. `thread-cert` scripts (in `tests/scripts/thread-cert`) also use CLI commands. However, these two test frameworks have certain differences and are intended for different situations. The `toranj` test cases run in real-time (though it is possible to run with a time speed-up factor) while the `thread-cert` scripts use virtual-time and event-based simulation model.
184
185- `toranj` test cases are useful to validate the real-time (non event-based) simulation platform implementation itself.
186- `toranj` test cases can be used in situations where the platform layer may not support event-based model.
187- `toranj` frameworks allows for more interactive testing (e.g., read–eval–print loop (REPL) model in python) and do not need a separate process to run to handle/dispatch events (which is required for the virtual-time simulation model).
188- `thread-cert` test cases can run quickly (due to virtual time emulation), but the test script itself needs to manage the flow and advancement of time.
189