From 97ccba1185d3ca9edd2b31622d94090c9cad07e1 Mon Sep 17 00:00:00 2001 From: Yu Qi Zhang Date: Wed, 1 Apr 2026 10:22:40 -0400 Subject: [PATCH 1/2] Include candidate tier in default sippy queries for feature promotion Some job/platforms (MCO vsphere, metal) only run TechPreview tests in candidate-tier jobs. The default tier list used by QueriesFor() only included standard/informing/blocking, causing the feature promotion analyzer to report 0 tests found for these platforms. This was the behaviour before https://github.com/openshift/api/pull/2763 and the partial fix in https://github.com/openshift/api/pull/2781, so the defaults should be fine to include candidate always. Asked claude to add tests to verify the default queries include candidate tier and that all required variant definitions will query for it. Co-Authored-By: Claude Opus 4.6 --- .../codegen/cmd/featuregate-test-analyzer.go | 4 +- .../cmd/featuregate-test-analyzer_test.go | 41 +++++++++++++++++++ tools/codegen/pkg/sippy/json_types.go | 6 +-- 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/tools/codegen/cmd/featuregate-test-analyzer.go b/tools/codegen/cmd/featuregate-test-analyzer.go index 57967a371c1..bdc12f9f105 100644 --- a/tools/codegen/cmd/featuregate-test-analyzer.go +++ b/tools/codegen/cmd/featuregate-test-analyzer.go @@ -618,7 +618,7 @@ type JobVariant struct { Topology string NetworkStack string OS string - JobTiers string // Comma-separated tiers (e.g., "standard,informing,blocking"). If empty, defaults to "standard,informing,blocking" + JobTiers string // Comma-separated tiers (e.g., "standard,informing,blocking"). If empty, defaults to "standard,informing,blocking,candidate" Optional bool // If true, validation failures for this variant are non-blocking warnings } @@ -680,7 +680,7 @@ func testResultByName(results []TestResults, testName string) *TestResults { func validateJobTiers(jobVariant JobVariant) error { if jobVariant.JobTiers == "" { - return nil // Empty is valid - will default to standard,informing,blocking + return nil // Empty is valid - will default to standard,informing,blocking,candidate } validTiers := map[string]bool{ diff --git a/tools/codegen/cmd/featuregate-test-analyzer_test.go b/tools/codegen/cmd/featuregate-test-analyzer_test.go index df66edcac67..5689aacb722 100644 --- a/tools/codegen/cmd/featuregate-test-analyzer_test.go +++ b/tools/codegen/cmd/featuregate-test-analyzer_test.go @@ -6,6 +6,8 @@ import ( "testing" "k8s.io/apimachinery/pkg/util/sets" + + "github.com/openshift/api/tools/codegen/pkg/sippy" ) func Test_listTestResultFor(t *testing.T) { @@ -475,3 +477,42 @@ func Test_checkIfTestingIsSufficient_OptionalVariants(t *testing.T) { }) } } + +func Test_defaultQueriesIncludeCandidateTier(t *testing.T) { + // When JobTiers is empty, QueriesFor should generate queries for all tiers + // including candidate. This test is added to prevent regressions for candidate-tier + // jobs being excluded, like we had for MCO TP jobs. + queries := sippy.QueriesFor("vsphere", "amd64", "ha", "", "", "", "FeatureGate:TestGate]") + + tierNames := sets.New[string]() + for _, q := range queries { + tierNames.Insert(q.TierName) + } + + expectedTiers := []string{"standard", "informing", "blocking", "candidate"} + for _, tier := range expectedTiers { + if !tierNames.Has(tier) { + t.Errorf("default queries missing tier %q - got tiers: %v", tier, sets.List(tierNames)) + } + } +} + +func Test_allRequiredVariantsQueryCandidateTier(t *testing.T) { + // Verify that all required variant definitions will query for the candidate + // tier, either explicitly via JobTiers or via the default. + allVariants := append(append([]JobVariant{}, requiredSelfManagedJobVariants...), requiredHypershiftJobVariants...) + + for _, variant := range allVariants { + queries := sippy.QueriesFor(variant.Cloud, variant.Architecture, variant.Topology, variant.NetworkStack, variant.OS, variant.JobTiers, "FeatureGate:Test]") + hasCandidateQuery := false + for _, q := range queries { + if q.TierName == "candidate" { + hasCandidateQuery = true + break + } + } + if !hasCandidateQuery { + t.Errorf("variant %+v does not query candidate tier - some platforms only run TechPreview tests in candidate-tier jobs", variant) + } + } +} diff --git a/tools/codegen/pkg/sippy/json_types.go b/tools/codegen/pkg/sippy/json_types.go index 2785d496f4a..0795c2519a4 100644 --- a/tools/codegen/pkg/sippy/json_types.go +++ b/tools/codegen/pkg/sippy/json_types.go @@ -101,10 +101,10 @@ func QueriesFor(cloud, architecture, topology, networkStack, os, jobTiers, testP }) } - // Parse JobTiers - comma-separated string, default to standard/informing/blocking if empty + // Parse JobTiers - comma-separated string, default to standard/informing/blocking/candidate if empty var jobTiersList []string if jobTiers == "" { - jobTiersList = []string{"standard", "informing", "blocking"} + jobTiersList = []string{"standard", "informing", "blocking", "candidate"} } else { // Split by comma, trim whitespace, and deduplicate using sets tierSet := sets.New[string]() @@ -115,7 +115,7 @@ func QueriesFor(cloud, architecture, topology, networkStack, os, jobTiers, testP } // If all tiers were whitespace/empty after trimming, use defaults if tierSet.Len() == 0 { - jobTiersList = []string{"standard", "informing", "blocking"} + jobTiersList = []string{"standard", "informing", "blocking", "candidate"} } else { jobTiersList = sets.List(tierSet) } From d0eee8e328f165b74dbfe2e2a20f508f3b9d195c Mon Sep 17 00:00:00 2001 From: Isabella Janssen Date: Wed, 25 Mar 2026 08:50:34 -0400 Subject: [PATCH 2/2] MCO-1736: promote ImageModeStatusReporting feature gate to default --- features.md | 2 +- features/features.go | 2 +- .../featuregates/featureGate-4-10-Hypershift-Default.yaml | 6 +++--- .../featuregates/featureGate-4-10-Hypershift-OKD.yaml | 6 +++--- .../featureGate-4-10-SelfManagedHA-Default.yaml | 6 +++--- .../featuregates/featureGate-4-10-SelfManagedHA-OKD.yaml | 6 +++--- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/features.md b/features.md index 0746864de9d..b7d995f2b3a 100644 --- a/features.md +++ b/features.md @@ -67,7 +67,6 @@ | GCPDualStackInstall| | | Enabled | Enabled | | | Enabled | Enabled | | GatewayAPIWithoutOLM| | | Enabled | Enabled | | | Enabled | Enabled | | HyperShiftOnlyDynamicResourceAllocation| Enabled | | Enabled | | Enabled | | Enabled | | -| ImageModeStatusReporting| | | Enabled | Enabled | | | Enabled | Enabled | | IngressControllerDynamicConfigurationManager| | | Enabled | Enabled | | | Enabled | Enabled | | IrreconcilableMachineConfig| | | Enabled | Enabled | | | Enabled | Enabled | | KMSEncryption| | | Enabled | Enabled | | | Enabled | Enabled | @@ -101,6 +100,7 @@ | ExternalOIDC| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | ExternalOIDCWithUIDAndExtraClaimMappings| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | GCPClusterHostedDNSInstall| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | +| ImageModeStatusReporting| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | ImageStreamImportMode| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | InsightsConfig| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | InsightsOnDemandDataGather| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | diff --git a/features/features.go b/features/features.go index 9b56faf67df..e9052c9ff3e 100644 --- a/features/features.go +++ b/features/features.go @@ -262,7 +262,7 @@ var ( contactPerson("ijanssen"). productScope(ocpSpecific). enhancementPR("https://github.com/openshift/enhancements/pull/1809"). - enable(inTechPreviewNoUpgrade(), inDevPreviewNoUpgrade()). + enable(inDefault(), inOKD(), inTechPreviewNoUpgrade(), inDevPreviewNoUpgrade()). mustRegister() FeatureGateClusterAPIInstall = newFeatureGate("ClusterAPIInstall"). diff --git a/payload-manifests/featuregates/featureGate-4-10-Hypershift-Default.yaml b/payload-manifests/featuregates/featureGate-4-10-Hypershift-Default.yaml index 1e7bbbf9722..c59e7dc4c6f 100644 --- a/payload-manifests/featuregates/featureGate-4-10-Hypershift-Default.yaml +++ b/payload-manifests/featuregates/featureGate-4-10-Hypershift-Default.yaml @@ -173,9 +173,6 @@ { "name": "GatewayAPIWithoutOLM" }, - { - "name": "ImageModeStatusReporting" - }, { "name": "IngressControllerDynamicConfigurationManager" }, @@ -319,6 +316,9 @@ { "name": "HyperShiftOnlyDynamicResourceAllocation" }, + { + "name": "ImageModeStatusReporting" + }, { "name": "ImageStreamImportMode" }, diff --git a/payload-manifests/featuregates/featureGate-4-10-Hypershift-OKD.yaml b/payload-manifests/featuregates/featureGate-4-10-Hypershift-OKD.yaml index 80234030144..7d2baa02548 100644 --- a/payload-manifests/featuregates/featureGate-4-10-Hypershift-OKD.yaml +++ b/payload-manifests/featuregates/featureGate-4-10-Hypershift-OKD.yaml @@ -175,9 +175,6 @@ { "name": "GatewayAPIWithoutOLM" }, - { - "name": "ImageModeStatusReporting" - }, { "name": "IngressControllerDynamicConfigurationManager" }, @@ -321,6 +318,9 @@ { "name": "HyperShiftOnlyDynamicResourceAllocation" }, + { + "name": "ImageModeStatusReporting" + }, { "name": "ImageStreamImportMode" }, diff --git a/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-Default.yaml b/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-Default.yaml index db208cded2d..393975d162c 100644 --- a/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-Default.yaml +++ b/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-Default.yaml @@ -173,9 +173,6 @@ { "name": "HyperShiftOnlyDynamicResourceAllocation" }, - { - "name": "ImageModeStatusReporting" - }, { "name": "IngressControllerDynamicConfigurationManager" }, @@ -313,6 +310,9 @@ { "name": "GCPClusterHostedDNSInstall" }, + { + "name": "ImageModeStatusReporting" + }, { "name": "ImageStreamImportMode" }, diff --git a/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-OKD.yaml b/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-OKD.yaml index 3c46a9898b3..0481d1dbf09 100644 --- a/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-OKD.yaml +++ b/payload-manifests/featuregates/featureGate-4-10-SelfManagedHA-OKD.yaml @@ -175,9 +175,6 @@ { "name": "HyperShiftOnlyDynamicResourceAllocation" }, - { - "name": "ImageModeStatusReporting" - }, { "name": "IngressControllerDynamicConfigurationManager" }, @@ -315,6 +312,9 @@ { "name": "GCPClusterHostedDNSInstall" }, + { + "name": "ImageModeStatusReporting" + }, { "name": "ImageStreamImportMode" },