From 65824c93274f0df0cd4e4a0a904966a7b76b83f0 Mon Sep 17 00:00:00 2001 From: Bhargav Date: Mon, 28 Oct 2024 00:47:16 +0530 Subject: [PATCH] refactor(helm test): Pass extra args with helm tests Pass these extra arguments in Helm test cases: 1. REST client getter to be used with Helm action config 2. Kube client options for be used with fake printer kube client Related to #12722 Signed-off-by: Bhargav Ravuri --- cmd/helm/completion_test.go | 2 +- cmd/helm/create_test.go | 7 +++-- cmd/helm/dependency_build_test.go | 10 +++--- cmd/helm/dependency_update_test.go | 18 +++++++---- cmd/helm/helm_test.go | 49 +++++++++++++++++++++++------- cmd/helm/package_test.go | 4 +-- cmd/helm/pull_test.go | 4 +-- cmd/helm/repo_add_test.go | 2 +- cmd/helm/rollback_test.go | 2 +- cmd/helm/root_test.go | 4 +-- cmd/helm/search_hub_test.go | 6 ++-- cmd/helm/show_test.go | 3 +- cmd/helm/upgrade_test.go | 22 +++++++------- cmd/helm/verify_test.go | 2 +- pkg/kube/fake/printer.go | 9 +++++- 15 files changed, 92 insertions(+), 52 deletions(-) diff --git a/cmd/helm/completion_test.go b/cmd/helm/completion_test.go index 1143d644516..6ec9030e96f 100644 --- a/cmd/helm/completion_test.go +++ b/cmd/helm/completion_test.go @@ -41,7 +41,7 @@ func checkFileCompletion(t *testing.T, cmdName string, shouldBePerformed bool) { }) testcmd := fmt.Sprintf("__complete %s ''", cmdName) - _, out, err := executeActionCommandC(storage, testcmd) + _, out, err := executeActionCommandC(storage, testcmd, nil, nil) if err != nil { t.Errorf("unexpected error, %s", err) } diff --git a/cmd/helm/create_test.go b/cmd/helm/create_test.go index 1a22d058fd0..22caa6737b2 100644 --- a/cmd/helm/create_test.go +++ b/cmd/helm/create_test.go @@ -36,7 +36,7 @@ func TestCreateCmd(t *testing.T) { defer testChdir(t, dir)() // Run a create - if _, _, err := executeActionCommand("create " + cname); err != nil { + if _, _, err := executeActionCommand("create "+cname, nil, nil); err != nil { t.Fatalf("Failed to run create: %s", err) } @@ -81,7 +81,7 @@ func TestCreateStarterCmd(t *testing.T) { } // Run a create - if _, _, err := executeActionCommand(fmt.Sprintf("create --starter=starterchart %s", cname)); err != nil { + if _, _, err := executeActionCommand(fmt.Sprintf("create --starter=starterchart %s", cname), nil, nil); err != nil { t.Errorf("Failed to run create: %s", err) return } @@ -149,7 +149,8 @@ func TestCreateStarterAbsoluteCmd(t *testing.T) { starterChartPath := filepath.Join(starterchart, "starterchart") // Run a create - if _, _, err := executeActionCommand(fmt.Sprintf("create --starter=%s %s", starterChartPath, cname)); err != nil { + _, _, err := executeActionCommand(fmt.Sprintf("create --starter=%s %s", starterChartPath, cname), nil, nil) + if err != nil { t.Errorf("Failed to run create: %s", err) return } diff --git a/cmd/helm/dependency_build_test.go b/cmd/helm/dependency_build_test.go index 37e3242c49f..d8ec5fd9805 100644 --- a/cmd/helm/dependency_build_test.go +++ b/cmd/helm/dependency_build_test.go @@ -59,7 +59,7 @@ func TestDependencyBuildCmd(t *testing.T) { repoFile := filepath.Join(rootDir, "repositories.yaml") cmd := fmt.Sprintf("dependency build '%s' --repository-config %s --repository-cache %s", filepath.Join(rootDir, chartname), repoFile, rootDir) - _, out, err := executeActionCommand(cmd) + _, out, err := executeActionCommand(cmd, nil, nil) // In the first pass, we basically want the same results as an update. if err != nil { @@ -87,7 +87,7 @@ func TestDependencyBuildCmd(t *testing.T) { t.Fatal(err) } - _, out, err = executeActionCommand(cmd) + _, out, err = executeActionCommand(cmd, nil, nil) if err != nil { t.Logf("Output: %s", out) t.Fatal(err) @@ -118,7 +118,7 @@ func TestDependencyBuildCmd(t *testing.T) { } skipRefreshCmd := fmt.Sprintf("dependency build '%s' --skip-refresh --repository-config %s --repository-cache %s", filepath.Join(rootDir, chartname), repoFile, rootDir) - _, out, err = executeActionCommand(skipRefreshCmd) + _, out, err = executeActionCommand(skipRefreshCmd, nil, nil) // In this pass, we check --skip-refresh option becomes effective. if err != nil { @@ -139,7 +139,7 @@ func TestDependencyBuildCmd(t *testing.T) { dir("repositories.yaml"), dir(), dir()) - _, out, err = executeActionCommand(cmd) + _, out, err = executeActionCommand(cmd, nil, nil) if err != nil { t.Logf("Output: %s", out) t.Fatal(err) @@ -154,7 +154,7 @@ func TestDependencyBuildCmdWithHelmV2Hash(t *testing.T) { chartName := "testdata/testcharts/issue-7233" cmd := fmt.Sprintf("dependency build '%s'", chartName) - _, out, err := executeActionCommand(cmd) + _, out, err := executeActionCommand(cmd, nil, nil) // Want to make sure the build can verify Helm v2 hash if err != nil { diff --git a/cmd/helm/dependency_update_test.go b/cmd/helm/dependency_update_test.go index 1a1e0468f07..0178bcccf82 100644 --- a/cmd/helm/dependency_update_test.go +++ b/cmd/helm/dependency_update_test.go @@ -68,7 +68,7 @@ func TestDependencyUpdateCmd(t *testing.T) { _, out, err := executeActionCommand( fmt.Sprintf("dependency update '%s' --repository-config %s --repository-cache %s", dir(chartname), dir("repositories.yaml"), dir()), - ) + nil, nil) if err != nil { t.Logf("Output: %s", out) t.Fatal(err) @@ -110,7 +110,9 @@ func TestDependencyUpdateCmd(t *testing.T) { t.Fatal(err) } - _, out, err = executeActionCommand(fmt.Sprintf("dependency update '%s' --repository-config %s --repository-cache %s", dir(chartname), dir("repositories.yaml"), dir())) + _, out, err = executeActionCommand( + fmt.Sprintf("dependency update '%s' --repository-config %s --repository-cache %s", dir(chartname), dir("repositories.yaml"), dir()), + nil, nil) if err != nil { t.Logf("Output: %s", out) t.Fatal(err) @@ -136,7 +138,7 @@ func TestDependencyUpdateCmd(t *testing.T) { dir("repositories.yaml"), dir(), dir()) - _, out, err = executeActionCommand(cmd) + _, out, err = executeActionCommand(cmd, nil, nil) if err != nil { t.Logf("Output: %s", out) t.Fatal(err) @@ -169,7 +171,9 @@ func TestDependencyUpdateCmd_DoNotDeleteOldChartsOnError(t *testing.T) { } createTestingChart(t, dir(), chartname, srv.URL()) - _, output, err := executeActionCommand(fmt.Sprintf("dependency update %s --repository-config %s --repository-cache %s", dir(chartname), dir("repositories.yaml"), dir())) + _, output, err := executeActionCommand( + fmt.Sprintf("dependency update %s --repository-config %s --repository-cache %s", dir(chartname), dir("repositories.yaml"), dir()), + nil, nil) if err != nil { t.Logf("Output: %s", output) t.Fatal(err) @@ -178,7 +182,9 @@ func TestDependencyUpdateCmd_DoNotDeleteOldChartsOnError(t *testing.T) { // Chart repo is down srv.Stop() - _, output, err = executeActionCommand(fmt.Sprintf("dependency update %s --repository-config %s --repository-cache %s", dir(chartname), dir("repositories.yaml"), dir())) + _, output, err = executeActionCommand( + fmt.Sprintf("dependency update %s --repository-config %s --repository-cache %s", dir(chartname), dir("repositories.yaml"), dir()), + nil, nil) if err == nil { t.Logf("Output: %s", output) t.Fatal("Expected error, got nil") @@ -233,7 +239,7 @@ func TestDependencyUpdateCmd_WithRepoThatWasNotAdded(t *testing.T) { _, out, err := executeActionCommand( fmt.Sprintf("dependency update '%s' --repository-config %s --repository-cache %s", dir(chartname), dir("repositories.yaml"), dir()), - ) + nil, nil) if err != nil { t.Logf("Output: %s", out) diff --git a/cmd/helm/helm_test.go b/cmd/helm/helm_test.go index 7d0bf57516a..810ade20959 100644 --- a/cmd/helm/helm_test.go +++ b/cmd/helm/helm_test.go @@ -59,7 +59,12 @@ func runTestCmd(t *testing.T, tests []cmdTestCase) { } } t.Logf("running cmd (attempt %d): %s", i+1, tt.cmd) - _, out, err := executeActionCommandC(storage, tt.cmd) + _, out, err := executeActionCommandC( + storage, + tt.cmd, + tt.restClientGetter, + tt.kubeClientOpts, + ) if tt.wantError && err == nil { t.Errorf("expected error, got success with the following output:\n%s", out) } @@ -78,11 +83,22 @@ func storageFixture() *storage.Storage { return storage.Init(driver.NewMemory()) } -func executeActionCommandC(store *storage.Storage, cmd string) (*cobra.Command, string, error) { - return executeActionCommandStdinC(store, nil, cmd) +func executeActionCommandC( + store *storage.Storage, + cmd string, + restClientGetter action.RESTClientGetter, + kubeClientOpts *kubefake.Options, +) (*cobra.Command, string, error) { + return executeActionCommandStdinC(store, nil, cmd, restClientGetter, kubeClientOpts) } -func executeActionCommandStdinC(store *storage.Storage, in *os.File, cmd string) (*cobra.Command, string, error) { +func executeActionCommandStdinC( + store *storage.Storage, + in *os.File, + cmd string, + restClientGetter action.RESTClientGetter, + kubeClientOpts *kubefake.Options, +) (*cobra.Command, string, error) { args, err := shellwords.Parse(cmd) if err != nil { return nil, "", err @@ -91,10 +107,14 @@ func executeActionCommandStdinC(store *storage.Storage, in *os.File, cmd string) buf := new(bytes.Buffer) actionConfig := &action.Configuration{ - Releases: store, - KubeClient: &kubefake.PrintingKubeClient{Out: io.Discard}, - Capabilities: chartutil.DefaultCapabilities, - Log: func(_ string, _ ...interface{}) {}, + Releases: store, + KubeClient: &kubefake.PrintingKubeClient{ + Out: io.Discard, + Options: kubeClientOpts, + }, + Capabilities: chartutil.DefaultCapabilities, + Log: func(_ string, _ ...interface{}) {}, + RESTClientGetter: restClientGetter, } root, err := newRootCmd(actionConfig, buf, args) @@ -135,10 +155,18 @@ type cmdTestCase struct { // Number of repeats (in case a feature was previously flaky and the test checks // it's now stably producing identical results). 0 means test is run exactly once. repeat int + // REST client getter to be used with Helm action config + restClientGetter action.RESTClientGetter + // Kube client options for be used with fake printer kube client + kubeClientOpts *kubefake.Options } -func executeActionCommand(cmd string) (*cobra.Command, string, error) { - return executeActionCommandC(storageFixture(), cmd) +func executeActionCommand( + cmd string, + restClientGetter action.RESTClientGetter, + kubeClintOpts *kubefake.Options, +) (*cobra.Command, string, error) { + return executeActionCommandC(storageFixture(), cmd, restClientGetter, kubeClintOpts) } func resetEnv() func() { @@ -201,7 +229,6 @@ func TestPluginExitCode(t *testing.T) { cmd.Stderr = stderr err := cmd.Run() exiterr, ok := err.(*exec.ExitError) - if !ok { t.Fatalf("Unexpected error returned by os.Exit: %T", err) } diff --git a/cmd/helm/package_test.go b/cmd/helm/package_test.go index 9093b510cfd..0b698cd81e9 100644 --- a/cmd/helm/package_test.go +++ b/cmd/helm/package_test.go @@ -138,7 +138,7 @@ func TestPackage(t *testing.T) { cmd = append(cmd, fmt.Sprintf("--%s=%s", k, v)) } } - _, _, err = executeActionCommand(strings.Join(cmd, " ")) + _, _, err = executeActionCommand(strings.Join(cmd, " "), nil, nil) if err != nil { if tt.err && re.MatchString(err.Error()) { return @@ -171,7 +171,7 @@ func TestSetAppVersion(t *testing.T) { chartToPackage := "testdata/testcharts/alpine" dir := t.TempDir() cmd := fmt.Sprintf("package %s --destination=%s --app-version=%s", chartToPackage, dir, expectedAppVersion) - _, output, err := executeActionCommand(cmd) + _, output, err := executeActionCommand(cmd, nil, nil) if err != nil { t.Logf("Output: %s", output) t.Fatal(err) diff --git a/cmd/helm/pull_test.go b/cmd/helm/pull_test.go index ae70595f933..3709d489ee2 100644 --- a/cmd/helm/pull_test.go +++ b/cmd/helm/pull_test.go @@ -220,7 +220,7 @@ func TestPullCmd(t *testing.T) { t.Fatal(err) } } - _, out, err := executeActionCommand(cmd) + _, out, err := executeActionCommand(cmd, nil, nil) if err != nil { if tt.wantError { if tt.wantErrorMsg != "" && tt.wantErrorMsg == err.Error() { @@ -337,7 +337,7 @@ func TestPullWithCredentialsCmd(t *testing.T) { t.Fatal(err) } } - _, _, err := executeActionCommand(cmd) + _, _, err := executeActionCommand(cmd, nil, nil) if err != nil { if tt.wantError { if tt.wantErrorMsg != "" && tt.wantErrorMsg == err.Error() { diff --git a/cmd/helm/repo_add_test.go b/cmd/helm/repo_add_test.go index 2386bb01fa0..f501d88793b 100644 --- a/cmd/helm/repo_add_test.go +++ b/cmd/helm/repo_add_test.go @@ -262,7 +262,7 @@ func TestRepoAddWithPasswordFromStdin(t *testing.T) { const username = "username" cmd := fmt.Sprintf("repo add %s %s --repository-config %s --repository-cache %s --username %s --password-stdin", testName, srv.URL(), repoFile, tmpdir, username) var result string - _, result, err = executeActionCommandStdinC(store, in, cmd) + _, result, err = executeActionCommandStdinC(store, in, cmd, nil, nil) if err != nil { t.Errorf("unexpected error, got '%v'", err) } diff --git a/cmd/helm/rollback_test.go b/cmd/helm/rollback_test.go index b58e4c162f3..f3273600b58 100644 --- a/cmd/helm/rollback_test.go +++ b/cmd/helm/rollback_test.go @@ -151,7 +151,7 @@ func TestRollbackWithLabels(t *testing.T) { t.Fatal(err) } } - _, _, err := executeActionCommandC(storage, fmt.Sprintf("rollback %s 1", releaseName)) + _, _, err := executeActionCommandC(storage, fmt.Sprintf("rollback %s 1", releaseName), nil, nil) if err != nil { t.Errorf("unexpected error, got '%v'", err) } diff --git a/cmd/helm/root_test.go b/cmd/helm/root_test.go index 65e6d66c711..25edac56510 100644 --- a/cmd/helm/root_test.go +++ b/cmd/helm/root_test.go @@ -83,7 +83,7 @@ func TestRootCmd(t *testing.T) { os.Setenv(k, v) } - if _, _, err := executeActionCommand(tt.args); err != nil { + if _, _, err := executeActionCommand(tt.args, nil, nil); err != nil { t.Fatalf("unexpected error: %s", err) } @@ -115,7 +115,7 @@ func TestRootCmd(t *testing.T) { } func TestUnknownSubCmd(t *testing.T) { - _, _, err := executeActionCommand("foobar") + _, _, err := executeActionCommand("foobar", nil, nil) if err == nil || err.Error() != `unknown command "foobar" for "helm"` { t.Errorf("Expect unknown command error, got %q", err) diff --git a/cmd/helm/search_hub_test.go b/cmd/helm/search_hub_test.go index f3730275a8f..711165f5ecf 100644 --- a/cmd/helm/search_hub_test.go +++ b/cmd/helm/search_hub_test.go @@ -42,7 +42,7 @@ func TestSearchHubCmd(t *testing.T) { testcmd := "search hub --endpoint " + ts.URL + " maria" storage := storageFixture() - _, out, err := executeActionCommandC(storage, testcmd) + _, out, err := executeActionCommandC(storage, testcmd, nil, nil) if err != nil { t.Errorf("unexpected error, %s", err) } @@ -72,7 +72,7 @@ func TestSearchHubListRepoCmd(t *testing.T) { testcmd := "search hub --list-repo-url --endpoint " + ts.URL + " maria" storage := storageFixture() - _, out, err := executeActionCommandC(storage, testcmd) + _, out, err := executeActionCommandC(storage, testcmd, nil, nil) if err != nil { t.Errorf("unexpected error, %s", err) } @@ -165,7 +165,7 @@ func TestSearchHubCmd_FailOnNoResponseTests(t *testing.T) { storage := storageFixture() - _, out, err := executeActionCommandC(storage, tt.cmd) + _, out, err := executeActionCommandC(storage, tt.cmd, nil, nil) if tt.wantErr { if err == nil { t.Errorf("expected error due to no record in response, got nil") diff --git a/cmd/helm/show_test.go b/cmd/helm/show_test.go index 93ec08d0f6b..05782f6dbd8 100644 --- a/cmd/helm/show_test.go +++ b/cmd/helm/show_test.go @@ -73,8 +73,7 @@ func TestShowPreReleaseChart(t *testing.T) { filepath.Join(outdir, "repositories.yaml"), outdir, ) - //_, out, err := executeActionCommand(cmd) - _, _, err := executeActionCommand(cmd) + _, _, err := executeActionCommand(cmd, nil, nil) if err != nil { if tt.fail { if !strings.Contains(err.Error(), tt.expectedErr) { diff --git a/cmd/helm/upgrade_test.go b/cmd/helm/upgrade_test.go index 497c78d71c2..4f2ec3038e8 100644 --- a/cmd/helm/upgrade_test.go +++ b/cmd/helm/upgrade_test.go @@ -196,7 +196,7 @@ func TestUpgradeWithValue(t *testing.T) { store.Create(relMock(releaseName, 3, ch)) cmd := fmt.Sprintf("upgrade %s --set favoriteDrink=tea '%s'", releaseName, chartPath) - _, _, err := executeActionCommandC(store, cmd) + _, _, err := executeActionCommandC(store, cmd, nil, nil) if err != nil { t.Errorf("unexpected error, got '%v'", err) } @@ -223,7 +223,7 @@ func TestUpgradeWithStringValue(t *testing.T) { store.Create(relMock(releaseName, 3, ch)) cmd := fmt.Sprintf("upgrade %s --set-string favoriteDrink=coffee '%s'", releaseName, chartPath) - _, _, err := executeActionCommandC(store, cmd) + _, _, err := executeActionCommandC(store, cmd, nil, nil) if err != nil { t.Errorf("unexpected error, got '%v'", err) } @@ -251,7 +251,7 @@ func TestUpgradeInstallWithSubchartNotes(t *testing.T) { store.Create(relMock(releaseName, 1, ch)) cmd := fmt.Sprintf("upgrade %s -i --render-subchart-notes '%s'", releaseName, "testdata/testcharts/chart-with-subchart-notes") - _, _, err := executeActionCommandC(store, cmd) + _, _, err := executeActionCommandC(store, cmd, nil, nil) if err != nil { t.Errorf("unexpected error, got '%v'", err) } @@ -283,7 +283,7 @@ func TestUpgradeWithValuesFile(t *testing.T) { store.Create(relMock(releaseName, 3, ch)) cmd := fmt.Sprintf("upgrade %s --values testdata/testcharts/upgradetest/values.yaml '%s'", releaseName, chartPath) - _, _, err := executeActionCommandC(store, cmd) + _, _, err := executeActionCommandC(store, cmd, nil, nil) if err != nil { t.Errorf("unexpected error, got '%v'", err) } @@ -316,7 +316,7 @@ func TestUpgradeWithValuesFromStdin(t *testing.T) { } cmd := fmt.Sprintf("upgrade %s --values - '%s'", releaseName, chartPath) - _, _, err = executeActionCommandStdinC(store, in, cmd) + _, _, err = executeActionCommandStdinC(store, in, cmd, nil, nil) if err != nil { t.Errorf("unexpected error, got '%v'", err) } @@ -346,7 +346,7 @@ func TestUpgradeInstallWithValuesFromStdin(t *testing.T) { } cmd := fmt.Sprintf("upgrade %s -f - --install '%s'", releaseName, chartPath) - _, _, err = executeActionCommandStdinC(store, in, cmd) + _, _, err = executeActionCommandStdinC(store, in, cmd, nil, nil) if err != nil { t.Errorf("unexpected error, got '%v'", err) } @@ -450,7 +450,7 @@ func TestUpgradeInstallWithLabels(t *testing.T) { "key2": "val2", } cmd := fmt.Sprintf("upgrade %s --install --labels key1=val1,key2=val2 '%s'", releaseName, chartPath) - _, _, err := executeActionCommandC(store, cmd) + _, _, err := executeActionCommandC(store, cmd, nil, nil) if err != nil { t.Errorf("unexpected error, got '%v'", err) } @@ -515,7 +515,7 @@ func TestUpgradeWithDryRun(t *testing.T) { // First install a release into the store so that future --dry-run attempts // have it available. cmd := fmt.Sprintf("upgrade %s --install '%s'", releaseName, chartPath) - _, _, err := executeActionCommandC(store, cmd) + _, _, err := executeActionCommandC(store, cmd, nil, nil) if err != nil { t.Errorf("unexpected error, got '%v'", err) } @@ -526,7 +526,7 @@ func TestUpgradeWithDryRun(t *testing.T) { } cmd = fmt.Sprintf("upgrade %s --dry-run '%s'", releaseName, chartPath) - _, out, err := executeActionCommandC(store, cmd) + _, out, err := executeActionCommandC(store, cmd, nil, nil) if err != nil { t.Errorf("unexpected error, got '%v'", err) } @@ -543,7 +543,7 @@ func TestUpgradeWithDryRun(t *testing.T) { // Ensure the secret is not in the output cmd = fmt.Sprintf("upgrade %s --dry-run --hide-secret '%s'", releaseName, chartPath) - _, out, err = executeActionCommandC(store, cmd) + _, out, err = executeActionCommandC(store, cmd, nil, nil) if err != nil { t.Errorf("unexpected error, got '%v'", err) } @@ -560,7 +560,7 @@ func TestUpgradeWithDryRun(t *testing.T) { // Ensure there is an error when --hide-secret used without dry-run cmd = fmt.Sprintf("upgrade %s --hide-secret '%s'", releaseName, chartPath) - _, _, err = executeActionCommandC(store, cmd) + _, _, err = executeActionCommandC(store, cmd, nil, nil) if err == nil { t.Error("expected error when --hide-secret used without --dry-run") } diff --git a/cmd/helm/verify_test.go b/cmd/helm/verify_test.go index 23b7935577c..b907c121405 100644 --- a/cmd/helm/verify_test.go +++ b/cmd/helm/verify_test.go @@ -72,7 +72,7 @@ func TestVerifyCmd(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - _, out, err := executeActionCommand(tt.cmd) + _, out, err := executeActionCommand(tt.cmd, nil, nil) if tt.wantError { if err == nil { t.Errorf("Expected error, but got none: %q", out) diff --git a/pkg/kube/fake/printer.go b/pkg/kube/fake/printer.go index cc2c84b40b8..d6a937c718c 100644 --- a/pkg/kube/fake/printer.go +++ b/pkg/kube/fake/printer.go @@ -29,10 +29,17 @@ import ( "helm.sh/helm/v3/pkg/kube" ) +// Options to control the fake behavior of PrintingKubeClient +type Options struct { + GetReturnResourceMap bool + BuildReturnResourceList bool +} + // PrintingKubeClient implements KubeClient, but simply prints the reader to // the given output. type PrintingKubeClient struct { - Out io.Writer + Out io.Writer + Options *Options } // IsReachable checks if the cluster is reachable