diff --git a/pytest_fixtures/component/provision_libvirt.py b/pytest_fixtures/component/provision_libvirt.py index b294ca27a29..82f06ac86d9 100644 --- a/pytest_fixtures/component/provision_libvirt.py +++ b/pytest_fixtures/component/provision_libvirt.py @@ -1,11 +1,23 @@ # Compute resource - Libvirt entities +from fauxfactory import gen_string import pytest +from robottelo.config import settings +from robottelo.constants import COMPUTE_PROFILE_SMALL, FOREMAN_PROVIDERS, LIBVIRT_RESOURCE_URL + +LIBVIRT_URL = LIBVIRT_RESOURCE_URL % settings.libvirt.libvirt_hostname + @pytest.fixture(scope='module') def module_cr_libvirt(module_target_sat, module_org, module_location): + """Create a Libvirt compute resource for the module.""" return module_target_sat.api.LibvirtComputeResource( - organization=[module_org], location=[module_location] + name=gen_string('alpha'), + provider=FOREMAN_PROVIDERS['libvirt'], + display_type='VNC', + organization=[module_org], + location=[module_location], + url=LIBVIRT_URL, ).create() @@ -19,3 +31,24 @@ def module_libvirt_provisioning_sat(module_provisioning_sat): # Configure Libvirt CR for provisioning module_provisioning_sat.sat.configure_libvirt_cr() return module_provisioning_sat + + +@pytest.fixture(scope='module') +def module_libvirt_compute_profile(module_target_sat, module_cr_libvirt): + """Create compute attributes for Libvirt compute profile.""" + return module_target_sat.api.ComputeAttribute( + compute_profile=COMPUTE_PROFILE_SMALL, + compute_resource=module_cr_libvirt, + vm_attrs={ + 'cpus': 1, + 'memory': 6442450944, + 'firmware': 'Automatic', + 'volumes_attributes': {'0': {'capacity': '10G', 'format_type': 'qcow2'}}, + 'nics_attributes': { + '0': { + 'type': 'bridge', + 'bridge': f'br-{settings.provisioning.vlan_id}', + }, + }, + }, + ).create() diff --git a/tests/foreman/ui/test_computeresource_libvirt.py b/tests/foreman/ui/test_computeresource_libvirt.py index 2d77786370b..8ebfaef6cf4 100644 --- a/tests/foreman/ui/test_computeresource_libvirt.py +++ b/tests/foreman/ui/test_computeresource_libvirt.py @@ -211,3 +211,137 @@ def test_positive_provision_end_to_end( session.host.delete(name) assert not sat.api.Host().search(query={'search': f'name="{name}"'}) + + +@pytest.mark.e2e +@pytest.mark.on_premises_provisioning +@pytest.mark.parametrize('setting_update', ['destroy_vm_on_host_delete=True'], indirect=True) +@pytest.mark.parametrize('pxe_loader', ['bios', 'uefi'], indirect=True) +@pytest.mark.rhel_ver_list('[10]') +def test_positive_image_provision_end_to_end( + request, + session, + setting_update, + module_provisioning_rhel_content, + module_libvirt_provisioning_sat, + configure_secureboot_provisioning, + module_sca_manifest_org, + module_location, + module_ssh_key_file, + pxe_loader, + module_cr_libvirt, + default_architecture, + module_libvirt_compute_profile, +): + """Perform end to end testing for image-based provisioning on Libvirt compute resource. + + :id: cd9bc749-4e4f-4639-bc9b-d9fc2a2d98e9 + + :steps: + 1. Configure provisioning setup with required content and networking. + 2. Create a Libvirt compute resource image with credentials and OS details. + 3. Create a host via UI using image-based provisioning method. + 4. Verify the VM is running on the Libvirt hypervisor. + 5. Monitor and verify the build status transitions to 'Installed'. + 6. If SecureBoot is configured, validate it's enabled on the provisioned host. + + :expectedresults: + 1. Image is successfully created on the compute resource. + 2. Host is created via UI without errors. + 3. VM appears in the running state on the Libvirt hypervisor. + 4. Build status progresses from 'Pending installation' to 'Installed'. + 5. SecureBoot is enabled when UEFI SecureBoot firmware is configured. + + :CaseImportance: Critical + """ + # Initialize satellite and network configuration objects + sat = module_libvirt_provisioning_sat.sat + subnet = module_libvirt_provisioning_sat.subnet + + # Generate a unique hostname for the test VM + hostname = gen_string('alpha').lower() + + # Create an image resource on the Libvirt compute resource + # This image will be used as the base for provisioning the host + image = sat.api.Image( + compute_resource=module_cr_libvirt, + name=gen_string('alpha'), + operatingsystem=module_provisioning_rhel_content.os, + architecture=default_architecture, + username=settings.libvirt.image_username, + password=settings.libvirt.image_password, + uuid=settings.libvirt.libvirt_image_path, + ).create() + + @request.addfinalizer + def _finalize(): + # Cleanup: Delete the image and compute resource after test execution. + sat.provisioning_cleanup(host_fqdn) + cr = sat.api.LibvirtComputeResource().search( + query={'search': f'name={module_cr_libvirt.id}'} + ) + sat.api.Image(id=image.id, compute_resource=module_cr_libvirt.id).delete() + if cr: + sat.api.LibvirtComputeResource(id=cr[0].id).delete() + + # Begin UI session to create and manage the host + with sat.ui_session() as session: + session.organization.select(org_name=module_sca_manifest_org.name) + session.location.select(loc_name=module_location.name) + + # Create a new host via the UI with image-based provisioning + session.host.create( + { + 'host.name': hostname, + 'host.organization': module_sca_manifest_org.name, + 'host.location': module_location.name, + 'host.deploy': f'{module_cr_libvirt.name} (Libvirt)', + 'host.compute_profile': COMPUTE_PROFILE_SMALL, + 'host.content_source': sat.hostname, + 'operating_system.architecture': 'x86_64', + 'operating_system.operating_system': module_provisioning_rhel_content.os.title, + 'provider_content.operating_system.provision_method': 'image', + 'operating_system.root_password': gen_string('alpha').lower(), + 'interfaces.interface.domain': module_libvirt_provisioning_sat.domain.name, + 'interfaces.interface.subnet': f'{subnet.name} ({subnet.network}/{subnet.cidr})', + } + ) + + # Verify the VM was successfully created and is running on the Libvirt hypervisor + result = sat.execute( + f'su foreman -s /bin/bash -c "virsh -c {LIBVIRT_URL} list --state-running"' + ) + assert hostname in result.stdout, f"VM '{hostname}' not found in running VMs on hypervisor" + + # Monitor the build status until provisioning completes + # The host should transition from 'Pending installation' to 'Installed' + host_fqdn = f'{hostname}.{module_libvirt_provisioning_sat.domain.name}' + wait_for( + lambda: session.host_new.get_host_statuses(host_fqdn)['Build']['Status'] + != 'Pending installation', + timeout=1800, + delay=30, + fail_func=session.browser.refresh, + silent_failure=True, + handle_exception=True, + ) + + # Verify the final build status is 'Installed' + values = session.host_new.get_host_statuses(host_fqdn) + assert values['Build']['Status'] == 'Installed' + + # If UEFI SecureBoot firmware is configured, verify SecureBoot is enabled on the host + if pxe_loader.vm_firmware == 'uefi_secure_boot': + # Search for the provisioned host to get its details + host_info = sat.api.Host().search(query={'search': f'name="{host_fqdn}"'}) + for host in host_info: + # Establish SSH connection to the provisioned host + provisioning_host = ContentHost(host.ip, auth=module_ssh_key_file) + + # Wait for the host to complete reboot and SSH service to be available + provisioning_host.wait_for_connection() + + # Verify SecureBoot is enabled using mokutil command + assert ( + 'SecureBoot enabled' in provisioning_host.execute('mokutil --sb-state').stdout + ), "SecureBoot is not enabled on the provisioned host"