* [PATCH 0/3] RFC: Preview of tunbridge based tests
@ 2025-10-02 7:57 David Gibson
2025-10-02 7:57 ` [PATCH 1/3] test: Prepare for " David Gibson
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: David Gibson @ 2025-10-02 7:57 UTC (permalink / raw)
To: passt-dev, Stefano Brivio; +Cc: David Gibson
Here's a preliminary cut at some exeter+tunbridge based test cases.
Specifically, this converts the pasta NDP tests from the existing
framework.
This is pretty unpolished at this stage, and obviously doesn't cover
much. At this stage I'm looking less for detailed review and more for
first impressions both of how the code looks for writing tests and how
the logs appear when running.
I think both have a lot of room for improvement, so I'd like to start
incorporating feedback ASAP, hence this early version.
David Gibson (3):
test: Prepare for tunbridge based tests
test: Add some missing quoting in exeter runner
test: Re-implement pasta NDP tests using tunbridge & exeter
test/.gitignore | 2 ++
test/Makefile | 19 ++++++++------
test/lib/exeter | 4 +--
test/pasta/dhcp | 5 ++++
test/pasta/ndp.py | 59 ++++++++++++++++++++++++++++++++++++++++++
test/run | 8 +++---
test/smoke/smoke.py | 26 +++++++++++++++++++
test/tasst/__init__.py | 14 ++++++++++
test/tasst/pasta.py | 40 ++++++++++++++++++++++++++++
9 files changed, 164 insertions(+), 13 deletions(-)
create mode 100755 test/pasta/ndp.py
create mode 100755 test/smoke/smoke.py
create mode 100644 test/tasst/__init__.py
create mode 100644 test/tasst/pasta.py
--
2.51.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/3] test: Prepare for tunbridge based tests
2025-10-02 7:57 [PATCH 0/3] RFC: Preview of tunbridge based tests David Gibson
@ 2025-10-02 7:57 ` David Gibson
2025-10-07 20:00 ` Stefano Brivio
2025-10-02 7:57 ` [PATCH 2/3] test: Add some missing quoting in exeter runner David Gibson
` (2 subsequent siblings)
3 siblings, 1 reply; 9+ messages in thread
From: David Gibson @ 2025-10-02 7:57 UTC (permalink / raw)
To: passt-dev, Stefano Brivio; +Cc: David Gibson
I plan to start converting many of our tests to the tunbridge[0] network
simulator framework. This is the first step: downloading and setting up
tunbridge to work within our test scripts. It also introduces a 'tasst'
Python library for code that we might want to reuse across various
tunbridge based tests.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
test/.gitignore | 2 ++
test/Makefile | 19 +++++++++++--------
test/run | 2 +-
test/smoke/smoke.py | 26 ++++++++++++++++++++++++++
test/tasst/__init__.py | 10 ++++++++++
5 files changed, 50 insertions(+), 9 deletions(-)
create mode 100755 test/smoke/smoke.py
create mode 100644 test/tasst/__init__.py
diff --git a/test/.gitignore b/test/.gitignore
index 9412f0d3..71409c51 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -12,4 +12,6 @@ rampstream
guest-key
guest-key.pub
/exeter/
+/tunbridge/
*.bats
+__pycache__/
diff --git a/test/Makefile b/test/Makefile
index 5b5f0fc1..f66c7e7e 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -54,7 +54,7 @@ UBUNTU_NEW_IMGS = xenial-server-cloudimg-powerpc-disk1.img \
jammy-server-cloudimg-s390x.img
UBUNTU_IMGS = $(UBUNTU_OLD_IMGS) $(UBUNTU_NEW_IMGS)
-DOWNLOAD_ASSETS = $(EXETOOL) mbuto podman \
+DOWNLOAD_ASSETS = $(EXETOOL) tunbridge mbuto podman \
$(DEBIAN_IMGS) $(FEDORA_IMGS) $(OPENSUSE_IMGS) $(UBUNTU_IMGS)
TESTDATA_ASSETS = small.bin big.bin medium.bin \
rampstream
@@ -65,15 +65,15 @@ LOCAL_ASSETS = mbuto.img mbuto.mem.img podman/bin/podman QEMU_EFI.fd \
ASSETS = $(DOWNLOAD_ASSETS) $(LOCAL_ASSETS)
-EXETER_PYPATH = exeter/py3
-EXETER_PYTHON = build/build.py
-EXETER_BATS = smoke/smoke.sh.bats \
- $(EXETER_PYTHON:%=%.bats) build/static_checkers.sh.bats
+EXETER_SH = smoke/smoke.sh build/static_checkers.sh
+EXETER_PYPATH = exeter/py3:tunbridge/:.
+EXETER_PYTHON = smoke/smoke.py build/build.py
+EXETER_BATS = $(EXETER_SH:%=%.bats) $(EXETER_PYTHON:%=%.bats)
BATS_FILES = $(EXETER_BATS) \
podman/test/system/505-networking-pasta.bats
# Python test code (for linters)
-PYPKGS = $(EXETER_PYTHON)
+PYPKGS = $(EXETER_PYTHON) tasst
CFLAGS = -Wall -Werror -Wextra -pedantic -std=c99
@@ -88,6 +88,9 @@ exeter:
exeter/exetool/exetool: pull-exeter
+tunbridge:
+ git clone https://gitlab.com/dgibson/tunbridge.git
+
mbuto:
git clone git://mbuto.sh/mbuto
@@ -139,7 +142,7 @@ flake8: pull-exeter
mypy: pull-exeter
PYTHONPATH=$(EXETER_PYPATH) $(MYPY) $(PYPKGS)
-$(EXETER_BATS): %.bats: % $(EXETOOL)
+$(EXETER_BATS): %.bats: % $(EXETOOL) pull-tunbridge
PYTHONPATH=$(EXETER_PYPATH) $(EXETOOL) bats -- $< > $@
bats: $(BATS_FILES) pull-podman
@@ -153,7 +156,7 @@ debug: assets
clean:
rm -f perf.js *~
- rm -rf .mypy_cache
+ rm -rf .mypy_cache __pycache__
rm -f $(LOCAL_ASSETS)
rm -f $(EXETER_BATS)
rm -rf test_logs
diff --git a/test/run b/test/run
index f858e558..3872a56e 100755
--- a/test/run
+++ b/test/run
@@ -44,7 +44,7 @@ KERNEL=${KERNEL:-"/boot/vmlinuz-$(uname -r)"}
COMMIT="$(git log --oneline --no-decorate -1)"
# Let exeter tests written in Python find their modules
-export PYTHONPATH=${BASEPATH}/exeter/py3
+export PYTHONPATH=${BASEPATH}/exeter/py3:${BASEPATH}/tunbridge:${BASEPATH}
. lib/util
. lib/context
diff --git a/test/smoke/smoke.py b/test/smoke/smoke.py
new file mode 100755
index 00000000..cbf77ad9
--- /dev/null
+++ b/test/smoke/smoke.py
@@ -0,0 +1,26 @@
+#! /usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# test/smoke/smoke.py - Python smoke tests
+#
+# Copyright Red Hat
+# Author: David Gibson <david@gibson.dropbear.id.au>
+
+import exeter
+
+
+@exeter.test
+def py_test_libraries() -> None:
+ """Check test in Python have access to the libraries we need"""
+
+ import tunbridge
+ import tasst
+
+ print(f"Imported exeter: {exeter}")
+ print(f"Imported tunbridge: {tunbridge}")
+ print(f"Imported tasst: {tasst}")
+
+
+if __name__ == '__main__':
+ exeter.main()
diff --git a/test/tasst/__init__.py b/test/tasst/__init__.py
new file mode 100644
index 00000000..fd4fe9a8
--- /dev/null
+++ b/test/tasst/__init__.py
@@ -0,0 +1,10 @@
+#! /usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# TASST - Test A Simple Socket Transport
+#
+# test/tasst/__init.py__ - Python library code useful for test cases
+#
+# Copyright Red Hat
+# Author: David Gibson <david@gibson.dropbear.id.au>
--
2.51.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/3] test: Add some missing quoting in exeter runner
2025-10-02 7:57 [PATCH 0/3] RFC: Preview of tunbridge based tests David Gibson
2025-10-02 7:57 ` [PATCH 1/3] test: Prepare for " David Gibson
@ 2025-10-02 7:57 ` David Gibson
2025-10-02 7:57 ` [PATCH 3/3] test: Re-implement pasta NDP tests using tunbridge & exeter David Gibson
2025-10-02 7:57 ` [PATCH 0/3] RFC: Preview of tunbridge based tests David Gibson
3 siblings, 0 replies; 9+ messages in thread
From: David Gibson @ 2025-10-02 7:57 UTC (permalink / raw)
To: passt-dev, Stefano Brivio; +Cc: David Gibson
exeter() quoted ${__testid}, but in some places we use it there's an
extra level of shell, which needs another layer of quoting. This breaks
if testids include ';', which is quite common in exeter tests created as
a composition/pipeline of two functions. Add the required extra quoting.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
test/lib/exeter | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/test/lib/exeter b/test/lib/exeter
index 3b19beaa..530c6909 100644
--- a/test/lib/exeter
+++ b/test/lib/exeter
@@ -47,9 +47,9 @@ exeter() {
[ ${CI} -eq 1 ] && video_link "${1}"
for __testid in $($EXETOOL list -- "$@"); do
- __desc="$($EXETOOL desc -- "$@" -- ${__testid})"
+ __desc="$($EXETOOL desc -- "$@" -- "${__testid}")"
status_test_start "${__desc}"
- context_run host "$@" "${__testid}" && status_test_ok || status_test_fail
+ context_run host "$* '${__testid}'" && status_test_ok || status_test_fail
done
cd ..
--
2.51.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 3/3] test: Re-implement pasta NDP tests using tunbridge & exeter
2025-10-02 7:57 [PATCH 0/3] RFC: Preview of tunbridge based tests David Gibson
2025-10-02 7:57 ` [PATCH 1/3] test: Prepare for " David Gibson
2025-10-02 7:57 ` [PATCH 2/3] test: Add some missing quoting in exeter runner David Gibson
@ 2025-10-02 7:57 ` David Gibson
2025-10-07 20:01 ` Stefano Brivio
2025-10-02 7:57 ` [PATCH 0/3] RFC: Preview of tunbridge based tests David Gibson
3 siblings, 1 reply; 9+ messages in thread
From: David Gibson @ 2025-10-02 7:57 UTC (permalink / raw)
To: passt-dev, Stefano Brivio; +Cc: David Gibson
Convert the pasta NDP tests from shell and our own DSL to Python using
the exeter test protocol and tunbridge network simulation library.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
test/Makefile | 2 +-
test/pasta/dhcp | 5 ++++
test/pasta/ndp.py | 59 ++++++++++++++++++++++++++++++++++++++++++
test/run | 6 +++--
test/tasst/__init__.py | 4 +++
test/tasst/pasta.py | 40 ++++++++++++++++++++++++++++
6 files changed, 113 insertions(+), 3 deletions(-)
create mode 100755 test/pasta/ndp.py
create mode 100644 test/tasst/pasta.py
diff --git a/test/Makefile b/test/Makefile
index f66c7e7e..95e3d75e 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -67,7 +67,7 @@ ASSETS = $(DOWNLOAD_ASSETS) $(LOCAL_ASSETS)
EXETER_SH = smoke/smoke.sh build/static_checkers.sh
EXETER_PYPATH = exeter/py3:tunbridge/:.
-EXETER_PYTHON = smoke/smoke.py build/build.py
+EXETER_PYTHON = smoke/smoke.py build/build.py pasta/ndp.py
EXETER_BATS = $(EXETER_SH:%=%.bats) $(EXETER_PYTHON:%=%.bats)
BATS_FILES = $(EXETER_BATS) \
podman/test/system/505-networking-pasta.bats
diff --git a/test/pasta/dhcp b/test/pasta/dhcp
index e1c66be6..61279fbf 100644
--- a/test/pasta/dhcp
+++ b/test/pasta/dhcp
@@ -18,6 +18,11 @@ test Interface name
nsout IFNAME ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname'
check [ -n "__IFNAME__" ]
+# Bring up the interface
+ns ip link set dev __IFNAME__ up
+# Wait for SLAAC & DAD to complete
+ns while ! ip -j -6 addr show dev __IFNAME__ | jq -e '.[].addr_info.[] | select(.protocol == "kernel_ra")'; do sleep 0.1; done
+
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'
diff --git a/test/pasta/ndp.py b/test/pasta/ndp.py
new file mode 100755
index 00000000..8c7ce31e
--- /dev/null
+++ b/test/pasta/ndp.py
@@ -0,0 +1,59 @@
+#! /usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# test/pasta/ndp.py - pasta NDP functionality
+#
+# Copyright Red Hat
+# Author: David Gibson <david@gibson.dropbear.id.au>
+
+import contextlib
+import dataclasses
+from typing import Iterator
+
+import exeter
+import tunbridge
+import tasst
+
+
+@dataclasses.dataclass
+class UnconfiguredScenario(exeter.Scenario):
+ """Tests for a pasta instance without --config-net"""
+
+ host: tunbridge.Site
+ guest: tunbridge.Site
+ ifname: str
+ addr6: tunbridge.ip.AddrMask6
+ gw6: tunbridge.ip.Addr6
+
+ @exeter.scenariotest
+ def test_ifname(self) -> None:
+ ifs = tunbridge.ip.ifs(self.guest)
+ exeter.assert_eq(set(ifs), {'lo', self.ifname})
+
+ @tunbridge.ndp.NdpScenario.subscenario
+ def test_ndp(self) -> tunbridge.ndp.NdpScenario:
+ tunbridge.ip.ifup(self.guest, self.ifname)
+ return tunbridge.ndp.NdpScenario(client=self.guest,
+ ifname=self.ifname,
+ network=self.addr6.network,
+ gateway=self.gw6)
+
+
+@UnconfiguredScenario.test
+@contextlib.contextmanager
+def simh_pasta_setup() -> Iterator[UnconfiguredScenario]:
+ with (tunbridge.sample.simple_host('host') as simh,
+ tunbridge.sample.isolated('guest', simh.site) as guest):
+ assert simh.ip6 is not None
+ assert simh.gw6_ll is not None
+ with tasst.pasta.pasta(simh.site, guest):
+ yield UnconfiguredScenario(host=simh.site,
+ guest=guest,
+ ifname=simh.ifname,
+ addr6=simh.ip6,
+ gw6=simh.gw6_ll)
+
+
+if __name__ == '__main__':
+ exeter.main()
diff --git a/test/run b/test/run
index 3872a56e..4f09d767 100755
--- a/test/run
+++ b/test/run
@@ -43,8 +43,10 @@ KERNEL=${KERNEL:-"/boot/vmlinuz-$(uname -r)"}
COMMIT="$(git log --oneline --no-decorate -1)"
-# Let exeter tests written in Python find their modules
+# Let exeter tests written in Python find their modules and binaries to run
export PYTHONPATH=${BASEPATH}/exeter/py3:${BASEPATH}/tunbridge:${BASEPATH}
+export PASTA=${PASTA:-${BASEPATH}/../pasta}
+
. lib/util
. lib/context
@@ -75,8 +77,8 @@ run() {
exeter build/build.py
exeter build/static_checkers.sh
+ exeter pasta/ndp.py
setup pasta
- test pasta/ndp
test pasta/dhcp
test pasta/tcp
test pasta/udp
diff --git a/test/tasst/__init__.py b/test/tasst/__init__.py
index fd4fe9a8..f5386b3a 100644
--- a/test/tasst/__init__.py
+++ b/test/tasst/__init__.py
@@ -8,3 +8,7 @@
#
# Copyright Red Hat
# Author: David Gibson <david@gibson.dropbear.id.au>
+
+from . import pasta
+
+__all__ = ['pasta']
diff --git a/test/tasst/pasta.py b/test/tasst/pasta.py
new file mode 100644
index 00000000..91f59036
--- /dev/null
+++ b/test/tasst/pasta.py
@@ -0,0 +1,40 @@
+#! /usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# TASST - Test A Simple Socket Transport
+#
+# test/tasst/pasta.py - Helpers for seeting up pasta instances
+#
+# Copyright Red Hat
+# Author: David Gibson <david@gibson.dropbear.id.au>
+
+import contextlib
+import os
+from typing import Iterator
+
+import tunbridge
+
+
+@contextlib.contextmanager
+def pasta(host: tunbridge.Site, guest: tunbridge.Site, *opts: str) \
+ -> Iterator[tunbridge.site.SiteProcess]:
+ if tunbridge.unshare.parent(guest) is not host:
+ raise ValueError("pasta guest must be a namespace under host site")
+
+ # This implies guest is a namespace site
+ assert isinstance(guest, tunbridge.unshare.NsenterSite)
+
+ exe = os.environ['PASTA']
+
+ with host.tempdir() as piddir:
+ pidfile = os.path.join(piddir, 'pasta.pid')
+ cmd = [exe, '-f', '-P', pidfile] + list(opts) + [f'{guest.pid}']
+ with host.bg(*cmd, stop=True) as pasta:
+ # Wait for the PID file to be written
+ pidstr = None
+ while not pidstr:
+ pidstr = host.readfile(pidfile, check=False)
+ pid = int(pidstr)
+ print(f'pasta started, host: {host}, guest: {guest}, pid: {pid}')
+ yield pasta
--
2.51.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/3] RFC: Preview of tunbridge based tests
2025-10-02 7:57 [PATCH 0/3] RFC: Preview of tunbridge based tests David Gibson
` (2 preceding siblings ...)
2025-10-02 7:57 ` [PATCH 3/3] test: Re-implement pasta NDP tests using tunbridge & exeter David Gibson
@ 2025-10-02 7:57 ` David Gibson
3 siblings, 0 replies; 9+ messages in thread
From: David Gibson @ 2025-10-02 7:57 UTC (permalink / raw)
To: passt-dev, Stefano Brivio
[-- Attachment #1: Type: text/plain, Size: 920 bytes --]
On Thu, Oct 02, 2025 at 05:57:05PM +1000, David Gibson wrote:
> Here's a preliminary cut at some exeter+tunbridge based test cases.
> Specifically, this converts the pasta NDP tests from the existing
> framework.
>
> This is pretty unpolished at this stage, and obviously doesn't cover
> much. At this stage I'm looking less for detailed review and more for
> first impressions both of how the code looks for writing tests and how
> the logs appear when running.
>
> I think both have a lot of room for improvement, so I'd like to start
> incorporating feedback ASAP, hence this early version.
Forgot to add, this series is based on the series of small test
Makefile and linter fixups I posted earlier.
--
David Gibson (he or they) | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you, not the other way
| around.
http://www.ozlabs.org/~dgibson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/3] test: Prepare for tunbridge based tests
2025-10-02 7:57 ` [PATCH 1/3] test: Prepare for " David Gibson
@ 2025-10-07 20:00 ` Stefano Brivio
2025-10-08 1:27 ` David Gibson
0 siblings, 1 reply; 9+ messages in thread
From: Stefano Brivio @ 2025-10-07 20:00 UTC (permalink / raw)
To: David Gibson; +Cc: passt-dev
One nit only (given it's a RFC...):
On Thu, 2 Oct 2025 17:57:06 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:
> I plan to start converting many of our tests to the tunbridge[0] network
> simulator framework. This is the first step: downloading and setting up
> tunbridge to work within our test scripts. It also introduces a 'tasst'
> Python library for code that we might want to reuse across various
> tunbridge based tests.
>
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
> test/.gitignore | 2 ++
> test/Makefile | 19 +++++++++++--------
> test/run | 2 +-
> test/smoke/smoke.py | 26 ++++++++++++++++++++++++++
> test/tasst/__init__.py | 10 ++++++++++
> 5 files changed, 50 insertions(+), 9 deletions(-)
> create mode 100755 test/smoke/smoke.py
> create mode 100644 test/tasst/__init__.py
>
> diff --git a/test/.gitignore b/test/.gitignore
> index 9412f0d3..71409c51 100644
> --- a/test/.gitignore
> +++ b/test/.gitignore
> @@ -12,4 +12,6 @@ rampstream
> guest-key
> guest-key.pub
> /exeter/
> +/tunbridge/
> *.bats
> +__pycache__/
> diff --git a/test/Makefile b/test/Makefile
> index 5b5f0fc1..f66c7e7e 100644
> --- a/test/Makefile
> +++ b/test/Makefile
> @@ -54,7 +54,7 @@ UBUNTU_NEW_IMGS = xenial-server-cloudimg-powerpc-disk1.img \
> jammy-server-cloudimg-s390x.img
> UBUNTU_IMGS = $(UBUNTU_OLD_IMGS) $(UBUNTU_NEW_IMGS)
>
> -DOWNLOAD_ASSETS = $(EXETOOL) mbuto podman \
> +DOWNLOAD_ASSETS = $(EXETOOL) tunbridge mbuto podman \
> $(DEBIAN_IMGS) $(FEDORA_IMGS) $(OPENSUSE_IMGS) $(UBUNTU_IMGS)
> TESTDATA_ASSETS = small.bin big.bin medium.bin \
> rampstream
> @@ -65,15 +65,15 @@ LOCAL_ASSETS = mbuto.img mbuto.mem.img podman/bin/podman QEMU_EFI.fd \
>
> ASSETS = $(DOWNLOAD_ASSETS) $(LOCAL_ASSETS)
>
> -EXETER_PYPATH = exeter/py3
> -EXETER_PYTHON = build/build.py
> -EXETER_BATS = smoke/smoke.sh.bats \
> - $(EXETER_PYTHON:%=%.bats) build/static_checkers.sh.bats
> +EXETER_SH = smoke/smoke.sh build/static_checkers.sh
> +EXETER_PYPATH = exeter/py3:tunbridge/:.
> +EXETER_PYTHON = smoke/smoke.py build/build.py
> +EXETER_BATS = $(EXETER_SH:%=%.bats) $(EXETER_PYTHON:%=%.bats)
> BATS_FILES = $(EXETER_BATS) \
> podman/test/system/505-networking-pasta.bats
>
> # Python test code (for linters)
> -PYPKGS = $(EXETER_PYTHON)
> +PYPKGS = $(EXETER_PYTHON) tasst
>
> CFLAGS = -Wall -Werror -Wextra -pedantic -std=c99
>
> @@ -88,6 +88,9 @@ exeter:
>
> exeter/exetool/exetool: pull-exeter
>
> +tunbridge:
> + git clone https://gitlab.com/dgibson/tunbridge.git
> +
> mbuto:
> git clone git://mbuto.sh/mbuto
>
> @@ -139,7 +142,7 @@ flake8: pull-exeter
> mypy: pull-exeter
> PYTHONPATH=$(EXETER_PYPATH) $(MYPY) $(PYPKGS)
>
> -$(EXETER_BATS): %.bats: % $(EXETOOL)
> +$(EXETER_BATS): %.bats: % $(EXETOOL) pull-tunbridge
> PYTHONPATH=$(EXETER_PYPATH) $(EXETOOL) bats -- $< > $@
>
> bats: $(BATS_FILES) pull-podman
> @@ -153,7 +156,7 @@ debug: assets
>
> clean:
> rm -f perf.js *~
> - rm -rf .mypy_cache
> + rm -rf .mypy_cache __pycache__
> rm -f $(LOCAL_ASSETS)
> rm -f $(EXETER_BATS)
> rm -rf test_logs
> diff --git a/test/run b/test/run
> index f858e558..3872a56e 100755
> --- a/test/run
> +++ b/test/run
> @@ -44,7 +44,7 @@ KERNEL=${KERNEL:-"/boot/vmlinuz-$(uname -r)"}
> COMMIT="$(git log --oneline --no-decorate -1)"
>
> # Let exeter tests written in Python find their modules
> -export PYTHONPATH=${BASEPATH}/exeter/py3
> +export PYTHONPATH=${BASEPATH}/exeter/py3:${BASEPATH}/tunbridge:${BASEPATH}
>
> . lib/util
> . lib/context
> diff --git a/test/smoke/smoke.py b/test/smoke/smoke.py
> new file mode 100755
> index 00000000..cbf77ad9
> --- /dev/null
> +++ b/test/smoke/smoke.py
> @@ -0,0 +1,26 @@
> +#! /usr/bin/env python3
> +#
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +#
> +# test/smoke/smoke.py - Python smoke tests
> +#
> +# Copyright Red Hat
> +# Author: David Gibson <david@gibson.dropbear.id.au>
> +
> +import exeter
> +
> +
> +@exeter.test
> +def py_test_libraries() -> None:
> + """Check test in Python have access to the libraries we need"""
tests
--
Stefano
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 3/3] test: Re-implement pasta NDP tests using tunbridge & exeter
2025-10-02 7:57 ` [PATCH 3/3] test: Re-implement pasta NDP tests using tunbridge & exeter David Gibson
@ 2025-10-07 20:01 ` Stefano Brivio
2025-10-08 2:32 ` David Gibson
0 siblings, 1 reply; 9+ messages in thread
From: Stefano Brivio @ 2025-10-07 20:01 UTC (permalink / raw)
To: David Gibson; +Cc: passt-dev
On Thu, 2 Oct 2025 17:57:08 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:
> Convert the pasta NDP tests from shell and our own DSL to Python using
> the exeter test protocol and tunbridge network simulation library.
>
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
> test/Makefile | 2 +-
> test/pasta/dhcp | 5 ++++
> test/pasta/ndp.py | 59 ++++++++++++++++++++++++++++++++++++++++++
> test/run | 6 +++--
> test/tasst/__init__.py | 4 +++
> test/tasst/pasta.py | 40 ++++++++++++++++++++++++++++
> 6 files changed, 113 insertions(+), 3 deletions(-)
> create mode 100755 test/pasta/ndp.py
> create mode 100644 test/tasst/pasta.py
>
> diff --git a/test/Makefile b/test/Makefile
> index f66c7e7e..95e3d75e 100644
> --- a/test/Makefile
> +++ b/test/Makefile
> @@ -67,7 +67,7 @@ ASSETS = $(DOWNLOAD_ASSETS) $(LOCAL_ASSETS)
>
> EXETER_SH = smoke/smoke.sh build/static_checkers.sh
> EXETER_PYPATH = exeter/py3:tunbridge/:.
> -EXETER_PYTHON = smoke/smoke.py build/build.py
> +EXETER_PYTHON = smoke/smoke.py build/build.py pasta/ndp.py
> EXETER_BATS = $(EXETER_SH:%=%.bats) $(EXETER_PYTHON:%=%.bats)
> BATS_FILES = $(EXETER_BATS) \
> podman/test/system/505-networking-pasta.bats
> diff --git a/test/pasta/dhcp b/test/pasta/dhcp
> index e1c66be6..61279fbf 100644
> --- a/test/pasta/dhcp
> +++ b/test/pasta/dhcp
> @@ -18,6 +18,11 @@ test Interface name
> nsout IFNAME ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname'
> check [ -n "__IFNAME__" ]
>
> +# Bring up the interface
> +ns ip link set dev __IFNAME__ up
> +# Wait for SLAAC & DAD to complete
> +ns while ! ip -j -6 addr show dev __IFNAME__ | jq -e '.[].addr_info.[] | select(.protocol == "kernel_ra")'; do sleep 0.1; done
> +
> 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'
> diff --git a/test/pasta/ndp.py b/test/pasta/ndp.py
> new file mode 100755
> index 00000000..8c7ce31e
> --- /dev/null
> +++ b/test/pasta/ndp.py
> @@ -0,0 +1,59 @@
> +#! /usr/bin/env python3
> +#
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +#
> +# test/pasta/ndp.py - pasta NDP functionality
> +#
> +# Copyright Red Hat
> +# Author: David Gibson <david@gibson.dropbear.id.au>
> +
> +import contextlib
> +import dataclasses
> +from typing import Iterator
> +
> +import exeter
> +import tunbridge
> +import tasst
> +
> +
> +@dataclasses.dataclass
> +class UnconfiguredScenario(exeter.Scenario):
> + """Tests for a pasta instance without --config-net"""
> +
> + host: tunbridge.Site
> + guest: tunbridge.Site
> + ifname: str
> + addr6: tunbridge.ip.AddrMask6
> + gw6: tunbridge.ip.Addr6
Until this point, it looks like stuff I can happily copy and paste,
and grasp, even. But then:
> + @exeter.scenariotest
> + def test_ifname(self) -> None:
> + ifs = tunbridge.ip.ifs(self.guest)
> + exeter.assert_eq(set(ifs), {'lo', self.ifname})
...why does a "Scenario" have a .ifname?
> +
> + @tunbridge.ndp.NdpScenario.subscenario
> + def test_ndp(self) -> tunbridge.ndp.NdpScenario:
> + tunbridge.ip.ifup(self.guest, self.ifname)
This raises the question of how much of tunbridge one needs to know to
be able to write a basic test. Why is ifup() in 'ip'? I thought it
would be more of a "link" thing.
I admit I haven't had time to browse tunbridge recently, I'm just
looking at this series right now.
> + return tunbridge.ndp.NdpScenario(client=self.guest,
> + ifname=self.ifname,
> + network=self.addr6.network,
> + gateway=self.gw6)
This makes sense to me.
> +
> +
> +@UnconfiguredScenario.test
> +@contextlib.contextmanager
> +def simh_pasta_setup() -> Iterator[UnconfiguredScenario]:
> + with (tunbridge.sample.simple_host('host') as simh,
> + tunbridge.sample.isolated('guest', simh.site) as guest):
> + assert simh.ip6 is not None
> + assert simh.gw6_ll is not None
> + with tasst.pasta.pasta(simh.site, guest):
> + yield UnconfiguredScenario(host=simh.site,
> + guest=guest,
> + ifname=simh.ifname,
> + addr6=simh.ip6,
> + gw6=simh.gw6_ll)
...and this too.
But there's one thing I'm missing: if it's a network simulator, why do
you need to call a simple_host() method to *describe* the fact that you
have a host / site? That looks rather unexpected.
I mean, I would have expected a syntax, in pseudocode, expressing:
1. x := node (properties such as a list of interfaces a, b, c)
2. pasta implements/connects a
...I think this is mostly embedded in the sample.simple_host() thing,
but I'm not sure how. Maybe it will become clearer once I actually look
into tunbridge, though.
Of course, I'm trying to push away my bias coming from the fact I was,
several years ago, for kselftests, aiming at something like this
instead:
A veth B
x=$(addr A veth)
B ping -c1 $x
A $x vxlan B $(addr B veth)
...
(where 'veth', 'vxlan' were both reserved keywords). Maybe once
non-trivial links are implemented in tunbridge it will all become more
obvious.
> +
> +
> +if __name__ == '__main__':
> + exeter.main()
> diff --git a/test/run b/test/run
> index 3872a56e..4f09d767 100755
> --- a/test/run
> +++ b/test/run
> @@ -43,8 +43,10 @@ KERNEL=${KERNEL:-"/boot/vmlinuz-$(uname -r)"}
>
> COMMIT="$(git log --oneline --no-decorate -1)"
>
> -# Let exeter tests written in Python find their modules
> +# Let exeter tests written in Python find their modules and binaries to run
> export PYTHONPATH=${BASEPATH}/exeter/py3:${BASEPATH}/tunbridge:${BASEPATH}
> +export PASTA=${PASTA:-${BASEPATH}/../pasta}
> +
>
> . lib/util
> . lib/context
> @@ -75,8 +77,8 @@ run() {
> exeter build/build.py
> exeter build/static_checkers.sh
>
> + exeter pasta/ndp.py
> setup pasta
> - test pasta/ndp
> test pasta/dhcp
> test pasta/tcp
> test pasta/udp
> diff --git a/test/tasst/__init__.py b/test/tasst/__init__.py
> index fd4fe9a8..f5386b3a 100644
> --- a/test/tasst/__init__.py
> +++ b/test/tasst/__init__.py
> @@ -8,3 +8,7 @@
> #
> # Copyright Red Hat
> # Author: David Gibson <david@gibson.dropbear.id.au>
> +
> +from . import pasta
> +
> +__all__ = ['pasta']
> diff --git a/test/tasst/pasta.py b/test/tasst/pasta.py
> new file mode 100644
> index 00000000..91f59036
> --- /dev/null
> +++ b/test/tasst/pasta.py
> @@ -0,0 +1,40 @@
> +#! /usr/bin/env python3
> +#
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +#
> +# TASST - Test A Simple Socket Transport
> +#
> +# test/tasst/pasta.py - Helpers for seeting up pasta instances
> +#
> +# Copyright Red Hat
> +# Author: David Gibson <david@gibson.dropbear.id.au>
> +
> +import contextlib
> +import os
> +from typing import Iterator
> +
> +import tunbridge
> +
> +
> +@contextlib.contextmanager
> +def pasta(host: tunbridge.Site, guest: tunbridge.Site, *opts: str) \
> + -> Iterator[tunbridge.site.SiteProcess]:
> + if tunbridge.unshare.parent(guest) is not host:
> + raise ValueError("pasta guest must be a namespace under host site")
> +
> + # This implies guest is a namespace site
> + assert isinstance(guest, tunbridge.unshare.NsenterSite)
> +
> + exe = os.environ['PASTA']
> +
> + with host.tempdir() as piddir:
> + pidfile = os.path.join(piddir, 'pasta.pid')
> + cmd = [exe, '-f', '-P', pidfile] + list(opts) + [f'{guest.pid}']
> + with host.bg(*cmd, stop=True) as pasta:
> + # Wait for the PID file to be written
> + pidstr = None
> + while not pidstr:
> + pidstr = host.readfile(pidfile, check=False)
> + pid = int(pidstr)
> + print(f'pasta started, host: {host}, guest: {guest}, pid: {pid}')
> + yield pasta
...perhaps we could also print version and path. This part also looks
quite readable and intuitive to me without having looked into tunbridge
recently.
--
Stefano
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/3] test: Prepare for tunbridge based tests
2025-10-07 20:00 ` Stefano Brivio
@ 2025-10-08 1:27 ` David Gibson
0 siblings, 0 replies; 9+ messages in thread
From: David Gibson @ 2025-10-08 1:27 UTC (permalink / raw)
To: Stefano Brivio; +Cc: passt-dev
[-- Attachment #1: Type: text/plain, Size: 1027 bytes --]
On Tue, Oct 07, 2025 at 10:00:51PM +0200, Stefano Brivio wrote:
> One nit only (given it's a RFC...):
>
> On Thu, 2 Oct 2025 17:57:06 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
[snip]
> > diff --git a/test/smoke/smoke.py b/test/smoke/smoke.py
> > new file mode 100755
> > index 00000000..cbf77ad9
> > --- /dev/null
> > +++ b/test/smoke/smoke.py
> > @@ -0,0 +1,26 @@
> > +#! /usr/bin/env python3
> > +#
> > +# SPDX-License-Identifier: GPL-2.0-or-later
> > +#
> > +# test/smoke/smoke.py - Python smoke tests
> > +#
> > +# Copyright Red Hat
> > +# Author: David Gibson <david@gibson.dropbear.id.au>
> > +
> > +import exeter
> > +
> > +
> > +@exeter.test
> > +def py_test_libraries() -> None:
> > + """Check test in Python have access to the libraries we need"""
>
> tests
Fixed.
--
David Gibson (he or they) | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you, not the other way
| around.
http://www.ozlabs.org/~dgibson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 3/3] test: Re-implement pasta NDP tests using tunbridge & exeter
2025-10-07 20:01 ` Stefano Brivio
@ 2025-10-08 2:32 ` David Gibson
0 siblings, 0 replies; 9+ messages in thread
From: David Gibson @ 2025-10-08 2:32 UTC (permalink / raw)
To: Stefano Brivio; +Cc: passt-dev
[-- Attachment #1: Type: text/plain, Size: 12364 bytes --]
On Tue, Oct 07, 2025 at 10:01:10PM +0200, Stefano Brivio wrote:
> On Thu, 2 Oct 2025 17:57:08 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
>
> > Convert the pasta NDP tests from shell and our own DSL to Python using
> > the exeter test protocol and tunbridge network simulation library.
> >
> > Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> > ---
> > test/Makefile | 2 +-
> > test/pasta/dhcp | 5 ++++
> > test/pasta/ndp.py | 59 ++++++++++++++++++++++++++++++++++++++++++
> > test/run | 6 +++--
> > test/tasst/__init__.py | 4 +++
> > test/tasst/pasta.py | 40 ++++++++++++++++++++++++++++
> > 6 files changed, 113 insertions(+), 3 deletions(-)
> > create mode 100755 test/pasta/ndp.py
> > create mode 100644 test/tasst/pasta.py
> >
> > diff --git a/test/Makefile b/test/Makefile
> > index f66c7e7e..95e3d75e 100644
> > --- a/test/Makefile
> > +++ b/test/Makefile
> > @@ -67,7 +67,7 @@ ASSETS = $(DOWNLOAD_ASSETS) $(LOCAL_ASSETS)
> >
> > EXETER_SH = smoke/smoke.sh build/static_checkers.sh
> > EXETER_PYPATH = exeter/py3:tunbridge/:.
> > -EXETER_PYTHON = smoke/smoke.py build/build.py
> > +EXETER_PYTHON = smoke/smoke.py build/build.py pasta/ndp.py
> > EXETER_BATS = $(EXETER_SH:%=%.bats) $(EXETER_PYTHON:%=%.bats)
> > BATS_FILES = $(EXETER_BATS) \
> > podman/test/system/505-networking-pasta.bats
> > diff --git a/test/pasta/dhcp b/test/pasta/dhcp
> > index e1c66be6..61279fbf 100644
> > --- a/test/pasta/dhcp
> > +++ b/test/pasta/dhcp
> > @@ -18,6 +18,11 @@ test Interface name
> > nsout IFNAME ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname'
> > check [ -n "__IFNAME__" ]
> >
> > +# Bring up the interface
> > +ns ip link set dev __IFNAME__ up
> > +# Wait for SLAAC & DAD to complete
> > +ns while ! ip -j -6 addr show dev __IFNAME__ | jq -e '.[].addr_info.[] | select(.protocol == "kernel_ra")'; do sleep 0.1; done
> > +
> > 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'
> > diff --git a/test/pasta/ndp.py b/test/pasta/ndp.py
> > new file mode 100755
> > index 00000000..8c7ce31e
> > --- /dev/null
> > +++ b/test/pasta/ndp.py
> > @@ -0,0 +1,59 @@
> > +#! /usr/bin/env python3
> > +#
> > +# SPDX-License-Identifier: GPL-2.0-or-later
> > +#
> > +# test/pasta/ndp.py - pasta NDP functionality
> > +#
> > +# Copyright Red Hat
> > +# Author: David Gibson <david@gibson.dropbear.id.au>
> > +
> > +import contextlib
> > +import dataclasses
> > +from typing import Iterator
> > +
> > +import exeter
> > +import tunbridge
> > +import tasst
> > +
> > +
> > +@dataclasses.dataclass
> > +class UnconfiguredScenario(exeter.Scenario):
> > + """Tests for a pasta instance without --config-net"""
> > +
> > + host: tunbridge.Site
> > + guest: tunbridge.Site
> > + ifname: str
> > + addr6: tunbridge.ip.AddrMask6
> > + gw6: tunbridge.ip.Addr6
>
> Until this point, it looks like stuff I can happily copy and paste,
> and grasp, even. But then:
>
> > + @exeter.scenariotest
> > + def test_ifname(self) -> None:
> > + ifs = tunbridge.ip.ifs(self.guest)
> > + exeter.assert_eq(set(ifs), {'lo', self.ifname})
>
> ...why does a "Scenario" have a .ifname?
Yeah, the readability of the Scenario mechanism was something I was
particularly concerned about. I think the concept is valuable, but
I'm very open to different ways of naming or organising it, if we can
up with something better.
A "Scenario" (specifically a subclass of exeter.Scenario) is a group
of tests with a common set of parameters. In this case
UnconfiguredScenario is a bunch of tests about the behaviour of pasta
without --config-net. Each of those tests has access to the host and
guest sites, the expected interface name, address and gateway in the
guest - that is, the contents of an UncofiguredScenario instance.
That instance describes a real (simulated) environment in which we can
run those tests.
You use this by supplying a function which sets things up, then yields
an UnconfiguredScenario instance describing what it set up. exeter
will run all of the UnconfiguredScenario tests on the environment the
setup function created, each one as a separate test case.
Usually, there are multiple ways to set up a suitable enviroment:
running pasta with an existing guest ns vs. pasta creating the ns is a
simple example. You can create different setup functions for each of
those, and re-use all the tests in the Scenario against each of those
setups.
> > +
> > + @tunbridge.ndp.NdpScenario.subscenario
> > + def test_ndp(self) -> tunbridge.ndp.NdpScenario:
> > + tunbridge.ip.ifup(self.guest, self.ifname)
>
> This raises the question of how much of tunbridge one needs to know to
> be able to write a basic test. Why is ifup() in 'ip'? I thought it
> would be more of a "link" thing.
Finding misleading names is a big reason for seeking early feedback.
There's kind of a reason for ifup to be in ip: it optionally takes IP
addresses to configure on the interface. But... there's no inherent
reason it couldn't take other sorts of network address too, so I'll
look into moving that into a "link" module or something like it.
> I admit I haven't had time to browse tunbridge recently, I'm just
> looking at this series right now.
That's fine. At some point it would be good to have you look at
tunbridge too, but reading this series _without_ reading tunbridge is
a very useful perspective at this stage.
>
> > + return tunbridge.ndp.NdpScenario(client=self.guest,
> > + ifname=self.ifname,
> > + network=self.addr6.network,
> > + gateway=self.gw6)
>
> This makes sense to me.
Ok, good. The Scenario stuff might not be as impenetrable as I
feared.
> > +
> > +
> > +@UnconfiguredScenario.test
> > +@contextlib.contextmanager
> > +def simh_pasta_setup() -> Iterator[UnconfiguredScenario]:
> > + with (tunbridge.sample.simple_host('host') as simh,
> > + tunbridge.sample.isolated('guest', simh.site) as guest):
> > + assert simh.ip6 is not None
> > + assert simh.gw6_ll is not None
> > + with tasst.pasta.pasta(simh.site, guest):
> > + yield UnconfiguredScenario(host=simh.site,
> > + guest=guest,
> > + ifname=simh.ifname,
> > + addr6=simh.ip6,
> > + gw6=simh.gw6_ll)
>
> ...and this too.
>
> But there's one thing I'm missing: if it's a network simulator, why do
> you need to call a simple_host() method to *describe* the fact that you
> have a host / site? That looks rather unexpected.
>
> I mean, I would have expected a syntax, in pseudocode, expressing:
>
> 1. x := node (properties such as a list of interfaces a, b, c)
>
> 2. pasta implements/connects a
>
> ...I think this is mostly embedded in the sample.simple_host() thing,
> but I'm not sure how. Maybe it will become clearer once I actually look
> into tunbridge, though.
Right. "simple_host" isn't just an arbitrary node, but a (small)
predefined network topology: a node configured with a single default
gateway (also simulated, albeit minimally) - that is, the "classic"
pasta host. The idea is that the tunbridge.sample module will have a
bunch of such example networks - so far there's:
- isolated() (node with loopback only)
- back_to_back() (two nodes connected by a veth)
- simple_host()
Suggestions for better names welcome, as always.
> Of course, I'm trying to push away my bias coming from the fact I was,
> several years ago, for kselftests, aiming at something like this
> instead:
>
> A veth B
> x=$(addr A veth)
> B ping -c1 $x
> A $x vxlan B $(addr B veth)
> ...
>
> (where 'veth', 'vxlan' were both reserved keywords). Maybe once
> non-trivial links are implemented in tunbridge it will all become more
> obvious.
I think tunbridge is not dissimilar to this, though with functions
rather than reserved words. It's a bit hidden here, because we're
using these pre-built chunks - I expect that would be the case for
your system as well, once you get to complex enough setups that you
want to re-use non-trivial pieces.
For example the guts of back_to_back() is:
with isolated(f'{name}0', sb) as s0, \
isolated(f'{name}1', sb) as s1:
if0, if1 = f'veth{name}0', f'veth{name}1'
with veth.veth(s0, if0, s1, if1):
...
There's more, but that's mostly about IP allocation (it optionally
does that).
> > +
> > +
> > +if __name__ == '__main__':
> > + exeter.main()
> > diff --git a/test/run b/test/run
> > index 3872a56e..4f09d767 100755
> > --- a/test/run
> > +++ b/test/run
> > @@ -43,8 +43,10 @@ KERNEL=${KERNEL:-"/boot/vmlinuz-$(uname -r)"}
> >
> > COMMIT="$(git log --oneline --no-decorate -1)"
> >
> > -# Let exeter tests written in Python find their modules
> > +# Let exeter tests written in Python find their modules and binaries to run
> > export PYTHONPATH=${BASEPATH}/exeter/py3:${BASEPATH}/tunbridge:${BASEPATH}
> > +export PASTA=${PASTA:-${BASEPATH}/../pasta}
> > +
> >
> > . lib/util
> > . lib/context
> > @@ -75,8 +77,8 @@ run() {
> > exeter build/build.py
> > exeter build/static_checkers.sh
> >
> > + exeter pasta/ndp.py
> > setup pasta
> > - test pasta/ndp
> > test pasta/dhcp
> > test pasta/tcp
> > test pasta/udp
> > diff --git a/test/tasst/__init__.py b/test/tasst/__init__.py
> > index fd4fe9a8..f5386b3a 100644
> > --- a/test/tasst/__init__.py
> > +++ b/test/tasst/__init__.py
> > @@ -8,3 +8,7 @@
> > #
> > # Copyright Red Hat
> > # Author: David Gibson <david@gibson.dropbear.id.au>
> > +
> > +from . import pasta
> > +
> > +__all__ = ['pasta']
> > diff --git a/test/tasst/pasta.py b/test/tasst/pasta.py
> > new file mode 100644
> > index 00000000..91f59036
> > --- /dev/null
> > +++ b/test/tasst/pasta.py
> > @@ -0,0 +1,40 @@
> > +#! /usr/bin/env python3
> > +#
> > +# SPDX-License-Identifier: GPL-2.0-or-later
> > +#
> > +# TASST - Test A Simple Socket Transport
> > +#
> > +# test/tasst/pasta.py - Helpers for seeting up pasta instances
> > +#
> > +# Copyright Red Hat
> > +# Author: David Gibson <david@gibson.dropbear.id.au>
> > +
> > +import contextlib
> > +import os
> > +from typing import Iterator
> > +
> > +import tunbridge
> > +
> > +
> > +@contextlib.contextmanager
> > +def pasta(host: tunbridge.Site, guest: tunbridge.Site, *opts: str) \
> > + -> Iterator[tunbridge.site.SiteProcess]:
> > + if tunbridge.unshare.parent(guest) is not host:
> > + raise ValueError("pasta guest must be a namespace under host site")
> > +
> > + # This implies guest is a namespace site
> > + assert isinstance(guest, tunbridge.unshare.NsenterSite)
> > +
> > + exe = os.environ['PASTA']
> > +
> > + with host.tempdir() as piddir:
> > + pidfile = os.path.join(piddir, 'pasta.pid')
> > + cmd = [exe, '-f', '-P', pidfile] + list(opts) + [f'{guest.pid}']
> > + with host.bg(*cmd, stop=True) as pasta:
> > + # Wait for the PID file to be written
> > + pidstr = None
> > + while not pidstr:
> > + pidstr = host.readfile(pidfile, check=False)
> > + pid = int(pidstr)
> > + print(f'pasta started, host: {host}, guest: {guest}, pid: {pid}')
> > + yield pasta
>
> ...perhaps we could also print version and path.
Path I can easily add. Version would require an extra invocation of
pasta, which I don't really want to do.
> This part also looks
> quite readable and intuitive to me without having looked into tunbridge
> recently.
Ok, that's promising.
--
David Gibson (he or they) | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you, not the other way
| around.
http://www.ozlabs.org/~dgibson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-10-08 2:32 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-10-02 7:57 [PATCH 0/3] RFC: Preview of tunbridge based tests David Gibson
2025-10-02 7:57 ` [PATCH 1/3] test: Prepare for " David Gibson
2025-10-07 20:00 ` Stefano Brivio
2025-10-08 1:27 ` David Gibson
2025-10-02 7:57 ` [PATCH 2/3] test: Add some missing quoting in exeter runner David Gibson
2025-10-02 7:57 ` [PATCH 3/3] test: Re-implement pasta NDP tests using tunbridge & exeter David Gibson
2025-10-07 20:01 ` Stefano Brivio
2025-10-08 2:32 ` David Gibson
2025-10-02 7:57 ` [PATCH 0/3] RFC: Preview of tunbridge based tests David Gibson
Code repositories for project(s) associated with this public inbox
https://passt.top/passt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).