From 9b30076180b8f73bbe25d0f4cd752207154ad0c1 Mon Sep 17 00:00:00 2001 From: LarytheLord Date: Thu, 5 Mar 2026 23:47:34 +0530 Subject: [PATCH 01/61] test(cli): isolate user-agent rest config test from host kubeconfig Signed-off-by: LarytheLord --- pkg/cli/environment_test.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/pkg/cli/environment_test.go b/pkg/cli/environment_test.go index 9303389a3..df87b86df 100644 --- a/pkg/cli/environment_test.go +++ b/pkg/cli/environment_test.go @@ -18,6 +18,7 @@ package cli import ( "os" + "path/filepath" "strings" "testing" @@ -220,6 +221,30 @@ func TestEnvOrBool(t *testing.T) { func TestUserAgentHeaderInK8sRESTClientConfig(t *testing.T) { defer resetEnv()() + kubeconfigPath := filepath.Join(t.TempDir(), "config") + kubeconfig := `apiVersion: v1 +clusters: +- cluster: + server: https://127.0.0.1:6443 + name: test +contexts: +- context: + cluster: test + user: test-user + name: test +current-context: test +kind: Config +preferences: {} +users: +- name: test-user + user: + token: test-token +` + if err := os.WriteFile(kubeconfigPath, []byte(kubeconfig), 0o600); err != nil { + t.Fatalf("failed to create test kubeconfig: %v", err) + } + t.Setenv("KUBECONFIG", kubeconfigPath) + settings := New() restConfig, err := settings.RESTClientGetter().ToRESTConfig() require.NoError(t, err) From 47bde119597961113d769a9d46a565f448565e7a Mon Sep 17 00:00:00 2001 From: LarytheLord Date: Sun, 8 Mar 2026 18:32:35 +0530 Subject: [PATCH 02/61] test(cli): use t.Cleanup for resetEnv with t.Setenv Signed-off-by: LarytheLord --- pkg/cli/environment_test.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pkg/cli/environment_test.go b/pkg/cli/environment_test.go index df87b86df..2d7851a4f 100644 --- a/pkg/cli/environment_test.go +++ b/pkg/cli/environment_test.go @@ -120,7 +120,8 @@ func TestEnvSettings(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - defer resetEnv()() + cleanup := resetEnv() + t.Cleanup(cleanup) for k, v := range tt.envvars { t.Setenv(k, v) @@ -219,7 +220,8 @@ func TestEnvOrBool(t *testing.T) { } func TestUserAgentHeaderInK8sRESTClientConfig(t *testing.T) { - defer resetEnv()() + cleanup := resetEnv() + t.Cleanup(cleanup) kubeconfigPath := filepath.Join(t.TempDir(), "config") kubeconfig := `apiVersion: v1 From 9f3c89a4b50e99a46c23b6942b87b205bdd8c33f Mon Sep 17 00:00:00 2001 From: Benoit Tigeot Date: Thu, 16 Jul 2026 09:29:59 +0200 Subject: [PATCH 03/61] ci: auto-label PRs targeting main with v4.x Mirrors the dev-v3 labeling workflow from #32340, reusing the existing v4.x label since main tracks the upcoming v4 release. Signed-off-by: Benoit Tigeot --- .github/labeler.yml | 2 ++ .github/workflows/label-pr.yml | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 .github/labeler.yml create mode 100644 .github/workflows/label-pr.yml diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 000000000..46d20af9c --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,2 @@ +"v4.x": + - base-branch: "main" diff --git a/.github/workflows/label-pr.yml b/.github/workflows/label-pr.yml new file mode 100644 index 000000000..5c2b2fa17 --- /dev/null +++ b/.github/workflows/label-pr.yml @@ -0,0 +1,16 @@ +name: Label PRs +on: + pull_request_target: + branches: [main] + types: [opened, reopened, edited, synchronize] +permissions: {} +jobs: + label: + permissions: + contents: read + pull-requests: write + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@b8dd2d9be0f68b860e7dae5dae7d772984eacd6d # pin@v6.2.0 + with: + sync-labels: true From eeb37edfeafffdb562b97774f85a394332cf58dd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Jul 2026 21:32:51 +0000 Subject: [PATCH 04/61] chore(deps): bump github/codeql-action/autobuild from 4.37.0 to 4.37.1 Bumps [github/codeql-action/autobuild](https://github.com/github/codeql-action) from 4.37.0 to 4.37.1. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/99df26d4f13ea111d4ec1a7dddef6063f76b97e9...7188fc363630916deb702c7fdcf4e481b751f97a) --- updated-dependencies: - dependency-name: github/codeql-action/autobuild dependency-version: 4.37.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index e87ec8ec2..52c045e85 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -59,7 +59,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # pinv4.37.0 + uses: github/codeql-action/autobuild@7188fc363630916deb702c7fdcf4e481b751f97a # pinv4.37.1 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl From a494169853d1e6f752eb838fedbb00d1a8593b66 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Jul 2026 05:44:01 -0600 Subject: [PATCH 05/61] chore(deps): bump actions/setup-go from 6.5.0 to 7.0.0 (#32376) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 6.5.0 to 7.0.0. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/924ae3a1cded613372ab5595356fb5720e22ba16...b7ad1dad31e06c5925ef5d2fc7ad053ef454303e) --- updated-dependencies: - dependency-name: actions/setup-go dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-test.yml | 2 +- .github/workflows/golangci-lint.yml | 2 +- .github/workflows/govulncheck.yml | 2 +- .github/workflows/release.yml | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index b4ce89f26..066adf1ce 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -22,7 +22,7 @@ jobs: - name: Add variables to environment file run: cat ".github/env" >> "$GITHUB_ENV" - name: Setup Go - uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # pin@6.5.0 + uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # pin@7.0.0 with: go-version: '${{ env.GOLANG_VERSION }}' check-latest: true diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 6355db230..c5312e936 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -17,7 +17,7 @@ jobs: - name: Add variables to environment file run: cat ".github/env" >> "$GITHUB_ENV" - name: Setup Go - uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # pin@6.5.0 + uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # pin@7.0.0 with: go-version: '${{ env.GOLANG_VERSION }}' check-latest: true diff --git a/.github/workflows/govulncheck.yml b/.github/workflows/govulncheck.yml index c7c9b3d53..0aee4c01c 100644 --- a/.github/workflows/govulncheck.yml +++ b/.github/workflows/govulncheck.yml @@ -25,7 +25,7 @@ jobs: - name: Add variables to environment file run: cat ".github/env" >> "$GITHUB_ENV" - name: Setup Go - uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # pin@6.5.0 + uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # pin@7.0.0 with: go-version: '${{ env.GOLANG_VERSION }}' check-latest: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ee2612917..3bed1e12a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,7 +28,7 @@ jobs: run: cat ".github/env" >> "$GITHUB_ENV" - name: Setup Go - uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # pin@6.5.0 + uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # pin@7.0.0 with: go-version: '${{ env.GOLANG_VERSION }}' check-latest: true @@ -93,7 +93,7 @@ jobs: run: cat ".github/env" >> "$GITHUB_ENV" - name: Setup Go - uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # pin@6.5.0 + uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # pin@7.0.0 with: go-version: '${{ env.GOLANG_VERSION }}' check-latest: true From 06b95860dc2419062834a5e59921569676b45031 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Jul 2026 05:44:39 -0600 Subject: [PATCH 06/61] chore(deps): bump github/codeql-action/upload-sarif (#32378) Bumps [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) from 4.37.0 to 4.37.1. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/99df26d4f13ea111d4ec1a7dddef6063f76b97e9...7188fc363630916deb702c7fdcf4e481b751f97a) --- updated-dependencies: - dependency-name: github/codeql-action/upload-sarif dependency-version: 4.37.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecards.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 343669859..3a8410ced 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -64,6 +64,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0 + uses: github/codeql-action/upload-sarif@7188fc363630916deb702c7fdcf4e481b751f97a # v4.37.1 with: sarif_file: results.sarif From 0563162dd95dcff0f7b1ac09e0c784ae21b72245 Mon Sep 17 00:00:00 2001 From: Terry Howe Date: Fri, 17 Jul 2026 05:51:11 -0600 Subject: [PATCH 07/61] chore(deps): bump github/codeql-action init and analyze to 4.37.1 Signed-off-by: Terry Howe --- .github/workflows/codeql-analysis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 52c045e85..b0a03b342 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -48,7 +48,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # pinv4.37.0 + uses: github/codeql-action/init@7188fc363630916deb702c7fdcf4e481b751f97a # pinv4.37.1 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -73,4 +73,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # pinv4.37.0 + uses: github/codeql-action/analyze@7188fc363630916deb702c7fdcf4e481b751f97a # pinv4.37.1 From a2b1a60d51223254bd9c2f08cf3f411eb9d9fc58 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Sat, 18 Jul 2026 13:28:03 +0200 Subject: [PATCH 08/61] fix: enhance error handling and improve test assertions (#32352) Signed-off-by: Matthieu MOREL --- .golangci.yml | 4 +-- .../chart/v3/lint/rules/deprecations_test.go | 8 ++---- internal/plugin/runtime_subprocess.go | 7 +++-- internal/sympath/walk.go | 9 +++--- pkg/chart/v2/lint/rules/deprecations_test.go | 13 +++++---- pkg/chart/v2/lint/rules/template_test.go | 10 ++++--- pkg/chart/v2/util/dependencies_test.go | 10 +++---- pkg/cmd/plugin_test.go | 28 ++++++------------- pkg/kube/client.go | 7 +++-- pkg/provenance/sign_test.go | 8 ++---- pkg/registry/transport.go | 3 +- pkg/repo/v1/index.go | 4 +-- pkg/strvals/parser.go | 22 +++++++-------- 13 files changed, 63 insertions(+), 70 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 6727d3001..5b6d7cf8e 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -74,9 +74,9 @@ linters: errorlint: # Check for plain type assertions and type switches. - asserts: false + asserts: true # Check for plain error comparisons. - comparison: false + comparison: true exhaustive: default-signifies-exhaustive: true diff --git a/internal/chart/v3/lint/rules/deprecations_test.go b/internal/chart/v3/lint/rules/deprecations_test.go index a255abf50..55c454118 100644 --- a/internal/chart/v3/lint/rules/deprecations_test.go +++ b/internal/chart/v3/lint/rules/deprecations_test.go @@ -29,14 +29,12 @@ func TestValidateNoDeprecations(t *testing.T) { Kind: "Deployment", } err := validateNoDeprecations(deprecated, nil) - var depErr deprecatedAPIError require.Error(t, err, "Expected deprecated extension to be flagged") + var depErr deprecatedAPIError require.ErrorAs(t, err, &depErr, "Expected error to be of type deprecatedAPIError") require.NotEmpty(t, depErr.Message, "Expected error message to be non-blank: %v", err) - - err = validateNoDeprecations(&k8sYamlStruct{ + assert.NoError(t, validateNoDeprecations(&k8sYamlStruct{ APIVersion: "v1", Kind: "Pod", - }, nil) - assert.NoError(t, err, "Expected a v1 Pod to not be deprecated") + }, nil), "Expected a v1 Pod to not be deprecated") } diff --git a/internal/plugin/runtime_subprocess.go b/internal/plugin/runtime_subprocess.go index b921587c1..2dbe220d9 100644 --- a/internal/plugin/runtime_subprocess.go +++ b/internal/plugin/runtime_subprocess.go @@ -18,6 +18,7 @@ package plugin import ( "bytes" "context" + "errors" "fmt" "io" "log/slog" @@ -152,7 +153,8 @@ func (r *SubprocessPluginRuntime) InvokeHook(event string) error { slog.Debug("executing plugin hook command", slog.String("pluginName", r.metadata.Name), slog.String("command", cmd.String())) if err := cmd.Run(); err != nil { - if eerr, ok := err.(*exec.ExitError); ok { + var eerr *exec.ExitError + if errors.As(err, &eerr) { os.Stderr.Write(eerr.Stderr) return fmt.Errorf("plugin %s hook for %q exited with error", event, r.metadata.Name) } @@ -166,7 +168,8 @@ func (r *SubprocessPluginRuntime) InvokeHook(event string) error { // then replace the other three with a call to this func func executeCmd(prog *exec.Cmd, pluginName string) error { if err := prog.Run(); err != nil { - if eerr, ok := err.(*exec.ExitError); ok { + var eerr *exec.ExitError + if errors.As(err, &eerr) { slog.Debug( "plugin execution failed", slog.String("pluginName", pluginName), diff --git a/internal/sympath/walk.go b/internal/sympath/walk.go index 812bb68ce..b54b97ad4 100644 --- a/internal/sympath/walk.go +++ b/internal/sympath/walk.go @@ -21,6 +21,7 @@ limitations under the License. package sympath import ( + "errors" "fmt" "log/slog" "os" @@ -40,7 +41,7 @@ func Walk(root string, walkFn filepath.WalkFunc) error { } else { err = symwalk(root, info, walkFn) } - if err == filepath.SkipDir { + if errors.Is(err, filepath.SkipDir) { return nil } return err @@ -75,7 +76,7 @@ func symwalk(path string, info os.FileInfo, walkFn filepath.WalkFunc) error { if info, err = os.Lstat(resolved); err != nil { return err } - if err := symwalk(path, info, walkFn); err != nil && err != filepath.SkipDir { + if err := symwalk(path, info, walkFn); err != nil && !errors.Is(err, filepath.SkipDir) { return err } return nil @@ -98,13 +99,13 @@ func symwalk(path string, info os.FileInfo, walkFn filepath.WalkFunc) error { filename := filepath.Join(path, name) fileInfo, err := os.Lstat(filename) if err != nil { - if err := walkFn(filename, fileInfo, err); err != nil && err != filepath.SkipDir { + if err := walkFn(filename, fileInfo, err); err != nil && !errors.Is(err, filepath.SkipDir) { return err } } else { err = symwalk(filename, fileInfo, walkFn) if err != nil { - if (!fileInfo.IsDir() && !IsSymlink(fileInfo)) || err != filepath.SkipDir { + if (!fileInfo.IsDir() && !IsSymlink(fileInfo)) || !errors.Is(err, filepath.SkipDir) { return err } } diff --git a/pkg/chart/v2/lint/rules/deprecations_test.go b/pkg/chart/v2/lint/rules/deprecations_test.go index 86643f1c9..fdeb47e91 100644 --- a/pkg/chart/v2/lint/rules/deprecations_test.go +++ b/pkg/chart/v2/lint/rules/deprecations_test.go @@ -16,7 +16,11 @@ limitations under the License. package rules // import "helm.sh/helm/v4/pkg/chart/v2/lint/rules" -import "testing" +import ( + "testing" + + "github.com/stretchr/testify/require" +) func TestValidateNoDeprecations(t *testing.T) { deprecated := &k8sYamlStruct{ @@ -27,10 +31,9 @@ func TestValidateNoDeprecations(t *testing.T) { if err == nil { t.Fatal("Expected deprecated extension to be flagged") } - depErr := err.(deprecatedAPIError) - if depErr.Message == "" { - t.Fatalf("Expected error message to be non-blank: %v", err) - } + var depErr deprecatedAPIError + require.ErrorAs(t, err, &depErr) + require.NotEmptyf(t, depErr.Message, "Expected error message to be non-blank") if err := validateNoDeprecations(&k8sYamlStruct{ APIVersion: "v1", diff --git a/pkg/chart/v2/lint/rules/template_test.go b/pkg/chart/v2/lint/rules/template_test.go index f0eb008b3..12eec7531 100644 --- a/pkg/chart/v2/lint/rules/template_test.go +++ b/pkg/chart/v2/lint/rules/template_test.go @@ -24,6 +24,9 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "helm.sh/helm/v4/pkg/chart/common" chart "helm.sh/helm/v4/pkg/chart/v2" "helm.sh/helm/v4/pkg/chart/v2/lint/support" @@ -235,10 +238,9 @@ func TestDeprecatedAPIFails(t *testing.T) { t.Fatalf("Expected 1 lint error, got %d", l) } - err := linter.Messages[0].Err.(deprecatedAPIError) - if err.Deprecated != "apps/v1beta1 Deployment" { - t.Errorf("Surprised to learn that %q is deprecated", err.Deprecated) - } + var depErr deprecatedAPIError + require.ErrorAs(t, linter.Messages[0].Err, &depErr) + assert.Equalf(t, "apps/v1beta1 Deployment", depErr.Deprecated, "Surprised to learn that %q is deprecated", depErr.Deprecated) } const manifest = `apiVersion: v1 diff --git a/pkg/chart/v2/util/dependencies_test.go b/pkg/chart/v2/util/dependencies_test.go index 90a8806ec..40a17ac3a 100644 --- a/pkg/chart/v2/util/dependencies_test.go +++ b/pkg/chart/v2/util/dependencies_test.go @@ -21,6 +21,8 @@ import ( "strconv" "testing" + "github.com/stretchr/testify/require" + "helm.sh/helm/v4/pkg/chart/common" chart "helm.sh/helm/v4/pkg/chart/v2" "helm.sh/helm/v4/pkg/chart/v2/loader" @@ -251,12 +253,8 @@ func TestProcessDependencyImportValues(t *testing.T) { if err == nil { t.Error("expect nil value not found but found it") } - switch xerr := err.(type) { - case common.ErrNoValue: - // We found what we expected - default: - t.Errorf("expected an ErrNoValue but got %q instead", xerr) - } + var xerr common.ErrNoValue + require.ErrorAs(t, err, &xerr, "expected an ErrNoValue") c = loadChart(t, "testdata/subpop") if err := processDependencyImportValues(c, true); err != nil { diff --git a/pkg/cmd/plugin_test.go b/pkg/cmd/plugin_test.go index 476997110..5364423a0 100644 --- a/pkg/cmd/plugin_test.go +++ b/pkg/cmd/plugin_test.go @@ -144,16 +144,10 @@ func TestLoadCLIPlugins(t *testing.T) { // tests until this is fixed if runtime.GOOS != "windows" { if err := pluginCmd.RunE(pluginCmd, tt.args); err != nil { - if tt.code > 0 { - cerr, ok := err.(CommandError) - if !ok { - t.Errorf("Expected %s to return pluginError: got %v(%T)", tt.use, err, err) - } - if cerr.ExitCode != tt.code { - t.Errorf("Expected %s to return %d: got %d", tt.use, tt.code, cerr.ExitCode) - } - } else { - t.Errorf("Error running %s: %+v", tt.use, err) + if assert.Positive(t, tt.code, "Error running %s: %+v", tt.use, err) { + var cerr CommandError + require.ErrorAs(t, err, &cerr, "Expected %s to return pluginError: got %v(%T)", tt.use, err, err) + assert.Equalf(t, tt.code, cerr.ExitCode, "Expected %s to return %d: got %d", tt.use, tt.code, cerr.ExitCode) } } assert.Equal(t, tt.expect, out.String(), "expected output for %q", tt.use) @@ -218,16 +212,10 @@ func TestLoadPluginsWithSpace(t *testing.T) { // tests until this is fixed if runtime.GOOS != "windows" { if err := pp.RunE(pp, tt.args); err != nil { - if tt.code > 0 { - cerr, ok := err.(CommandError) - if !ok { - t.Errorf("Expected %s to return pluginError: got %v(%T)", tt.use, err, err) - } - if cerr.ExitCode != tt.code { - t.Errorf("Expected %s to return %d: got %d", tt.use, tt.code, cerr.ExitCode) - } - } else { - t.Errorf("Error running %s: %+v", tt.use, err) + if assert.Positive(t, tt.code, "Error running %s: %+v", tt.use, err) { + var cerr CommandError + require.ErrorAs(t, err, &cerr, "Expected %s to return pluginError: got %v(%T)", tt.use, err, err) + assert.Equalf(t, tt.code, cerr.ExitCode, "Expected %s to return %d: got %d", tt.use, tt.code, cerr.ExitCode) } } assert.Equal(t, tt.expect, out.String(), "expected output for %s", tt.use) diff --git a/pkg/kube/client.go b/pkg/kube/client.go index e363fad61..1dfa88800 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -249,7 +249,7 @@ func (c *Client) getKubeClient() (kubernetes.Interface, error) { // IsReachable tests connectivity to the cluster. func (c *Client) IsReachable() error { client, err := c.getKubeClient() - if err == genericclioptions.ErrEmptyConfig { + if errors.Is(err, genericclioptions.ErrEmptyConfig) { // re-replace kubernetes ErrEmptyConfig error with a friendly error // moar workarounds for Kubernetes API breaking. return errors.New("kubernetes cluster unreachable") @@ -949,11 +949,12 @@ func (c *Client) Delete(resources ResourceList, policy metav1.DeletionPropagatio func isIncompatibleServerError(err error) bool { // 415: Unsupported media type means we're talking to a server which doesn't // support server-side apply. - if _, ok := err.(*apierrors.StatusError); !ok { + var sErr *apierrors.StatusError + if !errors.As(err, &sErr) { // Non-StatusError means the error isn't because the server is incompatible. return false } - return err.(*apierrors.StatusError).Status().Code == http.StatusUnsupportedMediaType + return sErr.Status().Code == http.StatusUnsupportedMediaType } // isServerSideRetryable checks if an error encountered during server-side apply diff --git a/pkg/provenance/sign_test.go b/pkg/provenance/sign_test.go index 3f8e654f9..79b33a970 100644 --- a/pkg/provenance/sign_test.go +++ b/pkg/provenance/sign_test.go @@ -385,11 +385,9 @@ func TestVerify(t *testing.T) { _, err = signer.Verify(archiveData, tamperedSigData, filepath.Base(testChartfile)) require.Errorf(t, err, "Expected %s to fail.", testTamperedSigBlock) - switch err.(type) { - case pgperrors.SignatureError: - t.Logf("Tampered sig block error: %s (%T)", err, err) - default: - t.Errorf("Expected invalid signature error, got %q (%T)", err, err) + var sErr pgperrors.SignatureError + if assert.ErrorAs(t, err, &sErr, "Expected invalid signature error, got %q (%T)", err, err) { + t.Logf("Tampered sig block error: %s (%T)", sErr, sErr) } } diff --git a/pkg/registry/transport.go b/pkg/registry/transport.go index beec43cdd..fa0103ac0 100644 --- a/pkg/registry/transport.go +++ b/pkg/registry/transport.go @@ -18,6 +18,7 @@ package registry import ( "bytes" + "errors" "fmt" "io" "log/slog" @@ -126,7 +127,7 @@ func logResponseBody(resp *http.Response) string { Closer: body, } // read the body up to limit+1 to check if the body exceeds the limit - if _, err := io.CopyN(buf, body, payloadSizeLimit+1); err != nil && err != io.EOF { + if _, err := io.CopyN(buf, body, payloadSizeLimit+1); err != nil && !errors.Is(err, io.EOF) { return fmt.Sprintf(" Error reading response body: %v", err) } diff --git a/pkg/repo/v1/index.go b/pkg/repo/v1/index.go index 839a4cca9..1c1497c5e 100644 --- a/pkg/repo/v1/index.go +++ b/pkg/repo/v1/index.go @@ -421,8 +421,8 @@ func jsonOrYamlUnmarshal(b []byte, i any) error { // And repository indexes may be generated by older/non-compliant software, which doesn't // conform to all validations. func ignoreSkippableChartValidationError(err error) error { - verr, ok := err.(chart.ValidationError) - if !ok { + var verr chart.ValidationError + if !errors.As(err, &verr) { return err } diff --git a/pkg/strvals/parser.go b/pkg/strvals/parser.go index d74e46986..be3b1e71b 100644 --- a/pkg/strvals/parser.go +++ b/pkg/strvals/parser.go @@ -238,16 +238,16 @@ func (t *parser) key(data map[string]any, nestedNameLevel int) (reterr error) { // End of key. Consume =, Get value. // FIXME: Get value list first vl, e := t.valList() - switch e { - case nil: + switch { + case e == nil: set(data, string(k), vl) return nil - case io.EOF: + case errors.Is(e, io.EOF): set(data, string(k), "") return e - case ErrNotList: + case errors.Is(e, ErrNotList): rs, e := t.val() - if e != nil && e != io.EOF { + if e != nil && !errors.Is(e, io.EOF) { return e } v, e := t.reader(rs) @@ -370,14 +370,14 @@ func (t *parser) listItem(list []any, i, nestedNameLevel int) ([]any, error) { return list, err } vl, e := t.valList() - switch e { - case nil: + switch { + case e == nil: return setIndex(list, i, vl) - case io.EOF: + case errors.Is(e, io.EOF): return setIndex(list, i, "") - case ErrNotList: + case errors.Is(e, ErrNotList): rs, e := t.val() - if e != nil && e != io.EOF { + if e != nil && !errors.Is(e, io.EOF) { return list, e } v, e := t.reader(rs) @@ -476,7 +476,7 @@ func (t *parser) valList() ([]any, error) { for { switch rs, last, err := runesUntil(t.sc, stop); { case err != nil: - if err == io.EOF { + if errors.Is(err, io.EOF) { err = errors.New("list must terminate with '}'") } return list, err From c2fda5ac5835cd1eca44a29047c18edcde66e00f Mon Sep 17 00:00:00 2001 From: Terry Howe Date: Sat, 18 Jul 2026 05:33:34 -0600 Subject: [PATCH 09/61] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Terry Howe --- pkg/cli/environment_test.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pkg/cli/environment_test.go b/pkg/cli/environment_test.go index 2d7851a4f..fc71038f8 100644 --- a/pkg/cli/environment_test.go +++ b/pkg/cli/environment_test.go @@ -242,9 +242,7 @@ users: user: token: test-token ` - if err := os.WriteFile(kubeconfigPath, []byte(kubeconfig), 0o600); err != nil { - t.Fatalf("failed to create test kubeconfig: %v", err) - } + require.NoError(t, os.WriteFile(kubeconfigPath, []byte(kubeconfig), 0o600), "failed to create test kubeconfig") t.Setenv("KUBECONFIG", kubeconfigPath) settings := New() From 82be04d7f2881f59b3a85483eb248417e1d18fc3 Mon Sep 17 00:00:00 2001 From: Abhay Chaurasiya <44005156+abhay1999@users.noreply.github.com> Date: Sat, 18 Jul 2026 17:12:20 +0530 Subject: [PATCH 10/61] remove legacy import comments from remaining packages (#31933) Pre-Go-modules import path comments (e.g. `// import "helm.sh/helm/v4/..."`) are obsolete since Go 1.11 where go.mod is the authoritative module path. These stale comments cause issues with downstream tooling such as Kythe. Removes the legacy import comments from 64 files across 20 packages: - cmd/helm - internal/chart/v3/lint and sub-packages - internal/plugin and sub-packages - internal/release/v2/util - pkg/chart/v2/lint and sub-packages - pkg/cmd, pkg/engine, pkg/ignore, pkg/provenance - pkg/registry - pkg/release/v1/util - pkg/repo/v1 - pkg/storage and pkg/storage/driver Follows up on #31931 and #31932 which addressed pkg/kube. Fixes #31846 Signed-off-by: abhay1999 Signed-off-by: abhay1999 --- cmd/helm/helm.go | 2 +- internal/chart/v3/lint/lint.go | 2 +- internal/chart/v3/lint/rules/chartfile.go | 2 +- internal/chart/v3/lint/rules/dependencies.go | 2 +- internal/chart/v3/lint/rules/deprecations.go | 2 +- internal/chart/v3/lint/rules/deprecations_test.go | 2 +- internal/chart/v3/lint/support/doc.go | 2 +- internal/plugin/cache/cache.go | 2 +- internal/plugin/installer/base.go | 2 +- internal/plugin/installer/base_test.go | 2 +- internal/plugin/installer/doc.go | 2 +- internal/plugin/installer/extractor.go | 2 +- internal/plugin/installer/http_installer.go | 2 +- internal/plugin/installer/http_installer_test.go | 2 +- internal/plugin/installer/local_installer.go | 2 +- internal/plugin/installer/local_installer_test.go | 2 +- internal/plugin/installer/oci_installer_test.go | 2 +- internal/plugin/installer/vcs_installer.go | 2 +- internal/plugin/installer/vcs_installer_test.go | 2 +- internal/plugin/plugin.go | 2 +- internal/plugin/runtime_subprocess_hooks.go | 2 +- internal/release/v2/util/filter.go | 2 +- internal/release/v2/util/filter_test.go | 2 +- internal/release/v2/util/kind_sorter.go | 2 +- internal/release/v2/util/kind_sorter_test.go | 2 +- internal/release/v2/util/manifest.go | 2 +- internal/release/v2/util/manifest_sorter.go | 2 +- internal/release/v2/util/manifest_sorter_test.go | 2 +- internal/release/v2/util/manifest_test.go | 2 +- internal/release/v2/util/sorter.go | 2 +- internal/release/v2/util/sorter_test.go | 2 +- pkg/chart/v2/lint/lint.go | 2 +- pkg/chart/v2/lint/rules/chartfile.go | 2 +- pkg/chart/v2/lint/rules/dependencies.go | 2 +- pkg/chart/v2/lint/rules/deprecations.go | 2 +- pkg/chart/v2/lint/rules/deprecations_test.go | 2 +- pkg/chart/v2/lint/support/doc.go | 2 +- pkg/cmd/root.go | 2 +- pkg/engine/doc.go | 2 +- pkg/ignore/doc.go | 2 +- pkg/provenance/doc.go | 2 +- pkg/registry/chart.go | 2 +- pkg/registry/chart_test.go | 2 +- pkg/registry/client.go | 2 +- pkg/registry/constants.go | 2 +- pkg/registry/tag.go | 2 +- pkg/release/v1/util/filter.go | 2 +- pkg/release/v1/util/filter_test.go | 2 +- pkg/release/v1/util/manifest_test.go | 2 +- pkg/release/v1/util/sorter.go | 2 +- pkg/release/v1/util/sorter_test.go | 2 +- pkg/repo/v1/chartrepo.go | 2 +- pkg/repo/v1/repo.go | 2 +- pkg/storage/driver/cfgmaps.go | 2 +- pkg/storage/driver/driver.go | 2 +- pkg/storage/driver/labels_test.go | 2 +- pkg/storage/driver/mock_test.go | 2 +- pkg/storage/driver/records.go | 2 +- pkg/storage/driver/records_test.go | 2 +- pkg/storage/driver/secrets.go | 2 +- pkg/storage/driver/sql.go | 2 +- pkg/storage/driver/util.go | 2 +- pkg/storage/storage.go | 2 +- pkg/storage/storage_test.go | 2 +- 64 files changed, 64 insertions(+), 64 deletions(-) diff --git a/cmd/helm/helm.go b/cmd/helm/helm.go index 0c4f697b6..60df8a308 100644 --- a/cmd/helm/helm.go +++ b/cmd/helm/helm.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package main // import "helm.sh/helm/v4/cmd/helm" +package main import ( "errors" diff --git a/internal/chart/v3/lint/lint.go b/internal/chart/v3/lint/lint.go index ea8ca3d60..193f0f796 100644 --- a/internal/chart/v3/lint/lint.go +++ b/internal/chart/v3/lint/lint.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package lint // import "helm.sh/helm/v4/internal/chart/v3/lint" +package lint import ( "path/filepath" diff --git a/internal/chart/v3/lint/rules/chartfile.go b/internal/chart/v3/lint/rules/chartfile.go index db7ac61dc..c76654d53 100644 --- a/internal/chart/v3/lint/rules/chartfile.go +++ b/internal/chart/v3/lint/rules/chartfile.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package rules // import "helm.sh/helm/v4/internal/chart/v3/lint/rules" +package rules import ( "errors" diff --git a/internal/chart/v3/lint/rules/dependencies.go b/internal/chart/v3/lint/rules/dependencies.go index f45153728..2f558aaf0 100644 --- a/internal/chart/v3/lint/rules/dependencies.go +++ b/internal/chart/v3/lint/rules/dependencies.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package rules // import "helm.sh/helm/v4/internal/chart/v3/lint/rules" +package rules import ( "fmt" diff --git a/internal/chart/v3/lint/rules/deprecations.go b/internal/chart/v3/lint/rules/deprecations.go index 9c73268af..85dddd114 100644 --- a/internal/chart/v3/lint/rules/deprecations.go +++ b/internal/chart/v3/lint/rules/deprecations.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package rules // import "helm.sh/helm/v4/internal/chart/v3/lint/rules" +package rules import ( "fmt" diff --git a/internal/chart/v3/lint/rules/deprecations_test.go b/internal/chart/v3/lint/rules/deprecations_test.go index 55c454118..920fdc31f 100644 --- a/internal/chart/v3/lint/rules/deprecations_test.go +++ b/internal/chart/v3/lint/rules/deprecations_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package rules // import "helm.sh/helm/v4/internal/chart/v3/lint/rules" +package rules import ( "testing" diff --git a/internal/chart/v3/lint/support/doc.go b/internal/chart/v3/lint/support/doc.go index 2d54a9b7d..80b1d2169 100644 --- a/internal/chart/v3/lint/support/doc.go +++ b/internal/chart/v3/lint/support/doc.go @@ -20,4 +20,4 @@ Package support contains tools for linting charts. Linting is the process of testing charts for errors or warnings regarding formatting, compilation, or standards compliance. */ -package support // import "helm.sh/helm/v4/internal/chart/v3/lint/support" +package support diff --git a/internal/plugin/cache/cache.go b/internal/plugin/cache/cache.go index f3b737477..1613d4d76 100644 --- a/internal/plugin/cache/cache.go +++ b/internal/plugin/cache/cache.go @@ -14,7 +14,7 @@ limitations under the License. */ // Package cache provides a key generator for vcs urls. -package cache // import "helm.sh/helm/v4/internal/plugin/cache" +package cache import ( "net/url" diff --git a/internal/plugin/installer/base.go b/internal/plugin/installer/base.go index c21a245a8..54d25287a 100644 --- a/internal/plugin/installer/base.go +++ b/internal/plugin/installer/base.go @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package installer // import "helm.sh/helm/v4/internal/plugin/installer" +package installer import ( "path/filepath" diff --git a/internal/plugin/installer/base_test.go b/internal/plugin/installer/base_test.go index 6df8ec8a1..b7902e699 100644 --- a/internal/plugin/installer/base_test.go +++ b/internal/plugin/installer/base_test.go @@ -11,7 +11,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package installer // import "helm.sh/helm/v4/internal/plugin/installer" +package installer import ( "testing" diff --git a/internal/plugin/installer/doc.go b/internal/plugin/installer/doc.go index a4cf384bf..a9d9555c9 100644 --- a/internal/plugin/installer/doc.go +++ b/internal/plugin/installer/doc.go @@ -14,4 +14,4 @@ limitations under the License. */ // Package installer provides an interface for installing Helm plugins. -package installer // import "helm.sh/helm/v4/internal/plugin/installer" +package installer diff --git a/internal/plugin/installer/extractor.go b/internal/plugin/installer/extractor.go index 85d695bd2..6cd45e2d8 100644 --- a/internal/plugin/installer/extractor.go +++ b/internal/plugin/installer/extractor.go @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package installer // import "helm.sh/helm/v4/internal/plugin/installer" +package installer import ( "archive/tar" diff --git a/internal/plugin/installer/http_installer.go b/internal/plugin/installer/http_installer.go index 92d3d686e..7be326de2 100644 --- a/internal/plugin/installer/http_installer.go +++ b/internal/plugin/installer/http_installer.go @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package installer // import "helm.sh/helm/v4/internal/plugin/installer" +package installer import ( "bytes" diff --git a/internal/plugin/installer/http_installer_test.go b/internal/plugin/installer/http_installer_test.go index cbd868f3a..3235e9796 100644 --- a/internal/plugin/installer/http_installer_test.go +++ b/internal/plugin/installer/http_installer_test.go @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package installer // import "helm.sh/helm/v4/internal/plugin/installer" +package installer import ( "archive/tar" diff --git a/internal/plugin/installer/local_installer.go b/internal/plugin/installer/local_installer.go index a7a6caa14..59918401b 100644 --- a/internal/plugin/installer/local_installer.go +++ b/internal/plugin/installer/local_installer.go @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package installer // import "helm.sh/helm/v4/internal/plugin/installer" +package installer import ( "bytes" diff --git a/internal/plugin/installer/local_installer_test.go b/internal/plugin/installer/local_installer_test.go index 02d4d7bff..f46fcb44b 100644 --- a/internal/plugin/installer/local_installer_test.go +++ b/internal/plugin/installer/local_installer_test.go @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package installer // import "helm.sh/helm/v4/internal/plugin/installer" +package installer import ( "archive/tar" diff --git a/internal/plugin/installer/oci_installer_test.go b/internal/plugin/installer/oci_installer_test.go index c3bebdb52..48eccf6e1 100644 --- a/internal/plugin/installer/oci_installer_test.go +++ b/internal/plugin/installer/oci_installer_test.go @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package installer // import "helm.sh/helm/v4/internal/plugin/installer" +package installer import ( "archive/tar" diff --git a/internal/plugin/installer/vcs_installer.go b/internal/plugin/installer/vcs_installer.go index 3601ec7a8..13aba74dc 100644 --- a/internal/plugin/installer/vcs_installer.go +++ b/internal/plugin/installer/vcs_installer.go @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package installer // import "helm.sh/helm/v4/internal/plugin/installer" +package installer import ( "errors" diff --git a/internal/plugin/installer/vcs_installer_test.go b/internal/plugin/installer/vcs_installer_test.go index 401f2b921..7e44cc957 100644 --- a/internal/plugin/installer/vcs_installer_test.go +++ b/internal/plugin/installer/vcs_installer_test.go @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package installer // import "helm.sh/helm/v4/internal/plugin/installer" +package installer import ( "fmt" diff --git a/internal/plugin/plugin.go b/internal/plugin/plugin.go index 789e583ae..ad2dd7922 100644 --- a/internal/plugin/plugin.go +++ b/internal/plugin/plugin.go @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package plugin // import "helm.sh/helm/v4/internal/plugin" +package plugin import ( "context" diff --git a/internal/plugin/runtime_subprocess_hooks.go b/internal/plugin/runtime_subprocess_hooks.go index 7b4ff5a38..8d5f3cba6 100644 --- a/internal/plugin/runtime_subprocess_hooks.go +++ b/internal/plugin/runtime_subprocess_hooks.go @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package plugin // import "helm.sh/helm/v4/internal/plugin" +package plugin // Types of hooks const ( diff --git a/internal/release/v2/util/filter.go b/internal/release/v2/util/filter.go index bc568cbdc..0daf06014 100644 --- a/internal/release/v2/util/filter.go +++ b/internal/release/v2/util/filter.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package util // import "helm.sh/helm/v4/internal/release/v2/util" +package util import ( v2 "helm.sh/helm/v4/internal/release/v2" diff --git a/internal/release/v2/util/filter_test.go b/internal/release/v2/util/filter_test.go index 8c7363b87..542510ba3 100644 --- a/internal/release/v2/util/filter_test.go +++ b/internal/release/v2/util/filter_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package util // import "helm.sh/helm/v4/internal/release/v2/util" +package util import ( "testing" diff --git a/internal/release/v2/util/kind_sorter.go b/internal/release/v2/util/kind_sorter.go index dba35b6d2..950e836fa 100644 --- a/internal/release/v2/util/kind_sorter.go +++ b/internal/release/v2/util/kind_sorter.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package util // import "helm.sh/helm/v4/internal/release/v2/util" +package util import ( "sort" diff --git a/internal/release/v2/util/kind_sorter_test.go b/internal/release/v2/util/kind_sorter_test.go index dba19e287..06885aa93 100644 --- a/internal/release/v2/util/kind_sorter_test.go +++ b/internal/release/v2/util/kind_sorter_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package util // import "helm.sh/helm/v4/internal/release/v2/util" +package util import ( "bytes" diff --git a/internal/release/v2/util/manifest.go b/internal/release/v2/util/manifest.go index d3296984e..37b9dfbd3 100644 --- a/internal/release/v2/util/manifest.go +++ b/internal/release/v2/util/manifest.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package util // import "helm.sh/helm/v4/internal/release/v2/util" +package util import ( "fmt" diff --git a/internal/release/v2/util/manifest_sorter.go b/internal/release/v2/util/manifest_sorter.go index f269dda6d..3507deed5 100644 --- a/internal/release/v2/util/manifest_sorter.go +++ b/internal/release/v2/util/manifest_sorter.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package util // import "helm.sh/helm/v4/internal/release/v2/util" +package util import ( "fmt" diff --git a/internal/release/v2/util/manifest_sorter_test.go b/internal/release/v2/util/manifest_sorter_test.go index eac9c9f36..deb9426ce 100644 --- a/internal/release/v2/util/manifest_sorter_test.go +++ b/internal/release/v2/util/manifest_sorter_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package util // import "helm.sh/helm/v4/internal/release/v2/util" +package util import ( "testing" diff --git a/internal/release/v2/util/manifest_test.go b/internal/release/v2/util/manifest_test.go index 1806368af..e76905a63 100644 --- a/internal/release/v2/util/manifest_test.go +++ b/internal/release/v2/util/manifest_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package util // import "helm.sh/helm/v4/internal/release/v2/util" +package util import ( "testing" diff --git a/internal/release/v2/util/sorter.go b/internal/release/v2/util/sorter.go index 5f13569c1..66b51d873 100644 --- a/internal/release/v2/util/sorter.go +++ b/internal/release/v2/util/sorter.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package util // import "helm.sh/helm/v4/internal/release/v2/util" +package util import ( "sort" diff --git a/internal/release/v2/util/sorter_test.go b/internal/release/v2/util/sorter_test.go index 82a53ae66..e151f0790 100644 --- a/internal/release/v2/util/sorter_test.go +++ b/internal/release/v2/util/sorter_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package util // import "helm.sh/helm/v4/internal/release/v2/util" +package util import ( "testing" diff --git a/pkg/chart/v2/lint/lint.go b/pkg/chart/v2/lint/lint.go index 23a93c551..204c15861 100644 --- a/pkg/chart/v2/lint/lint.go +++ b/pkg/chart/v2/lint/lint.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package lint // import "helm.sh/helm/v4/pkg/chart/v2/lint" +package lint import ( "path/filepath" diff --git a/pkg/chart/v2/lint/rules/chartfile.go b/pkg/chart/v2/lint/rules/chartfile.go index 08508f46e..f867daa21 100644 --- a/pkg/chart/v2/lint/rules/chartfile.go +++ b/pkg/chart/v2/lint/rules/chartfile.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package rules // import "helm.sh/helm/v4/pkg/chart/v2/lint/rules" +package rules import ( "errors" diff --git a/pkg/chart/v2/lint/rules/dependencies.go b/pkg/chart/v2/lint/rules/dependencies.go index d944a016d..616984c08 100644 --- a/pkg/chart/v2/lint/rules/dependencies.go +++ b/pkg/chart/v2/lint/rules/dependencies.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package rules // import "helm.sh/helm/v4/pkg/chart/v2/lint/rules" +package rules import ( "fmt" diff --git a/pkg/chart/v2/lint/rules/deprecations.go b/pkg/chart/v2/lint/rules/deprecations.go index 76626659b..2ed682891 100644 --- a/pkg/chart/v2/lint/rules/deprecations.go +++ b/pkg/chart/v2/lint/rules/deprecations.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package rules // import "helm.sh/helm/v4/pkg/chart/v2/lint/rules" +package rules import ( "fmt" diff --git a/pkg/chart/v2/lint/rules/deprecations_test.go b/pkg/chart/v2/lint/rules/deprecations_test.go index fdeb47e91..0aa983678 100644 --- a/pkg/chart/v2/lint/rules/deprecations_test.go +++ b/pkg/chart/v2/lint/rules/deprecations_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package rules // import "helm.sh/helm/v4/pkg/chart/v2/lint/rules" +package rules import ( "testing" diff --git a/pkg/chart/v2/lint/support/doc.go b/pkg/chart/v2/lint/support/doc.go index 7e050b8c2..80b1d2169 100644 --- a/pkg/chart/v2/lint/support/doc.go +++ b/pkg/chart/v2/lint/support/doc.go @@ -20,4 +20,4 @@ Package support contains tools for linting charts. Linting is the process of testing charts for errors or warnings regarding formatting, compilation, or standards compliance. */ -package support // import "helm.sh/helm/v4/pkg/chart/v2/lint/support" +package support diff --git a/pkg/cmd/root.go b/pkg/cmd/root.go index 28798de5c..410a9162c 100644 --- a/pkg/cmd/root.go +++ b/pkg/cmd/root.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package cmd // import "helm.sh/helm/v4/pkg/cmd" +package cmd import ( "context" diff --git a/pkg/engine/doc.go b/pkg/engine/doc.go index e764a829a..9bb1059f2 100644 --- a/pkg/engine/doc.go +++ b/pkg/engine/doc.go @@ -21,4 +21,4 @@ When Helm renders templates it does so with additional functions and different modes (e.g., strict, lint mode). This package handles the helm specific implementation. */ -package engine // import "helm.sh/helm/v4/pkg/engine" +package engine diff --git a/pkg/ignore/doc.go b/pkg/ignore/doc.go index a66066eb2..bba658d41 100644 --- a/pkg/ignore/doc.go +++ b/pkg/ignore/doc.go @@ -65,4 +65,4 @@ Notable differences from .gitignore: - The evaluation of escape sequences has not been tested for compatibility - There is no support for '\!' as a special leading sequence. */ -package ignore // import "helm.sh/helm/v4/pkg/ignore" +package ignore diff --git a/pkg/provenance/doc.go b/pkg/provenance/doc.go index dd14568d9..bd60bc593 100644 --- a/pkg/provenance/doc.go +++ b/pkg/provenance/doc.go @@ -35,4 +35,4 @@ and using `gpg --verify`, `keybase pgp verify`, or similar: gpg: Signature made Mon Jul 25 17:23:44 2016 MDT using RSA key ID 1FC18762 gpg: Good signature from "Helm Testing (This key should only be used for testing. DO NOT TRUST.) " [ultimate] */ -package provenance // import "helm.sh/helm/v4/pkg/provenance" +package provenance diff --git a/pkg/registry/chart.go b/pkg/registry/chart.go index 7c41785c5..b8b0d88b6 100644 --- a/pkg/registry/chart.go +++ b/pkg/registry/chart.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package registry // import "helm.sh/helm/v4/pkg/registry" +package registry import ( "bytes" diff --git a/pkg/registry/chart_test.go b/pkg/registry/chart_test.go index e27c3d619..c80544b5b 100644 --- a/pkg/registry/chart_test.go +++ b/pkg/registry/chart_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package registry // import "helm.sh/helm/v4/pkg/registry" +package registry import ( "testing" diff --git a/pkg/registry/client.go b/pkg/registry/client.go index cba346dea..d1a744f4b 100644 --- a/pkg/registry/client.go +++ b/pkg/registry/client.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package registry // import "helm.sh/helm/v4/pkg/registry" +package registry import ( "context" diff --git a/pkg/registry/constants.go b/pkg/registry/constants.go index c455cf314..df31a18c4 100644 --- a/pkg/registry/constants.go +++ b/pkg/registry/constants.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package registry // import "helm.sh/helm/v4/pkg/registry" +package registry const ( // OCIScheme is the URL scheme for OCI-based requests diff --git a/pkg/registry/tag.go b/pkg/registry/tag.go index bfb4b1ef6..7e15d0dd9 100644 --- a/pkg/registry/tag.go +++ b/pkg/registry/tag.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package registry // import "helm.sh/helm/v4/pkg/registry" +package registry import ( "fmt" diff --git a/pkg/release/v1/util/filter.go b/pkg/release/v1/util/filter.go index dc60195cf..88ac995d7 100644 --- a/pkg/release/v1/util/filter.go +++ b/pkg/release/v1/util/filter.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package util // import "helm.sh/helm/v4/pkg/release/v1/util" +package util import ( "helm.sh/helm/v4/pkg/release/common" diff --git a/pkg/release/v1/util/filter_test.go b/pkg/release/v1/util/filter_test.go index d6bda8f84..57d7e6801 100644 --- a/pkg/release/v1/util/filter_test.go +++ b/pkg/release/v1/util/filter_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package util // import "helm.sh/helm/v4/pkg/release/v1/util" +package util import ( "testing" diff --git a/pkg/release/v1/util/manifest_test.go b/pkg/release/v1/util/manifest_test.go index 773723c86..e76905a63 100644 --- a/pkg/release/v1/util/manifest_test.go +++ b/pkg/release/v1/util/manifest_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package util // import "helm.sh/helm/v4/pkg/release/v1/util" +package util import ( "testing" diff --git a/pkg/release/v1/util/sorter.go b/pkg/release/v1/util/sorter.go index 47506fbf2..e15b87593 100644 --- a/pkg/release/v1/util/sorter.go +++ b/pkg/release/v1/util/sorter.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package util // import "helm.sh/helm/v4/pkg/release/v1/util" +package util import ( "sort" diff --git a/pkg/release/v1/util/sorter_test.go b/pkg/release/v1/util/sorter_test.go index 0450b09e6..1a3bb3e6a 100644 --- a/pkg/release/v1/util/sorter_test.go +++ b/pkg/release/v1/util/sorter_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package util // import "helm.sh/helm/v4/pkg/release/v1/util" +package util import ( "testing" diff --git a/pkg/repo/v1/chartrepo.go b/pkg/repo/v1/chartrepo.go index c7c4a3e7b..42ed52f75 100644 --- a/pkg/repo/v1/chartrepo.go +++ b/pkg/repo/v1/chartrepo.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package repo // import "helm.sh/helm/v4/pkg/repo/v1" +package repo import ( "bytes" diff --git a/pkg/repo/v1/repo.go b/pkg/repo/v1/repo.go index 199b56ed8..be241a0ab 100644 --- a/pkg/repo/v1/repo.go +++ b/pkg/repo/v1/repo.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package repo // import "helm.sh/helm/v4/pkg/repo/v1" +package repo import ( "fmt" diff --git a/pkg/storage/driver/cfgmaps.go b/pkg/storage/driver/cfgmaps.go index 2636755a9..f71ce44f1 100644 --- a/pkg/storage/driver/cfgmaps.go +++ b/pkg/storage/driver/cfgmaps.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package driver // import "helm.sh/helm/v4/pkg/storage/driver" +package driver import ( "context" diff --git a/pkg/storage/driver/driver.go b/pkg/storage/driver/driver.go index 6efd1dbaa..a7d194d69 100644 --- a/pkg/storage/driver/driver.go +++ b/pkg/storage/driver/driver.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package driver // import "helm.sh/helm/v4/pkg/storage/driver" +package driver import ( "errors" diff --git a/pkg/storage/driver/labels_test.go b/pkg/storage/driver/labels_test.go index 81e561c15..848ae8861 100644 --- a/pkg/storage/driver/labels_test.go +++ b/pkg/storage/driver/labels_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package driver // import "helm.sh/helm/v4/pkg/storage/driver" +package driver import ( "testing" diff --git a/pkg/storage/driver/mock_test.go b/pkg/storage/driver/mock_test.go index e62b02f43..ab7b261cf 100644 --- a/pkg/storage/driver/mock_test.go +++ b/pkg/storage/driver/mock_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package driver // import "helm.sh/helm/v4/pkg/storage/driver" +package driver import ( "context" diff --git a/pkg/storage/driver/records.go b/pkg/storage/driver/records.go index 6b4efef3a..f78b76b8b 100644 --- a/pkg/storage/driver/records.go +++ b/pkg/storage/driver/records.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package driver // import "helm.sh/helm/v4/pkg/storage/driver" +package driver import ( "sort" diff --git a/pkg/storage/driver/records_test.go b/pkg/storage/driver/records_test.go index 24e4ccb4e..cd1064342 100644 --- a/pkg/storage/driver/records_test.go +++ b/pkg/storage/driver/records_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package driver // import "helm.sh/helm/v4/pkg/storage/driver" +package driver import ( "reflect" diff --git a/pkg/storage/driver/secrets.go b/pkg/storage/driver/secrets.go index 5e12684df..a1f3e94fc 100644 --- a/pkg/storage/driver/secrets.go +++ b/pkg/storage/driver/secrets.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package driver // import "helm.sh/helm/v4/pkg/storage/driver" +package driver import ( "context" diff --git a/pkg/storage/driver/sql.go b/pkg/storage/driver/sql.go index 88d24123d..85e6cbd3f 100644 --- a/pkg/storage/driver/sql.go +++ b/pkg/storage/driver/sql.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package driver // import "helm.sh/helm/v4/pkg/storage/driver" +package driver import ( "fmt" diff --git a/pkg/storage/driver/util.go b/pkg/storage/driver/util.go index 4bc48db23..08c38585c 100644 --- a/pkg/storage/driver/util.go +++ b/pkg/storage/driver/util.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package driver // import "helm.sh/helm/v4/pkg/storage/driver" +package driver import ( "bytes" diff --git a/pkg/storage/storage.go b/pkg/storage/storage.go index d5d2ea317..1d7fb9103 100644 --- a/pkg/storage/storage.go +++ b/pkg/storage/storage.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package storage // import "helm.sh/helm/v4/pkg/storage" +package storage import ( "errors" diff --git a/pkg/storage/storage_test.go b/pkg/storage/storage_test.go index 32f926e08..8ecee447f 100644 --- a/pkg/storage/storage_test.go +++ b/pkg/storage/storage_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package storage // import "helm.sh/helm/v4/pkg/storage" +package storage import ( "context" From 3bcf965f997499c477436515e6ccf5d51ab82e5e Mon Sep 17 00:00:00 2001 From: Zhaofeng Miao <522856232@qq.com> Date: Sat, 18 Jul 2026 21:10:36 +0800 Subject: [PATCH 11/61] perf: enable concurrent status computation to prevent multi-minute delays (#32043) * fix: enable concurrent status computation to prevent multi-minute delays Set StatusComputeWorkers=8 on DefaultStatusWatcher for Wait, WaitWithJobs, and WatchUntilReady. This opts in to the async status computation added in fluxcd/cli-utils#20, preventing the informer notification pipeline from being blocked by slow API calls when many resources are updated simultaneously. Without this, status computation for resources like Deployments (which require additional LIST ReplicaSets/Pods calls) runs serially inside the informer, causing growing delays of 1-3+ minutes when upgrading many resources at once (e.g., ~20 Deployments via Helm). Signed-off-by: maplemiao * refactor(kube): expose StatusComputeWorkers as a WaitOption Replace the package-level DefaultStatusComputeWorkers variable with a WithStatusComputeWorkers WaitOption threaded through waitOptions into the statusWaiter. This removes global mutable state from pkg/kube and lets callers opt in explicitly. SDK consumers (e.g. helm-controller) inherit the zero value, which preserves the upstream cli-utils synchronous behavior and avoids an unexpected fan-out of status-compute goroutines when many releases reconcile concurrently. The Helm CLI continues to enable 8 workers by default via a shared pkg/cmd/flags.go helper, so install/upgrade/ rollback/uninstall/test users still get the fix for multi-minute informer stalls out of the box. Signed-off-by: maplemiao * refactor(kube): clamp negative StatusComputeWorkers values to zero Address review feedback: when a caller passes a negative value to WithStatusComputeWorkers, coerce it to zero rather than propagating it to the underlying cli-utils watcher, where the behavior is undefined. Zero is the safe default and matches the SDK opt-in contract. Signed-off-by: maplemiao --------- Signed-off-by: maplemiao Signed-off-by: Maple Miao Co-authored-by: Cursor --- pkg/cmd/flags.go | 20 ++++++++++++++++++++ pkg/cmd/install.go | 1 + pkg/cmd/release_testing.go | 1 + pkg/cmd/rollback.go | 1 + pkg/cmd/uninstall.go | 1 + pkg/cmd/upgrade.go | 2 ++ pkg/kube/client.go | 17 +++++++++-------- pkg/kube/options.go | 35 +++++++++++++++++++++++++++++------ pkg/kube/statuswait.go | 20 ++++++++++++-------- pkg/kube/statuswait_test.go | 22 ++++++++++++++++++++++ 10 files changed, 98 insertions(+), 22 deletions(-) diff --git a/pkg/cmd/flags.go b/pkg/cmd/flags.go index e7db3dde2..e59487044 100644 --- a/pkg/cmd/flags.go +++ b/pkg/cmd/flags.go @@ -65,6 +65,26 @@ func AddWaitFlag(cmd *cobra.Command, wait *kube.WaitStrategy) { cmd.Flags().Lookup("wait").NoOptDefVal = string(kube.StatusWatcherStrategy) } +// cliDefaultStatusComputeWorkers is the number of concurrent status-compute +// workers the Helm CLI enables by default. This prevents the informer +// notification pipeline from being blocked by slow API calls (e.g. LIST +// ReplicaSets/Pods for Deployments) when many resources are updated +// simultaneously. See https://github.com/fluxcd/cli-utils/pull/20. +// +// SDK consumers (e.g. helm-controller) inherit the zero value and can opt in +// via kube.WithStatusComputeWorkers when they want the same behavior. +const cliDefaultStatusComputeWorkers = 8 + +// defaultCLIWaitOptions returns the set of WaitOptions the Helm CLI applies +// by default to every wait-enabled command. Keeping these in one place keeps +// behavior consistent across install/upgrade/rollback/uninstall and makes the +// CLI-vs-SDK default asymmetry explicit. +func defaultCLIWaitOptions() []kube.WaitOption { + return []kube.WaitOption{ + kube.WithStatusComputeWorkers(cliDefaultStatusComputeWorkers), + } +} + type waitValue kube.WaitStrategy func newWaitValue(defaultValue kube.WaitStrategy, ws *kube.WaitStrategy) *waitValue { diff --git a/pkg/cmd/install.go b/pkg/cmd/install.go index b935ed4d0..b6cee5843 100644 --- a/pkg/cmd/install.go +++ b/pkg/cmd/install.go @@ -131,6 +131,7 @@ charts in a repository, use 'helm search'. func newInstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { client := action.NewInstall(cfg) + client.WaitOptions = append(client.WaitOptions, defaultCLIWaitOptions()...) valueOpts := &values.Options{} var outfmt output.Format diff --git a/pkg/cmd/release_testing.go b/pkg/cmd/release_testing.go index 5a6159e7d..6be83c966 100644 --- a/pkg/cmd/release_testing.go +++ b/pkg/cmd/release_testing.go @@ -40,6 +40,7 @@ The tests to be run are defined in the chart that was installed. func newReleaseTestCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { client := action.NewReleaseTesting(cfg) + client.WaitOptions = append(client.WaitOptions, defaultCLIWaitOptions()...) outfmt := output.Table var outputLogs bool var filter []string diff --git a/pkg/cmd/rollback.go b/pkg/cmd/rollback.go index 01d8b1866..b716dae10 100644 --- a/pkg/cmd/rollback.go +++ b/pkg/cmd/rollback.go @@ -40,6 +40,7 @@ To see revision numbers, run 'helm history RELEASE'. func newRollbackCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { client := action.NewRollback(cfg) + client.WaitOptions = append(client.WaitOptions, defaultCLIWaitOptions()...) cmd := &cobra.Command{ Use: "rollback [REVISION]", diff --git a/pkg/cmd/uninstall.go b/pkg/cmd/uninstall.go index bfecd4741..315c29a8d 100644 --- a/pkg/cmd/uninstall.go +++ b/pkg/cmd/uninstall.go @@ -42,6 +42,7 @@ are fully deleted before the command returns. func newUninstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { client := action.NewUninstall(cfg) + client.WaitOptions = append(client.WaitOptions, defaultCLIWaitOptions()...) cmd := &cobra.Command{ Use: "uninstall RELEASE_NAME [...]", diff --git a/pkg/cmd/upgrade.go b/pkg/cmd/upgrade.go index c038a2149..d0d0166ba 100644 --- a/pkg/cmd/upgrade.go +++ b/pkg/cmd/upgrade.go @@ -84,6 +84,7 @@ which can contain sensitive values. To hide Kubernetes Secrets use the func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { client := action.NewUpgrade(cfg) + client.WaitOptions = append(client.WaitOptions, defaultCLIWaitOptions()...) valueOpts := &values.Options{} var outfmt output.Format var createNamespace bool @@ -139,6 +140,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { instClient.SkipCRDs = client.SkipCRDs instClient.Timeout = client.Timeout instClient.WaitStrategy = client.WaitStrategy + instClient.WaitOptions = client.WaitOptions instClient.WaitForJobs = client.WaitForJobs instClient.Devel = client.Devel instClient.Namespace = client.Namespace diff --git a/pkg/kube/client.go b/pkg/kube/client.go index 1dfa88800..bb26fbcc9 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -167,14 +167,15 @@ func (c *Client) newStatusWatcher(opts ...WaitOption) (*statusWaiter, error) { waitContext = c.WaitContext } sw := &statusWaiter{ - restMapper: restMapper, - client: dynamicClient, - ctx: waitContext, - watchUntilReadyCtx: o.watchUntilReadyCtx, - waitCtx: o.waitCtx, - waitWithJobsCtx: o.waitWithJobsCtx, - waitForDeleteCtx: o.waitForDeleteCtx, - readers: o.statusReaders, + restMapper: restMapper, + client: dynamicClient, + ctx: waitContext, + watchUntilReadyCtx: o.watchUntilReadyCtx, + waitCtx: o.waitCtx, + waitWithJobsCtx: o.waitWithJobsCtx, + waitForDeleteCtx: o.waitForDeleteCtx, + readers: o.statusReaders, + statusComputeWorkers: o.statusComputeWorkers, } sw.SetLogger(c.Logger().Handler()) return sw, nil diff --git a/pkg/kube/options.go b/pkg/kube/options.go index 3326c284b..7853cb63a 100644 --- a/pkg/kube/options.go +++ b/pkg/kube/options.go @@ -72,11 +72,34 @@ func WithKStatusReaders(readers ...engine.StatusReader) WaitOption { } } +// WithStatusComputeWorkers sets the number of concurrent goroutines used to +// compute object status per informer. This prevents the informer notification +// pipeline from being blocked by slow API calls (e.g., LIST ReplicaSets/Pods +// for Deployments) when many resources are updated simultaneously. +// +// A value of 0 (the default) keeps the underlying cli-utils behavior, where +// status is computed synchronously on the informer goroutine. Negative values +// are clamped to 0 so callers cannot propagate invalid counts to the +// underlying watcher. SDK consumers (for example helm-controller) inherit +// this conservative default and can opt in explicitly. The Helm CLI passes +// a non-zero value so that `helm install/upgrade/rollback` users get the +// fix for multi-minute waits out of the box. +// See https://github.com/fluxcd/cli-utils/pull/20. +func WithStatusComputeWorkers(n int) WaitOption { + return func(wo *waitOptions) { + if n < 0 { + n = 0 + } + wo.statusComputeWorkers = n + } +} + type waitOptions struct { - ctx context.Context - watchUntilReadyCtx context.Context - waitCtx context.Context - waitWithJobsCtx context.Context - waitForDeleteCtx context.Context - statusReaders []engine.StatusReader + ctx context.Context + watchUntilReadyCtx context.Context + waitCtx context.Context + waitWithJobsCtx context.Context + waitForDeleteCtx context.Context + statusReaders []engine.StatusReader + statusComputeWorkers int } diff --git a/pkg/kube/statuswait.go b/pkg/kube/statuswait.go index 12c3e95a6..91eec30ef 100644 --- a/pkg/kube/statuswait.go +++ b/pkg/kube/statuswait.go @@ -43,14 +43,15 @@ import ( ) type statusWaiter struct { - client dynamic.Interface - restMapper meta.RESTMapper - ctx context.Context - watchUntilReadyCtx context.Context - waitCtx context.Context - waitWithJobsCtx context.Context - waitForDeleteCtx context.Context - readers []engine.StatusReader + client dynamic.Interface + restMapper meta.RESTMapper + ctx context.Context + watchUntilReadyCtx context.Context + waitCtx context.Context + waitWithJobsCtx context.Context + waitForDeleteCtx context.Context + readers []engine.StatusReader + statusComputeWorkers int logging.LogHolder } @@ -82,6 +83,7 @@ func (w *statusWaiter) WatchUntilReady(resourceList ResourceList, timeout time.D defer cancel() w.Logger().Debug("waiting for resources", "count", len(resourceList), "timeout", timeout) sw := getStatusWatcher(w.client, w.restMapper) + sw.StatusComputeWorkers = w.statusComputeWorkers jobSR := helmStatusReaders.NewCustomJobStatusReader(w.restMapper) podSR := helmStatusReaders.NewCustomPodStatusReader(w.restMapper) // We don't want to wait on any other resources as watchUntilReady is only for Helm hooks. @@ -104,6 +106,7 @@ func (w *statusWaiter) Wait(resourceList ResourceList, timeout time.Duration) er defer cancel() w.Logger().Debug("waiting for resources", "count", len(resourceList), "timeout", timeout) sw := getStatusWatcher(w.client, w.restMapper) + sw.StatusComputeWorkers = w.statusComputeWorkers sw.StatusReader = statusreaders.NewStatusReader(w.restMapper, w.readers...) return w.wait(ctx, resourceList, sw) } @@ -116,6 +119,7 @@ func (w *statusWaiter) WaitWithJobs(resourceList ResourceList, timeout time.Dura defer cancel() w.Logger().Debug("waiting for resources", "count", len(resourceList), "timeout", timeout) sw := getStatusWatcher(w.client, w.restMapper) + sw.StatusComputeWorkers = w.statusComputeWorkers newCustomJobStatusReader := helmStatusReaders.NewCustomJobStatusReader(w.restMapper) readers := append([]engine.StatusReader(nil), w.readers...) readers = append(readers, newCustomJobStatusReader) diff --git a/pkg/kube/statuswait_test.go b/pkg/kube/statuswait_test.go index 14f10124c..21580b57a 100644 --- a/pkg/kube/statuswait_test.go +++ b/pkg/kube/statuswait_test.go @@ -1293,6 +1293,28 @@ func TestWaitOptionFunctions(t *testing.T) { WithWaitForDeleteMethodContext(ctx)(opts) assert.Equal(t, ctx, opts.waitForDeleteCtx) }) + + t.Run("WithStatusComputeWorkers sets statusComputeWorkers", func(t *testing.T) { + t.Parallel() + opts := &waitOptions{} + WithStatusComputeWorkers(8)(opts) + assert.Equal(t, 8, opts.statusComputeWorkers) + }) + + t.Run("WithStatusComputeWorkers clamps negative values to zero", func(t *testing.T) { + t.Parallel() + opts := &waitOptions{} + WithStatusComputeWorkers(-1)(opts) + assert.Equal(t, 0, opts.statusComputeWorkers, + "negative worker counts must not propagate to the underlying watcher") + }) + + t.Run("waitOptions.statusComputeWorkers defaults to zero", func(t *testing.T) { + t.Parallel() + opts := &waitOptions{} + assert.Equal(t, 0, opts.statusComputeWorkers, + "SDK consumers must opt in to concurrent status computation") + }) } func TestMethodSpecificContextCancellation(t *testing.T) { From 0604d8fb1ee8ea172604cb739c93ea8d5ad068c6 Mon Sep 17 00:00:00 2001 From: Gates Wang <9372086+SetagGnaw@users.noreply.github.com> Date: Sun, 19 Jul 2026 20:36:57 -0400 Subject: [PATCH 12/61] fix: pass registry client to downloader.Manager in upgrade `helm upgrade --dependency-update` built its downloader.Manager without a RegistryClient, unlike the identical literals in install, dependency update, and dependency build. Resolving an OCI chart dependency whose version is a range then dereferenced a nil *registry.Client in registry.(*Client).Tags, panicking the process. Pass the registry client already constructed for the command, matching install. Add a regression test that runs `upgrade --dependency-update` against a chart with an unresolved OCI dependency and asserts the command returns an error instead of panicking. Signed-off-by: Gates Wang <9372086+SetagGnaw@users.noreply.github.com> --- pkg/cmd/upgrade.go | 1 + pkg/cmd/upgrade_test.go | 60 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/pkg/cmd/upgrade.go b/pkg/cmd/upgrade.go index d0d0166ba..688842141 100644 --- a/pkg/cmd/upgrade.go +++ b/pkg/cmd/upgrade.go @@ -226,6 +226,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { ContentCache: settings.ContentCache, Debug: settings.Debug, SourceDateEpoch: sourceDateEpoch, + RegistryClient: registryClient, } if err := man.Update(); err != nil { return err diff --git a/pkg/cmd/upgrade_test.go b/pkg/cmd/upgrade_test.go index 30188d3d9..203ec19cc 100644 --- a/pkg/cmd/upgrade_test.go +++ b/pkg/cmd/upgrade_test.go @@ -18,6 +18,8 @@ package cmd import ( "fmt" + "net/http" + "net/http/httptest" "os" "path/filepath" "reflect" @@ -193,6 +195,64 @@ func TestUpgradeCmd(t *testing.T) { runTestCmd(t, tests) } +// TestUpgradeDependencyUpdateOCINoPanic is a regression test for a nil-pointer +// panic in `helm upgrade --dependency-update` when a chart declares an OCI +// dependency. The upgrade command built its downloader.Manager without a +// RegistryClient (unlike install, dependency update, and dependency build), so +// resolving an OCI dependency dereferenced a nil *registry.Client. The command +// must now return a graceful error instead of panicking. +func TestUpgradeDependencyUpdateOCINoPanic(t *testing.T) { + defer resetEnv()() + + // A stub registry that answers the API-version ping but rejects the tag + // lookup, so OCI dependency resolution fails fast and hermetically instead + // of reaching a real registry. + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Docker-Distribution-API-Version", "registry/2.0") + if r.URL.Path == "/v2/" { + w.WriteHeader(http.StatusOK) + return + } + w.WriteHeader(http.StatusNotFound) + })) + defer srv.Close() + + // A chart with an unresolved OCI dependency forces --dependency-update into + // the tag-lookup path that previously panicked: the version is a range (an + // explicit version would skip the lookup) and the dependency is not present + // under charts/. + tmp := t.TempDir() + parent := &chart.Chart{ + Metadata: &chart.Metadata{ + APIVersion: chart.APIVersionV2, + Name: "oci-parent", + Version: "0.1.0", + Dependencies: []*chart.Dependency{{ + Name: "subchart", + Repository: fmt.Sprintf("oci://%s/charts", srv.Listener.Addr()), + Version: "^1.0.0", + }}, + }, + } + if err := chartutil.SaveDir(parent, tmp); err != nil { + t.Fatalf("Error creating chart: %v", err) + } + chartPath := filepath.Join(tmp, parent.Metadata.Name) + // SaveDir writes only resolved subcharts (Chart.Dependencies()), not the + // declared Metadata.Dependencies, so create the empty charts/ directory + // explicitly to make the "dependency missing from charts/" state concrete. + if err := os.MkdirAll(filepath.Join(chartPath, "charts"), 0o755); err != nil { + t.Fatalf("Error creating charts dir: %v", err) + } + + // The command must return an error (registry rejects the lookup), not panic. + _, _, err := executeActionCommandC(storageFixture(), + fmt.Sprintf("upgrade --dependency-update --plain-http oci-parent '%s'", chartPath)) + if err == nil { + t.Fatal("expected an error resolving the OCI dependency, got nil") + } +} + func TestUpgradeWithValue(t *testing.T) { releaseName := "funny-bunny-v2" relMock, ch, chartPath := prepareMockRelease(t, releaseName) From 615a29987660b11909f984887b47f7f608757d87 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 20:50:57 +0200 Subject: [PATCH 13/61] chore(internal): refactor: convert tests to testify assert/require part 2 #### Description refactor: convert tests to testify assert/require in internal/plugin/installer Signed-off-by: Matthieu MOREL --- internal/chart/v3/util/dependencies_test.go | 12 +- .../plugin/installer/http_installer_test.go | 290 ++++++------------ .../plugin/installer/local_installer_test.go | 80 ++--- 3 files changed, 116 insertions(+), 266 deletions(-) diff --git a/internal/chart/v3/util/dependencies_test.go b/internal/chart/v3/util/dependencies_test.go index f6ca06da3..45693ef46 100644 --- a/internal/chart/v3/util/dependencies_test.go +++ b/internal/chart/v3/util/dependencies_test.go @@ -369,8 +369,7 @@ func TestDependentChartWithSubChartsAbsentInDependency(t *testing.T) { require.Len(t, c.Dependencies(), 2, "expected 2 dependencies for this chart, but got %d", len(c.Dependencies())) - err := processDependencyEnabled(c, c.Values, "") - require.NoError(t, err, "expected no errors") + require.NoError(t, processDependencyEnabled(c, c.Values, ""), "expected no errors") require.Len(t, c.Dependencies(), 2, "expected no changes in dependencies") } @@ -381,8 +380,7 @@ func TestDependentChartWithSubChartsHelmignore(t *testing.T) { func TestDependentChartsWithSubChartsSymlink(t *testing.T) { joonix := filepath.Join("testdata", "joonix") - err := os.Symlink(filepath.Join("..", "..", "frobnitz"), filepath.Join(joonix, "charts", "frobnitz")) - require.NoError(t, err, "failed to create symlink") + require.NoError(t, os.Symlink(filepath.Join("..", "..", "frobnitz"), filepath.Join(joonix, "charts", "frobnitz")), "failed to create symlink") defer os.RemoveAll(filepath.Join(joonix, "charts", "frobnitz")) c := loadChart(t, joonix) @@ -394,12 +392,8 @@ func TestDependentChartsWithSubchartsAllSpecifiedInDependency(t *testing.T) { c := loadChart(t, "testdata/dependent-chart-with-all-in-requirements-yaml") require.Len(t, c.Dependencies(), 2, "expected 2 dependencies for this chart, but got %d", len(c.Dependencies())) - - err := processDependencyEnabled(c, c.Values, "") - require.NoError(t, err, "expected no errors") - + require.NoError(t, processDependencyEnabled(c, c.Values, ""), "expected no errors") require.Len(t, c.Dependencies(), 2, "expected no changes in dependencies") - require.Len(t, c.Dependencies(), len(c.Metadata.Dependencies), "expected number of chart dependencies %d, but got %d", len(c.Metadata.Dependencies), len(c.Dependencies())) } diff --git a/internal/plugin/installer/http_installer_test.go b/internal/plugin/installer/http_installer_test.go index 3235e9796..d0d5e099d 100644 --- a/internal/plugin/installer/http_installer_test.go +++ b/internal/plugin/installer/http_installer_test.go @@ -27,10 +27,14 @@ import ( "net/http/httptest" "os" "path/filepath" + "strconv" "strings" "syscall" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "helm.sh/helm/v4/internal/test/ensure" "helm.sh/helm/v4/pkg/getter" "helm.sh/helm/v4/pkg/helmpath" @@ -52,18 +56,10 @@ func (t *TestHTTPGetter) Get(_ string, _ ...getter.Option) (*bytes.Buffer, error var fakePluginB64 = "H4sIAAAAAAAAA+3SQUvDMBgG4Jz7K0LwapdvSxrwJig6mCKC5xHabBaXdDSt4L+3cQ56mV42ZPg+lw+SF5LwZmXf3OV206/rMGEnIgdG6zTJaDmee4y01FOlZpqGHJGZSsb1qS401sfOtpyz0FTup9xv+2dqNep/N/IP6zdHPSMVXCh1sH8yhtGMDBUFFTL1r4iIcXnUWxzwz/sP1rsrLkbfQGTvro11E4ZlmcucRNZHu04py1OO73OVi2Vbb7td9vp7nXevtvsKRpGVjfc2VMP2xf3t4mH5tHi5mz8ub+bPk9JXIvvr5wMAAAAAAAAAAAAAAAAAAAAAnLVPqwHcXQAoAAA=" func TestStripName(t *testing.T) { - if stripPluginName("fake-plugin-0.0.1.tar.gz") != "fake-plugin" { - t.Error("name does not match expected value") - } - if stripPluginName("fake-plugin-0.0.1.tgz") != "fake-plugin" { - t.Error("name does not match expected value") - } - if stripPluginName("fake-plugin.tgz") != "fake-plugin" { - t.Error("name does not match expected value") - } - if stripPluginName("fake-plugin.tar.gz") != "fake-plugin" { - t.Error("name does not match expected value") - } + assert.Equal(t, "fake-plugin", stripPluginName("fake-plugin-0.0.1.tar.gz"), "name does not match expected value") + assert.Equal(t, "fake-plugin", stripPluginName("fake-plugin-0.0.1.tgz"), "name does not match expected value") + assert.Equal(t, "fake-plugin", stripPluginName("fake-plugin.tgz"), "name does not match expected value") + assert.Equal(t, "fake-plugin", stripPluginName("fake-plugin.tar.gz"), "name does not match expected value") } func mockArchiveServer() *httptest.Server { @@ -85,45 +81,29 @@ func TestHTTPInstaller(t *testing.T) { defer srv.Close() source := srv.URL + "/plugins/fake-plugin-0.0.1.tar.gz" - if err := os.MkdirAll(helmpath.DataPath("plugins"), 0o755); err != nil { - t.Fatalf("Could not create %s: %s", helmpath.DataPath("plugins"), err) - } + require.NoErrorf(t, os.MkdirAll(helmpath.DataPath("plugins"), 0o755), "Could not create %s", helmpath.DataPath("plugins")) i, err := NewForSource(source, "0.0.1") - if err != nil { - t.Fatalf("unexpected error: %s", err) - } + require.NoError(t, err) // ensure a HTTPInstaller was returned httpInstaller, ok := i.(*HTTPInstaller) - if !ok { - t.Fatal("expected a HTTPInstaller") - } + require.True(t, ok, "expected a HTTPInstaller") // inject fake http client responding with minimal plugin tarball mockTgz, err := base64.StdEncoding.DecodeString(fakePluginB64) - if err != nil { - t.Fatalf("Could not decode fake tgz plugin: %s", err) - } + require.NoError(t, err, "Could not decode fake tgz plugin") httpInstaller.getter = &TestHTTPGetter{ MockResponse: bytes.NewBuffer(mockTgz), } // install the plugin - if err := Install(i); err != nil { - t.Fatal(err) - } - if i.Path() != helmpath.DataPath("plugins", "fake-plugin") { - t.Fatalf("expected path '$XDG_CONFIG_HOME/helm/plugins/fake-plugin', got %q", i.Path()) - } + require.NoError(t, Install(i)) + require.Equal(t, helmpath.DataPath("plugins", "fake-plugin"), i.Path(), "expected path '$XDG_CONFIG_HOME/helm/plugins/fake-plugin', got %q", i.Path()) // Install again to test plugin exists error - if err := Install(i); err == nil { - t.Fatal("expected error for plugin exists, got none") - } else if err.Error() != "plugin already exists" { - t.Fatalf("expected error for plugin exists, got (%v)", err) - } + require.EqualErrorf(t, Install(i), "plugin already exists", "expected error for plugin exists") } func TestHTTPInstallerNonExistentVersion(t *testing.T) { @@ -132,20 +112,14 @@ func TestHTTPInstallerNonExistentVersion(t *testing.T) { defer srv.Close() source := srv.URL + "/plugins/fake-plugin-0.0.1.tar.gz" - if err := os.MkdirAll(helmpath.DataPath("plugins"), 0o755); err != nil { - t.Fatalf("Could not create %s: %s", helmpath.DataPath("plugins"), err) - } + require.NoErrorf(t, os.MkdirAll(helmpath.DataPath("plugins"), 0o755), "Could not create %s", helmpath.DataPath("plugins")) i, err := NewForSource(source, "0.0.2") - if err != nil { - t.Fatalf("unexpected error: %s", err) - } + require.NoError(t, err) // ensure a HTTPInstaller was returned httpInstaller, ok := i.(*HTTPInstaller) - if !ok { - t.Fatal("expected a HTTPInstaller") - } + require.True(t, ok, "expected a HTTPInstaller") // inject fake http client responding with error httpInstaller.getter = &TestHTTPGetter{ @@ -153,9 +127,7 @@ func TestHTTPInstallerNonExistentVersion(t *testing.T) { } // attempt to install the plugin - if err := Install(i); err == nil { - t.Fatal("expected error from http client") - } + require.Error(t, Install(i), "expected error from http client") } func TestHTTPInstallerUpdate(t *testing.T) { @@ -164,43 +136,29 @@ func TestHTTPInstallerUpdate(t *testing.T) { source := srv.URL + "/plugins/fake-plugin-0.0.1.tar.gz" ensure.HelmHome(t) - if err := os.MkdirAll(helmpath.DataPath("plugins"), 0o755); err != nil { - t.Fatalf("Could not create %s: %s", helmpath.DataPath("plugins"), err) - } + require.NoErrorf(t, os.MkdirAll(helmpath.DataPath("plugins"), 0o755), "Could not create %s", helmpath.DataPath("plugins")) i, err := NewForSource(source, "0.0.1") - if err != nil { - t.Fatalf("unexpected error: %s", err) - } + require.NoError(t, err) // ensure a HTTPInstaller was returned httpInstaller, ok := i.(*HTTPInstaller) - if !ok { - t.Fatal("expected a HTTPInstaller") - } + require.True(t, ok, "expected a HTTPInstaller") // inject fake http client responding with minimal plugin tarball mockTgz, err := base64.StdEncoding.DecodeString(fakePluginB64) - if err != nil { - t.Fatalf("Could not decode fake tgz plugin: %s", err) - } + require.NoError(t, err, "Could not decode fake tgz plugin") httpInstaller.getter = &TestHTTPGetter{ MockResponse: bytes.NewBuffer(mockTgz), } // install the plugin before updating - if err := Install(i); err != nil { - t.Fatal(err) - } - if i.Path() != helmpath.DataPath("plugins", "fake-plugin") { - t.Fatalf("expected path '$XDG_CONFIG_HOME/helm/plugins/fake-plugin', got %q", i.Path()) - } + require.NoError(t, Install(i)) + require.Equal(t, helmpath.DataPath("plugins", "fake-plugin"), i.Path(), "expected path '$XDG_CONFIG_HOME/helm/plugins/fake-plugin', got %q", i.Path()) // Update plugin, should fail because it is not implemented - if err := Update(i); err == nil { - t.Fatal("update method not implemented for http installer") - } + require.Error(t, Update(i), "update method not implemented for http installer") } func TestExtract(t *testing.T) { @@ -229,12 +187,9 @@ func TestExtract(t *testing.T) { Mode: file.Mode, Size: int64(len(file.Body)), } - if err := tw.WriteHeader(hdr); err != nil { - t.Fatal(err) - } - if _, err := tw.Write([]byte(file.Body)); err != nil { - t.Fatal(err) - } + require.NoError(t, tw.WriteHeader(hdr)) + _, err := tw.Write([]byte(file.Body)) + require.NoError(t, err) } // Add pax global headers. This should be ignored. @@ -242,33 +197,24 @@ func TestExtract(t *testing.T) { // Details are in the internal Go function for the tar packaged named // allowedFormats. For a TypeXHeader it will return a message stating // "cannot manually encode TypeXHeader, TypeGNULongName, or TypeGNULongLink headers" - if err := tw.WriteHeader(&tar.Header{ + require.NoError(t, tw.WriteHeader(&tar.Header{ Name: "pax_global_header", Typeflag: tar.TypeXGlobalHeader, - }); err != nil { - t.Fatal(err) - } + })) - if err := tw.Close(); err != nil { - t.Fatal(err) - } + require.NoError(t, tw.Close()) var buf bytes.Buffer gz := gzip.NewWriter(&buf) - if _, err := gz.Write(tarbuf.Bytes()); err != nil { - t.Fatal(err) - } + _, err := gz.Write(tarbuf.Bytes()) + require.NoError(t, err) gz.Close() // END tarball creation extractor, err := NewExtractor(source) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if err = extractor.Extract(&buf, tempDir); err != nil { - t.Fatalf("Did not expect error but got error: %v", err) - } + require.NoErrorf(t, extractor.Extract(&buf, tempDir), "Did not expect error") // Calculate expected permissions after umask is applied expectedPluginYAMLPerm := os.FileMode(0o600 &^ currentUmask) @@ -276,23 +222,19 @@ func TestExtract(t *testing.T) { pluginYAMLFullPath := filepath.Join(tempDir, "plugin.yaml") if info, err := os.Stat(pluginYAMLFullPath); err != nil { - if errors.Is(err, fs.ErrNotExist) { - t.Fatalf("Expected %s to exist but doesn't", pluginYAMLFullPath) - } + require.NotErrorIs(t, err, fs.ErrNotExist, "Expected %s to exist but doesn't", pluginYAMLFullPath) t.Fatal(err) - } else if info.Mode().Perm() != expectedPluginYAMLPerm { - t.Fatalf("Expected %s to have %o mode but has %o (umask: %o)", + } else { + require.Equalf(t, expectedPluginYAMLPerm, info.Mode().Perm(), "Expected %s to have %o mode but has %o (umask: %o)", pluginYAMLFullPath, expectedPluginYAMLPerm, info.Mode().Perm(), currentUmask) } readmeFullPath := filepath.Join(tempDir, "README.md") if info, err := os.Stat(readmeFullPath); err != nil { - if errors.Is(err, fs.ErrNotExist) { - t.Fatalf("Expected %s to exist but doesn't", readmeFullPath) - } + require.NotErrorIs(t, err, fs.ErrNotExist, "Expected %s to exist but doesn't", readmeFullPath) t.Fatal(err) - } else if info.Mode().Perm() != expectedReadmePerm { - t.Fatalf("Expected %s to have %o mode but has %o (umask: %o)", + } else { + require.Equalf(t, expectedReadmePerm, info.Mode().Perm(), "Expected %s to have %o mode but has %o (umask: %o)", readmeFullPath, expectedReadmePerm, info.Mode().Perm(), currentUmask) } } @@ -313,16 +255,15 @@ func TestCleanJoin(t *testing.T) { {"foo\\bar.txt", "/tmp/foo/bar.txt", false}, {"c:\\foo\\bar.txt", "", true}, } { - out, err := cleanJoin("/tmp", fixture.path) - if err != nil { - if !fixture.expectError { - t.Errorf("Test %d: Path was not cleaned: %s", i, err) + t.Run(strconv.Itoa(i), func(t *testing.T) { + out, err := cleanJoin("/tmp", fixture.path) + if fixture.expectError { + require.Error(t, err, "Test %d: Path was not cleaned", i) + } else { + require.NoError(t, err) + assert.Equal(t, fixture.expect, out, "Test %d: Expected %q but got %q", i, fixture.expect, out) } - continue - } - if fixture.expect != out { - t.Errorf("Test %d: Expected %q but got %q", i, fixture.expect, out) - } + }) } } @@ -336,14 +277,11 @@ func TestMediaTypeToExtension(t *testing.T) { "application/json": false, } { ext, ok := mediaTypeToExtension(mt) - if ok != shouldPass { - t.Errorf("Media type %q failed test", mt) - } - if shouldPass && ext == "" { - t.Error("Expected an extension but got empty string") - } - if !shouldPass && ext != "" { - t.Error("Expected extension to be empty for unrecognized type") + assert.Equal(t, shouldPass, ok, "Media type %q failed test", mt) + if shouldPass { + assert.NotEmpty(t, ext, "Expected an extension but got empty string for media type %q", mt) + } else { + assert.Empty(t, ext, "Expected extension to be empty for unrecognized media type %q", mt) } } } @@ -377,55 +315,41 @@ func TestExtractWithNestedDirectories(t *testing.T) { Mode: file.Mode, Size: int64(len(file.Body)), } - if err := tw.WriteHeader(hdr); err != nil { - t.Fatal(err) - } + require.NoError(t, tw.WriteHeader(hdr)) if file.TypeFlag == tar.TypeReg { - if _, err := tw.Write([]byte(file.Body)); err != nil { - t.Fatal(err) - } + _, err := tw.Write([]byte(file.Body)) + require.NoError(t, err) } } - if err := tw.Close(); err != nil { - t.Fatal(err) - } + require.NoError(t, tw.Close()) var buf bytes.Buffer gz := gzip.NewWriter(&buf) - if _, err := gz.Write(tarbuf.Bytes()); err != nil { - t.Fatal(err) - } + _, err := gz.Write(tarbuf.Bytes()) + require.NoError(t, err) gz.Close() extractor, err := NewExtractor(source) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) // First extraction - if err = extractor.Extract(&buf, tempDir); err != nil { - t.Fatalf("First extraction failed: %v", err) - } + require.NoError(t, extractor.Extract(&buf, tempDir), "First extraction failed") // Verify nested structure was created nestedFile := filepath.Join(tempDir, "docs", "examples", "example1.yaml") - if _, err := os.Stat(nestedFile); err != nil { - t.Fatalf("Expected nested file %s to exist but got error: %v", nestedFile, err) - } + _, err = os.Stat(nestedFile) + require.NoErrorf(t, err, "Expected nested file %s to exist", nestedFile) // Reset buffer for second extraction buf.Reset() gz = gzip.NewWriter(&buf) - if _, err := gz.Write(tarbuf.Bytes()); err != nil { - t.Fatal(err) - } + _, err = gz.Write(tarbuf.Bytes()) + require.NoError(t, err) gz.Close() // Second extraction to same directory (should not fail) - if err = extractor.Extract(&buf, tempDir); err != nil { - t.Fatalf("Second extraction to existing directory failed: %v", err) - } + require.NoErrorf(t, extractor.Extract(&buf, tempDir), "Second extraction to existing directory failed") } func TestExtractWithExistingDirectory(t *testing.T) { @@ -434,15 +358,11 @@ func TestExtractWithExistingDirectory(t *testing.T) { // Pre-create the cache directory structure cacheDir := filepath.Join(tempDir, "cache") - if err := os.MkdirAll(filepath.Join(cacheDir, "existing", "dir"), 0o755); err != nil { - t.Fatal(err) - } + require.NoError(t, os.MkdirAll(filepath.Join(cacheDir, "existing", "dir"), 0o755)) // Create a file in the existing directory existingFile := filepath.Join(cacheDir, "existing", "file.txt") - if err := os.WriteFile(existingFile, []byte("existing content"), 0o644); err != nil { - t.Fatal(err) - } + require.NoError(t, os.WriteFile(existingFile, []byte("existing content"), 0o644)) // Write a tarball var tarbuf bytes.Buffer @@ -466,47 +386,35 @@ func TestExtractWithExistingDirectory(t *testing.T) { Mode: file.Mode, Size: int64(len(file.Body)), } - if err := tw.WriteHeader(hdr); err != nil { - t.Fatal(err) - } + require.NoError(t, tw.WriteHeader(hdr)) if file.TypeFlag == tar.TypeReg { - if _, err := tw.Write([]byte(file.Body)); err != nil { - t.Fatal(err) - } + _, err := tw.Write([]byte(file.Body)) + require.NoError(t, err) } } - if err := tw.Close(); err != nil { - t.Fatal(err) - } + require.NoError(t, tw.Close()) var buf bytes.Buffer gz := gzip.NewWriter(&buf) - if _, err := gz.Write(tarbuf.Bytes()); err != nil { - t.Fatal(err) - } + _, err := gz.Write(tarbuf.Bytes()) + require.NoError(t, err) gz.Close() extractor, err := NewExtractor(source) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) // Extract to directory with existing content - if err = extractor.Extract(&buf, cacheDir); err != nil { - t.Fatalf("Extraction to directory with existing content failed: %v", err) - } + require.NoErrorf(t, extractor.Extract(&buf, cacheDir), "Extraction to directory with existing content failed") // Verify new file was created newFile := filepath.Join(cacheDir, "existing", "dir", "newfile.txt") - if _, err := os.Stat(newFile); err != nil { - t.Fatalf("Expected new file %s to exist but got error: %v", newFile, err) - } + _, err = os.Stat(newFile) + require.NoErrorf(t, err, "Expected new file %s to exist but got error", newFile) // Verify existing file is still there - if _, err := os.Stat(existingFile); err != nil { - t.Fatalf("Expected existing file %s to still exist but got error: %v", existingFile, err) - } + _, err = os.Stat(existingFile) + require.NoErrorf(t, err, "Expected existing file %s to still exist", existingFile) } func TestExtractPluginInSubdirectory(t *testing.T) { @@ -536,25 +444,19 @@ func TestExtractPluginInSubdirectory(t *testing.T) { Mode: file.Mode, Size: int64(len(file.Body)), } - if err := tw.WriteHeader(hdr); err != nil { - t.Fatal(err) - } + require.NoError(t, tw.WriteHeader(hdr)) if file.TypeFlag == tar.TypeReg { - if _, err := tw.Write([]byte(file.Body)); err != nil { - t.Fatal(err) - } + _, err := tw.Write([]byte(file.Body)) + require.NoError(t, err) } } - if err := tw.Close(); err != nil { - t.Fatal(err) - } + require.NoError(t, tw.Close()) var buf bytes.Buffer gz := gzip.NewWriter(&buf) - if _, err := gz.Write(tarbuf.Bytes()); err != nil { - t.Fatal(err) - } + _, err := gz.Write(tarbuf.Bytes()) + require.NoError(t, err) gz.Close() // Test the installer @@ -573,24 +475,16 @@ func TestExtractPluginInSubdirectory(t *testing.T) { // Ensure the destination directory doesn't exist // (In a real scenario, this is handled by installer.Install() wrapper) destPath := installer.Path() - if err := os.RemoveAll(destPath); err != nil { - t.Fatalf("Failed to clean destination path: %v", err) - } + require.NoErrorf(t, os.RemoveAll(destPath), "Failed to clean destination path") // Install should handle the subdirectory correctly - if err := installer.Install(); err != nil { - t.Fatalf("Failed to install plugin with subdirectory: %v", err) - } + require.NoErrorf(t, installer.Install(), "Failed to install plugin with subdirectory") // The plugin should be installed from the subdirectory // Check that detectPluginRoot found the correct location pluginRoot, err := detectPluginRoot(tempDir) - if err != nil { - t.Fatalf("Failed to detect plugin root: %v", err) - } + require.NoError(t, err, "Failed to detect plugin root") expectedRoot := filepath.Join(tempDir, "my-plugin") - if pluginRoot != expectedRoot { - t.Errorf("Expected plugin root to be %s but got %s", expectedRoot, pluginRoot) - } + assert.Equal(t, expectedRoot, pluginRoot, "Expected plugin root to be %s but got %s", expectedRoot, pluginRoot) } diff --git a/internal/plugin/installer/local_installer_test.go b/internal/plugin/installer/local_installer_test.go index f46fcb44b..94632756c 100644 --- a/internal/plugin/installer/local_installer_test.go +++ b/internal/plugin/installer/local_installer_test.go @@ -19,11 +19,12 @@ import ( "archive/tar" "bytes" "compress/gzip" - "errors" "os" "path/filepath" "testing" + "github.com/stretchr/testify/require" + "helm.sh/helm/v4/internal/test/ensure" "helm.sh/helm/v4/pkg/helmpath" ) @@ -34,40 +35,23 @@ func TestLocalInstaller(t *testing.T) { ensure.HelmHome(t) // Make a temp dir tdir := t.TempDir() - if err := os.WriteFile(filepath.Join(tdir, "plugin.yaml"), []byte{}, 0o644); err != nil { - t.Fatal(err) - } + require.NoError(t, os.WriteFile(filepath.Join(tdir, "plugin.yaml"), []byte{}, 0o644)) source := "../testdata/plugdir/good/echo-v1" i, err := NewForSource(source, "") - if err != nil { - t.Fatalf("unexpected error: %s", err) - } + require.NoError(t, err) - if err := Install(i); err != nil { - t.Fatal(err) - } + require.NoError(t, Install(i)) - if i.Path() != helmpath.DataPath("plugins", "echo-v1") { - t.Fatalf("expected path '$XDG_CONFIG_HOME/helm/plugins/helm-env', got %q", i.Path()) - } + require.Equal(t, helmpath.DataPath("plugins", "echo-v1"), i.Path(), "expected path '$XDG_CONFIG_HOME/helm/plugins/helm-env', got %q", i.Path()) os.RemoveAll(filepath.Dir(helmpath.DataPath())) // helmpath.DataPath is like /tmp/helm013130971/helm } func TestLocalInstallerNotAFolder(t *testing.T) { source := "../testdata/plugdir/good/echo-v1/plugin.yaml" i, err := NewForSource(source, "") - if err != nil { - t.Fatalf("unexpected error: %s", err) - } - - err = Install(i) - if err == nil { - t.Fatal("expected error") - } - if !errors.Is(err, ErrPluginNotADirectory) { - t.Fatalf("expected error to equal: %q", err) - } + require.NoError(t, err) + require.ErrorIs(t, Install(i), ErrPluginNotADirectory) } func TestLocalInstallerTarball(t *testing.T) { @@ -97,53 +81,31 @@ func TestLocalInstallerTarball(t *testing.T) { Mode: file.Mode, Size: int64(len(file.Body)), } - if err := tw.WriteHeader(hdr); err != nil { - t.Fatal(err) - } - if _, err := tw.Write([]byte(file.Body)); err != nil { - t.Fatal(err) - } + require.NoError(t, tw.WriteHeader(hdr)) + _, err := tw.Write([]byte(file.Body)) + require.NoError(t, err) } - if err := tw.Close(); err != nil { - t.Fatal(err) - } - if err := gw.Close(); err != nil { - t.Fatal(err) - } + require.NoError(t, tw.Close()) + require.NoError(t, gw.Close()) // Write tarball to file - if err := os.WriteFile(tarballPath, buf.Bytes(), 0o644); err != nil { - t.Fatal(err) - } + require.NoError(t, os.WriteFile(tarballPath, buf.Bytes(), 0o644)) // Test installation i, err := NewForSource(tarballPath, "") - if err != nil { - t.Fatalf("unexpected error: %s", err) - } + require.NoError(t, err) // Verify it's detected as LocalInstaller localInstaller, ok := i.(*LocalInstaller) - if !ok { - t.Fatal("expected LocalInstaller") - } - - if !localInstaller.isArchive { - t.Fatal("expected isArchive to be true") - } - - if err := Install(i); err != nil { - t.Fatal(err) - } + require.True(t, ok, "expected LocalInstaller") + require.True(t, localInstaller.isArchive, "expected isArchive to be true") + require.NoError(t, Install(i)) expectedPath := helmpath.DataPath("plugins", "test-plugin") - if i.Path() != expectedPath { - t.Fatalf("expected path %q, got %q", expectedPath, i.Path()) - } + require.Equal(t, expectedPath, i.Path(), "expected path %q, got %q", expectedPath, i.Path()) // Verify plugin was installed - if _, err := os.Stat(i.Path()); err != nil { - t.Fatalf("plugin not found at %s: %v", i.Path(), err) - } + _, err = os.Stat(i.Path()) + require.NoErrorf(t, err, "plugin not found at %s", i.Path()) } From ba31ca0c0b455541f05986e8dcb8a0554fa70dd2 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 20:50:56 +0200 Subject: [PATCH 14/61] chore(internal): refactor: convert tests to testify assert/require part 1 refactor: convert tests to testify assert/require in internal/plugin/installer Signed-off-by: Matthieu MOREL --- .../plugin/installer/oci_installer_test.go | 316 +++++------------- .../plugin/installer/vcs_installer_test.go | 89 ++--- 2 files changed, 113 insertions(+), 292 deletions(-) diff --git a/internal/plugin/installer/oci_installer_test.go b/internal/plugin/installer/oci_installer_test.go index 48eccf6e1..ce381d12c 100644 --- a/internal/plugin/installer/oci_installer_test.go +++ b/internal/plugin/installer/oci_installer_test.go @@ -64,12 +64,9 @@ command: "$HELM_PLUGIN_DIR/bin/%s" Size: int64(len(pluginYAML)), Typeflag: tar.TypeReg, } - if err := tarWriter.WriteHeader(header); err != nil { - t.Fatal(err) - } - if _, err := tarWriter.Write([]byte(pluginYAML)); err != nil { - t.Fatal(err) - } + require.NoError(t, tarWriter.WriteHeader(header)) + _, err := tarWriter.Write([]byte(pluginYAML)) + require.NoError(t, err) // Add bin directory dirHeader := &tar.Header{ @@ -77,9 +74,7 @@ command: "$HELM_PLUGIN_DIR/bin/%s" Mode: 0o755, Typeflag: tar.TypeDir, } - if err := tarWriter.WriteHeader(dirHeader); err != nil { - t.Fatal(err) - } + require.NoError(t, tarWriter.WriteHeader(dirHeader)) // Add executable execContent := fmt.Sprintf("#!/bin/sh\necho '%s test plugin'", pluginName) @@ -89,12 +84,9 @@ command: "$HELM_PLUGIN_DIR/bin/%s" Size: int64(len(execContent)), Typeflag: tar.TypeReg, } - if err := tarWriter.WriteHeader(execHeader); err != nil { - t.Fatal(err) - } - if _, err := tarWriter.Write([]byte(execContent)); err != nil { - t.Fatal(err) - } + require.NoError(t, tarWriter.WriteHeader(execHeader)) + _, err = tarWriter.Write([]byte(execContent)) + require.NoError(t, err) tarWriter.Close() gzWriter.Close() @@ -135,9 +127,7 @@ func mockOCIRegistryWithArtifactType(t *testing.T, pluginName string) (*httptest } manifestData, err := json.Marshal(manifest) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) manifestDigest := fmt.Sprintf("sha256:%x", sha256Sum(manifestData)) server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -175,9 +165,7 @@ func mockOCIRegistryWithArtifactType(t *testing.T, pluginName string) (*httptest // Parse server URL to get host:port format for OCI reference serverURL, err := url.Parse(server.URL) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) registryHost := serverURL.Host return server, registryHost @@ -240,42 +228,20 @@ func TestNewOCIInstaller(t *testing.T) { installer, err := NewOCIInstaller(tt.source) if tt.expectError { - if err == nil { - t.Error("expected error but got none") - } - return - } - - if err != nil { - t.Errorf("unexpected error: %v", err) - return - } - - // Check all fields thoroughly - if installer.PluginName != tt.expectName { - t.Errorf("expected plugin name %s, got %s", tt.expectName, installer.PluginName) - } - - if installer.Source != tt.source { - t.Errorf("expected source %s, got %s", tt.source, installer.Source) - } - - if installer.CacheDir == "" { - t.Error("expected non-empty cache directory") - } - - if !strings.Contains(installer.CacheDir, "plugins") { - t.Errorf("expected cache directory to contain 'plugins', got %s", installer.CacheDir) - } - - if installer.settings == nil { - t.Error("expected settings to be initialized") - } - - // Check that Path() method works - expectedPath := helmpath.DataPath("plugins", tt.expectName) - if installer.Path() != expectedPath { - t.Errorf("expected path %s, got %s", expectedPath, installer.Path()) + require.Error(t, err) + } else { + require.NoError(t, err) + + // Check all fields thoroughly + assert.Equal(t, tt.expectName, installer.PluginName, "expected plugin name %s, got %s", tt.expectName, installer.PluginName) + assert.Equal(t, tt.source, installer.Source, "expected source %s, got %s", tt.source, installer.Source) + assert.NotEmpty(t, installer.CacheDir, "expected non-empty cache directory") + assert.Contains(t, installer.CacheDir, "plugins", "expected cache directory to contain 'plugins', got %s", installer.CacheDir) + assert.NotNil(t, installer.settings, "expected settings to be initialized") + + // Check that Path() method works + expectedPath := helmpath.DataPath("plugins", tt.expectName) + assert.Equal(t, expectedPath, installer.Path(), "expected path %s, got %s", expectedPath, installer.Path()) } }) } @@ -311,9 +277,7 @@ func TestOCIInstaller_Path(t *testing.T) { } path := installer.Path() - if path != tt.expectPath { - t.Errorf("expected path %s, got %s", tt.expectPath, path) - } + assert.Equal(t, tt.expectPath, path, "expected path %s, got %s", tt.expectPath, path) }) } } @@ -331,39 +295,30 @@ func TestOCIInstaller_Install(t *testing.T) { // Test with plain HTTP (since test server uses HTTP) installer, err := NewOCIInstaller(source, getter.WithPlainHTTP(true)) - if err != nil { - t.Fatalf("Expected no error, got %v", err) - } + require.NoError(t, err) // The OCI installer uses helmpath.DataPath, which is isolated by ensure.HelmHome(t) actualPath := installer.Path() t.Logf("Installer will use path: %s", actualPath) // Install the plugin - if err := Install(installer); err != nil { - t.Fatalf("Expected installation to succeed, got error: %v", err) - } + require.NoErrorf(t, Install(installer), "Expected installation to succeed") // Verify plugin was installed to the correct location - if !isPlugin(actualPath) { - t.Errorf("Expected plugin directory %s to contain plugin.yaml", actualPath) - } + assert.Truef(t, isPlugin(actualPath), "Expected plugin directory %s to contain plugin.yaml", actualPath) // Debug: list what was actually created - if entries, err := os.ReadDir(actualPath); err != nil { - t.Fatalf("Could not read plugin directory %s: %v", actualPath, err) - } else { - t.Logf("Plugin directory %s contains:", actualPath) - for _, entry := range entries { - t.Logf(" - %s", entry.Name()) - } + entries, err := os.ReadDir(actualPath) + require.NoError(t, err, "Could not read plugin directory %s", actualPath) + t.Logf("Plugin directory %s contains:", actualPath) + for _, entry := range entries { + t.Logf(" - %s", entry.Name()) } // Verify the plugin.yaml file exists and is valid pluginFile := filepath.Join(actualPath, "plugin.yaml") - if _, err := os.Stat(pluginFile); err != nil { - t.Errorf("Expected plugin.yaml to exist, got error: %v", err) - } + _, err = os.Stat(pluginFile) + assert.NoErrorf(t, err, "Expected plugin.yaml to exist") } func TestOCIInstaller_Install_WithGetterOptions(t *testing.T) { @@ -404,11 +359,9 @@ func TestOCIInstaller_Install_WithGetterOptions(t *testing.T) { source := fmt.Sprintf("oci://%s/%s:latest", registryHost, tc.pluginName) installer, err := NewOCIInstaller(source, tc.options...) - if err != nil { - if !tc.wantErr { - t.Fatalf("Expected no error creating installer, got %v", err) - } - return + + if !tc.wantErr { + require.NoError(t, err, "Expected no error creating installer") } // The installer now uses our isolated test directory @@ -419,7 +372,7 @@ func TestOCIInstaller_Install_WithGetterOptions(t *testing.T) { if tc.wantErr { require.Error(t, err, "Expected installation to fail, but it succeeded") } else { - require.NoError(t, err, "Expected installation to succeed, got error: %v", err) + require.NoError(t, err, "Expected installation to succeed") // Verify plugin was installed to the actual path assert.True(t, isPlugin(actualPath), "Expected plugin directory %s to contain plugin.yaml", actualPath) } @@ -437,27 +390,16 @@ func TestOCIInstaller_Install_AlreadyExists(t *testing.T) { source := fmt.Sprintf("oci://%s/%s:latest", registryHost, pluginName) installer, err := NewOCIInstaller(source, getter.WithPlainHTTP(true)) - if err != nil { - t.Fatalf("Expected no error, got %v", err) - } + require.NoError(t, err) // First install should succeed - if err := Install(installer); err != nil { - t.Fatalf("Expected first installation to succeed, got error: %v", err) - } + require.NoErrorf(t, Install(installer), "Expected first installation to succeed") // Verify plugin was installed - if !isPlugin(installer.Path()) { - t.Errorf("Expected plugin directory %s to contain plugin.yaml", installer.Path()) - } + assert.Truef(t, isPlugin(installer.Path()), "Expected plugin directory %s to contain plugin.yaml", installer.Path()) // Second install should fail with "plugin already exists" - err = Install(installer) - if err == nil { - t.Error("Expected error when installing plugin that already exists") - } else if !strings.Contains(err.Error(), "plugin already exists") { - t.Errorf("Expected 'plugin already exists' error, got: %v", err) - } + assert.ErrorContains(t, Install(installer), "plugin already exists") } func TestOCIInstaller_Update(t *testing.T) { @@ -470,38 +412,23 @@ func TestOCIInstaller_Update(t *testing.T) { source := fmt.Sprintf("oci://%s/%s:latest", registryHost, pluginName) installer, err := NewOCIInstaller(source, getter.WithPlainHTTP(true)) - if err != nil { - t.Fatalf("Expected no error, got %v", err) - } + require.NoError(t, err) // Test update when plugin does not exist - should fail - err = Update(installer) - if err == nil { - t.Error("Expected error when updating plugin that does not exist") - } else if !strings.Contains(err.Error(), "plugin does not exist") { - t.Errorf("Expected 'plugin does not exist' error, got: %v", err) - } + require.ErrorContains(t, Update(installer), "plugin does not exist") // Install plugin first - if err := Install(installer); err != nil { - t.Fatalf("Expected installation to succeed, got error: %v", err) - } + require.NoErrorf(t, Install(installer), "Expected installation to succeed") // Verify plugin was installed - if !isPlugin(installer.Path()) { - t.Errorf("Expected plugin directory %s to contain plugin.yaml", installer.Path()) - } + assert.Truef(t, isPlugin(installer.Path()), "Expected plugin directory %s to contain plugin.yaml", installer.Path()) // Test update when plugin exists - should succeed // For OCI, Update() removes old version and reinstalls - if err := Update(installer); err != nil { - t.Errorf("Expected update to succeed, got error: %v", err) - } + require.NoErrorf(t, Update(installer), "Expected update to succeed") // Verify plugin is still installed after update - if !isPlugin(installer.Path()) { - t.Errorf("Expected plugin directory %s to contain plugin.yaml after update", installer.Path()) - } + assert.Truef(t, isPlugin(installer.Path()), "Expected plugin directory %s to contain plugin.yaml after update", installer.Path()) } func TestOCIInstaller_Install_ComponentExtraction(t *testing.T) { @@ -513,35 +440,26 @@ func TestOCIInstaller_Install_ComponentExtraction(t *testing.T) { pluginData := createTestPluginTarGz(t, pluginName) // Test extraction - err := extractTarGz(bytes.NewReader(pluginData), tempDir) - if err != nil { - t.Fatalf("Failed to extract plugin: %v", err) - } + require.NoError(t, extractTarGz(bytes.NewReader(pluginData), tempDir), "Failed to extract plugin") // Verify plugin.yaml exists pluginYAMLPath := filepath.Join(tempDir, "plugin.yaml") - if _, err := os.Stat(pluginYAMLPath); os.IsNotExist(err) { - t.Error("plugin.yaml not found after extraction") - } + _, err := os.Stat(pluginYAMLPath) + assert.False(t, os.IsNotExist(err), "plugin.yaml not found after extraction") // Verify bin directory exists binPath := filepath.Join(tempDir, "bin") - if _, err := os.Stat(binPath); os.IsNotExist(err) { - t.Error("bin directory not found after extraction") - } + _, err = os.Stat(binPath) + assert.False(t, os.IsNotExist(err), "bin directory not found after extraction") // Verify executable exists and has correct permissions execPath := filepath.Join(tempDir, "bin", pluginName) - if info, err := os.Stat(execPath); err != nil { - t.Errorf("executable not found: %v", err) - } else if info.Mode()&0o111 == 0 { - t.Error("file is not executable") - } + info, err := os.Stat(execPath) + require.NoError(t, err, "executable not found") + assert.NotEqual(t, 0, info.Mode()&0o111, "file is not executable") // Verify this would be recognized as a plugin - if !isPlugin(tempDir) { - t.Error("extracted directory is not a valid plugin") - } + assert.True(t, isPlugin(tempDir), "extracted directory is not a valid plugin") } func TestExtractTarGz(t *testing.T) { @@ -561,13 +479,10 @@ func TestExtractTarGz(t *testing.T) { Typeflag: tar.TypeReg, } - if err := tarWriter.WriteHeader(header); err != nil { - t.Fatal(err) - } + require.NoError(t, tarWriter.WriteHeader(header)) - if _, err := tarWriter.Write([]byte(testContent)); err != nil { - t.Fatal(err) - } + _, err := tarWriter.Write([]byte(testContent)) + require.NoError(t, err) // Add a test directory dirHeader := &tar.Header{ @@ -576,35 +491,25 @@ func TestExtractTarGz(t *testing.T) { Typeflag: tar.TypeDir, } - if err := tarWriter.WriteHeader(dirHeader); err != nil { - t.Fatal(err) - } + require.NoError(t, tarWriter.WriteHeader(dirHeader)) tarWriter.Close() gzWriter.Close() // Test extraction - err := extractTarGz(bytes.NewReader(buf.Bytes()), tempDir) - if err != nil { - t.Errorf("extractTarGz failed: %v", err) - } + require.NoError(t, extractTarGz(bytes.NewReader(buf.Bytes()), tempDir), "extractTarGz failed") // Verify extracted file extractedFile := filepath.Join(tempDir, "test-file.txt") content, err := os.ReadFile(extractedFile) - if err != nil { - t.Errorf("failed to read extracted file: %v", err) - } + require.NoError(t, err, "failed to read extracted file") - if string(content) != testContent { - t.Errorf("expected content %s, got %s", testContent, string(content)) - } + assert.Equal(t, testContent, string(content), "expected content %s, got %s", testContent, string(content)) // Verify extracted directory extractedDir := filepath.Join(tempDir, "test-dir") - if _, err := os.Stat(extractedDir); os.IsNotExist(err) { - t.Errorf("extracted directory does not exist: %s", extractedDir) - } + _, err = os.Stat(extractedDir) + assert.Falsef(t, os.IsNotExist(err), "extracted directory does not exist: %s", extractedDir) } func TestExtractTarGz_InvalidGzip(t *testing.T) { @@ -612,10 +517,7 @@ func TestExtractTarGz_InvalidGzip(t *testing.T) { // Test with invalid gzip data invalidGzipData := []byte("not gzip data") - err := extractTarGz(bytes.NewReader(invalidGzipData), tempDir) - if err == nil { - t.Error("expected error for invalid gzip data") - } + assert.Error(t, extractTarGz(bytes.NewReader(invalidGzipData), tempDir), "expected error for invalid gzip data") } func TestExtractTar_UnknownFileType(t *testing.T) { @@ -634,13 +536,10 @@ func TestExtractTar_UnknownFileType(t *testing.T) { Typeflag: tar.TypeReg, } - if err := tarWriter.WriteHeader(header); err != nil { - t.Fatal(err) - } + require.NoError(t, tarWriter.WriteHeader(header)) - if _, err := tarWriter.Write([]byte(testContent)); err != nil { - t.Fatal(err) - } + _, err := tarWriter.Write([]byte(testContent)) + require.NoError(t, err) // Test unknown file type unknownHeader := &tar.Header{ @@ -649,21 +548,12 @@ func TestExtractTar_UnknownFileType(t *testing.T) { Typeflag: tar.TypeSymlink, // Use a type that's not handled } - if err := tarWriter.WriteHeader(unknownHeader); err != nil { - t.Fatal(err) - } + require.NoError(t, tarWriter.WriteHeader(unknownHeader)) tarWriter.Close() // Test extraction - should fail due to unknown type - err := extractTar(bytes.NewReader(buf.Bytes()), tempDir) - if err == nil { - t.Error("expected error for unknown tar file type") - } - - if !strings.Contains(err.Error(), "unknown type") { - t.Errorf("expected 'unknown type' error, got: %v", err) - } + assert.ErrorContains(t, extractTar(bytes.NewReader(buf.Bytes()), tempDir), "unknown type") } func TestExtractTar_SuccessfulExtraction(t *testing.T) { @@ -686,32 +576,22 @@ func TestExtractTar_SuccessfulExtraction(t *testing.T) { Typeflag: tar.TypeReg, } - if err := tarWriter.WriteHeader(header); err != nil { - t.Fatal(err) - } + require.NoError(t, tarWriter.WriteHeader(header)) - if _, err := tarWriter.Write([]byte(testContent)); err != nil { - t.Fatal(err) - } + _, err := tarWriter.Write([]byte(testContent)) + require.NoError(t, err) tarWriter.Close() // Test extraction - err := extractTar(bytes.NewReader(buf.Bytes()), tempDir) - if err != nil { - t.Errorf("extractTar failed: %v", err) - } + require.NoError(t, extractTar(bytes.NewReader(buf.Bytes()), tempDir), "extractTar failed") // Verify the regular file was extracted extractedFile := filepath.Join(tempDir, "test-file.txt") content, err := os.ReadFile(extractedFile) - if err != nil { - t.Errorf("failed to read extracted file: %v", err) - } + require.NoError(t, err, "failed to read extracted file") - if string(content) != testContent { - t.Errorf("expected content %s, got %s", testContent, string(content)) - } + assert.Equal(t, testContent, string(content), "expected content %s, got %s", testContent, string(content)) } func TestOCIInstaller_Install_PlainHTTPOption(t *testing.T) { @@ -720,41 +600,25 @@ func TestOCIInstaller_Install_PlainHTTPOption(t *testing.T) { // Test with PlainHTTP=false (default) installer1, err := NewOCIInstaller(source) - if err != nil { - t.Fatalf("failed to create installer: %v", err) - } - if installer1.getter == nil { - t.Error("getter should be initialized") - } + require.NoError(t, err, "failed to create installer") + assert.NotNil(t, installer1.getter, "getter should be initialized") // Test with PlainHTTP=true installer2, err := NewOCIInstaller(source, getter.WithPlainHTTP(true)) - if err != nil { - t.Fatalf("failed to create installer with PlainHTTP=true: %v", err) - } - if installer2.getter == nil { - t.Error("getter should be initialized with PlainHTTP=true") - } + require.NoError(t, err, "failed to create installer with PlainHTTP=true") + assert.NotNil(t, installer2.getter, "getter should be initialized with PlainHTTP=true") // Both installers should have the same basic properties - if installer1.PluginName != installer2.PluginName { - t.Error("plugin names should match") - } - if installer1.Source != installer2.Source { - t.Error("sources should match") - } + assert.Equal(t, installer2.PluginName, installer1.PluginName, "plugin names should match") + assert.Equal(t, installer2.Source, installer1.Source, "sources should match") // Test with multiple options installer3, err := NewOCIInstaller(source, getter.WithPlainHTTP(true), getter.WithBasicAuth("user", "pass"), ) - if err != nil { - t.Fatalf("failed to create installer with multiple options: %v", err) - } - if installer3.getter == nil { - t.Error("getter should be initialized with multiple options") - } + require.NoError(t, err, "failed to create installer with multiple options") + assert.NotNil(t, installer3.getter, "getter should be initialized with multiple options") } func TestOCIInstaller_Install_ValidationErrors(t *testing.T) { @@ -789,12 +653,8 @@ func TestOCIInstaller_Install_ValidationErrors(t *testing.T) { // Test the gzip validation logic that's used in the Install method if len(tt.layerData) < 2 || tt.layerData[0] != 0x1f || tt.layerData[1] != 0x8b { // This matches the validation in the Install method - if !tt.expectError { - t.Error("expected valid gzip data") - } - if !strings.Contains(tt.errorMsg, "is not a gzip compressed archive") { - t.Error("expected error message to contain 'is not a gzip compressed archive'") - } + assert.True(t, tt.expectError, "expected valid gzip data") + assert.Contains(t, tt.errorMsg, "is not a gzip compressed archive") } }) } diff --git a/internal/plugin/installer/vcs_installer_test.go b/internal/plugin/installer/vcs_installer_test.go index 7e44cc957..3f5b098e4 100644 --- a/internal/plugin/installer/vcs_installer_test.go +++ b/internal/plugin/installer/vcs_installer_test.go @@ -23,6 +23,7 @@ import ( "testing" "github.com/Masterminds/vcs" + "github.com/stretchr/testify/require" "helm.sh/helm/v4/internal/test/ensure" "helm.sh/helm/v4/pkg/helmpath" @@ -52,9 +53,7 @@ func (r *testRepo) UpdateVersion(version string) error { func TestVCSInstaller(t *testing.T) { ensure.HelmHome(t) - if err := os.MkdirAll(helmpath.DataPath("plugins"), 0o755); err != nil { - t.Fatalf("Could not create %s: %s", helmpath.DataPath("plugins"), err) - } + require.NoErrorf(t, os.MkdirAll(helmpath.DataPath("plugins"), 0o755), "Could not create %s", helmpath.DataPath("plugins")) source := "https://github.com/adamreese/helm-env" testRepoPath, _ := filepath.Abs("../testdata/plugdir/good/echo-v1") @@ -64,43 +63,27 @@ func TestVCSInstaller(t *testing.T) { } i, err := NewForSource(source, "~0.1.0") - if err != nil { - t.Fatalf("unexpected error: %s", err) - } + require.NoError(t, err) // ensure a VCSInstaller was returned vcsInstaller, ok := i.(*VCSInstaller) - if !ok { - t.Fatal("expected a VCSInstaller") - } + require.True(t, ok, "expected a VCSInstaller") // set the testRepo in the VCSInstaller vcsInstaller.Repo = repo - if err := Install(i); err != nil { - t.Fatal(err) - } - if repo.current != "0.1.1" { - t.Fatalf("expected version '0.1.1', got %q", repo.current) - } + require.NoError(t, Install(i)) + require.Equal(t, "0.1.1", repo.current, "expected version '0.1.1', got %q", repo.current) expectedPath := helmpath.DataPath("plugins", "helm-env") - if i.Path() != expectedPath { - t.Fatalf("expected path %q, got %q", expectedPath, i.Path()) - } + require.Equal(t, expectedPath, i.Path(), "expected path %q, got %q", expectedPath, i.Path()) // Install again to test plugin exists error - if err := Install(i); err == nil { - t.Fatal("expected error for plugin exists, got none") - } else if err.Error() != "plugin already exists" { - t.Fatalf("expected error for plugin exists, got (%v)", err) - } + require.EqualErrorf(t, Install(i), "plugin already exists", "expected error for plugin exists") // Testing FindSource method, expect error because plugin code is not a cloned repository - if _, err := FindSource(i.Path()); err == nil { - t.Fatal("expected error for inability to find plugin source, got none") - } else if err.Error() != "cannot get information about plugin source" { - t.Fatalf("expected error for inability to find plugin source, got (%v)", err) - } + _, err = FindSource(i.Path()) + require.Error(t, err, "expected error for inability to find plugin source, got none") + require.EqualErrorf(t, err, "cannot get information about plugin source", "expected error for inability to find plugin source") } func TestVCSInstallerNonExistentVersion(t *testing.T) { @@ -110,21 +93,18 @@ func TestVCSInstallerNonExistentVersion(t *testing.T) { version := "0.2.0" i, err := NewForSource(source, version) - if err != nil { - t.Fatalf("unexpected error: %s", err) - } + require.NoError(t, err) // ensure a VCSInstaller was returned - if _, ok := i.(*VCSInstaller); !ok { - t.Fatal("expected a VCSInstaller") - } + _, ok := i.(*VCSInstaller) + require.True(t, ok, "expected a VCSInstaller") if err := Install(i); err == nil { t.Fatal("expected error for version does not exists, got none") } else if strings.Contains(err.Error(), "Could not resolve host: github.com") { t.Skip("Unable to run test without Internet access") - } else if err.Error() != fmt.Sprintf("requested version %q does not exist for plugin %q", version, source) { - t.Fatalf("expected error for version does not exists, got (%v)", err) + } else { + require.EqualErrorf(t, err, fmt.Sprintf("requested version %q does not exist for plugin %q", version, source), "expected error for version does not exists") } } func TestVCSInstallerUpdate(t *testing.T) { @@ -133,20 +113,13 @@ func TestVCSInstallerUpdate(t *testing.T) { source := "https://github.com/adamreese/helm-env" i, err := NewForSource(source, "") - if err != nil { - t.Fatalf("unexpected error: %s", err) - } + require.NoError(t, err) // ensure a VCSInstaller was returned - if _, ok := i.(*VCSInstaller); !ok { - t.Fatal("expected a VCSInstaller") - } + _, ok := i.(*VCSInstaller) + require.True(t, ok, "expected a VCSInstaller") - if err := Update(i); err == nil { - t.Fatal("expected error for plugin does not exist, got none") - } else if err.Error() != "plugin does not exist" { - t.Fatalf("expected error for plugin does not exist, got (%v)", err) - } + require.EqualErrorf(t, Update(i), "plugin does not exist", "expected error for plugin does not exist") // Install plugin before update if err := Install(i); err != nil { @@ -159,30 +132,18 @@ func TestVCSInstallerUpdate(t *testing.T) { // Test FindSource method for positive result pluginInfo, err := FindSource(i.Path()) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) vcsInstaller := pluginInfo.(*VCSInstaller) repoRemote := vcsInstaller.Repo.Remote() - if repoRemote != source { - t.Fatalf("invalid source found, expected %q got %q", source, repoRemote) - } + require.Equal(t, source, repoRemote, "invalid source found, expected %q got %q", source, repoRemote) // Update plugin - if err := Update(i); err != nil { - t.Fatal(err) - } + require.NoError(t, Update(i)) // Test update failure - if err := os.Remove(filepath.Join(vcsInstaller.Repo.LocalPath(), "plugin.yaml")); err != nil { - t.Fatal(err) - } + require.NoError(t, os.Remove(filepath.Join(vcsInstaller.Repo.LocalPath(), "plugin.yaml"))) // Testing update for error - if err := Update(vcsInstaller); err == nil { - t.Fatal("expected error for plugin modified, got none") - } else if err.Error() != "plugin repo was modified" { - t.Fatalf("expected error for plugin modified, got (%v)", err) - } + require.EqualErrorf(t, Update(vcsInstaller), "plugin repo was modified", "expected error for plugin modified") } From f3402c1cd69b84d278af5a30551e376d727d27c1 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 20:50:57 +0200 Subject: [PATCH 15/61] chore(internal): refactor: convert tests to testify assert/require part 6 refactor: convert tests to testify assert/require in internal/plugin Signed-off-by: Matthieu MOREL --- .../chart/v3/lint/rules/deprecations_test.go | 2 +- internal/chart/v3/lint/rules/values_test.go | 5 ++-- internal/chart/v3/util/validate_name_test.go | 28 ++++++++++--------- internal/fileutil/fileutil_test.go | 12 +++----- internal/logging/logging_test.go | 6 ++-- internal/plugin/installer/base_test.go | 6 ++-- internal/plugin/loader_test.go | 8 ++---- internal/plugin/metadata_test.go | 10 +++---- internal/plugin/metadata_v1_test.go | 3 +- internal/plugin/plugin_test.go | 10 +++---- internal/release/v2/hook_test.go | 23 +++++++-------- internal/sympath/walk_test.go | 3 +- 12 files changed, 49 insertions(+), 67 deletions(-) diff --git a/internal/chart/v3/lint/rules/deprecations_test.go b/internal/chart/v3/lint/rules/deprecations_test.go index 920fdc31f..96462bc15 100644 --- a/internal/chart/v3/lint/rules/deprecations_test.go +++ b/internal/chart/v3/lint/rules/deprecations_test.go @@ -32,7 +32,7 @@ func TestValidateNoDeprecations(t *testing.T) { require.Error(t, err, "Expected deprecated extension to be flagged") var depErr deprecatedAPIError require.ErrorAs(t, err, &depErr, "Expected error to be of type deprecatedAPIError") - require.NotEmpty(t, depErr.Message, "Expected error message to be non-blank: %v", err) + require.NotEmpty(t, depErr.Message, "Expected error message to be non-blank") assert.NoError(t, validateNoDeprecations(&k8sYamlStruct{ APIVersion: "v1", Kind: "Pod", diff --git a/internal/chart/v3/lint/rules/values_test.go b/internal/chart/v3/lint/rules/values_test.go index c87607f2d..7f1177729 100644 --- a/internal/chart/v3/lint/rules/values_test.go +++ b/internal/chart/v3/lint/rules/values_test.go @@ -56,8 +56,7 @@ func TestValidateValuesYamlNotDirectory(t *testing.T) { _ = os.Mkdir(nonExistingValuesFilePath, os.ModePerm) defer os.Remove(nonExistingValuesFilePath) - err := validateValuesFileExistence(nonExistingValuesFilePath) - assert.Error(t, err, "validateValuesFileExistence to return a linter error, got no error") + assert.Error(t, validateValuesFileExistence(nonExistingValuesFilePath), "validateValuesFileExistence to return a linter error, got no error") } func TestValidateValuesFileWellFormed(t *testing.T) { @@ -150,7 +149,7 @@ func TestValidateValuesFile(t *testing.T) { require.NoError(t, err, "Failed validation") } else { require.Error(t, err, "expected values file to fail parsing") - assert.ErrorContains(t, err, tt.errorMessage, "Failed with unexpected error") + assert.ErrorContains(t, err, tt.errorMessage) } }) } diff --git a/internal/chart/v3/util/validate_name_test.go b/internal/chart/v3/util/validate_name_test.go index cfc62a0f7..3ea768db2 100644 --- a/internal/chart/v3/util/validate_name_test.go +++ b/internal/chart/v3/util/validate_name_test.go @@ -16,7 +16,11 @@ limitations under the License. package util -import "testing" +import ( + "testing" + + "github.com/stretchr/testify/assert" +) // TestValidateReleaseName is a regression test for ValidateName // @@ -46,12 +50,11 @@ func TestValidateReleaseName(t *testing.T) { "a1111111111111111111111111111111111111111111111111111111111z": false, } for input, expectPass := range names { - if err := ValidateReleaseName(input); (err == nil) != expectPass { - st := "fail" - if expectPass { - st = "succeed" - } - t.Errorf("Expected %q to %s", input, st) + err := ValidateReleaseName(input) + if expectPass { + assert.NoErrorf(t, err, "Expected release name %q to pass validation", input) + } else { + assert.Errorf(t, err, "Expected release name %q to fail validation, but it passed", input) } } } @@ -80,12 +83,11 @@ func TestValidateMetadataName(t *testing.T) { "a1111111111111111111111111111111111111111111111111111111111z": false, } for input, expectPass := range names { - if err := ValidateMetadataName(input); (err == nil) != expectPass { - st := "fail" - if expectPass { - st = "succeed" - } - t.Errorf("Expected %q to %s", input, st) + err := ValidateMetadataName(input) + if expectPass { + assert.NoError(t, err, "Expected %q to succeed", input) + } else { + assert.Error(t, err, "Expected %q to fail", input) } } } diff --git a/internal/fileutil/fileutil_test.go b/internal/fileutil/fileutil_test.go index 9c997fcd3..85dd51894 100644 --- a/internal/fileutil/fileutil_test.go +++ b/internal/fileutil/fileutil_test.go @@ -37,8 +37,7 @@ func TestAtomicWriteFile(t *testing.T) { reader := bytes.NewReader([]byte(stringContent)) mode := os.FileMode(0o644) - err := AtomicWriteFile(testpath, reader, mode) - require.NoError(t, err) + require.NoError(t, AtomicWriteFile(testpath, reader, mode)) got, err := os.ReadFile(testpath) require.NoError(t, err) @@ -58,8 +57,7 @@ func TestAtomicWriteFile_CreateTempError(t *testing.T) { reader := bytes.NewReader([]byte("test content")) mode := os.FileMode(0o644) - err := AtomicWriteFile(invalidPath, reader, mode) - assert.Error(t, err, "Expected error when CreateTemp fails") + assert.Error(t, AtomicWriteFile(invalidPath, reader, mode), "Expected error when CreateTemp fails") } // TestAtomicWriteFile_EmptyContent tests with empty content @@ -70,8 +68,7 @@ func TestAtomicWriteFile_EmptyContent(t *testing.T) { reader := bytes.NewReader([]byte("")) mode := os.FileMode(0o644) - err := AtomicWriteFile(testpath, reader, mode) - require.NoError(t, err, "AtomicWriteFile error with empty content") + require.NoError(t, AtomicWriteFile(testpath, reader, mode), "AtomicWriteFile error with empty content") got, err := os.ReadFile(testpath) require.NoError(t, err) @@ -89,8 +86,7 @@ func TestAtomicWriteFile_LargeContent(t *testing.T) { reader := bytes.NewReader([]byte(largeContent)) mode := os.FileMode(0o644) - err := AtomicWriteFile(testpath, reader, mode) - require.NoError(t, err, "AtomicWriteFile error with large content") + require.NoError(t, AtomicWriteFile(testpath, reader, mode), "AtomicWriteFile error with large content") got, err := os.ReadFile(testpath) require.NoError(t, err) diff --git a/internal/logging/logging_test.go b/internal/logging/logging_test.go index 83979e9db..1d6eaf852 100644 --- a/internal/logging/logging_test.go +++ b/internal/logging/logging_test.go @@ -197,9 +197,8 @@ func TestDebugCheckHandler_Handle(t *testing.T) { } record := slog.NewRecord(time.Now(), slog.LevelInfo, "test message", 0) - err := handler.Handle(t.Context(), record) - require.NoError(t, err) + require.NoError(t, handler.Handle(t.Context(), record)) assert.Contains(t, buf.String(), "test message") }) @@ -214,9 +213,8 @@ func TestDebugCheckHandler_Handle(t *testing.T) { type testKey string ctx := context.WithValue(t.Context(), testKey("test"), "value") record := slog.NewRecord(time.Now(), slog.LevelInfo, "context test", 0) - err := handler.Handle(ctx, record) - require.NoError(t, err) + require.NoError(t, handler.Handle(ctx, record)) assert.Contains(t, buf.String(), "context test") }) } diff --git a/internal/plugin/installer/base_test.go b/internal/plugin/installer/base_test.go index b7902e699..8ef7ff588 100644 --- a/internal/plugin/installer/base_test.go +++ b/internal/plugin/installer/base_test.go @@ -15,6 +15,8 @@ package installer import ( "testing" + + "github.com/stretchr/testify/assert" ) func TestPath(t *testing.T) { @@ -38,8 +40,6 @@ func TestPath(t *testing.T) { t.Setenv("HELM_PLUGINS", tt.helmPluginsDir) baseIns := newBase(tt.source) baseInsPath := baseIns.Path() - if baseInsPath != tt.expectPath { - t.Errorf("expected name %s, got %s", tt.expectPath, baseInsPath) - } + assert.Equal(t, tt.expectPath, baseInsPath, "expected name %s, got %s", tt.expectPath, baseInsPath) } } diff --git a/internal/plugin/loader_test.go b/internal/plugin/loader_test.go index 4b98a6f83..e0682aed7 100644 --- a/internal/plugin/loader_test.go +++ b/internal/plugin/loader_test.go @@ -194,13 +194,9 @@ func TestDetectDuplicates(t *testing.T) { mockSubprocessCLIPlugin(t, "foo"), mockSubprocessCLIPlugin(t, "bar"), } - if err := detectDuplicates(plugs); err != nil { - t.Error("no duplicates in the first set") - } + require.NoError(t, detectDuplicates(plugs), "no duplicates in the first set") plugs = append(plugs, mockSubprocessCLIPlugin(t, "foo")) - if err := detectDuplicates(plugs); err == nil { - t.Error("duplicates in the second set") - } + assert.Error(t, detectDuplicates(plugs), "duplicates in the second set") } func TestLoadAllDir_Empty(t *testing.T) { diff --git a/internal/plugin/metadata_test.go b/internal/plugin/metadata_test.go index b4994cf68..9cfdbc83a 100644 --- a/internal/plugin/metadata_test.go +++ b/internal/plugin/metadata_test.go @@ -66,7 +66,7 @@ func TestValidatePluginData(t *testing.T) { t.Run(strconv.Itoa(i), func(t *testing.T) { err := item.plug.Metadata().Validate() if item.pass { - require.NoError(t, err, "failed to validate case %d: %s", i, err) + require.NoError(t, err, "failed to validate case %d", i) } else { require.Error(t, err, "expected case %d to fail", i) assert.ErrorContains(t, err, item.errString, "expected case %d error to contain %q", i, item.errString) @@ -97,8 +97,7 @@ func TestMetadataValidateVersion(t *testing.T) { t.Run(name, func(t *testing.T) { m := mockSubprocessCLIPlugin(t, "testplugin") m.metadata.Version = tc.version - err := m.Metadata().Validate() - assert.NoError(t, err) + assert.NoError(t, m.Metadata().Validate()) }) } @@ -106,8 +105,7 @@ func TestMetadataValidateVersion(t *testing.T) { t.Run(name, func(t *testing.T) { m := mockSubprocessCLIPlugin(t, "testplugin") m.metadata.Version = tc.version - err := m.Metadata().Validate() - assert.ErrorContains(t, err, "invalid plugin version") + assert.ErrorContains(t, m.Metadata().Validate(), "invalid plugin version") }) } } @@ -139,7 +137,7 @@ func TestMetadataValidateMultipleErrors(t *testing.T) { } for _, expectedErr := range expectedErrors { - assert.Contains(t, errStr, expectedErr, "expected error to contain %q, but got: %v", expectedErr, errStr) + require.ErrorContains(t, err, expectedErr) } // Verify that the error contains the correct number of error messages diff --git a/internal/plugin/metadata_v1_test.go b/internal/plugin/metadata_v1_test.go index 74c67178e..8a6f28705 100644 --- a/internal/plugin/metadata_v1_test.go +++ b/internal/plugin/metadata_v1_test.go @@ -77,8 +77,7 @@ func TestMetadataV1ValidateVersion(t *testing.T) { t.Run("invalid/"+name, func(t *testing.T) { m := base() m.Version = tc.version - err := m.Validate() - assert.ErrorContains(t, err, tc.errMsg) + assert.ErrorContains(t, m.Validate(), tc.errMsg) }) } } diff --git a/internal/plugin/plugin_test.go b/internal/plugin/plugin_test.go index 2e3f274f2..947792046 100644 --- a/internal/plugin/plugin_test.go +++ b/internal/plugin/plugin_test.go @@ -18,6 +18,8 @@ package plugin import ( "testing" + "github.com/stretchr/testify/assert" + "helm.sh/helm/v4/internal/plugin/schema" ) @@ -34,9 +36,7 @@ func TestValidPluginName(t *testing.T) { for name, pluginName := range validNames { t.Run("valid/"+name, func(t *testing.T) { - if !validPluginName.MatchString(pluginName) { - t.Errorf("expected %q to match validPluginName regex", pluginName) - } + assert.Truef(t, validPluginName.MatchString(pluginName), "expected %q to match validPluginName regex", pluginName) }) } @@ -52,9 +52,7 @@ func TestValidPluginName(t *testing.T) { for name, pluginName := range invalidNames { t.Run("invalid/"+name, func(t *testing.T) { - if validPluginName.MatchString(pluginName) { - t.Errorf("expected %q to not match validPluginName regex", pluginName) - } + assert.Falsef(t, validPluginName.MatchString(pluginName), "expected %q to not match validPluginName regex", pluginName) }) } } diff --git a/internal/release/v2/hook_test.go b/internal/release/v2/hook_test.go index 5a0867398..3e946825e 100644 --- a/internal/release/v2/hook_test.go +++ b/internal/release/v2/hook_test.go @@ -170,12 +170,12 @@ func TestHookExecutionUnmarshalJSON(t *testing.T) { err := json.Unmarshal([]byte(tt.input), &exec) if tt.wantErr { assert.Error(t, err) - return + } else { + require.NoError(t, err) + assert.Equal(t, tt.expected.StartedAt.Unix(), exec.StartedAt.Unix()) + assert.Equal(t, tt.expected.CompletedAt.Unix(), exec.CompletedAt.Unix()) + assert.Equal(t, tt.expected.Phase, exec.Phase) } - require.NoError(t, err) - assert.Equal(t, tt.expected.StartedAt.Unix(), exec.StartedAt.Unix()) - assert.Equal(t, tt.expected.CompletedAt.Unix(), exec.CompletedAt.Unix()) - assert.Equal(t, tt.expected.Phase, exec.Phase) }) } } @@ -194,8 +194,7 @@ func TestHookExecutionRoundTrip(t *testing.T) { require.NoError(t, err) var decoded HookExecution - err = json.Unmarshal(data, &decoded) - require.NoError(t, err) + require.NoError(t, json.Unmarshal(data, &decoded)) assert.Equal(t, original.StartedAt.Unix(), decoded.StartedAt.Unix()) assert.Equal(t, original.CompletedAt.Unix(), decoded.CompletedAt.Unix()) @@ -208,12 +207,11 @@ func TestHookExecutionEmptyStringRoundTrip(t *testing.T) { input := `{"started_at":"","completed_at":"","phase":"Succeeded"}` var exec HookExecution - err := json.Unmarshal([]byte(input), &exec) - require.NoError(t, err) + require.NoError(t, json.Unmarshal([]byte(input), &exec)) // Verify time fields are zero values - assert.True(t, exec.StartedAt.IsZero()) - assert.True(t, exec.CompletedAt.IsZero()) + assert.Zero(t, exec.StartedAt) + assert.Zero(t, exec.CompletedAt) assert.Equal(t, HookPhaseSucceeded, exec.Phase) // Marshal back and verify empty time fields are omitted @@ -221,8 +219,7 @@ func TestHookExecutionEmptyStringRoundTrip(t *testing.T) { require.NoError(t, err) var result map[string]any - err = json.Unmarshal(data, &result) - require.NoError(t, err) + require.NoError(t, json.Unmarshal(data, &result)) // Zero time values should be omitted assert.NotContains(t, result, "started_at") diff --git a/internal/sympath/walk_test.go b/internal/sympath/walk_test.go index 76ed39cac..5dd051e4d 100644 --- a/internal/sympath/walk_test.go +++ b/internal/sympath/walk_test.go @@ -132,8 +132,7 @@ func TestWalk(t *testing.T) { return mark(info, err, &errors, true) } // Expect no errors. - err := Walk(tree.name, markFn) - require.NoError(t, err) + require.NoError(t, Walk(tree.name, markFn)) require.Empty(t, errors, "unexpected errors") checkMarks(t, true) From f1d5979e7d8b9d1e36b3cf703d150e8078c2e16e Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 20:50:56 +0200 Subject: [PATCH 16/61] chore(internal): refactor: convert tests to testify assert/require part 5 refactor: convert tests to testify assert/require in internal/plugin/installer Signed-off-by: Matthieu MOREL --- internal/chart/v3/lint/rules/template_test.go | 27 ++- .../chart/v3/lint/support/message_test.go | 29 +-- internal/chart/v3/util/chartfile_test.go | 27 +-- internal/plugin/installer/installer_test.go | 26 +-- .../plugin/installer/plugin_structure_test.go | 31 +-- .../plugin/installer/verification_test.go | 181 +++++------------- internal/plugin/runtime_extismv1_test.go | 3 +- internal/plugin/subprocess_commands_test.go | 28 +-- internal/plugin/verify_test.go | 26 +-- 9 files changed, 118 insertions(+), 260 deletions(-) diff --git a/internal/chart/v3/lint/rules/template_test.go b/internal/chart/v3/lint/rules/template_test.go index 0b83e1cd5..b4fa2d311 100644 --- a/internal/chart/v3/lint/rules/template_test.go +++ b/internal/chart/v3/lint/rules/template_test.go @@ -37,13 +37,11 @@ const templateTestBasedir = "./testdata/albatross" func TestValidateAllowedExtension(t *testing.T) { var failTest = []string{"/foo", "/test.toml"} for _, test := range failTest { - err := validateAllowedExtension(test) - require.ErrorContains(t, err, "Valid extensions are .yaml, .yml, .tpl, or .txt", "validateAllowedExtension('%s') to return \"Valid extensions are .yaml, .yml, .tpl, or .txt\", got no error", test) + require.ErrorContains(t, validateAllowedExtension(test), "Valid extensions are .yaml, .yml, .tpl, or .txt", "validateAllowedExtension('%s') to return \"Valid extensions are .yaml, .yml, .tpl, or .txt\", got no error", test) } var successTest = []string{"/foo.yaml", "foo.yaml", "foo.tpl", "/foo/bar/baz.yaml", "NOTES.txt"} for _, test := range successTest { - err := validateAllowedExtension(test) - assert.NoError(t, err, "validateAllowedExtension('%s') to return no error", test) + assert.NoError(t, validateAllowedExtension(test), "validateAllowedExtension('%s') to return no error", test) } } @@ -58,8 +56,7 @@ func TestTemplateParsing(t *testing.T) { res := linter.Messages require.Len(t, res, 1, "Expected one error, got %d, %v", len(res), res) - - assert.ErrorContains(t, res[0].Err, "deliberateSyntaxError", "Unexpected error: %s", res[0]) + assert.ErrorContains(t, res[0].Err, "deliberateSyntaxError") } var wrongTemplatePath = filepath.Join(templateTestBasedir, "templates", "fail.yaml") @@ -86,7 +83,7 @@ func TestMultiTemplateFail(t *testing.T) { require.Len(t, res, 1, "Expected 1 error, got %d, %v", len(res), res) - assert.ErrorContains(t, res[0].Err, "object name does not conform to Kubernetes naming requirements", "Unexpected error: %s", res[0].Err) + assert.ErrorContains(t, res[0].Err, "object name does not conform to Kubernetes naming requirements") } func TestValidateMetadataName(t *testing.T) { @@ -292,8 +289,7 @@ spec: - name: nginx image: nginx:1.14.2 ` - err := validateMatchSelector(md, manifest) - require.NoError(t, err) + require.NoError(t, validateMatchSelector(md, manifest)) manifest = ` apiVersion: apps/v1 kind: Deployment @@ -315,8 +311,7 @@ spec: - name: nginx image: nginx:1.14.2 ` - err = validateMatchSelector(md, manifest) - require.NoError(t, err) + require.NoError(t, validateMatchSelector(md, manifest)) manifest = ` apiVersion: apps/v1 kind: Deployment @@ -335,8 +330,7 @@ spec: - name: nginx image: nginx:1.14.2 ` - err = validateMatchSelector(md, manifest) - assert.Error(t, err, "expected Deployment with no selector to fail") + assert.Error(t, validateMatchSelector(md, manifest), "expected Deployment with no selector to fail") } func TestValidateTopIndentLevel(t *testing.T) { @@ -349,8 +343,11 @@ func TestValidateTopIndentLevel(t *testing.T) { " apiVersion:foo": true, "\n\n apiVersion:foo\n\n": true, } { - if err := validateTopIndentLevel(doc); (err == nil) == shouldFail { - t.Errorf("Expected %t for %q", shouldFail, doc) + err := validateTopIndentLevel(doc) + if shouldFail { + assert.Errorf(t, err, "Expected %t for %q", shouldFail, doc) + } else { + assert.NoErrorf(t, err, "Expected %t for %q", shouldFail, doc) } } } diff --git a/internal/chart/v3/lint/support/message_test.go b/internal/chart/v3/lint/support/message_test.go index ce5b5e42e..4c3ed3a3f 100644 --- a/internal/chart/v3/lint/support/message_test.go +++ b/internal/chart/v3/lint/support/message_test.go @@ -19,6 +19,9 @@ package support import ( "errors" "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var errLint = errors.New("lint failed") @@ -47,33 +50,19 @@ func TestRunLinterRule(t *testing.T) { linter := Linter{} for _, test := range tests { isValid := linter.RunLinterRule(test.Severity, "chart", test.LintError) - if len(linter.Messages) != test.ExpectedMessages { - t.Errorf("RunLinterRule(%d, \"chart\", %v), linter.Messages should now have %d message, we got %d", test.Severity, test.LintError, test.ExpectedMessages, len(linter.Messages)) - } - - if linter.HighestSeverity != test.ExpectedHighestSeverity { - t.Errorf("RunLinterRule(%d, \"chart\", %v), linter.HighestSeverity should be %d, we got %d", test.Severity, test.LintError, test.ExpectedHighestSeverity, linter.HighestSeverity) - } - - if isValid != test.ExpectedReturn { - t.Errorf("RunLinterRule(%d, \"chart\", %v), should have returned %t but returned %t", test.Severity, test.LintError, test.ExpectedReturn, isValid) - } + assert.Lenf(t, linter.Messages, test.ExpectedMessages, "RunLinterRule(%d, \"chart\", %v), linter.Messages should now have %d message, we got %d", test.Severity, test.LintError, test.ExpectedMessages, len(linter.Messages)) + assert.Equalf(t, test.ExpectedHighestSeverity, linter.HighestSeverity, "RunLinterRule(%d, \"chart\", %v), linter.HighestSeverity should be %d, we got %d", test.Severity, test.LintError, test.ExpectedHighestSeverity, linter.HighestSeverity) + assert.Equalf(t, test.ExpectedReturn, isValid, "RunLinterRule(%d, \"chart\", %v), should have returned %t but returned %t", test.Severity, test.LintError, test.ExpectedReturn, isValid) } } func TestMessage(t *testing.T) { m := Message{ErrorSev, "Chart.yaml", errors.New("Foo")} - if m.Error() != "[ERROR] Chart.yaml: Foo" { - t.Errorf("Unexpected output: %s", m.Error()) - } + require.EqualErrorf(t, m, "[ERROR] Chart.yaml: Foo", "Unexpected output: %s", m.Error()) m = Message{WarningSev, "templates/", errors.New("Bar")} - if m.Error() != "[WARNING] templates/: Bar" { - t.Errorf("Unexpected output: %s", m.Error()) - } + require.EqualErrorf(t, m, "[WARNING] templates/: Bar", "Unexpected output: %s", m.Error()) m = Message{InfoSev, "templates/rc.yaml", errors.New("FooBar")} - if m.Error() != "[INFO] templates/rc.yaml: FooBar" { - t.Errorf("Unexpected output: %s", m.Error()) - } + assert.EqualErrorf(t, m, "[INFO] templates/rc.yaml: FooBar", "Unexpected output: %s", m.Error()) } diff --git a/internal/chart/v3/util/chartfile_test.go b/internal/chart/v3/util/chartfile_test.go index c791930c1..0cc8a66af 100644 --- a/internal/chart/v3/util/chartfile_test.go +++ b/internal/chart/v3/util/chartfile_test.go @@ -29,10 +29,7 @@ const testfile = "testdata/chartfiletest.yaml" func TestLoadChartfile(t *testing.T) { f, err := LoadChartfile(testfile) - if err != nil { - t.Errorf("Failed to open %s: %s", testfile, err) - return - } + require.NoErrorf(t, err, "Failed to open %s", testfile) verifyChartfile(t, f, "frobnitz") } @@ -64,13 +61,11 @@ func verifyChartfile(t *testing.T, f *chart.Metadata, name string) { require.Len(t, f.Annotations, 2, "Unexpected annotations") - if want, got := "extravalue", f.Annotations["extrakey"]; want != got { - t.Errorf("Want %q, but got %q", want, got) - } + want, got := "extravalue", f.Annotations["extrakey"] + assert.Equalf(t, want, got, "Want %q, but got %q", want, got) - if want, got := "anothervalue", f.Annotations["anotherkey"]; want != got { - t.Errorf("Want %q, but got %q", want, got) - } + want, got = "anothervalue", f.Annotations["anotherkey"] + assert.Equalf(t, want, got, "Want %q, but got %q", want, got) kk := []string{"frobnitz", "sprocket", "dodad"} for i, k := range f.Keywords { @@ -80,13 +75,9 @@ func verifyChartfile(t *testing.T, f *chart.Metadata, name string) { func TestIsChartDir(t *testing.T) { validChartDir, err := IsChartDir("testdata/frobnitz") - if !validChartDir { - t.Errorf("unexpected error while reading chart-directory: (%v)", err) - return - } + require.NoError(t, err, "while reading chart-directory") + require.True(t, validChartDir, "expected valid chart directory") validChartDir, err = IsChartDir("testdata") - if validChartDir || err == nil { - t.Error("expected error but did not get any") - return - } + require.Error(t, err) + require.False(t, validChartDir, "expected invalid chart directory") } diff --git a/internal/plugin/installer/installer_test.go b/internal/plugin/installer/installer_test.go index 50e8e1ee2..620afc183 100644 --- a/internal/plugin/installer/installer_test.go +++ b/internal/plugin/installer/installer_test.go @@ -15,33 +15,27 @@ limitations under the License. package installer -import "testing" +import ( + "testing" + + "github.com/stretchr/testify/assert" +) func TestIsRemoteHTTPArchive(t *testing.T) { srv := mockArchiveServer() defer srv.Close() source := srv.URL + "/plugins/fake-plugin-0.0.1.tar.gz" - if isRemoteHTTPArchive("/not/a/URL") { - t.Error("Expected non-URL to return false") - } + assert.False(t, isRemoteHTTPArchive("/not/a/URL"), "Expected non-URL to return false") // URLs with valid archive extensions are considered valid archives // even if the server is unreachable (optimization to avoid unnecessary HTTP requests) - if !isRemoteHTTPArchive("https://127.0.0.1:123/fake/plugin-1.2.3.tgz") { - t.Error("URL with .tgz extension should be considered a valid archive") - } + assert.True(t, isRemoteHTTPArchive("https://127.0.0.1:123/fake/plugin-1.2.3.tgz"), "URL with .tgz extension should be considered a valid archive") // Test with invalid extension and unreachable server - if isRemoteHTTPArchive("https://127.0.0.1:123/fake/plugin-1.2.3.notanarchive") { - t.Error("Bad URL without valid extension should not succeed") - } + assert.False(t, isRemoteHTTPArchive("https://127.0.0.1:123/fake/plugin-1.2.3.notanarchive"), "Bad URL without valid extension should not succeed") - if !isRemoteHTTPArchive(source) { - t.Errorf("Expected %q to be a valid archive URL", source) - } + assert.True(t, isRemoteHTTPArchive(source), "Expected %q to be a valid archive URL", source) - if isRemoteHTTPArchive(source + "-not-an-extension") { - t.Error("Expected media type match to fail") - } + assert.False(t, isRemoteHTTPArchive(source+"-not-an-extension"), "Expected media type match to fail") } diff --git a/internal/plugin/installer/plugin_structure_test.go b/internal/plugin/installer/plugin_structure_test.go index 182eb9bd8..187918a4b 100644 --- a/internal/plugin/installer/plugin_structure_test.go +++ b/internal/plugin/installer/plugin_structure_test.go @@ -19,6 +19,9 @@ import ( "os" "path/filepath" "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestDetectPluginRoot(t *testing.T) { @@ -73,26 +76,18 @@ func TestDetectPluginRoot(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { dir := t.TempDir() - if err := tt.setup(dir); err != nil { - t.Fatalf("Setup failed: %v", err) - } + require.NoErrorf(t, tt.setup(dir), "Setup failed") root, err := detectPluginRoot(dir) if tt.expectError { - if err == nil { - t.Error("Expected error but got none") - } + assert.Error(t, err) } else { - if err != nil { - t.Errorf("Unexpected error: %v", err) - } + require.NoError(t, err) expectedPath := dir if tt.expectRoot != "." { expectedPath = filepath.Join(dir, tt.expectRoot) } - if root != expectedPath { - t.Errorf("Expected root %s but got %s", expectedPath, root) - } + assert.Equal(t, expectedPath, root, "Expected root %s but got %s", expectedPath, root) } }) } @@ -145,20 +140,14 @@ description: test` for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { dir := t.TempDir() - if err := tt.setup(dir); err != nil { - t.Fatalf("Setup failed: %v", err) - } + require.NoErrorf(t, tt.setup(dir), "Setup failed") pluginRoot := filepath.Join(dir, tt.pluginRoot) err := validatePluginName(pluginRoot, tt.expectedName) if tt.expectError { - if err == nil { - t.Error("Expected error but got none") - } + assert.Error(t, err) } else { - if err != nil { - t.Errorf("Unexpected error: %v", err) - } + assert.NoError(t, err) } }) } diff --git a/internal/plugin/installer/verification_test.go b/internal/plugin/installer/verification_test.go index d3824a0fc..1f8aa7ef4 100644 --- a/internal/plugin/installer/verification_test.go +++ b/internal/plugin/installer/verification_test.go @@ -23,6 +23,9 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "helm.sh/helm/v4/internal/plugin" "helm.sh/helm/v4/internal/test/ensure" ) @@ -37,29 +40,20 @@ func TestInstallWithOptions_VerifyMissingProvenance(t *testing.T) { // Create local installer installer, err := NewLocalInstaller(pluginTgz) - if err != nil { - t.Fatalf("Failed to create installer: %v", err) - } + require.NoError(t, err, "Failed to create installer") defer os.RemoveAll(installer.Path()) // Install with verification enabled should fail when .prov is missing result, err := InstallWithOptions(installer, Options{Verify: true, Keyring: "dummy"}) // Should fail with a missing provenance error - if err == nil { - t.Fatal("Expected installation to fail when .prov file is missing and verification is enabled") - } - if !strings.Contains(err.Error(), "no provenance file") { - t.Errorf("Expected 'no provenance file' in error message, got: %v", err) - } - if result != nil { - t.Errorf("Expected nil verification result when .prov file is missing, got: %+v", result) - } + require.Error(t, err, "Expected installation to fail when .prov file is missing and verification is enabled") + require.ErrorContains(t, err, "no provenance file") + assert.Nil(t, result, "Expected nil verification result when .prov file is missing, got: %+v", result) // Plugin should NOT be installed - if _, err := os.Stat(installer.Path()); !os.IsNotExist(err) { - t.Error("Plugin should not be installed when verification fails due to missing .prov") - } + _, err = os.Stat(installer.Path()) + assert.True(t, os.IsNotExist(err), "Plugin should not be installed when verification fails due to missing .prov") } func TestInstallWithOptions_NoVerifyMissingProvenance(t *testing.T) { @@ -72,25 +66,18 @@ func TestInstallWithOptions_NoVerifyMissingProvenance(t *testing.T) { // Create local installer installer, err := NewLocalInstaller(pluginTgz) - if err != nil { - t.Fatalf("Failed to create installer: %v", err) - } + require.NoError(t, err, "Failed to create installer") defer os.RemoveAll(installer.Path()) // Install with verification explicitly disabled should succeed without .prov result, err := InstallWithOptions(installer, Options{Verify: false}) - if err != nil { - t.Fatalf("Expected installation to succeed with --verify=false, got error: %v", err) - } - if result != nil { - t.Errorf("Expected nil verification result when verification is disabled, got: %+v", result) - } + require.NoError(t, err, "Expected installation to succeed with --verify=false") + assert.Nil(t, result, "Expected nil verification result when verification is disabled, got: %+v", result) // Plugin should be installed - if _, err := os.Stat(installer.Path()); os.IsNotExist(err) { - t.Errorf("Plugin should be installed at %s", installer.Path()) - } + _, err = os.Stat(installer.Path()) + assert.Falsef(t, os.IsNotExist(err), "Plugin should be installed at %s", installer.Path()) } func TestInstallWithOptions_VerifyWithValidProvenance(t *testing.T) { @@ -110,9 +97,7 @@ func TestInstallWithOptions_VerifyWithValidProvenance(t *testing.T) { // Create local installer installer, err := NewLocalInstaller(pluginTgz) - if err != nil { - t.Fatalf("Failed to create installer: %v", err) - } + require.NoError(t, err, "Failed to create installer") defer os.RemoveAll(installer.Path()) // Install with verification enabled @@ -120,20 +105,13 @@ func TestInstallWithOptions_VerifyWithValidProvenance(t *testing.T) { result, err := InstallWithOptions(installer, Options{Verify: true, Keyring: keyring}) // Should fail due to invalid signature (empty keyring) but we test that it gets past the hash check - if err == nil { - t.Fatal("Expected installation to fail with empty keyring") - } - if !strings.Contains(err.Error(), "plugin verification failed") { - t.Errorf("Expected plugin verification failed error, got: %v", err) - } - if result != nil { - t.Errorf("Expected nil verification result when verification fails, got: %+v", result) - } + require.Error(t, err, "Expected installation to fail with empty keyring") + require.ErrorContains(t, err, "plugin verification failed") + assert.Nil(t, result, "Expected nil verification result when verification fails, got: %+v", result) // Plugin should not be installed due to verification failure - if _, err := os.Stat(installer.Path()); !os.IsNotExist(err) { - t.Error("Plugin should not be installed when verification fails") - } + _, err = os.Stat(installer.Path()) + assert.True(t, os.IsNotExist(err), "Plugin should not be installed when verification fails") } func TestInstallWithOptions_VerifyWithInvalidProvenance(t *testing.T) { @@ -154,32 +132,23 @@ func TestInstallWithOptions_VerifyWithInvalidProvenance(t *testing.T) { // Create local installer installer, err := NewLocalInstaller(pluginTgz) - if err != nil { - t.Fatalf("Failed to create installer: %v", err) - } + require.NoError(t, err, "Failed to create installer") defer os.RemoveAll(installer.Path()) // Install with verification enabled (should fail) result, err := InstallWithOptions(installer, Options{Verify: true, Keyring: keyring}) // Should fail with verification error - if err == nil { - t.Fatal("Expected installation with invalid .prov file to fail") - } - if result != nil { - t.Errorf("Expected nil verification result when verification fails, got: %+v", result) - } + require.Error(t, err, "Expected installation with invalid .prov file to fail") + assert.Nil(t, result, "Expected nil verification result when verification fails, got: %+v", result) // Should contain verification failure message expectedError := "plugin verification failed" - if !strings.Contains(err.Error(), expectedError) { - t.Errorf("Expected error message '%s', got: %s", expectedError, err.Error()) - } + require.ErrorContains(t, err, expectedError) // Plugin should not be installed - if _, err := os.Stat(installer.Path()); !os.IsNotExist(err) { - t.Error("Plugin should not be installed when verification fails") - } + _, err = os.Stat(installer.Path()) + assert.True(t, os.IsNotExist(err), "Plugin should not be installed when verification fails") } func TestInstallWithOptions_NoVerifyRequested(t *testing.T) { @@ -192,26 +161,19 @@ func TestInstallWithOptions_NoVerifyRequested(t *testing.T) { // Create local installer installer, err := NewLocalInstaller(pluginTgz) - if err != nil { - t.Fatalf("Failed to create installer: %v", err) - } + require.NoError(t, err, "Failed to create installer") defer os.RemoveAll(installer.Path()) // Install without verification (should succeed without any verification) result, err := InstallWithOptions(installer, Options{Verify: false}) // Should succeed with no verification - if err != nil { - t.Fatalf("Expected installation without verification to succeed, got error: %v", err) - } - if result != nil { - t.Errorf("Expected nil verification result when verification is disabled, got: %+v", result) - } + require.NoError(t, err, "Expected installation without verification to succeed") + assert.Nil(t, result, "Expected nil verification result when verification is disabled, got: %+v", result) // Plugin should be installed - if _, err := os.Stat(installer.Path()); os.IsNotExist(err) { - t.Errorf("Plugin should be installed at %s", installer.Path()) - } + _, err = os.Stat(installer.Path()) + assert.Falsef(t, os.IsNotExist(err), "Plugin should be installed at %s", installer.Path()) } func TestInstallWithOptions_VerifyDirectoryNotSupported(t *testing.T) { @@ -222,24 +184,16 @@ func TestInstallWithOptions_VerifyDirectoryNotSupported(t *testing.T) { // Create local installer for directory installer, err := NewLocalInstaller(pluginDir) - if err != nil { - t.Fatalf("Failed to create installer: %v", err) - } + require.NoError(t, err, "Failed to create installer") defer os.RemoveAll(installer.Path()) // Install with verification should fail (directories don't support verification) result, err := InstallWithOptions(installer, Options{Verify: true, Keyring: "dummy"}) // Should fail with verification not supported error - if err == nil { - t.Fatal("Expected installation to fail with verification not supported error") - } - if !strings.Contains(err.Error(), "--verify is only supported for plugin tarballs") { - t.Errorf("Expected verification not supported error, got: %v", err) - } - if result != nil { - t.Errorf("Expected nil verification result when verification fails, got: %+v", result) - } + require.Error(t, err, "Expected installation to fail with verification not supported error") + require.ErrorContains(t, err, "--verify is only supported for plugin tarballs") + assert.Nil(t, result, "Expected nil verification result when verification fails, got: %+v", result) } func TestInstallWithOptions_VerifyMismatchedProvenance(t *testing.T) { @@ -261,24 +215,16 @@ func TestInstallWithOptions_VerifyMismatchedProvenance(t *testing.T) { // Create local installer installer, err := NewLocalInstaller(pluginTgz) - if err != nil { - t.Fatalf("Failed to create installer: %v", err) - } + require.NoError(t, err, "Failed to create installer") defer os.RemoveAll(installer.Path()) // Install with verification should fail due to hash mismatch result, err := InstallWithOptions(installer, Options{Verify: true, Keyring: keyring}) // Should fail with verification error - if err == nil { - t.Fatal("Expected installation to fail with hash mismatch") - } - if !strings.Contains(err.Error(), "plugin verification failed") { - t.Errorf("Expected plugin verification failed error, got: %v", err) - } - if result != nil { - t.Errorf("Expected nil verification result when verification fails, got: %+v", result) - } + require.Error(t, err, "Expected installation to fail with hash mismatch") + require.ErrorContains(t, err, "plugin verification failed") + assert.Nil(t, result, "Expected nil verification result when verification fails, got: %+v", result) } func TestInstallWithOptions_VerifyProvenanceAccessError(t *testing.T) { @@ -291,9 +237,7 @@ func TestInstallWithOptions_VerifyProvenanceAccessError(t *testing.T) { // Create a .prov file but make it inaccessible (simulate permission error) provFile := pluginTgz + ".prov" - if err := os.WriteFile(provFile, []byte("test"), 0o000); err != nil { - t.Fatalf("Failed to create inaccessible provenance file: %v", err) - } + require.NoErrorf(t, os.WriteFile(provFile, []byte("test"), 0o000), "Failed to create inaccessible provenance file") defer os.Remove(provFile) // Create keyring @@ -302,27 +246,21 @@ func TestInstallWithOptions_VerifyProvenanceAccessError(t *testing.T) { // Create local installer installer, err := NewLocalInstaller(pluginTgz) - if err != nil { - t.Fatalf("Failed to create installer: %v", err) - } + require.NoError(t, err, "Failed to create installer") defer os.RemoveAll(installer.Path()) // Install with verification should fail due to access error result, err := InstallWithOptions(installer, Options{Verify: true, Keyring: keyring}) // Should fail with access error (either at stat level or during verification) - if err == nil { - t.Fatal("Expected installation to fail with provenance file access error") - } + require.Error(t, err, "Expected installation to fail with provenance file access error") // The error could be either "failed to access provenance file" or "plugin verification failed" // depending on when the permission error occurs if !strings.Contains(err.Error(), "failed to access provenance file") && !strings.Contains(err.Error(), "plugin verification failed") { t.Errorf("Expected provenance file access or verification error, got: %v", err) } - if result != nil { - t.Errorf("Expected nil verification result when verification fails, got: %+v", result) - } + assert.Nil(t, result, "Expected nil verification result when verification fails, got: %+v", result) } // Helper functions for test setup @@ -333,9 +271,7 @@ func createTestPluginDir(t *testing.T) string { // Create temporary directory with plugin structure tmpDir := t.TempDir() pluginDir := filepath.Join(tmpDir, "test-plugin") - if err := os.MkdirAll(pluginDir, 0o755); err != nil { - t.Fatalf("Failed to create plugin directory: %v", err) - } + require.NoErrorf(t, os.MkdirAll(pluginDir, 0o755), "Failed to create plugin directory") // Create plugin.yaml using the standardized v1 format pluginYaml := `apiVersion: v1 @@ -346,9 +282,7 @@ version: 1.0.0 runtimeConfig: platformCommand: - command: echo` - if err := os.WriteFile(filepath.Join(pluginDir, "plugin.yaml"), []byte(pluginYaml), 0o644); err != nil { - t.Fatalf("Failed to create plugin.yaml: %v", err) - } + require.NoErrorf(t, os.WriteFile(filepath.Join(pluginDir, "plugin.yaml"), []byte(pluginYaml), 0o644), "Failed to create plugin.yaml") return pluginDir } @@ -360,15 +294,10 @@ func createTarballFromPluginDir(t *testing.T, pluginDir string) string { tmpDir := filepath.Dir(pluginDir) tgzPath := filepath.Join(tmpDir, "test-plugin-1.0.0.tgz") tarFile, err := os.Create(tgzPath) - if err != nil { - t.Fatalf("Failed to create tarball file: %v", err) - } + require.NoError(t, err, "Failed to create tarball file") defer tarFile.Close() - if err := plugin.CreatePluginTarball(pluginDir, "test-plugin", tarFile); err != nil { - t.Fatalf("Failed to create tarball: %v", err) - } - + require.NoErrorf(t, plugin.CreatePluginTarball(pluginDir, "test-plugin", tarFile), "Failed to create tarball") return tgzPath } @@ -379,9 +308,7 @@ func createProvFile(t *testing.T, provFile, pluginTgz, hash string) { if hash == "" { // Calculate actual hash of the tarball for realistic testing data, err := os.ReadFile(pluginTgz) - if err != nil { - t.Fatalf("Failed to read tarball for hashing: %v", err) - } + require.NoError(t, err, "Failed to read tarball for hashing") hashSum := sha256.Sum256(data) hashStr = fmt.Sprintf("sha256:%x", hashSum) } else { @@ -404,9 +331,7 @@ Version: GnuPG v1 iQEcBAEBCAAGBQJktest... -----END PGP SIGNATURE----- `, hashStr) - if err := os.WriteFile(provFile, []byte(provContent), 0o644); err != nil { - t.Fatalf("Failed to create provenance file: %v", err) - } + require.NoErrorf(t, os.WriteFile(provFile, []byte(provContent), 0o644), "Failed to create provenance file") } func createProvFileInvalidFormat(t *testing.T, provFile string) { @@ -414,9 +339,7 @@ func createProvFileInvalidFormat(t *testing.T, provFile string) { // Create an invalid provenance file (not PGP signed format) invalidProv := "This is not a valid PGP signed message" - if err := os.WriteFile(provFile, []byte(invalidProv), 0o644); err != nil { - t.Fatalf("Failed to create invalid provenance file: %v", err) - } + require.NoErrorf(t, os.WriteFile(provFile, []byte(invalidProv), 0o644), "Failed to create invalid provenance file") } func createTestKeyring(t *testing.T) string { @@ -427,9 +350,7 @@ func createTestKeyring(t *testing.T) string { keyringPath := filepath.Join(tmpDir, "pubring.gpg") // Create empty keyring for testing - if err := os.WriteFile(keyringPath, []byte{}, 0o644); err != nil { - t.Fatalf("Failed to create test keyring: %v", err) - } + require.NoErrorf(t, os.WriteFile(keyringPath, []byte{}, 0o644), "Failed to create test keyring") return keyringPath } diff --git a/internal/plugin/runtime_extismv1_test.go b/internal/plugin/runtime_extismv1_test.go index 290d418ea..72a24d111 100644 --- a/internal/plugin/runtime_extismv1_test.go +++ b/internal/plugin/runtime_extismv1_test.go @@ -59,8 +59,7 @@ func buildLoadExtismPlugin(t *testing.T, dir string) pluginRaw { func TestRuntimeConfigExtismV1Validate(t *testing.T) { rc := RuntimeConfigExtismV1{} - err := rc.Validate() - assert.NoError(t, err, "expected no error for empty RuntimeConfigExtismV1") + assert.NoError(t, rc.Validate(), "expected no error for empty RuntimeConfigExtismV1") } func TestRuntimeExtismV1InvokePlugin(t *testing.T) { diff --git a/internal/plugin/subprocess_commands_test.go b/internal/plugin/subprocess_commands_test.go index 6aa0a7435..b2ac19c02 100644 --- a/internal/plugin/subprocess_commands_test.go +++ b/internal/plugin/subprocess_commands_test.go @@ -39,9 +39,7 @@ func TestPrepareCommand(t *testing.T) { cmd, args, err := PrepareCommands(platformCommand, true, []string{}, env) require.NoError(t, err) require.Equal(t, cmdMain, cmd, "Expected %q, got %q", cmdMain, cmd) - if !reflect.DeepEqual(args, cmdArgs) { - t.Fatalf("Expected %v, got %v", cmdArgs, args) - } + require.Truef(t, reflect.DeepEqual(args, cmdArgs), "Expected %v, got %v", cmdArgs, args) } func TestPrepareCommandExtraArgs(t *testing.T) { @@ -113,9 +111,7 @@ func TestPrepareCommands(t *testing.T) { cmd, args, err := PrepareCommands(cmds, true, []string{}, env) require.NoError(t, err) require.Equal(t, cmdMain, cmd, "Expected %q, got %q", cmdMain, cmd) - if !reflect.DeepEqual(args, cmdArgs) { - t.Fatalf("Expected %v, got %v", cmdArgs, args) - } + require.Truef(t, reflect.DeepEqual(args, cmdArgs), "Expected %v, got %v", cmdArgs, args) } func TestPrepareCommandsExtraArgs(t *testing.T) { @@ -136,9 +132,7 @@ func TestPrepareCommandsExtraArgs(t *testing.T) { cmd, args, err := PrepareCommands(cmds, true, extraArgs, env) require.NoError(t, err) require.Equal(t, cmdMain, cmd, "Expected %q, got %q", cmdMain, cmd) - if !reflect.DeepEqual(args, expectedArgs) { - t.Fatalf("Expected %v, got %v", expectedArgs, args) - } + require.Truef(t, reflect.DeepEqual(args, expectedArgs), "Expected %v, got %v", expectedArgs, args) } func TestPrepareCommandsNoArch(t *testing.T) { @@ -155,9 +149,7 @@ func TestPrepareCommandsNoArch(t *testing.T) { cmd, args, err := PrepareCommands(cmds, true, []string{}, env) require.NoError(t, err) require.Equal(t, cmdMain, cmd, "Expected %q, got %q", cmdMain, cmd) - if !reflect.DeepEqual(args, cmdArgs) { - t.Fatalf("Expected %v, got %v", cmdArgs, args) - } + require.Truef(t, reflect.DeepEqual(args, cmdArgs), "Expected %v, got %v", cmdArgs, args) } func TestPrepareCommandsNoOsNoArch(t *testing.T) { @@ -174,9 +166,7 @@ func TestPrepareCommandsNoOsNoArch(t *testing.T) { cmd, args, err := PrepareCommands(cmds, true, []string{}, env) require.NoError(t, err) require.Equal(t, cmdMain, cmd, "Expected %q, got %q", cmdMain, cmd) - if !reflect.DeepEqual(args, cmdArgs) { - t.Fatalf("Expected %v, got %v", cmdArgs, args) - } + require.Truef(t, reflect.DeepEqual(args, cmdArgs), "Expected %v, got %v", cmdArgs, args) } func TestPrepareCommandsNoMatch(t *testing.T) { @@ -216,9 +206,7 @@ func TestPrepareCommandsExpand(t *testing.T) { cmd, args, err := PrepareCommands(cmds, true, []string{}, env) require.NoError(t, err) require.Equal(t, cmdMain, cmd, "Expected %q, got %q", cmdMain, cmd) - if !reflect.DeepEqual(args, expectedArgs) { - t.Fatalf("Expected %v, got %v", expectedArgs, args) - } + require.Truef(t, reflect.DeepEqual(args, expectedArgs), "Expected %v, got %v", expectedArgs, args) } func TestPrepareCommandsNoExpand(t *testing.T) { @@ -235,7 +223,5 @@ func TestPrepareCommandsNoExpand(t *testing.T) { cmd, args, err := PrepareCommands(cmds, false, []string{}, env) require.NoError(t, err) require.Equal(t, cmdMain, cmd, "Expected %q, got %q", cmdMain, cmd) - if !reflect.DeepEqual(args, cmdArgs) { - t.Fatalf("Expected %v, got %v", cmdArgs, args) - } + require.Truef(t, reflect.DeepEqual(args, cmdArgs), "Expected %v, got %v", cmdArgs, args) } diff --git a/internal/plugin/verify_test.go b/internal/plugin/verify_test.go index 5721e0414..4f5b26a97 100644 --- a/internal/plugin/verify_test.go +++ b/internal/plugin/verify_test.go @@ -44,11 +44,9 @@ func TestVerifyPlugin(t *testing.T) { // Create plugin directory pluginDir := filepath.Join(tempDir, "verify-test-plugin") - err := os.MkdirAll(pluginDir, 0o755) - require.NoError(t, err) + require.NoError(t, os.MkdirAll(pluginDir, 0o755)) - err = os.WriteFile(filepath.Join(pluginDir, "plugin.yaml"), []byte(testPluginYAML), 0o644) - require.NoError(t, err) + require.NoError(t, os.WriteFile(filepath.Join(pluginDir, "plugin.yaml"), []byte(testPluginYAML), 0o644)) // Create tarball tarballPath := filepath.Join(tempDir, "verify-test-plugin.tar.gz") @@ -64,10 +62,9 @@ func TestVerifyPlugin(t *testing.T) { // Sign the plugin with source directory signer, err := provenance.NewFromKeyring(testKeyFile, "helm-test") require.NoError(t, err) - err = signer.DecryptKey(func(_ string) ([]byte, error) { + require.NoError(t, signer.DecryptKey(func(_ string) ([]byte, error) { return []byte(""), nil - }) - require.NoError(t, err) + })) // Read the tarball data tarballData, err := os.ReadFile(tarballPath) @@ -78,8 +75,7 @@ func TestVerifyPlugin(t *testing.T) { // Write the signature to .prov file provFile := tarballPath + ".prov" - err = os.WriteFile(provFile, []byte(sig), 0o644) - require.NoError(t, err) + require.NoError(t, os.WriteFile(provFile, []byte(sig), 0o644)) // Read the files for verification archiveData, err := os.ReadFile(tarballPath) @@ -105,11 +101,9 @@ func TestVerifyPluginBadSignature(t *testing.T) { // Create a plugin tarball pluginDir := filepath.Join(tempDir, "bad-plugin") - err := os.MkdirAll(pluginDir, 0o755) - require.NoError(t, err) + require.NoError(t, os.MkdirAll(pluginDir, 0o755)) - err = os.WriteFile(filepath.Join(pluginDir, "plugin.yaml"), []byte(testPluginYAML), 0o644) - require.NoError(t, err) + require.NoError(t, os.WriteFile(filepath.Join(pluginDir, "plugin.yaml"), []byte(testPluginYAML), 0o644)) tarballPath := filepath.Join(tempDir, "bad-plugin.tar.gz") tarFile, err := os.Create(tarballPath) @@ -133,8 +127,7 @@ InvalidSignatureData -----END PGP SIGNATURE-----` provFile := tarballPath + ".prov" - err = os.WriteFile(provFile, []byte(badSig), 0o644) - require.NoError(t, err) + require.NoError(t, os.WriteFile(provFile, []byte(badSig), 0o644)) // Read the files archiveData, err := os.ReadFile(tarballPath) @@ -153,8 +146,7 @@ func TestVerifyPluginMissingProvenance(t *testing.T) { tarballPath := filepath.Join(tempDir, "no-prov.tar.gz") // Create a minimal tarball - err := os.WriteFile(tarballPath, []byte("dummy"), 0o644) - require.NoError(t, err) + require.NoError(t, os.WriteFile(tarballPath, []byte("dummy"), 0o644)) // Read the tarball data archiveData, err := os.ReadFile(tarballPath) From 668e7e580a01dbf66da0f620da6b980ee0cb4d80 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 20:50:57 +0200 Subject: [PATCH 17/61] chore(internal): refactor: convert tests to testify assert/require part 3 refactor: convert tests to testify assert/require in internal Signed-off-by: Matthieu MOREL --- internal/chart/v3/dependency_test.go | 10 +- .../chart/v3/lint/rules/chartfile_test.go | 53 ++-- internal/chart/v3/util/expand_test.go | 40 +-- internal/third_party/dep/fs/fs_test.go | 262 +++++------------- 4 files changed, 112 insertions(+), 253 deletions(-) diff --git a/internal/chart/v3/dependency_test.go b/internal/chart/v3/dependency_test.go index fcea19aea..54b9ed9da 100644 --- a/internal/chart/v3/dependency_test.go +++ b/internal/chart/v3/dependency_test.go @@ -17,6 +17,8 @@ package v3 import ( "testing" + + "github.com/stretchr/testify/assert" ) func TestValidateDependency(t *testing.T) { @@ -35,10 +37,10 @@ func TestValidateDependency(t *testing.T) { } { dep.Alias = value res := dep.Validate() - if res != nil && !shouldFail { - t.Errorf("Failed on case %q", dep.Alias) - } else if res == nil && shouldFail { - t.Errorf("Expected failure for %q", dep.Alias) + if shouldFail { + assert.Errorf(t, res, "Expected failure for %q", dep.Alias) + } else { + assert.NoErrorf(t, res, "Failed on case %q", dep.Alias) } } } diff --git a/internal/chart/v3/lint/rules/chartfile_test.go b/internal/chart/v3/lint/rules/chartfile_test.go index 9ac4ce75e..0638589b6 100644 --- a/internal/chart/v3/lint/rules/chartfile_test.go +++ b/internal/chart/v3/lint/rules/chartfile_test.go @@ -52,24 +52,19 @@ func TestValidateChartYamlNotDirectory(t *testing.T) { _ = os.Mkdir(nonExistingChartFilePath, os.ModePerm) defer os.Remove(nonExistingChartFilePath) - err := validateChartYamlNotDirectory(nonExistingChartFilePath) - assert.Error(t, err, "validateChartYamlNotDirectory to return a linter error, got no error") + assert.Error(t, validateChartYamlNotDirectory(nonExistingChartFilePath), "validateChartYamlNotDirectory to return a linter error, got no error") } func TestValidateChartYamlFormat(t *testing.T) { - err := validateChartYamlFormat(errors.New("Read error")) - require.Error(t, err, "validateChartYamlFormat to return a linter error, got no error") + require.Error(t, validateChartYamlFormat(errors.New("Read error")), "validateChartYamlFormat to return a linter error, got no error") - err = validateChartYamlFormat(nil) - assert.NoError(t, err, "validateChartYamlFormat to return no error, got a linter error") + assert.NoError(t, validateChartYamlFormat(nil), "validateChartYamlFormat to return no error, got a linter error") } func TestValidateChartName(t *testing.T) { - err := validateChartName(badChart) - require.Error(t, err, "validateChartName to return a linter error, got no error") + require.Error(t, validateChartName(badChart), "validateChartName to return a linter error, got no error") - err = validateChartName(badChartName) - assert.Error(t, err, "expected validateChartName to return a linter error for an invalid name, got no error") + assert.Error(t, validateChartName(badChartName), "expected validateChartName to return a linter error for an invalid name, got no error") } func TestValidateChartVersion(t *testing.T) { @@ -90,15 +85,13 @@ func TestValidateChartVersion(t *testing.T) { for i, test := range failTest { t.Run(strconv.Itoa(i), func(t *testing.T) { badChart.Version = test.Version - err := validateChartVersion(badChart) - require.ErrorContains(t, err, test.ErrorMsg, "validateChartVersion(%s) to return \"%s\", got no error", test.Version, test.ErrorMsg) + require.ErrorContains(t, validateChartVersion(badChart), test.ErrorMsg, "validateChartVersion(%s) to return \"%s\", got no error", test.Version, test.ErrorMsg) }) } for _, version := range successTest { badChart.Version = version - err := validateChartVersion(badChart) - assert.NoError(t, err, "validateChartVersion(%s) to return no error, got a linter error", version) + assert.NoError(t, validateChartVersion(badChart), "validateChartVersion(%s) to return no error, got a linter error", version) } } @@ -124,24 +117,20 @@ func TestValidateChartMaintainer(t *testing.T) { for _, test := range failTest { t.Run(fmt.Sprintf("%s, %s", test.Name, test.Email), func(t *testing.T) { badChart.Maintainers = []*chart.Maintainer{{Name: test.Name, Email: test.Email}} - err := validateChartMaintainer(badChart) - require.ErrorContains(t, err, test.ErrorMsg, "validateChartMaintainer(%s, %s) to return \"%s\", got no error", test.Name, test.Email, test.ErrorMsg) + require.ErrorContains(t, validateChartMaintainer(badChart), test.ErrorMsg, "validateChartMaintainer(%s, %s) to return \"%s\", got no error", test.Name, test.Email, test.ErrorMsg) }) } for _, test := range successTest { t.Run(fmt.Sprintf("%s, %s", test.Name, test.Email), func(t *testing.T) { badChart.Maintainers = []*chart.Maintainer{{Name: test.Name, Email: test.Email}} - err := validateChartMaintainer(badChart) - require.NoError(t, err, "validateChartMaintainer(%s, %s) to return no error", test.Name, test.Email) + require.NoError(t, validateChartMaintainer(badChart), "validateChartMaintainer(%s, %s) to return no error", test.Name, test.Email) }) } // Testing for an empty maintainer badChart.Maintainers = []*chart.Maintainer{nil} - err := validateChartMaintainer(badChart) - require.Error(t, err, "validateChartMaintainer did not return error for nil maintainer as expected") - assert.EqualError(t, err, "a maintainer entry is empty", "validateChartMaintainer returned unexpected error for nil maintainer") + assert.EqualError(t, validateChartMaintainer(badChart), "a maintainer entry is empty") } func TestValidateChartSources(t *testing.T) { @@ -150,15 +139,13 @@ func TestValidateChartSources(t *testing.T) { for _, test := range failTest { t.Run(test, func(t *testing.T) { badChart.Sources = []string{test} - err := validateChartSources(badChart) - require.ErrorContains(t, err, "invalid source URL", "validateChartSources(%s) to return \"invalid source URL\", got no error", test) + require.ErrorContains(t, validateChartSources(badChart), "invalid source URL", "validateChartSources(%s) to return \"invalid source URL\", got no error", test) }) } for _, test := range successTest { badChart.Sources = []string{test} - err := validateChartSources(badChart) - assert.NoError(t, err, "validateChartSources(%s) to return no error", test) + assert.NoError(t, validateChartSources(badChart), "validateChartSources(%s) to return no error", test) } } @@ -168,19 +155,13 @@ func TestValidateChartIconPresence(t *testing.T) { Icon: "", } - err := validateChartIconPresence(testChart) - - require.Error(t, err, "validateChartIconPresence to return a linter error, got no error") - assert.ErrorContains(t, err, "icon is recommended", "expected %q", "icon is recommended") + assert.ErrorContains(t, validateChartIconPresence(testChart), "icon is recommended", "expected %q", "icon is recommended") }) t.Run("Icon present", func(t *testing.T) { testChart := &chart.Metadata{ Icon: "http://example.org/icon.png", } - - err := validateChartIconPresence(testChart) - - assert.NoError(t, err, "Unexpected error") + assert.NoError(t, validateChartIconPresence(testChart)) }) } @@ -190,15 +171,13 @@ func TestValidateChartIconURL(t *testing.T) { for _, test := range failTest { t.Run(test, func(t *testing.T) { badChart.Icon = test - err := validateChartIconURL(badChart) - require.ErrorContains(t, err, "invalid icon URL", "validateChartIconURL(%s) to return \"invalid icon URL\", got no error", test) + require.ErrorContains(t, validateChartIconURL(badChart), "invalid icon URL", "validateChartIconURL(%s) to return \"invalid icon URL\", got no error", test) }) } for _, test := range successTest { badChart.Icon = test - err := validateChartIconURL(badChart) - assert.NoError(t, err, "validateChartIconURL(%s) to return no error", test) + assert.NoError(t, validateChartIconURL(badChart), "validateChartIconURL(%s) to return no error", test) } } diff --git a/internal/chart/v3/util/expand_test.go b/internal/chart/v3/util/expand_test.go index a7a756485..e6d66b74e 100644 --- a/internal/chart/v3/util/expand_test.go +++ b/internal/chart/v3/util/expand_test.go @@ -47,19 +47,19 @@ func makeTestChartArchive(t *testing.T, chartName, sourceDir string) *bytes.Buff fStat, err := f.Stat() require.NoError(t, err) - err = tw.WriteHeader(&tar.Header{ + require.NoError(t, tw.WriteHeader(&tar.Header{ Name: filepath.Join(chartName, relPath), Mode: int64(fStat.Mode()), Size: fStat.Size(), - }) - require.NoError(t, err) + })) data, err := fs.ReadFile(dir, relPath) require.NoError(t, err) - tw.Write(data) + _, err = tw.Write(data) + require.NoError(t, err) } - err := fs.WalkDir(dir, ".", func(path string, d os.DirEntry, walkErr error) error { + require.NoError(t, fs.WalkDir(dir, ".", func(path string, d os.DirEntry, walkErr error) error { if walkErr != nil { return walkErr } @@ -71,13 +71,10 @@ func makeTestChartArchive(t *testing.T, chartName, sourceDir string) *bytes.Buff writeFile(path) return nil - }) - require.NoError(t, err) + })) - err = tw.Close() - require.NoError(t, err) - err = gw.Close() - require.NoError(t, err) + require.NoError(t, tw.Close()) + require.NoError(t, gw.Close()) return &result } @@ -87,20 +84,18 @@ func TestExpand(t *testing.T) { reader, err := os.Open("testdata/frobnitz-1.2.3.tgz") require.NoError(t, err) + t.Cleanup(func() { assert.NoError(t, reader.Close()) }) - if err := Expand(dest, reader); err != nil { - t.Fatal(err) - } + require.NoError(t, Expand(dest, reader)) expectedChartPath := filepath.Join(dest, "frobnitz") fi, err := os.Stat(expectedChartPath) require.NoError(t, err) - if !fi.IsDir() { - t.Fatalf("expected a chart directory at %s", expectedChartPath) - } + require.Truef(t, fi.IsDir(), "expected a chart directory at %s", expectedChartPath) dir, err := os.Open(expectedChartPath) require.NoError(t, err) + t.Cleanup(func() { assert.NoError(t, dir.Close()) }) fis, err := dir.Readdir(0) require.NoError(t, err) @@ -137,8 +132,7 @@ func TestExpandError(t *testing.T) { archive := makeTestChartArchive(t, tt.chartName, tt.chartDir) dest := t.TempDir() - err := Expand(dest, archive) - assert.ErrorContains(t, err, tt.wantErr) + assert.ErrorContains(t, Expand(dest, archive), tt.wantErr) }) } } @@ -146,16 +140,12 @@ func TestExpandError(t *testing.T) { func TestExpandFile(t *testing.T) { dest := t.TempDir() - if err := ExpandFile(dest, "testdata/frobnitz-1.2.3.tgz"); err != nil { - t.Fatal(err) - } + require.NoError(t, ExpandFile(dest, "testdata/frobnitz-1.2.3.tgz")) expectedChartPath := filepath.Join(dest, "frobnitz") fi, err := os.Stat(expectedChartPath) require.NoError(t, err) - if !fi.IsDir() { - t.Fatalf("expected a chart directory at %s", expectedChartPath) - } + require.Truef(t, fi.IsDir(), "expected a chart directory at %s", expectedChartPath) dir, err := os.Open(expectedChartPath) require.NoError(t, err) diff --git a/internal/third_party/dep/fs/fs_test.go b/internal/third_party/dep/fs/fs_test.go index 797890f9f..d777b6af4 100644 --- a/internal/third_party/dep/fs/fs_test.go +++ b/internal/third_party/dep/fs/fs_test.go @@ -32,54 +32,41 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package fs import ( - "errors" "os" "path/filepath" "runtime" "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestRenameWithFallback(t *testing.T) { dir := t.TempDir() - if err := RenameWithFallback(filepath.Join(dir, "does_not_exists"), filepath.Join(dir, "dst")); err == nil { - t.Fatal("expected an error for non existing file, but got nil") - } + require.Error(t, RenameWithFallback(filepath.Join(dir, "does_not_exists"), filepath.Join(dir, "dst")), "expected an error for non existing file, but got nil") srcpath := filepath.Join(dir, "src") - if srcf, err := os.Create(srcpath); err != nil { - t.Fatal(err) - } else { - srcf.Close() - } + srcf, err := os.Create(srcpath) + require.NoError(t, err) + srcf.Close() - if err := RenameWithFallback(srcpath, filepath.Join(dir, "dst")); err != nil { - t.Fatal(err) - } + require.NoError(t, RenameWithFallback(srcpath, filepath.Join(dir, "dst"))) srcpath = filepath.Join(dir, "a") - if err := os.MkdirAll(srcpath, 0o777); err != nil { - t.Fatal(err) - } + require.NoError(t, os.MkdirAll(srcpath, 0o777)) dstpath := filepath.Join(dir, "b") - if err := os.MkdirAll(dstpath, 0o777); err != nil { - t.Fatal(err) - } - - if err := RenameWithFallback(srcpath, dstpath); err == nil { - t.Fatal("expected an error if dst is an existing directory, but got nil") - } + require.NoError(t, os.MkdirAll(dstpath, 0o777)) + require.Error(t, RenameWithFallback(srcpath, dstpath), "expected an error if dst is an existing directory, but got nil") } func TestCopyDir(t *testing.T) { dir := t.TempDir() srcdir := filepath.Join(dir, "src") - if err := os.MkdirAll(srcdir, 0o755); err != nil { - t.Fatal(err) - } + require.NoError(t, os.MkdirAll(srcdir, 0o755)) files := []struct { path string @@ -94,61 +81,40 @@ func TestCopyDir(t *testing.T) { for i, file := range files { fn := filepath.Join(srcdir, file.path) dn := filepath.Dir(fn) - if err := os.MkdirAll(dn, 0o755); err != nil { - t.Fatal(err) - } + require.NoError(t, os.MkdirAll(dn, 0o755)) fh, err := os.Create(fn) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if _, err = fh.WriteString(file.contents); err != nil { - t.Fatal(err) - } + _, err = fh.WriteString(file.contents) + require.NoError(t, err) fh.Close() files[i].fi, err = os.Stat(fn) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) } destdir := filepath.Join(dir, "dest") - if err := CopyDir(srcdir, destdir); err != nil { - t.Fatal(err) - } + require.NoError(t, CopyDir(srcdir, destdir)) // Compare copy against structure indicated in 'files' for _, file := range files { fn := filepath.Join(srcdir, file.path) dn := filepath.Dir(fn) dirOK, err := IsDir(dn) - if err != nil { - t.Fatal(err) - } - if !dirOK { - t.Fatalf("expected %s to be a directory", dn) - } + require.NoError(t, err) + require.Truef(t, dirOK, "expected %s to be a directory", dn) got, err := os.ReadFile(fn) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if file.contents != string(got) { - t.Fatalf("expected: %s, got: %s", file.contents, string(got)) - } + require.Equalf(t, file.contents, string(got), "expected: %s, got: %s", file.contents, string(got)) gotinfo, err := os.Stat(fn) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if file.fi.Mode() != gotinfo.Mode() { - t.Fatalf("expected %s: %#v\n to be the same mode as %s: %#v", - file.path, file.fi.Mode(), fn, gotinfo.Mode()) - } + require.Equalf(t, file.fi.Mode(), gotinfo.Mode(), "expected %s: %#v\n to be the same mode as %s: %#v", + file.path, file.fi.Mode(), fn, gotinfo.Mode()) } } @@ -178,9 +144,7 @@ func TestCopyDirFail_SrcInaccessible(t *testing.T) { dir := t.TempDir() dstdir = filepath.Join(dir, "dst") - if err := CopyDir(srcdir, dstdir); err == nil { - t.Fatalf("expected error for CopyDir(%s, %s), got none", srcdir, dstdir) - } + assert.Errorf(t, CopyDir(srcdir, dstdir), "expected error for CopyDir(%s, %s), got none", srcdir, dstdir) } func TestCopyDirFail_DstInaccessible(t *testing.T) { @@ -203,9 +167,7 @@ func TestCopyDirFail_DstInaccessible(t *testing.T) { dir := t.TempDir() srcdir = filepath.Join(dir, "src") - if err := os.MkdirAll(srcdir, 0o755); err != nil { - t.Fatal(err) - } + require.NoError(t, os.MkdirAll(srcdir, 0o755)) cleanup := setupInaccessibleDir(t, func(dir string) error { dstdir = filepath.Join(dir, "dst") @@ -213,9 +175,7 @@ func TestCopyDirFail_DstInaccessible(t *testing.T) { }) defer cleanup() - if err := CopyDir(srcdir, dstdir); err == nil { - t.Fatalf("expected error for CopyDir(%s, %s), got none", srcdir, dstdir) - } + assert.Errorf(t, CopyDir(srcdir, dstdir), "expected error for CopyDir(%s, %s), got none", srcdir, dstdir) } func TestCopyDirFail_SrcIsNotDir(t *testing.T) { @@ -225,44 +185,25 @@ func TestCopyDirFail_SrcIsNotDir(t *testing.T) { dir := t.TempDir() srcdir = filepath.Join(dir, "src") - if _, err = os.Create(srcdir); err != nil { - t.Fatal(err) - } + _, err = os.Create(srcdir) + require.NoError(t, err) dstdir = filepath.Join(dir, "dst") - if err = CopyDir(srcdir, dstdir); err == nil { - t.Fatalf("expected error for CopyDir(%s, %s), got none", srcdir, dstdir) - } - - if !errors.Is(err, errSrcNotDir) { - t.Fatalf("expected %v error for CopyDir(%s, %s), got %s", errSrcNotDir, srcdir, dstdir, err) - } + require.ErrorIsf(t, CopyDir(srcdir, dstdir), errSrcNotDir, "expected %v error for CopyDir(%s, %s)", errSrcNotDir, srcdir, dstdir) } func TestCopyDirFail_DstExists(t *testing.T) { var srcdir, dstdir string - var err error dir := t.TempDir() srcdir = filepath.Join(dir, "src") - if err = os.MkdirAll(srcdir, 0o755); err != nil { - t.Fatal(err) - } + require.NoError(t, os.MkdirAll(srcdir, 0o755)) dstdir = filepath.Join(dir, "dst") - if err = os.MkdirAll(dstdir, 0o755); err != nil { - t.Fatal(err) - } - - if err = CopyDir(srcdir, dstdir); err == nil { - t.Fatalf("expected error for CopyDir(%s, %s), got none", srcdir, dstdir) - } - - if !errors.Is(err, errDstExist) { - t.Fatalf("expected %v error for CopyDir(%s, %s), got %s", errDstExist, srcdir, dstdir, err) - } + require.NoError(t, os.MkdirAll(dstdir, 0o755)) + require.ErrorIs(t, CopyDir(srcdir, dstdir), errDstExist, "expected %v error for CopyDir(%s, %s)", errDstExist, srcdir, dstdir) } func TestCopyDirFailOpen(t *testing.T) { @@ -288,70 +229,46 @@ func TestCopyDirFailOpen(t *testing.T) { dir := t.TempDir() srcdir = filepath.Join(dir, "src") - if err := os.MkdirAll(srcdir, 0o755); err != nil { - t.Fatal(err) - } + require.NoError(t, os.MkdirAll(srcdir, 0o755)) srcfn := filepath.Join(srcdir, "file") srcf, err := os.Create(srcfn) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) srcf.Close() // setup source file so that it cannot be read - if err = os.Chmod(srcfn, 0o222); err != nil { - t.Fatal(err) - } + require.NoError(t, os.Chmod(srcfn, 0o222)) dstdir = filepath.Join(dir, "dst") - - if err = CopyDir(srcdir, dstdir); err == nil { - t.Fatalf("expected error for CopyDir(%s, %s), got none", srcdir, dstdir) - } + assert.Errorf(t, CopyDir(srcdir, dstdir), "expected error for CopyDir(%s, %s), got none", srcdir, dstdir) } func TestCopyFile(t *testing.T) { dir := t.TempDir() srcf, err := os.Create(filepath.Join(dir, "srcfile")) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) want := "hello world" - if _, err := srcf.WriteString(want); err != nil { - t.Fatal(err) - } + _, err = srcf.WriteString(want) + require.NoError(t, err) srcf.Close() destf := filepath.Join(dir, "destf") - if err := CopyFile(srcf.Name(), destf); err != nil { - t.Fatal(err) - } + require.NoError(t, CopyFile(srcf.Name(), destf)) got, err := os.ReadFile(destf) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if want != string(got) { - t.Fatalf("expected: %s, got: %s", want, string(got)) - } + require.Equalf(t, want, string(got), "expected: %s, got: %s", want, string(got)) wantinfo, err := os.Stat(srcf.Name()) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) gotinfo, err := os.Stat(destf) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if wantinfo.Mode() != gotinfo.Mode() { - t.Fatalf("expected %s: %#v\n to be the same mode as %s: %#v", srcf.Name(), wantinfo.Mode(), destf, gotinfo.Mode()) - } + assert.Equalf(t, wantinfo.Mode(), gotinfo.Mode(), "expected %s: %#v\n to be the same mode as %s: %#v", srcf.Name(), wantinfo.Mode(), destf, gotinfo.Mode()) } func TestCopyFileSymlink(t *testing.T) { @@ -366,9 +283,7 @@ func TestCopyFileSymlink(t *testing.T) { for symlink, dst := range testcases { t.Run(symlink, func(t *testing.T) { var err error - if err = CopyFile(symlink, dst); err != nil { - t.Fatalf("failed to copy symlink: %s", err) - } + require.NoErrorf(t, CopyFile(symlink, dst), "failed to copy symlink") var want, got string @@ -377,31 +292,21 @@ func TestCopyFileSymlink(t *testing.T) { // regular users aren't granted usually. So we copy the file // content as a fall back instead of creating a real symlink. srcb, err := os.ReadFile(symlink) - if err != nil { - t.Fatalf("%+v", err) - } + require.NoError(t, err) dstb, err := os.ReadFile(dst) - if err != nil { - t.Fatalf("%+v", err) - } + require.NoError(t, err) want = string(srcb) got = string(dstb) } else { want, err = os.Readlink(symlink) - if err != nil { - t.Fatalf("%+v", err) - } + require.NoError(t, err) got, err = os.Readlink(dst) - if err != nil { - t.Fatalf("could not resolve symlink: %s", err) - } + require.NoErrorf(t, err, "could not resolve symlink") } - if want != got { - t.Fatalf("resolved path is incorrect. expected %s, got %s", want, got) - } + require.Equalf(t, want, got, "resolved path is incorrect. expected %s, got %s", want, got) }) } } @@ -424,9 +329,7 @@ func TestCopyFileFail(t *testing.T) { dir := t.TempDir() srcf, err := os.Create(filepath.Join(dir, "srcfile")) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) srcf.Close() var dstdir string @@ -438,9 +341,7 @@ func TestCopyFileFail(t *testing.T) { defer cleanup() fn := filepath.Join(dstdir, "file") - if err := CopyFile(srcf.Name(), fn); err == nil { - t.Fatalf("expected error for %s, got none", fn) - } + require.Errorf(t, CopyFile(srcf.Name(), fn), "expected error for %s, got none", fn) } // setupInaccessibleDir creates a temporary location with a single @@ -463,9 +364,7 @@ func setupInaccessibleDir(t *testing.T, op func(dir string) error) func() { subdir := filepath.Join(dir, "dir") cleanup := func() { - if err := os.Chmod(subdir, 0o777); err != nil { - t.Error(err) - } + assert.NoError(t, os.Chmod(subdir, 0o777)) } if err := os.Mkdir(subdir, 0o777); err != nil { @@ -498,9 +397,7 @@ func TestIsDir(t *testing.T) { } wd, err := os.Getwd() - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) var dn string @@ -530,14 +427,16 @@ func TestIsDir(t *testing.T) { } for f, want := range tests { - got, err := IsDir(f) - if err != nil && !want.err { - t.Fatalf("expected no error, got %v", err) - } + t.Run(f, func(t *testing.T) { + got, err := IsDir(f) - if got != want.exists { - t.Fatalf("expected %t for %s, got %t", want.exists, f, got) - } + if want.err { + require.Error(t, err) + } else { + require.NoError(t, err) + } + require.Equalf(t, want.exists, got, "expected %t for %s, got %t", want.exists, f, got) + }) } } @@ -552,26 +451,18 @@ func TestIsSymlink(t *testing.T) { dir := t.TempDir() dirPath := filepath.Join(dir, "directory") - if err := os.MkdirAll(dirPath, 0o777); err != nil { - t.Fatal(err) - } + require.NoError(t, os.MkdirAll(dirPath, 0o777)) filePath := filepath.Join(dir, "file") f, err := os.Create(filePath) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) f.Close() dirSymlink := filepath.Join(dir, "dirSymlink") fileSymlink := filepath.Join(dir, "fileSymlink") - if err = os.Symlink(dirPath, dirSymlink); err != nil { - t.Fatal(err) - } - if err = os.Symlink(filePath, fileSymlink); err != nil { - t.Fatal(err) - } + require.NoError(t, os.Symlink(dirPath, dirSymlink)) + require.NoError(t, os.Symlink(filePath, fileSymlink)) var ( inaccessibleFile string @@ -609,14 +500,11 @@ func TestIsSymlink(t *testing.T) { for path, want := range tests { got, err := IsSymlink(path) - if err != nil { - if !want.err { - t.Errorf("expected no error, got %v", err) - } - } - - if got != want.expected { - t.Errorf("expected %t for %s, got %t", want.expected, path, got) + if want.err { + require.Error(t, err, "expected an error") + } else { + require.NoError(t, err, "expected no error") } + assert.Equalf(t, want.expected, got, "expected %t for %s, got %t", want.expected, path, got) } } From 6c45810119937e8fcbbc4f0b7f56c32a40c52d87 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 22:30:19 +0200 Subject: [PATCH 18/61] chore(internal): refactor: convert tests to testify assert/require part 4 (#32408) refactor: convert tests to testify assert/require in internal/chart/v3/util Signed-off-by: Matthieu MOREL --- internal/chart/v3/loader/load_test.go | 281 ++++++--------------- internal/chart/v3/util/create_test.go | 41 ++- internal/chart/v3/util/save_test.go | 32 +-- internal/plugin/runtime_subprocess_test.go | 4 +- internal/release/v2/info_test.go | 42 ++- 5 files changed, 121 insertions(+), 279 deletions(-) diff --git a/internal/chart/v3/loader/load_test.go b/internal/chart/v3/loader/load_test.go index 5caec7815..9378bcdf5 100644 --- a/internal/chart/v3/loader/load_test.go +++ b/internal/chart/v3/loader/load_test.go @@ -41,13 +41,9 @@ import ( func TestLoadDir(t *testing.T) { l, err := Loader("testdata/frobnitz") - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") c, err := l.Load() - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") verifyFrobnitz(t, c) verifyChart(t, c) verifyDependencies(t, c) @@ -60,33 +56,24 @@ func TestLoadDirWithDevNull(t *testing.T) { } l, err := Loader("testdata/frobnitz_with_dev_null") - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } - if _, err := l.Load(); err == nil { - t.Error("packages with an irregular file (/dev/null) should not load") - } + require.NoError(t, err, "Failed to load testdata") + _, err = l.Load() + assert.Error(t, err, "packages with an irregular file (/dev/null) should not load") } func TestLoadDirWithSymlink(t *testing.T) { sym := filepath.Join("..", "LICENSE") link := filepath.Join("testdata", "frobnitz_with_symlink", "LICENSE") - if err := os.Symlink(sym, link); err != nil { - t.Fatal(err) - } + require.NoError(t, os.Symlink(sym, link)) defer os.Remove(link) l, err := Loader("testdata/frobnitz_with_symlink") - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") c, err := l.Load() - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") verifyFrobnitz(t, c) verifyChart(t, c) verifyDependencies(t, c) @@ -109,8 +96,7 @@ func TestBomTestData(t *testing.T) { defer unzipped.Close() for _, testFile := range testFiles { data := make([]byte, 3) - err := unzipped.Reset(bytes.NewReader(archive)) - require.NoErrorf(t, err, "Error reading archive frobnitz_with_bom.tgz") + require.NoErrorf(t, unzipped.Reset(bytes.NewReader(archive)), "Error reading archive frobnitz_with_bom.tgz") tr := tar.NewReader(unzipped) for { file, err := tr.Next() @@ -132,13 +118,9 @@ func TestBomTestData(t *testing.T) { func TestLoadDirWithUTFBOM(t *testing.T) { l, err := Loader("testdata/frobnitz_with_bom") - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") c, err := l.Load() - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") verifyFrobnitz(t, c) verifyChart(t, c) verifyDependencies(t, c) @@ -148,13 +130,9 @@ func TestLoadDirWithUTFBOM(t *testing.T) { func TestLoadArchiveWithUTFBOM(t *testing.T) { l, err := Loader("testdata/frobnitz_with_bom.tgz") - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") c, err := l.Load() - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") verifyFrobnitz(t, c) verifyChart(t, c) verifyDependencies(t, c) @@ -164,13 +142,9 @@ func TestLoadArchiveWithUTFBOM(t *testing.T) { func TestLoadFile(t *testing.T) { l, err := Loader("testdata/frobnitz-1.2.3.tgz") - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") c, err := l.Load() - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") verifyFrobnitz(t, c) verifyChart(t, c) verifyDependencies(t, c) @@ -224,36 +198,18 @@ icon: https://example.com/64x64.png } c, err := LoadFiles(goodFiles) - if err != nil { - t.Errorf("Expected good files to be loaded, got %v", err) - } - - if c.Name() != "frobnitz" { - t.Errorf("Expected chart name to be 'frobnitz', got %s", c.Name()) - } - - if c.Values["var"] != "some values" { - t.Error("Expected chart values to be populated with default values") - } + require.NoError(t, err, "Expected good files to be loaded") + assert.Equal(t, "frobnitz", c.Name(), "Expected chart name to be 'frobnitz', got %s", c.Name()) + assert.Equal(t, "some values", c.Values["var"], "Expected chart values to be populated with default values") + assert.Len(t, c.Raw, 5, "Expected %d files, got %d", 5, len(c.Raw)) - if len(c.Raw) != 5 { - t.Errorf("Expected %d files, got %d", 5, len(c.Raw)) - } + assert.True(t, bytes.Equal(c.Schema, []byte("type: Values")), "Expected chart schema to be populated with default values") - if !bytes.Equal(c.Schema, []byte("type: Values")) { - t.Error("Expected chart schema to be populated with default values") - } + assert.Len(t, c.Templates, 2, "Expected number of templates == 2, got %d", len(c.Templates)) - if len(c.Templates) != 2 { - t.Errorf("Expected number of templates == 2, got %d", len(c.Templates)) - } - - if _, err = LoadFiles([]*archive.BufferedFile{}); err == nil { - t.Fatal("Expected err to be non-nil") - } - if err.Error() != "Chart.yaml file is missing" { - t.Errorf("Expected chart metadata missing error, got '%s'", err.Error()) - } + _, err = LoadFiles([]*archive.BufferedFile{}) + require.Error(t, err, "Expected err to be non-nil") + assert.EqualError(t, err, "Chart.yaml file is missing", "Expected chart metadata missing error, got '%s'", err.Error()) } // Test the order of file loading. The Chart.yaml file needs to come first for @@ -309,9 +265,7 @@ icon: https://example.com/64x64.png // Capture stderr to make sure message about Chart.yaml handle dependencies // is not present r, w, err := os.Pipe() - if err != nil { - t.Fatalf("Unable to create pipe: %s", err) - } + require.NoError(t, err, "Unable to create pipe") stderr := log.Writer() log.SetOutput(w) defer func() { @@ -319,25 +273,19 @@ icon: https://example.com/64x64.png }() _, err = LoadFiles(goodFiles) - if err != nil { - t.Errorf("Expected good files to be loaded, got %v", err) - } + require.NoError(t, err, "Expected good files to be loaded") w.Close() var text bytes.Buffer io.Copy(&text, r) - if text.String() != "" { - t.Errorf("Expected no message to Stderr, got %s", text.String()) - } + assert.Empty(t, text.String(), "Expected no message to Stderr, got %s", text.String()) } // Packaging the chart on a Windows machine will produce an // archive that has \\ as delimiters. Test that we support these archives func TestLoadFileBackslash(t *testing.T) { c, err := Load("testdata/frobnitz_backslash-1.2.3.tgz") - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") verifyChartFileAndTemplate(t, c, "frobnitz_backslash") verifyChart(t, c) verifyDependencies(t, c) @@ -345,13 +293,9 @@ func TestLoadFileBackslash(t *testing.T) { func TestLoadV3WithReqs(t *testing.T) { l, err := Loader("testdata/frobnitz.v3.reqs") - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") c, err := l.Load() - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") verifyDependencies(t, c) verifyDependenciesLock(t, c) } @@ -361,9 +305,7 @@ func TestLoadInvalidArchive(t *testing.T) { writeTar := func(filename, internalPath string, body []byte) { dest, err := os.Create(filename) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) zipper := gzip.NewWriter(dest) tw := tar.NewWriter(zipper) @@ -373,12 +315,9 @@ func TestLoadInvalidArchive(t *testing.T) { Size: int64(len(body)), ModTime: time.Now(), } - if err := tw.WriteHeader(h); err != nil { - t.Fatal(err) - } - if _, err := tw.Write(body); err != nil { - t.Fatal(err) - } + require.NoError(t, tw.WriteHeader(h)) + _, err = tw.Write(body) + require.NoError(t, err) tw.Close() zipper.Close() dest.Close() @@ -410,37 +349,27 @@ func TestLoadInvalidArchive(t *testing.T) { illegalChart := filepath.Join(tmpdir, tt.chartname) writeTar(illegalChart, tt.internal, []byte("hello: world")) _, err := Load(illegalChart) - if err == nil { - t.Fatal("expected error when unpacking illegal files") - } - if !strings.Contains(err.Error(), tt.expectError) { - t.Errorf("Expected error to contain %q, got %q for %s", tt.expectError, err.Error(), tt.chartname) - } + require.Error(t, err, "expected error when unpacking illegal files") + require.ErrorContains(t, err, tt.expectError, "Expected error to contain %q, got %q for %s", tt.expectError, err.Error(), tt.chartname) } // Make sure that absolute path gets interpreted as relative illegalChart := filepath.Join(tmpdir, "abs-path.tgz") writeTar(illegalChart, "/Chart.yaml", []byte("hello: world")) _, err := Load(illegalChart) - if err.Error() != "validation: chart.metadata.name is required" { - t.Error(err) - } + require.EqualError(t, err, "validation: chart.metadata.name is required") // And just to validate that the above was not spurious illegalChart = filepath.Join(tmpdir, "abs-path2.tgz") writeTar(illegalChart, "files/whatever.yaml", []byte("hello: world")) _, err = Load(illegalChart) - if err.Error() != "Chart.yaml file is missing" { - t.Errorf("Unexpected error message: %s", err) - } + require.EqualError(t, err, "Chart.yaml file is missing") // Finally, test that drive letter gets stripped off on Windows illegalChart = filepath.Join(tmpdir, "abs-winpath.tgz") writeTar(illegalChart, "c:\\Chart.yaml", []byte("hello: world")) _, err = Load(illegalChart) - if err.Error() != "validation: chart.metadata.name is required" { - t.Error(err) - } + assert.EqualError(t, err, "validation: chart.metadata.name is required") } func TestLoadValues(t *testing.T) { @@ -487,12 +416,8 @@ foo: for testName, testCase := range testCases { t.Run(testName, func(tt *testing.T) { values, err := LoadValues(bytes.NewReader(testCase.data)) - if err != nil { - tt.Fatal(err) - } - if !reflect.DeepEqual(values, testCase.expctedValues) { - tt.Errorf("Expected values: %v, got %v", testCase.expctedValues, values) - } + require.NoError(tt, err) + assert.Truef(tt, reflect.DeepEqual(values, testCase.expctedValues), "Expected values: %v, got %v", testCase.expctedValues, values) }) } } @@ -521,21 +446,15 @@ func TestMergeValuesV3(t *testing.T) { testMap := MergeMaps(flatMap, nestedMap) equal := reflect.DeepEqual(testMap, nestedMap) - if !equal { - t.Errorf("Expected a nested map to overwrite a flat value. Expected: %v, got %v", nestedMap, testMap) - } + assert.True(t, equal, "Expected a nested map to overwrite a flat value. Expected: %v, got %v", nestedMap, testMap) testMap = MergeMaps(nestedMap, flatMap) equal = reflect.DeepEqual(testMap, flatMap) - if !equal { - t.Errorf("Expected a flat value to overwrite a map. Expected: %v, got %v", flatMap, testMap) - } + assert.True(t, equal, "Expected a flat value to overwrite a map. Expected: %v, got %v", flatMap, testMap) testMap = MergeMaps(nestedMap, anotherNestedMap) equal = reflect.DeepEqual(testMap, anotherNestedMap) - if !equal { - t.Errorf("Expected a nested map to overwrite another nested map. Expected: %v, got %v", anotherNestedMap, testMap) - } + assert.True(t, equal, "Expected a nested map to overwrite another nested map. Expected: %v, got %v", anotherNestedMap, testMap) testMap = MergeMaps(anotherFlatMap, anotherNestedMap) expectedMap := map[string]any{ @@ -547,20 +466,14 @@ func TestMergeValuesV3(t *testing.T) { }, } equal = reflect.DeepEqual(testMap, expectedMap) - if !equal { - t.Errorf("Expected a map with different keys to merge properly with another map. Expected: %v, got %v", expectedMap, testMap) - } + assert.True(t, equal, "Expected a map with different keys to merge properly with another map. Expected: %v, got %v", expectedMap, testMap) } func verifyChart(t *testing.T, c *chart.Chart) { t.Helper() - if c.Name() == "" { - t.Fatalf("No chart metadata found on %v", c) - } + require.NotEmpty(t, c.Name(), "No chart metadata found on %v", c) t.Logf("Verifying chart %s", c.Name()) - if len(c.Templates) != 1 { - t.Errorf("Expected 1 template, got %d", len(c.Templates)) - } + assert.Len(t, c.Templates, 1, "Expected 1 template, got %d", len(c.Templates)) numfiles := 6 if len(c.Files) != numfiles { @@ -587,62 +500,40 @@ func verifyChart(t *testing.T, c *chart.Chart) { } for _, dep := range c.Dependencies() { - if dep.Metadata == nil { - t.Fatalf("expected metadata on dependency: %v", dep) - } + require.NotNil(t, dep.Metadata, "expected metadata on dependency: %v", dep) exp, ok := expect[dep.Name()] - if !ok { - t.Fatalf("Unknown dependency %s", dep.Name()) - } - if exp["version"] != dep.Metadata.Version { - t.Errorf("Expected %s version %s, got %s", dep.Name(), exp["version"], dep.Metadata.Version) - } + require.True(t, ok, "Unknown dependency %s", dep.Name()) + assert.Equal(t, exp["version"], dep.Metadata.Version, "Expected %s version %s, got %s", dep.Name(), exp["version"], dep.Metadata.Version) } } func verifyDependencies(t *testing.T, c *chart.Chart) { t.Helper() - if len(c.Metadata.Dependencies) != 2 { - t.Errorf("Expected 2 dependencies, got %d", len(c.Metadata.Dependencies)) - } + assert.Len(t, c.Metadata.Dependencies, 2, "Expected 2 dependencies, got %d", len(c.Metadata.Dependencies)) tests := []*chart.Dependency{ {Name: "alpine", Version: "0.1.0", Repository: "https://example.com/charts"}, {Name: "mariner", Version: "4.3.2", Repository: "https://example.com/charts"}, } for i, tt := range tests { d := c.Metadata.Dependencies[i] - if d.Name != tt.Name { - t.Errorf("Expected dependency named %q, got %q", tt.Name, d.Name) - } - if d.Version != tt.Version { - t.Errorf("Expected dependency named %q to have version %q, got %q", tt.Name, tt.Version, d.Version) - } - if d.Repository != tt.Repository { - t.Errorf("Expected dependency named %q to have repository %q, got %q", tt.Name, tt.Repository, d.Repository) - } + assert.Equal(t, tt.Name, d.Name, "Expected dependency named %q, got %q", tt.Name, d.Name) + assert.Equal(t, tt.Version, d.Version, "Expected dependency named %q to have version %q, got %q", tt.Name, tt.Version, d.Version) + assert.Equal(t, tt.Repository, d.Repository, "Expected dependency named %q to have repository %q, got %q", tt.Name, tt.Repository, d.Repository) } } func verifyDependenciesLock(t *testing.T, c *chart.Chart) { t.Helper() - if len(c.Metadata.Dependencies) != 2 { - t.Errorf("Expected 2 dependencies, got %d", len(c.Metadata.Dependencies)) - } + assert.Len(t, c.Metadata.Dependencies, 2, "Expected 2 dependencies, got %d", len(c.Metadata.Dependencies)) tests := []*chart.Dependency{ {Name: "alpine", Version: "0.1.0", Repository: "https://example.com/charts"}, {Name: "mariner", Version: "4.3.2", Repository: "https://example.com/charts"}, } for i, tt := range tests { d := c.Metadata.Dependencies[i] - if d.Name != tt.Name { - t.Errorf("Expected dependency named %q, got %q", tt.Name, d.Name) - } - if d.Version != tt.Version { - t.Errorf("Expected dependency named %q to have version %q, got %q", tt.Name, tt.Version, d.Version) - } - if d.Repository != tt.Repository { - t.Errorf("Expected dependency named %q to have repository %q, got %q", tt.Name, tt.Repository, d.Repository) - } + assert.Equal(t, tt.Name, d.Name, "Expected dependency named %q, got %q", tt.Name, d.Name) + assert.Equal(t, tt.Version, d.Version, "Expected dependency named %q to have version %q, got %q", tt.Name, tt.Version, d.Version) + assert.Equal(t, tt.Repository, d.Repository, "Expected dependency named %q to have repository %q, got %q", tt.Name, tt.Repository, d.Repository) } } @@ -653,51 +544,25 @@ func verifyFrobnitz(t *testing.T, c *chart.Chart) { func verifyChartFileAndTemplate(t *testing.T, c *chart.Chart, name string) { t.Helper() - if c.Metadata == nil { - t.Fatal("Metadata is nil") - } - if c.Name() != name { - t.Errorf("Expected %s, got %s", name, c.Name()) - } - if len(c.Templates) != 1 { - t.Fatalf("Expected 1 template, got %d", len(c.Templates)) - } - if c.Templates[0].Name != "templates/template.tpl" { - t.Errorf("Unexpected template: %s", c.Templates[0].Name) - } - if len(c.Templates[0].Data) == 0 { - t.Error("No template data.") - } - if len(c.Files) != 6 { - t.Fatalf("Expected 6 Files, got %d", len(c.Files)) - } - if len(c.Dependencies()) != 2 { - t.Fatalf("Expected 2 Dependency, got %d", len(c.Dependencies())) - } - if len(c.Metadata.Dependencies) != 2 { - t.Fatalf("Expected 2 Dependencies.Dependency, got %d", len(c.Metadata.Dependencies)) - } - if len(c.Lock.Dependencies) != 2 { - t.Fatalf("Expected 2 Lock.Dependency, got %d", len(c.Lock.Dependencies)) - } + require.NotNil(t, c.Metadata, "Metadata is nil") + assert.Equal(t, name, c.Name(), "Expected %s, got %s", name, c.Name()) + require.Len(t, c.Templates, 1, "Expected 1 template, got %d", len(c.Templates)) + assert.Equal(t, "templates/template.tpl", c.Templates[0].Name, "Unexpected template: %s", c.Templates[0].Name) + assert.NotEmpty(t, c.Templates[0].Data, "No template data.") + require.Len(t, c.Files, 6, "Expected 6 Files, got %d", len(c.Files)) + require.Len(t, c.Dependencies(), 2, "Expected 2 Dependency, got %d", len(c.Dependencies())) + require.Len(t, c.Metadata.Dependencies, 2, "Expected 2 Dependencies.Dependency, got %d", len(c.Metadata.Dependencies)) + require.Len(t, c.Lock.Dependencies, 2, "Expected 2 Lock.Dependency, got %d", len(c.Lock.Dependencies)) for _, dep := range c.Dependencies() { switch dep.Name() { case "mariner": case "alpine": - if len(dep.Templates) != 1 { - t.Fatalf("Expected 1 template, got %d", len(dep.Templates)) - } - if dep.Templates[0].Name != "templates/alpine-pod.yaml" { - t.Errorf("Unexpected template: %s", dep.Templates[0].Name) - } + require.Len(t, dep.Templates, 1, "Expected 1 template, got %d", len(dep.Templates)) + assert.Equal(t, "templates/alpine-pod.yaml", dep.Templates[0].Name, "Unexpected template: %s", dep.Templates[0].Name) assert.NotEmpty(t, dep.Templates[0].Data, "No template data.") - if len(dep.Files) != 1 { - t.Fatalf("Expected 1 Files, got %d", len(dep.Files)) - } - if len(dep.Dependencies()) != 2 { - t.Fatalf("Expected 2 Dependency, got %d", len(dep.Dependencies())) - } + require.Len(t, dep.Files, 1, "Expected 1 Files, got %d", len(dep.Files)) + require.Len(t, dep.Dependencies(), 2, "Expected 2 Dependency, got %d", len(dep.Dependencies())) default: t.Errorf("Unexpected dependency %s", dep.Name()) } @@ -707,8 +572,6 @@ func verifyChartFileAndTemplate(t *testing.T, c *chart.Chart, name string) { func verifyBomStripped(t *testing.T, files []*common.File) { t.Helper() for _, file := range files { - if bytes.HasPrefix(file.Data, utf8bom) { - t.Errorf("Byte Order Mark still present in processed file %s", file.Name) - } + assert.Falsef(t, bytes.HasPrefix(file.Data, utf8bom), "Byte Order Mark still present in processed file %s", file.Name) } } diff --git a/internal/chart/v3/util/create_test.go b/internal/chart/v3/util/create_test.go index eba0811ae..ddbbf6216 100644 --- a/internal/chart/v3/util/create_test.go +++ b/internal/chart/v3/util/create_test.go @@ -38,7 +38,7 @@ func TestCreate(t *testing.T) { dir := filepath.Join(tdir, "foo") mychart, err := loader.LoadDir(c) - require.NoError(t, err, "Failed to load newly created chart %q: %s", c, err) + require.NoError(t, err, "Failed to load newly created chart %q", c) assert.Equal(t, "foo", mychart.Name(), "Expected name to be 'foo', got %q", mychart.Name()) @@ -55,9 +55,8 @@ func TestCreate(t *testing.T) { TestConnectionName, ValuesfileName, } { - if _, err := os.Stat(filepath.Join(dir, f)); err != nil { - t.Errorf("Expected %s file: %s", f, err) - } + _, err := os.Stat(filepath.Join(dir, f)) + assert.NoErrorf(t, err, "Expected %s file", f) } } @@ -71,14 +70,12 @@ func TestCreateFrom(t *testing.T) { } srcdir := "./testdata/frobnitz/charts/mariner" - if err := CreateFrom(cf, tdir, srcdir); err != nil { - t.Fatal(err) - } + require.NoError(t, CreateFrom(cf, tdir, srcdir)) dir := filepath.Join(tdir, "foo") c := filepath.Join(tdir, cf.Name) mychart, err := loader.LoadDir(c) - require.NoError(t, err, "Failed to load newly created chart %q: %s", c, err) + require.NoError(t, err, "Failed to load newly created chart %q", c) assert.Equal(t, "foo", mychart.Name(), "Expected name to be 'foo', got %q", mychart.Name()) @@ -87,16 +84,13 @@ func TestCreateFrom(t *testing.T) { ValuesfileName, filepath.Join(TemplatesDir, "placeholder.tpl"), } { - if _, err := os.Stat(filepath.Join(dir, f)); err != nil { - t.Errorf("Expected %s file: %s", f, err) - } + _, err := os.Stat(filepath.Join(dir, f)) + require.NoErrorf(t, err, "Expected %s file", f) // Check each file to make sure has been replaced b, err := os.ReadFile(filepath.Join(dir, f)) - require.NoError(t, err, "Unable to read file %s: %s", f, err) - if bytes.Contains(b, []byte("")) { - t.Errorf("File %s contains ", f) - } + require.NoError(t, err, "Unable to read file %s", f) + assert.Falsef(t, bytes.Contains(b, []byte("")), "File %s contains ", f) } } @@ -106,9 +100,8 @@ func TestCreate_Overwrite(t *testing.T) { var errlog bytes.Buffer - if _, err := Create("foo", tdir); err != nil { - t.Fatal(err) - } + _, err := Create("foo", tdir) + require.NoError(t, err) dir := filepath.Join(tdir, "foo") @@ -117,9 +110,8 @@ func TestCreate_Overwrite(t *testing.T) { // Now re-run the create Stderr = &errlog - if _, err := Create("foo", tdir); err != nil { - t.Fatal(err) - } + _, err = Create("foo", tdir) + require.NoError(t, err) data, err := os.ReadFile(tplname) require.NoError(t, err) @@ -150,8 +142,11 @@ func TestValidateChartName(t *testing.T) { "abcdefghijklmnopqrstuvwxyz-_." + "ABCDEFGHIJKLMNOPQRSTUVWXYZ-_.": false, } { - if err := validateChartName(name); (err != nil) == shouldPass { - t.Errorf("test for %q failed", name) + err := validateChartName(name) + if shouldPass { + assert.NoErrorf(t, err, "Expected chart name %q to pass validation", name) + } else { + assert.Errorf(t, err, "Expected chart name %q to fail validation, but it passed", name) } } } diff --git a/internal/chart/v3/util/save_test.go b/internal/chart/v3/util/save_test.go index e729ad3b3..f7bd5dcfb 100644 --- a/internal/chart/v3/util/save_test.go +++ b/internal/chart/v3/util/save_test.go @@ -62,13 +62,9 @@ func TestSave(t *testing.T) { chartWithInvalidJSON := withSchema(*c, []byte("{")) where, err := Save(c, dest) - require.NoError(t, err, "Failed to save: %s", err) - if !strings.HasPrefix(where, dest) { - t.Fatalf("Expected %q to start with %q", where, dest) - } - if !strings.HasSuffix(where, ".tgz") { - t.Fatalf("Expected %q to end with .tgz", where) - } + require.NoError(t, err, "Failed to save") + require.Truef(t, strings.HasPrefix(where, dest), "Expected %q to start with %q", where, dest) + require.Truef(t, strings.HasSuffix(where, ".tgz"), "Expected %q to end with .tgz", where) c2, err := loader.LoadFile(where) require.NoError(t, err) @@ -83,13 +79,12 @@ func TestSave(t *testing.T) { formattedActual := Indent(indentation, string(c2.Schema)) t.Fatalf("Schema data did not match.\nExpected:\n%s\nActual:\n%s", formattedExpected, formattedActual) } - if _, err := Save(&chartWithInvalidJSON, dest); err == nil { - t.Fatal("Invalid JSON was not caught while saving chart") - } + _, err = Save(&chartWithInvalidJSON, dest) + require.Error(t, err, "Invalid JSON was not caught while saving chart") c.Metadata.APIVersion = chart.APIVersionV3 where, err = Save(c, dest) - require.NoError(t, err, "Failed to save: %s", err) + require.NoError(t, err, "Failed to save") c2, err = loader.LoadFile(where) require.NoError(t, err) require.NotNil(t, c2.Lock, "Expected v3 chart archive to contain a Chart.lock file") @@ -152,16 +147,14 @@ func TestSavePreservesTimestamps(t *testing.T) { } where, err := Save(c, tmp) - require.NoError(t, err, "Failed to save: %s", err) + require.NoError(t, err, "Failed to save") allHeaders, err := retrieveAllHeadersFromTar(where) - require.NoError(t, err, "Failed to parse tar: %v", err) + require.NoError(t, err, "Failed to parse tar") roundedTime := initialCreateTime.Round(time.Second) for _, header := range allHeaders { - if !header.ModTime.Equal(roundedTime) { - t.Fatalf("File timestamp not preserved: %v", header.ModTime) - } + require.Truef(t, header.ModTime.Equal(roundedTime), "File timestamp not preserved: %v", header.ModTime) } } @@ -235,8 +228,7 @@ func TestSaveDir(t *testing.T) { pth := filepath.Join(tmp2, "tmpcharts") require.NoError(t, os.MkdirAll(filepath.Join(pth), 0o755), "Failed to create directory") - err = SaveDir(c, pth) - assert.EqualError(t, err, "\"../ahab\" is not a valid chart name", "Did not get expected error for chart named %q", c.Name()) + assert.EqualError(t, SaveDir(c, pth), "\"../ahab\" is not a valid chart name", "Did not get expected error for chart named %q", c.Name()) } func TestRepeatableSave(t *testing.T) { @@ -297,10 +289,10 @@ func TestRepeatableSave(t *testing.T) { // create package dest := path.Join(tmp, "newdir") where, err := Save(test.chart, dest) - require.NoError(t, err, "Failed to save: %s", err) + require.NoError(t, err, "Failed to save") // get shasum for package result, err := sha256Sum(where) - require.NoError(t, err, "Failed to check shasum: %s", err) + require.NoError(t, err, "Failed to check shasum") // assert that the package SHA is what we wanted. assert.Equal(t, test.want, result, "FormatName() result = %v, want %v", result, test.want) }) diff --git a/internal/plugin/runtime_subprocess_test.go b/internal/plugin/runtime_subprocess_test.go index c651dd3f7..c04127e0d 100644 --- a/internal/plugin/runtime_subprocess_test.go +++ b/internal/plugin/runtime_subprocess_test.go @@ -16,7 +16,6 @@ limitations under the License. package plugin import ( - "errors" "fmt" "os" "path/filepath" @@ -78,8 +77,7 @@ func TestSubprocessPluginRuntime(t *testing.T) { require.Error(t, err) ieerr := &InvokeExecError{} - ok := errors.As(err, &ieerr) - require.True(t, ok, "expected InvokeExecError, got %T", err) + require.ErrorAs(t, err, &ieerr, "expected InvokeExecError") assert.Equal(t, 56, ieerr.ExitCode) assert.Nil(t, output) diff --git a/internal/release/v2/info_test.go b/internal/release/v2/info_test.go index 5812c6560..571daa025 100644 --- a/internal/release/v2/info_test.go +++ b/internal/release/v2/info_test.go @@ -253,17 +253,17 @@ func TestInfoUnmarshalJSON(t *testing.T) { err := json.Unmarshal([]byte(tt.input), &info) if tt.wantErr { assert.Error(t, err) - return + } else { + require.NoError(t, err) + assert.Equal(t, tt.expected.FirstDeployed.Unix(), info.FirstDeployed.Unix()) + assert.Equal(t, tt.expected.LastDeployed.Unix(), info.LastDeployed.Unix()) + assert.Equal(t, tt.expected.Deleted.Unix(), info.Deleted.Unix()) + assert.Equal(t, tt.expected.Description, info.Description) + assert.Equal(t, tt.expected.Status, info.Status) + assert.Equal(t, tt.expected.RollbackRevision, info.RollbackRevision) + assert.Equal(t, tt.expected.Notes, info.Notes) + assert.Equal(t, tt.expected.Resources, info.Resources) } - require.NoError(t, err) - assert.Equal(t, tt.expected.FirstDeployed.Unix(), info.FirstDeployed.Unix()) - assert.Equal(t, tt.expected.LastDeployed.Unix(), info.LastDeployed.Unix()) - assert.Equal(t, tt.expected.Deleted.Unix(), info.Deleted.Unix()) - assert.Equal(t, tt.expected.Description, info.Description) - assert.Equal(t, tt.expected.Status, info.Status) - assert.Equal(t, tt.expected.RollbackRevision, info.RollbackRevision) - assert.Equal(t, tt.expected.Notes, info.Notes) - assert.Equal(t, tt.expected.Resources, info.Resources) }) } } @@ -284,9 +284,7 @@ func TestInfoRoundTrip(t *testing.T) { require.NoError(t, err) var decoded Info - err = json.Unmarshal(data, &decoded) - require.NoError(t, err) - + require.NoError(t, json.Unmarshal(data, &decoded)) assert.Equal(t, original.FirstDeployed.Unix(), decoded.FirstDeployed.Unix()) assert.Equal(t, original.LastDeployed.Unix(), decoded.LastDeployed.Unix()) assert.Equal(t, original.Deleted.Unix(), decoded.Deleted.Unix()) @@ -330,8 +328,7 @@ func TestInfoRollbackRevisionRoundTrip(t *testing.T) { require.NoError(t, err) var decoded Info - err = json.Unmarshal(data, &decoded) - require.NoError(t, err) + require.NoError(t, json.Unmarshal(data, &decoded)) assert.Equal(t, tt.info.RollbackRevision, decoded.RollbackRevision) assert.Equal(t, tt.info.FirstDeployed.Unix(), decoded.FirstDeployed.Unix()) @@ -342,8 +339,7 @@ func TestInfoRollbackRevisionRoundTrip(t *testing.T) { // Verify omitempty behavior: zero rollback_revision should not appear in JSON if tt.info.RollbackRevision == 0 { var raw map[string]any - err = json.Unmarshal(data, &raw) - require.NoError(t, err) + require.NoError(t, json.Unmarshal(data, &raw)) assert.NotContains(t, raw, "rollback_revision") } }) @@ -356,13 +352,12 @@ func TestInfoEmptyStringRoundTrip(t *testing.T) { input := `{"first_deployed":"","last_deployed":"","deleted":"","status":"deployed","description":"test"}` var info Info - err := json.Unmarshal([]byte(input), &info) - require.NoError(t, err) + require.NoError(t, json.Unmarshal([]byte(input), &info)) // Verify time fields are zero values - assert.True(t, info.FirstDeployed.IsZero()) - assert.True(t, info.LastDeployed.IsZero()) - assert.True(t, info.Deleted.IsZero()) + assert.Zero(t, info.FirstDeployed) + assert.Zero(t, info.LastDeployed) + assert.Zero(t, info.Deleted) assert.Equal(t, common.StatusDeployed, info.Status) assert.Equal(t, "test", info.Description) @@ -371,8 +366,7 @@ func TestInfoEmptyStringRoundTrip(t *testing.T) { require.NoError(t, err) var result map[string]any - err = json.Unmarshal(data, &result) - require.NoError(t, err) + require.NoError(t, json.Unmarshal(data, &result)) // Zero time values should be omitted due to omitzero tag assert.NotContains(t, result, "first_deployed") From 8c7f3a14d2cbde663847641b1f4274d266e6f0f3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Jul 2026 19:09:32 -0600 Subject: [PATCH 19/61] chore(deps): bump actions/checkout from 7.0.0 to 7.0.1 (#32411) Bumps [actions/checkout](https://github.com/actions/checkout) from 7.0.0 to 7.0.1. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0...3d3c42e5aac5ba805825da76410c181273ba90b1) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 7.0.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-test.yml | 2 +- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/golangci-lint.yml | 2 +- .github/workflows/govulncheck.yml | 2 +- .github/workflows/release.yml | 4 ++-- .github/workflows/scorecards.yml | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 066adf1ce..9503674ed 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout source code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # pin@v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # pin@v7.0.1 - name: Add variables to environment file run: cat ".github/env" >> "$GITHUB_ENV" - name: Setup Go diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index b0a03b342..d02d55b82 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -44,7 +44,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # pin@v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # pin@v7.0.1 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index c5312e936..955f12002 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # pin@v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # pin@v7.0.1 - name: Add variables to environment file run: cat ".github/env" >> "$GITHUB_ENV" - name: Setup Go diff --git a/.github/workflows/govulncheck.yml b/.github/workflows/govulncheck.yml index 0aee4c01c..0fae0be3a 100644 --- a/.github/workflows/govulncheck.yml +++ b/.github/workflows/govulncheck.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # pin@v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # pin@v7.0.1 with: persist-credentials: false - name: Add variables to environment file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3bed1e12a..2b2f93f4d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest-16-cores steps: - name: Checkout source code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # pin@v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # pin@v7.0.1 with: fetch-depth: 0 @@ -85,7 +85,7 @@ jobs: if: github.ref == 'refs/heads/main' && github.repository == 'helm/helm' steps: - name: Checkout source code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # pin@v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # pin@v7.0.1 with: fetch-depth: 0 diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 3a8410ced..41f97dd45 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -28,7 +28,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false From df2d013517b0a237ea8858677558db3129a92911 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 20:50:56 +0200 Subject: [PATCH 20/61] chore(pkg): refactor: convert tests to testify assert/require part 3 refactor: convert tests to testify assert/require in pkg Signed-off-by: Matthieu MOREL --- pkg/chart/v2/util/chartfile_test.go | 107 +++------- pkg/repo/v1/index_test.go | 309 ++++++++-------------------- 2 files changed, 119 insertions(+), 297 deletions(-) diff --git a/pkg/chart/v2/util/chartfile_test.go b/pkg/chart/v2/util/chartfile_test.go index 068977eef..bdcb506da 100644 --- a/pkg/chart/v2/util/chartfile_test.go +++ b/pkg/chart/v2/util/chartfile_test.go @@ -19,6 +19,9 @@ package util import ( "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + chart "helm.sh/helm/v4/pkg/chart/v2" ) @@ -26,96 +29,44 @@ const testfile = "testdata/chartfiletest.yaml" func TestLoadChartfile(t *testing.T) { f, err := LoadChartfile(testfile) - if err != nil { - t.Errorf("Failed to open %s: %s", testfile, err) - return - } + require.NoErrorf(t, err, "Failed to open %s", testfile) verifyChartfile(t, f, "frobnitz") } func verifyChartfile(t *testing.T, f *chart.Metadata, name string) { t.Helper() - if f == nil { - t.Fatal("Failed verifyChartfile because f is nil") - } - - if f.APIVersion != chart.APIVersionV1 { - t.Errorf("Expected API Version %q, got %q", chart.APIVersionV1, f.APIVersion) - } - - if f.Name != name { - t.Errorf("Expected %s, got %s", name, f.Name) - } - - if f.Description != "This is a frobnitz." { - t.Errorf("Unexpected description %q", f.Description) - } - - if f.Version != "1.2.3" { - t.Errorf("Unexpected version %q", f.Version) - } - - if len(f.Maintainers) != 2 { - t.Errorf("Expected 2 maintainers, got %d", len(f.Maintainers)) - } - - if f.Maintainers[0].Name != "The Helm Team" { - t.Error("Unexpected maintainer name.") - } - - if f.Maintainers[1].Email != "nobody@example.com" { - t.Error("Unexpected maintainer email.") - } - - if len(f.Sources) != 1 { - t.Fatal("Unexpected number of sources") - } - - if f.Sources[0] != "https://example.com/foo/bar" { - t.Errorf("Expected https://example.com/foo/bar, got %s", f.Sources) - } - - if f.Home != "http://example.com" { - t.Error("Unexpected home.") - } - - if f.Icon != "https://example.com/64x64.png" { - t.Errorf("Unexpected icon: %q", f.Icon) - } - - if len(f.Keywords) != 3 { - t.Error("Unexpected keywords") - } - - if len(f.Annotations) != 2 { - t.Fatal("Unexpected annotations") - } - - if want, got := "extravalue", f.Annotations["extrakey"]; want != got { - t.Errorf("Want %q, but got %q", want, got) - } - - if want, got := "anothervalue", f.Annotations["anotherkey"]; want != got { - t.Errorf("Want %q, but got %q", want, got) - } + require.NotNil(t, f, "Failed verifyChartfile because f is nil") + assert.Equal(t, chart.APIVersionV1, f.APIVersion, "Expected API Version %q, got %q", chart.APIVersionV1, f.APIVersion) + assert.Equal(t, name, f.Name, "Expected %s, got %s", name, f.Name) + assert.Equal(t, "This is a frobnitz.", f.Description, "Unexpected description %q", f.Description) + assert.Equal(t, "1.2.3", f.Version, "Unexpected version %q", f.Version) + assert.Len(t, f.Maintainers, 2, "Expected 2 maintainers, got %d", len(f.Maintainers)) + assert.Equal(t, "The Helm Team", f.Maintainers[0].Name, "Unexpected maintainer name.") + assert.Equal(t, "nobody@example.com", f.Maintainers[1].Email, "Unexpected maintainer email.") + require.Len(t, f.Sources, 1, "Unexpected number of sources") + assert.Equal(t, "https://example.com/foo/bar", f.Sources[0], "Expected https://example.com/foo/bar, got %s", f.Sources) + assert.Equal(t, "http://example.com", f.Home, "Unexpected home.") + assert.Equal(t, "https://example.com/64x64.png", f.Icon, "Unexpected icon: %q", f.Icon) + assert.Len(t, f.Keywords, 3, "Unexpected keywords") + require.Len(t, f.Annotations, 2, "Unexpected annotations") + + want, got := "extravalue", f.Annotations["extrakey"] + assert.Equalf(t, want, got, "Want %q, but got %q", want, got) + + want, got = "anothervalue", f.Annotations["anotherkey"] + assert.Equalf(t, want, got, "Want %q, but got %q", want, got) kk := []string{"frobnitz", "sprocket", "dodad"} for i, k := range f.Keywords { - if kk[i] != k { - t.Errorf("Expected %q, got %q", kk[i], k) - } + assert.Equal(t, kk[i], k, "Expected %q, got %q", kk[i], k) } } func TestIsChartDir(t *testing.T) { validChartDir, err := IsChartDir("testdata/frobnitz") - if !validChartDir { - t.Errorf("unexpected error while reading chart-directory: (%v)", err) - return - } + require.NoError(t, err) + require.True(t, validChartDir, "expected valid chart directory") validChartDir, err = IsChartDir("testdata") - if validChartDir || err == nil { - t.Error("expected error but did not get any") - return - } + require.Error(t, err) + require.False(t, validChartDir, "expected invalid chart directory") } diff --git a/pkg/repo/v1/index_test.go b/pkg/repo/v1/index_test.go index 126be125f..88aed14d7 100644 --- a/pkg/repo/v1/index_test.go +++ b/pkg/repo/v1/index_test.go @@ -28,6 +28,9 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + chart "helm.sh/helm/v4/pkg/chart/v2" "helm.sh/helm/v4/pkg/cli" "helm.sh/helm/v4/pkg/getter" @@ -95,33 +98,22 @@ func TestIndexFile(t *testing.T) { {&chart.Metadata{APIVersion: "v2", Name: "setter", Version: "0.1.8"}, "setter-0.1.8.tgz", "http://example.com/charts", "sha256:1234567890abc"}, {&chart.Metadata{APIVersion: "v2", Name: "setter", Version: "0.1.8+beta"}, "setter-0.1.8+beta.tgz", "http://example.com/charts", "sha256:1234567890abc"}, } { - if err := i.MustAdd(x.md, x.filename, x.baseURL, x.digest); err != nil { - t.Errorf("unexpected error adding to index: %s", err) - } + require.NoErrorf(t, i.MustAdd(x.md, x.filename, x.baseURL, x.digest), "unexpected error adding to index") } i.SortEntries() - if i.APIVersion != APIVersionV1 { - t.Error("Expected API version v1") - } + assert.Equal(t, APIVersionV1, i.APIVersion, "Expected API version v1") - if len(i.Entries) != 3 { - t.Errorf("Expected 3 charts. Got %d", len(i.Entries)) - } + assert.Lenf(t, i.Entries, 3, "Expected 3 charts. Got %d", len(i.Entries)) - if i.Entries["clipper"][0].Name != "clipper" { - t.Errorf("Expected clipper, got %s", i.Entries["clipper"][0].Name) - } + assert.Equalf(t, "clipper", i.Entries["clipper"][0].Name, "Expected clipper, got %s", i.Entries["clipper"][0].Name) - if len(i.Entries["cutter"]) != 3 { - t.Error("Expected three cutters.") - } + assert.Len(t, i.Entries["cutter"], 3, "Expected three cutters.") // Test that the sort worked. 0.2 should be at the first index for Cutter. - if v := i.Entries["cutter"][0].Version; v != "0.2.0" { - t.Errorf("Unexpected first version: %s", v) - } + v := i.Entries["cutter"][0].Version + assert.Equalf(t, "0.2.0", v, "Unexpected first version: %s", v) cv, err := i.Get("setter", "0.1.9") if err == nil && !strings.Contains(cv.Version, "0.1.9") { @@ -129,14 +121,12 @@ func TestIndexFile(t *testing.T) { } cv, err = i.Get("setter", "0.1.9+alpha") - if err != nil || cv.Version != "0.1.9+alpha" { - t.Error("Expected version: 0.1.9+alpha") - } + require.NoError(t, err, "Expected version: 0.1.9+alpha") + assert.Equal(t, "0.1.9+alpha", cv.Version, "Expected version: 0.1.9+alpha") cv, err = i.Get("setter", "0.1.8") - if err != nil || cv.Version != "0.1.8" { - t.Error("Expected version: 0.1.8") - } + require.NoError(t, err, "Expected version: 0.1.8") + assert.Equal(t, "0.1.8", cv.Version, "Expected version: 0.1.8") } func TestLoadIndex(t *testing.T) { @@ -162,9 +152,7 @@ func TestLoadIndex(t *testing.T) { t.Run(tc.Name, func(t *testing.T) { t.Parallel() i, err := LoadIndexFile(tc.Filename) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) verifyLocalIndex(t, i) }) } @@ -172,52 +160,39 @@ func TestLoadIndex(t *testing.T) { // TestLoadIndex_Duplicates is a regression to make sure that we don't non-deterministically allow duplicate packages. func TestLoadIndex_Duplicates(t *testing.T) { - if _, err := loadIndex([]byte(indexWithDuplicates), "indexWithDuplicates"); err == nil { - t.Error("Expected an error when duplicate entries are present") - } + _, err := loadIndex([]byte(indexWithDuplicates), "indexWithDuplicates") + assert.Error(t, err, "Expected an error when duplicate entries are present") } func TestLoadIndex_EmptyEntry(t *testing.T) { - if _, err := loadIndex([]byte(indexWithEmptyEntry), "indexWithEmptyEntry"); err != nil { - t.Errorf("unexpected error: %s", err) - } + _, err := loadIndex([]byte(indexWithEmptyEntry), "indexWithEmptyEntry") + assert.NoError(t, err) } func TestLoadIndex_Empty(t *testing.T) { - if _, err := loadIndex([]byte(""), "indexWithEmpty"); err == nil { - t.Error("Expected an error when index.yaml is empty.") - } + _, err := loadIndex([]byte(""), "indexWithEmpty") + assert.Error(t, err, "Expected an error when index.yaml is empty.") } func TestLoadIndexFileAnnotations(t *testing.T) { i, err := LoadIndexFile(annotationstestfile) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) verifyLocalIndex(t, i) - if len(i.Annotations) != 1 { - t.Fatalf("Expected 1 annotation but got %d", len(i.Annotations)) - } - if i.Annotations["helm.sh/test"] != "foo bar" { - t.Error("Did not get expected value for helm.sh/test annotation") - } + require.Lenf(t, i.Annotations, 1, "Expected 1 annotation but got %d", len(i.Annotations)) + assert.Equal(t, "foo bar", i.Annotations["helm.sh/test"], "Did not get expected value for helm.sh/test annotation") } func TestLoadUnorderedIndex(t *testing.T) { i, err := LoadIndexFile(unorderedTestfile) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) verifyLocalIndex(t, i) } func TestMerge(t *testing.T) { ind1 := NewIndexFile() - if err := ind1.MustAdd(&chart.Metadata{APIVersion: "v2", Name: "dreadnought", Version: "0.1.0"}, "dreadnought-0.1.0.tgz", "http://example.com", "aaaa"); err != nil { - t.Fatalf("unexpected error: %s", err) - } + require.NoError(t, ind1.MustAdd(&chart.Metadata{APIVersion: "v2", Name: "dreadnought", Version: "0.1.0"}, "dreadnought-0.1.0.tgz", "http://example.com", "aaaa")) ind2 := NewIndexFile() @@ -230,121 +205,89 @@ func TestMerge(t *testing.T) { {&chart.Metadata{APIVersion: "v2", Name: "dreadnought", Version: "0.2.0"}, "dreadnought-0.2.0.tgz", "http://example.com", "aaaabbbb"}, {&chart.Metadata{APIVersion: "v2", Name: "doughnut", Version: "0.2.0"}, "doughnut-0.2.0.tgz", "http://example.com", "ccccbbbb"}, } { - if err := ind2.MustAdd(x.md, x.filename, x.baseURL, x.digest); err != nil { - t.Errorf("unexpected error: %s", err) - } + require.NoError(t, ind2.MustAdd(x.md, x.filename, x.baseURL, x.digest)) } ind1.Merge(ind2) - if len(ind1.Entries) != 2 { - t.Errorf("Expected 2 entries, got %d", len(ind1.Entries)) - } + assert.Lenf(t, ind1.Entries, 2, "Expected 2 entries, got %d", len(ind1.Entries)) vs := ind1.Entries["dreadnought"] - if len(vs) != 2 { - t.Errorf("Expected 2 versions, got %d", len(vs)) - } + assert.Lenf(t, vs, 2, "Expected 2 versions, got %d", len(vs)) - if v := vs[1]; v.Version != "0.2.0" { - t.Errorf("Expected %q version to be 0.2.0, got %s", v.Name, v.Version) - } + v := vs[1] + assert.Equalf(t, "0.2.0", v.Version, "Expected %q version to be 0.2.0, got %s", v.Name, v.Version) } func TestDownloadIndexFile(t *testing.T) { t.Run("should download index file", func(t *testing.T) { srv, err := startLocalServerForTests(nil) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) defer srv.Close() r, err := NewChartRepository(&Entry{ Name: testRepo, URL: srv.URL, }, getter.All(&cli.EnvSettings{})) - if err != nil { - t.Errorf("Problem creating chart repository from %s: %v", testRepo, err) - } + require.NoErrorf(t, err, "Problem creating chart repository from %s", testRepo) idx, err := r.DownloadIndexFile() - if err != nil { - t.Fatalf("Failed to download index file to %s: %#v", idx, err) - } + require.NoErrorf(t, err, "Failed to download index file to %s", idx) - if _, err := os.Stat(idx); err != nil { - t.Fatalf("error finding created index file: %#v", err) - } + _, err = os.Stat(idx) + + require.NoErrorf(t, err, "error finding created index file") i, err := LoadIndexFile(idx) - if err != nil { - t.Fatalf("Index %q failed to parse: %s", testfile, err) - } + require.NoErrorf(t, err, "Index %q failed to parse", testfile) verifyLocalIndex(t, i) // Check that charts file is also created idx = filepath.Join(r.CachePath, helmpath.CacheChartsFile(r.Config.Name)) - if _, err := os.Stat(idx); err != nil { - t.Fatalf("error finding created charts file: %#v", err) - } + _, err = os.Stat(idx) + require.NoErrorf(t, err, "error finding created charts file") b, err := os.ReadFile(idx) - if err != nil { - t.Fatalf("error reading charts file: %#v", err) - } + require.NoErrorf(t, err, "error reading charts file") verifyLocalChartsFile(t, b, i) }) t.Run("should not decode the path in the repo url while downloading index", func(t *testing.T) { chartRepoURLPath := "/some%2Fpath/test" fileBytes, err := os.ReadFile("testdata/local-index.yaml") - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.RawPath == chartRepoURLPath+"/index.yaml" { w.Write(fileBytes) } }) srv, err := startLocalServerForTests(handler) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) defer srv.Close() r, err := NewChartRepository(&Entry{ Name: testRepo, URL: srv.URL + chartRepoURLPath, }, getter.All(&cli.EnvSettings{})) - if err != nil { - t.Errorf("Problem creating chart repository from %s: %v", testRepo, err) - } + require.NoErrorf(t, err, "Problem creating chart repository from %s", testRepo) idx, err := r.DownloadIndexFile() - if err != nil { - t.Fatalf("Failed to download index file to %s: %#v", idx, err) - } + require.NoErrorf(t, err, "Failed to download index file to %s", idx) - if _, err := os.Stat(idx); err != nil { - t.Fatalf("error finding created index file: %#v", err) - } + _, err = os.Stat(idx) + require.NoErrorf(t, err, "error finding created index file") i, err := LoadIndexFile(idx) - if err != nil { - t.Fatalf("Index %q failed to parse: %s", testfile, err) - } + require.NoErrorf(t, err, "Index %q failed to parse", testfile) verifyLocalIndex(t, i) // Check that charts file is also created idx = filepath.Join(r.CachePath, helmpath.CacheChartsFile(r.Config.Name)) - if _, err := os.Stat(idx); err != nil { - t.Fatalf("error finding created charts file: %#v", err) - } + _, err = os.Stat(idx) + require.NoErrorf(t, err, "error finding created charts file") b, err := os.ReadFile(idx) - if err != nil { - t.Fatalf("error reading charts file: %#v", err) - } + require.NoErrorf(t, err, "error reading charts file") verifyLocalChartsFile(t, b, i) }) } @@ -352,18 +295,13 @@ func TestDownloadIndexFile(t *testing.T) { func verifyLocalIndex(t *testing.T, i *IndexFile) { t.Helper() numEntries := len(i.Entries) - if numEntries != 3 { - t.Errorf("Expected 3 entries in index file but got %d", numEntries) - } + assert.Equalf(t, 3, numEntries, "Expected 3 entries in index file but got %d", numEntries) alpine, ok := i.Entries["alpine"] - if !ok { - t.Fatal("'alpine' section not found.") - } + require.True(t, ok, "'alpine' section not found.") - if l := len(alpine); l != 1 { - t.Fatalf("'alpine' should have 1 chart, got %d", l) - } + l := len(alpine) + require.Equalf(t, 1, l, "'alpine' should have 1 chart, got %d", l) nginx, ok := i.Entries["nginx"] if !ok || len(nginx) != 2 { @@ -419,31 +357,17 @@ func verifyLocalIndex(t *testing.T, i *IndexFile) { for i, tt := range tests { expect := expects[i] - if tt.Name != expect.Name { - t.Errorf("Expected name %q, got %q", expect.Name, tt.Name) - } - if tt.Description != expect.Description { - t.Errorf("Expected description %q, got %q", expect.Description, tt.Description) - } - if tt.Version != expect.Version { - t.Errorf("Expected version %q, got %q", expect.Version, tt.Version) - } - if tt.Digest != expect.Digest { - t.Errorf("Expected digest %q, got %q", expect.Digest, tt.Digest) - } - if tt.Home != expect.Home { - t.Errorf("Expected home %q, got %q", expect.Home, tt.Home) - } + assert.Equalf(t, expect.Name, tt.Name, "Expected name %q, got %q", expect.Name, tt.Name) + assert.Equalf(t, expect.Description, tt.Description, "Expected description %q, got %q", expect.Description, tt.Description) + assert.Equalf(t, expect.Version, tt.Version, "Expected version %q, got %q", expect.Version, tt.Version) + assert.Equalf(t, expect.Digest, tt.Digest, "Expected digest %q, got %q", expect.Digest, tt.Digest) + assert.Equalf(t, expect.Home, tt.Home, "Expected home %q, got %q", expect.Home, tt.Home) for i, url := range tt.URLs { - if url != expect.URLs[i] { - t.Errorf("Expected URL %q, got %q", expect.URLs[i], url) - } + assert.Equalf(t, expect.URLs[i], url, "Expected URL %q, got %q", expect.URLs[i], url) } for i, kw := range tt.Keywords { - if kw != expect.Keywords[i] { - t.Errorf("Expected keywords %q, got %q", expect.Keywords[i], kw) - } + assert.Equalf(t, expect.Keywords[i], kw, "Expected keywords %q, got %q", expect.Keywords[i], kw) } } } @@ -462,21 +386,16 @@ func verifyLocalChartsFile(t *testing.T, chartsContent []byte, indexContent *Ind } sort.Strings(reald) - if strings.Join(expected, " ") != strings.Join(reald, " ") { - t.Errorf("Cached charts file content unexpected. Expected:\n%s\ngot:\n%s", expected, reald) - } + assert.Equalf(t, strings.Join(expected, " "), strings.Join(reald, " "), "Cached charts file content unexpected. Expected:\n%s\ngot:\n%s", expected, reald) } func TestIndexDirectory(t *testing.T) { dir := "testdata/repository" index, err := IndexDirectory(dir, "http://localhost:8080") - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if l := len(index.Entries); l != 3 { - t.Fatalf("Expected 3 entries, got %d", l) - } + l := len(index.Entries) + require.Equalf(t, 3, l, "Expected 3 entries, got %d", l) // Other things test the entry generation more thoroughly. We just test a // few fields. @@ -489,20 +408,12 @@ func TestIndexDirectory(t *testing.T) { for _, test := range corpus { cname := test.chartName frobs, ok := index.Entries[cname] - if !ok { - t.Fatalf("Could not read chart %s", cname) - } + require.Truef(t, ok, "Could not read chart %s", cname) frob := frobs[0] - if frob.Digest == "" { - t.Errorf("Missing digest of file %s.", frob.Name) - } - if frob.URLs[0] != test.downloadLink { - t.Errorf("Unexpected URLs: %v", frob.URLs) - } - if frob.Name != cname { - t.Errorf("Expected %q, got %q", cname, frob.Name) - } + assert.NotEmptyf(t, frob.Digest, "Missing digest of file %s.", frob.Name) + assert.Equalf(t, test.downloadLink, frob.URLs[0], "Unexpected URLs: %v", frob.URLs) + assert.Equalf(t, cname, frob.Name, "Expected %q, got %q", cname, frob.Name) } } @@ -520,64 +431,40 @@ func TestIndexAdd(t *testing.T) { {&chart.Metadata{APIVersion: "v2", Name: "alpine", Version: "0.1.0"}, "/home/charts/alpine-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890"}, {&chart.Metadata{APIVersion: "v2", Name: "deis", Version: "0.1.0"}, "/home/charts/deis-0.1.0.tgz", "http://example.com/charts/", "sha256:1234567890"}, } { - if err := i.MustAdd(x.md, x.filename, x.baseURL, x.digest); err != nil { - t.Errorf("unexpected error adding to index: %s", err) - } + require.NoErrorf(t, i.MustAdd(x.md, x.filename, x.baseURL, x.digest), "unexpected error adding to index") } - if i.Entries["clipper"][0].URLs[0] != "http://example.com/charts/clipper-0.1.0.tgz" { - t.Errorf("Expected http://example.com/charts/clipper-0.1.0.tgz, got %s", i.Entries["clipper"][0].URLs[0]) - } - if i.Entries["alpine"][0].URLs[0] != "http://example.com/charts/alpine-0.1.0.tgz" { - t.Errorf("Expected http://example.com/charts/alpine-0.1.0.tgz, got %s", i.Entries["alpine"][0].URLs[0]) - } - if i.Entries["deis"][0].URLs[0] != "http://example.com/charts/deis-0.1.0.tgz" { - t.Errorf("Expected http://example.com/charts/deis-0.1.0.tgz, got %s", i.Entries["deis"][0].URLs[0]) - } + assert.Equalf(t, "http://example.com/charts/clipper-0.1.0.tgz", i.Entries["clipper"][0].URLs[0], "Expected http://example.com/charts/clipper-0.1.0.tgz, got %s", i.Entries["clipper"][0].URLs[0]) + assert.Equalf(t, "http://example.com/charts/alpine-0.1.0.tgz", i.Entries["alpine"][0].URLs[0], "Expected http://example.com/charts/alpine-0.1.0.tgz, got %s", i.Entries["alpine"][0].URLs[0]) + assert.Equalf(t, "http://example.com/charts/deis-0.1.0.tgz", i.Entries["deis"][0].URLs[0], "Expected http://example.com/charts/deis-0.1.0.tgz, got %s", i.Entries["deis"][0].URLs[0]) // test error condition - if err := i.MustAdd(&chart.Metadata{}, "error-0.1.0.tgz", "", ""); err == nil { - t.Fatal("expected error adding to index") - } + require.Error(t, i.MustAdd(&chart.Metadata{}, "error-0.1.0.tgz", "", ""), "expected error adding to index") } func TestIndexWrite(t *testing.T) { i := NewIndexFile() - if err := i.MustAdd(&chart.Metadata{APIVersion: "v2", Name: "clipper", Version: "0.1.0"}, "clipper-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890"); err != nil { - t.Fatalf("unexpected error: %s", err) - } + require.NoError(t, i.MustAdd(&chart.Metadata{APIVersion: "v2", Name: "clipper", Version: "0.1.0"}, "clipper-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890")) dir := t.TempDir() testpath := filepath.Join(dir, "test") i.WriteFile(testpath, 0o600) got, err := os.ReadFile(testpath) - if err != nil { - t.Fatal(err) - } - if !strings.Contains(string(got), "clipper-0.1.0.tgz") { - t.Fatal("Index files doesn't contain expected content") - } + require.NoError(t, err) + require.Contains(t, string(got), "clipper-0.1.0.tgz", "Index files doesn't contain expected content") } func TestIndexJSONWrite(t *testing.T) { i := NewIndexFile() - if err := i.MustAdd(&chart.Metadata{APIVersion: "v2", Name: "clipper", Version: "0.1.0"}, "clipper-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890"); err != nil { - t.Fatalf("unexpected error: %s", err) - } + require.NoError(t, i.MustAdd(&chart.Metadata{APIVersion: "v2", Name: "clipper", Version: "0.1.0"}, "clipper-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890")) dir := t.TempDir() testpath := filepath.Join(dir, "test") i.WriteJSONFile(testpath, 0o600) got, err := os.ReadFile(testpath) - if err != nil { - t.Fatal(err) - } - if !json.Valid(got) { - t.Fatal("Index files doesn't contain valid JSON") - } - if !strings.Contains(string(got), "clipper-0.1.0.tgz") { - t.Fatal("Index files doesn't contain expected content") - } + require.NoError(t, err) + require.True(t, json.Valid(got), "Index files doesn't contain valid JSON") + require.Contains(t, string(got), "clipper-0.1.0.tgz", "Index files doesn't contain expected content") } func TestAddFileIndexEntriesNil(t *testing.T) { @@ -592,9 +479,7 @@ func TestAddFileIndexEntriesNil(t *testing.T) { }{ {&chart.Metadata{APIVersion: "v2", Name: " ", Version: "8033-5.apinie+s.r"}, "setter-0.1.9+beta.tgz", "http://example.com/charts", "sha256:1234567890abc"}, } { - if err := i.MustAdd(x.md, x.filename, x.baseURL, x.digest); err == nil { - t.Error("expected err to be non-nil when entries not initialized") - } + assert.Error(t, i.MustAdd(x.md, x.filename, x.baseURL, x.digest), "expected err to be non-nil when entries not initialized") } } @@ -624,22 +509,16 @@ func TestIgnoreSkippableChartValidationError(t *testing.T) { result := ignoreSkippableChartValidationError(tc.Input) if tc.Input == nil { - if result != nil { - t.Error("expected nil result for nil input") - } + assert.NoError(t, result, "expected nil result for nil input") return } if tc.ErrorSkipped { - if result != nil { - t.Error("expected nil result for skipped error") - } + assert.NoError(t, result, "expected nil result for skipped error") return } - if !errors.Is(tc.Input, result) { - t.Error("expected the result equal to input") - } + assert.ErrorIs(t, tc.Input, result, "expected the result equal to input") }) } } @@ -700,17 +579,11 @@ func TestLoadIndex_DuplicateChartDeps(t *testing.T) { for _, tc := range tests { t.Run(tc.source, func(t *testing.T) { idx, err := loadIndex([]byte(tc.data), tc.source) - if err != nil { - t.Fatalf("unexpected error: %s", err) - } + require.NoError(t, err) cvs := idx.Entries["nginx"] - if cvs == nil { - t.Error("expected one chart version not to be filtered out") - } + assert.NotNil(t, cvs, "expected one chart version not to be filtered out") for _, v := range cvs { - if v.Name == "alpine" { - t.Error("malformed version was not filtered out") - } + assert.NotEqual(t, "alpine", v.Name, "malformed version was not filtered out") } }) } @@ -751,9 +624,7 @@ func TestIsVersionRange(t *testing.T) { for _, tt := range tests { t.Run(tt.version, func(t *testing.T) { got := isVersionRange(tt.version) - if got != tt.expected { - t.Errorf("isVersionRange(%q) = %v, want %v", tt.version, got, tt.expected) - } + assert.Equalf(t, tt.expected, got, "isVersionRange(%q) = %v, want %v", tt.version, got, tt.expected) }) } } From 658a8fac156a92a7462cc9aab98da796da6dc116 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 20:50:57 +0200 Subject: [PATCH 21/61] chore(pkg): refactor: convert tests to testify assert/require part 4 refactor: convert tests to testify assert/require in pkg Signed-off-by: Matthieu MOREL --- pkg/chart/v2/loader/load_test.go | 322 ++++++++---------------------- pkg/storage/driver/memory_test.go | 93 +++------ 2 files changed, 116 insertions(+), 299 deletions(-) diff --git a/pkg/chart/v2/loader/load_test.go b/pkg/chart/v2/loader/load_test.go index 46d17e899..da5c3b725 100644 --- a/pkg/chart/v2/loader/load_test.go +++ b/pkg/chart/v2/loader/load_test.go @@ -31,6 +31,7 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "helm.sh/helm/v4/pkg/chart/common" @@ -40,13 +41,9 @@ import ( func TestLoadDir(t *testing.T) { l, err := Loader("testdata/frobnitz") - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") c, err := l.Load() - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") verifyFrobnitz(t, c) verifyChart(t, c) verifyDependencies(t, c) @@ -59,33 +56,24 @@ func TestLoadDirWithDevNull(t *testing.T) { } l, err := Loader("testdata/frobnitz_with_dev_null") - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } - if _, err := l.Load(); err == nil { - t.Error("packages with an irregular file (/dev/null) should not load") - } + require.NoError(t, err, "Failed to load testdata") + _, err = l.Load() + assert.Error(t, err, "packages with an irregular file (/dev/null) should not load") } func TestLoadDirWithSymlink(t *testing.T) { sym := filepath.Join("..", "LICENSE") link := filepath.Join("testdata", "frobnitz_with_symlink", "LICENSE") - if err := os.Symlink(sym, link); err != nil { - t.Fatal(err) - } + require.NoError(t, os.Symlink(sym, link)) defer os.Remove(link) l, err := Loader("testdata/frobnitz_with_symlink") - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") c, err := l.Load() - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") verifyFrobnitz(t, c) verifyChart(t, c) verifyDependencies(t, c) @@ -102,18 +90,13 @@ func TestBomTestData(t *testing.T) { } archive, err := os.ReadFile("testdata/frobnitz_with_bom.tgz") - if err != nil { - t.Fatalf("Error reading archive frobnitz_with_bom.tgz: %s", err) - } + require.NoError(t, err, "Error reading archive frobnitz_with_bom.tgz") unzipped, err := gzip.NewReader(bytes.NewReader(archive)) - if err != nil { - t.Fatalf("Error reading archive frobnitz_with_bom.tgz: %s", err) - } + require.NoError(t, err, "Error reading archive frobnitz_with_bom.tgz") defer unzipped.Close() for _, testFile := range testFiles { data := make([]byte, 3) - err := unzipped.Reset(bytes.NewReader(archive)) - require.NoErrorf(t, err, "Error reading archive frobnitz_with_bom.tgz") + require.NoErrorf(t, unzipped.Reset(bytes.NewReader(archive)), "Error reading archive frobnitz_with_bom.tgz") tr := tar.NewReader(unzipped) for { file, err := tr.Next() @@ -135,13 +118,9 @@ func TestBomTestData(t *testing.T) { func TestLoadDirWithUTFBOM(t *testing.T) { l, err := Loader("testdata/frobnitz_with_bom") - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") c, err := l.Load() - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") verifyFrobnitz(t, c) verifyChart(t, c) verifyDependencies(t, c) @@ -151,13 +130,9 @@ func TestLoadDirWithUTFBOM(t *testing.T) { func TestLoadArchiveWithUTFBOM(t *testing.T) { l, err := Loader("testdata/frobnitz_with_bom.tgz") - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") c, err := l.Load() - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") verifyFrobnitz(t, c) verifyChart(t, c) verifyDependencies(t, c) @@ -167,39 +142,27 @@ func TestLoadArchiveWithUTFBOM(t *testing.T) { func TestLoadV1(t *testing.T) { l, err := Loader("testdata/frobnitz.v1") - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") c, err := l.Load() - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") verifyDependencies(t, c) verifyDependenciesLock(t, c) } func TestLoadFileV1(t *testing.T) { l, err := Loader("testdata/frobnitz.v1.tgz") - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") c, err := l.Load() - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") verifyDependencies(t, c) verifyDependenciesLock(t, c) } func TestLoadFile(t *testing.T) { l, err := Loader("testdata/frobnitz-1.2.3.tgz") - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") c, err := l.Load() - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") verifyFrobnitz(t, c) verifyChart(t, c) verifyDependencies(t, c) @@ -223,12 +186,8 @@ func TestLoadFiles_BadCases(t *testing.T) { expectError: "validation: chart.metadata.apiVersion is required"}, } { _, err := LoadFiles(tt.bufferedFiles) - if err == nil { - t.Fatal("expected error when load illegal files") - } - if !strings.Contains(err.Error(), tt.expectError) { - t.Errorf("Expected error to contain %q, got %q for %s", tt.expectError, err.Error(), tt.name) - } + require.Error(t, err, "expected error when load illegal files") + assert.ErrorContains(t, err, tt.expectError, "Expected error to contain %q, got %q for %s", tt.expectError, err.Error(), tt.name) } } @@ -280,36 +239,16 @@ icon: https://example.com/64x64.png } c, err := LoadFiles(goodFiles) - if err != nil { - t.Errorf("Expected good files to be loaded, got %v", err) - } - - if c.Name() != "frobnitz" { - t.Errorf("Expected chart name to be 'frobnitz', got %s", c.Name()) - } - - if c.Values["var"] != "some values" { - t.Error("Expected chart values to be populated with default values") - } - - if len(c.Raw) != 5 { - t.Errorf("Expected %d files, got %d", 5, len(c.Raw)) - } - - if !bytes.Equal(c.Schema, []byte("type: Values")) { - t.Error("Expected chart schema to be populated with default values") - } - - if len(c.Templates) != 2 { - t.Errorf("Expected number of templates == 2, got %d", len(c.Templates)) - } - - if _, err = LoadFiles([]*archive.BufferedFile{}); err == nil { - t.Fatal("Expected err to be non-nil") - } - if err.Error() != "Chart.yaml file is missing" { - t.Errorf("Expected chart metadata missing error, got '%s'", err.Error()) - } + require.NoError(t, err, "Expected good files to be loaded") + assert.Equal(t, "frobnitz", c.Name(), "Expected chart name to be 'frobnitz', got %s", c.Name()) + assert.Equal(t, "some values", c.Values["var"], "Expected chart values to be populated with default values") + assert.Len(t, c.Raw, 5, "Expected %d files, got %d", 5, len(c.Raw)) + assert.True(t, bytes.Equal(c.Schema, []byte("type: Values")), "Expected chart schema to be populated with default values") + assert.Len(t, c.Templates, 2, "Expected number of templates == 2, got %d", len(c.Templates)) + + _, err = LoadFiles([]*archive.BufferedFile{}) + require.Error(t, err, "Expected err to be non-nil") + assert.EqualError(t, err, "Chart.yaml file is missing") } // Test the order of file loading. The Chart.yaml file needs to come first for @@ -365,9 +304,7 @@ icon: https://example.com/64x64.png // Capture stderr to make sure message about Chart.yaml handle dependencies // is not present r, w, err := os.Pipe() - if err != nil { - t.Fatalf("Unable to create pipe: %s", err) - } + require.NoError(t, err, "Unable to create pipe") stderr := log.Writer() log.SetOutput(w) defer func() { @@ -375,25 +312,19 @@ icon: https://example.com/64x64.png }() _, err = LoadFiles(goodFiles) - if err != nil { - t.Errorf("Expected good files to be loaded, got %v", err) - } + require.NoError(t, err, "Expected good files to be loaded") w.Close() var text bytes.Buffer io.Copy(&text, r) - if text.String() != "" { - t.Errorf("Expected no message to Stderr, got %s", text.String()) - } + assert.Empty(t, text.String(), "Expected no message to Stderr, got %s", text.String()) } // Packaging the chart on a Windows machine will produce an // archive that has \\ as delimiters. Test that we support these archives func TestLoadFileBackslash(t *testing.T) { c, err := Load("testdata/frobnitz_backslash-1.2.3.tgz") - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") verifyChartFileAndTemplate(t, c, "frobnitz_backslash") verifyChart(t, c) verifyDependencies(t, c) @@ -401,13 +332,9 @@ func TestLoadFileBackslash(t *testing.T) { func TestLoadV2WithReqs(t *testing.T) { l, err := Loader("testdata/frobnitz.v2.reqs") - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") c, err := l.Load() - if err != nil { - t.Fatalf("Failed to load testdata: %s", err) - } + require.NoError(t, err, "Failed to load testdata") verifyDependencies(t, c) verifyDependenciesLock(t, c) } @@ -417,9 +344,7 @@ func TestLoadInvalidArchive(t *testing.T) { writeTar := func(filename, internalPath string, body []byte) { dest, err := os.Create(filename) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) zipper := gzip.NewWriter(dest) tw := tar.NewWriter(zipper) @@ -429,12 +354,9 @@ func TestLoadInvalidArchive(t *testing.T) { Size: int64(len(body)), ModTime: time.Now(), } - if err := tw.WriteHeader(h); err != nil { - t.Fatal(err) - } - if _, err := tw.Write(body); err != nil { - t.Fatal(err) - } + require.NoError(t, tw.WriteHeader(h)) + _, err = tw.Write(body) + require.NoError(t, err) tw.Close() zipper.Close() dest.Close() @@ -466,37 +388,27 @@ func TestLoadInvalidArchive(t *testing.T) { illegalChart := filepath.Join(tmpdir, tt.chartname) writeTar(illegalChart, tt.internal, []byte("hello: world")) _, err := Load(illegalChart) - if err == nil { - t.Fatal("expected error when unpacking illegal files") - } - if !strings.Contains(err.Error(), tt.expectError) { - t.Errorf("Expected error to contain %q, got %q for %s", tt.expectError, err.Error(), tt.chartname) - } + require.Error(t, err, "expected error when unpacking illegal files") + require.ErrorContains(t, err, tt.expectError, "Expected error to contain %q, got %q for %s", tt.expectError, err.Error(), tt.chartname) } // Make sure that absolute path gets interpreted as relative illegalChart := filepath.Join(tmpdir, "abs-path.tgz") writeTar(illegalChart, "/Chart.yaml", []byte("hello: world")) _, err := Load(illegalChart) - if err.Error() != "validation: chart.metadata.name is required" { - t.Error(err) - } + require.EqualError(t, err, "validation: chart.metadata.name is required") // And just to validate that the above was not spurious illegalChart = filepath.Join(tmpdir, "abs-path2.tgz") writeTar(illegalChart, "files/whatever.yaml", []byte("hello: world")) _, err = Load(illegalChart) - if err.Error() != "Chart.yaml file is missing" { - t.Errorf("Unexpected error message: %s", err) - } + require.EqualError(t, err, "Chart.yaml file is missing") // Finally, test that drive letter gets stripped off on Windows illegalChart = filepath.Join(tmpdir, "abs-winpath.tgz") writeTar(illegalChart, "c:\\Chart.yaml", []byte("hello: world")) _, err = Load(illegalChart) - if err.Error() != "validation: chart.metadata.name is required" { - t.Error(err) - } + assert.EqualError(t, err, "validation: chart.metadata.name is required") } func TestLoadValues(t *testing.T) { @@ -543,12 +455,8 @@ foo: for testName, testCase := range testCases { t.Run(testName, func(tt *testing.T) { values, err := LoadValues(bytes.NewReader(testCase.data)) - if err != nil { - tt.Fatal(err) - } - if !reflect.DeepEqual(values, testCase.expctedValues) { - tt.Errorf("Expected values: %v, got %v", testCase.expctedValues, values) - } + require.NoError(tt, err) + assert.Truef(t, reflect.DeepEqual(values, testCase.expctedValues), "Expected values: %v, got %v", testCase.expctedValues, values) }) } } @@ -577,21 +485,15 @@ func TestMergeValuesV2(t *testing.T) { testMap := MergeMaps(flatMap, nestedMap) equal := reflect.DeepEqual(testMap, nestedMap) - if !equal { - t.Errorf("Expected a nested map to overwrite a flat value. Expected: %v, got %v", nestedMap, testMap) - } + assert.True(t, equal, "Expected a nested map to overwrite a flat value. Expected: %v, got %v", nestedMap, testMap) testMap = MergeMaps(nestedMap, flatMap) equal = reflect.DeepEqual(testMap, flatMap) - if !equal { - t.Errorf("Expected a flat value to overwrite a map. Expected: %v, got %v", flatMap, testMap) - } + assert.True(t, equal, "Expected a flat value to overwrite a map. Expected: %v, got %v", flatMap, testMap) testMap = MergeMaps(nestedMap, anotherNestedMap) equal = reflect.DeepEqual(testMap, anotherNestedMap) - if !equal { - t.Errorf("Expected a nested map to overwrite another nested map. Expected: %v, got %v", anotherNestedMap, testMap) - } + assert.True(t, equal, "Expected a nested map to overwrite another nested map. Expected: %v, got %v", anotherNestedMap, testMap) testMap = MergeMaps(anotherFlatMap, anotherNestedMap) expectedMap := map[string]any{ @@ -603,20 +505,14 @@ func TestMergeValuesV2(t *testing.T) { }, } equal = reflect.DeepEqual(testMap, expectedMap) - if !equal { - t.Errorf("Expected a map with different keys to merge properly with another map. Expected: %v, got %v", expectedMap, testMap) - } + assert.True(t, equal, "Expected a map with different keys to merge properly with another map. Expected: %v, got %v", expectedMap, testMap) } func verifyChart(t *testing.T, c *chart.Chart) { t.Helper() - if c.Name() == "" { - t.Fatalf("No chart metadata found on %v", c) - } + require.NotEmpty(t, c.Name(), "No chart metadata found on %v", c) t.Logf("Verifying chart %s", c.Name()) - if len(c.Templates) != 1 { - t.Errorf("Expected 1 template, got %d", len(c.Templates)) - } + assert.Len(t, c.Templates, 1, "Expected 1 template, got %d", len(c.Templates)) numfiles := 6 if len(c.Files) != numfiles { @@ -643,62 +539,40 @@ func verifyChart(t *testing.T, c *chart.Chart) { } for _, dep := range c.Dependencies() { - if dep.Metadata == nil { - t.Fatalf("expected metadata on dependency: %v", dep) - } + require.NotNil(t, dep.Metadata, "expected metadata on dependency: %v", dep) exp, ok := expect[dep.Name()] - if !ok { - t.Fatalf("Unknown dependency %s", dep.Name()) - } - if exp["version"] != dep.Metadata.Version { - t.Errorf("Expected %s version %s, got %s", dep.Name(), exp["version"], dep.Metadata.Version) - } + require.True(t, ok, "Unknown dependency %s", dep.Name()) + assert.Equal(t, dep.Metadata.Version, exp["version"], "Expected %s version %s, got %s", dep.Name(), exp["version"], dep.Metadata.Version) } } func verifyDependencies(t *testing.T, c *chart.Chart) { t.Helper() - if len(c.Metadata.Dependencies) != 2 { - t.Errorf("Expected 2 dependencies, got %d", len(c.Metadata.Dependencies)) - } + assert.Len(t, c.Metadata.Dependencies, 2, "Expected 2 dependencies, got %d", len(c.Metadata.Dependencies)) tests := []*chart.Dependency{ {Name: "alpine", Version: "0.1.0", Repository: "https://example.com/charts"}, {Name: "mariner", Version: "4.3.2", Repository: "https://example.com/charts"}, } for i, tt := range tests { d := c.Metadata.Dependencies[i] - if d.Name != tt.Name { - t.Errorf("Expected dependency named %q, got %q", tt.Name, d.Name) - } - if d.Version != tt.Version { - t.Errorf("Expected dependency named %q to have version %q, got %q", tt.Name, tt.Version, d.Version) - } - if d.Repository != tt.Repository { - t.Errorf("Expected dependency named %q to have repository %q, got %q", tt.Name, tt.Repository, d.Repository) - } + assert.Equal(t, tt.Name, d.Name, "Expected dependency named %q, got %q", tt.Name, d.Name) + assert.Equal(t, tt.Version, d.Version, "Expected dependency named %q to have version %q, got %q", tt.Name, tt.Version, d.Version) + assert.Equal(t, tt.Repository, d.Repository, "Expected dependency named %q to have repository %q, got %q", tt.Name, tt.Repository, d.Repository) } } func verifyDependenciesLock(t *testing.T, c *chart.Chart) { t.Helper() - if len(c.Metadata.Dependencies) != 2 { - t.Errorf("Expected 2 dependencies, got %d", len(c.Metadata.Dependencies)) - } + assert.Len(t, c.Metadata.Dependencies, 2, "Expected 2 dependencies, got %d", len(c.Metadata.Dependencies)) tests := []*chart.Dependency{ {Name: "alpine", Version: "0.1.0", Repository: "https://example.com/charts"}, {Name: "mariner", Version: "4.3.2", Repository: "https://example.com/charts"}, } for i, tt := range tests { d := c.Metadata.Dependencies[i] - if d.Name != tt.Name { - t.Errorf("Expected dependency named %q, got %q", tt.Name, d.Name) - } - if d.Version != tt.Version { - t.Errorf("Expected dependency named %q to have version %q, got %q", tt.Name, tt.Version, d.Version) - } - if d.Repository != tt.Repository { - t.Errorf("Expected dependency named %q to have repository %q, got %q", tt.Name, tt.Repository, d.Repository) - } + assert.Equal(t, tt.Name, d.Name, "Expected dependency named %q, got %q", tt.Name, d.Name) + assert.Equal(t, tt.Version, d.Version, "Expected dependency named %q to have version %q, got %q", tt.Name, tt.Version, d.Version) + assert.Equal(t, tt.Repository, d.Repository, "Expected dependency named %q to have repository %q, got %q", tt.Name, tt.Repository, d.Repository) } } @@ -709,53 +583,25 @@ func verifyFrobnitz(t *testing.T, c *chart.Chart) { func verifyChartFileAndTemplate(t *testing.T, c *chart.Chart, name string) { t.Helper() - if c.Metadata == nil { - t.Fatal("Metadata is nil") - } - if c.Name() != name { - t.Errorf("Expected %s, got %s", name, c.Name()) - } - if len(c.Templates) != 1 { - t.Fatalf("Expected 1 template, got %d", len(c.Templates)) - } - if c.Templates[0].Name != "templates/template.tpl" { - t.Errorf("Unexpected template: %s", c.Templates[0].Name) - } - if len(c.Templates[0].Data) == 0 { - t.Error("No template data.") - } - if len(c.Files) != 6 { - t.Fatalf("Expected 6 Files, got %d", len(c.Files)) - } - if len(c.Dependencies()) != 2 { - t.Fatalf("Expected 2 Dependency, got %d", len(c.Dependencies())) - } - if len(c.Metadata.Dependencies) != 2 { - t.Fatalf("Expected 2 Dependencies.Dependency, got %d", len(c.Metadata.Dependencies)) - } - if len(c.Lock.Dependencies) != 2 { - t.Fatalf("Expected 2 Lock.Dependency, got %d", len(c.Lock.Dependencies)) - } + require.NotNil(t, c.Metadata, "Metadata is nil") + assert.Equal(t, name, c.Name(), "Expected %s, got %s", name, c.Name()) + require.Len(t, c.Templates, 1, "Expected 1 template, got %d", len(c.Templates)) + assert.Equal(t, "templates/template.tpl", c.Templates[0].Name, "Unexpected template: %s", c.Templates[0].Name) + assert.NotEmpty(t, c.Templates[0].Data, "No template data.") + require.Len(t, c.Files, 6, "Expected 6 Files, got %d", len(c.Files)) + require.Len(t, c.Dependencies(), 2, "Expected 2 Dependency, got %d", len(c.Dependencies())) + require.Len(t, c.Metadata.Dependencies, 2, "Expected 2 Dependencies.Dependency, got %d", len(c.Metadata.Dependencies)) + require.Len(t, c.Lock.Dependencies, 2, "Expected 2 Lock.Dependency, got %d", len(c.Lock.Dependencies)) for _, dep := range c.Dependencies() { switch dep.Name() { case "mariner": case "alpine": - if len(dep.Templates) != 1 { - t.Fatalf("Expected 1 template, got %d", len(dep.Templates)) - } - if dep.Templates[0].Name != "templates/alpine-pod.yaml" { - t.Errorf("Unexpected template: %s", dep.Templates[0].Name) - } - if len(dep.Templates[0].Data) == 0 { - t.Error("No template data.") - } - if len(dep.Files) != 1 { - t.Fatalf("Expected 1 Files, got %d", len(dep.Files)) - } - if len(dep.Dependencies()) != 2 { - t.Fatalf("Expected 2 Dependency, got %d", len(dep.Dependencies())) - } + require.Len(t, dep.Templates, 1, "Expected 1 template, got %d", len(dep.Templates)) + assert.Equal(t, "templates/alpine-pod.yaml", dep.Templates[0].Name, "Unexpected template: %s", dep.Templates[0].Name) + assert.NotEmpty(t, dep.Templates[0].Data, "No template data.") + require.Len(t, dep.Files, 1, "Expected 1 Files, got %d", len(dep.Files)) + require.Len(t, dep.Dependencies(), 2, "Expected 2 Dependency, got %d", len(dep.Dependencies())) default: t.Errorf("Unexpected dependency %s", dep.Name()) } @@ -765,8 +611,6 @@ func verifyChartFileAndTemplate(t *testing.T, c *chart.Chart, name string) { func verifyBomStripped(t *testing.T, files []*common.File) { t.Helper() for _, file := range files { - if bytes.HasPrefix(file.Data, utf8bom) { - t.Errorf("Byte Order Mark still present in processed file %s", file.Name) - } + assert.Falsef(t, bytes.HasPrefix(file.Data, utf8bom), "Byte Order Mark still present in processed file %s", file.Name) } } diff --git a/pkg/storage/driver/memory_test.go b/pkg/storage/driver/memory_test.go index 6040daf59..7a8d4cb3e 100644 --- a/pkg/storage/driver/memory_test.go +++ b/pkg/storage/driver/memory_test.go @@ -21,6 +21,7 @@ import ( "reflect" "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "helm.sh/helm/v4/pkg/release" @@ -29,9 +30,8 @@ import ( ) func TestMemoryName(t *testing.T) { - if mem := NewMemory(); mem.Name() != MemoryDriverName { - t.Errorf("Expected name to be %q, got %q", MemoryDriverName, mem.Name()) - } + mem := NewMemory() + assert.Equalf(t, MemoryDriverName, mem.Name(), "Expected name to be %q, got %q", MemoryDriverName, mem.Name()) } func TestMemoryCreate(t *testing.T) { @@ -66,13 +66,12 @@ func TestMemoryCreate(t *testing.T) { for _, tt := range tests { key := testKey(tt.rls.Name, tt.rls.Version) rls := tt.rls + err := ts.Create(key, rls) - if err := ts.Create(key, rls); err != nil { - if !tt.err { - t.Fatalf("failed to create %q: %s", tt.desc, err) - } - } else if tt.err { - t.Fatalf("Did not get expected error for %q\n", tt.desc) + if tt.err { + require.Error(t, err, "Did not get expected error for %q\n", tt.desc) + } else { + require.NoError(t, err, "failed to create %q", tt.desc) } } } @@ -93,12 +92,11 @@ func TestMemoryGet(t *testing.T) { ts := tsFixtureMemory(t) for _, tt := range tests { ts.SetNamespace(tt.namespace) - if _, err := ts.Get(tt.key); err != nil { - if !tt.err { - t.Fatalf("Failed %q to get '%s': %q\n", tt.desc, tt.key, err) - } - } else if tt.err { - t.Fatalf("Did not get expected error for %q '%s'\n", tt.desc, tt.key) + _, err := ts.Get(tt.key) + if tt.err { + require.Error(t, err, "Did not get expected error for %q '%s'\n", tt.desc, tt.key) + } else { + require.NoError(t, err, "Failed %q to get '%s'", tt.desc, tt.key) } } } @@ -113,12 +111,8 @@ func TestMemoryList(t *testing.T) { return rls.Info.Status == common.StatusDeployed }) // check - if err != nil { - t.Errorf("Failed to list deployed releases: %s", err) - } - if len(dpl) != 2 { - t.Errorf("Expected 2 deployed, got %d", len(dpl)) - } + require.NoError(t, err, "Failed to list deployed releases") + assert.Len(t, dpl, 2, "Expected 2 deployed, got %d", len(dpl)) // list all superseded releases ssd, err := ts.List(func(rel release.Releaser) bool { @@ -126,12 +120,8 @@ func TestMemoryList(t *testing.T) { return rls.Info.Status == common.StatusSuperseded }) // check - if err != nil { - t.Errorf("Failed to list superseded releases: %s", err) - } - if len(ssd) != 6 { - t.Errorf("Expected 6 superseded, got %d", len(ssd)) - } + require.NoError(t, err, "Failed to list superseded releases") + assert.Len(t, ssd, 6, "Expected 6 superseded, got %d", len(ssd)) // list all deleted releases del, err := ts.List(func(rel release.Releaser) bool { @@ -139,12 +129,8 @@ func TestMemoryList(t *testing.T) { return rls.Info.Status == common.StatusUninstalled }) // check - if err != nil { - t.Errorf("Failed to list deleted releases: %s", err) - } - if len(del) != 0 { - t.Errorf("Expected 0 deleted, got %d", len(del)) - } + require.NoError(t, err, "Failed to list deleted releases") + assert.Empty(t, del, "Expected 0 deleted, got %d", len(del)) } func TestMemoryQuery(t *testing.T) { @@ -172,13 +158,9 @@ func TestMemoryQuery(t *testing.T) { for _, tt := range tests { ts.SetNamespace(tt.namespace) l, err := ts.Query(tt.lbs) - if err != nil { - t.Fatalf("Failed to query: %s\n", err) - } + require.NoError(t, err, "Failed to query") - if tt.xlen != len(l) { - t.Fatalf("Expected %d results, actual %d\n", tt.xlen, len(l)) - } + require.Equal(t, len(l), tt.xlen, "Expected %d results, actual %d\n", tt.xlen, len(l)) } } @@ -217,23 +199,18 @@ func TestMemoryUpdate(t *testing.T) { ts := tsFixtureMemory(t) for _, tt := range tests { - if err := ts.Update(tt.key, tt.rls); err != nil { - if !tt.err { - t.Fatalf("Failed %q: %s\n", tt.desc, err) - } - continue - } else if tt.err { - t.Fatalf("Did not get expected error for %q '%s'\n", tt.desc, tt.key) - } + err := ts.Update(tt.key, tt.rls) - ts.SetNamespace(tt.rls.Namespace) - r, err := ts.Get(tt.key) - if err != nil { - t.Fatalf("Failed to get: %s\n", err) - } + if tt.err { + require.Error(t, err, "Did not get expected error for %q '%s'\n", tt.desc, tt.key) + } else { + require.NoError(t, err, "Failed %q", tt.desc) + + ts.SetNamespace(tt.rls.Namespace) - if !reflect.DeepEqual(r, tt.rls) { - t.Fatalf("Expected %v, actual %v\n", tt.rls, r) + r, err := ts.Get(tt.key) + require.NoError(t, err, "Failed to get") + require.Truef(t, reflect.DeepEqual(r, tt.rls), "Expected %v, actual %v\n", tt.rls, r) } } } @@ -256,9 +233,7 @@ func TestMemoryDelete(t *testing.T) { ts := tsFixtureMemory(t) ts.SetNamespace("") start, err := ts.Query(map[string]string{"status": "deployed"}) - if err != nil { - t.Errorf("Query failed: %s", err) - } + require.NoError(t, err, "Query failed") startLen := len(start) for _, tt := range tests { t.Run(tt.desc, func(t *testing.T) { @@ -280,9 +255,7 @@ func TestMemoryDelete(t *testing.T) { // Make sure that the deleted records are gone. ts.SetNamespace("") end, err := ts.Query(map[string]string{"status": "deployed"}) - if err != nil { - t.Errorf("Query failed: %s", err) - } + require.NoError(t, err, "Query failed") endLen := len(end) if startLen-2 != endLen { From 3ff05c835ecb1bbf794089d309556dbc75778ef7 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 20:50:56 +0200 Subject: [PATCH 22/61] chore(pkg): refactor: convert tests to testify assert/require part 5 refactor: convert tests to testify assert/require in pkg Signed-off-by: Matthieu MOREL --- pkg/downloader/cache_test.go | 5 +- pkg/kube/client_test.go | 279 ++++++++++------------------------- pkg/repo/v1/repo_test.go | 100 ++++--------- 3 files changed, 109 insertions(+), 275 deletions(-) diff --git a/pkg/downloader/cache_test.go b/pkg/downloader/cache_test.go index 49a7adc5d..32f014727 100644 --- a/pkg/downloader/cache_test.go +++ b/pkg/downloader/cache_test.go @@ -105,10 +105,9 @@ func TestDiskCache_PutAndGet(t *testing.T) { t.Run("GetDirectory", func(t *testing.T) { dirKey := sha256.Sum256([]byte("i am a directory")) dirPath := cache.fileName(dirKey, CacheChart) - err := os.MkdirAll(dirPath, 0o755) - require.NoError(t, err) + require.NoError(t, os.MkdirAll(dirPath, 0o755)) - _, err = cache.Get(dirKey, CacheChart) + _, err := cache.Get(dirKey, CacheChart) assert.EqualError(t, err, "is a directory") }) } diff --git a/pkg/kube/client_test.go b/pkg/kube/client_test.go index 6421a2c2d..4d46d2692 100644 --- a/pkg/kube/client_test.go +++ b/pkg/kube/client_test.go @@ -316,9 +316,7 @@ func TestCreate(t *testing.T) { list, err := c.Build(objBody(&tc.Pods), false) require.NoError(t, err) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) result, err := c.Create( list, @@ -487,7 +485,7 @@ func TestUpdate(t *testing.T) { data, err := io.ReadAll(req.Body) require.NoError(t, err) - assert.Equal(t, `{}`, string(data)) + assert.JSONEq(t, `{}`, string(data)) } return newResponse(http.StatusOK, &listTarget.Items[0]) @@ -622,15 +620,12 @@ func TestBuild(t *testing.T) { t.Run(tt.name, func(t *testing.T) { // Test for an invalid manifest infos, err := c.Build(tt.reader, false) - if err != nil && !tt.err { - t.Errorf("Got error message when no error should have occurred: %v", err) - } else if err != nil && strings.Contains(err.Error(), "--validate=false") { - t.Error("error message was not scrubbed") - } - - if len(infos) != tt.count { - t.Errorf("expected %d result objects, got %d", tt.count, len(infos)) + if tt.err { + require.ErrorContains(t, err, "--validate=false", "error message was not scrubbed") + } else { + require.NoError(t, err, "Got error message when no error should have occurred") } + assert.Len(t, infos, tt.count, "expected %d result objects, got %d", tt.count, len(infos)) }) } } @@ -661,15 +656,12 @@ func TestBuildTable(t *testing.T) { t.Run(tt.name, func(t *testing.T) { // Test for an invalid manifest infos, err := c.BuildTable(tt.reader, false) - if err != nil && !tt.err { - t.Errorf("Got error message when no error should have occurred: %v", err) - } else if err != nil && strings.Contains(err.Error(), "--validate=false") { - t.Error("error message was not scrubbed") - } - - if len(infos) != tt.count { - t.Errorf("expected %d result objects, got %d", tt.count, len(infos)) + if tt.err { + require.ErrorContains(t, err, "--validate=false", "error message was not scrubbed") + } else { + require.NoError(t, err, "Got error message when no error should have occurred") } + assert.Len(t, infos, tt.count, "expected %d result objects, got %d", tt.count, len(infos)) }) } } @@ -705,21 +697,17 @@ func TestPerform(t *testing.T) { c := newTestClient(t) infos, err := c.Build(tt.reader, false) - if err != nil && err.Error() != tt.errMessage { - t.Errorf("Error while building manifests: %v", err) + if err != nil { + require.EqualErrorf(t, err, tt.errMessage, "Error while building manifests") } err = perform(infos, fn) - if (err != nil) != tt.err { - t.Errorf("expected error: %v, got %v", tt.err, err) - } - if err != nil && err.Error() != tt.errMessage { - t.Errorf("expected error message: %v, got %v", tt.errMessage, err) + assert.Equal(t, tt.err, (err != nil), "expected error: %v", tt.err) + if err != nil { + require.EqualErrorf(t, err, tt.errMessage, "expected error message: %v, got %v", tt.errMessage, err) } - if len(results) != tt.count { - t.Errorf("expected %d result objects, got %d", tt.count, len(results)) - } + assert.Len(t, results, tt.count, "expected %d result objects, got %d", tt.count, len(results)) }) } } @@ -771,9 +759,7 @@ func TestWait(t *testing.T) { return newResponse(http.StatusOK, pod) case p == "/namespaces/default/pods" && m == http.MethodPost: resources, err := c.Build(req.Body, false) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) now := time.Now() created = &now return newResponse(http.StatusOK, resources[0].Object) @@ -785,32 +771,19 @@ func TestWait(t *testing.T) { } var err error c.Waiter, err = c.GetWaiterWithOptions(LegacyStrategy) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) resources, err := c.Build(objBody(&podList), false) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) result, err := c.Create( resources, ClientCreateOptionServerSideApply(false, false)) - if err != nil { - t.Fatal(err) - } - if len(result.Created) != 3 { - t.Errorf("expected 3 resource created, got %d", len(result.Created)) - } - - if err := c.Wait(resources, time.Second*30); err != nil { - t.Errorf("expected wait without error, got %s", err) - } + require.NoError(t, err) + assert.Len(t, result.Created, 3, "expected 3 resource created, got %d", len(result.Created)) + require.NoErrorf(t, c.Wait(resources, time.Second*30), "expected wait without error") - if time.Since(*created) < time.Second*5 { - t.Errorf("expected to wait at least 5 seconds before ready status was detected, but got %s", time.Since(*created)) - } + assert.GreaterOrEqualf(t, time.Since(*created), time.Second*5, "expected to wait at least 5 seconds before ready status was detected, but got %s", time.Since(*created)) } func TestWaitJob(t *testing.T) { @@ -832,9 +805,7 @@ func TestWaitJob(t *testing.T) { return newResponse(http.StatusOK, job) case p == "/namespaces/default/jobs" && m == http.MethodPost: resources, err := c.Build(req.Body, false) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) now := time.Now() created = &now return newResponse(http.StatusOK, resources[0].Object) @@ -846,31 +817,17 @@ func TestWaitJob(t *testing.T) { } var err error c.Waiter, err = c.GetWaiterWithOptions(LegacyStrategy) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) resources, err := c.Build(objBody(job), false) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) result, err := c.Create( resources, ClientCreateOptionServerSideApply(false, false)) - if err != nil { - t.Fatal(err) - } - if len(result.Created) != 1 { - t.Errorf("expected 1 resource created, got %d", len(result.Created)) - } - - if err := c.WaitWithJobs(resources, time.Second*30); err != nil { - t.Errorf("expected wait without error, got %s", err) - } - - if time.Since(*created) < time.Second*5 { - t.Errorf("expected to wait at least 5 seconds before ready status was detected, but got %s", time.Since(*created)) - } + require.NoError(t, err) + assert.Len(t, result.Created, 1, "expected 1 resource created, got %d", len(result.Created)) + require.NoErrorf(t, c.WaitWithJobs(resources, time.Second*30), "expected wait without error") + assert.GreaterOrEqualf(t, time.Since(*created), time.Second*5, "expected to wait at least 5 seconds before ready status was detected, but got %s", time.Since(*created)) } func TestWaitDelete(t *testing.T) { @@ -896,9 +853,7 @@ func TestWaitDelete(t *testing.T) { return newResponse(http.StatusOK, &pod) case p == "/namespaces/default/pods" && m == http.MethodPost: resources, err := c.Build(req.Body, false) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) return newResponse(http.StatusOK, resources[0].Object) default: t.Fatalf("unexpected request: %s %s", req.Method, req.URL.Path) @@ -908,73 +863,46 @@ func TestWaitDelete(t *testing.T) { } var err error c.Waiter, err = c.GetWaiterWithOptions(LegacyStrategy) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) resources, err := c.Build(objBody(&pod), false) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) result, err := c.Create( resources, ClientCreateOptionServerSideApply(false, false)) - if err != nil { - t.Fatal(err) - } - if len(result.Created) != 1 { - t.Errorf("expected 1 resource created, got %d", len(result.Created)) - } - if _, err := c.Delete(resources, metav1.DeletePropagationBackground); err != nil { - t.Fatal(err) - } - - if err := c.WaitForDelete(resources, time.Second*30); err != nil { - t.Errorf("expected wait without error, got %s", err) - } - - if time.Since(*deleted) < time.Second*5 { - t.Errorf("expected to wait at least 5 seconds before ready status was detected, but got %s", time.Since(*deleted)) - } + require.NoError(t, err) + assert.Len(t, result.Created, 1, "expected 1 resource created, got %d", len(result.Created)) + _, errs := c.Delete(resources, metav1.DeletePropagationBackground) + require.Nil(t, errs) + require.NoErrorf(t, c.WaitForDelete(resources, time.Second*30), "expected wait without error") + assert.GreaterOrEqualf(t, time.Since(*deleted), time.Second*5, "expected to wait at least 5 seconds before ready status was detected, but got %s", time.Since(*deleted)) } func TestReal(t *testing.T) { t.Skip("This is a live test, comment this line to run") c := New(nil) resources, err := c.Build(strings.NewReader(guestbookManifest), false) - if err != nil { - t.Fatal(err) - } - if _, err := c.Create(resources); err != nil { - t.Fatal(err) - } + require.NoError(t, err) + _, err = c.Create(resources) + require.NoError(t, err) testSvcEndpointManifest := testServiceManifest + "\n---\n" + testEndpointManifest c = New(nil) resources, err = c.Build(strings.NewReader(testSvcEndpointManifest), false) - if err != nil { - t.Fatal(err) - } - if _, err := c.Create(resources); err != nil { - t.Fatal(err) - } + require.NoError(t, err) + _, err = c.Create(resources) + require.NoError(t, err) resources, err = c.Build(strings.NewReader(testEndpointManifest), false) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if _, errs := c.Delete(resources, metav1.DeletePropagationBackground); errs != nil { - t.Fatal(errs) - } + _, errs := c.Delete(resources, metav1.DeletePropagationBackground) + require.Nil(t, errs) resources, err = c.Build(strings.NewReader(testSvcEndpointManifest), false) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) // ensures that delete does not fail if a resource is not found - if _, errs := c.Delete(resources, metav1.DeletePropagationBackground); errs != nil { - t.Fatal(errs) - } + _, errs = c.Delete(resources, metav1.DeletePropagationBackground) + require.Nil(t, errs) } func TestGetPodList(t *testing.T) { @@ -1004,10 +932,9 @@ func TestOutputContainerLogsForPodList(t *testing.T) { c := Client{Namespace: namespace, kubeClient: kubeClient} outBuffer := &bytes.Buffer{} outBufferFunc := func(_, _, _ string) io.Writer { return outBuffer } - err := c.OutputContainerLogsForPodList(&somePodList, namespace, outBufferFunc) clientAssertions := assert.New(t) req := require.New(t) - req.NoError(err) + req.NoError(c.OutputContainerLogsForPodList(&somePodList, namespace, outBufferFunc)) clientAssertions.Equal("fake logsfake logsfake logs", outBuffer.String()) } @@ -1247,23 +1174,11 @@ func (c createPatchTestCase) run(t *testing.T) { } patch, patchType, err := createPatch(c.original, targetInfo, c.threeWayMergeForUnstructured) - if err != nil { - t.Fatalf("Failed to create patch: %v", err) - } + require.NoError(t, err, "Failed to create patch") - if c.expectedPatch != string(patch) { - t.Errorf("Unexpected patch.\nTarget:\n%s\nOriginal:\n%s\nActual:\n%s\n\nExpected:\n%s\nGot:\n%s", - c.target, - c.original, - c.actual, - c.expectedPatch, - string(patch), - ) - } + assert.Equal(t, c.expectedPatch, string(patch), "Unexpected patch.\nTarget:\n%s\nOriginal:\n%s\nActual:\n%s\n\nExpected:\n%s\nGot:\n%s", c.target, c.original, c.actual, c.expectedPatch, string(patch)) - if patchType != types.MergePatchType { - t.Errorf("Expected patch type %s, got %s", types.MergePatchType, patchType) - } + assert.Equal(t, types.MergePatchType, patchType, "Expected patch type %s, got %s", types.MergePatchType, patchType) } func newTestCustomResourceData(metadata map[string]string, spec map[string]any) *unstructured.Unstructured { @@ -1438,12 +1353,8 @@ func TestIsReachableTwiceAfterClientCreationFailure(t *testing.T) { assertReachableErr := func(label string, err error) { t.Helper() - if err == nil { - t.Fatalf("%s: expected error, got nil", label) - } - if !errors.Is(err, refusedErr) { - t.Fatalf("%s: expected error wrapping %v, got %v", label, refusedErr, err) - } + require.Error(t, err, "%s: expected error, got nil", label) + require.ErrorIs(t, err, refusedErr) } assertReachableErr("first call", client.IsReachable()) @@ -1472,9 +1383,7 @@ func TestIsIncompatibleServerError(t *testing.T) { for name, tc := range testCases { t.Run(name, func(t *testing.T) { - if got := isIncompatibleServerError(tc.Err); got != tc.Want { - t.Errorf("isIncompatibleServerError() = %v, want %v", got, tc.Want) - } + assert.Equalf(t, tc.Want, isIncompatibleServerError(tc.Err), "isIncompatibleServerError()") }) } } @@ -1926,9 +1835,7 @@ func TestClientWaitContextCancellationLegacy(t *testing.T) { return newResponse(http.StatusOK, pod) case p == "/namespaces/default/pods" && m == http.MethodPost: resources, err := c.Build(req.Body, false) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) return newResponse(http.StatusOK, resources[0].Object) default: t.Logf("unexpected request: %s %s", req.Method, req.URL.Path) @@ -1949,10 +1856,7 @@ func TestClientWaitContextCancellationLegacy(t *testing.T) { ClientCreateOptionServerSideApply(false, false)) require.NoError(t, err) assert.Len(t, result.Created, 2, "expected 2 resources created, got %d", len(result.Created)) - - err = c.Wait(resources, time.Second*30) - require.Error(t, err) - assert.ErrorContains(t, err, "context canceled", "expected context canceled error, got: %v", err) + assert.ErrorContains(t, c.Wait(resources, time.Second*30), "context canceled") } func TestClientWaitWithJobsContextCancellationLegacy(t *testing.T) { @@ -1981,9 +1885,7 @@ func TestClientWaitWithJobsContextCancellationLegacy(t *testing.T) { return newResponse(http.StatusOK, job) case p == "/namespaces/default/jobs" && m == http.MethodPost: resources, err := c.Build(req.Body, false) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) return newResponse(http.StatusOK, resources[0].Object) default: t.Logf("unexpected request: %s %s", req.Method, req.URL.Path) @@ -2004,9 +1906,7 @@ func TestClientWaitWithJobsContextCancellationLegacy(t *testing.T) { ClientCreateOptionServerSideApply(false, false)) require.NoError(t, err) assert.Len(t, result.Created, 1, "expected 1 resource created, got %d", len(result.Created)) - - err = c.WaitWithJobs(resources, time.Second*30) - assert.ErrorContains(t, err, "context canceled", "expected context canceled error, got: %v", err) + assert.ErrorContains(t, c.WaitWithJobs(resources, time.Second*30), "context canceled", "expected context canceled error") } func TestClientWaitForDeleteContextCancellationLegacy(t *testing.T) { @@ -2041,9 +1941,7 @@ func TestClientWaitForDeleteContextCancellationLegacy(t *testing.T) { return newResponse(http.StatusOK, &pod) case p == "/namespaces/default/pods" && m == http.MethodPost: resources, err := c.Build(req.Body, false) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) return newResponse(http.StatusOK, resources[0].Object) default: t.Logf("unexpected request: %s %s", req.Method, req.URL.Path) @@ -2065,12 +1963,9 @@ func TestClientWaitForDeleteContextCancellationLegacy(t *testing.T) { require.NoError(t, err) assert.Len(t, result.Created, 1, "expected 1 resource created, got %d", len(result.Created)) - if _, err := c.Delete(resources, metav1.DeletePropagationBackground); err != nil { - t.Fatal(err) - } - - err = c.WaitForDelete(resources, time.Second*30) - assert.ErrorContains(t, err, "context canceled", "expected context canceled error, got: %v", err) + _, errs := c.Delete(resources, metav1.DeletePropagationBackground) + require.Nil(t, errs) + assert.ErrorContains(t, c.WaitForDelete(resources, time.Second*30), "context canceled", "expected context canceled error") } func TestClientWaitContextNilDoesNotPanic(t *testing.T) { @@ -2100,9 +1995,7 @@ func TestClientWaitContextNilDoesNotPanic(t *testing.T) { return newResponse(http.StatusOK, pod) case p == "/namespaces/default/pods" && m == http.MethodPost: resources, err := c.Build(req.Body, false) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) now := time.Now() created = &now return newResponse(http.StatusOK, resources[0].Object) @@ -2125,10 +2018,7 @@ func TestClientWaitContextNilDoesNotPanic(t *testing.T) { ClientCreateOptionServerSideApply(false, false)) require.NoError(t, err) assert.Len(t, result.Created, 1, "expected 1 resource created, got %d", len(result.Created)) - - err = c.Wait(resources, time.Second*30) - require.NoError(t, err) - + require.NoError(t, c.Wait(resources, time.Second*30)) assert.GreaterOrEqual(t, time.Since(*created), time.Second*2, "expected to wait at least 2 seconds") } @@ -2152,9 +2042,7 @@ func TestClientWaitContextPreCancelledLegacy(t *testing.T) { return newResponse(http.StatusOK, pod) case p == "/namespaces/default/pods" && m == http.MethodPost: resources, err := c.Build(req.Body, false) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) return newResponse(http.StatusOK, resources[0].Object) default: t.Fatalf("unexpected request: %s %s", req.Method, req.URL.Path) @@ -2175,9 +2063,7 @@ func TestClientWaitContextPreCancelledLegacy(t *testing.T) { ClientCreateOptionServerSideApply(false, false)) require.NoError(t, err) assert.Len(t, result.Created, 1, "expected 1 resource created, got %d", len(result.Created)) - - err = c.Wait(resources, time.Second*30) - assert.ErrorContains(t, err, "context canceled", "expected context canceled error, got: %v", err) + assert.ErrorContains(t, c.Wait(resources, time.Second*30), "context canceled") } func TestClientWaitContextCancellationStatusWatcher(t *testing.T) { @@ -2202,8 +2088,7 @@ metadata: cancel() - err = c.Wait(resources, time.Second*30) - assert.ErrorContains(t, err, "context canceled", "expected context canceled error, got: %v", err) + assert.ErrorContains(t, c.Wait(resources, time.Second*30), "context canceled", "expected context canceled error") } func TestClientWaitWithJobsContextCancellationStatusWatcher(t *testing.T) { @@ -2228,8 +2113,7 @@ metadata: cancel() - err = c.WaitWithJobs(resources, time.Second*30) - assert.ErrorContains(t, err, "context canceled", "expected context canceled error, got: %v", err) + assert.ErrorContains(t, c.WaitWithJobs(resources, time.Second*30), "context canceled") } func TestClientWaitForDeleteContextCancellationStatusWatcher(t *testing.T) { @@ -2259,8 +2143,7 @@ status: cancel() - err = c.WaitForDelete(resources, time.Second*30) - assert.ErrorContains(t, err, "context canceled", "expected context canceled error, got: %v", err) + assert.ErrorContains(t, c.WaitForDelete(resources, time.Second*30), "context canceled") } // testStatusReader is a custom status reader for testing that returns a configurable status. @@ -2334,8 +2217,7 @@ metadata: // The pod has no Ready condition, but our custom reader returns CurrentStatus, // so the wait should succeed immediately without timeout. - err = c.Wait(resources, time.Second*3) - require.NoError(t, err) + require.NoError(t, c.Wait(resources, time.Second*3)) } func TestClientStatusReadersWithWaitWithJobs(t *testing.T) { @@ -2376,8 +2258,7 @@ metadata: // The job has no Complete condition, but our custom reader returns CurrentStatus, // so the wait should succeed immediately without timeout. - err = c.WaitWithJobs(resources, time.Second*3) - require.NoError(t, err) + require.NoError(t, c.WaitWithJobs(resources, time.Second*3)) } func createManifest(t *testing.T, manifest string, @@ -2385,12 +2266,10 @@ func createManifest(t *testing.T, manifest string, t.Helper() m := make(map[string]any) - err := yaml.Unmarshal([]byte(manifest), &m) - require.NoError(t, err) + require.NoError(t, yaml.Unmarshal([]byte(manifest), &m)) obj := &unstructured.Unstructured{Object: m} gvk := obj.GroupVersionKind() mapping, err := fakeMapper.RESTMapping(gvk.GroupKind(), gvk.Version) require.NoError(t, err) - err = fakeClient.Tracker().Create(mapping.Resource, obj, obj.GetNamespace()) - require.NoError(t, err) + require.NoError(t, fakeClient.Tracker().Create(mapping.Resource, obj, obj.GetNamespace())) } diff --git a/pkg/repo/v1/repo_test.go b/pkg/repo/v1/repo_test.go index 960635fc5..e3373fc49 100644 --- a/pkg/repo/v1/repo_test.go +++ b/pkg/repo/v1/repo_test.go @@ -18,8 +18,10 @@ package repo import ( "os" - "strings" "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) const testRepositoriesFile = "testdata/repositories.yaml" @@ -37,24 +39,14 @@ func TestFile(t *testing.T) { }, ) - if len(rf.Repositories) != 2 { - t.Fatal("Expected 2 repositories") - } + require.Len(t, rf.Repositories, 2, "Expected 2 repositories") - if rf.Has("nosuchrepo") { - t.Error("Found nonexistent repo") - } - if !rf.Has("incubator") { - t.Error("incubator repo is missing") - } + assert.False(t, rf.Has("nosuchrepo"), "Found nonexistent repo") + assert.True(t, rf.Has("incubator"), "incubator repo is missing") stable := rf.Repositories[0] - if stable.Name != "stable" { - t.Error("stable is not named stable") - } - if stable.URL != "https://example.com/stable/charts" { - t.Error("Wrong URL for stable") - } + assert.Equal(t, "stable", stable.Name, "stable is not named stable") + assert.Equal(t, "https://example.com/stable/charts", stable.URL, "Wrong URL for stable") } func TestNewFile(t *testing.T) { @@ -71,22 +63,14 @@ func TestNewFile(t *testing.T) { ) file, err := LoadFile(testRepositoriesFile) - if err != nil { - t.Errorf("%q could not be loaded: %s", testRepositoriesFile, err) - } + require.NoErrorf(t, err, "%q could not be loaded", testRepositoriesFile) - if len(expects.Repositories) != len(file.Repositories) { - t.Fatalf("Unexpected repo data: %#v", file.Repositories) - } + require.Lenf(t, file.Repositories, len(expects.Repositories), "Unexpected repo data: %#v", file.Repositories) for i, expect := range expects.Repositories { got := file.Repositories[i] - if expect.Name != got.Name { - t.Errorf("Expected name %q, got %q", expect.Name, got.Name) - } - if expect.URL != got.URL { - t.Errorf("Expected url %q, got %q", expect.URL, got.URL) - } + assert.Equalf(t, expect.Name, got.Name, "Expected name %q, got %q", expect.Name, got.Name) + assert.Equalf(t, expect.URL, got.URL, "Expected url %q, got %q", expect.URL, got.URL) } } @@ -114,18 +98,12 @@ func TestRepoFile_Get(t *testing.T) { name := "second" entry := repo.Get(name) - if entry == nil { - t.Fatalf("Expected repo entry %q to be found", name) - } + require.NotNilf(t, entry, "Expected repo entry %q to be found", name) - if entry.URL != "https://example.com/second" { - t.Errorf("Expected repo URL to be %q but got %q", "https://example.com/second", entry.URL) - } + assert.Equalf(t, "https://example.com/second", entry.URL, "Expected repo URL to be %q but got %q", "https://example.com/second", entry.URL) entry = repo.Get("nonexistent") - if entry != nil { - t.Errorf("Got unexpected entry %+v", entry) - } + assert.Nilf(t, entry, "Got unexpected entry %+v", entry) } func TestRemoveRepository(t *testing.T) { @@ -143,14 +121,10 @@ func TestRemoveRepository(t *testing.T) { removeRepository := "stable" found := sampleRepository.Remove(removeRepository) - if !found { - t.Errorf("expected repository %s not found", removeRepository) - } + assert.Truef(t, found, "expected repository %s not found", removeRepository) found = sampleRepository.Has(removeRepository) - if found { - t.Errorf("repository %s not deleted", removeRepository) - } + assert.Falsef(t, found, "repository %s not deleted", removeRepository) } func TestUpdateRepository(t *testing.T) { @@ -170,18 +144,14 @@ func TestUpdateRepository(t *testing.T) { URL: "https://example.com/sample", }) - if !sampleRepository.Has(newRepoName) { - t.Errorf("expected repository %s not found", newRepoName) - } + assert.Truef(t, sampleRepository.Has(newRepoName), "expected repository %s not found", newRepoName) repoCount := len(sampleRepository.Repositories) sampleRepository.Update(&Entry{Name: newRepoName, URL: "https://example.com/sample", }) - if repoCount != len(sampleRepository.Repositories) { - t.Errorf("invalid number of repositories found %d, expected number of repositories %d", len(sampleRepository.Repositories), repoCount) - } + assert.Lenf(t, sampleRepository.Repositories, repoCount, "invalid number of repositories found %d, expected number of repositories %d", len(sampleRepository.Repositories), repoCount) } func TestWriteFile(t *testing.T) { @@ -198,31 +168,21 @@ func TestWriteFile(t *testing.T) { ) file, err := os.CreateTemp(t.TempDir(), "helm-repo") - if err != nil { - t.Errorf("failed to create test-file (%v)", err) - } + require.NoErrorf(t, err, "failed to create test-file") defer os.Remove(file.Name()) - if err := sampleRepository.WriteFile(file.Name(), 0o600); err != nil { - t.Errorf("failed to write file (%v)", err) - } + require.NoErrorf(t, sampleRepository.WriteFile(file.Name(), 0o600), "failed to write file") repos, err := LoadFile(file.Name()) - if err != nil { - t.Errorf("failed to load file (%v)", err) - } + require.NoErrorf(t, err, "failed to load file") for _, repo := range sampleRepository.Repositories { - if !repos.Has(repo.Name) { - t.Errorf("expected repository %s not found", repo.Name) - } + assert.Truef(t, repos.Has(repo.Name), "expected repository %s not found", repo.Name) } } func TestRepoNotExists(t *testing.T) { - if _, err := LoadFile("/this/path/does/not/exist.yaml"); err == nil { - t.Error("expected err to be non-nil when path does not exist") - } else if !strings.Contains(err.Error(), "couldn't load repositories file") { - t.Error("expected prompt `couldn't load repositories file`") - } + _, err := LoadFile("/this/path/does/not/exist.yaml") + require.Error(t, err, "expected err to be non-nil when path does not exist") + assert.ErrorContains(t, err, "couldn't load repositories file", "expected prompt `couldn't load repositories file`") } func TestRemoveRepositoryInvalidEntries(t *testing.T) { @@ -246,12 +206,8 @@ func TestRemoveRepositoryInvalidEntries(t *testing.T) { removeRepository := "stable" found := sampleRepository.Remove(removeRepository) - if !found { - t.Errorf("expected repository %s not found", removeRepository) - } + assert.Truef(t, found, "expected repository %s not found", removeRepository) found = sampleRepository.Has(removeRepository) - if found { - t.Errorf("repository %s not deleted", removeRepository) - } + assert.Falsef(t, found, "repository %s not deleted", removeRepository) } From 0844b3b8b513e1ae6787c44fc5cfd224bf86c573 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 20:50:56 +0200 Subject: [PATCH 23/61] chore(pkg): refactor: convert tests to testify assert/require part 6 refactor: convert tests to testify assert/require in pkg Signed-off-by: Matthieu MOREL --- pkg/chart/v2/util/dependencies_test.go | 281 +++++++------------------ pkg/registry/chart_test.go | 2 +- pkg/repo/v1/chartrepo_test.go | 127 ++++------- 3 files changed, 110 insertions(+), 300 deletions(-) diff --git a/pkg/chart/v2/util/dependencies_test.go b/pkg/chart/v2/util/dependencies_test.go index 40a17ac3a..2386d2c28 100644 --- a/pkg/chart/v2/util/dependencies_test.go +++ b/pkg/chart/v2/util/dependencies_test.go @@ -21,6 +21,7 @@ import ( "strconv" "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "helm.sh/helm/v4/pkg/chart/common" @@ -31,9 +32,7 @@ import ( func loadChart(t *testing.T, path string) *chart.Chart { t.Helper() c, err := loader.Load(path) - if err != nil { - t.Fatalf("failed to load testdata: %s", err) - } + require.NoError(t, err, "failed to load testdata") return c } @@ -44,19 +43,11 @@ func TestLoadDependency(t *testing.T) { } check := func(deps []*chart.Dependency) { - if len(deps) != 2 { - t.Errorf("expected 2 dependencies, got %d", len(deps)) - } + assert.Len(t, deps, 2, "expected 2 dependencies, got %d", len(deps)) for i, tt := range tests { - if deps[i].Name != tt.Name { - t.Errorf("expected dependency named %q, got %q", tt.Name, deps[i].Name) - } - if deps[i].Version != tt.Version { - t.Errorf("expected dependency named %q to have version %q, got %q", tt.Name, tt.Version, deps[i].Version) - } - if deps[i].Repository != tt.Repository { - t.Errorf("expected dependency named %q to have repository %q, got %q", tt.Name, tt.Repository, deps[i].Repository) - } + assert.Equal(t, tt.Name, deps[i].Name, "expected dependency named %q, got %q", tt.Name, deps[i].Name) + assert.Equal(t, tt.Version, deps[i].Version, "expected dependency named %q to have version %q, got %q", tt.Name, tt.Version, deps[i].Version) + assert.Equal(t, tt.Repository, deps[i].Repository, "expected dependency named %q to have repository %q, got %q", tt.Name, tt.Repository, deps[i].Repository) } } c := loadChart(t, "testdata/frobnitz") @@ -119,18 +110,12 @@ func TestDependencyEnabled(t *testing.T) { for _, tc := range tests { c := loadChart(t, "testdata/subpop") t.Run(tc.name, func(t *testing.T) { - if err := processDependencyEnabled(c, tc.v, ""); err != nil { - t.Fatalf("error processing enabled dependencies %v", err) - } + require.NoErrorf(t, processDependencyEnabled(c, tc.v, ""), "error processing enabled dependencies") names := extractChartNames(c) - if len(names) != len(tc.e) { - t.Fatalf("slice lengths do not match got %v, expected %v", len(names), len(tc.e)) - } + require.Len(t, names, len(tc.e), "slice lengths do not match got %v, expected %v", len(names), len(tc.e)) for i := range names { - if names[i] != tc.e[i] { - t.Fatalf("slice values do not match got %v, expected %v", names, tc.e) - } + require.Equal(t, tc.e[i], names[i], "slice values do not match got %v, expected %v", names, tc.e) } }) } @@ -221,64 +206,44 @@ func TestProcessDependencyImportValues(t *testing.T) { e["SCBexported2A"] = "blaster" e["global.SC1exported2.all.SC1exported3"] = "SC1expstr" - if err := processDependencyImportValues(c, false); err != nil { - t.Fatalf("processing import values dependencies %v", err) - } + require.NoErrorf(t, processDependencyImportValues(c, false), "processing import values dependencies") cc := common.Values(c.Values) for kk, vv := range e { pv, err := cc.PathValue(kk) - if err != nil { - t.Fatalf("retrieving import values table %v %v", kk, err) - } + require.NoError(t, err, "retrieving import values table %v", kk) switch pv := pv.(type) { case float64: - if s := strconv.FormatFloat(pv, 'f', -1, 64); s != vv { - t.Errorf("failed to match imported float value %v with expected %v for key %q", s, vv, kk) - } + s := strconv.FormatFloat(pv, 'f', -1, 64) + assert.Equalf(t, s, vv, "failed to match imported float value %v with expected %v for key %q", s, vv, kk) case bool: - if b := strconv.FormatBool(pv); b != vv { - t.Errorf("failed to match imported bool value %v with expected %v for key %q", b, vv, kk) - } + b := strconv.FormatBool(pv) + assert.Equalf(t, b, vv, "failed to match imported bool value %v with expected %v for key %q", b, vv, kk) default: - if pv != vv { - t.Errorf("failed to match imported string value %q with expected %q for key %q", pv, vv, kk) - } + assert.Equal(t, vv, pv, "failed to match imported string value %q with expected %q for key %q", pv, vv, kk) } } // Since this was processed with coalescing there should be no null values. // Here we verify that. _, err := cc.PathValue("ensurenull") - if err == nil { - t.Error("expect nil value not found but found it") - } + require.Error(t, err, "expect nil value not found but found it") var xerr common.ErrNoValue require.ErrorAs(t, err, &xerr, "expected an ErrNoValue") c = loadChart(t, "testdata/subpop") - if err := processDependencyImportValues(c, true); err != nil { - t.Fatalf("processing import values dependencies %v", err) - } + require.NoErrorf(t, processDependencyImportValues(c, true), "processing import values dependencies") cc = common.Values(c.Values) val, err := cc.PathValue("ensurenull") - if err != nil { - t.Error("expect value but ensurenull was not found") - } - if val != nil { - t.Errorf("expect nil value but got %q instead", val) - } + require.NoError(t, err, "expect value but ensurenull was not found") + assert.Nil(t, val, "expect nil value but got %q instead", val) } func TestProcessDependencyImportValuesFromSharedDependencyToAliases(t *testing.T) { c := loadChart(t, "testdata/chart-with-import-from-aliased-dependencies") - if err := processDependencyEnabled(c, c.Values, ""); err != nil { - t.Fatalf("expected no errors but got %q", err) - } - if err := processDependencyImportValues(c, true); err != nil { - t.Fatalf("processing import values dependencies %v", err) - } + require.NoErrorf(t, processDependencyEnabled(c, c.Values, ""), "expected no errors") + require.NoErrorf(t, processDependencyImportValues(c, true), "processing import values dependencies") e := make(map[string]string) e["foo-defaults.defaultValue"] = "42" @@ -293,12 +258,8 @@ func TestProcessDependencyImportValuesFromSharedDependencyToAliases(t *testing.T cValues := common.Values(c.Values) for kk, vv := range e { pv, err := cValues.PathValue(kk) - if err != nil { - t.Fatalf("retrieving import values table %v %v", kk, err) - } - if pv != vv { - t.Errorf("failed to match imported value %v with expected %v", pv, vv) - } + require.NoError(t, err, "retrieving import values table %v", kk) + assert.Equal(t, vv, pv, "failed to match imported value %v with expected %v", pv, vv) } } @@ -325,25 +286,18 @@ func TestProcessDependencyImportValuesMultiLevelPrecedence(t *testing.T) { e["app2.service.port"] = "8080" e["app3.service.port"] = "9090" e["app4.service.port"] = "1234" - if err := processDependencyImportValues(c, true); err != nil { - t.Fatalf("processing import values dependencies %v", err) - } + require.NoErrorf(t, processDependencyImportValues(c, true), "processing import values dependencies") cc := common.Values(c.Values) for kk, vv := range e { pv, err := cc.PathValue(kk) - if err != nil { - t.Fatalf("retrieving import values table %v %v", kk, err) - } + require.NoError(t, err, "retrieving import values table %v", kk) switch pv := pv.(type) { case float64: - if s := strconv.FormatFloat(pv, 'f', -1, 64); s != vv { - t.Errorf("failed to match imported float value %v with expected %v", s, vv) - } + s := strconv.FormatFloat(pv, 'f', -1, 64) + assert.Equalf(t, s, vv, "failed to match imported float value %v with expected %v", s, vv) default: - if pv != vv { - t.Errorf("failed to match imported string value %q with expected %q", pv, vv) - } + assert.Equal(t, vv, pv, "failed to match imported string value %q with expected %q", pv, vv) } } } @@ -352,127 +306,71 @@ func TestProcessDependencyImportValuesForEnabledCharts(t *testing.T) { c := loadChart(t, "testdata/import-values-from-enabled-subchart/parent-chart") nameOverride := "parent-chart-prod" - if err := processDependencyImportValues(c, true); err != nil { - t.Fatalf("processing import values dependencies %v", err) - } - - if len(c.Dependencies()) != 2 { - t.Fatalf("expected 2 dependencies for this chart, but got %d", len(c.Dependencies())) - } - - if err := processDependencyEnabled(c, c.Values, ""); err != nil { - t.Fatalf("expected no errors but got %q", err) - } - - if len(c.Dependencies()) != 1 { - t.Fatal("expected no changes in dependencies") - } - - if len(c.Metadata.Dependencies) != 1 { - t.Fatalf("expected 1 dependency specified in Chart.yaml, got %d", len(c.Metadata.Dependencies)) - } - + require.NoErrorf(t, processDependencyImportValues(c, true), "processing import values dependencies") + require.Len(t, c.Dependencies(), 2, "expected 2 dependencies for this chart, but got %d", len(c.Dependencies())) + require.NoErrorf(t, processDependencyEnabled(c, c.Values, ""), "expected no errors") + require.Len(t, c.Dependencies(), 1, "expected no changes in dependencies") + require.Len(t, c.Metadata.Dependencies, 1, "expected 1 dependency specified in Chart.yaml, got %d", len(c.Metadata.Dependencies)) prodDependencyValues := c.Dependencies()[0].Values - if prodDependencyValues["nameOverride"] != nameOverride { - t.Fatalf("dependency chart name should be %s but got %s", nameOverride, prodDependencyValues["nameOverride"]) - } + require.Equal(t, nameOverride, prodDependencyValues["nameOverride"], "dependency chart name should be %s but got %s", nameOverride, prodDependencyValues["nameOverride"]) } func TestGetAliasDependency(t *testing.T) { c := loadChart(t, "testdata/frobnitz") req := c.Metadata.Dependencies - if len(req) == 0 { - t.Fatal("there are no dependencies to test") - } + require.NotEmpty(t, req, "there are no dependencies to test") // Success case aliasChart := getAliasDependency(c.Dependencies(), req[0]) - if aliasChart == nil { - t.Fatalf("failed to get dependency chart for alias %s", req[0].Name) - } + require.NotNil(t, aliasChart, "failed to get dependency chart for alias %s", req[0].Name) if req[0].Alias != "" { - if aliasChart.Name() != req[0].Alias { - t.Fatalf("dependency chart name should be %s but got %s", req[0].Alias, aliasChart.Name()) - } - } else if aliasChart.Name() != req[0].Name { - t.Fatalf("dependency chart name should be %s but got %s", req[0].Name, aliasChart.Name()) + require.Equal(t, req[0].Alias, aliasChart.Name(), "dependency chart name should be %s but got %s", req[0].Alias, aliasChart.Name()) + } else { + require.Equalf(t, aliasChart.Name(), req[0].Name, "dependency chart name should be %s but got %s", req[0].Name, aliasChart.Name()) } if req[0].Version != "" { - if !IsCompatibleRange(req[0].Version, aliasChart.Metadata.Version) { - t.Fatal("dependency chart version is not in the compatible range") - } + require.True(t, IsCompatibleRange(req[0].Version, aliasChart.Metadata.Version), "dependency chart version is not in the compatible range") } // Failure case req[0].Name = "something-else" - if aliasChart := getAliasDependency(c.Dependencies(), req[0]); aliasChart != nil { - t.Fatalf("expected no chart but got %s", aliasChart.Name()) - } + require.Nilf(t, getAliasDependency(c.Dependencies(), req[0]), "expected no chart") req[0].Version = "something else which is not in the compatible range" - if IsCompatibleRange(req[0].Version, aliasChart.Metadata.Version) { - t.Fatal("dependency chart version outside the compatible range should fail, but it succeeded") - } + require.False(t, IsCompatibleRange(req[0].Version, aliasChart.Metadata.Version), "dependency chart version outside the compatible range should fail, but it succeeded") } func TestDependentChartAliases(t *testing.T) { c := loadChart(t, "testdata/dependent-chart-alias") req := c.Metadata.Dependencies - if len(c.Dependencies()) != 2 { - t.Fatalf("expected 2 dependencies for this chart, but got %d", len(c.Dependencies())) - } - - if err := processDependencyEnabled(c, c.Values, ""); err != nil { - t.Fatalf("expected no errors but got %q", err) - } - - if len(c.Dependencies()) != 3 { - t.Fatal("expected alias dependencies to be added") - } - - if len(c.Dependencies()) != len(c.Metadata.Dependencies) { - t.Fatalf("expected number of chart dependencies %d, but got %d", len(c.Metadata.Dependencies), len(c.Dependencies())) - } + require.Len(t, c.Dependencies(), 2, "expected 2 dependencies for this chart, but got %d", len(c.Dependencies())) + require.NoErrorf(t, processDependencyEnabled(c, c.Values, ""), "expected no errors") + require.Len(t, c.Dependencies(), 3, "expected alias dependencies to be added") + require.Len(t, c.Dependencies(), len(c.Metadata.Dependencies), "expected number of chart dependencies %d, but got %d", len(c.Metadata.Dependencies), len(c.Dependencies())) aliasChart := getAliasDependency(c.Dependencies(), req[2]) - if aliasChart == nil { - t.Fatalf("failed to get dependency chart for alias %s", req[2].Name) - } - if aliasChart.Parent() != c { - t.Fatalf("dependency chart has wrong parent, expected %s but got %s", c.Name(), aliasChart.Parent().Name()) - } + require.NotNil(t, aliasChart, "failed to get dependency chart for alias %s", req[2].Name) + require.Equal(t, c, aliasChart.Parent(), "dependency chart has wrong parent, expected %s but got %s", c.Name(), aliasChart.Parent().Name()) if req[2].Alias != "" { - if aliasChart.Name() != req[2].Alias { - t.Fatalf("dependency chart name should be %s but got %s", req[2].Alias, aliasChart.Name()) - } - } else if aliasChart.Name() != req[2].Name { - t.Fatalf("dependency chart name should be %s but got %s", req[2].Name, aliasChart.Name()) + require.Equal(t, req[2].Alias, aliasChart.Name(), "dependency chart name should be %s but got %s", req[2].Alias, aliasChart.Name()) + } else { + require.Equalf(t, aliasChart.Name(), req[2].Name, "dependency chart name should be %s but got %s", req[2].Name, aliasChart.Name()) } req[2].Name = "dummy-name" - if aliasChart := getAliasDependency(c.Dependencies(), req[2]); aliasChart != nil { - t.Fatalf("expected no chart but got %s", aliasChart.Name()) - } + require.Nilf(t, getAliasDependency(c.Dependencies(), req[2]), "expected no chart") } func TestDependentChartWithSubChartsAbsentInDependency(t *testing.T) { c := loadChart(t, "testdata/dependent-chart-no-requirements-yaml") - if len(c.Dependencies()) != 2 { - t.Fatalf("expected 2 dependencies for this chart, but got %d", len(c.Dependencies())) - } - - if err := processDependencyEnabled(c, c.Values, ""); err != nil { - t.Fatalf("expected no errors but got %q", err) - } - - if len(c.Dependencies()) != 2 { - t.Fatal("expected no changes in dependencies") - } + require.Len(t, c.Dependencies(), 2, "expected 2 dependencies for this chart, but got %d", len(c.Dependencies())) + require.NoErrorf(t, processDependencyEnabled(c, c.Values, ""), "expected no errors") + require.Len(t, c.Dependencies(), 2, "expected no changes in dependencies") } func TestDependentChartWithSubChartsHelmignore(t *testing.T) { @@ -482,67 +380,37 @@ func TestDependentChartWithSubChartsHelmignore(t *testing.T) { func TestDependentChartsWithSubChartsSymlink(t *testing.T) { joonix := filepath.Join("testdata", "joonix") - if err := os.Symlink(filepath.Join("..", "..", "frobnitz"), filepath.Join(joonix, "charts", "frobnitz")); err != nil { - t.Fatal(err) - } + require.NoError(t, os.Symlink(filepath.Join("..", "..", "frobnitz"), filepath.Join(joonix, "charts", "frobnitz"))) defer os.RemoveAll(filepath.Join(joonix, "charts", "frobnitz")) c := loadChart(t, joonix) - if c.Name() != "joonix" { - t.Fatalf("unexpected chart name: %s", c.Name()) - } - if n := len(c.Dependencies()); n != 1 { - t.Fatalf("expected 1 dependency for this chart, but got %d", n) - } + require.Equal(t, "joonix", c.Name(), "unexpected chart name: %s", c.Name()) + require.Lenf(t, c.Dependencies(), 1, "expected 1 dependency for this chart") } func TestDependentChartsWithSubchartsAllSpecifiedInDependency(t *testing.T) { c := loadChart(t, "testdata/dependent-chart-with-all-in-requirements-yaml") - if len(c.Dependencies()) != 2 { - t.Fatalf("expected 2 dependencies for this chart, but got %d", len(c.Dependencies())) - } - - if err := processDependencyEnabled(c, c.Values, ""); err != nil { - t.Fatalf("expected no errors but got %q", err) - } - - if len(c.Dependencies()) != 2 { - t.Fatal("expected no changes in dependencies") - } - - if len(c.Dependencies()) != len(c.Metadata.Dependencies) { - t.Fatalf("expected number of chart dependencies %d, but got %d", len(c.Metadata.Dependencies), len(c.Dependencies())) - } + require.Len(t, c.Dependencies(), 2, "expected 2 dependencies for this chart, but got %d", len(c.Dependencies())) + require.NoErrorf(t, processDependencyEnabled(c, c.Values, ""), "expected no errors") + require.Len(t, c.Dependencies(), 2, "expected no changes in dependencies") + require.Len(t, c.Dependencies(), len(c.Metadata.Dependencies), "expected number of chart dependencies %d, but got %d", len(c.Metadata.Dependencies), len(c.Dependencies())) } func TestDependentChartsWithSomeSubchartsSpecifiedInDependency(t *testing.T) { c := loadChart(t, "testdata/dependent-chart-with-mixed-requirements-yaml") - if len(c.Dependencies()) != 2 { - t.Fatalf("expected 2 dependencies for this chart, but got %d", len(c.Dependencies())) - } - - if err := processDependencyEnabled(c, c.Values, ""); err != nil { - t.Fatalf("expected no errors but got %q", err) - } - - if len(c.Dependencies()) != 2 { - t.Fatal("expected no changes in dependencies") - } - - if len(c.Metadata.Dependencies) != 1 { - t.Fatalf("expected 1 dependency specified in Chart.yaml, got %d", len(c.Metadata.Dependencies)) - } + require.Len(t, c.Dependencies(), 2, "expected 2 dependencies for this chart, but got %d", len(c.Dependencies())) + require.NoErrorf(t, processDependencyEnabled(c, c.Values, ""), "expected no errors") + require.Len(t, c.Dependencies(), 2, "expected no changes in dependencies") + require.Len(t, c.Metadata.Dependencies, 1, "expected 1 dependency specified in Chart.yaml, got %d", len(c.Metadata.Dependencies)) } func validateDependencyTree(t *testing.T, c *chart.Chart) { t.Helper() for _, dependency := range c.Dependencies() { if dependency.Parent() != c { - if dependency.Parent() != c { - t.Fatalf("dependency chart %s has wrong parent, expected %s but got %s", dependency.Name(), c.Name(), dependency.Parent().Name()) - } + require.Equal(t, c, dependency.Parent(), "dependency chart %s has wrong parent, expected %s but got %s", dependency.Name(), c.Name(), dependency.Parent().Name()) } // recurse entire tree validateDependencyTree(t, dependency) @@ -552,16 +420,9 @@ func validateDependencyTree(t *testing.T, c *chart.Chart) { func TestChartWithDependencyAliasedTwiceAndDoublyReferencedSubDependency(t *testing.T) { c := loadChart(t, "testdata/chart-with-dependency-aliased-twice") - if len(c.Dependencies()) != 1 { - t.Fatalf("expected one dependency for this chart, but got %d", len(c.Dependencies())) - } - - if err := processDependencyEnabled(c, c.Values, ""); err != nil { - t.Fatalf("expected no errors but got %q", err) - } + require.Len(t, c.Dependencies(), 1, "expected one dependency for this chart, but got %d", len(c.Dependencies())) + require.NoErrorf(t, processDependencyEnabled(c, c.Values, ""), "expected no errors") + require.Len(t, c.Dependencies(), 2, "expected two dependencies after processing aliases") - if len(c.Dependencies()) != 2 { - t.Fatal("expected two dependencies after processing aliases") - } validateDependencyTree(t, c) } diff --git a/pkg/registry/chart_test.go b/pkg/registry/chart_test.go index c80544b5b..95e429a0b 100644 --- a/pkg/registry/chart_test.go +++ b/pkg/registry/chart_test.go @@ -250,5 +250,5 @@ func TestGenerateOCICreatedAnnotations(t *testing.T) { require.NoError(t, err, "%s annotation with value '%s' not in RFC3339 format", ocispec.AnnotationCreated, result[ocispec.AnnotationCreated]) // Verify creation annotation after (or equals) time test began - assert.False(t, nowTime.Before(createdTimeAnnotation), "%s annotation with value '%s' not configured properly. Annotation value is not after %s", ocispec.AnnotationCreated, result[ocispec.AnnotationCreated], nowTimeString) + assert.GreaterOrEqual(t, nowTime, createdTimeAnnotation, "%s annotation with value '%s' not configured properly. Annotation value is not after %s", ocispec.AnnotationCreated, result[ocispec.AnnotationCreated], nowTimeString) } diff --git a/pkg/repo/v1/chartrepo_test.go b/pkg/repo/v1/chartrepo_test.go index 9c992474b..4be2ebf73 100644 --- a/pkg/repo/v1/chartrepo_test.go +++ b/pkg/repo/v1/chartrepo_test.go @@ -18,7 +18,6 @@ package repo import ( "bytes" - "errors" "net/http" "net/http/httptest" "os" @@ -29,6 +28,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "sigs.k8s.io/yaml" "helm.sh/helm/v4/pkg/cli" @@ -68,37 +69,25 @@ func TestIndexCustomSchemeDownload(t *testing.T) { Name: repoName, URL: repoURL, }, providers) - if err != nil { - t.Fatalf("Problem loading chart repository from %s: %v", repoURL, err) - } + require.NoErrorf(t, err, "Problem loading chart repository from %s", repoURL) repo.CachePath = t.TempDir() tempIndexFile, err := os.CreateTemp(t.TempDir(), "test-repo") - if err != nil { - t.Fatalf("Failed to create temp index file: %v", err) - } + require.NoErrorf(t, err, "Failed to create temp index file") defer os.Remove(tempIndexFile.Name()) idx, err := repo.DownloadIndexFile() - if err != nil { - t.Fatalf("Failed to download index file to %s: %v", idx, err) - } + require.NoErrorf(t, err, "Failed to download index file to %s", idx) - if len(myCustomGetter.repoUrls) != 1 { - t.Fatal("Custom Getter.Get should be called once") - } + require.Len(t, myCustomGetter.repoUrls, 1, "Custom Getter.Get should be called once") expectedRepoIndexURL := repoURL + "/index.yaml" - if myCustomGetter.repoUrls[0] != expectedRepoIndexURL { - t.Fatalf("Custom Getter.Get should be called with %s", expectedRepoIndexURL) - } + require.Equalf(t, expectedRepoIndexURL, myCustomGetter.repoUrls[0], "Custom Getter.Get should be called with %s", expectedRepoIndexURL) } func TestConcurrencyDownloadIndex(t *testing.T) { srv, err := startLocalServerForTests(nil) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) defer srv.Close() repo, err := NewChartRepository(&Entry{ @@ -106,16 +95,12 @@ func TestConcurrencyDownloadIndex(t *testing.T) { URL: srv.URL, }, getter.All(&cli.EnvSettings{})) - if err != nil { - t.Fatalf("Problem loading chart repository from %s: %v", srv.URL, err) - } + require.NoErrorf(t, err, "Problem loading chart repository from %s", srv.URL) repo.CachePath = t.TempDir() // initial download index idx, err := repo.DownloadIndexFile() - if err != nil { - t.Fatalf("Failed to download index file to %s: %v", idx, err) - } + require.NoErrorf(t, err, "Failed to download index file to %s", idx) indexFName := filepath.Join(repo.CachePath, helmpath.CacheIndexFile(repo.Config.Name)) @@ -128,16 +113,12 @@ func TestConcurrencyDownloadIndex(t *testing.T) { for range 150 { wg.Go(func() { idx, err := repo.DownloadIndexFile() - if err != nil { - t.Errorf("Failed to download index file to %s: %v", idx, err) - } + assert.NoErrorf(t, err, "Failed to download index file to %s", idx) }) wg.Go(func() { _, err := LoadIndexFile(indexFName) - if err != nil { - t.Errorf("Failed to load index file: %v", err) - } + assert.NoErrorf(t, err, "Failed to load index file") }) } wg.Wait() @@ -175,9 +156,7 @@ func startLocalTLSServerForTests(handler http.Handler) (*httptest.Server, error) func TestFindChartInAuthAndTLSAndPassRepoURL(t *testing.T) { srv, err := startLocalTLSServerForTests(nil) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) defer srv.Close() chartURL, err := FindChartInRepoURL( @@ -186,12 +165,8 @@ func TestFindChartInAuthAndTLSAndPassRepoURL(t *testing.T) { getter.All(&cli.EnvSettings{}), WithInsecureSkipTLSVerify(true), ) - if err != nil { - t.Fatalf("%v", err) - } - if chartURL != "https://charts.helm.sh/stable/nginx-0.2.0.tgz" { - t.Errorf("%s is not the valid URL", chartURL) - } + require.NoError(t, err) + assert.Equalf(t, "https://charts.helm.sh/stable/nginx-0.2.0.tgz", chartURL, "%s is not the valid URL", chartURL) // If the insecureSkipTLSVerify is false, it will return an error that contains "x509: certificate signed by unknown authority". _, err = FindChartInRepoURL(srv.URL, "nginx", getter.All(&cli.EnvSettings{}), WithChartVersion("0.1.0")) @@ -203,33 +178,23 @@ func TestFindChartInAuthAndTLSAndPassRepoURL(t *testing.T) { if !strings.Contains(err.Error(), "x509: “Acme Co” certificate is not trusted") && !strings.Contains(err.Error(), "x509: certificate signed by unknown authority") { t.Errorf("Expected TLS error for function FindChartInAuthAndTLSAndPassRepoURL not found, but got a different error (%v)", err) } - } else if !strings.Contains(err.Error(), "x509: certificate signed by unknown authority") { - t.Errorf("Expected TLS error for function FindChartInAuthAndTLSAndPassRepoURL not found, but got a different error (%v)", err) + } else { + assert.ErrorContainsf(t, err, "x509: certificate signed by unknown authority", "Expected TLS error for function FindChartInAuthAndTLSAndPassRepoURL not found, but got a different error") } } func TestFindChartInRepoURL(t *testing.T) { srv, err := startLocalServerForTests(nil) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) defer srv.Close() chartURL, err := FindChartInRepoURL(srv.URL, "nginx", getter.All(&cli.EnvSettings{})) - if err != nil { - t.Fatalf("%v", err) - } - if chartURL != "https://charts.helm.sh/stable/nginx-0.2.0.tgz" { - t.Errorf("%s is not the valid URL", chartURL) - } + require.NoError(t, err) + assert.Equalf(t, "https://charts.helm.sh/stable/nginx-0.2.0.tgz", chartURL, "%s is not the valid URL", chartURL) chartURL, err = FindChartInRepoURL(srv.URL, "nginx", getter.All(&cli.EnvSettings{}), WithChartVersion("0.1.0")) - if err != nil { - t.Errorf("%s", err) - } - if chartURL != "https://charts.helm.sh/stable/nginx-0.1.0.tgz" { - t.Errorf("%s is not the valid URL", chartURL) - } + require.NoError(t, err) + assert.Equalf(t, "https://charts.helm.sh/stable/nginx-0.1.0.tgz", chartURL, "%s is not the valid URL", chartURL) } func TestErrorFindChartInRepoURL(t *testing.T) { @@ -237,38 +202,26 @@ func TestErrorFindChartInRepoURL(t *testing.T) { RepositoryCache: t.TempDir(), }) - if _, err := FindChartInRepoURL("http://someserver/something", "nginx", g); err == nil { - t.Error("Expected error for bad chart URL, but did not get any errors") - } else if !strings.Contains(err.Error(), `looks like "http://someserver/something" is not a valid chart repository or cannot be reached`) { - t.Errorf("Expected error for bad chart URL, but got a different error (%v)", err) - } + _, err := FindChartInRepoURL("http://someserver/something", "nginx", g) + require.Error(t, err, "Expected error for bad chart URL, but did not get any errors") + require.ErrorContainsf(t, err, `looks like "http://someserver/something" is not a valid chart repository or cannot be reached`, "Expected error for bad chart URL, but got a different error") srv, err := startLocalServerForTests(nil) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) defer srv.Close() - if _, err = FindChartInRepoURL(srv.URL, "nginx1", g); err == nil { - t.Error("Expected error for chart not found, but did not get any errors") - } else if err.Error() != `chart "nginx1" not found in `+srv.URL+` repository` { - t.Errorf("Expected error for chart not found, but got a different error (%v)", err) - } - if !errors.Is(err, ChartNotFoundError{}) { - t.Error("error is not of correct error type structure") - } + _, err = FindChartInRepoURL(srv.URL, "nginx1", g) + require.Error(t, err, "Expected error for chart not found, but did not get any errors") + require.EqualError(t, err, `chart "nginx1" not found in `+srv.URL+` repository`, "Expected error for chart not found, but got a different error") + require.ErrorIs(t, err, ChartNotFoundError{}, "error is not of correct error type structure") - if _, err = FindChartInRepoURL(srv.URL, "nginx1", g, WithChartVersion("0.1.0")); err == nil { - t.Error("Expected error for chart not found, but did not get any errors") - } else if err.Error() != `chart "nginx1" version "0.1.0" not found in `+srv.URL+` repository` { - t.Errorf("Expected error for chart not found, but got a different error (%v)", err) - } + _, err = FindChartInRepoURL(srv.URL, "nginx1", g, WithChartVersion("0.1.0")) + require.Error(t, err, "Expected error for chart not found, but did not get any errors") + require.EqualError(t, err, `chart "nginx1" version "0.1.0" not found in `+srv.URL+` repository`, "Expected error for chart not found, but got a different error") - if _, err = FindChartInRepoURL(srv.URL, "chartWithNoURL", g); err == nil { - t.Error("Expected error for no chart URLs available, but did not get any errors") - } else if err.Error() != `chart "chartWithNoURL" has no downloadable URLs` { - t.Errorf("Expected error for chart not found, but got a different error (%v)", err) - } + _, err = FindChartInRepoURL(srv.URL, "chartWithNoURL", g) + require.Error(t, err, "Expected error for no chart URLs available, but did not get any errors") + assert.EqualError(t, err, `chart "chartWithNoURL" has no downloadable URLs`, "Expected error for chart not found, but got a different error") } func TestResolveReferenceURL(t *testing.T) { @@ -286,11 +239,7 @@ func TestResolveReferenceURL(t *testing.T) { {"http://localhost:8123/charts?with=queryparameter", "/nginx-0.2.0.tgz", "http://localhost:8123/nginx-0.2.0.tgz?with=queryparameter"}, } { chartURL, err := ResolveReferenceURL(tt.baseURL, tt.refURL) - if err != nil { - t.Errorf("unexpected error in ResolveReferenceURL(%q, %q): %s", tt.baseURL, tt.refURL, err) - } - if chartURL != tt.chartURL { - t.Errorf("expected ResolveReferenceURL(%q, %q) to equal %q, got %q", tt.baseURL, tt.refURL, tt.chartURL, chartURL) - } + require.NoErrorf(t, err, "unexpected error in ResolveReferenceURL(%q, %q)", tt.baseURL, tt.refURL) + assert.Equalf(t, chartURL, tt.chartURL, "expected ResolveReferenceURL(%q, %q) to equal %q, got %q", tt.baseURL, tt.refURL, tt.chartURL, chartURL) } } From d4ec8e9b87a002d48c2d7a8f3c145c9a324bfaef Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 20:50:55 +0200 Subject: [PATCH 24/61] chore(pkg): refactor: convert tests to testify assert/require part 1 refactor: convert tests to testify assert/require in pkg/engine Signed-off-by: Matthieu MOREL --- pkg/engine/engine_test.go | 395 +++++++++----------------------------- 1 file changed, 96 insertions(+), 299 deletions(-) diff --git a/pkg/engine/engine_test.go b/pkg/engine/engine_test.go index f666b63a6..ecc1eee3b 100644 --- a/pkg/engine/engine_test.go +++ b/pkg/engine/engine_test.go @@ -51,9 +51,7 @@ func TestSortTemplates(t *testing.T) { "/mychart/templates/charts/bar/templates/foo.tpl": {}, } got := sortTemplates(tpls) - if len(got) != len(tpls) { - t.Fatal("Sorted results are missing templates") - } + require.Len(t, got, len(tpls), "Sorted results are missing templates") expect := []string{ "/mychart/templates/charts/foo/charts/bar/templates/foo.tpl", @@ -65,12 +63,7 @@ func TestSortTemplates(t *testing.T) { "/mychart/templates/_foo.tpl", } for i, e := range expect { - if got[i] != e { - t.Fatalf("\n\tExp:\n%s\n\tGot:\n%s", - strings.Join(expect, "\n"), - strings.Join(got, "\n"), - ) - } + require.Equal(t, e, got[i], "\n\tExp:\n%s\n\tGot:\n%s", strings.Join(expect, "\n"), strings.Join(got, "\n")) } } @@ -78,17 +71,15 @@ func TestFuncMap(t *testing.T) { fns := funcMap() forbidden := []string{"env", "expandenv"} for _, f := range forbidden { - if _, ok := fns[f]; ok { - t.Errorf("Forbidden function %s exists in FuncMap.", f) - } + _, ok := fns[f] + assert.Falsef(t, ok, "Forbidden function %s exists in FuncMap.", f) } // Test for Engine-specific template functions. expect := []string{"include", "required", "tpl", "toYaml", "fromYaml", "toToml", "fromToml", "toJson", "fromJson", "lookup"} for _, f := range expect { - if _, ok := fns[f]; !ok { - t.Errorf("Expected add-on function %q", f) - } + _, ok := fns[f] + assert.Truef(t, ok, "Expected add-on function %q", f) } } @@ -120,13 +111,9 @@ func TestRender(t *testing.T) { } v, err := util.CoalesceValues(c, vals) - if err != nil { - t.Fatalf("Failed to coalesce values: %s", err) - } + require.NoError(t, err, "Failed to coalesce values") out, err := Render(c, v) - if err != nil { - t.Errorf("Failed to render templates: %s", err) - } + require.NoError(t, err, "Failed to render templates") expect := map[string]string{ "moby/templates/test1": "Spouter Inn", @@ -137,9 +124,7 @@ func TestRender(t *testing.T) { } for name, data := range expect { - if out[name] != data { - t.Errorf("Expected %q, got %q", data, out[name]) - } + assert.Equal(t, data, out[name], "Expected %q, got %q", data, out[name]) } } @@ -173,14 +158,10 @@ func TestRenderRefsOrdering(t *testing.T) { for i := range 100 { out, err := Render(parentChart, common.Values{}) - if err != nil { - t.Fatalf("Failed to render templates: %s", err) - } + require.NoError(t, err, "Failed to render templates") for name, data := range expect { - if out[name] != data { - t.Fatalf("Expected %q, got %q (iteration %d)", data, out[name], i+1) - } + require.Equal(t, data, out[name], "Expected %q, got %q (iteration %d)", data, out[name], i+1) } } } @@ -198,25 +179,12 @@ func TestRenderInternals(t *testing.T) { } out, err := new(Engine).render(t.Context(), tpls) - if err != nil { - t.Fatalf("Failed template rendering: %s", err) - } - - if len(out) != 3 { - t.Fatalf("Expected 3 templates, got %d", len(out)) - } - - if out["one"] != "Hello One" { - t.Errorf("Expected 'Hello One', got %q", out["one"]) - } - if out["two"] != "Goodbye TWO" { - t.Errorf("Expected 'Goodbye TWO'. got %q", out["two"]) - } - - if out["three"] != "Goodbye THREE" { - t.Errorf("Expected 'Goodbye THREE'. got %q", out["two"]) - } + require.NoError(t, err, "Failed template rendering") + require.Len(t, out, 3, "Expected 3 templates, got %d", len(out)) + assert.Equal(t, "Hello One", out["one"]) + assert.Equal(t, "Goodbye TWO", out["two"]) + assert.Equal(t, "Goodbye THREE", out["three"]) } func TestRenderWithDNS(t *testing.T) { @@ -236,22 +204,16 @@ func TestRenderWithDNS(t *testing.T) { } v, err := util.CoalesceValues(c, vals) - if err != nil { - t.Fatalf("Failed to coalesce values: %s", err) - } + require.NoError(t, err, "Failed to coalesce values") var e Engine e.EnableDNS = true out, err := e.Render(c, v) - if err != nil { - t.Errorf("Failed to render templates: %s", err) - } + require.NoError(t, err, "Failed to render templates") for _, val := range c.Templates { fp := path.Join("moby", val.Name) - if out[fp] == "" { - t.Errorf("Expected IP address, got %q", out[fp]) - } + assert.NotEmpty(t, out[fp], "Expected IP address, got %q", out[fp]) } } @@ -375,21 +337,15 @@ func TestRenderWithClientProvider(t *testing.T) { } v, err := util.CoalesceValues(c, vals) - if err != nil { - t.Fatalf("Failed to coalesce values: %s", err) - } + require.NoError(t, err, "Failed to coalesce values") out, err := RenderWithClientProvider(c, v, provider) - if err != nil { - t.Errorf("Failed to render templates: %s", err) - } + require.NoError(t, err, "Failed to render templates") for name, want := range cases { t.Run(name, func(t *testing.T) { key := path.Join("moby/templates", name) - if out[key] != want.output { - t.Errorf("Expected %q, got %q", want, out[key]) - } + assert.Equal(t, want.output, out[key], "Expected %q, got %q", want, out[key]) }) } } @@ -411,9 +367,7 @@ func TestRenderWithClientProvider_error(t *testing.T) { } v, err := util.CoalesceValues(c, vals) - if err != nil { - t.Fatalf("Failed to coalesce values: %s", err) - } + require.NoError(t, err, "Failed to coalesce values") provider := &testClientProvider{ t: t, @@ -424,9 +378,7 @@ func TestRenderWithClientProvider_error(t *testing.T) { }, } _, err = RenderWithClientProvider(c, v, provider) - if err == nil || !strings.Contains(err.Error(), "kaboom") { - t.Errorf("Expected error from client provider when rendering, got %q", err) - } + assert.ErrorContainsf(t, err, "kaboom", "Expected error from client provider when rendering") } func TestParallelRenderInternals(t *testing.T) { @@ -444,12 +396,8 @@ func TestParallelRenderInternals(t *testing.T) { }, } out, err := e.render(t.Context(), tpls) - if err != nil { - t.Errorf("Failed to render %s: %s", tt, err) - } - if out["t"] != tt { - t.Errorf("Expected %q, got %q", tt, out["t"]) - } + assert.NoError(t, err, "Failed to render %s", tt) + assert.Equal(t, tt, out["t"], "Expected %q, got %q", tt, out["t"]) wg.Done() }(i) } @@ -463,13 +411,9 @@ func TestParseErrors(t *testing.T) { "undefined_function": {tpl: `{{foo}}`, vals: vals}, } _, err := new(Engine).render(t.Context(), tplsUndefinedFunction) - if err == nil { - t.Fatalf("Expected failures while rendering: %s", err) - } + require.Error(t, err, "Expected failures while rendering") expected := `parse error at (undefined_function:1): function "foo" not defined` - if err.Error() != expected { - t.Errorf("Expected '%s', got %q", expected, err.Error()) - } + assert.EqualError(t, err, expected) } func TestExecErrors(t *testing.T) { @@ -526,12 +470,8 @@ linebreak`, for _, tt := range cases { t.Run(tt.name, func(t *testing.T) { _, err := new(Engine).render(t.Context(), tt.tpls) - if err == nil { - t.Fatalf("Expected failures while rendering: %s", err) - } - if err.Error() != tt.expected { - t.Errorf("Expected %q, got %q", tt.expected, err.Error()) - } + require.Error(t, err, "Expected failures while rendering") + assert.EqualError(t, err, tt.expected) }) } } @@ -544,25 +484,15 @@ func TestFailErrors(t *testing.T) { "failtpl": {tpl: failtpl, vals: vals}, } _, err := new(Engine).render(t.Context(), tplsFailed) - if err == nil { - t.Fatalf("Expected failures while rendering: %s", err) - } + require.Error(t, err, "Expected failures while rendering") expected := `execution error at (failtpl:1:33): This is an error` - if err.Error() != expected { - t.Errorf("Expected '%s', got %q", expected, err.Error()) - } + require.EqualError(t, err, expected) var e Engine e.LintMode = true out, err := e.render(t.Context(), tplsFailed) - if err != nil { - t.Fatal(err) - } - - expectStr := "All your base are belong to us" - if gotStr := out["failtpl"]; gotStr != expectStr { - t.Errorf("Expected %q, got %q (%v)", expectStr, gotStr, out) - } + require.NoError(t, err) + assert.Equal(t, "All your base are belong to us", out["failtpl"]) } func TestAllTemplates(t *testing.T) { @@ -592,9 +522,7 @@ func TestAllTemplates(t *testing.T) { dep1.AddDependency(dep2) tpls := allTemplates(ch1, common.Values{}) - if len(tpls) != 5 { - t.Errorf("Expected 5 charts, got %d", len(tpls)) - } + assert.Len(t, tpls, 5, "Expected 5 charts, got %d", len(tpls)) } func TestChartValuesContainsIsRoot(t *testing.T) { @@ -614,17 +542,13 @@ func TestChartValuesContainsIsRoot(t *testing.T) { ch1.AddDependency(dep1) out, err := Render(ch1, common.Values{}) - if err != nil { - t.Fatalf("failed to render templates: %s", err) - } + require.NoError(t, err, "failed to render templates") expects := map[string]string{ "parent/charts/child/templates/isroot": "false", "parent/templates/isroot": "true", } for file, expect := range expects { - if out[file] != expect { - t.Errorf("Expected %q, got %q", expect, out[file]) - } + assert.Equal(t, expect, out[file], "Expected %q, got %q", expect, out[file]) } } @@ -646,18 +570,10 @@ func TestRenderDependency(t *testing.T) { }) out, err := Render(ch, map[string]any{}) - if err != nil { - t.Fatalf("failed to render chart: %s", err) - } - - if len(out) != 2 { - t.Errorf("Expected 2, got %d", len(out)) - } + require.NoError(t, err, "failed to render chart") - expect := "Hello World" - if out["outerchart/templates/outer"] != expect { - t.Errorf("Expected %q, got %q", expect, out["outer"]) - } + assert.Len(t, out, 2, "Expected 2, got %d", len(out)) + assert.Equal(t, "Hello World", out["outerchart/templates/outer"]) } func TestRenderNestedValues(t *testing.T) { @@ -719,9 +635,7 @@ func TestRenderNestedValues(t *testing.T) { } tmp, err := util.CoalesceValues(outer, injValues) - if err != nil { - t.Fatalf("Failed to coalesce values: %s", err) - } + require.NoError(t, err, "Failed to coalesce values") inject := common.Values{ "Values": tmp, @@ -734,34 +648,22 @@ func TestRenderNestedValues(t *testing.T) { t.Logf("Calculated values: %v", inject) out, err := Render(outer, inject) - if err != nil { - t.Fatalf("failed to render templates: %s", err) - } + require.NoError(t, err, "failed to render templates") fullouterpath := "top/" + outerpath - if out[fullouterpath] != "Gather ye rosebuds while ye may" { - t.Errorf("Unexpected outer: %q", out[fullouterpath]) - } + assert.Equal(t, "Gather ye rosebuds while ye may", out[fullouterpath], "Unexpected outer: %q", out[fullouterpath]) fullinnerpath := "top/charts/herrick/" + innerpath - if out[fullinnerpath] != "Old time is still a-flyin'" { - t.Errorf("Unexpected inner: %q", out[fullinnerpath]) - } + assert.Equal(t, "Old time is still a-flyin'", out[fullinnerpath], "Unexpected inner: %q", out[fullinnerpath]) fulldeepestpath := "top/charts/herrick/charts/deepest/" + deepestpath - if out[fulldeepestpath] != "And this same flower that smiles to-day" { - t.Errorf("Unexpected deepest: %q", out[fulldeepestpath]) - } + assert.Equal(t, "And this same flower that smiles to-day", out[fulldeepestpath], "Unexpected deepest: %q", out[fulldeepestpath]) fullcheckrelease := "top/charts/herrick/charts/deepest/" + checkrelease - if out[fullcheckrelease] != "Tomorrow will be dyin" { - t.Errorf("Unexpected release: %q", out[fullcheckrelease]) - } + assert.Equal(t, "Tomorrow will be dyin", out[fullcheckrelease], "Unexpected release: %q", out[fullcheckrelease]) fullchecksubcharts := "top/" + subchartspath - if out[fullchecksubcharts] != "The glorious Lamp of Heaven, the Sun" { - t.Errorf("Unexpected subcharts: %q", out[fullchecksubcharts]) - } + assert.Equal(t, "The glorious Lamp of Heaven, the Sun", out[fullchecksubcharts], "Unexpected subcharts: %q", out[fullchecksubcharts]) } func TestRenderBuiltinValues(t *testing.T) { @@ -798,9 +700,7 @@ func TestRenderBuiltinValues(t *testing.T) { t.Logf("Calculated values: %v", outer) out, err := Render(outer, inject) - if err != nil { - t.Fatalf("failed to render templates: %s", err) - } + require.NoError(t, err, "failed to render templates") expects := map[string]string{ "Troy/charts/Latium/templates/Lavinia": "Troy/charts/Latium/templates/LaviniaLatiumAeneid", @@ -809,9 +709,7 @@ func TestRenderBuiltinValues(t *testing.T) { "Troy/charts/Latium/templates/From": "Virgil Aeneid", } for file, expect := range expects { - if out[file] != expect { - t.Errorf("Expected %q, got %q", expect, out[file]) - } + assert.Equal(t, expect, out[file], "Expected %q, got %q", expect, out[file]) } } @@ -843,20 +741,12 @@ func TestAlterFuncMap_include(t *testing.T) { } out, err := Render(c, v) - if err != nil { - t.Fatal(err) - } - - expect := " Mistah Kurtz - he dead." - if got := out["conrad/templates/quote"]; got != expect { - t.Errorf("Expected %q, got %q (%v)", expect, got, out) - } + require.NoError(t, err) + assert.Equal(t, " Mistah Kurtz - he dead.", out["conrad/templates/quote"]) _, err = Render(d, v) expectErrName := "nested/templates/quote" - if err == nil { - t.Errorf("Expected err of nested reference name: %v", expectErrName) - } + assert.Error(t, err, "Expected err of nested reference name: %v", expectErrName) } func TestAlterFuncMap_require(t *testing.T) { @@ -881,18 +771,10 @@ func TestAlterFuncMap_require(t *testing.T) { } out, err := Render(c, v) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - expectStr := "All your base are belong to us" - if gotStr := out["conan/templates/quote"]; gotStr != expectStr { - t.Errorf("Expected %q, got %q (%v)", expectStr, gotStr, out) - } - expectNum := "All 2 of them!" - if gotNum := out["conan/templates/bases"]; gotNum != expectNum { - t.Errorf("Expected %q, got %q (%v)", expectNum, gotNum, out) - } + assert.Equal(t, "All your base are belong to us", out["conan/templates/quote"]) + assert.Equal(t, "All 2 of them!", out["conan/templates/bases"]) // test required without passing in needed values with lint mode on // verifies lint replaces required with an empty string (should not fail) @@ -907,19 +789,11 @@ func TestAlterFuncMap_require(t *testing.T) { } var e Engine e.LintMode = true - out, err = e.Render(c, lintValues) - if err != nil { - t.Fatal(err) - } - expectStr = "All your base are belong to us" - if gotStr := out["conan/templates/quote"]; gotStr != expectStr { - t.Errorf("Expected %q, got %q (%v)", expectStr, gotStr, out) - } - expectNum = "All of them!" - if gotNum := out["conan/templates/bases"]; gotNum != expectNum { - t.Errorf("Expected %q, got %q (%v)", expectNum, gotNum, out) - } + out, err = e.Render(c, lintValues) + require.NoError(t, err) + assert.Equal(t, "All your base are belong to us", out["conan/templates/quote"]) + assert.Equal(t, "All of them!", out["conan/templates/bases"]) } func TestAlterFuncMap_tpl(t *testing.T) { @@ -941,14 +815,8 @@ func TestAlterFuncMap_tpl(t *testing.T) { } out, err := Render(c, v) - if err != nil { - t.Fatal(err) - } - - expect := "Evaluate tpl Value: myvalue" - if got := out["TplFunction/templates/base"]; got != expect { - t.Errorf("Expected %q, got %q (%v)", expect, got, out) - } + require.NoError(t, err) + assert.Equal(t, "Evaluate tpl Value: myvalue", out["TplFunction/templates/base"]) } func TestAlterFuncMap_tplfunc(t *testing.T) { @@ -970,14 +838,8 @@ func TestAlterFuncMap_tplfunc(t *testing.T) { } out, err := Render(c, v) - if err != nil { - t.Fatal(err) - } - - expect := "Evaluate tpl Value: \"myvalue\"" - if got := out["TplFunction/templates/base"]; got != expect { - t.Errorf("Expected %q, got %q (%v)", expect, got, out) - } + require.NoError(t, err) + assert.Equal(t, "Evaluate tpl Value: \"myvalue\"", out["TplFunction/templates/base"]) } func TestAlterFuncMap_tplinclude(t *testing.T) { @@ -1000,14 +862,8 @@ func TestAlterFuncMap_tplinclude(t *testing.T) { } out, err := Render(c, v) - if err != nil { - t.Fatal(err) - } - - expect := "\"TplFunction/templates/base\"" - if got := out["TplFunction/templates/base"]; got != expect { - t.Errorf("Expected %q, got %q (%v)", expect, got, out) - } + require.NoError(t, err) + assert.Equal(t, "\"TplFunction/templates/base\"", out["TplFunction/templates/base"]) } func TestRenderRecursionLimit(t *testing.T) { @@ -1053,9 +909,7 @@ func TestRenderRecursionLimit(t *testing.T) { } out, err := Render(d, v) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) var expect string var expectSb1062 strings.Builder @@ -1063,9 +917,7 @@ func TestRenderRecursionLimit(t *testing.T) { expectSb1062.WriteString(phrase + "\n") } expect += expectSb1062.String() - if got := out["overlook/templates/quote"]; got != expect { - t.Errorf("Expected %q, got %q (%v)", expect, got, out) - } + assert.Equal(t, expect, out["overlook/templates/quote"]) } func TestRenderLoadTemplateForTplFromFile(t *testing.T) { @@ -1094,14 +946,8 @@ func TestRenderLoadTemplateForTplFromFile(t *testing.T) { } out, err := Render(c, v) - if err != nil { - t.Fatal(err) - } - - expect := "test-function nested-define-content" - if got := out["TplLoadFromFile/templates/base"]; got != expect { - t.Fatalf("Expected %q, got %q", expect, got) - } + require.NoError(t, err) + require.Equal(t, "test-function nested-define-content", out["TplLoadFromFile/templates/base"]) } func TestRenderTplEmpty(t *testing.T) { @@ -1122,9 +968,7 @@ func TestRenderTplEmpty(t *testing.T) { } out, err := Render(c, v) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) expects := map[string]string{ "TplEmpty/templates/empty-string": "", @@ -1132,9 +976,7 @@ func TestRenderTplEmpty(t *testing.T) { "TplEmpty/templates/only-defines": "", } for file, expect := range expects { - if out[file] != expect { - t.Errorf("Expected %q, got %q", expect, out[file]) - } + assert.Equal(t, expect, out[file], "Expected %q, got %q", expect, out[file]) } } @@ -1168,9 +1010,7 @@ func TestRenderTplTemplateNames(t *testing.T) { } out, err := Render(c, v) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) expects := map[string]string{ "TplTemplateNames/templates/default-basepath": "TplTemplateNames/templates", @@ -1180,9 +1020,7 @@ func TestRenderTplTemplateNames(t *testing.T) { "TplTemplateNames/templates/modified-field": "extra-field", } for file, expect := range expects { - if out[file] != expect { - t.Errorf("Expected %q, got %q", expect, out[file]) - } + assert.Equal(t, expect, out[file], "Expected %q, got %q", expect, out[file]) } } @@ -1232,9 +1070,7 @@ func TestRenderTplRedefines(t *testing.T) { } out, err := Render(c, v) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) expects := map[string]string{ "TplRedefines/templates/partial": `before: original-in-partial\ntpl: redefined-in-tpl\nafter: original-in-partial`, @@ -1247,9 +1083,7 @@ func TestRenderTplRedefines(t *testing.T) { `after: original-in-manifest original-outer-in-manifest`, } for file, expect := range expects { - if out[file] != expect { - t.Errorf("Expected %q, got %q", expect, out[file]) - } + assert.Equal(t, expect, out[file], "Expected %q, got %q", expect, out[file]) } } @@ -1272,17 +1106,13 @@ func TestRenderTplMissingKey(t *testing.T) { } out, err := Render(c, v) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) expects := map[string]string{ "TplMissingKey/templates/manifest": `missingValue: `, } for file, expect := range expects { - if out[file] != expect { - t.Errorf("Expected %q, got %q", expect, out[file]) - } + assert.Equal(t, expect, out[file], "Expected %q, got %q", expect, out[file]) } } @@ -1307,15 +1137,9 @@ func TestRenderTplMissingKeyString(t *testing.T) { e := new(Engine) e.Strict = true - out, err := e.Render(c, v) - if err == nil { - t.Errorf("Expected error, got %v", out) - return - } - errTxt := fmt.Sprint(err) - if !strings.Contains(errTxt, "noSuchKey") { - t.Errorf("Expected error to contain 'noSuchKey', got %s", errTxt) - } + _, err := e.Render(c, v) + require.Error(t, err) + assert.ErrorContains(t, err, "noSuchKey") } func TestNestedHelpersProducesMultilineStacktrace(t *testing.T) { @@ -1354,7 +1178,7 @@ NestedHelperFunctions/charts/common/templates/_helpers_2.tpl:1:49 _, err := Render(c, vals) require.Error(t, err) - assert.Equal(t, expectedErrorMessage, err.Error()) + assert.EqualError(t, err, expectedErrorMessage) } func TestMultilineNoTemplateAssociatedError(t *testing.T) { @@ -1374,11 +1198,6 @@ func TestMultilineNoTemplateAssociatedError(t *testing.T) { }, } - expectedErrorMessage := `multiline/templates/svc.yaml:1:9 - executing "multiline/templates/svc.yaml" at : - error calling include: -template: no template "nested_helper.name" associated with template "gotpl"` - v := common.Values{} val, _ := util.CoalesceValues(c, v) @@ -1388,7 +1207,10 @@ template: no template "nested_helper.name" associated with template "gotpl"` _, err := Render(c, vals) require.Error(t, err) - assert.Equal(t, expectedErrorMessage, err.Error()) + assert.EqualError(t, err, `multiline/templates/svc.yaml:1:9 + executing "multiline/templates/svc.yaml" at : + error calling include: +template: no template "nested_helper.name" associated with template "gotpl"`) } func TestRenderCustomTemplateFuncs(t *testing.T) { @@ -1436,9 +1258,7 @@ func TestRenderCustomTemplateFuncs(t *testing.T) { // Render the chart. out, err := e.Render(c, v) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) // Expected output should be "hello!!!". expected := "hello!!!" @@ -1461,12 +1281,8 @@ func TestTraceableError_SimpleForm(t *testing.T) { } for _, errString := range testStrings { trace, done := parseTemplateSimpleErrorString(errString) - if !done { - t.Error("Expected parse to pass but did not") - } - if trace.message != "error calling include" { - t.Errorf("Expected %q, got %q", errString, trace.message) - } + assert.True(t, done, "Expected parse to pass but did not") + assert.Equal(t, "error calling include", trace.message, "Expected %q, got %q", errString, trace.message) } } func TestTraceableError_ExecutingForm(t *testing.T) { @@ -1478,12 +1294,8 @@ func TestTraceableError_ExecutingForm(t *testing.T) { errString := errTuple[0] expectedLocation := errTuple[1] trace, done := parseTemplateExecutingAtErrorType(errString) - if !done { - t.Error("Expected parse to pass but did not") - } - if trace.location != expectedLocation { - t.Errorf("Expected %q, got %q", expectedLocation, trace.location) - } + assert.True(t, done, "Expected parse to pass but did not") + assert.Equal(t, expectedLocation, trace.location, "Expected %q, got %q", expectedLocation, trace.location) } } @@ -1493,12 +1305,8 @@ func TestTraceableError_NoTemplateForm(t *testing.T) { } for _, errString := range testStrings { trace, done := parseTemplateNoTemplateError(errString, errString) - if !done { - t.Error("Expected parse to pass but did not") - } - if trace.message != errString { - t.Errorf("Expected %q, got %q", errString, trace.message) - } + assert.True(t, done, "Expected parse to pass but did not") + assert.Equal(t, errString, trace.message, "Expected %q, got %q", errString, trace.message) } } @@ -1535,9 +1343,7 @@ func TestRenderSubchartDefaultNilNoStringify(t *testing.T) { injValues := map[string]any{} tmp, err := util.CoalesceValues(parent, injValues) - if err != nil { - t.Fatalf("Failed to coalesce values: %s", err) - } + require.NoError(t, err, "Failed to coalesce values") inject := common.Values{ "Values": tmp, @@ -1548,18 +1354,9 @@ func TestRenderSubchartDefaultNilNoStringify(t *testing.T) { } out, err := Render(parent, inject) - if err != nil { - t.Fatalf("Failed to render templates: %s", err) - } + require.NoError(t, err, "Failed to render templates") rendered := out["parent/charts/child/templates/test.yaml"] - - if strings.Contains(rendered, "%!s()") { - t.Errorf("Rendered output contains %%!s(), got: %q", rendered) - } - - expected := "subPath: fallback" - if rendered != expected { - t.Errorf("Expected %q, got %q", expected, rendered) - } + assert.NotContains(t, rendered, "%!s()", "Rendered output contains %%!s(), got: %q", rendered) + assert.Equal(t, "subPath: fallback", rendered) } From 0daa77fa9bffe2c8359bb079d3e978fe74a0b5a4 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 20:50:57 +0200 Subject: [PATCH 25/61] chore(pkg): refactor: convert tests to testify assert/require part 2 refactor: convert tests to testify assert/require in pkg Signed-off-by: Matthieu MOREL --- pkg/cmd/flags_test.go | 9 +- pkg/getter/httpgetter_test.go | 345 +++++++++------------------------- 2 files changed, 93 insertions(+), 261 deletions(-) diff --git a/pkg/cmd/flags_test.go b/pkg/cmd/flags_test.go index 614970252..09dc61638 100644 --- a/pkg/cmd/flags_test.go +++ b/pkg/cmd/flags_test.go @@ -110,14 +110,11 @@ func TestPostRendererFlagSetOnce(t *testing.T) { }, } // Set the plugin name once - err := str.Set("postrenderer-v1") - require.NoError(t, err) + require.NoError(t, str.Set("postrenderer-v1")) // Set the plugin name again to the same value is not ok - err = str.Set("postrenderer-v1") - require.Error(t, err) + require.Error(t, str.Set("postrenderer-v1")) // Set the plugin name again to a different value is not ok - err = str.Set("cat") - require.Error(t, err) + require.Error(t, str.Set("cat")) } diff --git a/pkg/getter/httpgetter_test.go b/pkg/getter/httpgetter_test.go index d7ba770b3..bfde5efa8 100644 --- a/pkg/getter/httpgetter_test.go +++ b/pkg/getter/httpgetter_test.go @@ -28,6 +28,9 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "helm.sh/helm/v4/internal/tlsutil" "helm.sh/helm/v4/internal/version" "helm.sh/helm/v4/pkg/cli" @@ -35,13 +38,10 @@ import ( func TestHTTPGetter(t *testing.T) { g, err := NewHTTPGetter(WithURL("http://example.com")) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if _, ok := g.(*HTTPGetter); !ok { - t.Fatal("Expected NewHTTPGetter to produce an *HTTPGetter") - } + _, ok := g.(*HTTPGetter) + require.True(t, ok, "Expected NewHTTPGetter to produce an *HTTPGetter") cd := "../../testdata" join := filepath.Join @@ -60,54 +60,20 @@ func TestHTTPGetter(t *testing.T) { WithTimeout(timeout), WithTransport(transport), ) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) hg, ok := g.(*HTTPGetter) - if !ok { - t.Fatal("expected NewHTTPGetter to produce an *HTTPGetter") - } - - if hg.opts.username != "I" { - t.Errorf("Expected NewHTTPGetter to contain %q as the username, got %q", "I", hg.opts.username) - } - - if hg.opts.password != "Am" { - t.Errorf("Expected NewHTTPGetter to contain %q as the password, got %q", "Am", hg.opts.password) - } - - if hg.opts.passCredentialsAll != false { - t.Errorf("Expected NewHTTPGetter to contain %t as PassCredentialsAll, got %t", false, hg.opts.passCredentialsAll) - } - - if hg.opts.userAgent != "Groot" { - t.Errorf("Expected NewHTTPGetter to contain %q as the user agent, got %q", "Groot", hg.opts.userAgent) - } - - if hg.opts.certFile != pub { - t.Errorf("Expected NewHTTPGetter to contain %q as the public key file, got %q", pub, hg.opts.certFile) - } - - if hg.opts.keyFile != priv { - t.Errorf("Expected NewHTTPGetter to contain %q as the private key file, got %q", priv, hg.opts.keyFile) - } - - if hg.opts.caFile != ca { - t.Errorf("Expected NewHTTPGetter to contain %q as the CA file, got %q", ca, hg.opts.caFile) - } - - if hg.opts.insecureSkipVerifyTLS != insecure { - t.Errorf("Expected NewHTTPGetter to contain %t as InsecureSkipVerifyTLs flag, got %t", false, hg.opts.insecureSkipVerifyTLS) - } - - if hg.opts.timeout != timeout { - t.Errorf("Expected NewHTTPGetter to contain %s as Timeout flag, got %s", timeout, hg.opts.timeout) - } - - if hg.opts.transport != transport { - t.Errorf("Expected NewHTTPGetter to contain %p as Transport, got %p", transport, hg.opts.transport) - } + require.True(t, ok, "expected NewHTTPGetter to produce an *HTTPGetter") + assert.Equal(t, "I", hg.opts.username, "Expected NewHTTPGetter to contain %q as the username, got %q", "I", hg.opts.username) + assert.Equal(t, "Am", hg.opts.password, "Expected NewHTTPGetter to contain %q as the password, got %q", "Am", hg.opts.password) + assert.False(t, hg.opts.passCredentialsAll, "Expected NewHTTPGetter to contain %t as PassCredentialsAll, got %t", false, hg.opts.passCredentialsAll) + assert.Equal(t, "Groot", hg.opts.userAgent, "Expected NewHTTPGetter to contain %q as the user agent, got %q", "Groot", hg.opts.userAgent) + assert.Equal(t, pub, hg.opts.certFile, "Expected NewHTTPGetter to contain %q as the public key file, got %q", pub, hg.opts.certFile) + assert.Equal(t, priv, hg.opts.keyFile, "Expected NewHTTPGetter to contain %q as the private key file, got %q", priv, hg.opts.keyFile) + assert.Equal(t, ca, hg.opts.caFile, "Expected NewHTTPGetter to contain %q as the CA file, got %q", ca, hg.opts.caFile) + assert.Equal(t, insecure, hg.opts.insecureSkipVerifyTLS, "Expected NewHTTPGetter to contain %t as InsecureSkipVerifyTLs flag, got %t", false, hg.opts.insecureSkipVerifyTLS) + assert.Equal(t, timeout, hg.opts.timeout, "Expected NewHTTPGetter to contain %s as Timeout flag, got %s", timeout, hg.opts.timeout) + assert.Same(t, transport, hg.opts.transport, "Expected NewHTTPGetter to contain %p as Transport, got %p", transport, hg.opts.transport) // Test if setting insecureSkipVerifyTLS is being passed to the ops insecure = true @@ -115,65 +81,42 @@ func TestHTTPGetter(t *testing.T) { g, err = NewHTTPGetter( WithInsecureSkipVerifyTLS(insecure), ) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) hg, ok = g.(*HTTPGetter) - if !ok { - t.Fatal("expected NewHTTPGetter to produce an *HTTPGetter") - } - - if hg.opts.insecureSkipVerifyTLS != insecure { - t.Errorf("Expected NewHTTPGetter to contain %t as InsecureSkipVerifyTLs flag, got %t", insecure, hg.opts.insecureSkipVerifyTLS) - } + require.True(t, ok, "expected NewHTTPGetter to produce an *HTTPGetter") + assert.Equal(t, insecure, hg.opts.insecureSkipVerifyTLS, "Expected NewHTTPGetter to contain %t as InsecureSkipVerifyTLs flag, got %t", insecure, hg.opts.insecureSkipVerifyTLS) // Checking false by default - if hg.opts.passCredentialsAll != false { - t.Errorf("Expected NewHTTPGetter to contain %t as PassCredentialsAll, got %t", false, hg.opts.passCredentialsAll) - } + assert.False(t, hg.opts.passCredentialsAll, "Expected NewHTTPGetter to contain %t as PassCredentialsAll, got %t", false, hg.opts.passCredentialsAll) // Test setting PassCredentialsAll g, err = NewHTTPGetter( WithBasicAuth("I", "Am"), WithPassCredentialsAll(true), ) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) hg, ok = g.(*HTTPGetter) - if !ok { - t.Fatal("expected NewHTTPGetter to produce an *HTTPGetter") - } - if hg.opts.passCredentialsAll != true { - t.Errorf("Expected NewHTTPGetter to contain %t as PassCredentialsAll, got %t", true, hg.opts.passCredentialsAll) - } + require.True(t, ok, "expected NewHTTPGetter to produce an *HTTPGetter") + assert.True(t, hg.opts.passCredentialsAll, "Expected NewHTTPGetter to contain %t as PassCredentialsAll, got %t", true, hg.opts.passCredentialsAll) } func TestDownload(t *testing.T) { expect := "Call me Ishmael" srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { defaultUserAgent := version.GetUserAgent() - if r.UserAgent() != defaultUserAgent { - t.Errorf("Expected '%s', got '%s'", defaultUserAgent, r.UserAgent()) - } + assert.Equal(t, defaultUserAgent, r.UserAgent(), "Expected '%s', got '%s'", defaultUserAgent, r.UserAgent()) fmt.Fprint(w, expect) })) defer srv.Close() g, err := All(cli.New()).ByScheme("http") - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) got, err := g.Get(srv.URL, WithURL(srv.URL)) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if got.String() != expect { - t.Errorf("Expected %q, got %q", expect, got.String()) - } + assert.Equal(t, expect, got.String(), "Expected %q, got %q", expect, got.String()) // test with http server const expectedUserAgent = "I am Groot" @@ -182,9 +125,7 @@ func TestDownload(t *testing.T) { if !ok || username != "username" || password != "password" { t.Errorf("Expected request to use basic auth and for username == 'username' and password == 'password', got '%v', '%s', '%s'", ok, username, password) } - if r.UserAgent() != expectedUserAgent { - t.Errorf("Expected '%s', got '%s'", expectedUserAgent, r.UserAgent()) - } + assert.Equal(t, expectedUserAgent, r.UserAgent(), "Expected '%s', got '%s'", expectedUserAgent, r.UserAgent()) fmt.Fprint(w, expect) })) @@ -197,17 +138,11 @@ func TestDownload(t *testing.T) { WithPassCredentialsAll(false), WithUserAgent(expectedUserAgent), ) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) got, err = httpgetter.Get(u.String()) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if got.String() != expect { - t.Errorf("Expected %q, got %q", expect, got.String()) - } + assert.Equal(t, expect, got.String(), "Expected %q, got %q", expect, got.String()) // test with Get URL differing from withURL crossAuthSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -232,17 +167,11 @@ func TestDownload(t *testing.T) { WithBasicAuth("username", "password"), WithPassCredentialsAll(false), ) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) got, err = httpgetter.Get(u.String()) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if got.String() != expect { - t.Errorf("Expected %q, got %q", expect, got.String()) - } + assert.Equal(t, expect, got.String(), "Expected %q, got %q", expect, got.String()) // test with Get URL differing from withURL and should pass creds crossAuthSrv = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -267,24 +196,16 @@ func TestDownload(t *testing.T) { WithBasicAuth("username", "password"), WithPassCredentialsAll(true), ) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) got, err = httpgetter.Get(u.String()) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if got.String() != expect { - t.Errorf("Expected %q, got %q", expect, got.String()) - } + assert.Equal(t, expect, got.String(), "Expected %q, got %q", expect, got.String()) // test server with varied Accept Header const expectedAcceptHeader = "application/gzip,application/octet-stream" acceptHeaderSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Header.Get("Accept") != expectedAcceptHeader { - t.Errorf("Expected '%s', got '%s'", expectedAcceptHeader, r.Header.Get("Accept")) - } + assert.Equal(t, expectedAcceptHeader, r.Header.Get("Accept"), "Expected '%s', got '%s'", expectedAcceptHeader, r.Header.Get("Accept")) fmt.Fprint(w, expect) })) @@ -294,13 +215,9 @@ func TestDownload(t *testing.T) { httpgetter, err = NewHTTPGetter( WithAcceptHeader(expectedAcceptHeader), ) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) _, err = httpgetter.Get(u.String()) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) } func TestDownloadTLS(t *testing.T) { @@ -314,9 +231,7 @@ func TestDownloadTLS(t *testing.T) { tlsutil.WithCertKeyPairFiles(pub, priv), tlsutil.WithCAFile(ca), ) - if err != nil { - t.Fatal(fmt.Errorf("can't create TLS config for client: %w", err)) - } + require.NoError(t, err, "can't create TLS config for client") tlsConf.ServerName = "helm.sh" tlsSrv.TLS = tlsConf tlsSrv.StartTLS() @@ -327,33 +242,24 @@ func TestDownloadTLS(t *testing.T) { WithURL(u.String()), WithTLSClientConfig(pub, priv, ca), ) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if _, err := g.Get(u.String()); err != nil { - t.Error(err) - } + _, err = g.Get(u.String()) + require.NoError(t, err) // now test with TLS config being passed along in .Get (see #6635) g, err = NewHTTPGetter() - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if _, err := g.Get(u.String(), WithURL(u.String()), WithTLSClientConfig(pub, priv, ca)); err != nil { - t.Error(err) - } + _, err = g.Get(u.String(), WithURL(u.String()), WithTLSClientConfig(pub, priv, ca)) + require.NoError(t, err) // test with only the CA file (see also #6635) g, err = NewHTTPGetter() - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if _, err := g.Get(u.String(), WithURL(u.String()), WithTLSClientConfig("", "", ca)); err != nil { - t.Error(err) - } + _, err = g.Get(u.String(), WithURL(u.String()), WithTLSClientConfig("", "", ca)) + assert.NoError(t, err) } func TestDownloadTLSWithRedirect(t *testing.T) { @@ -369,9 +275,7 @@ func TestDownloadTLSWithRedirect(t *testing.T) { tlsutil.WithInsecureSkipVerify(insecureSkipTLSVerify), ) - if err != nil { - t.Fatal(fmt.Errorf("can't create TLS config for client: %w", err)) - } + require.NoError(t, err, "can't create TLS config for client") tlsSrv2 := httptest.NewUnstartedServer(http.HandlerFunc(func(rw http.ResponseWriter, _ *http.Request) { rw.Header().Set("Content-Type", "text/plain") @@ -390,9 +294,7 @@ func TestDownloadTLSWithRedirect(t *testing.T) { tlsutil.WithInsecureSkipVerify(insecureSkipTLSVerify), ) - if err != nil { - t.Fatal(fmt.Errorf("can't create TLS config for client: %w", err)) - } + require.NoError(t, err, "can't create TLS config for client") tlsSrv1 := httptest.NewUnstartedServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { u, _ := url.ParseRequestURI(tlsSrv2.URL) @@ -419,65 +321,41 @@ func TestDownloadTLSWithRedirect(t *testing.T) { WithURL(u.String()), WithTLSClientConfig(pub, priv, ca), ) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) buf, err := g.Get(u.String()) - if err != nil { - t.Error(err) - } + require.NoError(t, err) b, err := io.ReadAll(buf) - if err != nil { - t.Error(err) - } + require.NoError(t, err) - if string(b) != srv2Resp { - t.Errorf("expected response from Server2 to be '%s', instead got: %s", srv2Resp, string(b)) - } + assert.Equal(t, srv2Resp, string(b), "expected response from Server2 to be '%s', instead got: %s", srv2Resp, string(b)) }) t.Run("Test with TLS config being passed along in .Get (see #6635)", func(t *testing.T) { g, err := NewHTTPGetter() - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) buf, err := g.Get(u.String(), WithURL(u.String()), WithTLSClientConfig(pub, priv, ca)) - if err != nil { - t.Error(err) - } + require.NoError(t, err) b, err := io.ReadAll(buf) - if err != nil { - t.Error(err) - } + require.NoError(t, err) - if string(b) != srv2Resp { - t.Errorf("expected response from Server2 to be '%s', instead got: %s", srv2Resp, string(b)) - } + assert.Equal(t, srv2Resp, string(b), "expected response from Server2 to be '%s', instead got: %s", srv2Resp, string(b)) }) t.Run("Test with only the CA file (see also #6635)", func(t *testing.T) { g, err := NewHTTPGetter() - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) buf, err := g.Get(u.String(), WithURL(u.String()), WithTLSClientConfig("", "", ca)) - if err != nil { - t.Error(err) - } + require.NoError(t, err) b, err := io.ReadAll(buf) - if err != nil { - t.Error(err) - } + require.NoError(t, err) - if string(b) != srv2Resp { - t.Errorf("expected response from Server2 to be '%s', instead got: %s", srv2Resp, string(b)) - } + assert.Equal(t, srv2Resp, string(b), "expected response from Server2 to be '%s', instead got: %s", srv2Resp, string(b)) }) } @@ -491,25 +369,19 @@ func TestDownloadInsecureSkipTLSVerify(t *testing.T) { g, err := NewHTTPGetter( WithURL(u.String()), ) - if err != nil { - t.Error(err) - } + require.NoError(t, err) - if _, err := g.Get(u.String()); err == nil { - t.Errorf("Expected Getter to throw an error, got %s", err) - } + _, err = g.Get(u.String()) + require.Errorf(t, err, "Expected Getter to throw an error") // Test certificate check skip g, err = NewHTTPGetter( WithURL(u.String()), WithInsecureSkipVerifyTLS(true), ) - if err != nil { - t.Error(err) - } - if _, err = g.Get(u.String()); err != nil { - t.Error(err) - } + require.NoError(t, err) + _, err = g.Get(u.String()) + assert.NoError(t, err) } func TestHTTPGetterTarDownload(t *testing.T) { @@ -535,17 +407,13 @@ func TestHTTPGetterTarDownload(t *testing.T) { defer srv.Close() g, err := NewHTTPGetter(WithURL(srv.URL)) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) data, _ := g.Get(srv.URL) mimeType := http.DetectContentType(data.Bytes()) expectedMimeType := "application/x-gzip" - if mimeType != expectedMimeType { - t.Fatalf("Expected response with MIME type %s, but got %s", expectedMimeType, mimeType) - } + require.Equal(t, expectedMimeType, mimeType, "Expected response with MIME type %s, but got %s", expectedMimeType, mimeType) } func TestHttpClientInsecureSkipVerify(t *testing.T) { @@ -569,31 +437,22 @@ func TestHttpClientInsecureSkipVerify(t *testing.T) { g.opts.keyFile = "testdata/client.key" g.opts.insecureSkipVerifyTLS = true transport := verifyInsecureSkipVerify(t, &g, "HTTPGetter with 2 way ssl", true) - if len(transport.TLSClientConfig.Certificates) == 0 { - t.Fatal("transport.TLSClientConfig.Certificates is not present") - } + require.NotEmpty(t, transport.TLSClientConfig.Certificates, "transport.TLSClientConfig.Certificates is not present") } func verifyInsecureSkipVerify(t *testing.T, g *HTTPGetter, caseName string, expectedValue bool) *http.Transport { t.Helper() returnVal, err := g.httpClient(g.opts) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if returnVal == nil { - t.Fatal("Expected non nil value for http client") - } + require.NotNil(t, returnVal, "Expected non nil value for http client") transport := (returnVal.Transport).(*http.Transport) gotValue := false if transport.TLSClientConfig != nil { gotValue = transport.TLSClientConfig.InsecureSkipVerify } - if gotValue != expectedValue { - t.Fatalf("Case Name = %s\nInsecureSkipVerify did not come as expected. Expected = %t; Got = %v", - caseName, expectedValue, gotValue) - } + require.Equal(t, expectedValue, gotValue, "Case Name = %s\nInsecureSkipVerify did not come as expected. Expected = %t; Got = %v", caseName, expectedValue, gotValue) return transport } @@ -602,31 +461,21 @@ func TestDefaultHTTPTransportReuse(t *testing.T) { httpClient1, err := g.httpClient(g.opts) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if httpClient1 == nil { - t.Fatal("Expected non nil value for http client") - } + require.NotNil(t, httpClient1, "Expected non nil value for http client") transport1 := (httpClient1.Transport).(*http.Transport) httpClient2, err := g.httpClient(g.opts) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if httpClient2 == nil { - t.Fatal("Expected non nil value for http client") - } + require.NotNil(t, httpClient2, "Expected non nil value for http client") transport2 := (httpClient2.Transport).(*http.Transport) - if transport1 != transport2 { - t.Fatal("Expected default transport to be reused") - } + require.Equal(t, transport2, transport1, "Expected default transport to be reused") } func TestHTTPTransportOption(t *testing.T) { @@ -636,35 +485,23 @@ func TestHTTPTransportOption(t *testing.T) { g.opts.transport = transport httpClient1, err := g.httpClient(g.opts) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if httpClient1 == nil { - t.Fatal("Expected non nil value for http client") - } + require.NotNil(t, httpClient1, "Expected non nil value for http client") transport1 := (httpClient1.Transport).(*http.Transport) - if transport1 != transport { - t.Fatal("Expected transport option to be applied") - } + require.Equal(t, transport, transport1, "Expected transport option to be applied") httpClient2, err := g.httpClient(g.opts) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if httpClient2 == nil { - t.Fatal("Expected non nil value for http client") - } + require.NotNil(t, httpClient2, "Expected non nil value for http client") transport2 := (httpClient2.Transport).(*http.Transport) - if transport1 != transport2 { - t.Fatal("Expected applied transport to be reused") - } + require.Equal(t, transport2, transport1, "Expected applied transport to be reused") g = HTTPGetter{} g.opts.url = "https://localhost" @@ -673,7 +510,5 @@ func TestHTTPTransportOption(t *testing.T) { g.opts.insecureSkipVerifyTLS = true g.opts.transport = transport usedTransport := verifyInsecureSkipVerify(t, &g, "HTTPGetter with 2 way ssl", false) - if usedTransport.TLSClientConfig != nil { - t.Fatal("transport.TLSClientConfig should not be set") - } + require.Nil(t, usedTransport.TLSClientConfig, "transport.TLSClientConfig should not be set") } From ca1767b81397e5ee3b3a5f7926590ddf1134c9c5 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 20:50:55 +0200 Subject: [PATCH 26/61] chore(pkg): refactor: convert tests to testify assert/require part 7 refactor: convert tests to testify assert/require in pkg Signed-off-by: Matthieu MOREL --- pkg/chart/v2/util/save_test.go | 133 +++++------------- pkg/cmd/upgrade_test.go | 250 +++++++++------------------------ 2 files changed, 104 insertions(+), 279 deletions(-) diff --git a/pkg/chart/v2/util/save_test.go b/pkg/chart/v2/util/save_test.go index 55c67f49e..1795226bc 100644 --- a/pkg/chart/v2/util/save_test.go +++ b/pkg/chart/v2/util/save_test.go @@ -37,6 +37,7 @@ import ( chart "helm.sh/helm/v4/pkg/chart/v2" "helm.sh/helm/v4/pkg/chart/v2/loader" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -62,29 +63,16 @@ func TestSave(t *testing.T) { chartWithInvalidJSON := withSchema(*c, []byte("{")) where, err := Save(c, dest) - if err != nil { - t.Fatalf("Failed to save: %s", err) - } - if !strings.HasPrefix(where, dest) { - t.Fatalf("Expected %q to start with %q", where, dest) - } - if !strings.HasSuffix(where, ".tgz") { - t.Fatalf("Expected %q to end with .tgz", where) - } + require.NoError(t, err, "Failed to save") + require.Truef(t, strings.HasPrefix(where, dest), "Expected %q to start with %q", where, dest) + require.Truef(t, strings.HasSuffix(where, ".tgz"), "Expected %q to end with .tgz", where) c2, err := loader.LoadFile(where) - if err != nil { - t.Fatal(err) - } - if c2.Name() != c.Name() { - t.Fatalf("Expected chart archive to have %q, got %q", c.Name(), c2.Name()) - } - if len(c2.Files) != 1 || c2.Files[0].Name != "scheherazade/shahryar.txt" { - t.Fatal("Files data did not match") - } - if c2.Lock != nil { - t.Fatal("Expected v1 chart archive not to contain Chart.lock file") - } + require.NoError(t, err) + require.Equal(t, c.Name(), c2.Name(), "Expected chart archive to have %q, got %q", c.Name(), c2.Name()) + require.Len(t, c2.Files, 1, "Files data did not match") + require.Equal(t, "scheherazade/shahryar.txt", c2.Files[0].Name, "Files data did not match") + require.Nil(t, c2.Lock, "Expected v1 chart archive not to contain Chart.lock file") if !bytes.Equal(c.Schema, c2.Schema) { indentation := 4 @@ -92,25 +80,16 @@ func TestSave(t *testing.T) { formattedActual := Indent(indentation, string(c2.Schema)) t.Fatalf("Schema data did not match.\nExpected:\n%s\nActual:\n%s", formattedExpected, formattedActual) } - if _, err := Save(&chartWithInvalidJSON, dest); err == nil { - t.Fatal("Invalid JSON was not caught while saving chart") - } + _, err = Save(&chartWithInvalidJSON, dest) + require.Error(t, err, "Invalid JSON was not caught while saving chart") c.Metadata.APIVersion = chart.APIVersionV2 where, err = Save(c, dest) - if err != nil { - t.Fatalf("Failed to save: %s", err) - } + require.NoError(t, err, "Failed to save") c2, err = loader.LoadFile(where) - if err != nil { - t.Fatal(err) - } - if c2.Lock == nil { - t.Fatal("Expected v2 chart archive to contain a Chart.lock file") - } - if c2.Lock.Digest != c.Lock.Digest { - t.Fatal("Chart.lock data did not match") - } + require.NoError(t, err) + require.NotNil(t, c2.Lock, "Expected v2 chart archive to contain a Chart.lock file") + require.Equal(t, c.Lock.Digest, c2.Lock.Digest, "Chart.lock data did not match") }) } @@ -128,9 +107,7 @@ func TestSave(t *testing.T) { }, } _, err := Save(c, tmp) - if err == nil { - t.Fatal("Expected error saving chart with invalid name") - } + require.Error(t, err, "Expected error saving chart with invalid name") } // https://github.com/helm/helm/issues/31844 @@ -145,20 +122,14 @@ func TestSavedGzipExtraFieldIsValid(t *testing.T) { } where, err := Save(c, tmp) - if err != nil { - t.Fatalf("Failed to save: %s", err) - } + require.NoError(t, err, "Failed to save") f, err := os.Open(where) - if err != nil { - t.Fatalf("Failed to open saved file: %s", err) - } + require.NoError(t, err, "Failed to open saved file") defer f.Close() r, err := gzip.NewReader(f) - if err != nil { - t.Fatalf("Failed to create gzip reader: %s", err) - } + require.NoError(t, err, "Failed to create gzip reader") defer r.Close() // RFC 1952 §2.3.1.1: @@ -214,20 +185,14 @@ func TestSavePreservesTimestamps(t *testing.T) { } where, err := Save(c, tmp) - if err != nil { - t.Fatalf("Failed to save: %s", err) - } + require.NoError(t, err, "Failed to save") allHeaders, err := retrieveAllHeadersFromTar(where) - if err != nil { - t.Fatalf("Failed to parse tar: %v", err) - } + require.NoError(t, err, "Failed to parse tar") roundedTime := initialCreateTime.Round(time.Second) for _, header := range allHeaders { - if !header.ModTime.Equal(roundedTime) { - t.Fatalf("File timestamp not preserved: %v", header.ModTime) - } + require.Truef(t, header.ModTime.Equal(roundedTime), "File timestamp not preserved: %v", header.ModTime) } } @@ -248,20 +213,14 @@ func TestSaveWithSourceDateEpoch(t *testing.T) { c.StampModTimes(epoch) where, err := Save(c, tmp) - if err != nil { - t.Fatalf("Failed to save: %s", err) - } + require.NoError(t, err, "Failed to save") allHeaders, err := retrieveAllHeadersFromTar(where) - if err != nil { - t.Fatalf("Failed to parse tar: %v", err) - } + require.NoError(t, err, "Failed to parse tar") expected := epoch.Round(time.Second) for _, header := range allHeaders { - if !header.ModTime.Equal(expected) { - t.Fatalf("Expected SOURCE_DATE_EPOCH timestamp %v, got %v for %q", expected, header.ModTime, header.Name) - } + require.Truef(t, header.ModTime.Equal(expected), "Expected SOURCE_DATE_EPOCH timestamp %v, got %v for %q", expected, header.ModTime, header.Name) } } @@ -317,37 +276,25 @@ func TestSaveDir(t *testing.T) { }, } - if err := SaveDir(c, tmp); err != nil { - t.Fatalf("Failed to save: %s", err) - } + require.NoErrorf(t, SaveDir(c, tmp), "Failed to save") c2, err := loader.LoadDir(tmp + "/ahab") - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if c2.Name() != c.Name() { - t.Fatalf("Expected chart archive to have %q, got %q", c.Name(), c2.Name()) - } + require.Equal(t, c.Name(), c2.Name(), "Expected chart archive to have %q, got %q", c.Name(), c2.Name()) - if len(c2.Templates) != 1 || c2.Templates[0].Name != c.Templates[0].Name { - t.Fatal("Templates data did not match") - } + require.Len(t, c2.Templates, 1, "Templates data did not match") + require.Equal(t, c2.Templates[0].Name, c.Templates[0].Name, "Templates data did not match") - if len(c2.Files) != 1 || c2.Files[0].Name != c.Files[0].Name { - t.Fatal("Files data did not match") - } + require.Len(t, c2.Files, 1, "Files data did not match") + require.Equal(t, c2.Files[0].Name, c.Files[0].Name, "Files data did not match") tmp2 := t.TempDir() c.Metadata.Name = "../ahab" pth := filepath.Join(tmp2, "tmpcharts") - if err := os.MkdirAll(filepath.Join(pth), 0o755); err != nil { - t.Fatal(err) - } + require.NoError(t, os.MkdirAll(filepath.Join(pth), 0o755)) - if err := SaveDir(c, pth); err.Error() != "\"../ahab\" is not a valid chart name" { - t.Fatalf("Did not get expected error for chart named %q", c.Name()) - } + require.EqualErrorf(t, SaveDir(c, pth), "\"../ahab\" is not a valid chart name", "Did not get expected error for chart named %q", c.Name()) } func TestRepeatableSave(t *testing.T) { @@ -408,18 +355,12 @@ func TestRepeatableSave(t *testing.T) { // create package dest := path.Join(tmp, "newdir") where, err := Save(test.chart, dest) - if err != nil { - t.Fatalf("Failed to save: %s", err) - } + require.NoError(t, err, "Failed to save") // get shasum for package result, err := sha256Sum(where) - if err != nil { - t.Fatalf("Failed to check shasum: %s", err) - } + require.NoError(t, err, "Failed to check shasum") // assert that the package SHA is what we wanted. - if result != test.want { - t.Errorf("FormatName() result = %v, want %v", result, test.want) - } + assert.Equal(t, test.want, result, "FormatName() result = %v, want %v", result, test.want) }) } } diff --git a/pkg/cmd/upgrade_test.go b/pkg/cmd/upgrade_test.go index 30188d3d9..ab6c43235 100644 --- a/pkg/cmd/upgrade_test.go +++ b/pkg/cmd/upgrade_test.go @@ -21,10 +21,12 @@ import ( "os" "path/filepath" "reflect" - "strings" "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "helm.sh/helm/v4/pkg/chart/common" chart "helm.sh/helm/v4/pkg/chart/v2" "helm.sh/helm/v4/pkg/chart/v2/loader" @@ -44,13 +46,9 @@ func TestUpgradeCmd(t *testing.T) { }, } chartPath := filepath.Join(tmpChart, cfile.Metadata.Name) - if err := chartutil.SaveDir(cfile, tmpChart); err != nil { - t.Fatalf("Error creating chart for upgrade: %v", err) - } + require.NoErrorf(t, chartutil.SaveDir(cfile, tmpChart), "Error creating chart for upgrade") ch, err := loader.Load(chartPath) - if err != nil { - t.Fatalf("Error loading chart: %v", err) - } + require.NoError(t, err, "Error loading chart") _ = release.Mock(&release.MockReleaseOptions{ Name: "funny-bunny", Chart: ch, @@ -59,25 +57,17 @@ func TestUpgradeCmd(t *testing.T) { // update chart version cfile.Metadata.Version = "0.1.2" - if err := chartutil.SaveDir(cfile, tmpChart); err != nil { - t.Fatalf("Error creating chart: %v", err) - } + require.NoErrorf(t, chartutil.SaveDir(cfile, tmpChart), "Error creating chart") ch, err = loader.Load(chartPath) - if err != nil { - t.Fatalf("Error loading updated chart: %v", err) - } + require.NoError(t, err, "Error loading updated chart") // update chart version again cfile.Metadata.Version = "0.1.3" - if err := chartutil.SaveDir(cfile, tmpChart); err != nil { - t.Fatalf("Error creating chart: %v", err) - } + require.NoErrorf(t, chartutil.SaveDir(cfile, tmpChart), "Error creating chart") var ch2 *chart.Chart ch2, err = loader.Load(chartPath) - if err != nil { - t.Fatalf("Error loading updated chart: %v", err) - } + require.NoError(t, err, "Error loading updated chart") missingDepsPath := "testdata/testcharts/chart-missing-deps" badDepsPath := "testdata/testcharts/chart-bad-requirements" @@ -205,22 +195,14 @@ func TestUpgradeWithValue(t *testing.T) { cmd := fmt.Sprintf("upgrade %s --set favoriteDrink=tea '%s'", releaseName, chartPath) _, _, err := executeActionCommandC(store, cmd) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } + require.NoError(t, err) updatedReli, err := store.Get(releaseName, 4) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } - updatedRel, err := releaserToV1Release(updatedReli) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } + require.NoError(t, err) - if !strings.Contains(updatedRel.Manifest, "drink: tea") { - t.Errorf("The value is not set correctly. manifest: %s", updatedRel.Manifest) - } + updatedRel, err := releaserToV1Release(updatedReli) + require.NoError(t, err) + assert.Contains(t, updatedRel.Manifest, "drink: tea", "The value is not set correctly. manifest: %s", updatedRel.Manifest) } func TestUpgradeWithStringValue(t *testing.T) { @@ -235,22 +217,14 @@ func TestUpgradeWithStringValue(t *testing.T) { cmd := fmt.Sprintf("upgrade %s --set-string favoriteDrink=coffee '%s'", releaseName, chartPath) _, _, err := executeActionCommandC(store, cmd) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } + require.NoError(t, err) updatedReli, err := store.Get(releaseName, 4) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } - updatedRel, err := releaserToV1Release(updatedReli) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } + require.NoError(t, err) - if !strings.Contains(updatedRel.Manifest, "drink: coffee") { - t.Errorf("The value is not set correctly. manifest: %s", updatedRel.Manifest) - } + updatedRel, err := releaserToV1Release(updatedReli) + require.NoError(t, err) + assert.Contains(t, updatedRel.Manifest, "drink: coffee", "The value is not set correctly. manifest: %s", updatedRel.Manifest) } func TestUpgradeInstallWithSubchartNotes(t *testing.T) { @@ -265,26 +239,15 @@ func TestUpgradeInstallWithSubchartNotes(t *testing.T) { cmd := fmt.Sprintf("upgrade %s -i --render-subchart-notes '%s'", releaseName, "testdata/testcharts/chart-with-subchart-notes") _, _, err := executeActionCommandC(store, cmd) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } + require.NoError(t, err) upgradedReli, err := store.Get(releaseName, 2) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } - upgradedRel, err := releaserToV1Release(upgradedReli) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } + require.NoError(t, err) - if !strings.Contains(upgradedRel.Info.Notes, "PARENT NOTES") { - t.Errorf("The parent notes are not set correctly. NOTES: %s", upgradedRel.Info.Notes) - } - - if !strings.Contains(upgradedRel.Info.Notes, "SUBCHART NOTES") { - t.Errorf("The subchart notes are not set correctly. NOTES: %s", upgradedRel.Info.Notes) - } + upgradedRel, err := releaserToV1Release(upgradedReli) + require.NoError(t, err) + assert.Contains(t, upgradedRel.Info.Notes, "PARENT NOTES", "The parent notes are not set correctly. NOTES: %s", upgradedRel.Info.Notes) + assert.Contains(t, upgradedRel.Info.Notes, "SUBCHART NOTES", "The subchart notes are not set correctly. NOTES: %s", upgradedRel.Info.Notes) } func TestUpgradeWithValuesFile(t *testing.T) { @@ -299,22 +262,14 @@ func TestUpgradeWithValuesFile(t *testing.T) { cmd := fmt.Sprintf("upgrade %s --values testdata/testcharts/upgradetest/values.yaml '%s'", releaseName, chartPath) _, _, err := executeActionCommandC(store, cmd) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } + require.NoError(t, err) updatedReli, err := store.Get(releaseName, 4) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } - updatedRel, err := releaserToV1Release(updatedReli) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } + require.NoError(t, err) - if !strings.Contains(updatedRel.Manifest, "drink: beer") { - t.Errorf("The value is not set correctly. manifest: %s", updatedRel.Manifest) - } + updatedRel, err := releaserToV1Release(updatedReli) + require.NoError(t, err) + assert.Contains(t, updatedRel.Manifest, "drink: beer", "The value is not set correctly. manifest: %s", updatedRel.Manifest) } func TestUpgradeWithValuesFromStdin(t *testing.T) { @@ -328,28 +283,18 @@ func TestUpgradeWithValuesFromStdin(t *testing.T) { store.Create(relMock(releaseName, 3, ch)) in, err := os.Open("testdata/testcharts/upgradetest/values.yaml") - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } + require.NoError(t, err) cmd := fmt.Sprintf("upgrade %s --values - '%s'", releaseName, chartPath) _, _, err = executeActionCommandStdinC(store, in, cmd) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } + require.NoError(t, err) updatedReli, err := store.Get(releaseName, 4) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } - updatedRel, err := releaserToV1Release(updatedReli) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } + require.NoError(t, err) - if !strings.Contains(updatedRel.Manifest, "drink: beer") { - t.Errorf("The value is not set correctly. manifest: %s", updatedRel.Manifest) - } + updatedRel, err := releaserToV1Release(updatedReli) + require.NoError(t, err) + assert.Contains(t, updatedRel.Manifest, "drink: beer", "The value is not set correctly. manifest: %s", updatedRel.Manifest) } func TestUpgradeInstallWithValuesFromStdin(t *testing.T) { @@ -361,37 +306,25 @@ func TestUpgradeInstallWithValuesFromStdin(t *testing.T) { store := storageFixture() in, err := os.Open("testdata/testcharts/upgradetest/values.yaml") - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } + require.NoError(t, err) cmd := fmt.Sprintf("upgrade %s -f - --install '%s'", releaseName, chartPath) _, _, err = executeActionCommandStdinC(store, in, cmd) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } + require.NoError(t, err) updatedReli, err := store.Get(releaseName, 1) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } - updatedRel, err := releaserToV1Release(updatedReli) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } + require.NoError(t, err) - if !strings.Contains(updatedRel.Manifest, "drink: beer") { - t.Errorf("The value is not set correctly. manifest: %s", updatedRel.Manifest) - } + updatedRel, err := releaserToV1Release(updatedReli) + require.NoError(t, err) + assert.Contains(t, updatedRel.Manifest, "drink: beer", "The value is not set correctly. manifest: %s", updatedRel.Manifest) } func prepareMockRelease(t *testing.T, releaseName string) (func(n string, v int, ch *chart.Chart) *release.Release, *chart.Chart, string) { t.Helper() tmpChart := t.TempDir() configmapData, err := os.ReadFile("testdata/testcharts/upgradetest/templates/configmap.yaml") - if err != nil { - t.Fatalf("Error loading template yaml %v", err) - } + require.NoError(t, err, "Error loading template yaml") cfile := &chart.Chart{ Metadata: &chart.Metadata{ APIVersion: chart.APIVersionV1, @@ -402,13 +335,9 @@ func prepareMockRelease(t *testing.T, releaseName string) (func(n string, v int, Templates: []*common.File{{Name: "templates/configmap.yaml", ModTime: time.Now(), Data: configmapData}}, } chartPath := filepath.Join(tmpChart, cfile.Metadata.Name) - if err := chartutil.SaveDir(cfile, tmpChart); err != nil { - t.Fatalf("Error creating chart for upgrade: %v", err) - } + require.NoErrorf(t, chartutil.SaveDir(cfile, tmpChart), "Error creating chart for upgrade") ch, err := loader.Load(chartPath) - if err != nil { - t.Fatalf("Error loading chart: %v", err) - } + require.NoError(t, err, "Error loading chart") _ = release.Mock(&release.MockReleaseOptions{ Name: releaseName, Chart: ch, @@ -475,35 +404,23 @@ func TestUpgradeInstallWithLabels(t *testing.T) { } cmd := fmt.Sprintf("upgrade %s --install --labels key1=val1,key2=val2 '%s'", releaseName, chartPath) _, _, err := executeActionCommandC(store, cmd) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } + require.NoError(t, err) updatedReli, err := store.Get(releaseName, 1) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } - updatedRel, err := releaserToV1Release(updatedReli) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } + require.NoError(t, err) - if !reflect.DeepEqual(updatedRel.Labels, expectedLabels) { - t.Errorf("Expected {%v}, got {%v}", expectedLabels, updatedRel.Labels) - } + updatedRel, err := releaserToV1Release(updatedReli) + require.NoError(t, err) + assert.Truef(t, reflect.DeepEqual(updatedRel.Labels, expectedLabels), "Expected {%v}, got {%v}", expectedLabels, updatedRel.Labels) } func prepareMockReleaseWithSecret(t *testing.T, releaseName string) (func(n string, v int, ch *chart.Chart) *release.Release, *chart.Chart, string) { t.Helper() tmpChart := t.TempDir() configmapData, err := os.ReadFile("testdata/testcharts/chart-with-secret/templates/configmap.yaml") - if err != nil { - t.Fatalf("Error loading template yaml %v", err) - } + require.NoError(t, err, "Error loading template yaml") secretData, err := os.ReadFile("testdata/testcharts/chart-with-secret/templates/secret.yaml") - if err != nil { - t.Fatalf("Error loading template yaml %v", err) - } + require.NoError(t, err, "Error loading template yaml") modTime := time.Now() cfile := &chart.Chart{ Metadata: &chart.Metadata{ @@ -515,13 +432,9 @@ func prepareMockReleaseWithSecret(t *testing.T, releaseName string) (func(n stri Templates: []*common.File{{Name: "templates/configmap.yaml", ModTime: modTime, Data: configmapData}, {Name: "templates/secret.yaml", ModTime: modTime, Data: secretData}}, } chartPath := filepath.Join(tmpChart, cfile.Metadata.Name) - if err := chartutil.SaveDir(cfile, tmpChart); err != nil { - t.Fatalf("Error creating chart for upgrade: %v", err) - } + require.NoErrorf(t, chartutil.SaveDir(cfile, tmpChart), "Error creating chart for upgrade") ch, err := loader.Load(chartPath) - if err != nil { - t.Fatalf("Error loading chart: %v", err) - } + require.NoError(t, err, "Error loading chart") _ = release.Mock(&release.MockReleaseOptions{ Name: releaseName, Chart: ch, @@ -546,54 +459,34 @@ func TestUpgradeWithDryRun(t *testing.T) { // have it available. cmd := fmt.Sprintf("upgrade %s --install '%s'", releaseName, chartPath) _, _, err := executeActionCommandC(store, cmd) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } + require.NoError(t, err) _, err = store.Get(releaseName, 1) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } + require.NoError(t, err) cmd = fmt.Sprintf("upgrade %s --dry-run '%s'", releaseName, chartPath) _, out, err := executeActionCommandC(store, cmd) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } + require.NoError(t, err) // No second release should be stored because this is a dry run. _, err = store.Get(releaseName, 2) - if err == nil { - t.Error("expected error as there should be no new release but got none") - } - - if !strings.Contains(out, "kind: Secret") { - t.Error("expected secret in output from --dry-run but found none") - } + require.Error(t, err, "expected error as there should be no new release but got none") + assert.Contains(t, out, "kind: Secret", "expected secret in output from --dry-run but found none") // 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) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } + require.NoError(t, err) // No second release should be stored because this is a dry run. _, err = store.Get(releaseName, 2) - if err == nil { - t.Error("expected error as there should be no new release but got none") - } - - if strings.Contains(out, "kind: Secret") { - t.Error("expected no secret in output from --dry-run --hide-secret but found one") - } + require.Error(t, err, "expected error as there should be no new release but got none") + assert.NotContains(t, out, "kind: Secret", "expected no secret in output from --dry-run --hide-secret but found one") // 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) - if err == nil { - t.Error("expected error when --hide-secret used without --dry-run") - } + assert.Error(t, err, "expected error when --hide-secret used without --dry-run") } func TestUpgradeInstallServerSideApply(t *testing.T) { @@ -630,23 +523,14 @@ func TestUpgradeInstallServerSideApply(t *testing.T) { cmd := fmt.Sprintf("upgrade %s --install %s '%s'", releaseName, tt.serverSideFlag, chartPath) _, _, err := executeActionCommandC(store, cmd) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } + require.NoError(t, err) rel, err := store.Get(releaseName, 1) - if err != nil { - t.Fatalf("unexpected error getting release: %v", err) - } + require.NoError(t, err, "unexpected error getting release") relV1, err := releaserToV1Release(rel) - if err != nil { - t.Fatalf("unexpected error converting release: %v", err) - } - - if relV1.ApplyMethod != tt.expectedApplyMethod { - t.Errorf("expected ApplyMethod %q, got %q", tt.expectedApplyMethod, relV1.ApplyMethod) - } + require.NoError(t, err, "unexpected error converting release") + assert.Equal(t, tt.expectedApplyMethod, relV1.ApplyMethod, "expected ApplyMethod %q, got %q", tt.expectedApplyMethod, relV1.ApplyMethod) }) } } From e5f0e07b96580305c3902eceb738cef230b44bec Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 20:50:55 +0200 Subject: [PATCH 27/61] chore(pkg): refactor: convert tests to testify assert/require part 8 refactor: convert tests to testify assert/require in pkg Signed-off-by: Matthieu MOREL --- pkg/chart/v2/chart_test.go | 10 +- pkg/kube/statuswait_test.go | 168 +++++++++++------------------ pkg/storage/driver/cfgmaps_test.go | 115 ++++++-------------- 3 files changed, 98 insertions(+), 195 deletions(-) diff --git a/pkg/chart/v2/chart_test.go b/pkg/chart/v2/chart_test.go index 813669366..313d65480 100644 --- a/pkg/chart/v2/chart_test.go +++ b/pkg/chart/v2/chart_test.go @@ -21,6 +21,7 @@ import ( "time" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "helm.sh/helm/v4/pkg/chart/common" ) @@ -76,15 +77,12 @@ func TestSaveChartNoRawData(t *testing.T) { } is := assert.New(t) + req := require.New(t) data, err := json.Marshal(chrt) - if err != nil { - t.Fatal(err) - } + req.NoError(err) res := &Chart{} - if err := json.Unmarshal(data, res); err != nil { - t.Fatal(err) - } + req.NoError(json.Unmarshal(data, res)) is.Equal([]*common.File(nil), res.Raw) } diff --git a/pkg/kube/statuswait_test.go b/pkg/kube/statuswait_test.go index 21580b57a..5f5f5d051 100644 --- a/pkg/kube/statuswait_test.go +++ b/pkg/kube/statuswait_test.go @@ -272,8 +272,7 @@ func getRuntimeObjFromManifests(t *testing.T, manifests []string) []runtime.Obje objects := []runtime.Object{} for _, manifest := range manifests { m := make(map[string]any) - err := yaml.Unmarshal([]byte(manifest), &m) - require.NoError(t, err) + require.NoError(t, yaml.Unmarshal([]byte(manifest), &m)) resource := &unstructured.Unstructured{Object: m} objects = append(objects, resource) } @@ -332,8 +331,7 @@ func TestStatusWaitForDelete(t *testing.T) { for _, objToCreate := range objsToCreate { u := objToCreate.(*unstructured.Unstructured) gvr := getGVR(t, fakeMapper, u) - err := fakeClient.Tracker().Create(gvr, u, u.GetNamespace()) - require.NoError(t, err) + require.NoError(t, fakeClient.Tracker().Create(gvr, u, u.GetNamespace())) } objsToDelete := getRuntimeObjFromManifests(t, tt.manifestsToDelete) for _, objToDelete := range objsToDelete { @@ -341,8 +339,7 @@ func TestStatusWaitForDelete(t *testing.T) { gvr := getGVR(t, fakeMapper, u) go func(gvr schema.GroupVersionResource, u *unstructured.Unstructured) { time.Sleep(timeUntilPodDelete) - err := fakeClient.Tracker().Delete(gvr, u.GetNamespace(), u.GetName()) - assert.NoError(t, err) + assert.NoError(t, fakeClient.Tracker().Delete(gvr, u.GetNamespace(), u.GetName())) }(gvr, u) } resourceList := getResourceListFromRuntimeObjs(t, c, objsToCreate) @@ -352,9 +349,9 @@ func TestStatusWaitForDelete(t *testing.T) { for _, expectedErrStr := range tt.expectErrs { require.ErrorContains(t, err, expectedErrStr) } - return + } else { + assert.NoError(t, err) } - assert.NoError(t, err) }) } } @@ -375,8 +372,7 @@ func TestStatusWaitForDeleteNonExistentObject(t *testing.T) { // Don't create the object to test that the wait for delete works when the object doesn't exist objManifest := getRuntimeObjFromManifests(t, []string{podCurrentManifest}) resourceList := getResourceListFromRuntimeObjs(t, c, objManifest) - err := statusWaiter.WaitForDelete(resourceList, timeout) - assert.NoError(t, err) + assert.NoError(t, statusWaiter.WaitForDelete(resourceList, timeout)) } func TestStatusWait(t *testing.T) { @@ -433,8 +429,7 @@ func TestStatusWait(t *testing.T) { for _, obj := range objs { u := obj.(*unstructured.Unstructured) gvr := getGVR(t, fakeMapper, u) - err := fakeClient.Tracker().Create(gvr, u, u.GetNamespace()) - require.NoError(t, err) + require.NoError(t, fakeClient.Tracker().Create(gvr, u, u.GetNamespace())) } resourceList := getResourceListFromRuntimeObjs(t, c, objs) err := statusWaiter.Wait(resourceList, time.Second*3) @@ -443,9 +438,9 @@ func TestStatusWait(t *testing.T) { for _, expectedErrStr := range tt.expectErrStrs { require.ErrorContains(t, err, expectedErrStr) } - return + } else { + assert.NoError(t, err) } - assert.NoError(t, err) }) } } @@ -490,8 +485,7 @@ func TestWaitForJobComplete(t *testing.T) { for _, obj := range objs { u := obj.(*unstructured.Unstructured) gvr := getGVR(t, fakeMapper, u) - err := fakeClient.Tracker().Create(gvr, u, u.GetNamespace()) - require.NoError(t, err) + require.NoError(t, fakeClient.Tracker().Create(gvr, u, u.GetNamespace())) } resourceList := getResourceListFromRuntimeObjs(t, c, objs) err := statusWaiter.WaitWithJobs(resourceList, time.Second*3) @@ -500,9 +494,9 @@ func TestWaitForJobComplete(t *testing.T) { for _, expectedErrStr := range tt.expectErrStrs { require.ErrorContains(t, err, expectedErrStr) } - return + } else { + assert.NoError(t, err) } - assert.NoError(t, err) }) } } @@ -553,8 +547,7 @@ func TestWatchForReady(t *testing.T) { for _, obj := range objs { u := obj.(*unstructured.Unstructured) gvr := getGVR(t, fakeMapper, u) - err := fakeClient.Tracker().Create(gvr, u, u.GetNamespace()) - require.NoError(t, err) + require.NoError(t, fakeClient.Tracker().Create(gvr, u, u.GetNamespace())) } resourceList := getResourceListFromRuntimeObjs(t, c, objs) err := statusWaiter.WatchUntilReady(resourceList, time.Second*3) @@ -563,9 +556,9 @@ func TestWatchForReady(t *testing.T) { for _, expectedErrStr := range tt.expectErrStrs { require.ErrorContains(t, err, expectedErrStr) } - return + } else { + assert.NoError(t, err) } - assert.NoError(t, err) }) } } @@ -657,8 +650,7 @@ func TestStatusWaitMultipleNamespaces(t *testing.T) { for _, obj := range objs { u := obj.(*unstructured.Unstructured) gvr := getGVR(t, fakeMapper, u) - err := fakeClient.Tracker().Create(gvr, u, u.GetNamespace()) - require.NoError(t, err) + require.NoError(t, fakeClient.Tracker().Create(gvr, u, u.GetNamespace())) } if strings.Contains(tt.name, "delete") { @@ -668,8 +660,7 @@ func TestStatusWaitMultipleNamespaces(t *testing.T) { gvr := getGVR(t, fakeMapper, u) go func(gvr schema.GroupVersionResource, u *unstructured.Unstructured) { time.Sleep(timeUntilDelete) - err := fakeClient.Tracker().Delete(gvr, u.GetNamespace(), u.GetName()) - assert.NoError(t, err) + assert.NoError(t, fakeClient.Tracker().Delete(gvr, u.GetNamespace(), u.GetName())) }(gvr, u) } } @@ -681,9 +672,9 @@ func TestStatusWaitMultipleNamespaces(t *testing.T) { for _, expectedErrStr := range tt.expectErrStrs { require.ErrorContains(t, err, expectedErrStr) } - return + } else { + assert.NoError(t, err) } - assert.NoError(t, err) }) } } @@ -839,8 +830,7 @@ func TestStatusWaitRestrictedRBAC(t *testing.T) { for _, obj := range objs { u := obj.(*unstructured.Unstructured) gvr := getGVR(t, fakeMapper, u) - err := baseFakeClient.Tracker().Create(gvr, u, u.GetNamespace()) - require.NoError(t, err) + require.NoError(t, baseFakeClient.Tracker().Create(gvr, u, u.GetNamespace())) } if strings.Contains(tt.name, "delet") { @@ -850,8 +840,7 @@ func TestStatusWaitRestrictedRBAC(t *testing.T) { gvr := getGVR(t, fakeMapper, u) go func(gvr schema.GroupVersionResource, u *unstructured.Unstructured) { time.Sleep(timeUntilDelete) - err := baseFakeClient.Tracker().Delete(gvr, u.GetNamespace(), u.GetName()) - assert.NoError(t, err) + assert.NoError(t, baseFakeClient.Tracker().Delete(gvr, u.GetNamespace(), u.GetName())) }(gvr, u) } } @@ -863,10 +852,10 @@ func TestStatusWaitRestrictedRBAC(t *testing.T) { for _, expectedErr := range tt.expectErrs { require.ErrorContains(t, err, expectedErr.Error()) } - return + } else { + require.NoError(t, err) + assert.False(t, restrictedConfig.clusterScopedListAttempted) } - require.NoError(t, err) - assert.False(t, restrictedConfig.clusterScopedListAttempted) }) } } @@ -947,8 +936,7 @@ func TestStatusWaitMixedResources(t *testing.T) { for _, obj := range objs { u := obj.(*unstructured.Unstructured) gvr := getGVR(t, fakeMapper, u) - err := baseFakeClient.Tracker().Create(gvr, u, u.GetNamespace()) - require.NoError(t, err) + require.NoError(t, baseFakeClient.Tracker().Create(gvr, u, u.GetNamespace())) } if strings.Contains(tt.name, "delet") { @@ -958,8 +946,7 @@ func TestStatusWaitMixedResources(t *testing.T) { gvr := getGVR(t, fakeMapper, u) go func(gvr schema.GroupVersionResource, u *unstructured.Unstructured) { time.Sleep(timeUntilDelete) - err := baseFakeClient.Tracker().Delete(gvr, u.GetNamespace(), u.GetName()) - assert.NoError(t, err) + assert.NoError(t, baseFakeClient.Tracker().Delete(gvr, u.GetNamespace(), u.GetName())) }(gvr, u) } } @@ -971,10 +958,10 @@ func TestStatusWaitMixedResources(t *testing.T) { for _, expectedErr := range tt.expectErrs { require.ErrorContains(t, err, expectedErr.Error()) } - return + } else { + require.NoError(t, err) + assert.False(t, restrictedConfig.clusterScopedListAttempted) } - require.NoError(t, err) - assert.False(t, restrictedConfig.clusterScopedListAttempted) }) } } @@ -1067,8 +1054,7 @@ func TestStatusWaitWithCustomReaders(t *testing.T) { for _, obj := range objs { u := obj.(*unstructured.Unstructured) gvr := getGVR(t, fakeMapper, u) - err := fakeClient.Tracker().Create(gvr, u, u.GetNamespace()) - require.NoError(t, err) + require.NoError(t, fakeClient.Tracker().Create(gvr, u, u.GetNamespace())) } resourceList := getResourceListFromRuntimeObjs(t, c, objs) err := statusWaiter.Wait(resourceList, time.Second*3) @@ -1077,9 +1063,9 @@ func TestStatusWaitWithCustomReaders(t *testing.T) { for _, expectedErrStr := range tt.expectErrStrs { require.ErrorContains(t, err, expectedErrStr) } - return + } else { + assert.NoError(t, err) } - assert.NoError(t, err) }) } } @@ -1139,16 +1125,15 @@ func TestStatusWaitWithJobsAndCustomReaders(t *testing.T) { for _, obj := range objs { u := obj.(*unstructured.Unstructured) gvr := getGVR(t, fakeMapper, u) - err := fakeClient.Tracker().Create(gvr, u, u.GetNamespace()) - require.NoError(t, err) + require.NoError(t, fakeClient.Tracker().Create(gvr, u, u.GetNamespace())) } resourceList := getResourceListFromRuntimeObjs(t, c, objs) err := statusWaiter.WaitWithJobs(resourceList, time.Second*3) if tt.expectErrs != nil { assert.EqualError(t, err, errors.Join(tt.expectErrs...).Error()) - return + } else { + assert.NoError(t, err) } - assert.NoError(t, err) }) } } @@ -1238,8 +1223,7 @@ func TestStatusWaitWithFailedResources(t *testing.T) { for _, obj := range objs { u := obj.(*unstructured.Unstructured) gvr := getGVR(t, fakeMapper, u) - err := fakeClient.Tracker().Create(gvr, u, u.GetNamespace()) - require.NoError(t, err) + require.NoError(t, fakeClient.Tracker().Create(gvr, u, u.GetNamespace())) } resourceList := getResourceListFromRuntimeObjs(t, c, objs) err := tt.testFunc(&sw, resourceList, time.Second*3) @@ -1248,9 +1232,9 @@ func TestStatusWaitWithFailedResources(t *testing.T) { for _, expectedErrStr := range tt.expectErrStrs { require.ErrorContains(t, err, expectedErrStr) } - return + } else { + assert.NoError(t, err) } - assert.NoError(t, err) }) } } @@ -1343,14 +1327,12 @@ func TestMethodSpecificContextCancellation(t *testing.T) { for _, obj := range objs { u := obj.(*unstructured.Unstructured) gvr := getGVR(t, fakeMapper, u) - err := fakeClient.Tracker().Create(gvr, u, u.GetNamespace()) - require.NoError(t, err) + require.NoError(t, fakeClient.Tracker().Create(gvr, u, u.GetNamespace())) } resourceList := getResourceListFromRuntimeObjs(t, c, objs) - err := sw.WatchUntilReady(resourceList, time.Second*3) // Should fail due to cancelled method context - assert.ErrorContains(t, err, "context canceled") + assert.ErrorContains(t, sw.WatchUntilReady(resourceList, time.Second*3), "context canceled") }) t.Run("Wait uses method-specific context", func(t *testing.T) { @@ -1376,14 +1358,12 @@ func TestMethodSpecificContextCancellation(t *testing.T) { for _, obj := range objs { u := obj.(*unstructured.Unstructured) gvr := getGVR(t, fakeMapper, u) - err := fakeClient.Tracker().Create(gvr, u, u.GetNamespace()) - require.NoError(t, err) + require.NoError(t, fakeClient.Tracker().Create(gvr, u, u.GetNamespace())) } resourceList := getResourceListFromRuntimeObjs(t, c, objs) - err := sw.Wait(resourceList, time.Second*3) // Should fail due to cancelled method context - assert.ErrorContains(t, err, "context canceled") + assert.ErrorContains(t, sw.Wait(resourceList, time.Second*3), "context canceled") }) t.Run("WaitWithJobs uses method-specific context", func(t *testing.T) { @@ -1409,14 +1389,12 @@ func TestMethodSpecificContextCancellation(t *testing.T) { for _, obj := range objs { u := obj.(*unstructured.Unstructured) gvr := getGVR(t, fakeMapper, u) - err := fakeClient.Tracker().Create(gvr, u, u.GetNamespace()) - require.NoError(t, err) + require.NoError(t, fakeClient.Tracker().Create(gvr, u, u.GetNamespace())) } resourceList := getResourceListFromRuntimeObjs(t, c, objs) - err := sw.WaitWithJobs(resourceList, time.Second*3) // Should fail due to cancelled method context - assert.ErrorContains(t, err, "context canceled") + assert.ErrorContains(t, sw.WaitWithJobs(resourceList, time.Second*3), "context canceled") }) t.Run("WaitForDelete uses method-specific context", func(t *testing.T) { @@ -1442,14 +1420,12 @@ func TestMethodSpecificContextCancellation(t *testing.T) { for _, obj := range objs { u := obj.(*unstructured.Unstructured) gvr := getGVR(t, fakeMapper, u) - err := fakeClient.Tracker().Create(gvr, u, u.GetNamespace()) - require.NoError(t, err) + require.NoError(t, fakeClient.Tracker().Create(gvr, u, u.GetNamespace())) } resourceList := getResourceListFromRuntimeObjs(t, c, objs) - err := sw.WaitForDelete(resourceList, time.Second*3) // Should fail due to cancelled method context - assert.ErrorContains(t, err, "context canceled") + assert.ErrorContains(t, sw.WaitForDelete(resourceList, time.Second*3), "context canceled") }) } @@ -1479,14 +1455,12 @@ func TestMethodContextFallbackToGeneralContext(t *testing.T) { for _, obj := range objs { u := obj.(*unstructured.Unstructured) gvr := getGVR(t, fakeMapper, u) - err := fakeClient.Tracker().Create(gvr, u, u.GetNamespace()) - require.NoError(t, err) + require.NoError(t, fakeClient.Tracker().Create(gvr, u, u.GetNamespace())) } resourceList := getResourceListFromRuntimeObjs(t, c, objs) - err := sw.WatchUntilReady(resourceList, time.Second*3) // Should fail due to cancelled general context - assert.ErrorContains(t, err, "context canceled") + assert.ErrorContains(t, sw.WatchUntilReady(resourceList, time.Second*3), "context canceled") }) t.Run("Wait falls back to general context when method context is nil", func(t *testing.T) { @@ -1512,14 +1486,12 @@ func TestMethodContextFallbackToGeneralContext(t *testing.T) { for _, obj := range objs { u := obj.(*unstructured.Unstructured) gvr := getGVR(t, fakeMapper, u) - err := fakeClient.Tracker().Create(gvr, u, u.GetNamespace()) - require.NoError(t, err) + require.NoError(t, fakeClient.Tracker().Create(gvr, u, u.GetNamespace())) } resourceList := getResourceListFromRuntimeObjs(t, c, objs) - err := sw.Wait(resourceList, time.Second*3) // Should fail due to cancelled general context - assert.ErrorContains(t, err, "context canceled") + assert.ErrorContains(t, sw.Wait(resourceList, time.Second*3), "context canceled") }) t.Run("WaitWithJobs falls back to general context when method context is nil", func(t *testing.T) { @@ -1545,14 +1517,12 @@ func TestMethodContextFallbackToGeneralContext(t *testing.T) { for _, obj := range objs { u := obj.(*unstructured.Unstructured) gvr := getGVR(t, fakeMapper, u) - err := fakeClient.Tracker().Create(gvr, u, u.GetNamespace()) - require.NoError(t, err) + require.NoError(t, fakeClient.Tracker().Create(gvr, u, u.GetNamespace())) } resourceList := getResourceListFromRuntimeObjs(t, c, objs) - err := sw.WaitWithJobs(resourceList, time.Second*3) // Should fail due to cancelled general context - assert.ErrorContains(t, err, "context canceled") + assert.ErrorContains(t, sw.WaitWithJobs(resourceList, time.Second*3), "context canceled") }) t.Run("WaitForDelete falls back to general context when method context is nil", func(t *testing.T) { @@ -1578,14 +1548,12 @@ func TestMethodContextFallbackToGeneralContext(t *testing.T) { for _, obj := range objs { u := obj.(*unstructured.Unstructured) gvr := getGVR(t, fakeMapper, u) - err := fakeClient.Tracker().Create(gvr, u, u.GetNamespace()) - require.NoError(t, err) + require.NoError(t, fakeClient.Tracker().Create(gvr, u, u.GetNamespace())) } resourceList := getResourceListFromRuntimeObjs(t, c, objs) - err := sw.WaitForDelete(resourceList, time.Second*3) // Should fail due to cancelled general context - assert.ErrorContains(t, err, "context canceled") + assert.ErrorContains(t, sw.WaitForDelete(resourceList, time.Second*3), "context canceled") }) } @@ -1615,14 +1583,12 @@ func TestMethodContextOverridesGeneralContext(t *testing.T) { for _, obj := range objs { u := obj.(*unstructured.Unstructured) gvr := getGVR(t, fakeMapper, u) - err := fakeClient.Tracker().Create(gvr, u, u.GetNamespace()) - require.NoError(t, err) + require.NoError(t, fakeClient.Tracker().Create(gvr, u, u.GetNamespace())) } resourceList := getResourceListFromRuntimeObjs(t, c, objs) - err := sw.WatchUntilReady(resourceList, time.Second*3) // Should succeed because method context is used and it's not cancelled - assert.NoError(t, err) + assert.NoError(t, sw.WatchUntilReady(resourceList, time.Second*3)) }) t.Run("method-specific context overrides general context for Wait", func(t *testing.T) { @@ -1648,14 +1614,12 @@ func TestMethodContextOverridesGeneralContext(t *testing.T) { for _, obj := range objs { u := obj.(*unstructured.Unstructured) gvr := getGVR(t, fakeMapper, u) - err := fakeClient.Tracker().Create(gvr, u, u.GetNamespace()) - require.NoError(t, err) + require.NoError(t, fakeClient.Tracker().Create(gvr, u, u.GetNamespace())) } resourceList := getResourceListFromRuntimeObjs(t, c, objs) - err := sw.Wait(resourceList, time.Second*3) // Should succeed because method context is used and it's not cancelled - assert.NoError(t, err) + assert.NoError(t, sw.Wait(resourceList, time.Second*3)) }) t.Run("method-specific context overrides general context for WaitWithJobs", func(t *testing.T) { @@ -1681,14 +1645,12 @@ func TestMethodContextOverridesGeneralContext(t *testing.T) { for _, obj := range objs { u := obj.(*unstructured.Unstructured) gvr := getGVR(t, fakeMapper, u) - err := fakeClient.Tracker().Create(gvr, u, u.GetNamespace()) - require.NoError(t, err) + require.NoError(t, fakeClient.Tracker().Create(gvr, u, u.GetNamespace())) } resourceList := getResourceListFromRuntimeObjs(t, c, objs) - err := sw.WaitWithJobs(resourceList, time.Second*3) // Should succeed because method context is used and it's not cancelled - assert.NoError(t, err) + assert.NoError(t, sw.WaitWithJobs(resourceList, time.Second*3)) }) t.Run("method-specific context overrides general context for WaitForDelete", func(t *testing.T) { @@ -1717,9 +1679,8 @@ func TestMethodContextOverridesGeneralContext(t *testing.T) { // immediately cancelled and the call would return a context error. objs := getRuntimeObjFromManifests(t, []string{podCurrentManifest}) resourceList := getResourceListFromRuntimeObjs(t, c, objs) - err := sw.WaitForDelete(resourceList, time.Second) // Should succeed because method context is used and it's not cancelled - assert.NoError(t, err) + assert.NoError(t, sw.WaitForDelete(resourceList, time.Second)) }) } @@ -1801,8 +1762,7 @@ func TestWatchUntilReadyWithCustomReaders(t *testing.T) { for _, obj := range objs { u := obj.(*unstructured.Unstructured) gvr := getGVR(t, fakeMapper, u) - err := fakeClient.Tracker().Create(gvr, u, u.GetNamespace()) - require.NoError(t, err) + require.NoError(t, fakeClient.Tracker().Create(gvr, u, u.GetNamespace())) } resourceList := getResourceListFromRuntimeObjs(t, c, objs) err := statusWaiter.WatchUntilReady(resourceList, time.Second*3) @@ -1811,9 +1771,9 @@ func TestWatchUntilReadyWithCustomReaders(t *testing.T) { for _, expectedErrStr := range tt.expectErrStrs { require.ErrorContains(t, err, expectedErrStr) } - return + } else { + assert.NoError(t, err) } - assert.NoError(t, err) }) } } diff --git a/pkg/storage/driver/cfgmaps_test.go b/pkg/storage/driver/cfgmaps_test.go index 947ebff71..e36aecce8 100644 --- a/pkg/storage/driver/cfgmaps_test.go +++ b/pkg/storage/driver/cfgmaps_test.go @@ -16,10 +16,11 @@ package driver import ( "encoding/base64" "encoding/json" - "errors" "reflect" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" "helm.sh/helm/v4/pkg/release" @@ -29,9 +30,7 @@ import ( func TestConfigMapName(t *testing.T) { c := newTestFixtureCfgMaps(t) - if c.Name() != ConfigMapsDriverName { - t.Errorf("Expected name to be %q, got %q", ConfigMapsDriverName, c.Name()) - } + assert.Equal(t, ConfigMapsDriverName, c.Name(), "Expected name to be %q, got %q", ConfigMapsDriverName, c.Name()) } func TestConfigMapGet(t *testing.T) { @@ -45,13 +44,9 @@ func TestConfigMapGet(t *testing.T) { // get release with key got, err := cfgmaps.Get(key) - if err != nil { - t.Fatalf("Failed to get release: %s", err) - } + require.NoError(t, err, "Failed to get release") // compare fetched release with original - if !reflect.DeepEqual(rel, got) { - t.Errorf("Expected {%v}, got {%v}", rel, got) - } + assert.Truef(t, reflect.DeepEqual(rel, got), "Expected {%v}, got {%v}", rel, got) } func TestUncompressedConfigMapGet(t *testing.T) { @@ -63,13 +58,9 @@ func TestUncompressedConfigMapGet(t *testing.T) { // Create a test fixture which contains an uncompressed release cfgmap, err := newConfigMapsObject(key, rel, nil) - if err != nil { - t.Fatalf("Failed to create configmap: %s", err) - } + require.NoError(t, err, "Failed to create configmap") b, err := json.Marshal(rel) - if err != nil { - t.Fatalf("Failed to marshal release: %s", err) - } + require.NoError(t, err, "Failed to marshal release") cfgmap.Data["release"] = base64.StdEncoding.EncodeToString(b) var mock MockConfigMapsInterface mock.objects = map[string]*v1.ConfigMap{key: cfgmap} @@ -77,13 +68,9 @@ func TestUncompressedConfigMapGet(t *testing.T) { // get release with key got, err := cfgmaps.Get(key) - if err != nil { - t.Fatalf("Failed to get release: %s", err) - } + require.NoError(t, err, "Failed to get release") // compare fetched release with original - if !reflect.DeepEqual(rel, got) { - t.Errorf("Expected {%v}, got {%v}", rel, got) - } + assert.Truef(t, reflect.DeepEqual(rel, got), "Expected {%v}, got {%v}", rel, got) } func convertReleaserToV1(t *testing.T, rel release.Releaser) *rspb.Release { @@ -117,12 +104,8 @@ func TestConfigMapList(t *testing.T) { return rls.Info.Status == common.StatusUninstalled }) // check - if err != nil { - t.Errorf("Failed to list deleted: %s", err) - } - if len(del) != 2 { - t.Errorf("Expected 2 deleted, got %d:\n%v\n", len(del), del) - } + require.NoError(t, err, "Failed to list deleted") + assert.Len(t, del, 2, "Expected 2 deleted, got %d:\n%v\n", len(del), del) // list all deployed releases dpl, err := cfgmaps.List(func(rel release.Releaser) bool { @@ -130,12 +113,8 @@ func TestConfigMapList(t *testing.T) { return rls.Info.Status == common.StatusDeployed }) // check - if err != nil { - t.Errorf("Failed to list deployed: %s", err) - } - if len(dpl) != 2 { - t.Errorf("Expected 2 deployed, got %d", len(dpl)) - } + require.NoError(t, err, "Failed to list deployed") + assert.Len(t, dpl, 2, "Expected 2 deployed, got %d", len(dpl)) // list all superseded releases ssd, err := cfgmaps.List(func(rel release.Releaser) bool { @@ -143,22 +122,14 @@ func TestConfigMapList(t *testing.T) { return rls.Info.Status == common.StatusSuperseded }) // check - if err != nil { - t.Errorf("Failed to list superseded: %s", err) - } - if len(ssd) != 2 { - t.Errorf("Expected 2 superseded, got %d", len(ssd)) - } + require.NoError(t, err, "Failed to list superseded") + assert.Len(t, ssd, 2, "Expected 2 superseded, got %d", len(ssd)) // Check if release having both system and custom labels, this is needed to ensure that selector filtering would work. rls := convertReleaserToV1(t, ssd[0]) _, ok := rls.Labels["name"] - if !ok { - t.Fatalf("Expected 'name' label in results, actual %v", rls.Labels) - } + require.True(t, ok, "Expected 'name' label in results, actual %v", rls.Labels) _, ok = rls.Labels["key1"] - if !ok { - t.Fatalf("Expected 'key1' label in results, actual %v", rls.Labels) - } + require.True(t, ok, "Expected 'key1' label in results, actual %v", rls.Labels) } func TestConfigMapQuery(t *testing.T) { @@ -172,17 +143,11 @@ func TestConfigMapQuery(t *testing.T) { }...) rls, err := cfgmaps.Query(map[string]string{"status": "deployed"}) - if err != nil { - t.Errorf("Failed to query: %s", err) - } - if len(rls) != 2 { - t.Errorf("Expected 2 results, got %d", len(rls)) - } + require.NoError(t, err, "Failed to query") + assert.Len(t, rls, 2, "Expected 2 results, got %d", len(rls)) _, err = cfgmaps.Query(map[string]string{"name": "notExist"}) - if !errors.Is(err, ErrReleaseNotFound) { - t.Errorf("Expected {%v}, got {%v}", ErrReleaseNotFound, err) - } + assert.ErrorIs(t, err, ErrReleaseNotFound) } func TestConfigMapCreate(t *testing.T) { @@ -195,20 +160,14 @@ func TestConfigMapCreate(t *testing.T) { rel := releaseStub(name, vers, namespace, common.StatusDeployed) // store the release in a configmap - if err := cfgmaps.Create(key, rel); err != nil { - t.Fatalf("Failed to create release with key %q: %s", key, err) - } + require.NoErrorf(t, cfgmaps.Create(key, rel), "Failed to create release with key %q", key) // get the release back got, err := cfgmaps.Get(key) - if err != nil { - t.Fatalf("Failed to get release with key %q: %s", key, err) - } + require.NoError(t, err, "Failed to get release with key %q", key) // compare created release with original - if !reflect.DeepEqual(rel, got) { - t.Errorf("Expected {%v}, got {%v}", rel, got) - } + assert.Truef(t, reflect.DeepEqual(rel, got), "Expected {%v}, got {%v}", rel, got) } func TestConfigMapUpdate(t *testing.T) { @@ -224,21 +183,15 @@ func TestConfigMapUpdate(t *testing.T) { rel.Info.Status = common.StatusSuperseded // perform the update - if err := cfgmaps.Update(key, rel); err != nil { - t.Fatalf("Failed to update release: %s", err) - } + require.NoErrorf(t, cfgmaps.Update(key, rel), "Failed to update release") // fetch the updated release goti, err := cfgmaps.Get(key) - if err != nil { - t.Fatalf("Failed to get release with key %q: %s", key, err) - } + require.NoError(t, err, "Failed to get release with key %q", key) got := convertReleaserToV1(t, goti) // check release has actually been updated by comparing modified fields - if rel.Info.Status != got.Info.Status { - t.Errorf("Expected status %s, got status %s", rel.Info.Status.String(), got.Info.Status.String()) - } + assert.Equal(t, got.Info.Status, rel.Info.Status, "Expected status %s, got status %s", rel.Info.Status.String(), got.Info.Status.String()) } func TestConfigMapDelete(t *testing.T) { @@ -252,20 +205,12 @@ func TestConfigMapDelete(t *testing.T) { // perform the delete on a non-existent release _, err := cfgmaps.Delete("nonexistent") - if !errors.Is(err, ErrReleaseNotFound) { - t.Fatalf("Expected ErrReleaseNotFound: got {%v}", err) - } + require.ErrorIs(t, err, ErrReleaseNotFound) // perform the delete rls, err := cfgmaps.Delete(key) - if err != nil { - t.Fatalf("Failed to delete release with key %q: %s", key, err) - } - if !reflect.DeepEqual(rel, rls) { - t.Errorf("Expected {%v}, got {%v}", rel, rls) - } + require.NoError(t, err, "Failed to delete release with key %q", key) + assert.Truef(t, reflect.DeepEqual(rel, rls), "Expected {%v}, got {%v}", rel, rls) _, err = cfgmaps.Get(key) - if !errors.Is(err, ErrReleaseNotFound) { - t.Errorf("Expected {%v}, got {%v}", ErrReleaseNotFound, err) - } + assert.ErrorIs(t, err, ErrReleaseNotFound) } From 13d1edc5f346e136b249d4c8232e83689f07c3b4 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 20:50:55 +0200 Subject: [PATCH 28/61] chore(pkg): refactor: convert tests to testify assert/require part 9 refactor: convert tests to testify assert/require in pkg/chart/common/util Signed-off-by: Matthieu MOREL --- pkg/chart/common/util/coalesce_test.go | 269 +++++++---------------- pkg/chart/common/util/jsonschema_test.go | 132 +++-------- pkg/cmd/completion_test.go | 6 +- 3 files changed, 116 insertions(+), 291 deletions(-) diff --git a/pkg/chart/common/util/coalesce_test.go b/pkg/chart/common/util/coalesce_test.go index d7f46a1da..6ef092365 100644 --- a/pkg/chart/common/util/coalesce_test.go +++ b/pkg/chart/common/util/coalesce_test.go @@ -141,9 +141,7 @@ func TestCoalesceValues(t *testing.T) { ) vals, err := common.ReadValues(testCoalesceValuesYaml) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) // taking a copy of the values before passing it // to CoalesceValues as argument, so that we can @@ -152,9 +150,7 @@ func TestCoalesceValues(t *testing.T) { maps.Copy(valsCopy, vals) v, err := CoalesceValues(c, vals) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) j, _ := json.MarshalIndent(v, "", " ") t.Logf("Coalesced Values: %s", string(j)) @@ -211,32 +207,26 @@ func TestCoalesceValues(t *testing.T) { nullKeys := []string{"bottom", "right", "left", "front"} for _, nullKey := range nullKeys { - if _, ok := v[nullKey]; ok { - t.Errorf("Expected key %q to be removed, still present", nullKey) - } + _, ok := v[nullKey] + assert.Falsef(t, ok, "Expected key %q to be removed, still present", nullKey) } - if _, ok := v["nested"].(map[string]any)["boat"]; ok { - t.Error("Expected nested boat key to be removed, still present") - } + _, ok := v["nested"].(map[string]any)["boat"] + assert.False(t, ok, "Expected nested boat key to be removed, still present") subchart := v["pequod"].(map[string]any) - if _, ok := subchart["boat"]; ok { - t.Error("Expected subchart boat key to be removed, still present") - } + _, ok = subchart["boat"] + assert.False(t, ok, "Expected subchart boat key to be removed, still present") subsubchart := subchart["ahab"].(map[string]any) - if _, ok := subsubchart["boat"]; ok { - t.Error("Expected sub-subchart ahab boat key to be removed, still present") - } + _, ok = subsubchart["boat"] + assert.False(t, ok, "Expected sub-subchart ahab boat key to be removed, still present") - if _, ok := subsubchart["nested"].(map[string]any)["boat"]; ok { - t.Error("Expected sub-subchart nested boat key to be removed, still present") - } + _, ok = subsubchart["nested"].(map[string]any)["boat"] + assert.False(t, ok, "Expected sub-subchart nested boat key to be removed, still present") - if _, ok := subsubchart["object"]; ok { - t.Error("Expected sub-subchart object map to be removed, still present") - } + _, ok = subsubchart["object"] + assert.False(t, ok, "Expected sub-subchart object map to be removed, still present") // CoalesceValues should not mutate the passed arguments is.Equal(valsCopy, vals) @@ -306,9 +296,7 @@ func TestMergeValues(t *testing.T) { ) vals, err := common.ReadValues(testCoalesceValuesYaml) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) // taking a copy of the values before passing it // to MergeValues as argument, so that we can @@ -317,9 +305,7 @@ func TestMergeValues(t *testing.T) { maps.Copy(valsCopy, vals) v, err := MergeValues(c, vals) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) j, _ := json.MarshalIndent(v, "", " ") t.Logf("Coalesced Values: %s", string(j)) @@ -377,25 +363,20 @@ func TestMergeValues(t *testing.T) { // removed. nullKeys := []string{"bottom", "right", "left", "front"} for _, nullKey := range nullKeys { - if vv, ok := v[nullKey]; !ok { - t.Errorf("Expected key %q to be present but it was removed", nullKey) - } else if vv != nil { - t.Errorf("Expected key %q to be null but it has a value of %v", nullKey, vv) - } + vv, ok := v[nullKey] + assert.Truef(t, ok, "Expected key %q to be present but it was removed", nullKey) + assert.Nilf(t, vv, "Expected key %q to be null but it has a value of %v", nullKey, vv) } - if _, ok := v["nested"].(map[string]any)["boat"]; !ok { - t.Error("Expected nested boat key to be present but it was removed") - } + _, ok := v["nested"].(map[string]any)["boat"] + assert.True(t, ok, "Expected nested boat key to be present but it was removed") subchart := v["pequod"].(map[string]any)["ahab"].(map[string]any) - if _, ok := subchart["boat"]; !ok { - t.Error("Expected subchart boat key to be present but it was removed") - } + _, ok = subchart["boat"] + assert.True(t, ok, "Expected subchart boat key to be present but it was removed") - if _, ok := subchart["nested"].(map[string]any)["bar"]; !ok { - t.Error("Expected subchart nested bar key to be present but it was removed") - } + _, ok = subchart["nested"].(map[string]any)["bar"] + assert.True(t, ok, "Expected subchart nested bar key to be present but it was removed") // CoalesceValues should not mutate the passed arguments is.Equal(valsCopy, vals) @@ -433,47 +414,27 @@ func TestCoalesceTables(t *testing.T) { // otherwise the values are coalesced. CoalesceTables(dst, src) - if dst["name"] != "Ishmael" { - t.Errorf("Unexpected name: %s", dst["name"]) - } - if dst["occupation"] != "whaler" { - t.Errorf("Unexpected occupation: %s", dst["occupation"]) - } + assert.Equal(t, "Ishmael", dst["name"], "Unexpected name: %s", dst["name"]) + assert.Equal(t, "whaler", dst["occupation"], "Unexpected occupation: %s", dst["occupation"]) addr, ok := dst["address"].(map[string]any) - if !ok { - t.Fatal("Address went away.") - } - - if addr["street"].(string) != "123 Spouter Inn Ct." { - t.Errorf("Unexpected address: %v", addr["street"]) - } + require.True(t, ok, "Address went away.") + assert.Equal(t, "123 Spouter Inn Ct.", addr["street"].(string), "Unexpected address: %v", addr["street"]) + assert.Equal(t, "Nantucket", addr["city"].(string), "Unexpected city: %v", addr["city"]) + assert.Equal(t, "MA", addr["state"].(string), "Unexpected state: %v", addr["state"]) - if addr["city"].(string) != "Nantucket" { - t.Errorf("Unexpected city: %v", addr["city"]) - } + _, ok = addr["country"] + assert.False(t, ok, "The country is not left out.") - if addr["state"].(string) != "MA" { - t.Errorf("Unexpected state: %v", addr["state"]) - } + det, ok := dst["details"].(map[string]any) + require.Truef(t, ok, "Details is the wrong type: %v", dst["details"]) - if _, ok = addr["country"]; ok { - t.Error("The country is not left out.") - } + _, ok = det["friends"] + assert.True(t, ok, "Could not find your friends. Maybe you don't have any. :-(") + assert.Equal(t, "pequod", dst["boat"].(string), "Expected boat string, got %v", dst["boat"]) - if det, ok := dst["details"].(map[string]any); !ok { - t.Fatalf("Details is the wrong type: %v", dst["details"]) - } else if _, ok := det["friends"]; !ok { - t.Error("Could not find your friends. Maybe you don't have any. :-(") - } - - if dst["boat"].(string) != "pequod" { - t.Errorf("Expected boat string, got %v", dst["boat"]) - } - - if _, ok = dst["hole"]; ok { - t.Error("The hole still exists.") - } + _, ok = dst["hole"] + assert.False(t, ok, "The hole still exists.") dst2 := map[string]any{ "name": "Ishmael", @@ -493,40 +454,21 @@ func TestCoalesceTables(t *testing.T) { // this happens when the --reuse-values flag is set but the chart has no modifications yet CoalesceTables(dst2, nil) - if dst2["name"] != "Ishmael" { - t.Errorf("Unexpected name: %s", dst2["name"]) - } + assert.Equal(t, "Ishmael", dst2["name"], "Unexpected name: %s", dst2["name"]) addr2, ok := dst2["address"].(map[string]any) - if !ok { - t.Fatal("Address went away.") - } - - if addr2["street"].(string) != "123 Spouter Inn Ct." { - t.Errorf("Unexpected address: %v", addr2["street"]) - } - - if addr2["city"].(string) != "Nantucket" { - t.Errorf("Unexpected city: %v", addr2["city"]) - } - - if addr2["country"].(string) != "US" { - t.Errorf("Unexpected Country: %v", addr2["country"]) - } - - if det2, ok := dst2["details"].(map[string]any); !ok { - t.Fatalf("Details is the wrong type: %v", dst2["details"]) - } else if _, ok := det2["friends"]; !ok { - t.Error("Could not find your friends. Maybe you don't have any. :-(") - } - - if dst2["boat"].(string) != "pequod" { - t.Errorf("Expected boat string, got %v", dst2["boat"]) - } - - if dst2["hole"].(string) != "black" { - t.Errorf("Expected hole string, got %v", dst2["boat"]) - } + require.True(t, ok, "Address went away.") + assert.Equal(t, "123 Spouter Inn Ct.", addr2["street"].(string), "Unexpected address: %v", addr2["street"]) + assert.Equal(t, "Nantucket", addr2["city"].(string), "Unexpected city: %v", addr2["city"]) + assert.Equal(t, "US", addr2["country"].(string), "Unexpected Country: %v", addr2["country"]) + + det2, ok := dst2["details"].(map[string]any) + require.Truef(t, ok, "Details is the wrong type: %v", dst2["details"]) + + _, ok = det2["friends"] + assert.True(t, ok, "Could not find your friends. Maybe you don't have any. :-(") + assert.Equal(t, "pequod", dst2["boat"].(string), "Expected boat string, got %v", dst2["boat"]) + assert.Equal(t, "black", dst2["hole"].(string), "Expected hole string, got %v", dst2["boat"]) } func TestMergeTables(t *testing.T) { @@ -561,51 +503,31 @@ func TestMergeTables(t *testing.T) { // otherwise the values are coalesced. MergeTables(dst, src) - if dst["name"] != "Ishmael" { - t.Errorf("Unexpected name: %s", dst["name"]) - } - if dst["occupation"] != "whaler" { - t.Errorf("Unexpected occupation: %s", dst["occupation"]) - } + assert.Equal(t, "Ishmael", dst["name"], "Unexpected name: %s", dst["name"]) + assert.Equal(t, "whaler", dst["occupation"], "Unexpected occupation: %s", dst["occupation"]) addr, ok := dst["address"].(map[string]any) - if !ok { - t.Fatal("Address went away.") - } - - if addr["street"].(string) != "123 Spouter Inn Ct." { - t.Errorf("Unexpected address: %v", addr["street"]) - } - - if addr["city"].(string) != "Nantucket" { - t.Errorf("Unexpected city: %v", addr["city"]) - } - - if addr["state"].(string) != "MA" { - t.Errorf("Unexpected state: %v", addr["state"]) - } + require.True(t, ok, "Address went away.") + assert.Equal(t, "123 Spouter Inn Ct.", addr["street"].(string), "Unexpected address: %v", addr["street"]) + assert.Equal(t, "Nantucket", addr["city"].(string), "Unexpected city: %v", addr["city"]) + assert.Equal(t, "MA", addr["state"].(string), "Unexpected state: %v", addr["state"]) // This is one test that is different from CoalesceTables. Because country // is a nil value and it's not removed it's still present. - if _, ok = addr["country"]; !ok { - t.Error("The country is left out.") - } + _, ok = addr["country"] + assert.True(t, ok, "The country is left out.") - if det, ok := dst["details"].(map[string]any); !ok { - t.Fatalf("Details is the wrong type: %v", dst["details"]) - } else if _, ok := det["friends"]; !ok { - t.Error("Could not find your friends. Maybe you don't have any. :-(") - } + det, ok := dst["details"].(map[string]any) + require.Truef(t, ok, "Details is the wrong type: %v", dst["details"]) - if dst["boat"].(string) != "pequod" { - t.Errorf("Expected boat string, got %v", dst["boat"]) - } + _, ok = det["friends"] + assert.True(t, ok, "Could not find your friends. Maybe you don't have any. :-(") + assert.Equal(t, "pequod", dst["boat"].(string), "Expected boat string, got %v", dst["boat"]) // This is one test that is different from CoalesceTables. Because hole // is a nil value and it's not removed it's still present. - if _, ok = dst["hole"]; !ok { - t.Error("The hole no longer exists.") - } + _, ok = dst["hole"] + assert.True(t, ok, "The hole no longer exists.") dst2 := map[string]any{ "name": "Ishmael", @@ -626,44 +548,22 @@ func TestMergeTables(t *testing.T) { // this happens when the --reuse-values flag is set but the chart has no modifications yet MergeTables(dst2, nil) - if dst2["name"] != "Ishmael" { - t.Errorf("Unexpected name: %s", dst2["name"]) - } + assert.Equal(t, "Ishmael", dst2["name"], "Unexpected name: %s", dst2["name"]) addr2, ok := dst2["address"].(map[string]any) - if !ok { - t.Fatal("Address went away.") - } - - if addr2["street"].(string) != "123 Spouter Inn Ct." { - t.Errorf("Unexpected address: %v", addr2["street"]) - } - - if addr2["city"].(string) != "Nantucket" { - t.Errorf("Unexpected city: %v", addr2["city"]) - } - - if addr2["country"].(string) != "US" { - t.Errorf("Unexpected Country: %v", addr2["country"]) - } - - if det2, ok := dst2["details"].(map[string]any); !ok { - t.Fatalf("Details is the wrong type: %v", dst2["details"]) - } else if _, ok := det2["friends"]; !ok { - t.Error("Could not find your friends. Maybe you don't have any. :-(") - } - - if dst2["boat"].(string) != "pequod" { - t.Errorf("Expected boat string, got %v", dst2["boat"]) - } - - if dst2["hole"].(string) != "black" { - t.Errorf("Expected hole string, got %v", dst2["boat"]) - } - - if dst2["nilval"] != nil { - t.Error("Expected nilvalue to have nil value but it does not") - } + require.True(t, ok, "Address went away.") + assert.Equal(t, "123 Spouter Inn Ct.", addr2["street"].(string), "Unexpected address: %v", addr2["street"]) + assert.Equal(t, "Nantucket", addr2["city"].(string), "Unexpected city: %v", addr2["city"]) + assert.Equal(t, "US", addr2["country"].(string), "Unexpected Country: %v", addr2["country"]) + + det2, ok := dst2["details"].(map[string]any) + require.Truef(t, ok, "Details is the wrong type: %v", dst2["details"]) + + _, ok = det2["friends"] + assert.True(t, ok, "Could not find your friends. Maybe you don't have any. :-(") + assert.Equal(t, "pequod", dst2["boat"].(string), "Expected boat string, got %v", dst2["boat"]) + assert.Equal(t, "black", dst2["hole"].(string), "Expected hole string, got %v", dst2["hole"]) + assert.Nil(t, dst2["nilval"], "Expected nilvalue to have nil value but it does not") } func TestCoalesceValuesWarnings(t *testing.T) { @@ -716,9 +616,7 @@ func TestCoalesceValuesWarnings(t *testing.T) { } _, err := coalesce(printf, c, vals, "", false) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) t.Logf("vals: %v", vals) assert.Contains(t, warnings, "warning: skipped value for level1.level2.level3.boat: Not a table.") @@ -926,7 +824,6 @@ func TestCoalesceValuesSubchartNilCleanedWhenUserPartiallyOverrides(t *testing.T keyMapping, ok := childVals["keyMapping"].(map[string]any) is.True(ok, "keyMapping should be a map") - is.Equal("sha256", keyMapping["format"], "User override should be preserved") _, ok = keyMapping["password"] diff --git a/pkg/chart/common/util/jsonschema_test.go b/pkg/chart/common/util/jsonschema_test.go index 838d152a1..90fdc9b11 100644 --- a/pkg/chart/common/util/jsonschema_test.go +++ b/pkg/chart/common/util/jsonschema_test.go @@ -20,75 +20,47 @@ import ( "net/http" "net/http/httptest" "os" - "strings" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "helm.sh/helm/v4/pkg/chart/common" chart "helm.sh/helm/v4/pkg/chart/v2" ) func TestValidateAgainstSingleSchema(t *testing.T) { values, err := common.ReadValuesFile("./testdata/test-values.yaml") - if err != nil { - t.Fatalf("Error reading YAML file: %s", err) - } - schema, err := os.ReadFile("./testdata/test-values.schema.json") - if err != nil { - t.Fatalf("Error reading YAML file: %s", err) - } + require.NoError(t, err, "Error reading YAML file") - if err := ValidateAgainstSingleSchema(values, schema); err != nil { - t.Errorf("Error validating Values against Schema: %s", err) - } + schema, err := os.ReadFile("./testdata/test-values.schema.json") + require.NoError(t, err, "Error reading YAML file") + assert.NoErrorf(t, ValidateAgainstSingleSchema(values, schema), "Error validating Values against Schema") } func TestValidateAgainstInvalidSingleSchema(t *testing.T) { values, err := common.ReadValuesFile("./testdata/test-values.yaml") - if err != nil { - t.Fatalf("Error reading YAML file: %s", err) - } - schema, err := os.ReadFile("./testdata/test-values-invalid.schema.json") - if err != nil { - t.Fatalf("Error reading YAML file: %s", err) - } + require.NoError(t, err, "Error reading YAML file") - var errString string - if err := ValidateAgainstSingleSchema(values, schema); err == nil { - t.Fatal("Expected an error, but got nil") - } else { - errString = err.Error() - } + schema, err := os.ReadFile("./testdata/test-values-invalid.schema.json") + require.NoError(t, err, "Error reading YAML file") expectedErrString := `"file:///values.schema.json#" is not valid against metaschema: jsonschema validation failed with 'https://json-schema.org/draft/2020-12/schema#' - at '': got number, want boolean or object` - if errString != expectedErrString { - t.Errorf("Error string :\n`%s`\ndoes not match expected\n`%s`", errString, expectedErrString) - } + assert.EqualError(t, ValidateAgainstSingleSchema(values, schema), expectedErrString) } func TestValidateAgainstSingleSchemaNegative(t *testing.T) { values, err := common.ReadValuesFile("./testdata/test-values-negative.yaml") - if err != nil { - t.Fatalf("Error reading YAML file: %s", err) - } - schema, err := os.ReadFile("./testdata/test-values.schema.json") - if err != nil { - t.Fatalf("Error reading JSON file: %s", err) - } + require.NoError(t, err, "Error reading YAML file") - var errString string - if err := ValidateAgainstSingleSchema(values, schema); err == nil { - t.Fatal("Expected an error, but got nil") - } else { - errString = err.Error() - } + schema, err := os.ReadFile("./testdata/test-values.schema.json") + require.NoError(t, err, "Error reading JSON file") expectedErrString := `- at '': missing property 'employmentInfo' - at '/age': minimum: got -5, want 0 ` - if errString != expectedErrString { - t.Errorf("Error string :\n`%s`\ndoes not match expected\n`%s`", errString, expectedErrString) - } + assert.EqualError(t, ValidateAgainstSingleSchema(values, schema), expectedErrString) } const subchartSchema = `{ @@ -145,9 +117,7 @@ func TestValidateAgainstSchema(t *testing.T) { }, } - if err := ValidateAgainstSchema(chrt, vals); err != nil { - t.Errorf("Error validating Values against Schema: %s", err) - } + assert.NoErrorf(t, ValidateAgainstSchema(chrt, vals), "Error validating Values against Schema") } func TestValidateAgainstSchemaNegative(t *testing.T) { @@ -170,19 +140,10 @@ func TestValidateAgainstSchemaNegative(t *testing.T) { "subchart": map[string]any{}, } - var errString string - if err := ValidateAgainstSchema(chrt, vals); err == nil { - t.Fatal("Expected an error, but got nil") - } else { - errString = err.Error() - } - expectedErrString := `subchart: - at '': missing property 'age' ` - if errString != expectedErrString { - t.Errorf("Error string :\n`%s`\ndoes not match expected\n`%s`", errString, expectedErrString) - } + assert.EqualError(t, ValidateAgainstSchema(chrt, vals), expectedErrString) } func TestValidateAgainstSchema2020(t *testing.T) { @@ -207,9 +168,7 @@ func TestValidateAgainstSchema2020(t *testing.T) { }, } - if err := ValidateAgainstSchema(chrt, vals); err != nil { - t.Errorf("Error validating Values against Schema: %s", err) - } + assert.NoErrorf(t, ValidateAgainstSchema(chrt, vals), "Error validating Values against Schema") } func TestValidateAgainstSchema2020Negative(t *testing.T) { @@ -234,20 +193,11 @@ func TestValidateAgainstSchema2020Negative(t *testing.T) { }, } - var errString string - if err := ValidateAgainstSchema(chrt, vals); err == nil { - t.Fatal("Expected an error, but got nil") - } else { - errString = err.Error() - } - expectedErrString := `subchart: - at '/data': no items match contains schema - at '/data/0': got number, want string ` - if errString != expectedErrString { - t.Errorf("Error string :\n`%s`\ndoes not match expected\n`%s`", errString, expectedErrString) - } + assert.EqualError(t, ValidateAgainstSchema(chrt, vals), expectedErrString) } func TestHTTPURLLoader_Load(t *testing.T) { @@ -262,12 +212,8 @@ func TestHTTPURLLoader_Load(t *testing.T) { loader := newHTTPURLLoader() result, err := loader.Load(server.URL) - if err != nil { - t.Fatalf("Expected no error, got: %v", err) - } - if result == nil { - t.Fatal("Expected result to be non-nil") - } + require.NoError(t, err, "Expected no error, got") + require.NotNil(t, result, "Expected result to be non-nil") }) t.Run("HTTP error status", func(t *testing.T) { @@ -278,12 +224,8 @@ func TestHTTPURLLoader_Load(t *testing.T) { loader := newHTTPURLLoader() _, err := loader.Load(server.URL) - if err == nil { - t.Fatal("Expected error for HTTP 404") - } - if !strings.Contains(err.Error(), "404") { - t.Errorf("Expected error message to contain '404', got: %v", err) - } + require.Error(t, err, "Expected error for HTTP 404") + assert.ErrorContains(t, err, "404", "Expected error message to contain '404'") }) } @@ -295,9 +237,7 @@ func TestValidateAgainstSingleSchema_UnresolvedURN_Ignored(t *testing.T) { "$ref": "urn:example:helm:schemas:v1:helm-schema-validation-conditions:v1/helmSchemaValidation-true" }`) vals := map[string]any{"any": "value"} - if err := ValidateAgainstSingleSchema(vals, schema); err != nil { - t.Fatalf("expected no error when URN unresolved is ignored, got: %v", err) - } + require.NoErrorf(t, ValidateAgainstSingleSchema(vals, schema), "expected no error when URN unresolved is ignored, got") } // Non-regression tests for https://github.com/helm/helm/issues/31202 @@ -323,14 +263,10 @@ func TestValidateAgainstSchema_MissingSubchartValues_NoPanic(t *testing.T) { } defer func() { - if r := recover(); r != nil { - t.Fatalf("ValidateAgainstSchema panicked (missing subchart values): %v", r) - } + require.Nilf(t, recover(), "ValidateAgainstSchema panicked (missing subchart values)") }() - if err := ValidateAgainstSchema(chrt, vals); err != nil { - t.Fatalf("expected no error when subchart values are missing, got: %v", err) - } + require.NoErrorf(t, ValidateAgainstSchema(chrt, vals), "expected no error when subchart values are missing, got") } func TestValidateAgainstSchema_SubchartNil_NoPanic(t *testing.T) { @@ -351,14 +287,10 @@ func TestValidateAgainstSchema_SubchartNil_NoPanic(t *testing.T) { } defer func() { - if r := recover(); r != nil { - t.Fatalf("ValidateAgainstSchema panicked (nil subchart values): %v", r) - } + require.Nilf(t, recover(), "ValidateAgainstSchema panicked (nil subchart values)") }() - if err := ValidateAgainstSchema(chrt, vals); err != nil { - t.Fatalf("expected no error when subchart values are nil, got: %v", err) - } + require.NoErrorf(t, ValidateAgainstSchema(chrt, vals), "expected no error when subchart values are nil, got") } func TestValidateAgainstSchema_InvalidSubchartValuesType_NoPanic(t *testing.T) { @@ -379,13 +311,9 @@ func TestValidateAgainstSchema_InvalidSubchartValuesType_NoPanic(t *testing.T) { } defer func() { - if r := recover(); r != nil { - t.Fatalf("ValidateAgainstSchema panicked (invalid subchart values type): %v", r) - } + require.Nilf(t, recover(), "ValidateAgainstSchema panicked (invalid subchart values type)") }() // We expect a non-nil error (invalid type), but crucially no panic. - if err := ValidateAgainstSchema(chrt, vals); err == nil { - t.Fatal("expected an error when subchart values have invalid type, got nil") - } + require.Error(t, ValidateAgainstSchema(chrt, vals), "expected an error when subchart values have invalid type, got nil") } diff --git a/pkg/cmd/completion_test.go b/pkg/cmd/completion_test.go index 399ff1f0c..219d1eed0 100644 --- a/pkg/cmd/completion_test.go +++ b/pkg/cmd/completion_test.go @@ -21,6 +21,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/require" + chart "helm.sh/helm/v4/pkg/chart/v2" "helm.sh/helm/v4/pkg/release/common" release "helm.sh/helm/v4/pkg/release/v1" @@ -44,9 +46,7 @@ func checkFileCompletion(t *testing.T, cmdName string, shouldBePerformed bool) { testcmd := fmt.Sprintf("__complete %s ''", cmdName) _, out, err := executeActionCommandC(storage, testcmd) - if err != nil { - t.Errorf("unexpected error, %s", err) - } + require.NoError(t, err) if !strings.Contains(out, "ShellCompDirectiveNoFileComp") != shouldBePerformed { if shouldBePerformed { t.Errorf("Unexpected directive ShellCompDirectiveNoFileComp when completing '%s'", cmdName) From 2f5a33fb77daca9ade910ed7fe557e3e85fd77f6 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 20:50:55 +0200 Subject: [PATCH 29/61] chore(pkg): refactor: convert tests to testify assert/require part 10 #### Description refactor: convert tests to testify assert/require in pkg Signed-off-by: Matthieu MOREL --- pkg/cmd/create_test.go | 155 +++++++---------------- pkg/storage/storage_test.go | 242 +++++++++++++----------------------- 2 files changed, 134 insertions(+), 263 deletions(-) diff --git a/pkg/cmd/create_test.go b/pkg/cmd/create_test.go index 1a1289775..6f25d4c63 100644 --- a/pkg/cmd/create_test.go +++ b/pkg/cmd/create_test.go @@ -22,6 +22,9 @@ import ( "slices" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + chartv3 "helm.sh/helm/v4/internal/chart/v3" chartutilv3 "helm.sh/helm/v4/internal/chart/v3/util" "helm.sh/helm/v4/internal/gates" @@ -39,38 +42,25 @@ func TestCreateCmd(t *testing.T) { cname := "testchart" // Run a create - if _, _, err := executeActionCommand("create " + cname); err != nil { - t.Fatalf("Failed to run create: %s", err) - } + _, _, err := executeActionCommand("create " + cname) + require.NoErrorf(t, err, "Failed to run create") // Test that the chart is there - if fi, err := os.Stat(cname); err != nil { - t.Fatalf("no chart directory: %s", err) - } else if !fi.IsDir() { - t.Fatal("chart is not directory") - } + fi, err := os.Stat(cname) + require.NoErrorf(t, err, "no chart directory") + require.Truef(t, fi.IsDir(), "chart is not directory") c, err := chartloader.LoadDir(cname) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) acc, err := chart.NewAccessor(c) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if acc.Name() != cname { - t.Errorf("Expected %q name, got %q", cname, acc.Name()) - } + assert.Equal(t, cname, acc.Name(), "Expected %q name, got %q", cname, acc.Name()) metadata := acc.MetadataAsMap() apiVersion, ok := metadata["APIVersion"].(string) - if !ok { - t.Fatal("APIVersion not found in metadata") - } - if apiVersion != chartv2.APIVersionV2 { - t.Errorf("Wrong API version: %q", apiVersion) - } + require.True(t, ok, "APIVersion not found in metadata") + assert.Equal(t, chartv2.APIVersionV2, apiVersion, "Wrong API version: %q", apiVersion) } func TestCreateStarterCmd(t *testing.T) { @@ -123,15 +113,11 @@ func TestCreateStarterCmd(t *testing.T) { } else { dest, err = chartutil.Create("starterchart", starterchart) } - if err != nil { - t.Fatalf("Could not create chart: %s", err) - } + require.NoError(t, err, "Could not create chart") t.Logf("Created %s", dest) tplpath := filepath.Join(starterchart, "starterchart", "templates", "foo.tpl") - if err := os.WriteFile(tplpath, []byte("test"), 0o644); err != nil { - t.Fatalf("Could not write template: %s", err) - } + require.NoErrorf(t, os.WriteFile(tplpath, []byte("test"), 0o644), "Could not write template") // Build the command starterArg := "starterchart" @@ -147,51 +133,36 @@ func TestCreateStarterCmd(t *testing.T) { cmd += " " + cname // Run create - if _, _, err := executeActionCommand(cmd); err != nil { - t.Fatalf("Failed to run create: %s", err) - } + _, _, err = executeActionCommand(cmd) + require.NoErrorf(t, err, "Failed to run create") // Test that the chart is there - if fi, err := os.Stat(cname); err != nil { - t.Fatalf("no chart directory: %s", err) - } else if !fi.IsDir() { - t.Fatal("chart is not directory") - } + fi, err := os.Stat(cname) + require.NoErrorf(t, err, "no chart directory") + require.Truef(t, fi.IsDir(), "chart is not directory") // Load and verify the chart c, err := chartloader.LoadDir(cname) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) acc, err := chart.NewAccessor(c) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) chartName := acc.Name() metadata := acc.MetadataAsMap() apiVersion, ok := metadata["APIVersion"].(string) - if !ok { - t.Fatal("APIVersion not found in metadata") - } + require.True(t, ok, "APIVersion not found in metadata") var templates []string for _, tpl := range acc.Templates() { templates = append(templates, tpl.Name) } - if chartName != cname { - t.Errorf("Expected %q name, got %q", cname, chartName) - } - if apiVersion != tt.expectedVersion { - t.Errorf("Wrong API version: expected %q, got %q", tt.expectedVersion, apiVersion) - } + assert.Equal(t, cname, chartName, "Expected %q name, got %q", cname, chartName) + assert.Equal(t, tt.expectedVersion, apiVersion, "Wrong API version: expected %q, got %q", tt.expectedVersion, apiVersion) // Verify custom template exists found := slices.Contains(templates, "templates/foo.tpl") - if !found { - t.Error("Did not find foo.tpl") - } + assert.True(t, found, "Did not find foo.tpl") }) } } @@ -207,38 +178,25 @@ func TestCreateCmdChartAPIVersionV2(t *testing.T) { cname := "testchart" // Run a create with explicit v2 - if _, _, err := executeActionCommand("create --chart-api-version=v2 " + cname); err != nil { - t.Fatalf("Failed to run create: %s", err) - } + _, _, err := executeActionCommand("create --chart-api-version=v2 " + cname) + require.NoErrorf(t, err, "Failed to run create") // Test that the chart is there - if fi, err := os.Stat(cname); err != nil { - t.Fatalf("no chart directory: %s", err) - } else if !fi.IsDir() { - t.Fatal("chart is not directory") - } + fi, err := os.Stat(cname) + require.NoErrorf(t, err, "no chart directory") + require.Truef(t, fi.IsDir(), "chart is not directory") c, err := chartloader.LoadDir(cname) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) acc, err := chart.NewAccessor(c) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if acc.Name() != cname { - t.Errorf("Expected %q name, got %q", cname, acc.Name()) - } + assert.Equal(t, cname, acc.Name(), "Expected %q name, got %q", cname, acc.Name()) metadata := acc.MetadataAsMap() apiVersion, ok := metadata["APIVersion"].(string) - if !ok { - t.Fatal("APIVersion not found in metadata") - } - if apiVersion != chartv2.APIVersionV2 { - t.Errorf("Wrong API version: expected %q, got %q", chartv2.APIVersionV2, apiVersion) - } + require.True(t, ok, "APIVersion not found in metadata") + assert.Equal(t, chartv2.APIVersionV2, apiVersion, "Wrong API version: expected %q, got %q", chartv2.APIVersionV2, apiVersion) } func TestCreateCmdChartAPIVersionV3(t *testing.T) { @@ -248,38 +206,25 @@ func TestCreateCmdChartAPIVersionV3(t *testing.T) { cname := "testchart" // Run a create with v3 - if _, _, err := executeActionCommand("create --chart-api-version=v3 " + cname); err != nil { - t.Fatalf("Failed to run create: %s", err) - } + _, _, err := executeActionCommand("create --chart-api-version=v3 " + cname) + require.NoErrorf(t, err, "Failed to run create") // Test that the chart is there - if fi, err := os.Stat(cname); err != nil { - t.Fatalf("no chart directory: %s", err) - } else if !fi.IsDir() { - t.Fatal("chart is not directory") - } + fi, err := os.Stat(cname) + require.NoErrorf(t, err, "no chart directory") + require.Truef(t, fi.IsDir(), "chart is not directory") c, err := chartloader.LoadDir(cname) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) acc, err := chart.NewAccessor(c) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if acc.Name() != cname { - t.Errorf("Expected %q name, got %q", cname, acc.Name()) - } + assert.Equal(t, cname, acc.Name(), "Expected %q name, got %q", cname, acc.Name()) metadata := acc.MetadataAsMap() apiVersion, ok := metadata["APIVersion"].(string) - if !ok { - t.Fatal("APIVersion not found in metadata") - } - if apiVersion != chartv3.APIVersionV3 { - t.Errorf("Wrong API version: expected %q, got %q", chartv3.APIVersionV3, apiVersion) - } + require.True(t, ok, "APIVersion not found in metadata") + assert.Equal(t, chartv3.APIVersionV3, apiVersion, "Wrong API version: expected %q, got %q", chartv3.APIVersionV3, apiVersion) } func TestCreateCmdInvalidChartAPIVersion(t *testing.T) { @@ -289,12 +234,8 @@ func TestCreateCmdInvalidChartAPIVersion(t *testing.T) { // Run a create with invalid version _, _, err := executeActionCommand("create --chart-api-version=v1 " + cname) - if err == nil { - t.Fatal("Expected error for invalid API version, got nil") - } + require.Error(t, err, "Expected error for invalid API version, got nil") expectedErr := "unsupported chart API version: v1 (supported: v2, v3)" - if err.Error() != expectedErr { - t.Errorf("Expected error %q, got %q", expectedErr, err.Error()) - } + assert.EqualError(t, err, expectedErr, "Expected error %q, got %q", expectedErr, err.Error()) } diff --git a/pkg/storage/storage_test.go b/pkg/storage/storage_test.go index 8ecee447f..821eccb81 100644 --- a/pkg/storage/storage_test.go +++ b/pkg/storage/storage_test.go @@ -19,11 +19,11 @@ package storage import ( "context" "errors" - "fmt" "log/slog" "reflect" "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "helm.sh/helm/v4/pkg/release" @@ -42,16 +42,14 @@ func TestStorageCreate(t *testing.T) { Version: 1, }.ToRelease() - assertErrNil(t.Fatal, storage.Create(rls), "StoreRelease") + require.NoError(t, storage.Create(rls), "StoreRelease") // fetch the release res, err := storage.Get(rls.Name, rls.Version) - assertErrNil(t.Fatal, err, "QueryRelease") + require.NoError(t, err, "QueryRelease") // verify the fetched and created release are the same - if !reflect.DeepEqual(rls, res) { - t.Fatalf("Expected %v, got %v", rls, res) - } + require.Truef(t, reflect.DeepEqual(rls, res), "Expected %v, got %v", rls, res) } func TestStorageUpdate(t *testing.T) { @@ -65,20 +63,18 @@ func TestStorageUpdate(t *testing.T) { Status: common.StatusDeployed, }.ToRelease() - assertErrNil(t.Fatal, storage.Create(rls), "StoreRelease") + require.NoError(t, storage.Create(rls), "StoreRelease") // modify the release rls.Info.Status = common.StatusUninstalled - assertErrNil(t.Fatal, storage.Update(rls), "UpdateRelease") + require.NoError(t, storage.Update(rls), "UpdateRelease") // retrieve the updated release res, err := storage.Get(rls.Name, rls.Version) - assertErrNil(t.Fatal, err, "QueryRelease") + require.NoError(t, err, "QueryRelease") // verify updated and fetched releases are the same. - if !reflect.DeepEqual(rls, res) { - t.Fatalf("Expected %v, got %v", rls, res) - } + require.Truef(t, reflect.DeepEqual(rls, res), "Expected %v, got %v", rls, res) } func TestStorageDelete(t *testing.T) { @@ -95,34 +91,26 @@ func TestStorageDelete(t *testing.T) { Version: 2, }.ToRelease() - assertErrNil(t.Fatal, storage.Create(rls), "StoreRelease") - assertErrNil(t.Fatal, storage.Create(rls2), "StoreRelease") + require.NoError(t, storage.Create(rls), "StoreRelease") + require.NoError(t, storage.Create(rls2), "StoreRelease") // delete the release res, err := storage.Delete(rls.Name, rls.Version) - assertErrNil(t.Fatal, err, "DeleteRelease") + require.NoError(t, err, "DeleteRelease") // verify updated and fetched releases are the same. - if !reflect.DeepEqual(rls, res) { - t.Fatalf("Expected %v, got %v", rls, res) - } + require.Truef(t, reflect.DeepEqual(rls, res), "Expected %v, got %v", rls, res) hist, err := storage.History(rls.Name) - if err != nil { - t.Errorf("unexpected error: %s", err) - } + require.NoError(t, err) rhist, err := releaseListToV1List(hist) require.NoError(t, err) // We have now deleted one of the two records. - if len(rhist) != 1 { - t.Errorf("expected 1 record for deleted release version, got %d", len(hist)) - } + assert.Len(t, rhist, 1, "expected 1 record for deleted release version, got %d", len(hist)) - if rhist[0].Version != 2 { - t.Errorf("Expected version to be 2, got %d", rhist[0].Version) - } + assert.Equal(t, 2, rhist[0].Version, "Expected version to be 2, got %d", rhist[0].Version) } func TestStorageList(t *testing.T) { @@ -141,13 +129,13 @@ func TestStorageList(t *testing.T) { rls6 := ReleaseTestData{Name: "happy-liger", Status: common.StatusUninstalled}.ToRelease() // create the release records in the storage - assertErrNil(t.Fatal, storage.Create(rls0), "Storing release 'rls0'") - assertErrNil(t.Fatal, storage.Create(rls1), "Storing release 'rls1'") - assertErrNil(t.Fatal, storage.Create(rls2), "Storing release 'rls2'") - assertErrNil(t.Fatal, storage.Create(rls3), "Storing release 'rls3'") - assertErrNil(t.Fatal, storage.Create(rls4), "Storing release 'rls4'") - assertErrNil(t.Fatal, storage.Create(rls5), "Storing release 'rls5'") - assertErrNil(t.Fatal, storage.Create(rls6), "Storing release 'rls6'") + require.NoError(t, storage.Create(rls0), "Storing release 'rls0'") + require.NoError(t, storage.Create(rls1), "Storing release 'rls1'") + require.NoError(t, storage.Create(rls2), "Storing release 'rls2'") + require.NoError(t, storage.Create(rls3), "Storing release 'rls3'") + require.NoError(t, storage.Create(rls4), "Storing release 'rls4'") + require.NoError(t, storage.Create(rls5), "Storing release 'rls5'") + require.NoError(t, storage.Create(rls6), "Storing release 'rls6'") } var listTests = []struct { @@ -164,14 +152,9 @@ func TestStorageList(t *testing.T) { for _, tt := range listTests { list, err := tt.ListFunc() - assertErrNil(t.Fatal, err, tt.Description) + require.NoError(t, err, tt.Description) // verify the count of releases returned - if len(list) != tt.NumExpected { - t.Errorf("ListReleases(%s): expected %d, actual %d", - tt.Description, - tt.NumExpected, - len(list)) - } + assert.Len(t, list, tt.NumExpected, "ListReleases(%s): expected %d, actual %d", tt.Description, tt.NumExpected, len(list)) } } @@ -190,32 +173,24 @@ func TestStorageDeployed(t *testing.T) { rls3 := ReleaseTestData{Name: name, Version: 4, Status: common.StatusDeployed}.ToRelease() // create the release records in the storage - assertErrNil(t.Fatal, storage.Create(rls0), "Storing release 'angry-bird' (v1)") - assertErrNil(t.Fatal, storage.Create(rls1), "Storing release 'angry-bird' (v2)") - assertErrNil(t.Fatal, storage.Create(rls2), "Storing release 'angry-bird' (v3)") - assertErrNil(t.Fatal, storage.Create(rls3), "Storing release 'angry-bird' (v4)") + require.NoError(t, storage.Create(rls0), "Storing release 'angry-bird' (v1)") + require.NoError(t, storage.Create(rls1), "Storing release 'angry-bird' (v2)") + require.NoError(t, storage.Create(rls2), "Storing release 'angry-bird' (v3)") + require.NoError(t, storage.Create(rls3), "Storing release 'angry-bird' (v4)") } setup() rls, err := storage.Last(name) - if err != nil { - t.Fatalf("Failed to query for deployed release: %s\n", err) - } + require.NoError(t, err, "Failed to query for deployed release") rel, err := releaserToV1Release(rls) require.NoError(t, err) - switch { - case rls == nil: - t.Fatal("Release is nil") - case rel.Name != name: - t.Fatalf("Expected release name %q, actual %q\n", name, rel.Name) - case rel.Version != vers: - t.Fatalf("Expected release version %d, actual %d\n", vers, rel.Version) - case rel.Info.Status != common.StatusDeployed: - t.Fatalf("Expected release status 'DEPLOYED', actual %s\n", rel.Info.Status.String()) - } + require.NotNil(t, rls, "Release is nil") + require.Equal(t, name, rel.Name, "Expected release name %q, actual %q\n", name, rel.Name) + require.Equal(t, vers, rel.Version, "Expected release version %d, actual %d\n", vers, rel.Version) + require.Equal(t, common.StatusDeployed, rel.Info.Status, "Expected release status 'DEPLOYED', actual %s\n", rel.Info.Status.String()) } func TestStorageDeployedWithCorruption(t *testing.T) { @@ -233,32 +208,24 @@ func TestStorageDeployedWithCorruption(t *testing.T) { rls3 := ReleaseTestData{Name: name, Version: 2, Status: common.StatusDeployed}.ToRelease() // create the release records in the storage - assertErrNil(t.Fatal, storage.Create(rls0), "Storing release 'angry-bird' (v1)") - assertErrNil(t.Fatal, storage.Create(rls1), "Storing release 'angry-bird' (v2)") - assertErrNil(t.Fatal, storage.Create(rls2), "Storing release 'angry-bird' (v3)") - assertErrNil(t.Fatal, storage.Create(rls3), "Storing release 'angry-bird' (v4)") + require.NoError(t, storage.Create(rls0), "Storing release 'angry-bird' (v1)") + require.NoError(t, storage.Create(rls1), "Storing release 'angry-bird' (v2)") + require.NoError(t, storage.Create(rls2), "Storing release 'angry-bird' (v3)") + require.NoError(t, storage.Create(rls3), "Storing release 'angry-bird' (v4)") } setup() rls, err := storage.Deployed(name) - if err != nil { - t.Fatalf("Failed to query for deployed release: %s\n", err) - } + require.NoError(t, err, "Failed to query for deployed release") rel, err := releaserToV1Release(rls) require.NoError(t, err) - switch { - case rls == nil: - t.Fatal("Release is nil") - case rel.Name != name: - t.Fatalf("Expected release name %q, actual %q\n", name, rel.Name) - case rel.Version != vers: - t.Fatalf("Expected release version %d, actual %d\n", vers, rel.Version) - case rel.Info.Status != common.StatusDeployed: - t.Fatalf("Expected release status 'DEPLOYED', actual %s\n", rel.Info.Status.String()) - } + require.NotNil(t, rls, "Release is nil") + require.Equal(t, name, rel.Name, "Expected release name %q, actual %q\n", name, rel.Name) + require.Equal(t, vers, rel.Version, "Expected release version %d, actual %d\n", vers, rel.Version) + require.Equal(t, common.StatusDeployed, rel.Info.Status, "Expected release status 'DEPLOYED', actual %s\n", rel.Info.Status.String()) } func TestStorageHistory(t *testing.T) { @@ -275,21 +242,17 @@ func TestStorageHistory(t *testing.T) { rls3 := ReleaseTestData{Name: name, Version: 4, Status: common.StatusDeployed}.ToRelease() // create the release records in the storage - assertErrNil(t.Fatal, storage.Create(rls0), "Storing release 'angry-bird' (v1)") - assertErrNil(t.Fatal, storage.Create(rls1), "Storing release 'angry-bird' (v2)") - assertErrNil(t.Fatal, storage.Create(rls2), "Storing release 'angry-bird' (v3)") - assertErrNil(t.Fatal, storage.Create(rls3), "Storing release 'angry-bird' (v4)") + require.NoError(t, storage.Create(rls0), "Storing release 'angry-bird' (v1)") + require.NoError(t, storage.Create(rls1), "Storing release 'angry-bird' (v2)") + require.NoError(t, storage.Create(rls2), "Storing release 'angry-bird' (v3)") + require.NoError(t, storage.Create(rls3), "Storing release 'angry-bird' (v4)") } setup() h, err := storage.History(name) - if err != nil { - t.Fatalf("Failed to query for release history (%q): %s\n", name, err) - } - if len(h) != 4 { - t.Fatalf("Release history (%q) is empty\n", name) - } + require.NoError(t, err, "Failed to query for release history (%q)", name) + require.Len(t, h, 4, "Release history (%q) is empty\n", name) } var errMaxHistoryMockDriverSomethingHappened = errors.New("something happened") @@ -336,16 +299,14 @@ func TestMaxHistoryErrorHandling(t *testing.T) { rls1 := ReleaseTestData{Name: name, Version: 1, Status: common.StatusSuperseded}.ToRelease() // create the release records in the storage - assertErrNil(t.Fatal, storage.Driver.Create(makeKey(rls1.Name, rls1.Version), rls1), "Storing release 'angry-bird' (v1)") + require.NoError(t, storage.Driver.Create(makeKey(rls1.Name, rls1.Version), rls1), "Storing release 'angry-bird' (v1)") } setup() rls2 := ReleaseTestData{Name: name, Version: 2, Status: common.StatusSuperseded}.ToRelease() wantErr := errMaxHistoryMockDriverSomethingHappened gotErr := storage.Create(rls2) - if !errors.Is(gotErr, wantErr) { - t.Fatalf("Storing release 'angry-bird' (v2) should return the error %#v, but returned %#v", wantErr, gotErr) - } + require.ErrorIs(t, gotErr, wantErr, "Storing release 'angry-bird' (v2) should return the error %#v, but returned %#v", wantErr, gotErr) } func TestStorageRemoveLeastRecent(t *testing.T) { @@ -365,27 +326,25 @@ func TestStorageRemoveLeastRecent(t *testing.T) { rls3 := ReleaseTestData{Name: name, Version: 4, Status: common.StatusDeployed}.ToRelease() // create the release records in the storage - assertErrNil(t.Fatal, storage.Create(rls0), "Storing release 'angry-bird' (v1)") - assertErrNil(t.Fatal, storage.Create(rls1), "Storing release 'angry-bird' (v2)") - assertErrNil(t.Fatal, storage.Create(rls2), "Storing release 'angry-bird' (v3)") - assertErrNil(t.Fatal, storage.Create(rls3), "Storing release 'angry-bird' (v4)") + require.NoError(t, storage.Create(rls0), "Storing release 'angry-bird' (v1)") + require.NoError(t, storage.Create(rls1), "Storing release 'angry-bird' (v2)") + require.NoError(t, storage.Create(rls2), "Storing release 'angry-bird' (v3)") + require.NoError(t, storage.Create(rls3), "Storing release 'angry-bird' (v4)") } setup() // Because we have not set a limit, we expect 4. expect := 4 - if hist, err := storage.History(name); err != nil { - t.Fatal(err) - } else if len(hist) != expect { - t.Fatalf("expected %d items in history, got %d", expect, len(hist)) - } + hist, err := storage.History(name) + require.NoError(t, err) + require.Equal(t, len(hist), expect, "expected %d items in history, got %d", expect, len(hist)) storage.MaxHistory = 3 rls5 := ReleaseTestData{Name: name, Version: 5, Status: common.StatusDeployed}.ToRelease() - assertErrNil(t.Fatal, storage.Create(rls5), "Storing release 'angry-bird' (v5)") + require.NoError(t, storage.Create(rls5), "Storing release 'angry-bird' (v5)") // On inserting the 5th record, we expect two records to be pruned from history. - hist, err := storage.History(name) + hist, err = storage.History(name) require.NoError(t, err) rhist, err := releaseListToV1List(hist) require.NoError(t, err) @@ -399,9 +358,8 @@ func TestStorageRemoveLeastRecent(t *testing.T) { // We expect the existing records to be 3, 4, and 5. for i, item := range rhist { v := item.Version - if expect := i + 3; v != expect { - t.Errorf("Expected release %d, got %d", expect, v) - } + expect := i + 3 + assert.Equalf(t, v, expect, "Expected release %d, got %d", expect, v) } } @@ -420,22 +378,21 @@ func TestStorageDoNotDeleteDeployed(t *testing.T) { rls3 := ReleaseTestData{Name: name, Version: 4, Status: common.StatusFailed}.ToRelease() // create the release records in the storage - assertErrNil(t.Fatal, storage.Create(rls0), "Storing release 'angry-bird' (v1)") - assertErrNil(t.Fatal, storage.Create(rls1), "Storing release 'angry-bird' (v2)") - assertErrNil(t.Fatal, storage.Create(rls2), "Storing release 'angry-bird' (v3)") - assertErrNil(t.Fatal, storage.Create(rls3), "Storing release 'angry-bird' (v4)") + require.NoError(t, storage.Create(rls0), "Storing release 'angry-bird' (v1)") + require.NoError(t, storage.Create(rls1), "Storing release 'angry-bird' (v2)") + require.NoError(t, storage.Create(rls2), "Storing release 'angry-bird' (v3)") + require.NoError(t, storage.Create(rls3), "Storing release 'angry-bird' (v4)") } setup() rls5 := ReleaseTestData{Name: name, Version: 5, Status: common.StatusFailed}.ToRelease() - assertErrNil(t.Fatal, storage.Create(rls5), "Storing release 'angry-bird' (v5)") + require.NoError(t, storage.Create(rls5), "Storing release 'angry-bird' (v5)") // On inserting the 5th record, we expect a total of 3 releases, but we expect version 2 // (the only deployed release), to still exist hist, err := storage.History(name) - if err != nil { - t.Fatal(err) - } else if len(hist) != storage.MaxHistory { + require.NoError(t, err) + if len(hist) != storage.MaxHistory { rhist, err := releaseListToV1List(hist) require.NoError(t, err) for _, item := range rhist { @@ -453,9 +410,7 @@ func TestStorageDoNotDeleteDeployed(t *testing.T) { rhist, err := releaseListToV1List(hist) require.NoError(t, err) for _, item := range rhist { - if !expectedVersions[item.Version] { - t.Errorf("Release version %d, found when not expected", item.Version) - } + assert.Truef(t, expectedVersions[item.Version], "Release version %d, found when not expected", item.Version) } } @@ -473,25 +428,21 @@ func TestStorageLast(t *testing.T) { rls3 := ReleaseTestData{Name: name, Version: 4, Status: common.StatusFailed}.ToRelease() // create the release records in the storage - assertErrNil(t.Fatal, storage.Create(rls0), "Storing release 'angry-bird' (v1)") - assertErrNil(t.Fatal, storage.Create(rls1), "Storing release 'angry-bird' (v2)") - assertErrNil(t.Fatal, storage.Create(rls2), "Storing release 'angry-bird' (v3)") - assertErrNil(t.Fatal, storage.Create(rls3), "Storing release 'angry-bird' (v4)") + require.NoError(t, storage.Create(rls0), "Storing release 'angry-bird' (v1)") + require.NoError(t, storage.Create(rls1), "Storing release 'angry-bird' (v2)") + require.NoError(t, storage.Create(rls2), "Storing release 'angry-bird' (v3)") + require.NoError(t, storage.Create(rls3), "Storing release 'angry-bird' (v4)") } setup() h, err := storage.Last(name) - if err != nil { - t.Fatalf("Failed to query for release history (%q): %s\n", name, err) - } + require.NoError(t, err, "Failed to query for release history (%q)", name) rel, err := releaserToV1Release(h) require.NoError(t, err) - if rel.Version != 4 { - t.Errorf("Expected revision 4, got %d", rel.Version) - } + assert.Equal(t, 4, rel.Version, "Expected revision 4, got %d", rel.Version) } // TestUpgradeInitiallyFailedReleaseWithHistoryLimit tests a case when there are no deployed release yet, but history limit has been @@ -511,47 +462,34 @@ func TestUpgradeInitiallyFailedReleaseWithHistoryLimit(t *testing.T) { rls3 := ReleaseTestData{Name: name, Version: 4, Status: common.StatusFailed}.ToRelease() // create the release records in the storage - assertErrNil(t.Fatal, storage.Create(rls0), "Storing release 'angry-bird' (v1)") - assertErrNil(t.Fatal, storage.Create(rls1), "Storing release 'angry-bird' (v2)") - assertErrNil(t.Fatal, storage.Create(rls2), "Storing release 'angry-bird' (v3)") - assertErrNil(t.Fatal, storage.Create(rls3), "Storing release 'angry-bird' (v4)") + require.NoError(t, storage.Create(rls0), "Storing release 'angry-bird' (v1)") + require.NoError(t, storage.Create(rls1), "Storing release 'angry-bird' (v2)") + require.NoError(t, storage.Create(rls2), "Storing release 'angry-bird' (v3)") + require.NoError(t, storage.Create(rls3), "Storing release 'angry-bird' (v4)") hist, err := storage.History(name) - if err != nil { - t.Fatalf("unexpected error: %s", err) - } + require.NoError(t, err) wantHistoryLen := 4 - if len(hist) != wantHistoryLen { - t.Fatalf("expected history of release %q to contain %d releases, got %d", name, wantHistoryLen, len(hist)) - } + require.Len(t, hist, wantHistoryLen, "expected history of release %q to contain %d releases, got %d", name, wantHistoryLen, len(hist)) } setup() rls5 := ReleaseTestData{Name: name, Version: 5, Status: common.StatusFailed}.ToRelease() - err := storage.Create(rls5) - if err != nil { - t.Fatalf("Failed to create a new release version: %s", err) - } + require.NoError(t, storage.Create(rls5), "Failed to create a new release version") hist, err := storage.History(name) - if err != nil { - t.Fatalf("unexpected error: %s", err) - } + require.NoError(t, err) rhist, err := releaseListToV1List(hist) require.NoError(t, err) for i, rel := range rhist { wantVersion := i + 2 - if rel.Version != wantVersion { - t.Fatalf("Expected history release %d version to equal %d, got %d", i+1, wantVersion, rel.Version) - } + require.Equal(t, wantVersion, rel.Version, "Expected history release %d version to equal %d, got %d", i+1, wantVersion, rel.Version) wantStatus := common.StatusFailed - if rel.Info.Status != wantStatus { - t.Fatalf("Expected history release %d status to equal %q, got %q", i+1, wantStatus, rel.Info.Status) - } + require.Equal(t, wantStatus, rel.Info.Status, "Expected history release %d status to equal %q, got %q", i+1, wantStatus, rel.Info.Status) } } @@ -573,21 +511,13 @@ func (test ReleaseTestData) ToRelease() *rspb.Release { } } -func assertErrNil(eh func(args ...any), err error, message string) { - if err != nil { - eh(fmt.Sprintf("%s: %q", message, err)) - } -} - func TestStorageGetsLoggerFromDriver(t *testing.T) { d := driver.NewMemory() l := &mockSLogHandler{} d.SetLogger(l) s := Init(d) _, _ = s.Get("doesnt-matter", 123) - if !l.Called { - t.Fatal("Expected storage to use driver's logger, but it did not") - } + require.True(t, l.Called, "Expected storage to use driver's logger, but it did not") } type mockSLogHandler struct { From dc3e3a5e7efadff49fd26eac511cf18801af0ebc Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 20:50:56 +0200 Subject: [PATCH 30/61] chore(pkg): refactor: convert tests to testify assert/require part 11 refactor: convert tests to testify assert/require in pkg Signed-off-by: Matthieu MOREL --- pkg/action/rollback_test.go | 3 +- pkg/downloader/manager_test.go | 217 +++++++++------------------------ pkg/kube/ready_test.go | 202 +++++++++++------------------- 3 files changed, 128 insertions(+), 294 deletions(-) diff --git a/pkg/action/rollback_test.go b/pkg/action/rollback_test.go index 01419341b..7ffd90d25 100644 --- a/pkg/action/rollback_test.go +++ b/pkg/action/rollback_test.go @@ -78,8 +78,7 @@ func TestRollback_WaitOptionsPassedDownstream(t *testing.T) { // Access the underlying FailingKubeClient to check recorded options failer := config.KubeClient.(*kubefake.FailingKubeClient) - err := client.Run(rel.Name) - req.NoError(err) + req.NoError(client.Run(rel.Name)) // Verify that WaitOptions were passed to GetWaiter is.NotEmpty(failer.RecordedWaitOptions, "WaitOptions should be passed to GetWaiter") diff --git a/pkg/downloader/manager_test.go b/pkg/downloader/manager_test.go index e0cea0cd2..00cb5b668 100644 --- a/pkg/downloader/manager_test.go +++ b/pkg/downloader/manager_test.go @@ -17,7 +17,6 @@ package downloader import ( "bytes" - "errors" "io/fs" "os" "path/filepath" @@ -50,9 +49,7 @@ func TestVersionEquals(t *testing.T) { } for _, tt := range tests { - if versionEquals(tt.v1, tt.v2) != tt.expect { - t.Errorf("%s: failed comparison of %q and %q (expect equal: %t)", tt.name, tt.v1, tt.v2, tt.expect) - } + assert.Equal(t, tt.expect, versionEquals(tt.v1, tt.v2), "%s: failed comparison of %q and %q (expect equal: %t)", tt.name, tt.v1, tt.v2, tt.expect) } } @@ -64,84 +61,46 @@ func TestFindChartURL(t *testing.T) { RepositoryCache: repoCache, } repos, err := m.loadChartRepositories() - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) name := "alpine" version := "0.1.0" repoURL := "http://example.com/charts" churl, username, password, insecureSkipTLSVerify, passcredentialsall, _, _, _, err := m.findChartURL(name, version, repoURL, repos) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if churl != "https://charts.helm.sh/stable/alpine-0.1.0.tgz" { - t.Errorf("Unexpected URL %q", churl) - } - if username != "" { - t.Errorf("Unexpected username %q", username) - } - if password != "" { - t.Errorf("Unexpected password %q", password) - } - if passcredentialsall != false { - t.Errorf("Unexpected passcredentialsall %t", passcredentialsall) - } - if insecureSkipTLSVerify { - t.Errorf("Unexpected insecureSkipTLSVerify %t", insecureSkipTLSVerify) - } + assert.Equal(t, "https://charts.helm.sh/stable/alpine-0.1.0.tgz", churl, "Unexpected URL %q", churl) + assert.Empty(t, username, "Unexpected username %q", username) + assert.Empty(t, password, "Unexpected password %q", password) + assert.False(t, passcredentialsall, "Unexpected passcredentialsall %t", passcredentialsall) + assert.False(t, insecureSkipTLSVerify, "Unexpected insecureSkipTLSVerify %t", insecureSkipTLSVerify) name = "tlsfoo" version = "1.2.3" repoURL = "https://example-https-insecureskiptlsverify.com" churl, username, password, insecureSkipTLSVerify, passcredentialsall, _, _, _, err = m.findChartURL(name, version, repoURL, repos) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if !insecureSkipTLSVerify { - t.Errorf("Unexpected insecureSkipTLSVerify %t", insecureSkipTLSVerify) - } - if churl != "https://example.com/tlsfoo-1.2.3.tgz" { - t.Errorf("Unexpected URL %q", churl) - } - if username != "" { - t.Errorf("Unexpected username %q", username) - } - if password != "" { - t.Errorf("Unexpected password %q", password) - } - if passcredentialsall != false { - t.Errorf("Unexpected passcredentialsall %t", passcredentialsall) - } + assert.True(t, insecureSkipTLSVerify, "Unexpected insecureSkipTLSVerify %t", insecureSkipTLSVerify) + assert.Equal(t, "https://example.com/tlsfoo-1.2.3.tgz", churl, "Unexpected URL %q", churl) + assert.Empty(t, username, "Unexpected username %q", username) + assert.Empty(t, password, "Unexpected password %q", password) + assert.False(t, passcredentialsall, "Unexpected passcredentialsall %t", passcredentialsall) name = "foo" version = "1.2.3" repoURL = "http://example.com/helm" churl, username, password, insecureSkipTLSVerify, passcredentialsall, _, _, _, err = m.findChartURL(name, version, repoURL, repos) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if churl != "http://example.com/helm/charts/foo-1.2.3.tgz" { - t.Errorf("Unexpected URL %q", churl) - } - if username != "" { - t.Errorf("Unexpected username %q", username) - } - if password != "" { - t.Errorf("Unexpected password %q", password) - } - if passcredentialsall != false { - t.Errorf("Unexpected passcredentialsall %t", passcredentialsall) - } - if insecureSkipTLSVerify { - t.Errorf("Unexpected insecureSkipTLSVerify %t", insecureSkipTLSVerify) - } + assert.Equal(t, "http://example.com/helm/charts/foo-1.2.3.tgz", churl, "Unexpected URL %q", churl) + assert.Empty(t, username, "Unexpected username %q", username) + assert.Empty(t, password, "Unexpected password %q", password) + assert.False(t, passcredentialsall, "Unexpected passcredentialsall %t", passcredentialsall) + assert.False(t, insecureSkipTLSVerify, "Unexpected insecureSkipTLSVerify %t", insecureSkipTLSVerify) } func TestGetRepoNames(t *testing.T) { @@ -217,15 +176,11 @@ func TestGetRepoNames(t *testing.T) { t.Fatal(err) } - if tt.err { - t.Fatalf("Expected error in test %q", tt.name) - } + require.False(t, tt.err, "Expected error in test %q", tt.name) // m1 and m2 are the maps we want to compare eq := reflect.DeepEqual(l, tt.expect) - if !eq { - t.Errorf("%s: expected map %v, got %v", tt.name, l, tt.name) - } + assert.True(t, eq, "%s: expected map %v, got %v", tt.name, l, tt.name) } } @@ -238,20 +193,12 @@ func TestDownloadAll(t *testing.T) { ChartPath: chartPath, } signtest, err := loader.LoadDir(filepath.Join("testdata", "signtest")) - if err != nil { - t.Fatal(err) - } - if err := chartutil.SaveDir(signtest, filepath.Join(chartPath, "testdata")); err != nil { - t.Fatal(err) - } + require.NoError(t, err) + require.NoError(t, chartutil.SaveDir(signtest, filepath.Join(chartPath, "testdata"))) local, err := loader.LoadDir(filepath.Join("testdata", "local-subchart")) - if err != nil { - t.Fatal(err) - } - if err := chartutil.SaveDir(local, filepath.Join(chartPath, "charts")); err != nil { - t.Fatal(err) - } + require.NoError(t, err) + require.NoError(t, chartutil.SaveDir(local, filepath.Join(chartPath, "charts"))) signDep := &chart.Dependency{ Name: signtest.Name(), @@ -265,16 +212,11 @@ func TestDownloadAll(t *testing.T) { } // create a 'tmpcharts' directory to test #5567 - if err := os.MkdirAll(filepath.Join(chartPath, "tmpcharts"), 0o755); err != nil { - t.Fatal(err) - } - if err := m.downloadAll([]*chart.Dependency{signDep, localDep}); err != nil { - t.Error(err) - } + require.NoError(t, os.MkdirAll(filepath.Join(chartPath, "tmpcharts"), 0o755)) + require.NoError(t, m.downloadAll([]*chart.Dependency{signDep, localDep})) - if _, err := os.Stat(filepath.Join(chartPath, "charts", "signtest-0.1.0.tgz")); errors.Is(err, fs.ErrNotExist) { - t.Error(err) - } + _, err = os.Stat(filepath.Join(chartPath, "charts", "signtest-0.1.0.tgz")) + require.NotErrorIs(t, err, fs.ErrNotExist) // A chart with a bad name like this cannot be loaded and saved. Handling in // the loading and saving will return an error about the invalid name. In @@ -283,24 +225,15 @@ func TestDownloadAll(t *testing.T) { description: A Helm chart for Kubernetes name: ../bad-local-subchart version: 0.1.0` - if err := os.MkdirAll(filepath.Join(chartPath, "testdata", "bad-local-subchart"), 0o755); err != nil { - t.Fatal(err) - } - err = os.WriteFile(filepath.Join(chartPath, "testdata", "bad-local-subchart", "Chart.yaml"), []byte(badchartyaml), 0o644) - if err != nil { - t.Fatal(err) - } + require.NoError(t, os.MkdirAll(filepath.Join(chartPath, "testdata", "bad-local-subchart"), 0o755)) + require.NoError(t, os.WriteFile(filepath.Join(chartPath, "testdata", "bad-local-subchart", "Chart.yaml"), []byte(badchartyaml), 0o644)) badLocalDep := &chart.Dependency{ Name: "../bad-local-subchart", Repository: "file://./testdata/bad-local-subchart", Version: "0.1.0", } - - err = m.downloadAll([]*chart.Dependency{badLocalDep}) - if err == nil { - t.Fatal("Expected error for bad dependency name") - } + require.Error(t, m.downloadAll([]*chart.Dependency{badLocalDep}), "Expected error for bad dependency name") } func TestUpdateBeforeBuild(t *testing.T) { @@ -310,9 +243,7 @@ func TestUpdateBeforeBuild(t *testing.T) { repotest.WithChartSourceGlob("testdata/*.tgz*"), ) defer srv.Stop() - if err := srv.LinkIndices(); err != nil { - t.Fatal(err) - } + require.NoError(t, srv.LinkIndices()) dir := func(p ...string) string { return filepath.Join(append([]string{srv.Root()}, p...)...) } @@ -325,9 +256,7 @@ func TestUpdateBeforeBuild(t *testing.T) { APIVersion: "v1", }, } - if err := chartutil.SaveDir(d, dir()); err != nil { - t.Fatal(err) - } + require.NoError(t, chartutil.SaveDir(d, dir())) // Save a chart c := &chart.Chart{ Metadata: &chart.Metadata{ @@ -341,9 +270,7 @@ func TestUpdateBeforeBuild(t *testing.T) { }}, }, } - if err := chartutil.SaveDir(c, dir()); err != nil { - t.Fatal(err) - } + require.NoError(t, chartutil.SaveDir(c, dir())) // Set-up a manager b := bytes.NewBuffer(nil) @@ -360,13 +287,8 @@ func TestUpdateBeforeBuild(t *testing.T) { } // Update before Build. see issue: https://github.com/helm/helm/issues/7101 - if err := m.Update(); err != nil { - t.Fatal(err) - } - - if err := m.Build(); err != nil { - t.Fatal(err) - } + require.NoError(t, m.Update()) + require.NoError(t, m.Build()) } // TestUpdateWithNoRepo is for the case of a dependency that has no repo listed. @@ -379,9 +301,7 @@ func TestUpdateWithNoRepo(t *testing.T) { repotest.WithChartSourceGlob("testdata/*.tgz*"), ) defer srv.Stop() - if err := srv.LinkIndices(); err != nil { - t.Fatal(err) - } + require.NoError(t, srv.LinkIndices()) dir := func(p ...string) string { return filepath.Join(append([]string{srv.Root()}, p...)...) } @@ -407,16 +327,12 @@ func TestUpdateWithNoRepo(t *testing.T) { }}, }, } - if err := chartutil.SaveDir(c, dir()); err != nil { - t.Fatal(err) - } + require.NoError(t, chartutil.SaveDir(c, dir())) // Save dependent chart into the parents charts directory. If the chart is // not in the charts directory Helm will return an error that it is not // found. - if err := chartutil.SaveDir(d, dir(c.Metadata.Name, "charts")); err != nil { - t.Fatal(err) - } + require.NoError(t, chartutil.SaveDir(d, dir(c.Metadata.Name, "charts"))) // Set-up a manager b := bytes.NewBuffer(nil) @@ -433,9 +349,7 @@ func TestUpdateWithNoRepo(t *testing.T) { } // Test the update - if err := m.Update(); err != nil { - t.Fatal(err) - } + require.NoError(t, m.Update()) } // This function is the skeleton test code of failing tests for #6416 and #6871 and bugs due to #5874. @@ -452,9 +366,7 @@ func checkBuildWithOptionalFields(t *testing.T, chartName string, dep chart.Depe repotest.WithChartSourceGlob("testdata/*.tgz*"), ) defer srv.Stop() - if err := srv.LinkIndices(); err != nil { - t.Fatal(err) - } + require.NoError(t, srv.LinkIndices()) dir := func(p ...string) string { return filepath.Join(append([]string{srv.Root()}, p...)...) } @@ -479,9 +391,7 @@ func checkBuildWithOptionalFields(t *testing.T, chartName string, dep chart.Depe Dependencies: []*chart.Dependency{&dep}, }, } - if err := chartutil.SaveDir(c, dir()); err != nil { - t.Fatal(err) - } + require.NoError(t, chartutil.SaveDir(c, dir())) // Set-up a manager b := bytes.NewBuffer(nil) @@ -500,14 +410,10 @@ func checkBuildWithOptionalFields(t *testing.T, chartName string, dep chart.Depe } // First build will update dependencies and create Chart.lock file. - if err := m.Build(); err != nil { - t.Fatal(err) - } + require.NoError(t, m.Build()) // Second build should be passed. See PR #6655. - if err := m.Build(); err != nil { - t.Fatal(err) - } + require.NoError(t, m.Build()) } func TestBuild_WithoutOptionalFields(t *testing.T) { @@ -573,9 +479,8 @@ func TestErrRepoNotFound_Error(t *testing.T) { e := ErrRepoNotFound{ Repos: tt.fields.Repos, } - if got := e.Error(); got != tt.want { - t.Errorf("Error() = %v, want %v", got, tt.want) - } + got := e.Error() + assert.EqualErrorf(t, e, tt.want, "Error() = %v, want %v", got, tt.want) }) } } @@ -601,12 +506,8 @@ func TestKey(t *testing.T) { for _, tt := range tests { o, err := key(tt.name) - if err != nil { - t.Fatalf("unable to generate key for %q with error: %s", tt.name, err) - } - if o != tt.expect { - t.Errorf("wrong key name generated for %q, expected %q but got %q", tt.name, tt.expect, o) - } + require.NoError(t, err, "unable to generate key for %q", tt.name) + assert.Equal(t, tt.expect, o, "wrong key name generated for %q, expected %q but got %q", tt.name, tt.expect, o) } } @@ -697,8 +598,7 @@ func TestWriteLock(t *testing.T) { t.Run("v2 lock file", func(t *testing.T) { dir := t.TempDir() - err := writeLock(dir, lock, false) - require.NoError(t, err) + require.NoError(t, writeLock(dir, lock, false)) lockfilePath := filepath.Join(dir, "Chart.lock") _, err = os.Stat(lockfilePath) @@ -716,8 +616,7 @@ func TestWriteLock(t *testing.T) { t.Run("v1 lock file", func(t *testing.T) { dir := t.TempDir() - err := writeLock(dir, lock, true) - require.NoError(t, err) + require.NoError(t, writeLock(dir, lock, true)) lockfilePath := filepath.Join(dir, "requirements.lock") _, err = os.Stat(lockfilePath) @@ -737,9 +636,7 @@ func TestWriteLock(t *testing.T) { dir := t.TempDir() lockfilePath := filepath.Join(dir, "Chart.lock") require.NoError(t, os.WriteFile(lockfilePath, []byte("old content"), 0o644)) - - err = writeLock(dir, lock, false) - require.NoError(t, err) + require.NoError(t, writeLock(dir, lock, false)) content, err := os.ReadFile(lockfilePath) require.NoError(t, err) @@ -753,17 +650,13 @@ func TestWriteLock(t *testing.T) { lockfilePath := filepath.Join(dir, "Chart.lock") require.NoError(t, os.Symlink(dummyFile, lockfilePath)) - - err = writeLock(dir, lock, false) - assert.ErrorContains(t, err, "the Chart.lock file is a symlink to") + assert.ErrorContains(t, writeLock(dir, lock, false), "the Chart.lock file is a symlink to") }) t.Run("chart path is not a directory", func(t *testing.T) { dir := t.TempDir() filePath := filepath.Join(dir, "not-a-dir") require.NoError(t, os.WriteFile(filePath, []byte("file"), 0o644)) - - err = writeLock(filePath, lock, false) - assert.Error(t, err) + assert.Error(t, writeLock(filePath, lock, false)) }) } diff --git a/pkg/kube/ready_test.go b/pkg/kube/ready_test.go index fc3ac9409..01f6db3cb 100644 --- a/pkg/kube/ready_test.go +++ b/pkg/kube/ready_test.go @@ -19,6 +19,8 @@ import ( "context" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" appsv1 "k8s.io/api/apps/v1" batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" @@ -90,18 +92,15 @@ func Test_ReadyChecker_IsReady_Pod(t *testing.T) { checkJobs: tt.fields.checkJobs, pausedAsReady: tt.fields.pausedAsReady, } - if _, err := c.client.CoreV1().Pods(defaultNamespace).Create(t.Context(), tt.pod, metav1.CreateOptions{}); err != nil { - t.Errorf("Failed to create Pod error: %v", err) - return - } + _, err := c.client.CoreV1().Pods(defaultNamespace).Create(t.Context(), tt.pod, metav1.CreateOptions{}) + require.NoError(t, err, "Failed to create Pod error") got, err := c.IsReady(tt.args.ctx, tt.args.resource) - if (err != nil) != tt.wantErr { - t.Errorf("IsReady() error = %v, wantErr %v", err, tt.wantErr) - return - } - if got != tt.want { - t.Errorf("IsReady() = %v, want %v", got, tt.want) + if tt.wantErr { + require.Error(t, err, "IsReady()") + } else { + require.NoError(t, err, "IsReady()") } + assert.Equal(t, tt.want, got, "IsReady() = %v, want %v", got, tt.want) }) } } @@ -162,17 +161,12 @@ func Test_ReadyChecker_IsReady_Job(t *testing.T) { checkJobs: tt.fields.checkJobs, pausedAsReady: tt.fields.pausedAsReady, } - if _, err := c.client.BatchV1().Jobs(defaultNamespace).Create(t.Context(), tt.job, metav1.CreateOptions{}); err != nil { - t.Errorf("Failed to create Job error: %v", err) - return - } + _, err := c.client.BatchV1().Jobs(defaultNamespace).Create(t.Context(), tt.job, metav1.CreateOptions{}) + + require.NoError(t, err, "Failed to create Job") got, err := c.IsReady(tt.args.ctx, tt.args.resource) - if (err != nil) != tt.wantErr { - t.Errorf("IsReady() error = %v, wantErr %v", err, tt.wantErr) - } - if got != tt.want { - t.Errorf("IsReady() = %v, want %v", got, tt.want) - } + assert.Equal(t, tt.wantErr, (err != nil), "IsReady() error = %v, wantErr %v", err, tt.wantErr) + assert.Equal(t, tt.want, got, "IsReady() = %v, want %v", got, tt.want) }) } } @@ -236,21 +230,15 @@ func Test_ReadyChecker_IsReady_Deployment(t *testing.T) { checkJobs: tt.fields.checkJobs, pausedAsReady: tt.fields.pausedAsReady, } - if _, err := c.client.AppsV1().Deployments(defaultNamespace).Create(t.Context(), tt.deployment, metav1.CreateOptions{}); err != nil { - t.Errorf("Failed to create Deployment error: %v", err) - return - } - if _, err := c.client.AppsV1().ReplicaSets(defaultNamespace).Create(t.Context(), tt.replicaSet, metav1.CreateOptions{}); err != nil { - t.Errorf("Failed to create ReplicaSet error: %v", err) - return - } + _, err := c.client.AppsV1().Deployments(defaultNamespace).Create(t.Context(), tt.deployment, metav1.CreateOptions{}) + require.NoError(t, err, "Failed to create Deployment") + + _, err = c.client.AppsV1().ReplicaSets(defaultNamespace).Create(t.Context(), tt.replicaSet, metav1.CreateOptions{}) + require.NoError(t, err, "Failed to create ReplicaSet") + got, err := c.IsReady(tt.args.ctx, tt.args.resource) - if (err != nil) != tt.wantErr { - t.Errorf("IsReady() error = %v, wantErr %v", err, tt.wantErr) - } - if got != tt.want { - t.Errorf("IsReady() = %v, want %v", got, tt.want) - } + assert.Equal(t, tt.wantErr, (err != nil), "IsReady() error = %v, wantErr %v", err, tt.wantErr) + assert.Equal(t, tt.want, got, "IsReady() = %v, want %v", got, tt.want) }) } } @@ -311,17 +299,12 @@ func Test_ReadyChecker_IsReady_PersistentVolumeClaim(t *testing.T) { checkJobs: tt.fields.checkJobs, pausedAsReady: tt.fields.pausedAsReady, } - if _, err := c.client.CoreV1().PersistentVolumeClaims(defaultNamespace).Create(t.Context(), tt.pvc, metav1.CreateOptions{}); err != nil { - t.Errorf("Failed to create PersistentVolumeClaim error: %v", err) - return - } + _, err := c.client.CoreV1().PersistentVolumeClaims(defaultNamespace).Create(t.Context(), tt.pvc, metav1.CreateOptions{}) + require.NoError(t, err, "Failed to create PersistentVolumeClaim") + got, err := c.IsReady(tt.args.ctx, tt.args.resource) - if (err != nil) != tt.wantErr { - t.Errorf("IsReady() error = %v, wantErr %v", err, tt.wantErr) - } - if got != tt.want { - t.Errorf("IsReady() = %v, want %v", got, tt.want) - } + assert.Equal(t, tt.wantErr, (err != nil), "IsReady() error = %v, wantErr %v", err, tt.wantErr) + assert.Equal(t, tt.want, got, "IsReady() = %v, want %v", got, tt.want) }) } } @@ -382,17 +365,12 @@ func Test_ReadyChecker_IsReady_Service(t *testing.T) { checkJobs: tt.fields.checkJobs, pausedAsReady: tt.fields.pausedAsReady, } - if _, err := c.client.CoreV1().Services(defaultNamespace).Create(t.Context(), tt.svc, metav1.CreateOptions{}); err != nil { - t.Errorf("Failed to create Service error: %v", err) - return - } + _, err := c.client.CoreV1().Services(defaultNamespace).Create(t.Context(), tt.svc, metav1.CreateOptions{}) + require.NoError(t, err, "Failed to create Service") + got, err := c.IsReady(tt.args.ctx, tt.args.resource) - if (err != nil) != tt.wantErr { - t.Errorf("IsReady() error = %v, wantErr %v", err, tt.wantErr) - } - if got != tt.want { - t.Errorf("IsReady() = %v, want %v", got, tt.want) - } + assert.Equal(t, tt.wantErr, (err != nil), "IsReady() error = %v, wantErr %v", err, tt.wantErr) + assert.Equal(t, tt.want, got, "IsReady() = %v, want %v", got, tt.want) }) } } @@ -453,17 +431,12 @@ func Test_ReadyChecker_IsReady_DaemonSet(t *testing.T) { checkJobs: tt.fields.checkJobs, pausedAsReady: tt.fields.pausedAsReady, } - if _, err := c.client.AppsV1().DaemonSets(defaultNamespace).Create(t.Context(), tt.ds, metav1.CreateOptions{}); err != nil { - t.Errorf("Failed to create DaemonSet error: %v", err) - return - } + _, err := c.client.AppsV1().DaemonSets(defaultNamespace).Create(t.Context(), tt.ds, metav1.CreateOptions{}) + require.NoError(t, err, "Failed to create DaemonSet") + got, err := c.IsReady(tt.args.ctx, tt.args.resource) - if (err != nil) != tt.wantErr { - t.Errorf("IsReady() error = %v, wantErr %v", err, tt.wantErr) - } - if got != tt.want { - t.Errorf("IsReady() = %v, want %v", got, tt.want) - } + assert.Equal(t, tt.wantErr, (err != nil), "IsReady() error = %v, wantErr %v", err, tt.wantErr) + assert.Equal(t, tt.want, got, "IsReady() = %v, want %v", got, tt.want) }) } } @@ -524,17 +497,12 @@ func Test_ReadyChecker_IsReady_StatefulSet(t *testing.T) { checkJobs: tt.fields.checkJobs, pausedAsReady: tt.fields.pausedAsReady, } - if _, err := c.client.AppsV1().StatefulSets(defaultNamespace).Create(t.Context(), tt.ss, metav1.CreateOptions{}); err != nil { - t.Errorf("Failed to create StatefulSet error: %v", err) - return - } + _, err := c.client.AppsV1().StatefulSets(defaultNamespace).Create(t.Context(), tt.ss, metav1.CreateOptions{}) + require.NoError(t, err, "Failed to create StatefulSet") + got, err := c.IsReady(tt.args.ctx, tt.args.resource) - if (err != nil) != tt.wantErr { - t.Errorf("IsReady() error = %v, wantErr %v", err, tt.wantErr) - } - if got != tt.want { - t.Errorf("IsReady() = %v, want %v", got, tt.want) - } + assert.Equal(t, tt.wantErr, (err != nil), "IsReady() error = %v, wantErr %v", err, tt.wantErr) + assert.Equal(t, tt.want, got, "IsReady() = %v, want %v", got, tt.want) }) } } @@ -610,17 +578,12 @@ func Test_ReadyChecker_IsReady_ReplicationController(t *testing.T) { checkJobs: tt.fields.checkJobs, pausedAsReady: tt.fields.pausedAsReady, } - if _, err := c.client.CoreV1().ReplicationControllers(defaultNamespace).Create(t.Context(), tt.rc, metav1.CreateOptions{}); err != nil { - t.Errorf("Failed to create ReplicationController error: %v", err) - return - } + _, err := c.client.CoreV1().ReplicationControllers(defaultNamespace).Create(t.Context(), tt.rc, metav1.CreateOptions{}) + require.NoError(t, err, "Failed to create ReplicationController") + got, err := c.IsReady(tt.args.ctx, tt.args.resource) - if (err != nil) != tt.wantErr { - t.Errorf("IsReady() error = %v, wantErr %v", err, tt.wantErr) - } - if got != tt.want { - t.Errorf("IsReady() = %v, want %v", got, tt.want) - } + assert.Equal(t, tt.wantErr, (err != nil), "IsReady() error = %v, wantErr %v", err, tt.wantErr) + assert.Equal(t, tt.want, got, "IsReady() = %v, want %v", got, tt.want) }) } } @@ -683,12 +646,8 @@ func Test_ReadyChecker_IsReady_ReplicaSet(t *testing.T) { } // got, err := c.IsReady(tt.args.ctx, tt.args.resource) - if (err != nil) != tt.wantErr { - t.Errorf("IsReady() error = %v, wantErr %v", err, tt.wantErr) - } - if got != tt.want { - t.Errorf("IsReady() = %v, want %v", got, tt.want) - } + assert.Equal(t, tt.wantErr, (err != nil), "IsReady() error = %v, wantErr %v", err, tt.wantErr) + assert.Equal(t, tt.want, got, "IsReady() = %v, want %v", got, tt.want) }) } } @@ -755,9 +714,8 @@ func Test_ReadyChecker_deploymentReady(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { c := NewReadyChecker(fake.NewClientset()) - if got := c.deploymentReady(tt.args.rs, tt.args.dep); got != tt.want { - t.Errorf("deploymentReady() = %v, want %v", got, tt.want) - } + got := c.deploymentReady(tt.args.rs, tt.args.dep) + assert.Equalf(t, tt.want, got, "deploymentReady() = %v, want %v", got, tt.want) }) } } @@ -789,9 +747,8 @@ func Test_ReadyChecker_replicaSetReady(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { c := NewReadyChecker(fake.NewClientset()) - if got := c.replicaSetReady(tt.args.rs); got != tt.want { - t.Errorf("replicaSetReady() = %v, want %v", got, tt.want) - } + got := c.replicaSetReady(tt.args.rs) + assert.Equalf(t, tt.want, got, "replicaSetReady() = %v, want %v", got, tt.want) }) } } @@ -823,9 +780,8 @@ func Test_ReadyChecker_replicationControllerReady(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { c := NewReadyChecker(fake.NewClientset()) - if got := c.replicationControllerReady(tt.args.rc); got != tt.want { - t.Errorf("replicationControllerReady() = %v, want %v", got, tt.want) - } + got := c.replicationControllerReady(tt.args.rc) + assert.Equalf(t, tt.want, got, "replicationControllerReady() = %v, want %v", got, tt.want) }) } } @@ -878,9 +834,8 @@ func Test_ReadyChecker_daemonSetReady(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { c := NewReadyChecker(fake.NewClientset()) - if got := c.daemonSetReady(tt.args.ds); got != tt.want { - t.Errorf("daemonSetReady() = %v, want %v", got, tt.want) - } + got := c.daemonSetReady(tt.args.ds) + assert.Equalf(t, tt.want, got, "daemonSetReady() = %v, want %v", got, tt.want) }) } } @@ -954,9 +909,8 @@ func Test_ReadyChecker_statefulSetReady(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { c := NewReadyChecker(fake.NewClientset()) - if got := c.statefulSetReady(tt.args.sts); got != tt.want { - t.Errorf("statefulSetReady() = %v, want %v", got, tt.want) - } + got := c.statefulSetReady(tt.args.sts) + assert.Equalf(t, tt.want, got, "statefulSetReady() = %v, want %v", got, tt.want) }) } } @@ -1014,19 +968,16 @@ func Test_ReadyChecker_podsReadyForObject(t *testing.T) { t.Run(tt.name, func(t *testing.T) { c := NewReadyChecker(fake.NewClientset()) for _, pod := range tt.existPods { - if _, err := c.client.CoreV1().Pods(defaultNamespace).Create(t.Context(), &pod, metav1.CreateOptions{}); err != nil { - t.Errorf("Failed to create Pod error: %v", err) - return - } + _, err := c.client.CoreV1().Pods(defaultNamespace).Create(t.Context(), &pod, metav1.CreateOptions{}) + require.NoError(t, err, "Failed to create Pod error") } got, err := c.podsReadyForObject(t.Context(), tt.args.namespace, tt.args.obj) - if (err != nil) != tt.wantErr { - t.Errorf("podsReadyForObject() error = %v, wantErr %v", err, tt.wantErr) - return - } - if got != tt.want { - t.Errorf("podsReadyForObject() got = %v, want %v", got, tt.want) + if tt.wantErr { + require.Error(t, err, "podsReadyForObject()") + } else { + require.NoError(t, err, "podsReadyForObject()") } + assert.Equal(t, tt.want, got, "podsReadyForObject() got = %v, want %v", got, tt.want) }) } } @@ -1097,9 +1048,7 @@ func Test_ReadyChecker_jobReady(t *testing.T) { t.Errorf("jobReady() error = %v, wantErr %v", err, tt.wantErr) return } - if got != tt.want { - t.Errorf("jobReady() = %v, want %v", got, tt.want) - } + assert.Equal(t, tt.want, got, "jobReady() = %v, want %v", got, tt.want) }) } } @@ -1131,9 +1080,8 @@ func Test_ReadyChecker_volumeReady(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { c := NewReadyChecker(fake.NewClientset()) - if got := c.volumeReady(tt.args.v); got != tt.want { - t.Errorf("volumeReady() = %v, want %v", got, tt.want) - } + got := c.volumeReady(tt.args.v) + assert.Equalf(t, tt.want, got, "volumeReady() = %v, want %v", got, tt.want) }) } } @@ -1177,9 +1125,7 @@ func Test_ReadyChecker_serviceReady(t *testing.T) { t.Run(tt.name, func(t *testing.T) { c := NewReadyChecker(fake.NewClientset()) got := c.serviceReady(tt.args.service) - if got != tt.want { - t.Errorf("serviceReady() = %v, want %v", got, tt.want) - } + assert.Equal(t, tt.want, got, "serviceReady() = %v, want %v", got, tt.want) }) } } @@ -1246,9 +1192,7 @@ func Test_ReadyChecker_crdBetaReady(t *testing.T) { t.Run(tt.name, func(t *testing.T) { c := NewReadyChecker(fake.NewClientset()) got := c.crdBetaReady(tt.args.crdBeta) - if got != tt.want { - t.Errorf("crdBetaReady() = %v, want %v", got, tt.want) - } + assert.Equal(t, tt.want, got, "crdBetaReady() = %v, want %v", got, tt.want) }) } } @@ -1315,9 +1259,7 @@ func Test_ReadyChecker_crdReady(t *testing.T) { t.Run(tt.name, func(t *testing.T) { c := NewReadyChecker(fake.NewClientset()) got := c.crdReady(tt.args.crdBeta) - if got != tt.want { - t.Errorf("crdBetaReady() = %v, want %v", got, tt.want) - } + assert.Equal(t, tt.want, got, "crdBetaReady() = %v, want %v", got, tt.want) }) } } From a3fa28ae22934450389ab31343c0ca20321d302c Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 20:50:56 +0200 Subject: [PATCH 31/61] chore(pkg): refactor: convert tests to testify assert/require part 12 refactor: convert tests to testify assert/require in pkg Signed-off-by: Matthieu MOREL --- pkg/action/install_test.go | 197 ++++++++++++------------------------ pkg/cmd/verify_test.go | 20 ++-- pkg/provenance/sign_test.go | 155 ++++++++-------------------- 3 files changed, 116 insertions(+), 256 deletions(-) diff --git a/pkg/action/install_test.go b/pkg/action/install_test.go index f79590670..da680f41a 100644 --- a/pkg/action/install_test.go +++ b/pkg/action/install_test.go @@ -185,9 +185,7 @@ func TestInstallRelease(t *testing.T) { vals := map[string]any{} ctx, done := context.WithCancel(t.Context()) resi, err := instAction.RunWithContext(ctx, buildChart(), vals) - if err != nil { - t.Fatalf("Failed install: %s", err) - } + req.NoError(err, "Failed install") res, err := releaserToV1Release(resi) req.NoError(err) is.Equal("test-install-release", res.Name, "Expected release name.") @@ -238,9 +236,7 @@ func TestInstallReleaseWithTakeOwnership_ResourceNotOwned(t *testing.T) { instAction := installActionWithConfig(config) instAction.TakeOwnership = true resi, err := instAction.Run(buildChart(), nil) - if err != nil { - t.Fatalf("Failed install: %s", err) - } + req.NoError(err, "Failed install") res, err := releaserToV1Release(resi) req.NoError(err) @@ -262,9 +258,7 @@ func TestInstallReleaseWithTakeOwnership_ResourceOwned(t *testing.T) { instAction := installActionWithConfig(config) instAction.TakeOwnership = false resi, err := instAction.Run(buildChart(), nil) - if err != nil { - t.Fatalf("Failed install: %s", err) - } + req.NoError(err, "Failed install") res, err := releaserToV1Release(resi) req.NoError(err) r, err := instAction.cfg.Releases.Get(res.Name, res.Version) @@ -285,7 +279,7 @@ func TestInstallReleaseWithTakeOwnership_ResourceOwnedNoFlag(t *testing.T) { instAction := installActionWithConfig(config) _, err := instAction.Run(buildChart(), nil) req.Error(err) - is.Contains(err.Error(), "unable to continue with install") + is.ErrorContains(err, "unable to continue with install") } func TestInstallReleaseWithValues(t *testing.T) { @@ -303,9 +297,7 @@ func TestInstallReleaseWithValues(t *testing.T) { }, } resi, err := instAction.Run(buildChart(withSampleValues()), userVals) - if err != nil { - t.Fatalf("Failed install: %s", err) - } + req.NoError(err, "Failed install") res, err := releaserToV1Release(resi) req.NoError(err) is.Equal("test-install-release", res.Name, "Expected release name.") @@ -344,9 +336,7 @@ func TestInstallRelease_WithNotes(t *testing.T) { instAction.ReleaseName = "with-notes" vals := map[string]any{} resi, err := instAction.Run(buildChart(withNotes("note here")), vals) - if err != nil { - t.Fatalf("Failed install: %s", err) - } + req.NoError(err, "Failed install") res, err := releaserToV1Release(resi) req.NoError(err) @@ -376,9 +366,7 @@ func TestInstallRelease_WithNotesRendered(t *testing.T) { instAction.ReleaseName = "with-notes" vals := map[string]any{} resi, err := instAction.Run(buildChart(withNotes("got-{{.Release.Name}}")), vals) - if err != nil { - t.Fatalf("Failed install: %s", err) - } + req.NoError(err, "Failed install") res, err := releaserToV1Release(resi) req.NoError(err) @@ -400,9 +388,7 @@ func TestInstallRelease_WithChartAndDependencyParentNotes(t *testing.T) { instAction.ReleaseName = "with-notes" vals := map[string]any{} resi, err := instAction.Run(buildChart(withNotes("parent"), withDependency(withNotes("child"))), vals) - if err != nil { - t.Fatalf("Failed install: %s", err) - } + req.NoError(err, "Failed install") res, err := releaserToV1Release(resi) req.NoError(err) @@ -424,9 +410,7 @@ func TestInstallRelease_WithChartAndDependencyAllNotes(t *testing.T) { instAction.SubNotes = true vals := map[string]any{} resi, err := instAction.Run(buildChart(withNotes("parent"), withDependency(withNotes("child"))), vals) - if err != nil { - t.Fatalf("Failed install: %s", err) - } + req.NoError(err, "Failed install") res, err := releaserToV1Release(resi) req.NoError(err) @@ -451,9 +435,7 @@ func TestInstallRelease_DryRunClient(t *testing.T) { vals := map[string]any{} resi, err := instAction.Run(buildChart(withSampleTemplates()), vals) - if err != nil { - t.Fatalf("Failed install: %s", err) - } + req.NoError(err, "Failed install") res, err := releaserToV1Release(resi) req.NoError(err) @@ -466,7 +448,7 @@ func TestInstallRelease_DryRunClient(t *testing.T) { _, err = instAction.cfg.Releases.Get(res.Name, res.Version) req.Error(err) is.Len(res.Hooks, 1) - is.True(res.Hooks[0].LastRun.CompletedAt.IsZero(), "expect hook to not be marked as run") + is.Zero(res.Hooks[0].LastRun.CompletedAt, "expect hook to not be marked as run") is.Equal("Dry run complete", res.Info.Description) } } @@ -480,9 +462,7 @@ func TestInstallRelease_DryRunHiddenSecret(t *testing.T) { instAction.DryRunStrategy = DryRunClient vals := map[string]any{} resi, err := instAction.Run(buildChart(withSampleSecret(), withSampleTemplates()), vals) - if err != nil { - t.Fatalf("Failed install: %s", err) - } + req.NoError(err, "Failed install") res, err := releaserToV1Release(resi) req.NoError(err) is.Contains(res.Manifest, "---\n# Source: hello/templates/secret.yaml\napiVersion: v1\nkind: Secret") @@ -495,9 +475,7 @@ func TestInstallRelease_DryRunHiddenSecret(t *testing.T) { instAction.HideSecret = true vals = map[string]any{} res2i, err := instAction.Run(buildChart(withSampleSecret(), withSampleTemplates()), vals) - if err != nil { - t.Fatalf("Failed install: %s", err) - } + req.NoError(err, "Failed install") res2, err := releaserToV1Release(res2i) req.NoError(err) @@ -511,9 +489,7 @@ func TestInstallRelease_DryRunHiddenSecret(t *testing.T) { instAction.DryRunStrategy = DryRunNone vals = map[string]any{} _, err = instAction.Run(buildChart(withSampleSecret(), withSampleTemplates()), vals) - if err == nil { - t.Fatal("Did not get the expected error when dry-run is false and hide secret is true") - } + req.Error(err, "Did not get the expected error when dry-run is false and hide secret is true") } // Regression test for #7955 @@ -532,9 +508,7 @@ func TestInstallRelease_DryRun_Lookup(t *testing.T) { }) resi, err := instAction.Run(mockChart, vals) - if err != nil { - t.Fatalf("Failed install: %s", err) - } + req.NoError(err, "Failed install") res, err := releaserToV1Release(resi) req.NoError(err) @@ -543,6 +517,7 @@ func TestInstallRelease_DryRun_Lookup(t *testing.T) { func TestInstallReleaseIncorrectTemplate_DryRun(t *testing.T) { is := assert.New(t) + req := require.New(t) instAction := installAction(t) instAction.DryRunStrategy = DryRunNone vals := map[string]any{} @@ -550,10 +525,8 @@ func TestInstallReleaseIncorrectTemplate_DryRun(t *testing.T) { expectedErr := `hello/templates/incorrect:1:10 executing "hello/templates/incorrect" at <.Values.bad.doh>: nil pointer evaluating interface {}.doh` - if err == nil { - t.Fatalf("Install should fail containing error: %s", expectedErr) - } - is.Contains(err.Error(), expectedErr) + req.Error(err, "Install should fail containing error: %s", expectedErr) + is.ErrorContains(err, expectedErr) } func TestInstallRelease_NoHooks(t *testing.T) { @@ -562,17 +535,15 @@ func TestInstallRelease_NoHooks(t *testing.T) { instAction := installAction(t) instAction.DisableHooks = true instAction.ReleaseName = "no-hooks" - require.NoError(t, instAction.cfg.Releases.Create(releaseStub())) + req.NoError(instAction.cfg.Releases.Create(releaseStub())) vals := map[string]any{} resi, err := instAction.Run(buildChart(), vals) - if err != nil { - t.Fatalf("Failed install: %s", err) - } + req.NoError(err, "Failed install") res, err := releaserToV1Release(resi) req.NoError(err) - is.True(res.Hooks[0].LastRun.CompletedAt.IsZero(), "hooks should not run with no-hooks") + is.Zero(res.Hooks[0].LastRun.CompletedAt, "hooks should not run with no-hooks") } func TestInstallRelease_FailedHooks(t *testing.T) { @@ -637,7 +608,7 @@ func TestInstallRelease_KubeVersion(t *testing.T) { vals = map[string]any{} _, err = instAction.Run(buildChart(withKube(">=99.0.0")), vals) req.Error(err) - is.Contains(err.Error(), "chart requires kubeVersion: >=99.0.0 which is incompatible with Kubernetes v1.20.") + is.ErrorContains(err, "chart requires kubeVersion: >=99.0.0 which is incompatible with Kubernetes v1.20.") } func TestInstallRelease_Wait(t *testing.T) { @@ -680,7 +651,7 @@ func TestInstallRelease_Wait_Interrupted(t *testing.T) { _, err := instAction.RunWithContext(ctx, buildChart(), vals) req.Error(err) - is.Contains(err.Error(), "context canceled") + req.ErrorContains(err, "context canceled") is.Equal(goroutines+1, instAction.getGoroutineCount()) // installation goroutine still is in background time.Sleep(10 * time.Second) // wait for goroutine to finish @@ -723,8 +694,8 @@ func TestInstallRelease_RollbackOnFailure(t *testing.T) { resi, err := instAction.Run(buildChart(), vals) req.Error(err) - is.Contains(err.Error(), "I timed out") - is.Contains(err.Error(), "rollback-on-failure") + req.ErrorContains(err, "I timed out") + req.ErrorContains(err, "rollback-on-failure") res, err := releaserToV1Release(resi) req.NoError(err) @@ -748,9 +719,9 @@ func TestInstallRelease_RollbackOnFailure(t *testing.T) { _, err := instAction.Run(buildChart(), vals) req.Error(err) - is.Contains(err.Error(), "I timed out") - is.Contains(err.Error(), "uninstall fail") - is.Contains(err.Error(), "an error occurred while uninstalling the release") + req.ErrorContains(err, "I timed out") + req.ErrorContains(err, "uninstall fail") + is.ErrorContains(err, "an error occurred while uninstalling the release") }) } func TestInstallRelease_RollbackOnFailure_Interrupted(t *testing.T) { @@ -771,9 +742,9 @@ func TestInstallRelease_RollbackOnFailure_Interrupted(t *testing.T) { resi, err := instAction.RunWithContext(ctx, buildChart(), vals) req.Error(err) - is.Contains(err.Error(), "context canceled") - is.Contains(err.Error(), "rollback-on-failure") - is.Contains(err.Error(), "uninstalled") + req.ErrorContains(err, "context canceled") + req.ErrorContains(err, "rollback-on-failure") + req.ErrorContains(err, "uninstalled") res, err := releaserToV1Release(resi) req.NoError(err) @@ -820,36 +791,23 @@ func TestNameTemplate(t *testing.T) { } for _, tc := range testCases { - n, err := TemplateName(tc.tpl) - if err != nil { + t.Run(tc.tpl, func(t *testing.T) { + n, err := TemplateName(tc.tpl) if tc.expectedErrorStr == "" { - t.Errorf("Was not expecting error, but got: %v", err) - continue + require.NoError(t, err) + } else { + require.Error(t, err) + re, compErr := regexp.Compile(tc.expectedErrorStr) + require.NoError(t, compErr, "Expected error string failed to compile") + assert.True(t, re.MatchString(err.Error()), "Error didn't match for %s expected %s", tc.tpl, tc.expectedErrorStr) } - re, compErr := regexp.Compile(tc.expectedErrorStr) - if compErr != nil { - t.Errorf("Expected error string failed to compile: %v", compErr) - continue - } - if !re.MatchString(err.Error()) { - t.Errorf("Error didn't match for %s expected %s but got %v", tc.tpl, tc.expectedErrorStr, err) - continue - } - } - if err == nil && tc.expectedErrorStr != "" { - t.Errorf("Was expecting error %s but didn't get an error back", tc.expectedErrorStr) - } - if tc.expected != "" { - re, err := regexp.Compile(tc.expected) - if err != nil { - t.Errorf("Expected string failed to compile: %v", err) - continue - } - if !re.MatchString(n) { - t.Errorf("Returned name didn't match for %s expected %s but got %s", tc.tpl, tc.expected, n) + if tc.expected != "" { + re, err := regexp.Compile(tc.expected) + require.NoError(t, err) + assert.True(t, re.MatchString(n), "Returned name didn't match for %s expected %s but got %s", tc.tpl, tc.expected, n) } - } + }) } } @@ -864,9 +822,7 @@ func TestInstallReleaseOutputDir(t *testing.T) { instAction.OutputDir = dir _, err := instAction.Run(buildChart(withSampleTemplates(), withMultipleManifestTemplate()), vals) - if err != nil { - t.Fatalf("Failed install: %s", err) - } + req.NoError(err, "Failed install") _, err = os.Stat(filepath.Join(dir, "hello", "templates", "goodbye")) req.NoError(err) @@ -901,9 +857,7 @@ func TestInstallOutputDirWithReleaseName(t *testing.T) { newDir := filepath.Join(dir, instAction.ReleaseName) _, err := instAction.Run(buildChart(withSampleTemplates(), withMultipleManifestTemplate()), vals) - if err != nil { - t.Fatalf("Failed install: %s", err) - } + req.NoError(err, "Failed install") _, err = os.Stat(filepath.Join(newDir, "hello", "templates", "goodbye")) req.NoError(err) @@ -925,46 +879,37 @@ func TestInstallOutputDirWithReleaseName(t *testing.T) { func TestNameAndChart(t *testing.T) { is := assert.New(t) + req := require.New(t) instAction := installAction(t) chartName := "./foo" name, chrt, err := instAction.NameAndChart([]string{chartName}) - if err != nil { - t.Fatal(err) - } + req.NoError(err) is.Equal(instAction.ReleaseName, name) is.Equal(chartName, chrt) instAction.GenerateName = true _, _, err = instAction.NameAndChart([]string{"foo", chartName}) - if err == nil { - t.Fatal("expected an error") - } - is.Equal("cannot set --generate-name and also specify a name", err.Error()) + req.Error(err, "expected an error") + req.EqualError(err, "cannot set --generate-name and also specify a name") instAction.GenerateName = false instAction.NameTemplate = "{{ . }}" _, _, err = instAction.NameAndChart([]string{"foo", chartName}) - if err == nil { - t.Fatal("expected an error") - } - is.Equal("cannot set --name-template and also specify a name", err.Error()) + req.Error(err, "expected an error") + req.EqualError(err, "cannot set --name-template and also specify a name") instAction.NameTemplate = "" instAction.ReleaseName = "" _, _, err = instAction.NameAndChart([]string{chartName}) - if err == nil { - t.Fatal("expected an error") - } - is.Equal("must either provide a name or specify --generate-name", err.Error()) + req.Error(err, "expected an error") + req.EqualError(err, "must either provide a name or specify --generate-name") instAction.NameTemplate = "" instAction.ReleaseName = "" _, _, err = instAction.NameAndChart([]string{"foo", chartName, "bar"}) - if err == nil { - t.Fatal("expected an error") - } - is.Equal("expected at most two arguments, unexpected arguments: bar", err.Error()) + req.Error(err, "expected an error") + is.EqualError(err, "expected at most two arguments, unexpected arguments: bar") } func TestNameAndChartGenerateName(t *testing.T) { @@ -1016,9 +961,7 @@ func TestNameAndChartGenerateName(t *testing.T) { t.Parallel() name, chrt, err := instAction.NameAndChart([]string{tc.Chart}) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) is.Equal(tc.ExpectedName, name) is.Equal(tc.Chart, chrt) @@ -1035,9 +978,7 @@ func TestInstallWithLabels(t *testing.T) { "key2": "val2", } resi, err := instAction.Run(buildChart(), nil) - if err != nil { - t.Fatalf("Failed install: %s", err) - } + req.NoError(err, "Failed install") res, err := releaserToV1Release(resi) req.NoError(err) @@ -1046,17 +987,15 @@ func TestInstallWithLabels(t *testing.T) { func TestInstallWithSystemLabels(t *testing.T) { is := assert.New(t) + req := require.New(t) instAction := installAction(t) instAction.Labels = map[string]string{ "owner": "val1", "key2": "val2", } _, err := instAction.Run(buildChart(), nil) - if err == nil { - t.Fatal("expected an error") - } - - is.Equal(fmt.Errorf("user supplied labels contains system reserved label name. System labels: %+v", driver.GetSystemLabels()), err) + req.Error(err, "expected an error") + is.EqualError(err, fmt.Sprintf("user supplied labels contains system reserved label name. System labels: %+v", driver.GetSystemLabels())) } func TestUrlEqual(t *testing.T) { @@ -1111,13 +1050,9 @@ func TestUrlEqual(t *testing.T) { t.Parallel() u1, err := url.Parse(tc.url1) - if err != nil { - t.Fatalf("Failed to parse URL1 %s: %v", tc.url1, err) - } + require.NoError(t, err, "Failed to parse URL1 %s", tc.url1) u2, err := url.Parse(tc.url2) - if err != nil { - t.Fatalf("Failed to parse URL2 %s: %v", tc.url2, err) - } + require.NoError(t, err, "Failed to parse URL2 %s", tc.url2) is.Equal(tc.expected, urlEqual(u1, u2)) }) @@ -1285,11 +1220,7 @@ func TestInstallCRDs_CheckNilErrors(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { instAction := installAction(t) - - err := instAction.installCRDs(tt.input) - if err == nil { - t.Error("got nil expected err") - } + assert.Error(t, instAction.installCRDs(tt.input), "got nil expected err") }) } } diff --git a/pkg/cmd/verify_test.go b/pkg/cmd/verify_test.go index 050d799c9..0b4078e1e 100644 --- a/pkg/cmd/verify_test.go +++ b/pkg/cmd/verify_test.go @@ -19,6 +19,9 @@ import ( "fmt" "runtime" "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestVerifyCmd(t *testing.T) { @@ -73,18 +76,11 @@ func TestVerifyCmd(t *testing.T) { t.Run(tt.name, func(t *testing.T) { _, out, err := executeActionCommand(tt.cmd) if tt.wantError { - if err == nil { - t.Errorf("Expected error, but got none: %q", out) - } - if err.Error() != tt.expect { - t.Errorf("Expected error %q, got %q", tt.expect, err) - } - return - } else if err != nil { - t.Errorf("Unexpected error: %s", err) - } - if out != tt.expect { - t.Errorf("Expected %q, got %q", tt.expect, out) + require.Error(t, err, "Expected error, but got none: %q", out) + assert.EqualError(t, err, tt.expect, "Expected error %q", tt.expect) + } else { + require.NoError(t, err) + assert.Equal(t, tt.expect, out, "Expected %q, got %q", tt.expect, out) } }) } diff --git a/pkg/provenance/sign_test.go b/pkg/provenance/sign_test.go index 79b33a970..32253df90 100644 --- a/pkg/provenance/sign_test.go +++ b/pkg/provenance/sign_test.go @@ -89,14 +89,10 @@ func loadChartMetadataForSigning(t *testing.T, chartPath string) []byte { t.Helper() chart, err := loader.LoadFile(chartPath) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) metadataBytes, err := yaml.Marshal(chart.Metadata) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) return metadataBytes } @@ -106,170 +102,116 @@ func TestMessageBlock(t *testing.T) { // Read the chart file data archiveData, err := os.ReadFile(testChartfile) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) out, err := messageBlock(archiveData, filepath.Base(testChartfile), metadataBytes) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) got := out.String() - if got != testMessageBlock { - t.Errorf("Expected:\n%q\nGot\n%q\n", testMessageBlock, got) - } + assert.Equal(t, testMessageBlock, got, "Expected:\n%q\nGot\n%q\n", testMessageBlock, got) } func TestParseMessageBlock(t *testing.T) { sc, err := parseMessageBlock([]byte(testMessageBlock)) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) // parseMessageBlock only returns checksums, not metadata (like upstream) - if lsc := len(sc.Files); lsc != 1 { - t.Errorf("Expected 1 file, got %d", lsc) - } + lsc := len(sc.Files) + assert.Equalf(t, 1, lsc, "Expected 1 file, got %d", lsc) - if hash, ok := sc.Files["hashtest-1.2.3.tgz"]; !ok { - t.Error("hashtest file not found in Files") - } else if hash != "sha256:c6841b3a895f1444a6738b5d04564a57e860ce42f8519c3be807fb6d9bee7888" { - t.Errorf("Unexpected hash: %q", hash) - } + hash, ok := sc.Files["hashtest-1.2.3.tgz"] + assert.True(t, ok, "hashtest file not found in Files") + assert.Equalf(t, "sha256:c6841b3a895f1444a6738b5d04564a57e860ce42f8519c3be807fb6d9bee7888", hash, "Unexpected hash: %q", hash) } func TestLoadKey(t *testing.T) { k, err := loadKey(testKeyfile) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if _, ok := k.Identities[testKeyName]; !ok { - t.Errorf("Expected to load a key for user %q", testKeyName) - } + _, ok := k.Identities[testKeyName] + assert.Truef(t, ok, "Expected to load a key for user %q", testKeyName) } func TestLoadKeyRing(t *testing.T) { k, err := loadKeyRing(testPubfile) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if len(k) > 1 { - t.Errorf("Expected 1, got %d", len(k)) - } + assert.LessOrEqualf(t, len(k), 1, "Expected 1, got %d", len(k)) for _, e := range k { - if ii, ok := e.Identities[testKeyName]; !ok { - t.Errorf("Expected %s in %v", testKeyName, ii) - } + ii, ok := e.Identities[testKeyName] + assert.Truef(t, ok, "Expected %s in %v", testKeyName, ii) } } func TestDigest(t *testing.T) { f, err := os.Open(testChartfile) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) defer f.Close() hash, err := Digest(f) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) sig, err := readSumFile(testSumfile) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if !strings.Contains(sig, hash) { - t.Errorf("Expected %s to be in %s", hash, sig) - } + assert.Contains(t, sig, hash, "Expected %s to be in %s", hash, sig) } func TestNewFromFiles(t *testing.T) { s, err := NewFromFiles(testKeyfile, testPubfile) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if _, ok := s.Entity.Identities[testKeyName]; !ok { - t.Errorf("Expected to load a key for user %q", testKeyName) - } + _, ok := s.Entity.Identities[testKeyName] + assert.Truef(t, ok, "Expected to load a key for user %q", testKeyName) } func TestDigestFile(t *testing.T) { hash, err := DigestFile(testChartfile) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) sig, err := readSumFile(testSumfile) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if !strings.Contains(sig, hash) { - t.Errorf("Expected %s to be in %s", hash, sig) - } + assert.Contains(t, sig, hash, "Expected %s to be in %s", hash, sig) } func TestDecryptKey(t *testing.T) { k, err := NewFromKeyring(testPasswordKeyfile, testPasswordKeyName) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if !k.Entity.PrivateKey.Encrypted { - t.Fatal("Key is not encrypted") - } + require.True(t, k.Entity.PrivateKey.Encrypted, "Key is not encrypted") // We give this a simple callback that returns the password. - if err := k.DecryptKey(func(_ string) ([]byte, error) { + require.NoError(t, k.DecryptKey(func(_ string) ([]byte, error) { return []byte("secret"), nil - }); err != nil { - t.Fatal(err) - } + })) // Re-read the key (since we already unlocked it) k, err = NewFromKeyring(testPasswordKeyfile, testPasswordKeyName) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) // Now we give it a bogus password. - if err := k.DecryptKey(func(_ string) ([]byte, error) { + require.Error(t, k.DecryptKey(func(_ string) ([]byte, error) { return []byte("secrets_and_lies"), nil - }); err == nil { - t.Fatal("Expected an error when giving a bogus passphrase") - } + }), "Expected an error when giving a bogus passphrase") } func TestClearSign(t *testing.T) { signer, err := NewFromFiles(testKeyfile, testPubfile) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) metadataBytes := loadChartMetadataForSigning(t, testChartfile) // Read the chart file data archiveData, err := os.ReadFile(testChartfile) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) sig, err := signer.ClearSign(archiveData, filepath.Base(testChartfile), metadataBytes) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) t.Logf("Sig:\n%s", sig) - if !strings.Contains(sig, testMessageBlock) { - t.Errorf("expected message block to be in sig: %s", sig) - } + assert.Contains(t, sig, testMessageBlock, "expected message block to be in sig: %s", sig) } func TestMixedKeyringRSASigningAndVerification(t *testing.T) { @@ -335,9 +277,7 @@ func (s failSigner) Sign(_ io.Reader, _ []byte, _ crypto.SignerOpts) ([]byte, er func TestClearSignError(t *testing.T) { signer, err := NewFromFiles(testKeyfile, testPubfile) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) // ensure that signing always fails signer.Entity.PrivateKey.PrivateKey = failSigner{} @@ -346,18 +286,11 @@ func TestClearSignError(t *testing.T) { // Read the chart file data archiveData, err := os.ReadFile(testChartfile) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) sig, err := signer.ClearSign(archiveData, filepath.Base(testChartfile), metadataBytes) - if err == nil { - t.Fatal("didn't get an error from ClearSign but expected one") - } - - if sig != "" { - t.Fatalf("expected an empty signature after failed ClearSign but got %q", sig) - } + require.Error(t, err, "didn't get an error from ClearSign but expected one") + assert.Empty(t, sig, "expected an empty signature after failed ClearSign but got %q", sig) } func TestVerify(t *testing.T) { @@ -386,7 +319,7 @@ func TestVerify(t *testing.T) { require.Errorf(t, err, "Expected %s to fail.", testTamperedSigBlock) var sErr pgperrors.SignatureError - if assert.ErrorAs(t, err, &sErr, "Expected invalid signature error, got %q (%T)", err, err) { + if assert.ErrorAs(t, err, &sErr, "Expected invalid signature error") { t.Logf("Tampered sig block error: %s (%T)", sErr, sErr) } } From aae82bf97a4c02c70982c14118912c459db43ec9 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 20:50:57 +0200 Subject: [PATCH 32/61] chore(pkg): refactor: convert tests to testify assert/require part 13 refactor: convert tests to testify assert/require in pkg Signed-off-by: Matthieu MOREL --- pkg/action/pull_test.go | 4 +- pkg/chart/v2/lint/rules/chartfile_test.go | 161 +++++----------------- pkg/cmd/search/search_test.go | 75 ++++------ pkg/pusher/ocipusher_test.go | 160 ++++++--------------- 4 files changed, 100 insertions(+), 300 deletions(-) diff --git a/pkg/action/pull_test.go b/pkg/action/pull_test.go index 7cd5d3e85..a483de248 100644 --- a/pkg/action/pull_test.go +++ b/pkg/action/pull_test.go @@ -48,9 +48,7 @@ func TestPullSetRegistryClient(t *testing.T) { func TestPullRun_ChartNotFound(t *testing.T) { srv, err := startLocalServerForTests(t, nil) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) defer srv.Close() config := actionConfigFixture(t) diff --git a/pkg/chart/v2/lint/rules/chartfile_test.go b/pkg/chart/v2/lint/rules/chartfile_test.go index c9e202770..7c9f1c422 100644 --- a/pkg/chart/v2/lint/rules/chartfile_test.go +++ b/pkg/chart/v2/lint/rules/chartfile_test.go @@ -20,9 +20,11 @@ import ( "errors" "os" "path/filepath" - "strings" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + chart "helm.sh/helm/v4/pkg/chart/v2" "helm.sh/helm/v4/pkg/chart/v2/lint/support" chartutil "helm.sh/helm/v4/pkg/chart/v2/util" @@ -47,35 +49,17 @@ var badChartName, _ = chartutil.LoadChartfile(badChartNamePath) func TestValidateChartYamlNotDirectory(t *testing.T) { _ = os.Mkdir(nonExistingChartFilePath, os.ModePerm) defer os.Remove(nonExistingChartFilePath) - - err := validateChartYamlNotDirectory(nonExistingChartFilePath) - if err == nil { - t.Error("validateChartYamlNotDirectory to return a linter error, got no error") - } + assert.Error(t, validateChartYamlNotDirectory(nonExistingChartFilePath), "validateChartYamlNotDirectory to return a linter error, got no error") } func TestValidateChartYamlFormat(t *testing.T) { - err := validateChartYamlFormat(errors.New("Read error")) - if err == nil { - t.Error("validateChartYamlFormat to return a linter error, got no error") - } - - err = validateChartYamlFormat(nil) - if err != nil { - t.Error("validateChartYamlFormat to return no error, got a linter error") - } + require.Error(t, validateChartYamlFormat(errors.New("Read error")), "validateChartYamlFormat to return a linter error, got no error") + assert.NoError(t, validateChartYamlFormat(nil), "validateChartYamlFormat to return no error, got a linter error") } func TestValidateChartName(t *testing.T) { - err := validateChartName(badChart) - if err == nil { - t.Error("validateChartName to return a linter error, got no error") - } - - err = validateChartName(badChartName) - if err == nil { - t.Error("expected validateChartName to return a linter error for an invalid name, got no error") - } + require.Error(t, validateChartName(badChart), "validateChartName to return a linter error, got no error") + assert.Error(t, validateChartName(badChartName), "expected validateChartName to return a linter error for an invalid name, got no error") } func TestValidateChartVersion(t *testing.T) { @@ -93,18 +77,12 @@ func TestValidateChartVersion(t *testing.T) { for _, test := range failTest { badChart.Version = test.Version - err := validateChartVersion(badChart) - if err == nil || !strings.Contains(err.Error(), test.ErrorMsg) { - t.Errorf("validateChartVersion(%s) to return \"%s\", got no error", test.Version, test.ErrorMsg) - } + require.ErrorContainsf(t, validateChartVersion(badChart), test.ErrorMsg, "validateChartVersion(%s) to return \"%s\", got no error", test.Version, test.ErrorMsg) } for _, version := range successTest { badChart.Version = version - err := validateChartVersion(badChart) - if err != nil { - t.Errorf("validateChartVersion(%s) to return no error, got a linter error", version) - } + assert.NoError(t, validateChartVersion(badChart), "validateChartVersion(%s) to return no error, got a linter error", version) } } @@ -122,18 +100,12 @@ func TestValidateChartVersionStrictSemVerV2(t *testing.T) { for _, test := range failTest { badChart.Version = test.Version - err := validateChartVersionStrictSemVerV2(badChart) - if err == nil || !strings.Contains(err.Error(), test.ErrorMsg) { - t.Errorf("validateChartVersionStrictSemVerV2(%s) to return \"%s\", got no error", test.Version, test.ErrorMsg) - } + require.ErrorContainsf(t, validateChartVersionStrictSemVerV2(badChart), test.ErrorMsg, "validateChartVersionStrictSemVerV2(%s) to return \"%s\", got no error", test.Version, test.ErrorMsg) } for _, version := range successTest { badChart.Version = version - err := validateChartVersionStrictSemVerV2(badChart) - if err != nil { - t.Errorf("validateChartVersionStrictSemVerV2(%s) to return no error, got a linter error", version) - } + assert.NoError(t, validateChartVersionStrictSemVerV2(badChart), "validateChartVersionStrictSemVerV2(%s) to return no error, got a linter error", version) } } @@ -158,29 +130,17 @@ func TestValidateChartMaintainer(t *testing.T) { for _, test := range failTest { badChart.Maintainers = []*chart.Maintainer{{Name: test.Name, Email: test.Email}} - err := validateChartMaintainer(badChart) - if err == nil || !strings.Contains(err.Error(), test.ErrorMsg) { - t.Errorf("validateChartMaintainer(%s, %s) to return \"%s\", got no error", test.Name, test.Email, test.ErrorMsg) - } + require.ErrorContainsf(t, validateChartMaintainer(badChart), test.ErrorMsg, "validateChartMaintainer(%s, %s) to return \"%s\", got no error", test.Name, test.Email, test.ErrorMsg) } for _, test := range successTest { badChart.Maintainers = []*chart.Maintainer{{Name: test.Name, Email: test.Email}} - err := validateChartMaintainer(badChart) - if err != nil { - t.Errorf("validateChartMaintainer(%s, %s) to return no error, got %s", test.Name, test.Email, err.Error()) - } + require.NoError(t, validateChartMaintainer(badChart), "validateChartMaintainer(%s, %s)", test.Name, test.Email) } // Testing for an empty maintainer badChart.Maintainers = []*chart.Maintainer{nil} - err := validateChartMaintainer(badChart) - if err == nil { - t.Error("validateChartMaintainer did not return error for nil maintainer as expected") - } - if err.Error() != "a maintainer entry is empty" { - t.Errorf("validateChartMaintainer returned unexpected error for nil maintainer: %s", err.Error()) - } + assert.EqualError(t, validateChartMaintainer(badChart), "a maintainer entry is empty") } func TestValidateChartSources(t *testing.T) { @@ -188,18 +148,12 @@ func TestValidateChartSources(t *testing.T) { var successTest = []string{"http://riverrun.io", "https://riverrun.io", "https://riverrun.io/blackfish"} for _, test := range failTest { badChart.Sources = []string{test} - err := validateChartSources(badChart) - if err == nil || !strings.Contains(err.Error(), "invalid source URL") { - t.Errorf("validateChartSources(%s) to return \"invalid source URL\", got no error", test) - } + require.ErrorContainsf(t, validateChartSources(badChart), "invalid source URL", "validateChartSources(%s) to return \"invalid source URL\", got no error", test) } for _, test := range successTest { badChart.Sources = []string{test} - err := validateChartSources(badChart) - if err != nil { - t.Errorf("validateChartSources(%s) to return no error, got %s", test, err.Error()) - } + assert.NoError(t, validateChartSources(badChart), "validateChartSources(%s) to return no error", test) } } @@ -209,24 +163,13 @@ func TestValidateChartIconPresence(t *testing.T) { Icon: "", } - err := validateChartIconPresence(testChart) - - if err == nil { - t.Error("validateChartIconPresence to return a linter error, got no error") - } else if !strings.Contains(err.Error(), "icon is recommended") { - t.Errorf("expected %q, got %q", "icon is recommended", err.Error()) - } + assert.ErrorContainsf(t, validateChartIconPresence(testChart), "icon is recommended", "expected %q", "icon is recommended") }) t.Run("Icon present", func(t *testing.T) { testChart := &chart.Metadata{ Icon: "http://example.org/icon.png", } - - err := validateChartIconPresence(testChart) - - if err != nil { - t.Errorf("Unexpected error: %q", err.Error()) - } + assert.NoError(t, validateChartIconPresence(testChart)) }) } @@ -235,18 +178,12 @@ func TestValidateChartIconURL(t *testing.T) { var successTest = []string{"http://riverrun.io", "https://riverrun.io", "https://riverrun.io/blackfish.png"} for _, test := range failTest { badChart.Icon = test - err := validateChartIconURL(badChart) - if err == nil || !strings.Contains(err.Error(), "invalid icon URL") { - t.Errorf("validateChartIconURL(%s) to return \"invalid icon URL\", got no error", test) - } + require.ErrorContainsf(t, validateChartIconURL(badChart), "invalid icon URL", "validateChartIconURL(%s) to return \"invalid icon URL\", got no error", test) } for _, test := range successTest { badChart.Icon = test - err := validateChartSources(badChart) - if err != nil { - t.Errorf("validateChartIconURL(%s) to return no error, got %s", test, err.Error()) - } + assert.NoError(t, validateChartSources(badChart), "validateChartIconURL(%s) to return no error", test) } } @@ -257,37 +194,15 @@ func TestChartfile(t *testing.T) { msgs := linter.Messages expectedNumberOfErrorMessages := 7 - if len(msgs) != expectedNumberOfErrorMessages { - t.Errorf("Expected %d errors, got %d", expectedNumberOfErrorMessages, len(msgs)) - return - } - - if !strings.Contains(msgs[0].Err.Error(), "name is required") { - t.Errorf("Unexpected message 0: %s", msgs[0].Err) - } - - if !strings.Contains(msgs[1].Err.Error(), "apiVersion is required. The value must be either \"v1\" or \"v2\"") { - t.Errorf("Unexpected message 1: %s", msgs[1].Err) - } - - if !strings.Contains(msgs[2].Err.Error(), "version '0.0.0.0' is not a valid SemVer") { - t.Errorf("Unexpected message 2: %s", msgs[2].Err) - } - - if !strings.Contains(msgs[3].Err.Error(), "icon is recommended") { - t.Errorf("Unexpected message 3: %s", msgs[3].Err) - } - - if !strings.Contains(msgs[4].Err.Error(), "chart type is not valid in apiVersion") { - t.Errorf("Unexpected message 4: %s", msgs[4].Err) - } + require.Lenf(t, msgs, expectedNumberOfErrorMessages, "Expected %d errors, got %d", expectedNumberOfErrorMessages, len(msgs)) - if !strings.Contains(msgs[5].Err.Error(), "dependencies are not valid in the Chart file with apiVersion") { - t.Errorf("Unexpected message 5: %s", msgs[5].Err) - } - if !strings.Contains(msgs[6].Err.Error(), "version '0.0.0.0' is not a valid SemVerV2") { - t.Errorf("Unexpected message 6: %s", msgs[6].Err) - } + require.ErrorContains(t, msgs[0].Err, "name is required", "Unexpected message 0: %s", msgs[0].Err) + require.ErrorContains(t, msgs[1].Err, "apiVersion is required. The value must be either \"v1\" or \"v2\"", "Unexpected message 1: %s", msgs[1].Err) + require.ErrorContains(t, msgs[2].Err, "version '0.0.0.0' is not a valid SemVer", "Unexpected message 2: %s", msgs[2].Err) + require.ErrorContains(t, msgs[3].Err, "icon is recommended", "Unexpected message 3: %s", msgs[3].Err) + require.ErrorContains(t, msgs[4].Err, "chart type is not valid in apiVersion", "Unexpected message 4: %s", msgs[4].Err) + require.ErrorContains(t, msgs[5].Err, "dependencies are not valid in the Chart file with apiVersion", "Unexpected message 5: %s", msgs[5].Err) + assert.ErrorContains(t, msgs[6].Err, "version '0.0.0.0' is not a valid SemVerV2", "Unexpected message 6: %s", msgs[6].Err) }) t.Run("Chart.yaml validity issues due to type mismatch", func(t *testing.T) { @@ -301,19 +216,9 @@ func TestChartfile(t *testing.T) { return } - if !strings.Contains(msgs[0].Err.Error(), "version should be of type string") { - t.Errorf("Unexpected message 0: %s", msgs[0].Err) - } - - if !strings.Contains(msgs[1].Err.Error(), "version '7.2445e+06' is not a valid SemVer") { - t.Errorf("Unexpected message 1: %s", msgs[1].Err) - } - - if !strings.Contains(msgs[2].Err.Error(), "appVersion should be of type string") { - t.Errorf("Unexpected message 2: %s", msgs[2].Err) - } - if !strings.Contains(msgs[3].Err.Error(), "version '7.2445e+06' is not a valid SemVerV2") { - t.Errorf("Unexpected message 3: %s", msgs[3].Err) - } + require.ErrorContains(t, msgs[0].Err, "version should be of type string", "Unexpected message 0: %s", msgs[0].Err) + require.ErrorContains(t, msgs[1].Err, "version '7.2445e+06' is not a valid SemVer", "Unexpected message 1: %s", msgs[1].Err) + require.ErrorContains(t, msgs[2].Err, "appVersion should be of type string", "Unexpected message 2: %s", msgs[2].Err) + assert.ErrorContains(t, msgs[3].Err, "version '7.2445e+06' is not a valid SemVerV2", "Unexpected message 3: %s", msgs[3].Err) }) } diff --git a/pkg/cmd/search/search_test.go b/pkg/cmd/search/search_test.go index 46394e77f..f8c9504d1 100644 --- a/pkg/cmd/search/search_test.go +++ b/pkg/cmd/search/search_test.go @@ -20,6 +20,9 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + chart "helm.sh/helm/v4/pkg/chart/v2" "helm.sh/helm/v4/pkg/repo/v1" ) @@ -40,24 +43,16 @@ func TestSortScore(t *testing.T) { // Test Score for i := range expectScore { - if expectScore[i] != in[i].Score { - t.Errorf("Sort error on index %d: expected %d, got %d", i, expectScore[i], in[i].Score) - } + assert.Equalf(t, expectScore[i], in[i].Score, "Sort error on index %d: expected %d, got %d", i, expectScore[i], in[i].Score) } // Test Name for i := range expect { - if expect[i] != in[i].Name { - t.Errorf("Sort error: expected %s, got %s", expect[i], in[i].Name) - } + assert.Equalf(t, expect[i], in[i].Name, "Sort error: expected %s, got %s", expect[i], in[i].Name) } // Test version of last two items - if in[5].Chart.Version != "1.2.4" { - t.Errorf("Expected 1.2.4, got %s", in[5].Chart.Version) - } - if in[6].Chart.Version != "1.2.3" { - t.Error("Expected 1.2.3 to be last") - } + assert.Equalf(t, "1.2.4", in[5].Chart.Version, "Expected 1.2.4, got %s", in[5].Chart.Version) + assert.Equal(t, "1.2.3", in[6].Chart.Version, "Expected 1.2.3 to be last") } var indexfileEntries = map[string]repo.ChartVersions{ @@ -122,30 +117,22 @@ func loadTestIndex(_ *testing.T, all bool) *Index { func TestAll(t *testing.T) { i := loadTestIndex(t, false) all := i.All() - if len(all) != 4 { - t.Errorf("Expected 4 entries, got %d", len(all)) - } + assert.Lenf(t, all, 4, "Expected 4 entries, got %d", len(all)) i = loadTestIndex(t, true) all = i.All() - if len(all) != 5 { - t.Errorf("Expected 5 entries, got %d", len(all)) - } + assert.Lenf(t, all, 5, "Expected 5 entries, got %d", len(all)) } func TestAddRepo_Sort(t *testing.T) { i := loadTestIndex(t, true) sr, err := i.Search("TESTING/SANTA-MARIA", 100, false) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) SortScore(sr) ch := sr[0] expect := "1.2.3" - if ch.Chart.Version != expect { - t.Errorf("Expected %q, got %q", expect, ch.Chart.Version) - } + assert.Equalf(t, ch.Chart.Version, expect, "Expected %q, got %q", expect, ch.Chart.Version) } func TestSearchByName(t *testing.T) { @@ -247,9 +234,7 @@ func TestSearchByName(t *testing.T) { charts, err := i.Search(tt.query, 100, tt.regexp) if err != nil { if tt.fail { - if !strings.Contains(err.Error(), tt.failMsg) { - t.Fatalf("Unexpected error message: %s", err) - } + require.ErrorContains(t, err, tt.failMsg) return } t.Fatalf("%s: %s", tt.name, err) @@ -258,9 +243,7 @@ func TestSearchByName(t *testing.T) { SortScore(charts) l := len(charts) - if l != len(tt.expect) { - t.Fatalf("Expected %d result, got %d", len(tt.expect), l) - } + require.Lenf(t, tt.expect, l, "Expected %d result, got %d", len(tt.expect), l) // For empty result sets, just keep going. if l == 0 { return @@ -268,9 +251,7 @@ func TestSearchByName(t *testing.T) { for i, got := range charts { ex := tt.expect[i] - if got.Name != ex.Name { - t.Errorf("[%d]: Expected name %q, got %q", i, ex.Name, got.Name) - } + assert.Equalf(t, got.Name, ex.Name, "[%d]: Expected name %q, got %q", i, ex.Name, got.Name) } }) } @@ -280,12 +261,8 @@ func TestSearchByNameAll(t *testing.T) { // Test with the All bit turned on. i := loadTestIndex(t, true) cs, err := i.Search("santa-maria", 100, false) - if err != nil { - t.Fatal(err) - } - if len(cs) != 2 { - t.Errorf("expected 2 charts, got %d", len(cs)) - } + require.NoError(t, err) + assert.Lenf(t, cs, 2, "expected 2 charts, got %d", len(cs)) } func TestCalcScore(t *testing.T) { @@ -293,16 +270,12 @@ func TestCalcScore(t *testing.T) { fields := []string{"aaa", "bbb", "ccc", "ddd"} matchline := strings.Join(fields, sep) - if r := i.calcScore(2, matchline); r != 0 { - t.Errorf("Expected 0, got %d", r) - } - if r := i.calcScore(5, matchline); r != 1 { - t.Errorf("Expected 1, got %d", r) - } - if r := i.calcScore(10, matchline); r != 2 { - t.Errorf("Expected 2, got %d", r) - } - if r := i.calcScore(14, matchline); r != 3 { - t.Errorf("Expected 3, got %d", r) - } + r := i.calcScore(2, matchline) + assert.Equalf(t, 0, r, "Expected 0, got %d", r) + r = i.calcScore(5, matchline) + assert.Equalf(t, 1, r, "Expected 1, got %d", r) + r = i.calcScore(10, matchline) + assert.Equalf(t, 2, r, "Expected 2, got %d", r) + r = i.calcScore(14, matchline) + assert.Equalf(t, 3, r, "Expected 3, got %d", r) } diff --git a/pkg/pusher/ocipusher_test.go b/pkg/pusher/ocipusher_test.go index a4542500a..ceb61d442 100644 --- a/pkg/pusher/ocipusher_test.go +++ b/pkg/pusher/ocipusher_test.go @@ -21,9 +21,9 @@ import ( "io" "os" "path/filepath" - "strings" "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "helm.sh/helm/v4/pkg/registry" @@ -31,13 +31,10 @@ import ( func TestNewOCIPusher(t *testing.T) { p, err := NewOCIPusher() - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if _, ok := p.(*OCIPusher); !ok { - t.Fatal("Expected NewOCIPusher to produce an *OCIPusher") - } + _, ok := p.(*OCIPusher) + require.True(t, ok, "Expected NewOCIPusher to produce an *OCIPusher") cd := "../../testdata" join := filepath.Join @@ -51,55 +48,28 @@ func TestNewOCIPusher(t *testing.T) { WithInsecureSkipTLSVerify(insecureSkipTLSVerify), WithPlainHTTP(plainHTTP), ) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) op, ok := p.(*OCIPusher) - if !ok { - t.Fatal("Expected NewOCIPusher to produce an *OCIPusher") - } - - if op.opts.certFile != pub { - t.Errorf("Expected NewOCIPusher to contain %q as the public key file, got %q", pub, op.opts.certFile) - } - - if op.opts.keyFile != priv { - t.Errorf("Expected NewOCIPusher to contain %q as the private key file, got %q", priv, op.opts.keyFile) - } - - if op.opts.caFile != ca { - t.Errorf("Expected NewOCIPusher to contain %q as the CA file, got %q", ca, op.opts.caFile) - } - - if op.opts.plainHTTP != plainHTTP { - t.Errorf("Expected NewOCIPusher to have plainHTTP as %t, got %t", plainHTTP, op.opts.plainHTTP) - } - - if op.opts.insecureSkipTLSVerify != insecureSkipTLSVerify { - t.Errorf("Expected NewOCIPusher to have insecureSkipVerifyTLS as %t, got %t", insecureSkipTLSVerify, op.opts.insecureSkipTLSVerify) - } + require.True(t, ok, "Expected NewOCIPusher to produce an *OCIPusher") + assert.Equal(t, pub, op.opts.certFile, "Expected NewOCIPusher to contain %q as the public key file, got %q", pub, op.opts.certFile) + assert.Equal(t, priv, op.opts.keyFile, "Expected NewOCIPusher to contain %q as the private key file, got %q", priv, op.opts.keyFile) + assert.Equal(t, ca, op.opts.caFile, "Expected NewOCIPusher to contain %q as the CA file, got %q", ca, op.opts.caFile) + assert.Equal(t, plainHTTP, op.opts.plainHTTP, "Expected NewOCIPusher to have plainHTTP as %t, got %t", plainHTTP, op.opts.plainHTTP) + assert.Equal(t, insecureSkipTLSVerify, op.opts.insecureSkipTLSVerify, "Expected NewOCIPusher to have insecureSkipVerifyTLS as %t, got %t", insecureSkipTLSVerify, op.opts.insecureSkipTLSVerify) // Test if setting registryClient is being passed to the ops registryClient, err := registry.NewClient() - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) p, err = NewOCIPusher( WithRegistryClient(registryClient), ) - if err != nil { - t.Fatal(err) - } - op, ok = p.(*OCIPusher) - if !ok { - t.Fatal("expected NewOCIPusher to produce an *OCIPusher") - } + require.NoError(t, err) - if op.opts.registryClient != registryClient { - t.Errorf("Expected NewOCIPusher to contain %p as RegistryClient, got %p", registryClient, op.opts.registryClient) - } + op, ok = p.(*OCIPusher) + require.True(t, ok, "expected NewOCIPusher to produce an *OCIPusher") + assert.Equal(t, registryClient, op.opts.registryClient, "Expected NewOCIPusher to contain %p as RegistryClient, got %p", registryClient, op.opts.registryClient) } func TestOCIPusher_Push_ErrorHandling(t *testing.T) { @@ -127,23 +97,13 @@ func TestOCIPusher_Push_ErrorHandling(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { pusher, err := NewOCIPusher() - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) chartRef := tt.chartRef if tt.setupFunc != nil { chartRef = tt.setupFunc() } - - err = pusher.Push(chartRef, "oci://localhost:5000/test") - if err == nil { - t.Fatal("Expected error but got none") - } - - if !strings.Contains(err.Error(), tt.expectedError) { - t.Errorf("Expected error containing %q, got %q", tt.expectedError, err.Error()) - } + assert.ErrorContains(t, pusher.Push(chartRef, "oci://localhost:5000/test"), tt.expectedError) }) } } @@ -227,30 +187,20 @@ func TestOCIPusher_newRegistryClient(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { pusher, err := NewOCIPusher(tt.opts...) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) op, ok := pusher.(*OCIPusher) - if !ok { - t.Fatal("Expected *OCIPusher") - } + require.True(t, ok, "Expected *OCIPusher") client, err := op.newRegistryClient() if tt.expectError { - if err == nil { - t.Fatal("Expected error but got none") - } - if tt.errorContains != "" && !strings.Contains(err.Error(), tt.errorContains) { - t.Errorf("Expected error containing %q, got %q", tt.errorContains, err.Error()) + require.Error(t, err, "Expected error but got none") + if tt.errorContains != "" { + require.ErrorContainsf(t, err, tt.errorContains, "Expected error containing %q, got %q", tt.errorContains, err.Error()) } } else { - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - if client == nil { - t.Fatal("Expected non-nil registry client") - } + require.NoError(t, err) + require.NotNil(t, client, "Expected non-nil registry client") } }) } @@ -287,25 +237,18 @@ func TestOCIPusher_Push_ChartOperations(t *testing.T) { // Copy a valid chart src, err := os.Open(chartPath) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) defer src.Close() dst, err := os.Create(tempChart) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if _, err := io.Copy(dst, src); err != nil { - t.Fatal(err) - } + _, err = io.Copy(dst, src) + require.NoError(t, err) dst.Close() // Make the file unreadable - if err := os.Chmod(tempChart, 0o000); err != nil { - t.Fatal(err) - } + require.NoError(t, os.Chmod(tempChart, 0o000)) return tempChart, func() { os.Chmod(tempChart, 0o644) // Restore permissions for cleanup @@ -328,25 +271,18 @@ func TestOCIPusher_Push_ChartOperations(t *testing.T) { // Copy chart file src, err := os.Open(chartWithProvPath) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) defer src.Close() dst, err := os.Create(tempChart) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if _, err := io.Copy(dst, src); err != nil { - t.Fatal(err) - } + _, err = io.Copy(dst, src) + require.NoError(t, err) dst.Close() // Create provenance file - if err := os.WriteFile(tempProv, []byte("test provenance data"), 0o644); err != nil { - t.Fatal(err) - } + require.NoError(t, os.WriteFile(tempProv, []byte("test provenance data"), 0o644)) return tempChart, func() {} }, @@ -373,9 +309,7 @@ func TestOCIPusher_Push_ChartOperations(t *testing.T) { } pusher, err := NewOCIPusher(tt.options...) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) err = pusher.Push(chartRef, tt.href) @@ -400,27 +334,17 @@ func TestOCIPusher_Push_MultipleOptions(t *testing.T) { } pusher, err := NewOCIPusher() - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) // Test that multiple options are applied correctly - err = pusher.Push(chartPath, "oci://localhost:5000/test", + // We expect an error since we're not actually pushing to a registry + require.Error(t, pusher.Push(chartPath, "oci://localhost:5000/test", WithPlainHTTP(true), WithInsecureSkipTLSVerify(true), - ) - - // We expect an error since we're not actually pushing to a registry - if err == nil { - t.Fatal("Expected error when pushing without a valid registry") - } + ), "Expected error when pushing without a valid registry") // Verify options were applied op := pusher.(*OCIPusher) - if !op.opts.plainHTTP { - t.Error("Expected plainHTTP option to be applied") - } - if !op.opts.insecureSkipTLSVerify { - t.Error("Expected insecureSkipTLSVerify option to be applied") - } + assert.True(t, op.opts.plainHTTP, "Expected plainHTTP option to be applied") + assert.True(t, op.opts.insecureSkipTLSVerify, "Expected insecureSkipTLSVerify option to be applied") } From dc66ee7be786b1ac146a21fb2114b9678aaf25a4 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 20:50:56 +0200 Subject: [PATCH 33/61] chore(pkg): refactor: convert tests to testify assert/require part 14 refactor: convert tests to testify assert/require in pkg/storage/driver Signed-off-by: Matthieu MOREL --- pkg/chart/v2/metadata_test.go | 20 ++-- pkg/downloader/chart_downloader_test.go | 129 ++++++++---------------- pkg/storage/driver/secrets_test.go | 115 ++++++--------------- pkg/storage/driver/sql_test.go | 128 +++++++---------------- 4 files changed, 112 insertions(+), 280 deletions(-) diff --git a/pkg/chart/v2/metadata_test.go b/pkg/chart/v2/metadata_test.go index 63dd99e52..720ca4886 100644 --- a/pkg/chart/v2/metadata_test.go +++ b/pkg/chart/v2/metadata_test.go @@ -16,8 +16,10 @@ limitations under the License. package v2 import ( - "errors" "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestValidate(t *testing.T) { @@ -192,21 +194,13 @@ func TestValidate(t *testing.T) { for _, tt := range tests { result := tt.md.Validate() - if !errors.Is(result, tt.err) { - t.Errorf("expected %q, got %q in test %q", tt.err, result, tt.name) - } + assert.ErrorIs(t, result, tt.err, "expected %q, got %q in test %q", tt.err, result, tt.name) } } func TestValidate_sanitize(t *testing.T) { md := &Metadata{APIVersion: "v2", Name: "test", Version: "1.0", Description: "\adescr\u0081iption\rtest", Maintainers: []*Maintainer{{Name: "\r"}}} - if err := md.Validate(); err != nil { - t.Fatalf("unexpected error: %s", err) - } - if md.Description != "description test" { - t.Fatalf("description was not sanitized: %q", md.Description) - } - if md.Maintainers[0].Name != " " { - t.Fatal("maintainer name was not sanitized") - } + require.NoError(t, md.Validate()) + require.Equal(t, "description test", md.Description, "description was not sanitized: %q", md.Description) + require.Equal(t, " ", md.Maintainers[0].Name, "maintainer name was not sanitized") } diff --git a/pkg/downloader/chart_downloader_test.go b/pkg/downloader/chart_downloader_test.go index a4de2f5e3..7187bdff1 100644 --- a/pkg/downloader/chart_downloader_test.go +++ b/pkg/downloader/chart_downloader_test.go @@ -18,7 +18,6 @@ package downloader import ( "crypto/sha256" "encoding/hex" - "errors" "os" "path/filepath" "testing" @@ -69,9 +68,7 @@ func TestResolveChartRef(t *testing.T) { // Create a mock registry client for OCI references registryClient, err := registry.NewClient() - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) c := ChartDownloader{ Out: os.Stderr, @@ -93,9 +90,8 @@ func TestResolveChartRef(t *testing.T) { t.Errorf("%s: failed with error %q", tt.name, err) continue } - if got := u.String(); got != tt.expect { - t.Errorf("%s: expected %s, got %s", tt.name, tt.expect, got) - } + got := u.String() + assert.Equalf(t, tt.expect, got, "%s: expected %s, got %s", tt.name, tt.expect, got) } } @@ -162,14 +158,10 @@ func TestResolveChartOpts(t *testing.T) { func TestVerifyChart(t *testing.T) { v, err := VerifyChart("testdata/signtest-0.1.0.tgz", "testdata/signtest-0.1.0.tgz.prov", "testdata/helm-test-key.pub") - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) // The verification is tested at length in the provenance package. Here, // we just want a quick sanity check that the v is not empty. - if v.FileHash == "" { - t.Error("Digest missing") - } + assert.NotEmpty(t, v.FileHash, "Digest missing") } func TestIsTar(t *testing.T) { @@ -183,9 +175,7 @@ func TestIsTar(t *testing.T) { } for src, expect := range tests { - if isTar(src) != expect { - t.Errorf("%q should be %t", src, expect) - } + assert.Equal(t, expect, isTar(src), "%q should be %t", src, expect) } } @@ -196,13 +186,8 @@ func TestDownloadTo(t *testing.T) { repotest.WithMiddleware(repotest.BasicAuthMiddleware(t)), ) defer srv.Stop() - if err := srv.CreateIndex(); err != nil { - t.Fatal(err) - } - - if err := srv.LinkIndices(); err != nil { - t.Fatal(err) - } + require.NoError(t, srv.CreateIndex()) + require.NoError(t, srv.LinkIndices()) contentCache := t.TempDir() @@ -226,21 +211,14 @@ func TestDownloadTo(t *testing.T) { cname := "/signtest-0.1.0.tgz" dest := srv.Root() where, v, err := c.DownloadTo(srv.URL()+cname, "", dest) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if expect := filepath.Join(dest, cname); where != expect { - t.Errorf("Expected download to %s, got %s", expect, where) - } - - if v.FileHash == "" { - t.Error("File hash was empty, but verification is required.") - } + expect := filepath.Join(dest, cname) + assert.Equalf(t, expect, where, "Expected download to %s, got %s", expect, where) + assert.NotEmpty(t, v.FileHash, "File hash was empty, but verification is required.") - if _, err := os.Stat(filepath.Join(dest, cname)); err != nil { - t.Error(err) - } + _, err = os.Stat(filepath.Join(dest, cname)) + assert.NoError(t, err) } func TestDownloadTo_TLS(t *testing.T) { @@ -251,12 +229,8 @@ func TestDownloadTo_TLS(t *testing.T) { repotest.WithTLSConfig(repotest.MakeTestTLSConfig(t, "../../testdata")), ) defer srv.Stop() - if err := srv.CreateIndex(); err != nil { - t.Fatal(err) - } - if err := srv.LinkIndices(); err != nil { - t.Fatal(err) - } + require.NoError(t, srv.CreateIndex()) + require.NoError(t, srv.LinkIndices()) repoConfig := filepath.Join(srv.Root(), "repositories.yaml") repoCache := srv.Root() @@ -285,22 +259,15 @@ func TestDownloadTo_TLS(t *testing.T) { cname := "test/signtest" dest := srv.Root() where, v, err := c.DownloadTo(cname, "", dest) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) target := filepath.Join(dest, "signtest-0.1.0.tgz") - if expect := target; where != expect { - t.Errorf("Expected download to %s, got %s", expect, where) - } + expect := target + assert.Equalf(t, expect, where, "Expected download to %s, got %s", expect, where) + assert.NotEmpty(t, v.FileHash, "File hash was empty, but verification is required.") - if v.FileHash == "" { - t.Error("File hash was empty, but verification is required.") - } - - if _, err := os.Stat(target); err != nil { - t.Error(err) - } + _, err = os.Stat(target) + assert.NoError(t, err) } func TestDownloadTo_VerifyLater(t *testing.T) { @@ -314,9 +281,7 @@ func TestDownloadTo_VerifyLater(t *testing.T) { repotest.WithChartSourceGlob("testdata/*.tgz*"), ) defer srv.Stop() - if err := srv.LinkIndices(); err != nil { - t.Fatal(err) - } + require.NoError(t, srv.LinkIndices()) contentCache := t.TempDir() c := ChartDownloader{ @@ -333,20 +298,16 @@ func TestDownloadTo_VerifyLater(t *testing.T) { } cname := "/signtest-0.1.0.tgz" where, _, err := c.DownloadTo(srv.URL()+cname, "", dest) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if expect := filepath.Join(dest, cname); where != expect { - t.Errorf("Expected download to %s, got %s", expect, where) - } + expect := filepath.Join(dest, cname) + assert.Equalf(t, expect, where, "Expected download to %s, got %s", expect, where) - if _, err := os.Stat(filepath.Join(dest, cname)); err != nil { - t.Fatal(err) - } - if _, err := os.Stat(filepath.Join(dest, cname+".prov")); err != nil { - t.Fatal(err) - } + _, err = os.Stat(filepath.Join(dest, cname)) + require.NoError(t, err) + + _, err = os.Stat(filepath.Join(dest, cname+".prov")) + require.NoError(t, err) } func TestScanReposForURL(t *testing.T) { @@ -363,24 +324,17 @@ func TestScanReposForURL(t *testing.T) { u := "http://example.com/alpine-0.2.0.tgz" rf, err := repo.LoadFile(repoConfig) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) entry, err := c.scanReposForURL(u, rf) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if entry.Name != "testing" { - t.Errorf("Unexpected repo %q for URL %q", entry.Name, u) - } + assert.Equal(t, "testing", entry.Name, "Unexpected repo %q for URL %q", entry.Name, u) // A lookup failure should produce an ErrNoOwnerRepo u = "https://no.such.repo/foo/bar-1.23.4.tgz" - if _, err = c.scanReposForURL(u, rf); !errors.Is(err, ErrNoOwnerRepo) { - t.Fatalf("expected ErrNoOwnerRepo, got %v", err) - } + _, err = c.scanReposForURL(u, rf) + require.ErrorIs(t, err, ErrNoOwnerRepo) } func TestDownloadToCache(t *testing.T) { @@ -388,12 +342,8 @@ func TestDownloadToCache(t *testing.T) { repotest.WithChartSourceGlob("testdata/*.tgz*"), ) defer srv.Stop() - if err := srv.CreateIndex(); err != nil { - t.Fatal(err) - } - if err := srv.LinkIndices(); err != nil { - t.Fatal(err) - } + require.NoError(t, srv.CreateIndex()) + require.NoError(t, srv.LinkIndices()) // The repo file needs to point to our server. repoFile := filepath.Join(srv.Root(), "repositories.yaml") @@ -431,6 +381,7 @@ func TestDownloadToCache(t *testing.T) { // Check that it's in the cache digest, _, err := c.ResolveChartVersion("test/signtest", "0.1.0") require.NoError(t, err) + digestBytes, err := hex.DecodeString(digest) require.NoError(t, err) var digestArray [sha256.Size]byte @@ -472,6 +423,7 @@ func TestDownloadToCache(t *testing.T) { // Check that both chart and prov are in cache digest, _, err := c.ResolveChartVersion("test/signtest", "0.1.0") require.NoError(t, err) + digestBytes, err := hex.DecodeString(digest) require.NoError(t, err) var digestArray [sha256.Size]byte @@ -479,6 +431,7 @@ func TestDownloadToCache(t *testing.T) { _, err = c.Cache.Get(digestArray, CacheChart) require.NoError(t, err, "chart should be in cache") + _, err = c.Cache.Get(digestArray, CacheProv) require.NoError(t, err, "provenance file should be in cache") diff --git a/pkg/storage/driver/secrets_test.go b/pkg/storage/driver/secrets_test.go index a11ec4380..8cc3f390d 100644 --- a/pkg/storage/driver/secrets_test.go +++ b/pkg/storage/driver/secrets_test.go @@ -16,10 +16,11 @@ package driver import ( "encoding/base64" "encoding/json" - "errors" "reflect" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" "helm.sh/helm/v4/pkg/release" @@ -29,9 +30,7 @@ import ( func TestSecretName(t *testing.T) { c := newTestFixtureSecrets(t) - if c.Name() != SecretsDriverName { - t.Errorf("Expected name to be %q, got %q", SecretsDriverName, c.Name()) - } + assert.Equal(t, SecretsDriverName, c.Name(), "Expected name to be %q, got %q", SecretsDriverName, c.Name()) } func TestSecretGet(t *testing.T) { @@ -45,13 +44,9 @@ func TestSecretGet(t *testing.T) { // get release with key got, err := secrets.Get(key) - if err != nil { - t.Fatalf("Failed to get release: %s", err) - } + require.NoError(t, err, "Failed to get release") // compare fetched release with original - if !reflect.DeepEqual(rel, got) { - t.Errorf("Expected {%v}, got {%v}", rel, got) - } + assert.Truef(t, reflect.DeepEqual(rel, got), "Expected {%v}, got {%v}", rel, got) } func TestUNcompressedSecretGet(t *testing.T) { @@ -63,13 +58,9 @@ func TestUNcompressedSecretGet(t *testing.T) { // Create a test fixture which contains an uncompressed release secret, err := newSecretsObject(key, rel, nil) - if err != nil { - t.Fatalf("Failed to create secret: %s", err) - } + require.NoError(t, err, "Failed to create secret") b, err := json.Marshal(rel) - if err != nil { - t.Fatalf("Failed to marshal release: %s", err) - } + require.NoError(t, err, "Failed to marshal release") secret.Data["release"] = []byte(base64.StdEncoding.EncodeToString(b)) var mock MockSecretsInterface mock.objects = map[string]*v1.Secret{key: secret} @@ -77,13 +68,9 @@ func TestUNcompressedSecretGet(t *testing.T) { // get release with key got, err := secrets.Get(key) - if err != nil { - t.Fatalf("Failed to get release: %s", err) - } + require.NoError(t, err, "Failed to get release") // compare fetched release with original - if !reflect.DeepEqual(rel, got) { - t.Errorf("Expected {%v}, got {%v}", rel, got) - } + assert.Truef(t, reflect.DeepEqual(rel, got), "Expected {%v}, got {%v}", rel, got) } func TestSecretList(t *testing.T) { @@ -102,12 +89,8 @@ func TestSecretList(t *testing.T) { return rls.Info.Status == common.StatusUninstalled }) // check - if err != nil { - t.Errorf("Failed to list deleted: %s", err) - } - if len(del) != 2 { - t.Errorf("Expected 2 deleted, got %d:\n%v\n", len(del), del) - } + require.NoError(t, err, "Failed to list deleted") + assert.Len(t, del, 2, "Expected 2 deleted, got %d:\n%v\n", len(del), del) // list all deployed releases dpl, err := secrets.List(func(rel release.Releaser) bool { @@ -115,12 +98,8 @@ func TestSecretList(t *testing.T) { return rls.Info.Status == common.StatusDeployed }) // check - if err != nil { - t.Errorf("Failed to list deployed: %s", err) - } - if len(dpl) != 2 { - t.Errorf("Expected 2 deployed, got %d", len(dpl)) - } + require.NoError(t, err, "Failed to list deployed") + assert.Len(t, dpl, 2, "Expected 2 deployed, got %d", len(dpl)) // list all superseded releases ssd, err := secrets.List(func(rel release.Releaser) bool { @@ -128,22 +107,14 @@ func TestSecretList(t *testing.T) { return rls.Info.Status == common.StatusSuperseded }) // check - if err != nil { - t.Errorf("Failed to list superseded: %s", err) - } - if len(ssd) != 2 { - t.Errorf("Expected 2 superseded, got %d", len(ssd)) - } + require.NoError(t, err, "Failed to list superseded") + assert.Len(t, ssd, 2, "Expected 2 superseded, got %d", len(ssd)) // Check if release having both system and custom labels, this is needed to ensure that selector filtering would work. rls := convertReleaserToV1(t, ssd[0]) _, ok := rls.Labels["name"] - if !ok { - t.Fatalf("Expected 'name' label in results, actual %v", rls.Labels) - } + require.True(t, ok, "Expected 'name' label in results, actual %v", rls.Labels) _, ok = rls.Labels["key1"] - if !ok { - t.Fatalf("Expected 'key1' label in results, actual %v", rls.Labels) - } + require.True(t, ok, "Expected 'key1' label in results, actual %v", rls.Labels) } func TestSecretQuery(t *testing.T) { @@ -157,17 +128,11 @@ func TestSecretQuery(t *testing.T) { }...) rls, err := secrets.Query(map[string]string{"status": "deployed"}) - if err != nil { - t.Fatalf("Failed to query: %s", err) - } - if len(rls) != 2 { - t.Fatalf("Expected 2 results, actual %d", len(rls)) - } + require.NoError(t, err, "Failed to query") + require.Len(t, rls, 2, "Expected 2 results, actual %d", len(rls)) _, err = secrets.Query(map[string]string{"name": "notExist"}) - if !errors.Is(err, ErrReleaseNotFound) { - t.Errorf("Expected {%v}, got {%v}", ErrReleaseNotFound, err) - } + assert.ErrorIs(t, err, ErrReleaseNotFound) } func TestSecretCreate(t *testing.T) { @@ -180,20 +145,14 @@ func TestSecretCreate(t *testing.T) { rel := releaseStub(name, vers, namespace, common.StatusDeployed) // store the release in a secret - if err := secrets.Create(key, rel); err != nil { - t.Fatalf("Failed to create release with key %q: %s", key, err) - } + require.NoErrorf(t, secrets.Create(key, rel), "Failed to create release with key %q", key) // get the release back got, err := secrets.Get(key) - if err != nil { - t.Fatalf("Failed to get release with key %q: %s", key, err) - } + require.NoError(t, err, "Failed to get release with key %q", key) // compare created release with original - if !reflect.DeepEqual(rel, got) { - t.Errorf("Expected {%v}, got {%v}", rel, got) - } + assert.Truef(t, reflect.DeepEqual(rel, got), "Expected {%v}, got {%v}", rel, got) } func TestSecretUpdate(t *testing.T) { @@ -209,21 +168,15 @@ func TestSecretUpdate(t *testing.T) { rel.Info.Status = common.StatusSuperseded // perform the update - if err := secrets.Update(key, rel); err != nil { - t.Fatalf("Failed to update release: %s", err) - } + require.NoErrorf(t, secrets.Update(key, rel), "Failed to update release") // fetch the updated release goti, err := secrets.Get(key) - if err != nil { - t.Fatalf("Failed to get release with key %q: %s", key, err) - } + require.NoError(t, err, "Failed to get release with key %q", key) got := convertReleaserToV1(t, goti) // check release has actually been updated by comparing modified fields - if rel.Info.Status != got.Info.Status { - t.Errorf("Expected status %s, got status %s", rel.Info.Status.String(), got.Info.Status.String()) - } + assert.Equal(t, got.Info.Status, rel.Info.Status, "Expected status %s, got status %s", rel.Info.Status.String(), got.Info.Status.String()) } func TestSecretDelete(t *testing.T) { @@ -237,20 +190,12 @@ func TestSecretDelete(t *testing.T) { // perform the delete on a non-existing release _, err := secrets.Delete("nonexistent") - if !errors.Is(err, ErrReleaseNotFound) { - t.Fatalf("Expected ErrReleaseNotFound, got: {%v}", err) - } + require.ErrorIs(t, err, ErrReleaseNotFound, "Expected ErrReleaseNotFound") // perform the delete rls, err := secrets.Delete(key) - if err != nil { - t.Fatalf("Failed to delete release with key %q: %s", key, err) - } - if !reflect.DeepEqual(rel, rls) { - t.Errorf("Expected {%v}, got {%v}", rel, rls) - } + require.NoError(t, err, "Failed to delete release with key %q", key) + assert.Truef(t, reflect.DeepEqual(rel, rls), "Expected {%v}, got {%v}", rel, rls) _, err = secrets.Get(key) - if !errors.Is(err, ErrReleaseNotFound) { - t.Errorf("Expected {%v}, got {%v}", ErrReleaseNotFound, err) - } + assert.ErrorIs(t, err, ErrReleaseNotFound) } diff --git a/pkg/storage/driver/sql_test.go b/pkg/storage/driver/sql_test.go index 6044ce3c6..adcc780aa 100644 --- a/pkg/storage/driver/sql_test.go +++ b/pkg/storage/driver/sql_test.go @@ -24,6 +24,8 @@ import ( sqlmock "github.com/DATA-DOG/go-sqlmock" migrate "github.com/rubenv/sql-migrate" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "helm.sh/helm/v4/pkg/release" "helm.sh/helm/v4/pkg/release/common" @@ -59,9 +61,7 @@ func (recentUnixTimestampArgument) Match(value driver.Value) bool { func TestSQLName(t *testing.T) { sqlDriver, _ := newTestFixtureSQL(t) - if sqlDriver.Name() != SQLDriverName { - t.Errorf("Expected name to be %s, got %s", SQLDriverName, sqlDriver.Name()) - } + assert.Equal(t, SQLDriverName, sqlDriver.Name(), "Expected name to be %s, got %s", SQLDriverName, sqlDriver.Name()) } func TestSQLGet(t *testing.T) { @@ -97,17 +97,10 @@ func TestSQLGet(t *testing.T) { mockGetReleaseCustomLabels(mock, key, namespace, rel.Labels) got, err := sqlDriver.Get(key) - if err != nil { - t.Fatalf("Failed to get release: %v", err) - } + require.NoError(t, err, "Failed to get release") - if !reflect.DeepEqual(rel, got) { - t.Errorf("Expected release {%v}, got {%v}", rel, got) - } - - if err := mock.ExpectationsWereMet(); err != nil { - t.Errorf("sql expectations weren't met: %v", err) - } + assert.Truef(t, reflect.DeepEqual(rel, got), "Expected release {%v}, got {%v}", rel, got) + assert.NoErrorf(t, mock.ExpectationsWereMet(), "sql expectations weren't met") } func TestSQLList(t *testing.T) { @@ -157,12 +150,8 @@ func TestSQLList(t *testing.T) { return rls.Info.Status == common.StatusUninstalled }) // check - if err != nil { - t.Errorf("Failed to list deleted: %v", err) - } - if len(del) != 2 { - t.Errorf("Expected 2 deleted, got %d:\n%v\n", len(del), del) - } + require.NoError(t, err, "Failed to list deleted") + assert.Len(t, del, 2, "Expected 2 deleted, got %d:\n%v\n", len(del), del) // list all deployed releases dpl, err := sqlDriver.List(func(rel release.Releaser) bool { @@ -170,12 +159,8 @@ func TestSQLList(t *testing.T) { return rls.Info.Status == common.StatusDeployed }) // check - if err != nil { - t.Errorf("Failed to list deployed: %v", err) - } - if len(dpl) != 2 { - t.Errorf("Expected 2 deployed, got %d:\n%v\n", len(dpl), dpl) - } + require.NoError(t, err, "Failed to list deployed") + assert.Len(t, dpl, 2, "Expected 2 deployed, got %d:\n%v\n", len(dpl), dpl) // list all superseded releases ssd, err := sqlDriver.List(func(rel release.Releaser) bool { @@ -183,27 +168,16 @@ func TestSQLList(t *testing.T) { return rls.Info.Status == common.StatusSuperseded }) // check - if err != nil { - t.Errorf("Failed to list superseded: %v", err) - } - if len(ssd) != 2 { - t.Errorf("Expected 2 superseded, got %d:\n%v\n", len(ssd), ssd) - } - - if err := mock.ExpectationsWereMet(); err != nil { - t.Errorf("sql expectations weren't met: %v", err) - } + require.NoError(t, err, "Failed to list superseded") + assert.Len(t, ssd, 2, "Expected 2 superseded, got %d:\n%v\n", len(ssd), ssd) + require.NoErrorf(t, mock.ExpectationsWereMet(), "sql expectations weren't met") // Check if release having both system and custom labels, this is needed to ensure that selector filtering would work. rls := convertReleaserToV1(t, ssd[0]) _, ok := rls.Labels["name"] - if !ok { - t.Fatalf("Expected 'name' label in results, actual %v", rls.Labels) - } + require.True(t, ok, "Expected 'name' label in results, actual %v", rls.Labels) _, ok = rls.Labels["key1"] - if !ok { - t.Fatalf("Expected 'key1' label in results, actual %v", rls.Labels) - } + require.True(t, ok, "Expected 'key1' label in results, actual %v", rls.Labels) } func TestSqlCreate(t *testing.T) { @@ -254,13 +228,8 @@ func TestSqlCreate(t *testing.T) { } mock.ExpectCommit() - if err := sqlDriver.Create(key, rel); err != nil { - t.Fatalf("failed to create release with key %s: %v", key, err) - } - - if err := mock.ExpectationsWereMet(); err != nil { - t.Errorf("sql expectations weren't met: %v", err) - } + require.NoErrorf(t, sqlDriver.Create(key, rel), "failed to create release with key %s", key) + assert.NoErrorf(t, mock.ExpectationsWereMet(), "sql expectations weren't met") } func TestSqlCreateAlreadyExists(t *testing.T) { @@ -315,13 +284,8 @@ func TestSqlCreateAlreadyExists(t *testing.T) { ).RowsWillBeClosed() mock.ExpectRollback() - if err := sqlDriver.Create(key, rel); err == nil { - t.Fatalf("failed to create release with key %s: %v", key, err) - } - - if err := mock.ExpectationsWereMet(); err != nil { - t.Errorf("sql expectations weren't met: %v", err) - } + require.Errorf(t, sqlDriver.Create(key, rel), "failed to create release with key %s", key) + assert.NoErrorf(t, mock.ExpectationsWereMet(), "sql expectations weren't met") } func TestSqlUpdate(t *testing.T) { @@ -352,13 +316,8 @@ func TestSqlUpdate(t *testing.T) { WithArgs(body, rel.Name, int(rel.Version), rel.Info.Status.String(), sqlReleaseDefaultOwner, recentUnixTimestamp(), key, namespace). WillReturnResult(sqlmock.NewResult(0, 1)) - if err := sqlDriver.Update(key, rel); err != nil { - t.Fatalf("failed to update release with key %s: %v", key, err) - } - - if err := mock.ExpectationsWereMet(); err != nil { - t.Errorf("sql expectations weren't met: %v", err) - } + require.NoErrorf(t, sqlDriver.Update(key, rel), "failed to update release with key %s", key) + assert.NoErrorf(t, mock.ExpectationsWereMet(), "sql expectations weren't met") } func TestSqlQuery(t *testing.T) { @@ -448,31 +407,20 @@ func TestSqlQuery(t *testing.T) { mockGetReleaseCustomLabels(mock, "", deployedRelease.Namespace, deployedRelease.Labels) _, err := sqlDriver.Query(labelSetUnknown) - if err == nil { - t.Errorf("Expected error {%v}, got nil", ErrReleaseNotFound) - } else if !errors.Is(err, ErrReleaseNotFound) { - t.Fatalf("failed to query for unknown smug-pigeon release: %v", err) - } + require.Errorf(t, err, "Expected error {%v}, got nil", ErrReleaseNotFound) + require.ErrorIsf(t, err, ErrReleaseNotFound, "failed to query for unknown smug-pigeon release") results, err := sqlDriver.Query(labelSetDeployed) - if err != nil { - t.Fatalf("failed to query for deployed smug-pigeon release: %v", err) - } + require.NoError(t, err, "failed to query for deployed smug-pigeon release") for _, res := range results { - if !reflect.DeepEqual(res, deployedRelease) { - t.Errorf("Expected release {%v}, got {%v}", deployedRelease, res) - } + assert.Truef(t, reflect.DeepEqual(res, deployedRelease), "Expected release {%v}, got {%v}", deployedRelease, res) } results, err = sqlDriver.Query(labelSetAll) - if err != nil { - t.Fatalf("failed to query release history for smug-pigeon: %v", err) - } + require.NoError(t, err, "failed to query release history for smug-pigeon") - if len(results) != 2 { - t.Errorf("expected a resultset of size 2, got %d", len(results)) - } + assert.Len(t, results, 2, "expected a resultset of size 2, got %d", len(results)) for _, res := range results { if !reflect.DeepEqual(res, deployedRelease) && !reflect.DeepEqual(res, supersededRelease) { @@ -480,9 +428,7 @@ func TestSqlQuery(t *testing.T) { } } - if err := mock.ExpectationsWereMet(); err != nil { - t.Errorf("sql expectations weren't met: %v", err) - } + assert.NoErrorf(t, mock.ExpectationsWereMet(), "sql expectations weren't met") } func TestSqlDelete(t *testing.T) { @@ -544,16 +490,12 @@ func TestSqlDelete(t *testing.T) { mock.ExpectCommit() deletedRelease, err := sqlDriver.Delete(key) - if err := mock.ExpectationsWereMet(); err != nil { - t.Errorf("sql expectations weren't met: %v", err) - } - if err != nil { - t.Fatalf("failed to delete release with key %q: %v", key, err) - } + require.NoError(t, err) + err = mock.ExpectationsWereMet() + assert.NoErrorf(t, err, "sql expectations weren't met") + require.NoError(t, err, "failed to delete release with key %q", key) - if !reflect.DeepEqual(rel, deletedRelease) { - t.Errorf("Expected release {%v}, got {%v}", rel, deletedRelease) - } + assert.Truef(t, reflect.DeepEqual(rel, deletedRelease), "Expected release {%v}, got {%v}", rel, deletedRelease) } func mockGetReleaseCustomLabels(mock sqlmock.Sqlmock, key string, namespace string, labels map[string]string) { @@ -621,8 +563,6 @@ func TestSqlCheckAppliedMigrations(t *testing.T) { ExpectQuery(""). WillReturnRows(rows) mock.ExpectCommit() - if sqlDriver.checkAlreadyApplied(c.migrationsToApply) != c.expectedResult { - t.Errorf("Test case: %v, Expected: %v, Have: %v, Explanation: %v", i, c.expectedResult, !c.expectedResult, c.errorExplanation) - } + assert.Equal(t, c.expectedResult, sqlDriver.checkAlreadyApplied(c.migrationsToApply), "Test case: %v, Expected: %v, Have: %v, Explanation: %v", i, c.expectedResult, !c.expectedResult, c.errorExplanation) } } From 71733656a5c64307f85290bc9fe6480ad637a117 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 20:50:55 +0200 Subject: [PATCH 34/61] chore(pkg): refactor: convert tests to testify assert/require part 15 #### Description refactor: convert tests to testify assert/require in pkg/cmd Signed-off-by: Matthieu MOREL --- pkg/chart/loader/load_test.go | 66 +++++++----------- pkg/cmd/dependency_update_test.go | 106 +++++++++------------------- pkg/cmd/repo_index_test.go | 112 +++++++++--------------------- pkg/getter/ocigetter_test.go | 92 +++++++----------------- 4 files changed, 116 insertions(+), 260 deletions(-) diff --git a/pkg/chart/loader/load_test.go b/pkg/chart/loader/load_test.go index a42861eac..3834fad7a 100644 --- a/pkg/chart/loader/load_test.go +++ b/pkg/chart/loader/load_test.go @@ -24,10 +24,12 @@ import ( "io" "maps" "path/filepath" - "strings" "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + c3 "helm.sh/helm/v4/internal/chart/v3" "helm.sh/helm/v4/pkg/chart" c2 "helm.sh/helm/v4/pkg/chart/v2" @@ -59,20 +61,13 @@ description: A test chart Size: int64(len(data)), ModTime: time.Now(), } - if err := tw.WriteHeader(header); err != nil { - t.Fatalf("Failed to write tar header for %s: %v", name, err) - } - if _, err := tw.Write(data); err != nil { - t.Fatalf("Failed to write tar data for %s: %v", name, err) - } + require.NoErrorf(t, tw.WriteHeader(header), "Failed to write tar header for %s", name) + _, err := tw.Write(data) + require.NoErrorf(t, err, "Failed to write tar data for %s", name) } - if err := tw.Close(); err != nil { - t.Fatalf("Failed to close tar writer: %v", err) - } - if err := gw.Close(); err != nil { - t.Fatalf("Failed to close gzip writer: %v", err) - } + require.NoErrorf(t, tw.Close(), "Failed to close tar writer") + require.NoErrorf(t, gw.Close(), "Failed to close gzip writer") return &buf } @@ -149,37 +144,26 @@ func TestLoadArchive(t *testing.T) { loadedChart, err := LoadArchive(reader) if tc.expectedError != "" { - if err == nil || !strings.Contains(err.Error(), tc.expectedError) { - t.Errorf("Expected error containing %q, but got %v", tc.expectedError, err) - } - return - } + require.Errorf(t, err, "Expected error containing %q, but got no error", tc.expectedError) + assert.ErrorContains(t, err, tc.expectedError) + } else { + require.NoError(t, err) - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - lac, err := chart.NewAccessor(loadedChart) - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - eac, err := chart.NewAccessor(tc.expectedChart) - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } + lac, err := chart.NewAccessor(loadedChart) + require.NoError(t, err) - if lac.Name() != eac.Name() { - t.Errorf("Expected chart name %q, got %q", eac.Name(), lac.Name()) - } + eac, err := chart.NewAccessor(tc.expectedChart) + require.NoError(t, err) + assert.Equalf(t, lac.Name(), eac.Name(), "Expected chart name %q, got %q", eac.Name(), lac.Name()) - var loadedAPIVersion string - switch lc := loadedChart.(type) { - case *c2.Chart: - loadedAPIVersion = lc.Metadata.APIVersion - case *c3.Chart: - loadedAPIVersion = lc.Metadata.APIVersion - } - if loadedAPIVersion != tc.apiVersion { - t.Errorf("Expected API version %q, got %q", tc.apiVersion, loadedAPIVersion) + var loadedAPIVersion string + switch lc := loadedChart.(type) { + case *c2.Chart: + loadedAPIVersion = lc.Metadata.APIVersion + case *c3.Chart: + loadedAPIVersion = lc.Metadata.APIVersion + } + assert.Equalf(t, loadedAPIVersion, tc.apiVersion, "Expected API version %q, got %q", tc.apiVersion, loadedAPIVersion) } }) } diff --git a/pkg/cmd/dependency_update_test.go b/pkg/cmd/dependency_update_test.go index f9ff68097..13eb74532 100644 --- a/pkg/cmd/dependency_update_test.go +++ b/pkg/cmd/dependency_update_test.go @@ -16,14 +16,15 @@ limitations under the License. package cmd import ( - "errors" "fmt" "io/fs" "os" "path/filepath" - "strings" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "helm.sh/helm/v4/internal/test/ensure" chart "helm.sh/helm/v4/pkg/chart/v2" chartutil "helm.sh/helm/v4/pkg/chart/v2/util" @@ -42,21 +43,16 @@ func TestDependencyUpdateCmd(t *testing.T) { t.Logf("Listening on directory %s", srv.Root()) ociSrv, err := repotest.NewOCIServer(t, srv.Root()) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) contentCache := t.TempDir() ociChartName := "oci-depending-chart" c := createTestingMetadataForOCI(ociChartName, ociSrv.RegistryURL) - if _, err := chartutil.Save(c, ociSrv.Dir); err != nil { - t.Fatal(err) - } + _, err = chartutil.Save(c, ociSrv.Dir) + require.NoError(t, err) ociSrv.Run(t, repotest.WithDependingChart(c)) - if err := srv.LinkIndices(); err != nil { - t.Fatal(err) - } + require.NoError(t, srv.LinkIndices()) dir := func(p ...string) string { return filepath.Join(append([]string{srv.Root()}, p...)...) @@ -65,9 +61,7 @@ func TestDependencyUpdateCmd(t *testing.T) { chartname := "depup" ch := createTestingMetadata(chartname, srv.URL()) md := ch.Metadata - if err := chartutil.SaveDir(ch, dir()); err != nil { - t.Fatal(err) - } + require.NoError(t, chartutil.SaveDir(ch, dir())) _, out, err := executeActionCommand( fmt.Sprintf("dependency update '%s' --repository-config %s --repository-cache %s --content-cache %s --plain-http", dir(chartname), dir("repositories.yaml"), dir(), contentCache), @@ -78,30 +72,22 @@ func TestDependencyUpdateCmd(t *testing.T) { } // This is written directly to stdout, so we have to capture as is. - if !strings.Contains(out, `update from the "test" chart repository`) { - t.Errorf("Repo did not get updated\n%s", out) - } + assert.Contains(t, out, `update from the "test" chart repository`, "Repo did not get updated\n%s", out) // Make sure the actual file got downloaded. expect := dir(chartname, "charts/reqtest-0.1.0.tgz") - if _, err := os.Stat(expect); err != nil { - t.Fatal(err) - } + _, err = os.Stat(expect) + require.NoError(t, err) hash, err := provenance.DigestFile(expect) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) i, err := repo.LoadIndexFile(dir(helmpath.CacheIndexFile("test"))) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) reqver := i.Entries["reqtest"][0] - if h := reqver.Digest; h != hash { - t.Errorf("Failed hash match: expected %s, got %s", hash, h) - } + h := reqver.Digest + assert.Equalf(t, h, hash, "Failed hash match: expected %s, got %s", hash, h) // Now change the dependencies and update. This verifies that on update, // old dependencies are cleansed and new dependencies are added. @@ -109,9 +95,7 @@ func TestDependencyUpdateCmd(t *testing.T) { {Name: "reqtest", Version: "0.1.0", Repository: srv.URL()}, {Name: "compressedchart", Version: "0.3.0", Repository: srv.URL()}, } - if err := chartutil.SaveChartfile(dir(chartname, "Chart.yaml"), md); err != nil { - t.Fatal(err) - } + require.NoError(t, chartutil.SaveChartfile(dir(chartname, "Chart.yaml"), md)) _, out, err = executeActionCommand(fmt.Sprintf("dependency update '%s' --repository-config %s --repository-cache %s --content-cache %s --plain-http", dir(chartname), dir("repositories.yaml"), dir(), contentCache)) if err != nil { @@ -122,18 +106,14 @@ func TestDependencyUpdateCmd(t *testing.T) { // In this second run, we should see compressedchart-0.3.0.tgz, and not // the 0.1.0 version. expect = dir(chartname, "charts/compressedchart-0.3.0.tgz") - if _, err := os.Stat(expect); err != nil { - t.Fatalf("Expected %q: %s", expect, err) - } + _, err = os.Stat(expect) + require.NoErrorf(t, err, "Expected %q", expect) unexpected := dir(chartname, "charts/compressedchart-0.1.0.tgz") - if _, err := os.Stat(unexpected); err == nil { - t.Fatalf("Unexpected %q", unexpected) - } + _, err = os.Stat(unexpected) + require.Errorf(t, err, "Unexpected %q", unexpected) // test for OCI charts - if err := chartutil.SaveDir(c, dir()); err != nil { - t.Fatal(err) - } + require.NoError(t, chartutil.SaveDir(c, dir())) cmd := fmt.Sprintf("dependency update '%s' --repository-config %s --repository-cache %s --registry-config %s/config.json --content-cache %s --plain-http", dir(ociChartName), dir("repositories.yaml"), @@ -146,9 +126,8 @@ func TestDependencyUpdateCmd(t *testing.T) { t.Fatal(err) } expect = dir(ociChartName, "charts/oci-dependent-chart-0.1.0.tgz") - if _, err := os.Stat(expect); err != nil { - t.Fatal(err) - } + _, err = os.Stat(expect) + require.NoError(t, err) } func TestDependencyUpdateCmd_DoNotDeleteOldChartsOnError(t *testing.T) { @@ -162,9 +141,7 @@ func TestDependencyUpdateCmd_DoNotDeleteOldChartsOnError(t *testing.T) { defer srv.Stop() t.Logf("Listening on directory %s", srv.Root()) - if err := srv.LinkIndices(); err != nil { - t.Fatal(err) - } + require.NoError(t, srv.LinkIndices()) chartname := "depupdelete" @@ -191,25 +168,18 @@ func TestDependencyUpdateCmd_DoNotDeleteOldChartsOnError(t *testing.T) { // Make sure charts dir still has dependencies files, err := os.ReadDir(filepath.Join(dir(chartname), "charts")) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) dependencies := []string{"compressedchart-0.1.0.tgz", "reqtest-0.1.0.tgz"} - if len(dependencies) != len(files) { - t.Fatalf("Expected %d chart dependencies, got %d", len(dependencies), len(files)) - } + require.Len(t, dependencies, len(files), "Expected %d chart dependencies, got %d", len(dependencies), len(files)) for index, file := range files { - if dependencies[index] != file.Name() { - t.Fatalf("Chart dependency %s not matching %s", dependencies[index], file.Name()) - } + require.Equal(t, file.Name(), dependencies[index], "Chart dependency %s not matching %s", dependencies[index], file.Name()) } // Make sure tmpcharts-x is deleted tmpPath := filepath.Join(dir(chartname), fmt.Sprintf("tmpcharts-%d", os.Getpid())) - if _, err := os.Stat(tmpPath); !errors.Is(err, fs.ErrNotExist) { - t.Fatal("tmpcharts dir still exists") - } + _, err = os.Stat(tmpPath) + require.ErrorIs(t, err, fs.ErrNotExist, "tmpcharts dir still exists") } func TestDependencyUpdateCmd_WithRepoThatWasNotAdded(t *testing.T) { @@ -231,9 +201,7 @@ func TestDependencyUpdateCmd_WithRepoThatWasNotAdded(t *testing.T) { } ch.Metadata.Dependencies = append(ch.Metadata.Dependencies, chartDependency) - if err := chartutil.SaveDir(ch, dir()); err != nil { - t.Fatal(err) - } + require.NoError(t, chartutil.SaveDir(ch, dir())) contentCache := t.TempDir() @@ -248,10 +216,8 @@ func TestDependencyUpdateCmd_WithRepoThatWasNotAdded(t *testing.T) { } // This is written directly to stdout, so we have to capture as is - if !strings.Contains(out, `Getting updates for unmanaged Helm repositories...`) { - t.Errorf("No ‘unmanaged’ Helm repo used in test chartdependency or it doesn’t cause the creation "+ - "of an ‘ad hoc’ repo index cache file\n%s", out) - } + assert.Contains(t, out, `Getting updates for unmanaged Helm repositories...`, "No ‘unmanaged’ Helm repo used in test chartdependency or it doesn’t cause the creation "+ + "of an ‘ad hoc’ repo index cache file\n%s", out) } func setupMockRepoServer(t *testing.T) *repotest.Server { @@ -263,9 +229,7 @@ func setupMockRepoServer(t *testing.T) *repotest.Server { t.Logf("Listening on directory %s", srv.Root()) - if err := srv.LinkIndices(); err != nil { - t.Fatal(err) - } + require.NoError(t, srv.LinkIndices()) return srv } @@ -306,7 +270,5 @@ func createTestingMetadataForOCI(name, registryURL string) *chart.Chart { func createTestingChart(t *testing.T, dest, name, baseURL string) { t.Helper() cfile := createTestingMetadata(name, baseURL) - if err := chartutil.SaveDir(cfile, dest); err != nil { - t.Fatal(err) - } + require.NoError(t, chartutil.SaveDir(cfile, dest)) } diff --git a/pkg/cmd/repo_index_test.go b/pkg/cmd/repo_index_test.go index 68f105d6d..30700749b 100644 --- a/pkg/cmd/repo_index_test.go +++ b/pkg/cmd/repo_index_test.go @@ -24,6 +24,9 @@ import ( "path/filepath" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "helm.sh/helm/v4/pkg/repo/v1" ) @@ -31,134 +34,81 @@ func TestRepoIndexCmd(t *testing.T) { dir := t.TempDir() comp := filepath.Join(dir, "compressedchart-0.1.0.tgz") - if err := linkOrCopy("testdata/testcharts/compressedchart-0.1.0.tgz", comp); err != nil { - t.Fatal(err) - } + require.NoError(t, linkOrCopy("testdata/testcharts/compressedchart-0.1.0.tgz", comp)) comp2 := filepath.Join(dir, "compressedchart-0.2.0.tgz") - if err := linkOrCopy("testdata/testcharts/compressedchart-0.2.0.tgz", comp2); err != nil { - t.Fatal(err) - } + require.NoError(t, linkOrCopy("testdata/testcharts/compressedchart-0.2.0.tgz", comp2)) buf := bytes.NewBuffer(nil) c := newRepoIndexCmd(buf) - if err := c.RunE(c, []string{dir}); err != nil { - t.Error(err) - } + require.NoError(t, c.RunE(c, []string{dir})) destIndex := filepath.Join(dir, "index.yaml") index, err := repo.LoadIndexFile(destIndex) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if len(index.Entries) != 1 { - t.Errorf("expected 1 entry, got %d: %#v", len(index.Entries), index.Entries) - } + assert.Len(t, index.Entries, 1, "expected 1 entry, got %d: %#v", len(index.Entries), index.Entries) vs := index.Entries["compressedchart"] - if len(vs) != 2 { - t.Errorf("expected 2 versions, got %d: %#v", len(vs), vs) - } + assert.Len(t, vs, 2, "expected 2 versions, got %d: %#v", len(vs), vs) expectedVersion := "0.2.0" - if vs[0].Version != expectedVersion { - t.Errorf("expected %q, got %q", expectedVersion, vs[0].Version) - } + assert.Equal(t, expectedVersion, vs[0].Version, "expected %q, got %q", expectedVersion, vs[0].Version) b, err := os.ReadFile(destIndex) - if err != nil { - t.Fatal(err) - } - if json.Valid(b) { - t.Error("did not expect index file to be valid json") - } + require.NoError(t, err) + assert.False(t, json.Valid(b), "did not expect index file to be valid json") // Test with `--json` c.ParseFlags([]string{"--json", "true"}) - if err := c.RunE(c, []string{dir}); err != nil { - t.Error(err) - } + require.NoError(t, c.RunE(c, []string{dir})) - if b, err = os.ReadFile(destIndex); err != nil { - t.Fatal(err) - } - if !json.Valid(b) { - t.Error("index file is not valid json") - } + b, err = os.ReadFile(destIndex) + require.NoError(t, err) + assert.True(t, json.Valid(b), "index file is not valid json") // Test with `--merge` // Remove first two charts. - if err := os.Remove(comp); err != nil { - t.Fatal(err) - } - if err := os.Remove(comp2); err != nil { - t.Fatal(err) - } + require.NoError(t, os.Remove(comp)) + require.NoError(t, os.Remove(comp2)) // Add a new chart and a new version of an existing chart - if err := linkOrCopy("testdata/testcharts/reqtest-0.1.0.tgz", filepath.Join(dir, "reqtest-0.1.0.tgz")); err != nil { - t.Fatal(err) - } - if err := linkOrCopy("testdata/testcharts/compressedchart-0.3.0.tgz", filepath.Join(dir, "compressedchart-0.3.0.tgz")); err != nil { - t.Fatal(err) - } + require.NoError(t, linkOrCopy("testdata/testcharts/reqtest-0.1.0.tgz", filepath.Join(dir, "reqtest-0.1.0.tgz"))) + require.NoError(t, linkOrCopy("testdata/testcharts/compressedchart-0.3.0.tgz", filepath.Join(dir, "compressedchart-0.3.0.tgz"))) c.ParseFlags([]string{"--merge", destIndex}) - if err := c.RunE(c, []string{dir}); err != nil { - t.Error(err) - } + require.NoError(t, c.RunE(c, []string{dir})) index, err = repo.LoadIndexFile(destIndex) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if len(index.Entries) != 2 { - t.Errorf("expected 2 entries, got %d: %#v", len(index.Entries), index.Entries) - } + assert.Len(t, index.Entries, 2, "expected 2 entries, got %d: %#v", len(index.Entries), index.Entries) vs = index.Entries["compressedchart"] - if len(vs) != 3 { - t.Errorf("expected 3 versions, got %d: %#v", len(vs), vs) - } + assert.Len(t, vs, 3, "expected 3 versions, got %d: %#v", len(vs), vs) expectedVersion = "0.3.0" - if vs[0].Version != expectedVersion { - t.Errorf("expected %q, got %q", expectedVersion, vs[0].Version) - } + assert.Equal(t, expectedVersion, vs[0].Version, "expected %q, got %q", expectedVersion, vs[0].Version) // test that index.yaml gets generated on merge even when it doesn't exist - if err := os.Remove(destIndex); err != nil { - t.Fatal(err) - } + require.NoError(t, os.Remove(destIndex)) c.ParseFlags([]string{"--merge", destIndex}) - if err := c.RunE(c, []string{dir}); err != nil { - t.Error(err) - } + require.NoError(t, c.RunE(c, []string{dir})) index, err = repo.LoadIndexFile(destIndex) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) // verify it didn't create an empty index.yaml and the merged happened - if len(index.Entries) != 2 { - t.Errorf("expected 2 entries, got %d: %#v", len(index.Entries), index.Entries) - } + assert.Len(t, index.Entries, 2, "expected 2 entries, got %d: %#v", len(index.Entries), index.Entries) vs = index.Entries["compressedchart"] - if len(vs) != 1 { - t.Errorf("expected 1 versions, got %d: %#v", len(vs), vs) - } + assert.Len(t, vs, 1, "expected 1 versions, got %d: %#v", len(vs), vs) expectedVersion = "0.3.0" - if vs[0].Version != expectedVersion { - t.Errorf("expected %q, got %q", expectedVersion, vs[0].Version) - } + assert.Equal(t, expectedVersion, vs[0].Version, "expected %q, got %q", expectedVersion, vs[0].Version) } func linkOrCopy(source, target string) error { diff --git a/pkg/getter/ocigetter_test.go b/pkg/getter/ocigetter_test.go index 5a7c99ebe..dfcc74890 100644 --- a/pkg/getter/ocigetter_test.go +++ b/pkg/getter/ocigetter_test.go @@ -21,18 +21,18 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "helm.sh/helm/v4/pkg/registry" ) func TestOCIGetter(t *testing.T) { g, err := NewOCIGetter(WithURL("oci://example.com")) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if _, ok := g.(*OCIGetter); !ok { - t.Fatal("Expected NewOCIGetter to produce an *OCIGetter") - } + _, ok := g.(*OCIGetter) + require.True(t, ok, "Expected NewOCIGetter to produce an *OCIGetter") cd := "../../testdata" join := filepath.Join @@ -51,71 +51,41 @@ func TestOCIGetter(t *testing.T) { WithInsecureSkipVerifyTLS(insecureSkipVerifyTLS), WithPlainHTTP(plainHTTP), ) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) og, ok := g.(*OCIGetter) - if !ok { - t.Fatal("expected NewOCIGetter to produce an *OCIGetter") - } + require.True(t, ok, "expected NewOCIGetter to produce an *OCIGetter") - if og.opts.username != "I" { - t.Errorf("Expected NewOCIGetter to contain %q as the username, got %q", "I", og.opts.username) - } + assert.Equal(t, "I", og.opts.username, "Expected NewOCIGetter to contain %q as the username, got %q", "I", og.opts.username) - if og.opts.password != "Am" { - t.Errorf("Expected NewOCIGetter to contain %q as the password, got %q", "Am", og.opts.password) - } + assert.Equal(t, "Am", og.opts.password, "Expected NewOCIGetter to contain %q as the password, got %q", "Am", og.opts.password) - if og.opts.certFile != pub { - t.Errorf("Expected NewOCIGetter to contain %q as the public key file, got %q", pub, og.opts.certFile) - } + assert.Equal(t, pub, og.opts.certFile, "Expected NewOCIGetter to contain %q as the public key file, got %q", pub, og.opts.certFile) - if og.opts.keyFile != priv { - t.Errorf("Expected NewOCIGetter to contain %q as the private key file, got %q", priv, og.opts.keyFile) - } + assert.Equal(t, priv, og.opts.keyFile, "Expected NewOCIGetter to contain %q as the private key file, got %q", priv, og.opts.keyFile) - if og.opts.caFile != ca { - t.Errorf("Expected NewOCIGetter to contain %q as the CA file, got %q", ca, og.opts.caFile) - } + assert.Equal(t, ca, og.opts.caFile, "Expected NewOCIGetter to contain %q as the CA file, got %q", ca, og.opts.caFile) - if og.opts.timeout != timeout { - t.Errorf("Expected NewOCIGetter to contain %s as Timeout flag, got %s", timeout, og.opts.timeout) - } + assert.Equal(t, timeout, og.opts.timeout, "Expected NewOCIGetter to contain %s as Timeout flag, got %s", timeout, og.opts.timeout) - if og.opts.transport != transport { - t.Errorf("Expected NewOCIGetter to contain %p as Transport, got %p", transport, og.opts.transport) - } + assert.Equal(t, transport, og.opts.transport, "Expected NewOCIGetter to contain %p as Transport, got %p", transport, og.opts.transport) - if og.opts.plainHTTP != plainHTTP { - t.Errorf("Expected NewOCIGetter to have plainHTTP as %t, got %t", plainHTTP, og.opts.plainHTTP) - } + assert.Equal(t, plainHTTP, og.opts.plainHTTP, "Expected NewOCIGetter to have plainHTTP as %t, got %t", plainHTTP, og.opts.plainHTTP) - if og.opts.insecureSkipVerifyTLS != insecureSkipVerifyTLS { - t.Errorf("Expected NewOCIGetter to have insecureSkipVerifyTLS as %t, got %t", insecureSkipVerifyTLS, og.opts.insecureSkipVerifyTLS) - } + assert.Equal(t, insecureSkipVerifyTLS, og.opts.insecureSkipVerifyTLS, "Expected NewOCIGetter to have insecureSkipVerifyTLS as %t, got %t", insecureSkipVerifyTLS, og.opts.insecureSkipVerifyTLS) // Test if setting registryClient is being passed to the ops registryClient, err := registry.NewClient() - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) g, err = NewOCIGetter( WithRegistryClient(registryClient), ) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) og, ok = g.(*OCIGetter) - if !ok { - t.Fatal("expected NewOCIGetter to produce an *OCIGetter") - } + require.True(t, ok, "expected NewOCIGetter to produce an *OCIGetter") - if og.opts.registryClient != registryClient { - t.Errorf("Expected NewOCIGetter to contain %p as RegistryClient, got %p", registryClient, og.opts.registryClient) - } + assert.Equal(t, registryClient, og.opts.registryClient, "Expected NewOCIGetter to contain %p as RegistryClient, got %p", registryClient, og.opts.registryClient) } func TestOCIHTTPTransportReuse(t *testing.T) { @@ -123,29 +93,19 @@ func TestOCIHTTPTransportReuse(t *testing.T) { _, err := g.newRegistryClient() - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if g.transport == nil { - t.Fatal("Expected non nil value for transport") - } + require.NotNil(t, g.transport, "Expected non nil value for transport") transport1 := g.transport _, err = g.newRegistryClient() - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if g.transport == nil { - t.Fatal("Expected non nil value for transport") - } + require.NotNil(t, g.transport, "Expected non nil value for transport") transport2 := g.transport - if transport1 != transport2 { - t.Fatal("Expected default transport to be reused") - } + require.Equal(t, transport2, transport1, "Expected default transport to be reused") } From 4073566e285d5bfaafaf0cec2b927fa037bfcb2a Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 20:50:55 +0200 Subject: [PATCH 35/61] chore(pkg): refactor: convert tests to testify assert/require part 17 #### Description refactor: convert tests to testify assert/require in pkg/cmd Signed-off-by: Matthieu MOREL --- pkg/action/uninstall_test.go | 4 +- pkg/chart/common/capabilities_test.go | 80 +++++++----------------- pkg/chart/v2/lint/rules/template_test.go | 71 +++++---------------- pkg/cmd/dependency_build_test.go | 67 +++++++------------- pkg/cmd/plugin_package_test.go | 75 +++++++--------------- pkg/cmd/repo_add_test.go | 76 ++++++---------------- 6 files changed, 108 insertions(+), 265 deletions(-) diff --git a/pkg/action/uninstall_test.go b/pkg/action/uninstall_test.go index 913ade1a5..f36fe7874 100644 --- a/pkg/action/uninstall_test.go +++ b/pkg/action/uninstall_test.go @@ -121,7 +121,7 @@ func TestUninstallRelease_Wait(t *testing.T) { unAction.cfg.KubeClient = failer resi, err := unAction.Run(rel.Name) req.Error(err) - is.Contains(err.Error(), "U timed out") + req.ErrorContains(err, "U timed out") res, err := releaserToV1Release(resi.Release) req.NoError(err) is.Equal(common.StatusUninstalled, res.Info.Status) @@ -163,7 +163,7 @@ func TestUninstallRelease_Cascade(t *testing.T) { unAction.cfg.KubeClient = failer _, err := unAction.Run(rel.Name) require.Error(t, err) - is.Contains(err.Error(), "failed to delete release: come-fail-away") + is.ErrorContains(err, "failed to delete release: come-fail-away") } func TestUninstallRun_UnreachableKubeClient(t *testing.T) { diff --git a/pkg/chart/common/capabilities_test.go b/pkg/chart/common/capabilities_test.go index c8d47581c..b099e3193 100644 --- a/pkg/chart/common/capabilities_test.go +++ b/pkg/chart/common/capabilities_test.go @@ -17,68 +17,44 @@ package common import ( "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestVersionSet(t *testing.T) { vs := VersionSet{"v1", "apps/v1"} - if d := len(vs); d != 2 { - t.Errorf("Expected 2 versions, got %d", d) - } + d := len(vs) + assert.Equalf(t, 2, d, "Expected 2 versions, got %d", d) - if !vs.Has("apps/v1") { - t.Error("Expected to find apps/v1") - } + assert.True(t, vs.Has("apps/v1"), "Expected to find apps/v1") - if vs.Has("Spanish/inquisition") { - t.Error("No one expects the Spanish/inquisition") - } + assert.False(t, vs.Has("Spanish/inquisition"), "No one expects the Spanish/inquisition") } func TestDefaultVersionSet(t *testing.T) { - if !DefaultVersionSet.Has("v1") { - t.Error("Expected core v1 version set") - } + assert.True(t, DefaultVersionSet.Has("v1"), "Expected core v1 version set") } func TestDefaultCapabilities(t *testing.T) { caps := DefaultCapabilities kv := caps.KubeVersion - if kv.String() != "v1.20.0" { - t.Errorf("Expected default KubeVersion.String() to be v1.20.0, got %q", kv.String()) - } - if kv.Version != "v1.20.0" { - t.Errorf("Expected default KubeVersion.Version to be v1.20.0, got %q", kv.Version) - } - if kv.GitVersion() != "v1.20.0" { - t.Errorf("Expected default KubeVersion.GitVersion() to be v1.20.0, got %q", kv.Version) - } - if kv.Major != "1" { - t.Errorf("Expected default KubeVersion.Major to be 1, got %q", kv.Major) - } - if kv.Minor != "20" { - t.Errorf("Expected default KubeVersion.Minor to be 20, got %q", kv.Minor) - } + assert.Equalf(t, "v1.20.0", kv.String(), "Expected default KubeVersion.String() to be v1.20.0, got %q", kv.String()) + assert.Equalf(t, "v1.20.0", kv.Version, "Expected default KubeVersion.Version to be v1.20.0, got %q", kv.Version) + assert.Equalf(t, "v1.20.0", kv.GitVersion(), "Expected default KubeVersion.GitVersion() to be v1.20.0, got %q", kv.Version) + assert.Equalf(t, "1", kv.Major, "Expected default KubeVersion.Major to be 1, got %q", kv.Major) + assert.Equalf(t, "20", kv.Minor, "Expected default KubeVersion.Minor to be 20, got %q", kv.Minor) hv := caps.HelmVersion - if hv.Version != "v4.2" { - t.Errorf("Expected default HelmVersion to be v4.2, got %q", hv.Version) - } + assert.Equalf(t, "v4.2", hv.Version, "Expected default HelmVersion to be v4.2, got %q", hv.Version) } func TestParseKubeVersion(t *testing.T) { kv, err := ParseKubeVersion("v1.16.0") - if err != nil { - t.Error("Expected v1.16.0 to parse successfully") - } - if kv.Version != "v1.16.0" { - t.Errorf("Expected parsed KubeVersion.Version to be v1.16.0, got %q", kv.String()) - } - if kv.Major != "1" { - t.Errorf("Expected parsed KubeVersion.Major to be 1, got %q", kv.Major) - } - if kv.Minor != "16" { - t.Errorf("Expected parsed KubeVersion.Minor to be 16, got %q", kv.Minor) - } + require.NoError(t, err, "Expected v1.16.0 to parse successfully") + assert.Equalf(t, "v1.16.0", kv.Version, "Expected parsed KubeVersion.Version to be v1.16.0, got %q", kv.String()) + assert.Equalf(t, "1", kv.Major, "Expected parsed KubeVersion.Major to be 1, got %q", kv.Major) + assert.Equalf(t, "16", kv.Minor, "Expected parsed KubeVersion.Minor to be 16, got %q", kv.Minor) } func TestParseKubeVersionWithVendorSuffixes(t *testing.T) { @@ -101,21 +77,11 @@ func TestParseKubeVersionWithVendorSuffixes(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { kv, err := ParseKubeVersion(tt.input) - if err != nil { - t.Fatalf("ParseKubeVersion() error = %v", err) - } - if kv.Version != tt.wantVer { - t.Errorf("Version = %q, want %q", kv.Version, tt.wantVer) - } - if kv.String() != tt.wantString { - t.Errorf("String() = %q, want %q", kv.String(), tt.wantString) - } - if kv.Major != tt.wantMajor { - t.Errorf("Major = %q, want %q", kv.Major, tt.wantMajor) - } - if kv.Minor != tt.wantMinor { - t.Errorf("Minor = %q, want %q", kv.Minor, tt.wantMinor) - } + require.NoErrorf(t, err, "ParseKubeVersion()") + assert.Equalf(t, tt.wantVer, kv.Version, "Version = %q, want %q", kv.Version, tt.wantVer) + assert.Equalf(t, tt.wantString, kv.String(), "String() = %q, want %q", kv.String(), tt.wantString) + assert.Equalf(t, tt.wantMajor, kv.Major, "Major = %q, want %q", kv.Major, tt.wantMajor) + assert.Equalf(t, tt.wantMinor, kv.Minor, "Minor = %q, want %q", kv.Minor, tt.wantMinor) }) } } diff --git a/pkg/chart/v2/lint/rules/template_test.go b/pkg/chart/v2/lint/rules/template_test.go index 12eec7531..37a33a7eb 100644 --- a/pkg/chart/v2/lint/rules/template_test.go +++ b/pkg/chart/v2/lint/rules/template_test.go @@ -20,7 +20,6 @@ import ( "fmt" "os" "path/filepath" - "strings" "testing" "time" @@ -38,17 +37,11 @@ const templateTestBasedir = "./testdata/albatross" func TestValidateAllowedExtension(t *testing.T) { var failTest = []string{"/foo", "/test.toml"} for _, test := range failTest { - err := validateAllowedExtension(test) - if err == nil || !strings.Contains(err.Error(), "Valid extensions are .yaml, .yml, .tpl, or .txt") { - t.Errorf("validateAllowedExtension('%s') to return \"Valid extensions are .yaml, .yml, .tpl, or .txt\", got no error", test) - } + require.ErrorContainsf(t, validateAllowedExtension(test), "Valid extensions are .yaml, .yml, .tpl, or .txt", "validateAllowedExtension('%s') to return \"Valid extensions are .yaml, .yml, .tpl, or .txt\", got no error", test) } var successTest = []string{"/foo.yaml", "foo.yaml", "foo.tpl", "/foo/bar/baz.yaml", "NOTES.txt"} for _, test := range successTest { - err := validateAllowedExtension(test) - if err != nil { - t.Errorf("validateAllowedExtension('%s') to return no error but got \"%s\"", test, err.Error()) - } + assert.NoError(t, validateAllowedExtension(test), "validateAllowedExtension('%s') to return no error", test) } } @@ -65,13 +58,8 @@ func TestTemplateParsing(t *testing.T) { TemplateLinterSkipSchemaValidation(false)) res := linter.Messages - if len(res) != 1 { - t.Fatalf("Expected one error, got %d, %v", len(res), res) - } - - if !strings.Contains(res[0].Err.Error(), "deliberateSyntaxError") { - t.Errorf("Unexpected error: %s", res[0]) - } + require.Len(t, res, 1, "Expected one error, got %d, %v", len(res), res) + assert.ErrorContains(t, res[0].Err, "deliberateSyntaxError") } var wrongTemplatePath = filepath.Join(templateTestBasedir, "templates", "fail.yaml") @@ -92,9 +80,7 @@ func TestTemplateIntegrationHappyPath(t *testing.T) { TemplateLinterSkipSchemaValidation(false)) res := linter.Messages - if len(res) != 0 { - t.Fatalf("Expected no error, got %d, %v", len(res), res) - } + require.Empty(t, res, "Expected no error, got %d, %v", len(res), res) } func TestMultiTemplateFail(t *testing.T) { @@ -106,13 +92,8 @@ func TestMultiTemplateFail(t *testing.T) { TemplateLinterSkipSchemaValidation(false)) res := linter.Messages - if len(res) != 1 { - t.Fatalf("Expected 1 error, got %d, %v", len(res), res) - } - - if !strings.Contains(res[0].Err.Error(), "object name does not conform to Kubernetes naming requirements") { - t.Errorf("Unexpected error: %s", res[0].Err) - } + require.Len(t, res, 1, "Expected 1 error, got %d, %v", len(res), res) + assert.ErrorContains(t, res[0].Err, "object name does not conform to Kubernetes naming requirements") } func TestValidateMetadataName(t *testing.T) { @@ -221,9 +202,7 @@ func TestDeprecatedAPIFails(t *testing.T) { } tmpdir := t.TempDir() - if err := chartutil.SaveDir(&mychart, tmpdir); err != nil { - t.Fatal(err) - } + require.NoError(t, chartutil.SaveDir(&mychart, tmpdir)) linter := support.Linter{ChartDir: filepath.Join(tmpdir, mychart.Name())} Templates( @@ -279,9 +258,7 @@ func TestStrictTemplateParsingMapError(t *testing.T) { }, } dir := t.TempDir() - if err := chartutil.SaveDir(&ch, dir); err != nil { - t.Fatal(err) - } + require.NoError(t, chartutil.SaveDir(&ch, dir)) linter := &support.Linter{ ChartDir: filepath.Join(dir, ch.Metadata.Name), } @@ -327,9 +304,7 @@ spec: - name: nginx image: nginx:1.14.2 ` - if err := validateMatchSelector(md, manifest); err != nil { - t.Error(err) - } + require.NoError(t, validateMatchSelector(md, manifest)) manifest = ` apiVersion: apps/v1 kind: Deployment @@ -351,9 +326,7 @@ spec: - name: nginx image: nginx:1.14.2 ` - if err := validateMatchSelector(md, manifest); err != nil { - t.Error(err) - } + require.NoError(t, validateMatchSelector(md, manifest)) manifest = ` apiVersion: apps/v1 kind: Deployment @@ -372,9 +345,7 @@ spec: - name: nginx image: nginx:1.14.2 ` - if err := validateMatchSelector(md, manifest); err == nil { - t.Error("expected Deployment with no selector to fail") - } + assert.Error(t, validateMatchSelector(md, manifest), "expected Deployment with no selector to fail") } func TestValidateTopIndentLevel(t *testing.T) { @@ -413,9 +384,7 @@ func TestEmptyWithCommentsManifests(t *testing.T) { } tmpdir := t.TempDir() - if err := chartutil.SaveDir(&mychart, tmpdir); err != nil { - t.Fatal(err) - } + require.NoError(t, chartutil.SaveDir(&mychart, tmpdir)) linter := support.Linter{ChartDir: filepath.Join(tmpdir, mychart.Name())} Templates( @@ -448,10 +417,7 @@ items: annotations: helm.sh/resource-policy: keep ` - - if err := validateListAnnotations(md, manifest); err == nil { - t.Fatal("expected list with nested keep annotations to fail") - } + require.Error(t, validateListAnnotations(md, manifest), "expected list with nested keep annotations to fail") manifest = ` apiVersion: v1 @@ -463,10 +429,7 @@ items: - apiVersion: v1 kind: ConfigMap ` - - if err := validateListAnnotations(md, manifest); err != nil { - t.Fatalf("List objects keep annotations should pass. got: %s", err) - } + require.NoErrorf(t, validateListAnnotations(md, manifest), "List objects keep annotations should pass. got") } func TestIsYamlFileExtension(t *testing.T) { @@ -482,8 +445,6 @@ func TestIsYamlFileExtension(t *testing.T) { for _, test := range tests { result := isYamlFileExtension(test.filename) - if result != test.expected { - t.Errorf("isYamlFileExtension(%s) = %v; want %v", test.filename, result, test.expected) - } + assert.Equal(t, test.expected, result, "isYamlFileExtension(%s) = %v; want %v", test.filename, result, test.expected) } } diff --git a/pkg/cmd/dependency_build_test.go b/pkg/cmd/dependency_build_test.go index 7b3bea28a..485ae18b3 100644 --- a/pkg/cmd/dependency_build_test.go +++ b/pkg/cmd/dependency_build_test.go @@ -19,9 +19,11 @@ import ( "fmt" "os" "path/filepath" - "strings" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + chartutil "helm.sh/helm/v4/pkg/chart/v2/util" "helm.sh/helm/v4/pkg/provenance" "helm.sh/helm/v4/pkg/repo/v1" @@ -39,15 +41,12 @@ func TestDependencyBuildCmd(t *testing.T) { srv.LinkIndices() ociSrv, err := repotest.NewOCIServer(t, srv.Root()) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) ociChartName := "oci-depending-chart" c := createTestingMetadataForOCI(ociChartName, ociSrv.RegistryURL) - if _, err := chartutil.Save(c, ociSrv.Dir); err != nil { - t.Fatal(err) - } + _, err = chartutil.Save(c, ociSrv.Dir) + require.NoError(t, err) ociSrv.Run(t, repotest.WithDependingChart(c)) dir := func(p ...string) string { @@ -67,25 +66,19 @@ func TestDependencyBuildCmd(t *testing.T) { t.Fatal(err) } - if !strings.Contains(out, `update from the "test" chart repository`) { - t.Errorf("Repo did not get updated\n%s", out) - } + assert.Contains(t, out, `update from the "test" chart repository`, "Repo did not get updated\n%s", out) // Make sure the actual file got downloaded. expect := filepath.Join(rootDir, chartname, "charts", "reqtest-0.1.0.tgz") - if _, err := os.Stat(expect); err != nil { - t.Fatal(err) - } + _, err = os.Stat(expect) + require.NoError(t, err) // In the second pass, we want to remove the chart's request dependency, // then see if it restores from the lock. lockfile := filepath.Join(rootDir, chartname, "Chart.lock") - if _, err := os.Stat(lockfile); err != nil { - t.Fatal(err) - } - if err := os.RemoveAll(expect); err != nil { - t.Fatal(err) - } + _, err = os.Stat(lockfile) + require.NoError(t, err) + require.NoError(t, os.RemoveAll(expect)) _, out, err = executeActionCommand(cmd) if err != nil { @@ -94,28 +87,21 @@ func TestDependencyBuildCmd(t *testing.T) { } // Now repeat the test that the dependency exists. - if _, err := os.Stat(expect); err != nil { - t.Fatal(err) - } + _, err = os.Stat(expect) + require.NoError(t, err) // Make sure that build is also fetching the correct version. hash, err := provenance.DigestFile(expect) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) i, err := repo.LoadIndexFile(filepath.Join(rootDir, "index.yaml")) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) reqver := i.Entries["reqtest"][0] - if h := reqver.Digest; h != hash { - t.Errorf("Failed hash match: expected %s, got %s", hash, h) - } - if v := reqver.Version; v != "0.1.0" { - t.Errorf("mismatched versions. Expected %q, got %q", "0.1.0", v) - } + h := reqver.Digest + assert.Equalf(t, h, hash, "Failed hash match: expected %s, got %s", hash, h) + v := reqver.Version + assert.Equalf(t, "0.1.0", v, "mismatched versions. Expected %q, got %q", "0.1.0", v) skipRefreshCmd := fmt.Sprintf("dependency build '%s' --skip-refresh --repository-config %s --repository-cache %s --plain-http", filepath.Join(rootDir, chartname), repoFile, rootDir) _, out, err = executeActionCommand(skipRefreshCmd) @@ -126,14 +112,10 @@ func TestDependencyBuildCmd(t *testing.T) { t.Fatal(err) } - if strings.Contains(out, `update from the "test" chart repository`) { - t.Errorf("Repo did get updated\n%s", out) - } + assert.NotContains(t, out, `update from the "test" chart repository`, "Repo did get updated\n%s", out) // OCI dependencies - if err := chartutil.SaveDir(c, dir()); err != nil { - t.Fatal(err) - } + require.NoError(t, chartutil.SaveDir(c, dir())) cmd = fmt.Sprintf("dependency build '%s' --repository-config %s --repository-cache %s --registry-config %s/config.json --plain-http", dir(ociChartName), dir("repositories.yaml"), @@ -145,9 +127,8 @@ func TestDependencyBuildCmd(t *testing.T) { t.Fatal(err) } expect = dir(ociChartName, "charts/oci-dependent-chart-0.1.0.tgz") - if _, err := os.Stat(expect); err != nil { - t.Fatal(err) - } + _, err = os.Stat(expect) + require.NoError(t, err) } func TestDependencyBuildCmdWithHelmV2Hash(t *testing.T) { diff --git a/pkg/cmd/plugin_package_test.go b/pkg/cmd/plugin_package_test.go index b5ecf2bf1..e04498b98 100644 --- a/pkg/cmd/plugin_package_test.go +++ b/pkg/cmd/plugin_package_test.go @@ -19,8 +19,10 @@ import ( "bytes" "os" "path/filepath" - "strings" "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) // Common plugin.yaml content for v1 format tests @@ -43,14 +45,10 @@ func TestPluginPackageWithoutSigning(t *testing.T) { // Create a test plugin directory tempDir := t.TempDir() pluginDir := filepath.Join(tempDir, "test-plugin") - if err := os.MkdirAll(pluginDir, 0o755); err != nil { - t.Fatal(err) - } + require.NoError(t, os.MkdirAll(pluginDir, 0o755)) // Create a plugin.yaml file - if err := os.WriteFile(filepath.Join(pluginDir, "plugin.yaml"), []byte(testPluginYAML), 0o644); err != nil { - t.Fatal(err) - } + require.NoError(t, os.WriteFile(filepath.Join(pluginDir, "plugin.yaml"), []byte(testPluginYAML), 0o644)) // Create package options with sign=false o := &pluginPackageOptions{ @@ -61,47 +59,34 @@ func TestPluginPackageWithoutSigning(t *testing.T) { // Run the package command out := &bytes.Buffer{} - err := o.run(out) // Should succeed without error - if err != nil { - t.Errorf("unexpected error: %v", err) - } + require.NoError(t, o.run(out)) // Check that tarball was created with plugin name and version tarballPath := filepath.Join(tempDir, "test-plugin-1.0.0.tgz") - if _, err := os.Stat(tarballPath); os.IsNotExist(err) { - t.Error("tarball should exist when sign=false") - } + _, err := os.Stat(tarballPath) + assert.False(t, os.IsNotExist(err), "tarball should exist when sign=false") // Check that no .prov file was created provPath := tarballPath + ".prov" - if _, err := os.Stat(provPath); !os.IsNotExist(err) { - t.Error("provenance file should not exist when sign=false") - } + _, err = os.Stat(provPath) + assert.True(t, os.IsNotExist(err), "provenance file should not exist when sign=false") // Output should contain warning about skipping signing output := out.String() - if !strings.Contains(output, "WARNING: Skipping plugin signing") { - t.Error("should print warning when signing is skipped") - } - if !strings.Contains(output, "Successfully packaged") { - t.Error("should print success message") - } + assert.Contains(t, output, "WARNING: Skipping plugin signing", "should print warning when signing is skipped") + assert.Contains(t, output, "Successfully packaged", "should print success message") } func TestPluginPackageDefaultRequiresSigning(t *testing.T) { // Create a test plugin directory tempDir := t.TempDir() pluginDir := filepath.Join(tempDir, "test-plugin") - if err := os.MkdirAll(pluginDir, 0o755); err != nil { - t.Fatal(err) - } + require.NoError(t, os.MkdirAll(pluginDir, 0o755)) // Create a plugin.yaml file - if err := os.WriteFile(filepath.Join(pluginDir, "plugin.yaml"), []byte(testPluginYAML), 0o644); err != nil { - t.Fatal(err) - } + require.NoError(t, os.WriteFile(filepath.Join(pluginDir, "plugin.yaml"), []byte(testPluginYAML), 0o644)) // Create package options with default sign=true and invalid keyring o := &pluginPackageOptions{ @@ -113,32 +98,24 @@ func TestPluginPackageDefaultRequiresSigning(t *testing.T) { // Run the package command out := &bytes.Buffer{} - err := o.run(out) // Should fail because signing is required by default - if err == nil { - t.Error("expected error when signing fails with default settings") - } + require.Error(t, o.run(out), "expected error when signing fails with default settings") // Check that no tarball was created tarballPath := filepath.Join(tempDir, "test-plugin.tgz") - if _, err := os.Stat(tarballPath); !os.IsNotExist(err) { - t.Error("tarball should not exist when signing fails") - } + _, err := os.Stat(tarballPath) + assert.True(t, os.IsNotExist(err), "tarball should not exist when signing fails") } func TestPluginPackageSigningFailure(t *testing.T) { // Create a test plugin directory tempDir := t.TempDir() pluginDir := filepath.Join(tempDir, "test-plugin") - if err := os.MkdirAll(pluginDir, 0o755); err != nil { - t.Fatal(err) - } + require.NoError(t, os.MkdirAll(pluginDir, 0o755)) // Create a plugin.yaml file - if err := os.WriteFile(filepath.Join(pluginDir, "plugin.yaml"), []byte(testPluginYAML), 0o644); err != nil { - t.Fatal(err) - } + require.NoError(t, os.WriteFile(filepath.Join(pluginDir, "plugin.yaml"), []byte(testPluginYAML), 0o644)) // Create package options with sign flag but invalid keyring o := &pluginPackageOptions{ @@ -150,21 +127,15 @@ func TestPluginPackageSigningFailure(t *testing.T) { // Run the package command out := &bytes.Buffer{} - err := o.run(out) // Should get an error - if err == nil { - t.Error("expected error when signing fails, got nil") - } + require.Error(t, o.run(out), "expected error when signing fails, got nil") // Check that no tarball was created tarballPath := filepath.Join(tempDir, "test-plugin.tgz") - if _, err := os.Stat(tarballPath); !os.IsNotExist(err) { - t.Error("tarball should not exist when signing fails") - } + _, err := os.Stat(tarballPath) + assert.True(t, os.IsNotExist(err), "tarball should not exist when signing fails") // Output should not contain success message - if bytes.Contains(out.Bytes(), []byte("Successfully packaged")) { - t.Error("should not print success message when signing fails") - } + assert.False(t, bytes.Contains(out.Bytes(), []byte("Successfully packaged")), "should not print success message when signing fails") } diff --git a/pkg/cmd/repo_add_test.go b/pkg/cmd/repo_add_test.go index ed677f98a..6ed2a7422 100644 --- a/pkg/cmd/repo_add_test.go +++ b/pkg/cmd/repo_add_test.go @@ -17,16 +17,16 @@ limitations under the License. package cmd import ( - "errors" "fmt" "io" "io/fs" "os" "path/filepath" - "strings" "sync" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "sigs.k8s.io/yaml" "helm.sh/helm/v4/pkg/helmpath" @@ -50,9 +50,7 @@ func TestRepoAddCmd(t *testing.T) { defer srv2.Stop() tmpdir := filepath.Join(t.TempDir(), "path-component.yaml", "data") - if err := os.MkdirAll(tmpdir, 0o777); err != nil { - t.Fatal(err) - } + require.NoError(t, os.MkdirAll(tmpdir, 0o777)) repoFile := filepath.Join(tmpdir, "repositories.yaml") tests := []cmdTestCase{ @@ -101,37 +99,24 @@ func TestRepoAdd(t *testing.T) { } t.Setenv(xdg.CacheHomeEnvVar, rootDir) - if err := o.run(io.Discard); err != nil { - t.Error(err) - } + require.NoError(t, o.run(io.Discard)) f, err := repo.LoadFile(repoFile) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if !f.Has(testRepoName) { - t.Errorf("%s was not successfully inserted into %s", testRepoName, repoFile) - } + assert.Truef(t, f.Has(testRepoName), "%s was not successfully inserted into %s", testRepoName, repoFile) idx := filepath.Join(helmpath.CachePath("repository"), helmpath.CacheIndexFile(testRepoName)) - if _, err := os.Stat(idx); errors.Is(err, fs.ErrNotExist) { - t.Errorf("Error cache index file was not created for repository %s", testRepoName) - } + _, err = os.Stat(idx) + require.NotErrorIsf(t, err, fs.ErrNotExist, "Error cache index file was not created for repository %s", testRepoName) idx = filepath.Join(helmpath.CachePath("repository"), helmpath.CacheChartsFile(testRepoName)) - if _, err := os.Stat(idx); errors.Is(err, fs.ErrNotExist) { - t.Errorf("Error cache charts file was not created for repository %s", testRepoName) - } + _, err = os.Stat(idx) + require.NotErrorIsf(t, err, fs.ErrNotExist, "Error cache charts file was not created for repository %s", testRepoName) o.forceUpdate = true - if err := o.run(io.Discard); err != nil { - t.Errorf("Repository was not updated: %s", err) - } - - if err := o.run(io.Discard); err != nil { - t.Error("Duplicate repository name was added") - } + require.NoError(t, o.run(io.Discard), "Repository was not updated") + assert.NoError(t, o.run(io.Discard), "Duplicate repository name was added") } func TestRepoAddCheckLegalName(t *testing.T) { @@ -156,14 +141,7 @@ func TestRepoAddCheckLegalName(t *testing.T) { t.Setenv(xdg.CacheHomeEnvVar, rootDir) wantErrorMsg := fmt.Sprintf("repository name (%s) contains '/', please specify a different name without '/'", testRepoName) - - if err := o.run(io.Discard); err != nil { - if wantErrorMsg != err.Error() { - t.Fatalf("Actual error %s, not equal to expected error %s", err, wantErrorMsg) - } - } else { - t.Fatal("expect reported an error.") - } + require.EqualError(t, o.run(io.Discard), wantErrorMsg) } func TestRepoAddConcurrentGoRoutines(t *testing.T) { @@ -209,29 +187,21 @@ func repoAddConcurrent(t *testing.T, testName, repoFile string) { forceUpdate: false, repoFile: repoFile, } - if err := o.run(io.Discard); err != nil { - t.Error(err) - } + assert.NoError(t, o.run(io.Discard)) }(fmt.Sprintf("%s-%d", testName, i)) } wg.Wait() b, err := os.ReadFile(repoFile) - if err != nil { - t.Error(err) - } + require.NoError(t, err) var f repo.File - if err := yaml.Unmarshal(b, &f); err != nil { - t.Error(err) - } + require.NoError(t, yaml.Unmarshal(b, &f)) var name string for i := range 3 { name = fmt.Sprintf("%s-%d", testName, i) - if !f.Has(name) { - t.Errorf("%s was not successfully inserted into %s: %s", name, repoFile, f.Repositories[0]) - } + assert.Truef(t, f.Has(name), "%s was not successfully inserted into %s: %s", name, repoFile, f.Repositories[0]) } } @@ -252,9 +222,7 @@ func TestRepoAddWithPasswordFromStdin(t *testing.T) { defer resetEnv()() in, err := os.Open("testdata/password") - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } + require.NoError(t, err) tmpdir := t.TempDir() repoFile := filepath.Join(tmpdir, "repositories.yaml") @@ -266,11 +234,7 @@ func TestRepoAddWithPasswordFromStdin(t *testing.T) { 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) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } - if !strings.Contains(result, fmt.Sprintf("%q has been added to your repositories", testName)) { - t.Errorf("Repo was not successfully added. Output: %s", result) - } + require.NoError(t, err) + assert.Contains(t, result, fmt.Sprintf("%q has been added to your repositories", testName), "Repo was not successfully added. Output: %s", result) } From 0fa9f7d427b99437e51dbb8ada21d19f93898652 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 20:50:56 +0200 Subject: [PATCH 36/61] chore(pkg): refactor: convert tests to testify assert/require part 16 #### Description refactor: convert tests to testify assert/require in pkg/cmd Signed-off-by: Matthieu MOREL --- pkg/action/get_metadata_test.go | 6 +- pkg/chart/common/values_test.go | 116 ++++++++++++------------------- pkg/chart/v2/util/expand_test.go | 92 +++++++----------------- pkg/cmd/plugin_verify_test.go | 83 +++++----------------- pkg/cmd/pull_test.go | 105 +++++++++------------------- 5 files changed, 120 insertions(+), 282 deletions(-) diff --git a/pkg/action/get_metadata_test.go b/pkg/action/get_metadata_test.go index 37f20fb60..f8851e456 100644 --- a/pkg/action/get_metadata_test.go +++ b/pkg/action/get_metadata_test.go @@ -65,8 +65,7 @@ func TestGetMetadata_Run_BasicMetadata(t *testing.T) { Namespace: "default", } - err := cfg.Releases.Create(rel) - require.NoError(t, err) + require.NoError(t, cfg.Releases.Create(rel)) result, err := client.Run(releaseName) require.NoError(t, err) @@ -645,8 +644,7 @@ func TestGetMetadata_Labels(t *testing.T) { rel.Labels = customLabels metaGetter := NewGetMetadata(actionConfigFixture(t)) - err := metaGetter.cfg.Releases.Create(rel) - require.NoError(t, err) + require.NoError(t, metaGetter.cfg.Releases.Create(rel)) metadata, err := metaGetter.Run(rel.Name) require.NoError(t, err) diff --git a/pkg/chart/common/values_test.go b/pkg/chart/common/values_test.go index 9743869ec..803513c32 100644 --- a/pkg/chart/common/values_test.go +++ b/pkg/chart/common/values_test.go @@ -21,6 +21,9 @@ import ( "fmt" "testing" "text/template" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestReadValues(t *testing.T) { @@ -46,29 +49,21 @@ water: ` data, err := ReadValues([]byte(doc)) - if err != nil { - t.Fatalf("Error parsing bytes: %s", err) - } + require.NoErrorf(t, err, "Error parsing bytes") matchValues(t, data) tests := []string{`poet: "Coleridge"`, "# Just a comment", ""} for _, tt := range tests { data, err = ReadValues([]byte(tt)) - if err != nil { - t.Fatalf("Error parsing bytes (%s): %s", tt, err) - } - if data == nil { - t.Errorf(`YAML string "%s" gave a nil map`, tt) - } + require.NoErrorf(t, err, "Error parsing bytes (%s)", tt) + require.NotNilf(t, data, `YAML string "%s" gave a nil map`, tt) } } func TestReadValuesFile(t *testing.T) { data, err := ReadValuesFile("./testdata/coleridge.yaml") - if err != nil { - t.Fatalf("Error reading YAML file: %s", err) - } + require.NoErrorf(t, err, "Error reading YAML file") matchValues(t, data) } @@ -108,56 +103,40 @@ chapter: title: "The Spouter Inn" ` d, err := ReadValues([]byte(doc)) - if err != nil { - t.Fatalf("Failed to parse the White Whale: %s", err) - } + require.NoErrorf(t, err, "Failed to parse the White Whale") - if _, err := d.Table("title"); err == nil { - t.Fatal("Title is not a table.") - } + _, err = d.Table("title") + require.Error(t, err, "Title is not a table.") - if _, err := d.Table("chapter"); err != nil { - t.Fatalf("Failed to get the chapter table: %s\n%v", err, d) - } + _, err = d.Table("chapter") + require.NoErrorf(t, err, "Failed to get the chapter table: %v", d) - if v, err := d.Table("chapter.one"); err != nil { - t.Errorf("Failed to get chapter.one: %s", err) - } else if v["title"] != "Loomings" { - t.Errorf("Unexpected title: %s", v["title"]) - } + v, err := d.Table("chapter.one") + require.NoErrorf(t, err, "Failed to get chapter.one") + assert.Equalf(t, "Loomings", v["title"], "Unexpected title: %s", v["title"]) - if _, err := d.Table("chapter.three"); err != nil { - t.Errorf("Chapter three is missing: %s\n%v", err, d) - } + _, err = d.Table("chapter.three") + require.NoErrorf(t, err, "Chapter three is missing: %v", d) - if _, err := d.Table("chapter.OneHundredThirtySix"); err == nil { - t.Error("I think you mean 'Epilogue'") - } + _, err = d.Table("chapter.OneHundredThirtySix") + assert.Error(t, err, "I think you mean 'Epilogue'") } func matchValues(t *testing.T, data map[string]any) { t.Helper() - if data["poet"] != "Coleridge" { - t.Errorf("Unexpected poet: %s", data["poet"]) - } + assert.Equalf(t, "Coleridge", data["poet"], "Unexpected poet: %s", data["poet"]) - if o, err := ttpl("{{len .stanza}}", data); err != nil { - t.Errorf("len stanza: %s", err) - } else if o != "6" { - t.Errorf("Expected 6, got %s", o) - } + o, err := ttpl("{{len .stanza}}", data) + require.NoErrorf(t, err, "len stanza") + assert.Equalf(t, "6", o, "Expected 6, got %s", o) - if o, err := ttpl("{{.mariner.shot}}", data); err != nil { - t.Errorf(".mariner.shot: %s", err) - } else if o != "ALBATROSS" { - t.Error("Expected that mariner shot ALBATROSS") - } + o, err = ttpl("{{.mariner.shot}}", data) + require.NoErrorf(t, err, ".mariner.shot") + assert.Equal(t, "ALBATROSS", o, "Expected that mariner shot ALBATROSS") - if o, err := ttpl("{{.water.water.where}}", data); err != nil { - t.Errorf(".water.water.where: %s", err) - } else if o != "everywhere" { - t.Error("Expected water water everywhere") - } + o, err = ttpl("{{.water.water.where}}", data) + require.NoErrorf(t, err, ".water.water.where") + assert.Equal(t, "everywhere", o, "Expected water water everywhere") } func ttpl(tpl string, v map[string]any) (string, error) { @@ -179,27 +158,18 @@ chapter: title: "The Spouter Inn" ` d, err := ReadValues([]byte(doc)) - if err != nil { - t.Fatalf("Failed to parse the White Whale: %s", err) - } - - if v, err := d.PathValue("chapter.one.title"); err != nil { - t.Errorf("Got error instead of title: %s\n%v", err, d) - } else if v != "Loomings" { - t.Errorf("No error but got wrong value for title: %s\n%v", err, d) - } - if _, err := d.PathValue("chapter.one.doesnotexist"); err == nil { - t.Errorf("Non-existent key should return error: %s\n%v", err, d) - } - if _, err := d.PathValue("chapter.doesnotexist.one"); err == nil { - t.Errorf("Non-existent key in middle of path should return error: %s\n%v", err, d) - } - if _, err := d.PathValue(""); err == nil { - t.Error("Asking for the value from an empty path should yield an error") - } - if v, err := d.PathValue("title"); err == nil { - if v != "Moby Dick" { - t.Error("Failed to return values for root key title") - } - } + require.NoErrorf(t, err, "Failed to parse the White Whale") + + v, err := d.PathValue("chapter.one.title") + require.NoErrorf(t, err, "Got error instead of title: %v", d) + assert.Equalf(t, "Loomings", v, "No error but got wrong value for title: %v", d) + _, err = d.PathValue("chapter.one.doesnotexist") + require.Errorf(t, err, "Non-existent key should return error: %v", d) + _, err = d.PathValue("chapter.doesnotexist.one") + require.Errorf(t, err, "Non-existent key in middle of path should return error: %v", d) + _, err = d.PathValue("") + require.Error(t, err, "Asking for the value from an empty path should yield an error") + v, err = d.PathValue("title") + require.NoErrorf(t, err, "Failed to get title: %v", d) + assert.Equalf(t, "Moby Dick", v, "Failed to return values for root key title: got %s\n%v", v, d) } diff --git a/pkg/chart/v2/util/expand_test.go b/pkg/chart/v2/util/expand_test.go index e9e298b81..bc8cc7855 100644 --- a/pkg/chart/v2/util/expand_test.go +++ b/pkg/chart/v2/util/expand_test.go @@ -47,19 +47,18 @@ func makeTestChartArchive(t *testing.T, chartName, sourceDir string) *bytes.Buff fStat, err := f.Stat() require.NoError(t, err) - err = tw.WriteHeader(&tar.Header{ + require.NoError(t, tw.WriteHeader(&tar.Header{ Name: filepath.Join(chartName, relPath), Mode: int64(fStat.Mode()), Size: fStat.Size(), - }) - require.NoError(t, err) + })) data, err := fs.ReadFile(dir, relPath) require.NoError(t, err) tw.Write(data) } - err := fs.WalkDir(dir, ".", func(path string, d os.DirEntry, walkErr error) error { + require.NoError(t, fs.WalkDir(dir, ".", func(path string, d os.DirEntry, walkErr error) error { if walkErr != nil { return walkErr } @@ -71,15 +70,9 @@ func makeTestChartArchive(t *testing.T, chartName, sourceDir string) *bytes.Buff writeFile(path) return nil - }) - if err != nil { - t.Fatal(err) - } - - err = tw.Close() - require.NoError(t, err) - err = gw.Close() - require.NoError(t, err) + })) + require.NoError(t, tw.Close()) + require.NoError(t, gw.Close()) return &result } @@ -88,51 +81,33 @@ func TestExpand(t *testing.T) { dest := t.TempDir() reader, err := os.Open("testdata/frobnitz-1.2.3.tgz") - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if err := Expand(dest, reader); err != nil { - t.Fatal(err) - } + require.NoError(t, Expand(dest, reader)) expectedChartPath := filepath.Join(dest, "frobnitz") fi, err := os.Stat(expectedChartPath) - if err != nil { - t.Fatal(err) - } - if !fi.IsDir() { - t.Fatalf("expected a chart directory at %s", expectedChartPath) - } + require.NoError(t, err) + require.Truef(t, fi.IsDir(), "expected a chart directory at %s", expectedChartPath) dir, err := os.Open(expectedChartPath) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) fis, err := dir.Readdir(0) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) expectLen := 11 - if len(fis) != expectLen { - t.Errorf("Expected %d files, but got %d", expectLen, len(fis)) - } + assert.Len(t, fis, expectLen, "Expected %d files, but got %d", expectLen, len(fis)) for _, fi := range fis { expect, err := os.Stat(filepath.Join("testdata", "frobnitz", fi.Name())) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) // os.Stat can return different values for directories, based on the OS // for Linux, for example, os.Stat always returns the size of the directory // (value-4096) regardless of the size of the contents of the directory mode := expect.Mode() if !mode.IsDir() { - if fi.Size() != expect.Size() { - t.Errorf("Expected %s to have size %d, got %d", fi.Name(), expect.Size(), fi.Size()) - } + assert.Equal(t, expect.Size(), fi.Size(), "Expected %s to have size %d, got %d", fi.Name(), expect.Size(), fi.Size()) } } } @@ -151,10 +126,9 @@ func TestExpandError(t *testing.T) { for name, tt := range tests { t.Run(name, func(t *testing.T) { archive := makeTestChartArchive(t, tt.chartName, tt.chartDir) - dest := t.TempDir() - err := Expand(dest, archive) - assert.ErrorContains(t, err, tt.wantErr) + + assert.ErrorContains(t, Expand(dest, archive), tt.wantErr) }) } } @@ -162,47 +136,31 @@ func TestExpandError(t *testing.T) { func TestExpandFile(t *testing.T) { dest := t.TempDir() - if err := ExpandFile(dest, "testdata/frobnitz-1.2.3.tgz"); err != nil { - t.Fatal(err) - } + require.NoError(t, ExpandFile(dest, "testdata/frobnitz-1.2.3.tgz")) expectedChartPath := filepath.Join(dest, "frobnitz") fi, err := os.Stat(expectedChartPath) - if err != nil { - t.Fatal(err) - } - if !fi.IsDir() { - t.Fatalf("expected a chart directory at %s", expectedChartPath) - } + require.NoError(t, err) + require.Truef(t, fi.IsDir(), "expected a chart directory at %s", expectedChartPath) dir, err := os.Open(expectedChartPath) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) fis, err := dir.Readdir(0) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) expectLen := 11 - if len(fis) != expectLen { - t.Errorf("Expected %d files, but got %d", expectLen, len(fis)) - } + assert.Len(t, fis, expectLen, "Expected %d files, but got %d", expectLen, len(fis)) for _, fi := range fis { expect, err := os.Stat(filepath.Join("testdata", "frobnitz", fi.Name())) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) // os.Stat can return different values for directories, based on the OS // for Linux, for example, os.Stat always returns the size of the directory // (value-4096) regardless of the size of the contents of the directory mode := expect.Mode() if !mode.IsDir() { - if fi.Size() != expect.Size() { - t.Errorf("Expected %s to have size %d, got %d", fi.Name(), expect.Size(), fi.Size()) - } + assert.Equal(t, expect.Size(), fi.Size(), "Expected %s to have size %d, got %d", fi.Name(), expect.Size(), fi.Size()) } } } diff --git a/pkg/cmd/plugin_verify_test.go b/pkg/cmd/plugin_verify_test.go index 4ce664c0c..64e6cc18c 100644 --- a/pkg/cmd/plugin_verify_test.go +++ b/pkg/cmd/plugin_verify_test.go @@ -21,9 +21,11 @@ import ( "fmt" "os" "path/filepath" - "strings" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "helm.sh/helm/v4/internal/plugin" "helm.sh/helm/v4/internal/test/ensure" ) @@ -35,13 +37,7 @@ func TestPluginVerifyCmd_NoArgs(t *testing.T) { cmd := newPluginVerifyCmd(out) cmd.SetArgs([]string{}) - err := cmd.Execute() - if err == nil { - t.Error("expected error when no arguments provided") - } - if !strings.Contains(err.Error(), "requires 1 argument") { - t.Errorf("expected 'requires 1 argument' error, got: %v", err) - } + assert.ErrorContains(t, cmd.Execute(), "requires 1 argument", "expected 'requires 1 argument' error") } func TestPluginVerifyCmd_TooManyArgs(t *testing.T) { @@ -51,13 +47,7 @@ func TestPluginVerifyCmd_TooManyArgs(t *testing.T) { cmd := newPluginVerifyCmd(out) cmd.SetArgs([]string{"plugin1", "plugin2"}) - err := cmd.Execute() - if err == nil { - t.Error("expected error when too many arguments provided") - } - if !strings.Contains(err.Error(), "requires 1 argument") { - t.Errorf("expected 'requires 1 argument' error, got: %v", err) - } + assert.ErrorContains(t, cmd.Execute(), "requires 1 argument", "expected 'requires 1 argument' error") } func TestPluginVerifyCmd_NonexistentFile(t *testing.T) { @@ -67,10 +57,7 @@ func TestPluginVerifyCmd_NonexistentFile(t *testing.T) { cmd := newPluginVerifyCmd(out) cmd.SetArgs([]string{"/nonexistent/plugin.tgz"}) - err := cmd.Execute() - if err == nil { - t.Error("expected error when plugin file doesn't exist") - } + assert.Error(t, cmd.Execute(), "expected error when plugin file doesn't exist") } func TestPluginVerifyCmd_MissingProvenance(t *testing.T) { @@ -84,13 +71,7 @@ func TestPluginVerifyCmd_MissingProvenance(t *testing.T) { cmd := newPluginVerifyCmd(out) cmd.SetArgs([]string{pluginTgz}) - err := cmd.Execute() - if err == nil { - t.Error("expected error when .prov file is missing") - } - if !strings.Contains(err.Error(), "could not find provenance file") { - t.Errorf("expected 'could not find provenance file' error, got: %v", err) - } + assert.ErrorContains(t, cmd.Execute(), "could not find provenance file", "expected 'could not find provenance file' error") } func TestPluginVerifyCmd_InvalidProvenance(t *testing.T) { @@ -102,19 +83,14 @@ func TestPluginVerifyCmd_InvalidProvenance(t *testing.T) { // Create invalid .prov file provFile := pluginTgz + ".prov" - if err := os.WriteFile(provFile, []byte("invalid provenance"), 0o644); err != nil { - t.Fatal(err) - } + require.NoError(t, os.WriteFile(provFile, []byte("invalid provenance"), 0o644)) defer os.Remove(provFile) out := &bytes.Buffer{} cmd := newPluginVerifyCmd(out) cmd.SetArgs([]string{pluginTgz}) - err := cmd.Execute() - if err == nil { - t.Error("expected error when .prov file is invalid") - } + assert.Error(t, cmd.Execute(), "expected error when .prov file is invalid") } func TestPluginVerifyCmd_DirectoryNotSupported(t *testing.T) { @@ -127,13 +103,7 @@ func TestPluginVerifyCmd_DirectoryNotSupported(t *testing.T) { cmd := newPluginVerifyCmd(out) cmd.SetArgs([]string{pluginDir}) - err := cmd.Execute() - if err == nil { - t.Error("expected error when verifying directory") - } - if !strings.Contains(err.Error(), "directory verification not supported") { - t.Errorf("expected 'directory verification not supported' error, got: %v", err) - } + assert.ErrorContains(t, cmd.Execute(), "directory verification not supported", "expected 'directory verification not supported' error") } func TestPluginVerifyCmd_KeyringFlag(t *testing.T) { @@ -157,10 +127,7 @@ func TestPluginVerifyCmd_KeyringFlag(t *testing.T) { cmd.SetArgs([]string{"--keyring", keyring, pluginTgz}) // Should fail with keyring error but command parsing should work - err := cmd.Execute() - if err == nil { - t.Error("expected error with empty keyring") - } + assert.Error(t, cmd.Execute(), "expected error with empty keyring") // The important thing is that the keyring flag was parsed and used } @@ -178,14 +145,10 @@ func createTestPluginDir(t *testing.T) string { // Create temporary directory with plugin structure tmpDir := t.TempDir() pluginDir := filepath.Join(tmpDir, "test-plugin") - if err := os.MkdirAll(pluginDir, 0o755); err != nil { - t.Fatalf("Failed to create plugin directory: %v", err) - } + require.NoErrorf(t, os.MkdirAll(pluginDir, 0o755), "Failed to create plugin directory") // Use the same plugin YAML as other cmd tests - if err := os.WriteFile(filepath.Join(pluginDir, "plugin.yaml"), []byte(testPluginYAML), 0o644); err != nil { - t.Fatalf("Failed to create plugin.yaml: %v", err) - } + require.NoErrorf(t, os.WriteFile(filepath.Join(pluginDir, "plugin.yaml"), []byte(testPluginYAML), 0o644), "Failed to create plugin.yaml") return pluginDir } @@ -199,14 +162,10 @@ func createTestPluginTarball(t *testing.T) string { tmpDir := filepath.Dir(pluginDir) tgzPath := filepath.Join(tmpDir, "test-plugin-1.0.0.tgz") tarFile, err := os.Create(tgzPath) - if err != nil { - t.Fatalf("Failed to create tarball file: %v", err) - } + require.NoError(t, err, "Failed to create tarball file") defer tarFile.Close() - if err := plugin.CreatePluginTarball(pluginDir, "test-plugin", tarFile); err != nil { - t.Fatalf("Failed to create tarball: %v", err) - } + require.NoErrorf(t, plugin.CreatePluginTarball(pluginDir, "test-plugin", tarFile), "Failed to create tarball") return tgzPath } @@ -218,9 +177,7 @@ func createProvFile(t *testing.T, provFile, pluginTgz, hash string) { if hash == "" { // Calculate actual hash of the tarball data, err := os.ReadFile(pluginTgz) - if err != nil { - t.Fatalf("Failed to read tarball for hashing: %v", err) - } + require.NoError(t, err, "Failed to read tarball for hashing") hashSum := sha256.Sum256(data) hashStr = fmt.Sprintf("sha256:%x", hashSum) } else { @@ -243,9 +200,7 @@ Version: GnuPG v1 iQEcBAEBCAAGBQJktest... -----END PGP SIGNATURE----- `, hashStr) - if err := os.WriteFile(provFile, []byte(provContent), 0o644); err != nil { - t.Fatalf("Failed to create provenance file: %v", err) - } + require.NoErrorf(t, os.WriteFile(provFile, []byte(provContent), 0o644), "Failed to create provenance file") } func createTestKeyring(t *testing.T) string { @@ -256,9 +211,7 @@ func createTestKeyring(t *testing.T) string { keyringPath := filepath.Join(tmpDir, "pubring.gpg") // Create empty keyring for testing - if err := os.WriteFile(keyringPath, []byte{}, 0o644); err != nil { - t.Fatalf("Failed to create test keyring: %v", err) - } + require.NoErrorf(t, os.WriteFile(keyringPath, []byte{}, 0o644), "Failed to create test keyring") return keyringPath } diff --git a/pkg/cmd/pull_test.go b/pkg/cmd/pull_test.go index e1b3e8134..352c36a29 100644 --- a/pkg/cmd/pull_test.go +++ b/pkg/cmd/pull_test.go @@ -25,6 +25,9 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "helm.sh/helm/v4/pkg/repo/v1/repotest" ) @@ -36,14 +39,10 @@ func TestPullCmd(t *testing.T) { defer srv.Stop() ociSrv, err := repotest.NewOCIServer(t, srv.Root()) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) ociSrv.Run(t) - if err := srv.LinkIndices(); err != nil { - t.Fatal(err) - } + require.NoError(t, srv.LinkIndices()) helmTestKeyOut := "Signed by: Helm Testing (This key should only be used for testing. DO NOT TRUST.) \n" + "Using Key With Fingerprint: 5E615389B53CA37F0EE60BD3843BBF981FC18762\n" + @@ -229,20 +228,13 @@ func TestPullCmd(t *testing.T) { // Create file or Dir before helm pull --untar, see: https://github.com/helm/helm/issues/7182 if tt.existFile != "" { file := filepath.Join(outdir, tt.existFile) - if err := os.MkdirAll(filepath.Dir(file), 0o755); err != nil { - t.Fatal(err) - } - _, err := os.Create(file) - if err != nil { - t.Fatal(err) - } + require.NoError(t, os.MkdirAll(filepath.Dir(file), 0o755)) + _, err = os.Create(file) + require.NoError(t, err) } if tt.existDir != "" { file := filepath.Join(outdir, tt.existDir) - err := os.MkdirAll(file, 0o755) - if err != nil { - t.Fatal(err) - } + require.NoError(t, os.MkdirAll(file, 0o755)) } _, out, err := executeActionCommand(cmd) if err != nil { @@ -257,19 +249,13 @@ func TestPullCmd(t *testing.T) { if tt.expectVerify { outString := helmTestKeyOut + tt.expectSha + "\n" - if out != outString { - t.Errorf("%q: expected verification output %q, got %q", tt.name, outString, out) - } + assert.Equal(t, outString, out, "%q: expected verification output %q, got %q", tt.name, outString, out) } ef := filepath.Join(outdir, tt.expectFile) fi, err := os.Stat(ef) - if err != nil { - t.Errorf("%q: expected a file at %s. %s", tt.name, ef, err) - } - if fi.IsDir() != tt.expectDir { - t.Errorf("%q: expected directory=%t, but it's not.", tt.name, tt.expectDir) - } + require.NoError(t, err, "%q: expected a file at %s.", tt.name, ef) + assert.Equal(t, tt.expectDir, fi.IsDir(), "%q: expected directory=%t, but it's not.", tt.name, tt.expectDir) }) } } @@ -300,38 +286,24 @@ func runPullTests(t *testing.T, tests []struct { if tt.existFile != "" { file := filepath.Join(outdir, tt.existFile) _, err := os.Create(file) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) } if tt.existDir != "" { file := filepath.Join(outdir, tt.existDir) - err := os.MkdirAll(file, 0o755) - if err != nil { - t.Fatal(err) - } + require.NoError(t, os.MkdirAll(file, 0o755)) } _, _, err := executeActionCommand(cmd) - if tt.wantError && err == nil { - t.Fatalf("%q: expected error but got none", tt.name) - } - if err != nil { - if tt.wantError { - if tt.wantErrorMsg != "" && tt.wantErrorMsg != err.Error() { - t.Fatalf("Actual error '%s', not equal to expected error '%s'", err, tt.wantErrorMsg) - } - return + if tt.wantError { + require.Error(t, err, "%q: expected error but got none", tt.name) + if tt.wantErrorMsg != "" { + require.EqualErrorf(t, err, tt.wantErrorMsg, "Actual error '%s', not equal to expected error '%s'", err, tt.wantErrorMsg) } - t.Fatalf("%q reported error: %s", tt.name, err) - } - - ef := filepath.Join(outdir, tt.expectFile) - fi, err := os.Stat(ef) - if err != nil { - t.Errorf("%q: expected a file at %s. %s", tt.name, ef, err) - } - if fi.IsDir() != tt.expectDir { - t.Errorf("%q: expected directory=%t, but it's not.", tt.name, tt.expectDir) + } else { + require.NoError(t, err, "%q reported error", tt.name) + ef := filepath.Join(outdir, tt.expectFile) + fi, err := os.Stat(ef) + require.NoError(t, err, "%q: expected a file at %s.", tt.name, ef) + assert.Equal(t, tt.expectDir, fi.IsDir(), "%q: expected directory=%t, but it's not.", tt.name, tt.expectDir) } }) } @@ -362,9 +334,7 @@ func TestPullWithCredentialsCmd(t *testing.T) { })) defer srv2.Close() - if err := srv.LinkIndices(); err != nil { - t.Fatal(err) - } + require.NoError(t, srv.LinkIndices()) // all flags will get "-d outdir" appended. tests := []struct { @@ -445,14 +415,10 @@ func TestPullWithCredentialsCmdOCIRegistry(t *testing.T) { defer srv.Stop() ociSrv, err := repotest.NewOCIServer(t, srv.Root()) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) ociSrv.Run(t) - if err := srv.LinkIndices(); err != nil { - t.Fatal(err) - } + require.NoError(t, srv.LinkIndices()) // all flags will get "-d outdir" appended. tests := []struct { @@ -517,9 +483,7 @@ func TestPullOCIWithTagAndDigest(t *testing.T) { defer srv.Stop() ociSrv, err := repotest.NewOCIServer(t, srv.Root()) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) result := ociSrv.RunWithReturn(t) contentCache := t.TempDir() @@ -538,9 +502,7 @@ func TestPullOCIWithTagAndDigest(t *testing.T) { ) _, _, err = executeActionCommand(cmd) - if err != nil { - t.Fatalf("pull with tag+digest failed: %v", err) - } + require.NoError(t, err, "pull with tag+digest failed") // Verify the file was downloaded // When digest is present, the filename uses the digest format (e.g. chart@sha256-hex.tgz) @@ -548,12 +510,9 @@ func TestPullOCIWithTagAndDigest(t *testing.T) { if _, err := os.Stat(expectedFile); err != nil { // Try the digest-based filename; parse algorithm:hex to avoid fixed-offset assumptions algorithm, digestPart, ok := strings.Cut(result.PushedChart.Manifest.Digest, ":") - if !ok { - t.Fatalf("digest must be in algorithm:hex format, got %q", result.PushedChart.Manifest.Digest) - } + require.True(t, ok, "digest must be in algorithm:hex format, got %q", result.PushedChart.Manifest.Digest) expectedFile = filepath.Join(outdir, fmt.Sprintf("oci-dependent-chart@%s-%s.tgz", algorithm, digestPart)) - if _, err := os.Stat(expectedFile); err != nil { - t.Errorf("expected chart file not found: %v", err) - } + _, err := os.Stat(expectedFile) + assert.NoErrorf(t, err, "expected chart file not found") } } From fb8a62bf13cbc0ad78d0856678365b246b224997 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 20:50:56 +0200 Subject: [PATCH 37/61] chore(pkg): refactor: convert tests to testify assert/require part 18 #### Description refactor: convert tests to testify assert/require in pkg/cmd Signed-off-by: Matthieu MOREL --- pkg/action/package_test.go | 54 ++++----------- pkg/chart/v2/lint/rules/dependencies_test.go | 22 ++---- pkg/chart/v2/util/create_test.go | 71 ++++++-------------- pkg/cmd/plugin_uninstall_test.go | 66 +++++++----------- pkg/cmd/repo_remove_test.go | 62 ++++++----------- pkg/cmd/repo_update_test.go | 65 ++++++------------ pkg/kube/resource_test.go | 45 ++++--------- 7 files changed, 117 insertions(+), 268 deletions(-) diff --git a/pkg/action/package_test.go b/pkg/action/package_test.go index 9984b508a..421f34b33 100644 --- a/pkg/action/package_test.go +++ b/pkg/action/package_test.go @@ -17,7 +17,6 @@ limitations under the License. package action import ( - "errors" "os" "path" "testing" @@ -35,18 +34,12 @@ func TestPassphraseFileFetcher(t *testing.T) { testPkg := NewPackage() fetcher, err := testPkg.passphraseFileFetcher(path.Join(directory, "passphrase-file"), nil) - if err != nil { - t.Fatal("Unable to create passphraseFileFetcher", err) - } + require.NoError(t, err, "Unable to create passphraseFileFetcher") passphrase, err := fetcher("key") - if err != nil { - t.Fatal("Unable to fetch passphrase") - } + require.NoError(t, err, "Unable to fetch passphrase") - if string(passphrase) != secret { - t.Errorf("Expected %s got %s", secret, string(passphrase)) - } + assert.Equal(t, secret, string(passphrase), "Expected %s got %s", secret, string(passphrase)) } func TestPassphraseFileFetcher_WithLineBreak(t *testing.T) { @@ -55,18 +48,12 @@ func TestPassphraseFileFetcher_WithLineBreak(t *testing.T) { testPkg := NewPackage() fetcher, err := testPkg.passphraseFileFetcher(path.Join(directory, "passphrase-file"), nil) - if err != nil { - t.Fatal("Unable to create passphraseFileFetcher", err) - } + require.NoError(t, err, "Unable to create passphraseFileFetcher") passphrase, err := fetcher("key") - if err != nil { - t.Fatal("Unable to fetch passphrase") - } + require.NoError(t, err, "Unable to fetch passphrase") - if string(passphrase) != secret { - t.Errorf("Expected %s got %s", secret, string(passphrase)) - } + assert.Equal(t, secret, string(passphrase), "Expected %s got %s", secret, string(passphrase)) } func TestPassphraseFileFetcher_WithInvalidStdin(t *testing.T) { @@ -74,21 +61,16 @@ func TestPassphraseFileFetcher_WithInvalidStdin(t *testing.T) { testPkg := NewPackage() stdin, err := os.CreateTemp(directory, "non-existing") - if err != nil { - t.Fatal("Unable to create test file", err) - } + require.NoError(t, err, "Unable to create test file") - if _, err := testPkg.passphraseFileFetcher("-", stdin); err == nil { - t.Error("Expected passphraseFileFetcher returning an error") - } + _, err = testPkg.passphraseFileFetcher("-", stdin) + assert.Error(t, err, "Expected passphraseFileFetcher returning an error") } func TestPassphraseFileFetcher_WithStdinAndMultipleFetches(t *testing.T) { testPkg := NewPackage() stdin, w, err := os.Pipe() - if err != nil { - t.Fatal("Unable to create pipe", err) - } + require.NoError(t, err, "Unable to create pipe") passphrase := "secret-from-stdin" @@ -99,18 +81,12 @@ func TestPassphraseFileFetcher_WithStdinAndMultipleFetches(t *testing.T) { for range 4 { fetcher, err := testPkg.passphraseFileFetcher("-", stdin) - if err != nil { - t.Errorf("Expected passphraseFileFetcher to not return an error, but got %v", err) - } + require.NoError(t, err, "Expected passphraseFileFetcher to not return an error") pass, err := fetcher("key") - if err != nil { - t.Errorf("Expected passphraseFileFetcher invocation to succeed, failed with %v", err) - } + require.NoError(t, err, "Expected passphraseFileFetcher invocation to succeed") - if string(pass) != string(passphrase) { - t.Errorf("Expected multiple passphrase fetch to return %q, got %q", passphrase, pass) - } + assert.Equal(t, string(passphrase), string(pass), "Expected multiple passphrase fetch to return %q, got %q", passphrase, pass) } } @@ -148,9 +124,7 @@ func TestValidateVersion(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if err := validateVersion(tt.args.ver); err != nil { - if !errors.Is(err, tt.wantErr) { - t.Errorf("Expected {%v}, got {%v}", tt.wantErr, err) - } + assert.ErrorIs(t, err, tt.wantErr) } }) } diff --git a/pkg/chart/v2/lint/rules/dependencies_test.go b/pkg/chart/v2/lint/rules/dependencies_test.go index c50fc4b2d..c800887bd 100644 --- a/pkg/chart/v2/lint/rules/dependencies_test.go +++ b/pkg/chart/v2/lint/rules/dependencies_test.go @@ -19,6 +19,9 @@ import ( "path/filepath" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + chart "helm.sh/helm/v4/pkg/chart/v2" "helm.sh/helm/v4/pkg/chart/v2/lint/support" chartutil "helm.sh/helm/v4/pkg/chart/v2/util" @@ -62,18 +65,12 @@ func chartWithBadDependencies() chart.Chart { func TestValidateDependencyInChartsDir(t *testing.T) { c := chartWithBadDependencies() - - if err := validateDependencyInChartsDir(&c); err == nil { - t.Error("chart should have been flagged for missing deps in chart directory") - } + assert.Error(t, validateDependencyInChartsDir(&c), "chart should have been flagged for missing deps in chart directory") } func TestValidateDependencyInMetadata(t *testing.T) { c := chartWithBadDependencies() - - if err := validateDependencyInMetadata(&c); err == nil { - t.Error("chart should have been flagged for missing deps in chart metadata") - } + assert.Error(t, validateDependencyInMetadata(&c), "chart should have been flagged for missing deps in chart metadata") } func TestValidateDependenciesUnique(t *testing.T) { @@ -131,9 +128,7 @@ func TestValidateDependenciesUnique(t *testing.T) { } for _, tt := range tests { - if err := validateDependenciesUnique(&tt.chart); err == nil { - t.Error("chart should have been flagged for dependency shadowing") - } + assert.Error(t, validateDependenciesUnique(&tt.chart), "chart should have been flagged for dependency shadowing") } } @@ -141,10 +136,7 @@ func TestDependencies(t *testing.T) { tmp := t.TempDir() c := chartWithBadDependencies() - err := chartutil.SaveDir(&c, tmp) - if err != nil { - t.Fatal(err) - } + require.NoError(t, chartutil.SaveDir(&c, tmp)) linter := support.Linter{ChartDir: filepath.Join(tmp, c.Metadata.Name)} Dependencies(&linter) diff --git a/pkg/chart/v2/util/create_test.go b/pkg/chart/v2/util/create_test.go index 367b755d9..c85c4e3d4 100644 --- a/pkg/chart/v2/util/create_test.go +++ b/pkg/chart/v2/util/create_test.go @@ -22,6 +22,9 @@ import ( "path/filepath" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + chart "helm.sh/helm/v4/pkg/chart/v2" "helm.sh/helm/v4/pkg/chart/v2/loader" ) @@ -30,20 +33,13 @@ func TestCreate(t *testing.T) { tdir := t.TempDir() c, err := Create("foo", tdir) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) dir := filepath.Join(tdir, "foo") mychart, err := loader.LoadDir(c) - if err != nil { - t.Fatalf("Failed to load newly created chart %q: %s", c, err) - } - - if mychart.Name() != "foo" { - t.Errorf("Expected name to be 'foo', got %q", mychart.Name()) - } + require.NoError(t, err, "Failed to load newly created chart %q", c) + assert.Equal(t, "foo", mychart.Name(), "Expected name to be 'foo', got %q", mychart.Name()) for _, f := range []string{ ChartfileName, @@ -58,9 +54,8 @@ func TestCreate(t *testing.T) { TestConnectionName, ValuesfileName, } { - if _, err := os.Stat(filepath.Join(dir, f)); err != nil { - t.Errorf("Expected %s file: %s", f, err) - } + _, err := os.Stat(filepath.Join(dir, f)) + assert.NoErrorf(t, err, "Expected %s file", f) } } @@ -74,38 +69,26 @@ func TestCreateFrom(t *testing.T) { } srcdir := "./testdata/frobnitz/charts/mariner" - if err := CreateFrom(cf, tdir, srcdir); err != nil { - t.Fatal(err) - } + require.NoError(t, CreateFrom(cf, tdir, srcdir)) dir := filepath.Join(tdir, "foo") c := filepath.Join(tdir, cf.Name) mychart, err := loader.LoadDir(c) - if err != nil { - t.Fatalf("Failed to load newly created chart %q: %s", c, err) - } - - if mychart.Name() != "foo" { - t.Errorf("Expected name to be 'foo', got %q", mychart.Name()) - } + require.NoError(t, err, "Failed to load newly created chart %q", c) + assert.Equal(t, "foo", mychart.Name(), "Expected name to be 'foo', got %q", mychart.Name()) for _, f := range []string{ ChartfileName, ValuesfileName, filepath.Join(TemplatesDir, "placeholder.tpl"), } { - if _, err := os.Stat(filepath.Join(dir, f)); err != nil { - t.Errorf("Expected %s file: %s", f, err) - } + _, err := os.Stat(filepath.Join(dir, f)) + require.NoErrorf(t, err, "Expected %s file", f) // Check each file to make sure has been replaced b, err := os.ReadFile(filepath.Join(dir, f)) - if err != nil { - t.Errorf("Unable to read file %s: %s", f, err) - } - if bytes.Contains(b, []byte("")) { - t.Errorf("File %s contains ", f) - } + require.NoError(t, err, "Unable to read file %s", f) + assert.Falsef(t, bytes.Contains(b, []byte("")), "File %s contains ", f) } } @@ -115,9 +98,8 @@ func TestCreate_Overwrite(t *testing.T) { var errlog bytes.Buffer - if _, err := Create("foo", tdir); err != nil { - t.Fatal(err) - } + _, err := Create("foo", tdir) + require.NoError(t, err) dir := filepath.Join(tdir, "foo") @@ -126,22 +108,13 @@ func TestCreate_Overwrite(t *testing.T) { // Now re-run the create Stderr = &errlog - if _, err := Create("foo", tdir); err != nil { - t.Fatal(err) - } + _, err = Create("foo", tdir) + require.NoError(t, err) data, err := os.ReadFile(tplname) - if err != nil { - t.Fatal(err) - } - - if string(data) == "FOO" { - t.Fatal("File that should have been modified was not.") - } - - if errlog.Len() == 0 { - t.Error("Expected warnings about overwriting files.") - } + require.NoError(t, err) + require.NotEqual(t, "FOO", string(data), "File that should have been modified was not.") + assert.NotEqual(t, 0, errlog.Len(), "Expected warnings about overwriting files.") } func TestValidateChartName(t *testing.T) { diff --git a/pkg/cmd/plugin_uninstall_test.go b/pkg/cmd/plugin_uninstall_test.go index f715b09c8..bd08f6f13 100644 --- a/pkg/cmd/plugin_uninstall_test.go +++ b/pkg/cmd/plugin_uninstall_test.go @@ -21,6 +21,9 @@ import ( "path/filepath" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "helm.sh/helm/v4/internal/plugin" "helm.sh/helm/v4/internal/test/ensure" "helm.sh/helm/v4/pkg/cli" @@ -39,9 +42,7 @@ func TestPluginUninstallCleansUpVersionedFiles(t *testing.T) { // Create plugin directory pluginDir := filepath.Join(pluginsDir, pluginName) - if err := os.MkdirAll(pluginDir, 0o755); err != nil { - t.Fatal(err) - } + require.NoError(t, os.MkdirAll(pluginDir, 0o755)) // Create plugin.yaml pluginYAML := `name: test-plugin @@ -49,31 +50,21 @@ version: 1.2.3 description: Test plugin command: $HELM_PLUGIN_DIR/test-plugin ` - if err := os.WriteFile(filepath.Join(pluginDir, "plugin.yaml"), []byte(pluginYAML), 0o644); err != nil { - t.Fatal(err) - } + require.NoError(t, os.WriteFile(filepath.Join(pluginDir, "plugin.yaml"), []byte(pluginYAML), 0o644)) // Create versioned tarball and provenance files tarballFile := filepath.Join(pluginsDir, "test-plugin-1.2.3.tgz") provFile := filepath.Join(pluginsDir, "test-plugin-1.2.3.tgz.prov") otherVersionTarball := filepath.Join(pluginsDir, "test-plugin-2.0.0.tgz") - if err := os.WriteFile(tarballFile, []byte("fake tarball"), 0o644); err != nil { - t.Fatal(err) - } - if err := os.WriteFile(provFile, []byte("fake provenance"), 0o644); err != nil { - t.Fatal(err) - } + require.NoError(t, os.WriteFile(tarballFile, []byte("fake tarball"), 0o644)) + require.NoError(t, os.WriteFile(provFile, []byte("fake provenance"), 0o644)) // Create another version that should NOT be removed - if err := os.WriteFile(otherVersionTarball, []byte("other version"), 0o644); err != nil { - t.Fatal(err) - } + require.NoError(t, os.WriteFile(otherVersionTarball, []byte("other version"), 0o644)) // Load the plugin p, err := plugin.LoadDir(pluginDir) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) // Create a test uninstall function that uses our test settings testUninstallPlugin := func(plugin plugin.Plugin) error { @@ -112,35 +103,26 @@ command: $HELM_PLUGIN_DIR/test-plugin } // Verify files exist before uninstall - if _, err := os.Stat(tarballFile); os.IsNotExist(err) { - t.Fatal("tarball file should exist before uninstall") - } - if _, err := os.Stat(provFile); os.IsNotExist(err) { - t.Fatal("provenance file should exist before uninstall") - } - if _, err := os.Stat(otherVersionTarball); os.IsNotExist(err) { - t.Fatal("other version tarball should exist before uninstall") - } + _, err = os.Stat(tarballFile) + require.False(t, os.IsNotExist(err), "tarball file should exist before uninstall") + _, err = os.Stat(provFile) + require.False(t, os.IsNotExist(err), "provenance file should exist before uninstall") + _, err = os.Stat(otherVersionTarball) + require.False(t, os.IsNotExist(err), "other version tarball should exist before uninstall") // Uninstall the plugin - if err := testUninstallPlugin(p); err != nil { - t.Fatal(err) - } + require.NoError(t, testUninstallPlugin(p)) // Verify plugin directory is removed - if _, err := os.Stat(pluginDir); !os.IsNotExist(err) { - t.Error("plugin directory should be removed") - } + _, err = os.Stat(pluginDir) + assert.True(t, os.IsNotExist(err), "plugin directory should be removed") // Verify only exact version files are removed - if _, err := os.Stat(tarballFile); !os.IsNotExist(err) { - t.Error("versioned tarball file should be removed") - } - if _, err := os.Stat(provFile); !os.IsNotExist(err) { - t.Error("versioned provenance file should be removed") - } + _, err = os.Stat(tarballFile) + assert.True(t, os.IsNotExist(err), "versioned tarball file should be removed") + _, err = os.Stat(provFile) + assert.True(t, os.IsNotExist(err), "versioned provenance file should be removed") // Verify other version files are NOT removed - if _, err := os.Stat(otherVersionTarball); os.IsNotExist(err) { - t.Error("other version tarball should NOT be removed") - } + _, err = os.Stat(otherVersionTarball) + assert.False(t, os.IsNotExist(err), "other version tarball should NOT be removed") } diff --git a/pkg/cmd/repo_remove_test.go b/pkg/cmd/repo_remove_test.go index 3b0072a68..7d252c35d 100644 --- a/pkg/cmd/repo_remove_test.go +++ b/pkg/cmd/repo_remove_test.go @@ -21,9 +21,11 @@ import ( "fmt" "os" "path/filepath" - "strings" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "helm.sh/helm/v4/pkg/helmpath" "helm.sh/helm/v4/pkg/repo/v1" "helm.sh/helm/v4/pkg/repo/v1/repotest" @@ -49,41 +51,29 @@ func TestRepoRemove(t *testing.T) { repoCache: rootDir, } - if err := rmOpts.run(os.Stderr); err == nil { - t.Errorf("Expected error removing %s, but did not get one.", testRepoName) - } + require.Errorf(t, rmOpts.run(os.Stderr), "Expected error removing %s, but did not get one.", testRepoName) o := &repoAddOptions{ name: testRepoName, url: ts.URL(), repoFile: repoFile, } - if err := o.run(os.Stderr); err != nil { - t.Error(err) - } + require.NoError(t, o.run(os.Stderr)) cacheIndexFile, cacheChartsFile := createCacheFiles(rootDir, testRepoName) // Reset the buffer before running repo remove b.Reset() - if err := rmOpts.run(b); err != nil { - t.Errorf("Error removing %s from repositories", testRepoName) - } - if !strings.Contains(b.String(), "has been removed") { - t.Errorf("Unexpected output: %s", b.String()) - } + require.NoErrorf(t, rmOpts.run(b), "Error removing %s from repositories", testRepoName) + assert.Contains(t, b.String(), "has been removed", "Unexpected output: %s", b.String()) testCacheFiles(t, cacheIndexFile, cacheChartsFile, testRepoName) f, err := repo.LoadFile(repoFile) - if err != nil { - t.Error(err) - } + require.NoError(t, err) - if f.Has(testRepoName) { - t.Errorf("%s was not successfully removed from repositories list", testRepoName) - } + assert.Falsef(t, f.Has(testRepoName), "%s was not successfully removed from repositories list", testRepoName) // Test removal of multiple repos in one go var testRepoNames = []string{"foo", "bar", "baz"} @@ -97,9 +87,7 @@ func TestRepoRemove(t *testing.T) { repoFile: repoFile, } - if err := o.run(os.Stderr); err != nil { - t.Error(err) - } + require.NoError(t, o.run(os.Stderr)) cacheIndex, cacheChart := createCacheFiles(rootDir, repoName) cacheFiles[repoName] = []string{cacheIndex, cacheChart} @@ -116,23 +104,15 @@ func TestRepoRemove(t *testing.T) { b.Reset() // Run repo remove command - if err := multiRmOpts.run(b); err != nil { - t.Errorf("Error removing list of repos from repositories: %q", testRepoNames) - } + require.NoErrorf(t, multiRmOpts.run(b), "Error removing list of repos from repositories: %q", testRepoNames) // Check that stuff were removed - if !strings.Contains(b.String(), "has been removed") { - t.Errorf("Unexpected output: %s", b.String()) - } + assert.Contains(t, b.String(), "has been removed", "Unexpected output: %s", b.String()) for _, repoName := range testRepoNames { f, err := repo.LoadFile(repoFile) - if err != nil { - t.Error(err) - } - if f.Has(repoName) { - t.Errorf("%s was not successfully removed from repositories list", repoName) - } + require.NoError(t, err) + assert.Falsef(t, f.Has(repoName), "%s was not successfully removed from repositories list", repoName) cacheIndex := cacheFiles[repoName][0] cacheChart := cacheFiles[repoName][1] testCacheFiles(t, cacheIndex, cacheChart, repoName) @@ -153,12 +133,10 @@ func createCacheFiles(rootDir string, repoName string) (cacheIndexFile string, c func testCacheFiles(t *testing.T, cacheIndexFile string, cacheChartsFile string, repoName string) { t.Helper() - if _, err := os.Stat(cacheIndexFile); err == nil { - t.Errorf("Error cache index file was not removed for repository %s", repoName) - } - if _, err := os.Stat(cacheChartsFile); err == nil { - t.Errorf("Error cache chart file was not removed for repository %s", repoName) - } + _, err := os.Stat(cacheIndexFile) + require.Errorf(t, err, "Error cache index file was not removed for repository %s", repoName) + _, err = os.Stat(cacheChartsFile) + assert.Errorf(t, err, "Error cache chart file was not removed for repository %s", repoName) } func TestRepoRemoveCompletion(t *testing.T) { @@ -183,9 +161,7 @@ func TestRepoRemoveCompletion(t *testing.T) { repoFile: repoFile, } - if err := o.run(os.Stderr); err != nil { - t.Error(err) - } + require.NoError(t, o.run(os.Stderr)) } repoSetup := fmt.Sprintf("--repository-config %s --repository-cache %s", repoFile, repoCache) diff --git a/pkg/cmd/repo_update_test.go b/pkg/cmd/repo_update_test.go index 7aa4d414f..ccd8b89c6 100644 --- a/pkg/cmd/repo_update_test.go +++ b/pkg/cmd/repo_update_test.go @@ -24,6 +24,9 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "helm.sh/helm/v4/internal/test/ensure" "helm.sh/helm/v4/pkg/getter" "helm.sh/helm/v4/pkg/repo/v1" @@ -44,9 +47,7 @@ func TestUpdateCmd(t *testing.T) { update: updater, repoFile: "testdata/repositories.yaml", } - if err := o.run(&out); err != nil { - t.Fatal(err) - } + require.NoError(t, o.run(&out)) if got := out.String(); !strings.Contains(got, "charts") || !strings.Contains(got, "firstexample") || @@ -70,9 +71,7 @@ func TestUpdateCmdMultiple(t *testing.T) { repoFile: "testdata/repositories.yaml", names: []string{"firstexample", "charts"}, } - if err := o.run(&out); err != nil { - t.Fatal(err) - } + require.NoError(t, o.run(&out)) if got := out.String(); !strings.Contains(got, "charts") || !strings.Contains(got, "firstexample") || @@ -96,9 +95,7 @@ func TestUpdateCmdInvalid(t *testing.T) { repoFile: "testdata/repositories.yaml", names: []string{"firstexample", "invalid"}, } - if err := o.run(&out); err == nil { - t.Fatal("expected error but did not get one") - } + require.Error(t, o.run(&out), "expected error but did not get one") } func TestUpdateCustomCacheCmd(t *testing.T) { @@ -119,12 +116,9 @@ func TestUpdateCustomCacheCmd(t *testing.T) { repoCache: cachePath, } b := io.Discard - if err := o.run(b); err != nil { - t.Fatal(err) - } - if _, err := os.Stat(filepath.Join(cachePath, "test-index.yaml")); err != nil { - t.Fatalf("error finding created index file in custom cache: %v", err) - } + require.NoError(t, o.run(b)) + _, err := os.Stat(filepath.Join(cachePath, "test-index.yaml")) + require.NoErrorf(t, err, "error finding created index file in custom cache") } func TestUpdateCharts(t *testing.T) { @@ -140,20 +134,14 @@ func TestUpdateCharts(t *testing.T) { Name: "charts", URL: ts.URL(), }, getter.All(settings)) - if err != nil { - t.Error(err) - } + require.NoError(t, err) b := bytes.NewBuffer(nil) updateCharts([]*repo.ChartRepository{r}, b) got := b.String() - if strings.Contains(got, "Unable to get an update") { - t.Errorf("Failed to get a repo: %q", got) - } - if !strings.Contains(got, "Update Complete.") { - t.Error("Update was not successful") - } + assert.NotContains(t, got, "Unable to get an update", "Failed to get a repo: %q", got) + assert.Contains(t, got, "Update Complete.", "Update was not successful") } func TestRepoUpdateFileCompletion(t *testing.T) { @@ -176,37 +164,22 @@ func TestUpdateChartsFailWithError(t *testing.T) { Name: "charts", URL: invalidURL, }, getter.All(settings)) - if err != nil { - t.Error(err) - } + require.NoError(t, err) r2, err := repo.NewChartRepository(&repo.Entry{ Name: "charts", URL: invalidURL, }, getter.All(settings)) - if err != nil { - t.Error(err) - } + require.NoError(t, err) b := bytes.NewBuffer(nil) err = updateCharts([]*repo.ChartRepository{r1, r2}, b) - if err == nil { - t.Error("Repo update should return error because update of repository fails and 'fail-on-repo-update-fail' flag set") - return - } + require.Error(t, err, "Repo update should return error because update of repository fails and 'fail-on-repo-update-fail' flag set") var expectedErr = "failed to update the following repositories" var receivedErr = err.Error() - if !strings.Contains(receivedErr, expectedErr) { - t.Errorf("Expected error (%s) but got (%s) instead", expectedErr, receivedErr) - } - if !strings.Contains(receivedErr, invalidURL) { - t.Errorf("Expected invalid URL (%s) in error message but got (%s) instead", invalidURL, receivedErr) - } + require.ErrorContains(t, err, expectedErr, "Expected error (%s) but got (%s) instead", expectedErr, receivedErr) + require.ErrorContains(t, err, invalidURL, "Expected invalid URL (%s) in error message but got (%s) instead", invalidURL, receivedErr) got := b.String() - if !strings.Contains(got, "Unable to get an update") { - t.Errorf("Repo should have failed update but instead got: %q", got) - } - if strings.Contains(got, "Update Complete.") { - t.Error("Update was not successful and should return error message because 'fail-on-repo-update-fail' flag set") - } + assert.Contains(t, got, "Unable to get an update", "Repo should have failed update but instead got: %q", got) + assert.NotContains(t, got, "Update Complete.", "Update was not successful and should return error message because 'fail-on-repo-update-fail' flag set") } diff --git a/pkg/kube/resource_test.go b/pkg/kube/resource_test.go index 283b44945..ca41a06ed 100644 --- a/pkg/kube/resource_test.go +++ b/pkg/kube/resource_test.go @@ -19,6 +19,7 @@ package kube import ( "testing" + "github.com/stretchr/testify/assert" "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/cli-runtime/pkg/resource" @@ -37,27 +38,17 @@ func TestResourceList(t *testing.T) { r1 = []*resource.Info{info("foo"), info("bar")} r2 = []*resource.Info{info("bar")} - if r1.Get(info("bar")).Mapping.Resource.Resource != "pod" { - t.Error("expected get pod") - } + assert.Equal(t, "pod", r1.Get(info("bar")).Mapping.Resource.Resource, "expected get pod") diff := r1.Difference(r2) - if len(diff) != 1 { - t.Error("expected 1 result") - } + assert.Len(t, diff, 1, "expected 1 result") - if !diff.Contains(info("foo")) { - t.Error("expected diff to return foo") - } + assert.True(t, diff.Contains(info("foo")), "expected diff to return foo") inter := r1.Intersect(r2) - if len(inter) != 1 { - t.Error("expected 1 result") - } + assert.Len(t, inter, 1, "expected 1 result") - if !inter.Contains(info("bar")) { - t.Error("expected intersect to return bar") - } + assert.True(t, inter.Contains(info("bar")), "expected intersect to return bar") } func TestIsMatchingInfo(t *testing.T) { @@ -66,35 +57,23 @@ func TestIsMatchingInfo(t *testing.T) { gvkDiffGroup := schema.GroupVersionKind{Group: "diff", Version: "version1", Kind: "pod"} resourceInfoDiffGroup := resource.Info{Name: "name1", Namespace: "namespace1", Mapping: &meta.RESTMapping{GroupVersionKind: gvkDiffGroup}} - if isMatchingInfo(&resourceInfo, &resourceInfoDiffGroup) { - t.Error("expected resources not equal") - } + assert.False(t, isMatchingInfo(&resourceInfo, &resourceInfoDiffGroup), "expected resources not equal") gvkDiffVersion := schema.GroupVersionKind{Group: "group1", Version: "diff", Kind: "pod"} resourceInfoDiffVersion := resource.Info{Name: "name1", Namespace: "namespace1", Mapping: &meta.RESTMapping{GroupVersionKind: gvkDiffVersion}} - if !isMatchingInfo(&resourceInfo, &resourceInfoDiffVersion) { - t.Error("expected resources with different versions but same group and kind to be equal") - } + assert.True(t, isMatchingInfo(&resourceInfo, &resourceInfoDiffVersion), "expected resources with different versions but same group and kind to be equal") gvkDiffKind := schema.GroupVersionKind{Group: "group1", Version: "version1", Kind: "deployment"} resourceInfoDiffKind := resource.Info{Name: "name1", Namespace: "namespace1", Mapping: &meta.RESTMapping{GroupVersionKind: gvkDiffKind}} - if isMatchingInfo(&resourceInfo, &resourceInfoDiffKind) { - t.Error("expected resources not equal") - } + assert.False(t, isMatchingInfo(&resourceInfo, &resourceInfoDiffKind), "expected resources not equal") resourceInfoDiffName := resource.Info{Name: "diff", Namespace: "namespace1", Mapping: &meta.RESTMapping{GroupVersionKind: gvk}} - if isMatchingInfo(&resourceInfo, &resourceInfoDiffName) { - t.Error("expected resources not equal") - } + assert.False(t, isMatchingInfo(&resourceInfo, &resourceInfoDiffName), "expected resources not equal") resourceInfoDiffNamespace := resource.Info{Name: "name1", Namespace: "diff", Mapping: &meta.RESTMapping{GroupVersionKind: gvk}} - if isMatchingInfo(&resourceInfo, &resourceInfoDiffNamespace) { - t.Error("expected resources not equal") - } + assert.False(t, isMatchingInfo(&resourceInfo, &resourceInfoDiffNamespace), "expected resources not equal") gvkEqual := schema.GroupVersionKind{Group: "group1", Version: "version1", Kind: "pod"} resourceInfoEqual := resource.Info{Name: "name1", Namespace: "namespace1", Mapping: &meta.RESTMapping{GroupVersionKind: gvkEqual}} - if !isMatchingInfo(&resourceInfo, &resourceInfoEqual) { - t.Error("expected resources to be equal") - } + assert.True(t, isMatchingInfo(&resourceInfo, &resourceInfoEqual), "expected resources to be equal") } From 1d4665e54c28a41a5631c19f3bff14ef3d4e058f Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 20:50:56 +0200 Subject: [PATCH 38/61] chore(pkg): refactor: convert tests to testify assert/require part 20 #### Description refactor: convert tests to testify assert/require in pkg/cmd Signed-off-by: Matthieu MOREL --- pkg/chart/common/util/values_test.go | 52 ++++++-------- pkg/chart/loader/archive/archive_test.go | 29 +++----- pkg/chart/v2/lint/lint_test.go | 43 +++--------- pkg/cmd/list_test.go | 46 +++---------- pkg/cmd/package_test.go | 44 +++++------- pkg/cmd/release_testing_test.go | 12 ++-- pkg/cmd/source_date_epoch_test.go | 44 ++++-------- .../chart_downloader_windows_test.go | 67 +++++++++---------- pkg/kube/wait_test.go | 36 +++------- pkg/registry/client_tls_test.go | 23 +++---- pkg/release/v1/info_test.go | 43 +++++------- 11 files changed, 151 insertions(+), 288 deletions(-) diff --git a/pkg/chart/common/util/values_test.go b/pkg/chart/common/util/values_test.go index 1882fd0c4..e87a69237 100644 --- a/pkg/chart/common/util/values_test.go +++ b/pkg/chart/common/util/values_test.go @@ -20,6 +20,9 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "helm.sh/helm/v4/pkg/chart/common" chart "helm.sh/helm/v4/pkg/chart/v2" ) @@ -61,42 +64,26 @@ func TestToRenderValues(t *testing.T) { } res, err := ToRenderValuesWithSchemaValidation(c, overrideValues, o, nil, false) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) // Ensure that the top-level values are all set. metamap := res["Chart"].(map[string]any) - if name := metamap["Name"]; name.(string) != "test" { - t.Errorf("Expected chart name 'test', got %q", name) - } + name := metamap["Name"] + assert.Equalf(t, "test", name.(string), "Expected chart name 'test', got %q", name) relmap := res["Release"].(map[string]any) - if name := relmap["Name"]; name.(string) != "Seven Voyages" { - t.Errorf("Expected release name 'Seven Voyages', got %q", name) - } - if namespace := relmap["Namespace"]; namespace.(string) != "default" { - t.Errorf("Expected namespace 'default', got %q", namespace) - } - if revision := relmap["Revision"]; revision.(int) != 1 { - t.Errorf("Expected revision '1', got %d", revision) - } - if relmap["IsUpgrade"].(bool) { - t.Error("Expected upgrade to be false.") - } - if !relmap["IsInstall"].(bool) { - t.Error("Expected install to be true.") - } - if !res["Capabilities"].(*common.Capabilities).APIVersions.Has("v1") { - t.Error("Expected Capabilities to have v1 as an API") - } - if res["Capabilities"].(*common.Capabilities).KubeVersion.Major != "1" { - t.Error("Expected Capabilities to have a Kube version") - } + name = relmap["Name"] + assert.Equalf(t, "Seven Voyages", name.(string), "Expected release name 'Seven Voyages', got %q", name) + namespace := relmap["Namespace"] + assert.Equalf(t, "default", namespace.(string), "Expected namespace 'default', got %q", namespace) + revision := relmap["Revision"] + assert.Equalf(t, 1, revision.(int), "Expected revision '1', got %d", revision) + assert.False(t, relmap["IsUpgrade"].(bool), "Expected upgrade to be false.") + assert.True(t, relmap["IsInstall"].(bool), "Expected install to be true.") + assert.True(t, res["Capabilities"].(*common.Capabilities).APIVersions.Has("v1"), "Expected Capabilities to have v1 as an API") + assert.Equal(t, "1", res["Capabilities"].(*common.Capabilities).KubeVersion.Major, "Expected Capabilities to have a Kube version") vals := res["Values"].(common.Values) - if vals["name"] != "Haroun" { - t.Errorf("Expected 'Haroun', got %q (%v)", vals["name"], vals) - } + assert.Equal(t, "Haroun", vals["name"], "Expected 'Haroun', got %q (%v)", vals["name"], vals) where := vals["where"].(map[string]any) expects := map[string]string{ "city": "Baghdad", @@ -104,8 +91,7 @@ func TestToRenderValues(t *testing.T) { "title": "caliph", } for field, expect := range expects { - if got := where[field]; got != expect { - t.Errorf("Expected %q, got %q (%v)", expect, got, where) - } + got := where[field] + assert.Equalf(t, got, expect, "Expected %q, got %q (%v)", expect, got, where) } } diff --git a/pkg/chart/loader/archive/archive_test.go b/pkg/chart/loader/archive/archive_test.go index 2fe09e9b2..3c3d336c3 100644 --- a/pkg/chart/loader/archive/archive_test.go +++ b/pkg/chart/loader/archive/archive_test.go @@ -21,6 +21,8 @@ import ( "bytes" "compress/gzip" "testing" + + "github.com/stretchr/testify/require" ) func TestLoadArchiveFiles(t *testing.T) { @@ -34,9 +36,7 @@ func TestLoadArchiveFiles(t *testing.T) { generate: func(_ *tar.Writer) {}, check: func(t *testing.T, _ []*BufferedFile, err error) { t.Helper() - if err.Error() != "no files in chart archive" { - t.Fatalf(`expected "no files in chart archive", got [%#v]`, err) - } + require.EqualError(t, err, "no files in chart archive") }, }, { @@ -44,32 +44,21 @@ func TestLoadArchiveFiles(t *testing.T) { generate: func(w *tar.Writer) { // simulate the presence of a `pax_global_header` file like you would get when // processing a GitHub release archive. - err := w.WriteHeader(&tar.Header{ + require.NoError(t, w.WriteHeader(&tar.Header{ Typeflag: tar.TypeXGlobalHeader, Name: "pax_global_header", - }) - if err != nil { - t.Fatal(err) - } + })) // we need to have at least one file, otherwise we'll get the "no files in chart archive" error - err = w.WriteHeader(&tar.Header{ + require.NoError(t, w.WriteHeader(&tar.Header{ Typeflag: tar.TypeReg, Name: "dir/empty", - }) - if err != nil { - t.Fatal(err) - } + })) }, check: func(t *testing.T, files []*BufferedFile, err error) { t.Helper() - if err != nil { - t.Fatalf(`got unwanted error [%#v] for tar file with pax_global_header content`, err) - } - - if len(files) != 1 { - t.Fatalf(`expected to get one file but got [%v]`, files) - } + require.NoErrorf(t, err, `got unwanted error for tar file with pax_global_header content`) + require.Lenf(t, files, 1, `expected to get one file but got [%v]`, files) }, }, } diff --git a/pkg/chart/v2/lint/lint_test.go b/pkg/chart/v2/lint/lint_test.go index 85960131b..1782c01d4 100644 --- a/pkg/chart/v2/lint/lint_test.go +++ b/pkg/chart/v2/lint/lint_test.go @@ -97,34 +97,22 @@ func TestBadChart(t *testing.T) { func TestInvalidYaml(t *testing.T) { var values map[string]any m := RunAll(badYamlFileDir, values, namespace).Messages - if len(m) != 1 { - t.Fatalf("All didn't fail with expected errors, got %#v", m) - } - if !strings.Contains(m[0].Err.Error(), "deliberateSyntaxError") { - t.Error("All didn't have the error for deliberateSyntaxError") - } + require.Len(t, m, 1, "All didn't fail with expected errors, got %#v", m) + assert.ErrorContains(t, m[0].Err, "deliberateSyntaxError", "All didn't have the error for deliberateSyntaxError") } func TestInvalidChartYaml(t *testing.T) { var values map[string]any m := RunAll(invalidChartFileDir, values, namespace).Messages - if len(m) != 2 { - t.Fatalf("All didn't fail with expected errors, got %#v", m) - } - if !strings.Contains(m[0].Err.Error(), "failed to strictly parse chart metadata file") { - t.Error("All didn't have the error for duplicate YAML keys") - } + require.Len(t, m, 2, "All didn't fail with expected errors, got %#v", m) + assert.ErrorContains(t, m[0].Err, "failed to strictly parse chart metadata file", "All didn't have the error for duplicate YAML keys") } func TestBadValues(t *testing.T) { var values map[string]any m := RunAll(badValuesFileDir, values, namespace).Messages - if len(m) < 1 { - t.Fatalf("All didn't fail with expected errors, got %#v", m) - } - if !strings.Contains(m[0].Err.Error(), "unable to parse YAML") { - t.Errorf("All didn't have the error for invalid key format: %s", m[0].Err) - } + require.GreaterOrEqualf(t, len(m), 1, "All didn't fail with expected errors, got %#v", m) + assert.ErrorContains(t, m[0].Err, "unable to parse YAML", "All didn't have the error for invalid key format: %s", m[0].Err) } func TestBadCrdFile(t *testing.T) { @@ -154,11 +142,7 @@ func TestHelmCreateChart(t *testing.T) { dir := t.TempDir() createdChart, err := chartutil.Create("testhelmcreatepasseslint", dir) - if err != nil { - t.Error(err) - // Fatal is bad because of the defer. - return - } + require.NoError(t, err) // Note: we test with strict=true here, even though others have // strict = false. @@ -182,10 +166,7 @@ func TestHelmCreateChart(t *testing.T) { // of the `--set` flag. func TestHelmCreateChart_CheckDeprecatedWarnings(t *testing.T) { createdChart, err := chartutil.Create("checkdeprecatedwarnings", t.TempDir()) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) // Add values to enable hpa, and ingress which are disabled by default. // This is the equivalent of: @@ -238,11 +219,7 @@ func TestMalformedTemplate(t *testing.T) { case <-c: t.Fatal("lint malformed template timeout") case <-ch: - if len(m) != 1 { - t.Fatalf("All didn't fail with expected errors, got %#v", m) - } - if !strings.Contains(m[0].Err.Error(), "invalid character '{'") { - t.Error("All didn't have the error for invalid character '{'") - } + require.Len(t, m, 1, "All didn't fail with expected errors, got %#v", m) + assert.ErrorContains(t, m[0].Err, "invalid character '{'", "All didn't have the error for invalid character '{'") } } diff --git a/pkg/cmd/list_test.go b/pkg/cmd/list_test.go index f45616250..41426fedb 100644 --- a/pkg/cmd/list_test.go +++ b/pkg/cmd/list_test.go @@ -426,20 +426,9 @@ func TestReleaseListWriterMethods(t *testing.T) { var buf []byte out := &bytesWriter{buf: &buf} - err := writer.WriteJSON(out) - if err != nil { - t.Errorf("WriteJSON failed: %v", err) - } - - err = writer.WriteYAML(out) - if err != nil { - t.Errorf("WriteYAML failed: %v", err) - } - - err = writer.WriteTable(out) - if err != nil { - t.Errorf("WriteTable failed: %v", err) - } + require.NoError(t, writer.WriteJSON(out), "WriteJSON failed") + require.NoError(t, writer.WriteYAML(out), "WriteYAML failed") + assert.NoError(t, writer.WriteTable(out), "WriteTable failed") }) } @@ -448,20 +437,9 @@ func TestReleaseListWriterMethods(t *testing.T) { var buf []byte out := &bytesWriter{buf: &buf} - err := writer.WriteJSON(out) - if err != nil { - t.Errorf("WriteJSON failed: %v", err) - } - - err = writer.WriteYAML(out) - if err != nil { - t.Errorf("WriteYAML failed: %v", err) - } - - err = writer.WriteTable(out) - if err != nil { - t.Errorf("WriteTable failed: %v", err) - } + require.NoError(t, writer.WriteJSON(out), "WriteJSON failed") + require.NoError(t, writer.WriteYAML(out), "WriteYAML failed") + assert.NoError(t, writer.WriteTable(out), "WriteTable failed") } func TestFilterReleases(t *testing.T) { @@ -512,9 +490,7 @@ func TestFilterReleases(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result := filterReleases(tt.releases, tt.ignoredReleaseNames) - if len(result) != tt.expectedCount { - t.Errorf("Expected %d releases, got %d", tt.expectedCount, len(result)) - } + assert.Len(t, result, tt.expectedCount, "Expected %d releases, got %d", tt.expectedCount, len(result)) }) } } @@ -603,13 +579,9 @@ func TestListStatusMapping(t *testing.T) { } writer := newReleaseListWriter(releaseFixture, "", false, false) - if len(writer.releases) != 1 { - t.Errorf("Expected 1 release, got %d", len(writer.releases)) - } + assert.Len(t, writer.releases, 1, "Expected 1 release, got %d", len(writer.releases)) - if writer.releases[0].Status != tc.status.String() { - t.Errorf("Expected status %s, got %s", tc.status.String(), writer.releases[0].Status) - } + assert.Equal(t, tc.status.String(), writer.releases[0].Status, "Expected status %s, got %s", tc.status.String(), writer.releases[0].Status) }) } } diff --git a/pkg/cmd/package_test.go b/pkg/cmd/package_test.go index 5705c9b9e..d78f5d88d 100644 --- a/pkg/cmd/package_test.go +++ b/pkg/cmd/package_test.go @@ -23,6 +23,9 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "helm.sh/helm/v4/internal/test/ensure" chart "helm.sh/helm/v4/pkg/chart/v2" "helm.sh/helm/v4/pkg/chart/v2/loader" @@ -105,18 +108,14 @@ func TestPackage(t *testing.T) { } origDir, err := os.Getwd() - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { t.Chdir(t.TempDir()) ensure.HelmHome(t) - if err := os.MkdirAll("toot", 0o777); err != nil { - t.Fatal(err) - } + require.NoError(t, os.MkdirAll("toot", 0o777)) // This is an unfortunate byproduct of the tmpdir if v, ok := tt.flags["keyring"]; ok && v != "" { @@ -140,6 +139,7 @@ func TestPackage(t *testing.T) { } } _, _, err = executeActionCommand(strings.Join(cmd, " ")) + if err != nil { if tt.err && re.MatchString(err.Error()) { return @@ -148,19 +148,15 @@ func TestPackage(t *testing.T) { } if tt.hasfile != "" { - if fi, err := os.Stat(tt.hasfile); err != nil { - t.Errorf("%q: expected file %q, got err %q", tt.name, tt.hasfile, err) - } else if fi.Size() == 0 { - t.Errorf("%q: file %q has zero bytes.", tt.name, tt.hasfile) - } + fi, err := os.Stat(tt.hasfile) + require.NoErrorf(t, err, "%q: expected file %q", tt.name, tt.hasfile) + assert.NotEqualf(t, 0, fi.Size(), "%q: file %q has zero bytes.", tt.name, tt.hasfile) } if v, ok := tt.flags["sign"]; ok && v == "1" { - if fi, err := os.Stat(tt.hasfile + ".prov"); err != nil { - t.Errorf("%q: expected provenance file", tt.name) - } else if fi.Size() == 0 { - t.Errorf("%q: provenance file is empty", tt.name) - } + fi, err := os.Stat(tt.hasfile + ".prov") + require.NoErrorf(t, err, "%q: expected provenance file", tt.name) + assert.NotEqualf(t, 0, fi.Size(), "%q: provenance file is empty", tt.name) } }) } @@ -178,18 +174,12 @@ func TestSetAppVersion(t *testing.T) { t.Fatal(err) } chartPath := filepath.Join(dir, "alpine-0.1.0.tgz") - if fi, err := os.Stat(chartPath); err != nil { - t.Errorf("expected file %q, got err %q", chartPath, err) - } else if fi.Size() == 0 { - t.Errorf("file %q has zero bytes.", chartPath) - } + fi, err := os.Stat(chartPath) + require.NoErrorf(t, err, "expected file %q", chartPath) + assert.NotEqualf(t, 0, fi.Size(), "file %q has zero bytes.", chartPath) ch, err = loader.Load(chartPath) - if err != nil { - t.Fatalf("unexpected error loading packaged chart: %v", err) - } - if ch.Metadata.AppVersion != expectedAppVersion { - t.Errorf("expected app-version %q, found %q", expectedAppVersion, ch.Metadata.AppVersion) - } + require.NoError(t, err, "unexpected error loading packaged chart") + assert.Equal(t, expectedAppVersion, ch.Metadata.AppVersion, "expected app-version %q, found %q", expectedAppVersion, ch.Metadata.AppVersion) } func TestPackageFileCompletion(t *testing.T) { diff --git a/pkg/cmd/release_testing_test.go b/pkg/cmd/release_testing_test.go index fdb5df1e9..a39816843 100644 --- a/pkg/cmd/release_testing_test.go +++ b/pkg/cmd/release_testing_test.go @@ -19,9 +19,11 @@ package cmd import ( "bytes" "io" - "strings" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "helm.sh/helm/v4/pkg/action" "helm.sh/helm/v4/pkg/chart/common" chart "helm.sh/helm/v4/pkg/chart/v2" @@ -71,11 +73,7 @@ func TestReleaseTestNotesHandling(t *testing.T) { cmd1 := newReleaseTestCmd(actionConfig, &buf1) cmd1.SetArgs([]string{"test-release"}) err1 := cmd1.Execute() - if err1 != nil { - t.Fatalf("Unexpected error for default test: %v", err1) - } + require.NoError(t, err1, "Unexpected error for default test") output1 := buf1.String() - if strings.Contains(output1, "NOTES:") { - t.Errorf("Expected notes to be hidden by default, but found NOTES section in output: %s", output1) - } + assert.NotContains(t, output1, "NOTES:", "Expected notes to be hidden by default, but found NOTES section in output: %s", output1) } diff --git a/pkg/cmd/source_date_epoch_test.go b/pkg/cmd/source_date_epoch_test.go index 719de7c90..fa64c08b0 100644 --- a/pkg/cmd/source_date_epoch_test.go +++ b/pkg/cmd/source_date_epoch_test.go @@ -19,64 +19,48 @@ package cmd import ( "testing" "time" + + "github.com/stretchr/testify/require" ) func TestSourceDateEpochFromEnv(t *testing.T) { t.Setenv("SOURCE_DATE_EPOCH", "1609459200") got, err := sourceDateEpochFromEnv() - if err != nil { - t.Fatalf("sourceDateEpochFromEnv() error: %v", err) - } - if got == nil { - t.Fatal("expected non-nil epoch") - } + require.NoError(t, err, "sourceDateEpochFromEnv()") + require.NotNil(t, got, "expected non-nil epoch") want := time.Unix(1609459200, 0).UTC() - if !got.Equal(want) { - t.Fatalf("expected %v, got %v", want, *got) - } + require.Truef(t, got.Equal(want), "expected %v, got %v", want, *got) } func TestSourceDateEpochFromEnvUnset(t *testing.T) { t.Setenv("SOURCE_DATE_EPOCH", "") got, err := sourceDateEpochFromEnv() - if err != nil { - t.Fatalf("sourceDateEpochFromEnv() error: %v", err) - } - if got != nil { - t.Fatalf("expected nil epoch, got %v", *got) - } + require.NoError(t, err, "sourceDateEpochFromEnv()") + require.Nil(t, got, "expected nil epoch") } func TestSourceDateEpochFromEnvInvalid(t *testing.T) { t.Setenv("SOURCE_DATE_EPOCH", "not-a-number") - if _, err := sourceDateEpochFromEnv(); err == nil { - t.Fatal("expected error for invalid SOURCE_DATE_EPOCH") - } + _, err := sourceDateEpochFromEnv() + require.Error(t, err, "expected error for invalid SOURCE_DATE_EPOCH") } func TestSourceDateEpochFromEnvNegative(t *testing.T) { t.Setenv("SOURCE_DATE_EPOCH", "-1") - if _, err := sourceDateEpochFromEnv(); err == nil { - t.Fatal("expected error for negative SOURCE_DATE_EPOCH") - } + _, err := sourceDateEpochFromEnv() + require.Error(t, err, "expected error for negative SOURCE_DATE_EPOCH") } func TestSourceDateEpochFromEnvZero(t *testing.T) { t.Setenv("SOURCE_DATE_EPOCH", "0") got, err := sourceDateEpochFromEnv() - if err != nil { - t.Fatalf("sourceDateEpochFromEnv() error: %v", err) - } - if got == nil { - t.Fatal("expected non-nil epoch") - } + require.NoError(t, err, "sourceDateEpochFromEnv() error") + require.NotNil(t, got, "expected non-nil epoch") want := time.Unix(0, 0).UTC() - if !got.Equal(want) { - t.Fatalf("expected %v, got %v", want, *got) - } + require.Truef(t, got.Equal(want), "expected %v, got %v", want, *got) } diff --git a/pkg/downloader/chart_downloader_windows_test.go b/pkg/downloader/chart_downloader_windows_test.go index 732416701..2b6bea5eb 100644 --- a/pkg/downloader/chart_downloader_windows_test.go +++ b/pkg/downloader/chart_downloader_windows_test.go @@ -23,6 +23,9 @@ import ( "sync" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "helm.sh/helm/v4/pkg/cli" "helm.sh/helm/v4/pkg/getter" "helm.sh/helm/v4/pkg/repo/v1/repotest" @@ -36,9 +39,7 @@ func TestParallelDownloadTo(t *testing.T) { srv := repotest.NewTempServer(t, repotest.WithChartSourceGlob("testdata/*.tgz")) defer srv.Stop() - if err := srv.CreateIndex(); err != nil { - t.Fatal(err) - } + require.NoError(t, srv.CreateIndex()) dest := t.TempDir() cacheDir := t.TempDir() @@ -86,46 +87,38 @@ func TestParallelDownloadTo(t *testing.T) { } // With the file locking fix, all parallel downloads should succeed - if failedCount > 0 { - t.Errorf("Parallel downloads failed: %d out of %d downloads failed due to concurrent file access", failedCount, numDownloads) - } + assert.Falsef(t, failedCount > 0, "Parallel downloads failed: %d out of %d downloads failed due to concurrent file access", failedCount, numDownloads) // Verify the file exists and is valid expectedFile := filepath.Join(dest, "local-subchart-0.1.0.tgz") info, err := os.Stat(expectedFile) - if err != nil { - t.Errorf("Expected file %s does not exist: %v", expectedFile, err) - } else { - // Verify the file is not empty - if info.Size() == 0 { - t.Errorf("Downloaded file %s is empty (0 bytes)", expectedFile) - } - - // Verify the file has the expected size (should match the source file) - sourceFile := "testdata/local-subchart-0.1.0.tgz" - sourceInfo, err := os.Stat(sourceFile) - if err == nil && info.Size() != sourceInfo.Size() { - t.Errorf("Downloaded file size (%d bytes) doesn't match source file size (%d bytes)", - info.Size(), sourceInfo.Size()) - } + require.NoError(t, err, "Expected file %s does not exist: %v", expectedFile) + // Verify the file is not empty + assert.Falsef(t, info.Size() == 0, "Downloaded file %s is empty (0 bytes)", expectedFile) + + // Verify the file has the expected size (should match the source file) + sourceFile := "testdata/local-subchart-0.1.0.tgz" + sourceInfo, err := os.Stat(sourceFile) + if err == nil && info.Size() != sourceInfo.Size() { + t.Errorf("Downloaded file size (%d bytes) doesn't match source file size (%d bytes)", + info.Size(), sourceInfo.Size()) + } - // Verify it's a valid tar.gz file by checking the magic bytes - file, err := os.Open(expectedFile) - if err == nil { - defer file.Close() - // gzip magic bytes are 0x1f 0x8b - magic := make([]byte, 2) - if n, err := file.Read(magic); err == nil && n == 2 { - if magic[0] != 0x1f || magic[1] != 0x8b { - t.Errorf("Downloaded file is not a valid gzip file (magic bytes: %x)", magic) - } + // Verify it's a valid tar.gz file by checking the magic bytes + file, err := os.Open(expectedFile) + if err == nil { + defer file.Close() + // gzip magic bytes are 0x1f 0x8b + magic := make([]byte, 2) + if n, err := file.Read(magic); err == nil && n == 2 { + if magic[0] != 0x1f || magic[1] != 0x8b { + t.Errorf("Downloaded file is not a valid gzip file (magic bytes: %x)", magic) } } - - // Verify no lock file was left behind - lockFile := expectedFile + ".lock" - if _, err := os.Stat(lockFile); err == nil { - t.Errorf("Lock file %s was not cleaned up", lockFile) - } } + + // Verify no lock file was left behind + lockFile := expectedFile + ".lock" + _, err = os.Stat(lockFile) + assert.Falsef(t, err == nil, "Lock file %s was not cleaned up", lockFile) } diff --git a/pkg/kube/wait_test.go b/pkg/kube/wait_test.go index acdfffa23..9cf1e5506 100644 --- a/pkg/kube/wait_test.go +++ b/pkg/kube/wait_test.go @@ -19,7 +19,6 @@ package kube import ( "errors" "net/http" - "strings" "testing" "github.com/stretchr/testify/assert" @@ -298,17 +297,12 @@ func TestLegacyWaiter_waitForPodSuccess(t *testing.T) { t.Run(tt.name, func(t *testing.T) { done, err := lw.waitForPodSuccess(tt.obj, "foo") if tt.wantErr { - if err == nil { - t.Error("expected error, got none") - } else if !strings.Contains(err.Error(), tt.errMessage) { - t.Errorf("expected error to contain %q, got %q", tt.errMessage, err.Error()) - } - } else if err != nil { - t.Errorf("unexpected error: %v", err) - } - if done != tt.wantDone { - t.Errorf("got done=%v, want %v", done, tt.wantDone) + require.Error(t, err, "expected error, got none") + require.ErrorContains(t, err, tt.errMessage, "expected error to contain %q, got %q", tt.errMessage, err.Error()) + } else { + require.NoError(t, err) } + assert.Equal(t, tt.wantDone, done, "got done=%v, want %v", done, tt.wantDone) }) } } @@ -390,17 +384,11 @@ func TestLegacyWaiter_waitForJob(t *testing.T) { t.Run(tt.name, func(t *testing.T) { done, err := lw.waitForJob(tt.obj, "test-job") if tt.wantErr { - if err == nil { - t.Error("expected error, got none") - } else if !strings.Contains(err.Error(), tt.errMessage) { - t.Errorf("expected error to contain %q, got %q", tt.errMessage, err.Error()) - } - } else if err != nil { - t.Errorf("unexpected error: %v", err) - } - - if done != tt.wantDone { - t.Errorf("got done=%v, want %v", done, tt.wantDone) + require.Error(t, err, "expected error, got none") + require.ErrorContainsf(t, err, tt.errMessage, "expected error to contain %q, got %q", tt.errMessage, err.Error()) + } else { + require.NoError(t, err) + assert.Equal(t, tt.wantDone, done, "got done=%v, want %v", done, tt.wantDone) } }) } @@ -459,9 +447,7 @@ func TestLegacyWaiter_isRetryableError(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := lw.isRetryableError(tt.err, info) - if got != tt.wantRetry { - t.Errorf("isRetryableError() = %v, want %v", got, tt.wantRetry) - } + assert.Equal(t, tt.wantRetry, got, "isRetryableError() = %v, want %v", got, tt.wantRetry) }) } } diff --git a/pkg/registry/client_tls_test.go b/pkg/registry/client_tls_test.go index 45eff232c..0bad5df64 100644 --- a/pkg/registry/client_tls_test.go +++ b/pkg/registry/client_tls_test.go @@ -40,22 +40,19 @@ func (suite *TLSRegistryClientTestSuite) TearDownSuite() { } func (suite *TLSRegistryClientTestSuite) Test_0_Login() { - err := suite.RegistryClient.Login(suite.DockerRegistryHost, + suite.Require().Error(suite.RegistryClient.Login(suite.DockerRegistryHost, LoginOptBasicAuth("badverybad", "ohsobad"), - LoginOptTLSClientConfig(tlsCert, tlsKey, tlsCA)) - suite.Require().Error(err, "error logging into registry with bad credentials") + LoginOptTLSClientConfig(tlsCert, tlsKey, tlsCA)), "error logging into registry with bad credentials") - err = suite.RegistryClient.Login(suite.DockerRegistryHost, + suite.Require().NoError(suite.RegistryClient.Login(suite.DockerRegistryHost, LoginOptBasicAuth(testUsername, testPassword), - LoginOptTLSClientConfig(tlsCert, tlsKey, tlsCA)) - suite.Require().NoError(err, "no error logging into registry with good credentials") + LoginOptTLSClientConfig(tlsCert, tlsKey, tlsCA)), "no error logging into registry with good credentials") } func (suite *TLSRegistryClientTestSuite) Test_1_Login() { - err := suite.RegistryClient.Login(suite.DockerRegistryHost, + suite.Require().Error(suite.RegistryClient.Login(suite.DockerRegistryHost, LoginOptBasicAuth("badverybad", "ohsobad"), - LoginOptTLSClientConfigFromConfig(&tls.Config{})) - suite.Require().Error(err, "error logging into registry with bad credentials") + LoginOptTLSClientConfigFromConfig(&tls.Config{})), "error logging into registry with bad credentials") // Create a *tls.Config from tlsCert, tlsKey, and tlsCA. cert, err := tls.LoadX509KeyPair(tlsCert, tlsKey) @@ -69,10 +66,9 @@ func (suite *TLSRegistryClientTestSuite) Test_1_Login() { RootCAs: rootCAs, } - err = suite.RegistryClient.Login(suite.DockerRegistryHost, + suite.Require().NoError(suite.RegistryClient.Login(suite.DockerRegistryHost, LoginOptBasicAuth(testUsername, testPassword), - LoginOptTLSClientConfigFromConfig(conf)) - suite.Require().NoError(err, "no error logging into registry with good credentials") + LoginOptTLSClientConfigFromConfig(conf)), "no error logging into registry with good credentials") } func (suite *TLSRegistryClientTestSuite) Test_1_Push() { @@ -94,8 +90,7 @@ func (suite *TLSRegistryClientTestSuite) Test_4_Logout() { suite.Require().Error(err, "failed to delete the credential for this-host-aint-real:5000") } - err = suite.RegistryClient.Logout(suite.DockerRegistryHost) - suite.Require().NoError(err, "no error logging out of registry") + suite.Require().NoError(suite.RegistryClient.Logout(suite.DockerRegistryHost), "no error logging out of registry") } func TestTLSRegistryClientTestSuite(t *testing.T) { diff --git a/pkg/release/v1/info_test.go b/pkg/release/v1/info_test.go index 12b3014f6..61a888cb8 100644 --- a/pkg/release/v1/info_test.go +++ b/pkg/release/v1/info_test.go @@ -253,17 +253,17 @@ func TestInfoUnmarshalJSON(t *testing.T) { err := json.Unmarshal([]byte(tt.input), &info) if tt.wantErr { assert.Error(t, err) - return + } else { + require.NoError(t, err) + assert.Equal(t, tt.expected.FirstDeployed.Unix(), info.FirstDeployed.Unix()) + assert.Equal(t, tt.expected.LastDeployed.Unix(), info.LastDeployed.Unix()) + assert.Equal(t, tt.expected.Deleted.Unix(), info.Deleted.Unix()) + assert.Equal(t, tt.expected.Description, info.Description) + assert.Equal(t, tt.expected.Status, info.Status) + assert.Equal(t, tt.expected.RollbackRevision, info.RollbackRevision) + assert.Equal(t, tt.expected.Notes, info.Notes) + assert.Equal(t, tt.expected.Resources, info.Resources) } - require.NoError(t, err) - assert.Equal(t, tt.expected.FirstDeployed.Unix(), info.FirstDeployed.Unix()) - assert.Equal(t, tt.expected.LastDeployed.Unix(), info.LastDeployed.Unix()) - assert.Equal(t, tt.expected.Deleted.Unix(), info.Deleted.Unix()) - assert.Equal(t, tt.expected.Description, info.Description) - assert.Equal(t, tt.expected.Status, info.Status) - assert.Equal(t, tt.expected.RollbackRevision, info.RollbackRevision) - assert.Equal(t, tt.expected.Notes, info.Notes) - assert.Equal(t, tt.expected.Resources, info.Resources) }) } } @@ -284,9 +284,7 @@ func TestInfoRoundTrip(t *testing.T) { require.NoError(t, err) var decoded Info - err = json.Unmarshal(data, &decoded) - require.NoError(t, err) - + require.NoError(t, json.Unmarshal(data, &decoded)) assert.Equal(t, original.FirstDeployed.Unix(), decoded.FirstDeployed.Unix()) assert.Equal(t, original.LastDeployed.Unix(), decoded.LastDeployed.Unix()) assert.Equal(t, original.Deleted.Unix(), decoded.Deleted.Unix()) @@ -330,9 +328,7 @@ func TestInfoRollbackRevisionRoundTrip(t *testing.T) { require.NoError(t, err) var decoded Info - err = json.Unmarshal(data, &decoded) - require.NoError(t, err) - + require.NoError(t, json.Unmarshal(data, &decoded)) assert.Equal(t, tt.info.RollbackRevision, decoded.RollbackRevision) assert.Equal(t, tt.info.FirstDeployed.Unix(), decoded.FirstDeployed.Unix()) assert.Equal(t, tt.info.LastDeployed.Unix(), decoded.LastDeployed.Unix()) @@ -342,8 +338,7 @@ func TestInfoRollbackRevisionRoundTrip(t *testing.T) { // Verify omitempty behavior: zero rollback_revision should not appear in JSON if tt.info.RollbackRevision == 0 { var raw map[string]any - err = json.Unmarshal(data, &raw) - require.NoError(t, err) + require.NoError(t, json.Unmarshal(data, &raw)) assert.NotContains(t, raw, "rollback_revision") } }) @@ -356,13 +351,12 @@ func TestInfoEmptyStringRoundTrip(t *testing.T) { input := `{"first_deployed":"","last_deployed":"","deleted":"","status":"deployed","description":"test"}` var info Info - err := json.Unmarshal([]byte(input), &info) - require.NoError(t, err) + require.NoError(t, json.Unmarshal([]byte(input), &info)) // Verify time fields are zero values - assert.True(t, info.FirstDeployed.IsZero()) - assert.True(t, info.LastDeployed.IsZero()) - assert.True(t, info.Deleted.IsZero()) + assert.Zero(t, info.FirstDeployed) + assert.Zero(t, info.LastDeployed) + assert.Zero(t, info.Deleted) assert.Equal(t, common.StatusDeployed, info.Status) assert.Equal(t, "test", info.Description) @@ -371,8 +365,7 @@ func TestInfoEmptyStringRoundTrip(t *testing.T) { require.NoError(t, err) var result map[string]any - err = json.Unmarshal(data, &result) - require.NoError(t, err) + require.NoError(t, json.Unmarshal(data, &result)) // Zero time values should be omitted due to omitzero tag assert.NotContains(t, result, "first_deployed") From a934b827fa9569c8769c981b1d4847f72a4c1f94 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 20:50:57 +0200 Subject: [PATCH 39/61] chore(pkg): refactor: convert tests to testify assert/require part 21 #### Description refactor: convert tests to testify assert/require in pkg/cmd Signed-off-by: Matthieu MOREL --- pkg/action/action_test.go | 20 ++++---------- pkg/action/dependency_test.go | 24 +++++------------ pkg/action/list_test.go | 29 +++++++------------- pkg/chart/v2/lint/support/message_test.go | 29 +++++++------------- pkg/cmd/history_test.go | 30 +++++++++------------ pkg/cmd/require/args_test.go | 16 ++++-------- pkg/cmd/rollback_test.go | 26 +++++++----------- pkg/cmd/root_test.go | 32 ++++++++--------------- pkg/cmd/search_hub_test.go | 28 +++++++------------- pkg/engine/files_test.go | 14 ++++------ pkg/engine/funcs_test.go | 12 +++------ pkg/getter/plugingetter_test.go | 23 ++++++---------- pkg/pusher/pusher_test.go | 31 +++++++++------------- pkg/registry/client_insecure_tls_test.go | 13 ++++----- pkg/release/v1/hook_test.go | 24 +++++++---------- pkg/storage/driver/mock_test.go | 18 ++++--------- pkg/storage/driver/util_test.go | 22 +++++++--------- 17 files changed, 138 insertions(+), 253 deletions(-) diff --git a/pkg/action/action_test.go b/pkg/action/action_test.go index 880a9930b..056c539a5 100644 --- a/pkg/action/action_test.go +++ b/pkg/action/action_test.go @@ -58,9 +58,7 @@ func actionConfigFixtureWithDummyResources(t *testing.T, dummyResources kube.Res slog.SetDefault(logger) registryClient, err := registry.NewClient() - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) return &Configuration{ Releases: storage.Init(driver.NewMemory()), @@ -371,16 +369,10 @@ func TestGetVersionSet(t *testing.T) { client := fakeclientset.NewClientset() vs, err := GetVersionSet(client.Discovery()) - if err != nil { - t.Error(err) - } + require.NoError(t, err) - if !vs.Has("v1") { - t.Error("Expected supported versions to at least include v1.") - } - if vs.Has("nosuchversion/v1") { - t.Error("Non-existent version is reported found.") - } + assert.True(t, vs.Has("v1"), "Expected supported versions to at least include v1.") + assert.False(t, vs.Has("nosuchversion/v1"), "Non-existent version is reported found.") } // Mock PostRenderer for testing @@ -2031,9 +2023,7 @@ spec: mockPR := &mockPostRenderer{ transform: func(content string) string { count := strings.Count(content, "kind: ServiceAccount") - if count > 1 { - t.Errorf("post-renderer received %d ServiceAccount resources in a single stream, expected at most 1", count) - } + assert.LessOrEqualf(t, count, 1, "post-renderer received %d ServiceAccount resources in a single stream, expected at most 1", count) return content }, } diff --git a/pkg/action/dependency_test.go b/pkg/action/dependency_test.go index 25664b98c..adbe311d6 100644 --- a/pkg/action/dependency_test.go +++ b/pkg/action/dependency_test.go @@ -57,9 +57,7 @@ func TestList(t *testing.T) { }, } { buf := bytes.Buffer{} - if err := NewDependency().List(tcase.chart, &buf); err != nil { - t.Fatal(err) - } + require.NoError(t, NewDependency().List(tcase.chart, &buf)) test.AssertGoldenString(t, buf.String(), tcase.golden) } } @@ -71,22 +69,16 @@ func TestDependencyStatus_Dashes(t *testing.T) { dir := t.TempDir() chartpath := filepath.Join(dir, "charts") - if err := os.MkdirAll(chartpath, 0o700); err != nil { - t.Fatal(err) - } + require.NoError(t, os.MkdirAll(chartpath, 0o700)) // Add some fake charts first := buildChart(withName("first-chart")) _, err := chartutil.Save(first, chartpath) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) second := buildChart(withName("first-chart-second-chart")) _, err = chartutil.Save(second, chartpath) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) dep := &chart.Dependency{ Name: "first-chart", @@ -95,9 +87,7 @@ func TestDependencyStatus_Dashes(t *testing.T) { // Now try to get the deps stat := NewDependency().dependencyStatus(dir, dep, first) - if stat != "ok" { - t.Errorf("Unexpected status: %q", stat) - } + assert.Equal(t, "ok", stat, "Unexpected status: %q", stat) } func TestStatArchiveForStatus(t *testing.T) { @@ -105,9 +95,7 @@ func TestStatArchiveForStatus(t *testing.T) { dir := t.TempDir() chartpath := filepath.Join(dir, "charts") - if err := os.MkdirAll(chartpath, 0o700); err != nil { - t.Fatal(err) - } + require.NoError(t, os.MkdirAll(chartpath, 0o700)) // unsaved chart lilith := buildChart(withName("lilith")) diff --git a/pkg/action/list_test.go b/pkg/action/list_test.go index e7c2770d7..1c849028d 100644 --- a/pkg/action/list_test.go +++ b/pkg/action/list_test.go @@ -44,9 +44,7 @@ func TestListStates(t *testing.T) { "unknown": ListUnknown, "totally made up key": ListUnknown, } { - if expect != expect.FromName(input) { - t.Errorf("Expected %d for %s", expect, input) - } + assert.Equal(t, expect.FromName(input), expect, "Expected %d for %s", expect, input) // This is a cheap way to verify that ListAll actually allows everything but Unknown if got := expect.FromName(input); got != ListUnknown && got&ListAll == 0 { t.Errorf("Expected %s to match the ListAll filter", input) @@ -54,12 +52,10 @@ func TestListStates(t *testing.T) { } filter := ListDeployed | ListPendingRollback - if status := filter.FromName("deployed"); filter&status == 0 { - t.Errorf("Expected %d to match mask %d", status, filter) - } - if status := filter.FromName("failed"); filter&status != 0 { - t.Errorf("Expected %d to fail to match mask %d", status, filter) - } + status := filter.FromName("deployed") + assert.NotEqualf(t, ListStates(0), filter&status, "Expected %d to match mask %d", status, filter) + status = filter.FromName("failed") + assert.Equalf(t, ListStates(0), filter&status, "Expected %d to fail to match mask %d", status, filter) } func TestList_Empty(t *testing.T) { @@ -202,8 +198,7 @@ func TestList_StateMask(t *testing.T) { } one.SetStatus(common.StatusUninstalled, "uninstalled") - err = lister.cfg.Releases.Update(one) - req.NoError(err) + req.NoError(lister.cfg.Releases.Update(one)) res, err := lister.Run() req.NoError(err) @@ -277,9 +272,7 @@ func makeMeSomeReleasesWithStaleFailure(t *testing.T, store *storage.Storage) { five.Version = 1 for _, rel := range []*release.Release{one, two, three, four, five} { - if err := store.Create(rel); err != nil { - t.Fatal(err) - } + require.NoError(t, store.Create(rel)) } all, err := store.ListReleases() @@ -328,9 +321,7 @@ func makeMeSomeReleases(t *testing.T, store *storage.Storage) { three.Version = 3 for _, rel := range []*release.Release{one, two, three} { - if err := store.Create(rel); err != nil { - t.Fatal(err) - } + require.NoError(t, store.Create(rel)) } all, err := store.ListReleases() @@ -389,9 +380,7 @@ func TestSelectorList(t *testing.T) { lister := newListFixture(t) for _, rel := range []*release.Release{r1, r2, r3} { - if err := lister.cfg.Releases.Create(rel); err != nil { - t.Fatal(err) - } + require.NoError(t, lister.cfg.Releases.Create(rel)) } t.Run("should fail selector parsing", func(t *testing.T) { diff --git a/pkg/chart/v2/lint/support/message_test.go b/pkg/chart/v2/lint/support/message_test.go index ce5b5e42e..dfbc65844 100644 --- a/pkg/chart/v2/lint/support/message_test.go +++ b/pkg/chart/v2/lint/support/message_test.go @@ -19,6 +19,9 @@ package support import ( "errors" "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var errLint = errors.New("lint failed") @@ -47,33 +50,19 @@ func TestRunLinterRule(t *testing.T) { linter := Linter{} for _, test := range tests { isValid := linter.RunLinterRule(test.Severity, "chart", test.LintError) - if len(linter.Messages) != test.ExpectedMessages { - t.Errorf("RunLinterRule(%d, \"chart\", %v), linter.Messages should now have %d message, we got %d", test.Severity, test.LintError, test.ExpectedMessages, len(linter.Messages)) - } - - if linter.HighestSeverity != test.ExpectedHighestSeverity { - t.Errorf("RunLinterRule(%d, \"chart\", %v), linter.HighestSeverity should be %d, we got %d", test.Severity, test.LintError, test.ExpectedHighestSeverity, linter.HighestSeverity) - } - - if isValid != test.ExpectedReturn { - t.Errorf("RunLinterRule(%d, \"chart\", %v), should have returned %t but returned %t", test.Severity, test.LintError, test.ExpectedReturn, isValid) - } + assert.Lenf(t, linter.Messages, test.ExpectedMessages, "RunLinterRule(%d, \"chart\", %v), linter.Messages should now have %d message, we got %d", test.Severity, test.LintError, test.ExpectedMessages, len(linter.Messages)) + assert.Equalf(t, linter.HighestSeverity, test.ExpectedHighestSeverity, "RunLinterRule(%d, \"chart\", %v), linter.HighestSeverity should be %d, we got %d", test.Severity, test.LintError, test.ExpectedHighestSeverity, linter.HighestSeverity) + assert.Equalf(t, isValid, test.ExpectedReturn, "RunLinterRule(%d, \"chart\", %v), should have returned %t but returned %t", test.Severity, test.LintError, test.ExpectedReturn, isValid) } } func TestMessage(t *testing.T) { m := Message{ErrorSev, "Chart.yaml", errors.New("Foo")} - if m.Error() != "[ERROR] Chart.yaml: Foo" { - t.Errorf("Unexpected output: %s", m.Error()) - } + require.EqualErrorf(t, m, "[ERROR] Chart.yaml: Foo", "Unexpected output: %s", m.Error()) m = Message{WarningSev, "templates/", errors.New("Bar")} - if m.Error() != "[WARNING] templates/: Bar" { - t.Errorf("Unexpected output: %s", m.Error()) - } + require.EqualErrorf(t, m, "[WARNING] templates/: Bar", "Unexpected output: %s", m.Error()) m = Message{InfoSev, "templates/rc.yaml", errors.New("FooBar")} - if m.Error() != "[INFO] templates/rc.yaml: FooBar" { - t.Errorf("Unexpected output: %s", m.Error()) - } + assert.EqualErrorf(t, m, "[INFO] templates/rc.yaml: FooBar", "Unexpected output: %s", m.Error()) } diff --git a/pkg/cmd/history_test.go b/pkg/cmd/history_test.go index 2bace98e0..cd8e353e7 100644 --- a/pkg/cmd/history_test.go +++ b/pkg/cmd/history_test.go @@ -385,16 +385,16 @@ func TestReleaseInfoUnmarshalJSON(t *testing.T) { err := json.Unmarshal([]byte(tt.input), &info) if tt.wantErr { assert.Error(t, err) - return + } else { + require.NoError(t, err) + assert.Equal(t, tt.expected.Revision, info.Revision) + assert.Equal(t, tt.expected.Updated.Unix(), info.Updated.Unix()) + assert.Equal(t, tt.expected.Status, info.Status) + assert.Equal(t, tt.expected.Chart, info.Chart) + assert.Equal(t, tt.expected.AppVersion, info.AppVersion) + assert.Equal(t, tt.expected.RollbackRevision, info.RollbackRevision) + assert.Equal(t, tt.expected.Description, info.Description) } - require.NoError(t, err) - assert.Equal(t, tt.expected.Revision, info.Revision) - assert.Equal(t, tt.expected.Updated.Unix(), info.Updated.Unix()) - assert.Equal(t, tt.expected.Status, info.Status) - assert.Equal(t, tt.expected.Chart, info.Chart) - assert.Equal(t, tt.expected.AppVersion, info.AppVersion) - assert.Equal(t, tt.expected.RollbackRevision, info.RollbackRevision) - assert.Equal(t, tt.expected.Description, info.Description) }) } } @@ -415,9 +415,7 @@ func TestReleaseInfoRoundTrip(t *testing.T) { require.NoError(t, err) var decoded releaseInfo - err = json.Unmarshal(data, &decoded) - require.NoError(t, err) - + require.NoError(t, json.Unmarshal(data, &decoded)) assert.Equal(t, original.Revision, decoded.Revision) assert.Equal(t, original.Updated.Unix(), decoded.Updated.Unix()) assert.Equal(t, original.Status, decoded.Status) @@ -433,11 +431,10 @@ func TestReleaseInfoEmptyStringRoundTrip(t *testing.T) { input := `{"revision":1,"updated":"","status":"deployed","chart":"mychart-1.0.0","app_version":"1.0.0","description":"Test"}` var info releaseInfo - err := json.Unmarshal([]byte(input), &info) - require.NoError(t, err) + require.NoError(t, json.Unmarshal([]byte(input), &info)) // Verify time field is zero value - assert.True(t, info.Updated.IsZero()) + assert.Zero(t, info.Updated) assert.Equal(t, 1, info.Revision) assert.Equal(t, "deployed", info.Status) @@ -446,8 +443,7 @@ func TestReleaseInfoEmptyStringRoundTrip(t *testing.T) { require.NoError(t, err) var result map[string]any - err = json.Unmarshal(data, &result) - require.NoError(t, err) + require.NoError(t, json.Unmarshal(data, &result)) // Zero time value should be omitted assert.NotContains(t, result, "updated") diff --git a/pkg/cmd/require/args_test.go b/pkg/cmd/require/args_test.go index 89403140e..5d3a9f003 100644 --- a/pkg/cmd/require/args_test.go +++ b/pkg/cmd/require/args_test.go @@ -18,10 +18,10 @@ package require import ( "io" "strconv" - "strings" "testing" "github.com/spf13/cobra" + "github.com/stretchr/testify/require" ) func TestArgs(t *testing.T) { @@ -77,16 +77,10 @@ func runTestCases(t *testing.T, testCases []testCase) { err := cmd.Execute() if tc.wantError == "" { - if err != nil { - t.Fatalf("unexpected error, got '%v'", err) - } - return - } - if !strings.Contains(err.Error(), tc.wantError) { - t.Fatalf("unexpected error \n\nWANT:\n%q\n\nGOT:\n%q\n", tc.wantError, err) - } - if !strings.Contains(err.Error(), "Usage:") { - t.Fatalf("unexpected error: want Usage string\n\nGOT:\n%q\n", err) + require.NoError(t, err) + } else { + require.ErrorContains(t, err, tc.wantError) + require.ErrorContains(t, err, "Usage:") } }) } diff --git a/pkg/cmd/rollback_test.go b/pkg/cmd/rollback_test.go index 116e158fd..ff7f314c9 100644 --- a/pkg/cmd/rollback_test.go +++ b/pkg/cmd/rollback_test.go @@ -21,6 +21,9 @@ import ( "reflect" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + chart "helm.sh/helm/v4/pkg/chart/v2" "helm.sh/helm/v4/pkg/release/common" release "helm.sh/helm/v4/pkg/release/v1" @@ -148,24 +151,15 @@ func TestRollbackWithLabels(t *testing.T) { } storage := storageFixture() for _, rel := range rels { - if err := storage.Create(rel); err != nil { - t.Fatal(err) - } + require.NoError(t, storage.Create(rel)) } _, _, err := executeActionCommandC(storage, fmt.Sprintf("rollback %s 1", releaseName)) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } + require.NoError(t, err) + updatedReli, err := storage.Get(releaseName, 3) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } - updatedRel, err := releaserToV1Release(updatedReli) - if err != nil { - t.Errorf("unexpected error, got '%v'", err) - } + require.NoError(t, err) - if !reflect.DeepEqual(updatedRel.Labels, labels1) { - t.Errorf("Expected {%v}, got {%v}", labels1, updatedRel.Labels) - } + updatedRel, err := releaserToV1Release(updatedReli) + require.NoError(t, err) + assert.Truef(t, reflect.DeepEqual(updatedRel.Labels, labels1), "Expected {%v}, got {%v}", labels1, updatedRel.Labels) } diff --git a/pkg/cmd/root_test.go b/pkg/cmd/root_test.go index 316e6bd2e..b07bdbbf6 100644 --- a/pkg/cmd/root_test.go +++ b/pkg/cmd/root_test.go @@ -23,6 +23,9 @@ import ( "path/filepath" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "helm.sh/helm/v4/internal/test/ensure" "helm.sh/helm/v4/pkg/action" "helm.sh/helm/v4/pkg/helmpath" @@ -86,9 +89,8 @@ func TestRootCmd(t *testing.T) { t.Setenv(k, v) } - if _, _, err := executeActionCommand(tt.args); err != nil { - t.Fatalf("unexpected error: %s", err) - } + _, _, err := executeActionCommand(tt.args) + require.NoError(t, err) // NOTE(bacongobbler): we need to check here after calling ensure.HelmHome so we // load the proper paths after XDG_*_HOME is set @@ -104,15 +106,9 @@ func TestRootCmd(t *testing.T) { tt.dataPath = filepath.Join(os.Getenv(xdg.DataHomeEnvVar), "helm") } - if helmpath.CachePath() != tt.cachePath { - t.Errorf("expected cache path %q, got %q", tt.cachePath, helmpath.CachePath()) - } - if helmpath.ConfigPath() != tt.configPath { - t.Errorf("expected config path %q, got %q", tt.configPath, helmpath.ConfigPath()) - } - if helmpath.DataPath() != tt.dataPath { - t.Errorf("expected data path %q, got %q", tt.dataPath, helmpath.DataPath()) - } + assert.Equal(t, tt.cachePath, helmpath.CachePath(), "expected cache path %q, got %q", tt.cachePath, helmpath.CachePath()) + assert.Equal(t, tt.configPath, helmpath.ConfigPath(), "expected config path %q, got %q", tt.configPath, helmpath.ConfigPath()) + assert.Equal(t, tt.dataPath, helmpath.DataPath(), "expected data path %q, got %q", tt.dataPath, helmpath.DataPath()) }) } } @@ -120,9 +116,7 @@ func TestRootCmd(t *testing.T) { func TestUnknownSubCmd(t *testing.T) { _, _, err := executeActionCommand("foobar") - if err == nil || err.Error() != `unknown command "foobar" for "helm"` { - t.Errorf("Expect unknown command error, got %q", err) - } + assert.EqualErrorf(t, err, `unknown command "foobar" for "helm"`, "Expect unknown command error") } // Need the release of Cobra following 1.0 to be able to disable @@ -138,14 +132,10 @@ func TestRootCmdLogger(t *testing.T) { buf := new(bytes.Buffer) actionConfig := action.NewConfiguration() _, err := newRootCmdWithConfig(actionConfig, buf, args, SetupLogging) - if err != nil { - t.Errorf("expected no error, got: '%v'", err) - } + require.NoError(t, err) l1 := actionConfig.Logger() l2 := slog.Default() - if l1.Handler() != l2.Handler() { - t.Error("expected actionConfig logger to be the slog default logger") - } + assert.Equal(t, l2.Handler(), l1.Handler(), "expected actionConfig logger to be the slog default logger") } diff --git a/pkg/cmd/search_hub_test.go b/pkg/cmd/search_hub_test.go index 98bf052f2..7b00cc295 100644 --- a/pkg/cmd/search_hub_test.go +++ b/pkg/cmd/search_hub_test.go @@ -21,6 +21,9 @@ import ( "net/http" "net/http/httptest" "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestSearchHubCmd(t *testing.T) { @@ -42,9 +45,7 @@ func TestSearchHubCmd(t *testing.T) { testcmd := "search hub --endpoint " + ts.URL + " maria" storage := storageFixture() _, out, err := executeActionCommandC(storage, testcmd) - if err != nil { - t.Errorf("unexpected error, %s", err) - } + require.NoError(t, err) if out != expected { t.Error("expected and actual output did not match") t.Log(out) @@ -71,9 +72,7 @@ func TestSearchHubListRepoCmd(t *testing.T) { testcmd := "search hub --list-repo-url --endpoint " + ts.URL + " maria" storage := storageFixture() _, out, err := executeActionCommandC(storage, testcmd) - if err != nil { - t.Errorf("unexpected error, %s", err) - } + require.NoError(t, err) if out != expected { t.Error("expected and actual output did not match") t.Log(out) @@ -165,21 +164,14 @@ func TestSearchHubCmd_FailOnNoResponseTests(t *testing.T) { _, out, err := executeActionCommandC(storage, tt.cmd) if tt.wantErr { - if err == nil { - t.Error("expected error due to no record in response, got nil") - } + require.Error(t, err, "expected error due to no record in response, got nil") } else { - if err != nil { - t.Errorf("unexpected error, got %q", err) - } + require.NoError(t, err) } - if out != tt.expected { - t.Errorf("expected and actual output did not match\n"+ - "expected: %q\n"+ - "actual : %q", - tt.expected, out) - } + assert.Equal(t, tt.expected, out, "expected and actual output did not match\n"+ + "expected: %q\n"+ + "actual : %q", tt.expected, out) }) } } diff --git a/pkg/engine/files_test.go b/pkg/engine/files_test.go index b4318a597..6ff251aad 100644 --- a/pkg/engine/files_test.go +++ b/pkg/engine/files_test.go @@ -44,17 +44,13 @@ func getTestFiles() files { func TestNewFiles(t *testing.T) { files := getTestFiles() - if len(files) != len(cases) { - t.Errorf("Expected len() = %d, got %d", len(cases), len(files)) - } + assert.Len(t, files, len(cases), "Expected len() = %d, got %d", len(cases), len(files)) for i, f := range cases { - if got := string(files.GetBytes(f.path)); got != f.data { - t.Errorf("%d: expected %q, got %q", i, f.data, got) - } - if got := files.Get(f.path); got != f.data { - t.Errorf("%d: expected %q, got %q", i, f.data, got) - } + got := string(files.GetBytes(f.path)) + assert.Equalf(t, got, f.data, "%d: expected %q, got %q", i, f.data, got) + got = files.Get(f.path) + assert.Equalf(t, got, f.data, "%d: expected %q, got %q", i, f.data, got) } } diff --git a/pkg/engine/funcs_test.go b/pkg/engine/funcs_test.go index bc541339b..beb87b429 100644 --- a/pkg/engine/funcs_test.go +++ b/pkg/engine/funcs_test.go @@ -134,8 +134,7 @@ keyInElement1 = "valueInElement1"`, for _, tt := range tests { var b strings.Builder - err := template.Must(template.New("test").Funcs(funcMap()).Parse(tt.tpl)).Execute(&b, tt.vars) - require.NoError(t, err) + require.NoError(t, template.Must(template.New("test").Funcs(funcMap()).Parse(tt.tpl)).Execute(&b, tt.vars)) assert.Equal(t, tt.expect, b.String(), tt.tpl) } @@ -360,8 +359,7 @@ func TestDurationHelpers(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { var b strings.Builder - err := template.Must(template.New("test").Funcs(funcMap()).Parse(tt.tpl)).Execute(&b, tt.vars) - require.NoError(t, err, tt.tpl) + require.NoError(t, template.Must(template.New("test").Funcs(funcMap()).Parse(tt.tpl)).Execute(&b, tt.vars), tt.tpl) assert.Equal(t, tt.expect, b.String(), tt.tpl) }) } @@ -422,8 +420,7 @@ func TestDurationHelpers(t *testing.T) { Funcs(funcMap()). Parse(tt.tpl), ) - err := tmpl.Execute(&b, tt.vars) - require.Error(t, err, tt.tpl) + require.Error(t, tmpl.Execute(&b, tt.vars), tt.tpl) }) } } @@ -474,8 +471,7 @@ func TestMerge(t *testing.T) { } tpl := `{{merge .dst .src1 .src2}}` var b strings.Builder - err := template.Must(template.New("test").Funcs(funcMap()).Parse(tpl)).Execute(&b, dict) - require.NoError(t, err) + require.NoError(t, template.Must(template.New("test").Funcs(funcMap()).Parse(tpl)).Execute(&b, dict)) expected := map[string]any{ "a": "one", // key overridden diff --git a/pkg/getter/plugingetter_test.go b/pkg/getter/plugingetter_test.go index 16af9eb31..c9ed9f779 100644 --- a/pkg/getter/plugingetter_test.go +++ b/pkg/getter/plugingetter_test.go @@ -35,25 +35,18 @@ func TestCollectPlugins(t *testing.T) { env.PluginsDirectory = pluginDir p, err := collectGetterPlugins(env) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if len(p) != 2 { - t.Errorf("Expected 2 plugins, got %d: %v", len(p), p) - } + assert.Len(t, p, 2, "Expected 2 plugins, got %d: %v", len(p), p) - if _, err := p.ByScheme("test2"); err != nil { - t.Error(err) - } + _, err = p.ByScheme("test2") + require.NoError(t, err) - if _, err := p.ByScheme("test"); err != nil { - t.Error(err) - } + _, err = p.ByScheme("test") + require.NoError(t, err) - if _, err := p.ByScheme("nosuchthing"); err == nil { - t.Fatal("did not expect protocol handler for nosuchthing") - } + _, err = p.ByScheme("nosuchthing") + require.Error(t, err, "did not expect protocol handler for nosuchthing") } func TestConvertOptions(t *testing.T) { diff --git a/pkg/pusher/pusher_test.go b/pkg/pusher/pusher_test.go index 71fab8694..078b2fa73 100644 --- a/pkg/pusher/pusher_test.go +++ b/pkg/pusher/pusher_test.go @@ -18,6 +18,9 @@ package pusher import ( "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "helm.sh/helm/v4/pkg/cli" "helm.sh/helm/v4/pkg/registry" ) @@ -28,9 +31,7 @@ func TestProvider(t *testing.T) { func(_ ...Option) (Pusher, error) { return nil, nil }, } - if !p.Provides("three") { - t.Error("Expected provider to provide three") - } + assert.True(t, p.Provides("three"), "Expected provider to provide three") } func TestProviders(t *testing.T) { @@ -39,30 +40,24 @@ func TestProviders(t *testing.T) { {[]string{"two", "four"}, func(_ ...Option) (Pusher, error) { return nil, nil }}, } - if _, err := ps.ByScheme("one"); err != nil { - t.Error(err) - } - if _, err := ps.ByScheme("four"); err != nil { - t.Error(err) - } + _, err := ps.ByScheme("one") + require.NoError(t, err) + _, err = ps.ByScheme("four") + require.NoError(t, err) - if _, err := ps.ByScheme("five"); err == nil { - t.Error("Did not expect handler for five") - } + _, err = ps.ByScheme("five") + assert.Error(t, err, "Did not expect handler for five") } func TestAll(t *testing.T) { env := cli.New() all := All(env) - if len(all) != 1 { - t.Errorf("expected 1 provider (OCI), got %d", len(all)) - } + assert.Len(t, all, 1, "expected 1 provider (OCI), got %d", len(all)) } func TestByScheme(t *testing.T) { env := cli.New() g := All(env) - if _, err := g.ByScheme(registry.OCIScheme); err != nil { - t.Error(err) - } + _, err := g.ByScheme(registry.OCIScheme) + assert.NoError(t, err) } diff --git a/pkg/registry/client_insecure_tls_test.go b/pkg/registry/client_insecure_tls_test.go index ae0a44337..f1ece1b1c 100644 --- a/pkg/registry/client_insecure_tls_test.go +++ b/pkg/registry/client_insecure_tls_test.go @@ -38,15 +38,13 @@ func (suite *InsecureTLSRegistryClientTestSuite) TearDownSuite() { } func (suite *InsecureTLSRegistryClientTestSuite) Test_0_Login() { - err := suite.RegistryClient.Login(suite.DockerRegistryHost, + suite.Require().Error(suite.RegistryClient.Login(suite.DockerRegistryHost, LoginOptBasicAuth("badverybad", "ohsobad"), - LoginOptInsecure(true)) - suite.Require().Error(err, "error logging into registry with bad credentials") + LoginOptInsecure(true)), "error logging into registry with bad credentials") - err = suite.RegistryClient.Login(suite.DockerRegistryHost, + suite.Require().NoError(suite.RegistryClient.Login(suite.DockerRegistryHost, LoginOptBasicAuth(testUsername, testPassword), - LoginOptInsecure(true)) - suite.Require().NoError(err, "no error logging into registry with good credentials") + LoginOptInsecure(true)), "no error logging into registry with good credentials") } func (suite *InsecureTLSRegistryClientTestSuite) Test_1_Push() { @@ -68,8 +66,7 @@ func (suite *InsecureTLSRegistryClientTestSuite) Test_4_Logout() { suite.Require().Error(err, "failed to delete the credential for this-host-aint-real:5000") } - err = suite.RegistryClient.Logout(suite.DockerRegistryHost) - suite.Require().NoError(err, "no error logging out of registry") + suite.Require().NoError(suite.RegistryClient.Logout(suite.DockerRegistryHost), "no error logging out of registry") } func TestInsecureTLSRegistryClientTestSuite(t *testing.T) { diff --git a/pkg/release/v1/hook_test.go b/pkg/release/v1/hook_test.go index f3b8811a6..9e803a0fc 100644 --- a/pkg/release/v1/hook_test.go +++ b/pkg/release/v1/hook_test.go @@ -170,12 +170,12 @@ func TestHookExecutionUnmarshalJSON(t *testing.T) { err := json.Unmarshal([]byte(tt.input), &exec) if tt.wantErr { assert.Error(t, err) - return + } else { + require.NoError(t, err) + assert.Equal(t, tt.expected.StartedAt.Unix(), exec.StartedAt.Unix()) + assert.Equal(t, tt.expected.CompletedAt.Unix(), exec.CompletedAt.Unix()) + assert.Equal(t, tt.expected.Phase, exec.Phase) } - require.NoError(t, err) - assert.Equal(t, tt.expected.StartedAt.Unix(), exec.StartedAt.Unix()) - assert.Equal(t, tt.expected.CompletedAt.Unix(), exec.CompletedAt.Unix()) - assert.Equal(t, tt.expected.Phase, exec.Phase) }) } } @@ -194,9 +194,7 @@ func TestHookExecutionRoundTrip(t *testing.T) { require.NoError(t, err) var decoded HookExecution - err = json.Unmarshal(data, &decoded) - require.NoError(t, err) - + require.NoError(t, json.Unmarshal(data, &decoded)) assert.Equal(t, original.StartedAt.Unix(), decoded.StartedAt.Unix()) assert.Equal(t, original.CompletedAt.Unix(), decoded.CompletedAt.Unix()) assert.Equal(t, original.Phase, decoded.Phase) @@ -208,12 +206,11 @@ func TestHookExecutionEmptyStringRoundTrip(t *testing.T) { input := `{"started_at":"","completed_at":"","phase":"Succeeded"}` var exec HookExecution - err := json.Unmarshal([]byte(input), &exec) - require.NoError(t, err) + require.NoError(t, json.Unmarshal([]byte(input), &exec)) // Verify time fields are zero values - assert.True(t, exec.StartedAt.IsZero()) - assert.True(t, exec.CompletedAt.IsZero()) + assert.Zero(t, exec.StartedAt) + assert.Zero(t, exec.CompletedAt) assert.Equal(t, HookPhaseSucceeded, exec.Phase) // Marshal back and verify empty time fields are omitted @@ -221,8 +218,7 @@ func TestHookExecutionEmptyStringRoundTrip(t *testing.T) { require.NoError(t, err) var result map[string]any - err = json.Unmarshal(data, &result) - require.NoError(t, err) + require.NoError(t, json.Unmarshal(data, &result)) // Zero time values should be omitted assert.NotContains(t, result, "started_at") diff --git a/pkg/storage/driver/mock_test.go b/pkg/storage/driver/mock_test.go index ab7b261cf..c366d106d 100644 --- a/pkg/storage/driver/mock_test.go +++ b/pkg/storage/driver/mock_test.go @@ -24,6 +24,7 @@ import ( sqlmock "github.com/DATA-DOG/go-sqlmock" sq "github.com/Masterminds/squirrel" "github.com/jmoiron/sqlx" + "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -74,10 +75,7 @@ func tsFixtureMemory(t *testing.T) *Memory { mem := NewMemory() for _, tt := range hs { - err := mem.Create(testKey(tt.Name, tt.Version), tt) - if err != nil { - t.Fatalf("Test setup failed to create: %s\n", err) - } + require.NoError(t, mem.Create(testKey(tt.Name, tt.Version), tt), "Test setup failed to create") } return mem } @@ -108,9 +106,7 @@ func (mock *MockConfigMapsInterface) Init(t *testing.T, releases ...*rspb.Releas objkey := testKey(rls.Name, rls.Version) cfgmap, err := newConfigMapsObject(objkey, rls, nil) - if err != nil { - t.Fatalf("Failed to create configmap: %s", err) - } + require.NoError(t, err, "Failed to create configmap") mock.objects[objkey] = cfgmap } } @@ -196,9 +192,7 @@ func (mock *MockSecretsInterface) Init(t *testing.T, releases ...*rspb.Release) objkey := testKey(rls.Name, rls.Version) secret, err := newSecretsObject(objkey, rls, nil) - if err != nil { - t.Fatalf("Failed to create secret: %s", err) - } + require.NoError(t, err, "Failed to create secret") mock.objects[objkey] = secret } } @@ -262,9 +256,7 @@ func (mock *MockSecretsInterface) Delete(_ context.Context, name string, _ metav func newTestFixtureSQL(t *testing.T, _ ...*rspb.Release) (*SQL, sqlmock.Sqlmock) { t.Helper() sqlDB, mock, err := sqlmock.New() - if err != nil { - t.Fatalf("error when opening stub database connection: %v", err) - } + require.NoError(t, err, "error when opening stub database connection") sqlxDB := sqlx.NewDb(sqlDB, "sqlmock") return &SQL{ diff --git a/pkg/storage/driver/util_test.go b/pkg/storage/driver/util_test.go index d16043924..7074f252a 100644 --- a/pkg/storage/driver/util_test.go +++ b/pkg/storage/driver/util_test.go @@ -16,12 +16,13 @@ package driver import ( "reflect" "testing" + + "github.com/stretchr/testify/assert" ) func TestGetSystemLabel(t *testing.T) { - if output := GetSystemLabels(); !reflect.DeepEqual(systemLabels, output) { - t.Errorf("Expected {%v}, got {%v}", systemLabels, output) - } + output := GetSystemLabels() + assert.Truef(t, reflect.DeepEqual(systemLabels, output), "Expected {%v}, got {%v}", systemLabels, output) } func TestIsSystemLabel(t *testing.T) { @@ -32,9 +33,8 @@ func TestIsSystemLabel(t *testing.T) { "NaMe": false, } for label, result := range tests { - if output := isSystemLabel(label); output != result { - t.Errorf("Output %t not equal to expected %t", output, result) - } + output := isSystemLabel(label) + assert.Equalf(t, output, result, "Output %t not equal to expected %t", output, result) } } @@ -68,9 +68,8 @@ func TestFilterSystemLabels(t *testing.T) { }}, } for _, test := range tests { - if output := filterSystemLabels(test[0]); !reflect.DeepEqual(test[1], output) { - t.Errorf("Expected {%v}, got {%v}", test[1], output) - } + output := filterSystemLabels(test[0]) + assert.Truef(t, reflect.DeepEqual(test[1], output), "Expected {%v}, got {%v}", test[1], output) } } @@ -101,8 +100,7 @@ func TestContainsSystemLabels(t *testing.T) { }, false}, } for _, test := range tests { - if output := ContainsSystemLabels(test.input); !reflect.DeepEqual(test.output, output) { - t.Errorf("Expected {%v}, got {%v}", test.output, output) - } + output := ContainsSystemLabels(test.input) + assert.Truef(t, reflect.DeepEqual(test.output, output), "Expected {%v}, got {%v}", test.output, output) } } From 0b1aa55cbb14ce3b7c805a6262e2159c4a70bf73 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 20:50:57 +0200 Subject: [PATCH 40/61] chore(pkg): refactor: convert tests to testify assert/require part 22 #### Description refactor: convert tests to testify assert/require in pkg/action Signed-off-by: Matthieu MOREL --- pkg/action/history_test.go | 4 +--- pkg/action/hooks_test.go | 17 ++++++----------- pkg/action/release_testing_test.go | 12 ++++-------- pkg/chart/v2/dependency_test.go | 10 ++++++---- pkg/chart/v2/lint/rules/deprecations_test.go | 11 ++++------- pkg/chart/v2/util/compatible_test.go | 10 ++++++---- pkg/cmd/helpers_test.go | 16 ++++++---------- pkg/cmd/show_test.go | 12 +++++------- pkg/registry/client_http_test.go | 10 ++++------ pkg/registry/registry_test.go | 10 ++++------ 10 files changed, 46 insertions(+), 66 deletions(-) diff --git a/pkg/action/history_test.go b/pkg/action/history_test.go index 31fdd4a96..51212b610 100644 --- a/pkg/action/history_test.go +++ b/pkg/action/history_test.go @@ -50,9 +50,7 @@ func TestHistoryRun(t *testing.T) { client.Max = 3 client.cfg.Releases.MaxHistory = 3 for _, rel := range []*release.Release{simpleRelease, updatedRelease} { - if err := client.cfg.Releases.Create(rel); err != nil { - t.Fatal(err, "Could not add releases to Config") - } + require.NoError(t, client.cfg.Releases.Create(rel), "Could not add releases to Config") } releases, err := config.Releases.ListReleases() diff --git a/pkg/action/hooks_test.go b/pkg/action/hooks_test.go index 20442af13..ad3a4b618 100644 --- a/pkg/action/hooks_test.go +++ b/pkg/action/hooks_test.go @@ -401,16 +401,12 @@ data: serverSideApply := true err := configuration.execHook(&tc.inputRelease, hookEvent, kube.StatusWatcherStrategy, nil, 600, serverSideApply) - if !reflect.DeepEqual(kubeClient.deleteRecord, tc.expectedDeleteRecord) { - t.Fatalf("Got unexpected delete record, expected: %#v, but got: %#v", kubeClient.deleteRecord, tc.expectedDeleteRecord) - } - - if err != nil && !tc.expectError { - t.Fatal("Got an unexpected error.") - } + require.Truef(t, reflect.DeepEqual(kubeClient.deleteRecord, tc.expectedDeleteRecord), "Got unexpected delete record, expected: %#v, but got: %#v", kubeClient.deleteRecord, tc.expectedDeleteRecord) - if err == nil && tc.expectError { - t.Fatal("Expected and error but did not get it.") + if !tc.expectError { + require.NoError(t, err) + } else { + require.Error(t, err) } }) } @@ -490,8 +486,7 @@ data: ctx := context.Background() waitOptions := []kube.WaitOption{kube.WithWaitContext(ctx)} - err := configuration.execHook(rel, release.HookPreInstall, kube.StatusWatcherStrategy, waitOptions, 600, false) - req.NoError(err) + req.NoError(configuration.execHook(rel, release.HookPreInstall, kube.StatusWatcherStrategy, waitOptions, 600, false)) // Verify that WaitOptions were passed to GetWaiter is.NotEmpty(failer.RecordedWaitOptions, "WaitOptions should be passed to GetWaiter") diff --git a/pkg/action/release_testing_test.go b/pkg/action/release_testing_test.go index 48a3251a1..91cb548a5 100644 --- a/pkg/action/release_testing_test.go +++ b/pkg/action/release_testing_test.go @@ -190,8 +190,7 @@ func TestGetContainerLogs_MultipleContainers(t *testing.T) { rt := &ReleaseTesting{Namespace: "default"} var buf bytes.Buffer - err := rt.getContainerLogs(&buf, client, "test-pod") - require.NoError(t, err) + require.NoError(t, rt.getContainerLogs(&buf, client, "test-pod")) output := buf.String() assert.Contains(t, output, "POD LOGS: test-pod (main)") assert.Contains(t, output, "POD LOGS: test-pod (sidecar)") @@ -217,8 +216,7 @@ func TestGetContainerLogs_WithInitContainers(t *testing.T) { rt := &ReleaseTesting{Namespace: "default"} var buf bytes.Buffer - err := rt.getContainerLogs(&buf, client, "test-pod") - require.NoError(t, err) + require.NoError(t, rt.getContainerLogs(&buf, client, "test-pod")) output := buf.String() // Init containers should appear before regular containers assert.Contains(t, output, "POD LOGS: test-pod (init-setup)") @@ -230,8 +228,7 @@ func TestGetContainerLogs_PodNotFound(t *testing.T) { rt := &ReleaseTesting{Namespace: "default"} var buf bytes.Buffer - err := rt.getContainerLogs(&buf, client, "nonexistent-pod") - assert.ErrorContains(t, err, "unable to get pod nonexistent-pod") + assert.ErrorContains(t, rt.getContainerLogs(&buf, client, "nonexistent-pod"), "unable to get pod nonexistent-pod") } func TestGetContainerLogs_OutputHeaderFormat(t *testing.T) { @@ -252,8 +249,7 @@ func TestGetContainerLogs_OutputHeaderFormat(t *testing.T) { rt := &ReleaseTesting{Namespace: "default"} var buf bytes.Buffer - err := rt.getContainerLogs(&buf, client, "multi-test") - require.NoError(t, err) + require.NoError(t, rt.getContainerLogs(&buf, client, "multi-test")) output := buf.String() assert.Contains(t, output, "POD LOGS: multi-test (container-a)") assert.Contains(t, output, "POD LOGS: multi-test (container-b)") diff --git a/pkg/chart/v2/dependency_test.go b/pkg/chart/v2/dependency_test.go index 35919bd7a..f44a6b06f 100644 --- a/pkg/chart/v2/dependency_test.go +++ b/pkg/chart/v2/dependency_test.go @@ -17,6 +17,8 @@ package v2 import ( "testing" + + "github.com/stretchr/testify/require" ) func TestValidateDependency(t *testing.T) { @@ -35,10 +37,10 @@ func TestValidateDependency(t *testing.T) { } { dep.Alias = value res := dep.Validate() - if res != nil && !shouldFail { - t.Errorf("Failed on case %q", dep.Alias) - } else if res == nil && shouldFail { - t.Errorf("Expected failure for %q", dep.Alias) + if shouldFail { + require.Errorf(t, res, "Expected failure for %q", dep.Alias) + } else { + require.NoErrorf(t, res, "Failed on case %q", dep.Alias) } } } diff --git a/pkg/chart/v2/lint/rules/deprecations_test.go b/pkg/chart/v2/lint/rules/deprecations_test.go index 0aa983678..3c8553cce 100644 --- a/pkg/chart/v2/lint/rules/deprecations_test.go +++ b/pkg/chart/v2/lint/rules/deprecations_test.go @@ -19,6 +19,7 @@ package rules import ( "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -28,17 +29,13 @@ func TestValidateNoDeprecations(t *testing.T) { Kind: "Deployment", } err := validateNoDeprecations(deprecated, nil) - if err == nil { - t.Fatal("Expected deprecated extension to be flagged") - } + require.Error(t, err, "Expected deprecated extension to be flagged") var depErr deprecatedAPIError require.ErrorAs(t, err, &depErr) require.NotEmptyf(t, depErr.Message, "Expected error message to be non-blank") - if err := validateNoDeprecations(&k8sYamlStruct{ + assert.NoError(t, validateNoDeprecations(&k8sYamlStruct{ APIVersion: "v1", Kind: "Pod", - }, nil); err != nil { - t.Error("Expected a v1 Pod to not be deprecated") - } + }, nil), "Expected a v1 Pod to not be deprecated") } diff --git a/pkg/chart/v2/util/compatible_test.go b/pkg/chart/v2/util/compatible_test.go index e17d33e35..9a57ef64a 100644 --- a/pkg/chart/v2/util/compatible_test.go +++ b/pkg/chart/v2/util/compatible_test.go @@ -17,7 +17,11 @@ limitations under the License. // Package version represents the current version of the project. package util -import "testing" +import ( + "testing" + + "github.com/stretchr/testify/assert" +) func TestIsCompatibleRange(t *testing.T) { tests := []struct { @@ -36,8 +40,6 @@ func TestIsCompatibleRange(t *testing.T) { } for _, tt := range tests { - if IsCompatibleRange(tt.constraint, tt.ver) != tt.expected { - t.Errorf("expected constraint %s to be %v for %s", tt.constraint, tt.expected, tt.ver) - } + assert.Equal(t, tt.expected, IsCompatibleRange(tt.constraint, tt.ver), "expected constraint %s to be %v for %s", tt.constraint, tt.expected, tt.ver) } } diff --git a/pkg/cmd/helpers_test.go b/pkg/cmd/helpers_test.go index 3db5f38ab..611d1a54c 100644 --- a/pkg/cmd/helpers_test.go +++ b/pkg/cmd/helpers_test.go @@ -56,17 +56,14 @@ func runTestCmd(t *testing.T, tests []cmdTestCase) { storage := storageFixture() for _, rel := range tt.rels { - if err := storage.Create(rel); err != nil { - t.Fatal(err) - } + require.NoError(t, storage.Create(rel)) } t.Logf("running cmd (attempt %d): %s", i+1, tt.cmd) _, out, err := executeActionCommandC(storage, tt.cmd) - if tt.wantError && err == nil { - t.Errorf("expected error, got success with the following output:\n%s", out) - } - if !tt.wantError && err != nil { - t.Errorf("expected no error, got: '%v'", err) + if tt.wantError { + require.Error(t, err, "expected error, got success with the following output:\n%s", out) + } else { + require.NoError(t, err, "expected no error") } if tt.golden != "" { test.AssertGoldenString(t, out, tt.golden) @@ -294,8 +291,7 @@ func TestCmdGetDryRunFlagStrategy(t *testing.T) { if tc.ExpectedLog != nil { logResult := map[string]string{} - err = json.Unmarshal(logBuf.Bytes(), &logResult) - require.NoError(t, err) + require.NoError(t, json.Unmarshal(logBuf.Bytes(), &logResult)) assert.Equal(t, tc.ExpectedLog.Level, logResult["level"]) assert.Equal(t, tc.ExpectedLog.Msg, logResult["msg"]) diff --git a/pkg/cmd/show_test.go b/pkg/cmd/show_test.go index e24b8c442..3ed01d418 100644 --- a/pkg/cmd/show_test.go +++ b/pkg/cmd/show_test.go @@ -19,9 +19,11 @@ package cmd import ( "fmt" "path/filepath" - "strings" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "helm.sh/helm/v4/pkg/repo/v1/repotest" ) @@ -32,9 +34,7 @@ func TestShowPreReleaseChart(t *testing.T) { ) defer srv.Stop() - if err := srv.LinkIndices(); err != nil { - t.Fatal(err) - } + require.NoError(t, srv.LinkIndices()) tests := []struct { name string @@ -79,9 +79,7 @@ func TestShowPreReleaseChart(t *testing.T) { _, _, err := executeActionCommand(cmd) if err != nil { if tt.fail { - if !strings.Contains(err.Error(), tt.expectedErr) { - t.Errorf("%q expected error: %s, got: %s", tt.name, tt.expectedErr, err.Error()) - } + assert.ErrorContains(t, err, tt.expectedErr, "%q expected error: %s, got: %s", tt.name, tt.expectedErr, err.Error()) return } t.Errorf("%q reported error: %s", tt.name, err) diff --git a/pkg/registry/client_http_test.go b/pkg/registry/client_http_test.go index 316a82d3f..0a51b3347 100644 --- a/pkg/registry/client_http_test.go +++ b/pkg/registry/client_http_test.go @@ -39,15 +39,13 @@ func (suite *HTTPRegistryClientTestSuite) TearDownSuite() { } func (suite *HTTPRegistryClientTestSuite) Test_0_Login() { - err := suite.RegistryClient.Login(suite.DockerRegistryHost, + suite.Require().Error(suite.RegistryClient.Login(suite.DockerRegistryHost, LoginOptBasicAuth("badverybad", "ohsobad"), - LoginOptPlainText(true)) - suite.Require().Error(err, "error logging into registry with bad credentials") + LoginOptPlainText(true)), "error logging into registry with bad credentials") - err = suite.RegistryClient.Login(suite.DockerRegistryHost, + suite.Require().NoError(suite.RegistryClient.Login(suite.DockerRegistryHost, LoginOptBasicAuth(testUsername, testPassword), - LoginOptPlainText(true)) - suite.Require().NoError(err, "no error logging into registry with good credentials") + LoginOptPlainText(true)), "no error logging into registry with good credentials") } func (suite *HTTPRegistryClientTestSuite) Test_1_Push() { diff --git a/pkg/registry/registry_test.go b/pkg/registry/registry_test.go index 429b15113..313cb861c 100644 --- a/pkg/registry/registry_test.go +++ b/pkg/registry/registry_test.go @@ -73,10 +73,8 @@ type TestRegistry struct { func setup(suite *TestRegistry, tlsEnabled, insecure bool, auth string) { suite.WorkspaceDir = testWorkspaceDir - err := os.RemoveAll(suite.WorkspaceDir) - suite.Require().NoError(err, "no error removing test workspace dir") - err = os.Mkdir(suite.WorkspaceDir, 0o700) - suite.Require().NoError(err, "no error creating test workspace dir") + suite.Require().NoError(os.RemoveAll(suite.WorkspaceDir), "no error removing test workspace dir") + suite.Require().NoError(os.Mkdir(suite.WorkspaceDir, 0o700), "no error creating test workspace dir") var out bytes.Buffer @@ -92,6 +90,7 @@ func setup(suite *TestRegistry, tlsEnabled, insecure bool, auth string) { ClientOptBasicAuth(testUsername, testPassword), } + var err error if tlsEnabled { var tlsConf *tls.Config if insecure { @@ -122,8 +121,7 @@ func setup(suite *TestRegistry, tlsEnabled, insecure bool, auth string) { pwBytes, err := bcrypt.GenerateFromPassword([]byte(testPassword), bcrypt.DefaultCost) suite.Require().NoError(err, "no error generating bcrypt password for test htpasswd file") htpasswdPath := filepath.Join(suite.WorkspaceDir, testHtpasswdFileBasename) - err = os.WriteFile(htpasswdPath, fmt.Appendf(nil, "%s:%s\n", testUsername, string(pwBytes)), 0o644) - suite.Require().NoError(err, "no error creating test htpasswd file") + suite.Require().NoError(os.WriteFile(htpasswdPath, fmt.Appendf(nil, "%s:%s\n", testUsername, string(pwBytes)), 0o644), "no error creating test htpasswd file") // Registry config config := &configuration.Configuration{} From 33c28395695c53b579c1f94d3dfcadbe2ff2b862 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 20 Jul 2026 20:50:56 +0200 Subject: [PATCH 41/61] chore(pkg): refactor: convert tests to testify assert/require part 19 refactor: convert tests to testify assert/require in pkg/action Signed-off-by: Matthieu MOREL --- pkg/action/lint_test.go | 46 +++++++++------------- pkg/action/show_test.go | 41 ++++++-------------- pkg/action/upgrade_test.go | 40 ++++++++----------- pkg/action/validate_test.go | 37 ++++++------------ pkg/chart/v2/lint/rules/values_test.go | 44 ++++++--------------- pkg/cmd/install_test.go | 6 +-- pkg/cmd/plugin_test.go | 48 +++++++---------------- pkg/getter/getter_test.go | 53 ++++++++++---------------- pkg/storage/driver/records_test.go | 53 ++++++++++---------------- 9 files changed, 125 insertions(+), 243 deletions(-) diff --git a/pkg/action/lint_test.go b/pkg/action/lint_test.go index 5b5c2c50a..5c956c682 100644 --- a/pkg/action/lint_test.go +++ b/pkg/action/lint_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "helm.sh/helm/v4/pkg/chart/v2/lint/support" ) @@ -89,11 +90,10 @@ func TestLintChart(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { _, err := lintChart(tt.chartPath, map[string]any{}, namespace, nil, tt.skipSchemaValidation) - switch { - case err != nil && !tt.err: - t.Errorf("%s", err) - case err == nil && tt.err: - t.Error("Expected a chart parsing error") + if tt.err { + require.Error(t, err, "Expected a chart parsing error") + } else { + require.NoError(t, err) } }) } @@ -106,14 +106,10 @@ func TestNonExistentChart(t *testing.T) { testLint := NewLint() result := testLint.Run(testCharts, values) - if len(result.Errors) != 1 { - t.Error("expected one error, but got", len(result.Errors)) - } + assert.Len(t, result.Errors, 1, "expected one error, but got", len(result.Errors)) actual := result.Errors[0].Error() - if actual != expectedError { - t.Errorf("expected '%s', but got '%s'", expectedError, actual) - } + assert.EqualError(t, result.Errors[0], expectedError, "expected '%s', but got '%s'", expectedError, actual) }) t.Run("should error out for corrupted tgz chart", func(t *testing.T) { @@ -122,31 +118,25 @@ func TestNonExistentChart(t *testing.T) { testLint := NewLint() result := testLint.Run(testCharts, values) - if len(result.Errors) != 1 { - t.Error("expected one error, but got", len(result.Errors)) - } + assert.Len(t, result.Errors, 1, "expected one error, but got", len(result.Errors)) actual := result.Errors[0].Error() - if actual != expectedEOFError { - t.Errorf("expected '%s', but got '%s'", expectedEOFError, actual) - } + assert.EqualError(t, result.Errors[0], expectedEOFError, "expected '%s', but got '%s'", expectedEOFError, actual) }) } func TestLint_MultipleCharts(t *testing.T) { testCharts := []string{chart2MultipleChartLint, chart1MultipleChartLint} testLint := NewLint() - if result := testLint.Run(testCharts, values); len(result.Errors) > 0 { - t.Error(result.Errors) - } + result := testLint.Run(testCharts, values) + assert.Empty(t, result.Errors) } func TestLint_EmptyResultErrors(t *testing.T) { testCharts := []string{chart2MultipleChartLint} testLint := NewLint() - if result := testLint.Run(testCharts, values); len(result.Errors) > 0 { - t.Error("Expected no error, got more") - } + result := testLint.Run(testCharts, values) + assert.Empty(t, result.Errors, "Expected no error, got more") } func TestLint_ChartWithWarnings(t *testing.T) { @@ -154,18 +144,16 @@ func TestLint_ChartWithWarnings(t *testing.T) { testCharts := []string{chartWithNoTemplatesDir} testLint := NewLint() testLint.Strict = false - if result := testLint.Run(testCharts, values); len(result.Errors) > 0 { - t.Error("Expected no error, got more") - } + result := testLint.Run(testCharts, values) + assert.Empty(t, result.Errors, "Expected no error, got more") }) t.Run("should fail with one error when strict", func(t *testing.T) { testCharts := []string{chartWithNoTemplatesDir} testLint := NewLint() testLint.Strict = true - if result := testLint.Run(testCharts, values); len(result.Errors) != 1 { - t.Error("expected one error, but got", len(result.Errors)) - } + result := testLint.Run(testCharts, values) + assert.Len(t, result.Errors, 1, "expected one error") }) } diff --git a/pkg/action/show_test.go b/pkg/action/show_test.go index 0dde7fb74..c6c55ead1 100644 --- a/pkg/action/show_test.go +++ b/pkg/action/show_test.go @@ -21,6 +21,7 @@ import ( "time" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "helm.sh/helm/v4/pkg/chart/common" chart "helm.sh/helm/v4/pkg/chart/v2" @@ -47,9 +48,7 @@ func TestShow(t *testing.T) { } output, err := client.Run("") - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) expect := `name: alpine @@ -69,9 +68,7 @@ bar baz ` - if output != expect { - t.Errorf("Expected\n%q\nGot\n%q\n", expect, output) - } + assert.Equal(t, expect, output, "Expected\n%q\nGot\n%q\n", expect, output) } func TestShowNoValues(t *testing.T) { @@ -82,13 +79,9 @@ func TestShowNoValues(t *testing.T) { // Regression tests for missing values. See issue #1024. client.OutputFormat = ShowValues output, err := client.Run("") - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if output != "" { - t.Errorf("expected empty values buffer, got %s", output) - } + assert.Empty(t, output, "expected empty values buffer, got %s", output) } func TestShowValuesByJsonPathFormat(t *testing.T) { @@ -97,13 +90,9 @@ func TestShowValuesByJsonPathFormat(t *testing.T) { client.JSONPathTemplate = "{$.nestedKey.simpleKey}" client.chart = buildChart(withSampleValues()) output, err := client.Run("") - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) expect := "simpleValue" - if output != expect { - t.Errorf("Expected\n%q\nGot\n%q\n", expect, output) - } + assert.Equal(t, expect, output, "Expected\n%q\nGot\n%q\n", expect, output) } func TestShowCRDs(t *testing.T) { @@ -121,9 +110,7 @@ func TestShowCRDs(t *testing.T) { } output, err := client.Run("") - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) expect := `--- foo @@ -135,9 +122,7 @@ bar baz ` - if output != expect { - t.Errorf("Expected\n%q\nGot\n%q\n", expect, output) - } + assert.Equal(t, expect, output, "Expected\n%q\nGot\n%q\n", expect, output) } func TestShowNoReadme(t *testing.T) { @@ -154,9 +139,7 @@ func TestShowNoReadme(t *testing.T) { } output, err := client.Run("") - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) expect := `name: alpine @@ -167,9 +150,7 @@ foo bar ` - if output != expect { - t.Errorf("Expected\n%q\nGot\n%q\n", expect, output) - } + assert.Equal(t, expect, output, "Expected\n%q\nGot\n%q\n", expect, output) } func TestShowSetRegistryClient(t *testing.T) { diff --git a/pkg/action/upgrade_test.go b/pkg/action/upgrade_test.go index 7a73c7179..b7e25206d 100644 --- a/pkg/action/upgrade_test.go +++ b/pkg/action/upgrade_test.go @@ -176,8 +176,8 @@ func TestUpgradeRelease_RollbackOnFailure(t *testing.T) { resi, err := upAction.Run(rel.Name, buildChart(), vals) req.Error(err) - is.Contains(err.Error(), "arming key removed") - is.Contains(err.Error(), "rollback-on-failure") + req.ErrorContains(err, "arming key removed") + req.ErrorContains(err, "rollback-on-failure") res, err := releaserToV1Release(resi) req.NoError(err) @@ -207,8 +207,8 @@ func TestUpgradeRelease_RollbackOnFailure(t *testing.T) { _, err := upAction.Run(rel.Name, buildChart(), vals) req.Error(err) - is.Contains(err.Error(), "update fail") - is.Contains(err.Error(), "an error occurred while rolling back the release") + req.ErrorContains(err, "update fail") + is.ErrorContains(err, "an error occurred while rolling back the release") }) } @@ -240,8 +240,7 @@ func TestUpgradeRelease_ReuseValues(t *testing.T) { rel.Info.Status = common.StatusDeployed rel.Config = existingValues - err := upAction.cfg.Releases.Create(rel) - req.NoError(err) + req.NoError(upAction.cfg.Releases.Create(rel)) upAction.ReuseValues = true // setting newValues and upgrading @@ -303,8 +302,7 @@ func TestUpgradeRelease_ReuseValues(t *testing.T) { Config: existingValues, Version: 1, } - err := upAction.cfg.Releases.Create(rel) - req.NoError(err) + req.NoError(upAction.cfg.Releases.Create(rel)) upAction.ReuseValues = true sampleChartWithSubChart := buildChart( @@ -373,8 +371,7 @@ func TestUpgradeRelease_ResetThenReuseValues(t *testing.T) { rel.Info.Status = common.StatusDeployed rel.Config = existingValues - err := upAction.cfg.Releases.Create(rel) - req.NoError(err) + req.NoError(upAction.cfg.Releases.Create(rel)) upAction.ResetThenReuseValues = true // setting newValues and upgrading @@ -417,7 +414,7 @@ func TestUpgradeRelease_Pending(t *testing.T) { vals := map[string]any{} _, err := upAction.Run(rel.Name, buildChart(), vals) - req.Contains(err.Error(), "progress", err) + req.ErrorContains(err, "progress") } func TestUpgradeRelease_Interrupted_Wait(t *testing.T) { @@ -470,7 +467,7 @@ func TestUpgradeRelease_Interrupted_RollbackOnFailure(t *testing.T) { resi, err := upAction.RunWithContext(ctx, rel.Name, buildChart(), vals) req.Error(err) - is.Contains(err.Error(), "release interrupted-release failed, and has been rolled back due to rollback-on-failure being set: context canceled") + req.ErrorContains(err, "release interrupted-release failed, and has been rolled back due to rollback-on-failure being set: context canceled") res, err := releaserToV1Release(resi) req.NoError(err) // Now make sure it is actually upgraded @@ -491,9 +488,8 @@ func TestMergeCustomLabels(t *testing.T) { {map[string]string{"k1": "v1", "k2": "v2"}, map[string]string{"k1": "null", "k2": "v3"}, map[string]string{"k2": "v3"}}, } for _, test := range tests { - if output := mergeCustomLabels(test[0], test[1]); !reflect.DeepEqual(test[2], output) { - t.Errorf("Expected {%v}, got {%v}", test[2], output) - } + output := mergeCustomLabels(test[0], test[1]) + assert.Truef(t, reflect.DeepEqual(test[2], output), "Expected {%v}, got {%v}", test[2], output) } } @@ -511,8 +507,7 @@ func TestUpgradeRelease_Labels(t *testing.T) { } rel.Info.Status = common.StatusDeployed - err := upAction.cfg.Releases.Create(rel) - req.NoError(err) + req.NoError(upAction.cfg.Releases.Create(rel)) upAction.Labels = map[string]string{ "key1": "null", @@ -566,8 +561,7 @@ func TestUpgradeRelease_SystemLabels(t *testing.T) { } rel.Info.Status = common.StatusDeployed - err := upAction.cfg.Releases.Create(rel) - req.NoError(err) + req.NoError(upAction.cfg.Releases.Create(rel)) upAction.Labels = map[string]string{ "key1": "null", @@ -575,12 +569,10 @@ func TestUpgradeRelease_SystemLabels(t *testing.T) { "owner": "val3", } // setting newValues and upgrading - _, err = upAction.Run(rel.Name, buildChart(), nil) - if err == nil { - t.Fatal("expected an error") - } + _, err := upAction.Run(rel.Name, buildChart(), nil) + require.Error(t, err, "expected an error") - is.Equal(fmt.Errorf("user supplied labels contains system reserved label name. System labels: %+v", driver.GetSystemLabels()), err) + is.EqualError(err, fmt.Sprintf("user supplied labels contains system reserved label name. System labels: %+v", driver.GetSystemLabels())) } func TestUpgradeRelease_DryRun(t *testing.T) { diff --git a/pkg/action/validate_test.go b/pkg/action/validate_test.go index 878bec599..27097d177 100644 --- a/pkg/action/validate_test.go +++ b/pkg/action/validate_test.go @@ -171,45 +171,38 @@ func TestCheckOwnership(t *testing.T) { deployFoo := newDeploymentResource("foo", "ns-a", "") // Verify that a resource that lacks labels/annotations is not owned - err := checkOwnership(deployFoo.Object, "rel-a", "ns-a") - require.EqualError(t, err, `invalid ownership metadata; label validation error: missing key "app.kubernetes.io/managed-by": must be set to "Helm"; annotation validation error: missing key "meta.helm.sh/release-name": must be set to "rel-a"; annotation validation error: missing key "meta.helm.sh/release-namespace": must be set to "ns-a"`) + require.EqualError(t, checkOwnership(deployFoo.Object, "rel-a", "ns-a"), `invalid ownership metadata; label validation error: missing key "app.kubernetes.io/managed-by": must be set to "Helm"; annotation validation error: missing key "meta.helm.sh/release-name": must be set to "rel-a"; annotation validation error: missing key "meta.helm.sh/release-namespace": must be set to "ns-a"`) // Set managed by label and verify annotation error message _ = accessor.SetLabels(deployFoo.Object, map[string]string{ appManagedByLabel: appManagedByHelm, }) - err = checkOwnership(deployFoo.Object, "rel-a", "ns-a") - require.EqualError(t, err, `invalid ownership metadata; annotation validation error: missing key "meta.helm.sh/release-name": must be set to "rel-a"; annotation validation error: missing key "meta.helm.sh/release-namespace": must be set to "ns-a"`) + require.EqualError(t, checkOwnership(deployFoo.Object, "rel-a", "ns-a"), `invalid ownership metadata; annotation validation error: missing key "meta.helm.sh/release-name": must be set to "rel-a"; annotation validation error: missing key "meta.helm.sh/release-namespace": must be set to "ns-a"`) // Set only the release name annotation and verify missing release namespace error message _ = accessor.SetAnnotations(deployFoo.Object, map[string]string{ helmReleaseNameAnnotation: "rel-a", }) - err = checkOwnership(deployFoo.Object, "rel-a", "ns-a") - require.EqualError(t, err, `invalid ownership metadata; annotation validation error: missing key "meta.helm.sh/release-namespace": must be set to "ns-a"`) + require.EqualError(t, checkOwnership(deployFoo.Object, "rel-a", "ns-a"), `invalid ownership metadata; annotation validation error: missing key "meta.helm.sh/release-namespace": must be set to "ns-a"`) // Set both release name and namespace annotations and verify no ownership errors _ = accessor.SetAnnotations(deployFoo.Object, map[string]string{ helmReleaseNameAnnotation: "rel-a", helmReleaseNamespaceAnnotation: "ns-a", }) - err = checkOwnership(deployFoo.Object, "rel-a", "ns-a") - require.NoError(t, err) + require.NoError(t, checkOwnership(deployFoo.Object, "rel-a", "ns-a")) // Verify ownership error for wrong release name - err = checkOwnership(deployFoo.Object, "rel-b", "ns-a") - require.EqualError(t, err, `invalid ownership metadata; annotation validation error: key "meta.helm.sh/release-name" must equal "rel-b": current value is "rel-a"`) + require.EqualError(t, checkOwnership(deployFoo.Object, "rel-b", "ns-a"), `invalid ownership metadata; annotation validation error: key "meta.helm.sh/release-name" must equal "rel-b": current value is "rel-a"`) // Verify ownership error for wrong release namespace - err = checkOwnership(deployFoo.Object, "rel-a", "ns-b") - require.EqualError(t, err, `invalid ownership metadata; annotation validation error: key "meta.helm.sh/release-namespace" must equal "ns-b": current value is "ns-a"`) + require.EqualError(t, checkOwnership(deployFoo.Object, "rel-a", "ns-b"), `invalid ownership metadata; annotation validation error: key "meta.helm.sh/release-namespace" must equal "ns-b": current value is "ns-a"`) // Verify ownership error for wrong manager label _ = accessor.SetLabels(deployFoo.Object, map[string]string{ appManagedByLabel: "helm", }) - err = checkOwnership(deployFoo.Object, "rel-a", "ns-a") - assert.EqualError(t, err, `invalid ownership metadata; label validation error: key "app.kubernetes.io/managed-by" must equal "Helm": current value is "helm"`) + assert.EqualError(t, checkOwnership(deployFoo.Object, "rel-a", "ns-a"), `invalid ownership metadata; label validation error: key "app.kubernetes.io/managed-by" must equal "Helm": current value is "helm"`) } func TestVerifyOwnershipBeforeDelete(t *testing.T) { @@ -306,32 +299,26 @@ func TestVerifyOwnershipBeforeDelete(t *testing.T) { func TestSetMetadataVisitor(t *testing.T) { var ( - err error deployFoo = newDeploymentResource("foo", "ns-a", "") deployBar = newDeploymentResource("bar", "ns-a-system", "") resources = kube.ResourceList{deployFoo, deployBar} ) // Set release tracking metadata and verify no error - err = resources.Visit(setMetadataVisitor("rel-a", "ns-a", true)) - require.NoError(t, err) + require.NoError(t, resources.Visit(setMetadataVisitor("rel-a", "ns-a", true))) // Verify that release "b" cannot take ownership of "a" - err = resources.Visit(setMetadataVisitor("rel-b", "ns-a", false)) - require.Error(t, err) + require.Error(t, resources.Visit(setMetadataVisitor("rel-b", "ns-a", false))) // Force release "b" to take ownership - err = resources.Visit(setMetadataVisitor("rel-b", "ns-a", true)) - require.NoError(t, err) + require.NoError(t, resources.Visit(setMetadataVisitor("rel-b", "ns-a", true))) // Check that there is now no ownership error when setting metadata without force - err = resources.Visit(setMetadataVisitor("rel-b", "ns-a", false)) - require.NoError(t, err) + require.NoError(t, resources.Visit(setMetadataVisitor("rel-b", "ns-a", false))) // Add a new resource that is missing ownership metadata and verify error resources.Append(newDeploymentResource("baz", "default", "")) - err = resources.Visit(setMetadataVisitor("rel-b", "ns-a", false)) - assert.ErrorContains(t, err, `Deployment "baz" in namespace "" cannot be owned`) + assert.ErrorContains(t, resources.Visit(setMetadataVisitor("rel-b", "ns-a", false)), `Deployment "baz" in namespace "" cannot be owned`) } func TestValidateNameAndGenerateName(t *testing.T) { diff --git a/pkg/chart/v2/lint/rules/values_test.go b/pkg/chart/v2/lint/rules/values_test.go index 470904049..82e8e660e 100644 --- a/pkg/chart/v2/lint/rules/values_test.go +++ b/pkg/chart/v2/lint/rules/values_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "helm.sh/helm/v4/internal/test/ensure" ) @@ -54,11 +55,7 @@ const testSchema = ` func TestValidateValuesYamlNotDirectory(t *testing.T) { _ = os.Mkdir(nonExistingValuesFilePath, os.ModePerm) defer os.Remove(nonExistingValuesFilePath) - - err := validateValuesFileExistence(nonExistingValuesFilePath) - if err == nil { - t.Error("validateValuesFileExistence to return a linter error, got no error") - } + assert.Error(t, validateValuesFileExistence(nonExistingValuesFilePath), "validateValuesFileExistence to return a linter error, got no error") } func TestValidateValuesFileWellFormed(t *testing.T) { @@ -67,9 +64,7 @@ func TestValidateValuesFileWellFormed(t *testing.T) { ` tmpdir := ensure.TempFile(t, "values.yaml", []byte(badYaml)) valfile := filepath.Join(tmpdir, "values.yaml") - if err := validateValuesFile(valfile, map[string]any{}, false); err == nil { - t.Fatal("expected values file to fail parsing") - } + require.Error(t, validateValuesFile(valfile, map[string]any{}, false), "expected values file to fail parsing") } func TestValidateValuesFileSchema(t *testing.T) { @@ -78,9 +73,7 @@ func TestValidateValuesFileSchema(t *testing.T) { createTestingSchema(t, tmpdir) valfile := filepath.Join(tmpdir, "values.yaml") - if err := validateValuesFile(valfile, map[string]any{}, false); err != nil { - t.Fatalf("Failed validation with %s", err) - } + require.NoErrorf(t, validateValuesFile(valfile, map[string]any{}, false), "Failed validation") } func TestValidateValuesFileSchemaFailure(t *testing.T) { @@ -90,9 +83,7 @@ func TestValidateValuesFileSchemaFailure(t *testing.T) { createTestingSchema(t, tmpdir) valfile := filepath.Join(tmpdir, "values.yaml") - - err := validateValuesFile(valfile, map[string]any{}, false) - assert.ErrorContains(t, err, "- at '/username': got number, want string") + assert.ErrorContains(t, validateValuesFile(valfile, map[string]any{}, false), "- at '/username': got number, want string") } func TestValidateValuesFileSchemaFailureButWithSkipSchemaValidation(t *testing.T) { @@ -102,11 +93,7 @@ func TestValidateValuesFileSchemaFailureButWithSkipSchemaValidation(t *testing.T createTestingSchema(t, tmpdir) valfile := filepath.Join(tmpdir, "values.yaml") - - err := validateValuesFile(valfile, map[string]any{}, true) - if err != nil { - t.Fatal("expected values file to pass parsing because of skipSchemaValidation") - } + require.NoError(t, validateValuesFile(valfile, map[string]any{}, true), "expected values file to pass parsing because of skipSchemaValidation") } func TestValidateValuesFileSchemaOverrides(t *testing.T) { @@ -118,9 +105,7 @@ func TestValidateValuesFileSchemaOverrides(t *testing.T) { createTestingSchema(t, tmpdir) valfile := filepath.Join(tmpdir, "values.yaml") - if err := validateValuesFile(valfile, overrides, false); err != nil { - t.Fatalf("Failed validation with %s", err) - } + require.NoErrorf(t, validateValuesFile(valfile, overrides, false), "Failed validation") } func TestValidateValuesFile(t *testing.T) { @@ -157,13 +142,10 @@ func TestValidateValuesFile(t *testing.T) { err := validateValuesFile(valfile, tt.overrides, false) - switch { - case err != nil && tt.errorMessage == "": - t.Errorf("Failed validation with %s", err) - case err == nil && tt.errorMessage != "": - t.Error("expected values file to fail parsing") - case err != nil && tt.errorMessage != "": - assert.ErrorContains(t, err, tt.errorMessage, "Failed with unexpected error") + if tt.errorMessage == "" { + require.NoErrorf(t, err, "Failed validation with") + } else { + assert.ErrorContains(t, err, tt.errorMessage) } }) } @@ -172,8 +154,6 @@ func TestValidateValuesFile(t *testing.T) { func createTestingSchema(t *testing.T, dir string) string { t.Helper() schemafile := filepath.Join(dir, "values.schema.json") - if err := os.WriteFile(schemafile, []byte(testSchema), 0o700); err != nil { - t.Fatalf("Failed to write schema to tmpdir: %s", err) - } + require.NoErrorf(t, os.WriteFile(schemafile, []byte(testSchema), 0o700), "Failed to write schema to tmpdir") return schemafile } diff --git a/pkg/cmd/install_test.go b/pkg/cmd/install_test.go index 8d3435e03..d1e081e5c 100644 --- a/pkg/cmd/install_test.go +++ b/pkg/cmd/install_test.go @@ -23,6 +23,8 @@ import ( "path/filepath" "testing" + "github.com/stretchr/testify/require" + "helm.sh/helm/v4/pkg/repo/v1/repotest" ) @@ -39,9 +41,7 @@ func TestInstall(t *testing.T) { })) defer srv2.Close() - if err := srv.LinkIndices(); err != nil { - t.Fatal(err) - } + require.NoError(t, srv.LinkIndices()) repoFile := filepath.Join(srv.Root(), "repositories.yaml") diff --git a/pkg/cmd/plugin_test.go b/pkg/cmd/plugin_test.go index 5364423a0..6a7980119 100644 --- a/pkg/cmd/plugin_test.go +++ b/pkg/cmd/plugin_test.go @@ -72,14 +72,10 @@ func TestManuallyProcessArgs(t *testing.T) { known, unknown := manuallyProcessArgs(input) for i, k := range known { - if k != expectKnown[i] { - t.Errorf("expected known flag %d to be %q, got %q", i, expectKnown[i], k) - } + assert.Equal(t, expectKnown[i], k, "expected known flag %d to be %q, got %q", i, expectKnown[i], k) } for i, k := range unknown { - if k != expectUnknown[i] { - t.Errorf("expected unknown flag %d to be %q, got %q", i, expectUnknown[i], k) - } + assert.Equal(t, expectUnknown[i], k, "expected unknown flag %d to be %q, got %q", i, expectUnknown[i], k) } } @@ -130,23 +126,17 @@ func TestLoadCLIPlugins(t *testing.T) { pluginCmd := pluginCmds[i] t.Run(fmt.Sprintf("%s-%d", pluginCmd.Name(), i), func(t *testing.T) { out.Reset() - if pluginCmd.Use != tt.use { - t.Errorf("%d: Expected Use=%q, got %q", i, tt.use, pluginCmd.Use) - } - if pluginCmd.Short != tt.short { - t.Errorf("%d: Expected Use=%q, got %q", i, tt.short, pluginCmd.Short) - } - if pluginCmd.Long != tt.long { - t.Errorf("%d: Expected Use=%q, got %q", i, tt.long, pluginCmd.Long) - } + assert.Equal(t, tt.use, pluginCmd.Use, "%d: Expected Use=%q, got %q", i, tt.use, pluginCmd.Use) + assert.Equal(t, tt.short, pluginCmd.Short, "%d: Expected Use=%q, got %q", i, tt.short, pluginCmd.Short) + assert.Equal(t, tt.long, pluginCmd.Long, "%d: Expected Use=%q, got %q", i, tt.long, pluginCmd.Long) // Currently, plugins assume a Linux subsystem. Skip the execution // tests until this is fixed if runtime.GOOS != "windows" { if err := pluginCmd.RunE(pluginCmd, tt.args); err != nil { - if assert.Positive(t, tt.code, "Error running %s: %+v", tt.use, err) { + if assert.Positive(t, tt.code, "Error running %s", tt.use) { var cerr CommandError - require.ErrorAs(t, err, &cerr, "Expected %s to return pluginError: got %v(%T)", tt.use, err, err) + require.ErrorAs(t, err, &cerr, "Expected %s to return pluginError", tt.use) assert.Equalf(t, tt.code, cerr.ExitCode, "Expected %s to return %d: got %d", tt.use, tt.code, cerr.ExitCode) } } @@ -190,31 +180,23 @@ func TestLoadPluginsWithSpace(t *testing.T) { plugins := cmd.Commands() - if len(plugins) != len(tests) { - t.Fatalf("Expected %d plugins, got %d", len(tests), len(plugins)) - } + require.Len(t, plugins, len(tests), "Expected %d plugins, got %d", len(tests), len(plugins)) for i := range plugins { out.Reset() tt := tests[i] pp := plugins[i] - if pp.Use != tt.use { - t.Errorf("%d: Expected Use=%q, got %q", i, tt.use, pp.Use) - } - if pp.Short != tt.short { - t.Errorf("%d: Expected Use=%q, got %q", i, tt.short, pp.Short) - } - if pp.Long != tt.long { - t.Errorf("%d: Expected Use=%q, got %q", i, tt.long, pp.Long) - } + assert.Equal(t, tt.use, pp.Use, "%d: Expected Use=%q, got %q", i, tt.use, pp.Use) + assert.Equal(t, tt.short, pp.Short, "%d: Expected Use=%q, got %q", i, tt.short, pp.Short) + assert.Equal(t, tt.long, pp.Long, "%d: Expected Use=%q, got %q", i, tt.long, pp.Long) // Currently, plugins assume a Linux subsystem. Skip the execution // tests until this is fixed if runtime.GOOS != "windows" { if err := pp.RunE(pp, tt.args); err != nil { - if assert.Positive(t, tt.code, "Error running %s: %+v", tt.use, err) { + if assert.Positive(t, tt.code, "Error running %s", tt.use) { var cerr CommandError - require.ErrorAs(t, err, &cerr, "Expected %s to return pluginError: got %v(%T)", tt.use, err, err) + require.ErrorAs(t, err, &cerr, "Expected %s to return pluginError", tt.use) assert.Equalf(t, tt.code, cerr.ExitCode, "Expected %s to return %d: got %d", tt.use, tt.code, cerr.ExitCode) } } @@ -334,9 +316,7 @@ func TestLoadCLIPlugins_HelmNoPlugins(t *testing.T) { loadCLIPlugins(cmd, out) plugins := cmd.Commands() - if len(plugins) != 0 { - t.Fatalf("Expected 0 plugins, got %d", len(plugins)) - } + require.Empty(t, plugins, "Expected 0 plugins, got %d", len(plugins)) } func TestPluginCmdsCompletion(t *testing.T) { diff --git a/pkg/getter/getter_test.go b/pkg/getter/getter_test.go index 3a09b4d82..67cfc2ef0 100644 --- a/pkg/getter/getter_test.go +++ b/pkg/getter/getter_test.go @@ -19,6 +19,9 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "helm.sh/helm/v4/pkg/cli" ) @@ -30,9 +33,7 @@ func TestProvider(t *testing.T) { func(_ ...Option) (Getter, error) { return nil, nil }, } - if !p.Provides("three") { - t.Error("Expected provider to provide three") - } + assert.True(t, p.Provides("three"), "Expected provider to provide three") } func TestProviders(t *testing.T) { @@ -41,34 +42,25 @@ func TestProviders(t *testing.T) { {[]string{"two", "four"}, func(_ ...Option) (Getter, error) { return nil, nil }}, } - if _, err := ps.ByScheme("one"); err != nil { - t.Error(err) - } - if _, err := ps.ByScheme("four"); err != nil { - t.Error(err) - } + _, err := ps.ByScheme("one") + require.NoError(t, err) + _, err = ps.ByScheme("four") + require.NoError(t, err) - if _, err := ps.ByScheme("five"); err == nil { - t.Error("Did not expect handler for five") - } + _, err = ps.ByScheme("five") + assert.Error(t, err, "Did not expect handler for five") } func TestProvidersWithTimeout(t *testing.T) { want := time.Hour getters := Getters(WithTimeout(want)) getter, err := getters.ByScheme("http") - if err != nil { - t.Error(err) - } + require.NoError(t, err) httpGetter := getter.(*HTTPGetter) client, err := httpGetter.httpClient(httpGetter.opts) - if err != nil { - t.Error(err) - } + require.NoError(t, err) got := client.Timeout - if got != want { - t.Errorf("Expected %q, got %q", want, got) - } + assert.Equal(t, want, got, "Expected %q, got %q", want, got) } func TestAll(t *testing.T) { @@ -76,13 +68,10 @@ func TestAll(t *testing.T) { env.PluginsDirectory = pluginDir all := All(env) - if len(all) != 4 { - t.Errorf("expected 4 providers (default plus three plugins), got %d", len(all)) - } + assert.Len(t, all, 4, "expected 4 providers (default plus three plugins), got %d", len(all)) - if _, err := all.ByScheme("test2"); err != nil { - t.Error(err) - } + _, err := all.ByScheme("test2") + assert.NoError(t, err) } func TestByScheme(t *testing.T) { @@ -90,10 +79,8 @@ func TestByScheme(t *testing.T) { env.PluginsDirectory = pluginDir g := All(env) - if _, err := g.ByScheme("test"); err != nil { - t.Error(err) - } - if _, err := g.ByScheme("https"); err != nil { - t.Error(err) - } + _, err := g.ByScheme("test") + require.NoError(t, err) + _, err = g.ByScheme("https") + assert.NoError(t, err) } diff --git a/pkg/storage/driver/records_test.go b/pkg/storage/driver/records_test.go index cd1064342..067e31e76 100644 --- a/pkg/storage/driver/records_test.go +++ b/pkg/storage/driver/records_test.go @@ -20,6 +20,9 @@ import ( "reflect" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "helm.sh/helm/v4/pkg/release/common" ) @@ -50,10 +53,11 @@ func TestRecordsAdd(t *testing.T) { } for _, tt := range tests { - if err := rs.Add(tt.rec); err != nil { - if !tt.ok { - t.Fatalf("failed: %q: %s\n", tt.desc, err) - } + err := rs.Add(tt.rec) + if !tt.ok { + require.NoError(t, err, "failed: %q:", tt.desc) + } else { + require.Error(t, err) } } } @@ -77,23 +81,18 @@ func TestRecordsRemove(t *testing.T) { startLen := rs.Len() for _, tt := range tests { - if r := rs.Remove(tt.key); r == nil { - if !tt.ok { - t.Fatalf("Failed to %q (key = %s). Expected nil, got %v", - tt.desc, - tt.key, - r, - ) - } + r := rs.Remove(tt.key) + if tt.ok { + require.Nil(t, r, "Failed to %q (key = %s). Expected nil, got %v", tt.desc, tt.key, r) + } else { + require.NotNil(t, r) } } // We expect the total number of records will be less now than there were // when we started. endLen := rs.Len() - if endLen >= startLen { - t.Errorf("expected ending length %d to be less than starting length %d", endLen, startLen) - } + assert.Lessf(t, endLen, startLen, "expected ending length %d to be less than starting length %d", endLen, startLen) } func TestRecordsRemoveAt(t *testing.T) { @@ -102,14 +101,10 @@ func TestRecordsRemoveAt(t *testing.T) { newRecord("rls-a.v2", releaseStub("rls-a", 2, "default", common.StatusDeployed)), }) - if len(rs) != 2 { - t.Fatal("Expected len=2 for mock") - } + require.Len(t, rs, 2, "Expected len=2 for mock") rs.Remove("rls-a.v1") - if len(rs) != 1 { - t.Fatalf("Expected length of rs to be 1, got %d", len(rs)) - } + require.Len(t, rs, 1, "Expected length of rs to be 1, got %d", len(rs)) } func TestRecordsGet(t *testing.T) { @@ -137,9 +132,7 @@ func TestRecordsGet(t *testing.T) { for _, tt := range tests { got := rs.Get(tt.key) - if !reflect.DeepEqual(tt.rec, got) { - t.Fatalf("Expected %v, got %v", tt.rec, got) - } + require.Truef(t, reflect.DeepEqual(tt.rec, got), "Expected %v, got %v", tt.rec, got) } } @@ -168,9 +161,7 @@ func TestRecordsIndex(t *testing.T) { for _, tt := range tests { got, _ := rs.Index(tt.key) - if got != tt.sort { - t.Fatalf("Expected %d, got %d", tt.sort, got) - } + require.Equal(t, tt.sort, got, "Expected %d, got %d", tt.sort, got) } } @@ -199,9 +190,7 @@ func TestRecordsExists(t *testing.T) { for _, tt := range tests { got := rs.Exists(tt.key) - if got != tt.ok { - t.Fatalf("Expected %t, got %t", tt.ok, got) - } + require.Equal(t, tt.ok, got, "Expected %t, got %t", tt.ok, got) } } @@ -233,8 +222,6 @@ func TestRecordsReplace(t *testing.T) { for _, tt := range tests { got := rs.Replace(tt.key, tt.rec) - if !reflect.DeepEqual(tt.expected, got) { - t.Fatalf("Expected %v, got %v", tt.expected, got) - } + require.Truef(t, reflect.DeepEqual(tt.expected, got), "Expected %v, got %v", tt.expected, got) } } From cd4c5d3bfd7d19be9a3a01ba63a650cf044e1409 Mon Sep 17 00:00:00 2001 From: Terry Howe Date: Tue, 21 Jul 2026 14:38:44 -0600 Subject: [PATCH 42/61] chore: group github-actions dependabot updates Signed-off-by: Terry Howe --- .github/dependabot.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index d8e8e3379..1b1de9e55 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -37,9 +37,17 @@ updates: directory: "/" schedule: interval: "daily" + groups: + github-actions: + patterns: + - "*" - # Keep dev-v3 GitHub Actions up to date, while Helm v3 is within support package-ecosystem: "github-actions" target-branch: "dev-v3" directory: "/" schedule: interval: "daily" + groups: + github-actions: + patterns: + - "*" From 065d3a6a3dcda016a9de88a9b32f0e9eedcf0876 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Jul 2026 21:33:05 +0000 Subject: [PATCH 43/61] chore(deps): bump github/codeql-action/analyze from 4.37.1 to 4.37.2 Bumps [github/codeql-action/analyze](https://github.com/github/codeql-action) from 4.37.1 to 4.37.2. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/7188fc363630916deb702c7fdcf4e481b751f97a...e0647621c2984b5ed2f768cb892365bf2a616ad1) --- updated-dependencies: - dependency-name: github/codeql-action/analyze dependency-version: 4.37.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index d02d55b82..53a76f6f6 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -73,4 +73,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7188fc363630916deb702c7fdcf4e481b751f97a # pinv4.37.1 + uses: github/codeql-action/analyze@e0647621c2984b5ed2f768cb892365bf2a616ad1 # pinv4.37.2 From cdccef4818c06e4d1ee9521cfb9bcadc30c282e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Jul 2026 21:33:15 +0000 Subject: [PATCH 44/61] chore(deps): bump github/codeql-action/init from 4.37.1 to 4.37.2 Bumps [github/codeql-action/init](https://github.com/github/codeql-action) from 4.37.1 to 4.37.2. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/7188fc363630916deb702c7fdcf4e481b751f97a...e0647621c2984b5ed2f768cb892365bf2a616ad1) --- updated-dependencies: - dependency-name: github/codeql-action/init dependency-version: 4.37.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index d02d55b82..1e7748d44 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -48,7 +48,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@7188fc363630916deb702c7fdcf4e481b751f97a # pinv4.37.1 + uses: github/codeql-action/init@e0647621c2984b5ed2f768cb892365bf2a616ad1 # pinv4.37.2 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. From a0f954e277702f87883d18760207b34ba3efbf80 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Jul 2026 21:33:23 +0000 Subject: [PATCH 45/61] chore(deps): bump github/codeql-action/autobuild from 4.37.1 to 4.37.2 Bumps [github/codeql-action/autobuild](https://github.com/github/codeql-action) from 4.37.1 to 4.37.2. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/7188fc363630916deb702c7fdcf4e481b751f97a...e0647621c2984b5ed2f768cb892365bf2a616ad1) --- updated-dependencies: - dependency-name: github/codeql-action/autobuild dependency-version: 4.37.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index d02d55b82..d28011b0a 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -59,7 +59,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@7188fc363630916deb702c7fdcf4e481b751f97a # pinv4.37.1 + uses: github/codeql-action/autobuild@e0647621c2984b5ed2f768cb892365bf2a616ad1 # pinv4.37.2 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl From 5223ceacda672bdd72efe8995d4abd9327c6539c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Jul 2026 16:08:04 -0600 Subject: [PATCH 46/61] chore(deps): bump github/codeql-action/upload-sarif (#32440) Bumps [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) from 4.37.1 to 4.37.2. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/7188fc363630916deb702c7fdcf4e481b751f97a...e0647621c2984b5ed2f768cb892365bf2a616ad1) --- updated-dependencies: - dependency-name: github/codeql-action/upload-sarif dependency-version: 4.37.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecards.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 41f97dd45..879ff1325 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -64,6 +64,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@7188fc363630916deb702c7fdcf4e481b751f97a # v4.37.1 + uses: github/codeql-action/upload-sarif@e0647621c2984b5ed2f768cb892365bf2a616ad1 # v4.37.2 with: sarif_file: results.sarif From ed246e29f7940fffa4631aa67cfef66c5722d4a7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Jul 2026 16:08:39 -0600 Subject: [PATCH 47/61] chore(deps): bump actions/labeler from 6.2.0 to 7.0.0 (#32441) Bumps [actions/labeler](https://github.com/actions/labeler) from 6.2.0 to 7.0.0. - [Release notes](https://github.com/actions/labeler/releases) - [Commits](https://github.com/actions/labeler/compare/b8dd2d9be0f68b860e7dae5dae7d772984eacd6d...bf12e9b00b37c5c0ca2b87b79b2daf7891dbda13) --- updated-dependencies: - dependency-name: actions/labeler dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/label-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/label-pr.yml b/.github/workflows/label-pr.yml index 5c2b2fa17..11f0f5d00 100644 --- a/.github/workflows/label-pr.yml +++ b/.github/workflows/label-pr.yml @@ -11,6 +11,6 @@ jobs: pull-requests: write runs-on: ubuntu-latest steps: - - uses: actions/labeler@b8dd2d9be0f68b860e7dae5dae7d772984eacd6d # pin@v6.2.0 + - uses: actions/labeler@bf12e9b00b37c5c0ca2b87b79b2daf7891dbda13 # pin@v7.0.0 with: sync-labels: true From fe3f98b5641fe3a0a9fa2575df8698136c2a0029 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Jul 2026 09:11:20 +0000 Subject: [PATCH 48/61] chore(deps): bump google.golang.org/grpc from 1.80.0 to 1.82.1 Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.80.0 to 1.82.1. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.80.0...v1.82.1) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-version: 1.82.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 016b0fded..dffe65d46 100644 --- a/go.mod +++ b/go.mod @@ -165,9 +165,9 @@ require ( golang.org/x/sys v0.47.0 // indirect golang.org/x/time v0.15.0 // indirect golang.org/x/tools v0.47.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 // indirect - google.golang.org/grpc v1.80.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect + google.golang.org/grpc v1.82.1 // indirect google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect diff --git a/go.sum b/go.sum index d097bc72c..ded47f4be 100644 --- a/go.sum +++ b/go.sum @@ -465,12 +465,12 @@ golang.org/x/tools v0.47.0/go.mod h1:dFHnyTvFWY212G+h7ZY4Vsp/K3U4/7W9TyVaAul8uCA golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= -google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 h1:VPWxll4HlMw1Vs/qXtN7BvhZqsS9cdAittCNvVENElA= -google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:7QBABkRtR8z+TEnmXTqIqwJLlzrZKVfAUm7tY3yGv0M= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 h1:m8qni9SQFH0tJc1X0vmnpw/0t+AImlSvp30sEupozUg= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= -google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= +google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 h1:yQugLulqltosq0B/f8l4w9VryjV+N/5gcW0jQ3N8Qec= +google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478/go.mod h1:C6ADNqOxbgdUUeRTU+LCHDPB9ttAMCTff6auwCVa4uc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= +google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI= google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= From ea7c838e0875449a4b2fe141a961aa29f1435a5d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Jul 2026 19:09:19 +0000 Subject: [PATCH 49/61] chore(deps): bump the github-actions group with 4 updates Bumps the github-actions group with 4 updates: [github/codeql-action/init](https://github.com/github/codeql-action), [github/codeql-action/autobuild](https://github.com/github/codeql-action), [github/codeql-action/analyze](https://github.com/github/codeql-action) and [github/codeql-action/upload-sarif](https://github.com/github/codeql-action). Updates `github/codeql-action/init` from 4.37.2 to 4.37.3 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/e0647621c2984b5ed2f768cb892365bf2a616ad1...e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81) Updates `github/codeql-action/autobuild` from 4.37.2 to 4.37.3 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/e0647621c2984b5ed2f768cb892365bf2a616ad1...e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81) Updates `github/codeql-action/analyze` from 4.37.2 to 4.37.3 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/e0647621c2984b5ed2f768cb892365bf2a616ad1...e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81) Updates `github/codeql-action/upload-sarif` from 4.37.2 to 4.37.3 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/e0647621c2984b5ed2f768cb892365bf2a616ad1...e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81) --- updated-dependencies: - dependency-name: github/codeql-action/init dependency-version: 4.37.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions - dependency-name: github/codeql-action/autobuild dependency-version: 4.37.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions - dependency-name: github/codeql-action/analyze dependency-version: 4.37.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions - dependency-name: github/codeql-action/upload-sarif dependency-version: 4.37.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yml | 6 +++--- .github/workflows/scorecards.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index b85756718..d8c1a9d12 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -48,7 +48,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@e0647621c2984b5ed2f768cb892365bf2a616ad1 # pinv4.37.2 + uses: github/codeql-action/init@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # pinv4.37.3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -59,7 +59,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@e0647621c2984b5ed2f768cb892365bf2a616ad1 # pinv4.37.2 + uses: github/codeql-action/autobuild@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # pinv4.37.3 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -73,4 +73,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e0647621c2984b5ed2f768cb892365bf2a616ad1 # pinv4.37.2 + uses: github/codeql-action/analyze@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # pinv4.37.3 diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 879ff1325..d8f878f10 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -64,6 +64,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@e0647621c2984b5ed2f768cb892365bf2a616ad1 # v4.37.2 + uses: github/codeql-action/upload-sarif@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4.37.3 with: sarif_file: results.sarif From 050d3e99b9dc8796ced4b99cb272cba91c43055f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Jul 2026 04:32:02 -0600 Subject: [PATCH 50/61] chore(deps): bump ossf/scorecard-action in the github-actions group (#32458) Bumps the github-actions group with 1 update: [ossf/scorecard-action](https://github.com/ossf/scorecard-action). Updates `ossf/scorecard-action` from 2.4.3 to 2.4.4 - [Release notes](https://github.com/ossf/scorecard-action/releases) - [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md) - [Commits](https://github.com/ossf/scorecard-action/compare/4eaacf0543bb3f2c246792bd56e8cdeffafb205a...2d1146689b8cda280b9bc96326124645441f03bc) --- updated-dependencies: - dependency-name: ossf/scorecard-action dependency-version: 2.4.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecards.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index d8f878f10..6c142b511 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -33,7 +33,7 @@ jobs: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 + uses: ossf/scorecard-action@2d1146689b8cda280b9bc96326124645441f03bc # v2.4.4 with: results_file: results.sarif results_format: sarif From 8f74dce6ba8d7264ce75f52507616720865e712d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Jul 2026 04:40:32 -0600 Subject: [PATCH 51/61] chore(deps): bump the k8s-io group across 1 directory with 7 updates (#32459) Bumps the k8s-io group with 4 updates in the / directory: [k8s.io/api](https://github.com/kubernetes/api), [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver), [k8s.io/cli-runtime](https://github.com/kubernetes/cli-runtime) and [k8s.io/kubectl](https://github.com/kubernetes/kubectl). Updates `k8s.io/api` from 0.36.2 to 0.36.3 - [Commits](https://github.com/kubernetes/api/compare/v0.36.2...v0.36.3) Updates `k8s.io/apiextensions-apiserver` from 0.36.2 to 0.36.3 - [Release notes](https://github.com/kubernetes/apiextensions-apiserver/releases) - [Commits](https://github.com/kubernetes/apiextensions-apiserver/compare/v0.36.2...v0.36.3) Updates `k8s.io/apimachinery` from 0.36.2 to 0.36.3 - [Commits](https://github.com/kubernetes/apimachinery/compare/v0.36.2...v0.36.3) Updates `k8s.io/apiserver` from 0.36.2 to 0.36.3 - [Commits](https://github.com/kubernetes/apiserver/compare/v0.36.2...v0.36.3) Updates `k8s.io/cli-runtime` from 0.36.2 to 0.36.3 - [Commits](https://github.com/kubernetes/cli-runtime/compare/v0.36.2...v0.36.3) Updates `k8s.io/client-go` from 0.36.2 to 0.36.3 - [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md) - [Commits](https://github.com/kubernetes/client-go/compare/v0.36.2...v0.36.3) Updates `k8s.io/kubectl` from 0.36.2 to 0.36.3 - [Commits](https://github.com/kubernetes/kubectl/compare/v0.36.2...v0.36.3) --- updated-dependencies: - dependency-name: k8s.io/api dependency-version: 0.36.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: k8s-io - dependency-name: k8s.io/apiextensions-apiserver dependency-version: 0.36.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: k8s-io - dependency-name: k8s.io/apimachinery dependency-version: 0.36.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: k8s-io - dependency-name: k8s.io/apiserver dependency-version: 0.36.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: k8s-io - dependency-name: k8s.io/cli-runtime dependency-version: 0.36.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: k8s-io - dependency-name: k8s.io/client-go dependency-version: 0.36.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: k8s-io - dependency-name: k8s.io/kubectl dependency-version: 0.36.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: k8s-io ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 18 +++++++++--------- go.sum | 36 ++++++++++++++++++------------------ 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/go.mod b/go.mod index dffe65d46..6b9878bb2 100644 --- a/go.mod +++ b/go.mod @@ -39,14 +39,14 @@ require ( golang.org/x/term v0.45.0 golang.org/x/text v0.40.0 gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.36.2 - k8s.io/apiextensions-apiserver v0.36.2 - k8s.io/apimachinery v0.36.2 - k8s.io/apiserver v0.36.2 - k8s.io/cli-runtime v0.36.2 - k8s.io/client-go v0.36.2 + k8s.io/api v0.36.3 + k8s.io/apiextensions-apiserver v0.36.3 + k8s.io/apimachinery v0.36.3 + k8s.io/apiserver v0.36.3 + k8s.io/cli-runtime v0.36.3 + k8s.io/client-go v0.36.3 k8s.io/klog/v2 v2.140.0 - k8s.io/kubectl v0.36.2 + k8s.io/kubectl v0.36.3 oras.land/oras-go/v2 v2.6.2 sigs.k8s.io/controller-runtime v0.24.1 sigs.k8s.io/kustomize/kyaml v0.21.1 @@ -172,11 +172,11 @@ require ( gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - k8s.io/component-base v0.36.2 // indirect + k8s.io/component-base v0.36.3 // indirect k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a // indirect k8s.io/utils v0.0.0-20260507154919-ff6756f316d2 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/kustomize/api v0.21.1 // indirect sigs.k8s.io/randfill v1.0.0 // indirect - sigs.k8s.io/structured-merge-diff/v6 v6.3.2 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.3.3 // indirect ) diff --git a/go.sum b/go.sum index ded47f4be..e5933d99a 100644 --- a/go.sum +++ b/go.sum @@ -487,26 +487,26 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.36.2 h1:TF6YDLIzKfccK7cq9YpTcGX8TJmEkHVRv78DM51fRYY= -k8s.io/api v0.36.2/go.mod h1:F4LbMO4brjZYh7yFkXWhynSvtB7YauxV4c+HHkNRGNg= -k8s.io/apiextensions-apiserver v0.36.2 h1:3O5gqOj/dt2XWWbpMe+TXWpE9yU6pjM/tXxtHHJT/K4= -k8s.io/apiextensions-apiserver v0.36.2/go.mod h1:cL1tBWe8XSaP1H30iWKGo7hf6iAUUUJPEU70dskmAnA= -k8s.io/apimachinery v0.36.2 h1:0PE/W/WNy1UX61NLbXY5TMbJ6UwLL6E6lAPkYrKFxbQ= -k8s.io/apimachinery v0.36.2/go.mod h1:fvf/HOLXq9RId0rnDIbN1OEBvHXdQbLMM8nu0LcBUf4= -k8s.io/apiserver v0.36.2 h1:6vMnkmHZPeBloNkHUhmZYq7Ylv8WIB8xjyEl+eSt26E= -k8s.io/apiserver v0.36.2/go.mod h1:9PoQ2ikCytrZyZg11mGhLEF5m8Rgsb5FJmYJ4Wvnl1k= -k8s.io/cli-runtime v0.36.2 h1:CconTvEeV4DJs4ZX3HQKCFbFRGsm6OtuBM9yjmMP2VM= -k8s.io/cli-runtime v0.36.2/go.mod h1:LddcjiMf4YlnHO7c1Y7rEtDqL84FyiYVLco7V679GUU= -k8s.io/client-go v0.36.2 h1:bfgxmFKc9CgqsgX4xKLAAdmTQlWee7Ob/HlDOrJ5TBI= -k8s.io/client-go v0.36.2/go.mod h1:1vgO4OAlfPnoLcb+Rze2GF5rAr14w8qjrYMoyXJzQj0= -k8s.io/component-base v0.36.2 h1:Z0VH80O7Ng0HDZnZj3WRR3urEGa0kTwmO8CwEwjVK1w= -k8s.io/component-base v0.36.2/go.mod h1:mGfFOA7Gwpdm1VW2cwSQYbiDIlz8GD2WGwH88QSeCyA= +k8s.io/api v0.36.3 h1:NxB+05W2UGqXWFXcLO0RB5cnqnUPP5v5sVlaOH0Iz4w= +k8s.io/api v0.36.3/go.mod h1:JzLQKqRHC5+I8RVj/lS3lCg0mg6nWI9Fo/Sk3ElxHzg= +k8s.io/apiextensions-apiserver v0.36.3 h1:dPmOAPhwTtqb1bTxbFPsy18KHPhktQeO3WUPXunZIB0= +k8s.io/apiextensions-apiserver v0.36.3/go.mod h1:KTXFqgXiuw2pRoL+Wpmttqc+up9Xt/GohadPWeLLOa4= +k8s.io/apimachinery v0.36.3 h1:PkzMRBRG8joFD8EhCuQAtNPvJlxb82FwplP26HIzvAM= +k8s.io/apimachinery v0.36.3/go.mod h1:cTSjBWgPe/6CQyBKzY/hDIRWCQQQeK0mfLbml0UYFHE= +k8s.io/apiserver v0.36.3 h1:MGSg2SkdfuytiDEcRylT5mQFmmSsbx90XFUO67Y4bsQ= +k8s.io/apiserver v0.36.3/go.mod h1:fVH7zv9EUNUA7Fl7LtDKh8aB9W7u1VQPSGtWV5SjUxg= +k8s.io/cli-runtime v0.36.3 h1:g+eJ+M1sYpnNYp/q5fzaw2KejIL0Q7DH+xFl6YVoL4U= +k8s.io/cli-runtime v0.36.3/go.mod h1:hZpAqK8nSFXvvLaVCbzUPVp8e9TRLSTCfpNzMt7s3tE= +k8s.io/client-go v0.36.3 h1:M4JdVzXxYcZk4fGpfDdYnxSwhLKWCFoQsHW6t+z8Hfg= +k8s.io/client-go v0.36.3/go.mod h1:gcPwr0c87vjjG6HB6pWEqOeuYVoXSsREjzux2j6GF30= +k8s.io/component-base v0.36.3 h1:vc/UFvPCkW0irPz84LAodAL1j3f4xktPM6dDJIEheAY= +k8s.io/component-base v0.36.3/go.mod h1:hZbNFG+gCMl9EbykDGEu73feKP9/Cq6JsV4pTo9GTO8= k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc= k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0= k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a h1:xCeOEAOoGYl2jnJoHkC3hkbPJgdATINPMAxaynU2Ovg= k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a/go.mod h1:uGBT7iTA6c6MvqUvSXIaYZo9ukscABYi2btjhvgKGZ0= -k8s.io/kubectl v0.36.2 h1:rpUGGpeL09XVOLep2yle5jrtk//JA1L6ZHfkQQtVEwk= -k8s.io/kubectl v0.36.2/go.mod h1:gVbQ3B/yb4bSR2ggQ7rd0W6icUSWs7sduH4e16Vii+0= +k8s.io/kubectl v0.36.3 h1:TesKp+XYQEjPYoFvuobcVnuvira2+/xAVlq//+kksaI= +k8s.io/kubectl v0.36.3/go.mod h1:W+NEb1CzBGmoaI1Nrpn2ETo9omNBl0AsyxnnMT40N6E= k8s.io/utils v0.0.0-20260507154919-ff6756f316d2 h1:wU4tMEhLGgIbLvXQb1cfN+EcM0wf7zC6CPF+C79jroc= k8s.io/utils v0.0.0-20260507154919-ff6756f316d2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= oras.land/oras-go/v2 v2.6.2 h1:N04RXngAp1LJKTG6ifz3xHPipasEkWr+hFmInja5YKo= @@ -521,7 +521,7 @@ sigs.k8s.io/kustomize/kyaml v0.21.1 h1:IVlbmhC076nf6foyL6Taw4BkrLuEsXUXNpsE+ScX7 sigs.k8s.io/kustomize/kyaml v0.21.1/go.mod h1:hmxADesM3yUN2vbA5z1/YTBnzLJ1dajdqpQonwBL1FQ= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/structured-merge-diff/v6 v6.3.2 h1:kwVWMx5yS1CrnFWA/2QHyRVJ8jM6dBA80uLmm0wJkk8= -sigs.k8s.io/structured-merge-diff/v6 v6.3.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/structured-merge-diff/v6 v6.3.3 h1:u08YRbVUi59ri4YD6cg0UqNM4Dimn0sIl+wldcx5PYw= +sigs.k8s.io/structured-merge-diff/v6 v6.3.3/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= From 5142ca8ddca79a19c8529508c77ab4b27cb23a8f Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Fri, 24 Jul 2026 13:24:06 +0200 Subject: [PATCH 52/61] chore(internal): refactor: finer tests conversions to testify part 1 #### Description refactor: finer tests conversions to testify in internal/chart/v3/util Signed-off-by: Matthieu MOREL --- internal/chart/v3/lint/lint_test.go | 15 +++--- internal/chart/v3/lint/rules/crds_test.go | 3 +- internal/chart/v3/lint/rules/template_test.go | 11 ++-- .../chart/v3/lint/support/message_test.go | 6 +-- internal/chart/v3/loader/load_test.go | 31 ++++------- internal/chart/v3/util/chartfile_test.go | 19 +------ internal/chart/v3/util/expand_test.go | 4 +- internal/chart/v3/util/save_test.go | 5 +- .../plugin/installer/http_installer_test.go | 26 +++++----- internal/plugin/installer/installer_test.go | 2 - .../plugin/installer/vcs_installer_test.go | 25 ++++----- internal/plugin/subprocess_commands_test.go | 15 +++--- .../release/v2/util/manifest_sorter_test.go | 1 - internal/resolver/resolver_test.go | 52 ++++++++----------- 14 files changed, 84 insertions(+), 131 deletions(-) diff --git a/internal/chart/v3/lint/lint_test.go b/internal/chart/v3/lint/lint_test.go index 8916c6e22..b0a7ce651 100644 --- a/internal/chart/v3/lint/lint_test.go +++ b/internal/chart/v3/lint/lint_test.go @@ -114,7 +114,7 @@ func TestBadValuesV3(t *testing.T) { func TestBadCrdFileV3(t *testing.T) { var values map[string]any m := RunAll(badCrdFileDir, values, namespace).Messages - assert.Lenf(t, m, 2, "All didn't fail with expected errors, got %#v", m) + require.Lenf(t, m, 2, "All didn't fail with expected errors, got %#v", m) require.ErrorContains(t, m[0].Err, "apiVersion is not in 'apiextensions.k8s.io'") assert.ErrorContains(t, m[1].Err, "object kind is not 'CustomResourceDefinition'") } @@ -122,8 +122,7 @@ func TestBadCrdFileV3(t *testing.T) { func TestGoodChart(t *testing.T) { var values map[string]any m := RunAll(goodChartDir, values, namespace).Messages - if len(m) != 0 { - t.Error("All returned linter messages when it shouldn't have") + if !assert.Empty(t, m, "All returned linter messages when it shouldn't have") { for i, msg := range m { t.Logf("Message %d: %s", i, msg) } @@ -143,13 +142,12 @@ func TestHelmCreateChart(t *testing.T) { // Note: we test with strict=true here, even though others have // strict = false. m := RunAll(createdChart, values, namespace, WithSkipSchemaValidation(true)).Messages - if ll := len(m); ll != 1 { - t.Errorf("All should have had exactly 1 error. Got %d", ll) + if !assert.Len(t, m, 1, "All should have had exactly 1 error") { for i, msg := range m { t.Logf("Message %d: %s", i, msg.Error()) } - } else if msg := m[0].Err.Error(); !strings.Contains(msg, "icon is recommended") { - t.Errorf("Unexpected lint error: %s", msg) + } else { + assert.ErrorContains(t, m[0].Err, "icon is recommended") } } @@ -192,8 +190,7 @@ func TestHelmCreateChart_CheckDeprecatedWarnings(t *testing.T) { func TestSubChartValuesChart(t *testing.T) { var values map[string]any m := RunAll(subChartValuesDir, values, namespace).Messages - if len(m) != 0 { - t.Error("All returned linter messages when it shouldn't have") + if !assert.Empty(t, m, "All returned linter messages when it shouldn't have") { for i, msg := range m { t.Logf("Message %d: %s", i, msg) } diff --git a/internal/chart/v3/lint/rules/crds_test.go b/internal/chart/v3/lint/rules/crds_test.go index 60cb1b5ba..9009c1801 100644 --- a/internal/chart/v3/lint/rules/crds_test.go +++ b/internal/chart/v3/lint/rules/crds_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "helm.sh/helm/v4/internal/chart/v3/lint/support" ) @@ -33,7 +34,7 @@ func TestInvalidCrdsDir(t *testing.T) { Crds(&linter) res := linter.Messages - assert.Len(t, res, 1) + require.Len(t, res, 1) assert.ErrorContains(t, res[0].Err, "not a directory") } diff --git a/internal/chart/v3/lint/rules/template_test.go b/internal/chart/v3/lint/rules/template_test.go index b4fa2d311..3271a5bbe 100644 --- a/internal/chart/v3/lint/rules/template_test.go +++ b/internal/chart/v3/lint/rules/template_test.go @@ -199,12 +199,12 @@ func TestDeprecatedAPIFails(t *testing.T) { linter := support.Linter{ChartDir: filepath.Join(tmpdir, mychart.Name())} Templates(&linter, values, namespace, strict) - if l := len(linter.Messages); l != 1 { + if !assert.Len(t, linter.Messages, 1) { for i, msg := range linter.Messages { t.Logf("Message %d: %s", i, msg) } - t.Fatalf("Expected 1 lint error, got %d", l) } + require.Len(t, linter.Messages, 1, "Expected 1 lint error") var err deprecatedAPIError require.ErrorAs(t, linter.Messages[0].Err, &err, "Expected error to be of type deprecatedAPIError") @@ -252,8 +252,7 @@ func TestStrictTemplateParsingMapError(t *testing.T) { ChartDir: filepath.Join(dir, ch.Metadata.Name), } Templates(linter, ch.Values, namespace, strict) - if len(linter.Messages) != 0 { - t.Errorf("expected zero messages, got %d", len(linter.Messages)) + if !assert.Empty(t, linter.Messages, "expected zero messages") { for i, msg := range linter.Messages { t.Logf("Message %d: %q", i, msg) } @@ -376,12 +375,12 @@ func TestEmptyWithCommentsManifests(t *testing.T) { linter := support.Linter{ChartDir: filepath.Join(tmpdir, mychart.Name())} Templates(&linter, values, namespace, strict) - if l := len(linter.Messages); l > 0 { + if !assert.Empty(t, linter.Messages) { for i, msg := range linter.Messages { t.Logf("Message %d: %s", i, msg) } - t.Fatalf("Expected 0 lint errors, got %d", l) } + require.Empty(t, linter.Messages, "Expected 0 lint errors") } func TestValidateListAnnotations(t *testing.T) { md := &k8sYamlStruct{ diff --git a/internal/chart/v3/lint/support/message_test.go b/internal/chart/v3/lint/support/message_test.go index 4c3ed3a3f..d07cf9ed4 100644 --- a/internal/chart/v3/lint/support/message_test.go +++ b/internal/chart/v3/lint/support/message_test.go @@ -58,11 +58,11 @@ func TestRunLinterRule(t *testing.T) { func TestMessage(t *testing.T) { m := Message{ErrorSev, "Chart.yaml", errors.New("Foo")} - require.EqualErrorf(t, m, "[ERROR] Chart.yaml: Foo", "Unexpected output: %s", m.Error()) + require.EqualError(t, m, "[ERROR] Chart.yaml: Foo") m = Message{WarningSev, "templates/", errors.New("Bar")} - require.EqualErrorf(t, m, "[WARNING] templates/: Bar", "Unexpected output: %s", m.Error()) + require.EqualError(t, m, "[WARNING] templates/: Bar") m = Message{InfoSev, "templates/rc.yaml", errors.New("FooBar")} - assert.EqualErrorf(t, m, "[INFO] templates/rc.yaml: FooBar", "Unexpected output: %s", m.Error()) + assert.EqualError(t, m, "[INFO] templates/rc.yaml: FooBar") } diff --git a/internal/chart/v3/loader/load_test.go b/internal/chart/v3/loader/load_test.go index 9378bcdf5..dd5fdc8db 100644 --- a/internal/chart/v3/loader/load_test.go +++ b/internal/chart/v3/loader/load_test.go @@ -25,7 +25,6 @@ import ( "log" "os" "path/filepath" - "reflect" "runtime" "strings" "testing" @@ -201,11 +200,9 @@ icon: https://example.com/64x64.png require.NoError(t, err, "Expected good files to be loaded") assert.Equal(t, "frobnitz", c.Name(), "Expected chart name to be 'frobnitz', got %s", c.Name()) assert.Equal(t, "some values", c.Values["var"], "Expected chart values to be populated with default values") - assert.Len(t, c.Raw, 5, "Expected %d files, got %d", 5, len(c.Raw)) - + assert.Len(t, c.Raw, 5, "Expected 5 files") assert.True(t, bytes.Equal(c.Schema, []byte("type: Values")), "Expected chart schema to be populated with default values") - - assert.Len(t, c.Templates, 2, "Expected number of templates == 2, got %d", len(c.Templates)) + assert.Len(t, c.Templates, 2, "Expected 2 templates") _, err = LoadFiles([]*archive.BufferedFile{}) require.Error(t, err, "Expected err to be non-nil") @@ -417,7 +414,7 @@ foo: t.Run(testName, func(tt *testing.T) { values, err := LoadValues(bytes.NewReader(testCase.data)) require.NoError(tt, err) - assert.Truef(tt, reflect.DeepEqual(values, testCase.expctedValues), "Expected values: %v, got %v", testCase.expctedValues, values) + assert.Equalf(tt, testCase.expctedValues, values, "Expected values: %v, got %v", testCase.expctedValues, values) }) } } @@ -445,16 +442,13 @@ func TestMergeValuesV3(t *testing.T) { } testMap := MergeMaps(flatMap, nestedMap) - equal := reflect.DeepEqual(testMap, nestedMap) - assert.True(t, equal, "Expected a nested map to overwrite a flat value. Expected: %v, got %v", nestedMap, testMap) + assert.Equal(t, testMap, nestedMap, "Expected a nested map to overwrite a flat value. Expected: %v, got %v", nestedMap, testMap) testMap = MergeMaps(nestedMap, flatMap) - equal = reflect.DeepEqual(testMap, flatMap) - assert.True(t, equal, "Expected a flat value to overwrite a map. Expected: %v, got %v", flatMap, testMap) + assert.Equal(t, testMap, flatMap, "Expected a flat value to overwrite a map. Expected: %v, got %v", flatMap, testMap) testMap = MergeMaps(nestedMap, anotherNestedMap) - equal = reflect.DeepEqual(testMap, anotherNestedMap) - assert.True(t, equal, "Expected a nested map to overwrite another nested map. Expected: %v, got %v", anotherNestedMap, testMap) + assert.Equal(t, testMap, anotherNestedMap, "Expected a nested map to overwrite another nested map. Expected: %v, got %v", anotherNestedMap, testMap) testMap = MergeMaps(anotherFlatMap, anotherNestedMap) expectedMap := map[string]any{ @@ -465,26 +459,23 @@ func TestMergeValuesV3(t *testing.T) { "awesome": "stuff", }, } - equal = reflect.DeepEqual(testMap, expectedMap) - assert.True(t, equal, "Expected a map with different keys to merge properly with another map. Expected: %v, got %v", expectedMap, testMap) + assert.Equal(t, expectedMap, testMap, "Expected a map with different keys to merge properly with another map. Expected: %v, got %v", expectedMap, testMap) } func verifyChart(t *testing.T, c *chart.Chart) { t.Helper() require.NotEmpty(t, c.Name(), "No chart metadata found on %v", c) t.Logf("Verifying chart %s", c.Name()) - assert.Len(t, c.Templates, 1, "Expected 1 template, got %d", len(c.Templates)) + assert.Len(t, c.Templates, 1, "Expected 1 template") numfiles := 6 - if len(c.Files) != numfiles { - t.Errorf("Expected %d extra files, got %d", numfiles, len(c.Files)) + if !assert.Len(t, c.Files, numfiles, "Expected %d extra files", numfiles) { for _, n := range c.Files { t.Logf("\t%s", n.Name) } } - if len(c.Dependencies()) != 2 { - t.Errorf("Expected 2 dependencies, got %d (%v)", len(c.Dependencies()), c.Dependencies()) + if !assert.Len(t, c.Dependencies(), 2, "Expected 2 dependencies") { for _, d := range c.Dependencies() { t.Logf("\tSubchart: %s\n", d.Name()) } @@ -509,7 +500,7 @@ func verifyChart(t *testing.T, c *chart.Chart) { func verifyDependencies(t *testing.T, c *chart.Chart) { t.Helper() - assert.Len(t, c.Metadata.Dependencies, 2, "Expected 2 dependencies, got %d", len(c.Metadata.Dependencies)) + assert.Len(t, c.Metadata.Dependencies, 2, "Expected 2 dependencies") tests := []*chart.Dependency{ {Name: "alpine", Version: "0.1.0", Repository: "https://example.com/charts"}, {Name: "mariner", Version: "4.3.2", Repository: "https://example.com/charts"}, diff --git a/internal/chart/v3/util/chartfile_test.go b/internal/chart/v3/util/chartfile_test.go index 0cc8a66af..850f39af2 100644 --- a/internal/chart/v3/util/chartfile_test.go +++ b/internal/chart/v3/util/chartfile_test.go @@ -36,36 +36,21 @@ func TestLoadChartfile(t *testing.T) { func verifyChartfile(t *testing.T, f *chart.Metadata, name string) { t.Helper() require.NotNil(t, f, "Failed verifyChartfile because f is nil") - assert.Equal(t, name, f.Name, "Expected %s, got %s", name, f.Name) - assert.Equal(t, "This is a frobnitz.", f.Description, "Unexpected description %q", f.Description) - assert.Equal(t, "1.2.3", f.Version, "Unexpected version %q", f.Version) - assert.Len(t, f.Maintainers, 2, "Expected 2 maintainers, got %d", len(f.Maintainers)) - assert.Equal(t, "The Helm Team", f.Maintainers[0].Name, "Unexpected maintainer name.") - assert.Equal(t, "nobody@example.com", f.Maintainers[1].Email, "Unexpected maintainer email.") - require.Len(t, f.Sources, 1, "Unexpected number of sources") - assert.Equal(t, "https://example.com/foo/bar", f.Sources[0], "Expected https://example.com/foo/bar, got %s", f.Sources) - assert.Equal(t, "http://example.com", f.Home, "Unexpected home.") - assert.Equal(t, "https://example.com/64x64.png", f.Icon, "Unexpected icon: %q", f.Icon) - require.Len(t, f.Keywords, 3, "Unexpected keywords") - require.Len(t, f.Annotations, 2, "Unexpected annotations") - want, got := "extravalue", f.Annotations["extrakey"] - assert.Equalf(t, want, got, "Want %q, but got %q", want, got) - - want, got = "anothervalue", f.Annotations["anotherkey"] - assert.Equalf(t, want, got, "Want %q, but got %q", want, got) + assert.Equal(t, "extravalue", f.Annotations["extrakey"]) + assert.Equal(t, "anothervalue", f.Annotations["anotherkey"]) kk := []string{"frobnitz", "sprocket", "dodad"} for i, k := range f.Keywords { diff --git a/internal/chart/v3/util/expand_test.go b/internal/chart/v3/util/expand_test.go index e6d66b74e..ddf74b392 100644 --- a/internal/chart/v3/util/expand_test.go +++ b/internal/chart/v3/util/expand_test.go @@ -101,7 +101,7 @@ func TestExpand(t *testing.T) { require.NoError(t, err) expectLen := 11 - assert.Len(t, fis, expectLen, "Expected %d files, but got %d", expectLen, len(fis)) + assert.Len(t, fis, expectLen, "Expected %d files", expectLen) for _, fi := range fis { expect, err := os.Stat(filepath.Join("testdata", "frobnitz", fi.Name())) @@ -154,7 +154,7 @@ func TestExpandFile(t *testing.T) { require.NoError(t, err) expectLen := 11 - assert.Len(t, fis, expectLen, "Expected %d files, but got %d", expectLen, len(fis)) + assert.Len(t, fis, expectLen, "Expected %d files", expectLen) for _, fi := range fis { expect, err := os.Stat(filepath.Join("testdata", "frobnitz", fi.Name())) diff --git a/internal/chart/v3/util/save_test.go b/internal/chart/v3/util/save_test.go index f7bd5dcfb..26bb54019 100644 --- a/internal/chart/v3/util/save_test.go +++ b/internal/chart/v3/util/save_test.go @@ -69,9 +69,8 @@ func TestSave(t *testing.T) { c2, err := loader.LoadFile(where) require.NoError(t, err) require.Equal(t, c.Name(), c2.Name(), "Expected chart archive to have %q, got %q", c.Name(), c2.Name()) - if len(c2.Files) != 1 || c2.Files[0].Name != "scheherazade/shahryar.txt" { - t.Fatal("Files data did not match") - } + require.Len(t, c2.Files, 1, "Files data did not match") + require.Equal(t, "scheherazade/shahryar.txt", c2.Files[0].Name, "Files data did not match") if !bytes.Equal(c.Schema, c2.Schema) { indentation := 4 diff --git a/internal/plugin/installer/http_installer_test.go b/internal/plugin/installer/http_installer_test.go index d0d5e099d..df8385ed6 100644 --- a/internal/plugin/installer/http_installer_test.go +++ b/internal/plugin/installer/http_installer_test.go @@ -67,10 +67,10 @@ func mockArchiveServer() *httptest.Server { if !strings.HasSuffix(r.URL.Path, ".tar.gz") { w.Header().Add("Content-Type", "text/html") fmt.Fprintln(w, "broken") - return + } else { + w.Header().Add("Content-Type", "application/gzip") + fmt.Fprintln(w, "test") } - w.Header().Add("Content-Type", "application/gzip") - fmt.Fprintln(w, "test") })) } @@ -221,22 +221,22 @@ func TestExtract(t *testing.T) { expectedReadmePerm := os.FileMode(0o777 &^ currentUmask) pluginYAMLFullPath := filepath.Join(tempDir, "plugin.yaml") - if info, err := os.Stat(pluginYAMLFullPath); err != nil { + info, err := os.Stat(pluginYAMLFullPath) + if err != nil { require.NotErrorIs(t, err, fs.ErrNotExist, "Expected %s to exist but doesn't", pluginYAMLFullPath) - t.Fatal(err) - } else { - require.Equalf(t, expectedPluginYAMLPerm, info.Mode().Perm(), "Expected %s to have %o mode but has %o (umask: %o)", - pluginYAMLFullPath, expectedPluginYAMLPerm, info.Mode().Perm(), currentUmask) } + require.NoError(t, err) + require.Equalf(t, expectedPluginYAMLPerm, info.Mode().Perm(), "Expected %s to have %o mode but has %o (umask: %o)", + pluginYAMLFullPath, expectedPluginYAMLPerm, info.Mode().Perm(), currentUmask) readmeFullPath := filepath.Join(tempDir, "README.md") - if info, err := os.Stat(readmeFullPath); err != nil { + info, err = os.Stat(readmeFullPath) + if err != nil { require.NotErrorIs(t, err, fs.ErrNotExist, "Expected %s to exist but doesn't", readmeFullPath) - t.Fatal(err) - } else { - require.Equalf(t, expectedReadmePerm, info.Mode().Perm(), "Expected %s to have %o mode but has %o (umask: %o)", - readmeFullPath, expectedReadmePerm, info.Mode().Perm(), currentUmask) } + require.NoError(t, err) + require.Equalf(t, expectedReadmePerm, info.Mode().Perm(), "Expected %s to have %o mode but has %o (umask: %o)", + readmeFullPath, expectedReadmePerm, info.Mode().Perm(), currentUmask) } func TestCleanJoin(t *testing.T) { diff --git a/internal/plugin/installer/installer_test.go b/internal/plugin/installer/installer_test.go index 620afc183..75c22787b 100644 --- a/internal/plugin/installer/installer_test.go +++ b/internal/plugin/installer/installer_test.go @@ -34,8 +34,6 @@ func TestIsRemoteHTTPArchive(t *testing.T) { // Test with invalid extension and unreachable server assert.False(t, isRemoteHTTPArchive("https://127.0.0.1:123/fake/plugin-1.2.3.notanarchive"), "Bad URL without valid extension should not succeed") - assert.True(t, isRemoteHTTPArchive(source), "Expected %q to be a valid archive URL", source) - assert.False(t, isRemoteHTTPArchive(source+"-not-an-extension"), "Expected media type match to fail") } diff --git a/internal/plugin/installer/vcs_installer_test.go b/internal/plugin/installer/vcs_installer_test.go index 3f5b098e4..82401d069 100644 --- a/internal/plugin/installer/vcs_installer_test.go +++ b/internal/plugin/installer/vcs_installer_test.go @@ -96,16 +96,14 @@ func TestVCSInstallerNonExistentVersion(t *testing.T) { require.NoError(t, err) // ensure a VCSInstaller was returned - _, ok := i.(*VCSInstaller) - require.True(t, ok, "expected a VCSInstaller") + require.IsType(t, &VCSInstaller{}, i, "expected a VCSInstaller") - if err := Install(i); err == nil { - t.Fatal("expected error for version does not exists, got none") - } else if strings.Contains(err.Error(), "Could not resolve host: github.com") { + err = Install(i) + require.Error(t, err, "expected error for version does not exists, got none") + if strings.Contains(err.Error(), "Could not resolve host: github.com") { t.Skip("Unable to run test without Internet access") - } else { - require.EqualErrorf(t, err, fmt.Sprintf("requested version %q does not exist for plugin %q", version, source), "expected error for version does not exists") } + require.EqualErrorf(t, err, fmt.Sprintf("requested version %q does not exist for plugin %q", version, source), "expected error for version does not exists") } func TestVCSInstallerUpdate(t *testing.T) { ensure.HelmHome(t) @@ -116,19 +114,16 @@ func TestVCSInstallerUpdate(t *testing.T) { require.NoError(t, err) // ensure a VCSInstaller was returned - _, ok := i.(*VCSInstaller) - require.True(t, ok, "expected a VCSInstaller") + require.IsType(t, &VCSInstaller{}, i, "expected a VCSInstaller") require.EqualErrorf(t, Update(i), "plugin does not exist", "expected error for plugin does not exist") // Install plugin before update - if err := Install(i); err != nil { - if strings.Contains(err.Error(), "Could not resolve host: github.com") { - t.Skip("Unable to run test without Internet access") - } else { - t.Fatal(err) - } + err = Install(i) + if err != nil && strings.Contains(err.Error(), "Could not resolve host: github.com") { + t.Skip("Unable to run test without Internet access") } + require.NoError(t, err) // Test FindSource method for positive result pluginInfo, err := FindSource(i.Path()) diff --git a/internal/plugin/subprocess_commands_test.go b/internal/plugin/subprocess_commands_test.go index b2ac19c02..7505bf343 100644 --- a/internal/plugin/subprocess_commands_test.go +++ b/internal/plugin/subprocess_commands_test.go @@ -16,7 +16,6 @@ limitations under the License. package plugin import ( - "reflect" "runtime" "testing" @@ -39,7 +38,7 @@ func TestPrepareCommand(t *testing.T) { cmd, args, err := PrepareCommands(platformCommand, true, []string{}, env) require.NoError(t, err) require.Equal(t, cmdMain, cmd, "Expected %q, got %q", cmdMain, cmd) - require.Truef(t, reflect.DeepEqual(args, cmdArgs), "Expected %v, got %v", cmdArgs, args) + require.Equalf(t, args, cmdArgs, "Expected %v, got %v", cmdArgs, args) } func TestPrepareCommandExtraArgs(t *testing.T) { @@ -111,7 +110,7 @@ func TestPrepareCommands(t *testing.T) { cmd, args, err := PrepareCommands(cmds, true, []string{}, env) require.NoError(t, err) require.Equal(t, cmdMain, cmd, "Expected %q, got %q", cmdMain, cmd) - require.Truef(t, reflect.DeepEqual(args, cmdArgs), "Expected %v, got %v", cmdArgs, args) + require.Equalf(t, args, cmdArgs, "Expected %v, got %v", cmdArgs, args) } func TestPrepareCommandsExtraArgs(t *testing.T) { @@ -132,7 +131,7 @@ func TestPrepareCommandsExtraArgs(t *testing.T) { cmd, args, err := PrepareCommands(cmds, true, extraArgs, env) require.NoError(t, err) require.Equal(t, cmdMain, cmd, "Expected %q, got %q", cmdMain, cmd) - require.Truef(t, reflect.DeepEqual(args, expectedArgs), "Expected %v, got %v", expectedArgs, args) + require.Equalf(t, expectedArgs, args, "Expected %v, got %v", expectedArgs, args) } func TestPrepareCommandsNoArch(t *testing.T) { @@ -149,7 +148,7 @@ func TestPrepareCommandsNoArch(t *testing.T) { cmd, args, err := PrepareCommands(cmds, true, []string{}, env) require.NoError(t, err) require.Equal(t, cmdMain, cmd, "Expected %q, got %q", cmdMain, cmd) - require.Truef(t, reflect.DeepEqual(args, cmdArgs), "Expected %v, got %v", cmdArgs, args) + require.Equalf(t, args, cmdArgs, "Expected %v, got %v", cmdArgs, args) } func TestPrepareCommandsNoOsNoArch(t *testing.T) { @@ -166,7 +165,7 @@ func TestPrepareCommandsNoOsNoArch(t *testing.T) { cmd, args, err := PrepareCommands(cmds, true, []string{}, env) require.NoError(t, err) require.Equal(t, cmdMain, cmd, "Expected %q, got %q", cmdMain, cmd) - require.Truef(t, reflect.DeepEqual(args, cmdArgs), "Expected %v, got %v", cmdArgs, args) + require.Equalf(t, args, cmdArgs, "Expected %v, got %v", cmdArgs, args) } func TestPrepareCommandsNoMatch(t *testing.T) { @@ -206,7 +205,7 @@ func TestPrepareCommandsExpand(t *testing.T) { cmd, args, err := PrepareCommands(cmds, true, []string{}, env) require.NoError(t, err) require.Equal(t, cmdMain, cmd, "Expected %q, got %q", cmdMain, cmd) - require.Truef(t, reflect.DeepEqual(args, expectedArgs), "Expected %v, got %v", expectedArgs, args) + require.Equalf(t, expectedArgs, args, "Expected %v, got %v", expectedArgs, args) } func TestPrepareCommandsNoExpand(t *testing.T) { @@ -223,5 +222,5 @@ func TestPrepareCommandsNoExpand(t *testing.T) { cmd, args, err := PrepareCommands(cmds, false, []string{}, env) require.NoError(t, err) require.Equal(t, cmdMain, cmd, "Expected %q, got %q", cmdMain, cmd) - require.Truef(t, reflect.DeepEqual(args, cmdArgs), "Expected %v, got %v", cmdArgs, args) + require.Equalf(t, args, cmdArgs, "Expected %v, got %v", cmdArgs, args) } diff --git a/internal/release/v2/util/manifest_sorter_test.go b/internal/release/v2/util/manifest_sorter_test.go index deb9426ce..6cf529bff 100644 --- a/internal/release/v2/util/manifest_sorter_test.go +++ b/internal/release/v2/util/manifest_sorter_test.go @@ -143,7 +143,6 @@ metadata: // This test will fail if 'six' or 'seven' was added. assert.Len(t, generic, 2) - assert.Len(t, hs, 4) for _, out := range hs { diff --git a/internal/resolver/resolver_test.go b/internal/resolver/resolver_test.go index 547419e17..db976a45b 100644 --- a/internal/resolver/resolver_test.go +++ b/internal/resolver/resolver_test.go @@ -148,28 +148,22 @@ func TestResolve(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { l, err := r.Resolve(tt.req, repoNames) - if err != nil { - if tt.err { - return - } + if tt.err { + require.Error(t, err) + } else { require.NoError(t, err) - } + h, err := HashReq(tt.req, tt.expect.Dependencies) + require.NoError(t, err) + assert.Equal(t, l.Digest, h, "%q: hashes don't match.", tt.name) - if tt.err { - require.Failf(t, "Expected error in test %q", tt.name) + // Check fields. + require.Len(t, l.Dependencies, len(tt.req), "%s: wrong number of dependencies in lock", tt.name) + d0 := l.Dependencies[0] + e0 := tt.expect.Dependencies[0] + assert.Equal(t, e0.Name, d0.Name, tt.name) + assert.Equal(t, e0.Repository, d0.Repository, tt.name) + assert.Equal(t, e0.Version, d0.Version, tt.name) } - - h, err := HashReq(tt.req, tt.expect.Dependencies) - require.NoError(t, err) - assert.Equal(t, l.Digest, h, "%q: hashes don't match.", tt.name) - - // Check fields. - assert.Len(t, l.Dependencies, len(tt.req), "%s: wrong number of dependencies in lock", tt.name) - d0 := l.Dependencies[0] - e0 := tt.expect.Dependencies[0] - assert.Equal(t, e0.Name, d0.Name, tt.name) - assert.Equal(t, e0.Repository, d0.Repository, tt.name) - assert.Equal(t, e0.Version, d0.Version, tt.name) }) } } @@ -280,20 +274,16 @@ func TestGetLocalPath(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { p, err := GetLocalPath(tt.repo, tt.chartpath) - if err != nil { - if tt.err { - return - } - require.NoError(t, err) - } if tt.err { - require.Failf(t, "Expected error in test %q", tt.name) - } - expect := tt.expect - if runtime.GOOS == "windows" { - expect = tt.winExpect + require.Error(t, err) + } else { + require.NoError(t, err) + if runtime.GOOS == "windows" { + assert.Equal(t, tt.winExpect, p, tt.name) + } else { + assert.Equal(t, tt.expect, p, tt.name) + } } - assert.Equal(t, expect, p, tt.name) }) } } From 4d9c03f51c30f851a03676a1315f492de10210e6 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Fri, 24 Jul 2026 13:24:06 +0200 Subject: [PATCH 53/61] chore(pkg): refactor: finer tests conversions to testify part 2 #### Description refactor: finer tests conversions to testify in pkg/storage/driver Signed-off-by: Matthieu MOREL --- pkg/chart/v2/lint/lint_test.go | 15 +++++------ pkg/chart/v2/util/validate_name_test.go | 28 +++++++++++---------- pkg/cli/values/options_test.go | 30 +++++++++++----------- pkg/cmd/package_test.go | 30 +++++++++++----------- pkg/cmd/pull_test.go | 30 +++++++++++----------- pkg/cmd/search/search_test.go | 33 +++++++++++-------------- pkg/cmd/upgrade_test.go | 19 +++++--------- pkg/downloader/manager_test.go | 23 +++++++---------- pkg/engine/engine_test.go | 27 ++++++++------------ pkg/getter/ocigetter_test.go | 10 -------- pkg/repo/v1/index_test.go | 24 +++++++----------- pkg/storage/driver/cfgmaps_test.go | 23 ++++++++--------- pkg/storage/driver/memory_test.go | 11 +++------ pkg/storage/driver/secrets_test.go | 21 +++++++--------- pkg/storage/driver/sql_test.go | 25 ++++++++----------- pkg/storage/storage_test.go | 15 ++++++----- 16 files changed, 151 insertions(+), 213 deletions(-) diff --git a/pkg/chart/v2/lint/lint_test.go b/pkg/chart/v2/lint/lint_test.go index 1782c01d4..c4705872d 100644 --- a/pkg/chart/v2/lint/lint_test.go +++ b/pkg/chart/v2/lint/lint_test.go @@ -118,7 +118,7 @@ func TestBadValues(t *testing.T) { func TestBadCrdFile(t *testing.T) { var values map[string]any m := RunAll(badCrdFileDir, values, namespace).Messages - assert.Lenf(t, m, 2, "All didn't fail with expected errors, got %#v", m) + require.Lenf(t, m, 2, "All didn't fail with expected errors, got %#v", m) require.ErrorContains(t, m[0].Err, "apiVersion is not in 'apiextensions.k8s.io'") assert.ErrorContains(t, m[1].Err, "object kind is not 'CustomResourceDefinition'") } @@ -126,8 +126,7 @@ func TestBadCrdFile(t *testing.T) { func TestGoodChart(t *testing.T) { var values map[string]any m := RunAll(goodChartDir, values, namespace).Messages - if len(m) != 0 { - t.Error("All returned linter messages when it shouldn't have") + if !assert.Empty(t, m, "All returned linter messages when it shouldn't have") { for i, msg := range m { t.Logf("Message %d: %s", i, msg) } @@ -147,13 +146,12 @@ func TestHelmCreateChart(t *testing.T) { // Note: we test with strict=true here, even though others have // strict = false. m := RunAll(createdChart, values, namespace, WithSkipSchemaValidation(true)).Messages - if ll := len(m); ll != 1 { - t.Errorf("All should have had exactly 1 error. Got %d", ll) + if !assert.Len(t, m, 1, "All should have had exactly 1 error") { for i, msg := range m { t.Logf("Message %d: %s", i, msg.Error()) } - } else if msg := m[0].Err.Error(); !strings.Contains(msg, "icon is recommended") { - t.Errorf("Unexpected lint error: %s", msg) + } else { + assert.ErrorContains(t, m[0].Err, "icon is recommended") } } @@ -196,8 +194,7 @@ func TestHelmCreateChart_CheckDeprecatedWarnings(t *testing.T) { func TestSubChartValuesChart(t *testing.T) { var values map[string]any m := RunAll(subChartValuesDir, values, namespace).Messages - if len(m) != 0 { - t.Error("All returned linter messages when it shouldn't have") + if !assert.Empty(t, m, "All returned linter messages when it shouldn't have") { for i, msg := range m { t.Logf("Message %d: %s", i, msg) } diff --git a/pkg/chart/v2/util/validate_name_test.go b/pkg/chart/v2/util/validate_name_test.go index cfc62a0f7..9095dc4dc 100644 --- a/pkg/chart/v2/util/validate_name_test.go +++ b/pkg/chart/v2/util/validate_name_test.go @@ -16,7 +16,11 @@ limitations under the License. package util -import "testing" +import ( + "testing" + + "github.com/stretchr/testify/assert" +) // TestValidateReleaseName is a regression test for ValidateName // @@ -46,12 +50,11 @@ func TestValidateReleaseName(t *testing.T) { "a1111111111111111111111111111111111111111111111111111111111z": false, } for input, expectPass := range names { - if err := ValidateReleaseName(input); (err == nil) != expectPass { - st := "fail" - if expectPass { - st = "succeed" - } - t.Errorf("Expected %q to %s", input, st) + err := ValidateReleaseName(input) + if expectPass { + assert.NoError(t, err) + } else { + assert.Error(t, err) } } } @@ -80,12 +83,11 @@ func TestValidateMetadataName(t *testing.T) { "a1111111111111111111111111111111111111111111111111111111111z": false, } for input, expectPass := range names { - if err := ValidateMetadataName(input); (err == nil) != expectPass { - st := "fail" - if expectPass { - st = "succeed" - } - t.Errorf("Expected %q to %s", input, st) + err := ValidateMetadataName(input) + if expectPass { + assert.NoError(t, err) + } else { + assert.Error(t, err) } } } diff --git a/pkg/cli/values/options_test.go b/pkg/cli/values/options_test.go index 40590f33f..6debb693e 100644 --- a/pkg/cli/values/options_test.go +++ b/pkg/cli/values/options_test.go @@ -215,19 +215,17 @@ func TestReadFile(t *testing.T) { got, err := readFile(actualFilePath, tt.providers) require.NoError(t, err, "readFile() expected no error for stdin") assert.Equal(t, testData, got) - return - } - - // Regular test cases - got, err := readFile(actualFilePath, tt.providers) - if tt.expectError { - assert.Error(t, err) - return - } - require.NoError(t, err) - - if tt.expectedData != nil { - assert.Equal(t, tt.expectedData, got) + } else { + // Regular test cases + got, err := readFile(actualFilePath, tt.providers) + if tt.expectError { + assert.Error(t, err) + } else { + require.NoError(t, err) + if tt.expectedData != nil { + assert.Equal(t, tt.expectedData, got) + } + } } }) } @@ -356,10 +354,10 @@ func TestMergeValuesCLI(t *testing.T) { got, err := tt.opts.MergeValues(getter.Providers{}) if tt.wantErr { assert.Error(t, err) - return + } else { + require.NoError(t, err) + assert.Equal(t, tt.expected, got) } - require.NoError(t, err) - assert.Equal(t, tt.expected, got) }) } } diff --git a/pkg/cmd/package_test.go b/pkg/cmd/package_test.go index d78f5d88d..8b19faf08 100644 --- a/pkg/cmd/package_test.go +++ b/pkg/cmd/package_test.go @@ -139,24 +139,22 @@ func TestPackage(t *testing.T) { } } _, _, err = executeActionCommand(strings.Join(cmd, " ")) - - if err != nil { - if tt.err && re.MatchString(err.Error()) { - return + if tt.err { + require.Error(t, err) + require.True(t, re.MatchString(err.Error())) + } else { + require.NoError(t, err) + if tt.hasfile != "" { + fi, err := os.Stat(tt.hasfile) + require.NoErrorf(t, err, "%q: expected file %q", tt.name, tt.hasfile) + assert.NotEqualf(t, 0, fi.Size(), "%q: file %q has zero bytes.", tt.name, tt.hasfile) } - t.Fatalf("%q: expected error %q, got %q", tt.name, tt.expect, err) - } - if tt.hasfile != "" { - fi, err := os.Stat(tt.hasfile) - require.NoErrorf(t, err, "%q: expected file %q", tt.name, tt.hasfile) - assert.NotEqualf(t, 0, fi.Size(), "%q: file %q has zero bytes.", tt.name, tt.hasfile) - } - - if v, ok := tt.flags["sign"]; ok && v == "1" { - fi, err := os.Stat(tt.hasfile + ".prov") - require.NoErrorf(t, err, "%q: expected provenance file", tt.name) - assert.NotEqualf(t, 0, fi.Size(), "%q: provenance file is empty", tt.name) + if v, ok := tt.flags["sign"]; ok && v == "1" { + fi, err := os.Stat(tt.hasfile + ".prov") + require.NoErrorf(t, err, "%q: expected provenance file", tt.name) + assert.NotEqualf(t, 0, fi.Size(), "%q: provenance file is empty", tt.name) + } } }) } diff --git a/pkg/cmd/pull_test.go b/pkg/cmd/pull_test.go index 352c36a29..d0371710b 100644 --- a/pkg/cmd/pull_test.go +++ b/pkg/cmd/pull_test.go @@ -237,25 +237,23 @@ func TestPullCmd(t *testing.T) { require.NoError(t, os.MkdirAll(file, 0o755)) } _, out, err := executeActionCommand(cmd) - if err != nil { - if tt.wantError { - if tt.wantErrorMsg != "" && tt.wantErrorMsg != err.Error() { - t.Fatalf("Actual error '%s', not equal to expected error '%s'", err, tt.wantErrorMsg) - } - return + if tt.wantError { + if tt.wantErrorMsg != "" { + require.EqualError(t, err, tt.wantErrorMsg, "Actual error '%s', not equal to expected error '%s'", err, tt.wantErrorMsg) } - t.Fatalf("%q reported error: %s", tt.name, err) - } + } else { + require.NoError(t, err) - if tt.expectVerify { - outString := helmTestKeyOut + tt.expectSha + "\n" - assert.Equal(t, outString, out, "%q: expected verification output %q, got %q", tt.name, outString, out) - } + if tt.expectVerify { + outString := helmTestKeyOut + tt.expectSha + "\n" + assert.Equal(t, outString, out, "%q: expected verification output %q, got %q", tt.name, outString, out) + } - ef := filepath.Join(outdir, tt.expectFile) - fi, err := os.Stat(ef) - require.NoError(t, err, "%q: expected a file at %s.", tt.name, ef) - assert.Equal(t, tt.expectDir, fi.IsDir(), "%q: expected directory=%t, but it's not.", tt.name, tt.expectDir) + ef := filepath.Join(outdir, tt.expectFile) + fi, err := os.Stat(ef) + require.NoError(t, err, "%q: expected a file at %s.", tt.name, ef) + assert.Equal(t, tt.expectDir, fi.IsDir(), "%q: expected directory=%t, but it's not.", tt.name, tt.expectDir) + } }) } } diff --git a/pkg/cmd/search/search_test.go b/pkg/cmd/search/search_test.go index f8c9504d1..e45386947 100644 --- a/pkg/cmd/search/search_test.go +++ b/pkg/cmd/search/search_test.go @@ -232,26 +232,21 @@ func TestSearchByName(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { charts, err := i.Search(tt.query, 100, tt.regexp) - if err != nil { - if tt.fail { - require.ErrorContains(t, err, tt.failMsg) - return - } - t.Fatalf("%s: %s", tt.name, err) - } - // Give us predictably ordered results. - SortScore(charts) + if tt.fail { + require.ErrorContains(t, err, tt.failMsg) + } else { + require.NoError(t, err) // Give us predictably ordered results. + SortScore(charts) - l := len(charts) - require.Lenf(t, tt.expect, l, "Expected %d result, got %d", len(tt.expect), l) - // For empty result sets, just keep going. - if l == 0 { - return - } - - for i, got := range charts { - ex := tt.expect[i] - assert.Equalf(t, got.Name, ex.Name, "[%d]: Expected name %q, got %q", i, ex.Name, got.Name) + l := len(tt.expect) + require.Len(t, charts, len(tt.expect)) + // For empty result sets, just keep going. + if l != 0 { + for i, got := range charts { + ex := tt.expect[i] + assert.Equalf(t, got.Name, ex.Name, "[%d]: Expected name %q, got %q", i, ex.Name, got.Name) + } + } } }) } diff --git a/pkg/cmd/upgrade_test.go b/pkg/cmd/upgrade_test.go index 1c1823199..5aba7b11b 100644 --- a/pkg/cmd/upgrade_test.go +++ b/pkg/cmd/upgrade_test.go @@ -22,7 +22,6 @@ import ( "net/http/httptest" "os" "path/filepath" - "reflect" "testing" "time" @@ -201,9 +200,9 @@ func TestUpgradeDependencyUpdateOCINoPanic(t *testing.T) { w.Header().Set("Docker-Distribution-API-Version", "registry/2.0") if r.URL.Path == "/v2/" { w.WriteHeader(http.StatusOK) - return + } else { + w.WriteHeader(http.StatusNotFound) } - w.WriteHeader(http.StatusNotFound) })) defer srv.Close() @@ -224,23 +223,17 @@ func TestUpgradeDependencyUpdateOCINoPanic(t *testing.T) { }}, }, } - if err := chartutil.SaveDir(parent, tmp); err != nil { - t.Fatalf("Error creating chart: %v", err) - } + require.NoError(t, chartutil.SaveDir(parent, tmp), "Error creating chart") chartPath := filepath.Join(tmp, parent.Metadata.Name) // SaveDir writes only resolved subcharts (Chart.Dependencies()), not the // declared Metadata.Dependencies, so create the empty charts/ directory // explicitly to make the "dependency missing from charts/" state concrete. - if err := os.MkdirAll(filepath.Join(chartPath, "charts"), 0o755); err != nil { - t.Fatalf("Error creating charts dir: %v", err) - } + require.NoError(t, os.MkdirAll(filepath.Join(chartPath, "charts"), 0o755), "Error creating charts dir") // The command must return an error (registry rejects the lookup), not panic. _, _, err := executeActionCommandC(storageFixture(), fmt.Sprintf("upgrade --dependency-update --plain-http oci-parent '%s'", chartPath)) - if err == nil { - t.Fatal("expected an error resolving the OCI dependency, got nil") - } + require.Error(t, err, "expected an error resolving the OCI dependency, got nil") } func TestUpgradeWithValue(t *testing.T) { @@ -471,7 +464,7 @@ func TestUpgradeInstallWithLabels(t *testing.T) { updatedRel, err := releaserToV1Release(updatedReli) require.NoError(t, err) - assert.Truef(t, reflect.DeepEqual(updatedRel.Labels, expectedLabels), "Expected {%v}, got {%v}", expectedLabels, updatedRel.Labels) + assert.Equal(t, expectedLabels, updatedRel.Labels) } func prepareMockReleaseWithSecret(t *testing.T, releaseName string) (func(n string, v int, ch *chart.Chart) *release.Release, *chart.Chart, string) { diff --git a/pkg/downloader/manager_test.go b/pkg/downloader/manager_test.go index 00cb5b668..e40bbbac1 100644 --- a/pkg/downloader/manager_test.go +++ b/pkg/downloader/manager_test.go @@ -20,7 +20,6 @@ import ( "io/fs" "os" "path/filepath" - "reflect" "testing" "time" @@ -168,19 +167,16 @@ func TestGetRepoNames(t *testing.T) { } for _, tt := range tests { - l, err := m.resolveRepoNames(tt.req) - if err != nil { + t.Run(tt.name, func(t *testing.T) { + l, err := m.resolveRepoNames(tt.req) if tt.err { - continue + require.Error(t, err) + } else { + require.NoError(t, err) + // m1 and m2 are the maps we want to compare + assert.Equal(t, l, tt.expect, "%s: expected map %v, got %v", tt.name, l, tt.name) } - t.Fatal(err) - } - - require.False(t, tt.err, "Expected error in test %q", tt.name) - - // m1 and m2 are the maps we want to compare - eq := reflect.DeepEqual(l, tt.expect) - assert.True(t, eq, "%s: expected map %v, got %v", tt.name, l, tt.name) + }) } } @@ -479,8 +475,7 @@ func TestErrRepoNotFound_Error(t *testing.T) { e := ErrRepoNotFound{ Repos: tt.fields.Repos, } - got := e.Error() - assert.EqualErrorf(t, e, tt.want, "Error() = %v, want %v", got, tt.want) + assert.EqualError(t, e, tt.want) }) } } diff --git a/pkg/engine/engine_test.go b/pkg/engine/engine_test.go index ecc1eee3b..1f3096366 100644 --- a/pkg/engine/engine_test.go +++ b/pkg/engine/engine_test.go @@ -78,8 +78,7 @@ func TestFuncMap(t *testing.T) { // Test for Engine-specific template functions. expect := []string{"include", "required", "tpl", "toYaml", "fromYaml", "toToml", "fromToml", "toJson", "fromJson", "lookup"} for _, f := range expect { - _, ok := fns[f] - assert.Truef(t, ok, "Expected add-on function %q", f) + assert.Containsf(t, fns, f, "Expected add-on function %q", f) } } @@ -412,8 +411,7 @@ func TestParseErrors(t *testing.T) { } _, err := new(Engine).render(t.Context(), tplsUndefinedFunction) require.Error(t, err, "Expected failures while rendering") - expected := `parse error at (undefined_function:1): function "foo" not defined` - assert.EqualError(t, err, expected) + assert.EqualError(t, err, `parse error at (undefined_function:1): function "foo" not defined`) } func TestExecErrors(t *testing.T) { @@ -887,9 +885,8 @@ func TestRenderRecursionLimit(t *testing.T) { expectErr := "rendering template has a nested reference name: recursion: unable to execute template" _, err := Render(c, v) - if err == nil || !strings.HasSuffix(err.Error(), expectErr) { - t.Errorf("Expected err with suffix: %s", expectErr) - } + require.Error(t, err) + assert.True(t, strings.HasSuffix(err.Error(), expectErr), "Expected err with suffix: %s", expectErr) // calling the same function many times is ok times := 4000 @@ -1261,18 +1258,14 @@ func TestRenderCustomTemplateFuncs(t *testing.T) { require.NoError(t, err) // Expected output should be "hello!!!". - expected := "hello!!!" - key := "CustomFunc/templates/manifest" - if rendered, ok := out[key]; !ok || rendered != expected { - t.Errorf("Expected %q, got %q", expected, rendered) - } + rendered, ok := out["CustomFunc/templates/manifest"] + require.True(t, ok) + assert.Equal(t, "hello!!!", rendered) // Verify that the rendered template used the custom "upper" function. - expected = "custom:hello" - key = "CustomFunc/templates/override" - if rendered, ok := out[key]; !ok || rendered != expected { - t.Errorf("Expected %q, got %q", expected, rendered) - } + rendered, ok = out["CustomFunc/templates/override"] + require.True(t, ok) + assert.Equal(t, "custom:hello", rendered) } func TestTraceableError_SimpleForm(t *testing.T) { diff --git a/pkg/getter/ocigetter_test.go b/pkg/getter/ocigetter_test.go index dfcc74890..5e7f01420 100644 --- a/pkg/getter/ocigetter_test.go +++ b/pkg/getter/ocigetter_test.go @@ -55,23 +55,14 @@ func TestOCIGetter(t *testing.T) { og, ok := g.(*OCIGetter) require.True(t, ok, "expected NewOCIGetter to produce an *OCIGetter") - assert.Equal(t, "I", og.opts.username, "Expected NewOCIGetter to contain %q as the username, got %q", "I", og.opts.username) - assert.Equal(t, "Am", og.opts.password, "Expected NewOCIGetter to contain %q as the password, got %q", "Am", og.opts.password) - assert.Equal(t, pub, og.opts.certFile, "Expected NewOCIGetter to contain %q as the public key file, got %q", pub, og.opts.certFile) - assert.Equal(t, priv, og.opts.keyFile, "Expected NewOCIGetter to contain %q as the private key file, got %q", priv, og.opts.keyFile) - assert.Equal(t, ca, og.opts.caFile, "Expected NewOCIGetter to contain %q as the CA file, got %q", ca, og.opts.caFile) - assert.Equal(t, timeout, og.opts.timeout, "Expected NewOCIGetter to contain %s as Timeout flag, got %s", timeout, og.opts.timeout) - assert.Equal(t, transport, og.opts.transport, "Expected NewOCIGetter to contain %p as Transport, got %p", transport, og.opts.transport) - assert.Equal(t, plainHTTP, og.opts.plainHTTP, "Expected NewOCIGetter to have plainHTTP as %t, got %t", plainHTTP, og.opts.plainHTTP) - assert.Equal(t, insecureSkipVerifyTLS, og.opts.insecureSkipVerifyTLS, "Expected NewOCIGetter to have insecureSkipVerifyTLS as %t, got %t", insecureSkipVerifyTLS, og.opts.insecureSkipVerifyTLS) // Test if setting registryClient is being passed to the ops @@ -84,7 +75,6 @@ func TestOCIGetter(t *testing.T) { require.NoError(t, err) og, ok = g.(*OCIGetter) require.True(t, ok, "expected NewOCIGetter to produce an *OCIGetter") - assert.Equal(t, registryClient, og.opts.registryClient, "Expected NewOCIGetter to contain %p as RegistryClient, got %p", registryClient, og.opts.registryClient) } diff --git a/pkg/repo/v1/index_test.go b/pkg/repo/v1/index_test.go index 88aed14d7..09fc7de8a 100644 --- a/pkg/repo/v1/index_test.go +++ b/pkg/repo/v1/index_test.go @@ -116,9 +116,8 @@ func TestIndexFile(t *testing.T) { assert.Equalf(t, "0.2.0", v, "Unexpected first version: %s", v) cv, err := i.Get("setter", "0.1.9") - if err == nil && !strings.Contains(cv.Version, "0.1.9") { - t.Errorf("Unexpected version: %s", cv.Version) - } + require.NoError(t, err) + assert.Contains(t, cv.Version, "0.1.9", "Unexpected version: %s", cv.Version) cv, err = i.Get("setter", "0.1.9+alpha") require.NoError(t, err, "Expected version: 0.1.9+alpha") @@ -304,9 +303,8 @@ func verifyLocalIndex(t *testing.T, i *IndexFile) { require.Equalf(t, 1, l, "'alpine' should have 1 chart, got %d", l) nginx, ok := i.Entries["nginx"] - if !ok || len(nginx) != 2 { - t.Fatal("Expected 2 nginx entries") - } + require.True(t, ok) + require.Len(t, nginx, 2, "Expected 2 nginx entries") expects := []*ChartVersion{ { @@ -507,18 +505,14 @@ func TestIgnoreSkippableChartValidationError(t *testing.T) { for name, tc := range testCases { t.Run(name, func(t *testing.T) { result := ignoreSkippableChartValidationError(tc.Input) - - if tc.Input == nil { + switch { + case tc.Input == nil: assert.NoError(t, result, "expected nil result for nil input") - return - } - - if tc.ErrorSkipped { + case tc.ErrorSkipped: assert.NoError(t, result, "expected nil result for skipped error") - return + default: + assert.ErrorIs(t, tc.Input, result, "expected the result equal to input") } - - assert.ErrorIs(t, tc.Input, result, "expected the result equal to input") }) } } diff --git a/pkg/storage/driver/cfgmaps_test.go b/pkg/storage/driver/cfgmaps_test.go index e36aecce8..b8449f67e 100644 --- a/pkg/storage/driver/cfgmaps_test.go +++ b/pkg/storage/driver/cfgmaps_test.go @@ -16,7 +16,6 @@ package driver import ( "encoding/base64" "encoding/json" - "reflect" "testing" "github.com/stretchr/testify/assert" @@ -46,7 +45,7 @@ func TestConfigMapGet(t *testing.T) { got, err := cfgmaps.Get(key) require.NoError(t, err, "Failed to get release") // compare fetched release with original - assert.Truef(t, reflect.DeepEqual(rel, got), "Expected {%v}, got {%v}", rel, got) + assert.Equalf(t, rel, got, "Expected {%v}, got {%v}", rel, got) } func TestUncompressedConfigMapGet(t *testing.T) { @@ -70,7 +69,7 @@ func TestUncompressedConfigMapGet(t *testing.T) { got, err := cfgmaps.Get(key) require.NoError(t, err, "Failed to get release") // compare fetched release with original - assert.Truef(t, reflect.DeepEqual(rel, got), "Expected {%v}, got {%v}", rel, got) + assert.Equalf(t, rel, got, "Expected {%v}, got {%v}", rel, got) } func convertReleaserToV1(t *testing.T, rel release.Releaser) *rspb.Release { @@ -105,7 +104,7 @@ func TestConfigMapList(t *testing.T) { }) // check require.NoError(t, err, "Failed to list deleted") - assert.Len(t, del, 2, "Expected 2 deleted, got %d:\n%v\n", len(del), del) + assert.Len(t, del, 2, "Expected 2 deleted") // list all deployed releases dpl, err := cfgmaps.List(func(rel release.Releaser) bool { @@ -114,7 +113,7 @@ func TestConfigMapList(t *testing.T) { }) // check require.NoError(t, err, "Failed to list deployed") - assert.Len(t, dpl, 2, "Expected 2 deployed, got %d", len(dpl)) + assert.Len(t, dpl, 2, "Expected 2 deployed") // list all superseded releases ssd, err := cfgmaps.List(func(rel release.Releaser) bool { @@ -123,13 +122,11 @@ func TestConfigMapList(t *testing.T) { }) // check require.NoError(t, err, "Failed to list superseded") - assert.Len(t, ssd, 2, "Expected 2 superseded, got %d", len(ssd)) + assert.Len(t, ssd, 2, "Expected 2 superseded") // Check if release having both system and custom labels, this is needed to ensure that selector filtering would work. rls := convertReleaserToV1(t, ssd[0]) - _, ok := rls.Labels["name"] - require.True(t, ok, "Expected 'name' label in results, actual %v", rls.Labels) - _, ok = rls.Labels["key1"] - require.True(t, ok, "Expected 'key1' label in results, actual %v", rls.Labels) + require.Contains(t, rls.Labels, "name", "Expected 'name' label in results, actual %v", rls.Labels) + require.Contains(t, rls.Labels, "key1", "Expected 'key1' label in results, actual %v", rls.Labels) } func TestConfigMapQuery(t *testing.T) { @@ -144,7 +141,7 @@ func TestConfigMapQuery(t *testing.T) { rls, err := cfgmaps.Query(map[string]string{"status": "deployed"}) require.NoError(t, err, "Failed to query") - assert.Len(t, rls, 2, "Expected 2 results, got %d", len(rls)) + assert.Len(t, rls, 2, "Expected 2 results") _, err = cfgmaps.Query(map[string]string{"name": "notExist"}) assert.ErrorIs(t, err, ErrReleaseNotFound) @@ -167,7 +164,7 @@ func TestConfigMapCreate(t *testing.T) { require.NoError(t, err, "Failed to get release with key %q", key) // compare created release with original - assert.Truef(t, reflect.DeepEqual(rel, got), "Expected {%v}, got {%v}", rel, got) + assert.Equalf(t, rel, got, "Expected {%v}, got {%v}", rel, got) } func TestConfigMapUpdate(t *testing.T) { @@ -210,7 +207,7 @@ func TestConfigMapDelete(t *testing.T) { // perform the delete rls, err := cfgmaps.Delete(key) require.NoError(t, err, "Failed to delete release with key %q", key) - assert.Truef(t, reflect.DeepEqual(rel, rls), "Expected {%v}, got {%v}", rel, rls) + assert.Equalf(t, rel, rls, "Expected {%v}, got {%v}", rel, rls) _, err = cfgmaps.Get(key) assert.ErrorIs(t, err, ErrReleaseNotFound) } diff --git a/pkg/storage/driver/memory_test.go b/pkg/storage/driver/memory_test.go index 7a8d4cb3e..c0eff3cf9 100644 --- a/pkg/storage/driver/memory_test.go +++ b/pkg/storage/driver/memory_test.go @@ -18,7 +18,6 @@ package driver import ( "fmt" - "reflect" "testing" "github.com/stretchr/testify/assert" @@ -112,7 +111,7 @@ func TestMemoryList(t *testing.T) { }) // check require.NoError(t, err, "Failed to list deployed releases") - assert.Len(t, dpl, 2, "Expected 2 deployed, got %d", len(dpl)) + assert.Len(t, dpl, 2, "Expected 2 deployed") // list all superseded releases ssd, err := ts.List(func(rel release.Releaser) bool { @@ -121,7 +120,7 @@ func TestMemoryList(t *testing.T) { }) // check require.NoError(t, err, "Failed to list superseded releases") - assert.Len(t, ssd, 6, "Expected 6 superseded, got %d", len(ssd)) + assert.Len(t, ssd, 6, "Expected 6 superseded") // list all deleted releases del, err := ts.List(func(rel release.Releaser) bool { @@ -210,7 +209,7 @@ func TestMemoryUpdate(t *testing.T) { r, err := ts.Get(tt.key) require.NoError(t, err, "Failed to get") - require.Truef(t, reflect.DeepEqual(r, tt.rls), "Expected %v, actual %v\n", tt.rls, r) + require.Equalf(t, r, tt.rls, "Expected %v, actual %v\n", tt.rls, r) } } } @@ -256,10 +255,8 @@ func TestMemoryDelete(t *testing.T) { ts.SetNamespace("") end, err := ts.Query(map[string]string{"status": "deployed"}) require.NoError(t, err, "Query failed") - endLen := len(end) - if startLen-2 != endLen { - t.Errorf("expected end to be %d instead of %d", startLen-2, endLen) + if !assert.Len(t, end, startLen-2) { for _, ee := range end { rac, err := release.NewAccessor(ee) require.NoError(t, err, "unable to get release accessor") diff --git a/pkg/storage/driver/secrets_test.go b/pkg/storage/driver/secrets_test.go index 8cc3f390d..b53f17ad9 100644 --- a/pkg/storage/driver/secrets_test.go +++ b/pkg/storage/driver/secrets_test.go @@ -16,7 +16,6 @@ package driver import ( "encoding/base64" "encoding/json" - "reflect" "testing" "github.com/stretchr/testify/assert" @@ -46,7 +45,7 @@ func TestSecretGet(t *testing.T) { got, err := secrets.Get(key) require.NoError(t, err, "Failed to get release") // compare fetched release with original - assert.Truef(t, reflect.DeepEqual(rel, got), "Expected {%v}, got {%v}", rel, got) + assert.Equalf(t, rel, got, "Expected {%v}, got {%v}", rel, got) } func TestUNcompressedSecretGet(t *testing.T) { @@ -70,7 +69,7 @@ func TestUNcompressedSecretGet(t *testing.T) { got, err := secrets.Get(key) require.NoError(t, err, "Failed to get release") // compare fetched release with original - assert.Truef(t, reflect.DeepEqual(rel, got), "Expected {%v}, got {%v}", rel, got) + assert.Equalf(t, rel, got, "Expected {%v}, got {%v}", rel, got) } func TestSecretList(t *testing.T) { @@ -90,7 +89,7 @@ func TestSecretList(t *testing.T) { }) // check require.NoError(t, err, "Failed to list deleted") - assert.Len(t, del, 2, "Expected 2 deleted, got %d:\n%v\n", len(del), del) + assert.Len(t, del, 2, "Expected 2 deleted") // list all deployed releases dpl, err := secrets.List(func(rel release.Releaser) bool { @@ -99,7 +98,7 @@ func TestSecretList(t *testing.T) { }) // check require.NoError(t, err, "Failed to list deployed") - assert.Len(t, dpl, 2, "Expected 2 deployed, got %d", len(dpl)) + assert.Len(t, dpl, 2, "Expected 2 deployed") // list all superseded releases ssd, err := secrets.List(func(rel release.Releaser) bool { @@ -108,13 +107,11 @@ func TestSecretList(t *testing.T) { }) // check require.NoError(t, err, "Failed to list superseded") - assert.Len(t, ssd, 2, "Expected 2 superseded, got %d", len(ssd)) + require.Len(t, ssd, 2, "Expected 2 superseded") // Check if release having both system and custom labels, this is needed to ensure that selector filtering would work. rls := convertReleaserToV1(t, ssd[0]) - _, ok := rls.Labels["name"] - require.True(t, ok, "Expected 'name' label in results, actual %v", rls.Labels) - _, ok = rls.Labels["key1"] - require.True(t, ok, "Expected 'key1' label in results, actual %v", rls.Labels) + require.Contains(t, rls.Labels, "name", "Expected 'name' label in results, actual %v", rls.Labels) + require.Contains(t, rls.Labels, "key1", "Expected 'key1' label in results, actual %v", rls.Labels) } func TestSecretQuery(t *testing.T) { @@ -152,7 +149,7 @@ func TestSecretCreate(t *testing.T) { require.NoError(t, err, "Failed to get release with key %q", key) // compare created release with original - assert.Truef(t, reflect.DeepEqual(rel, got), "Expected {%v}, got {%v}", rel, got) + assert.Equalf(t, rel, got, "Expected {%v}, got {%v}", rel, got) } func TestSecretUpdate(t *testing.T) { @@ -195,7 +192,7 @@ func TestSecretDelete(t *testing.T) { // perform the delete rls, err := secrets.Delete(key) require.NoError(t, err, "Failed to delete release with key %q", key) - assert.Truef(t, reflect.DeepEqual(rel, rls), "Expected {%v}, got {%v}", rel, rls) + assert.Equalf(t, rel, rls, "Expected {%v}, got {%v}", rel, rls) _, err = secrets.Get(key) assert.ErrorIs(t, err, ErrReleaseNotFound) } diff --git a/pkg/storage/driver/sql_test.go b/pkg/storage/driver/sql_test.go index adcc780aa..044e9df7b 100644 --- a/pkg/storage/driver/sql_test.go +++ b/pkg/storage/driver/sql_test.go @@ -99,7 +99,7 @@ func TestSQLGet(t *testing.T) { got, err := sqlDriver.Get(key) require.NoError(t, err, "Failed to get release") - assert.Truef(t, reflect.DeepEqual(rel, got), "Expected release {%v}, got {%v}", rel, got) + assert.Equalf(t, rel, got, "Expected release {%v}, got {%v}", rel, got) assert.NoErrorf(t, mock.ExpectationsWereMet(), "sql expectations weren't met") } @@ -151,7 +151,7 @@ func TestSQLList(t *testing.T) { }) // check require.NoError(t, err, "Failed to list deleted") - assert.Len(t, del, 2, "Expected 2 deleted, got %d:\n%v\n", len(del), del) + assert.Len(t, del, 2, "Expected 2 deleted") // list all deployed releases dpl, err := sqlDriver.List(func(rel release.Releaser) bool { @@ -160,7 +160,7 @@ func TestSQLList(t *testing.T) { }) // check require.NoError(t, err, "Failed to list deployed") - assert.Len(t, dpl, 2, "Expected 2 deployed, got %d:\n%v\n", len(dpl), dpl) + assert.Len(t, dpl, 2, "Expected 2 deployed") // list all superseded releases ssd, err := sqlDriver.List(func(rel release.Releaser) bool { @@ -169,15 +169,13 @@ func TestSQLList(t *testing.T) { }) // check require.NoError(t, err, "Failed to list superseded") - assert.Len(t, ssd, 2, "Expected 2 superseded, got %d:\n%v\n", len(ssd), ssd) + require.Len(t, ssd, 2, "Expected 2 superseded") require.NoErrorf(t, mock.ExpectationsWereMet(), "sql expectations weren't met") // Check if release having both system and custom labels, this is needed to ensure that selector filtering would work. rls := convertReleaserToV1(t, ssd[0]) - _, ok := rls.Labels["name"] - require.True(t, ok, "Expected 'name' label in results, actual %v", rls.Labels) - _, ok = rls.Labels["key1"] - require.True(t, ok, "Expected 'key1' label in results, actual %v", rls.Labels) + require.Contains(t, rls.Labels, "name", "Expected 'name' label in results, actual %v", rls.Labels) + require.Contains(t, rls.Labels, "key1", "Expected 'key1' label in results, actual %v", rls.Labels) } func TestSqlCreate(t *testing.T) { @@ -414,18 +412,15 @@ func TestSqlQuery(t *testing.T) { require.NoError(t, err, "failed to query for deployed smug-pigeon release") for _, res := range results { - assert.Truef(t, reflect.DeepEqual(res, deployedRelease), "Expected release {%v}, got {%v}", deployedRelease, res) + assert.Equalf(t, res, deployedRelease, "Expected release {%v}, got {%v}", deployedRelease, res) } results, err = sqlDriver.Query(labelSetAll) require.NoError(t, err, "failed to query release history for smug-pigeon") - - assert.Len(t, results, 2, "expected a resultset of size 2, got %d", len(results)) + assert.Len(t, results, 2, "expected a resultset of size 2") for _, res := range results { - if !reflect.DeepEqual(res, deployedRelease) && !reflect.DeepEqual(res, supersededRelease) { - t.Errorf("Expected release {%v} or {%v}, got {%v}", deployedRelease, supersededRelease, res) - } + assert.False(t, !reflect.DeepEqual(res, deployedRelease) && !reflect.DeepEqual(res, supersededRelease), "Expected release {%v} or {%v}, got {%v}", deployedRelease, supersededRelease, res) } assert.NoErrorf(t, mock.ExpectationsWereMet(), "sql expectations weren't met") @@ -495,7 +490,7 @@ func TestSqlDelete(t *testing.T) { assert.NoErrorf(t, err, "sql expectations weren't met") require.NoError(t, err, "failed to delete release with key %q", key) - assert.Truef(t, reflect.DeepEqual(rel, deletedRelease), "Expected release {%v}, got {%v}", rel, deletedRelease) + assert.Equalf(t, rel, deletedRelease, "Expected release {%v}, got {%v}", rel, deletedRelease) } func mockGetReleaseCustomLabels(mock sqlmock.Sqlmock, key string, namespace string, labels map[string]string) { diff --git a/pkg/storage/storage_test.go b/pkg/storage/storage_test.go index 821eccb81..58cb56776 100644 --- a/pkg/storage/storage_test.go +++ b/pkg/storage/storage_test.go @@ -20,7 +20,6 @@ import ( "context" "errors" "log/slog" - "reflect" "testing" "github.com/stretchr/testify/assert" @@ -49,7 +48,7 @@ func TestStorageCreate(t *testing.T) { require.NoError(t, err, "QueryRelease") // verify the fetched and created release are the same - require.Truef(t, reflect.DeepEqual(rls, res), "Expected %v, got %v", rls, res) + require.Equalf(t, rls, res, "Expected %v, got %v", rls, res) } func TestStorageUpdate(t *testing.T) { @@ -74,7 +73,7 @@ func TestStorageUpdate(t *testing.T) { require.NoError(t, err, "QueryRelease") // verify updated and fetched releases are the same. - require.Truef(t, reflect.DeepEqual(rls, res), "Expected %v, got %v", rls, res) + require.Equalf(t, rls, res, "Expected %v, got %v", rls, res) } func TestStorageDelete(t *testing.T) { @@ -99,7 +98,7 @@ func TestStorageDelete(t *testing.T) { require.NoError(t, err, "DeleteRelease") // verify updated and fetched releases are the same. - require.Truef(t, reflect.DeepEqual(rls, res), "Expected %v, got %v", rls, res) + require.Equalf(t, rls, res, "Expected %v, got %v", rls, res) hist, err := storage.History(rls.Name) require.NoError(t, err) @@ -348,12 +347,12 @@ func TestStorageRemoveLeastRecent(t *testing.T) { require.NoError(t, err) rhist, err := releaseListToV1List(hist) require.NoError(t, err) - if len(rhist) != storage.MaxHistory { + if !assert.Len(t, rhist, storage.MaxHistory) { for _, item := range rhist { t.Logf("%s %v", item.Name, item.Version) } - t.Fatalf("expected %d items in history, got %d", storage.MaxHistory, len(rhist)) } + require.Len(t, rhist, storage.MaxHistory) // We expect the existing records to be 3, 4, and 5. for i, item := range rhist { @@ -392,14 +391,14 @@ func TestStorageDoNotDeleteDeployed(t *testing.T) { // (the only deployed release), to still exist hist, err := storage.History(name) require.NoError(t, err) - if len(hist) != storage.MaxHistory { + if !assert.Len(t, hist, storage.MaxHistory) { rhist, err := releaseListToV1List(hist) require.NoError(t, err) for _, item := range rhist { t.Logf("%s %v", item.Name, item.Version) } - t.Fatalf("expected %d items in history, got %d", storage.MaxHistory, len(rhist)) } + require.Len(t, hist, storage.MaxHistory) expectedVersions := map[int]bool{ 2: true, From 9a2be11e6f1af0c89dc0988b88fd339751baa44c Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Fri, 24 Jul 2026 13:24:06 +0200 Subject: [PATCH 54/61] chore(pkg): refactor: finer tests conversions to testify part 3 refactor: finer tests conversions to testify in pkg/cmd Signed-off-by: Matthieu MOREL --- pkg/action/install_test.go | 6 +- pkg/action/lint_test.go | 12 ++-- pkg/action/validate_test.go | 12 ++-- pkg/chart/common/util/coalesce_test.go | 12 ++-- pkg/chart/v2/lint/rules/chartfile_test.go | 7 +-- pkg/chart/v2/lint/rules/crds_test.go | 3 +- pkg/chart/v2/lint/rules/dependencies_test.go | 3 +- pkg/chart/v2/lint/support/message_test.go | 6 +- pkg/chart/v2/util/chartfile_test.go | 8 +-- pkg/chart/v2/util/create_test.go | 7 ++- pkg/chart/v2/util/dependencies_test.go | 2 +- pkg/cmd/completion_test.go | 13 ++--- pkg/cmd/repo_index_test.go | 4 +- pkg/cmd/repo_update_test.go | 6 +- pkg/cmd/rollback_test.go | 3 +- pkg/cmd/search_hub_test.go | 12 +--- pkg/cmd/show_test.go | 10 ++-- .../chart_downloader_windows_test.go | 14 ++--- pkg/engine/files_test.go | 9 +-- pkg/gates/gates_test.go | 2 +- pkg/getter/httpgetter_test.go | 18 +++--- pkg/kube/ready_test.go | 55 +++++++++++++++---- pkg/kube/resource_test.go | 6 +- pkg/kube/wait_test.go | 6 +- pkg/kubeenv/roundtripper_test.go | 9 ++- pkg/provenance/sign_test.go | 12 +--- pkg/pusher/ocipusher_test.go | 5 +- pkg/registry/chart_test.go | 6 +- pkg/registry/client_test.go | 4 +- pkg/registry/plugin_test.go | 7 +-- pkg/registry/registry_test.go | 14 ++--- pkg/release/v1/util/manifest_sorter_test.go | 1 - pkg/repo/v1/chartrepo_test.go | 8 +-- pkg/repo/v1/repo_test.go | 14 ++--- pkg/repo/v1/repotest/server_test.go | 9 +-- pkg/storage/driver/labels_test.go | 8 ++- pkg/storage/driver/records_test.go | 5 +- pkg/storage/driver/util_test.go | 7 +-- 38 files changed, 158 insertions(+), 187 deletions(-) diff --git a/pkg/action/install_test.go b/pkg/action/install_test.go index da680f41a..4dbeb7c79 100644 --- a/pkg/action/install_test.go +++ b/pkg/action/install_test.go @@ -420,9 +420,7 @@ func TestInstallRelease_WithChartAndDependencyAllNotes(t *testing.T) { req.NoError(err) is.Equal("with-notes", rel.Name) // test run can return as either 'parent\nchild' or 'child\nparent' - if !strings.Contains(rel.Info.Notes, "parent") && !strings.Contains(rel.Info.Notes, "child") { - t.Fatalf("Expected 'parent\nchild' or 'child\nparent', got '%s'", rel.Info.Notes) - } + req.True(strings.Contains(rel.Info.Notes, "parent") || strings.Contains(rel.Info.Notes, "child"), "Expected 'parent\nchild' or 'child\nparent', got '%s'", rel.Info.Notes) is.Equal("Install complete", rel.Info.Description) } @@ -1096,7 +1094,7 @@ func TestInstallCRDs(t *testing.T) { mockChart := buildChart(withFile(mockFile)) crdsToInstall := mockChart.CRDObjects() - assert.Len(t, crdsToInstall, 1) + require.Len(t, crdsToInstall, 1) assert.Equal(t, crdsToInstall[0].File.Data, mockFile.Data) require.NoError(t, instAction.installCRDs(crdsToInstall)) } diff --git a/pkg/action/lint_test.go b/pkg/action/lint_test.go index 5c956c682..f3fd994d7 100644 --- a/pkg/action/lint_test.go +++ b/pkg/action/lint_test.go @@ -106,10 +106,8 @@ func TestNonExistentChart(t *testing.T) { testLint := NewLint() result := testLint.Run(testCharts, values) - assert.Len(t, result.Errors, 1, "expected one error, but got", len(result.Errors)) - - actual := result.Errors[0].Error() - assert.EqualError(t, result.Errors[0], expectedError, "expected '%s', but got '%s'", expectedError, actual) + require.Len(t, result.Errors, 1, "expected one error, but got", len(result.Errors)) + assert.EqualError(t, result.Errors[0], expectedError) }) t.Run("should error out for corrupted tgz chart", func(t *testing.T) { @@ -118,10 +116,8 @@ func TestNonExistentChart(t *testing.T) { testLint := NewLint() result := testLint.Run(testCharts, values) - assert.Len(t, result.Errors, 1, "expected one error, but got", len(result.Errors)) - - actual := result.Errors[0].Error() - assert.EqualError(t, result.Errors[0], expectedEOFError, "expected '%s', but got '%s'", expectedEOFError, actual) + require.Len(t, result.Errors, 1, "expected one error, but got", len(result.Errors)) + assert.EqualError(t, result.Errors[0], expectedEOFError) }) } diff --git a/pkg/action/validate_test.go b/pkg/action/validate_test.go index 27097d177..8bd9f1916 100644 --- a/pkg/action/validate_test.go +++ b/pkg/action/validate_test.go @@ -132,7 +132,7 @@ func TestRequireAdoption(t *testing.T) { // Verify that a resource that lacks labels/annotations can be adopted found, err := requireAdoption(resources) require.NoError(t, err) - assert.Len(t, found, 1) + require.Len(t, found, 1) assert.Equal(t, found[0], existing) assert.NotSame(t, found[0], existing) } @@ -157,7 +157,7 @@ func TestExistingResourceConflict(t *testing.T) { // Verify only existing resources are returned found, err := existingResourceConflict(resources, releaseName, releaseNamespace) require.NoError(t, err) - assert.Len(t, found, 1) + require.Len(t, found, 1) assert.Equal(t, found[0], existing) assert.NotSame(t, found[0], existing) @@ -242,8 +242,8 @@ func TestVerifyOwnershipBeforeDelete(t *testing.T) { ownedList, unownedList, _, err := verifyOwnershipBeforeDelete(resources, releaseName, releaseNamespace) require.NoError(t, err) - assert.Len(t, ownedList, 1) - assert.Len(t, unownedList, 1) + require.Len(t, ownedList, 1) + require.Len(t, unownedList, 1) assert.Equal(t, "owned", ownedList[0].Name) assert.Equal(t, "unowned", unownedList[0].Name) }) @@ -290,8 +290,8 @@ func TestVerifyOwnershipBeforeDelete(t *testing.T) { ownedList, unownedList, _, err := verifyOwnershipBeforeDelete(resources, releaseName, releaseNamespace) require.NoError(t, err) - assert.Len(t, ownedList, 1) - assert.Len(t, unownedList, 1) + require.Len(t, ownedList, 1) + require.Len(t, unownedList, 1) assert.Equal(t, "owned", ownedList[0].Name) assert.Equal(t, "unowned", unownedList[0].Name) }) diff --git a/pkg/chart/common/util/coalesce_test.go b/pkg/chart/common/util/coalesce_test.go index 6ef092365..e058bd996 100644 --- a/pkg/chart/common/util/coalesce_test.go +++ b/pkg/chart/common/util/coalesce_test.go @@ -372,8 +372,7 @@ func TestMergeValues(t *testing.T) { assert.True(t, ok, "Expected nested boat key to be present but it was removed") subchart := v["pequod"].(map[string]any)["ahab"].(map[string]any) - _, ok = subchart["boat"] - assert.True(t, ok, "Expected subchart boat key to be present but it was removed") + assert.Contains(t, subchart, "boat", "Expected subchart boat key to be present but it was removed") _, ok = subchart["nested"].(map[string]any)["bar"] assert.True(t, ok, "Expected subchart nested bar key to be present but it was removed") @@ -526,8 +525,7 @@ func TestMergeTables(t *testing.T) { // This is one test that is different from CoalesceTables. Because hole // is a nil value and it's not removed it's still present. - _, ok = dst["hole"] - assert.True(t, ok, "The hole no longer exists.") + assert.Contains(t, dst, "hole", "The hole no longer exists.") dst2 := map[string]any{ "name": "Ishmael", @@ -559,8 +557,7 @@ func TestMergeTables(t *testing.T) { det2, ok := dst2["details"].(map[string]any) require.Truef(t, ok, "Details is the wrong type: %v", dst2["details"]) - _, ok = det2["friends"] - assert.True(t, ok, "Could not find your friends. Maybe you don't have any. :-(") + assert.Contains(t, det2, "friends", "Could not find your friends. Maybe you don't have any. :-(") assert.Equal(t, "pequod", dst2["boat"].(string), "Expected boat string, got %v", dst2["boat"]) assert.Equal(t, "black", dst2["hole"].(string), "Expected hole string, got %v", dst2["hole"]) assert.Nil(t, dst2["nilval"], "Expected nilvalue to have nil value but it does not") @@ -659,8 +656,7 @@ func TestCoalesceValuesEmptyMapWithNils(t *testing.T) { is.Equal("bar", data["foo"]) // "baz" should be preserved with nil value since it wasn't in chart defaults - _, ok = data["baz"] - is.True(ok, "Expected data.baz key to be present but it was removed") + is.Contains(data, "baz", "Expected data.baz key to be present but it was removed") is.Nil(data["baz"], "Expected data.baz key to be nil but it is not") } diff --git a/pkg/chart/v2/lint/rules/chartfile_test.go b/pkg/chart/v2/lint/rules/chartfile_test.go index 7c9f1c422..1cc331a74 100644 --- a/pkg/chart/v2/lint/rules/chartfile_test.go +++ b/pkg/chart/v2/lint/rules/chartfile_test.go @@ -195,7 +195,6 @@ func TestChartfile(t *testing.T) { expectedNumberOfErrorMessages := 7 require.Lenf(t, msgs, expectedNumberOfErrorMessages, "Expected %d errors, got %d", expectedNumberOfErrorMessages, len(msgs)) - require.ErrorContains(t, msgs[0].Err, "name is required", "Unexpected message 0: %s", msgs[0].Err) require.ErrorContains(t, msgs[1].Err, "apiVersion is required. The value must be either \"v1\" or \"v2\"", "Unexpected message 1: %s", msgs[1].Err) require.ErrorContains(t, msgs[2].Err, "version '0.0.0.0' is not a valid SemVer", "Unexpected message 2: %s", msgs[2].Err) @@ -211,11 +210,7 @@ func TestChartfile(t *testing.T) { msgs := linter.Messages expectedNumberOfErrorMessages := 4 - if len(msgs) != expectedNumberOfErrorMessages { - t.Errorf("Expected %d errors, got %d", expectedNumberOfErrorMessages, len(msgs)) - return - } - + require.Len(t, msgs, expectedNumberOfErrorMessages, "Expected %d errors, got %d", expectedNumberOfErrorMessages, len(msgs)) require.ErrorContains(t, msgs[0].Err, "version should be of type string", "Unexpected message 0: %s", msgs[0].Err) require.ErrorContains(t, msgs[1].Err, "version '7.2445e+06' is not a valid SemVer", "Unexpected message 1: %s", msgs[1].Err) require.ErrorContains(t, msgs[2].Err, "appVersion should be of type string", "Unexpected message 2: %s", msgs[2].Err) diff --git a/pkg/chart/v2/lint/rules/crds_test.go b/pkg/chart/v2/lint/rules/crds_test.go index 7016c4d9a..d0790692f 100644 --- a/pkg/chart/v2/lint/rules/crds_test.go +++ b/pkg/chart/v2/lint/rules/crds_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "helm.sh/helm/v4/pkg/chart/v2/lint/support" ) @@ -33,7 +34,7 @@ func TestInvalidCrdsDir(t *testing.T) { Crds(&linter) res := linter.Messages - assert.Len(t, res, 1) + require.Len(t, res, 1) assert.ErrorContains(t, res[0].Err, "not a directory") } diff --git a/pkg/chart/v2/lint/rules/dependencies_test.go b/pkg/chart/v2/lint/rules/dependencies_test.go index c800887bd..4bd7b3e37 100644 --- a/pkg/chart/v2/lint/rules/dependencies_test.go +++ b/pkg/chart/v2/lint/rules/dependencies_test.go @@ -140,8 +140,7 @@ func TestDependencies(t *testing.T) { linter := support.Linter{ChartDir: filepath.Join(tmp, c.Metadata.Name)} Dependencies(&linter) - if l := len(linter.Messages); l != 2 { - t.Errorf("expected 2 linter errors for bad chart dependencies. Got %d.", l) + if !assert.Len(t, linter.Messages, 2, "expected 2 linter errors for bad chart dependencies") { for i, msg := range linter.Messages { t.Logf("Message: %d, Error: %#v", i, msg) } diff --git a/pkg/chart/v2/lint/support/message_test.go b/pkg/chart/v2/lint/support/message_test.go index dfbc65844..6d09df688 100644 --- a/pkg/chart/v2/lint/support/message_test.go +++ b/pkg/chart/v2/lint/support/message_test.go @@ -58,11 +58,11 @@ func TestRunLinterRule(t *testing.T) { func TestMessage(t *testing.T) { m := Message{ErrorSev, "Chart.yaml", errors.New("Foo")} - require.EqualErrorf(t, m, "[ERROR] Chart.yaml: Foo", "Unexpected output: %s", m.Error()) + require.EqualError(t, m, "[ERROR] Chart.yaml: Foo") m = Message{WarningSev, "templates/", errors.New("Bar")} - require.EqualErrorf(t, m, "[WARNING] templates/: Bar", "Unexpected output: %s", m.Error()) + require.EqualError(t, m, "[WARNING] templates/: Bar") m = Message{InfoSev, "templates/rc.yaml", errors.New("FooBar")} - assert.EqualErrorf(t, m, "[INFO] templates/rc.yaml: FooBar", "Unexpected output: %s", m.Error()) + assert.EqualError(t, m, "[INFO] templates/rc.yaml: FooBar") } diff --git a/pkg/chart/v2/util/chartfile_test.go b/pkg/chart/v2/util/chartfile_test.go index bdcb506da..981d0e131 100644 --- a/pkg/chart/v2/util/chartfile_test.go +++ b/pkg/chart/v2/util/chartfile_test.go @@ -49,12 +49,8 @@ func verifyChartfile(t *testing.T, f *chart.Metadata, name string) { assert.Equal(t, "https://example.com/64x64.png", f.Icon, "Unexpected icon: %q", f.Icon) assert.Len(t, f.Keywords, 3, "Unexpected keywords") require.Len(t, f.Annotations, 2, "Unexpected annotations") - - want, got := "extravalue", f.Annotations["extrakey"] - assert.Equalf(t, want, got, "Want %q, but got %q", want, got) - - want, got = "anothervalue", f.Annotations["anotherkey"] - assert.Equalf(t, want, got, "Want %q, but got %q", want, got) + assert.Equal(t, "extravalue", f.Annotations["extrakey"]) + assert.Equal(t, "anothervalue", f.Annotations["anotherkey"]) kk := []string{"frobnitz", "sprocket", "dodad"} for i, k := range f.Keywords { diff --git a/pkg/chart/v2/util/create_test.go b/pkg/chart/v2/util/create_test.go index c85c4e3d4..69ba1336d 100644 --- a/pkg/chart/v2/util/create_test.go +++ b/pkg/chart/v2/util/create_test.go @@ -138,8 +138,11 @@ func TestValidateChartName(t *testing.T) { "abcdefghijklmnopqrstuvwxyz-_." + "ABCDEFGHIJKLMNOPQRSTUVWXYZ-_.": false, } { - if err := validateChartName(name); (err != nil) == shouldPass { - t.Errorf("test for %q failed", name) + err := validateChartName(name) + if shouldPass { + assert.NoError(t, err) + } else { + assert.Error(t, err) } } } diff --git a/pkg/chart/v2/util/dependencies_test.go b/pkg/chart/v2/util/dependencies_test.go index 2386d2c28..097663783 100644 --- a/pkg/chart/v2/util/dependencies_test.go +++ b/pkg/chart/v2/util/dependencies_test.go @@ -43,7 +43,7 @@ func TestLoadDependency(t *testing.T) { } check := func(deps []*chart.Dependency) { - assert.Len(t, deps, 2, "expected 2 dependencies, got %d", len(deps)) + require.Len(t, deps, 2, "expected 2 dependencies, got %d", len(deps)) for i, tt := range tests { assert.Equal(t, tt.Name, deps[i].Name, "expected dependency named %q, got %q", tt.Name, deps[i].Name) assert.Equal(t, tt.Version, deps[i].Version, "expected dependency named %q to have version %q, got %q", tt.Name, tt.Version, deps[i].Version) diff --git a/pkg/cmd/completion_test.go b/pkg/cmd/completion_test.go index 219d1eed0..296ae457e 100644 --- a/pkg/cmd/completion_test.go +++ b/pkg/cmd/completion_test.go @@ -18,9 +18,9 @@ package cmd import ( "fmt" - "strings" "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" chart "helm.sh/helm/v4/pkg/chart/v2" @@ -47,13 +47,10 @@ func checkFileCompletion(t *testing.T, cmdName string, shouldBePerformed bool) { testcmd := fmt.Sprintf("__complete %s ''", cmdName) _, out, err := executeActionCommandC(storage, testcmd) require.NoError(t, err) - if !strings.Contains(out, "ShellCompDirectiveNoFileComp") != shouldBePerformed { - if shouldBePerformed { - t.Errorf("Unexpected directive ShellCompDirectiveNoFileComp when completing '%s'", cmdName) - } else { - t.Errorf("Did not receive directive ShellCompDirectiveNoFileComp when completing '%s'", cmdName) - } - t.Log(out) + if shouldBePerformed { + assert.NotContains(t, out, "ShellCompDirectiveNoFileComp", "Unexpected directive ShellCompDirectiveNoFileComp when completing '%s'", cmdName) + } else { + assert.Contains(t, out, "ShellCompDirectiveNoFileComp", "Did not receive directive ShellCompDirectiveNoFileComp when completing '%s'", cmdName) } } diff --git a/pkg/cmd/repo_index_test.go b/pkg/cmd/repo_index_test.go index 30700749b..67984f3b7 100644 --- a/pkg/cmd/repo_index_test.go +++ b/pkg/cmd/repo_index_test.go @@ -48,10 +48,10 @@ func TestRepoIndexCmd(t *testing.T) { index, err := repo.LoadIndexFile(destIndex) require.NoError(t, err) - assert.Len(t, index.Entries, 1, "expected 1 entry, got %d: %#v", len(index.Entries), index.Entries) + require.Len(t, index.Entries, 1, "expected 1 entry, got %d: %#v", len(index.Entries), index.Entries) vs := index.Entries["compressedchart"] - assert.Len(t, vs, 2, "expected 2 versions, got %d: %#v", len(vs), vs) + require.Len(t, vs, 2, "expected 2 versions") expectedVersion := "0.2.0" assert.Equal(t, expectedVersion, vs[0].Version, "expected %q, got %q", expectedVersion, vs[0].Version) diff --git a/pkg/cmd/repo_update_test.go b/pkg/cmd/repo_update_test.go index ccd8b89c6..70b6dfbef 100644 --- a/pkg/cmd/repo_update_test.go +++ b/pkg/cmd/repo_update_test.go @@ -174,10 +174,8 @@ func TestUpdateChartsFailWithError(t *testing.T) { b := bytes.NewBuffer(nil) err = updateCharts([]*repo.ChartRepository{r1, r2}, b) require.Error(t, err, "Repo update should return error because update of repository fails and 'fail-on-repo-update-fail' flag set") - var expectedErr = "failed to update the following repositories" - var receivedErr = err.Error() - require.ErrorContains(t, err, expectedErr, "Expected error (%s) but got (%s) instead", expectedErr, receivedErr) - require.ErrorContains(t, err, invalidURL, "Expected invalid URL (%s) in error message but got (%s) instead", invalidURL, receivedErr) + require.ErrorContains(t, err, "failed to update the following repositories") + require.ErrorContains(t, err, invalidURL) got := b.String() assert.Contains(t, got, "Unable to get an update", "Repo should have failed update but instead got: %q", got) diff --git a/pkg/cmd/rollback_test.go b/pkg/cmd/rollback_test.go index ff7f314c9..aa60043aa 100644 --- a/pkg/cmd/rollback_test.go +++ b/pkg/cmd/rollback_test.go @@ -18,7 +18,6 @@ package cmd import ( "fmt" - "reflect" "testing" "github.com/stretchr/testify/assert" @@ -161,5 +160,5 @@ func TestRollbackWithLabels(t *testing.T) { updatedRel, err := releaserToV1Release(updatedReli) require.NoError(t, err) - assert.Truef(t, reflect.DeepEqual(updatedRel.Labels, labels1), "Expected {%v}, got {%v}", labels1, updatedRel.Labels) + assert.Equalf(t, updatedRel.Labels, labels1, "Expected {%v}, got {%v}", labels1, updatedRel.Labels) } diff --git a/pkg/cmd/search_hub_test.go b/pkg/cmd/search_hub_test.go index 7b00cc295..a1612443a 100644 --- a/pkg/cmd/search_hub_test.go +++ b/pkg/cmd/search_hub_test.go @@ -46,11 +46,7 @@ func TestSearchHubCmd(t *testing.T) { storage := storageFixture() _, out, err := executeActionCommandC(storage, testcmd) require.NoError(t, err) - if out != expected { - t.Error("expected and actual output did not match") - t.Log(out) - t.Log(expected) - } + assert.Equal(t, expected, out, "expected and actual output did not match") } func TestSearchHubListRepoCmd(t *testing.T) { @@ -73,11 +69,7 @@ func TestSearchHubListRepoCmd(t *testing.T) { storage := storageFixture() _, out, err := executeActionCommandC(storage, testcmd) require.NoError(t, err) - if out != expected { - t.Error("expected and actual output did not match") - t.Log(out) - t.Log(expected) - } + assert.Equal(t, expected, out, "expected and actual output did not match") } func TestSearchHubOutputCompletion(t *testing.T) { diff --git a/pkg/cmd/show_test.go b/pkg/cmd/show_test.go index 3ed01d418..b7ad94d94 100644 --- a/pkg/cmd/show_test.go +++ b/pkg/cmd/show_test.go @@ -77,12 +77,10 @@ func TestShowPreReleaseChart(t *testing.T) { contentTmp, ) _, _, err := executeActionCommand(cmd) - if err != nil { - if tt.fail { - assert.ErrorContains(t, err, tt.expectedErr, "%q expected error: %s, got: %s", tt.name, tt.expectedErr, err.Error()) - return - } - t.Errorf("%q reported error: %s", tt.name, err) + if tt.fail { + assert.ErrorContains(t, err, tt.expectedErr, "%q expected error: %s, got: %s", tt.name, tt.expectedErr, err.Error()) + } else { + assert.NoError(t, err) } }) } diff --git a/pkg/downloader/chart_downloader_windows_test.go b/pkg/downloader/chart_downloader_windows_test.go index 2b6bea5eb..0c7a23d23 100644 --- a/pkg/downloader/chart_downloader_windows_test.go +++ b/pkg/downloader/chart_downloader_windows_test.go @@ -99,10 +99,8 @@ func TestParallelDownloadTo(t *testing.T) { // Verify the file has the expected size (should match the source file) sourceFile := "testdata/local-subchart-0.1.0.tgz" sourceInfo, err := os.Stat(sourceFile) - if err == nil && info.Size() != sourceInfo.Size() { - t.Errorf("Downloaded file size (%d bytes) doesn't match source file size (%d bytes)", - info.Size(), sourceInfo.Size()) - } + require.NoError(t, err) + assert.False(t, info.Size() != sourceInfo.Size(), "Downloaded file size doesn't match source file size") // Verify it's a valid tar.gz file by checking the magic bytes file, err := os.Open(expectedFile) @@ -110,10 +108,10 @@ func TestParallelDownloadTo(t *testing.T) { defer file.Close() // gzip magic bytes are 0x1f 0x8b magic := make([]byte, 2) - if n, err := file.Read(magic); err == nil && n == 2 { - if magic[0] != 0x1f || magic[1] != 0x8b { - t.Errorf("Downloaded file is not a valid gzip file (magic bytes: %x)", magic) - } + n, err := file.Read(magic) + require.NoError(t, err) + if n == 2 { + assert.False(t, magic[0] != 0x1f || magic[1] != 0x8b, "Downloaded file is not a valid gzip file (magic bytes: %x)", magic) } } diff --git a/pkg/engine/files_test.go b/pkg/engine/files_test.go index 6ff251aad..9fec2e132 100644 --- a/pkg/engine/files_test.go +++ b/pkg/engine/files_test.go @@ -16,6 +16,7 @@ limitations under the License. package engine import ( + "strconv" "testing" "github.com/stretchr/testify/assert" @@ -47,10 +48,10 @@ func TestNewFiles(t *testing.T) { assert.Len(t, files, len(cases), "Expected len() = %d, got %d", len(cases), len(files)) for i, f := range cases { - got := string(files.GetBytes(f.path)) - assert.Equalf(t, got, f.data, "%d: expected %q, got %q", i, f.data, got) - got = files.Get(f.path) - assert.Equalf(t, got, f.data, "%d: expected %q, got %q", i, f.data, got) + t.Run(strconv.Itoa(i), func(t *testing.T) { + assert.Equal(t, f.data, string(files.GetBytes(f.path))) + assert.Equal(t, f.data, files.Get(f.path)) + }) } } diff --git a/pkg/gates/gates_test.go b/pkg/gates/gates_test.go index 217ee1bbe..e57f1aa8f 100644 --- a/pkg/gates/gates_test.go +++ b/pkg/gates/gates_test.go @@ -38,7 +38,7 @@ func TestError(t *testing.T) { os.Unsetenv(name) g := Gate(name) - assert.Equal(t, "this feature has been marked as experimental and is not enabled by default. Please set HELM_EXPERIMENTAL_FEATURE=1 in your environment to use this feature", g.Error().Error()) + assert.EqualError(t, g.Error(), "this feature has been marked as experimental and is not enabled by default. Please set HELM_EXPERIMENTAL_FEATURE=1 in your environment to use this feature") } func TestString(t *testing.T) { diff --git a/pkg/getter/httpgetter_test.go b/pkg/getter/httpgetter_test.go index bfde5efa8..aebb6f11c 100644 --- a/pkg/getter/httpgetter_test.go +++ b/pkg/getter/httpgetter_test.go @@ -122,9 +122,9 @@ func TestDownload(t *testing.T) { const expectedUserAgent = "I am Groot" basicAuthSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { username, password, ok := r.BasicAuth() - if !ok || username != "username" || password != "password" { - t.Errorf("Expected request to use basic auth and for username == 'username' and password == 'password', got '%v', '%s', '%s'", ok, username, password) - } + assert.True(t, ok, "Expected request to use basic auth") + assert.Equal(t, "username", username) + assert.Equal(t, "password", password) assert.Equal(t, expectedUserAgent, r.UserAgent(), "Expected '%s', got '%s'", expectedUserAgent, r.UserAgent()) fmt.Fprint(w, expect) })) @@ -147,9 +147,9 @@ func TestDownload(t *testing.T) { // test with Get URL differing from withURL crossAuthSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { username, password, ok := r.BasicAuth() - if ok || username == "username" || password == "password" { - t.Errorf("Expected request to not include but got '%v', '%s', '%s'", ok, username, password) - } + assert.False(t, ok) + assert.NotEqual(t, "username", username) + assert.NotEqual(t, "password", password) fmt.Fprint(w, expect) })) @@ -176,9 +176,9 @@ func TestDownload(t *testing.T) { // test with Get URL differing from withURL and should pass creds crossAuthSrv = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { username, password, ok := r.BasicAuth() - if !ok || username != "username" || password != "password" { - t.Errorf("Expected request to use basic auth and for username == 'username' and password == 'password', got '%v', '%s', '%s'", ok, username, password) - } + assert.True(t, ok, "Expected request to use basic auth") + assert.Equal(t, "username", username) + assert.Equal(t, "password", password) fmt.Fprint(w, expect) })) diff --git a/pkg/kube/ready_test.go b/pkg/kube/ready_test.go index 01f6db3cb..c40ad1d4d 100644 --- a/pkg/kube/ready_test.go +++ b/pkg/kube/ready_test.go @@ -165,7 +165,11 @@ func Test_ReadyChecker_IsReady_Job(t *testing.T) { require.NoError(t, err, "Failed to create Job") got, err := c.IsReady(tt.args.ctx, tt.args.resource) - assert.Equal(t, tt.wantErr, (err != nil), "IsReady() error = %v, wantErr %v", err, tt.wantErr) + if tt.wantErr { + require.Error(t, err, "IsReady()") + } else { + require.NoError(t, err, "IsReady()") + } assert.Equal(t, tt.want, got, "IsReady() = %v, want %v", got, tt.want) }) } @@ -237,7 +241,11 @@ func Test_ReadyChecker_IsReady_Deployment(t *testing.T) { require.NoError(t, err, "Failed to create ReplicaSet") got, err := c.IsReady(tt.args.ctx, tt.args.resource) - assert.Equal(t, tt.wantErr, (err != nil), "IsReady() error = %v, wantErr %v", err, tt.wantErr) + if tt.wantErr { + require.Error(t, err, "IsReady()") + } else { + require.NoError(t, err, "IsReady()") + } assert.Equal(t, tt.want, got, "IsReady() = %v, want %v", got, tt.want) }) } @@ -303,7 +311,11 @@ func Test_ReadyChecker_IsReady_PersistentVolumeClaim(t *testing.T) { require.NoError(t, err, "Failed to create PersistentVolumeClaim") got, err := c.IsReady(tt.args.ctx, tt.args.resource) - assert.Equal(t, tt.wantErr, (err != nil), "IsReady() error = %v, wantErr %v", err, tt.wantErr) + if tt.wantErr { + require.Error(t, err, "IsReady()") + } else { + require.NoError(t, err, "IsReady()") + } assert.Equal(t, tt.want, got, "IsReady() = %v, want %v", got, tt.want) }) } @@ -369,7 +381,11 @@ func Test_ReadyChecker_IsReady_Service(t *testing.T) { require.NoError(t, err, "Failed to create Service") got, err := c.IsReady(tt.args.ctx, tt.args.resource) - assert.Equal(t, tt.wantErr, (err != nil), "IsReady() error = %v, wantErr %v", err, tt.wantErr) + if tt.wantErr { + require.Error(t, err, "IsReady()") + } else { + require.NoError(t, err, "IsReady()") + } assert.Equal(t, tt.want, got, "IsReady() = %v, want %v", got, tt.want) }) } @@ -435,7 +451,11 @@ func Test_ReadyChecker_IsReady_DaemonSet(t *testing.T) { require.NoError(t, err, "Failed to create DaemonSet") got, err := c.IsReady(tt.args.ctx, tt.args.resource) - assert.Equal(t, tt.wantErr, (err != nil), "IsReady() error = %v, wantErr %v", err, tt.wantErr) + if tt.wantErr { + require.Error(t, err, "IsReady()") + } else { + require.NoError(t, err, "IsReady()") + } assert.Equal(t, tt.want, got, "IsReady() = %v, want %v", got, tt.want) }) } @@ -501,7 +521,11 @@ func Test_ReadyChecker_IsReady_StatefulSet(t *testing.T) { require.NoError(t, err, "Failed to create StatefulSet") got, err := c.IsReady(tt.args.ctx, tt.args.resource) - assert.Equal(t, tt.wantErr, (err != nil), "IsReady() error = %v, wantErr %v", err, tt.wantErr) + if tt.wantErr { + require.Error(t, err, "IsReady()") + } else { + require.NoError(t, err, "IsReady()") + } assert.Equal(t, tt.want, got, "IsReady() = %v, want %v", got, tt.want) }) } @@ -582,7 +606,11 @@ func Test_ReadyChecker_IsReady_ReplicationController(t *testing.T) { require.NoError(t, err, "Failed to create ReplicationController") got, err := c.IsReady(tt.args.ctx, tt.args.resource) - assert.Equal(t, tt.wantErr, (err != nil), "IsReady() error = %v, wantErr %v", err, tt.wantErr) + if tt.wantErr { + require.Error(t, err, "IsReady()") + } else { + require.NoError(t, err, "IsReady()") + } assert.Equal(t, tt.want, got, "IsReady() = %v, want %v", got, tt.want) }) } @@ -646,7 +674,11 @@ func Test_ReadyChecker_IsReady_ReplicaSet(t *testing.T) { } // got, err := c.IsReady(tt.args.ctx, tt.args.resource) - assert.Equal(t, tt.wantErr, (err != nil), "IsReady() error = %v, wantErr %v", err, tt.wantErr) + if tt.wantErr { + require.Error(t, err, "IsReady()") + } else { + require.NoError(t, err, "IsReady()") + } assert.Equal(t, tt.want, got, "IsReady() = %v, want %v", got, tt.want) }) } @@ -1044,9 +1076,10 @@ func Test_ReadyChecker_jobReady(t *testing.T) { t.Run(tt.name, func(t *testing.T) { c := NewReadyChecker(fake.NewClientset()) got, err := c.jobReady(tt.args.job) - if (err != nil) != tt.wantErr { - t.Errorf("jobReady() error = %v, wantErr %v", err, tt.wantErr) - return + if tt.wantErr { + require.Error(t, err, "jobReady()") + } else { + require.NoError(t, err, "jobReady()") } assert.Equal(t, tt.want, got, "jobReady() = %v, want %v", got, tt.want) }) diff --git a/pkg/kube/resource_test.go b/pkg/kube/resource_test.go index ca41a06ed..18501d4e8 100644 --- a/pkg/kube/resource_test.go +++ b/pkg/kube/resource_test.go @@ -42,13 +42,11 @@ func TestResourceList(t *testing.T) { diff := r1.Difference(r2) assert.Len(t, diff, 1, "expected 1 result") - - assert.True(t, diff.Contains(info("foo")), "expected diff to return foo") + assert.Contains(t, diff, info("foo"), "expected diff to return foo") inter := r1.Intersect(r2) assert.Len(t, inter, 1, "expected 1 result") - - assert.True(t, inter.Contains(info("bar")), "expected intersect to return bar") + assert.Contains(t, inter, info("bar"), "expected intersect to return bar") } func TestIsMatchingInfo(t *testing.T) { diff --git a/pkg/kube/wait_test.go b/pkg/kube/wait_test.go index 9cf1e5506..d33a12c87 100644 --- a/pkg/kube/wait_test.go +++ b/pkg/kube/wait_test.go @@ -297,8 +297,7 @@ func TestLegacyWaiter_waitForPodSuccess(t *testing.T) { t.Run(tt.name, func(t *testing.T) { done, err := lw.waitForPodSuccess(tt.obj, "foo") if tt.wantErr { - require.Error(t, err, "expected error, got none") - require.ErrorContains(t, err, tt.errMessage, "expected error to contain %q, got %q", tt.errMessage, err.Error()) + require.ErrorContains(t, err, tt.errMessage) } else { require.NoError(t, err) } @@ -384,8 +383,7 @@ func TestLegacyWaiter_waitForJob(t *testing.T) { t.Run(tt.name, func(t *testing.T) { done, err := lw.waitForJob(tt.obj, "test-job") if tt.wantErr { - require.Error(t, err, "expected error, got none") - require.ErrorContainsf(t, err, tt.errMessage, "expected error to contain %q, got %q", tt.errMessage, err.Error()) + require.ErrorContains(t, err, tt.errMessage) } else { require.NoError(t, err) assert.Equal(t, tt.wantDone, done, "got done=%v, want %v", done, tt.wantDone) diff --git a/pkg/kubeenv/roundtripper_test.go b/pkg/kubeenv/roundtripper_test.go index 6f0caf6f8..8d5b80e39 100644 --- a/pkg/kubeenv/roundtripper_test.go +++ b/pkg/kubeenv/roundtripper_test.go @@ -141,12 +141,11 @@ func TestRetryingRoundTripper_RoundTrip(t *testing.T) { if tt.expectedErr != "" { require.ErrorContains(t, err, tt.expectedErr) - return + } else { + require.NoError(t, err) + assert.Equal(t, tt.expectedCode, resp.StatusCode) + assert.Equal(t, tt.expectedCalls, fakeRT.calls) } - require.NoError(t, err) - - assert.Equal(t, tt.expectedCode, resp.StatusCode) - assert.Equal(t, tt.expectedCalls, fakeRT.calls) }) } } diff --git a/pkg/provenance/sign_test.go b/pkg/provenance/sign_test.go index 32253df90..ec6e6194b 100644 --- a/pkg/provenance/sign_test.go +++ b/pkg/provenance/sign_test.go @@ -128,9 +128,7 @@ func TestParseMessageBlock(t *testing.T) { func TestLoadKey(t *testing.T) { k, err := loadKey(testKeyfile) require.NoError(t, err) - - _, ok := k.Identities[testKeyName] - assert.Truef(t, ok, "Expected to load a key for user %q", testKeyName) + assert.Containsf(t, k.Identities, testKeyName, "Expected to load a key for user %q", testKeyName) } func TestLoadKeyRing(t *testing.T) { @@ -163,8 +161,7 @@ func TestNewFromFiles(t *testing.T) { s, err := NewFromFiles(testKeyfile, testPubfile) require.NoError(t, err) - _, ok := s.Entity.Identities[testKeyName] - assert.Truef(t, ok, "Expected to load a key for user %q", testKeyName) + assert.Containsf(t, s.Entity.Identities, testKeyName, "Expected to load a key for user %q", testKeyName) } func TestDigestFile(t *testing.T) { @@ -240,7 +237,6 @@ func TestMixedKeyringRSASigningAndVerification(t *testing.T) { } assert.True(t, hasEdDSA, "expected %s to include an Ed25519 public key", testMixedKeyring) - require.NotNil(t, signer.Entity, "expected signer entity to be loaded") require.NotNil(t, signer.Entity.PrivateKey, "expected signer private key to be loaded") assert.Equal(t, packet.PubKeyAlgoRSA, signer.Entity.PrivateKey.PubKeyAlgo, "expected RSA key") @@ -259,9 +255,7 @@ func TestMixedKeyringRSASigningAndVerification(t *testing.T) { require.NotNil(t, verification.SignedBy, "expected verification to include signer") require.NotNil(t, verification.SignedBy.PrimaryKey, "expected verification to include signer primary key") assert.Equal(t, packet.PubKeyAlgoRSA, verification.SignedBy.PrimaryKey.PubKeyAlgo, "expected verification to report RSA key") - - _, ok := verification.SignedBy.Identities[testKeyName] - assert.True(t, ok, "expected verification to be signed by %q", testKeyName) + assert.Contains(t, verification.SignedBy.Identities, testKeyName, "expected verification to be signed by %q", testKeyName) } // failSigner always fails to sign and returns an error diff --git a/pkg/pusher/ocipusher_test.go b/pkg/pusher/ocipusher_test.go index ceb61d442..b63077293 100644 --- a/pkg/pusher/ocipusher_test.go +++ b/pkg/pusher/ocipusher_test.go @@ -33,8 +33,7 @@ func TestNewOCIPusher(t *testing.T) { p, err := NewOCIPusher() require.NoError(t, err) - _, ok := p.(*OCIPusher) - require.True(t, ok, "Expected NewOCIPusher to produce an *OCIPusher") + require.IsType(t, &OCIPusher{}, p, "Expected NewOCIPusher to produce an *OCIPusher") cd := "../../testdata" join := filepath.Join @@ -196,7 +195,7 @@ func TestOCIPusher_newRegistryClient(t *testing.T) { if tt.expectError { require.Error(t, err, "Expected error but got none") if tt.errorContains != "" { - require.ErrorContainsf(t, err, tt.errorContains, "Expected error containing %q, got %q", tt.errorContains, err.Error()) + require.ErrorContains(t, err, tt.errorContains) } } else { require.NoError(t, err) diff --git a/pkg/registry/chart_test.go b/pkg/registry/chart_test.go index 95e429a0b..3edf21e38 100644 --- a/pkg/registry/chart_test.go +++ b/pkg/registry/chart_test.go @@ -232,8 +232,7 @@ func TestGenerateOCICreatedAnnotations(t *testing.T) { result := generateOCIAnnotations(testChart, nowTimeString) // Check that created annotation exists - _, ok := result[ocispec.AnnotationCreated] - assert.True(t, ok, "%s annotation not created", ocispec.AnnotationCreated) + assert.Contains(t, result, ocispec.AnnotationCreated, "%s annotation not created", ocispec.AnnotationCreated) // Verify value of created artifact in RFC3339 format _, err := time.Parse(time.RFC3339, result[ocispec.AnnotationCreated]) @@ -243,8 +242,7 @@ func TestGenerateOCICreatedAnnotations(t *testing.T) { result = generateOCIAnnotations(testChart, "") // Check that created annotation exists - _, ok = result[ocispec.AnnotationCreated] - require.True(t, ok, "%s annotation not created", ocispec.AnnotationCreated) + require.Contains(t, result, ocispec.AnnotationCreated, "%s annotation not created", ocispec.AnnotationCreated) createdTimeAnnotation, err := time.Parse(time.RFC3339, result[ocispec.AnnotationCreated]) require.NoError(t, err, "%s annotation with value '%s' not in RFC3339 format", ocispec.AnnotationCreated, result[ocispec.AnnotationCreated]) diff --git a/pkg/registry/client_test.go b/pkg/registry/client_test.go index 97b7c7c4c..21604ce7e 100644 --- a/pkg/registry/client_test.go +++ b/pkg/registry/client_test.go @@ -65,9 +65,9 @@ func TestLogin_ResetsForceAttemptOAuth2_OnSuccess(t *testing.T) { if r.URL.Path == "/v2/" { // Accept either HEAD or GET w.WriteHeader(http.StatusOK) - return + } else { + http.NotFound(w, r) } - http.NotFound(w, r) })) defer srv.Close() diff --git a/pkg/registry/plugin_test.go b/pkg/registry/plugin_test.go index bb557c5b8..d51cfa0d6 100644 --- a/pkg/registry/plugin_test.go +++ b/pkg/registry/plugin_test.go @@ -78,11 +78,10 @@ func TestGetPluginName(t *testing.T) { if tt.expectErr { assert.Error(t, err, "expected error but got none") - return + } else { + require.NoError(t, err) + assert.Equal(t, tt.expected, pluginName) } - - require.NoError(t, err) - assert.Equal(t, tt.expected, pluginName) }) } } diff --git a/pkg/registry/registry_test.go b/pkg/registry/registry_test.go index 313cb861c..40ebe9687 100644 --- a/pkg/registry/registry_test.go +++ b/pkg/registry/registry_test.go @@ -376,23 +376,21 @@ func initFakeRegistryTestServer() string { if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) - return + } else { + w.Header().Set("Content-Type", ProvLayerMediaType) + w.Write(data) } - w.Header().Set("Content-Type", ProvLayerMediaType) - w.Write(data) - case "/v2/testrepo/image-index/blobs/sha256:e5ef611620fb97704d8751c16bab17fedb68883bfb0edc76f78a70e9173f9b55": data, err := os.ReadFile("../downloader/testdata/signtest-0.1.0.tgz") if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) - return + } else { + w.Header().Set("Content-Type", ChartLayerMediaType) + w.Write(data) } - w.Header().Set("Content-Type", ChartLayerMediaType) - w.Write(data) - default: w.WriteHeader(http.StatusNotFound) } diff --git a/pkg/release/v1/util/manifest_sorter_test.go b/pkg/release/v1/util/manifest_sorter_test.go index 35c7a0721..da08ab169 100644 --- a/pkg/release/v1/util/manifest_sorter_test.go +++ b/pkg/release/v1/util/manifest_sorter_test.go @@ -143,7 +143,6 @@ metadata: // This test will fail if 'six' or 'seven' was added. assert.Len(t, generic, 2) - assert.Len(t, hs, 4) for _, out := range hs { diff --git a/pkg/repo/v1/chartrepo_test.go b/pkg/repo/v1/chartrepo_test.go index 4be2ebf73..54275e28d 100644 --- a/pkg/repo/v1/chartrepo_test.go +++ b/pkg/repo/v1/chartrepo_test.go @@ -175,9 +175,7 @@ func TestFindChartInAuthAndTLSAndPassRepoURL(t *testing.T) { // versions of Darwin do not. As there are people developing Helm using both old and new versions of Darwin we test // for both messages. if runtime.GOOS == "darwin" { - if !strings.Contains(err.Error(), "x509: “Acme Co” certificate is not trusted") && !strings.Contains(err.Error(), "x509: certificate signed by unknown authority") { - t.Errorf("Expected TLS error for function FindChartInAuthAndTLSAndPassRepoURL not found, but got a different error (%v)", err) - } + assert.True(t, strings.Contains(err.Error(), "x509: “Acme Co” certificate is not trusted") || strings.Contains(err.Error(), "x509: certificate signed by unknown authority"), "Expected TLS error for function FindChartInAuthAndTLSAndPassRepoURL not found, but got a different error (%v)", err) } else { assert.ErrorContainsf(t, err, "x509: certificate signed by unknown authority", "Expected TLS error for function FindChartInAuthAndTLSAndPassRepoURL not found, but got a different error") } @@ -203,7 +201,6 @@ func TestErrorFindChartInRepoURL(t *testing.T) { }) _, err := FindChartInRepoURL("http://someserver/something", "nginx", g) - require.Error(t, err, "Expected error for bad chart URL, but did not get any errors") require.ErrorContainsf(t, err, `looks like "http://someserver/something" is not a valid chart repository or cannot be reached`, "Expected error for bad chart URL, but got a different error") srv, err := startLocalServerForTests(nil) @@ -211,16 +208,13 @@ func TestErrorFindChartInRepoURL(t *testing.T) { defer srv.Close() _, err = FindChartInRepoURL(srv.URL, "nginx1", g) - require.Error(t, err, "Expected error for chart not found, but did not get any errors") require.EqualError(t, err, `chart "nginx1" not found in `+srv.URL+` repository`, "Expected error for chart not found, but got a different error") require.ErrorIs(t, err, ChartNotFoundError{}, "error is not of correct error type structure") _, err = FindChartInRepoURL(srv.URL, "nginx1", g, WithChartVersion("0.1.0")) - require.Error(t, err, "Expected error for chart not found, but did not get any errors") require.EqualError(t, err, `chart "nginx1" version "0.1.0" not found in `+srv.URL+` repository`, "Expected error for chart not found, but got a different error") _, err = FindChartInRepoURL(srv.URL, "chartWithNoURL", g) - require.Error(t, err, "Expected error for no chart URLs available, but did not get any errors") assert.EqualError(t, err, `chart "chartWithNoURL" has no downloadable URLs`, "Expected error for chart not found, but got a different error") } diff --git a/pkg/repo/v1/repo_test.go b/pkg/repo/v1/repo_test.go index e3373fc49..f7f5df9be 100644 --- a/pkg/repo/v1/repo_test.go +++ b/pkg/repo/v1/repo_test.go @@ -120,11 +120,8 @@ func TestRemoveRepository(t *testing.T) { ) removeRepository := "stable" - found := sampleRepository.Remove(removeRepository) - assert.Truef(t, found, "expected repository %s not found", removeRepository) - - found = sampleRepository.Has(removeRepository) - assert.Falsef(t, found, "repository %s not deleted", removeRepository) + assert.Truef(t, sampleRepository.Remove(removeRepository), "expected repository %s not found", removeRepository) + assert.Falsef(t, sampleRepository.Has(removeRepository), "repository %s not deleted", removeRepository) } func TestUpdateRepository(t *testing.T) { @@ -205,9 +202,6 @@ func TestRemoveRepositoryInvalidEntries(t *testing.T) { ) removeRepository := "stable" - found := sampleRepository.Remove(removeRepository) - assert.Truef(t, found, "expected repository %s not found", removeRepository) - - found = sampleRepository.Has(removeRepository) - assert.Falsef(t, found, "repository %s not deleted", removeRepository) + assert.Truef(t, sampleRepository.Remove(removeRepository), "expected repository %s not found", removeRepository) + assert.Falsef(t, sampleRepository.Has(removeRepository), "repository %s not deleted", removeRepository) } diff --git a/pkg/repo/v1/repotest/server_test.go b/pkg/repo/v1/repotest/server_test.go index 7008e2305..f74adb445 100644 --- a/pkg/repo/v1/repotest/server_test.go +++ b/pkg/repo/v1/repotest/server_test.go @@ -42,24 +42,25 @@ func TestServer(t *testing.T) { c, err := srv.CopyCharts("testdata/*.tgz") require.NoError(t, err) - - assert.Len(t, c, 1) - + require.Len(t, c, 1) assert.Equal(t, "examplechart-0.1.0.tgz", filepath.Base(c[0])) req, err := http.NewRequestWithContext(t.Context(), http.MethodGet, srv.URL()+"/examplechart-0.1.0.tgz", http.NoBody) require.NoError(t, err) + client := http.DefaultClient res, err := client.Do(req) require.NoError(t, err) - res.Body.Close() + res.Body.Close() assert.GreaterOrEqual(t, res.ContentLength, int64(500)) req, err = http.NewRequestWithContext(t.Context(), http.MethodGet, srv.URL()+"/index.yaml", http.NoBody) require.NoError(t, err) + res, err = client.Do(req) require.NoError(t, err) + data, err := io.ReadAll(res.Body) res.Body.Close() require.NoError(t, err) diff --git a/pkg/storage/driver/labels_test.go b/pkg/storage/driver/labels_test.go index 848ae8861..481b8c467 100644 --- a/pkg/storage/driver/labels_test.go +++ b/pkg/storage/driver/labels_test.go @@ -18,6 +18,8 @@ package driver import ( "testing" + + "github.com/stretchr/testify/require" ) func TestLabelsMatch(t *testing.T) { @@ -42,8 +44,8 @@ func TestLabelsMatch(t *testing.T) { } for _, tt := range tests { - if !tt.set1.match(tt.set2) && tt.expect { - t.Fatalf("Expected match '%s'\n", tt.desc) - } + t.Run(tt.desc, func(t *testing.T) { + require.False(t, !tt.set1.match(tt.set2) && tt.expect) + }) } } diff --git a/pkg/storage/driver/records_test.go b/pkg/storage/driver/records_test.go index 067e31e76..22d54e6cc 100644 --- a/pkg/storage/driver/records_test.go +++ b/pkg/storage/driver/records_test.go @@ -17,7 +17,6 @@ limitations under the License. package driver import ( - "reflect" "testing" "github.com/stretchr/testify/assert" @@ -132,7 +131,7 @@ func TestRecordsGet(t *testing.T) { for _, tt := range tests { got := rs.Get(tt.key) - require.Truef(t, reflect.DeepEqual(tt.rec, got), "Expected %v, got %v", tt.rec, got) + require.Equal(t, tt.rec, got, "Expected %v, got %v", tt.rec, got) } } @@ -222,6 +221,6 @@ func TestRecordsReplace(t *testing.T) { for _, tt := range tests { got := rs.Replace(tt.key, tt.rec) - require.Truef(t, reflect.DeepEqual(tt.expected, got), "Expected %v, got %v", tt.expected, got) + require.Equalf(t, tt.expected, got, "Expected %v, got %v", tt.expected, got) } } diff --git a/pkg/storage/driver/util_test.go b/pkg/storage/driver/util_test.go index 7074f252a..5dda3cd1f 100644 --- a/pkg/storage/driver/util_test.go +++ b/pkg/storage/driver/util_test.go @@ -14,7 +14,6 @@ limitations under the License. package driver import ( - "reflect" "testing" "github.com/stretchr/testify/assert" @@ -22,7 +21,7 @@ import ( func TestGetSystemLabel(t *testing.T) { output := GetSystemLabels() - assert.Truef(t, reflect.DeepEqual(systemLabels, output), "Expected {%v}, got {%v}", systemLabels, output) + assert.Equalf(t, systemLabels, output, "Expected {%v}, got {%v}", systemLabels, output) } func TestIsSystemLabel(t *testing.T) { @@ -69,7 +68,7 @@ func TestFilterSystemLabels(t *testing.T) { } for _, test := range tests { output := filterSystemLabels(test[0]) - assert.Truef(t, reflect.DeepEqual(test[1], output), "Expected {%v}, got {%v}", test[1], output) + assert.Equalf(t, test[1], output, "Expected {%v}, got {%v}", test[1], output) } } @@ -101,6 +100,6 @@ func TestContainsSystemLabels(t *testing.T) { } for _, test := range tests { output := ContainsSystemLabels(test.input) - assert.Truef(t, reflect.DeepEqual(test.output, output), "Expected {%v}, got {%v}", test.output, output) + assert.Equalf(t, test.output, output, "Expected {%v}, got {%v}", test.output, output) } } From 828d01a8786162987482408b7803ceb3f3c176ac Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Fri, 24 Jul 2026 13:24:06 +0200 Subject: [PATCH 55/61] chore(pkg): refactor: finer tests conversions to testify part 1 refactor: finer tests conversions to testify in pkg/strvals Signed-off-by: Matthieu MOREL --- pkg/action/upgrade_test.go | 25 +-- pkg/chart/v2/lint/rules/template_test.go | 29 ++-- pkg/chart/v2/loader/load_test.go | 37 ++--- pkg/downloader/chart_downloader_test.go | 65 ++++---- pkg/kube/client_test.go | 22 ++- pkg/strvals/literal_parser_test.go | 81 ++++------ pkg/strvals/parser_test.go | 189 +++++++++-------------- 7 files changed, 177 insertions(+), 271 deletions(-) diff --git a/pkg/action/upgrade_test.go b/pkg/action/upgrade_test.go index b7e25206d..53419b6a8 100644 --- a/pkg/action/upgrade_test.go +++ b/pkg/action/upgrade_test.go @@ -252,11 +252,8 @@ func TestUpgradeRelease_ReuseValues(t *testing.T) { // Now make sure it is actually upgraded updatedResi, err := upAction.cfg.Releases.Get(res.Name, 2) req.NoError(err) + req.NotNil(updatedResi, "Updated Release is nil") - if updatedResi == nil { - is.Fail("Updated Release is nil") - return - } updatedRes, err := releaserToV1Release(updatedResi) req.NoError(err) @@ -320,11 +317,8 @@ func TestUpgradeRelease_ReuseValues(t *testing.T) { // Now get the upgraded release updatedResi, err := upAction.cfg.Releases.Get(res.Name, 2) req.NoError(err) + req.NotNil(updatedResi, "Updated Release is nil") - if updatedResi == nil { - is.Fail("Updated Release is nil") - return - } updatedRes, err := releaserToV1Release(updatedResi) req.NoError(err) @@ -383,11 +377,8 @@ func TestUpgradeRelease_ResetThenReuseValues(t *testing.T) { // Now make sure it is actually upgraded updatedResi, err := upAction.cfg.Releases.Get(res.Name, 2) req.NoError(err) + req.NotNil(updatedResi, "Updated Release is nil") - if updatedResi == nil { - is.Fail("Updated Release is nil") - return - } updatedRes, err := releaserToV1Release(updatedResi) req.NoError(err) @@ -523,11 +514,8 @@ func TestUpgradeRelease_Labels(t *testing.T) { // Now make sure it is actually upgraded and labels were merged updatedResi, err := upAction.cfg.Releases.Get(res.Name, 2) req.NoError(err) + req.NotNil(updatedResi, "Updated Release is nil") - if updatedResi == nil { - is.Fail("Updated Release is nil") - return - } updatedRes, err := releaserToV1Release(updatedResi) req.NoError(err) is.Equal(common.StatusDeployed, updatedRes.Info.Status) @@ -536,11 +524,8 @@ func TestUpgradeRelease_Labels(t *testing.T) { // Now make sure it is suppressed release still contains original labels initialResi, err := upAction.cfg.Releases.Get(res.Name, 1) req.NoError(err) + req.NotNil(initialResi, "Initial Release is nil") - if initialResi == nil { - is.Fail("Updated Release is nil") - return - } initialRes, err := releaserToV1Release(initialResi) req.NoError(err) is.Equal(common.StatusSuperseded, initialRes.Info.Status) diff --git a/pkg/chart/v2/lint/rules/template_test.go b/pkg/chart/v2/lint/rules/template_test.go index 37a33a7eb..ab78450b9 100644 --- a/pkg/chart/v2/lint/rules/template_test.go +++ b/pkg/chart/v2/lint/rules/template_test.go @@ -171,8 +171,11 @@ func TestValidateMetadataName(t *testing.T) { } for _, tt := range tests { t.Run(fmt.Sprintf("%s/%s", tt.obj.Kind, tt.obj.Metadata.Name), func(t *testing.T) { - if err := validateMetadataName(tt.obj); (err != nil) != tt.wantErr { - t.Errorf("validateMetadataName() error = %v, wantErr %v", err, tt.wantErr) + err := validateMetadataName(tt.obj) + if tt.wantErr { + require.Error(t, err, "validateMetadataName()") + } else { + require.NoError(t, err, "validateMetadataName()") } }) } @@ -210,12 +213,12 @@ func TestDeprecatedAPIFails(t *testing.T) { namespace, values, TemplateLinterSkipSchemaValidation(false)) - if l := len(linter.Messages); l != 1 { + if !assert.Len(t, linter.Messages, 1) { for i, msg := range linter.Messages { t.Logf("Message %d: %s", i, msg) } - t.Fatalf("Expected 1 lint error, got %d", l) } + require.Len(t, linter.Messages, 1, "Expected 1 lint error") var depErr deprecatedAPIError require.ErrorAs(t, linter.Messages[0].Err, &depErr) @@ -267,8 +270,7 @@ func TestStrictTemplateParsingMapError(t *testing.T) { namespace, ch.Values, TemplateLinterSkipSchemaValidation(false)) - if len(linter.Messages) != 0 { - t.Errorf("expected zero messages, got %d", len(linter.Messages)) + if !assert.Empty(t, linter.Messages, "expected zero messages") { for i, msg := range linter.Messages { t.Logf("Message %d: %q", i, msg) } @@ -358,9 +360,14 @@ func TestValidateTopIndentLevel(t *testing.T) { " apiVersion:foo": true, "\n\n apiVersion:foo\n\n": true, } { - if err := validateTopIndentLevel(doc); (err == nil) == shouldFail { - t.Errorf("Expected %t for %q", shouldFail, doc) - } + t.Run(doc, func(t *testing.T) { + err := validateTopIndentLevel(doc) + if shouldFail { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) } } @@ -392,12 +399,12 @@ func TestEmptyWithCommentsManifests(t *testing.T) { namespace, values, TemplateLinterSkipSchemaValidation(false)) - if l := len(linter.Messages); l > 0 { + if !assert.Empty(t, linter.Messages) { for i, msg := range linter.Messages { t.Logf("Message %d: %s", i, msg) } - t.Fatalf("Expected 0 lint errors, got %d", l) } + require.Empty(t, linter.Messages, "Expected 0 lint errors") } func TestValidateListAnnotations(t *testing.T) { md := &k8sYamlStruct{ diff --git a/pkg/chart/v2/loader/load_test.go b/pkg/chart/v2/loader/load_test.go index da5c3b725..4d73cb0d6 100644 --- a/pkg/chart/v2/loader/load_test.go +++ b/pkg/chart/v2/loader/load_test.go @@ -25,7 +25,6 @@ import ( "log" "os" "path/filepath" - "reflect" "runtime" "strings" "testing" @@ -385,11 +384,13 @@ func TestLoadInvalidArchive(t *testing.T) { {"illegal-abspath5.tgz", "/./c://foo", "chart contains illegally named files"}, {"illegal-abspath6.tgz", "\\\\?\\Some\\windows\\magic", "chart illegally contains absolute paths"}, } { - illegalChart := filepath.Join(tmpdir, tt.chartname) - writeTar(illegalChart, tt.internal, []byte("hello: world")) - _, err := Load(illegalChart) - require.Error(t, err, "expected error when unpacking illegal files") - require.ErrorContains(t, err, tt.expectError, "Expected error to contain %q, got %q for %s", tt.expectError, err.Error(), tt.chartname) + t.Run(tt.chartname, func(t *testing.T) { + illegalChart := filepath.Join(tmpdir, tt.chartname) + writeTar(illegalChart, tt.internal, []byte("hello: world")) + _, err := Load(illegalChart) + require.Error(t, err, "expected error when unpacking illegal files") + require.ErrorContains(t, err, tt.expectError) + }) } // Make sure that absolute path gets interpreted as relative @@ -456,7 +457,7 @@ foo: t.Run(testName, func(tt *testing.T) { values, err := LoadValues(bytes.NewReader(testCase.data)) require.NoError(tt, err) - assert.Truef(t, reflect.DeepEqual(values, testCase.expctedValues), "Expected values: %v, got %v", testCase.expctedValues, values) + assert.Equal(t, testCase.expctedValues, values) }) } } @@ -484,16 +485,13 @@ func TestMergeValuesV2(t *testing.T) { } testMap := MergeMaps(flatMap, nestedMap) - equal := reflect.DeepEqual(testMap, nestedMap) - assert.True(t, equal, "Expected a nested map to overwrite a flat value. Expected: %v, got %v", nestedMap, testMap) + assert.Equal(t, testMap, nestedMap, "Expected a nested map to overwrite a flat value. Expected: %v, got %v", nestedMap, testMap) testMap = MergeMaps(nestedMap, flatMap) - equal = reflect.DeepEqual(testMap, flatMap) - assert.True(t, equal, "Expected a flat value to overwrite a map. Expected: %v, got %v", flatMap, testMap) + assert.Equal(t, testMap, flatMap, "Expected a flat value to overwrite a map. Expected: %v, got %v", flatMap, testMap) testMap = MergeMaps(nestedMap, anotherNestedMap) - equal = reflect.DeepEqual(testMap, anotherNestedMap) - assert.True(t, equal, "Expected a nested map to overwrite another nested map. Expected: %v, got %v", anotherNestedMap, testMap) + assert.Equal(t, testMap, anotherNestedMap, "Expected a nested map to overwrite another nested map. Expected: %v, got %v", anotherNestedMap, testMap) testMap = MergeMaps(anotherFlatMap, anotherNestedMap) expectedMap := map[string]any{ @@ -504,8 +502,7 @@ func TestMergeValuesV2(t *testing.T) { "awesome": "stuff", }, } - equal = reflect.DeepEqual(testMap, expectedMap) - assert.True(t, equal, "Expected a map with different keys to merge properly with another map. Expected: %v, got %v", expectedMap, testMap) + assert.Equal(t, expectedMap, testMap, "Expected a map with different keys to merge properly with another map. Expected: %v, got %v", expectedMap, testMap) } func verifyChart(t *testing.T, c *chart.Chart) { @@ -515,15 +512,13 @@ func verifyChart(t *testing.T, c *chart.Chart) { assert.Len(t, c.Templates, 1, "Expected 1 template, got %d", len(c.Templates)) numfiles := 6 - if len(c.Files) != numfiles { - t.Errorf("Expected %d extra files, got %d", numfiles, len(c.Files)) + if !assert.Len(t, c.Files, numfiles) { for _, n := range c.Files { t.Logf("\t%s", n.Name) } } - if len(c.Dependencies()) != 2 { - t.Errorf("Expected 2 dependencies, got %d (%v)", len(c.Dependencies()), c.Dependencies()) + if !assert.Len(t, c.Dependencies(), 2, "Expected 2 dependencies") { for _, d := range c.Dependencies() { t.Logf("\tSubchart: %s\n", d.Name()) } @@ -548,7 +543,7 @@ func verifyChart(t *testing.T, c *chart.Chart) { func verifyDependencies(t *testing.T, c *chart.Chart) { t.Helper() - assert.Len(t, c.Metadata.Dependencies, 2, "Expected 2 dependencies, got %d", len(c.Metadata.Dependencies)) + require.Len(t, c.Metadata.Dependencies, 2, "Expected 2 dependencies, got %d", len(c.Metadata.Dependencies)) tests := []*chart.Dependency{ {Name: "alpine", Version: "0.1.0", Repository: "https://example.com/charts"}, {Name: "mariner", Version: "4.3.2", Repository: "https://example.com/charts"}, @@ -563,7 +558,7 @@ func verifyDependencies(t *testing.T, c *chart.Chart) { func verifyDependenciesLock(t *testing.T, c *chart.Chart) { t.Helper() - assert.Len(t, c.Metadata.Dependencies, 2, "Expected 2 dependencies, got %d", len(c.Metadata.Dependencies)) + require.Len(t, c.Metadata.Dependencies, 2, "Expected 2 dependencies, got %d", len(c.Metadata.Dependencies)) tests := []*chart.Dependency{ {Name: "alpine", Version: "0.1.0", Repository: "https://example.com/charts"}, {Name: "mariner", Version: "4.3.2", Repository: "https://example.com/charts"}, diff --git a/pkg/downloader/chart_downloader_test.go b/pkg/downloader/chart_downloader_test.go index 7187bdff1..92d4f024d 100644 --- a/pkg/downloader/chart_downloader_test.go +++ b/pkg/downloader/chart_downloader_test.go @@ -82,16 +82,15 @@ func TestResolveChartRef(t *testing.T) { } for _, tt := range tests { - _, u, err := c.ResolveChartVersion(tt.ref, tt.version) - if err != nil { - if tt.fail { - continue + t.Run(tt.name, func(t *testing.T) { + _, u, err := c.ResolveChartVersion(tt.ref, tt.version) + if err != nil { + require.True(t, tt.fail) + } else { + got := u.String() + assert.Equalf(t, tt.expect, got, "%s: expected %s, got %s", tt.name, tt.expect, got) } - t.Errorf("%s: failed with error %q", tt.name, err) - continue - } - got := u.String() - assert.Equalf(t, tt.expect, got, "%s: expected %s, got %s", tt.name, tt.expect, got) + }) } } @@ -124,35 +123,25 @@ func TestResolveChartOpts(t *testing.T) { snapshotOpts := c.Options for _, tt := range tests { - // reset chart downloader options for each test case - c.Options = snapshotOpts - - expect, err := getter.NewHTTPGetter(tt.expect...) - if err != nil { - t.Errorf("%s: failed to setup http client: %s", tt.name, err) - continue - } - - _, u, err := c.ResolveChartVersion(tt.ref, tt.version) - if err != nil { - t.Errorf("%s: failed with error %s", tt.name, err) - continue - } - - got, err := getter.NewHTTPGetter( - append( - c.Options, - getter.WithURL(u.String()), - )..., - ) - if err != nil { - t.Errorf("%s: failed to create http client: %s", tt.name, err) - continue - } - - if *(got.(*getter.HTTPGetter)) != *(expect.(*getter.HTTPGetter)) { - t.Errorf("%s: expected %s, got %s", tt.name, expect, got) - } + t.Run(tt.name, func(t *testing.T) { + // reset chart downloader options for each test case + c.Options = snapshotOpts + + expect, err := getter.NewHTTPGetter(tt.expect...) + require.NoError(t, err, "failed to setup http client") + + _, u, err := c.ResolveChartVersion(tt.ref, tt.version) + require.NoError(t, err, "failed with error") + + got, err := getter.NewHTTPGetter( + append( + c.Options, + getter.WithURL(u.String()), + )..., + ) + require.NoError(t, err, "failed to create http client") + assert.Equal(t, expect, got) + }) } } diff --git a/pkg/kube/client_test.go b/pkg/kube/client_test.go index 4d46d2692..405925a30 100644 --- a/pkg/kube/client_test.go +++ b/pkg/kube/client_test.go @@ -567,17 +567,16 @@ func TestUpdate(t *testing.T) { // Special handling for the rollback test case if name == "rollback after failed upgrade with removed resource" { - assert.Empty(t, result.Created, "expected 0 resource created, got %d", len(result.Created)) - assert.Len(t, result.Updated, 1, "expected 1 resource updated, got %d", len(result.Updated)) - assert.Empty(t, result.Deleted, "expected 0 resource deleted, got %d", len(result.Deleted)) + assert.Empty(t, result.Created, "expected 0 resource created") + assert.Len(t, result.Updated, 1, "expected 1 resource updated") + assert.Empty(t, result.Deleted, "expected 0 resource deleted") } else { - assert.Len(t, result.Created, 1, "expected 1 resource created, got %d", len(result.Created)) - assert.Len(t, result.Updated, 2, "expected 2 resource updated, got %d", len(result.Updated)) - assert.Len(t, result.Deleted, 1, "expected 1 resource deleted, got %d", len(result.Deleted)) + assert.Len(t, result.Created, 1, "expected 1 resource created") + assert.Len(t, result.Updated, 2, "expected 2 resource updated") + assert.Len(t, result.Deleted, 1, "expected 1 resource deleted") } if tc.ExpectedError != "" { - require.Error(t, err) require.ErrorContains(t, err, tc.ExpectedError) } else { require.NoError(t, err) @@ -702,11 +701,11 @@ func TestPerform(t *testing.T) { } err = perform(infos, fn) - assert.Equal(t, tt.err, (err != nil), "expected error: %v", tt.err) - if err != nil { - require.EqualErrorf(t, err, tt.errMessage, "expected error message: %v, got %v", tt.errMessage, err) + if tt.err { + require.EqualError(t, err, tt.errMessage) + } else { + require.NoError(t, err) } - assert.Len(t, results, tt.count, "expected %d result objects, got %d", tt.count, len(results)) }) } @@ -782,7 +781,6 @@ func TestWait(t *testing.T) { require.NoError(t, err) assert.Len(t, result.Created, 3, "expected 3 resource created, got %d", len(result.Created)) require.NoErrorf(t, c.Wait(resources, time.Second*30), "expected wait without error") - assert.GreaterOrEqualf(t, time.Since(*created), time.Second*5, "expected to wait at least 5 seconds before ready status was detected, but got %s", time.Since(*created)) } diff --git a/pkg/strvals/literal_parser_test.go b/pkg/strvals/literal_parser_test.go index 6c22a732b..94e0c6050 100644 --- a/pkg/strvals/literal_parser_test.go +++ b/pkg/strvals/literal_parser_test.go @@ -16,7 +16,6 @@ limitations under the License. package strvals import ( - "bytes" "fmt" "strings" "testing" @@ -279,29 +278,21 @@ func TestParseLiteral(t *testing.T) { } for _, tt := range cases { - got, err := ParseLiteral(tt.str) - if err != nil { - if !tt.err { - require.NoError(t, err, tt.str) - } - continue - } - - if tt.err { - assert.Fail(t, "Expected error. Got nil", tt.str) - } - - y1, err := yaml.Marshal(tt.expect) - require.NoError(t, err) + t.Run(tt.str, func(t *testing.T) { + got, err := ParseLiteral(tt.str) + if tt.err { + require.Error(t, err) + } else { + require.NoError(t, err) + y1, err := yaml.Marshal(tt.expect) + require.NoError(t, err) - y2, err := yaml.Marshal(got) - if err != nil { - require.NoError(t, err, "Error serializing parsed value") - } + y2, err := yaml.Marshal(got) + require.NoError(t, err, "Error serializing parsed value") - if !bytes.Equal(y1, y2) { - assert.Equal(t, string(y1), string(y2), tt.str) - } + assert.YAMLEq(t, string(y1), string(y2), tt.str) + } + }) } } @@ -386,17 +377,13 @@ func TestParseLiteralInto(t *testing.T) { } for _, tt := range tests { - if err := ParseLiteralInto(tt.input, tt.got); err != nil { - require.NoError(t, err) - } + require.NoError(t, ParseLiteralInto(tt.input, tt.got)) if tt.err { assert.Fail(t, "Expected error. Got nil", tt.input) } if tt.input2 != "" { - if err := ParseLiteralInto(tt.input2, tt.got); err != nil { - require.NoError(t, err) - } + require.NoError(t, ParseLiteralInto(tt.input2, tt.got)) if tt.err { assert.Fail(t, "Expected error. Got nil", tt.input2) } @@ -406,13 +393,9 @@ func TestParseLiteralInto(t *testing.T) { require.NoError(t, err) y2, err := yaml.Marshal(tt.got) - if err != nil { - require.NoError(t, err, "Error serializing parsed value") - } + require.NoError(t, err, "Error serializing parsed value") - if !bytes.Equal(y1, y2) { - assert.Equal(t, string(y1), string(y2), tt.input) - } + assert.YAMLEq(t, string(y1), string(y2), tt.input) } } @@ -447,29 +430,23 @@ func TestParseLiteralNestedLevels(t *testing.T) { } for _, tt := range tests { - got, err := ParseLiteral(tt.str) - if err != nil { + t.Run(tt.str, func(t *testing.T) { + got, err := ParseLiteral(tt.str) if tt.err { + require.Error(t, err) if tt.errStr != "" { require.EqualError(t, err, tt.errStr) } - continue - } - require.NoError(t, err, tt.str) - } - - if tt.err { - assert.Fail(t, "Expected error. Got nil", tt.str) - } - - y1, err := yaml.Marshal(tt.expect) - require.NoError(t, err) + } else { + require.NoError(t, err) + y1, err := yaml.Marshal(tt.expect) + require.NoError(t, err) - y2, err := yaml.Marshal(got) - require.NoError(t, err, "Error serializing parsed value") + y2, err := yaml.Marshal(got) + require.NoError(t, err, "Error serializing parsed value") - if !bytes.Equal(y1, y2) { - assert.Equal(t, string(y1), string(y2), tt.str) - } + assert.YAMLEq(t, string(y1), string(y2), tt.str) + } + }) } } diff --git a/pkg/strvals/parser_test.go b/pkg/strvals/parser_test.go index e68bc4e19..c6c866711 100644 --- a/pkg/strvals/parser_test.go +++ b/pkg/strvals/parser_test.go @@ -16,8 +16,8 @@ limitations under the License. package strvals import ( - "bytes" "fmt" + "strconv" "strings" "testing" @@ -383,50 +383,37 @@ func TestParseSet(t *testing.T) { } for _, tt := range tests { - got, err := Parse(tt.str) - if err != nil { + t.Run(tt.str, func(t *testing.T) { + got, err := Parse(tt.str) if tt.err { - continue - } - require.NoError(t, err, tt.str) - } - if tt.err { - assert.Fail(t, "Expected error. Got nil", tt.str) - } - - y1, err := yaml.Marshal(tt.expect) - require.NoError(t, err) - y2, err := yaml.Marshal(got) - if err != nil { - require.NoError(t, err, "Error serializing parsed value") - } + require.Error(t, err) + } else { + require.NoError(t, err) + y1, err := yaml.Marshal(tt.expect) + require.NoError(t, err) + y2, err := yaml.Marshal(got) + if err != nil { + require.NoError(t, err, "Error serializing parsed value") + } - if !bytes.Equal(y1, y2) { - assert.Equal(t, string(y1), string(y2), tt.str) - } + assert.YAMLEq(t, string(y1), string(y2), tt.str) + } + }) } for _, tt := range testsString { - got, err := ParseString(tt.str) - if err != nil { + t.Run(tt.str, func(t *testing.T) { + got, err := ParseString(tt.str) if tt.err { - continue + require.Error(t, err) + } else { + require.NoError(t, err) + y1, err := yaml.Marshal(tt.expect) + require.NoError(t, err) + y2, err := yaml.Marshal(got) + require.NoError(t, err, "Error serializing parsed value") + assert.YAMLEq(t, string(y1), string(y2)) } - require.NoError(t, err, tt.str) - } - if tt.err { - assert.Fail(t, "Expected error. Got nil", tt.str) - } - - y1, err := yaml.Marshal(tt.expect) - require.NoError(t, err) - y2, err := yaml.Marshal(got) - if err != nil { - require.NoError(t, err, "Error serializing parsed value") - } - - if !bytes.Equal(y1, y2) { - assert.Equal(t, string(y1), string(y2), tt.str) - } + }) } } @@ -511,33 +498,26 @@ func TestParseInto(t *testing.T) { err: false, }, } - for _, tt := range tests { - if err := ParseInto(tt.input, tt.got); err != nil { - require.NoError(t, err) - } - if tt.err { - assert.Fail(t, "Expected error. Got nil", tt.input) - } - - if tt.input2 != "" { - if err := ParseInto(tt.input2, tt.got); err != nil { - require.NoError(t, err) - } + for i, tt := range tests { + t.Run(strconv.Itoa(i), func(t *testing.T) { + require.NoError(t, ParseInto(tt.input, tt.got)) if tt.err { - assert.Fail(t, "Expected error. Got nil", tt.input2) + assert.Fail(t, "Expected error. Got nil", tt.input) } - } - y1, err := yaml.Marshal(tt.expect) - require.NoError(t, err) - y2, err := yaml.Marshal(tt.got) - if err != nil { - require.NoError(t, err, "Error serializing parsed value") - } + if tt.input2 != "" { + require.NoError(t, ParseInto(tt.input2, tt.got)) + if tt.err { + assert.Fail(t, "Expected error. Got nil", tt.input2) + } + } - if !bytes.Equal(y1, y2) { - assert.Equal(t, string(y1), string(y2), tt.input) - } + y1, err := yaml.Marshal(tt.expect) + require.NoError(t, err) + y2, err := yaml.Marshal(tt.got) + require.NoError(t, err, "Error serializing parsed value") + assert.YAMLEq(t, string(y1), string(y2), tt.input) + }) } } @@ -564,13 +544,8 @@ func TestParseIntoString(t *testing.T) { y1, err := yaml.Marshal(expect) require.NoError(t, err) y2, err := yaml.Marshal(got) - if err != nil { - require.NoError(t, err, "Error serializing parsed value") - } - - if !bytes.Equal(y1, y2) { - assert.Equal(t, string(y1), string(y2), input) - } + require.NoError(t, err, "Error serializing parsed value") + assert.YAMLEq(t, string(y1), string(y2), input) } func TestParseJSON(t *testing.T) { @@ -650,27 +625,19 @@ func TestParseJSON(t *testing.T) { }, } for _, tt := range tests { - if err := ParseJSON(tt.input, tt.got); err != nil { + t.Run(tt.input, func(t *testing.T) { + err := ParseJSON(tt.input, tt.got) if tt.err { - continue + require.Error(t, err) + } else { + require.NoError(t, err) + y1, err := yaml.Marshal(tt.expect) + require.NoError(t, err, "Error serializing expected value") + y2, err := yaml.Marshal(tt.got) + require.NoError(t, err, "Error serializing parsed value") + assert.YAMLEq(t, string(y1), string(y2)) } - require.NoError(t, err, tt.input) - } - if tt.err { - require.Fail(t, "Expected error. Got nil", tt.input) - } - y1, err := yaml.Marshal(tt.expect) - if err != nil { - require.NoError(t, err, "Error serializing expected value") - } - y2, err := yaml.Marshal(tt.got) - if err != nil { - require.NoError(t, err, "Error serializing parsed value") - } - - if !bytes.Equal(y1, y2) { - assert.Equal(t, string(y1), string(y2), tt.input) - } + }) } } @@ -693,14 +660,10 @@ func TestParseFile(t *testing.T) { y1, err := yaml.Marshal(expect) require.NoError(t, err) - y2, err := yaml.Marshal(got) - if err != nil { - require.NoError(t, err, "Error serializing parsed value") - } - if !bytes.Equal(y1, y2) { - assert.Equal(t, string(y1), string(y2), input) - } + y2, err := yaml.Marshal(got) + require.NoError(t, err, "Error serializing parsed value") + assert.YAMLEq(t, string(y1), string(y2), input) } func TestParseIntoFile(t *testing.T) { @@ -725,13 +688,9 @@ func TestParseIntoFile(t *testing.T) { y1, err := yaml.Marshal(expect) require.NoError(t, err) y2, err := yaml.Marshal(got) - if err != nil { - require.NoError(t, err, "Error serializing parsed value") - } + require.NoError(t, err, "Error serializing parsed value") - if !bytes.Equal(y1, y2) { - assert.Equal(t, string(y1), string(y2), input) - } + assert.YAMLEq(t, string(y1), string(y2), input) } func TestToYAML(t *testing.T) { @@ -775,27 +734,23 @@ func TestParseSetNestedLevels(t *testing.T) { } for _, tt := range tests { - got, err := Parse(tt.str) - if err != nil { + t.Run(tt.str, func(t *testing.T) { + got, err := Parse(tt.str) if tt.err { + require.Error(t, err) if tt.errStr != "" { require.EqualError(t, err, tt.errStr) } - continue - } - require.NoError(t, err, tt.str) - } - if tt.err { - assert.Fail(t, "Expected error. Got nil", tt.str) - } + } else { + require.NoError(t, err) - y1, err := yaml.Marshal(tt.expect) - require.NoError(t, err) - y2, err := yaml.Marshal(got) - require.NoError(t, err, "Error serializing parsed value") + y1, err := yaml.Marshal(tt.expect) + require.NoError(t, err) - if !bytes.Equal(y1, y2) { - assert.Equal(t, string(y1), string(y2), tt.str) - } + y2, err := yaml.Marshal(got) + require.NoError(t, err, "Error serializing parsed value") + assert.YAMLEq(t, string(y1), string(y2), tt.str) + } + }) } } From a27f3a062027d8b459eed2186076fb9384b82f38 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Fri, 24 Jul 2026 18:19:56 +0200 Subject: [PATCH 56/61] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Matthieu MOREL --- pkg/cmd/rollback_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/cmd/rollback_test.go b/pkg/cmd/rollback_test.go index aa60043aa..e4dbf9779 100644 --- a/pkg/cmd/rollback_test.go +++ b/pkg/cmd/rollback_test.go @@ -160,5 +160,5 @@ func TestRollbackWithLabels(t *testing.T) { updatedRel, err := releaserToV1Release(updatedReli) require.NoError(t, err) - assert.Equalf(t, updatedRel.Labels, labels1, "Expected {%v}, got {%v}", labels1, updatedRel.Labels) +assert.Equalf(t, labels1, updatedRel.Labels, "Expected {%v}, got {%v}", labels1, updatedRel.Labels) } From b59dfd39015311d94c04541ec5b91959c6b4b6d3 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Fri, 24 Jul 2026 18:44:53 +0200 Subject: [PATCH 57/61] Update rollback_test.go Signed-off-by: Matthieu MOREL --- pkg/cmd/rollback_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/cmd/rollback_test.go b/pkg/cmd/rollback_test.go index e4dbf9779..21d6a65af 100644 --- a/pkg/cmd/rollback_test.go +++ b/pkg/cmd/rollback_test.go @@ -160,5 +160,5 @@ func TestRollbackWithLabels(t *testing.T) { updatedRel, err := releaserToV1Release(updatedReli) require.NoError(t, err) -assert.Equalf(t, labels1, updatedRel.Labels, "Expected {%v}, got {%v}", labels1, updatedRel.Labels) + assert.Equalf(t, labels1, updatedRel.Labels, "Expected {%v}, got {%v}", labels1, updatedRel.Labels) } From bfca0688b1a44b1cf7ae37ac5f64792a8dffe7f1 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Fri, 24 Jul 2026 18:45:58 +0200 Subject: [PATCH 58/61] Update show_test.go Signed-off-by: Matthieu MOREL --- pkg/cmd/show_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/cmd/show_test.go b/pkg/cmd/show_test.go index b7ad94d94..61c4f8b10 100644 --- a/pkg/cmd/show_test.go +++ b/pkg/cmd/show_test.go @@ -78,7 +78,7 @@ func TestShowPreReleaseChart(t *testing.T) { ) _, _, err := executeActionCommand(cmd) if tt.fail { - assert.ErrorContains(t, err, tt.expectedErr, "%q expected error: %s, got: %s", tt.name, tt.expectedErr, err.Error()) + assert.ErrorContains(t, err, tt.expectedErr) } else { assert.NoError(t, err) } From 532eabf88afa2b119f90ef82d1bf309923cbbb78 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Fri, 24 Jul 2026 18:47:43 +0200 Subject: [PATCH 59/61] Update chartrepo_test.go Signed-off-by: Matthieu MOREL --- pkg/repo/v1/chartrepo_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/repo/v1/chartrepo_test.go b/pkg/repo/v1/chartrepo_test.go index 54275e28d..f0e5839ac 100644 --- a/pkg/repo/v1/chartrepo_test.go +++ b/pkg/repo/v1/chartrepo_test.go @@ -175,6 +175,7 @@ func TestFindChartInAuthAndTLSAndPassRepoURL(t *testing.T) { // versions of Darwin do not. As there are people developing Helm using both old and new versions of Darwin we test // for both messages. if runtime.GOOS == "darwin" { + require.Error(t, err) assert.True(t, strings.Contains(err.Error(), "x509: “Acme Co” certificate is not trusted") || strings.Contains(err.Error(), "x509: certificate signed by unknown authority"), "Expected TLS error for function FindChartInAuthAndTLSAndPassRepoURL not found, but got a different error (%v)", err) } else { assert.ErrorContainsf(t, err, "x509: certificate signed by unknown authority", "Expected TLS error for function FindChartInAuthAndTLSAndPassRepoURL not found, but got a different error") From 61d99a8bdbc90219c474c96e11790ab6a90cde61 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Fri, 24 Jul 2026 18:53:45 +0200 Subject: [PATCH 60/61] Update labels_test.go Signed-off-by: Matthieu MOREL --- pkg/storage/driver/labels_test.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/storage/driver/labels_test.go b/pkg/storage/driver/labels_test.go index 481b8c467..34f01be79 100644 --- a/pkg/storage/driver/labels_test.go +++ b/pkg/storage/driver/labels_test.go @@ -45,7 +45,11 @@ func TestLabelsMatch(t *testing.T) { for _, tt := range tests { t.Run(tt.desc, func(t *testing.T) { - require.False(t, !tt.set1.match(tt.set2) && tt.expect) + if tt.expect { + require.True(t, tt.set1.match(tt.set2)) + } else { + require.False(t, tt.set1.match(tt.set2)) + } }) } } From 622f16b37fdb1f1915aece9436165dc53c26b3c5 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Fri, 24 Jul 2026 19:06:05 +0200 Subject: [PATCH 61/61] Update resource_test.go Signed-off-by: Matthieu MOREL --- pkg/kube/resource_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/kube/resource_test.go b/pkg/kube/resource_test.go index 18501d4e8..8bc644833 100644 --- a/pkg/kube/resource_test.go +++ b/pkg/kube/resource_test.go @@ -20,6 +20,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/cli-runtime/pkg/resource" @@ -41,11 +42,11 @@ func TestResourceList(t *testing.T) { assert.Equal(t, "pod", r1.Get(info("bar")).Mapping.Resource.Resource, "expected get pod") diff := r1.Difference(r2) - assert.Len(t, diff, 1, "expected 1 result") + require.Len(t, diff, 1, "expected 1 result") assert.Contains(t, diff, info("foo"), "expected diff to return foo") inter := r1.Intersect(r2) - assert.Len(t, inter, 1, "expected 1 result") + require.Len(t, inter, 1, "expected 1 result") assert.Contains(t, inter, info("bar"), "expected intersect to return bar") }