From 6e5792a1f6ecc155fc977e3813e75fc8ede478ab Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrangé" Date: Wed, 15 Mar 2023 17:43:20 +0000 Subject: iotests: print TAP protocol version when reporting tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Recently meson started complaining that TAP test reports don't include the TAP protocol version. While this warning is bogus and has since been removed from Meson, it looks like good practice to include this header going forward. The GLib library test harness has started unconditionally printing the version, so this brings the I/O tests into line. Reviewed-by: Thomas Huth Reviewed-by: Alex Bennée Signed-off-by: Daniel P. Berrangé Acked-by: Hanna Czenczek Tested-by: Thomas Huth Message-Id: <20230303160727.3977246-5-berrange@redhat.com> Signed-off-by: Alex Bennée Message-Id: <20230315174331.2959-22-alex.bennee@linaro.org> --- tests/qemu-iotests/testrunner.py | 1 + 1 file changed, 1 insertion(+) (limited to 'tests/qemu-iotests/testrunner.py') diff --git a/tests/qemu-iotests/testrunner.py b/tests/qemu-iotests/testrunner.py index 5a771da86e..e734800b3d 100644 --- a/tests/qemu-iotests/testrunner.py +++ b/tests/qemu-iotests/testrunner.py @@ -391,6 +391,7 @@ class TestRunner(ContextManager['TestRunner']): casenotrun = [] if self.tap: + print('TAP version 13') self.env.print_env('# ') print('1..%d' % len(tests)) else: -- cgit 1.4.1 From cb845eaa88eb266c5023af06989e94d95c712871 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrangé" Date: Wed, 15 Mar 2023 17:43:21 +0000 Subject: iotests: connect stdin to /dev/null when running tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently the tests have their stdin inherited from the test harness, meaning they are connected to a TTY. The QEMU processes spawned by certain tests, however, modify TTY settings and if the test exits abnormally the settings might not be restored. The python test harness thus has some logic which will capture the initial TTY settings and restore them once all tests are finished. This does not, however, take into account the possibility of many copies of the 'check' program running in parallel. With parallel execution, a later invokation may save the TTY state that QEMU has already modified, and thus restore bad state leaving the TTY non-functional. None of the I/O tests shnould actually be interactive requiring user input and so they should not require a TTY at all. To avoid this while TTY save/restore complexity we can connect the test stdin to /dev/null instead. Signed-off-by: Daniel P. Berrangé Reviewed-by: Thomas Huth Acked-by: Hanna Czenczek Tested-by: Thomas Huth Message-Id: <20230303160727.3977246-6-berrange@redhat.com> Signed-off-by: Alex Bennée Message-Id: <20230315174331.2959-23-alex.bennee@linaro.org> --- tests/qemu-iotests/testrunner.py | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) (limited to 'tests/qemu-iotests/testrunner.py') diff --git a/tests/qemu-iotests/testrunner.py b/tests/qemu-iotests/testrunner.py index e734800b3d..81519ed6e2 100644 --- a/tests/qemu-iotests/testrunner.py +++ b/tests/qemu-iotests/testrunner.py @@ -24,12 +24,10 @@ import difflib import subprocess import contextlib import json -import termios import shutil import sys from multiprocessing import Pool -from contextlib import contextmanager -from typing import List, Optional, Iterator, Any, Sequence, Dict, \ +from typing import List, Optional, Any, Sequence, Dict, \ ContextManager from testenv import TestEnv @@ -56,22 +54,6 @@ def file_diff(file1: str, file2: str) -> List[str]: return res -# We want to save current tty settings during test run, -# since an aborting qemu call may leave things screwed up. -@contextmanager -def savetty() -> Iterator[None]: - isterm = sys.stdin.isatty() - if isterm: - fd = sys.stdin.fileno() - attr = termios.tcgetattr(fd) - - try: - yield - finally: - if isterm: - termios.tcsetattr(fd, termios.TCSADRAIN, attr) - - class LastElapsedTime(ContextManager['LastElapsedTime']): """ Cache for elapsed time for tests, to show it during new test run @@ -169,7 +151,6 @@ class TestRunner(ContextManager['TestRunner']): self._stack = contextlib.ExitStack() self._stack.enter_context(self.env) self._stack.enter_context(self.last_elapsed) - self._stack.enter_context(savetty()) return self def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None: @@ -294,6 +275,7 @@ class TestRunner(ContextManager['TestRunner']): t0 = time.time() with f_bad.open('w', encoding="utf-8") as f: with subprocess.Popen(args, cwd=str(f_test.parent), env=env, + stdin=subprocess.DEVNULL, stdout=f, stderr=subprocess.STDOUT) as proc: try: proc.wait() -- cgit 1.4.1 From 5ba7db0938c8b8e6e457b9aab8c6c625913d773f Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrangé" Date: Wed, 15 Mar 2023 17:43:22 +0000 Subject: iotests: always use a unique sub-directory per test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current test runner is only safe against parallel execution within a single instance of the 'check' process, and only if -j is given a value greater than 2. This prevents running multiple copies of the 'check' process for different test scenarios. This change switches the output / socket directories to always include the test name, image format and image protocol. This should allow full parallelism of all distinct test scenarios. eg running both qcow2 and raw tests at the same time, or both file and nbd tests at the same time. It would be possible to allow for parallelism of the same test scenario by including the pid, but that would potentially let many directories accumulate over time on failures, so is not done. Signed-off-by: Daniel P. Berrangé Reviewed-by: Thomas Huth Acked-by: Hanna Czenczek Tested-by: Thomas Huth Message-Id: <20230303160727.3977246-7-berrange@redhat.com> Signed-off-by: Alex Bennée Message-Id: <20230315174331.2959-24-alex.bennee@linaro.org> --- tests/qemu-iotests/testrunner.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'tests/qemu-iotests/testrunner.py') diff --git a/tests/qemu-iotests/testrunner.py b/tests/qemu-iotests/testrunner.py index 81519ed6e2..7b322272e9 100644 --- a/tests/qemu-iotests/testrunner.py +++ b/tests/qemu-iotests/testrunner.py @@ -228,13 +228,11 @@ class TestRunner(ContextManager['TestRunner']): return f'{test}.out' - def do_run_test(self, test: str, mp: bool) -> TestResult: + def do_run_test(self, test: str) -> TestResult: """ Run one test :param test: test file path - :param mp: if true, we are in a multiprocessing environment, use - personal subdirectories for test run Note: this method may be called from subprocess, so it does not change ``self`` object in any way! @@ -257,12 +255,14 @@ class TestRunner(ContextManager['TestRunner']): args = [str(f_test.resolve())] env = self.env.prepare_subprocess(args) - if mp: - # Split test directories, so that tests running in parallel don't - # break each other. - for d in ['TEST_DIR', 'SOCK_DIR']: - env[d] = os.path.join(env[d], f_test.name) - Path(env[d]).mkdir(parents=True, exist_ok=True) + + # Split test directories, so that tests running in parallel don't + # break each other. + for d in ['TEST_DIR', 'SOCK_DIR']: + env[d] = os.path.join( + env[d], + f"{self.env.imgfmt}-{self.env.imgproto}-{f_test.name}") + Path(env[d]).mkdir(parents=True, exist_ok=True) test_dir = env['TEST_DIR'] f_bad = Path(test_dir, f_test.name + '.out.bad') @@ -347,7 +347,7 @@ class TestRunner(ContextManager['TestRunner']): testname = os.path.basename(test) print(f'# running {self.env.imgfmt} {testname}') - res = self.do_run_test(test, mp) + res = self.do_run_test(test) end = datetime.datetime.now().strftime('%H:%M:%S') self.test_print_one_line(test=test, -- cgit 1.4.1