github.com/azure-devops-engineer/helm@v3.0.0-alpha.2+incompatible/pkg/action/action_test.go (about)

     1  /*
     2  Copyright The Helm Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  package action
    17  
    18  import (
    19  	"flag"
    20  	"io/ioutil"
    21  	"testing"
    22  	"time"
    23  
    24  	fakeclientset "k8s.io/client-go/kubernetes/fake"
    25  
    26  	"helm.sh/helm/pkg/chart"
    27  	"helm.sh/helm/pkg/chartutil"
    28  	kubefake "helm.sh/helm/pkg/kube/fake"
    29  	"helm.sh/helm/pkg/release"
    30  	"helm.sh/helm/pkg/storage"
    31  	"helm.sh/helm/pkg/storage/driver"
    32  )
    33  
    34  var verbose = flag.Bool("test.log", false, "enable test logging")
    35  
    36  func actionConfigFixture(t *testing.T) *Configuration {
    37  	t.Helper()
    38  
    39  	return &Configuration{
    40  		Releases:     storage.Init(driver.NewMemory()),
    41  		KubeClient:   &kubefake.FailingKubeClient{PrintingKubeClient: kubefake.PrintingKubeClient{Out: ioutil.Discard}},
    42  		Capabilities: chartutil.DefaultCapabilities,
    43  		Log: func(format string, v ...interface{}) {
    44  			t.Helper()
    45  			if *verbose {
    46  				t.Logf(format, v...)
    47  			}
    48  		},
    49  	}
    50  }
    51  
    52  var manifestWithHook = `kind: ConfigMap
    53  metadata:
    54    name: test-cm
    55    annotations:
    56      "helm.sh/hook": post-install,pre-delete,post-upgrade
    57  data:
    58    name: value`
    59  
    60  var manifestWithTestHook = `kind: Pod
    61    metadata:
    62  	name: finding-nemo,
    63  	annotations:
    64  	  "helm.sh/hook": test-success
    65    spec:
    66  	containers:
    67  	- name: nemo-test
    68  	  image: fake-image
    69  	  cmd: fake-command
    70    `
    71  
    72  var rbacManifests = `apiVersion: rbac.authorization.k8s.io/v1
    73  kind: Role
    74  metadata:
    75    name: schedule-agents
    76  rules:
    77  - apiGroups: [""]
    78    resources: ["pods", "pods/exec", "pods/log"]
    79    verbs: ["*"]
    80  
    81  ---
    82  
    83  apiVersion: rbac.authorization.k8s.io/v1
    84  kind: RoleBinding
    85  metadata:
    86    name: schedule-agents
    87    namespace: {{ default .Release.Namespace}}
    88  roleRef:
    89    apiGroup: rbac.authorization.k8s.io
    90    kind: Role
    91    name: schedule-agents
    92  subjects:
    93  - kind: ServiceAccount
    94    name: schedule-agents
    95    namespace: {{ .Release.Namespace }}
    96  `
    97  
    98  type chartOptions struct {
    99  	*chart.Chart
   100  }
   101  
   102  type chartOption func(*chartOptions)
   103  
   104  func buildChart(opts ...chartOption) *chart.Chart {
   105  	c := &chartOptions{
   106  		Chart: &chart.Chart{
   107  			// TODO: This should be more complete.
   108  			Metadata: &chart.Metadata{
   109  				Name: "hello",
   110  			},
   111  			// This adds a basic template and hooks.
   112  			Templates: []*chart.File{
   113  				{Name: "templates/hello", Data: []byte("hello: world")},
   114  				{Name: "templates/hooks", Data: []byte(manifestWithHook)},
   115  			},
   116  		},
   117  	}
   118  
   119  	for _, opt := range opts {
   120  		opt(c)
   121  	}
   122  
   123  	return c.Chart
   124  }
   125  
   126  func withNotes(notes string) chartOption {
   127  	return func(opts *chartOptions) {
   128  		opts.Templates = append(opts.Templates, &chart.File{
   129  			Name: "templates/NOTES.txt",
   130  			Data: []byte(notes),
   131  		})
   132  	}
   133  }
   134  
   135  func withDependency(dependencyOpts ...chartOption) chartOption {
   136  	return func(opts *chartOptions) {
   137  		opts.AddDependency(buildChart(dependencyOpts...))
   138  	}
   139  }
   140  
   141  func withSampleTemplates() chartOption {
   142  	return func(opts *chartOptions) {
   143  		sampleTemplates := []*chart.File{
   144  			// This adds basic templates and partials.
   145  			{Name: "templates/goodbye", Data: []byte("goodbye: world")},
   146  			{Name: "templates/empty", Data: []byte("")},
   147  			{Name: "templates/with-partials", Data: []byte(`hello: {{ template "_planet" . }}`)},
   148  			{Name: "templates/partials/_planet", Data: []byte(`{{define "_planet"}}Earth{{end}}`)},
   149  		}
   150  		opts.Templates = append(opts.Templates, sampleTemplates...)
   151  	}
   152  }
   153  
   154  func withMultipleManifestTemplate() chartOption {
   155  	return func(opts *chartOptions) {
   156  		sampleTemplates := []*chart.File{
   157  			{Name: "templates/rbac", Data: []byte(rbacManifests)},
   158  		}
   159  		opts.Templates = append(opts.Templates, sampleTemplates...)
   160  	}
   161  }
   162  
   163  func withKube(version string) chartOption {
   164  	return func(opts *chartOptions) {
   165  		opts.Metadata.KubeVersion = version
   166  	}
   167  }
   168  
   169  // releaseStub creates a release stub, complete with the chartStub as its chart.
   170  func releaseStub() *release.Release {
   171  	return namedReleaseStub("angry-panda", release.StatusDeployed)
   172  }
   173  
   174  func namedReleaseStub(name string, status release.Status) *release.Release {
   175  	now := time.Now()
   176  	return &release.Release{
   177  		Name: name,
   178  		Info: &release.Info{
   179  			FirstDeployed: now,
   180  			LastDeployed:  now,
   181  			Status:        status,
   182  			Description:   "Named Release Stub",
   183  		},
   184  		Chart:   buildChart(withSampleTemplates()),
   185  		Config:  map[string]interface{}{"name": "value"},
   186  		Version: 1,
   187  		Hooks: []*release.Hook{
   188  			{
   189  				Name:     "test-cm",
   190  				Kind:     "ConfigMap",
   191  				Path:     "test-cm",
   192  				Manifest: manifestWithHook,
   193  				Events: []release.HookEvent{
   194  					release.HookPostInstall,
   195  					release.HookPreDelete,
   196  				},
   197  			},
   198  			{
   199  				Name:     "finding-nemo",
   200  				Kind:     "Pod",
   201  				Path:     "finding-nemo",
   202  				Manifest: manifestWithTestHook,
   203  				Events: []release.HookEvent{
   204  					release.HookReleaseTestSuccess,
   205  				},
   206  			},
   207  		},
   208  	}
   209  }
   210  
   211  func TestGetVersionSet(t *testing.T) {
   212  	client := fakeclientset.NewSimpleClientset()
   213  
   214  	vs, err := GetVersionSet(client.Discovery())
   215  	if err != nil {
   216  		t.Error(err)
   217  	}
   218  
   219  	if !vs.Has("v1") {
   220  		t.Errorf("Expected supported versions to at least include v1.")
   221  	}
   222  	if vs.Has("nosuchversion/v1") {
   223  		t.Error("Non-existent version is reported found.")
   224  	}
   225  }