Unverified Commit d0c3cd18 authored by k8s-ci-robot's avatar k8s-ci-robot Committed by GitHub

Merge pull request #71100 from liggitt/feature-gate-testing

ensure feature gate changes don't escape unit tests
parents 7c4d097f 733dd9df
...@@ -32,11 +32,15 @@ filegroup( ...@@ -32,11 +32,15 @@ filegroup(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = ["util_test.go"], srcs = [
"main_test.go",
"util_test.go",
],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/features: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:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature/testing:go_default_library",
], ],
) )
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package persistentvolumeclaim
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -20,6 +20,7 @@ import ( ...@@ -20,6 +20,7 @@ import (
"testing" "testing"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
"k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
) )
...@@ -36,36 +37,24 @@ func TestDropAlphaPVCVolumeMode(t *testing.T) { ...@@ -36,36 +37,24 @@ func TestDropAlphaPVCVolumeMode(t *testing.T) {
} }
// Enable alpha feature BlockVolume // Enable alpha feature BlockVolume
err1 := utilfeature.DefaultFeatureGate.Set("BlockVolume=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
if err1 != nil {
t.Fatalf("Failed to enable feature gate for BlockVolume: %v", err1)
}
// now test dropping the fields - should not be dropped // now test dropping the fields - should not be dropped
DropDisabledAlphaFields(&pvc.Spec) DropDisabledAlphaFields(&pvc.Spec)
// check to make sure VolumeDevices is still present // check to make sure VolumeDevices is still present
// if featureset is set to true // if featureset is set to true
if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) { if pvc.Spec.VolumeMode == nil {
if pvc.Spec.VolumeMode == nil { t.Error("VolumeMode in pvc.Spec should not have been dropped based on feature-gate")
t.Error("VolumeMode in pvc.Spec should not have been dropped based on feature-gate")
}
} }
// Disable alpha feature BlockVolume // Disable alpha feature BlockVolume
err := utilfeature.DefaultFeatureGate.Set("BlockVolume=false") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, false)()
if err != nil {
t.Fatalf("Failed to disable feature gate for BlockVolume: %v", err)
}
// now test dropping the fields // now test dropping the fields
DropDisabledAlphaFields(&pvc.Spec) DropDisabledAlphaFields(&pvc.Spec)
// check to make sure VolumeDevices is nil // check to make sure VolumeDevices is nil
// if featureset is set to false // if featureset is set to false
if !utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) { if pvc.Spec.VolumeMode != nil {
if pvc.Spec.VolumeMode != nil { t.Error("DropDisabledAlphaFields VolumeMode for pvc.Spec failed")
t.Error("DropDisabledAlphaFields VolumeMode for pvc.Spec failed")
}
} }
} }
...@@ -33,7 +33,10 @@ filegroup( ...@@ -33,7 +33,10 @@ filegroup(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = ["util_test.go"], srcs = [
"main_test.go",
"util_test.go",
],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
...@@ -41,5 +44,6 @@ go_test( ...@@ -41,5 +44,6 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature: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",
], ],
) )
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package pod
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -24,6 +24,7 @@ import ( ...@@ -24,6 +24,7 @@ import (
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apimachinery/pkg/util/validation/field"
utilfeature "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" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
) )
...@@ -303,42 +304,32 @@ func TestDropAlphaVolumeDevices(t *testing.T) { ...@@ -303,42 +304,32 @@ func TestDropAlphaVolumeDevices(t *testing.T) {
} }
// Enable alpha feature BlockVolume // Enable alpha feature BlockVolume
err1 := utilfeature.DefaultFeatureGate.Set("BlockVolume=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
if err1 != nil {
t.Fatalf("Failed to enable feature gate for BlockVolume: %v", err1)
}
// now test dropping the fields - should not be dropped // now test dropping the fields - should not be dropped
DropDisabledAlphaFields(&testPod.Spec) DropDisabledAlphaFields(&testPod.Spec)
// check to make sure VolumeDevices is still present // check to make sure VolumeDevices is still present
// if featureset is set to true // if featureset is set to true
if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) { if testPod.Spec.Containers[0].VolumeDevices == nil {
if testPod.Spec.Containers[0].VolumeDevices == nil { t.Error("VolumeDevices in Container should not have been dropped based on feature-gate")
t.Error("VolumeDevices in Container should not have been dropped based on feature-gate") }
} if testPod.Spec.InitContainers[0].VolumeDevices == nil {
if testPod.Spec.InitContainers[0].VolumeDevices == nil { t.Error("VolumeDevices in InitContainers should not have been dropped based on feature-gate")
t.Error("VolumeDevices in InitContainers should not have been dropped based on feature-gate")
}
} }
// Disable alpha feature BlockVolume // Disable alpha feature BlockVolume
err := utilfeature.DefaultFeatureGate.Set("BlockVolume=false") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, false)()
if err != nil {
t.Fatalf("Failed to disable feature gate for BlockVolume: %v", err)
}
// now test dropping the fields // now test dropping the fields
DropDisabledAlphaFields(&testPod.Spec) DropDisabledAlphaFields(&testPod.Spec)
// check to make sure VolumeDevices is nil // check to make sure VolumeDevices is nil
// if featureset is set to false // if featureset is set to false
if !utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) { if testPod.Spec.Containers[0].VolumeDevices != nil {
if testPod.Spec.Containers[0].VolumeDevices != nil { t.Error("DropDisabledAlphaFields for Containers failed")
t.Error("DropDisabledAlphaFields for Containers failed") }
} if testPod.Spec.InitContainers[0].VolumeDevices != nil {
if testPod.Spec.InitContainers[0].VolumeDevices != nil { t.Error("DropDisabledAlphaFields for InitContainers failed")
t.Error("DropDisabledAlphaFields for InitContainers failed")
}
} }
} }
...@@ -32,12 +32,16 @@ filegroup( ...@@ -32,12 +32,16 @@ filegroup(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = ["util_test.go"], srcs = [
"main_test.go",
"util_test.go",
],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/apis/policy:go_default_library", "//pkg/apis/policy:go_default_library",
"//pkg/features: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:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature/testing:go_default_library",
], ],
) )
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package podsecuritypolicy
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -27,7 +27,10 @@ go_library( ...@@ -27,7 +27,10 @@ go_library(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = ["validation_test.go"], srcs = [
"main_test.go",
"validation_test.go",
],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/apis/batch:go_default_library", "//pkg/apis/batch:go_default_library",
...@@ -36,6 +39,7 @@ go_test( ...@@ -36,6 +39,7 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature: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",
], ],
) )
......
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package validation
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -36,6 +36,7 @@ go_test( ...@@ -36,6 +36,7 @@ go_test(
srcs = [ srcs = [
"conversion_test.go", "conversion_test.go",
"defaults_test.go", "defaults_test.go",
"main_test.go",
], ],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
...@@ -44,6 +45,7 @@ go_test( ...@@ -44,6 +45,7 @@ go_test(
"//pkg/apis/apps:go_default_library", "//pkg/apis/apps:go_default_library",
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/apis/core/fuzzer:go_default_library", "//pkg/apis/core/fuzzer:go_default_library",
"//pkg/features:go_default_library",
"//staging/src/k8s.io/api/apps/v1:go_default_library", "//staging/src/k8s.io/api/apps/v1:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/apitesting/fuzzer:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/apitesting/fuzzer:go_default_library",
...@@ -55,6 +57,7 @@ go_test( ...@@ -55,6 +57,7 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature: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/k8s.io/utils/pointer:go_default_library", "//vendor/k8s.io/utils/pointer:go_default_library",
], ],
) )
......
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -47,6 +47,7 @@ go_test( ...@@ -47,6 +47,7 @@ go_test(
name = "go_default_test", name = "go_default_test",
srcs = [ srcs = [
"events_test.go", "events_test.go",
"main_test.go",
"validation_test.go", "validation_test.go",
], ],
embed = [":go_default_library"], embed = [":go_default_library"],
......
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package validation
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -550,29 +550,31 @@ func TestValidateLocalVolumesDisabled(t *testing.T) { ...@@ -550,29 +550,31 @@ func TestValidateLocalVolumesDisabled(t *testing.T) {
}, },
} }
utilfeature.DefaultFeatureGate.Set("PersistentLocalVolumes=false")
for name, scenario := range scenarios { for name, scenario := range scenarios {
errs := ValidatePersistentVolume(scenario.volume) t.Run(name+" PersistentLocalVolumes disabled", func(t *testing.T) {
if len(errs) == 0 && scenario.isExpectedFailure { defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PersistentLocalVolumes, false)()
t.Errorf("Unexpected success for scenario: %s", name) errs := ValidatePersistentVolume(scenario.volume)
} if len(errs) == 0 && scenario.isExpectedFailure {
if len(errs) > 0 && !scenario.isExpectedFailure { t.Errorf("Unexpected success for scenario: %s", name)
t.Errorf("Unexpected failure for scenario: %s - %+v", name, errs) }
} 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 { for name, scenario := range scenarios {
errs := ValidatePersistentVolume(scenario.volume) t.Run(name+" VolumeScheduling disabled", func(t *testing.T) {
if len(errs) == 0 && scenario.isExpectedFailure { defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, false)()
t.Errorf("Unexpected success for scenario: %s", name) errs := ValidatePersistentVolume(scenario.volume)
} if len(errs) == 0 && scenario.isExpectedFailure {
if len(errs) > 0 && !scenario.isExpectedFailure { t.Errorf("Unexpected success for scenario: %s", name)
t.Errorf("Unexpected failure for scenario: %s - %+v", name, errs) }
} 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 { func testVolumeWithNodeAffinity(affinity *core.VolumeNodeAffinity) *core.PersistentVolume {
...@@ -1553,18 +1555,21 @@ func TestValidatePersistentVolumeClaimUpdate(t *testing.T) { ...@@ -1553,18 +1555,21 @@ func TestValidatePersistentVolumeClaimUpdate(t *testing.T) {
} }
for name, scenario := range scenarios { for name, scenario := range scenarios {
// ensure we have a resource version specified for updates t.Run(name, func(t *testing.T) {
togglePVExpandFeature(scenario.enableResize, t) // ensure we have a resource version specified for updates
toggleBlockVolumeFeature(scenario.enableBlock, t) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExpandPersistentVolumes, scenario.enableResize)()
scenario.oldClaim.ResourceVersion = "1"
scenario.newClaim.ResourceVersion = "1" toggleBlockVolumeFeature(scenario.enableBlock, t)
errs := ValidatePersistentVolumeClaimUpdate(scenario.newClaim, scenario.oldClaim) scenario.oldClaim.ResourceVersion = "1"
if len(errs) == 0 && scenario.isExpectedFailure { scenario.newClaim.ResourceVersion = "1"
t.Errorf("Unexpected success for scenario: %s", name) errs := ValidatePersistentVolumeClaimUpdate(scenario.newClaim, scenario.oldClaim)
} if len(errs) == 0 && scenario.isExpectedFailure {
if len(errs) > 0 && !scenario.isExpectedFailure { t.Errorf("Unexpected success for scenario: %s", name)
t.Errorf("Unexpected failure for scenario: %s - %+v", name, errs) }
} if len(errs) > 0 && !scenario.isExpectedFailure {
t.Errorf("Unexpected failure for scenario: %s - %+v", name, errs)
}
})
} }
} }
...@@ -1585,23 +1590,6 @@ func toggleBlockVolumeFeature(toggleFlag bool, t *testing.T) { ...@@ -1585,23 +1590,6 @@ func toggleBlockVolumeFeature(toggleFlag bool, t *testing.T) {
} }
} }
func togglePVExpandFeature(toggleFlag bool, t *testing.T) {
if toggleFlag {
// Enable alpha feature LocalStorageCapacityIsolation
err := utilfeature.DefaultFeatureGate.Set("ExpandPersistentVolumes=true")
if err != nil {
t.Errorf("Failed to enable feature gate for ExpandPersistentVolumes: %v", err)
return
}
} else {
err := utilfeature.DefaultFeatureGate.Set("ExpandPersistentVolumes=false")
if err != nil {
t.Errorf("Failed to disable feature gate for ExpandPersistentVolumes: %v", err)
return
}
}
}
func TestValidateKeyToPath(t *testing.T) { func TestValidateKeyToPath(t *testing.T) {
testCases := []struct { testCases := []struct {
kp core.KeyToPath kp core.KeyToPath
...@@ -1925,11 +1913,7 @@ func TestValidateCSIVolumeSource(t *testing.T) { ...@@ -1925,11 +1913,7 @@ func TestValidateCSIVolumeSource(t *testing.T) {
}, },
} }
err := utilfeature.DefaultFeatureGate.Set("CSIPersistentVolume=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIPersistentVolume, true)()
if err != nil {
t.Errorf("Failed to enable feature gate for CSIPersistentVolumes: %v", err)
return
}
for i, tc := range testCases { for i, tc := range testCases {
errs := validateCSIPersistentVolumeSource(tc.csi, field.NewPath("field")) errs := validateCSIPersistentVolumeSource(tc.csi, field.NewPath("field"))
...@@ -1946,11 +1930,6 @@ func TestValidateCSIVolumeSource(t *testing.T) { ...@@ -1946,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 // This test is a little too top-to-bottom. Ideally we would test each volume
...@@ -3764,20 +3743,14 @@ func TestValidateVolumes(t *testing.T) { ...@@ -3764,20 +3743,14 @@ func TestValidateVolumes(t *testing.T) {
// Validate HugePages medium type for EmptyDir when HugePages feature is enabled/disabled // Validate HugePages medium type for EmptyDir when HugePages feature is enabled/disabled
hugePagesCase := core.VolumeSource{EmptyDir: &core.EmptyDirVolumeSource{Medium: core.StorageMediumHugePages}} hugePagesCase := core.VolumeSource{EmptyDir: &core.EmptyDirVolumeSource{Medium: core.StorageMediumHugePages}}
// Enable alpha feature HugePages // Enable HugePages
err := utilfeature.DefaultFeatureGate.Set("HugePages=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HugePages, true)()
if err != nil {
t.Errorf("Failed to enable feature gate for HugePages: %v", err)
}
if errs := validateVolumeSource(&hugePagesCase, field.NewPath("field").Index(0), "working"); len(errs) != 0 { if errs := validateVolumeSource(&hugePagesCase, field.NewPath("field").Index(0), "working"); len(errs) != 0 {
t.Errorf("Unexpected error when HugePages feature is enabled.") t.Errorf("Unexpected error when HugePages feature is enabled.")
} }
// Disable alpha feature HugePages // Disable feature HugePages
err = utilfeature.DefaultFeatureGate.Set("HugePages=false") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HugePages, false)()
if err != nil {
t.Errorf("Failed to disable feature gate for HugePages: %v", err)
}
if errs := validateVolumeSource(&hugePagesCase, field.NewPath("field").Index(0), "failing"); len(errs) == 0 { if errs := validateVolumeSource(&hugePagesCase, field.NewPath("field").Index(0), "failing"); len(errs) == 0 {
t.Errorf("Expected error when HugePages feature is disabled got nothing.") t.Errorf("Expected error when HugePages feature is disabled got nothing.")
} }
...@@ -3882,12 +3855,8 @@ func TestAlphaHugePagesIsolation(t *testing.T) { ...@@ -3882,12 +3855,8 @@ func TestAlphaHugePagesIsolation(t *testing.T) {
}, },
}, },
} }
// Enable alpha feature HugePages // Enable feature HugePages
err := utilfeature.DefaultFeatureGate.Set("HugePages=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HugePages, true)()
if err != nil {
t.Errorf("Failed to enable feature gate for HugePages: %v", err)
return
}
for i := range successCases { for i := range successCases {
pod := &successCases[i] pod := &successCases[i]
if errs := ValidatePod(pod); len(errs) != 0 { if errs := ValidatePod(pod); len(errs) != 0 {
...@@ -3900,13 +3869,9 @@ func TestAlphaHugePagesIsolation(t *testing.T) { ...@@ -3900,13 +3869,9 @@ func TestAlphaHugePagesIsolation(t *testing.T) {
t.Errorf("Expected error for case[%d], pod: %v", i, pod.Name) t.Errorf("Expected error for case[%d], pod: %v", i, pod.Name)
} }
} }
// Disable alpha feature HugePages // Disable feature HugePages
err = utilfeature.DefaultFeatureGate.Set("HugePages=false") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HugePages, false)()
if err != nil { // Disable feature HugePages and ensure all success cases fail
t.Errorf("Failed to disable feature gate for HugePages: %v", err)
return
}
// Disable alpha feature HugePages and ensure all success cases fail
for i := range successCases { for i := range successCases {
pod := &successCases[i] pod := &successCases[i]
if errs := ValidatePod(pod); len(errs) == 0 { if errs := ValidatePod(pod); len(errs) == 0 {
...@@ -4067,23 +4032,15 @@ func TestAlphaLocalStorageCapacityIsolation(t *testing.T) { ...@@ -4067,23 +4032,15 @@ func TestAlphaLocalStorageCapacityIsolation(t *testing.T) {
testCases := []core.VolumeSource{ testCases := []core.VolumeSource{
{EmptyDir: &core.EmptyDirVolumeSource{SizeLimit: resource.NewQuantity(int64(5), resource.BinarySI)}}, {EmptyDir: &core.EmptyDirVolumeSource{SizeLimit: resource.NewQuantity(int64(5), resource.BinarySI)}},
} }
// Enable alpha feature LocalStorageCapacityIsolation // Enable feature LocalStorageCapacityIsolation
err := utilfeature.DefaultFeatureGate.Set("LocalStorageCapacityIsolation=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LocalStorageCapacityIsolation, true)()
if err != nil {
t.Errorf("Failed to enable feature gate for LocalStorageCapacityIsolation: %v", err)
return
}
for _, tc := range testCases { for _, tc := range testCases {
if errs := validateVolumeSource(&tc, field.NewPath("spec"), "tmpvol"); len(errs) != 0 { if errs := validateVolumeSource(&tc, field.NewPath("spec"), "tmpvol"); len(errs) != 0 {
t.Errorf("expected success: %v", errs) t.Errorf("expected success: %v", errs)
} }
} }
// Disable alpha feature LocalStorageCapacityIsolation // Disable feature LocalStorageCapacityIsolation
err = utilfeature.DefaultFeatureGate.Set("LocalStorageCapacityIsolation=false") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LocalStorageCapacityIsolation, false)()
if err != nil {
t.Errorf("Failed to disable feature gate for LocalStorageCapacityIsolation: %v", err)
return
}
for _, tc := range testCases { for _, tc := range testCases {
if errs := validateVolumeSource(&tc, field.NewPath("spec"), "tmpvol"); len(errs) == 0 { if errs := validateVolumeSource(&tc, field.NewPath("spec"), "tmpvol"); len(errs) == 0 {
t.Errorf("expected failure: %v", errs) t.Errorf("expected failure: %v", errs)
...@@ -4097,21 +4054,13 @@ func TestAlphaLocalStorageCapacityIsolation(t *testing.T) { ...@@ -4097,21 +4054,13 @@ func TestAlphaLocalStorageCapacityIsolation(t *testing.T) {
resource.BinarySI), resource.BinarySI),
}, },
} }
// Enable alpha feature LocalStorageCapacityIsolation // Enable feature LocalStorageCapacityIsolation
err = utilfeature.DefaultFeatureGate.Set("LocalStorageCapacityIsolation=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LocalStorageCapacityIsolation, true)()
if err != nil {
t.Errorf("Failed to enable feature gate for LocalStorageCapacityIsolation: %v", err)
return
}
if errs := ValidateResourceRequirements(&containerLimitCase, field.NewPath("resources")); len(errs) != 0 { if errs := ValidateResourceRequirements(&containerLimitCase, field.NewPath("resources")); len(errs) != 0 {
t.Errorf("expected success: %v", errs) t.Errorf("expected success: %v", errs)
} }
// Disable alpha feature LocalStorageCapacityIsolation // Disable feature LocalStorageCapacityIsolation
err = utilfeature.DefaultFeatureGate.Set("LocalStorageCapacityIsolation=false") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LocalStorageCapacityIsolation, false)()
if err != nil {
t.Errorf("Failed to disable feature gate for LocalStorageCapacityIsolation: %v", err)
return
}
if errs := ValidateResourceRequirements(&containerLimitCase, field.NewPath("resources")); len(errs) == 0 { if errs := ValidateResourceRequirements(&containerLimitCase, field.NewPath("resources")); len(errs) == 0 {
t.Errorf("expected failure: %v", errs) t.Errorf("expected failure: %v", errs)
} }
...@@ -4146,22 +4095,14 @@ func TestValidateResourceQuotaWithAlphaLocalStorageCapacityIsolation(t *testing. ...@@ -4146,22 +4095,14 @@ func TestValidateResourceQuotaWithAlphaLocalStorageCapacityIsolation(t *testing.
Spec: spec, Spec: spec,
} }
// Enable alpha feature LocalStorageCapacityIsolation // Enable feature LocalStorageCapacityIsolation
err := utilfeature.DefaultFeatureGate.Set("LocalStorageCapacityIsolation=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LocalStorageCapacityIsolation, true)()
if err != nil {
t.Errorf("Failed to enable feature gate for LocalStorageCapacityIsolation: %v", err)
return
}
if errs := ValidateResourceQuota(resourceQuota); len(errs) != 0 { if errs := ValidateResourceQuota(resourceQuota); len(errs) != 0 {
t.Errorf("expected success: %v", errs) t.Errorf("expected success: %v", errs)
} }
// Disable alpha feature LocalStorageCapacityIsolation // Disable feature LocalStorageCapacityIsolation
err = utilfeature.DefaultFeatureGate.Set("LocalStorageCapacityIsolation=false") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LocalStorageCapacityIsolation, false)()
if err != nil {
t.Errorf("Failed to disable feature gate for LocalStorageCapacityIsolation: %v", err)
return
}
errs := ValidateResourceQuota(resourceQuota) errs := ValidateResourceQuota(resourceQuota)
if len(errs) == 0 { if len(errs) == 0 {
t.Errorf("expected failure for %s", resourceQuota.Name) t.Errorf("expected failure for %s", resourceQuota.Name)
...@@ -4294,24 +4235,16 @@ func TestLocalStorageEnvWithFeatureGate(t *testing.T) { ...@@ -4294,24 +4235,16 @@ func TestLocalStorageEnvWithFeatureGate(t *testing.T) {
}, },
}, },
} }
// Enable alpha feature LocalStorageCapacityIsolation // Enable feature LocalStorageCapacityIsolation
err := utilfeature.DefaultFeatureGate.Set("LocalStorageCapacityIsolation=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LocalStorageCapacityIsolation, true)()
if err != nil {
t.Errorf("Failed to enable feature gate for LocalStorageCapacityIsolation: %v", err)
return
}
for _, testCase := range testCases { for _, testCase := range testCases {
if errs := validateEnvVarValueFrom(testCase, field.NewPath("field")); len(errs) != 0 { if errs := validateEnvVarValueFrom(testCase, field.NewPath("field")); len(errs) != 0 {
t.Errorf("expected success, got: %v", errs) t.Errorf("expected success, got: %v", errs)
} }
} }
// Disable alpha feature LocalStorageCapacityIsolation // Disable feature LocalStorageCapacityIsolation
err = utilfeature.DefaultFeatureGate.Set("LocalStorageCapacityIsolation=false") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LocalStorageCapacityIsolation, false)()
if err != nil {
t.Errorf("Failed to disable feature gate for LocalStorageCapacityIsolation: %v", err)
return
}
for _, testCase := range testCases { for _, testCase := range testCases {
if errs := validateEnvVarValueFrom(testCase, field.NewPath("field")); len(errs) == 0 { if errs := validateEnvVarValueFrom(testCase, field.NewPath("field")); len(errs) == 0 {
t.Errorf("expected failure for %v", testCase.Name) t.Errorf("expected failure for %v", testCase.Name)
...@@ -11201,13 +11134,8 @@ func TestValidateLimitRangeForLocalStorage(t *testing.T) { ...@@ -11201,13 +11134,8 @@ func TestValidateLimitRangeForLocalStorage(t *testing.T) {
}, },
} }
// Enable alpha feature LocalStorageCapacityIsolation // Enable feature LocalStorageCapacityIsolation
err := utilfeature.DefaultFeatureGate.Set("LocalStorageCapacityIsolation=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LocalStorageCapacityIsolation, true)()
if err != nil {
t.Errorf("Failed to enable feature gate for LocalStorageCapacityIsolation: %v", err)
return
}
for _, testCase := range testCases { for _, testCase := range testCases {
limitRange := &core.LimitRange{ObjectMeta: metav1.ObjectMeta{Name: testCase.name, Namespace: "foo"}, Spec: testCase.spec} limitRange := &core.LimitRange{ObjectMeta: metav1.ObjectMeta{Name: testCase.name, Namespace: "foo"}, Spec: testCase.spec}
if errs := ValidateLimitRange(limitRange); len(errs) != 0 { if errs := ValidateLimitRange(limitRange); len(errs) != 0 {
...@@ -11215,12 +11143,8 @@ func TestValidateLimitRangeForLocalStorage(t *testing.T) { ...@@ -11215,12 +11143,8 @@ func TestValidateLimitRangeForLocalStorage(t *testing.T) {
} }
} }
// Disable alpha feature LocalStorageCapacityIsolation // Disable feature LocalStorageCapacityIsolation
err = utilfeature.DefaultFeatureGate.Set("LocalStorageCapacityIsolation=false") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LocalStorageCapacityIsolation, false)()
if err != nil {
t.Errorf("Failed to disable feature gate for LocalStorageCapacityIsolation: %v", err)
return
}
for _, testCase := range testCases { for _, testCase := range testCases {
limitRange := &core.LimitRange{ObjectMeta: metav1.ObjectMeta{Name: testCase.name, Namespace: "foo"}, Spec: testCase.spec} limitRange := &core.LimitRange{ObjectMeta: metav1.ObjectMeta{Name: testCase.name, Namespace: "foo"}, Spec: testCase.spec}
if errs := ValidateLimitRange(limitRange); len(errs) == 0 { if errs := ValidateLimitRange(limitRange); len(errs) == 0 {
...@@ -11577,17 +11501,20 @@ func TestValidatePersistentVolumeClaimStatusUpdate(t *testing.T) { ...@@ -11577,17 +11501,20 @@ func TestValidatePersistentVolumeClaimStatusUpdate(t *testing.T) {
}, },
} }
for name, scenario := range scenarios { for name, scenario := range scenarios {
// ensure we have a resource version specified for updates t.Run(name, func(t *testing.T) {
togglePVExpandFeature(scenario.enableResize, t) // ensure we have a resource version specified for updates
scenario.oldClaim.ResourceVersion = "1" defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExpandPersistentVolumes, scenario.enableResize)()
scenario.newClaim.ResourceVersion = "1"
errs := ValidatePersistentVolumeClaimStatusUpdate(scenario.newClaim, scenario.oldClaim) scenario.oldClaim.ResourceVersion = "1"
if len(errs) == 0 && scenario.isExpectedFailure { scenario.newClaim.ResourceVersion = "1"
t.Errorf("Unexpected success for scenario: %s", name) errs := ValidatePersistentVolumeClaimStatusUpdate(scenario.newClaim, scenario.oldClaim)
} if len(errs) == 0 && scenario.isExpectedFailure {
if len(errs) > 0 && !scenario.isExpectedFailure { t.Errorf("Unexpected success for scenario: %s", name)
t.Errorf("Unexpected failure for scenario: %s - %+v", name, errs) }
} if len(errs) > 0 && !scenario.isExpectedFailure {
t.Errorf("Unexpected failure for scenario: %s - %+v", name, errs)
}
})
} }
} }
...@@ -11757,13 +11684,13 @@ func TestValidateResourceQuota(t *testing.T) { ...@@ -11757,13 +11684,13 @@ func TestValidateResourceQuota(t *testing.T) {
Spec: nonBestEffortSpec, Spec: nonBestEffortSpec,
}, },
} }
utilfeature.DefaultFeatureGate.Set("ResourceQuotaScopeSelectors=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ResourceQuotaScopeSelectors, true)()
for _, successCase := range successCases { for _, successCase := range successCases {
if errs := ValidateResourceQuota(&successCase); len(errs) != 0 { if errs := ValidateResourceQuota(&successCase); len(errs) != 0 {
t.Errorf("expected success: %v", errs) t.Errorf("expected success: %v", errs)
} }
} }
utilfeature.DefaultFeatureGate.Set("ResourceQuotaScopeSelectors=false") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ResourceQuotaScopeSelectors, false)()
errorCases := map[string]struct { errorCases := map[string]struct {
R core.ResourceQuota R core.ResourceQuota
......
...@@ -36,11 +36,16 @@ filegroup( ...@@ -36,11 +36,16 @@ filegroup(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = ["util_test.go"], srcs = [
"main_test.go",
"util_test.go",
],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/apis/storage: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:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature/testing:go_default_library",
], ],
) )
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package util
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -21,8 +21,10 @@ import ( ...@@ -21,8 +21,10 @@ import (
"testing" "testing"
utilfeature "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" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/apis/storage" "k8s.io/kubernetes/pkg/apis/storage"
"k8s.io/kubernetes/pkg/features"
) )
func TestDropAlphaFields(t *testing.T) { func TestDropAlphaFields(t *testing.T) {
...@@ -39,9 +41,7 @@ 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 // Test that field gets dropped when feature gate is not set
if err := utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false"); err != nil { defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, false)()
t.Fatalf("Failed to set feature gate for VolumeScheduling: %v", err)
}
class := &storage.StorageClass{ class := &storage.StorageClass{
VolumeBindingMode: &bindingMode, VolumeBindingMode: &bindingMode,
AllowedTopologies: allowedTopologies, AllowedTopologies: allowedTopologies,
...@@ -59,9 +59,7 @@ func TestDropAlphaFields(t *testing.T) { ...@@ -59,9 +59,7 @@ func TestDropAlphaFields(t *testing.T) {
VolumeBindingMode: &bindingMode, VolumeBindingMode: &bindingMode,
AllowedTopologies: allowedTopologies, AllowedTopologies: allowedTopologies,
} }
if err := utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true"); err != nil { defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)()
t.Fatalf("Failed to set feature gate for VolumeScheduling: %v", err)
}
DropDisabledAlphaFields(class) DropDisabledAlphaFields(class)
if class.VolumeBindingMode != &bindingMode { if class.VolumeBindingMode != &bindingMode {
t.Errorf("VolumeBindingMode field got unexpectantly modified: %+v", class.VolumeBindingMode) t.Errorf("VolumeBindingMode field got unexpectantly modified: %+v", class.VolumeBindingMode)
...@@ -69,8 +67,4 @@ func TestDropAlphaFields(t *testing.T) { ...@@ -69,8 +67,4 @@ func TestDropAlphaFields(t *testing.T) {
if !reflect.DeepEqual(class.AllowedTopologies, allowedTopologies) { if !reflect.DeepEqual(class.AllowedTopologies, allowedTopologies) {
t.Errorf("AllowedTopologies field got unexpectantly modified: %+v", class.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)
}
} }
...@@ -47,13 +47,18 @@ filegroup( ...@@ -47,13 +47,18 @@ filegroup(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = ["defaults_test.go"], srcs = [
"defaults_test.go",
"main_test.go",
],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/api/legacyscheme:go_default_library", "//pkg/api/legacyscheme:go_default_library",
"//pkg/apis/storage/install:go_default_library", "//pkg/apis/storage/install:go_default_library",
"//pkg/features:go_default_library",
"//staging/src/k8s.io/api/storage/v1:go_default_library", "//staging/src/k8s.io/api/storage/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature: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",
], ],
) )
...@@ -23,8 +23,10 @@ import ( ...@@ -23,8 +23,10 @@ import (
storagev1 "k8s.io/api/storage/v1" storagev1 "k8s.io/api/storage/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
_ "k8s.io/kubernetes/pkg/apis/storage/install" _ "k8s.io/kubernetes/pkg/apis/storage/install"
"k8s.io/kubernetes/pkg/features"
) )
func roundTrip(t *testing.T, obj runtime.Object) runtime.Object { func roundTrip(t *testing.T, obj runtime.Object) runtime.Object {
...@@ -51,25 +53,9 @@ func roundTrip(t *testing.T, obj runtime.Object) runtime.Object { ...@@ -51,25 +53,9 @@ func roundTrip(t *testing.T, obj runtime.Object) runtime.Object {
func TestSetDefaultVolumeBindingMode(t *testing.T) { func TestSetDefaultVolumeBindingMode(t *testing.T) {
class := &storagev1.StorageClass{} class := &storagev1.StorageClass{}
// When feature gate is disabled, field should not be defaulted
err := utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false")
if err != nil {
t.Fatalf("Failed to enable feature gate for VolumeScheduling: %v", err)
}
output := roundTrip(t, runtime.Object(class)).(*storagev1.StorageClass)
if output.VolumeBindingMode != nil {
t.Errorf("Expected VolumeBindingMode to not be defaulted, got: %+v", output.VolumeBindingMode)
}
class = &storagev1.StorageClass{}
// When feature gate is enabled, field should be defaulted // When feature gate is enabled, field should be defaulted
err = utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true")
if err != nil {
t.Fatalf("Failed to enable feature gate for VolumeScheduling: %v", err)
}
defaultMode := storagev1.VolumeBindingImmediate defaultMode := storagev1.VolumeBindingImmediate
output = roundTrip(t, runtime.Object(class)).(*storagev1.StorageClass) output := roundTrip(t, runtime.Object(class)).(*storagev1.StorageClass)
outMode := output.VolumeBindingMode outMode := output.VolumeBindingMode
if outMode == nil { if outMode == nil {
t.Errorf("Expected VolumeBindingMode to be defaulted to: %+v, got: nil", defaultMode) t.Errorf("Expected VolumeBindingMode to be defaulted to: %+v, got: nil", defaultMode)
...@@ -77,8 +63,12 @@ func TestSetDefaultVolumeBindingMode(t *testing.T) { ...@@ -77,8 +63,12 @@ func TestSetDefaultVolumeBindingMode(t *testing.T) {
t.Errorf("Expected VolumeBindingMode to be defaulted to: %+v, got: %+v", defaultMode, outMode) t.Errorf("Expected VolumeBindingMode to be defaulted to: %+v, got: %+v", defaultMode, outMode)
} }
err = utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false") class = &storagev1.StorageClass{}
if err != nil {
t.Fatalf("Failed to disable feature gate for VolumeScheduling: %v", err) // When feature gate is disabled, field should not be defaulted
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, false)()
output = roundTrip(t, runtime.Object(class)).(*storagev1.StorageClass)
if output.VolumeBindingMode != nil {
t.Errorf("Expected VolumeBindingMode to not be defaulted, got: %+v", output.VolumeBindingMode)
} }
} }
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -47,13 +47,18 @@ filegroup( ...@@ -47,13 +47,18 @@ filegroup(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = ["defaults_test.go"], srcs = [
"defaults_test.go",
"main_test.go",
],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/api/legacyscheme:go_default_library", "//pkg/api/legacyscheme:go_default_library",
"//pkg/apis/storage/install:go_default_library", "//pkg/apis/storage/install:go_default_library",
"//pkg/features:go_default_library",
"//staging/src/k8s.io/api/storage/v1beta1:go_default_library", "//staging/src/k8s.io/api/storage/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature: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",
], ],
) )
...@@ -23,8 +23,10 @@ import ( ...@@ -23,8 +23,10 @@ import (
storagev1beta1 "k8s.io/api/storage/v1beta1" storagev1beta1 "k8s.io/api/storage/v1beta1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
_ "k8s.io/kubernetes/pkg/apis/storage/install" _ "k8s.io/kubernetes/pkg/apis/storage/install"
"k8s.io/kubernetes/pkg/features"
) )
func roundTrip(t *testing.T, obj runtime.Object) runtime.Object { func roundTrip(t *testing.T, obj runtime.Object) runtime.Object {
...@@ -51,25 +53,9 @@ func roundTrip(t *testing.T, obj runtime.Object) runtime.Object { ...@@ -51,25 +53,9 @@ func roundTrip(t *testing.T, obj runtime.Object) runtime.Object {
func TestSetDefaultVolumeBindingMode(t *testing.T) { func TestSetDefaultVolumeBindingMode(t *testing.T) {
class := &storagev1beta1.StorageClass{} class := &storagev1beta1.StorageClass{}
// When feature gate is disabled, field should not be defaulted
err := utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false")
if err != nil {
t.Fatalf("Failed to enable feature gate for VolumeScheduling: %v", err)
}
output := roundTrip(t, runtime.Object(class)).(*storagev1beta1.StorageClass)
if output.VolumeBindingMode != nil {
t.Errorf("Expected VolumeBindingMode to not be defaulted, got: %+v", output.VolumeBindingMode)
}
class = &storagev1beta1.StorageClass{}
// When feature gate is enabled, field should be defaulted // When feature gate is enabled, field should be defaulted
err = utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true")
if err != nil {
t.Fatalf("Failed to enable feature gate for VolumeScheduling: %v", err)
}
defaultMode := storagev1beta1.VolumeBindingImmediate defaultMode := storagev1beta1.VolumeBindingImmediate
output = roundTrip(t, runtime.Object(class)).(*storagev1beta1.StorageClass) output := roundTrip(t, runtime.Object(class)).(*storagev1beta1.StorageClass)
outMode := output.VolumeBindingMode outMode := output.VolumeBindingMode
if outMode == nil { if outMode == nil {
t.Errorf("Expected VolumeBindingMode to be defaulted to: %+v, got: nil", defaultMode) t.Errorf("Expected VolumeBindingMode to be defaulted to: %+v, got: nil", defaultMode)
...@@ -77,8 +63,13 @@ func TestSetDefaultVolumeBindingMode(t *testing.T) { ...@@ -77,8 +63,13 @@ func TestSetDefaultVolumeBindingMode(t *testing.T) {
t.Errorf("Expected VolumeBindingMode to be defaulted to: %+v, got: %+v", defaultMode, outMode) t.Errorf("Expected VolumeBindingMode to be defaulted to: %+v, got: %+v", defaultMode, outMode)
} }
err = utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false") class = &storagev1beta1.StorageClass{}
if err != nil {
t.Fatalf("Failed to disable feature gate for VolumeScheduling: %v", err) // When feature gate is disabled, field should not be defaulted
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, false)()
output = roundTrip(t, runtime.Object(class)).(*storagev1beta1.StorageClass)
if output.VolumeBindingMode != nil {
t.Errorf("Expected VolumeBindingMode to not be defaulted, got: %+v", output.VolumeBindingMode)
} }
} }
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1beta1
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -26,13 +26,18 @@ go_library( ...@@ -26,13 +26,18 @@ go_library(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = ["validation_test.go"], srcs = [
"main_test.go",
"validation_test.go",
],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/apis/storage:go_default_library", "//pkg/apis/storage:go_default_library",
"//pkg/features:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature: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",
], ],
) )
......
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package validation
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -23,8 +23,10 @@ import ( ...@@ -23,8 +23,10 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
utilfeature "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" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/apis/storage" "k8s.io/kubernetes/pkg/apis/storage"
"k8s.io/kubernetes/pkg/features"
) )
var ( var (
...@@ -151,21 +153,13 @@ func TestAlphaExpandPersistentVolumesFeatureValidation(t *testing.T) { ...@@ -151,21 +153,13 @@ func TestAlphaExpandPersistentVolumesFeatureValidation(t *testing.T) {
VolumeBindingMode: &immediateMode1, VolumeBindingMode: &immediateMode1,
} }
// Enable alpha feature ExpandPersistentVolumes // Enable feature ExpandPersistentVolumes
err := utilfeature.DefaultFeatureGate.Set("ExpandPersistentVolumes=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExpandPersistentVolumes, true)()
if err != nil {
t.Errorf("Failed to enable feature gate for ExpandPersistentVolumes: %v", err)
return
}
if errs := ValidateStorageClass(testSC); len(errs) != 0 { if errs := ValidateStorageClass(testSC); len(errs) != 0 {
t.Errorf("expected success: %v", errs) t.Errorf("expected success: %v", errs)
} }
// Disable alpha feature ExpandPersistentVolumes // Disable feature ExpandPersistentVolumes
err = utilfeature.DefaultFeatureGate.Set("ExpandPersistentVolumes=false") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExpandPersistentVolumes, false)()
if err != nil {
t.Errorf("Failed to disable feature gate for ExpandPersistentVolumes: %v", err)
return
}
if errs := ValidateStorageClass(testSC); len(errs) == 0 { if errs := ValidateStorageClass(testSC); len(errs) == 0 {
t.Errorf("expected failure, but got no error") t.Errorf("expected failure, but got no error")
} }
...@@ -520,10 +514,7 @@ func TestValidateVolumeBindingModeAlphaDisabled(t *testing.T) { ...@@ -520,10 +514,7 @@ func TestValidateVolumeBindingModeAlphaDisabled(t *testing.T) {
"invalid mode": makeClass(&invalidMode, nil), "invalid mode": makeClass(&invalidMode, nil),
} }
err := utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, false)()
if err != nil {
t.Fatalf("Failed to enable feature gate for VolumeScheduling: %v", err)
}
for testName, storageClass := range errorCases { for testName, storageClass := range errorCases {
if errs := ValidateStorageClass(storageClass); len(errs) == 0 { if errs := ValidateStorageClass(storageClass); len(errs) == 0 {
t.Errorf("Expected failure for test: %v", testName) t.Errorf("Expected failure for test: %v", testName)
...@@ -557,11 +548,7 @@ func TestValidateVolumeBindingMode(t *testing.T) { ...@@ -557,11 +548,7 @@ func TestValidateVolumeBindingMode(t *testing.T) {
} }
// TODO: remove when feature gate not required // TODO: remove when feature gate not required
err := utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)()
if err != nil {
t.Fatalf("Failed to enable feature gate for VolumeScheduling: %v", err)
}
for testName, testCase := range cases { for testName, testCase := range cases {
errs := ValidateStorageClass(testCase.class) errs := ValidateStorageClass(testCase.class)
if testCase.shouldSucceed && len(errs) != 0 { if testCase.shouldSucceed && len(errs) != 0 {
...@@ -571,11 +558,6 @@ func TestValidateVolumeBindingMode(t *testing.T) { ...@@ -571,11 +558,6 @@ func TestValidateVolumeBindingMode(t *testing.T) {
t.Errorf("Expected failure for test %q, got success", testName) 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 { type updateTest struct {
...@@ -624,11 +606,7 @@ func TestValidateUpdateVolumeBindingMode(t *testing.T) { ...@@ -624,11 +606,7 @@ func TestValidateUpdateVolumeBindingMode(t *testing.T) {
} }
// TODO: remove when feature gate not required // TODO: remove when feature gate not required
err := utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)()
if err != nil {
t.Fatalf("Failed to enable feature gate for VolumeScheduling: %v", err)
}
for testName, testCase := range cases { for testName, testCase := range cases {
errs := ValidateStorageClassUpdate(testCase.newClass, testCase.oldClass) errs := ValidateStorageClassUpdate(testCase.newClass, testCase.oldClass)
if testCase.shouldSucceed && len(errs) != 0 { if testCase.shouldSucceed && len(errs) != 0 {
...@@ -638,11 +616,6 @@ func TestValidateUpdateVolumeBindingMode(t *testing.T) { ...@@ -638,11 +616,6 @@ func TestValidateUpdateVolumeBindingMode(t *testing.T) {
t.Errorf("Expected failure for %v, got success", testName) 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) { func TestValidateAllowedTopologies(t *testing.T) {
...@@ -936,12 +909,7 @@ func TestValidateAllowedTopologies(t *testing.T) { ...@@ -936,12 +909,7 @@ func TestValidateAllowedTopologies(t *testing.T) {
}, },
} }
// TODO: remove when feature gate not required defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)()
err := utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true")
if err != nil {
t.Fatalf("Failed to enable feature gate for VolumeScheduling: %v", err)
}
for testName, testCase := range cases { for testName, testCase := range cases {
errs := ValidateStorageClass(testCase.class) errs := ValidateStorageClass(testCase.class)
if testCase.shouldSucceed && len(errs) != 0 { if testCase.shouldSucceed && len(errs) != 0 {
...@@ -952,11 +920,7 @@ func TestValidateAllowedTopologies(t *testing.T) { ...@@ -952,11 +920,7 @@ func TestValidateAllowedTopologies(t *testing.T) {
} }
} }
err = utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, false)()
if err != nil {
t.Fatalf("Failed to disable feature gate for VolumeScheduling: %v", err)
}
for testName, testCase := range cases { for testName, testCase := range cases {
errs := ValidateStorageClass(testCase.class) errs := ValidateStorageClass(testCase.class)
if len(errs) == 0 && testCase.class.AllowedTopologies != nil { if len(errs) == 0 && testCase.class.AllowedTopologies != nil {
......
...@@ -50,6 +50,7 @@ go_library( ...@@ -50,6 +50,7 @@ go_library(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = [ srcs = [
"main_test.go",
"node_controller_test.go", "node_controller_test.go",
"pvlcontroller_test.go", "pvlcontroller_test.go",
], ],
...@@ -58,6 +59,7 @@ go_test( ...@@ -58,6 +59,7 @@ go_test(
"//pkg/cloudprovider/providers/fake:go_default_library", "//pkg/cloudprovider/providers/fake:go_default_library",
"//pkg/controller:go_default_library", "//pkg/controller:go_default_library",
"//pkg/controller/testutil:go_default_library", "//pkg/controller/testutil:go_default_library",
"//pkg/features:go_default_library",
"//pkg/kubelet/apis:go_default_library", "//pkg/kubelet/apis:go_default_library",
"//pkg/scheduler/api:go_default_library", "//pkg/scheduler/api:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
...@@ -68,6 +70,7 @@ go_test( ...@@ -68,6 +70,7 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//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/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: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/informers:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake: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", "//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library",
......
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cloud
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -28,8 +28,10 @@ import ( ...@@ -28,8 +28,10 @@ import (
sets "k8s.io/apimachinery/pkg/util/sets" sets "k8s.io/apimachinery/pkg/util/sets"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
"k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/kubernetes/fake"
core "k8s.io/client-go/testing" core "k8s.io/client-go/testing"
"k8s.io/kubernetes/pkg/features"
kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis" kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
...@@ -449,8 +451,7 @@ func TestCreatePatch(t *testing.T) { ...@@ -449,8 +451,7 @@ func TestCreatePatch(t *testing.T) {
}, },
} }
utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)()
defer utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false")
for d, tc := range testCases { for d, tc := range testCases {
cloud := &fakecloud.FakeCloud{} cloud := &fakecloud.FakeCloud{}
client := fake.NewSimpleClientset() client := fake.NewSimpleClientset()
...@@ -519,8 +520,7 @@ func TestAddLabelsToVolume(t *testing.T) { ...@@ -519,8 +520,7 @@ func TestAddLabelsToVolume(t *testing.T) {
}, },
} }
utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)()
defer utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false")
for d, tc := range testCases { for d, tc := range testCases {
labeledCh := make(chan bool, 1) labeledCh := make(chan bool, 1)
......
...@@ -61,6 +61,7 @@ go_test( ...@@ -61,6 +61,7 @@ go_test(
name = "go_default_test", name = "go_default_test",
srcs = [ srcs = [
"daemon_controller_test.go", "daemon_controller_test.go",
"main_test.go",
"update_test.go", "update_test.go",
], ],
embed = [":go_default_library"], embed = [":go_default_library"],
...@@ -84,6 +85,7 @@ go_test( ...@@ -84,6 +85,7 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/storage/names:go_default_library", "//staging/src/k8s.io/apiserver/pkg/storage/names:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature: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/informers:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
"//staging/src/k8s.io/client-go/testing:go_default_library", "//staging/src/k8s.io/client-go/testing:go_default_library",
......
...@@ -35,6 +35,7 @@ import ( ...@@ -35,6 +35,7 @@ import (
"k8s.io/apimachinery/pkg/util/uuid" "k8s.io/apimachinery/pkg/util/uuid"
"k8s.io/apiserver/pkg/storage/names" "k8s.io/apiserver/pkg/storage/names"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
"k8s.io/client-go/informers" "k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/kubernetes/fake"
core "k8s.io/client-go/testing" core "k8s.io/client-go/testing"
...@@ -411,7 +412,7 @@ func clearExpectations(t *testing.T, manager *daemonSetsController, ds *apps.Dae ...@@ -411,7 +412,7 @@ func clearExpectations(t *testing.T, manager *daemonSetsController, ds *apps.Dae
func TestDeleteFinalStateUnknown(t *testing.T) { func TestDeleteFinalStateUnknown(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
manager, _, _, err := newTestController() manager, _, _, err := newTestController()
if err != nil { if err != nil {
...@@ -443,16 +444,10 @@ func markPodReady(pod *v1.Pod) { ...@@ -443,16 +444,10 @@ func markPodReady(pod *v1.Pod) {
podutil.UpdatePodCondition(&pod.Status, &condition) podutil.UpdatePodCondition(&pod.Status, &condition)
} }
func setFeatureGate(t *testing.T, feature utilfeature.Feature, enabled bool) {
if err := utilfeature.DefaultFeatureGate.Set(fmt.Sprintf("%s=%t", feature, enabled)); err != nil {
t.Fatalf("Failed to set FeatureGate %v to %t: %v", feature, enabled, err)
}
}
// DaemonSets without node selectors should launch pods on every node. // DaemonSets without node selectors should launch pods on every node.
func TestSimpleDaemonSetLaunchesPods(t *testing.T) { func TestSimpleDaemonSetLaunchesPods(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo") ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -470,12 +465,7 @@ func TestSimpleDaemonSetLaunchesPods(t *testing.T) { ...@@ -470,12 +465,7 @@ func TestSimpleDaemonSetLaunchesPods(t *testing.T) {
// When ScheduleDaemonSetPods is enabled, DaemonSets without node selectors should // When ScheduleDaemonSetPods is enabled, DaemonSets without node selectors should
// launch pods on every node by NodeAffinity. // launch pods on every node by NodeAffinity.
func TestSimpleDaemonSetScheduleDaemonSetPodsLaunchesPods(t *testing.T) { func TestSimpleDaemonSetScheduleDaemonSetPodsLaunchesPods(t *testing.T) {
enabled := utilfeature.DefaultFeatureGate.Enabled(features.ScheduleDaemonSetPods) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, true)()
// Rollback feature gate.
defer func() {
setFeatureGate(t, features.ScheduleDaemonSetPods, enabled)
}()
setFeatureGate(t, features.ScheduleDaemonSetPods, true)
nodeNum := 5 nodeNum := 5
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
...@@ -552,7 +542,7 @@ func TestSimpleDaemonSetScheduleDaemonSetPodsLaunchesPods(t *testing.T) { ...@@ -552,7 +542,7 @@ func TestSimpleDaemonSetScheduleDaemonSetPodsLaunchesPods(t *testing.T) {
// of 10 pods, and verify that the ds doesn't make 100 create calls per sync pass // of 10 pods, and verify that the ds doesn't make 100 create calls per sync pass
func TestSimpleDaemonSetPodCreateErrors(t *testing.T) { func TestSimpleDaemonSetPodCreateErrors(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo") ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -578,7 +568,7 @@ func TestSimpleDaemonSetPodCreateErrors(t *testing.T) { ...@@ -578,7 +568,7 @@ func TestSimpleDaemonSetPodCreateErrors(t *testing.T) {
func TestSimpleDaemonSetUpdatesStatusAfterLaunchingPods(t *testing.T) { func TestSimpleDaemonSetUpdatesStatusAfterLaunchingPods(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo") ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -614,7 +604,7 @@ func TestSimpleDaemonSetUpdatesStatusAfterLaunchingPods(t *testing.T) { ...@@ -614,7 +604,7 @@ func TestSimpleDaemonSetUpdatesStatusAfterLaunchingPods(t *testing.T) {
// DaemonSets should do nothing if there aren't any nodes // DaemonSets should do nothing if there aren't any nodes
func TestNoNodesDoesNothing(t *testing.T) { func TestNoNodesDoesNothing(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
manager, podControl, _, err := newTestController() manager, podControl, _, err := newTestController()
if err != nil { if err != nil {
...@@ -632,7 +622,7 @@ func TestNoNodesDoesNothing(t *testing.T) { ...@@ -632,7 +622,7 @@ func TestNoNodesDoesNothing(t *testing.T) {
// single node cluster. // single node cluster.
func TestOneNodeDaemonLaunchesPod(t *testing.T) { func TestOneNodeDaemonLaunchesPod(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo") ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -650,7 +640,7 @@ func TestOneNodeDaemonLaunchesPod(t *testing.T) { ...@@ -650,7 +640,7 @@ func TestOneNodeDaemonLaunchesPod(t *testing.T) {
// DaemonSets should place onto NotReady nodes // DaemonSets should place onto NotReady nodes
func TestNotReadyNodeDaemonDoesLaunchPod(t *testing.T) { func TestNotReadyNodeDaemonDoesLaunchPod(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo") ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -706,21 +696,7 @@ func allocatableResources(memory, cpu string) v1.ResourceList { ...@@ -706,21 +696,7 @@ func allocatableResources(memory, cpu string) v1.ResourceList {
// When ScheduleDaemonSetPods is disabled, DaemonSets should not place onto nodes with insufficient free resource // When ScheduleDaemonSetPods is disabled, DaemonSets should not place onto nodes with insufficient free resource
func TestInsufficientCapacityNodeDaemonDoesNotLaunchPod(t *testing.T) { func TestInsufficientCapacityNodeDaemonDoesNotLaunchPod(t *testing.T) {
enabled := utilfeature.DefaultFeatureGate.Enabled(features.ScheduleDaemonSetPods) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, false)()
// Rollback feature gate.
defer func() {
if enabled {
err := utilfeature.DefaultFeatureGate.Set("ScheduleDaemonSetPods=true")
if err != nil {
t.Fatalf("Failed to enable feature gate for ScheduleDaemonSetPods: %v", err)
}
}
}()
err := utilfeature.DefaultFeatureGate.Set("ScheduleDaemonSetPods=false")
if err != nil {
t.Fatalf("Failed to disable feature gate for ScheduleDaemonSetPods: %v", err)
}
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
podSpec := resourcePodSpec("too-much-mem", "75M", "75m") podSpec := resourcePodSpec("too-much-mem", "75M", "75m")
ds := newDaemonSet("foo") ds := newDaemonSet("foo")
...@@ -751,7 +727,7 @@ func TestInsufficientCapacityNodeDaemonDoesNotLaunchPod(t *testing.T) { ...@@ -751,7 +727,7 @@ func TestInsufficientCapacityNodeDaemonDoesNotLaunchPod(t *testing.T) {
// DaemonSets should not unschedule a daemonset pod from a node with insufficient free resource // DaemonSets should not unschedule a daemonset pod from a node with insufficient free resource
func TestInsufficientCapacityNodeDaemonDoesNotUnscheduleRunningPod(t *testing.T) { func TestInsufficientCapacityNodeDaemonDoesNotUnscheduleRunningPod(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
podSpec := resourcePodSpec("too-much-mem", "75M", "75m") podSpec := resourcePodSpec("too-much-mem", "75M", "75m")
podSpec.NodeName = "too-much-mem" podSpec.NodeName = "too-much-mem"
...@@ -792,7 +768,7 @@ func TestInsufficientCapacityNodeDaemonDoesNotUnscheduleRunningPod(t *testing.T) ...@@ -792,7 +768,7 @@ func TestInsufficientCapacityNodeDaemonDoesNotUnscheduleRunningPod(t *testing.T)
// DaemonSets should only place onto nodes with sufficient free resource and matched node selector // DaemonSets should only place onto nodes with sufficient free resource and matched node selector
func TestInsufficientCapacityNodeSufficientCapacityWithNodeLabelDaemonLaunchPod(t *testing.T) { func TestInsufficientCapacityNodeSufficientCapacityWithNodeLabelDaemonLaunchPod(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
podSpec := resourcePodSpecWithoutNodeName("50M", "75m") podSpec := resourcePodSpecWithoutNodeName("50M", "75m")
ds := newDaemonSet("foo") ds := newDaemonSet("foo")
ds.Spec.Template.Spec = podSpec ds.Spec.Template.Spec = podSpec
...@@ -819,15 +795,7 @@ func TestInsufficientCapacityNodeSufficientCapacityWithNodeLabelDaemonLaunchPod( ...@@ -819,15 +795,7 @@ func TestInsufficientCapacityNodeSufficientCapacityWithNodeLabelDaemonLaunchPod(
// When ScheduleDaemonSetPods is disabled, DaemonSetPods should launch onto node with terminated pods if there // When ScheduleDaemonSetPods is disabled, DaemonSetPods should launch onto node with terminated pods if there
// are sufficient resources. // are sufficient resources.
func TestSufficientCapacityWithTerminatedPodsDaemonLaunchesPod(t *testing.T) { func TestSufficientCapacityWithTerminatedPodsDaemonLaunchesPod(t *testing.T) {
enabled := utilfeature.DefaultFeatureGate.Enabled(features.ScheduleDaemonSetPods) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, false)()
// Rollback feature gate.
defer func() {
if enabled {
setFeatureGate(t, features.ScheduleDaemonSetPods, true)
}
}()
setFeatureGate(t, features.ScheduleDaemonSetPods, false)
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
podSpec := resourcePodSpec("too-much-mem", "75M", "75m") podSpec := resourcePodSpec("too-much-mem", "75M", "75m")
ds := newDaemonSet("foo") ds := newDaemonSet("foo")
...@@ -851,15 +819,7 @@ func TestSufficientCapacityWithTerminatedPodsDaemonLaunchesPod(t *testing.T) { ...@@ -851,15 +819,7 @@ func TestSufficientCapacityWithTerminatedPodsDaemonLaunchesPod(t *testing.T) {
// When ScheduleDaemonSetPods is disabled, DaemonSets should place onto nodes with sufficient free resources. // When ScheduleDaemonSetPods is disabled, DaemonSets should place onto nodes with sufficient free resources.
func TestSufficientCapacityNodeDaemonLaunchesPod(t *testing.T) { func TestSufficientCapacityNodeDaemonLaunchesPod(t *testing.T) {
enabled := utilfeature.DefaultFeatureGate.Enabled(features.ScheduleDaemonSetPods) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, false)()
// Rollback feature gate.
defer func() {
if enabled {
setFeatureGate(t, features.ScheduleDaemonSetPods, true)
}
}()
setFeatureGate(t, features.ScheduleDaemonSetPods, false)
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
podSpec := resourcePodSpec("not-too-much-mem", "75M", "75m") podSpec := resourcePodSpec("not-too-much-mem", "75M", "75m")
...@@ -884,7 +844,7 @@ func TestSufficientCapacityNodeDaemonLaunchesPod(t *testing.T) { ...@@ -884,7 +844,7 @@ func TestSufficientCapacityNodeDaemonLaunchesPod(t *testing.T) {
// DaemonSet should launch a pod on a node with taint NetworkUnavailable condition. // DaemonSet should launch a pod on a node with taint NetworkUnavailable condition.
func TestNetworkUnavailableNodeDaemonLaunchesPod(t *testing.T) { func TestNetworkUnavailableNodeDaemonLaunchesPod(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("simple") ds := newDaemonSet("simple")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -908,7 +868,7 @@ func TestNetworkUnavailableNodeDaemonLaunchesPod(t *testing.T) { ...@@ -908,7 +868,7 @@ func TestNetworkUnavailableNodeDaemonLaunchesPod(t *testing.T) {
// DaemonSets not take any actions when being deleted // DaemonSets not take any actions when being deleted
func TestDontDoAnythingIfBeingDeleted(t *testing.T) { func TestDontDoAnythingIfBeingDeleted(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
podSpec := resourcePodSpec("not-too-much-mem", "75M", "75m") podSpec := resourcePodSpec("not-too-much-mem", "75M", "75m")
ds := newDaemonSet("foo") ds := newDaemonSet("foo")
...@@ -934,7 +894,7 @@ func TestDontDoAnythingIfBeingDeleted(t *testing.T) { ...@@ -934,7 +894,7 @@ func TestDontDoAnythingIfBeingDeleted(t *testing.T) {
func TestDontDoAnythingIfBeingDeletedRace(t *testing.T) { func TestDontDoAnythingIfBeingDeletedRace(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
// Bare client says it IS deleted. // Bare client says it IS deleted.
ds := newDaemonSet("foo") ds := newDaemonSet("foo")
...@@ -963,15 +923,7 @@ func TestDontDoAnythingIfBeingDeletedRace(t *testing.T) { ...@@ -963,15 +923,7 @@ func TestDontDoAnythingIfBeingDeletedRace(t *testing.T) {
// When ScheduleDaemonSetPods is disabled, DaemonSets should not place onto nodes that would cause port conflicts. // When ScheduleDaemonSetPods is disabled, DaemonSets should not place onto nodes that would cause port conflicts.
func TestPortConflictNodeDaemonDoesNotLaunchPod(t *testing.T) { func TestPortConflictNodeDaemonDoesNotLaunchPod(t *testing.T) {
enabled := utilfeature.DefaultFeatureGate.Enabled(features.ScheduleDaemonSetPods) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, false)()
// Rollback feature gate.
defer func() {
if enabled {
setFeatureGate(t, features.ScheduleDaemonSetPods, true)
}
}()
setFeatureGate(t, features.ScheduleDaemonSetPods, false)
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
podSpec := v1.PodSpec{ podSpec := v1.PodSpec{
NodeName: "port-conflict", NodeName: "port-conflict",
...@@ -1005,7 +957,7 @@ func TestPortConflictNodeDaemonDoesNotLaunchPod(t *testing.T) { ...@@ -1005,7 +957,7 @@ func TestPortConflictNodeDaemonDoesNotLaunchPod(t *testing.T) {
// Issue: https://github.com/kubernetes/kubernetes/issues/22309 // Issue: https://github.com/kubernetes/kubernetes/issues/22309
func TestPortConflictWithSameDaemonPodDoesNotDeletePod(t *testing.T) { func TestPortConflictWithSameDaemonPodDoesNotDeletePod(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
podSpec := v1.PodSpec{ podSpec := v1.PodSpec{
NodeName: "port-conflict", NodeName: "port-conflict",
...@@ -1035,7 +987,7 @@ func TestPortConflictWithSameDaemonPodDoesNotDeletePod(t *testing.T) { ...@@ -1035,7 +987,7 @@ func TestPortConflictWithSameDaemonPodDoesNotDeletePod(t *testing.T) {
// DaemonSets should place onto nodes that would not cause port conflicts // DaemonSets should place onto nodes that would not cause port conflicts
func TestNoPortConflictNodeDaemonLaunchesPod(t *testing.T) { func TestNoPortConflictNodeDaemonLaunchesPod(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
podSpec1 := v1.PodSpec{ podSpec1 := v1.PodSpec{
NodeName: "no-port-conflict", NodeName: "no-port-conflict",
...@@ -1085,7 +1037,7 @@ func TestPodIsNotDeletedByDaemonsetWithEmptyLabelSelector(t *testing.T) { ...@@ -1085,7 +1037,7 @@ func TestPodIsNotDeletedByDaemonsetWithEmptyLabelSelector(t *testing.T) {
// should detect this misconfiguration and choose not to sync the DaemonSet. We should // should detect this misconfiguration and choose not to sync the DaemonSet. We should
// not observe a deletion of the pod on node1. // not observe a deletion of the pod on node1.
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo") ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -1118,7 +1070,7 @@ func TestPodIsNotDeletedByDaemonsetWithEmptyLabelSelector(t *testing.T) { ...@@ -1118,7 +1070,7 @@ func TestPodIsNotDeletedByDaemonsetWithEmptyLabelSelector(t *testing.T) {
// Controller should not create pods on nodes which have daemon pods, and should remove excess pods from nodes that have extra pods. // Controller should not create pods on nodes which have daemon pods, and should remove excess pods from nodes that have extra pods.
func TestDealsWithExistingPods(t *testing.T) { func TestDealsWithExistingPods(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo") ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -1140,7 +1092,7 @@ func TestDealsWithExistingPods(t *testing.T) { ...@@ -1140,7 +1092,7 @@ func TestDealsWithExistingPods(t *testing.T) {
// Daemon with node selector should launch pods on nodes matching selector. // Daemon with node selector should launch pods on nodes matching selector.
func TestSelectorDaemonLaunchesPods(t *testing.T) { func TestSelectorDaemonLaunchesPods(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
daemon := newDaemonSet("foo") daemon := newDaemonSet("foo")
daemon.Spec.UpdateStrategy = *strategy daemon.Spec.UpdateStrategy = *strategy
...@@ -1160,7 +1112,7 @@ func TestSelectorDaemonLaunchesPods(t *testing.T) { ...@@ -1160,7 +1112,7 @@ func TestSelectorDaemonLaunchesPods(t *testing.T) {
// Daemon with node selector should delete pods from nodes that do not satisfy selector. // Daemon with node selector should delete pods from nodes that do not satisfy selector.
func TestSelectorDaemonDeletesUnselectedPods(t *testing.T) { func TestSelectorDaemonDeletesUnselectedPods(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo") ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -1184,7 +1136,7 @@ func TestSelectorDaemonDeletesUnselectedPods(t *testing.T) { ...@@ -1184,7 +1136,7 @@ func TestSelectorDaemonDeletesUnselectedPods(t *testing.T) {
// DaemonSet with node selector should launch pods on nodes matching selector, but also deal with existing pods on nodes. // DaemonSet with node selector should launch pods on nodes matching selector, but also deal with existing pods on nodes.
func TestSelectorDaemonDealsWithExistingPods(t *testing.T) { func TestSelectorDaemonDealsWithExistingPods(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo") ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -1212,7 +1164,7 @@ func TestSelectorDaemonDealsWithExistingPods(t *testing.T) { ...@@ -1212,7 +1164,7 @@ func TestSelectorDaemonDealsWithExistingPods(t *testing.T) {
// DaemonSet with node selector which does not match any node labels should not launch pods. // DaemonSet with node selector which does not match any node labels should not launch pods.
func TestBadSelectorDaemonDoesNothing(t *testing.T) { func TestBadSelectorDaemonDoesNothing(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
manager, podControl, _, err := newTestController() manager, podControl, _, err := newTestController()
if err != nil { if err != nil {
...@@ -1232,7 +1184,7 @@ func TestBadSelectorDaemonDoesNothing(t *testing.T) { ...@@ -1232,7 +1184,7 @@ func TestBadSelectorDaemonDoesNothing(t *testing.T) {
// DaemonSet with node name should launch pod on node with corresponding name. // DaemonSet with node name should launch pod on node with corresponding name.
func TestNameDaemonSetLaunchesPods(t *testing.T) { func TestNameDaemonSetLaunchesPods(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo") ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -1251,7 +1203,7 @@ func TestNameDaemonSetLaunchesPods(t *testing.T) { ...@@ -1251,7 +1203,7 @@ func TestNameDaemonSetLaunchesPods(t *testing.T) {
// DaemonSet with node name that does not exist should not launch pods. // DaemonSet with node name that does not exist should not launch pods.
func TestBadNameDaemonSetDoesNothing(t *testing.T) { func TestBadNameDaemonSetDoesNothing(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo") ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -1270,7 +1222,7 @@ func TestBadNameDaemonSetDoesNothing(t *testing.T) { ...@@ -1270,7 +1222,7 @@ func TestBadNameDaemonSetDoesNothing(t *testing.T) {
// DaemonSet with node selector, and node name, matching a node, should launch a pod on the node. // DaemonSet with node selector, and node name, matching a node, should launch a pod on the node.
func TestNameAndSelectorDaemonSetLaunchesPods(t *testing.T) { func TestNameAndSelectorDaemonSetLaunchesPods(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo") ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -1291,7 +1243,7 @@ func TestNameAndSelectorDaemonSetLaunchesPods(t *testing.T) { ...@@ -1291,7 +1243,7 @@ func TestNameAndSelectorDaemonSetLaunchesPods(t *testing.T) {
// DaemonSet with node selector that matches some nodes, and node name that matches a different node, should do nothing. // DaemonSet with node selector that matches some nodes, and node name that matches a different node, should do nothing.
func TestInconsistentNameSelectorDaemonSetDoesNothing(t *testing.T) { func TestInconsistentNameSelectorDaemonSetDoesNothing(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo") ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -1312,7 +1264,7 @@ func TestInconsistentNameSelectorDaemonSetDoesNothing(t *testing.T) { ...@@ -1312,7 +1264,7 @@ func TestInconsistentNameSelectorDaemonSetDoesNothing(t *testing.T) {
// DaemonSet with node selector, matching some nodes, should launch pods on all the nodes. // DaemonSet with node selector, matching some nodes, should launch pods on all the nodes.
func TestSelectorDaemonSetLaunchesPods(t *testing.T) { func TestSelectorDaemonSetLaunchesPods(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
ds := newDaemonSet("foo") ds := newDaemonSet("foo")
ds.Spec.Template.Spec.NodeSelector = simpleNodeLabel ds.Spec.Template.Spec.NodeSelector = simpleNodeLabel
manager, podControl, _, err := newTestController(ds) manager, podControl, _, err := newTestController(ds)
...@@ -1329,7 +1281,7 @@ func TestSelectorDaemonSetLaunchesPods(t *testing.T) { ...@@ -1329,7 +1281,7 @@ func TestSelectorDaemonSetLaunchesPods(t *testing.T) {
// Daemon with node affinity should launch pods on nodes matching affinity. // Daemon with node affinity should launch pods on nodes matching affinity.
func TestNodeAffinityDaemonLaunchesPods(t *testing.T) { func TestNodeAffinityDaemonLaunchesPods(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
daemon := newDaemonSet("foo") daemon := newDaemonSet("foo")
daemon.Spec.UpdateStrategy = *strategy daemon.Spec.UpdateStrategy = *strategy
...@@ -1365,7 +1317,7 @@ func TestNodeAffinityDaemonLaunchesPods(t *testing.T) { ...@@ -1365,7 +1317,7 @@ func TestNodeAffinityDaemonLaunchesPods(t *testing.T) {
func TestNumberReadyStatus(t *testing.T) { func TestNumberReadyStatus(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo") ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -1410,7 +1362,7 @@ func TestNumberReadyStatus(t *testing.T) { ...@@ -1410,7 +1362,7 @@ func TestNumberReadyStatus(t *testing.T) {
func TestObservedGeneration(t *testing.T) { func TestObservedGeneration(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo") ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -1457,7 +1409,7 @@ func TestDaemonKillFailedPods(t *testing.T) { ...@@ -1457,7 +1409,7 @@ func TestDaemonKillFailedPods(t *testing.T) {
for _, test := range tests { for _, test := range tests {
t.Run(test.test, func(t *testing.T) { t.Run(test.test, func(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo") ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -1479,7 +1431,7 @@ func TestDaemonKillFailedPods(t *testing.T) { ...@@ -1479,7 +1431,7 @@ func TestDaemonKillFailedPods(t *testing.T) {
// DaemonSet controller needs to backoff when killing failed pods to avoid hot looping and fighting with kubelet. // DaemonSet controller needs to backoff when killing failed pods to avoid hot looping and fighting with kubelet.
func TestDaemonKillFailedPodsBackoff(t *testing.T) { func TestDaemonKillFailedPodsBackoff(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
t.Run(string(strategy.Type), func(t *testing.T) { t.Run(string(strategy.Type), func(t *testing.T) {
ds := newDaemonSet("foo") ds := newDaemonSet("foo")
...@@ -1549,7 +1501,7 @@ func TestDaemonKillFailedPodsBackoff(t *testing.T) { ...@@ -1549,7 +1501,7 @@ func TestDaemonKillFailedPodsBackoff(t *testing.T) {
// tolerate the nodes NoSchedule taint // tolerate the nodes NoSchedule taint
func TestNoScheduleTaintedDoesntEvicitRunningIntolerantPod(t *testing.T) { func TestNoScheduleTaintedDoesntEvicitRunningIntolerantPod(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("intolerant") ds := newDaemonSet("intolerant")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -1573,7 +1525,7 @@ func TestNoScheduleTaintedDoesntEvicitRunningIntolerantPod(t *testing.T) { ...@@ -1573,7 +1525,7 @@ func TestNoScheduleTaintedDoesntEvicitRunningIntolerantPod(t *testing.T) {
// tolerate the nodes NoExecute taint // tolerate the nodes NoExecute taint
func TestNoExecuteTaintedDoesEvicitRunningIntolerantPod(t *testing.T) { func TestNoExecuteTaintedDoesEvicitRunningIntolerantPod(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("intolerant") ds := newDaemonSet("intolerant")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -1596,7 +1548,7 @@ func TestNoExecuteTaintedDoesEvicitRunningIntolerantPod(t *testing.T) { ...@@ -1596,7 +1548,7 @@ func TestNoExecuteTaintedDoesEvicitRunningIntolerantPod(t *testing.T) {
// DaemonSet should not launch a pod on a tainted node when the pod doesn't tolerate that taint. // DaemonSet should not launch a pod on a tainted node when the pod doesn't tolerate that taint.
func TestTaintedNodeDaemonDoesNotLaunchIntolerantPod(t *testing.T) { func TestTaintedNodeDaemonDoesNotLaunchIntolerantPod(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("intolerant") ds := newDaemonSet("intolerant")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -1618,7 +1570,7 @@ func TestTaintedNodeDaemonDoesNotLaunchIntolerantPod(t *testing.T) { ...@@ -1618,7 +1570,7 @@ func TestTaintedNodeDaemonDoesNotLaunchIntolerantPod(t *testing.T) {
// DaemonSet should launch a pod on a tainted node when the pod can tolerate that taint. // DaemonSet should launch a pod on a tainted node when the pod can tolerate that taint.
func TestTaintedNodeDaemonLaunchesToleratePod(t *testing.T) { func TestTaintedNodeDaemonLaunchesToleratePod(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("tolerate") ds := newDaemonSet("tolerate")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -1641,7 +1593,7 @@ func TestTaintedNodeDaemonLaunchesToleratePod(t *testing.T) { ...@@ -1641,7 +1593,7 @@ func TestTaintedNodeDaemonLaunchesToleratePod(t *testing.T) {
// DaemonSet should launch a pod on a not ready node with taint notReady:NoExecute. // DaemonSet should launch a pod on a not ready node with taint notReady:NoExecute.
func TestNotReadyNodeDaemonLaunchesPod(t *testing.T) { func TestNotReadyNodeDaemonLaunchesPod(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("simple") ds := newDaemonSet("simple")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -1666,7 +1618,7 @@ func TestNotReadyNodeDaemonLaunchesPod(t *testing.T) { ...@@ -1666,7 +1618,7 @@ func TestNotReadyNodeDaemonLaunchesPod(t *testing.T) {
// DaemonSet should launch a pod on an unreachable node with taint unreachable:NoExecute. // DaemonSet should launch a pod on an unreachable node with taint unreachable:NoExecute.
func TestUnreachableNodeDaemonLaunchesPod(t *testing.T) { func TestUnreachableNodeDaemonLaunchesPod(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("simple") ds := newDaemonSet("simple")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -1691,7 +1643,7 @@ func TestUnreachableNodeDaemonLaunchesPod(t *testing.T) { ...@@ -1691,7 +1643,7 @@ func TestUnreachableNodeDaemonLaunchesPod(t *testing.T) {
// DaemonSet should launch a pod on an untainted node when the pod has tolerations. // DaemonSet should launch a pod on an untainted node when the pod has tolerations.
func TestNodeDaemonLaunchesToleratePod(t *testing.T) { func TestNodeDaemonLaunchesToleratePod(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("tolerate") ds := newDaemonSet("tolerate")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -1711,7 +1663,7 @@ func TestNodeDaemonLaunchesToleratePod(t *testing.T) { ...@@ -1711,7 +1663,7 @@ func TestNodeDaemonLaunchesToleratePod(t *testing.T) {
// DaemonSet should launch a pod on a not ready node with taint notReady:NoExecute. // DaemonSet should launch a pod on a not ready node with taint notReady:NoExecute.
func TestDaemonSetRespectsTermination(t *testing.T) { func TestDaemonSetRespectsTermination(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo") ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -1742,12 +1694,8 @@ func setDaemonSetToleration(ds *apps.DaemonSet, tolerations []v1.Toleration) { ...@@ -1742,12 +1694,8 @@ func setDaemonSetToleration(ds *apps.DaemonSet, tolerations []v1.Toleration) {
// DaemonSet should launch a critical pod even when the node with OutOfDisk taints. // DaemonSet should launch a critical pod even when the node with OutOfDisk taints.
// TODO(#48843) OutOfDisk taints will be removed in 1.10 // TODO(#48843) OutOfDisk taints will be removed in 1.10
func TestTaintOutOfDiskNodeDaemonLaunchesCriticalPod(t *testing.T) { func TestTaintOutOfDiskNodeDaemonLaunchesCriticalPod(t *testing.T) {
enabled := utilfeature.DefaultFeatureGate.Enabled(features.ExperimentalCriticalPodAnnotation)
defer func() {
setFeatureGate(t, features.ExperimentalCriticalPodAnnotation, enabled)
}()
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("critical") ds := newDaemonSet("critical")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -1765,12 +1713,12 @@ func TestTaintOutOfDiskNodeDaemonLaunchesCriticalPod(t *testing.T) { ...@@ -1765,12 +1713,12 @@ func TestTaintOutOfDiskNodeDaemonLaunchesCriticalPod(t *testing.T) {
// NOTE: Whether or not TaintNodesByCondition is enabled, it'll add toleration to DaemonSet pods. // NOTE: Whether or not TaintNodesByCondition is enabled, it'll add toleration to DaemonSet pods.
// Without enabling critical pod annotation feature gate, we shouldn't create critical pod // Without enabling critical pod annotation feature gate, we shouldn't create critical pod
setFeatureGate(t, features.ExperimentalCriticalPodAnnotation, false) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExperimentalCriticalPodAnnotation, false)()
manager.dsStore.Add(ds) manager.dsStore.Add(ds)
syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0, 0) syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0, 0)
// With enabling critical pod annotation feature gate, we will create critical pod // With enabling critical pod annotation feature gate, we will create critical pod
setFeatureGate(t, features.ExperimentalCriticalPodAnnotation, true) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExperimentalCriticalPodAnnotation, true)()
manager.dsStore.Add(ds) manager.dsStore.Add(ds)
syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0, 0) syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0, 0)
} }
...@@ -1779,13 +1727,8 @@ func TestTaintOutOfDiskNodeDaemonLaunchesCriticalPod(t *testing.T) { ...@@ -1779,13 +1727,8 @@ func TestTaintOutOfDiskNodeDaemonLaunchesCriticalPod(t *testing.T) {
// DaemonSet should launch a pod even when the node with MemoryPressure/DiskPressure taints. // DaemonSet should launch a pod even when the node with MemoryPressure/DiskPressure taints.
func TestTaintPressureNodeDaemonLaunchesPod(t *testing.T) { func TestTaintPressureNodeDaemonLaunchesPod(t *testing.T) {
enabled := utilfeature.DefaultFeatureGate.Enabled(features.TaintNodesByCondition)
defer func() {
setFeatureGate(t, features.TaintNodesByCondition, enabled)
}()
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("critical") ds := newDaemonSet("critical")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -1807,7 +1750,7 @@ func TestTaintPressureNodeDaemonLaunchesPod(t *testing.T) { ...@@ -1807,7 +1750,7 @@ func TestTaintPressureNodeDaemonLaunchesPod(t *testing.T) {
manager.nodeStore.Add(node) manager.nodeStore.Add(node)
// Enabling critical pod and taint nodes by condition feature gate should create critical pod // Enabling critical pod and taint nodes by condition feature gate should create critical pod
setFeatureGate(t, features.TaintNodesByCondition, true) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.TaintNodesByCondition, true)()
manager.dsStore.Add(ds) manager.dsStore.Add(ds)
syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0, 0) syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0, 0)
} }
...@@ -1816,10 +1759,7 @@ func TestTaintPressureNodeDaemonLaunchesPod(t *testing.T) { ...@@ -1816,10 +1759,7 @@ func TestTaintPressureNodeDaemonLaunchesPod(t *testing.T) {
// When ScheduleDaemonSetPods is disabled, DaemonSet should launch a critical pod even when the node has insufficient free resource. // When ScheduleDaemonSetPods is disabled, DaemonSet should launch a critical pod even when the node has insufficient free resource.
func TestInsufficientCapacityNodeDaemonLaunchesCriticalPod(t *testing.T) { func TestInsufficientCapacityNodeDaemonLaunchesCriticalPod(t *testing.T) {
enabled := utilfeature.DefaultFeatureGate.Enabled(features.ExperimentalCriticalPodAnnotation) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, false)()
defer func() {
setFeatureGate(t, features.ExperimentalCriticalPodAnnotation, enabled)
}()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
podSpec := resourcePodSpec("too-much-mem", "75M", "75m") podSpec := resourcePodSpec("too-much-mem", "75M", "75m")
ds := newDaemonSet("critical") ds := newDaemonSet("critical")
...@@ -1839,7 +1779,7 @@ func TestInsufficientCapacityNodeDaemonLaunchesCriticalPod(t *testing.T) { ...@@ -1839,7 +1779,7 @@ func TestInsufficientCapacityNodeDaemonLaunchesCriticalPod(t *testing.T) {
}) })
// Without enabling critical pod annotation feature gate, we shouldn't create critical pod // Without enabling critical pod annotation feature gate, we shouldn't create critical pod
setFeatureGate(t, features.ExperimentalCriticalPodAnnotation, false) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExperimentalCriticalPodAnnotation, false)()
manager.dsStore.Add(ds) manager.dsStore.Add(ds)
switch strategy.Type { switch strategy.Type {
case apps.OnDeleteDaemonSetStrategyType: case apps.OnDeleteDaemonSetStrategyType:
...@@ -1851,7 +1791,7 @@ func TestInsufficientCapacityNodeDaemonLaunchesCriticalPod(t *testing.T) { ...@@ -1851,7 +1791,7 @@ func TestInsufficientCapacityNodeDaemonLaunchesCriticalPod(t *testing.T) {
} }
// Enabling critical pod annotation feature gate should create critical pod // Enabling critical pod annotation feature gate should create critical pod
setFeatureGate(t, features.ExperimentalCriticalPodAnnotation, true) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExperimentalCriticalPodAnnotation, true)()
switch strategy.Type { switch strategy.Type {
case apps.OnDeleteDaemonSetStrategyType: case apps.OnDeleteDaemonSetStrategyType:
syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0, 2) syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0, 2)
...@@ -1865,11 +1805,7 @@ func TestInsufficientCapacityNodeDaemonLaunchesCriticalPod(t *testing.T) { ...@@ -1865,11 +1805,7 @@ func TestInsufficientCapacityNodeDaemonLaunchesCriticalPod(t *testing.T) {
// When ScheduleDaemonSetPods is disabled, DaemonSets should NOT launch a critical pod when there are port conflicts. // When ScheduleDaemonSetPods is disabled, DaemonSets should NOT launch a critical pod when there are port conflicts.
func TestPortConflictNodeDaemonDoesNotLaunchCriticalPod(t *testing.T) { func TestPortConflictNodeDaemonDoesNotLaunchCriticalPod(t *testing.T) {
enabled := utilfeature.DefaultFeatureGate.Enabled(features.ExperimentalCriticalPodAnnotation) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, false)()
defer func() {
setFeatureGate(t, features.ExperimentalCriticalPodAnnotation, enabled)
}()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
podSpec := v1.PodSpec{ podSpec := v1.PodSpec{
NodeName: "port-conflict", NodeName: "port-conflict",
...@@ -1889,7 +1825,7 @@ func TestPortConflictNodeDaemonDoesNotLaunchCriticalPod(t *testing.T) { ...@@ -1889,7 +1825,7 @@ func TestPortConflictNodeDaemonDoesNotLaunchCriticalPod(t *testing.T) {
Spec: podSpec, Spec: podSpec,
}) })
setFeatureGate(t, features.ExperimentalCriticalPodAnnotation, true) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExperimentalCriticalPodAnnotation, true)()
ds := newDaemonSet("critical") ds := newDaemonSet("critical")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
ds.Spec.Template.Spec = podSpec ds.Spec.Template.Spec = podSpec
...@@ -1909,7 +1845,7 @@ func setDaemonSetCritical(ds *apps.DaemonSet) { ...@@ -1909,7 +1845,7 @@ func setDaemonSetCritical(ds *apps.DaemonSet) {
func TestNodeShouldRunDaemonPod(t *testing.T) { func TestNodeShouldRunDaemonPod(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
var shouldCreate, wantToRun, shouldContinueRunning bool var shouldCreate, wantToRun, shouldContinueRunning bool
if utilfeature.DefaultFeatureGate.Enabled(features.ScheduleDaemonSetPods) { if utilfeature.DefaultFeatureGate.Enabled(features.ScheduleDaemonSetPods) {
shouldCreate = true shouldCreate = true
...@@ -2236,7 +2172,7 @@ func TestNodeShouldRunDaemonPod(t *testing.T) { ...@@ -2236,7 +2172,7 @@ func TestNodeShouldRunDaemonPod(t *testing.T) {
func TestUpdateNode(t *testing.T) { func TestUpdateNode(t *testing.T) {
var enqueued bool var enqueued bool
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
cases := []struct { cases := []struct {
test string test string
newNode *v1.Node newNode *v1.Node
...@@ -2545,7 +2481,7 @@ func TestDeleteNoDaemonPod(t *testing.T) { ...@@ -2545,7 +2481,7 @@ func TestDeleteNoDaemonPod(t *testing.T) {
func TestGetNodesToDaemonPods(t *testing.T) { func TestGetNodesToDaemonPods(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo") ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
...@@ -2611,7 +2547,7 @@ func TestGetNodesToDaemonPods(t *testing.T) { ...@@ -2611,7 +2547,7 @@ func TestGetNodesToDaemonPods(t *testing.T) {
func TestAddNode(t *testing.T) { func TestAddNode(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
manager, _, _, err := newTestController() manager, _, _, err := newTestController()
if err != nil { if err != nil {
t.Fatalf("error creating DaemonSets controller: %v", err) t.Fatalf("error creating DaemonSets controller: %v", err)
...@@ -2640,7 +2576,7 @@ func TestAddNode(t *testing.T) { ...@@ -2640,7 +2576,7 @@ func TestAddNode(t *testing.T) {
func TestAddPod(t *testing.T) { func TestAddPod(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
manager, _, _, err := newTestController() manager, _, _, err := newTestController()
if err != nil { if err != nil {
...@@ -2686,7 +2622,7 @@ func TestAddPod(t *testing.T) { ...@@ -2686,7 +2622,7 @@ func TestAddPod(t *testing.T) {
func TestAddPodOrphan(t *testing.T) { func TestAddPodOrphan(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
manager, _, _, err := newTestController() manager, _, _, err := newTestController()
if err != nil { if err != nil {
...@@ -2718,7 +2654,7 @@ func TestAddPodOrphan(t *testing.T) { ...@@ -2718,7 +2654,7 @@ func TestAddPodOrphan(t *testing.T) {
func TestUpdatePod(t *testing.T) { func TestUpdatePod(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
manager, _, _, err := newTestController() manager, _, _, err := newTestController()
if err != nil { if err != nil {
...@@ -2768,7 +2704,7 @@ func TestUpdatePod(t *testing.T) { ...@@ -2768,7 +2704,7 @@ func TestUpdatePod(t *testing.T) {
func TestUpdatePodOrphanSameLabels(t *testing.T) { func TestUpdatePodOrphanSameLabels(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
manager, _, _, err := newTestController() manager, _, _, err := newTestController()
...@@ -2795,7 +2731,7 @@ func TestUpdatePodOrphanSameLabels(t *testing.T) { ...@@ -2795,7 +2731,7 @@ func TestUpdatePodOrphanSameLabels(t *testing.T) {
func TestUpdatePodOrphanWithNewLabels(t *testing.T) { func TestUpdatePodOrphanWithNewLabels(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
manager, _, _, err := newTestController() manager, _, _, err := newTestController()
...@@ -2826,7 +2762,7 @@ func TestUpdatePodOrphanWithNewLabels(t *testing.T) { ...@@ -2826,7 +2762,7 @@ func TestUpdatePodOrphanWithNewLabels(t *testing.T) {
func TestUpdatePodChangeControllerRef(t *testing.T) { func TestUpdatePodChangeControllerRef(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo") ds := newDaemonSet("foo")
...@@ -2854,7 +2790,7 @@ func TestUpdatePodChangeControllerRef(t *testing.T) { ...@@ -2854,7 +2790,7 @@ func TestUpdatePodChangeControllerRef(t *testing.T) {
func TestUpdatePodControllerRefRemoved(t *testing.T) { func TestUpdatePodControllerRefRemoved(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
manager, _, _, err := newTestController() manager, _, _, err := newTestController()
...@@ -2882,7 +2818,7 @@ func TestUpdatePodControllerRefRemoved(t *testing.T) { ...@@ -2882,7 +2818,7 @@ func TestUpdatePodControllerRefRemoved(t *testing.T) {
func TestDeletePod(t *testing.T) { func TestDeletePod(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
manager, _, _, err := newTestController() manager, _, _, err := newTestController()
...@@ -2929,7 +2865,7 @@ func TestDeletePod(t *testing.T) { ...@@ -2929,7 +2865,7 @@ func TestDeletePod(t *testing.T) {
func TestDeletePodOrphan(t *testing.T) { func TestDeletePodOrphan(t *testing.T) {
for _, f := range []bool{true, false} { for _, f := range []bool{true, false} {
setFeatureGate(t, features.ScheduleDaemonSetPods, f) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
manager, _, _, err := newTestController() manager, _, _, err := newTestController()
......
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package daemon
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -39,7 +39,10 @@ filegroup( ...@@ -39,7 +39,10 @@ filegroup(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = ["daemonset_util_test.go"], srcs = [
"daemonset_util_test.go",
"main_test.go",
],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/api/testapi:go_default_library", "//pkg/api/testapi:go_default_library",
...@@ -50,5 +53,6 @@ go_test( ...@@ -50,5 +53,6 @@ go_test(
"//staging/src/k8s.io/api/extensions/v1beta1:go_default_library", "//staging/src/k8s.io/api/extensions/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature: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",
], ],
) )
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package util
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
package(default_visibility = ["//visibility:public"]) package(default_visibility = ["//visibility:public"])
load( load("@io_bazel_rules_go//go:def.bzl", "go_library")
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library( go_library(
name = "go_default_library", name = "go_default_library",
......
...@@ -70,6 +70,7 @@ go_test( ...@@ -70,6 +70,7 @@ go_test(
"delete_test.go", "delete_test.go",
"framework_test.go", "framework_test.go",
"index_test.go", "index_test.go",
"main_test.go",
"provision_test.go", "provision_test.go",
"pv_controller_test.go", "pv_controller_test.go",
"recycle_test.go", "recycle_test.go",
...@@ -82,6 +83,7 @@ go_test( ...@@ -82,6 +83,7 @@ go_test(
"//pkg/api/testapi:go_default_library", "//pkg/api/testapi:go_default_library",
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/controller:go_default_library", "//pkg/controller:go_default_library",
"//pkg/features:go_default_library",
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/recyclerclient:go_default_library", "//pkg/volume/util/recyclerclient:go_default_library",
...@@ -96,6 +98,7 @@ go_test( ...@@ -96,6 +98,7 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature: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/informers:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
......
...@@ -639,9 +639,6 @@ func TestSync(t *testing.T) { ...@@ -639,9 +639,6 @@ func TestSync(t *testing.T) {
}, },
} }
utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true")
defer utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false")
runSyncTests(t, tests, []*storage.StorageClass{ runSyncTests(t, tests, []*storage.StorageClass{
{ {
ObjectMeta: metav1.ObjectMeta{Name: classWait}, ObjectMeta: metav1.ObjectMeta{Name: classWait},
......
...@@ -24,9 +24,11 @@ import ( ...@@ -24,9 +24,11 @@ import (
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
"k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/kubernetes/scheme"
ref "k8s.io/client-go/tools/reference" ref "k8s.io/client-go/tools/reference"
"k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
) )
...@@ -1207,7 +1209,7 @@ func TestAlphaFilteringVolumeModes(t *testing.T) { ...@@ -1207,7 +1209,7 @@ func TestAlphaFilteringVolumeModes(t *testing.T) {
toggleFeature(false, "BlockVolume", t) toggleFeature(false, "BlockVolume", t)
} }
func TestAlphaStorageObjectInUseProtectionFiltering(t *testing.T) { func TestStorageObjectInUseProtectionFiltering(t *testing.T) {
pv := &v1.PersistentVolume{ pv := &v1.PersistentVolume{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "pv1", Name: "pv1",
...@@ -1271,17 +1273,19 @@ func TestAlphaStorageObjectInUseProtectionFiltering(t *testing.T) { ...@@ -1271,17 +1273,19 @@ func TestAlphaStorageObjectInUseProtectionFiltering(t *testing.T) {
} }
for name, testCase := range satisfyingTestCases { for name, testCase := range satisfyingTestCases {
toggleFeature(testCase.enableStorageObjectInUseProtection, "StorageObjectInUseProtection", t) t.Run(name, func(t *testing.T) {
err := checkVolumeSatisfyClaim(testCase.vol, testCase.pvc) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StorageObjectInUseProtection, testCase.enableStorageObjectInUseProtection)()
// expected to match but got an error
if err != nil && testCase.isExpectedMatch {
t.Errorf("%s: expected to match but got an error: %v", name, err)
}
// not expected to match but did
if err == nil && !testCase.isExpectedMatch {
t.Errorf("%s: not expected to match but did", name)
}
err := checkVolumeSatisfyClaim(testCase.vol, testCase.pvc)
// expected to match but got an error
if err != nil && testCase.isExpectedMatch {
t.Errorf("%s: expected to match but got an error: %v", name, err)
}
// not expected to match but did
if err == nil && !testCase.isExpectedMatch {
t.Errorf("%s: not expected to match but did", name)
}
})
} }
filteringTestCases := map[string]struct { filteringTestCases := map[string]struct {
...@@ -1316,26 +1320,26 @@ func TestAlphaStorageObjectInUseProtectionFiltering(t *testing.T) { ...@@ -1316,26 +1320,26 @@ func TestAlphaStorageObjectInUseProtectionFiltering(t *testing.T) {
}, },
} }
for name, testCase := range filteringTestCases { for name, testCase := range filteringTestCases {
toggleFeature(testCase.enableStorageObjectInUseProtection, "StorageObjectInUseProtection", t) t.Run(name, func(t *testing.T) {
pvmatch, err := testCase.vol.findBestMatchForClaim(testCase.pvc, false) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StorageObjectInUseProtection, testCase.enableStorageObjectInUseProtection)()
// expected to match but either got an error or no returned pvmatch
if pvmatch == nil && testCase.isExpectedMatch { pvmatch, err := testCase.vol.findBestMatchForClaim(testCase.pvc, false)
t.Errorf("Unexpected failure for testcase, no matching volume: %s", name) // expected to match but either got an error or no returned pvmatch
} if pvmatch == nil && testCase.isExpectedMatch {
if err != nil && testCase.isExpectedMatch { t.Errorf("Unexpected failure for testcase, no matching volume: %s", name)
t.Errorf("Unexpected failure for testcase: %s - %+v", name, err) }
} if err != nil && testCase.isExpectedMatch {
// expected to not match but either got an error or a returned pvmatch t.Errorf("Unexpected failure for testcase: %s - %+v", name, err)
if pvmatch != nil && !testCase.isExpectedMatch { }
t.Errorf("Unexpected failure for testcase, expected no matching volume: %s", name) // expected to not match but either got an error or a returned pvmatch
} if pvmatch != nil && !testCase.isExpectedMatch {
if err != nil && !testCase.isExpectedMatch { t.Errorf("Unexpected failure for testcase, expected no matching volume: %s", name)
t.Errorf("Unexpected failure for testcase: %s - %+v", name, err) }
} if err != nil && !testCase.isExpectedMatch {
t.Errorf("Unexpected failure for testcase: %s - %+v", name, err)
}
})
} }
// make sure feature gate is turned off
toggleFeature(false, "StorageObjectInUseProtection", t)
} }
func TestFindingPreboundVolumes(t *testing.T) { func TestFindingPreboundVolumes(t *testing.T) {
......
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package persistentvolume
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -34,6 +34,7 @@ var class2Parameters = map[string]string{ ...@@ -34,6 +34,7 @@ var class2Parameters = map[string]string{
"param2": "value2", "param2": "value2",
} }
var deleteReclaimPolicy = v1.PersistentVolumeReclaimDelete var deleteReclaimPolicy = v1.PersistentVolumeReclaimDelete
var modeImmediate = storage.VolumeBindingImmediate
var storageClasses = []*storage.StorageClass{ var storageClasses = []*storage.StorageClass{
{ {
TypeMeta: metav1.TypeMeta{ TypeMeta: metav1.TypeMeta{
...@@ -44,9 +45,10 @@ var storageClasses = []*storage.StorageClass{ ...@@ -44,9 +45,10 @@ var storageClasses = []*storage.StorageClass{
Name: "gold", Name: "gold",
}, },
Provisioner: mockPluginName, Provisioner: mockPluginName,
Parameters: class1Parameters, Parameters: class1Parameters,
ReclaimPolicy: &deleteReclaimPolicy, ReclaimPolicy: &deleteReclaimPolicy,
VolumeBindingMode: &modeImmediate,
}, },
{ {
TypeMeta: metav1.TypeMeta{ TypeMeta: metav1.TypeMeta{
...@@ -55,9 +57,10 @@ var storageClasses = []*storage.StorageClass{ ...@@ -55,9 +57,10 @@ var storageClasses = []*storage.StorageClass{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "silver", Name: "silver",
}, },
Provisioner: mockPluginName, Provisioner: mockPluginName,
Parameters: class2Parameters, Parameters: class2Parameters,
ReclaimPolicy: &deleteReclaimPolicy, ReclaimPolicy: &deleteReclaimPolicy,
VolumeBindingMode: &modeImmediate,
}, },
{ {
TypeMeta: metav1.TypeMeta{ TypeMeta: metav1.TypeMeta{
...@@ -66,9 +69,10 @@ var storageClasses = []*storage.StorageClass{ ...@@ -66,9 +69,10 @@ var storageClasses = []*storage.StorageClass{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "external", Name: "external",
}, },
Provisioner: "vendor.com/my-volume", Provisioner: "vendor.com/my-volume",
Parameters: class1Parameters, Parameters: class1Parameters,
ReclaimPolicy: &deleteReclaimPolicy, ReclaimPolicy: &deleteReclaimPolicy,
VolumeBindingMode: &modeImmediate,
}, },
{ {
TypeMeta: metav1.TypeMeta{ TypeMeta: metav1.TypeMeta{
...@@ -77,9 +81,10 @@ var storageClasses = []*storage.StorageClass{ ...@@ -77,9 +81,10 @@ var storageClasses = []*storage.StorageClass{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "unknown-internal", Name: "unknown-internal",
}, },
Provisioner: "kubernetes.io/unknown", Provisioner: "kubernetes.io/unknown",
Parameters: class1Parameters, Parameters: class1Parameters,
ReclaimPolicy: &deleteReclaimPolicy, ReclaimPolicy: &deleteReclaimPolicy,
VolumeBindingMode: &modeImmediate,
}, },
{ {
TypeMeta: metav1.TypeMeta{ TypeMeta: metav1.TypeMeta{
...@@ -88,10 +93,11 @@ var storageClasses = []*storage.StorageClass{ ...@@ -88,10 +93,11 @@ var storageClasses = []*storage.StorageClass{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "unsupported-mountoptions", Name: "unsupported-mountoptions",
}, },
Provisioner: mockPluginName, Provisioner: mockPluginName,
Parameters: class1Parameters, Parameters: class1Parameters,
ReclaimPolicy: &deleteReclaimPolicy, ReclaimPolicy: &deleteReclaimPolicy,
MountOptions: []string{"foo"}, MountOptions: []string{"foo"},
VolumeBindingMode: &modeImmediate,
}, },
} }
......
...@@ -20,18 +20,26 @@ import ( ...@@ -20,18 +20,26 @@ import (
"testing" "testing"
"time" "time"
"k8s.io/klog"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
storagev1 "k8s.io/api/storage/v1" storagev1 "k8s.io/api/storage/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/watch" "k8s.io/apimachinery/pkg/watch"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
"k8s.io/client-go/informers" "k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/kubernetes/fake"
core "k8s.io/client-go/testing" core "k8s.io/client-go/testing"
"k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/cache"
"k8s.io/klog"
"k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/controller"
"k8s.io/kubernetes/pkg/features"
)
var (
classNotHere = "not-here"
classNoMode = "no-mode"
classImmediateMode = "immediate-mode"
classWaitMode = "wait-mode"
) )
// Test the real controller methods (add/update/delete claim/volume) with // Test the real controller methods (add/update/delete claim/volume) with
...@@ -264,16 +272,6 @@ func makeStorageClass(scName string, mode *storagev1.VolumeBindingMode) *storage ...@@ -264,16 +272,6 @@ func makeStorageClass(scName string, mode *storagev1.VolumeBindingMode) *storage
} }
func TestDelayBinding(t *testing.T) { func TestDelayBinding(t *testing.T) {
var (
classNotHere = "not-here"
classNoMode = "no-mode"
classImmediateMode = "immediate-mode"
classWaitMode = "wait-mode"
modeImmediate = storagev1.VolumeBindingImmediate
modeWait = storagev1.VolumeBindingWaitForFirstConsumer
)
tests := map[string]struct { tests := map[string]struct {
pvc *v1.PersistentVolumeClaim pvc *v1.PersistentVolumeClaim
shouldDelay bool shouldDelay bool
...@@ -325,22 +323,8 @@ func TestDelayBinding(t *testing.T) { ...@@ -325,22 +323,8 @@ func TestDelayBinding(t *testing.T) {
} }
} }
// When volumeScheduling feature gate is disabled, should always be delayed
name := "volumeScheduling-feature-disabled"
shouldDelay, err := ctrl.shouldDelayBinding(makePVCClass(&classWaitMode, false))
if err != nil {
t.Errorf("Test %q returned error: %v", name, err)
}
if shouldDelay {
t.Errorf("Test %q returned true, expected false", name)
}
// Enable volumeScheduling feature gate
utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true")
defer utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false")
for name, test := range tests { for name, test := range tests {
shouldDelay, err = ctrl.shouldDelayBinding(test.pvc) shouldDelay, err := ctrl.shouldDelayBinding(test.pvc)
if err != nil && !test.shouldFail { if err != nil && !test.shouldFail {
t.Errorf("Test %q returned error: %v", name, err) t.Errorf("Test %q returned error: %v", name, err)
} }
...@@ -352,3 +336,24 @@ func TestDelayBinding(t *testing.T) { ...@@ -352,3 +336,24 @@ func TestDelayBinding(t *testing.T) {
} }
} }
} }
func TestDelayBindingDisabled(t *testing.T) {
// When volumeScheduling feature gate is disabled, should always be immediate
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, false)()
client := &fake.Clientset{}
informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
classInformer := informerFactory.Storage().V1().StorageClasses()
ctrl := &PersistentVolumeController{
classLister: classInformer.Lister(),
}
name := "volumeScheduling-feature-disabled"
shouldDelay, err := ctrl.shouldDelayBinding(makePVCClass(&classWaitMode, false))
if err != nil {
t.Errorf("Test %q returned error: %v", name, err)
}
if shouldDelay {
t.Errorf("Test %q returned true, expected false", name)
}
}
...@@ -30,7 +30,6 @@ import ( ...@@ -30,7 +30,6 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/diff" "k8s.io/apimachinery/pkg/util/diff"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/informers" "k8s.io/client-go/informers"
clientset "k8s.io/client-go/kubernetes" clientset "k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/kubernetes/fake"
...@@ -728,10 +727,6 @@ func TestFindPodVolumesWithoutProvisioning(t *testing.T) { ...@@ -728,10 +727,6 @@ func TestFindPodVolumesWithoutProvisioning(t *testing.T) {
}, },
} }
// Set feature gate
utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true")
defer utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false")
testNode := &v1.Node{ testNode := &v1.Node{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "node1", Name: "node1",
...@@ -844,10 +839,6 @@ func TestFindPodVolumesWithProvisioning(t *testing.T) { ...@@ -844,10 +839,6 @@ func TestFindPodVolumesWithProvisioning(t *testing.T) {
}, },
} }
// Set VolumeScheduling feature gate
utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true")
defer utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false")
testNode := &v1.Node{ testNode := &v1.Node{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "node1", Name: "node1",
...@@ -1426,10 +1417,6 @@ func TestBindPodVolumes(t *testing.T) { ...@@ -1426,10 +1417,6 @@ func TestBindPodVolumes(t *testing.T) {
} }
func TestFindAssumeVolumes(t *testing.T) { func TestFindAssumeVolumes(t *testing.T) {
// Set feature gate
utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true")
defer utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false")
// Test case // Test case
podPVCs := []*v1.PersistentVolumeClaim{unboundPVC} podPVCs := []*v1.PersistentVolumeClaim{unboundPVC}
pvs := []*v1.PersistentVolume{pvNode2, pvNode1a, pvNode1c} pvs := []*v1.PersistentVolume{pvNode2, pvNode1a, pvNode1c}
......
...@@ -166,6 +166,7 @@ go_test( ...@@ -166,6 +166,7 @@ go_test(
"kubelet_resources_test.go", "kubelet_resources_test.go",
"kubelet_test.go", "kubelet_test.go",
"kubelet_volumes_test.go", "kubelet_volumes_test.go",
"main_test.go",
"oom_watcher_test.go", "oom_watcher_test.go",
"pod_container_deletor_test.go", "pod_container_deletor_test.go",
"pod_workers_test.go", "pod_workers_test.go",
......
...@@ -50,16 +50,19 @@ go_test( ...@@ -50,16 +50,19 @@ go_test(
name = "go_default_test", name = "go_default_test",
srcs = [ srcs = [
"cadvisor_linux_test.go", "cadvisor_linux_test.go",
"main_test.go",
"util_test.go", "util_test.go",
], ],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = select({ deps = [
"//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",
] + select({
"@io_bazel_rules_go//go/platform:linux": [ "@io_bazel_rules_go//go/platform:linux": [
"//pkg/apis/core/v1/helper:go_default_library", "//pkg/apis/core/v1/helper:go_default_library",
"//pkg/features:go_default_library",
"//pkg/kubelet/types:go_default_library", "//pkg/kubelet/types:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//vendor/github.com/google/cadvisor/info/v1:go_default_library", "//vendor/github.com/google/cadvisor/info/v1:go_default_library",
"//vendor/github.com/google/cadvisor/metrics:go_default_library", "//vendor/github.com/google/cadvisor/metrics:go_default_library",
"//vendor/github.com/stretchr/testify/assert:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library",
......
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cadvisor
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -19,14 +19,15 @@ limitations under the License. ...@@ -19,14 +19,15 @@ limitations under the License.
package cadvisor package cadvisor
import ( import (
"fmt" "testing"
info "github.com/google/cadvisor/info/v1" info "github.com/google/cadvisor/info/v1"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper" v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
"testing"
) )
func TestCapacityFromMachineInfo(t *testing.T) { func TestCapacityFromMachineInfo(t *testing.T) {
...@@ -42,7 +43,7 @@ func TestCapacityFromMachineInfo(t *testing.T) { ...@@ -42,7 +43,7 @@ func TestCapacityFromMachineInfo(t *testing.T) {
} }
// enable the features.HugePages // enable the features.HugePages
utilfeature.DefaultFeatureGate.Set(fmt.Sprintf("%s=true", features.HugePages)) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HugePages, true)()
resourceList := CapacityFromMachineInfo(machineInfo) resourceList := CapacityFromMachineInfo(machineInfo)
......
...@@ -11,6 +11,7 @@ go_test( ...@@ -11,6 +11,7 @@ go_test(
srcs = [ srcs = [
"eviction_manager_test.go", "eviction_manager_test.go",
"helpers_test.go", "helpers_test.go",
"main_test.go",
"memory_threshold_notifier_test.go", "memory_threshold_notifier_test.go",
"mock_threshold_notifier_test.go", "mock_threshold_notifier_test.go",
], ],
...@@ -28,6 +29,7 @@ go_test( ...@@ -28,6 +29,7 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/clock:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/clock:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature: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/tools/record:go_default_library", "//staging/src/k8s.io/client-go/tools/record:go_default_library",
"//vendor/github.com/stretchr/testify/mock:go_default_library", "//vendor/github.com/stretchr/testify/mock:go_default_library",
], ],
......
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package eviction
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -34,6 +34,7 @@ import ( ...@@ -34,6 +34,7 @@ import (
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
core "k8s.io/client-go/testing" core "k8s.io/client-go/testing"
"k8s.io/client-go/tools/record" "k8s.io/client-go/tools/record"
...@@ -42,6 +43,7 @@ import ( ...@@ -42,6 +43,7 @@ import (
// to "v1"? // to "v1"?
_ "k8s.io/kubernetes/pkg/apis/core/install" _ "k8s.io/kubernetes/pkg/apis/core/install"
"k8s.io/kubernetes/pkg/features"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
containertest "k8s.io/kubernetes/pkg/kubelet/container/testing" containertest "k8s.io/kubernetes/pkg/kubelet/container/testing"
"k8s.io/kubernetes/pkg/kubelet/server/portforward" "k8s.io/kubernetes/pkg/kubelet/server/portforward"
...@@ -91,9 +93,7 @@ func TestDisabledSubpath(t *testing.T) { ...@@ -91,9 +93,7 @@ func TestDisabledSubpath(t *testing.T) {
}, },
} }
utilfeature.DefaultFeatureGate.Set("VolumeSubpath=false") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeSubpath, false)()
defer utilfeature.DefaultFeatureGate.Set("VolumeSubpath=true")
for name, test := range cases { for name, test := range cases {
_, _, err := makeMounts(&pod, "/pod", &test.container, "fakepodname", "", "", podVolumes, fm, nil) _, _, err := makeMounts(&pod, "/pod", &test.container, "fakepodname", "", "", podVolumes, fm, nil)
if err != nil && !test.expectError { if err != nil && !test.expectError {
......
...@@ -95,6 +95,7 @@ go_test( ...@@ -95,6 +95,7 @@ go_test(
"kuberuntime_sandbox_test.go", "kuberuntime_sandbox_test.go",
"labels_test.go", "labels_test.go",
"legacy_test.go", "legacy_test.go",
"main_test.go",
"security_context_test.go", "security_context_test.go",
], ],
embed = [":go_default_library"], embed = [":go_default_library"],
......
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package kuberuntime
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package kubelet
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -21,15 +21,20 @@ go_library( ...@@ -21,15 +21,20 @@ go_library(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = ["dns_test.go"], srcs = [
"dns_test.go",
"main_test.go",
],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/features:go_default_library",
"//pkg/kubelet/apis/cri/runtime/v1alpha2:go_default_library", "//pkg/kubelet/apis/cri/runtime/v1alpha2:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature: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/tools/record:go_default_library", "//staging/src/k8s.io/client-go/tools/record:go_default_library",
"//vendor/github.com/stretchr/testify/assert:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library",
"//vendor/github.com/stretchr/testify/require:go_default_library", "//vendor/github.com/stretchr/testify/require:go_default_library",
......
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package dns
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -41,16 +41,21 @@ filegroup( ...@@ -41,16 +41,21 @@ filegroup(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = ["preemption_test.go"], srcs = [
"main_test.go",
"preemption_test.go",
],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/apis/scheduling:go_default_library", "//pkg/apis/scheduling:go_default_library",
"//pkg/features:go_default_library",
"//pkg/kubelet/types:go_default_library", "//pkg/kubelet/types:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature: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/tools/record:go_default_library", "//staging/src/k8s.io/client-go/tools/record:go_default_library",
], ],
) )
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package preemption
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -24,9 +24,11 @@ import ( ...@@ -24,9 +24,11 @@ import (
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
"k8s.io/client-go/tools/record" "k8s.io/client-go/tools/record"
kubeapi "k8s.io/kubernetes/pkg/apis/core" kubeapi "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/apis/scheduling" "k8s.io/kubernetes/pkg/apis/scheduling"
"k8s.io/kubernetes/pkg/features"
kubetypes "k8s.io/kubernetes/pkg/kubelet/types" kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
) )
...@@ -89,9 +91,7 @@ func getTestCriticalPodAdmissionHandler(podProvider *fakePodProvider, podKiller ...@@ -89,9 +91,7 @@ func getTestCriticalPodAdmissionHandler(podProvider *fakePodProvider, podKiller
} }
func TestEvictPodsToFreeRequests(t *testing.T) { func TestEvictPodsToFreeRequests(t *testing.T) {
if err := utilfeature.DefaultFeatureGate.Set("ExperimentalCriticalPodAnnotation=true"); err != nil { defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExperimentalCriticalPodAnnotation, true)()
t.Errorf("failed to set ExperimentalCriticalPodAnnotation to true: %v", err)
}
type testRun struct { type testRun struct {
testName string testName string
inputPods []*v1.Pod inputPods []*v1.Pod
...@@ -159,6 +159,7 @@ func BenchmarkGetPodsToPreempt(t *testing.B) { ...@@ -159,6 +159,7 @@ func BenchmarkGetPodsToPreempt(t *testing.B) {
} }
func TestGetPodsToPreempt(t *testing.T) { func TestGetPodsToPreempt(t *testing.T) {
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExperimentalCriticalPodAnnotation, true)()
type testRun struct { type testRun struct {
testName string testName string
preemptor *v1.Pod preemptor *v1.Pod
......
...@@ -32,15 +32,18 @@ go_test( ...@@ -32,15 +32,18 @@ go_test(
name = "go_default_test", name = "go_default_test",
srcs = [ srcs = [
"labels_test.go", "labels_test.go",
"main_test.go",
"pod_status_test.go", "pod_status_test.go",
"pod_update_test.go", "pod_update_test.go",
"types_test.go", "types_test.go",
], ],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/features:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature: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/stretchr/testify/assert:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library",
"//vendor/github.com/stretchr/testify/require:go_default_library", "//vendor/github.com/stretchr/testify/require:go_default_library",
], ],
......
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package types
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -24,6 +24,8 @@ import ( ...@@ -24,6 +24,8 @@ import (
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
"k8s.io/kubernetes/pkg/features"
) )
func TestGetValidatedSources(t *testing.T) { func TestGetValidatedSources(t *testing.T) {
...@@ -116,9 +118,7 @@ func TestString(t *testing.T) { ...@@ -116,9 +118,7 @@ func TestString(t *testing.T) {
} }
func TestIsCriticalPod(t *testing.T) { func TestIsCriticalPod(t *testing.T) {
if err := utilfeature.DefaultFeatureGate.Set("ExperimentalCriticalPodAnnotation=true"); err != nil { defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExperimentalCriticalPodAnnotation, true)()
t.Errorf("failed to set ExperimentalCriticalPodAnnotation to true: %v", err)
}
cases := []struct { cases := []struct {
pod v1.Pod pod v1.Pod
expected bool expected bool
......
...@@ -47,7 +47,10 @@ filegroup( ...@@ -47,7 +47,10 @@ filegroup(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = ["desired_state_of_world_populator_test.go"], srcs = [
"desired_state_of_world_populator_test.go",
"main_test.go",
],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/features:go_default_library", "//pkg/features:go_default_library",
...@@ -67,6 +70,7 @@ go_test( ...@@ -67,6 +70,7 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1: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:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature: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/kubernetes/fake:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
"//staging/src/k8s.io/client-go/testing:go_default_library", "//staging/src/k8s.io/client-go/testing:go_default_library",
], ],
......
...@@ -27,6 +27,7 @@ import ( ...@@ -27,6 +27,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
"k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/kubernetes/fake"
core "k8s.io/client-go/testing" core "k8s.io/client-go/testing"
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
...@@ -151,7 +152,7 @@ func TestFindAndAddNewPods_FindAndRemoveDeletedPods(t *testing.T) { ...@@ -151,7 +152,7 @@ func TestFindAndAddNewPods_FindAndRemoveDeletedPods(t *testing.T) {
func TestFindAndAddNewPods_FindAndRemoveDeletedPods_Valid_Block_VolumeDevices(t *testing.T) { func TestFindAndAddNewPods_FindAndRemoveDeletedPods_Valid_Block_VolumeDevices(t *testing.T) {
// Enable BlockVolume feature gate // Enable BlockVolume feature gate
utilfeature.DefaultFeatureGate.Set("BlockVolume=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
// create dswp // create dswp
mode := v1.PersistentVolumeBlock mode := v1.PersistentVolumeBlock
...@@ -256,9 +257,6 @@ func TestFindAndAddNewPods_FindAndRemoveDeletedPods_Valid_Block_VolumeDevices(t ...@@ -256,9 +257,6 @@ func TestFindAndAddNewPods_FindAndRemoveDeletedPods_Valid_Block_VolumeDevices(t
expectedVolumeName) expectedVolumeName)
} }
} }
// Rollback feature gate to false.
utilfeature.DefaultFeatureGate.Set("BlockVolume=false")
} }
func TestCreateVolumeSpec_Valid_File_VolumeMounts(t *testing.T) { func TestCreateVolumeSpec_Valid_File_VolumeMounts(t *testing.T) {
...@@ -309,7 +307,7 @@ func TestCreateVolumeSpec_Valid_File_VolumeMounts(t *testing.T) { ...@@ -309,7 +307,7 @@ func TestCreateVolumeSpec_Valid_File_VolumeMounts(t *testing.T) {
func TestCreateVolumeSpec_Valid_Block_VolumeDevices(t *testing.T) { func TestCreateVolumeSpec_Valid_Block_VolumeDevices(t *testing.T) {
// Enable BlockVolume feature gate // Enable BlockVolume feature gate
utilfeature.DefaultFeatureGate.Set("BlockVolume=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
// create dswp // create dswp
mode := v1.PersistentVolumeBlock mode := v1.PersistentVolumeBlock
...@@ -354,14 +352,11 @@ func TestCreateVolumeSpec_Valid_Block_VolumeDevices(t *testing.T) { ...@@ -354,14 +352,11 @@ func TestCreateVolumeSpec_Valid_Block_VolumeDevices(t *testing.T) {
if volumeSpec == nil || err != nil { if volumeSpec == nil || err != nil {
t.Fatalf("Failed to create volumeSpec with combination of block mode and volumeDevices. err: %v", err) t.Fatalf("Failed to create volumeSpec with combination of block mode and volumeDevices. err: %v", err)
} }
// Rollback feature gate to false.
utilfeature.DefaultFeatureGate.Set("BlockVolume=false")
} }
func TestCreateVolumeSpec_Invalid_File_VolumeDevices(t *testing.T) { func TestCreateVolumeSpec_Invalid_File_VolumeDevices(t *testing.T) {
// Enable BlockVolume feature gate // Enable BlockVolume feature gate
utilfeature.DefaultFeatureGate.Set("BlockVolume=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
// create dswp // create dswp
mode := v1.PersistentVolumeFilesystem mode := v1.PersistentVolumeFilesystem
...@@ -406,14 +401,11 @@ func TestCreateVolumeSpec_Invalid_File_VolumeDevices(t *testing.T) { ...@@ -406,14 +401,11 @@ func TestCreateVolumeSpec_Invalid_File_VolumeDevices(t *testing.T) {
if volumeSpec != nil || err == nil { if volumeSpec != nil || err == nil {
t.Fatalf("Unexpected volumeMode and volumeMounts/volumeDevices combination is accepted") t.Fatalf("Unexpected volumeMode and volumeMounts/volumeDevices combination is accepted")
} }
// Rollback feature gate to false.
utilfeature.DefaultFeatureGate.Set("BlockVolume=false")
} }
func TestCreateVolumeSpec_Invalid_Block_VolumeMounts(t *testing.T) { func TestCreateVolumeSpec_Invalid_Block_VolumeMounts(t *testing.T) {
// Enable BlockVolume feature gate // Enable BlockVolume feature gate
utilfeature.DefaultFeatureGate.Set("BlockVolume=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
// create dswp // create dswp
mode := v1.PersistentVolumeBlock mode := v1.PersistentVolumeBlock
...@@ -458,9 +450,6 @@ func TestCreateVolumeSpec_Invalid_Block_VolumeMounts(t *testing.T) { ...@@ -458,9 +450,6 @@ func TestCreateVolumeSpec_Invalid_Block_VolumeMounts(t *testing.T) {
if volumeSpec != nil || err == nil { if volumeSpec != nil || err == nil {
t.Fatalf("Unexpected volumeMode and volumeMounts/volumeDevices combination is accepted") t.Fatalf("Unexpected volumeMode and volumeMounts/volumeDevices combination is accepted")
} }
// Rollback feature gate to false.
utilfeature.DefaultFeatureGate.Set("BlockVolume=false")
} }
func TestCheckVolumeFSResize(t *testing.T) { func TestCheckVolumeFSResize(t *testing.T) {
...@@ -510,7 +499,7 @@ func TestCheckVolumeFSResize(t *testing.T) { ...@@ -510,7 +499,7 @@ func TestCheckVolumeFSResize(t *testing.T) {
reconcileASW(fakeASW, fakeDSW, t) reconcileASW(fakeASW, fakeDSW, t)
// No resize request for volume, volumes in ASW shouldn't be marked as fsResizeRequired. // No resize request for volume, volumes in ASW shouldn't be marked as fsResizeRequired.
setExpandOnlinePersistentVolumesFeatureGate("true", t) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExpandInUsePersistentVolumes, true)()
resizeRequiredVolumes := reprocess(dswp, uniquePodName, fakeDSW, fakeASW) resizeRequiredVolumes := reprocess(dswp, uniquePodName, fakeDSW, fakeASW)
if len(resizeRequiredVolumes) > 0 { if len(resizeRequiredVolumes) > 0 {
t.Fatalf("No resize request for any volumes, but found resize required volumes in ASW: %v", resizeRequiredVolumes) t.Fatalf("No resize request for any volumes, but found resize required volumes in ASW: %v", resizeRequiredVolumes)
...@@ -521,14 +510,14 @@ func TestCheckVolumeFSResize(t *testing.T) { ...@@ -521,14 +510,14 @@ func TestCheckVolumeFSResize(t *testing.T) {
pvc.Spec.Resources.Requests = volumeCapacity(2) pvc.Spec.Resources.Requests = volumeCapacity(2)
// Disable the feature gate, so volume shouldn't be marked as fsResizeRequired. // Disable the feature gate, so volume shouldn't be marked as fsResizeRequired.
setExpandOnlinePersistentVolumesFeatureGate("false", t) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExpandInUsePersistentVolumes, false)()
resizeRequiredVolumes = reprocess(dswp, uniquePodName, fakeDSW, fakeASW) resizeRequiredVolumes = reprocess(dswp, uniquePodName, fakeDSW, fakeASW)
if len(resizeRequiredVolumes) > 0 { if len(resizeRequiredVolumes) > 0 {
t.Fatalf("Feature gate disabled, but found resize required volumes in ASW: %v", resizeRequiredVolumes) t.Fatalf("Feature gate disabled, but found resize required volumes in ASW: %v", resizeRequiredVolumes)
} }
// Make volume used as ReadOnly, so volume shouldn't be marked as fsResizeRequired. // Make volume used as ReadOnly, so volume shouldn't be marked as fsResizeRequired.
setExpandOnlinePersistentVolumesFeatureGate("true", t) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExpandInUsePersistentVolumes, true)()
pod.Spec.Containers[0].VolumeMounts[0].ReadOnly = true pod.Spec.Containers[0].VolumeMounts[0].ReadOnly = true
resizeRequiredVolumes = reprocess(dswp, uniquePodName, fakeDSW, fakeASW) resizeRequiredVolumes = reprocess(dswp, uniquePodName, fakeDSW, fakeASW)
if len(resizeRequiredVolumes) > 0 { if len(resizeRequiredVolumes) > 0 {
...@@ -561,13 +550,6 @@ func volumeCapacity(size int) v1.ResourceList { ...@@ -561,13 +550,6 @@ func volumeCapacity(size int) v1.ResourceList {
return v1.ResourceList{v1.ResourceStorage: resource.MustParse(fmt.Sprintf("%dGi", size))} return v1.ResourceList{v1.ResourceStorage: resource.MustParse(fmt.Sprintf("%dGi", size))}
} }
func setExpandOnlinePersistentVolumesFeatureGate(value string, t *testing.T) {
err := utilfeature.DefaultFeatureGate.Set(fmt.Sprintf("%s=%s", features.ExpandInUsePersistentVolumes, value))
if err != nil {
t.Fatalf("Set ExpandInUsePersistentVolumes feature gate to %s failed: %v", value, err)
}
}
func reconcileASW(asw cache.ActualStateOfWorld, dsw cache.DesiredStateOfWorld, t *testing.T) { func reconcileASW(asw cache.ActualStateOfWorld, dsw cache.DesiredStateOfWorld, t *testing.T) {
for _, volumeToMount := range dsw.GetVolumesToMount() { for _, volumeToMount := range dsw.GetVolumesToMount() {
err := asw.MarkVolumeAsAttached(volumeToMount.VolumeName, volumeToMount.VolumeSpec, "", "") err := asw.MarkVolumeAsAttached(volumeToMount.VolumeName, volumeToMount.VolumeSpec, "", "")
......
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package populator
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -35,7 +35,10 @@ go_library( ...@@ -35,7 +35,10 @@ go_library(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = ["reconciler_test.go"], srcs = [
"main_test.go",
"reconciler_test.go",
],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/features:go_default_library", "//pkg/features:go_default_library",
...@@ -52,6 +55,7 @@ go_test( ...@@ -52,6 +55,7 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/wait: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:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature/testing:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
"//staging/src/k8s.io/client-go/testing:go_default_library", "//staging/src/k8s.io/client-go/testing:go_default_library",
"//staging/src/k8s.io/client-go/tools/record:go_default_library", "//staging/src/k8s.io/client-go/tools/record:go_default_library",
......
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package reconciler
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -29,6 +29,7 @@ import ( ...@@ -29,6 +29,7 @@ import (
k8stypes "k8s.io/apimachinery/pkg/types" k8stypes "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
"k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/kubernetes/fake"
core "k8s.io/client-go/testing" core "k8s.io/client-go/testing"
"k8s.io/client-go/tools/record" "k8s.io/client-go/tools/record"
...@@ -439,7 +440,8 @@ func Test_Run_Positive_VolumeUnmountControllerAttachEnabled(t *testing.T) { ...@@ -439,7 +440,8 @@ func Test_Run_Positive_VolumeUnmountControllerAttachEnabled(t *testing.T) {
// no detach/teardownDevice calls. // no detach/teardownDevice calls.
func Test_Run_Positive_VolumeAttachAndMap(t *testing.T) { func Test_Run_Positive_VolumeAttachAndMap(t *testing.T) {
// Enable BlockVolume feature gate // Enable BlockVolume feature gate
utilfeature.DefaultFeatureGate.Set("BlockVolume=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
// Arrange // Arrange
volumePluginMgr, fakePlugin := volumetesting.GetTestVolumePluginMgr(t) volumePluginMgr, fakePlugin := volumetesting.GetTestVolumePluginMgr(t)
dsw := cache.NewDesiredStateOfWorld(volumePluginMgr) dsw := cache.NewDesiredStateOfWorld(volumePluginMgr)
...@@ -513,9 +515,6 @@ func Test_Run_Positive_VolumeAttachAndMap(t *testing.T) { ...@@ -513,9 +515,6 @@ func Test_Run_Positive_VolumeAttachAndMap(t *testing.T) {
1 /* expectedGetMapDeviceCallCount */, fakePlugin)) 1 /* expectedGetMapDeviceCallCount */, fakePlugin))
assert.NoError(t, volumetesting.VerifyZeroTearDownDeviceCallCount(fakePlugin)) assert.NoError(t, volumetesting.VerifyZeroTearDownDeviceCallCount(fakePlugin))
assert.NoError(t, volumetesting.VerifyZeroDetachCallCount(fakePlugin)) assert.NoError(t, volumetesting.VerifyZeroDetachCallCount(fakePlugin))
// Rollback feature gate to false.
utilfeature.DefaultFeatureGate.Set("BlockVolume=false")
} }
// Populates desiredStateOfWorld cache with one volume/pod. // Populates desiredStateOfWorld cache with one volume/pod.
...@@ -526,7 +525,8 @@ func Test_Run_Positive_VolumeAttachAndMap(t *testing.T) { ...@@ -526,7 +525,8 @@ func Test_Run_Positive_VolumeAttachAndMap(t *testing.T) {
// Verifies there are no attach/detach calls. // Verifies there are no attach/detach calls.
func Test_Run_Positive_BlockVolumeMapControllerAttachEnabled(t *testing.T) { func Test_Run_Positive_BlockVolumeMapControllerAttachEnabled(t *testing.T) {
// Enable BlockVolume feature gate // Enable BlockVolume feature gate
utilfeature.DefaultFeatureGate.Set("BlockVolume=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
// Arrange // Arrange
volumePluginMgr, fakePlugin := volumetesting.GetTestVolumePluginMgr(t) volumePluginMgr, fakePlugin := volumetesting.GetTestVolumePluginMgr(t)
dsw := cache.NewDesiredStateOfWorld(volumePluginMgr) dsw := cache.NewDesiredStateOfWorld(volumePluginMgr)
...@@ -601,9 +601,6 @@ func Test_Run_Positive_BlockVolumeMapControllerAttachEnabled(t *testing.T) { ...@@ -601,9 +601,6 @@ func Test_Run_Positive_BlockVolumeMapControllerAttachEnabled(t *testing.T) {
1 /* expectedGetMapDeviceCallCount */, fakePlugin)) 1 /* expectedGetMapDeviceCallCount */, fakePlugin))
assert.NoError(t, volumetesting.VerifyZeroTearDownDeviceCallCount(fakePlugin)) assert.NoError(t, volumetesting.VerifyZeroTearDownDeviceCallCount(fakePlugin))
assert.NoError(t, volumetesting.VerifyZeroDetachCallCount(fakePlugin)) assert.NoError(t, volumetesting.VerifyZeroDetachCallCount(fakePlugin))
// Rollback feature gate to false.
utilfeature.DefaultFeatureGate.Set("BlockVolume=false")
} }
// Populates desiredStateOfWorld cache with one volume/pod. // Populates desiredStateOfWorld cache with one volume/pod.
...@@ -614,7 +611,8 @@ func Test_Run_Positive_BlockVolumeMapControllerAttachEnabled(t *testing.T) { ...@@ -614,7 +611,8 @@ func Test_Run_Positive_BlockVolumeMapControllerAttachEnabled(t *testing.T) {
// Verifies one detach/teardownDevice calls are issued. // Verifies one detach/teardownDevice calls are issued.
func Test_Run_Positive_BlockVolumeAttachMapUnmapDetach(t *testing.T) { func Test_Run_Positive_BlockVolumeAttachMapUnmapDetach(t *testing.T) {
// Enable BlockVolume feature gate // Enable BlockVolume feature gate
utilfeature.DefaultFeatureGate.Set("BlockVolume=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
// Arrange // Arrange
volumePluginMgr, fakePlugin := volumetesting.GetTestVolumePluginMgr(t) volumePluginMgr, fakePlugin := volumetesting.GetTestVolumePluginMgr(t)
dsw := cache.NewDesiredStateOfWorld(volumePluginMgr) dsw := cache.NewDesiredStateOfWorld(volumePluginMgr)
...@@ -698,9 +696,6 @@ func Test_Run_Positive_BlockVolumeAttachMapUnmapDetach(t *testing.T) { ...@@ -698,9 +696,6 @@ func Test_Run_Positive_BlockVolumeAttachMapUnmapDetach(t *testing.T) {
1 /* expectedTearDownDeviceCallCount */, fakePlugin)) 1 /* expectedTearDownDeviceCallCount */, fakePlugin))
assert.NoError(t, volumetesting.VerifyDetachCallCount( assert.NoError(t, volumetesting.VerifyDetachCallCount(
1 /* expectedDetachCallCount */, fakePlugin)) 1 /* expectedDetachCallCount */, fakePlugin))
// Rollback feature gate to false.
utilfeature.DefaultFeatureGate.Set("BlockVolume=false")
} }
// Populates desiredStateOfWorld cache with one volume/pod. // Populates desiredStateOfWorld cache with one volume/pod.
...@@ -712,7 +707,8 @@ func Test_Run_Positive_BlockVolumeAttachMapUnmapDetach(t *testing.T) { ...@@ -712,7 +707,8 @@ func Test_Run_Positive_BlockVolumeAttachMapUnmapDetach(t *testing.T) {
// Verifies there are no attach/detach calls made. // Verifies there are no attach/detach calls made.
func Test_Run_Positive_VolumeUnmapControllerAttachEnabled(t *testing.T) { func Test_Run_Positive_VolumeUnmapControllerAttachEnabled(t *testing.T) {
// Enable BlockVolume feature gate // Enable BlockVolume feature gate
utilfeature.DefaultFeatureGate.Set("BlockVolume=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
// Arrange // Arrange
volumePluginMgr, fakePlugin := volumetesting.GetTestVolumePluginMgr(t) volumePluginMgr, fakePlugin := volumetesting.GetTestVolumePluginMgr(t)
dsw := cache.NewDesiredStateOfWorld(volumePluginMgr) dsw := cache.NewDesiredStateOfWorld(volumePluginMgr)
...@@ -797,9 +793,6 @@ func Test_Run_Positive_VolumeUnmapControllerAttachEnabled(t *testing.T) { ...@@ -797,9 +793,6 @@ func Test_Run_Positive_VolumeUnmapControllerAttachEnabled(t *testing.T) {
assert.NoError(t, volumetesting.VerifyTearDownDeviceCallCount( assert.NoError(t, volumetesting.VerifyTearDownDeviceCallCount(
1 /* expectedTearDownDeviceCallCount */, fakePlugin)) 1 /* expectedTearDownDeviceCallCount */, fakePlugin))
assert.NoError(t, volumetesting.VerifyZeroDetachCallCount(fakePlugin)) assert.NoError(t, volumetesting.VerifyZeroDetachCallCount(fakePlugin))
// Rollback feature gate to false.
utilfeature.DefaultFeatureGate.Set("BlockVolume=false")
} }
func Test_GenerateMapVolumeFunc_Plugin_Not_Found(t *testing.T) { func Test_GenerateMapVolumeFunc_Plugin_Not_Found(t *testing.T) {
...@@ -821,7 +814,8 @@ func Test_GenerateMapVolumeFunc_Plugin_Not_Found(t *testing.T) { ...@@ -821,7 +814,8 @@ func Test_GenerateMapVolumeFunc_Plugin_Not_Found(t *testing.T) {
} }
// Enable BlockVolume feature gate // Enable BlockVolume feature gate
utilfeature.DefaultFeatureGate.Set("BlockVolume=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
for name, tc := range testCases { for name, tc := range testCases {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
volumePluginMgr := &volume.VolumePluginMgr{} volumePluginMgr := &volume.VolumePluginMgr{}
...@@ -853,8 +847,6 @@ func Test_GenerateMapVolumeFunc_Plugin_Not_Found(t *testing.T) { ...@@ -853,8 +847,6 @@ func Test_GenerateMapVolumeFunc_Plugin_Not_Found(t *testing.T) {
} }
}) })
} }
// Rollback feature gate to false.
utilfeature.DefaultFeatureGate.Set("BlockVolume=false")
} }
func Test_GenerateUnmapVolumeFunc_Plugin_Not_Found(t *testing.T) { func Test_GenerateUnmapVolumeFunc_Plugin_Not_Found(t *testing.T) {
...@@ -876,7 +868,8 @@ func Test_GenerateUnmapVolumeFunc_Plugin_Not_Found(t *testing.T) { ...@@ -876,7 +868,8 @@ func Test_GenerateUnmapVolumeFunc_Plugin_Not_Found(t *testing.T) {
} }
// Enable BlockVolume feature gate // Enable BlockVolume feature gate
utilfeature.DefaultFeatureGate.Set("BlockVolume=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
for name, tc := range testCases { for name, tc := range testCases {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
volumePluginMgr := &volume.VolumePluginMgr{} volumePluginMgr := &volume.VolumePluginMgr{}
...@@ -900,8 +893,6 @@ func Test_GenerateUnmapVolumeFunc_Plugin_Not_Found(t *testing.T) { ...@@ -900,8 +893,6 @@ func Test_GenerateUnmapVolumeFunc_Plugin_Not_Found(t *testing.T) {
} }
}) })
} }
// Rollback feature gate to false.
utilfeature.DefaultFeatureGate.Set("BlockVolume=false")
} }
func Test_GenerateUnmapDeviceFunc_Plugin_Not_Found(t *testing.T) { func Test_GenerateUnmapDeviceFunc_Plugin_Not_Found(t *testing.T) {
...@@ -923,7 +914,8 @@ func Test_GenerateUnmapDeviceFunc_Plugin_Not_Found(t *testing.T) { ...@@ -923,7 +914,8 @@ func Test_GenerateUnmapDeviceFunc_Plugin_Not_Found(t *testing.T) {
} }
// Enable BlockVolume feature gate // Enable BlockVolume feature gate
utilfeature.DefaultFeatureGate.Set("BlockVolume=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
for name, tc := range testCases { for name, tc := range testCases {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
volumePluginMgr := &volume.VolumePluginMgr{} volumePluginMgr := &volume.VolumePluginMgr{}
...@@ -946,8 +938,6 @@ func Test_GenerateUnmapDeviceFunc_Plugin_Not_Found(t *testing.T) { ...@@ -946,8 +938,6 @@ func Test_GenerateUnmapDeviceFunc_Plugin_Not_Found(t *testing.T) {
} }
}) })
} }
// Rollback feature gate to false.
utilfeature.DefaultFeatureGate.Set("BlockVolume=false")
} }
// Populates desiredStateOfWorld cache with one volume/pod. // Populates desiredStateOfWorld cache with one volume/pod.
...@@ -957,7 +947,8 @@ func Test_GenerateUnmapDeviceFunc_Plugin_Not_Found(t *testing.T) { ...@@ -957,7 +947,8 @@ func Test_GenerateUnmapDeviceFunc_Plugin_Not_Found(t *testing.T) {
// Mark volume as fsResizeRequired in ASW. // Mark volume as fsResizeRequired in ASW.
// Verifies volume's fsResizeRequired flag is cleared later. // Verifies volume's fsResizeRequired flag is cleared later.
func Test_Run_Positive_VolumeFSResizeControllerAttachEnabled(t *testing.T) { func Test_Run_Positive_VolumeFSResizeControllerAttachEnabled(t *testing.T) {
utilfeature.DefaultFeatureGate.Set(fmt.Sprintf("%s=true", features.ExpandInUsePersistentVolumes)) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExpandInUsePersistentVolumes, true)()
pv := &v1.PersistentVolume{ pv := &v1.PersistentVolume{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "pv", Name: "pv",
......
...@@ -40,11 +40,15 @@ go_library( ...@@ -40,11 +40,15 @@ go_library(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = ["scheduler_test.go"], srcs = [
"main_test.go",
"scheduler_test.go",
],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/api/legacyscheme:go_default_library", "//pkg/api/legacyscheme:go_default_library",
"//pkg/controller/volume/persistentvolume:go_default_library", "//pkg/controller/volume/persistentvolume:go_default_library",
"//pkg/features:go_default_library",
"//pkg/scheduler/algorithm:go_default_library", "//pkg/scheduler/algorithm:go_default_library",
"//pkg/scheduler/algorithm/predicates:go_default_library", "//pkg/scheduler/algorithm/predicates:go_default_library",
"//pkg/scheduler/api:go_default_library", "//pkg/scheduler/api:go_default_library",
...@@ -65,6 +69,7 @@ go_test( ...@@ -65,6 +69,7 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//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/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: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/informers:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
"//staging/src/k8s.io/client-go/listers/core/v1:go_default_library", "//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
......
...@@ -49,6 +49,7 @@ go_test( ...@@ -49,6 +49,7 @@ go_test(
name = "go_default_test", name = "go_default_test",
srcs = [ srcs = [
"csi_volume_predicate_test.go", "csi_volume_predicate_test.go",
"main_test.go",
"max_attachable_volume_predicate_test.go", "max_attachable_volume_predicate_test.go",
"metadata_test.go", "metadata_test.go",
"predicates_test.go", "predicates_test.go",
......
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package predicates
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -30,7 +30,9 @@ import ( ...@@ -30,7 +30,9 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper" v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
"k8s.io/kubernetes/pkg/features"
kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis" kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
"k8s.io/kubernetes/pkg/scheduler/algorithm" "k8s.io/kubernetes/pkg/scheduler/algorithm"
schedulerapi "k8s.io/kubernetes/pkg/scheduler/api" schedulerapi "k8s.io/kubernetes/pkg/scheduler/api"
...@@ -4913,10 +4915,7 @@ func TestVolumeZonePredicateWithVolumeBinding(t *testing.T) { ...@@ -4913,10 +4915,7 @@ func TestVolumeZonePredicateWithVolumeBinding(t *testing.T) {
}, },
} }
err := utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)()
if err != nil {
t.Fatalf("Failed to enable feature gate for VolumeScheduling: %v", err)
}
for _, test := range tests { for _, test := range tests {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
...@@ -4937,10 +4936,6 @@ func TestVolumeZonePredicateWithVolumeBinding(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) { func TestGetMaxVols(t *testing.T) {
......
...@@ -55,6 +55,7 @@ go_test( ...@@ -55,6 +55,7 @@ go_test(
"image_locality_test.go", "image_locality_test.go",
"interpod_affinity_test.go", "interpod_affinity_test.go",
"least_requested_test.go", "least_requested_test.go",
"main_test.go",
"metadata_test.go", "metadata_test.go",
"most_requested_test.go", "most_requested_test.go",
"node_affinity_test.go", "node_affinity_test.go",
...@@ -79,6 +80,7 @@ go_test( ...@@ -79,6 +80,7 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature: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/stretchr/testify/assert:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library",
], ],
) )
......
...@@ -17,7 +17,6 @@ limitations under the License. ...@@ -17,7 +17,6 @@ limitations under the License.
package priorities package priorities
import ( import (
"fmt"
"reflect" "reflect"
"testing" "testing"
...@@ -25,6 +24,7 @@ import ( ...@@ -25,6 +24,7 @@ import (
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
schedulerapi "k8s.io/kubernetes/pkg/scheduler/api" schedulerapi "k8s.io/kubernetes/pkg/scheduler/api"
schedulercache "k8s.io/kubernetes/pkg/scheduler/cache" schedulercache "k8s.io/kubernetes/pkg/scheduler/cache"
...@@ -44,7 +44,7 @@ func getExistingVolumeCountForNode(pods []*v1.Pod, maxVolumes int) int { ...@@ -44,7 +44,7 @@ func getExistingVolumeCountForNode(pods []*v1.Pod, maxVolumes int) int {
func TestBalancedResourceAllocation(t *testing.T) { func TestBalancedResourceAllocation(t *testing.T) {
// Enable volumesOnNodeForBalancing to do balanced resource allocation // Enable volumesOnNodeForBalancing to do balanced resource allocation
utilfeature.DefaultFeatureGate.Set(fmt.Sprintf("%s=true", features.BalanceAttachedNodeVolumes)) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BalanceAttachedNodeVolumes, true)()
podwithVol1 := v1.PodSpec{ podwithVol1 := v1.PodSpec{
Containers: []v1.Container{ Containers: []v1.Container{
{ {
......
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package priorities
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -15,11 +15,16 @@ go_library( ...@@ -15,11 +15,16 @@ go_library(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = ["plugins_test.go"], srcs = [
"main_test.go",
"plugins_test.go",
],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/features:go_default_library",
"//pkg/scheduler/factory:go_default_library", "//pkg/scheduler/factory:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature: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",
], ],
) )
......
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package algorithmprovider
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -21,6 +21,8 @@ import ( ...@@ -21,6 +21,8 @@ import (
"testing" "testing"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/scheduler/factory" "k8s.io/kubernetes/pkg/scheduler/factory"
) )
...@@ -90,7 +92,7 @@ func TestApplyFeatureGates(t *testing.T) { ...@@ -90,7 +92,7 @@ func TestApplyFeatureGates(t *testing.T) {
} }
// Apply features for algorithm providers. // Apply features for algorithm providers.
utilfeature.DefaultFeatureGate.Set("TaintNodesByCondition=True") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.TaintNodesByCondition, true)()
ApplyFeatureGates() ApplyFeatureGates()
......
...@@ -26,6 +26,7 @@ go_test( ...@@ -26,6 +26,7 @@ go_test(
name = "go_default_test", name = "go_default_test",
srcs = [ srcs = [
"cache_test.go", "cache_test.go",
"main_test.go",
"node_tree_test.go", "node_tree_test.go",
], ],
embed = [":go_default_library"], embed = [":go_default_library"],
...@@ -40,6 +41,7 @@ go_test( ...@@ -40,6 +41,7 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature: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",
], ],
) )
......
...@@ -29,6 +29,7 @@ import ( ...@@ -29,6 +29,7 @@ import (
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
priorityutil "k8s.io/kubernetes/pkg/scheduler/algorithm/priorities/util" priorityutil "k8s.io/kubernetes/pkg/scheduler/algorithm/priorities/util"
schedulercache "k8s.io/kubernetes/pkg/scheduler/cache" schedulercache "k8s.io/kubernetes/pkg/scheduler/cache"
...@@ -92,7 +93,7 @@ func newNodeInfo(requestedResource *schedulercache.Resource, ...@@ -92,7 +93,7 @@ func newNodeInfo(requestedResource *schedulercache.Resource,
// on node level. // on node level.
func TestAssumePodScheduled(t *testing.T) { func TestAssumePodScheduled(t *testing.T) {
// Enable volumesOnNodeForBalancing to do balanced resource allocation // Enable volumesOnNodeForBalancing to do balanced resource allocation
utilfeature.DefaultFeatureGate.Set(fmt.Sprintf("%s=true", features.BalanceAttachedNodeVolumes)) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BalanceAttachedNodeVolumes, true)()
nodeName := "node" nodeName := "node"
testPods := []*v1.Pod{ testPods := []*v1.Pod{
makeBasePod(t, nodeName, "test", "100m", "500", "", []v1.ContainerPort{{HostIP: "127.0.0.1", HostPort: 80, Protocol: "TCP"}}), makeBasePod(t, nodeName, "test", "100m", "500", "", []v1.ContainerPort{{HostIP: "127.0.0.1", HostPort: 80, Protocol: "TCP"}}),
...@@ -240,7 +241,7 @@ func assumeAndFinishBinding(cache *schedulerCache, pod *v1.Pod, assumedTime time ...@@ -240,7 +241,7 @@ func assumeAndFinishBinding(cache *schedulerCache, pod *v1.Pod, assumedTime time
// The removal will be reflected in node info. // The removal will be reflected in node info.
func TestExpirePod(t *testing.T) { func TestExpirePod(t *testing.T) {
// Enable volumesOnNodeForBalancing to do balanced resource allocation // Enable volumesOnNodeForBalancing to do balanced resource allocation
utilfeature.DefaultFeatureGate.Set(fmt.Sprintf("%s=true", features.BalanceAttachedNodeVolumes)) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BalanceAttachedNodeVolumes, true)()
nodeName := "node" nodeName := "node"
testPods := []*v1.Pod{ testPods := []*v1.Pod{
makeBasePod(t, nodeName, "test-1", "100m", "500", "", []v1.ContainerPort{{HostIP: "127.0.0.1", HostPort: 80, Protocol: "TCP"}}), makeBasePod(t, nodeName, "test-1", "100m", "500", "", []v1.ContainerPort{{HostIP: "127.0.0.1", HostPort: 80, Protocol: "TCP"}}),
...@@ -299,7 +300,7 @@ func TestExpirePod(t *testing.T) { ...@@ -299,7 +300,7 @@ func TestExpirePod(t *testing.T) {
// The pod info should still exist after manually expiring unconfirmed pods. // The pod info should still exist after manually expiring unconfirmed pods.
func TestAddPodWillConfirm(t *testing.T) { func TestAddPodWillConfirm(t *testing.T) {
// Enable volumesOnNodeForBalancing to do balanced resource allocation // Enable volumesOnNodeForBalancing to do balanced resource allocation
utilfeature.DefaultFeatureGate.Set(fmt.Sprintf("%s=true", features.BalanceAttachedNodeVolumes)) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BalanceAttachedNodeVolumes, true)()
nodeName := "node" nodeName := "node"
now := time.Now() now := time.Now()
ttl := 10 * time.Second ttl := 10 * time.Second
...@@ -455,7 +456,7 @@ func TestAddPodWillReplaceAssumed(t *testing.T) { ...@@ -455,7 +456,7 @@ func TestAddPodWillReplaceAssumed(t *testing.T) {
// TestAddPodAfterExpiration tests that a pod being Add()ed will be added back if expired. // TestAddPodAfterExpiration tests that a pod being Add()ed will be added back if expired.
func TestAddPodAfterExpiration(t *testing.T) { func TestAddPodAfterExpiration(t *testing.T) {
// Enable volumesOnNodeForBalancing to do balanced resource allocation // Enable volumesOnNodeForBalancing to do balanced resource allocation
utilfeature.DefaultFeatureGate.Set(fmt.Sprintf("%s=true", features.BalanceAttachedNodeVolumes)) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BalanceAttachedNodeVolumes, true)()
nodeName := "node" nodeName := "node"
ttl := 10 * time.Second ttl := 10 * time.Second
basePod := makeBasePod(t, nodeName, "test", "100m", "500", "", []v1.ContainerPort{{HostIP: "127.0.0.1", HostPort: 80, Protocol: "TCP"}}) basePod := makeBasePod(t, nodeName, "test", "100m", "500", "", []v1.ContainerPort{{HostIP: "127.0.0.1", HostPort: 80, Protocol: "TCP"}})
...@@ -504,7 +505,7 @@ func TestAddPodAfterExpiration(t *testing.T) { ...@@ -504,7 +505,7 @@ func TestAddPodAfterExpiration(t *testing.T) {
// TestUpdatePod tests that a pod will be updated if added before. // TestUpdatePod tests that a pod will be updated if added before.
func TestUpdatePod(t *testing.T) { func TestUpdatePod(t *testing.T) {
// Enable volumesOnNodeForBalancing to do balanced resource allocation // Enable volumesOnNodeForBalancing to do balanced resource allocation
utilfeature.DefaultFeatureGate.Set(fmt.Sprintf("%s=true", features.BalanceAttachedNodeVolumes)) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BalanceAttachedNodeVolumes, true)()
nodeName := "node" nodeName := "node"
ttl := 10 * time.Second ttl := 10 * time.Second
testPods := []*v1.Pod{ testPods := []*v1.Pod{
...@@ -630,7 +631,7 @@ func TestUpdatePodAndGet(t *testing.T) { ...@@ -630,7 +631,7 @@ func TestUpdatePodAndGet(t *testing.T) {
// TestExpireAddUpdatePod test the sequence that a pod is expired, added, then updated // TestExpireAddUpdatePod test the sequence that a pod is expired, added, then updated
func TestExpireAddUpdatePod(t *testing.T) { func TestExpireAddUpdatePod(t *testing.T) {
// Enable volumesOnNodeForBalancing to do balanced resource allocation // Enable volumesOnNodeForBalancing to do balanced resource allocation
utilfeature.DefaultFeatureGate.Set(fmt.Sprintf("%s=true", features.BalanceAttachedNodeVolumes)) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BalanceAttachedNodeVolumes, true)()
nodeName := "node" nodeName := "node"
ttl := 10 * time.Second ttl := 10 * time.Second
testPods := []*v1.Pod{ testPods := []*v1.Pod{
...@@ -727,7 +728,7 @@ func makePodWithEphemeralStorage(nodeName, ephemeralStorage string) *v1.Pod { ...@@ -727,7 +728,7 @@ func makePodWithEphemeralStorage(nodeName, ephemeralStorage string) *v1.Pod {
func TestEphemeralStorageResource(t *testing.T) { func TestEphemeralStorageResource(t *testing.T) {
// Enable volumesOnNodeForBalancing to do balanced resource allocation // Enable volumesOnNodeForBalancing to do balanced resource allocation
utilfeature.DefaultFeatureGate.Set(fmt.Sprintf("%s=true", features.BalanceAttachedNodeVolumes)) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BalanceAttachedNodeVolumes, true)()
nodeName := "node" nodeName := "node"
podE := makePodWithEphemeralStorage(nodeName, "500") podE := makePodWithEphemeralStorage(nodeName, "500")
tests := []struct { tests := []struct {
...@@ -772,7 +773,7 @@ func TestEphemeralStorageResource(t *testing.T) { ...@@ -772,7 +773,7 @@ func TestEphemeralStorageResource(t *testing.T) {
// TestRemovePod tests after added pod is removed, its information should also be subtracted. // TestRemovePod tests after added pod is removed, its information should also be subtracted.
func TestRemovePod(t *testing.T) { func TestRemovePod(t *testing.T) {
// Enable volumesOnNodeForBalancing to do balanced resource allocation // Enable volumesOnNodeForBalancing to do balanced resource allocation
utilfeature.DefaultFeatureGate.Set(fmt.Sprintf("%s=true", features.BalanceAttachedNodeVolumes)) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BalanceAttachedNodeVolumes, true)()
nodeName := "node" nodeName := "node"
basePod := makeBasePod(t, nodeName, "test", "100m", "500", "", []v1.ContainerPort{{HostIP: "127.0.0.1", HostPort: 80, Protocol: "TCP"}}) basePod := makeBasePod(t, nodeName, "test", "100m", "500", "", []v1.ContainerPort{{HostIP: "127.0.0.1", HostPort: 80, Protocol: "TCP"}})
tests := []struct { tests := []struct {
...@@ -1126,7 +1127,7 @@ func BenchmarkList1kNodes30kPods(b *testing.B) { ...@@ -1126,7 +1127,7 @@ func BenchmarkList1kNodes30kPods(b *testing.B) {
func BenchmarkUpdate1kNodes30kPods(b *testing.B) { func BenchmarkUpdate1kNodes30kPods(b *testing.B) {
// Enable volumesOnNodeForBalancing to do balanced resource allocation // Enable volumesOnNodeForBalancing to do balanced resource allocation
utilfeature.DefaultFeatureGate.Set(fmt.Sprintf("%s=true", features.BalanceAttachedNodeVolumes)) defer utilfeaturetesting.SetFeatureGateDuringTest(nil, utilfeature.DefaultFeatureGate, features.BalanceAttachedNodeVolumes, true)()
cache := setupCacheOf1kNodes30kPods(b) cache := setupCacheOf1kNodes30kPods(b)
b.ResetTimer() b.ResetTimer()
for n := 0; n < b.N; n++ { for n := 0; n < b.N; n++ {
......
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cache
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package scheduler
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -33,6 +33,7 @@ import ( ...@@ -33,6 +33,7 @@ import (
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
"k8s.io/client-go/informers" "k8s.io/client-go/informers"
clientsetfake "k8s.io/client-go/kubernetes/fake" clientsetfake "k8s.io/client-go/kubernetes/fake"
corelister "k8s.io/client-go/listers/core/v1" corelister "k8s.io/client-go/listers/core/v1"
...@@ -40,6 +41,7 @@ import ( ...@@ -40,6 +41,7 @@ import (
"k8s.io/client-go/tools/record" "k8s.io/client-go/tools/record"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/controller/volume/persistentvolume" "k8s.io/kubernetes/pkg/controller/volume/persistentvolume"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/scheduler/algorithm" "k8s.io/kubernetes/pkg/scheduler/algorithm"
"k8s.io/kubernetes/pkg/scheduler/algorithm/predicates" "k8s.io/kubernetes/pkg/scheduler/algorithm/predicates"
"k8s.io/kubernetes/pkg/scheduler/api" "k8s.io/kubernetes/pkg/scheduler/api"
...@@ -774,8 +776,7 @@ func TestSchedulerWithVolumeBinding(t *testing.T) { ...@@ -774,8 +776,7 @@ func TestSchedulerWithVolumeBinding(t *testing.T) {
// This can be small because we wait for pod to finish scheduling first // This can be small because we wait for pod to finish scheduling first
chanTimeout := 2 * time.Second chanTimeout := 2 * time.Second
utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, true)()
defer utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false")
table := []struct { table := []struct {
name string name string
......
...@@ -44,6 +44,7 @@ go_test( ...@@ -44,6 +44,7 @@ go_test(
"csi_client_test.go", "csi_client_test.go",
"csi_mounter_test.go", "csi_mounter_test.go",
"csi_plugin_test.go", "csi_plugin_test.go",
"main_test.go",
], ],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
......
...@@ -25,7 +25,10 @@ import ( ...@@ -25,7 +25,10 @@ import (
api "k8s.io/api/core/v1" api "k8s.io/api/core/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/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" fakeclient "k8s.io/client-go/kubernetes/fake"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumetest "k8s.io/kubernetes/pkg/volume/testing" volumetest "k8s.io/kubernetes/pkg/volume/testing"
) )
...@@ -46,6 +49,8 @@ func prepareBlockMapperTest(plug *csiPlugin, specVolumeName string) (*csiBlockMa ...@@ -46,6 +49,8 @@ func prepareBlockMapperTest(plug *csiPlugin, specVolumeName string) (*csiBlockMa
} }
func TestBlockMapperGetGlobalMapPath(t *testing.T) { func TestBlockMapperGetGlobalMapPath(t *testing.T) {
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)()
plug, tmpDir := newTestPlugin(t, nil, nil) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
...@@ -85,6 +90,8 @@ func TestBlockMapperGetGlobalMapPath(t *testing.T) { ...@@ -85,6 +90,8 @@ func TestBlockMapperGetGlobalMapPath(t *testing.T) {
} }
func TestBlockMapperGetStagingPath(t *testing.T) { func TestBlockMapperGetStagingPath(t *testing.T) {
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)()
plug, tmpDir := newTestPlugin(t, nil, nil) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
...@@ -120,6 +127,8 @@ func TestBlockMapperGetStagingPath(t *testing.T) { ...@@ -120,6 +127,8 @@ func TestBlockMapperGetStagingPath(t *testing.T) {
} }
func TestBlockMapperGetPublishPath(t *testing.T) { func TestBlockMapperGetPublishPath(t *testing.T) {
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)()
plug, tmpDir := newTestPlugin(t, nil, nil) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
...@@ -155,6 +164,8 @@ func TestBlockMapperGetPublishPath(t *testing.T) { ...@@ -155,6 +164,8 @@ func TestBlockMapperGetPublishPath(t *testing.T) {
} }
func TestBlockMapperGetDeviceMapPath(t *testing.T) { func TestBlockMapperGetDeviceMapPath(t *testing.T) {
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)()
plug, tmpDir := newTestPlugin(t, nil, nil) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
...@@ -194,6 +205,8 @@ func TestBlockMapperGetDeviceMapPath(t *testing.T) { ...@@ -194,6 +205,8 @@ func TestBlockMapperGetDeviceMapPath(t *testing.T) {
} }
func TestBlockMapperSetupDevice(t *testing.T) { func TestBlockMapperSetupDevice(t *testing.T) {
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)()
plug, tmpDir := newTestPlugin(t, nil, nil) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
fakeClient := fakeclient.NewSimpleClientset() fakeClient := fakeclient.NewSimpleClientset()
...@@ -259,6 +272,8 @@ func TestBlockMapperSetupDevice(t *testing.T) { ...@@ -259,6 +272,8 @@ func TestBlockMapperSetupDevice(t *testing.T) {
} }
func TestBlockMapperMapDevice(t *testing.T) { func TestBlockMapperMapDevice(t *testing.T) {
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)()
plug, tmpDir := newTestPlugin(t, nil, nil) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
fakeClient := fakeclient.NewSimpleClientset() fakeClient := fakeclient.NewSimpleClientset()
...@@ -340,6 +355,8 @@ func TestBlockMapperMapDevice(t *testing.T) { ...@@ -340,6 +355,8 @@ func TestBlockMapperMapDevice(t *testing.T) {
} }
func TestBlockMapperTearDownDevice(t *testing.T) { func TestBlockMapperTearDownDevice(t *testing.T) {
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)()
plug, tmpDir := newTestPlugin(t, nil, nil) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
fakeClient := fakeclient.NewSimpleClientset() fakeClient := fakeclient.NewSimpleClientset()
......
...@@ -29,6 +29,7 @@ import ( ...@@ -29,6 +29,7 @@ import (
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
fakeclient "k8s.io/client-go/kubernetes/fake" fakeclient "k8s.io/client-go/kubernetes/fake"
utiltesting "k8s.io/client-go/util/testing" utiltesting "k8s.io/client-go/util/testing"
fakecsi "k8s.io/csi-api/pkg/client/clientset/versioned/fake" fakecsi "k8s.io/csi-api/pkg/client/clientset/versioned/fake"
...@@ -39,11 +40,6 @@ import ( ...@@ -39,11 +40,6 @@ import (
// create a plugin mgr to load plugins and setup a fake client // 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) { 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") tmpDir, err := utiltesting.MkTmpdir("csi-test")
if err != nil { if err != nil {
t.Fatalf("can't create temp dir: %v", err) t.Fatalf("can't create temp dir: %v", err)
...@@ -109,6 +105,8 @@ func makeTestPV(name string, sizeGig int, driverName, volID string) *api.Persist ...@@ -109,6 +105,8 @@ func makeTestPV(name string, sizeGig int, driverName, volID string) *api.Persist
} }
func TestPluginGetPluginName(t *testing.T) { func TestPluginGetPluginName(t *testing.T) {
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)()
plug, tmpDir := newTestPlugin(t, nil, nil) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
if plug.GetPluginName() != "kubernetes.io/csi" { if plug.GetPluginName() != "kubernetes.io/csi" {
...@@ -117,6 +115,8 @@ func TestPluginGetPluginName(t *testing.T) { ...@@ -117,6 +115,8 @@ func TestPluginGetPluginName(t *testing.T) {
} }
func TestPluginGetVolumeName(t *testing.T) { func TestPluginGetVolumeName(t *testing.T) {
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)()
plug, tmpDir := newTestPlugin(t, nil, nil) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
testCases := []struct { testCases := []struct {
...@@ -146,6 +146,8 @@ func TestPluginGetVolumeName(t *testing.T) { ...@@ -146,6 +146,8 @@ func TestPluginGetVolumeName(t *testing.T) {
} }
func TestPluginCanSupport(t *testing.T) { func TestPluginCanSupport(t *testing.T) {
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)()
plug, tmpDir := newTestPlugin(t, nil, nil) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
...@@ -158,6 +160,8 @@ func TestPluginCanSupport(t *testing.T) { ...@@ -158,6 +160,8 @@ func TestPluginCanSupport(t *testing.T) {
} }
func TestPluginConstructVolumeSpec(t *testing.T) { func TestPluginConstructVolumeSpec(t *testing.T) {
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)()
plug, tmpDir := newTestPlugin(t, nil, nil) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
...@@ -218,6 +222,8 @@ func TestPluginConstructVolumeSpec(t *testing.T) { ...@@ -218,6 +222,8 @@ func TestPluginConstructVolumeSpec(t *testing.T) {
} }
func TestPluginNewMounter(t *testing.T) { func TestPluginNewMounter(t *testing.T) {
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)()
plug, tmpDir := newTestPlugin(t, nil, nil) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
...@@ -266,6 +272,8 @@ func TestPluginNewMounter(t *testing.T) { ...@@ -266,6 +272,8 @@ func TestPluginNewMounter(t *testing.T) {
} }
func TestPluginNewUnmounter(t *testing.T) { func TestPluginNewUnmounter(t *testing.T) {
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)()
plug, tmpDir := newTestPlugin(t, nil, nil) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
...@@ -311,6 +319,8 @@ func TestPluginNewUnmounter(t *testing.T) { ...@@ -311,6 +319,8 @@ func TestPluginNewUnmounter(t *testing.T) {
} }
func TestPluginNewAttacher(t *testing.T) { func TestPluginNewAttacher(t *testing.T) {
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)()
plug, tmpDir := newTestPlugin(t, nil, nil) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
...@@ -329,6 +339,8 @@ func TestPluginNewAttacher(t *testing.T) { ...@@ -329,6 +339,8 @@ func TestPluginNewAttacher(t *testing.T) {
} }
func TestPluginNewDetacher(t *testing.T) { func TestPluginNewDetacher(t *testing.T) {
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)()
plug, tmpDir := newTestPlugin(t, nil, nil) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
...@@ -347,6 +359,8 @@ func TestPluginNewDetacher(t *testing.T) { ...@@ -347,6 +359,8 @@ func TestPluginNewDetacher(t *testing.T) {
} }
func TestPluginNewBlockMapper(t *testing.T) { func TestPluginNewBlockMapper(t *testing.T) {
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)()
plug, tmpDir := newTestPlugin(t, nil, nil) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
...@@ -392,6 +406,8 @@ func TestPluginNewBlockMapper(t *testing.T) { ...@@ -392,6 +406,8 @@ func TestPluginNewBlockMapper(t *testing.T) {
} }
func TestPluginNewUnmapper(t *testing.T) { func TestPluginNewUnmapper(t *testing.T) {
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)()
plug, tmpDir := newTestPlugin(t, nil, nil) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
...@@ -449,6 +465,8 @@ func TestPluginNewUnmapper(t *testing.T) { ...@@ -449,6 +465,8 @@ func TestPluginNewUnmapper(t *testing.T) {
} }
func TestPluginConstructBlockVolumeSpec(t *testing.T) { func TestPluginConstructBlockVolumeSpec(t *testing.T) {
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIBlockVolume, true)()
plug, tmpDir := newTestPlugin(t, nil, nil) plug, tmpDir := newTestPlugin(t, nil, nil)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
......
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package csi
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -52,6 +52,7 @@ go_test( ...@@ -52,6 +52,7 @@ go_test(
"atomic_writer_test.go", "atomic_writer_test.go",
"attach_limit_test.go", "attach_limit_test.go",
"device_util_linux_test.go", "device_util_linux_test.go",
"main_test.go",
"nested_volumes_test.go", "nested_volumes_test.go",
"resize_util_test.go", "resize_util_test.go",
"util_test.go", "util_test.go",
...@@ -60,6 +61,7 @@ go_test( ...@@ -60,6 +61,7 @@ go_test(
deps = [ deps = [
"//pkg/apis/core/install:go_default_library", "//pkg/apis/core/install:go_default_library",
"//pkg/apis/core/v1/helper:go_default_library", "//pkg/apis/core/v1/helper:go_default_library",
"//pkg/features:go_default_library",
"//pkg/kubelet/apis:go_default_library", "//pkg/kubelet/apis:go_default_library",
"//pkg/util/mount:go_default_library", "//pkg/util/mount:go_default_library",
"//pkg/util/slice:go_default_library", "//pkg/util/slice:go_default_library",
...@@ -70,6 +72,7 @@ go_test( ...@@ -70,6 +72,7 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature: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/util/testing:go_default_library", "//staging/src/k8s.io/client-go/util/testing:go_default_library",
], ],
) )
......
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package util
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -24,12 +24,15 @@ import ( ...@@ -24,12 +24,15 @@ import (
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
utiltesting "k8s.io/client-go/util/testing" utiltesting "k8s.io/client-go/util/testing"
// util.go uses api.Codecs.LegacyCodec so import this package to do some // util.go uses api.Codecs.LegacyCodec so import this package to do some
// resource initialization. // resource initialization.
"hash/fnv" "hash/fnv"
_ "k8s.io/kubernetes/pkg/apis/core/install" _ "k8s.io/kubernetes/pkg/apis/core/install"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"reflect" "reflect"
...@@ -1426,59 +1429,54 @@ func TestSelectZoneForVolume(t *testing.T) { ...@@ -1426,59 +1429,54 @@ func TestSelectZoneForVolume(t *testing.T) {
} }
for _, test := range tests { for _, test := range tests {
utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false") t.Run(test.Name, func(t *testing.T) {
if test.VolumeScheduling { defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeScheduling, test.VolumeScheduling)()
utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true")
}
var zonesParameter, zonesWithNodes sets.String var zonesParameter, zonesWithNodes sets.String
var err error var err error
if test.Zones != "" { if test.Zones != "" {
zonesParameter, err = ZonesToSet(test.Zones) zonesParameter, err = ZonesToSet(test.Zones)
if err != nil { if err != nil {
t.Errorf("Could not convert Zones to a set: %s. This is a test error %s", test.Zones, test.Name) t.Fatalf("Could not convert Zones to a set: %s. This is a test error %s", test.Zones, test.Name)
continue }
} }
}
if test.ZonesWithNodes != "" { if test.ZonesWithNodes != "" {
zonesWithNodes, err = ZonesToSet(test.ZonesWithNodes) zonesWithNodes, err = ZonesToSet(test.ZonesWithNodes)
if err != nil { if err != nil {
t.Errorf("Could not convert specified ZonesWithNodes to a set: %s. This is a test error %s", test.ZonesWithNodes, test.Name) t.Fatalf("Could not convert specified ZonesWithNodes to a set: %s. This is a test error %s", test.ZonesWithNodes, test.Name)
continue }
} }
}
zone, err := SelectZoneForVolume(test.ZonePresent, test.ZonesPresent, test.Zone, zonesParameter, zonesWithNodes, test.Node, test.AllowedTopologies, test.Name) zone, err := SelectZoneForVolume(test.ZonePresent, test.ZonesPresent, test.Zone, zonesParameter, zonesWithNodes, test.Node, test.AllowedTopologies, test.Name)
if test.Reject && err == nil { if test.Reject && err == nil {
t.Errorf("Unexpected zone from SelectZoneForVolume for %s", zone) t.Errorf("Unexpected zone from SelectZoneForVolume for %s", zone)
continue
}
if !test.Reject {
if err != nil {
t.Errorf("Unexpected error from SelectZoneForVolume for %s; Error: %v", test.Name, err)
continue
} }
if test.ExpectSpecificZone == true { if !test.Reject {
if zone != test.ExpectedZone { if err != nil {
t.Errorf("Expected zone %v does not match obtained zone %v for %s", test.ExpectedZone, zone, test.Name) t.Errorf("Unexpected error from SelectZoneForVolume for %s; Error: %v", test.Name, err)
} }
continue
}
expectedZones, err := ZonesToSet(test.ExpectedZones) if test.ExpectSpecificZone == true {
if err != nil { if zone != test.ExpectedZone {
t.Errorf("Could not convert ExpectedZones to a set: %s. This is a test error", test.ExpectedZones) t.Errorf("Expected zone %v does not match obtained zone %v for %s", test.ExpectedZone, zone, test.Name)
continue }
} }
if !expectedZones.Has(zone) {
t.Errorf("Obtained zone %s not member of expectedZones %s", zone, expectedZones) if test.ExpectedZones != "" {
expectedZones, err := ZonesToSet(test.ExpectedZones)
if err != nil {
t.Fatalf("Could not convert ExpectedZones to a set: %s. This is a test error", test.ExpectedZones)
}
if !expectedZones.Has(zone) {
t.Errorf("Obtained zone %s not member of expectedZones %s", zone, expectedZones)
}
}
} }
} })
} }
} }
......
...@@ -8,10 +8,14 @@ load( ...@@ -8,10 +8,14 @@ load(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = ["admission_test.go"], srcs = [
"admission_test.go",
"main_test.go",
],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/features:go_default_library",
"//pkg/scheduler/api:go_default_library", "//pkg/scheduler/api:go_default_library",
"//pkg/util/tolerations:go_default_library", "//pkg/util/tolerations:go_default_library",
"//plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction:go_default_library", "//plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction:go_default_library",
...@@ -21,6 +25,7 @@ go_test( ...@@ -21,6 +25,7 @@ go_test(
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/admission/initializer:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission/initializer:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature: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/informers:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
......
...@@ -27,10 +27,12 @@ import ( ...@@ -27,10 +27,12 @@ import (
"k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission"
genericadmissioninitializer "k8s.io/apiserver/pkg/admission/initializer" genericadmissioninitializer "k8s.io/apiserver/pkg/admission/initializer"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
"k8s.io/client-go/informers" "k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/kubernetes/fake"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/features"
schedulerapi "k8s.io/kubernetes/pkg/scheduler/api" schedulerapi "k8s.io/kubernetes/pkg/scheduler/api"
"k8s.io/kubernetes/pkg/util/tolerations" "k8s.io/kubernetes/pkg/util/tolerations"
pluginapi "k8s.io/kubernetes/plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction" pluginapi "k8s.io/kubernetes/plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction"
...@@ -83,9 +85,7 @@ func TestPodAdmission(t *testing.T) { ...@@ -83,9 +85,7 @@ func TestPodAdmission(t *testing.T) {
}, },
} }
if err := utilfeature.DefaultFeatureGate.Set("TaintNodesByCondition=true"); err != nil { defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.TaintNodesByCondition, true)()
t.Errorf("Failed to enable TaintByCondition feature: %v.", err)
}
tests := []struct { tests := []struct {
pod *api.Pod pod *api.Pod
......
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package podtolerationrestriction
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -8,7 +8,10 @@ load( ...@@ -8,7 +8,10 @@ load(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = ["admission_test.go"], srcs = [
"admission_test.go",
"main_test.go",
],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
...@@ -21,6 +24,7 @@ go_test( ...@@ -21,6 +24,7 @@ go_test(
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature: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/informers:go_default_library",
"//vendor/k8s.io/klog:go_default_library", "//vendor/k8s.io/klog:go_default_library",
], ],
......
...@@ -17,7 +17,6 @@ limitations under the License. ...@@ -17,7 +17,6 @@ limitations under the License.
package priority package priority
import ( import (
"fmt"
"testing" "testing"
"k8s.io/klog" "k8s.io/klog"
...@@ -27,6 +26,7 @@ import ( ...@@ -27,6 +26,7 @@ import (
"k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authentication/user"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
"k8s.io/client-go/informers" "k8s.io/client-go/informers"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/apis/scheduling" "k8s.io/kubernetes/pkg/apis/scheduling"
...@@ -468,9 +468,9 @@ func TestPodAdmission(t *testing.T) { ...@@ -468,9 +468,9 @@ func TestPodAdmission(t *testing.T) {
}, },
} }
// Enable PodPriority feature gate. // Enable PodPriority feature gate.
utilfeature.DefaultFeatureGate.Set(fmt.Sprintf("%s=true", features.PodPriority)) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PodPriority, true)()
// Enable ExperimentalCriticalPodAnnotation feature gate. // Enable ExperimentalCriticalPodAnnotation feature gate.
utilfeature.DefaultFeatureGate.Set(fmt.Sprintf("%s=true", features.ExperimentalCriticalPodAnnotation)) defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExperimentalCriticalPodAnnotation, true)()
tests := []struct { tests := []struct {
name string name string
existingClasses []*scheduling.PriorityClass existingClasses []*scheduling.PriorityClass
......
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package priority
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -51,11 +51,15 @@ go_library( ...@@ -51,11 +51,15 @@ go_library(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = ["admission_test.go"], srcs = [
"admission_test.go",
"main_test.go",
],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/controller:go_default_library", "//pkg/controller:go_default_library",
"//pkg/features:go_default_library",
"//pkg/quota/v1/generic:go_default_library", "//pkg/quota/v1/generic:go_default_library",
"//pkg/quota/v1/install:go_default_library", "//pkg/quota/v1/install:go_default_library",
"//plugin/pkg/admission/resourcequota/apis/resourcequota:go_default_library", "//plugin/pkg/admission/resourcequota/apis/resourcequota:go_default_library",
...@@ -65,6 +69,7 @@ go_test( ...@@ -65,6 +69,7 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/admission: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: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/informers:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
"//staging/src/k8s.io/client-go/testing:go_default_library", "//staging/src/k8s.io/client-go/testing:go_default_library",
......
...@@ -31,12 +31,14 @@ import ( ...@@ -31,12 +31,14 @@ import (
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
"k8s.io/client-go/informers" "k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/kubernetes/fake"
testcore "k8s.io/client-go/testing" testcore "k8s.io/client-go/testing"
"k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/cache"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/controller"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/quota/v1/generic" "k8s.io/kubernetes/pkg/quota/v1/generic"
"k8s.io/kubernetes/pkg/quota/v1/install" "k8s.io/kubernetes/pkg/quota/v1/install"
resourcequotaapi "k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota" resourcequotaapi "k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota"
...@@ -452,15 +454,7 @@ func TestAdmitHandlesNegativePVCUpdates(t *testing.T) { ...@@ -452,15 +454,7 @@ func TestAdmitHandlesNegativePVCUpdates(t *testing.T) {
stopCh := make(chan struct{}) stopCh := make(chan struct{})
defer close(stopCh) defer close(stopCh)
err := utilfeature.DefaultFeatureGate.Set("ExpandPersistentVolumes=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExpandPersistentVolumes, true)()
if err != nil {
t.Errorf("Failed to enable feature gate for LocalPersistentVolumes: %v", err)
return
}
defer func() {
utilfeature.DefaultFeatureGate.Set("ExpandPersistentVolumes=false")
}()
kubeClient := fake.NewSimpleClientset(resourceQuota) kubeClient := fake.NewSimpleClientset(resourceQuota)
informerFactory := informers.NewSharedInformerFactory(kubeClient, controller.NoResyncPeriodFunc()) informerFactory := informers.NewSharedInformerFactory(kubeClient, controller.NoResyncPeriodFunc())
...@@ -491,7 +485,7 @@ func TestAdmitHandlesNegativePVCUpdates(t *testing.T) { ...@@ -491,7 +485,7 @@ func TestAdmitHandlesNegativePVCUpdates(t *testing.T) {
}, },
} }
err = handler.Validate(admission.NewAttributesRecord(newPVC, oldPVC, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPVC.Namespace, newPVC.Name, corev1.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Update, false, nil)) err := handler.Validate(admission.NewAttributesRecord(newPVC, oldPVC, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPVC.Namespace, newPVC.Name, corev1.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Update, false, nil))
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
...@@ -515,15 +509,7 @@ func TestAdmitHandlesPVCUpdates(t *testing.T) { ...@@ -515,15 +509,7 @@ func TestAdmitHandlesPVCUpdates(t *testing.T) {
}, },
} }
err := utilfeature.DefaultFeatureGate.Set("ExpandPersistentVolumes=true") defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExpandPersistentVolumes, true)()
if err != nil {
t.Errorf("Failed to enable feature gate for LocalPersistentVolumes: %v", err)
return
}
defer func() {
utilfeature.DefaultFeatureGate.Set("ExpandPersistentVolumes=false")
}()
// start up quota system // start up quota system
stopCh := make(chan struct{}) stopCh := make(chan struct{})
...@@ -558,7 +544,7 @@ func TestAdmitHandlesPVCUpdates(t *testing.T) { ...@@ -558,7 +544,7 @@ func TestAdmitHandlesPVCUpdates(t *testing.T) {
}, },
} }
err = handler.Validate(admission.NewAttributesRecord(newPVC, oldPVC, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPVC.Namespace, newPVC.Name, corev1.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Update, false, nil)) err := handler.Validate(admission.NewAttributesRecord(newPVC, oldPVC, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPVC.Namespace, newPVC.Name, corev1.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Update, false, nil))
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
......
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package resourcequota
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -32,11 +32,15 @@ go_library( ...@@ -32,11 +32,15 @@ go_library(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = ["admission_test.go"], srcs = [
"admission_test.go",
"main_test.go",
],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/cloudprovider/providers/aws:go_default_library", "//pkg/cloudprovider/providers/aws:go_default_library",
"//pkg/features:go_default_library",
"//pkg/kubelet/apis:go_default_library", "//pkg/kubelet/apis:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
...@@ -44,6 +48,7 @@ go_test( ...@@ -44,6 +48,7 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//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/admission:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature: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",
], ],
) )
......
...@@ -28,8 +28,10 @@ import ( ...@@ -28,8 +28,10 @@ import (
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission"
utilfeature "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" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/cloudprovider/providers/aws" "k8s.io/kubernetes/pkg/cloudprovider/providers/aws"
"k8s.io/kubernetes/pkg/features"
kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis" kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
) )
...@@ -122,8 +124,8 @@ func TestAdmission(t *testing.T) { ...@@ -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 // 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)) 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))
......
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package label
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -17,16 +17,21 @@ go_library( ...@@ -17,16 +17,21 @@ go_library(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = ["admission_test.go"], srcs = [
"admission_test.go",
"main_test.go",
],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/features:go_default_library",
"//pkg/volume/util: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/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime: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/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/admission: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: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", "//vendor/github.com/davecgh/go-spew/spew:go_default_library",
], ],
) )
......
...@@ -17,7 +17,6 @@ limitations under the License. ...@@ -17,7 +17,6 @@ limitations under the License.
package storageobjectinuseprotection package storageobjectinuseprotection
import ( import (
"fmt"
"reflect" "reflect"
"testing" "testing"
...@@ -27,8 +26,10 @@ import ( ...@@ -27,8 +26,10 @@ import (
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/admission" "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" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/features"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
) )
...@@ -118,31 +119,29 @@ func TestAdmit(t *testing.T) { ...@@ -118,31 +119,29 @@ func TestAdmit(t *testing.T) {
ctrl := newPlugin() ctrl := newPlugin()
for _, test := range tests { for _, test := range tests {
feature.DefaultFeatureGate.Set(fmt.Sprintf("StorageObjectInUseProtection=%v", test.featureEnabled)) t.Run(test.name, func(t *testing.T) {
obj := test.object.DeepCopyObject() defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StorageObjectInUseProtection, test.featureEnabled)()
attrs := admission.NewAttributesRecord( obj := test.object.DeepCopyObject()
obj, // new object attrs := admission.NewAttributesRecord(
obj.DeepCopyObject(), // old object, copy to be sure it's not modified obj, // new object
schema.GroupVersionKind{}, obj.DeepCopyObject(), // old object, copy to be sure it's not modified
test.namespace, schema.GroupVersionKind{},
"foo", test.namespace,
test.resource, "foo",
"", // subresource test.resource,
admission.Create, "", // subresource
false, // dryRun admission.Create,
nil, // userInfo false, // dryRun
) nil, // userInfo
)
err := ctrl.Admit(attrs) err := ctrl.Admit(attrs)
if err != nil { if err != nil {
t.Errorf("Test %q: got unexpected error: %v", test.name, err) t.Errorf("Test %q: got unexpected error: %v", test.name, err)
} }
if !reflect.DeepEqual(test.expectedObject, obj) { 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)) 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")
} }
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package storageobjectinuseprotection
import (
"testing"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
_ "k8s.io/kubernetes/pkg/features"
)
func TestMain(m *testing.M) {
utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
}
...@@ -18,13 +18,57 @@ package testing ...@@ -18,13 +18,57 @@ package testing
import ( import (
"fmt" "fmt"
"os"
"strings"
"testing" "testing"
"k8s.io/apiserver/pkg/util/feature" "k8s.io/apiserver/pkg/util/feature"
) )
// VerifyFeatureGatesUnchanged ensures the provided gate does not change any values when tests() are completed.
// Intended to be placed into unit test packages that mess with feature gates.
//
// Example use:
//
// import (
// "testing"
//
// utilfeature "k8s.io/apiserver/pkg/util/feature"
// utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
// _ "k8s.io/kubernetes/pkg/features"
// )
//
// func TestMain(m *testing.M) {
// utilfeaturetesting.VerifyFeatureGatesUnchanged(utilfeature.DefaultFeatureGate, m.Run)
// }
func VerifyFeatureGatesUnchanged(gate feature.FeatureGate, tests func() int) {
originalGates := gate.DeepCopy()
originalSet := fmt.Sprint(gate)
rc := tests()
finalSet := fmt.Sprint(gate)
if finalSet != originalSet {
for _, kv := range strings.Split(finalSet, ",") {
k := strings.Split(kv, "=")[0]
if originalGates.Enabled(feature.Feature(k)) != gate.Enabled(feature.Feature(k)) {
fmt.Println(fmt.Sprintf("VerifyFeatureGatesUnchanged: mutated %s feature gate from %v to %v", k, originalGates.Enabled(feature.Feature(k)), gate.Enabled(feature.Feature(k))))
rc = 1
}
}
}
if rc != 0 {
os.Exit(rc)
}
}
// SetFeatureGateDuringTest sets the specified gate to the specified value, and returns a function that restores the original value. // SetFeatureGateDuringTest sets the specified gate to the specified value, and returns a function that restores the original value.
// Failures to set or restore cause the test to fail. // Failures to set or restore cause the test to fail.
//
// Example use:
//
// defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.<FeatureName>, true)()
func SetFeatureGateDuringTest(t *testing.T, gate feature.FeatureGate, feature feature.Feature, value bool) func() { func SetFeatureGateDuringTest(t *testing.T, gate feature.FeatureGate, feature feature.Feature, value bool) func() {
originalValue := gate.Enabled(feature) originalValue := gate.Enabled(feature)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment