From 5d3989400f71ab4ef7f5be8467aec2dd449ab4a6 Mon Sep 17 00:00:00 2001 From: David Caravello <119438707+dcaravel@users.noreply.github.com> Date: Fri, 6 Mar 2026 19:01:44 -0600 Subject: [PATCH 1/3] add scanner v4 enabled flag --- qa-tests-backend/src/test/groovy/BaseSpecification.groovy | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/qa-tests-backend/src/test/groovy/BaseSpecification.groovy b/qa-tests-backend/src/test/groovy/BaseSpecification.groovy index 096d455ae6b90..a3953115b56a6 100644 --- a/qa-tests-backend/src/test/groovy/BaseSpecification.groovy +++ b/qa-tests-backend/src/test/groovy/BaseSpecification.groovy @@ -26,6 +26,7 @@ import objects.K8sServiceAccount import objects.Secret import services.BaseService import services.ClusterService +import services.FeatureFlagService import services.ImageIntegrationService import services.MetadataService import services.RoleService @@ -73,6 +74,8 @@ class BaseSpecification extends Specification { public static String coreImageIntegrationId = null + public static boolean scannerV4Enabled = false + private static synchronizedGlobalSetup() { synchronized(BaseSpecification) { globalSetup() @@ -128,6 +131,9 @@ class BaseSpecification extends Specification { } } + scannerV4Enabled = FeatureFlagService.isFeatureFlagEnabled("ROX_SCANNER_V4") + LOG.info "Scanner V4 enabled: ${scannerV4Enabled}" + if (ClusterService.isOpenShift4()) { assert Env.mustGetOrchestratorType() == OrchestratorTypes.OPENSHIFT, "Set CLUSTER=OPENSHIFT when testing OpenShift" From 8e59e44cece22181c0d775e83280afbf3a432c58 Mon Sep 17 00:00:00 2001 From: David Caravello <119438707+dcaravel@users.noreply.github.com> Date: Mon, 23 Mar 2026 19:47:02 -0500 Subject: [PATCH 2/3] add null guard to enable retries waiting for image vulns Add null guard to found checks so that it actually retries when image not found yet vs. failing with NullPointerException. This was causing CI flakes during testing. --- qa-tests-backend/src/test/groovy/Services.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qa-tests-backend/src/test/groovy/Services.groovy b/qa-tests-backend/src/test/groovy/Services.groovy index 5301a1db12377..8a6728b737d3e 100644 --- a/qa-tests-backend/src/test/groovy/Services.groovy +++ b/qa-tests-backend/src/test/groovy/Services.groovy @@ -540,7 +540,7 @@ class Services extends BaseService { Timer t = new Timer(retries, interval) while (t.IsValid()) { def found = ImageService.getImages().find { it.name.endsWith(imageName) } - if (found.hasCves() || found.hasFixableCves()) { + if (found?.hasCves() || found?.hasFixableCves()) { LOG.info "SR found vulnerabilities for the image ${imageName} within ${t.SecondsSince()}s" return true } From 07257dc4a587b76522c2c0cdee35849decfa59cf Mon Sep 17 00:00:00 2001 From: David Caravello <119438707+dcaravel@users.noreply.github.com> Date: Thu, 26 Mar 2026 13:51:57 -0500 Subject: [PATCH 3/3] add ScannerV4Integration type, deletable trait, and update testability flag - Creates a ScannerV4Integration type for tests to use (will be part of future commits) - The Scanner V4 integration cannot be deleted in Central by design, the new isDeletable() method allows tests to act accordingly. - Makes isTestable() for StackRoxScannerIntegration conditional on Scanner V4 being enabled. When Scanner V4 is enabled StackRox Scanner is not reachable for image scans (exception: delegated scanning, but that is not tested in groovy tests) --- .../groovy/objects/ImageIntegration.groovy | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/qa-tests-backend/src/main/groovy/objects/ImageIntegration.groovy b/qa-tests-backend/src/main/groovy/objects/ImageIntegration.groovy index ff55932b96314..45373a5e22ce6 100644 --- a/qa-tests-backend/src/main/groovy/objects/ImageIntegration.groovy +++ b/qa-tests-backend/src/main/groovy/objects/ImageIntegration.groovy @@ -2,11 +2,15 @@ package objects import common.Constants import io.stackrox.proto.storage.ImageIntegrationOuterClass +import services.FeatureFlagService import services.ImageIntegrationService import util.Env trait ImageIntegration { abstract static ImageIntegrationOuterClass.ImageIntegration.Builder getCustomBuilder(Map customArgs) + + // Returns true for integrations that can be deleted, false otherwise. + static boolean isDeletable() { true } } class StackroxScannerIntegration implements ImageIntegration { @@ -14,7 +18,7 @@ class StackroxScannerIntegration implements ImageIntegration { static String name() { Constants.AUTO_REGISTERED_STACKROX_SCANNER_INTEGRATION } static Boolean isTestable() { - return true + return !FeatureFlagService.isFeatureFlagEnabled("ROX_SCANNER_V4") } static String createDefaultIntegration() { @@ -428,6 +432,28 @@ class GoogleArtifactRegistry implements ImageIntegration { } } +class ScannerV4Integration implements ImageIntegration { + + static String name() { "Scanner V4" } + + static Boolean isTestable() { + return FeatureFlagService.isFeatureFlagEnabled("ROX_SCANNER_V4") + } + + static boolean isDeletable() { false } + + // The Scanner V4 integration is auto-registered and cannot be deleted. + // createDefaultIntegration() looks up the existing integration rather than creating one. + static String createDefaultIntegration() { + ImageIntegrationOuterClass.ImageIntegration existing = + ImageIntegrationService.getImageIntegrationByName(name()) + if (!existing) { + return "" + } + return existing.id + } +} + class GCRImageIntegration implements ImageIntegration { static String name() { "GCR Registry+Scanner" }