From 2fa339b25d0a011d82d3ae3af7f64f6b6cc3a83b Mon Sep 17 00:00:00 2001 From: Stephane Moser Date: Sun, 31 Jan 2021 21:02:08 +0000 Subject: [PATCH] Add test for Upgrade Release Interrupted Implement timer in the fake.go and printer.go to simulate the wait period Add test Upgrade Release when it is interruped with SIGINT Signed-off-by: Stephane Moser --- pkg/action/upgrade_test.go | 67 ++++++++++++++++++++++++++++++++++++++ pkg/kube/fake/fake.go | 6 ++++ pkg/kube/fake/printer.go | 9 +++-- 3 files changed, 80 insertions(+), 2 deletions(-) diff --git a/pkg/action/upgrade_test.go b/pkg/action/upgrade_test.go index 5cca7ca1a..e03c68011 100644 --- a/pkg/action/upgrade_test.go +++ b/pkg/action/upgrade_test.go @@ -18,7 +18,11 @@ package action import ( "fmt" + "io/ioutil" + "os" + "os/exec" "testing" + gotime "time" "helm.sh/helm/v3/pkg/chart" @@ -296,3 +300,66 @@ func TestUpgradeRelease_Pending(t *testing.T) { _, err := upAction.Run(rel.Name, buildChart(), vals) req.Contains(err.Error(), "progress", err) } + +func TestUpgradeRelease_Interrupted_Wait(t *testing.T) { + if os.Getenv("HANDLE_SIGINT") == "1" { + t.Run("Execute TestUpgradeRelease_Interrupted_Wait", func(t *testing.T) { + is := assert.New(t) + req := require.New(t) + + upAction := upgradeAction(t) + rel := releaseStub() + rel.Name = "interrupted-release" + rel.Info.Status = release.StatusDeployed + upAction.cfg.Releases.Create(rel) + + failer := upAction.cfg.KubeClient.(*kubefake.FailingKubeClient) + failer.PrintingKubeClient.WaitDuration = 10 * gotime.Second + upAction.cfg.KubeClient = failer + upAction.Wait = true + vals := map[string]interface{}{} + res, err := upAction.Run(rel.Name, buildChart(), vals) + + req.Error(err) + is.Contains(res.Info.Description, "Upgrade \"interrupted-release\" failed: SIGTERM or SIGINT received, release failed") + is.Equal(res.Info.Status, release.StatusFailed) + }) + return + + } + t.Run("Setup TestUpgradeRelease_Interrupted_Wait", func(t *testing.T) { + cmd := exec.Command(os.Args[0], "-test.run=TestUpgradeRelease_Interrupted_Wait") + cmd.Env = append(os.Environ(), "HANDLE_SIGINT=1") + stdout, err := cmd.StdoutPipe() + if err != nil { + t.Fatal(err) + } + stderr, err := cmd.StderrPipe() + if err != nil { + t.Fatal(err) + } + if err := cmd.Start(); err != nil { + t.Fatal(err) + } + go func() { + slurp, _ := ioutil.ReadAll(stdout) + fmt.Printf("%s\n", slurp) + }() + + go func() { + slurp, _ := ioutil.ReadAll(stderr) + fmt.Printf("%s\n", slurp) + }() + + gotime.Sleep(2 * gotime.Second) + p, _ := os.FindProcess(cmd.Process.Pid) + + if err := p.Signal(os.Interrupt); err != nil { + t.Fatal(err) + } + + if err := cmd.Wait(); err != nil { + t.FailNow() + } + }) +} diff --git a/pkg/kube/fake/fake.go b/pkg/kube/fake/fake.go index ff800864c..a80961566 100644 --- a/pkg/kube/fake/fake.go +++ b/pkg/kube/fake/fake.go @@ -40,6 +40,7 @@ type FailingKubeClient struct { BuildError error BuildUnstructuredError error WaitAndGetCompletedPodPhaseError error + WaitDuration time.Duration } // Create returns the configured error if set or prints @@ -52,7 +53,12 @@ func (f *FailingKubeClient) Create(resources kube.ResourceList) (*kube.Result, e // Wait returns the configured error if set or prints func (f *FailingKubeClient) Wait(resources kube.ResourceList, d time.Duration) error { + if f.WaitDuration != 0 { + d = f.WaitDuration + } + if f.WaitError != nil { + time.Sleep(d) return f.WaitError } return f.PrintingKubeClient.Wait(resources, d) diff --git a/pkg/kube/fake/printer.go b/pkg/kube/fake/printer.go index e8bd1845b..d08c71444 100644 --- a/pkg/kube/fake/printer.go +++ b/pkg/kube/fake/printer.go @@ -30,7 +30,8 @@ import ( // PrintingKubeClient implements KubeClient, but simply prints the reader to // the given output. type PrintingKubeClient struct { - Out io.Writer + Out io.Writer + WaitDuration time.Duration } // IsReachable checks if the cluster is reachable @@ -47,7 +48,11 @@ func (p *PrintingKubeClient) Create(resources kube.ResourceList) (*kube.Result, return &kube.Result{Created: resources}, nil } -func (p *PrintingKubeClient) Wait(resources kube.ResourceList, _ time.Duration) error { +func (p *PrintingKubeClient) Wait(resources kube.ResourceList, d time.Duration) error { + if p.WaitDuration != 0 { + time.Sleep(p.WaitDuration) + } + _, err := io.Copy(p.Out, bufferize(resources)) return err }