From 5153b6cbe908a0290347daa6a296b021b39a7b09 Mon Sep 17 00:00:00 2001 From: David Moore Date: Thu, 11 Jan 2024 17:43:28 -0500 Subject: [PATCH] Pagination in new host UI>errata tab --- tests/foreman/ui/test_errata.py | 250 +++++++++++++++++++++++--------- 1 file changed, 181 insertions(+), 69 deletions(-) diff --git a/tests/foreman/ui/test_errata.py b/tests/foreman/ui/test_errata.py index d7773533a89..b02dc447995 100644 --- a/tests/foreman/ui/test_errata.py +++ b/tests/foreman/ui/test_errata.py @@ -21,6 +21,7 @@ from robottelo.config import settings from robottelo.constants import ( + DEFAULT_ARCHITECTURE, DEFAULT_LOC, FAKE_1_CUSTOM_PACKAGE, FAKE_1_CUSTOM_PACKAGE_NAME, @@ -39,12 +40,19 @@ REAL_0_RH_PACKAGE, REAL_4_ERRATA_CVES, REAL_4_ERRATA_ID, + REPOS, + REPOSET, ) from robottelo.hosts import ContentHost CUSTOM_REPO_URL = settings.repos.yum_9.url +CUSTOM_REPO_ERRATA = settings.repos.yum_9.errata CUSTOM_REPO_ERRATA_ID = settings.repos.yum_9.errata[0] +CUSTOM_REPO_3_URL = settings.repos.yum_3.url +CUSTOM_REPO_3_ERRATA = settings.repos.yum_3.errata +CUSTOM_REPO_3_ERRATA_ID = settings.repos.yum_3.errata[0] + RHVA_PACKAGE = REAL_0_RH_PACKAGE RHVA_ERRATA_ID = REAL_4_ERRATA_ID RHVA_ERRATA_CVES = REAL_4_ERRATA_CVES @@ -139,29 +147,107 @@ def vm(module_repos_collection_with_setup, rhel7_contenthost, target_sat): return rhel7_contenthost +def cv_publish_promote(sat, org, cv, lce=None, needs_publish=True): + """Publish & promote Content View Version with all content visible in org. + + :param lce: if None, default to 'Library', + pass a single instance of lce, or list of instances. + :param bool needs_publish: if False, skip publish of a new version + :return dictionary: + 'content-view': instance of updated cv + 'content-view-version': instance of newest cv version + """ + # Default to 'Library' lce, if None passed + # Take a single instance of lce, or list of instances + lce_ids = 'Library' + if lce is not None: + if not isinstance(lce, list): + lce_ids = [lce.id] + else: + lce_ids = sorted(_lce.id for _lce in lce) + + if needs_publish is True: + _publish_and_wait(sat, org, cv) + # Content-view must have at least one published version + cv = sat.api.ContentView(id=cv.id).read() + assert cv.version, f'No version(s) are published to the Content-View: {cv.id}' + # Find highest version id, will be the latest + cvv_id = max(cvv.id for cvv in cv.version) + # Promote to lifecycle-environment(s) + if lce_ids == 'Library': + library_lce = cv.environment[0].read() + sat.api.ContentViewVersion(id=cvv_id).promote( + data={'environment_ids': library_lce.id, 'force': 'True'} + ) + else: + sat.api.ContentViewVersion(id=cvv_id).promote(data={'environment_ids': lce_ids}) + _result = { + 'content-view': sat.api.ContentView(id=cv.id).read(), + 'content-view-version': sat.api.ContentViewVersion(id=cvv_id).read(), + } + assert all( + entry for entry in _result.values() + ), f'One or more necessary components are missing: {_result}' + return _result + + +def _publish_and_wait(sat, org, cv): + """Publish a new version of content-view to organization, wait for task(s) completion.""" + task_id = sat.api.ContentView(id=cv.id).publish({'id': cv.id, 'organization': org})['id'] + assert task_id, f'No task was invoked to publish the Content-View: {cv.id}.' + # Should take < 1 minute, check in 5s intervals + sat.wait_for_tasks( + search_query=(f'label = Actions::Katello::ContentView::Publish and id = {task_id}'), + search_rate=5, + max_tries=12, + ), ( + f'Failed to publish the Content-View: {cv.id}, in time.' + f'Task: {task_id} failed, or timed out (60s).' + ) + + +@pytest.fixture +def errata_host_ak(module_target_sat, module_org, module_lce): + "New activation key created in module_org and module_lce" + ak = module_target_sat.api.ActivationKey( + organization=module_org, + environment=module_lce, + ).create() + return ak + + @pytest.fixture def registered_contenthost( + module_target_sat, rhel_contenthost, + errata_host_ak, module_org, module_lce, module_cv, - module_target_sat, request, repos=None, ): """RHEL ContentHost registered in satellite, Using SCA and global registration. - :param repos: list of upstream URLs for custom repositories, - default to CUSTOM_REPO_URL + :note: rhel_contenthost will be parameterized by rhel6 to 9, also -fips for all distros. + to use specific rhel version parameterized contenthost, use pytest.mark.rhel_ver_match() + for marking contenthost version(s) for tests using this fixture. + + :repos: pass as a parameterized request + list of upstream URLs for custom repositories. + default: None; when None set to [CUSTOM_REPO_URL,] """ - if not repos: + # read indirect parameterization request, could be None + try: + repos = getattr(request, 'param', repos).copy() + except AttributeError: + # Default, no parameterized request passed repos = [CUSTOM_REPO_URL] - activation_key = module_target_sat.api.ActivationKey( - organization=module_org, - environment=module_lce, - ).create() + assert isinstance(repos, list), 'Passed request must be a list of upstream url strings.' + assert len(repos) > 0, 'Passed request must be a non-empty list.' + activation_key = errata_host_ak.read() custom_products = [] custom_repos = [] for repo_url in repos: @@ -178,12 +264,8 @@ def registered_contenthost( custom_products.append(custom_repo_info['product-id']) custom_repos.append(custom_repo_info['repository-id']) - # Promote newest version with all content - module_cv = module_cv.read() - module_cv.version.sort(key=lambda version: version.id) - module_cv.version[-1].promote(data={'environment_ids': module_lce.id}) - module_cv = module_cv.read() - + # Publish new version and promote with all content + cv_publish_promote(module_target_sat, module_org, module_cv, module_lce) result = rhel_contenthost.register( activation_keys=activation_key.name, target=module_target_sat, @@ -250,10 +332,9 @@ def cleanup(): @pytest.mark.no_containers def test_end_to_end( session, - request, module_org, module_lce, - module_published_cv, + module_cv, module_target_sat, registered_contenthost, ): @@ -311,7 +392,6 @@ def test_end_to_end( ), f'Expected 1 applicable errata: {CUSTOM_REPO_ERRATA_ID}, after setup. Got {applicable_errata}' with session: - datetime_utc_start = datetime.utcnow() # Check selection box function for BZ#1688636 session.location.select(loc_name=DEFAULT_LOC) @@ -362,7 +442,6 @@ def test_end_to_end( install_end = datetime.strptime(task_status['ended_at'], _UTC_format) assert (install_end - install_start).total_seconds() <= 60 assert (install_end - datetime_utc_start).total_seconds() <= 600 - # Find bulk generate applicability task results = module_target_sat.wait_for_tasks( search_query=( @@ -395,8 +474,18 @@ def test_end_to_end( @pytest.mark.tier2 +@pytest.mark.rhel_ver_match('8') +@pytest.mark.parametrize("registered_contenthost", [[CUSTOM_REPO_3_URL]], indirect=True) @pytest.mark.skipif((not settings.robottelo.REPOS_HOSTING_URL), reason='Missing repos_hosting_url') -def test_content_host_errata_page_pagination(session, function_org_with_parameter, lce, target_sat): +def test_host_content_errata_tab_pagination( + session, + module_target_sat, + registered_contenthost, + module_sca_manifest_org, + errata_host_ak, + module_lce, + module_cv, +): """ # Test per-page pagination for BZ#1662254 # Test apply by REX using Select All for BZ#1846670 @@ -426,57 +515,80 @@ def test_content_host_errata_page_pagination(session, function_org_with_paramete :BZ: 1662254, 1846670 """ - - org = function_org_with_parameter - pkgs = ' '.join(FAKE_3_YUM_OUTDATED_PACKAGES) - repos_collection = target_sat.cli_factory.RepositoryCollection( - distro='rhel7', - repositories=[ - target_sat.cli_factory.SatelliteToolsRepository(), - target_sat.cli_factory.YumRepository(url=settings.repos.yum_3.url), - ], + org = module_sca_manifest_org + all_repos = module_target_sat.api.Repository(organization=org).search() + # custom_repo was created & added to cv, in registered_contenthost fixture + # search for the instance + custom_repo = [repo for repo in all_repos if repo.url == CUSTOM_REPO_3_URL] + assert len(custom_repo) == 1 + custom_repo = custom_repo[0].read() + custom_repo.sync() + # Set up rh_repo + rh_repo_id = module_target_sat.api_factory.enable_rhrepo_and_fetchid( + basearch=DEFAULT_ARCHITECTURE, + org_id=org.id, + product=PRDS['rhel8'], + repo=REPOS['rhst8']['name'], + reposet=REPOSET['rhst8'], + releasever='None', ) - repos_collection.setup_content(org.id, lce.id) - with Broker(nick=repos_collection.distro, host_class=ContentHost) as client: - client.add_rex_key(satellite=target_sat) - # Add repo and install packages that need errata - repos_collection.setup_virtual_machine(client) - assert client.execute(f'yum install -y {pkgs}').status == 0 - with session: - # Go to content host's Errata tab and read the page's pagination widgets - session.organization.select(org_name=org.name) - session.location.select(loc_name=DEFAULT_LOC) - page_values = session.contenthost.read( - client.hostname, widget_names=['errata.pagination'] - ) - assert int(page_values['errata']['pagination']['per_page']) == 20 - # assert total_pages > 1 with default page settings - assert int(page_values['errata']['pagination']['pages']) > 1 - - view = session.contenthost.navigate_to( - session.contenthost, 'Edit', entity_name=client.hostname - ) - per_page_value = view.errata.pagination.per_page - # Change per-page setting to 100 and assert there is now only one page - assert per_page_value.fill('100') - page_values = session.contenthost.read( - client.hostname, widget_names=['errata.pagination'] - ) - assert int(page_values['errata']['pagination']['per_page']) == 100 - assert int(page_values['errata']['pagination']['pages']) == 1 - # assert at least the 28 errata from fake repo are present - assert int(page_values['errata']['pagination']['total_items']) >= 28 - - # install all errata using REX - status = session.contenthost.install_errata(client.hostname, 'All', install_via='rex') - # Assert errata are listed on job invocation page - assert status['overview']['job_status'] == 'Success' - assert status['overview']['job_status_progress'] == '100%' - # check that there are no applicable errata left on the CHost's errata page - page_values = session.contenthost.read( - client.hostname, widget_names=['errata.pagination'] - ) - assert int(page_values['errata']['pagination']['total_items']) == 0 + # Sync step because repo is not synced by default + rh_repo = module_target_sat.api.Repository(id=rh_repo_id).read() + rh_repo.sync() + # add rh_repo to cv, publish version and promote w/ the repository + module_target_sat.cli.ContentView.add_repository( + { + 'id': module_cv.id, + 'organization-id': org.id, + 'repository-id': rh_repo_id, + } + ) + module_cv = module_cv.read() + cv_publish_promote( + module_target_sat, + org, + module_cv, + module_lce, + ) + assert registered_contenthost.subscribed + registered_contenthost.add_rex_key(satellite=module_target_sat) + # Enable repos and install packages that need errata + assert registered_contenthost.execute(r'subscription-manager repos --enable \*').status == 0 + pkgs = ' '.join(FAKE_3_YUM_OUTDATED_PACKAGES) + assert registered_contenthost.execute(f'yum install -y {pkgs}').status == 0 + with session: + # Go to new host's page UI, Content>Errata tab, + # read the page's pagination widgets + session.organization.select(org_name=org.name) + session.location.select(loc_name=DEFAULT_LOC) + page_values = session.host_new.get_errata_pagination(registered_contenthost.hostname) + pagination = page_values['content']['errata']['pagination'] + assert int(pagination['per_page']) == 20 + # assert total_pages > 1 with default page settings + assert int(pagination['pages']) > 1 + + view = session.host_new.navigate_to( + session.contenthost, 'Edit', entity_name=registered_contenthost.hostname + ) + per_page_value = view.errata.pagination.per_page + # Change per-page setting to 100 and assert there is now only one page + assert per_page_value.fill('100') + page_values = session.host_new.get_errata_pagination(registered_contenthost.hostname) + pagination = page_values['content']['errata']['pagination'] + assert int(pagination['per_page']) == 100 + assert int(pagination['pages']) == 1 + # assert at least the 28 errata from fake repo are present + assert int(pagination['total_items']) >= 28 + + # install all errata with REX by default + status = session.host_new.apply_erratas(registered_contenthost.hostname, 'All') + # assert errata are listed on job invocation page + assert status['overview']['job_status'] == 'Success' + assert status['overview']['job_status_progress'] == '100%' + # check that there are no applicable errata left on the CHost's errata page + page_values = session.host_new.get_errata_pagination(registered_contenthost.hostname) + pagination = page_values['content']['errata']['pagination'] + assert int(pagination['total_items']) == 0 @pytest.mark.tier2