From 6765ac47382322fc879826bca7e1898c2e4e89a0 Mon Sep 17 00:00:00 2001 From: Ladislav Vasina Date: Tue, 1 Jul 2025 12:07:41 +0200 Subject: [PATCH 1/5] disassociateHostsCoverage --- tests/foreman/ui/test_host.py | 146 ++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) diff --git a/tests/foreman/ui/test_host.py b/tests/foreman/ui/test_host.py index ff55eb53fc0..153c11962f4 100644 --- a/tests/foreman/ui/test_host.py +++ b/tests/foreman/ui/test_host.py @@ -38,6 +38,7 @@ FAKE_7_CUSTOM_PACKAGE, FAKE_8_CUSTOM_PACKAGE, FAKE_8_CUSTOM_PACKAGE_NAME, + FOREMAN_PROVIDERS, OSCAP_PERIOD, OSCAP_WEEKDAY, REPO_TYPE, @@ -45,6 +46,7 @@ ROLES, ) from robottelo.constants.repos import CUSTOM_FILE_REPO +from robottelo.exceptions import CLIReturnCodeError from robottelo.utils.datafactory import gen_string from tests.foreman.api.test_errata import cv_publish_promote @@ -2985,3 +2987,147 @@ def test_positive_manage_repository_sets( for content_host in content_hosts: output = content_host.execute('subscription-manager repos --list').stdout assert "Enabled: 1" in output, 'repository status not changed' + + +def test_disassociate_multiple_hosts( + new_host_ui, request, session, target_sat, module_location, module_org, vmware +): + """ + Import multiple VMs from a VMware compute resource, disassociate them via the UI, + and verify via API that their uuid and compute_resource_id are cleared. + + :id: e5af21c7-62ef-4cc7-a72a-ab6c26090b68 + + :steps: + 1. Create all required entities (domain, subnet, hostgroup, etc.) + 2. Import 2 VMs from VMware into Satellite + 3. Disassociate the VMs via the All Hosts UI + 4. Verify via API that uuid and compute_resource_id are None + + :expectedresults: VMs are disassociated and their compute resource info is cleared. + + :CaseComponent: Hosts-Content + + :Team: Phoenix-subscriptions + """ + + cr_name = gen_string('alpha') + hostgroup_name = gen_string('alpha') + + # create entities for hostgroup + default_loc_id = ( + target_sat.api.Location().search(query={'search': f'name="{DEFAULT_LOC}"'})[0].id + ) + target_sat.api.SmartProxy(id=1, location=[default_loc_id, module_location.id]).update() + domain = target_sat.api.Domain( + organization=[module_org.id], location=[module_location] + ).create() + subnet = target_sat.api.Subnet( + organization=[module_org.id], location=[module_location], domain=[domain] + ).create() + architecture = target_sat.api.Architecture().create() + ptable = target_sat.api.PartitionTable( + organization=[module_org.id], location=[module_location] + ).create() + operatingsystem = target_sat.api.OperatingSystem( + architecture=[architecture], ptable=[ptable] + ).create() + medium = target_sat.api.Media( + organization=[module_org.id], location=[module_location], operatingsystem=[operatingsystem] + ).create() + lce = ( + target_sat.api.LifecycleEnvironment(name="Library", organization=module_org.id) + .search()[0] + .read() + .id + ) + cv = target_sat.api.ContentView(organization=module_org).create() + cv.publish() + + # create hostgroup + hostgroup_name = gen_string('alpha') + target_sat.api.HostGroup( + name=hostgroup_name, + architecture=architecture, + domain=domain, + subnet=subnet, + location=[module_location.id], + medium=medium, + operatingsystem=operatingsystem, + organization=[module_org], + ptable=ptable, + lifecycle_environment=lce, + content_view=cv, + content_source=1, + ).create() + + with session: + session.organization.select(org_name=module_org.name) + session.location.select(loc_name=module_location.name) + session.computeresource.create( + { + 'name': cr_name, + 'provider': FOREMAN_PROVIDERS['vmware'], + 'provider_content.vcenter': vmware.hostname, + 'provider_content.user': settings.vmware.username, + 'provider_content.password': settings.vmware.password, + 'provider_content.datacenter.value': settings.vmware.datacenter, + 'locations.resources.assigned': [module_location.name], + 'organizations.resources.assigned': [module_org.name], + } + ) + session.hostgroup.update(hostgroup_name, {'host_group.deploy': cr_name + " (VMware)"}) + + cr_vm_names = [settings.vmware.vm_name, 'phoenix-testing-guest-rhel-8'] + vm_names_with_domains = [f'{name.replace(".", "")}.{domain.name}' for name in cr_vm_names] + + # Import VMs from VMware compute resource + for cr_vm_name, vm_name_with_domain in zip( + cr_vm_names, vm_names_with_domains, strict=False + ): + session.computeresource.vm_import( + cr_name, + cr_vm_name, + hostgroup_name, + module_location.name, + name=cr_vm_name.replace('.', ''), + ) + assert session.all_hosts.search(vm_name_with_domain) + + @request.addfinalizer + def _cleanup(): + for vm_name in vm_names_with_domains: + try: + target_sat.cli.Host.delete({'name': vm_name}) + except CLIReturnCodeError as e: + print(f"Failed to delete VM {vm_name}: {e}") + + vm_values_pre_disassociation = {} + for vm_name in vm_names_with_domains: + # Get info about host from API + api_val_pre_disassociation = target_sat.api.Host().search( + query={"search": f'name={vm_name}'} + )[0] + vm_values_pre_disassociation[vm_name] = api_val_pre_disassociation + # Check that uuid and compute_resource_id are set + assert api_val_pre_disassociation.uuid is not None, f"UUID for {vm_name} is not set" + assert api_val_pre_disassociation.compute_resource.id is not None, ( + f"Compute resource ID for {vm_name} is not set" + ) + + session.all_hosts.disassociate_hosts(host_names=vm_names_with_domains) + + vm_values_post_disassociation = {} + for vm_name in vm_names_with_domains: + # Get info about host from API + api_val_post_disassociation = target_sat.api.Host().search( + query={"search": f'name={vm_name}'} + )[0] + vm_values_post_disassociation[vm_name] = api_val_post_disassociation + # Check that uuid and compute_resource_id are set to None + assert api_val_post_disassociation.uuid is None, ( + f"UUID for {vm_name} is not None after disassociation" + ) + assert api_val_post_disassociation.compute_resource is None, ( + f"Compute resource ID for {vm_name} is not None after disassociation" + ) From 001eba0d94d3751e8800b6abe2a08654c5f7c9c4 Mon Sep 17 00:00:00 2001 From: Ladislav Vasina Date: Tue, 1 Jul 2025 13:00:03 +0200 Subject: [PATCH 2/5] UiSessionUpdate --- tests/foreman/ui/test_host.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/foreman/ui/test_host.py b/tests/foreman/ui/test_host.py index 153c11962f4..fe1d10a2d23 100644 --- a/tests/foreman/ui/test_host.py +++ b/tests/foreman/ui/test_host.py @@ -2990,7 +2990,7 @@ def test_positive_manage_repository_sets( def test_disassociate_multiple_hosts( - new_host_ui, request, session, target_sat, module_location, module_org, vmware + new_host_ui, request, target_sat, module_location, module_org, vmware ): """ Import multiple VMs from a VMware compute resource, disassociate them via the UI, @@ -3061,7 +3061,7 @@ def test_disassociate_multiple_hosts( content_source=1, ).create() - with session: + with target_sat.ui_session() as session: session.organization.select(org_name=module_org.name) session.location.select(loc_name=module_location.name) session.computeresource.create( From a94021069a719424f586ff12e9d4fb36d2cf42cc Mon Sep 17 00:00:00 2001 From: Ladislav Vasina Date: Wed, 2 Jul 2025 16:56:04 +0200 Subject: [PATCH 3/5] Adress comment --- tests/foreman/ui/test_host.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/foreman/ui/test_host.py b/tests/foreman/ui/test_host.py index fe1d10a2d23..b9a2c811461 100644 --- a/tests/foreman/ui/test_host.py +++ b/tests/foreman/ui/test_host.py @@ -3102,13 +3102,11 @@ def _cleanup(): except CLIReturnCodeError as e: print(f"Failed to delete VM {vm_name}: {e}") - vm_values_pre_disassociation = {} for vm_name in vm_names_with_domains: # Get info about host from API api_val_pre_disassociation = target_sat.api.Host().search( query={"search": f'name={vm_name}'} )[0] - vm_values_pre_disassociation[vm_name] = api_val_pre_disassociation # Check that uuid and compute_resource_id are set assert api_val_pre_disassociation.uuid is not None, f"UUID for {vm_name} is not set" assert api_val_pre_disassociation.compute_resource.id is not None, ( @@ -3117,13 +3115,11 @@ def _cleanup(): session.all_hosts.disassociate_hosts(host_names=vm_names_with_domains) - vm_values_post_disassociation = {} for vm_name in vm_names_with_domains: # Get info about host from API api_val_post_disassociation = target_sat.api.Host().search( query={"search": f'name={vm_name}'} )[0] - vm_values_post_disassociation[vm_name] = api_val_post_disassociation # Check that uuid and compute_resource_id are set to None assert api_val_post_disassociation.uuid is None, ( f"UUID for {vm_name} is not None after disassociation" From fb0dfef9be4eb6b2c1aa06195de4c76fe5c48ebd Mon Sep 17 00:00:00 2001 From: Ladislav Vasina Date: Mon, 7 Jul 2025 16:26:12 +0200 Subject: [PATCH 4/5] AdressComments --- tests/foreman/ui/test_host.py | 45 ++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/tests/foreman/ui/test_host.py b/tests/foreman/ui/test_host.py index b9a2c811461..797a06f2c80 100644 --- a/tests/foreman/ui/test_host.py +++ b/tests/foreman/ui/test_host.py @@ -46,7 +46,7 @@ ROLES, ) from robottelo.constants.repos import CUSTOM_FILE_REPO -from robottelo.exceptions import CLIReturnCodeError +from robottelo.exceptions import APIResponseError from robottelo.utils.datafactory import gen_string from tests.foreman.api.test_errata import cv_publish_promote @@ -2990,7 +2990,13 @@ def test_positive_manage_repository_sets( def test_disassociate_multiple_hosts( - new_host_ui, request, target_sat, module_location, module_org, vmware + new_host_ui, + request, + target_sat, + module_location, + module_org, + vmware, + default_location, ): """ Import multiple VMs from a VMware compute resource, disassociate them via the UI, @@ -3015,10 +3021,9 @@ def test_disassociate_multiple_hosts( hostgroup_name = gen_string('alpha') # create entities for hostgroup - default_loc_id = ( - target_sat.api.Location().search(query={'search': f'name="{DEFAULT_LOC}"'})[0].id - ) - target_sat.api.SmartProxy(id=1, location=[default_loc_id, module_location.id]).update() + target_sat.api.SmartProxy( + id=target_sat.nailgun_smart_proxy.id, location=[default_location.id, module_location.id] + ).update() domain = target_sat.api.Domain( organization=[module_org.id], location=[module_location] ).create() @@ -3058,7 +3063,7 @@ def test_disassociate_multiple_hosts( ptable=ptable, lifecycle_environment=lce, content_view=cv, - content_source=1, + content_source=target_sat.nailgun_smart_proxy.id, ).create() with target_sat.ui_session() as session: @@ -3076,7 +3081,9 @@ def test_disassociate_multiple_hosts( 'organizations.resources.assigned': [module_org.name], } ) - session.hostgroup.update(hostgroup_name, {'host_group.deploy': cr_name + " (VMware)"}) + session.hostgroup.update( + hostgroup_name, {'host_group.deploy': f'{cr_name} ({FOREMAN_PROVIDERS["vmware"]})'} + ) cr_vm_names = [settings.vmware.vm_name, 'phoenix-testing-guest-rhel-8'] vm_names_with_domains = [f'{name.replace(".", "")}.{domain.name}' for name in cr_vm_names] @@ -3098,18 +3105,16 @@ def test_disassociate_multiple_hosts( def _cleanup(): for vm_name in vm_names_with_domains: try: - target_sat.cli.Host.delete({'name': vm_name}) - except CLIReturnCodeError as e: + target_sat.api.Host().search(query={"search": f'name={vm_name}'})[0].delete() + except APIResponseError as e: print(f"Failed to delete VM {vm_name}: {e}") for vm_name in vm_names_with_domains: # Get info about host from API - api_val_pre_disassociation = target_sat.api.Host().search( - query={"search": f'name={vm_name}'} - )[0] + host = target_sat.api.Host().search(query={"search": f'name={vm_name}'})[0] # Check that uuid and compute_resource_id are set - assert api_val_pre_disassociation.uuid is not None, f"UUID for {vm_name} is not set" - assert api_val_pre_disassociation.compute_resource.id is not None, ( + assert host.uuid is not None, f"UUID for {vm_name} is not set" + assert host.compute_resource.id is not None, ( f"Compute resource ID for {vm_name} is not set" ) @@ -3117,13 +3122,9 @@ def _cleanup(): for vm_name in vm_names_with_domains: # Get info about host from API - api_val_post_disassociation = target_sat.api.Host().search( - query={"search": f'name={vm_name}'} - )[0] + host = target_sat.api.Host().search(query={"search": f'name={vm_name}'})[0] # Check that uuid and compute_resource_id are set to None - assert api_val_post_disassociation.uuid is None, ( - f"UUID for {vm_name} is not None after disassociation" - ) - assert api_val_post_disassociation.compute_resource is None, ( + assert host.uuid is None, f"UUID for {vm_name} is not None after disassociation" + assert host.compute_resource is None, ( f"Compute resource ID for {vm_name} is not None after disassociation" ) From f1d22746c9274196071f5394d5384a3876094d42 Mon Sep 17 00:00:00 2001 From: Ladislav Vasina Date: Tue, 8 Jul 2025 09:32:38 +0200 Subject: [PATCH 5/5] RemoveDuplication --- tests/foreman/ui/test_host.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/foreman/ui/test_host.py b/tests/foreman/ui/test_host.py index 797a06f2c80..dcb12ffb2a8 100644 --- a/tests/foreman/ui/test_host.py +++ b/tests/foreman/ui/test_host.py @@ -3018,7 +3018,6 @@ def test_disassociate_multiple_hosts( """ cr_name = gen_string('alpha') - hostgroup_name = gen_string('alpha') # create entities for hostgroup target_sat.api.SmartProxy(