diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 584e6309f..7547e8054 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -7,12 +7,7 @@ on: jobs: cicd: - runs-on: [self-hosted, Linux, Ubuntu, x64] - strategy: - max-parallel: 1 - matrix: - python-version: [python27, python38] - + runs-on: [snappi-ixn-ci-novus100g] steps: - name: Checkout source uses: actions/checkout@v2 @@ -22,7 +17,7 @@ jobs: submodules: recursive - name: Set python path id: path - run: echo "::set-output name=pythonv::/home/otg/${{matrix.python-version}}/bin/python" + run: echo "::set-output name=pythonv::/home/github-runner/pyenv/.env/bin/python" - name: Install dependencies run: | rm -rf .env diff --git a/do.py b/do.py index ef7cc7421..9b7f7116e 100644 --- a/do.py +++ b/do.py @@ -37,25 +37,13 @@ def lint(): def test(): coverage_threshold = 67 - # args = [ - # '--location="https://10.39.71.97:443"', - # ( - # '--ports="10.39.65.230;6;1 10.39.65.230;6;2 10.39.65.230;6;3' - # ' 10.39.65.230;6;4"' - # ), - # '--media="fiber"', - # "tests", - # '-m "not e2e and not l1_manual"', - # '--cov=./snappi_ixnetwork --cov-report term' - # ' --cov-report html:cov_report', - # ] args = [ - '--location="https://otg-novus100g.lbj.is.keysight.com:5000"', + '--location="https://snappi-ixn-ci-novus100g.lbj.is.keysight.com:5000"', ( - '--ports="otg-novus100g.lbj.is.keysight.com;1;1' - " otg-novus100g.lbj.is.keysight.com;1;2" - " otg-novus100g.lbj.is.keysight.com;1;5" - ' otg-novus100g.lbj.is.keysight.com;1;6"' + '--ports="snappi-ixn-ci-novus100g.lbj.is.keysight.com;1;1' + " snappi-ixn-ci-novus100g.lbj.is.keysight.com;1;2" + " snappi-ixn-ci-novus100g.lbj.is.keysight.com;1;5" + ' snappi-ixn-ci-novus100g.lbj.is.keysight.com;1;6"' ), "--ext=ixnetwork", "--speed=speed_100_gbps", diff --git a/readme.md b/readme.md index 2088d1131..0f736f532 100644 --- a/readme.md +++ b/readme.md @@ -1,7 +1,7 @@ # snappi Extension for IxNetwork [![license](https://img.shields.io/badge/license-MIT-green.svg)](https://en.wikipedia.org/wiki/MIT_License) -[![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) +[![Project Status: Active - The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) [![Build](https://github.com/open-traffic-generator/snappi-ixnetwork/workflows/Build/badge.svg)](https://github.com/open-traffic-generator/snappi-ixnetwork/actions) [![pypi](https://img.shields.io/pypi/v/snappi_ixnetwork.svg)](https://pypi.org/project/snappi_ixnetwork) [![python](https://img.shields.io/pypi/pyversions/snappi_ixnetwork.svg)](https://pypi.python.org/pypi/snappi_ixnetwork) diff --git a/setup.py b/setup.py index f042f1747..8b7f548d9 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ import setuptools pkg_name = "snappi_ixnetwork" -version = "0.9.1" +version = "0.11.5" # read long description from readme.md base_dir = os.path.abspath(os.path.dirname(__file__)) @@ -37,7 +37,7 @@ install_requires=["ixnetwork-restpy>=1.0.52"], extras_require={ "testing": [ - "snappi==0.9.1", + "snappi==0.11.5", "snappi_convergence==0.4.1", "pytest", "mock", diff --git a/snappi_ixnetwork/ping.py b/snappi_ixnetwork/ping.py index e312ebe48..5cb1bf7f3 100644 --- a/snappi_ixnetwork/ping.py +++ b/snappi_ixnetwork/ping.py @@ -19,7 +19,7 @@ class Ping(object): def __init__(self, ixnetworkapi): self._api = ixnetworkapi - def results(self, ping_request): + def results(self, req_type, ping_request): responses = [] v4_names = [] for device in self._api._config.devices: @@ -33,9 +33,8 @@ def results(self, ping_request): v6_names.append(ip.name) with Timer(self._api, "Ping requests completed in"): - for endpoint in ping_request.endpoints: + for endpoint in ping_request.requests: response = {} - req_type = endpoint.parent.choice src_name = endpoint.get("src_name") dst_ip = endpoint.get("dst_ip") if req_type == "ipv4": @@ -71,9 +70,9 @@ def results(self, ping_request): for reply in ping_status: if dst_ip in reply["arg3"]: if reply["arg2"]: - response["result"] = "success" + response["result"] = "succeeded" else: - response["result"] = "failure" + response["result"] = "failed" response["src_name"] = src_name response["dst_ip"] = dst_ip responses.append(response) diff --git a/snappi_ixnetwork/protocolmetrics.py b/snappi_ixnetwork/protocolmetrics.py index 4080a8c94..d964f490f 100644 --- a/snappi_ixnetwork/protocolmetrics.py +++ b/snappi_ixnetwork/protocolmetrics.py @@ -387,5 +387,5 @@ def results(self, request): if len(self.columns) > 0: self.columns.append("name") if "name" not in self.columns else None self.columns = list(set(self.columns)) - with Timer(self._api, "Fetching {} Metrics".format(protocol)): - return self._filter_stats(protocol) + #with Timer(self._api, "Fetching {} Metrics".format(protocol)): + return self._filter_stats(protocol) diff --git a/snappi_ixnetwork/snappi_api.py b/snappi_ixnetwork/snappi_api.py index 9a0e49b11..943dc5349 100644 --- a/snappi_ixnetwork/snappi_api.py +++ b/snappi_ixnetwork/snappi_api.py @@ -67,6 +67,8 @@ def __init__(self, **kwargs): self._device_encap = {} self.ixn_objects = None self._config_type = self.config() + self._control_state = self.control_state() + self._control_action = self.control_action() self._protocol_state = self.protocol_state() self._flows_update = self.flows_update() self._transmit_state = self.transmit_state() @@ -160,7 +162,7 @@ def _dict_to_obj(self, source): return o def _request_detail(self): - request_detail = snappi.ResponseWarning() + request_detail = snappi.Warning() errors = self._errors warnings = list() app_errors = self._globals.AppErrors.find() @@ -301,9 +303,62 @@ def _protocols_exists(self): return True else: return False - + + def set_control_state(self, payload): + try: + control_option = payload.choice + control_obj = getattr(payload, control_option) + control_choice = control_obj.get("choice") + request_payload = getattr(control_obj, control_choice) + self._connect() + if control_option == "port": + if control_choice == "capture": + self.capture.set_capture_state(request_payload) + elif control_choice == "link": + self.vport.set_link_state(request_payload) + elif control_option == "protocol": + if control_choice == "all": + self.ngpf.set_protocol_state(request_payload) + elif control_choice == "route": + self.ngpf.set_route_state(request_payload) + elif control_choice == "lacp": + self.ngpf.set_device_state(request_payload) + elif control_option == "traffic": + self.traffic_item.transmit(request_payload) + except Exception as err: + raise SnappiIxnException(err) + return self._request_detail() + + def set_control_action(self, payload): + try: + control_option = payload.choice + control_obj = getattr(payload, control_option) + control_choice = control_obj.get("choice") + choice_obj = getattr(control_obj, control_choice) + if control_choice == "ipv4": + choice = choice_obj.get("choice") + request_payload = getattr(choice_obj, choice) + if choice == "ping": + res = self.control_action_response() + self._connect() + res.response.protocol.ipv4.ping.responses.deserialize(self.ping.results(control_choice, request_payload)) + elif control_choice == "ipv6": + choice = choice_obj.get("choice") + request_payload = getattr(choice_obj, choice) + if choice == "ping": + res = self.control_action_response() + self._connect() + res.response.protocol.ipv6.ping.responses.deserialize(self.ping.results(control_choice, request_payload)) + res.warnings=snappi.Warning() + return res + except Exception as err: + raise SnappiIxnException(err) + def set_protocol_state(self, payload): """Set the transmit state of flows""" + self.add_warnings( + "set_protocol_state api is deprecated, Please use `set_control_state` with `protocol.all` choice instead" + ) try: if isinstance(payload, (type(self._protocol_state), str)) is False: raise TypeError( @@ -320,6 +375,9 @@ def set_protocol_state(self, payload): def set_transmit_state(self, payload): """Set the transmit state of flows""" + self.add_warnings( + "set_transmit_state api is deprecated, Please use `set_control_state` with `traffic` choice instead" + ) try: if isinstance(payload, (type(self._transmit_state), str)) is False: raise TypeError( @@ -334,6 +392,9 @@ def set_transmit_state(self, payload): return self._request_detail() def set_link_state(self, link_state): + self.add_warnings( + "set_link_state api is deprecated, Please use `set_control_state` with `port.link` choice instead" + ) try: if isinstance(link_state, (type(self._link_state), str)) is False: raise TypeError( @@ -350,6 +411,9 @@ def set_link_state(self, link_state): def set_capture_state(self, payload): """Starts capture on all ports that have capture enabled.""" + self.add_warnings( + "set_capture_state api is deprecated, Please use `set_control_state` with `port.capture` choice instead" + ) try: if isinstance(payload, (type(self._capture_state), str)) is False: raise TypeError( @@ -364,6 +428,9 @@ def set_capture_state(self, payload): return self._request_detail() def set_route_state(self, payload): + self.add_warnings( + "set_route_state api is deprecated, Please use `set_control_state` with `protocol.all` choice instead" + ) try: route_state = self.route_state() if isinstance(payload, (type(route_state), str)) is False: @@ -380,6 +447,9 @@ def set_route_state(self, payload): raise SnappiIxnException(err) def set_device_state(self, payload): + self.add_warnings( + "set_device_state api is deprecated, Please use `set_control_state` with `protocol.link` choice instead" + ) try: device_state = self.device_state() if isinstance(payload, (type(device_state), str)) is False: @@ -396,6 +466,9 @@ def set_device_state(self, payload): raise SnappiIxnException(err) def send_ping(self, ping_request, cvg_api=None): + self.add_warnings( + "send_ping api is deprecated, Please use `set_control_action` with `protocol.ipv4.ping` choice instead" + ) try: if cvg_api: if isinstance(ping_request, type(cvg_api.ping_request())): @@ -432,6 +505,7 @@ def send_ping(self, ping_request, cvg_api=None): except Exception as err: raise SnappiIxnException(err) + def get_capture(self, request): """Gets capture file and returns it as a byte stream""" try: @@ -1135,4 +1209,24 @@ def debug(self, message): self.logger.debug(message) def warning(self, message): - logging.warning(message) \ No newline at end of file + logging.warning(message) + + def get_version(self): + try: + import pkg_resources + sdk_version = ( + "snappi-" + + pkg_resources.get_distribution("snappi").version + ) + app_version = ( + "snappi_ixnetwork-" + + pkg_resources.get_distribution( + "snappi_ixnetwork" + ).version + ) + + return {"api_spec_version" : "open-api-models-" + snappi.Api.get_local_version(self).api_spec_version, + "sdk_version" : sdk_version, + "app_version" : app_version} + except: + raise SnappiIxnException("unable to get version") \ No newline at end of file diff --git a/tests/bgp/test_bgpv4_stats.py b/tests/bgp/test_bgpv4_stats.py index 5b3ba3ea7..01db1ba6f 100644 --- a/tests/bgp/test_bgpv4_stats.py +++ b/tests/bgp/test_bgpv4_stats.py @@ -1,7 +1,7 @@ import pytest -@pytest.mark.skip(reason="Revisit CI/CD fail") +#@pytest.mark.skip(reason="Revisit CI/CD fail") def test_bgpv4_stats(api, b2b_raw_config, utils): """ Test for the bgpv4 metrics @@ -68,7 +68,6 @@ def test_bgpv4_stats(api, b2b_raw_config, utils): req.bgpv4.peer_names = [] req.bgpv4.column_names = enums[:3] results = api.get_metrics(req) - assert len(results.bgpv4_metrics) == 2 for bgp_res in results.bgpv4_metrics: for i, enum in enumerate(enums[:3]): diff --git a/tests/bgp_evpn/test_bgp_evpn.py b/tests/bgp_evpn/test_bgp_evpn.py index 9ccdd81cc..b7fadd207 100644 --- a/tests/bgp_evpn/test_bgp_evpn.py +++ b/tests/bgp_evpn/test_bgp_evpn.py @@ -1,180 +1,180 @@ -def test_bgp_evpn(api, utils): - # Creating Ports - config = api.config() - p1 = config.ports.port(name='p1', location=utils.settings.ports[0])[-1] - p2 = config.ports.port(name='p2', location=utils.settings.ports[1])[-1] - - # Create BGP devices on tx & rx - tx_d = config.devices.device(name='tx_d')[-1] - rx_d = config.devices.device(name='rx_d')[-1] - - tx_eth = tx_d.ethernets.ethernet(port_name=p1.name)[-1] - rx_eth = rx_d.ethernets.ethernet(port_name=p2.name)[-1] - - tx_eth.name = 'tx_eth' - tx_eth.mac = '00:11:00:00:00:01' - tx_ip = tx_eth.ipv4_addresses.ipv4(name='tx_ip', - address='20.20.20.2', - gateway='20.20.20.1')[-1] - - rx_eth.name = 'rx_eth' - rx_eth.mac = '00:12:00:00:00:01' - rx_ip = rx_eth.ipv4_addresses.ipv4(name='rx_ip', - address='20.20.20.1', - gateway='20.20.20.2')[-1] - - # tx_bgp - tx_bgp = tx_d.bgp - tx_bgp.router_id = "192.0.0.1" - tx_bgp_iface = (tx_bgp.ipv4_interfaces - .v4interface(ipv4_name=tx_ip.name)[-1]) - tx_bgp_peer = tx_bgp_iface.peers.v4peer(name="tx_eBGP", - peer_address='20.20.20.1', - as_type='ebgp', - as_number=100)[-1] - - # rx_bgp - rx_bgp = rx_d.bgp - rx_bgp.router_id = "193.0.0.1" - rx_bgp_iface = (rx_bgp.ipv4_interfaces - .v4interface(ipv4_name=rx_ip.name)[-1]) - rx_bgp_peer = rx_bgp_iface.peers.v4peer(name="rx_eBGP", - peer_address='20.20.20.2', - as_type='ebgp', - as_number=200)[-1] - - # Create & advertise loopback under bgp in tx and rx - tx_l1 = tx_d.ipv4_loopbacks.add() - tx_l1.name = "tx_loopback1" - tx_l1.eth_name = "tx_eth" - tx_l1.address = "1.1.1.1" - - tx_l1_r = tx_bgp_peer.v4_routes.add(name="tx_l1") - tx_l1_r.addresses.add(address="1.1.1.1", prefix=32) - - rx_l1 = rx_d.ipv4_loopbacks.add() - rx_l1.name = "rx_loopback1" - rx_l1.eth_name = "rx_eth" - rx_l1.address = "2.2.2.2" - - rx_l1_r = rx_bgp_peer.v4_routes.add(name="rx_l1") - rx_l1_r.addresses.add(address="2.2.2.2", prefix=32) - - # Create BGP EVPN on tx - tx_vtep = config.devices.device(name='tx_vtep')[-1] - tx_vtep_bgp = tx_vtep.bgp - tx_vtep_bgp.router_id = "190.0.0.1" - tx_vtep_bgp_iface = (tx_vtep_bgp.ipv4_interfaces - .v4interface(ipv4_name=tx_l1.name)[-1]) - tx_vtep_bgp_peer = tx_vtep_bgp_iface.peers.v4peer(name="bgp1", - peer_address='2.2.2.2', - as_type='ibgp', - as_number=101)[-1] - - # Adding 1 Ethernet Segment per Bgp Peer - tx_vtep_es1 = tx_vtep_bgp_peer.evpn_ethernet_segments.ethernetsegment()[-1] - - # Adding 1 EVI on the Ethernet Segment - tx_es1_evisV4_1 = tx_vtep_es1.evis.evi_vxlan()[-1] - tx_es1_evisV4_1.route_distinguisher.auto_config_rd_ip_addr = True - tx_es1_evisV4_1.route_distinguisher.rd_type = ( - tx_es1_evisV4_1.route_distinguisher.AS_2OCTET) - tx_es1_evisV4_1.route_distinguisher.rd_value = "100:1" - - export_rt = tx_es1_evisV4_1.route_target_export.routetarget()[-1] - import_rt = tx_es1_evisV4_1.route_target_import.routetarget()[-1] - export_rt.rt_type = export_rt.AS_2OCTET - export_rt.rt_value = "100:20" - - import_rt.rt_type = import_rt.AS_2OCTET - import_rt.rt_value = "100:20" - - # Adding 1 Broadcast Domain per EVI - tx_es1_evisV4_1_bd_1 = (tx_es1_evisV4_1 - .broadcast_domains - .broadcastdomain()[-1]) - - # Adding 1 MAC Range Per Broadcast Domain - tx_es1_evisV4_1_bd_1_mac_Pool1 = (tx_es1_evisV4_1_bd_1 - .cmac_ip_range - .cmaciprange(l2vni=20)[-1]) - - tx_es1_evisV4_1_bd_1_mac_Pool1.name = "tx_mac_pool" - tx_es1_evisV4_1_bd_1_mac_Pool1.mac_addresses.address = "10:11:22:33:44:55" - - # Adding 1 IP Range Per Broadcast Domain - tx_es1_evisV4_1_bd_1_mac_Pool1.ipv4_addresses.address = "192.168.0.1" - - # Create BGP EVPN on rx - rx_vtep = config.devices.device(name='rx_vtep')[-1] - rx_vtep_bgp = rx_vtep.bgp - rx_vtep_bgp.router_id = "191.0.0.1" - rx_vtep_bgp_iface = (rx_vtep_bgp.ipv4_interfaces - .v4interface(ipv4_name=rx_l1.name)[-1]) - rx_vtep_bgp_peer = rx_vtep_bgp_iface.peers.v4peer(name="bgp2", - peer_address='1.1.1.1', - as_type='ibgp', - as_number=101)[-1] - - # Adding 1 Ethernet Segment per Bgp Peer - rx_vtep_es1 = rx_vtep_bgp_peer.evpn_ethernet_segments.ethernetsegment()[-1] - - # Adding 1 EVI on the Ethernet Segment - rx_es1_evisV4_1 = rx_vtep_es1.evis.evi_vxlan()[-1] - - rx_es1_evisV4_1.route_distinguisher.rd_type = ( - rx_es1_evisV4_1.route_distinguisher.AS_2OCTET) - rx_es1_evisV4_1.route_distinguisher.rd_value = "1000:1" - - export_rt = rx_es1_evisV4_1.route_target_export.routetarget()[-1] - import_rt = rx_es1_evisV4_1.route_target_import.routetarget()[-1] - export_rt.rt_type = export_rt.AS_2OCTET - export_rt.rt_value = "100:20" - - import_rt.rt_type = import_rt.AS_2OCTET - import_rt.rt_value = "100:20" - - # Adding 1 Broadcast Domain per EVI - rx_es1_evisV4_1_bd_1 = (rx_es1_evisV4_1 - .broadcast_domains - .broadcastdomain()[-1]) - - # Adding 1 MAC Range Per Broadcast Domain - rx_es1_evisV4_1_bd_1_mac_Pool1 = (rx_es1_evisV4_1_bd_1 - .cmac_ip_range - .cmaciprange(l2vni=20)[-1]) - rx_es1_evisV4_1_bd_1_mac_Pool1.name = "rx_mac_pool" - rx_es1_evisV4_1_bd_1_mac_Pool1.mac_addresses.address = "10:11:22:33:44:77" - - # Adding 1 IP Range Per Broadcast Domain - rx_es1_evisV4_1_bd_1_mac_Pool1.ipv4_addresses.address = "192.168.1.2" - - f1 = config.flows.flow(name="f1")[-1] - f1.tx_rx.device.tx_names = [tx_es1_evisV4_1_bd_1_mac_Pool1.name] - f1.tx_rx.device.rx_names = [rx_es1_evisV4_1_bd_1_mac_Pool1.name] - - f1.duration.fixed_packets.packets = 1000 - - f1.size.fixed = 1500 - f1.metrics.enable = True - f1.metrics.loss = True - - utils.start_traffic(api, config) - - utils.wait_for( - lambda: results_ok(api, ["f1"], 1000), - "stats to be as expected", - timeout_seconds=10, - ) - utils.stop_traffic(api, config) - - -def results_ok(api, flow_names, expected): - """ - Returns True if there is no traffic loss else False - """ - request = api.metrics_request() - request.flow.flow_names = flow_names - flow_results = api.get_metrics(request).flow_metrics - flow_rx = sum([f.frames_rx for f in flow_results]) - return flow_rx == expected +def test_bgp_evpn(api, utils): + # Creating Ports + config = api.config() + p1 = config.ports.port(name='p1', location=utils.settings.ports[0])[-1] + p2 = config.ports.port(name='p2', location=utils.settings.ports[1])[-1] + + # Create BGP devices on tx & rx + tx_d = config.devices.device(name='tx_d')[-1] + rx_d = config.devices.device(name='rx_d')[-1] + + tx_eth = tx_d.ethernets.ethernet(port_name=p1.name)[-1] + rx_eth = rx_d.ethernets.ethernet(port_name=p2.name)[-1] + + tx_eth.name = 'tx_eth' + tx_eth.mac = '00:11:00:00:00:01' + tx_ip = tx_eth.ipv4_addresses.ipv4(name='tx_ip', + address='20.20.20.2', + gateway='20.20.20.1')[-1] + + rx_eth.name = 'rx_eth' + rx_eth.mac = '00:12:00:00:00:01' + rx_ip = rx_eth.ipv4_addresses.ipv4(name='rx_ip', + address='20.20.20.1', + gateway='20.20.20.2')[-1] + + # tx_bgp + tx_bgp = tx_d.bgp + tx_bgp.router_id = "192.0.0.1" + tx_bgp_iface = (tx_bgp.ipv4_interfaces + .v4interface(ipv4_name=tx_ip.name)[-1]) + tx_bgp_peer = tx_bgp_iface.peers.v4peer(name="tx_eBGP", + peer_address='20.20.20.1', + as_type='ebgp', + as_number=100)[-1] + + # rx_bgp + rx_bgp = rx_d.bgp + rx_bgp.router_id = "193.0.0.1" + rx_bgp_iface = (rx_bgp.ipv4_interfaces + .v4interface(ipv4_name=rx_ip.name)[-1]) + rx_bgp_peer = rx_bgp_iface.peers.v4peer(name="rx_eBGP", + peer_address='20.20.20.2', + as_type='ebgp', + as_number=200)[-1] + + # Create & advertise loopback under bgp in tx and rx + tx_l1 = tx_d.ipv4_loopbacks.add() + tx_l1.name = "tx_loopback1" + tx_l1.eth_name = "tx_eth" + tx_l1.address = "1.1.1.1" + + tx_l1_r = tx_bgp_peer.v4_routes.add(name="tx_l1") + tx_l1_r.addresses.add(address="1.1.1.1", prefix=32) + + rx_l1 = rx_d.ipv4_loopbacks.add() + rx_l1.name = "rx_loopback1" + rx_l1.eth_name = "rx_eth" + rx_l1.address = "2.2.2.2" + + rx_l1_r = rx_bgp_peer.v4_routes.add(name="rx_l1") + rx_l1_r.addresses.add(address="2.2.2.2", prefix=32) + + # Create BGP EVPN on tx + tx_vtep = config.devices.device(name='tx_vtep')[-1] + tx_vtep_bgp = tx_vtep.bgp + tx_vtep_bgp.router_id = "190.0.0.1" + tx_vtep_bgp_iface = (tx_vtep_bgp.ipv4_interfaces + .v4interface(ipv4_name=tx_l1.name)[-1]) + tx_vtep_bgp_peer = tx_vtep_bgp_iface.peers.v4peer(name="bgp1", + peer_address='2.2.2.2', + as_type='ibgp', + as_number=101)[-1] + + # Adding 1 Ethernet Segment per Bgp Peer + tx_vtep_es1 = tx_vtep_bgp_peer.evpn_ethernet_segments.ethernetsegment()[-1] + + # Adding 1 EVI on the Ethernet Segment + tx_es1_evisV4_1 = tx_vtep_es1.evis.evi_vxlan()[-1] + tx_es1_evisV4_1.route_distinguisher.auto_config_rd_ip_addr = True + tx_es1_evisV4_1.route_distinguisher.rd_type = ( + tx_es1_evisV4_1.route_distinguisher.AS_2OCTET) + tx_es1_evisV4_1.route_distinguisher.rd_value = "100:1" + + export_rt = tx_es1_evisV4_1.route_target_export.routetarget()[-1] + import_rt = tx_es1_evisV4_1.route_target_import.routetarget()[-1] + export_rt.rt_type = export_rt.AS_2OCTET + export_rt.rt_value = "100:20" + + import_rt.rt_type = import_rt.AS_2OCTET + import_rt.rt_value = "100:20" + + # Adding 1 Broadcast Domain per EVI + tx_es1_evisV4_1_bd_1 = (tx_es1_evisV4_1 + .broadcast_domains + .broadcastdomain()[-1]) + + # Adding 1 MAC Range Per Broadcast Domain + tx_es1_evisV4_1_bd_1_mac_Pool1 = (tx_es1_evisV4_1_bd_1 + .cmac_ip_range + .cmaciprange(l2vni=20)[-1]) + + tx_es1_evisV4_1_bd_1_mac_Pool1.name = "tx_mac_pool" + tx_es1_evisV4_1_bd_1_mac_Pool1.mac_addresses.address = "10:11:22:33:44:55" + + # Adding 1 IP Range Per Broadcast Domain + tx_es1_evisV4_1_bd_1_mac_Pool1.ipv4_addresses.address = "192.168.0.1" + + # Create BGP EVPN on rx + rx_vtep = config.devices.device(name='rx_vtep')[-1] + rx_vtep_bgp = rx_vtep.bgp + rx_vtep_bgp.router_id = "191.0.0.1" + rx_vtep_bgp_iface = (rx_vtep_bgp.ipv4_interfaces + .v4interface(ipv4_name=rx_l1.name)[-1]) + rx_vtep_bgp_peer = rx_vtep_bgp_iface.peers.v4peer(name="bgp2", + peer_address='1.1.1.1', + as_type='ibgp', + as_number=101)[-1] + + # Adding 1 Ethernet Segment per Bgp Peer + rx_vtep_es1 = rx_vtep_bgp_peer.evpn_ethernet_segments.ethernetsegment()[-1] + + # Adding 1 EVI on the Ethernet Segment + rx_es1_evisV4_1 = rx_vtep_es1.evis.evi_vxlan()[-1] + + rx_es1_evisV4_1.route_distinguisher.rd_type = ( + rx_es1_evisV4_1.route_distinguisher.AS_2OCTET) + rx_es1_evisV4_1.route_distinguisher.rd_value = "1000:1" + + export_rt = rx_es1_evisV4_1.route_target_export.routetarget()[-1] + import_rt = rx_es1_evisV4_1.route_target_import.routetarget()[-1] + export_rt.rt_type = export_rt.AS_2OCTET + export_rt.rt_value = "100:20" + + import_rt.rt_type = import_rt.AS_2OCTET + import_rt.rt_value = "100:20" + + # Adding 1 Broadcast Domain per EVI + rx_es1_evisV4_1_bd_1 = (rx_es1_evisV4_1 + .broadcast_domains + .broadcastdomain()[-1]) + + # Adding 1 MAC Range Per Broadcast Domain + rx_es1_evisV4_1_bd_1_mac_Pool1 = (rx_es1_evisV4_1_bd_1 + .cmac_ip_range + .cmaciprange(l2vni=20)[-1]) + rx_es1_evisV4_1_bd_1_mac_Pool1.name = "rx_mac_pool" + rx_es1_evisV4_1_bd_1_mac_Pool1.mac_addresses.address = "10:11:22:33:44:77" + + # Adding 1 IP Range Per Broadcast Domain + rx_es1_evisV4_1_bd_1_mac_Pool1.ipv4_addresses.address = "192.168.1.2" + + f1 = config.flows.flow(name="f1")[-1] + f1.tx_rx.device.tx_names = [tx_es1_evisV4_1_bd_1_mac_Pool1.name] + f1.tx_rx.device.rx_names = [rx_es1_evisV4_1_bd_1_mac_Pool1.name] + + f1.duration.fixed_packets.packets = 1000 + + f1.size.fixed = 1500 + f1.metrics.enable = True + f1.metrics.loss = True + + utils.start_traffic(api, config) + + utils.wait_for( + lambda: results_ok(api, ["f1"], 1000), + "stats to be as expected", + timeout_seconds=10, + ) + utils.stop_traffic(api, config) + + +def results_ok(api, flow_names, expected): + """ + Returns True if there is no traffic loss else False + """ + request = api.metrics_request() + request.flow.flow_names = flow_names + flow_results = api.get_metrics(request).flow_metrics + flow_rx = sum([f.frames_rx for f in flow_results]) + return flow_rx == expected diff --git a/tests/bgp_evpn/test_bgp_evpn_attribute_validation.py b/tests/bgp_evpn/test_bgp_evpn_attribute_validation.py index dd051fbe9..5ddb889c2 100644 --- a/tests/bgp_evpn/test_bgp_evpn_attribute_validation.py +++ b/tests/bgp_evpn/test_bgp_evpn_attribute_validation.py @@ -1,428 +1,428 @@ -import pytest - - -def test_bgp_evpn_validation(api, utils): - "Validate BGP EVPN Attributes against RestPy" - - BGPV4_EVPN_ETH_SEGMENT = { - "DfElectionTimer": 10, - "EsiValue": "1000000000000000", - "EsiLabel": 8, - "EnableSingleActive": "true", - "MultiExitDiscriminator": 5, - "EnableMultiExitDiscriminator": "true", - "Origin": "egp", - "EnableOrigin": "true", - "EnableCommunity": "true", - "EnableExtendedCommunity": "true", - "EnableAsPathSegments": "true", - "AsSetMode": "includelocalasasasset" - } - - BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST = { - "Type": "manual", - "AsNumber": "8", - "LastTwoOctets": "8", - } - - BGPV4_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST = { - "Type": "opaque", - "SubType": "color", - "ColorValue": "200" - } - - BGPV4_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST = { - "SegmentType": "asseqconfederation", - } - - BGPV4_EVPN_VXLAN = { - "AdRouteLabel": 10, - "UpstreamDownstreamAssignedMplsLabel": 20, - "RdASNumber": 1000, - "RdEvi": 10, - "MultiExitDiscriminator": 99 - } - - BGPV4_EVPN_VXLAN_EXPORT_TARGET = { - "TargetAs4Number": "100", - "TargetAssignedNumber": "20" - } - - BGPV4_EVPN_VXLAN_IMPORT_TARGET = { - "TargetAs4Number": "200", - "TargetAssignedNumber": "30" - } - - BGPV4_EVPN_VXLAN_L3_EXPORT_TARGET = { - "TargetAs4Number": "300", - "TargetAssignedNumber": "50" - } - - BGPV4_EVPN_VXLAN_L3_IMPORT_TARGET = { - "TargetAs4Number": "400", - "TargetAssignedNumber": "60" - } - - BROADCAST_DOMAIN = { - "EthernetTagId": "5", - "EnableVlanAwareService": "true" - } - - MAC_ADDRESS = { - "Mac": "10:11:22:33:44:55", - "PrefixLength": "48", - "NumberOfAddressesAsy": "1" - } - - IP_ADDRESS = { - "NetworkAddress": "2.2.2.2", - "PrefixLength": "24", - "NumberOfAddressesAsy": "1" - } - - IPV6_ADDRESS = { - "NetworkAddress": "2000:0:2:1::1", - "PrefixLength": "64", - "NumberOfAddressesAsy": "1" - } - - CMAC_PROPERTIES = { - "FirstLabelStart": "16", - "SecondLabelStart": "20", - "MultiExitDiscriminator": "37", - "IncludeDefaultGatewayExtendedCommunity": "true" - } - - # Creating Ports - config = api.config() - p1 = config.ports.port(name='p1', location=utils.settings.ports[0])[-1] - # Create BGP devices on tx - tx_d = config.devices.device(name='tx_d')[-1] - tx_eth = tx_d.ethernets.ethernet(port_name=p1.name)[-1] - tx_eth.name = 'tx_eth' - tx_eth.mac = '00:11:00:00:00:01' - tx_ip = tx_eth.ipv4_addresses.ipv4(name='tx_ip', - address='20.20.20.2', - gateway='20.20.20.1')[-1] - - # tx_bgp - tx_bgp = tx_d.bgp - tx_bgp.router_id = "192.0.0.1" - tx_bgp_iface = (tx_bgp.ipv4_interfaces - .v4interface(ipv4_name=tx_ip.name)[-1]) - tx_bgp_peer = tx_bgp_iface.peers.v4peer(name="tx_eBGP", - peer_address='20.20.20.1', - as_type='ebgp', - as_number=100)[-1] - - # Create & advertise loopback under bgp in tx and rx - tx_l1 = tx_d.ipv4_loopbacks.add() - tx_l1.name = "tx_loopback1" - tx_l1.eth_name = "tx_eth" - tx_l1.address = "1.1.1.1" - tx_l1_r = tx_bgp_peer.v4_routes.add(name="tx_l1") - tx_l1_r.addresses.add(address="1.1.1.1", prefix=32) - - # Create BGP EVPN on tx - tx_vtep = config.devices.device(name='tx_vtep')[-1] - tx_vtep_bgp = tx_vtep.bgp - tx_vtep_bgp.router_id = "190.0.0.1" - tx_vtep_bgp_iface = (tx_vtep_bgp.ipv4_interfaces - .v4interface(ipv4_name=tx_l1.name)[-1]) - tx_vtep_bgp_peer = tx_vtep_bgp_iface.peers.v4peer(name="bgp1", - peer_address='2.2.2.2', - as_type='ibgp', - as_number=101)[-1] - - tx_eth_seg = tx_vtep_bgp_peer.evpn_ethernet_segments.ethernetsegment()[-1] - tx_eth_seg.df_election.election_timer = ( - BGPV4_EVPN_ETH_SEGMENT["DfElectionTimer"]) - tx_eth_seg.esi = BGPV4_EVPN_ETH_SEGMENT["EsiValue"] - tx_eth_seg.esi_label = BGPV4_EVPN_ETH_SEGMENT["EsiLabel"] - tx_eth_seg.active_mode = tx_eth_seg.SINGLE_ACTIVE - tx_eth_seg.advanced.origin = tx_eth_seg.advanced.EGP - tx_eth_seg.advanced.multi_exit_discriminator = ( - BGPV4_EVPN_ETH_SEGMENT["MultiExitDiscriminator"]) - tx_eth_seg_community = tx_eth_seg.communities.add() - tx_eth_seg_community.type = tx_eth_seg_community.MANUAL_AS_NUMBER - tx_eth_seg_community.as_number = int( - BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["AsNumber"]) - tx_eth_seg_community.as_custom = int( - BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["LastTwoOctets"]) - tx_eth_seg_ext_community = tx_eth_seg.ext_communities.add() - tx_eth_seg_ext_community.type = "opaque" - tx_eth_seg_ext_community.subtype = "color" - tx_eth_seg_ext_community.value = "0000000000C8" - tx_eth_seg.as_path.as_set_mode = "include_as_set" - tx_eth_seg.as_path.segments.add("as_confed_seq", [2, 3]) - - # Adding Tx EVI on the Ethernet Segment - tx_evi_vxlan = tx_eth_seg.evis.evi_vxlan()[-1] - tx_evi_vxlan.route_distinguisher.rd_type = ( - tx_evi_vxlan.route_distinguisher.AS_2OCTET) - tx_evi_vxlan.route_distinguisher.rd_value = ( - str(BGPV4_EVPN_VXLAN["RdASNumber"]) + ":" + str( - BGPV4_EVPN_VXLAN["RdEvi"])) - tx_evi_vxlan.ad_label = BGPV4_EVPN_VXLAN["AdRouteLabel"] - tx_evi_vxlan.pmsi_label = ( - BGPV4_EVPN_VXLAN["UpstreamDownstreamAssignedMplsLabel"]) - - export_rt = tx_evi_vxlan.route_target_export.routetarget()[-1] - import_rt = tx_evi_vxlan.route_target_import.routetarget()[-1] - export_rt.rt_type = export_rt.AS_4OCTET - export_rt.rt_value = ( - BGPV4_EVPN_VXLAN_EXPORT_TARGET[ - "TargetAs4Number"] + ":" + BGPV4_EVPN_VXLAN_EXPORT_TARGET[ - "TargetAssignedNumber"]) - import_rt.rt_type = import_rt.AS_4OCTET - import_rt.rt_value = ( - BGPV4_EVPN_VXLAN_IMPORT_TARGET[ - "TargetAs4Number"] + ":" + BGPV4_EVPN_VXLAN_IMPORT_TARGET[ - "TargetAssignedNumber"]) - - l3_export_rt = tx_evi_vxlan.l3_route_target_export.routetarget()[-1] - l3_import_rt = tx_evi_vxlan.l3_route_target_import.routetarget()[-1] - l3_export_rt.rt_type = l3_export_rt.AS_4OCTET - l3_export_rt.rt_value = ( - BGPV4_EVPN_VXLAN_L3_EXPORT_TARGET[ - "TargetAs4Number"] + ":" + BGPV4_EVPN_VXLAN_L3_EXPORT_TARGET[ - "TargetAssignedNumber"]) - l3_import_rt.rt_type = l3_import_rt.AS_4OCTET - l3_import_rt.rt_value = ( - BGPV4_EVPN_VXLAN_L3_IMPORT_TARGET[ - "TargetAs4Number"] + ":" + BGPV4_EVPN_VXLAN_L3_IMPORT_TARGET[ - "TargetAssignedNumber"]) - - tx_evi_vxlan.advanced.origin = tx_evi_vxlan.advanced.EGP - tx_evi_vxlan.advanced.multi_exit_discriminator = ( - BGPV4_EVPN_VXLAN["MultiExitDiscriminator"]) - tx_evi_vxlan_comm = tx_evi_vxlan.communities.add() - tx_evi_vxlan_comm.type = tx_evi_vxlan_comm.MANUAL_AS_NUMBER - tx_evi_vxlan_comm.as_number = int( - BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["AsNumber"]) - tx_evi_vxlan_comm.as_custom = int( - BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["LastTwoOctets"]) - tx_evi_vxlan_ext_comm = tx_evi_vxlan.ext_communities.add() - tx_evi_vxlan_ext_comm.type = "opaque" - tx_evi_vxlan_ext_comm.subtype = "color" - tx_evi_vxlan_ext_comm.value = "0000000000C8" - tx_evi_vxlan.as_path.segments.add("as_confed_seq", [9, 10]) - - # Adding tx Broadcast Domain per EVI and MAC range - tx_evpn_brodcast_domain = ( - tx_evi_vxlan.broadcast_domains.broadcastdomain()[-1]) - tx_evpn_brodcast_domain.ethernet_tag_id = int( - BROADCAST_DOMAIN["EthernetTagId"]) - tx_evpn_brodcast_domain.vlan_aware_service = True - tx_broadcast_macrange = ( - tx_evpn_brodcast_domain.cmac_ip_range.cmaciprange( - l2vni=16, l3vni=20, name="tx_cmaciprange", - include_default_gateway=True)[-1]) - tx_broadcast_macrange.mac_addresses.address = MAC_ADDRESS["Mac"] - tx_broadcast_macrange.ipv4_addresses.address = IP_ADDRESS["NetworkAddress"] - tx_broadcast_macrange.ipv6_addresses.address = ( - IPV6_ADDRESS["NetworkAddress"]) - - tx_broadcast_macrange.advanced.multi_exit_discriminator = int( - CMAC_PROPERTIES["MultiExitDiscriminator"]) - - cmac_comm = tx_broadcast_macrange.communities.add() - cmac_comm.type = cmac_comm.MANUAL_AS_NUMBER - cmac_comm.as_number = int( - BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["AsNumber"]) - cmac_comm.as_custom = int( - BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["LastTwoOctets"]) - cmac_ext_comm = tx_broadcast_macrange.ext_communities.add() - cmac_ext_comm.type = "opaque" - cmac_ext_comm.subtype = "color" - cmac_ext_comm.value = "0000000000C8" - tx_broadcast_macrange.as_path.segments.add("as_confed_seq", [9, 10]) - - api.set_config(config) - - validate_config(api, - BGPV4_EVPN_ETH_SEGMENT, - BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST, - BGPV4_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST, - BGPV4_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST, - BGPV4_EVPN_VXLAN, - BGPV4_EVPN_VXLAN_EXPORT_TARGET, - BGPV4_EVPN_VXLAN_IMPORT_TARGET, - BGPV4_EVPN_VXLAN_L3_EXPORT_TARGET, - BGPV4_EVPN_VXLAN_L3_IMPORT_TARGET, - BROADCAST_DOMAIN, - MAC_ADDRESS, - IP_ADDRESS, - IPV6_ADDRESS, - CMAC_PROPERTIES) - - -def validate_config(api, - BGPV4_EVPN_ETH_SEGMENT, - BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST, - BGPV4_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST, - BGPV4_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST, - BGPV4_EVPN_VXLAN, - BGPV4_EVPN_VXLAN_EXPORT_TARGET, - BGPV4_EVPN_VXLAN_IMPORT_TARGET, - BGPV4_EVPN_VXLAN_L3_EXPORT_TARGET, - BGPV4_EVPN_VXLAN_L3_IMPORT_TARGET, - BROADCAST_DOMAIN, - MAC_ADDRESS, - IP_ADDRESS, - IPV6_ADDRESS, - CMAC_PROPERTIES): - ixn = api._ixnetwork - bgps = ( - ixn.Topology.find().DeviceGroup.find() - .DeviceGroup.find().Ipv4Loopback.find().BgpIpv4Peer.find()) - for bgp in bgps: - assert bgp.EthernetSegmentsCountV4 == 1 - assert bgp.BgpEthernetSegmentV4.EvisCount == 1 - evis = bgp.BgpIPv4EvpnVXLAN.find() - assert evis.Multiplier == 1 - - bgp_eth_seg = bgps[0].BgpEthernetSegmentV4 - for attr in BGPV4_EVPN_ETH_SEGMENT: - if attr in ["DfElectionTimer", "EsiLabel", - "MultiExitDiscriminator"]: - assert BGPV4_EVPN_ETH_SEGMENT[attr] == int( - (getattr(bgp_eth_seg, attr).Values)[0] - ) - else: - assert BGPV4_EVPN_ETH_SEGMENT[attr] == ( - (getattr(bgp_eth_seg, attr).Values)[0] - ) - - bgp_eth_seg_comm_list = ( - bgps[0].BgpEthernetSegmentV4.BgpCommunitiesList.find()) - for attr in BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST: - assert BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST[attr] == ( - (getattr(bgp_eth_seg_comm_list, attr).Values)[0] - ) - - bgp_eth_seg_ext_comm_list = ( - bgps[0].BgpEthernetSegmentV4.BgpExtendedCommunitiesList.find()) - for attr in BGPV4_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST: - assert BGPV4_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST[attr] == ( - (getattr(bgp_eth_seg_ext_comm_list, attr).Values)[0] - ) - - bgp_eth_seg_aspath_segments_list = ( - bgps[0].BgpEthernetSegmentV4.BgpAsPathSegmentList.find()) - for attr in BGPV4_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST: - assert BGPV4_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST[attr] == ( - (getattr(bgp_eth_seg_aspath_segments_list, attr).Values)[0] - ) - - bgp_evpn_vxlan = bgps[0].BgpIPv4EvpnVXLAN.find() - for attr in BGPV4_EVPN_VXLAN: - assert BGPV4_EVPN_VXLAN[attr] == int( - (getattr(bgp_evpn_vxlan, attr).Values)[0] - ) - - bgp_evpn_vxlan_export_target = ( - bgp_evpn_vxlan.BgpExportRouteTargetList.find()) - for attr in BGPV4_EVPN_VXLAN_EXPORT_TARGET: - assert BGPV4_EVPN_VXLAN_EXPORT_TARGET[attr] == ( - (getattr(bgp_evpn_vxlan_export_target, attr).Values)[0] - ) - - bgp_evpn_vxlan_import_target = ( - bgp_evpn_vxlan.BgpImportRouteTargetList.find()) - for attr in BGPV4_EVPN_VXLAN_IMPORT_TARGET: - assert BGPV4_EVPN_VXLAN_IMPORT_TARGET[attr] == ( - (getattr(bgp_evpn_vxlan_import_target, attr).Values)[0] - ) - - bgp_evpn_vxlan_l3_export_target = ( - bgp_evpn_vxlan.BgpL3VNIExportRouteTargetList.find()) - for attr in BGPV4_EVPN_VXLAN_L3_EXPORT_TARGET: - assert BGPV4_EVPN_VXLAN_L3_EXPORT_TARGET[attr] == ( - (getattr(bgp_evpn_vxlan_l3_export_target, attr).Values)[0] - ) - - bgp_evpn_vxlan_l3_import_target = ( - bgp_evpn_vxlan.BgpL3VNIImportRouteTargetList.find()) - for attr in BGPV4_EVPN_VXLAN_L3_IMPORT_TARGET: - assert BGPV4_EVPN_VXLAN_L3_IMPORT_TARGET[attr] == ( - (getattr(bgp_evpn_vxlan_l3_import_target, attr).Values)[0] - ) - - bgp_eth_seg_vxlan_comm_list = ( - bgps[0].BgpIPv4EvpnVXLAN.find().BgpCommunitiesList.find()) - for attr in BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST: - assert BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST[attr] == ( - (getattr(bgp_eth_seg_vxlan_comm_list, attr).Values)[0] - ) - - bgp_eth_seg_vxlan_ext_comm_list = ( - bgps[0].BgpIPv4EvpnVXLAN.find().BgpExtendedCommunitiesList.find()) - for attr in BGPV4_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST: - assert BGPV4_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST[attr] == ( - (getattr(bgp_eth_seg_vxlan_ext_comm_list, attr).Values)[0] - ) - - bgp_eth_seg_vxlan_aspath_segments_list = ( - bgps[0].BgpIPv4EvpnVXLAN.find().BgpAsPathSegmentList.find()) - for attr in BGPV4_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST: - assert BGPV4_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST[attr] == ( - (getattr(bgp_eth_seg_vxlan_aspath_segments_list, attr).Values)[0] - ) - - bgp_eth_seg_vxlan_broadcast_domain = ( - bgps[0].BgpIPv4EvpnVXLAN.find().BroadcastDomainV4) - for attr in BROADCAST_DOMAIN: - assert BROADCAST_DOMAIN[attr] == ( - (getattr(bgp_eth_seg_vxlan_broadcast_domain, attr).Values)[0] - ) - - mac = (ixn.Topology.find().DeviceGroup.find() - .DeviceGroup.find().NetworkGroup.find().MacPools.find()) - for attr in MAC_ADDRESS: - assert MAC_ADDRESS[attr] == ( - (getattr(mac, attr).Values)[0] - ) - - ipv4 = (mac.Ipv4PrefixPools.find()) - for attr in IP_ADDRESS: - assert IP_ADDRESS[attr] == ( - (getattr(ipv4, attr).Values)[0] - ) - - ipv6 = (mac.Ipv6PrefixPools.find()) - for attr in IPV6_ADDRESS: - assert IPV6_ADDRESS[attr] == ( - (getattr(ipv6, attr).Values)[0] - ) - - cmac = (mac.CMacProperties.find()) - for attr in CMAC_PROPERTIES: - assert CMAC_PROPERTIES[attr] == ( - (getattr(cmac, attr).Values)[0] - ) - - cmac_comm_list = ( - cmac.BgpCommunitiesList.find()) - for attr in BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST: - assert BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST[attr] == ( - (getattr(cmac_comm_list, attr).Values)[0] - ) - - cmac_ext_comm_list = ( - cmac.BgpExtendedCommunitiesList.find()) - for attr in BGPV4_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST: - assert BGPV4_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST[attr] == ( - (getattr(cmac_ext_comm_list, attr).Values)[0] - ) - - cmac_aspath_segments_list = ( - cmac.BgpAsPathSegmentList.find()) - for attr in BGPV4_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST: - assert BGPV4_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST[attr] == ( - (getattr(cmac_aspath_segments_list, attr).Values)[0] - ) - - -if __name__ == "__main__": - pytest.main(["-s", __file__]) +import pytest + + +def test_bgp_evpn_validation(api, utils): + "Validate BGP EVPN Attributes against RestPy" + + BGPV4_EVPN_ETH_SEGMENT = { + "DfElectionTimer": 10, + "EsiValue": "1000000000000000", + "EsiLabel": 8, + "EnableSingleActive": "true", + "MultiExitDiscriminator": 5, + "EnableMultiExitDiscriminator": "true", + "Origin": "egp", + "EnableOrigin": "true", + "EnableCommunity": "true", + "EnableExtendedCommunity": "true", + "EnableAsPathSegments": "true", + "AsSetMode": "includelocalasasasset" + } + + BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST = { + "Type": "manual", + "AsNumber": "8", + "LastTwoOctets": "8", + } + + BGPV4_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST = { + "Type": "opaque", + "SubType": "color", + "ColorValue": "200" + } + + BGPV4_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST = { + "SegmentType": "asseqconfederation", + } + + BGPV4_EVPN_VXLAN = { + "AdRouteLabel": 10, + "UpstreamDownstreamAssignedMplsLabel": 20, + "RdASNumber": 1000, + "RdEvi": 10, + "MultiExitDiscriminator": 99 + } + + BGPV4_EVPN_VXLAN_EXPORT_TARGET = { + "TargetAs4Number": "100", + "TargetAssignedNumber": "20" + } + + BGPV4_EVPN_VXLAN_IMPORT_TARGET = { + "TargetAs4Number": "200", + "TargetAssignedNumber": "30" + } + + BGPV4_EVPN_VXLAN_L3_EXPORT_TARGET = { + "TargetAs4Number": "300", + "TargetAssignedNumber": "50" + } + + BGPV4_EVPN_VXLAN_L3_IMPORT_TARGET = { + "TargetAs4Number": "400", + "TargetAssignedNumber": "60" + } + + BROADCAST_DOMAIN = { + "EthernetTagId": "5", + "EnableVlanAwareService": "true" + } + + MAC_ADDRESS = { + "Mac": "10:11:22:33:44:55", + "PrefixLength": "48", + "NumberOfAddressesAsy": "1" + } + + IP_ADDRESS = { + "NetworkAddress": "2.2.2.2", + "PrefixLength": "24", + "NumberOfAddressesAsy": "1" + } + + IPV6_ADDRESS = { + "NetworkAddress": "2000:0:2:1::1", + "PrefixLength": "64", + "NumberOfAddressesAsy": "1" + } + + CMAC_PROPERTIES = { + "FirstLabelStart": "16", + "SecondLabelStart": "20", + "MultiExitDiscriminator": "37", + "IncludeDefaultGatewayExtendedCommunity": "true" + } + + # Creating Ports + config = api.config() + p1 = config.ports.port(name='p1', location=utils.settings.ports[0])[-1] + # Create BGP devices on tx + tx_d = config.devices.device(name='tx_d')[-1] + tx_eth = tx_d.ethernets.ethernet(port_name=p1.name)[-1] + tx_eth.name = 'tx_eth' + tx_eth.mac = '00:11:00:00:00:01' + tx_ip = tx_eth.ipv4_addresses.ipv4(name='tx_ip', + address='20.20.20.2', + gateway='20.20.20.1')[-1] + + # tx_bgp + tx_bgp = tx_d.bgp + tx_bgp.router_id = "192.0.0.1" + tx_bgp_iface = (tx_bgp.ipv4_interfaces + .v4interface(ipv4_name=tx_ip.name)[-1]) + tx_bgp_peer = tx_bgp_iface.peers.v4peer(name="tx_eBGP", + peer_address='20.20.20.1', + as_type='ebgp', + as_number=100)[-1] + + # Create & advertise loopback under bgp in tx and rx + tx_l1 = tx_d.ipv4_loopbacks.add() + tx_l1.name = "tx_loopback1" + tx_l1.eth_name = "tx_eth" + tx_l1.address = "1.1.1.1" + tx_l1_r = tx_bgp_peer.v4_routes.add(name="tx_l1") + tx_l1_r.addresses.add(address="1.1.1.1", prefix=32) + + # Create BGP EVPN on tx + tx_vtep = config.devices.device(name='tx_vtep')[-1] + tx_vtep_bgp = tx_vtep.bgp + tx_vtep_bgp.router_id = "190.0.0.1" + tx_vtep_bgp_iface = (tx_vtep_bgp.ipv4_interfaces + .v4interface(ipv4_name=tx_l1.name)[-1]) + tx_vtep_bgp_peer = tx_vtep_bgp_iface.peers.v4peer(name="bgp1", + peer_address='2.2.2.2', + as_type='ibgp', + as_number=101)[-1] + + tx_eth_seg = tx_vtep_bgp_peer.evpn_ethernet_segments.ethernetsegment()[-1] + tx_eth_seg.df_election.election_timer = ( + BGPV4_EVPN_ETH_SEGMENT["DfElectionTimer"]) + tx_eth_seg.esi = BGPV4_EVPN_ETH_SEGMENT["EsiValue"] + tx_eth_seg.esi_label = BGPV4_EVPN_ETH_SEGMENT["EsiLabel"] + tx_eth_seg.active_mode = tx_eth_seg.SINGLE_ACTIVE + tx_eth_seg.advanced.origin = tx_eth_seg.advanced.EGP + tx_eth_seg.advanced.multi_exit_discriminator = ( + BGPV4_EVPN_ETH_SEGMENT["MultiExitDiscriminator"]) + tx_eth_seg_community = tx_eth_seg.communities.add() + tx_eth_seg_community.type = tx_eth_seg_community.MANUAL_AS_NUMBER + tx_eth_seg_community.as_number = int( + BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["AsNumber"]) + tx_eth_seg_community.as_custom = int( + BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["LastTwoOctets"]) + tx_eth_seg_ext_community = tx_eth_seg.ext_communities.add() + tx_eth_seg_ext_community.type = "opaque" + tx_eth_seg_ext_community.subtype = "color" + tx_eth_seg_ext_community.value = "0000000000C8" + tx_eth_seg.as_path.as_set_mode = "include_as_set" + tx_eth_seg.as_path.segments.add("as_confed_seq", [2, 3]) + + # Adding Tx EVI on the Ethernet Segment + tx_evi_vxlan = tx_eth_seg.evis.evi_vxlan()[-1] + tx_evi_vxlan.route_distinguisher.rd_type = ( + tx_evi_vxlan.route_distinguisher.AS_2OCTET) + tx_evi_vxlan.route_distinguisher.rd_value = ( + str(BGPV4_EVPN_VXLAN["RdASNumber"]) + ":" + str( + BGPV4_EVPN_VXLAN["RdEvi"])) + tx_evi_vxlan.ad_label = BGPV4_EVPN_VXLAN["AdRouteLabel"] + tx_evi_vxlan.pmsi_label = ( + BGPV4_EVPN_VXLAN["UpstreamDownstreamAssignedMplsLabel"]) + + export_rt = tx_evi_vxlan.route_target_export.routetarget()[-1] + import_rt = tx_evi_vxlan.route_target_import.routetarget()[-1] + export_rt.rt_type = export_rt.AS_4OCTET + export_rt.rt_value = ( + BGPV4_EVPN_VXLAN_EXPORT_TARGET[ + "TargetAs4Number"] + ":" + BGPV4_EVPN_VXLAN_EXPORT_TARGET[ + "TargetAssignedNumber"]) + import_rt.rt_type = import_rt.AS_4OCTET + import_rt.rt_value = ( + BGPV4_EVPN_VXLAN_IMPORT_TARGET[ + "TargetAs4Number"] + ":" + BGPV4_EVPN_VXLAN_IMPORT_TARGET[ + "TargetAssignedNumber"]) + + l3_export_rt = tx_evi_vxlan.l3_route_target_export.routetarget()[-1] + l3_import_rt = tx_evi_vxlan.l3_route_target_import.routetarget()[-1] + l3_export_rt.rt_type = l3_export_rt.AS_4OCTET + l3_export_rt.rt_value = ( + BGPV4_EVPN_VXLAN_L3_EXPORT_TARGET[ + "TargetAs4Number"] + ":" + BGPV4_EVPN_VXLAN_L3_EXPORT_TARGET[ + "TargetAssignedNumber"]) + l3_import_rt.rt_type = l3_import_rt.AS_4OCTET + l3_import_rt.rt_value = ( + BGPV4_EVPN_VXLAN_L3_IMPORT_TARGET[ + "TargetAs4Number"] + ":" + BGPV4_EVPN_VXLAN_L3_IMPORT_TARGET[ + "TargetAssignedNumber"]) + + tx_evi_vxlan.advanced.origin = tx_evi_vxlan.advanced.EGP + tx_evi_vxlan.advanced.multi_exit_discriminator = ( + BGPV4_EVPN_VXLAN["MultiExitDiscriminator"]) + tx_evi_vxlan_comm = tx_evi_vxlan.communities.add() + tx_evi_vxlan_comm.type = tx_evi_vxlan_comm.MANUAL_AS_NUMBER + tx_evi_vxlan_comm.as_number = int( + BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["AsNumber"]) + tx_evi_vxlan_comm.as_custom = int( + BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["LastTwoOctets"]) + tx_evi_vxlan_ext_comm = tx_evi_vxlan.ext_communities.add() + tx_evi_vxlan_ext_comm.type = "opaque" + tx_evi_vxlan_ext_comm.subtype = "color" + tx_evi_vxlan_ext_comm.value = "0000000000C8" + tx_evi_vxlan.as_path.segments.add("as_confed_seq", [9, 10]) + + # Adding tx Broadcast Domain per EVI and MAC range + tx_evpn_brodcast_domain = ( + tx_evi_vxlan.broadcast_domains.broadcastdomain()[-1]) + tx_evpn_brodcast_domain.ethernet_tag_id = int( + BROADCAST_DOMAIN["EthernetTagId"]) + tx_evpn_brodcast_domain.vlan_aware_service = True + tx_broadcast_macrange = ( + tx_evpn_brodcast_domain.cmac_ip_range.cmaciprange( + l2vni=16, l3vni=20, name="tx_cmaciprange", + include_default_gateway=True)[-1]) + tx_broadcast_macrange.mac_addresses.address = MAC_ADDRESS["Mac"] + tx_broadcast_macrange.ipv4_addresses.address = IP_ADDRESS["NetworkAddress"] + tx_broadcast_macrange.ipv6_addresses.address = ( + IPV6_ADDRESS["NetworkAddress"]) + + tx_broadcast_macrange.advanced.multi_exit_discriminator = int( + CMAC_PROPERTIES["MultiExitDiscriminator"]) + + cmac_comm = tx_broadcast_macrange.communities.add() + cmac_comm.type = cmac_comm.MANUAL_AS_NUMBER + cmac_comm.as_number = int( + BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["AsNumber"]) + cmac_comm.as_custom = int( + BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["LastTwoOctets"]) + cmac_ext_comm = tx_broadcast_macrange.ext_communities.add() + cmac_ext_comm.type = "opaque" + cmac_ext_comm.subtype = "color" + cmac_ext_comm.value = "0000000000C8" + tx_broadcast_macrange.as_path.segments.add("as_confed_seq", [9, 10]) + + api.set_config(config) + + validate_config(api, + BGPV4_EVPN_ETH_SEGMENT, + BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST, + BGPV4_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST, + BGPV4_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST, + BGPV4_EVPN_VXLAN, + BGPV4_EVPN_VXLAN_EXPORT_TARGET, + BGPV4_EVPN_VXLAN_IMPORT_TARGET, + BGPV4_EVPN_VXLAN_L3_EXPORT_TARGET, + BGPV4_EVPN_VXLAN_L3_IMPORT_TARGET, + BROADCAST_DOMAIN, + MAC_ADDRESS, + IP_ADDRESS, + IPV6_ADDRESS, + CMAC_PROPERTIES) + + +def validate_config(api, + BGPV4_EVPN_ETH_SEGMENT, + BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST, + BGPV4_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST, + BGPV4_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST, + BGPV4_EVPN_VXLAN, + BGPV4_EVPN_VXLAN_EXPORT_TARGET, + BGPV4_EVPN_VXLAN_IMPORT_TARGET, + BGPV4_EVPN_VXLAN_L3_EXPORT_TARGET, + BGPV4_EVPN_VXLAN_L3_IMPORT_TARGET, + BROADCAST_DOMAIN, + MAC_ADDRESS, + IP_ADDRESS, + IPV6_ADDRESS, + CMAC_PROPERTIES): + ixn = api._ixnetwork + bgps = ( + ixn.Topology.find().DeviceGroup.find() + .DeviceGroup.find().Ipv4Loopback.find().BgpIpv4Peer.find()) + for bgp in bgps: + assert bgp.EthernetSegmentsCountV4 == 1 + assert bgp.BgpEthernetSegmentV4.EvisCount == 1 + evis = bgp.BgpIPv4EvpnVXLAN.find() + assert evis.Multiplier == 1 + + bgp_eth_seg = bgps[0].BgpEthernetSegmentV4 + for attr in BGPV4_EVPN_ETH_SEGMENT: + if attr in ["DfElectionTimer", "EsiLabel", + "MultiExitDiscriminator"]: + assert BGPV4_EVPN_ETH_SEGMENT[attr] == int( + (getattr(bgp_eth_seg, attr).Values)[0] + ) + else: + assert BGPV4_EVPN_ETH_SEGMENT[attr] == ( + (getattr(bgp_eth_seg, attr).Values)[0] + ) + + bgp_eth_seg_comm_list = ( + bgps[0].BgpEthernetSegmentV4.BgpCommunitiesList.find()) + for attr in BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST: + assert BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST[attr] == ( + (getattr(bgp_eth_seg_comm_list, attr).Values)[0] + ) + + bgp_eth_seg_ext_comm_list = ( + bgps[0].BgpEthernetSegmentV4.BgpExtendedCommunitiesList.find()) + for attr in BGPV4_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST: + assert BGPV4_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST[attr] == ( + (getattr(bgp_eth_seg_ext_comm_list, attr).Values)[0] + ) + + bgp_eth_seg_aspath_segments_list = ( + bgps[0].BgpEthernetSegmentV4.BgpAsPathSegmentList.find()) + for attr in BGPV4_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST: + assert BGPV4_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST[attr] == ( + (getattr(bgp_eth_seg_aspath_segments_list, attr).Values)[0] + ) + + bgp_evpn_vxlan = bgps[0].BgpIPv4EvpnVXLAN.find() + for attr in BGPV4_EVPN_VXLAN: + assert BGPV4_EVPN_VXLAN[attr] == int( + (getattr(bgp_evpn_vxlan, attr).Values)[0] + ) + + bgp_evpn_vxlan_export_target = ( + bgp_evpn_vxlan.BgpExportRouteTargetList.find()) + for attr in BGPV4_EVPN_VXLAN_EXPORT_TARGET: + assert BGPV4_EVPN_VXLAN_EXPORT_TARGET[attr] == ( + (getattr(bgp_evpn_vxlan_export_target, attr).Values)[0] + ) + + bgp_evpn_vxlan_import_target = ( + bgp_evpn_vxlan.BgpImportRouteTargetList.find()) + for attr in BGPV4_EVPN_VXLAN_IMPORT_TARGET: + assert BGPV4_EVPN_VXLAN_IMPORT_TARGET[attr] == ( + (getattr(bgp_evpn_vxlan_import_target, attr).Values)[0] + ) + + bgp_evpn_vxlan_l3_export_target = ( + bgp_evpn_vxlan.BgpL3VNIExportRouteTargetList.find()) + for attr in BGPV4_EVPN_VXLAN_L3_EXPORT_TARGET: + assert BGPV4_EVPN_VXLAN_L3_EXPORT_TARGET[attr] == ( + (getattr(bgp_evpn_vxlan_l3_export_target, attr).Values)[0] + ) + + bgp_evpn_vxlan_l3_import_target = ( + bgp_evpn_vxlan.BgpL3VNIImportRouteTargetList.find()) + for attr in BGPV4_EVPN_VXLAN_L3_IMPORT_TARGET: + assert BGPV4_EVPN_VXLAN_L3_IMPORT_TARGET[attr] == ( + (getattr(bgp_evpn_vxlan_l3_import_target, attr).Values)[0] + ) + + bgp_eth_seg_vxlan_comm_list = ( + bgps[0].BgpIPv4EvpnVXLAN.find().BgpCommunitiesList.find()) + for attr in BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST: + assert BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST[attr] == ( + (getattr(bgp_eth_seg_vxlan_comm_list, attr).Values)[0] + ) + + bgp_eth_seg_vxlan_ext_comm_list = ( + bgps[0].BgpIPv4EvpnVXLAN.find().BgpExtendedCommunitiesList.find()) + for attr in BGPV4_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST: + assert BGPV4_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST[attr] == ( + (getattr(bgp_eth_seg_vxlan_ext_comm_list, attr).Values)[0] + ) + + bgp_eth_seg_vxlan_aspath_segments_list = ( + bgps[0].BgpIPv4EvpnVXLAN.find().BgpAsPathSegmentList.find()) + for attr in BGPV4_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST: + assert BGPV4_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST[attr] == ( + (getattr(bgp_eth_seg_vxlan_aspath_segments_list, attr).Values)[0] + ) + + bgp_eth_seg_vxlan_broadcast_domain = ( + bgps[0].BgpIPv4EvpnVXLAN.find().BroadcastDomainV4) + for attr in BROADCAST_DOMAIN: + assert BROADCAST_DOMAIN[attr] == ( + (getattr(bgp_eth_seg_vxlan_broadcast_domain, attr).Values)[0] + ) + + mac = (ixn.Topology.find().DeviceGroup.find() + .DeviceGroup.find().NetworkGroup.find().MacPools.find()) + for attr in MAC_ADDRESS: + assert MAC_ADDRESS[attr] == ( + (getattr(mac, attr).Values)[0] + ) + + ipv4 = (mac.Ipv4PrefixPools.find()) + for attr in IP_ADDRESS: + assert IP_ADDRESS[attr] == ( + (getattr(ipv4, attr).Values)[0] + ) + + ipv6 = (mac.Ipv6PrefixPools.find()) + for attr in IPV6_ADDRESS: + assert IPV6_ADDRESS[attr] == ( + (getattr(ipv6, attr).Values)[0] + ) + + cmac = (mac.CMacProperties.find()) + for attr in CMAC_PROPERTIES: + assert CMAC_PROPERTIES[attr] == ( + (getattr(cmac, attr).Values)[0] + ) + + cmac_comm_list = ( + cmac.BgpCommunitiesList.find()) + for attr in BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST: + assert BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST[attr] == ( + (getattr(cmac_comm_list, attr).Values)[0] + ) + + cmac_ext_comm_list = ( + cmac.BgpExtendedCommunitiesList.find()) + for attr in BGPV4_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST: + assert BGPV4_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST[attr] == ( + (getattr(cmac_ext_comm_list, attr).Values)[0] + ) + + cmac_aspath_segments_list = ( + cmac.BgpAsPathSegmentList.find()) + for attr in BGPV4_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST: + assert BGPV4_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST[attr] == ( + (getattr(cmac_aspath_segments_list, attr).Values)[0] + ) + + +if __name__ == "__main__": + pytest.main(["-s", __file__]) diff --git a/tests/bgp_evpn/test_bgpv6_evpn_attribute_validation.py b/tests/bgp_evpn/test_bgpv6_evpn_attribute_validation.py index 2a73adfb4..702534e15 100644 --- a/tests/bgp_evpn/test_bgpv6_evpn_attribute_validation.py +++ b/tests/bgp_evpn/test_bgpv6_evpn_attribute_validation.py @@ -1,428 +1,428 @@ -import pytest - - -def test_bgpv6_evpn_validation(api, utils): - "Validate BGP EVPN Attributes against RestPy" - - BGPV6_EVPN_ETH_SEGMENT = { - "DfElectionTimer": 10, - "EsiValue": "1000000000000000", - "EsiLabel": 8, - "EnableSingleActive": "true", - "MultiExitDiscriminator": 5, - "EnableMultiExitDiscriminator": "true", - "Origin": "egp", - "EnableOrigin": "true", - "EnableCommunity": "true", - "EnableExtendedCommunity": "true", - "EnableAsPathSegments": "true", - "AsSetMode": "includelocalasasasset" - } - - BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST = { - "Type": "manual", - "AsNumber": "8", - "LastTwoOctets": "8", - } - - BGPV6_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST = { - "Type": "opaque", - "SubType": "color", - "ColorValue": "200" - } - - BGPV6_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST = { - "SegmentType": "asseqconfederation", - } - - BGPV6_EVPN_VXLAN = { - "AdRouteLabel": 10, - "UpstreamDownstreamAssignedMplsLabel": 20, - "RdASNumber": 1000, - "RdEvi": 10, - "MultiExitDiscriminator": 99 - } - - BGPV6_EVPN_VXLAN_EXPORT_TARGET = { - "TargetAs4Number": "100", - "TargetAssignedNumber": "20" - } - - BGPV6_EVPN_VXLAN_IMPORT_TARGET = { - "TargetAs4Number": "200", - "TargetAssignedNumber": "30" - } - - BGPV6_EVPN_VXLAN_L3_EXPORT_TARGET = { - "TargetAs4Number": "300", - "TargetAssignedNumber": "50" - } - - BGPV6_EVPN_VXLAN_L3_IMPORT_TARGET = { - "TargetAs4Number": "400", - "TargetAssignedNumber": "60" - } - - BROADCAST_DOMAIN = { - "EthernetTagId": "5", - "EnableVlanAwareService": "true" - } - - MAC_ADDRESS = { - "Mac": "10:11:22:33:44:55", - "PrefixLength": "48", - "NumberOfAddressesAsy": "1" - } - - IP_ADDRESS = { - "NetworkAddress": "2.2.2.2", - "PrefixLength": "24", - "NumberOfAddressesAsy": "1" - } - - IPV6_ADDRESS = { - "NetworkAddress": "2000:0:2:1::1", - "PrefixLength": "64", - "NumberOfAddressesAsy": "1" - } - - CMAC_PROPERTIES = { - "FirstLabelStart": "16", - "SecondLabelStart": "20", - "MultiExitDiscriminator": "37", - "IncludeDefaultGatewayExtendedCommunity": "true" - } - - # Creating Ports - config = api.config() - p1 = config.ports.port(name='p1', location=utils.settings.ports[0])[-1] - # Create BGP devices on tx - tx_d = config.devices.device(name='tx_d')[-1] - tx_eth = tx_d.ethernets.ethernet(port_name=p1.name)[-1] - tx_eth.name = 'tx_eth' - tx_eth.mac = '00:11:00:00:00:01' - tx_ip = tx_eth.ipv6_addresses.ipv6(name='tx_ip', - address='2000::2', - gateway='2000::1')[-1] - - # tx_bgp - tx_bgp = tx_d.bgp - tx_bgp.router_id = "192.0.0.1" - tx_bgp_iface = (tx_bgp.ipv6_interfaces - .v6interface(ipv6_name=tx_ip.name)[-1]) - tx_bgp_peer = tx_bgp_iface.peers.v6peer(name="tx_eBGP", - peer_address='2000::1', - as_type='ebgp', - as_number=100)[-1] - - # Create & advertise loopback under bgp in tx and rx - tx_l1 = tx_d.ipv6_loopbacks.add() - tx_l1.name = "tx_loopback1" - tx_l1.eth_name = "tx_eth" - tx_l1.address = "2222::1" - tx_l1_r = tx_bgp_peer.v6_routes.add(name="tx_l1") - tx_l1_r.addresses.add(address="2222::1", prefix=64) - - # Create BGP EVPN on tx - tx_vtep = config.devices.device(name='tx_vtep')[-1] - tx_vtep_bgp = tx_vtep.bgp - tx_vtep_bgp.router_id = "190.0.0.1" - tx_vtep_bgp_iface = (tx_vtep_bgp.ipv6_interfaces - .v6interface(ipv6_name=tx_l1.name)[-1]) - tx_vtep_bgp_peer = tx_vtep_bgp_iface.peers.v6peer(name="bgp1", - peer_address='2000::1', - as_type='ibgp', - as_number=101)[-1] - - tx_eth_seg = tx_vtep_bgp_peer.evpn_ethernet_segments.ethernetsegment()[-1] - tx_eth_seg.df_election.election_timer = ( - BGPV6_EVPN_ETH_SEGMENT["DfElectionTimer"]) - tx_eth_seg.esi = BGPV6_EVPN_ETH_SEGMENT["EsiValue"] - tx_eth_seg.esi_label = BGPV6_EVPN_ETH_SEGMENT["EsiLabel"] - tx_eth_seg.active_mode = tx_eth_seg.SINGLE_ACTIVE - tx_eth_seg.advanced.origin = tx_eth_seg.advanced.EGP - tx_eth_seg.advanced.multi_exit_discriminator = ( - BGPV6_EVPN_ETH_SEGMENT["MultiExitDiscriminator"]) - tx_eth_seg_community = tx_eth_seg.communities.add() - tx_eth_seg_community.type = tx_eth_seg_community.MANUAL_AS_NUMBER - tx_eth_seg_community.as_number = int( - BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["AsNumber"]) - tx_eth_seg_community.as_custom = int( - BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["LastTwoOctets"]) - tx_eth_seg_ext_community = tx_eth_seg.ext_communities.add() - tx_eth_seg_ext_community.type = "opaque" - tx_eth_seg_ext_community.subtype = "color" - tx_eth_seg_ext_community.value = "0000000000C8" - tx_eth_seg.as_path.as_set_mode = "include_as_set" - tx_eth_seg.as_path.segments.add("as_confed_seq", [2, 3]) - - # Adding Tx EVI on the Ethernet Segment - tx_evi_vxlan = tx_eth_seg.evis.evi_vxlan()[-1] - tx_evi_vxlan.route_distinguisher.rd_type = ( - tx_evi_vxlan.route_distinguisher.AS_2OCTET) - tx_evi_vxlan.route_distinguisher.rd_value = ( - str(BGPV6_EVPN_VXLAN["RdASNumber"]) + ":" + str( - BGPV6_EVPN_VXLAN["RdEvi"])) - tx_evi_vxlan.ad_label = BGPV6_EVPN_VXLAN["AdRouteLabel"] - tx_evi_vxlan.pmsi_label = ( - BGPV6_EVPN_VXLAN["UpstreamDownstreamAssignedMplsLabel"]) - - export_rt = tx_evi_vxlan.route_target_export.routetarget()[-1] - import_rt = tx_evi_vxlan.route_target_import.routetarget()[-1] - export_rt.rt_type = export_rt.AS_4OCTET - export_rt.rt_value = ( - BGPV6_EVPN_VXLAN_EXPORT_TARGET[ - "TargetAs4Number"] + ":" + BGPV6_EVPN_VXLAN_EXPORT_TARGET[ - "TargetAssignedNumber"]) - import_rt.rt_type = import_rt.AS_4OCTET - import_rt.rt_value = ( - BGPV6_EVPN_VXLAN_IMPORT_TARGET[ - "TargetAs4Number"] + ":" + BGPV6_EVPN_VXLAN_IMPORT_TARGET[ - "TargetAssignedNumber"]) - - l3_export_rt = tx_evi_vxlan.l3_route_target_export.routetarget()[-1] - l3_import_rt = tx_evi_vxlan.l3_route_target_import.routetarget()[-1] - l3_export_rt.rt_type = l3_export_rt.AS_4OCTET - l3_export_rt.rt_value = ( - BGPV6_EVPN_VXLAN_L3_EXPORT_TARGET[ - "TargetAs4Number"] + ":" + BGPV6_EVPN_VXLAN_L3_EXPORT_TARGET[ - "TargetAssignedNumber"]) - l3_import_rt.rt_type = l3_import_rt.AS_4OCTET - l3_import_rt.rt_value = ( - BGPV6_EVPN_VXLAN_L3_IMPORT_TARGET[ - "TargetAs4Number"] + ":" + BGPV6_EVPN_VXLAN_L3_IMPORT_TARGET[ - "TargetAssignedNumber"]) - - tx_evi_vxlan.advanced.origin = tx_evi_vxlan.advanced.EGP - tx_evi_vxlan.advanced.multi_exit_discriminator = ( - BGPV6_EVPN_VXLAN["MultiExitDiscriminator"]) - tx_evi_vxlan_comm = tx_evi_vxlan.communities.add() - tx_evi_vxlan_comm.type = tx_evi_vxlan_comm.MANUAL_AS_NUMBER - tx_evi_vxlan_comm.as_number = ( - BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["AsNumber"]) - tx_evi_vxlan_comm.as_custom = ( - BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["LastTwoOctets"]) - tx_evi_vxlan_ext_comm = tx_evi_vxlan.ext_communities.add() - tx_evi_vxlan_ext_comm.type = "opaque" - tx_evi_vxlan_ext_comm.subtype = "color" - tx_evi_vxlan_ext_comm.value = "0000000000C8" - tx_evi_vxlan.as_path.segments.add("as_confed_seq", [9, 10]) - - # Adding tx Broadcast Domain per EVI and MAC range - tx_evpn_brodcast_domain = ( - tx_evi_vxlan.broadcast_domains.broadcastdomain()[-1]) - tx_evpn_brodcast_domain.ethernet_tag_id = int( - BROADCAST_DOMAIN["EthernetTagId"]) - tx_evpn_brodcast_domain.vlan_aware_service = True - tx_broadcast_macrange = ( - tx_evpn_brodcast_domain.cmac_ip_range.cmaciprange( - l2vni=16, l3vni=20, name="tx_cmaciprange", - include_default_gateway=True)[-1]) - tx_broadcast_macrange.mac_addresses.address = MAC_ADDRESS["Mac"] - tx_broadcast_macrange.ipv4_addresses.address = IP_ADDRESS["NetworkAddress"] - tx_broadcast_macrange.ipv6_addresses.address = ( - IPV6_ADDRESS["NetworkAddress"]) - - tx_broadcast_macrange.advanced.multi_exit_discriminator = int( - CMAC_PROPERTIES["MultiExitDiscriminator"]) - - cmac_comm = tx_broadcast_macrange.communities.add() - cmac_comm.type = cmac_comm.MANUAL_AS_NUMBER - cmac_comm.as_number = ( - BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["AsNumber"]) - cmac_comm.as_custom = ( - BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["LastTwoOctets"]) - cmac_ext_comm = tx_broadcast_macrange.ext_communities.add() - cmac_ext_comm.type = "opaque" - cmac_ext_comm.subtype = "color" - cmac_ext_comm.value = "0000000000C8" - tx_broadcast_macrange.as_path.segments.add("as_confed_seq", [9, 10]) - - api.set_config(config) - - validate_config(api, - BGPV6_EVPN_ETH_SEGMENT, - BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST, - BGPV6_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST, - BGPV6_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST, - BGPV6_EVPN_VXLAN, - BGPV6_EVPN_VXLAN_EXPORT_TARGET, - BGPV6_EVPN_VXLAN_IMPORT_TARGET, - BGPV6_EVPN_VXLAN_L3_EXPORT_TARGET, - BGPV6_EVPN_VXLAN_L3_IMPORT_TARGET, - BROADCAST_DOMAIN, - MAC_ADDRESS, - IP_ADDRESS, - IPV6_ADDRESS, - CMAC_PROPERTIES) - - -def validate_config(api, - BGPV6_EVPN_ETH_SEGMENT, - BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST, - BGPV6_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST, - BGPV6_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST, - BGPV6_EVPN_VXLAN, - BGPV6_EVPN_VXLAN_EXPORT_TARGET, - BGPV6_EVPN_VXLAN_IMPORT_TARGET, - BGPV6_EVPN_VXLAN_L3_EXPORT_TARGET, - BGPV6_EVPN_VXLAN_L3_IMPORT_TARGET, - BROADCAST_DOMAIN, - MAC_ADDRESS, - IP_ADDRESS, - IPV6_ADDRESS, - CMAC_PROPERTIES): - ixn = api._ixnetwork - bgps = ( - ixn.Topology.find().DeviceGroup.find() - .DeviceGroup.find().Ipv6Loopback.find().BgpIpv6Peer.find()) - for bgp in bgps: - assert bgp.EthernetSegmentsCountV6 == 1 - assert bgp.BgpEthernetSegmentV6.EvisCount == 1 - evis = bgp.BgpIPv6EvpnVXLAN.find() - assert evis.Multiplier == 1 - - bgp_eth_seg = bgps[0].BgpEthernetSegmentV6 - for attr in BGPV6_EVPN_ETH_SEGMENT: - if attr in ["DfElectionTimer", "EsiLabel", - "MultiExitDiscriminator"]: - assert BGPV6_EVPN_ETH_SEGMENT[attr] == int( - (getattr(bgp_eth_seg, attr).Values)[0] - ) - else: - assert BGPV6_EVPN_ETH_SEGMENT[attr] == ( - (getattr(bgp_eth_seg, attr).Values)[0] - ) - - bgp_eth_seg_comm_list = ( - bgps[0].BgpEthernetSegmentV6.BgpCommunitiesList.find()) - for attr in BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST: - assert BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST[attr] == ( - (getattr(bgp_eth_seg_comm_list, attr).Values)[0] - ) - - bgp_eth_seg_ext_comm_list = ( - bgps[0].BgpEthernetSegmentV6.BgpExtendedCommunitiesList.find()) - for attr in BGPV6_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST: - assert BGPV6_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST[attr] == ( - (getattr(bgp_eth_seg_ext_comm_list, attr).Values)[0] - ) - - bgp_eth_seg_aspath_segments_list = ( - bgps[0].BgpEthernetSegmentV6.BgpAsPathSegmentList.find()) - for attr in BGPV6_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST: - assert BGPV6_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST[attr] == ( - (getattr(bgp_eth_seg_aspath_segments_list, attr).Values)[0] - ) - - bgp_evpn_vxlan = bgps[0].BgpIPv6EvpnVXLAN.find() - for attr in BGPV6_EVPN_VXLAN: - assert BGPV6_EVPN_VXLAN[attr] == int( - (getattr(bgp_evpn_vxlan, attr).Values)[0] - ) - - bgp_evpn_vxlan_export_target = ( - bgp_evpn_vxlan.BgpExportRouteTargetList.find()) - for attr in BGPV6_EVPN_VXLAN_EXPORT_TARGET: - assert BGPV6_EVPN_VXLAN_EXPORT_TARGET[attr] == ( - (getattr(bgp_evpn_vxlan_export_target, attr).Values)[0] - ) - - bgp_evpn_vxlan_import_target = ( - bgp_evpn_vxlan.BgpImportRouteTargetList.find()) - for attr in BGPV6_EVPN_VXLAN_IMPORT_TARGET: - assert BGPV6_EVPN_VXLAN_IMPORT_TARGET[attr] == ( - (getattr(bgp_evpn_vxlan_import_target, attr).Values)[0] - ) - - bgp_evpn_vxlan_l3_export_target = ( - bgp_evpn_vxlan.BgpL3VNIExportRouteTargetList.find()) - for attr in BGPV6_EVPN_VXLAN_L3_EXPORT_TARGET: - assert BGPV6_EVPN_VXLAN_L3_EXPORT_TARGET[attr] == ( - (getattr(bgp_evpn_vxlan_l3_export_target, attr).Values)[0] - ) - - bgp_evpn_vxlan_l3_import_target = ( - bgp_evpn_vxlan.BgpL3VNIImportRouteTargetList.find()) - for attr in BGPV6_EVPN_VXLAN_L3_IMPORT_TARGET: - assert BGPV6_EVPN_VXLAN_L3_IMPORT_TARGET[attr] == ( - (getattr(bgp_evpn_vxlan_l3_import_target, attr).Values)[0] - ) - - bgp_eth_seg_vxlan_comm_list = ( - bgps[0].BgpIPv6EvpnVXLAN.find().BgpCommunitiesList.find()) - for attr in BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST: - assert BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST[attr] == ( - (getattr(bgp_eth_seg_vxlan_comm_list, attr).Values)[0] - ) - - bgp_eth_seg_vxlan_ext_comm_list = ( - bgps[0].BgpIPv6EvpnVXLAN.find().BgpExtendedCommunitiesList.find()) - for attr in BGPV6_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST: - assert BGPV6_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST[attr] == ( - (getattr(bgp_eth_seg_vxlan_ext_comm_list, attr).Values)[0] - ) - - bgp_eth_seg_vxlan_aspath_segments_list = ( - bgps[0].BgpIPv6EvpnVXLAN.find().BgpAsPathSegmentList.find()) - for attr in BGPV6_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST: - assert BGPV6_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST[attr] == ( - (getattr(bgp_eth_seg_vxlan_aspath_segments_list, attr).Values)[0] - ) - - bgp_eth_seg_vxlan_broadcast_domain = ( - bgps[0].BgpIPv6EvpnVXLAN.find().BroadcastDomainV6) - for attr in BROADCAST_DOMAIN: - assert BROADCAST_DOMAIN[attr] == ( - (getattr(bgp_eth_seg_vxlan_broadcast_domain, attr).Values)[0] - ) - - mac = (ixn.Topology.find().DeviceGroup.find() - .DeviceGroup.find().NetworkGroup.find().MacPools.find()) - for attr in MAC_ADDRESS: - assert MAC_ADDRESS[attr] == ( - (getattr(mac, attr).Values)[0] - ) - - ipv4 = (mac.Ipv4PrefixPools.find()) - for attr in IP_ADDRESS: - assert IP_ADDRESS[attr] == ( - (getattr(ipv4, attr).Values)[0] - ) - - ipv6 = (mac.Ipv6PrefixPools.find()) - for attr in IPV6_ADDRESS: - assert IPV6_ADDRESS[attr] == ( - (getattr(ipv6, attr).Values)[0] - ) - - cmac = (mac.CMacProperties.find()) - for attr in CMAC_PROPERTIES: - assert CMAC_PROPERTIES[attr] == ( - (getattr(cmac, attr).Values)[0] - ) - - cmac_comm_list = ( - cmac.BgpCommunitiesList.find()) - for attr in BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST: - assert BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST[attr] == ( - (getattr(cmac_comm_list, attr).Values)[0] - ) - - cmac_ext_comm_list = ( - cmac.BgpExtendedCommunitiesList.find()) - for attr in BGPV6_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST: - assert BGPV6_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST[attr] == ( - (getattr(cmac_ext_comm_list, attr).Values)[0] - ) - - cmac_aspath_segments_list = ( - cmac.BgpAsPathSegmentList.find()) - for attr in BGPV6_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST: - assert BGPV6_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST[attr] == ( - (getattr(cmac_aspath_segments_list, attr).Values)[0] - ) - - -if __name__ == "__main__": - pytest.main(["-s", __file__]) +import pytest + + +def test_bgpv6_evpn_validation(api, utils): + "Validate BGP EVPN Attributes against RestPy" + + BGPV6_EVPN_ETH_SEGMENT = { + "DfElectionTimer": 10, + "EsiValue": "1000000000000000", + "EsiLabel": 8, + "EnableSingleActive": "true", + "MultiExitDiscriminator": 5, + "EnableMultiExitDiscriminator": "true", + "Origin": "egp", + "EnableOrigin": "true", + "EnableCommunity": "true", + "EnableExtendedCommunity": "true", + "EnableAsPathSegments": "true", + "AsSetMode": "includelocalasasasset" + } + + BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST = { + "Type": "manual", + "AsNumber": "8", + "LastTwoOctets": "8", + } + + BGPV6_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST = { + "Type": "opaque", + "SubType": "color", + "ColorValue": "200" + } + + BGPV6_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST = { + "SegmentType": "asseqconfederation", + } + + BGPV6_EVPN_VXLAN = { + "AdRouteLabel": 10, + "UpstreamDownstreamAssignedMplsLabel": 20, + "RdASNumber": 1000, + "RdEvi": 10, + "MultiExitDiscriminator": 99 + } + + BGPV6_EVPN_VXLAN_EXPORT_TARGET = { + "TargetAs4Number": "100", + "TargetAssignedNumber": "20" + } + + BGPV6_EVPN_VXLAN_IMPORT_TARGET = { + "TargetAs4Number": "200", + "TargetAssignedNumber": "30" + } + + BGPV6_EVPN_VXLAN_L3_EXPORT_TARGET = { + "TargetAs4Number": "300", + "TargetAssignedNumber": "50" + } + + BGPV6_EVPN_VXLAN_L3_IMPORT_TARGET = { + "TargetAs4Number": "400", + "TargetAssignedNumber": "60" + } + + BROADCAST_DOMAIN = { + "EthernetTagId": "5", + "EnableVlanAwareService": "true" + } + + MAC_ADDRESS = { + "Mac": "10:11:22:33:44:55", + "PrefixLength": "48", + "NumberOfAddressesAsy": "1" + } + + IP_ADDRESS = { + "NetworkAddress": "2.2.2.2", + "PrefixLength": "24", + "NumberOfAddressesAsy": "1" + } + + IPV6_ADDRESS = { + "NetworkAddress": "2000:0:2:1::1", + "PrefixLength": "64", + "NumberOfAddressesAsy": "1" + } + + CMAC_PROPERTIES = { + "FirstLabelStart": "16", + "SecondLabelStart": "20", + "MultiExitDiscriminator": "37", + "IncludeDefaultGatewayExtendedCommunity": "true" + } + + # Creating Ports + config = api.config() + p1 = config.ports.port(name='p1', location=utils.settings.ports[0])[-1] + # Create BGP devices on tx + tx_d = config.devices.device(name='tx_d')[-1] + tx_eth = tx_d.ethernets.ethernet(port_name=p1.name)[-1] + tx_eth.name = 'tx_eth' + tx_eth.mac = '00:11:00:00:00:01' + tx_ip = tx_eth.ipv6_addresses.ipv6(name='tx_ip', + address='2000::2', + gateway='2000::1')[-1] + + # tx_bgp + tx_bgp = tx_d.bgp + tx_bgp.router_id = "192.0.0.1" + tx_bgp_iface = (tx_bgp.ipv6_interfaces + .v6interface(ipv6_name=tx_ip.name)[-1]) + tx_bgp_peer = tx_bgp_iface.peers.v6peer(name="tx_eBGP", + peer_address='2000::1', + as_type='ebgp', + as_number=100)[-1] + + # Create & advertise loopback under bgp in tx and rx + tx_l1 = tx_d.ipv6_loopbacks.add() + tx_l1.name = "tx_loopback1" + tx_l1.eth_name = "tx_eth" + tx_l1.address = "2222::1" + tx_l1_r = tx_bgp_peer.v6_routes.add(name="tx_l1") + tx_l1_r.addresses.add(address="2222::1", prefix=64) + + # Create BGP EVPN on tx + tx_vtep = config.devices.device(name='tx_vtep')[-1] + tx_vtep_bgp = tx_vtep.bgp + tx_vtep_bgp.router_id = "190.0.0.1" + tx_vtep_bgp_iface = (tx_vtep_bgp.ipv6_interfaces + .v6interface(ipv6_name=tx_l1.name)[-1]) + tx_vtep_bgp_peer = tx_vtep_bgp_iface.peers.v6peer(name="bgp1", + peer_address='2000::1', + as_type='ibgp', + as_number=101)[-1] + + tx_eth_seg = tx_vtep_bgp_peer.evpn_ethernet_segments.ethernetsegment()[-1] + tx_eth_seg.df_election.election_timer = ( + BGPV6_EVPN_ETH_SEGMENT["DfElectionTimer"]) + tx_eth_seg.esi = BGPV6_EVPN_ETH_SEGMENT["EsiValue"] + tx_eth_seg.esi_label = BGPV6_EVPN_ETH_SEGMENT["EsiLabel"] + tx_eth_seg.active_mode = tx_eth_seg.SINGLE_ACTIVE + tx_eth_seg.advanced.origin = tx_eth_seg.advanced.EGP + tx_eth_seg.advanced.multi_exit_discriminator = ( + BGPV6_EVPN_ETH_SEGMENT["MultiExitDiscriminator"]) + tx_eth_seg_community = tx_eth_seg.communities.add() + tx_eth_seg_community.type = tx_eth_seg_community.MANUAL_AS_NUMBER + tx_eth_seg_community.as_number = int( + BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["AsNumber"]) + tx_eth_seg_community.as_custom = int( + BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["LastTwoOctets"]) + tx_eth_seg_ext_community = tx_eth_seg.ext_communities.add() + tx_eth_seg_ext_community.type = "opaque" + tx_eth_seg_ext_community.subtype = "color" + tx_eth_seg_ext_community.value = "0000000000C8" + tx_eth_seg.as_path.as_set_mode = "include_as_set" + tx_eth_seg.as_path.segments.add("as_confed_seq", [2, 3]) + + # Adding Tx EVI on the Ethernet Segment + tx_evi_vxlan = tx_eth_seg.evis.evi_vxlan()[-1] + tx_evi_vxlan.route_distinguisher.rd_type = ( + tx_evi_vxlan.route_distinguisher.AS_2OCTET) + tx_evi_vxlan.route_distinguisher.rd_value = ( + str(BGPV6_EVPN_VXLAN["RdASNumber"]) + ":" + str( + BGPV6_EVPN_VXLAN["RdEvi"])) + tx_evi_vxlan.ad_label = BGPV6_EVPN_VXLAN["AdRouteLabel"] + tx_evi_vxlan.pmsi_label = ( + BGPV6_EVPN_VXLAN["UpstreamDownstreamAssignedMplsLabel"]) + + export_rt = tx_evi_vxlan.route_target_export.routetarget()[-1] + import_rt = tx_evi_vxlan.route_target_import.routetarget()[-1] + export_rt.rt_type = export_rt.AS_4OCTET + export_rt.rt_value = ( + BGPV6_EVPN_VXLAN_EXPORT_TARGET[ + "TargetAs4Number"] + ":" + BGPV6_EVPN_VXLAN_EXPORT_TARGET[ + "TargetAssignedNumber"]) + import_rt.rt_type = import_rt.AS_4OCTET + import_rt.rt_value = ( + BGPV6_EVPN_VXLAN_IMPORT_TARGET[ + "TargetAs4Number"] + ":" + BGPV6_EVPN_VXLAN_IMPORT_TARGET[ + "TargetAssignedNumber"]) + + l3_export_rt = tx_evi_vxlan.l3_route_target_export.routetarget()[-1] + l3_import_rt = tx_evi_vxlan.l3_route_target_import.routetarget()[-1] + l3_export_rt.rt_type = l3_export_rt.AS_4OCTET + l3_export_rt.rt_value = ( + BGPV6_EVPN_VXLAN_L3_EXPORT_TARGET[ + "TargetAs4Number"] + ":" + BGPV6_EVPN_VXLAN_L3_EXPORT_TARGET[ + "TargetAssignedNumber"]) + l3_import_rt.rt_type = l3_import_rt.AS_4OCTET + l3_import_rt.rt_value = ( + BGPV6_EVPN_VXLAN_L3_IMPORT_TARGET[ + "TargetAs4Number"] + ":" + BGPV6_EVPN_VXLAN_L3_IMPORT_TARGET[ + "TargetAssignedNumber"]) + + tx_evi_vxlan.advanced.origin = tx_evi_vxlan.advanced.EGP + tx_evi_vxlan.advanced.multi_exit_discriminator = ( + BGPV6_EVPN_VXLAN["MultiExitDiscriminator"]) + tx_evi_vxlan_comm = tx_evi_vxlan.communities.add() + tx_evi_vxlan_comm.type = tx_evi_vxlan_comm.MANUAL_AS_NUMBER + tx_evi_vxlan_comm.as_number = ( + BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["AsNumber"]) + tx_evi_vxlan_comm.as_custom = ( + BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["LastTwoOctets"]) + tx_evi_vxlan_ext_comm = tx_evi_vxlan.ext_communities.add() + tx_evi_vxlan_ext_comm.type = "opaque" + tx_evi_vxlan_ext_comm.subtype = "color" + tx_evi_vxlan_ext_comm.value = "0000000000C8" + tx_evi_vxlan.as_path.segments.add("as_confed_seq", [9, 10]) + + # Adding tx Broadcast Domain per EVI and MAC range + tx_evpn_brodcast_domain = ( + tx_evi_vxlan.broadcast_domains.broadcastdomain()[-1]) + tx_evpn_brodcast_domain.ethernet_tag_id = int( + BROADCAST_DOMAIN["EthernetTagId"]) + tx_evpn_brodcast_domain.vlan_aware_service = True + tx_broadcast_macrange = ( + tx_evpn_brodcast_domain.cmac_ip_range.cmaciprange( + l2vni=16, l3vni=20, name="tx_cmaciprange", + include_default_gateway=True)[-1]) + tx_broadcast_macrange.mac_addresses.address = MAC_ADDRESS["Mac"] + tx_broadcast_macrange.ipv4_addresses.address = IP_ADDRESS["NetworkAddress"] + tx_broadcast_macrange.ipv6_addresses.address = ( + IPV6_ADDRESS["NetworkAddress"]) + + tx_broadcast_macrange.advanced.multi_exit_discriminator = int( + CMAC_PROPERTIES["MultiExitDiscriminator"]) + + cmac_comm = tx_broadcast_macrange.communities.add() + cmac_comm.type = cmac_comm.MANUAL_AS_NUMBER + cmac_comm.as_number = ( + BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["AsNumber"]) + cmac_comm.as_custom = ( + BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["LastTwoOctets"]) + cmac_ext_comm = tx_broadcast_macrange.ext_communities.add() + cmac_ext_comm.type = "opaque" + cmac_ext_comm.subtype = "color" + cmac_ext_comm.value = "0000000000C8" + tx_broadcast_macrange.as_path.segments.add("as_confed_seq", [9, 10]) + + api.set_config(config) + + validate_config(api, + BGPV6_EVPN_ETH_SEGMENT, + BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST, + BGPV6_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST, + BGPV6_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST, + BGPV6_EVPN_VXLAN, + BGPV6_EVPN_VXLAN_EXPORT_TARGET, + BGPV6_EVPN_VXLAN_IMPORT_TARGET, + BGPV6_EVPN_VXLAN_L3_EXPORT_TARGET, + BGPV6_EVPN_VXLAN_L3_IMPORT_TARGET, + BROADCAST_DOMAIN, + MAC_ADDRESS, + IP_ADDRESS, + IPV6_ADDRESS, + CMAC_PROPERTIES) + + +def validate_config(api, + BGPV6_EVPN_ETH_SEGMENT, + BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST, + BGPV6_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST, + BGPV6_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST, + BGPV6_EVPN_VXLAN, + BGPV6_EVPN_VXLAN_EXPORT_TARGET, + BGPV6_EVPN_VXLAN_IMPORT_TARGET, + BGPV6_EVPN_VXLAN_L3_EXPORT_TARGET, + BGPV6_EVPN_VXLAN_L3_IMPORT_TARGET, + BROADCAST_DOMAIN, + MAC_ADDRESS, + IP_ADDRESS, + IPV6_ADDRESS, + CMAC_PROPERTIES): + ixn = api._ixnetwork + bgps = ( + ixn.Topology.find().DeviceGroup.find() + .DeviceGroup.find().Ipv6Loopback.find().BgpIpv6Peer.find()) + for bgp in bgps: + assert bgp.EthernetSegmentsCountV6 == 1 + assert bgp.BgpEthernetSegmentV6.EvisCount == 1 + evis = bgp.BgpIPv6EvpnVXLAN.find() + assert evis.Multiplier == 1 + + bgp_eth_seg = bgps[0].BgpEthernetSegmentV6 + for attr in BGPV6_EVPN_ETH_SEGMENT: + if attr in ["DfElectionTimer", "EsiLabel", + "MultiExitDiscriminator"]: + assert BGPV6_EVPN_ETH_SEGMENT[attr] == int( + (getattr(bgp_eth_seg, attr).Values)[0] + ) + else: + assert BGPV6_EVPN_ETH_SEGMENT[attr] == ( + (getattr(bgp_eth_seg, attr).Values)[0] + ) + + bgp_eth_seg_comm_list = ( + bgps[0].BgpEthernetSegmentV6.BgpCommunitiesList.find()) + for attr in BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST: + assert BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST[attr] == ( + (getattr(bgp_eth_seg_comm_list, attr).Values)[0] + ) + + bgp_eth_seg_ext_comm_list = ( + bgps[0].BgpEthernetSegmentV6.BgpExtendedCommunitiesList.find()) + for attr in BGPV6_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST: + assert BGPV6_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST[attr] == ( + (getattr(bgp_eth_seg_ext_comm_list, attr).Values)[0] + ) + + bgp_eth_seg_aspath_segments_list = ( + bgps[0].BgpEthernetSegmentV6.BgpAsPathSegmentList.find()) + for attr in BGPV6_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST: + assert BGPV6_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST[attr] == ( + (getattr(bgp_eth_seg_aspath_segments_list, attr).Values)[0] + ) + + bgp_evpn_vxlan = bgps[0].BgpIPv6EvpnVXLAN.find() + for attr in BGPV6_EVPN_VXLAN: + assert BGPV6_EVPN_VXLAN[attr] == int( + (getattr(bgp_evpn_vxlan, attr).Values)[0] + ) + + bgp_evpn_vxlan_export_target = ( + bgp_evpn_vxlan.BgpExportRouteTargetList.find()) + for attr in BGPV6_EVPN_VXLAN_EXPORT_TARGET: + assert BGPV6_EVPN_VXLAN_EXPORT_TARGET[attr] == ( + (getattr(bgp_evpn_vxlan_export_target, attr).Values)[0] + ) + + bgp_evpn_vxlan_import_target = ( + bgp_evpn_vxlan.BgpImportRouteTargetList.find()) + for attr in BGPV6_EVPN_VXLAN_IMPORT_TARGET: + assert BGPV6_EVPN_VXLAN_IMPORT_TARGET[attr] == ( + (getattr(bgp_evpn_vxlan_import_target, attr).Values)[0] + ) + + bgp_evpn_vxlan_l3_export_target = ( + bgp_evpn_vxlan.BgpL3VNIExportRouteTargetList.find()) + for attr in BGPV6_EVPN_VXLAN_L3_EXPORT_TARGET: + assert BGPV6_EVPN_VXLAN_L3_EXPORT_TARGET[attr] == ( + (getattr(bgp_evpn_vxlan_l3_export_target, attr).Values)[0] + ) + + bgp_evpn_vxlan_l3_import_target = ( + bgp_evpn_vxlan.BgpL3VNIImportRouteTargetList.find()) + for attr in BGPV6_EVPN_VXLAN_L3_IMPORT_TARGET: + assert BGPV6_EVPN_VXLAN_L3_IMPORT_TARGET[attr] == ( + (getattr(bgp_evpn_vxlan_l3_import_target, attr).Values)[0] + ) + + bgp_eth_seg_vxlan_comm_list = ( + bgps[0].BgpIPv6EvpnVXLAN.find().BgpCommunitiesList.find()) + for attr in BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST: + assert BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST[attr] == ( + (getattr(bgp_eth_seg_vxlan_comm_list, attr).Values)[0] + ) + + bgp_eth_seg_vxlan_ext_comm_list = ( + bgps[0].BgpIPv6EvpnVXLAN.find().BgpExtendedCommunitiesList.find()) + for attr in BGPV6_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST: + assert BGPV6_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST[attr] == ( + (getattr(bgp_eth_seg_vxlan_ext_comm_list, attr).Values)[0] + ) + + bgp_eth_seg_vxlan_aspath_segments_list = ( + bgps[0].BgpIPv6EvpnVXLAN.find().BgpAsPathSegmentList.find()) + for attr in BGPV6_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST: + assert BGPV6_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST[attr] == ( + (getattr(bgp_eth_seg_vxlan_aspath_segments_list, attr).Values)[0] + ) + + bgp_eth_seg_vxlan_broadcast_domain = ( + bgps[0].BgpIPv6EvpnVXLAN.find().BroadcastDomainV6) + for attr in BROADCAST_DOMAIN: + assert BROADCAST_DOMAIN[attr] == ( + (getattr(bgp_eth_seg_vxlan_broadcast_domain, attr).Values)[0] + ) + + mac = (ixn.Topology.find().DeviceGroup.find() + .DeviceGroup.find().NetworkGroup.find().MacPools.find()) + for attr in MAC_ADDRESS: + assert MAC_ADDRESS[attr] == ( + (getattr(mac, attr).Values)[0] + ) + + ipv4 = (mac.Ipv4PrefixPools.find()) + for attr in IP_ADDRESS: + assert IP_ADDRESS[attr] == ( + (getattr(ipv4, attr).Values)[0] + ) + + ipv6 = (mac.Ipv6PrefixPools.find()) + for attr in IPV6_ADDRESS: + assert IPV6_ADDRESS[attr] == ( + (getattr(ipv6, attr).Values)[0] + ) + + cmac = (mac.CMacProperties.find()) + for attr in CMAC_PROPERTIES: + assert CMAC_PROPERTIES[attr] == ( + (getattr(cmac, attr).Values)[0] + ) + + cmac_comm_list = ( + cmac.BgpCommunitiesList.find()) + for attr in BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST: + assert BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST[attr] == ( + (getattr(cmac_comm_list, attr).Values)[0] + ) + + cmac_ext_comm_list = ( + cmac.BgpExtendedCommunitiesList.find()) + for attr in BGPV6_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST: + assert BGPV6_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST[attr] == ( + (getattr(cmac_ext_comm_list, attr).Values)[0] + ) + + cmac_aspath_segments_list = ( + cmac.BgpAsPathSegmentList.find()) + for attr in BGPV6_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST: + assert BGPV6_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST[attr] == ( + (getattr(cmac_aspath_segments_list, attr).Values)[0] + ) + + +if __name__ == "__main__": + pytest.main(["-s", __file__]) diff --git a/tests/ping/test_ping.py b/tests/ping/test_ping.py index d1f8a8c49..94ec08d44 100644 --- a/tests/ping/test_ping.py +++ b/tests/ping/test_ping.py @@ -8,6 +8,9 @@ def test_ping(api, b2b_raw_config): Return the ping responses and validate as per user's expectation """ + version = api.get_version() + print(version) + port1, port2 = b2b_raw_config.ports d1, d2 = b2b_raw_config.devices.device(name="tx_bgp").device(name="rx_bgp") eth1, eth2 = d1.ethernets.add(), d2.ethernets.add() @@ -80,29 +83,26 @@ def test_ping(api, b2b_raw_config): time.sleep(1) retry_count = retry_count + 1 - # Ping Requests once ARP is resolved - req = api.ping_request() - p1, p2, p3, p4 = req.endpoints.ipv4().ipv4().ipv6().ipv6() - p1.src_name = ip1.name - p1.dst_ip = "10.1.1.2" - p2.src_name = ip1.name - p2.dst_ip = "10.1.1.3" - p3.src_name = ipv62.name - p3.dst_ip = "3000::1" - p4.src_name = ipv62.name - p4.dst_ip = "3000::9" - - responses = api.send_ping(req).responses + cs = api.control_action() + cs.protocol.ipv4.ping.requests.add(src_name=ip1.name, dst_ip="10.1.1.2") + cs.protocol.ipv4.ping.requests.add(src_name=ip1.name, dst_ip = "10.1.1.3") + responses = api.set_control_action(cs).response.protocol.ipv4.ping.responses for resp in responses: if resp.src_name == ip1.name and resp.dst_ip == "10.1.1.2": - assert resp.result == "success" + assert resp.result == "succeeded" elif resp.src_name == ip1.name and resp.dst_ip == "10.1.1.3": - assert resp.result == "failure" - elif resp.src_name == ipv62.name and resp.dst_ip == "3000::1": - assert resp.result == "success" - elif resp.src_name == ipv62.name and resp.dst_ip == "3000::9": - assert resp.result == "failure" + assert resp.result == "failed" + + cs = api.control_action() + cs.protocol.ipv6.ping.requests.add(src_name=ipv62.name, dst_ip= "3000::1") + cs.protocol.ipv6.ping.requests.add(src_name=ipv62.name, dst_ip = "3000::9") + responses = api.set_control_action(cs).response.protocol.ipv6.ping.responses + for resp in responses: + if resp.src_name == ipv62.name and resp.dst_ip == "3000::1": + assert resp.result == "succeeded" + elif resp.src_name == ipv62.name and resp.dst_ip == "3000::9": + assert resp.result == "failed" if __name__ == "__main__": pytest.main(["-vv", "-s", __file__]) diff --git a/tests/test_issue_microsoft.py b/tests/test_issue_microsoft.py index ed3c5d714..de7a5a625 100644 --- a/tests/test_issue_microsoft.py +++ b/tests/test_issue_microsoft.py @@ -1,188 +1,188 @@ -import time - - -def wait_for_arp(snappi_api, max_attempts=10, poll_interval_sec=1): - """ - Args: - snappi_api: snappi api - max_attempts: maximum attempts for timeout - poll_interval_sec: interval poll second - Return: - returns number of attempts if arp is resolved within max attempts else fail - """ - attempts = 0 - v4_gateway_macs_resolved = False - v6_gateway_macs_resolved = False - - get_config = snappi_api.get_config() - v4_addresses = [] - v6_addresses = [] - - for device in get_config.devices: - for ethernet in device.ethernets: - for v4_address in ethernet.ipv4_addresses: - v4_addresses.append(v4_address.address) - for v6_address in ethernet.ipv6_addresses: - v6_addresses.append(v6_address.address) - - while attempts < max_attempts: - request = snappi_api.states_request() - request.choice = request.IPV4_NEIGHBORS - states = snappi_api.get_states(request) - - if len(v4_addresses) > 0: - v4_link_layer_address = [ - state.link_layer_address - for state in states.ipv4_neighbors - if state.link_layer_address is not None - ] - if len(v4_addresses) == len(v4_link_layer_address): - v4_gateway_macs_resolved = True - else: - v4_gateway_macs_resolved = True - - request = snappi_api.states_request() - request.choice = request.IPV6_NEIGHBORS - states = snappi_api.get_states(request) - - if len(v6_addresses) > 0: - v6_link_layer_address = [ - state.link_layer_address - for state in states.ipv6_neighbors - if state.link_layer_address is not None - ] - if len(v6_addresses) == len(v6_link_layer_address): - v6_gateway_macs_resolved = True - else: - v6_gateway_macs_resolved = True - - if v4_gateway_macs_resolved and v6_gateway_macs_resolved: - break - else: - time.sleep(poll_interval_sec) - attempts += 1 - - print("Attempts: ", attempts) - print("Maxmimum Attempts:", max_attempts) - if attempts >= max_attempts: - import pdb;pdb.set_trace() - raise Exception("ARP is not resolved in {} seconds".format( - max_attempts * poll_interval_sec)) - - return attempts - - -def static_lag(api, utils): - """Demonstrates the following: - 1) Creating a lag comprised of multiple ports - 2) Creating emulated devices over the lag - 3) Creating traffic over the emulated devices that will transmit - traffic to a single rx port. - - TX LAG DUT RX - ------+ +---------+ - port 1| | - .. | ------> | - port n| | - ------+ - """ - config = api.config() - p1, p2 = ( - config.ports.port(name="txp1", location=utils.settings.ports[0]) - .port(name="rxp2", location=utils.settings.ports[1]) - ) - - config.layer1.layer1( - name="layer1", - port_names=[p.name for p in config.ports], - speed=utils.settings.speed, - media=utils.settings.media, - ) - - lag1, lag2 = config.lags.lag(name="lag1").lag(name="lag2") - lp1 = lag1.ports.port(port_name=p1.name)[-1] - lp2 = lag2.ports.port(port_name=p2.name)[-1] - lag1.protocol.static.lag_id = 1 - lag2.protocol.static.lag_id = 2 - - lp1.ethernet.name, lp2.ethernet.name = "eth1", "eth2" - - lp1.ethernet.mac = "00:11:02:00:00:01" - lp2.ethernet.mac = "00:22:02:00:00:01" - - lp1.ethernet.vlans.vlan(priority=1, name="vlan1", id=1)[-1] - lp2.ethernet.vlans.vlan(priority=1, name="vlan2", id=1)[-1] - - packets = 2000 - f1_size = 74 - f2_size = 1500 - d1, d2 = config.devices.device(name="device1").device(name="device2") - eth1, eth2 = d1.ethernets.add(), d2.ethernets.add() - eth1.port_name, eth2.port_name = lag1.name, lag2.name - eth1.name, eth2.name = "d_eth1", "d_eth2" - eth1.mac, eth2.mac = "00:00:00:00:00:11", "00:00:00:00:00:22" - ip1, ip2 = eth1.ipv4_addresses.add(), eth2.ipv4_addresses.add() - ip1.name, ip2.name = "ip1", "ip2" - ip1.address = "10.1.1.1" - ip1.gateway = "10.1.1.2" - ip2.address = "10.1.1.2" - ip2.gateway = "10.1.1.1" - f1, f2 = config.flows.flow(name="f1").flow(name="f2") - f1.tx_rx.port.tx_name = p1.name - f1.tx_rx.port.rx_name = p2.name - f2.tx_rx.port.rx_name = p1.name - f2.tx_rx.port.tx_name = p2.name - config.options.port_options.location_preemption = True - f1.duration.fixed_packets.packets = packets - f2.duration.fixed_packets.packets = packets - f1.size.fixed = f1_size - f2.size.fixed = f2_size - f1.rate.percentage = 10 - f2.rate.percentage = 10 - - f1.metrics.enable = True - f1.metrics.loss = True - - f2.metrics.enable = True - f2.metrics.loss = True - - api.set_config(config) - - wait_for_arp(api, max_attempts=10, poll_interval_sec=2) - - print("Starting transmit on all flows ...") - ts = api.transmit_state() - ts.state = ts.START - api.set_transmit_state(ts) - - utils.wait_for(lambda: utils.is_traffic_stopped(api), "traffic to stop") - - utils.wait_for( - lambda: utils.is_stats_accumulated(api, packets * 2), - "stats to be accumulated", - ) - - utils.wait_for( - lambda: results_ok(api, utils, f1_size, f2_size, packets), - "stats to be as expected", - timeout_seconds=30, - ) - - -def results_ok(api, utils, size1, size2, packets): - """ - Returns true if stats are as expected, false otherwise. - """ - port_results, flow_results = utils.get_all_stats(api) - frames_ok = utils.total_frames_ok(port_results, flow_results, packets * 2) - bytes_ok = utils.total_bytes_ok( - port_results, flow_results, packets * size1 + packets * size2 - ) - return frames_ok and bytes_ok - - -def test_static_lag(api, utils): - for i in range(0, 4): - static_lag(api, utils) - # test1(api, utils) - # test2(api, utils) +import time + + +def wait_for_arp(snappi_api, max_attempts=10, poll_interval_sec=1): + """ + Args: + snappi_api: snappi api + max_attempts: maximum attempts for timeout + poll_interval_sec: interval poll second + Return: + returns number of attempts if arp is resolved within max attempts else fail + """ + attempts = 0 + v4_gateway_macs_resolved = False + v6_gateway_macs_resolved = False + + get_config = snappi_api.get_config() + v4_addresses = [] + v6_addresses = [] + + for device in get_config.devices: + for ethernet in device.ethernets: + for v4_address in ethernet.ipv4_addresses: + v4_addresses.append(v4_address.address) + for v6_address in ethernet.ipv6_addresses: + v6_addresses.append(v6_address.address) + + while attempts < max_attempts: + request = snappi_api.states_request() + request.choice = request.IPV4_NEIGHBORS + states = snappi_api.get_states(request) + + if len(v4_addresses) > 0: + v4_link_layer_address = [ + state.link_layer_address + for state in states.ipv4_neighbors + if state.link_layer_address is not None + ] + if len(v4_addresses) == len(v4_link_layer_address): + v4_gateway_macs_resolved = True + else: + v4_gateway_macs_resolved = True + + request = snappi_api.states_request() + request.choice = request.IPV6_NEIGHBORS + states = snappi_api.get_states(request) + + if len(v6_addresses) > 0: + v6_link_layer_address = [ + state.link_layer_address + for state in states.ipv6_neighbors + if state.link_layer_address is not None + ] + if len(v6_addresses) == len(v6_link_layer_address): + v6_gateway_macs_resolved = True + else: + v6_gateway_macs_resolved = True + + if v4_gateway_macs_resolved and v6_gateway_macs_resolved: + break + else: + time.sleep(poll_interval_sec) + attempts += 1 + + print("Attempts: ", attempts) + print("Maxmimum Attempts:", max_attempts) + if attempts >= max_attempts: + import pdb;pdb.set_trace() + raise Exception("ARP is not resolved in {} seconds".format( + max_attempts * poll_interval_sec)) + + return attempts + + +def static_lag(api, utils): + """Demonstrates the following: + 1) Creating a lag comprised of multiple ports + 2) Creating emulated devices over the lag + 3) Creating traffic over the emulated devices that will transmit + traffic to a single rx port. + + TX LAG DUT RX + ------+ +---------+ + port 1| | + .. | ------> | + port n| | + ------+ + """ + config = api.config() + p1, p2 = ( + config.ports.port(name="txp1", location=utils.settings.ports[0]) + .port(name="rxp2", location=utils.settings.ports[1]) + ) + + config.layer1.layer1( + name="layer1", + port_names=[p.name for p in config.ports], + speed=utils.settings.speed, + media=utils.settings.media, + ) + + lag1, lag2 = config.lags.lag(name="lag1").lag(name="lag2") + lp1 = lag1.ports.port(port_name=p1.name)[-1] + lp2 = lag2.ports.port(port_name=p2.name)[-1] + lag1.protocol.static.lag_id = 1 + lag2.protocol.static.lag_id = 2 + + lp1.ethernet.name, lp2.ethernet.name = "eth1", "eth2" + + lp1.ethernet.mac = "00:11:02:00:00:01" + lp2.ethernet.mac = "00:22:02:00:00:01" + + lp1.ethernet.vlans.vlan(priority=1, name="vlan1", id=1)[-1] + lp2.ethernet.vlans.vlan(priority=1, name="vlan2", id=1)[-1] + + packets = 2000 + f1_size = 74 + f2_size = 1500 + d1, d2 = config.devices.device(name="device1").device(name="device2") + eth1, eth2 = d1.ethernets.add(), d2.ethernets.add() + eth1.port_name, eth2.port_name = lag1.name, lag2.name + eth1.name, eth2.name = "d_eth1", "d_eth2" + eth1.mac, eth2.mac = "00:00:00:00:00:11", "00:00:00:00:00:22" + ip1, ip2 = eth1.ipv4_addresses.add(), eth2.ipv4_addresses.add() + ip1.name, ip2.name = "ip1", "ip2" + ip1.address = "10.1.1.1" + ip1.gateway = "10.1.1.2" + ip2.address = "10.1.1.2" + ip2.gateway = "10.1.1.1" + f1, f2 = config.flows.flow(name="f1").flow(name="f2") + f1.tx_rx.port.tx_name = p1.name + f1.tx_rx.port.rx_name = p2.name + f2.tx_rx.port.rx_name = p1.name + f2.tx_rx.port.tx_name = p2.name + config.options.port_options.location_preemption = True + f1.duration.fixed_packets.packets = packets + f2.duration.fixed_packets.packets = packets + f1.size.fixed = f1_size + f2.size.fixed = f2_size + f1.rate.percentage = 10 + f2.rate.percentage = 10 + + f1.metrics.enable = True + f1.metrics.loss = True + + f2.metrics.enable = True + f2.metrics.loss = True + + api.set_config(config) + + wait_for_arp(api, max_attempts=10, poll_interval_sec=2) + + print("Starting transmit on all flows ...") + ts = api.transmit_state() + ts.state = ts.START + api.set_transmit_state(ts) + + utils.wait_for(lambda: utils.is_traffic_stopped(api), "traffic to stop") + + utils.wait_for( + lambda: utils.is_stats_accumulated(api, packets * 2), + "stats to be accumulated", + ) + + utils.wait_for( + lambda: results_ok(api, utils, f1_size, f2_size, packets), + "stats to be as expected", + timeout_seconds=30, + ) + + +def results_ok(api, utils, size1, size2, packets): + """ + Returns true if stats are as expected, false otherwise. + """ + port_results, flow_results = utils.get_all_stats(api) + frames_ok = utils.total_frames_ok(port_results, flow_results, packets * 2) + bytes_ok = utils.total_bytes_ok( + port_results, flow_results, packets * size1 + packets * size2 + ) + return frames_ok and bytes_ok + + +def test_static_lag(api, utils): + for i in range(0, 4): + static_lag(api, utils) + # test1(api, utils) + # test2(api, utils) diff --git a/tests/utils/common.py b/tests/utils/common.py index fbd967f88..7784e9dc1 100644 --- a/tests/utils/common.py +++ b/tests/utils/common.py @@ -123,41 +123,41 @@ def start_traffic(api, cfg, start_capture=True): capture_names = get_capture_port_names(cfg) if capture_names and start_capture: print("Starting capture on ports %s ..." % str(capture_names)) - cs = api.capture_state() - cs.state = cs.START - api.set_capture_state(cs) + cs = api.control_state() + cs.port.capture.state = cs.port.capture.START + api.set_control_state(cs) + print("Starting all protocols ...") - ps = api.protocol_state() - ps.state = ps.START - api.set_protocol_state(ps) + cs = api.control_state() + cs.protocol.all.state = cs.protocol.all.START + api.set_control_state(cs) print("Starting transmit on all flows ...") - ts = api.transmit_state() - ts.state = ts.START - api.set_transmit_state(ts) + cs = api.control_state() + cs.traffic.flow_transmit.state = cs.traffic.flow_transmit.START + api.set_control_state(cs) def stop_traffic(api, cfg, stop_capture=True): """ Stops flows """ print("Stopping transmit on all flows ...") - ts = api.transmit_state() - ts.state = ts.STOP - api.set_transmit_state(ts) - - print("Starting all protocols ...") - ps = api.protocol_state() - ps.state = ps.STOP - api.set_protocol_state(ps) + cs = api.control_state() + cs.traffic.flow_transmit.state = cs.traffic.flow_transmit.STOP + api.set_control_state(cs) + + print("Stopping all protocols ...") + cs = api.control_state() + cs.protocol.all.state = cs.protocol.all.STOP + api.set_control_state(cs) capture_names = get_capture_port_names(cfg) if capture_names and stop_capture: print("Stopping capture on ports %s ..." % str(capture_names)) - cs = api.capture_state() - cs.state = cs.STOP - api.set_capture_state(cs) - + cs = api.control_state() + cs.port.capture.state = cs.port.capture.STOP + api.set_control_state(cs) def seconds_elapsed(start_seconds): return int(round(time.time() - start_seconds)) diff --git a/tests/vxlan/test_manual_gateway_mac.py b/tests/vxlan/test_manual_gateway_mac.py index 23a3ba020..e6d510e9e 100644 --- a/tests/vxlan/test_manual_gateway_mac.py +++ b/tests/vxlan/test_manual_gateway_mac.py @@ -1,207 +1,207 @@ -import pytest - - -def test_manual_gateway_mac(api, utils): - count = 128 - config = api.config() - - edge1_macs = get_macs("001801000011", count) - edge2_macs = get_macs("001601000011", count) - - p1, p2 = config.ports.port( - name="p1", location=utils.settings.ports[0] - ).port(name="p2", location=utils.settings.ports[1]) - - d1, d2 = config.devices.device(name="d1").device(name="d2") - - e1, e2 = d1.ethernets.ethernet()[-1], d2.ethernets.ethernet()[-1] - e1.port_name, e2.port_name = p1.name, p2.name - e1.name, e2.name = "e1", "e2" - e1.mac, e2.mac = "00:01:00:00:00:01", "00:01:00:00:00:02" - - ip1, ip2 = e1.ipv4_addresses.add(), e2.ipv4_addresses.add() - ip1.name, ip2.name = "ip_d1", "ip_d2" - - ip1.address, ip2.address = "10.10.10.1", "10.10.10.2" - ip1.gateway, ip2.gateway = "10.10.10.2", "10.10.10.1" - - ip1.gateway_mac.value = "aa:aa:aa:aa:aa:aa" - - bgp1, bgp2 = d1.bgp, d2.bgp - bgp1.router_id, bgp2.router_id = "10.10.10.1", "10.10.10.2" - bgp1_ipv4 = bgp1.ipv4_interfaces.add() - bgp2_ipv4 = bgp2.ipv4_interfaces.add() - - bgp1_ipv4.ipv4_name, bgp2_ipv4.ipv4_name = ip1.name, ip2.name - bgp1_peer, bgp2_peer = bgp1_ipv4.peers.add(), bgp2_ipv4.peers.add() - bgp1_peer.name, bgp2_peer.name = "bgp_router1", "bgp_router2" - - bgp1_peer.peer_address, bgp2_peer.peer_address = "10.10.10.2", "10.10.10.1" - bgp1_peer.as_type, bgp2_peer.as_type = "ebgp", "ebgp" - bgp1_peer.as_number, bgp2_peer.as_number = 100, 200 - - # Create & advertise loopbacks under bgp in d1 & d2 - for i in range(1, count + 1): - d1_l1 = d1.ipv4_loopbacks.add() - d1_l1.name = "d1_loopback{}".format(i) - d1_l1.eth_name = "e1" - d1_l1.address = "1.1.1.{}".format(i) - - bgp1_l1 = bgp1_peer.v4_routes.add(name="bgp_l{}".format(i)) - bgp1_l1.addresses.add(address="1.1.1.{}".format(i), prefix=32) - - for i in range(1, count + 1): - d2_l1 = d2.ipv4_loopbacks.add() - d2_l1.name = "d2_loopback{}".format(i) - d2_l1.eth_name = "e2" - d2_l1.address = "2.2.2.{}".format(i) - - bgp2_l1 = bgp2_peer.v4_routes.add(name="bgp2_l{}".format(i)) - bgp2_l1.addresses.add(address="2.2.2.{}".format(i), prefix=32) - - # Create vxlan tunnels on d1 - for i in range(1, count + 1): - d1_vxlan = d1.vxlan.v4_tunnels.add() - - d1_vxlan.vni = 1000 + i - d1_vxlan.source_interface = "d1_loopback{}".format(i) - d1_vxlan.name = "d1_vxlan{}".format(i) - - # unicast communication, Add two unicast info - vtep = d1_vxlan.destination_ip_mode.unicast.vteps.add() - vtep.remote_vtep_address = "2.2.2.{}".format(i) - vtep.arp_suppression_cache.add(edge2_macs[i], "100.1.2.{}".format(i)) - vtep.arp_suppression_cache.add("00:1b:6e:00:00:01", "1.2.0.1") - - # Create vxlan on d2 - for i in range(1, count + 1): - d2_vxlan = d2.vxlan.v4_tunnels.add() - - d2_vxlan.vni = 1000 + i - d2_vxlan.source_interface = "d2_loopback{}".format(i) - d2_vxlan.name = "d2_vxlan{}".format(i) - - # unicast communication - vtep = d2_vxlan.destination_ip_mode.unicast.vteps.add() - vtep.remote_vtep_address = "1.1.1.{}".format(i) - vtep.arp_suppression_cache.add(edge1_macs[i], "100.1.1.{}".format(i)) - vtep.arp_suppression_cache.add("00:1b:6e:00:00:01", "1.2.0.1") - - for i in range(1, count + 1): - edge1_d = config.devices.device(name="edge1_d{}".format(i))[-1] - edge2_d = config.devices.device(name="edge2_d{}".format(i))[-1] - - edge1_e = edge1_d.ethernets.ethernet()[-1] - edge2_e = edge2_d.ethernets.ethernet()[-1] - - edge1_e.connection.vxlan_name = "d1_vxlan{}".format(i) - edge2_e.connection.vxlan_name = "d2_vxlan{}".format(i) - - edge1_e.name = "edge1_e{}".format(i) - edge2_e.name = "edge2_e{}".format(i) - - edge1_e.mac = edge1_macs[i] - edge2_e.mac = edge2_macs[i] - - edge1_ip = edge1_e.ipv4_addresses.add() - edge2_ip = edge2_e.ipv4_addresses.add() - - edge1_ip.name = "edge1_ip_d{}".format(i) - edge2_ip.name = "edge2_ip_d{}".format(i) - - edge1_ip.address = "100.1.{}.1".format(i) - edge2_ip.address = "100.1.{}.2".format(i) - - edge1_ip.gateway = "100.1.{}.2".format(i) - edge2_ip.gateway = "100.1.{}.1".format(i) - - edge1_ip.gateway_mac.value = edge2_macs[i] - - edge1_bgp, edge2_bgp = edge1_d.bgp, edge2_d.bgp - edge1_bgp.router_id = "100.1.{}.1".format(i) - edge2_bgp.router_id = "100.1.{}.2".format(i) - - edge1_bgp_ipv4 = edge1_bgp.ipv4_interfaces.add() - edge2_bgp_ipv4 = edge2_bgp.ipv4_interfaces.add() - - edge1_bgp_ipv4.ipv4_name = "edge1_ip_d{}".format(i) - edge2_bgp_ipv4.ipv4_name = "edge2_ip_d{}".format(i) - - edge1_bgp_peer = edge1_bgp_ipv4.peers.add() - edge2_bgp_peer = edge2_bgp_ipv4.peers.add() - - edge1_bgp_peer.name = "edge1_bgp{}".format(i) - edge2_bgp_peer.name = "edge2_bgp{}".format(i) - - edge1_bgp_peer.peer_address = "100.1.{}.2".format(i) - edge2_bgp_peer.peer_address = "100.1.{}.1".format(i) - - edge1_bgp_peer.as_type, edge2_bgp_peer.as_type = "ibgp", "ibgp" - edge1_bgp_peer.as_number, edge2_bgp_peer.as_number = 1000, 1000 - - edge1_bgp_rr = edge1_bgp_peer.v4_routes.add(name="A1{}".format(i)) - edge1_bgp_rr.addresses.add( - address="1.1.0.{}".format(i), count=180, prefix=32 - ) - - edge1_bgp_rr2 = edge1_bgp_peer.v4_routes.add(name="D1{}".format(i)) - edge1_bgp_rr2.addresses.add( - address="2.1.0.{}".format(i), count=1, prefix=32 - ) - - edge2_bgp_rr = edge2_bgp_peer.v4_routes.add(name="A2{}".format(i)) - edge2_bgp_rr.addresses.add( - address="3.1.0.{}".format(i), count=180, prefix=32 - ) - - edge2_bgp_rr2 = edge2_bgp_peer.v4_routes.add(name="D2{}".format(i)) - edge2_bgp_rr2.addresses.add( - address="4.1.0.{}".format(i), count=1, prefix=32 - ) - - api.set_config(config) - - assert ( - api._ixnetwork.Topology.find()[0] - .DeviceGroup.find() - .DeviceGroup.find() - .Multiplier - ) == 128 - - assert ( - api._ixnetwork.Topology.find()[0] - .DeviceGroup.find() - .DeviceGroup.find() - .DeviceGroup.find() - .Count - ) == 128 - - assert ( - api._ixnetwork.Topology.find()[0] - .DeviceGroup.find()[0].Ethernet.find()[0] - .Ipv4.find().ManualGatewayMac.Values[0] - ) == "aa:aa:aa:aa:aa:aa" - - assert ( - api._ixnetwork.Topology.find()[0].DeviceGroup.find() - .DeviceGroup.find().DeviceGroup.find() - .Ethernet.find()[0].Ipv4.find().ManualGatewayMac.Values - ) == edge2_macs[1:] - - -def get_macs(mac, count, offset=1): - """ - Take mac as start mac returns the count of macs in a list - """ - mac_list = list() - for i in range(count + 1): - mac_address = "{:012X}".format(int(mac, 16) + offset * i) - mac_address = ":".join( - format(s, "02x") for s in bytearray.fromhex(mac_address) - ) - mac_list.append(mac_address) - return mac_list - - -if __name__ == "__main__": - pytest.main(["-s", __file__]) +import pytest + + +def test_manual_gateway_mac(api, utils): + count = 128 + config = api.config() + + edge1_macs = get_macs("001801000011", count) + edge2_macs = get_macs("001601000011", count) + + p1, p2 = config.ports.port( + name="p1", location=utils.settings.ports[0] + ).port(name="p2", location=utils.settings.ports[1]) + + d1, d2 = config.devices.device(name="d1").device(name="d2") + + e1, e2 = d1.ethernets.ethernet()[-1], d2.ethernets.ethernet()[-1] + e1.port_name, e2.port_name = p1.name, p2.name + e1.name, e2.name = "e1", "e2" + e1.mac, e2.mac = "00:01:00:00:00:01", "00:01:00:00:00:02" + + ip1, ip2 = e1.ipv4_addresses.add(), e2.ipv4_addresses.add() + ip1.name, ip2.name = "ip_d1", "ip_d2" + + ip1.address, ip2.address = "10.10.10.1", "10.10.10.2" + ip1.gateway, ip2.gateway = "10.10.10.2", "10.10.10.1" + + ip1.gateway_mac.value = "aa:aa:aa:aa:aa:aa" + + bgp1, bgp2 = d1.bgp, d2.bgp + bgp1.router_id, bgp2.router_id = "10.10.10.1", "10.10.10.2" + bgp1_ipv4 = bgp1.ipv4_interfaces.add() + bgp2_ipv4 = bgp2.ipv4_interfaces.add() + + bgp1_ipv4.ipv4_name, bgp2_ipv4.ipv4_name = ip1.name, ip2.name + bgp1_peer, bgp2_peer = bgp1_ipv4.peers.add(), bgp2_ipv4.peers.add() + bgp1_peer.name, bgp2_peer.name = "bgp_router1", "bgp_router2" + + bgp1_peer.peer_address, bgp2_peer.peer_address = "10.10.10.2", "10.10.10.1" + bgp1_peer.as_type, bgp2_peer.as_type = "ebgp", "ebgp" + bgp1_peer.as_number, bgp2_peer.as_number = 100, 200 + + # Create & advertise loopbacks under bgp in d1 & d2 + for i in range(1, count + 1): + d1_l1 = d1.ipv4_loopbacks.add() + d1_l1.name = "d1_loopback{}".format(i) + d1_l1.eth_name = "e1" + d1_l1.address = "1.1.1.{}".format(i) + + bgp1_l1 = bgp1_peer.v4_routes.add(name="bgp_l{}".format(i)) + bgp1_l1.addresses.add(address="1.1.1.{}".format(i), prefix=32) + + for i in range(1, count + 1): + d2_l1 = d2.ipv4_loopbacks.add() + d2_l1.name = "d2_loopback{}".format(i) + d2_l1.eth_name = "e2" + d2_l1.address = "2.2.2.{}".format(i) + + bgp2_l1 = bgp2_peer.v4_routes.add(name="bgp2_l{}".format(i)) + bgp2_l1.addresses.add(address="2.2.2.{}".format(i), prefix=32) + + # Create vxlan tunnels on d1 + for i in range(1, count + 1): + d1_vxlan = d1.vxlan.v4_tunnels.add() + + d1_vxlan.vni = 1000 + i + d1_vxlan.source_interface = "d1_loopback{}".format(i) + d1_vxlan.name = "d1_vxlan{}".format(i) + + # unicast communication, Add two unicast info + vtep = d1_vxlan.destination_ip_mode.unicast.vteps.add() + vtep.remote_vtep_address = "2.2.2.{}".format(i) + vtep.arp_suppression_cache.add(edge2_macs[i], "100.1.2.{}".format(i)) + vtep.arp_suppression_cache.add("00:1b:6e:00:00:01", "1.2.0.1") + + # Create vxlan on d2 + for i in range(1, count + 1): + d2_vxlan = d2.vxlan.v4_tunnels.add() + + d2_vxlan.vni = 1000 + i + d2_vxlan.source_interface = "d2_loopback{}".format(i) + d2_vxlan.name = "d2_vxlan{}".format(i) + + # unicast communication + vtep = d2_vxlan.destination_ip_mode.unicast.vteps.add() + vtep.remote_vtep_address = "1.1.1.{}".format(i) + vtep.arp_suppression_cache.add(edge1_macs[i], "100.1.1.{}".format(i)) + vtep.arp_suppression_cache.add("00:1b:6e:00:00:01", "1.2.0.1") + + for i in range(1, count + 1): + edge1_d = config.devices.device(name="edge1_d{}".format(i))[-1] + edge2_d = config.devices.device(name="edge2_d{}".format(i))[-1] + + edge1_e = edge1_d.ethernets.ethernet()[-1] + edge2_e = edge2_d.ethernets.ethernet()[-1] + + edge1_e.connection.vxlan_name = "d1_vxlan{}".format(i) + edge2_e.connection.vxlan_name = "d2_vxlan{}".format(i) + + edge1_e.name = "edge1_e{}".format(i) + edge2_e.name = "edge2_e{}".format(i) + + edge1_e.mac = edge1_macs[i] + edge2_e.mac = edge2_macs[i] + + edge1_ip = edge1_e.ipv4_addresses.add() + edge2_ip = edge2_e.ipv4_addresses.add() + + edge1_ip.name = "edge1_ip_d{}".format(i) + edge2_ip.name = "edge2_ip_d{}".format(i) + + edge1_ip.address = "100.1.{}.1".format(i) + edge2_ip.address = "100.1.{}.2".format(i) + + edge1_ip.gateway = "100.1.{}.2".format(i) + edge2_ip.gateway = "100.1.{}.1".format(i) + + edge1_ip.gateway_mac.value = edge2_macs[i] + + edge1_bgp, edge2_bgp = edge1_d.bgp, edge2_d.bgp + edge1_bgp.router_id = "100.1.{}.1".format(i) + edge2_bgp.router_id = "100.1.{}.2".format(i) + + edge1_bgp_ipv4 = edge1_bgp.ipv4_interfaces.add() + edge2_bgp_ipv4 = edge2_bgp.ipv4_interfaces.add() + + edge1_bgp_ipv4.ipv4_name = "edge1_ip_d{}".format(i) + edge2_bgp_ipv4.ipv4_name = "edge2_ip_d{}".format(i) + + edge1_bgp_peer = edge1_bgp_ipv4.peers.add() + edge2_bgp_peer = edge2_bgp_ipv4.peers.add() + + edge1_bgp_peer.name = "edge1_bgp{}".format(i) + edge2_bgp_peer.name = "edge2_bgp{}".format(i) + + edge1_bgp_peer.peer_address = "100.1.{}.2".format(i) + edge2_bgp_peer.peer_address = "100.1.{}.1".format(i) + + edge1_bgp_peer.as_type, edge2_bgp_peer.as_type = "ibgp", "ibgp" + edge1_bgp_peer.as_number, edge2_bgp_peer.as_number = 1000, 1000 + + edge1_bgp_rr = edge1_bgp_peer.v4_routes.add(name="A1{}".format(i)) + edge1_bgp_rr.addresses.add( + address="1.1.0.{}".format(i), count=180, prefix=32 + ) + + edge1_bgp_rr2 = edge1_bgp_peer.v4_routes.add(name="D1{}".format(i)) + edge1_bgp_rr2.addresses.add( + address="2.1.0.{}".format(i), count=1, prefix=32 + ) + + edge2_bgp_rr = edge2_bgp_peer.v4_routes.add(name="A2{}".format(i)) + edge2_bgp_rr.addresses.add( + address="3.1.0.{}".format(i), count=180, prefix=32 + ) + + edge2_bgp_rr2 = edge2_bgp_peer.v4_routes.add(name="D2{}".format(i)) + edge2_bgp_rr2.addresses.add( + address="4.1.0.{}".format(i), count=1, prefix=32 + ) + + api.set_config(config) + + assert ( + api._ixnetwork.Topology.find()[0] + .DeviceGroup.find() + .DeviceGroup.find() + .Multiplier + ) == 128 + + assert ( + api._ixnetwork.Topology.find()[0] + .DeviceGroup.find() + .DeviceGroup.find() + .DeviceGroup.find() + .Count + ) == 128 + + assert ( + api._ixnetwork.Topology.find()[0] + .DeviceGroup.find()[0].Ethernet.find()[0] + .Ipv4.find().ManualGatewayMac.Values[0] + ) == "aa:aa:aa:aa:aa:aa" + + assert ( + api._ixnetwork.Topology.find()[0].DeviceGroup.find() + .DeviceGroup.find().DeviceGroup.find() + .Ethernet.find()[0].Ipv4.find().ManualGatewayMac.Values + ) == edge2_macs[1:] + + +def get_macs(mac, count, offset=1): + """ + Take mac as start mac returns the count of macs in a list + """ + mac_list = list() + for i in range(count + 1): + mac_address = "{:012X}".format(int(mac, 16) + offset * i) + mac_address = ":".join( + format(s, "02x") for s in bytearray.fromhex(mac_address) + ) + mac_list.append(mac_address) + return mac_list + + +if __name__ == "__main__": + pytest.main(["-s", __file__]) diff --git a/tests/vxlan/test_vxlan_b2b_scale.py b/tests/vxlan/test_vxlan_b2b_scale.py index df6b927f9..bc443ba83 100644 --- a/tests/vxlan/test_vxlan_b2b_scale.py +++ b/tests/vxlan/test_vxlan_b2b_scale.py @@ -1,229 +1,229 @@ -import pytest - - -def test_vxlan_b2b_scale(api, utils): - """ - 1. Create 128 loopbacks and advertise them using BGP. - 2. Create VXLAN connected to each loopback, so total 128 vxlan tunnels. - 3. Create BGP devices in VXLAN and advertise the routes. - """ - count = 128 - config = api.config() - - edge1_macs = get_macs("001801000011", count) - edge2_macs = get_macs("001601000011", count) - - p1, p2 = config.ports.port( - name="p1", location=utils.settings.ports[0] - ).port(name="p2", location=utils.settings.ports[1]) - - d1, d2 = config.devices.device(name="d1").device(name="d2") - - e1, e2 = d1.ethernets.ethernet()[-1], d2.ethernets.ethernet()[-1] - e1.port_name, e2.port_name = p1.name, p2.name - e1.name, e2.name = "e1", "e2" - e1.mac, e2.mac = "00:01:00:00:00:01", "00:01:00:00:00:02" - - ip1, ip2 = e1.ipv4_addresses.add(), e2.ipv4_addresses.add() - ip1.name, ip2.name = "ip_d1", "ip_d2" - - ip1.address, ip2.address = "10.10.10.1", "10.10.10.2" - ip1.gateway, ip2.gateway = "10.10.10.2", "10.10.10.1" - - bgp1, bgp2 = d1.bgp, d2.bgp - bgp1.router_id, bgp2.router_id = "10.10.10.1", "10.10.10.2" - bgp1_ipv4 = bgp1.ipv4_interfaces.add() - bgp2_ipv4 = bgp2.ipv4_interfaces.add() - - bgp1_ipv4.ipv4_name, bgp2_ipv4.ipv4_name = ip1.name, ip2.name - bgp1_peer, bgp2_peer = bgp1_ipv4.peers.add(), bgp2_ipv4.peers.add() - bgp1_peer.name, bgp2_peer.name = "bgp_router1", "bgp_router2" - - bgp1_peer.peer_address, bgp2_peer.peer_address = "10.10.10.2", "10.10.10.1" - bgp1_peer.as_type, bgp2_peer.as_type = "ebgp", "ebgp" - bgp1_peer.as_number, bgp2_peer.as_number = 100, 200 - - # Create & advertise loopbacks under bgp in d1 & d2 - for i in range(1, count + 1): - d1_l1 = d1.ipv4_loopbacks.add() - d1_l1.name = "d1_loopback{}".format(i) - d1_l1.eth_name = "e1" - d1_l1.address = "1.1.1.{}".format(i) - - bgp1_l1 = bgp1_peer.v4_routes.add(name="bgp_l{}".format(i)) - bgp1_l1.addresses.add(address="1.1.1.{}".format(i), prefix=32) - - for i in range(1, count + 1): - d2_l1 = d2.ipv4_loopbacks.add() - d2_l1.name = "d2_loopback{}".format(i) - d2_l1.eth_name = "e2" - d2_l1.address = "2.2.2.{}".format(i) - - bgp2_l1 = bgp2_peer.v4_routes.add(name="bgp2_l{}".format(i)) - bgp2_l1.addresses.add(address="2.2.2.{}".format(i), prefix=32) - - # Create vxlan tunnels on d1 - for i in range(1, count + 1): - d1_vxlan = d1.vxlan.v4_tunnels.add() - - d1_vxlan.vni = 1000 + i - d1_vxlan.source_interface = "d1_loopback{}".format(i) - d1_vxlan.name = "d1_vxlan{}".format(i) - - # unicast communication, Add two unicast info - vtep = d1_vxlan.destination_ip_mode.unicast.vteps.add() - vtep.remote_vtep_address = "2.2.2.{}".format(i) - vtep.arp_suppression_cache.add(edge2_macs[i], "100.1.2.{}".format(i)) - vtep.arp_suppression_cache.add("00:1b:6e:00:00:01", "1.2.0.1") - - # Create vxlan on d2 - for i in range(1, count + 1): - d2_vxlan = d2.vxlan.v4_tunnels.add() - - d2_vxlan.vni = 1000 + i - d2_vxlan.source_interface = "d2_loopback{}".format(i) - d2_vxlan.name = "d2_vxlan{}".format(i) - - # unicast communication - vtep = d2_vxlan.destination_ip_mode.unicast.vteps.add() - vtep.remote_vtep_address = "1.1.1.{}".format(i) - vtep.arp_suppression_cache.add(edge1_macs[i], "100.1.1.{}".format(i)) - vtep.arp_suppression_cache.add("00:1b:6e:00:00:01", "1.2.0.1") - - for i in range(1, count + 1): - edge1_d = config.devices.device(name="edge1_d{}".format(i))[-1] - edge2_d = config.devices.device(name="edge2_d{}".format(i))[-1] - - edge1_e = edge1_d.ethernets.ethernet()[-1] - edge2_e = edge2_d.ethernets.ethernet()[-1] - - edge1_e.connection.vxlan_name = "d1_vxlan{}".format(i) - edge2_e.connection.vxlan_name = "d2_vxlan{}".format(i) - - edge1_e.name = "edge1_e{}".format(i) - edge2_e.name = "edge2_e{}".format(i) - - edge1_e.mac = edge1_macs[i] - edge2_e.mac = edge2_macs[i] - - edge1_ip = edge1_e.ipv4_addresses.add() - edge2_ip = edge2_e.ipv4_addresses.add() - - edge1_ip.name = "edge1_ip_d{}".format(i) - edge2_ip.name = "edge2_ip_d{}".format(i) - - edge1_ip.address = "100.1.{}.1".format(i) - edge2_ip.address = "100.1.{}.2".format(i) - - edge1_ip.gateway = "100.1.{}.2".format(i) - edge2_ip.gateway = "100.1.{}.1".format(i) - - edge1_bgp, edge2_bgp = edge1_d.bgp, edge2_d.bgp - edge1_bgp.router_id = "100.1.{}.1".format(i) - edge2_bgp.router_id = "100.1.{}.2".format(i) - - edge1_bgp_ipv4 = edge1_bgp.ipv4_interfaces.add() - edge2_bgp_ipv4 = edge2_bgp.ipv4_interfaces.add() - - edge1_bgp_ipv4.ipv4_name = "edge1_ip_d{}".format(i) - edge2_bgp_ipv4.ipv4_name = "edge2_ip_d{}".format(i) - - edge1_bgp_peer = edge1_bgp_ipv4.peers.add() - edge2_bgp_peer = edge2_bgp_ipv4.peers.add() - - edge1_bgp_peer.name = "edge1_bgp{}".format(i) - edge2_bgp_peer.name = "edge2_bgp{}".format(i) - - edge1_bgp_peer.peer_address = "100.1.{}.2".format(i) - edge2_bgp_peer.peer_address = "100.1.{}.1".format(i) - - edge1_bgp_peer.as_type, edge2_bgp_peer.as_type = "ibgp", "ibgp" - edge1_bgp_peer.as_number, edge2_bgp_peer.as_number = 1000, 1000 - - edge1_bgp_rr = edge1_bgp_peer.v4_routes.add(name="A1{}".format(i)) - edge1_bgp_rr.addresses.add( - address="1.1.0.{}".format(i), count=180, prefix=32 - ) - - edge1_bgp_rr2 = edge1_bgp_peer.v4_routes.add(name="D1{}".format(i)) - edge1_bgp_rr2.addresses.add( - address="2.1.0.{}".format(i), count=1, prefix=32 - ) - - edge2_bgp_rr = edge2_bgp_peer.v4_routes.add(name="A2{}".format(i)) - edge2_bgp_rr.addresses.add( - address="3.1.0.{}".format(i), count=180, prefix=32 - ) - - edge2_bgp_rr2 = edge2_bgp_peer.v4_routes.add(name="D2{}".format(i)) - edge2_bgp_rr2.addresses.add( - address="4.1.0.{}".format(i), count=1, prefix=32 - ) - - a1_routes = ["A1{}".format(i) for i in range(1, count + 1)] - d1_routes = ["D1{}".format(i) for i in range(1, count + 1)] - - a2_routes = ["A2{}".format(i) for i in range(1, count + 1)] - d2_routes = ["D2{}".format(i) for i in range(1, count + 1)] - - flow = config.flows.flow(name="f1")[-1] - flow.tx_rx.device.tx_names = a1_routes + d1_routes - flow.tx_rx.device.rx_names = a2_routes + d2_routes - - flow.duration.fixed_packets.packets = count * 10 - - flow.metrics.enable = True - flow.metrics.loss = True - - utils.start_traffic(api, config, start_capture=False) - - assert ( - api._ixnetwork.Topology.find()[0] - .DeviceGroup.find() - .DeviceGroup.find() - .Multiplier - ) == 128 - - assert ( - api._ixnetwork.Topology.find()[0] - .DeviceGroup.find() - .DeviceGroup.find() - .DeviceGroup.find() - .Count - ) == 128 - - utils.wait_for( - lambda: results_ok(api, ["f1"], count * 10), - "stats to be as expected", - timeout_seconds=30, - ) - utils.stop_traffic(api, config) - - -def get_macs(mac, count, offset=1): - """ - Take mac as start mac returns the count of macs in a list - """ - mac_list = list() - for i in range(count + 1): - mac_address = "{:012X}".format(int(mac, 16) + offset * i) - mac_address = ":".join( - format(s, "02x") for s in bytearray.fromhex(mac_address) - ) - mac_list.append(mac_address) - return mac_list - - -def results_ok(api, flow_names, expected): - """ - Returns True if there is no traffic loss else False - """ - request = api.metrics_request() - request.flow.flow_names = flow_names - flow_results = api.get_metrics(request).flow_metrics - flow_rx = sum([f.frames_rx for f in flow_results]) - return flow_rx == expected - - -if __name__ == "__main__": - pytest.main(["-s", __file__]) +import pytest + + +def test_vxlan_b2b_scale(api, utils): + """ + 1. Create 128 loopbacks and advertise them using BGP. + 2. Create VXLAN connected to each loopback, so total 128 vxlan tunnels. + 3. Create BGP devices in VXLAN and advertise the routes. + """ + count = 128 + config = api.config() + + edge1_macs = get_macs("001801000011", count) + edge2_macs = get_macs("001601000011", count) + + p1, p2 = config.ports.port( + name="p1", location=utils.settings.ports[0] + ).port(name="p2", location=utils.settings.ports[1]) + + d1, d2 = config.devices.device(name="d1").device(name="d2") + + e1, e2 = d1.ethernets.ethernet()[-1], d2.ethernets.ethernet()[-1] + e1.port_name, e2.port_name = p1.name, p2.name + e1.name, e2.name = "e1", "e2" + e1.mac, e2.mac = "00:01:00:00:00:01", "00:01:00:00:00:02" + + ip1, ip2 = e1.ipv4_addresses.add(), e2.ipv4_addresses.add() + ip1.name, ip2.name = "ip_d1", "ip_d2" + + ip1.address, ip2.address = "10.10.10.1", "10.10.10.2" + ip1.gateway, ip2.gateway = "10.10.10.2", "10.10.10.1" + + bgp1, bgp2 = d1.bgp, d2.bgp + bgp1.router_id, bgp2.router_id = "10.10.10.1", "10.10.10.2" + bgp1_ipv4 = bgp1.ipv4_interfaces.add() + bgp2_ipv4 = bgp2.ipv4_interfaces.add() + + bgp1_ipv4.ipv4_name, bgp2_ipv4.ipv4_name = ip1.name, ip2.name + bgp1_peer, bgp2_peer = bgp1_ipv4.peers.add(), bgp2_ipv4.peers.add() + bgp1_peer.name, bgp2_peer.name = "bgp_router1", "bgp_router2" + + bgp1_peer.peer_address, bgp2_peer.peer_address = "10.10.10.2", "10.10.10.1" + bgp1_peer.as_type, bgp2_peer.as_type = "ebgp", "ebgp" + bgp1_peer.as_number, bgp2_peer.as_number = 100, 200 + + # Create & advertise loopbacks under bgp in d1 & d2 + for i in range(1, count + 1): + d1_l1 = d1.ipv4_loopbacks.add() + d1_l1.name = "d1_loopback{}".format(i) + d1_l1.eth_name = "e1" + d1_l1.address = "1.1.1.{}".format(i) + + bgp1_l1 = bgp1_peer.v4_routes.add(name="bgp_l{}".format(i)) + bgp1_l1.addresses.add(address="1.1.1.{}".format(i), prefix=32) + + for i in range(1, count + 1): + d2_l1 = d2.ipv4_loopbacks.add() + d2_l1.name = "d2_loopback{}".format(i) + d2_l1.eth_name = "e2" + d2_l1.address = "2.2.2.{}".format(i) + + bgp2_l1 = bgp2_peer.v4_routes.add(name="bgp2_l{}".format(i)) + bgp2_l1.addresses.add(address="2.2.2.{}".format(i), prefix=32) + + # Create vxlan tunnels on d1 + for i in range(1, count + 1): + d1_vxlan = d1.vxlan.v4_tunnels.add() + + d1_vxlan.vni = 1000 + i + d1_vxlan.source_interface = "d1_loopback{}".format(i) + d1_vxlan.name = "d1_vxlan{}".format(i) + + # unicast communication, Add two unicast info + vtep = d1_vxlan.destination_ip_mode.unicast.vteps.add() + vtep.remote_vtep_address = "2.2.2.{}".format(i) + vtep.arp_suppression_cache.add(edge2_macs[i], "100.1.2.{}".format(i)) + vtep.arp_suppression_cache.add("00:1b:6e:00:00:01", "1.2.0.1") + + # Create vxlan on d2 + for i in range(1, count + 1): + d2_vxlan = d2.vxlan.v4_tunnels.add() + + d2_vxlan.vni = 1000 + i + d2_vxlan.source_interface = "d2_loopback{}".format(i) + d2_vxlan.name = "d2_vxlan{}".format(i) + + # unicast communication + vtep = d2_vxlan.destination_ip_mode.unicast.vteps.add() + vtep.remote_vtep_address = "1.1.1.{}".format(i) + vtep.arp_suppression_cache.add(edge1_macs[i], "100.1.1.{}".format(i)) + vtep.arp_suppression_cache.add("00:1b:6e:00:00:01", "1.2.0.1") + + for i in range(1, count + 1): + edge1_d = config.devices.device(name="edge1_d{}".format(i))[-1] + edge2_d = config.devices.device(name="edge2_d{}".format(i))[-1] + + edge1_e = edge1_d.ethernets.ethernet()[-1] + edge2_e = edge2_d.ethernets.ethernet()[-1] + + edge1_e.connection.vxlan_name = "d1_vxlan{}".format(i) + edge2_e.connection.vxlan_name = "d2_vxlan{}".format(i) + + edge1_e.name = "edge1_e{}".format(i) + edge2_e.name = "edge2_e{}".format(i) + + edge1_e.mac = edge1_macs[i] + edge2_e.mac = edge2_macs[i] + + edge1_ip = edge1_e.ipv4_addresses.add() + edge2_ip = edge2_e.ipv4_addresses.add() + + edge1_ip.name = "edge1_ip_d{}".format(i) + edge2_ip.name = "edge2_ip_d{}".format(i) + + edge1_ip.address = "100.1.{}.1".format(i) + edge2_ip.address = "100.1.{}.2".format(i) + + edge1_ip.gateway = "100.1.{}.2".format(i) + edge2_ip.gateway = "100.1.{}.1".format(i) + + edge1_bgp, edge2_bgp = edge1_d.bgp, edge2_d.bgp + edge1_bgp.router_id = "100.1.{}.1".format(i) + edge2_bgp.router_id = "100.1.{}.2".format(i) + + edge1_bgp_ipv4 = edge1_bgp.ipv4_interfaces.add() + edge2_bgp_ipv4 = edge2_bgp.ipv4_interfaces.add() + + edge1_bgp_ipv4.ipv4_name = "edge1_ip_d{}".format(i) + edge2_bgp_ipv4.ipv4_name = "edge2_ip_d{}".format(i) + + edge1_bgp_peer = edge1_bgp_ipv4.peers.add() + edge2_bgp_peer = edge2_bgp_ipv4.peers.add() + + edge1_bgp_peer.name = "edge1_bgp{}".format(i) + edge2_bgp_peer.name = "edge2_bgp{}".format(i) + + edge1_bgp_peer.peer_address = "100.1.{}.2".format(i) + edge2_bgp_peer.peer_address = "100.1.{}.1".format(i) + + edge1_bgp_peer.as_type, edge2_bgp_peer.as_type = "ibgp", "ibgp" + edge1_bgp_peer.as_number, edge2_bgp_peer.as_number = 1000, 1000 + + edge1_bgp_rr = edge1_bgp_peer.v4_routes.add(name="A1{}".format(i)) + edge1_bgp_rr.addresses.add( + address="1.1.0.{}".format(i), count=180, prefix=32 + ) + + edge1_bgp_rr2 = edge1_bgp_peer.v4_routes.add(name="D1{}".format(i)) + edge1_bgp_rr2.addresses.add( + address="2.1.0.{}".format(i), count=1, prefix=32 + ) + + edge2_bgp_rr = edge2_bgp_peer.v4_routes.add(name="A2{}".format(i)) + edge2_bgp_rr.addresses.add( + address="3.1.0.{}".format(i), count=180, prefix=32 + ) + + edge2_bgp_rr2 = edge2_bgp_peer.v4_routes.add(name="D2{}".format(i)) + edge2_bgp_rr2.addresses.add( + address="4.1.0.{}".format(i), count=1, prefix=32 + ) + + a1_routes = ["A1{}".format(i) for i in range(1, count + 1)] + d1_routes = ["D1{}".format(i) for i in range(1, count + 1)] + + a2_routes = ["A2{}".format(i) for i in range(1, count + 1)] + d2_routes = ["D2{}".format(i) for i in range(1, count + 1)] + + flow = config.flows.flow(name="f1")[-1] + flow.tx_rx.device.tx_names = a1_routes + d1_routes + flow.tx_rx.device.rx_names = a2_routes + d2_routes + + flow.duration.fixed_packets.packets = count * 10 + + flow.metrics.enable = True + flow.metrics.loss = True + + utils.start_traffic(api, config, start_capture=False) + + assert ( + api._ixnetwork.Topology.find()[0] + .DeviceGroup.find() + .DeviceGroup.find() + .Multiplier + ) == 128 + + assert ( + api._ixnetwork.Topology.find()[0] + .DeviceGroup.find() + .DeviceGroup.find() + .DeviceGroup.find() + .Count + ) == 128 + + utils.wait_for( + lambda: results_ok(api, ["f1"], count * 10), + "stats to be as expected", + timeout_seconds=30, + ) + utils.stop_traffic(api, config) + + +def get_macs(mac, count, offset=1): + """ + Take mac as start mac returns the count of macs in a list + """ + mac_list = list() + for i in range(count + 1): + mac_address = "{:012X}".format(int(mac, 16) + offset * i) + mac_address = ":".join( + format(s, "02x") for s in bytearray.fromhex(mac_address) + ) + mac_list.append(mac_address) + return mac_list + + +def results_ok(api, flow_names, expected): + """ + Returns True if there is no traffic loss else False + """ + request = api.metrics_request() + request.flow.flow_names = flow_names + flow_results = api.get_metrics(request).flow_metrics + flow_rx = sum([f.frames_rx for f in flow_results]) + return flow_rx == expected + + +if __name__ == "__main__": + pytest.main(["-s", __file__])