From a02a598c33d951ddb4f1d2fd261bdcbca5607af0 Mon Sep 17 00:00:00 2001 From: Adam Reese Date: Mon, 14 May 2018 09:23:21 -0700 Subject: [PATCH] ref(tests): simplify cmd test setup/teardown Ensure proper cleanup of `HELM_HOME` and `HELM_DEBUG` --- Makefile | 2 +- cmd/helm/create.go | 10 +- cmd/helm/create_test.go | 59 ++---- cmd/helm/delete_test.go | 4 +- cmd/helm/dependency_build.go | 7 +- cmd/helm/dependency_build_test.go | 14 +- cmd/helm/dependency_test.go | 4 +- cmd/helm/dependency_update_test.go | 33 +--- cmd/helm/fetch_test.go | 18 +- cmd/helm/get_hooks_test.go | 4 +- cmd/helm/get_manifest_test.go | 4 +- cmd/helm/get_test.go | 4 +- cmd/helm/get_values_test.go | 4 +- cmd/helm/helm.go | 79 -------- cmd/helm/helm_test.go | 177 +++++++----------- cmd/helm/history_test.go | 4 +- cmd/helm/init_test.go | 8 +- cmd/helm/install_test.go | 4 +- cmd/helm/list_test.go | 4 +- cmd/helm/package_test.go | 87 +++------ cmd/helm/plugin_test.go | 7 +- cmd/helm/release_testing_test.go | 4 +- cmd/helm/repo_add_test.go | 37 ++-- cmd/helm/repo_index_test.go | 7 +- cmd/helm/repo_remove_test.go | 17 +- cmd/helm/repo_update_test.go | 32 +--- cmd/helm/rollback_test.go | 4 +- cmd/helm/root.go | 102 ++++++++++ cmd/helm/root_test.go | 93 +++++++++ cmd/helm/search_test.go | 35 ++-- cmd/helm/status_test.go | 4 +- .../output/upgrade-with-install-timeout.txt | 44 ----- .../testdata/output/upgrade-with-install.txt | 44 ----- .../output/upgrade-with-reset-values.txt | 44 ----- .../output/upgrade-with-reset-values2.txt | 44 ----- .../testdata/output/upgrade-with-timeout.txt | 44 ----- .../testdata/output/upgrade-with-wait.txt | 44 ----- cmd/helm/testdata/output/upgrade.txt | 44 ----- cmd/helm/upgrade_test.go | 29 ++- cmd/helm/version_test.go | 4 +- internal/test/test.go | 4 +- pkg/helm/environment/environment_test.go | 7 +- 42 files changed, 413 insertions(+), 811 deletions(-) create mode 100644 cmd/helm/root.go create mode 100644 cmd/helm/root_test.go diff --git a/Makefile b/Makefile index 32bef5c6d..394a4a2e0 100644 --- a/Makefile +++ b/Makefile @@ -74,7 +74,7 @@ test: test-unit test-unit: @echo @echo "==> Running unit tests <==" - HELM_HOME=/no/such/dir $(GO) test $(GOFLAGS) -run $(TESTS) $(PKG) $(TESTFLAGS) + HELM_HOME=/no_such_dir $(GO) test $(GOFLAGS) -run $(TESTS) $(PKG) $(TESTFLAGS) .PHONY: test-style test-style: diff --git a/cmd/helm/create.go b/cmd/helm/create.go index 39ec211aa..6a099454a 100644 --- a/cmd/helm/create.go +++ b/cmd/helm/create.go @@ -26,7 +26,6 @@ import ( "k8s.io/helm/pkg/chartutil" "k8s.io/helm/pkg/hapi/chart" - "k8s.io/helm/pkg/helm/helmpath" ) const createDesc = ` @@ -51,11 +50,7 @@ will be overwritten, but other files will be left alone. type createOptions struct { starter string // --starter - - // args - name string - - home helmpath.Home + name string } func newCreateCmd(out io.Writer) *cobra.Command { @@ -66,7 +61,6 @@ func newCreateCmd(out io.Writer) *cobra.Command { Short: "create a new chart with the given name", Long: createDesc, RunE: func(cmd *cobra.Command, args []string) error { - o.home = settings.Home if len(args) == 0 { return errors.New("the name of the new chart is required") } @@ -93,7 +87,7 @@ func (o *createOptions) run(out io.Writer) error { if o.starter != "" { // Create from the starter - lstarter := filepath.Join(o.home.Starters(), o.starter) + lstarter := filepath.Join(settings.Home.Starters(), o.starter) return chartutil.CreateFrom(cfile, filepath.Dir(o.name), lstarter) } diff --git a/cmd/helm/create_test.go b/cmd/helm/create_test.go index bf3fdc342..5ec69f678 100644 --- a/cmd/helm/create_test.go +++ b/cmd/helm/create_test.go @@ -28,23 +28,10 @@ import ( ) func TestCreateCmd(t *testing.T) { - cname := "testchart" - // Make a temp dir - tdir, err := ioutil.TempDir("", "helm-create-") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tdir) + tdir := testTempDir(t) + defer testChdir(t, tdir)() - // CD into it - pwd, err := os.Getwd() - if err != nil { - t.Fatal(err) - } - if err := os.Chdir(tdir); err != nil { - t.Fatal(err) - } - defer os.Chdir(pwd) + cname := "testchart" // Run a create if _, err := executeCommand(nil, "create "+cname); err != nil { @@ -73,28 +60,17 @@ func TestCreateCmd(t *testing.T) { } func TestCreateStarterCmd(t *testing.T) { + defer resetEnv()() + cname := "testchart" // Make a temp dir - tdir, err := ioutil.TempDir("", "helm-create-") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tdir) - - thome, err := tempHelmHome(t) - if err != nil { - t.Fatal(err) - } - cleanup := resetEnv() - defer func() { - os.RemoveAll(thome.String()) - cleanup() - }() + tdir := testTempDir(t) - settings.Home = thome + hh := testHelmHome(t) + settings.Home = hh // Create a starter. - starterchart := filepath.Join(thome.String(), "starters") + starterchart := hh.Starters() os.Mkdir(starterchart, 0755) if dest, err := chartutil.Create(&chart.Metadata{Name: "starterchart"}, starterchart); err != nil { t.Fatalf("Could not create chart: %s", err) @@ -106,18 +82,10 @@ func TestCreateStarterCmd(t *testing.T) { t.Fatalf("Could not write template: %s", err) } - // CD into it - pwd, err := os.Getwd() - if err != nil { - t.Fatal(err) - } - if err := os.Chdir(tdir); err != nil { - t.Fatal(err) - } - defer os.Chdir(pwd) + defer testChdir(t, tdir)() // Run a create - if _, err := executeCommand(nil, fmt.Sprintf("--home=%s create --starter=starterchart %s", thome, cname)); err != nil { + if _, err := executeCommand(nil, fmt.Sprintf("--home=%s create --starter=starterchart %s", hh, cname)); err != nil { t.Errorf("Failed to run create: %s", err) return } @@ -149,9 +117,8 @@ func TestCreateStarterCmd(t *testing.T) { for _, tpl := range c.Templates { if tpl.Name == "templates/foo.tpl" { found = true - data := tpl.Data - if string(data) != "test" { - t.Errorf("Expected template 'test', got %q", string(data)) + if data := string(tpl.Data); data != "test" { + t.Errorf("Expected template 'test', got %q", data) } } } diff --git a/cmd/helm/delete_test.go b/cmd/helm/delete_test.go index fffaccdd6..a391d995f 100644 --- a/cmd/helm/delete_test.go +++ b/cmd/helm/delete_test.go @@ -27,7 +27,7 @@ func TestDelete(t *testing.T) { rels := []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"})} - tests := []releaseCase{ + tests := []cmdTestCase{ { name: "basic delete", cmd: "delete aeneas", @@ -59,5 +59,5 @@ func TestDelete(t *testing.T) { wantError: true, }, } - testReleaseCmd(t, tests) + runTestCmd(t, tests) } diff --git a/cmd/helm/dependency_build.go b/cmd/helm/dependency_build.go index 69ff3637d..7a9942087 100644 --- a/cmd/helm/dependency_build.go +++ b/cmd/helm/dependency_build.go @@ -22,7 +22,6 @@ import ( "k8s.io/helm/pkg/downloader" "k8s.io/helm/pkg/getter" - "k8s.io/helm/pkg/helm/helmpath" ) const dependencyBuildDesc = ` @@ -40,10 +39,7 @@ type dependencyBuildOptions struct { keyring string // --keyring verify bool // --verify - // args chartpath string - - helmhome helmpath.Home } func newDependencyBuildCmd(out io.Writer) *cobra.Command { @@ -56,7 +52,6 @@ func newDependencyBuildCmd(out io.Writer) *cobra.Command { Short: "rebuild the charts/ directory based on the requirements.lock file", Long: dependencyBuildDesc, RunE: func(cmd *cobra.Command, args []string) error { - o.helmhome = settings.Home if len(args) > 0 { o.chartpath = args[0] } @@ -75,7 +70,7 @@ func (o *dependencyBuildOptions) run(out io.Writer) error { man := &downloader.Manager{ Out: out, ChartPath: o.chartpath, - HelmHome: o.helmhome, + HelmHome: settings.Home, Keyring: o.keyring, Getters: getter.All(settings), } diff --git a/cmd/helm/dependency_build_test.go b/cmd/helm/dependency_build_test.go index b313f5c2c..234fc9b30 100644 --- a/cmd/helm/dependency_build_test.go +++ b/cmd/helm/dependency_build_test.go @@ -27,22 +27,14 @@ import ( ) func TestDependencyBuildCmd(t *testing.T) { - hh, err := tempHelmHome(t) - if err != nil { - t.Fatal(err) - } - cleanup := resetEnv() - defer func() { - os.RemoveAll(hh.String()) - cleanup() - }() + defer resetEnv()() + hh := testHelmHome(t) settings.Home = hh srv := repotest.NewServer(hh.String()) defer srv.Stop() - _, err = srv.CopyCharts("testdata/testcharts/*.tgz") - if err != nil { + if _, err := srv.CopyCharts("testdata/testcharts/*.tgz"); err != nil { t.Fatal(err) } diff --git a/cmd/helm/dependency_test.go b/cmd/helm/dependency_test.go index 27e64f28b..98dcab1a6 100644 --- a/cmd/helm/dependency_test.go +++ b/cmd/helm/dependency_test.go @@ -20,7 +20,7 @@ import ( ) func TestDependencyListCmd(t *testing.T) { - tests := []releaseCase{{ + tests := []cmdTestCase{{ name: "No such chart", cmd: "dependency list /no/such/chart", golden: "output/dependency-list-no-chart.txt", @@ -38,5 +38,5 @@ func TestDependencyListCmd(t *testing.T) { cmd: "dependency list testdata/testcharts/reqtest-0.1.0.tgz", golden: "output/dependency-list-archive.txt", }} - testReleaseCmd(t, tests) + runTestCmd(t, tests) } diff --git a/cmd/helm/dependency_update_test.go b/cmd/helm/dependency_update_test.go index f8d0537bc..212106af4 100644 --- a/cmd/helm/dependency_update_test.go +++ b/cmd/helm/dependency_update_test.go @@ -35,16 +35,9 @@ import ( ) func TestDependencyUpdateCmd(t *testing.T) { - hh, err := tempHelmHome(t) - if err != nil { - t.Fatal(err) - } - cleanup := resetEnv() - defer func() { - os.RemoveAll(hh.String()) - cleanup() - }() + defer resetEnv()() + hh := testHelmHome(t) settings.Home = hh srv := repotest.NewServer(hh.String()) @@ -125,16 +118,9 @@ func TestDependencyUpdateCmd(t *testing.T) { } func TestDependencyUpdateCmd_SkipRefresh(t *testing.T) { - hh, err := tempHelmHome(t) - if err != nil { - t.Fatal(err) - } - cleanup := resetEnv() - defer func() { - os.RemoveAll(hh.String()) - cleanup() - }() + defer resetEnv()() + hh := testHelmHome(t) settings.Home = hh srv := repotest.NewServer(hh.String()) @@ -163,16 +149,9 @@ func TestDependencyUpdateCmd_SkipRefresh(t *testing.T) { } func TestDependencyUpdateCmd_DontDeleteOldChartsOnError(t *testing.T) { - hh, err := tempHelmHome(t) - if err != nil { - t.Fatal(err) - } - cleanup := resetEnv() - defer func() { - os.RemoveAll(hh.String()) - cleanup() - }() + defer resetEnv()() + hh := testHelmHome(t) settings.Home = hh srv := repotest.NewServer(hh.String()) diff --git a/cmd/helm/fetch_test.go b/cmd/helm/fetch_test.go index 66b688a41..86c0c5327 100644 --- a/cmd/helm/fetch_test.go +++ b/cmd/helm/fetch_test.go @@ -28,20 +28,14 @@ import ( ) func TestFetchCmd(t *testing.T) { - hh, err := tempHelmHome(t) - if err != nil { - t.Fatal(err) - } - cleanup := resetEnv() - defer func() { - os.RemoveAll(hh.String()) - cleanup() - }() - srv := repotest.NewServer(hh.String()) - defer srv.Stop() + defer resetEnv()() + hh := testHelmHome(t) settings.Home = hh + srv := repotest.NewServer(hh.String()) + defer srv.Stop() + // all flags will get "--home=TMDIR -d outdir" appended. tests := []struct { name string @@ -131,7 +125,7 @@ func TestFetchCmd(t *testing.T) { } for _, tt := range tests { - outdir := filepath.Join(hh.String(), "testout") + outdir := hh.Path("testout") os.RemoveAll(outdir) os.Mkdir(outdir, 0755) diff --git a/cmd/helm/get_hooks_test.go b/cmd/helm/get_hooks_test.go index 1af2fdbd3..001c826b6 100644 --- a/cmd/helm/get_hooks_test.go +++ b/cmd/helm/get_hooks_test.go @@ -24,7 +24,7 @@ import ( ) func TestGetHooks(t *testing.T) { - tests := []releaseCase{{ + tests := []cmdTestCase{{ name: "get hooks with release", cmd: "get hooks aeneas", golden: "output/get-hooks.txt", @@ -35,5 +35,5 @@ func TestGetHooks(t *testing.T) { golden: "output/get-hooks-no-args.txt", wantError: true, }} - testReleaseCmd(t, tests) + runTestCmd(t, tests) } diff --git a/cmd/helm/get_manifest_test.go b/cmd/helm/get_manifest_test.go index 08160a71b..da29aee1d 100644 --- a/cmd/helm/get_manifest_test.go +++ b/cmd/helm/get_manifest_test.go @@ -24,7 +24,7 @@ import ( ) func TestGetManifest(t *testing.T) { - tests := []releaseCase{{ + tests := []cmdTestCase{{ name: "get manifest with release", cmd: "get manifest juno", golden: "output/get-manifest.txt", @@ -35,5 +35,5 @@ func TestGetManifest(t *testing.T) { golden: "output/get-manifest-no-args.txt", wantError: true, }} - testReleaseCmd(t, tests) + runTestCmd(t, tests) } diff --git a/cmd/helm/get_test.go b/cmd/helm/get_test.go index 9a00bb356..1df178aa8 100644 --- a/cmd/helm/get_test.go +++ b/cmd/helm/get_test.go @@ -24,7 +24,7 @@ import ( ) func TestGetCmd(t *testing.T) { - tests := []releaseCase{{ + tests := []cmdTestCase{{ name: "get with a release", cmd: "get thomas-guide", golden: "output/get-release.txt", @@ -35,5 +35,5 @@ func TestGetCmd(t *testing.T) { golden: "output/get-no-args.txt", wantError: true, }} - testReleaseCmd(t, tests) + runTestCmd(t, tests) } diff --git a/cmd/helm/get_values_test.go b/cmd/helm/get_values_test.go index bcef9c432..a9e81dbce 100644 --- a/cmd/helm/get_values_test.go +++ b/cmd/helm/get_values_test.go @@ -24,7 +24,7 @@ import ( ) func TestGetValuesCmd(t *testing.T) { - tests := []releaseCase{{ + tests := []cmdTestCase{{ name: "get values with a release", cmd: "get values thomas-guide", golden: "output/get-values.txt", @@ -35,5 +35,5 @@ func TestGetValuesCmd(t *testing.T) { golden: "output/get-values-args.txt", wantError: true, }} - testReleaseCmd(t, tests) + runTestCmd(t, tests) } diff --git a/cmd/helm/helm.go b/cmd/helm/helm.go index 1451fac37..1e58be85f 100644 --- a/cmd/helm/helm.go +++ b/cmd/helm/helm.go @@ -18,14 +18,12 @@ package main // import "k8s.io/helm/cmd/helm" import ( "fmt" - "io" "log" "os" "strings" "sync" "github.com/pkg/errors" - "github.com/spf13/cobra" // Import to initialize client auth plugins. _ "k8s.io/client-go/plugin/pkg/client/auth" "k8s.io/client-go/tools/clientcmd" @@ -42,83 +40,6 @@ var ( configOnce sync.Once ) -var globalUsage = `The Kubernetes package manager - -To begin working with Helm, run the 'helm init' command: - - $ helm init - -This will set up any necessary local configuration. - -Common actions from this point include: - -- helm search: search for charts -- helm fetch: download a chart to your local directory to view -- helm install: upload the chart to Kubernetes -- helm list: list releases of charts - -Environment: - $HELM_HOME set an alternative location for Helm files. By default, these are stored in ~/.helm - $HELM_NO_PLUGINS disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins. - $KUBECONFIG set an alternative Kubernetes configuration file (default "~/.kube/config") -` - -func newRootCmd(c helm.Interface, out io.Writer, args []string) *cobra.Command { - cmd := &cobra.Command{ - Use: "helm", - Short: "The Helm package manager for Kubernetes.", - Long: globalUsage, - SilenceUsage: true, - } - flags := cmd.PersistentFlags() - - settings.AddFlags(flags) - - cmd.AddCommand( - // chart commands - newCreateCmd(out), - newDependencyCmd(out), - newFetchCmd(out), - newInspectCmd(out), - newLintCmd(out), - newPackageCmd(out), - newRepoCmd(out), - newSearchCmd(out), - newVerifyCmd(out), - - // release commands - newDeleteCmd(c, out), - newGetCmd(c, out), - newHistoryCmd(c, out), - newInstallCmd(c, out), - newListCmd(c, out), - newReleaseTestCmd(c, out), - newRollbackCmd(c, out), - newStatusCmd(c, out), - newUpgradeCmd(c, out), - - newCompletionCmd(out), - newHomeCmd(out), - newInitCmd(out), - newPluginCmd(out), - newTemplateCmd(out), - newVersionCmd(out), - - // Hidden documentation generator command: 'helm docs' - newDocsCmd(out), - ) - - flags.Parse(args) - - // set defaults from environment - settings.Init(flags) - - // Find and add plugins - loadPlugins(cmd, out) - - return cmd -} - func init() { log.SetFlags(log.Lshortfile) } diff --git a/cmd/helm/helm_test.go b/cmd/helm/helm_test.go index 46cfeddb8..f1d7563af 100644 --- a/cmd/helm/helm_test.go +++ b/cmd/helm/helm_test.go @@ -20,12 +20,10 @@ import ( "bytes" "io/ioutil" "os" - "path/filepath" "strings" "testing" shellwords "github.com/mattn/go-shellwords" - "github.com/pkg/errors" "github.com/spf13/cobra" "k8s.io/helm/internal/test" @@ -35,30 +33,40 @@ import ( "k8s.io/helm/pkg/repo" ) -func executeCommand(c helm.Interface, cmd string) (string, error) { - _, output, err := executeCommandC(c, cmd) - return output, err -} +// base temp directory +var testingDir string -func executeCommandC(client helm.Interface, cmd string) (*cobra.Command, string, error) { - args, err := shellwords.Parse(cmd) +func init() { + var err error + testingDir, err = ioutil.TempDir(testingDir, "helm") if err != nil { - return nil, "", err + panic(err) } - buf := new(bytes.Buffer) - root := newRootCmd(client, buf, args) - root.SetOutput(buf) - root.SetArgs(args) +} - c, err := root.ExecuteC() +func TestMain(m *testing.M) { + os.Unsetenv("HELM_HOME") - return c, buf.String(), err + exitCode := m.Run() + os.RemoveAll(testingDir) + os.Exit(exitCode) } -func testReleaseCmd(t *testing.T, tests []releaseCase) { +func testTempDir(t *testing.T) string { + t.Helper() + d, err := ioutil.TempDir(testingDir, "helm") + if err != nil { + t.Fatal(err) + } + return d +} + +func runTestCmd(t *testing.T, tests []cmdTestCase) { t.Helper() for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + defer resetEnv()() + c := &helm.FakeClient{ Rels: tt.rels, TestRunStatus: tt.testRunStatus, @@ -74,8 +82,8 @@ func testReleaseCmd(t *testing.T, tests []releaseCase) { } } -// releaseCase describes a test case that works with releases. -type releaseCase struct { +// cmdTestCase describes a test case that works with releases. +type cmdTestCase struct { name string cmd string golden string @@ -85,29 +93,28 @@ type releaseCase struct { testRunStatus map[string]release.TestRunStatus } -// tempHelmHome sets up a Helm Home in a temp dir. -// -// This does not clean up the directory. You must do that yourself. -// You must also set helmHome yourself. -func tempHelmHome(t *testing.T) (helmpath.Home, error) { - oldhome := settings.Home - dir, err := ioutil.TempDir("", "helm_home-") +func executeCommand(c helm.Interface, cmd string) (string, error) { + _, output, err := executeCommandC(c, cmd) + return output, err +} + +func executeCommandC(client helm.Interface, cmd string) (*cobra.Command, string, error) { + args, err := shellwords.Parse(cmd) if err != nil { - return helmpath.Home("n/"), err + return nil, "", err } + buf := new(bytes.Buffer) + root := newRootCmd(client, buf, args) + root.SetOutput(buf) + root.SetArgs(args) - settings.Home = helmpath.Home(dir) - if err := ensureTestHome(t, settings.Home); err != nil { - return helmpath.Home("n/"), err - } - settings.Home = oldhome - return helmpath.Home(dir), nil + c, err := root.ExecuteC() + + return c, buf.String(), err } // ensureTestHome creates a home directory like ensureHome, but without remote references. -// -// t is used only for logging. -func ensureTestHome(t *testing.T, home helmpath.Home) error { +func ensureTestHome(t *testing.T, home helmpath.Home) { t.Helper() for _, p := range []string{ home.String(), @@ -117,7 +124,7 @@ func ensureTestHome(t *testing.T, home helmpath.Home) error { home.Starters(), } { if err := os.MkdirAll(p, 0755); err != nil { - return errors.Wrapf(err, "could not create %s", p) + t.Fatal(err) } } @@ -130,96 +137,30 @@ func ensureTestHome(t *testing.T, home helmpath.Home) error { Cache: "charts-index.yaml", }) if err := rf.WriteFile(repoFile, 0644); err != nil { - return err + t.Fatal(err) } } if r, err := repo.LoadRepositoriesFile(repoFile); err == repo.ErrRepoOutOfDate { t.Log("Updating repository file format...") if err := r.WriteFile(repoFile, 0644); err != nil { - return err + t.Fatal(err) } } - t.Logf("$HELM_HOME has been configured at %s.\n", home) - return nil - } -func TestRootCmd(t *testing.T) { - cleanup := resetEnv() - defer cleanup() - - tests := []struct { - name, args, home string - envars map[string]string - }{ - { - name: "defaults", - args: "home", - home: filepath.Join(os.Getenv("HOME"), "/.helm"), - }, - { - name: "with --home set", - args: "--home /foo", - home: "/foo", - }, - { - name: "subcommands with --home set", - args: "home --home /foo", - home: "/foo", - }, - { - name: "with $HELM_HOME set", - args: "home", - envars: map[string]string{"HELM_HOME": "/bar"}, - home: "/bar", - }, - { - name: "subcommands with $HELM_HOME set", - args: "home", - envars: map[string]string{"HELM_HOME": "/bar"}, - home: "/bar", - }, - { - name: "with $HELM_HOME and --home set", - args: "home --home /foo", - envars: map[string]string{"HELM_HOME": "/bar"}, - home: "/foo", - }, - } - - // ensure not set locally - os.Unsetenv("HELM_HOME") - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - defer os.Unsetenv("HELM_HOME") - - for k, v := range tt.envars { - os.Setenv(k, v) - } - - cmd, _, err := executeCommandC(nil, tt.args) - if err != nil { - t.Fatalf("unexpected error: %s", err) - } - - if settings.Home.String() != tt.home { - t.Errorf("expected home %q, got %q", tt.home, settings.Home) - } - homeFlag := cmd.Flag("home").Value.String() - homeFlag = os.ExpandEnv(homeFlag) - if homeFlag != tt.home { - t.Errorf("expected home %q, got %q", tt.home, homeFlag) - } - }) - } +// testHelmHome sets up a Helm Home in a temp dir. +func testHelmHome(t *testing.T) helmpath.Home { + t.Helper() + dir := helmpath.Home(testTempDir(t)) + ensureTestHome(t, dir) + return dir } func resetEnv() func() { - origSettings := settings - origEnv := os.Environ() + origSettings, origEnv := settings, os.Environ() return func() { + os.Clearenv() settings = origSettings for _, pair := range origEnv { kv := strings.SplitN(pair, "=", 2) @@ -227,3 +168,15 @@ func resetEnv() func() { } } } + +func testChdir(t *testing.T, dir string) func() { + t.Helper() + old, err := os.Getwd() + if err != nil { + t.Fatal(err) + } + if err := os.Chdir(dir); err != nil { + t.Fatal(err) + } + return func() { os.Chdir(old) } +} diff --git a/cmd/helm/history_test.go b/cmd/helm/history_test.go index 84fcfe691..3d7786e04 100644 --- a/cmd/helm/history_test.go +++ b/cmd/helm/history_test.go @@ -32,7 +32,7 @@ func TestHistoryCmd(t *testing.T) { }) } - tests := []releaseCase{{ + tests := []cmdTestCase{{ name: "get history for release", cmd: "history angry-bird", rels: []*rpb.Release{ @@ -67,5 +67,5 @@ func TestHistoryCmd(t *testing.T) { }, golden: "output/history.json", }} - testReleaseCmd(t, tests) + runTestCmd(t, tests) } diff --git a/cmd/helm/init_test.go b/cmd/helm/init_test.go index 5ee148bae..5f6724b28 100644 --- a/cmd/helm/init_test.go +++ b/cmd/helm/init_test.go @@ -18,7 +18,6 @@ package main import ( "bytes" - "io/ioutil" "os" "testing" @@ -26,14 +25,9 @@ import ( ) func TestEnsureHome(t *testing.T) { - home, err := ioutil.TempDir("", "helm_home") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(home) + hh := helmpath.Home(testTempDir(t)) b := bytes.NewBuffer(nil) - hh := helmpath.Home(home) settings.Home = hh if err := ensureDirectories(hh, b); err != nil { t.Error(err) diff --git a/cmd/helm/install_test.go b/cmd/helm/install_test.go index 397805345..298edb5f2 100644 --- a/cmd/helm/install_test.go +++ b/cmd/helm/install_test.go @@ -23,7 +23,7 @@ import ( ) func TestInstall(t *testing.T) { - tests := []releaseCase{ + tests := []cmdTestCase{ // Install, base case { name: "basic install", @@ -120,7 +120,7 @@ func TestInstall(t *testing.T) { }, } - testReleaseCmd(t, tests) + runTestCmd(t, tests) } type nameTemplateTestCase struct { diff --git a/cmd/helm/list_test.go b/cmd/helm/list_test.go index efffaf070..2a331eb01 100644 --- a/cmd/helm/list_test.go +++ b/cmd/helm/list_test.go @@ -24,7 +24,7 @@ import ( ) func TestListCmd(t *testing.T) { - tests := []releaseCase{{ + tests := []cmdTestCase{{ name: "with a release", cmd: "list", rels: []*release.Release{ @@ -111,5 +111,5 @@ func TestListCmd(t *testing.T) { golden: "output/list-with-old-releases.txt", }} - testReleaseCmd(t, tests) + runTestCmd(t, tests) } diff --git a/cmd/helm/package_test.go b/cmd/helm/package_test.go index ead7c7fb1..d7f0e0f9d 100644 --- a/cmd/helm/package_test.go +++ b/cmd/helm/package_test.go @@ -53,6 +53,7 @@ func TestSetVersion(t *testing.T) { } func TestPackage(t *testing.T) { + defer resetEnv()() tests := []struct { name string @@ -132,32 +133,20 @@ func TestPackage(t *testing.T) { }, } - // Because these tests are destructive, we run them in a tempdir. origDir, err := os.Getwd() if err != nil { t.Fatal(err) } - tmp, err := ioutil.TempDir("", "helm-package-test-") - if err != nil { - t.Fatal(err) - } + tmp := testTempDir(t) t.Logf("Running tests in %s", tmp) - if err := os.Chdir(tmp); err != nil { - t.Fatal(err) - } + defer testChdir(t, tmp)() if err := os.Mkdir("toot", 0777); err != nil { t.Fatal(err) } ensureTestHome(t, helmpath.Home(tmp)) - cleanup := resetEnv() - defer func() { - os.Chdir(origDir) - os.RemoveAll(tmp) - cleanup() - }() settings.Home = helmpath.Home(tmp) @@ -210,22 +199,14 @@ func TestPackage(t *testing.T) { } func TestSetAppVersion(t *testing.T) { + defer resetEnv()() + var ch *chart.Chart expectedAppVersion := "app-version-foo" - tmp, _ := ioutil.TempDir("", "helm-package-app-version-") + tmp := testTempDir(t) - thome, err := tempHelmHome(t) - if err != nil { - t.Fatal(err) - } - cleanup := resetEnv() - defer func() { - os.RemoveAll(tmp) - os.RemoveAll(thome.String()) - cleanup() - }() - - settings.Home = helmpath.Home(thome) + hh := testHelmHome(t) + settings.Home = helmpath.Home(hh) c := newPackageCmd(&bytes.Buffer{}) flags := map[string]string{ @@ -233,8 +214,7 @@ func TestSetAppVersion(t *testing.T) { "app-version": expectedAppVersion, } setFlags(c, flags) - err = c.RunE(c, []string{"testdata/testcharts/alpine"}) - if err != nil { + if err := c.RunE(c, []string{"testdata/testcharts/alpine"}); err != nil { t.Errorf("unexpected error %q", err) } @@ -244,7 +224,7 @@ func TestSetAppVersion(t *testing.T) { } else if fi.Size() == 0 { t.Errorf("file %q has zero bytes.", chartPath) } - ch, err = chartutil.Load(chartPath) + ch, err := chartutil.Load(chartPath) if err != nil { t.Errorf("unexpected error loading packaged chart: %v", err) } @@ -254,6 +234,8 @@ func TestSetAppVersion(t *testing.T) { } func TestPackageValues(t *testing.T) { + defer resetEnv()() + testCases := []struct { desc string args []string @@ -288,26 +270,13 @@ func TestPackageValues(t *testing.T) { }, } - thome, err := tempHelmHome(t) - if err != nil { - t.Fatal(err) - } - cleanup := resetEnv() - defer func() { - os.RemoveAll(thome.String()) - cleanup() - }() - - settings.Home = thome + hh := testHelmHome(t) + settings.Home = hh for _, tc := range testCases { var files []string for _, contents := range tc.valuefilesContents { - f, err := createValuesFile(contents) - if err != nil { - t.Errorf("%q unexpected error creating temporary values file: %q", tc.desc, err) - } - defer os.RemoveAll(filepath.Dir(f)) + f := createValuesFile(t, contents) files = append(files, f) } valueFiles := strings.Join(files, ",") @@ -322,11 +291,7 @@ func TestPackageValues(t *testing.T) { } func runAndVerifyPackageCommandValues(t *testing.T, args []string, flags map[string]string, valueFiles string, expected chartutil.Values) { - outputDir, err := ioutil.TempDir("", "helm-package") - if err != nil { - t.Errorf("unexpected error creating temporary output directory: %q", err) - } - defer os.RemoveAll(outputDir) + outputDir := testTempDir(t) if len(flags) == 0 { flags = make(map[string]string) @@ -339,16 +304,14 @@ func runAndVerifyPackageCommandValues(t *testing.T, args []string, flags map[str cmd := newPackageCmd(&bytes.Buffer{}) setFlags(cmd, flags) - err = cmd.RunE(cmd, args) - if err != nil { + if err := cmd.RunE(cmd, args); err != nil { t.Errorf("unexpected error: %q", err) } outputFile := filepath.Join(outputDir, "alpine-0.1.0.tgz") verifyOutputChartExists(t, outputFile) - var actual chartutil.Values - actual, err = getChartValues(outputFile) + actual, err := getChartValues(outputFile) if err != nil { t.Errorf("unexpected error extracting chart values: %q", err) } @@ -356,19 +319,15 @@ func runAndVerifyPackageCommandValues(t *testing.T, args []string, flags map[str verifyValues(t, actual, expected) } -func createValuesFile(data string) (string, error) { - outputDir, err := ioutil.TempDir("", "values-file") - if err != nil { - return "", err - } +func createValuesFile(t *testing.T, data string) string { + outputDir := testTempDir(t) outputFile := filepath.Join(outputDir, "values.yaml") - if err = ioutil.WriteFile(outputFile, []byte(data), 0755); err != nil { - os.RemoveAll(outputFile) - return "", err + if err := ioutil.WriteFile(outputFile, []byte(data), 0755); err != nil { + t.Fatalf("err: %s", err) } - return outputFile, nil + return outputFile } func getChartValues(chartPath string) (chartutil.Values, error) { diff --git a/cmd/helm/plugin_test.go b/cmd/helm/plugin_test.go index 707616f5a..32af2cd21 100644 --- a/cmd/helm/plugin_test.go +++ b/cmd/helm/plugin_test.go @@ -62,8 +62,7 @@ func TestManuallyProcessArgs(t *testing.T) { } func TestLoadPlugins(t *testing.T) { - cleanup := resetEnv() - defer cleanup() + defer resetEnv()() settings.Home = "testdata/helmhome" @@ -133,8 +132,7 @@ func TestLoadPlugins(t *testing.T) { } func TestLoadPlugins_HelmNoPlugins(t *testing.T) { - cleanup := resetEnv() - defer cleanup() + defer resetEnv()() settings.Home = "testdata/helmhome" @@ -151,6 +149,7 @@ func TestLoadPlugins_HelmNoPlugins(t *testing.T) { } func TestSetupEnv(t *testing.T) { + defer resetEnv()() name := "pequod" settings.Home = helmpath.Home("testdata/helmhome") base := filepath.Join(settings.Home.Plugins(), name) diff --git a/cmd/helm/release_testing_test.go b/cmd/helm/release_testing_test.go index 6213cda33..4f7392b93 100644 --- a/cmd/helm/release_testing_test.go +++ b/cmd/helm/release_testing_test.go @@ -23,7 +23,7 @@ import ( ) func TestReleaseTesting(t *testing.T) { - tests := []releaseCase{{ + tests := []cmdTestCase{{ name: "basic test", cmd: "test example-release", testRunStatus: map[string]release.TestRunStatus{"PASSED: green lights everywhere": release.TestRunSuccess}, @@ -62,5 +62,5 @@ func TestReleaseTesting(t *testing.T) { "PASSED: feel free to party again": release.TestRunSuccess}, wantError: true, }} - testReleaseCmd(t, tests) + runTestCmd(t, tests) } diff --git a/cmd/helm/repo_add_test.go b/cmd/helm/repo_add_test.go index 4f4f041da..406d9c756 100644 --- a/cmd/helm/repo_add_test.go +++ b/cmd/helm/repo_add_test.go @@ -26,50 +26,43 @@ import ( ) func TestRepoAddCmd(t *testing.T) { - srv, thome, err := repotest.NewTempServer("testdata/testserver/*.*") + defer resetEnv()() + + srv, hh, err := repotest.NewTempServer("testdata/testserver/*.*") if err != nil { t.Fatal(err) } - cleanup := resetEnv() defer func() { srv.Stop() - os.RemoveAll(thome.String()) - cleanup() + os.RemoveAll(hh.String()) }() - if err := ensureTestHome(t, thome); err != nil { - t.Fatal(err) - } - - settings.Home = thome + ensureTestHome(t, hh) + settings.Home = hh - tests := []releaseCase{{ + tests := []cmdTestCase{{ name: "add a repository", - cmd: fmt.Sprintf("repo add test-name %s --home %s", srv.URL(), thome), + cmd: fmt.Sprintf("repo add test-name %s --home %s", srv.URL(), hh), golden: "output/repo-add.txt", }} - testReleaseCmd(t, tests) + runTestCmd(t, tests) } func TestRepoAdd(t *testing.T) { - ts, thome, err := repotest.NewTempServer("testdata/testserver/*.*") + defer resetEnv()() + + ts, hh, err := repotest.NewTempServer("testdata/testserver/*.*") if err != nil { t.Fatal(err) } - cleanup := resetEnv() - hh := thome defer func() { ts.Stop() - os.RemoveAll(thome.String()) - cleanup() + os.RemoveAll(hh.String()) }() - if err := ensureTestHome(t, hh); err != nil { - t.Fatal(err) - } - - settings.Home = thome + ensureTestHome(t, hh) + settings.Home = hh const testRepoName = "test-name" diff --git a/cmd/helm/repo_index_test.go b/cmd/helm/repo_index_test.go index 4d6313f6c..026e162f3 100644 --- a/cmd/helm/repo_index_test.go +++ b/cmd/helm/repo_index_test.go @@ -19,7 +19,6 @@ package main import ( "bytes" "io" - "io/ioutil" "os" "path/filepath" "testing" @@ -29,11 +28,7 @@ import ( func TestRepoIndexCmd(t *testing.T) { - dir, err := ioutil.TempDir("", "helm-") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(dir) + dir := testTempDir(t) comp := filepath.Join(dir, "compressedchart-0.1.0.tgz") if err := linkOrCopy("testdata/testcharts/compressedchart-0.1.0.tgz", comp); err != nil { diff --git a/cmd/helm/repo_remove_test.go b/cmd/helm/repo_remove_test.go index 7b7ad5a5d..340af3ef8 100644 --- a/cmd/helm/repo_remove_test.go +++ b/cmd/helm/repo_remove_test.go @@ -22,29 +22,24 @@ import ( "strings" "testing" - "k8s.io/helm/pkg/helm/helmpath" "k8s.io/helm/pkg/repo" "k8s.io/helm/pkg/repo/repotest" ) func TestRepoRemove(t *testing.T) { - ts, thome, err := repotest.NewTempServer("testdata/testserver/*.*") + defer resetEnv()() + + ts, hh, err := repotest.NewTempServer("testdata/testserver/*.*") if err != nil { t.Fatal(err) } - hh := helmpath.Home(thome) - cleanup := resetEnv() defer func() { ts.Stop() - os.RemoveAll(thome.String()) - cleanup() + os.RemoveAll(hh.String()) }() - if err := ensureTestHome(t, hh); err != nil { - t.Fatal(err) - } - - settings.Home = thome + ensureTestHome(t, hh) + settings.Home = hh const testRepoName = "test-name" diff --git a/cmd/helm/repo_update_test.go b/cmd/helm/repo_update_test.go index 582113314..b84cd7a2d 100644 --- a/cmd/helm/repo_update_test.go +++ b/cmd/helm/repo_update_test.go @@ -30,18 +30,10 @@ import ( ) func TestUpdateCmd(t *testing.T) { - thome, err := tempHelmHome(t) - if err != nil { - t.Fatal(err) - } - - cleanup := resetEnv() - defer func() { - os.RemoveAll(thome.String()) - cleanup() - }() + defer resetEnv()() - settings.Home = thome + hh := testHelmHome(t) + settings.Home = hh out := bytes.NewBuffer(nil) // Instead of using the HTTP updater, we provide our own for this test. @@ -53,7 +45,7 @@ func TestUpdateCmd(t *testing.T) { } o := &repoUpdateOptions{ update: updater, - home: helmpath.Home(thome), + home: helmpath.Home(hh), } if err := o.run(out); err != nil { t.Fatal(err) @@ -65,23 +57,19 @@ func TestUpdateCmd(t *testing.T) { } func TestUpdateCharts(t *testing.T) { - ts, thome, err := repotest.NewTempServer("testdata/testserver/*.*") + defer resetEnv()() + + ts, hh, err := repotest.NewTempServer("testdata/testserver/*.*") if err != nil { t.Fatal(err) } - hh := helmpath.Home(thome) - cleanup := resetEnv() defer func() { ts.Stop() - os.RemoveAll(thome.String()) - cleanup() + os.RemoveAll(hh.String()) }() - if err := ensureTestHome(t, hh); err != nil { - t.Fatal(err) - } - - settings.Home = thome + ensureTestHome(t, hh) + settings.Home = hh r, err := repo.NewChartRepository(&repo.Entry{ Name: "charts", diff --git a/cmd/helm/rollback_test.go b/cmd/helm/rollback_test.go index fd78c4d0d..73624c31e 100644 --- a/cmd/helm/rollback_test.go +++ b/cmd/helm/rollback_test.go @@ -21,7 +21,7 @@ import ( ) func TestRollbackCmd(t *testing.T) { - tests := []releaseCase{{ + tests := []cmdTestCase{{ name: "rollback a release", cmd: "rollback funny-honey 1", golden: "output/rollback.txt", @@ -39,5 +39,5 @@ func TestRollbackCmd(t *testing.T) { golden: "output/rollback-no-args.txt", wantError: true, }} - testReleaseCmd(t, tests) + runTestCmd(t, tests) } diff --git a/cmd/helm/root.go b/cmd/helm/root.go new file mode 100644 index 000000000..4ee894588 --- /dev/null +++ b/cmd/helm/root.go @@ -0,0 +1,102 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main // import "k8s.io/helm/cmd/helm" + +import ( + "io" + + "github.com/spf13/cobra" + + "k8s.io/helm/pkg/helm" +) + +var globalUsage = `The Kubernetes package manager + +To begin working with Helm, run the 'helm init' command: + + $ helm init + +This will set up any necessary local configuration. + +Common actions from this point include: + +- helm search: search for charts +- helm fetch: download a chart to your local directory to view +- helm install: upload the chart to Kubernetes +- helm list: list releases of charts + +Environment: + $HELM_HOME set an alternative location for Helm files. By default, these are stored in ~/.helm + $HELM_NO_PLUGINS disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins. + $KUBECONFIG set an alternative Kubernetes configuration file (default "~/.kube/config") +` + +func newRootCmd(c helm.Interface, out io.Writer, args []string) *cobra.Command { + cmd := &cobra.Command{ + Use: "helm", + Short: "The Helm package manager for Kubernetes.", + Long: globalUsage, + SilenceUsage: true, + } + flags := cmd.PersistentFlags() + + settings.AddFlags(flags) + + cmd.AddCommand( + // chart commands + newCreateCmd(out), + newDependencyCmd(out), + newFetchCmd(out), + newInspectCmd(out), + newLintCmd(out), + newPackageCmd(out), + newRepoCmd(out), + newSearchCmd(out), + newVerifyCmd(out), + + // release commands + newDeleteCmd(c, out), + newGetCmd(c, out), + newHistoryCmd(c, out), + newInstallCmd(c, out), + newListCmd(c, out), + newReleaseTestCmd(c, out), + newRollbackCmd(c, out), + newStatusCmd(c, out), + newUpgradeCmd(c, out), + + newCompletionCmd(out), + newHomeCmd(out), + newInitCmd(out), + newPluginCmd(out), + newTemplateCmd(out), + newVersionCmd(out), + + // Hidden documentation generator command: 'helm docs' + newDocsCmd(out), + ) + + flags.Parse(args) + + // set defaults from environment + settings.Init(flags) + + // Find and add plugins + loadPlugins(cmd, out) + + return cmd +} diff --git a/cmd/helm/root_test.go b/cmd/helm/root_test.go new file mode 100644 index 000000000..4787a43b1 --- /dev/null +++ b/cmd/helm/root_test.go @@ -0,0 +1,93 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "os" + "path/filepath" + "testing" +) + +func TestRootCmd(t *testing.T) { + defer resetEnv()() + + tests := []struct { + name, args, home string + envars map[string]string + }{ + { + name: "defaults", + args: "home", + home: filepath.Join(os.Getenv("HOME"), "/.helm"), + }, + { + name: "with --home set", + args: "--home /foo", + home: "/foo", + }, + { + name: "subcommands with --home set", + args: "home --home /foo", + home: "/foo", + }, + { + name: "with $HELM_HOME set", + args: "home", + envars: map[string]string{"HELM_HOME": "/bar"}, + home: "/bar", + }, + { + name: "subcommands with $HELM_HOME set", + args: "home", + envars: map[string]string{"HELM_HOME": "/bar"}, + home: "/bar", + }, + { + name: "with $HELM_HOME and --home set", + args: "home --home /foo", + envars: map[string]string{"HELM_HOME": "/bar"}, + home: "/foo", + }, + } + + // ensure not set locally + os.Unsetenv("HELM_HOME") + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + defer os.Unsetenv("HELM_HOME") + + for k, v := range tt.envars { + os.Setenv(k, v) + } + + cmd, _, err := executeCommandC(nil, tt.args) + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + + if settings.Home.String() != tt.home { + t.Errorf("expected home %q, got %q", tt.home, settings.Home) + } + homeFlag := cmd.Flag("home").Value.String() + homeFlag = os.ExpandEnv(homeFlag) + if homeFlag != tt.home { + t.Errorf("expected home %q, got %q", tt.home, homeFlag) + } + }) + } +} diff --git a/cmd/helm/search_test.go b/cmd/helm/search_test.go index 27d8c6c3e..9733942c0 100644 --- a/cmd/helm/search_test.go +++ b/cmd/helm/search_test.go @@ -21,51 +21,52 @@ import ( ) func TestSearchCmd(t *testing.T) { - tests := []releaseCase{{ + defer resetEnv()() + + setHome := func(cmd string) string { + return cmd + " --home=testdata/helmhome" + } + + tests := []cmdTestCase{{ name: "search for 'maria', expect one match", - cmd: "search maria", + cmd: setHome("search maria"), golden: "output/search-single.txt", }, { name: "search for 'alpine', expect two matches", - cmd: "search alpine", + cmd: setHome("search alpine"), golden: "output/search-multiple.txt", }, { name: "search for 'alpine' with versions, expect three matches", - cmd: "search alpine --versions", + cmd: setHome("search alpine --versions"), golden: "output/search-multiple-versions.txt", }, { name: "search for 'alpine' with version constraint, expect one match with version 0.1.0", - cmd: "search alpine --version '>= 0.1, < 0.2'", + cmd: setHome("search alpine --version '>= 0.1, < 0.2'"), golden: "output/search-constraint.txt", }, { name: "search for 'alpine' with version constraint, expect one match with version 0.1.0", - cmd: "search alpine --versions --version '>= 0.1, < 0.2'", + cmd: setHome("search alpine --versions --version '>= 0.1, < 0.2'"), golden: "output/search-versions-constraint.txt", }, { name: "search for 'alpine' with version constraint, expect one match with version 0.2.0", - cmd: "search alpine --version '>= 0.1'", + cmd: setHome("search alpine --version '>= 0.1'"), golden: "output/search-constraint-single.txt", }, { name: "search for 'alpine' with version constraint and --versions, expect two matches", - cmd: "search alpine --versions --version '>= 0.1'", + cmd: setHome("search alpine --versions --version '>= 0.1'"), golden: "output/search-multiple-versions-constraints.txt", }, { name: "search for 'syzygy', expect no matches", - cmd: "search syzygy", + cmd: setHome("search syzygy"), golden: "output/search-not-found.txt", }, { name: "search for 'alp[a-z]+', expect two matches", - cmd: "search alp[a-z]+ --regexp", + cmd: setHome("search alp[a-z]+ --regexp"), golden: "output/search-regex.txt", }, { name: "search for 'alp[', expect failure to compile regexp", - cmd: "search alp[ --regexp", + cmd: setHome("search alp[ --regexp"), wantError: true, }} - - cleanup := resetEnv() - defer cleanup() - - settings.Home = "testdata/helmhome" - testReleaseCmd(t, tests) + runTestCmd(t, tests) } diff --git a/cmd/helm/status_test.go b/cmd/helm/status_test.go index c94d278a3..787b59e6f 100644 --- a/cmd/helm/status_test.go +++ b/cmd/helm/status_test.go @@ -32,7 +32,7 @@ func TestStatusCmd(t *testing.T) { }} } - tests := []releaseCase{{ + tests := []cmdTestCase{{ name: "get status of a deployed release", cmd: "status flummoxed-chickadee", golden: "output/status.txt", @@ -89,5 +89,5 @@ func TestStatusCmd(t *testing.T) { }, }), }} - testReleaseCmd(t, tests) + runTestCmd(t, tests) } diff --git a/cmd/helm/testdata/output/upgrade-with-install-timeout.txt b/cmd/helm/testdata/output/upgrade-with-install-timeout.txt index 4a2233228..11d66d8d3 100644 --- a/cmd/helm/testdata/output/upgrade-with-install-timeout.txt +++ b/cmd/helm/testdata/output/upgrade-with-install-timeout.txt @@ -1,47 +1,3 @@ -REVISION: 1 -RELEASED: Fri Sep 2 22:04:05 1977 -CHART: testUpgradeChart-0.1.0 -USER-SUPPLIED VALUES: -name: "value" -COMPUTED VALUES: -affinity: {} -fullnameOverride: "" -image: - pullPolicy: IfNotPresent - repository: nginx - tag: stable -ingress: - annotations: {} - enabled: false - hosts: - - chart-example.local - path: / - tls: [] -name: value -nameOverride: "" -nodeSelector: {} -replicaCount: 1 -resources: {} -service: - port: 80 - type: ClusterIP -tolerations: [] - -HOOKS: ---- -# pre-install-hook -apiVersion: v1 -kind: Job -metadata: - annotations: - "helm.sh/hook": pre-install - -MANIFEST: -apiVersion: v1 -kind: Secret -metadata: - name: fixture - Release "crazy-bunny" has been upgraded. Happy Helming! LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC NAMESPACE: default diff --git a/cmd/helm/testdata/output/upgrade-with-install.txt b/cmd/helm/testdata/output/upgrade-with-install.txt index 90d69d65f..95cc1f625 100644 --- a/cmd/helm/testdata/output/upgrade-with-install.txt +++ b/cmd/helm/testdata/output/upgrade-with-install.txt @@ -1,47 +1,3 @@ -REVISION: 1 -RELEASED: Fri Sep 2 22:04:05 1977 -CHART: testUpgradeChart-0.1.0 -USER-SUPPLIED VALUES: -name: "value" -COMPUTED VALUES: -affinity: {} -fullnameOverride: "" -image: - pullPolicy: IfNotPresent - repository: nginx - tag: stable -ingress: - annotations: {} - enabled: false - hosts: - - chart-example.local - path: / - tls: [] -name: value -nameOverride: "" -nodeSelector: {} -replicaCount: 1 -resources: {} -service: - port: 80 - type: ClusterIP -tolerations: [] - -HOOKS: ---- -# pre-install-hook -apiVersion: v1 -kind: Job -metadata: - annotations: - "helm.sh/hook": pre-install - -MANIFEST: -apiVersion: v1 -kind: Secret -metadata: - name: fixture - Release "zany-bunny" has been upgraded. Happy Helming! LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC NAMESPACE: default diff --git a/cmd/helm/testdata/output/upgrade-with-reset-values.txt b/cmd/helm/testdata/output/upgrade-with-reset-values.txt index 4e5989e7f..53227b192 100644 --- a/cmd/helm/testdata/output/upgrade-with-reset-values.txt +++ b/cmd/helm/testdata/output/upgrade-with-reset-values.txt @@ -1,47 +1,3 @@ -REVISION: 4 -RELEASED: Fri Sep 2 22:04:05 1977 -CHART: testUpgradeChart-0.1.0 -USER-SUPPLIED VALUES: -name: "value" -COMPUTED VALUES: -affinity: {} -fullnameOverride: "" -image: - pullPolicy: IfNotPresent - repository: nginx - tag: stable -ingress: - annotations: {} - enabled: false - hosts: - - chart-example.local - path: / - tls: [] -name: value -nameOverride: "" -nodeSelector: {} -replicaCount: 1 -resources: {} -service: - port: 80 - type: ClusterIP -tolerations: [] - -HOOKS: ---- -# pre-install-hook -apiVersion: v1 -kind: Job -metadata: - annotations: - "helm.sh/hook": pre-install - -MANIFEST: -apiVersion: v1 -kind: Secret -metadata: - name: fixture - Release "funny-bunny" has been upgraded. Happy Helming! LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC NAMESPACE: default diff --git a/cmd/helm/testdata/output/upgrade-with-reset-values2.txt b/cmd/helm/testdata/output/upgrade-with-reset-values2.txt index 12c5d47a8..53227b192 100644 --- a/cmd/helm/testdata/output/upgrade-with-reset-values2.txt +++ b/cmd/helm/testdata/output/upgrade-with-reset-values2.txt @@ -1,47 +1,3 @@ -REVISION: 5 -RELEASED: Fri Sep 2 22:04:05 1977 -CHART: testUpgradeChart-0.1.0 -USER-SUPPLIED VALUES: -name: "value" -COMPUTED VALUES: -affinity: {} -fullnameOverride: "" -image: - pullPolicy: IfNotPresent - repository: nginx - tag: stable -ingress: - annotations: {} - enabled: false - hosts: - - chart-example.local - path: / - tls: [] -name: value -nameOverride: "" -nodeSelector: {} -replicaCount: 1 -resources: {} -service: - port: 80 - type: ClusterIP -tolerations: [] - -HOOKS: ---- -# pre-install-hook -apiVersion: v1 -kind: Job -metadata: - annotations: - "helm.sh/hook": pre-install - -MANIFEST: -apiVersion: v1 -kind: Secret -metadata: - name: fixture - Release "funny-bunny" has been upgraded. Happy Helming! LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC NAMESPACE: default diff --git a/cmd/helm/testdata/output/upgrade-with-timeout.txt b/cmd/helm/testdata/output/upgrade-with-timeout.txt index 156fa5951..53227b192 100644 --- a/cmd/helm/testdata/output/upgrade-with-timeout.txt +++ b/cmd/helm/testdata/output/upgrade-with-timeout.txt @@ -1,47 +1,3 @@ -REVISION: 3 -RELEASED: Fri Sep 2 22:04:05 1977 -CHART: testUpgradeChart-0.1.0 -USER-SUPPLIED VALUES: -name: "value" -COMPUTED VALUES: -affinity: {} -fullnameOverride: "" -image: - pullPolicy: IfNotPresent - repository: nginx - tag: stable -ingress: - annotations: {} - enabled: false - hosts: - - chart-example.local - path: / - tls: [] -name: value -nameOverride: "" -nodeSelector: {} -replicaCount: 1 -resources: {} -service: - port: 80 - type: ClusterIP -tolerations: [] - -HOOKS: ---- -# pre-install-hook -apiVersion: v1 -kind: Job -metadata: - annotations: - "helm.sh/hook": pre-install - -MANIFEST: -apiVersion: v1 -kind: Secret -metadata: - name: fixture - Release "funny-bunny" has been upgraded. Happy Helming! LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC NAMESPACE: default diff --git a/cmd/helm/testdata/output/upgrade-with-wait.txt b/cmd/helm/testdata/output/upgrade-with-wait.txt index 092c813a2..11d66d8d3 100644 --- a/cmd/helm/testdata/output/upgrade-with-wait.txt +++ b/cmd/helm/testdata/output/upgrade-with-wait.txt @@ -1,47 +1,3 @@ -REVISION: 2 -RELEASED: Fri Sep 2 22:04:05 1977 -CHART: testUpgradeChart-0.1.0 -USER-SUPPLIED VALUES: -name: "value" -COMPUTED VALUES: -affinity: {} -fullnameOverride: "" -image: - pullPolicy: IfNotPresent - repository: nginx - tag: stable -ingress: - annotations: {} - enabled: false - hosts: - - chart-example.local - path: / - tls: [] -name: value -nameOverride: "" -nodeSelector: {} -replicaCount: 1 -resources: {} -service: - port: 80 - type: ClusterIP -tolerations: [] - -HOOKS: ---- -# pre-install-hook -apiVersion: v1 -kind: Job -metadata: - annotations: - "helm.sh/hook": pre-install - -MANIFEST: -apiVersion: v1 -kind: Secret -metadata: - name: fixture - Release "crazy-bunny" has been upgraded. Happy Helming! LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC NAMESPACE: default diff --git a/cmd/helm/testdata/output/upgrade.txt b/cmd/helm/testdata/output/upgrade.txt index 2a31c7ea7..53227b192 100644 --- a/cmd/helm/testdata/output/upgrade.txt +++ b/cmd/helm/testdata/output/upgrade.txt @@ -1,47 +1,3 @@ -REVISION: 2 -RELEASED: Fri Sep 2 22:04:05 1977 -CHART: testUpgradeChart-0.1.0 -USER-SUPPLIED VALUES: -name: "value" -COMPUTED VALUES: -affinity: {} -fullnameOverride: "" -image: - pullPolicy: IfNotPresent - repository: nginx - tag: stable -ingress: - annotations: {} - enabled: false - hosts: - - chart-example.local - path: / - tls: [] -name: value -nameOverride: "" -nodeSelector: {} -replicaCount: 1 -resources: {} -service: - port: 80 - type: ClusterIP -tolerations: [] - -HOOKS: ---- -# pre-install-hook -apiVersion: v1 -kind: Job -metadata: - annotations: - "helm.sh/hook": pre-install - -MANIFEST: -apiVersion: v1 -kind: Secret -metadata: - name: fixture - Release "funny-bunny" has been upgraded. Happy Helming! LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC NAMESPACE: default diff --git a/cmd/helm/upgrade_test.go b/cmd/helm/upgrade_test.go index 4b689297e..c75b50b1a 100644 --- a/cmd/helm/upgrade_test.go +++ b/cmd/helm/upgrade_test.go @@ -17,9 +17,6 @@ limitations under the License. package main import ( - "io/ioutil" - "os" - "path/filepath" "testing" "k8s.io/helm/pkg/chartutil" @@ -29,8 +26,7 @@ import ( ) func TestUpgradeCmd(t *testing.T) { - tmpChart, _ := ioutil.TempDir("testdata", "tmp") - defer os.RemoveAll(tmpChart) + tmpChart := testTempDir(t) cfile := &chart.Metadata{ Name: "testUpgradeChart", Description: "A Helm chart for Kubernetes", @@ -38,9 +34,12 @@ func TestUpgradeCmd(t *testing.T) { } chartPath, err := chartutil.Create(cfile, tmpChart) if err != nil { - t.Errorf("Error creating chart for upgrade: %v", err) + t.Fatalf("Error creating chart for upgrade: %v", err) + } + ch, err := chartutil.Load(chartPath) + if err != nil { + t.Fatalf("Error loading chart: %v", err) } - ch, _ := chartutil.Load(chartPath) _ = helm.ReleaseMock(&helm.MockReleaseOptions{ Name: "funny-bunny", Chart: ch, @@ -55,11 +54,11 @@ func TestUpgradeCmd(t *testing.T) { chartPath, err = chartutil.Create(cfile, tmpChart) if err != nil { - t.Errorf("Error creating chart: %v", err) + t.Fatalf("Error creating chart: %v", err) } ch, err = chartutil.Load(chartPath) if err != nil { - t.Errorf("Error loading updated chart: %v", err) + t.Fatalf("Error loading updated chart: %v", err) } // update chart version again @@ -71,22 +70,22 @@ func TestUpgradeCmd(t *testing.T) { chartPath, err = chartutil.Create(cfile, tmpChart) if err != nil { - t.Errorf("Error creating chart: %v", err) + t.Fatalf("Error creating chart: %v", err) } var ch2 *chart.Chart ch2, err = chartutil.Load(chartPath) if err != nil { - t.Errorf("Error loading updated chart: %v", err) + t.Fatalf("Error loading updated chart: %v", err) } - missingDepsPath := filepath.Join("testdata/testcharts/chart-missing-deps") - badDepsPath := filepath.Join("testdata/testcharts/chart-bad-requirements") + missingDepsPath := "testdata/testcharts/chart-missing-deps" + badDepsPath := "testdata/testcharts/chart-bad-requirements" relMock := func(n string, v int, ch *chart.Chart) *release.Release { return helm.ReleaseMock(&helm.MockReleaseOptions{Name: n, Version: v, Chart: ch}) } - tests := []releaseCase{ + tests := []cmdTestCase{ { name: "upgrade a release", cmd: "upgrade funny-bunny " + chartPath, @@ -142,5 +141,5 @@ func TestUpgradeCmd(t *testing.T) { wantError: true, }, } - testReleaseCmd(t, tests) + runTestCmd(t, tests) } diff --git a/cmd/helm/version_test.go b/cmd/helm/version_test.go index 166b78f93..0573dbf06 100644 --- a/cmd/helm/version_test.go +++ b/cmd/helm/version_test.go @@ -20,7 +20,7 @@ import ( ) func TestVersion(t *testing.T) { - tests := []releaseCase{{ + tests := []cmdTestCase{{ name: "default", cmd: "version", golden: "output/version.txt", @@ -29,5 +29,5 @@ func TestVersion(t *testing.T) { cmd: "version --template='Version: {{.Version}}'", golden: "output/version-template.txt", }} - testReleaseCmd(t, tests) + runTestCmd(t, tests) } diff --git a/internal/test/test.go b/internal/test/test.go index 6dbff7b90..a61c32a83 100644 --- a/internal/test/test.go +++ b/internal/test/test.go @@ -42,7 +42,7 @@ func AssertGoldenBytes(t TestingT, actual []byte, filename string) { t.Helper() if err := compare(actual, path(filename)); err != nil { - t.Fatalf("%+v", err) + t.Fatalf("%v", err) } } @@ -50,7 +50,7 @@ func AssertGoldenString(t TestingT, actual, filename string) { t.Helper() if err := compare([]byte(actual), path(filename)); err != nil { - t.Fatalf("%+v", err) + t.Fatalf("%v", err) } } diff --git a/pkg/helm/environment/environment_test.go b/pkg/helm/environment/environment_test.go index ebc5822b4..3f506b099 100644 --- a/pkg/helm/environment/environment_test.go +++ b/pkg/helm/environment/environment_test.go @@ -71,11 +71,10 @@ func TestEnvSettings(t *testing.T) { }, } - cleanup := resetEnv() - defer cleanup() - for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + defer resetEnv()() + for k, v := range tt.envars { os.Setenv(k, v) } @@ -103,8 +102,6 @@ func TestEnvSettings(t *testing.T) { if settings.KubeContext != tt.kcontext { t.Errorf("expected kube-context %q, got %q", tt.kcontext, settings.KubeContext) } - - cleanup() }) } }