From 76601fd587744e09fa375b37b79ee0bafc6dbb94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Tue, 21 Jan 2025 05:14:48 +0100 Subject: [PATCH 1/6] tests: don't let the repo server process steal stdin The repo server process shouldn't get the stdin connected. Otherwise it may (and will) steal key presses meant for the test runner itself. --- qubes/tests/integ/dom0_update.py | 1 + qubes/tests/integ/vm_update.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/qubes/tests/integ/dom0_update.py b/qubes/tests/integ/dom0_update.py index d57f265ec..247c4c292 100644 --- a/qubes/tests/integ/dom0_update.py +++ b/qubes/tests/integ/dom0_update.py @@ -276,6 +276,7 @@ def start_repo(self): self.repo_proc = self.loop.run_until_complete( self.updatevm.run( "cd /tmp/repo && python3 -m http.server 8080", + stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, ) diff --git a/qubes/tests/integ/vm_update.py b/qubes/tests/integ/vm_update.py index 3d661b2db..fe9e223a2 100644 --- a/qubes/tests/integ/vm_update.py +++ b/qubes/tests/integ/vm_update.py @@ -390,6 +390,7 @@ def create_repo_and_serve(self): self.repo_proc = self.loop.run_until_complete( self.netvm_repo.run( "cd /tmp/apt-repo && python3 -m http.server 8080", + stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, ) @@ -399,6 +400,7 @@ def create_repo_and_serve(self): self.repo_proc = self.loop.run_until_complete( self.netvm_repo.run( "cd /tmp/yum-repo && python3 -m http.server 8080", + stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, ) From c63dc03b1d785888c927153d67950daedd8b8505 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Tue, 21 Jan 2025 05:15:48 +0100 Subject: [PATCH 2/6] tests: add support for testing updates of Archlinux template --- qubes/tests/integ/vm_update.py | 100 +++++++++++++++++++++++++++++++-- 1 file changed, 96 insertions(+), 4 deletions(-) diff --git a/qubes/tests/integ/vm_update.py b/qubes/tests/integ/vm_update.py index fe9e223a2..8755a095a 100644 --- a/qubes/tests/integ/vm_update.py +++ b/qubes/tests/integ/vm_update.py @@ -158,6 +158,23 @@ class VmUpdatesMixin(object): ), ] + ARCH_PACKAGE = [ + ( + b"pkgname=test-pkg\n" + b"pkgver=1.0\n" + b"pkgrel=1\n" + b"arch=(any)\n" + b'options=("!debug")\n' + ), + ( + b"pkgname=test-pkg\n" + b"pkgver=1.1\n" + b"pkgrel=1\n" + b"arch=(any)\n" + b'options=("!debug")\n' + ), + ] + @classmethod def setUpClass(cls): super(VmUpdatesMixin, cls).setUpClass() @@ -200,8 +217,10 @@ def setUp(self): """ :type self: qubes.tests.SystemTestCase | VmUpdatesMixin """ - if not self.template.count("debian") and not self.template.count( - "fedora" + if ( + not self.template.count("debian") + and not self.template.count("fedora") + and not self.template.count("archlinux") ): self.skipTest( "Template {} not supported by this test".format(self.template) @@ -235,6 +254,13 @@ def setUp(self): self.install_test_cmd = "rpm -q {}" self.upgrade_test_cmd = "rpm -q {} | grep 1.1" self.ret_code_ok = [0, 100] + elif self.template.count("archlinux"): + self.update_cmd = "pacman -Syy" + self.upgrade_cmd = "pacman -Syu --noconfirm" + self.install_cmd = "pacman -Sy --noconfirm {}" + self.install_test_cmd = "pacman -Q {}" + self.upgrade_test_cmd = "pacman -Q {} | grep 1.1" + self.ret_code_ok = [0] self.init_default_template(self.template) self.init_networking() @@ -381,6 +407,34 @@ def create_repo_yum(self, version=0): self.netvm_repo.run_for_stdio("createrepo_c /tmp/yum-repo") ) + def create_repo_arch(self, version=0): + """ + :type self: qubes.tests.SystemTestCase | VmUpdatesMixin + :type version: int + """ + self.loop.run_until_complete( + self.netvm_repo.run_for_stdio( + """mkdir -p /tmp/pkg \ + && cd /tmp/pkg \ + && cat > PKGBUILD \ + && makepkg""", + input=self.ARCH_PACKAGE[version], + ) + ) + pkg_file_name = "test-pkg-1.{}-1-any.pkg.tar.zst".format(version) + self.loop.run_until_complete( + self.netvm_repo.run_for_stdio( + """ + mkdir -p /tmp/arch-repo \ + && cd /tmp/arch-repo \ + && cp /tmp/pkg/{0} ./ \ + && repo-add ./testrepo.db.tar.zst {0} + """.format( + pkg_file_name + ), + ) + ) + def create_repo_and_serve(self): """ :type self: qubes.tests.SystemTestCase | VmUpdatesMixin @@ -405,6 +459,16 @@ def create_repo_and_serve(self): stderr=subprocess.DEVNULL, ) ) + elif self.template.count("archlinux"): + self.create_repo_arch() + self.repo_proc = self.loop.run_until_complete( + self.netvm_repo.run( + "cd /tmp/arch-repo && python3 -m http.server 8080", + stdin=subprocess.DEVNULL, + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + ) + ) else: # not reachable... self.skipTest( @@ -426,6 +490,8 @@ def add_update_to_repo(self): self.create_repo_apt(1) elif self.template.count("fedora"): self.create_repo_yum(1) + elif self.template.count("archlinux"): + self.create_repo_arch(1) def configure_test_repo(self): """ @@ -458,6 +524,18 @@ def configure_test_repo(self): user="root", ) ) + elif self.template.count("archlinux"): + self.loop.run_until_complete( + self.testvm1.run_for_stdio( + "rm -f /etc/pacman.d/*.conf &&" + "echo '[testrepo]' > /etc/pacman.d/70-test.conf &&" + "echo 'SigLevel = Optional TrustAll'" + " >> /etc/pacman.d/70-test.conf &&" + "echo 'Server = http://localhost:8080/'" + " >> /etc/pacman.d/70-test.conf", + user="root", + ) + ) else: # not reachable... self.skipTest( @@ -744,19 +822,33 @@ def test_121_updates_available_notification_qubes_vm_update_cli(self): ) def test_130_no_network_qubes_vm_update(self): + expected_ret_codes = (23,) + if self.template.count("archlinux"): + # updater on Arch doesn't have separate metadata refresh step + expected_ret_codes = ( + 23, + 24, + ) self.update_via_proxy_qubes_vm_update_impl( method="qubes-vm-update", options=(), - expected_ret_codes=(23,), + expected_ret_codes=expected_ret_codes, break_repo=True, expect_updated=False, ) def test_131_no_network_qubes_vm_update_cli(self): + expected_ret_codes = (23,) + if self.template.count("archlinux"): + # updater on Arch doesn't have separate metadata refresh step + expected_ret_codes = ( + 23, + 24, + ) self.update_via_proxy_qubes_vm_update_impl( method="qubes-vm-update", options=("--no-progress",), - expected_ret_codes=(23,), + expected_ret_codes=expected_ret_codes, break_repo=True, expect_updated=False, ) From 2ca007ce7e3e5e568d7d4e07cb70a0be5bb11290 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Tue, 21 Jan 2025 18:41:45 +0100 Subject: [PATCH 3/6] tests: exclude gnome-terminal test on Arch It isn't installed there. --- qubes/tests/integ/vm_qrexec_gui.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qubes/tests/integ/vm_qrexec_gui.py b/qubes/tests/integ/vm_qrexec_gui.py index 021c688e5..5684549dd 100644 --- a/qubes/tests/integ/vm_qrexec_gui.py +++ b/qubes/tests/integ/vm_qrexec_gui.py @@ -120,6 +120,8 @@ def test_011_run_gnome_terminal(self): self.skipTest("Whonix template doesn't have 'gnome-terminal'") if "xfce" in self.template: self.skipTest("Xfce template doesn't have 'gnome-terminal'") + if "archlinux" in self.template: + self.skipTest("Arch template doesn't have 'gnome-terminal'") self.loop.run_until_complete(self.testvm1.start()) self.assertEqual(self.testvm1.get_power_state(), "Running") self.loop.run_until_complete(self.wait_for_session(self.testvm1)) From 36f886d268700ecff3a24eb9ee5dc7674a07dde4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Tue, 21 Jan 2025 18:42:13 +0100 Subject: [PATCH 4/6] tests: typo fix --- qubes/tests/integ/vm_qrexec_gui.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qubes/tests/integ/vm_qrexec_gui.py b/qubes/tests/integ/vm_qrexec_gui.py index 5684549dd..febf825e1 100644 --- a/qubes/tests/integ/vm_qrexec_gui.py +++ b/qubes/tests/integ/vm_qrexec_gui.py @@ -126,7 +126,7 @@ def test_011_run_gnome_terminal(self): self.assertEqual(self.testvm1.get_power_state(), "Running") self.loop.run_until_complete(self.wait_for_session(self.testvm1)) p = self.loop.run_until_complete( - self.testvm1.run("gnome-terminal || " "ptyxis") + self.testvm1.run("gnome-terminal || ptyxis") ) try: title = "user@{}".format(self.testvm1.name) From 1019f2094b01027ecd88a5c2b0737fa31b24c093 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Tue, 21 Jan 2025 19:04:18 +0100 Subject: [PATCH 5/6] tests: exclude Arch from salt tests There is no salt package in the standard Arch repos. There is one in AUR, but default setup can't rely on them. --- qubes/tests/integ/salt.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qubes/tests/integ/salt.py b/qubes/tests/integ/salt.py index 3c33ae6d9..f789fa93e 100644 --- a/qubes/tests/integ/salt.py +++ b/qubes/tests/integ/salt.py @@ -308,6 +308,8 @@ class SaltVMTestMixin(SaltTestMixin): def setUp(self): if self.template.startswith("whonix"): self.skipTest("Whonix not supported as salt VM") + if self.template.startswith("archlinux"): + self.skipTest("Archlinux not supported as salt VM") super(SaltVMTestMixin, self).setUp() self.init_default_template(self.template) From a784c37ade478da8c7c7bfb8a906e2b9f4ad7131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Wed, 22 Jan 2025 01:15:45 +0100 Subject: [PATCH 6/6] tests/network: use ping -6 instead of ping6 The latter is a symlink to the former, and the symlink is not present in Arch. --- qubes/tests/integ/network_ipv6.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qubes/tests/integ/network_ipv6.py b/qubes/tests/integ/network_ipv6.py index 486907702..9ce462595 100644 --- a/qubes/tests/integ/network_ipv6.py +++ b/qubes/tests/integ/network_ipv6.py @@ -36,7 +36,7 @@ class VmIPv6NetworkingMixin(VmNetworkingMixin): test_ip6 = "2000:abcd::1" - ping6_cmd = "ping6 -W 1 -n -c 1 {target}" + ping6_cmd = "ping -6 -W 1 -n -c 1 {target}" def setUp(self): super(VmIPv6NetworkingMixin, self).setUp()