1
16
17 package hash
18
19 import (
20 "reflect"
21 "strings"
22 "testing"
23
24 "k8s.io/api/core/v1"
25 )
26
27 func TestConfigMapHash(t *testing.T) {
28 cases := []struct {
29 desc string
30 cm *v1.ConfigMap
31 hash string
32 err string
33 }{
34
35 {"empty data", &v1.ConfigMap{Data: map[string]string{}, BinaryData: map[string][]byte{}}, "42745tchd9", ""},
36
37 {"one key", &v1.ConfigMap{Data: map[string]string{"one": ""}}, "9g67k2htb6", ""},
38
39 {"three keys", &v1.ConfigMap{Data: map[string]string{"two": "2", "one": "", "three": "3"}}, "f5h7t85m9b", ""},
40
41 {"empty binary data", &v1.ConfigMap{BinaryData: map[string][]byte{}}, "dk855m5d49", ""},
42
43 {"one key with binary data", &v1.ConfigMap{BinaryData: map[string][]byte{"one": []byte("")}}, "mk79584b8c", ""},
44
45 {"three keys with binary data", &v1.ConfigMap{BinaryData: map[string][]byte{"two": []byte("2"), "one": []byte(""), "three": []byte("3")}}, "t458mc6db2", ""},
46
47 {"two keys with one each", &v1.ConfigMap{Data: map[string]string{"one": ""}, BinaryData: map[string][]byte{"two": []byte("")}}, "698h7c7t9m", ""},
48 }
49
50 for _, c := range cases {
51 h, err := ConfigMapHash(c.cm)
52 if SkipRest(t, c.desc, err, c.err) {
53 continue
54 }
55 if c.hash != h {
56 t.Errorf("case %q, expect hash %q but got %q", c.desc, c.hash, h)
57 }
58 }
59 }
60
61 func TestSecretHash(t *testing.T) {
62 cases := []struct {
63 desc string
64 secret *v1.Secret
65 hash string
66 err string
67 }{
68
69 {"empty data", &v1.Secret{Type: "my-type", Data: map[string][]byte{}}, "t75bgf6ctb", ""},
70
71 {"one key", &v1.Secret{Type: "my-type", Data: map[string][]byte{"one": []byte("")}}, "74bd68bm66", ""},
72
73 {"three keys", &v1.Secret{Type: "my-type", Data: map[string][]byte{"two": []byte("2"), "one": []byte(""), "three": []byte("3")}}, "dgcb6h9tmk", ""},
74 }
75
76 for _, c := range cases {
77 h, err := SecretHash(c.secret)
78 if SkipRest(t, c.desc, err, c.err) {
79 continue
80 }
81 if c.hash != h {
82 t.Errorf("case %q, expect hash %q but got %q", c.desc, c.hash, h)
83 }
84 }
85 }
86
87 func TestEncodeConfigMap(t *testing.T) {
88 cases := []struct {
89 desc string
90 cm *v1.ConfigMap
91 expect string
92 err string
93 }{
94
95 {"empty data", &v1.ConfigMap{Data: map[string]string{}}, `{"data":{},"kind":"ConfigMap","name":""}`, ""},
96
97 {"one key", &v1.ConfigMap{Data: map[string]string{"one": ""}}, `{"data":{"one":""},"kind":"ConfigMap","name":""}`, ""},
98
99 {"three keys", &v1.ConfigMap{Data: map[string]string{"two": "2", "one": "", "three": "3"}}, `{"data":{"one":"","three":"3","two":"2"},"kind":"ConfigMap","name":""}`, ""},
100
101 {"empty data", &v1.ConfigMap{BinaryData: map[string][]byte{}}, `{"data":null,"kind":"ConfigMap","name":""}`, ""},
102
103 {"one key", &v1.ConfigMap{BinaryData: map[string][]byte{"one": []byte("")}}, `{"binaryData":{"one":""},"data":null,"kind":"ConfigMap","name":""}`, ""},
104
105 {"three keys", &v1.ConfigMap{BinaryData: map[string][]byte{"two": []byte("2"), "one": []byte(""), "three": []byte("3")}}, `{"binaryData":{"one":"","three":"Mw==","two":"Mg=="},"data":null,"kind":"ConfigMap","name":""}`, ""},
106
107 {"two keys with one each", &v1.ConfigMap{Data: map[string]string{"one": ""}, BinaryData: map[string][]byte{"two": []byte("")}}, `{"binaryData":{"two":""},"data":{"one":""},"kind":"ConfigMap","name":""}`, ""},
108 }
109 for _, c := range cases {
110 s, err := encodeConfigMap(c.cm)
111 if SkipRest(t, c.desc, err, c.err) {
112 continue
113 }
114 if s != c.expect {
115 t.Errorf("case %q, expect %q but got %q from encode %#v", c.desc, c.expect, s, c.cm)
116 }
117 }
118 }
119
120 func TestEncodeSecret(t *testing.T) {
121 cases := []struct {
122 desc string
123 secret *v1.Secret
124 expect string
125 err string
126 }{
127
128 {"empty data", &v1.Secret{Type: "my-type", Data: map[string][]byte{}}, `{"data":{},"kind":"Secret","name":"","type":"my-type"}`, ""},
129
130 {"one key", &v1.Secret{Type: "my-type", Data: map[string][]byte{"one": []byte("")}}, `{"data":{"one":""},"kind":"Secret","name":"","type":"my-type"}`, ""},
131
132 {"three keys", &v1.Secret{Type: "my-type", Data: map[string][]byte{"two": []byte("2"), "one": []byte(""), "three": []byte("3")}}, `{"data":{"one":"","three":"Mw==","two":"Mg=="},"kind":"Secret","name":"","type":"my-type"}`, ""},
133 }
134 for _, c := range cases {
135 s, err := encodeSecret(c.secret)
136 if SkipRest(t, c.desc, err, c.err) {
137 continue
138 }
139 if s != c.expect {
140 t.Errorf("case %q, expect %q but got %q from encode %#v", c.desc, c.expect, s, c.secret)
141 }
142 }
143 }
144
145 func TestHash(t *testing.T) {
146
147 expect := "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
148 sum := hash("")
149 if expect != sum {
150 t.Errorf("expected hash %q but got %q", expect, sum)
151 }
152 }
153
154
155
156 func TestTypeStability(t *testing.T) {
157 errfmt := `case %q, expected %d fields but got %d
158 Depending on the field(s) you added, you may need to modify the hash function for this type.
159 To guide you: the hash function targets fields that comprise the contents of objects,
160 not their metadata (e.g. the Data of a ConfigMap, but nothing in ObjectMeta).
161 `
162 cases := []struct {
163 typeName string
164 obj interface{}
165 expect int
166 }{
167 {"ConfigMap", v1.ConfigMap{}, 5},
168 {"Secret", v1.Secret{}, 6},
169 }
170 for _, c := range cases {
171 val := reflect.ValueOf(c.obj)
172 if num := val.NumField(); c.expect != num {
173 t.Errorf(errfmt, c.typeName, c.expect, num)
174 }
175 }
176 }
177
178
179
180
181 func SkipRest(t *testing.T, desc string, err error, contains string) bool {
182 if err != nil {
183 if len(contains) == 0 {
184 t.Errorf("case %q, expect nil error but got %q", desc, err.Error())
185 } else if !strings.Contains(err.Error(), contains) {
186 t.Errorf("case %q, expect error to contain %q but got %q", desc, contains, err.Error())
187 }
188 return true
189 } else if len(contains) > 0 {
190 t.Errorf("case %q, expect error to contain %q but got nil error", desc, contains)
191 return true
192 }
193 return false
194 }
195
View as plain text