From d4914ba84f380f030ded1449055c50daf821ac14 Mon Sep 17 00:00:00 2001 From: Avi Biton Date: Sun, 17 Dec 2023 15:41:47 +0200 Subject: [PATCH] chore(RHTAPWATCH-682): add the ability to extract images from snapshot add the ability to extract images from snapshot add tests Signed-off-by: Avi Biton --- tests/test_rpm_verifier.py | 42 ++++++++++++++++++++++++++++++++++++- verify_rpms/rpm_verifier.py | 13 +++++++++--- 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/tests/test_rpm_verifier.py b/tests/test_rpm_verifier.py index 55bd0d1..0d50ab9 100644 --- a/tests/test_rpm_verifier.py +++ b/tests/test_rpm_verifier.py @@ -1,5 +1,4 @@ """Test rpm_verifier.py end-to-end""" - from pathlib import Path from textwrap import dedent from unittest.mock import MagicMock, call, create_autospec, sentinel @@ -14,6 +13,7 @@ generate_output, get_rpmdb, get_unsigned_rpms, + parse_image_input, ) @@ -130,6 +130,46 @@ def test_get_unsigned_rpms(test_input: list[str], expected: list[str]) -> None: assert result == expected +@pytest.mark.parametrize( + "test_input,expected", + [ + pytest.param( + '{"apiVersion": "appstudio.redhat.com/v1alpha1", "kind": "Snapshot", "metadata": {"generateName": "acs-", "annotations": {"pac.test.appstudio.openshift.io/pull-request": "8689", "pac.test.appstudio.openshift.io/url-repository": "stackrox", "pac.test.appstudio.openshift.io/repository": "roxctl", "pac.test.appstudio.openshift.io/git-provider": "github", "pac.test.appstudio.openshift.io/on-event": "[pull_request]", "pac.test.appstudio.openshift.io/event-type": "pull_request", "pac.test.appstudio.openshift.io/url-org": "stackrox", "pac.test.appstudio.openshift.io/log-url": "https://console.redhat.com/preview/application-pipeline", "pac.test.appstudio.openshift.io/max-keep-runs": "3", "pac.test.appstudio.openshift.io/on-target-branch": "[*]", "pac.test.appstudio.openshift.io/original-prname": "main-on-pull-request", "build.appstudio.openshift.io/repo": "https://github.com/stackrox/stackrox?rev=429e796a9b73dd9f271b5b558d242e53794221e9", "pac.test.appstudio.openshift.io/sha": "429e796a9b73dd9f271b5b558d242e53794221e9", "pac.test.appstudio.openshift.io/repo-url": "https://github.com/stackrox/stackrox", "pac.test.appstudio.openshift.io/sender": "msugakov", "pac.test.appstudio.openshift.io/installation-id": "41511273", "pac.test.appstudio.openshift.io/sha-url": "https://github.com/stackrox/stackrox/commit/429e796a9b73dd9f271b5b558d242e53794221e9", "pac.test.appstudio.openshift.io/state": "completed", "build.appstudio.redhat.com/target_branch": "master", "build.appstudio.redhat.com/pull_request_number": "8689", "pac.test.appstudio.openshift.io/sha-title": "chore(deps): update rhtap references (misha/rhtap-main-onboarding) (#8880)", "pac.test.appstudio.openshift.io/git-auth-secret": "pac-gitauth-qkhh", "pac.test.appstudio.openshift.io/branch": "master", "pac.test.appstudio.openshift.io/check-run-id": "19323605484", "build.appstudio.redhat.com/commit_sha": "429e796a9b73dd9f271b5b558d242e53794221e9"}, "resourceVersion": "1069003978", "name": "acs-4dm5m", "uid": "93330627-bbf2-4ae3-bdbe-c91fa012c145", "creationTimestamp": "2023-12-05T10:44:05Z", "generation": 1, "namespace": "rh-acs-tenant", "ownerReferences": [{"apiVersion": "appstudio.redhat.com/v1alpha1", "blockOwnerDeletion": true, "controller": true, "kind": "Application", "name": "acs", "uid": "ebb689ba-9716-4073-9c27-c2a3c6d4475a"}], "labels": {"appstudio.openshift.io/component": "main", "pac.test.appstudio.openshift.io/pull-request": "8689", "pac.test.appstudio.openshift.io/url-repository": "stackrox", "pac.test.appstudio.openshift.io/repository": "roxctl", "pac.test.appstudio.openshift.io/git-provider": "github", "pac.test.appstudio.openshift.io/event-type": "pull_request", "test.appstudio.openshift.io/pipelinerunfinishtime": "1701773039", "pac.test.appstudio.openshift.io/url-org": "stackrox", "pac.test.appstudio.openshift.io/original-prname": "main-on-pull-request", "appstudio.openshift.io/build-pipelinerun": "main-on-pull-request-s2th2", "pac.test.appstudio.openshift.io/sha": "429e796a9b73dd9f271b5b558d242e53794221e9", "pac.test.appstudio.openshift.io/sender": "msugakov", "appstudio.openshift.io/application": "acs", "pac.test.appstudio.openshift.io/state": "completed", "test.appstudio.openshift.io/type": "component", "pac.test.appstudio.openshift.io/branch": "master", "pac.test.appstudio.openshift.io/check-run-id": "19323605484"}}, "spec": {"application": "acs", "artifacts": {}, "components": [{"containerImage": "quay.io/redhat-user-workloads/rh-acs-tenant/acs/roxctl@sha256:3ec7a3cd38dbafafa766b22bfc3c433aaafdfed29d41ef2e01e372260b304b9d", "name": "roxctl", "source": {"git": {"dockerfileUrl": "Dockerfile", "revision": "3a373fc1658fa3bb7314f9bbdeb7b8f8ca066126", "url": "https://github.com/stackrox/stackrox"}}}, {"containerImage": "quay.io/redhat-user-workloads/rh-acs-tenant/acs/central-db@sha256:bedba7db0634d801be86d7d18286adfc90d251ff39be1efc567cc25d5c362c28", "name": "central-db", "source": {"git": {"dockerfileUrl": "image/postgres/rhtap.Dockerfile", "revision": "3a373fc1658fa3bb7314f9bbdeb7b8f8ca066126", "url": "https://github.com/stackrox/stackrox"}}}, {"containerImage": "quay.io/redhat-user-workloads/rh-acs-tenant/acs/main@sha256:5f715a2ca023dc549abaacb3ec4d7b4ad644c34ca8e7ff697b5cda92b811e731", "name": "main", "source": {"git": {"revision": "429e796a9b73dd9f271b5b558d242e53794221e9", "url": "https://github.com/stackrox/stackrox"}}}, {"containerImage": "quay.io/abiton1/ansible-automation-platform-2-next-eda-controller-rhel8:latest", "name": "central-db", "source": {"git": {"dockerfileUrl": "image/postgres/rhtap.Dockerfile", "revision": "3a373fc1658fa3bb7314f9bbdeb7b8f8ca066126", "url": "https://github.com/stackrox/stackrox"}}}]}, "status": {"conditions": [{"lastTransitionTime": "2023-12-05T10:44:05Z", "message": "Snapshot starts being tested by the integrationPipelineRun", "reason": "InProgress", "status": "Unknown", "type": "AppStudioIntegrationStatus"}, {"lastTransitionTime": "2023-12-05T10:44:05Z", "message": "No required IntegrationTestScenarios found, skipped testing", "reason": "Passed", "status": "True", "type": "AppStudioTestSucceeded"}]}}', # pylint: disable=line-too-long + [ + "quay.io/redhat-user-workloads/rh-acs-tenant/acs/roxctl@" + "sha256:3ec7a3cd38dbafafa766b22bfc3c433aaafdfed29d41ef2e01e372260b304b9d", + "quay.io/redhat-user-workloads/rh-acs-tenant/acs/central-db@" + "sha256:bedba7db0634d801be86d7d18286adfc90d251ff39be1efc567cc25d5c362c28", + "quay.io/redhat-user-workloads/rh-acs-tenant/acs/main@" + "sha256:5f715a2ca023dc549abaacb3ec4d7b4ad644c34ca8e7ff697b5cda92b811e731", + "quay.io/abiton1/ansible-automation-platform-2-next-eda-controller-rhel8:latest", + ], + id="snapshot test", + ), + pytest.param( + "quay.io/redhat-user-workloads/rh-acs-tenant/acs/roxctl@" + "sha256:3ec7a3cd38dbafafa766b22bfc3c433aaafdfed29d41ef2e01e372260b304b9d", + [ + "quay.io/redhat-user-workloads/rh-acs-tenant/acs/roxctl@" + "sha256:3ec7a3cd38dbafafa766b22bfc3c433aaafdfed29d41ef2e01e372260b304b9d" + ], + id="single container", + ), + ], +) +def test_parse_image_input(test_input: str, expected: list[str]) -> None: + """Test parse_image_input""" + result = parse_image_input(image_input=test_input) + assert result == expected + + +def test_parse_image_input_exception() -> None: + """Test parse_image_input throws exception""" + test_input = '{"apiVersion": "appstudio.redhat.com/v1alpha1"}' + with pytest.raises(KeyError): + parse_image_input(image_input=test_input) + + class TestImageProcessor: """Test ImageProcessor's callable""" diff --git a/verify_rpms/rpm_verifier.py b/verify_rpms/rpm_verifier.py index 42249b0..eb0d08d 100644 --- a/verify_rpms/rpm_verifier.py +++ b/verify_rpms/rpm_verifier.py @@ -6,6 +6,7 @@ import tempfile from concurrent.futures import ThreadPoolExecutor from dataclasses import dataclass +from json import JSONDecodeError, loads from pathlib import Path from subprocess import run from typing import Callable, Iterable @@ -97,9 +98,15 @@ def parse_image_input(image_input: str) -> list[str]: Try parsing as json and extract the images. If failing to parse as json, assume it's an image reference as one-element list. """ - # Currently assuming a single image. To be replaced by deciding whether this is an - # image or a snapshot json, and parsing accordingly - return [image_input] + try: + snapshot = loads(s=image_input) + except JSONDecodeError: + return [image_input] + components = snapshot["spec"]["components"] + container_images: list[str] = [] + for component in components: + container_images.append(component["containerImage"]) + return container_images @dataclass(frozen=True)