Skip to content

Commit

Permalink
guest_os_booting: update tests for s390x
Browse files Browse the repository at this point in the history
The following features are not available on s390x:
* SMBIOS
* ACPI
* fw_cfg
* USB
* <boot dev.../>
* firmware settings
* SATA

For direct kernel boot, don't use hard coded kernel filename.
In our setup we'll use kernel.img, so just use the filename
from the download url.

Don't use ttyS0, it's the line mode console which is not useful.
Using ttysclp0 is the standard on s390x.

Cover also s390x-specific parameter @loadparm by allowing generically
to run a test command in the booted VM whose output should match an
expected regular expression.

On s390x, the VM will stop if no bootable medium - such as missing cdrom
file - is found.

Some tests were written assuming the VM would use the //os/boot element
instead of the per-device element by trying to remove only that element.
Instead just remove all present boot elements in these cases, no matter
where, the test will define the new one that's relevant for the test
case.

In some boot tests also enable boot for VMs without Secure Boot, where
there's no firmware.

Add test case that attaches same bootable device twice, this had a bug
on s390x recently.

s390x currently doesn't have secure boot. Use the first VM and don't set
os attributes that relate to secure boot on other archs.

Move s390x PXE setup to provider for reuse in boot order tests.
Allow for pxelinux.cfg without kickstart, for the boot check we don't
need it.

Signed-off-by: Sebastian Mitterle <[email protected]>
  • Loading branch information
smitterl authored and libvirt-qe committed Dec 20, 2024
1 parent 9e94e76 commit 362175e
Show file tree
Hide file tree
Showing 17 changed files with 216 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,28 @@
- without_cdrom:
only os_dev
- with_cdrom_with_no_src:
no s390-virtio
cdrom1_attrs = {'target': {'dev': 'sda', 'bus': 'sata'}, **${cdrom_attrs}}
aarch64:
cdrom1_attrs = {'target': {'dev': 'sda', 'bus': 'scsi'}, **${cdrom_attrs}}
bootable_patterns = ["Shell>"]
- with_cdrom:
check_bootable_iso = "yes"
cdrom1_attrs = {'source': {'attrs': {'file': boot_img_path}}, 'target': {'dev': 'sda', 'bus': 'scsi'}, **${cdrom_attrs}}
bootable_patterns = ["begin the installation process|Install Red Hat Enterprise"]
bootable_patterns = ["begin the installation process|Install Red Hat Enterprise|Starting installer"]
- multi_cdroms:
cdrom1_attrs = {'target': {'dev': 'sda', 'bus': 'scsi'}, **${cdrom_attrs}}
cdrom2_attrs = {'source': {'attrs': {'file': boot_img_path}}, 'target': {'dev': 'sdb', 'bus': 'sata'}, **${cdrom_attrs}}
aarch64:
aarch64, s390-virtio:
cdrom2_attrs = {'source': {'attrs': {'file': boot_img_path}}, 'target': {'dev': 'sdb', 'bus': 'scsi'}, **${cdrom_attrs}}
cdrom_boot_order:
check_bootable_iso = "yes"
bootable_patterns = ["begin the installation process|Install Red Hat Enterprise"]
bootable_patterns = ["begin the installation process|Install Red Hat Enterprise|Starting installer"]
os_dev:
status_error = "yes"
variants:
- os_dev:
no s390-virtio
os_attrs_boots = ['cdrom']
- cdrom_boot_order:
variants firmware_type:
Expand All @@ -36,3 +38,4 @@
status_error = "yes"
- ovmf:
only q35, aarch64
- default:
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
disk1_attrs_target = {'dev': 'vda', 'bus': 'virtio'}
variants:
- os_dev:
no s390-virtio
os_attrs_boots = ['hd']
disk1_attrs = {'target': ${disk1_attrs_target}}
variants:
Expand All @@ -24,8 +25,13 @@
disk2_attrs = {'target': {'dev': 'sda', 'bus': 'scsi'}}
seabios:
status_error = "yes"
- multi_disks_bootable:
disk1_img = "copied_original.qcow2"
disk1_attrs = {'target': ${disk1_attrs_target}}
disk2_attrs = {'target': {'dev': 'sda', 'bus': 'scsi'}}
variants firmware_type:
- seabios:
only x86_64
- ovmf:
only q35, aarch64
- default:
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
os_dict = {'boots': ['%s', '%s'], 'bootmenu_enable': 'yes'}
cdrom_dict = {'source': {'attrs': {'file': '%s'}}, 'type_name': 'file', 'device': 'cdrom', 'driver': {'name': 'qemu', 'type': 'raw'}, 'target': {'dev': 'sda', 'bus': '${target_bus}'}}
check_prompt = ["begin the installation process|Install Red Hat Enterprise"]
no s390-virtio
variants first_dev:
- hd:
variants second_dev:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
aarch64:
os_dict = {'bootmenu_enable': 'yes'}
target_bus = 'scsi'
s390-virtio:
os_dict = {'bootmenu_enable': 'no'}
target_bus = 'scsi'
cdrom_dict = {'source': {'attrs': {'file': '%s'}}, 'type_name': 'file', 'device': 'cdrom', 'driver': {'name': 'qemu', 'type': 'raw'}, 'target': {'dev': 'sda', 'bus': '${target_bus}'}}
check_prompt = ["begin the installation process|Install Red Hat Enterprise"]
check_prompt = ["begin the installation process|Install Red Hat Enterprise|Starting installer"]
variants first_dev:
- hd:
disk_order = {'boot': '1'}
Expand All @@ -16,39 +19,76 @@
cdrom_order = {'boot': '2'}
variants bootable_device:
- hd_bootable:
variants:
- @default:
- with_loadparm:
only s390-virtio
disk_order = {'boot': '1', 'loadparm': '1'}
test_cmd = "lsreipl"
expected_output = Loadparm:\s+"1"
- cdrom_bootable:
- network:
network_order = {'boot': '2'}
variants bootable_device:
- hd_bootable:
- network_bootable:
check_prompt = ["iPXE initialising devices|Start PXE over IPv4"]
s390-virtio:
set_up_tftp = yes
check_prompt = ["Starting installer"]
install_tree_url = INSTALL_TREE_URL
- cdrom:
cdrom_order = {'boot': '1'}
variants second_dev:
- hd:
disk_order = {'boot': '2'}
variants bootable_device:
- hd_bootable:
variants:
- @default:
- with_loadparm:
only s390-virtio
disk_order = {'boot': '2', 'loadparm': '2'}
test_cmd = "lsreipl"
expected_output = Loadparm:\s+"2"
- cdrom_bootable:
- network:
network_order = {'boot': '2'}
variants bootable_device:
- cdrom_bootable:
- network_bootable:
check_prompt = ["iPXE initialising devices|Start PXE over IPv4"]
s390-virtio:
set_up_tftp = yes
check_prompt = ["Starting installer"]
install_tree_url = INSTALL_TREE_URL
- network:
network_order = {'boot': '1'}
variants second_dev:
- hd:
disk_order = {'boot': '2'}
variants bootable_device:
- hd_bootable:
variants:
- @default:
- with_loadparm:
only s390-virtio
disk_order = {'boot': '2', 'loadparm': '2'}
test_cmd = "lsreipl"
expected_output = Loadparm:\s+"2"
- network_bootable:
check_prompt = ["iPXE initialising devices|Start PXE over IPv4"]
s390-virtio:
set_up_tftp = yes
check_prompt = ["Starting installer"]
install_tree_url = INSTALL_TREE_URL
- cdrom:
cdrom_order = {'boot': '2'}
variants bootable_device:
- cdrom_bootable:
- network_bootable:
check_prompt = ["iPXE initialising devices|Start PXE over IPv4"]
s390-virtio:
set_up_tftp = yes
check_prompt = ["Starting installer"]
install_tree_url = INSTALL_TREE_URL
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
bus_type = "usb"
target_disk = "sda"
device_dict = {"type_name":"file", "target":{"dev": "${target_disk}", "bus": "${bus_type}"}, 'boot': '2'}
s390-virtio:
expected_error = unsupported configuration: This QEMU doesn't support
- filesystem_device:
target_dir = "mount_tag"
source_dir = "/tmp"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
initrd_url = "${repo_url}/images/pxeboot/initrd.img"
vmlinuz_url = "${repo_url}/images/pxeboot/vmlinuz"
direct_kernel_dict = {'cmdline': 'console=ttyS0 inst.repo=${repo_url}', 'initrd': '%s', 'kernel': '%s'}
s390-virtio:
direct_kernel_dict = {'cmdline': 'console=ttysclp0 inst.repo=${repo_url}', 'initrd': '%s', 'kernel': '%s'}
variants:
- start_guest:
check_prompt = "Starting installer"
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
acpi_url = "EXAMPLE_ACPI_URL"
acpi_file = "slic.dat"
acpi_dict = {'acpi': {'table_type': 'slic', 'table': '%s'}}
no aarch64
no aarch64, s390-virtio
variants:
- start_guest:
cmd_in_guest = "acpidump"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
- guest_os_booting.smbios_mode:
type = smbios_mode
start_vm = no
no s390-virtio
variants:
- positive_test:
variants smbios_mode:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
type = sysinfo_fwcfg
start_vm = no
entry_value = "example value"
no s390-virtio
variants:
- positive_test:
variants:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
virsh_migrate_connect_uri = "qemu:///system"
variants:
- os_dev:
no s390-virtio
os_attrs_boots = ['hd', 'cdrom', 'network']
- boot_order:
disk_boot_idx = 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,7 @@ def update_vm_xml(vm, params, cdrom_attrs_list):
os_attrs = {'boots': os_attrs_boots}
vmxml.setup_attrs(os=os_attrs)
else:
vm_os = vmxml.os
vm_os.del_boots()
vmxml.os = vm_os
vmxml.remove_all_boots()
if "yes" == params.get("check_bootable_iso", "no"):
os_attrs.update({'bootmenu_enable': 'yes',
'bootmenu_timeout': '3000'})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,19 @@

from virttest.libvirt_xml import vm_xml
from virttest.libvirt_xml.devices import disk
from virttest.utils_misc import cmd_status_output
from virttest.utils_libvirt import libvirt_disk
from virttest.utils_libvirt import libvirt_vmxml

from provider.guest_os_booting import guest_os_booting_base


def parse_disks_attrs(vmxml, params):
def parse_disks_attrs(vmxml, test, params):
"""
Parse disk devices' attrs
:param vmxml: The vmxml object
:param test: The test object
:param params: Dictionary with the test parameters
:return: (Newly created disk image path, list of disk devices' attrs)
"""
Expand All @@ -28,7 +30,14 @@ def parse_disks_attrs(vmxml, params):
if disk1_img:
disk1_img_path = os.path.join(data_dir.get_data_dir(), 'images',
disk1_img)
libvirt_disk.create_disk('file', disk1_img_path, disk_format='qcow2')
if disk1_img == "copied_original.qcow2":
org_source_file = disk_org_attrs['source']['attrs']['file']
cmd_status_output("qemu-img convert "
"-f qcow2 -O qcow2 -o lazy_refcounts=on "
f"{org_source_file} {disk1_img_path}")
else:
libvirt_disk.create_disk('file', disk1_img_path, disk_format='qcow2')

disk1_attrs = copy.deepcopy(disk_org_attrs)
disk1_attrs['source'] = {'attrs': {'file': disk1_img_path}}
disk_attrs_list.append(disk1_attrs)
Expand Down Expand Up @@ -84,22 +93,28 @@ def run(test, params, env):
vm = env.get_vm(vm_name)
vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm.name)
bkxml = vmxml.copy()
session = None

try:
disk1_img_path, disk_attrs_list = parse_disks_attrs(vmxml, params)
disk1_img_path, disk_attrs_list = parse_disks_attrs(vmxml, test, params)
update_vm_xml(vm, params, disk_attrs_list)
test.log.debug(vm_xml.VMXML.new_from_dumpxml(vm.name))

vm.start()
try:
vm.wait_for_serial_login().close()
#vm.wait_for_serial_login(timeout=120).close()
session = vm.wait_for_serial_login()
if 'emergency mode' in session.get_output():
test.fail("Couldn't boot correctly")
except remote.LoginTimeoutError as detail:
if status_error:
test.log.debug("Found the expected error: %s", detail)
else:
test.fail(detail)

finally:
if session:
session.close()
bkxml.sync()
if disk1_img_path and os.path.isfile(disk1_img_path):
test.log.debug(f"removing {disk1_img_path}")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Copyright Red Hat
# SPDX-License-Identifier: GPL-2.0
# Author: Meina Li <[email protected]>

import platform
import os
import re

from avocado.utils import process

Expand All @@ -13,6 +14,7 @@
from virttest.utils_test import libvirt

from provider.guest_os_booting import guest_os_booting_base as guest_os
from provider.virtual_network import tftpboot

# Prepare a list to record the file path which need to be removed
file_list = []
Expand All @@ -33,6 +35,7 @@ def prepare_device_attrs(test, params, vm_name, bootable_device):
disk_order = eval(params.get("disk_order", "{}"))
cdrom_order = eval(params.get("cdrom_order", "{}"))
network_order = eval(params.get("network_order", "{}"))
set_up_tftp = "yes" == params.get("set_up_tftp", "no")
disk_image = os.path.join(data_dir.get_data_dir(), 'images', 'test.img')
vmxml = guest_os.prepare_os_xml(vm_name, os_dict)
vmxml.remove_all_boots()
Expand All @@ -51,6 +54,14 @@ def prepare_device_attrs(test, params, vm_name, bootable_device):
else:
cdrom_path = os.path.join(data_dir.get_data_dir(), 'images', 'test.iso')
libvirt.create_local_disk("file", path=cdrom_path, size="500M", disk_format="raw")
if bootable_device == "network_bootable" and set_up_tftp:
install_tree_url = params.get("install_tree_url")
tftpboot.create_tftp_content(install_tree_url,
None,
arch=platform.machine())
tftpboot.create_tftp_network()
iface_dict = {"type": "network", "source": {'network': tftpboot.net_name},"model": "virtio"}
libvirt_vmxml.modify_vm_device(vmxml, 'interface', iface_dict)
file_list.append(cdrom_path)
cdrom_dict = eval(params.get("cdrom_dict") % cdrom_path)
cdrom_dict.update(cdrom_order)
Expand All @@ -74,10 +85,13 @@ def run(test, params, env):
check_prompt = eval(params.get("check_prompt", "[]"))
bootable_device = params.get("bootable_device")
os_dict = eval(params.get("os_dict"))
test_cmd = params.get("test_cmd", None)
expected_output = params.get("expected_output", None)

vm = env.get_vm(vm_name)
vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm.name)
bkxml = vmxml.copy()
session = None

try:
test.log.info("TEST_SETUP: prepare a guest with necessary attributes.")
Expand All @@ -89,12 +103,20 @@ def run(test, params, env):
test.log.debug(f"The current guest xml is: {vmxml}")
test.log.info("TEST_STEP2: check the guest boot from expected device.")
if bootable_device == "hd_bootable":
vm.wait_for_login(timeout=360).close()
session = vm.wait_for_login(timeout=360)
test.log.debug("Succeed to boot %s", vm_name)
if test_cmd is not None:
output = session.cmd(test_cmd)
if not re.search(expected_output, output):
test.fail(f"Couldn't get {expected_output}, got instead {output}")
test.log.debug("Succeed to set %s", expected_output)
session.close()
else:
vm.serial_console.read_until_output_matches(check_prompt, timeout=300,
internal_timeout=0.5)
finally:
if session:
session.close()
bkxml.sync()
for file in file_list:
if os.path.exists(file):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ def run(test, params, env):
bkxml = vmxml.copy()

try:
boot_initrd = os.path.join(data_dir.get_data_dir(), "initrd.img")
boot_vmlinuz = os.path.join(data_dir.get_data_dir(), "vmlinuz")
boot_initrd = os.path.join(data_dir.get_data_dir(), initrd_url.split("/")[-1])
boot_vmlinuz = os.path.join(data_dir.get_data_dir(), vmlinuz_url.split("/")[-1])
url_download(initrd_url, boot_initrd)
url_download(vmlinuz_url, boot_vmlinuz)
direct_kernel_dict = eval(params.get("direct_kernel_dict")
Expand Down
4 changes: 4 additions & 0 deletions provider/guest_os_booting/guest_os_booting_base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
import platform

from avocado.core import exceptions
from avocado.utils import distro
Expand All @@ -25,6 +26,9 @@ def get_vm(params):
firmware_type = params.get('firmware_type')
detected_distro = distro.detect()
os_type_dict = {}
if platform.machine() == "s390x":
return vms[0]

for _vm in vms:
if os_type_dict.get("seabios") and os_type_dict.get("ovmf"):
break
Expand Down
Loading

0 comments on commit 362175e

Please sign in to comment.