]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/lib/test/test_json.py
7b3c8593ccb9a9177f0e80178b6dc84f6616f699
[mirror_frr.git] / tests / topotests / lib / test / test_json.py
1 #!/usr/bin/env python
2
3 #
4 # test_json.py
5 # Tests for library function: json_cmp().
6 #
7 # Copyright (c) 2017 by
8 # Network Device Education Foundation, Inc. ("NetDEF")
9 #
10 # Permission to use, copy, modify, and/or distribute this software
11 # for any purpose with or without fee is hereby granted, provided
12 # that the above copyright notice and this permission notice appear
13 # in all copies.
14 #
15 # THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
16 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
17 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
18 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
19 # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
21 # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
22 # OF THIS SOFTWARE.
23 #
24
25 """
26 Tests for the json_cmp() function.
27 """
28
29 import os
30 import sys
31 import pytest
32
33 # Save the Current Working Directory to find lib files.
34 CWD = os.path.dirname(os.path.realpath(__file__))
35 sys.path.append(os.path.join(CWD, "../../"))
36
37 # pylint: disable=C0413
38 from lib.topotest import json_cmp
39
40
41 def test_json_intersect_true():
42 "Test simple correct JSON intersections"
43
44 dcomplete = {
45 "i1": "item1",
46 "i2": "item2",
47 "i3": "item3",
48 "i100": "item4",
49 }
50
51 dsub1 = {
52 "i1": "item1",
53 "i3": "item3",
54 }
55 dsub2 = {
56 "i1": "item1",
57 "i2": "item2",
58 }
59 dsub3 = {
60 "i100": "item4",
61 "i2": "item2",
62 }
63 dsub4 = {
64 "i50": None,
65 "i100": "item4",
66 }
67
68 assert json_cmp(dcomplete, dsub1) is None
69 assert json_cmp(dcomplete, dsub2) is None
70 assert json_cmp(dcomplete, dsub3) is None
71 assert json_cmp(dcomplete, dsub4) is None
72
73
74 def test_json_intersect_false():
75 "Test simple incorrect JSON intersections"
76
77 dcomplete = {
78 "i1": "item1",
79 "i2": "item2",
80 "i3": "item3",
81 "i100": "item4",
82 }
83
84 # Incorrect value for 'i1'
85 dsub1 = {
86 "i1": "item3",
87 "i3": "item3",
88 }
89 # Non-existing key 'i5'
90 dsub2 = {
91 "i1": "item1",
92 "i5": "item2",
93 }
94 # Key should not exist
95 dsub3 = {
96 "i100": None,
97 }
98
99 assert json_cmp(dcomplete, dsub1) is not None
100 assert json_cmp(dcomplete, dsub2) is not None
101 assert json_cmp(dcomplete, dsub3) is not None
102
103
104 def test_json_intersect_multilevel_true():
105 "Test multi level correct JSON intersections"
106
107 dcomplete = {
108 "i1": "item1",
109 "i2": "item2",
110 "i3": {
111 "i100": "item100",
112 },
113 "i4": {
114 "i41": {
115 "i411": "item411",
116 },
117 "i42": {
118 "i421": "item421",
119 "i422": "item422",
120 },
121 },
122 }
123
124 dsub1 = {
125 "i1": "item1",
126 "i3": {
127 "i100": "item100",
128 },
129 "i10": None,
130 }
131 dsub2 = {
132 "i1": "item1",
133 "i2": "item2",
134 "i3": {},
135 }
136 dsub3 = {
137 "i2": "item2",
138 "i4": {
139 "i41": {
140 "i411": "item411",
141 },
142 "i42": {
143 "i422": "item422",
144 "i450": None,
145 },
146 },
147 }
148 dsub4 = {
149 "i2": "item2",
150 "i4": {
151 "i41": {},
152 "i42": {
153 "i450": None,
154 },
155 },
156 }
157 dsub5 = {
158 "i2": "item2",
159 "i3": {
160 "i100": "item100",
161 },
162 "i4": {
163 "i42": {
164 "i450": None,
165 }
166 },
167 }
168
169 assert json_cmp(dcomplete, dsub1) is None
170 assert json_cmp(dcomplete, dsub2) is None
171 assert json_cmp(dcomplete, dsub3) is None
172 assert json_cmp(dcomplete, dsub4) is None
173 assert json_cmp(dcomplete, dsub5) is None
174
175
176 def test_json_intersect_multilevel_false():
177 "Test multi level incorrect JSON intersections"
178
179 dcomplete = {
180 "i1": "item1",
181 "i2": "item2",
182 "i3": {
183 "i100": "item100",
184 },
185 "i4": {
186 "i41": {
187 "i411": "item411",
188 },
189 "i42": {
190 "i421": "item421",
191 "i422": "item422",
192 },
193 },
194 }
195
196 # Incorrect sub-level value
197 dsub1 = {
198 "i1": "item1",
199 "i3": {
200 "i100": "item00",
201 },
202 "i10": None,
203 }
204 # Inexistent sub-level
205 dsub2 = {
206 "i1": "item1",
207 "i2": "item2",
208 "i3": None,
209 }
210 # Inexistent sub-level value
211 dsub3 = {
212 "i1": "item1",
213 "i3": {
214 "i100": None,
215 },
216 }
217 # Inexistent sub-sub-level value
218 dsub4 = {
219 "i4": {
220 "i41": {
221 "i412": "item412",
222 },
223 "i42": {
224 "i421": "item421",
225 },
226 }
227 }
228 # Invalid sub-sub-level value
229 dsub5 = {
230 "i4": {
231 "i41": {
232 "i411": "item411",
233 },
234 "i42": {
235 "i421": "item420000",
236 },
237 }
238 }
239 # sub-sub-level should be value
240 dsub6 = {
241 "i4": {
242 "i41": {
243 "i411": "item411",
244 },
245 "i42": "foobar",
246 }
247 }
248
249 assert json_cmp(dcomplete, dsub1) is not None
250 assert json_cmp(dcomplete, dsub2) is not None
251 assert json_cmp(dcomplete, dsub3) is not None
252 assert json_cmp(dcomplete, dsub4) is not None
253 assert json_cmp(dcomplete, dsub5) is not None
254 assert json_cmp(dcomplete, dsub6) is not None
255
256
257 def test_json_with_list_sucess():
258 "Test successful json comparisons that have lists."
259
260 dcomplete = {
261 "list": [
262 {
263 "i1": "item 1",
264 "i2": "item 2",
265 },
266 {
267 "i10": "item 10",
268 },
269 ],
270 "i100": "item 100",
271 }
272
273 # Test list type
274 dsub1 = {
275 "list": [],
276 }
277 # Test list correct list items
278 dsub2 = {
279 "list": [
280 {
281 "i1": "item 1",
282 },
283 ],
284 "i100": "item 100",
285 }
286 # Test list correct list size
287 dsub3 = {
288 "list": [
289 {},
290 {},
291 ],
292 }
293
294 assert json_cmp(dcomplete, dsub1) is None
295 assert json_cmp(dcomplete, dsub2) is None
296 assert json_cmp(dcomplete, dsub3) is None
297
298
299 def test_json_with_list_failure():
300 "Test failed json comparisons that have lists."
301
302 dcomplete = {
303 "list": [
304 {
305 "i1": "item 1",
306 "i2": "item 2",
307 },
308 {
309 "i10": "item 10",
310 },
311 ],
312 "i100": "item 100",
313 }
314
315 # Test list type
316 dsub1 = {
317 "list": {},
318 }
319 # Test list incorrect list items
320 dsub2 = {
321 "list": [
322 {
323 "i1": "item 2",
324 },
325 ],
326 "i100": "item 100",
327 }
328 # Test list correct list size
329 dsub3 = {
330 "list": [
331 {},
332 {},
333 {},
334 ],
335 }
336
337 assert json_cmp(dcomplete, dsub1) is not None
338 assert json_cmp(dcomplete, dsub2) is not None
339 assert json_cmp(dcomplete, dsub3) is not None
340
341
342 def test_json_list_start_success():
343 "Test JSON encoded data that starts with a list that should succeed."
344
345 dcomplete = [
346 {
347 "id": 100,
348 "value": "abc",
349 },
350 {
351 "id": 200,
352 "value": "abcd",
353 },
354 {
355 "id": 300,
356 "value": "abcde",
357 },
358 ]
359
360 dsub1 = [
361 {
362 "id": 100,
363 "value": "abc",
364 }
365 ]
366
367 dsub2 = [
368 {
369 "id": 100,
370 "value": "abc",
371 },
372 {
373 "id": 200,
374 "value": "abcd",
375 },
376 ]
377
378 dsub3 = [
379 {
380 "id": 300,
381 "value": "abcde",
382 }
383 ]
384
385 dsub4 = []
386
387 dsub5 = [
388 {
389 "id": 100,
390 }
391 ]
392
393 assert json_cmp(dcomplete, dsub1) is None
394 assert json_cmp(dcomplete, dsub2) is None
395 assert json_cmp(dcomplete, dsub3) is None
396 assert json_cmp(dcomplete, dsub4) is None
397 assert json_cmp(dcomplete, dsub5) is None
398
399
400 def test_json_list_start_failure():
401 "Test JSON encoded data that starts with a list that should fail."
402
403 dcomplete = [
404 {"id": 100, "value": "abc"},
405 {"id": 200, "value": "abcd"},
406 {"id": 300, "value": "abcde"},
407 ]
408
409 dsub1 = [
410 {
411 "id": 100,
412 "value": "abcd",
413 }
414 ]
415
416 dsub2 = [
417 {
418 "id": 100,
419 "value": "abc",
420 },
421 {
422 "id": 200,
423 "value": "abc",
424 },
425 ]
426
427 dsub3 = [
428 {
429 "id": 100,
430 "value": "abc",
431 },
432 {
433 "id": 350,
434 "value": "abcde",
435 },
436 ]
437
438 dsub4 = [
439 {
440 "value": "abcx",
441 },
442 {
443 "id": 300,
444 "value": "abcde",
445 },
446 ]
447
448 assert json_cmp(dcomplete, dsub1) is not None
449 assert json_cmp(dcomplete, dsub2) is not None
450 assert json_cmp(dcomplete, dsub3) is not None
451 assert json_cmp(dcomplete, dsub4) is not None
452
453
454 def test_json_list_ordered():
455 "Test JSON encoded data that should be ordered using the '__ordered__' tag."
456
457 dcomplete = [
458 {"id": 1, "value": "abc"},
459 "some string",
460 123,
461 ]
462
463 dsub1 = [
464 "__ordered__",
465 "some string",
466 {"id": 1, "value": "abc"},
467 123,
468 ]
469
470 assert json_cmp(dcomplete, dsub1) is not None
471
472
473 def test_json_list_exact_matching():
474 "Test JSON array on exact matching using the 'exact' parameter."
475
476 dcomplete = [
477 {"id": 1, "value": "abc"},
478 "some string",
479 123,
480 [1, 2, 3],
481 ]
482
483 dsub1 = [
484 "some string",
485 {"id": 1, "value": "abc"},
486 123,
487 [1, 2, 3],
488 ]
489
490 dsub2 = [
491 {"id": 1},
492 "some string",
493 123,
494 [1, 2, 3],
495 ]
496
497 dsub3 = [
498 {"id": 1, "value": "abc"},
499 "some string",
500 123,
501 [1, 3, 2],
502 ]
503
504 assert json_cmp(dcomplete, dsub1, exact=True) is not None
505 assert json_cmp(dcomplete, dsub2, exact=True) is not None
506
507
508 def test_json_object_exact_matching():
509 "Test JSON object on exact matching using the 'exact' parameter."
510
511 dcomplete = {
512 "a": {"id": 1, "value": "abc"},
513 "b": "some string",
514 "c": 123,
515 "d": [1, 2, 3],
516 }
517
518 dsub1 = {
519 "a": {"id": 1, "value": "abc"},
520 "c": 123,
521 "d": [1, 2, 3],
522 }
523
524 dsub2 = {
525 "a": {"id": 1},
526 "b": "some string",
527 "c": 123,
528 "d": [1, 2, 3],
529 }
530
531 dsub3 = {
532 "a": {"id": 1, "value": "abc"},
533 "b": "some string",
534 "c": 123,
535 "d": [1, 3],
536 }
537
538 assert json_cmp(dcomplete, dsub1, exact=True) is not None
539 assert json_cmp(dcomplete, dsub2, exact=True) is not None
540 assert json_cmp(dcomplete, dsub3, exact=True) is not None
541
542
543 def test_json_list_asterisk_matching():
544 "Test JSON array elements on matching '*' as a placeholder for arbitrary data."
545
546 dcomplete = [
547 {"id": 1, "value": "abc"},
548 "some string",
549 123,
550 [1, 2, 3],
551 ]
552
553 dsub1 = [
554 "*",
555 "some string",
556 123,
557 [1, 2, 3],
558 ]
559
560 dsub2 = [
561 {"id": "*", "value": "abc"},
562 "some string",
563 123,
564 [1, 2, 3],
565 ]
566
567 dsub3 = [
568 {"id": 1, "value": "abc"},
569 "some string",
570 123,
571 [1, "*", 3],
572 ]
573
574 dsub4 = [
575 "*",
576 "some string",
577 "*",
578 [1, 2, 3],
579 ]
580
581 assert json_cmp(dcomplete, dsub1) is None
582 assert json_cmp(dcomplete, dsub2) is None
583 assert json_cmp(dcomplete, dsub3) is None
584 assert json_cmp(dcomplete, dsub4) is None
585
586
587 def test_json_object_asterisk_matching():
588 "Test JSON object value elements on matching '*' as a placeholder for arbitrary data."
589
590 dcomplete = {
591 "a": {"id": 1, "value": "abc"},
592 "b": "some string",
593 "c": 123,
594 "d": [1, 2, 3],
595 }
596
597 dsub1 = {
598 "a": "*",
599 "b": "some string",
600 "c": 123,
601 "d": [1, 2, 3],
602 }
603
604 dsub2 = {
605 "a": {"id": 1, "value": "abc"},
606 "b": "some string",
607 "c": 123,
608 "d": [1, "*", 3],
609 }
610
611 dsub3 = {
612 "a": {"id": "*", "value": "abc"},
613 "b": "some string",
614 "c": 123,
615 "d": [1, 2, 3],
616 }
617
618 dsub4 = {
619 "a": "*",
620 "b": "some string",
621 "c": "*",
622 "d": [1, 2, 3],
623 }
624
625 assert json_cmp(dcomplete, dsub1) is None
626 assert json_cmp(dcomplete, dsub2) is None
627 assert json_cmp(dcomplete, dsub3) is None
628 assert json_cmp(dcomplete, dsub4) is None
629
630
631 def test_json_list_nested_with_objects():
632
633 dcomplete = [{"key": 1, "list": [123]}, {"key": 2, "list": [123]}]
634
635 dsub1 = [{"key": 2, "list": [123]}, {"key": 1, "list": [123]}]
636
637 assert json_cmp(dcomplete, dsub1) is None
638
639
640 if __name__ == "__main__":
641 sys.exit(pytest.main())