mirror of
https://github.com/helm/helm.git
synced 2026-05-28 04:35:48 -04:00
Add install test for TakeOwnership flag
Signed-off-by: Evans Mungai <mbuevans@gmail.com>
This commit is contained in:
parent
e55707b09d
commit
7c37a109f2
3 changed files with 130 additions and 1 deletions
|
|
@ -26,6 +26,7 @@ import (
|
|||
|
||||
chart "helm.sh/helm/v4/pkg/chart/v2"
|
||||
chartutil "helm.sh/helm/v4/pkg/chart/v2/util"
|
||||
"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"
|
||||
|
|
@ -37,6 +38,10 @@ import (
|
|||
var verbose = flag.Bool("test.log", false, "enable test logging")
|
||||
|
||||
func actionConfigFixture(t *testing.T) *Configuration {
|
||||
return actionConfigFixtureWithDummyResources(t, nil)
|
||||
}
|
||||
|
||||
func actionConfigFixtureWithDummyResources(t *testing.T, dummyResources kube.ResourceList) *Configuration {
|
||||
t.Helper()
|
||||
|
||||
registryClient, err := registry.NewClient()
|
||||
|
|
@ -46,7 +51,7 @@ func actionConfigFixture(t *testing.T) *Configuration {
|
|||
|
||||
return &Configuration{
|
||||
Releases: storage.Init(driver.NewMemory()),
|
||||
KubeClient: &kubefake.FailingKubeClient{PrintingKubeClient: kubefake.PrintingKubeClient{Out: io.Discard}},
|
||||
KubeClient: &kubefake.FailingKubeClient{PrintingKubeClient: kubefake.PrintingKubeClient{Out: io.Discard}, DummyResources: dummyResources},
|
||||
Capabilities: chartutil.DefaultCapabilities,
|
||||
RegistryClient: registryClient,
|
||||
Log: func(format string, v ...interface{}) {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
|
|
@ -31,6 +32,14 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
kuberuntime "k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/cli-runtime/pkg/resource"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest/fake"
|
||||
|
||||
"helm.sh/helm/v4/internal/test"
|
||||
chart "helm.sh/helm/v4/pkg/chart/v2"
|
||||
|
|
@ -48,6 +57,62 @@ type nameTemplateTestCase struct {
|
|||
expectedErrorStr string
|
||||
}
|
||||
|
||||
func createDummyResourceList(owned bool) kube.ResourceList {
|
||||
obj := &appsv1.Deployment{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "dummyName",
|
||||
Namespace: "spaced",
|
||||
},
|
||||
}
|
||||
|
||||
if owned {
|
||||
obj.Labels = map[string]string{
|
||||
"app.kubernetes.io/managed-by": "Helm",
|
||||
}
|
||||
obj.Annotations = map[string]string{
|
||||
"meta.helm.sh/release-name": "test-install-release",
|
||||
"meta.helm.sh/release-namespace": "spaced",
|
||||
}
|
||||
}
|
||||
|
||||
resInfo := resource.Info{
|
||||
Name: "dummyName",
|
||||
Namespace: "spaced",
|
||||
Mapping: &meta.RESTMapping{
|
||||
Resource: schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployment"},
|
||||
GroupVersionKind: schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "Deployment"},
|
||||
Scope: meta.RESTScopeNamespace,
|
||||
},
|
||||
Object: obj,
|
||||
}
|
||||
body := io.NopCloser(bytes.NewReader([]byte(kuberuntime.EncodeOrDie(appsv1Codec, obj))))
|
||||
|
||||
resInfo.Client = &fake.RESTClient{
|
||||
GroupVersion: schema.GroupVersion{Group: "apps", Version: "v1"},
|
||||
NegotiatedSerializer: scheme.Codecs.WithoutConversion(),
|
||||
Client: fake.CreateHTTPClient(func(_ *http.Request) (*http.Response, error) {
|
||||
header := http.Header{}
|
||||
header.Set("Content-Type", kuberuntime.ContentTypeJSON)
|
||||
return &http.Response{
|
||||
StatusCode: http.StatusOK,
|
||||
Header: header,
|
||||
Body: body,
|
||||
}, nil
|
||||
}),
|
||||
}
|
||||
var resourceList kube.ResourceList
|
||||
resourceList.Append(&resInfo)
|
||||
return resourceList
|
||||
}
|
||||
|
||||
func installActionWithConfig(config *Configuration) *Install {
|
||||
instAction := NewInstall(config)
|
||||
instAction.Namespace = "spaced"
|
||||
instAction.ReleaseName = "test-install-release"
|
||||
|
||||
return instAction
|
||||
}
|
||||
|
||||
func installAction(t *testing.T) *Install {
|
||||
config := actionConfigFixture(t)
|
||||
instAction := NewInstall(config)
|
||||
|
|
@ -93,6 +158,61 @@ func TestInstallRelease(t *testing.T) {
|
|||
is.Equal(lastRelease.Info.Status, release.StatusDeployed)
|
||||
}
|
||||
|
||||
func TestInstallReleaseWithTakeOwnership_ResourceNotOwned(t *testing.T) {
|
||||
// This test will test checking ownership of a resource
|
||||
// returned by the fake client. If the resource is not
|
||||
// owned by the chart, ownership is taken.
|
||||
// To verify ownership has been taken, the fake client
|
||||
// needs to store state which is a bigger rewrite.
|
||||
// TODO: Ensure fake kube client stores state. Maybe using
|
||||
// "k8s.io/client-go/kubernetes/fake" could be sufficient? i.e
|
||||
// "Client{Namespace: namespace, kubeClient: k8sfake.NewClientset()}"
|
||||
|
||||
is := assert.New(t)
|
||||
|
||||
// Resource list from cluster is NOT owned by helm chart
|
||||
config := actionConfigFixtureWithDummyResources(t, createDummyResourceList(false))
|
||||
instAction := installActionWithConfig(config)
|
||||
instAction.TakeOwnership = true
|
||||
res, err := instAction.Run(buildChart(), nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed install: %s", err)
|
||||
}
|
||||
|
||||
rel, err := instAction.cfg.Releases.Get(res.Name, res.Version)
|
||||
is.NoError(err)
|
||||
|
||||
is.Equal(rel.Info.Description, "Install complete")
|
||||
}
|
||||
|
||||
func TestInstallReleaseWithTakeOwnership_ResourceOwned(t *testing.T) {
|
||||
is := assert.New(t)
|
||||
|
||||
// Resource list from cluster is owned by helm chart
|
||||
config := actionConfigFixtureWithDummyResources(t, createDummyResourceList(true))
|
||||
instAction := installActionWithConfig(config)
|
||||
instAction.TakeOwnership = false
|
||||
res, err := instAction.Run(buildChart(), nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed install: %s", err)
|
||||
}
|
||||
rel, err := instAction.cfg.Releases.Get(res.Name, res.Version)
|
||||
is.NoError(err)
|
||||
|
||||
is.Equal(rel.Info.Description, "Install complete")
|
||||
}
|
||||
|
||||
func TestInstallReleaseWithTakeOwnership_ResourceOwnedNoFlag(t *testing.T) {
|
||||
is := assert.New(t)
|
||||
|
||||
// Resource list from cluster is NOT owned by helm chart
|
||||
config := actionConfigFixtureWithDummyResources(t, createDummyResourceList(false))
|
||||
instAction := installActionWithConfig(config)
|
||||
_, err := instAction.Run(buildChart(), nil)
|
||||
is.Error(err)
|
||||
is.Contains(err.Error(), "Unable to continue with install")
|
||||
}
|
||||
|
||||
func TestInstallReleaseWithValues(t *testing.T) {
|
||||
is := assert.New(t)
|
||||
instAction := installAction(t)
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ type FailingKubeClient struct {
|
|||
BuildError error
|
||||
BuildTableError error
|
||||
BuildDummy bool
|
||||
DummyResources kube.ResourceList
|
||||
BuildUnstructuredError error
|
||||
WaitError error
|
||||
WaitForDeleteError error
|
||||
|
|
@ -136,6 +137,9 @@ func (f *FailingKubeClient) Build(r io.Reader, _ bool) (kube.ResourceList, error
|
|||
if f.BuildError != nil {
|
||||
return []*resource.Info{}, f.BuildError
|
||||
}
|
||||
if f.DummyResources != nil {
|
||||
return f.DummyResources, nil
|
||||
}
|
||||
if f.BuildDummy {
|
||||
return createDummyResourceList(), nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue