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 }