From 7315d0a68789586355cffbfcfe48c5da05b06061 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Sat, 21 Dec 2024 22:38:30 -0800 Subject: [PATCH] Change internal-version RC.Spec.Replicas to a ptr This is needed to make declaratve validation clean. Past me thought this was clever (pointer versioned, non-pointer internal) but it is just confusing. --- pkg/apis/core/fuzzer/fuzzer.go | 9 ++++- pkg/apis/core/types.go | 2 +- pkg/apis/core/v1/conversion.go | 8 ++-- pkg/apis/core/v1/zz_generated.conversion.go | 8 +--- pkg/apis/core/validation/validation.go | 10 +++-- pkg/apis/core/validation/validation_test.go | 39 +++++++++++++------ pkg/apis/core/zz_generated.deepcopy.go | 5 +++ pkg/printers/internalversion/printers.go | 3 +- pkg/printers/internalversion/printers_test.go | 14 +++++-- .../declarative_validation_test.go | 8 ++-- .../replicationcontroller/storage/storage.go | 4 +- .../storage/storage_test.go | 12 +++--- .../replicationcontroller/strategy_test.go | 13 ++++--- 13 files changed, 89 insertions(+), 46 deletions(-) diff --git a/pkg/apis/core/fuzzer/fuzzer.go b/pkg/apis/core/fuzzer/fuzzer.go index f918053ebcb..4be4286a2b7 100644 --- a/pkg/apis/core/fuzzer/fuzzer.go +++ b/pkg/apis/core/fuzzer/fuzzer.go @@ -21,8 +21,6 @@ import ( "strconv" "time" - "sigs.k8s.io/randfill" - v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -32,6 +30,7 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/kubernetes/pkg/apis/core" "k8s.io/utils/ptr" + "sigs.k8s.io/randfill" ) // Funcs returns the fuzzer functions for the core group. @@ -119,6 +118,12 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { func(j *core.ReplicationControllerSpec, c randfill.Continue) { c.FillNoCustom(j) // fuzz self without calling this function again //j.TemplateRef = nil // this is required for round trip + + // match defaulting + if j.Replicas == nil { + replicas := int32(0) + j.Replicas = &replicas + } }, func(j *core.List, c randfill.Continue) { c.FillNoCustom(j) // fuzz self without calling this function again diff --git a/pkg/apis/core/types.go b/pkg/apis/core/types.go index 7e2c2bef74f..bf94d618971 100644 --- a/pkg/apis/core/types.go +++ b/pkg/apis/core/types.go @@ -4332,7 +4332,7 @@ type PodTemplateList struct { // a TemplateRef or a Template set. type ReplicationControllerSpec struct { // Replicas is the number of desired replicas. - Replicas int32 + Replicas *int32 // Minimum number of seconds for which a newly created pod should be ready // without any of its container crashing, for it to be considered available. diff --git a/pkg/apis/core/v1/conversion.go b/pkg/apis/core/v1/conversion.go index 2ec47908e6d..06a916fe6ff 100644 --- a/pkg/apis/core/v1/conversion.go +++ b/pkg/apis/core/v1/conversion.go @@ -199,7 +199,9 @@ func Convert_apps_ReplicaSetStatus_To_v1_ReplicationControllerStatus(in *apps.Re } func Convert_core_ReplicationControllerSpec_To_v1_ReplicationControllerSpec(in *core.ReplicationControllerSpec, out *v1.ReplicationControllerSpec, s conversion.Scope) error { - out.Replicas = &in.Replicas + if err := autoConvert_core_ReplicationControllerSpec_To_v1_ReplicationControllerSpec(in, out, s); err != nil { + return err + } out.MinReadySeconds = in.MinReadySeconds out.Selector = in.Selector if in.Template != nil { @@ -214,8 +216,8 @@ func Convert_core_ReplicationControllerSpec_To_v1_ReplicationControllerSpec(in * } func Convert_v1_ReplicationControllerSpec_To_core_ReplicationControllerSpec(in *v1.ReplicationControllerSpec, out *core.ReplicationControllerSpec, s conversion.Scope) error { - if in.Replicas != nil { - out.Replicas = *in.Replicas + if err := autoConvert_v1_ReplicationControllerSpec_To_core_ReplicationControllerSpec(in, out, s); err != nil { + return err } out.MinReadySeconds = in.MinReadySeconds out.Selector = in.Selector diff --git a/pkg/apis/core/v1/zz_generated.conversion.go b/pkg/apis/core/v1/zz_generated.conversion.go index 81994392ac1..2d93df5757d 100644 --- a/pkg/apis/core/v1/zz_generated.conversion.go +++ b/pkg/apis/core/v1/zz_generated.conversion.go @@ -7416,9 +7416,7 @@ func Convert_core_ReplicationControllerList_To_v1_ReplicationControllerList(in * } func autoConvert_v1_ReplicationControllerSpec_To_core_ReplicationControllerSpec(in *corev1.ReplicationControllerSpec, out *core.ReplicationControllerSpec, s conversion.Scope) error { - if err := metav1.Convert_Pointer_int32_To_int32(&in.Replicas, &out.Replicas, s); err != nil { - return err - } + out.Replicas = (*int32)(unsafe.Pointer(in.Replicas)) out.MinReadySeconds = in.MinReadySeconds out.Selector = *(*map[string]string)(unsafe.Pointer(&in.Selector)) if in.Template != nil { @@ -7434,9 +7432,7 @@ func autoConvert_v1_ReplicationControllerSpec_To_core_ReplicationControllerSpec( } func autoConvert_core_ReplicationControllerSpec_To_v1_ReplicationControllerSpec(in *core.ReplicationControllerSpec, out *corev1.ReplicationControllerSpec, s conversion.Scope) error { - if err := metav1.Convert_int32_To_Pointer_int32(&in.Replicas, &out.Replicas, s); err != nil { - return err - } + out.Replicas = (*int32)(unsafe.Pointer(in.Replicas)) out.MinReadySeconds = in.MinReadySeconds out.Selector = *(*map[string]string)(unsafe.Pointer(&in.Selector)) if in.Template != nil { diff --git a/pkg/apis/core/validation/validation.go b/pkg/apis/core/validation/validation.go index 1905b9af48e..298aa7b621d 100644 --- a/pkg/apis/core/validation/validation.go +++ b/pkg/apis/core/validation/validation.go @@ -6291,7 +6291,7 @@ func ValidateNonEmptySelector(selectorMap map[string]string, fldPath *field.Path } // Validates the given template and ensures that it is in accordance with the desired selector and replicas. -func ValidatePodTemplateSpecForRC(template *core.PodTemplateSpec, selectorMap map[string]string, replicas int32, fldPath *field.Path, opts PodValidationOptions) field.ErrorList { +func ValidatePodTemplateSpecForRC(template *core.PodTemplateSpec, selectorMap map[string]string, fldPath *field.Path, opts PodValidationOptions) field.ErrorList { allErrs := field.ErrorList{} if template == nil { allErrs = append(allErrs, field.Required(fldPath, "")) @@ -6321,8 +6321,12 @@ func ValidateReplicationControllerSpec(spec, oldSpec *core.ReplicationController allErrs := field.ErrorList{} allErrs = append(allErrs, ValidateNonnegativeField(int64(spec.MinReadySeconds), fldPath.Child("minReadySeconds"))...) allErrs = append(allErrs, ValidateNonEmptySelector(spec.Selector, fldPath.Child("selector"))...) - allErrs = append(allErrs, ValidateNonnegativeField(int64(spec.Replicas), fldPath.Child("replicas"))...) - allErrs = append(allErrs, ValidatePodTemplateSpecForRC(spec.Template, spec.Selector, spec.Replicas, fldPath.Child("template"), opts)...) + if spec.Replicas == nil { + allErrs = append(allErrs, field.Required(fldPath.Child("replicas"), "")) + } else { + allErrs = append(allErrs, ValidateNonnegativeField(int64(*spec.Replicas), fldPath.Child("replicas"))...) + } + allErrs = append(allErrs, ValidatePodTemplateSpecForRC(spec.Template, spec.Selector, fldPath.Child("template"), opts)...) return allErrs } diff --git a/pkg/apis/core/validation/validation_test.go b/pkg/apis/core/validation/validation_test.go index 19fc8d231a0..705b0258d31 100644 --- a/pkg/apis/core/validation/validation_test.go +++ b/pkg/apis/core/validation/validation_test.go @@ -16670,7 +16670,7 @@ func TestValidateReplicationControllerStatusUpdate(t *testing.T) { update: core.ReplicationController{ ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, Spec: core.ReplicationControllerSpec{ - Replicas: 3, + Replicas: ptr.To[int32](3), Selector: validSelector, Template: &validPodTemplate.Template, }, @@ -16702,7 +16702,7 @@ func TestValidateReplicationControllerStatusUpdate(t *testing.T) { update: core.ReplicationController{ ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, Spec: core.ReplicationControllerSpec{ - Replicas: 2, + Replicas: ptr.To[int32](2), Selector: validSelector, Template: &validPodTemplate.Template, }, @@ -16725,7 +16725,7 @@ func mkValidReplicationController(tweaks ...func(rc *core.ReplicationController) rc := core.ReplicationController{ ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, Spec: core.ReplicationControllerSpec{ - Replicas: 1, + Replicas: ptr.To[int32](1), Selector: map[string]string{"a": "b"}, Template: &core.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ @@ -16748,17 +16748,17 @@ func TestValidateReplicationControllerUpdate(t *testing.T) { }{{ old: mkValidReplicationController(func(rc *core.ReplicationController) {}), update: mkValidReplicationController(func(rc *core.ReplicationController) { - rc.Spec.Replicas = 0 + rc.Spec.Replicas = ptr.To[int32](0) }), }, { old: mkValidReplicationController(func(rc *core.ReplicationController) {}), update: mkValidReplicationController(func(rc *core.ReplicationController) { - rc.Spec.Replicas = 3 + rc.Spec.Replicas = ptr.To[int32](3) }), }, { old: mkValidReplicationController(func(rc *core.ReplicationController) {}), update: mkValidReplicationController(func(rc *core.ReplicationController) { - rc.Spec.Replicas = 2 + rc.Spec.Replicas = ptr.To[int32](2) rc.Spec.Template.Spec = podtest.MakePodSpec( podtest.SetVolumes( core.Volume{ @@ -16816,12 +16816,21 @@ func TestValidateReplicationControllerUpdate(t *testing.T) { "negative replicas": { old: mkValidReplicationController(func(rc *core.ReplicationController) {}), update: mkValidReplicationController(func(rc *core.ReplicationController) { - rc.Spec.Replicas = -1 + rc.Spec.Replicas = ptr.To[int32](-1) }), expectedErrs: field.ErrorList{ field.Invalid(field.NewPath("spec.replicas"), nil, "").WithOrigin("minimum"), }, }, + "nil replicas": { + old: mkValidReplicationController(func(rc *core.ReplicationController) {}), + update: mkValidReplicationController(func(rc *core.ReplicationController) { + rc.Spec.Replicas = nil + }), + expectedErrs: field.ErrorList{ + field.Required(field.NewPath("spec.replicas"), ""), + }, + }, } for k, tc := range errorCases { t.Run(k, func(t *testing.T) { @@ -16839,7 +16848,7 @@ func TestValidateReplicationController(t *testing.T) { mkValidReplicationController(func(rc *core.ReplicationController) {}), mkValidReplicationController(func(rc *core.ReplicationController) { rc.Name = "abc-123" }), mkValidReplicationController(func(rc *core.ReplicationController) { - rc.Spec.Replicas = 2 + rc.Spec.Replicas = ptr.To[int32](2) rc.Spec.Template.Spec = podtest.MakePodSpec( podtest.SetVolumes( core.Volume{ @@ -16860,9 +16869,9 @@ func TestValidateReplicationController(t *testing.T) { }))), ) }), - mkValidReplicationController(func(rc *core.ReplicationController) { rc.Spec.Replicas = 0 }), - mkValidReplicationController(func(rc *core.ReplicationController) { rc.Spec.Replicas = 1 }), - mkValidReplicationController(func(rc *core.ReplicationController) { rc.Spec.Replicas = 100 }), + mkValidReplicationController(func(rc *core.ReplicationController) { rc.Spec.Replicas = ptr.To[int32](0) }), + mkValidReplicationController(func(rc *core.ReplicationController) { rc.Spec.Replicas = ptr.To[int32](1) }), + mkValidReplicationController(func(rc *core.ReplicationController) { rc.Spec.Replicas = ptr.To[int32](100) }), } for _, tc := range successCases { if errs := ValidateReplicationController(&tc, PodValidationOptions{}); len(errs) != 0 { @@ -16905,11 +16914,17 @@ func TestValidateReplicationController(t *testing.T) { }, }, "negative replicas": { - input: mkValidReplicationController(func(rc *core.ReplicationController) { rc.Spec.Replicas = -1 }), + input: mkValidReplicationController(func(rc *core.ReplicationController) { rc.Spec.Replicas = ptr.To[int32](-1) }), expectedErrs: field.ErrorList{ field.Invalid(field.NewPath("spec.replicas"), nil, "").WithOrigin("minimum"), }, }, + "nil replicas": { + input: mkValidReplicationController(func(rc *core.ReplicationController) { rc.Spec.Replicas = nil }), + expectedErrs: field.ErrorList{ + field.Required(field.NewPath("spec.replicas"), ""), + }, + }, "invalid label": { input: mkValidReplicationController(func(rc *core.ReplicationController) { rc.Labels = map[string]string{ diff --git a/pkg/apis/core/zz_generated.deepcopy.go b/pkg/apis/core/zz_generated.deepcopy.go index a9d32c1ca69..6d63d2da3e7 100644 --- a/pkg/apis/core/zz_generated.deepcopy.go +++ b/pkg/apis/core/zz_generated.deepcopy.go @@ -4920,6 +4920,11 @@ func (in *ReplicationControllerList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ReplicationControllerSpec) DeepCopyInto(out *ReplicationControllerSpec) { *out = *in + if in.Replicas != nil { + in, out := &in.Replicas, &out.Replicas + *out = new(int32) + **out = **in + } if in.Selector != nil { in, out := &in.Selector, &out.Selector *out = make(map[string]string, len(*in)) diff --git a/pkg/printers/internalversion/printers.go b/pkg/printers/internalversion/printers.go index 868ab8170da..b0d7e421dd1 100644 --- a/pkg/printers/internalversion/printers.go +++ b/pkg/printers/internalversion/printers.go @@ -51,6 +51,7 @@ import ( "k8s.io/apimachinery/pkg/util/duration" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/client-go/util/certificate/csr" + "k8s.io/utils/ptr" podutil "k8s.io/kubernetes/pkg/api/pod" podutilv1 "k8s.io/kubernetes/pkg/api/v1/pod" @@ -1123,7 +1124,7 @@ func printReplicationController(obj *api.ReplicationController, options printers Object: runtime.RawExtension{Object: obj}, } - desiredReplicas := obj.Spec.Replicas + desiredReplicas := ptr.Deref(obj.Spec.Replicas, 0) currentReplicas := obj.Status.Replicas readyReplicas := obj.Status.ReadyReplicas diff --git a/pkg/printers/internalversion/printers_test.go b/pkg/printers/internalversion/printers_test.go index e72cab35696..e5e71ae3fca 100644 --- a/pkg/printers/internalversion/printers_test.go +++ b/pkg/printers/internalversion/printers_test.go @@ -25,7 +25,6 @@ import ( "time" "github.com/google/go-cmp/cmp" - apiv1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -4559,18 +4558,21 @@ func TestPrintCertificateSigningRequest(t *testing.T) { func TestPrintReplicationController(t *testing.T) { tests := []struct { + name string rc api.ReplicationController options printers.GenerateOptions expected []metav1.TableRow }{ // Basic print replication controller without replicas or status. { + name: "basic", rc: api.ReplicationController{ ObjectMeta: metav1.ObjectMeta{ Name: "rc1", Namespace: "test-namespace", }, Spec: api.ReplicationControllerSpec{ + Replicas: ptr.To[int32](0), Selector: map[string]string{"a": "b"}, Template: &api.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ @@ -4597,13 +4599,14 @@ func TestPrintReplicationController(t *testing.T) { }, // Basic print replication controller with replicas; does not print containers or labels { + name: "basic with replicas", rc: api.ReplicationController{ ObjectMeta: metav1.ObjectMeta{ Name: "rc1", Namespace: "test-namespace", }, Spec: api.ReplicationControllerSpec{ - Replicas: 5, + Replicas: ptr.To[int32](5), Selector: map[string]string{"a": "b"}, Template: &api.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ @@ -4634,12 +4637,13 @@ func TestPrintReplicationController(t *testing.T) { }, // Generate options: Wide; print containers and labels. { + name: "wide", rc: api.ReplicationController{ ObjectMeta: metav1.ObjectMeta{ Name: "rc1", }, Spec: api.ReplicationControllerSpec{ - Replicas: 5, + Replicas: ptr.To[int32](5), Selector: map[string]string{"a": "b"}, Template: &api.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ @@ -4670,12 +4674,16 @@ func TestPrintReplicationController(t *testing.T) { }, { // make sure Bookmark event will not lead a panic + name: "no panic", rc: api.ReplicationController{ ObjectMeta: metav1.ObjectMeta{ Annotations: map[string]string{ metav1.InitialEventsAnnotationKey: "true", }, }, + Spec: api.ReplicationControllerSpec{ + Replicas: ptr.To[int32](0), + }, }, options: printers.GenerateOptions{Wide: true}, // Columns: Name, Desired, Current, Ready, Age, Containers, Images, Selector diff --git a/pkg/registry/core/replicationcontroller/declarative_validation_test.go b/pkg/registry/core/replicationcontroller/declarative_validation_test.go index 4c06439d7f4..048fddb779f 100644 --- a/pkg/registry/core/replicationcontroller/declarative_validation_test.go +++ b/pkg/registry/core/replicationcontroller/declarative_validation_test.go @@ -28,6 +28,7 @@ import ( apitesting "k8s.io/kubernetes/pkg/api/testing" api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/features" + "k8s.io/utils/ptr" ) func TestDeclarativeValidateForDeclarative(t *testing.T) { @@ -121,7 +122,7 @@ func TestValidateUpdateForDeclarative(t *testing.T) { // The equivalenceMatcher is used to verify the output errors from hand-written imperative validation // are equivalent to the output errors when DeclarativeValidationTakeover is enabled. equivalenceMatcher := field.ErrorMatcher{}.ByType().ByField().ByOrigin() - // TODO: remove this once ErrorMatcher has been extended to handle this form of deduplication. + // TODO: remove this once RC's validation is fixed to not return duplicate errors. dedupedImperativeErrs := field.ErrorList{} for _, err := range imperativeErrs { found := false @@ -142,12 +143,13 @@ func TestValidateUpdateForDeclarative(t *testing.T) { } } -// Helper function for RC tests. +// mkValidReplicationController produces a ReplicationController which passes +// validation with no tweaks. func mkValidReplicationController(tweaks ...func(rc *api.ReplicationController)) api.ReplicationController { rc := api.ReplicationController{ ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, Spec: api.ReplicationControllerSpec{ - Replicas: 1, + Replicas: ptr.To[int32](1), Selector: map[string]string{"a": "b"}, Template: &api.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ diff --git a/pkg/registry/core/replicationcontroller/storage/storage.go b/pkg/registry/core/replicationcontroller/storage/storage.go index b2e34c9560d..3bd7e2a421e 100644 --- a/pkg/registry/core/replicationcontroller/storage/storage.go +++ b/pkg/registry/core/replicationcontroller/storage/storage.go @@ -244,7 +244,7 @@ func scaleFromRC(rc *api.ReplicationController) *autoscaling.Scale { CreationTimestamp: rc.CreationTimestamp, }, Spec: autoscaling.ScaleSpec{ - Replicas: rc.Spec.Replicas, + Replicas: *rc.Spec.Replicas, }, Status: autoscaling.ScaleStatus{ Replicas: rc.Status.Replicas, @@ -325,7 +325,7 @@ func (i *scaleUpdatedObjectInfo) UpdatedObject(ctx context.Context, oldObj runti } // move replicas/resourceVersion fields to object and return - replicationcontroller.Spec.Replicas = scale.Spec.Replicas + replicationcontroller.Spec.Replicas = &scale.Spec.Replicas replicationcontroller.ResourceVersion = scale.ResourceVersion updatedEntries, err := managedFieldsHandler.ToParent(scale.ManagedFields) diff --git a/pkg/registry/core/replicationcontroller/storage/storage_test.go b/pkg/registry/core/replicationcontroller/storage/storage_test.go index cf840aa972e..92ab6179a0c 100644 --- a/pkg/registry/core/replicationcontroller/storage/storage_test.go +++ b/pkg/registry/core/replicationcontroller/storage/storage_test.go @@ -38,6 +38,7 @@ import ( "k8s.io/kubernetes/pkg/apis/autoscaling" api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/registry/registrytest" + "k8s.io/utils/ptr" ) const ( @@ -85,6 +86,7 @@ func validNewController() *api.ReplicationController { }, Spec: podtest.MakePodSpec(), }, + Replicas: ptr.To[int32](1), }, } } @@ -104,7 +106,7 @@ func TestCreate(t *testing.T) { // invalid (invalid selector) &api.ReplicationController{ Spec: api.ReplicationControllerSpec{ - Replicas: 2, + Replicas: ptr.To[int32](2), Selector: map[string]string{}, Template: validController.Spec.Template, }, @@ -123,7 +125,7 @@ func TestUpdate(t *testing.T) { // valid updateFunc func(obj runtime.Object) runtime.Object { object := obj.(*api.ReplicationController) - object.Spec.Replicas = object.Spec.Replicas + 1 + object.Spec.Replicas = ptr.To[int32](*object.Spec.Replicas + 1) return object }, // invalid updateFunc @@ -172,7 +174,7 @@ func TestGenerationNumber(t *testing.T) { } // Updates to spec should increment the generation number - controller.Spec.Replicas++ + (*controller.Spec.Replicas)++ if _, _, err := storage.Controller.Update(ctx, controller.Name, rest.DefaultUpdatedObjectInfo(controller), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { t.Errorf("unexpected error: %v", err) } @@ -297,7 +299,7 @@ func TestScaleGet(t *testing.T) { CreationTimestamp: rc.CreationTimestamp, }, Spec: autoscaling.ScaleSpec{ - Replicas: validController.Spec.Replicas, + Replicas: *validController.Spec.Replicas, }, Status: autoscaling.ScaleStatus{ Replicas: validController.Status.Replicas, @@ -341,7 +343,7 @@ func TestScaleUpdate(t *testing.T) { } scale := obj.(*autoscaling.Scale) if scale.Spec.Replicas != replicas { - t.Errorf("wrong replicas count expected: %d got: %d", replicas, rc.Spec.Replicas) + t.Errorf("wrong replicas count expected: %d got: %d", replicas, *rc.Spec.Replicas) } update.ResourceVersion = rc.ResourceVersion diff --git a/pkg/registry/core/replicationcontroller/strategy_test.go b/pkg/registry/core/replicationcontroller/strategy_test.go index d22d82458da..115e60f823c 100644 --- a/pkg/registry/core/replicationcontroller/strategy_test.go +++ b/pkg/registry/core/replicationcontroller/strategy_test.go @@ -25,6 +25,7 @@ import ( podtest "k8s.io/kubernetes/pkg/api/pod/testing" apitesting "k8s.io/kubernetes/pkg/api/testing" api "k8s.io/kubernetes/pkg/apis/core" + "k8s.io/utils/ptr" // ensure types are installed _ "k8s.io/kubernetes/pkg/apis/core/install" @@ -53,6 +54,7 @@ func TestControllerStrategy(t *testing.T) { Spec: api.ReplicationControllerSpec{ Selector: validSelector, Template: &validPodTemplate.Template, + Replicas: ptr.To[int32](1), }, Status: api.ReplicationControllerStatus{ Replicas: 1, @@ -67,6 +69,7 @@ func TestControllerStrategy(t *testing.T) { if rc.Status.ObservedGeneration != int64(0) { t.Error("ReplicationController should not allow setting status.observedGeneration on create") } + errs := Strategy.Validate(ctx, rc) if len(errs) != 0 { t.Errorf("Unexpected error validating %v", errs) @@ -109,7 +112,7 @@ func TestControllerStatusStrategy(t *testing.T) { oldController := &api.ReplicationController{ ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault, ResourceVersion: "10"}, Spec: api.ReplicationControllerSpec{ - Replicas: 3, + Replicas: ptr.To[int32](3), Selector: validSelector, Template: &validPodTemplate.Template, }, @@ -121,7 +124,7 @@ func TestControllerStatusStrategy(t *testing.T) { newController := &api.ReplicationController{ ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault, ResourceVersion: "9"}, Spec: api.ReplicationControllerSpec{ - Replicas: 1, + Replicas: ptr.To[int32](1), Selector: validSelector, Template: &validPodTemplate.Template, }, @@ -134,7 +137,7 @@ func TestControllerStatusStrategy(t *testing.T) { if newController.Status.Replicas != 3 { t.Errorf("Replication controller status updates should allow change of replicas: %v", newController.Status.Replicas) } - if newController.Spec.Replicas != 3 { + if *newController.Spec.Replicas != 3 { t.Errorf("PrepareForUpdate should have preferred spec") } errs := StatusStrategy.ValidateUpdate(ctx, newController, oldController) @@ -166,7 +169,7 @@ func TestValidateUpdate(t *testing.T) { oldController := &api.ReplicationController{ ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault, ResourceVersion: "10", Annotations: make(map[string]string)}, Spec: api.ReplicationControllerSpec{ - Replicas: 3, + Replicas: ptr.To[int32](3), Selector: validSelector, Template: &validPodTemplate.Template, }, @@ -182,7 +185,7 @@ func TestValidateUpdate(t *testing.T) { newController := oldController.DeepCopy() // Irrelevant (to the selector) update for the replication controller. - newController.Spec.Replicas = 5 + newController.Spec.Replicas = ptr.To[int32](5) // If they didn't try to update the selector then we should not return any error. errs := Strategy.ValidateUpdate(ctx, newController, oldController)