From f13a2b6b99ae7af7934b88ecc9dba5c8bfe4db5e Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Tue, 20 Mar 2018 11:25:18 +0000 Subject: [PATCH] tests: add dhcpv6_client test application --- tests/gnrc_dhcpv6_client/Makefile | 50 ++++++++++++++++ tests/gnrc_dhcpv6_client/Makefile.board.dep | 3 + tests/gnrc_dhcpv6_client/Makefile.ci | 36 ++++++++++++ tests/gnrc_dhcpv6_client/README.md | 38 ++++++++++++ tests/gnrc_dhcpv6_client/dhcpv6_server.sh | 25 ++++++++ tests/gnrc_dhcpv6_client/kea-dhcp6.conf | 45 ++++++++++++++ tests/gnrc_dhcpv6_client/main.c | 65 +++++++++++++++++++++ tests/gnrc_dhcpv6_client/tests/01-run.py | 32 ++++++++++ 8 files changed, 294 insertions(+) create mode 100644 tests/gnrc_dhcpv6_client/Makefile create mode 100644 tests/gnrc_dhcpv6_client/Makefile.board.dep create mode 100644 tests/gnrc_dhcpv6_client/Makefile.ci create mode 100644 tests/gnrc_dhcpv6_client/README.md create mode 100755 tests/gnrc_dhcpv6_client/dhcpv6_server.sh create mode 100644 tests/gnrc_dhcpv6_client/kea-dhcp6.conf create mode 100644 tests/gnrc_dhcpv6_client/main.c create mode 100755 tests/gnrc_dhcpv6_client/tests/01-run.py diff --git a/tests/gnrc_dhcpv6_client/Makefile b/tests/gnrc_dhcpv6_client/Makefile new file mode 100644 index 0000000000..c0a6da45ee --- /dev/null +++ b/tests/gnrc_dhcpv6_client/Makefile @@ -0,0 +1,50 @@ +include ../Makefile.tests_common + +# generate random free port +DHCPV6_SERVER_PORT := 61342 + +RIOTBASE ?= $(CURDIR)/../.. + +# boards don't support ethos +BOARD_BLACKLIST += mips-malta pic32-wifire pic32-clicker ruuvitag thingy52 + +USEMODULE += gnrc_dhcpv6_client +USEMODULE += gnrc_ipv6_default +USEMODULE += xtimer +ifneq (,$(filter native,$(BOARD))) + # Has to be provided here and not in Makefile.dep, so TERMFLAGS are properly + # configured + USEMODULE += netdev_default + IFACE ?= tapbr0 +else + IFACE ?= tap0 + ETHOS_BAUDRATE ?= 115200 + CFLAGS += -DETHOS_BAUDRATE=$(ETHOS_BAUDRATE) + TERMPROG ?= sudo sh $(RIOTBASE)/dist/tools/ethos/ethos + TERMFLAGS ?= $(IFACE) $(PORT) $(ETHOS_BAUDRATE) + TERMDEPS += ethos +endif +USEMODULE += auto_init_gnrc_netif + +USEMODULE += shell_commands + +CFLAGS += -DDHCPV6_SERVER_PORT=$(DHCPV6_SERVER_PORT) + +TEST_DEPS += dhcpv6_server + +# The test requires to be run as root +TEST_ON_CI_BLACKLIST += all + +include $(RIOTBASE)/Makefile.include + +.PHONY: dhcpv6_server + +dhcpv6_server: + $(CURDIR)/dhcpv6_server.sh $(DHCPV6_SERVER_PORT) $(CURDIR)/kea-dhcp6.conf + +ifeq (,$(filter native,$(BOARD))) +.PHONY: ethos + +ethos: + $(Q)env -u CC -u CFLAGS make -C $(RIOTBASE)/dist/tools/ethos +endif diff --git a/tests/gnrc_dhcpv6_client/Makefile.board.dep b/tests/gnrc_dhcpv6_client/Makefile.board.dep new file mode 100644 index 0000000000..c6c89a0bde --- /dev/null +++ b/tests/gnrc_dhcpv6_client/Makefile.board.dep @@ -0,0 +1,3 @@ +ifneq (native,$(BOARD)) + USEMODULE += stdio_ethos +endif diff --git a/tests/gnrc_dhcpv6_client/Makefile.ci b/tests/gnrc_dhcpv6_client/Makefile.ci new file mode 100644 index 0000000000..cf493050f1 --- /dev/null +++ b/tests/gnrc_dhcpv6_client/Makefile.ci @@ -0,0 +1,36 @@ +BOARD_INSUFFICIENT_MEMORY := \ + arduino-duemilanove \ + arduino-leonardo \ + arduino-mega2560 \ + arduino-nano \ + arduino-uno \ + atmega1284p \ + atmega328p \ + derfmega128 \ + hifive1 \ + hifive1b \ + i-nucleo-lrwan1 \ + mega-xplained \ + microduino-corerf \ + msb-430 \ + msb-430h \ + nucleo-f030r8 \ + nucleo-f031k6 \ + nucleo-f042k6 \ + nucleo-f070rb \ + nucleo-f072rb \ + nucleo-f303k8 \ + nucleo-f334r8 \ + nucleo-l031k6 \ + nucleo-l053r8 \ + saml10-xpro \ + saml11-xpro \ + stm32f030f4-demo \ + stm32f0discovery \ + stm32l0538-disco \ + telosb \ + waspmote-pro \ + wsn430-v1_3b \ + wsn430-v1_4 \ + z1 \ + # diff --git a/tests/gnrc_dhcpv6_client/README.md b/tests/gnrc_dhcpv6_client/README.md new file mode 100644 index 0000000000..90fbe649ca --- /dev/null +++ b/tests/gnrc_dhcpv6_client/README.md @@ -0,0 +1,38 @@ +# Overview + +This folder contains a test application for RIOT's DHCPv6 client. + +# How to test + +The test script requires [Kea] as DHCPv6 server. It is available as +`kea-dhcp6-server` on Ubuntu since Ubuntu 16.04: + +```sh +apt-get install kea-dhcp6-server +``` + +On Arch Linux it is available in the `kea` package: + +```sh +pacman -Syu kea +``` + +If you use any platform other than `native`, you need to use `ethos`, otherwise +`netdev_tap` is chosen. + +An instance of Kea that configured via [kea-dhcp6.conf](kea-dhcp6.conf) is +started in parallel to `make term`/`make test`. + +Read the [Kea documentation] on the configuration file for more information. + +The default set-up is configured so a `2001:db8::/32` is delegated via the +`tapbr0` bridge as created with the `dist/tools/tapsetup/tapsetup` script. +If you created your interface and without the script, please reconfigure Kea by +search & replacing "`tapbr0`" in the configuration file. + +```sh +BOARD=samr21-xpro make flash test +``` + +[Kea]: http://kea.isc.org +[Kea documentation]: https://kea.readthedocs.io/en/latest/arm/config.html diff --git a/tests/gnrc_dhcpv6_client/dhcpv6_server.sh b/tests/gnrc_dhcpv6_client/dhcpv6_server.sh new file mode 100755 index 0000000000..5a1e95691b --- /dev/null +++ b/tests/gnrc_dhcpv6_client/dhcpv6_server.sh @@ -0,0 +1,25 @@ +#! /bin/bash +# +# random_port.sh +# Copyright (C) 2018 Martine Lenders +# +# Distributed under terms of the MIT license. +# + +if [ "$EUID" -ne 0 ]; then + echo -e "\033[31;1mRequire root since kea uses some PID and Lock files in /var\033[0m" >&2 + exit 1 +fi + +if ! command -v kea-dhcp6; then + echo -e "\033[31;1mCommand kea-dhcp6 required\033[0m" >&2 + exit 1 +fi + +_dhcpv6_server() { + sleep 1 # sleep to let TAP become active + sudo kea-dhcp6 -p $1 -c $2 +} + +# no need to kill from external, kea handles double instances gracefully +_dhcpv6_server $1 $2 & diff --git a/tests/gnrc_dhcpv6_client/kea-dhcp6.conf b/tests/gnrc_dhcpv6_client/kea-dhcp6.conf new file mode 100644 index 0000000000..e8b9a7964a --- /dev/null +++ b/tests/gnrc_dhcpv6_client/kea-dhcp6.conf @@ -0,0 +1,45 @@ +{ + "Dhcp6": + { + "interfaces-config": { + "interfaces": [ "tapbr0" ] + }, + "lease-database": { + "type": "memfile" + }, + "expired-leases-processing": { + "reclaim-timer-wait-time": 10, + "flush-reclaimed-timer-wait-time": 25, + "hold-reclaimed-time": 3600, + "max-reclaim-leases": 100, + "max-reclaim-time": 250, + "unwarned-reclaim-cycles": 5 + }, + "preferred-lifetime": 3000, + "valid-lifetime": 4000, + "renew-timer": 1000, + "rebind-timer": 2000, + "subnet6": [ + { "interface": "tapbr0", + "subnet": "2001:db8::/32", + "pd-pools": [ { "prefix": "2001:db8::", + "prefix-len": 32, + "delegated-len": 64 } ] } + ] + }, +"Logging": +{ + "loggers": [ + { + "name": "kea-dhcp6", + "output_options": [ + { + "output": "stderr" + } + ], + "severity": "INFO", + "debuglevel": 0 + } + ] +} +} diff --git a/tests/gnrc_dhcpv6_client/main.c b/tests/gnrc_dhcpv6_client/main.c new file mode 100644 index 0000000000..b1260a4ccd --- /dev/null +++ b/tests/gnrc_dhcpv6_client/main.c @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2018 Freie Universität Berlin + * + * 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 DHCPv6 client test application + * + * @author Martine Lenders + * @} + */ + +#include + +#include "net/gnrc/netif.h" +#include "net/dhcpv6/client.h" +#include "net/sock.h" +#include "xtimer.h" + +static char _dhcpv6_client_stack[DHCPV6_CLIENT_STACK_SIZE]; + +extern int _gnrc_netif_config(int argc, char **argv); +extern int _gnrc_ipv6_nib(int argc, char **argv); + +void *_dhcpv6_client_thread(void *args) +{ + event_queue_t event_queue; + gnrc_netif_t *netif = gnrc_netif_iter(NULL); + + (void)args; + /* initialize client event queue */ + event_queue_init(&event_queue); + /* initialize DHCPv6 client on any interface */ + dhcpv6_client_init(&event_queue, SOCK_ADDR_ANY_NETIF); + /* configure client to request prefix delegation of /64 subnet + * interface netif */ + dhcpv6_client_req_ia_pd(netif->pid, 64U); + /* start DHCPv6 client */ + dhcpv6_client_start(); + /* start event loop of DHCPv6 client */ + event_loop(&event_queue); /* never returns */ + return NULL; +} + +int main(void) +{ + char *pl[] = { "nib", "prefix" }; + + _gnrc_netif_config(0, NULL); + thread_create(_dhcpv6_client_stack, DHCPV6_CLIENT_STACK_SIZE, + DHCPV6_CLIENT_PRIORITY, THREAD_CREATE_STACKTEST, + _dhcpv6_client_thread, NULL, "dhcpv6-client"); + xtimer_sleep(5); + /* global address should now be configured */ + _gnrc_netif_config(0, NULL); + _gnrc_ipv6_nib(2, pl); + return 0; +} diff --git a/tests/gnrc_dhcpv6_client/tests/01-run.py b/tests/gnrc_dhcpv6_client/tests/01-run.py new file mode 100755 index 0000000000..ed9d1ab41e --- /dev/null +++ b/tests/gnrc_dhcpv6_client/tests/01-run.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2018 Freie Universität Berlin +# +# 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 sys +from testrunner import run + + +def testfunc(child): + child.expect(r"Iface\s+\d+") + child.expect(r"inet6 addr:\sfe80:[0-9a-f:]+\s+scope: link") + child.expect(r"Iface\s+\d+") + child.expect(r"inet6 addr:\s+fe80:[0-9a-f:]+\s+scope: link") + child.expect(r"inet6 addr:\s+(?P[0-9a-f:]+)\s+scope: global") + global_addr = child.match.group("global_addr") + child.expect(r"(?P[0-9a-f:]+)/64\s+dev #\d\s+" + r"expires \d+sec\s+" + r"deprecates \d+sec") + global_pfx = child.match.group("global_pfx") + if global_pfx.endswith("::"): + # remove one trailing : in case there are no 0s between prefix and + # suffix + global_pfx = global_pfx[0:-1] + assert global_addr.startswith(global_pfx) + + +if __name__ == "__main__": + sys.exit(run(testfunc, timeout=5))