From ebc5d6a3e0be1a7fb3fc5e55ed8dab3b026517be Mon Sep 17 00:00:00 2001 From: Daniel Barlow Date: Sun, 5 Feb 2023 17:37:31 +0000 Subject: [PATCH] convert pppoe test to a derivation * move shell script to a runCommand * multicast needs special options to run on loopback (nix-build sandbox disables non-local network interfaces) --- ci.nix | 1 + scripts/run-qemu.sh | 4 +-- tests/pppoe/run.sh | 31 ---------------- tests/pppoe/test-dhcp-service.py | 9 +++-- tests/pppoe/test.nix | 61 ++++++++++++++++++++++++++++++++ 5 files changed, 68 insertions(+), 38 deletions(-) delete mode 100755 tests/pppoe/run.sh create mode 100644 tests/pppoe/test.nix diff --git a/ci.nix b/ci.nix index 0469407..3998d71 100644 --- a/ci.nix +++ b/ci.nix @@ -1,4 +1,5 @@ { smoke = import ./tests/smoke/test.nix; pseudofiles = import ./tests/pseudofiles/test.nix; + pppoe = import ./tests/pppoe/test.nix; } diff --git a/scripts/run-qemu.sh b/scripts/run-qemu.sh index 1816ce9..24e3b8f 100755 --- a/scripts/run-qemu.sh +++ b/scripts/run-qemu.sh @@ -18,8 +18,8 @@ qemu-system-mips \ -echr 16 \ -append "default console=ttyS0,38400n8 panic=10 oops=panic init=$INIT loglevel=8 root=/dev/vda" \ -drive file=$2,format=raw,readonly=on,if=virtio \ - -netdev socket,id=access,mcast=230.0.0.1:1234 \ + -netdev socket,id=access,mcast=230.0.0.1:1234,localaddr=127.0.0.1 \ -device virtio-net-pci,disable-legacy=on,disable-modern=off,netdev=access,mac=ba:ad:1d:ea:21:02 \ - -netdev socket,id=lan,mcast=230.0.0.1:1235 \ + -netdev socket,id=lan,mcast=230.0.0.1:1235,localaddr=127.0.0.1 \ -device virtio-net-pci,disable-legacy=on,disable-modern=off,netdev=lan,mac=ba:ad:1d:ea:21:01 \ -kernel $1 -display none $flags ${QEMU_OPTIONS} diff --git a/tests/pppoe/run.sh b/tests/pppoe/run.sh deleted file mode 100755 index e6294a5..0000000 --- a/tests/pppoe/run.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env sh - -cleanup(){ - if test -e foo.pid && test -d /proc/`cat foo.pid` ; then - echo "killing qemu" - kill `cat foo.pid` - fi -} -trap cleanup EXIT -fatal(){ - err=$? - echo "FAIL: command $(eval echo $BASH_COMMAND) exited with code $err" - exit $err -} -trap fatal ERR - -NIXPKGS_ALLOW_UNSUPPORTED_SYSTEM=1 nix-build '' -I liminix-config=./configuration.nix --arg device "import " -A outputs.default $* - -if ! ( echo "cont" | socat - unix-connect:../support/ppp-server/qemu-monitor); then - echo "need pppoe server running" - exit 1 -fi - -../../scripts/run-qemu.sh --background foo.sock result/vmlinux result/squashfs -nix-shell -p expect --run "expect getaddress.expect" - -set -o pipefail -response=$(nix-shell -p python3Packages.scapy --run 'python ./test-dhcp-service.py' ) - -echo "$response" -echo "$response" | nix-shell -p jq --run "jq -e 'select((.router == \"192.168.19.1\") and (.server_id==\"192.168.19.1\"))'" diff --git a/tests/pppoe/test-dhcp-service.py b/tests/pppoe/test-dhcp-service.py index 6f9ccaf..86a543f 100644 --- a/tests/pppoe/test-dhcp-service.py +++ b/tests/pppoe/test-dhcp-service.py @@ -66,10 +66,9 @@ sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, MULTICAST_TTL) sock.bind((MCAST_GRP, MCAST_PORT)) -host = socket.gethostbyname(socket.gethostname()) -sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(host)) +sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton('127.0.0.1')) sock.setsockopt(socket.SOL_IP, socket.IP_ADD_MEMBERSHIP, - socket.inet_aton(MCAST_GRP) + socket.inet_aton(host)) + socket.inet_aton(MCAST_GRP) + socket.inet_aton('127.0.0.1')) endtime = time.time() + TIMEOUT sock.sendto(payload, (MCAST_GRP, MCAST_PORT)) @@ -77,8 +76,8 @@ sock.sendto(payload, (MCAST_GRP, MCAST_PORT)) while time.time() < endtime: try: data, addr = sock.recvfrom(1024) - except socket.error: - print('Exception') + except socket.error as e: + print('recv exception: ', e) else: reply = Ether(data) if is_dhcp_offer(reply): diff --git a/tests/pppoe/test.nix b/tests/pppoe/test.nix new file mode 100644 index 0000000..4ac2df2 --- /dev/null +++ b/tests/pppoe/test.nix @@ -0,0 +1,61 @@ +{ + liminix +, nixpkgs +}: +let img = (import liminix { + device = import "${liminix}/devices/qemu/"; + liminix-config = ./configuration.nix; + }).outputs.default; + pkgs = import {}; + ros = pkgs.callPackage ../support/ppp-server {}; + run-qemu = pkgs.writeShellScriptBin "run-qemu" '' + export PATH="${pkgs.lib.makeBinPath [pkgs.qemu]}:$PATH" + ${builtins.readFile ../../scripts/run-qemu.sh} + ''; + +in pkgs.runCommand "check" { + nativeBuildInputs = with pkgs; [ + python3Packages.scapy + expect + jq + socat + ros.routeros + run-qemu + ] ; +} '' +serverstatedir=$(mktemp -d -t routeros-XXXXXX) +# python scapy drags in matplotlib which doesn't enjoy running in +# a sandbox with no $HOME, hence this environment variable +export MPLCONFIGDIR=$(mktemp -d -t routeros-XXXXXX) + +killpid(){ + if test -e $1 && test -d /proc/`cat $1` ; then + pid=$(cat $1) + kill $pid + fi +} + +cleanup(){ + killpid $serverstatedir/pid + test -n "$MPLCONFIGDIR" && test -d "$MPLCONFIGDIR" && rm -rf "$MPLCONFIGDIR" + killpid foo.pid +} +trap cleanup EXIT + +fatal(){ + err=$? + echo "FAIL: command $(eval echo $BASH_COMMAND) exited with code $err" + exit $err +} +trap fatal ERR + +routeros $serverstatedir + +run-qemu --background foo.sock ${img}/vmlinux ${img}/squashfs +expect ${./getaddress.expect} + +set -o pipefail +response=$(python ${./test-dhcp-service.py}) +echo "$response" | jq -e 'select((.router == "192.168.19.1") and (.server_id=="192.168.19.1"))' +echo $response > $out +''