mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-28 07:51:19 +01:00
tests/pkg_semtech-loramac: add automatic test
This commit is contained in:
parent
9e130be8a8
commit
f60e6e008d
@ -26,4 +26,12 @@ USEMODULE += fmt
|
||||
|
||||
FEATURES_OPTIONAL += periph_eeprom
|
||||
|
||||
# Default IotLab Config to run the test
|
||||
ifneq (,$(filter iotlab%,$(MAKECMDGOALS)))
|
||||
IOTLAB_NODES ?= 1
|
||||
IOTLAB_TYPE ?= st-lrwan1:sx1276
|
||||
IOTLAB_SITE ?= saclay
|
||||
include $(RIOTBASE)/dist/testbed-support/Makefile.iotlab
|
||||
endif
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
||||
|
||||
@ -206,3 +206,63 @@ The node will also print the data received:
|
||||
|
||||
> loramac tx test
|
||||
Data received: This is RIOT!
|
||||
|
||||
## Automatic test
|
||||
|
||||
The automatic test replicates 11-lorawan release specs tests:
|
||||
|
||||
- [11-lorawan](https://github.com/RIOT-OS/Release-Specs/blob/ba236c4a1d1258ab63d21b0a860d0f5a5935bbd4/11-lorawan/11-lorawan.md)
|
||||
- [Task #02 - OTAA join procedure](https://github.com/RIOT-OS/Release-Specs/blob/ba236c4a1d1258ab63d21b0a860d0f5a5935bbd4/11-lorawan/11-lorawan.md#task-02---otaa-join-procedure)
|
||||
- [Task #03 - ABP join procedure](https://github.com/RIOT-OS/Release-Specs/blob/ba236c4a1d1258ab63d21b0a860d0f5a5935bbd4/11-lorawan/11-lorawan.md#task-03---abp-join-procedure)
|
||||
- [Task #04 - LoRaWAN device parameters persistence](https://github.com/RIOT-OS/Release-Specs/blob/master/11-lorawan/11-lorawan.md#task-04---lorawan-device-parameters-persistence)
|
||||
|
||||
It is recommended to test using iotlab-nodes. The default configuration is already
|
||||
set on the application Makefile.
|
||||
|
||||
### Requirements
|
||||
|
||||
- The tests assumes that there is a gateway in all DR distance to the device and the
|
||||
device was flashed with the correct keys. The APPEUI is assumed to be the same for OTAA
|
||||
and ABP.
|
||||
|
||||
- The DR duty cycling time-offs values are for EU863-870
|
||||
|
||||
- To use iotlab it is required to have a valid account for the FIT IoT-LAB
|
||||
(registration there is open for everyone) and the [iot-lab/cli-tools](https://github.com/iot-lab/cli-tools) need to be installed.
|
||||
|
||||
- The frame counters must be reset on the LoRaWAN backend at the beginning of the
|
||||
test.
|
||||
|
||||
- iotlab uses TTN lorawan gateways, to run the test you will need to create an
|
||||
[account](https://account.thethingsnetwork.org/), add an [application](https://www.thethingsnetwork.org/docs/applications/add.html)
|
||||
and [register](https://www.thethingsnetwork.org/docs/devices/registration.html)
|
||||
a device. Two devices must be registered, one configured for OTA and another
|
||||
for ABP. For this test you need to take note of the Device EUI, Application EUI
|
||||
& Application Key of the device registered for OTA, as well as the Device EUI,
|
||||
Device Address, Network and Application session keys of the device registered
|
||||
for ABP. The test assumes that both devices have the same Application EUI.
|
||||
|
||||
### Usage
|
||||
|
||||
1. flash device with appropriate keys and test
|
||||
|
||||
$ DEVEUI_OTA=<...> DEVEUI_ABP=<...> APPEUI=<...> APPKEY=<...> DEVADDR=<...> NWKSKEY=<...> APPSKEY=<...> RX2_DR=<...> make BOARD=b-l072z-lrwan1 -C tests/pkg_semtech-loramac test
|
||||
|
||||
#### With iotlab
|
||||
|
||||
1. setup the iotlab experiment:
|
||||
|
||||
$ make -C tests/pkg_semtech-loramac iotlab-exp
|
||||
|
||||
2. flash device with the appropriate keys and test
|
||||
|
||||
$ DEVEUI=<...> APPEUI=<...> APPKEY=<...> DEVADDR=<...> NWKSKEY=<...> APPSKEY=<...> RX2_DR=<...> IOTLAB_NODE=auto-ssh make -C tests/pkg_semtech-loramac flash test
|
||||
|
||||
3. stop the iotlab experiment:
|
||||
|
||||
$ make -C examples/lorawan/ iotlab-stop
|
||||
|
||||
_note_: if you have multiple running experiments you will need to set `IOTLAB_EXP_ID`
|
||||
to the appropriate experiment, when using the `iotlab-exp` you will see a:
|
||||
`Waiting that experiment 175694 gets in state Running`. That number matches
|
||||
the experiment id you started.
|
||||
187
tests/pkg_semtech-loramac/tests/01-run.py
Executable file
187
tests/pkg_semtech-loramac/tests/01-run.py
Executable file
@ -0,0 +1,187 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright (C) 2019 Inria
|
||||
#
|
||||
# This file is subject to the terms and conditions of the GNU Lesser
|
||||
# General Public License v2.1. See the file LICENSE in the top level
|
||||
# directory for more details.
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
from testrunner import run
|
||||
|
||||
# It's assumed that the same APPEUI is used for abp and otaa
|
||||
DEVEUI_ABP = os.getenv('DEVEUI_ABP')
|
||||
DEVEUI_OTA = os.getenv('DEVEUI_OTA')
|
||||
APPEUI = os.getenv('APPEUI')
|
||||
APPKEY = os.getenv('APPKEY')
|
||||
DEVADDR = os.getenv('DEVADDR')
|
||||
NWKSKEY = os.getenv('NWKSKEY')
|
||||
APPSKEY = os.getenv('APPSKEY')
|
||||
|
||||
# Default to things network RX2_DR
|
||||
TEST_RX2_DR = os.getenv('RX2_DR', 3)
|
||||
|
||||
# Theoretical duty cycling timeoff for EU863-870
|
||||
# https://www.semtech.com/uploads/documents/LoraDesignGuide_STD.pdf#page=7
|
||||
TEST_DATA_RATES = {"0": 164.6, "3": 20.6, "5": 6.2}
|
||||
|
||||
# Dummy Message
|
||||
MSG = "This is RIOT"
|
||||
|
||||
|
||||
def _send_line_echo(child, line):
|
||||
child.sendline(line)
|
||||
child.expect_exact(line)
|
||||
child.expect_exact(">")
|
||||
|
||||
|
||||
def _send_line(child, line, expect_line):
|
||||
child.sendline(line)
|
||||
child.expect_exact(expect_line)
|
||||
child.expect_exact(">")
|
||||
|
||||
|
||||
def _reset_config(child):
|
||||
# Start with a clean config
|
||||
child.sendline("loramac erase")
|
||||
child.expect("loramac erase")
|
||||
child.expect_exact(">")
|
||||
child.sendline("reboot")
|
||||
child.expect_exact("reboot")
|
||||
child.expect_exact("All up, running the shell now")
|
||||
child.expect_exact(">")
|
||||
|
||||
|
||||
def _check_eeprom(child):
|
||||
# Check if eeprom is supported
|
||||
child.sendline("loramac help")
|
||||
child.expect(r'Usage: loramac \<([\w+\|?]+)\>')
|
||||
return (len(child.match.group(1).split('|')) == 7)
|
||||
|
||||
|
||||
def _reboot(child, join):
|
||||
if join == "abp":
|
||||
child.sendline("loramac get ul_cnt")
|
||||
child.expect(r'Uplink Counter: (\d+)')
|
||||
uplink_counter = int(child.match.group(1))
|
||||
child.sendline("reboot")
|
||||
child.expect_exact("All up, running the shell now")
|
||||
child.expect_exact(">")
|
||||
if join == "abp":
|
||||
_send_line_echo(child, "loramac set ul_cnt {}".format(uplink_counter))
|
||||
|
||||
|
||||
def _loramac_setup(child, join):
|
||||
if join == "abp":
|
||||
_send_line_echo(child, "loramac set deveui {}".format(DEVEUI_ABP))
|
||||
_send_line_echo(child, "loramac set appeui {}".format(APPEUI))
|
||||
_send_line_echo(child, "loramac set devaddr {}".format(DEVADDR))
|
||||
_send_line_echo(child, "loramac set nwkskey {}".format(NWKSKEY))
|
||||
_send_line_echo(child, "loramac set appskey {}".format(APPSKEY))
|
||||
_send_line_echo(child, "loramac set rx2_dr {}".format(TEST_RX2_DR))
|
||||
else:
|
||||
_send_line_echo(child, "loramac set deveui {}".format(DEVEUI_OTA))
|
||||
_send_line_echo(child, "loramac set appeui {}".format(APPEUI))
|
||||
_send_line_echo(child, "loramac set appkey {}".format(APPKEY))
|
||||
|
||||
|
||||
def loramac_tx_test(child, join):
|
||||
|
||||
_reset_config(child)
|
||||
|
||||
# test all data rates
|
||||
for key, time_off in TEST_DATA_RATES.items():
|
||||
# Setup keys and rx2_dr
|
||||
_loramac_setup(child, join)
|
||||
# Set DR and join
|
||||
_send_line_echo(child, "loramac set dr {}".format(key))
|
||||
child.sendline("loramac join {}".format(join))
|
||||
child.expect_exact(["Join procedure succeeded!",
|
||||
"Warning: already joined!"])
|
||||
child.expect_exact(">")
|
||||
# Transmit cnf message
|
||||
child.sendline("loramac tx \"{}\" cnf 123".format(MSG))
|
||||
child.expect_exact("Received ACK from network", timeout=30)
|
||||
child.expect_exact("Message sent with success")
|
||||
child.expect_exact(">")
|
||||
# Wake-up just before time_off, fail to send
|
||||
time.sleep(time_off)
|
||||
# Send uncnf message with success
|
||||
child.sendline("loramac tx \"{}\" uncnf 42".format(MSG))
|
||||
child.expect_exact("Message sent with success")
|
||||
child.expect_exact(">")
|
||||
# Reboot node
|
||||
_reboot(child, join)
|
||||
|
||||
|
||||
def test_task02(child):
|
||||
loramac_tx_test(child, "otaa")
|
||||
|
||||
|
||||
def test_task03(child):
|
||||
loramac_tx_test(child, "abp")
|
||||
|
||||
|
||||
def test_task04(child):
|
||||
# Erase eeprom
|
||||
_reset_config(child)
|
||||
|
||||
# Verify start from erased state
|
||||
_send_line(child, "loramac get deveui", "DEVEUI: 0000000000000000")
|
||||
_send_line(child, "loramac get appeui", "APPEUI: 0000000000000000")
|
||||
_send_line(child, "loramac get appkey",
|
||||
"APPKEY: 00000000000000000000000000000000")
|
||||
_send_line(child, "loramac get devaddr", "DEVADDR: 00000000")
|
||||
_send_line(child, "loramac get nwkskey",
|
||||
"NWKSKEY: 00000000000000000000000000000000")
|
||||
_send_line(child, "loramac get appskey",
|
||||
"APPSKEY: 00000000000000000000000000000000")
|
||||
|
||||
# Save and verify otaa keys
|
||||
_loramac_setup(child, "otaa")
|
||||
_send_line_echo(child, "loramac save")
|
||||
child.sendline("reboot")
|
||||
child.expect_exact("All up, running the shell now")
|
||||
child.expect_exact(">")
|
||||
_send_line(child, "loramac get deveui", "DEVEUI: {}".format(DEVEUI_OTA))
|
||||
_send_line(child, "loramac get appeui", "APPEUI: {}".format(APPEUI))
|
||||
_send_line(child, "loramac get appkey", "APPKEY: {}".format(APPKEY))
|
||||
_reset_config(child)
|
||||
|
||||
# Save and verify abp keys
|
||||
_loramac_setup(child, "abp")
|
||||
_send_line_echo(child, "loramac save")
|
||||
child.sendline("reboot")
|
||||
child.expect_exact("All up, running the shell now")
|
||||
child.expect_exact(">")
|
||||
_send_line(child, "loramac get devaddr", "DEVADDR: {}".format(DEVADDR))
|
||||
_send_line(child, "loramac get nwkskey", "NWKSKEY: {}".format(NWKSKEY))
|
||||
_send_line(child, "loramac get appskey", "APPSKEY: {}".format(APPSKEY))
|
||||
|
||||
|
||||
def testfunc(child):
|
||||
|
||||
def run(func):
|
||||
if child.logfile == sys.stdout:
|
||||
func(child)
|
||||
else:
|
||||
try:
|
||||
func(child)
|
||||
print(".", end="", flush=True)
|
||||
except Exception as e:
|
||||
print("FAILED")
|
||||
raise e
|
||||
|
||||
run(test_task02)
|
||||
run(test_task03)
|
||||
if(_check_eeprom(child)):
|
||||
run(test_task04)
|
||||
|
||||
print("TEST PASSED")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(run(testfunc))
|
||||
Loading…
x
Reference in New Issue
Block a user