From bfbd92f186aee0634f2c4c324ca5ee78d79c2a25 Mon Sep 17 00:00:00 2001 From: Vladimir Sedmik Date: Fri, 31 May 2024 17:57:31 +0200 Subject: [PATCH 1/3] Add upgrade scenario test for docker manifest indexing --- tests/upgrades/test_repository.py | 105 ++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/tests/upgrades/test_repository.py b/tests/upgrades/test_repository.py index ae8f672ab3f..f5067469612 100644 --- a/tests/upgrades/test_repository.py +++ b/tests/upgrades/test_repository.py @@ -375,6 +375,111 @@ def test_post_scenario_sync_large_repo(self, target_sat, pre_upgrade_data): assert res['result'] == 'success' +class TestScenarioContainerRepoSync: + """Scenario to verify that container repositories with labels, annotations and othe flages + synced before upgrade are indexed properly after upgrade including labels (as of 6.16). + + Test Steps: + + 1. Before Satellite upgrade. + 2. Synchronize container repositories that contains some labels and other flags. + 3. Upgrade Satellite. + 4. Check the labels and other flags were indexed properly in Katello DB via API. + """ + + @pytest.mark.pre_upgrade + def test_pre_container_repo_sync( + self, + target_sat, + module_org, + module_product, + save_test_data, + ): + """This is a pre-upgrade test to sync container repositories + with some labels, annotations and bootable and flatpak flags. + + :id: 55b82217-7fd0-4b98-bd38-2a08a36f77db + + :steps: + 1. Create bootable container repository with some labels and flags. + 2. Sync the repository and assert sync succeeds. + 3. Create flatpak container repository with some labels and flags. + 4. Sync the repository and assert sync succeeds. + + :expectedresults: Container repositories are synced and ready for upgrade. + """ + # Create and sync bootable container repository with some labels and flags. + bootable_repo = target_sat.api.Repository( + content_type='docker', + docker_upstream_name='pulp/bootc-labeled', + product=module_product, + url='https://ghcr.io', + ).create() + bootable_repo.sync() + bootable_repo = bootable_repo.read() + assert bootable_repo.content_counts['docker_manifest'] > 0 + + # Create and sync flatpak container repository with some labels and flags. + flatpak_repo = target_sat.api.Repository( + content_type='docker', + docker_upstream_name='pulp/oci-net.fishsoup.hello', + product=module_product, + url='https://ghcr.io', + ).create() + flatpak_repo.sync() + flatpak_repo = flatpak_repo.read() + assert flatpak_repo.content_counts['docker_manifest'] > 0 + + save_test_data({'boot_repo_id': bootable_repo.id, 'flatpak_repo_id': flatpak_repo.id}) + + @pytest.mark.post_upgrade(depend_on=test_pre_container_repo_sync) + def test_post_container_repo_sync(self, target_sat, pre_upgrade_data): + """This is a post-upgrade test to verify the container labels + were indexed properly in the post-upgrade task. + + :id: 1e8f2f4a-6232-4671-9d6f-2ada1b70bc59 + + :steps: + 1. Verify the manifests count matches the repository content counts + and ensure all manifests in each repo contain the expected keys. + 2. Verify the vaules meet the expectations specific for each repo. + + :expectedresults: Container labels were indexed properly. + """ + # Verify the manifests count matches the repository content counts + # and ensure all manifests in each repo contain the expected keys. + expected_keys = {'annotations', 'labels', 'is_bootable', 'is_flatpak'} + for repo_id in pre_upgrade_data.values(): + dms = target_sat.api.Repository(id=repo_id).docker_manifests()['results'] + assert ( + len(dms) + == target_sat.api.Repository(id=repo_id).read().content_counts['docker_manifest'] + ), 'Manifests count does not match the repository content counts' + assert all( + [expected_keys.issubset(m.keys()) for m in dms] + ), 'Some expected key is missing in the repository manifests' + + # Verify the vaules meet the expectations specific for the bootable repo. + dms = target_sat.api.Repository(id=pre_upgrade_data.boot_repo_id).docker_manifests()[ + 'results' + ] + assert len(dms) == 1, 'Expected 1 manifest in the repo' + assert dms[0]['is_bootable'], 'Expected is_bootable flag set to True' + assert not dms[0]['is_flatpak'], 'Expected is_flatpak flag set to False' + assert len(dms[0]['labels']) == 2, 'Expected 2 labels for this manifest' + assert len(dms[0]['annotations']) == 2, 'Expected 2 annotations for this manifest' + + # Verify the vaules meet the expectations specific for the flatpak repo. + dms = target_sat.api.Repository(id=pre_upgrade_data.flatpak_repo_id).docker_manifests()[ + 'results' + ] + assert len(dms) == 2, 'Expected 2 manifests in the repo' + assert all([not m['is_bootable'] for m in dms]), 'Expected is_bootable flags set to False' + assert all([m['is_flatpak'] for m in dms]), 'Expected is_flatpak flags set to True' + assert all([len(m['labels']) == 10 for m in dms]), 'Expected 10 labels in the manifests' + assert all([len(m['annotations']) == 0 for m in dms]), 'No annotations expected' + + class TestSimpleContentAccessOnly: """ The scenario to test simple content access mode before and after an upgrade to a From 2ae351d388f0936a2fca9cedebc9c910c4e521a8 Mon Sep 17 00:00:00 2001 From: Vladimir Sedmik Date: Mon, 3 Jun 2024 20:12:07 +0200 Subject: [PATCH 2/3] Add repo sync test for docker manifest indexing --- robottelo/constants/__init__.py | 19 ++++++ tests/foreman/api/test_repository.py | 71 +++++++++++++++++++- tests/upgrades/test_repository.py | 97 ++++++++++++---------------- 3 files changed, 132 insertions(+), 55 deletions(-) diff --git a/robottelo/constants/__init__.py b/robottelo/constants/__init__.py index 464ba7e41e4..2d1a78292f1 100644 --- a/robottelo/constants/__init__.py +++ b/robottelo/constants/__init__.py @@ -706,9 +706,28 @@ REPORT_TEMPLATE_FILE = 'report_template.txt' CONTAINER_REGISTRY_HUB = 'https://mirror.gcr.io' RH_CONTAINER_REGISTRY_HUB = 'https://registry.redhat.io/' +PULP_CONTAINER_REGISTRY_HUB = 'https://ghcr.io' CONTAINER_UPSTREAM_NAME = 'library/busybox' DOCKER_REPO_UPSTREAM_NAME = 'openshift3/logging-elasticsearch' CONTAINER_RH_REGISTRY_UPSTREAM_NAME = 'openshift3/ose-metrics-hawkular-openshift-agent' +BOOTABLE_REPO = { + 'upstream_name': 'pulp/bootc-labeled', + 'manifests_count': 1, + 'bootable': True, + 'flatpak': False, + 'labels_count': 2, + 'annotations_count': 2, +} +FLATPAK_REPO = { + 'upstream_name': 'pulp/oci-net.fishsoup.hello', + 'manifests_count': 2, + 'bootable': False, + 'flatpak': True, + 'labels_count': 10, + 'annotations_count': 0, +} +LABELLED_REPOS = [BOOTABLE_REPO, FLATPAK_REPO] +CONTAINER_MANIFEST_LABELS = {'annotations', 'labels', 'is_bootable', 'is_flatpak'} CONTAINER_CLIENTS = ['docker', 'podman'] CUSTOM_LOCAL_FOLDER = '/var/lib/pulp/imports/myrepo/' CUSTOM_LOCAL_FILE = '/var/lib/pulp/imports/myrepo/test.txt' diff --git a/tests/foreman/api/test_repository.py b/tests/foreman/api/test_repository.py index 5c946a5bc53..a4454aff104 100644 --- a/tests/foreman/api/test_repository.py +++ b/tests/foreman/api/test_repository.py @@ -26,7 +26,12 @@ from robottelo import constants from robottelo.config import settings -from robottelo.constants import DataFile, repos as repo_constants +from robottelo.constants import ( + CONTAINER_MANIFEST_LABELS, + LABELLED_REPOS, + DataFile, + repos as repo_constants, +) from robottelo.content_info import get_repo_files_by_url from robottelo.logging import logger from robottelo.utils import datafactory @@ -1837,6 +1842,70 @@ def test_positive_synchronize_docker_repo_with_included_tags(self, repo_options, assert repo.include_tags == repo_options['include_tags'] assert repo.content_counts['docker_tag'] == 1 + @pytest.mark.tier2 + @pytest.mark.upgrade + @pytest.mark.parametrize( + 'repo_options', + **datafactory.parametrized( + [ + { + 'content_type': 'docker', + 'docker_upstream_name': repo['upstream_name'], + 'name': gen_string('alpha'), + 'url': constants.PULP_CONTAINER_REGISTRY_HUB, + } + for repo in LABELLED_REPOS + ] + ), + indirect=True, + ) + def test_positive_synchronize_docker_repo_with_manifest_labels( + self, target_sat, repo_options, repo + ): + """Verify the container manifest labels were indexed properly during the repo sync. + + :id: c865d350-fd19-43fb-b9fd-5ef86cbe3e09 + + :parametrized: yes + + :steps: + 1. Sync container-type repositories with some labels, annotations + and bootable and flatpak flags. + 2. Verify all manifests in each repo contain the expected keys. + 3. Verify the manifests count matches the repository content counts and the expectation. + 4. Verify the values meet the expectations specific for each repo. + + :expectedresults: Container labels were indexed properly. + """ + repo.sync() + repo = repo.read() + dms = target_sat.api.Repository(id=repo.id).docker_manifests()['results'] + assert all( + [CONTAINER_MANIFEST_LABELS.issubset(m.keys()) for m in dms] + ), 'Some expected key is missing in the repository manifests' + expected_values = next( + (i for i in LABELLED_REPOS if i['upstream_name'] == repo.docker_upstream_name), None + ) + assert expected_values, f'{repo.docker_upstream_name} not found in {LABELLED_REPOS}' + assert ( + len(dms) == repo.content_counts['docker_manifest'] + ), 'Manifests count does not match the repository content counts' + assert ( + len(dms) == expected_values['manifests_count'] + ), 'Manifests count does not meet the expectation' + assert all( + [m['is_bootable'] == expected_values['bootable'] for m in dms] + ), 'Unexpected is_bootable flag' + assert all( + [m['is_flatpak'] == expected_values['flatpak'] for m in dms] + ), 'Unexpected is_flatpak flag' + assert all( + [len(m['labels']) == expected_values['labels_count'] for m in dms] + ), 'Unexpected lables count' + assert all( + [len(m['annotations']) == expected_values['annotations_count'] for m in dms] + ), 'Unexpected annotations count' + @pytest.mark.skip( reason="Tests behavior that is no longer present in the same way, needs refactor" ) diff --git a/tests/upgrades/test_repository.py b/tests/upgrades/test_repository.py index f5067469612..7568df1a3f2 100644 --- a/tests/upgrades/test_repository.py +++ b/tests/upgrades/test_repository.py @@ -17,9 +17,12 @@ from robottelo import constants from robottelo.config import settings from robottelo.constants import ( + CONTAINER_MANIFEST_LABELS, DEFAULT_ARCHITECTURE, FAKE_0_CUSTOM_PACKAGE_NAME, FAKE_4_CUSTOM_PACKAGE_NAME, + LABELLED_REPOS, + PULP_CONTAINER_REGISTRY_HUB, REPOS, ) from robottelo.hosts import ContentHost @@ -376,7 +379,7 @@ def test_post_scenario_sync_large_repo(self, target_sat, pre_upgrade_data): class TestScenarioContainerRepoSync: - """Scenario to verify that container repositories with labels, annotations and othe flages + """Scenario to verify that container repositories with labels, annotations and other flags synced before upgrade are indexed properly after upgrade including labels (as of 6.16). Test Steps: @@ -408,29 +411,19 @@ def test_pre_container_repo_sync( :expectedresults: Container repositories are synced and ready for upgrade. """ - # Create and sync bootable container repository with some labels and flags. - bootable_repo = target_sat.api.Repository( - content_type='docker', - docker_upstream_name='pulp/bootc-labeled', - product=module_product, - url='https://ghcr.io', - ).create() - bootable_repo.sync() - bootable_repo = bootable_repo.read() - assert bootable_repo.content_counts['docker_manifest'] > 0 - - # Create and sync flatpak container repository with some labels and flags. - flatpak_repo = target_sat.api.Repository( - content_type='docker', - docker_upstream_name='pulp/oci-net.fishsoup.hello', - product=module_product, - url='https://ghcr.io', - ).create() - flatpak_repo.sync() - flatpak_repo = flatpak_repo.read() - assert flatpak_repo.content_counts['docker_manifest'] > 0 - - save_test_data({'boot_repo_id': bootable_repo.id, 'flatpak_repo_id': flatpak_repo.id}) + repos = dict() + for model in LABELLED_REPOS: + repo = target_sat.api.Repository( + content_type='docker', + docker_upstream_name=model['upstream_name'], + product=module_product, + url=PULP_CONTAINER_REGISTRY_HUB, + ).create() + repo.sync() + repo = repo.read() + assert repo.content_counts['docker_manifest'] > 0 + repos[model['upstream_name']] = repo.id + save_test_data(repos) @pytest.mark.post_upgrade(depend_on=test_pre_container_repo_sync) def test_post_container_repo_sync(self, target_sat, pre_upgrade_data): @@ -440,44 +433,40 @@ def test_post_container_repo_sync(self, target_sat, pre_upgrade_data): :id: 1e8f2f4a-6232-4671-9d6f-2ada1b70bc59 :steps: - 1. Verify the manifests count matches the repository content counts - and ensure all manifests in each repo contain the expected keys. - 2. Verify the vaules meet the expectations specific for each repo. + 1. Verify all manifests in each repo contain the expected keys. + 2. Verify the manifests count matches the repository content counts and the expectation. + 3. Verify the values meet the expectations specific for each repo. :expectedresults: Container labels were indexed properly. """ - # Verify the manifests count matches the repository content counts - # and ensure all manifests in each repo contain the expected keys. - expected_keys = {'annotations', 'labels', 'is_bootable', 'is_flatpak'} for repo_id in pre_upgrade_data.values(): + repo = target_sat.api.Repository(id=repo_id).read() dms = target_sat.api.Repository(id=repo_id).docker_manifests()['results'] + assert all( + [CONTAINER_MANIFEST_LABELS.issubset(m.keys()) for m in dms] + ), 'Some expected key is missing in the repository manifests' + expected_values = next( + (i for i in LABELLED_REPOS if i['upstream_name'] == repo.docker_upstream_name), None + ) + assert expected_values, f'{repo.docker_upstream_name} not found in {LABELLED_REPOS}' assert ( - len(dms) - == target_sat.api.Repository(id=repo_id).read().content_counts['docker_manifest'] + len(dms) == repo.content_counts['docker_manifest'] ), 'Manifests count does not match the repository content counts' + assert ( + len(dms) == expected_values['manifests_count'] + ), 'Manifests count does not meet the expectation' assert all( - [expected_keys.issubset(m.keys()) for m in dms] - ), 'Some expected key is missing in the repository manifests' - - # Verify the vaules meet the expectations specific for the bootable repo. - dms = target_sat.api.Repository(id=pre_upgrade_data.boot_repo_id).docker_manifests()[ - 'results' - ] - assert len(dms) == 1, 'Expected 1 manifest in the repo' - assert dms[0]['is_bootable'], 'Expected is_bootable flag set to True' - assert not dms[0]['is_flatpak'], 'Expected is_flatpak flag set to False' - assert len(dms[0]['labels']) == 2, 'Expected 2 labels for this manifest' - assert len(dms[0]['annotations']) == 2, 'Expected 2 annotations for this manifest' - - # Verify the vaules meet the expectations specific for the flatpak repo. - dms = target_sat.api.Repository(id=pre_upgrade_data.flatpak_repo_id).docker_manifests()[ - 'results' - ] - assert len(dms) == 2, 'Expected 2 manifests in the repo' - assert all([not m['is_bootable'] for m in dms]), 'Expected is_bootable flags set to False' - assert all([m['is_flatpak'] for m in dms]), 'Expected is_flatpak flags set to True' - assert all([len(m['labels']) == 10 for m in dms]), 'Expected 10 labels in the manifests' - assert all([len(m['annotations']) == 0 for m in dms]), 'No annotations expected' + [m['is_bootable'] == expected_values['bootable'] for m in dms] + ), 'Unexpected is_bootable flag' + assert all( + [m['is_flatpak'] == expected_values['flatpak'] for m in dms] + ), 'Unexpected is_flatpak flag' + assert all( + [len(m['labels']) == expected_values['labels_count'] for m in dms] + ), 'Unexpected lables count' + assert all( + [len(m['annotations']) == expected_values['annotations_count'] for m in dms] + ), 'Unexpected annotations count' class TestSimpleContentAccessOnly: From 0b16fc0f564a55f925fa220929ca1b9aa2c54e66 Mon Sep 17 00:00:00 2001 From: Vladimir Sedmik Date: Tue, 11 Jun 2024 15:15:36 +0200 Subject: [PATCH 3/3] Update loop vars to be less confusing --- tests/foreman/api/test_repository.py | 4 ++-- tests/upgrades/test_repository.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/foreman/api/test_repository.py b/tests/foreman/api/test_repository.py index a4454aff104..4dde7744e40 100644 --- a/tests/foreman/api/test_repository.py +++ b/tests/foreman/api/test_repository.py @@ -1850,11 +1850,11 @@ def test_positive_synchronize_docker_repo_with_included_tags(self, repo_options, [ { 'content_type': 'docker', - 'docker_upstream_name': repo['upstream_name'], + 'docker_upstream_name': item['upstream_name'], 'name': gen_string('alpha'), 'url': constants.PULP_CONTAINER_REGISTRY_HUB, } - for repo in LABELLED_REPOS + for item in LABELLED_REPOS ] ), indirect=True, diff --git a/tests/upgrades/test_repository.py b/tests/upgrades/test_repository.py index 7568df1a3f2..ddb1d85345a 100644 --- a/tests/upgrades/test_repository.py +++ b/tests/upgrades/test_repository.py @@ -412,17 +412,17 @@ def test_pre_container_repo_sync( :expectedresults: Container repositories are synced and ready for upgrade. """ repos = dict() - for model in LABELLED_REPOS: + for item in LABELLED_REPOS: repo = target_sat.api.Repository( content_type='docker', - docker_upstream_name=model['upstream_name'], + docker_upstream_name=item['upstream_name'], product=module_product, url=PULP_CONTAINER_REGISTRY_HUB, ).create() repo.sync() repo = repo.read() assert repo.content_counts['docker_manifest'] > 0 - repos[model['upstream_name']] = repo.id + repos[item['upstream_name']] = repo.id save_test_data(repos) @pytest.mark.post_upgrade(depend_on=test_pre_container_repo_sync)