test: Add Origin field support to ReplicationController spec.Replicas validation test

This commit is contained in:
yongruilin 2025-02-21 23:37:34 +00:00
parent 07477c656e
commit c7cf852086
2 changed files with 131 additions and 86 deletions

View File

@ -6266,7 +6266,7 @@ func ValidateReplicationControllerSpec(spec, oldSpec *core.ReplicationController
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
allErrs = append(allErrs, ValidateNonnegativeField(int64(spec.MinReadySeconds), fldPath.Child("minReadySeconds"))...) allErrs = append(allErrs, ValidateNonnegativeField(int64(spec.MinReadySeconds), fldPath.Child("minReadySeconds"))...)
allErrs = append(allErrs, ValidateNonEmptySelector(spec.Selector, fldPath.Child("selector"))...) allErrs = append(allErrs, ValidateNonEmptySelector(spec.Selector, fldPath.Child("selector"))...)
allErrs = append(allErrs, ValidateNonnegativeField(int64(spec.Replicas), fldPath.Child("replicas"))...) allErrs = append(allErrs, ValidateNonnegativeField(int64(spec.Replicas), fldPath.Child("replicas")).WithOrigin("minimum")...)
allErrs = append(allErrs, ValidatePodTemplateSpecForRC(spec.Template, spec.Selector, spec.Replicas, fldPath.Child("template"), opts)...) allErrs = append(allErrs, ValidatePodTemplateSpecForRC(spec.Template, spec.Selector, spec.Replicas, fldPath.Child("template"), opts)...)
return allErrs return allErrs
} }

View File

@ -16791,144 +16791,179 @@ func TestValidateReplicationController(t *testing.T) {
} }
} }
errorCases := map[string]core.ReplicationController{ errorCases := map[string]struct {
rc core.ReplicationController
expectedOrigin []string
}{
"zero-length ID": { "zero-length ID": {
ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: metav1.NamespaceDefault}, rc: core.ReplicationController{
Spec: core.ReplicationControllerSpec{ ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: metav1.NamespaceDefault},
Selector: validSelector, Spec: core.ReplicationControllerSpec{
Template: &validPodTemplate.Template, Selector: validSelector,
Template: &validPodTemplate.Template,
},
}, },
}, },
"missing-namespace": { "missing-namespace": {
ObjectMeta: metav1.ObjectMeta{Name: "abc-123"}, rc: core.ReplicationController{
Spec: core.ReplicationControllerSpec{ ObjectMeta: metav1.ObjectMeta{Name: "abc-123"},
Selector: validSelector, Spec: core.ReplicationControllerSpec{
Template: &validPodTemplate.Template, Selector: validSelector,
Template: &validPodTemplate.Template,
},
}, },
}, },
"empty selector": { "empty selector": {
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, rc: core.ReplicationController{
Spec: core.ReplicationControllerSpec{ ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
Template: &validPodTemplate.Template, Spec: core.ReplicationControllerSpec{
Template: &validPodTemplate.Template,
},
}, },
}, },
"selector_doesnt_match": { "selector_doesnt_match": {
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, rc: core.ReplicationController{
Spec: core.ReplicationControllerSpec{ ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
Selector: map[string]string{"foo": "bar"}, Spec: core.ReplicationControllerSpec{
Template: &validPodTemplate.Template, Selector: map[string]string{"foo": "bar"},
Template: &validPodTemplate.Template,
},
}, },
}, },
"invalid manifest": { "invalid manifest": {
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, rc: core.ReplicationController{
Spec: core.ReplicationControllerSpec{ ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
Selector: validSelector, Spec: core.ReplicationControllerSpec{
Selector: validSelector,
},
}, },
}, },
"read-write persistent disk with > 1 pod": { "read-write persistent disk with > 1 pod": {
ObjectMeta: metav1.ObjectMeta{Name: "abc"}, rc: core.ReplicationController{
Spec: core.ReplicationControllerSpec{ ObjectMeta: metav1.ObjectMeta{Name: "abc"},
Replicas: 2, Spec: core.ReplicationControllerSpec{
Selector: validSelector, Replicas: 2,
Template: &readWriteVolumePodTemplate.Template, Selector: validSelector,
Template: &readWriteVolumePodTemplate.Template,
},
}, },
}, },
"negative_replicas": { "negative_replicas": {
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, rc: core.ReplicationController{
Spec: core.ReplicationControllerSpec{ ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
Replicas: -1, Spec: core.ReplicationControllerSpec{
Selector: validSelector, Replicas: -1,
Selector: validSelector,
},
},
expectedOrigin: []string{
"minimum",
}, },
}, },
"invalid_label": { "invalid_label": {
ObjectMeta: metav1.ObjectMeta{ rc: core.ReplicationController{
Name: "abc-123", ObjectMeta: metav1.ObjectMeta{
Namespace: metav1.NamespaceDefault, Name: "abc-123",
Labels: map[string]string{ Namespace: metav1.NamespaceDefault,
"NoUppercaseOrSpecialCharsLike=Equals": "bar", Labels: map[string]string{
"NoUppercaseOrSpecialCharsLike=Equals": "bar",
},
},
Spec: core.ReplicationControllerSpec{
Selector: validSelector,
Template: &validPodTemplate.Template,
}, },
},
Spec: core.ReplicationControllerSpec{
Selector: validSelector,
Template: &validPodTemplate.Template,
}, },
}, },
"invalid_label 2": { "invalid_label 2": {
ObjectMeta: metav1.ObjectMeta{ rc: core.ReplicationController{
Name: "abc-123", ObjectMeta: metav1.ObjectMeta{
Namespace: metav1.NamespaceDefault, Name: "abc-123",
Labels: map[string]string{ Namespace: metav1.NamespaceDefault,
"NoUppercaseOrSpecialCharsLike=Equals": "bar", Labels: map[string]string{
"NoUppercaseOrSpecialCharsLike=Equals": "bar",
},
},
Spec: core.ReplicationControllerSpec{
Template: &invalidPodTemplate.Template,
}, },
},
Spec: core.ReplicationControllerSpec{
Template: &invalidPodTemplate.Template,
}, },
}, },
"invalid_annotation": { "invalid_annotation": {
ObjectMeta: metav1.ObjectMeta{ rc: core.ReplicationController{
Name: "abc-123", ObjectMeta: metav1.ObjectMeta{
Namespace: metav1.NamespaceDefault, Name: "abc-123",
Annotations: map[string]string{ Namespace: metav1.NamespaceDefault,
"NoUppercaseOrSpecialCharsLike=Equals": "bar", Annotations: map[string]string{
"NoUppercaseOrSpecialCharsLike=Equals": "bar",
},
},
Spec: core.ReplicationControllerSpec{
Selector: validSelector,
Template: &validPodTemplate.Template,
}, },
},
Spec: core.ReplicationControllerSpec{
Selector: validSelector,
Template: &validPodTemplate.Template,
}, },
}, },
"invalid restart policy 1": { "invalid restart policy 1": {
ObjectMeta: metav1.ObjectMeta{ rc: core.ReplicationController{
Name: "abc-123", ObjectMeta: metav1.ObjectMeta{
Namespace: metav1.NamespaceDefault, Name: "abc-123",
}, Namespace: metav1.NamespaceDefault,
Spec: core.ReplicationControllerSpec{ },
Selector: validSelector, Spec: core.ReplicationControllerSpec{
Template: &core.PodTemplateSpec{ Selector: validSelector,
Spec: podtest.MakePodSpec(podtest.SetRestartPolicy(core.RestartPolicyOnFailure)), Template: &core.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{ Spec: podtest.MakePodSpec(podtest.SetRestartPolicy(core.RestartPolicyOnFailure)),
Labels: validSelector, ObjectMeta: metav1.ObjectMeta{
Labels: validSelector,
},
}, },
}, },
}, },
}, },
"invalid restart policy 2": { "invalid restart policy 2": {
ObjectMeta: metav1.ObjectMeta{ rc: core.ReplicationController{
Name: "abc-123", ObjectMeta: metav1.ObjectMeta{
Namespace: metav1.NamespaceDefault, Name: "abc-123",
}, Namespace: metav1.NamespaceDefault,
Spec: core.ReplicationControllerSpec{ },
Selector: validSelector, Spec: core.ReplicationControllerSpec{
Template: &core.PodTemplateSpec{ Selector: validSelector,
Spec: podtest.MakePodSpec(podtest.SetRestartPolicy(core.RestartPolicyNever)), Template: &core.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{ Spec: podtest.MakePodSpec(podtest.SetRestartPolicy(core.RestartPolicyNever)),
Labels: validSelector, ObjectMeta: metav1.ObjectMeta{
Labels: validSelector,
},
}, },
}, },
}, },
}, },
"template may not contain ephemeral containers": { "template may not contain ephemeral containers": {
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault}, rc: core.ReplicationController{
Spec: core.ReplicationControllerSpec{ ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
Replicas: 1, Spec: core.ReplicationControllerSpec{
Selector: validSelector, Replicas: 1,
Template: &core.PodTemplateSpec{ Selector: validSelector,
ObjectMeta: metav1.ObjectMeta{ Template: &core.PodTemplateSpec{
Labels: validSelector, ObjectMeta: metav1.ObjectMeta{
Labels: validSelector,
},
Spec: podtest.MakePodSpec(
podtest.SetEphemeralContainers(core.EphemeralContainer{EphemeralContainerCommon: core.EphemeralContainerCommon{Name: "debug", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}),
),
}, },
Spec: podtest.MakePodSpec(
podtest.SetEphemeralContainers(core.EphemeralContainer{EphemeralContainerCommon: core.EphemeralContainerCommon{Name: "debug", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}),
),
}, },
}, },
}, },
} }
for k, v := range errorCases { for k, v := range errorCases {
errs := ValidateReplicationController(&v, PodValidationOptions{}) errs := ValidateReplicationController(&v.rc, PodValidationOptions{})
if len(errs) == 0 { if len(errs) == 0 {
t.Errorf("expected failure for %s", k) t.Errorf("expected failure for %s", k)
} }
expectedOrigins := sets.NewString(v.expectedOrigin...)
for i := range errs { for i := range errs {
field := errs[i].Field field := errs[i].Field
if !strings.HasPrefix(field, "spec.template.") && if !strings.HasPrefix(field, "spec.template.") &&
@ -16944,6 +16979,16 @@ func TestValidateReplicationController(t *testing.T) {
field != "status.replicas" { field != "status.replicas" {
t.Errorf("%s: missing prefix for: %v", k, errs[i]) t.Errorf("%s: missing prefix for: %v", k, errs[i])
} }
if len(v.expectedOrigin) > 0 && errs[i].Origin != "" {
if !expectedOrigins.Has(errs[i].Origin) {
t.Errorf("%s: unexpected origin for: %v, expected one of %v", k, errs[i].Origin, v.expectedOrigin)
}
expectedOrigins.Delete(errs[i].Origin)
}
}
if len(expectedOrigins) > 0 {
t.Errorf("%s: missing errors with origin: %v", k, expectedOrigins.List())
} }
} }
} }