diff --git a/pkg/cmd/helpers_test.go b/pkg/cmd/helpers_test.go index 611d1a54c..207dc2863 100644 --- a/pkg/cmd/helpers_test.go +++ b/pkg/cmd/helpers_test.go @@ -81,27 +81,25 @@ func executeActionCommandC(store *storage.Storage, cmd string) (*cobra.Command, return executeActionCommandStdinC(store, nil, cmd) } -func executeActionCommandStdinC(store *storage.Storage, in *os.File, cmd string) (*cobra.Command, string, error) { +func executeActionCommandWithWriters(store *storage.Storage, in *os.File, outWriter, errWriter io.Writer, cmd string) (*cobra.Command, error) { args, err := shellwords.Parse(cmd) if err != nil { - return nil, "", err + return nil, err } - buf := new(bytes.Buffer) - actionConfig := &action.Configuration{ Releases: store, KubeClient: &kubefake.PrintingKubeClient{Out: io.Discard}, Capabilities: common.DefaultCapabilities, } - root, err := newRootCmdWithConfig(actionConfig, buf, args, SetupLogging) + root, err := newRootCmdWithConfig(actionConfig, outWriter, args, SetupLogging) if err != nil { - return nil, "", err + return nil, err } - root.SetOut(buf) - root.SetErr(buf) + root.SetOut(outWriter) + root.SetErr(errWriter) root.SetArgs(args) oldStdin := os.Stdin @@ -118,10 +116,13 @@ func executeActionCommandStdinC(store *storage.Storage, in *os.File, cmd string) mem.SetNamespace(settings.Namespace()) } c, err := root.ExecuteC() + return c, err +} - result := buf.String() - - return c, result, err +func executeActionCommandStdinC(store *storage.Storage, in *os.File, cmd string) (*cobra.Command, string, error) { + buf := new(bytes.Buffer) + c, err := executeActionCommandWithWriters(store, in, buf, buf, cmd) + return c, buf.String(), err } // cmdTestCase describes a test case that works with releases. @@ -301,3 +302,10 @@ func TestCmdGetDryRunFlagStrategy(t *testing.T) { }) } } + +func executeActionCommandErr(store *storage.Storage, in *os.File, cmd string) (*cobra.Command, string, string, error) { + bufOut := new(bytes.Buffer) + bufErr := new(bytes.Buffer) + c, err := executeActionCommandWithWriters(store, in, bufOut, bufErr, cmd) + return c, bufOut.String(), bufErr.String(), err +} diff --git a/pkg/cmd/show_test.go b/pkg/cmd/show_test.go index 61c4f8b10..6eaf15ccc 100644 --- a/pkg/cmd/show_test.go +++ b/pkg/cmd/show_test.go @@ -19,6 +19,7 @@ package cmd import ( "fmt" "path/filepath" + "strings" "testing" "github.com/stretchr/testify/assert" @@ -86,6 +87,43 @@ func TestShowPreReleaseChart(t *testing.T) { } } +func TestShowOCIChartRegistryPullMetadataGoesToStderr(t *testing.T) { + srv := repotest.NewTempServer( + t, + repotest.WithChartSourceGlob("testdata/testcharts/*.tgz*"), + ) + defer srv.Stop() + + ociSrv, err := repotest.NewOCIServer(t, srv.Root()) + if err != nil { + t.Fatal(err) + } + ociSrv.Run(t) + + contentTmp := t.TempDir() + outdir := srv.Root() + cmdStr := fmt.Sprintf("show chart oci://%s/u/ocitestuser/oci-dependent-chart --version 0.1.0 --registry-config %s --content-cache %s --plain-http", + ociSrv.RegistryURL, + filepath.Join(outdir, "config.json"), + contentTmp, + ) + + _, outStr, errStr, err := executeActionCommandErr(storageFixture(), nil, cmdStr) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + if strings.Contains(outStr, "Pulled: ") || strings.Contains(outStr, "Digest: ") { + t.Fatalf("expected stdout to exclude registry pull metadata, got: %s", outStr) + } + if !strings.Contains(errStr, "Pulled: ") { + t.Fatalf("expected stderr to contain registry pull metadata, got: %s", errStr) + } + if !strings.Contains(outStr, "apiVersion:") { + t.Fatalf("expected chart metadata in output, got: %s", outStr) + } +} + func TestShowVersionCompletion(t *testing.T) { repoFile := "testdata/helmhome/helm/repositories.yaml" repoCache := "testdata/helmhome/helm/repository" diff --git a/pkg/cmd/template_test.go b/pkg/cmd/template_test.go index d508a0505..9e671daae 100644 --- a/pkg/cmd/template_test.go +++ b/pkg/cmd/template_test.go @@ -19,7 +19,10 @@ package cmd import ( "fmt" "path/filepath" + "strings" "testing" + + "helm.sh/helm/v4/pkg/repo/v1/repotest" ) var chartPath = "testdata/testcharts/subchart" @@ -176,6 +179,43 @@ func TestTemplateCmd(t *testing.T) { runTestCmd(t, tests) } +func TestTemplateOCIChartRegistryPullMetadataGoesToStderr(t *testing.T) { + srv := repotest.NewTempServer( + t, + repotest.WithChartSourceGlob("testdata/testcharts/*.tgz*"), + ) + defer srv.Stop() + + ociSrv, err := repotest.NewOCIServer(t, srv.Root()) + if err != nil { + t.Fatal(err) + } + ociSrv.Run(t) + + contentTmp := t.TempDir() + outdir := srv.Root() + cmdStr := fmt.Sprintf("template --generate-name oci://%s/u/ocitestuser/oci-dependent-chart --version 0.1.0 --registry-config %s --content-cache %s --plain-http", + ociSrv.RegistryURL, + filepath.Join(outdir, "config.json"), + contentTmp, + ) + + _, outStr, errStr, err := executeActionCommandErr(storageFixture(), nil, cmdStr) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + if strings.Contains(outStr, "Pulled: ") || strings.Contains(outStr, "Digest: ") { + t.Fatalf("expected stdout to exclude registry pull metadata, got: %s", outStr) + } + if !strings.Contains(errStr, "Pulled: ") { + t.Fatalf("expected stderr to contain registry pull metadata, got: %s", errStr) + } + if !strings.Contains(outStr, "# Source:") { + t.Fatalf("expected rendered manifests in output, got: %s", outStr) + } +} + func TestTemplateVersionCompletion(t *testing.T) { repoFile := "testdata/helmhome/helm/repositories.yaml" repoCache := "testdata/helmhome/helm/repository"