diff --git a/libvirt/tests/cfg/controller/pcie_root_port_controller.cfg b/libvirt/tests/cfg/controller/pcie_root_port_controller.cfg index 36f7492404..b350e4d81a 100644 --- a/libvirt/tests/cfg/controller/pcie_root_port_controller.cfg +++ b/libvirt/tests/cfg/controller/pcie_root_port_controller.cfg @@ -1,8 +1,10 @@ - pcie_root_port_controller: type = pcie_root_port_controller start_vm = "no" + controller_type = "pci" controller_model = "pcie-root-port" controller_target = '{"chassis":1,"port":"0x8"}' + slot_equal_after_define = "yes" variants: - positive_test: status_error = "no" @@ -10,6 +12,17 @@ - controllers_different_chassis_same_port: second_controller_model = "pcie-root-port" second_controller_target = "{'chassis':2,'port':'0x8'}" + - address_slot_too_low: + check_slot = "yes" + wipe_devices = "yes" + test_define_only = "yes" + controller_address = '{"type": "pci", "domain": "0x0000", "bus": "0x00", "slot": "0x00", "function":"0x0"}' + slot_equal_after_define = "no" + - address_slot_min_value: + check_slot = "yes" + wipe_devices = "yes" + test_define_only = "yes" + controller_address = '{"type": "pci", "domain": "0x0000", "bus": "0x00", "slot": "0x03", "function":"0x0"}' - negative_test: status_error = "yes" variants: @@ -22,7 +35,7 @@ test_define_only = "yes" interface_slot_type = "hex" interface_slot = 1 - minimal_interface_dict = '{"source": {"network": "default"}}' + minimal_interface_dict = '{"source": {"network": "default"}, "model": "virtio"}' failure_message = "Invalid PCI address .* slot must be <= 0" - controllers_same_chassis_same_port: second_controller_model = "pcie-root-port" @@ -35,12 +48,12 @@ controller_model = "dmi-to-pci-bridge" - index_equals_address_bus: test_define_only = "yes" - controller_address = '{"type": "pci", "domain": "0x0000", "bus": "0x01", "slot": "0x1", "function":"0x0"}' + controller_address = '{"type": "pci", "domain": "0x0000", "slot": "0x1", "function":"0x0"}' failure_message = ".*The device at PCI address .* cannot be plugged into the PCI controller with index='.*'. It requires a controller that accepts a pcie\-root\-port.*" - index_less_than_address_bus: bus_offset = 1 test_define_only = "yes" - controller_address = '{"type": "pci", "domain": "0x0000", "bus": "0x02", "slot": "0x1", "function":"0x0"}' + controller_address = '{"type": "pci", "domain": "0x0000", "slot": "0x1", "function":"0x0"}' failure_message = ".*a PCI slot is needed to connect a PCI controller model='pcie\-root\-port', but none is available, and it cannot be automatically added.*" - controller_index_zero: test_define_only = "yes" @@ -52,8 +65,8 @@ failure_message = "internal error: a PCI slot is needed to connect a PCI controller model='pcie\-root\-port', but none is available, and it cannot be automatically added" - controller_index_invalid: test_define_only = "yes" - controller_index = xxx - failure_message = "Invalid value for attribute 'index' in element 'controller': 'xxx'. Expected integer value|internal error: Cannot parse controller index xxx" + controller_index = "invalid_index" + failure_message = "Invalid value for attribute 'index' in element 'controller': '${controller_index}'. Expected integer value|internal error: Cannot parse controller index ${controller_index}" - chassis_less_than_valid: test_define_only = "yes" controller_target = '{"chassis":-1,"port":"0x8"}' @@ -68,3 +81,8 @@ test_define_only = "yes" controller_target = '{"chassis":"a","port":"0x8"}' failure_message = "XML error: Invalid value for attribute 'chassis' in element 'target': 'a'. Expected integer value" + - address_slot_too_high: + wipe_devices = "yes" + test_define_only = "yes" + controller_address = '{"type": "pci", "domain": "0x0000", "bus": "0x02", "slot": "0x20", "function":"0x0"}' + failure_message = "Invalid PCI address slot='0x20', must be <= 0x1F" diff --git a/libvirt/tests/src/controller/pcie_root_port_controller.py b/libvirt/tests/src/controller/pcie_root_port_controller.py index aacda0c866..12e2afc86e 100644 --- a/libvirt/tests/src/controller/pcie_root_port_controller.py +++ b/libvirt/tests/src/controller/pcie_root_port_controller.py @@ -19,7 +19,6 @@ def setup_test(params): """ controller_model = params.get("controller_model") controller_target = ast.literal_eval(params.get("controller_target")) - controller_index = params.get("controller_index", 0) second_controller_model = params.get("second_controller_model") second_controller_target = ast.literal_eval( params.get("second_controller_target", "{}")) @@ -27,7 +26,6 @@ def setup_test(params): test_define_only = params.get("test_define_only") == "yes" vmxml.remove_all_device_by_type("controller") - index = 0 contr_dict = {"type": "pci", "model": "pcie-root", "index": index} libvirt_vmxml.modify_vm_device(vmxml, "controller", contr_dict, index) @@ -35,8 +33,9 @@ def setup_test(params): if test_define_only: return - index += 1 - contr_dict = create_controller_dict(controller_model, controller_target, index) + index = 1 + contr_dict = create_controller_dict(controller_model, + controller_target, index) libvirt_vmxml.modify_vm_device(vmxml, "controller", contr_dict, index) if second_controller_model and second_controller_target: @@ -59,7 +58,7 @@ def execute_test(vm, test, params): test_define_only = params.get("test_define_only") == "yes" if test_define_only: vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm.name) - check_define_vm(vmxml, params) + check_define_vm(vmxml, test, params) else: check_vm_start(vm, params) @@ -74,26 +73,30 @@ def create_controller_dict(model, target, index, address=None): :param address: Dict, optional, device address example: {'attrs': {'bus': 0x01}} :returns Built in dictionary, prepared to be added to VM XML """ - contr_dict = {'type': 'pci', - 'model': model, - "index": index, - 'target': target} + contr_dict = {"type": "pci", + "index": index} + if target: + contr_dict.update({"target": target}) + if model: + contr_dict.update({"model": model}) if address: contr_dict.update({"address": address}) LOG.debug("Created controller %s", contr_dict) return contr_dict -def check_define_vm(vmxml, params): +def check_define_vm(vmxml, test, params): """ Alternate function for checking and finishing the test. Checks only if VM define action was successful instead of VM start. :param vmxml: VM XML object + :param test: Avocado test object :param params: Test parameters object """ LOG.info("Checking VM in define only mode.") model = params.get("controller_model") + controller_type = params.get("controller_type") target = params.get("controller_target") address = ast.literal_eval(params.get("controller_address", "{}")) bus_offset = int(params.get("bus_offset", 0)) @@ -102,19 +105,28 @@ def check_define_vm(vmxml, params): minimal_interface_dict = ast.literal_eval(params.get("minimal_interface_dict", "{}")) interface_slot = params.get("interface_slot", 0) interface_slot_type = params.get("interface_slot_type", "int") + check_slot = params.get("check_slot", "no") == "yes" + wipe_devices = params.get("wipe_devices", "no") == "yes" + if wipe_devices: + wipe_pcie_controllers(vmxml) if interface_slot_type == "hex": interface_slot = hex(int(interface_slot)) index = get_controller_index(vmxml, params) - if address: + if address and "bus" not in address: address["bus"] = hex(index + bus_offset) - contr_dict = {'controller_type': 'pci', - 'controller_model': model, + slot_equal_after_define = params.get("slot_equal_after_define", "yes") == "yes" + contr_dict = {'controller_type': controller_type, "controller_index": index, 'controller_target': target, "controller_addr": str(address)} + if model: + contr_dict.update({"controller_model": model}) contr_object = libvirt.create_controller_xml(contr_dict) + if index == 0: + contr_object.index = 0 # Workaround for non-working avocado-vt vmxml.add_device(contr_object) if minimal_interface_dict: + index += 1 interface_dict = customize_interface_dict(minimal_interface_dict, interface_bus=hex(index), interface_slot=interface_slot) @@ -125,14 +137,50 @@ def check_define_vm(vmxml, params): libvirt.check_result(cmd_result, [failure_message]) else: libvirt.check_exit_status(cmd_result, status_error) + if check_slot: + vmxml = vm_xml.VMXML.new_from_inactive_dumpxml( + params.get("main_vm", "avocado-vt-vm1")) + expected_value = address["slot"] + if not check_slot_in_controller(vmxml, index, expected_value, + slot_equal_after_define): + test.fail("Controller slot doesn't have the" + "expected value of %s.", expected_value) + + +def check_slot_in_controller(vmxml, device_index, expected_value, expected_equal=True): + """ + This function checks if address_slot value in a controller in VM XML equals + expected value or not. + + :param vmxml: VM XML object to check + :param device_index: Int, device index to check + :param expected_value: The value that is used in the check + :param expected_equal: Bool, true if expected_value should be equal to + value in xml + :returns Bool, based on the value comparison + """ + controllers = vmxml.get_devices("controller") + device = controllers[device_index] + if expected_equal: + return device.address.attrs["slot"] == expected_value + return device.address.attrs["slot"] != expected_value def get_controller_index(vmxml, params): + """ + Function that finds index for a PCIe controller and returns it + + :param vmxml: VM XML object to check + :param params: Test parameters object + :returns Index number + """ # We want to default to None so we can differentiate between None and 0 controller_index = params.get("controller_index", None) model = params.get("controller_model") - if controller_index is not None: + if controller_index == "invalid_index": return controller_index + if controller_index is not None: + return int(controller_index) max_indexes = libvirt_pcicontr.get_max_contr_indexes(vmxml, 'pci', model, 1) if max_indexes: return max_indexes[0] + 1 @@ -190,6 +238,20 @@ def check_vm_start(vm, params, **virsh_options): libvirt.check_exit_status(cmd_result, status_error) +def wipe_pcie_controllers(vmxml): + """ + Function that removes all controller devices from VM XML. + It then re-adds pcie-root, so that pcie-root-ports can be easily added. + + :param vmxml: VM XML object to check + """ + + vmxml.remove_all_device_by_type("controller") + index = 0 + contr_dict = {"type": "pci", "model": "pcie-root", "index": index} + libvirt_vmxml.modify_vm_device(vmxml, "controller", contr_dict, index) + + def run(test, params, env): """ Function executed by avocado. Similar to "main" function of a module.