diff --git a/pkg/apis/core/validation/validation_test.go b/pkg/apis/core/validation/validation_test.go index d4f228935c..93eb14cd26 100644 --- a/pkg/apis/core/validation/validation_test.go +++ b/pkg/apis/core/validation/validation_test.go @@ -550,29 +550,31 @@ func TestValidateLocalVolumesDisabled(t *testing.T) { }, } - utilfeature.DefaultFeatureGate.Set("PersistentLocalVolumes=false") for name, scenario := range scenarios { - errs := ValidatePersistentVolume(scenario.volume) - if len(errs) == 0 && scenario.isExpectedFailure { - t.Errorf("Unexpected success for scenario: %s", name) - } - if len(errs) > 0 && !scenario.isExpectedFailure { - t.Errorf("Unexpected failure for scenario: %s - %+v", name, errs) - } + t.Run(name+" PersistentLocalVolumes disabled", func(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PersistentLocalVolumes, false)() + errs := ValidatePersistentVolume(scenario.volume) + if len(errs) == 0 && scenario.isExpectedFailure { + t.Errorf("Unexpected success for scenario: %s", name) + } + if len(errs) > 0 && !scenario.isExpectedFailure { + t.Errorf("Unexpected failure for scenario: %s - %+v", name, errs) + } + }) } - utilfeature.DefaultFeatureGate.Set("PersistentLocalVolumes=true") - utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false") for name, scenario := range scenarios { - errs := ValidatePersistentVolume(scenario.volume) - if len(errs) == 0 && scenario.isExpectedFailure { - t.Errorf("Unexpected success for scenario: %s", name) - } - if len(errs) > 0 && !scenario.isExpectedFailure { - t.Errorf("Unexpected failure for scenario: %s - %+v", name, errs) - } + t.Run(name+" VolumeScheduling disabled", func(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, false)() + errs := ValidatePersistentVolume(scenario.volume) + if len(errs) == 0 && scenario.isExpectedFailure { + t.Errorf("Unexpected success for scenario: %s", name) + } + if len(errs) > 0 && !scenario.isExpectedFailure { + t.Errorf("Unexpected failure for scenario: %s - %+v", name, errs) + } + }) } - utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true") } func testVolumeWithNodeAffinity(affinity *core.VolumeNodeAffinity) *core.PersistentVolume { @@ -1911,11 +1913,7 @@ func TestValidateCSIVolumeSource(t *testing.T) { }, } - err := utilfeature.DefaultFeatureGate.Set("CSIPersistentVolume=true") - if err != nil { - t.Errorf("Failed to enable feature gate for CSIPersistentVolumes: %v", err) - return - } + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIPersistentVolume, true)() for i, tc := range testCases { errs := validateCSIPersistentVolumeSource(tc.csi, field.NewPath("field")) @@ -1932,11 +1930,6 @@ func TestValidateCSIVolumeSource(t *testing.T) { } } } - err = utilfeature.DefaultFeatureGate.Set("CSIPersistentVolume=false") - if err != nil { - t.Errorf("Failed to disable feature gate for CSIPersistentVolumes: %v", err) - return - } } // This test is a little too top-to-bottom. Ideally we would test each volume @@ -3750,20 +3743,14 @@ func TestValidateVolumes(t *testing.T) { // Validate HugePages medium type for EmptyDir when HugePages feature is enabled/disabled hugePagesCase := core.VolumeSource{EmptyDir: &core.EmptyDirVolumeSource{Medium: core.StorageMediumHugePages}} - // Enable alpha feature HugePages - err := utilfeature.DefaultFeatureGate.Set("HugePages=true") - if err != nil { - t.Errorf("Failed to enable feature gate for HugePages: %v", err) - } + // Enable HugePages + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HugePages, true)() if errs := validateVolumeSource(&hugePagesCase, field.NewPath("field").Index(0), "working"); len(errs) != 0 { t.Errorf("Unexpected error when HugePages feature is enabled.") } - // Disable alpha feature HugePages - err = utilfeature.DefaultFeatureGate.Set("HugePages=false") - if err != nil { - t.Errorf("Failed to disable feature gate for HugePages: %v", err) - } + // Disable feature HugePages + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HugePages, false)() if errs := validateVolumeSource(&hugePagesCase, field.NewPath("field").Index(0), "failing"); len(errs) == 0 { t.Errorf("Expected error when HugePages feature is disabled got nothing.") } @@ -3868,12 +3855,8 @@ func TestAlphaHugePagesIsolation(t *testing.T) { }, }, } - // Enable alpha feature HugePages - err := utilfeature.DefaultFeatureGate.Set("HugePages=true") - if err != nil { - t.Errorf("Failed to enable feature gate for HugePages: %v", err) - return - } + // Enable feature HugePages + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HugePages, true)() for i := range successCases { pod := &successCases[i] if errs := ValidatePod(pod); len(errs) != 0 { @@ -3886,13 +3869,9 @@ func TestAlphaHugePagesIsolation(t *testing.T) { t.Errorf("Expected error for case[%d], pod: %v", i, pod.Name) } } - // Disable alpha feature HugePages - err = utilfeature.DefaultFeatureGate.Set("HugePages=false") - if err != nil { - t.Errorf("Failed to disable feature gate for HugePages: %v", err) - return - } - // Disable alpha feature HugePages and ensure all success cases fail + // Disable feature HugePages + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HugePages, false)() + // Disable feature HugePages and ensure all success cases fail for i := range successCases { pod := &successCases[i] if errs := ValidatePod(pod); len(errs) == 0 { @@ -4053,23 +4032,15 @@ func TestAlphaLocalStorageCapacityIsolation(t *testing.T) { testCases := []core.VolumeSource{ {EmptyDir: &core.EmptyDirVolumeSource{SizeLimit: resource.NewQuantity(int64(5), resource.BinarySI)}}, } - // Enable alpha feature LocalStorageCapacityIsolation - err := utilfeature.DefaultFeatureGate.Set("LocalStorageCapacityIsolation=true") - if err != nil { - t.Errorf("Failed to enable feature gate for LocalStorageCapacityIsolation: %v", err) - return - } + // Enable feature LocalStorageCapacityIsolation + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LocalStorageCapacityIsolation, true)() for _, tc := range testCases { if errs := validateVolumeSource(&tc, field.NewPath("spec"), "tmpvol"); len(errs) != 0 { t.Errorf("expected success: %v", errs) } } - // Disable alpha feature LocalStorageCapacityIsolation - err = utilfeature.DefaultFeatureGate.Set("LocalStorageCapacityIsolation=false") - if err != nil { - t.Errorf("Failed to disable feature gate for LocalStorageCapacityIsolation: %v", err) - return - } + // Disable feature LocalStorageCapacityIsolation + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LocalStorageCapacityIsolation, false)() for _, tc := range testCases { if errs := validateVolumeSource(&tc, field.NewPath("spec"), "tmpvol"); len(errs) == 0 { t.Errorf("expected failure: %v", errs) @@ -4083,21 +4054,13 @@ func TestAlphaLocalStorageCapacityIsolation(t *testing.T) { resource.BinarySI), }, } - // Enable alpha feature LocalStorageCapacityIsolation - err = utilfeature.DefaultFeatureGate.Set("LocalStorageCapacityIsolation=true") - if err != nil { - t.Errorf("Failed to enable feature gate for LocalStorageCapacityIsolation: %v", err) - return - } + // Enable feature LocalStorageCapacityIsolation + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LocalStorageCapacityIsolation, true)() if errs := ValidateResourceRequirements(&containerLimitCase, field.NewPath("resources")); len(errs) != 0 { t.Errorf("expected success: %v", errs) } - // Disable alpha feature LocalStorageCapacityIsolation - err = utilfeature.DefaultFeatureGate.Set("LocalStorageCapacityIsolation=false") - if err != nil { - t.Errorf("Failed to disable feature gate for LocalStorageCapacityIsolation: %v", err) - return - } + // Disable feature LocalStorageCapacityIsolation + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LocalStorageCapacityIsolation, false)() if errs := ValidateResourceRequirements(&containerLimitCase, field.NewPath("resources")); len(errs) == 0 { t.Errorf("expected failure: %v", errs) } @@ -4132,22 +4095,14 @@ func TestValidateResourceQuotaWithAlphaLocalStorageCapacityIsolation(t *testing. Spec: spec, } - // Enable alpha feature LocalStorageCapacityIsolation - err := utilfeature.DefaultFeatureGate.Set("LocalStorageCapacityIsolation=true") - if err != nil { - t.Errorf("Failed to enable feature gate for LocalStorageCapacityIsolation: %v", err) - return - } + // Enable feature LocalStorageCapacityIsolation + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LocalStorageCapacityIsolation, true)() if errs := ValidateResourceQuota(resourceQuota); len(errs) != 0 { t.Errorf("expected success: %v", errs) } - // Disable alpha feature LocalStorageCapacityIsolation - err = utilfeature.DefaultFeatureGate.Set("LocalStorageCapacityIsolation=false") - if err != nil { - t.Errorf("Failed to disable feature gate for LocalStorageCapacityIsolation: %v", err) - return - } + // Disable feature LocalStorageCapacityIsolation + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LocalStorageCapacityIsolation, false)() errs := ValidateResourceQuota(resourceQuota) if len(errs) == 0 { t.Errorf("expected failure for %s", resourceQuota.Name) @@ -4280,24 +4235,16 @@ func TestLocalStorageEnvWithFeatureGate(t *testing.T) { }, }, } - // Enable alpha feature LocalStorageCapacityIsolation - err := utilfeature.DefaultFeatureGate.Set("LocalStorageCapacityIsolation=true") - if err != nil { - t.Errorf("Failed to enable feature gate for LocalStorageCapacityIsolation: %v", err) - return - } + // Enable feature LocalStorageCapacityIsolation + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LocalStorageCapacityIsolation, true)() for _, testCase := range testCases { if errs := validateEnvVarValueFrom(testCase, field.NewPath("field")); len(errs) != 0 { t.Errorf("expected success, got: %v", errs) } } - // Disable alpha feature LocalStorageCapacityIsolation - err = utilfeature.DefaultFeatureGate.Set("LocalStorageCapacityIsolation=false") - if err != nil { - t.Errorf("Failed to disable feature gate for LocalStorageCapacityIsolation: %v", err) - return - } + // Disable feature LocalStorageCapacityIsolation + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LocalStorageCapacityIsolation, false)() for _, testCase := range testCases { if errs := validateEnvVarValueFrom(testCase, field.NewPath("field")); len(errs) == 0 { t.Errorf("expected failure for %v", testCase.Name) @@ -11187,13 +11134,8 @@ func TestValidateLimitRangeForLocalStorage(t *testing.T) { }, } - // Enable alpha feature LocalStorageCapacityIsolation - err := utilfeature.DefaultFeatureGate.Set("LocalStorageCapacityIsolation=true") - if err != nil { - t.Errorf("Failed to enable feature gate for LocalStorageCapacityIsolation: %v", err) - return - } - + // Enable feature LocalStorageCapacityIsolation + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LocalStorageCapacityIsolation, true)() for _, testCase := range testCases { limitRange := &core.LimitRange{ObjectMeta: metav1.ObjectMeta{Name: testCase.name, Namespace: "foo"}, Spec: testCase.spec} if errs := ValidateLimitRange(limitRange); len(errs) != 0 { @@ -11201,12 +11143,8 @@ func TestValidateLimitRangeForLocalStorage(t *testing.T) { } } - // Disable alpha feature LocalStorageCapacityIsolation - err = utilfeature.DefaultFeatureGate.Set("LocalStorageCapacityIsolation=false") - if err != nil { - t.Errorf("Failed to disable feature gate for LocalStorageCapacityIsolation: %v", err) - return - } + // Disable feature LocalStorageCapacityIsolation + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LocalStorageCapacityIsolation, false)() for _, testCase := range testCases { limitRange := &core.LimitRange{ObjectMeta: metav1.ObjectMeta{Name: testCase.name, Namespace: "foo"}, Spec: testCase.spec} if errs := ValidateLimitRange(limitRange); len(errs) == 0 { @@ -11746,13 +11684,13 @@ func TestValidateResourceQuota(t *testing.T) { Spec: nonBestEffortSpec, }, } - utilfeature.DefaultFeatureGate.Set("ResourceQuotaScopeSelectors=true") + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ResourceQuotaScopeSelectors, true)() for _, successCase := range successCases { if errs := ValidateResourceQuota(&successCase); len(errs) != 0 { t.Errorf("expected success: %v", errs) } } - utilfeature.DefaultFeatureGate.Set("ResourceQuotaScopeSelectors=false") + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ResourceQuotaScopeSelectors, false)() errorCases := map[string]struct { R core.ResourceQuota diff --git a/pkg/apis/storage/util/BUILD b/pkg/apis/storage/util/BUILD index 1b3f629507..1b37c7f631 100644 --- a/pkg/apis/storage/util/BUILD +++ b/pkg/apis/storage/util/BUILD @@ -41,6 +41,8 @@ go_test( deps = [ "//pkg/apis/core:go_default_library", "//pkg/apis/storage:go_default_library", + "//pkg/features:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/util/feature/testing:go_default_library", ], ) diff --git a/pkg/apis/storage/util/util_test.go b/pkg/apis/storage/util/util_test.go index 8b62ddfab3..d2cf140210 100644 --- a/pkg/apis/storage/util/util_test.go +++ b/pkg/apis/storage/util/util_test.go @@ -21,8 +21,10 @@ import ( "testing" utilfeature "k8s.io/apiserver/pkg/util/feature" + utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing" api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/apis/storage" + "k8s.io/kubernetes/pkg/features" ) func TestDropAlphaFields(t *testing.T) { @@ -39,9 +41,7 @@ func TestDropAlphaFields(t *testing.T) { } // Test that field gets dropped when feature gate is not set - if err := utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false"); err != nil { - t.Fatalf("Failed to set feature gate for VolumeScheduling: %v", err) - } + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, false)() class := &storage.StorageClass{ VolumeBindingMode: &bindingMode, AllowedTopologies: allowedTopologies, @@ -59,9 +59,7 @@ func TestDropAlphaFields(t *testing.T) { VolumeBindingMode: &bindingMode, AllowedTopologies: allowedTopologies, } - if err := utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true"); err != nil { - t.Fatalf("Failed to set feature gate for VolumeScheduling: %v", err) - } + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)() DropDisabledAlphaFields(class) if class.VolumeBindingMode != &bindingMode { t.Errorf("VolumeBindingMode field got unexpectantly modified: %+v", class.VolumeBindingMode) @@ -69,8 +67,4 @@ func TestDropAlphaFields(t *testing.T) { if !reflect.DeepEqual(class.AllowedTopologies, allowedTopologies) { t.Errorf("AllowedTopologies field got unexpectantly modified: %+v", class.AllowedTopologies) } - - if err := utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false"); err != nil { - t.Fatalf("Failed to disable feature gate for VolumeScheduling: %v", err) - } } diff --git a/pkg/apis/storage/validation/validation_test.go b/pkg/apis/storage/validation/validation_test.go index 905469735d..d9940300c9 100644 --- a/pkg/apis/storage/validation/validation_test.go +++ b/pkg/apis/storage/validation/validation_test.go @@ -514,10 +514,7 @@ func TestValidateVolumeBindingModeAlphaDisabled(t *testing.T) { "invalid mode": makeClass(&invalidMode, nil), } - err := utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false") - if err != nil { - t.Fatalf("Failed to enable feature gate for VolumeScheduling: %v", err) - } + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, false)() for testName, storageClass := range errorCases { if errs := ValidateStorageClass(storageClass); len(errs) == 0 { t.Errorf("Expected failure for test: %v", testName) @@ -551,11 +548,7 @@ func TestValidateVolumeBindingMode(t *testing.T) { } // TODO: remove when feature gate not required - err := utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true") - if err != nil { - t.Fatalf("Failed to enable feature gate for VolumeScheduling: %v", err) - } - + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)() for testName, testCase := range cases { errs := ValidateStorageClass(testCase.class) if testCase.shouldSucceed && len(errs) != 0 { @@ -565,11 +558,6 @@ func TestValidateVolumeBindingMode(t *testing.T) { t.Errorf("Expected failure for test %q, got success", testName) } } - - err = utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false") - if err != nil { - t.Fatalf("Failed to disable feature gate for VolumeScheduling: %v", err) - } } type updateTest struct { @@ -618,11 +606,7 @@ func TestValidateUpdateVolumeBindingMode(t *testing.T) { } // TODO: remove when feature gate not required - err := utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true") - if err != nil { - t.Fatalf("Failed to enable feature gate for VolumeScheduling: %v", err) - } - + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)() for testName, testCase := range cases { errs := ValidateStorageClassUpdate(testCase.newClass, testCase.oldClass) if testCase.shouldSucceed && len(errs) != 0 { @@ -632,11 +616,6 @@ func TestValidateUpdateVolumeBindingMode(t *testing.T) { t.Errorf("Expected failure for %v, got success", testName) } } - - err = utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false") - if err != nil { - t.Fatalf("Failed to disable feature gate for VolumeScheduling: %v", err) - } } func TestValidateAllowedTopologies(t *testing.T) { @@ -930,12 +909,7 @@ func TestValidateAllowedTopologies(t *testing.T) { }, } - // TODO: remove when feature gate not required - err := utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true") - if err != nil { - t.Fatalf("Failed to enable feature gate for VolumeScheduling: %v", err) - } - + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)() for testName, testCase := range cases { errs := ValidateStorageClass(testCase.class) if testCase.shouldSucceed && len(errs) != 0 { @@ -946,11 +920,7 @@ func TestValidateAllowedTopologies(t *testing.T) { } } - err = utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false") - if err != nil { - t.Fatalf("Failed to disable feature gate for VolumeScheduling: %v", err) - } - + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, false)() for testName, testCase := range cases { errs := ValidateStorageClass(testCase.class) if len(errs) == 0 && testCase.class.AllowedTopologies != nil { diff --git a/pkg/controller/cloud/BUILD b/pkg/controller/cloud/BUILD index 8999338aa2..65171eaf32 100644 --- a/pkg/controller/cloud/BUILD +++ b/pkg/controller/cloud/BUILD @@ -58,6 +58,7 @@ go_test( "//pkg/cloudprovider/providers/fake:go_default_library", "//pkg/controller:go_default_library", "//pkg/controller/testutil:go_default_library", + "//pkg/features:go_default_library", "//pkg/kubelet/apis:go_default_library", "//pkg/scheduler/api:go_default_library", "//pkg/volume/util:go_default_library", @@ -68,6 +69,7 @@ go_test( "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/util/feature/testing:go_default_library", "//staging/src/k8s.io/client-go/informers:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library", diff --git a/pkg/controller/cloud/pvlcontroller_test.go b/pkg/controller/cloud/pvlcontroller_test.go index e74af89d93..1931540d1e 100644 --- a/pkg/controller/cloud/pvlcontroller_test.go +++ b/pkg/controller/cloud/pvlcontroller_test.go @@ -28,8 +28,10 @@ import ( sets "k8s.io/apimachinery/pkg/util/sets" utilfeature "k8s.io/apiserver/pkg/util/feature" + utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing" "k8s.io/client-go/kubernetes/fake" core "k8s.io/client-go/testing" + "k8s.io/kubernetes/pkg/features" kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis" volumeutil "k8s.io/kubernetes/pkg/volume/util" @@ -449,8 +451,7 @@ func TestCreatePatch(t *testing.T) { }, } - utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true") - defer utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false") + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)() for d, tc := range testCases { cloud := &fakecloud.FakeCloud{} client := fake.NewSimpleClientset() @@ -519,8 +520,7 @@ func TestAddLabelsToVolume(t *testing.T) { }, } - utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true") - defer utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false") + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)() for d, tc := range testCases { labeledCh := make(chan bool, 1) diff --git a/pkg/scheduler/BUILD b/pkg/scheduler/BUILD index 1158a60ad5..b833e399be 100644 --- a/pkg/scheduler/BUILD +++ b/pkg/scheduler/BUILD @@ -45,6 +45,7 @@ go_test( deps = [ "//pkg/api/legacyscheme:go_default_library", "//pkg/controller/volume/persistentvolume:go_default_library", + "//pkg/features:go_default_library", "//pkg/scheduler/algorithm:go_default_library", "//pkg/scheduler/algorithm/predicates:go_default_library", "//pkg/scheduler/api:go_default_library", diff --git a/pkg/scheduler/algorithm/predicates/predicates_test.go b/pkg/scheduler/algorithm/predicates/predicates_test.go index d147ec2d71..5a75290106 100644 --- a/pkg/scheduler/algorithm/predicates/predicates_test.go +++ b/pkg/scheduler/algorithm/predicates/predicates_test.go @@ -30,7 +30,9 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/sets" utilfeature "k8s.io/apiserver/pkg/util/feature" + utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing" v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper" + "k8s.io/kubernetes/pkg/features" kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis" "k8s.io/kubernetes/pkg/scheduler/algorithm" schedulerapi "k8s.io/kubernetes/pkg/scheduler/api" @@ -4913,10 +4915,7 @@ func TestVolumeZonePredicateWithVolumeBinding(t *testing.T) { }, } - err := utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true") - if err != nil { - t.Fatalf("Failed to enable feature gate for VolumeScheduling: %v", err) - } + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)() for _, test := range tests { t.Run(test.name, func(t *testing.T) { @@ -4937,10 +4936,6 @@ func TestVolumeZonePredicateWithVolumeBinding(t *testing.T) { }) } - err = utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false") - if err != nil { - t.Fatalf("Failed to disable feature gate for VolumeScheduling: %v", err) - } } func TestGetMaxVols(t *testing.T) { diff --git a/pkg/scheduler/scheduler_test.go b/pkg/scheduler/scheduler_test.go index b781087bae..8a5c40f4f8 100644 --- a/pkg/scheduler/scheduler_test.go +++ b/pkg/scheduler/scheduler_test.go @@ -40,6 +40,7 @@ import ( "k8s.io/client-go/tools/record" "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/controller/volume/persistentvolume" + "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/scheduler/algorithm" "k8s.io/kubernetes/pkg/scheduler/algorithm/predicates" "k8s.io/kubernetes/pkg/scheduler/api" @@ -774,8 +775,7 @@ func TestSchedulerWithVolumeBinding(t *testing.T) { // This can be small because we wait for pod to finish scheduling first chanTimeout := 2 * time.Second - utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true") - defer utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false") + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)() table := []struct { name string diff --git a/pkg/volume/csi/csi_block_test.go b/pkg/volume/csi/csi_block_test.go index 8bff6b7f85..b19c486755 100644 --- a/pkg/volume/csi/csi_block_test.go +++ b/pkg/volume/csi/csi_block_test.go @@ -25,7 +25,10 @@ import ( api "k8s.io/api/core/v1" meta "k8s.io/apimachinery/pkg/apis/meta/v1" + utilfeature "k8s.io/apiserver/pkg/util/feature" + utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing" fakeclient "k8s.io/client-go/kubernetes/fake" + "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/volume" volumetest "k8s.io/kubernetes/pkg/volume/testing" ) @@ -46,6 +49,8 @@ func prepareBlockMapperTest(plug *csiPlugin, specVolumeName string) (*csiBlockMa } func TestBlockMapperGetGlobalMapPath(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)() + plug, tmpDir := newTestPlugin(t, nil, nil) defer os.RemoveAll(tmpDir) @@ -85,6 +90,8 @@ func TestBlockMapperGetGlobalMapPath(t *testing.T) { } func TestBlockMapperGetStagingPath(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)() + plug, tmpDir := newTestPlugin(t, nil, nil) defer os.RemoveAll(tmpDir) @@ -120,6 +127,8 @@ func TestBlockMapperGetStagingPath(t *testing.T) { } func TestBlockMapperGetPublishPath(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)() + plug, tmpDir := newTestPlugin(t, nil, nil) defer os.RemoveAll(tmpDir) @@ -155,6 +164,8 @@ func TestBlockMapperGetPublishPath(t *testing.T) { } func TestBlockMapperGetDeviceMapPath(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)() + plug, tmpDir := newTestPlugin(t, nil, nil) defer os.RemoveAll(tmpDir) @@ -194,6 +205,8 @@ func TestBlockMapperGetDeviceMapPath(t *testing.T) { } func TestBlockMapperSetupDevice(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)() + plug, tmpDir := newTestPlugin(t, nil, nil) defer os.RemoveAll(tmpDir) fakeClient := fakeclient.NewSimpleClientset() @@ -259,6 +272,8 @@ func TestBlockMapperSetupDevice(t *testing.T) { } func TestBlockMapperMapDevice(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)() + plug, tmpDir := newTestPlugin(t, nil, nil) defer os.RemoveAll(tmpDir) fakeClient := fakeclient.NewSimpleClientset() @@ -340,6 +355,8 @@ func TestBlockMapperMapDevice(t *testing.T) { } func TestBlockMapperTearDownDevice(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)() + plug, tmpDir := newTestPlugin(t, nil, nil) defer os.RemoveAll(tmpDir) fakeClient := fakeclient.NewSimpleClientset() diff --git a/pkg/volume/csi/csi_plugin_test.go b/pkg/volume/csi/csi_plugin_test.go index a4d9e9b404..c2fbafd95a 100644 --- a/pkg/volume/csi/csi_plugin_test.go +++ b/pkg/volume/csi/csi_plugin_test.go @@ -29,6 +29,7 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/wait" utilfeature "k8s.io/apiserver/pkg/util/feature" + utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing" fakeclient "k8s.io/client-go/kubernetes/fake" utiltesting "k8s.io/client-go/util/testing" fakecsi "k8s.io/csi-api/pkg/client/clientset/versioned/fake" @@ -39,11 +40,6 @@ import ( // create a plugin mgr to load plugins and setup a fake client func newTestPlugin(t *testing.T, client *fakeclient.Clientset, csiClient *fakecsi.Clientset) (*csiPlugin, string) { - err := utilfeature.DefaultFeatureGate.Set("CSIBlockVolume=true") - if err != nil { - t.Fatalf("Failed to enable feature gate for CSIBlockVolume: %v", err) - } - tmpDir, err := utiltesting.MkTmpdir("csi-test") if err != nil { t.Fatalf("can't create temp dir: %v", err) @@ -109,6 +105,8 @@ func makeTestPV(name string, sizeGig int, driverName, volID string) *api.Persist } func TestPluginGetPluginName(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)() + plug, tmpDir := newTestPlugin(t, nil, nil) defer os.RemoveAll(tmpDir) if plug.GetPluginName() != "kubernetes.io/csi" { @@ -117,6 +115,8 @@ func TestPluginGetPluginName(t *testing.T) { } func TestPluginGetVolumeName(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)() + plug, tmpDir := newTestPlugin(t, nil, nil) defer os.RemoveAll(tmpDir) testCases := []struct { @@ -146,6 +146,8 @@ func TestPluginGetVolumeName(t *testing.T) { } func TestPluginCanSupport(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)() + plug, tmpDir := newTestPlugin(t, nil, nil) defer os.RemoveAll(tmpDir) @@ -158,6 +160,8 @@ func TestPluginCanSupport(t *testing.T) { } func TestPluginConstructVolumeSpec(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)() + plug, tmpDir := newTestPlugin(t, nil, nil) defer os.RemoveAll(tmpDir) @@ -218,6 +222,8 @@ func TestPluginConstructVolumeSpec(t *testing.T) { } func TestPluginNewMounter(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)() + plug, tmpDir := newTestPlugin(t, nil, nil) defer os.RemoveAll(tmpDir) @@ -266,6 +272,8 @@ func TestPluginNewMounter(t *testing.T) { } func TestPluginNewUnmounter(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)() + plug, tmpDir := newTestPlugin(t, nil, nil) defer os.RemoveAll(tmpDir) @@ -311,6 +319,8 @@ func TestPluginNewUnmounter(t *testing.T) { } func TestPluginNewAttacher(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)() + plug, tmpDir := newTestPlugin(t, nil, nil) defer os.RemoveAll(tmpDir) @@ -329,6 +339,8 @@ func TestPluginNewAttacher(t *testing.T) { } func TestPluginNewDetacher(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)() + plug, tmpDir := newTestPlugin(t, nil, nil) defer os.RemoveAll(tmpDir) @@ -347,6 +359,8 @@ func TestPluginNewDetacher(t *testing.T) { } func TestPluginNewBlockMapper(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)() + plug, tmpDir := newTestPlugin(t, nil, nil) defer os.RemoveAll(tmpDir) @@ -392,6 +406,8 @@ func TestPluginNewBlockMapper(t *testing.T) { } func TestPluginNewUnmapper(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)() + plug, tmpDir := newTestPlugin(t, nil, nil) defer os.RemoveAll(tmpDir) @@ -449,6 +465,8 @@ func TestPluginNewUnmapper(t *testing.T) { } func TestPluginConstructBlockVolumeSpec(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)() + plug, tmpDir := newTestPlugin(t, nil, nil) defer os.RemoveAll(tmpDir) diff --git a/plugin/pkg/admission/storage/persistentvolume/label/BUILD b/plugin/pkg/admission/storage/persistentvolume/label/BUILD index 318777c214..d93e3e75c1 100644 --- a/plugin/pkg/admission/storage/persistentvolume/label/BUILD +++ b/plugin/pkg/admission/storage/persistentvolume/label/BUILD @@ -37,6 +37,7 @@ go_test( deps = [ "//pkg/apis/core:go_default_library", "//pkg/cloudprovider/providers/aws:go_default_library", + "//pkg/features:go_default_library", "//pkg/kubelet/apis:go_default_library", "//pkg/volume/util:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", @@ -44,6 +45,7 @@ go_test( "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/util/feature/testing:go_default_library", ], ) diff --git a/plugin/pkg/admission/storage/persistentvolume/label/admission_test.go b/plugin/pkg/admission/storage/persistentvolume/label/admission_test.go index bc462e7410..5b6dc02041 100644 --- a/plugin/pkg/admission/storage/persistentvolume/label/admission_test.go +++ b/plugin/pkg/admission/storage/persistentvolume/label/admission_test.go @@ -28,8 +28,10 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/apiserver/pkg/admission" utilfeature "k8s.io/apiserver/pkg/util/feature" + utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing" api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/cloudprovider/providers/aws" + "k8s.io/kubernetes/pkg/features" kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis" volumeutil "k8s.io/kubernetes/pkg/volume/util" ) @@ -122,8 +124,8 @@ func TestAdmission(t *testing.T) { }, }, } - utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true") - defer utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false") + + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)() // Non-cloud PVs are ignored err := handler.Admit(admission.NewAttributesRecord(&ignoredPV, nil, api.Kind("PersistentVolume").WithVersion("version"), ignoredPV.Namespace, ignoredPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, false, nil)) diff --git a/plugin/pkg/admission/storage/storageobjectinuseprotection/BUILD b/plugin/pkg/admission/storage/storageobjectinuseprotection/BUILD index fda54ef498..712b6555d5 100644 --- a/plugin/pkg/admission/storage/storageobjectinuseprotection/BUILD +++ b/plugin/pkg/admission/storage/storageobjectinuseprotection/BUILD @@ -21,12 +21,14 @@ go_test( embed = [":go_default_library"], deps = [ "//pkg/apis/core:go_default_library", + "//pkg/features:go_default_library", "//pkg/volume/util:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/util/feature/testing:go_default_library", "//vendor/github.com/davecgh/go-spew/spew:go_default_library", ], ) diff --git a/plugin/pkg/admission/storage/storageobjectinuseprotection/admission_test.go b/plugin/pkg/admission/storage/storageobjectinuseprotection/admission_test.go index 757a93749e..54ee9da6ae 100644 --- a/plugin/pkg/admission/storage/storageobjectinuseprotection/admission_test.go +++ b/plugin/pkg/admission/storage/storageobjectinuseprotection/admission_test.go @@ -17,7 +17,6 @@ limitations under the License. package storageobjectinuseprotection import ( - "fmt" "reflect" "testing" @@ -27,8 +26,10 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apiserver/pkg/admission" - "k8s.io/apiserver/pkg/util/feature" + utilfeature "k8s.io/apiserver/pkg/util/feature" + utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing" api "k8s.io/kubernetes/pkg/apis/core" + "k8s.io/kubernetes/pkg/features" volumeutil "k8s.io/kubernetes/pkg/volume/util" ) @@ -118,31 +119,29 @@ func TestAdmit(t *testing.T) { ctrl := newPlugin() for _, test := range tests { - feature.DefaultFeatureGate.Set(fmt.Sprintf("StorageObjectInUseProtection=%v", test.featureEnabled)) - obj := test.object.DeepCopyObject() - attrs := admission.NewAttributesRecord( - obj, // new object - obj.DeepCopyObject(), // old object, copy to be sure it's not modified - schema.GroupVersionKind{}, - test.namespace, - "foo", - test.resource, - "", // subresource - admission.Create, - false, // dryRun - nil, // userInfo - ) + t.Run(test.name, func(t *testing.T) { + defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StorageObjectInUseProtection, test.featureEnabled)() + obj := test.object.DeepCopyObject() + attrs := admission.NewAttributesRecord( + obj, // new object + obj.DeepCopyObject(), // old object, copy to be sure it's not modified + schema.GroupVersionKind{}, + test.namespace, + "foo", + test.resource, + "", // subresource + admission.Create, + false, // dryRun + nil, // userInfo + ) - err := ctrl.Admit(attrs) - if err != nil { - t.Errorf("Test %q: got unexpected error: %v", test.name, err) - } - if !reflect.DeepEqual(test.expectedObject, obj) { - t.Errorf("Test %q: Expected object:\n%s\ngot:\n%s", test.name, spew.Sdump(test.expectedObject), spew.Sdump(obj)) - } + err := ctrl.Admit(attrs) + if err != nil { + t.Errorf("Test %q: got unexpected error: %v", test.name, err) + } + if !reflect.DeepEqual(test.expectedObject, obj) { + t.Errorf("Test %q: Expected object:\n%s\ngot:\n%s", test.name, spew.Sdump(test.expectedObject), spew.Sdump(obj)) + } + }) } - - // Disable the feature for rest of the tests. - // TODO: remove after alpha - feature.DefaultFeatureGate.Set("StorageObjectInUseProtection=false") }