Clean kube_features.go

Added tests, info about new feature gate in error message, fixes from review

Added basic e2e test

Added unit tests

Ran hack/update-featuregates.sh

Tolerate updates to existing resources after disabling feature gate

Added feature gate to versioned_kube_features.go

Fixed existing tests

Use PodValidationOptions for validation instead of using feature gate directly

Relaxed validation for allowing zero in prestop hook sleep action
This commit is contained in:
Sreeram Venkitesh
2024-10-17 14:16:00 +05:30
parent 0daa75b972
commit f1f9e7b398
8 changed files with 197 additions and 47 deletions

View File

@@ -7445,7 +7445,7 @@ func TestValidateProbe(t *testing.T) {
}
for _, p := range successCases {
if errs := validateProbe(p, defaultGracePeriod, field.NewPath("field")); len(errs) != 0 {
if errs := validateProbe(p, defaultGracePeriod, field.NewPath("field"), PodValidationOptions{}); len(errs) != 0 {
t.Errorf("expected success: %v", errs)
}
}
@@ -7457,7 +7457,7 @@ func TestValidateProbe(t *testing.T) {
errorCases = append(errorCases, probe)
}
for _, p := range errorCases {
if errs := validateProbe(p, defaultGracePeriod, field.NewPath("field")); len(errs) == 0 {
if errs := validateProbe(p, defaultGracePeriod, field.NewPath("field"), PodValidationOptions{}); len(errs) == 0 {
t.Errorf("expected failure for %v", p)
}
}
@@ -7563,7 +7563,7 @@ func Test_validateProbe(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := validateProbe(tt.args.probe, defaultGracePeriod, tt.args.fldPath)
got := validateProbe(tt.args.probe, defaultGracePeriod, tt.args.fldPath, PodValidationOptions{})
if len(got) != len(tt.want) {
t.Errorf("validateProbe() = %v, want %v", got, tt.want)
return
@@ -7588,7 +7588,7 @@ func TestValidateHandler(t *testing.T) {
{HTTPGet: &core.HTTPGetAction{Path: "/", Port: intstr.FromString("port"), Host: "", Scheme: "HTTP", HTTPHeaders: []core.HTTPHeader{{Name: "X-Forwarded-For", Value: "1.2.3.4"}, {Name: "X-Forwarded-For", Value: "5.6.7.8"}}}},
}
for _, h := range successCases {
if errs := validateHandler(handlerFromProbe(&h), defaultGracePeriod, field.NewPath("field")); len(errs) != 0 {
if errs := validateHandler(handlerFromProbe(&h), defaultGracePeriod, field.NewPath("field"), PodValidationOptions{}); len(errs) != 0 {
t.Errorf("expected success: %v", errs)
}
}
@@ -7603,7 +7603,7 @@ func TestValidateHandler(t *testing.T) {
{HTTPGet: &core.HTTPGetAction{Path: "/", Port: intstr.FromString("port"), Host: "", Scheme: "HTTP", HTTPHeaders: []core.HTTPHeader{{Name: "X_Forwarded_For", Value: "foo.example.com"}}}},
}
for _, h := range errorCases {
if errs := validateHandler(handlerFromProbe(&h), defaultGracePeriod, field.NewPath("field")); len(errs) == 0 {
if errs := validateHandler(handlerFromProbe(&h), defaultGracePeriod, field.NewPath("field"), PodValidationOptions{}); len(errs) == 0 {
t.Errorf("expected failure for %#v", h)
}
}
@@ -24147,43 +24147,109 @@ func TestValidateLoadBalancerStatus(t *testing.T) {
func TestValidateSleepAction(t *testing.T) {
fldPath := field.NewPath("root")
getInvalidStr := func(gracePeriod int64) string {
return fmt.Sprintf("must be greater than 0 and less than terminationGracePeriodSeconds (%d)", gracePeriod)
return fmt.Sprintf("must be greater than 0 and less than terminationGracePeriodSeconds (%d). Enable AllowPodLifecycleSleepActionZeroValue feature gate for zero sleep.", gracePeriod)
}
getInvalidStrWithZeroValueEnabled := func(gracePeriod int64) string {
return fmt.Sprintf("must be non-negative and less than terminationGracePeriodSeconds (%d)", gracePeriod)
}
testCases := []struct {
name string
action *core.SleepAction
gracePeriod int64
expectErr field.ErrorList
name string
action *core.SleepAction
gracePeriod int64
zeroValueEnabled bool
expectErr field.ErrorList
}{
{
name: "valid setting",
action: &core.SleepAction{
Seconds: 5,
},
gracePeriod: 30,
gracePeriod: 30,
zeroValueEnabled: false,
},
{
name: "negative seconds",
action: &core.SleepAction{
Seconds: -1,
},
gracePeriod: 30,
expectErr: field.ErrorList{field.Invalid(fldPath, -1, getInvalidStr(30))},
gracePeriod: 30,
zeroValueEnabled: false,
expectErr: field.ErrorList{field.Invalid(fldPath, -1, getInvalidStr(30))},
},
{
name: "longer than gracePeriod",
action: &core.SleepAction{
Seconds: 5,
},
gracePeriod: 3,
expectErr: field.ErrorList{field.Invalid(fldPath, 5, getInvalidStr(3))},
gracePeriod: 3,
zeroValueEnabled: false,
expectErr: field.ErrorList{field.Invalid(fldPath, 5, getInvalidStr(3))},
},
{
name: "sleep duration of zero with zero value feature gate disabled",
action: &core.SleepAction{
Seconds: 0,
},
gracePeriod: 30,
zeroValueEnabled: false,
expectErr: field.ErrorList{field.Invalid(fldPath, 0, getInvalidStr(30))},
},
{
name: "sleep duration of zero with zero value feature gate enabled",
action: &core.SleepAction{
Seconds: 0,
},
gracePeriod: 30,
zeroValueEnabled: true,
},
{
name: "invalid sleep duration (negative value) with zero value disabled",
action: &core.SleepAction{
Seconds: -1,
},
gracePeriod: 30,
zeroValueEnabled: false,
expectErr: field.ErrorList{field.Invalid(fldPath, -1, getInvalidStr(30))},
},
{
name: "invalid sleep duration (negative value) with zero value enabled",
action: &core.SleepAction{
Seconds: -1,
},
gracePeriod: 30,
zeroValueEnabled: true,
expectErr: field.ErrorList{field.Invalid(fldPath, -1, getInvalidStrWithZeroValueEnabled(30))},
},
{
name: "zero grace period duration with zero value enabled",
action: &core.SleepAction{
Seconds: 0,
},
gracePeriod: 0,
zeroValueEnabled: true,
},
{
name: "nil grace period with zero value disabled",
action: &core.SleepAction{
Seconds: 5,
},
zeroValueEnabled: false,
expectErr: field.ErrorList{field.Invalid(fldPath, 5, getInvalidStr(0))},
},
{
name: "nil grace period with zero value enabled",
action: &core.SleepAction{
Seconds: 0,
},
zeroValueEnabled: true,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
errs := validateSleepAction(tc.action, &tc.gracePeriod, fldPath)
errs := validateSleepAction(tc.action, &tc.gracePeriod, fldPath, PodValidationOptions{AllowPodLifecycleSleepActionZeroValue: tc.zeroValueEnabled})
if len(tc.expectErr) > 0 && len(errs) == 0 {
t.Errorf("Unexpected success")