From b1f3b410528177c0a2f86b48bb9fb24422008fb1 Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Thu, 11 Feb 2021 16:55:05 -0500 Subject: [PATCH 01/23] Acceptance Tests: use the job work directory for created VMs The QEMUMachine uses a base temporary directory for all temporary needs. By setting it to the Avocado's workdir, it's possible to keep the temporary files during debugging sessions much more easily by setting the "--keep-tmp" command line option. Reference: https://avocado-framework.readthedocs.io/en/85.0/api/test/avocado.html#avocado.Test.workdir Reference: https://avocado-framework.readthedocs.io/en/85.0/config/index.html#run-keep-tmp Signed-off-by: Cleber Rosa Reviewed-by: Wainer dos Santos Moschetta Reviewed-by: John Snow Message-Id: <20210211220146.2525771-4-crosa@redhat.com> Signed-off-by: Cleber Rosa --- tests/acceptance/avocado_qemu/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py index 93c4b9851f..693c226d91 100644 --- a/tests/acceptance/avocado_qemu/__init__.py +++ b/tests/acceptance/avocado_qemu/__init__.py @@ -221,7 +221,8 @@ class Test(avocado.Test): def _new_vm(self, *args): self._sd = tempfile.TemporaryDirectory(prefix="avo_qemu_sock_") - vm = QEMUMachine(self.qemu_bin, sock_dir=self._sd.name) + vm = QEMUMachine(self.qemu_bin, base_temp_dir=self.workdir, + sock_dir=self._sd.name) if args: vm.add_args(*args) return vm From 776b019d9d446c2a24a4dcde352616d496a89b36 Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Thu, 11 Feb 2021 16:55:05 -0500 Subject: [PATCH 02/23] Acceptance Tests: log information when creating QEMUMachine Including its base temporary directory, given that information useful for debugging can be put there. Signed-off-by: Cleber Rosa Reviewed-by: Wainer dos Santos Moschetta Message-Id: <20210211220146.2525771-5-crosa@redhat.com> Signed-off-by: Cleber Rosa --- tests/acceptance/avocado_qemu/__init__.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py index 693c226d91..4ce09de4fa 100644 --- a/tests/acceptance/avocado_qemu/__init__.py +++ b/tests/acceptance/avocado_qemu/__init__.py @@ -219,10 +219,12 @@ class Test(avocado.Test): if self.qemu_bin is None: self.cancel("No QEMU binary defined or found in the build tree") - def _new_vm(self, *args): + def _new_vm(self, name, *args): self._sd = tempfile.TemporaryDirectory(prefix="avo_qemu_sock_") vm = QEMUMachine(self.qemu_bin, base_temp_dir=self.workdir, sock_dir=self._sd.name) + self.log.debug('QEMUMachine "%s" created', name) + self.log.debug('QEMUMachine "%s" temp_dir: %s', name, vm.temp_dir) if args: vm.add_args(*args) return vm @@ -235,7 +237,7 @@ class Test(avocado.Test): if not name: name = str(uuid.uuid4()) if self._vms.get(name) is None: - self._vms[name] = self._new_vm(*args) + self._vms[name] = self._new_vm(name, *args) if self.machine is not None: self._vms[name].set_machine(self.machine) return self._vms[name] From b306e26ce0f33ef0a899131c5191b77aaf6df364 Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Thu, 11 Feb 2021 16:55:05 -0500 Subject: [PATCH 03/23] Acceptance Tests: distinguish between temp and logs dir Logs can be very important to debug issues, and currently QEMUMachine instances will remove logs that are created under the temporary directories. With this change, the stdout and stderr generated by the QEMU process started by QEMUMachine will always be kept along the test results directory. Signed-off-by: Cleber Rosa Message-Id: <20210211220146.2525771-6-crosa@redhat.com> Reviewed-by: Wainer dos Santos Moschetta Signed-off-by: Cleber Rosa --- python/qemu/machine/machine.py | 17 ++++++++++++++--- tests/acceptance/avocado_qemu/__init__.py | 3 ++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/python/qemu/machine/machine.py b/python/qemu/machine/machine.py index d47ab3d896..94846dd71b 100644 --- a/python/qemu/machine/machine.py +++ b/python/qemu/machine/machine.py @@ -96,7 +96,8 @@ class QEMUMachine: socket_scm_helper: Optional[str] = None, sock_dir: Optional[str] = None, drain_console: bool = False, - console_log: Optional[str] = None): + console_log: Optional[str] = None, + log_dir: Optional[str] = None): ''' Initialize a QEMUMachine @@ -110,6 +111,7 @@ class QEMUMachine: @param sock_dir: where to create socket (defaults to base_temp_dir) @param drain_console: (optional) True to drain console socket to buffer @param console_log: (optional) path to console log file + @param log_dir: where to create and keep log files @note: Qemu process is not started until launch() is used. ''' # pylint: disable=too-many-arguments @@ -123,6 +125,7 @@ class QEMUMachine: self._name = name or "qemu-%d" % os.getpid() self._base_temp_dir = base_temp_dir self._sock_dir = sock_dir or self._base_temp_dir + self._log_dir = log_dir self._socket_scm_helper = socket_scm_helper if monitor_address is not None: @@ -314,8 +317,6 @@ class QEMUMachine: return args def _pre_launch(self) -> None: - self._qemu_log_path = os.path.join(self.temp_dir, self._name + ".log") - if self._console_set: self._remove_files.append(self._console_address) @@ -332,6 +333,7 @@ class QEMUMachine: # NOTE: Make sure any opened resources are *definitely* freed in # _post_shutdown()! # pylint: disable=consider-using-with + self._qemu_log_path = os.path.join(self.log_dir, self._name + ".log") self._qemu_log_file = open(self._qemu_log_path, 'wb') def _post_launch(self) -> None: @@ -770,3 +772,12 @@ class QEMUMachine: self._temp_dir = tempfile.mkdtemp(prefix="qemu-machine-", dir=self._base_temp_dir) return self._temp_dir + + @property + def log_dir(self) -> str: + """ + Returns a directory to be used for writing logs + """ + if self._log_dir is None: + return self.temp_dir + return self._log_dir diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py index 4ce09de4fa..420c00f1a9 100644 --- a/tests/acceptance/avocado_qemu/__init__.py +++ b/tests/acceptance/avocado_qemu/__init__.py @@ -222,9 +222,10 @@ class Test(avocado.Test): def _new_vm(self, name, *args): self._sd = tempfile.TemporaryDirectory(prefix="avo_qemu_sock_") vm = QEMUMachine(self.qemu_bin, base_temp_dir=self.workdir, - sock_dir=self._sd.name) + sock_dir=self._sd.name, log_dir=self.logdir) self.log.debug('QEMUMachine "%s" created', name) self.log.debug('QEMUMachine "%s" temp_dir: %s', name, vm.temp_dir) + self.log.debug('QEMUMachine "%s" log_dir: %s', name, vm.log_dir) if args: vm.add_args(*args) return vm From 341929234c584565ddd7d29bb48d2a5f5f40de22 Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Wed, 14 Apr 2021 18:14:55 -0400 Subject: [PATCH 04/23] Acceptance Tests: rename attribute holding the distro image checksum MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This renames the attribute that holds the checksum for the image Linux distribution image used. The current name of the attribute is not very descriptive. Also, in preparation for making the distribution used configurable, which will add distro related parameters, attributes and tags, let's make the naming of those more uniform. Signed-off-by: Cleber Rosa Message-Id: <20210414221457.1653745-2-crosa@redhat.com> Reviewed-by: Wainer dos Santos Moschetta Reviewed-by: Eric Auger Reviewed-by: Willian Rampazzo Reviewed-by: Philippe Mathieu-Daudé [CR: split long lines] Signed-off-by: Cleber Rosa --- tests/acceptance/avocado_qemu/__init__.py | 4 ++-- tests/acceptance/boot_linux.py | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py index 420c00f1a9..0e62c15c60 100644 --- a/tests/acceptance/avocado_qemu/__init__.py +++ b/tests/acceptance/avocado_qemu/__init__.py @@ -312,7 +312,7 @@ class LinuxTest(Test, LinuxSSHMixIn): """ timeout = 900 - chksum = None + distro_checksum = None username = 'root' password = 'password' @@ -360,7 +360,7 @@ class LinuxTest(Test, LinuxSSHMixIn): try: boot = vmimage.get( 'fedora', arch=image_arch, version='31', - checksum=self.chksum, + checksum=self.distro_checksum, algorithm='sha256', cache_dir=self.cache_dirs[0], snapshot_dir=self.workdir) diff --git a/tests/acceptance/boot_linux.py b/tests/acceptance/boot_linux.py index 4c8a5994b2..3901c23690 100644 --- a/tests/acceptance/boot_linux.py +++ b/tests/acceptance/boot_linux.py @@ -20,7 +20,8 @@ class BootLinuxX8664(LinuxTest): :avocado: tags=arch:x86_64 """ - chksum = 'e3c1b309d9203604922d6e255c2c5d098a309c2d46215d8fc026954f3c5c27a0' + distro_checksum = ('e3c1b309d9203604922d6e255c2c5d09' + '8a309c2d46215d8fc026954f3c5c27a0') def test_pc_i440fx_tcg(self): """ @@ -66,7 +67,8 @@ class BootLinuxAarch64(LinuxTest): :avocado: tags=machine:gic-version=2 """ - chksum = '1e18d9c0cf734940c4b5d5ec592facaed2af0ad0329383d5639c997fdf16fe49' + distro_checksum = ('1e18d9c0cf734940c4b5d5ec592facae' + 'd2af0ad0329383d5639c997fdf16fe49') def add_common_args(self): self.vm.add_args('-bios', @@ -119,7 +121,8 @@ class BootLinuxPPC64(LinuxTest): :avocado: tags=arch:ppc64 """ - chksum = '7c3528b85a3df4b2306e892199a9e1e43f991c506f2cc390dc4efa2026ad2f58' + distro_checksum = ('7c3528b85a3df4b2306e892199a9e1e4' + '3f991c506f2cc390dc4efa2026ad2f58') def test_pseries_tcg(self): """ @@ -136,7 +139,8 @@ class BootLinuxS390X(LinuxTest): :avocado: tags=arch:s390x """ - chksum = '4caaab5a434fd4d1079149a072fdc7891e354f834d355069ca982fdcaf5a122d' + distro_checksum = ('4caaab5a434fd4d1079149a072fdc789' + '1e354f834d355069ca982fdcaf5a122d') @skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab') def test_s390_ccw_virtio_tcg(self): From 889554f09ed0d4c2fcc6be28b81e2e9fc8f35aee Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Wed, 14 Apr 2021 18:14:56 -0400 Subject: [PATCH 05/23] Acceptance Tests: move definition of distro checksums to the framework MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of having, by default, the checksum in the tests, and the definition of tests in the framework, let's keep them together. A central definition for distributions is available, and it should allow other known distros to be added more easily. No behavior change is expected here, and tests can still define a distro_checksum value if for some reason they want to override the known distribution information. Signed-off-by: Cleber Rosa Message-Id: <20210414221457.1653745-3-crosa@redhat.com> Reviewed-by: Philippe Mathieu-Daudé Acked-by: Eric Auger [CR: split long lines] Signed-off-by: Cleber Rosa --- tests/acceptance/avocado_qemu/__init__.py | 39 +++++++++++++++++++++-- tests/acceptance/boot_linux.py | 12 ------- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py index 0e62c15c60..3a144cded4 100644 --- a/tests/acceptance/avocado_qemu/__init__.py +++ b/tests/acceptance/avocado_qemu/__init__.py @@ -304,6 +304,35 @@ class LinuxSSHMixIn: return stdout_lines, stderr_lines +#: A collection of known distros and their respective image checksum +KNOWN_DISTROS = { + 'fedora': { + '31': { + 'x86_64': + {'checksum': ('e3c1b309d9203604922d6e255c2c5d09' + '8a309c2d46215d8fc026954f3c5c27a0')}, + 'aarch64': + {'checksum': ('1e18d9c0cf734940c4b5d5ec592facae' + 'd2af0ad0329383d5639c997fdf16fe49')}, + 'ppc64': + {'checksum': ('7c3528b85a3df4b2306e892199a9e1e4' + '3f991c506f2cc390dc4efa2026ad2f58')}, + 's390x': + {'checksum': ('4caaab5a434fd4d1079149a072fdc789' + '1e354f834d355069ca982fdcaf5a122d')}, + } + } + } + + +def get_known_distro_checksum(distro, distro_version, arch): + try: + return KNOWN_DISTROS.get(distro).get(distro_version).\ + get(arch).get('checksum') + except AttributeError: + return None + + class LinuxTest(Test, LinuxSSHMixIn): """Facilitates having a cloud-image Linux based available. @@ -353,14 +382,20 @@ class LinuxTest(Test, LinuxSSHMixIn): vmimage.QEMU_IMG = qemu_img self.log.info('Downloading/preparing boot image') + distro = 'fedora' + distro_version = '31' + known_distro_checksum = get_known_distro_checksum(distro, + distro_version, + self.arch) + distro_checksum = self.distro_checksum or known_distro_checksum # Fedora 31 only provides ppc64le images image_arch = self.arch if image_arch == 'ppc64': image_arch = 'ppc64le' try: boot = vmimage.get( - 'fedora', arch=image_arch, version='31', - checksum=self.distro_checksum, + distro, arch=image_arch, version=distro_version, + checksum=distro_checksum, algorithm='sha256', cache_dir=self.cache_dirs[0], snapshot_dir=self.workdir) diff --git a/tests/acceptance/boot_linux.py b/tests/acceptance/boot_linux.py index 3901c23690..34c4366366 100644 --- a/tests/acceptance/boot_linux.py +++ b/tests/acceptance/boot_linux.py @@ -20,9 +20,6 @@ class BootLinuxX8664(LinuxTest): :avocado: tags=arch:x86_64 """ - distro_checksum = ('e3c1b309d9203604922d6e255c2c5d09' - '8a309c2d46215d8fc026954f3c5c27a0') - def test_pc_i440fx_tcg(self): """ :avocado: tags=machine:pc @@ -67,9 +64,6 @@ class BootLinuxAarch64(LinuxTest): :avocado: tags=machine:gic-version=2 """ - distro_checksum = ('1e18d9c0cf734940c4b5d5ec592facae' - 'd2af0ad0329383d5639c997fdf16fe49') - def add_common_args(self): self.vm.add_args('-bios', os.path.join(BUILD_DIR, 'pc-bios', @@ -121,9 +115,6 @@ class BootLinuxPPC64(LinuxTest): :avocado: tags=arch:ppc64 """ - distro_checksum = ('7c3528b85a3df4b2306e892199a9e1e4' - '3f991c506f2cc390dc4efa2026ad2f58') - def test_pseries_tcg(self): """ :avocado: tags=machine:pseries @@ -139,9 +130,6 @@ class BootLinuxS390X(LinuxTest): :avocado: tags=arch:s390x """ - distro_checksum = ('4caaab5a434fd4d1079149a072fdc789' - '1e354f834d355069ca982fdcaf5a122d') - @skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab') def test_s390_ccw_virtio_tcg(self): """ From d5adf9d52b36d63347b2f658b8c67567ff6bd525 Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Wed, 14 Apr 2021 18:14:57 -0400 Subject: [PATCH 06/23] Acceptance Tests: support choosing specific distro and version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tests based on the LinuxTest class give the test writer a ready to use guest operating system, currently pinned to Fedora 31. With this change, it's now possible to choose different distros and versions, similar to how other tags and parameter can be set for the target arch, accelerator, etc. One of the reasons for this work, is that some development features depend on updates on the guest side. For instance the tests on virtiofs_submounts.py, require newer kernels, and may benefit from running, say on Fedora 34, without the need for a custom kernel. Please notice that the pre-caching of the Fedora 31 images done during the early stages of `make check-acceptance` (before the tests are actually executed) are not expanded here to cover every new image added. But, the tests will download other needed images (and cache them) during the first execution. Signed-off-by: Cleber Rosa Message-Id: <20210414221457.1653745-4-crosa@redhat.com> Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Willian Rampazzo Signed-off-by: Cleber Rosa --- docs/devel/testing.rst | 65 +++++++++++++++++++++++ tests/acceptance/avocado_qemu/__init__.py | 47 ++++++++++++---- 2 files changed, 102 insertions(+), 10 deletions(-) diff --git a/docs/devel/testing.rst b/docs/devel/testing.rst index 4e42392810..19cbf532ae 100644 --- a/docs/devel/testing.rst +++ b/docs/devel/testing.rst @@ -922,6 +922,39 @@ The preserved value of the ``qemu_bin`` parameter or the result of the dynamic probe for a QEMU binary in the current working directory or source tree. +LinuxTest +~~~~~~~~~ + +Besides the attributes present on the ``avocado_qemu.Test`` base +class, the ``avocado_qemu.LinuxTest`` adds the following attributes: + +distro +...... + +The name of the Linux distribution used as the guest image for the +test. The name should match the **Provider** column on the list +of images supported by the avocado.utils.vmimage library: + +https://avocado-framework.readthedocs.io/en/latest/guides/writer/libs/vmimage.html#supported-images + +distro_version +.............. + +The version of the Linux distribution as the guest image for the +test. The name should match the **Version** column on the list +of images supported by the avocado.utils.vmimage library: + +https://avocado-framework.readthedocs.io/en/latest/guides/writer/libs/vmimage.html#supported-images + +distro_checksum +............... + +The sha256 hash of the guest image file used for the test. + +If this value is not set in the code or by a test parameter (with the +same name), no validation on the integrity of the image will be +performed. + Parameter reference ------------------- @@ -962,6 +995,38 @@ qemu_bin The exact QEMU binary to be used on QEMUMachine. +LinuxTest +~~~~~~~~~ + +Besides the parameters present on the ``avocado_qemu.Test`` base +class, the ``avocado_qemu.LinuxTest`` adds the following parameters: + +distro +...... + +The name of the Linux distribution used as the guest image for the +test. The name should match the **Provider** column on the list +of images supported by the avocado.utils.vmimage library: + +https://avocado-framework.readthedocs.io/en/latest/guides/writer/libs/vmimage.html#supported-images + +distro_version +.............. + +The version of the Linux distribution as the guest image for the +test. The name should match the **Version** column on the list +of images supported by the avocado.utils.vmimage library: + +https://avocado-framework.readthedocs.io/en/latest/guides/writer/libs/vmimage.html#supported-images + +distro_checksum +............... + +The sha256 hash of the guest image file used for the test. + +If this value is not set in the code or by this parameter no +validation on the integrity of the image will be performed. + Skipping tests -------------- The Avocado framework provides Python decorators which allow for easily skip diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py index 3a144cded4..1f1728ab83 100644 --- a/tests/acceptance/avocado_qemu/__init__.py +++ b/tests/acceptance/avocado_qemu/__init__.py @@ -345,8 +345,39 @@ class LinuxTest(Test, LinuxSSHMixIn): username = 'root' password = 'password' + def _set_distro(self): + distro = self.params.get( + 'distro', + default=self._get_unique_tag_val('distro')) + if not distro: + distro = 'fedora' + self.distro = distro + + distro_version = self.params.get( + 'distro_version', + default=self._get_unique_tag_val('distro_version')) + if not distro_version: + distro_version = '31' + self.distro_version = distro_version + + # The distro checksum behaves differently than distro name and + # version. First, it does not respect a tag with the same + # name, given that it's not expected to be used for filtering + # (distro name versions are the natural choice). Second, the + # order of precedence is: parameter, attribute and then value + # from KNOWN_DISTROS. + distro_checksum = self.params.get('distro_checksum', + default=self.distro_checksum) + if not distro_checksum: + distro_checksum = get_known_distro_checksum(self.distro, + self.distro_version, + self.arch) + if distro_checksum: + self.distro_checksum = distro_checksum + def setUp(self, ssh_pubkey=None, network_device_type='virtio-net'): super(LinuxTest, self).setUp() + self._set_distro() self.vm.add_args('-smp', '2') self.vm.add_args('-m', '1024') # The following network device allows for SSH connections @@ -382,20 +413,16 @@ class LinuxTest(Test, LinuxSSHMixIn): vmimage.QEMU_IMG = qemu_img self.log.info('Downloading/preparing boot image') - distro = 'fedora' - distro_version = '31' - known_distro_checksum = get_known_distro_checksum(distro, - distro_version, - self.arch) - distro_checksum = self.distro_checksum or known_distro_checksum # Fedora 31 only provides ppc64le images image_arch = self.arch - if image_arch == 'ppc64': - image_arch = 'ppc64le' + if self.distro == 'fedora': + if image_arch == 'ppc64': + image_arch = 'ppc64le' + try: boot = vmimage.get( - distro, arch=image_arch, version=distro_version, - checksum=distro_checksum, + self.distro, arch=image_arch, version=self.distro_version, + checksum=self.distro_checksum, algorithm='sha256', cache_dir=self.cache_dirs[0], snapshot_dir=self.workdir) From 9f5193413026ed65f9651108b6656054b40e43a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 15 May 2021 15:45:54 +0200 Subject: [PATCH 07/23] tests/acceptance: Ignore binary data sent on serial console MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a guest sends binary data on the serial console, we get: File "tests/acceptance/avocado_qemu/__init__.py", line 92, in _console_interaction msg = console.readline().strip() File "/usr/lib64/python3.8/codecs.py", line 322, in decode (result, consumed) = self._buffer_decode(data, self.errors, final) UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa9 in position 2: invalid start byte Since we use the console with readline(), fix it the easiest way possible: ignore binary data (all current tests compare text string anyway). Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20210515134555.307404-2-f4bug@amsat.org> Reviewed-by: Wainer dos Santos Moschetta Tested-by: Wainer dos Santos Moschetta Signed-off-by: Cleber Rosa --- tests/acceptance/avocado_qemu/__init__.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py index 1f1728ab83..c3163af3b7 100644 --- a/tests/acceptance/avocado_qemu/__init__.py +++ b/tests/acceptance/avocado_qemu/__init__.py @@ -86,14 +86,17 @@ def _console_interaction(test, success_message, failure_message, assert not keep_sending or send_string if vm is None: vm = test.vm - console = vm.console_socket.makefile() + console = vm.console_socket.makefile(mode='rb', encoding='utf-8') console_logger = logging.getLogger('console') while True: if send_string: vm.console_socket.sendall(send_string.encode()) if not keep_sending: send_string = None # send only once - msg = console.readline().strip() + try: + msg = console.readline().decode().strip() + except UnicodeDecodeError: + msg = None if not msg: continue console_logger.debug(msg) From fb130401736d294843764bfbab37a9e9e020ef08 Mon Sep 17 00:00:00 2001 From: Willian Rampazzo Date: Tue, 6 Jul 2021 15:17:26 +0200 Subject: [PATCH 08/23] avocado_qemu: Fix KNOWN_DISTROS map into the LinuxDistro class As the KNOWN_DISTROS grows, more loosely methods will be created in the avocado_qemu/__init__.py file. Let's refactor the code so that KNOWN_DISTROS and related methods are packaged in a class Signed-off-by: Wainer dos Santos Moschetta Signed-off-by: Eric Auger Message-Id: <20210706131729.30749-2-eric.auger@redhat.com> [CR: moved aarch64 definition from patch 2 to 1] [CR: protect get() when arch is not defined] [CR: split long lines] Acked-by: Wainer dos Santos Moschetta Signed-off-by: Cleber Rosa --- tests/acceptance/avocado_qemu/__init__.py | 86 +++++++++++++---------- 1 file changed, 49 insertions(+), 37 deletions(-) diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py index c3163af3b7..256befafc4 100644 --- a/tests/acceptance/avocado_qemu/__init__.py +++ b/tests/acceptance/avocado_qemu/__init__.py @@ -306,34 +306,50 @@ class LinuxSSHMixIn: f'Guest command failed: {command}') return stdout_lines, stderr_lines +class LinuxDistro: + """Represents a Linux distribution -#: A collection of known distros and their respective image checksum -KNOWN_DISTROS = { - 'fedora': { - '31': { - 'x86_64': - {'checksum': ('e3c1b309d9203604922d6e255c2c5d09' - '8a309c2d46215d8fc026954f3c5c27a0')}, - 'aarch64': - {'checksum': ('1e18d9c0cf734940c4b5d5ec592facae' - 'd2af0ad0329383d5639c997fdf16fe49')}, - 'ppc64': - {'checksum': ('7c3528b85a3df4b2306e892199a9e1e4' - '3f991c506f2cc390dc4efa2026ad2f58')}, - 's390x': - {'checksum': ('4caaab5a434fd4d1079149a072fdc789' - '1e354f834d355069ca982fdcaf5a122d')}, + Holds information of known distros. + """ + #: A collection of known distros and their respective image checksum + KNOWN_DISTROS = { + 'fedora': { + '31': { + 'x86_64': + {'checksum': ('e3c1b309d9203604922d6e255c2c5d09' + '8a309c2d46215d8fc026954f3c5c27a0')}, + 'aarch64': + {'checksum': ('1e18d9c0cf734940c4b5d5ec592facae' + 'd2af0ad0329383d5639c997fdf16fe49')}, + 'ppc64': + {'checksum': ('7c3528b85a3df4b2306e892199a9e1e4' + '3f991c506f2cc390dc4efa2026ad2f58')}, + 's390x': + {'checksum': ('4caaab5a434fd4d1079149a072fdc789' + '1e354f834d355069ca982fdcaf5a122d')}, } } } + def __init__(self, name, version, arch): + self.name = name + self.version = version + self.arch = arch + try: + info = self.KNOWN_DISTROS.get(name).get(version).get(arch) + except AttributeError: + # Unknown distro + info = None + self._info = info or {} -def get_known_distro_checksum(distro, distro_version, arch): - try: - return KNOWN_DISTROS.get(distro).get(distro_version).\ - get(arch).get('checksum') - except AttributeError: - return None + @property + def checksum(self): + """Gets the cloud-image file checksum""" + return self._info.get('checksum', None) + + @checksum.setter + def checksum(self, value): + self._info['checksum'] = value class LinuxTest(Test, LinuxSSHMixIn): @@ -344,24 +360,24 @@ class LinuxTest(Test, LinuxSSHMixIn): """ timeout = 900 - distro_checksum = None + distro = None username = 'root' password = 'password' def _set_distro(self): - distro = self.params.get( + distro_name = self.params.get( 'distro', default=self._get_unique_tag_val('distro')) - if not distro: - distro = 'fedora' - self.distro = distro + if not distro_name: + distro_name = 'fedora' distro_version = self.params.get( 'distro_version', default=self._get_unique_tag_val('distro_version')) if not distro_version: distro_version = '31' - self.distro_version = distro_version + + self.distro = LinuxDistro(distro_name, distro_version, self.arch) # The distro checksum behaves differently than distro name and # version. First, it does not respect a tag with the same @@ -370,13 +386,9 @@ class LinuxTest(Test, LinuxSSHMixIn): # order of precedence is: parameter, attribute and then value # from KNOWN_DISTROS. distro_checksum = self.params.get('distro_checksum', - default=self.distro_checksum) - if not distro_checksum: - distro_checksum = get_known_distro_checksum(self.distro, - self.distro_version, - self.arch) + default=None) if distro_checksum: - self.distro_checksum = distro_checksum + self.distro.checksum = distro_checksum def setUp(self, ssh_pubkey=None, network_device_type='virtio-net'): super(LinuxTest, self).setUp() @@ -418,14 +430,14 @@ class LinuxTest(Test, LinuxSSHMixIn): self.log.info('Downloading/preparing boot image') # Fedora 31 only provides ppc64le images image_arch = self.arch - if self.distro == 'fedora': + if self.distro.name == 'fedora': if image_arch == 'ppc64': image_arch = 'ppc64le' try: boot = vmimage.get( - self.distro, arch=image_arch, version=self.distro_version, - checksum=self.distro_checksum, + self.distro.name, arch=image_arch, version=self.distro.version, + checksum=self.distro.checksum, algorithm='sha256', cache_dir=self.cache_dirs[0], snapshot_dir=self.workdir) From c839d305b90d04643c21b30b8cd1828a9e995163 Mon Sep 17 00:00:00 2001 From: Willian Rampazzo Date: Tue, 6 Jul 2021 15:17:27 +0200 Subject: [PATCH 09/23] Acceptance Tests: Add default kernel params and pxeboot url to the KNOWN_DISTROS collection When running LinuxTests we may need to run the guest with custom params. It is practical to store the pxeboot URL and the default kernel params so that the tests just need to fetch those and augment the kernel params. Signed-off-by: Eric Auger Reviewed-by: Willian Rampazzo Message-Id: <20210706131729.30749-3-eric.auger@redhat.com> [CR: split long lines] Signed-off-by: Cleber Rosa --- tests/acceptance/avocado_qemu/__init__.py | 58 +++++++++++++++++++++-- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py index 256befafc4..1de1edce0d 100644 --- a/tests/acceptance/avocado_qemu/__init__.py +++ b/tests/acceptance/avocado_qemu/__init__.py @@ -317,17 +317,59 @@ class LinuxDistro: '31': { 'x86_64': {'checksum': ('e3c1b309d9203604922d6e255c2c5d09' - '8a309c2d46215d8fc026954f3c5c27a0')}, + '8a309c2d46215d8fc026954f3c5c27a0'), + 'pxeboot_url': ('https://archives.fedoraproject.org/' + 'pub/archive/fedora/linux/releases/31/' + 'Everything/x86_64/os/images/pxeboot/'), + 'kernel_params': ('root=UUID=b1438b9b-2cab-4065-a99a-' + '08a96687f73c ro no_timer_check ' + 'net.ifnames=0 console=tty1 ' + 'console=ttyS0,115200n8'), + }, 'aarch64': {'checksum': ('1e18d9c0cf734940c4b5d5ec592facae' - 'd2af0ad0329383d5639c997fdf16fe49')}, + 'd2af0ad0329383d5639c997fdf16fe49'), + 'pxeboot_url': 'https://archives.fedoraproject.org/' + 'pub/archive/fedora/linux/releases/31/' + 'Everything/aarch64/os/images/pxeboot/', + 'kernel_params': ('root=UUID=b6950a44-9f3c-4076-a9c2-' + '355e8475b0a7 ro earlyprintk=pl011,0x9000000' + ' ignore_loglevel no_timer_check' + ' printk.time=1 rd_NO_PLYMOUTH' + ' console=ttyAMA0'), + }, 'ppc64': {'checksum': ('7c3528b85a3df4b2306e892199a9e1e4' '3f991c506f2cc390dc4efa2026ad2f58')}, 's390x': {'checksum': ('4caaab5a434fd4d1079149a072fdc789' '1e354f834d355069ca982fdcaf5a122d')}, - } + }, + '32': { + 'aarch64': + {'checksum': ('b367755c664a2d7a26955bbfff985855' + 'adfa2ca15e908baf15b4b176d68d3967'), + 'pxeboot_url': ('http://dl.fedoraproject.org/pub/fedora/linux/' + 'releases/32/Server/aarch64/os/images/' + 'pxeboot/'), + 'kernel_params': ('root=UUID=3df75b65-be8d-4db4-8655-' + '14d95c0e90c5 ro no_timer_check net.ifnames=0' + ' console=tty1 console=ttyS0,115200n8'), + }, + }, + '33': { + 'aarch64': + {'checksum': ('e7f75cdfd523fe5ac2ca9eeece68edc1' + 'a81f386a17f969c1d1c7c87031008a6b'), + 'pxeboot_url': ('http://dl.fedoraproject.org/pub/fedora/linux/' + 'releases/33/Server/aarch64/os/images/' + 'pxeboot/'), + 'kernel_params': ('root=UUID=d20b3ffa-6397-4a63-a734-' + '1126a0208f8a ro no_timer_check net.ifnames=0' + ' console=tty1 console=ttyS0,115200n8' + ' console=tty0'), + }, + }, } } @@ -351,6 +393,16 @@ class LinuxDistro: def checksum(self, value): self._info['checksum'] = value + @property + def pxeboot_url(self): + """Gets the repository url where pxeboot files can be found""" + return self._info.get('pxeboot_url', None) + + @property + def default_kernel_params(self): + """Gets the default kernel parameters""" + return self._info.get('kernel_params', None) + class LinuxTest(Test, LinuxSSHMixIn): """Facilitates having a cloud-image Linux based available. From 6ace9b4e5e78f5d4fac1e5b63264945a5373afd5 Mon Sep 17 00:00:00 2001 From: Eric Auger Date: Tue, 6 Jul 2021 15:17:28 +0200 Subject: [PATCH 10/23] avocado_qemu: Add SMMUv3 tests Add new tests checking the good behavior of the SMMUv3 protecting 2 virtio pci devices (block and net). We check the guest boots and we are able to install a package. Different guest configs are tested: standard, passthrough an strict=0. This is tested with both fedora 31 and 33. The former uses a 5.3 kernel without range invalidation whereas the latter uses a 5.8 kernel that features range invalidation. Signed-off-by: Eric Auger Reviewed-by: Willian Rampazzo Reviewed-by: Wainer dos Santos Moschetta Tested-by: Wainer dos Santos Moschetta Message-Id: <20210706131729.30749-4-eric.auger@redhat.com> [CR: split long lines] [CR: added MAINTAINERS entry] Signed-off-by: Cleber Rosa --- MAINTAINERS | 1 + tests/acceptance/smmu.py | 137 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 tests/acceptance/smmu.py diff --git a/MAINTAINERS b/MAINTAINERS index c340bb02b0..148153d74f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -171,6 +171,7 @@ L: qemu-arm@nongnu.org S: Maintained F: hw/arm/smmu* F: include/hw/arm/smmu* +F: tests/acceptance/smmu.py AVR TCG CPUs M: Michael Rolnik diff --git a/tests/acceptance/smmu.py b/tests/acceptance/smmu.py new file mode 100644 index 0000000000..b3c4de6bf4 --- /dev/null +++ b/tests/acceptance/smmu.py @@ -0,0 +1,137 @@ +# SMMUv3 Functional tests +# +# Copyright (c) 2021 Red Hat, Inc. +# +# Author: +# Eric Auger +# +# This work is licensed under the terms of the GNU GPL, version 2 or +# later. See the COPYING file in the top-level directory. +import os + +from avocado import skipIf +from avocado_qemu import LinuxTest, BUILD_DIR + +@skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab') +class SMMU(LinuxTest): + """ + :avocado: tags=accel:kvm + :avocado: tags=cpu:host + :avocado: tags=arch:aarch64 + :avocado: tags=machine:virt + :avocado: tags=distro:fedora + :avocado: tags=smmu + """ + + IOMMU_ADDON = ',iommu_platform=on,disable-modern=off,disable-legacy=on' + kernel_path = None + initrd_path = None + kernel_params = None + + def set_up_boot(self): + path = self.download_boot() + self.vm.add_args('-device', 'virtio-blk-pci,bus=pcie.0,scsi=off,' + + 'drive=drv0,id=virtio-disk0,bootindex=1,' + 'werror=stop,rerror=stop' + self.IOMMU_ADDON) + self.vm.add_args('-drive', + 'file=%s,if=none,cache=writethrough,id=drv0' % path) + + def setUp(self): + super(SMMU, self).setUp(None, 'virtio-net-pci' + self.IOMMU_ADDON) + + def common_vm_setup(self, custom_kernel=False): + self.require_accelerator("kvm") + self.vm.add_args("-accel", "kvm") + self.vm.add_args("-cpu", "host") + self.vm.add_args("-machine", "iommu=smmuv3") + self.vm.add_args("-d", "guest_errors") + self.vm.add_args('-bios', os.path.join(BUILD_DIR, 'pc-bios', + 'edk2-aarch64-code.fd')) + self.vm.add_args('-device', 'virtio-rng-pci,rng=rng0') + self.vm.add_args('-object', + 'rng-random,id=rng0,filename=/dev/urandom') + + if custom_kernel is False: + return + + kernel_url = self.distro.pxeboot_url + 'vmlinuz' + initrd_url = self.distro.pxeboot_url + 'initrd.img' + self.kernel_path = self.fetch_asset(kernel_url) + self.initrd_path = self.fetch_asset(initrd_url) + + def run_and_check(self): + if self.kernel_path: + self.vm.add_args('-kernel', self.kernel_path, + '-append', self.kernel_params, + '-initrd', self.initrd_path) + self.launch_and_wait() + self.ssh_command('cat /proc/cmdline') + self.ssh_command('dnf -y install numactl-devel') + + + # 5.3 kernel without RIL # + + def test_smmu_noril(self): + """ + :avocado: tags=smmu_noril + :avocado: tags=smmu_noril_tests + :avocado: tags=distro_version:31 + """ + self.common_vm_setup() + self.run_and_check() + + def test_smmu_noril_passthrough(self): + """ + :avocado: tags=smmu_noril_passthrough + :avocado: tags=smmu_noril_tests + :avocado: tags=distro_version:31 + """ + self.common_vm_setup(True) + self.kernel_params = (self.distro.default_kernel_params + + ' iommu.passthrough=on') + self.run_and_check() + + def test_smmu_noril_nostrict(self): + """ + :avocado: tags=smmu_noril_nostrict + :avocado: tags=smmu_noril_tests + :avocado: tags=distro_version:31 + """ + self.common_vm_setup(True) + self.kernel_params = (self.distro.default_kernel_params + + ' iommu.strict=0') + self.run_and_check() + + # 5.8 kernel featuring range invalidation + # >= v5.7 kernel + + def test_smmu_ril(self): + """ + :avocado: tags=smmu_ril + :avocado: tags=smmu_ril_tests + :avocado: tags=distro_version:33 + """ + self.common_vm_setup() + self.run_and_check() + + def test_smmu_ril_passthrough(self): + """ + :avocado: tags=smmu_ril_passthrough + :avocado: tags=smmu_ril_tests + :avocado: tags=distro_version:33 + """ + self.common_vm_setup(True) + self.kernel_params = (self.distro.default_kernel_params + + ' iommu.passthrough=on') + self.run_and_check() + + def test_smmu_ril_nostrict(self): + """ + :avocado: tags=smmu_ril_nostrict + :avocado: tags=smmu_ril_tests + :avocado: tags=distro_version:33 + """ + self.common_vm_setup(True) + self.kernel_params = (self.distro.default_kernel_params + + ' iommu.strict=0') + self.run_and_check() From 5e57d4e895e59579b3c3a7119df259cdfde2d1ce Mon Sep 17 00:00:00 2001 From: Eric Auger Date: Tue, 6 Jul 2021 15:17:29 +0200 Subject: [PATCH 11/23] avocado_qemu: Add Intel iommu tests Add Intel IOMMU functional tests based on fedora 31. Different configs are checked: - strict - caching mode, strict - passthrough. Signed-off-by: Eric Auger Signed-off-by: Willian Rampazzo Tested-by: Wainer dos Santos Moschetta Acked-by: Peter Xu Message-Id: <20210706131729.30749-5-eric.auger@redhat.com> [CR: split long lines] Signed-off-by: Cleber Rosa --- tests/acceptance/intel_iommu.py | 119 ++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 tests/acceptance/intel_iommu.py diff --git a/tests/acceptance/intel_iommu.py b/tests/acceptance/intel_iommu.py new file mode 100644 index 0000000000..474d62f6bf --- /dev/null +++ b/tests/acceptance/intel_iommu.py @@ -0,0 +1,119 @@ +# INTEL_IOMMU Functional tests +# +# Copyright (c) 2021 Red Hat, Inc. +# +# Author: +# Eric Auger +# +# This work is licensed under the terms of the GNU GPL, version 2 or +# later. See the COPYING file in the top-level directory. +import os + +from avocado import skipIf +from avocado_qemu import LinuxTest + +@skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab') +class IntelIOMMU(LinuxTest): + """ + :avocado: tags=arch:x86_64 + :avocado: tags=distro:fedora + :avocado: tags=distro_version:31 + :avocado: tags=machine:q35 + :avocado: tags=accel:kvm + :avocado: tags=intel_iommu + """ + + IOMMU_ADDON = ',iommu_platform=on,disable-modern=off,disable-legacy=on' + kernel_path = None + initrd_path = None + kernel_params = None + + def set_up_boot(self): + path = self.download_boot() + self.vm.add_args('-device', 'virtio-blk-pci,bus=pcie.0,scsi=off,' + + 'drive=drv0,id=virtio-disk0,bootindex=1,' + 'werror=stop,rerror=stop' + self.IOMMU_ADDON) + self.vm.add_args('-device', 'virtio-gpu-pci' + self.IOMMU_ADDON) + self.vm.add_args('-drive', + 'file=%s,if=none,cache=writethrough,id=drv0' % path) + + def setUp(self): + super(IntelIOMMU, self).setUp(None, 'virtio-net-pci' + self.IOMMU_ADDON) + + def add_common_args(self): + self.vm.add_args('-device', 'virtio-rng-pci,rng=rng0') + self.vm.add_args('-object', + 'rng-random,id=rng0,filename=/dev/urandom') + + def common_vm_setup(self, custom_kernel=None): + self.require_accelerator("kvm") + self.add_common_args() + self.vm.add_args("-accel", "kvm") + + if custom_kernel is None: + return + + kernel_url = self.distro.pxeboot_url + 'vmlinuz' + initrd_url = self.distro.pxeboot_url + 'initrd.img' + self.kernel_path = self.fetch_asset(kernel_url) + self.initrd_path = self.fetch_asset(initrd_url) + + def run_and_check(self): + if self.kernel_path: + self.vm.add_args('-kernel', self.kernel_path, + '-append', self.kernel_params, + '-initrd', self.initrd_path) + self.launch_and_wait() + self.ssh_command('cat /proc/cmdline') + self.ssh_command('dmesg | grep -e DMAR -e IOMMU') + self.ssh_command('find /sys/kernel/iommu_groups/ -type l') + self.ssh_command('dnf -y install numactl-devel') + + def test_intel_iommu(self): + """ + :avocado: tags=intel_iommu_intremap + """ + + self.common_vm_setup(True) + self.vm.add_args('-device', 'intel-iommu,intremap=on') + self.vm.add_args('-machine', 'kernel_irqchip=split') + + self.kernel_params = (self.distro.default_kernel_params + + ' quiet intel_iommu=on') + self.run_and_check() + + def test_intel_iommu_strict(self): + """ + :avocado: tags=intel_iommu_strict + """ + + self.common_vm_setup(True) + self.vm.add_args('-device', 'intel-iommu,intremap=on') + self.vm.add_args('-machine', 'kernel_irqchip=split') + self.kernel_params = (self.distro.default_kernel_params + + ' quiet intel_iommu=on,strict') + self.run_and_check() + + def test_intel_iommu_strict_cm(self): + """ + :avocado: tags=intel_iommu_strict_cm + """ + + self.common_vm_setup(True) + self.vm.add_args('-device', 'intel-iommu,intremap=on,caching-mode=on') + self.vm.add_args('-machine', 'kernel_irqchip=split') + self.kernel_params = (self.distro.default_kernel_params + + ' quiet intel_iommu=on,strict') + self.run_and_check() + + def test_intel_iommu_pt(self): + """ + :avocado: tags=intel_iommu_pt + """ + + self.common_vm_setup(True) + self.vm.add_args('-device', 'intel-iommu,intremap=on') + self.vm.add_args('-machine', 'kernel_irqchip=split') + self.kernel_params = (self.distro.default_kernel_params + + ' quiet intel_iommu=on iommu=pt') + self.run_and_check() From 012293c1b1451edc28e9b3a6ea573d74c5ed373c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 23 Jun 2021 20:00:15 +0200 Subject: [PATCH 12/23] tests/acceptance: Tag NetBSD tests as 'os:netbsd' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avocado allows us to select set of tests using tags. When wanting to run all tests using a NetBSD guest OS, it is convenient to have them tagged, add the 'os:netbsd' tag. It allows one to run the NetBSD tests with: $ avocado --show=app,console run -t os:netbsd tests/acceptance/ Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20210623180021.898286-4-f4bug@amsat.org> Reviewed-by: Niek Linnenbank Reviewed-by: Willian Rampazzo Reviewed-by: Cleber Rosa [PMD: ammend the commit message with example command] Signed-off-by: Cleber Rosa --- tests/acceptance/boot_linux_console.py | 1 + tests/acceptance/ppc_prep_40p.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py index 3ae11a7a8f..0a8222f17d 100644 --- a/tests/acceptance/boot_linux_console.py +++ b/tests/acceptance/boot_linux_console.py @@ -905,6 +905,7 @@ class BootLinuxConsole(LinuxKernelTest): :avocado: tags=arch:arm :avocado: tags=machine:orangepi-pc :avocado: tags=device:sd + :avocado: tags=os:netbsd """ # This test download a 304MB compressed image and expand it to 2GB deb_url = ('http://snapshot.debian.org/archive/debian/' diff --git a/tests/acceptance/ppc_prep_40p.py b/tests/acceptance/ppc_prep_40p.py index 96ba13b894..2993ee3b07 100644 --- a/tests/acceptance/ppc_prep_40p.py +++ b/tests/acceptance/ppc_prep_40p.py @@ -27,6 +27,7 @@ class IbmPrep40pMachine(Test): """ :avocado: tags=arch:ppc :avocado: tags=machine:40p + :avocado: tags=os:netbsd :avocado: tags=slowness:high """ bios_url = ('http://ftpmirror.your.org/pub/misc/' @@ -64,6 +65,7 @@ class IbmPrep40pMachine(Test): """ :avocado: tags=arch:ppc :avocado: tags=machine:40p + :avocado: tags=os:netbsd """ drive_url = ('https://cdn.netbsd.org/pub/NetBSD/iso/7.1.2/' 'NetBSD-7.1.2-prep.iso') From 20bbf846b960477a71284bbf848437f2a6e7c804 Mon Sep 17 00:00:00 2001 From: Wainer dos Santos Moschetta Date: Fri, 30 Apr 2021 10:34:08 -0300 Subject: [PATCH 13/23] tests/acceptance: Automatic set -cpu to the test vm This introduces a new feature to the functional tests: automatic setting of the '-cpu VALUE' option to the created vm if the test is tagged with 'cpu:VALUE'. The 'cpu' property is made available to the test object as well. For example, for a simple test as: def test(self): """ :avocado: tags=cpu:host """ self.assertEqual(self.cpu, "host") self.vm.launch() The resulting QEMU evocation will be like: qemu-system-x86_64 -display none -vga none \ -chardev socket,id=mon,path=/var/tmp/avo_qemu_sock_pdgzbgd_/qemu-1135557-monitor.sock \ -mon chardev=mon,mode=control -cpu host Reviewed-by: Cleber Rosa Tested-by: Cleber Rosa Reviewed-by: Willian Rampazzo Signed-off-by: Wainer dos Santos Moschetta Message-Id: <20210430133414.39905-2-wainersm@redhat.com> Signed-off-by: Cleber Rosa --- docs/devel/testing.rst | 17 +++++++++++++++++ tests/acceptance/avocado_qemu/__init__.py | 5 +++++ 2 files changed, 22 insertions(+) diff --git a/docs/devel/testing.rst b/docs/devel/testing.rst index 19cbf532ae..8f572255d3 100644 --- a/docs/devel/testing.rst +++ b/docs/devel/testing.rst @@ -904,6 +904,17 @@ name. If one is not given explicitly, it will either be set to ``None``, or, if the test is tagged with one (and only one) ``:avocado: tags=arch:VALUE`` tag, it will be set to ``VALUE``. +cpu +~~~ + +The cpu model that will be set to all QEMUMachine instances created +by the test. + +The ``cpu`` attribute will be set to the test parameter of the same +name. If one is not given explicitly, it will either be set to +``None ``, or, if the test is tagged with one (and only one) +``:avocado: tags=cpu:VALUE`` tag, it will be set to ``VALUE``. + machine ~~~~~~~ @@ -983,6 +994,12 @@ architecture of a kernel or disk image to boot a VM with. This parameter has a direct relation with the ``arch`` attribute. If not given, it will default to None. +cpu +~~~ + +The cpu model that will be set to all QEMUMachine instances created +by the test. + machine ~~~~~~~ diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py index 1de1edce0d..3a218057b3 100644 --- a/tests/acceptance/avocado_qemu/__init__.py +++ b/tests/acceptance/avocado_qemu/__init__.py @@ -213,6 +213,9 @@ class Test(avocado.Test): self.arch = self.params.get('arch', default=self._get_unique_tag_val('arch')) + self.cpu = self.params.get('cpu', + default=self._get_unique_tag_val('cpu')) + self.machine = self.params.get('machine', default=self._get_unique_tag_val('machine')) @@ -242,6 +245,8 @@ class Test(avocado.Test): name = str(uuid.uuid4()) if self._vms.get(name) is None: self._vms[name] = self._new_vm(name, *args) + if self.cpu is not None: + self._vms[name].add_args('-cpu', self.cpu) if self.machine is not None: self._vms[name].set_machine(self.machine) return self._vms[name] From 8a7c1fdecb91b6aeb943156a169fd7a160691542 Mon Sep 17 00:00:00 2001 From: Wainer dos Santos Moschetta Date: Fri, 30 Apr 2021 10:34:09 -0300 Subject: [PATCH 14/23] tests/acceptance: Fix mismatch on cpu tagged tests There are test cases on machine_mips_malta.py and tcg_plugins.py files where the cpu tag does not correspond to the value actually given to the QEMU binary. This fixed those tests tags. Reviewed-by: Cleber Rosa Tested-by: Cleber Rosa Reviewed-by: Willian Rampazzo Signed-off-by: Wainer dos Santos Moschetta Message-Id: <20210430133414.39905-3-wainersm@redhat.com> Signed-off-by: Cleber Rosa --- tests/acceptance/machine_mips_malta.py | 6 +++--- tests/acceptance/tcg_plugins.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/acceptance/machine_mips_malta.py b/tests/acceptance/machine_mips_malta.py index 7c9a4ee4d2..b1fd075f51 100644 --- a/tests/acceptance/machine_mips_malta.py +++ b/tests/acceptance/machine_mips_malta.py @@ -96,7 +96,7 @@ class MaltaMachineFramebuffer(Test): """ :avocado: tags=arch:mips64el :avocado: tags=machine:malta - :avocado: tags=cpu:i6400 + :avocado: tags=cpu:I6400 """ self.do_test_i6400_framebuffer_logo(1) @@ -105,7 +105,7 @@ class MaltaMachineFramebuffer(Test): """ :avocado: tags=arch:mips64el :avocado: tags=machine:malta - :avocado: tags=cpu:i6400 + :avocado: tags=cpu:I6400 :avocado: tags=mips:smp """ self.do_test_i6400_framebuffer_logo(7) @@ -115,7 +115,7 @@ class MaltaMachineFramebuffer(Test): """ :avocado: tags=arch:mips64el :avocado: tags=machine:malta - :avocado: tags=cpu:i6400 + :avocado: tags=cpu:I6400 :avocado: tags=mips:smp """ self.do_test_i6400_framebuffer_logo(8) diff --git a/tests/acceptance/tcg_plugins.py b/tests/acceptance/tcg_plugins.py index c21bf9e52a..aa6e18b62d 100644 --- a/tests/acceptance/tcg_plugins.py +++ b/tests/acceptance/tcg_plugins.py @@ -68,7 +68,7 @@ class PluginKernelNormal(PluginKernelBase): :avocado: tags=accel:tcg :avocado: tags=arch:aarch64 :avocado: tags=machine:virt - :avocado: tags=cpu:cortex-a57 + :avocado: tags=cpu:cortex-a53 """ kernel_path = self._grab_aarch64_kernel() kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + @@ -95,7 +95,7 @@ class PluginKernelNormal(PluginKernelBase): :avocado: tags=accel:tcg :avocado: tags=arch:aarch64 :avocado: tags=machine:virt - :avocado: tags=cpu:cortex-a57 + :avocado: tags=cpu:cortex-a53 """ kernel_path = self._grab_aarch64_kernel() kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + @@ -121,7 +121,7 @@ class PluginKernelNormal(PluginKernelBase): :avocado: tags=accel:tcg :avocado: tags=arch:aarch64 :avocado: tags=machine:virt - :avocado: tags=cpu:cortex-a57 + :avocado: tags=cpu:cortex-a53 """ kernel_path = self._grab_aarch64_kernel() kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + From d377ba48524781310536d5e97642e4b95a4b62c8 Mon Sep 17 00:00:00 2001 From: Wainer dos Santos Moschetta Date: Fri, 30 Apr 2021 10:34:10 -0300 Subject: [PATCH 15/23] tests/acceptance: Let the framework handle "cpu:VALUE" tagged tests The tests that are already tagged with "cpu:VALUE" don't need to add "-cpu VALUE" to the list of arguments of the vm object because the avocado_qemu framework is able to handle it automatically. Reviewed-by: Cleber Rosa Tested-by: Cleber Rosa Reviewed-by: Willian Rampazzo Signed-off-by: Wainer dos Santos Moschetta Message-Id: <20210430133414.39905-4-wainersm@redhat.com> Signed-off-by: Cleber Rosa --- tests/acceptance/boot_linux.py | 3 --- tests/acceptance/boot_xen.py | 1 - tests/acceptance/machine_mips_malta.py | 1 - tests/acceptance/replay_kernel.py | 8 +++----- tests/acceptance/reverse_debugging.py | 2 +- tests/acceptance/tcg_plugins.py | 9 ++++----- 6 files changed, 8 insertions(+), 16 deletions(-) diff --git a/tests/acceptance/boot_linux.py b/tests/acceptance/boot_linux.py index 34c4366366..ab19146d1e 100644 --- a/tests/acceptance/boot_linux.py +++ b/tests/acceptance/boot_linux.py @@ -79,7 +79,6 @@ class BootLinuxAarch64(LinuxTest): """ self.require_accelerator("tcg") self.vm.add_args("-accel", "tcg") - self.vm.add_args("-cpu", "max") self.vm.add_args("-machine", "virt,gic-version=2") self.add_common_args() self.launch_and_wait(set_up_ssh_connection=False) @@ -92,7 +91,6 @@ class BootLinuxAarch64(LinuxTest): """ self.require_accelerator("tcg") self.vm.add_args("-accel", "tcg") - self.vm.add_args("-cpu", "max") self.vm.add_args("-machine", "virt,gic-version=3") self.add_common_args() self.launch_and_wait(set_up_ssh_connection=False) @@ -104,7 +102,6 @@ class BootLinuxAarch64(LinuxTest): """ self.require_accelerator("kvm") self.vm.add_args("-accel", "kvm") - self.vm.add_args("-cpu", "host") self.vm.add_args("-machine", "virt,gic-version=host") self.add_common_args() self.launch_and_wait(set_up_ssh_connection=False) diff --git a/tests/acceptance/boot_xen.py b/tests/acceptance/boot_xen.py index 75c2d44492..3479b5233b 100644 --- a/tests/acceptance/boot_xen.py +++ b/tests/acceptance/boot_xen.py @@ -48,7 +48,6 @@ class BootXenBase(LinuxKernelTest): xen_command_line = self.XEN_COMMON_COMMAND_LINE self.vm.add_args('-machine', 'virtualization=on', - '-cpu', 'cortex-a57', '-m', '768', '-kernel', xen_path, '-append', xen_command_line, diff --git a/tests/acceptance/machine_mips_malta.py b/tests/acceptance/machine_mips_malta.py index b1fd075f51..b67d8cb141 100644 --- a/tests/acceptance/machine_mips_malta.py +++ b/tests/acceptance/machine_mips_malta.py @@ -62,7 +62,6 @@ class MaltaMachineFramebuffer(Test): kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + 'clocksource=GIC console=tty0 console=ttyS0') self.vm.add_args('-kernel', kernel_path, - '-cpu', 'I6400', '-smp', '%u' % cpu_cores_count, '-vga', 'std', '-append', kernel_command_line) diff --git a/tests/acceptance/replay_kernel.py b/tests/acceptance/replay_kernel.py index 71facdaa75..75f80506c1 100644 --- a/tests/acceptance/replay_kernel.py +++ b/tests/acceptance/replay_kernel.py @@ -156,8 +156,7 @@ class ReplayKernelNormal(ReplayKernelBase): 'console=ttyAMA0') console_pattern = 'VFS: Cannot open root device' - self.run_rr(kernel_path, kernel_command_line, console_pattern, - args=('-cpu', 'cortex-a53')) + self.run_rr(kernel_path, kernel_command_line, console_pattern) def test_arm_virt(self): """ @@ -301,7 +300,7 @@ class ReplayKernelNormal(ReplayKernelBase): tar_url = ('https://www.qemu-advent-calendar.org' '/2018/download/day19.tar.xz') file_path = self.fetch_asset(tar_url, asset_hash=tar_hash) - self.do_test_advcal_2018(file_path, 'uImage', ('-cpu', 'e5500')) + self.do_test_advcal_2018(file_path, 'uImage') def test_ppc_g3beige(self): """ @@ -348,8 +347,7 @@ class ReplayKernelNormal(ReplayKernelBase): tar_url = ('https://www.qemu-advent-calendar.org' '/2018/download/day02.tar.xz') file_path = self.fetch_asset(tar_url, asset_hash=tar_hash) - self.do_test_advcal_2018(file_path, 'santas-sleigh-ride.elf', - args=('-cpu', 'dc233c')) + self.do_test_advcal_2018(file_path, 'santas-sleigh-ride.elf') @skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout') class ReplayKernelSlow(ReplayKernelBase): diff --git a/tests/acceptance/reverse_debugging.py b/tests/acceptance/reverse_debugging.py index be01aca217..d2921e70c3 100644 --- a/tests/acceptance/reverse_debugging.py +++ b/tests/acceptance/reverse_debugging.py @@ -207,4 +207,4 @@ class ReverseDebugging_AArch64(ReverseDebugging): kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) self.reverse_debugging( - args=('-kernel', kernel_path, '-cpu', 'cortex-a53')) + args=('-kernel', kernel_path)) diff --git a/tests/acceptance/tcg_plugins.py b/tests/acceptance/tcg_plugins.py index aa6e18b62d..9ca1515c3b 100644 --- a/tests/acceptance/tcg_plugins.py +++ b/tests/acceptance/tcg_plugins.py @@ -25,7 +25,7 @@ class PluginKernelBase(LinuxKernelTest): KERNEL_COMMON_COMMAND_LINE = 'printk.time=1 panic=-1 ' def run_vm(self, kernel_path, kernel_command_line, - plugin, plugin_log, console_pattern, args): + plugin, plugin_log, console_pattern, args=None): vm = self.get_vm() vm.set_console() @@ -80,8 +80,7 @@ class PluginKernelNormal(PluginKernelBase): self.run_vm(kernel_path, kernel_command_line, "tests/plugin/libinsn.so", plugin_log.name, - console_pattern, - args=('-cpu', 'cortex-a53')) + console_pattern) with plugin_log as lf, \ mmap.mmap(lf.fileno(), 0, access=mmap.ACCESS_READ) as s: @@ -108,7 +107,7 @@ class PluginKernelNormal(PluginKernelBase): self.run_vm(kernel_path, kernel_command_line, "tests/plugin/libinsn.so", plugin_log.name, console_pattern, - args=('-cpu', 'cortex-a53', '-icount', 'shift=1')) + args=('-icount', 'shift=1')) with plugin_log as lf, \ mmap.mmap(lf.fileno(), 0, access=mmap.ACCESS_READ) as s: @@ -134,7 +133,7 @@ class PluginKernelNormal(PluginKernelBase): self.run_vm(kernel_path, kernel_command_line, "tests/plugin/libmem.so,arg=both", plugin_log.name, console_pattern, - args=('-cpu', 'cortex-a53', '-icount', 'shift=1')) + args=('-icount', 'shift=1')) with plugin_log as lf, \ mmap.mmap(lf.fileno(), 0, access=mmap.ACCESS_READ) as s: From 2d14975963b831701363a1153a0db97dc19e0d2e Mon Sep 17 00:00:00 2001 From: Wainer dos Santos Moschetta Date: Fri, 30 Apr 2021 10:34:11 -0300 Subject: [PATCH 16/23] tests/acceptance: Tagging tests with "cpu:VALUE" The existing tests which are passing "-cpu VALUE" argument to the vm object are now properly "cpu:VALUE" tagged, so letting the avocado_qemu framework to handle that automatically. Reviewed-by: Cleber Rosa Reviewed-by: Willian Rampazzo Signed-off-by: Wainer dos Santos Moschetta Message-Id: <20210430133414.39905-5-wainersm@redhat.com> Signed-off-by: Cleber Rosa --- tests/acceptance/boot_linux_console.py | 13 ++++++++----- tests/acceptance/pc_cpu_hotplug_props.py | 2 +- tests/acceptance/replay_kernel.py | 9 ++++++--- tests/acceptance/virtio-gpu.py | 4 ++-- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py index 0a8222f17d..5248c8097d 100644 --- a/tests/acceptance/boot_linux_console.py +++ b/tests/acceptance/boot_linux_console.py @@ -239,6 +239,7 @@ class BootLinuxConsole(LinuxKernelTest): :avocado: tags=arch:mips64el :avocado: tags=machine:malta :avocado: tags=endian:little + :avocado: tags=cpu:5KEc """ kernel_url = ('https://github.com/philmd/qemu-testing-blob/' 'raw/9ad2df38/mips/malta/mips64el/' @@ -258,8 +259,7 @@ class BootLinuxConsole(LinuxKernelTest): kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0 console=tty ' + 'rdinit=/sbin/init noreboot') - self.vm.add_args('-cpu', '5KEc', - '-kernel', kernel_path, + self.vm.add_args('-kernel', kernel_path, '-initrd', initrd_path, '-append', kernel_command_line, '-no-reboot') @@ -287,7 +287,6 @@ class BootLinuxConsole(LinuxKernelTest): + 'mem=256m@@0x0 ' + 'console=ttyS0') self.vm.add_args('-no-reboot', - '-cpu', 'I7200', '-kernel', kernel_path, '-append', kernel_command_line) self.vm.launch() @@ -299,6 +298,7 @@ class BootLinuxConsole(LinuxKernelTest): :avocado: tags=arch:mipsel :avocado: tags=machine:malta :avocado: tags=endian:little + :avocado: tags=cpu:I7200 """ kernel_url = ('https://mipsdistros.mips.com/LinuxDistro/nanomips/' 'kernels/v4.15.18-432-gb2eb9a8b07a1-20180627102142/' @@ -311,6 +311,7 @@ class BootLinuxConsole(LinuxKernelTest): :avocado: tags=arch:mipsel :avocado: tags=machine:malta :avocado: tags=endian:little + :avocado: tags=cpu:I7200 """ kernel_url = ('https://mipsdistros.mips.com/LinuxDistro/nanomips/' 'kernels/v4.15.18-432-gb2eb9a8b07a1-20180627102142/' @@ -323,6 +324,7 @@ class BootLinuxConsole(LinuxKernelTest): :avocado: tags=arch:mipsel :avocado: tags=machine:malta :avocado: tags=endian:little + :avocado: tags=cpu:I7200 """ kernel_url = ('https://mipsdistros.mips.com/LinuxDistro/nanomips/' 'kernels/v4.15.18-432-gb2eb9a8b07a1-20180627102142/' @@ -335,6 +337,7 @@ class BootLinuxConsole(LinuxKernelTest): :avocado: tags=arch:aarch64 :avocado: tags=machine:virt :avocado: tags=accel:tcg + :avocado: tags=cpu:cortex-a53 """ kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora' '/linux/releases/29/Everything/aarch64/os/images/pxeboot' @@ -1168,9 +1171,9 @@ class BootLinuxConsole(LinuxKernelTest): """ :avocado: tags=arch:ppc64 :avocado: tags=machine:ppce500 + :avocado: tags=cpu:e5500 """ tar_hash = '6951d86d644b302898da2fd701739c9406527fe1' - self.vm.add_args('-cpu', 'e5500') self.do_test_advcal_2018('19', tar_hash, 'uImage') def test_ppc_g3beige(self): @@ -1212,7 +1215,7 @@ class BootLinuxConsole(LinuxKernelTest): """ :avocado: tags=arch:xtensa :avocado: tags=machine:lx60 + :avocado: tags=cpu:dc233c """ tar_hash = '49e88d9933742f0164b60839886c9739cb7a0d34' - self.vm.add_args('-cpu', 'dc233c') self.do_test_advcal_2018('02', tar_hash, 'santas-sleigh-ride.elf') diff --git a/tests/acceptance/pc_cpu_hotplug_props.py b/tests/acceptance/pc_cpu_hotplug_props.py index f48f68fc6b..2e86d5017a 100644 --- a/tests/acceptance/pc_cpu_hotplug_props.py +++ b/tests/acceptance/pc_cpu_hotplug_props.py @@ -25,11 +25,11 @@ from avocado_qemu import Test class OmittedCPUProps(Test): """ :avocado: tags=arch:x86_64 + :avocado: tags=cpu:qemu64 """ def test_no_die_id(self): self.vm.add_args('-nodefaults', '-S') self.vm.add_args('-smp', '1,sockets=2,cores=2,threads=2,maxcpus=8') - self.vm.add_args('-cpu', 'qemu64') self.vm.add_args('-device', 'qemu64-x86_64-cpu,socket-id=1,core-id=0,thread-id=0') self.vm.launch() self.assertEquals(len(self.vm.command('query-cpus-fast')), 2) diff --git a/tests/acceptance/replay_kernel.py b/tests/acceptance/replay_kernel.py index 75f80506c1..bb32b31240 100644 --- a/tests/acceptance/replay_kernel.py +++ b/tests/acceptance/replay_kernel.py @@ -392,6 +392,7 @@ class ReplayKernelSlow(ReplayKernelBase): :avocado: tags=machine:malta :avocado: tags=endian:little :avocado: tags=slowness:high + :avocado: tags=cpu:5KEc """ kernel_url = ('https://github.com/philmd/qemu-testing-blob/' 'raw/9ad2df38/mips/malta/mips64el/' @@ -412,7 +413,7 @@ class ReplayKernelSlow(ReplayKernelBase): 'rdinit=/sbin/init noreboot') console_pattern = 'Boot successful.' self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5, - args=('-initrd', initrd_path, '-cpu', '5KEc')) + args=('-initrd', initrd_path)) def do_test_mips_malta32el_nanomips(self, kernel_path_xz): kernel_path = self.workdir + "kernel" @@ -424,14 +425,14 @@ class ReplayKernelSlow(ReplayKernelBase): 'mem=256m@@0x0 ' 'console=ttyS0') console_pattern = 'Kernel command line: %s' % kernel_command_line - self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5, - args=('-cpu', 'I7200')) + self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5) def test_mips_malta32el_nanomips_4k(self): """ :avocado: tags=arch:mipsel :avocado: tags=machine:malta :avocado: tags=endian:little + :avocado: tags=cpu:I7200 """ kernel_url = ('https://mipsdistros.mips.com/LinuxDistro/nanomips/' 'kernels/v4.15.18-432-gb2eb9a8b07a1-20180627102142/' @@ -445,6 +446,7 @@ class ReplayKernelSlow(ReplayKernelBase): :avocado: tags=arch:mipsel :avocado: tags=machine:malta :avocado: tags=endian:little + :avocado: tags=cpu:I7200 """ kernel_url = ('https://mipsdistros.mips.com/LinuxDistro/nanomips/' 'kernels/v4.15.18-432-gb2eb9a8b07a1-20180627102142/' @@ -458,6 +460,7 @@ class ReplayKernelSlow(ReplayKernelBase): :avocado: tags=arch:mipsel :avocado: tags=machine:malta :avocado: tags=endian:little + :avocado: tags=cpu:I7200 """ kernel_url = ('https://mipsdistros.mips.com/LinuxDistro/nanomips/' 'kernels/v4.15.18-432-gb2eb9a8b07a1-20180627102142/' diff --git a/tests/acceptance/virtio-gpu.py b/tests/acceptance/virtio-gpu.py index e7979343e9..589332c1b7 100644 --- a/tests/acceptance/virtio-gpu.py +++ b/tests/acceptance/virtio-gpu.py @@ -60,6 +60,7 @@ class VirtioGPUx86(Test): """ :avocado: tags=arch:x86_64 :avocado: tags=device:virtio-vga + :avocado: tags=cpu:host """ kernel_command_line = ( self.KERNEL_COMMON_COMMAND_LINE + "console=ttyS0 rdinit=/bin/bash" @@ -72,7 +73,6 @@ class VirtioGPUx86(Test): initrd_path = self.fetch_asset(self.INITRD_URL) self.vm.set_console() - self.vm.add_args("-cpu", "host") self.vm.add_args("-m", "2G") self.vm.add_args("-machine", "pc,accel=kvm") self.vm.add_args("-device", "virtio-vga,virgl=on") @@ -101,6 +101,7 @@ class VirtioGPUx86(Test): """ :avocado: tags=arch:x86_64 :avocado: tags=device:vhost-user-vga + :avocado: tags=cpu:host """ kernel_command_line = ( self.KERNEL_COMMON_COMMAND_LINE + "console=ttyS0 rdinit=/bin/bash" @@ -140,7 +141,6 @@ class VirtioGPUx86(Test): ) self.vm.set_console() - self.vm.add_args("-cpu", "host") self.vm.add_args("-m", "2G") self.vm.add_args("-object", "memory-backend-memfd,id=mem,size=2G") self.vm.add_args("-machine", "pc,memory-backend=mem,accel=kvm") From 555fe0c2a8d5c8a9b6dbf17670018cc2d8f062b3 Mon Sep 17 00:00:00 2001 From: Wainer dos Santos Moschetta Date: Fri, 30 Apr 2021 10:34:12 -0300 Subject: [PATCH 17/23] python/qemu: Add args property to the QEMUMachine class This added the args property to QEMUMachine so that users of the class can access and handle the list of arguments to be given to the QEMU binary. Reviewed-by: Cleber Rosa Reviewed-by: Willian Rampazzo Signed-off-by: Wainer dos Santos Moschetta Message-Id: <20210430133414.39905-6-wainersm@redhat.com> Signed-off-by: Cleber Rosa --- python/qemu/machine/machine.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/python/qemu/machine/machine.py b/python/qemu/machine/machine.py index 94846dd71b..971ed7e8c6 100644 --- a/python/qemu/machine/machine.py +++ b/python/qemu/machine/machine.py @@ -316,6 +316,11 @@ class QEMUMachine: args.extend(['-device', device]) return args + @property + def args(self) -> List[str]: + """Returns the list of arguments given to the QEMU binary.""" + return self._args + def _pre_launch(self) -> None: if self._console_set: self._remove_files.append(self._console_address) From 58954ac0b59966ebd32720b183a3c7fcfc60e83d Mon Sep 17 00:00:00 2001 From: Wainer dos Santos Moschetta Date: Fri, 30 Apr 2021 10:34:13 -0300 Subject: [PATCH 18/23] tests/acceptance: Add set_vm_arg() to the Test class The set_vm_arg method is added to avocado_qemu.Test class on this change. Use that method to set (or replace) an argument to the list of arguments given to the QEMU binary. Suggested-by: Cleber Rosa Signed-off-by: Wainer dos Santos Moschetta Reviewed-by: Willian Rampazzo Message-Id: <20210430133414.39905-7-wainersm@redhat.com> Signed-off-by: Cleber Rosa --- tests/acceptance/avocado_qemu/__init__.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py index 3a218057b3..2c4fef3e14 100644 --- a/tests/acceptance/avocado_qemu/__init__.py +++ b/tests/acceptance/avocado_qemu/__init__.py @@ -251,6 +251,27 @@ class Test(avocado.Test): self._vms[name].set_machine(self.machine) return self._vms[name] + def set_vm_arg(self, arg, value): + """ + Set an argument to list of extra arguments to be given to the QEMU + binary. If the argument already exists then its value is replaced. + + :param arg: the QEMU argument, such as "-cpu" in "-cpu host" + :type arg: str + :param value: the argument value, such as "host" in "-cpu host" + :type value: str + """ + if not arg or not value: + return + if arg not in self.vm.args: + self.vm.args.extend([arg, value]) + else: + idx = self.vm.args.index(arg) + 1 + if idx < len(self.vm.args): + self.vm.args[idx] = value + else: + self.vm.args.append(value) + def tearDown(self): for vm in self._vms.values(): vm.shutdown() From 3843a32152a54092f1fc2c8eb54a03da64ad4c6d Mon Sep 17 00:00:00 2001 From: Wainer dos Santos Moschetta Date: Fri, 30 Apr 2021 10:34:14 -0300 Subject: [PATCH 19/23] tests/acceptance: Handle cpu tag on x86_cpu_model_versions tests Some test cases on x86_cpu_model_versions.py are corner cases because they need to pass extra options to the -cpu argument. Once the avocado_qemu framework will set -cpu automatically, the value should be reset. This changed those tests so to call set_vm_arg() to overwrite the -cpu value. Signed-off-by: Wainer dos Santos Moschetta Reviewed-by: Willian Rampazzo Message-Id: <20210430133414.39905-8-wainersm@redhat.com> Signed-off-by: Cleber Rosa --- tests/acceptance/x86_cpu_model_versions.py | 40 +++++++++++++++++----- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/tests/acceptance/x86_cpu_model_versions.py b/tests/acceptance/x86_cpu_model_versions.py index 77ed8597a4..0e9feda62d 100644 --- a/tests/acceptance/x86_cpu_model_versions.py +++ b/tests/acceptance/x86_cpu_model_versions.py @@ -252,10 +252,13 @@ class CascadelakeArchCapabilities(avocado_qemu.Test): def test_4_1(self): """ :avocado: tags=machine:pc-i440fx-4.1 + :avocado: tags=cpu:Cascadelake-Server """ # machine-type only: self.vm.add_args('-S') - self.vm.add_args('-cpu', 'Cascadelake-Server,x-force-features=on,check=off,enforce=off') + self.set_vm_arg('-cpu', + 'Cascadelake-Server,x-force-features=on,check=off,' + 'enforce=off') self.vm.launch() self.assertFalse(self.get_cpu_prop('arch-capabilities'), 'pc-i440fx-4.1 + Cascadelake-Server should not have arch-capabilities') @@ -263,9 +266,12 @@ class CascadelakeArchCapabilities(avocado_qemu.Test): def test_4_0(self): """ :avocado: tags=machine:pc-i440fx-4.0 + :avocado: tags=cpu:Cascadelake-Server """ self.vm.add_args('-S') - self.vm.add_args('-cpu', 'Cascadelake-Server,x-force-features=on,check=off,enforce=off') + self.set_vm_arg('-cpu', + 'Cascadelake-Server,x-force-features=on,check=off,' + 'enforce=off') self.vm.launch() self.assertFalse(self.get_cpu_prop('arch-capabilities'), 'pc-i440fx-4.0 + Cascadelake-Server should not have arch-capabilities') @@ -273,10 +279,13 @@ class CascadelakeArchCapabilities(avocado_qemu.Test): def test_set_4_0(self): """ :avocado: tags=machine:pc-i440fx-4.0 + :avocado: tags=cpu:Cascadelake-Server """ # command line must override machine-type if CPU model is not versioned: self.vm.add_args('-S') - self.vm.add_args('-cpu', 'Cascadelake-Server,x-force-features=on,check=off,enforce=off,+arch-capabilities') + self.set_vm_arg('-cpu', + 'Cascadelake-Server,x-force-features=on,check=off,' + 'enforce=off,+arch-capabilities') self.vm.launch() self.assertTrue(self.get_cpu_prop('arch-capabilities'), 'pc-i440fx-4.0 + Cascadelake-Server,+arch-capabilities should have arch-capabilities') @@ -284,9 +293,12 @@ class CascadelakeArchCapabilities(avocado_qemu.Test): def test_unset_4_1(self): """ :avocado: tags=machine:pc-i440fx-4.1 + :avocado: tags=cpu:Cascadelake-Server """ self.vm.add_args('-S') - self.vm.add_args('-cpu', 'Cascadelake-Server,x-force-features=on,check=off,enforce=off,-arch-capabilities') + self.set_vm_arg('-cpu', + 'Cascadelake-Server,x-force-features=on,check=off,' + 'enforce=off,-arch-capabilities') self.vm.launch() self.assertFalse(self.get_cpu_prop('arch-capabilities'), 'pc-i440fx-4.1 + Cascadelake-Server,-arch-capabilities should not have arch-capabilities') @@ -294,10 +306,13 @@ class CascadelakeArchCapabilities(avocado_qemu.Test): def test_v1_4_0(self): """ :avocado: tags=machine:pc-i440fx-4.0 + :avocado: tags=cpu:Cascadelake-Server """ # versioned CPU model overrides machine-type: self.vm.add_args('-S') - self.vm.add_args('-cpu', 'Cascadelake-Server-v1,x-force-features=on,check=off,enforce=off') + self.set_vm_arg('-cpu', + 'Cascadelake-Server-v1,x-force-features=on,check=off,' + 'enforce=off') self.vm.launch() self.assertFalse(self.get_cpu_prop('arch-capabilities'), 'pc-i440fx-4.0 + Cascadelake-Server-v1 should not have arch-capabilities') @@ -305,9 +320,12 @@ class CascadelakeArchCapabilities(avocado_qemu.Test): def test_v2_4_0(self): """ :avocado: tags=machine:pc-i440fx-4.0 + :avocado: tags=cpu:Cascadelake-Server """ self.vm.add_args('-S') - self.vm.add_args('-cpu', 'Cascadelake-Server-v2,x-force-features=on,check=off,enforce=off') + self.set_vm_arg('-cpu', + 'Cascadelake-Server-v2,x-force-features=on,check=off,' + 'enforce=off') self.vm.launch() self.assertTrue(self.get_cpu_prop('arch-capabilities'), 'pc-i440fx-4.0 + Cascadelake-Server-v2 should have arch-capabilities') @@ -315,10 +333,13 @@ class CascadelakeArchCapabilities(avocado_qemu.Test): def test_v1_set_4_0(self): """ :avocado: tags=machine:pc-i440fx-4.0 + :avocado: tags=cpu:Cascadelake-Server """ # command line must override machine-type and versioned CPU model: self.vm.add_args('-S') - self.vm.add_args('-cpu', 'Cascadelake-Server-v1,x-force-features=on,check=off,enforce=off,+arch-capabilities') + self.set_vm_arg('-cpu', + 'Cascadelake-Server-v1,x-force-features=on,check=off,' + 'enforce=off,+arch-capabilities') self.vm.launch() self.assertTrue(self.get_cpu_prop('arch-capabilities'), 'pc-i440fx-4.0 + Cascadelake-Server-v1,+arch-capabilities should have arch-capabilities') @@ -326,9 +347,12 @@ class CascadelakeArchCapabilities(avocado_qemu.Test): def test_v2_unset_4_1(self): """ :avocado: tags=machine:pc-i440fx-4.1 + :avocado: tags=cpu:Cascadelake-Server """ self.vm.add_args('-S') - self.vm.add_args('-cpu', 'Cascadelake-Server-v2,x-force-features=on,check=off,enforce=off,-arch-capabilities') + self.set_vm_arg('-cpu', + 'Cascadelake-Server-v2,x-force-features=on,check=off,' + 'enforce=off,-arch-capabilities') self.vm.launch() self.assertFalse(self.get_cpu_prop('arch-capabilities'), 'pc-i440fx-4.1 + Cascadelake-Server-v2,-arch-capabilities should not have arch-capabilities') From 6f651a6d84b64060aa77373a72ba02ff61ad9911 Mon Sep 17 00:00:00 2001 From: Wainer dos Santos Moschetta Date: Wed, 30 Jun 2021 15:45:46 -0300 Subject: [PATCH 20/23] python: Configure tox to skip missing interpreters Currently tox tests against the installed interpreters, however if any supported interpreter is absent then it will return fail. It seems not reasonable to expect developers to have all supported interpreters installed on their systems. Luckily tox can be configured to skip missing interpreters. This changed the tox setup so that missing interpreters are skipped by default. On the CI, however, we still want to enforce it tests against all supported. This way on CI the --skip-missing-interpreters=false option is passed to tox. Signed-off-by: Wainer dos Santos Moschetta Message-Id: <20210630184546.456582-1-wainersm@redhat.com> Reviewed-by: Willian Rampazzo Reviewed-by: John Snow Signed-off-by: Cleber Rosa --- .gitlab-ci.d/static_checks.yml | 1 + python/Makefile | 5 ++++- python/setup.cfg | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.d/static_checks.yml b/.gitlab-ci.d/static_checks.yml index b01f6ec231..96dbd9e310 100644 --- a/.gitlab-ci.d/static_checks.yml +++ b/.gitlab-ci.d/static_checks.yml @@ -43,6 +43,7 @@ check-python-tox: - make -C python check-tox variables: GIT_DEPTH: 1 + QEMU_TOX_EXTRA_ARGS: --skip-missing-interpreters=false needs: job: python-container allow_failure: true diff --git a/python/Makefile b/python/Makefile index ac46ae33e7..fe27a3e12e 100644 --- a/python/Makefile +++ b/python/Makefile @@ -1,4 +1,5 @@ QEMU_VENV_DIR=.dev-venv +QEMU_TOX_EXTRA_ARGS ?= .PHONY: help help: @@ -15,6 +16,8 @@ help: @echo " These tests use the newest dependencies." @echo " Requires: Python 3.6 - 3.10, and tox." @echo " Hint (Fedora): 'sudo dnf install python3-tox python3.10'" + @echo " The variable QEMU_TOX_EXTRA_ARGS can be use to pass extra" + @echo " arguments to tox". @echo "" @echo "make check-dev:" @echo " Run tests in a venv against your default python3 version." @@ -87,7 +90,7 @@ check: .PHONY: check-tox check-tox: - @tox + @tox $(QEMU_TOX_EXTRA_ARGS) .PHONY: clean clean: diff --git a/python/setup.cfg b/python/setup.cfg index 11f71d5312..14bab90288 100644 --- a/python/setup.cfg +++ b/python/setup.cfg @@ -121,6 +121,7 @@ multi_line_output=3 [tox:tox] envlist = py36, py37, py38, py39, py310 +skip_missing_interpreters = true [testenv] allowlist_externals = make From 414e9ae345c5372ece6699342f8afe8d2db107d0 Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Thu, 15 Apr 2021 17:51:35 -0400 Subject: [PATCH 21/23] Acceptance tests: do not try to reuse packages from the system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The premise behind the original behavior is that it would save people from downloading Avocado (and other dependencies) if already installed on the system. To be honest, I think it's extremely rare that the same versions described as dependencies will be available on most systems. But, the biggest motivations here are that: 1) Hacking on QEMU in the same system used to develop Avocado leads to confusion with regards to the exact bits that are being used; 2) Not reusing Python packages from system wide installations gives extra assurance that the same behavior will be seen from tests run on different machines; With regards to downloads, pip already caches the downloaded wheels and tarballs under ~/.cache/pip, so there should not be more than one download even if the venv is destroyed and recreated. Signed-off-by: Cleber Rosa Message-Id: <20210415215141.1865467-3-crosa@redhat.com> Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Willian Rampazzo Reviewed-by: Wainer dos Santos Moschetta Signed-off-by: Cleber Rosa --- tests/Makefile.include | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Makefile.include b/tests/Makefile.include index e4dcb17329..6e16c05f10 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -96,7 +96,7 @@ AVOCADO_TAGS=$(patsubst %-softmmu,-t arch:%, $(filter %-softmmu,$(TARGETS))) $(TESTS_VENV_DIR): $(TESTS_VENV_REQ) $(call quiet-command, \ - $(PYTHON) -m venv --system-site-packages $@, \ + $(PYTHON) -m venv $@, \ VENV, $@) $(call quiet-command, \ $(TESTS_VENV_DIR)/bin/python -m pip -q install -r $(TESTS_VENV_REQ), \ From 9a94d8ae97cd25d71565b99682bb7e49133c1af3 Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Thu, 15 Apr 2021 17:51:36 -0400 Subject: [PATCH 22/23] tests/acceptance/linux_ssh_mips_malta.py: drop identical setUp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These tests' setUp do not do anything beyong what their base class do. And while they do decorate the setUp() we can decorate the classes instead, so no functionality is lost here. This is possible because since Avocado 76.0 we can decorate setUp() directly. Signed-off-by: Cleber Rosa Message-Id: <20210415215141.1865467-4-crosa@redhat.com> Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Willian Rampazzo [PMD: added note to commit message about Avocado feature/version] Signed-off-by: Cleber Rosa --- tests/acceptance/linux_ssh_mips_malta.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/acceptance/linux_ssh_mips_malta.py b/tests/acceptance/linux_ssh_mips_malta.py index 61c9079d04..4de1947418 100644 --- a/tests/acceptance/linux_ssh_mips_malta.py +++ b/tests/acceptance/linux_ssh_mips_malta.py @@ -19,6 +19,8 @@ from avocado.utils import archive from avocado.utils import ssh +@skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout') +@skipUnless(ssh.SSH_CLIENT_BINARY, 'No SSH client available') class LinuxSSH(Test, LinuxSSHMixIn): timeout = 150 # Not for 'configure --enable-debug --enable-debug-tcg' @@ -65,11 +67,6 @@ class LinuxSSH(Test, LinuxSSHMixIn): kernel_hash = self.IMAGE_INFO[endianess]['kernel_hash'][wordsize] return kernel_url, kernel_hash - @skipUnless(ssh.SSH_CLIENT_BINARY, 'No SSH client available') - @skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout') - def setUp(self): - super(LinuxSSH, self).setUp() - def ssh_disconnect_vm(self): self.ssh_session.quit() From c4e2d499c94fb7d6ea43d28e2613559861ef5d79 Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Thu, 15 Apr 2021 17:51:38 -0400 Subject: [PATCH 23/23] tests/acceptance/cpu_queries.py: use the proper logging channels The test contains methods for the proper log of test related information. Let's use that and remove the print and the unused logging import. Reference: https://avocado-framework.readthedocs.io/en/87.0/api/test/avocado.html#avocado.Test.log Signed-off-by: Cleber Rosa Message-Id: <20210415215141.1865467-6-crosa@redhat.com> Reviewed-by: Willian Rampazzo Reviewed-by: Wainer dos Santos Moschetta Signed-off-by: Cleber Rosa --- tests/acceptance/cpu_queries.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/acceptance/cpu_queries.py b/tests/acceptance/cpu_queries.py index 293dccb89a..cc9e380cc7 100644 --- a/tests/acceptance/cpu_queries.py +++ b/tests/acceptance/cpu_queries.py @@ -8,8 +8,6 @@ # This work is licensed under the terms of the GNU GPL, version 2 or # later. See the COPYING file in the top-level directory. -import logging - from avocado_qemu import Test class QueryCPUModelExpansion(Test): @@ -27,7 +25,7 @@ class QueryCPUModelExpansion(Test): cpus = self.vm.command('query-cpu-definitions') for c in cpus: - print(repr(c)) + self.log.info("Checking CPU: %s", c) self.assertNotIn('', c['unavailable-features'], c['name']) for c in cpus: