From 77d977032c7cd2e8b572340823786321d5a5504c Mon Sep 17 00:00:00 2001
From: Martine Lenders <m.lenders@fu-berlin.de>
Date: Fri, 21 Jul 2017 15:34:51 +0200
Subject: [PATCH] tests: add tests for gnrc_netif2

---
 tests/gnrc_netif2/Makefile        |   37 +
 tests/gnrc_netif2/common.c        |  163 +++++
 tests/gnrc_netif2/common.h        |   88 +++
 tests/gnrc_netif2/main.c          | 1038 +++++++++++++++++++++++++++++
 tests/gnrc_netif2/tests/01-run.py |   82 +++
 5 files changed, 1408 insertions(+)
 create mode 100644 tests/gnrc_netif2/Makefile
 create mode 100644 tests/gnrc_netif2/common.c
 create mode 100644 tests/gnrc_netif2/common.h
 create mode 100644 tests/gnrc_netif2/main.c
 create mode 100755 tests/gnrc_netif2/tests/01-run.py

diff --git a/tests/gnrc_netif2/Makefile b/tests/gnrc_netif2/Makefile
new file mode 100644
index 0000000000..37e2497de0
--- /dev/null
+++ b/tests/gnrc_netif2/Makefile
@@ -0,0 +1,37 @@
+# name of your application
+APPLICATION = gnrc_ipv6_nib
+include ../Makefile.tests_common
+
+BOARD_INSUFFICIENT_MEMORY := airfy-beacon b-l072z-lrwan1 calliope-mini \
+                             cc2650-launchpad cc2650stk chronos maple-mini \
+                             microbit msb-430 msb-430h nrf51dongle nrf6310 \
+                             nucleo-f030 nucleo-f070 nucleo-f072 nucleo-f103 \
+                             nucleo-f302 nucleo-f334 nucleo-l053 nucleo-l073 \
+                             nucleo32-f031 nucleo32-f042 nucleo32-f303 \
+                             nucleo32-l031 opencm904 pca10000 pca10005 \
+                             spark-core stm32f0discovery telosb wsn430-v1_3b \
+                             wsn430-v1_4 yunjia-nrf51822 z1 \
+
+USEMODULE += embunit
+USEMODULE += gnrc_netif2
+USEMODULE += gnrc_pktdump
+USEMODULE += gnrc_sixlowpan
+USEMODULE += gnrc_sixlowpan_iphc
+USEMODULE += gnrc_ipv6
+USEMODULE += netdev_eth
+USEMODULE += netdev_test
+USEMODULE += od
+
+CFLAGS += -DDEVELHELP
+CFLAGS += -DGNRC_NETIF_NUMOF=4
+CFLAGS += -DGNRC_NETIF2_ADDRS_NUMOF=16
+CFLAGS += -DGNRC_NETIF2_GROUPS_NUMOF=8
+CFLAGS += -DLOG_LEVEL=LOG_NONE
+CFLAGS += -DTEST_SUITES
+
+include $(RIOTBASE)/Makefile.include
+
+test:
+# `testrunner` calls `make term` recursively, results in duplicated `TERMFLAGS`.
+# So clears `TERMFLAGS` before run.
+	TERMFLAGS= tests/01-run.py
diff --git a/tests/gnrc_netif2/common.c b/tests/gnrc_netif2/common.c
new file mode 100644
index 0000000000..d106ee3d09
--- /dev/null
+++ b/tests/gnrc_netif2/common.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+/**
+ * @{
+ *
+ * @file
+ * @author  Martine Lenders <m.lenders@fu-berlin.de>
+ */
+
+#include <errno.h>
+#include <stdio.h>
+
+#include "common.h"
+#include "net/ethernet.h"
+#include "net/gnrc/netreg.h"
+#include "net/gnrc/pktdump.h"
+#include "net/ipv6.h"
+#include "net/netdev_test.h"
+#include "od.h"
+
+static netdev_test_t _devs[GNRC_NETIF_NUMOF];
+
+netdev_t *ethernet_dev = (netdev_t *)&_devs[0];
+netdev_t *devs[DEFAULT_DEVS_NUMOF];
+
+#define MSG_QUEUE_SIZE  (8)
+
+static gnrc_netreg_entry_t dumper_undef, dumper_ipv6;
+static msg_t _main_msg_queue[MSG_QUEUE_SIZE];
+static uint8_t tmp_buffer[ETHERNET_DATA_LEN];
+static size_t tmp_buffer_bytes = 0;
+
+static int _dump_send_packet(netdev_t *netdev, const struct iovec *vector,
+                             int count)
+{
+    int res;
+
+    tmp_buffer_bytes = 0;
+
+    printf("Sending data from ");
+    if (netdev == ethernet_dev) {
+        printf("Ethernet ");
+    }
+    else {
+        printf("unknown ");
+    }
+    puts("device:");
+    for (int i = 0; i < count; i++) {
+        if ((tmp_buffer_bytes + vector[i].iov_len) > ETHERNET_DATA_LEN) {
+            return -ENOBUFS;
+        }
+        memcpy(&tmp_buffer[tmp_buffer_bytes], vector[i].iov_base,
+               vector[i].iov_len);
+        tmp_buffer_bytes += vector[i].iov_len;
+    }
+    od_hex_dump(tmp_buffer, tmp_buffer_bytes, OD_WIDTH_DEFAULT);
+    res = (int)tmp_buffer_bytes;
+    return res;
+}
+
+void _test_trigger_recv(gnrc_netif2_t *netif, const uint8_t *data,
+                        size_t data_len)
+{
+    netdev_t *dev = netif->dev;
+
+    assert(data_len <= ETHERNET_DATA_LEN);
+    if ((data != NULL) || (data_len > 0)) {
+        tmp_buffer_bytes = data_len;
+        memcpy(tmp_buffer, data, data_len);
+    }
+    else {
+        tmp_buffer_bytes = 0;
+    }
+    assert(dev->event_callback);
+    dev->event_callback(dev, NETDEV_EVENT_ISR);
+}
+
+static int _netdev_recv(netdev_t *dev, char *buf, int len, void *info)
+{
+    int res;
+
+    (void)dev;
+    (void)info;
+    res = (int)tmp_buffer_bytes;
+    if (buf == NULL) {
+        if (len > 0) {
+            tmp_buffer_bytes = 0;
+        }
+        return res;
+    }
+    if (((unsigned)len) < tmp_buffer_bytes) {
+        return -ENOBUFS;
+    }
+    memcpy(buf, tmp_buffer, tmp_buffer_bytes);
+    return res;
+}
+
+static void _netdev_isr(netdev_t *dev)
+{
+    assert(dev->event_callback);
+    dev->event_callback(dev, NETDEV_EVENT_RX_COMPLETE);
+}
+
+static int _get_netdev_device_type(netdev_t *netdev, void *value, size_t max_len)
+{
+    netdev_test_t *dev = (netdev_test_t *)netdev;
+    assert(max_len == sizeof(uint16_t));
+    if (dev->state == 0x0) {
+        *((uint16_t *)value) = NETDEV_TYPE_ETHERNET;
+    }
+    else {
+        *((uint16_t *)value) = NETDEV_TYPE_UNKNOWN;
+    }
+    return sizeof(uint16_t);
+}
+static int _get_netdev_max_packet_size(netdev_t *netdev, void *value, size_t max_len)
+{
+    netdev_test_t *dev = (netdev_test_t *)netdev;
+    assert(max_len == sizeof(uint16_t));
+    if (dev->state == 0x0) {
+        *((uint16_t *)value) = ETHERNET_DATA_LEN;
+    }
+    else {
+        *((uint16_t *)value) = IPV6_MIN_MTU;
+    }
+    return sizeof(uint16_t);
+}
+
+
+void _tests_init(void)
+{
+    msg_init_queue(_main_msg_queue, MSG_QUEUE_SIZE);
+    netdev_test_setup((netdev_test_t *)ethernet_dev, 0);
+    netdev_test_set_send_cb((netdev_test_t *)ethernet_dev, _dump_send_packet);
+    netdev_test_set_recv_cb((netdev_test_t *)ethernet_dev, _netdev_recv);
+    netdev_test_set_isr_cb((netdev_test_t *)ethernet_dev, _netdev_isr);
+    netdev_test_set_get_cb((netdev_test_t *)ethernet_dev, NETOPT_DEVICE_TYPE,
+                           _get_netdev_device_type);
+    netdev_test_set_get_cb((netdev_test_t *)ethernet_dev, NETOPT_MAX_PACKET_SIZE,
+                           _get_netdev_max_packet_size);
+    for (intptr_t i = SPECIAL_DEVS; i < GNRC_NETIF_NUMOF; i++) {
+        devs[i - SPECIAL_DEVS] = (netdev_t *)&_devs[i];
+        netdev_test_setup(&_devs[i], (void *)i);
+        netdev_test_set_get_cb(&_devs[i], NETOPT_DEVICE_TYPE,
+                               _get_netdev_device_type);
+        netdev_test_set_get_cb(&_devs[i], NETOPT_MAX_PACKET_SIZE,
+                               _get_netdev_max_packet_size);
+    }
+    gnrc_netreg_entry_init_pid(&dumper_undef, GNRC_NETREG_DEMUX_CTX_ALL,
+                               gnrc_pktdump_pid);
+    gnrc_netreg_entry_init_pid(&dumper_ipv6, GNRC_NETREG_DEMUX_CTX_ALL,
+                               gnrc_pktdump_pid);
+    gnrc_netreg_register(GNRC_NETTYPE_UNDEF, &dumper_undef);
+    gnrc_netreg_register(GNRC_NETTYPE_IPV6, &dumper_ipv6);
+}
+
+/** @} */
diff --git a/tests/gnrc_netif2/common.h b/tests/gnrc_netif2/common.h
new file mode 100644
index 0000000000..7144bd723d
--- /dev/null
+++ b/tests/gnrc_netif2/common.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+/**
+ * @defgroup    tests_gnrc_ipv6_nib Common header for GNRC's NIB tests
+ * @ingroup     tests
+ * @brief       Common definitions for GNRC's NIB tests
+ * @{
+ *
+ * @file
+ *
+ * @author  Martine Lenders <m.lenders@fu-berlin.de>
+ */
+#ifndef COMMON_H
+#define COMMON_H
+
+
+#include "net/gnrc/netif2.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SPECIAL_DEVS        (1)
+#define DEFAULT_DEVS_NUMOF  (GNRC_NETIF_NUMOF - SPECIAL_DEVS)
+
+#define GP1 (0x20U)
+#define GP2 (0x01U)
+#define GP3 (0x0dU)
+#define GP4 (0xb8U)
+#define GP5 (0x00U)
+#define GP6 (0x00U)
+#define GP7 (0x5aU)
+#define GP8 (0x1aU)
+
+#define LP1 (0xfeU)
+#define LP2 (0x80U)
+#define LP3 (0x00U)
+#define LP4 (0x00U)
+#define LP5 (0x00U)
+#define LP6 (0x00U)
+#define LP7 (0x00U)
+#define LP8 (0x00U)
+
+#define LA1 (0x3eU)
+#define LA2 (0xe6U)
+#define LA3 (0xb5U)
+#define LA4 (0x0fU)
+#define LA5 (0x19U)
+#define LA6 (0x22U)
+#define LA7 (0xfdU)
+#define LA8 (0x0aU)
+
+#define ETHERNET_SRC        { LA1, LA2, LA3, LA6, LA7, LA8 }
+#define ETHERNET_IPV6_LL    { LP1, LP2, LP3, LP4, LP5, LP6, LP7, LP8, \
+                              LA1 ^ 0x2, LA2, LA3, 0xff, 0xfe, LA6, LA7, LA8 }
+#define ETHERNET_IPV6_G     { GP1, GP2, GP3, GP4, GP5, GP6, GP7, GP8, \
+                              LA1 ^ 0x2, LA2, LA3, 0xff, 0xfe, LA6, LA7, LA8 }
+#define NETIF0_SRC          { LA1, LA2 + 1, LA3, LA4, LA5, LA6, LA7, LA8 }
+#define NETIF0_IPV6_LL      { LP1, LP2, LP3, LP4, LP5, LP6, LP7, LP8, \
+                              LA1 ^ 0x2, LA2 + 1, LA3, LA4, LA5, LA6, LA7, LA8 }
+#define NETIF0_IPV6_G       { GP1, GP2, GP3, GP4, GP5, GP6, GP7, GP8, \
+                              LA1 ^ 0x2, LA2 + 1, LA3, LA4, LA5, LA6, LA7, LA8 }
+#define GLOBAL_PFX18        { GP1, GP2, GP3 ^ 0x3f, GP4, GP5, GP6, GP7, GP8, \
+                              LA1 ^ 0x2, LA2, LA3, LA4, LA5, LA6, LA7, LA8 }
+#define GLOBAL_PFX23        { GP1, GP2, GP3 ^ 0x1, GP4, GP5, GP6, GP7, GP8, \
+                              LA1 ^ 0x2, LA2, LA3, LA4, LA5, LA6, LA7, LA8 }
+#define GLOBAL_PFX64        { GP1, GP2, GP3, GP4, GP5, GP6, GP7, GP8, \
+                              LA1 ^ 0x82, LA2, LA3, LA4, LA5, LA6, LA7, LA8 }
+
+extern netdev_t *ethernet_dev;
+extern netdev_t *devs[DEFAULT_DEVS_NUMOF];
+
+void _tests_init(void);
+void _test_trigger_recv(gnrc_netif2_t *netif, const uint8_t *data,
+                        size_t data_len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* COMMON_H */
+/** @} */
diff --git a/tests/gnrc_netif2/main.c b/tests/gnrc_netif2/main.c
new file mode 100644
index 0000000000..435a0f8f61
--- /dev/null
+++ b/tests/gnrc_netif2/main.c
@@ -0,0 +1,1038 @@
+/*
+ * Copyright (C) 2017 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       Tests default configuration of GNRC's Network Information Base
+ *
+ * @author      Martine Lenders <m.lenders@fu-berlin.de>
+ *
+ * @}
+ */
+
+#include <errno.h>
+#include <stdio.h>
+
+#include "common.h"
+#include "embUnit.h"
+#include "embUnit/embUnit.h"
+#include "net/ethernet.h"
+#include "net/ipv6.h"
+#include "net/gnrc.h"
+#include "net/gnrc/ipv6/hdr.h"
+#include "net/gnrc/netif/hdr.h"
+#include "net/gnrc/netif2.h"
+#include "net/gnrc/netif2/ethernet.h"
+#include "net/gnrc/netif2/internal.h"
+#include "net/netdev_test.h"
+#include "utlist.h"
+#include "xtimer.h"
+
+#define ETHERNET_STACKSIZE          (THREAD_STACKSIZE_MAIN)
+
+static gnrc_netif2_t *ethernet_netif = NULL;
+static gnrc_netif2_t *netifs[DEFAULT_DEVS_NUMOF];
+static char ethernet_netif_stack[ETHERNET_STACKSIZE];
+static char netifs_stack[DEFAULT_DEVS_NUMOF][THREAD_STACKSIZE_DEFAULT];
+static bool init_called = false;
+
+static inline void _test_init(gnrc_netif2_t *netif);
+static inline int _mock_netif_send(gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt);
+static inline gnrc_pktsnip_t *_mock_netif_recv(gnrc_netif2_t * netif);
+static int _get_netdev_address(netdev_t *dev, void *value, size_t max_len);
+static int _set_netdev_address(netdev_t *dev, const void *value, size_t value_len);
+
+static const gnrc_netif2_ops_t default_ops = {
+    .init = _test_init,
+    .send = _mock_netif_send,
+    .recv = _mock_netif_recv,
+    .get = gnrc_netif2_get_from_netdev,
+    .set = gnrc_netif2_set_from_netdev,
+    .msg_handler = NULL,
+};
+
+static void _set_up(void)
+{
+    msg_t msg;
+
+    if (ethernet_netif != NULL) {
+        memset(ethernet_netif->ipv6.addrs_flags, 0,
+               sizeof(ethernet_netif->ipv6.addrs_flags));
+        memset(ethernet_netif->ipv6.addrs, 0,
+               sizeof(ethernet_netif->ipv6.addrs));
+        memset(ethernet_netif->ipv6.groups, 0,
+               sizeof(ethernet_netif->ipv6.groups));
+    }
+    for (unsigned i = 0; i < DEFAULT_DEVS_NUMOF; i++) {
+        if (netifs[i] != NULL) {
+            memset(netifs[i]->ipv6.addrs_flags, 0,
+                   sizeof(netifs[i]->ipv6.addrs_flags));
+            memset(netifs[i]->ipv6.addrs, 0, sizeof(netifs[i]->ipv6.addrs));
+            memset(netifs[i]->ipv6.groups, 0, sizeof(netifs[i]->ipv6.groups));
+        }
+    }
+    /* empty message queue */
+    while (msg_try_receive(&msg) > 0) {}
+}
+
+static inline void _test_init(gnrc_netif2_t *netif)
+{
+    (void)netif;
+    init_called = true;
+}
+
+static void test_creation(void)
+{
+    char test_stack[4];
+    gnrc_netif2_t *ptr = NULL;
+
+    TEST_ASSERT_EQUAL_INT(0, gnrc_netif2_numof());
+    TEST_ASSERT_NULL(gnrc_netif2_iter(ptr));
+    TEST_ASSERT_NOT_NULL((ethernet_netif = gnrc_netif2_ethernet_create(
+            ethernet_netif_stack, ETHERNET_STACKSIZE, GNRC_NETIF2_PRIO,
+            "eth", ethernet_dev
+        )));
+    TEST_ASSERT_EQUAL_INT(1, gnrc_netif2_numof());
+    TEST_ASSERT_NOT_NULL((ptr = gnrc_netif2_iter(ptr)));
+    TEST_ASSERT_NULL((ptr = gnrc_netif2_iter(ptr)));
+    TEST_ASSERT_NOT_NULL(ethernet_netif->ops);
+    TEST_ASSERT_NOT_NULL(ethernet_netif->dev);
+    TEST_ASSERT_EQUAL_INT(ETHERNET_DATA_LEN, ethernet_netif->ipv6.mtu);
+    TEST_ASSERT_EQUAL_INT(GNRC_NETIF2_DEFAULT_HL, ethernet_netif->cur_hl);
+    TEST_ASSERT_EQUAL_INT(NETDEV_TYPE_ETHERNET, ethernet_netif->device_type);
+    TEST_ASSERT(ethernet_netif->pid > KERNEL_PID_UNDEF);
+#ifdef DEVELHELP
+    TEST_ASSERT_EQUAL_STRING("eth", sched_threads[ethernet_netif->pid]->name);
+#endif
+    TEST_ASSERT_NOT_NULL(sched_threads[ethernet_netif->pid]->msg_array);
+    for (unsigned i = 0; i < DEFAULT_DEVS_NUMOF; i++) {
+        TEST_ASSERT_NOT_NULL((netifs[i] = gnrc_netif2_create(
+                netifs_stack[i], THREAD_STACKSIZE_DEFAULT,
+                GNRC_NETIF2_PRIO, "netif", devs[i], &default_ops
+            )));
+        TEST_ASSERT_NOT_NULL(netifs[i]->ops);
+        TEST_ASSERT_NOT_NULL(netifs[i]->dev);
+        TEST_ASSERT_EQUAL_INT(GNRC_NETIF2_DEFAULT_HL, netifs[i]->cur_hl);
+        TEST_ASSERT_EQUAL_INT(NETDEV_TYPE_UNKNOWN, netifs[i]->device_type);
+        TEST_ASSERT(netifs[i]->pid > KERNEL_PID_UNDEF);
+        TEST_ASSERT_NOT_NULL(sched_threads[netifs[i]->pid]->msg_array);
+        TEST_ASSERT_EQUAL_INT(i + SPECIAL_DEVS + 1, gnrc_netif2_numof());
+        for (unsigned j = 0; j < (i + SPECIAL_DEVS + 1); j++) {
+            TEST_ASSERT_NOT_NULL((ptr = gnrc_netif2_iter(ptr)));
+        }
+        TEST_ASSERT_NULL((ptr = gnrc_netif2_iter(ptr)));
+    }
+    TEST_ASSERT(init_called);
+    TEST_ASSERT_NULL(gnrc_netif2_create(test_stack, 4, GNRC_NETIF2_PRIO,
+                                        "netif", NULL, &default_ops));
+}
+
+static void test_get_by_pid(void)
+{
+    TEST_ASSERT(ethernet_netif == gnrc_netif2_get_by_pid(ethernet_netif->pid));
+    for (kernel_pid_t i = 0; i < DEFAULT_DEVS_NUMOF; i++) {
+        TEST_ASSERT(netifs[i] == gnrc_netif2_get_by_pid(netifs[i]->pid));
+    }
+}
+
+static void test_addr_to_str(void)
+{
+    static const uint8_t ethernet_l2addr[] = ETHERNET_SRC;
+    static const uint8_t netif0_l2addr[] = NETIF0_SRC;
+    char out[sizeof(netif0_l2addr) * 3];
+
+    TEST_ASSERT(out == gnrc_netif2_addr_to_str(NULL, 0, out));
+    TEST_ASSERT_EQUAL_STRING("", &out[0]);
+    TEST_ASSERT(out == gnrc_netif2_addr_to_str(ethernet_l2addr,
+                                               sizeof(ethernet_l2addr), out));
+    TEST_ASSERT_EQUAL_STRING("3e:e6:b5:22:fd:0a", &out[0]);
+    TEST_ASSERT(out == gnrc_netif2_addr_to_str(netif0_l2addr,
+                                               sizeof(netif0_l2addr),
+                                               out));
+    TEST_ASSERT_EQUAL_STRING("3e:e7:b5:0f:19:22:fd:0a", &out[0]);
+}
+
+static void test_addr_from_str(void)
+{
+    static const uint8_t ethernet_l2addr[] = ETHERNET_SRC;
+    uint8_t out[GNRC_NETIF2_L2ADDR_MAXLEN];
+
+    TEST_ASSERT_EQUAL_INT(0, gnrc_netif2_addr_from_str("", out));
+    TEST_ASSERT_EQUAL_INT(sizeof(ethernet_l2addr),
+                          gnrc_netif2_addr_from_str("3e:e6:b5:22:fd:0a", out));
+    TEST_ASSERT_EQUAL_INT(0, memcmp(ethernet_l2addr, out,
+                                    sizeof(ethernet_l2addr)));
+}
+
+static void test_ipv6_addr_add__ENOMEM(void)
+{
+    ipv6_addr_t addr = { .u8 = NETIF0_IPV6_G };
+
+    for (unsigned i = 0; i < GNRC_NETIF2_IPV6_ADDRS_NUMOF;
+         i++, addr.u16[3].u16++) {
+        TEST_ASSERT(0 <= gnrc_netif2_ipv6_addr_add(netifs[0], &addr, 64U,
+                                                   GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_VALID));
+    }
+    TEST_ASSERT_EQUAL_INT(-ENOMEM,
+                          gnrc_netif2_ipv6_addr_add(netifs[0], &addr, 64U,
+                                                    GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_VALID));
+}
+
+static void test_ipv6_addr_add__success(void)
+{
+    static const ipv6_addr_t addr = { .u8 = NETIF0_IPV6_LL };
+    int idx;
+
+    TEST_ASSERT(0 <= (idx = gnrc_netif2_ipv6_addr_add(netifs[0], &addr, 64U,
+                                                      GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_VALID)));
+    /* check duplicate addition */
+    TEST_ASSERT_EQUAL_INT(idx,
+                          gnrc_netif2_ipv6_addr_add(netifs[0], &addr, 64U,
+                                                    GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_VALID));
+    TEST_ASSERT_EQUAL_INT(GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_VALID,
+                          netifs[0]->ipv6.addrs_flags[idx]);
+    TEST_ASSERT(ipv6_addr_equal(&addr, &netifs[0]->ipv6.addrs[idx]));
+}
+
+static void test_ipv6_addr_add__readd_with_free_entry(void)
+{
+    /* Tests for possible duplicates (see #2965) */
+    static const ipv6_addr_t addr1 = { .u8 = NETIF0_IPV6_LL };
+    static const ipv6_addr_t addr2 = { .u8 = NETIF0_IPV6_G };
+    int idx;
+
+    TEST_ASSERT(0 <= gnrc_netif2_ipv6_addr_add(netifs[0], &addr1, 64U,
+                                               GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_VALID));
+    TEST_ASSERT(0 <= (idx = gnrc_netif2_ipv6_addr_add(netifs[0], &addr2, 64U,
+                                                      GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_VALID)));
+    gnrc_netif2_ipv6_addr_remove(netifs[0], &addr1);
+    TEST_ASSERT_EQUAL_INT(idx,
+                          gnrc_netif2_ipv6_addr_add(netifs[0], &addr2, 64U,
+                                                    GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_VALID));
+}
+
+static void test_ipv6_addr_remove__not_allocated(void)
+{
+    static const ipv6_addr_t addr1 = { .u8 = NETIF0_IPV6_LL };
+    static const ipv6_addr_t addr2 = { .u8 = NETIF0_IPV6_G };
+
+    test_ipv6_addr_add__success();
+    TEST_ASSERT(0 <= gnrc_netif2_ipv6_addr_idx(netifs[0], &addr1));
+    TEST_ASSERT(0 <= gnrc_netif2_ipv6_addr_add(netifs[0], &addr2, 64U,
+                                               GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_VALID));
+    gnrc_netif2_ipv6_addr_remove(netifs[0], &addr2);
+    TEST_ASSERT(0 <= gnrc_netif2_ipv6_addr_idx(netifs[0], &addr1));
+}
+
+static void test_ipv6_addr_remove__success(void)
+{
+    static const ipv6_addr_t addr = { .u8 = NETIF0_IPV6_LL };
+
+    test_ipv6_addr_add__success();
+    gnrc_netif2_ipv6_addr_remove(netifs[0], &addr);
+    TEST_ASSERT_EQUAL_INT(-1, gnrc_netif2_ipv6_addr_idx(netifs[0], &addr));
+}
+
+static void test_ipv6_addr_idx__empty(void)
+{
+    static const ipv6_addr_t addr = { .u8 = NETIF0_IPV6_LL };
+
+    TEST_ASSERT_EQUAL_INT(-1, gnrc_netif2_ipv6_addr_idx(netifs[0], &addr));
+}
+
+static void test_ipv6_addr_idx__wrong_netif(void)
+{
+    static const ipv6_addr_t addr = { .u8 = NETIF0_IPV6_LL };
+
+    test_ipv6_addr_add__success();
+    TEST_ASSERT_EQUAL_INT(-1, gnrc_netif2_ipv6_addr_idx(netifs[1], &addr));
+}
+
+static void test_ipv6_addr_idx__wrong_addr(void)
+{
+    static const ipv6_addr_t addr2 = { .u8 = NETIF0_IPV6_G };
+
+    test_ipv6_addr_add__success();
+    TEST_ASSERT_EQUAL_INT(-1, gnrc_netif2_ipv6_addr_idx(netifs[0], &addr2));
+}
+
+static void test_ipv6_addr_idx__success(void)
+{
+    static const ipv6_addr_t addr = { .u8 = NETIF0_IPV6_LL };
+
+    test_ipv6_addr_add__success();
+    TEST_ASSERT(0 <= gnrc_netif2_ipv6_addr_idx(netifs[0], &addr));
+}
+
+static void test_ipv6_addr_match__empty(void)
+{
+    static const ipv6_addr_t addr = { .u8 = NETIF0_IPV6_G };
+
+    TEST_ASSERT_EQUAL_INT(-1, gnrc_netif2_ipv6_addr_match(netifs[0], &addr));
+}
+
+static void test_ipv6_addr_match__wrong_netif(void)
+{
+    static const ipv6_addr_t addr = { .u8 = NETIF0_IPV6_G };
+
+    test_ipv6_addr_add__success();
+    TEST_ASSERT_EQUAL_INT(-1, gnrc_netif2_ipv6_addr_match(netifs[1], &addr));
+}
+
+static void test_ipv6_addr_match__wrong_addr(void)
+{
+    static const ipv6_addr_t addr2 = { .u8 = NETIF0_IPV6_G };
+
+    test_ipv6_addr_add__success();
+    TEST_ASSERT_EQUAL_INT(-1, gnrc_netif2_ipv6_addr_match(netifs[0], &addr2));
+}
+
+static void test_ipv6_addr_match__success18(void)
+{
+    static const ipv6_addr_t addr = { .u8 = NETIF0_IPV6_G };
+
+    static const ipv6_addr_t pfx = { .u8 = GLOBAL_PFX18 };
+    int idx;
+
+    TEST_ASSERT(0 <= (idx = gnrc_netif2_ipv6_addr_add(netifs[0], &addr, 64U,
+                                                      GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_VALID)));
+    TEST_ASSERT_EQUAL_INT(idx, gnrc_netif2_ipv6_addr_match(netifs[0], &pfx));
+    TEST_ASSERT_EQUAL_INT(18, ipv6_addr_match_prefix(&netifs[0]->ipv6.addrs[idx],
+                                                     &pfx));
+}
+
+static void test_ipv6_addr_match__success23(void)
+{
+    static const ipv6_addr_t addr = { .u8 = NETIF0_IPV6_G };
+
+    static const ipv6_addr_t pfx = { .u8 = GLOBAL_PFX23 };
+    int idx;
+
+    TEST_ASSERT(0 <= (idx = gnrc_netif2_ipv6_addr_add(netifs[0], &addr, 64U,
+                                                      GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_VALID)));
+    TEST_ASSERT_EQUAL_INT(idx, gnrc_netif2_ipv6_addr_match(netifs[0], &pfx));
+    TEST_ASSERT_EQUAL_INT(23, ipv6_addr_match_prefix(&netifs[0]->ipv6.addrs[idx],
+                                                     &pfx));
+}
+
+static void test_ipv6_addr_match__success64(void)
+{
+    static const ipv6_addr_t addr = { .u8 = NETIF0_IPV6_G };
+
+    static const ipv6_addr_t pfx = { .u8 = GLOBAL_PFX64 };
+    int idx;
+
+    TEST_ASSERT(0 <= (idx = gnrc_netif2_ipv6_addr_add(netifs[0], &addr, 64U,
+                                                      GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_VALID)));
+    TEST_ASSERT_EQUAL_INT(idx, gnrc_netif2_ipv6_addr_match(netifs[0], &pfx));
+    TEST_ASSERT_EQUAL_INT(64, ipv6_addr_match_prefix(&netifs[0]->ipv6.addrs[idx],
+                                                     &pfx));
+}
+
+static void test_ipv6_addr_best_src__multicast_input(void)
+{
+    static const ipv6_addr_t addr1 = { .u8 = NETIF0_IPV6_G };
+
+    static const ipv6_addr_t addr2 = { .u8 = GLOBAL_PFX18 };
+    ipv6_addr_t *out;
+
+    /* adds a link-local address */
+    test_ipv6_addr_add__success();
+    TEST_ASSERT(0 <= gnrc_netif2_ipv6_addr_add(netifs[0], &addr1, 64U,
+                                               GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_VALID));
+    TEST_ASSERT_NOT_NULL((out = gnrc_netif2_ipv6_addr_best_src(netifs[0],
+                                                               &addr2,
+                                                               false)));
+    TEST_ASSERT(!ipv6_addr_equal(&addr2, out));
+    TEST_ASSERT(ipv6_addr_equal(&addr1, out));
+}
+
+static void test_ipv6_addr_best_src__other_subnet(void)
+{
+    static const ipv6_addr_t mc_addr = IPV6_ADDR_ALL_ROUTERS_SITE_LOCAL;
+    ipv6_addr_t *out = NULL;
+
+    test_ipv6_addr_add__success();
+    TEST_ASSERT_NOT_NULL((out = gnrc_netif2_ipv6_addr_best_src(netifs[0],
+                                                               &mc_addr,
+                                                               false)));
+    TEST_ASSERT(!ipv6_addr_equal(&mc_addr, out));
+    TEST_ASSERT(!ipv6_addr_is_multicast(out));
+    TEST_ASSERT(!ipv6_addr_is_unspecified(out));
+}
+
+static void test_get_by_ipv6_addr__empty(void)
+{
+    static const ipv6_addr_t addr = { .u8 = NETIF0_IPV6_LL };
+
+    TEST_ASSERT_NULL(gnrc_netif2_get_by_ipv6_addr(&addr));
+}
+
+static void test_get_by_ipv6_addr__success(void)
+{
+    static const ipv6_addr_t addr = { .u8 = NETIF0_IPV6_LL };
+
+    test_ipv6_addr_add__success();
+    TEST_ASSERT_NOT_NULL(netifs[0]);
+    TEST_ASSERT(netifs[0] == gnrc_netif2_get_by_ipv6_addr(&addr));
+}
+
+static void test_get_by_prefix__empty(void)
+{
+    static const ipv6_addr_t addr = { .u8 = NETIF0_IPV6_G };
+
+    TEST_ASSERT_NULL(gnrc_netif2_get_by_prefix(&addr));
+}
+
+static void test_get_by_prefix__success18(void)
+{
+    static const ipv6_addr_t addr = { .u8 = NETIF0_IPV6_G };
+    static const ipv6_addr_t pfx = { .u8 = GLOBAL_PFX18 };
+
+    TEST_ASSERT(0 <= gnrc_netif2_ipv6_addr_add(netifs[0], &addr, 64U,
+                                               GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_VALID));
+    TEST_ASSERT_NOT_NULL(netifs[0]);
+    TEST_ASSERT(netifs[0] == gnrc_netif2_get_by_prefix(&pfx));
+    test_ipv6_addr_match__success18();
+}
+
+static void test_get_by_prefix__success23(void)
+{
+    static const ipv6_addr_t addr = { .u8 = NETIF0_IPV6_G };
+    static const ipv6_addr_t pfx = { .u8 = GLOBAL_PFX23 };
+
+    TEST_ASSERT(0 <= gnrc_netif2_ipv6_addr_add(netifs[0], &addr, 64U,
+                                               GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_VALID));
+    TEST_ASSERT_NOT_NULL(netifs[0]);
+    TEST_ASSERT(netifs[0] == gnrc_netif2_get_by_prefix(&pfx));
+    test_ipv6_addr_match__success23();
+}
+
+static void test_get_by_prefix__success64(void)
+{
+    static const ipv6_addr_t addr = { .u8 = NETIF0_IPV6_G };
+    static const ipv6_addr_t pfx = { .u8 = GLOBAL_PFX64 };
+
+    TEST_ASSERT(0 <= gnrc_netif2_ipv6_addr_add(netifs[0], &addr, 64U,
+                                               GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_VALID));
+    TEST_ASSERT_NOT_NULL(netifs[0]);
+    TEST_ASSERT(netifs[0] == gnrc_netif2_get_by_prefix(&pfx));
+    test_ipv6_addr_match__success64();
+}
+
+static void test_ipv6_group_join__ENOMEM(void)
+{
+    ipv6_addr_t addr = IPV6_ADDR_ALL_NODES_LINK_LOCAL;
+
+    for (unsigned i = 0; i < GNRC_NETIF2_IPV6_ADDRS_NUMOF;
+         i++, addr.u16[7].u16++) {
+        TEST_ASSERT(0 <= gnrc_netif2_ipv6_group_join(netifs[0], &addr));
+    }
+    TEST_ASSERT_EQUAL_INT(-ENOMEM,
+                          gnrc_netif2_ipv6_group_join(netifs[0], &addr));
+}
+
+static void test_ipv6_group_join__success(void)
+{
+    int idx;
+
+    TEST_ASSERT(0 <= (idx = gnrc_netif2_ipv6_group_join(netifs[0],
+                                                        &ipv6_addr_all_nodes_link_local)));
+    /* check duplicate addition */
+    TEST_ASSERT_EQUAL_INT(idx,
+                          gnrc_netif2_ipv6_group_join(netifs[0],
+                                                      &ipv6_addr_all_nodes_link_local));
+    TEST_ASSERT(ipv6_addr_equal(&ipv6_addr_all_nodes_link_local,
+                                &netifs[0]->ipv6.groups[idx]));
+}
+
+static void test_ipv6_group_join__readd_with_free_entry(void)
+{
+    /* Tests for possible duplicates (see #2965) */
+    int idx;
+
+    TEST_ASSERT(0 <= gnrc_netif2_ipv6_group_join(netifs[0],
+                                                 &ipv6_addr_all_nodes_link_local));
+    TEST_ASSERT(0 <= (idx = gnrc_netif2_ipv6_group_join(netifs[0],
+                                                        &ipv6_addr_all_routers_link_local)));
+    gnrc_netif2_ipv6_group_leave(netifs[0], &ipv6_addr_all_nodes_link_local);
+    TEST_ASSERT_EQUAL_INT(idx,
+                          gnrc_netif2_ipv6_group_join(netifs[0],
+                                                      &ipv6_addr_all_routers_link_local));
+}
+
+static void test_ipv6_group_leave__not_allocated(void)
+{
+    test_ipv6_group_join__success();
+    TEST_ASSERT(0 <= gnrc_netif2_ipv6_group_idx(netifs[0],
+                                                &ipv6_addr_all_nodes_link_local));
+    TEST_ASSERT(0 <= gnrc_netif2_ipv6_group_join(netifs[0],
+                                                 &ipv6_addr_all_routers_link_local));
+    gnrc_netif2_ipv6_group_leave(netifs[0], &ipv6_addr_all_routers_link_local);
+    TEST_ASSERT(0 <= gnrc_netif2_ipv6_group_idx(netifs[0],
+                                                &ipv6_addr_all_nodes_link_local));
+}
+
+static void test_ipv6_group_leave__success(void)
+{
+    test_ipv6_group_join__success();
+    gnrc_netif2_ipv6_group_leave(netifs[0], &ipv6_addr_all_nodes_link_local);
+    TEST_ASSERT_EQUAL_INT(-1, gnrc_netif2_ipv6_group_idx(netifs[0],
+                                                         &ipv6_addr_all_nodes_link_local));
+}
+
+static void test_ipv6_group_idx__empty(void)
+{
+    TEST_ASSERT_EQUAL_INT(-1, gnrc_netif2_ipv6_group_idx(netifs[0],
+                                                         &ipv6_addr_all_nodes_link_local));
+}
+
+static void test_ipv6_group_idx__wrong_netif(void)
+{
+    test_ipv6_group_join__success();
+    TEST_ASSERT_EQUAL_INT(-1, gnrc_netif2_ipv6_group_idx(netifs[1],
+                                                         &ipv6_addr_all_nodes_link_local));
+}
+
+static void test_ipv6_group_idx__wrong_addr(void)
+{
+    test_ipv6_group_join__success();
+    TEST_ASSERT_EQUAL_INT(-1, gnrc_netif2_ipv6_group_idx(netifs[0],
+                                                         &ipv6_addr_all_routers_link_local));
+}
+
+static void test_ipv6_group_idx__success(void)
+{
+    test_ipv6_group_join__success();
+    TEST_ASSERT(0 <= gnrc_netif2_ipv6_group_idx(netifs[0], &ipv6_addr_all_nodes_link_local));
+}
+
+static void test_ipv6_get_iid(void)
+{
+    static const ipv6_addr_t ethernet_ipv6_ll = { .u8 = ETHERNET_IPV6_LL };
+    eui64_t res;
+
+    TEST_ASSERT_EQUAL_INT(0, gnrc_netif2_ipv6_get_iid(ethernet_netif, &res));
+    TEST_ASSERT_EQUAL_INT(0, memcmp(&res, &ethernet_ipv6_ll.u64[1],
+                                    sizeof(res)));
+    for (unsigned i = 0; i < DEFAULT_DEVS_NUMOF; i++) {
+        TEST_ASSERT_EQUAL_INT(-ENOTSUP, gnrc_netif2_ipv6_get_iid(netifs[i], &res));
+    }
+}
+
+static void test_netapi_get__HOP_LIMIT(void)
+{
+    uint8_t value;
+
+    TEST_ASSERT_EQUAL_INT(sizeof(value),
+                          gnrc_netapi_get(netifs[0]->pid, NETOPT_HOP_LIMIT,
+                                          0, &value, sizeof(value)));
+    TEST_ASSERT_EQUAL_INT(netifs[0]->cur_hl, value);
+}
+
+static void test_netapi_get__IPV6_ADDR(void)
+{
+    static const ipv6_addr_t exp = { NETIF0_IPV6_LL };
+    ipv6_addr_t value[GNRC_NETIF2_IPV6_ADDRS_NUMOF];
+
+    test_ipv6_addr_add__success();
+    TEST_ASSERT_EQUAL_INT(sizeof(ipv6_addr_t), gnrc_netapi_get(netifs[0]->pid,
+                                                               NETOPT_IPV6_ADDR,
+                                                               0, &value,
+                                                               sizeof(value)));
+    TEST_ASSERT(ipv6_addr_equal(&exp, &value[0]));
+}
+
+static void test_netapi_get__IPV6_ADDR_FLAGS(void)
+{
+    uint8_t value[GNRC_NETIF2_IPV6_ADDRS_NUMOF];
+
+    test_ipv6_addr_add__success();
+    TEST_ASSERT_EQUAL_INT(sizeof(uint8_t), gnrc_netapi_get(netifs[0]->pid,
+                                                           NETOPT_IPV6_ADDR_FLAGS,
+                                                           0, &value,
+                                                           sizeof(value)));
+    TEST_ASSERT_EQUAL_INT(GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_VALID,
+                          value[0]);
+}
+
+static void test_netapi_get__IPV6_GROUP(void)
+{
+    ipv6_addr_t value[GNRC_NETIF2_IPV6_GROUPS_NUMOF];
+
+    test_ipv6_group_join__success();
+    TEST_ASSERT_EQUAL_INT(sizeof(ipv6_addr_t), gnrc_netapi_get(netifs[0]->pid,
+                                                               NETOPT_IPV6_GROUP,
+                                                               0, &value,
+                                                               sizeof(value)));
+    TEST_ASSERT(ipv6_addr_equal(&ipv6_addr_all_nodes_link_local, &value[0]));
+}
+
+static void test_netapi_get__IPV6_IID(void)
+{
+    static const ipv6_addr_t ethernet_ipv6_ll = { .u8 = ETHERNET_IPV6_LL };
+    eui64_t value;
+
+    TEST_ASSERT_EQUAL_INT(sizeof(eui64_t), gnrc_netapi_get(ethernet_netif->pid,
+                                                           NETOPT_IPV6_IID,
+                                                           0, &value, sizeof(value)));
+    TEST_ASSERT_EQUAL_INT(0, memcmp(&value, &ethernet_ipv6_ll.u64[1],
+                                    sizeof(value)));
+    TEST_ASSERT_EQUAL_INT(-ENOTSUP, gnrc_netapi_get(netifs[0]->pid,
+                                                    NETOPT_IPV6_IID,
+                                                    0, &value, sizeof(value)));
+}
+
+static void test_netapi_get__MAX_PACKET_SIZE(void)
+{
+    uint16_t value;
+
+    TEST_ASSERT_EQUAL_INT(sizeof(uint16_t), gnrc_netapi_get(ethernet_netif->pid,
+                                                            NETOPT_MAX_PACKET_SIZE,
+                                                            GNRC_NETTYPE_IPV6,
+                                                            &value, sizeof(value)));
+    TEST_ASSERT_EQUAL_INT(ETHERNET_DATA_LEN, value);
+    TEST_ASSERT_EQUAL_INT(sizeof(uint16_t), gnrc_netapi_get(ethernet_netif->pid,
+                                                            NETOPT_MAX_PACKET_SIZE,
+                                                            GNRC_NETTYPE_NETIF,
+                                                            &value, sizeof(value)));
+    TEST_ASSERT_EQUAL_INT(ETHERNET_DATA_LEN, value);
+    TEST_ASSERT_EQUAL_INT(sizeof(uint16_t), gnrc_netapi_get(netifs[0]->pid,
+                                                            NETOPT_MAX_PACKET_SIZE,
+                                                            GNRC_NETTYPE_IPV6,
+                                                            &value, sizeof(value)));
+    TEST_ASSERT_EQUAL_INT(IPV6_MIN_MTU, value);
+    TEST_ASSERT_EQUAL_INT(sizeof(uint16_t), gnrc_netapi_get(netifs[0]->pid,
+                                                            NETOPT_MAX_PACKET_SIZE,
+                                                            GNRC_NETTYPE_NETIF,
+                                                            &value, sizeof(value)));
+    TEST_ASSERT_EQUAL_INT(IPV6_MIN_MTU, value);
+}
+
+static void test_netapi_get__6LO_IPHC(void)
+{
+    netopt_enable_t value;
+
+    TEST_ASSERT_EQUAL_INT(sizeof(netopt_enable_t),
+                          gnrc_netapi_get(ethernet_netif->pid,
+                                          NETOPT_6LO_IPHC, 0,
+                                          &value, sizeof(value)));
+    TEST_ASSERT_EQUAL_INT(NETOPT_DISABLE, value);
+    TEST_ASSERT_EQUAL_INT(sizeof(netopt_enable_t),
+                          gnrc_netapi_get(netifs[0]->pid,
+                                          NETOPT_6LO_IPHC, 0,
+                                          &value, sizeof(value)));
+    TEST_ASSERT_EQUAL_INT(NETOPT_DISABLE, value);
+}
+
+static void test_netapi_get__ADDRESS(void)
+{
+    static const uint8_t exp_ethernet[] = ETHERNET_SRC;
+    uint8_t value[GNRC_NETIF2_L2ADDR_MAXLEN];
+
+    TEST_ASSERT_EQUAL_INT(sizeof(exp_ethernet),
+                          gnrc_netapi_get(ethernet_netif->pid,
+                                          NETOPT_ADDRESS, 0,
+                                          &value, sizeof(value)));
+    TEST_ASSERT_EQUAL_INT(0, memcmp(exp_ethernet, value, sizeof(exp_ethernet)));
+}
+
+static void test_netapi_get__ADDRESS_LONG(void)
+{
+    uint8_t value[GNRC_NETIF2_L2ADDR_MAXLEN];
+
+    TEST_ASSERT_EQUAL_INT(-ENOTSUP,
+                          gnrc_netapi_get(ethernet_netif->pid,
+                                          NETOPT_ADDRESS_LONG, 0,
+                                          &value, sizeof(value)));
+    TEST_ASSERT_EQUAL_INT(-ENOTSUP,
+                          gnrc_netapi_get(netifs[0]->pid,
+                                          NETOPT_ADDRESS_LONG, 0,
+                                          &value, sizeof(value)));
+}
+
+static void test_netapi_set__HOP_LIMIT(void)
+{
+    uint8_t value = 89;
+
+    TEST_ASSERT_EQUAL_INT(sizeof(value),
+                          gnrc_netapi_set(netifs[0]->pid,
+                                          NETOPT_HOP_LIMIT, 0,
+                                          &value, sizeof(value)));
+    TEST_ASSERT_EQUAL_INT(value, netifs[0]->cur_hl);
+}
+
+static void test_netapi_set__IPV6_ADDR(void)
+{
+    ipv6_addr_t value = { .u8 = NETIF0_IPV6_LL };
+    static const uint16_t context = (64U << 8) |
+                                    (GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_VALID);
+
+    TEST_ASSERT(0 > gnrc_netif2_ipv6_addr_idx(netifs[0], &value));
+    TEST_ASSERT_EQUAL_INT(sizeof(value),
+                          gnrc_netapi_set(netifs[0]->pid,
+                                          NETOPT_IPV6_ADDR, context,
+                                          &value, sizeof(value)));
+    TEST_ASSERT(0 <= gnrc_netif2_ipv6_addr_idx(netifs[0], &value));
+}
+
+static void test_netapi_set__IPV6_ADDR_REMOVE(void)
+{
+    ipv6_addr_t value = { .u8 = NETIF0_IPV6_LL };
+
+    test_ipv6_addr_add__success();
+    TEST_ASSERT(0 <= gnrc_netif2_ipv6_addr_idx(netifs[0], &value));
+    TEST_ASSERT_EQUAL_INT(sizeof(value),
+                          gnrc_netapi_set(netifs[0]->pid,
+                                          NETOPT_IPV6_ADDR_REMOVE, 0,
+                                          &value, sizeof(value)));
+    TEST_ASSERT(0 > gnrc_netif2_ipv6_addr_idx(netifs[0], &value));
+}
+
+static void test_netapi_set__IPV6_GROUP(void)
+{
+    ipv6_addr_t value = IPV6_ADDR_ALL_NODES_LINK_LOCAL;
+
+    TEST_ASSERT(0 > gnrc_netif2_ipv6_group_idx(netifs[0], &value));
+    TEST_ASSERT_EQUAL_INT(sizeof(value),
+                          gnrc_netapi_set(netifs[0]->pid,
+                                          NETOPT_IPV6_GROUP, 0,
+                                          &value, sizeof(value)));
+    TEST_ASSERT(0 <= gnrc_netif2_ipv6_group_idx(netifs[0], &value));
+}
+
+static void test_netapi_set__IPV6_GROUP_LEAVE(void)
+{
+    ipv6_addr_t value = IPV6_ADDR_ALL_NODES_LINK_LOCAL;
+
+    test_ipv6_group_join__success();
+    TEST_ASSERT(0 <= gnrc_netif2_ipv6_group_idx(netifs[0], &value));
+    TEST_ASSERT_EQUAL_INT(sizeof(value),
+                          gnrc_netapi_set(netifs[0]->pid,
+                                          NETOPT_IPV6_GROUP_LEAVE, 0,
+                                          &value, sizeof(value)));
+    TEST_ASSERT(0 > gnrc_netif2_ipv6_group_idx(netifs[0], &value));
+}
+
+static void test_netapi_set__MAX_PACKET_SIZE(void)
+{
+    uint16_t value = 57194;
+
+    TEST_ASSERT_EQUAL_INT(sizeof(value),
+                          gnrc_netapi_set(netifs[0]->pid,
+                                          NETOPT_MAX_PACKET_SIZE,
+                                          GNRC_NETTYPE_IPV6,
+                                          &value, sizeof(value)));
+    TEST_ASSERT_EQUAL_INT(value, netifs[0]->ipv6.mtu);
+    TEST_ASSERT_EQUAL_INT(-ENOTSUP,
+                          gnrc_netapi_set(netifs[0]->pid,
+                                          NETOPT_MAX_PACKET_SIZE, 0,
+                                          &value, sizeof(value)));
+}
+
+static void test_netapi_set__6LO_IPHC(void)
+{
+    netopt_enable_t value = NETOPT_ENABLE;
+
+    TEST_ASSERT_EQUAL_INT(sizeof(value),
+                          gnrc_netapi_set(netifs[0]->pid,
+                                          NETOPT_6LO_IPHC, 0,
+                                          &value, sizeof(value)));
+    TEST_ASSERT(netifs[0]->flags & GNRC_NETIF2_FLAGS_6LO_HC);
+}
+
+static void test_netapi_set__ADDRESS(void)
+{
+    static const uint8_t exp_ethernet[] = ETHERNET_SRC;
+    uint8_t value[] = { LA1 + 1, LA2 + 2, LA3 + 3, LA4 + 4, LA5 + 5, LA6 + 6 };
+
+    TEST_ASSERT_EQUAL_INT(sizeof(exp_ethernet),
+                          gnrc_netapi_set(ethernet_netif->pid,
+                                          NETOPT_ADDRESS, 0,
+                                          &value, sizeof(value)));
+    TEST_ASSERT_EQUAL_INT(sizeof(value), ethernet_netif->l2addr_len);
+    TEST_ASSERT_EQUAL_INT(0, memcmp(value, ethernet_netif->l2addr,
+                                    sizeof(value)));
+    TEST_ASSERT_EQUAL_INT(-ENOTSUP,
+                          gnrc_netapi_set(netifs[0]->pid,
+                                          NETOPT_ADDRESS_LONG, 0,
+                                          &value, sizeof(value)));
+    /* return addresses to previous state for further testing */
+    memcpy(value, exp_ethernet, sizeof(exp_ethernet));
+    TEST_ASSERT_EQUAL_INT(sizeof(exp_ethernet),
+                          gnrc_netapi_set(ethernet_netif->pid,
+                                          NETOPT_ADDRESS, 0,
+                                          &value, sizeof(value)));
+    TEST_ASSERT_EQUAL_INT(sizeof(value), ethernet_netif->l2addr_len);
+    TEST_ASSERT_EQUAL_INT(0, memcmp(value, ethernet_netif->l2addr,
+                                    sizeof(value)));
+}
+
+static void test_netapi_set__ADDRESS_LONG(void)
+{
+    uint8_t value[GNRC_NETIF2_L2ADDR_MAXLEN];
+
+    TEST_ASSERT_EQUAL_INT(-ENOTSUP,
+                          gnrc_netapi_set(ethernet_netif->pid,
+                                          NETOPT_ADDRESS_LONG, 0,
+                                          &value, sizeof(value)));
+    TEST_ASSERT_EQUAL_INT(-ENOTSUP,
+                          gnrc_netapi_set(netifs[0]->pid,
+                                          NETOPT_ADDRESS_LONG, 0,
+                                          &value, sizeof(value)));
+}
+
+static void test_netapi_send__raw_unicast_ethernet_packet(void)
+{
+    uint8_t dst[] = { LA1, LA2, LA3, LA4, LA5, LA6 + 1 };
+    gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(NULL, "ABCDEFG",
+                                          sizeof("ABCDEFG"),
+                                          GNRC_NETTYPE_UNDEF);
+    TEST_ASSERT_NOT_NULL(pkt);
+    gnrc_pktsnip_t *netif = gnrc_netif_hdr_build(NULL, 0, dst, sizeof(dst));
+    TEST_ASSERT_NOT_NULL(netif);
+    LL_PREPEND(pkt, netif);
+    gnrc_netapi_send(ethernet_netif->pid, pkt);
+}
+
+static void test_netapi_send__raw_broadcast_ethernet_packet(void)
+{
+    gnrc_netif_hdr_t *hdr;
+    gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(NULL, "ABCDEFG",
+                                          sizeof("ABCDEFG"),
+                                          GNRC_NETTYPE_UNDEF);
+    TEST_ASSERT_NOT_NULL(pkt);
+    gnrc_pktsnip_t *netif = gnrc_netif_hdr_build(NULL, 0, NULL, 0);
+    TEST_ASSERT_NOT_NULL(netif);
+    hdr = netif->data;
+    hdr->flags |= GNRC_NETIF_HDR_FLAGS_BROADCAST;
+    LL_PREPEND(pkt, netif);
+    gnrc_netapi_send(ethernet_netif->pid, pkt);
+}
+
+static void test_netapi_send__ipv6_unicast_ethernet_packet(void)
+{
+    ipv6_hdr_t *ipv6_hdr;
+    uint8_t dst_netif[] = { LA1, LA2, LA3, LA4, LA5, LA6 + 1 };
+    static const ipv6_addr_t dst_ipv6 = { .u8 = { LP1, LP2, LP3, LP4,
+                                                  LP5, LP6, LP7, LP8,
+                                                  LA1 ^ 0x2, LA2, LA3, 0xff,
+                                                  0xfe, LA4, LA5, LA6 + 1} };
+    static const ipv6_addr_t src_ipv6 = { .u8 = ETHERNET_IPV6_LL };
+    gnrc_pktsnip_t *payload = gnrc_pktbuf_add(NULL, "ABCDEFG",
+                                          sizeof("ABCDEFG"),
+                                          GNRC_NETTYPE_UNDEF);
+    TEST_ASSERT_NOT_NULL(payload);
+    /* we don't send through gnrc_ipv6 (because we are lazy and don't want
+     * to update the neighbor cache ;-)) so we need to set the IPv6 source
+     * address */
+    gnrc_pktsnip_t *pkt = gnrc_ipv6_hdr_build(payload, &src_ipv6, &dst_ipv6);
+    TEST_ASSERT_NOT_NULL(pkt);
+    ipv6_hdr = pkt->data;
+    ipv6_hdr->len = byteorder_htons(sizeof("ABCDEFG"));
+    ipv6_hdr->nh = PROTNUM_IPV6_NONXT;
+    ipv6_hdr->hl = ethernet_netif->cur_hl;
+    gnrc_pktsnip_t *netif = gnrc_netif_hdr_build(NULL, 0, dst_netif,
+                                                 sizeof(dst_netif));
+    TEST_ASSERT_NOT_NULL(netif);
+    LL_PREPEND(pkt, netif);
+    gnrc_netapi_send(ethernet_netif->pid, pkt);
+}
+
+static void test_netapi_send__ipv6_multicast_ethernet_packet(void)
+{
+    ipv6_hdr_t *ipv6_hdr;
+    gnrc_netif_hdr_t *netif_hdr;
+    static const ipv6_addr_t src_ipv6 = { .u8 = ETHERNET_IPV6_LL };
+    gnrc_pktsnip_t *payload = gnrc_pktbuf_add(NULL, "ABCDEFG",
+                                          sizeof("ABCDEFG"),
+                                          GNRC_NETTYPE_UNDEF);
+    TEST_ASSERT_NOT_NULL(payload);
+    /* we don't send through gnrc_ipv6 (because we are lazy and don't want
+     * to update the neighbor cache ;-)) so we need to set the IPv6 source
+     * address */
+    gnrc_pktsnip_t *pkt = gnrc_ipv6_hdr_build(payload, &src_ipv6,
+                                              &ipv6_addr_all_nodes_link_local);
+    TEST_ASSERT_NOT_NULL(pkt);
+    ipv6_hdr = pkt->data;
+    ipv6_hdr->len = byteorder_htons(sizeof("ABCDEFG"));
+    ipv6_hdr->nh = PROTNUM_IPV6_NONXT;
+    ipv6_hdr->hl = ethernet_netif->cur_hl;
+    gnrc_pktsnip_t *netif = gnrc_netif_hdr_build(NULL, 0, NULL, 0);
+    TEST_ASSERT_NOT_NULL(netif);
+    netif_hdr = netif->data;
+    netif_hdr->flags |= GNRC_NETIF_HDR_FLAGS_MULTICAST;
+    LL_PREPEND(pkt, netif);
+    gnrc_netapi_send(ethernet_netif->pid, pkt);
+}
+
+static void test_netapi_recv__empty_ethernet_payload(void)
+{
+    static const uint8_t data[] = { LA1, LA2, LA3, LA6, LA7, LA8,
+                                    LA1, LA2, LA3, LA6, LA7, LA8 + 1,
+                                    0xff, 0xff };
+
+    puts("pktdump dumping Ethernet packet with empty payload");
+    _test_trigger_recv(ethernet_netif, data, sizeof(data));
+}
+
+static void test_netapi_recv__raw_ethernet_payload(void)
+{
+    static const uint8_t data[] = { LA1, LA2, LA3, LA6, LA7, LA8,
+                                    LA1, LA2, LA3, LA6, LA7, LA8 + 1,
+                                    0xff, 0xff, 0x12, 0x34, 0x45, 0x56 };
+
+    puts("pktdump dumping Ethernet packet with payload 12 34 45 56");
+    _test_trigger_recv(ethernet_netif, data, sizeof(data));
+}
+
+static void test_netapi_recv__ipv6_ethernet_payload(void)
+{
+    static const uint8_t data[] = { LA1, LA2, LA3, LA6, LA7, LA8,
+                                    LA1, LA2, LA3, LA6, LA7, LA8 + 1,
+                                    0x86, 0xdd, /* Ethertype: IPv6 */
+                                    0x60, 0, 0, 0,  /* Version + TC + FL */
+                                    0, 1, /* payload length 1 */
+                                    59, /* next header: no next header */
+                                    64, /* hop limit */
+                                    /* IPv6 source */
+                                    LP1, LP2, LP3, LP4, LP5, LP6, LP7, LP8,
+                                    LA1 ^ 1, LA2, LA3, 0xff, 0xfe, LA6, LA7, LA8,
+                                    /* IPv6 destination */
+                                    LP1, LP2, LP3, LP4, LP5, LP6, LP7, LP8,
+                                    LA1 ^ 1, LA2, LA3, 0xff, 0xfe, LA6, LA7, LA8 + 1,
+                                    0x01 /* payload */
+                                  };
+
+    puts("pktdump dumping IPv6 over Ethernet packet with payload 01");
+    _test_trigger_recv(ethernet_netif, data, sizeof(data));
+}
+
+static Test *embunit_tests_gnrc_netif2(void)
+{
+    EMB_UNIT_TESTFIXTURES(fixtures) {
+        new_TestFixture(test_creation),
+        new_TestFixture(test_get_by_pid),
+        new_TestFixture(test_addr_to_str),
+        new_TestFixture(test_addr_from_str),
+        new_TestFixture(test_ipv6_addr_add__ENOMEM),
+        new_TestFixture(test_ipv6_addr_add__success),
+        new_TestFixture(test_ipv6_addr_add__readd_with_free_entry),
+        new_TestFixture(test_ipv6_addr_remove__not_allocated),
+        new_TestFixture(test_ipv6_addr_remove__success),
+        new_TestFixture(test_ipv6_addr_idx__empty),
+        new_TestFixture(test_ipv6_addr_idx__wrong_netif),
+        new_TestFixture(test_ipv6_addr_idx__wrong_addr),
+        new_TestFixture(test_ipv6_addr_idx__success),
+        new_TestFixture(test_ipv6_addr_match__empty),
+        new_TestFixture(test_ipv6_addr_match__wrong_netif),
+        new_TestFixture(test_ipv6_addr_match__wrong_addr),
+        new_TestFixture(test_ipv6_addr_match__success18),
+        new_TestFixture(test_ipv6_addr_match__success23),
+        new_TestFixture(test_ipv6_addr_match__success64),
+        new_TestFixture(test_ipv6_addr_best_src__multicast_input),
+        new_TestFixture(test_ipv6_addr_best_src__other_subnet),
+        new_TestFixture(test_get_by_ipv6_addr__empty),
+        new_TestFixture(test_get_by_ipv6_addr__success),
+        new_TestFixture(test_get_by_prefix__empty),
+        new_TestFixture(test_get_by_prefix__success18),
+        new_TestFixture(test_get_by_prefix__success23),
+        new_TestFixture(test_get_by_prefix__success64),
+        new_TestFixture(test_ipv6_group_join__ENOMEM),
+        new_TestFixture(test_ipv6_group_join__success),
+        new_TestFixture(test_ipv6_group_join__readd_with_free_entry),
+        new_TestFixture(test_ipv6_group_leave__not_allocated),
+        new_TestFixture(test_ipv6_group_leave__success),
+        new_TestFixture(test_ipv6_group_idx__empty),
+        new_TestFixture(test_ipv6_group_idx__wrong_netif),
+        new_TestFixture(test_ipv6_group_idx__wrong_addr),
+        new_TestFixture(test_ipv6_group_idx__success),
+        new_TestFixture(test_ipv6_get_iid),
+        new_TestFixture(test_netapi_get__HOP_LIMIT),
+        new_TestFixture(test_netapi_get__IPV6_ADDR),
+        new_TestFixture(test_netapi_get__IPV6_ADDR_FLAGS),
+        new_TestFixture(test_netapi_get__IPV6_GROUP),
+        new_TestFixture(test_netapi_get__IPV6_IID),
+        new_TestFixture(test_netapi_get__MAX_PACKET_SIZE),
+        new_TestFixture(test_netapi_get__6LO_IPHC),
+        new_TestFixture(test_netapi_get__ADDRESS),
+        new_TestFixture(test_netapi_get__ADDRESS_LONG),
+        new_TestFixture(test_netapi_set__HOP_LIMIT),
+        new_TestFixture(test_netapi_set__IPV6_ADDR),
+        new_TestFixture(test_netapi_set__IPV6_ADDR_REMOVE),
+        new_TestFixture(test_netapi_set__IPV6_GROUP),
+        new_TestFixture(test_netapi_set__IPV6_GROUP_LEAVE),
+        new_TestFixture(test_netapi_set__MAX_PACKET_SIZE),
+        new_TestFixture(test_netapi_set__6LO_IPHC),
+        new_TestFixture(test_netapi_set__ADDRESS),
+        new_TestFixture(test_netapi_set__ADDRESS_LONG),
+        /* only add tests not involving output here */
+    };
+    EMB_UNIT_TESTCALLER(tests, _set_up, NULL, fixtures);
+
+    return (Test *)&tests;
+}
+
+int main(void)
+{
+    _tests_init();
+    netdev_test_set_get_cb((netdev_test_t *)ethernet_dev, NETOPT_ADDRESS,
+                           _get_netdev_address);
+    netdev_test_set_set_cb((netdev_test_t *)ethernet_dev, NETOPT_ADDRESS,
+                           _set_netdev_address);
+    TESTS_START();
+    TESTS_RUN(embunit_tests_gnrc_netif2());
+    TESTS_END();
+    /* add netapi send and receive tests here */
+    test_netapi_send__raw_unicast_ethernet_packet();
+    test_netapi_send__raw_broadcast_ethernet_packet();
+    test_netapi_send__ipv6_unicast_ethernet_packet();
+    test_netapi_send__ipv6_multicast_ethernet_packet();
+    test_netapi_recv__empty_ethernet_payload();
+    test_netapi_recv__raw_ethernet_payload();
+    test_netapi_recv__ipv6_ethernet_payload();
+    return 0;
+}
+
+static inline int _mock_netif_send(gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt)
+{
+    (void)netif;
+    (void)pkt;
+    return -1;
+}
+
+static inline gnrc_pktsnip_t *_mock_netif_recv(gnrc_netif2_t * netif)
+{
+    (void)netif;
+    return NULL;
+}
+
+static uint8_t ethernet_l2addr[] = ETHERNET_SRC;
+
+static int _get_netdev_address(netdev_t *dev, void *value, size_t max_len)
+{
+    if (dev == ethernet_dev) {
+        assert(max_len >= sizeof(ethernet_l2addr));
+        memcpy(value, ethernet_l2addr, sizeof(ethernet_l2addr));
+        return sizeof(ethernet_l2addr);
+    }
+    return -ENOTSUP;
+}
+
+static int _set_netdev_address(netdev_t *dev, const void *value, size_t value_len)
+{
+    if (dev == ethernet_dev) {
+        assert(value_len <= sizeof(ethernet_l2addr));
+        memcpy(ethernet_l2addr, value, value_len);
+        return value_len;
+    }
+    return -ENOTSUP;
+}
diff --git a/tests/gnrc_netif2/tests/01-run.py b/tests/gnrc_netif2/tests/01-run.py
new file mode 100755
index 0000000000..584bf4465b
--- /dev/null
+++ b/tests/gnrc_netif2/tests/01-run.py
@@ -0,0 +1,82 @@
+#!/usr/bin/env python3
+
+# Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
+# Copyright (C) 2016 Takuo Yonezawa <Yonezawa-T2@mail.dnp.co.jp>
+#
+# 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
+
+sys.path.append(os.path.join(os.environ['RIOTBASE'], 'dist/tools/testrunner'))
+import testrunner
+
+def testfunc(child):
+    # embUnit tests
+    child.expect(r"OK \(\d+ tests\)")
+    # output cross-checked hex data with WireShark -> "Import from Hex Dump..."
+    # test_netapi_send__raw_unicast_ethernet_packet
+    child.expect("Sending data from Ethernet device:")
+    child.expect("00000000  3E  E6  B5  0F  19  23  3E  E6  B5  22  FD  0A  " +
+                           "FF  FF  41  42")
+    child.expect("00000010  43  44  45  46  47  00")
+    # test_netapi_send__raw_broadcast_ethernet_packet
+    child.expect("Sending data from Ethernet device:")
+    child.expect("00000000  FF  FF  FF  FF  FF  FF  3E  E6  B5  22  FD  0A  " +
+                           "FF  FF  41  42")
+    child.expect("00000010  43  44  45  46  47  00")
+    # test_netapi_send__ipv6_unicast_ethernet_packet
+    child.expect("Sending data from Ethernet device:")
+    child.expect("00000000  3E  E6  B5  0F  19  23  3E  E6  B5  22  FD  0A  86  DD  60  00")
+    child.expect("00000010  00  00  00  08  3B  40  FE  80  00  00  00  00  00  00  3C  E6")
+    child.expect("00000020  B5  FF  FE  22  FD  0A  FE  80  00  00  00  00  00  00  3C  E6")
+    child.expect("00000030  B5  FF  FE  0F  19  23  41  42  43  44  45  46  47  00")
+    # test_netapi_send__ipv6_multicast_ethernet_packet
+    child.expect("Sending data from Ethernet device:")
+    child.expect("00000000  33  33  00  00  00  01  3E  E6  B5  22  FD  0A  86  DD  60  00")
+    child.expect("00000010  00  00  00  08  3B  40  FE  80  00  00  00  00  00  00  3C  E6")
+    child.expect("00000020  B5  FF  FE  22  FD  0A  FF  02  00  00  00  00  00  00  00  00")
+    child.expect("00000030  00  00  00  00  00  01  41  42  43  44  45  46  47  00")
+    # test_netapi_recv__empty_ethernet_payload
+    child.expect("pktdump dumping Ethernet packet with empty payload")
+    child.expect("PKTDUMP: data received:")
+    child.expect(r"~~ SNIP  0 - size:   0 byte, type: NETTYPE_UNDEF \(0\)")
+    child.expect(r"00000000~~ SNIP  1 - size:  20 byte, type: NETTYPE_NETIF \(-1\)")
+    child.expect(r"if_pid: \d+  rssi: 0  lqi: 0")
+    child.expect("flags: 0x0")
+    child.expect("src_l2addr: 3e:e6:b5:22:fd:0b")
+    child.expect("dst_l2addr: 3e:e6:b5:22:fd:0a")
+    child.expect("~~ PKT    -  2 snips, total size:  20 byte")
+    # test_netapi_recv__raw_ethernet_payload
+    child.expect("pktdump dumping Ethernet packet with payload 12 34 45 56")
+    child.expect("PKTDUMP: data received:")
+    child.expect(r"~~ SNIP  0 - size:   4 byte, type: NETTYPE_UNDEF \(0\)")
+    child.expect("00000000  12  34  45  56")
+    child.expect(r"~~ SNIP  1 - size:  20 byte, type: NETTYPE_NETIF \(-1\)")
+    child.expect(r"if_pid: \d+  rssi: 0  lqi: 0")
+    child.expect("flags: 0x0")
+    child.expect("src_l2addr: 3e:e6:b5:22:fd:0b")
+    child.expect("dst_l2addr: 3e:e6:b5:22:fd:0a")
+    child.expect("~~ PKT    -  2 snips, total size:  24 byte")
+    # test_netapi_recv__ipv6_ethernet_payload
+    child.expect("pktdump dumping IPv6 over Ethernet packet with payload 01")
+    child.expect("PKTDUMP: data received:")
+    # payload not dumped because not parsed yet, but header looks okay, so let's
+    # assume the payload is as well
+    child.expect(r"~~ SNIP  0 - size:  41 byte, type: NETTYPE_IPV6 \(2\)")
+    child.expect(r"traffic class: 0x00 \(ECN: 0x0, DSCP: 0x00\)")
+    child.expect("flow label: 0x00000")
+    child.expect("length: 1  next header: 59  hop limit: 64")
+    child.expect("source address: fe80::3fe6:b5ff:fe22:fd0a")
+    child.expect("destination address: fe80::3fe6:b5ff:fe22:fd0b")
+    child.expect(r"~~ SNIP  1 - size:  20 byte, type: NETTYPE_NETIF \(-1\)")
+    child.expect(r"if_pid: \d+  rssi: 0  lqi: 0")
+    child.expect("flags: 0x0")
+    child.expect("src_l2addr: 3e:e6:b5:22:fd:0b")
+    child.expect("dst_l2addr: 3e:e6:b5:22:fd:0a")
+    child.expect("~~ PKT    -  2 snips, total size:  61 byte")
+
+if __name__ == "__main__":
+    sys.exit(testrunner.run(testfunc, timeout=1, traceback=True))
-- 
GitLab