]> git.puffer.fish Git - matthieu/frr.git/commitdiff
topotests: use json exact test for bgp_srv6l3vpn_to_bgp_vrf3
authorPhilippe Guibert <philippe.guibert@6wind.com>
Mon, 24 Mar 2025 16:35:22 +0000 (17:35 +0100)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Mon, 24 Mar 2025 16:39:20 +0000 (17:39 +0100)
Add more control on the expected outputs, by using an exact json
comparison.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv4_rib_locator_deleted.json
tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv4_rib_sid_vpn_export_disabled.json
tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv6_rib_locator_deleted.json
tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv6_rib_sid_vpn_export_disabled.json
tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r2/vpnv4_rib_locator_deleted.json
tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r2/vpnv6_rib_locator_deleted.json
tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py
tests/topotests/lib/bgp.py

index f1ec26c96728a3b7b29d57cb62f1041177d5603c..4e803a05141cf1449614e272b4928963431f1d20 100644 (file)
@@ -9,7 +9,7 @@
       "1:10": {
         "192.168.1.0/24": [
           {
-            "selectionReason": "First path received",
+            "multipath": true,
             "pathFrom": "external",
             "prefix": "192.168.1.0",
             "prefixLen": 24,
@@ -32,7 +32,7 @@
         ],
         "192.168.3.0/24": [
           {
-            "selectionReason": "First path received",
+            "multipath": true,
             "pathFrom": "external",
             "prefix": "192.168.3.0",
             "prefixLen": 24,
@@ -57,7 +57,7 @@
       "1:20": {
         "192.168.5.0/24": [
           {
-            "selectionReason": "First path received",
+            "multipath": true,
             "pathFrom": "external",
             "prefix": "192.168.5.0",
             "prefixLen": 24,
             ]
           }
         ]
+      },
+      "2:10": {
+        "192.168.2.0/24": [
+          {
+            "valid": true,
+            "bestpath": true,
+            "selectionReason": "First path received",
+            "pathFrom": "external",
+            "prefix": "192.168.2.0",
+            "prefixLen": 24,
+            "network": "192.168.2.0/24",
+            "metric": 0,
+            "weight": 0,
+            "peerId": "2001::2",
+            "path": "2",
+            "origin": "incomplete",
+            "nexthops": [
+              {
+                "ip": "2001::2",
+                "hostname": "r2",
+                "afi": "ipv6",
+                "used": true
+              }
+            ]
+          }
+        ]
+      },
+      "2:20": {
+        "192.168.4.0/24": [
+          {
+            "valid": true,
+            "bestpath": true,
+            "selectionReason": "First path received",
+            "pathFrom": "external",
+            "prefix": "192.168.4.0",
+            "prefixLen": 24,
+            "network": "192.168.4.0/24",
+            "metric": 0,
+            "weight": 0,
+            "peerId": "2001::2",
+            "path": "2",
+            "origin": "incomplete",
+            "nexthops": [
+              {
+                "ip": "2001::2",
+                "hostname": "r2",
+                "afi": "ipv6",
+                "used": true
+              }
+            ]
+          }
+        ],
+        "192.168.6.0/24": [
+             {
+            "valid": true,
+            "bestpath": true,
+            "selectionReason": "First path received",
+            "pathFrom": "external",
+            "prefix": "192.168.6.0",
+            "prefixLen": 24,
+            "network": "192.168.6.0/24",
+            "metric": 0,
+            "weight": 0,
+            "peerId": "2001::2",
+            "path": "2",
+            "origin": "incomplete",
+            "nexthops": [
+              {
+                "ip": "2001::2",
+                "hostname": "r2",
+                "afi": "ipv6",
+                "used": true
+              }
+            ]
+          }
+        ]
       }
     }
   }
index 205079574c082dcd78eb8ec6335939536e075715..d49c357432095d59753f02795c0be8b1af565dbc 100644 (file)
@@ -6,6 +6,54 @@
   "localAS": 1,
   "routes": {
     "routeDistinguishers": {
+      "1:10": {
+        "192.168.1.0/24": [
+          {
+            "multipath": true,
+            "pathFrom": "external",
+            "prefix": "192.168.1.0",
+            "prefixLen": 24,
+            "network": "192.168.1.0/24",
+            "metric": 0,
+            "weight": 32768,
+            "peerId": "(unspec)",
+            "path": "",
+            "origin": "incomplete",
+            "nhVrfName": "vrf10",
+            "nexthops": [
+              {
+                "ip": "2001::1",
+                "hostname": "r1",
+                "afi": "ipv6",
+                "used": true
+              }
+            ]
+          }
+        ],
+        "192.168.3.0/24": [
+          {
+            "multipath": true,
+            "pathFrom": "external",
+            "prefix": "192.168.3.0",
+            "prefixLen": 24,
+            "network": "192.168.3.0/24",
+            "metric": 0,
+            "weight": 32768,
+            "peerId": "(unspec)",
+            "path": "",
+            "origin": "incomplete",
+            "nhVrfName": "vrf10",
+            "nexthops": [
+              {
+                "ip": "2001::1",
+                "hostname": "r1",
+                "afi": "ipv6",
+                "used": true
+              }
+            ]
+          }
+        ]
+      },
       "1:20": {
         "192.168.5.0/24": [
           {
index f2df9be49d9f35c053fed99303109594f37c2101..547b262d4b348e6ba1e358c9c36efaa0783fec7d 100644 (file)
@@ -9,6 +9,7 @@
       "1:10": {
         "2001:1::/64": [
           {
+            "multipath": true,
             "pathFrom": "external",
             "prefix": "2001:1::",
             "prefixLen": 64,
@@ -32,6 +33,7 @@
         ],
         "2001:3::/64": [
           {
+            "multipath": true,
             "pathFrom": "external",
             "prefix": "2001:3::",
             "prefixLen": 64,
@@ -57,6 +59,7 @@
       "1:20": {
         "2001:5::/64": [
           {
+            "multipath": true,
             "pathFrom": "external",
             "prefix": "2001:5::",
             "prefixLen": 64,
           }
         ],
         "2001:6::/64": [
-          {
+             {
             "valid": true,
             "bestpath": true,
             "selectionReason": "First path received",
index e289df1d44dabedbf0da45d3e3bdc19fd78de126..8cfe2231017283c589fc999b9a24dd45c09dff0b 100644 (file)
@@ -6,6 +6,56 @@
   "localAS": 1,
   "routes": {
     "routeDistinguishers": {
+      "1:10": {
+        "2001:1::/64": [
+          {
+            "multipath": true,
+            "pathFrom": "external",
+            "prefix": "2001:1::",
+            "prefixLen": 64,
+            "network": "2001:1::/64",
+            "metric": 0,
+            "weight": 32768,
+            "peerId": "(unspec)",
+            "path": "",
+            "origin": "incomplete",
+            "announceNexthopSelf": true,
+            "nhVrfName": "vrf10",
+            "nexthops": [
+              {
+                "ip": "::",
+                "hostname": "r1",
+                "afi": "ipv6",
+                "used": true
+              }
+            ]
+          }
+        ],
+        "2001:3::/64": [
+          {
+            "multipath": true,
+            "pathFrom": "external",
+            "prefix": "2001:3::",
+            "prefixLen": 64,
+            "network": "2001:3::/64",
+            "metric": 0,
+            "weight": 32768,
+            "peerId": "(unspec)",
+            "path": "",
+            "origin": "incomplete",
+            "announceNexthopSelf": true,
+            "nhVrfName": "vrf10",
+            "nexthops": [
+              {
+                "ip": "::",
+                "hostname": "r1",
+                "afi": "ipv6",
+                "used": true
+              }
+            ]
+          }
+        ]
+      },
       "1:20": {
         "2001:5::/64": [
           {
index e2b717085321e093aebe9997cae6ff05c5dd6771..e3edee172b036fc486230370fb3ed2dd501dd9dd 100644 (file)
@@ -86,7 +86,5 @@
         ]
       }
     }
-  },
-    "totalRoutes": 3,
-    "totalPaths": 3
+  }
 }
index 41e8a82e400ac3eba71ebe94732386a98ede1cff..25cdf031c3de50a5e6f537732f3c80b852292b19 100644 (file)
@@ -89,7 +89,5 @@
         ]
       }
     }
-  },
-    "totalRoutes": 3,
-    "totalPaths": 3
+  }
 }
index 530537646bb45279aaaad3b98089d2aa75000c24..9e588d1d71101129a6e771719739d035ffbd5a63 100644 (file)
@@ -18,6 +18,7 @@ sys.path.append(os.path.join(CWD, "../"))
 # pylint: disable=C0413
 # Import topogen and topotest helpers
 from lib import topotest
+from lib.bgp import bgp_vpn_router_json_cmp_exact_filter
 from lib.topogen import Topogen, TopoRouter, get_topogen
 from lib.topolog import logger
 from lib.common_config import required_linux_kernel_version
@@ -95,24 +96,29 @@ def open_json_file(filename):
         assert False, "Could not read file {}".format(filename)
 
 
-def check_rib(name, cmd, expected_file, count=30, wait=0.5):
-    def _check(name, dest_addr, match):
+def check_rib(name, cmd, expected_file, count=10, wait=0.5):
+    def _check(router, cmd, expected):
         logger.info("polling")
         tgen = get_topogen()
-        router = tgen.gears[name]
         output = json.loads(router.vtysh_cmd(cmd))
-        expected = open_json_file("{}/{}".format(CWD, expected_file))
         return topotest.json_cmp(output, expected)
 
     logger.info('[+] check {} "{}" {}'.format(name, cmd, expected_file))
     tgen = get_topogen()
-    func = functools.partial(_check, name, cmd, expected_file)
+    router = tgen.gears[name]
+    expected = open_json_file("{}/{}".format(CWD, expected_file))
+    if "show bgp" in cmd and "vpn" in cmd:
+        func = functools.partial(
+            bgp_vpn_router_json_cmp_exact_filter, tgen.gears[name], cmd, expected
+        )
+    else:
+        func = functools.partial(_check, router, cmd, expected)
     _, result = topotest.run_and_expect(func, None, count, wait)
     assert result is None, "Failed"
 
 
 def test_rib():
-    check_rib("r1", "show bgp ipv4 vpn json", "r1/vpnv4_rib.json", 120, 1)
+    check_rib("r1", "show bgp ipv4 vpn json", "r1/vpnv4_rib.json", 10, 1)
     check_rib("r2", "show bgp ipv4 vpn json", "r2/vpnv4_rib.json")
     check_rib("r1", "show ip route vrf vrf10 json", "r1/vrf10v4_rib.json")
     check_rib("r1", "show ip route vrf vrf20 json", "r1/vrf20v4_rib.json")
index 632aa4a10b7b94bb3e119987937d0017e036ce1b..01fe2b3714ab542861f194607a19fa5cea13ff5c 100644 (file)
@@ -5,6 +5,7 @@
 # ("NetDEF") in this file.
 #
 
+import json
 import ipaddress
 import sys
 import traceback
@@ -5658,3 +5659,34 @@ def bgp_configure_prefixes(router, asn, safi, prefixes, vrf=None, update=True):
         ]
         logger.debug(f"setting prefix: ipv{ip.version} {safi} {ip}")
         router.vtysh_cmd("".join(cmd))
+
+
+# compare exact fields of 'show bgp ipv4 vpn' and related commands
+# after having removed some attributes that are not relevant.
+def bgp_vpn_router_json_cmp_exact_filter(router, cmd, expected):
+    output = router.vtysh_cmd(cmd)
+    logger.info("{}: {}\n{}".format(router.name, cmd, output))
+
+    json_output = json.loads(output)
+
+    # filter out tableVersion, version and nhVrfID
+    json_output.pop("tableVersion")
+    if "totalRoutes" in json_output:
+        json_output.pop("totalRoutes")
+    if "totalPaths" in json_output:
+        json_output.pop("totalPaths")
+    for rd, data in json_output["routes"]["routeDistinguishers"].items():
+        for _, attrs in data.items():
+            for attr in attrs:
+                if "nhVrfId" in attr:
+                    attr.pop("nhVrfId")
+                if "version" in attr:
+                    attr.pop("version")
+
+    # filter out RD with no data (e.g. "444:3": {})
+    json_tmp = deepcopy(json_output)
+    for rd, data in json_tmp["routes"]["routeDistinguishers"].items():
+        if len(data.keys()) == 0:
+            json_output["routes"]["routeDistinguishers"].pop(rd)
+
+    return topotest.json_cmp(json_output, expected, exact=True)