diff --git a/examples/suit_update/Makefile b/examples/suit_update/Makefile index 805701daad4f..2adea002de34 100644 --- a/examples/suit_update/Makefile +++ b/examples/suit_update/Makefile @@ -55,6 +55,7 @@ DEFAULT_MODULE += test_utils_interactive_sync ifeq ($(BOARD),native) USE_ETHOS ?= 0 + IFACE ?= tapbr0 # Configure two RAM regions with 2K each CFLAGS += -DCONFIG_SUIT_STORAGE_RAM_REGIONS=2 -DCONFIG_SUIT_STORAGE_RAM_SIZE=2048 endif @@ -78,9 +79,9 @@ ifeq (1,$(USE_ETHOS)) # $ cd dist/tools/ethos; sudo ./setup_network.sh riot0 2001:db8::0/64 # #... in another shell and keep it running. - export TAP ?= riot0 + IFACE ?= riot0 TERMPROG = $(RIOTTOOLS)/ethos/ethos - TERMFLAGS = $(TAP) $(PORT) + TERMFLAGS = $(IFACE) $(PORT) endif # Ensure both slot bin files are always generated and linked to avoid compiling @@ -106,6 +107,11 @@ include $(CURDIR)/Makefile.suit.custom include $(RIOTBASE)/Makefile.include +# export IFACE for test +$(call target-export-variables,test-with-config test-with-config/check-config,IFACE) +# export BOARD +$(call target-export-variables,test-with-config test-with-config/check-config,BOARD) + # allow to use large blocks to utilize large MTUs (802.15.4g, Ethernet, WiFi) LARGE_BLOCKS ?= 0 ifeq (1, $(LARGE_BLOCKS)) diff --git a/examples/suit_update/Makefile.suit.custom b/examples/suit_update/Makefile.suit.custom index 0e2c8bd1e305..cdfaa35faebc 100644 --- a/examples/suit_update/Makefile.suit.custom +++ b/examples/suit_update/Makefile.suit.custom @@ -12,6 +12,7 @@ APP_VER ?= $(EPOCH) ifeq ($(BOARD),native) SUIT_CLIENT ?= [2001:db8::2] SUIT_COAP_SERVER ?= [2001:db8::1] + $(call target-export-variables,test-with-config,SUIT_COAP_SERVER) endif ifeq ($(BOARD),native) diff --git a/examples/suit_update/tests-with-config/01-run.py b/examples/suit_update/tests-with-config/01-run.py index de9170ddb980..6c27b0f326aa 100755 --- a/examples/suit_update/tests-with-config/01-run.py +++ b/examples/suit_update/tests-with-config/01-run.py @@ -11,21 +11,39 @@ import sys import tempfile import time +import re +import random +from ipaddress import ( + IPv6Address, + IPv6Network, +) from testrunner import run from testrunner import utils -# Default test over loopback interface -COAP_HOST = "[fd00:dead:beef::1]" +COAP_HOST = os.getenv("SUIT_COAP_SERVER", "[fd00:dead:beef::1]") +BOARD = os.getenv("BOARD", "samr21-xpro") UPDATING_TIMEOUT = 10 MANIFEST_TIMEOUT = 15 USE_ETHOS = int(os.getenv("USE_ETHOS", "1")) -TAP = os.getenv("TAP", "riot0") +IFACE = os.getenv("IFACE", "tapbr0") TMPDIR = tempfile.TemporaryDirectory() +def get_iface_addr(iface): + out = subprocess.check_output(["ip", "a", "s", "dev", iface]).decode() + p = re.compile( + r"inet6\s+(?P[0-9a-fA-F:]+:[A-Fa-f:0-9]+/\d+)\s+" r"scope\s+global" + ) + for line in out.splitlines(): + m = p.search(line) + if m is not None: + return m.group("global") + return None + + def start_aiocoap_fileserver(): aiocoap_process = subprocess.Popen( "exec aiocoap-fileserver %s" % TMPDIR.name, shell=True @@ -90,7 +108,7 @@ def get_ipv6_addr(child): child.expect( r"inet6 addr: (?P[0-9a-fA-F:]+:[A-Fa-f:0-9]+)" " scope: link VAL" ) - addr = "{}%{}".format(child.match.group("lladdr").lower(), TAP) + addr = "{}%{}".format(child.match.group("lladdr").lower(), IFACE) return addr @@ -117,7 +135,20 @@ def get_reachable_addr(child): # Give some time for the network interface to be configured time.sleep(1) # Get address - client_addr = get_ipv6_addr(child) + if BOARD == "native": + iface_addr = get_iface_addr(IFACE) + network = IPv6Network(iface_addr, strict=False) + client_addr = iface_addr + while iface_addr == client_addr: + client_addr = IPv6Address( + random.randrange( + int(network.network_address) + 1, int(network.broadcast_address) - 1 + ) + ) + child.sendline(f"ifconfig 5 add {client_addr}/{format(network.prefixlen)}") + client_addr = format(client_addr) + else: + client_addr = get_ipv6_addr(child) # Verify address is reachable ping6(client_addr) return "[{}]".format(client_addr) @@ -166,21 +197,22 @@ def _test_successful_update(child, client, app_ver): child.expect_exact("suit_coap: trigger received") child.expect_exact("suit: verifying manifest signature") child.expect( - r"riotboot_flashwrite: initializing update to target slot (\d+)\r\n", + r"SUIT policy check OK.\r\n", timeout=MANIFEST_TIMEOUT, ) - target_slot = int(child.match.group(1)) # Wait for update to complete while wait_for_update(child) == 0: pass - - # Wait for reboot - child.expect_exact("suit_coap: rebooting...") - # Verify running slot - current_slot = running_slot(child) - assert target_slot == current_slot, "BOOTED FROM SAME SLOT" - # Verify client is reachable and get address - client = get_reachable_addr(child) + # Check successful install + child.expect_exact("Install correct payload") + child.expect_exact("Install correct payload") + + # Wait for reboot on non-native BOARDs + if BOARD != "native": + child.expect_exact("suit_coap: rebooting...") + # Verify client is reachable and get address + client = get_reachable_addr(child) + assert seq_no(child) == version def _test_suit_command_is_there(child): diff --git a/examples/suit_update/tests-with-config/check-config.sh b/examples/suit_update/tests-with-config/check-config.sh new file mode 100755 index 000000000000..9e202f85d527 --- /dev/null +++ b/examples/suit_update/tests-with-config/check-config.sh @@ -0,0 +1,36 @@ +#! /bin/sh +# +# check_config.sh +# Copyright (C) 2021 Martine Lenders +# Copyright (C) 2022 Inria +# +# Distributed under terms of the MIT license. +# + +ip link show dev "${IFACE}" > /dev/null +RESULT=$? + +if [ $RESULT -eq 0 ]; then + if [ "${BOARD}" = "native" ]; then + IFACE_IPV6_ADDR=$(ip -6 addr show dev "${IFACE}"| grep inet6 | \ + awk -F '[ \t]+|/' '{print $3}' | grep -v ^::1 | \ + grep -v ^fe80) + if [ -n "${IFACE_IPV6_ADDR}" ]; then + exit 0 + fi + else + exit 0 + fi +fi + +if [ "${BOARD}" = "native" ]; then + echo "You may be able to create \"${IFACE}\" by using e.g." \ + "\`${RIOTTOOLS#${RIOTBASE}/}/tapsetup/tapsetup\`." + echo "You can add a routable IPV6 address by using e.g." \ + "sudo ip address add 2001:db8::1/64 dev ${IFACE}" +else + echo "You may setup \"${IFACE}\" by using e.g." \ + "\`${RIOTTOOLS#${RIOTBASE}/}/ethos/setup_network.sh ${IFACE} 2001:db8::/64\`" +fi + +exit 1