diff options
Diffstat (limited to 'tests/avocado')
71 files changed, 0 insertions, 13868 deletions
diff --git a/tests/avocado/README.rst b/tests/avocado/README.rst deleted file mode 100644 index 9448837..0000000 --- a/tests/avocado/README.rst +++ /dev/null @@ -1,10 +0,0 @@ -============================================= -Integration tests using the Avocado Framework -============================================= - -This directory contains integration tests. They're usually higher -level, and may interact with external resources and with various -guest operating systems. - -For more information, please refer to ``docs/devel/testing.rst``, -section "Integration tests using the Avocado Framework". diff --git a/tests/avocado/acpi-bits.py b/tests/avocado/acpi-bits.py deleted file mode 100644 index efe4f52..0000000 --- a/tests/avocado/acpi-bits.py +++ /dev/null @@ -1,409 +0,0 @@ -#!/usr/bin/env python3 -# group: rw quick -# Exercise QEMU generated ACPI/SMBIOS tables using biosbits, -# https://biosbits.org/ -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. -# -# -# Author: -# Ani Sinha <anisinha@redhat.com> - -# pylint: disable=invalid-name -# pylint: disable=consider-using-f-string - -""" -This is QEMU ACPI/SMBIOS avocado tests using biosbits. -Biosbits is available originally at https://biosbits.org/. -This test uses a fork of the upstream bits and has numerous fixes -including an upgraded acpica. The fork is located here: -https://gitlab.com/qemu-project/biosbits-bits . -""" - -import logging -import os -import platform -import re -import shutil -import subprocess -import tarfile -import tempfile -import time -import zipfile -from typing import ( - List, - Optional, - Sequence, -) -from qemu.machine import QEMUMachine -from avocado import skipIf -from avocado.utils import datadrainer as drainer -from avocado_qemu import QemuBaseTest - -deps = ["xorriso", "mformat"] # dependent tools needed in the test setup/box. -supported_platforms = ['x86_64'] # supported test platforms. - -# default timeout of 120 secs is sometimes not enough for bits test. -BITS_TIMEOUT = 200 - -def which(tool): - """ looks up the full path for @tool, returns None if not found - or if @tool does not have executable permissions. - """ - paths=os.getenv('PATH') - for p in paths.split(os.path.pathsep): - p = os.path.join(p, tool) - if os.path.exists(p) and os.access(p, os.X_OK): - return p - return None - -def missing_deps(): - """ returns True if any of the test dependent tools are absent. - """ - for dep in deps: - if which(dep) is None: - return True - return False - -def supported_platform(): - """ checks if the test is running on a supported platform. - """ - return platform.machine() in supported_platforms - -class QEMUBitsMachine(QEMUMachine): # pylint: disable=too-few-public-methods - """ - A QEMU VM, with isa-debugcon enabled and bits iso passed - using -cdrom to QEMU commandline. - - """ - def __init__(self, - binary: str, - args: Sequence[str] = (), - wrapper: Sequence[str] = (), - name: Optional[str] = None, - base_temp_dir: str = "/var/tmp", - debugcon_log: str = "debugcon-log.txt", - debugcon_addr: str = "0x403", - qmp_timer: Optional[float] = None): - # pylint: disable=too-many-arguments - - if name is None: - name = "qemu-bits-%d" % os.getpid() - super().__init__(binary, args, wrapper=wrapper, name=name, - base_temp_dir=base_temp_dir, - qmp_timer=qmp_timer) - self.debugcon_log = debugcon_log - self.debugcon_addr = debugcon_addr - self.base_temp_dir = base_temp_dir - - @property - def _base_args(self) -> List[str]: - args = super()._base_args - args.extend([ - '-chardev', - 'file,path=%s,id=debugcon' %os.path.join(self.base_temp_dir, - self.debugcon_log), - '-device', - 'isa-debugcon,iobase=%s,chardev=debugcon' %self.debugcon_addr, - ]) - return args - - def base_args(self): - """return the base argument to QEMU binary""" - return self._base_args - -@skipIf(not supported_platform() or missing_deps(), - 'unsupported platform or dependencies (%s) not installed' \ - % ','.join(deps)) -class AcpiBitsTest(QemuBaseTest): #pylint: disable=too-many-instance-attributes - """ - ACPI and SMBIOS tests using biosbits. - - :avocado: tags=arch:x86_64 - :avocado: tags=acpi - - """ - # in slower systems the test can take as long as 3 minutes to complete. - timeout = BITS_TIMEOUT - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self._vm = None - self._workDir = None - self._baseDir = None - - # following are some standard configuration constants - self._bitsInternalVer = 2020 # gitlab CI does shallow clones of depth 20 - self._bitsCommitHash = 'c7920d2b' # commit hash must match - # the artifact tag below - self._bitsTag = "qemu-bits-10262023" # this is the latest bits - # release as of today. - self._bitsArtSHA1Hash = 'b22cdfcfc7453875297d06d626f5474ee36a343f' - self._bitsArtURL = ("https://gitlab.com/qemu-project/" - "biosbits-bits/-/jobs/artifacts/%s/" - "download?job=qemu-bits-build" %self._bitsTag) - self._debugcon_addr = '0x403' - self._debugcon_log = 'debugcon-log.txt' - logging.basicConfig(level=logging.INFO) - self.logger = logging.getLogger('acpi-bits') - - def _print_log(self, log): - self.logger.info('\nlogs from biosbits follows:') - self.logger.info('==========================================\n') - self.logger.info(log) - self.logger.info('==========================================\n') - - def copy_bits_config(self): - """ copies the bios bits config file into bits. - """ - config_file = 'bits-cfg.txt' - bits_config_dir = os.path.join(self._baseDir, 'acpi-bits', - 'bits-config') - target_config_dir = os.path.join(self._workDir, - 'bits-%d' %self._bitsInternalVer, - 'boot') - self.assertTrue(os.path.exists(bits_config_dir)) - self.assertTrue(os.path.exists(target_config_dir)) - self.assertTrue(os.access(os.path.join(bits_config_dir, - config_file), os.R_OK)) - shutil.copy2(os.path.join(bits_config_dir, config_file), - target_config_dir) - self.logger.info('copied config file %s to %s', - config_file, target_config_dir) - - def copy_test_scripts(self): - """copies the python test scripts into bits. """ - - bits_test_dir = os.path.join(self._baseDir, 'acpi-bits', - 'bits-tests') - target_test_dir = os.path.join(self._workDir, - 'bits-%d' %self._bitsInternalVer, - 'boot', 'python') - - self.assertTrue(os.path.exists(bits_test_dir)) - self.assertTrue(os.path.exists(target_test_dir)) - - for filename in os.listdir(bits_test_dir): - if os.path.isfile(os.path.join(bits_test_dir, filename)) and \ - filename.endswith('.py2'): - # all test scripts are named with extension .py2 so that - # avocado does not try to load them. These scripts are - # written for python 2.7 not python 3 and hence if avocado - # loaded them, it would complain about python 3 specific - # syntaxes. - newfilename = os.path.splitext(filename)[0] + '.py' - shutil.copy2(os.path.join(bits_test_dir, filename), - os.path.join(target_test_dir, newfilename)) - self.logger.info('copied test file %s to %s', - filename, target_test_dir) - - # now remove the pyc test file if it exists, otherwise the - # changes in the python test script won't be executed. - testfile_pyc = os.path.splitext(filename)[0] + '.pyc' - if os.access(os.path.join(target_test_dir, testfile_pyc), - os.F_OK): - os.remove(os.path.join(target_test_dir, testfile_pyc)) - self.logger.info('removed compiled file %s', - os.path.join(target_test_dir, - testfile_pyc)) - - def fix_mkrescue(self, mkrescue): - """ grub-mkrescue is a bash script with two variables, 'prefix' and - 'libdir'. They must be pointed to the right location so that the - iso can be generated appropriately. We point the two variables to - the directory where we have extracted our pre-built bits grub - tarball. - """ - grub_x86_64_mods = os.path.join(self._workDir, 'grub-inst-x86_64-efi') - grub_i386_mods = os.path.join(self._workDir, 'grub-inst') - - self.assertTrue(os.path.exists(grub_x86_64_mods)) - self.assertTrue(os.path.exists(grub_i386_mods)) - - new_script = "" - with open(mkrescue, 'r', encoding='utf-8') as filehandle: - orig_script = filehandle.read() - new_script = re.sub('(^prefix=)(.*)', - r'\1"%s"' %grub_x86_64_mods, - orig_script, flags=re.M) - new_script = re.sub('(^libdir=)(.*)', r'\1"%s/lib"' %grub_i386_mods, - new_script, flags=re.M) - - with open(mkrescue, 'w', encoding='utf-8') as filehandle: - filehandle.write(new_script) - - def generate_bits_iso(self): - """ Uses grub-mkrescue to generate a fresh bits iso with the python - test scripts - """ - bits_dir = os.path.join(self._workDir, - 'bits-%d' %self._bitsInternalVer) - iso_file = os.path.join(self._workDir, - 'bits-%d.iso' %self._bitsInternalVer) - mkrescue_script = os.path.join(self._workDir, - 'grub-inst-x86_64-efi', 'bin', - 'grub-mkrescue') - - self.assertTrue(os.access(mkrescue_script, - os.R_OK | os.W_OK | os.X_OK)) - - self.fix_mkrescue(mkrescue_script) - - self.logger.info('using grub-mkrescue for generating biosbits iso ...') - - try: - if os.getenv('V') or os.getenv('BITS_DEBUG'): - subprocess.check_call([mkrescue_script, '-o', iso_file, - bits_dir], stderr=subprocess.STDOUT) - else: - subprocess.check_call([mkrescue_script, '-o', - iso_file, bits_dir], - stderr=subprocess.DEVNULL, - stdout=subprocess.DEVNULL) - except Exception as e: # pylint: disable=broad-except - self.skipTest("Error while generating the bits iso. " - "Pass V=1 in the environment to get more details. " - + str(e)) - - self.assertTrue(os.access(iso_file, os.R_OK)) - - self.logger.info('iso file %s successfully generated.', iso_file) - - def setUp(self): # pylint: disable=arguments-differ - super().setUp('qemu-system-') - - self._baseDir = os.getenv('AVOCADO_TEST_BASEDIR') - - # workdir could also be avocado's own workdir in self.workdir. - # At present, I prefer to maintain my own temporary working - # directory. It gives us more control over the generated bits - # log files and also for debugging, we may chose not to remove - # this working directory so that the logs and iso can be - # inspected manually and archived if needed. - self._workDir = tempfile.mkdtemp(prefix='acpi-bits-', - suffix='.tmp') - self.logger.info('working dir: %s', self._workDir) - - prebuiltDir = os.path.join(self._workDir, 'prebuilt') - if not os.path.isdir(prebuiltDir): - os.mkdir(prebuiltDir, mode=0o775) - - bits_zip_file = os.path.join(prebuiltDir, 'bits-%d-%s.zip' - %(self._bitsInternalVer, - self._bitsCommitHash)) - grub_tar_file = os.path.join(prebuiltDir, - 'bits-%d-%s-grub.tar.gz' - %(self._bitsInternalVer, - self._bitsCommitHash)) - - bitsLocalArtLoc = self.fetch_asset(self._bitsArtURL, - asset_hash=self._bitsArtSHA1Hash) - self.logger.info("downloaded bits artifacts to %s", bitsLocalArtLoc) - - # extract the bits artifact in the temp working directory - with zipfile.ZipFile(bitsLocalArtLoc, 'r') as zref: - zref.extractall(prebuiltDir) - - # extract the bits software in the temp working directory - with zipfile.ZipFile(bits_zip_file, 'r') as zref: - zref.extractall(self._workDir) - - with tarfile.open(grub_tar_file, 'r', encoding='utf-8') as tarball: - tarball.extractall(self._workDir) - - self.copy_test_scripts() - self.copy_bits_config() - self.generate_bits_iso() - - def parse_log(self): - """parse the log generated by running bits tests and - check for failures. - """ - debugconf = os.path.join(self._workDir, self._debugcon_log) - log = "" - with open(debugconf, 'r', encoding='utf-8') as filehandle: - log = filehandle.read() - - matchiter = re.finditer(r'(.*Summary: )(\d+ passed), (\d+ failed).*', - log) - for match in matchiter: - # verify that no test cases failed. - try: - self.assertEqual(match.group(3).split()[0], '0', - 'Some bits tests seems to have failed. ' \ - 'Please check the test logs for more info.') - except AssertionError as e: - self._print_log(log) - raise e - else: - if os.getenv('V') or os.getenv('BITS_DEBUG'): - self._print_log(log) - - def tearDown(self): - """ - Lets do some cleanups. - """ - if self._vm: - self.assertFalse(not self._vm.is_running) - if not os.getenv('BITS_DEBUG') and self._workDir: - self.logger.info('removing the work directory %s', self._workDir) - shutil.rmtree(self._workDir) - else: - self.logger.info('not removing the work directory %s ' \ - 'as BITS_DEBUG is ' \ - 'passed in the environment', self._workDir) - super().tearDown() - - def test_acpi_smbios_bits(self): - """The main test case implementation.""" - - iso_file = os.path.join(self._workDir, - 'bits-%d.iso' %self._bitsInternalVer) - - self.assertTrue(os.access(iso_file, os.R_OK)) - - self._vm = QEMUBitsMachine(binary=self.qemu_bin, - base_temp_dir=self._workDir, - debugcon_log=self._debugcon_log, - debugcon_addr=self._debugcon_addr) - - self._vm.add_args('-cdrom', '%s' %iso_file) - # the vm needs to be run under icount so that TCG emulation is - # consistent in terms of timing. smilatency tests have consistent - # timing requirements. - self._vm.add_args('-icount', 'auto') - # currently there is no support in bits for recognizing 64-bit SMBIOS - # entry points. QEMU defaults to 64-bit entry points since the - # upstream commit bf376f3020 ("hw/i386/pc: Default to use SMBIOS 3.0 - # for newer machine models"). Therefore, enforce 32-bit entry point. - self._vm.add_args('-machine', 'smbios-entry-point-type=32') - - # enable console logging - self._vm.set_console() - self._vm.launch() - - self.logger.debug("Console output from bits VM follows ...") - c_drainer = drainer.LineLogger(self._vm.console_socket.fileno(), - logger=self.logger.getChild("console"), - stop_check=(lambda : - not self._vm.is_running())) - c_drainer.start() - - # biosbits has been configured to run all the specified test suites - # in batch mode and then automatically initiate a vm shutdown. - # Set timeout to BITS_TIMEOUT for SHUTDOWN event from bits VM at par - # with the avocado test timeout. - self._vm.event_wait('SHUTDOWN', timeout=BITS_TIMEOUT) - self._vm.wait(timeout=None) - self.parse_log() diff --git a/tests/avocado/acpi-bits/bits-config/bits-cfg.txt b/tests/avocado/acpi-bits/bits-config/bits-cfg.txt deleted file mode 100644 index 8010804..0000000 --- a/tests/avocado/acpi-bits/bits-config/bits-cfg.txt +++ /dev/null @@ -1,18 +0,0 @@ -# BITS configuration file -[bits] - -# To run BITS in batch mode, set batch to a list of one or more of the -# following keywords; BITS will then run all of the requested operations, then -# save the log file to disk. -# -# test: Run the full BITS testsuite. -# acpi: Dump all ACPI structures. -# smbios: Dump all SMBIOS structures. -# -# Leave batch set to an empty string to disable batch mode. -# batch = - -# Uncomment the following to run all available batch operations -# please take a look at boot/python/init.py in bits zip file -# to see how these options are parsed and used. -batch = test acpi smbios diff --git a/tests/avocado/acpi-bits/bits-tests/smbios.py2 b/tests/avocado/acpi-bits/bits-tests/smbios.py2 deleted file mode 100644 index 5868a71..0000000 --- a/tests/avocado/acpi-bits/bits-tests/smbios.py2 +++ /dev/null @@ -1,2434 +0,0 @@ -# Copyright (c) 2015, Intel Corporation -# All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# * Neither the name of Intel Corporation nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# This script runs only from the biosbits VM. - -"""SMBIOS/DMI module.""" - -import bits -import bitfields -import ctypes -import redirect -import struct -import uuid -import unpack -import ttypager -import sys - -class SMBIOS(unpack.Struct): - def __new__(cls): - if sys.platform == "BITS-EFI": - import efi - sm_ptr = efi.system_table.ConfigurationTableDict.get(efi.SMBIOS_TABLE_GUID) - else: - address = 0xF0000 - mem = bits.memory(0xF0000, 0x10000) - for offset in range(0, len(mem), 16): - signature = (ctypes.c_char * 4).from_address(address + offset).value - if signature == "_SM_": - entry_point_length = ctypes.c_ubyte.from_address(address + offset + 5).value - csum = sum(map(ord, mem[offset:offset + entry_point_length])) & 0xff - if csum == 0: - sm_ptr = address + offset - break - else: - return None - - if not sm_ptr: - return None - - sm = super(SMBIOS, cls).__new__(cls) - sm._header_memory = bits.memory(sm_ptr, 0x1f) - return sm - - def __init__(self): - super(SMBIOS, self).__init__() - u = unpack.Unpackable(self._header_memory) - self.add_field('header', Header(u)) - self._structure_memory = bits.memory(self.header.structure_table_address, self.header.structure_table_length) - u = unpack.Unpackable(self._structure_memory) - self.add_field('structures', unpack.unpack_all(u, _smbios_structures, self), unpack.format_each("\n\n{!r}")) - - def structure_type(self, num): - '''Dumps structure of given Type if present''' - try: - types_present = [self.structures[x].smbios_structure_type for x in range(len(self.structures))] - matrix = dict() - for index in range(len(types_present)): - if types_present.count(types_present[index]) == 1: - matrix[types_present[index]] = self.structures[index] - else: # if multiple structures of the same type, return a list of structures for the type number - if matrix.has_key(types_present[index]): - matrix[types_present[index]].append(self.structures[index]) - else: - matrix[types_present[index]] = [self.structures[index]] - return matrix[num] - except: - print "Failure: Type {} - not found".format(num) - -class Header(unpack.Struct): - def __new__(cls, u): - return super(Header, cls).__new__(cls) - - def __init__(self, u): - super(Header, self).__init__() - self.raw_data = u.unpack_rest() - u = unpack.Unpackable(self.raw_data) - self.add_field('anchor_string', u.unpack_one("4s")) - self.add_field('checksum', u.unpack_one("B")) - self.add_field('length', u.unpack_one("B")) - self.add_field('major_version', u.unpack_one("B")) - self.add_field('minor_version', u.unpack_one("B")) - self.add_field('max_structure_size', u.unpack_one("<H")) - self.add_field('entry_point_revision', u.unpack_one("B")) - self.add_field('formatted_area', u.unpack_one("5s")) - self.add_field('intermediate_anchor_string', u.unpack_one("5s")) - self.add_field('intermediate_checksum', u.unpack_one("B")) - self.add_field('structure_table_length', u.unpack_one("<H")) - self.add_field('structure_table_address', u.unpack_one("<I")) - self.add_field('number_structures', u.unpack_one("<H")) - self.add_field('bcd_revision', u.unpack_one("B")) - if not u.at_end(): - self.add_field('data', u.unpack_rest()) - -class SmbiosBaseStructure(unpack.Struct): - def __new__(cls, u, sm): - t = u.unpack_peek_one("B") - if cls.smbios_structure_type is not None and t != cls.smbios_structure_type: - return None - return super(SmbiosBaseStructure, cls).__new__(cls) - - def __init__(self, u, sm): - super(SmbiosBaseStructure, self).__init__() - self.start_offset = u.offset - length = u.unpack_peek_one("<xB") - self.raw_data = u.unpack_raw(length) - self.u = unpack.Unpackable(self.raw_data) - - self.strings_offset = u.offset - def unpack_string(): - return "".join(iter(lambda: u.unpack_one("c"), "\x00")) - strings = list(iter(unpack_string, "")) - if not strings: - u.skip(1) - - self.strings_length = u.offset - self.strings_offset - self.raw_strings = str(bits.memory(sm.header.structure_table_address + self.strings_offset, self.strings_length)) - - if len(strings): - self.strings = strings - - self.add_field('type', self.u.unpack_one("B")) - self.add_field('length', self.u.unpack_one("B")) - self.add_field('handle', self.u.unpack_one("<H")) - - def fini(self): - if not self.u.at_end(): - self.add_field('data', self.u.unpack_rest()) - del self.u - - def fmtstr(self, i): - """Format the specified index and the associated string""" - return "{} '{}'".format(i, self.getstr(i)) - - def getstr(self, i): - """Get the string associated with the given index""" - if i == 0: - return "(none)" - if not hasattr(self, "strings"): - return "(error: structure has no strings)" - if i > len(self.strings): - return "(error: string index out of range)" - return self.strings[i - 1] - -class BIOSInformation(SmbiosBaseStructure): - smbios_structure_type = 0 - - def __init__(self, u, sm): - super(BIOSInformation, self).__init__(u, sm) - u = self.u - try: - self.add_field('vendor', u.unpack_one("B"), self.fmtstr) - self.add_field('version', u.unpack_one("B"), self.fmtstr) - self.add_field('starting_address_segment', u.unpack_one("<H")) - self.add_field('release_date', u.unpack_one("B"), self.fmtstr) - self.add_field('rom_size', u.unpack_one("B")) - self.add_field('characteristics', u.unpack_one("<Q")) - minor_version_str = str(sm.header.minor_version) # 34 is .34, 4 is .4, 41 is .41; compare ASCIIbetically to compare initial digits rather than numeric value - if (sm.header.major_version, minor_version_str) >= (2,"4"): - characteristic_bytes = 2 - else: - characteristic_bytes = self.length - 0x12 - self.add_field('characteristics_extensions', [u.unpack_one("B") for b in range(characteristic_bytes)]) - if (sm.header.major_version, minor_version_str) >= (2,"4"): - self.add_field('major_release', u.unpack_one("B")) - self.add_field('minor_release', u.unpack_one("B")) - self.add_field('ec_major_release', u.unpack_one("B")) - self.add_field('ec_minor_release', u.unpack_one("B")) - except: - self.decode_failure = True - print "Error parsing BIOSInformation" - import traceback - traceback.print_exc() - self.fini() - -class SystemInformation(SmbiosBaseStructure): - smbios_structure_type = 1 - - def __init__(self, u, sm): - super(SystemInformation, self).__init__(u, sm) - u = self.u - try: - self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr) - self.add_field('product_name', u.unpack_one("B"), self.fmtstr) - self.add_field('version', u.unpack_one("B"), self.fmtstr) - self.add_field('serial_number', u.unpack_one("B"), self.fmtstr) - if self.length > 0x8: - self.add_field('uuid', uuid.UUID(bytes_le=u.unpack_one("16s"))) - wakeup_types = { - 0: 'Reserved', - 1: 'Other', - 2: 'Unknown', - 3: 'APM Timer', - 4: 'Modem Ring', - 5: 'LAN Remote', - 6: 'Power Switch', - 7: 'PCI PME#', - 8: 'AC Power Restored' - } - self.add_field('wakeup_type', u.unpack_one("B"), unpack.format_table("{}", wakeup_types)) - if self.length > 0x19: - self.add_field('sku_number', u.unpack_one("B"), self.fmtstr) - self.add_field('family', u.unpack_one("B"), self.fmtstr) - except: - self.decode_failure = True - print "Error parsing SystemInformation" - import traceback - traceback.print_exc() - self.fini() - -_board_types = { - 1: 'Unknown', - 2: 'Other', - 3: 'Server Blade', - 4: 'Connectivity Switch', - 5: 'System Management Module', - 6: 'Processor Module', - 7: 'I/O Module', - 8: 'Memory Module', - 9: 'Daughter Board', - 0xA: 'Motherboard', - 0xB: 'Processor/Memory Module', - 0xC: 'Processor/IO Module', - 0xD: 'Interconnect Board' -} - -class BaseboardInformation(SmbiosBaseStructure): - smbios_structure_type = 2 - - def __init__(self, u, sm): - super(BaseboardInformation, self).__init__(u, sm) - u = self.u - try: - self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr) - self.add_field('product', u.unpack_one("B"), self.fmtstr) - self.add_field('version', u.unpack_one("B"), self.fmtstr) - self.add_field('serial_number', u.unpack_one("B"), self.fmtstr) - - if self.length > 0x8: - self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr) - - if self.length > 0x9: - self.add_field('feature_flags', u.unpack_one("B")) - self.add_field('hosting_board', bool(bitfields.getbits(self.feature_flags, 0)), "feature_flags[0]={}") - self.add_field('requires_daughter_card', bool(bitfields.getbits(self.feature_flags, 1)), "feature_flags[1]={}") - self.add_field('removable', bool(bitfields.getbits(self.feature_flags, 2)), "feature_flags[2]={}") - self.add_field('replaceable', bool(bitfields.getbits(self.feature_flags, 3)), "feature_flags[3]={}") - self.add_field('hot_swappable', bool(bitfields.getbits(self.feature_flags, 4)), "feature_flags[4]={}") - - if self.length > 0xA: - self.add_field('location', u.unpack_one("B"), self.fmtstr) - - if self.length > 0xB: - self.add_field('chassis_handle', u.unpack_one("<H")) - - if self.length > 0xD: - self.add_field('board_type', u.unpack_one("B"), unpack.format_table("{}", _board_types)) - - if self.length > 0xE: - self.add_field('handle_count', u.unpack_one("B")) - if self.handle_count > 0: - self.add_field('contained_object_handles', tuple(u.unpack_one("<H") for i in range(self.handle_count))) - except: - self.decode_failure = True - print "Error parsing BaseboardInformation" - import traceback - traceback.print_exc() - self.fini() - -class SystemEnclosure(SmbiosBaseStructure): - smbios_structure_type = 3 - - def __init__(self, u, sm): - super(SystemEnclosure, self).__init__(u, sm) - u = self.u - try: - self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr) - self.add_field('enumerated_type', u.unpack_one("B")) - self.add_field('chassis_lock_present', bool(bitfields.getbits(self.enumerated_type, 7)), "enumerated_type[7]={}") - board_types = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'Desktop', - 0x04: 'Low Profile Desktop', - 0x05: 'Pizza Box', - 0x06: 'Mini Tower', - 0x07: 'Tower', - 0x08: 'Portable', - 0x09: 'Laptop', - 0x0A: 'Notebook', - 0x0B: 'Hand Held', - 0x0C: 'Docking Station', - 0x0D: 'All in One', - 0x0E: 'Sub Notebook', - 0x0F: 'Space-saving', - 0x10: 'Lunch Box', - 0x11: 'Main Server Chassis', - 0x12: 'Expansion Chassis', - 0x13: 'SubChassis', - 0x14: 'Bus Expansion Chassis', - 0x15: 'Peripheral Chassis', - 0x16: 'RAID Chassis', - 0x17: 'Rack Mount Chassis', - 0x18: 'Sealed-case PC', - 0x19: 'Multi-system chassis W', - 0x1A: 'Compact PCI', - 0x1B: 'Advanced TCA', - 0x1C: 'Blade', - 0x1D: 'Blade Enclosure', - } - self.add_field('system_enclosure_type', bitfields.getbits(self.enumerated_type, 6, 0), unpack.format_table("enumerated_type[6:0]={}", board_types)) - self.add_field('version', u.unpack_one("B"), self.fmtstr) - self.add_field('serial_number', u.unpack_one("B"), self.fmtstr) - self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr) - minor_version_str = str(sm.header.minor_version) # 34 is .34, 4 is .4, 41 is .41; compare ASCIIbetically to compare initial digits rather than numeric value - if self.length > 9: - chassis_states = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'Safe', - 0x04: 'Warning', - 0x05: 'Critical', - 0x06: 'Non-recoverable', - } - self.add_field('bootup_state', u.unpack_one("B"), unpack.format_table("{}", chassis_states)) - self.add_field('power_supply_state', u.unpack_one("B"), unpack.format_table("{}", chassis_states)) - self.add_field('thermal_state', u.unpack_one("B"), unpack.format_table("{}", chassis_states)) - security_states = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'None', - 0x04: 'External interface locked out', - 0x05: 'External interface enabled', - } - self.add_field('security_status', u.unpack_one("B"), unpack.format_table("{}", security_states)) - if self.length > 0xd: - self.add_field('oem_defined', u.unpack_one("<I")) - if self.length > 0x11: - self.add_field('height', u.unpack_one("B")) - self.add_field('num_power_cords', u.unpack_one("B")) - self.add_field('contained_element_count', u.unpack_one("B")) - self.add_field('contained_element_length', u.unpack_one("B")) - if getattr(self, 'contained_element_count', 0): - self.add_field('contained_elements', tuple(SystemEnclosureContainedElement(u, self.contained_element_length) for i in range(self.contained_element_count))) - if self.length > (0x15 + (getattr(self, 'contained_element_count', 0) * getattr(self, 'contained_element_length', 0))): - self.add_field('sku_number', u.unpack_one("B"), self.fmtstr) - except: - self.decode_failure = True - print "Error parsing SystemEnclosure" - import traceback - traceback.print_exc() - self.fini() - -class SystemEnclosureContainedElement(unpack.Struct): - def __init__(self, u, length): - super(SystemEnclosureContainedElement, self).__init__() - self.start_offset = u.offset - self.raw_data = u.unpack_raw(length) - self.u = unpack.Unpackable(self.raw_data) - u = self.u - self.add_field('contained_element_type', u.unpack_one("B")) - type_selections = { - 0: 'SMBIOS baseboard type enumeration', - 1: 'SMBIOS structure type enumeration', - } - self.add_field('type_select', bitfields.getbits(self.contained_element_type, 7), unpack.format_table("contained_element_type[7]={}", type_selections)) - self.add_field('type', bitfields.getbits(self.contained_element_type, 6, 0)) - if self.type_select == 0: - self.add_field('smbios_board_type', self.type, unpack.format_table("{}", _board_types)) - else: - self.add_field('smbios_structure_type', self.type) - self.add_field('minimum', u.unpack_one("B")) - self.add_field('maximum', u.unpack_one("B")) - if not u.at_end(): - self.add_field('data', u.unpack_rest()) - del self.u - -class ProcessorInformation(SmbiosBaseStructure): - smbios_structure_type = 4 - - def __init__(self, u, sm): - super(ProcessorInformation, self).__init__(u, sm) - u = self.u - try: - self.add_field('socket_designation', u.unpack_one("B"), self.fmtstr) - processor_types = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'Central Processor', - 0x04: 'Math Processor', - 0x05: 'DSP Processor', - 0x06: 'Video Processor', - } - self.add_field('processor_type', u.unpack_one("B"), unpack.format_table("{}", processor_types)) - self.add_field('processor_family', u.unpack_one("B")) - self.add_field('processor_manufacturer', u.unpack_one("B"), self.fmtstr) - self.add_field('processor_id', u.unpack_one("<Q")) - self.add_field('processor_version', u.unpack_one("B"), self.fmtstr) - self.add_field('voltage', u.unpack_one("B")) - self.add_field('external_clock', u.unpack_one("<H")) - self.add_field('max_speed', u.unpack_one("<H")) - self.add_field('current_speed', u.unpack_one("<H")) - self.add_field('status', u.unpack_one("B")) - processor_upgrades = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'Daughter Board', - 0x04: 'ZIF Socket', - 0x05: 'Replaceable Piggy Back', - 0x06: 'None', - 0x07: 'LIF Socket', - 0x08: 'Slot 1', - 0x09: 'Slot 2', - 0x0A: '370-pin socket', - 0x0B: 'Slot A', - 0x0C: 'Slot M', - 0x0D: 'Socket 423', - 0x0E: 'Socket A (Socket 462)', - 0x0F: 'Socket 478', - 0x10: 'Socket 754', - 0x11: 'Socket 940', - 0x12: 'Socket 939', - 0x13: 'Socket mPGA604', - 0x14: 'Socket LGA771', - 0x15: 'Socket LGA775', - 0x16: 'Socket S1', - 0x17: 'Socket AM2', - 0x18: 'Socket F (1207)', - 0x19: 'Socket LGA1366', - 0x1A: 'Socket G34', - 0x1B: 'Socket AM3', - 0x1C: 'Socket C32', - 0x1D: 'Socket LGA1156', - 0x1E: 'Socket LGA1567', - 0x1F: 'Socket PGA988A', - 0x20: 'Socket BGA1288', - 0x21: 'Socket rPGA988B', - 0x22: 'Socket BGA1023', - 0x23: 'Socket BGA1224', - 0x24: 'Socket BGA1155', - 0x25: 'Socket LGA1356', - 0x26: 'Socket LGA2011', - 0x27: 'Socket FS1', - 0x28: 'Socket FS2', - 0x29: 'Socket FM1', - 0x2A: 'Socket FM2', - } - self.add_field('processor_upgrade', u.unpack_one("B"), unpack.format_table("{}", processor_upgrades)) - if self.length > 0x1A: - self.add_field('l1_cache_handle', u.unpack_one("<H")) - self.add_field('l2_cache_handle', u.unpack_one("<H")) - self.add_field('l3_cache_handle', u.unpack_one("<H")) - if self.length > 0x20: - self.add_field('serial_number', u.unpack_one("B"), self.fmtstr) - self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr) - self.add_field('part_number', u.unpack_one("B"), self.fmtstr) - if self.length > 0x24: - self.add_field('core_count', u.unpack_one("B")) - self.add_field('core_enabled', u.unpack_one("B")) - self.add_field('thread_count', u.unpack_one("B")) - self.add_field('processor_characteristics', u.unpack_one("<H")) - if self.length > 0x28: - self.add_field('processor_family_2', u.unpack_one("<H")) - if self.length > 0x2A: - self.add_field('core_count2', u.unpack_one("<H")) - self.add_field('core_enabled2', u.unpack_one("<H")) - self.add_field('thread_count2', u.unpack_one("<H")) - except: - self.decode_failure = True - print "Error parsing Processor Information" - import traceback - traceback.print_exc() - self.fini() - -class MemoryControllerInformation(SmbiosBaseStructure): #obsolete starting with v2.1 - smbios_structure_type = 5 - - def __init__(self, u, sm): - super(MemoryControllerInformation, self).__init__(u, sm) - u = self.u - try: - _error_detecting_method = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'None', - 0x04: '8-bit Parity', - 0x05: '32-bit ECC', - 0x06: '64-bit ECC', - 0x07: '128-bit ECC', - 0x08: 'CRC' - } - self.add_field('error_detecting_method', u.unpack_one("B"), unpack.format_table("{}", _error_detecting_method)) - self.add_field('error_correcting_capability', u.unpack_one("B")) - _interleaves = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'One-Way Interleave', - 0x04: 'Two-Way Interleave', - 0x05: 'Four-Way Interleave', - 0x06: 'Eight-Way Interleave', - 0x07: 'Sixteen-Way Interleave' - } - self.add_field('supported_interleave', u.unpack_one("B"), unpack.format_table("{}", _interleaves)) - self.add_field('current_interleave', u.unpack_one("B"), unpack.format_table("{}", _interleaves)) - self.add_field('max_memory_module_size', u.unpack_one("B"), self.fmtstr) - self.add_field('supported_speeds', u.unpack_one("<H")) - self.add_field('supported_memory_types', u.unpack_one("<H")) - self.add_field('memory_module_voltage', u.unpack_one("B")) - self.add_field('req_voltage_b2', bitfields.getbits(self.memory_module_voltage, 2), "memory_module_voltage[2]={}") - self.add_field('req_voltage_b1', bitfields.getbits(self.memory_module_voltage, 1), "memory_module_voltage[1]={}") - self.add_field('req_voltage_b0', bitfields.getbits(self.memory_module_voltage, 0), "memory_module_voltage[0]={}") - self.add_field('num_associated_memory_slots', u.unpack_one("B")) - self.add_field('memory_module_configuration_handles', u.unpack_one("<(self.num_associated_memory_slots)H")) - self.add_field('enabled_error_correcting_capabilities', u.unpack_one("B")) - except: - self.decode_failure = True - print "Error parsing MemoryControllerInformation" - import traceback - traceback.print_exc() - self.fini() - -class MemoryModuleInformation(SmbiosBaseStructure): #obsolete starting with v2.1 - smbios_structure_type = 6 - - def __init__(self, u, sm): - super(MemoryModuleInformation, self).__init__(u, sm) - u = self.u - try: - self.add_field('socket_designation', u.unpack_one("B"), self.fmtstr) - self.add_field('bank_connections', u.unpack_one("B")) - self.add_field('current_speed', u.unpack_one("B")) - self.add_field('current_memory_type', u.unpack_one("<H")) - _mem_connection = { - 0: 'single', - 1: 'double-bank' - } - self.add_field('installed_mem', u.unpack_one("B")) - self.add_field('installed_size', bitfields.getbits(self.installed_mem, 6, 0), "installed_mem[6:0]={}") - self.add_field('installed_memory_module_connection', bitfields.getbits(self.installed_mem, 7), unpack.format_table("installed_mem[7]={}", _mem_connection)) - self.add_field('enabled_mem', u.unpack_one("B")) - self.add_field('enabled_size', bitfields.getbits(self.installed_mem, 6, 0), "enabled_mem[6:0]={}") - self.add_field('enabled_memory_module_connection', bitfields.getbits(self.installed_mem, 7), unpack.format_table("enabled_mem[7]={}", _mem_connection)) - self.add_field('error_status', u.unpack_one("B")) - self.add_field('error_status_info_obstained_from_event_log', bool(bitfields.getbits(self.error_status, 2)), unpack.format_table("error_status[2]={}", _mem_connection)) - self.add_field('correctable_errors_received', bool(bitfields.getbits(self.error_status, 1)), unpack.format_table("error_status[1]={}", _mem_connection)) - self.add_field('uncorrectable_errors_received', bool(bitfields.getbits(self.error_status, 0)), unpack.format_table("error_status[0]={}", _mem_connection)) - except: - self.decode_failure = True - print "Error parsing MemoryModuleInformation" - import traceback - traceback.print_exc() - self.fini() - -class CacheInformation(SmbiosBaseStructure): - smbios_structure_type = 7 - - def __init__(self, u, sm): - super(CacheInformation, self).__init__(u, sm) - u = self.u - try: - self.add_field('socket_designation', u.unpack_one("B"), self.fmtstr) - processor_types = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'Central Processor', - 0x04: 'Math Processor', - 0x05: 'DSP Processor', - 0x06: 'Video Processor', - } - self.add_field('cache_configuration', u.unpack_one("<H")) - _operational_mode = { - 0b00: 'Write Through', - 0b01: 'Write Back', - 0b10: 'Varies with Memory Address', - 0b11: 'Unknown' - } - self.add_field('operational_mode', bitfields.getbits(self.cache_configuration, 9, 8), unpack.format_table("cache_configuration[9:8]={}", _operational_mode)) - self.add_field('enabled_at_boot_time', bool(bitfields.getbits(self.cache_configuration, 7)), "cache_configuration[7]={}") - _location = { - 0b00: 'Internal', - 0b01: 'External', - 0b10: 'Reserved', - 0b11: 'Unknown' - } - self.add_field('location_relative_to_cpu_module', bitfields.getbits(self.cache_configuration, 6, 5), unpack.format_table("cache_configuration[6:5]={}", _location)) - self.add_field('cache_socketed', bool(bitfields.getbits(self.cache_configuration, 3)), "cache_configuration[3]={}") - self.add_field('cache_level', bitfields.getbits(self.cache_configuration, 2, 0), "cache_configuration[2:0]={}") - self.add_field('max_cache_size', u.unpack_one("<H")) - _granularity = { - 0: '1K granularity', - 1: '64K granularity' - } - self.add_field('max_granularity', bitfields.getbits(self.cache_configuration, 15), unpack.format_table("max_cache_size[15]={}", _granularity)) - self.add_field('max_size_in_granularity', bitfields.getbits(self.cache_configuration, 14, 0), "max_cache_size[14, 0]={}") - self.add_field('installed_size', u.unpack_one("<H")) - if self.installed_size != 0: - self.add_field('installed_granularity', bitfields.getbits(self.cache_configuration, 15), unpack.format_table("installed_size[15]={}", _granularity)) - self.add_field('installed_size_in_granularity', bitfields.getbits(self.cache_configuration, 14, 0), "installed_size[14, 0]={}") - self.add_field('supported_sram_type', u.unpack_one("<H")) - self.add_field('current_sram_type', u.unpack_one("<H")) - if self.length > 0x0F: - self.add_field('cache_speed', u.unpack_one("B")) - if self.length > 0x10: - _error_correction = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'None', - 0x04: 'Parity', - 0x05: 'Single-bit ECC', - 0x06: 'Multi-bit ECC' - } - self.add_field('error_correction', u.unpack_one("B"), unpack.format_table("{}", _error_correction)) - if self.length > 0x10: - _system_cache_type = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'Instruction', - 0x04: 'Data', - 0x05: 'Unified' - } - self.add_field('system_cache_type', u.unpack_one("B"), unpack.format_table("{}", _system_cache_type)) - if self.length > 0x12: - _associativity = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'Direct Mapped', - 0x04: '2-way Set-Associative', - 0x05: '4-way Set-Associative', - 0x06: 'Fully Associative', - 0x07: '8-way Set-Associative', - 0x08: '16-way Set-Associative', - 0x09: '12-way Set-Associative', - 0x0A: '24-way Set-Associative', - 0x0B: '32-way Set-Associative', - 0x0C: '48-way Set-Associative', - 0x0D: '64-way Set-Associative', - 0x0E: '20-way Set-Associative' - } - self.add_field('associativity', u.unpack_one("B"), unpack.format_table("{}", _associativity)) - - except: - self.decode_failure = True - print "Error parsing CacheInformation" - import traceback - traceback.print_exc() - self.fini() - -class PortConnectorInfo(SmbiosBaseStructure): - smbios_structure_type = 8 - - def __init__(self, u, sm): - super(PortConnectorInfo, self).__init__(u, sm) - u = self.u - try: - self.add_field('internal_reference_designator', u.unpack_one("B"), self.fmtstr) - connector_types = { - 0x00: 'None', - 0x01: 'Centronics', - 0x02: 'Mini Centronics', - 0x03: 'Proprietary', - 0x04: 'DB-25 pin male', - 0x05: 'DB-25 pin female', - 0x06: 'DB-15 pin male', - 0x07: 'DB-15 pin female', - 0x08: 'DB-9 pin male', - 0x09: 'DB-9 pin female', - 0x0A: 'RJ-11', - 0x0B: 'RJ-45', - 0x0C: '50-pin MiniSCSI', - 0x0D: 'Mini-DIN', - 0x0E: 'Micro-DIN', - 0x0F: 'PS/2', - 0x10: 'Infrared', - 0x11: 'HP-HIL', - 0x12: 'Access Bus (USB)', - 0x13: 'SSA SCSI', - 0x14: 'Circular DIN-8 male', - 0x15: 'Circular DIN-8 female', - 0x16: 'On Board IDE', - 0x17: 'On Board Floppy', - 0x18: '9-pin Dual Inline (pin 10 cut)', - 0x19: '25-pin Dual Inline (pin 26 cut)', - 0x1A: '50-pin Dual Inline', - 0x1B: '68-pin Dual Inline', - 0x1C: 'On Board Sound Input from CD-ROM', - 0x1D: 'Mini-Centronics Type-14', - 0x1E: 'Mini-Centronics Type-26', - 0x1F: 'Mini-jack (headphones)', - 0x20: 'BNC', - 0x21: '1394', - 0x22: 'SAS/SATA Plug Receptacle', - 0xA0: 'PC-98', - 0xA1: 'PC-98Hireso', - 0xA2: 'PC-H98', - 0xA3: 'PC-98Note', - 0xA4: 'PC-98Full', - 0xFF: 'Other', - } - self.add_field('internal_connector_type', u.unpack_one("B"), unpack.format_table("{}", connector_types)) - self.add_field('external_reference_designator', u.unpack_one("B"), self.fmtstr) - self.add_field('external_connector_type', u.unpack_one("B"), unpack.format_table("{}", connector_types)) - port_types = { - 0x00: 'None', - 0x01: 'Parallel Port XT/AT Compatible', - 0x02: 'Parallel Port PS/2', - 0x03: 'Parallel Port ECP', - 0x04: 'Parallel Port EPP', - 0x05: 'Parallel Port ECP/EPP', - 0x06: 'Serial Port XT/AT Compatible', - 0x07: 'Serial Port 16450 Compatible', - 0x08: 'Serial Port 16550 Compatible', - 0x09: 'Serial Port 16550A Compatible', - 0x0A: 'SCSI Port', - 0x0B: 'MIDI Port', - 0x0C: 'Joy Stick Port', - 0x0D: 'Keyboard Port', - 0x0E: 'Mouse Port', - 0x0F: 'SSA SCSI', - 0x10: 'USB', - 0x11: 'FireWire (IEEE P1394)', - 0x12: 'PCMCIA Type I2', - 0x13: 'PCMCIA Type II', - 0x14: 'PCMCIA Type III', - 0x15: 'Cardbus', - 0x16: 'Access Bus Port', - 0x17: 'SCSI II', - 0x18: 'SCSI Wide', - 0x19: 'PC-98', - 0x1A: 'PC-98-Hireso', - 0x1B: 'PC-H98', - 0x1C: 'Video Port', - 0x1D: 'Audio Port', - 0x1E: 'Modem Port', - 0x1F: 'Network Port', - 0x20: 'SATA', - 0x21: 'SAS', - 0xA0: '8251 Compatible', - 0xA1: '8251 FIFO Compatible', - 0xFF: 'Other', - } - self.add_field('port_type', u.unpack_one("B"), unpack.format_table("{}", port_types)) - except: - self.decodeFailure = True - print "Error parsing PortConnectorInfo" - import traceback - traceback.print_exc() - self.fini() - -class SystemSlots(SmbiosBaseStructure): - smbios_structure_type = 9 - - def __init__(self, u, sm): - super(SystemSlots, self).__init__(u, sm) - u = self.u - try: - self.add_field('designation', u.unpack_one("B"), self.fmtstr) - _slot_types = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'ISA', - 0x04: 'MCA', - 0x05: 'EISA', - 0x06: 'PCI', - 0x07: 'PC Card (PCMCIA)', - 0x08: 'VL-VESA', - 0x09: 'Proprietary', - 0x0A: 'Processor Card Slot', - 0x0B: 'Proprietary Memory Card Slot', - 0x0C: 'I/O Riser Card Slot', - 0x0D: 'NuBus', - 0x0E: 'PCI 66MHz Capable', - 0x0F: 'AGP', - 0x10: 'AGP 2X', - 0x11: 'AGP 4X', - 0x12: 'PCI-X', - 0x13: 'AGP 8X', - 0xA0: 'PC-98/C20', - 0xA1: 'PC-98/C24', - 0xA2: 'PC-98/E', - 0xA3: 'PC-98/Local Bus', - 0xA4: 'PC-98/Card', - 0xA5: 'PCI Express', - 0xA6: 'PCI Express x1', - 0xA7: 'PCI Express x2', - 0xA8: 'PCI Express x4', - 0xA9: 'PCI Express x8', - 0xAA: 'PCI Express x16', - 0xAB: 'PCI Express Gen 2', - 0xAC: 'PCI Express Gen 2 x1', - 0xAD: 'PCI Express Gen 2 x2', - 0xAE: 'PCI Express Gen 2 x4', - 0xAF: 'PCI Express Gen 2 x8', - 0xB0: 'PCI Express Gen 2 x16', - 0xB1: 'PCI Express Gen 3', - 0xB2: 'PCI Express Gen 3 x1', - 0xB3: 'PCI Express Gen 3 x2', - 0xB4: 'PCI Express Gen 3 x4', - 0xB5: 'PCI Express Gen 3 x8', - 0xB6: 'PCI Express Gen 3 x16', - } - self.add_field('slot_type', u.unpack_one("B"), unpack.format_table("{}", _slot_types)) - _slot_data_bus_widths = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: '8 bit', - 0x04: '16 bit', - 0x05: '32 bit', - 0x06: '64 bit', - 0x07: '128 bit', - 0x08: '1x or x1', - 0x09: '2x or x2', - 0x0A: '4x or x4', - 0x0B: '8x or x8', - 0x0C: '12x or x12', - 0x0D: '16x or x16', - 0x0E: '32x or x32', - } - self.add_field('slot_data_bus_width', u.unpack_one('B'), unpack.format_table("{}", _slot_data_bus_widths)) - _current_usages = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'Available', - 0x04: 'In use', - } - self.add_field('current_usage', u.unpack_one('B'), unpack.format_table("{}", _current_usages)) - _slot_lengths = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'Short Length', - 0x04: 'Long Length', - } - self.add_field('slot_length', u.unpack_one('B'), unpack.format_table("{}", _slot_lengths)) - self.add_field('slot_id', u.unpack_one('<H')) - self.add_field('characteristics1', u.unpack_one('B')) - self.add_field('characteristics_unknown', bool(bitfields.getbits(self.characteristics1, 0)), "characteristics1[0]={}") - self.add_field('provides_5_0_volts', bool(bitfields.getbits(self.characteristics1, 1)), "characteristics1[1]={}") - self.add_field('provides_3_3_volts', bool(bitfields.getbits(self.characteristics1, 2)), "characteristics1[2]={}") - self.add_field('shared_slot', bool(bitfields.getbits(self.characteristics1, 3)), "characteristics1[3]={}") - self.add_field('supports_pc_card_16', bool(bitfields.getbits(self.characteristics1, 4)), "characteristics1[4]={}") - self.add_field('supports_cardbus', bool(bitfields.getbits(self.characteristics1, 5)), "characteristics1[5]={}") - self.add_field('supports_zoom_video', bool(bitfields.getbits(self.characteristics1, 6)), "characteristics1[6]={}") - self.add_field('supports_modem_ring_resume', bool(bitfields.getbits(self.characteristics1, 7)), "characteristics1[7]={}") - if self.length > 0x0C: - self.add_field('characteristics2', u.unpack_one('B')) - self.add_field('supports_PME', bool(bitfields.getbits(self.characteristics2, 0)), "characteristics2[0]={}") - self.add_field('supports_hot_plug', bool(bitfields.getbits(self.characteristics2, 1)), "characteristics2[1]={}") - self.add_field('supports_smbus', bool(bitfields.getbits(self.characteristics2, 2)), "characteristics2[2]={}") - if self.length > 0x0D: - self.add_field('segment_group_number', u.unpack_one('<H')) - self.add_field('bus_number', u.unpack_one('B')) - self.add_field('device_function_number', u.unpack_one('B')) - self.add_field('device_number', bitfields.getbits(self.device_function_number, 7, 3), "device_function_number[7:3]={}") - self.add_field('function_number', bitfields.getbits(self.device_function_number, 2, 0), "device_function_number[2:0]={}") - except: - self.decodeFailure = True - print "Error parsing SystemSlots" - import traceback - traceback.print_exc() - self.fini() - -class OnBoardDevicesInformation(SmbiosBaseStructure): - smbios_structure_type = 10 - - def __init__(self, u, sm): - super(OnBoardDevicesInformation, self).__init__(u, sm) - u = self.u - try: - self.add_field('device_type', u.unpack_one("B")) - self.add_field('device_enabled', bool(bitfields.getbits(self.device_type, 7)), "device_type[7]={}") - _device_types = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'Video', - 0x04: 'SCSI Controller', - 0x05: 'Ethernet', - 0x06: 'Token Ring', - 0x07: 'Sound', - 0x08: 'PATA Controller', - 0x09: 'SATA Controller', - 0x0A: 'SAS Controller' - } - self.add_field('type_of_device', bitfields.getbits(self.device_type, 6, 0), unpack.format_table("device_type[6:0]={}", _device_types)) - self.add_field('description_string', u.unpack_one("B"), self.fmtstr) - except: - self.decodeFailure = True - print "Error parsing OnBoardDevicesInformation" - import traceback - traceback.print_exc() - self.fini() - -class OEMStrings(SmbiosBaseStructure): - smbios_structure_type = 11 - - def __init__(self, u, sm): - super(OEMStrings, self).__init__(u, sm) - u = self.u - try: - self.add_field('count', u.unpack_one("B")) - except: - self.decodeFailure = True - print "Error parsing OEMStrings" - import traceback - traceback.print_exc() - self.fini() - -class SystemConfigOptions(SmbiosBaseStructure): - smbios_structure_type = 12 - - def __init__(self, u, sm): - super(SystemConfigOptions, self).__init__(u, sm) - u = self.u - try: - self.add_field('count', u.unpack_one("B")) - except: - self.decodeFailure = True - print "Error parsing SystemConfigOptions" - import traceback - traceback.print_exc() - self.fini() - -class BIOSLanguageInformation(SmbiosBaseStructure): - smbios_structure_type = 13 - - def __init__(self, u, sm): - super(BIOSLanguageInformation, self).__init__(u, sm) - u = self.u - try: - self.add_field('installable_languages', u.unpack_one("B")) - if self.length > 0x05: - self.add_field('flags', u.unpack_one('B')) - self.add_field('abbreviated_format', bool(bitfields.getbits(self.flags, 0)), "flags[0]={}") - if self.length > 0x6: - u.skip(15) - self.add_field('current_language', u.unpack_one('B'), self.fmtstr) - except: - self.decodeFailure = True - print "Error parsing BIOSLanguageInformation" - import traceback - traceback.print_exc() - self.fini() - -class GroupAssociations(SmbiosBaseStructure): - smbios_structure_type = 14 - - def __init__(self, u, sm): - super(GroupAssociations, self).__init__(u, sm) - u = self.u - try: - self.add_field('group_name', u.unpack_one("B"), self.fmtstr) - self.add_field('item_type', u.unpack_one('B')) - self.add_field('item_handle', u.unpack_one('<H')) - except: - self.decodeFailure = True - print "Error parsing GroupAssociations" - import traceback - traceback.print_exc() - self.fini() - -class SystemEventLog(SmbiosBaseStructure): - smbios_structure_type = 15 - - def __init__(self, u, sm): - super(SystemEventLog, self).__init__(u, sm) - u = self.u - try: - self.add_field('log_area_length', u.unpack_one("<H")) - self.add_field('log_header_start_offset', u.unpack_one('<H')) - self.add_field('log_data_start_offset', u.unpack_one('<H')) - _access_method = { - 0x00: 'Indexed I/O: 1 8-bit index port, 1 8-bit data port', - 0x01: 'Indexed I/O: 2 8-bit index ports, 1 8-bit data port', - 0x02: 'Indexed I/O: 1 16-bit index port, 1 8-bit data port', - 0x03: 'Memory-mapped physical 32-bit address', - 0x04: 'Available through General-Purpose NonVolatile Data functions', - xrange(0x05, 0x07F): 'Available for future assignment', - xrange(0x80, 0xFF): 'BIOS Vendor/OEM-specific' - } - self.add_field('access_method', u.unpack_one('B'), unpack.format_table("{}", _access_method)) - self.add_field('log_status', u.unpack_one('B')) - self.add_field('log_area_full', bool(bitfields.getbits(self.log_status, 1)), "log_status[1]={}") - self.add_field('log_area_valid', bool(bitfields.getbits(self.log_status, 0)), "log_status[0]={}") - self.add_field('log_change_token', u.unpack_one('<I')) - self.add_field('access_method_address', u.unpack_one('<I')) - if self.length > 0x14: - _log_header_formats = { - 0: 'No header', - 1: 'Type 1 log header', - xrange(2, 0x7f): 'Available for future assignment', - xrange(0x80, 0xff): 'BIOS vendor or OEM-specific format' - } - self.add_field('log_header_format', u.unpack_one("B"), unpack.format_table("{}", _log_header_formats)) - if self.length > 0x15: - self.add_field('num_supported_log_type_descriptors', u.unpack_one('B')) - if self.length > 0x16: - self.add_field('length_log_type_descriptor', u.unpack_one('B')) - if self.length != (0x17 + (self.num_supported_log_type_descriptors * self.length_log_type_descriptor)): - print "Error: structure length ({}) != 0x17 + (num_supported_log_type_descriptors ({}) * length_log_type_descriptor({}))".format(self.length, self.num_supported_log_type_descriptors, self.length_log_type_descriptor) - print "structure length = {}".format(self.length) - print "num_supported_log_type_descriptors = {}".format(self.num_supported_log_type_descriptors) - print "length_log_type_descriptor = {}".format(self.length_log_type_descriptor) - self.decodeFailure = True - self.add_field('descriptors', tuple(EventLogDescriptor.unpack(u) for i in range(self.num_supported_log_type_descriptors)), unpack.format_each("\n{!r}")) - except: - self.decodeFailure = True - print "Error parsing SystemEventLog" - import traceback - traceback.print_exc() - self.fini() - -class EventLogDescriptor(unpack.Struct): - @staticmethod - def _unpack(u): - _event_log_type_descriptors = { - 0x00: 'Reserved', - 0x01: 'Single-bit ECC memory error', - 0x02: 'Multi-bit ECC memory error', - 0x03: 'Parity memory error', - 0x04: 'Bus time-out', - 0x05: 'I/O Channel Check', - 0x06: 'Software NMI', - 0x07: 'POST Memory Resize', - 0x08: 'POST Error', - 0x09: 'PCI Parity Error', - 0x0A: 'PCI System Error', - 0x0B: 'CPU Failure', - 0x0C: 'EISA FailSafe Timer time-out', - 0x0D: 'Correctable memory log disabled', - 0x0E: 'Logging disabled for a specific Event Type - too many errors of the same type received in a short amount of time', - 0x0F: 'Reserved', - 0x10: 'System Limit Exceeded', - 0x11: 'Asynchronous hardware timer expired and issued a system reset', - 0x12: 'System configuration information', - 0x13: 'Hard-disk information', - 0x14: 'System reconfigured', - 0x15: 'Uncorrectable CPU-complex error', - 0x16: 'Log Area Reset/Cleared', - 0x17: 'System boot', - xrange(0x18, 0x7F): 'Unused, available for assignment', - xrange(0x80, 0xFE): 'Available for system- and OEM-specific assignments', - 0xFF: 'End of log' - } - yield 'log_type', u.unpack_one('B'), unpack.format_table("{}", _event_log_type_descriptors) - _event_log_format = { - 0x00: 'None', - 0x01: 'Handle', - 0x02: 'Multiple-Event', - 0x03: 'Multiple-Event Handle', - 0x04: 'POST Results Bitmap', - 0x05: 'System Management Type', - 0x06: 'Multiple-Event System Management Type', - xrange(0x80, 0xFF): 'OEM assigned' - } - yield 'variable_data_format_type', u.unpack_one('B'), unpack.format_table("{}", _event_log_format) - -class PhysicalMemoryArray(SmbiosBaseStructure): - smbios_structure_type = 16 - - def __init__(self, u, sm): - super(PhysicalMemoryArray, self).__init__(u, sm) - u = self.u - try: - if self.length > 0x4: - _location_field = { - 0x01: "Other", - 0x02: "Unknown", - 0x03: "System board or motherboard", - 0x04: "ISA add-on card", - 0x05: "EISA add-on card", - 0x06: "PCI add-on card", - 0x07: "MCA add-on card", - 0x08: "PCMCIA add-on card", - 0x09: "Proprietary add-on card", - 0x0A: "NuBus", - 0xA0: "PC-98/C20 add-on card", - 0xA1: "PC-98/C24 add-on card", - 0xA2: "PC-98/E add-on card", - 0xA3: "PC-98/Local bus add-on card" - } - self.add_field('location', u.unpack_one("B"), unpack.format_table("{}", _location_field)) - if self.length > 0x05: - _use = { - 0x01: "Other", - 0x02: "Unknown", - 0x03: "System memory", - 0x04: "Video memory", - 0x05: "Flash memory", - 0x06: "Non-volatile RAM", - 0x07: "Cache memory" - } - self.add_field('use', u.unpack_one('B'), unpack.format_table("{}", _use)) - if self.length > 0x06: - _error_correction = { - 0x01: "Other", - 0x02: "Unknown", - 0x03: "None", - 0x04: "Parity", - 0x05: "Single-bit ECC", - 0x06: "Multi-bit ECC", - 0x07: "CRC" - } - self.add_field('memory_error_correction', u.unpack_one('B'), unpack.format_table("{}", _error_correction)) - if self.length > 0x07: - self.add_field('maximum_capacity', u.unpack_one('<I')) - if self.length > 0x0B: - self.add_field('memory_error_information_handle', u.unpack_one('<H')) - if self.length > 0x0D: - self.add_field('num_memory_devices', u.unpack_one('<H')) - if self.length > 0x0F: - self.add_field('extended_maximum_capacity', u.unpack_one('<Q')) - except: - self.decodeFailure = True - print "Error parsing PhysicalMemoryArray" - import traceback - traceback.print_exc() - self.fini() - -class MemoryDevice(SmbiosBaseStructure): - smbios_structure_type = 17 - - def __init__(self, u, sm): - super(MemoryDevice, self).__init__(u, sm) - u = self.u - try: - if self.length > 0x4: - self.add_field('physical_memory_array_handle', u.unpack_one("<H")) - if self.length > 0x6: - self.add_field('memory_error_information_handle', u.unpack_one("<H")) - if self.length > 0x8: - self.add_field('total_width', u.unpack_one("<H")) - if self.length > 0xA: - self.add_field('data_width', u.unpack_one("<H")) - if self.length > 0xC: - self.add_field('size', u.unpack_one("<H")) - if self.length > 0xE: - _form_factors = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'SIMM', - 0x04: 'SIP', - 0x05: 'Chip', - 0x06: 'DIP', - 0x07: 'ZIP', - 0x08: 'Proprietary Card', - 0x09: 'DIMM', - 0x0A: 'TSOP', - 0x0B: 'Row of chips', - 0x0C: 'RIMM', - 0x0D: 'SODIMM', - 0x0E: 'SRIMM', - 0x0F: 'FB-DIMM' - } - self.add_field('form_factor', u.unpack_one("B"), unpack.format_table("{}", _form_factors)) - if self.length > 0xF: - self.add_field('device_set', u.unpack_one("B")) - if self.length > 0x10: - self.add_field('device_locator', u.unpack_one("B"), self.fmtstr) - if self.length > 0x11: - self.add_field('bank_locator', u.unpack_one("B"), self.fmtstr) - if self.length > 0x12: - _memory_types = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'DRAM', - 0x04: 'EDRAM', - 0x05: 'VRAM', - 0x06: 'SRAM', - 0x07: 'RAM', - 0x08: 'ROM', - 0x09: 'FLASH', - 0x0A: 'EEPROM', - 0x0B: 'FEPROM', - 0x0C: 'EPROM', - 0x0D: 'CDRAM', - 0x0E: '3DRAM', - 0x0F: 'SDRAM', - 0x10: 'SGRAM', - 0x11: 'RDRAM', - 0x12: 'DDR', - 0x13: 'DDR2', - 0x14: 'DDR2 FB-DIMM', - xrange(0x15, 0x17): 'Reserved', - 0x18: 'DDR3', - 0x19: 'FBD2' - } - self.add_field('memory_type', u.unpack_one("B"), unpack.format_table("{}", _memory_types)) - if self.length > 0x13: - self.add_field('type_detail', u.unpack_one('<H')) - if self.length > 0x15: - self.add_field('speed', u.unpack_one("<H")) - if self.length > 0x17: - self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr) - if self.length > 0x18: - self.add_field('serial_number', u.unpack_one("B"), self.fmtstr) - if self.length > 0x19: - self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr) - if self.length > 0x1A: - self.add_field('part_number', u.unpack_one("B"), self.fmtstr) - if self.length > 0x1B: - self.add_field('attributes', u.unpack_one("B")) - self.add_field('rank', bitfields.getbits(self.attributes, 3, 0), "attributes[3:0]={}") - if self.length > 0x1C: - if self.size == 0x7FFF: - self.add_field('extended_size', u.unpack_one('<I')) - self.add_field('mem_size', bitfields.getbits(self.type_detail, 30, 0), "type_detail[30:0]={}") - else: - u.skip(4) - if self.length > 0x20: - self.add_field('configured_memory_clock_speed', u.unpack_one("<H")) - if self.length > 0x22: - self.add_field('minimum_voltage', u.unpack_one("<H")) - if self.length > 0x24: - self.add_field('maximum_voltage', u.unpack_one("<H")) - if self.length > 0x26: - self.add_field('configured_voltage', u.unpack_one("<H")) - except: - self.decodeFailure = True - print "Error parsing MemoryDevice" - import traceback - traceback.print_exc() - self.fini() - -class MemoryErrorInfo32Bit(SmbiosBaseStructure): - smbios_structure_type = 18 - - def __init__(self, u, sm): - super(MemoryErrorInfo32Bit, self).__init__(u, sm) - u = self.u - try: - if self.length > 0x4: - _error_types = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'OK', - 0x04: 'Bad read', - 0x05: 'Parity error', - 0x06: 'Single-bit error', - 0x07: 'Double-bit error', - 0x08: 'Multi-bit error', - 0x09: 'Nibble error', - 0x0A: 'Checksum error', - 0x0B: 'CRC error', - 0x0C: 'Corrected single-bit error', - 0x0D: 'Corrected error', - 0x0E: 'Uncorrectable error' - } - self.add_field('error_type', u.unpack_one("B"), unpack.format_table("{}", _error_types)) - if self.length > 0x5: - _error_granularity_field = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'Device level', - 0x04: 'Memory partition level' - } - self.add_field('error_granularity', u.unpack_one("B"), unpack.format_table("{}", _error_granularity_field)) - if self.length > 0x6: - _error_operation_field = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'Read', - 0x04: 'Write', - 0x05: 'Partial write' - } - self.add_field('error_operation', u.unpack_one("B"), unpack.format_table("{}", _error_operation_field)) - if self.length > 0x7: - self.add_field('vendor_syndrome', u.unpack_one("<I")) - if self.length > 0xB: - self.add_field('memory_array_error_address', u.unpack_one("<I")) - if self.length > 0xF: - self.add_field('device_error_address', u.unpack_one("<I")) - if self.length > 0x13: - self.add_field('error_resolution', u.unpack_one("<I")) - except: - self.decodeFailure = True - print "Error parsing MemoryErrorInfo32Bit" - import traceback - traceback.print_exc() - self.fini() - -class MemoryArrayMappedAddress(SmbiosBaseStructure): - smbios_structure_type = 19 - - def __init__(self, u, sm): - super(MemoryArrayMappedAddress, self).__init__(u, sm) - u = self.u - try: - if self.length > 0x4: - self.add_field('starting_address', u.unpack_one("<I")) - # if FFFF FFFF: address stored in Extended Starting Address - if self.length > 0x8: - self.add_field('ending_address', u.unpack_one("<I")) - if self.length > 0xC: - self.add_field('memory_array_handle', u.unpack_one("<H")) - if self.length > 0xE: - self.add_field('partition_width', u.unpack_one("B")) - if self.length > 0xF: - # valid if starting_address = FFFF FFFF - if self.starting_address == 0xFFFFFFFF: - self.add_field('extended_starting_address', u.unpack_one("<Q")) - if self.length > 0x17: - self.add_field('extended_ending_address', u.unpack_one("<Q")) - else: - u.skip(16) - - except: - self.decodeFailure = True - print "Error parsing MemoryArrayMappedAddress" - import traceback - traceback.print_exc() - self.fini() - -class MemoryDeviceMappedAddress(SmbiosBaseStructure): - smbios_structure_type = 20 - - def __init__(self, u, sm): - super(MemoryDeviceMappedAddress, self).__init__(u, sm) - u = self.u - try: - if self.length > 0x4: - self.add_field('starting_address', u.unpack_one("<I")) - # if FFFF FFFF: address stored in Extended Starting Address - if self.length > 0x8: - self.add_field('ending_address', u.unpack_one("<I")) - if self.length > 0xC: - self.add_field('memory_device_handle', u.unpack_one("<H")) - if self.length > 0xE: - self.add_field('memory_array_mapped_address_handle', u.unpack_one("<H")) - if self.length > 0x10: - self.add_field('partition_row_position', u.unpack_one("B")) - if self.length > 0x11: - self.add_field('interleave_position', u.unpack_one("B")) - if self.length > 0x12: - self.add_field('interleave_data_depth', u.unpack_one("B")) - if self.length > 0x13: - # valid if starting_address = FFFF FFFF - if self.starting_address == 0xFFFFFFFF: - self.add_field('extended_starting_address', u.unpack_one("<Q")) - if self.length > 0x1B: - self.add_field('extended_ending_address', u.unpack_one("<Q")) - else: - u.skip(16) - except: - self.decodeFailure = True - print "Error parsing MemoryDeviceMappedAddress" - import traceback - traceback.print_exc() - self.fini() - -class BuiltInPointingDevice(SmbiosBaseStructure): - smbios_structure_type = 21 - - def __init__(self, u, sm): - super(BuiltInPointingDevice, self).__init__(u, sm) - u = self.u - try: - if self.length > 0x4: - _pointing_device_types = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'Mouse', - 0x04: 'Track Ball', - 0x05: 'Track Point', - 0x06: 'Glide Point', - 0x07: 'Touch Pad', - 0x08: 'Touch Screen', - 0x09: 'Optical Sensor' - } - self.add_field('pointing_device_type', u.unpack_one("B"), unpack.format_table("{}", _pointing_device_types)) - if self.length > 0x5: - _interfaces = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'Serial', - 0x04: 'PS/2', - 0x05: 'Infared', - 0x06: 'HP-HIL', - 0x07: 'Bus mouse', - 0x08: 'ADB (Apple Desktop Bus)', - 0x09: 'Bus mouse DB-9', - 0x0A: 'Bus mouse micro-DIN', - 0x0B: 'USB' - } - self.add_field('interface', u.unpack_one("B"), unpack.format_table("{}", _interfaces)) - if self.length > 0x6: - self.add_field('num_buttons', u.unpack_one("B")) - except: - self.decodeFailure = True - print "Error parsing BuiltInPointingDevice" - import traceback - traceback.print_exc() - self.fini() - -class PortableBattery(SmbiosBaseStructure): - smbios_structure_type = 22 - - def __init__(self, u, sm): - super(PortableBattery, self).__init__(u, sm) - u = self.u - try: - if self.length > 0x4: - self.add_field('location', u.unpack_one("B"), self.fmtstr) - if self.length > 0x5: - self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr) - if self.length > 0x6: - self.add_field('manufacturer_date', u.unpack_one("B"), self.fmtstr) - if self.length > 0x7: - self.add_field('serial_number', u.unpack_one("B"), self.fmtstr) - if self.length > 0x8: - self.add_field('device_name', u.unpack_one("B"), self.fmtstr) - if self.length > 0x9: - _device_chemistry = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'Lead Acid', - 0x04: 'Nickel Cadmium', - 0x05: 'Nickel metal hydride', - 0x06: 'Lithium-ion', - 0x07: 'Zinc air', - 0x08: 'Lithium Polymer' - } - self.add_field('device_chemistry', u.unpack_one("B"), unpack.format_table("{}", _device_chemistry)) - if self.length > 0xA: - self.add_field('design_capacity', u.unpack_one("<H")) - if self.length > 0xC: - self.add_field('design_voltage', u.unpack_one("<H")) - if self.length > 0xE: - self.add_field('sbds_version_number', u.unpack_one("B"), self.fmtstr) - if self.length > 0xF: - self.add_field('max_error_battery_data', u.unpack_one("B"), self.fmtstr) - if self.length > 0x10: - if self.serial_number == 0: - self.add_field('sbds_serial_number', u.unpack_one("<H")) - else: - u.skip(2) - if self.length > 0x12: - if self.manufacturer_date == 0: - self.add_field('sbds_manufacture_date', u.unpack_one("<H")) - self.add_field('year_biased_by_1980', bitfields.getbits(self.sbds_manufacture_date, 15, 9), "sbds_manufacture_date[15:9]={}") - self.add_field('month', bitfields.getbits(self.sbds_manufacture_date, 8, 5), "sbds_manufacture_date[8:5]={}") - self.add_field('date', bitfields.getbits(self.sbds_manufacture_date, 4, 0), "sbds_manufacture_date[4:0]={}") - else: - u.skip(2) - if self.length > 0x14: - if self.device_chemistry == 0x02: - self.add_field('sbds_device_chemistry', u.unpack_one("B"), self.fmtstr) - else: - u.skip(1) - if self.length > 0x15: - self.add_field('design_capacity_multiplier', u.unpack_one("B")) - if self.length > 0x16: - self.add_field('oem_specific', u.unpack_one("<I")) - except: - self.decodeFailure = True - print "Error parsing PortableBattery" - import traceback - traceback.print_exc() - self.fini() - -class SystemReset(SmbiosBaseStructure): - smbios_structure_type = 23 - - def __init__(self, u, sm): - super(SystemReset, self).__init__(u, sm) - u = self.u - try: - if self.length > 0x4: - self.add_field('capabilities', u.unpack_one("B")) - self.add_field('contains_watchdog_timer', bool(bitfields.getbits(self.capabilities, 5)), "capabilities[5]={}") - _boot_option = { - 0b00: 'Reserved, do not use', - 0b01: 'Operating System', - 0b10: 'System utilities', - 0b11: 'Do not reboot' - } - self.add_field('boot_option_on_limit', bitfields.getbits(self.capabilities, 4, 3), unpack.format_table("capabilities[4:3]={}", _boot_option)) - self.add_field('boot_option_after_watchdog_reset', bitfields.getbits(self.capabilities, 2, 1), unpack.format_table("capabilities[2:1]={}", _boot_option)) - self.add_field('system_reset_enabled_by_user', bool(bitfields.getbits(self.capabilities, 0)), "capabilities[0]={}") - if self.length > 0x5: - self.add_field('reset_count', u.unpack_one("<H")) - if self.length > 0x5: - self.add_field('reset_limit', u.unpack_one("<H")) - if self.length > 0x9: - self.add_field('timer_interval', u.unpack_one("<H")) - if self.length > 0xB: - self.add_field('timeout', u.unpack_one("<H")) - except: - self.decodeFailure = True - print "Error parsing SystemReset" - import traceback - traceback.print_exc() - self.fini() - -class HardwareSecurity(SmbiosBaseStructure): - smbios_structure_type = 24 - - def __init__(self, u, sm): - super(HardwareSecurity, self).__init__(u, sm) - u = self.u - try: - if self.length > 0x4: - self.add_field('hardware_security_settings', u.unpack_one("B")) - _status = { - 0x00: 'Disabled', - 0x01: 'Enabled', - 0x02: 'Not Implemented', - 0x03: 'Unknown' - } - self.add_field('power_on_password_status', bitfields.getbits(self.hardware_security_settings, 7, 6), unpack.format_table("hardware_security_settings[7:6]={}", _status)) - self.add_field('keyboard_password_status', bitfields.getbits(self.hardware_security_settings, 5, 4), unpack.format_table("hardware_security_settings[5:4]={}", _status)) - self.add_field('admin_password_status', bitfields.getbits(self.hardware_security_settings, 3, 2), unpack.format_table("hardware_security_settings0[3:2]={}", _status)) - self.add_field('front_panel_reset_status', bitfields.getbits(self.hardware_security_settings, 1, 0), unpack.format_table("hardware_security_settings[1:0]={}", _status)) - except: - self.decodeFailure = True - print "Error parsing HardwareSecurity" - import traceback - traceback.print_exc() - self.fini() - -class SystemPowerControls(SmbiosBaseStructure): - smbios_structure_type = 25 - - def __init__(self, u, sm): - super(SystemPowerControls, self).__init__(u, sm) - u = self.u - try: - if self.length > 0x4: - self.add_field('next_scheduled_poweron_month', u.unpack_one("B")) - self.add_field('next_scheduled_poweron_day_of_month', u.unpack_one("B")) - self.add_field('next_scheduled_poweron_hour', u.unpack_one("B")) - self.add_field('next_scheduled_poweron_minute', u.unpack_one("B")) - self.add_field('next_scheduled_poweron_second', u.unpack_one("B")) - except: - self.decodeFailure = True - print "Error parsing SystemPowerControls" - import traceback - traceback.print_exc() - self.fini() - -class VoltageProbe(SmbiosBaseStructure): - smbios_structure_type = 26 - - def __init__(self, u, sm): - super(VoltageProbe, self).__init__(u, sm) - u = self.u - try: - if self.length > 0x4: - self.add_field('description', u.unpack_one("B"), self.fmtstr) - if self.length > 0x5: - self.add_field('location_and_status', u.unpack_one("B")) - _status = { - 0b001: 'Other', - 0b010: 'Unknown', - 0b011: 'OK', - 0b100: 'Non-critical', - 0b101: 'Critical', - 0b110: 'Non-recoverable' - } - _location = { - 0b00001: 'Other', - 0b00010: 'Unknown', - 0b00011: 'Processor', - 0b00100: 'Disk', - 0b00101: 'Peripheral Bay', - 0b00110: 'System Management Module', - 0b00111: 'Motherboard', - 0b01000: 'Memory Module', - 0b01001: 'Processor Module', - 0b01010: 'Power Unit', - 0b01011: 'Add-in Card' - } - self.add_field('status', bitfields.getbits(self.location_and_status, 7, 5), unpack.format_table("location_and_status[7:5]={}", _status)) - self.add_field('location', bitfields.getbits(self.location_and_status, 4, 0), unpack.format_table("location_and_status[4:0]={}", _location)) - if self.length > 0x6: - self.add_field('max_value', u.unpack_one("<H")) - if self.length > 0x8: - self.add_field('min_value', u.unpack_one("<H")) - if self.length > 0xA: - self.add_field('resolution', u.unpack_one("<H")) - if self.length > 0xC: - self.add_field('tolerance', u.unpack_one("<H")) - if self.length > 0xE: - self.add_field('accuracy', u.unpack_one("<H")) - if self.length > 0x10: - self.add_field('oem_defined', u.unpack_one("<I")) - if self.length > 0x14: - self.add_field('nominal_value', u.unpack_one("<H")) - except: - self.decodeFailure = True - print "Error parsing VoltageProbe" - import traceback - traceback.print_exc() - self.fini() - -class CoolingDevice(SmbiosBaseStructure): - smbios_structure_type = 27 - - def __init__(self, u, sm): - super(CoolingDevice, self).__init__(u, sm) - u = self.u - try: - if self.length > 0x4: - self.add_field('temperature_probe_handle', u.unpack_one("<H")) - if self.length > 0x6: - self.add_field('device_type_and_status', u.unpack_one("B")) - _status = { - 0b001: 'Other', - 0b010: 'Unknown', - 0b011: 'OK', - 0b100: 'Non-critical', - 0b101: 'Critical', - 0b110: 'Non-recoverable' - } - _type = { - 0b00001: 'Other', - 0b00010: 'Unknown', - 0b00011: 'Fan', - 0b00100: 'Centrifugal Blower', - 0b00101: 'Chip Fan', - 0b00110: 'Cabinet Fan', - 0b00111: 'Power Supply Fan', - 0b01000: 'Heat Pipe', - 0b01001: 'Integrated Refrigeration', - 0b10000: 'Active Cooling', - 0b10001: 'Passive Cooling' - } - self.add_field('status', bitfields.getbits(self.device_type_and_status, 7, 5), unpack.format_table("device_type_and_status[7:5]={}", _status)) - self.add_field('device_type', bitfields.getbits(self.device_type_and_status, 4, 0), unpack.format_table("device_type_and_status[4:0]={}", _type)) - if self.length > 0x7: - self.add_field('cooling_unit_group', u.unpack_one("B")) - if self.length > 0x8: - self.add_field('OEM_defined', u.unpack_one("<I")) - if self.length > 0xC: - self.add_field('nominal_speed', u.unpack_one("<H")) - if self.length > 0xE: - self.add_field('description', u.unpack_one("B"), self.fmtstr) - except: - self.decodeFailure = True - print "Error parsing CoolingDevice" - import traceback - traceback.print_exc() - self.fini() - -class TemperatureProbe(SmbiosBaseStructure): - smbios_structure_type = 28 - - def __init__(self, u, sm): - super(TemperatureProbe, self).__init__(u, sm) - u = self.u - try: - if self.length > 0x4: - self.add_field('description', u.unpack_one("B"), self.fmtstr) - if self.length > 0x5: - self.add_field('location_and_status', u.unpack_one("B")) - _status = { - 0b001: 'Other', - 0b010: 'Unknown', - 0b011: 'OK', - 0b100: 'Non-critical', - 0b101: 'Critical', - 0b110: 'Non-recoverable' - } - _location = { - 0b00001: 'Other', - 0b00010: 'Unknown', - 0b00011: 'Processor', - 0b00100: 'Disk', - 0b00101: 'Peripheral Bay', - 0b00110: 'System Management Module', - 0b00111: 'Motherboard', - 0b01000: 'Memory Module', - 0b01001: 'Processor Module', - 0b01010: 'Power Unit', - 0b01011: 'Add-in Card', - 0b01100: 'Front Panel Board', - 0b01101: 'Back Panel Board', - 0b01110: 'Power System Board', - 0b01111: 'Drive Back Plane' - } - self.add_field('status', bitfields.getbits(self.location_and_status, 7, 5), unpack.format_table("location_and_status[7:5]={}", _status)) - self.add_field('location', bitfields.getbits(self.location_and_status, 4, 0), unpack.format_table("location_and_status[4:0]={}", _location)) - if self.length > 0x6: - self.add_field('maximum_value', u.unpack_one("<H")) - if self.length > 0x8: - self.add_field('minimum_value', u.unpack_one("<H")) - if self.length > 0xA: - self.add_field('resolution', u.unpack_one("<H")) - if self.length > 0xC: - self.add_field('tolerance', u.unpack_one("<H")) - if self.length > 0xE: - self.add_field('accuracy', u.unpack_one("<H")) - if self.length > 0x10: - self.add_field('OEM_defined', u.unpack_one("<I")) - if self.length > 0x14: - self.add_field('nominal_value', u.unpack_one("<H")) - except: - self.decodeFailure = True - print "Error parsing TemperatureProbe" - import traceback - traceback.print_exc() - self.fini() - -class ElectricalCurrentProbe(SmbiosBaseStructure): - smbios_structure_type = 29 - - def __init__(self, u, sm): - super(ElectricalCurrentProbe, self).__init__(u, sm) - u = self.u - try: - if self.length > 0x4: - self.add_field('description', u.unpack_one("B"), self.fmtstr) - if self.length > 0x5: - self.add_field('location_and_status', u.unpack_one("B")) - _status = { - 0b001: 'Other', - 0b010: 'Unknown', - 0b011: 'OK', - 0b100: 'Non-critical', - 0b101: 'Critical', - 0b110: 'Non-recoverable' - } - _location = { - 0b00001: 'Other', - 0b00010: 'Unknown', - 0b00011: 'Processor', - 0b00100: 'Disk', - 0b00101: 'Peripheral Bay', - 0b00110: 'System Management Module', - 0b00111: 'Motherboard', - 0b01000: 'Memory Module', - 0b01001: 'Processor Module', - 0b01010: 'Power Unit', - 0b01011: 'Add-in Card', - 0b01100: 'Front Panel Board', - 0b01101: 'Back Panel Board', - 0b01110: 'Power System Board', - 0b01111: 'Drive Back Plane' - } - self.add_field('status', bitfields.getbits(self.location_and_status, 7, 5), unpack.format_table("location_and_status[7:5]={}", _status)) - self.add_field('location', bitfields.getbits(self.location_and_status, 4, 0), unpack.format_table("location_and_status[4:0]={}", _location)) - if self.length > 0x6: - self.add_field('maximum_value', u.unpack_one("<H")) - if self.length > 0x8: - self.add_field('minimum_value', u.unpack_one("<H")) - if self.length > 0xA: - self.add_field('resolution', u.unpack_one("<H")) - if self.length > 0xC: - self.add_field('tolerance', u.unpack_one("<H")) - if self.length > 0xE: - self.add_field('accuracy', u.unpack_one("<H")) - if self.length > 0x10: - self.add_field('OEM_defined', u.unpack_one("<I")) - if self.length > 0x14: - self.add_field('nominal_value', u.unpack_one("<H")) - except: - self.decodeFailure = True - print "Error parsing ElectricalCurrentProbe" - import traceback - traceback.print_exc() - self.fini() - -class OutOfBandRemoteAccess(SmbiosBaseStructure): - smbios_structure_type = 30 - - def __init__(self, u, sm): - super(OutOfBandRemoteAccess, self).__init__(u, sm) - u = self.u - try: - if self.length > 0x4: - self.add_field('manufacturer_name', u.unpack_one("B"), self.fmtstr) - if self.length > 0x5: - self.add_field('connections', u.unpack_one("B")) - self.add_field('outbound_connection_enabled', bool(bitfields.getbits(self.connections, 1)), "connections[1]={}") - self.add_field('inbound_connection_enabled', bool(bitfields.getbits(self.connections, 0)), "connections[0]={}") - except: - self.decodeFailure = True - print "Error parsing OutOfBandRemoteAccess" - import traceback - traceback.print_exc() - self.fini() - -class BootIntegrityServicesEntryPoint(SmbiosBaseStructure): - smbios_structure_type = 31 - -class SystemBootInformation(SmbiosBaseStructure): - smbios_structure_type = 32 - - def __init__(self, u, sm): - super(SystemBootInformation, self).__init__(u, sm) - u = self.u - try: - if self.length > 0xA: - u.skip(6) - _boot_status = { - 0: 'No errors detected', - 1: 'No bootable media', - 2: '"normal" operating system failed to load', - 3: 'Firmware-detected hardware failure, including "unknown" failure types', - 4: 'Operating system-detected hardware failure', - 5: 'User-requested boot, usually through a keystroke', - 6: 'System security violation', - 7: 'Previously-requested image', - 8: 'System watchdog timer expired, causing the system to reboot', - xrange(9,127): 'Reserved for future assignment', - xrange(128, 191): 'Vendor/OEM-specific implementations', - xrange(192, 255): 'Product-specific implementations' - } - self.add_field('boot_status', u.unpack_one("B"), unpack.format_table("{}", _boot_status)) - except: - self.decodeFailure = True - print "Error parsing SystemBootInformation" - import traceback - traceback.print_exc() - self.fini() - -class MemoryErrorInfo64Bit(SmbiosBaseStructure): - smbios_structure_type = 33 - - def __init__(self, u, sm): - super(MemoryErrorInfo64Bit, self).__init__(u, sm) - u = self.u - try: - if self.length > 0x4: - _error_types = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'OK', - 0x04: 'Bad read', - 0x05: 'Parity error', - 0x06: 'Single-bit error', - 0x07: 'Double-bit error', - 0x08: 'Multi-bit error', - 0x09: 'Nibble error', - 0x0A: 'Checksum error', - 0x0B: 'CRC error', - 0x0C: 'Corrected single-bit error', - 0x0D: 'Corrected error', - 0x0E: 'Uncorrectable error' - } - self.add_field('error_type', u.unpack_one("B"), unpack.format_table("{}", _error_types)) - if self.length > 0x5: - _error_granularity_field = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'Device level', - 0x04: 'Memory partition level' - } - self.add_field('error_granularity', u.unpack_one("B"), unpack.format_table("{}", _error_granularity_field)) - if self.length > 0x6: - _error_operation_field = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'Read', - 0x04: 'Write', - 0x05: 'Partial write' - } - self.add_field('error_operation', u.unpack_one("B"), unpack.format_table("{}", _error_operation_field)) - if self.length > 0x7: - self.add_field('vendor_syndrome', u.unpack_one("<I")) - if self.length > 0xB: - self.add_field('memory_array_error_address', u.unpack_one("<Q")) - if self.length > 0xF: - self.add_field('device_error_address', u.unpack_one("<Q")) - if self.length > 0x13: - self.add_field('error_resolution', u.unpack_one("<Q")) - except: - self.decodeFailure = True - print "Error parsing MemoryErrorInfo64Bit" - import traceback - traceback.print_exc() - self.fini() - -class ManagementDevice(SmbiosBaseStructure): - smbios_structure_type = 34 - - def __init__(self, u, sm): - super(ManagementDevice, self).__init__(u, sm) - u = self.u - try: - if self.length > 0x4: - self.add_field('description', u.unpack_one("B"), self.fmtstr) - if self.length > 0x5: - _type = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'National Semiconductor LM75', - 0x04: 'National Semiconductor LM78', - 0x05: 'National Semiconductor LM79', - 0x06: 'National Semiconductor LM80', - 0x07: 'National Semiconductor LM81', - 0x08: 'Analog Devices ADM9240', - 0x09: 'Dallas Semiconductor DS1780', - 0x0A: 'Maxim 1617', - 0x0B: 'Genesys GL518SM', - 0x0C: 'Winbond W83781D', - 0x0D: 'Holtek HT82H791' - } - self.add_field('device_type', u.unpack_one("B"), unpack.format_table("{}", _type)) - if self.length > 0x6: - self.add_field('address', u.unpack_one("<I")) - if self.length > 0xA: - _address_type = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'I/O Port', - 0x04: 'Memory', - 0x05: 'SM Bus' - } - self.add_field('address_type', u.unpack_one("B"), unpack.format_table("{}", _address_type)) - except: - self.decodeFailure = True - print "Error parsing ManagementDevice" - import traceback - traceback.print_exc() - self.fini() - -class ManagementDeviceComponent(SmbiosBaseStructure): - smbios_structure_type = 35 - - def __init__(self, u, sm): - super(ManagementDeviceComponent, self).__init__(u, sm) - u = self.u - try: - if self.length > 0x4: - self.add_field('description', u.unpack_one("B"), self.fmtstr) - if self.length > 0x5: - self.add_field('management_device_handle', u.unpack_one("<H")) - if self.length > 0x7: - self.add_field('component_handle', u.unpack_one("<H")) - if self.length > 0x9: - self.add_field('threshold_handle', u.unpack_one("<H")) - except: - self.decodeFailure = True - print "Error parsing ManagementDeviceComponent" - import traceback - traceback.print_exc() - self.fini() - -class ManagementDeviceThresholdData(SmbiosBaseStructure): - smbios_structure_type = 36 - - def __init__(self, u, sm): - super(ManagementDeviceThresholdData, self).__init__(u, sm) - u = self.u - try: - if self.length > 0x4: - self.add_field('lower_threshold_noncritical', u.unpack_one("<H")) - if self.length > 0x6: - self.add_field('upper_threshold_noncritical', u.unpack_one("<H")) - if self.length > 0x8: - self.add_field('lower_threshold_critical', u.unpack_one("<H")) - if self.length > 0xA: - self.add_field('upper_threshold_critical', u.unpack_one("<H")) - if self.length > 0xC: - self.add_field('lower_threshold_nonrecoverable', u.unpack_one("<H")) - if self.length > 0xE: - self.add_field('upper_threshold_nonrecoverable', u.unpack_one("<H")) - except: - self.decodeFailure = True - print "Error parsing ManagementDeviceThresholdData" - import traceback - traceback.print_exc() - self.fini() - -class MemoryChannel(SmbiosBaseStructure): - smbios_structure_type = 37 - - def __init__(self, u, sm): - super(MemoryChannel, self).__init__(u, sm) - u = self.u - try: - if self.length > 0x4: - _channel_type = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'RamBus', - 0x04: 'SyncLink' - } - self.add_field('channel_type', u.unpack_one("B"), unpack.format_table("{}", _channel_type)) - if self.length > 0x6: - self.add_field('max_channel_load', u.unpack_one("B")) - if self.length > 0x8: - self.add_field('memory_device_count', u.unpack_one("B")) - if self.length > 0xA: - self.add_field('memory_device_load', u.unpack_one("B")) - if self.length > 0xC: - self.add_field('memory_device_handle', u.unpack_one("<H")) - except: - self.decodeFailure = True - print "Error parsing MemoryChannel" - import traceback - traceback.print_exc() - self.fini() - -class IPMIDeviceInformation(SmbiosBaseStructure): - smbios_structure_type = 38 - - def __init__(self, u, sm): - super(IPMIDeviceInformation, self).__init__(u, sm) - u = self.u - try: - _interface_type = { - 0x00: 'Unknown', - 0x01: 'KCS: Keyboard Controller Style', - 0x02: 'SMIC: Server Management Interface Chip', - 0x03: 'BT: Block Transfer', - xrange(0x04, 0xFF): 'Reserved' - } - self.add_field('interface_type', u.unpack_one("B"), unpack.format_table("{}", _interface_type)) - self.add_field('ipmi_specification_revision', u.unpack_one("B")) - self.add_field('msd_revision', bitfields.getbits(self.ipmi_specification_revision, 7, 4), "ipmi_specification_revision[7:4]={}") - self.add_field('lsd_revision', bitfields.getbits(self.ipmi_specification_revision, 3, 0), "ipmi_specification_revision[3:0]={}") - - self.add_field('i2c_slave_address', u.unpack_one("B")) - self.add_field('nv_storage_device_address', u.unpack_one("B")) - self.add_field('base_address', u.unpack_one("<Q")) - # if lsb is 1, address is in IO space. otherwise, memory-mapped - self.add_field('base_address_modifier_interrupt_info', u.unpack_one("B")) - _reg_spacing = { - 0b00: 'Interface registers are on successive byte boundaries', - 0b01: 'Interface registers are on 32-bit boundaries', - 0b10: 'Interface registers are on 16-byte boundaries', - 0b11: 'Reserved' - } - self.add_field('register_spacing', bitfields.getbits(self.base_address_modifier_interrupt_info, 7, 6), unpack.format_table("base_address_modifier_interrupt_info[7:6]={}", _reg_spacing)) - self.add_field('ls_bit_for_addresses', bitfields.getbits(self.base_address_modifier_interrupt_info, 4), "base_address_modifier_interrupt_info[4]={}") - self.add_field('interrupt_info_specified', bool(bitfields.getbits(self.base_address_modifier_interrupt_info, 3)), "base_address_modifier_interrupt_info[3]={}") - _polarity = { - 0: 'active low', - 1: 'active high' - } - self.add_field('interrupt_polarity', bitfields.getbits(self.base_address_modifier_interrupt_info, 1), unpack.format_table("base_address_modifier_interrupt_info[1]={}", _polarity)) - _interrupt_trigger = { - 0: 'edge', - 1: 'level' - } - self.add_field('interrupt_trigger_mode', bitfields.getbits(self.base_address_modifier_interrupt_info, 0), unpack.format_table("base_address_modifier_interrupt_info[0]={}", _interrupt_trigger)) - self.add_field('interrupt_number', u.unpack_one("B")) - except: - self.decodeFailure = True - print "Error parsing IPMIDeviceInformation" - import traceback - traceback.print_exc() - self.fini() - -class SystemPowerSupply(SmbiosBaseStructure): - smbios_structure_type = 39 - - def __init__(self, u, sm): - super(SystemPowerSupply, self).__init__(u, sm) - u = self.u - try: - if self.length > 0x4: - self.add_field('power_unit_group', u.unpack_one("B")) - if self.length > 0x5: - self.add_field('location', u.unpack_one("B"), self.fmtstr) - if self.length > 0x6: - self.add_field('device_name', u.unpack_one("B"), self.fmtstr) - if self.length > 0x7: - self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr) - if self.length > 0x8: - self.add_field('serial_number', u.unpack_one("B"), self.fmtstr) - if self.length > 0x9: - self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr) - if self.length > 0xA: - self.add_field('model_part_number', u.unpack_one("B"), self.fmtstr) - if self.length > 0xB: - self.add_field('revision_level', u.unpack_one("B"), self.fmtstr) - if self.length > 0xC: - self.add_field('max_power_capacity', u.unpack_one("<H")) - if self.length > 0xE: - self.add_field('power_supply_characteristics', u.unpack_one("<H")) - _dmtf_power_supply_type = { - 0b001: 'Other', - 0b010: 'Unknown', - 0b011: 'Linear', - 0b100: 'Switching', - 0b101: 'Battery', - 0b110: 'UPS', - 0b111: 'Converter', - 0b1000: 'Regulator', - xrange(0b1001, 0b1111): 'Reserved' - } - self.add_field('dmtf_power_supply_type', bitfields.getbits(self.power_supply_characteristics, 13, 10), unpack.format_table("power_supply_characteristics[13:10]={}", _dmtf_power_supply_type)) - _status = { - 0b001: 'Other', - 0b010: 'Unknown', - 0b011: 'OK', - 0b100: 'Non-critical', - 0b101: 'Critical; power supply has failed and has been taken off-line' - } - self.add_field('status', bitfields.getbits(self.power_supply_characteristics, 9, 7), unpack.format_table("power_supply_characteristics[9:7]={}", _status)) - _dmtf_input_voltage_range_switching = { - 0b001: 'Other', - 0b010: 'Unknown', - 0b011: 'Manual', - 0b100: 'Auto-switch', - 0b101: 'Wide range', - 0b110: 'Not applicable', - xrange(0b0111, 0b1111): 'Reserved' - } - self.add_field('dmtf_input_voltage_range_switching', bitfields.getbits(self.power_supply_characteristics, 6, 3), unpack.format_table("power_supply_characteristics[6:3]={}", _dmtf_input_voltage_range_switching)) - self.add_field('power_supply_unplugged', bool(bitfields.getbits(self.power_supply_characteristics, 2)), "power_supply_characteristics[2]={}") - self.add_field('power_supply_present', bool(bitfields.getbits(self.power_supply_characteristics, 1)), "power_supply_characteristics[1]={}") - self.add_field('power_supply_hot_replaceable', bool(bitfields.getbits(self.power_supply_characteristics, 0)), "power_supply_characteristics[0]={}") - if self.length > 0x10: - self.add_field('input_voltage_probe_handle', u.unpack_one("<H")) - if self.length > 0x12: - self.add_field('cooling_device_handle', u.unpack_one("<H")) - if self.length > 0x14: - self.add_field('input_current_probe_handle', u.unpack_one("<H")) - except: - self.decodeFailure = True - print "Error parsing SystemPowerSupply" - import traceback - traceback.print_exc() - self.fini() - -class AdditionalInformation(SmbiosBaseStructure): - smbios_structure_type = 40 - - def __init__(self, u, sm): - super(AdditionalInformation, self).__init__(u, sm) - u = self.u - try: - if self.length > 0x4: - self.add_field('num_additional_information_entries', u.unpack_one("B")) - if self.length > 0x5: - self.add_field('additional_information_entry_length', u.unpack_one("B")) - self.add_field('referenced_handle', u.unpack_one("<H")) - self.add_field('referenced_offset', u.unpack_one("B")) - self.add_field('string', u.unpack_one("B"), self.fmtstr) - self.add_field('value', u.unpack_rest()) - except: - self.decodeFailure = True - print "Error parsing AdditionalInformation" - import traceback - traceback.print_exc() - self.fini() - -class OnboardDevicesExtendedInformation(SmbiosBaseStructure): - smbios_structure_type = 41 - - def __init__(self, u, sm): - super(OnboardDevicesExtendedInformation, self).__init__(u, sm) - u = self.u - try: - if self.length > 0x4: - self.add_field('reference_designation', u.unpack_one("B"), self.fmtstr) - if self.length > 0x5: - self.add_field('device_type', u.unpack_one("B")) - self.add_field('device_enabled', bool(bitfields.getbits(self.device_type, 7)), "device_type[7]={}") - _device_types = { - 0x01: 'Other', - 0x02: 'Unknown', - 0x03: 'Video', - 0x04: 'SCSI Controller', - 0x05: 'Ethernet', - 0x06: 'Token Ring', - 0x07: 'Sound', - 0x08: 'PATA Controller', - 0x09: 'SATA Controller', - 0x0A: 'SAS Controller' - } - self.add_field('type_of_device', bitfields.getbits(self.device_type, 6, 0), unpack.format_table("device_type[6:0]={}", _device_types)) - if self.length > 0x6: - self.add_field('device_type_instance', u.unpack_one("B")) - if self.length > 0x7: - self.add_field('segment_group_number', u.unpack_one("<H")) - if self.length > 0x9: - self.add_field('bus_number', u.unpack_one("B"), self.fmtstr) - if self.length > 0xA: - self.add_field('device_and_function_number', u.unpack_one("B")) - self.add_field('device_number', bitfields.getbits(self.device_type, 7, 3), "device_and_function_number[7:3]={}") - self.add_field('function_number', bitfields.getbits(self.device_type, 2, 0), "device_and_function_number[2:0]={}") - except: - self.decodeFailure = True - print "Error parsing OnboardDevicesExtendedInformation" - import traceback - traceback.print_exc() - self.fini() - -class ManagementControllerHostInterface(SmbiosBaseStructure): - smbios_structure_type = 42 - - def __init__(self, u, sm): - super(ManagementControllerHostInterface, self).__init__(u, sm) - u = self.u - try: - if self.length > 0x4: - _interface_types = { - 0x00: 'Reserved', - 0x01: 'Reserved', - 0x02: 'KCS: Keyboard Controller Style', - 0x03: '8250 UART Register Compatible', - 0x04: '16450 UART Register Compatible', - 0x05: '16550/16550A UART Register Compatible', - 0x06: '16650/16650A UART Register Compatible', - 0x07: '16750/16750A UART Register Compatible', - 0x08: '16850/16850A UART Register Compatible', - 0xF0: 'OEM' - } - self.add_field('interface_type', u.unpack_one("B"), unpack.format_table("{}", _interface_types)) - if self.length > 0x5: - self.add_field('mc_host_interface_data', u.unpack_rest(), self.fmtstr) - except: - self.decodeFailure = True - print "Error parsing ManagementControllerHostInterface" - import traceback - traceback.print_exc() - self.fini() - -class Inactive(SmbiosBaseStructure): - smbios_structure_type = 126 - - def __init__(self, u, sm): - super(Inactive, self).__init__(u, sm) - self.fini() - -class EndOfTable(SmbiosBaseStructure): - smbios_structure_type = 127 - - def __init__(self, u, sm): - super(EndOfTable, self).__init__(u, sm) - self.fini() - -class SmbiosStructureUnknown(SmbiosBaseStructure): - smbios_structure_type = None - - def __init__(self, u, sm): - super(SmbiosStructureUnknown, self).__init__(u, sm) - self.fini() - -_smbios_structures = [ - BIOSInformation, - SystemInformation, - BaseboardInformation, - SystemEnclosure, - ProcessorInformation, - MemoryControllerInformation, - MemoryModuleInformation, - CacheInformation, - PortConnectorInfo, - SystemSlots, - OnBoardDevicesInformation, - OEMStrings, - SystemConfigOptions, - BIOSLanguageInformation, - GroupAssociations, - SystemEventLog, - PhysicalMemoryArray, - MemoryDevice, - MemoryErrorInfo32Bit, - MemoryArrayMappedAddress, - MemoryDeviceMappedAddress, - BuiltInPointingDevice, - PortableBattery, - SystemReset, - HardwareSecurity, - SystemPowerControls, - VoltageProbe, - CoolingDevice, - TemperatureProbe, - ElectricalCurrentProbe, - OutOfBandRemoteAccess, - BootIntegrityServicesEntryPoint, - SystemBootInformation, - MemoryErrorInfo64Bit, - ManagementDevice, - ManagementDeviceComponent, - ManagementDeviceThresholdData, - MemoryChannel, - IPMIDeviceInformation, - SystemPowerSupply, - AdditionalInformation, - OnboardDevicesExtendedInformation, - ManagementControllerHostInterface, - Inactive, - EndOfTable, - SmbiosStructureUnknown, # Must always come last -] - -def log_smbios_info(): - with redirect.logonly(): - try: - sm = SMBIOS() - print - if sm is None: - print "No SMBIOS structures found" - return - output = {} - known_types = (0, 1) - for sm_struct in sm.structures: - if sm_struct.type in known_types: - output.setdefault(sm_struct.type, []).append(sm_struct) - if len(output) == len(known_types): - break - - print "SMBIOS information:" - for key in sorted(known_types): - for s in output.get(key, ["No structure of type {} found".format(key)]): - print ttypager._wrap("{}: {}".format(key, s)) - except: - print "Error parsing SMBIOS information:" - import traceback - traceback.print_exc() - -def dump_raw(): - try: - sm = SMBIOS() - if sm: - s = "SMBIOS -- Raw bytes and structure decode.\n\n" - - s += str(sm.header) + '\n' - s += bits.dumpmem(sm._header_memory) + '\n' - - s += "Raw bytes for the SMBIOS structures\n" - s += bits.dumpmem(sm._structure_memory) + '\n' - - for sm_struct in sm.structures: - s += str(sm_struct) + '\n' - s += bits.dumpmem(sm_struct.raw_data) - - s += "Strings:\n" - for n in range(1, len(getattr(sm_struct, "strings", [])) + 1): - s += str(sm_struct.fmtstr(n)) + '\n' - s += bits.dumpmem(sm_struct.raw_strings) + '\n' - else: - s = "No SMBIOS structures found" - ttypager.ttypager_wrap(s, indent=False) - except: - print "Error parsing SMBIOS information:" - import traceback - traceback.print_exc() - -def dump(): - try: - sm = SMBIOS() - if sm: - s = str(sm) - else: - s = "No SMBIOS structures found" - ttypager.ttypager_wrap(s, indent=False) - except: - print "Error parsing SMBIOS information:" - import traceback - traceback.print_exc() - -def annex_a_conformance(): - try: - sm = SMBIOS() - - # check: 1. The table anchor string "_SM_" is present in the address range 0xF0000 to 0xFFFFF on a 16-byte bound - - def table_entry_point_verification(): - ''' Verify table entry-point''' - if (sm.header.length < 0x1F): - print "Failure: Table entry-point - The entry-point Length must be at least 0x1F" - if sm.header.checksum != 0: - print "Failure: Table entry-point - The entry-point checksum must evaluate to 0" - if ((sm.header.major_version < 2) and (sm.header.minor_version < 4)): - print "Failure: Table entry-point - SMBIOS version must be at least 2.4" - if (sm.header.intermediate_anchor_string == '_DMI_'): - print "Failure: Table entry-point - The Intermediate Anchor String must be '_DMI_'" - if (sm.header.intermediate_checksum != 0): - print "Failure: Table entry-point - The Intermediate checksum must evaluate to 0" - - #check: 3. The structure-table is traversable and conforms to the entry-point specifications: - - def req_structures(): - '''Checks for required structures and corresponding data''' - types_present = [sm.structures[x].smbios_structure_type for x in range(len(sm.structures))] - required = [0, 1, 4, 7, 9, 16, 17, 19, 31, 32] - for s in required: - if s not in set(types_present): - print "Failure: Type {} required but not found".format(s) - - else: - if s == 0: - if types_present.count(s) > 1: - print "Failure: Type {} - One and only one structure of this type must be present.".format(s) - if sm.structure_type(s).length < 0x18: - print "Failure: Type {} - The structure Length field must be at least 0x18".format(s) - if sm.structure_type(s).version is None: - print "Failure: Type {} - BIOS Version string must be present and non-null.".format(s) - if sm.structure_type(s).release_date is None: - print "Failure: Type {} - BIOS Release Date string must be present, non-null, and include a 4-digit year".format(s) - if bitfields.getbits(sm.structure_type(s).characteristics, 3, 0) != 0 or bitfields.getbits(sm.structure_type(s).characteristics, 31, 4) == 0: - print "Failure: Type {} - BIOS Characteristics: bits 3:0 must all be 0, and at least one of bits 31:4 must be set to 1.".format(s) - elif s == 1: - if types_present.count(s) > 1: - print "Failure: Type {} - One and only one structure of this type must be present.".format(s) - if sm.structure_type(s).length < 0x1B: - print "Failure: Type {} - The structure Length field must be at least 0x1B".format(s) - if sm.structure_type(s).manufacturer == None: - print "Failure: Type {} - Manufacturer string must be present and non-null.".format(s) - if sm.structure_type(s).product_name == None: - print "Failure: Type {} - Product Name string must be present and non-null".format(s) - if sm.structure_type(s).uuid == '00000000 00000000' and sm.structure_type(s).uuid == 'FFFFFFFF FFFFFFFF': - print "Failure: Type {} - UUID field must be neither 00000000 00000000 nor FFFFFFFF FFFFFFFF.".format(s) - if sm.structure_type(s).wakeup_type == 00 and sm.structure_type(s).wakeup_type == 0x02: - print "Failure: Type {} - Wake-up Type field must be neither 00h (Reserved) nor 02h (Unknown).".format(s) - # continue for remaining required types - - # check remaining conformance guidelines - - table_entry_point_verification() - req_structures() - except: - print "Error checking ANNEX A conformance guidelines" - import traceback - traceback.print_exc() diff --git a/tests/avocado/acpi-bits/bits-tests/smilatency.py2 b/tests/avocado/acpi-bits/bits-tests/smilatency.py2 deleted file mode 100644 index 405af67..0000000 --- a/tests/avocado/acpi-bits/bits-tests/smilatency.py2 +++ /dev/null @@ -1,107 +0,0 @@ -# Copyright (c) 2015, Intel Corporation -# All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause - -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# * Neither the name of Intel Corporation nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# This script runs only from the biosbits VM. - -"""SMI latency test.""" - -import bits -from collections import namedtuple -import testsuite -import time -import usb - -def register_tests(): - pass -# testsuite.add_test("SMI latency test", smi_latency); -# testsuite.add_test("SMI latency test with USB disabled via BIOS handoff", test_with_usb_disabled, runall=False); - -def smi_latency(): - MSR_SMI_COUNT = 0x34 - - print "Warning: touching the keyboard can affect the results of this test." - - tsc_per_sec = bits.tsc_per_sec() - tsc_per_usec = tsc_per_sec / (1000 * 1000) - bins = [long(tsc_per_usec * 10**i) for i in range(9)] - bin_descs = [ - "0 < t <= 1us", - "1us < t <= 10us", - "10us < t <= 100us", - "100us < t <= 1ms", - "1ms < t <= 10ms", - "10ms < t <= 100ms", - "100ms < t <= 1s ", - "1s < t <= 10s ", - "10s < t <= 100s ", - "100s < t ", - ] - - print "Starting test. Wait here, I will be back in 15 seconds." - (max_latency, smi_count_delta, bins) = bits.smi_latency(long(15 * tsc_per_sec), bins) - BinType = namedtuple('BinType', ("max", "total", "count", "times")) - bins = [BinType(*b) for b in bins] - - testsuite.test("SMI latency < 150us to minimize risk of OS timeouts", max_latency / tsc_per_usec <= 150) - if not testsuite.show_detail(): - return - - for bin, desc in zip(bins, bin_descs): - if bin.count == 0: - continue - testsuite.print_detail("{}; average = {}; count = {}".format(desc, bits.format_tsc(bin.total/bin.count), bin.count)) - deltas = (bits.format_tsc(t2 - t1) for t1,t2 in zip(bin.times, bin.times[1:])) - testsuite.print_detail(" Times between first few observations: {}".format(" ".join("{:>6}".format(delta) for delta in deltas))) - - if smi_count_delta is not None: - testsuite.print_detail("{} SMI detected using MSR_SMI_COUNT (MSR {:#x})".format(smi_count_delta, MSR_SMI_COUNT)) - - testsuite.print_detail("Summary of impact: observed maximum latency = {}".format(bits.format_tsc(max_latency))) - -def test_with_usb_disabled(): - if usb.handoff_to_os(): - smi_latency() - -def average_io_smi(port, value, count): - def f(): - tsc_start = bits.rdtsc() - bits.outb(port, value) - return bits.rdtsc() - tsc_start - counts = [f() for i in range(count)] - return sum(counts)/len(counts) - -def time_io_smi(port=0xb2, value=0, count=1000): - count_for_estimate = 10 - start = time.time() - average_io_smi(port, value, count_for_estimate) - avg10 = time.time() - start - estimate = avg10 * count/count_for_estimate - if estimate > 1: - print "Running test, estimated time: {}s".format(int(estimate)) - average = average_io_smi(port, value, count) - print "Average of {} SMIs (via outb, port={:#x}, value={:#x}): {}".format(count, port, value, bits.format_tsc(average)) diff --git a/tests/avocado/acpi-bits/bits-tests/testacpi.py2 b/tests/avocado/acpi-bits/bits-tests/testacpi.py2 deleted file mode 100644 index 7bf9075..0000000 --- a/tests/avocado/acpi-bits/bits-tests/testacpi.py2 +++ /dev/null @@ -1,287 +0,0 @@ -# Copyright (c) 2015, Intel Corporation -# All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# * Neither the name of Intel Corporation nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# This script runs only from the biosbits VM. - -"""Tests for ACPI""" - -import acpi -import bits -import bits.mwait -import struct -import testutil -import testsuite -import time - -def register_tests(): - testsuite.add_test("ACPI _MAT (Multiple APIC Table Entry) under Processor objects", test_mat, submenu="ACPI Tests") -# testsuite.add_test("ACPI _PSS (Pstate) table conformance tests", test_pss, submenu="ACPI Tests") -# testsuite.add_test("ACPI _PSS (Pstate) runtime tests", test_pstates, submenu="ACPI Tests") - testsuite.add_test("ACPI DSDT (Differentiated System Description Table)", test_dsdt, submenu="ACPI Tests") - testsuite.add_test("ACPI FACP (Fixed ACPI Description Table)", test_facp, submenu="ACPI Tests") - testsuite.add_test("ACPI HPET (High Precision Event Timer Table)", test_hpet, submenu="ACPI Tests") - testsuite.add_test("ACPI MADT (Multiple APIC Description Table)", test_apic, submenu="ACPI Tests") - testsuite.add_test("ACPI MPST (Memory Power State Table)", test_mpst, submenu="ACPI Tests") - testsuite.add_test("ACPI RSDP (Root System Description Pointer Structure)", test_rsdp, submenu="ACPI Tests") - testsuite.add_test("ACPI XSDT (Extended System Description Table)", test_xsdt, submenu="ACPI Tests") - -def test_mat(): - cpupaths = acpi.get_cpupaths() - apic = acpi.parse_apic() - procid_apicid = apic.procid_apicid - uid_x2apicid = apic.uid_x2apicid - for cpupath in cpupaths: - # Find the ProcId defined by the processor object - processor = acpi.evaluate(cpupath) - # Find the UID defined by the processor object's _UID method - uid = acpi.evaluate(cpupath + "._UID") - mat_buffer = acpi.evaluate(cpupath + "._MAT") - if mat_buffer is None: - continue - # Process each _MAT subtable - mat = acpi._MAT(mat_buffer) - for index, subtable in enumerate(mat): - if subtable.subtype == acpi.MADT_TYPE_LOCAL_APIC: - if subtable.flags.bits.enabled: - testsuite.test("{} Processor declaration ProcId = _MAT ProcId".format(cpupath), processor.ProcId == subtable.proc_id) - testsuite.print_detail("{} ProcId ({:#02x}) != _MAT ProcId ({:#02x})".format(cpupath, processor.ProcId, subtable.proc_id)) - testsuite.print_detail("Processor Declaration: {}".format(processor)) - testsuite.print_detail("_MAT entry[{}]: {}".format(index, subtable)) - if testsuite.test("{} with local APIC in _MAT has local APIC in MADT".format(cpupath), processor.ProcId in procid_apicid): - testsuite.test("{} ApicId derived using Processor declaration ProcId = _MAT ApicId".format(cpupath), procid_apicid[processor.ProcId] == subtable.apic_id) - testsuite.print_detail("{} ApicId derived from MADT ({:#02x}) != _MAT ApicId ({:#02x})".format(cpupath, procid_apicid[processor.ProcId], subtable.apic_id)) - testsuite.print_detail("Processor Declaration: {}".format(processor)) - testsuite.print_detail("_MAT entry[{}]: {}".format(index, subtable)) - if subtable.subtype == acpi.MADT_TYPE_LOCAL_X2APIC: - if subtable.flags.bits.enabled: - if testsuite.test("{} with x2Apic in _MAT has _UID".format(cpupath), uid is not None): - testsuite.test("{}._UID = _MAT UID".format(cpupath), uid == subtable.uid) - testsuite.print_detail("{}._UID ({:#x}) != _MAT UID ({:#x})".format(cpupath, uid, subtable.uid)) - testsuite.print_detail("_MAT entry[{}]: {}".format(index, subtable)) - if testsuite.test("{} with _MAT x2Apic has x2Apic in MADT".format(cpupath), subtable.uid in uid_x2apicid): - testsuite.test("{} x2ApicId derived from MADT using UID = _MAT x2ApicId".format(cpupath), uid_x2apicid[subtable.uid] == subtable.x2apicid) - testsuite.print_detail("{} x2ApicId derived from MADT ({:#02x}) != _MAT x2ApicId ({:#02x})".format(cpupath, uid_x2apicid[subtable.uid], subtable.x2apicid)) - testsuite.print_detail("_MAT entry[{}]: {}".format(index, subtable)) - -def test_pss(): - uniques = acpi.parse_cpu_method("_PSS") - # We special-case None here to avoid a double-failure for CPUs without a _PSS - testsuite.test("_PSS must be identical for all CPUs", len(uniques) <= 1 or (len(uniques) == 2 and None in uniques)) - for pss, cpupaths in uniques.iteritems(): - if not testsuite.test("_PSS must exist", pss is not None): - testsuite.print_detail(acpi.factor_commonprefix(cpupaths)) - testsuite.print_detail('No _PSS exists') - continue - - if not testsuite.test("_PSS must not be empty", pss.pstates): - testsuite.print_detail(acpi.factor_commonprefix(cpupaths)) - testsuite.print_detail('_PSS is empty') - continue - - testsuite.print_detail(acpi.factor_commonprefix(cpupaths)) - for index, pstate in enumerate(pss.pstates): - testsuite.print_detail("P[{}]: {}".format(index, pstate)) - - testsuite.test("_PSS must contain at most 16 Pstates", len(pss.pstates) <= 16) - testsuite.test("_PSS must have no duplicate Pstates", len(pss.pstates) == len(set(pss.pstates))) - - frequencies = [p.core_frequency for p in pss.pstates] - testsuite.test("_PSS must list Pstates in descending order of frequency", frequencies == sorted(frequencies, reverse=True)) - - testsuite.test("_PSS must have Pstates with no duplicate frequencies", len(frequencies) == len(set(frequencies))) - - dissipations = [p.power for p in pss.pstates] - testsuite.test("_PSS must list Pstates in descending order of power dissipation", dissipations == sorted(dissipations, reverse=True)) - -def test_pstates(): - """Execute and verify frequency for each Pstate in the _PSS""" - IA32_PERF_CTL = 0x199 - with bits.mwait.use_hint(), bits.preserve_msr(IA32_PERF_CTL): - cpupath_procid = acpi.find_procid() - cpupath_uid = acpi.find_uid() - apic = acpi.parse_apic() - procid_apicid = apic.procid_apicid - uid_x2apicid = apic.uid_x2apicid - def cpupath_apicid(cpupath): - if procid_apicid is not None: - procid = cpupath_procid.get(cpupath, None) - if procid is not None: - apicid = procid_apicid.get(procid, None) - if apicid is not None: - return apicid - if uid_x2apicid is not None: - uid = cpupath_uid.get(cpupath, None) - if uid is not None: - apicid = uid_x2apicid.get(uid, None) - if apicid is not None: - return apicid - return bits.cpus()[0] - - bclk = testutil.adjust_to_nearest(bits.bclk(), 100.0/12) * 1000000 - - uniques = acpi.parse_cpu_method("_PSS") - for pss, cpupaths in uniques.iteritems(): - if not testsuite.test("_PSS must exist", pss is not None): - testsuite.print_detail(acpi.factor_commonprefix(cpupaths)) - testsuite.print_detail('No _PSS exists') - continue - - for n, pstate in enumerate(pss.pstates): - for cpupath in cpupaths: - apicid = cpupath_apicid(cpupath) - if apicid is None: - print 'Failed to find apicid for cpupath {}'.format(cpupath) - continue - bits.wrmsr(apicid, IA32_PERF_CTL, pstate.control) - - # Detecting Turbo frequency requires at least 2 pstates - # since turbo frequency = max non-turbo frequency + 1 - turbo = False - if len(pss.pstates) >= 2: - turbo = (n == 0 and pstate.core_frequency == (pss.pstates[1].core_frequency + 1)) - if turbo: - # Needs to busywait, not sleep - start = time.time() - while (time.time() - start < 2): - pass - - for duration in (0.1, 1.0): - frequency_data = bits.cpu_frequency(duration) - # Abort the test if no cpu frequency is not available - if frequency_data is None: - continue - aperf = frequency_data[1] - aperf = testutil.adjust_to_nearest(aperf, bclk/2) - aperf = int(aperf / 1000000) - if turbo: - if aperf >= pstate.core_frequency: - break - else: - if aperf == pstate.core_frequency: - break - - if turbo: - testsuite.test("P{}: Turbo measured frequency {} >= expected {} MHz".format(n, aperf, pstate.core_frequency), aperf >= pstate.core_frequency) - else: - testsuite.test("P{}: measured frequency {} MHz == expected {} MHz".format(n, aperf, pstate.core_frequency), aperf == pstate.core_frequency) - -def test_psd_thread_scope(): - uniques = acpi.parse_cpu_method("_PSD") - if not testsuite.test("_PSD (P-State Dependency) must exist for each processor", None not in uniques): - testsuite.print_detail(acpi.factor_commonprefix(uniques[None])) - testsuite.print_detail('No _PSD exists') - return - unique_num_dependencies = {} - unique_num_entries = {} - unique_revision = {} - unique_domain = {} - unique_coordination_type = {} - unique_num_processors = {} - for value, cpupaths in uniques.iteritems(): - unique_num_dependencies.setdefault(len(value.dependencies), []).extend(cpupaths) - unique_num_entries.setdefault(value.dependencies[0].num_entries, []).extend(cpupaths) - unique_revision.setdefault(value.dependencies[0].revision, []).extend(cpupaths) - unique_domain.setdefault(value.dependencies[0].domain, []).extend(cpupaths) - unique_coordination_type.setdefault(value.dependencies[0].coordination_type, []).extend(cpupaths) - unique_num_processors.setdefault(value.dependencies[0].num_processors, []).extend(cpupaths) - def detail(d, fmt): - for value, cpupaths in sorted(d.iteritems(), key=(lambda (k,v): v)): - testsuite.print_detail(acpi.factor_commonprefix(cpupaths)) - testsuite.print_detail(fmt.format(value)) - - testsuite.test('Dependency count for each processor must be 1', unique_num_dependencies.keys() == [1]) - detail(unique_num_dependencies, 'Dependency count for each processor = {} (Expected 1)') - testsuite.test('_PSD.num_entries must be 5', unique_num_entries.keys() == [5]) - detail(unique_num_entries, 'num_entries = {} (Expected 5)') - testsuite.test('_PSD.revision must be 0', unique_revision.keys() == [0]) - detail(unique_revision, 'revision = {}') - testsuite.test('_PSD.coordination_type must be 0xFE (HW_ALL)', unique_coordination_type.keys() == [0xfe]) - detail(unique_coordination_type, 'coordination_type = {:#x} (Expected 0xFE HW_ALL)') - testsuite.test('_PSD.domain must be unique (thread-scoped) for each processor', len(unique_domain) == len(acpi.get_cpupaths())) - detail(unique_domain, 'domain = {:#x} (Expected a unique value for each processor)') - testsuite.test('_PSD.num_processors must be 1', unique_num_processors.keys() == [1]) - detail(unique_num_processors, 'num_processors = {} (Expected 1)') - -def test_table_checksum(data): - csum = sum(ord(c) for c in data) % 0x100 - testsuite.test('ACPI table cumulative checksum must equal 0', csum == 0) - testsuite.print_detail("Cumulative checksum = {} (Expected 0)".format(csum)) - -def test_apic(): - data = acpi.get_table("APIC") - if data is None: - return - test_table_checksum(data) - apic = acpi.parse_apic() - -def test_dsdt(): - data = acpi.get_table("DSDT") - if data is None: - return - test_table_checksum(data) - -def test_facp(): - data = acpi.get_table("FACP") - if data is None: - return - test_table_checksum(data) - facp = acpi.parse_facp() - -def test_hpet(): - data = acpi.get_table("HPET") - if data is None: - return - test_table_checksum(data) - hpet = acpi.parse_hpet() - -def test_mpst(): - data = acpi.get_table("MPST") - if data is None: - return - test_table_checksum(data) - mpst = acpi.MPST(data) - -def test_rsdp(): - data = acpi.get_table("RSD PTR ") - if data is None: - return - - # Checksum the first 20 bytes per ACPI 1.0 - csum = sum(ord(c) for c in data[:20]) % 0x100 - testsuite.test('ACPI 1.0 table first 20 bytes cumulative checksum must equal 0', csum == 0) - testsuite.print_detail("Cumulative checksum = {} (Expected 0)".format(csum)) - - test_table_checksum(data) - rsdp = acpi.parse_rsdp() - -def test_xsdt(): - data = acpi.get_table("XSDT") - if data is None: - return - test_table_checksum(data) - xsdt = acpi.parse_xsdt() diff --git a/tests/avocado/acpi-bits/bits-tests/testcpuid.py2 b/tests/avocado/acpi-bits/bits-tests/testcpuid.py2 deleted file mode 100644 index 7adefbe..0000000 --- a/tests/avocado/acpi-bits/bits-tests/testcpuid.py2 +++ /dev/null @@ -1,87 +0,0 @@ -# Copyright (c) 2012, Intel Corporation -# All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# * Neither the name of Intel Corporation nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# This script runs only from the biosbits VM. - -"""Tests and helpers for CPUID.""" - -import bits -import testsuite -import testutil - -def cpuid_helper(function, index=None, shift=0, mask=~0, eax_mask=~0, ebx_mask=~0, ecx_mask=~0, edx_mask=~0): - if index is None: - index = 0 - indexdesc = "" - else: - indexdesc = " index {0:#x}".format(index) - - def find_mask(m): - if m == ~0: - return mask - return m - masks = map(find_mask, [eax_mask, ebx_mask, ecx_mask, edx_mask]) - - uniques = {} - for cpu in bits.cpus(): - regs = bits.cpuid_result(*[(r >> shift) & m for r, m in zip(bits.cpuid(cpu, function, index), masks)]) - uniques.setdefault(regs, []).append(cpu) - - desc = ["CPUID function {:#x}{}".format(function, indexdesc)] - - if shift != 0: - desc.append("Register values have been shifted by {}".format(shift)) - if mask != ~0 or eax_mask != ~0 or ebx_mask != ~0 or ecx_mask != ~0 or edx_mask != ~0: - desc.append("Register values have been masked:") - shifted_masks = bits.cpuid_result(*[m << shift for m in masks]) - desc.append("Masks: eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**shifted_masks._asdict())) - - if len(uniques) > 1: - regvalues = zip(*uniques.iterkeys()) - common_masks = bits.cpuid_result(*map(testutil.find_common_mask, regvalues)) - common_values = bits.cpuid_result(*[v[0] & m for v, m in zip(regvalues, common_masks)]) - desc.append('Register values are not unique across all logical processors') - desc.append("Common bits: eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**common_values._asdict())) - desc.append("Mask of common bits: {eax:#010x} {ebx:#010x} {ecx:#010x} {edx:#010x}".format(**common_masks._asdict())) - - for regs in sorted(uniques.iterkeys()): - cpus = uniques[regs] - desc.append("Register value: eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**regs._asdict())) - desc.append("On {0} CPUs: {1}".format(len(cpus), testutil.apicid_list(cpus))) - - return uniques, desc - -def test_cpuid_consistency(text, function, index=None, shift=0, mask=~0, eax_mask=~0, ebx_mask=~0, ecx_mask=~0, edx_mask=~0): - uniques, desc = cpuid_helper(function, index, shift, mask, eax_mask, ebx_mask, ecx_mask, edx_mask) - desc[0] += " Consistency Check" - if text: - desc.insert(0, text) - status = testsuite.test(desc[0], len(uniques) == 1) - for line in desc[1:]: - testsuite.print_detail(line) - return status diff --git a/tests/avocado/avocado_qemu/__init__.py b/tests/avocado/avocado_qemu/__init__.py deleted file mode 100644 index 304c428..0000000 --- a/tests/avocado/avocado_qemu/__init__.py +++ /dev/null @@ -1,681 +0,0 @@ -# Test class and utilities for functional tests -# -# Copyright (c) 2018 Red Hat, Inc. -# -# Author: -# Cleber Rosa <crosa@redhat.com> -# -# 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 -import os -import shutil -import subprocess -import sys -import tempfile -import time -import uuid - -import avocado -from avocado.utils import cloudinit, datadrainer, process, ssh, vmimage -from avocado.utils.path import find_command - -from qemu.machine import QEMUMachine -from qemu.utils import (get_info_usernet_hostfwd_port, kvm_available, - tcg_available) - - -#: The QEMU build root directory. It may also be the source directory -#: if building from the source dir, but it's safer to use BUILD_DIR for -#: that purpose. Be aware that if this code is moved outside of a source -#: and build tree, it will not be accurate. -BUILD_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) - -if os.path.islink(os.path.dirname(os.path.dirname(__file__))): - # The link to the avocado tests dir in the source code directory - lnk = os.path.dirname(os.path.dirname(__file__)) - #: The QEMU root source directory - SOURCE_DIR = os.path.dirname(os.path.dirname(os.readlink(lnk))) -else: - SOURCE_DIR = BUILD_DIR - - -def has_cmd(name, args=None): - """ - This function is for use in a @avocado.skipUnless decorator, e.g.: - - @skipUnless(*has_cmd('sudo -n', ('sudo', '-n', 'true'))) - def test_something_that_needs_sudo(self): - ... - """ - - if args is None: - args = ('which', name) - - try: - _, stderr, exitcode = run_cmd(args) - except Exception as e: - exitcode = -1 - stderr = str(e) - - if exitcode != 0: - cmd_line = ' '.join(args) - err = f'{name} required, but "{cmd_line}" failed: {stderr.strip()}' - return (False, err) - else: - return (True, '') - -def has_cmds(*cmds): - """ - This function is for use in a @avocado.skipUnless decorator and - allows checking for the availability of multiple commands, e.g.: - - @skipUnless(*has_cmds(('cmd1', ('cmd1', '--some-parameter')), - 'cmd2', 'cmd3')) - def test_something_that_needs_cmd1_and_cmd2(self): - ... - """ - - for cmd in cmds: - if isinstance(cmd, str): - cmd = (cmd,) - - ok, errstr = has_cmd(*cmd) - if not ok: - return (False, errstr) - - return (True, '') - -def run_cmd(args): - subp = subprocess.Popen(args, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - universal_newlines=True) - stdout, stderr = subp.communicate() - ret = subp.returncode - - return (stdout, stderr, ret) - -def is_readable_executable_file(path): - return os.path.isfile(path) and os.access(path, os.R_OK | os.X_OK) - - -def pick_default_qemu_bin(bin_prefix='qemu-system-', arch=None): - """ - Picks the path of a QEMU binary, starting either in the current working - directory or in the source tree root directory. - - :param arch: the arch to use when looking for a QEMU binary (the target - will match the arch given). If None (the default), arch - will be the current host system arch (as given by - :func:`os.uname`). - :type arch: str - :returns: the path to the default QEMU binary or None if one could not - be found - :rtype: str or None - """ - if arch is None: - arch = os.uname()[4] - # qemu binary path does not match arch for powerpc, handle it - if 'ppc64le' in arch: - arch = 'ppc64' - qemu_bin_name = bin_prefix + arch - qemu_bin_paths = [ - os.path.join(".", qemu_bin_name), - os.path.join(BUILD_DIR, qemu_bin_name), - os.path.join(BUILD_DIR, "build", qemu_bin_name), - ] - for path in qemu_bin_paths: - if is_readable_executable_file(path): - return path - return None - - -def _console_interaction(test, success_message, failure_message, - send_string, keep_sending=False, vm=None): - assert not keep_sending or send_string - if vm is None: - vm = test.vm - console = vm.console_file - 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 - try: - msg = console.readline().decode().strip() - except UnicodeDecodeError: - msg = None - if not msg: - continue - console_logger.debug(msg) - if success_message is None or success_message in msg: - break - if failure_message and failure_message in msg: - console.close() - fail = 'Failure message found in console: "%s". Expected: "%s"' % \ - (failure_message, success_message) - test.fail(fail) - -def interrupt_interactive_console_until_pattern(test, success_message, - failure_message=None, - interrupt_string='\r'): - """ - Keep sending a string to interrupt a console prompt, while logging the - console output. Typical use case is to break a boot loader prompt, such: - - Press a key within 5 seconds to interrupt boot process. - 5 - 4 - 3 - 2 - 1 - Booting default image... - - :param test: an Avocado test containing a VM that will have its console - read and probed for a success or failure message - :type test: :class:`avocado_qemu.QemuSystemTest` - :param success_message: if this message appears, test succeeds - :param failure_message: if this message appears, test fails - :param interrupt_string: a string to send to the console before trying - to read a new line - """ - _console_interaction(test, success_message, failure_message, - interrupt_string, True) - -def wait_for_console_pattern(test, success_message, failure_message=None, - vm=None): - """ - Waits for messages to appear on the console, while logging the content - - :param test: an Avocado test containing a VM that will have its console - read and probed for a success or failure message - :type test: :class:`avocado_qemu.QemuSystemTest` - :param success_message: if this message appears, test succeeds - :param failure_message: if this message appears, test fails - """ - _console_interaction(test, success_message, failure_message, None, vm=vm) - -def exec_command(test, command): - """ - Send a command to a console (appending CRLF characters), while logging - the content. - - :param test: an Avocado test containing a VM. - :type test: :class:`avocado_qemu.QemuSystemTest` - :param command: the command to send - :type command: str - """ - _console_interaction(test, None, None, command + '\r') - -def exec_command_and_wait_for_pattern(test, command, - success_message, failure_message=None): - """ - Send a command to a console (appending CRLF characters), then wait - for success_message to appear on the console, while logging the. - content. Mark the test as failed if failure_message is found instead. - - :param test: an Avocado test containing a VM that will have its console - read and probed for a success or failure message - :type test: :class:`avocado_qemu.QemuSystemTest` - :param command: the command to send - :param success_message: if this message appears, test succeeds - :param failure_message: if this message appears, test fails - """ - _console_interaction(test, success_message, failure_message, command + '\r') - -class QemuBaseTest(avocado.Test): - - # default timeout for all tests, can be overridden - timeout = 120 - - def _get_unique_tag_val(self, tag_name): - """ - Gets a tag value, if unique for a key - """ - vals = self.tags.get(tag_name, []) - if len(vals) == 1: - return vals.pop() - return None - - def setUp(self, bin_prefix): - 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')) - - default_qemu_bin = pick_default_qemu_bin(bin_prefix, arch=self.arch) - self.qemu_bin = self.params.get('qemu_bin', - default=default_qemu_bin) - if self.qemu_bin is None: - self.cancel("No QEMU binary defined or found in the build tree") - - def fetch_asset(self, name, - asset_hash, algorithm=None, - locations=None, expire=None, - find_only=False, cancel_on_missing=True): - return super().fetch_asset(name, - asset_hash=asset_hash, - algorithm=algorithm, - locations=locations, - expire=expire, - find_only=find_only, - cancel_on_missing=cancel_on_missing) - - -class QemuSystemTest(QemuBaseTest): - """Facilitates system emulation tests.""" - - def setUp(self): - self._vms = {} - - super().setUp('qemu-system-') - - accel_required = self._get_unique_tag_val('accel') - if accel_required: - self.require_accelerator(accel_required) - - self.machine = self.params.get('machine', - default=self._get_unique_tag_val('machine')) - - def require_accelerator(self, accelerator): - """ - Requires an accelerator to be available for the test to continue - - It takes into account the currently set qemu binary. - - If the check fails, the test is canceled. If the check itself - for the given accelerator is not available, the test is also - canceled. - - :param accelerator: name of the accelerator, such as "kvm" or "tcg" - :type accelerator: str - """ - checker = {'tcg': tcg_available, - 'kvm': kvm_available}.get(accelerator) - if checker is None: - self.cancel("Don't know how to check for the presence " - "of accelerator %s" % accelerator) - if not checker(qemu_bin=self.qemu_bin): - self.cancel("%s accelerator does not seem to be " - "available" % accelerator) - - def require_netdev(self, netdevname): - netdevhelp = run_cmd([self.qemu_bin, - '-M', 'none', '-netdev', 'help'])[0]; - if netdevhelp.find('\n' + netdevname + '\n') < 0: - self.cancel('no support for user networking') - - def require_multiprocess(self): - """ - Test for the presence of the x-pci-proxy-dev which is required - to support multiprocess. - """ - devhelp = run_cmd([self.qemu_bin, - '-M', 'none', '-device', 'help'])[0]; - if devhelp.find('x-pci-proxy-dev') < 0: - self.cancel('no support for multiprocess device emulation') - - def _new_vm(self, name, *args): - self._sd = tempfile.TemporaryDirectory(prefix="qemu_") - vm = QEMUMachine(self.qemu_bin, base_temp_dir=self.workdir, - 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 - - def get_qemu_img(self): - self.log.debug('Looking for and selecting a qemu-img binary') - - # If qemu-img has been built, use it, otherwise the system wide one - # will be used. - qemu_img = os.path.join(BUILD_DIR, 'qemu-img') - if not os.path.exists(qemu_img): - qemu_img = find_command('qemu-img', False) - if qemu_img is False: - self.cancel('Could not find "qemu-img"') - - return qemu_img - - @property - def vm(self): - return self.get_vm(name='default') - - def get_vm(self, *args, name=None): - if not name: - 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] - - 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() - self._sd = None - super().tearDown() - - -class QemuUserTest(QemuBaseTest): - """Facilitates user-mode emulation tests.""" - - def setUp(self): - self._ldpath = [] - super().setUp('qemu-') - - def add_ldpath(self, ldpath): - self._ldpath.append(os.path.abspath(ldpath)) - - def run(self, bin_path, args=[]): - qemu_args = " ".join(["-L %s" % ldpath for ldpath in self._ldpath]) - bin_args = " ".join(args) - return process.run("%s %s %s %s" % (self.qemu_bin, qemu_args, - bin_path, bin_args)) - - -class LinuxSSHMixIn: - """Contains utility methods for interacting with a guest via SSH.""" - - def ssh_connect(self, username, credential, credential_is_key=True): - self.ssh_logger = logging.getLogger('ssh') - res = self.vm.cmd('human-monitor-command', - command_line='info usernet') - port = get_info_usernet_hostfwd_port(res) - self.assertIsNotNone(port) - self.assertGreater(port, 0) - self.log.debug('sshd listening on port: %d', port) - if credential_is_key: - self.ssh_session = ssh.Session('127.0.0.1', port=port, - user=username, key=credential) - else: - self.ssh_session = ssh.Session('127.0.0.1', port=port, - user=username, password=credential) - for i in range(10): - try: - self.ssh_session.connect() - return - except: - time.sleep(i) - self.fail('ssh connection timeout') - - def ssh_command(self, command): - self.ssh_logger.info(command) - result = self.ssh_session.cmd(command) - stdout_lines = [line.rstrip() for line - in result.stdout_text.splitlines()] - for line in stdout_lines: - self.ssh_logger.info(line) - stderr_lines = [line.rstrip() for line - in result.stderr_text.splitlines()] - for line in stderr_lines: - self.ssh_logger.warning(line) - - self.assertEqual(result.exit_status, 0, - f'Guest command failed: {command}') - return stdout_lines, stderr_lines - - def ssh_command_output_contains(self, cmd, exp): - stdout, _ = self.ssh_command(cmd) - for line in stdout: - if exp in line: - break - else: - self.fail('"%s" output does not contain "%s"' % (cmd, exp)) - -class LinuxDistro: - """Represents a Linux distribution - - Holds information of known distros. - """ - #: A collection of known distros and their respective image checksum - KNOWN_DISTROS = { - 'fedora': { - '31': { - 'x86_64': - {'checksum': ('e3c1b309d9203604922d6e255c2c5d09' - '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'), - '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'), - }, - }, - } - } - - 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 {} - - @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 - - @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(LinuxSSHMixIn, QemuSystemTest): - """Facilitates having a cloud-image Linux based available. - - For tests that intend to interact with guests, this is a better choice - to start with than the more vanilla `QemuSystemTest` class. - """ - - distro = None - username = 'root' - password = 'password' - smp = '2' - memory = '1024' - - def _set_distro(self): - distro_name = self.params.get( - 'distro', - default=self._get_unique_tag_val('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 = 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 - # 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=None) - if distro_checksum: - self.distro.checksum = distro_checksum - - def setUp(self, ssh_pubkey=None, network_device_type='virtio-net'): - super().setUp() - self.require_netdev('user') - self._set_distro() - self.vm.add_args('-smp', self.smp) - self.vm.add_args('-m', self.memory) - # The following network device allows for SSH connections - self.vm.add_args('-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22', - '-device', '%s,netdev=vnet' % network_device_type) - self.set_up_boot() - if ssh_pubkey is None: - ssh_pubkey, self.ssh_key = self.set_up_existing_ssh_keys() - self.set_up_cloudinit(ssh_pubkey) - - def set_up_existing_ssh_keys(self): - ssh_public_key = os.path.join(SOURCE_DIR, 'tests', 'keys', 'id_rsa.pub') - source_private_key = os.path.join(SOURCE_DIR, 'tests', 'keys', 'id_rsa') - ssh_dir = os.path.join(self.workdir, '.ssh') - os.mkdir(ssh_dir, mode=0o700) - ssh_private_key = os.path.join(ssh_dir, - os.path.basename(source_private_key)) - shutil.copyfile(source_private_key, ssh_private_key) - os.chmod(ssh_private_key, 0o600) - return (ssh_public_key, ssh_private_key) - - def download_boot(self): - # Set the qemu-img binary. - # If none is available, the test will cancel. - vmimage.QEMU_IMG = super().get_qemu_img() - - self.log.info('Downloading/preparing boot image') - # Fedora 31 only provides ppc64le images - image_arch = self.arch - if self.distro.name == 'fedora': - if image_arch == 'ppc64': - image_arch = 'ppc64le' - - try: - boot = vmimage.get( - 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) - except: - self.cancel('Failed to download/prepare boot image') - return boot.path - - def prepare_cloudinit(self, ssh_pubkey=None): - self.log.info('Preparing cloudinit image') - try: - cloudinit_iso = os.path.join(self.workdir, 'cloudinit.iso') - pubkey_content = None - if ssh_pubkey: - with open(ssh_pubkey) as pubkey: - pubkey_content = pubkey.read() - cloudinit.iso(cloudinit_iso, self.name, - username=self.username, - password=self.password, - # QEMU's hard coded usermode router address - phone_home_host='10.0.2.2', - phone_home_port=self.phone_server.server_port, - authorized_key=pubkey_content) - except Exception: - self.cancel('Failed to prepare the cloudinit image') - return cloudinit_iso - - def set_up_boot(self): - path = self.download_boot() - self.vm.add_args('-drive', 'file=%s' % path) - - def set_up_cloudinit(self, ssh_pubkey=None): - self.phone_server = cloudinit.PhoneHomeServer(('0.0.0.0', 0), - self.name) - cloudinit_iso = self.prepare_cloudinit(ssh_pubkey) - self.vm.add_args('-drive', 'file=%s,format=raw' % cloudinit_iso) - - def launch_and_wait(self, set_up_ssh_connection=True): - self.vm.set_console() - self.vm.launch() - console_drainer = datadrainer.LineLogger(self.vm.console_socket.fileno(), - logger=self.log.getChild('console')) - console_drainer.start() - self.log.info('VM launched, waiting for boot confirmation from guest') - while not self.phone_server.instance_phoned_back: - self.phone_server.handle_request() - - if set_up_ssh_connection: - self.log.info('Setting up the SSH connection') - self.ssh_connect(self.username, self.ssh_key) diff --git a/tests/avocado/boot_linux.py b/tests/avocado/boot_linux.py deleted file mode 100644 index cdce4cb..0000000 --- a/tests/avocado/boot_linux.py +++ /dev/null @@ -1,131 +0,0 @@ -# Functional test that boots a complete Linux system via a cloud image -# -# Copyright (c) 2018-2020 Red Hat, Inc. -# -# Author: -# Cleber Rosa <crosa@redhat.com> -# -# 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_qemu import LinuxTest, BUILD_DIR - -from avocado import skipUnless - - -class BootLinuxX8664(LinuxTest): - """ - :avocado: tags=arch:x86_64 - """ - timeout = 480 - - def test_pc_i440fx_tcg(self): - """ - :avocado: tags=machine:pc - :avocado: tags=accel:tcg - """ - self.require_accelerator("tcg") - self.vm.add_args("-accel", "tcg") - self.launch_and_wait(set_up_ssh_connection=False) - - def test_pc_i440fx_kvm(self): - """ - :avocado: tags=machine:pc - :avocado: tags=accel:kvm - """ - self.require_accelerator("kvm") - self.vm.add_args("-accel", "kvm") - self.launch_and_wait(set_up_ssh_connection=False) - - def test_pc_q35_tcg(self): - """ - :avocado: tags=machine:q35 - :avocado: tags=accel:tcg - """ - self.require_accelerator("tcg") - self.vm.add_args("-accel", "tcg") - self.launch_and_wait(set_up_ssh_connection=False) - - def test_pc_q35_kvm(self): - """ - :avocado: tags=machine:q35 - :avocado: tags=accel:kvm - """ - self.require_accelerator("kvm") - self.vm.add_args("-accel", "kvm") - self.launch_and_wait(set_up_ssh_connection=False) - - -# For Aarch64 we only boot KVM tests in CI as booting the current -# Fedora OS in TCG tests is very heavyweight. There are lighter weight -# distros which we use in the machine_aarch64_virt.py tests. -class BootLinuxAarch64(LinuxTest): - """ - :avocado: tags=arch:aarch64 - :avocado: tags=machine:virt - """ - timeout = 720 - - def test_virt_kvm(self): - """ - :avocado: tags=accel:kvm - :avocado: tags=cpu:host - """ - self.require_accelerator("kvm") - self.vm.add_args("-accel", "kvm") - self.vm.add_args("-machine", "virt,gic-version=host") - 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') - self.launch_and_wait(set_up_ssh_connection=False) - - -# See the tux_baseline.py tests for almost the same coverage in a lot -# less time. -class BootLinuxPPC64(LinuxTest): - """ - :avocado: tags=arch:ppc64 - """ - - timeout = 360 - - @skipUnless(os.getenv('SPEED') == 'slow', 'runtime limited') - def test_pseries_tcg(self): - """ - :avocado: tags=machine:pseries - :avocado: tags=accel:tcg - """ - self.require_accelerator("tcg") - self.vm.add_args("-accel", "tcg") - self.launch_and_wait(set_up_ssh_connection=False) - - def test_pseries_kvm(self): - """ - :avocado: tags=machine:pseries - :avocado: tags=accel:kvm - """ - self.require_accelerator("kvm") - self.vm.add_args("-accel", "kvm") - self.vm.add_args("-machine", "cap-ccf-assist=off") - self.launch_and_wait(set_up_ssh_connection=False) - -class BootLinuxS390X(LinuxTest): - """ - :avocado: tags=arch:s390x - """ - - timeout = 240 - - @skipUnless(os.getenv('SPEED') == 'slow', 'runtime limited') - def test_s390_ccw_virtio_tcg(self): - """ - :avocado: tags=machine:s390-ccw-virtio - :avocado: tags=accel:tcg - """ - self.require_accelerator("tcg") - self.vm.add_args("-accel", "tcg") - self.launch_and_wait(set_up_ssh_connection=False) diff --git a/tests/avocado/boot_linux_console.py b/tests/avocado/boot_linux_console.py deleted file mode 100644 index c35fc5e..0000000 --- a/tests/avocado/boot_linux_console.py +++ /dev/null @@ -1,1547 +0,0 @@ -# Functional test that boots a Linux kernel and checks the console -# -# Copyright (c) 2018 Red Hat, Inc. -# -# Author: -# Cleber Rosa <crosa@redhat.com> -# -# 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 -import lzma -import gzip -import shutil - -from avocado import skip -from avocado import skipUnless -from avocado import skipUnless -from avocado_qemu import QemuSystemTest -from avocado_qemu import exec_command -from avocado_qemu import exec_command_and_wait_for_pattern -from avocado_qemu import interrupt_interactive_console_until_pattern -from avocado_qemu import wait_for_console_pattern -from avocado.utils import process -from avocado.utils import archive - -""" -Round up to next power of 2 -""" -def pow2ceil(x): - return 1 if x == 0 else 2**(x - 1).bit_length() - -def file_truncate(path, size): - if size != os.path.getsize(path): - with open(path, 'ab+') as fd: - fd.truncate(size) - -""" -Expand file size to next power of 2 -""" -def image_pow2ceil_expand(path): - size = os.path.getsize(path) - size_aligned = pow2ceil(size) - if size != size_aligned: - with open(path, 'ab+') as fd: - fd.truncate(size_aligned) - -class LinuxKernelTest(QemuSystemTest): - KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 ' - - def wait_for_console_pattern(self, success_message, vm=None): - wait_for_console_pattern(self, success_message, - failure_message='Kernel panic - not syncing', - vm=vm) - - def extract_from_deb(self, deb, path): - """ - Extracts a file from a deb package into the test workdir - - :param deb: path to the deb archive - :param path: path within the deb archive of the file to be extracted - :returns: path of the extracted file - """ - cwd = os.getcwd() - os.chdir(self.workdir) - file_path = process.run("ar t %s" % deb).stdout_text.split()[2] - process.run("ar x %s %s" % (deb, file_path)) - archive.extract(file_path, self.workdir) - os.chdir(cwd) - # Return complete path to extracted file. Because callers to - # extract_from_deb() specify 'path' with a leading slash, it is - # necessary to use os.path.relpath() as otherwise os.path.join() - # interprets it as an absolute path and drops the self.workdir part. - return os.path.normpath(os.path.join(self.workdir, - os.path.relpath(path, '/'))) - - def extract_from_rpm(self, rpm, path): - """ - Extracts a file from an RPM package into the test workdir. - - :param rpm: path to the rpm archive - :param path: path within the rpm archive of the file to be extracted - needs to be a relative path (starting with './') because - cpio(1), which is used to extract the file, expects that. - :returns: path of the extracted file - """ - cwd = os.getcwd() - os.chdir(self.workdir) - process.run("rpm2cpio %s | cpio -id %s" % (rpm, path), shell=True) - os.chdir(cwd) - return os.path.normpath(os.path.join(self.workdir, path)) - -class BootLinuxConsole(LinuxKernelTest): - """ - Boots a Linux kernel and checks that the console is operational and the - kernel command line is properly passed from QEMU to the kernel - """ - timeout = 90 - - def test_x86_64_pc(self): - """ - :avocado: tags=arch:x86_64 - :avocado: tags=machine:pc - """ - kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora' - '/linux/releases/29/Everything/x86_64/os/images/pxeboot' - '/vmlinuz') - kernel_hash = '23bebd2680757891cf7adedb033532163a792495' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - - self.vm.set_console() - kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0' - self.vm.add_args('-kernel', kernel_path, - '-append', kernel_command_line) - self.vm.launch() - console_pattern = 'Kernel command line: %s' % kernel_command_line - self.wait_for_console_pattern(console_pattern) - - def test_mips_malta(self): - """ - :avocado: tags=arch:mips - :avocado: tags=machine:malta - :avocado: tags=endian:big - """ - deb_url = ('http://snapshot.debian.org/archive/debian/' - '20130217T032700Z/pool/main/l/linux-2.6/' - 'linux-image-2.6.32-5-4kc-malta_2.6.32-48_mips.deb') - deb_hash = 'a8cfc28ad8f45f54811fc6cf74fc43ffcfe0ba04' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) - kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinux-2.6.32-5-4kc-malta') - - self.vm.set_console() - kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0' - self.vm.add_args('-kernel', kernel_path, - '-append', kernel_command_line) - self.vm.launch() - console_pattern = 'Kernel command line: %s' % kernel_command_line - self.wait_for_console_pattern(console_pattern) - - def test_mips64el_malta(self): - """ - This test requires the ar tool to extract "data.tar.gz" from - the Debian package. - - The kernel can be rebuilt using this Debian kernel source [1] and - following the instructions on [2]. - - [1] http://snapshot.debian.org/package/linux-2.6/2.6.32-48/ - #linux-source-2.6.32_2.6.32-48 - [2] https://kernel-team.pages.debian.net/kernel-handbook/ - ch-common-tasks.html#s-common-official - - :avocado: tags=arch:mips64el - :avocado: tags=machine:malta - """ - deb_url = ('http://snapshot.debian.org/archive/debian/' - '20130217T032700Z/pool/main/l/linux-2.6/' - 'linux-image-2.6.32-5-5kc-malta_2.6.32-48_mipsel.deb') - deb_hash = '1aaec92083bf22fda31e0d27fa8d9a388e5fc3d5' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) - kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinux-2.6.32-5-5kc-malta') - - self.vm.set_console() - kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0' - self.vm.add_args('-kernel', kernel_path, - '-append', kernel_command_line) - self.vm.launch() - console_pattern = 'Kernel command line: %s' % kernel_command_line - self.wait_for_console_pattern(console_pattern) - - def test_mips64el_fuloong2e(self): - """ - :avocado: tags=arch:mips64el - :avocado: tags=machine:fuloong2e - :avocado: tags=endian:little - """ - deb_url = ('http://archive.debian.org/debian/pool/main/l/linux/' - 'linux-image-3.16.0-6-loongson-2e_3.16.56-1+deb8u1_mipsel.deb') - deb_hash = 'd04d446045deecf7b755ef576551de0c4184dd44' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) - kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinux-3.16.0-6-loongson-2e') - - self.vm.set_console() - kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0' - self.vm.add_args('-kernel', kernel_path, - '-append', kernel_command_line) - self.vm.launch() - console_pattern = 'Kernel command line: %s' % kernel_command_line - self.wait_for_console_pattern(console_pattern) - - def test_mips_malta_cpio(self): - """ - :avocado: tags=arch:mips - :avocado: tags=machine:malta - :avocado: tags=endian:big - """ - deb_url = ('http://snapshot.debian.org/archive/debian/' - '20160601T041800Z/pool/main/l/linux/' - 'linux-image-4.5.0-2-4kc-malta_4.5.5-1_mips.deb') - deb_hash = 'a3c84f3e88b54e06107d65a410d1d1e8e0f340f8' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) - kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinux-4.5.0-2-4kc-malta') - initrd_url = ('https://github.com/groeck/linux-build-test/raw/' - '8584a59ed9e5eb5ee7ca91f6d74bbb06619205b8/rootfs/' - 'mips/rootfs.cpio.gz') - initrd_hash = 'bf806e17009360a866bf537f6de66590de349a99' - initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash) - initrd_path = self.workdir + "rootfs.cpio" - archive.gzip_uncompress(initrd_path_gz, initrd_path) - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE - + 'console=ttyS0 console=tty ' - + 'rdinit=/sbin/init noreboot') - self.vm.add_args('-kernel', kernel_path, - '-initrd', initrd_path, - '-append', kernel_command_line, - '-no-reboot') - self.vm.launch() - self.wait_for_console_pattern('Boot successful.') - - exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo', - 'BogoMIPS') - exec_command_and_wait_for_pattern(self, 'uname -a', - 'Debian') - exec_command_and_wait_for_pattern(self, 'reboot', - 'reboot: Restarting system') - # Wait for VM to shut down gracefully - self.vm.wait() - - @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code') - def test_mips64el_malta_5KEc_cpio(self): - """ - :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/' - 'vmlinux-3.19.3.mtoman.20150408') - kernel_hash = '00d1d268fb9f7d8beda1de6bebcc46e884d71754' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - initrd_url = ('https://github.com/groeck/linux-build-test/' - 'raw/8584a59e/rootfs/' - 'mipsel64/rootfs.mipsel64r1.cpio.gz') - initrd_hash = '1dbb8a396e916847325284dbe2151167' - initrd_path_gz = self.fetch_asset(initrd_url, algorithm='md5', - asset_hash=initrd_hash) - initrd_path = self.workdir + "rootfs.cpio" - archive.gzip_uncompress(initrd_path_gz, initrd_path) - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE - + 'console=ttyS0 console=tty ' - + 'rdinit=/sbin/init noreboot') - self.vm.add_args('-kernel', kernel_path, - '-initrd', initrd_path, - '-append', kernel_command_line, - '-no-reboot') - self.vm.launch() - wait_for_console_pattern(self, 'Boot successful.') - - exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo', - 'MIPS 5KE') - exec_command_and_wait_for_pattern(self, 'uname -a', - '3.19.3.mtoman.20150408') - exec_command_and_wait_for_pattern(self, 'reboot', - 'reboot: Restarting system') - # Wait for VM to shut down gracefully - self.vm.wait() - - def do_test_mips_malta32el_nanomips(self, kernel_url, kernel_hash): - kernel_path_xz = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - kernel_path = self.workdir + "kernel" - with lzma.open(kernel_path_xz, 'rb') as f_in: - with open(kernel_path, 'wb') as f_out: - shutil.copyfileobj(f_in, f_out) - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE - + 'mem=256m@@0x0 ' - + 'console=ttyS0') - self.vm.add_args('-no-reboot', - '-kernel', kernel_path, - '-append', kernel_command_line) - self.vm.launch() - console_pattern = 'Kernel command line: %s' % kernel_command_line - self.wait_for_console_pattern(console_pattern) - - 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/' - 'generic_nano32r6el_page4k.xz') - kernel_hash = '477456aafd2a0f1ddc9482727f20fe9575565dd6' - self.do_test_mips_malta32el_nanomips(kernel_url, kernel_hash) - - def test_mips_malta32el_nanomips_16k_up(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/' - 'generic_nano32r6el_page16k_up.xz') - kernel_hash = 'e882868f944c71c816e832e2303b7874d044a7bc' - self.do_test_mips_malta32el_nanomips(kernel_url, kernel_hash) - - def test_mips_malta32el_nanomips_64k_dbg(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/' - 'generic_nano32r6el_page64k_dbg.xz') - kernel_hash = '18d1c68f2e23429e266ca39ba5349ccd0aeb7180' - self.do_test_mips_malta32el_nanomips(kernel_url, kernel_hash) - - def test_aarch64_xlnx_versal_virt(self): - """ - :avocado: tags=arch:aarch64 - :avocado: tags=machine:xlnx-versal-virt - :avocado: tags=device:pl011 - :avocado: tags=device:arm_gicv3 - :avocado: tags=accel:tcg - """ - images_url = ('http://ports.ubuntu.com/ubuntu-ports/dists/' - 'bionic-updates/main/installer-arm64/' - '20101020ubuntu543.19/images/') - kernel_url = images_url + 'netboot/ubuntu-installer/arm64/linux' - kernel_hash = 'e167757620640eb26de0972f578741924abb3a82' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - - initrd_url = images_url + 'netboot/ubuntu-installer/arm64/initrd.gz' - initrd_hash = 'cab5cb3fcefca8408aa5aae57f24574bfce8bdb9' - initrd_path = self.fetch_asset(initrd_url, asset_hash=initrd_hash) - - self.vm.set_console() - self.vm.add_args('-m', '2G', - '-accel', 'tcg', - '-kernel', kernel_path, - '-initrd', initrd_path) - self.vm.launch() - self.wait_for_console_pattern('Checked W+X mappings: passed') - - def test_arm_virt(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:virt - :avocado: tags=accel:tcg - """ - kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora' - '/linux/releases/29/Everything/armhfp/os/images/pxeboot' - '/vmlinuz') - kernel_hash = 'e9826d741b4fb04cadba8d4824d1ed3b7fb8b4d4' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=ttyAMA0') - self.vm.add_args('-kernel', kernel_path, - '-append', kernel_command_line) - self.vm.launch() - console_pattern = 'Kernel command line: %s' % kernel_command_line - self.wait_for_console_pattern(console_pattern) - - def test_arm_emcraft_sf2(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:emcraft-sf2 - :avocado: tags=endian:little - :avocado: tags=u-boot - :avocado: tags=accel:tcg - """ - self.require_netdev('user') - - uboot_url = ('https://raw.githubusercontent.com/' - 'Subbaraya-Sundeep/qemu-test-binaries/' - 'fe371d32e50ca682391e1e70ab98c2942aeffb01/u-boot') - uboot_hash = 'cbb8cbab970f594bf6523b9855be209c08374ae2' - uboot_path = self.fetch_asset(uboot_url, asset_hash=uboot_hash) - spi_url = ('https://raw.githubusercontent.com/' - 'Subbaraya-Sundeep/qemu-test-binaries/' - 'fe371d32e50ca682391e1e70ab98c2942aeffb01/spi.bin') - spi_hash = '65523a1835949b6f4553be96dec1b6a38fb05501' - spi_path = self.fetch_asset(spi_url, asset_hash=spi_hash) - - file_truncate(spi_path, 16 << 20) # Spansion S25FL128SDPBHICO is 16 MiB - - self.vm.set_console() - kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE - self.vm.add_args('-kernel', uboot_path, - '-append', kernel_command_line, - '-drive', 'file=' + spi_path + ',if=mtd,format=raw', - '-no-reboot') - self.vm.launch() - self.wait_for_console_pattern('Enter \'help\' for a list') - - exec_command_and_wait_for_pattern(self, 'ifconfig eth0 10.0.2.15', - 'eth0: link becomes ready') - exec_command_and_wait_for_pattern(self, 'ping -c 3 10.0.2.2', - '3 packets transmitted, 3 packets received, 0% packet loss') - - def do_test_arm_raspi2(self, uart_id): - """ - :avocado: tags=accel:tcg - - The kernel can be rebuilt using the kernel source referenced - and following the instructions on the on: - https://www.raspberrypi.org/documentation/linux/kernel/building.md - """ - serial_kernel_cmdline = { - 0: 'earlycon=pl011,0x3f201000 console=ttyAMA0', - } - deb_url = ('http://archive.raspberrypi.org/debian/' - 'pool/main/r/raspberrypi-firmware/' - 'raspberrypi-kernel_1.20190215-1_armhf.deb') - deb_hash = 'cd284220b32128c5084037553db3c482426f3972' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) - kernel_path = self.extract_from_deb(deb_path, '/boot/kernel7.img') - dtb_path = self.extract_from_deb(deb_path, '/boot/bcm2709-rpi-2-b.dtb') - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - serial_kernel_cmdline[uart_id] + - ' root=/dev/mmcblk0p2 rootwait ' + - 'dwc_otg.fiq_fsm_enable=0') - self.vm.add_args('-kernel', kernel_path, - '-dtb', dtb_path, - '-append', kernel_command_line, - '-device', 'usb-kbd') - self.vm.launch() - console_pattern = 'Kernel command line: %s' % kernel_command_line - self.wait_for_console_pattern(console_pattern) - console_pattern = 'Product: QEMU USB Keyboard' - self.wait_for_console_pattern(console_pattern) - - def test_arm_raspi2_uart0(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:raspi2b - :avocado: tags=device:pl011 - :avocado: tags=accel:tcg - """ - self.do_test_arm_raspi2(0) - - def test_arm_raspi2_initrd(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:raspi2b - """ - deb_url = ('http://archive.raspberrypi.org/debian/' - 'pool/main/r/raspberrypi-firmware/' - 'raspberrypi-kernel_1.20190215-1_armhf.deb') - deb_hash = 'cd284220b32128c5084037553db3c482426f3972' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) - kernel_path = self.extract_from_deb(deb_path, '/boot/kernel7.img') - dtb_path = self.extract_from_deb(deb_path, '/boot/bcm2709-rpi-2-b.dtb') - - initrd_url = ('https://github.com/groeck/linux-build-test/raw/' - '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/' - 'arm/rootfs-armv7a.cpio.gz') - initrd_hash = '604b2e45cdf35045846b8bbfbf2129b1891bdc9c' - initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash) - initrd_path = os.path.join(self.workdir, 'rootfs.cpio') - archive.gzip_uncompress(initrd_path_gz, initrd_path) - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'earlycon=pl011,0x3f201000 console=ttyAMA0 ' - 'panic=-1 noreboot ' + - 'dwc_otg.fiq_fsm_enable=0') - self.vm.add_args('-kernel', kernel_path, - '-dtb', dtb_path, - '-initrd', initrd_path, - '-append', kernel_command_line, - '-no-reboot') - self.vm.launch() - self.wait_for_console_pattern('Boot successful.') - - exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo', - 'BCM2835') - exec_command_and_wait_for_pattern(self, 'cat /proc/iomem', - '/soc/cprman@7e101000') - exec_command_and_wait_for_pattern(self, 'halt', 'reboot: System halted') - # Wait for VM to shut down gracefully - self.vm.wait() - - def test_arm_raspi4(self): - """ - :avocado: tags=arch:aarch64 - :avocado: tags=machine:raspi4b - :avocado: tags=device:pl011 - :avocado: tags=accel:tcg - :avocado: tags=rpi4b - - The kernel can be rebuilt using the kernel source referenced - and following the instructions on the on: - https://www.raspberrypi.org/documentation/linux/kernel/building.md - """ - - deb_url = ('http://archive.raspberrypi.org/debian/' - 'pool/main/r/raspberrypi-firmware/' - 'raspberrypi-kernel_1.20230106-1_arm64.deb') - deb_hash = '08dc55696535b18a6d4fe6fa10d4c0d905cbb2ed' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) - kernel_path = self.extract_from_deb(deb_path, '/boot/kernel8.img') - dtb_path = self.extract_from_deb(deb_path, '/boot/bcm2711-rpi-4-b.dtb') - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'earlycon=pl011,mmio32,0xfe201000 ' + - 'console=ttyAMA0,115200 ' + - 'root=/dev/mmcblk1p2 rootwait ' + - 'dwc_otg.fiq_fsm_enable=0') - self.vm.add_args('-kernel', kernel_path, - '-dtb', dtb_path, - '-append', kernel_command_line) - # When PCI is supported we can add a USB controller: - # '-device', 'qemu-xhci,bus=pcie.1,id=xhci', - # '-device', 'usb-kbd,bus=xhci.0', - self.vm.launch() - console_pattern = 'Kernel command line: %s' % kernel_command_line - self.wait_for_console_pattern(console_pattern) - # When USB is enabled we can look for this - # console_pattern = 'Product: QEMU USB Keyboard' - # self.wait_for_console_pattern(console_pattern) - console_pattern = 'Waiting for root device' - self.wait_for_console_pattern(console_pattern) - - - def test_arm_raspi4_initrd(self): - """ - :avocado: tags=arch:aarch64 - :avocado: tags=machine:raspi4b - :avocado: tags=device:pl011 - :avocado: tags=accel:tcg - :avocado: tags=rpi4b - - The kernel can be rebuilt using the kernel source referenced - and following the instructions on the on: - https://www.raspberrypi.org/documentation/linux/kernel/building.md - """ - deb_url = ('http://archive.raspberrypi.org/debian/' - 'pool/main/r/raspberrypi-firmware/' - 'raspberrypi-kernel_1.20230106-1_arm64.deb') - deb_hash = '08dc55696535b18a6d4fe6fa10d4c0d905cbb2ed' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) - kernel_path = self.extract_from_deb(deb_path, '/boot/kernel8.img') - dtb_path = self.extract_from_deb(deb_path, '/boot/bcm2711-rpi-4-b.dtb') - - initrd_url = ('https://github.com/groeck/linux-build-test/raw/' - '86b2be1384d41c8c388e63078a847f1e1c4cb1de/rootfs/' - 'arm64/rootfs.cpio.gz') - initrd_hash = 'f3d4f9fa92a49aa542f1b44d34be77bbf8ca5b9d' - initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash) - initrd_path = os.path.join(self.workdir, 'rootfs.cpio') - archive.gzip_uncompress(initrd_path_gz, initrd_path) - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'earlycon=pl011,mmio32,0xfe201000 ' + - 'console=ttyAMA0,115200 ' + - 'panic=-1 noreboot ' + - 'dwc_otg.fiq_fsm_enable=0') - self.vm.add_args('-kernel', kernel_path, - '-dtb', dtb_path, - '-initrd', initrd_path, - '-append', kernel_command_line, - '-no-reboot') - # When PCI is supported we can add a USB controller: - # '-device', 'qemu-xhci,bus=pcie.1,id=xhci', - # '-device', 'usb-kbd,bus=xhci.0', - self.vm.launch() - self.wait_for_console_pattern('Boot successful.') - - exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo', - 'BCM2835') - exec_command_and_wait_for_pattern(self, 'cat /proc/iomem', - 'cprman@7e101000') - exec_command_and_wait_for_pattern(self, 'halt', 'reboot: System halted') - # TODO: Raspberry Pi4 doesn't shut down properly with recent kernels - # Wait for VM to shut down gracefully - #self.vm.wait() - - def test_arm_exynos4210_initrd(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:smdkc210 - :avocado: tags=accel:tcg - """ - deb_url = ('https://snapshot.debian.org/archive/debian/' - '20190928T224601Z/pool/main/l/linux/' - 'linux-image-4.19.0-6-armmp_4.19.67-2+deb10u1_armhf.deb') - deb_hash = 'fa9df4a0d38936cb50084838f2cb933f570d7d82' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) - kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinuz-4.19.0-6-armmp') - dtb_path = '/usr/lib/linux-image-4.19.0-6-armmp/exynos4210-smdkv310.dtb' - dtb_path = self.extract_from_deb(deb_path, dtb_path) - - initrd_url = ('https://github.com/groeck/linux-build-test/raw/' - '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/' - 'arm/rootfs-armv5.cpio.gz') - initrd_hash = '2b50f1873e113523967806f4da2afe385462ff9b' - initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash) - initrd_path = os.path.join(self.workdir, 'rootfs.cpio') - archive.gzip_uncompress(initrd_path_gz, initrd_path) - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'earlycon=exynos4210,0x13800000 earlyprintk ' + - 'console=ttySAC0,115200n8 ' + - 'random.trust_cpu=off cryptomgr.notests ' + - 'cpuidle.off=1 panic=-1 noreboot') - - self.vm.add_args('-kernel', kernel_path, - '-dtb', dtb_path, - '-initrd', initrd_path, - '-append', kernel_command_line, - '-no-reboot') - self.vm.launch() - - self.wait_for_console_pattern('Boot successful.') - # TODO user command, for now the uart is stuck - - def test_arm_cubieboard_initrd(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:cubieboard - :avocado: tags=accel:tcg - """ - deb_url = ('https://apt.armbian.com/pool/main/l/' - 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb') - deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) - kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinuz-6.6.16-current-sunxi') - dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun4i-a10-cubieboard.dtb' - dtb_path = self.extract_from_deb(deb_path, dtb_path) - initrd_url = ('https://github.com/groeck/linux-build-test/raw/' - '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/' - 'arm/rootfs-armv5.cpio.gz') - initrd_hash = '2b50f1873e113523967806f4da2afe385462ff9b' - initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash) - initrd_path = os.path.join(self.workdir, 'rootfs.cpio') - archive.gzip_uncompress(initrd_path_gz, initrd_path) - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=ttyS0,115200 ' - 'usbcore.nousb ' - 'panic=-1 noreboot') - self.vm.add_args('-kernel', kernel_path, - '-dtb', dtb_path, - '-initrd', initrd_path, - '-append', kernel_command_line, - '-no-reboot') - self.vm.launch() - self.wait_for_console_pattern('Boot successful.') - - exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo', - 'Allwinner sun4i/sun5i') - exec_command_and_wait_for_pattern(self, 'cat /proc/iomem', - 'system-control@1c00000') - exec_command_and_wait_for_pattern(self, 'reboot', - 'reboot: Restarting system') - # Wait for VM to shut down gracefully - self.vm.wait() - - def test_arm_cubieboard_sata(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:cubieboard - :avocado: tags=accel:tcg - """ - deb_url = ('https://apt.armbian.com/pool/main/l/' - 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb') - deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) - kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinuz-6.6.16-current-sunxi') - dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun4i-a10-cubieboard.dtb' - dtb_path = self.extract_from_deb(deb_path, dtb_path) - rootfs_url = ('https://github.com/groeck/linux-build-test/raw/' - '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/' - 'arm/rootfs-armv5.ext2.gz') - rootfs_hash = '093e89d2b4d982234bf528bc9fb2f2f17a9d1f93' - rootfs_path_gz = self.fetch_asset(rootfs_url, asset_hash=rootfs_hash) - rootfs_path = os.path.join(self.workdir, 'rootfs.cpio') - archive.gzip_uncompress(rootfs_path_gz, rootfs_path) - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=ttyS0,115200 ' - 'usbcore.nousb ' - 'root=/dev/sda ro ' - 'panic=-1 noreboot') - self.vm.add_args('-kernel', kernel_path, - '-dtb', dtb_path, - '-drive', 'if=none,format=raw,id=disk0,file=' - + rootfs_path, - '-device', 'ide-hd,bus=ide.0,drive=disk0', - '-append', kernel_command_line, - '-no-reboot') - self.vm.launch() - self.wait_for_console_pattern('Boot successful.') - - exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo', - 'Allwinner sun4i/sun5i') - exec_command_and_wait_for_pattern(self, 'cat /proc/partitions', - 'sda') - exec_command_and_wait_for_pattern(self, 'reboot', - 'reboot: Restarting system') - # Wait for VM to shut down gracefully - self.vm.wait() - - @skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited') - def test_arm_cubieboard_openwrt_22_03_2(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:cubieboard - :avocado: tags=device:sd - """ - - # This test download a 7.5 MiB compressed image and expand it - # to 126 MiB. - image_url = ('https://downloads.openwrt.org/releases/22.03.2/targets/' - 'sunxi/cortexa8/openwrt-22.03.2-sunxi-cortexa8-' - 'cubietech_a10-cubieboard-ext4-sdcard.img.gz') - image_hash = ('94b5ecbfbc0b3b56276e5146b899eafa' - '2ac5dc2d08733d6705af9f144f39f554') - image_path_gz = self.fetch_asset(image_url, asset_hash=image_hash, - algorithm='sha256') - image_path = archive.extract(image_path_gz, self.workdir) - image_pow2ceil_expand(image_path) - - self.vm.set_console() - self.vm.add_args('-drive', 'file=' + image_path + ',if=sd,format=raw', - '-nic', 'user', - '-no-reboot') - self.vm.launch() - - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'usbcore.nousb ' - 'noreboot') - - self.wait_for_console_pattern('U-Boot SPL') - - interrupt_interactive_console_until_pattern( - self, 'Hit any key to stop autoboot:', '=>') - exec_command_and_wait_for_pattern(self, "setenv extraargs '" + - kernel_command_line + "'", '=>') - exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...'); - - self.wait_for_console_pattern( - 'Please press Enter to activate this console.') - - exec_command_and_wait_for_pattern(self, ' ', 'root@') - - exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo', - 'Allwinner sun4i/sun5i') - exec_command_and_wait_for_pattern(self, 'reboot', - 'reboot: Restarting system') - # Wait for VM to shut down gracefully - self.vm.wait() - - @skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout') - def test_arm_quanta_gsj(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:quanta-gsj - :avocado: tags=accel:tcg - """ - # 25 MiB compressed, 32 MiB uncompressed. - image_url = ( - 'https://github.com/hskinnemoen/openbmc/releases/download/' - '20200711-gsj-qemu-0/obmc-phosphor-image-gsj.static.mtd.gz') - image_hash = '14895e634923345cb5c8776037ff7876df96f6b1' - image_path_gz = self.fetch_asset(image_url, asset_hash=image_hash) - image_name = 'obmc.mtd' - image_path = os.path.join(self.workdir, image_name) - archive.gzip_uncompress(image_path_gz, image_path) - - self.vm.set_console() - drive_args = 'file=' + image_path + ',if=mtd,bus=0,unit=0' - self.vm.add_args('-drive', drive_args) - self.vm.launch() - - # Disable drivers and services that stall for a long time during boot, - # to avoid running past the 90-second timeout. These may be removed - # as the corresponding device support is added. - kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + ( - 'console=${console} ' - 'mem=${mem} ' - 'initcall_blacklist=npcm_i2c_bus_driver_init ' - 'systemd.mask=systemd-random-seed.service ' - 'systemd.mask=dropbearkey.service ' - ) - - self.wait_for_console_pattern('> BootBlock by Nuvoton') - self.wait_for_console_pattern('>Device: Poleg BMC NPCM730') - self.wait_for_console_pattern('>Skip DDR init.') - self.wait_for_console_pattern('U-Boot ') - interrupt_interactive_console_until_pattern( - self, 'Hit any key to stop autoboot:', 'U-Boot>') - exec_command_and_wait_for_pattern( - self, "setenv bootargs ${bootargs} " + kernel_command_line, - 'U-Boot>') - exec_command_and_wait_for_pattern( - self, 'run romboot', 'Booting Kernel from flash') - self.wait_for_console_pattern('Booting Linux on physical CPU 0x0') - self.wait_for_console_pattern('CPU1: thread -1, cpu 1, socket 0') - self.wait_for_console_pattern('OpenBMC Project Reference Distro') - self.wait_for_console_pattern('gsj login:') - - def test_arm_quanta_gsj_initrd(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:quanta-gsj - :avocado: tags=accel:tcg - """ - initrd_url = ( - 'https://github.com/hskinnemoen/openbmc/releases/download/' - '20200711-gsj-qemu-0/obmc-phosphor-initramfs-gsj.cpio.xz') - initrd_hash = '98fefe5d7e56727b1eb17d5c00311b1b5c945300' - initrd_path = self.fetch_asset(initrd_url, asset_hash=initrd_hash) - kernel_url = ( - 'https://github.com/hskinnemoen/openbmc/releases/download/' - '20200711-gsj-qemu-0/uImage-gsj.bin') - kernel_hash = 'fa67b2f141d56d39b3c54305c0e8a899c99eb2c7' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - dtb_url = ( - 'https://github.com/hskinnemoen/openbmc/releases/download/' - '20200711-gsj-qemu-0/nuvoton-npcm730-gsj.dtb') - dtb_hash = '18315f7006d7b688d8312d5c727eecd819aa36a4' - dtb_path = self.fetch_asset(dtb_url, asset_hash=dtb_hash) - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=ttyS0,115200n8 ' - 'earlycon=uart8250,mmio32,0xf0001000') - self.vm.add_args('-kernel', kernel_path, - '-initrd', initrd_path, - '-dtb', dtb_path, - '-append', kernel_command_line) - self.vm.launch() - - self.wait_for_console_pattern('Booting Linux on physical CPU 0x0') - self.wait_for_console_pattern('CPU1: thread -1, cpu 1, socket 0') - self.wait_for_console_pattern( - 'Give root password for system maintenance') - - def test_arm_bpim2u(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:bpim2u - :avocado: tags=accel:tcg - """ - deb_url = ('https://apt.armbian.com/pool/main/l/' - 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb') - deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) - kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinuz-6.6.16-current-sunxi') - dtb_path = ('/usr/lib/linux-image-6.6.16-current-sunxi/' - 'sun8i-r40-bananapi-m2-ultra.dtb') - dtb_path = self.extract_from_deb(deb_path, dtb_path) - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=ttyS0,115200n8 ' - 'earlycon=uart,mmio32,0x1c28000') - self.vm.add_args('-kernel', kernel_path, - '-dtb', dtb_path, - '-append', kernel_command_line) - self.vm.launch() - console_pattern = 'Kernel command line: %s' % kernel_command_line - self.wait_for_console_pattern(console_pattern) - - def test_arm_bpim2u_initrd(self): - """ - :avocado: tags=arch:arm - :avocado: tags=accel:tcg - :avocado: tags=machine:bpim2u - """ - deb_url = ('https://apt.armbian.com/pool/main/l/' - 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb') - deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) - kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinuz-6.6.16-current-sunxi') - dtb_path = ('/usr/lib/linux-image-6.6.16-current-sunxi/' - 'sun8i-r40-bananapi-m2-ultra.dtb') - dtb_path = self.extract_from_deb(deb_path, dtb_path) - initrd_url = ('https://github.com/groeck/linux-build-test/raw/' - '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/' - 'arm/rootfs-armv7a.cpio.gz') - initrd_hash = '604b2e45cdf35045846b8bbfbf2129b1891bdc9c' - initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash) - initrd_path = os.path.join(self.workdir, 'rootfs.cpio') - archive.gzip_uncompress(initrd_path_gz, initrd_path) - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=ttyS0,115200 ' - 'panic=-1 noreboot') - self.vm.add_args('-kernel', kernel_path, - '-dtb', dtb_path, - '-initrd', initrd_path, - '-append', kernel_command_line, - '-no-reboot') - self.vm.launch() - self.wait_for_console_pattern('Boot successful.') - - exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo', - 'Allwinner sun8i Family') - exec_command_and_wait_for_pattern(self, 'cat /proc/iomem', - 'system-control@1c00000') - exec_command_and_wait_for_pattern(self, 'reboot', - 'reboot: Restarting system') - # Wait for VM to shut down gracefully - self.vm.wait() - - def test_arm_bpim2u_gmac(self): - """ - :avocado: tags=arch:arm - :avocado: tags=accel:tcg - :avocado: tags=machine:bpim2u - :avocado: tags=device:sd - """ - self.require_netdev('user') - - deb_url = ('https://apt.armbian.com/pool/main/l/' - 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb') - deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) - kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinuz-6.6.16-current-sunxi') - dtb_path = ('/usr/lib/linux-image-6.6.16-current-sunxi/' - 'sun8i-r40-bananapi-m2-ultra.dtb') - dtb_path = self.extract_from_deb(deb_path, dtb_path) - rootfs_url = ('http://storage.kernelci.org/images/rootfs/buildroot/' - 'buildroot-baseline/20221116.0/armel/rootfs.ext2.xz') - rootfs_hash = 'fae32f337c7b87547b10f42599acf109da8b6d9a' - rootfs_path_xz = self.fetch_asset(rootfs_url, asset_hash=rootfs_hash) - rootfs_path = os.path.join(self.workdir, 'rootfs.cpio') - archive.lzma_uncompress(rootfs_path_xz, rootfs_path) - image_pow2ceil_expand(rootfs_path) - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=ttyS0,115200 ' - 'root=b300 rootwait rw ' - 'panic=-1 noreboot') - self.vm.add_args('-kernel', kernel_path, - '-dtb', dtb_path, - '-drive', 'file=' + rootfs_path + ',if=sd,format=raw', - '-net', 'nic,model=gmac,netdev=host_gmac', - '-netdev', 'user,id=host_gmac', - '-append', kernel_command_line, - '-no-reboot') - self.vm.launch() - shell_ready = "/bin/sh: can't access tty; job control turned off" - self.wait_for_console_pattern(shell_ready) - - exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo', - 'Allwinner sun8i Family') - exec_command_and_wait_for_pattern(self, 'cat /proc/partitions', - 'mmcblk') - exec_command_and_wait_for_pattern(self, 'ifconfig eth0 up', - 'eth0: Link is Up') - exec_command_and_wait_for_pattern(self, 'udhcpc eth0', - 'udhcpc: lease of 10.0.2.15 obtained') - exec_command_and_wait_for_pattern(self, 'ping -c 3 10.0.2.2', - '3 packets transmitted, 3 packets received, 0% packet loss') - exec_command_and_wait_for_pattern(self, 'reboot', - 'reboot: Restarting system') - # Wait for VM to shut down gracefully - self.vm.wait() - - @skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited') - def test_arm_bpim2u_openwrt_22_03_3(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:bpim2u - :avocado: tags=device:sd - """ - - # This test download a 8.9 MiB compressed image and expand it - # to 127 MiB. - image_url = ('https://downloads.openwrt.org/releases/22.03.3/targets/' - 'sunxi/cortexa7/openwrt-22.03.3-sunxi-cortexa7-' - 'sinovoip_bananapi-m2-ultra-ext4-sdcard.img.gz') - image_hash = ('5b41b4e11423e562c6011640f9a7cd3b' - 'dd0a3d42b83430f7caa70a432e6cd82c') - image_path_gz = self.fetch_asset(image_url, asset_hash=image_hash, - algorithm='sha256') - image_path = archive.extract(image_path_gz, self.workdir) - image_pow2ceil_expand(image_path) - - self.vm.set_console() - self.vm.add_args('-drive', 'file=' + image_path + ',if=sd,format=raw', - '-nic', 'user', - '-no-reboot') - self.vm.launch() - - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'usbcore.nousb ' - 'noreboot') - - self.wait_for_console_pattern('U-Boot SPL') - - interrupt_interactive_console_until_pattern( - self, 'Hit any key to stop autoboot:', '=>') - exec_command_and_wait_for_pattern(self, "setenv extraargs '" + - kernel_command_line + "'", '=>') - exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...'); - - self.wait_for_console_pattern( - 'Please press Enter to activate this console.') - - exec_command_and_wait_for_pattern(self, ' ', 'root@') - - exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo', - 'Allwinner sun8i Family') - exec_command_and_wait_for_pattern(self, 'cat /proc/iomem', - 'system-control@1c00000') - - def test_arm_orangepi(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:orangepi-pc - :avocado: tags=accel:tcg - """ - deb_url = ('https://apt.armbian.com/pool/main/l/' - 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb') - deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) - kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinuz-6.6.16-current-sunxi') - dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun8i-h3-orangepi-pc.dtb' - dtb_path = self.extract_from_deb(deb_path, dtb_path) - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=ttyS0,115200n8 ' - 'earlycon=uart,mmio32,0x1c28000') - self.vm.add_args('-kernel', kernel_path, - '-dtb', dtb_path, - '-append', kernel_command_line) - self.vm.launch() - console_pattern = 'Kernel command line: %s' % kernel_command_line - self.wait_for_console_pattern(console_pattern) - - def test_arm_orangepi_initrd(self): - """ - :avocado: tags=arch:arm - :avocado: tags=accel:tcg - :avocado: tags=machine:orangepi-pc - """ - deb_url = ('https://apt.armbian.com/pool/main/l/' - 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb') - deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) - kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinuz-6.6.16-current-sunxi') - dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun8i-h3-orangepi-pc.dtb' - dtb_path = self.extract_from_deb(deb_path, dtb_path) - initrd_url = ('https://github.com/groeck/linux-build-test/raw/' - '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/' - 'arm/rootfs-armv7a.cpio.gz') - initrd_hash = '604b2e45cdf35045846b8bbfbf2129b1891bdc9c' - initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash) - initrd_path = os.path.join(self.workdir, 'rootfs.cpio') - archive.gzip_uncompress(initrd_path_gz, initrd_path) - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=ttyS0,115200 ' - 'panic=-1 noreboot') - self.vm.add_args('-kernel', kernel_path, - '-dtb', dtb_path, - '-initrd', initrd_path, - '-append', kernel_command_line, - '-no-reboot') - self.vm.launch() - self.wait_for_console_pattern('Boot successful.') - - exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo', - 'Allwinner sun8i Family') - exec_command_and_wait_for_pattern(self, 'cat /proc/iomem', - 'system-control@1c00000') - exec_command_and_wait_for_pattern(self, 'reboot', - 'reboot: Restarting system') - # Wait for VM to shut down gracefully - self.vm.wait() - - def test_arm_orangepi_sd(self): - """ - :avocado: tags=arch:arm - :avocado: tags=accel:tcg - :avocado: tags=machine:orangepi-pc - :avocado: tags=device:sd - """ - self.require_netdev('user') - - deb_url = ('https://apt.armbian.com/pool/main/l/' - 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb') - deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) - kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinuz-6.6.16-current-sunxi') - dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun8i-h3-orangepi-pc.dtb' - dtb_path = self.extract_from_deb(deb_path, dtb_path) - rootfs_url = ('http://storage.kernelci.org/images/rootfs/buildroot/' - 'buildroot-baseline/20221116.0/armel/rootfs.ext2.xz') - rootfs_hash = 'fae32f337c7b87547b10f42599acf109da8b6d9a' - rootfs_path_xz = self.fetch_asset(rootfs_url, asset_hash=rootfs_hash) - rootfs_path = os.path.join(self.workdir, 'rootfs.cpio') - archive.lzma_uncompress(rootfs_path_xz, rootfs_path) - image_pow2ceil_expand(rootfs_path) - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=ttyS0,115200 ' - 'root=/dev/mmcblk0 rootwait rw ' - 'panic=-1 noreboot') - self.vm.add_args('-kernel', kernel_path, - '-dtb', dtb_path, - '-drive', 'file=' + rootfs_path + ',if=sd,format=raw', - '-append', kernel_command_line, - '-no-reboot') - self.vm.launch() - shell_ready = "/bin/sh: can't access tty; job control turned off" - self.wait_for_console_pattern(shell_ready) - - exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo', - 'Allwinner sun8i Family') - exec_command_and_wait_for_pattern(self, 'cat /proc/partitions', - 'mmcblk0') - exec_command_and_wait_for_pattern(self, 'ifconfig eth0 up', - 'eth0: Link is Up') - exec_command_and_wait_for_pattern(self, 'udhcpc eth0', - 'udhcpc: lease of 10.0.2.15 obtained') - exec_command_and_wait_for_pattern(self, 'ping -c 3 10.0.2.2', - '3 packets transmitted, 3 packets received, 0% packet loss') - exec_command_and_wait_for_pattern(self, 'reboot', - 'reboot: Restarting system') - # Wait for VM to shut down gracefully - self.vm.wait() - - @skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited') - def test_arm_orangepi_bionic_20_08(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:orangepi-pc - :avocado: tags=device:sd - """ - - # This test download a 275 MiB compressed image and expand it - # to 1036 MiB, but the underlying filesystem is 1552 MiB... - # As we expand it to 2 GiB we are safe. - - image_url = ('https://archive.armbian.com/orangepipc/archive/' - 'Armbian_20.08.1_Orangepipc_bionic_current_5.8.5.img.xz') - image_hash = ('b4d6775f5673486329e45a0586bf06b6' - 'dbe792199fd182ac6b9c7bb6c7d3e6dd') - image_path_xz = self.fetch_asset(image_url, asset_hash=image_hash, - algorithm='sha256') - image_path = archive.extract(image_path_xz, self.workdir) - image_pow2ceil_expand(image_path) - - self.vm.set_console() - self.vm.add_args('-drive', 'file=' + image_path + ',if=sd,format=raw', - '-nic', 'user', - '-no-reboot') - self.vm.launch() - - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=ttyS0,115200 ' - 'loglevel=7 ' - 'nosmp ' - 'systemd.default_timeout_start_sec=9000 ' - 'systemd.mask=armbian-zram-config.service ' - 'systemd.mask=armbian-ramlog.service') - - self.wait_for_console_pattern('U-Boot SPL') - self.wait_for_console_pattern('Autoboot in ') - exec_command_and_wait_for_pattern(self, ' ', '=>') - exec_command_and_wait_for_pattern(self, "setenv extraargs '" + - kernel_command_line + "'", '=>') - exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...'); - - self.wait_for_console_pattern('systemd[1]: Set hostname ' + - 'to <orangepipc>') - self.wait_for_console_pattern('Starting Load Kernel Modules...') - - @skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited') - def test_arm_orangepi_uboot_netbsd9(self): - """ - :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/' - '20200108T145233Z/pool/main/u/u-boot/' - 'u-boot-sunxi_2020.01%2Bdfsg-1_armhf.deb') - deb_hash = 'f67f404a80753ca3d1258f13e38f2b060e13db99' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) - # We use the common OrangePi PC 'plus' build of U-Boot for our secondary - # program loader (SPL). We will then set the path to the more specific - # OrangePi "PC" device tree blob with 'setenv fdtfile' in U-Boot prompt, - # before to boot NetBSD. - uboot_path = '/usr/lib/u-boot/orangepi_plus/u-boot-sunxi-with-spl.bin' - uboot_path = self.extract_from_deb(deb_path, uboot_path) - image_url = ('https://cdn.netbsd.org/pub/NetBSD/NetBSD-9.0/' - 'evbarm-earmv7hf/binary/gzimg/armv7.img.gz') - image_hash = '2babb29d36d8360adcb39c09e31060945259917a' - image_path_gz = self.fetch_asset(image_url, asset_hash=image_hash) - image_path = os.path.join(self.workdir, 'armv7.img') - archive.gzip_uncompress(image_path_gz, image_path) - image_pow2ceil_expand(image_path) - image_drive_args = 'if=sd,format=raw,snapshot=on,file=' + image_path - - # dd if=u-boot-sunxi-with-spl.bin of=armv7.img bs=1K seek=8 conv=notrunc - with open(uboot_path, 'rb') as f_in: - with open(image_path, 'r+b') as f_out: - f_out.seek(8 * 1024) - shutil.copyfileobj(f_in, f_out) - - self.vm.set_console() - self.vm.add_args('-nic', 'user', - '-drive', image_drive_args, - '-global', 'allwinner-rtc.base-year=2000', - '-no-reboot') - self.vm.launch() - wait_for_console_pattern(self, 'U-Boot 2020.01+dfsg-1') - interrupt_interactive_console_until_pattern(self, - 'Hit any key to stop autoboot:', - 'switch to partitions #0, OK') - - exec_command_and_wait_for_pattern(self, '', '=>') - cmd = 'setenv bootargs root=ld0a' - exec_command_and_wait_for_pattern(self, cmd, '=>') - cmd = 'setenv kernel netbsd-GENERIC.ub' - exec_command_and_wait_for_pattern(self, cmd, '=>') - cmd = 'setenv fdtfile dtb/sun8i-h3-orangepi-pc.dtb' - exec_command_and_wait_for_pattern(self, cmd, '=>') - cmd = ("setenv bootcmd 'fatload mmc 0:1 ${kernel_addr_r} ${kernel}; " - "fatload mmc 0:1 ${fdt_addr_r} ${fdtfile}; " - "fdt addr ${fdt_addr_r}; " - "bootm ${kernel_addr_r} - ${fdt_addr_r}'") - exec_command_and_wait_for_pattern(self, cmd, '=>') - - exec_command_and_wait_for_pattern(self, 'boot', - 'Booting kernel from Legacy Image') - wait_for_console_pattern(self, 'Starting kernel ...') - wait_for_console_pattern(self, 'NetBSD 9.0 (GENERIC)') - # Wait for user-space - wait_for_console_pattern(self, 'Starting root file system check') - - def test_aarch64_raspi3_atf(self): - """ - :avocado: tags=accel:tcg - :avocado: tags=arch:aarch64 - :avocado: tags=machine:raspi3b - :avocado: tags=cpu:cortex-a53 - :avocado: tags=device:pl011 - :avocado: tags=atf - """ - zip_url = ('https://github.com/pbatard/RPi3/releases/download/' - 'v1.15/RPi3_UEFI_Firmware_v1.15.zip') - zip_hash = '74b3bd0de92683cadb14e008a7575e1d0c3cafb9' - zip_path = self.fetch_asset(zip_url, asset_hash=zip_hash) - - archive.extract(zip_path, self.workdir) - efi_fd = os.path.join(self.workdir, 'RPI_EFI.fd') - - self.vm.set_console(console_index=1) - self.vm.add_args('-nodefaults', - '-device', 'loader,file=%s,force-raw=true' % efi_fd) - self.vm.launch() - self.wait_for_console_pattern('version UEFI Firmware v1.15') - - def test_s390x_s390_ccw_virtio(self): - """ - :avocado: tags=arch:s390x - :avocado: tags=machine:s390-ccw-virtio - """ - kernel_url = ('https://archives.fedoraproject.org/pub/archive' - '/fedora-secondary/releases/29/Everything/s390x/os/images' - '/kernel.img') - kernel_hash = 'e8e8439103ef8053418ef062644ffd46a7919313' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - - self.vm.set_console() - kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=sclp0' - self.vm.add_args('-nodefaults', - '-kernel', kernel_path, - '-append', kernel_command_line) - self.vm.launch() - console_pattern = 'Kernel command line: %s' % kernel_command_line - self.wait_for_console_pattern(console_pattern) - - def test_alpha_clipper(self): - """ - :avocado: tags=arch:alpha - :avocado: tags=machine:clipper - """ - kernel_url = ('http://archive.debian.org/debian/dists/lenny/main/' - 'installer-alpha/20090123lenny10/images/cdrom/vmlinuz') - kernel_hash = '3a943149335529e2ed3e74d0d787b85fb5671ba3' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - - uncompressed_kernel = archive.uncompress(kernel_path, self.workdir) - - self.vm.set_console() - kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0' - self.vm.add_args('-nodefaults', - '-kernel', uncompressed_kernel, - '-append', kernel_command_line) - self.vm.launch() - console_pattern = 'Kernel command line: %s' % kernel_command_line - self.wait_for_console_pattern(console_pattern) - - def test_m68k_q800(self): - """ - :avocado: tags=arch:m68k - :avocado: tags=machine:q800 - """ - deb_url = ('https://snapshot.debian.org/archive/debian-ports' - '/20191021T083923Z/pool-m68k/main' - '/l/linux/kernel-image-5.3.0-1-m68k-di_5.3.7-1_m68k.udeb') - deb_hash = '044954bb9be4160a3ce81f8bc1b5e856b75cccd1' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) - kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinux-5.3.0-1-m68k') - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=ttyS0 vga=off') - self.vm.add_args('-kernel', kernel_path, - '-append', kernel_command_line) - self.vm.launch() - console_pattern = 'Kernel command line: %s' % kernel_command_line - self.wait_for_console_pattern(console_pattern) - console_pattern = 'No filesystem could mount root' - self.wait_for_console_pattern(console_pattern) - - def do_test_advcal_2018(self, day, tar_hash, kernel_name, console=0): - tar_url = ('https://qemu-advcal.gitlab.io' - '/qac-best-of-multiarch/download/day' + day + '.tar.xz') - file_path = self.fetch_asset(tar_url, asset_hash=tar_hash) - archive.extract(file_path, self.workdir) - self.vm.set_console(console_index=console) - self.vm.add_args('-kernel', - self.workdir + '/day' + day + '/' + kernel_name) - self.vm.launch() - self.wait_for_console_pattern('QEMU advent calendar') - - def test_arm_vexpressa9(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:vexpress-a9 - """ - tar_hash = '32b7677ce8b6f1471fb0059865f451169934245b' - self.vm.add_args('-dtb', self.workdir + '/day16/vexpress-v2p-ca9.dtb') - self.do_test_advcal_2018('16', tar_hash, 'winter.zImage') - - def test_arm_ast2600_debian(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:rainier-bmc - """ - deb_url = ('http://snapshot.debian.org/archive/debian/' - '20220606T211338Z/' - 'pool/main/l/linux/' - 'linux-image-5.17.0-2-armmp_5.17.6-1%2Bb1_armhf.deb') - deb_hash = '8acb2b4439faedc2f3ed4bdb2847ad4f6e0491f73debaeb7f660c8abe4dcdc0e' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash, - algorithm='sha256') - kernel_path = self.extract_from_deb(deb_path, '/boot/vmlinuz-5.17.0-2-armmp') - dtb_path = self.extract_from_deb(deb_path, - '/usr/lib/linux-image-5.17.0-2-armmp/aspeed-bmc-ibm-rainier.dtb') - - self.vm.set_console() - self.vm.add_args('-kernel', kernel_path, - '-dtb', dtb_path, - '-net', 'nic') - self.vm.launch() - self.wait_for_console_pattern("Booting Linux on physical CPU 0xf00") - self.wait_for_console_pattern("SMP: Total of 2 processors activated") - self.wait_for_console_pattern("No filesystem could mount root") - - def test_m68k_mcf5208evb(self): - """ - :avocado: tags=arch:m68k - :avocado: tags=machine:mcf5208evb - """ - tar_hash = 'ac688fd00561a2b6ce1359f9ff6aa2b98c9a570c' - self.do_test_advcal_2018('07', tar_hash, 'sanity-clause.elf') - - def test_or1k_sim(self): - """ - :avocado: tags=arch:or1k - :avocado: tags=machine:or1k-sim - """ - tar_hash = '20334cdaf386108c530ff0badaecc955693027dd' - self.do_test_advcal_2018('20', tar_hash, 'vmlinux') - - def test_ppc64_e500(self): - """ - :avocado: tags=arch:ppc64 - :avocado: tags=machine:ppce500 - :avocado: tags=cpu:e5500 - :avocado: tags=accel:tcg - """ - self.require_accelerator("tcg") - tar_hash = '6951d86d644b302898da2fd701739c9406527fe1' - self.do_test_advcal_2018('19', tar_hash, 'uImage') - - def do_test_ppc64_powernv(self, proc): - self.require_accelerator("tcg") - images_url = ('https://github.com/open-power/op-build/releases/download/v2.7/') - - kernel_url = images_url + 'zImage.epapr' - kernel_hash = '0ab237df661727e5392cee97460e8674057a883c5f74381a128fa772588d45cd' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash, - algorithm='sha256') - self.vm.set_console() - self.vm.add_args('-kernel', kernel_path, - '-append', 'console=tty0 console=hvc0', - '-device', 'pcie-pci-bridge,id=bridge1,bus=pcie.1,addr=0x0', - '-device', 'nvme,bus=pcie.2,addr=0x0,serial=1234', - '-device', 'e1000e,bus=bridge1,addr=0x3', - '-device', 'nec-usb-xhci,bus=bridge1,addr=0x2') - self.vm.launch() - - self.wait_for_console_pattern("CPU: " + proc + " generation processor") - self.wait_for_console_pattern("zImage starting: loaded") - self.wait_for_console_pattern("Run /init as init process") - # Device detection output driven by udev probing is sometimes cut off - # from console output, suspect S14silence-console init script. - - def test_ppc_powernv8(self): - """ - :avocado: tags=arch:ppc64 - :avocado: tags=machine:powernv8 - :avocado: tags=accel:tcg - """ - self.do_test_ppc64_powernv('P8') - - def test_ppc_powernv9(self): - """ - :avocado: tags=arch:ppc64 - :avocado: tags=machine:powernv9 - :avocado: tags=accel:tcg - """ - self.do_test_ppc64_powernv('P9') - - def test_ppc_powernv10(self): - """ - :avocado: tags=arch:ppc64 - :avocado: tags=machine:powernv10 - :avocado: tags=accel:tcg - """ - self.do_test_ppc64_powernv('P10') - - def test_ppc_g3beige(self): - """ - :avocado: tags=arch:ppc - :avocado: tags=machine:g3beige - :avocado: tags=accel:tcg - """ - # TODO: g3beige works with kvm_pr but we don't have a - # reliable way ATM (e.g. looking at /proc/modules) to detect - # whether we're running kvm_hv or kvm_pr. For now let's - # disable this test if we don't have TCG support. - self.require_accelerator("tcg") - tar_hash = 'e0b872a5eb8fdc5bed19bd43ffe863900ebcedfc' - self.vm.add_args('-M', 'graphics=off') - self.do_test_advcal_2018('15', tar_hash, 'invaders.elf') - - def test_ppc_mac99(self): - """ - :avocado: tags=arch:ppc - :avocado: tags=machine:mac99 - :avocado: tags=accel:tcg - """ - # TODO: mac99 works with kvm_pr but we don't have a - # reliable way ATM (e.g. looking at /proc/modules) to detect - # whether we're running kvm_hv or kvm_pr. For now let's - # disable this test if we don't have TCG support. - self.require_accelerator("tcg") - tar_hash = 'e0b872a5eb8fdc5bed19bd43ffe863900ebcedfc' - self.vm.add_args('-M', 'graphics=off') - self.do_test_advcal_2018('15', tar_hash, 'invaders.elf') - - # This test has a 6-10% failure rate on various hosts that look - # like issues with a buggy kernel. As a result we don't want it - # gating releases on Gitlab. - @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab') - - def test_sh4_r2d(self): - """ - :avocado: tags=arch:sh4 - :avocado: tags=machine:r2d - :avocado: tags=flaky - """ - tar_hash = 'fe06a4fd8ccbf2e27928d64472939d47829d4c7e' - self.vm.add_args('-append', 'console=ttySC1') - self.do_test_advcal_2018('09', tar_hash, 'zImage', console=1) - - def test_sparc_ss20(self): - """ - :avocado: tags=arch:sparc - :avocado: tags=machine:SS-20 - """ - tar_hash = 'b18550d5d61c7615d989a06edace051017726a9f' - self.do_test_advcal_2018('11', tar_hash, 'zImage.elf') - - def test_xtensa_lx60(self): - """ - :avocado: tags=arch:xtensa - :avocado: tags=machine:lx60 - :avocado: tags=cpu:dc233c - """ - tar_hash = '49e88d9933742f0164b60839886c9739cb7a0d34' - self.do_test_advcal_2018('02', tar_hash, 'santas-sleigh-ride.elf') diff --git a/tests/avocado/boot_xen.py b/tests/avocado/boot_xen.py deleted file mode 100644 index fc2faee..0000000 --- a/tests/avocado/boot_xen.py +++ /dev/null @@ -1,116 +0,0 @@ -# Functional test that boots a Xen hypervisor with a domU kernel and -# checks the console output is vaguely sane . -# -# Copyright (c) 2020 Linaro -# -# Author: -# Alex Bennée <alex.bennee@linaro.org> -# -# SPDX-License-Identifier: GPL-2.0-or-later -# -# 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_qemu import wait_for_console_pattern -from boot_linux_console import LinuxKernelTest - - -class BootXenBase(LinuxKernelTest): - """ - Boots a Xen hypervisor with a Linux DomU kernel. - """ - - timeout = 90 - XEN_COMMON_COMMAND_LINE = 'dom0_mem=128M loglvl=all guest_loglvl=all' - - def fetch_guest_kernel(self): - # Using my own built kernel - which works - kernel_url = ('https://fileserver.linaro.org/' - 's/JSsewXGZ6mqxPr5/download?path=%2F&files=' - 'linux-5.9.9-arm64-ajb') - kernel_sha1 = '4f92bc4b9f88d5ab792fa7a43a68555d344e1b83' - kernel_path = self.fetch_asset(kernel_url, - asset_hash=kernel_sha1) - - return kernel_path - - def launch_xen(self, xen_path): - """ - Launch Xen with a dom0 guest kernel - """ - self.log.info("launch with xen_path: %s", xen_path) - kernel_path = self.fetch_guest_kernel() - - self.vm.set_console() - - xen_command_line = self.XEN_COMMON_COMMAND_LINE - self.vm.add_args('-machine', 'virtualization=on', - '-m', '768', - '-kernel', xen_path, - '-append', xen_command_line, - '-device', - 'guest-loader,addr=0x47000000,kernel=%s,bootargs=console=hvc0' - % (kernel_path)) - - self.vm.launch() - - console_pattern = 'VFS: Cannot open root device' - wait_for_console_pattern(self, console_pattern, "Panic on CPU 0:") - - -class BootXen(BootXenBase): - - def test_arm64_xen_411_and_dom0(self): - """ - :avocado: tags=arch:aarch64 - :avocado: tags=accel:tcg - :avocado: tags=cpu:cortex-a57 - :avocado: tags=machine:virt - """ - - # archive of file from https://deb.debian.org/debian/pool/main/x/xen/ - xen_url = ('https://fileserver.linaro.org/s/JSsewXGZ6mqxPr5/' - 'download?path=%2F&files=' - 'xen-hypervisor-4.11-arm64_4.11.4%2B37-g3263f257ca-1_arm64.deb') - xen_sha1 = '034e634d4416adbad1212d59b62bccdcda63e62a' - xen_deb = self.fetch_asset(xen_url, asset_hash=xen_sha1) - xen_path = self.extract_from_deb(xen_deb, "/boot/xen-4.11-arm64") - - self.launch_xen(xen_path) - - def test_arm64_xen_414_and_dom0(self): - """ - :avocado: tags=arch:aarch64 - :avocado: tags=accel:tcg - :avocado: tags=cpu:cortex-a57 - :avocado: tags=machine:virt - """ - - # archive of file from https://deb.debian.org/debian/pool/main/x/xen/ - xen_url = ('https://fileserver.linaro.org/s/JSsewXGZ6mqxPr5/' - 'download?path=%2F&files=' - 'xen-hypervisor-4.14-arm64_4.14.0%2B80-gd101b417b7-1_arm64.deb') - xen_sha1 = 'b9d209dd689ed2b393e625303a225badefec1160' - xen_deb = self.fetch_asset(xen_url, asset_hash=xen_sha1) - xen_path = self.extract_from_deb(xen_deb, "/boot/xen-4.14-arm64") - - self.launch_xen(xen_path) - - def test_arm64_xen_415_and_dom0(self): - """ - :avocado: tags=arch:aarch64 - :avocado: tags=accel:tcg - :avocado: tags=cpu:cortex-a57 - :avocado: tags=machine:virt - """ - - xen_url = ('https://fileserver.linaro.org/' - 's/JSsewXGZ6mqxPr5/download' - '?path=%2F&files=xen-upstream-4.15-unstable.deb') - xen_sha1 = 'fc191172b85cf355abb95d275a24cc0f6d6579d8' - xen_deb = self.fetch_asset(xen_url, asset_hash=xen_sha1) - xen_path = self.extract_from_deb(xen_deb, "/boot/xen-4.15-unstable") - - self.launch_xen(xen_path) diff --git a/tests/avocado/cpu_queries.py b/tests/avocado/cpu_queries.py deleted file mode 100644 index d3faa14..0000000 --- a/tests/avocado/cpu_queries.py +++ /dev/null @@ -1,35 +0,0 @@ -# Sanity check of query-cpu-* results -# -# Copyright (c) 2019 Red Hat, Inc. -# -# Author: -# Eduardo Habkost <ehabkost@redhat.com> -# -# This work is licensed under the terms of the GNU GPL, version 2 or -# later. See the COPYING file in the top-level directory. - -from avocado_qemu import QemuSystemTest - -class QueryCPUModelExpansion(QemuSystemTest): - """ - Run query-cpu-model-expansion for each CPU model, and validate results - """ - - def test(self): - """ - :avocado: tags=arch:x86_64 - :avocado: tags=machine:none - """ - self.vm.add_args('-S') - self.vm.launch() - - cpus = self.vm.cmd('query-cpu-definitions') - for c in cpus: - self.log.info("Checking CPU: %s", c) - self.assertNotIn('', c['unavailable-features'], c['name']) - - for c in cpus: - model = {'name': c['name']} - e = self.vm.cmd('query-cpu-model-expansion', model=model, - type='full') - self.assertEqual(e['model']['name'], c['name']) diff --git a/tests/avocado/empty_cpu_model.py b/tests/avocado/empty_cpu_model.py deleted file mode 100644 index d906ef3..0000000 --- a/tests/avocado/empty_cpu_model.py +++ /dev/null @@ -1,19 +0,0 @@ -# Check for crash when using empty -cpu option -# -# Copyright (c) 2019 Red Hat, Inc. -# -# Author: -# Eduardo Habkost <ehabkost@redhat.com> -# -# This work is licensed under the terms of the GNU GPL, version 2 or -# later. See the COPYING file in the top-level directory. -from avocado_qemu import QemuSystemTest - -class EmptyCPUModel(QemuSystemTest): - def test(self): - self.vm.add_args('-S', '-display', 'none', '-machine', 'none', '-cpu', '') - self.vm.set_qmp_monitor(enabled=False) - self.vm.launch() - self.vm.wait() - self.assertEqual(self.vm.exitcode(), 1, "QEMU exit code should be 1") - self.assertRegex(self.vm.get_log(), r'-cpu option cannot be empty') diff --git a/tests/avocado/hotplug_cpu.py b/tests/avocado/hotplug_cpu.py deleted file mode 100644 index 292bb43..0000000 --- a/tests/avocado/hotplug_cpu.py +++ /dev/null @@ -1,37 +0,0 @@ -# Functional test that hotplugs a CPU and checks it on a Linux guest -# -# Copyright (c) 2021 Red Hat, Inc. -# -# Author: -# Cleber Rosa <crosa@redhat.com> -# -# This work is licensed under the terms of the GNU GPL, version 2 or -# later. See the COPYING file in the top-level directory. - -from avocado_qemu import LinuxTest - - -class HotPlugCPU(LinuxTest): - - def test(self): - """ - :avocado: tags=arch:x86_64 - :avocado: tags=machine:q35 - :avocado: tags=accel:kvm - """ - self.require_accelerator('kvm') - self.vm.add_args('-accel', 'kvm') - self.vm.add_args('-cpu', 'Haswell') - self.vm.add_args('-smp', '1,sockets=1,cores=2,threads=1,maxcpus=2') - self.launch_and_wait() - - self.ssh_command('test -e /sys/devices/system/cpu/cpu0') - with self.assertRaises(AssertionError): - self.ssh_command('test -e /sys/devices/system/cpu/cpu1') - - self.vm.cmd('device_add', - driver='Haswell-x86_64-cpu', - socket_id=0, - core_id=1, - thread_id=0) - self.ssh_command('test -e /sys/devices/system/cpu/cpu1') diff --git a/tests/avocado/info_usernet.py b/tests/avocado/info_usernet.py deleted file mode 100644 index e1aa7a6..0000000 --- a/tests/avocado/info_usernet.py +++ /dev/null @@ -1,33 +0,0 @@ -# Test for the hmp command "info usernet" -# -# Copyright (c) 2021 Red Hat, Inc. -# -# Author: -# Cleber Rosa <crosa@redhat.com> -# -# This work is licensed under the terms of the GNU GPL, version 2 or -# later. See the COPYING file in the top-level directory. - -from avocado_qemu import QemuSystemTest - -from qemu.utils import get_info_usernet_hostfwd_port - - -class InfoUsernet(QemuSystemTest): - """ - :avocado: tags=machine:none - """ - - def test_hostfwd(self): - self.require_netdev('user') - self.vm.add_args('-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22') - self.vm.launch() - res = self.vm.cmd('human-monitor-command', - command_line='info usernet') - port = get_info_usernet_hostfwd_port(res) - self.assertIsNotNone(port, - ('"info usernet" output content does not seem to ' - 'contain the redirected port')) - self.assertGreater(port, 0, - ('Found a redirected port that is not greater than' - ' zero')) diff --git a/tests/avocado/intel_iommu.py b/tests/avocado/intel_iommu.py deleted file mode 100644 index 09e694b..0000000 --- a/tests/avocado/intel_iommu.py +++ /dev/null @@ -1,123 +0,0 @@ -# INTEL_IOMMU Functional tests -# -# Copyright (c) 2021 Red Hat, Inc. -# -# Author: -# Eric Auger <eric.auger@redhat.com> -# -# 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 skipUnless -from avocado_qemu import LinuxTest - -@skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable 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 - :avocado: tags=flaky - """ - - 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,' + - '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' - kernel_hash = '5b6f6876e1b5bda314f93893271da0d5777b1f3c' - initrd_url = self.distro.pxeboot_url + 'initrd.img' - initrd_hash = 'dd0340a1b39bd28f88532babd4581c67649ec5b1' - self.kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - self.initrd_path = self.fetch_asset(initrd_url, asset_hash=initrd_hash) - - 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() diff --git a/tests/avocado/kvm_xen_guest.py b/tests/avocado/kvm_xen_guest.py deleted file mode 100644 index f8cb458..0000000 --- a/tests/avocado/kvm_xen_guest.py +++ /dev/null @@ -1,171 +0,0 @@ -# KVM Xen guest functional tests -# -# Copyright © 2021 Red Hat, Inc. -# Copyright © 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. -# -# Author: -# David Woodhouse <dwmw2@infradead.org> -# Alex Bennée <alex.bennee@linaro.org> -# -# SPDX-License-Identifier: GPL-2.0-or-later - -import os - -from qemu.machine import machine - -from avocado_qemu import LinuxSSHMixIn -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern - -class KVMXenGuest(QemuSystemTest, LinuxSSHMixIn): - """ - :avocado: tags=arch:x86_64 - :avocado: tags=machine:q35 - :avocado: tags=accel:kvm - :avocado: tags=kvm_xen_guest - """ - - KERNEL_DEFAULT = 'printk.time=0 root=/dev/xvda console=ttyS0' - - kernel_path = None - kernel_params = None - - # Fetch assets from the kvm-xen-guest subdir of my shared test - # images directory on fileserver.linaro.org where you can find - # build instructions for how they where assembled. - def get_asset(self, name, sha1): - base_url = ('https://fileserver.linaro.org/s/' - 'kE4nCFLdQcoBF9t/download?' - 'path=%2Fkvm-xen-guest&files=' ) - url = base_url + name - # use explicit name rather than failing to neatly parse the - # URL into a unique one - return self.fetch_asset(name=name, locations=(url), asset_hash=sha1) - - def common_vm_setup(self): - # We also catch lack of KVM_XEN support if we fail to launch - self.require_accelerator("kvm") - - self.vm.set_console() - - self.vm.add_args("-accel", "kvm,xen-version=0x4000a,kernel-irqchip=split") - self.vm.add_args("-smp", "2") - - self.kernel_path = self.get_asset("bzImage", - "367962983d0d32109998a70b45dcee4672d0b045") - self.rootfs = self.get_asset("rootfs.ext4", - "f1478401ea4b3fa2ea196396be44315bab2bb5e4") - - def run_and_check(self): - self.vm.add_args('-kernel', self.kernel_path, - '-append', self.kernel_params, - '-drive', f"file={self.rootfs},if=none,snapshot=on,format=raw,id=drv0", - '-device', 'xen-disk,drive=drv0,vdev=xvda', - '-device', 'virtio-net-pci,netdev=unet', - '-netdev', 'user,id=unet,hostfwd=:127.0.0.1:0-:22') - - try: - self.vm.launch() - except machine.VMLaunchFailure as e: - if "Xen HVM guest support not present" in e.output: - self.cancel("KVM Xen support is not present " - "(need v5.12+ kernel with CONFIG_KVM_XEN)") - elif "Property 'kvm-accel.xen-version' not found" in e.output: - self.cancel("QEMU not built with CONFIG_XEN_EMU support") - else: - raise e - - self.log.info('VM launched, waiting for sshd') - console_pattern = 'Starting dropbear sshd: OK' - wait_for_console_pattern(self, console_pattern, 'Oops') - self.log.info('sshd ready') - self.ssh_connect('root', '', False) - - self.ssh_command('cat /proc/cmdline') - self.ssh_command('dmesg | grep -e "Grant table initialized"') - - def test_kvm_xen_guest(self): - """ - :avocado: tags=kvm_xen_guest - """ - - self.common_vm_setup() - - self.kernel_params = (self.KERNEL_DEFAULT + - ' xen_emul_unplug=ide-disks') - self.run_and_check() - self.ssh_command('grep xen-pirq.*msi /proc/interrupts') - - def test_kvm_xen_guest_nomsi(self): - """ - :avocado: tags=kvm_xen_guest_nomsi - """ - - self.common_vm_setup() - - self.kernel_params = (self.KERNEL_DEFAULT + - ' xen_emul_unplug=ide-disks pci=nomsi') - self.run_and_check() - self.ssh_command('grep xen-pirq.* /proc/interrupts') - - def test_kvm_xen_guest_noapic_nomsi(self): - """ - :avocado: tags=kvm_xen_guest_noapic_nomsi - """ - - self.common_vm_setup() - - self.kernel_params = (self.KERNEL_DEFAULT + - ' xen_emul_unplug=ide-disks noapic pci=nomsi') - self.run_and_check() - self.ssh_command('grep xen-pirq /proc/interrupts') - - def test_kvm_xen_guest_vapic(self): - """ - :avocado: tags=kvm_xen_guest_vapic - """ - - self.common_vm_setup() - self.vm.add_args('-cpu', 'host,+xen-vapic') - self.kernel_params = (self.KERNEL_DEFAULT + - ' xen_emul_unplug=ide-disks') - self.run_and_check() - self.ssh_command('grep xen-pirq /proc/interrupts') - self.ssh_command('grep PCI-MSI /proc/interrupts') - - def test_kvm_xen_guest_novector(self): - """ - :avocado: tags=kvm_xen_guest_novector - """ - - self.common_vm_setup() - self.kernel_params = (self.KERNEL_DEFAULT + - ' xen_emul_unplug=ide-disks' + - ' xen_no_vector_callback') - self.run_and_check() - self.ssh_command('grep xen-platform-pci /proc/interrupts') - - def test_kvm_xen_guest_novector_nomsi(self): - """ - :avocado: tags=kvm_xen_guest_novector_nomsi - """ - - self.common_vm_setup() - - self.kernel_params = (self.KERNEL_DEFAULT + - ' xen_emul_unplug=ide-disks pci=nomsi' + - ' xen_no_vector_callback') - self.run_and_check() - self.ssh_command('grep xen-platform-pci /proc/interrupts') - - def test_kvm_xen_guest_novector_noapic(self): - """ - :avocado: tags=kvm_xen_guest_novector_noapic - """ - - self.common_vm_setup() - self.kernel_params = (self.KERNEL_DEFAULT + - ' xen_emul_unplug=ide-disks' + - ' xen_no_vector_callback noapic') - self.run_and_check() - self.ssh_command('grep xen-platform-pci /proc/interrupts') diff --git a/tests/avocado/linux_initrd.py b/tests/avocado/linux_initrd.py deleted file mode 100644 index aad5b19..0000000 --- a/tests/avocado/linux_initrd.py +++ /dev/null @@ -1,92 +0,0 @@ -# Linux initrd integration test. -# -# Copyright (c) 2018 Red Hat, Inc. -# -# Author: -# Wainer dos Santos Moschetta <wainersm@redhat.com> -# -# 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 -import logging -import tempfile - -from avocado_qemu import QemuSystemTest -from avocado import skipUnless - - -class LinuxInitrd(QemuSystemTest): - """ - Checks QEMU evaluates correctly the initrd file passed as -initrd option. - - :avocado: tags=arch:x86_64 - :avocado: tags=machine:pc - """ - - timeout = 300 - - def test_with_2gib_file_should_exit_error_msg_with_linux_v3_6(self): - """ - Pretends to boot QEMU with an initrd file with size of 2GiB - and expect it exits with error message. - Fedora-18 shipped with linux-3.6 which have not supported xloadflags - cannot support more than 2GiB initrd. - """ - kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora/li' - 'nux/releases/18/Fedora/x86_64/os/images/pxeboot/vmlinuz') - kernel_hash = '41464f68efe42b9991250bed86c7081d2ccdbb21' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - max_size = 2 * (1024 ** 3) - 1 - - with tempfile.NamedTemporaryFile() as initrd: - initrd.seek(max_size) - initrd.write(b'\0') - initrd.flush() - self.vm.add_args('-kernel', kernel_path, '-initrd', initrd.name, - '-m', '4096') - self.vm.set_qmp_monitor(enabled=False) - self.vm.launch() - self.vm.wait() - self.assertEqual(self.vm.exitcode(), 1) - expected_msg = r'.*initrd is too large.*max: \d+, need %s.*' % ( - max_size + 1) - self.assertRegex(self.vm.get_log(), expected_msg) - - @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab') - - def test_with_2gib_file_should_work_with_linux_v4_16(self): - """ - :avocado: tags=flaky - - QEMU has supported up to 4 GiB initrd for recent kernel - Expect guest can reach 'Unpacking initramfs...' - """ - kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora' - '/linux/releases/28/Everything/x86_64/os/images/pxeboot/' - 'vmlinuz') - kernel_hash = '238e083e114c48200f80d889f7e32eeb2793e02a' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - max_size = 2 * (1024 ** 3) + 1 - - with tempfile.NamedTemporaryFile() as initrd: - initrd.seek(max_size) - initrd.write(b'\0') - initrd.flush() - - self.vm.set_console() - kernel_command_line = 'console=ttyS0' - self.vm.add_args('-kernel', kernel_path, - '-append', kernel_command_line, - '-initrd', initrd.name, - '-m', '5120') - self.vm.launch() - console = self.vm.console_socket.makefile() - console_logger = logging.getLogger('console') - while True: - msg = console.readline() - console_logger.debug(msg.strip()) - if 'Unpacking initramfs...' in msg: - break - if 'Kernel panic - not syncing' in msg: - self.fail("Kernel panic reached") diff --git a/tests/avocado/linux_ssh_mips_malta.py b/tests/avocado/linux_ssh_mips_malta.py deleted file mode 100644 index d9bb525..0000000 --- a/tests/avocado/linux_ssh_mips_malta.py +++ /dev/null @@ -1,205 +0,0 @@ -# Functional test that boots a VM and run commands via a SSH session -# -# Copyright (c) Philippe Mathieu-Daudé <f4bug@amsat.org> -# -# 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 -import re -import base64 -import logging -import time - -from avocado import skipUnless -from avocado_qemu import LinuxSSHMixIn -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern -from avocado.utils import process -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(QemuSystemTest, LinuxSSHMixIn): - """ - :avocado: tags=accel:tcg - """ - - timeout = 150 # Not for 'configure --enable-debug --enable-debug-tcg' - - KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 ' - VM_IP = '127.0.0.1' - - BASE_URL = 'https://people.debian.org/~aurel32/qemu/' - IMAGE_INFO = { - 'be': {'base_url': 'mips', - 'image_name': 'debian_wheezy_mips_standard.qcow2', - 'image_hash': '8987a63270df67345b2135a6b7a4885a35e392d5', - 'kernel_hash': { - 32: '592e384a4edc16dade52a6cd5c785c637bcbc9ad', - 64: 'db6eea7de35d36c77d8c165b6bcb222e16eb91db'} - }, - 'le': {'base_url': 'mipsel', - 'image_name': 'debian_wheezy_mipsel_standard.qcow2', - 'image_hash': '7866764d9de3ef536ffca24c9fb9f04ffdb45802', - 'kernel_hash': { - 32: 'a66bea5a8adaa2cb3d36a1d4e0ccdb01be8f6c2a', - 64: '6a7f77245acf231415a0e8b725d91ed2f3487794'} - } - } - CPU_INFO = { - 32: {'cpu': 'MIPS 24Kc', 'kernel_release': '3.2.0-4-4kc-malta'}, - 64: {'cpu': 'MIPS 20Kc', 'kernel_release': '3.2.0-4-5kc-malta'} - } - - def get_url(self, endianess, path=''): - qkey = {'le': 'el', 'be': ''} - return '%s/mips%s/%s' % (self.BASE_URL, qkey[endianess], path) - - def get_image_info(self, endianess): - dinfo = self.IMAGE_INFO[endianess] - image_url = self.get_url(endianess, dinfo['image_name']) - image_hash = dinfo['image_hash'] - return (image_url, image_hash) - - def get_kernel_info(self, endianess, wordsize): - minfo = self.CPU_INFO[wordsize] - kernel_url = self.get_url(endianess, - 'vmlinux-%s' % minfo['kernel_release']) - kernel_hash = self.IMAGE_INFO[endianess]['kernel_hash'][wordsize] - return kernel_url, kernel_hash - - def ssh_disconnect_vm(self): - self.ssh_session.quit() - - def boot_debian_wheezy_image_and_ssh_login(self, endianess, kernel_path): - image_url, image_hash = self.get_image_info(endianess) - image_path = self.fetch_asset(image_url, asset_hash=image_hash) - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE - + 'console=ttyS0 root=/dev/sda1') - self.vm.add_args('-no-reboot', - '-kernel', kernel_path, - '-append', kernel_command_line, - '-drive', 'file=%s,snapshot=on' % image_path, - '-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22', - '-device', 'pcnet,netdev=vnet') - self.vm.launch() - - self.log.info('VM launched, waiting for sshd') - console_pattern = 'Starting OpenBSD Secure Shell server: sshd' - wait_for_console_pattern(self, console_pattern, 'Oops') - self.log.info('sshd ready') - - self.ssh_connect('root', 'root', False) - - def shutdown_via_ssh(self): - self.ssh_command('poweroff') - self.ssh_disconnect_vm() - wait_for_console_pattern(self, 'Power down', 'Oops') - - def run_common_commands(self, wordsize): - self.ssh_command_output_contains( - 'cat /proc/cpuinfo', - self.CPU_INFO[wordsize]['cpu']) - self.ssh_command_output_contains( - 'uname -m', - 'mips') - self.ssh_command_output_contains( - 'uname -r', - self.CPU_INFO[wordsize]['kernel_release']) - self.ssh_command_output_contains( - 'cat /proc/interrupts', - 'XT-PIC timer') - self.ssh_command_output_contains( - 'cat /proc/interrupts', - 'XT-PIC i8042') - self.ssh_command_output_contains( - 'cat /proc/interrupts', - 'XT-PIC serial') - self.ssh_command_output_contains( - 'cat /proc/interrupts', - 'XT-PIC ata_piix') - self.ssh_command_output_contains( - 'cat /proc/interrupts', - 'XT-PIC eth0') - self.ssh_command_output_contains( - 'cat /proc/devices', - 'input') - self.ssh_command_output_contains( - 'cat /proc/devices', - 'usb') - self.ssh_command_output_contains( - 'cat /proc/devices', - 'fb') - self.ssh_command_output_contains( - 'cat /proc/ioports', - ' : serial') - self.ssh_command_output_contains( - 'cat /proc/ioports', - ' : ata_piix') - self.ssh_command_output_contains( - 'cat /proc/ioports', - ' : piix4_smbus') - self.ssh_command_output_contains( - 'lspci -d 11ab:4620', - 'GT-64120') - self.ssh_command_output_contains( - 'cat /sys/bus/i2c/devices/i2c-0/name', - 'SMBus PIIX4 adapter') - self.ssh_command_output_contains( - 'cat /proc/mtd', - 'YAMON') - # Empty 'Board Config' (64KB) - self.ssh_command_output_contains( - 'md5sum /dev/mtd2ro', - '0dfbe8aa4c20b52e1b8bf3cb6cbdf193') - - def check_mips_malta(self, uname_m, endianess): - wordsize = 64 if '64' in uname_m else 32 - kernel_url, kernel_hash = self.get_kernel_info(endianess, wordsize) - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - self.boot_debian_wheezy_image_and_ssh_login(endianess, kernel_path) - - stdout, _ = self.ssh_command('uname -a') - self.assertIn(True, [uname_m + " GNU/Linux" in line for line in stdout]) - - self.run_common_commands(wordsize) - self.shutdown_via_ssh() - # Wait for VM to shut down gracefully - self.vm.wait() - - def test_mips_malta32eb_kernel3_2_0(self): - """ - :avocado: tags=arch:mips - :avocado: tags=endian:big - :avocado: tags=device:pcnet32 - """ - self.check_mips_malta('mips', 'be') - - def test_mips_malta32el_kernel3_2_0(self): - """ - :avocado: tags=arch:mipsel - :avocado: tags=endian:little - :avocado: tags=device:pcnet32 - """ - self.check_mips_malta('mips', 'le') - - def test_mips_malta64eb_kernel3_2_0(self): - """ - :avocado: tags=arch:mips64 - :avocado: tags=endian:big - :avocado: tags=device:pcnet32 - """ - self.check_mips_malta('mips64', 'be') - - def test_mips_malta64el_kernel3_2_0(self): - """ - :avocado: tags=arch:mips64el - :avocado: tags=endian:little - :avocado: tags=device:pcnet32 - """ - self.check_mips_malta('mips64', 'le') diff --git a/tests/avocado/load_bflt.py b/tests/avocado/load_bflt.py deleted file mode 100644 index bb50cec..0000000 --- a/tests/avocado/load_bflt.py +++ /dev/null @@ -1,54 +0,0 @@ -# Test the bFLT loader format -# -# Copyright (C) 2019 Philippe Mathieu-Daudé <f4bug@amsat.org> -# -# SPDX-License-Identifier: GPL-2.0-or-later - -import os -import bz2 -import subprocess - -from avocado import skipUnless -from avocado_qemu import QemuUserTest -from avocado_qemu import has_cmd - - -class LoadBFLT(QemuUserTest): - - def extract_cpio(self, cpio_path): - """ - Extracts a cpio archive into the test workdir - - :param cpio_path: path to the cpio archive - """ - cwd = os.getcwd() - os.chdir(self.workdir) - with bz2.open(cpio_path, 'rb') as archive_cpio: - subprocess.run(['cpio', '-i'], input=archive_cpio.read(), - stderr=subprocess.DEVNULL) - os.chdir(cwd) - - @skipUnless(*has_cmd('cpio')) - @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code') - def test_stm32(self): - """ - :avocado: tags=arch:arm - :avocado: tags=linux_user - :avocado: tags=quick - """ - # See https://elinux.org/STM32#User_Space - rootfs_url = ('https://elinux.org/images/5/51/' - 'Stm32_mini_rootfs.cpio.bz2') - rootfs_hash = '9f065e6ba40cce7411ba757f924f30fcc57951e6' - rootfs_path_bz2 = self.fetch_asset(rootfs_url, asset_hash=rootfs_hash) - busybox_path = os.path.join(self.workdir, "/bin/busybox") - - self.extract_cpio(rootfs_path_bz2) - - res = self.run(busybox_path) - ver = 'BusyBox v1.24.0.git (2015-02-03 22:17:13 CET) multi-call binary.' - self.assertIn(ver, res.stdout_text) - - res = self.run(busybox_path, ['uname', '-a']) - unm = 'armv7l GNU/Linux' - self.assertIn(unm, res.stdout_text) diff --git a/tests/avocado/machine_aarch64_sbsaref.py b/tests/avocado/machine_aarch64_sbsaref.py deleted file mode 100644 index 6bb82f2..0000000 --- a/tests/avocado/machine_aarch64_sbsaref.py +++ /dev/null @@ -1,238 +0,0 @@ -# Functional test that boots a Linux kernel and checks the console -# -# SPDX-FileCopyrightText: 2023-2024 Linaro Ltd. -# SPDX-FileContributor: Philippe Mathieu-Daudé <philmd@linaro.org> -# SPDX-FileContributor: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org> -# -# SPDX-License-Identifier: GPL-2.0-or-later - -import os - -from avocado import skipUnless -from avocado.utils import archive - -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern -from avocado_qemu import interrupt_interactive_console_until_pattern - - -class Aarch64SbsarefMachine(QemuSystemTest): - """ - :avocado: tags=arch:aarch64 - :avocado: tags=machine:sbsa-ref - :avocado: tags=accel:tcg - - As firmware runs at a higher privilege level than the hypervisor we - can only run these tests under TCG emulation. - """ - - timeout = 180 - - def fetch_firmware(self): - """ - Flash volumes generated using: - - Toolchain from Debian: - aarch64-linux-gnu-gcc (Debian 12.2.0-14) 12.2.0 - - Used components: - - - Trusted Firmware 2.11.0 - - Tianocore EDK2 stable202405 - - Tianocore EDK2-platforms commit 4bbd0ed - - """ - - # Secure BootRom (TF-A code) - fs0_xz_url = ( - "https://artifacts.codelinaro.org/artifactory/linaro-419-sbsa-ref/" - "20240528-140808/edk2/SBSA_FLASH0.fd.xz" - ) - fs0_xz_hash = "fa6004900b67172914c908b78557fec4d36a5f784f4c3dd08f49adb75e1892a9" - tar_xz_path = self.fetch_asset(fs0_xz_url, asset_hash=fs0_xz_hash, - algorithm='sha256') - archive.extract(tar_xz_path, self.workdir) - fs0_path = os.path.join(self.workdir, "SBSA_FLASH0.fd") - - # Non-secure rom (UEFI and EFI variables) - fs1_xz_url = ( - "https://artifacts.codelinaro.org/artifactory/linaro-419-sbsa-ref/" - "20240528-140808/edk2/SBSA_FLASH1.fd.xz" - ) - fs1_xz_hash = "5f3747d4000bc416d9641e33ff4ac60c3cc8cb74ca51b6e932e58531c62eb6f7" - tar_xz_path = self.fetch_asset(fs1_xz_url, asset_hash=fs1_xz_hash, - algorithm='sha256') - archive.extract(tar_xz_path, self.workdir) - fs1_path = os.path.join(self.workdir, "SBSA_FLASH1.fd") - - for path in [fs0_path, fs1_path]: - with open(path, "ab+") as fd: - fd.truncate(256 << 20) # Expand volumes to 256MiB - - self.vm.set_console() - self.vm.add_args( - "-drive", - f"if=pflash,file={fs0_path},format=raw", - "-drive", - f"if=pflash,file={fs1_path},format=raw", - "-smp", - "1", - "-machine", - "sbsa-ref", - ) - - def test_sbsaref_edk2_firmware(self): - """ - :avocado: tags=cpu:cortex-a57 - """ - - self.fetch_firmware() - self.vm.launch() - - # TF-A boot sequence: - # - # https://github.com/ARM-software/arm-trusted-firmware/blob/v2.8.0/\ - # docs/design/trusted-board-boot.rst#trusted-board-boot-sequence - # https://trustedfirmware-a.readthedocs.io/en/v2.8/\ - # design/firmware-design.html#cold-boot - - # AP Trusted ROM - wait_for_console_pattern(self, "Booting Trusted Firmware") - wait_for_console_pattern(self, "BL1: v2.11.0(release):") - wait_for_console_pattern(self, "BL1: Booting BL2") - - # Trusted Boot Firmware - wait_for_console_pattern(self, "BL2: v2.11.0(release)") - wait_for_console_pattern(self, "Booting BL31") - - # EL3 Runtime Software - wait_for_console_pattern(self, "BL31: v2.11.0(release)") - - # Non-trusted Firmware - wait_for_console_pattern(self, "UEFI firmware (version 1.0") - interrupt_interactive_console_until_pattern(self, "QEMU SBSA-REF Machine") - - # This tests the whole boot chain from EFI to Userspace - # We only boot a whole OS for the current top level CPU and GIC - # Other test profiles should use more minimal boots - def boot_alpine_linux(self, cpu): - self.fetch_firmware() - - iso_url = ( - "https://dl-cdn.alpinelinux.org/" - "alpine/v3.17/releases/aarch64/alpine-standard-3.17.2-aarch64.iso" - ) - - iso_hash = "5a36304ecf039292082d92b48152a9ec21009d3a62f459de623e19c4bd9dc027" - iso_path = self.fetch_asset(iso_url, algorithm="sha256", asset_hash=iso_hash) - - self.vm.set_console() - self.vm.add_args( - "-cpu", - cpu, - "-drive", - f"file={iso_path},format=raw", - ) - - self.vm.launch() - wait_for_console_pattern(self, "Welcome to Alpine Linux 3.17") - - def test_sbsaref_alpine_linux_cortex_a57(self): - """ - :avocado: tags=cpu:cortex-a57 - :avocado: tags=os:linux - """ - self.boot_alpine_linux("cortex-a57") - - def test_sbsaref_alpine_linux_neoverse_n1(self): - """ - :avocado: tags=cpu:neoverse-n1 - :avocado: tags=os:linux - """ - self.boot_alpine_linux("neoverse-n1") - - def test_sbsaref_alpine_linux_max_pauth_off(self): - """ - :avocado: tags=cpu:max - :avocado: tags=os:linux - """ - self.boot_alpine_linux("max,pauth=off") - - def test_sbsaref_alpine_linux_max_pauth_impdef(self): - """ - :avocado: tags=cpu:max - :avocado: tags=os:linux - """ - self.boot_alpine_linux("max,pauth-impdef=on") - - @skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout') - def test_sbsaref_alpine_linux_max(self): - """ - :avocado: tags=cpu:max - :avocado: tags=os:linux - """ - self.boot_alpine_linux("max") - - - # This tests the whole boot chain from EFI to Userspace - # We only boot a whole OS for the current top level CPU and GIC - # Other test profiles should use more minimal boots - def boot_openbsd73(self, cpu): - self.fetch_firmware() - - img_url = ( - "https://cdn.openbsd.org/pub/OpenBSD/7.3/arm64/miniroot73.img" - ) - - img_hash = "7fc2c75401d6f01fbfa25f4953f72ad7d7c18650056d30755c44b9c129b707e5" - img_path = self.fetch_asset(img_url, algorithm="sha256", asset_hash=img_hash) - - self.vm.set_console() - self.vm.add_args( - "-cpu", - cpu, - "-drive", - f"file={img_path},format=raw", - ) - - self.vm.launch() - wait_for_console_pattern(self, - "Welcome to the OpenBSD/arm64" - " 7.3 installation program.") - - def test_sbsaref_openbsd73_cortex_a57(self): - """ - :avocado: tags=cpu:cortex-a57 - :avocado: tags=os:openbsd - """ - self.boot_openbsd73("cortex-a57") - - def test_sbsaref_openbsd73_neoverse_n1(self): - """ - :avocado: tags=cpu:neoverse-n1 - :avocado: tags=os:openbsd - """ - self.boot_openbsd73("neoverse-n1") - - def test_sbsaref_openbsd73_max_pauth_off(self): - """ - :avocado: tags=cpu:max - :avocado: tags=os:openbsd - """ - self.boot_openbsd73("max,pauth=off") - - @skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout') - def test_sbsaref_openbsd73_max_pauth_impdef(self): - """ - :avocado: tags=cpu:max - :avocado: tags=os:openbsd - """ - self.boot_openbsd73("max,pauth-impdef=on") - - @skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout') - def test_sbsaref_openbsd73_max(self): - """ - :avocado: tags=cpu:max - :avocado: tags=os:openbsd - """ - self.boot_openbsd73("max") diff --git a/tests/avocado/machine_aarch64_virt.py b/tests/avocado/machine_aarch64_virt.py deleted file mode 100644 index a90dc6f..0000000 --- a/tests/avocado/machine_aarch64_virt.py +++ /dev/null @@ -1,146 +0,0 @@ -# Functional test that boots a various Linux systems and checks the -# console output. -# -# Copyright (c) 2022 Linaro Ltd. -# -# Author: -# Alex Bennée <alex.bennee@linaro.org> -# -# SPDX-License-Identifier: GPL-2.0-or-later - -import time -import os -import logging - -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern -from avocado_qemu import exec_command -from avocado_qemu import BUILD_DIR -from avocado.utils import process -from avocado.utils.path import find_command - -class Aarch64VirtMachine(QemuSystemTest): - KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 ' - timeout = 360 - - def wait_for_console_pattern(self, success_message, vm=None): - wait_for_console_pattern(self, success_message, - failure_message='Kernel panic - not syncing', - vm=vm) - - # This tests the whole boot chain from EFI to Userspace - # We only boot a whole OS for the current top level CPU and GIC - # Other test profiles should use more minimal boots - def test_alpine_virt_tcg_gic_max(self): - """ - :avocado: tags=arch:aarch64 - :avocado: tags=machine:virt - :avocado: tags=accel:tcg - """ - iso_url = ('https://dl-cdn.alpinelinux.org/' - 'alpine/v3.17/releases/aarch64/' - 'alpine-standard-3.17.2-aarch64.iso') - - # Alpine use sha256 so I recalculated this myself - iso_sha1 = '76284fcd7b41fe899b0c2375ceb8470803eea839' - iso_path = self.fetch_asset(iso_url, asset_hash=iso_sha1) - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=ttyAMA0') - self.require_accelerator("tcg") - - self.vm.add_args("-accel", "tcg") - self.vm.add_args("-cpu", "max,pauth-impdef=on") - self.vm.add_args("-machine", - "virt,acpi=on," - "virtualization=on," - "mte=on," - "gic-version=max,iommu=smmuv3") - self.vm.add_args("-smp", "2", "-m", "1024") - self.vm.add_args('-bios', os.path.join(BUILD_DIR, 'pc-bios', - 'edk2-aarch64-code.fd')) - self.vm.add_args("-drive", f"file={iso_path},format=raw") - self.vm.add_args('-device', 'virtio-rng-pci,rng=rng0') - self.vm.add_args('-object', 'rng-random,id=rng0,filename=/dev/urandom') - - self.vm.launch() - self.wait_for_console_pattern('Welcome to Alpine Linux 3.17') - - - def common_aarch64_virt(self, machine): - """ - Common code to launch basic virt machine with kernel+initrd - and a scratch disk. - """ - logger = logging.getLogger('aarch64_virt') - - kernel_url = ('https://fileserver.linaro.org/s/' - 'z6B2ARM7DQT3HWN/download') - kernel_hash = 'ed11daab50c151dde0e1e9c9cb8b2d9bd3215347' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=ttyAMA0') - self.require_accelerator("tcg") - self.vm.add_args('-cpu', 'max,pauth-impdef=on', - '-machine', machine, - '-accel', 'tcg', - '-kernel', kernel_path, - '-append', kernel_command_line) - - # A RNG offers an easy way to generate a few IRQs - self.vm.add_args('-device', 'virtio-rng-pci,rng=rng0') - self.vm.add_args('-object', - 'rng-random,id=rng0,filename=/dev/urandom') - - # Also add a scratch block device - logger.info('creating scratch qcow2 image') - image_path = os.path.join(self.workdir, 'scratch.qcow2') - qemu_img = os.path.join(BUILD_DIR, 'qemu-img') - if not os.path.exists(qemu_img): - qemu_img = find_command('qemu-img', False) - if qemu_img is False: - self.cancel('Could not find "qemu-img", which is required to ' - 'create the temporary qcow2 image') - cmd = '%s create -f qcow2 %s 8M' % (qemu_img, image_path) - process.run(cmd) - - # Add the device - self.vm.add_args('-blockdev', - f"driver=qcow2,file.driver=file,file.filename={image_path},node-name=scratch") - self.vm.add_args('-device', - 'virtio-blk-device,drive=scratch') - - self.vm.launch() - self.wait_for_console_pattern('Welcome to Buildroot') - time.sleep(0.1) - exec_command(self, 'root') - time.sleep(0.1) - exec_command(self, 'dd if=/dev/hwrng of=/dev/vda bs=512 count=4') - time.sleep(0.1) - exec_command(self, 'md5sum /dev/vda') - time.sleep(0.1) - exec_command(self, 'cat /proc/interrupts') - time.sleep(0.1) - exec_command(self, 'cat /proc/self/maps') - time.sleep(0.1) - - def test_aarch64_virt_gicv3(self): - """ - :avocado: tags=arch:aarch64 - :avocado: tags=machine:virt - :avocado: tags=accel:tcg - :avocado: tags=cpu:max - """ - self.common_aarch64_virt("virt,gic_version=3") - - def test_aarch64_virt_gicv2(self): - """ - :avocado: tags=arch:aarch64 - :avocado: tags=machine:virt - :avocado: tags=accel:tcg - :avocado: tags=cpu:max - """ - self.common_aarch64_virt("virt,gic-version=2") diff --git a/tests/avocado/machine_arm_canona1100.py b/tests/avocado/machine_arm_canona1100.py deleted file mode 100644 index a42d8b0..0000000 --- a/tests/avocado/machine_arm_canona1100.py +++ /dev/null @@ -1,35 +0,0 @@ -# Functional test that boots the canon-a1100 machine with firmware -# -# Copyright (c) 2020 Red Hat, Inc. -# -# Author: -# Thomas Huth <thuth@redhat.com> -# -# This work is licensed under the terms of the GNU GPL, version 2 or -# later. See the COPYING file in the top-level directory. - -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern -from avocado.utils import archive - -class CanonA1100Machine(QemuSystemTest): - """Boots the barebox firmware and checks that the console is operational""" - - timeout = 90 - - def test_arm_canona1100(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:canon-a1100 - :avocado: tags=device:pflash_cfi02 - """ - tar_url = ('https://qemu-advcal.gitlab.io' - '/qac-best-of-multiarch/download/day18.tar.xz') - tar_hash = '068b5fc4242b29381acee94713509f8a876e9db6' - file_path = self.fetch_asset(tar_url, asset_hash=tar_hash) - archive.extract(file_path, self.workdir) - self.vm.set_console() - self.vm.add_args('-bios', - self.workdir + '/day18/barebox.canon-a1100.bin') - self.vm.launch() - wait_for_console_pattern(self, 'running /env/bin/init') diff --git a/tests/avocado/machine_arm_integratorcp.py b/tests/avocado/machine_arm_integratorcp.py deleted file mode 100644 index 87f5cf3..0000000 --- a/tests/avocado/machine_arm_integratorcp.py +++ /dev/null @@ -1,99 +0,0 @@ -# Functional test that boots a Linux kernel and checks the console -# -# Copyright (c) 2020 Red Hat, Inc. -# -# Author: -# Thomas Huth <thuth@redhat.com> -# -# 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 -import logging - -from avocado import skipUnless -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern - - -NUMPY_AVAILABLE = True -try: - import numpy as np -except ImportError: - NUMPY_AVAILABLE = False - -CV2_AVAILABLE = True -try: - import cv2 -except ImportError: - CV2_AVAILABLE = False - - -class IntegratorMachine(QemuSystemTest): - - timeout = 90 - - def boot_integratorcp(self): - kernel_url = ('https://github.com/zayac/qemu-arm/raw/master/' - 'arm-test/kernel/zImage.integrator') - kernel_hash = '0d7adba893c503267c946a3cbdc63b4b54f25468' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - - initrd_url = ('https://github.com/zayac/qemu-arm/raw/master/' - 'arm-test/kernel/arm_root.img') - initrd_hash = 'b51e4154285bf784e017a37586428332d8c7bd8b' - initrd_path = self.fetch_asset(initrd_url, asset_hash=initrd_hash) - - self.vm.set_console() - self.vm.add_args('-kernel', kernel_path, - '-initrd', initrd_path, - '-append', 'printk.time=0 console=ttyAMA0') - self.vm.launch() - - @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code') - def test_integratorcp_console(self): - """ - Boots the Linux kernel and checks that the console is operational - :avocado: tags=arch:arm - :avocado: tags=machine:integratorcp - :avocado: tags=device:pl011 - """ - self.boot_integratorcp() - wait_for_console_pattern(self, 'Log in as root') - - @skipUnless(NUMPY_AVAILABLE, 'Python NumPy not installed') - @skipUnless(CV2_AVAILABLE, 'Python OpenCV not installed') - @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code') - def test_framebuffer_tux_logo(self): - """ - Boot Linux and verify the Tux logo is displayed on the framebuffer. - :avocado: tags=arch:arm - :avocado: tags=machine:integratorcp - :avocado: tags=device:pl110 - :avocado: tags=device:framebuffer - """ - screendump_path = os.path.join(self.workdir, "screendump.pbm") - tuxlogo_url = ('https://github.com/torvalds/linux/raw/v2.6.12/' - 'drivers/video/logo/logo_linux_vga16.ppm') - tuxlogo_hash = '3991c2ddbd1ddaecda7601f8aafbcf5b02dc86af' - tuxlogo_path = self.fetch_asset(tuxlogo_url, asset_hash=tuxlogo_hash) - - self.boot_integratorcp() - framebuffer_ready = 'Console: switching to colour frame buffer device' - wait_for_console_pattern(self, framebuffer_ready) - self.vm.cmd('human-monitor-command', command_line='stop') - self.vm.cmd('human-monitor-command', - command_line='screendump %s' % screendump_path) - logger = logging.getLogger('framebuffer') - - cpu_count = 1 - match_threshold = 0.92 - screendump_bgr = cv2.imread(screendump_path) - screendump_gray = cv2.cvtColor(screendump_bgr, cv2.COLOR_BGR2GRAY) - result = cv2.matchTemplate(screendump_gray, cv2.imread(tuxlogo_path, 0), - cv2.TM_CCOEFF_NORMED) - loc = np.where(result >= match_threshold) - tux_count = 0 - for tux_count, pt in enumerate(zip(*loc[::-1]), start=1): - logger.debug('found Tux at position [x, y] = %s', pt) - self.assertGreaterEqual(tux_count, cpu_count) diff --git a/tests/avocado/machine_arm_n8x0.py b/tests/avocado/machine_arm_n8x0.py deleted file mode 100644 index 12e9a68..0000000 --- a/tests/avocado/machine_arm_n8x0.py +++ /dev/null @@ -1,49 +0,0 @@ -# Functional test that boots a Linux kernel and checks the console -# -# Copyright (c) 2020 Red Hat, Inc. -# -# Author: -# Thomas Huth <thuth@redhat.com> -# -# 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 skipUnless -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern - -class N8x0Machine(QemuSystemTest): - """Boots the Linux kernel and checks that the console is operational""" - - timeout = 90 - - def __do_test_n8x0(self): - kernel_url = ('http://stskeeps.subnetmask.net/meego-n8x0/' - 'meego-arm-n8x0-1.0.80.20100712.1431-' - 'vmlinuz-2.6.35~rc4-129.1-n8x0') - kernel_hash = 'e9d5ab8d7548923a0061b6fbf601465e479ed269' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - - self.vm.set_console(console_index=1) - self.vm.add_args('-kernel', kernel_path, - '-append', 'printk.time=0 console=ttyS1') - self.vm.launch() - wait_for_console_pattern(self, 'TSC2005 driver initializing') - - @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code') - def test_n800(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:n800 - """ - self.__do_test_n8x0() - - @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code') - def test_n810(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:n810 - """ - self.__do_test_n8x0() diff --git a/tests/avocado/machine_aspeed.py b/tests/avocado/machine_aspeed.py deleted file mode 100644 index 3a20644..0000000 --- a/tests/avocado/machine_aspeed.py +++ /dev/null @@ -1,439 +0,0 @@ -# Functional test that boots the ASPEED SoCs with firmware -# -# Copyright (C) 2022 ASPEED Technology Inc -# -# 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 time -import os -import tempfile -import subprocess - -from avocado_qemu import LinuxSSHMixIn -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern -from avocado_qemu import exec_command -from avocado_qemu import exec_command_and_wait_for_pattern -from avocado_qemu import interrupt_interactive_console_until_pattern -from avocado_qemu import has_cmd -from avocado.utils import archive -from avocado import skipUnless -from avocado import skipUnless - - -class AST1030Machine(QemuSystemTest): - """Boots the zephyr os and checks that the console is operational""" - - timeout = 10 - - def test_ast1030_zephyros_1_04(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:ast1030-evb - :avocado: tags=os:zephyr - """ - tar_url = ('https://github.com/AspeedTech-BMC' - '/zephyr/releases/download/v00.01.04/ast1030-evb-demo.zip') - tar_hash = '4c6a8ce3a8ba76ef1a65dae419ae3409343c4b20' - tar_path = self.fetch_asset(tar_url, asset_hash=tar_hash) - archive.extract(tar_path, self.workdir) - kernel_file = self.workdir + "/ast1030-evb-demo/zephyr.elf" - self.vm.set_console() - self.vm.add_args('-kernel', kernel_file, - '-nographic') - self.vm.launch() - wait_for_console_pattern(self, "Booting Zephyr OS") - exec_command_and_wait_for_pattern(self, "help", - "Available commands") - - def test_ast1030_zephyros_1_07(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:ast1030-evb - :avocado: tags=os:zephyr - """ - tar_url = ('https://github.com/AspeedTech-BMC' - '/zephyr/releases/download/v00.01.07/ast1030-evb-demo.zip') - tar_hash = '40ac87eabdcd3b3454ce5aad11fedc72a33ecda2' - tar_path = self.fetch_asset(tar_url, asset_hash=tar_hash) - archive.extract(tar_path, self.workdir) - kernel_file = self.workdir + "/ast1030-evb-demo/zephyr.bin" - self.vm.set_console() - self.vm.add_args('-kernel', kernel_file, - '-nographic') - self.vm.launch() - wait_for_console_pattern(self, "Booting Zephyr OS") - for shell_cmd in [ - 'kernel stacks', - 'otp info conf', - 'otp info scu', - 'hwinfo devid', - 'crypto aes256_cbc_vault', - 'random get', - 'jtag JTAG1 sw_xfer high TMS', - 'adc ADC0 resolution 12', - 'adc ADC0 read 42', - 'adc ADC1 read 69', - 'i2c scan I2C_0', - 'i3c attach I3C_0', - 'hash test', - 'kernel uptime', - 'kernel reboot warm', - 'kernel uptime', - 'kernel reboot cold', - 'kernel uptime', - ]: exec_command_and_wait_for_pattern(self, shell_cmd, "uart:~$") - -class AST2x00Machine(QemuSystemTest): - - timeout = 90 - - def wait_for_console_pattern(self, success_message, vm=None): - wait_for_console_pattern(self, success_message, - failure_message='Kernel panic - not syncing', - vm=vm) - - def do_test_arm_aspeed(self, image): - self.vm.set_console() - self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw', - '-net', 'nic') - self.vm.launch() - - self.wait_for_console_pattern("U-Boot 2016.07") - self.wait_for_console_pattern("## Loading kernel from FIT Image at 20080000") - self.wait_for_console_pattern("Starting kernel ...") - self.wait_for_console_pattern("Booting Linux on physical CPU 0x0") - wait_for_console_pattern(self, - "aspeed-smc 1e620000.spi: read control register: 203b0641") - self.wait_for_console_pattern("ftgmac100 1e660000.ethernet eth0: irq ") - self.wait_for_console_pattern("systemd[1]: Set hostname to") - - def test_arm_ast2400_palmetto_openbmc_v2_9_0(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:palmetto-bmc - """ - - image_url = ('https://github.com/openbmc/openbmc/releases/download/2.9.0/' - 'obmc-phosphor-image-palmetto.static.mtd') - image_hash = ('3e13bbbc28e424865dc42f35ad672b10f2e82cdb11846bb28fa625b48beafd0d') - image_path = self.fetch_asset(image_url, asset_hash=image_hash, - algorithm='sha256') - - self.do_test_arm_aspeed(image_path) - - def test_arm_ast2500_romulus_openbmc_v2_9_0(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:romulus-bmc - """ - - image_url = ('https://github.com/openbmc/openbmc/releases/download/2.9.0/' - 'obmc-phosphor-image-romulus.static.mtd') - image_hash = ('820341076803f1955bc31e647a512c79f9add4f5233d0697678bab4604c7bb25') - image_path = self.fetch_asset(image_url, asset_hash=image_hash, - algorithm='sha256') - - self.do_test_arm_aspeed(image_path) - - def do_test_arm_aspeed_buildroot_start(self, image, cpu_id, pattern='Aspeed EVB'): - self.require_netdev('user') - - self.vm.set_console() - self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw', - '-net', 'nic', '-net', 'user') - self.vm.launch() - - self.wait_for_console_pattern('U-Boot 2019.04') - self.wait_for_console_pattern('## Loading kernel from FIT Image') - self.wait_for_console_pattern('Starting kernel ...') - self.wait_for_console_pattern('Booting Linux on physical CPU ' + cpu_id) - self.wait_for_console_pattern('lease of 10.0.2.15') - # the line before login: - self.wait_for_console_pattern(pattern) - time.sleep(0.1) - exec_command(self, 'root') - time.sleep(0.1) - exec_command(self, "passw0rd") - - def do_test_arm_aspeed_buildroot_poweroff(self): - exec_command_and_wait_for_pattern(self, 'poweroff', - 'reboot: System halted'); - - def test_arm_ast2500_evb_buildroot(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:ast2500-evb - """ - - image_url = ('https://github.com/legoater/qemu-aspeed-boot/raw/master/' - 'images/ast2500-evb/buildroot-2023.11/flash.img') - image_hash = ('c23db6160cf77d0258397eb2051162c8473a56c441417c52a91ba217186e715f') - image_path = self.fetch_asset(image_url, asset_hash=image_hash, - algorithm='sha256') - - self.vm.add_args('-device', - 'tmp105,bus=aspeed.i2c.bus.3,address=0x4d,id=tmp-test'); - self.do_test_arm_aspeed_buildroot_start(image_path, '0x0', 'Aspeed AST2500 EVB') - - exec_command_and_wait_for_pattern(self, - 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-3/device/new_device', - 'i2c i2c-3: new_device: Instantiated device lm75 at 0x4d'); - exec_command_and_wait_for_pattern(self, - 'cat /sys/class/hwmon/hwmon1/temp1_input', '0') - self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test', - property='temperature', value=18000); - exec_command_and_wait_for_pattern(self, - 'cat /sys/class/hwmon/hwmon1/temp1_input', '18000') - - self.do_test_arm_aspeed_buildroot_poweroff() - - def test_arm_ast2600_evb_buildroot(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:ast2600-evb - """ - - image_url = ('https://github.com/legoater/qemu-aspeed-boot/raw/master/' - 'images/ast2600-evb/buildroot-2023.11/flash.img') - image_hash = ('b62808daef48b438d0728ee07662290490ecfa65987bb91294cafb1bb7ad1a68') - image_path = self.fetch_asset(image_url, asset_hash=image_hash, - algorithm='sha256') - - self.vm.add_args('-device', - 'tmp105,bus=aspeed.i2c.bus.3,address=0x4d,id=tmp-test'); - self.vm.add_args('-device', - 'ds1338,bus=aspeed.i2c.bus.3,address=0x32'); - self.vm.add_args('-device', - 'i2c-echo,bus=aspeed.i2c.bus.3,address=0x42'); - self.do_test_arm_aspeed_buildroot_start(image_path, '0xf00', 'Aspeed AST2600 EVB') - - exec_command_and_wait_for_pattern(self, - 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-3/device/new_device', - 'i2c i2c-3: new_device: Instantiated device lm75 at 0x4d'); - exec_command_and_wait_for_pattern(self, - 'cat /sys/class/hwmon/hwmon1/temp1_input', '0') - self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test', - property='temperature', value=18000); - exec_command_and_wait_for_pattern(self, - 'cat /sys/class/hwmon/hwmon1/temp1_input', '18000') - - exec_command_and_wait_for_pattern(self, - 'echo ds1307 0x32 > /sys/class/i2c-dev/i2c-3/device/new_device', - 'i2c i2c-3: new_device: Instantiated device ds1307 at 0x32'); - year = time.strftime("%Y") - exec_command_and_wait_for_pattern(self, 'hwclock -f /dev/rtc1', year); - - exec_command_and_wait_for_pattern(self, - 'echo slave-24c02 0x1064 > /sys/bus/i2c/devices/i2c-3/new_device', - 'i2c i2c-3: new_device: Instantiated device slave-24c02 at 0x64'); - exec_command(self, 'i2cset -y 3 0x42 0x64 0x00 0xaa i'); - time.sleep(0.1) - exec_command_and_wait_for_pattern(self, - 'hexdump /sys/bus/i2c/devices/3-1064/slave-eeprom', - '0000000 ffaa ffff ffff ffff ffff ffff ffff ffff'); - self.do_test_arm_aspeed_buildroot_poweroff() - - @skipUnless(*has_cmd('swtpm')) - def test_arm_ast2600_evb_buildroot_tpm(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:ast2600-evb - """ - - image_url = ('https://github.com/legoater/qemu-aspeed-boot/raw/master/' - 'images/ast2600-evb/buildroot-2023.02-tpm/flash.img') - image_hash = ('a46009ae8a5403a0826d607215e731a8c68d27c14c41e55331706b8f9c7bd997') - image_path = self.fetch_asset(image_url, asset_hash=image_hash, - algorithm='sha256') - - # force creation of VM object, which also defines self._sd - vm = self.vm - - socket = os.path.join(self._sd.name, 'swtpm-socket') - - subprocess.run(['swtpm', 'socket', '-d', '--tpm2', - '--tpmstate', f'dir={self.vm.temp_dir}', - '--ctrl', f'type=unixio,path={socket}']) - - self.vm.add_args('-chardev', f'socket,id=chrtpm,path={socket}') - self.vm.add_args('-tpmdev', 'emulator,id=tpm0,chardev=chrtpm') - self.vm.add_args('-device', - 'tpm-tis-i2c,tpmdev=tpm0,bus=aspeed.i2c.bus.12,address=0x2e') - self.do_test_arm_aspeed_buildroot_start(image_path, '0xf00', 'Aspeed AST2600 EVB') - - exec_command_and_wait_for_pattern(self, - 'echo tpm_tis_i2c 0x2e > /sys/bus/i2c/devices/i2c-12/new_device', - 'tpm_tis_i2c 12-002e: 2.0 TPM (device-id 0x1, rev-id 1)'); - exec_command_and_wait_for_pattern(self, - 'cat /sys/class/tpm/tpm0/pcr-sha256/0', - 'B804724EA13F52A9072BA87FE8FDCC497DFC9DF9AA15B9088694639C431688E0'); - - self.do_test_arm_aspeed_buildroot_poweroff() - -class AST2x00MachineSDK(QemuSystemTest, LinuxSSHMixIn): - - EXTRA_BOOTARGS = ( - 'quiet ' - 'systemd.mask=org.openbmc.HostIpmi.service ' - 'systemd.mask=xyz.openbmc_project.Chassis.Control.Power@0.service ' - 'systemd.mask=modprobe@fuse.service ' - 'systemd.mask=rngd.service ' - 'systemd.mask=obmc-console@ttyS2.service ' - ) - - # FIXME: Although these tests boot a whole distro they are still - # slower than comparable machine models. There may be some - # optimisations which bring down the runtime. In the meantime they - # have generous timeouts and are disable for CI which aims for all - # tests to run in less than 60 seconds. - timeout = 240 - - def wait_for_console_pattern(self, success_message, vm=None): - wait_for_console_pattern(self, success_message, - failure_message='Kernel panic - not syncing', - vm=vm) - - def do_test_arm_aspeed_sdk_start(self, image): - self.require_netdev('user') - self.vm.set_console() - self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw', - '-net', 'nic', '-net', 'user,hostfwd=:127.0.0.1:0-:22') - self.vm.launch() - - self.wait_for_console_pattern('U-Boot 2019.04') - interrupt_interactive_console_until_pattern( - self, 'Hit any key to stop autoboot:', 'ast#') - exec_command_and_wait_for_pattern( - self, 'setenv bootargs ${bootargs} ' + self.EXTRA_BOOTARGS, 'ast#') - exec_command_and_wait_for_pattern( - self, 'boot', '## Loading kernel from FIT Image') - self.wait_for_console_pattern('Starting kernel ...') - - def do_test_aarch64_aspeed_sdk_start(self, image): - self.vm.set_console() - self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw') - - self.vm.launch() - - self.wait_for_console_pattern('U-Boot 2023.10') - self.wait_for_console_pattern('## Loading kernel from FIT Image') - self.wait_for_console_pattern('Starting kernel ...') - self.wait_for_console_pattern("systemd[1]: Hostname set to") - - @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab') - - def test_arm_ast2500_evb_sdk(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:ast2500-evb - :avocado: tags=flaky - """ - - image_url = ('https://github.com/AspeedTech-BMC/openbmc/releases/' - 'download/v08.06/ast2500-default-obmc.tar.gz') - image_hash = ('e1755f3cadff69190438c688d52dd0f0d399b70a1e14b1d3d5540fc4851d38ca') - image_path = self.fetch_asset(image_url, asset_hash=image_hash, - algorithm='sha256') - archive.extract(image_path, self.workdir) - - self.do_test_arm_aspeed_sdk_start( - self.workdir + '/ast2500-default/image-bmc') - self.wait_for_console_pattern('nodistro.0 ast2500-default ttyS4') - - @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab') - - def test_arm_ast2600_evb_sdk(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:ast2600-evb - :avocado: tags=flaky - """ - - image_url = ('https://github.com/AspeedTech-BMC/openbmc/releases/' - 'download/v08.06/ast2600-a2-obmc.tar.gz') - image_hash = ('9083506135f622d5e7351fcf7d4e1c7125cee5ba16141220c0ba88931f3681a4') - image_path = self.fetch_asset(image_url, asset_hash=image_hash, - algorithm='sha256') - archive.extract(image_path, self.workdir) - - self.vm.add_args('-device', - 'tmp105,bus=aspeed.i2c.bus.5,address=0x4d,id=tmp-test'); - self.vm.add_args('-device', - 'ds1338,bus=aspeed.i2c.bus.5,address=0x32'); - self.do_test_arm_aspeed_sdk_start( - self.workdir + '/ast2600-a2/image-bmc') - self.wait_for_console_pattern('nodistro.0 ast2600-a2 ttyS4') - - self.ssh_connect('root', '0penBmc', False) - self.ssh_command('dmesg -c > /dev/null') - - self.ssh_command_output_contains( - 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-5/device/new_device ; ' - 'dmesg -c', - 'i2c i2c-5: new_device: Instantiated device lm75 at 0x4d'); - self.ssh_command_output_contains( - 'cat /sys/class/hwmon/hwmon19/temp1_input', '0') - self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test', - property='temperature', value=18000); - self.ssh_command_output_contains( - 'cat /sys/class/hwmon/hwmon19/temp1_input', '18000') - - self.ssh_command_output_contains( - 'echo ds1307 0x32 > /sys/class/i2c-dev/i2c-5/device/new_device ; ' - 'dmesg -c', - 'i2c i2c-5: new_device: Instantiated device ds1307 at 0x32'); - year = time.strftime("%Y") - self.ssh_command_output_contains('/sbin/hwclock -f /dev/rtc1', year); - - def test_aarch64_ast2700_evb_sdk_v09_01(self): - """ - :avocado: tags=arch:aarch64 - :avocado: tags=machine:ast2700-evb - """ - - image_url = ('https://github.com/AspeedTech-BMC/openbmc/releases/' - 'download/v09.01/ast2700-default-obmc.tar.gz') - image_hash = 'b1cc0fd73c7650d34c9c8459a243f52a91e9e27144b8608b2645ab19461d1e07' - image_path = self.fetch_asset(image_url, asset_hash=image_hash, - algorithm='sha256') - archive.extract(image_path, self.workdir) - - num_cpu = 4 - image_dir = self.workdir + '/ast2700-default/' - uboot_size = os.path.getsize(image_dir + 'u-boot-nodtb.bin') - uboot_dtb_load_addr = hex(0x400000000 + uboot_size) - - load_images_list = [ - { - 'addr': '0x400000000', - 'file': image_dir + 'u-boot-nodtb.bin' - }, - { - 'addr': str(uboot_dtb_load_addr), - 'file': image_dir + 'u-boot.dtb' - }, - { - 'addr': '0x430000000', - 'file': image_dir + 'bl31.bin' - }, - { - 'addr': '0x430080000', - 'file': image_dir + 'optee/tee-raw.bin' - } - ] - - for load_image in load_images_list: - addr = load_image['addr'] - file = load_image['file'] - self.vm.add_args('-device', - f'loader,force-raw=on,addr={addr},file={file}') - - for i in range(num_cpu): - self.vm.add_args('-device', - f'loader,addr=0x430000000,cpu-num={i}') - - self.vm.add_args('-smp', str(num_cpu)) - self.do_test_aarch64_aspeed_sdk_start(image_dir + 'image-bmc') - diff --git a/tests/avocado/machine_avr6.py b/tests/avocado/machine_avr6.py deleted file mode 100644 index 5485db7..0000000 --- a/tests/avocado/machine_avr6.py +++ /dev/null @@ -1,50 +0,0 @@ -# -# QEMU AVR integration tests -# -# Copyright (c) 2019-2020 Michael Rolnik <mrolnik@gmail.com> -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. -# - -import time - -from avocado_qemu import QemuSystemTest - -class AVR6Machine(QemuSystemTest): - timeout = 5 - - def test_freertos(self): - """ - :avocado: tags=arch:avr - :avocado: tags=machine:arduino-mega-2560-v3 - """ - """ - https://github.com/seharris/qemu-avr-tests/raw/master/free-rtos/Demo/AVR_ATMega2560_GCC/demo.elf - constantly prints out 'ABCDEFGHIJKLMNOPQRSTUVWXABCDEFGHIJKLMNOPQRSTUVWX' - """ - rom_url = ('https://github.com/seharris/qemu-avr-tests' - '/raw/36c3e67b8755dcf/free-rtos/Demo' - '/AVR_ATMega2560_GCC/demo.elf') - rom_hash = '7eb521f511ca8f2622e0a3c5e8dd686efbb911d4' - rom_path = self.fetch_asset(rom_url, asset_hash=rom_hash) - - self.vm.add_args('-bios', rom_path) - self.vm.add_args('-nographic') - self.vm.launch() - - time.sleep(2) - self.vm.shutdown() - - self.assertIn('ABCDEFGHIJKLMNOPQRSTUVWXABCDEFGHIJKLMNOPQRSTUVWX', - self.vm.get_log()) diff --git a/tests/avocado/machine_loongarch.py b/tests/avocado/machine_loongarch.py deleted file mode 100644 index 8de308f..0000000 --- a/tests/avocado/machine_loongarch.py +++ /dev/null @@ -1,58 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later -# -# LoongArch virt test. -# -# Copyright (c) 2023 Loongson Technology Corporation Limited -# - -from avocado_qemu import QemuSystemTest -from avocado_qemu import exec_command_and_wait_for_pattern -from avocado_qemu import wait_for_console_pattern - -class LoongArchMachine(QemuSystemTest): - KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 ' - - timeout = 120 - - def wait_for_console_pattern(self, success_message, vm=None): - wait_for_console_pattern(self, success_message, - failure_message='Kernel panic - not syncing', - vm=vm) - - def test_loongarch64_devices(self): - - """ - :avocado: tags=arch:loongarch64 - :avocado: tags=machine:virt - """ - - kernel_url = ('https://github.com/yangxiaojuan-loongson/qemu-binary/' - 'releases/download/2024-05-30/vmlinuz.efi') - kernel_hash = '951b485b16e3788b6db03a3e1793c067009e31a2' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - - initrd_url = ('https://github.com/yangxiaojuan-loongson/qemu-binary/' - 'releases/download/2024-05-30/ramdisk') - initrd_hash = 'c67658d9b2a447ce7db2f73ba3d373c9b2b90ab2' - initrd_path = self.fetch_asset(initrd_url, asset_hash=initrd_hash) - - bios_url = ('https://github.com/yangxiaojuan-loongson/qemu-binary/' - 'releases/download/2024-05-30/QEMU_EFI.fd') - bios_hash = ('f4d0966b5117d4cd82327c050dd668741046be69') - bios_path = self.fetch_asset(bios_url, asset_hash=bios_hash) - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'root=/dev/ram rdinit=/sbin/init console=ttyS0,115200') - self.vm.add_args('-nographic', - '-smp', '4', - '-m', '1024', - '-cpu', 'la464', - '-kernel', kernel_path, - '-initrd', initrd_path, - '-bios', bios_path, - '-append', kernel_command_line) - self.vm.launch() - self.wait_for_console_pattern('Run /sbin/init as init process') - exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo', - 'processor : 3') diff --git a/tests/avocado/machine_m68k_nextcube.py b/tests/avocado/machine_m68k_nextcube.py deleted file mode 100644 index 1f3c883..0000000 --- a/tests/avocado/machine_m68k_nextcube.py +++ /dev/null @@ -1,70 +0,0 @@ -# Functional test that boots a VM and run OCR on the framebuffer -# -# Copyright (c) 2019 Philippe Mathieu-Daudé <f4bug@amsat.org> -# -# 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 -import time - -from avocado_qemu import QemuSystemTest -from avocado import skipUnless - -from tesseract_utils import tesseract_available, tesseract_ocr - -PIL_AVAILABLE = True -try: - from PIL import Image -except ImportError: - PIL_AVAILABLE = False - - -class NextCubeMachine(QemuSystemTest): - """ - :avocado: tags=arch:m68k - :avocado: tags=machine:next-cube - :avocado: tags=device:framebuffer - """ - - timeout = 15 - - def check_bootrom_framebuffer(self, screenshot_path): - rom_url = ('https://sourceforge.net/p/previous/code/1350/tree/' - 'trunk/src/Rev_2.5_v66.BIN?format=raw') - rom_hash = 'b3534796abae238a0111299fc406a9349f7fee24' - rom_path = self.fetch_asset(rom_url, asset_hash=rom_hash) - - self.vm.add_args('-bios', rom_path) - self.vm.launch() - - self.log.info('VM launched, waiting for display') - # TODO: Use avocado.utils.wait.wait_for to catch the - # 'displaysurface_create 1120x832' trace-event. - time.sleep(2) - - self.vm.cmd('human-monitor-command', - command_line='screendump %s' % screenshot_path) - - @skipUnless(PIL_AVAILABLE, 'Python PIL not installed') - def test_bootrom_framebuffer_size(self): - screenshot_path = os.path.join(self.workdir, "dump.ppm") - self.check_bootrom_framebuffer(screenshot_path) - - width, height = Image.open(screenshot_path).size - self.assertEqual(width, 1120) - self.assertEqual(height, 832) - - # Tesseract 4 adds a new OCR engine based on LSTM neural networks. The - # new version is faster and more accurate than version 3. The drawback is - # that it is still alpha-level software. - @skipUnless(tesseract_available(4), 'tesseract OCR tool not available') - def test_bootrom_framebuffer_ocr_with_tesseract(self): - screenshot_path = os.path.join(self.workdir, "dump.ppm") - self.check_bootrom_framebuffer(screenshot_path) - lines = tesseract_ocr(screenshot_path, tesseract_version=4) - text = '\n'.join(lines) - self.assertIn('Testing the FPU', text) - self.assertIn('System test failed. Error code', text) - self.assertIn('Boot command', text) - self.assertIn('Next>', text) diff --git a/tests/avocado/machine_microblaze.py b/tests/avocado/machine_microblaze.py deleted file mode 100644 index 807709c..0000000 --- a/tests/avocado/machine_microblaze.py +++ /dev/null @@ -1,61 +0,0 @@ -# Functional test that boots a microblaze Linux kernel and checks the console -# -# Copyright (c) 2018, 2021 Red Hat, Inc. -# -# 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 time -from avocado_qemu import exec_command, exec_command_and_wait_for_pattern -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern -from avocado.utils import archive - -class MicroblazeMachine(QemuSystemTest): - - timeout = 90 - - def test_microblaze_s3adsp1800(self): - """ - :avocado: tags=arch:microblaze - :avocado: tags=machine:petalogix-s3adsp1800 - """ - - tar_url = ('https://qemu-advcal.gitlab.io' - '/qac-best-of-multiarch/download/day17.tar.xz') - tar_hash = '08bf3e3bfb6b6c7ce1e54ab65d54e189f2caf13f' - file_path = self.fetch_asset(tar_url, asset_hash=tar_hash) - archive.extract(file_path, self.workdir) - self.vm.set_console() - self.vm.add_args('-kernel', self.workdir + '/day17/ballerina.bin') - self.vm.launch() - wait_for_console_pattern(self, 'This architecture does not have ' - 'kernel memory protection') - # Note: - # The kernel sometimes gets stuck after the "This architecture ..." - # message, that's why we don't test for a later string here. This - # needs some investigation by a microblaze wizard one day... - - def test_microblazeel_s3adsp1800(self): - """ - :avocado: tags=arch:microblazeel - :avocado: tags=machine:petalogix-s3adsp1800 - """ - - self.require_netdev('user') - tar_url = ('http://www.qemu-advent-calendar.org/2023/download/' - 'day13.tar.gz') - tar_hash = '6623d5fff5f84cfa8f34e286f32eff6a26546f44' - file_path = self.fetch_asset(tar_url, asset_hash=tar_hash) - archive.extract(file_path, self.workdir) - self.vm.set_console() - self.vm.add_args('-kernel', self.workdir + '/day13/xmaton.bin') - self.vm.add_args('-nic', 'user,tftp=' + self.workdir + '/day13/') - self.vm.launch() - wait_for_console_pattern(self, 'QEMU Advent Calendar 2023') - time.sleep(0.1) - exec_command(self, 'root') - time.sleep(0.1) - exec_command_and_wait_for_pattern(self, - 'tftp -g -r xmaton.png 10.0.2.2 ; md5sum xmaton.png', - '821cd3cab8efd16ad6ee5acc3642a8ea') diff --git a/tests/avocado/machine_mips_fuloong2e.py b/tests/avocado/machine_mips_fuloong2e.py deleted file mode 100644 index 89291f4..0000000 --- a/tests/avocado/machine_mips_fuloong2e.py +++ /dev/null @@ -1,42 +0,0 @@ -# Functional tests for the Lemote Fuloong-2E machine. -# -# Copyright (c) 2019 Philippe Mathieu-Daudé <f4bug@amsat.org> -# -# This work is licensed under the terms of the GNU GPL, version 2 or later. -# See the COPYING file in the top-level directory. -# -# SPDX-License-Identifier: GPL-2.0-or-later - -import os - -from avocado import skipUnless -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern - -class MipsFuloong2e(QemuSystemTest): - - timeout = 60 - - @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code') - @skipUnless(os.getenv('RESCUE_YL_PATH'), 'RESCUE_YL_PATH not available') - def test_linux_kernel_isa_serial(self): - """ - :avocado: tags=arch:mips64el - :avocado: tags=machine:fuloong2e - :avocado: tags=endian:little - :avocado: tags=device:bonito64 - :avocado: tags=device:via686b - """ - # Recovery system for the Yeeloong laptop - # (enough to test the fuloong2e southbridge, accessing its ISA bus) - # http://dev.lemote.com/files/resource/download/rescue/rescue-yl - kernel_hash = 'ec4d1bd89a8439c41033ca63db60160cc6d6f09a' - kernel_path = self.fetch_asset('file://' + os.getenv('RESCUE_YL_PATH'), - asset_hash=kernel_hash) - - self.vm.set_console() - self.vm.add_args('-kernel', kernel_path) - self.vm.launch() - wait_for_console_pattern(self, 'Linux version 2.6.27.7lemote') - cpu_revision = 'CPU revision is: 00006302 (ICT Loongson-2)' - wait_for_console_pattern(self, cpu_revision) diff --git a/tests/avocado/machine_mips_loongson3v.py b/tests/avocado/machine_mips_loongson3v.py deleted file mode 100644 index 5194cf1..0000000 --- a/tests/avocado/machine_mips_loongson3v.py +++ /dev/null @@ -1,39 +0,0 @@ -# Functional tests for the Generic Loongson-3 Platform. -# -# Copyright (c) 2021 Jiaxun Yang <jiaxun.yang@flygoat.com> -# -# This work is licensed under the terms of the GNU GPL, version 2 or later. -# See the COPYING file in the top-level directory. -# -# SPDX-License-Identifier: GPL-2.0-or-later - -import os -import time - -from avocado import skipUnless -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern - -class MipsLoongson3v(QemuSystemTest): - timeout = 60 - - @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code') - def test_pmon_serial_console(self): - """ - :avocado: tags=arch:mips64el - :avocado: tags=endian:little - :avocado: tags=machine:loongson3-virt - :avocado: tags=cpu:Loongson-3A1000 - :avocado: tags=device:liointc - :avocado: tags=device:goldfish_rtc - """ - - pmon_hash = '7c8b45dd81ccfc55ff28f5aa267a41c3' - pmon_path = self.fetch_asset('https://github.com/loongson-community/pmon/' - 'releases/download/20210112/pmon-3avirt.bin', - asset_hash=pmon_hash, algorithm='md5') - - self.vm.set_console() - self.vm.add_args('-bios', pmon_path) - self.vm.launch() - wait_for_console_pattern(self, 'CPU GODSON3 BogoMIPS:') diff --git a/tests/avocado/machine_mips_malta.py b/tests/avocado/machine_mips_malta.py deleted file mode 100644 index 8cf84bd..0000000 --- a/tests/avocado/machine_mips_malta.py +++ /dev/null @@ -1,164 +0,0 @@ -# Functional tests for the MIPS Malta board -# -# Copyright (c) Philippe Mathieu-Daudé <f4bug@amsat.org> -# -# This work is licensed under the terms of the GNU GPL, version 2 or later. -# See the COPYING file in the top-level directory. -# -# SPDX-License-Identifier: GPL-2.0-or-later - -import os -import gzip -import logging - -from avocado import skipUnless -from avocado import skipUnless -from avocado.utils import archive -from avocado_qemu import QemuSystemTest -from avocado_qemu import exec_command_and_wait_for_pattern -from avocado_qemu import interrupt_interactive_console_until_pattern -from avocado_qemu import wait_for_console_pattern - - -NUMPY_AVAILABLE = True -try: - import numpy as np -except ImportError: - NUMPY_AVAILABLE = False - -CV2_AVAILABLE = True -try: - import cv2 -except ImportError: - CV2_AVAILABLE = False - - -@skipUnless(NUMPY_AVAILABLE, 'Python NumPy not installed') -@skipUnless(CV2_AVAILABLE, 'Python OpenCV not installed') -class MaltaMachineFramebuffer(QemuSystemTest): - - timeout = 30 - - KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 ' - - def do_test_i6400_framebuffer_logo(self, cpu_cores_count): - """ - Boot Linux kernel and check Tux logo is displayed on the framebuffer. - """ - screendump_path = os.path.join(self.workdir, 'screendump.pbm') - - kernel_url = ('https://github.com/philmd/qemu-testing-blob/raw/' - 'a5966ca4b5/mips/malta/mips64el/' - 'vmlinux-4.7.0-rc1.I6400.gz') - kernel_hash = '096f50c377ec5072e6a366943324622c312045f6' - kernel_path_gz = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - kernel_path = self.workdir + "vmlinux" - archive.gzip_uncompress(kernel_path_gz, kernel_path) - - tuxlogo_url = ('https://github.com/torvalds/linux/raw/v2.6.12/' - 'drivers/video/logo/logo_linux_vga16.ppm') - tuxlogo_hash = '3991c2ddbd1ddaecda7601f8aafbcf5b02dc86af' - tuxlogo_path = self.fetch_asset(tuxlogo_url, asset_hash=tuxlogo_hash) - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'clocksource=GIC console=tty0 console=ttyS0') - self.vm.add_args('-kernel', kernel_path, - '-smp', '%u' % cpu_cores_count, - '-vga', 'std', - '-append', kernel_command_line) - self.vm.launch() - framebuffer_ready = 'Console: switching to colour frame buffer device' - wait_for_console_pattern(self, framebuffer_ready, - failure_message='Kernel panic - not syncing') - self.vm.cmd('human-monitor-command', command_line='stop') - self.vm.cmd('human-monitor-command', - command_line='screendump %s' % screendump_path) - logger = logging.getLogger('framebuffer') - - match_threshold = 0.95 - screendump_bgr = cv2.imread(screendump_path, cv2.IMREAD_COLOR) - tuxlogo_bgr = cv2.imread(tuxlogo_path, cv2.IMREAD_COLOR) - result = cv2.matchTemplate(screendump_bgr, tuxlogo_bgr, - cv2.TM_CCOEFF_NORMED) - loc = np.where(result >= match_threshold) - tuxlogo_count = 0 - h, w = tuxlogo_bgr.shape[:2] - debug_png = os.getenv('AVOCADO_CV2_SCREENDUMP_PNG_PATH') - for tuxlogo_count, pt in enumerate(zip(*loc[::-1]), start=1): - logger.debug('found Tux at position (x, y) = %s', pt) - cv2.rectangle(screendump_bgr, pt, - (pt[0] + w, pt[1] + h), (0, 0, 255), 2) - if debug_png: - cv2.imwrite(debug_png, screendump_bgr) - self.assertGreaterEqual(tuxlogo_count, cpu_cores_count) - - def test_mips_malta_i6400_framebuffer_logo_1core(self): - """ - :avocado: tags=arch:mips64el - :avocado: tags=machine:malta - :avocado: tags=cpu:I6400 - """ - self.do_test_i6400_framebuffer_logo(1) - - @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab') - - def test_mips_malta_i6400_framebuffer_logo_7cores(self): - """ - :avocado: tags=arch:mips64el - :avocado: tags=machine:malta - :avocado: tags=cpu:I6400 - :avocado: tags=mips:smp - :avocado: tags=flaky - """ - self.do_test_i6400_framebuffer_logo(7) - - @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab') - - def test_mips_malta_i6400_framebuffer_logo_8cores(self): - """ - :avocado: tags=arch:mips64el - :avocado: tags=machine:malta - :avocado: tags=cpu:I6400 - :avocado: tags=mips:smp - :avocado: tags=flaky - """ - self.do_test_i6400_framebuffer_logo(8) - -class MaltaMachine(QemuSystemTest): - - def do_test_yamon(self): - rom_url = ('https://s3-eu-west-1.amazonaws.com/' - 'downloads-mips/mips-downloads/' - 'YAMON/yamon-bin-02.22.zip') - rom_hash = '8da7ecddbc5312704b8b324341ee238189bde480' - zip_path = self.fetch_asset(rom_url, asset_hash=rom_hash) - - archive.extract(zip_path, self.workdir) - yamon_path = os.path.join(self.workdir, 'yamon-02.22.bin') - - self.vm.set_console() - self.vm.add_args('-bios', yamon_path) - self.vm.launch() - - prompt = 'YAMON>' - pattern = 'YAMON ROM Monitor' - interrupt_interactive_console_until_pattern(self, pattern, prompt) - wait_for_console_pattern(self, prompt) - self.vm.shutdown() - - def test_mipsel_malta_yamon(self): - """ - :avocado: tags=arch:mipsel - :avocado: tags=machine:malta - :avocado: tags=endian:little - """ - self.do_test_yamon() - - def test_mips64el_malta_yamon(self): - """ - :avocado: tags=arch:mips64el - :avocado: tags=machine:malta - :avocado: tags=endian:little - """ - self.do_test_yamon() diff --git a/tests/avocado/machine_rx_gdbsim.py b/tests/avocado/machine_rx_gdbsim.py deleted file mode 100644 index 412a7a5..0000000 --- a/tests/avocado/machine_rx_gdbsim.py +++ /dev/null @@ -1,77 +0,0 @@ -# Functional test that boots a Linux kernel and checks the console -# -# Copyright (c) 2018 Red Hat, Inc. -# -# Author: -# Cleber Rosa <crosa@redhat.com> -# -# 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 skipUnless -from avocado_qemu import QemuSystemTest -from avocado_qemu import exec_command_and_wait_for_pattern -from avocado_qemu import wait_for_console_pattern -from avocado.utils import archive - - -class RxGdbSimMachine(QemuSystemTest): - - timeout = 30 - KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 ' - - @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab') - - def test_uboot(self): - """ - U-Boot and checks that the console is operational. - - :avocado: tags=arch:rx - :avocado: tags=machine:gdbsim-r5f562n8 - :avocado: tags=endian:little - :avocado: tags=flaky - """ - uboot_url = ('https://acc.dl.osdn.jp/users/23/23888/u-boot.bin.gz') - uboot_hash = '9b78dbd43b40b2526848c0b1ce9de02c24f4dcdb' - uboot_path = self.fetch_asset(uboot_url, asset_hash=uboot_hash) - uboot_path = archive.uncompress(uboot_path, self.workdir) - - self.vm.set_console() - self.vm.add_args('-bios', uboot_path, - '-no-reboot') - self.vm.launch() - uboot_version = 'U-Boot 2016.05-rc3-23705-ga1ef3c71cb-dirty' - wait_for_console_pattern(self, uboot_version) - gcc_version = 'rx-unknown-linux-gcc (GCC) 9.0.0 20181105 (experimental)' - # FIXME limit baudrate on chardev, else we type too fast - #exec_command_and_wait_for_pattern(self, 'version', gcc_version) - - @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab') - - def test_linux_sash(self): - """ - Boots a Linux kernel and checks that the console is operational. - - :avocado: tags=arch:rx - :avocado: tags=machine:gdbsim-r5f562n7 - :avocado: tags=endian:little - :avocado: tags=flaky - """ - dtb_url = ('https://acc.dl.osdn.jp/users/23/23887/rx-virt.dtb') - dtb_hash = '7b4e4e2c71905da44e86ce47adee2210b026ac18' - dtb_path = self.fetch_asset(dtb_url, asset_hash=dtb_hash) - kernel_url = ('http://acc.dl.osdn.jp/users/23/23845/zImage') - kernel_hash = '39a81067f8d72faad90866ddfefa19165d68fc99' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - - self.vm.set_console() - kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'earlycon' - self.vm.add_args('-kernel', kernel_path, - '-dtb', dtb_path, - '-no-reboot') - self.vm.launch() - wait_for_console_pattern(self, 'Sash command shell (version 1.1.1)', - failure_message='Kernel panic - not syncing') - exec_command_and_wait_for_pattern(self, 'printenv', 'TERM=linux') diff --git a/tests/avocado/machine_s390_ccw_virtio.py b/tests/avocado/machine_s390_ccw_virtio.py deleted file mode 100644 index 26e938c..0000000 --- a/tests/avocado/machine_s390_ccw_virtio.py +++ /dev/null @@ -1,277 +0,0 @@ -# Functional test that boots an s390x Linux guest with ccw and PCI devices -# attached and checks whether the devices are recognized by Linux -# -# Copyright (c) 2020 Red Hat, Inc. -# -# Author: -# Cornelia Huck <cohuck@redhat.com> -# -# 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 -import tempfile - -from avocado import skipUnless -from avocado_qemu import QemuSystemTest -from avocado_qemu import exec_command_and_wait_for_pattern -from avocado_qemu import wait_for_console_pattern -from avocado.utils import archive - -class S390CCWVirtioMachine(QemuSystemTest): - KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 ' - - timeout = 120 - - def wait_for_console_pattern(self, success_message, vm=None): - wait_for_console_pattern(self, success_message, - failure_message='Kernel panic - not syncing', - vm=vm) - - def wait_for_crw_reports(self): - exec_command_and_wait_for_pattern(self, - 'while ! (dmesg -c | grep CRW) ; do sleep 1 ; done', - 'CRW reports') - - dmesg_clear_count = 1 - def clear_guest_dmesg(self): - exec_command_and_wait_for_pattern(self, 'dmesg -c > /dev/null; ' - r'echo dm_clear\ ' + str(self.dmesg_clear_count), - r'dm_clear ' + str(self.dmesg_clear_count)) - self.dmesg_clear_count += 1 - - def test_s390x_devices(self): - - """ - :avocado: tags=arch:s390x - :avocado: tags=machine:s390-ccw-virtio - """ - - kernel_url = ('https://snapshot.debian.org/archive/debian/' - '20201126T092837Z/dists/buster/main/installer-s390x/' - '20190702+deb10u6/images/generic/kernel.debian') - kernel_hash = '5821fbee57d6220a067a8b967d24595621aa1eb6' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - - initrd_url = ('https://snapshot.debian.org/archive/debian/' - '20201126T092837Z/dists/buster/main/installer-s390x/' - '20190702+deb10u6/images/generic/initrd.debian') - initrd_hash = '81ba09c97bef46e8f4660ac25b4ac0a5be3a94d6' - initrd_path = self.fetch_asset(initrd_url, asset_hash=initrd_hash) - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=sclp0 root=/dev/ram0 BOOT_DEBUG=3') - self.vm.add_args('-nographic', - '-kernel', kernel_path, - '-initrd', initrd_path, - '-append', kernel_command_line, - '-cpu', 'max,prno-trng=off', - '-device', 'virtio-net-ccw,devno=fe.1.1111', - '-device', - 'virtio-rng-ccw,devno=fe.2.0000,max_revision=0,id=rn1', - '-device', - 'virtio-rng-ccw,devno=fe.3.1234,max_revision=2,id=rn2', - '-device', 'zpci,uid=5,target=zzz', - '-device', 'virtio-net-pci,id=zzz', - '-device', 'zpci,uid=0xa,fid=12,target=serial', - '-device', 'virtio-serial-pci,id=serial', - '-device', 'virtio-balloon-ccw') - self.vm.launch() - - shell_ready = "sh: can't access tty; job control turned off" - self.wait_for_console_pattern(shell_ready) - # first debug shell is too early, we need to wait for device detection - exec_command_and_wait_for_pattern(self, 'exit', shell_ready) - - ccw_bus_ids="0.1.1111 0.2.0000 0.3.1234" - pci_bus_ids="0005:00:00.0 000a:00:00.0" - exec_command_and_wait_for_pattern(self, 'ls /sys/bus/ccw/devices/', - ccw_bus_ids) - exec_command_and_wait_for_pattern(self, 'ls /sys/bus/pci/devices/', - pci_bus_ids) - # check that the device at 0.2.0000 is in legacy mode, while the - # device at 0.3.1234 has the virtio-1 feature bit set - virtio_rng_features="00000000000000000000000000001100" + \ - "10000000000000000000000000000000" - virtio_rng_features_legacy="00000000000000000000000000001100" + \ - "00000000000000000000000000000000" - exec_command_and_wait_for_pattern(self, - 'cat /sys/bus/ccw/devices/0.2.0000/virtio?/features', - virtio_rng_features_legacy) - exec_command_and_wait_for_pattern(self, - 'cat /sys/bus/ccw/devices/0.3.1234/virtio?/features', - virtio_rng_features) - # check that /dev/hwrng works - and that it's gone after ejecting - exec_command_and_wait_for_pattern(self, - 'dd if=/dev/hwrng of=/dev/null bs=1k count=10', - '10+0 records out') - self.clear_guest_dmesg() - self.vm.cmd('device_del', id='rn1') - self.wait_for_crw_reports() - self.clear_guest_dmesg() - self.vm.cmd('device_del', id='rn2') - self.wait_for_crw_reports() - exec_command_and_wait_for_pattern(self, - 'dd if=/dev/hwrng of=/dev/null bs=1k count=10', - 'dd: /dev/hwrng: No such device') - # verify that we indeed have virtio-net devices (without having the - # virtio-net driver handy) - exec_command_and_wait_for_pattern(self, - 'cat /sys/bus/ccw/devices/0.1.1111/cutype', - '3832/01') - exec_command_and_wait_for_pattern(self, - r'cat /sys/bus/pci/devices/0005\:00\:00.0/subsystem_vendor', - r'0x1af4') - exec_command_and_wait_for_pattern(self, - r'cat /sys/bus/pci/devices/0005\:00\:00.0/subsystem_device', - r'0x0001') - # check fid propagation - exec_command_and_wait_for_pattern(self, - r'cat /sys/bus/pci/devices/000a\:00\:00.0/function_id', - r'0x0000000c') - # add another device - self.clear_guest_dmesg() - self.vm.cmd('device_add', driver='virtio-net-ccw', - devno='fe.0.4711', id='net_4711') - self.wait_for_crw_reports() - exec_command_and_wait_for_pattern(self, 'for i in 1 2 3 4 5 6 7 ; do ' - 'if [ -e /sys/bus/ccw/devices/*4711 ]; then break; fi ;' - 'sleep 1 ; done ; ls /sys/bus/ccw/devices/', - '0.0.4711') - # and detach it again - self.clear_guest_dmesg() - self.vm.cmd('device_del', id='net_4711') - self.vm.event_wait(name='DEVICE_DELETED', - match={'data': {'device': 'net_4711'}}) - self.wait_for_crw_reports() - exec_command_and_wait_for_pattern(self, - 'ls /sys/bus/ccw/devices/0.0.4711', - 'No such file or directory') - # test the virtio-balloon device - exec_command_and_wait_for_pattern(self, 'head -n 1 /proc/meminfo', - 'MemTotal: 115640 kB') - self.vm.cmd('human-monitor-command', command_line='balloon 96') - exec_command_and_wait_for_pattern(self, 'head -n 1 /proc/meminfo', - 'MemTotal: 82872 kB') - self.vm.cmd('human-monitor-command', command_line='balloon 128') - exec_command_and_wait_for_pattern(self, 'head -n 1 /proc/meminfo', - 'MemTotal: 115640 kB') - - - def test_s390x_fedora(self): - - """ - :avocado: tags=arch:s390x - :avocado: tags=machine:s390-ccw-virtio - :avocado: tags=device:virtio-gpu - :avocado: tags=device:virtio-crypto - :avocado: tags=device:virtio-net - :avocado: tags=flaky - """ - - kernel_url = ('https://archives.fedoraproject.org/pub/archive' - '/fedora-secondary/releases/31/Server/s390x/os' - '/images/kernel.img') - kernel_hash = 'b93d1efcafcf29c1673a4ce371a1f8b43941cfeb' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - - initrd_url = ('https://archives.fedoraproject.org/pub/archive' - '/fedora-secondary/releases/31/Server/s390x/os' - '/images/initrd.img') - initrd_hash = '3de45d411df5624b8d8ef21cd0b44419ab59b12f' - initrd_path_xz = self.fetch_asset(initrd_url, asset_hash=initrd_hash) - initrd_path = os.path.join(self.workdir, 'initrd-raw.img') - archive.lzma_uncompress(initrd_path_xz, initrd_path) - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + ' audit=0 ' - 'rd.plymouth=0 plymouth.enable=0 rd.rescue') - self.vm.add_args('-nographic', - '-smp', '4', - '-m', '512', - '-name', 'Some Guest Name', - '-uuid', '30de4fd9-b4d5-409e-86a5-09b387f70bfa', - '-kernel', kernel_path, - '-initrd', initrd_path, - '-append', kernel_command_line, - '-device', 'zpci,uid=7,target=n', - '-device', 'virtio-net-pci,id=n,mac=02:ca:fe:fa:ce:12', - '-device', 'virtio-rng-ccw,devno=fe.1.9876', - '-device', 'virtio-gpu-ccw,devno=fe.2.5432') - self.vm.launch() - self.wait_for_console_pattern('Entering emergency mode') - - # Some tests to see whether the CLI options have been considered: - self.log.info("Test whether QEMU CLI options have been considered") - exec_command_and_wait_for_pattern(self, - 'while ! (dmesg | grep enP7p0s0) ; do sleep 1 ; done', - 'virtio_net virtio0 enP7p0s0: renamed') - exec_command_and_wait_for_pattern(self, 'lspci', - '0007:00:00.0 Class 0200: Device 1af4:1000') - exec_command_and_wait_for_pattern(self, - 'cat /sys/class/net/enP7p0s0/address', - '02:ca:fe:fa:ce:12') - exec_command_and_wait_for_pattern(self, 'lscss', '0.1.9876') - exec_command_and_wait_for_pattern(self, 'lscss', '0.2.5432') - exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo', - 'processors : 4') - exec_command_and_wait_for_pattern(self, 'grep MemTotal /proc/meminfo', - 'MemTotal: 499848 kB') - exec_command_and_wait_for_pattern(self, 'grep Name /proc/sysinfo', - 'Extended Name: Some Guest Name') - exec_command_and_wait_for_pattern(self, 'grep UUID /proc/sysinfo', - '30de4fd9-b4d5-409e-86a5-09b387f70bfa') - - # Disable blinking cursor, then write some stuff into the framebuffer. - # QEMU's PPM screendumps contain uncompressed 24-bit values, while the - # framebuffer uses 32-bit, so we pad our text with some spaces when - # writing to the framebuffer. Since the PPM is uncompressed, we then - # can simply read the written "magic bytes" back from the PPM file to - # check whether the framebuffer is working as expected. - # Unfortunately, this test is flaky, so we don't run it by default - if os.getenv('QEMU_TEST_FLAKY_TESTS'): - self.log.info("Test screendump of virtio-gpu device") - exec_command_and_wait_for_pattern(self, - 'while ! (dmesg | grep gpudrmfb) ; do sleep 1 ; done', - 'virtio_gpudrmfb frame buffer device') - exec_command_and_wait_for_pattern(self, - r'echo -e "\e[?25l" > /dev/tty0', ':/#') - exec_command_and_wait_for_pattern(self, 'for ((i=0;i<250;i++)); do ' - 'echo " The qu ick fo x j ump s o ver a laz y d og" >> fox.txt;' - 'done', - ':/#') - exec_command_and_wait_for_pattern(self, - 'dd if=fox.txt of=/dev/fb0 bs=1000 oflag=sync,nocache ; rm fox.txt', - '12+0 records out') - with tempfile.NamedTemporaryFile(suffix='.ppm', - prefix='qemu-scrdump-') as ppmfile: - self.vm.cmd('screendump', filename=ppmfile.name) - ppmfile.seek(0) - line = ppmfile.readline() - self.assertEqual(line, b"P6\n") - line = ppmfile.readline() - self.assertEqual(line, b"1280 800\n") - line = ppmfile.readline() - self.assertEqual(line, b"255\n") - line = ppmfile.readline(256) - self.assertEqual(line, b"The quick fox jumps over a lazy dog\n") - else: - self.log.info("Skipped flaky screendump of virtio-gpu device test") - - # Hot-plug a virtio-crypto device and see whether it gets accepted - self.log.info("Test hot-plug virtio-crypto device") - self.clear_guest_dmesg() - self.vm.cmd('object-add', qom_type='cryptodev-backend-builtin', - id='cbe0') - self.vm.cmd('device_add', driver='virtio-crypto-ccw', id='crypdev0', - cryptodev='cbe0', devno='fe.0.2342') - exec_command_and_wait_for_pattern(self, - 'while ! (dmesg -c | grep Accelerator.device) ; do' - ' sleep 1 ; done', 'Accelerator device is ready') - exec_command_and_wait_for_pattern(self, 'lscss', '0.0.2342') - self.vm.cmd('device_del', id='crypdev0') - self.vm.cmd('object-del', id='cbe0') - exec_command_and_wait_for_pattern(self, - 'while ! (dmesg -c | grep Start.virtcrypto_remove) ; do' - ' sleep 1 ; done', 'Start virtcrypto_remove.') diff --git a/tests/avocado/machine_sparc64_sun4u.py b/tests/avocado/machine_sparc64_sun4u.py deleted file mode 100644 index d333c0a..0000000 --- a/tests/avocado/machine_sparc64_sun4u.py +++ /dev/null @@ -1,36 +0,0 @@ -# Functional test that boots a Linux kernel and checks the console -# -# Copyright (c) 2020 Red Hat, Inc. -# -# Author: -# Thomas Huth <thuth@redhat.com> -# -# 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_qemu import wait_for_console_pattern -from avocado.utils import archive -from boot_linux_console import LinuxKernelTest - -class Sun4uMachine(LinuxKernelTest): - """Boots the Linux kernel and checks that the console is operational""" - - timeout = 90 - - def test_sparc64_sun4u(self): - """ - :avocado: tags=arch:sparc64 - :avocado: tags=machine:sun4u - """ - tar_url = ('https://qemu-advcal.gitlab.io' - '/qac-best-of-multiarch/download/day23.tar.xz') - tar_hash = '142db83cd974ffadc4f75c8a5cad5bcc5722c240' - file_path = self.fetch_asset(tar_url, asset_hash=tar_hash) - archive.extract(file_path, self.workdir) - self.vm.set_console() - self.vm.add_args('-kernel', self.workdir + '/day23/vmlinux', - '-append', self.KERNEL_COMMON_COMMAND_LINE) - self.vm.launch() - wait_for_console_pattern(self, 'Starting logging: OK') diff --git a/tests/avocado/machine_sparc_leon3.py b/tests/avocado/machine_sparc_leon3.py deleted file mode 100644 index e61b223..0000000 --- a/tests/avocado/machine_sparc_leon3.py +++ /dev/null @@ -1,37 +0,0 @@ -# Functional test that boots a Leon3 machine and checks its serial console. -# -# Copyright (c) Philippe Mathieu-Daudé <f4bug@amsat.org> -# -# This work is licensed under the terms of the GNU GPL, version 2 or -# later. See the COPYING file in the top-level directory. - -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern -from avocado import skip - - -class Leon3Machine(QemuSystemTest): - - timeout = 60 - - @skip("Test currently broken") - # A Window Underflow exception occurs before booting the kernel, - # and QEMU exit calling cpu_abort(), which makes this test to fail. - def test_leon3_helenos_uimage(self): - """ - :avocado: tags=arch:sparc - :avocado: tags=machine:leon3_generic - :avocado: tags=binfmt:uimage - """ - kernel_url = ('http://www.helenos.org/releases/' - 'HelenOS-0.6.0-sparc32-leon3.bin') - kernel_hash = 'a88c9cfdb8430c66650e5290a08765f9bf049a30' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - - self.vm.set_console() - self.vm.add_args('-kernel', kernel_path) - - self.vm.launch() - - wait_for_console_pattern(self, 'Copyright (c) 2001-2014 HelenOS project') - wait_for_console_pattern(self, 'Booting the kernel ...') diff --git a/tests/avocado/mem-addr-space-check.py b/tests/avocado/mem-addr-space-check.py deleted file mode 100644 index 85541ea..0000000 --- a/tests/avocado/mem-addr-space-check.py +++ /dev/null @@ -1,355 +0,0 @@ -# Check for crash when using memory beyond the available guest processor -# address space. -# -# Copyright (c) 2023 Red Hat, Inc. -# -# Author: -# Ani Sinha <anisinha@redhat.com> -# -# SPDX-License-Identifier: GPL-2.0-or-later - -from avocado_qemu import QemuSystemTest -import signal -import time - -class MemAddrCheck(QemuSystemTest): - # after launch, in order to generate the logs from QEMU we need to - # wait for some time. Launching and then immediately shutting down - # the VM generates empty logs. A delay of 1 second is added for - # this reason. - DELAY_Q35_BOOT_SEQUENCE = 1 - - # first, lets test some 32-bit processors. - # for all 32-bit cases, pci64_hole_size is 0. - def test_phybits_low_pse36(self): - """ - :avocado: tags=machine:q35 - :avocado: tags=arch:x86_64 - - With pse36 feature ON, a processor has 36 bits of addressing. So it can - access up to a maximum of 64GiB of memory. Memory hotplug region begins - at 4 GiB boundary when "above_4g_mem_size" is 0 (this would be true when - we have 0.5 GiB of VM memory, see pc_q35_init()). This means total - hotpluggable memory size is 60 GiB. Per slot, we reserve 1 GiB of memory - for dimm alignment for all machines. That leaves total hotpluggable - actual memory size of 59 GiB. If the VM is started with 0.5 GiB of - memory, maxmem should be set to a maximum value of 59.5 GiB to ensure - that the processor can address all memory directly. - Note that 64-bit pci hole size is 0 in this case. If maxmem is set to - 59.6G, QEMU should fail to start with a message "phy-bits are too low". - If maxmem is set to 59.5G with all other QEMU parameters identical, QEMU - should start fine. - """ - self.vm.add_args('-S', '-machine', 'q35', '-m', - '512,slots=1,maxmem=59.6G', - '-cpu', 'pentium,pse36=on', '-display', 'none', - '-object', 'memory-backend-ram,id=mem1,size=1G', - '-device', 'pc-dimm,id=vm0,memdev=mem1') - self.vm.set_qmp_monitor(enabled=False) - self.vm.launch() - self.vm.wait() - self.assertEqual(self.vm.exitcode(), 1, "QEMU exit code should be 1") - self.assertRegex(self.vm.get_log(), r'phys-bits too low') - - def test_phybits_low_pae(self): - """ - :avocado: tags=machine:q35 - :avocado: tags=arch:x86_64 - - With pae feature ON, a processor has 36 bits of addressing. So it can - access up to a maximum of 64GiB of memory. Rest is the same as the case - with pse36 above. - """ - self.vm.add_args('-S', '-machine', 'q35', '-m', - '512,slots=1,maxmem=59.6G', - '-cpu', 'pentium,pae=on', '-display', 'none', - '-object', 'memory-backend-ram,id=mem1,size=1G', - '-device', 'pc-dimm,id=vm0,memdev=mem1') - self.vm.set_qmp_monitor(enabled=False) - self.vm.launch() - self.vm.wait() - self.assertEqual(self.vm.exitcode(), 1, "QEMU exit code should be 1") - self.assertRegex(self.vm.get_log(), r'phys-bits too low') - - def test_phybits_ok_pentium_pse36(self): - """ - :avocado: tags=machine:q35 - :avocado: tags=arch:x86_64 - - Setting maxmem to 59.5G and making sure that QEMU can start with the - same options as the failing case above with pse36 cpu feature. - """ - self.vm.add_args('-machine', 'q35', '-m', - '512,slots=1,maxmem=59.5G', - '-cpu', 'pentium,pse36=on', '-display', 'none', - '-object', 'memory-backend-ram,id=mem1,size=1G', - '-device', 'pc-dimm,id=vm0,memdev=mem1') - self.vm.set_qmp_monitor(enabled=False) - self.vm.launch() - time.sleep(self.DELAY_Q35_BOOT_SEQUENCE) - self.vm.shutdown() - self.assertNotRegex(self.vm.get_log(), r'phys-bits too low') - - def test_phybits_ok_pentium_pae(self): - """ - :avocado: tags=machine:q35 - :avocado: tags=arch:x86_64 - - Test is same as above but now with pae cpu feature turned on. - Setting maxmem to 59.5G and making sure that QEMU can start fine - with the same options as the case above. - """ - self.vm.add_args('-machine', 'q35', '-m', - '512,slots=1,maxmem=59.5G', - '-cpu', 'pentium,pae=on', '-display', 'none', - '-object', 'memory-backend-ram,id=mem1,size=1G', - '-device', 'pc-dimm,id=vm0,memdev=mem1') - self.vm.set_qmp_monitor(enabled=False) - self.vm.launch() - time.sleep(self.DELAY_Q35_BOOT_SEQUENCE) - self.vm.shutdown() - self.assertNotRegex(self.vm.get_log(), r'phys-bits too low') - - def test_phybits_ok_pentium2(self): - """ - :avocado: tags=machine:q35 - :avocado: tags=arch:x86_64 - - Pentium2 has 36 bits of addressing, so its same as pentium - with pse36 ON. - """ - self.vm.add_args('-machine', 'q35', '-m', - '512,slots=1,maxmem=59.5G', - '-cpu', 'pentium2', '-display', 'none', - '-object', 'memory-backend-ram,id=mem1,size=1G', - '-device', 'pc-dimm,id=vm0,memdev=mem1') - self.vm.set_qmp_monitor(enabled=False) - self.vm.launch() - time.sleep(self.DELAY_Q35_BOOT_SEQUENCE) - self.vm.shutdown() - self.assertNotRegex(self.vm.get_log(), r'phys-bits too low') - - def test_phybits_low_nonpse36(self): - """ - :avocado: tags=machine:q35 - :avocado: tags=arch:x86_64 - - Pentium processor has 32 bits of addressing without pse36 or pae - so it can access physical address up to 4 GiB. Setting maxmem to - 4 GiB should make QEMU fail to start with "phys-bits too low" - message because the region for memory hotplug is always placed - above 4 GiB due to the PCI hole and simplicity. - """ - self.vm.add_args('-S', '-machine', 'q35', '-m', - '512,slots=1,maxmem=4G', - '-cpu', 'pentium', '-display', 'none', - '-object', 'memory-backend-ram,id=mem1,size=1G', - '-device', 'pc-dimm,id=vm0,memdev=mem1') - self.vm.set_qmp_monitor(enabled=False) - self.vm.launch() - self.vm.wait() - self.assertEqual(self.vm.exitcode(), 1, "QEMU exit code should be 1") - self.assertRegex(self.vm.get_log(), r'phys-bits too low') - - # now lets test some 64-bit CPU cases. - def test_phybits_low_tcg_q35_70_amd(self): - """ - :avocado: tags=machine:q35 - :avocado: tags=arch:x86_64 - - For q35 7.1 machines and above, there is a HT window that starts at - 1024 GiB and ends at 1 TiB - 1. If the max GPA falls in this range, - "above_4G" memory is adjusted to start at 1 TiB boundary for AMD cpus - in the default case. Lets test without that case for machines 7.0. - For q35-7.0 machines, "above 4G" memory starts are 4G. - pci64_hole size is 32 GiB. Since TCG_PHYS_ADDR_BITS is defined to - be 40, TCG emulated CPUs have maximum of 1 TiB (1024 GiB) of - directly addressable memory. - Hence, maxmem value at most can be - 1024 GiB - 4 GiB - 1 GiB per slot for alignment - 32 GiB + 0.5 GiB - which is equal to 987.5 GiB. Setting the value to 988 GiB should - make QEMU fail with the error message. - """ - self.vm.add_args('-S', '-machine', 'pc-q35-7.0', '-m', - '512,slots=1,maxmem=988G', - '-display', 'none', - '-object', 'memory-backend-ram,id=mem1,size=1G', - '-device', 'pc-dimm,id=vm0,memdev=mem1') - self.vm.set_qmp_monitor(enabled=False) - self.vm.launch() - self.vm.wait() - self.assertEqual(self.vm.exitcode(), 1, "QEMU exit code should be 1") - self.assertRegex(self.vm.get_log(), r'phys-bits too low') - - def test_phybits_low_tcg_q35_71_amd(self): - """ - :avocado: tags=machine:q35 - :avocado: tags=arch:x86_64 - - AMD_HT_START is defined to be at 1012 GiB. So for q35 machines - version > 7.0 and AMD cpus, instead of 1024 GiB limit for 40 bit - processor address space, it has to be 1012 GiB , that is 12 GiB - less than the case above in order to accommodate HT hole. - Make sure QEMU fails when maxmem size is 976 GiB (12 GiB less - than 988 GiB). - """ - self.vm.add_args('-S', '-machine', 'pc-q35-7.1', '-m', - '512,slots=1,maxmem=976G', - '-display', 'none', - '-object', 'memory-backend-ram,id=mem1,size=1G', - '-device', 'pc-dimm,id=vm0,memdev=mem1') - self.vm.set_qmp_monitor(enabled=False) - self.vm.launch() - self.vm.wait() - self.assertEqual(self.vm.exitcode(), 1, "QEMU exit code should be 1") - self.assertRegex(self.vm.get_log(), r'phys-bits too low') - - def test_phybits_ok_tcg_q35_70_amd(self): - """ - :avocado: tags=machine:q35 - :avocado: tags=arch:x86_64 - - Same as q35-7.0 AMD case except that here we check that QEMU can - successfully start when maxmem is < 988G. - """ - self.vm.add_args('-S', '-machine', 'pc-q35-7.0', '-m', - '512,slots=1,maxmem=987.5G', - '-display', 'none', - '-object', 'memory-backend-ram,id=mem1,size=1G', - '-device', 'pc-dimm,id=vm0,memdev=mem1') - self.vm.set_qmp_monitor(enabled=False) - self.vm.launch() - time.sleep(self.DELAY_Q35_BOOT_SEQUENCE) - self.vm.shutdown() - self.assertNotRegex(self.vm.get_log(), r'phys-bits too low') - - def test_phybits_ok_tcg_q35_71_amd(self): - """ - :avocado: tags=machine:q35 - :avocado: tags=arch:x86_64 - - Same as q35-7.1 AMD case except that here we check that QEMU can - successfully start when maxmem is < 976G. - """ - self.vm.add_args('-S', '-machine', 'pc-q35-7.1', '-m', - '512,slots=1,maxmem=975.5G', - '-display', 'none', - '-object', 'memory-backend-ram,id=mem1,size=1G', - '-device', 'pc-dimm,id=vm0,memdev=mem1') - self.vm.set_qmp_monitor(enabled=False) - self.vm.launch() - time.sleep(self.DELAY_Q35_BOOT_SEQUENCE) - self.vm.shutdown() - self.assertNotRegex(self.vm.get_log(), r'phys-bits too low') - - def test_phybits_ok_tcg_q35_71_intel(self): - """ - :avocado: tags=machine:q35 - :avocado: tags=arch:x86_64 - - Same parameters as test_phybits_low_tcg_q35_71_amd() but use - Intel cpu instead. QEMU should start fine in this case as - "above_4G" memory starts at 4G. - """ - self.vm.add_args('-S', '-cpu', 'Skylake-Server', - '-machine', 'pc-q35-7.1', '-m', - '512,slots=1,maxmem=976G', - '-display', 'none', - '-object', 'memory-backend-ram,id=mem1,size=1G', - '-device', 'pc-dimm,id=vm0,memdev=mem1') - self.vm.set_qmp_monitor(enabled=False) - self.vm.launch() - time.sleep(self.DELAY_Q35_BOOT_SEQUENCE) - self.vm.shutdown() - self.assertNotRegex(self.vm.get_log(), r'phys-bits too low') - - def test_phybits_low_tcg_q35_71_amd_41bits(self): - """ - :avocado: tags=machine:q35 - :avocado: tags=arch:x86_64 - - AMD processor with 41 bits. Max cpu hw address = 2 TiB. - By setting maxram above 1012 GiB - 32 GiB - 4 GiB = 976 GiB, we can - force "above_4G" memory to start at 1 TiB for q35-7.1 machines - (max GPA will be above AMD_HT_START which is defined as 1012 GiB). - - With pci_64_hole size at 32 GiB, in this case, maxmem should be 991.5 - GiB with 1 GiB per slot for alignment and 0.5 GiB as non-hotplug - memory for the VM (1024 - 32 - 1 + 0.5). With 992 GiB, QEMU should - fail to start. - """ - self.vm.add_args('-S', '-cpu', 'EPYC-v4,phys-bits=41', - '-machine', 'pc-q35-7.1', '-m', - '512,slots=1,maxmem=992G', - '-display', 'none', - '-object', 'memory-backend-ram,id=mem1,size=1G', - '-device', 'pc-dimm,id=vm0,memdev=mem1') - self.vm.set_qmp_monitor(enabled=False) - self.vm.launch() - self.vm.wait() - self.assertEqual(self.vm.exitcode(), 1, "QEMU exit code should be 1") - self.assertRegex(self.vm.get_log(), r'phys-bits too low') - - def test_phybits_ok_tcg_q35_71_amd_41bits(self): - """ - :avocado: tags=machine:q35 - :avocado: tags=arch:x86_64 - - AMD processor with 41 bits. Max cpu hw address = 2 TiB. - Same as above but by setting maxram between 976 GiB and 992 Gib, - QEMU should start fine. - """ - self.vm.add_args('-S', '-cpu', 'EPYC-v4,phys-bits=41', - '-machine', 'pc-q35-7.1', '-m', - '512,slots=1,maxmem=990G', - '-display', 'none', - '-object', 'memory-backend-ram,id=mem1,size=1G', - '-device', 'pc-dimm,id=vm0,memdev=mem1') - self.vm.set_qmp_monitor(enabled=False) - self.vm.launch() - time.sleep(self.DELAY_Q35_BOOT_SEQUENCE) - self.vm.shutdown() - self.assertNotRegex(self.vm.get_log(), r'phys-bits too low') - - def test_phybits_low_tcg_q35_intel_cxl(self): - """ - :avocado: tags=machine:q35 - :avocado: tags=arch:x86_64 - - cxl memory window starts after memory device range. Here, we use 1 GiB - of cxl window memory. 4G_mem end aligns at 4G. pci64_hole is 32 GiB and - starts after the cxl memory window. - So maxmem here should be at most 986 GiB considering all memory boundary - alignment constraints with 40 bits (1 TiB) of processor physical bits. - """ - self.vm.add_args('-S', '-cpu', 'Skylake-Server,phys-bits=40', - '-machine', 'q35,cxl=on', '-m', - '512,slots=1,maxmem=987G', - '-display', 'none', - '-device', 'pxb-cxl,bus_nr=12,bus=pcie.0,id=cxl.1', - '-M', 'cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=1G') - self.vm.set_qmp_monitor(enabled=False) - self.vm.launch() - self.vm.wait() - self.assertEqual(self.vm.exitcode(), 1, "QEMU exit code should be 1") - self.assertRegex(self.vm.get_log(), r'phys-bits too low') - - def test_phybits_ok_tcg_q35_intel_cxl(self): - """ - :avocado: tags=machine:q35 - :avocado: tags=arch:x86_64 - - Same as above but here we do not reserve any cxl memory window. Hence, - with the exact same parameters as above, QEMU should start fine even - with cxl enabled. - """ - self.vm.add_args('-S', '-cpu', 'Skylake-Server,phys-bits=40', - '-machine', 'q35,cxl=on', '-m', - '512,slots=1,maxmem=987G', - '-display', 'none', - '-device', 'pxb-cxl,bus_nr=12,bus=pcie.0,id=cxl.1') - self.vm.set_qmp_monitor(enabled=False) - self.vm.launch() - time.sleep(self.DELAY_Q35_BOOT_SEQUENCE) - self.vm.shutdown() - self.assertNotRegex(self.vm.get_log(), r'phys-bits too low') diff --git a/tests/avocado/migration.py b/tests/avocado/migration.py deleted file mode 100644 index be6234b..0000000 --- a/tests/avocado/migration.py +++ /dev/null @@ -1,135 +0,0 @@ -# Migration test -# -# Copyright (c) 2019 Red Hat, Inc. -# -# Authors: -# Cleber Rosa <crosa@redhat.com> -# Caio Carrara <ccarrara@redhat.com> -# -# 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 tempfile -import os - -from avocado_qemu import QemuSystemTest -from avocado import skipUnless - -from avocado.utils.network import ports -from avocado.utils import wait -from avocado.utils.path import find_command - - -class MigrationTest(QemuSystemTest): - """ - :avocado: tags=migration - """ - - timeout = 10 - - @staticmethod - def migration_finished(vm): - return vm.cmd('query-migrate')['status'] in ('completed', 'failed') - - def assert_migration(self, src_vm, dst_vm): - wait.wait_for(self.migration_finished, - timeout=self.timeout, - step=0.1, - args=(src_vm,)) - wait.wait_for(self.migration_finished, - timeout=self.timeout, - step=0.1, - args=(dst_vm,)) - self.assertEqual(src_vm.cmd('query-migrate')['status'], 'completed') - self.assertEqual(dst_vm.cmd('query-migrate')['status'], 'completed') - self.assertEqual(dst_vm.cmd('query-status')['status'], 'running') - self.assertEqual(src_vm.cmd('query-status')['status'],'postmigrate') - - def do_migrate(self, dest_uri, src_uri=None): - dest_vm = self.get_vm('-incoming', dest_uri) - dest_vm.add_args('-nodefaults') - dest_vm.launch() - if src_uri is None: - src_uri = dest_uri - source_vm = self.get_vm() - source_vm.add_args('-nodefaults') - source_vm.launch() - source_vm.qmp('migrate', uri=src_uri) - self.assert_migration(source_vm, dest_vm) - - def _get_free_port(self): - port = ports.find_free_port() - if port is None: - self.cancel('Failed to find a free port') - return port - - def migration_with_tcp_localhost(self): - dest_uri = 'tcp:localhost:%u' % self._get_free_port() - self.do_migrate(dest_uri) - - def migration_with_unix(self): - with tempfile.TemporaryDirectory(prefix='socket_') as socket_path: - dest_uri = 'unix:%s/qemu-test.sock' % socket_path - self.do_migrate(dest_uri) - - @skipUnless(find_command('nc', default=False), "'nc' command not found") - def migration_with_exec(self): - """The test works for both netcat-traditional and netcat-openbsd packages.""" - free_port = self._get_free_port() - dest_uri = 'exec:nc -l localhost %u' % free_port - src_uri = 'exec:nc localhost %u' % free_port - self.do_migrate(dest_uri, src_uri) - - -@skipUnless('aarch64' in os.uname()[4], "host != target") -class Aarch64(MigrationTest): - """ - :avocado: tags=arch:aarch64 - :avocado: tags=machine:virt - :avocado: tags=cpu:max - """ - - def test_migration_with_tcp_localhost(self): - self.migration_with_tcp_localhost() - - def test_migration_with_unix(self): - self.migration_with_unix() - - def test_migration_with_exec(self): - self.migration_with_exec() - - -@skipUnless('x86_64' in os.uname()[4], "host != target") -class X86_64(MigrationTest): - """ - :avocado: tags=arch:x86_64 - :avocado: tags=machine:pc - :avocado: tags=cpu:qemu64 - """ - - def test_migration_with_tcp_localhost(self): - self.migration_with_tcp_localhost() - - def test_migration_with_unix(self): - self.migration_with_unix() - - def test_migration_with_exec(self): - self.migration_with_exec() - - -@skipUnless('ppc64le' in os.uname()[4], "host != target") -class PPC64(MigrationTest): - """ - :avocado: tags=arch:ppc64 - :avocado: tags=machine:pseries - """ - - def test_migration_with_tcp_localhost(self): - self.migration_with_tcp_localhost() - - def test_migration_with_unix(self): - self.migration_with_unix() - - def test_migration_with_exec(self): - self.migration_with_exec() diff --git a/tests/avocado/multiprocess.py b/tests/avocado/multiprocess.py deleted file mode 100644 index ee7490a..0000000 --- a/tests/avocado/multiprocess.py +++ /dev/null @@ -1,102 +0,0 @@ -# Test for multiprocess qemu -# -# 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 -import socket - -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern -from avocado_qemu import exec_command -from avocado_qemu import exec_command_and_wait_for_pattern - -class Multiprocess(QemuSystemTest): - """ - :avocado: tags=multiprocess - """ - KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 ' - - def do_test(self, kernel_url, kernel_hash, initrd_url, initrd_hash, - kernel_command_line, machine_type): - """Main test method""" - self.require_accelerator('kvm') - self.require_multiprocess() - - # Create socketpair to connect proxy and remote processes - proxy_sock, remote_sock = socket.socketpair(socket.AF_UNIX, - socket.SOCK_STREAM) - os.set_inheritable(proxy_sock.fileno(), True) - os.set_inheritable(remote_sock.fileno(), True) - - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - initrd_path = self.fetch_asset(initrd_url, asset_hash=initrd_hash) - - # Create remote process - remote_vm = self.get_vm() - remote_vm.add_args('-machine', 'x-remote') - remote_vm.add_args('-nodefaults') - remote_vm.add_args('-device', 'lsi53c895a,id=lsi1') - remote_vm.add_args('-object', 'x-remote-object,id=robj1,' - 'devid=lsi1,fd='+str(remote_sock.fileno())) - remote_vm.launch() - - # Create proxy process - self.vm.set_console() - self.vm.add_args('-machine', machine_type) - self.vm.add_args('-accel', 'kvm') - self.vm.add_args('-cpu', 'host') - self.vm.add_args('-object', - 'memory-backend-memfd,id=sysmem-file,size=2G') - self.vm.add_args('--numa', 'node,memdev=sysmem-file') - self.vm.add_args('-m', '2048') - self.vm.add_args('-kernel', kernel_path, - '-initrd', initrd_path, - '-append', kernel_command_line) - self.vm.add_args('-device', - 'x-pci-proxy-dev,' - 'id=lsi1,fd='+str(proxy_sock.fileno())) - self.vm.launch() - wait_for_console_pattern(self, 'as init process', - 'Kernel panic - not syncing') - exec_command(self, 'mount -t sysfs sysfs /sys') - exec_command_and_wait_for_pattern(self, - 'cat /sys/bus/pci/devices/*/uevent', - 'PCI_ID=1000:0012') - - def test_multiprocess_x86_64(self): - """ - :avocado: tags=arch:x86_64 - """ - kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora' - '/linux/releases/31/Everything/x86_64/os/images' - '/pxeboot/vmlinuz') - kernel_hash = '5b6f6876e1b5bda314f93893271da0d5777b1f3c' - initrd_url = ('https://archives.fedoraproject.org/pub/archive/fedora' - '/linux/releases/31/Everything/x86_64/os/images' - '/pxeboot/initrd.img') - initrd_hash = 'dd0340a1b39bd28f88532babd4581c67649ec5b1' - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=ttyS0 rdinit=/bin/bash') - machine_type = 'pc' - self.do_test(kernel_url, kernel_hash, initrd_url, initrd_hash, - kernel_command_line, machine_type) - - def test_multiprocess_aarch64(self): - """ - :avocado: tags=arch:aarch64 - """ - kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora' - '/linux/releases/31/Everything/aarch64/os/images' - '/pxeboot/vmlinuz') - kernel_hash = '3505f2751e2833c681de78cee8dda1e49cabd2e8' - initrd_url = ('https://archives.fedoraproject.org/pub/archive/fedora' - '/linux/releases/31/Everything/aarch64/os/images' - '/pxeboot/initrd.img') - initrd_hash = '519a1962daf17d67fc3a9c89d45affcb399607db' - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'rdinit=/bin/bash console=ttyAMA0') - machine_type = 'virt,gic-version=3' - self.do_test(kernel_url, kernel_hash, initrd_url, initrd_hash, - kernel_command_line, machine_type) diff --git a/tests/avocado/netdev-ethtool.py b/tests/avocado/netdev-ethtool.py deleted file mode 100644 index 5f33288..0000000 --- a/tests/avocado/netdev-ethtool.py +++ /dev/null @@ -1,101 +0,0 @@ -# ethtool tests for emulated network devices -# -# This test leverages ethtool's --test sequence to validate network -# device behaviour. -# -# SPDX-License-Identifier: GPL-2.0-or-late - -from avocado import skip -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern - -class NetDevEthtool(QemuSystemTest): - """ - :avocado: tags=arch:x86_64 - :avocado: tags=machine:q35 - """ - - # Runs in about 17s under KVM, 19s under TCG, 25s under GCOV - timeout = 45 - - # Fetch assets from the netdev-ethtool subdir of my shared test - # images directory on fileserver.linaro.org. - def get_asset(self, name, sha1): - base_url = ('https://fileserver.linaro.org/s/' - 'kE4nCFLdQcoBF9t/download?' - 'path=%2Fnetdev-ethtool&files=' ) - url = base_url + name - # use explicit name rather than failing to neatly parse the - # URL into a unique one - return self.fetch_asset(name=name, locations=(url), asset_hash=sha1) - - def common_test_code(self, netdev, extra_args=None): - - # This custom kernel has drivers for all the supported network - # devices we can emulate in QEMU - kernel = self.get_asset("bzImage", - "33469d7802732d5815226166581442395cb289e2") - - rootfs = self.get_asset("rootfs.squashfs", - "9793cea7021414ae844bda51f558bd6565b50cdc") - - append = 'printk.time=0 console=ttyS0 ' - append += 'root=/dev/sr0 rootfstype=squashfs ' - - # any additional kernel tweaks for the test - if extra_args: - append += extra_args - - # finally invoke ethtool directly - append += ' init=/usr/sbin/ethtool -- -t eth1 offline' - - # add the rootfs via a readonly cdrom image - drive = f"file={rootfs},if=ide,index=0,media=cdrom" - - self.vm.add_args('-kernel', kernel, - '-append', append, - '-drive', drive, - '-device', netdev) - - self.vm.set_console(console_index=0) - self.vm.launch() - - wait_for_console_pattern(self, - "The test result is PASS", - "The test result is FAIL", - vm=None) - # no need to gracefully shutdown, just finish - self.vm.kill() - - def test_igb(self): - """ - :avocado: tags=device:igb - """ - self.common_test_code("igb") - - def test_igb_nomsi(self): - """ - :avocado: tags=device:igb - """ - self.common_test_code("igb", "pci=nomsi") - - # It seems the other popular cards we model in QEMU currently fail - # the pattern test with: - # - # pattern test failed (reg 0x00178): got 0x00000000 expected 0x00005A5A - # - # So for now we skip them. - - @skip("Incomplete reg 0x00178 support") - def test_e1000(self): - """ - :avocado: tags=device:e1000 - """ - self.common_test_code("e1000") - - @skip("Incomplete reg 0x00178 support") - def test_i82550(self): - """ - :avocado: tags=device:i82550 - """ - self.common_test_code("i82550") diff --git a/tests/avocado/pc_cpu_hotplug_props.py b/tests/avocado/pc_cpu_hotplug_props.py deleted file mode 100644 index 4bd3e02..0000000 --- a/tests/avocado/pc_cpu_hotplug_props.py +++ /dev/null @@ -1,35 +0,0 @@ -# -# Ensure CPU die-id can be omitted on -device -# -# Copyright (c) 2019 Red Hat Inc -# -# Author: -# Eduardo Habkost <ehabkost@redhat.com> -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, see <http://www.gnu.org/licenses/>. -# - -from avocado_qemu import QemuSystemTest - -class OmittedCPUProps(QemuSystemTest): - """ - :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('-device', 'qemu64-x86_64-cpu,socket-id=1,core-id=0,thread-id=0') - self.vm.launch() - self.assertEqual(len(self.vm.cmd('query-cpus-fast')), 2) diff --git a/tests/avocado/ppc_405.py b/tests/avocado/ppc_405.py deleted file mode 100644 index 4e7e01a..0000000 --- a/tests/avocado/ppc_405.py +++ /dev/null @@ -1,36 +0,0 @@ -# Test that the U-Boot firmware boots on ppc 405 machines and check the console -# -# Copyright (c) 2021 Red Hat, Inc. -# -# This work is licensed under the terms of the GNU GPL, version 2 or -# later. See the COPYING file in the top-level directory. - -from avocado.utils import archive -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern -from avocado_qemu import exec_command_and_wait_for_pattern - -class Ppc405Machine(QemuSystemTest): - - timeout = 90 - - def do_test_ppc405(self): - uboot_url = ('https://gitlab.com/huth/u-boot/-/raw/' - 'taihu-2021-10-09/u-boot-taihu.bin') - uboot_hash = ('3208940e908a5edc7c03eab072c60f0dcfadc2ab'); - file_path = self.fetch_asset(uboot_url, asset_hash=uboot_hash) - self.vm.set_console(console_index=1) - self.vm.add_args('-bios', file_path) - self.vm.launch() - wait_for_console_pattern(self, 'AMCC PPC405EP Evaluation Board') - exec_command_and_wait_for_pattern(self, 'reset', 'AMCC PowerPC 405EP') - - def test_ppc_ref405ep(self): - """ - :avocado: tags=arch:ppc - :avocado: tags=machine:ref405ep - :avocado: tags=cpu:405ep - :avocado: tags=accel:tcg - """ - self.require_accelerator("tcg") - self.do_test_ppc405() diff --git a/tests/avocado/ppc_74xx.py b/tests/avocado/ppc_74xx.py deleted file mode 100644 index f54757c..0000000 --- a/tests/avocado/ppc_74xx.py +++ /dev/null @@ -1,136 +0,0 @@ -# Smoke tests for 74xx cpus (aka G4). -# -# Copyright (c) 2021, IBM Corp. -# -# This work is licensed under the terms of the GNU GPL, version 2 or -# later. See the COPYING file in the top-level directory. - -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern - -class ppc74xxCpu(QemuSystemTest): - """ - :avocado: tags=arch:ppc - :avocado: tags=accel:tcg - """ - timeout = 5 - - def test_ppc_7400(self): - """ - :avocado: tags=cpu:7400 - """ - self.require_accelerator("tcg") - self.vm.set_console() - self.vm.launch() - wait_for_console_pattern(self, '>> OpenBIOS') - wait_for_console_pattern(self, '>> CPU type PowerPC,G4') - - def test_ppc_7410(self): - """ - :avocado: tags=cpu:7410 - """ - self.require_accelerator("tcg") - self.vm.set_console() - self.vm.launch() - wait_for_console_pattern(self, '>> OpenBIOS') - wait_for_console_pattern(self, '>> CPU type PowerPC,74xx') - - def test_ppc_7441(self): - """ - :avocado: tags=cpu:7441 - """ - self.require_accelerator("tcg") - self.vm.set_console() - self.vm.launch() - wait_for_console_pattern(self, '>> OpenBIOS') - wait_for_console_pattern(self, '>> CPU type PowerPC,G4') - - def test_ppc_7445(self): - """ - :avocado: tags=cpu:7445 - """ - self.require_accelerator("tcg") - self.vm.set_console() - self.vm.launch() - wait_for_console_pattern(self, '>> OpenBIOS') - wait_for_console_pattern(self, '>> CPU type PowerPC,G4') - - def test_ppc_7447(self): - """ - :avocado: tags=cpu:7447 - """ - self.require_accelerator("tcg") - self.vm.set_console() - self.vm.launch() - wait_for_console_pattern(self, '>> OpenBIOS') - wait_for_console_pattern(self, '>> CPU type PowerPC,G4') - - def test_ppc_7447a(self): - """ - :avocado: tags=cpu:7447a - """ - self.require_accelerator("tcg") - self.vm.set_console() - self.vm.launch() - wait_for_console_pattern(self, '>> OpenBIOS') - wait_for_console_pattern(self, '>> CPU type PowerPC,G4') - - def test_ppc_7448(self): - """ - :avocado: tags=cpu:7448 - """ - self.require_accelerator("tcg") - self.vm.set_console() - self.vm.launch() - wait_for_console_pattern(self, '>> OpenBIOS') - wait_for_console_pattern(self, '>> CPU type PowerPC,MPC86xx') - - def test_ppc_7450(self): - """ - :avocado: tags=cpu:7450 - """ - self.require_accelerator("tcg") - self.vm.set_console() - self.vm.launch() - wait_for_console_pattern(self, '>> OpenBIOS') - wait_for_console_pattern(self, '>> CPU type PowerPC,G4') - - def test_ppc_7451(self): - """ - :avocado: tags=cpu:7451 - """ - self.require_accelerator("tcg") - self.vm.set_console() - self.vm.launch() - wait_for_console_pattern(self, '>> OpenBIOS') - wait_for_console_pattern(self, '>> CPU type PowerPC,G4') - - def test_ppc_7455(self): - """ - :avocado: tags=cpu:7455 - """ - self.require_accelerator("tcg") - self.vm.set_console() - self.vm.launch() - wait_for_console_pattern(self, '>> OpenBIOS') - wait_for_console_pattern(self, '>> CPU type PowerPC,G4') - - def test_ppc_7457(self): - """ - :avocado: tags=cpu:7457 - """ - self.require_accelerator("tcg") - self.vm.set_console() - self.vm.launch() - wait_for_console_pattern(self, '>> OpenBIOS') - wait_for_console_pattern(self, '>> CPU type PowerPC,G4') - - def test_ppc_7457a(self): - """ - :avocado: tags=cpu:7457a - """ - self.require_accelerator("tcg") - self.vm.set_console() - self.vm.launch() - wait_for_console_pattern(self, '>> OpenBIOS') - wait_for_console_pattern(self, '>> CPU type PowerPC,G4') diff --git a/tests/avocado/ppc_amiga.py b/tests/avocado/ppc_amiga.py deleted file mode 100644 index b6f866f..0000000 --- a/tests/avocado/ppc_amiga.py +++ /dev/null @@ -1,38 +0,0 @@ -# Test AmigaNG boards -# -# Copyright (c) 2023 BALATON Zoltan -# -# This work is licensed under the terms of the GNU GPL, version 2 or -# later. See the COPYING file in the top-level directory. - -from avocado.utils import archive -from avocado.utils import process -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern - -class AmigaOneMachine(QemuSystemTest): - - timeout = 90 - - def test_ppc_amigaone(self): - """ - :avocado: tags=arch:ppc - :avocado: tags=machine:amigaone - :avocado: tags=device:articia - :avocado: tags=accel:tcg - """ - self.require_accelerator("tcg") - tar_name = 'A1Firmware_Floppy_05-Mar-2005.zip' - tar_url = ('https://www.hyperion-entertainment.com/index.php/' - 'downloads?view=download&format=raw&file=25') - tar_hash = 'c52e59bc73e31d8bcc3cc2106778f7ac84f6c755' - zip_file = self.fetch_asset(tar_name, locations=tar_url, - asset_hash=tar_hash) - archive.extract(zip_file, self.workdir) - cmd = f"tail -c 524288 {self.workdir}/floppy_edition/updater.image >{self.workdir}/u-boot-amigaone.bin" - process.run(cmd, shell=True) - - self.vm.set_console() - self.vm.add_args('-bios', self.workdir + '/u-boot-amigaone.bin') - self.vm.launch() - wait_for_console_pattern(self, 'FLASH:') diff --git a/tests/avocado/ppc_bamboo.py b/tests/avocado/ppc_bamboo.py deleted file mode 100644 index a81be3d..0000000 --- a/tests/avocado/ppc_bamboo.py +++ /dev/null @@ -1,42 +0,0 @@ -# Test that Linux kernel boots on the ppc bamboo board and check the console -# -# Copyright (c) 2021 Red Hat -# -# This work is licensed under the terms of the GNU GPL, version 2 or -# later. See the COPYING file in the top-level directory. - -from avocado.utils import archive -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern -from avocado_qemu import exec_command_and_wait_for_pattern - -class BambooMachine(QemuSystemTest): - - timeout = 90 - - def test_ppc_bamboo(self): - """ - :avocado: tags=arch:ppc - :avocado: tags=machine:bamboo - :avocado: tags=cpu:440epb - :avocado: tags=device:rtl8139 - :avocado: tags=accel:tcg - """ - self.require_accelerator("tcg") - self.require_netdev('user') - tar_url = ('http://landley.net/aboriginal/downloads/binaries/' - 'system-image-powerpc-440fp.tar.gz') - tar_hash = '53e5f16414b195b82d2c70272f81c2eedb39bad9' - file_path = self.fetch_asset(tar_url, asset_hash=tar_hash) - archive.extract(file_path, self.workdir) - self.vm.set_console() - self.vm.add_args('-kernel', self.workdir + - '/system-image-powerpc-440fp/linux', - '-initrd', self.workdir + - '/system-image-powerpc-440fp/rootfs.cpio.gz', - '-nic', 'user,model=rtl8139,restrict=on') - self.vm.launch() - wait_for_console_pattern(self, 'Type exit when done') - exec_command_and_wait_for_pattern(self, 'ping 10.0.2.2', - '10.0.2.2 is alive!') - exec_command_and_wait_for_pattern(self, 'halt', 'System Halted') diff --git a/tests/avocado/ppc_hv_tests.py b/tests/avocado/ppc_hv_tests.py deleted file mode 100644 index bf8822b..0000000 --- a/tests/avocado/ppc_hv_tests.py +++ /dev/null @@ -1,206 +0,0 @@ -# Tests that specifically try to exercise hypervisor features of the -# target machines. powernv supports the Power hypervisor ISA, and -# pseries supports the nested-HV hypervisor spec. -# -# Copyright (c) 2023 IBM Corporation -# -# This work is licensed under the terms of the GNU GPL, version 2 or -# later. See the COPYING file in the top-level directory. - -from avocado import skipIf, skipUnless -from avocado.utils import archive -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern, exec_command -import os -import time -import subprocess -from datetime import datetime - -deps = ["xorriso"] # dependent tools needed in the test setup/box. - -def which(tool): - """ looks up the full path for @tool, returns None if not found - or if @tool does not have executable permissions. - """ - paths=os.getenv('PATH') - for p in paths.split(os.path.pathsep): - p = os.path.join(p, tool) - if os.path.exists(p) and os.access(p, os.X_OK): - return p - return None - -def missing_deps(): - """ returns True if any of the test dependent tools are absent. - """ - for dep in deps: - if which(dep) is None: - return True - return False - -# Alpine is a light weight distro that supports QEMU. These tests boot -# that on the machine then run a QEMU guest inside it in KVM mode, -# that runs the same Alpine distro image. -# QEMU packages are downloaded and installed on each test. That's not a -# large download, but it may be more polite to create qcow2 image with -# QEMU already installed and use that. -# XXX: The order of these tests seems to matter, see git blame. -@skipIf(missing_deps(), 'dependencies (%s) not installed' % ','.join(deps)) -@skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test sometimes gets stuck due to console handling problem') -@skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited') -@skipUnless(os.getenv('SPEED') == 'slow', 'runtime limited') -class HypervisorTest(QemuSystemTest): - - timeout = 1000 - KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 console=hvc0 ' - panic_message = 'Kernel panic - not syncing' - good_message = 'VFS: Cannot open root device' - - def extract_from_iso(self, iso, path): - """ - Extracts a file from an iso file into the test workdir - - :param iso: path to the iso file - :param path: path within the iso file of the file to be extracted - :returns: path of the extracted file - """ - filename = os.path.basename(path) - - cwd = os.getcwd() - os.chdir(self.workdir) - - with open(filename, "w") as outfile: - cmd = "xorriso -osirrox on -indev %s -cpx %s %s" % (iso, path, filename) - subprocess.run(cmd.split(), - stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) - - os.chdir(cwd) - - # Return complete path to extracted file. Because callers to - # extract_from_iso() specify 'path' with a leading slash, it is - # necessary to use os.path.relpath() as otherwise os.path.join() - # interprets it as an absolute path and drops the self.workdir part. - return os.path.normpath(os.path.join(self.workdir, filename)) - - def setUp(self): - super().setUp() - - iso_url = ('https://dl-cdn.alpinelinux.org/alpine/v3.18/releases/ppc64le/alpine-standard-3.18.4-ppc64le.iso') - - # Alpine use sha256 so I recalculated this myself - iso_sha256 = 'c26b8d3e17c2f3f0fed02b4b1296589c2390e6d5548610099af75300edd7b3ff' - iso_path = self.fetch_asset(iso_url, asset_hash=iso_sha256, - algorithm = "sha256") - - self.iso_path = iso_path - self.vmlinuz = self.extract_from_iso(iso_path, '/boot/vmlinuz-lts') - self.initramfs = self.extract_from_iso(iso_path, '/boot/initramfs-lts') - - def do_start_alpine(self): - self.vm.set_console() - kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE - self.vm.add_args("-kernel", self.vmlinuz) - self.vm.add_args("-initrd", self.initramfs) - self.vm.add_args("-smp", "4", "-m", "2g") - self.vm.add_args("-drive", f"file={self.iso_path},format=raw,if=none,id=drive0") - - self.vm.launch() - wait_for_console_pattern(self, 'Welcome to Alpine Linux 3.18') - exec_command(self, 'root') - wait_for_console_pattern(self, 'localhost login:') - wait_for_console_pattern(self, 'You may change this message by editing /etc/motd.') - # If the time is wrong, SSL certificates can fail. - exec_command(self, 'date -s "' + datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S' + '"')) - exec_command(self, 'setup-alpine -qe') - wait_for_console_pattern(self, 'Updating repository indexes... done.') - - def do_stop_alpine(self): - exec_command(self, 'poweroff') - wait_for_console_pattern(self, 'alpine:~#') - self.vm.wait() - - def do_setup_kvm(self): - exec_command(self, 'echo http://dl-cdn.alpinelinux.org/alpine/v3.18/main > /etc/apk/repositories') - wait_for_console_pattern(self, 'alpine:~#') - exec_command(self, 'echo http://dl-cdn.alpinelinux.org/alpine/v3.18/community >> /etc/apk/repositories') - wait_for_console_pattern(self, 'alpine:~#') - exec_command(self, 'apk update') - wait_for_console_pattern(self, 'alpine:~#') - exec_command(self, 'apk add qemu-system-ppc64') - wait_for_console_pattern(self, 'alpine:~#') - exec_command(self, 'modprobe kvm-hv') - wait_for_console_pattern(self, 'alpine:~#') - - # This uses the host's block device as the source file for guest block - # device for install media. This is a bit hacky but allows reuse of the - # iso without having a passthrough filesystem configured. - def do_test_kvm(self, hpt=False): - if hpt: - append = 'disable_radix' - else: - append = '' - exec_command(self, 'qemu-system-ppc64 -nographic -smp 2 -m 1g ' - '-machine pseries,x-vof=on,accel=kvm ' - '-machine cap-cfpc=broken,cap-sbbc=broken,' - 'cap-ibs=broken,cap-ccf-assist=off ' - '-drive file=/dev/nvme0n1,format=raw,readonly=on ' - '-initrd /media/nvme0n1/boot/initramfs-lts ' - '-kernel /media/nvme0n1/boot/vmlinuz-lts ' - '-append \'usbcore.nousb ' + append + '\'') - # Alpine 3.18 kernel seems to crash in XHCI USB driver. - wait_for_console_pattern(self, 'Welcome to Alpine Linux 3.18') - exec_command(self, 'root') - wait_for_console_pattern(self, 'localhost login:') - wait_for_console_pattern(self, 'You may change this message by editing /etc/motd.') - exec_command(self, 'poweroff >& /dev/null') - wait_for_console_pattern(self, 'localhost:~#') - wait_for_console_pattern(self, 'reboot: Power down') - time.sleep(1) - exec_command(self, '') - wait_for_console_pattern(self, 'alpine:~#') - - def test_hv_pseries(self): - """ - :avocado: tags=arch:ppc64 - :avocado: tags=machine:pseries - :avocado: tags=accel:tcg - """ - self.require_accelerator("tcg") - self.vm.add_args("-accel", "tcg,thread=multi") - self.vm.add_args('-device', 'nvme,serial=1234,drive=drive0') - self.vm.add_args("-machine", "x-vof=on,cap-nested-hv=on") - self.do_start_alpine() - self.do_setup_kvm() - self.do_test_kvm() - self.do_stop_alpine() - - def test_hv_pseries_kvm(self): - """ - :avocado: tags=arch:ppc64 - :avocado: tags=machine:pseries - :avocado: tags=accel:kvm - """ - self.require_accelerator("kvm") - self.vm.add_args("-accel", "kvm") - self.vm.add_args('-device', 'nvme,serial=1234,drive=drive0') - self.vm.add_args("-machine", "x-vof=on,cap-nested-hv=on,cap-ccf-assist=off") - self.do_start_alpine() - self.do_setup_kvm() - self.do_test_kvm() - self.do_stop_alpine() - - def test_hv_powernv(self): - """ - :avocado: tags=arch:ppc64 - :avocado: tags=machine:powernv - :avocado: tags=accel:tcg - """ - self.require_accelerator("tcg") - self.vm.add_args("-accel", "tcg,thread=multi") - self.vm.add_args('-device', 'nvme,bus=pcie.2,addr=0x0,serial=1234,drive=drive0', - '-device', 'e1000e,netdev=net0,mac=C0:FF:EE:00:00:02,bus=pcie.0,addr=0x0', - '-netdev', 'user,id=net0,hostfwd=::20022-:22,hostname=alpine') - self.do_start_alpine() - self.do_setup_kvm() - self.do_test_kvm() - self.do_test_kvm(True) - self.do_stop_alpine() diff --git a/tests/avocado/ppc_mpc8544ds.py b/tests/avocado/ppc_mpc8544ds.py deleted file mode 100644 index b599fb1..0000000 --- a/tests/avocado/ppc_mpc8544ds.py +++ /dev/null @@ -1,34 +0,0 @@ -# Test that Linux kernel boots on ppc machines and check the console -# -# Copyright (c) 2018, 2020 Red Hat, Inc. -# -# This work is licensed under the terms of the GNU GPL, version 2 or -# later. See the COPYING file in the top-level directory. - -from avocado.utils import archive -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern - -class Mpc8544dsMachine(QemuSystemTest): - - timeout = 90 - KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 ' - panic_message = 'Kernel panic - not syncing' - - def test_ppc_mpc8544ds(self): - """ - :avocado: tags=arch:ppc - :avocado: tags=machine:mpc8544ds - :avocado: tags=accel:tcg - """ - self.require_accelerator("tcg") - tar_url = ('https://qemu-advcal.gitlab.io' - '/qac-best-of-multiarch/download/day04.tar.xz') - tar_hash = 'f46724d281a9f30fa892d458be7beb7d34dc25f9' - file_path = self.fetch_asset(tar_url, asset_hash=tar_hash) - archive.extract(file_path, self.workdir) - self.vm.set_console() - self.vm.add_args('-kernel', self.workdir + '/creek/creek.bin') - self.vm.launch() - wait_for_console_pattern(self, 'QEMU advent calendar 2020', - self.panic_message) diff --git a/tests/avocado/ppc_powernv.py b/tests/avocado/ppc_powernv.py deleted file mode 100644 index 4342941..0000000 --- a/tests/avocado/ppc_powernv.py +++ /dev/null @@ -1,102 +0,0 @@ -# Test that Linux kernel boots on ppc powernv machines and check the console -# -# Copyright (c) 2018, 2020 Red Hat, Inc. -# -# This work is licensed under the terms of the GNU GPL, version 2 or -# later. See the COPYING file in the top-level directory. - -from avocado.utils import archive -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern - -class powernvMachine(QemuSystemTest): - - timeout = 90 - KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 console=hvc0 ' - panic_message = 'Kernel panic - not syncing' - good_message = 'VFS: Cannot open root device' - - def do_test_linux_boot(self, command_line = KERNEL_COMMON_COMMAND_LINE): - self.require_accelerator("tcg") - kernel_url = ('https://archives.fedoraproject.org/pub/archive' - '/fedora-secondary/releases/29/Everything/ppc64le/os' - '/ppc/ppc64/vmlinuz') - kernel_hash = '3fe04abfc852b66653b8c3c897a59a689270bc77' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - - self.vm.set_console() - self.vm.add_args('-kernel', kernel_path, - '-append', command_line) - self.vm.launch() - - def test_linux_boot(self): - """ - :avocado: tags=arch:ppc64 - :avocado: tags=machine:powernv - :avocado: tags=accel:tcg - """ - - self.do_test_linux_boot() - console_pattern = 'VFS: Cannot open root device' - wait_for_console_pattern(self, console_pattern, self.panic_message) - - def test_linux_smp_boot(self): - """ - :avocado: tags=arch:ppc64 - :avocado: tags=machine:powernv - :avocado: tags=accel:tcg - """ - - self.vm.add_args('-smp', '4') - self.do_test_linux_boot() - console_pattern = 'smp: Brought up 1 node, 4 CPUs' - wait_for_console_pattern(self, console_pattern, self.panic_message) - wait_for_console_pattern(self, self.good_message, self.panic_message) - - def test_linux_smp_hpt_boot(self): - """ - :avocado: tags=arch:ppc64 - :avocado: tags=machine:powernv - :avocado: tags=accel:tcg - """ - - self.vm.add_args('-smp', '4') - self.do_test_linux_boot(self.KERNEL_COMMON_COMMAND_LINE + - 'disable_radix') - console_pattern = 'smp: Brought up 1 node, 4 CPUs' - wait_for_console_pattern(self, 'hash-mmu: Initializing hash mmu', - self.panic_message) - wait_for_console_pattern(self, console_pattern, self.panic_message) - wait_for_console_pattern(self, self.good_message, self.panic_message) - - def test_linux_smt_boot(self): - """ - :avocado: tags=arch:ppc64 - :avocado: tags=machine:powernv - :avocado: tags=accel:tcg - """ - - self.vm.add_args('-smp', '4,threads=4') - self.do_test_linux_boot() - console_pattern = 'CPU maps initialized for 4 threads per core' - wait_for_console_pattern(self, console_pattern, self.panic_message) - console_pattern = 'smp: Brought up 1 node, 4 CPUs' - wait_for_console_pattern(self, console_pattern, self.panic_message) - wait_for_console_pattern(self, self.good_message, self.panic_message) - - def test_linux_big_boot(self): - """ - :avocado: tags=arch:ppc64 - :avocado: tags=machine:powernv - :avocado: tags=accel:tcg - """ - - self.vm.add_args('-smp', '16,threads=4,cores=2,sockets=2') - - # powernv does not support NUMA - self.do_test_linux_boot() - console_pattern = 'CPU maps initialized for 4 threads per core' - wait_for_console_pattern(self, console_pattern, self.panic_message) - console_pattern = 'smp: Brought up 2 nodes, 16 CPUs' - wait_for_console_pattern(self, console_pattern, self.panic_message) - wait_for_console_pattern(self, self.good_message, self.panic_message) diff --git a/tests/avocado/ppc_prep_40p.py b/tests/avocado/ppc_prep_40p.py deleted file mode 100644 index d4f1eb7..0000000 --- a/tests/avocado/ppc_prep_40p.py +++ /dev/null @@ -1,85 +0,0 @@ -# Functional test that boots a PReP/40p machine and checks its serial console. -# -# Copyright (c) Philippe Mathieu-Daudé <f4bug@amsat.org> -# -# 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 skipUnless -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern - - -class IbmPrep40pMachine(QemuSystemTest): - - timeout = 60 - - # 12H0455 PPS Firmware Licensed Materials - # Property of IBM (C) Copyright IBM Corp. 1994. - # All rights reserved. - # U.S. Government Users Restricted Rights - Use, duplication or disclosure - # restricted by GSA ADP Schedule Contract with IBM Corp. - @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code') - def test_factory_firmware_and_netbsd(self): - """ - :avocado: tags=arch:ppc - :avocado: tags=machine:40p - :avocado: tags=os:netbsd - :avocado: tags=slowness:high - :avocado: tags=accel:tcg - """ - self.require_accelerator("tcg") - bios_url = ('http://ftpmirror.your.org/pub/misc/' - 'ftp.software.ibm.com/rs6000/firmware/' - '7020-40p/P12H0456.IMG') - bios_hash = '1775face4e6dc27f3a6ed955ef6eb331bf817f03' - bios_path = self.fetch_asset(bios_url, asset_hash=bios_hash) - drive_url = ('https://archive.netbsd.org/pub/NetBSD-archive/' - 'NetBSD-4.0/prep/installation/floppy/generic_com0.fs') - drive_hash = 'dbcfc09912e71bd5f0d82c7c1ee43082fb596ceb' - drive_path = self.fetch_asset(drive_url, asset_hash=drive_hash) - - self.vm.set_console() - self.vm.add_args('-bios', bios_path, - '-fda', drive_path) - self.vm.launch() - os_banner = 'NetBSD 4.0 (GENERIC) #0: Sun Dec 16 00:49:40 PST 2007' - wait_for_console_pattern(self, os_banner) - wait_for_console_pattern(self, 'Model: IBM PPS Model 6015') - - def test_openbios_192m(self): - """ - :avocado: tags=arch:ppc - :avocado: tags=machine:40p - :avocado: tags=accel:tcg - """ - self.require_accelerator("tcg") - self.vm.set_console() - self.vm.add_args('-m', '192') # test fw_cfg - - self.vm.launch() - wait_for_console_pattern(self, '>> OpenBIOS') - wait_for_console_pattern(self, '>> Memory: 192M') - wait_for_console_pattern(self, '>> CPU type PowerPC,604') - - def test_openbios_and_netbsd(self): - """ - :avocado: tags=arch:ppc - :avocado: tags=machine:40p - :avocado: tags=os:netbsd - :avocado: tags=accel:tcg - """ - self.require_accelerator("tcg") - drive_url = ('https://archive.netbsd.org/pub/NetBSD-archive/' - 'NetBSD-7.1.2/iso/NetBSD-7.1.2-prep.iso') - drive_hash = 'ac6fa2707d888b36d6fa64de6e7fe48e' - drive_path = self.fetch_asset(drive_url, asset_hash=drive_hash, - algorithm='md5') - self.vm.set_console() - self.vm.add_args('-cdrom', drive_path, - '-boot', 'd') - - self.vm.launch() - wait_for_console_pattern(self, 'NetBSD/prep BOOT, Revision 1.9') diff --git a/tests/avocado/ppc_pseries.py b/tests/avocado/ppc_pseries.py deleted file mode 100644 index 74aaa4a..0000000 --- a/tests/avocado/ppc_pseries.py +++ /dev/null @@ -1,110 +0,0 @@ -# Test that Linux kernel boots on ppc machines and check the console -# -# Copyright (c) 2018, 2020 Red Hat, Inc. -# -# This work is licensed under the terms of the GNU GPL, version 2 or -# later. See the COPYING file in the top-level directory. - -from avocado.utils import archive -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern - -class pseriesMachine(QemuSystemTest): - - timeout = 90 - KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 console=hvc0 ' - panic_message = 'Kernel panic - not syncing' - good_message = 'VFS: Cannot open root device' - - def do_test_ppc64_linux_boot(self, kernel_command_line = KERNEL_COMMON_COMMAND_LINE): - kernel_url = ('https://archives.fedoraproject.org/pub/archive' - '/fedora-secondary/releases/29/Everything/ppc64le/os' - '/ppc/ppc64/vmlinuz') - kernel_hash = '3fe04abfc852b66653b8c3c897a59a689270bc77' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - - self.vm.set_console() - self.vm.add_args('-kernel', kernel_path, - '-append', kernel_command_line) - self.vm.launch() - - def test_ppc64_vof_linux_boot(self): - """ - :avocado: tags=arch:ppc64 - :avocado: tags=machine:pseries - """ - - self.vm.add_args('-machine', 'x-vof=on') - self.do_test_ppc64_linux_boot() - console_pattern = 'VFS: Cannot open root device' - wait_for_console_pattern(self, console_pattern, self.panic_message) - - def test_ppc64_linux_boot(self): - """ - :avocado: tags=arch:ppc64 - :avocado: tags=machine:pseries - """ - - self.do_test_ppc64_linux_boot() - console_pattern = 'VFS: Cannot open root device' - wait_for_console_pattern(self, console_pattern, self.panic_message) - - def test_ppc64_linux_smp_boot(self): - """ - :avocado: tags=arch:ppc64 - :avocado: tags=machine:pseries - """ - - self.vm.add_args('-smp', '4') - self.do_test_ppc64_linux_boot() - console_pattern = 'smp: Brought up 1 node, 4 CPUs' - wait_for_console_pattern(self, console_pattern, self.panic_message) - wait_for_console_pattern(self, self.good_message, self.panic_message) - - def test_ppc64_linux_hpt_smp_boot(self): - """ - :avocado: tags=arch:ppc64 - :avocado: tags=machine:pseries - """ - - self.vm.add_args('-smp', '4') - self.do_test_ppc64_linux_boot(self.KERNEL_COMMON_COMMAND_LINE + - 'disable_radix') - console_pattern = 'smp: Brought up 1 node, 4 CPUs' - wait_for_console_pattern(self, 'hash-mmu: Initializing hash mmu', - self.panic_message) - wait_for_console_pattern(self, console_pattern, self.panic_message) - wait_for_console_pattern(self, self.good_message, self.panic_message) - - def test_ppc64_linux_smt_boot(self): - """ - :avocado: tags=arch:ppc64 - :avocado: tags=machine:pseries - """ - - self.vm.add_args('-smp', '4,threads=4') - self.do_test_ppc64_linux_boot() - console_pattern = 'CPU maps initialized for 4 threads per core' - wait_for_console_pattern(self, console_pattern, self.panic_message) - console_pattern = 'smp: Brought up 1 node, 4 CPUs' - wait_for_console_pattern(self, console_pattern, self.panic_message) - wait_for_console_pattern(self, self.good_message, self.panic_message) - - def test_ppc64_linux_big_boot(self): - """ - :avocado: tags=arch:ppc64 - :avocado: tags=machine:pseries - """ - - self.vm.add_args('-smp', '16,threads=4,cores=2,sockets=2') - self.vm.add_args('-m', '512M', - '-object', 'memory-backend-ram,size=256M,id=m0', - '-object', 'memory-backend-ram,size=256M,id=m1') - self.vm.add_args('-numa', 'node,nodeid=0,memdev=m0') - self.vm.add_args('-numa', 'node,nodeid=1,memdev=m1') - self.do_test_ppc64_linux_boot() - console_pattern = 'CPU maps initialized for 4 threads per core' - wait_for_console_pattern(self, console_pattern, self.panic_message) - console_pattern = 'smp: Brought up 2 nodes, 16 CPUs' - wait_for_console_pattern(self, console_pattern, self.panic_message) - wait_for_console_pattern(self, self.good_message, self.panic_message) diff --git a/tests/avocado/ppc_virtex_ml507.py b/tests/avocado/ppc_virtex_ml507.py deleted file mode 100644 index a73f8ae..0000000 --- a/tests/avocado/ppc_virtex_ml507.py +++ /dev/null @@ -1,36 +0,0 @@ -# Test that Linux kernel boots on ppc machines and check the console -# -# Copyright (c) 2018, 2020 Red Hat, Inc. -# -# This work is licensed under the terms of the GNU GPL, version 2 or -# later. See the COPYING file in the top-level directory. - -from avocado.utils import archive -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern - -class VirtexMl507Machine(QemuSystemTest): - - timeout = 90 - KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 ' - panic_message = 'Kernel panic - not syncing' - - def test_ppc_virtex_ml507(self): - """ - :avocado: tags=arch:ppc - :avocado: tags=machine:virtex-ml507 - :avocado: tags=accel:tcg - """ - self.require_accelerator("tcg") - tar_url = ('https://qemu-advcal.gitlab.io' - '/qac-best-of-multiarch/download/day08.tar.xz') - tar_hash = '74c68f5af7a7b8f21c03097b298f3bb77ff52c1f' - file_path = self.fetch_asset(tar_url, asset_hash=tar_hash) - archive.extract(file_path, self.workdir) - self.vm.set_console() - self.vm.add_args('-kernel', self.workdir + '/hippo/hippo.linux', - '-dtb', self.workdir + '/hippo/virtex440-ml507.dtb', - '-m', '512') - self.vm.launch() - wait_for_console_pattern(self, 'QEMU advent calendar 2020', - self.panic_message) diff --git a/tests/avocado/replay_kernel.py b/tests/avocado/replay_kernel.py deleted file mode 100644 index 232d287..0000000 --- a/tests/avocado/replay_kernel.py +++ /dev/null @@ -1,550 +0,0 @@ -# Record/replay test that boots a Linux kernel -# -# Copyright (c) 2020 ISP RAS -# -# Author: -# Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru> -# -# 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 -import lzma -import shutil -import logging -import time - -from avocado import skip -from avocado import skipUnless -from avocado import skipUnless -from avocado_qemu import wait_for_console_pattern -from avocado.utils import archive -from avocado.utils import process -from boot_linux_console import LinuxKernelTest - -class ReplayKernelBase(LinuxKernelTest): - """ - Boots a Linux kernel in record mode and checks that the console - is operational and the kernel command line is properly passed - from QEMU to the kernel. - Then replays the same scenario and verifies, that QEMU correctly - terminates. - """ - - timeout = 120 - KERNEL_COMMON_COMMAND_LINE = 'printk.time=1 panic=-1 ' - - def run_vm(self, kernel_path, kernel_command_line, console_pattern, - record, shift, args, replay_path): - # icount requires TCG to be available - self.require_accelerator('tcg') - - logger = logging.getLogger('replay') - start_time = time.time() - vm = self.get_vm() - vm.set_console() - if record: - logger.info('recording the execution...') - mode = 'record' - else: - logger.info('replaying the execution...') - mode = 'replay' - vm.add_args('-icount', 'shift=%s,rr=%s,rrfile=%s' % - (shift, mode, replay_path), - '-kernel', kernel_path, - '-append', kernel_command_line, - '-net', 'none', - '-no-reboot') - if args: - vm.add_args(*args) - vm.launch() - self.wait_for_console_pattern(console_pattern, vm) - if record: - vm.shutdown() - logger.info('finished the recording with log size %s bytes' - % os.path.getsize(replay_path)) - else: - vm.wait() - logger.info('successfully finished the replay') - elapsed = time.time() - start_time - logger.info('elapsed time %.2f sec' % elapsed) - return elapsed - - def run_rr(self, kernel_path, kernel_command_line, console_pattern, - shift=7, args=None): - replay_path = os.path.join(self.workdir, 'replay.bin') - t1 = self.run_vm(kernel_path, kernel_command_line, console_pattern, - True, shift, args, replay_path) - t2 = self.run_vm(kernel_path, kernel_command_line, console_pattern, - False, shift, args, replay_path) - logger = logging.getLogger('replay') - logger.info('replay overhead {:.2%}'.format(t2 / t1 - 1)) - -class ReplayKernelNormal(ReplayKernelBase): - - def test_i386_pc(self): - """ - :avocado: tags=arch:i386 - :avocado: tags=machine:pc - """ - kernel_url = ('https://storage.tuxboot.com/20230331/i386/bzImage') - kernel_hash = 'a3e5b32a354729e65910f5a1ffcda7c14a6c12a55e8213fb86e277f1b76ed956' - kernel_path = self.fetch_asset(kernel_url, - asset_hash=kernel_hash, - algorithm = "sha256") - - kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0' - console_pattern = 'VFS: Cannot open root device' - - self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5) - - # See https://gitlab.com/qemu-project/qemu/-/issues/2094 - @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test sometimes gets stuck') - def test_x86_64_pc(self): - """ - :avocado: tags=arch:x86_64 - :avocado: tags=machine:pc - :avocado: tags=flaky - """ - kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora' - '/linux/releases/29/Everything/x86_64/os/images/pxeboot' - '/vmlinuz') - kernel_hash = '23bebd2680757891cf7adedb033532163a792495' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - - kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0' - console_pattern = 'VFS: Cannot open root device' - - self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5) - - def test_mips_malta(self): - """ - :avocado: tags=arch:mips - :avocado: tags=machine:malta - :avocado: tags=endian:big - """ - deb_url = ('http://snapshot.debian.org/archive/debian/' - '20130217T032700Z/pool/main/l/linux-2.6/' - 'linux-image-2.6.32-5-4kc-malta_2.6.32-48_mips.deb') - deb_hash = 'a8cfc28ad8f45f54811fc6cf74fc43ffcfe0ba04' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) - kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinux-2.6.32-5-4kc-malta') - kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0' - console_pattern = 'Kernel command line: %s' % kernel_command_line - - self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5) - - def test_mips64el_malta(self): - """ - This test requires the ar tool to extract "data.tar.gz" from - the Debian package. - - The kernel can be rebuilt using this Debian kernel source [1] and - following the instructions on [2]. - - [1] http://snapshot.debian.org/package/linux-2.6/2.6.32-48/ - #linux-source-2.6.32_2.6.32-48 - [2] https://kernel-team.pages.debian.net/kernel-handbook/ - ch-common-tasks.html#s-common-official - - :avocado: tags=arch:mips64el - :avocado: tags=machine:malta - """ - deb_url = ('http://snapshot.debian.org/archive/debian/' - '20130217T032700Z/pool/main/l/linux-2.6/' - 'linux-image-2.6.32-5-5kc-malta_2.6.32-48_mipsel.deb') - deb_hash = '1aaec92083bf22fda31e0d27fa8d9a388e5fc3d5' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) - kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinux-2.6.32-5-5kc-malta') - kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0' - console_pattern = 'Kernel command line: %s' % kernel_command_line - self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5) - - def test_aarch64_virt(self): - """ - :avocado: tags=arch:aarch64 - :avocado: tags=machine:virt - :avocado: tags=cpu:cortex-a53 - """ - kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora' - '/linux/releases/29/Everything/aarch64/os/images/pxeboot' - '/vmlinuz') - kernel_hash = '8c73e469fc6ea06a58dc83a628fc695b693b8493' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=ttyAMA0') - console_pattern = 'VFS: Cannot open root device' - - self.run_rr(kernel_path, kernel_command_line, console_pattern) - - def test_arm_virt(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:virt - """ - kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora' - '/linux/releases/29/Everything/armhfp/os/images/pxeboot' - '/vmlinuz') - kernel_hash = 'e9826d741b4fb04cadba8d4824d1ed3b7fb8b4d4' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=ttyAMA0') - console_pattern = 'VFS: Cannot open root device' - - self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=1) - - def test_arm_cubieboard_initrd(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:cubieboard - """ - deb_url = ('https://apt.armbian.com/pool/main/l/' - 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb') - deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) - kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinuz-6.6.16-current-sunxi') - dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun4i-a10-cubieboard.dtb' - dtb_path = self.extract_from_deb(deb_path, dtb_path) - initrd_url = ('https://github.com/groeck/linux-build-test/raw/' - '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/' - 'arm/rootfs-armv5.cpio.gz') - initrd_hash = '2b50f1873e113523967806f4da2afe385462ff9b' - initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash) - initrd_path = os.path.join(self.workdir, 'rootfs.cpio') - archive.gzip_uncompress(initrd_path_gz, initrd_path) - - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=ttyS0,115200 ' - 'usbcore.nousb ' - 'panic=-1 noreboot') - console_pattern = 'Boot successful.' - self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=1, - args=('-dtb', dtb_path, - '-initrd', initrd_path, - '-no-reboot')) - - def test_s390x_s390_ccw_virtio(self): - """ - :avocado: tags=arch:s390x - :avocado: tags=machine:s390-ccw-virtio - """ - kernel_url = ('https://archives.fedoraproject.org/pub/archive' - '/fedora-secondary/releases/29/Everything/s390x/os/images' - '/kernel.img') - kernel_hash = 'e8e8439103ef8053418ef062644ffd46a7919313' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - - kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=sclp0' - console_pattern = 'Kernel command line: %s' % kernel_command_line - self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=9) - - def test_alpha_clipper(self): - """ - :avocado: tags=arch:alpha - :avocado: tags=machine:clipper - """ - kernel_url = ('http://archive.debian.org/debian/dists/lenny/main/' - 'installer-alpha/20090123lenny10/images/cdrom/vmlinuz') - kernel_hash = '3a943149335529e2ed3e74d0d787b85fb5671ba3' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - - uncompressed_kernel = archive.uncompress(kernel_path, self.workdir) - - kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0' - console_pattern = 'Kernel command line: %s' % kernel_command_line - self.run_rr(uncompressed_kernel, kernel_command_line, console_pattern, shift=9, - args=('-nodefaults', )) - - def test_ppc64_pseries(self): - """ - :avocado: tags=arch:ppc64 - :avocado: tags=machine:pseries - :avocado: tags=accel:tcg - """ - kernel_url = ('https://archives.fedoraproject.org/pub/archive' - '/fedora-secondary/releases/29/Everything/ppc64le/os' - '/ppc/ppc64/vmlinuz') - kernel_hash = '3fe04abfc852b66653b8c3c897a59a689270bc77' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - - kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=hvc0' - console_pattern = 'VFS: Cannot open root device' - self.run_rr(kernel_path, kernel_command_line, console_pattern) - - def test_ppc64_powernv(self): - """ - :avocado: tags=arch:ppc64 - :avocado: tags=machine:powernv - :avocado: tags=accel:tcg - """ - kernel_url = ('https://archives.fedoraproject.org/pub/archive' - '/fedora-secondary/releases/29/Everything/ppc64le/os' - '/ppc/ppc64/vmlinuz') - kernel_hash = '3fe04abfc852b66653b8c3c897a59a689270bc77' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - - kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + \ - 'console=tty0 console=hvc0' - console_pattern = 'VFS: Cannot open root device' - self.run_rr(kernel_path, kernel_command_line, console_pattern) - - def test_m68k_q800(self): - """ - :avocado: tags=arch:m68k - :avocado: tags=machine:q800 - """ - deb_url = ('https://snapshot.debian.org/archive/debian-ports' - '/20191021T083923Z/pool-m68k/main' - '/l/linux/kernel-image-5.3.0-1-m68k-di_5.3.7-1_m68k.udeb') - deb_hash = '044954bb9be4160a3ce81f8bc1b5e856b75cccd1' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) - kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinux-5.3.0-1-m68k') - - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=ttyS0 vga=off') - console_pattern = 'No filesystem could mount root' - self.run_rr(kernel_path, kernel_command_line, console_pattern) - - def do_test_advcal_2018(self, file_path, kernel_name, args=None): - archive.extract(file_path, self.workdir) - - for entry in os.scandir(self.workdir): - if entry.name.startswith('day') and entry.is_dir(): - kernel_path = os.path.join(entry.path, kernel_name) - break - - kernel_command_line = '' - console_pattern = 'QEMU advent calendar' - self.run_rr(kernel_path, kernel_command_line, console_pattern, - args=args) - - def test_arm_vexpressa9(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:vexpress-a9 - """ - tar_hash = '32b7677ce8b6f1471fb0059865f451169934245b' - tar_url = ('https://qemu-advcal.gitlab.io' - '/qac-best-of-multiarch/download/day16.tar.xz') - file_path = self.fetch_asset(tar_url, asset_hash=tar_hash) - dtb_path = self.workdir + '/day16/vexpress-v2p-ca9.dtb' - self.do_test_advcal_2018(file_path, 'winter.zImage', - args=('-dtb', dtb_path)) - - def test_m68k_mcf5208evb(self): - """ - :avocado: tags=arch:m68k - :avocado: tags=machine:mcf5208evb - """ - tar_hash = 'ac688fd00561a2b6ce1359f9ff6aa2b98c9a570c' - tar_url = ('https://qemu-advcal.gitlab.io' - '/qac-best-of-multiarch/download/day07.tar.xz') - file_path = self.fetch_asset(tar_url, asset_hash=tar_hash) - self.do_test_advcal_2018(file_path, 'sanity-clause.elf') - - def test_microblaze_s3adsp1800(self): - """ - :avocado: tags=arch:microblaze - :avocado: tags=machine:petalogix-s3adsp1800 - """ - tar_hash = '08bf3e3bfb6b6c7ce1e54ab65d54e189f2caf13f' - tar_url = ('https://qemu-advcal.gitlab.io' - '/qac-best-of-multiarch/download/day17.tar.xz') - file_path = self.fetch_asset(tar_url, asset_hash=tar_hash) - self.do_test_advcal_2018(file_path, 'ballerina.bin') - - def test_ppc64_e500(self): - """ - :avocado: tags=arch:ppc64 - :avocado: tags=machine:ppce500 - :avocado: tags=cpu:e5500 - """ - tar_hash = '6951d86d644b302898da2fd701739c9406527fe1' - tar_url = ('https://qemu-advcal.gitlab.io' - '/qac-best-of-multiarch/download/day19.tar.xz') - file_path = self.fetch_asset(tar_url, asset_hash=tar_hash) - self.do_test_advcal_2018(file_path, 'uImage') - - def test_or1k_sim(self): - """ - :avocado: tags=arch:or1k - :avocado: tags=machine:or1k-sim - """ - tar_hash = '20334cdaf386108c530ff0badaecc955693027dd' - tar_url = ('https://qemu-advcal.gitlab.io' - '/qac-best-of-multiarch/download/day20.tar.xz') - file_path = self.fetch_asset(tar_url, asset_hash=tar_hash) - self.do_test_advcal_2018(file_path, 'vmlinux') - - def test_ppc_g3beige(self): - """ - :avocado: tags=arch:ppc - :avocado: tags=machine:g3beige - """ - tar_hash = 'e0b872a5eb8fdc5bed19bd43ffe863900ebcedfc' - tar_url = ('https://qemu-advcal.gitlab.io' - '/qac-best-of-multiarch/download/day15.tar.xz') - file_path = self.fetch_asset(tar_url, asset_hash=tar_hash) - self.do_test_advcal_2018(file_path, 'invaders.elf', - args=('-M', 'graphics=off')) - - def test_ppc_mac99(self): - """ - :avocado: tags=arch:ppc - :avocado: tags=machine:mac99 - """ - tar_hash = 'e0b872a5eb8fdc5bed19bd43ffe863900ebcedfc' - tar_url = ('https://qemu-advcal.gitlab.io' - '/qac-best-of-multiarch/download/day15.tar.xz') - file_path = self.fetch_asset(tar_url, asset_hash=tar_hash) - self.do_test_advcal_2018(file_path, 'invaders.elf', - args=('-M', 'graphics=off')) - - def test_sparc_ss20(self): - """ - :avocado: tags=arch:sparc - :avocado: tags=machine:SS-20 - """ - tar_hash = 'b18550d5d61c7615d989a06edace051017726a9f' - tar_url = ('https://qemu-advcal.gitlab.io' - '/qac-best-of-multiarch/download/day11.tar.xz') - file_path = self.fetch_asset(tar_url, asset_hash=tar_hash) - self.do_test_advcal_2018(file_path, 'zImage.elf') - - def test_xtensa_lx60(self): - """ - :avocado: tags=arch:xtensa - :avocado: tags=machine:lx60 - :avocado: tags=cpu:dc233c - """ - tar_hash = '49e88d9933742f0164b60839886c9739cb7a0d34' - tar_url = ('https://qemu-advcal.gitlab.io' - '/qac-best-of-multiarch/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') - -@skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout') -class ReplayKernelSlow(ReplayKernelBase): - # Override the timeout, because this kernel includes an inner - # loop which is executed with TB recompilings during replay, - # making it very slow. - timeout = 180 - - def test_mips_malta_cpio(self): - """ - :avocado: tags=arch:mips - :avocado: tags=machine:malta - :avocado: tags=endian:big - :avocado: tags=slowness:high - """ - deb_url = ('http://snapshot.debian.org/archive/debian/' - '20160601T041800Z/pool/main/l/linux/' - 'linux-image-4.5.0-2-4kc-malta_4.5.5-1_mips.deb') - deb_hash = 'a3c84f3e88b54e06107d65a410d1d1e8e0f340f8' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) - kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinux-4.5.0-2-4kc-malta') - initrd_url = ('https://github.com/groeck/linux-build-test/raw/' - '8584a59ed9e5eb5ee7ca91f6d74bbb06619205b8/rootfs/' - 'mips/rootfs.cpio.gz') - initrd_hash = 'bf806e17009360a866bf537f6de66590de349a99' - initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash) - initrd_path = self.workdir + "rootfs.cpio" - archive.gzip_uncompress(initrd_path_gz, initrd_path) - - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=ttyS0 console=tty ' - 'rdinit=/sbin/init noreboot') - console_pattern = 'Boot successful.' - self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5, - args=('-initrd', initrd_path)) - - @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code') - def test_mips64el_malta_5KEc_cpio(self): - """ - :avocado: tags=arch:mips64el - :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/' - 'vmlinux-3.19.3.mtoman.20150408') - kernel_hash = '00d1d268fb9f7d8beda1de6bebcc46e884d71754' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - initrd_url = ('https://github.com/groeck/linux-build-test/' - 'raw/8584a59e/rootfs/' - 'mipsel64/rootfs.mipsel64r1.cpio.gz') - initrd_hash = '1dbb8a396e916847325284dbe2151167' - initrd_path_gz = self.fetch_asset(initrd_url, algorithm='md5', - asset_hash=initrd_hash) - initrd_path = self.workdir + "rootfs.cpio" - archive.gzip_uncompress(initrd_path_gz, initrd_path) - - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=ttyS0 console=tty ' - 'rdinit=/sbin/init noreboot') - console_pattern = 'Boot successful.' - self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5, - args=('-initrd', initrd_path)) - - def do_test_mips_malta32el_nanomips(self, kernel_path_xz): - kernel_path = self.workdir + "kernel" - with lzma.open(kernel_path_xz, 'rb') as f_in: - with open(kernel_path, 'wb') as f_out: - shutil.copyfileobj(f_in, f_out) - - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - '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) - - 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 = ('http://mipsdistros.mips.com/LinuxDistro/nanomips/' - 'kernels/v4.15.18-432-gb2eb9a8b07a1-20180627102142/' - 'generic_nano32r6el_page4k.xz') - kernel_hash = '477456aafd2a0f1ddc9482727f20fe9575565dd6' - kernel_path_xz = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - self.do_test_mips_malta32el_nanomips(kernel_path_xz) - - def test_mips_malta32el_nanomips_16k_up(self): - """ - :avocado: tags=arch:mipsel - :avocado: tags=machine:malta - :avocado: tags=endian:little - :avocado: tags=cpu:I7200 - """ - kernel_url = ('http://mipsdistros.mips.com/LinuxDistro/nanomips/' - 'kernels/v4.15.18-432-gb2eb9a8b07a1-20180627102142/' - 'generic_nano32r6el_page16k_up.xz') - kernel_hash = 'e882868f944c71c816e832e2303b7874d044a7bc' - kernel_path_xz = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - self.do_test_mips_malta32el_nanomips(kernel_path_xz) - - def test_mips_malta32el_nanomips_64k_dbg(self): - """ - :avocado: tags=arch:mipsel - :avocado: tags=machine:malta - :avocado: tags=endian:little - :avocado: tags=cpu:I7200 - """ - kernel_url = ('http://mipsdistros.mips.com/LinuxDistro/nanomips/' - 'kernels/v4.15.18-432-gb2eb9a8b07a1-20180627102142/' - 'generic_nano32r6el_page64k_dbg.xz') - kernel_hash = '18d1c68f2e23429e266ca39ba5349ccd0aeb7180' - kernel_path_xz = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - self.do_test_mips_malta32el_nanomips(kernel_path_xz) diff --git a/tests/avocado/replay_linux.py b/tests/avocado/replay_linux.py deleted file mode 100644 index f3a43dc..0000000 --- a/tests/avocado/replay_linux.py +++ /dev/null @@ -1,196 +0,0 @@ -# Record/replay test that boots a complete Linux system via a cloud image -# -# Copyright (c) 2020 ISP RAS -# -# Author: -# Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru> -# -# 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 -import logging -import time - -from avocado import skipUnless -from avocado_qemu import BUILD_DIR -from avocado.utils import cloudinit -from avocado.utils import network -from avocado.utils import vmimage -from avocado.utils import datadrainer -from avocado.utils.path import find_command -from avocado_qemu import LinuxTest - -class ReplayLinux(LinuxTest): - """ - Boots a Linux system, checking for a successful initialization - """ - - timeout = 1800 - chksum = None - hdd = 'ide-hd' - cd = 'ide-cd' - bus = 'ide' - - def setUp(self): - # LinuxTest does many replay-incompatible things, but includes - # useful methods. Do not setup LinuxTest here and just - # call some functions. - super(LinuxTest, self).setUp() - self._set_distro() - self.boot_path = self.download_boot() - self.phone_server = cloudinit.PhoneHomeServer(('0.0.0.0', 0), - self.name) - ssh_pubkey, self.ssh_key = self.set_up_existing_ssh_keys() - self.cloudinit_path = self.prepare_cloudinit(ssh_pubkey) - - def vm_add_disk(self, vm, path, id, device): - bus_string = '' - if self.bus: - bus_string = ',bus=%s.%d' % (self.bus, id,) - vm.add_args('-drive', 'file=%s,snapshot=on,id=disk%s,if=none' % (path, id)) - vm.add_args('-drive', - 'driver=blkreplay,id=disk%s-rr,if=none,image=disk%s' % (id, id)) - vm.add_args('-device', - '%s,drive=disk%s-rr%s' % (device, id, bus_string)) - - def vm_add_cdrom(self, vm, path, id, device): - vm.add_args('-drive', 'file=%s,id=disk%s,if=none,media=cdrom' % (path, id)) - - def launch_and_wait(self, record, args, shift): - self.require_netdev('user') - vm = self.get_vm() - vm.add_args('-smp', '1') - vm.add_args('-m', '1024') - vm.add_args('-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22', - '-device', 'virtio-net,netdev=vnet') - vm.add_args('-object', 'filter-replay,id=replay,netdev=vnet') - if args: - vm.add_args(*args) - self.vm_add_disk(vm, self.boot_path, 0, self.hdd) - self.vm_add_cdrom(vm, self.cloudinit_path, 1, self.cd) - logger = logging.getLogger('replay') - if record: - logger.info('recording the execution...') - mode = 'record' - else: - logger.info('replaying the execution...') - mode = 'replay' - replay_path = os.path.join(self.workdir, 'replay.bin') - vm.add_args('-icount', 'shift=%s,rr=%s,rrfile=%s' % - (shift, mode, replay_path)) - - start_time = time.time() - - vm.set_console() - vm.launch() - console_drainer = datadrainer.LineLogger(vm.console_socket.fileno(), - logger=self.log.getChild('console'), - stop_check=(lambda : not vm.is_running())) - console_drainer.start() - if record: - while not self.phone_server.instance_phoned_back: - self.phone_server.handle_request() - vm.shutdown() - logger.info('finished the recording with log size %s bytes' - % os.path.getsize(replay_path)) - else: - vm.event_wait('SHUTDOWN', self.timeout) - vm.wait() - logger.info('successfully finished the replay') - elapsed = time.time() - start_time - logger.info('elapsed time %.2f sec' % elapsed) - return elapsed - - def run_rr(self, args=None, shift=7): - t1 = self.launch_and_wait(True, args, shift) - t2 = self.launch_and_wait(False, args, shift) - logger = logging.getLogger('replay') - logger.info('replay overhead {:.2%}'.format(t2 / t1 - 1)) - -@skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout') -class ReplayLinuxX8664(ReplayLinux): - """ - :avocado: tags=arch:x86_64 - :avocado: tags=accel:tcg - """ - - chksum = 'e3c1b309d9203604922d6e255c2c5d098a309c2d46215d8fc026954f3c5c27a0' - - def test_pc_i440fx(self): - """ - :avocado: tags=machine:pc - """ - self.run_rr(shift=1) - - def test_pc_q35(self): - """ - :avocado: tags=machine:q35 - """ - self.run_rr(shift=3) - -@skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout') -class ReplayLinuxX8664Virtio(ReplayLinux): - """ - :avocado: tags=arch:x86_64 - :avocado: tags=virtio - :avocado: tags=accel:tcg - """ - - hdd = 'virtio-blk-pci' - cd = 'virtio-blk-pci' - bus = None - - chksum = 'e3c1b309d9203604922d6e255c2c5d098a309c2d46215d8fc026954f3c5c27a0' - - def test_pc_i440fx(self): - """ - :avocado: tags=machine:pc - """ - self.run_rr(shift=1) - - def test_pc_q35(self): - """ - :avocado: tags=machine:q35 - """ - self.run_rr(shift=3) - -@skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout') -class ReplayLinuxAarch64(ReplayLinux): - """ - :avocado: tags=accel:tcg - :avocado: tags=arch:aarch64 - :avocado: tags=machine:virt - :avocado: tags=cpu:max - """ - - chksum = '1e18d9c0cf734940c4b5d5ec592facaed2af0ad0329383d5639c997fdf16fe49' - - hdd = 'virtio-blk-device' - cd = 'virtio-blk-device' - bus = None - - def get_common_args(self): - return ('-bios', - os.path.join(BUILD_DIR, 'pc-bios', 'edk2-aarch64-code.fd'), - "-cpu", "max,lpa2=off", - '-device', 'virtio-rng-pci,rng=rng0', - '-object', 'rng-builtin,id=rng0') - - def test_virt_gicv2(self): - """ - :avocado: tags=machine:gic-version=2 - """ - - self.run_rr(shift=3, - args=(*self.get_common_args(), - "-machine", "virt,gic-version=2")) - - def test_virt_gicv3(self): - """ - :avocado: tags=machine:gic-version=3 - """ - - self.run_rr(shift=3, - args=(*self.get_common_args(), - "-machine", "virt,gic-version=3")) diff --git a/tests/avocado/reverse_debugging.py b/tests/avocado/reverse_debugging.py deleted file mode 100644 index 92855a0..0000000 --- a/tests/avocado/reverse_debugging.py +++ /dev/null @@ -1,276 +0,0 @@ -# Reverse debugging test -# -# Copyright (c) 2020 ISP RAS -# -# Author: -# Pavel Dovgalyuk <Pavel.Dovgalyuk@ispras.ru> -# -# 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 -import logging - -from avocado import skipUnless -from avocado_qemu import BUILD_DIR -from avocado.utils import datadrainer -from avocado.utils import gdb -from avocado.utils import process -from avocado.utils.network.ports import find_free_port -from avocado.utils.path import find_command -from boot_linux_console import LinuxKernelTest - -class ReverseDebugging(LinuxKernelTest): - """ - Test GDB reverse debugging commands: reverse step and reverse continue. - Recording saves the execution of some instructions and makes an initial - VM snapshot to allow reverse execution. - Replay saves the order of the first instructions and then checks that they - are executed backwards in the correct order. - After that the execution is replayed to the end, and reverse continue - command is checked by setting several breakpoints, and asserting - that the execution is stopped at the last of them. - """ - - timeout = 10 - STEPS = 10 - endian_is_le = True - - def run_vm(self, record, shift, args, replay_path, image_path, port): - logger = logging.getLogger('replay') - vm = self.get_vm() - vm.set_console() - if record: - logger.info('recording the execution...') - mode = 'record' - else: - logger.info('replaying the execution...') - mode = 'replay' - vm.add_args('-gdb', 'tcp::%d' % port, '-S') - vm.add_args('-icount', 'shift=%s,rr=%s,rrfile=%s,rrsnapshot=init' % - (shift, mode, replay_path), - '-net', 'none') - vm.add_args('-drive', 'file=%s,if=none' % image_path) - if args: - vm.add_args(*args) - vm.launch() - console_drainer = datadrainer.LineLogger(vm.console_socket.fileno(), - logger=self.log.getChild('console'), - stop_check=(lambda : not vm.is_running())) - console_drainer.start() - return vm - - @staticmethod - def get_reg_le(g, reg): - res = g.cmd(b'p%x' % reg) - num = 0 - for i in range(len(res))[-2::-2]: - num = 0x100 * num + int(res[i:i + 2], 16) - return num - - @staticmethod - def get_reg_be(g, reg): - res = g.cmd(b'p%x' % reg) - return int(res, 16) - - def get_reg(self, g, reg): - # value may be encoded in BE or LE order - if self.endian_is_le: - return self.get_reg_le(g, reg) - else: - return self.get_reg_be(g, reg) - - def get_pc(self, g): - return self.get_reg(g, self.REG_PC) - - def check_pc(self, g, addr): - pc = self.get_pc(g) - if pc != addr: - self.fail('Invalid PC (read %x instead of %x)' % (pc, addr)) - - @staticmethod - def gdb_step(g): - g.cmd(b's', b'T05thread:01;') - - @staticmethod - def gdb_bstep(g): - g.cmd(b'bs', b'T05thread:01;') - - @staticmethod - def vm_get_icount(vm): - return vm.qmp('query-replay')['return']['icount'] - - def reverse_debugging(self, shift=7, args=None): - logger = logging.getLogger('replay') - - # create qcow2 for snapshots - logger.info('creating qcow2 image for VM snapshots') - image_path = os.path.join(self.workdir, 'disk.qcow2') - qemu_img = os.path.join(BUILD_DIR, 'qemu-img') - if not os.path.exists(qemu_img): - qemu_img = find_command('qemu-img', False) - if qemu_img is False: - self.cancel('Could not find "qemu-img", which is required to ' - 'create the temporary qcow2 image') - cmd = '%s create -f qcow2 %s 128M' % (qemu_img, image_path) - process.run(cmd) - - replay_path = os.path.join(self.workdir, 'replay.bin') - port = find_free_port() - - # record the log - vm = self.run_vm(True, shift, args, replay_path, image_path, port) - while self.vm_get_icount(vm) <= self.STEPS: - pass - last_icount = self.vm_get_icount(vm) - vm.shutdown() - - logger.info("recorded log with %s+ steps" % last_icount) - - # replay and run debug commands - vm = self.run_vm(False, shift, args, replay_path, image_path, port) - logger.info('connecting to gdbstub') - g = gdb.GDBRemote('127.0.0.1', port, False, False) - g.connect() - r = g.cmd(b'qSupported') - if b'qXfer:features:read+' in r: - g.cmd(b'qXfer:features:read:target.xml:0,ffb') - if b'ReverseStep+' not in r: - self.fail('Reverse step is not supported by QEMU') - if b'ReverseContinue+' not in r: - self.fail('Reverse continue is not supported by QEMU') - - logger.info('stepping forward') - steps = [] - # record first instruction addresses - for _ in range(self.STEPS): - pc = self.get_pc(g) - logger.info('saving position %x' % pc) - steps.append(pc) - self.gdb_step(g) - - # visit the recorded instruction in reverse order - logger.info('stepping backward') - for addr in steps[::-1]: - self.gdb_bstep(g) - self.check_pc(g, addr) - logger.info('found position %x' % addr) - - # visit the recorded instruction in forward order - logger.info('stepping forward') - for addr in steps: - self.check_pc(g, addr) - self.gdb_step(g) - logger.info('found position %x' % addr) - - # set breakpoints for the instructions just stepped over - logger.info('setting breakpoints') - for addr in steps: - # hardware breakpoint at addr with len=1 - g.cmd(b'Z1,%x,1' % addr, b'OK') - - # this may hit a breakpoint if first instructions are executed - # again - logger.info('continuing execution') - vm.qmp('replay-break', icount=last_icount - 1) - # continue - will return after pausing - # This could stop at the end and get a T02 return, or by - # re-executing one of the breakpoints and get a T05 return. - g.cmd(b'c') - if self.vm_get_icount(vm) == last_icount - 1: - logger.info('reached the end (icount %s)' % (last_icount - 1)) - else: - logger.info('hit a breakpoint again at %x (icount %s)' % - (self.get_pc(g), self.vm_get_icount(vm))) - - logger.info('running reverse continue to reach %x' % steps[-1]) - # reverse continue - will return after stopping at the breakpoint - g.cmd(b'bc', b'T05thread:01;') - - # assume that none of the first instructions is executed again - # breaking the order of the breakpoints - self.check_pc(g, steps[-1]) - logger.info('successfully reached %x' % steps[-1]) - - logger.info('exiting gdb and qemu') - vm.shutdown() - -class ReverseDebugging_X86_64(ReverseDebugging): - """ - :avocado: tags=accel:tcg - """ - - REG_PC = 0x10 - REG_CS = 0x12 - def get_pc(self, g): - return self.get_reg_le(g, self.REG_PC) \ - + self.get_reg_le(g, self.REG_CS) * 0x10 - - # unidentified gitlab timeout problem - @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab') - - def test_x86_64_pc(self): - """ - :avocado: tags=arch:x86_64 - :avocado: tags=machine:pc - """ - # start with BIOS only - self.reverse_debugging() - -class ReverseDebugging_AArch64(ReverseDebugging): - """ - :avocado: tags=accel:tcg - """ - - REG_PC = 32 - - # unidentified gitlab timeout problem - @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab') - - def test_aarch64_virt(self): - """ - :avocado: tags=arch:aarch64 - :avocado: tags=machine:virt - :avocado: tags=cpu:cortex-a53 - """ - kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora' - '/linux/releases/29/Everything/aarch64/os/images/pxeboot' - '/vmlinuz') - kernel_hash = '8c73e469fc6ea06a58dc83a628fc695b693b8493' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - - self.reverse_debugging( - args=('-kernel', kernel_path)) - -class ReverseDebugging_ppc64(ReverseDebugging): - """ - :avocado: tags=accel:tcg - """ - - REG_PC = 0x40 - - # unidentified gitlab timeout problem - @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab') - - def test_ppc64_pseries(self): - """ - :avocado: tags=arch:ppc64 - :avocado: tags=machine:pseries - :avocado: tags=flaky - """ - # SLOF branches back to its entry point, which causes this test - # to take the 'hit a breakpoint again' path. That's not a problem, - # just slightly different than the other machines. - self.endian_is_le = False - self.reverse_debugging() - - # See https://gitlab.com/qemu-project/qemu/-/issues/1992 - @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab') - - def test_ppc64_powernv(self): - """ - :avocado: tags=arch:ppc64 - :avocado: tags=machine:powernv - :avocado: tags=flaky - """ - self.endian_is_le = False - self.reverse_debugging() diff --git a/tests/avocado/riscv_opensbi.py b/tests/avocado/riscv_opensbi.py deleted file mode 100644 index bfff9cc..0000000 --- a/tests/avocado/riscv_opensbi.py +++ /dev/null @@ -1,63 +0,0 @@ -# OpenSBI boot test for RISC-V machines -# -# Copyright (c) 2022, Ventana Micro -# -# This work is licensed under the terms of the GNU GPL, version 2 or -# later. See the COPYING file in the top-level directory. - -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern - -class RiscvOpenSBI(QemuSystemTest): - """ - :avocado: tags=accel:tcg - """ - timeout = 5 - - def boot_opensbi(self): - self.vm.set_console() - self.vm.launch() - wait_for_console_pattern(self, 'Platform Name') - wait_for_console_pattern(self, 'Boot HART MEDELEG') - - def test_riscv32_spike(self): - """ - :avocado: tags=arch:riscv32 - :avocado: tags=machine:spike - """ - self.boot_opensbi() - - def test_riscv64_spike(self): - """ - :avocado: tags=arch:riscv64 - :avocado: tags=machine:spike - """ - self.boot_opensbi() - - def test_riscv32_sifive_u(self): - """ - :avocado: tags=arch:riscv32 - :avocado: tags=machine:sifive_u - """ - self.boot_opensbi() - - def test_riscv64_sifive_u(self): - """ - :avocado: tags=arch:riscv64 - :avocado: tags=machine:sifive_u - """ - self.boot_opensbi() - - def test_riscv32_virt(self): - """ - :avocado: tags=arch:riscv32 - :avocado: tags=machine:virt - """ - self.boot_opensbi() - - def test_riscv64_virt(self): - """ - :avocado: tags=arch:riscv64 - :avocado: tags=machine:virt - """ - self.boot_opensbi() diff --git a/tests/avocado/s390_topology.py b/tests/avocado/s390_topology.py deleted file mode 100644 index 9154ac8..0000000 --- a/tests/avocado/s390_topology.py +++ /dev/null @@ -1,439 +0,0 @@ -# Functional test that boots a Linux kernel and checks the console -# -# Copyright IBM Corp. 2023 -# -# Author: -# Pierre Morel <pmorel@linux.ibm.com> -# -# 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 -import shutil -import time - -from avocado_qemu import QemuSystemTest -from avocado_qemu import exec_command -from avocado_qemu import exec_command_and_wait_for_pattern -from avocado_qemu import interrupt_interactive_console_until_pattern -from avocado_qemu import wait_for_console_pattern -from avocado.utils import process -from avocado.utils import archive - - -class S390CPUTopology(QemuSystemTest): - """ - S390x CPU topology consists of 4 topology layers, from bottom to top, - the cores, sockets, books and drawers and 2 modifiers attributes, - the entitlement and the dedication. - See: docs/system/s390x/cpu-topology.rst. - - S390x CPU topology is setup in different ways: - - implicitly from the '-smp' argument by completing each topology - level one after the other beginning with drawer 0, book 0 and - socket 0. - - explicitly from the '-device' argument on the QEMU command line - - explicitly by hotplug of a new CPU using QMP or HMP - - it is modified by using QMP 'set-cpu-topology' - - The S390x modifier attribute entitlement depends on the machine - polarization, which can be horizontal or vertical. - The polarization is changed on a request from the guest. - """ - timeout = 90 - event_timeout = 10 - - KERNEL_COMMON_COMMAND_LINE = ('printk.time=0 ' - 'root=/dev/ram ' - 'selinux=0 ' - 'rdinit=/bin/sh') - - def wait_until_booted(self): - wait_for_console_pattern(self, 'no job control', - failure_message='Kernel panic - not syncing', - vm=None) - - def check_topology(self, c, s, b, d, e, t): - res = self.vm.qmp('query-cpus-fast') - cpus = res['return'] - for cpu in cpus: - core = cpu['props']['core-id'] - socket = cpu['props']['socket-id'] - book = cpu['props']['book-id'] - drawer = cpu['props']['drawer-id'] - entitlement = cpu.get('entitlement') - dedicated = cpu.get('dedicated') - if core == c: - self.assertEqual(drawer, d) - self.assertEqual(book, b) - self.assertEqual(socket, s) - self.assertEqual(entitlement, e) - self.assertEqual(dedicated, t) - - def kernel_init(self): - """ - We need a VM that supports CPU topology, - currently this only the case when using KVM, not TCG. - We need a kernel supporting the CPU topology. - We need a minimal root filesystem with a shell. - """ - self.require_accelerator("kvm") - kernel_url = ('https://archives.fedoraproject.org/pub/archive' - '/fedora-secondary/releases/35/Server/s390x/os' - '/images/kernel.img') - kernel_hash = '0d1aaaf303f07cf0160c8c48e56fe638' - kernel_path = self.fetch_asset(kernel_url, algorithm='md5', - asset_hash=kernel_hash) - - initrd_url = ('https://archives.fedoraproject.org/pub/archive' - '/fedora-secondary/releases/35/Server/s390x/os' - '/images/initrd.img') - initrd_hash = 'a122057d95725ac030e2ec51df46e172' - initrd_path_xz = self.fetch_asset(initrd_url, algorithm='md5', - asset_hash=initrd_hash) - initrd_path = os.path.join(self.workdir, 'initrd-raw.img') - archive.lzma_uncompress(initrd_path_xz, initrd_path) - - self.vm.set_console() - kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE - self.vm.add_args('-nographic', - '-enable-kvm', - '-cpu', 'max,ctop=on', - '-m', '512', - '-kernel', kernel_path, - '-initrd', initrd_path, - '-append', kernel_command_line) - - def system_init(self): - self.log.info("System init") - exec_command_and_wait_for_pattern(self, - """ mount proc -t proc /proc; - mount sys -t sysfs /sys; - cat /sys/devices/system/cpu/dispatching """, - '0') - - def test_single(self): - """ - This test checks the simplest topology with a single CPU. - - :avocado: tags=arch:s390x - :avocado: tags=machine:s390-ccw-virtio - """ - self.kernel_init() - self.vm.launch() - self.wait_until_booted() - self.check_topology(0, 0, 0, 0, 'medium', False) - - def test_default(self): - """ - This test checks the implicit topology. - - :avocado: tags=arch:s390x - :avocado: tags=machine:s390-ccw-virtio - """ - self.kernel_init() - self.vm.add_args('-smp', - '13,drawers=2,books=2,sockets=3,cores=2,maxcpus=24') - self.vm.launch() - self.wait_until_booted() - self.check_topology(0, 0, 0, 0, 'medium', False) - self.check_topology(1, 0, 0, 0, 'medium', False) - self.check_topology(2, 1, 0, 0, 'medium', False) - self.check_topology(3, 1, 0, 0, 'medium', False) - self.check_topology(4, 2, 0, 0, 'medium', False) - self.check_topology(5, 2, 0, 0, 'medium', False) - self.check_topology(6, 0, 1, 0, 'medium', False) - self.check_topology(7, 0, 1, 0, 'medium', False) - self.check_topology(8, 1, 1, 0, 'medium', False) - self.check_topology(9, 1, 1, 0, 'medium', False) - self.check_topology(10, 2, 1, 0, 'medium', False) - self.check_topology(11, 2, 1, 0, 'medium', False) - self.check_topology(12, 0, 0, 1, 'medium', False) - - def test_move(self): - """ - This test checks the topology modification by moving a CPU - to another socket: CPU 0 is moved from socket 0 to socket 2. - - :avocado: tags=arch:s390x - :avocado: tags=machine:s390-ccw-virtio - """ - self.kernel_init() - self.vm.add_args('-smp', - '1,drawers=2,books=2,sockets=3,cores=2,maxcpus=24') - self.vm.launch() - self.wait_until_booted() - - self.check_topology(0, 0, 0, 0, 'medium', False) - res = self.vm.qmp('set-cpu-topology', - {'core-id': 0, 'socket-id': 2, 'entitlement': 'low'}) - self.assertEqual(res['return'], {}) - self.check_topology(0, 2, 0, 0, 'low', False) - - def test_dash_device(self): - """ - This test verifies that a CPU defined with the '-device' - command line option finds its right place inside the topology. - - :avocado: tags=arch:s390x - :avocado: tags=machine:s390-ccw-virtio - """ - self.kernel_init() - self.vm.add_args('-smp', - '1,drawers=2,books=2,sockets=3,cores=2,maxcpus=24') - self.vm.add_args('-device', 'max-s390x-cpu,core-id=10') - self.vm.add_args('-device', - 'max-s390x-cpu,' - 'core-id=1,socket-id=0,book-id=1,drawer-id=1,entitlement=low') - self.vm.add_args('-device', - 'max-s390x-cpu,' - 'core-id=2,socket-id=0,book-id=1,drawer-id=1,entitlement=medium') - self.vm.add_args('-device', - 'max-s390x-cpu,' - 'core-id=3,socket-id=1,book-id=1,drawer-id=1,entitlement=high') - self.vm.add_args('-device', - 'max-s390x-cpu,' - 'core-id=4,socket-id=1,book-id=1,drawer-id=1') - self.vm.add_args('-device', - 'max-s390x-cpu,' - 'core-id=5,socket-id=2,book-id=1,drawer-id=1,dedicated=true') - - self.vm.launch() - self.wait_until_booted() - - self.check_topology(10, 2, 1, 0, 'medium', False) - self.check_topology(1, 0, 1, 1, 'low', False) - self.check_topology(2, 0, 1, 1, 'medium', False) - self.check_topology(3, 1, 1, 1, 'high', False) - self.check_topology(4, 1, 1, 1, 'medium', False) - self.check_topology(5, 2, 1, 1, 'high', True) - - - def guest_set_dispatching(self, dispatching): - exec_command(self, - f'echo {dispatching} > /sys/devices/system/cpu/dispatching') - self.vm.event_wait('CPU_POLARIZATION_CHANGE', self.event_timeout) - exec_command_and_wait_for_pattern(self, - 'cat /sys/devices/system/cpu/dispatching', dispatching) - - - def test_polarization(self): - """ - This test verifies that QEMU modifies the entitlement change after - several guest polarization change requests. - - :avocado: tags=arch:s390x - :avocado: tags=machine:s390-ccw-virtio - """ - self.kernel_init() - self.vm.launch() - self.wait_until_booted() - - self.system_init() - res = self.vm.qmp('query-s390x-cpu-polarization') - self.assertEqual(res['return']['polarization'], 'horizontal') - self.check_topology(0, 0, 0, 0, 'medium', False) - - self.guest_set_dispatching('1'); - res = self.vm.qmp('query-s390x-cpu-polarization') - self.assertEqual(res['return']['polarization'], 'vertical') - self.check_topology(0, 0, 0, 0, 'medium', False) - - self.guest_set_dispatching('0'); - res = self.vm.qmp('query-s390x-cpu-polarization') - self.assertEqual(res['return']['polarization'], 'horizontal') - self.check_topology(0, 0, 0, 0, 'medium', False) - - - def check_polarization(self, polarization): - #We need to wait for the change to have been propagated to the kernel - exec_command_and_wait_for_pattern(self, - "\n".join([ - "timeout 1 sh -c 'while true", - 'do', - ' syspath="/sys/devices/system/cpu/cpu0/polarization"', - ' polarization="$(cat "$syspath")" || exit', - f' if [ "$polarization" = "{polarization}" ]; then', - ' exit 0', - ' fi', - ' sleep 0.01', - #searched for strings mustn't show up in command, '' to obfuscate - "done' && echo succ''ess || echo fail''ure", - ]), - "success", "failure") - - - def test_entitlement(self): - """ - This test verifies that QEMU modifies the entitlement - after a guest request and that the guest sees the change. - - :avocado: tags=arch:s390x - :avocado: tags=machine:s390-ccw-virtio - """ - self.kernel_init() - self.vm.launch() - self.wait_until_booted() - - self.system_init() - - self.check_polarization('horizontal') - self.check_topology(0, 0, 0, 0, 'medium', False) - - self.guest_set_dispatching('1') - self.check_polarization('vertical:medium') - self.check_topology(0, 0, 0, 0, 'medium', False) - - res = self.vm.qmp('set-cpu-topology', - {'core-id': 0, 'entitlement': 'low'}) - self.assertEqual(res['return'], {}) - self.check_polarization('vertical:low') - self.check_topology(0, 0, 0, 0, 'low', False) - - res = self.vm.qmp('set-cpu-topology', - {'core-id': 0, 'entitlement': 'medium'}) - self.assertEqual(res['return'], {}) - self.check_polarization('vertical:medium') - self.check_topology(0, 0, 0, 0, 'medium', False) - - res = self.vm.qmp('set-cpu-topology', - {'core-id': 0, 'entitlement': 'high'}) - self.assertEqual(res['return'], {}) - self.check_polarization('vertical:high') - self.check_topology(0, 0, 0, 0, 'high', False) - - self.guest_set_dispatching('0'); - self.check_polarization("horizontal") - self.check_topology(0, 0, 0, 0, 'high', False) - - - def test_dedicated(self): - """ - This test verifies that QEMU adjusts the entitlement correctly when a - CPU is made dedicated. - QEMU retains the entitlement value when horizontal polarization is in effect. - For the guest, the field shows the effective value of the entitlement. - - :avocado: tags=arch:s390x - :avocado: tags=machine:s390-ccw-virtio - """ - self.kernel_init() - self.vm.launch() - self.wait_until_booted() - - self.system_init() - - self.check_polarization("horizontal") - - res = self.vm.qmp('set-cpu-topology', - {'core-id': 0, 'dedicated': True}) - self.assertEqual(res['return'], {}) - self.check_topology(0, 0, 0, 0, 'high', True) - self.check_polarization("horizontal") - - self.guest_set_dispatching('1'); - self.check_topology(0, 0, 0, 0, 'high', True) - self.check_polarization("vertical:high") - - self.guest_set_dispatching('0'); - self.check_topology(0, 0, 0, 0, 'high', True) - self.check_polarization("horizontal") - - - def test_socket_full(self): - """ - This test verifies that QEMU does not accept to overload a socket. - The socket-id 0 on book-id 0 already contains CPUs 0 and 1 and can - not accept any new CPU while socket-id 0 on book-id 1 is free. - - :avocado: tags=arch:s390x - :avocado: tags=machine:s390-ccw-virtio - """ - self.kernel_init() - self.vm.add_args('-smp', - '3,drawers=2,books=2,sockets=3,cores=2,maxcpus=24') - self.vm.launch() - self.wait_until_booted() - - self.system_init() - - res = self.vm.qmp('set-cpu-topology', - {'core-id': 2, 'socket-id': 0, 'book-id': 0}) - self.assertEqual(res['error']['class'], 'GenericError') - - res = self.vm.qmp('set-cpu-topology', - {'core-id': 2, 'socket-id': 0, 'book-id': 1}) - self.assertEqual(res['return'], {}) - - def test_dedicated_error(self): - """ - This test verifies that QEMU refuses to lower the entitlement - of a dedicated CPU - - :avocado: tags=arch:s390x - :avocado: tags=machine:s390-ccw-virtio - """ - self.kernel_init() - self.vm.launch() - self.wait_until_booted() - - self.system_init() - - res = self.vm.qmp('set-cpu-topology', - {'core-id': 0, 'dedicated': True}) - self.assertEqual(res['return'], {}) - - self.check_topology(0, 0, 0, 0, 'high', True) - - self.guest_set_dispatching('1'); - - self.check_topology(0, 0, 0, 0, 'high', True) - - res = self.vm.qmp('set-cpu-topology', - {'core-id': 0, 'entitlement': 'low', 'dedicated': True}) - self.assertEqual(res['error']['class'], 'GenericError') - - res = self.vm.qmp('set-cpu-topology', - {'core-id': 0, 'entitlement': 'low'}) - self.assertEqual(res['error']['class'], 'GenericError') - - res = self.vm.qmp('set-cpu-topology', - {'core-id': 0, 'entitlement': 'medium', 'dedicated': True}) - self.assertEqual(res['error']['class'], 'GenericError') - - res = self.vm.qmp('set-cpu-topology', - {'core-id': 0, 'entitlement': 'medium'}) - self.assertEqual(res['error']['class'], 'GenericError') - - res = self.vm.qmp('set-cpu-topology', - {'core-id': 0, 'entitlement': 'low', 'dedicated': False}) - self.assertEqual(res['return'], {}) - - res = self.vm.qmp('set-cpu-topology', - {'core-id': 0, 'entitlement': 'medium', 'dedicated': False}) - self.assertEqual(res['return'], {}) - - def test_move_error(self): - """ - This test verifies that QEMU refuses to move a CPU to an - nonexistent location - - :avocado: tags=arch:s390x - :avocado: tags=machine:s390-ccw-virtio - """ - self.kernel_init() - self.vm.launch() - self.wait_until_booted() - - self.system_init() - - res = self.vm.qmp('set-cpu-topology', {'core-id': 0, 'drawer-id': 1}) - self.assertEqual(res['error']['class'], 'GenericError') - - res = self.vm.qmp('set-cpu-topology', {'core-id': 0, 'book-id': 1}) - self.assertEqual(res['error']['class'], 'GenericError') - - res = self.vm.qmp('set-cpu-topology', {'core-id': 0, 'socket-id': 1}) - self.assertEqual(res['error']['class'], 'GenericError') - - self.check_topology(0, 0, 0, 0, 'medium', False) diff --git a/tests/avocado/smmu.py b/tests/avocado/smmu.py deleted file mode 100644 index 4ebfa71..0000000 --- a/tests/avocado/smmu.py +++ /dev/null @@ -1,139 +0,0 @@ -# SMMUv3 Functional tests -# -# Copyright (c) 2021 Red Hat, Inc. -# -# Author: -# Eric Auger <eric.auger@redhat.com> -# -# 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 skipUnless -from avocado_qemu import LinuxTest, BUILD_DIR - -@skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable 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 - :avocado: tags=flaky - """ - - 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,' + - '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() diff --git a/tests/avocado/tcg_plugins.py b/tests/avocado/tcg_plugins.py deleted file mode 100644 index 15fd87b..0000000 --- a/tests/avocado/tcg_plugins.py +++ /dev/null @@ -1,155 +0,0 @@ -# TCG Plugins tests -# -# These are a little more involved than the basic tests run by check-tcg. -# -# Copyright (c) 2021 Linaro -# -# Author: -# Alex Bennée <alex.bennee@linaro.org> -# -# SPDX-License-Identifier: GPL-2.0-or-later - -import tempfile -import mmap -import re - -from boot_linux_console import LinuxKernelTest - - -class PluginKernelBase(LinuxKernelTest): - """ - Boots a Linux kernel with a TCG plugin enabled. - """ - - timeout = 120 - KERNEL_COMMON_COMMAND_LINE = 'printk.time=1 panic=-1 ' - - def run_vm(self, kernel_path, kernel_command_line, - plugin, plugin_log, console_pattern, args=None): - - vm = self.get_vm() - vm.set_console() - vm.add_args('-kernel', kernel_path, - '-append', kernel_command_line, - '-plugin', plugin, - '-d', 'plugin', - '-D', plugin_log, - '-net', 'none', - '-no-reboot') - if args: - vm.add_args(*args) - - try: - vm.launch() - except: - # TODO: probably fails because plugins not enabled but we - # can't currently probe for the feature. - self.cancel("TCG Plugins not enabled?") - - self.wait_for_console_pattern(console_pattern, vm) - # ensure logs are flushed - vm.shutdown() - - -class PluginKernelNormal(PluginKernelBase): - - def _grab_aarch64_kernel(self): - kernel_url = ('https://storage.tuxboot.com/20230331/arm64/Image') - kernel_sha256 = 'ce95a7101a5fecebe0fe630deee6bd97b32ba41bc8754090e9ad8961ea8674c7' - kernel_path = self.fetch_asset(kernel_url, - asset_hash=kernel_sha256, - algorithm = "sha256") - return kernel_path - - def test_aarch64_virt_insn(self): - """ - :avocado: tags=accel:tcg - :avocado: tags=arch:aarch64 - :avocado: tags=machine:virt - :avocado: tags=cpu:cortex-a53 - """ - kernel_path = self._grab_aarch64_kernel() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=ttyAMA0') - console_pattern = 'Kernel panic - not syncing: VFS:' - - plugin_log = tempfile.NamedTemporaryFile(mode="r+t", prefix="plugin", - suffix=".log") - - self.run_vm(kernel_path, kernel_command_line, - "tests/plugin/libinsn.so", plugin_log.name, - console_pattern) - - with plugin_log as lf, \ - mmap.mmap(lf.fileno(), 0, access=mmap.ACCESS_READ) as s: - - m = re.search(br"insns: (?P<count>\d+)", s) - if "count" not in m.groupdict(): - self.fail("Failed to find instruction count") - else: - count = int(m.group("count")) - self.log.info(f"Counted: {count} instructions") - - - def test_aarch64_virt_insn_icount(self): - """ - :avocado: tags=accel:tcg - :avocado: tags=arch:aarch64 - :avocado: tags=machine:virt - :avocado: tags=cpu:cortex-a53 - """ - kernel_path = self._grab_aarch64_kernel() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=ttyAMA0') - console_pattern = 'Kernel panic - not syncing: VFS:' - - plugin_log = tempfile.NamedTemporaryFile(mode="r+t", prefix="plugin", - suffix=".log") - - self.run_vm(kernel_path, kernel_command_line, - "tests/plugin/libinsn.so", plugin_log.name, - console_pattern, - args=('-icount', 'shift=1')) - - with plugin_log as lf, \ - mmap.mmap(lf.fileno(), 0, access=mmap.ACCESS_READ) as s: - - m = re.search(br"insns: (?P<count>\d+)", s) - if "count" not in m.groupdict(): - self.fail("Failed to find instruction count") - else: - count = int(m.group("count")) - self.log.info(f"Counted: {count} instructions") - - def test_aarch64_virt_mem_icount(self): - """ - :avocado: tags=accel:tcg - :avocado: tags=arch:aarch64 - :avocado: tags=machine:virt - :avocado: tags=cpu:cortex-a53 - """ - kernel_path = self._grab_aarch64_kernel() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=ttyAMA0') - console_pattern = 'Kernel panic - not syncing: VFS:' - - plugin_log = tempfile.NamedTemporaryFile(mode="r+t", prefix="plugin", - suffix=".log") - - self.run_vm(kernel_path, kernel_command_line, - "tests/plugin/libmem.so,inline=true,callback=true", plugin_log.name, - console_pattern, - args=('-icount', 'shift=1')) - - with plugin_log as lf, \ - mmap.mmap(lf.fileno(), 0, access=mmap.ACCESS_READ) as s: - m = re.findall(br"mem accesses: (?P<count>\d+)", s) - if m is None or len(m) != 2: - self.fail("no memory access counts found") - else: - inline = int(m[0]) - callback = int(m[1]) - if inline != callback: - self.fail("mismatched access counts") - else: - self.log.info(f"Counted {inline} memory accesses") diff --git a/tests/avocado/tesseract_utils.py b/tests/avocado/tesseract_utils.py deleted file mode 100644 index 476f528..0000000 --- a/tests/avocado/tesseract_utils.py +++ /dev/null @@ -1,46 +0,0 @@ -# ... -# -# Copyright (c) 2019 Philippe Mathieu-Daudé <f4bug@amsat.org> -# -# 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 re -import logging - -from avocado.utils import process -from avocado.utils.path import find_command, CmdNotFoundError - -def tesseract_available(expected_version): - try: - find_command('tesseract') - except CmdNotFoundError: - return False - res = process.run('tesseract --version') - try: - version = res.stdout_text.split()[1] - except IndexError: - version = res.stderr_text.split()[1] - return int(version.split('.')[0]) >= expected_version - - match = re.match(r'tesseract\s(\d)', res) - if match is None: - return False - # now this is guaranteed to be a digit - return int(match.groups()[0]) >= expected_version - - -def tesseract_ocr(image_path, tesseract_args='', tesseract_version=3): - console_logger = logging.getLogger('tesseract') - console_logger.debug(image_path) - if tesseract_version == 4: - tesseract_args += ' --oem 1' - proc = process.run("tesseract {} {} stdout".format(tesseract_args, - image_path)) - lines = [] - for line in proc.stdout_text.split('\n'): - sline = line.strip() - if len(sline): - console_logger.debug(sline) - lines += [sline] - return lines diff --git a/tests/avocado/tuxrun_baselines.py b/tests/avocado/tuxrun_baselines.py deleted file mode 100644 index 736e4aa..0000000 --- a/tests/avocado/tuxrun_baselines.py +++ /dev/null @@ -1,620 +0,0 @@ -# Functional test that boots known good tuxboot images the same way -# that tuxrun (www.tuxrun.org) does. This tool is used by things like -# the LKFT project to run regression tests on kernels. -# -# Copyright (c) 2023 Linaro Ltd. -# -# Author: -# Alex Bennée <alex.bennee@linaro.org> -# -# SPDX-License-Identifier: GPL-2.0-or-later - -import os -import time -import tempfile - -from avocado import skip, skipUnless -from avocado_qemu import QemuSystemTest -from avocado_qemu import exec_command, exec_command_and_wait_for_pattern -from avocado_qemu import wait_for_console_pattern -from avocado.utils import process -from avocado.utils.path import find_command - -class TuxRunBaselineTest(QemuSystemTest): - """ - :avocado: tags=accel:tcg - """ - - KERNEL_COMMON_COMMAND_LINE = 'printk.time=0' - # Tests are ~10-40s, allow for --debug/--enable-gcov overhead - timeout = 100 - - def get_tag(self, tagname, default=None): - """ - Get the metadata tag or return the default. - """ - utag = self._get_unique_tag_val(tagname) - print(f"{tagname}/{default} -> {utag}") - if utag: - return utag - - return default - - def setUp(self): - super().setUp() - - # We need zstd for all the tuxrun tests - # See https://github.com/avocado-framework/avocado/issues/5609 - zstd = find_command('zstd', False) - if zstd is False: - self.cancel('Could not find "zstd", which is required to ' - 'decompress rootfs') - self.zstd = zstd - - # Process the TuxRun specific tags, most machines work with - # reasonable defaults but we sometimes need to tweak the - # config. To avoid open coding everything we store all these - # details in the metadata for each test. - - # The tuxboot tag matches the root directory - self.tuxboot = self.get_tag('tuxboot') - - # Most Linux's use ttyS0 for their serial port - self.console = self.get_tag('console', "ttyS0") - - # Does the machine shutdown QEMU nicely on "halt" - self.shutdown = self.get_tag('shutdown') - - # The name of the kernel Image file - self.image = self.get_tag('image', "Image") - - self.root = self.get_tag('root', "vda") - - # Occasionally we need extra devices to hook things up - self.extradev = self.get_tag('extradev') - - self.qemu_img = super().get_qemu_img() - - def wait_for_console_pattern(self, success_message, vm=None): - wait_for_console_pattern(self, success_message, - failure_message='Kernel panic - not syncing', - vm=vm) - - def fetch_tuxrun_assets(self, csums=None, dt=None): - """ - Fetch the TuxBoot assets. They are stored in a standard way so we - use the per-test tags to fetch details. - """ - base_url = f"https://storage.tuxboot.com/20230331/{self.tuxboot}/" - - # empty hash if we weren't passed one - csums = {} if csums is None else csums - ksum = csums.get(self.image, None) - isum = csums.get("rootfs.ext4.zst", None) - - kernel_image = self.fetch_asset(base_url + self.image, - asset_hash = ksum, - algorithm = "sha256") - disk_image_zst = self.fetch_asset(base_url + "rootfs.ext4.zst", - asset_hash = isum, - algorithm = "sha256") - - cmd = f"{self.zstd} -d {disk_image_zst} -o {self.workdir}/rootfs.ext4" - process.run(cmd) - - if dt: - dsum = csums.get(dt, None) - dtb = self.fetch_asset(base_url + dt, - asset_hash = dsum, - algorithm = "sha256") - else: - dtb = None - - return (kernel_image, self.workdir + "/rootfs.ext4", dtb) - - def prepare_run(self, kernel, disk, drive, dtb=None, console_index=0): - """ - Setup to run and add the common parameters to the system - """ - self.vm.set_console(console_index=console_index) - - # all block devices are raw ext4's - blockdev = "driver=raw,file.driver=file," \ - + f"file.filename={disk},node-name=hd0" - - kcmd_line = self.KERNEL_COMMON_COMMAND_LINE - kcmd_line += f" root=/dev/{self.root}" - kcmd_line += f" console={self.console}" - - self.vm.add_args('-kernel', kernel, - '-append', kcmd_line, - '-blockdev', blockdev) - - # Sometimes we need extra devices attached - if self.extradev: - self.vm.add_args('-device', self.extradev) - - self.vm.add_args('-device', - f"{drive},drive=hd0") - - # Some machines need an explicit DTB - if dtb: - self.vm.add_args('-dtb', dtb) - - def run_tuxtest_tests(self, haltmsg): - """ - Wait for the system to boot up, wait for the login prompt and - then do a few things on the console. Trigger a shutdown and - wait to exit cleanly. - """ - self.wait_for_console_pattern("Welcome to TuxTest") - time.sleep(0.2) - exec_command(self, 'root') - time.sleep(0.2) - exec_command(self, 'cat /proc/interrupts') - time.sleep(0.1) - exec_command(self, 'cat /proc/self/maps') - time.sleep(0.1) - exec_command(self, 'uname -a') - time.sleep(0.1) - exec_command_and_wait_for_pattern(self, 'halt', haltmsg) - - # Wait for VM to shut down gracefully if it can - if self.shutdown == "nowait": - self.vm.shutdown() - else: - self.vm.wait() - - def common_tuxrun(self, - csums=None, - dt=None, - drive="virtio-blk-device", - haltmsg="reboot: System halted", - console_index=0): - """ - Common path for LKFT tests. Unless we need to do something - special with the command line we can process most things using - the tag metadata. - """ - (kernel, disk, dtb) = self.fetch_tuxrun_assets(csums, dt) - - self.prepare_run(kernel, disk, drive, dtb, console_index) - self.vm.launch() - self.run_tuxtest_tests(haltmsg) - - def ppc64_common_tuxrun(self, sums, prefix): - # add device args to command line. - self.require_netdev('user') - self.vm.add_args('-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22', - '-device', 'virtio-net,netdev=vnet') - self.vm.add_args('-netdev', '{"type":"user","id":"hostnet0"}', - '-device', '{"driver":"virtio-net-pci","netdev":' - '"hostnet0","id":"net0","mac":"52:54:00:4c:e3:86",' - '"bus":"pci.0","addr":"0x9"}') - self.vm.add_args('-device', '{"driver":"qemu-xhci","p2":15,"p3":15,' - '"id":"usb","bus":"pci.0","addr":"0x2"}') - self.vm.add_args('-device', '{"driver":"virtio-scsi-pci","id":"scsi0"' - ',"bus":"pci.0","addr":"0x3"}') - self.vm.add_args('-device', '{"driver":"virtio-serial-pci","id":' - '"virtio-serial0","bus":"pci.0","addr":"0x4"}') - self.vm.add_args('-device', '{"driver":"scsi-cd","bus":"scsi0.0"' - ',"channel":0,"scsi-id":0,"lun":0,"device_id":' - '"drive-scsi0-0-0-0","id":"scsi0-0-0-0"}') - self.vm.add_args('-device', '{"driver":"virtio-balloon-pci",' - '"id":"balloon0","bus":"pci.0","addr":"0x6"}') - self.vm.add_args('-audiodev', '{"id":"audio1","driver":"none"}') - self.vm.add_args('-device', '{"driver":"usb-tablet","id":"input0"' - ',"bus":"usb.0","port":"1"}') - self.vm.add_args('-device', '{"driver":"usb-kbd","id":"input1"' - ',"bus":"usb.0","port":"2"}') - self.vm.add_args('-device', '{"driver":"VGA","id":"video0",' - '"vgamem_mb":16,"bus":"pci.0","addr":"0x7"}') - self.vm.add_args('-object', '{"qom-type":"rng-random","id":"objrng0"' - ',"filename":"/dev/urandom"}', - '-device', '{"driver":"virtio-rng-pci","rng":"objrng0"' - ',"id":"rng0","bus":"pci.0","addr":"0x8"}') - self.vm.add_args('-object', '{"qom-type":"cryptodev-backend-builtin",' - '"id":"objcrypto0","queues":1}', - '-device', '{"driver":"virtio-crypto-pci",' - '"cryptodev":"objcrypto0","id":"crypto0","bus"' - ':"pci.0","addr":"0xa"}') - self.vm.add_args('-device', '{"driver":"spapr-pci-host-bridge"' - ',"index":1,"id":"pci.1"}') - self.vm.add_args('-device', '{"driver":"spapr-vscsi","id":"scsi1"' - ',"reg":12288}') - self.vm.add_args('-m', '2G,slots=32,maxmem=4G', - '-object', 'memory-backend-ram,id=ram1,size=1G', - '-device', 'pc-dimm,id=dimm1,memdev=ram1') - - # Create a temporary qcow2 and launch the test-case - with tempfile.NamedTemporaryFile(prefix=prefix, - suffix='.qcow2') as qcow2: - process.run(self.qemu_img + ' create -f qcow2 ' + - qcow2.name + ' 1G') - - self.vm.add_args('-drive', 'file=' + qcow2.name + - ',format=qcow2,if=none,id=' - 'drive-virtio-disk1', - '-device', 'virtio-blk-pci,bus=pci.0,' - 'addr=0xb,drive=drive-virtio-disk1,id=virtio-disk1' - ',bootindex=2') - self.common_tuxrun(csums=sums, drive="scsi-hd") - - # - # The tests themselves. The configuration is derived from how - # tuxrun invokes qemu (with minor tweaks like using -blockdev - # consistently). The tuxrun equivalent is something like: - # - # tuxrun --device qemu-{ARCH} \ - # --kernel https://storage.tuxboot.com/{TUXBOOT}/{IMAGE} - # - - def test_arm64(self): - """ - :avocado: tags=arch:aarch64 - :avocado: tags=cpu:cortex-a57 - :avocado: tags=machine:virt - :avocado: tags=tuxboot:arm64 - :avocado: tags=console:ttyAMA0 - :avocado: tags=shutdown:nowait - """ - sums = {"Image" : - "ce95a7101a5fecebe0fe630deee6bd97b32ba41bc8754090e9ad8961ea8674c7", - "rootfs.ext4.zst" : - "bbd5ed4b9c7d3f4ca19ba71a323a843c6b585e880115df3b7765769dbd9dd061"} - self.common_tuxrun(csums=sums) - - def test_arm64be(self): - """ - :avocado: tags=arch:aarch64 - :avocado: tags=cpu:cortex-a57 - :avocado: tags=endian:big - :avocado: tags=machine:virt - :avocado: tags=tuxboot:arm64be - :avocado: tags=console:ttyAMA0 - :avocado: tags=shutdown:nowait - """ - sums = { "Image" : - "e0df4425eb2cd9ea9a283e808037f805641c65d8fcecc8f6407d8f4f339561b4", - "rootfs.ext4.zst" : - "e6ffd8813c8a335bc15728f2835f90539c84be7f8f5f691a8b01451b47fb4bd7"} - self.common_tuxrun(csums=sums) - - def test_armv5(self): - """ - :avocado: tags=arch:arm - :avocado: tags=cpu:arm926 - :avocado: tags=machine:versatilepb - :avocado: tags=tuxboot:armv5 - :avocado: tags=image:zImage - :avocado: tags=console:ttyAMA0 - :avocado: tags=shutdown:nowait - """ - sums = { "rootfs.ext4.zst" : - "17177afa74e7294da0642861f08c88ca3c836764299a54bf6d1ce276cb9712a5", - "versatile-pb.dtb" : - "0bc0c0b0858cefd3c32b385c0d66d97142ded29472a496f4f490e42fc7615b25", - "zImage" : - "c95af2f27647c12265d75e9df44c22ff5228c59855f54aaa70f41ec2842e3a4d" } - - self.common_tuxrun(csums=sums, - drive="virtio-blk-pci", - dt="versatile-pb.dtb") - - def test_armv7(self): - """ - :avocado: tags=arch:arm - :avocado: tags=cpu:cortex-a15 - :avocado: tags=machine:virt - :avocado: tags=tuxboot:armv7 - :avocado: tags=image:zImage - :avocado: tags=console:ttyAMA0 - :avocado: tags=shutdown:nowait - """ - sums = { "rootfs.ext4.zst" : - "ab1fbbeaddda1ffdd45c9405a28cd5370c20f23a7cbc809cc90dc9f243a8eb5a", - "zImage" : - "4c7a22e9f15875bec06bd2a29d822496571eb297d4f22694099ffcdb19077572" } - - self.common_tuxrun(csums=sums) - - def test_armv7be(self): - """ - :avocado: tags=arch:arm - :avocado: tags=cpu:cortex-a15 - :avocado: tags=endian:big - :avocado: tags=machine:virt - :avocado: tags=tuxboot:armv7be - :avocado: tags=image:zImage - :avocado: tags=console:ttyAMA0 - :avocado: tags=shutdown:nowait - """ - sums = {"rootfs.ext4.zst" : - "42ed46dd2d59986206c5b1f6cf35eab58fe3fd20c96b41aaa16b32f3f90a9835", - "zImage" : - "7facc62082b57af12015b08f7fdbaf2f123ba07a478367853ae12b219afc9f2f" } - - self.common_tuxrun(csums=sums) - - def test_i386(self): - """ - :avocado: tags=arch:i386 - :avocado: tags=cpu:coreduo - :avocado: tags=machine:q35 - :avocado: tags=tuxboot:i386 - :avocado: tags=image:bzImage - :avocado: tags=shutdown:nowait - """ - sums = {"bzImage" : - "a3e5b32a354729e65910f5a1ffcda7c14a6c12a55e8213fb86e277f1b76ed956", - "rootfs.ext4.zst" : - "f15e66b2bf673a210ec2a4b2e744a80530b36289e04f5388aab812b97f69754a" } - - self.common_tuxrun(csums=sums, drive="virtio-blk-pci") - - def test_mips32(self): - """ - :avocado: tags=arch:mips - :avocado: tags=machine:malta - :avocado: tags=cpu:mips32r6-generic - :avocado: tags=endian:big - :avocado: tags=tuxboot:mips32 - :avocado: tags=image:vmlinux - :avocado: tags=root:sda - :avocado: tags=shutdown:nowait - """ - sums = { "rootfs.ext4.zst" : - "fc3da0b4c2f38d74c6d705123bb0f633c76ed953128f9d0859378c328a6d11a0", - "vmlinux" : - "bfd2172f8b17fb32970ca0c8c58f59c5a4ca38aa5855d920be3a69b5d16e52f0" } - - self.common_tuxrun(csums=sums, drive="driver=ide-hd,bus=ide.0,unit=0") - - def test_mips32el(self): - """ - :avocado: tags=arch:mipsel - :avocado: tags=machine:malta - :avocado: tags=cpu:mips32r6-generic - :avocado: tags=tuxboot:mips32el - :avocado: tags=image:vmlinux - :avocado: tags=root:sda - :avocado: tags=shutdown:nowait - """ - sums = { "rootfs.ext4.zst" : - "e799768e289fd69209c21f4dacffa11baea7543d5db101e8ce27e3bc2c41d90e", - "vmlinux" : - "8573867c68a8443db8de6d08bb33fb291c189ca2ca671471d3973a3e712096a3" } - - self.common_tuxrun(csums=sums, drive="driver=ide-hd,bus=ide.0,unit=0") - - def test_mips64(self): - """ - :avocado: tags=arch:mips64 - :avocado: tags=machine:malta - :avocado: tags=tuxboot:mips64 - :avocado: tags=endian:big - :avocado: tags=image:vmlinux - :avocado: tags=root:sda - :avocado: tags=shutdown:nowait - """ - sums = { "rootfs.ext4.zst" : - "69d91eeb04df3d8d172922c6993bb37d4deeb6496def75d8580f6f9de3e431da", - "vmlinux" : - "09010e51e4b8bcbbd2494786ffb48eca78f228e96e5c5438344b0eac4029dc61" } - - self.common_tuxrun(csums=sums, drive="driver=ide-hd,bus=ide.0,unit=0") - - def test_mips64el(self): - """ - :avocado: tags=arch:mips64el - :avocado: tags=machine:malta - :avocado: tags=tuxboot:mips64el - :avocado: tags=image:vmlinux - :avocado: tags=root:sda - :avocado: tags=shutdown:nowait - """ - sums = { "rootfs.ext4.zst" : - "fba585368f5915b1498ed081863474b2d7ec4e97cdd46d21bdcb2f9698f83de4", - "vmlinux" : - "d4e08965e2155c4cccce7c5f34d18fe34c636cda2f2c9844387d614950155266" } - - self.common_tuxrun(csums=sums, drive="driver=ide-hd,bus=ide.0,unit=0") - - def test_ppc32(self): - """ - :avocado: tags=arch:ppc - :avocado: tags=machine:ppce500 - :avocado: tags=cpu:e500mc - :avocado: tags=tuxboot:ppc32 - :avocado: tags=image:uImage - :avocado: tags=shutdown:nowait - """ - sums = { "rootfs.ext4.zst" : - "8885b9d999cc24d679542a02e9b6aaf48f718f2050ece6b8347074b6ee41dd09", - "uImage" : - "1a68f74b860fda022fb12e03c5efece8c2b8b590d96cca37a8481a3ae0b3f81f" } - - self.common_tuxrun(csums=sums, drive="virtio-blk-pci") - - def test_ppc64(self): - """ - :avocado: tags=arch:ppc64 - :avocado: tags=machine:pseries - :avocado: tags=cpu:POWER10 - :avocado: tags=endian:big - :avocado: tags=console:hvc0 - :avocado: tags=tuxboot:ppc64 - :avocado: tags=image:vmlinux - :avocado: tags=extradev:driver=spapr-vscsi - :avocado: tags=root:sda - """ - sums = { "rootfs.ext4.zst" : - "1d953e81a4379e537fc8e41e05a0a59d9b453eef97aa03d47866c6c45b00bdff", - "vmlinux" : - "f22a9b9e924174a4c199f4c7e5d91a2339fcfe51c6eafd0907dc3e09b64ab728" } - self.ppc64_common_tuxrun(sums, prefix='tuxrun_ppc64_') - - def test_ppc64le(self): - """ - :avocado: tags=arch:ppc64 - :avocado: tags=machine:pseries - :avocado: tags=cpu:POWER10 - :avocado: tags=console:hvc0 - :avocado: tags=tuxboot:ppc64le - :avocado: tags=image:vmlinux - :avocado: tags=extradev:driver=spapr-vscsi - :avocado: tags=root:sda - """ - sums = { "rootfs.ext4.zst" : - "b442678c93fb8abe1f7d3bfa20556488de6b475c22c8fed363f42cf81a0a3906", - "vmlinux" : - "979eb61b445a010fb13e2b927126991f8ceef9c590fa2be0996c00e293e80cf2" } - self.ppc64_common_tuxrun(sums, prefix='tuxrun_ppc64le_') - - def test_riscv32(self): - """ - :avocado: tags=arch:riscv32 - :avocado: tags=machine:virt - :avocado: tags=tuxboot:riscv32 - """ - sums = { "Image" : - "89599407d7334de629a40e7ad6503c73670359eb5f5ae9d686353a3d6deccbd5", - "fw_jump.elf" : - "f2ef28a0b77826f79d085d3e4aa686f1159b315eff9099a37046b18936676985", - "rootfs.ext4.zst" : - "7168d296d0283238ea73cd5a775b3dd608e55e04c7b92b76ecce31bb13108cba" } - - self.common_tuxrun(csums=sums) - - def test_riscv64(self): - """ - :avocado: tags=arch:riscv64 - :avocado: tags=machine:virt - :avocado: tags=tuxboot:riscv64 - """ - sums = { "Image" : - "cd634badc65e52fb63465ec99e309c0de0369f0841b7d9486f9729e119bac25e", - "fw_jump.elf" : - "6e3373abcab4305fe151b564a4c71110d833c21f2c0a1753b7935459e36aedcf", - "rootfs.ext4.zst" : - "b18e3a3bdf27be03da0b285e84cb71bf09eca071c3a087b42884b6982ed679eb" } - - self.common_tuxrun(csums=sums) - - def test_riscv32_maxcpu(self): - """ - :avocado: tags=arch:riscv32 - :avocado: tags=machine:virt - :avocado: tags=cpu:max - :avocado: tags=tuxboot:riscv32 - """ - sums = { "Image" : - "89599407d7334de629a40e7ad6503c73670359eb5f5ae9d686353a3d6deccbd5", - "fw_jump.elf" : - "f2ef28a0b77826f79d085d3e4aa686f1159b315eff9099a37046b18936676985", - "rootfs.ext4.zst" : - "7168d296d0283238ea73cd5a775b3dd608e55e04c7b92b76ecce31bb13108cba" } - - self.common_tuxrun(csums=sums) - - def test_riscv64_maxcpu(self): - """ - :avocado: tags=arch:riscv64 - :avocado: tags=machine:virt - :avocado: tags=cpu:max - :avocado: tags=tuxboot:riscv64 - """ - sums = { "Image" : - "cd634badc65e52fb63465ec99e309c0de0369f0841b7d9486f9729e119bac25e", - "fw_jump.elf" : - "6e3373abcab4305fe151b564a4c71110d833c21f2c0a1753b7935459e36aedcf", - "rootfs.ext4.zst" : - "b18e3a3bdf27be03da0b285e84cb71bf09eca071c3a087b42884b6982ed679eb" } - - self.common_tuxrun(csums=sums) - - def test_s390(self): - """ - :avocado: tags=arch:s390x - :avocado: tags=endian:big - :avocado: tags=tuxboot:s390 - :avocado: tags=image:bzImage - :avocado: tags=shutdown:nowait - """ - sums = { "bzImage" : - "0414e98dd1c3dafff8496c9cd9c28a5f8d04553bb5ba37e906a812b48d442ef0", - "rootfs.ext4.zst" : - "88c37c32276677f873a25ab9ec6247895b8e3e6f8259134de2a616080b8ab3fc" } - - self.common_tuxrun(csums=sums, - drive="virtio-blk-ccw", - haltmsg="Requesting system halt") - - # Note: some segfaults caused by unaligned userspace access - @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab') - def test_sh4(self): - """ - :avocado: tags=arch:sh4 - :avocado: tags=machine:r2d - :avocado: tags=cpu:sh7785 - :avocado: tags=tuxboot:sh4 - :avocado: tags=image:zImage - :avocado: tags=root:sda - :avocado: tags=console:ttySC1 - :avocado: tags=flaky - """ - sums = { "rootfs.ext4.zst" : - "3592a7a3d5a641e8b9821449e77bc43c9904a56c30d45da0694349cfd86743fd", - "zImage" : - "29d9b2aba604a0f53a5dc3b5d0f2b8e35d497de1129f8ee5139eb6fdf0db692f" } - - # The test is currently too unstable to do much in userspace - # so we skip common_tuxrun and do a minimal boot and shutdown. - (kernel, disk, dtb) = self.fetch_tuxrun_assets(csums=sums) - - # the console comes on the second serial port - self.prepare_run(kernel, disk, - "driver=ide-hd,bus=ide.0,unit=0", - console_index=1) - self.vm.launch() - - self.wait_for_console_pattern("Welcome to TuxTest") - time.sleep(0.1) - exec_command(self, 'root') - time.sleep(0.1) - exec_command_and_wait_for_pattern(self, 'halt', - "reboot: System halted") - - def test_sparc64(self): - """ - :avocado: tags=arch:sparc64 - :avocado: tags=tuxboot:sparc64 - :avocado: tags=image:vmlinux - :avocado: tags=root:sda - :avocado: tags=shutdown:nowait - """ - - sums = { "rootfs.ext4.zst" : - "ad2f1dc436ab51583543d25d2c210cab478645d47078d30d129a66ab0e281d76", - "vmlinux" : - "e34313e4325ff21deaa3d38a502aa09a373ef62b9bd4d7f8f29388b688225c55" } - - self.common_tuxrun(csums=sums, drive="driver=ide-hd,bus=ide.0,unit=0") - - def test_x86_64(self): - """ - :avocado: tags=arch:x86_64 - :avocado: tags=machine:q35 - :avocado: tags=cpu:Nehalem - :avocado: tags=tuxboot:x86_64 - :avocado: tags=image:bzImage - :avocado: tags=root:sda - :avocado: tags=shutdown:nowait - """ - sums = { "bzImage" : - "2bc7480a669ee9b6b82500a236aba0c54233debe98cb968268fa230f52f03461", - "rootfs.ext4.zst" : - "b72ac729769b8f51c6dffb221113c9a063c774dbe1d66af30eb593c4e9999b4b" } - - self.common_tuxrun(csums=sums, - drive="driver=ide-hd,bus=ide.0,unit=0") diff --git a/tests/avocado/version.py b/tests/avocado/version.py deleted file mode 100644 index c613956..0000000 --- a/tests/avocado/version.py +++ /dev/null @@ -1,25 +0,0 @@ -# Version check example test -# -# Copyright (c) 2018 Red Hat, Inc. -# -# Author: -# Cleber Rosa <crosa@redhat.com> -# -# This work is licensed under the terms of the GNU GPL, version 2 or -# later. See the COPYING file in the top-level directory. - - -from avocado_qemu import QemuSystemTest - - -class Version(QemuSystemTest): - """ - :avocado: tags=quick - :avocado: tags=machine:none - """ - def test_qmp_human_info_version(self): - self.vm.add_args('-nodefaults') - self.vm.launch() - res = self.vm.cmd('human-monitor-command', - command_line='info version') - self.assertRegex(res, r'^(\d+\.\d+\.\d)') diff --git a/tests/avocado/virtio-gpu.py b/tests/avocado/virtio-gpu.py deleted file mode 100644 index 6091f61..0000000 --- a/tests/avocado/virtio-gpu.py +++ /dev/null @@ -1,157 +0,0 @@ -# virtio-gpu tests -# -# This work is licensed under the terms of the GNU GPL, version 2 or -# later. See the COPYING file in the top-level directory. - - -from avocado_qemu import BUILD_DIR -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern -from avocado_qemu import exec_command_and_wait_for_pattern -from avocado_qemu import is_readable_executable_file - -from qemu.utils import kvm_available - -import os -import socket -import subprocess - - -def pick_default_vug_bin(): - relative_path = "./contrib/vhost-user-gpu/vhost-user-gpu" - if is_readable_executable_file(relative_path): - return relative_path - - bld_dir_path = os.path.join(BUILD_DIR, relative_path) - if is_readable_executable_file(bld_dir_path): - return bld_dir_path - - -class VirtioGPUx86(QemuSystemTest): - """ - :avocado: tags=virtio-gpu - :avocado: tags=arch:x86_64 - :avocado: tags=cpu:host - """ - - KERNEL_COMMAND_LINE = "printk.time=0 console=ttyS0 rdinit=/bin/bash" - KERNEL_URL = ( - "https://archives.fedoraproject.org/pub/archive/fedora" - "/linux/releases/33/Everything/x86_64/os/images" - "/pxeboot/vmlinuz" - ) - KERNEL_HASH = '1433cfe3f2ffaa44de4ecfb57ec25dc2399cdecf' - INITRD_URL = ( - "https://archives.fedoraproject.org/pub/archive/fedora" - "/linux/releases/33/Everything/x86_64/os/images" - "/pxeboot/initrd.img" - ) - INITRD_HASH = 'c828d68a027b53e5220536585efe03412332c2d9' - - def wait_for_console_pattern(self, success_message, vm=None): - wait_for_console_pattern( - self, - success_message, - failure_message="Kernel panic - not syncing", - vm=vm, - ) - - def test_virtio_vga_virgl(self): - """ - :avocado: tags=device:virtio-vga-gl - """ - # FIXME: should check presence of virtio, virgl etc - self.require_accelerator('kvm') - - kernel_path = self.fetch_asset(self.KERNEL_URL, self.KERNEL_HASH) - initrd_path = self.fetch_asset(self.INITRD_URL, self.INITRD_HASH) - - self.vm.set_console() - self.vm.add_args("-m", "2G") - self.vm.add_args("-machine", "pc,accel=kvm") - self.vm.add_args("-device", "virtio-vga-gl") - self.vm.add_args("-display", "egl-headless") - self.vm.add_args( - "-kernel", - kernel_path, - "-initrd", - initrd_path, - "-append", - self.KERNEL_COMMAND_LINE, - ) - try: - self.vm.launch() - except: - # TODO: probably fails because we are missing the VirGL features - self.cancel("VirGL not enabled?") - - self.wait_for_console_pattern("as init process") - exec_command_and_wait_for_pattern( - self, "/usr/sbin/modprobe virtio_gpu", "" - ) - self.wait_for_console_pattern("features: +virgl +edid") - - def test_vhost_user_vga_virgl(self): - """ - :avocado: tags=device:vhost-user-vga - """ - # FIXME: should check presence of vhost-user-gpu, virgl, memfd etc - self.require_accelerator('kvm') - - vug = pick_default_vug_bin() - if not vug: - self.cancel("Could not find vhost-user-gpu") - - kernel_path = self.fetch_asset(self.KERNEL_URL, self.KERNEL_HASH) - initrd_path = self.fetch_asset(self.INITRD_URL, self.INITRD_HASH) - - # Create socketpair to connect proxy and remote processes - qemu_sock, vug_sock = socket.socketpair( - socket.AF_UNIX, socket.SOCK_STREAM - ) - os.set_inheritable(qemu_sock.fileno(), True) - os.set_inheritable(vug_sock.fileno(), True) - - self._vug_log_path = os.path.join( - self.logdir, "vhost-user-gpu.log" - ) - self._vug_log_file = open(self._vug_log_path, "wb") - self.log.info('Complete vhost-user-gpu.log file can be ' - 'found at %s', self._vug_log_path) - - vugp = subprocess.Popen( - [vug, "--virgl", "--fd=%d" % vug_sock.fileno()], - stdin=subprocess.DEVNULL, - stdout=self._vug_log_file, - stderr=subprocess.STDOUT, - shell=False, - close_fds=False, - ) - - self.vm.set_console() - 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") - self.vm.add_args("-chardev", "socket,id=vug,fd=%d" % qemu_sock.fileno()) - self.vm.add_args("-device", "vhost-user-vga,chardev=vug") - self.vm.add_args("-display", "egl-headless") - self.vm.add_args( - "-kernel", - kernel_path, - "-initrd", - initrd_path, - "-append", - self.KERNEL_COMMAND_LINE, - ) - try: - self.vm.launch() - except: - # TODO: probably fails because we are missing the VirGL features - self.cancel("VirGL not enabled?") - self.wait_for_console_pattern("as init process") - exec_command_and_wait_for_pattern(self, "/usr/sbin/modprobe virtio_gpu", - "features: +virgl +edid") - self.vm.shutdown() - qemu_sock.close() - vugp.terminate() - vugp.wait() diff --git a/tests/avocado/virtio_check_params.py b/tests/avocado/virtio_check_params.py deleted file mode 100644 index 5fe370a..0000000 --- a/tests/avocado/virtio_check_params.py +++ /dev/null @@ -1,143 +0,0 @@ -# -# Test virtio-scsi and virtio-blk queue settings for all machine types -# -# Copyright (c) 2019 Virtuozzo International GmbH -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. -# - -import sys -import os -import re -import logging - -from qemu.machine import QEMUMachine -from avocado_qemu import QemuSystemTest -from avocado import skip - -#list of machine types and virtqueue properties to test -VIRTIO_SCSI_PROPS = {'seg_max_adjust': 'seg_max_adjust'} -VIRTIO_BLK_PROPS = {'seg_max_adjust': 'seg-max-adjust'} - -DEV_TYPES = {'virtio-scsi-pci': VIRTIO_SCSI_PROPS, - 'virtio-blk-pci': VIRTIO_BLK_PROPS} - -VM_DEV_PARAMS = {'virtio-scsi-pci': ['-device', 'virtio-scsi-pci,id=scsi0'], - 'virtio-blk-pci': ['-device', - 'virtio-blk-pci,id=scsi0,drive=drive0', - '-drive', - 'driver=null-co,id=drive0,if=none']} - - -class VirtioMaxSegSettingsCheck(QemuSystemTest): - @staticmethod - def make_pattern(props): - pattern_items = [r'{0} = \w+'.format(prop) for prop in props] - return '|'.join(pattern_items) - - def query_virtqueue(self, vm, dev_type_name): - query_ok = False - error = None - props = None - - output = vm.cmd('human-monitor-command', - command_line = 'info qtree') - props_list = DEV_TYPES[dev_type_name].values(); - pattern = self.make_pattern(props_list) - res = re.findall(pattern, output) - - if len(res) != len(props_list): - props_list = set(props_list) - res = set(res) - not_found = props_list.difference(res) - not_found = ', '.join(not_found) - error = '({0}): The following properties not found: {1}'\ - .format(dev_type_name, not_found) - else: - query_ok = True - props = dict() - for prop in res: - p = prop.split(' = ') - props[p[0]] = p[1] - return query_ok, props, error - - def check_mt(self, mt, dev_type_name): - mt['device'] = dev_type_name # Only for the debug() call. - logger = logging.getLogger('machine') - logger.debug(mt) - with QEMUMachine(self.qemu_bin) as vm: - vm.set_machine(mt["name"]) - vm.add_args('-nodefaults') - for s in VM_DEV_PARAMS[dev_type_name]: - vm.add_args(s) - try: - vm.launch() - query_ok, props, error = self.query_virtqueue(vm, dev_type_name) - except: - query_ok = False - error = sys.exc_info()[0] - - if not query_ok: - self.fail('machine type {0}: {1}'.format(mt['name'], error)) - - for prop_name, prop_val in props.items(): - expected_val = mt[prop_name] - self.assertEqual(expected_val, prop_val) - - @staticmethod - def seg_max_adjust_enabled(mt): - # machine types >= 5.0 should have seg_max_adjust = true - # others seg_max_adjust = false - mt = mt.split("-") - - # machine types with one line name and name like pc-x.x - if len(mt) <= 2: - return False - - # machine types like pc-<chip_name>-x.x[.x] - ver = mt[2] - ver = ver.split("."); - - # versions >= 5.0 goes with seg_max_adjust enabled - major = int(ver[0]) - - if major >= 5: - return True - return False - - @skip("break multi-arch CI") - def test_machine_types(self): - # collect all machine types except 'none', 'isapc', 'microvm' - with QEMUMachine(self.qemu_bin) as vm: - vm.launch() - machines = [m['name'] for m in vm.cmd('query-machines')] - vm.shutdown() - machines.remove('none') - machines.remove('isapc') - machines.remove('microvm') - - for dev_type in DEV_TYPES: - # create the list of machine types and their parameters. - mtypes = list() - for m in machines: - if self.seg_max_adjust_enabled(m): - enabled = 'true' - else: - enabled = 'false' - mtypes.append({'name': m, - DEV_TYPES[dev_type]['seg_max_adjust']: enabled}) - - # test each machine type for a device type - for mt in mtypes: - self.check_mt(mt, dev_type) diff --git a/tests/avocado/virtio_version.py b/tests/avocado/virtio_version.py deleted file mode 100644 index afe5e82..0000000 --- a/tests/avocado/virtio_version.py +++ /dev/null @@ -1,175 +0,0 @@ -""" -Check compatibility of virtio device types -""" -# Copyright (c) 2018 Red Hat, Inc. -# -# Author: -# Eduardo Habkost <ehabkost@redhat.com> -# -# 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 sys -import os - -from qemu.machine import QEMUMachine -from avocado_qemu import QemuSystemTest - -# Virtio Device IDs: -VIRTIO_NET = 1 -VIRTIO_BLOCK = 2 -VIRTIO_CONSOLE = 3 -VIRTIO_RNG = 4 -VIRTIO_BALLOON = 5 -VIRTIO_RPMSG = 7 -VIRTIO_SCSI = 8 -VIRTIO_9P = 9 -VIRTIO_RPROC_SERIAL = 11 -VIRTIO_CAIF = 12 -VIRTIO_GPU = 16 -VIRTIO_INPUT = 18 -VIRTIO_VSOCK = 19 -VIRTIO_CRYPTO = 20 - -PCI_VENDOR_ID_REDHAT_QUMRANET = 0x1af4 - -# Device IDs for legacy/transitional devices: -PCI_LEGACY_DEVICE_IDS = { - VIRTIO_NET: 0x1000, - VIRTIO_BLOCK: 0x1001, - VIRTIO_BALLOON: 0x1002, - VIRTIO_CONSOLE: 0x1003, - VIRTIO_SCSI: 0x1004, - VIRTIO_RNG: 0x1005, - VIRTIO_9P: 0x1009, - VIRTIO_VSOCK: 0x1012, -} - -def pci_modern_device_id(virtio_devid): - return virtio_devid + 0x1040 - -def devtype_implements(vm, devtype, implements): - return devtype in [d['name'] for d in - vm.cmd('qom-list-types', implements=implements)] - -def get_pci_interfaces(vm, devtype): - interfaces = ('pci-express-device', 'conventional-pci-device') - return [i for i in interfaces if devtype_implements(vm, devtype, i)] - -class VirtioVersionCheck(QemuSystemTest): - """ - Check if virtio-version-specific device types result in the - same device tree created by `disable-modern` and - `disable-legacy`. - - :avocado: tags=arch:x86_64 - """ - - # just in case there are failures, show larger diff: - maxDiff = 4096 - - def run_device(self, devtype, opts=None, machine='pc'): - """ - Run QEMU with `-device DEVTYPE`, return device info from `query-pci` - """ - with QEMUMachine(self.qemu_bin) as vm: - vm.set_machine(machine) - if opts: - devtype += ',' + opts - vm.add_args('-device', '%s,id=devfortest' % (devtype)) - vm.add_args('-S') - vm.launch() - - pcibuses = vm.cmd('query-pci') - alldevs = [dev for bus in pcibuses for dev in bus['devices']] - devfortest = [dev for dev in alldevs - if dev['qdev_id'] == 'devfortest'] - return devfortest[0], get_pci_interfaces(vm, devtype) - - - def assert_devids(self, dev, devid, non_transitional=False): - self.assertEqual(dev['id']['vendor'], PCI_VENDOR_ID_REDHAT_QUMRANET) - self.assertEqual(dev['id']['device'], devid) - if non_transitional: - self.assertTrue(0x1040 <= dev['id']['device'] <= 0x107f) - self.assertGreaterEqual(dev['id']['subsystem'], 0x40) - - def check_all_variants(self, qemu_devtype, virtio_devid): - """Check if a virtio device type and its variants behave as expected""" - # Force modern mode: - dev_modern, _ = self.run_device(qemu_devtype, - 'disable-modern=off,disable-legacy=on') - self.assert_devids(dev_modern, pci_modern_device_id(virtio_devid), - non_transitional=True) - - # <prefix>-non-transitional device types should be 100% equivalent to - # <prefix>,disable-modern=off,disable-legacy=on - dev_1_0, nt_ifaces = self.run_device('%s-non-transitional' % (qemu_devtype)) - self.assertEqual(dev_modern, dev_1_0) - - # Force transitional mode: - dev_trans, _ = self.run_device(qemu_devtype, - 'disable-modern=off,disable-legacy=off') - self.assert_devids(dev_trans, PCI_LEGACY_DEVICE_IDS[virtio_devid]) - - # Force legacy mode: - dev_legacy, _ = self.run_device(qemu_devtype, - 'disable-modern=on,disable-legacy=off') - self.assert_devids(dev_legacy, PCI_LEGACY_DEVICE_IDS[virtio_devid]) - - # No options: default to transitional on PC machine-type: - no_opts_pc, generic_ifaces = self.run_device(qemu_devtype) - self.assertEqual(dev_trans, no_opts_pc) - - #TODO: check if plugging on a PCI Express bus will make the - # device non-transitional - #no_opts_q35 = self.run_device(qemu_devtype, machine='q35') - #self.assertEqual(dev_modern, no_opts_q35) - - # <prefix>-transitional device types should be 100% equivalent to - # <prefix>,disable-modern=off,disable-legacy=off - dev_trans, trans_ifaces = self.run_device('%s-transitional' % (qemu_devtype)) - self.assertEqual(dev_trans, dev_trans) - - # ensure the interface information is correct: - self.assertIn('conventional-pci-device', generic_ifaces) - self.assertIn('pci-express-device', generic_ifaces) - - self.assertIn('conventional-pci-device', nt_ifaces) - self.assertIn('pci-express-device', nt_ifaces) - - self.assertIn('conventional-pci-device', trans_ifaces) - self.assertNotIn('pci-express-device', trans_ifaces) - - - def test_conventional_devs(self): - self.check_all_variants('virtio-net-pci', VIRTIO_NET) - # virtio-blk requires 'driver' parameter - #self.check_all_variants('virtio-blk-pci', VIRTIO_BLOCK) - self.check_all_variants('virtio-serial-pci', VIRTIO_CONSOLE) - self.check_all_variants('virtio-rng-pci', VIRTIO_RNG) - self.check_all_variants('virtio-balloon-pci', VIRTIO_BALLOON) - self.check_all_variants('virtio-scsi-pci', VIRTIO_SCSI) - # virtio-9p requires 'fsdev' parameter - #self.check_all_variants('virtio-9p-pci', VIRTIO_9P) - - def check_modern_only(self, qemu_devtype, virtio_devid): - """Check if a modern-only virtio device type behaves as expected""" - # Force modern mode: - dev_modern, _ = self.run_device(qemu_devtype, - 'disable-modern=off,disable-legacy=on') - self.assert_devids(dev_modern, pci_modern_device_id(virtio_devid), - non_transitional=True) - - # No options: should be modern anyway - dev_no_opts, ifaces = self.run_device(qemu_devtype) - self.assertEqual(dev_modern, dev_no_opts) - - self.assertIn('conventional-pci-device', ifaces) - self.assertIn('pci-express-device', ifaces) - - def test_modern_only_devs(self): - self.check_modern_only('virtio-vga', VIRTIO_GPU) - self.check_modern_only('virtio-gpu-pci', VIRTIO_GPU) - self.check_modern_only('virtio-mouse-pci', VIRTIO_INPUT) - self.check_modern_only('virtio-tablet-pci', VIRTIO_INPUT) - self.check_modern_only('virtio-keyboard-pci', VIRTIO_INPUT) diff --git a/tests/avocado/virtiofs_submounts.py.data/cleanup.sh b/tests/avocado/virtiofs_submounts.py.data/cleanup.sh deleted file mode 100644 index 2a6579a..0000000 --- a/tests/avocado/virtiofs_submounts.py.data/cleanup.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash - -function print_usage() -{ - if [ -n "$2" ]; then - echo "Error: $2" - echo - fi - echo "Usage: $1 <scratch dir>" -} - -scratch_dir=$1 -if [ -z "$scratch_dir" ]; then - print_usage "$0" 'Scratch dir not given' >&2 - exit 1 -fi - -cd "$scratch_dir/share" || exit 1 -mps=(mnt*) -mp_i=0 -for mp in "${mps[@]}"; do - mp_i=$((mp_i + 1)) - printf "Unmounting %i/%i...\r" "$mp_i" "${#mps[@]}" - - sudo umount -R "$mp" - rm -rf "$mp" -done -echo - -rm some-file -cd .. -rmdir share - -imgs=(fs*.img) -img_i=0 -for img in "${imgs[@]}"; do - img_i=$((img_i + 1)) - printf "Detaching and deleting %i/%i...\r" "$img_i" "${#imgs[@]}" - - dev=$(losetup -j "$img" | sed -e 's/:.*//') - sudo losetup -d "$dev" - rm -f "$img" -done -echo - -echo 'Done.' diff --git a/tests/avocado/virtiofs_submounts.py.data/guest-cleanup.sh b/tests/avocado/virtiofs_submounts.py.data/guest-cleanup.sh deleted file mode 100644 index 729cb2d..0000000 --- a/tests/avocado/virtiofs_submounts.py.data/guest-cleanup.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -function print_usage() -{ - if [ -n "$2" ]; then - echo "Error: $2" - echo - fi - echo "Usage: $1 <scratch dir>" -} - -scratch_dir=$1 -if [ -z "$scratch_dir" ]; then - print_usage "$0" 'Scratch dir not given' >&2 - exit 1 -fi - -cd "$scratch_dir/share" || exit 1 - -mps=(mnt*) -mp_i=0 -for mp in "${mps[@]}"; do - mp_i=$((mp_i + 1)) - printf "Unmounting %i/%i...\r" "$mp_i" "${#mps[@]}" - - sudo umount -R "$mp" -done -echo - -echo 'Done.' diff --git a/tests/avocado/virtiofs_submounts.py.data/guest.sh b/tests/avocado/virtiofs_submounts.py.data/guest.sh deleted file mode 100644 index 59ba40f..0000000 --- a/tests/avocado/virtiofs_submounts.py.data/guest.sh +++ /dev/null @@ -1,138 +0,0 @@ -#!/bin/bash - -function print_usage() -{ - if [ -n "$2" ]; then - echo "Error: $2" - echo - fi - echo "Usage: $1 <shared dir>" - echo '(The shared directory is the "share" directory in the scratch' \ - 'directory)' -} - -shared_dir=$1 -if [ -z "$shared_dir" ]; then - print_usage "$0" 'Shared dir not given' >&2 - exit 1 -fi - -cd "$shared_dir" - -# FIXME: This should not be necessary, but it is. In order for all -# submounts to be proper mount points, we need to visit them. -# (Before we visit them, they will not be auto-mounted, and so just -# appear as normal directories, with the catch that their st_ino will -# be the st_ino of the filesystem they host, while the st_dev will -# still be the st_dev of the parent.) -# `find` does not work, because it will refuse to touch the mount -# points as long as they are not mounted; their st_dev being shared -# with the parent and st_ino just being the root node's inode ID -# will practically ensure that this node exists elsewhere on the -# filesystem, and `find` is required to recognize loops and not to -# follow them. -# Thus, we have to manually visit all nodes first. - -mnt_i=0 - -function recursively_visit() -{ - pushd "$1" >/dev/null - for entry in *; do - if [[ "$entry" == mnt* ]]; then - mnt_i=$((mnt_i + 1)) - printf "Triggering auto-mount $mnt_i...\r" - fi - - if [ -d "$entry" ]; then - recursively_visit "$entry" - fi - done - popd >/dev/null -} - -recursively_visit . -echo - - -if [ -n "$(find -name not-mounted)" ]; then - echo "Error: not-mounted files visible on mount points:" >&2 - find -name not-mounted >&2 - exit 1 -fi - -if [ ! -f some-file -o "$(cat some-file)" != 'root' ]; then - echo "Error: Bad file in the share root" >&2 - exit 1 -fi - -shopt -s nullglob - -function check_submounts() -{ - local base_path=$1 - - for mp in mnt*; do - printf "Checking submount %i...\r" "$((${#devs[@]} + 1))" - - mp_i=$(echo "$mp" | sed -e 's/mnt//') - dev=$(stat -c '%D' "$mp") - - if [ -n "${devs[mp_i]}" ]; then - echo "Error: $mp encountered twice" >&2 - exit 1 - fi - devs[mp_i]=$dev - - pushd "$mp" >/dev/null - path="$base_path$mp" - while true; do - expected_content="$(printf '%s\n%s\n' "$mp_i" "$path")" - if [ ! -f some-file ]; then - echo "Error: $PWD/some-file does not exist" >&2 - exit 1 - fi - - if [ "$(cat some-file)" != "$expected_content" ]; then - echo "Error: Bad content in $PWD/some-file:" >&2 - echo '--- found ---' - cat some-file - echo '--- expected ---' - echo "$expected_content" - exit 1 - fi - if [ "$(stat -c '%D' some-file)" != "$dev" ]; then - echo "Error: $PWD/some-file has the wrong device ID" >&2 - exit 1 - fi - - if [ -d sub ]; then - if [ "$(stat -c '%D' sub)" != "$dev" ]; then - echo "Error: $PWD/some-file has the wrong device ID" >&2 - exit 1 - fi - cd sub - path="$path/sub" - else - if [ -n "$(echo mnt*)" ]; then - check_submounts "$path/" - fi - break - fi - done - popd >/dev/null - done -} - -root_dev=$(stat -c '%D' some-file) -devs=() -check_submounts '' -echo - -reused_devs=$(echo "$root_dev ${devs[@]}" | tr ' ' '\n' | sort | uniq -d) -if [ -n "$reused_devs" ]; then - echo "Error: Reused device IDs: $reused_devs" >&2 - exit 1 -fi - -echo "Test passed for ${#devs[@]} submounts." diff --git a/tests/avocado/virtiofs_submounts.py.data/host.sh b/tests/avocado/virtiofs_submounts.py.data/host.sh deleted file mode 100644 index d8a9afe..0000000 --- a/tests/avocado/virtiofs_submounts.py.data/host.sh +++ /dev/null @@ -1,127 +0,0 @@ -#!/bin/bash - -mount_count=128 - -function print_usage() -{ - if [ -n "$2" ]; then - echo "Error: $2" - echo - fi - echo "Usage: $1 <scratch dir> [seed]" - echo "(If no seed is given, it will be randomly generated.)" -} - -scratch_dir=$1 -if [ -z "$scratch_dir" ]; then - print_usage "$0" 'No scratch dir given' >&2 - exit 1 -fi - -if [ ! -d "$scratch_dir" ]; then - print_usage "$0" "$scratch_dir is not a directory" >&2 - exit 1 -fi - -seed=$2 -if [ -z "$seed" ]; then - seed=$RANDOM -fi -RANDOM=$seed - -echo "Seed: $seed" - -set -e -shopt -s nullglob - -cd "$scratch_dir" -if [ -d share ]; then - echo 'Error: This directory seems to be in use already' >&2 - exit 1 -fi - -for ((i = 0; i < $mount_count; i++)); do - printf "Setting up fs %i/%i...\r" "$((i + 1))" "$mount_count" - - rm -f fs$i.img - truncate -s 512M fs$i.img - mkfs.xfs -q fs$i.img - devs[i]=$(sudo losetup -f --show fs$i.img) -done -echo - -top_level_mounts=$((RANDOM % mount_count + 1)) - -mkdir -p share -echo 'root' > share/some-file - -for ((i = 0; i < $top_level_mounts; i++)); do - printf "Mounting fs %i/%i...\r" "$((i + 1))" "$mount_count" - - mkdir -p share/mnt$i - touch share/mnt$i/not-mounted - sudo mount "${devs[i]}" share/mnt$i - sudo chown "$(id -u):$(id -g)" share/mnt$i - - pushd share/mnt$i >/dev/null - path=mnt$i - nesting=$((RANDOM % 4)) - for ((j = 0; j < $nesting; j++)); do - cat > some-file <<EOF -$i -$path -EOF - mkdir sub - cd sub - path="$path/sub" - done -cat > some-file <<EOF -$i -$path -EOF - popd >/dev/null -done - -for ((; i < $mount_count; i++)); do - printf "Mounting fs %i/%i...\r" "$((i + 1))" "$mount_count" - - mp_i=$((i % top_level_mounts)) - - pushd share/mnt$mp_i >/dev/null - path=mnt$mp_i - while true; do - sub_mp="$(echo mnt*)" - if cd sub 2>/dev/null; then - path="$path/sub" - elif [ -n "$sub_mp" ] && cd "$sub_mp" 2>/dev/null; then - path="$path/$sub_mp" - else - break - fi - done - mkdir mnt$i - touch mnt$i/not-mounted - sudo mount "${devs[i]}" mnt$i - sudo chown "$(id -u):$(id -g)" mnt$i - - cd mnt$i - path="$path/mnt$i" - nesting=$((RANDOM % 4)) - for ((j = 0; j < $nesting; j++)); do - cat > some-file <<EOF -$i -$path -EOF - mkdir sub - cd sub - path="$path/sub" - done - cat > some-file <<EOF -$i -$path -EOF - popd >/dev/null -done -echo - -echo 'Done.' diff --git a/tests/avocado/vnc.py b/tests/avocado/vnc.py deleted file mode 100644 index 862c899..0000000 --- a/tests/avocado/vnc.py +++ /dev/null @@ -1,115 +0,0 @@ -# Simple functional tests for VNC functionality -# -# Copyright (c) 2018 Red Hat, Inc. -# -# Author: -# Cleber Rosa <crosa@redhat.com> -# -# 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 socket -from typing import List - -from avocado_qemu import QemuSystemTest - - -VNC_ADDR = '127.0.0.1' -VNC_PORT_START = 32768 -VNC_PORT_END = VNC_PORT_START + 1024 - - -def check_bind(port: int) -> bool: - with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: - try: - sock.bind((VNC_ADDR, port)) - except OSError: - return False - - return True - - -def check_connect(port: int) -> bool: - with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: - try: - sock.connect((VNC_ADDR, port)) - except ConnectionRefusedError: - return False - - return True - - -def find_free_ports(count: int) -> List[int]: - result = [] - for port in range(VNC_PORT_START, VNC_PORT_END): - if check_bind(port): - result.append(port) - if len(result) >= count: - break - assert len(result) == count - return result - - -class Vnc(QemuSystemTest): - """ - :avocado: tags=vnc,quick - :avocado: tags=machine:none - """ - def test_no_vnc(self): - self.vm.add_args('-nodefaults', '-S') - self.vm.launch() - self.assertFalse(self.vm.qmp('query-vnc')['return']['enabled']) - - def test_no_vnc_change_password(self): - self.vm.add_args('-nodefaults', '-S') - self.vm.launch() - self.assertFalse(self.vm.qmp('query-vnc')['return']['enabled']) - set_password_response = self.vm.qmp('change-vnc-password', - password='new_password') - self.assertIn('error', set_password_response) - self.assertEqual(set_password_response['error']['class'], - 'GenericError') - self.assertEqual(set_password_response['error']['desc'], - 'Could not set password') - - def test_change_password_requires_a_password(self): - self.vm.add_args('-nodefaults', '-S', '-vnc', ':0') - self.vm.launch() - self.assertTrue(self.vm.qmp('query-vnc')['return']['enabled']) - set_password_response = self.vm.qmp('change-vnc-password', - password='new_password') - self.assertIn('error', set_password_response) - self.assertEqual(set_password_response['error']['class'], - 'GenericError') - self.assertEqual(set_password_response['error']['desc'], - 'Could not set password') - - def test_change_password(self): - self.vm.add_args('-nodefaults', '-S', '-vnc', ':0,password=on') - self.vm.launch() - self.assertTrue(self.vm.qmp('query-vnc')['return']['enabled']) - self.vm.cmd('change-vnc-password', - password='new_password') - - def test_change_listen(self): - a, b, c = find_free_ports(3) - self.assertFalse(check_connect(a)) - self.assertFalse(check_connect(b)) - self.assertFalse(check_connect(c)) - - self.vm.add_args('-nodefaults', '-S', '-vnc', f'{VNC_ADDR}:{a - 5900}') - self.vm.launch() - self.assertEqual(self.vm.qmp('query-vnc')['return']['service'], str(a)) - self.assertTrue(check_connect(a)) - self.assertFalse(check_connect(b)) - self.assertFalse(check_connect(c)) - - self.vm.cmd('display-update', type='vnc', - addresses=[{'type': 'inet', 'host': VNC_ADDR, - 'port': str(b)}, - {'type': 'inet', 'host': VNC_ADDR, - 'port': str(c)}]) - self.assertEqual(self.vm.qmp('query-vnc')['return']['service'], str(b)) - self.assertFalse(check_connect(a)) - self.assertTrue(check_connect(b)) - self.assertTrue(check_connect(c)) diff --git a/tests/avocado/x86_cpu_model_versions.py b/tests/avocado/x86_cpu_model_versions.py deleted file mode 100644 index 11101e0..0000000 --- a/tests/avocado/x86_cpu_model_versions.py +++ /dev/null @@ -1,362 +0,0 @@ -# -# Basic validation of x86 versioned CPU models and CPU model aliases -# -# Copyright (c) 2019 Red Hat Inc -# -# Author: -# Eduardo Habkost <ehabkost@redhat.com> -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, see <http://www.gnu.org/licenses/>. -# - - -import avocado_qemu -import re - -class X86CPUModelAliases(avocado_qemu.QemuSystemTest): - """ - Validation of PC CPU model versions and CPU model aliases - - :avocado: tags=arch:x86_64 - """ - def validate_aliases(self, cpus): - for c in cpus.values(): - if 'alias-of' in c: - # all aliases must point to a valid CPU model name: - self.assertIn(c['alias-of'], cpus, - '%s.alias-of (%s) is not a valid CPU model name' % (c['name'], c['alias-of'])) - # aliases must not point to aliases - self.assertNotIn('alias-of', cpus[c['alias-of']], - '%s.alias-of (%s) points to another alias' % (c['name'], c['alias-of'])) - - # aliases must not be static - self.assertFalse(c['static']) - - def validate_variant_aliases(self, cpus): - # -noTSX, -IBRS and -IBPB variants of CPU models are special: - # they shouldn't have their own versions: - self.assertNotIn("Haswell-noTSX-v1", cpus, - "Haswell-noTSX shouldn't be versioned") - self.assertNotIn("Broadwell-noTSX-v1", cpus, - "Broadwell-noTSX shouldn't be versioned") - self.assertNotIn("Nehalem-IBRS-v1", cpus, - "Nehalem-IBRS shouldn't be versioned") - self.assertNotIn("Westmere-IBRS-v1", cpus, - "Westmere-IBRS shouldn't be versioned") - self.assertNotIn("SandyBridge-IBRS-v1", cpus, - "SandyBridge-IBRS shouldn't be versioned") - self.assertNotIn("IvyBridge-IBRS-v1", cpus, - "IvyBridge-IBRS shouldn't be versioned") - self.assertNotIn("Haswell-noTSX-IBRS-v1", cpus, - "Haswell-noTSX-IBRS shouldn't be versioned") - self.assertNotIn("Haswell-IBRS-v1", cpus, - "Haswell-IBRS shouldn't be versioned") - self.assertNotIn("Broadwell-noTSX-IBRS-v1", cpus, - "Broadwell-noTSX-IBRS shouldn't be versioned") - self.assertNotIn("Broadwell-IBRS-v1", cpus, - "Broadwell-IBRS shouldn't be versioned") - self.assertNotIn("Skylake-Client-IBRS-v1", cpus, - "Skylake-Client-IBRS shouldn't be versioned") - self.assertNotIn("Skylake-Server-IBRS-v1", cpus, - "Skylake-Server-IBRS shouldn't be versioned") - self.assertNotIn("EPYC-IBPB-v1", cpus, - "EPYC-IBPB shouldn't be versioned") - - def test_4_0_alias_compatibility(self): - """ - Check if pc-*-4.0 unversioned CPU model won't be reported as aliases - - :avocado: tags=machine:pc-i440fx-4.0 - """ - # pc-*-4.0 won't expose non-versioned CPU models as aliases - # We do this to help management software to keep compatibility - # with older QEMU versions that didn't have the versioned CPU model - self.vm.add_args('-S') - self.vm.launch() - cpus = dict((m['name'], m) for m in - self.vm.cmd('query-cpu-definitions')) - - self.assertFalse(cpus['Cascadelake-Server']['static'], - 'unversioned Cascadelake-Server CPU model must not be static') - self.assertNotIn('alias-of', cpus['Cascadelake-Server'], - 'Cascadelake-Server must not be an alias') - self.assertNotIn('alias-of', cpus['Cascadelake-Server-v1'], - 'Cascadelake-Server-v1 must not be an alias') - - self.assertFalse(cpus['qemu64']['static'], - 'unversioned qemu64 CPU model must not be static') - self.assertNotIn('alias-of', cpus['qemu64'], - 'qemu64 must not be an alias') - self.assertNotIn('alias-of', cpus['qemu64-v1'], - 'qemu64-v1 must not be an alias') - - self.validate_variant_aliases(cpus) - - # On pc-*-4.0, no CPU model should be reported as an alias: - for name,c in cpus.items(): - self.assertNotIn('alias-of', c, "%s shouldn't be an alias" % (name)) - - def test_4_1_alias(self): - """ - Check if unversioned CPU model is an alias pointing to right version - - :avocado: tags=machine:pc-i440fx-4.1 - """ - self.vm.add_args('-S') - self.vm.launch() - - cpus = dict((m['name'], m) for m in - self.vm.cmd('query-cpu-definitions')) - - self.assertFalse(cpus['Cascadelake-Server']['static'], - 'unversioned Cascadelake-Server CPU model must not be static') - self.assertEqual(cpus['Cascadelake-Server'].get('alias-of'), - 'Cascadelake-Server-v1', - 'Cascadelake-Server must be an alias of Cascadelake-Server-v1') - self.assertNotIn('alias-of', cpus['Cascadelake-Server-v1'], - 'Cascadelake-Server-v1 must not be an alias') - - self.assertFalse(cpus['qemu64']['static'], - 'unversioned qemu64 CPU model must not be static') - self.assertEqual(cpus['qemu64'].get('alias-of'), 'qemu64-v1', - 'qemu64 must be an alias of qemu64-v1') - self.assertNotIn('alias-of', cpus['qemu64-v1'], - 'qemu64-v1 must not be an alias') - - self.validate_variant_aliases(cpus) - - # On pc-*-4.1, -noTSX and -IBRS models should be aliases: - self.assertEqual(cpus["Haswell"].get('alias-of'), - "Haswell-v1", - "Haswell must be an alias") - self.assertEqual(cpus["Haswell-noTSX"].get('alias-of'), - "Haswell-v2", - "Haswell-noTSX must be an alias") - self.assertEqual(cpus["Haswell-IBRS"].get('alias-of'), - "Haswell-v3", - "Haswell-IBRS must be an alias") - self.assertEqual(cpus["Haswell-noTSX-IBRS"].get('alias-of'), - "Haswell-v4", - "Haswell-noTSX-IBRS must be an alias") - - self.assertEqual(cpus["Broadwell"].get('alias-of'), - "Broadwell-v1", - "Broadwell must be an alias") - self.assertEqual(cpus["Broadwell-noTSX"].get('alias-of'), - "Broadwell-v2", - "Broadwell-noTSX must be an alias") - self.assertEqual(cpus["Broadwell-IBRS"].get('alias-of'), - "Broadwell-v3", - "Broadwell-IBRS must be an alias") - self.assertEqual(cpus["Broadwell-noTSX-IBRS"].get('alias-of'), - "Broadwell-v4", - "Broadwell-noTSX-IBRS must be an alias") - - self.assertEqual(cpus["Nehalem"].get('alias-of'), - "Nehalem-v1", - "Nehalem must be an alias") - self.assertEqual(cpus["Nehalem-IBRS"].get('alias-of'), - "Nehalem-v2", - "Nehalem-IBRS must be an alias") - - self.assertEqual(cpus["Westmere"].get('alias-of'), - "Westmere-v1", - "Westmere must be an alias") - self.assertEqual(cpus["Westmere-IBRS"].get('alias-of'), - "Westmere-v2", - "Westmere-IBRS must be an alias") - - self.assertEqual(cpus["SandyBridge"].get('alias-of'), - "SandyBridge-v1", - "SandyBridge must be an alias") - self.assertEqual(cpus["SandyBridge-IBRS"].get('alias-of'), - "SandyBridge-v2", - "SandyBridge-IBRS must be an alias") - - self.assertEqual(cpus["IvyBridge"].get('alias-of'), - "IvyBridge-v1", - "IvyBridge must be an alias") - self.assertEqual(cpus["IvyBridge-IBRS"].get('alias-of'), - "IvyBridge-v2", - "IvyBridge-IBRS must be an alias") - - self.assertEqual(cpus["Skylake-Client"].get('alias-of'), - "Skylake-Client-v1", - "Skylake-Client must be an alias") - self.assertEqual(cpus["Skylake-Client-IBRS"].get('alias-of'), - "Skylake-Client-v2", - "Skylake-Client-IBRS must be an alias") - - self.assertEqual(cpus["Skylake-Server"].get('alias-of'), - "Skylake-Server-v1", - "Skylake-Server must be an alias") - self.assertEqual(cpus["Skylake-Server-IBRS"].get('alias-of'), - "Skylake-Server-v2", - "Skylake-Server-IBRS must be an alias") - - self.assertEqual(cpus["EPYC"].get('alias-of'), - "EPYC-v1", - "EPYC must be an alias") - self.assertEqual(cpus["EPYC-IBPB"].get('alias-of'), - "EPYC-v2", - "EPYC-IBPB must be an alias") - - self.validate_aliases(cpus) - - def test_none_alias(self): - """ - Check if unversioned CPU model is an alias pointing to some version - - :avocado: tags=machine:none - """ - self.vm.add_args('-S') - self.vm.launch() - - cpus = dict((m['name'], m) for m in - self.vm.cmd('query-cpu-definitions')) - - self.assertFalse(cpus['Cascadelake-Server']['static'], - 'unversioned Cascadelake-Server CPU model must not be static') - self.assertTrue(re.match('Cascadelake-Server-v[0-9]+', cpus['Cascadelake-Server']['alias-of']), - 'Cascadelake-Server must be an alias of versioned CPU model') - self.assertNotIn('alias-of', cpus['Cascadelake-Server-v1'], - 'Cascadelake-Server-v1 must not be an alias') - - self.assertFalse(cpus['qemu64']['static'], - 'unversioned qemu64 CPU model must not be static') - self.assertTrue(re.match('qemu64-v[0-9]+', cpus['qemu64']['alias-of']), - 'qemu64 must be an alias of versioned CPU model') - self.assertNotIn('alias-of', cpus['qemu64-v1'], - 'qemu64-v1 must not be an alias') - - self.validate_aliases(cpus) - - -class CascadelakeArchCapabilities(avocado_qemu.QemuSystemTest): - """ - Validation of Cascadelake arch-capabilities - - :avocado: tags=arch:x86_64 - """ - def get_cpu_prop(self, prop): - cpu_path = self.vm.cmd('query-cpus-fast')[0].get('qom-path') - return self.vm.cmd('qom-get', path=cpu_path, property=prop) - - 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.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') - - def test_4_0(self): - """ - :avocado: tags=machine:pc-i440fx-4.0 - :avocado: tags=cpu:Cascadelake-Server - """ - self.vm.add_args('-S') - 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') - - 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.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') - - def test_unset_4_1(self): - """ - :avocado: tags=machine:pc-i440fx-4.1 - :avocado: tags=cpu:Cascadelake-Server - """ - self.vm.add_args('-S') - 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') - - 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.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') - - def test_v2_4_0(self): - """ - :avocado: tags=machine:pc-i440fx-4.0 - :avocado: tags=cpu:Cascadelake-Server - """ - self.vm.add_args('-S') - 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') - - 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.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') - - 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.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') |