From 586a0576ecbb2e9a04f606a04456b036986eea4f Mon Sep 17 00:00:00 2001 From: Shiming Zhang Date: Fri, 24 May 2024 23:22:57 +0800 Subject: [PATCH 1/2] Fix test stage --- pkg/tools/stage/stage.go | 11 +++--- pkg/utils/expression/value_duration_from.go | 38 +++++++++++++++++++++ pkg/utils/lifecycle/lifecycle.go | 27 +++++++++++++++ 3 files changed, 72 insertions(+), 4 deletions(-) diff --git a/pkg/tools/stage/stage.go b/pkg/tools/stage/stage.go index 2c238c833..d46e5f588 100644 --- a/pkg/tools/stage/stage.go +++ b/pkg/tools/stage/stage.go @@ -22,7 +22,6 @@ import ( "encoding/json" "fmt" "strings" - "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -84,15 +83,19 @@ func TestingStages(ctx context.Context, target any, stages []*internalversion.St return meta, nil } -var now = time.Date(2006, 1, 2, 15, 4, 5, 0, time.UTC) - func testingStage(ctx context.Context, testTarget Obj, stage *lifecycle.Stage) (any, error) { meta := map[string]any{ "stage": stage.Name(), } - delay, ok := stage.DelayRangePossible(ctx, testTarget, now) + delayRange, ok := stage.DelayRange(ctx, testTarget) if ok { + delay := map[string]string{ + "min": delayRange[0], + } + if len(delayRange) > 1 { + delay["max"] = delayRange[1] + } meta["delay"] = delay } diff --git a/pkg/utils/expression/value_duration_from.go b/pkg/utils/expression/value_duration_from.go index 648c6b60b..b3c2b488e 100644 --- a/pkg/utils/expression/value_duration_from.go +++ b/pkg/utils/expression/value_duration_from.go @@ -18,6 +18,7 @@ package expression import ( "context" + "fmt" "time" ) @@ -25,6 +26,8 @@ import ( type DurationGetter interface { // Get returns a duration value. Get(ctx context.Context, v interface{}, now time.Time) (time.Duration, bool) + // Info return a duration information + Info(ctx context.Context, v interface{}) (string, bool) } type durationFrom struct { @@ -78,6 +81,33 @@ func (d *durationFrom) Get(ctx context.Context, v interface{}, now time.Time) (t return 0, false } +func (d *durationFrom) Info(ctx context.Context, v interface{}) (string, bool) { + out, err := d.query.Execute(ctx, v) + if err != nil { + return "", false + } + if len(out) == 0 { + if d.value != nil { + return d.value.String(), true + } + return "", false + } + if t, ok := out[0].(string); ok { + if t == "" { + return "", false + } + _, err := time.Parse(time.RFC3339Nano, t) + if err == nil { + return fmt.Sprintf("(now - %q)", t), true + } + du, err := time.ParseDuration(t) + if err == nil { + return du.String(), true + } + } + return "", false +} + type durationNoop struct { } @@ -85,8 +115,16 @@ func (durationNoop) Get(ctx context.Context, v interface{}, now time.Time) (time return 0, false } +func (durationNoop) Info(ctx context.Context, v interface{}) (string, bool) { + return "", false +} + type duration int64 func (i duration) Get(ctx context.Context, v interface{}, now time.Time) (time.Duration, bool) { return time.Duration(i), true } + +func (i duration) Info(ctx context.Context, v interface{}) (string, bool) { + return time.Duration(i).String(), false +} diff --git a/pkg/utils/lifecycle/lifecycle.go b/pkg/utils/lifecycle/lifecycle.go index 15c1fd33b..e072a13fc 100644 --- a/pkg/utils/lifecycle/lifecycle.go +++ b/pkg/utils/lifecycle/lifecycle.go @@ -366,6 +366,33 @@ func (s *Stage) DelayRangePossible(ctx context.Context, v interface{}, now time. return []time.Duration{duration, jitterDuration}, true } +// DelayRange returns the delay range +func (s *Stage) DelayRange(ctx context.Context, v interface{}) ([]string, bool) { + if s.duration == nil { + return nil, false + } + + duration, ok := s.duration.Info(ctx, v) + if !ok { + return nil, false + } + + if s.jitterDuration == nil { + return []string{duration}, true + } + + jitterDuration, ok := s.jitterDuration.Info(ctx, v) + if !ok { + return []string{duration}, true + } + + if jitterDuration < duration { + return []string{jitterDuration}, true + } + + return []string{duration, jitterDuration}, true +} + // Next returns the next of the stage. func (s *Stage) Next() *Next { return newNext(s.next) From c4bd07d401fa6790069c6d24737013437f9f4969 Mon Sep 17 00:00:00 2001 From: Shiming Zhang Date: Fri, 24 May 2024 23:22:57 +0800 Subject: [PATCH 2/2] Add test for general pod pending --- .../general/testdata/pod-pending.input.yaml | 15 ++++++ .../general/testdata/pod-pending.output.yaml | 50 +++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 kustomize/stage/pod/general/testdata/pod-pending.input.yaml create mode 100644 kustomize/stage/pod/general/testdata/pod-pending.output.yaml diff --git a/kustomize/stage/pod/general/testdata/pod-pending.input.yaml b/kustomize/stage/pod/general/testdata/pod-pending.input.yaml new file mode 100644 index 000000000..dc515fcfe --- /dev/null +++ b/kustomize/stage/pod/general/testdata/pod-pending.input.yaml @@ -0,0 +1,15 @@ +# @Stage: ../pod-create.yaml +# @Stage: ../pod-init-container-running.yaml +# @Stage: ../pod-init-container-completed.yaml +# @Stage: ../pod-ready.yaml +# @Stage: ../pod-complete.yaml +# @Stage: ../pod-remove-finalizer.yaml +# @Stage: ../pod-delete.yaml +apiVersion: v1 +kind: Pod +metadata: + name: example-pod +spec: + containers: + - name: container + image: image diff --git a/kustomize/stage/pod/general/testdata/pod-pending.output.yaml b/kustomize/stage/pod/general/testdata/pod-pending.output.yaml new file mode 100644 index 000000000..759d5575e --- /dev/null +++ b/kustomize/stage/pod/general/testdata/pod-pending.output.yaml @@ -0,0 +1,50 @@ +apiGroup: v1 +kind: Pod +name: example-pod +stages: +- delay: + max: 5s + min: 1s + next: + - data: + - op: add + path: /metadata/finalizers + value: + - kwok.x-k8s.io/fake + kind: patch + type: application/json-patch+json + - data: + status: + conditions: + - lastProbeTime: null + lastTransitionTime: + status: "True" + type: Initialized + - lastProbeTime: null + lastTransitionTime: + message: 'containers with unready status: [ container ]' + reason: ContainersNotReady + status: "False" + type: Ready + - lastProbeTime: null + lastTransitionTime: + message: 'containers with unready status: [ container ]' + reason: ContainersNotReady + status: "False" + type: ContainersReady + containerStatuses: + - image: image + name: container + ready: false + restartCount: 0 + started: false + state: + waiting: + reason: ContainerCreating + hostIP: )> + phase: Pending + podIP: , false, "", "example-pod", "")> + kind: patch + subresource: status + type: application/merge-patch+json + stage: pod-create