Convert the old-style tests for pasta (DHCP, NDP, TCP and UDP transfers) to using avocado. There are a few differences in what we test, but this should generally improve coverage: * We run in a constructed network environment, so we no longer depend on the real host's networking configuration * We do independent setup for each individual test * We add explicit tests for --config-net, which we use to accelerate that setup for the TCP and UDP tests * The TCP and UDP tests now test transfers between the guest and a (simulated) remote site that's on a different network from the simulated pasta host. This better matches the typical passt/pasta usecase Signed-off-by: David Gibson <david(a)gibson.dropbear.id.au> --- oldtest/run | 14 ++-- test/Makefile | 1 + test/avocado/pasta.py | 129 ++++++++++++++++++++++++++++++++++ test/lib/layout | 31 -------- test/lib/setup | 40 ----------- test/pasta/dhcp | 46 ------------ test/pasta/ndp | 33 --------- test/pasta/tcp | 96 ------------------------- test/pasta/udp | 59 ---------------- test/run | 8 --- test/tasst/dhcpv6.py | 4 +- test/tasst/pasta.py | 42 +++++++++++ test/tasst/scenario/simple.py | 44 ++++++------ 13 files changed, 203 insertions(+), 344 deletions(-) create mode 100644 test/avocado/pasta.py delete mode 100644 test/pasta/dhcp delete mode 100644 test/pasta/ndp delete mode 100644 test/pasta/tcp delete mode 100644 test/pasta/udp create mode 100644 test/tasst/pasta.py diff --git a/oldtest/run b/oldtest/run index a16bc49b..f1157f90 100755 --- a/oldtest/run +++ b/oldtest/run @@ -70,13 +70,13 @@ run() { test build/clang_tidy teardown build -# setup pasta -# test pasta/ndp -# test pasta/dhcp -# test pasta/tcp -# test pasta/udp -# test passt/shutdown -# teardown pasta + setup pasta + test pasta/ndp + test pasta/dhcp + test pasta/tcp + test pasta/udp + test passt/shutdown + teardown pasta # setup pasta_options # test pasta_options/log_to_file diff --git a/test/Makefile b/test/Makefile index 953eacf2..9c3114c2 100644 --- a/test/Makefile +++ b/test/Makefile @@ -227,6 +227,7 @@ $(VENV): .PHONY: avocado-assets avocado-assets: nstool small.bin medium.bin big.bin + $(MAKE) -C .. pasta .PHONY: avocado avocado: avocado-assets $(VENV) diff --git a/test/avocado/pasta.py b/test/avocado/pasta.py new file mode 100644 index 00000000..891313f5 --- /dev/null +++ b/test/avocado/pasta.py @@ -0,0 +1,129 @@ +#! /usr/bin/env avocado-runner-avocado-classless + +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright Red Hat +# Author: David Gibson <david(a)gibson.dropbear.id.au> + +""" +avocado/pasta.py - Basic tests for pasta mode +""" + +import contextlib +import ipaddress +import os +import tempfile + +from avocado_classless.test import assert_eq, assert_eq_unordered, test + +from tasst.address import LOOPBACK4, LOOPBACK6 +from tasst.dhcp import test_dhcp +from tasst.dhcpv6 import test_dhcpv6 +from tasst.ndp import test_ndp +from tasst.nstool import unshare_site +from tasst.pasta import Pasta +from tasst.scenario.simple import ( + simple_net, IFNAME, HOST_NET6, IP4, IP6, GW_IP4, REMOTE_IP4, REMOTE_IP6 +) +from tasst.transfer import test_transfers + + +IN_FWD_PORT = 10002 +SPLICE_FWD_PORT = 10003 +FWD_OPTS = f'-t {IN_FWD_PORT} -u {IN_FWD_PORT} \ + -T {SPLICE_FWD_PORT} -U {SPLICE_FWD_PORT}' + + +(a)contextlib.contextmanager +def pasta_unconfigured(opts=FWD_OPTS): + with simple_net() as simnet: + with unshare_site('pastans', '-Ucnpf --mount-proc', + parent=simnet.simhost, sudo=True) as guestns: + with tempfile.TemporaryDirectory() as tmpdir: + pidfile = os.path.join(tmpdir, 'pasta.pid') + + with Pasta(simnet.simhost, pidfile, opts, ns=guestns) as pasta: + yield simnet, pasta.ns + + +@test +def test_ifname(): + with pasta_unconfigured() as (_, ns): + assert_eq_unordered(ns.ifs(), ('lo', IFNAME)) + + +@test_ndp(IFNAME, HOST_NET6) +(a)contextlib.contextmanager +def pasta_ndp(): + with pasta_unconfigured() as (simnet, guestns): + guestns.ifup(IFNAME) + yield guestns, simnet.gw_ip6_ll.ip + + +@test_dhcp(IFNAME, IP4.ip, GW_IP4.ip, 65520) +@test_dhcpv6(IFNAME, IP6.ip) +(a)contextlib.contextmanager +def pasta_dhcp(): + with pasta_unconfigured() as (_, guestns): + yield guestns + + +(a)contextlib.contextmanager +def pasta_configured(): + with pasta_unconfigured(FWD_OPTS + ' --config-net') as (simnet, ns): + # Wait for DAD to complete on the --config-net address + ns.addr_wait(IFNAME, family='inet6', scope='global') + yield simnet, ns + + +@test +def test_config_net_addr(): + with pasta_configured() as (_, ns): + addrs = ns.addrs(IFNAME, scope='global') + assert_eq_unordered(addrs, [IP4, IP6]) + + +@test +def test_config_net_route4(): + with pasta_configured() as (_, ns): + (defroute,) = ns.routes4(dst='default') + gateway = ipaddress.ip_address(defroute['gateway']) + assert_eq(gateway, GW_IP4.ip) + + +@test +def test_config_net_route6(): + with pasta_configured() as (simnet, ns): + (defroute,) = ns.routes6(dst='default') + gateway = ipaddress.ip_address(defroute['gateway']) + assert_eq(gateway, simnet.gw_ip6_ll.ip) + + +@test +def test_config_net_mtu(): + with pasta_configured() as (_, ns): + mtu = ns.mtu(IFNAME) + assert_eq(mtu, 65520) + + +(a)test_transfers(ip4=REMOTE_IP4.ip, ip6=REMOTE_IP6.ip, port=10000) +(a)contextlib.contextmanager +def outward_transfer(): + with pasta_configured() as (simnet, ns): + yield ns, simnet.gw + + +(a)test_transfers(ip4=IP4.ip, ip6=IP6.ip, port=IN_FWD_PORT, + fromip4=REMOTE_IP4.ip, fromip6=REMOTE_IP6.ip) +(a)contextlib.contextmanager +def inward_transfer(): + with pasta_configured() as (simnet, ns): + yield simnet.gw, ns + + +@test_transfers(ip4=LOOPBACK4, ip6=LOOPBACK6, port=SPLICE_FWD_PORT, + listenip4=LOOPBACK4, listenip6=LOOPBACK6) +(a)contextlib.contextmanager +def spliced_transfer(): + with pasta_configured() as (simnet, ns): + yield ns, simnet.simhost diff --git a/test/lib/layout b/test/lib/layout index f9a1cf1b..e2b1db06 100644 --- a/test/lib/layout +++ b/test/lib/layout @@ -13,37 +13,6 @@ # Copyright (c) 2021 Red Hat GmbH # Author: Stefano Brivio <sbrivio(a)redhat.com> -# layout_pasta() - Panes for host, pasta, and separate one for namespace -layout_pasta() { - sleep 3 - - tmux kill-pane -a -t 0 - cmd_write 0 clear - - tmux split-window -v -t passt_test - tmux split-window -h -t passt_test - tmux split-window -h -l '42%' -t passt_test:1.0 - - PANE_NS=0 - PANE_INFO=1 - PANE_HOST=2 - PANE_PASST=3 - - get_info_cols - - tmux send-keys -l -t ${PANE_INFO} 'while cat '"$STATEBASE/log_pipe"'; do :; done' - tmux send-keys -t ${PANE_INFO} -N 100 C-m - tmux select-pane -t ${PANE_INFO} -T "test log" - - pane_watch_contexts ${PANE_HOST} host host - pane_watch_contexts ${PANE_PASST} pasta passt - pane_watch_contexts ${PANE_NS} "namespace" unshare ns - - info_layout "single pasta instance with namespace" - - sleep 1 -} - # layout_passt() - Panes for host, passt, and guest layout_passt() { sleep 3 diff --git a/test/lib/setup b/test/lib/setup index 5386805f..7abf2064 100755 --- a/test/lib/setup +++ b/test/lib/setup @@ -61,36 +61,6 @@ setup_passt() { context_setup_guest guest $GUEST_CID } -# setup_pasta() - Create a network and user namespace, connect pasta to it -setup_pasta() { - context_setup_host host - context_setup_host passt - context_setup_host unshare - - layout_pasta - - context_run_bg unshare "unshare -rUnpf ${NSTOOL} hold ${STATESETUP}/ns.hold" - - context_setup_nstool ns ${STATESETUP}/ns.hold - - # Ports: - # - # ns | host - # ------------------|--------------------- - # 10002 as server | spliced to ns - # 10003 spliced to init | as server - - __opts= - [ ${PCAP} -eq 1 ] && __opts="${__opts} -p ${LOGDIR}/pasta.pcap" - [ ${DEBUG} -eq 1 ] && __opts="${__opts} -d" - [ ${TRACE} -eq 1 ] && __opts="${__opts} --trace" - - context_run_bg passt "./pasta ${__opts} -f -t 10002 -T 10003 -u 10002 -U 10003 -P ${STATESETUP}/passt.pid $(${NSTOOL} info -pw ${STATESETUP}/ns.hold)" - - # pidfile isn't created until pasta is ready - wait_for [ -f "${STATESETUP}/passt.pid" ] -} - # setup_passt_in_ns() - Set up namespace (with pasta), run qemu and passt into it setup_passt_in_ns() { context_setup_host host @@ -270,16 +240,6 @@ teardown_passt() { teardown_context_watch ${PANE_GUEST} qemu guest } -# teardown_pasta() - Exit namespace, kill pasta process -teardown_pasta() { - ${NSTOOL} stop "${STATESETUP}/ns.hold" - context_wait unshare - - teardown_context_watch ${PANE_HOST} host - teardown_context_watch ${PANE_PASST} passt - teardown_context_watch ${PANE_NS} unshare ns -} - # teardown_passt_in_ns() - Exit namespace, kill qemu and pasta, remove pid file teardown_passt_in_ns() { context_run ns kill $(cat "${STATESETUP}/qemu.pid") diff --git a/test/pasta/dhcp b/test/pasta/dhcp deleted file mode 100644 index 309001b7..00000000 --- a/test/pasta/dhcp +++ /dev/null @@ -1,46 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later -# -# PASST - Plug A Simple Socket Transport -# for qemu/UNIX domain socket mode -# -# PASTA - Pack A Subtle Tap Abstraction -# for network namespace/tap device mode -# -# test/pasta/dhcp - Check DHCP and DHCPv6 functionality in pasta mode -# -# Copyright (c) 2021 Red Hat GmbH -# Author: Stefano Brivio <sbrivio(a)redhat.com> - -nstools ip jq /sbin/dhclient -htools ip jq - -test Interface name -nsout IFNAME ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname' -check [ -n "__IFNAME__" ] - -test DHCP: address -ns /sbin/dhclient -4 --no-pid __IFNAME__ -nsout ADDR ip -j -4 addr show|jq -rM '.[] | select(.ifname == "__IFNAME__").addr_info[0].local' -hout HOST_ADDR ip -j -4 addr show|jq -rM '.[] | select(.ifname == "__IFNAME__").addr_info[0].local' -check [ __ADDR__ = __HOST_ADDR__ ] - -test DHCP: route -nsout GW ip -j -4 route show|jq -rM '.[] | select(.dst == "default").gateway' -hout HOST_GW ip -j -4 route show|jq -rM '[.[] | select(.dst == "default").gateway] | .[0]' -check [ __GW__ = __HOST_GW__ ] - -test DHCP: MTU -nsout MTU ip -j link show | jq -rM '.[] | select(.ifname == "__IFNAME__").mtu' -check [ __MTU__ = 65520 ] - -test DHCPv6: address -ns /sbin/dhclient -6 --no-pid __IFNAME__ -hout HOST_IFNAME6 ip -j -6 route show|jq -rM '[.[] | select(.dst == "default").dev] | .[0]' -nsout ADDR6 ip -j -6 addr show|jq -rM '.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.prefixlen == 128).local' -hout HOST_ADDR6 ip -j -6 addr show|jq -rM '.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope == "global").local' -check [ __ADDR6__ = __HOST_ADDR6__ ] - -test DHCPv6: route -nsout GW6 ip -j -6 route show|jq -rM '.[] | select(.dst == "default").gateway' -hout HOST_GW6 ip -j -6 route show|jq -rM '[.[] | select(.dst == "default").gateway] | .[0]' -check [ __GW6__ = __HOST_GW6__ ] diff --git a/test/pasta/ndp b/test/pasta/ndp deleted file mode 100644 index bb331102..00000000 --- a/test/pasta/ndp +++ /dev/null @@ -1,33 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later -# -# PASST - Plug A Simple Socket Transport -# for qemu/UNIX domain socket mode -# -# PASTA - Pack A Subtle Tap Abstraction -# for network namespace/tap device mode -# -# test/pasta/ndp - Check DHCP and DHCPv6 functionality in pasta mode -# -# Copyright (c) 2021 Red Hat GmbH -# Author: Stefano Brivio <sbrivio(a)redhat.com> - -nstools ip jq sipcalc grep cut -htools ip jq sipcalc grep cut - -test Interface name -nsout IFNAME ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname' -check [ -n "__IFNAME__" ] -ns ip link set dev __IFNAME__ up -sleep 2 - -test SLAAC: prefix -nsout ADDR6 ip -j -6 addr show|jq -rM '.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.scope == "global" and .prefixlen == 64).local' -nsout PREFIX6 sipcalc __ADDR6__/64 | grep prefix | cut -d' ' -f4 -hout HOST_ADDR6 ip -j -6 addr show|jq -rM '.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.scope == "global").local' -hout HOST_PREFIX6 sipcalc __HOST_ADDR6__/64 | grep prefix | cut -d' ' -f4 -check [ "__PREFIX6__" = "__HOST_PREFIX6__" ] - -test SLAAC: route -nsout GW6 ip -j -6 route show|jq -rM '.[] | select(.dst == "default").gateway' -hout HOST_GW6 ip -j -6 route show|jq -rM '[.[] | select(.dst == "default").gateway] | .[0]' -check [ __GW6__ = __HOST_GW6__ ] diff --git a/test/pasta/tcp b/test/pasta/tcp deleted file mode 100644 index 6ab18c5c..00000000 --- a/test/pasta/tcp +++ /dev/null @@ -1,96 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later -# -# PASST - Plug A Simple Socket Transport -# for qemu/UNIX domain socket mode -# -# PASTA - Pack A Subtle Tap Abstraction -# for network namespace/tap device mode -# -# test/pasta/tcp - Check TCP functionality for pasta -# -# Copyright (c) 2021 Red Hat GmbH -# Author: Stefano Brivio <sbrivio(a)redhat.com> - -htools socat ip jq -nstools socat ip jq - -set TEMP_BIG __STATEDIR__/test_big.bin -set TEMP_NS_BIG __STATEDIR__/test_ns_big.bin -set TEMP_SMALL __STATEDIR__/test_small.bin -set TEMP_NS_SMALL __STATEDIR__/test_ns_small.bin - -test TCP/IPv4: host to ns: big transfer -nsb socat -u TCP4-LISTEN:10002,bind=127.0.0.1 OPEN:__TEMP_NS_BIG__,create,trunc -host socat -u OPEN:__BASEPATH__/big.bin TCP4:127.0.0.1:10002 -nsw -check cmp __BASEPATH__/big.bin __TEMP_NS_BIG__ - -test TCP/IPv4: ns to host (spliced): big transfer -hostb socat -u TCP4-LISTEN:10003,bind=127.0.0.1 OPEN:__TEMP_BIG__,create,trunc -ns socat -u OPEN:__BASEPATH__/big.bin TCP4:127.0.0.1:10003 -hostw -check cmp __BASEPATH__/big.bin __TEMP_BIG__ - -test TCP/IPv4: ns to host (via tap): big transfer -hostb socat -u TCP4-LISTEN:10003 OPEN:__TEMP_BIG__,create,trunc -nsout GW ip -j -4 route show|jq -rM '.[] | select(.dst == "default").gateway' -ns socat -u OPEN:__BASEPATH__/big.bin TCP4:__GW__:10003 -hostw -check cmp __BASEPATH__/big.bin __TEMP_BIG__ - -test TCP/IPv4: host to ns: small transfer -nsb socat -u TCP4-LISTEN:10002,bind=127.0.0.1 OPEN:__TEMP_NS_SMALL__,create,trunc -host socat OPEN:__BASEPATH__/small.bin TCP4:127.0.0.1:10002 -nsw -check cmp __BASEPATH__/small.bin __TEMP_NS_SMALL__ - -test TCP/IPv4: ns to host (spliced): small transfer -hostb socat -u TCP4-LISTEN:10003,bind=127.0.0.1 OPEN:__TEMP_SMALL__,create,trunc -ns socat OPEN:__BASEPATH__/small.bin TCP4:127.0.0.1:10003 -hostw -check cmp __BASEPATH__/small.bin __TEMP_SMALL__ - -test TCP/IPv4: ns to host (via tap): small transfer -hostb socat -u TCP4-LISTEN:10003 OPEN:__TEMP_SMALL__,create,trunc -nsout GW ip -j -4 route show|jq -rM '.[] | select(.dst == "default").gateway' -ns socat -u OPEN:__BASEPATH__/small.bin TCP4:__GW__:10003 -hostw -check cmp __BASEPATH__/small.bin __TEMP_SMALL__ - -test TCP/IPv6: host to ns: big transfer -nsb socat -u TCP6-LISTEN:10002,bind=[::1] OPEN:__TEMP_NS_BIG__,create,trunc -host socat -u OPEN:__BASEPATH__/big.bin TCP6:[::1]:10002 -nsw -check cmp __BASEPATH__/big.bin __TEMP_NS_BIG__ - -test TCP/IPv6: ns to host (spliced): big transfer -hostb socat -u TCP6-LISTEN:10003,bind=[::1] OPEN:__TEMP_BIG__,create,trunc -ns socat -u OPEN:__BASEPATH__/big.bin TCP6:[::1]:10003 -hostw -check cmp __BASEPATH__/big.bin __TEMP_BIG__ - -test TCP/IPv6: ns to host (via tap): big transfer -hostb socat -u TCP6-LISTEN:10003 OPEN:__TEMP_BIG__,create,trunc -nsout GW6 ip -j -6 route show|jq -rM '.[] | select(.dst == "default").gateway' -nsout IFNAME ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname' -ns socat -u OPEN:__BASEPATH__/big.bin TCP6:[__GW6__%__IFNAME__]:10003 -hostw -check cmp __BASEPATH__/big.bin __TEMP_BIG__ - -test TCP/IPv6: host to ns: small transfer -nsb socat -u TCP6-LISTEN:10002,bind=[::1] OPEN:__TEMP_NS_SMALL__,create,trunc -host socat -u OPEN:__BASEPATH__/small.bin TCP6:[::1]:10002 -nsw -check cmp __BASEPATH__/small.bin __TEMP_NS_SMALL__ - -test TCP/IPv6: ns to host (spliced): small transfer -hostb socat -u TCP6-LISTEN:10003,bind=[::1] OPEN:__TEMP_SMALL__,create,trunc -ns socat -u OPEN:__BASEPATH__/small.bin TCP6:[::1]:10003 -hostw -check cmp __BASEPATH__/small.bin __TEMP_SMALL__ - -test TCP/IPv6: ns to host (via tap): small transfer -hostb socat -u TCP6-LISTEN:10003 OPEN:__TEMP_SMALL__,create,trunc -ns socat -u OPEN:__BASEPATH__/small.bin TCP6:[__GW6__%__IFNAME__]:10003 -hostw -check cmp __BASEPATH__/small.bin __TEMP_SMALL__ diff --git a/test/pasta/udp b/test/pasta/udp deleted file mode 100644 index 30e3a855..00000000 --- a/test/pasta/udp +++ /dev/null @@ -1,59 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later -# -# PASST - Plug A Simple Socket Transport -# for qemu/UNIX domain socket mode -# -# PASTA - Pack A Subtle Tap Abstraction -# for network namespace/tap device mode -# -# test/pasta/udp - Check UDP functionality for pasta -# -# Copyright (c) 2021 Red Hat GmbH -# Author: Stefano Brivio <sbrivio(a)redhat.com> - -nstools socat ip jq -htools dd socat ip jq - -set TEMP __STATEDIR__/test.bin -set TEMP_NS __STATEDIR__/test_ns.bin - -test UDP/IPv4: host to ns -nsb socat -u UDP4-LISTEN:10002,bind=127.0.0.1,null-eof OPEN:__TEMP_NS__,create,trunc -host socat OPEN:__BASEPATH__/medium.bin UDP4:127.0.0.1:10002,shut-null -nsw -check cmp __BASEPATH__/medium.bin __TEMP_NS__ - -test UDP/IPv4: ns to host (recvmmsg/sendmmsg) -hostb socat -u UDP4-LISTEN:10003,bind=127.0.0.1,null-eof OPEN:__TEMP__,create,trunc -sleep 1 -ns socat OPEN:__BASEPATH__/medium.bin UDP4:127.0.0.1:10003,shut-null -hostw -check cmp __BASEPATH__/medium.bin __TEMP__ - -test UDP/IPv4: ns to host (via tap) -hostb socat -u UDP4-LISTEN:10003,null-eof OPEN:__TEMP__,create,trunc -nsout GW ip -j -4 route show|jq -rM '.[] | select(.dst == "default").gateway' -ns socat -u OPEN:__BASEPATH__/medium.bin UDP4:__GW__:10003,shut-null -hostw -check cmp __BASEPATH__/medium.bin __TEMP__ - -test UDP/IPv6: host to ns -nsb socat -u UDP6-LISTEN:10002,bind=[::1],null-eof OPEN:__TEMP_NS__,create,trunc -host socat -u OPEN:__BASEPATH__/medium.bin UDP6:[::1]:10002,shut-null -nsw -check cmp __BASEPATH__/medium.bin __TEMP_NS__ - -test UDP/IPv6: ns to host (recvmmsg/sendmmsg) -hostb socat -u UDP6-LISTEN:10003,bind=[::1],null-eof OPEN:__TEMP__,create,trunc -sleep 1 -ns socat -u OPEN:__BASEPATH__/medium.bin UDP6:[::1]:10003,shut-null -hostw -check cmp __BASEPATH__/medium.bin __TEMP__ - -test UDP/IPv6: ns to host (via tap) -hostb socat -u UDP6-LISTEN:10003,null-eof OPEN:__TEMP__,create,trunc -nsout GW6 ip -j -6 route show|jq -rM '.[] | select(.dst == "default").gateway' -nsout IFNAME ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname' -ns socat -u OPEN:__BASEPATH__/medium.bin UDP6:[__GW6__%__IFNAME__]:10003,shut-null -hostw -check cmp __BASEPATH__/medium.bin __TEMP__ diff --git a/test/run b/test/run index b8000224..f4f5fc84 100755 --- a/test/run +++ b/test/run @@ -64,14 +64,6 @@ run() { perf_init [ ${CI} -eq 1 ] && video_start ci - setup pasta - test pasta/ndp - test pasta/dhcp - test pasta/tcp - test pasta/udp - test passt/shutdown - teardown pasta - setup pasta_options test pasta_options/log_to_file teardown pasta_options diff --git a/test/tasst/dhcpv6.py b/test/tasst/dhcpv6.py index 816c0ea9..b2166224 100644 --- a/test/tasst/dhcpv6.py +++ b/test/tasst/dhcpv6.py @@ -26,13 +26,13 @@ def dhclientv6(site, ifname): def test_dhcpv6(ifname, expected_addr): def dec(setupfn): - def test_addr(setup): + def test_addr6(setup): with setup as site, dhclientv6(site, ifname): addrs = [a.ip for a in site.addrs(ifname, family='inet6', scope='global')] assert_in(expected_addr, addrs) # Might also have a SLAAC address - return test_output(test_addr)(setupfn) + return test_output(test_addr6)(setupfn) return dec diff --git a/test/tasst/pasta.py b/test/tasst/pasta.py new file mode 100644 index 00000000..80ab20b5 --- /dev/null +++ b/test/tasst/pasta.py @@ -0,0 +1,42 @@ +#! /usr/bin/python3 + +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright Red Hat +# Author: David Gibson <david(a)gibson.dropbear.id.au> + +""" +Test A Simple Socket Transport + +pasta.py - Helpers for starting pasta +""" + +import contextlib + +from tasst.exesite import Site +from tasst.typecheck import typecheck + + +PASTA_BIN = '../pasta' + + +class Pasta(contextlib.AbstractContextManager): + """A managed pasta instance""" + + def __init__(self, hostsite, pidfile, extra_args, *, ns): + self.hostsite = typecheck(hostsite, Site) + self.hostsite.require_cmds(PASTA_BIN) + self.pidfile = typecheck(pidfile, str) + self.extra_args = typecheck(extra_args, str) + self.ns = typecheck(ns, Site) + self.proc = None + + def __enter__(self): + relpid = self.ns.relative_pid(self.hostsite) + cmd = f'{PASTA_BIN} -f -P {self.pidfile} {self.extra_args} {relpid}' + self.proc = self.hostsite.bg(cmd, pidfile=self.pidfile) + self.proc.__enter__() + return self + + def __exit__(self, *exc_details): + self.proc.__exit__(*exc_details) diff --git a/test/tasst/scenario/simple.py b/test/tasst/scenario/simple.py index 503a388a..57d7b000 100644 --- a/test/tasst/scenario/simple.py +++ b/test/tasst/scenario/simple.py @@ -13,13 +13,26 @@ scenario/simple.py - Smallest sensible network to use passt/pasta import contextlib +from tasst import address from tasst.nstool import unshare_site -from tasst.address import IpiAllocator, TEST_NET_2, TEST_NET6_TASST_B from tasst.exesite import Site from tasst.transfer import test_transfers from tasst.typecheck import typecheck +IFNAME = 'veth' +HOST_NET4 = address.TEST_NET_1 +HOST_NET6 = address.TEST_NET6_TASST_A + +ipa_local = address.IpiAllocator(HOST_NET4, HOST_NET6) +(IP4, IP6) = ipa_local.next_ipis() +(GW_IP4, GW_IP6) = ipa_local.next_ipis() + +ipa_remote = address.IpiAllocator(address.TEST_NET_2, + address.TEST_NET6_TASST_B) +(REMOTE_IP4, REMOTE_IP6) = ipa_remote.next_ipis() + + class __SimpleNet: # pylint: disable=R0903 """A simple network setup scenario @@ -44,40 +57,29 @@ class __SimpleNet: # pylint: disable=R0903 """ - IFNAME = 'veth' - ipa_local = IpiAllocator() - (IP4, IP6) = ipa_local.next_ipis() - (GW_IP4, GW_IP6) = ipa_local.next_ipis() - - ipa_remote = IpiAllocator(TEST_NET_2, TEST_NET6_TASST_B) - (REMOTE_IP4, REMOTE_IP6) = ipa_remote.next_ipis() - def __init__(self, hostsite, gwsite): self.simhost = typecheck(hostsite, Site) self.gw = typecheck(gwsite, Site) - ifname = self.IFNAME - self.gw_ifname = 'gw' + ifname - self.simhost.veth(self.IFNAME, self.gw_ifname, self.gw) + self.gw_ifname = 'gw' + IFNAME + self.simhost.veth(IFNAME, self.gw_ifname, self.gw) self.gw.ifup('lo') - self.gw.ifup(self.gw_ifname, self.GW_IP4, self.GW_IP6, - self.REMOTE_IP4, self.REMOTE_IP6) + self.gw.ifup(self.gw_ifname, GW_IP4, GW_IP6, REMOTE_IP4, REMOTE_IP6) self.simhost.ifup('lo') - self.simhost.ifup(ifname, self.IP4, self.IP6) + self.simhost.ifup(IFNAME, IP4, IP6) # Once link is up on both sides, SLAAC will run self.gw_ip6_ll = self.gw.addr_wait(self.gw_ifname, family='inet6', scope='link')[0] - self.ip6_ll = self.simhost.addr_wait(ifname, + self.ip6_ll = self.simhost.addr_wait(IFNAME, family='inet6', scope='link')[0] # Set up the default route - self.simhost.fg(f'ip -4 route add default via {self.GW_IP4.ip}', - sudo=True) + self.simhost.fg(f'ip -4 route add default via {GW_IP4.ip}', sudo=True) self.simhost.fg( - f'ip -6 route add default via {self.gw_ip6_ll.ip} dev {ifname}', + f'ip -6 route add default via {self.gw_ip6_ll.ip} dev {IFNAME}', sudo=True ) @@ -89,9 +91,7 @@ def simple_net(): yield __SimpleNet(simhost, gw) -(a)test_transfers(ip4=__SimpleNet.REMOTE_IP4.ip, - ip6=__SimpleNet.REMOTE_IP6.ip, - port=10000) +(a)test_transfers(ip4=REMOTE_IP4.ip, ip6=REMOTE_IP6.ip, port=10000) @contextlib.contextmanager def simple_net_transfers(): with simple_net() as net: -- 2.41.0