From 54a2889614bc2f5121cf506a95e6c6f66e6f51a4 Mon Sep 17 00:00:00 2001 From: Yasuyuki Tanaka Date: Wed, 29 Aug 2018 14:20:08 +0200 Subject: [PATCH] test/10-ipv6-nbr: add 01-test-nbr-multi-addrs --- .travis.yml | 1 + tests/10-ipv6-nbr/01-test-nbr-multi-addrs.sh | 21 ++ tests/10-ipv6-nbr/Makefile | 1 + tests/10-ipv6-nbr/nbr-multi-addrs/Makefile | 14 + tests/10-ipv6-nbr/nbr-multi-addrs/test.c | 260 +++++++++++++++++++ 5 files changed, 297 insertions(+) create mode 100755 tests/10-ipv6-nbr/01-test-nbr-multi-addrs.sh create mode 100644 tests/10-ipv6-nbr/Makefile create mode 100644 tests/10-ipv6-nbr/nbr-multi-addrs/Makefile create mode 100644 tests/10-ipv6-nbr/nbr-multi-addrs/test.c diff --git a/.travis.yml b/.travis.yml index 60d8db747..d9c98d75d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -68,3 +68,4 @@ env: - TEST_NAME='compile-tools' - TEST_NAME='native-runs' - TEST_NAME='ipv6' BUILD_COOJA=true + - TEST_NAME='ipv6-nbr' BUILD_COOJA=true diff --git a/tests/10-ipv6-nbr/01-test-nbr-multi-addrs.sh b/tests/10-ipv6-nbr/01-test-nbr-multi-addrs.sh new file mode 100755 index 000000000..8f73ee237 --- /dev/null +++ b/tests/10-ipv6-nbr/01-test-nbr-multi-addrs.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +TEST_NAME=01-test-nbr-multi-addrs + +if [ $# -eq 1 ]; then + # a (relative) path to CONTIKI_DIR is supposed to be given as $1 + TEST_DIR=$1/tests/10-ipv6-nbr +else + TEST_DIR=.//tests/10-ipv6-nbr +fi +SRC_DIR=${TEST_DIR}/nbr-multi-addrs +EXEC_FILE_NAME=test.native + +make -C ${SRC_DIR} clean + +echo "build the test program"... +make -C ${SRC_DIR} > ${TEST_NAME}.log + +echo "run the test..." +${TEST_DIR}/${SRC_DIR}/${EXEC_FILE_NAME} | tee ${TEST_NAME}.log | \ + grep -vE '^\[' >> ${TEST_NAME}.testlog diff --git a/tests/10-ipv6-nbr/Makefile b/tests/10-ipv6-nbr/Makefile new file mode 100644 index 000000000..c46e5271d --- /dev/null +++ b/tests/10-ipv6-nbr/Makefile @@ -0,0 +1 @@ +include ../Makefile.script-test diff --git a/tests/10-ipv6-nbr/nbr-multi-addrs/Makefile b/tests/10-ipv6-nbr/nbr-multi-addrs/Makefile new file mode 100644 index 000000000..711bf0987 --- /dev/null +++ b/tests/10-ipv6-nbr/nbr-multi-addrs/Makefile @@ -0,0 +1,14 @@ +CONTIKI_PROJECT = test +all: $(CONTIKI_PROJECT) + +CFLAGS += -DUNIT_TEST_PRINT_FUNCTION=my_test_print +CFLAGS += -DLOG_CONF_LEVEL_IPV6=LOG_LEVEL_DBG +CFLAGS += -DNBR_TABLE_FIND_REMOVABLE=my_always_return_null +CFLAGS += -DUIP_DS6_NBR_CONF_MULTI_IPV6_ADDRS=1 + +PLATFORM_ONLY = native +TARGET = native +MODULES += os/sys/log os/services/unit-test + +CONTIKI = ../../../ +include $(CONTIKI)/Makefile.include diff --git a/tests/10-ipv6-nbr/nbr-multi-addrs/test.c b/tests/10-ipv6-nbr/nbr-multi-addrs/test.c new file mode 100644 index 000000000..2cefd7cca --- /dev/null +++ b/tests/10-ipv6-nbr/nbr-multi-addrs/test.c @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2018, Yasuyuki Tanaka + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#define LOG_MODULE "test" +#define LOG_LEVEL LOG_LEVEL_DBG + +/* report function defined in unit-test.c */ +void unit_test_print_report(const unit_test_t *utp); + +static const uint8_t is_router = 1; +static const uint8_t state = NBR_INCOMPLETE; +static const nbr_table_reason_t reason = NBR_TABLE_REASON_UNDEFINED; + +static void remove_all_entries_in_neighbor_cache(void); + +PROCESS(node_process, "Node"); +AUTOSTART_PROCESSES(&node_process); + +void +my_test_print(const unit_test_t *utp) +{ + unit_test_print_report(utp); + if(utp->result == unit_test_failure) { + printf("\nTEST FAILED\n"); + exit(1); /* exit by failure */ + } +} + +/* my_always_return_null() is set to NBR_TABLE_FIND_REMOVABLE */ +const linkaddr_t * +my_always_return_null(nbr_table_reason_t reason, void *data) +{ + return NULL; +} + +void +remove_all_entries_in_neighbor_cache(void) +{ + uip_ds6_nbr_t *nbr, *next_nbr; + for(nbr = uip_ds6_nbr_head(); nbr != NULL; nbr = next_nbr) { + next_nbr = uip_ds6_nbr_next(nbr); + uip_ds6_nbr_rm(nbr); + } + /* + * uip_ds6_nbr_rm() cannot free the memory for an entry in nbr-table. There is + * no API to free or deallocate unused nbr-table entry. Because of that, + * nbr-table has some link-layer addresses even though this function removes + * all the neighbor cache entries. + */ +} + +UNIT_TEST_REGISTER(add_v6addrs_to_neighbor, + "add IPv6 addresses to a single neighbor"); +UNIT_TEST(add_v6addrs_to_neighbor) +{ + uip_ipaddr_t ipaddr; + uip_lladdr_t lladdr; + uip_ds6_nbr_t *nbr; + const uip_lladdr_t *ret_lladdr; + + memset(&ipaddr, 0, sizeof(ipaddr)); + memset(&lladdr, 0, sizeof(lladdr)); + + UNIT_TEST_BEGIN(); + + /* make sure the neighbor cache table is empty */ + remove_all_entries_in_neighbor_cache(); + UNIT_TEST_ASSERT(uip_ds6_nbr_head() == NULL); + UNIT_TEST_ASSERT(uip_ds6_nbr_num() == 0); + + /* prepare a link-layer address */ + LOG_DBG("link-layer addr: "); + LOG_DBG_LLADDR((const linkaddr_t *)&lladdr); + LOG_DBG_("\n"); + + for(int i = 0; i <= UIP_DS6_NBR_MAX_6ADDRS_PER_NBR; i++) { + ipaddr.u8[0] = i; + LOG_DBG("adding ipv6 addr ("); + LOG_DBG_6ADDR(&ipaddr); + LOG_DBG_("[i=%u])\n", i); + + /* add a binding of the IPv6 address and the MAC address */ + nbr = uip_ds6_nbr_add(&ipaddr, &lladdr, is_router, state, reason, NULL); + if(i < UIP_DS6_NBR_MAX_6ADDRS_PER_NBR) { + UNIT_TEST_ASSERT(nbr != NULL); + UNIT_TEST_ASSERT(memcmp(&nbr->ipaddr, &ipaddr, sizeof(ipaddr)) == 0); + UNIT_TEST_ASSERT(nbr->state == state); + UNIT_TEST_ASSERT(uip_ds6_nbr_num() == (i + 1)); + /* + * for some reason, nbr->isrouter is not set if both UIP_ND6_SEND_RA and + * !UIP_CONF_ROUTER is 0 (see uip-ds6-nbr.c) + */ + // UNIT_TEST_ASSERT(nbr->isrouter == is_router); + ret_lladdr = uip_ds6_nbr_lladdr_from_ipaddr((const uip_ipaddr_t *)&ipaddr); + UNIT_TEST_ASSERT(ret_lladdr != NULL); + UNIT_TEST_ASSERT(memcmp(ret_lladdr, &lladdr, sizeof(lladdr)) == 0); + + } else { + /* i == UIP_DS6_NBR_MAX_6ADDRS_PER_NBR; the address shouldn't be added */ + UNIT_TEST_ASSERT(nbr == NULL); + } + } + + UNIT_TEST_END(); +} + +UNIT_TEST_REGISTER(remove_v6addrs_of_neighbor, + "remove IPv6 addresses associated with a single neighbor"); +UNIT_TEST(remove_v6addrs_of_neighbor) +{ + uip_ipaddr_t ipaddr; + uip_lladdr_t lladdr; + uip_ds6_nbr_t *nbr, *next_nbr; + + memset(&ipaddr, 0, sizeof(ipaddr)); + memset(&lladdr, 0, sizeof(lladdr)); + + UNIT_TEST_BEGIN(); + + /* make sure the neighbor cache table is empty */ + remove_all_entries_in_neighbor_cache(); + UNIT_TEST_ASSERT(uip_ds6_nbr_head() == NULL); + UNIT_TEST_ASSERT(uip_ds6_nbr_num() == 0); + + /* prepare a link-layer address */ + LOG_DBG("link-layer addr: "); + LOG_DBG_LLADDR((const linkaddr_t *)&lladdr); + LOG_DBG_("\n"); + + /* fill the neighbor entry associated with the link-layer address */ + for(int i = 0; i < UIP_DS6_NBR_MAX_6ADDRS_PER_NBR; i++) { + ipaddr.u8[0] = i; + nbr = uip_ds6_nbr_add(&ipaddr, &lladdr, is_router, state, reason, NULL); + UNIT_TEST_ASSERT(nbr != NULL); + UNIT_TEST_ASSERT(uip_ds6_nbr_num() == (i + 1)); + } + + /* remove IPv6 addresses for the link-layer address one by one */ + for(nbr = uip_ds6_nbr_head(); nbr != NULL; nbr = next_nbr) { + LOG_DBG("removing nbr:%p\n", nbr); + next_nbr = uip_ds6_nbr_next(nbr); + UNIT_TEST_ASSERT(uip_ds6_nbr_rm(nbr) == 1); + } + UNIT_TEST_ASSERT(uip_ds6_nbr_num() == 0); + UNIT_TEST_ASSERT(uip_ds6_nbr_head() == NULL); + + UNIT_TEST_END(); + +} + +UNIT_TEST_REGISTER(fill_neighbor_cache_table, + "fill the neighbor cache table"); +UNIT_TEST(fill_neighbor_cache_table) +{ + /* + * We should be able to add the same number of link-layer addresses as + * NBR_TABLE_MAX_NEIGHBORS. In addition, we should be add the same number of + * IPv6 addresses per link-layer address as + * UIP_DS6_NBR_CONF_MAX_6ADDRS_PER_NBR. + */ + uip_ipaddr_t ipaddr; + uip_lladdr_t lladdr; + uip_ds6_nbr_t *nbr; + + memset(&ipaddr, 0, sizeof(ipaddr)); + memset(&lladdr, 0, sizeof(lladdr)); + + UNIT_TEST_BEGIN(); + + /* make sure the neighbor cache table is empty */ + remove_all_entries_in_neighbor_cache(); + UNIT_TEST_ASSERT(uip_ds6_nbr_head() == NULL); + UNIT_TEST_ASSERT(uip_ds6_nbr_num() == 0); + + for(int i = 0; i <= NBR_TABLE_MAX_NEIGHBORS; i++) { + lladdr.addr[0] = i & 0xFF; + lladdr.addr[1] = i >> 8; + for(int j = 0; j <= UIP_DS6_NBR_MAX_6ADDRS_PER_NBR; j++) { + ipaddr.u8[0] = i & 0xFF; + ipaddr.u8[1] = i >> 8; + ipaddr.u8[2] = j; + LOG_DBG("adding ipv6 addr ("); + LOG_DBG_6ADDR(&ipaddr); + LOG_DBG_(") to link-layer addr ("); + LOG_DBG_LLADDR((const linkaddr_t *)&lladdr); + LOG_DBG_(") [i=%u,j=%u]\n", i, j); + + nbr = uip_ds6_nbr_add(&ipaddr, &lladdr, is_router, state, reason, NULL); + if((i < NBR_TABLE_MAX_NEIGHBORS) && + (j < UIP_DS6_NBR_MAX_6ADDRS_PER_NBR)) { + UNIT_TEST_ASSERT(nbr != NULL); + } else if(i == NBR_TABLE_MAX_NEIGHBORS) { + /* we should not be able to add a link-layer address any more */ + UNIT_TEST_ASSERT(j == 0); + UNIT_TEST_ASSERT(nbr == NULL); + break; + } else if(j == UIP_DS6_NBR_MAX_6ADDRS_PER_NBR) { + /* we should not be able to add an IPv6 address any more */ + UNIT_TEST_ASSERT(i < NBR_TABLE_MAX_NEIGHBORS); + UNIT_TEST_ASSERT(nbr == NULL); + break; + } else { + /* shouldn't come here */ + UNIT_TEST_ASSERT(false); + } + } + } + + UNIT_TEST_END(); +} + +PROCESS_THREAD(node_process, ev, data) +{ + PROCESS_BEGIN(); + + UNIT_TEST_RUN(add_v6addrs_to_neighbor); + UNIT_TEST_RUN(remove_v6addrs_of_neighbor); + UNIT_TEST_RUN(fill_neighbor_cache_table); + + printf("\nTEST SUCCEEDED\n"); + exit(0); /* success: all the test passed */ + + PROCESS_END(); +}