From 1b2076122e305f1523e1eb0b874160877a012863 Mon Sep 17 00:00:00 2001 From: Tharun Date: Fri, 27 Nov 2020 23:55:31 +0530 Subject: [PATCH 1/8] feat(minikube) display scheduledstop status in minikube status Signed-off-by: Tharun --- cmd/minikube/cmd/status.go | 55 +++++++++++++++++++++++++++ cmd/minikube/cmd/status_test.go | 67 +++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) diff --git a/cmd/minikube/cmd/status.go b/cmd/minikube/cmd/status.go index 11950ee7d082..e35b2b46857e 100644 --- a/cmd/minikube/cmd/status.go +++ b/cmd/minikube/cmd/status.go @@ -170,6 +170,12 @@ type BaseState struct { StepDetail string `json:",omitempty"` } +// ScheduledStopStatus holds string representation of scheduledStopDuration +type ScheduledStopStatus struct { + InitiatedTime string `json:",omitempty"` + ScheduledTime string `json:",omitempty"` +} + const ( minikubeNotRunningStatusFlag = 1 << 0 clusterNotRunningStatusFlag = 1 << 1 @@ -187,6 +193,12 @@ type: Worker host: {{.Host}} kubelet: {{.Kubelet}} +` + + scheduledStopStatusFormat = `type: ScheduledDuration +initiatedTime: {{.InitiatedTime}} +scheduledTime: {{.ScheduledTime}} + ` ) @@ -256,6 +268,11 @@ func writeStatusesAtInterval(duration time.Duration, api libmachine.API, cc *con exit.Error(reason.InternalStatusText, "status text failure", err) } } + if cc.ScheduledStop != nil { + if err := scheduledStopStatusText(cc.ScheduledStop, os.Stdout); err != nil { + exit.Error(reason.InternalStatusText, "status text failure", err) + } + } case "json": // Layout is currently only supported for JSON mode if layout == "cluster" { @@ -267,6 +284,11 @@ func writeStatusesAtInterval(duration time.Duration, api libmachine.API, cc *con exit.Error(reason.InternalStatusJSON, "status json failure", err) } } + if cc.ScheduledStop != nil { + if err := scheduledStopStatusJSON(cc.ScheduledStop, os.Stdout); err != nil { + exit.Error(reason.InternalStatusJSON, "scheduledstop status json failure", err) + } + } default: exit.Message(reason.Usage, fmt.Sprintf("invalid output format: %s. Valid values: 'text', 'json'", output)) } @@ -444,6 +466,39 @@ func statusJSON(st []*Status, w io.Writer) error { return err } +func scheduledStopStatusText(sd *config.ScheduledStopConfig, w io.Writer) error { + var scheduledStopStatus ScheduledStopStatus + if sd.InitiationTime == 0 { + scheduledStopStatus.InitiatedTime = "-" + } else { + scheduledStopStatus.InitiatedTime = time.Unix(sd.InitiationTime, 0).String() + } + if sd.Duration == 0 { + scheduledStopStatus.ScheduledTime = "-" + } else { + stopAt := time.Now().Add(sd.Duration).Unix() + scheduledStopStatus.ScheduledTime = time.Unix(stopAt, 0).String() + } + tmpl, err := template.New("scheduled-stop-status").Parse(scheduledStopStatusFormat) + if err != nil { + return err + } + if err := tmpl.Execute(w, scheduledStopStatus); err != nil { + return err + } + return nil +} + +func scheduledStopStatusJSON(sd *config.ScheduledStopConfig, w io.Writer) error { + var js []byte + js, err := json.Marshal(sd) + if err != nil { + return err + } + _, err = w.Write(js) + return err +} + // readEventLog reads cloudevent logs from $MINIKUBE_HOME/profiles//events.json func readEventLog(name string) ([]cloudevents.Event, time.Time, error) { path := localpath.EventLog(name) diff --git a/cmd/minikube/cmd/status_test.go b/cmd/minikube/cmd/status_test.go index 8bae78103706..dc3d9b6e6592 100644 --- a/cmd/minikube/cmd/status_test.go +++ b/cmd/minikube/cmd/status_test.go @@ -20,6 +20,9 @@ import ( "bytes" "encoding/json" "testing" + "time" + + "k8s.io/minikube/pkg/minikube/config" ) func TestExitCode(t *testing.T) { @@ -105,3 +108,67 @@ func TestStatusJSON(t *testing.T) { }) } } + +func TestScheduledStopStatusText(t *testing.T) { + now := time.Now().Unix() + initiationTime := time.Unix(now, 0).String() + + stopAt := time.Now().Add(time.Minute * 10).Unix() + scheduledTime := time.Unix(stopAt, 0).String() + var tests = []struct { + name string + state *config.ScheduledStopConfig + want string + }{ + { + name: "valid", + state: &config.ScheduledStopConfig{InitiationTime: now, Duration: time.Minute * 10}, + want: "type: ScheduledDuration\ninitiatedTime: " + initiationTime + "\nscheduledTime: " + scheduledTime + "\n\n", + }, + { + name: "missing", + state: &config.ScheduledStopConfig{}, + want: "type: ScheduledDuration\ninitiatedTime: -\nscheduledTime: -\n\n", + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + var b bytes.Buffer + err := scheduledStopStatusText(tc.state, &b) + if err != nil { + t.Errorf("text(%+v) error: %v", tc.state, err) + } + + got := b.String() + if got != tc.want { + t.Errorf("text(%+v) = %q, want: %q", tc.state, got, tc.want) + } + }) + } +} + +func TestScheduledStopStatusJSON(t *testing.T) { + var tests = []struct { + name string + state *config.ScheduledStopConfig + }{ + { + name: "valid", + state: &config.ScheduledStopConfig{InitiationTime: time.Now().Unix(), Duration: time.Minute * 5}, + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + var b bytes.Buffer + err := scheduledStopStatusJSON(tc.state, &b) + if err != nil { + t.Errorf("json(%+v) error: %v", tc.state, err) + } + + st := &Status{} + if err := json.Unmarshal(b.Bytes(), st); err != nil { + t.Errorf("json(%+v) unmarshal error: %v", tc.state, err) + } + }) + } +} From 81e27dd7b42c1d953f5628ce2a1f483fcbddd962 Mon Sep 17 00:00:00 2001 From: Tharun Date: Wed, 2 Dec 2020 16:50:02 +0530 Subject: [PATCH 2/8] fixed review feedbacks Signed-off-by: Tharun --- cmd/minikube/cmd/status.go | 65 +++---------------- cmd/minikube/cmd/status_test.go | 85 +++---------------------- site/content/en/docs/commands/status.md | 2 +- 3 files changed, 19 insertions(+), 133 deletions(-) diff --git a/cmd/minikube/cmd/status.go b/cmd/minikube/cmd/status.go index e35b2b46857e..c985c72157b3 100644 --- a/cmd/minikube/cmd/status.go +++ b/cmd/minikube/cmd/status.go @@ -135,6 +135,7 @@ type Status struct { APIServer string Kubeconfig string Worker bool + TimeToStop string } // ClusterState holds a cluster state representation @@ -170,12 +171,6 @@ type BaseState struct { StepDetail string `json:",omitempty"` } -// ScheduledStopStatus holds string representation of scheduledStopDuration -type ScheduledStopStatus struct { - InitiatedTime string `json:",omitempty"` - ScheduledTime string `json:",omitempty"` -} - const ( minikubeNotRunningStatusFlag = 1 << 0 clusterNotRunningStatusFlag = 1 << 1 @@ -186,6 +181,7 @@ host: {{.Host}} kubelet: {{.Kubelet}} apiserver: {{.APIServer}} kubeconfig: {{.Kubeconfig}} +timeToStop: {{.TimeToStop}} ` workerStatusFormat = `{{.Name}} @@ -193,12 +189,6 @@ type: Worker host: {{.Host}} kubelet: {{.Kubelet}} -` - - scheduledStopStatusFormat = `type: ScheduledDuration -initiatedTime: {{.InitiatedTime}} -scheduledTime: {{.ScheduledTime}} - ` ) @@ -268,11 +258,6 @@ func writeStatusesAtInterval(duration time.Duration, api libmachine.API, cc *con exit.Error(reason.InternalStatusText, "status text failure", err) } } - if cc.ScheduledStop != nil { - if err := scheduledStopStatusText(cc.ScheduledStop, os.Stdout); err != nil { - exit.Error(reason.InternalStatusText, "status text failure", err) - } - } case "json": // Layout is currently only supported for JSON mode if layout == "cluster" { @@ -284,11 +269,6 @@ func writeStatusesAtInterval(duration time.Duration, api libmachine.API, cc *con exit.Error(reason.InternalStatusJSON, "status json failure", err) } } - if cc.ScheduledStop != nil { - if err := scheduledStopStatusJSON(cc.ScheduledStop, os.Stdout); err != nil { - exit.Error(reason.InternalStatusJSON, "scheduledstop status json failure", err) - } - } default: exit.Message(reason.Usage, fmt.Sprintf("invalid output format: %s. Valid values: 'text', 'json'", output)) } @@ -329,6 +309,7 @@ func nodeStatus(api libmachine.API, cc config.ClusterConfig, n config.Node) (*St Kubelet: Nonexistent, Kubeconfig: Nonexistent, Worker: !controlPlane, + TimeToStop: Nonexistent, } hs, err := machine.Status(api, name) @@ -388,7 +369,12 @@ func nodeStatus(api libmachine.API, cc config.ClusterConfig, n config.Node) (*St stk := kverify.ServiceStatus(cr, "kubelet") st.Kubelet = stk.String() - + if cc.ScheduledStop != nil { + initiationTime := time.Unix(cc.ScheduledStop.InitiationTime, 0) + st.TimeToStop = time.Until(initiationTime.Add(cc.ScheduledStop.Duration)).String() + } else { + st.TimeToStop = Irrelevant + } // Early exit for worker nodes if !controlPlane { return st, nil @@ -466,39 +452,6 @@ func statusJSON(st []*Status, w io.Writer) error { return err } -func scheduledStopStatusText(sd *config.ScheduledStopConfig, w io.Writer) error { - var scheduledStopStatus ScheduledStopStatus - if sd.InitiationTime == 0 { - scheduledStopStatus.InitiatedTime = "-" - } else { - scheduledStopStatus.InitiatedTime = time.Unix(sd.InitiationTime, 0).String() - } - if sd.Duration == 0 { - scheduledStopStatus.ScheduledTime = "-" - } else { - stopAt := time.Now().Add(sd.Duration).Unix() - scheduledStopStatus.ScheduledTime = time.Unix(stopAt, 0).String() - } - tmpl, err := template.New("scheduled-stop-status").Parse(scheduledStopStatusFormat) - if err != nil { - return err - } - if err := tmpl.Execute(w, scheduledStopStatus); err != nil { - return err - } - return nil -} - -func scheduledStopStatusJSON(sd *config.ScheduledStopConfig, w io.Writer) error { - var js []byte - js, err := json.Marshal(sd) - if err != nil { - return err - } - _, err = w.Write(js) - return err -} - // readEventLog reads cloudevent logs from $MINIKUBE_HOME/profiles//events.json func readEventLog(name string) ([]cloudevents.Event, time.Time, error) { path := localpath.EventLog(name) diff --git a/cmd/minikube/cmd/status_test.go b/cmd/minikube/cmd/status_test.go index dc3d9b6e6592..aa9f905c22af 100644 --- a/cmd/minikube/cmd/status_test.go +++ b/cmd/minikube/cmd/status_test.go @@ -20,9 +20,6 @@ import ( "bytes" "encoding/json" "testing" - "time" - - "k8s.io/minikube/pkg/minikube/config" ) func TestExitCode(t *testing.T) { @@ -54,18 +51,18 @@ func TestStatusText(t *testing.T) { }{ { name: "ok", - state: &Status{Name: "minikube", Host: "Running", Kubelet: "Running", APIServer: "Running", Kubeconfig: Configured}, - want: "minikube\ntype: Control Plane\nhost: Running\nkubelet: Running\napiserver: Running\nkubeconfig: Configured\n\n", + state: &Status{Name: "minikube", Host: "Running", Kubelet: "Running", APIServer: "Running", Kubeconfig: Configured, TimeToStop: "10m"}, + want: "minikube\ntype: Control Plane\nhost: Running\nkubelet: Running\napiserver: Running\nkubeconfig: Configured\ntimeToStop: 10m\n\n", }, { name: "paused", - state: &Status{Name: "minikube", Host: "Running", Kubelet: "Stopped", APIServer: "Paused", Kubeconfig: Configured}, - want: "minikube\ntype: Control Plane\nhost: Running\nkubelet: Stopped\napiserver: Paused\nkubeconfig: Configured\n\n", + state: &Status{Name: "minikube", Host: "Running", Kubelet: "Stopped", APIServer: "Paused", Kubeconfig: Configured, TimeToStop: Nonexistent}, + want: "minikube\ntype: Control Plane\nhost: Running\nkubelet: Stopped\napiserver: Paused\nkubeconfig: Configured\ntimeToStop: Nonexistent\n\n", }, { name: "down", - state: &Status{Name: "minikube", Host: "Stopped", Kubelet: "Stopped", APIServer: "Stopped", Kubeconfig: Misconfigured}, - want: "minikube\ntype: Control Plane\nhost: Stopped\nkubelet: Stopped\napiserver: Stopped\nkubeconfig: Misconfigured\n\n\nWARNING: Your kubectl is pointing to stale minikube-vm.\nTo fix the kubectl context, run `minikube update-context`\n", + state: &Status{Name: "minikube", Host: "Stopped", Kubelet: "Stopped", APIServer: "Stopped", Kubeconfig: Misconfigured, TimeToStop: Nonexistent}, + want: "minikube\ntype: Control Plane\nhost: Stopped\nkubelet: Stopped\napiserver: Stopped\nkubeconfig: Misconfigured\ntimeToStop: Nonexistent\n\n\nWARNING: Your kubectl is pointing to stale minikube-vm.\nTo fix the kubectl context, run `minikube update-context`\n", }, } for _, tc := range tests { @@ -89,9 +86,9 @@ func TestStatusJSON(t *testing.T) { name string state *Status }{ - {"ok", &Status{Host: "Running", Kubelet: "Running", APIServer: "Running", Kubeconfig: Configured}}, - {"paused", &Status{Host: "Running", Kubelet: "Stopped", APIServer: "Paused", Kubeconfig: Configured}}, - {"down", &Status{Host: "Stopped", Kubelet: "Stopped", APIServer: "Stopped", Kubeconfig: Misconfigured}}, + {"ok", &Status{Host: "Running", Kubelet: "Running", APIServer: "Running", Kubeconfig: Configured, TimeToStop: "10m"}}, + {"paused", &Status{Host: "Running", Kubelet: "Stopped", APIServer: "Paused", Kubeconfig: Configured, TimeToStop: Nonexistent}}, + {"down", &Status{Host: "Stopped", Kubelet: "Stopped", APIServer: "Stopped", Kubeconfig: Misconfigured, TimeToStop: Nonexistent}}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { @@ -108,67 +105,3 @@ func TestStatusJSON(t *testing.T) { }) } } - -func TestScheduledStopStatusText(t *testing.T) { - now := time.Now().Unix() - initiationTime := time.Unix(now, 0).String() - - stopAt := time.Now().Add(time.Minute * 10).Unix() - scheduledTime := time.Unix(stopAt, 0).String() - var tests = []struct { - name string - state *config.ScheduledStopConfig - want string - }{ - { - name: "valid", - state: &config.ScheduledStopConfig{InitiationTime: now, Duration: time.Minute * 10}, - want: "type: ScheduledDuration\ninitiatedTime: " + initiationTime + "\nscheduledTime: " + scheduledTime + "\n\n", - }, - { - name: "missing", - state: &config.ScheduledStopConfig{}, - want: "type: ScheduledDuration\ninitiatedTime: -\nscheduledTime: -\n\n", - }, - } - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - var b bytes.Buffer - err := scheduledStopStatusText(tc.state, &b) - if err != nil { - t.Errorf("text(%+v) error: %v", tc.state, err) - } - - got := b.String() - if got != tc.want { - t.Errorf("text(%+v) = %q, want: %q", tc.state, got, tc.want) - } - }) - } -} - -func TestScheduledStopStatusJSON(t *testing.T) { - var tests = []struct { - name string - state *config.ScheduledStopConfig - }{ - { - name: "valid", - state: &config.ScheduledStopConfig{InitiationTime: time.Now().Unix(), Duration: time.Minute * 5}, - }, - } - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - var b bytes.Buffer - err := scheduledStopStatusJSON(tc.state, &b) - if err != nil { - t.Errorf("json(%+v) error: %v", tc.state, err) - } - - st := &Status{} - if err := json.Unmarshal(b.Bytes(), st); err != nil { - t.Errorf("json(%+v) unmarshal error: %v", tc.state, err) - } - }) - } -} diff --git a/site/content/en/docs/commands/status.md b/site/content/en/docs/commands/status.md index f4902dab0baf..e5c3c89e7dd5 100644 --- a/site/content/en/docs/commands/status.md +++ b/site/content/en/docs/commands/status.md @@ -23,7 +23,7 @@ minikube status [flags] ``` -f, --format string Go template format string for the status output. The format for Go templates can be found here: https://golang.org/pkg/text/template/ - For the list accessible variables for the template, see the struct values here: https://godoc.org/k8s.io/minikube/cmd/minikube/cmd#Status (default "{{.Name}}\ntype: Control Plane\nhost: {{.Host}}\nkubelet: {{.Kubelet}}\napiserver: {{.APIServer}}\nkubeconfig: {{.Kubeconfig}}\n\n") + For the list accessible variables for the template, see the struct values here: https://godoc.org/k8s.io/minikube/cmd/minikube/cmd#Status (default "{{.Name}}\ntype: Control Plane\nhost: {{.Host}}\nkubelet: {{.Kubelet}}\napiserver: {{.APIServer}}\nkubeconfig: {{.Kubeconfig}}\ntimeToStop: {{.TimeToStop}}\n\n") -l, --layout string output layout (EXPERIMENTAL, JSON only): 'nodes' or 'cluster' (default "nodes") -n, --node string The node to check status for. Defaults to control plane. Leave blank with default format for status on all nodes. -o, --output string minikube status --output OUTPUT. json, text (default "text") From 3f57033c60d37abe6380dfd22c083fcf742d530e Mon Sep 17 00:00:00 2001 From: Tharun Date: Fri, 4 Dec 2020 13:05:39 +0530 Subject: [PATCH 3/8] added timetostop status in cluster layout --- cmd/minikube/cmd/status.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cmd/minikube/cmd/status.go b/cmd/minikube/cmd/status.go index c985c72157b3..2ce2f2064a71 100644 --- a/cmd/minikube/cmd/status.go +++ b/cmd/minikube/cmd/status.go @@ -372,8 +372,6 @@ func nodeStatus(api libmachine.API, cc config.ClusterConfig, n config.Node) (*St if cc.ScheduledStop != nil { initiationTime := time.Unix(cc.ScheduledStop.InitiationTime, 0) st.TimeToStop = time.Until(initiationTime.Add(cc.ScheduledStop.Duration)).String() - } else { - st.TimeToStop = Irrelevant } // Early exit for worker nodes if !controlPlane { @@ -486,6 +484,11 @@ func clusterState(sts []*Status) ClusterState { statusName = sts[0].Host } sc := statusCode(statusName) + + timeToStopStatusCode := Configured + if sts[0].TimeToStop == Nonexistent { + timeToStopStatusCode = Nonexistent + } cs := ClusterState{ BinaryVersion: version.GetVersion(), @@ -498,6 +501,7 @@ func clusterState(sts []*Status) ClusterState { Components: map[string]BaseState{ "kubeconfig": {Name: "kubeconfig", StatusCode: statusCode(sts[0].Kubeconfig)}, + "timetostop": {Name: "timetostop", StatusCode: statusCode(timeToStopStatusCode)}, }, } From 35e2ce2dcfa147a6a161e72bb9478a5e1f2c0f39 Mon Sep 17 00:00:00 2001 From: Tharun Date: Fri, 4 Dec 2020 16:05:24 +0530 Subject: [PATCH 4/8] added check for timetostop status --- test/integration/scheduled_stop_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/integration/scheduled_stop_test.go b/test/integration/scheduled_stop_test.go index 508a38599969..3de450e6299a 100644 --- a/test/integration/scheduled_stop_test.go +++ b/test/integration/scheduled_stop_test.go @@ -165,6 +165,10 @@ func ensureMinikubeStatus(ctx context.Context, t *testing.T, profile, wantStatus if got != wantStatus { return fmt.Errorf("expected post-stop host status to be -%q- but got *%q*", state.Stopped, got) } + got = Status(ctx, t, Target(), profile, "TimeToStop", profile) + if got != "Nonexistent" { + return fmt.Errorf("expected post-stop timetostop status to be -%q- but got *%q*", "Nonexistent", got) + } return nil } if err := retry.Expo(checkStatus, time.Second, time.Minute); err != nil { From 4ca4491124b95d83982236b80bfa6b8cf4b8c74d Mon Sep 17 00:00:00 2001 From: Tharun Date: Sat, 5 Dec 2020 14:23:34 +0530 Subject: [PATCH 5/8] fixed review feedbacks on clusterstate field and tests Signed-off-by: Tharun --- cmd/minikube/cmd/status.go | 8 +++----- test/integration/scheduled_stop_test.go | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/cmd/minikube/cmd/status.go b/cmd/minikube/cmd/status.go index 2ce2f2064a71..bfcde0880bb4 100644 --- a/cmd/minikube/cmd/status.go +++ b/cmd/minikube/cmd/status.go @@ -143,6 +143,7 @@ type ClusterState struct { BaseState BinaryVersion string + TimeToStop string Components map[string]BaseState Nodes []NodeState } @@ -485,10 +486,6 @@ func clusterState(sts []*Status) ClusterState { } sc := statusCode(statusName) - timeToStopStatusCode := Configured - if sts[0].TimeToStop == Nonexistent { - timeToStopStatusCode = Nonexistent - } cs := ClusterState{ BinaryVersion: version.GetVersion(), @@ -499,9 +496,10 @@ func clusterState(sts []*Status) ClusterState { StatusDetail: codeDetails[sc], }, + TimeToStop: sts[0].TimeToStop, + Components: map[string]BaseState{ "kubeconfig": {Name: "kubeconfig", StatusCode: statusCode(sts[0].Kubeconfig)}, - "timetostop": {Name: "timetostop", StatusCode: statusCode(timeToStopStatusCode)}, }, } diff --git a/test/integration/scheduled_stop_test.go b/test/integration/scheduled_stop_test.go index 3de450e6299a..81ee9e9e30f5 100644 --- a/test/integration/scheduled_stop_test.go +++ b/test/integration/scheduled_stop_test.go @@ -52,6 +52,11 @@ func TestScheduledStopWindows(t *testing.T) { // schedule a stop for 5m from now stopMinikube(ctx, t, profile, []string{"--schedule", "5m"}) + scheduledStopMinikube(ctx, t, profile, "5m") + // sleep for 1 second + time.Sleep(time.Second) + // make sure timeToStop is present in status + checkTimetoStop(ctx, t, profile, "4m") // make sure the systemd service is running rr, err := Run(t, exec.CommandContext(ctx, Target(), []string{"ssh", "-p", profile, "--", "sudo", "systemctl", "show", constants.ScheduledStopSystemdService, "--no-page"}...)) if err != nil { @@ -84,6 +89,11 @@ func TestScheduledStopUnix(t *testing.T) { // schedule a stop for 5 min from now and make sure PID is created stopMinikube(ctx, t, profile, []string{"--schedule", "5m"}) + scheduledStopMinikube(ctx, t, profile, "5m") + // sleep for 1 second + time.Sleep(time.Second) + // make sure timeToStop is present in status + checkTimetoStop(ctx, t, profile, "4m") pid := checkPID(t, profile) if !processRunning(t, pid) { t.Fatalf("process %v is not running", pid) @@ -175,3 +185,10 @@ func ensureMinikubeStatus(ctx context.Context, t *testing.T, profile, wantStatus t.Fatalf("error %v", err) } } + +func checkTimetoStop(ctx context.Context, t *testing.T, profile string, currentTimeToStop string) { + got := Status(ctx, t, Target(), profile, "TimeToStop", profile) + if !strings.Contains(got, currentTimeToStop) { + t.Fatalf("expected timetostop status to be -%q- but got *%q*", currentTimeToStop, got) + } +} From c51a20401d14cd4b09d05a51cb8fff650eb41556 Mon Sep 17 00:00:00 2001 From: Tharun Date: Sat, 5 Dec 2020 14:49:56 +0530 Subject: [PATCH 6/8] updated scheduled_stop tests Signed-off-by: Tharun --- test/integration/scheduled_stop_test.go | 32 +++++++++---------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/test/integration/scheduled_stop_test.go b/test/integration/scheduled_stop_test.go index 81ee9e9e30f5..e38ff1b28d44 100644 --- a/test/integration/scheduled_stop_test.go +++ b/test/integration/scheduled_stop_test.go @@ -51,12 +51,10 @@ func TestScheduledStopWindows(t *testing.T) { // schedule a stop for 5m from now stopMinikube(ctx, t, profile, []string{"--schedule", "5m"}) - - scheduledStopMinikube(ctx, t, profile, "5m") // sleep for 1 second time.Sleep(time.Second) // make sure timeToStop is present in status - checkTimetoStop(ctx, t, profile, "4m") + ensureMinikubeStatus(ctx, t, profile, "TimeToStop", "4m") // make sure the systemd service is running rr, err := Run(t, exec.CommandContext(ctx, Target(), []string{"ssh", "-p", profile, "--", "sudo", "systemctl", "show", constants.ScheduledStopSystemdService, "--no-page"}...)) if err != nil { @@ -72,7 +70,9 @@ func TestScheduledStopWindows(t *testing.T) { // sleep for 5 seconds time.Sleep(5 * time.Second) // make sure minikube status is "Stopped" - ensureMinikubeStatus(ctx, t, profile, state.Stopped.String()) + ensureMinikubeStatus(ctx, t, profile, "Host", state.Stopped.String()) + // make sure minikube timtostop is "Nonexistent" + ensureMinikubeStatus(ctx, t, profile, "TimeToStop", "Nonexistent") } func TestScheduledStopUnix(t *testing.T) { @@ -89,11 +89,10 @@ func TestScheduledStopUnix(t *testing.T) { // schedule a stop for 5 min from now and make sure PID is created stopMinikube(ctx, t, profile, []string{"--schedule", "5m"}) - scheduledStopMinikube(ctx, t, profile, "5m") // sleep for 1 second time.Sleep(time.Second) // make sure timeToStop is present in status - checkTimetoStop(ctx, t, profile, "4m") + ensureMinikubeStatus(ctx, t, profile, "TimeToStop", "4m") pid := checkPID(t, profile) if !processRunning(t, pid) { t.Fatalf("process %v is not running", pid) @@ -110,14 +109,16 @@ func TestScheduledStopUnix(t *testing.T) { // sleep 12 just to be safe stopMinikube(ctx, t, profile, []string{"--cancel-scheduled"}) time.Sleep(12 * time.Second) - ensureMinikubeStatus(ctx, t, profile, state.Running.String()) + ensureMinikubeStatus(ctx, t, profile, "Host", state.Running.String()) // schedule another stop, make sure minikube status is "Stopped" stopMinikube(ctx, t, profile, []string{"--schedule", "5s"}) if processRunning(t, pid) { t.Fatalf("process %v running but should have been killed on reschedule of stop", pid) } - ensureMinikubeStatus(ctx, t, profile, state.Stopped.String()) + ensureMinikubeStatus(ctx, t, profile, "Host", state.Stopped.String()) + // make sure minikube timtostop is "Nonexistent" + ensureMinikubeStatus(ctx, t, profile, "TimeToStop", "Nonexistent") } func startMinikube(ctx context.Context, t *testing.T, profile string) { @@ -166,29 +167,18 @@ func processRunning(t *testing.T, pid string) bool { t.Log("signal error was: ", err) return err == nil } -func ensureMinikubeStatus(ctx context.Context, t *testing.T, profile, wantStatus string) { +func ensureMinikubeStatus(ctx context.Context, t *testing.T, profile, key string, wantStatus string) { // wait allotted time to make sure minikube status is "Stopped" checkStatus := func() error { ctx, cancel := context.WithDeadline(ctx, time.Now().Add(10*time.Second)) defer cancel() - got := Status(ctx, t, Target(), profile, "Host", profile) + got := Status(ctx, t, Target(), profile, key, profile) if got != wantStatus { return fmt.Errorf("expected post-stop host status to be -%q- but got *%q*", state.Stopped, got) } - got = Status(ctx, t, Target(), profile, "TimeToStop", profile) - if got != "Nonexistent" { - return fmt.Errorf("expected post-stop timetostop status to be -%q- but got *%q*", "Nonexistent", got) - } return nil } if err := retry.Expo(checkStatus, time.Second, time.Minute); err != nil { t.Fatalf("error %v", err) } } - -func checkTimetoStop(ctx context.Context, t *testing.T, profile string, currentTimeToStop string) { - got := Status(ctx, t, Target(), profile, "TimeToStop", profile) - if !strings.Contains(got, currentTimeToStop) { - t.Fatalf("expected timetostop status to be -%q- but got *%q*", currentTimeToStop, got) - } -} From 40cf0dab1c9c39bbf7f7a9e4efc40b104e9ff16f Mon Sep 17 00:00:00 2001 From: Tharun Date: Sat, 5 Dec 2020 15:50:24 +0530 Subject: [PATCH 7/8] refractored minikube status function Signed-off-by: Tharun --- test/integration/scheduled_stop_test.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/test/integration/scheduled_stop_test.go b/test/integration/scheduled_stop_test.go index e38ff1b28d44..81998a0016b5 100644 --- a/test/integration/scheduled_stop_test.go +++ b/test/integration/scheduled_stop_test.go @@ -51,10 +51,8 @@ func TestScheduledStopWindows(t *testing.T) { // schedule a stop for 5m from now stopMinikube(ctx, t, profile, []string{"--schedule", "5m"}) - // sleep for 1 second - time.Sleep(time.Second) // make sure timeToStop is present in status - ensureMinikubeStatus(ctx, t, profile, "TimeToStop", "4m") + ensureMinikubeStatus(ctx, t, profile, "TimeToStop", "3m") // make sure the systemd service is running rr, err := Run(t, exec.CommandContext(ctx, Target(), []string{"ssh", "-p", profile, "--", "sudo", "systemctl", "show", constants.ScheduledStopSystemdService, "--no-page"}...)) if err != nil { @@ -89,10 +87,8 @@ func TestScheduledStopUnix(t *testing.T) { // schedule a stop for 5 min from now and make sure PID is created stopMinikube(ctx, t, profile, []string{"--schedule", "5m"}) - // sleep for 1 second - time.Sleep(time.Second) // make sure timeToStop is present in status - ensureMinikubeStatus(ctx, t, profile, "TimeToStop", "4m") + ensureMinikubeStatus(ctx, t, profile, "TimeToStop", "3m") pid := checkPID(t, profile) if !processRunning(t, pid) { t.Fatalf("process %v is not running", pid) @@ -173,8 +169,8 @@ func ensureMinikubeStatus(ctx context.Context, t *testing.T, profile, key string ctx, cancel := context.WithDeadline(ctx, time.Now().Add(10*time.Second)) defer cancel() got := Status(ctx, t, Target(), profile, key, profile) - if got != wantStatus { - return fmt.Errorf("expected post-stop host status to be -%q- but got *%q*", state.Stopped, got) + if !strings.Contains(got, wantStatus) { + return fmt.Errorf("expected post-stop %q status to be -%q- but got *%q*", key, wantStatus, got) } return nil } From c6e6f2dc93a4c045660840484a422875bb294abf Mon Sep 17 00:00:00 2001 From: Tharun Date: Tue, 8 Dec 2020 13:09:54 +0530 Subject: [PATCH 8/8] added function to check scheduledstop time comparison Signed-off-by: Tharun --- test/integration/scheduled_stop_test.go | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/test/integration/scheduled_stop_test.go b/test/integration/scheduled_stop_test.go index 81998a0016b5..f10c4e2d6bf4 100644 --- a/test/integration/scheduled_stop_test.go +++ b/test/integration/scheduled_stop_test.go @@ -52,7 +52,7 @@ func TestScheduledStopWindows(t *testing.T) { // schedule a stop for 5m from now stopMinikube(ctx, t, profile, []string{"--schedule", "5m"}) // make sure timeToStop is present in status - ensureMinikubeStatus(ctx, t, profile, "TimeToStop", "3m") + ensureMinikubeScheduledTime(ctx, t, profile, 5*time.Minute) // make sure the systemd service is running rr, err := Run(t, exec.CommandContext(ctx, Target(), []string{"ssh", "-p", profile, "--", "sudo", "systemctl", "show", constants.ScheduledStopSystemdService, "--no-page"}...)) if err != nil { @@ -88,7 +88,7 @@ func TestScheduledStopUnix(t *testing.T) { // schedule a stop for 5 min from now and make sure PID is created stopMinikube(ctx, t, profile, []string{"--schedule", "5m"}) // make sure timeToStop is present in status - ensureMinikubeStatus(ctx, t, profile, "TimeToStop", "3m") + ensureMinikubeScheduledTime(ctx, t, profile, 5*time.Minute) pid := checkPID(t, profile) if !processRunning(t, pid) { t.Fatalf("process %v is not running", pid) @@ -112,6 +112,8 @@ func TestScheduledStopUnix(t *testing.T) { if processRunning(t, pid) { t.Fatalf("process %v running but should have been killed on reschedule of stop", pid) } + + // make sure minikube status is "Stopped" ensureMinikubeStatus(ctx, t, profile, "Host", state.Stopped.String()) // make sure minikube timtostop is "Nonexistent" ensureMinikubeStatus(ctx, t, profile, "TimeToStop", "Nonexistent") @@ -164,12 +166,11 @@ func processRunning(t *testing.T, pid string) bool { return err == nil } func ensureMinikubeStatus(ctx context.Context, t *testing.T, profile, key string, wantStatus string) { - // wait allotted time to make sure minikube status is "Stopped" checkStatus := func() error { ctx, cancel := context.WithDeadline(ctx, time.Now().Add(10*time.Second)) defer cancel() got := Status(ctx, t, Target(), profile, key, profile) - if !strings.Contains(got, wantStatus) { + if got != wantStatus { return fmt.Errorf("expected post-stop %q status to be -%q- but got *%q*", key, wantStatus, got) } return nil @@ -178,3 +179,19 @@ func ensureMinikubeStatus(ctx context.Context, t *testing.T, profile, key string t.Fatalf("error %v", err) } } + +func ensureMinikubeScheduledTime(ctx context.Context, t *testing.T, profile string, givenTime time.Duration) { + checkTime := func() error { + ctx, cancel := context.WithDeadline(ctx, time.Now().Add(10*time.Second)) + defer cancel() + got := Status(ctx, t, Target(), profile, "TimeToStop", profile) + gotTime, _ := time.ParseDuration(got) + if gotTime < givenTime { + return nil + } + return fmt.Errorf("expected scheduled stop TimeToStop to be less than *%q* but got *%q*", givenTime, got) + } + if err := retry.Expo(checkTime, time.Second, time.Minute); err != nil { + t.Fatalf("error %v", err) + } +}