From 96ff840bd8597a1dd987bda86b751acb9b6b2fd1 Mon Sep 17 00:00:00 2001 From: mkirc Date: Thu, 13 Mar 2025 20:14:31 +0100 Subject: [PATCH] test: smoketest: setup for two-host announce and recieve This test uses network namespaces in order to create a virtual network for two hosts which can send and recieve UDP messages. The test can be run with 'sudo bash test_two_hosts_announce.sh [MAJOR.MINOR.PATCH]' (eg. sudo bash test_two_hosts_announce.sh 0.9.2). It automatically sets up a virtual environment for the specified rns version. There is some rudimentary version string parsing for ease of use. The test sets up two network namespaces for two hosts and assigns some arbitrary IP- and MAC addresses. Then a rnsd instance is started per namespace, an id (with rnid) is generated and an announce is sent out. The other side then verifies the announce and the same is repeated in reverse. The test script exits 1 if any of the announces could not be verified and 0 if both can be verified. --- .../test-announce/cleanup_directories.sh | 12 +++ .../test-announce/cleanup_virtual_network.sh | 5 + tests/smoketests/test-announce/common.sh | 14 +++ .../test-announce/network_config.env | 10 ++ tests/smoketests/test-announce/rns.config | 29 +++++ .../test-announce/setup_python_venv.sh | 29 +++++ .../test-announce/setup_rns_config.sh | 11 ++ .../test-announce/setup_virtual_network.sh | 37 +++++++ .../test-announce/test_two_hosts_announce.sh | 100 ++++++++++++++++++ 9 files changed, 247 insertions(+) create mode 100644 tests/smoketests/test-announce/cleanup_directories.sh create mode 100644 tests/smoketests/test-announce/cleanup_virtual_network.sh create mode 100644 tests/smoketests/test-announce/common.sh create mode 100644 tests/smoketests/test-announce/network_config.env create mode 100644 tests/smoketests/test-announce/rns.config create mode 100644 tests/smoketests/test-announce/setup_python_venv.sh create mode 100644 tests/smoketests/test-announce/setup_rns_config.sh create mode 100644 tests/smoketests/test-announce/setup_virtual_network.sh create mode 100644 tests/smoketests/test-announce/test_two_hosts_announce.sh diff --git a/tests/smoketests/test-announce/cleanup_directories.sh b/tests/smoketests/test-announce/cleanup_directories.sh new file mode 100644 index 0000000..f69e5d9 --- /dev/null +++ b/tests/smoketests/test-announce/cleanup_directories.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +set -x + +# get path of this file +base_path="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" + +[[ -d "$base_path"/rns-config/ ]] && rm -rf "$base_path"/rns-config/ + +[[ -d "$base_path"/venv/ ]] && rm -rf "$base_path"/venv/ + + diff --git a/tests/smoketests/test-announce/cleanup_virtual_network.sh b/tests/smoketests/test-announce/cleanup_virtual_network.sh new file mode 100644 index 0000000..b96da30 --- /dev/null +++ b/tests/smoketests/test-announce/cleanup_virtual_network.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +set -x + +ip netns del h1 +ip netns del h2 diff --git a/tests/smoketests/test-announce/common.sh b/tests/smoketests/test-announce/common.sh new file mode 100644 index 0000000..d635912 --- /dev/null +++ b/tests/smoketests/test-announce/common.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +valid_version_string() { + [[ "$1" =~ ([0-9]\.)+ ]] && return 0 || return 1 +} + +die() { + # Takes an an optional error message as the sole argument. + [[ -n "$1" ]] \ + && echo "$0 Error:" "$1" >&2 \ + || echo "$0 Unspecified error, aborting." >&2 + exit 1 +} + diff --git a/tests/smoketests/test-announce/network_config.env b/tests/smoketests/test-announce/network_config.env new file mode 100644 index 0000000..5dc2a7e --- /dev/null +++ b/tests/smoketests/test-announce/network_config.env @@ -0,0 +1,10 @@ +H1_DEV="eth0" +H1_IP=10.13.12.1 +H1_GW=10.13.12.101 +H1_MAC="DE:AD:BE:EF:DE:AD" + +H2_DEV="eth0" +H2_IP=10.13.12.2 +H2_GW=10.13.12.102 +H2_MAC="AC:AB:AC:AB:AC:AB" + diff --git a/tests/smoketests/test-announce/rns.config b/tests/smoketests/test-announce/rns.config new file mode 100644 index 0000000..61c566b --- /dev/null +++ b/tests/smoketests/test-announce/rns.config @@ -0,0 +1,29 @@ +# rnsd --exampleconfig + +[reticulum] + + enable_transport = False + + # share_instance = Yes + + # shared_instance_port = 37428 + # instance_control_port = 37429 + + panic_on_interface_error = No + +[logging] + + loglevel = 4 + + +[interfaces] + +# local Reticulum peers over UDP. +[[UDP Interface]] + + type = UDPInterface + interface_enabled = True + + device = eth0 + port = 4242 + diff --git a/tests/smoketests/test-announce/setup_python_venv.sh b/tests/smoketests/test-announce/setup_python_venv.sh new file mode 100644 index 0000000..4ab1b61 --- /dev/null +++ b/tests/smoketests/test-announce/setup_python_venv.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +set -e + +base_path="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" + +source "$base_path"/common.sh + +# set version by command line argument +if [[ $(valid_version_string "$1") -eq 0 ]]; then + RNS_VERSION_STR="$1" +# or by environment variable +elif [[ $(valid_version_string "$RNS_VERSION") -eq 0 ]]; then + RNS_VERSION_STR="$RNS_VERSION" +else + die 'Please supply a valid version string.' +fi + + +if [[ -d "$base_path"/venv ]]; then + echo "Found ./venv, assuming a python virtual env." +else + echo "Did not find virtual env, creating..." + python3 -m venv "$base_path"/venv +fi + +source "$base_path"/venv/bin/activate + +pip install -v "rns==${RNS_VERSION_STR}" diff --git a/tests/smoketests/test-announce/setup_rns_config.sh b/tests/smoketests/test-announce/setup_rns_config.sh new file mode 100644 index 0000000..edbc99b --- /dev/null +++ b/tests/smoketests/test-announce/setup_rns_config.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +set -x + +# get path of this file +base_path="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" + +mkdir -p "$base_path"/rns-config/h{1,2} + +cp "$base_path"/rns.config "$base_path"/rns-config/h1/config +cp "$base_path"/rns.config "$base_path"/rns-config/h2/config diff --git a/tests/smoketests/test-announce/setup_virtual_network.sh b/tests/smoketests/test-announce/setup_virtual_network.sh new file mode 100644 index 0000000..a90dd7d --- /dev/null +++ b/tests/smoketests/test-announce/setup_virtual_network.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +set -ex + +# get path of this file +base_path="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" + + +# load config +source "$base_path"/network_config.env + +# create network namespace +ip netns add h1 +ip netns add h2 + +# create virtual network +ip -n h1 link add "$H1_DEV" type veth peer name "$H2_DEV" netns h2 + +# Setup loopback +ip netns exec h1 ip link set lo up +ip netns exec h2 ip link set lo up + +# assign ip adresses +ip netns exec h1 ip addr add "$H1_IP/24" dev "$H1_DEV" +ip netns exec h2 ip addr add "$H2_IP/24" dev "$H2_DEV" + +# set mac adresses +ip netns exec h1 ip link set dev "$H1_DEV" address "$H1_MAC" +ip netns exec h2 ip link set dev "$H2_DEV" address "$H2_MAC" + +# activate interfaces +ip netns exec h1 ip link set "$H1_DEV" up +ip netns exec h2 ip link set "$H2_DEV" up + +# set default routes +ip netns exec h1 ip route add default via "$H1_GW" dev "$H1_DEV" +ip netns exec h2 ip route add default via "$H2_GW" dev "$H2_DEV" diff --git a/tests/smoketests/test-announce/test_two_hosts_announce.sh b/tests/smoketests/test-announce/test_two_hosts_announce.sh new file mode 100644 index 0000000..98d8cc2 --- /dev/null +++ b/tests/smoketests/test-announce/test_two_hosts_announce.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env bash + +set -x + +base_path="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" + +source "$base_path"/common.sh + +############ GET RNS VERSION STR ############ + +# set version by command line argument +if $(valid_version_string "$1"); then + RNS_VERSION_STR="$1" +# or by environment variable +elif $(valid_version_string "${RNS_VERSION}"); then + RNS_VERSION_STR="$RNS_VERSION" +else + die 'Please supply a valid version string. (eg. "0.9.1")' +fi + +############## SETUP #################### + + +# setup venv for rns version string +bash "$base_path"/setup_python_venv.sh "$RNS_VERSION_STR" + +# veth setup +bash "$base_path"/setup_virtual_network.sh + +# setup rns config +bash "$base_path"/setup_rns_config.sh + + +H1_DIR="$base_path"/rns-config/h1 +H2_DIR="$base_path"/rns-config/h2 + +[[ -d "$base_path"/venv/bin ]] && venv="$base_path"/venv/bin + +EXEC_H1="ip netns exec h1" +EXEC_H2="ip netns exec h2" + +################# TEST #################### + +# generate "$venv"/rns ids +$EXEC_H1 "$venv"/rnid --config "$H1_DIR" -g "$H1_DIR"/id +$EXEC_H2 "$venv"/rnid --config "$H2_DIR" -g "$H2_DIR"/id + +# start two "$venv"/rns daemons +$EXEC_H1 "$venv"/rnsd --config "$H1_DIR" & +$EXEC_H2 "$venv"/rnsd --config "$H2_DIR" & + +sleep 1 # seconds + +ANNOUNCE_REGEXP='(?<=Announcing destination )\<.*\>' + +# broadcast announce from h1 and capture the destination hash +h1_hash=$($EXEC_H1 "$venv"/rnid --config "$H1_DIR" -i "$H1_DIR"/id -a test.h1 | grep -oP "$ANNOUNCE_REGEXP") + +sleep 1 # seconds + +H1_ANNOUNCE_RECV=1 +# verify announce as seen from h2 +if [[ $($EXEC_H2 "$venv"/rnpath --config "$H2_DIR" -t) == *"$h1_hash"* ]] && [[ -n "$h1_hash" ]]; then + echo 'h1 announce sucessfully recieved' + H1_ANNOUNCE_RECV=0 +else + echo 'h1 announce was not recieved successfully' +fi + +# broadcast announce from h2 and capture the destination hash +h2_hash=$($EXEC_H2 "$venv"/rnid --config "$H2_DIR" -i "$H2_DIR"/id -a test.h2 | grep -oP "$ANNOUNCE_REGEXP") + +sleep 1 # seconds + +H2_ANNOUNCE_RECV=1 +# verify announce as seen from h1 +if [[ $($EXEC_H1 "$venv"/rnpath --config "$H1_DIR" -t) == *"$h2_hash"* ]] && [[ -n "$h2_hash" ]]; then + echo 'h2 announce sucessfully recieved' + H2_ANNOUNCE_RECV=0 +else + echo 'h2 announce was not recieved successfully' +fi + + +########## TEARDOWN ############ + +# stop rnsd instances +$EXEC_H1 pkill rnsd +$EXEC_H2 pkill rnsd + +# veth teardown +bash "$base_path"/cleanup_virtual_network.sh + +# directories teardown +bash "$base_path"/cleanup_directories.sh + + +########### EXIT BASED ON TEST OUTCOME ############# + +exit $([[ $H1_ANNOUNCE_RECV -eq 0 ]] && [[ $H2_ANNOUNCE_RECV -eq 0 ]])