diff --git a/cmd/kube-apiserver/app/options/validation_test.go b/cmd/kube-apiserver/app/options/validation_test.go index 452c4ff0163..78dcd0a4e7b 100644 --- a/cmd/kube-apiserver/app/options/validation_test.go +++ b/cmd/kube-apiserver/app/options/validation_test.go @@ -187,8 +187,10 @@ func TestClusterServiceIPRange(t *testing.T) { if !tc.ipAllocatorGate { featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, utilfeature.DefaultFeatureGate, version.MustParse("1.32")) } - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.MultiCIDRServiceAllocator, tc.ipAllocatorGate) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DisableAllocatorDualWrite, tc.disableDualWriteGate) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.MultiCIDRServiceAllocator: tc.ipAllocatorGate, + features.DisableAllocatorDualWrite: tc.disableDualWriteGate, + }) errs := validateClusterIPFlags(tc.options.Extra) if len(errs) > 0 && !tc.expectErrors { diff --git a/cmd/kube-controller-manager/app/controllermanager_test.go b/cmd/kube-controller-manager/app/controllermanager_test.go index 92fb4c1c8a9..f78f393187a 100644 --- a/cmd/kube-controller-manager/app/controllermanager_test.go +++ b/cmd/kube-controller-manager/app/controllermanager_test.go @@ -116,14 +116,18 @@ func TestNewControllerDescriptorsShouldNotPanic(t *testing.T) { } func TestNewControllerDescriptorsAlwaysReturnsDescriptorsForAllControllers(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, "AllAlpha", false) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, "AllBeta", false) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + "AllAlpha": false, + "AllBeta": false, + }) controllersWithoutFeatureGates := KnownControllers() // AllBeta must be enabled before AllAlpha to resolve dependencies. - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, "AllBeta", true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, "AllAlpha", true) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + "AllBeta": true, + "AllAlpha": true, + }) controllersWithFeatureGates := KnownControllers() diff --git a/pkg/api/persistentvolumeclaim/util_test.go b/pkg/api/persistentvolumeclaim/util_test.go index 61b6cb34844..f28f63f3f9a 100644 --- a/pkg/api/persistentvolumeclaim/util_test.go +++ b/pkg/api/persistentvolumeclaim/util_test.go @@ -272,8 +272,10 @@ func TestDataSourceFilter(t *testing.T) { t.Run(testName, func(t *testing.T) { // TODO: this will be removed in 1.36 featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, utilfeature.DefaultFeatureGate, version.MustParse("1.32")) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.AnyVolumeDataSource, test.anyEnabled) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CrossNamespaceVolumeDataSource, test.xnsEnabled) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.AnyVolumeDataSource: test.anyEnabled, + features.CrossNamespaceVolumeDataSource: test.xnsEnabled, + }) DropDisabledFields(&test.spec, &test.oldSpec) if test.spec.DataSource != test.want { t.Errorf("expected condition was not met, test: %s, anyEnabled: %v, xnsEnabled: %v, spec: %+v, expected DataSource: %+v", @@ -370,8 +372,10 @@ func TestDataSourceRef(t *testing.T) { }, } - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.AnyVolumeDataSource, true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CrossNamespaceVolumeDataSource, true) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.AnyVolumeDataSource: true, + features.CrossNamespaceVolumeDataSource: true, + }) for testName, test := range tests { t.Run(testName, func(t *testing.T) { @@ -598,8 +602,10 @@ func TestDropDisabledFieldsFromStatus(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.RecoverVolumeExpansionFailure, test.enableRecoverVolumeExpansionFailure) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeAttributesClass, test.enableVolumeAttributesClass) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.RecoverVolumeExpansionFailure: test.enableRecoverVolumeExpansionFailure, + features.VolumeAttributesClass: test.enableVolumeAttributesClass, + }) DropDisabledFieldsFromStatus(test.pvc, test.oldPVC) diff --git a/pkg/api/pod/util_test.go b/pkg/api/pod/util_test.go index 1ad61379fcd..fa8e45a0683 100644 --- a/pkg/api/pod/util_test.go +++ b/pkg/api/pod/util_test.go @@ -1058,8 +1058,10 @@ func TestDropDynamicResourceAllocation(t *testing.T) { for _, tc := range testcases { t.Run(tc.description, func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DynamicResourceAllocation, tc.enabled) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRAExtendedResource, tc.extendedEnabled) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.DynamicResourceAllocation: tc.enabled, + features.DRAExtendedResource: tc.extendedEnabled, + }) oldPod := tc.oldPod.DeepCopy() newPod := tc.newPod.DeepCopy() @@ -2790,8 +2792,10 @@ func TestOldPodViolatesMatchLabelKeysValidationOption(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.MatchLabelKeysInPodTopologySpread, tc.matchLabelKeysEnabled) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.MatchLabelKeysInPodTopologySpreadSelectorMerge, tc.matchLabelKeysSelectorMergeEnabled) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.MatchLabelKeysInPodTopologySpread: tc.matchLabelKeysEnabled, + features.MatchLabelKeysInPodTopologySpreadSelectorMerge: tc.matchLabelKeysSelectorMergeEnabled, + }) gotOptions := GetValidationOptionsFromPodSpecAndMeta(&api.PodSpec{}, tc.oldPodSpec, nil, nil) if tc.wantOption != gotOptions.OldPodViolatesMatchLabelKeysValidation { t.Errorf("Got OldPodViolatesMatchLabelKeysValidation=%t, want %t", gotOptions.OldPodViolatesMatchLabelKeysValidation, tc.wantOption) @@ -2851,8 +2855,10 @@ func TestOldPodViolatesLegacyMatchLabelKeysValidationOption(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.MatchLabelKeysInPodTopologySpread, tc.matchLabelKeysEnabled) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.MatchLabelKeysInPodTopologySpreadSelectorMerge, tc.matchLabelKeysSelectorMergeEnabled) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.MatchLabelKeysInPodTopologySpread: tc.matchLabelKeysEnabled, + features.MatchLabelKeysInPodTopologySpreadSelectorMerge: tc.matchLabelKeysSelectorMergeEnabled, + }) gotOptions := GetValidationOptionsFromPodSpecAndMeta(&api.PodSpec{}, tc.oldPodSpec, nil, nil) if tc.wantOption != gotOptions.OldPodViolatesLegacyMatchLabelKeysValidation { t.Errorf("Got OldPodViolatesLegacyMatchLabelKeysValidation=%t, want %t", gotOptions.OldPodViolatesLegacyMatchLabelKeysValidation, tc.wantOption) diff --git a/pkg/api/testing/validation.go b/pkg/api/testing/validation.go index cc0c5f72dd3..ed74e7b304d 100644 --- a/pkg/api/testing/validation.go +++ b/pkg/api/testing/validation.go @@ -241,8 +241,10 @@ func verifyValidationEquivalence(t *testing.T, expectedErrs field.ErrorList, run // 1) the DeclarativeValidationTakeover won't take effect if DeclarativeValidation is disabled. // 2) the validation output, when only DeclarativeValidation is enabled, is the same as when both gates are disabled. t.Run("with declarative validation", func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DeclarativeValidation, true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DeclarativeValidationTakeover, true) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.DeclarativeValidation: true, + features.DeclarativeValidationTakeover: true, + }) declarativeTakeoverErrs = runValidations() if len(expectedErrs) > 0 { @@ -253,8 +255,10 @@ func verifyValidationEquivalence(t *testing.T, expectedErrs field.ErrorList, run }) t.Run("hand written validation", func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DeclarativeValidationTakeover, false) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DeclarativeValidation, false) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.DeclarativeValidationTakeover: false, + features.DeclarativeValidation: false, + }) imperativeErrs = runValidations() if len(expectedErrs) > 0 { diff --git a/pkg/api/v1/pod/util_test.go b/pkg/api/v1/pod/util_test.go index 50c3e05461e..7e2d08439f4 100644 --- a/pkg/api/v1/pod/util_test.go +++ b/pkg/api/v1/pod/util_test.go @@ -1076,9 +1076,7 @@ func TestCalculatePodStatusObservedGeneration(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - for f, v := range tc.features { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, f, v) - } + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, tc.features) assert.Equal(t, tc.expected, CalculatePodStatusObservedGeneration(tc.pod)) }) } @@ -1165,9 +1163,7 @@ func TestCalculatePodConditionObservedGeneration(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - for f, v := range tc.features { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, f, v) - } + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, tc.features) assert.Equal(t, tc.expected, CalculatePodConditionObservedGeneration(&tc.pod.Status, tc.pod.Generation, v1.PodReady)) }) } diff --git a/pkg/apis/core/validation/validation_test.go b/pkg/apis/core/validation/validation_test.go index 7c29131a797..e0268c2123d 100644 --- a/pkg/apis/core/validation/validation_test.go +++ b/pkg/apis/core/validation/validation_test.go @@ -3105,8 +3105,10 @@ func TestValidatePersistentVolumeClaimUpdate(t *testing.T) { for name, scenario := range scenarios { t.Run(name, func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.RecoverVolumeExpansionFailure, scenario.enableRecoverFromExpansion) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeAttributesClass, scenario.enableVolumeAttributesClass) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.RecoverVolumeExpansionFailure: scenario.enableRecoverFromExpansion, + features.VolumeAttributesClass: scenario.enableVolumeAttributesClass, + }) scenario.oldClaim.ResourceVersion = "1" scenario.newClaim.ResourceVersion = "1" @@ -17567,9 +17569,11 @@ func TestValidateServiceCreate(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PreferSameTrafficDistribution, tc.newTrafficDist) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.RelaxedServiceNameValidation, tc.relaxedServiceNames) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StrictIPCIDRValidation, !tc.legacyIPs) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.PreferSameTrafficDistribution: tc.newTrafficDist, + features.RelaxedServiceNameValidation: tc.relaxedServiceNames, + features.StrictIPCIDRValidation: !tc.legacyIPs, + }) svc := makeValidService() tc.tweakSvc(&svc) errs := ValidateServiceCreate(&svc) @@ -20291,8 +20295,10 @@ func TestValidateServiceUpdate(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StrictIPCIDRValidation, true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.RelaxedServiceNameValidation, tc.relaxedServiceNames) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.StrictIPCIDRValidation: true, + features.RelaxedServiceNameValidation: tc.relaxedServiceNames, + }) oldSvc := makeValidService() newSvc := makeValidService() @@ -24196,8 +24202,10 @@ func TestCrossNamespaceSource(t *testing.T) { } for _, tc := range testCases { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.AnyVolumeDataSource, true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CrossNamespaceVolumeDataSource, true) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.AnyVolumeDataSource: true, + features.CrossNamespaceVolumeDataSource: true, + }) opts := PersistentVolumeClaimSpecValidationOptions{} if tc.expectedFail { if errs := ValidatePersistentVolumeClaimSpec(tc.claimSpec, field.NewPath("spec"), opts); len(errs) == 0 { @@ -27070,8 +27078,10 @@ func TestValidateLoadBalancerStatus(t *testing.T) { // when testing !ipModeEnabled.) featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StrictIPCIDRValidation, !tc.legacyIPs) } - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LoadBalancerIPMode, tc.ipModeEnabled) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.AllowServiceLBStatusOnNonLB, tc.nonLBAllowed) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.LoadBalancerIPMode: tc.ipModeEnabled, + features.AllowServiceLBStatusOnNonLB: tc.nonLBAllowed, + }) oldStatus := core.LoadBalancerStatus{} if tc.tweakOldLBStatus != nil { tc.tweakOldLBStatus(&oldStatus) diff --git a/pkg/apis/resource/validation/validation_resourceclaim_test.go b/pkg/apis/resource/validation/validation_resourceclaim_test.go index 991f8cef768..00dc5cadfe9 100644 --- a/pkg/apis/resource/validation/validation_resourceclaim_test.go +++ b/pkg/apis/resource/validation/validation_resourceclaim_test.go @@ -2249,10 +2249,12 @@ func TestValidateClaimStatusUpdate(t *testing.T) { for name, scenario := range scenarios { t.Run(name, func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRAAdminAccess, scenario.adminAccess) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRAResourceClaimDeviceStatus, scenario.deviceStatusFeatureGate) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRAPrioritizedList, scenario.prioritizedListFeatureGate) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRAConsumableCapacity, scenario.consumableCapacityFeatureGate) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.DRAAdminAccess: scenario.adminAccess, + features.DRAResourceClaimDeviceStatus: scenario.deviceStatusFeatureGate, + features.DRAPrioritizedList: scenario.prioritizedListFeatureGate, + features.DRAConsumableCapacity: scenario.consumableCapacityFeatureGate, + }) scenario.oldClaim.ResourceVersion = "1" errs := ValidateResourceClaimStatusUpdate(scenario.update(scenario.oldClaim.DeepCopy()), scenario.oldClaim) diff --git a/pkg/controller/controller_utils_test.go b/pkg/controller/controller_utils_test.go index 819d44be1e5..4065306473d 100644 --- a/pkg/controller/controller_utils_test.go +++ b/pkg/controller/controller_utils_test.go @@ -863,8 +863,10 @@ func TestSortingActivePodsWithRanks(t *testing.T) { for i, test := range inequalityTests { t.Run(fmt.Sprintf("Inequality tests %d", i), func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PodDeletionCost, !test.disablePodDeletioncost) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LogarithmicScaleDown, !test.disableLogarithmicScaleDown) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.PodDeletionCost: !test.disablePodDeletioncost, + features.LogarithmicScaleDown: !test.disableLogarithmicScaleDown, + }) podsWithRanks := ActivePodsWithRanks{ Pods: []*v1.Pod{test.lesser.pod, test.greater.pod}, diff --git a/pkg/controller/job/job_controller_test.go b/pkg/controller/job/job_controller_test.go index e82bb7939d0..3e02e614079 100644 --- a/pkg/controller/job/job_controller_test.go +++ b/pkg/controller/job/job_controller_test.go @@ -1245,9 +1245,11 @@ func TestControllerSyncJob(t *testing.T) { // TODO: this will be removed in 1.37. featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, feature.DefaultFeatureGate, utilversion.MustParse("1.33")) } - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.JobPodReplacementPolicy, tc.jobPodReplacementPolicy) - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.JobSuccessPolicy, tc.jobSuccessPolicy) - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.JobManagedBy, tc.jobManagedBy) + featuregatetesting.SetFeatureGatesDuringTest(t, feature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.JobPodReplacementPolicy: tc.jobPodReplacementPolicy, + features.JobSuccessPolicy: tc.jobSuccessPolicy, + features.JobManagedBy: tc.jobManagedBy, + }) // job manager setup clientSet := clientset.NewForConfigOrDie(&restclient.Config{Host: "", ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Group: "", Version: "v1"}}}) @@ -2429,10 +2431,12 @@ func TestTrackJobStatusAndRemoveFinalizers(t *testing.T) { // TODO: this will be removed in 1.36 featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, feature.DefaultFeatureGate, utilversion.MustParse("1.32")) } - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.JobBackoffLimitPerIndex, tc.enableJobBackoffLimitPerIndex) - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.JobSuccessPolicy, tc.enableJobSuccessPolicy) - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.JobPodReplacementPolicy, tc.enableJobPodReplacementPolicy) - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.JobManagedBy, tc.enableJobManagedBy) + featuregatetesting.SetFeatureGatesDuringTest(t, feature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.JobBackoffLimitPerIndex: tc.enableJobBackoffLimitPerIndex, + features.JobSuccessPolicy: tc.enableJobSuccessPolicy, + features.JobPodReplacementPolicy: tc.enableJobPodReplacementPolicy, + features.JobManagedBy: tc.enableJobManagedBy, + }) clientSet := clientset.NewForConfigOrDie(&restclient.Config{Host: "", ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Group: "", Version: "v1"}}}) manager, _ := newControllerFromClientWithClock(ctx, t, clientSet, controller.NoResyncPeriodFunc, fakeClock) @@ -2686,8 +2690,10 @@ func TestSyncJobPastDeadline(t *testing.T) { // TODO: this will be removed in 1.37. featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, feature.DefaultFeatureGate, utilversion.MustParse("1.33")) } - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.JobManagedBy, tc.enableJobManagedBy) - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.JobPodReplacementPolicy, tc.enableJobPodReplacementPolicy) + featuregatetesting.SetFeatureGatesDuringTest(t, feature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.JobManagedBy: tc.enableJobManagedBy, + features.JobPodReplacementPolicy: tc.enableJobPodReplacementPolicy, + }) // job manager setup clientSet := clientset.NewForConfigOrDie(&restclient.Config{Host: "", ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Group: "", Version: "v1"}}}) manager, sharedInformerFactory := newControllerFromClient(ctx, t, clientSet, controller.NoResyncPeriodFunc) @@ -4162,8 +4168,10 @@ func TestSyncJobWithJobPodFailurePolicy(t *testing.T) { // TODO: this will be removed in 1.37. featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, feature.DefaultFeatureGate, utilversion.MustParse("1.33")) } - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.JobPodReplacementPolicy, tc.enableJobPodReplacementPolicy) - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.JobManagedBy, tc.enableJobManagedBy) + featuregatetesting.SetFeatureGatesDuringTest(t, feature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.JobPodReplacementPolicy: tc.enableJobPodReplacementPolicy, + features.JobManagedBy: tc.enableJobManagedBy, + }) if tc.job.Spec.PodReplacementPolicy == nil { tc.job.Spec.PodReplacementPolicy = podReplacementPolicy(batch.Failed) @@ -5175,10 +5183,12 @@ func TestSyncJobWithJobSuccessPolicy(t *testing.T) { // TODO: this will be removed in 1.36 featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, feature.DefaultFeatureGate, utilversion.MustParse("1.32")) } - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.JobBackoffLimitPerIndex, tc.enableBackoffLimitPerIndex) - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.JobSuccessPolicy, tc.enableJobSuccessPolicy) - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.JobPodReplacementPolicy, tc.enableJobPodReplacementPolicy) - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.JobManagedBy, tc.enableJobManagedBy) + featuregatetesting.SetFeatureGatesDuringTest(t, feature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.JobBackoffLimitPerIndex: tc.enableBackoffLimitPerIndex, + features.JobSuccessPolicy: tc.enableJobSuccessPolicy, + features.JobPodReplacementPolicy: tc.enableJobPodReplacementPolicy, + features.JobManagedBy: tc.enableJobManagedBy, + }) clientSet := clientset.NewForConfigOrDie(&restclient.Config{Host: "", ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Group: "", Version: "v1"}}}) fakeClock := clocktesting.NewFakeClock(now) @@ -5860,9 +5870,11 @@ func TestSyncJobWithJobBackoffLimitPerIndex(t *testing.T) { // TODO: this will be removed in 1.37. featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, feature.DefaultFeatureGate, utilversion.MustParse("1.33")) } - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.JobBackoffLimitPerIndex, tc.enableJobBackoffLimitPerIndex) - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.JobPodReplacementPolicy, tc.enableJobPodReplacementPolicy) - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.JobManagedBy, tc.enableJobManagedBy) + featuregatetesting.SetFeatureGatesDuringTest(t, feature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.JobBackoffLimitPerIndex: tc.enableJobBackoffLimitPerIndex, + features.JobPodReplacementPolicy: tc.enableJobPodReplacementPolicy, + features.JobManagedBy: tc.enableJobManagedBy, + }) clientset := clientset.NewForConfigOrDie(&restclient.Config{Host: "", ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Group: "", Version: "v1"}}}) fakeClock := clocktesting.NewFakeClock(now) manager, sharedInformerFactory := newControllerFromClientWithClock(ctx, t, clientset, controller.NoResyncPeriodFunc, fakeClock) @@ -7365,8 +7377,10 @@ func TestJobBackoffForOnFailure(t *testing.T) { // TODO: this will be removed in 1.37. featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, feature.DefaultFeatureGate, utilversion.MustParse("1.33")) } - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.JobPodReplacementPolicy, tc.enableJobPodReplacementPolicy) - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.JobManagedBy, tc.enableJobManagedBy) + featuregatetesting.SetFeatureGatesDuringTest(t, feature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.JobPodReplacementPolicy: tc.enableJobPodReplacementPolicy, + features.JobManagedBy: tc.enableJobManagedBy, + }) // job manager setup clientset := clientset.NewForConfigOrDie(&restclient.Config{Host: "", ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Group: "", Version: "v1"}}}) manager, sharedInformerFactory := newControllerFromClient(ctx, t, clientset, controller.NoResyncPeriodFunc) diff --git a/pkg/kubelet/allocation/allocation_manager_test.go b/pkg/kubelet/allocation/allocation_manager_test.go index 53574a7c312..56e3c595320 100644 --- a/pkg/kubelet/allocation/allocation_manager_test.go +++ b/pkg/kubelet/allocation/allocation_manager_test.go @@ -812,8 +812,10 @@ func TestHandlePodResourcesResizeForGuanteedQOSPods(t *testing.T) { for _, originalPod := range tt.podsToTest { isSidecarContainer := len(originalPod.Spec.InitContainers) > 0 t.Run(fmt.Sprintf("%s/sidecar=%t", tt.name, isSidecarContainer), func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.InPlacePodVerticalScalingExclusiveCPUs, tt.ipprExclusiveCPUsFeatureGate) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.InPlacePodVerticalScalingExclusiveMemory, tt.ipprExclusiveMemoryFeatureGate) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.InPlacePodVerticalScalingExclusiveCPUs: tt.ipprExclusiveCPUsFeatureGate, + features.InPlacePodVerticalScalingExclusiveMemory: tt.ipprExclusiveMemoryFeatureGate, + }) var originalCtr *v1.Container if isSidecarContainer { @@ -914,8 +916,10 @@ func TestHandlePodResourcesResizeWithSwap(t *testing.T) { metrics.Register() metrics.PodInfeasibleResizes.Reset() - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.InPlacePodVerticalScaling, true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.NodeSwap, true) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.InPlacePodVerticalScaling: true, + features.NodeSwap: true, + }) noSwapContainerName, swapContainerName := "test-container-noswap", "test-container-limitedswap" cpu500m := resource.MustParse("500m") diff --git a/pkg/kubelet/apis/podresources/server_v1_test.go b/pkg/kubelet/apis/podresources/server_v1_test.go index 36f631a5953..0875366206d 100644 --- a/pkg/kubelet/apis/podresources/server_v1_test.go +++ b/pkg/kubelet/apis/podresources/server_v1_test.go @@ -899,8 +899,10 @@ func TestAllocatableResources(t *testing.T) { } func TestGetPodResourcesV1(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, pkgfeatures.KubeletPodResourcesGet, true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, pkgfeatures.KubeletPodResourcesDynamicResources, true) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + pkgfeatures.KubeletPodResourcesGet: true, + pkgfeatures.KubeletPodResourcesDynamicResources: true, + }) tCtx := ktesting.Init(t) podName := "pod-name" @@ -1077,8 +1079,10 @@ func TestGetPodResourcesV1(t *testing.T) { } func TestGetPodResourcesWithInitContainersV1(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, pkgfeatures.KubeletPodResourcesGet, true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, pkgfeatures.KubeletPodResourcesDynamicResources, true) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + pkgfeatures.KubeletPodResourcesGet: true, + pkgfeatures.KubeletPodResourcesDynamicResources: true, + }) tCtx := ktesting.Init(t) podName := "pod-name" diff --git a/pkg/kubelet/cm/cpumanager/policy_options_test.go b/pkg/kubelet/cm/cpumanager/policy_options_test.go index ba9c1461115..f09e580147e 100644 --- a/pkg/kubelet/cm/cpumanager/policy_options_test.go +++ b/pkg/kubelet/cm/cpumanager/policy_options_test.go @@ -149,8 +149,10 @@ func TestPolicyOptionsAlwaysAvailableOnceGA(t *testing.T) { } for _, option := range options { t.Run(option, func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, pkgfeatures.CPUManagerPolicyAlphaOptions, false) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, pkgfeatures.CPUManagerPolicyBetaOptions, false) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + pkgfeatures.CPUManagerPolicyAlphaOptions: false, + pkgfeatures.CPUManagerPolicyBetaOptions: false, + }) if err := CheckPolicyOptionAvailable(option); err != nil { t.Errorf("option %q should be available even with all featuregate disabled", option) } diff --git a/pkg/kubelet/server/server_test.go b/pkg/kubelet/server/server_test.go index 273f27bbbc7..bd80ac92d40 100644 --- a/pkg/kubelet/server/server_test.go +++ b/pkg/kubelet/server/server_test.go @@ -674,9 +674,11 @@ func TestInstallAuthNotRequiredHandlers(t *testing.T) { func TestAuthFilters(t *testing.T) { tCtx := ktesting.Init(t) // Enable features.ContainerCheckpoint during test - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ContainerCheckpoint, true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, zpagesfeatures.ComponentStatusz, true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, zpagesfeatures.ComponentFlagz, true) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.ContainerCheckpoint: true, + zpagesfeatures.ComponentStatusz: true, + zpagesfeatures.ComponentFlagz: true, + }) fw := newServerTest(tCtx) defer fw.testHTTPServer.Close() diff --git a/pkg/registry/batch/job/strategy_test.go b/pkg/registry/batch/job/strategy_test.go index 1997106a2da..f11d5959924 100644 --- a/pkg/registry/batch/job/strategy_test.go +++ b/pkg/registry/batch/job/strategy_test.go @@ -520,9 +520,11 @@ func TestJobStrategy_PrepareForUpdate(t *testing.T) { // TODO: this will be removed in 1.37. featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, utilfeature.DefaultFeatureGate, utilversion.MustParse("1.33")) } - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.JobBackoffLimitPerIndex, tc.enableJobBackoffLimitPerIndex) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.JobPodReplacementPolicy, tc.enableJobPodReplacementPolicy) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.JobSuccessPolicy, tc.enableJobSuccessPolicy) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.JobBackoffLimitPerIndex: tc.enableJobBackoffLimitPerIndex, + features.JobPodReplacementPolicy: tc.enableJobPodReplacementPolicy, + features.JobSuccessPolicy: tc.enableJobSuccessPolicy, + }) ctx := genericapirequest.NewDefaultContext() Strategy.PrepareForUpdate(ctx, &tc.updatedJob, &tc.job) @@ -905,10 +907,12 @@ func TestJobStrategy_PrepareForCreate(t *testing.T) { // TODO: this will be removed in 1.36 featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, utilfeature.DefaultFeatureGate, utilversion.MustParse("1.32")) } - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.JobBackoffLimitPerIndex, tc.enableJobBackoffLimitPerIndex) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.JobPodReplacementPolicy, tc.enableJobPodReplacementPolicy) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.JobManagedBy, tc.enableJobManageBy) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.JobSuccessPolicy, tc.enableJobSuccessPolicy) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.JobBackoffLimitPerIndex: tc.enableJobBackoffLimitPerIndex, + features.JobPodReplacementPolicy: tc.enableJobPodReplacementPolicy, + features.JobManagedBy: tc.enableJobManageBy, + features.JobSuccessPolicy: tc.enableJobSuccessPolicy, + }) ctx := genericapirequest.NewDefaultContext() Strategy.PrepareForCreate(ctx, &tc.job) @@ -3578,9 +3582,11 @@ func TestStatusStrategy_ValidateUpdate(t *testing.T) { // TODO: this will be removed in 1.37. featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, utilfeature.DefaultFeatureGate, utilversion.MustParse("1.33")) } - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.JobManagedBy, tc.enableJobManagedBy) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.JobSuccessPolicy, tc.enableJobSuccessPolicy) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.JobPodReplacementPolicy, tc.enableJobPodReplacementPolicy) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.JobManagedBy: tc.enableJobManagedBy, + features.JobSuccessPolicy: tc.enableJobSuccessPolicy, + features.JobPodReplacementPolicy: tc.enableJobPodReplacementPolicy, + }) errs := StatusStrategy.ValidateUpdate(ctx, tc.newJob, tc.job) if diff := cmp.Diff(tc.wantErrs, errs, ignoreErrValueDetail); diff != "" { diff --git a/pkg/registry/core/persistentvolumeclaim/strategy_test.go b/pkg/registry/core/persistentvolumeclaim/strategy_test.go index 5964f3c5260..3704f07e370 100644 --- a/pkg/registry/core/persistentvolumeclaim/strategy_test.go +++ b/pkg/registry/core/persistentvolumeclaim/strategy_test.go @@ -346,8 +346,10 @@ func TestPrepareForCreate(t *testing.T) { t.Run(testName, func(t *testing.T) { // TODO: this will be removed in 1.36 featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, utilfeature.DefaultFeatureGate, version.MustParse("1.32")) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.AnyVolumeDataSource, test.anyEnabled) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CrossNamespaceVolumeDataSource, test.xnsEnabled) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.AnyVolumeDataSource: test.anyEnabled, + features.CrossNamespaceVolumeDataSource: test.xnsEnabled, + }) pvc := api.PersistentVolumeClaim{ Spec: api.PersistentVolumeClaimSpec{ DataSource: test.dataSource, diff --git a/pkg/registry/core/pod/strategy_test.go b/pkg/registry/core/pod/strategy_test.go index 65fe5dbbf11..d4c2ab55e11 100644 --- a/pkg/registry/core/pod/strategy_test.go +++ b/pkg/registry/core/pod/strategy_test.go @@ -2047,8 +2047,10 @@ func Test_mutateTopologySpreadConstraints(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.MatchLabelKeysInPodTopologySpread, tc.matchLabelKeysEnabled) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.MatchLabelKeysInPodTopologySpreadSelectorMerge, tc.matchLabelKeysSelectorMergeEnabled) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.MatchLabelKeysInPodTopologySpread: tc.matchLabelKeysEnabled, + features.MatchLabelKeysInPodTopologySpreadSelectorMerge: tc.matchLabelKeysSelectorMergeEnabled, + }) pod := tc.pod mutateTopologySpreadConstraints(pod) @@ -2233,8 +2235,10 @@ func TestUpdateLabelOnPodWithTopologySpreadConstraintsEnabled(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.MatchLabelKeysInPodTopologySpread, tc.matchLabelKeysEnabled) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.MatchLabelKeysInPodTopologySpreadSelectorMerge, tc.matchLabelKeysSelectorMergeEnabled) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.MatchLabelKeysInPodTopologySpread: tc.matchLabelKeysEnabled, + features.MatchLabelKeysInPodTopologySpreadSelectorMerge: tc.matchLabelKeysSelectorMergeEnabled, + }) Strategy.PrepareForCreate(genericapirequest.NewContext(), tc.pod) if errs := Strategy.Validate(genericapirequest.NewContext(), tc.pod); len(errs) != 0 { @@ -3516,8 +3520,10 @@ func TestPodResizePrepareForUpdate(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.InPlacePodVerticalScaling, true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SidecarContainers, true) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.InPlacePodVerticalScaling: true, + features.SidecarContainers: true, + }) ctx := context.Background() ResizeStrategy.PrepareForUpdate(ctx, tc.newPod, tc.oldPod) if !cmp.Equal(tc.expected, tc.newPod) { @@ -4178,9 +4184,7 @@ func TestStatusPrepareForUpdate(t *testing.T) { for _, tc := range testCases { t.Run(tc.description, func(t *testing.T) { - for f, v := range tc.features { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, f, v) - } + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, tc.features) StatusStrategy.PrepareForUpdate(genericapirequest.NewContext(), tc.newPod, tc.oldPod) if !cmp.Equal(tc.expected, tc.newPod) { t.Errorf("StatusStrategy.PrepareForUpdate() diff = %v", cmp.Diff(tc.expected, tc.newPod)) diff --git a/pkg/registry/core/replicationcontroller/storage/scale_declarative_validation_test.go b/pkg/registry/core/replicationcontroller/storage/scale_declarative_validation_test.go index 0b4596fad7a..3be38c0e3dd 100644 --- a/pkg/registry/core/replicationcontroller/storage/scale_declarative_validation_test.go +++ b/pkg/registry/core/replicationcontroller/storage/scale_declarative_validation_test.go @@ -77,8 +77,10 @@ func TestValidateScaleForDeclarative(t *testing.T) { // We only need to test both gate enabled and disabled together, because // 1) the DeclarativeValidationTakeover won't take effect if DeclarativeValidation is disabled. // 2) the validation output, when only DeclarativeValidation is enabled, is the same as when both gates are disabled. - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DeclarativeValidation, gateVal) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DeclarativeValidationTakeover, gateVal) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.DeclarativeValidation: gateVal, + features.DeclarativeValidationTakeover: gateVal, + }) _, _, err := storage.Scale.Update(ctx, tc.input.Name, rest.DefaultUpdatedObjectInfo(&tc.input), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) errs := errorListFromStatusError(t, err) diff --git a/pkg/registry/resource/resourceclaim/strategy_test.go b/pkg/registry/resource/resourceclaim/strategy_test.go index 40c50e2a15c..245695c35b3 100644 --- a/pkg/registry/resource/resourceclaim/strategy_test.go +++ b/pkg/registry/resource/resourceclaim/strategy_test.go @@ -530,9 +530,11 @@ func TestStrategyCreate(t *testing.T) { t.Run(name, func(t *testing.T) { fakeClient := fake.NewSimpleClientset(ns1, ns2) mockNSClient := fakeClient.CoreV1().Namespaces() - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRAAdminAccess, tc.adminAccess) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRAPrioritizedList, tc.prioritizedList) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRAConsumableCapacity, tc.consumableCapacity) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.DRAAdminAccess: tc.adminAccess, + features.DRAPrioritizedList: tc.prioritizedList, + features.DRAConsumableCapacity: tc.consumableCapacity, + }) strategy := NewStrategy(mockNSClient) obj := tc.obj.DeepCopy() @@ -753,9 +755,11 @@ func TestStrategyUpdate(t *testing.T) { fakeClient := fake.NewSimpleClientset(ns1, ns2) mockNSClient := fakeClient.CoreV1().Namespaces() - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRAAdminAccess, tc.adminAccess) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRAPrioritizedList, tc.prioritizedList) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRAConsumableCapacity, tc.consumableCapacity) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.DRAAdminAccess: tc.adminAccess, + features.DRAPrioritizedList: tc.prioritizedList, + features.DRAConsumableCapacity: tc.consumableCapacity, + }) strategy := NewStrategy(mockNSClient) @@ -1364,13 +1368,17 @@ func TestStatusStrategyUpdate(t *testing.T) { mockNSClient := fakeClient.CoreV1().Namespaces() strategy := NewStrategy(mockNSClient) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRAAdminAccess, tc.adminAccess) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRAResourceClaimDeviceStatus, tc.deviceStatusFeatureGate) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRADeviceBindingConditions, tc.bindingConditions) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.DRAAdminAccess: tc.adminAccess, + features.DRAResourceClaimDeviceStatus: tc.deviceStatusFeatureGate, + features.DRADeviceBindingConditions: tc.bindingConditions, + }) klog.InfoS("Testing strategy", "adminAccess", tc.adminAccess, "bindingConditions", tc.bindingConditions, "deviceStatus", tc.deviceStatusFeatureGate) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRAConsumableCapacity, tc.consumableCapacityFeatureGate) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRAPrioritizedList, tc.prioritizedListFeatureGate) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.DRAConsumableCapacity: tc.consumableCapacityFeatureGate, + features.DRAPrioritizedList: tc.prioritizedListFeatureGate, + }) statusStrategy := NewStatusStrategy(strategy) oldObj := tc.oldObj.DeepCopy() diff --git a/pkg/registry/resource/resourceclaimtemplate/strategy_test.go b/pkg/registry/resource/resourceclaimtemplate/strategy_test.go index 201e6475312..33b834c54ce 100644 --- a/pkg/registry/resource/resourceclaimtemplate/strategy_test.go +++ b/pkg/registry/resource/resourceclaimtemplate/strategy_test.go @@ -359,8 +359,10 @@ func TestClaimTemplateStrategyCreate(t *testing.T) { t.Run(name, func(t *testing.T) { fakeClient := fake.NewSimpleClientset(ns1, ns2) mockNSClient := fakeClient.CoreV1().Namespaces() - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRAAdminAccess, tc.adminAccess) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRAPrioritizedList, tc.prioritizedList) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.DRAAdminAccess: tc.adminAccess, + features.DRAPrioritizedList: tc.prioritizedList, + }) strategy := NewStrategy(mockNSClient) obj := tc.obj.DeepCopy() diff --git a/pkg/registry/resource/resourceslice/strategy_test.go b/pkg/registry/resource/resourceslice/strategy_test.go index 9280cbf0cd5..277c2487644 100644 --- a/pkg/registry/resource/resourceslice/strategy_test.go +++ b/pkg/registry/resource/resourceslice/strategy_test.go @@ -310,11 +310,13 @@ func TestResourceSliceStrategyCreate(t *testing.T) { for name, tc := range testCases { t.Run(name, func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRADeviceTaints, tc.deviceTaints) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRAPartitionableDevices, tc.partitionableDevices) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRADeviceBindingConditions, tc.bindingConditions) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRAResourceClaimDeviceStatus, tc.deviceStatus) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRAConsumableCapacity, tc.consumableCapacity) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.DRADeviceTaints: tc.deviceTaints, + features.DRAPartitionableDevices: tc.partitionableDevices, + features.DRADeviceBindingConditions: tc.bindingConditions, + features.DRAResourceClaimDeviceStatus: tc.deviceStatus, + features.DRAConsumableCapacity: tc.consumableCapacity, + }) obj := tc.obj.DeepCopy() @@ -641,11 +643,13 @@ func TestResourceSliceStrategyUpdate(t *testing.T) { for name, tc := range testcases { t.Run(name, func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRADeviceTaints, tc.deviceTaints) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRAPartitionableDevices, tc.partitionableDevices) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRADeviceBindingConditions, tc.bindingConditions) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRAResourceClaimDeviceStatus, tc.deviceStatus) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRAConsumableCapacity, tc.consumableCapacity) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.DRADeviceTaints: tc.deviceTaints, + features.DRAPartitionableDevices: tc.partitionableDevices, + features.DRADeviceBindingConditions: tc.bindingConditions, + features.DRAResourceClaimDeviceStatus: tc.deviceStatus, + features.DRAConsumableCapacity: tc.consumableCapacity, + }) oldObj := tc.oldObj.DeepCopy() newObj := tc.newObj.DeepCopy() diff --git a/pkg/registry/storage/csidriver/strategy_test.go b/pkg/registry/storage/csidriver/strategy_test.go index 39c48c3fd86..96f31dda87b 100644 --- a/pkg/registry/storage/csidriver/strategy_test.go +++ b/pkg/registry/storage/csidriver/strategy_test.go @@ -397,8 +397,10 @@ func TestCSIDriverPrepareForUpdate(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, test.seLinuxMountReadWriteOncePodEnabled) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.MutableCSINodeAllocatableCount, test.mutableCSINodeAllocatableCountEnabled) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.SELinuxMountReadWriteOncePod: test.seLinuxMountReadWriteOncePodEnabled, + features.MutableCSINodeAllocatableCount: test.mutableCSINodeAllocatableCountEnabled, + }) csiDriver := test.update.DeepCopy() Strategy.PrepareForUpdate(ctx, csiDriver, test.old) @@ -624,8 +626,10 @@ func TestCSIDriverValidation(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { // assume this feature is on for this test, detailed enabled/disabled tests in TestCSIDriverValidationSELinuxMountEnabledDisabled - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.MutableCSINodeAllocatableCount, true) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.SELinuxMountReadWriteOncePod: true, + features.MutableCSINodeAllocatableCount: true, + }) testValidation := func(csiDriver *storage.CSIDriver, apiVersion string) field.ErrorList { ctx := genericapirequest.WithRequestInfo(genericapirequest.NewContext(), &genericapirequest.RequestInfo{ diff --git a/pkg/scheduler/apis/config/v1/default_plugins_test.go b/pkg/scheduler/apis/config/v1/default_plugins_test.go index c170958eb37..a6f945c96d5 100644 --- a/pkg/scheduler/apis/config/v1/default_plugins_test.go +++ b/pkg/scheduler/apis/config/v1/default_plugins_test.go @@ -101,9 +101,7 @@ func TestApplyFeatureGates(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - for k, v := range test.features { - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, k, v) - } + featuregatetesting.SetFeatureGatesDuringTest(t, feature.DefaultFeatureGate, test.features) gotConfig := getDefaultPlugins() if diff := cmp.Diff(test.wantConfig, gotConfig); diff != "" { diff --git a/pkg/scheduler/apis/config/v1/defaults_test.go b/pkg/scheduler/apis/config/v1/defaults_test.go index 41380d4c098..9291060c701 100644 --- a/pkg/scheduler/apis/config/v1/defaults_test.go +++ b/pkg/scheduler/apis/config/v1/defaults_test.go @@ -702,9 +702,7 @@ func TestSchedulerDefaults(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - for featureName, enabled := range tc.features { - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, featureName, enabled) - } + featuregatetesting.SetFeatureGatesDuringTest(t, feature.DefaultFeatureGate, tc.features) SetDefaults_KubeSchedulerConfiguration(tc.config) if diff := cmp.Diff(tc.expected, tc.config); diff != "" { t.Errorf("Got unexpected defaults (-want, +got):\n%s", diff) @@ -899,9 +897,7 @@ func TestPluginArgsDefaults(t *testing.T) { scheme := runtime.NewScheme() utilruntime.Must(AddToScheme(scheme)) t.Run(tc.name, func(t *testing.T) { - for k, v := range tc.features { - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, k, v) - } + featuregatetesting.SetFeatureGatesDuringTest(t, feature.DefaultFeatureGate, tc.features) scheme.Default(tc.in) if diff := cmp.Diff(tc.want, tc.in); diff != "" { t.Errorf("Got unexpected defaults (-want, +got):\n%s", diff) diff --git a/pkg/scheduler/apis/config/validation/validation_pluginargs_test.go b/pkg/scheduler/apis/config/validation/validation_pluginargs_test.go index f9ff3ea9b87..9c5a4c43ccf 100644 --- a/pkg/scheduler/apis/config/validation/validation_pluginargs_test.go +++ b/pkg/scheduler/apis/config/validation/validation_pluginargs_test.go @@ -656,9 +656,7 @@ func TestValidateVolumeBindingArgs(t *testing.T) { for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { - for k, v := range tc.features { - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, k, v) - } + featuregatetesting.SetFeatureGatesDuringTest(t, feature.DefaultFeatureGate, tc.features) err := ValidateVolumeBindingArgs(nil, &tc.args) if diff := cmp.Diff(tc.wantErr, err, ignoreBadValueDetail); diff != "" { t.Errorf("ValidateVolumeBindingArgs returned err (-want,+got):\n%s", diff) diff --git a/pkg/scheduler/eventhandlers_test.go b/pkg/scheduler/eventhandlers_test.go index 47fd3243a17..7a395b6159e 100644 --- a/pkg/scheduler/eventhandlers_test.go +++ b/pkg/scheduler/eventhandlers_test.go @@ -558,8 +558,10 @@ func TestAddAllEventHandlers(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DynamicResourceAllocation, tt.enableDRA) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRADeviceTaints, tt.enableDRADeviceTaints) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.DynamicResourceAllocation: tt.enableDRA, + features.DRADeviceTaints: tt.enableDRADeviceTaints, + }) logger, ctx := ktesting.NewTestContext(t) ctx, cancel := context.WithCancel(ctx) diff --git a/pkg/scheduler/scheduler_test.go b/pkg/scheduler/scheduler_test.go index 3fa7f7c6a80..1cbc3580224 100644 --- a/pkg/scheduler/scheduler_test.go +++ b/pkg/scheduler/scheduler_test.go @@ -1006,8 +1006,10 @@ func Test_UnionedGVKs(t *testing.T) { t.Run(tt.name, func(t *testing.T) { pluginConfig := defaults.PluginConfigsV1 - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.InPlacePodVerticalScaling, tt.enableInPlacePodVerticalScaling) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DynamicResourceAllocation, tt.enableDynamicResourceAllocation) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.InPlacePodVerticalScaling: tt.enableInPlacePodVerticalScaling, + features.DynamicResourceAllocation: tt.enableDynamicResourceAllocation, + }) if !tt.enableSchedulerQueueingHints { featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, utilfeature.DefaultFeatureGate, version.MustParse("1.33")) featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SchedulerQueueingHints, false) diff --git a/plugin/pkg/auth/authorizer/node/node_authorizer_test.go b/plugin/pkg/auth/authorizer/node/node_authorizer_test.go index 5b32082c3a5..06c9a7a1879 100644 --- a/plugin/pkg/auth/authorizer/node/node_authorizer_test.go +++ b/plugin/pkg/auth/authorizer/node/node_authorizer_test.go @@ -79,8 +79,10 @@ func TestNodeAuthorizer(t *testing.T) { selectorAuthzDisabled := func(t testing.TB) featuregate.FeatureGate { f := utilfeature.DefaultFeatureGate.DeepCopy() featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, f, version.MustParse("1.33")) - featuregatetesting.SetFeatureGateDuringTest(t, f, genericfeatures.AuthorizeWithSelectors, false) - featuregatetesting.SetFeatureGateDuringTest(t, f, features.AuthorizeNodeWithSelectors, false) + featuregatetesting.SetFeatureGatesDuringTest(t, f, featuregatetesting.FeatureOverrides{ + genericfeatures.AuthorizeWithSelectors: false, + features.AuthorizeNodeWithSelectors: false, + }) return f } @@ -102,9 +104,11 @@ func TestNodeAuthorizer(t *testing.T) { podCertificateProjectionEnabled := func(t testing.TB) featuregate.FeatureGate { f := utilfeature.DefaultFeatureGate.DeepCopy() - featuregatetesting.SetFeatureGateDuringTest(t, f, genericfeatures.AuthorizeWithSelectors, true) - featuregatetesting.SetFeatureGateDuringTest(t, f, features.AuthorizeNodeWithSelectors, true) - featuregatetesting.SetFeatureGateDuringTest(t, f, features.PodCertificateRequest, true) + featuregatetesting.SetFeatureGatesDuringTest(t, f, featuregatetesting.FeatureOverrides{ + genericfeatures.AuthorizeWithSelectors: true, + features.AuthorizeNodeWithSelectors: true, + features.PodCertificateRequest: true, + }) return f } diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy_test.go b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy_test.go index 50b20b08b35..c6b16a548ad 100644 --- a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy_test.go +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy_test.go @@ -178,8 +178,10 @@ func TestBootstrapClusterRoles(t *testing.T) { } func TestBootstrapClusterRolesWithFeatureGatesEnabled(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, "AllAlpha", true) - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, "AllBeta", true) + featuregatetesting.SetFeatureGatesDuringTest(t, feature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + "AllAlpha": true, + "AllBeta": true, + }) bootstrapRoles := bootstrappolicy.ClusterRoles() featureGateList := &api.List{} diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy_test.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy_test.go index 17abd2374eb..b4607c701bf 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy_test.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy_test.go @@ -1313,8 +1313,10 @@ func TestDropDisabledFields(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, utilfeature.DefaultFeatureGate, version.MustParse("1.31")) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, apiextensionsfeatures.CRDValidationRatcheting, tc.enableRatcheting) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, apiextensionsfeatures.CustomResourceFieldSelectors, tc.enableSelectableFields) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + apiextensionsfeatures.CRDValidationRatcheting: tc.enableRatcheting, + apiextensionsfeatures.CustomResourceFieldSelectors: tc.enableSelectableFields, + }) old := tc.oldCRD.DeepCopy() dropDisabledFields(tc.crd, tc.oldCRD) diff --git a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/validation/validation_test.go b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/validation/validation_test.go index 70b22998f06..e0ad15521bf 100644 --- a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/validation/validation_test.go +++ b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/validation/validation_test.go @@ -828,8 +828,10 @@ func TestValidateAuthenticationConfiguration(t *testing.T) { featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StructuredAuthenticationConfigurationEgressSelector, *tt.structuredAuthnEgressSelectorFeatureOverride) } if tt.gaOnly { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, "AllAlpha", false) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, "AllBeta", false) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + "AllAlpha": false, + "AllBeta": false, + }) } got := ValidateAuthenticationConfiguration(authenticationcel.NewDefaultCompiler(), tt.in, tt.disallowedIssuers).ToAggregate() if d := cmp.Diff(tt.want, errString(got)); d != "" { diff --git a/staging/src/k8s.io/apiserver/pkg/reconcilers/peer_endpoint_lease_test.go b/staging/src/k8s.io/apiserver/pkg/reconcilers/peer_endpoint_lease_test.go index cb17628f5e2..c4ac0bad30e 100644 --- a/staging/src/k8s.io/apiserver/pkg/reconcilers/peer_endpoint_lease_test.go +++ b/staging/src/k8s.io/apiserver/pkg/reconcilers/peer_endpoint_lease_test.go @@ -79,8 +79,10 @@ func (f *peerEndpointLeaseReconciler) SetKeys(servers []serverInfo) error { func TestPeerEndpointLeaseReconciler(t *testing.T) { // enable feature flags - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.APIServerIdentity, true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StorageVersionAPI, true) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.APIServerIdentity: true, + features.StorageVersionAPI: true, + }) server, sc := etcd3testing.NewUnsecuredEtcd3TestClientServer(t) t.Cleanup(func() { server.Terminate(t) }) @@ -189,8 +191,10 @@ func TestPeerEndpointLeaseReconciler(t *testing.T) { func TestPeerLeaseRemoveEndpoints(t *testing.T) { // enable feature flags - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.APIServerIdentity, true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StorageVersionAPI, true) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.APIServerIdentity: true, + features.StorageVersionAPI: true, + }) server, sc := etcd3testing.NewUnsecuredEtcd3TestClientServer(t) t.Cleanup(func() { server.Terminate(t) }) diff --git a/staging/src/k8s.io/apiserver/pkg/storage/cacher/cacher_whitebox_test.go b/staging/src/k8s.io/apiserver/pkg/storage/cacher/cacher_whitebox_test.go index c4660b69176..f3505293306 100644 --- a/staging/src/k8s.io/apiserver/pkg/storage/cacher/cacher_whitebox_test.go +++ b/staging/src/k8s.io/apiserver/pkg/storage/cacher/cacher_whitebox_test.go @@ -780,8 +780,10 @@ func TestGetListNonRecursiveCacheBypass(t *testing.T) { func TestGetListNonRecursiveCacheWithConsistentListFromCache(t *testing.T) { // Set feature gates once at the beginning since we only care about ConsistentListFromCache=true and ListFromCacheSnapshot=false - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ConsistentListFromCache, true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ListFromCacheSnapshot, false) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.ConsistentListFromCache: true, + features.ListFromCacheSnapshot: false, + }) forceRequestWatchProgressSupport(t) tests := []struct { @@ -2411,8 +2413,10 @@ func TestCacheIntervalInvalidationStopsWatch(t *testing.T) { } func TestWaitUntilWatchCacheFreshAndForceAllEvents(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.WatchList, true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ConsistentListFromCache, true) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.WatchList: true, + features.ConsistentListFromCache: true, + }) forceRequestWatchProgressSupport(t) scenarios := []struct { diff --git a/staging/src/k8s.io/component-base/featuregate/testing/feature_gate.go b/staging/src/k8s.io/component-base/featuregate/testing/feature_gate.go index 1d7fc46768e..2ae604c83f5 100644 --- a/staging/src/k8s.io/component-base/featuregate/testing/feature_gate.go +++ b/staging/src/k8s.io/component-base/featuregate/testing/feature_gate.go @@ -36,8 +36,11 @@ func init() { featureFlagOverride = map[featuregate.Feature]string{} } +type FeatureOverrides = map[featuregate.Feature]bool + // SetFeatureGateDuringTest sets the specified gate to the specified value for duration of the test. // Fails when it detects second call to the same flag or is unable to set or restore feature flag. +// When disabling a feature, this automatically disables all dependents. // // WARNING: Can leak set variable when called in test calling t.Parallel(), however second attempt to set the same feature flag will cause fatal. // @@ -46,52 +49,120 @@ func init() { // featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features., true) func SetFeatureGateDuringTest(tb TB, gate featuregate.FeatureGate, f featuregate.Feature, value bool) { tb.Helper() - detectParallelOverrideCleanup := detectParallelOverride(tb, f) - originalValue := gate.Enabled(f) + SetFeatureGatesDuringTest(tb, gate, FeatureOverrides{f: value}) +} + +// SetFeatureGatesDuringTest sets the specified map of feature gate values for duration of the test. +// Fails when it detects second call to the same flag or is unable to set or restore feature flag. +// When disabling a feature, this automatically disables all dependents that weren't explicitly set. +// +// WARNING: Can leak set variable when called in test calling t.Parallel(), however second attempt to set the same feature flag will cause fatal. +// +// Example use: +// +// featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ +// features.: true, +// features.: false, +// }) +func SetFeatureGatesDuringTest(tb TB, gate featuregate.FeatureGate, features FeatureOverrides) { + tb.Helper() originalEmuVer := gate.(featuregate.MutableVersionedFeatureGate).EmulationVersion() - originalExplicitlySet := gate.(featuregate.MutableVersionedFeatureGate).ExplicitlySet(f) + originalValues := map[string]bool{} + var originalUnset []featuregate.Feature + overrides := FeatureOverrides{} // Specially handle AllAlpha and AllBeta - if f == "AllAlpha" || f == "AllBeta" { + allAlphaValue, allAlpha := features["AllAlpha"] + allBetaValue, allBeta := features["AllBeta"] + if allAlpha || allBeta { // Iterate over individual gates so their individual values get restored for k, v := range gate.(featuregate.MutableFeatureGate).GetAll() { - if k == "AllAlpha" || k == "AllBeta" { - continue - } - if (f == "AllAlpha" && v.PreRelease == featuregate.Alpha) || (f == "AllBeta" && v.PreRelease == featuregate.Beta) { - SetFeatureGateDuringTest(tb, gate, k, value) + if (allAlpha && v.PreRelease == featuregate.Alpha) || (allBeta && v.PreRelease == featuregate.Beta) { + // Setting AllAlpha or AllBeta on their own only sets unset features, but for + // testing we want to override ALL alpha/beta features. So we explicitly set each + // alpha/beta feature in addition to AllAlpha/AllBeta + if v.PreRelease == featuregate.Alpha { + overrides[k] = allAlphaValue + } else { + overrides[k] = allBetaValue + } } } } - if err := gate.(featuregate.MutableFeatureGate).Set(fmt.Sprintf("%s=%v", f, value)); err != nil { - if s := suggestChangeEmulationVersion(tb, gate, f, value); s != "" { - tb.Errorf("error setting %s=%v: %v. %s", f, value, err, s) - } else { - tb.Errorf("error setting %s=%v: %v", f, value, err) + // Explicit features take precedence, so merge them in now. + for f, v := range features { + overrides[f] = v + } + + // Automatically disable dependents when disabling a dependency. + dependencies := gate.Dependencies() + for f := range dependencies { + if _, overridden := overrides[f]; overridden || !gate.Enabled(f) { + continue // Don't automatically disable features that have been explicitly set. + } + // If the feature gate was default-enabled and has an explicitly + // disabled dependency, then automatically disable it. + if disabled, disabledDep := hasDisabledDependency(f, dependencies, features); disabled { + tb.Logf("Disabling feature %s since it depends on disabled feature %s", f, disabledDep) + overrides[f] = false + } + } + + for f := range overrides { + originalValues[string(f)] = gate.Enabled(f) + if !gate.(featuregate.MutableVersionedFeatureGate).ExplicitlySet(f) { + originalUnset = append(originalUnset, f) + } + tb.Cleanup(detectParallelOverride(tb, featuregate.Feature(f))) + } + + m := map[string]bool{} + for f, v := range overrides { + m[string(f)] = v + } + if err := gate.(featuregate.MutableFeatureGate).SetFromMap(m); err != nil { + tb.Errorf("Failed to set feature gates: %v", err) + for f, v := range features { + if s := suggestChangeEmulationVersion(tb, gate, f, v); s != "" { + tb.Errorf("error setting %s=%v: %v. %s", f, v, err, s) + } } } tb.Cleanup(func() { tb.Helper() - detectParallelOverrideCleanup() emuVer := gate.(featuregate.MutableVersionedFeatureGate).EmulationVersion() if !emuVer.EqualTo(originalEmuVer) { tb.Fatalf("change of feature gate emulation version from %s to %s in the chain of SetFeatureGateDuringTest is not allowed\nuse SetFeatureGateEmulationVersionDuringTest to change emulation version in tests", originalEmuVer.String(), emuVer.String()) } - if originalExplicitlySet { - if err := gate.(featuregate.MutableFeatureGate).Set(fmt.Sprintf("%s=%v", f, originalValue)); err != nil { - tb.Errorf("error restoring %s=%v: %v", f, originalValue, err) - } - } else { + // To avoid violating feature dependencies, first atomicaly restore all original values, + // then reset features that were unset (the value should be unchanged). + if err := gate.(featuregate.MutableVersionedFeatureGate).SetFromMap(originalValues); err != nil { + tb.Errorf("error restoring features %v: %v", originalValues, err) + } + for _, f := range originalUnset { if err := gate.(featuregate.MutableVersionedFeatureGate).ResetFeatureValueToDefault(f); err != nil { - tb.Errorf("error restoring %s=%v: %v", f, originalValue, err) + tb.Errorf("error resetting %s: %v", f, err) } } }) } +// hasDisabledDependency recursively walks the dependencies for feature f, and checks whether any are explicitly disabled in the features map. +func hasDisabledDependency(f featuregate.Feature, dependencies map[featuregate.Feature][]featuregate.Feature, features map[featuregate.Feature]bool) (bool, featuregate.Feature) { + if enabled, set := features[f]; set { + return !enabled, f + } + for _, dep := range dependencies[f] { + if disabled, disabledDep := hasDisabledDependency(dep, dependencies, features); disabled { + return disabled, disabledDep + } + } + return false, "" +} + func suggestChangeEmulationVersion(tb TB, gate featuregate.FeatureGate, f featuregate.Feature, value bool) string { mutableVersionedFeatureGate, ok := gate.(featuregate.MutableVersionedFeatureGate) if !ok { @@ -191,6 +262,7 @@ func sameTestOrSubtest(tb TB, testName string) bool { type TB interface { Cleanup(func()) + Logf(format string, args ...any) Error(args ...any) Errorf(format string, args ...any) Fatal(args ...any) diff --git a/staging/src/k8s.io/component-base/featuregate/testing/feature_gate_test.go b/staging/src/k8s.io/component-base/featuregate/testing/feature_gate_test.go index 376d721341c..785275b262d 100644 --- a/staging/src/k8s.io/component-base/featuregate/testing/feature_gate_test.go +++ b/staging/src/k8s.io/component-base/featuregate/testing/feature_gate_test.go @@ -17,6 +17,7 @@ limitations under the License. package testing import ( + "maps" gotest "testing" "github.com/stretchr/testify/assert" @@ -159,6 +160,134 @@ func TestSetFeatureGateInTest(t *gotest.T) { assert.True(t, gate.Enabled("feature")) } +func TestSetFeatureGatesInTestWithDependencies(t *gotest.T) { + const ( + alphaFeature = "AlphaFeature" + alphaFeatureDep = "AlphaFeatureDep" + betaOffFeature = "BetaOffFeature" + betaOffFeatureDep = "BetaOffFeatureDep" + betaOnFeature = "BetaOnFeature" + betaOnFeatureDep = "BetaOnFeatureDep" + gaFeature = "GAFeature" + ) + gate := featuregate.NewFeatureGate() + require.NoError(t, gate.Add(map[featuregate.Feature]featuregate.FeatureSpec{ + alphaFeature: {PreRelease: featuregate.Alpha, Default: false}, + alphaFeatureDep: {PreRelease: featuregate.Alpha, Default: false}, + betaOffFeature: {PreRelease: featuregate.Beta, Default: false}, + betaOffFeatureDep: {PreRelease: featuregate.Beta, Default: false}, + betaOnFeature: {PreRelease: featuregate.Beta, Default: true}, + betaOnFeatureDep: {PreRelease: featuregate.Beta, Default: true}, + gaFeature: {PreRelease: featuregate.GA, Default: true}, + })) + require.NoError(t, gate.AddDependencies(map[featuregate.Feature][]featuregate.Feature{ + alphaFeature: {betaOnFeatureDep, betaOffFeatureDep, alphaFeatureDep}, + betaOffFeature: {betaOnFeatureDep, betaOffFeatureDep}, + betaOnFeature: {betaOnFeatureDep}, + gaFeature: {}, + })) + + initialState := map[featuregate.Feature]bool{ + "AllAlpha": false, + "AllBeta": false, + + alphaFeature: false, + alphaFeatureDep: false, + betaOffFeature: false, + betaOffFeatureDep: false, + betaOnFeature: true, + betaOnFeatureDep: true, + gaFeature: true, + } + expect(t, gate, initialState) + + tests := []struct { + name string + overrides FeatureOverrides + expectedOverrides FeatureOverrides + expectError bool + }{{ + name: "AllBeta", + overrides: FeatureOverrides{"AllBeta": true}, + expectedOverrides: FeatureOverrides{ + "AllBeta": true, + betaOffFeature: true, + betaOffFeatureDep: true, + }, + }, { + name: "AllBeta=false", + overrides: FeatureOverrides{"AllBeta": false}, + expectedOverrides: FeatureOverrides{ + "AllBeta": false, + betaOnFeature: false, + betaOnFeatureDep: false, + }, + }, { + name: "AllBeta+AllAlpha", + overrides: FeatureOverrides{"AllBeta": true, "AllAlpha": true}, + expectedOverrides: FeatureOverrides{ + "AllAlpha": true, + "AllBeta": true, + alphaFeature: true, + alphaFeatureDep: true, + betaOffFeature: true, + betaOffFeatureDep: true, + }, + }, { + name: "AllAlpha", + overrides: FeatureOverrides{"AllAlpha": true}, + expectError: true, + }, { + name: "Automatically disable deps", + overrides: FeatureOverrides{betaOnFeatureDep: false}, + expectedOverrides: FeatureOverrides{ + betaOnFeature: false, + betaOnFeatureDep: false, + }, + }, { + name: "Don't automatically enable deps", + overrides: FeatureOverrides{betaOffFeatureDep: true}, + expectedOverrides: FeatureOverrides{ + betaOffFeatureDep: true, + betaOffFeature: false, + }, + }, { + name: "Error when disabling dependency", + overrides: FeatureOverrides{ + betaOnFeature: true, // Explicitly enabled so it's not automatically disabled. + betaOnFeatureDep: false, + }, + expectError: true, + }, { + name: "Error when enabling dependent", + overrides: FeatureOverrides{ + betaOffFeature: true, + }, + expectError: true, + }} + + for _, test := range tests { + t.Run(test.name, func(t *gotest.T) { + // Separate inner test so we can verify cleanup in the outer test. + t.Run("Set", func(t *gotest.T) { + if test.expectError { + fakeT := &ignoreErrorT{ignoreFatalT: &ignoreFatalT{T: t}} + SetFeatureGatesDuringTest(fakeT, gate, test.overrides) + require.True(t, fakeT.errorRecorded, "should capture error") + expect(t, gate, initialState) + } else { + SetFeatureGatesDuringTest(t, gate, test.overrides) + expectedState := maps.Clone(initialState) + maps.Copy(expectedState, test.expectedOverrides) + expect(t, gate, expectedState) + } + }) + // Verify revert in cleanup. + expect(t, gate, initialState) + }) + } +} + func TestSpecialGatesVersioned(t *gotest.T) { originalEmulationVersion := version.MustParse("1.31") gate := featuregate.NewVersionedFeatureGate(originalEmulationVersion) @@ -435,7 +564,7 @@ type ignoreFatalT struct { func (f *ignoreFatalT) Fatal(args ...any) { f.T.Helper() f.fatalRecorded = true - newArgs := []any{"[IGNORED]"} + newArgs := []any{"[IGNORED Fatal]"} newArgs = append(newArgs, args...) f.T.Log(newArgs...) } @@ -443,7 +572,26 @@ func (f *ignoreFatalT) Fatal(args ...any) { func (f *ignoreFatalT) Fatalf(format string, args ...any) { f.T.Helper() f.fatalRecorded = true - f.T.Logf("[IGNORED] "+format, args...) + f.T.Logf("[IGNORED Fatalf] "+format, args...) +} + +type ignoreErrorT struct { + *ignoreFatalT + errorRecorded bool +} + +func (f *ignoreErrorT) Error(args ...any) { + f.T.Helper() + f.errorRecorded = true + newArgs := []any{"[IGNORED Error]"} + newArgs = append(newArgs, args...) + f.T.Log(newArgs...) +} + +func (f *ignoreErrorT) Errorf(format string, args ...any) { + f.T.Helper() + f.errorRecorded = true + f.T.Logf("[IGNORED Errorf] "+format, args...) } func cleanup() { diff --git a/test/integration/apiserver/apiserver_test.go b/test/integration/apiserver/apiserver_test.go index af99be760b5..a934ee82666 100644 --- a/test/integration/apiserver/apiserver_test.go +++ b/test/integration/apiserver/apiserver_test.go @@ -1705,8 +1705,10 @@ func TestGetScaleSubresourceAsTableForAllBuiltins(t *testing.T) { // Enable all features and apis for testing flags := framework.DefaultTestServerFlags() flags = append(flags, "--runtime-config=api/all=true") - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, "AllAlpha", true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, "AllBeta", true) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + "AllAlpha": true, + "AllBeta": true, + }) testNamespace := "test-scale" server := kubeapiservertesting.StartTestServerOrDie(t, nil, flags, framework.SharedEtcd()) @@ -3669,8 +3671,10 @@ func assertManagedFields(t *testing.T, obj *unstructured.Unstructured) { // TestDefaultStorageEncoding verifies that the storage encoding for all built-in resources is // Protobuf. func TestDefaultStorageEncoding(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, "AllAlpha", true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, "AllBeta", true) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + "AllAlpha": true, + "AllBeta": true, + }) protobufRecognizer := protobuf.NewSerializer(runtime.NewScheme(), runtime.NewScheme()) var recognizersByGroup map[string]recognizer.RecognizingDecoder diff --git a/test/integration/apiserver/peerproxy/peer_proxy_test.go b/test/integration/apiserver/peerproxy/peer_proxy_test.go index 522ed49d66e..608b1470d74 100644 --- a/test/integration/apiserver/peerproxy/peer_proxy_test.go +++ b/test/integration/apiserver/peerproxy/peer_proxy_test.go @@ -56,8 +56,10 @@ func TestPeerProxiedRequest(t *testing.T) { transport.DialerStopCh = ctx.Done() // enable feature flags - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.APIServerIdentity, true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, kubefeatures.UnknownVersionInteroperabilityProxy, true) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.APIServerIdentity: true, + kubefeatures.UnknownVersionInteroperabilityProxy: true, + }) // create sharedetcd etcd := framework.SharedEtcd() @@ -117,8 +119,10 @@ func TestPeerProxiedRequestToThirdServerAfterFirstDies(t *testing.T) { transport.DialerStopCh = ctx.Done() // enable feature flags - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.APIServerIdentity, true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, kubefeatures.UnknownVersionInteroperabilityProxy, true) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.APIServerIdentity: true, + kubefeatures.UnknownVersionInteroperabilityProxy: true, + }) // create sharedetcd etcd := framework.SharedEtcd() diff --git a/test/integration/auth/podsecurity_test.go b/test/integration/auth/podsecurity_test.go index a3b0d3ee987..384788ecd7f 100644 --- a/test/integration/auth/podsecurity_test.go +++ b/test/integration/auth/podsecurity_test.go @@ -52,8 +52,10 @@ import ( func TestPodSecurity(t *testing.T) { // Enable all feature gates needed to allow all fields to be exercised - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ProcMountType, true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.UserNamespacesSupport, true) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.ProcMountType: true, + features.UserNamespacesSupport: true, + }) // Start server server := startPodSecurityServer(t) opts := podsecuritytest.Options{ @@ -98,8 +100,10 @@ func TestPodSecurityGAOnly(t *testing.T) { func TestPodSecurityWebhook(t *testing.T) { // Enable all feature gates needed to allow all fields to be exercised - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ProcMountType, true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.UserNamespacesSupport, true) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.ProcMountType: true, + features.UserNamespacesSupport: true, + }) // Start test API server. capabilities.ResetForTest() diff --git a/test/integration/client/metrics/metrics_test.go b/test/integration/client/metrics/metrics_test.go index e8f7fec02f2..41b0539e587 100644 --- a/test/integration/client/metrics/metrics_test.go +++ b/test/integration/client/metrics/metrics_test.go @@ -44,8 +44,10 @@ import ( // regression test for https://issues.k8s.io/117258 func TestAPIServerTransportMetrics(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, "AllAlpha", true) - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, "AllBeta", true) + featuregatetesting.SetFeatureGatesDuringTest(t, feature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + "AllAlpha": true, + "AllBeta": true, + }) // reset default registry metrics legacyregistry.Reset() diff --git a/test/integration/controlplane/transformation/kms_transformation_test.go b/test/integration/controlplane/transformation/kms_transformation_test.go index 72634e55359..8f7c4074986 100644 --- a/test/integration/controlplane/transformation/kms_transformation_test.go +++ b/test/integration/controlplane/transformation/kms_transformation_test.go @@ -623,8 +623,10 @@ resources: t.Run("encrypt all resources", func(t *testing.T) { _ = mock.NewBase64Plugin(t, "@encrypt-all-kms-provider.sock") // To ensure we are checking all REST resources - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, "AllAlpha", true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, "AllBeta", true) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + "AllAlpha": true, + "AllBeta": true, + }) // Need to enable this explicitly as the feature is deprecated featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.KMSv1, true) diff --git a/test/integration/dra/dra_test.go b/test/integration/dra/dra_test.go index ec1b1e32b2b..0a4c3485820 100644 --- a/test/integration/dra/dra_test.go +++ b/test/integration/dra/dra_test.go @@ -337,9 +337,7 @@ func TestDRA(t *testing.T) { sort.Strings(entries) t.Logf("Config: %s", strings.Join(entries, ",")) - for key, value := range tc.features { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, key, value) - } + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, tc.features) etcdOptions := framework.SharedEtcd() apiServerOptions := kubeapiservertesting.NewDefaultTestServerOptions() diff --git a/test/integration/etcd/etcd_storage_path_test.go b/test/integration/etcd/etcd_storage_path_test.go index 4ebfca81325..9ad3b02f449 100644 --- a/test/integration/etcd/etcd_storage_path_test.go +++ b/test/integration/etcd/etcd_storage_path_test.go @@ -88,8 +88,10 @@ func TestEtcdStoragePath(t *testing.T) { func testEtcdStoragePathWithVersion(t *testing.T, v string) { if v == componentbaseversion.DefaultKubeBinaryVersion { - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, "AllAlpha", true) - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, "AllBeta", true) + featuregatetesting.SetFeatureGatesDuringTest(t, feature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + "AllAlpha": true, + "AllBeta": true, + }) } else { // Only test for beta and GA APIs with emulated version. featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, feature.DefaultFeatureGate, version.MustParse(v)) diff --git a/test/integration/job/job_test.go b/test/integration/job/job_test.go index 8e8e2aa9ef4..d855c925e1c 100644 --- a/test/integration/job/job_test.go +++ b/test/integration/job/job_test.go @@ -830,8 +830,10 @@ func TestSuccessPolicy(t *testing.T) { // TODO: this will be removed in 1.36 featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, feature.DefaultFeatureGate, utilversion.MustParse("1.32")) } - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.JobSuccessPolicy, tc.enableJobSuccessPolicy) - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.JobBackoffLimitPerIndex, tc.enableBackoffLimitPerIndex) + featuregatetesting.SetFeatureGatesDuringTest(t, feature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.JobSuccessPolicy: tc.enableJobSuccessPolicy, + features.JobBackoffLimitPerIndex: tc.enableBackoffLimitPerIndex, + }) ctx, cancel := startJobControllerAndWaitForCaches(t, restConfig) t.Cleanup(cancel) @@ -1592,9 +1594,11 @@ func TestDelayTerminalPhaseCondition(t *testing.T) { // TODO: this will be removed in 1.37. featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, feature.DefaultFeatureGate, utilversion.MustParse("1.33")) } - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.JobPodReplacementPolicy, test.enableJobPodReplacementPolicy) - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.JobManagedBy, test.enableJobManagedBy) - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.JobSuccessPolicy, test.enableJobSuccessPolicy) + featuregatetesting.SetFeatureGatesDuringTest(t, feature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.JobPodReplacementPolicy: test.enableJobPodReplacementPolicy, + features.JobManagedBy: test.enableJobManagedBy, + features.JobSuccessPolicy: test.enableJobSuccessPolicy, + }) ctx, cancel := startJobControllerAndWaitForCaches(t, restConfig) t.Cleanup(cancel) diff --git a/test/integration/scheduler/preemption/misc/miscpreemption_test.go b/test/integration/scheduler/preemption/misc/miscpreemption_test.go index 4ef96bee7f9..ed6df6d11e0 100644 --- a/test/integration/scheduler/preemption/misc/miscpreemption_test.go +++ b/test/integration/scheduler/preemption/misc/miscpreemption_test.go @@ -401,8 +401,10 @@ func TestPreemptionStarvation(t *testing.T) { for _, clearingNominatedNodeNameAfterBinding := range []bool{true, false} { for _, test := range tests { t.Run(fmt.Sprintf("%s (Async preemption enabled: %v, ClearingNominatedNodeNameAfterBinding: %v)", test.name, asyncPreemptionEnabled, clearingNominatedNodeNameAfterBinding), func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SchedulerAsyncPreemption, asyncPreemptionEnabled) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ClearingNominatedNodeNameAfterBinding, clearingNominatedNodeNameAfterBinding) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.SchedulerAsyncPreemption: asyncPreemptionEnabled, + features.ClearingNominatedNodeNameAfterBinding: clearingNominatedNodeNameAfterBinding, + }) pendingPods := make([]*v1.Pod, test.numExpectedPending) numRunningPods := test.numExistingPod - test.numExpectedPending @@ -513,8 +515,10 @@ func TestPreemptionRaces(t *testing.T) { for _, clearingNominatedNodeNameAfterBinding := range []bool{true, false} { for _, test := range tests { t.Run(fmt.Sprintf("%s (Async preemption enabled: %v, ClearingNominatedNodeNameAfterBinding: %v)", test.name, asyncPreemptionEnabled, clearingNominatedNodeNameAfterBinding), func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SchedulerAsyncPreemption, asyncPreemptionEnabled) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ClearingNominatedNodeNameAfterBinding, clearingNominatedNodeNameAfterBinding) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.SchedulerAsyncPreemption: asyncPreemptionEnabled, + features.ClearingNominatedNodeNameAfterBinding: clearingNominatedNodeNameAfterBinding, + }) if test.numRepetitions <= 0 { test.numRepetitions = 1 @@ -799,8 +803,10 @@ func TestPDBInPreemption(t *testing.T) { for _, clearingNominatedNodeNameAfterBinding := range []bool{true, false} { for _, test := range tests { t.Run(fmt.Sprintf("%s (Async preemption enabled: %v, ClearingNominatedNodeNameAfterBinding: %v)", test.name, asyncPreemptionEnabled, clearingNominatedNodeNameAfterBinding), func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SchedulerAsyncPreemption, asyncPreemptionEnabled) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ClearingNominatedNodeNameAfterBinding, clearingNominatedNodeNameAfterBinding) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.SchedulerAsyncPreemption: asyncPreemptionEnabled, + features.ClearingNominatedNodeNameAfterBinding: clearingNominatedNodeNameAfterBinding, + }) for i := 1; i <= test.nodeCnt; i++ { nodeName := fmt.Sprintf("node-%v", i) @@ -1184,8 +1190,10 @@ func TestReadWriteOncePodPreemption(t *testing.T) { for _, clearingNominatedNodeNameAfterBinding := range []bool{true, false} { for _, test := range tests { t.Run(fmt.Sprintf("%s (Async preemption enabled: %v, ClearingNominatedNodeNameAfterBinding: %v)", test.name, asyncPreemptionEnabled, clearingNominatedNodeNameAfterBinding), func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SchedulerAsyncPreemption, asyncPreemptionEnabled) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ClearingNominatedNodeNameAfterBinding, clearingNominatedNodeNameAfterBinding) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.SchedulerAsyncPreemption: asyncPreemptionEnabled, + features.ClearingNominatedNodeNameAfterBinding: clearingNominatedNodeNameAfterBinding, + }) if err := test.init(); err != nil { t.Fatalf("Error while initializing test: %v", err) diff --git a/test/integration/scheduler/preemption/nominatednodename/nominatednodename_test.go b/test/integration/scheduler/preemption/nominatednodename/nominatednodename_test.go index 9220f7b5ee6..58566544c35 100644 --- a/test/integration/scheduler/preemption/nominatednodename/nominatednodename_test.go +++ b/test/integration/scheduler/preemption/nominatednodename/nominatednodename_test.go @@ -235,9 +235,11 @@ func TestNominatedNode(t *testing.T) { for _, nominatedNodeNameForExpectationEnabled := range []bool{false} { for _, tt := range tests { t.Run(fmt.Sprintf("%s (Async preemption: %v, Async API calls: %v, NNN for expectation: %v)", tt.name, asyncPreemptionEnabled, asyncAPICallsEnabled, nominatedNodeNameForExpectationEnabled), func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SchedulerAsyncPreemption, asyncPreemptionEnabled) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SchedulerAsyncAPICalls, asyncAPICallsEnabled) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.NominatedNodeNameForExpectation, nominatedNodeNameForExpectationEnabled) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.SchedulerAsyncPreemption: asyncPreemptionEnabled, + features.SchedulerAsyncAPICalls: asyncAPICallsEnabled, + features.NominatedNodeNameForExpectation: nominatedNodeNameForExpectationEnabled, + }) cfg := configtesting.V1ToInternalWithDefaults(t, configv1.KubeSchedulerConfiguration{ Profiles: []configv1.KubeSchedulerProfile{{ diff --git a/test/integration/scheduler/preemption/preemption_test.go b/test/integration/scheduler/preemption/preemption_test.go index 3e69626ba75..e9c8b5da76b 100644 --- a/test/integration/scheduler/preemption/preemption_test.go +++ b/test/integration/scheduler/preemption/preemption_test.go @@ -408,9 +408,11 @@ func TestPreemption(t *testing.T) { for _, clearingNominatedNodeNameAfterBinding := range []bool{true, false} { for _, test := range tests { t.Run(fmt.Sprintf("%s (Async preemption enabled: %v, Async API calls enabled: %v, ClearingNominatedNodeNameAfterBinding: %v)", test.name, asyncPreemptionEnabled, asyncAPICallsEnabled, clearingNominatedNodeNameAfterBinding), func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SchedulerAsyncPreemption, asyncPreemptionEnabled) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SchedulerAsyncAPICalls, asyncAPICallsEnabled) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ClearingNominatedNodeNameAfterBinding, clearingNominatedNodeNameAfterBinding) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.SchedulerAsyncPreemption: asyncPreemptionEnabled, + features.SchedulerAsyncAPICalls: asyncAPICallsEnabled, + features.ClearingNominatedNodeNameAfterBinding: clearingNominatedNodeNameAfterBinding, + }) testCtx := testutils.InitTestSchedulerWithOptions(t, testutils.InitTestAPIServer(t, "preemption", nil), diff --git a/test/integration/scheduler/serving/endpoints_test.go b/test/integration/scheduler/serving/endpoints_test.go index 758511813a9..a8e4b3d43e4 100644 --- a/test/integration/scheduler/serving/endpoints_test.go +++ b/test/integration/scheduler/serving/endpoints_test.go @@ -39,8 +39,10 @@ import ( ) func TestEndpointHandlers(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ComponentFlagz, true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ComponentStatusz, true) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.ComponentFlagz: true, + features.ComponentStatusz: true, + }) server, configStr, _, err := startTestAPIServer(t) if err != nil { diff --git a/test/integration/scheduler_perf/dra/dra_test.go b/test/integration/scheduler_perf/dra/dra_test.go index 06a420480bd..2ca40591565 100644 --- a/test/integration/scheduler_perf/dra/dra_test.go +++ b/test/integration/scheduler_perf/dra/dra_test.go @@ -58,8 +58,10 @@ func TestSchedulerPerf(t *testing.T) { // - "ga-only": keep disabling optional features // - "default": don't change features if allocatorName == "stable" { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRAAdminAccess, false) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRAPrioritizedList, false) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.DRAAdminAccess: false, + features.DRAPrioritizedList: false, + }) } perf.RunIntegrationPerfScheduling(t, "performance-config.yaml") diff --git a/test/integration/service/service_test.go b/test/integration/service/service_test.go index 04b11f9f7ee..3d50f8d4a7e 100644 --- a/test/integration/service/service_test.go +++ b/test/integration/service/service_test.go @@ -559,8 +559,10 @@ func Test_TransitionsForPreferSameTrafficDistribution(t *testing.T) { // Setup components, like kube-apiserver and EndpointSlice controller. //////////////////////////////////////////////////////////////////////////// - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ServiceTrafficDistribution, true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PreferSameTrafficDistribution, true) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.ServiceTrafficDistribution: true, + features.PreferSameTrafficDistribution: true, + }) // Disable ServiceAccount admission plugin as we don't have serviceaccount controller running. server := kubeapiservertesting.StartTestServerOrDie(t, nil, framework.DefaultTestServerFlags(), framework.SharedEtcd()) diff --git a/test/integration/storageversion/gc_test.go b/test/integration/storageversion/gc_test.go index 21bb1082c3c..1c73edc5d22 100644 --- a/test/integration/storageversion/gc_test.go +++ b/test/integration/storageversion/gc_test.go @@ -49,8 +49,10 @@ const ( ) func TestStorageVersionGarbageCollection(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.APIServerIdentity, true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StorageVersionAPI, true) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.APIServerIdentity: true, + features.StorageVersionAPI: true, + }) flags := framework.DefaultTestServerFlags() flags = append(flags, fmt.Sprintf("--runtime-config=%s=true", apiserverinternalv1alpha1.SchemeGroupVersion)) result := kubeapiservertesting.StartTestServerOrDie(t, nil, flags, framework.SharedEtcd()) diff --git a/test/integration/storageversion/storage_version_filter_test.go b/test/integration/storageversion/storage_version_filter_test.go index 5e41929cf7b..8599b0b05a7 100644 --- a/test/integration/storageversion/storage_version_filter_test.go +++ b/test/integration/storageversion/storage_version_filter_test.go @@ -168,8 +168,10 @@ func TestStorageVersionBootstrap(t *testing.T) { } } // Restart api server, enable the storage version API and the feature gates. - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StorageVersionAPI, true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.APIServerIdentity, true) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.StorageVersionAPI: true, + features.APIServerIdentity: true, + }) server = kubeapiservertesting.StartTestServerOrDie(t, &kubeapiservertesting.TestServerInstanceOptions{ StorageVersionWrapFunc: wrapperFunc, diff --git a/test/integration/storageversionmigrator/storageversionmigrator_test.go b/test/integration/storageversionmigrator/storageversionmigrator_test.go index 4f9fbb439b8..12b4781b137 100644 --- a/test/integration/storageversionmigrator/storageversionmigrator_test.go +++ b/test/integration/storageversionmigrator/storageversionmigrator_test.go @@ -52,8 +52,10 @@ import ( // 7. Perform another Storage Version Migration for secrets // 8. Verify that the resource version of the secret is not updated. i.e. it was a no-op update func TestStorageVersionMigration(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StorageVersionMigrator, true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, featuregate.Feature(clientgofeaturegate.InformerResourceVersion), true) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.StorageVersionMigrator: true, + featuregate.Feature(clientgofeaturegate.InformerResourceVersion): true, + }) // this makes the test super responsive. It's set to a default of 1 minute. encryptionconfigcontroller.EncryptionConfigFileChangePollDuration = time.Second @@ -152,8 +154,10 @@ func TestStorageVersionMigration(t *testing.T) { // 10. Verify RV and Generations of CRs // 11. Verify the list of CRs at v2 works func TestStorageVersionMigrationWithCRD(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StorageVersionMigrator, true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, featuregate.Feature(clientgofeaturegate.InformerResourceVersion), true) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.StorageVersionMigrator: true, + featuregate.Feature(clientgofeaturegate.InformerResourceVersion): true, + }) // decode errors are expected when using conversation webhooks etcd3watcher.TestOnlySetFatalOnDecodeError(false) t.Cleanup(func() { etcd3watcher.TestOnlySetFatalOnDecodeError(true) }) @@ -300,8 +304,10 @@ func TestStorageVersionMigrationWithCRD(t *testing.T) { // It asserts that all migrations are successful and that none of the static instances // were changed after they were initially created (as the migrations must be a no-op). func TestStorageVersionMigrationDuringChaos(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StorageVersionMigrator, true) - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, featuregate.Feature(clientgofeaturegate.InformerResourceVersion), true) + featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ + features.StorageVersionMigrator: true, + featuregate.Feature(clientgofeaturegate.InformerResourceVersion): true, + }) ctx := ktesting.Init(t)