Merge pull request #4710 from ashish12pant/ecmp_tests

tests: Add ecmp test cases
This commit is contained in:
Martin Winter 2019-09-03 14:39:14 +02:00 committed by GitHub
commit db42a62a97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 3103 additions and 22 deletions

View File

@ -375,7 +375,7 @@ def test_static_routes(request):
# Verifying RIB routes # Verifying RIB routes
dut = 'r3' dut = 'r3'
protocol = 'bgp' protocol = 'bgp'
next_hop = '10.0.0.2' next_hop = ['10.0.0.2', '10.0.0.5']
result = verify_rib(tgen, 'ipv4', dut, input_dict, next_hop=next_hop, result = verify_rib(tgen, 'ipv4', dut, input_dict, next_hop=next_hop,
protocol=protocol) protocol=protocol)
assert result is True, "Testcase {} :Failed \n Error: {}". \ assert result is True, "Testcase {} :Failed \n Error: {}". \

View File

@ -0,0 +1,664 @@
{
"address_types": [
"ipv4",
"ipv6"
],
"ipv4base": "10.0.0.0",
"ipv4mask": 24,
"ipv6base": "fd00::",
"ipv6mask": 64,
"link_ip_start": {
"ipv4": "10.0.0.0",
"v4mask": 24,
"ipv6": "fd00::",
"v6mask": 64
},
"lo_prefix": {
"ipv4": "1.0.",
"v4mask": 32,
"ipv6": "2001:DB8:F::",
"v6mask": 128
},
"routers": {
"r1": {
"links": {
"lo": {
"ipv4": "auto",
"ipv6": "auto",
"type": "loopback"
},
"r2-link1": {
"ipv4": "auto",
"ipv6": "auto"
}
},
"bgp": {
"local_as": "100",
"address_family": {
"ipv4": {
"unicast": {
"neighbor": {
"r2": {
"dest_link": {
"r1-link1": {}
}
}
}
}
},
"ipv6": {
"unicast": {
"neighbor": {
"r2": {
"dest_link": {
"r1-link1": {}
}
}
}
}
}
}
}
},
"r2": {
"links": {
"lo": {
"ipv4": "auto",
"ipv6": "auto",
"type": "loopback"
},
"r1-link1": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link1": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link2": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link3": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link4": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link5": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link6": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link7": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link8": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link9": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link10": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link11": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link12": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link13": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link14": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link15": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link16": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link17": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link18": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link19": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link20": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link21": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link22": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link23": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link24": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link25": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link26": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link27": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link28": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link29": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link30": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link31": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link32": {
"ipv4": "auto",
"ipv6": "auto"
}
},
"bgp": {
"local_as": "200",
"address_family": {
"ipv4": {
"unicast": {
"neighbor": {
"r1": {
"dest_link": {
"r2-link1": {}
}
},
"r3": {
"dest_link": {
"r2-link1": {
"next_hop_self": true
},
"r2-link2": {
"next_hop_self": true
},
"r2-link3": {
"next_hop_self": true
},
"r2-link4": {
"next_hop_self": true
},
"r2-link5": {
"next_hop_self": true
},
"r2-link6": {
"next_hop_self": true
},
"r2-link7": {
"next_hop_self": true
},
"r2-link8": {
"next_hop_self": true
},
"r2-link9": {
"next_hop_self": true
},
"r2-link10": {
"next_hop_self": true
},
"r2-link11": {
"next_hop_self": true
},
"r2-link12": {
"next_hop_self": true
},
"r2-link13": {
"next_hop_self": true
},
"r2-link14": {
"next_hop_self": true
},
"r2-link15": {
"next_hop_self": true
},
"r2-link16": {
"next_hop_self": true
},
"r2-link17": {
"next_hop_self": true
},
"r2-link18": {
"next_hop_self": true
},
"r2-link19": {
"next_hop_self": true
},
"r2-link20": {
"next_hop_self": true
},
"r2-link21": {
"next_hop_self": true
},
"r2-link22": {
"next_hop_self": true
},
"r2-link23": {
"next_hop_self": true
},
"r2-link24": {
"next_hop_self": true
},
"r2-link25": {
"next_hop_self": true
},
"r2-link26": {
"next_hop_self": true
},
"r2-link27": {
"next_hop_self": true
},
"r2-link28": {
"next_hop_self": true
},
"r2-link29": {
"next_hop_self": true
},
"r2-link30": {
"next_hop_self": true
},
"r2-link31": {
"next_hop_self": true
},
"r2-link32": {
"next_hop_self": true
}
}
}
}
}
},
"ipv6": {
"unicast": {
"neighbor": {
"r1": {
"dest_link": {
"r2-link1": {}
}
},
"r3": {
"dest_link": {
"r2-link1": {
"next_hop_self": true
},
"r2-link2": {
"next_hop_self": true
},
"r2-link3": {
"next_hop_self": true
},
"r2-link4": {
"next_hop_self": true
},
"r2-link5": {
"next_hop_self": true
},
"r2-link6": {
"next_hop_self": true
},
"r2-link7": {
"next_hop_self": true
},
"r2-link8": {
"next_hop_self": true
},
"r2-link9": {
"next_hop_self": true
},
"r2-link10": {
"next_hop_self": true
},
"r2-link11": {
"next_hop_self": true
},
"r2-link12": {
"next_hop_self": true
},
"r2-link13": {
"next_hop_self": true
},
"r2-link14": {
"next_hop_self": true
},
"r2-link15": {
"next_hop_self": true
},
"r2-link16": {
"next_hop_self": true
},
"r2-link17": {
"next_hop_self": true
},
"r2-link18": {
"next_hop_self": true
},
"r2-link19": {
"next_hop_self": true
},
"r2-link20": {
"next_hop_self": true
},
"r2-link21": {
"next_hop_self": true
},
"r2-link22": {
"next_hop_self": true
},
"r2-link23": {
"next_hop_self": true
},
"r2-link24": {
"next_hop_self": true
},
"r2-link25": {
"next_hop_self": true
},
"r2-link26": {
"next_hop_self": true
},
"r2-link27": {
"next_hop_self": true
},
"r2-link28": {
"next_hop_self": true
},
"r2-link29": {
"next_hop_self": true
},
"r2-link30": {
"next_hop_self": true
},
"r2-link31": {
"next_hop_self": true
},
"r2-link32": {
"next_hop_self": true
}
}
}
}
}
}
}
}
},
"r3": {
"links": {
"lo": {
"ipv4": "auto",
"ipv6": "auto",
"type": "loopback"
},
"r2-link1": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link2": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link3": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link4": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link5": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link6": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link7": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link8": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link9": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link10": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link11": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link12": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link13": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link14": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link15": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link16": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link17": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link18": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link19": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link20": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link21": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link22": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link23": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link24": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link25": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link26": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link27": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link28": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link29": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link30": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link31": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link32": {
"ipv4": "auto",
"ipv6": "auto"
}
},
"bgp": {
"local_as": "300",
"address_family": {
"ipv4": {
"unicast": {
"maximum_paths": {
"ebgp": 32
},
"neighbor": {
"r2": {
"dest_link": {
"r3-link1": {},
"r3-link2": {},
"r3-link3": {},
"r3-link4": {},
"r3-link5": {},
"r3-link6": {},
"r3-link7": {},
"r3-link8": {},
"r3-link9": {},
"r3-link10": {},
"r3-link11": {},
"r3-link12": {},
"r3-link13": {},
"r3-link14": {},
"r3-link15": {},
"r3-link16": {},
"r3-link17": {},
"r3-link18": {},
"r3-link19": {},
"r3-link20": {},
"r3-link21": {},
"r3-link22": {},
"r3-link23": {},
"r3-link24": {},
"r3-link25": {},
"r3-link26": {},
"r3-link27": {},
"r3-link28": {},
"r3-link29": {},
"r3-link30": {},
"r3-link31": {},
"r3-link32": {}
}
}
}
}
},
"ipv6": {
"unicast": {
"maximum_paths": {
"ebgp": 32
},
"neighbor": {
"r2": {
"dest_link": {
"r3-link1": {},
"r3-link2": {},
"r3-link3": {},
"r3-link4": {},
"r3-link5": {},
"r3-link6": {},
"r3-link7": {},
"r3-link8": {},
"r3-link9": {},
"r3-link10": {},
"r3-link11": {},
"r3-link12": {},
"r3-link13": {},
"r3-link14": {},
"r3-link15": {},
"r3-link16": {},
"r3-link17": {},
"r3-link18": {},
"r3-link19": {},
"r3-link20": {},
"r3-link21": {},
"r3-link22": {},
"r3-link23": {},
"r3-link24": {},
"r3-link25": {},
"r3-link26": {},
"r3-link27": {},
"r3-link28": {},
"r3-link29": {},
"r3-link30": {},
"r3-link31": {},
"r3-link32": {}
}
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,674 @@
{
"address_types": [
"ipv4",
"ipv6"
],
"ipv4base": "10.0.0.0",
"ipv4mask": 24,
"ipv6base": "fd00::",
"ipv6mask": 64,
"link_ip_start": {
"ipv4": "10.0.0.0",
"v4mask": 24,
"ipv6": "fd00::",
"v6mask": 64
},
"lo_prefix": {
"ipv4": "1.0.",
"v4mask": 32,
"ipv6": "2001:DB8:F::",
"v6mask": 128
},
"routers": {
"r1": {
"links": {
"lo": {
"ipv4": "auto",
"ipv6": "auto",
"type": "loopback"
},
"r2-link1": {
"ipv4": "auto",
"ipv6": "auto"
}
},
"bgp": {
"local_as": "100",
"address_family": {
"ipv4": {
"unicast": {
"neighbor": {
"r2": {
"dest_link": {
"r1-link1": {}
}
}
}
}
},
"ipv6": {
"unicast": {
"neighbor": {
"r2": {
"dest_link": {
"r1-link1": {}
}
}
}
}
}
}
}
},
"r2": {
"links": {
"lo": {
"ipv4": "auto",
"ipv6": "auto",
"type": "loopback"
},
"r1-link1": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link1": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link2": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link3": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link4": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link5": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link6": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link7": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link8": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link9": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link10": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link11": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link12": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link13": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link14": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link15": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link16": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link17": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link18": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link19": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link20": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link21": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link22": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link23": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link24": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link25": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link26": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link27": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link28": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link29": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link30": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link31": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3-link32": {
"ipv4": "auto",
"ipv6": "auto"
}
},
"bgp": {
"local_as": "100",
"address_family": {
"ipv4": {
"unicast": {
"neighbor": {
"r1": {
"dest_link": {
"r2-link1": {}
}
},
"r3": {
"dest_link": {
"r2-link1": {
"next_hop_self": true
},
"r2-link2": {
"next_hop_self": true
},
"r2-link3": {
"next_hop_self": true
},
"r2-link4": {
"next_hop_self": true
},
"r2-link5": {
"next_hop_self": true
},
"r2-link6": {
"next_hop_self": true
},
"r2-link7": {
"next_hop_self": true
},
"r2-link8": {
"next_hop_self": true
},
"r2-link9": {
"next_hop_self": true
},
"r2-link10": {
"next_hop_self": true
},
"r2-link11": {
"next_hop_self": true
},
"r2-link12": {
"next_hop_self": true
},
"r2-link13": {
"next_hop_self": true
},
"r2-link14": {
"next_hop_self": true
},
"r2-link15": {
"next_hop_self": true
},
"r2-link16": {
"next_hop_self": true
},
"r2-link17": {
"next_hop_self": true
},
"r2-link18": {
"next_hop_self": true
},
"r2-link19": {
"next_hop_self": true
},
"r2-link20": {
"next_hop_self": true
},
"r2-link21": {
"next_hop_self": true
},
"r2-link22": {
"next_hop_self": true
},
"r2-link23": {
"next_hop_self": true
},
"r2-link24": {
"next_hop_self": true
},
"r2-link25": {
"next_hop_self": true
},
"r2-link26": {
"next_hop_self": true
},
"r2-link27": {
"next_hop_self": true
},
"r2-link28": {
"next_hop_self": true
},
"r2-link29": {
"next_hop_self": true
},
"r2-link30": {
"next_hop_self": true
},
"r2-link31": {
"next_hop_self": true
},
"r2-link32": {
"next_hop_self": true
}
}
}
},
"redistribute": [
{
"redist_type": "static"
}
]
}
},
"ipv6": {
"unicast": {
"neighbor": {
"r1": {
"dest_link": {
"r2-link1": {}
}
},
"r3": {
"dest_link": {
"r2-link1": {
"next_hop_self": true
},
"r2-link2": {
"next_hop_self": true
},
"r2-link3": {
"next_hop_self": true
},
"r2-link4": {
"next_hop_self": true
},
"r2-link5": {
"next_hop_self": true
},
"r2-link6": {
"next_hop_self": true
},
"r2-link7": {
"next_hop_self": true
},
"r2-link8": {
"next_hop_self": true
},
"r2-link9": {
"next_hop_self": true
},
"r2-link10": {
"next_hop_self": true
},
"r2-link11": {
"next_hop_self": true
},
"r2-link12": {
"next_hop_self": true
},
"r2-link13": {
"next_hop_self": true
},
"r2-link14": {
"next_hop_self": true
},
"r2-link15": {
"next_hop_self": true
},
"r2-link16": {
"next_hop_self": true
},
"r2-link17": {
"next_hop_self": true
},
"r2-link18": {
"next_hop_self": true
},
"r2-link19": {
"next_hop_self": true
},
"r2-link20": {
"next_hop_self": true
},
"r2-link21": {
"next_hop_self": true
},
"r2-link22": {
"next_hop_self": true
},
"r2-link23": {
"next_hop_self": true
},
"r2-link24": {
"next_hop_self": true
},
"r2-link25": {
"next_hop_self": true
},
"r2-link26": {
"next_hop_self": true
},
"r2-link27": {
"next_hop_self": true
},
"r2-link28": {
"next_hop_self": true
},
"r2-link29": {
"next_hop_self": true
},
"r2-link30": {
"next_hop_self": true
},
"r2-link31": {
"next_hop_self": true
},
"r2-link32": {
"next_hop_self": true
}
}
}
},
"redistribute": [
{
"redist_type": "static"
}
]
}
}
}
}
},
"r3": {
"links": {
"lo": {
"ipv4": "auto",
"ipv6": "auto",
"type": "loopback"
},
"r2-link1": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link2": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link3": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link4": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link5": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link6": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link7": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link8": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link9": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link10": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link11": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link12": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link13": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link14": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link15": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link16": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link17": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link18": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link19": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link20": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link21": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link22": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link23": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link24": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link25": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link26": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link27": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link28": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link29": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link30": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link31": {
"ipv4": "auto",
"ipv6": "auto"
},
"r2-link32": {
"ipv4": "auto",
"ipv6": "auto"
}
},
"bgp": {
"local_as": "100",
"address_family": {
"ipv4": {
"unicast": {
"maximum_paths": {
"ibgp": 32
},
"neighbor": {
"r2": {
"dest_link": {
"r3-link1": {},
"r3-link2": {},
"r3-link3": {},
"r3-link4": {},
"r3-link5": {},
"r3-link6": {},
"r3-link7": {},
"r3-link8": {},
"r3-link9": {},
"r3-link10": {},
"r3-link11": {},
"r3-link12": {},
"r3-link13": {},
"r3-link14": {},
"r3-link15": {},
"r3-link16": {},
"r3-link17": {},
"r3-link18": {},
"r3-link19": {},
"r3-link20": {},
"r3-link21": {},
"r3-link22": {},
"r3-link23": {},
"r3-link24": {},
"r3-link25": {},
"r3-link26": {},
"r3-link27": {},
"r3-link28": {},
"r3-link29": {},
"r3-link30": {},
"r3-link31": {},
"r3-link32": {}
}
}
}
}
},
"ipv6": {
"unicast": {
"maximum_paths": {
"ibgp": 32
},
"neighbor": {
"r2": {
"dest_link": {
"r3-link1": {},
"r3-link2": {},
"r3-link3": {},
"r3-link4": {},
"r3-link5": {},
"r3-link6": {},
"r3-link7": {},
"r3-link8": {},
"r3-link9": {},
"r3-link10": {},
"r3-link11": {},
"r3-link12": {},
"r3-link13": {},
"r3-link14": {},
"r3-link15": {},
"r3-link16": {},
"r3-link17": {},
"r3-link18": {},
"r3-link19": {},
"r3-link20": {},
"r3-link21": {},
"r3-link22": {},
"r3-link23": {},
"r3-link24": {},
"r3-link25": {},
"r3-link26": {},
"r3-link27": {},
"r3-link28": {},
"r3-link29": {},
"r3-link30": {},
"r3-link31": {},
"r3-link32": {}
}
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,817 @@
#!/usr/bin/env python
#
# Copyright (c) 2019 by VMware, Inc. ("VMware")
# Used Copyright (c) 2018 by Network Device Education Foundation, Inc.
# ("NetDEF") in this file.
#
# Permission to use, copy, modify, and/or distribute this software
# for any purpose with or without fee is hereby granted, provided
# that the above copyright notice and this permission notice appear
# in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
# OF THIS SOFTWARE.
#
"""
Following tests are covered to test ecmp functionality on EBGP.
1. Verify routes installed as per maximum-paths configuration (8/16/32)
2. Disable/Shut selected paths nexthops and verify other next are installed in
the RIB of DUT. Enable interfaces and verify RIB count.
3. Verify BGP table and RIB in DUT after clear BGP routes and neighbors.
4. Verify routes are cleared from BGP and RIB table of DUT when
redistribute static configuration is removed.
5. Shut BGP neigbors one by one and verify BGP and routing table updated
accordingly in DUT
6. Delete static routes and verify routers are cleared from BGP table and RIB
of DUT.
7. Verify routes are cleared from BGP and RIB table of DUT when advertise
network configuration is removed.
"""
import os
import sys
import time
import json
import pytest
# Save the Current Working Directory to find configuration files.
CWD = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(CWD, '../'))
sys.path.append(os.path.join(CWD, '../../'))
# pylint: disable=C0413
# Import topogen and topotest helpers
from lib.topogen import Topogen, get_topogen
from mininet.topo import Topo
from lib.common_config import (
start_topology, write_test_header,
write_test_footer,
verify_rib, create_static_routes, check_address_types,
interface_status, reset_config_on_routers
)
from lib.topolog import logger
from lib.bgp import (
verify_bgp_convergence, create_router_bgp,
clear_bgp_and_verify)
from lib.topojson import build_topo_from_json, build_config_from_json
# Reading the data from JSON File for topology and configuration creation
jsonFile = "{}/ebgp_ecmp_topo2.json".format(CWD)
try:
with open(jsonFile, "r") as topoJson:
topo = json.load(topoJson)
except IOError:
assert False, "Could not read file {}".format(jsonFile)
# Global variables
NEXT_HOPS = {"ipv4": [], "ipv6": []}
INTF_LIST_R3 = []
INTF_LIST_R2 = []
NETWORK = {"ipv4": "11.0.20.1/32", "ipv6": "1::/64"}
NEXT_HOP_IP = {"ipv4": "10.0.0.1", "ipv6": "fd00::1"}
BGP_CONVERGENCE = False
class CreateTopo(Topo):
"""
Test topology builder.
* `Topo`: Topology object
"""
def build(self, *_args, **_opts):
"""Build function."""
tgen = get_topogen(self)
# Building topology from json file
build_topo_from_json(tgen, topo)
def setup_module(mod):
"""
Sets up the pytest environment.
* `mod`: module name
"""
global NEXT_HOPS, INTF_LIST_R3, INTF_LIST_R2, TEST_STATIC
global ADDR_TYPES
testsuite_run_time = time.asctime(time.localtime(time.time()))
logger.info("Testsuite start time: {}".format(testsuite_run_time))
logger.info("=" * 40)
logger.info("Running setup_module to create topology")
# This function initiates the topology build with Topogen...
tgen = Topogen(CreateTopo, mod.__name__)
# Starting topology, create tmp files which are loaded to routers
# to start deamons and then start routers
start_topology(tgen)
# Creating configuration from JSON
build_config_from_json(tgen, topo)
# Don't run this test if we have any failure.
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
# tgen.mininet_cli()
# Api call verify whether BGP is converged
ADDR_TYPES = check_address_types()
BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
assert BGP_CONVERGENCE is True, ("setup_module :Failed \n Error:"
" {}".format(BGP_CONVERGENCE))
link_data = [val for links, val in
topo["routers"]["r2"]["links"].iteritems()
if "r3" in links]
for adt in ADDR_TYPES:
NEXT_HOPS[adt] = [val[adt].split("/")[0] for val in link_data]
if adt == "ipv4":
NEXT_HOPS[adt] = sorted(
NEXT_HOPS[adt], key=lambda x: int(x.split(".")[2]))
elif adt == "ipv6":
NEXT_HOPS[adt] = sorted(
NEXT_HOPS[adt], key=lambda x: int(x.split(':')[-3], 16))
INTF_LIST_R2 = [val["interface"].split("/")[0] for val in link_data]
INTF_LIST_R2 = sorted(INTF_LIST_R2, key=lambda x: int(x.split("eth")[1]))
link_data = [val for links, val in
topo["routers"]["r3"]["links"].iteritems()
if "r2" in links]
INTF_LIST_R3 = [val["interface"].split("/")[0] for val in link_data]
INTF_LIST_R3 = sorted(INTF_LIST_R3, key=lambda x: int(x.split("eth")[1]))
# STATIC_ROUTE = True
logger.info("Running setup_module() done")
def teardown_module():
"""
Teardown the pytest environment.
* `mod`: module name
"""
logger.info("Running teardown_module to delete topology")
tgen = get_topogen()
# Stop toplogy and Remove tmp files
tgen.stop_topology()
def static_or_nw(tgen, topo, tc_name, test_type, dut):
if test_type == "redist_static":
input_dict_static = {
dut: {
"static_routes": [
{
"network": NETWORK["ipv4"],
"next_hop": NEXT_HOP_IP["ipv4"]
},
{
"network": NETWORK["ipv6"],
"next_hop": NEXT_HOP_IP["ipv6"]
}
]
}
}
logger.info("Configuring static route on router %s", dut)
result = create_static_routes(tgen, input_dict_static)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
input_dict_2 = {
dut: {
"bgp": {
"address_family": {
"ipv4": {
"unicast": {
"redistribute": [{
"redist_type": "static"
}]
}
},
"ipv6": {
"unicast": {
"redistribute": [{
"redist_type": "static"
}]
}
}
}
}
}
}
logger.info("Configuring redistribute static route on router %s", dut)
result = create_router_bgp(tgen, topo, input_dict_2)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
elif test_type == "advertise_nw":
input_dict_nw = {
dut: {
"bgp": {
"address_family": {
"ipv4": {
"unicast": {
"advertise_networks": [
{"network": NETWORK["ipv4"]}
]
}
},
"ipv6": {
"unicast": {
"advertise_networks": [
{"network": NETWORK["ipv6"]}
]
}
}
}
}
}
}
logger.info("Advertising networks %s %s from router %s",
NETWORK["ipv4"], NETWORK["ipv6"], dut)
result = create_router_bgp(tgen, topo, input_dict_nw)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
@pytest.mark.parametrize("ecmp_num", ["8", "16", "32"])
@pytest.mark.parametrize("test_type", ["redist_static", "advertise_nw"])
def test_modify_ecmp_max_paths(request, ecmp_num, test_type):
"""
Verify routes installed as per maximum-paths
configuration (8/16/32).
"""
tc_name = request.node.name
write_test_header(tc_name)
tgen = get_topogen()
reset_config_on_routers(tgen)
static_or_nw(tgen, topo, tc_name, test_type, "r2")
input_dict = {
"r3": {
"bgp": {
"address_family": {
"ipv4": {
"unicast": {
"maximum_paths": {
"ebgp": ecmp_num,
}
}
},
"ipv6": {
"unicast": {
"maximum_paths": {
"ebgp": ecmp_num,
}
}
}
}
}
}
}
logger.info("Configuring bgp maximum-paths %s on router r3", ecmp_num)
result = create_router_bgp(tgen, topo, input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
# Verifying RIB routes
dut = "r3"
protocol = "bgp"
for addr_type in ADDR_TYPES:
input_dict_1 = {
"r3": {
"static_routes": [
{
"network": NETWORK[addr_type]
}
]
}
}
logger.info("Verifying %s routes on r3", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict_1,
next_hop=NEXT_HOPS[addr_type],
protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
write_test_footer(tc_name)
def test_ecmp_after_clear_bgp(request):
""" Verify BGP table and RIB in DUT after clear BGP routes and neighbors"""
tc_name = request.node.name
write_test_header(tc_name)
tgen = get_topogen()
reset_config_on_routers(tgen)
# Verifying RIB routes
dut = "r3"
protocol = "bgp"
static_or_nw(tgen, topo, tc_name, "redist_static", "r2")
for addr_type in ADDR_TYPES:
input_dict_1 = {
"r3": {
"static_routes": [
{
"network": NETWORK[addr_type]
}
]
}
}
logger.info("Verifying %s routes on r3", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict_1,
next_hop=NEXT_HOPS[addr_type],
protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
# Clear bgp
result = clear_bgp_and_verify(tgen, topo, dut)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
for addr_type in ADDR_TYPES:
input_dict_1 = {
"r3": {
"static_routes": [
{
"network": NETWORK[addr_type]
}
]
}
}
logger.info("Verifying %s routes on r3", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict_1,
next_hop=NEXT_HOPS[addr_type],
protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
write_test_footer(tc_name)
def test_ecmp_remove_redistribute_static(request):
""" Verify routes are cleared from BGP and RIB table of DUT when
redistribute static configuration is removed."""
tc_name = request.node.name
write_test_header(tc_name)
tgen = get_topogen()
reset_config_on_routers(tgen)
static_or_nw(tgen, topo, tc_name, "redist_static", "r2")
for addr_type in ADDR_TYPES:
# Verifying RIB routes
dut = "r3"
protocol = "bgp"
input_dict_1 = {
"r3": {
"static_routes": [
{
"network": NETWORK[addr_type]
}
]
}
}
logger.info("Verifying %s routes on r3", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict_1,
next_hop=NEXT_HOPS[addr_type],
protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
input_dict_2 = {
"r2": {
"bgp": {
"address_family": {
"ipv4": {
"unicast": {
"redistribute": [{
"redist_type": "static",
"delete": True
}]
}
},
"ipv6": {
"unicast": {
"redistribute": [{
"redist_type": "static",
"delete": True
}]
}
}
}
}
}
}
logger.info("Remove redistribute static")
result = create_router_bgp(tgen, topo, input_dict_2)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
for addr_type in ADDR_TYPES:
# Verifying RIB routes
dut = "r3"
protocol = "bgp"
input_dict_1 = {
"r3": {
"static_routes": [
{
"network": NETWORK[addr_type]
}
]
}
}
logger.info("Verifying %s routes on r3 are deleted", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict_1,
next_hop=[], protocol=protocol, expected=False)
assert result is not True, "Testcase {} : Failed \n Routes still" \
" present in RIB".format(tc_name)
logger.info("Enable redistribute static")
input_dict_2 = {
"r2": {
"bgp": {
"address_family": {
"ipv4": {
"unicast": {
"redistribute": [{
"redist_type": "static"
}]
}
},
"ipv6": {
"unicast": {
"redistribute": [{
"redist_type": "static"
}]
}
}
}
}
}
}
result = create_router_bgp(tgen, topo, input_dict_2)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
for addr_type in ADDR_TYPES:
# Verifying RIB routes
dut = "r3"
protocol = "bgp"
input_dict_1 = {
"r3": {
"static_routes": [
{
"network": NETWORK[addr_type]
}
]
}
}
logger.info("Verifying %s routes on r3", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict_1,
next_hop=NEXT_HOPS[addr_type],
protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
write_test_footer(tc_name)
def test_ecmp_shut_bgp_neighbor(request):
"""
Disable/Shut selected paths nexthops and verify other next are installed in
the RIB of DUT. Enable interfaces and verify RIB count.
Shut BGP neigbors one by one and verify BGP and routing table updated
accordingly in DUT
"""
tc_name = request.node.name
write_test_header(tc_name)
tgen = get_topogen()
logger.info(INTF_LIST_R2)
# Verifying RIB routes
dut = "r3"
protocol = "bgp"
reset_config_on_routers(tgen)
static_or_nw(tgen, topo, tc_name, "redist_static", "r2")
for addr_type in ADDR_TYPES:
input_dict = {
"r3": {
"static_routes": [
{
"network": NETWORK[addr_type]
}
]
}
}
logger.info("Verifying %s routes on r3", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict,
next_hop=NEXT_HOPS[addr_type],
protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
for intf_num in range(len(INTF_LIST_R2)+1, 16):
intf_val = INTF_LIST_R2[intf_num:intf_num+16]
input_dict_1 = {
"r2": {
"interface_list": [intf_val],
"status": "down"
}
}
logger.info("Shutting down neighbor interface {} on r2".
format(intf_val))
result = interface_status(tgen, topo, input_dict_1)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
for addr_type in ADDR_TYPES:
if intf_num + 16 < 32:
check_hops = NEXT_HOPS[addr_type]
else:
check_hops = []
input_dict = {
"r3": {
"static_routes": [
{
"network": NETWORK[addr_type]
}
]
}
}
logger.info("Verifying %s routes on r3", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict,
next_hop=check_hops,
protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
input_dict_1 = {
"r2": {
"interface_list": INTF_LIST_R2,
"status": "up"
}
}
logger.info("Enabling all neighbor interface {} on r2")
result = interface_status(tgen, topo, input_dict_1)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
static_or_nw(tgen, topo, tc_name, "redist_static", "r2")
for addr_type in ADDR_TYPES:
input_dict = {
"r3": {
"static_routes": [
{
"network": NETWORK[addr_type]
}
]
}
}
logger.info("Verifying %s routes on r3", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict,
next_hop=NEXT_HOPS[addr_type],
protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
write_test_footer(tc_name)
def test_ecmp_remove_static_route(request):
"""
Delete static routes and verify routers are cleared from BGP table,
and RIB of DUT.
"""
tc_name = request.node.name
write_test_header(tc_name)
tgen = get_topogen()
# Verifying RIB routes
dut = "r3"
protocol = "bgp"
reset_config_on_routers(tgen)
static_or_nw(tgen, topo, tc_name, "redist_static", "r2")
for addr_type in ADDR_TYPES:
input_dict_1 = {
"r3": {
"static_routes": [
{
"network": NETWORK[addr_type]
}
]
}
}
logger.info("Verifying %s routes on r3", addr_type)
result = verify_rib(
tgen, addr_type, dut, input_dict_1,
next_hop=NEXT_HOPS[addr_type], protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
for addr_type in ADDR_TYPES:
input_dict_2 = {
"r2": {
"static_routes": [
{
"network": NETWORK[addr_type],
"next_hop": NEXT_HOP_IP[addr_type],
"delete": True
}
]
}
}
logger.info("Remove static routes")
result = create_static_routes(tgen, input_dict_2)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
logger.info("Verifying %s routes on r3 are removed", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict_2,
next_hop=[], protocol=protocol, expected=False)
assert result is not True, "Testcase {} : Failed \n Routes still" \
" present in RIB".format(tc_name)
for addr_type in ADDR_TYPES:
# Enable static routes
input_dict_4 = {
"r2": {
"static_routes": [
{
"network": NETWORK[addr_type],
"next_hop": NEXT_HOP_IP[addr_type]
}
]
}
}
logger.info("Enable static route")
result = create_static_routes(tgen, input_dict_4)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
logger.info("Verifying %s routes on r3", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict_4,
next_hop=NEXT_HOPS[addr_type],
protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
def test_ecmp_remove_nw_advertise(request):
"""
Verify routes are cleared from BGP and RIB table of DUT,
when advertise network configuration is removed
"""
tc_name = request.node.name
write_test_header(tc_name)
tgen = get_topogen()
# Verifying RIB routes
dut = "r3"
protocol = "bgp"
reset_config_on_routers(tgen)
static_or_nw(tgen, topo, tc_name, "advertise_nw", "r2")
for addr_type in ADDR_TYPES:
input_dict = {
"r3": {
"static_routes": [
{
"network": NETWORK[addr_type]
}
]
}
}
logger.info("Verifying %s routes on r3", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict,
next_hop=NEXT_HOPS[addr_type],
protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
input_dict_3 = {
"r2": {
"bgp": {
"address_family": {
"ipv4": {
"unicast": {
"advertise_networks": [{
"network": NETWORK["ipv4"],
"delete": True
}]
}
},
"ipv6": {
"unicast": {
"advertise_networks": [{
"network": NETWORK["ipv6"],
"delete": True
}]
}
}
}
}
}
}
logger.info("Withdraw advertised networks")
result = create_router_bgp(tgen, topo, input_dict_3)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
for addr_type in ADDR_TYPES:
input_dict = {
"r3": {
"static_routes": [
{
"network": NETWORK[addr_type]
}
]
}
}
logger.info("Verifying %s routes on r3", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict,
next_hop=[], protocol=protocol, expected=False)
assert result is not True, "Testcase {} : Failed \n Routes still" \
" present in RIB".format(tc_name)
static_or_nw(tgen, topo, tc_name, "advertise_nw", "r2")
for addr_type in ADDR_TYPES:
input_dict = {
"r3": {
"static_routes": [
{
"network": NETWORK[addr_type]
}
]
}
}
logger.info("Verifying %s routes on r3", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict,
next_hop=NEXT_HOPS[addr_type],
protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
write_test_footer(tc_name)
if __name__ == "__main__":
args = ["-s"] + sys.argv[1:]
sys.exit(pytest.main(args))

View File

@ -0,0 +1,813 @@
#!/usr/bin/env python
#
# Copyright (c) 2019 by VMware, Inc. ("VMware")
# Used Copyright (c) 2018 by Network Device Education Foundation, Inc.
# ("NetDEF") in this file.
#
# Permission to use, copy, modify, and/or distribute this software
# for any purpose with or without fee is hereby granted, provided
# that the above copyright notice and this permission notice appear
# in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
# OF THIS SOFTWARE.
#
"""
Following tests are covered to test ecmp functionality on EBGP.
1. Verify routes installed as per maximum-paths configuration (8/16/32)
2. Disable/Shut selected paths nexthops and verify other next are installed in
the RIB of DUT. Enable interfaces and verify RIB count.
3. Verify BGP table and RIB in DUT after clear BGP routes and neighbors.
4. Verify routes are cleared from BGP and RIB table of DUT when
redistribute static configuration is removed.
5. Shut BGP neigbors one by one and verify BGP and routing table updated
accordingly in DUT
6. Delete static routes and verify routers are cleared from BGP table and RIB
of DUT.
7. Verify routes are cleared from BGP and RIB table of DUT when advertise
network configuration is removed.
"""
import os
import sys
import time
import json
import pytest
# Save the Current Working Directory to find configuration files.
CWD = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(CWD, '../'))
sys.path.append(os.path.join(CWD, '../../'))
# pylint: disable=C0413
# Import topogen and topotest helpers
from lib.topogen import Topogen, get_topogen
from mininet.topo import Topo
from lib.common_config import (
start_topology, write_test_header,
write_test_footer,
verify_rib, create_static_routes, check_address_types,
interface_status, reset_config_on_routers
)
from lib.topolog import logger
from lib.bgp import (
verify_bgp_convergence, create_router_bgp,
clear_bgp_and_verify)
from lib.topojson import build_topo_from_json, build_config_from_json
# Reading the data from JSON File for topology and configuration creation
jsonFile = "{}/ibgp_ecmp_topo2.json".format(CWD)
try:
with open(jsonFile, "r") as topoJson:
topo = json.load(topoJson)
except IOError:
assert False, "Could not read file {}".format(jsonFile)
# Global variables
NEXT_HOPS = {"ipv4": [], "ipv6": []}
INTF_LIST_R3 = []
INTF_LIST_R2 = []
NETWORK = {"ipv4": "11.0.20.1/32", "ipv6": "1::/64"}
NEXT_HOP_IP = {"ipv4": "10.0.0.1", "ipv6": "fd00::1"}
BGP_CONVERGENCE = False
class CreateTopo(Topo):
"""
Test topology builder.
* `Topo`: Topology object
"""
def build(self, *_args, **_opts):
"""Build function."""
tgen = get_topogen(self)
# Building topology from json file
build_topo_from_json(tgen, topo)
def setup_module(mod):
"""
Sets up the pytest environment.
* `mod`: module name
"""
global NEXT_HOPS, INTF_LIST_R3, INTF_LIST_R2, TEST_STATIC
global ADDR_TYPES
testsuite_run_time = time.asctime(time.localtime(time.time()))
logger.info("Testsuite start time: {}".format(testsuite_run_time))
logger.info("=" * 40)
logger.info("Running setup_module to create topology")
# This function initiates the topology build with Topogen...
tgen = Topogen(CreateTopo, mod.__name__)
# Starting topology, create tmp files which are loaded to routers
# to start deamons and then start routers
start_topology(tgen)
# Creating configuration from JSON
build_config_from_json(tgen, topo)
# Don't run this test if we have any failure.
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
# tgen.mininet_cli()
# Api call verify whether BGP is converged
ADDR_TYPES = check_address_types()
for addr_type in ADDR_TYPES:
BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
assert BGP_CONVERGENCE is True, ("setup_module :Failed \n Error:"
" {}".format(BGP_CONVERGENCE))
link_data = [val for links, val in
topo["routers"]["r2"]["links"].iteritems()
if "r3" in links]
for adt in ADDR_TYPES:
NEXT_HOPS[adt] = [val[adt].split("/")[0] for val in link_data]
if adt == "ipv4":
NEXT_HOPS[adt] = sorted(
NEXT_HOPS[adt], key=lambda x: int(x.split(".")[2]))
elif adt == "ipv6":
NEXT_HOPS[adt] = sorted(
NEXT_HOPS[adt], key=lambda x: int(x.split(':')[-3], 16))
INTF_LIST_R2 = [val["interface"].split("/")[0] for val in link_data]
INTF_LIST_R2 = sorted(INTF_LIST_R2, key=lambda x: int(x.split("eth")[1]))
link_data = [val for links, val in
topo["routers"]["r3"]["links"].iteritems()
if "r2" in links]
INTF_LIST_R3 = [val["interface"].split("/")[0] for val in link_data]
INTF_LIST_R3 = sorted(INTF_LIST_R3, key=lambda x: int(x.split("eth")[1]))
# STATIC_ROUTE = True
logger.info("Running setup_module() done")
def teardown_module():
"""
Teardown the pytest environment.
* `mod`: module name
"""
logger.info("Running teardown_module to delete topology")
tgen = get_topogen()
# Stop toplogy and Remove tmp files
tgen.stop_topology()
def static_or_nw(tgen, topo, tc_name, test_type, dut):
if test_type == "redist_static":
input_dict_static = {
dut: {
"static_routes": [
{
"network": NETWORK["ipv4"],
"next_hop": NEXT_HOP_IP["ipv4"]
},
{
"network": NETWORK["ipv6"],
"next_hop": NEXT_HOP_IP["ipv6"]
}
]
}
}
logger.info("Configuring static route on router %s", dut)
result = create_static_routes(tgen, input_dict_static)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
input_dict_2 = {
dut: {
"bgp": {
"address_family": {
"ipv4": {
"unicast": {
"redistribute": [{
"redist_type": "static"
}]
}
},
"ipv6": {
"unicast": {
"redistribute": [{
"redist_type": "static"
}]
}
}
}
}
}
}
logger.info("Configuring redistribute static route on router %s", dut)
result = create_router_bgp(tgen, topo, input_dict_2)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
elif test_type == "advertise_nw":
input_dict_nw = {
dut: {
"bgp": {
"address_family": {
"ipv4": {
"unicast": {
"advertise_networks": [
{"network": NETWORK["ipv4"]}
]
}
},
"ipv6": {
"unicast": {
"advertise_networks": [
{"network": NETWORK["ipv6"]}
]
}
}
}
}
}
}
logger.info("Advertising networks %s %s from router %s",
NETWORK["ipv4"], NETWORK["ipv6"], dut)
result = create_router_bgp(tgen, topo, input_dict_nw)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
@pytest.mark.parametrize("ecmp_num", ["8", "16", "32"])
@pytest.mark.parametrize("test_type", ["redist_static", "advertise_nw"])
def test_modify_ecmp_max_paths(request, ecmp_num, test_type):
"""
Verify routes installed as per maximum-paths
configuration (8/16/32).
"""
tc_name = request.node.name
write_test_header(tc_name)
tgen = get_topogen()
reset_config_on_routers(tgen)
static_or_nw(tgen, topo, tc_name, test_type, "r2")
input_dict = {
"r3": {
"bgp": {
"address_family": {
"ipv4": {
"unicast": {
"maximum_paths": {
"ibgp": ecmp_num,
}
}
},
"ipv6": {
"unicast": {
"maximum_paths": {
"ibgp": ecmp_num,
}
}
}
}
}
}
}
logger.info("Configuring bgp maximum-paths %s on router r3", ecmp_num)
result = create_router_bgp(tgen, topo, input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
# Verifying RIB routes
dut = "r3"
protocol = "bgp"
for addr_type in ADDR_TYPES:
input_dict_1 = {
"r3": {
"static_routes": [
{
"network": NETWORK[addr_type]
}
]
}
}
logger.info("Verifying %s routes on r3", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict_1,
next_hop=NEXT_HOPS[addr_type],
protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
write_test_footer(tc_name)
def test_ecmp_after_clear_bgp(request):
""" Verify BGP table and RIB in DUT after clear BGP routes and neighbors"""
tc_name = request.node.name
write_test_header(tc_name)
tgen = get_topogen()
reset_config_on_routers(tgen)
# Verifying RIB routes
dut = "r3"
protocol = "bgp"
static_or_nw(tgen, topo, tc_name, "redist_static", "r2")
for addr_type in ADDR_TYPES:
input_dict_1 = {
"r3": {
"static_routes": [
{
"network": NETWORK[addr_type]
}
]
}
}
logger.info("Verifying %s routes on r3", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict_1,
next_hop=NEXT_HOPS[addr_type],
protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
# Clear bgp
result = clear_bgp_and_verify(tgen, topo, dut)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
for addr_type in ADDR_TYPES:
input_dict_1 = {
"r3": {
"static_routes": [
{
"network": NETWORK[addr_type]
}
]
}
}
logger.info("Verifying %s routes on r3", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict_1,
next_hop=NEXT_HOPS[addr_type],
protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
write_test_footer(tc_name)
def test_ecmp_remove_redistribute_static(request):
""" Verify routes are cleared from BGP and RIB table of DUT when
redistribute static configuration is removed."""
tc_name = request.node.name
write_test_header(tc_name)
tgen = get_topogen()
reset_config_on_routers(tgen)
static_or_nw(tgen, topo, tc_name, "redist_static", "r2")
for addr_type in ADDR_TYPES:
# Verifying RIB routes
dut = "r3"
protocol = "bgp"
input_dict_1 = {
"r3": {
"static_routes": [
{
"network": NETWORK[addr_type]
}
]
}
}
logger.info("Verifying %s routes on r3", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict_1,
next_hop=NEXT_HOPS[addr_type],
protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
input_dict_2 = {
"r2": {
"bgp": {
"address_family": {
"ipv4": {
"unicast": {
"redistribute": [{
"redist_type": "static",
"delete": True
}]
}
},
"ipv6": {
"unicast": {
"redistribute": [{
"redist_type": "static",
"delete": True
}]
}
}
}
}
}
}
logger.info("Remove redistribute static")
result = create_router_bgp(tgen, topo, input_dict_2)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
for addr_type in ADDR_TYPES:
# Verifying RIB routes
dut = "r3"
protocol = "bgp"
input_dict_1 = {
"r3": {
"static_routes": [
{
"network": NETWORK[addr_type]
}
]
}
}
logger.info("Verifying %s routes on r3 are deleted", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict_1,
next_hop=[], protocol=protocol, expected=False)
assert result is not True, "Testcase {} : Failed \n Routes still" \
" present in RIB".format(tc_name)
logger.info("Enable redistribute static")
input_dict_2 = {
"r2": {
"bgp": {
"address_family": {
"ipv4": {
"unicast": {
"redistribute": [{
"redist_type": "static"
}]
}
},
"ipv6": {
"unicast": {
"redistribute": [{
"redist_type": "static"
}]
}
}
}
}
}
}
result = create_router_bgp(tgen, topo, input_dict_2)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
for addr_type in ADDR_TYPES:
# Verifying RIB routes
dut = "r3"
protocol = "bgp"
input_dict_1 = {
"r3": {
"static_routes": [
{
"network": NETWORK[addr_type]
}
]
}
}
logger.info("Verifying %s routes on r3", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict_1,
next_hop=NEXT_HOPS[addr_type],
protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
write_test_footer(tc_name)
def test_ecmp_shut_bgp_neighbor(request):
""" Shut BGP neigbors one by one and verify BGP and routing table updated
accordingly in DUT """
tc_name = request.node.name
write_test_header(tc_name)
tgen = get_topogen()
logger.info(INTF_LIST_R2)
# Verifying RIB routes
dut = "r3"
protocol = "bgp"
reset_config_on_routers(tgen)
static_or_nw(tgen, topo, tc_name, "redist_static", "r2")
for addr_type in ADDR_TYPES:
input_dict = {
"r3": {
"static_routes": [
{
"network": NETWORK[addr_type]
}
]
}
}
logger.info("Verifying %s routes on r3", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict,
next_hop=NEXT_HOPS[addr_type],
protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
for intf_num in range(len(INTF_LIST_R2)+1, 16):
intf_val = INTF_LIST_R2[intf_num:intf_num+16]
input_dict_1 = {
"r2": {
"interface_list": [intf_val],
"status": "down"
}
}
logger.info("Shutting down neighbor interface {} on r2".
format(intf_val))
result = interface_status(tgen, topo, input_dict_1)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
for addr_type in ADDR_TYPES:
if intf_num + 16 < 32:
check_hops = NEXT_HOPS[addr_type]
else:
check_hops = []
input_dict = {
"r3": {
"static_routes": [
{
"network": NETWORK[addr_type]
}
]
}
}
logger.info("Verifying %s routes on r3", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict,
next_hop=check_hops,
protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
input_dict_1 = {
"r2": {
"interface_list": INTF_LIST_R2,
"status": "up"
}
}
logger.info("Enabling all neighbor interface {} on r2")
result = interface_status(tgen, topo, input_dict_1)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
static_or_nw(tgen, topo, tc_name, "redist_static", "r2")
for addr_type in ADDR_TYPES:
input_dict = {
"r3": {
"static_routes": [
{
"network": NETWORK[addr_type]
}
]
}
}
logger.info("Verifying %s routes on r3", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict,
next_hop=NEXT_HOPS[addr_type],
protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
write_test_footer(tc_name)
def test_ecmp_remove_static_route(request):
"""
Delete static routes and verify routers are cleared from BGP table,
and RIB of DUT.
"""
tc_name = request.node.name
write_test_header(tc_name)
tgen = get_topogen()
# Verifying RIB routes
dut = "r3"
protocol = "bgp"
reset_config_on_routers(tgen)
static_or_nw(tgen, topo, tc_name, "redist_static", "r2")
for addr_type in ADDR_TYPES:
input_dict_1 = {
"r3": {
"static_routes": [
{
"network": NETWORK[addr_type]
}
]
}
}
logger.info("Verifying %s routes on r3", addr_type)
result = verify_rib(
tgen, addr_type, dut, input_dict_1,
next_hop=NEXT_HOPS[addr_type], protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
for addr_type in ADDR_TYPES:
input_dict_2 = {
"r2": {
"static_routes": [
{
"network": NETWORK[addr_type],
"next_hop": NEXT_HOP_IP[addr_type],
"delete": True
}
]
}
}
logger.info("Remove static routes")
result = create_static_routes(tgen, input_dict_2)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
logger.info("Verifying %s routes on r3 are removed", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict_2,
next_hop=[], protocol=protocol, expected=False)
assert result is not True, "Testcase {} : Failed \n Routes still" \
" present in RIB".format(tc_name)
for addr_type in ADDR_TYPES:
# Enable static routes
input_dict_4 = {
"r2": {
"static_routes": [
{
"network": NETWORK[addr_type],
"next_hop": NEXT_HOP_IP[addr_type]
}
]
}
}
logger.info("Enable static route")
result = create_static_routes(tgen, input_dict_4)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
logger.info("Verifying %s routes on r3", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict_4,
next_hop=NEXT_HOPS[addr_type],
protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
write_test_footer(tc_name)
def test_ecmp_remove_nw_advertise(request):
"""
Verify routes are cleared from BGP and RIB table of DUT,
when advertise network configuration is removed
"""
tc_name = request.node.name
write_test_header(tc_name)
tgen = get_topogen()
# Verifying RIB routes
dut = "r3"
protocol = "bgp"
reset_config_on_routers(tgen)
static_or_nw(tgen, topo, tc_name, "advertise_nw", "r2")
for addr_type in ADDR_TYPES:
input_dict = {
"r3": {
"static_routes": [
{
"network": NETWORK[addr_type]
}
]
}
}
logger.info("Verifying %s routes on r3", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict,
next_hop=NEXT_HOPS[addr_type],
protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
input_dict_3 = {
"r2": {
"bgp": {
"address_family": {
"ipv4": {
"unicast": {
"advertise_networks": [{
"network": NETWORK["ipv4"],
"delete": True
}]
}
},
"ipv6": {
"unicast": {
"advertise_networks": [{
"network": NETWORK["ipv6"],
"delete": True
}]
}
}
}
}
}
}
logger.info("Withdraw advertised networks")
result = create_router_bgp(tgen, topo, input_dict_3)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
for addr_type in ADDR_TYPES:
input_dict = {
"r3": {
"static_routes": [
{
"network": NETWORK[addr_type]
}
]
}
}
logger.info("Verifying %s routes on r3", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict,
next_hop=[], protocol=protocol, expected=False)
assert result is not True, "Testcase {} : Failed \n Routes still" \
" present in RIB".format(tc_name)
static_or_nw(tgen, topo, tc_name, "advertise_nw", "r2")
for addr_type in ADDR_TYPES:
input_dict = {
"r3": {
"static_routes": [
{
"network": NETWORK[addr_type]
}
]
}
}
logger.info("Verifying %s routes on r3", addr_type)
result = verify_rib(tgen, addr_type, dut, input_dict,
next_hop=NEXT_HOPS[addr_type],
protocol=protocol)
assert result is True, "Testcase {} : Failed \n Error: {}".format(
tc_name, result)
if __name__ == "__main__":
args = ["-s"] + sys.argv[1:]
sys.exit(pytest.main(args))

View File

@ -178,7 +178,7 @@ def test_static_routes(request):
# Static routes are created as part of initial configuration, # Static routes are created as part of initial configuration,
# verifying RIB # verifying RIB
dut = 'r3' dut = 'r3'
next_hop = '10.0.0.1' next_hop = ['10.0.0.1', '10.0.0.5']
input_dict = { input_dict = {
"r1": { "r1": {
"static_routes": [ "static_routes": [

View File

@ -470,9 +470,9 @@ def __create_bgp_unicast_address_family(topo, input_dict, router, addr_type,
dest_link]["ipv6"].split("/")[0] dest_link]["ipv6"].split("/")[0]
neigh_cxt = "neighbor {}".format(ip_addr) neigh_cxt = "neighbor {}".format(ip_addr)
#config_data.append("address-family {} unicast".format( config_data.append("address-family {} unicast".format(
# addr_type addr_type
#)) ))
if deactivate: if deactivate:
config_data.append( config_data.append(
"no neighbor {} activate".format(deactivate)) "no neighbor {} activate".format(deactivate))

View File

@ -34,12 +34,14 @@ import ConfigParser
import traceback import traceback
import socket import socket
import ipaddr import ipaddr
import re
from lib import topotest from lib import topotest
from functools import partial from functools import partial
from lib.topolog import logger, logger_config from lib.topolog import logger, logger_config
from lib.topogen import TopoRouter from lib.topogen import TopoRouter
from lib.topotest import interface_set_status
FRRCFG_FILE = "frr_json.conf" FRRCFG_FILE = "frr_json.conf"
@ -513,27 +515,31 @@ def validate_ip_address(ip_address):
" address" % ip_address) " address" % ip_address)
def check_address_types(addr_type): def check_address_types(addr_type=None):
""" """
Checks environment variable set and compares with the current address type Checks environment variable set and compares with the current address type
""" """
global ADDRESS_TYPES
if ADDRESS_TYPES is None:
ADDRESS_TYPES = "dual"
if ADDRESS_TYPES == "dual": addr_types_env = os.environ.get("ADDRESS_TYPES")
ADDRESS_TYPES = ["ipv4", "ipv6"] if not addr_types_env:
elif ADDRESS_TYPES == "ipv4": addr_types_env = "dual"
ADDRESS_TYPES = ["ipv4"]
elif ADDRESS_TYPES == "ipv6":
ADDRESS_TYPES = ["ipv6"]
if addr_type not in ADDRESS_TYPES: if addr_types_env == "dual":
addr_types = ["ipv4", "ipv6"]
elif addr_types_env == "ipv4":
addr_types = ["ipv4"]
elif addr_types_env == "ipv6":
addr_types = ["ipv6"]
if addr_type is None:
return addr_types
if addr_type not in addr_types:
logger.error("{} not in supported/configured address types {}". logger.error("{} not in supported/configured address types {}".
format(addr_type, ADDRESS_TYPES)) format(addr_type, addr_types))
return False return False
return ADDRESS_TYPES return True
def generate_ips(network, no_of_ips): def generate_ips(network, no_of_ips):
@ -627,6 +633,54 @@ def write_test_footer(tc_name):
logger.info("="*(len(tc_name)+count)) logger.info("="*(len(tc_name)+count))
def interface_status(tgen, topo, input_dict):
"""
Delete ip route maps from device
* `tgen` : Topogen object
* `topo` : json file data
* `input_dict` : for which router, route map has to be deleted
Usage
-----
input_dict = {
"r3": {
"interface_list": ['eth1-r1-r2', 'eth2-r1-r3'],
"status": "down"
}
}
Returns
-------
errormsg(str) or True
"""
logger.debug("Entering lib API: interface_status()")
try:
global frr_cfg
for router in input_dict.keys():
interface_list = input_dict[router]['interface_list']
status = input_dict[router].setdefault('status', 'up')
for intf in interface_list:
rnode = tgen.routers()[router]
interface_set_status(rnode, intf, status)
# Load config to router
load_config_to_router(tgen, router)
except Exception as e:
# handle any exception
logger.error("Error %s occured. Arguments %s.", e.message, e.args)
# Traceback
errormsg = traceback.format_exc()
logger.error(errormsg)
return errormsg
logger.debug("Exiting lib API: interface_status()")
return True
def retry(attempts=3, wait=2, return_is_str=True, initial_wait=0): def retry(attempts=3, wait=2, return_is_str=True, initial_wait=0):
""" """
Retries function execution, if return is an errormsg or exception Retries function execution, if return is an errormsg or exception
@ -682,6 +736,62 @@ def retry(attempts=3, wait=2, return_is_str=True, initial_wait=0):
return _retry return _retry
def disable_v6_link_local(tgen, router, intf_name=None):
"""
Disables ipv6 link local addresses for a particular interface or
all interfaces
* `tgen`: tgen onject
* `router` : router for which hightest interface should be
calculated
* `intf_name` : Interface name for which v6 link local needs to
be disabled
"""
router_list = tgen.routers()
for rname, rnode in router_list.iteritems():
if rname != router:
continue
linklocal = []
ifaces = router_list[router].run('ip -6 address')
# Fix newlines (make them all the same)
ifaces = ('\n'.join(ifaces.splitlines()) + '\n').splitlines()
interface = None
ll_per_if_count = 0
for line in ifaces:
# Interface name
m = re.search('[0-9]+: ([^:]+)[@if0-9:]+ <', line)
if m:
interface = m.group(1).split("@")[0]
ll_per_if_count = 0
# Interface ip
m = re.search('inet6 (fe80::[0-9a-f]+:[0-9a-f]+:[0-9a-f]+'
':[0-9a-f]+[/0-9]*) scope link', line)
if m:
local = m.group(1)
ll_per_if_count += 1
if ll_per_if_count > 1:
linklocal += [["%s-%s" % (interface, ll_per_if_count), local]]
else:
linklocal += [[interface, local]]
if len(linklocal[0]) > 1:
link_local_dict = {item[0]: item[1] for item in linklocal}
for lname, laddr in link_local_dict.items():
if intf_name is not None and lname != intf_name:
continue
cmd = "ip addr del {} dev {}".format(laddr, lname)
router_list[router].run(cmd)
############################################# #############################################
# These APIs, will used by testcase # These APIs, will used by testcase
############################################# #############################################
@ -711,6 +821,8 @@ def create_interfaces_cfg(tgen, topo, build=False):
interface_name = destRouterLink interface_name = destRouterLink
else: else:
interface_name = data["interface"] interface_name = data["interface"]
if "ipv6" in data:
disable_v6_link_local(tgen, c_router, interface_name)
interface_data.append("interface {}".format( interface_data.append("interface {}".format(
str(interface_name) str(interface_name)
)) ))
@ -724,6 +836,7 @@ def create_interfaces_cfg(tgen, topo, build=False):
interface_data.append("ipv6 address {}".format( interface_data.append("ipv6 address {}".format(
intf_addr intf_addr
)) ))
result = create_common_configuration(tgen, c_router, result = create_common_configuration(tgen, c_router,
interface_data, interface_data,
"interface_config", "interface_config",
@ -1303,7 +1416,7 @@ def verify_rib(tgen, addr_type, dut, input_dict, next_hop=None, protocol=None):
if "no_of_ip" in static_route: if "no_of_ip" in static_route:
no_of_ip = static_route["no_of_ip"] no_of_ip = static_route["no_of_ip"]
else: else:
no_of_ip = 0 no_of_ip = 1
# Generating IPs for verification # Generating IPs for verification
ip_list = generate_ips(network, no_of_ip) ip_list = generate_ips(network, no_of_ip)
@ -1321,9 +1434,9 @@ def verify_rib(tgen, addr_type, dut, input_dict, next_hop=None, protocol=None):
found_hops = [rib_r["ip"] for rib_r in found_hops = [rib_r["ip"] for rib_r in
rib_routes_json[st_rt][0][ rib_routes_json[st_rt][0][
"nexthops"]] "nexthops"]]
for nh in next_hop: for nh in found_hops:
nh_found = False nh_found = False
if nh and nh in found_hops: if nh and nh in next_hop:
nh_found = True nh_found = True
else: else:
errormsg = ("Nexthop {} is Missing for {}" errormsg = ("Nexthop {} is Missing for {}"

View File

@ -1,6 +1,6 @@
# Skip pytests example directory # Skip pytests example directory
[pytest] [pytest]
norecursedirs = .git example-test lib docker norecursedirs = .git example-test example-topojson-test lib docker
[topogen] [topogen]
# Default configuration values # Default configuration values