1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package tag
17
18 import (
19 "context"
20 "fmt"
21 "reflect"
22 "strings"
23 "testing"
24 )
25
26 var (
27 ttlUnlimitedPropMd = createMetadatas(WithTTL(TTLUnlimitedPropagation))
28 ttlNoPropMd = createMetadatas(WithTTL(TTLNoPropagation))
29 )
30
31 func TestContext(t *testing.T) {
32 k1, _ := NewKey("k1")
33 k2, _ := NewKey("k2")
34
35 ctx := context.Background()
36 ctx, _ = New(ctx,
37 Insert(k1, "v1"),
38 Insert(k2, "v2"),
39 )
40 got := FromContext(ctx)
41 want := newMap()
42 want.insert(k1, "v1", ttlUnlimitedPropMd)
43 want.insert(k2, "v2", ttlUnlimitedPropMd)
44
45 if !reflect.DeepEqual(got, want) {
46 t.Errorf("Map = %#v; want %#v", got, want)
47 }
48 }
49
50 func TestDo(t *testing.T) {
51 k1, _ := NewKey("k1")
52 k2, _ := NewKey("k2")
53 ctx := context.Background()
54 ctx, _ = New(ctx,
55 Insert(k1, "v1"),
56 Insert(k2, "v2"),
57 )
58 got := FromContext(ctx)
59 want := newMap()
60 want.insert(k1, "v1", ttlUnlimitedPropMd)
61 want.insert(k2, "v2", ttlUnlimitedPropMd)
62 Do(ctx, func(ctx context.Context) {
63 got = FromContext(ctx)
64 })
65 if !reflect.DeepEqual(got, want) {
66 t.Errorf("Map = %#v; want %#v", got, want)
67 }
68 }
69
70 func TestNewMap(t *testing.T) {
71 k1, _ := NewKey("k1")
72 k2, _ := NewKey("k2")
73 k3, _ := NewKey("k3")
74 k4, _ := NewKey("k4")
75 k5, _ := NewKey("k5")
76
77 initial := makeTestTagMap(5)
78
79 tests := []struct {
80 name string
81 initial *Map
82 mods []Mutator
83 want *Map
84 }{
85 {
86 name: "from empty; insert",
87 initial: nil,
88 mods: []Mutator{
89 Insert(k5, "v5"),
90 },
91 want: makeTestTagMap(2, 4, 5),
92 },
93 {
94 name: "from empty; insert existing",
95 initial: nil,
96 mods: []Mutator{
97 Insert(k1, "v1"),
98 },
99 want: makeTestTagMap(1, 2, 4),
100 },
101 {
102 name: "from empty; update",
103 initial: nil,
104 mods: []Mutator{
105 Update(k1, "v1"),
106 },
107 want: makeTestTagMap(2, 4),
108 },
109 {
110 name: "from empty; update unexisting",
111 initial: nil,
112 mods: []Mutator{
113 Update(k5, "v5"),
114 },
115 want: makeTestTagMap(2, 4),
116 },
117 {
118 name: "from existing; upsert",
119 initial: initial,
120 mods: []Mutator{
121 Upsert(k5, "v5"),
122 },
123 want: makeTestTagMap(2, 4, 5),
124 },
125 {
126 name: "from existing; delete",
127 initial: initial,
128 mods: []Mutator{
129 Delete(k2),
130 },
131 want: makeTestTagMap(4, 5),
132 },
133 {
134 name: "from empty; invalid",
135 initial: nil,
136 mods: []Mutator{
137 Insert(k5, "v\x19"),
138 Upsert(k5, "v\x19"),
139 Update(k5, "v\x19"),
140 },
141 want: nil,
142 },
143 {
144 name: "from empty; no partial",
145 initial: nil,
146 mods: []Mutator{
147 Insert(k5, "v1"),
148 Update(k5, "v\x19"),
149 },
150 want: nil,
151 },
152 }
153
154 for _, tt := range tests {
155 mods := []Mutator{
156 Insert(k1, "v1"),
157 Insert(k2, "v2"),
158 Update(k3, "v3"),
159 Upsert(k4, "v4"),
160 Insert(k2, "v2"),
161 Delete(k1),
162 }
163 mods = append(mods, tt.mods...)
164 ctx := NewContext(context.Background(), tt.initial)
165 ctx, err := New(ctx, mods...)
166 if tt.want != nil && err != nil {
167 t.Errorf("%v: New = %v", tt.name, err)
168 }
169
170 if got, want := FromContext(ctx), tt.want; !reflect.DeepEqual(got, want) {
171 t.Errorf("%v: got %v; want %v", tt.name, got, want)
172 }
173 }
174 }
175
176 func TestNewMapWithMetadata(t *testing.T) {
177 k3, _ := NewKey("k3")
178 k4, _ := NewKey("k4")
179 k5, _ := NewKey("k5")
180
181 tests := []struct {
182 name string
183 initial *Map
184 mods []Mutator
185 want *Map
186 }{
187 {
188 name: "from empty; insert",
189 initial: nil,
190 mods: []Mutator{
191 Insert(k5, "5", WithTTL(TTLNoPropagation)),
192 Insert(k4, "4"),
193 },
194 want: makeTestTagMapWithMetadata(
195 tagContent{"5", ttlNoPropMd},
196 tagContent{"4", ttlUnlimitedPropMd}),
197 },
198 {
199 name: "from existing; insert existing",
200 initial: makeTestTagMapWithMetadata(tagContent{"5", ttlNoPropMd}),
201 mods: []Mutator{
202 Insert(k5, "5", WithTTL(TTLUnlimitedPropagation)),
203 },
204 want: makeTestTagMapWithMetadata(tagContent{"5", ttlNoPropMd}),
205 },
206 {
207 name: "from existing; update non-existing",
208 initial: makeTestTagMapWithMetadata(tagContent{"5", ttlNoPropMd}),
209 mods: []Mutator{
210 Update(k4, "4", WithTTL(TTLUnlimitedPropagation)),
211 },
212 want: makeTestTagMapWithMetadata(tagContent{"5", ttlNoPropMd}),
213 },
214 {
215 name: "from existing; update existing",
216 initial: makeTestTagMapWithMetadata(
217 tagContent{"5", ttlUnlimitedPropMd},
218 tagContent{"4", ttlNoPropMd}),
219 mods: []Mutator{
220 Update(k5, "5"),
221 Update(k4, "4", WithTTL(TTLUnlimitedPropagation)),
222 },
223 want: makeTestTagMapWithMetadata(
224 tagContent{"5", ttlUnlimitedPropMd},
225 tagContent{"4", ttlUnlimitedPropMd}),
226 },
227 {
228 name: "from existing; upsert existing",
229 initial: makeTestTagMapWithMetadata(
230 tagContent{"5", ttlNoPropMd},
231 tagContent{"4", ttlNoPropMd}),
232 mods: []Mutator{
233 Upsert(k4, "4", WithTTL(TTLUnlimitedPropagation)),
234 },
235 want: makeTestTagMapWithMetadata(
236 tagContent{"5", ttlNoPropMd},
237 tagContent{"4", ttlUnlimitedPropMd}),
238 },
239 {
240 name: "from existing; upsert non-existing",
241 initial: makeTestTagMapWithMetadata(
242 tagContent{"5", ttlNoPropMd}),
243 mods: []Mutator{
244 Upsert(k4, "4", WithTTL(TTLUnlimitedPropagation)),
245 Upsert(k3, "3"),
246 },
247 want: makeTestTagMapWithMetadata(
248 tagContent{"5", ttlNoPropMd},
249 tagContent{"4", ttlUnlimitedPropMd},
250 tagContent{"3", ttlUnlimitedPropMd}),
251 },
252 {
253 name: "from existing; delete",
254 initial: makeTestTagMapWithMetadata(
255 tagContent{"5", ttlNoPropMd},
256 tagContent{"4", ttlNoPropMd}),
257 mods: []Mutator{
258 Delete(k5),
259 },
260 want: makeTestTagMapWithMetadata(
261 tagContent{"4", ttlNoPropMd}),
262 },
263 {
264 name: "from non-existing; upsert with multiple-metadata",
265 initial: nil,
266 mods: []Mutator{
267 Upsert(k4, "4", WithTTL(TTLUnlimitedPropagation), WithTTL(TTLNoPropagation)),
268 Upsert(k5, "5", WithTTL(TTLNoPropagation), WithTTL(TTLUnlimitedPropagation)),
269 },
270 want: makeTestTagMapWithMetadata(
271 tagContent{"4", ttlNoPropMd},
272 tagContent{"5", ttlUnlimitedPropMd}),
273 },
274 {
275 name: "from non-existing; insert with multiple-metadata",
276 initial: nil,
277 mods: []Mutator{
278 Insert(k5, "5", WithTTL(TTLNoPropagation), WithTTL(TTLUnlimitedPropagation)),
279 },
280 want: makeTestTagMapWithMetadata(
281 tagContent{"5", ttlUnlimitedPropMd}),
282 },
283 {
284 name: "from existing; update with multiple-metadata",
285 initial: makeTestTagMapWithMetadata(
286 tagContent{"5", ttlNoPropMd}),
287 mods: []Mutator{
288 Update(k5, "5", WithTTL(TTLNoPropagation), WithTTL(TTLUnlimitedPropagation)),
289 },
290 want: makeTestTagMapWithMetadata(
291 tagContent{"5", ttlUnlimitedPropMd}),
292 },
293 {
294 name: "from empty; update invalid",
295 initial: nil,
296 mods: []Mutator{
297 Insert(k4, "4\x19", WithTTL(TTLUnlimitedPropagation)),
298 Upsert(k4, "4\x19", WithTTL(TTLUnlimitedPropagation)),
299 Update(k4, "4\x19", WithTTL(TTLUnlimitedPropagation)),
300 },
301 want: nil,
302 },
303 {
304 name: "from empty; insert partial",
305 initial: nil,
306 mods: []Mutator{
307 Upsert(k3, "3", WithTTL(TTLUnlimitedPropagation)),
308 Upsert(k4, "4\x19", WithTTL(TTLUnlimitedPropagation)),
309 },
310 want: nil,
311 },
312 }
313
314
315 for _, tt := range tests {
316 ctx := NewContext(context.Background(), tt.initial)
317 ctx, err := New(ctx, tt.mods...)
318 if tt.want != nil && err != nil {
319 t.Errorf("%v: New = %v", tt.name, err)
320 }
321
322 if got, want := FromContext(ctx), tt.want; !reflect.DeepEqual(got, want) {
323 t.Errorf("%v: got %v; want %v", tt.name, got, want)
324 }
325 }
326 }
327
328 func TestNewValidation(t *testing.T) {
329 tests := []struct {
330 err string
331 seed *Map
332 }{
333
334 {err: "invalid key", seed: &Map{m: map[Key]tagContent{{name: ""}: {"foo", ttlNoPropMd}}}},
335 {err: "", seed: &Map{m: map[Key]tagContent{{name: "key"}: {"foo", ttlNoPropMd}}}},
336 {err: "", seed: &Map{m: map[Key]tagContent{{name: strings.Repeat("a", 255)}: {"census", ttlNoPropMd}}}},
337 {err: "invalid key", seed: &Map{m: map[Key]tagContent{{name: strings.Repeat("a", 256)}: {"census", ttlNoPropMd}}}},
338 {err: "invalid key", seed: &Map{m: map[Key]tagContent{{name: "Приве́т"}: {"census", ttlNoPropMd}}}},
339
340
341 {err: "", seed: &Map{m: map[Key]tagContent{{name: "key"}: {"", ttlNoPropMd}}}},
342 {err: "", seed: &Map{m: map[Key]tagContent{{name: "key"}: {strings.Repeat("a", 255), ttlNoPropMd}}}},
343 {err: "invalid value", seed: &Map{m: map[Key]tagContent{{name: "key"}: {"Приве́т", ttlNoPropMd}}}},
344 {err: "invalid value", seed: &Map{m: map[Key]tagContent{{name: "key"}: {strings.Repeat("a", 256), ttlNoPropMd}}}},
345 }
346
347 for i, tt := range tests {
348 ctx := NewContext(context.Background(), tt.seed)
349 ctx, err := New(ctx)
350
351 if tt.err != "" {
352 if err == nil {
353 t.Errorf("#%d: got nil error; want %q", i, tt.err)
354 continue
355 } else if s, substr := err.Error(), tt.err; !strings.Contains(s, substr) {
356 t.Errorf("#%d:\ngot %q\nwant %q", i, s, substr)
357 }
358 continue
359 }
360 if err != nil {
361 t.Errorf("#%d: got %q want nil", i, err)
362 continue
363 }
364 m := FromContext(ctx)
365 if m == nil {
366 t.Errorf("#%d: got nil map", i)
367 continue
368 }
369 }
370 }
371
372 func makeTestTagMap(ids ...int) *Map {
373 m := newMap()
374 for _, v := range ids {
375 k, _ := NewKey(fmt.Sprintf("k%d", v))
376 m.m[k] = tagContent{fmt.Sprintf("v%d", v), ttlUnlimitedPropMd}
377 }
378 return m
379 }
380
381 func makeTestTagMapWithMetadata(tcs ...tagContent) *Map {
382 m := newMap()
383 for _, tc := range tcs {
384 k, _ := NewKey(fmt.Sprintf("k%s", tc.value))
385 m.m[k] = tc
386 }
387 return m
388 }
389
View as plain text