1
16
17 package cli
18
19 import (
20 "os"
21 "reflect"
22 "strings"
23 "testing"
24
25 "github.com/spf13/pflag"
26
27 "helm.sh/helm/v3/internal/version"
28 )
29
30 func TestSetNamespace(t *testing.T) {
31 settings := New()
32
33 if settings.namespace != "" {
34 t.Errorf("Expected empty namespace, got %s", settings.namespace)
35 }
36
37 settings.SetNamespace("testns")
38 if settings.namespace != "testns" {
39 t.Errorf("Expected namespace testns, got %s", settings.namespace)
40 }
41
42 }
43
44 func TestEnvSettings(t *testing.T) {
45 tests := []struct {
46 name string
47
48
49 args string
50 envvars map[string]string
51
52
53 ns, kcontext string
54 debug bool
55 maxhistory int
56 kubeAsUser string
57 kubeAsGroups []string
58 kubeCaFile string
59 kubeInsecure bool
60 kubeTLSServer string
61 burstLimit int
62 qps float32
63 }{
64 {
65 name: "defaults",
66 ns: "default",
67 maxhistory: defaultMaxHistory,
68 burstLimit: defaultBurstLimit,
69 qps: defaultQPS,
70 },
71 {
72 name: "with flags set",
73 args: "--debug --namespace=myns --kube-as-user=poro --kube-as-group=admins --kube-as-group=teatime --kube-as-group=snackeaters --kube-ca-file=/tmp/ca.crt --burst-limit 100 --qps 50.12 --kube-insecure-skip-tls-verify=true --kube-tls-server-name=example.org",
74 ns: "myns",
75 debug: true,
76 maxhistory: defaultMaxHistory,
77 burstLimit: 100,
78 qps: 50.12,
79 kubeAsUser: "poro",
80 kubeAsGroups: []string{"admins", "teatime", "snackeaters"},
81 kubeCaFile: "/tmp/ca.crt",
82 kubeTLSServer: "example.org",
83 kubeInsecure: true,
84 },
85 {
86 name: "with envvars set",
87 envvars: map[string]string{"HELM_DEBUG": "1", "HELM_NAMESPACE": "yourns", "HELM_KUBEASUSER": "pikachu", "HELM_KUBEASGROUPS": ",,,operators,snackeaters,partyanimals", "HELM_MAX_HISTORY": "5", "HELM_KUBECAFILE": "/tmp/ca.crt", "HELM_BURST_LIMIT": "150", "HELM_KUBEINSECURE_SKIP_TLS_VERIFY": "true", "HELM_KUBETLS_SERVER_NAME": "example.org", "HELM_QPS": "60.34"},
88 ns: "yourns",
89 maxhistory: 5,
90 burstLimit: 150,
91 qps: 60.34,
92 debug: true,
93 kubeAsUser: "pikachu",
94 kubeAsGroups: []string{"operators", "snackeaters", "partyanimals"},
95 kubeCaFile: "/tmp/ca.crt",
96 kubeTLSServer: "example.org",
97 kubeInsecure: true,
98 },
99 {
100 name: "with flags and envvars set",
101 args: "--debug --namespace=myns --kube-as-user=poro --kube-as-group=admins --kube-as-group=teatime --kube-as-group=snackeaters --kube-ca-file=/my/ca.crt --burst-limit 175 --qps 70 --kube-insecure-skip-tls-verify=true --kube-tls-server-name=example.org",
102 envvars: map[string]string{"HELM_DEBUG": "1", "HELM_NAMESPACE": "yourns", "HELM_KUBEASUSER": "pikachu", "HELM_KUBEASGROUPS": ",,,operators,snackeaters,partyanimals", "HELM_MAX_HISTORY": "5", "HELM_KUBECAFILE": "/tmp/ca.crt", "HELM_BURST_LIMIT": "200", "HELM_KUBEINSECURE_SKIP_TLS_VERIFY": "true", "HELM_KUBETLS_SERVER_NAME": "example.org", "HELM_QPS": "40"},
103 ns: "myns",
104 debug: true,
105 maxhistory: 5,
106 burstLimit: 175,
107 qps: 70,
108 kubeAsUser: "poro",
109 kubeAsGroups: []string{"admins", "teatime", "snackeaters"},
110 kubeCaFile: "/my/ca.crt",
111 kubeTLSServer: "example.org",
112 kubeInsecure: true,
113 },
114 {
115 name: "invalid kubeconfig",
116 ns: "testns",
117 args: "--namespace=testns --kubeconfig=/path/to/fake/file",
118 maxhistory: defaultMaxHistory,
119 burstLimit: defaultBurstLimit,
120 qps: defaultQPS,
121 },
122 }
123
124 for _, tt := range tests {
125 t.Run(tt.name, func(t *testing.T) {
126 defer resetEnv()()
127
128 for k, v := range tt.envvars {
129 os.Setenv(k, v)
130 }
131
132 flags := pflag.NewFlagSet("testing", pflag.ContinueOnError)
133
134 settings := New()
135 settings.AddFlags(flags)
136 flags.Parse(strings.Split(tt.args, " "))
137
138 if settings.Debug != tt.debug {
139 t.Errorf("expected debug %t, got %t", tt.debug, settings.Debug)
140 }
141 if settings.Namespace() != tt.ns {
142 t.Errorf("expected namespace %q, got %q", tt.ns, settings.Namespace())
143 }
144 if settings.KubeContext != tt.kcontext {
145 t.Errorf("expected kube-context %q, got %q", tt.kcontext, settings.KubeContext)
146 }
147 if settings.MaxHistory != tt.maxhistory {
148 t.Errorf("expected maxHistory %d, got %d", tt.maxhistory, settings.MaxHistory)
149 }
150 if tt.kubeAsUser != settings.KubeAsUser {
151 t.Errorf("expected kAsUser %q, got %q", tt.kubeAsUser, settings.KubeAsUser)
152 }
153 if !reflect.DeepEqual(tt.kubeAsGroups, settings.KubeAsGroups) {
154 t.Errorf("expected kAsGroups %+v, got %+v", len(tt.kubeAsGroups), len(settings.KubeAsGroups))
155 }
156 if tt.kubeCaFile != settings.KubeCaFile {
157 t.Errorf("expected kCaFile %q, got %q", tt.kubeCaFile, settings.KubeCaFile)
158 }
159 if tt.burstLimit != settings.BurstLimit {
160 t.Errorf("expected BurstLimit %d, got %d", tt.burstLimit, settings.BurstLimit)
161 }
162 if tt.kubeInsecure != settings.KubeInsecureSkipTLSVerify {
163 t.Errorf("expected kubeInsecure %t, got %t", tt.kubeInsecure, settings.KubeInsecureSkipTLSVerify)
164 }
165 if tt.kubeTLSServer != settings.KubeTLSServerName {
166 t.Errorf("expected kubeTLSServer %q, got %q", tt.kubeTLSServer, settings.KubeTLSServerName)
167 }
168 })
169 }
170 }
171
172 func TestEnvOrBool(t *testing.T) {
173 const envName = "TEST_ENV_OR_BOOL"
174 tests := []struct {
175 name string
176 env string
177 val string
178 def bool
179 expected bool
180 }{
181 {
182 name: "unset with default false",
183 def: false,
184 expected: false,
185 },
186 {
187 name: "unset with default true",
188 def: true,
189 expected: true,
190 },
191 {
192 name: "blank env with default false",
193 env: envName,
194 def: false,
195 expected: false,
196 },
197 {
198 name: "blank env with default true",
199 env: envName,
200 def: true,
201 expected: true,
202 },
203 {
204 name: "env true with default false",
205 env: envName,
206 val: "true",
207 def: false,
208 expected: true,
209 },
210 {
211 name: "env false with default true",
212 env: envName,
213 val: "false",
214 def: true,
215 expected: false,
216 },
217 {
218 name: "env fails parsing with default true",
219 env: envName,
220 val: "NOT_A_BOOL",
221 def: true,
222 expected: true,
223 },
224 {
225 name: "env fails parsing with default false",
226 env: envName,
227 val: "NOT_A_BOOL",
228 def: false,
229 expected: false,
230 },
231 }
232
233 for _, tt := range tests {
234 t.Run(tt.name, func(t *testing.T) {
235 if tt.env != "" {
236 t.Cleanup(func() {
237 os.Unsetenv(tt.env)
238 })
239 os.Setenv(tt.env, tt.val)
240 }
241 actual := envBoolOr(tt.env, tt.def)
242 if actual != tt.expected {
243 t.Errorf("expected result %t, got %t", tt.expected, actual)
244 }
245 })
246 }
247 }
248
249 func TestUserAgentHeaderInK8sRESTClientConfig(t *testing.T) {
250 defer resetEnv()()
251
252 settings := New()
253 restConfig, err := settings.RESTClientGetter().ToRESTConfig()
254 if err != nil {
255 t.Fatal(err)
256 }
257
258 expectedUserAgent := version.GetUserAgent()
259 if restConfig.UserAgent != expectedUserAgent {
260 t.Errorf("expected User-Agent header %q in K8s REST client config, got %q", expectedUserAgent, restConfig.UserAgent)
261 }
262 }
263
264 func resetEnv() func() {
265 origEnv := os.Environ()
266
267
268 for e := range New().EnvVars() {
269 os.Unsetenv(e)
270 }
271
272 return func() {
273 for _, pair := range origEnv {
274 kv := strings.SplitN(pair, "=", 2)
275 os.Setenv(kv[0], kv[1])
276 }
277 }
278 }
279
View as plain text