Add tests to action package to improve coverage

Signed-off-by: Stephanie Hohenberg <stephanie.hohenberg@gmail.com>
pull/31239/head
Stephanie Hohenberg 3 weeks ago
parent 90a91e097f
commit 8554a7fe4b

@ -198,6 +198,12 @@ func withMetadataDependency(dependency chart.Dependency) chartOption {
}
}
func withFile(file common.File) chartOption {
return func(opts *chartOptions) {
opts.Files = append(opts.Files, &file)
}
}
func withSampleTemplates() chartOption {
return func(opts *chartOptions) {
sampleTemplates := []*common.File{

@ -63,7 +63,7 @@ func TestGetMetadata_Run_BasicMetadata(t *testing.T) {
Namespace: "default",
}
cfg.Releases.Create(rel)
require.NoError(t, cfg.Releases.Create(rel))
result, err := client.Run(releaseName)
require.NoError(t, err)
@ -118,7 +118,7 @@ func TestGetMetadata_Run_WithDependencies(t *testing.T) {
Namespace: "default",
}
cfg.Releases.Create(rel)
require.NoError(t, cfg.Releases.Create(rel))
result, err := client.Run(releaseName)
require.NoError(t, err)
@ -172,7 +172,7 @@ func TestGetMetadata_Run_WithDependenciesAliases(t *testing.T) {
Namespace: "default",
}
cfg.Releases.Create(rel)
require.NoError(t, cfg.Releases.Create(rel))
result, err := client.Run(releaseName)
require.NoError(t, err)
@ -238,7 +238,7 @@ func TestGetMetadata_Run_WithMixedDependencies(t *testing.T) {
Namespace: "default",
}
cfg.Releases.Create(rel)
require.NoError(t, cfg.Releases.Create(rel))
result, err := client.Run(releaseName)
require.NoError(t, err)
@ -293,7 +293,7 @@ func TestGetMetadata_Run_WithAnnotations(t *testing.T) {
Namespace: "default",
}
cfg.Releases.Create(rel)
require.NoError(t, cfg.Releases.Create(rel))
result, err := client.Run(releaseName)
require.NoError(t, err)
@ -348,8 +348,8 @@ func TestGetMetadata_Run_SpecificVersion(t *testing.T) {
Namespace: "default",
}
cfg.Releases.Create(rel1)
cfg.Releases.Create(rel2)
require.NoError(t, cfg.Releases.Create(rel1))
require.NoError(t, cfg.Releases.Create(rel2))
result, err := client.Run(releaseName)
require.NoError(t, err)
@ -402,7 +402,7 @@ func TestGetMetadata_Run_DifferentStatuses(t *testing.T) {
Namespace: "default",
}
cfg.Releases.Create(rel)
require.NoError(t, cfg.Releases.Create(rel))
result, err := client.Run(releaseName)
require.NoError(t, err)
@ -458,7 +458,7 @@ func TestGetMetadata_Run_EmptyAppVersion(t *testing.T) {
Namespace: "default",
}
cfg.Releases.Create(rel)
require.NoError(t, cfg.Releases.Create(rel))
result, err := client.Run(releaseName)
require.NoError(t, err)

@ -0,0 +1,66 @@
/*
Copyright The Helm Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package action
import (
"errors"
"io"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
kubefake "helm.sh/helm/v4/pkg/kube/fake"
release "helm.sh/helm/v4/pkg/release/v1"
)
func TestNewGet(t *testing.T) {
config := actionConfigFixture(t)
client := NewGet(config)
assert.NotNil(t, client)
assert.Equal(t, config, client.cfg)
assert.Equal(t, 0, client.Version)
}
func TestGetRun(t *testing.T) {
config := actionConfigFixture(t)
client := NewGet(config)
simpleRelease := namedReleaseStub("test-release", release.StatusPendingUpgrade)
require.NoError(t, config.Releases.Create(simpleRelease))
result, err := client.Run(simpleRelease.Name)
require.NoError(t, err)
assert.Equal(t, simpleRelease.Name, result.Name)
assert.Equal(t, simpleRelease.Version, result.Version)
}
func TestGetRun_UnreachableKubeClient(t *testing.T) {
config := actionConfigFixture(t)
failingKubeClient := kubefake.FailingKubeClient{PrintingKubeClient: kubefake.PrintingKubeClient{Out: io.Discard}, DummyResources: nil}
failingKubeClient.ConnectionError = errors.New("connection refused")
config.KubeClient = &failingKubeClient
client := NewGet(config)
simpleRelease := namedReleaseStub("test-release", release.StatusPendingUpgrade)
require.NoError(t, config.Releases.Create(simpleRelease))
result, err := client.Run(simpleRelease.Name)
assert.Nil(t, result)
assert.Error(t, err)
}

@ -78,7 +78,7 @@ func TestGetValues_Run_UserConfigOnly(t *testing.T) {
Namespace: "default",
}
cfg.Releases.Create(rel)
require.NoError(t, cfg.Releases.Create(rel))
result, err := client.Run(releaseName)
require.NoError(t, err)
@ -126,7 +126,7 @@ func TestGetValues_Run_AllValues(t *testing.T) {
Namespace: "default",
}
cfg.Releases.Create(rel)
require.NoError(t, cfg.Releases.Create(rel))
result, err := client.Run(releaseName)
require.NoError(t, err)
@ -160,7 +160,7 @@ func TestGetValues_Run_EmptyValues(t *testing.T) {
Namespace: "default",
}
cfg.Releases.Create(rel)
require.NoError(t, cfg.Releases.Create(rel))
result, err := client.Run(releaseName)
require.NoError(t, err)
@ -211,7 +211,7 @@ func TestGetValues_Run_NilConfig(t *testing.T) {
Namespace: "default",
}
cfg.Releases.Create(rel)
require.NoError(t, cfg.Releases.Create(rel))
result, err := client.Run(releaseName)
require.NoError(t, err)

@ -0,0 +1,101 @@
/*
Copyright The Helm Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package action
import (
"errors"
"io"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
kubefake "helm.sh/helm/v4/pkg/kube/fake"
release "helm.sh/helm/v4/pkg/release/v1"
)
func TestNewHistory(t *testing.T) {
config := actionConfigFixture(t)
client := NewHistory(config)
assert.NotNil(t, client)
assert.Equal(t, config, client.cfg)
}
func TestHistoryRun(t *testing.T) {
releaseName := "test-release"
simpleRelease := namedReleaseStub(releaseName, release.StatusPendingUpgrade)
updatedRelease := namedReleaseStub(releaseName, release.StatusDeployed)
updatedRelease.Chart.Metadata.Version = "0.1.1"
updatedRelease.Version = 2
config := actionConfigFixture(t)
client := NewHistory(config)
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")
}
}
releases, err := config.Releases.ListReleases()
require.NoError(t, err)
assert.Len(t, releases, 2, "expected 2 Releases in Config")
result, err := client.Run(releaseName)
require.NoError(t, err)
assert.Len(t, result, 2, "expected 2 Releases in History result")
assert.Equal(t, simpleRelease.Name, result[0].Name)
assert.Equal(t, simpleRelease.Version, result[0].Version)
assert.Equal(t, updatedRelease.Name, result[1].Name)
assert.Equal(t, updatedRelease.Version, result[1].Version)
}
func TestHistoryRun_UnreachableKubeClient(t *testing.T) {
config := actionConfigFixture(t)
failingKubeClient := kubefake.FailingKubeClient{PrintingKubeClient: kubefake.PrintingKubeClient{Out: io.Discard}, DummyResources: nil}
failingKubeClient.ConnectionError = errors.New("connection refused")
config.KubeClient = &failingKubeClient
client := NewHistory(config)
result, err := client.Run("release-name")
assert.Nil(t, result)
assert.Error(t, err)
}
func TestHistoryRun_InvalidReleaseNames(t *testing.T) {
config := actionConfigFixture(t)
client := NewHistory(config)
invalidReleaseNames := []string{
"",
"too-long-release-name-max-53-characters-abcdefghijklmnopqrstuvwxyz",
"MyRelease",
"release_name",
"release@123",
"-badstart",
"badend-",
".dotstart",
}
for _, name := range invalidReleaseNames {
result, err := client.Run(name)
assert.Nil(t, result)
assert.ErrorContains(t, err, "release name is invalid")
}
}

@ -190,7 +190,7 @@ func (i *Install) installCRDs(crds []chart.CRD) error {
kube.ClientCreateOptionServerSideApply(i.ServerSideApply, i.ForceConflicts)); err != nil {
// If the error is CRD already exists, continue.
if apierrors.IsAlreadyExists(err) {
crdName := res[0].Name
crdName := obj.Name
slog.Debug("CRD is already present. Skipping", "crd", crdName)
continue
}

@ -35,6 +35,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
appsv1 "k8s.io/api/apps/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kuberuntime "k8s.io/apimachinery/pkg/runtime"
@ -45,8 +46,10 @@ import (
"helm.sh/helm/v4/internal/test"
"helm.sh/helm/v4/pkg/chart/common"
chart "helm.sh/helm/v4/pkg/chart/v2"
"helm.sh/helm/v4/pkg/kube"
kubefake "helm.sh/helm/v4/pkg/kube/fake"
"helm.sh/helm/v4/pkg/registry"
release "helm.sh/helm/v4/pkg/release/v1"
"helm.sh/helm/v4/pkg/storage/driver"
)
@ -253,7 +256,8 @@ func TestInstallReleaseClientOnly(t *testing.T) {
is := assert.New(t)
instAction := installAction(t)
instAction.ClientOnly = true
instAction.Run(buildChart(), nil) // disregard output
_, err := instAction.Run(buildChart(), nil)
require.NoError(t, err)
is.Equal(instAction.cfg.Capabilities, common.DefaultCapabilities)
is.Equal(instAction.cfg.KubeClient, &kubefake.PrintingKubeClient{Out: io.Discard})
@ -459,7 +463,7 @@ func TestInstallRelease_NoHooks(t *testing.T) {
instAction := installAction(t)
instAction.DisableHooks = true
instAction.ReleaseName = "no-hooks"
instAction.cfg.Releases.Create(releaseStub())
require.NoError(t, instAction.cfg.Releases.Create(releaseStub()))
vals := map[string]interface{}{}
res, err := instAction.Run(buildChart(), vals)
@ -495,7 +499,7 @@ func TestInstallRelease_ReplaceRelease(t *testing.T) {
rel := releaseStub()
rel.Info.Status = release.StatusUninstalled
instAction.cfg.Releases.Create(rel)
require.NoError(t, instAction.cfg.Releases.Create(rel))
instAction.ReleaseName = rel.Name
vals := map[string]interface{}{}
@ -1009,3 +1013,116 @@ func TestInstallRun_UnreachableKubeClient(t *testing.T) {
assert.Nil(t, res)
assert.ErrorContains(t, err, "connection refused")
}
func TestInstallSetRegistryClient(t *testing.T) {
config := actionConfigFixture(t)
instAction := NewInstall(config)
registryClient := &registry.Client{}
instAction.SetRegistryClient(registryClient)
assert.Equal(t, registryClient, instAction.GetRegistryClient())
}
func TestInstalLCRDs(t *testing.T) {
config := actionConfigFixture(t)
instAction := NewInstall(config)
mockFile := common.File{
Name: "crds/foo.yaml",
Data: []byte("hello"),
}
mockChart := buildChart(withFile(mockFile))
crdsToInstall := mockChart.CRDObjects()
assert.Len(t, crdsToInstall, 1)
assert.Equal(t, crdsToInstall[0].File.Data, mockFile.Data)
require.NoError(t, instAction.installCRDs(crdsToInstall))
}
func TestInstalLCRDs_KubeClient_BuildError(t *testing.T) {
config := actionConfigFixture(t)
failingKubeClient := kubefake.FailingKubeClient{PrintingKubeClient: kubefake.PrintingKubeClient{Out: io.Discard}, DummyResources: nil}
failingKubeClient.BuildError = errors.New("build error")
config.KubeClient = &failingKubeClient
instAction := NewInstall(config)
mockFile := common.File{
Name: "crds/foo.yaml",
Data: []byte("hello"),
}
mockChart := buildChart(withFile(mockFile))
crdsToInstall := mockChart.CRDObjects()
require.Error(t, instAction.installCRDs(crdsToInstall), "failed to install CRD")
}
func TestInstalLCRDs_KubeClient_CreateError(t *testing.T) {
config := actionConfigFixture(t)
failingKubeClient := kubefake.FailingKubeClient{PrintingKubeClient: kubefake.PrintingKubeClient{Out: io.Discard}, DummyResources: nil}
failingKubeClient.CreateError = errors.New("create error")
config.KubeClient = &failingKubeClient
instAction := NewInstall(config)
mockFile := common.File{
Name: "crds/foo.yaml",
Data: []byte("hello"),
}
mockChart := buildChart(withFile(mockFile))
crdsToInstall := mockChart.CRDObjects()
require.Error(t, instAction.installCRDs(crdsToInstall), "failed to install CRD")
}
func TestInstalLCRDs_AlreadyExist(t *testing.T) {
config := actionConfigFixture(t)
failingKubeClient := kubefake.FailingKubeClient{PrintingKubeClient: kubefake.PrintingKubeClient{Out: io.Discard}, DummyResources: nil}
mockError := &apierrors.StatusError{ErrStatus: metav1.Status{
Status: metav1.StatusFailure,
Reason: metav1.StatusReasonAlreadyExists,
}}
failingKubeClient.CreateError = mockError
config.KubeClient = &failingKubeClient
instAction := NewInstall(config)
mockFile := common.File{
Name: "crds/foo.yaml",
Data: []byte("hello"),
}
mockChart := buildChart(withFile(mockFile))
crdsToInstall := mockChart.CRDObjects()
assert.Nil(t, instAction.installCRDs(crdsToInstall))
}
func TestInstalLCRDs_WaiterError(t *testing.T) {
config := actionConfigFixture(t)
failingKubeClient := kubefake.FailingKubeClient{PrintingKubeClient: kubefake.PrintingKubeClient{Out: io.Discard}, DummyResources: nil}
failingKubeClient.WaitError = errors.New("wait error")
failingKubeClient.BuildDummy = true
config.KubeClient = &failingKubeClient
instAction := NewInstall(config)
mockFile := common.File{
Name: "crds/foo.yaml",
Data: []byte("hello"),
}
mockChart := buildChart(withFile(mockFile))
crdsToInstall := mockChart.CRDObjects()
require.Error(t, instAction.installCRDs(crdsToInstall), "wait error")
}
func TestCheckDependencies(t *testing.T) {
dependency := chart.Dependency{Name: "hello"}
mockChart := buildChart(withDependency())
assert.Nil(t, CheckDependencies(mockChart, []*chart.Dependency{&dependency}))
}
func TestCheckDependencies_MissingDependency(t *testing.T) {
dependency := chart.Dependency{Name: "missing"}
mockChart := buildChart(withDependency())
assert.ErrorContains(t, CheckDependencies(mockChart, []*chart.Dependency{&dependency}), "missing in charts")
}

@ -17,7 +17,12 @@ limitations under the License.
package action
import (
"errors"
"testing"
"github.com/stretchr/testify/assert"
"helm.sh/helm/v4/pkg/chart/v2/lint/support"
)
var (
@ -163,3 +168,45 @@ func TestLint_ChartWithWarnings(t *testing.T) {
}
})
}
func TestHasWarningsOrErrors(t *testing.T) {
testError := errors.New("test-error")
cases := []struct {
name string
data LintResult
expected bool
}{
{
name: "has no warning messages and no errors",
data: LintResult{TotalChartsLinted: 1, Messages: make([]support.Message, 0), Errors: make([]error, 0)},
expected: false,
},
{
name: "has error",
data: LintResult{TotalChartsLinted: 1, Messages: make([]support.Message, 0), Errors: []error{testError}},
expected: true,
},
{
name: "has info message only",
data: LintResult{TotalChartsLinted: 1, Messages: []support.Message{{Severity: support.InfoSev, Path: "", Err: testError}}, Errors: make([]error, 0)},
expected: false,
},
{
name: "has warning message",
data: LintResult{TotalChartsLinted: 1, Messages: []support.Message{{Severity: support.WarningSev, Path: "", Err: testError}}, Errors: make([]error, 0)},
expected: true,
},
{
name: "has error message",
data: LintResult{TotalChartsLinted: 1, Messages: []support.Message{{Severity: support.ErrorSev, Path: "", Err: testError}}, Errors: make([]error, 0)},
expected: true,
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
result := HasWarningsOrErrors(&tc.data)
assert.Equal(t, tc.expected, result)
})
}
}

@ -22,6 +22,7 @@ import (
"testing"
"github.com/Masterminds/semver/v3"
"github.com/stretchr/testify/require"
"helm.sh/helm/v4/internal/test/ensure"
)
@ -90,7 +91,8 @@ func TestPassphraseFileFetcher_WithStdinAndMultipleFetches(t *testing.T) {
passphrase := "secret-from-stdin"
go func() {
w.Write([]byte(passphrase + "\n"))
_, err = w.Write([]byte(passphrase + "\n"))
require.NoError(t, err)
}()
for i := 0; i < 4; i++ {
@ -152,3 +154,18 @@ func TestValidateVersion(t *testing.T) {
})
}
}
func TestRun_ErrorPath(t *testing.T) {
client := NewPackage()
_, err := client.Run("err-path", nil)
require.Error(t, err)
}
func TestRun(t *testing.T) {
chartPath := "testdata/charts/chart-with-schema"
client := NewPackage()
filename, err := client.Run(chartPath, nil)
require.NoError(t, err)
require.Equal(t, "empty-0.1.0.tgz", filename)
require.NoError(t, os.Remove(filename))
}

@ -0,0 +1,80 @@
/*
Copyright The Helm Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package action
import (
"net/http"
"net/http/httptest"
"os"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"helm.sh/helm/v4/pkg/cli"
"helm.sh/helm/v4/pkg/registry"
)
func TestNewPull(t *testing.T) {
config := actionConfigFixture(t)
client := NewPull(WithConfig(config))
assert.NotNil(t, client)
assert.Equal(t, config, client.cfg)
}
func TestPullSetRegistryClient(t *testing.T) {
config := actionConfigFixture(t)
client := NewPull(WithConfig(config))
registryClient := &registry.Client{}
client.SetRegistryClient(registryClient)
assert.Equal(t, registryClient, client.cfg.RegistryClient)
}
func TestPullRun_ChartNotFound(t *testing.T) {
srv, err := startLocalServerForTests(t, nil)
if err != nil {
t.Fatal(err)
}
defer srv.Close()
config := actionConfigFixture(t)
client := NewPull(WithConfig(config))
client.Settings = cli.New()
client.RepoURL = srv.URL
chartRef := "nginx"
_, err = client.Run(chartRef)
require.ErrorContains(t, err, "404 Not Found")
}
func startLocalServerForTests(t *testing.T, handler http.Handler) (*httptest.Server, error) {
t.Helper()
if handler == nil {
fileBytes, err := os.ReadFile("../repo/v1/testdata/local-index.yaml")
if err != nil {
return nil, err
}
handler = http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
_, err = w.Write(fileBytes)
require.NoError(t, err)
})
}
return httptest.NewServer(handler), nil
}

@ -0,0 +1,66 @@
/*
Copyright The Helm Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package action
import (
"bytes"
"testing"
"github.com/stretchr/testify/assert"
)
func TestNewPushWithPushConfig(t *testing.T) {
config := actionConfigFixture(t)
client := NewPushWithOpts(WithPushConfig(config))
assert.NotNil(t, client)
assert.Equal(t, config, client.cfg)
}
func TestNewPushWithTLSClientConfig(t *testing.T) {
certFile := "certFile"
keyFile := "keyFile"
caFile := "caFile"
client := NewPushWithOpts(WithTLSClientConfig(certFile, keyFile, caFile))
assert.NotNil(t, client)
assert.Equal(t, certFile, client.certFile)
assert.Equal(t, keyFile, client.keyFile)
assert.Equal(t, caFile, client.caFile)
}
func TestNewPushWithInsecureSkipTLSVerify(t *testing.T) {
client := NewPushWithOpts(WithInsecureSkipTLSVerify(true))
assert.NotNil(t, client)
assert.Equal(t, true, client.insecureSkipTLSverify)
}
func TestNewPushWithPlainHTTP(t *testing.T) {
client := NewPushWithOpts(WithPlainHTTP(true))
assert.NotNil(t, client)
assert.Equal(t, true, client.plainHTTP)
}
func TestNewPushWithPushOptWriter(t *testing.T) {
buf := new(bytes.Buffer)
client := NewPushWithOpts(WithPushOptWriter(buf))
assert.NotNil(t, client)
assert.Equal(t, buf, client.out)
}

@ -0,0 +1,84 @@
/*
Copyright The Helm Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package action
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestNewRegistryLogin(t *testing.T) {
config := actionConfigFixture(t)
client := NewRegistryLogin(config)
assert.NotNil(t, client)
assert.Equal(t, config, client.cfg)
}
func TestWithCertFile(t *testing.T) {
config := actionConfigFixture(t)
client := NewRegistryLogin(config)
certFile := "testdata/cert.pem"
opt := WithCertFile(certFile)
assert.Nil(t, opt(client))
assert.Equal(t, certFile, client.certFile)
}
func TestWithInsecure(t *testing.T) {
config := actionConfigFixture(t)
client := NewRegistryLogin(config)
opt := WithInsecure(true)
assert.Nil(t, opt(client))
assert.Equal(t, true, client.insecure)
}
func TestWithKeyFile(t *testing.T) {
config := actionConfigFixture(t)
client := NewRegistryLogin(config)
keyFile := "testdata/key.pem"
opt := WithKeyFile(keyFile)
assert.Nil(t, opt(client))
assert.Equal(t, keyFile, client.keyFile)
}
func TestWithCAFile(t *testing.T) {
config := actionConfigFixture(t)
client := NewRegistryLogin(config)
caFile := "testdata/ca.pem"
opt := WithCAFile(caFile)
assert.Nil(t, opt(client))
assert.Equal(t, caFile, client.caFile)
}
func TestWithPlainHTTPLogin(t *testing.T) {
config := actionConfigFixture(t)
client := NewRegistryLogin(config)
opt := WithPlainHTTPLogin(true)
assert.Nil(t, opt(client))
assert.Equal(t, true, client.plainHTTP)
}

@ -0,0 +1,31 @@
/*
Copyright The Helm Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package action
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestNewRegistryLogout(t *testing.T) {
config := actionConfigFixture(t)
client := NewRegistryLogout(config)
assert.NotNil(t, client)
assert.Equal(t, config, client.cfg)
}

@ -0,0 +1,91 @@
/*
Copyright The Helm Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package action
import (
"bytes"
"errors"
"io"
"os"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"helm.sh/helm/v4/pkg/cli"
kubefake "helm.sh/helm/v4/pkg/kube/fake"
release "helm.sh/helm/v4/pkg/release/v1"
)
func TestNewReleaseTesting(t *testing.T) {
config := actionConfigFixture(t)
client := NewReleaseTesting(config)
assert.NotNil(t, client)
assert.Equal(t, config, client.cfg)
}
func TestReleaseTestingRun_UnreachableKubeClient(t *testing.T) {
config := actionConfigFixture(t)
failingKubeClient := kubefake.FailingKubeClient{PrintingKubeClient: kubefake.PrintingKubeClient{Out: io.Discard}, DummyResources: nil}
failingKubeClient.ConnectionError = errors.New("connection refused")
config.KubeClient = &failingKubeClient
client := NewReleaseTesting(config)
result, err := client.Run("")
assert.Nil(t, result)
assert.Error(t, err)
}
func TestReleaseTestingGetPodLogs_FilterEvents(t *testing.T) {
config := actionConfigFixture(t)
require.NoError(t, config.Init(cli.New().RESTClientGetter(), "", os.Getenv("HELM_DRIVER")))
client := NewReleaseTesting(config)
client.Filters[ExcludeNameFilter] = []string{"event-1"}
client.Filters[IncludeNameFilter] = []string{"event-3"}
hooks := []*release.Hook{
{
Name: "event-1",
Events: []release.HookEvent{release.HookTest},
},
{
Name: "event-2",
Events: []release.HookEvent{release.HookTest},
},
}
out := &bytes.Buffer{}
require.NoError(t, client.GetPodLogs(out, &release.Release{Hooks: hooks}))
assert.Contains(t, "", out.String())
}
func TestReleaseTestingGetPodLogs_PodRetrievalError(t *testing.T) {
config := actionConfigFixture(t)
require.NoError(t, config.Init(cli.New().RESTClientGetter(), "", os.Getenv("HELM_DRIVER")))
client := NewReleaseTesting(config)
hooks := []*release.Hook{
{
Name: "event-1",
Events: []release.HookEvent{release.HookTest},
},
}
require.ErrorContains(t, client.GetPodLogs(&bytes.Buffer{}, &release.Release{Hooks: hooks}), "unable to get pod logs")
}

@ -0,0 +1,45 @@
/*
Copyright The Helm Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package action
import (
"errors"
"io"
"testing"
"github.com/stretchr/testify/assert"
kubefake "helm.sh/helm/v4/pkg/kube/fake"
)
func TestNewRollback(t *testing.T) {
config := actionConfigFixture(t)
client := NewRollback(config)
assert.NotNil(t, client)
assert.Equal(t, config, client.cfg)
}
func TestRollbackRun_UnreachableKubeClient(t *testing.T) {
config := actionConfigFixture(t)
failingKubeClient := kubefake.FailingKubeClient{PrintingKubeClient: kubefake.PrintingKubeClient{Out: io.Discard}, DummyResources: nil}
failingKubeClient.ConnectionError = errors.New("connection refused")
config.KubeClient = &failingKubeClient
client := NewRollback(config)
assert.Error(t, client.Run(""))
}

@ -19,8 +19,11 @@ package action
import (
"testing"
"github.com/stretchr/testify/assert"
"helm.sh/helm/v4/pkg/chart/common"
chart "helm.sh/helm/v4/pkg/chart/v2"
"helm.sh/helm/v4/pkg/registry"
)
func TestShow(t *testing.T) {
@ -164,3 +167,12 @@ bar
t.Errorf("Expected\n%q\nGot\n%q\n", expect, output)
}
}
func TestShowSetRegistryClient(t *testing.T) {
config := actionConfigFixture(t)
client := NewShow(ShowAll, config)
registryClient := &registry.Client{}
client.SetRegistryClient(registryClient)
assert.Equal(t, registryClient, client.registryClient)
}

@ -0,0 +1,140 @@
/*
Copyright The Helm Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package action
import (
"errors"
"io"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
kubefake "helm.sh/helm/v4/pkg/kube/fake"
release "helm.sh/helm/v4/pkg/release/v1"
)
func TestNewStatus(t *testing.T) {
config := actionConfigFixture(t)
client := NewStatus(config)
assert.NotNil(t, client)
assert.Equal(t, config, client.cfg)
assert.Equal(t, 0, client.Version)
}
func TestStatusRun(t *testing.T) {
config := actionConfigFixture(t)
failingKubeClient := kubefake.FailingKubeClient{PrintingKubeClient: kubefake.PrintingKubeClient{Out: io.Discard}, DummyResources: nil}
failingKubeClient.BuildDummy = true
config.KubeClient = &failingKubeClient
client := NewStatus(config)
releaseName := "test-release"
require.NoError(t, configureReleaseContent(config, releaseName))
result, err := client.Run(releaseName)
client.ShowResourcesTable = true
require.NoError(t, err)
assert.Equal(t, releaseName, result.Name)
assert.Equal(t, 1, result.Version)
}
func TestStatusRun_KubeClientNotReachable(t *testing.T) {
config := actionConfigFixture(t)
failingKubeClient := kubefake.FailingKubeClient{PrintingKubeClient: kubefake.PrintingKubeClient{Out: io.Discard}, DummyResources: nil}
failingKubeClient.ConnectionError = errors.New("connection refused")
config.KubeClient = &failingKubeClient
client := NewStatus(config)
result, err := client.Run("")
assert.Nil(t, result)
assert.Error(t, err)
}
func TestStatusRun_KubeClientBuildTableError(t *testing.T) {
config := actionConfigFixture(t)
failingKubeClient := kubefake.FailingKubeClient{PrintingKubeClient: kubefake.PrintingKubeClient{Out: io.Discard}, DummyResources: nil}
failingKubeClient.BuildTableError = errors.New("build table error")
config.KubeClient = &failingKubeClient
releaseName := "test-release"
require.NoError(t, configureReleaseContent(config, releaseName))
client := NewStatus(config)
client.ShowResourcesTable = true
result, err := client.Run(releaseName)
assert.Nil(t, result)
assert.ErrorContains(t, err, "build table error")
}
func TestStatusRun_KubeClientBuildError(t *testing.T) {
config := actionConfigFixture(t)
failingKubeClient := kubefake.FailingKubeClient{PrintingKubeClient: kubefake.PrintingKubeClient{Out: io.Discard}, DummyResources: nil}
failingKubeClient.BuildError = errors.New("build error")
config.KubeClient = &failingKubeClient
releaseName := "test-release"
require.NoError(t, configureReleaseContent(config, releaseName))
client := NewStatus(config)
client.ShowResourcesTable = false
result, err := client.Run(releaseName)
assert.Nil(t, result)
assert.ErrorContains(t, err, "build error")
}
func TestStatusRun_KubeClientGetError(t *testing.T) {
config := actionConfigFixture(t)
failingKubeClient := kubefake.FailingKubeClient{PrintingKubeClient: kubefake.PrintingKubeClient{Out: io.Discard}, DummyResources: nil}
failingKubeClient.BuildError = errors.New("get error")
config.KubeClient = &failingKubeClient
releaseName := "test-release"
require.NoError(t, configureReleaseContent(config, releaseName))
client := NewStatus(config)
result, err := client.Run(releaseName)
assert.Nil(t, result)
assert.ErrorContains(t, err, "get error")
}
func configureReleaseContent(cfg *Configuration, releaseName string) error {
rel := &release.Release{
Name: releaseName,
Info: &release.Info{
Status: release.StatusDeployed,
},
Manifest: testManifest,
Version: 1,
Namespace: "default",
}
return cfg.Releases.Create(rel)
}
const testManifest = `
apiVersion: v1
kind: Pod
metadata:
namespace: default
name: test-application
`

@ -82,7 +82,7 @@ func TestUninstallRelease_deleteRelease(t *testing.T) {
"password": "password"
}
}`
unAction.cfg.Releases.Create(rel)
require.NoError(t, unAction.cfg.Releases.Create(rel))
res, err := unAction.Run(rel.Name)
is.NoError(err)
expected := `These resources were kept due to the resource policy:
@ -112,7 +112,7 @@ func TestUninstallRelease_Wait(t *testing.T) {
"password": "password"
}
}`
unAction.cfg.Releases.Create(rel)
require.NoError(t, unAction.cfg.Releases.Create(rel))
failer := unAction.cfg.KubeClient.(*kubefake.FailingKubeClient)
failer.WaitForDeleteError = fmt.Errorf("U timed out")
unAction.cfg.KubeClient = failer
@ -144,7 +144,7 @@ func TestUninstallRelease_Cascade(t *testing.T) {
"password": "password"
}
}`
unAction.cfg.Releases.Create(rel)
require.NoError(t, unAction.cfg.Releases.Create(rel))
failer := unAction.cfg.KubeClient.(*kubefake.FailingKubeClient)
failer.DeleteWithPropagationError = fmt.Errorf("Uninstall with cascade failed")
failer.BuildDummy = true

@ -25,15 +25,18 @@ import (
"testing"
"time"
chart "helm.sh/helm/v4/pkg/chart/v2"
"helm.sh/helm/v4/pkg/kube"
"helm.sh/helm/v4/pkg/storage/driver"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
appsv1 "k8s.io/api/apps/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/cli-runtime/pkg/resource"
chart "helm.sh/helm/v4/pkg/chart/v2"
"helm.sh/helm/v4/pkg/kube"
kubefake "helm.sh/helm/v4/pkg/kube/fake"
"helm.sh/helm/v4/pkg/registry"
release "helm.sh/helm/v4/pkg/release/v1"
"helm.sh/helm/v4/pkg/storage/driver"
)
func upgradeAction(t *testing.T) *Upgrade {
@ -80,7 +83,7 @@ func TestUpgradeRelease_Wait(t *testing.T) {
rel := releaseStub()
rel.Name = "come-fail-away"
rel.Info.Status = release.StatusDeployed
upAction.cfg.Releases.Create(rel)
require.NoError(t, upAction.cfg.Releases.Create(rel))
failer := upAction.cfg.KubeClient.(*kubefake.FailingKubeClient)
failer.WaitError = fmt.Errorf("I timed out")
@ -102,7 +105,7 @@ func TestUpgradeRelease_WaitForJobs(t *testing.T) {
rel := releaseStub()
rel.Name = "come-fail-away"
rel.Info.Status = release.StatusDeployed
upAction.cfg.Releases.Create(rel)
require.NoError(t, upAction.cfg.Releases.Create(rel))
failer := upAction.cfg.KubeClient.(*kubefake.FailingKubeClient)
failer.WaitError = fmt.Errorf("I timed out")
@ -125,7 +128,7 @@ func TestUpgradeRelease_CleanupOnFail(t *testing.T) {
rel := releaseStub()
rel.Name = "come-fail-away"
rel.Info.Status = release.StatusDeployed
upAction.cfg.Releases.Create(rel)
require.NoError(t, upAction.cfg.Releases.Create(rel))
failer := upAction.cfg.KubeClient.(*kubefake.FailingKubeClient)
failer.WaitError = fmt.Errorf("I timed out")
@ -152,7 +155,7 @@ func TestUpgradeRelease_RollbackOnFailure(t *testing.T) {
rel := releaseStub()
rel.Name = "nuketown"
rel.Info.Status = release.StatusDeployed
upAction.cfg.Releases.Create(rel)
require.NoError(t, upAction.cfg.Releases.Create(rel))
failer := upAction.cfg.KubeClient.(*kubefake.FailingKubeClient)
// We can't make Update error because then the rollback won't work
@ -178,7 +181,7 @@ func TestUpgradeRelease_RollbackOnFailure(t *testing.T) {
rel := releaseStub()
rel.Name = "fallout"
rel.Info.Status = release.StatusDeployed
upAction.cfg.Releases.Create(rel)
require.NoError(t, upAction.cfg.Releases.Create(rel))
failer := upAction.cfg.KubeClient.(*kubefake.FailingKubeClient)
failer.UpdateError = fmt.Errorf("update fail")
@ -371,12 +374,12 @@ func TestUpgradeRelease_Pending(t *testing.T) {
rel := releaseStub()
rel.Name = "come-fail-away"
rel.Info.Status = release.StatusDeployed
upAction.cfg.Releases.Create(rel)
require.NoError(t, upAction.cfg.Releases.Create(rel))
rel2 := releaseStub()
rel2.Name = "come-fail-away"
rel2.Info.Status = release.StatusPendingUpgrade
rel2.Version = 2
upAction.cfg.Releases.Create(rel2)
require.NoError(t, upAction.cfg.Releases.Create(rel2))
vals := map[string]interface{}{}
@ -392,7 +395,7 @@ func TestUpgradeRelease_Interrupted_Wait(t *testing.T) {
rel := releaseStub()
rel.Name = "interrupted-release"
rel.Info.Status = release.StatusDeployed
upAction.cfg.Releases.Create(rel)
require.NoError(t, upAction.cfg.Releases.Create(rel))
failer := upAction.cfg.KubeClient.(*kubefake.FailingKubeClient)
failer.WaitDuration = 10 * time.Second
@ -419,7 +422,7 @@ func TestUpgradeRelease_Interrupted_RollbackOnFailure(t *testing.T) {
rel := releaseStub()
rel.Name = "interrupted-release"
rel.Info.Status = release.StatusDeployed
upAction.cfg.Releases.Create(rel)
require.NoError(t, upAction.cfg.Releases.Create(rel))
failer := upAction.cfg.KubeClient.(*kubefake.FailingKubeClient)
failer.WaitDuration = 5 * time.Second
@ -706,3 +709,20 @@ func TestUpgradeRun_UnreachableKubeClient(t *testing.T) {
assert.Nil(t, result)
assert.ErrorContains(t, err, "connection refused")
}
func TestUpgradeSetRegistryClient(t *testing.T) {
config := actionConfigFixture(t)
client := NewUpgrade(config)
registryClient := &registry.Client{}
client.SetRegistryClient(registryClient)
assert.Equal(t, registryClient, client.registryClient)
}
func TestObjectKey(t *testing.T) {
obj := &appsv1.Deployment{}
obj.SetGroupVersionKind(schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "Deployment"})
info := resource.Info{Name: "name", Namespace: "namespace", Object: obj}
assert.Equal(t, "apps/v1/Deployment/namespace/name", objectKey(&info))
}

@ -0,0 +1,42 @@
/*
Copyright The Helm Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package action
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestNewVerify(t *testing.T) {
client := NewVerify()
assert.NotNil(t, client)
}
func TestVerifyRun(t *testing.T) {
client := NewVerify()
client.Keyring = "../downloader/testdata/helm-test-key.pub"
require.NoError(t, client.Run("../downloader/testdata/signtest-0.1.0.tgz"))
}
func TestVerifyRun_DownloadError(t *testing.T) {
client := NewVerify()
require.Error(t, client.Run("invalid-chart-path"))
}

@ -144,6 +144,9 @@ func (f *FailingKubeClient) BuildTable(r io.Reader, _ bool) (kube.ResourceList,
if f.BuildTableError != nil {
return []*resource.Info{}, f.BuildTableError
}
if f.BuildDummy {
return createDummyResourceList(), nil
}
return f.PrintingKubeClient.BuildTable(r, false)
}

Loading…
Cancel
Save