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" }, 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) }