From 46cc4ca91098d1f48eb7529cbadffbffe77d8f29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Sat, 8 Aug 2020 20:32:51 +0200 Subject: [PATCH] tests: collect detailed diagnostics on failure Help debugging test failures by collecting detailed information on failure. It will be logger to the standard logger, which will end up either on stderr or in journalctl. --- qubes/tests/integ/network.py | 28 +++++++++++++++++++++++++++- qubes/tests/integ/network_ipv6.py | 13 +++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/qubes/tests/integ/network.py b/qubes/tests/integ/network.py index faf7371f..f9c28bc9 100644 --- a/qubes/tests/integ/network.py +++ b/qubes/tests/integ/network.py @@ -18,7 +18,7 @@ # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, see . # - +import contextlib from distutils import spawn import asyncio @@ -87,6 +87,32 @@ class VmNetworkingMixin(object): self.configure_netvm() + def _run_cmd_and_log_output(self, vm, cmd): + """Used in tearDown to collect more info""" + if not vm.is_running(): + return + with contextlib.suppress(subprocess.CalledProcessError): + output = self.loop.run_until_complete( + self.testnetvm.run_for_stdio(cmd, user='root')) + self.log.error('{}: {}: {}'.format(vm.name, cmd, output)) + + def tearDown(self): + # collect more info on failure + if self._outcome and not self._outcome.success: + for vm in (self.testnetvm, self.testvm1, getattr(self, 'proxy', None)): + if vm is None: + continue + self._run_cmd_and_log_output(vm, 'ip a') + self._run_cmd_and_log_output(vm, 'ip r') + self._run_cmd_and_log_output(vm, 'iptables -vnL') + self._run_cmd_and_log_output(vm, 'iptables -vnL -t nat') + self._run_cmd_and_log_output(vm, 'nft list table qubes-firewall') + self._run_cmd_and_log_output(vm, 'systemctl --no-pager status qubes-firewall') + self._run_cmd_and_log_output(vm, 'systemctl --no-pager status qubes-iptables') + self._run_cmd_and_log_output(vm, 'systemctl --no-pager status xendriverdomain') + + super(VmNetworkingMixin, self).tearDown() + def configure_netvm(self): ''' diff --git a/qubes/tests/integ/network_ipv6.py b/qubes/tests/integ/network_ipv6.py index ac9db460..702e9e64 100644 --- a/qubes/tests/integ/network_ipv6.py +++ b/qubes/tests/integ/network_ipv6.py @@ -43,6 +43,19 @@ class VmIPv6NetworkingMixin(VmNetworkingMixin): self.ping6_ip = self.ping6_cmd.format(target=self.test_ip6) self.ping6_name = self.ping6_cmd.format(target=self.test_name) + def tearDown(self): + # collect more info on failure (ipv4 info collected in parent) + if self._outcome and not self._outcome.success: + for vm in (self.testnetvm, self.testvm1, getattr(self, 'proxy', None)): + if vm is None: + continue + self._run_cmd_and_log_output(vm, 'ip -6 r') + self._run_cmd_and_log_output(vm, 'ip6tables -vnL') + self._run_cmd_and_log_output(vm, 'ip6tables -vnL -t nat') + self._run_cmd_and_log_output(vm, 'nft list table ip6 qubes-firewall') + + super().tearDown() + def configure_netvm(self): ''' :type self: qubes.tests.SystemTestCase | VmIPv6NetworkingMixin