Skip to content

Commit

Permalink
tests/gnrc_rpl: add automated test for gnrc_rpl
Browse files Browse the repository at this point in the history
  • Loading branch information
benpicco committed Dec 7, 2021
1 parent 1931fe6 commit 4c91a20
Show file tree
Hide file tree
Showing 5 changed files with 195 additions and 0 deletions.
22 changes: 22 additions & 0 deletions tests/gnrc_rpl/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
include ../Makefile.tests_common

USEMODULE += auto_init_gnrc_netif
USEMODULE += auto_init_gnrc_rpl
USEMODULE += gnrc_ipv6_router_default
USEMODULE += gnrc_icmpv6_echo
USEMODULE += gnrc_rpl

USEMODULE += shell
USEMODULE += shell_commands

# automated test only works on native
TEST_ON_CI_WHITELIST += native

ifeq (native, $(BOARD))
USEMODULE += socket_zep
TERMFLAGS += -z [::1]:17754
else
USEMODULE += netdev_default
endif

include $(RIOTBASE)/Makefile.include
35 changes: 35 additions & 0 deletions tests/gnrc_rpl/Makefile.ci
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
BOARD_INSUFFICIENT_MEMORY := \
arduino-duemilanove \
arduino-leonardo \
arduino-mega2560 \
arduino-nano \
arduino-uno \
atmega328p \
atmega328p-xplained-mini \
bluepill-stm32f030c8 \
i-nucleo-lrwan1 \
msb-430 \
msb-430h \
nucleo-f030r8 \
nucleo-f031k6 \
nucleo-f042k6 \
nucleo-f070rb \
nucleo-f072rb \
nucleo-f103rb \
nucleo-f302r8 \
nucleo-f303k8 \
nucleo-f334r8 \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
samd10-xmini \
slstk3400a \
stk3200 \
stm32f030f4-demo \
stm32f0discovery \
stm32g0316-disco \
stm32l0538-disco \
telosb \
waspmote-pro \
z1 \
#
35 changes: 35 additions & 0 deletions tests/gnrc_rpl/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (C) 2020 HAW
*
* 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.
*/

/**
* @ingroup tests
* @{
*
* @file
* @brief Compile test for gnrc_rpl
*
* @author Cenk Gündoğan <mail+dev@gundogan.net>
*
* @}
*/

#include "shell.h"
#include "msg.h"

#define MAIN_QUEUE_SIZE (8)
static msg_t _main_msg_queue[MAIN_QUEUE_SIZE];

int main(void)
{
char line_buf[SHELL_DEFAULT_BUFSIZE];

msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE);
shell_run(NULL, line_buf, SHELL_DEFAULT_BUFSIZE);

return 0;
}
3 changes: 3 additions & 0 deletions tests/gnrc_rpl/test.topo
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
A B
B C
C D
100 changes: 100 additions & 0 deletions tests/gnrc_rpl/tests/01-run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#!/usr/bin/env python3

# Copyright (C) 2021 Benjamin Valentin
#
# 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 signal
import atexit
import time

from riotctrl_shell.gnrc import GNRCICMPv6Echo, GNRCICMPv6EchoParser
from riotctrl_shell.netif import Ifconfig
from contextlib import ContextDecorator
from riotctrl.ctrl import RIOTCtrl, RIOTCtrlBoardFactory
from riotctrl_ctrl import native
from riotctrl_shell.netif import IfconfigListParser

PARSERS = {
"ping6": GNRCICMPv6EchoParser(),
"ifconfig": IfconfigListParser(),
}

class RIOTCtrlAppFactory(RIOTCtrlBoardFactory, ContextDecorator):

def __init__(self):
super().__init__(board_cls={
'native': native.NativeRIOTCtrl,
})
self.ctrl_list = list()

def __enter__(self):
return self

def __exit__(self, *exc):
for ctrl in self.ctrl_list:
ctrl.stop_term()

def get_shell(self, application_directory='.', env=None):
# retrieve a RIOTCtrl Object
ctrl = super().get_ctrl(
env=env,
application_directory=application_directory
)
# append ctrl to list
self.ctrl_list.append(ctrl)
# flash and start terminal
ctrl.start_term()
# return ctrl with started terminal
return Shell(ctrl)

class Shell(Ifconfig, GNRCICMPv6Echo):
pass

def first_netif_and_addr_by_scope(ifconfig_out, scope):
netifs = PARSERS["ifconfig"].parse(ifconfig_out)
key = next(iter(netifs))
netif = netifs[key]
return (
key,
[addr["addr"] for addr in netif["ipv6_addrs"] if addr["scope"] == scope][0],
)

def global_addr(ifconfig_out):
return first_netif_and_addr_by_scope(ifconfig_out, "global")

with RIOTCtrlAppFactory() as factory:

# spawn dispatcher
pid = os.spawnl(os.P_NOWAIT, '../../dist/tools/zep_dispatch/bin/zep_dispatch',
'zep_dispatch', '-t', 'test.topo', '::1', '17754')
atexit.register(os.kill, pid, signal.SIGTERM)

# create native instances
env = {'BOARD': 'native'}

A = factory.get_shell(env=env)
B = factory.get_shell(env=env)
C = factory.get_shell(env=env)
D = factory.get_shell(env=env)

# add prefix to root node
A.cmd("nib prefix add 5 2001:db8::/32")
root_addr = global_addr(A.ifconfig_list())[1]

# wait for the creation of the DODAG
time.sleep(5)

# ping root node from last node
parser = GNRCICMPv6EchoParser()
result = parser.parse(D.ping6(root_addr))

# assert packetloss is under 10%"))
assert result['stats']['packet_loss'] < 10
# assert at least one responder
assert result['stats']['rx'] > 0
# 2 intermediate hops, 64 - 2
assert result['replies'][0]['ttl'] == 62

0 comments on commit 4c91a20

Please sign in to comment.