]> git.puffer.fish Git - matthieu/frr.git/commitdiff
topotest: add JSON list comparation support
authorRafael Zalamena <rzalamena@gmail.com>
Wed, 5 Jul 2017 16:46:28 +0000 (13:46 -0300)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 28 Nov 2018 01:22:11 +0000 (20:22 -0500)
Add missing list support for json_cmp(). The missing support was
noticed while writing the BGP ECMP topology test.

tests/topotests/lib/test/test_json.py
tests/topotests/lib/topotest.py

index 87bf48dda24256009ff252b0023c6075651b8f09..e39719450300c5b681e47c03ccefdf6021ff2f84 100755 (executable)
@@ -249,5 +249,85 @@ def test_json_intersect_multilevel_false():
     assert json_cmp(dcomplete, dsub5) is not None
     assert json_cmp(dcomplete, dsub6) is not None
 
+def test_json_with_list_sucess():
+    "Test successful json comparisons that have lists."
+
+    dcomplete = {
+        'list': [
+            {
+                'i1': 'item 1',
+                'i2': 'item 2',
+            },
+            {
+                'i10': 'item 10',
+            },
+        ],
+        'i100': 'item 100',
+    }
+
+    # Test list type
+    dsub1 = {
+        'list': [],
+    }
+    # Test list correct list items
+    dsub2 = {
+        'list': [
+            {
+                'i1': 'item 1',
+            },
+        ],
+        'i100': 'item 100',
+    }
+    # Test list correct list size
+    dsub3 = {
+        'list': [
+            {}, {},
+        ],
+    }
+
+    assert json_cmp(dcomplete, dsub1) is None
+    assert json_cmp(dcomplete, dsub2) is None
+    assert json_cmp(dcomplete, dsub3) is None
+
+def test_json_with_list_failure():
+    "Test failed json comparisons that have lists."
+
+    dcomplete = {
+        'list': [
+            {
+                'i1': 'item 1',
+                'i2': 'item 2',
+            },
+            {
+                'i10': 'item 10',
+            },
+        ],
+        'i100': 'item 100',
+    }
+
+    # Test list type
+    dsub1 = {
+        'list': {},
+    }
+    # Test list incorrect list items
+    dsub2 = {
+        'list': [
+            {
+                'i1': 'item 2',
+            },
+        ],
+        'i100': 'item 100',
+    }
+    # Test list correct list size
+    dsub3 = {
+        'list': [
+            {}, {}, {},
+        ],
+    }
+
+    assert json_cmp(dcomplete, dsub1) is not None
+    assert json_cmp(dcomplete, dsub2) is not None
+    assert json_cmp(dcomplete, dsub3) is not None
+
 if __name__ == '__main__':
     sys.exit(pytest.main())
index 9ed7c198d16b736b31e98b580cb6e32aef6c777b..fa065ad1787f15668a9eef7fe856261dcd9d6aa8 100644 (file)
@@ -91,9 +91,50 @@ def json_cmp(d1, d2, reason=False):
                 continue
             # If nd1 key is a dict, we have to recurse in it later.
             if isinstance(nd2[key], type({})):
+                if not isinstance(nd1[key], type({})):
+                    result.add_error(
+                        '{}["{}"] has different type than expected '.format(parent, key) +
+                        '(have {}, expected {})'.format(type(nd1[key]), type(nd2[key])))
+                    continue
                 nparent = '{}["{}"]'.format(parent, key)
                 squeue.append((nd1[key], nd2[key], nparent))
                 continue
+            # Check list items
+            if isinstance(nd2[key], type([])):
+                if not isinstance(nd1[key], type([])):
+                    result.add_error(
+                        '{}["{}"] has different type than expected '.format(parent, key) +
+                        '(have {}, expected {})'.format(type(nd1[key]), type(nd2[key])))
+                    continue
+                # Check list size
+                if len(nd2[key]) > len(nd1[key]):
+                    result.add_error(
+                        '{}["{}"] too few items '.format(parent, key) +
+                        '(have ({}) "{}", expected ({}) "{}")'.format(
+                            len(nd1[key]), str(nd1[key]), len(nd2[key]), str(nd2[key])))
+                    continue
+
+                # List all unmatched items errors
+                unmatched = []
+                for expected in nd2[key]:
+                    matched = False
+                    for value in nd1[key]:
+                        if json_cmp({'json': value}, {'json': expected}) is None:
+                            matched = True
+                            break
+
+                    if matched:
+                        break
+                    if not matched:
+                        unmatched.append(expected)
+
+                # If there are unmatched items, error out.
+                if unmatched:
+                    result.add_error(
+                        '{}["{}"] value is different (have "{}", expected "{}")'.format(
+                            parent, key, str(nd1[key]), str(nd2[key])))
+                continue
+
             # Compare JSON values
             if nd1[key] != nd2[key]:
                 result.add_error(