From 8d610f09d15eb7925a2e82b978bbf2e07f4f454c Mon Sep 17 00:00:00 2001 From: Reed Schalo Date: Mon, 12 Aug 2024 00:41:04 -0700 Subject: [PATCH] chore: Backport NillableDuration updates for v0.34.x (#1558) Co-authored-by: Jason Deal Co-authored-by: Nick Tran <10810510+njtran@users.noreply.github.com> --- pkg/apis/v1/duration.go | 34 ++++++-- pkg/apis/v1/nodeclaim_conversion_test.go | 6 +- pkg/apis/v1/nodepool_conversion_test.go | 78 +++++++++++++++++-- pkg/apis/v1/nodepool_validation_cel_test.go | 20 ++--- pkg/apis/v1/zz_generated.deepcopy.go | 5 ++ pkg/apis/v1beta1/duration.go | 34 ++++++-- .../v1beta1/nodepool_validation_cel_test.go | 12 +-- .../nodepool_validation_webhook_test.go | 8 +- pkg/apis/v1beta1/zz_generated.deepcopy.go | 5 ++ .../disruption/consolidation_test.go | 6 +- pkg/controllers/disruption/drift_test.go | 12 +-- pkg/controllers/disruption/emptiness_test.go | 14 ++-- pkg/controllers/disruption/expiration_test.go | 12 +-- pkg/controllers/disruption/suite_test.go | 8 +- .../nodeclaim/disruption/emptiness_test.go | 4 +- .../nodeclaim/disruption/expiration_test.go | 13 ++-- .../nodeclaim/disruption/suite_test.go | 8 +- pkg/controllers/nodepool/hash/suite_test.go | 5 +- 18 files changed, 202 insertions(+), 82 deletions(-) diff --git a/pkg/apis/v1/duration.go b/pkg/apis/v1/duration.go index 5d4436984e..7eeb5fbe4a 100644 --- a/pkg/apis/v1/duration.go +++ b/pkg/apis/v1/duration.go @@ -18,7 +18,11 @@ package v1 import ( "encoding/json" + "fmt" + "slices" "time" + + "github.com/samber/lo" ) const Never = "Never" @@ -28,6 +32,17 @@ const Never = "Never" // that the duration is disabled and sets the inner duration as nil type NillableDuration struct { *time.Duration + + // Raw is used to ensure we remarshal the NillableDuration in the same format it was specified. + // This ensures tools like Flux and ArgoCD don't mistakenly detect drift due to our conversion webhooks. + Raw []byte `hash:"ignore"` +} + +func MustParseNillableDuration(val string) NillableDuration { + nd := NillableDuration{} + // Use %q instead of %s to ensure that we unmarshal the value as a string and not an int + lo.Must0(json.Unmarshal([]byte(fmt.Sprintf("%q", val)), &nd)) + return nd } // UnmarshalJSON implements the json.Unmarshaller interface. @@ -44,22 +59,29 @@ func (d *NillableDuration) UnmarshalJSON(b []byte) error { if err != nil { return err } + d.Raw = slices.Clone(b) d.Duration = &pd return nil } // MarshalJSON implements the json.Marshaler interface. func (d NillableDuration) MarshalJSON() ([]byte, error) { - if d.Duration == nil { - return json.Marshal(Never) + if d.Raw != nil { + return d.Raw, nil + } + if d.Duration != nil { + return json.Marshal(d.Duration.String()) } - return json.Marshal(d.Duration.String()) + return json.Marshal(Never) } // ToUnstructured implements the value.UnstructuredConverter interface. func (d NillableDuration) ToUnstructured() interface{} { - if d.Duration == nil { - return Never + if d.Raw != nil { + return d.Raw + } + if d.Duration != nil { + return d.Duration.String() } - return d.Duration.String() + return Never } diff --git a/pkg/apis/v1/nodeclaim_conversion_test.go b/pkg/apis/v1/nodeclaim_conversion_test.go index 0c691ec29b..d7f587e38d 100644 --- a/pkg/apis/v1/nodeclaim_conversion_test.go +++ b/pkg/apis/v1/nodeclaim_conversion_test.go @@ -287,7 +287,7 @@ var _ = Describe("Convert V1beta1 to V1 NodeClaim API", func() { }, }, } - v1nodePool.Spec.Template.Spec.ExpireAfter = NillableDuration{Duration: lo.ToPtr(30 * time.Minute)} + v1nodePool.Spec.Template.Spec.ExpireAfter = MustParseNillableDuration("30m") v1nodeclaim = &NodeClaim{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ @@ -325,13 +325,13 @@ var _ = Describe("Convert V1beta1 to V1 NodeClaim API", func() { Context("ExpireAfter", func() { It("should default the v1beta1 expireAfter to v1 when the nodepool doesn't exist", func() { Expect(env.Client.Delete(ctx, v1nodePool)).To(Succeed()) - v1nodePool.Spec.Template.Spec.ExpireAfter = NillableDuration{Duration: lo.ToPtr(30 * time.Minute)} + v1nodePool.Spec.Template.Spec.ExpireAfter = MustParseNillableDuration("30m") Expect(v1nodeclaim.ConvertFrom(ctx, v1beta1nodeclaim)).To(Succeed()) Expect(v1nodeclaim.Spec.ExpireAfter.Duration).To(BeNil()) }) It("should default the v1beta1 expireAfter to v1 when the nodepool label doesn't exist", func() { delete(v1beta1nodeclaim.Labels, v1beta1.NodePoolLabelKey) - v1nodePool.Spec.Template.Spec.ExpireAfter = NillableDuration{Duration: lo.ToPtr(30 * time.Minute)} + v1nodePool.Spec.Template.Spec.ExpireAfter = MustParseNillableDuration("30m") Expect(env.Client.Update(ctx, v1nodePool)).To(Succeed()) Expect(v1nodeclaim.ConvertFrom(ctx, v1beta1nodeclaim)).To(Succeed()) Expect(v1nodeclaim.Spec.ExpireAfter.Duration).To(BeNil()) diff --git a/pkg/apis/v1/nodepool_conversion_test.go b/pkg/apis/v1/nodepool_conversion_test.go index cf6dbcd175..d54053cd0b 100644 --- a/pkg/apis/v1/nodepool_conversion_test.go +++ b/pkg/apis/v1/nodepool_conversion_test.go @@ -212,13 +212,13 @@ var _ = Describe("Convert V1 to V1beta1 NodePool API", func() { Context("Disruption", func() { It("should convert v1 nodepool consolidateAfter to nil with WhenEmptyOrUnderutilized", func() { v1nodepool.Spec.Disruption.ConsolidationPolicy = ConsolidationPolicyWhenEmptyOrUnderutilized - v1nodepool.Spec.Disruption.ConsolidateAfter = NillableDuration{Duration: lo.ToPtr(time.Second * 2121)} + v1nodepool.Spec.Disruption.ConsolidateAfter = MustParseNillableDuration("2121s") Expect(v1nodepool.ConvertTo(ctx, v1beta1nodepool)).To(Succeed()) Expect(v1beta1nodepool.Spec.Disruption.ConsolidateAfter).To(BeNil()) }) It("should convert v1 nodepool consolidateAfter with WhenEmpty", func() { v1nodepool.Spec.Disruption.ConsolidationPolicy = ConsolidationPolicyWhenEmpty - v1nodepool.Spec.Disruption.ConsolidateAfter = NillableDuration{Duration: lo.ToPtr(time.Second * 2121)} + v1nodepool.Spec.Disruption.ConsolidateAfter = MustParseNillableDuration("2121s") Expect(v1nodepool.ConvertTo(ctx, v1beta1nodepool)).To(Succeed()) Expect(lo.FromPtr(v1beta1nodepool.Spec.Disruption.ConsolidateAfter.Duration)).To(Equal(lo.FromPtr(v1nodepool.Spec.Disruption.ConsolidateAfter.Duration))) }) @@ -228,7 +228,7 @@ var _ = Describe("Convert V1 to V1beta1 NodePool API", func() { Expect(string(v1beta1nodepool.Spec.Disruption.ConsolidationPolicy)).To(Equal(string(v1nodepool.Spec.Disruption.ConsolidationPolicy))) }) It("should convert v1 nodepool ExpireAfter", func() { - v1nodepool.Spec.Template.Spec.ExpireAfter = NillableDuration{Duration: lo.ToPtr(time.Second * 2121)} + v1nodepool.Spec.Template.Spec.ExpireAfter = MustParseNillableDuration("2121s") Expect(v1nodepool.ConvertTo(ctx, v1beta1nodepool)).To(Succeed()) Expect(v1beta1nodepool.Spec.Disruption.ExpireAfter.Duration).To(Equal(v1nodepool.Spec.Template.Spec.ExpireAfter.Duration)) }) @@ -273,6 +273,40 @@ var _ = Describe("Convert V1 to V1beta1 NodePool API", func() { Expect(v1beta1nodepool.Status.Resources[resource]).To(Equal(v1nodepool.Status.Resources[resource])) } }) + Context("Round Trip", func() { + It("spec.template.spec.expireAfter", func() { + v1nodepool.Spec.Template.Spec.ExpireAfter = MustParseNillableDuration("10h") + Expect(v1nodepool.ConvertTo(ctx, v1beta1nodepool)).To(Succeed()) + Expect(v1nodepool.ConvertFrom(ctx, v1beta1nodepool)).To(Succeed()) + result, err := json.Marshal(v1nodepool.Spec.Template.Spec.ExpireAfter) + Expect(err).To(BeNil()) + Expect(string(result)).To(Equal(`"10h"`)) + }) + It("spec.template.spec.expireAfter (Never)", func() { + v1nodepool.Spec.Template.Spec.ExpireAfter = MustParseNillableDuration("Never") + Expect(v1nodepool.ConvertTo(ctx, v1beta1nodepool)).To(Succeed()) + Expect(v1nodepool.ConvertFrom(ctx, v1beta1nodepool)).To(Succeed()) + result, err := json.Marshal(v1nodepool.Spec.Template.Spec.ExpireAfter) + Expect(err).To(BeNil()) + Expect(string(result)).To(Equal(`"Never"`)) + }) + It("spec.disruption.consolidateAfter", func() { + v1nodepool.Spec.Disruption.ConsolidateAfter = MustParseNillableDuration("10h") + Expect(v1nodepool.ConvertTo(ctx, v1beta1nodepool)).To(Succeed()) + Expect(v1nodepool.ConvertFrom(ctx, v1beta1nodepool)).To(Succeed()) + result, err := json.Marshal(v1nodepool.Spec.Disruption.ConsolidateAfter) + Expect(err).To(BeNil()) + Expect(string(result)).To(Equal(`"10h"`)) + }) + It("spec.disruption.consolidateAfter (Never)", func() { + v1nodepool.Spec.Disruption.ConsolidateAfter = MustParseNillableDuration("Never") + Expect(v1nodepool.ConvertTo(ctx, v1beta1nodepool)).To(Succeed()) + Expect(v1nodepool.ConvertFrom(ctx, v1beta1nodepool)).To(Succeed()) + result, err := json.Marshal(v1nodepool.Spec.Disruption.ConsolidateAfter) + Expect(err).To(BeNil()) + Expect(string(result)).To(Equal(`"Never"`)) + }) + }) }) var _ = Describe("Convert V1beta1 to V1 NodePool API", func() { @@ -488,7 +522,7 @@ var _ = Describe("Convert V1beta1 to V1 NodePool API", func() { }) It("should convert v1beta1 nodepool consolidateAfter for WhenEmpty", func() { v1beta1nodepool.Spec.Disruption.ConsolidationPolicy = v1beta1.ConsolidationPolicyWhenEmpty - v1beta1nodepool.Spec.Disruption.ConsolidateAfter = &v1beta1.NillableDuration{Duration: lo.ToPtr(time.Second * 2121)} + v1beta1nodepool.Spec.Disruption.ConsolidateAfter = lo.ToPtr(v1beta1.MustParseNillableDuration("2121s")) Expect(v1nodepool.ConvertFrom(ctx, v1beta1nodepool)).To(Succeed()) Expect(v1nodepool.Spec.Disruption.ConsolidateAfter.Duration).To(Equal(v1beta1nodepool.Spec.Disruption.ConsolidateAfter.Duration)) }) @@ -498,7 +532,7 @@ var _ = Describe("Convert V1beta1 to V1 NodePool API", func() { Expect(string(v1nodepool.Spec.Disruption.ConsolidationPolicy)).To(Equal(string(v1beta1nodepool.Spec.Disruption.ConsolidationPolicy))) }) It("should convert v1beta1 nodepool ExpireAfter", func() { - v1beta1nodepool.Spec.Disruption.ExpireAfter = v1beta1.NillableDuration{Duration: lo.ToPtr(time.Second * 2121)} + v1beta1nodepool.Spec.Disruption.ExpireAfter = v1beta1.MustParseNillableDuration("2121s") Expect(v1nodepool.ConvertFrom(ctx, v1beta1nodepool)).To(Succeed()) Expect(v1nodepool.Spec.Template.Spec.ExpireAfter.Duration).To(Equal(v1beta1nodepool.Spec.Disruption.ExpireAfter.Duration)) }) @@ -543,4 +577,38 @@ var _ = Describe("Convert V1beta1 to V1 NodePool API", func() { Expect(v1beta1nodepool.Status.Resources[resource]).To(Equal(v1nodepool.Status.Resources[resource])) } }) + Context("Round Trip", func() { + It("spec.disruption.expireAfter", func() { + v1beta1nodepool.Spec.Disruption.ExpireAfter = v1beta1.MustParseNillableDuration("10h") + Expect(v1nodepool.ConvertFrom(ctx, v1beta1nodepool)).To(Succeed()) + Expect(v1nodepool.ConvertTo(ctx, v1beta1nodepool)).To(Succeed()) + result, err := json.Marshal(v1beta1nodepool.Spec.Disruption.ExpireAfter) + Expect(err).To(BeNil()) + Expect(string(result)).To(Equal(`"10h"`)) + }) + It("spec.disruption.expireAfter (Never)", func() { + v1beta1nodepool.Spec.Disruption.ExpireAfter = v1beta1.MustParseNillableDuration("Never") + Expect(v1nodepool.ConvertFrom(ctx, v1beta1nodepool)).To(Succeed()) + Expect(v1nodepool.ConvertTo(ctx, v1beta1nodepool)).To(Succeed()) + result, err := json.Marshal(v1beta1nodepool.Spec.Disruption.ExpireAfter) + Expect(err).To(BeNil()) + Expect(string(result)).To(Equal(`"Never"`)) + }) + It("spec.disruption.consolidateAfter", func() { + v1beta1nodepool.Spec.Disruption.ConsolidateAfter = lo.ToPtr(v1beta1.MustParseNillableDuration("10h")) + Expect(v1nodepool.ConvertFrom(ctx, v1beta1nodepool)).To(Succeed()) + Expect(v1nodepool.ConvertTo(ctx, v1beta1nodepool)).To(Succeed()) + result, err := json.Marshal(lo.FromPtr(v1beta1nodepool.Spec.Disruption.ConsolidateAfter)) + Expect(err).To(BeNil()) + Expect(string(result)).To(Equal(`"10h"`)) + }) + It("spec.disruption.consolidateAfter (Never)", func() { + v1beta1nodepool.Spec.Disruption.ConsolidateAfter = lo.ToPtr(v1beta1.MustParseNillableDuration("Never")) + Expect(v1nodepool.ConvertFrom(ctx, v1beta1nodepool)).To(Succeed()) + Expect(v1nodepool.ConvertTo(ctx, v1beta1nodepool)).To(Succeed()) + result, err := json.Marshal(lo.FromPtr(v1beta1nodepool.Spec.Disruption.ConsolidateAfter)) + Expect(err).To(BeNil()) + Expect(string(result)).To(Equal(`"Never"`)) + }) + }) }) diff --git a/pkg/apis/v1/nodepool_validation_cel_test.go b/pkg/apis/v1/nodepool_validation_cel_test.go index 9fd907cba0..47fe40972b 100644 --- a/pkg/apis/v1/nodepool_validation_cel_test.go +++ b/pkg/apis/v1/nodepool_validation_cel_test.go @@ -64,47 +64,47 @@ var _ = Describe("CEL/Validation", func() { }) Context("Disruption", func() { It("should fail on negative expireAfter", func() { - nodePool.Spec.Template.Spec.ExpireAfter.Duration = lo.ToPtr(lo.Must(time.ParseDuration("-1s"))) + nodePool.Spec.Template.Spec.ExpireAfter = MustParseNillableDuration("-1s") Expect(env.Client.Create(ctx, nodePool)).ToNot(Succeed()) }) It("should succeed on a disabled expireAfter", func() { - nodePool.Spec.Template.Spec.ExpireAfter.Duration = nil + nodePool.Spec.Template.Spec.ExpireAfter = MustParseNillableDuration("Never") Expect(env.Client.Create(ctx, nodePool)).To(Succeed()) }) It("should succeed on a valid expireAfter", func() { - nodePool.Spec.Template.Spec.ExpireAfter.Duration = lo.ToPtr(lo.Must(time.ParseDuration("30s"))) + nodePool.Spec.Template.Spec.ExpireAfter = MustParseNillableDuration("30s") Expect(env.Client.Create(ctx, nodePool)).To(Succeed()) }) It("should fail on negative consolidateAfter", func() { - nodePool.Spec.Disruption.ConsolidateAfter = NillableDuration{Duration: lo.ToPtr(lo.Must(time.ParseDuration("-1s")))} + nodePool.Spec.Disruption.ConsolidateAfter = MustParseNillableDuration("-1s") Expect(env.Client.Create(ctx, nodePool)).ToNot(Succeed()) }) It("should succeed on a disabled consolidateAfter", func() { - nodePool.Spec.Disruption.ConsolidateAfter = NillableDuration{Duration: nil} + nodePool.Spec.Disruption.ConsolidateAfter = MustParseNillableDuration("Never") Expect(env.Client.Create(ctx, nodePool)).To(Succeed()) }) It("should succeed on a valid consolidateAfter", func() { - nodePool.Spec.Disruption.ConsolidateAfter = NillableDuration{Duration: lo.ToPtr(lo.Must(time.ParseDuration("30s")))} + nodePool.Spec.Disruption.ConsolidateAfter = MustParseNillableDuration("30s") nodePool.Spec.Disruption.ConsolidationPolicy = ConsolidationPolicyWhenEmpty Expect(env.Client.Create(ctx, nodePool)).To(Succeed()) }) It("should succeed when setting consolidateAfter with consolidationPolicy=WhenEmpty", func() { - nodePool.Spec.Disruption.ConsolidateAfter = NillableDuration{Duration: lo.ToPtr(lo.Must(time.ParseDuration("30s")))} + nodePool.Spec.Disruption.ConsolidateAfter = MustParseNillableDuration("30s") nodePool.Spec.Disruption.ConsolidationPolicy = ConsolidationPolicyWhenEmpty Expect(env.Client.Create(ctx, nodePool)).To(Succeed()) }) It("should succeed when setting consolidateAfter with consolidationPolicy=WhenEmptyOrUnderutilized", func() { - nodePool.Spec.Disruption.ConsolidateAfter = NillableDuration{Duration: lo.ToPtr(lo.Must(time.ParseDuration("30s")))} + nodePool.Spec.Disruption.ConsolidateAfter = MustParseNillableDuration("30s") nodePool.Spec.Disruption.ConsolidationPolicy = ConsolidationPolicyWhenEmptyOrUnderutilized Expect(env.Client.Create(ctx, nodePool)).To(Succeed()) }) It("should succeed when setting consolidateAfter to 'Never' with consolidationPolicy=WhenEmptyOrUnderutilized", func() { - nodePool.Spec.Disruption.ConsolidateAfter = NillableDuration{Duration: nil} + nodePool.Spec.Disruption.ConsolidateAfter = MustParseNillableDuration("Never") nodePool.Spec.Disruption.ConsolidationPolicy = ConsolidationPolicyWhenEmptyOrUnderutilized Expect(env.Client.Create(ctx, nodePool)).To(Succeed()) }) It("should succeed when setting consolidateAfter to 'Never' with consolidationPolicy=WhenEmpty", func() { - nodePool.Spec.Disruption.ConsolidateAfter = NillableDuration{Duration: nil} + nodePool.Spec.Disruption.ConsolidateAfter = MustParseNillableDuration("Never") nodePool.Spec.Disruption.ConsolidationPolicy = ConsolidationPolicyWhenEmpty }) It("should fail when creating a budget with an invalid cron", func() { diff --git a/pkg/apis/v1/zz_generated.deepcopy.go b/pkg/apis/v1/zz_generated.deepcopy.go index e1d62f319c..4ccbab50db 100644 --- a/pkg/apis/v1/zz_generated.deepcopy.go +++ b/pkg/apis/v1/zz_generated.deepcopy.go @@ -110,6 +110,11 @@ func (in *NillableDuration) DeepCopyInto(out *NillableDuration) { *out = new(timex.Duration) **out = **in } + if in.Raw != nil { + in, out := &in.Raw, &out.Raw + *out = make([]byte, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NillableDuration. diff --git a/pkg/apis/v1beta1/duration.go b/pkg/apis/v1beta1/duration.go index 66ad492c95..052dae5ac8 100644 --- a/pkg/apis/v1beta1/duration.go +++ b/pkg/apis/v1beta1/duration.go @@ -18,7 +18,11 @@ package v1beta1 import ( "encoding/json" + "fmt" + "slices" "time" + + "github.com/samber/lo" ) const Never = "Never" @@ -28,6 +32,17 @@ const Never = "Never" // that the duration is disabled and sets the inner duration as nil type NillableDuration struct { *time.Duration + + // Raw is used to ensure we remarshal the NillableDuration in the same format it was specified. + // This ensures tools like Flux and ArgoCD don't mistakenly detect drift due to our conversion webhooks. + Raw []byte `hash:"ignore"` +} + +func MustParseNillableDuration(val string) NillableDuration { + nd := NillableDuration{} + // Use %q instead of %s to ensure that we unmarshal the value as a string and not an int + lo.Must0(json.Unmarshal([]byte(fmt.Sprintf("%q", val)), &nd)) + return nd } // UnmarshalJSON implements the json.Unmarshaller interface. @@ -44,22 +59,29 @@ func (d *NillableDuration) UnmarshalJSON(b []byte) error { if err != nil { return err } + d.Raw = slices.Clone(b) d.Duration = &pd return nil } // MarshalJSON implements the json.Marshaler interface. func (d NillableDuration) MarshalJSON() ([]byte, error) { - if d.Duration == nil { - return json.Marshal(Never) + if d.Raw != nil { + return d.Raw, nil + } + if d.Duration != nil { + return json.Marshal(d.Duration.String()) } - return json.Marshal(d.Duration.String()) + return json.Marshal(Never) } // ToUnstructured implements the value.UnstructuredConverter interface. func (d NillableDuration) ToUnstructured() interface{} { - if d.Duration == nil { - return Never + if d.Raw != nil { + return d.Raw + } + if d.Duration != nil { + return d.Duration.String() } - return d.Duration.String() + return Never } diff --git a/pkg/apis/v1beta1/nodepool_validation_cel_test.go b/pkg/apis/v1beta1/nodepool_validation_cel_test.go index 2dfbd88568..512e104c27 100644 --- a/pkg/apis/v1beta1/nodepool_validation_cel_test.go +++ b/pkg/apis/v1beta1/nodepool_validation_cel_test.go @@ -75,30 +75,30 @@ var _ = Describe("CEL/Validation", func() { Expect(env.Client.Create(ctx, nodePool)).To(Succeed()) }) It("should fail on negative consolidateAfter", func() { - nodePool.Spec.Disruption.ConsolidateAfter = &NillableDuration{Duration: lo.ToPtr(lo.Must(time.ParseDuration("-1s")))} + nodePool.Spec.Disruption.ConsolidateAfter = lo.ToPtr(MustParseNillableDuration("-1s")) Expect(env.Client.Create(ctx, nodePool)).ToNot(Succeed()) }) It("should succeed on a disabled consolidateAfter", func() { - nodePool.Spec.Disruption.ConsolidateAfter = &NillableDuration{Duration: nil} + nodePool.Spec.Disruption.ConsolidateAfter = lo.ToPtr(MustParseNillableDuration("Never")) Expect(env.Client.Create(ctx, nodePool)).To(Succeed()) }) It("should succeed on a valid consolidateAfter", func() { - nodePool.Spec.Disruption.ConsolidateAfter = &NillableDuration{Duration: lo.ToPtr(lo.Must(time.ParseDuration("30s")))} + nodePool.Spec.Disruption.ConsolidateAfter = lo.ToPtr(MustParseNillableDuration("30s")) nodePool.Spec.Disruption.ConsolidationPolicy = ConsolidationPolicyWhenEmpty Expect(env.Client.Create(ctx, nodePool)).To(Succeed()) }) It("should succeed when setting consolidateAfter with consolidationPolicy=WhenEmpty", func() { - nodePool.Spec.Disruption.ConsolidateAfter = &NillableDuration{Duration: lo.ToPtr(lo.Must(time.ParseDuration("30s")))} + nodePool.Spec.Disruption.ConsolidateAfter = lo.ToPtr(MustParseNillableDuration("30s")) nodePool.Spec.Disruption.ConsolidationPolicy = ConsolidationPolicyWhenEmpty Expect(env.Client.Create(ctx, nodePool)).To(Succeed()) }) It("should fail when setting consolidateAfter with consolidationPolicy=WhenUnderutilized", func() { - nodePool.Spec.Disruption.ConsolidateAfter = &NillableDuration{Duration: lo.ToPtr(lo.Must(time.ParseDuration("30s")))} + nodePool.Spec.Disruption.ConsolidateAfter = lo.ToPtr(MustParseNillableDuration("30s")) nodePool.Spec.Disruption.ConsolidationPolicy = ConsolidationPolicyWhenUnderutilized Expect(env.Client.Create(ctx, nodePool)).ToNot(Succeed()) }) It("should succeed when not setting consolidateAfter to 'Never' with consolidationPolicy=WhenUnderutilized", func() { - nodePool.Spec.Disruption.ConsolidateAfter = &NillableDuration{Duration: nil} + nodePool.Spec.Disruption.ConsolidateAfter = lo.ToPtr(MustParseNillableDuration("Never")) nodePool.Spec.Disruption.ConsolidationPolicy = ConsolidationPolicyWhenUnderutilized Expect(env.Client.Create(ctx, nodePool)).To(Succeed()) }) diff --git a/pkg/apis/v1beta1/nodepool_validation_webhook_test.go b/pkg/apis/v1beta1/nodepool_validation_webhook_test.go index c60fd0915a..f62d4f4504 100644 --- a/pkg/apis/v1beta1/nodepool_validation_webhook_test.go +++ b/pkg/apis/v1beta1/nodepool_validation_webhook_test.go @@ -62,20 +62,20 @@ var _ = Describe("Webhook/Validation", func() { Expect(nodePool.Validate(ctx)).To(Succeed()) }) It("should succeed on a disabled consolidateAfter", func() { - nodePool.Spec.Disruption.ConsolidateAfter = &NillableDuration{Duration: nil} + nodePool.Spec.Disruption.ConsolidateAfter = lo.ToPtr(MustParseNillableDuration("Never")) Expect(nodePool.Validate(ctx)).To(Succeed()) }) It("should succeed on a valid consolidateAfter", func() { - nodePool.Spec.Disruption.ConsolidateAfter = &NillableDuration{Duration: lo.ToPtr(lo.Must(time.ParseDuration("30s")))} + nodePool.Spec.Disruption.ConsolidateAfter = lo.ToPtr(MustParseNillableDuration("30s")) Expect(nodePool.Validate(ctx)).To(Succeed()) }) It("should succeed when setting consolidateAfter with consolidationPolicy=WhenEmpty", func() { - nodePool.Spec.Disruption.ConsolidateAfter = &NillableDuration{Duration: lo.ToPtr(lo.Must(time.ParseDuration("30s")))} + nodePool.Spec.Disruption.ConsolidateAfter = lo.ToPtr(MustParseNillableDuration("30s")) nodePool.Spec.Disruption.ConsolidationPolicy = ConsolidationPolicyWhenEmpty Expect(nodePool.Validate(ctx)).To(Succeed()) }) It("should fail when setting consolidateAfter with consolidationPolicy=WhenUnderutilized", func() { - nodePool.Spec.Disruption.ConsolidateAfter = &NillableDuration{Duration: lo.ToPtr(lo.Must(time.ParseDuration("30s")))} + nodePool.Spec.Disruption.ConsolidateAfter = lo.ToPtr(MustParseNillableDuration("30s")) nodePool.Spec.Disruption.ConsolidationPolicy = ConsolidationPolicyWhenUnderutilized Expect(nodePool.Validate(ctx)).ToNot(Succeed()) }) diff --git a/pkg/apis/v1beta1/zz_generated.deepcopy.go b/pkg/apis/v1beta1/zz_generated.deepcopy.go index cabcf7f4d7..87057ee285 100644 --- a/pkg/apis/v1beta1/zz_generated.deepcopy.go +++ b/pkg/apis/v1beta1/zz_generated.deepcopy.go @@ -195,6 +195,11 @@ func (in *NillableDuration) DeepCopyInto(out *NillableDuration) { *out = new(timex.Duration) **out = **in } + if in.Raw != nil { + in, out := &in.Raw, &out.Raw + *out = make([]byte, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NillableDuration. diff --git a/pkg/controllers/disruption/consolidation_test.go b/pkg/controllers/disruption/consolidation_test.go index f8556cf188..17d51fc1b0 100644 --- a/pkg/controllers/disruption/consolidation_test.go +++ b/pkg/controllers/disruption/consolidation_test.go @@ -103,7 +103,7 @@ var _ = Describe("Consolidation", func() { It("should not fire an event for ConsolidationDisabled when the NodePool has consolidation set to WhenEmpty", func() { pod := test.Pod() nodePool.Spec.Disruption.ConsolidationPolicy = v1beta1.ConsolidationPolicyWhenEmpty - nodePool.Spec.Disruption.ConsolidateAfter = &v1beta1.NillableDuration{Duration: lo.ToPtr(time.Minute)} + nodePool.Spec.Disruption.ConsolidateAfter = lo.ToPtr(v1beta1.MustParseNillableDuration("1m")) ExpectApplied(ctx, env.Client, pod, node, nodeClaim, nodePool) ExpectManualBinding(ctx, env.Client, pod, node) @@ -118,7 +118,7 @@ var _ = Describe("Consolidation", func() { }) It("should fire an event for ConsolidationDisabled when the NodePool has consolidateAfter set to 'Never'", func() { pod := test.Pod() - nodePool.Spec.Disruption.ConsolidateAfter = &v1beta1.NillableDuration{} + nodePool.Spec.Disruption.ConsolidateAfter = lo.ToPtr(v1beta1.MustParseNillableDuration("Never")) ExpectApplied(ctx, env.Client, pod, node, nodeClaim, nodePool) ExpectManualBinding(ctx, env.Client, pod, node) @@ -4407,7 +4407,7 @@ var _ = Describe("Consolidation", func() { var nodes []*v1.Node BeforeEach(func() { - nodePool.Spec.Disruption.ExpireAfter = v1beta1.NillableDuration{Duration: lo.ToPtr(3 * time.Second)} + nodePool.Spec.Disruption.ExpireAfter = v1beta1.MustParseNillableDuration("3s") nodeClaims, nodes = test.NodeClaimsAndNodes(2, v1beta1.NodeClaim{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ diff --git a/pkg/controllers/disruption/drift_test.go b/pkg/controllers/disruption/drift_test.go index 04b10ecd2c..4e37e5e7f1 100644 --- a/pkg/controllers/disruption/drift_test.go +++ b/pkg/controllers/disruption/drift_test.go @@ -50,8 +50,8 @@ var _ = Describe("Drift", func() { nodePool = test.NodePool(v1beta1.NodePool{ Spec: v1beta1.NodePoolSpec{ Disruption: v1beta1.Disruption{ - ConsolidateAfter: &v1beta1.NillableDuration{Duration: nil}, - ExpireAfter: v1beta1.NillableDuration{Duration: nil}, + ConsolidateAfter: lo.ToPtr(v1beta1.MustParseNillableDuration("Never")), + ExpireAfter: v1beta1.MustParseNillableDuration("Never"), // Disrupt away! Budgets: []v1beta1.Budget{{ Nodes: "100%", @@ -301,8 +301,8 @@ var _ = Describe("Drift", func() { nps := test.NodePools(10, v1beta1.NodePool{ Spec: v1beta1.NodePoolSpec{ Disruption: v1beta1.Disruption{ - ConsolidateAfter: &v1beta1.NillableDuration{Duration: nil}, - ExpireAfter: v1beta1.NillableDuration{Duration: nil}, + ConsolidateAfter: lo.ToPtr(v1beta1.MustParseNillableDuration("Never")), + ExpireAfter: v1beta1.MustParseNillableDuration("Never"), Budgets: []v1beta1.Budget{{ // 1/2 of 3 nodes == 1.5 nodes. This should round up to 2. Nodes: "50%", @@ -368,8 +368,8 @@ var _ = Describe("Drift", func() { nps := test.NodePools(10, v1beta1.NodePool{ Spec: v1beta1.NodePoolSpec{ Disruption: v1beta1.Disruption{ - ConsolidateAfter: &v1beta1.NillableDuration{Duration: nil}, - ExpireAfter: v1beta1.NillableDuration{Duration: nil}, + ConsolidateAfter: lo.ToPtr(v1beta1.MustParseNillableDuration("Never")), + ExpireAfter: v1beta1.MustParseNillableDuration("Never"), Budgets: []v1beta1.Budget{{ Nodes: "100%", }}, diff --git a/pkg/controllers/disruption/emptiness_test.go b/pkg/controllers/disruption/emptiness_test.go index 935202f732..0be67dfad8 100644 --- a/pkg/controllers/disruption/emptiness_test.go +++ b/pkg/controllers/disruption/emptiness_test.go @@ -45,9 +45,9 @@ var _ = Describe("Emptiness", func() { nodePool = test.NodePool(v1beta1.NodePool{ Spec: v1beta1.NodePoolSpec{ Disruption: v1beta1.Disruption{ - ConsolidateAfter: &v1beta1.NillableDuration{Duration: lo.ToPtr(time.Second * 0)}, + ConsolidateAfter: lo.ToPtr(v1beta1.MustParseNillableDuration("0s")), ConsolidationPolicy: v1beta1.ConsolidationPolicyWhenEmpty, - ExpireAfter: v1beta1.NillableDuration{Duration: nil}, + ExpireAfter: v1beta1.MustParseNillableDuration("Never"), // Disrupt away! Budgets: []v1beta1.Budget{{ Nodes: "100%", @@ -90,7 +90,7 @@ var _ = Describe("Emptiness", func() { Expect(recorder.Calls("Unconsolidatable")).To(Equal(0)) }) It("should fire an event for ConsolidationDisabled when the NodePool has consolidateAfter set to 'Never'", func() { - nodePool.Spec.Disruption.ConsolidateAfter = &v1beta1.NillableDuration{} + nodePool.Spec.Disruption.ConsolidateAfter = lo.ToPtr(v1beta1.MustParseNillableDuration("Never")) ExpectApplied(ctx, env.Client, node, nodeClaim, nodePool) ExpectMakeNodesAndNodeClaimsInitializedAndStateUpdated(ctx, env.Client, nodeStateController, nodeClaimStateController, []*v1.Node{node}, []*v1beta1.NodeClaim{nodeClaim}) @@ -252,9 +252,9 @@ var _ = Describe("Emptiness", func() { nps := test.NodePools(10, v1beta1.NodePool{ Spec: v1beta1.NodePoolSpec{ Disruption: v1beta1.Disruption{ - ConsolidateAfter: &v1beta1.NillableDuration{Duration: lo.ToPtr(time.Second * 30)}, + ConsolidateAfter: lo.ToPtr(v1beta1.MustParseNillableDuration("30s")), ConsolidationPolicy: v1beta1.ConsolidationPolicyWhenEmpty, - ExpireAfter: v1beta1.NillableDuration{Duration: nil}, + ExpireAfter: v1beta1.MustParseNillableDuration("Never"), Budgets: []v1beta1.Budget{{ // 1/2 of 3 nodes == 1.5 nodes. This should round up to 2. Nodes: "50%", @@ -323,9 +323,9 @@ var _ = Describe("Emptiness", func() { nps := test.NodePools(10, v1beta1.NodePool{ Spec: v1beta1.NodePoolSpec{ Disruption: v1beta1.Disruption{ - ConsolidateAfter: &v1beta1.NillableDuration{Duration: lo.ToPtr(time.Second * 30)}, + ConsolidateAfter: lo.ToPtr(v1beta1.MustParseNillableDuration("30s")), ConsolidationPolicy: v1beta1.ConsolidationPolicyWhenEmpty, - ExpireAfter: v1beta1.NillableDuration{Duration: nil}, + ExpireAfter: v1beta1.MustParseNillableDuration("Never"), Budgets: []v1beta1.Budget{{ Nodes: "100%", }}, diff --git a/pkg/controllers/disruption/expiration_test.go b/pkg/controllers/disruption/expiration_test.go index d0aedf59e3..488f75c370 100644 --- a/pkg/controllers/disruption/expiration_test.go +++ b/pkg/controllers/disruption/expiration_test.go @@ -49,8 +49,8 @@ var _ = Describe("Expiration", func() { nodePool = test.NodePool(v1beta1.NodePool{ Spec: v1beta1.NodePoolSpec{ Disruption: v1beta1.Disruption{ - ConsolidateAfter: &v1beta1.NillableDuration{Duration: nil}, - ExpireAfter: v1beta1.NillableDuration{Duration: lo.ToPtr(time.Second * 30)}, + ConsolidateAfter: lo.ToPtr(v1beta1.MustParseNillableDuration("Never")), + ExpireAfter: v1beta1.MustParseNillableDuration("30s"), // Disrupt away! Budgets: []v1beta1.Budget{{ Nodes: "100%", @@ -314,8 +314,8 @@ var _ = Describe("Expiration", func() { // 1/2 of 3 nodes == 1.5 nodes. This should round up to 2. Nodes: "50%", }}, - ExpireAfter: v1beta1.NillableDuration{Duration: lo.ToPtr(time.Second * 30)}, - ConsolidateAfter: &v1beta1.NillableDuration{Duration: nil}, + ExpireAfter: v1beta1.MustParseNillableDuration("30s"), + ConsolidateAfter: lo.ToPtr(v1beta1.MustParseNillableDuration("Never")), }, }, }) @@ -379,8 +379,8 @@ var _ = Describe("Expiration", func() { Budgets: []v1beta1.Budget{{ Nodes: "100%", }}, - ExpireAfter: v1beta1.NillableDuration{Duration: lo.ToPtr(time.Second * 30)}, - ConsolidateAfter: &v1beta1.NillableDuration{Duration: nil}, + ExpireAfter: v1beta1.MustParseNillableDuration("30s"), + ConsolidateAfter: lo.ToPtr(v1beta1.MustParseNillableDuration("Never")), }, }, }) diff --git a/pkg/controllers/disruption/suite_test.go b/pkg/controllers/disruption/suite_test.go index 6dd7318673..9a47a8db78 100644 --- a/pkg/controllers/disruption/suite_test.go +++ b/pkg/controllers/disruption/suite_test.go @@ -192,7 +192,7 @@ var _ = Describe("Simulate Scheduling", func() { }, }, }) - nodePool.Spec.Disruption.ConsolidateAfter = &v1beta1.NillableDuration{Duration: nil} + nodePool.Spec.Disruption.ConsolidateAfter = lo.ToPtr(v1beta1.MustParseNillableDuration("Never")) ExpectApplied(ctx, env.Client, pod) ExpectManualBinding(ctx, env.Client, pod, nodes[0]) @@ -267,8 +267,8 @@ var _ = Describe("Simulate Scheduling", func() { Key: "test-partition", Operator: v1.NodeSelectorOpExists, }) - nodePool.Spec.Disruption.ExpireAfter = v1beta1.NillableDuration{Duration: lo.ToPtr(5 * time.Minute)} - nodePool.Spec.Disruption.ConsolidateAfter = &v1beta1.NillableDuration{Duration: nil} + nodePool.Spec.Disruption.ExpireAfter = v1beta1.MustParseNillableDuration("5m") + nodePool.Spec.Disruption.ConsolidateAfter = lo.ToPtr(v1beta1.MustParseNillableDuration("Never")) nodePool.Spec.Disruption.Budgets = []v1beta1.Budget{{Nodes: "3"}} ExpectApplied(ctx, env.Client, nodePool) @@ -521,7 +521,7 @@ var _ = Describe("Disruption Taints", func() { }, }, }) - nodePool.Spec.Disruption.ConsolidateAfter = &v1beta1.NillableDuration{Duration: nil} + nodePool.Spec.Disruption.ConsolidateAfter = lo.ToPtr(v1beta1.MustParseNillableDuration("Never")) node.Spec.Taints = append(node.Spec.Taints, v1beta1.DisruptionNoScheduleTaint) ExpectApplied(ctx, env.Client, nodePool, nodeClaim, node, pod) ExpectManualBinding(ctx, env.Client, pod, node) diff --git a/pkg/controllers/nodeclaim/disruption/emptiness_test.go b/pkg/controllers/nodeclaim/disruption/emptiness_test.go index 3e35f30c50..741658b7eb 100644 --- a/pkg/controllers/nodeclaim/disruption/emptiness_test.go +++ b/pkg/controllers/nodeclaim/disruption/emptiness_test.go @@ -42,7 +42,7 @@ var _ = Describe("Emptiness", func() { BeforeEach(func() { nodePool = test.NodePool() nodePool.Spec.Disruption.ConsolidationPolicy = v1beta1.ConsolidationPolicyWhenEmpty - nodePool.Spec.Disruption.ConsolidateAfter = &v1beta1.NillableDuration{Duration: lo.ToPtr(time.Second * 30)} + nodePool.Spec.Disruption.ConsolidateAfter = lo.ToPtr(v1beta1.MustParseNillableDuration("30s")) nodeClaim, node = test.NodeClaimAndNode(v1beta1.NodeClaim{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ @@ -148,7 +148,7 @@ var _ = Describe("Emptiness", func() { Expect(nodeClaim.StatusConditions().GetCondition(v1beta1.Empty).IsTrue()).To(BeTrue()) }) It("should remove the status condition from the nodeClaim when emptiness is disabled", func() { - nodePool.Spec.Disruption.ConsolidateAfter.Duration = nil + nodePool.Spec.Disruption.ConsolidateAfter = lo.ToPtr(v1beta1.MustParseNillableDuration("Never")) nodeClaim.StatusConditions().MarkTrue(v1beta1.Empty) ExpectApplied(ctx, env.Client, nodePool, nodeClaim, node) ExpectMakeNodeClaimsInitialized(ctx, env.Client, nodeClaim) diff --git a/pkg/controllers/nodeclaim/disruption/expiration_test.go b/pkg/controllers/nodeclaim/disruption/expiration_test.go index 6c01161d79..6a2abd8cbd 100644 --- a/pkg/controllers/nodeclaim/disruption/expiration_test.go +++ b/pkg/controllers/nodeclaim/disruption/expiration_test.go @@ -19,7 +19,6 @@ package disruption_test import ( "time" - "github.com/samber/lo" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -47,7 +46,7 @@ var _ = Describe("Expiration", func() { }) Context("Metrics", func() { It("should fire a karpenter_nodeclaims_disrupted metric when expired", func() { - nodePool.Spec.Disruption.ExpireAfter.Duration = lo.ToPtr(time.Second * 30) + nodePool.Spec.Disruption.ExpireAfter = v1beta1.MustParseNillableDuration("30s") ExpectApplied(ctx, env.Client, nodePool, nodeClaim) // step forward to make the node expired @@ -66,7 +65,7 @@ var _ = Describe("Expiration", func() { }) }) It("should remove the status condition from the NodeClaims when expiration is disabled", func() { - nodePool.Spec.Disruption.ExpireAfter.Duration = nil + nodePool.Spec.Disruption.ExpireAfter = v1beta1.MustParseNillableDuration("Never") nodeClaim.StatusConditions().MarkTrue(v1beta1.Expired) ExpectApplied(ctx, env.Client, nodePool, nodeClaim) @@ -76,7 +75,7 @@ var _ = Describe("Expiration", func() { Expect(nodeClaim.StatusConditions().GetCondition(v1beta1.Expired)).To(BeNil()) }) It("should mark NodeClaims as expired", func() { - nodePool.Spec.Disruption.ExpireAfter.Duration = lo.ToPtr(time.Second * 30) + nodePool.Spec.Disruption.ExpireAfter = v1beta1.MustParseNillableDuration("30s") ExpectApplied(ctx, env.Client, nodePool, nodeClaim) // step forward to make the node expired @@ -87,7 +86,7 @@ var _ = Describe("Expiration", func() { Expect(nodeClaim.StatusConditions().GetCondition(v1beta1.Expired).IsTrue()).To(BeTrue()) }) It("should remove the status condition from non-expired NodeClaims", func() { - nodePool.Spec.Disruption.ExpireAfter.Duration = lo.ToPtr(time.Second * 200) + nodePool.Spec.Disruption.ExpireAfter = v1beta1.MustParseNillableDuration("200s") nodeClaim.StatusConditions().MarkTrue(v1beta1.Expired) ExpectApplied(ctx, env.Client, nodePool, nodeClaim) @@ -97,7 +96,7 @@ var _ = Describe("Expiration", func() { Expect(nodeClaim.StatusConditions().GetCondition(v1beta1.Expired)).To(BeNil()) }) It("should mark NodeClaims as expired if the nodeClaim is expired but the node isn't", func() { - nodePool.Spec.Disruption.ExpireAfter.Duration = lo.ToPtr(time.Second * 30) + nodePool.Spec.Disruption.ExpireAfter = v1beta1.MustParseNillableDuration("30s") ExpectApplied(ctx, env.Client, nodePool, nodeClaim) // step forward to make the node expired @@ -109,7 +108,7 @@ var _ = Describe("Expiration", func() { Expect(nodeClaim.StatusConditions().GetCondition(v1beta1.Expired).IsTrue()).To(BeTrue()) }) It("should return the requeue interval for the time between now and when the nodeClaim expires", func() { - nodePool.Spec.Disruption.ExpireAfter.Duration = lo.ToPtr(time.Second * 200) + nodePool.Spec.Disruption.ExpireAfter = v1beta1.MustParseNillableDuration("200s") ExpectApplied(ctx, env.Client, nodePool, nodeClaim, node) fakeClock.Step(time.Second * 100) diff --git a/pkg/controllers/nodeclaim/disruption/suite_test.go b/pkg/controllers/nodeclaim/disruption/suite_test.go index 68fc4fcd55..9c0c8562c9 100644 --- a/pkg/controllers/nodeclaim/disruption/suite_test.go +++ b/pkg/controllers/nodeclaim/disruption/suite_test.go @@ -101,8 +101,8 @@ var _ = Describe("Disruption", func() { It("should set multiple disruption conditions simultaneously", func() { cp.Drifted = "drifted" nodePool.Spec.Disruption.ConsolidationPolicy = v1beta1.ConsolidationPolicyWhenEmpty - nodePool.Spec.Disruption.ConsolidateAfter = &v1beta1.NillableDuration{Duration: lo.ToPtr(time.Second * 30)} - nodePool.Spec.Disruption.ExpireAfter.Duration = lo.ToPtr(time.Second * 30) + nodePool.Spec.Disruption.ConsolidateAfter = lo.ToPtr(v1beta1.MustParseNillableDuration("30s")) + nodePool.Spec.Disruption.ExpireAfter = v1beta1.MustParseNillableDuration("30s") ExpectApplied(ctx, env.Client, nodePool, nodeClaim, node) ExpectMakeNodeClaimsInitialized(ctx, env.Client, nodeClaim) @@ -116,8 +116,8 @@ var _ = Describe("Disruption", func() { Expect(nodeClaim.StatusConditions().GetCondition(v1beta1.Expired).IsTrue()).To(BeTrue()) }) It("should remove multiple disruption conditions simultaneously", func() { - nodePool.Spec.Disruption.ExpireAfter.Duration = nil - nodePool.Spec.Disruption.ConsolidateAfter = &v1beta1.NillableDuration{Duration: nil} + nodePool.Spec.Disruption.ExpireAfter = v1beta1.MustParseNillableDuration("Never") + nodePool.Spec.Disruption.ConsolidateAfter = lo.ToPtr(v1beta1.MustParseNillableDuration("Never")) nodeClaim.StatusConditions().MarkTrue(v1beta1.Drifted) nodeClaim.StatusConditions().MarkTrue(v1beta1.Empty) diff --git a/pkg/controllers/nodepool/hash/suite_test.go b/pkg/controllers/nodepool/hash/suite_test.go index e76525221f..cb951a165b 100644 --- a/pkg/controllers/nodepool/hash/suite_test.go +++ b/pkg/controllers/nodepool/hash/suite_test.go @@ -19,7 +19,6 @@ package hash_test import ( "context" "testing" - "time" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -123,8 +122,8 @@ var _ = Describe("Static Drift Hash", func() { nodePool.Spec.Limits = v1beta1.Limits(v1.ResourceList{"cpu": resource.MustParse("16")}) nodePool.Spec.Disruption.ConsolidationPolicy = v1beta1.ConsolidationPolicyWhenEmpty - nodePool.Spec.Disruption.ConsolidateAfter = &v1beta1.NillableDuration{Duration: lo.ToPtr(30 * time.Second)} - nodePool.Spec.Disruption.ExpireAfter.Duration = lo.ToPtr(30 * time.Second) + nodePool.Spec.Disruption.ConsolidateAfter = lo.ToPtr(v1beta1.MustParseNillableDuration("30s")) + nodePool.Spec.Disruption.ExpireAfter = v1beta1.MustParseNillableDuration("30s") nodePool.Spec.Template.Spec.Requirements = []v1.NodeSelectorRequirement{ {Key: v1.LabelTopologyZone, Operator: v1.NodeSelectorOpIn, Values: []string{"test"}}, {Key: v1.LabelTopologyZone, Operator: v1.NodeSelectorOpGt, Values: []string{"1"}},