1/*
2Copyright 2014 The Kubernetes Authors.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8    http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17package generate
18
19import (
20	"fmt"
21	"reflect"
22	"strings"
23	"testing"
24
25	"github.com/spf13/cobra"
26)
27
28type TestStruct struct {
29	val int
30}
31
32func TestIsZero(t *testing.T) {
33	tests := []struct {
34		name       string
35		val        interface{}
36		expectZero bool
37	}{
38		{
39			name:       "test1",
40			val:        "",
41			expectZero: true,
42		},
43		{
44			name:       "test2",
45			val:        nil,
46			expectZero: true,
47		},
48		{
49			name:       "test3",
50			val:        0,
51			expectZero: true,
52		},
53		{
54			name:       "test4",
55			val:        TestStruct{},
56			expectZero: true,
57		},
58		{
59			name:       "test5",
60			val:        "foo",
61			expectZero: false,
62		},
63		{
64			name:       "test6",
65			val:        1,
66			expectZero: false,
67		},
68		{
69			name:       "test7",
70			val:        TestStruct{val: 2},
71			expectZero: false,
72		},
73	}
74
75	for _, tt := range tests {
76		t.Run(tt.name, func(t *testing.T) {
77			output := IsZero(tt.val)
78			if output != tt.expectZero {
79				t.Errorf("expected: %v, saw %v", tt.expectZero, output)
80			}
81		})
82	}
83}
84
85func TestValidateParams(t *testing.T) {
86	tests := []struct {
87		name      string
88		paramSpec []GeneratorParam
89		params    map[string]interface{}
90		valid     bool
91	}{
92		{
93			name:      "test1",
94			paramSpec: []GeneratorParam{},
95			params:    map[string]interface{}{},
96			valid:     true,
97		},
98		{
99			name: "test2",
100			paramSpec: []GeneratorParam{
101				{Name: "foo"},
102			},
103			params: map[string]interface{}{},
104			valid:  true,
105		},
106		{
107			name: "test3",
108			paramSpec: []GeneratorParam{
109				{Name: "foo", Required: true},
110			},
111			params: map[string]interface{}{
112				"foo": "bar",
113			},
114			valid: true,
115		},
116		{
117			name: "test4",
118			paramSpec: []GeneratorParam{
119				{Name: "foo", Required: true},
120			},
121			params: map[string]interface{}{
122				"baz": "blah",
123				"foo": "bar",
124			},
125			valid: true,
126		},
127		{
128			name: "test5",
129			paramSpec: []GeneratorParam{
130				{Name: "foo", Required: true},
131				{Name: "baz", Required: true},
132			},
133			params: map[string]interface{}{
134				"baz": "blah",
135				"foo": "bar",
136			},
137			valid: true,
138		},
139		{
140			name: "test6",
141			paramSpec: []GeneratorParam{
142				{Name: "foo", Required: true},
143				{Name: "baz", Required: true},
144			},
145			params: map[string]interface{}{
146				"foo": "bar",
147			},
148			valid: false,
149		},
150	}
151	for _, tt := range tests {
152		t.Run(tt.name, func(t *testing.T) {
153			err := ValidateParams(tt.paramSpec, tt.params)
154			if tt.valid && err != nil {
155				t.Errorf("unexpected error: %v", err)
156			}
157			if !tt.valid && err == nil {
158				t.Errorf("unexpected non-error")
159			}
160		})
161	}
162}
163
164func TestMakeParams(t *testing.T) {
165	cmd := &cobra.Command{}
166	cmd.Flags().String("foo", "bar", "")
167	cmd.Flags().String("baz", "", "")
168	cmd.Flags().Set("baz", "blah")
169
170	paramSpec := []GeneratorParam{
171		{Name: "foo", Required: true},
172		{Name: "baz", Required: true},
173	}
174	expected := map[string]interface{}{
175		"foo": "bar",
176		"baz": "blah",
177	}
178	params := MakeParams(cmd, paramSpec)
179	if !reflect.DeepEqual(params, expected) {
180		t.Errorf("\nexpected:\n%v\nsaw:\n%v", expected, params)
181	}
182}
183
184func TestGetBool(t *testing.T) {
185	testCases := []struct {
186		name         string
187		parameters   map[string]string
188		key          string
189		defaultValue bool
190		expected     bool
191		expectError  bool
192	}{
193		{
194			name: "found key in parameters, default value is different from key value",
195			parameters: map[string]string{
196				"foo": "false",
197			},
198			key:          "foo",
199			defaultValue: false,
200			expected:     false,
201			expectError:  false,
202		},
203		{
204			name: "found key in parameters, default value is same with key value",
205			parameters: map[string]string{
206				"foo": "true",
207			},
208			key:          "foo",
209			defaultValue: true,
210			expected:     true,
211			expectError:  false,
212		},
213		{
214			name: "key not found in parameters, default value is true",
215			parameters: map[string]string{
216				"foo": "true",
217				"far": "false",
218			},
219			key:          "bar",
220			defaultValue: true,
221			expected:     true,
222			expectError:  false,
223		},
224		{
225			name: "key not found in parameters, default value is false",
226			parameters: map[string]string{
227				"foo": "true",
228				"far": "false",
229			},
230			key:          "bar",
231			defaultValue: false,
232			expected:     false,
233			expectError:  false,
234		},
235		{
236			name:         "parameters is empty",
237			parameters:   map[string]string{},
238			key:          "foo",
239			defaultValue: true,
240			expected:     true,
241			expectError:  false,
242		},
243		{
244			name: "parameters key is not a valid bool value",
245			parameters: map[string]string{
246				"foo": "error",
247			},
248			key:          "foo",
249			defaultValue: true,
250			expected:     false,
251			expectError:  true,
252		},
253	}
254	for _, tt := range testCases {
255		t.Run(tt.name, func(t *testing.T) {
256			got, err := GetBool(tt.parameters, tt.key, tt.defaultValue)
257			if err != nil && tt.expectError == false {
258				t.Errorf("%s: unexpected error: %v", tt.name, err)
259			}
260			if err == nil && tt.expectError == true {
261				t.Errorf("%s: expect error, got nil", tt.name)
262			}
263			if got != tt.expected {
264				t.Errorf("%s: expect %v, got %v", tt.name, tt.expected, got)
265			}
266		})
267	}
268}
269
270func makeLabels(labels map[string]string) string {
271	out := []string{}
272	for key, value := range labels {
273		out = append(out, fmt.Sprintf("%s=%s", key, value))
274	}
275	return strings.Join(out, ",")
276}
277
278func TestMakeParseLabels(t *testing.T) {
279	successCases := []struct {
280		name     string
281		labels   map[string]string
282		expected map[string]string
283	}{
284		{
285			name: "test1",
286			labels: map[string]string{
287				"foo": "false",
288			},
289			expected: map[string]string{
290				"foo": "false",
291			},
292		},
293		{
294			name: "test2",
295			labels: map[string]string{
296				"foo": "true",
297				"bar": "123",
298			},
299			expected: map[string]string{
300				"foo": "true",
301				"bar": "123",
302			},
303		},
304	}
305	for _, tt := range successCases {
306		t.Run(tt.name, func(t *testing.T) {
307			labelString := makeLabels(tt.labels)
308			got, err := ParseLabels(labelString)
309			if err != nil {
310				t.Errorf("unexpected error :%v", err)
311			}
312			if !reflect.DeepEqual(tt.expected, got) {
313				t.Errorf("\nexpected:\n%v\ngot:\n%v", tt.expected, got)
314			}
315		})
316	}
317
318	errorCases := []struct {
319		name   string
320		labels interface{}
321	}{
322		{
323			name:   "non-string",
324			labels: 123,
325		},
326		{
327			name:   "empty string",
328			labels: "",
329		},
330		{
331			name:   "error format",
332			labels: "abc=456;bcd=789",
333		},
334		{
335			name:   "error format",
336			labels: "abc=456.bcd=789",
337		},
338		{
339			name:   "error format",
340			labels: "abc,789",
341		},
342		{
343			name:   "error format",
344			labels: "abc",
345		},
346		{
347			name:   "error format",
348			labels: "=abc",
349		},
350	}
351	for _, test := range errorCases {
352		_, err := ParseLabels(test.labels)
353		if err == nil {
354			t.Errorf("labels %s expect error, reason: %s, got nil", test.labels, test.name)
355		}
356	}
357}
358
359func TestMakeParseProtocols(t *testing.T) {
360	successCases := []struct {
361		name      string
362		protocols map[string]string
363		expected  map[string]string
364	}{
365		{
366			name: "test1",
367			protocols: map[string]string{
368				"101": "TCP",
369			},
370			expected: map[string]string{
371				"101": "TCP",
372			},
373		},
374		{
375			name: "test2",
376			protocols: map[string]string{
377				"102": "UDP",
378				"101": "TCP",
379				"103": "SCTP",
380			},
381			expected: map[string]string{
382				"102": "UDP",
383				"101": "TCP",
384				"103": "SCTP",
385			},
386		},
387	}
388	for _, tt := range successCases {
389		t.Run(tt.name, func(t *testing.T) {
390			protocolString := MakeProtocols(tt.protocols)
391			got, err := ParseProtocols(protocolString)
392			if err != nil {
393				t.Errorf("unexpected error :%v", err)
394			}
395			if !reflect.DeepEqual(tt.expected, got) {
396				t.Errorf("\nexpected:\n%v\ngot:\n%v", tt.expected, got)
397			}
398		})
399	}
400
401	errorCases := []struct {
402		name      string
403		protocols interface{}
404	}{
405		{
406			name:      "non-string",
407			protocols: 123,
408		},
409		{
410			name:      "empty string",
411			protocols: "",
412		},
413		{
414			name:      "error format",
415			protocols: "123/TCP;456/UDP",
416		},
417		{
418			name:      "error format",
419			protocols: "123/TCP.456/UDP",
420		},
421		{
422			name:      "error format",
423			protocols: "123=456",
424		},
425		{
426			name:      "error format",
427			protocols: "123",
428		},
429		{
430			name:      "error format",
431			protocols: "123=",
432		},
433		{
434			name:      "error format",
435			protocols: "=TCP",
436		},
437	}
438	for _, test := range errorCases {
439		_, err := ParseProtocols(test.protocols)
440		if err == nil {
441			t.Errorf("protocols %s expect error, reason: %s, got nil", test.protocols, test.name)
442		}
443	}
444}
445