From 60e87137c549e29fd9cf57a40a3290983d7424ab Mon Sep 17 00:00:00 2001 From: desaimg1 Date: Mon, 29 May 2023 19:49:27 +0530 Subject: [PATCH 01/49] Worked on following issues: 1. Modified warnings as per latest model 2. Added set_control_state and set_control_action as per the latest model 3. Added get_version API --- snappi_ixnetwork/ping.py | 10 +- snappi_ixnetwork/protocolmetrics.py | 4 +- snappi_ixnetwork/snappi_api.py | 206 +++++++++++++--------------- tests/bgp/test_bgpv4_stats.py | 3 +- tests/ping/test_ping.py | 38 ++--- tests/utils/common.py | 42 +++--- 6 files changed, 141 insertions(+), 162 deletions(-) diff --git a/snappi_ixnetwork/ping.py b/snappi_ixnetwork/ping.py index e312ebe48..96752d3b2 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,9 @@ 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 + #req_type = endpoint.parent.choice src_name = endpoint.get("src_name") dst_ip = endpoint.get("dst_ip") if req_type == "ipv4": @@ -71,9 +71,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..b782bbfc2 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,136 +303,94 @@ def _protocols_exists(self): return True else: return False - - def set_protocol_state(self, payload): - """Set the transmit state of flows""" + + def set_control_state(self, payload): try: - if isinstance(payload, (type(self._protocol_state), str)) is False: - raise TypeError( - "The content must be of type Union[TransmitState, str]" - ) - if isinstance(payload, str) is True: - payload = self._protocol_state.deserialize(payload) + 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() - with Timer(self, "Setting Protocol state"): - self.ngpf.set_protocol_state(payload) + 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_transmit_state(self, payload): - """Set the transmit state of flows""" + + def set_control_action(self, payload): try: - if isinstance(payload, (type(self._transmit_state), str)) is False: - raise TypeError( - "The content must be of type Union[TransmitState, str]" - ) - if isinstance(payload, str) is True: - payload = self._transmit_state.deserialize(payload) - self._connect() - self.traffic_item.transmit(payload) + 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) - return self._request_detail() + + 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" + ) + + 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" + ) def set_link_state(self, link_state): - try: - if isinstance(link_state, (type(self._link_state), str)) is False: - raise TypeError( - "The content must be of type Union[LinkState, str]" - ) - if isinstance(link_state, str): - link_state = self._link_state.deserialize(link_state) - self._connect() - if link_state.port_names is not None: - self.vport.set_link_state(link_state) - except Exception as err: - raise SnappiIxnException(err) - return self._request_detail() + self.add_warnings( + "set_link_state api is deprecated, Please use `set_control_state` with `port.link` choice instead" + ) def set_capture_state(self, payload): """Starts capture on all ports that have capture enabled.""" - try: - if isinstance(payload, (type(self._capture_state), str)) is False: - raise TypeError( - "The content must be of type Union[CaptureState, str]" - ) - if isinstance(payload, str) is True: - payload = self._capture_state.deserialize(payload) - self._connect() - self.capture.set_capture_state(payload) - except Exception as err: - raise SnappiIxnException(err) - return self._request_detail() + self.add_warnings( + "set_capture_state api is deprecated, Please use `set_control_state` with `port.capture` choice instead" + ) def set_route_state(self, payload): - try: - route_state = self.route_state() - if isinstance(payload, (type(route_state), str)) is False: - raise TypeError( - "The content must be of type Union[RouteState, str]" - ) - if isinstance(payload, str) is True: - payload = route_state.deserialize(payload) - self._connect() - with Timer(self, "Setting route state"): - self.ngpf.set_route_state(payload) - return self._request_detail() - except Exception as err: - raise SnappiIxnException(err) + self.add_warnings( + "set_route_state api is deprecated, Please use `set_control_state` with `protocol.all` choice instead" + ) def set_device_state(self, payload): - try: - device_state = self.device_state() - if isinstance(payload, (type(device_state), str)) is False: - raise TypeError( - "The content must be of type Union[DeviceState, str]" - ) - if isinstance(payload, str) is True: - payload = device_state.deserialize(payload) - self._connect() - with Timer(self, "Setting device state"): - self.ngpf.set_device_state(payload) - return self._request_detail() - except Exception as err: - raise SnappiIxnException(err) + self.add_warnings( + "set_device_state api is deprecated, Please use `set_control_state` with `protocol.link` choice instead" + ) def send_ping(self, ping_request, cvg_api=None): - try: - if cvg_api: - if isinstance(ping_request, type(cvg_api.ping_request())): - if ( - isinstance( - ping_request, (type(cvg_api.ping_request()), str) - ) - is False - ): - raise TypeError( - "The content must be of type Union[PingRequest, str]" - ) - if isinstance(ping_request, str): - ping_request = cvg_api.ping_request().deserialize( - ping_request - ) - ping_res = cvg_api.ping_response() - cvg_api.ping_request().serialize() - else: - if ( - isinstance(ping_request, (type(self._ping_request), str)) - is False - ): - raise TypeError( - "The content must be of type Union[PingRequest, str]" - ) - if isinstance(ping_request, str): - ping_request = self._ping_request.deserialize(ping_request) - ping_res = self.ping_response() - ping_request.serialize() - self._connect() - ping_res.responses.deserialize(self.ping.results(ping_request)) - return ping_res - except Exception as err: - raise SnappiIxnException(err) + self.add_warnings( + "send_ping api is deprecated, Please use `set_control_action` with `protocol.ipv4.ping` choice instead" + ) def get_capture(self, request): """Gets capture file and returns it as a byte stream""" @@ -1135,4 +1095,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/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/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)) From 15b574028269a79ad06ab0e91f2b2bafb8b1a1f6 Mon Sep 17 00:00:00 2001 From: desaimg1 Date: Mon, 26 Jun 2023 11:03:11 +0530 Subject: [PATCH 02/49] Comment from vibaswan addressed --- snappi_ixnetwork/ping.py | 1 - 1 file changed, 1 deletion(-) diff --git a/snappi_ixnetwork/ping.py b/snappi_ixnetwork/ping.py index 96752d3b2..5cb1bf7f3 100644 --- a/snappi_ixnetwork/ping.py +++ b/snappi_ixnetwork/ping.py @@ -35,7 +35,6 @@ def results(self, req_type, ping_request): with Timer(self._api, "Ping requests completed in"): 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": From a48c3e432772561f4aa115488a53a643bdf349ce Mon Sep 17 00:00:00 2001 From: desaimg1 Date: Mon, 26 Jun 2023 12:36:36 +0530 Subject: [PATCH 03/49] Added backward compatabilty code back --- snappi_ixnetwork/snappi_api.py | 114 +++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/snappi_ixnetwork/snappi_api.py b/snappi_ixnetwork/snappi_api.py index b782bbfc2..943dc5349 100644 --- a/snappi_ixnetwork/snappi_api.py +++ b/snappi_ixnetwork/snappi_api.py @@ -359,38 +359,152 @@ def set_protocol_state(self, payload): 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( + "The content must be of type Union[TransmitState, str]" + ) + if isinstance(payload, str) is True: + payload = self._protocol_state.deserialize(payload) + self._connect() + with Timer(self, "Setting Protocol state"): + self.ngpf.set_protocol_state(payload) + except Exception as err: + raise SnappiIxnException(err) + return self._request_detail() 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( + "The content must be of type Union[TransmitState, str]" + ) + if isinstance(payload, str) is True: + payload = self._transmit_state.deserialize(payload) + self._connect() + self.traffic_item.transmit(payload) + except Exception as err: + raise SnappiIxnException(err) + 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( + "The content must be of type Union[LinkState, str]" + ) + if isinstance(link_state, str): + link_state = self._link_state.deserialize(link_state) + self._connect() + if link_state.port_names is not None: + self.vport.set_link_state(link_state) + except Exception as err: + raise SnappiIxnException(err) + return self._request_detail() 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( + "The content must be of type Union[CaptureState, str]" + ) + if isinstance(payload, str) is True: + payload = self._capture_state.deserialize(payload) + self._connect() + self.capture.set_capture_state(payload) + except Exception as err: + raise SnappiIxnException(err) + 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: + raise TypeError( + "The content must be of type Union[RouteState, str]" + ) + if isinstance(payload, str) is True: + payload = route_state.deserialize(payload) + self._connect() + with Timer(self, "Setting route state"): + self.ngpf.set_route_state(payload) + return self._request_detail() + except Exception as err: + 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: + raise TypeError( + "The content must be of type Union[DeviceState, str]" + ) + if isinstance(payload, str) is True: + payload = device_state.deserialize(payload) + self._connect() + with Timer(self, "Setting device state"): + self.ngpf.set_device_state(payload) + return self._request_detail() + except Exception as err: + 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())): + if ( + isinstance( + ping_request, (type(cvg_api.ping_request()), str) + ) + is False + ): + raise TypeError( + "The content must be of type Union[PingRequest, str]" + ) + if isinstance(ping_request, str): + ping_request = cvg_api.ping_request().deserialize( + ping_request + ) + ping_res = cvg_api.ping_response() + cvg_api.ping_request().serialize() + else: + if ( + isinstance(ping_request, (type(self._ping_request), str)) + is False + ): + raise TypeError( + "The content must be of type Union[PingRequest, str]" + ) + if isinstance(ping_request, str): + ping_request = self._ping_request.deserialize(ping_request) + ping_res = self.ping_response() + ping_request.serialize() + self._connect() + ping_res.responses.deserialize(self.ping.results(ping_request)) + return ping_res + except Exception as err: + raise SnappiIxnException(err) + def get_capture(self, request): """Gets capture file and returns it as a byte stream""" From 46cf92ade1c476e27b399d2ec15bb898e5270326 Mon Sep 17 00:00:00 2001 From: desaimg1 Date: Mon, 26 Jun 2023 13:29:41 +0530 Subject: [PATCH 04/49] updated snappi-ixnetwork version --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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", From 7fa925eb1ce110d9d19005f72521dcd394183b22 Mon Sep 17 00:00:00 2001 From: Ashutosh Kumar Date: Tue, 25 Jul 2023 14:52:22 +0530 Subject: [PATCH 05/49] updated runner details --- do.py | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) 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", From 6602e436cfd55822166dc433428a2cb6459ce0ad Mon Sep 17 00:00:00 2001 From: Ashutosh Kumar Date: Tue, 25 Jul 2023 14:52:51 +0530 Subject: [PATCH 06/49] updated runner details --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 584e6309f..6d516bf3d 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -7,7 +7,7 @@ on: jobs: cicd: - runs-on: [self-hosted, Linux, Ubuntu, x64] + runs-on: [snappi-ixn-ci-novus100g] strategy: max-parallel: 1 matrix: From ef483b90687dd243aac600629174ba862be74c8b Mon Sep 17 00:00:00 2001 From: Ashutosh Kumar Date: Tue, 25 Jul 2023 14:56:09 +0530 Subject: [PATCH 07/49] removed support for python2 --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 6d516bf3d..81f846a93 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -11,7 +11,7 @@ jobs: strategy: max-parallel: 1 matrix: - python-version: [python27, python38] + python-version: [python38] steps: - name: Checkout source From 4200ce69b711a182cdb261e53624974f0ff40a2c Mon Sep 17 00:00:00 2001 From: Ashutosh Kumar Date: Tue, 25 Jul 2023 15:09:58 +0530 Subject: [PATCH 08/49] update python binary path --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 81f846a93..4de74ea24 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -22,7 +22,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::python3" - name: Install dependencies run: | rm -rf .env From 4bf13af613796fd36f305e87123b47715123c7aa Mon Sep 17 00:00:00 2001 From: Ashutosh Kumar Date: Tue, 25 Jul 2023 15:14:21 +0530 Subject: [PATCH 09/49] updated python to point to virtualenv --- .github/workflows/publish.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 4de74ea24..7547e8054 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -8,11 +8,6 @@ on: jobs: cicd: runs-on: [snappi-ixn-ci-novus100g] - strategy: - max-parallel: 1 - matrix: - python-version: [python38] - 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::python3" + run: echo "::set-output name=pythonv::/home/github-runner/pyenv/.env/bin/python" - name: Install dependencies run: | rm -rf .env From d7f728bd6fbfdb557ee5978d6ebb293adde1c6dd Mon Sep 17 00:00:00 2001 From: Ashutosh Kumar Date: Tue, 25 Jul 2023 10:11:49 +0000 Subject: [PATCH 10/49] removed bad chars --- readme.md | 2 +- tests/bgp_evpn/test_bgp_evpn.py | 360 ++++---- .../test_bgp_evpn_attribute_validation.py | 856 +++++++++--------- .../test_bgpv6_evpn_attribute_validation.py | 856 +++++++++--------- tests/test_issue_microsoft.py | 376 ++++---- tests/vxlan/test_manual_gateway_mac.py | 414 ++++----- tests/vxlan/test_vxlan_b2b_scale.py | 458 +++++----- 7 files changed, 1661 insertions(+), 1661 deletions(-) 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/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/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/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__]) From e075606a8ca9d23ef69f791d5e78d971edd66dbc Mon Sep 17 00:00:00 2001 From: vhowdhur Date: Tue, 25 Jul 2023 18:19:09 +0530 Subject: [PATCH 11/49] trying to correct tests --- snappi_ixnetwork/snappi_api.py | 16 ++++++++++++++++ tests/conftest.py | 2 ++ 2 files changed, 18 insertions(+) diff --git a/snappi_ixnetwork/snappi_api.py b/snappi_ixnetwork/snappi_api.py index 943dc5349..073380ae4 100644 --- a/snappi_ixnetwork/snappi_api.py +++ b/snappi_ixnetwork/snappi_api.py @@ -138,6 +138,22 @@ def get_device_encap(self, name): def set_device_encap(self, name, type): self._device_encap[name] = type + @property + def username(self): + return self._username + + @username.setter + def username(self, value): + self._username = value + + @property + def password(self): + return self._password + + @username.setter + def password(self, value): + self._password = value + @property def assistant(self): return self._assistant diff --git a/tests/conftest.py b/tests/conftest.py index cd88fb691..f9dc4afe7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -73,6 +73,8 @@ def api(): api = snappi.api( location=utl.settings.location, ext=utl.settings.ext ) + api.username = "admin" + api.password = "1x14c0m!X!$C)M" yield api if getattr(api, "assistant", None) is not None: api.assistant.Session.remove() From 19f3538a0168c35a458acbec7cdeac8c06854510 Mon Sep 17 00:00:00 2001 From: vhowdhur Date: Tue, 25 Jul 2023 18:50:16 +0530 Subject: [PATCH 12/49] modify test --- tests/test_logger.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test_logger.py b/tests/test_logger.py index 10f81af4e..b00b8f579 100644 --- a/tests/test_logger.py +++ b/tests/test_logger.py @@ -13,6 +13,9 @@ def test_mac_addrs(b2b_raw_config_vports): loglevel=logging.DEBUG ) + api.username = "admin" + api.password = "1x14c0m!X!$C)M" + api.set_config(b2b_raw_config_vports) assert api.log_level == logging.DEBUG From 04a323381755dbca729c757c0a827548d93eee34 Mon Sep 17 00:00:00 2001 From: vhowdhur Date: Tue, 25 Jul 2023 19:46:25 +0530 Subject: [PATCH 13/49] exposing username and password --- .github/workflows/publish.yml | 2 +- do.py | 9 ++++++++- tests/conftest.py | 5 ++--- tests/settings.json | 3 ++- tests/test_logger.py | 2 +- tests/utils/common.py | 5 +++++ 6 files changed, 19 insertions(+), 7 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 7547e8054..f9dcc36c8 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -34,7 +34,7 @@ jobs: ${{steps.path.outputs.pythonv}} do.py init - name: Run tests run: | - ${{steps.path.outputs.pythonv}} do.py test + ${{steps.path.outputs.pythonv}} do.py test ${{secrets.TEST_USERNAME}} ${{secrets.TEST_PASSWORD}} - name: Get package version id: get_version run: | diff --git a/do.py b/do.py index 9b7f7116e..8c5c54c17 100644 --- a/do.py +++ b/do.py @@ -35,7 +35,7 @@ def lint(): ) -def test(): +def test(username=None, password=None): coverage_threshold = 67 args = [ '--location="https://snappi-ixn-ci-novus100g.lbj.is.keysight.com:5000"', @@ -52,6 +52,13 @@ def test(): "--cov=./snappi_ixnetwork --cov-report term" " --cov-report html:cov_report", ] + + if username is not None: + args.append("--username=" + username) + if password is not None: + args.append("--password=" + password) + print(args) + return run( [ py() + " -m pip install pytest-cov", diff --git a/tests/conftest.py b/tests/conftest.py index f9dc4afe7..d416b0c5a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -73,8 +73,7 @@ def api(): api = snappi.api( location=utl.settings.location, ext=utl.settings.ext ) - api.username = "admin" - api.password = "1x14c0m!X!$C)M" + utl.configure_credentials(api, utl.settings.username, utl.settings.password) yield api if getattr(api, "assistant", None) is not None: api.assistant.Session.remove() @@ -86,7 +85,7 @@ def cvg_api(): api = snappi_convergence.api( location=utl.settings.location, ext=utl.settings.ext ) - + utl.configure_credentials(api, utl.settings.username, utl.settings.password) yield api if getattr(api, "assistant", None) is not None: api.assistant.Session.remove() diff --git a/tests/settings.json b/tests/settings.json index aa4d6c6f2..1b42689a9 100644 --- a/tests/settings.json +++ b/tests/settings.json @@ -1,5 +1,6 @@ { - "username": "common", + "username": "admin", + "password": "admin", "location": "https://localhost:443", "ports": [ "localhost;1;1", diff --git a/tests/test_logger.py b/tests/test_logger.py index b00b8f579..a1434a17a 100644 --- a/tests/test_logger.py +++ b/tests/test_logger.py @@ -12,7 +12,7 @@ def test_mac_addrs(b2b_raw_config_vports): ext=utl.settings.ext, loglevel=logging.DEBUG ) - + utl.configure_credentials(api, utl.settings.username, utl.settings.password) api.username = "admin" api.password = "1x14c0m!X!$C)M" diff --git a/tests/utils/common.py b/tests/utils/common.py index 7784e9dc1..313cdc3af 100644 --- a/tests/utils/common.py +++ b/tests/utils/common.py @@ -61,6 +61,10 @@ def load_dict_from_json_file(path): return json.load(fp, object_hook=byteify) +def configure_credentials(api, usr, psd): + api.username = usr + api.password = psd + class Settings(object): """ Singleton for global settings @@ -69,6 +73,7 @@ class Settings(object): def __init__(self): # these not be defined and are here only for documentation self.username = None + self.password = None self.location = None self.ports = None self.speed = None From 0fa37a5bc8fc2a1215a8b4d73b4aed21dd50a54e Mon Sep 17 00:00:00 2001 From: vhowdhur Date: Tue, 25 Jul 2023 19:54:42 +0530 Subject: [PATCH 14/49] bug fix --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f9dcc36c8..d2cfcbea2 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -34,7 +34,7 @@ jobs: ${{steps.path.outputs.pythonv}} do.py init - name: Run tests run: | - ${{steps.path.outputs.pythonv}} do.py test ${{secrets.TEST_USERNAME}} ${{secrets.TEST_PASSWORD}} + ${{steps.path.outputs.pythonv}} do.py test ${{secrets.TEST_USERNAME}} "${{secrets.TEST_PASSWORD}}" - name: Get package version id: get_version run: | From 3c7881ed56ed8606ad7cd61d97964e50fb3509ce Mon Sep 17 00:00:00 2001 From: vhowdhur Date: Tue, 25 Jul 2023 20:00:59 +0530 Subject: [PATCH 15/49] bug fix --- do.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/do.py b/do.py index 8c5c54c17..794dd27ee 100644 --- a/do.py +++ b/do.py @@ -57,8 +57,7 @@ def test(username=None, password=None): args.append("--username=" + username) if password is not None: args.append("--password=" + password) - print(args) - return + run( [ py() + " -m pip install pytest-cov", From 0819f54f8fc0ee256d305828d3c6cc3fbaf03f75 Mon Sep 17 00:00:00 2001 From: vhowdhur Date: Tue, 25 Jul 2023 20:04:22 +0530 Subject: [PATCH 16/49] bug fix --- do.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/do.py b/do.py index 794dd27ee..88b0653e8 100644 --- a/do.py +++ b/do.py @@ -56,7 +56,7 @@ def test(username=None, password=None): if username is not None: args.append("--username=" + username) if password is not None: - args.append("--password=" + password) + args.append("--password=\"" + password + "\"") run( [ From 3186ea59145ef2a3320aa901e4e277a714de7e29 Mon Sep 17 00:00:00 2001 From: vhowdhur Date: Tue, 25 Jul 2023 20:27:21 +0530 Subject: [PATCH 17/49] bug fix --- .github/workflows/publish.yml | 2 +- do.py | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d2cfcbea2..998acd903 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -34,7 +34,7 @@ jobs: ${{steps.path.outputs.pythonv}} do.py init - name: Run tests run: | - ${{steps.path.outputs.pythonv}} do.py test ${{secrets.TEST_USERNAME}} "${{secrets.TEST_PASSWORD}}" + TEST_USERNAME=admin TEST_PASSWORD="1x14c0m!X!$C)M" ${{steps.path.outputs.pythonv}} do.py test - name: Get package version id: get_version run: | diff --git a/do.py b/do.py index 88b0653e8..85a18d1d2 100644 --- a/do.py +++ b/do.py @@ -35,8 +35,10 @@ def lint(): ) -def test(username=None, password=None): +def test(): coverage_threshold = 67 + username = os.environ.get("PYPI_USERNAME", "admin") + password = os.environ.get("PYPI_PASSWORD", "admin") args = [ '--location="https://snappi-ixn-ci-novus100g.lbj.is.keysight.com:5000"', ( @@ -45,18 +47,16 @@ def test(username=None, password=None): " snappi-ixn-ci-novus100g.lbj.is.keysight.com;1;5" ' snappi-ixn-ci-novus100g.lbj.is.keysight.com;1;6"' ), + "--username="+username, + "--password=\""+password+"\"" "--ext=ixnetwork", "--speed=speed_100_gbps", - "tests", + "tests/test_pretest.py", '-m "not e2e and not l1_manual and not uhd"', "--cov=./snappi_ixnetwork --cov-report term" " --cov-report html:cov_report", ] - - if username is not None: - args.append("--username=" + username) - if password is not None: - args.append("--password=\"" + password + "\"") + print(args) run( [ From 25c639eca52914b8e9994f11a0fde9d62e37e4bc Mon Sep 17 00:00:00 2001 From: vhowdhur Date: Tue, 25 Jul 2023 20:30:58 +0530 Subject: [PATCH 18/49] bug fix --- do.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/do.py b/do.py index 85a18d1d2..2d7f5a415 100644 --- a/do.py +++ b/do.py @@ -48,7 +48,7 @@ def test(): ' snappi-ixn-ci-novus100g.lbj.is.keysight.com;1;6"' ), "--username="+username, - "--password=\""+password+"\"" + "--password=\""+password+"\"", "--ext=ixnetwork", "--speed=speed_100_gbps", "tests/test_pretest.py", From ce17e1e58e6780cf3e72c566da990caf4e927c10 Mon Sep 17 00:00:00 2001 From: vhowdhur Date: Tue, 25 Jul 2023 20:34:16 +0530 Subject: [PATCH 19/49] bug fix --- do.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/do.py b/do.py index 2d7f5a415..80e35995d 100644 --- a/do.py +++ b/do.py @@ -37,8 +37,8 @@ def lint(): def test(): coverage_threshold = 67 - username = os.environ.get("PYPI_USERNAME", "admin") - password = os.environ.get("PYPI_PASSWORD", "admin") + username = os.environ.get("TEST_USERNAME", "admin") + password = os.environ.get("TEST_PASSWORD", "admin") args = [ '--location="https://snappi-ixn-ci-novus100g.lbj.is.keysight.com:5000"', ( From e95b5c8f5d060e16a7d142b2c5c80597971202af Mon Sep 17 00:00:00 2001 From: vhowdhur Date: Tue, 25 Jul 2023 20:41:18 +0530 Subject: [PATCH 20/49] trying by disabling shell --- do.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/do.py b/do.py index 80e35995d..1e762badd 100644 --- a/do.py +++ b/do.py @@ -62,7 +62,7 @@ def test(): [ py() + " -m pip install pytest-cov", py() + " -m pytest -sv {}".format(" ".join(args)), - ] + ], shell=False ) import re @@ -213,7 +213,7 @@ def py(): return py.path -def run(commands): +def run(commands, shell=True): """ Executes a list of commands in a native shell and raises exception upon failure. @@ -223,7 +223,7 @@ def run(commands): print(cmd) if sys.platform != "win32": cmd = cmd.encode("utf-8", errors="ignore") - subprocess.check_call(cmd, shell=True) + subprocess.check_call(cmd, shell=shell) except Exception: sys.exit(1) From 0f1dd178b744f2974a641df52c50930ecd58c79c Mon Sep 17 00:00:00 2001 From: vhowdhur Date: Tue, 25 Jul 2023 20:45:08 +0530 Subject: [PATCH 21/49] trying by disabling shell --- do.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/do.py b/do.py index 1e762badd..aec064c70 100644 --- a/do.py +++ b/do.py @@ -58,12 +58,8 @@ def test(): ] print(args) - run( - [ - py() + " -m pip install pytest-cov", - py() + " -m pytest -sv {}".format(" ".join(args)), - ], shell=False - ) + run([py() + " -m pip install pytest-cov"]) + run([py() + " -m pytest -sv {}".format(" ".join(args))],shell=False) import re with open("./cov_report/index.html") as fp: From 22e81bde6dc8957cf7aef4744e93256cf0218c57 Mon Sep 17 00:00:00 2001 From: vhowdhur Date: Tue, 25 Jul 2023 20:51:53 +0530 Subject: [PATCH 22/49] change back to original --- do.py | 12 ++++++++---- tests/conftest.py | 4 ++-- tests/settings.json | 2 +- tests/test_logger.py | 4 +--- tests/utils/common.py | 2 +- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/do.py b/do.py index aec064c70..80e35995d 100644 --- a/do.py +++ b/do.py @@ -58,8 +58,12 @@ def test(): ] print(args) - run([py() + " -m pip install pytest-cov"]) - run([py() + " -m pytest -sv {}".format(" ".join(args))],shell=False) + run( + [ + py() + " -m pip install pytest-cov", + py() + " -m pytest -sv {}".format(" ".join(args)), + ] + ) import re with open("./cov_report/index.html") as fp: @@ -209,7 +213,7 @@ def py(): return py.path -def run(commands, shell=True): +def run(commands): """ Executes a list of commands in a native shell and raises exception upon failure. @@ -219,7 +223,7 @@ def run(commands, shell=True): print(cmd) if sys.platform != "win32": cmd = cmd.encode("utf-8", errors="ignore") - subprocess.check_call(cmd, shell=shell) + subprocess.check_call(cmd, shell=True) except Exception: sys.exit(1) diff --git a/tests/conftest.py b/tests/conftest.py index d416b0c5a..8fd61ea04 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -73,7 +73,7 @@ def api(): api = snappi.api( location=utl.settings.location, ext=utl.settings.ext ) - utl.configure_credentials(api, utl.settings.username, utl.settings.password) + utl.configure_credentials(api, utl.settings.username, utl.settings.psd) yield api if getattr(api, "assistant", None) is not None: api.assistant.Session.remove() @@ -85,7 +85,7 @@ def cvg_api(): api = snappi_convergence.api( location=utl.settings.location, ext=utl.settings.ext ) - utl.configure_credentials(api, utl.settings.username, utl.settings.password) + utl.configure_credentials(api, utl.settings.username, utl.settings.psd) yield api if getattr(api, "assistant", None) is not None: api.assistant.Session.remove() diff --git a/tests/settings.json b/tests/settings.json index 1b42689a9..42ed1ed2c 100644 --- a/tests/settings.json +++ b/tests/settings.json @@ -1,6 +1,6 @@ { "username": "admin", - "password": "admin", + "psd": "admin", "location": "https://localhost:443", "ports": [ "localhost;1;1", diff --git a/tests/test_logger.py b/tests/test_logger.py index a1434a17a..af5ccf3cd 100644 --- a/tests/test_logger.py +++ b/tests/test_logger.py @@ -12,9 +12,7 @@ def test_mac_addrs(b2b_raw_config_vports): ext=utl.settings.ext, loglevel=logging.DEBUG ) - utl.configure_credentials(api, utl.settings.username, utl.settings.password) - api.username = "admin" - api.password = "1x14c0m!X!$C)M" + utl.configure_credentials(api, utl.settings.username, utl.settings.psd) api.set_config(b2b_raw_config_vports) assert api.log_level == logging.DEBUG diff --git a/tests/utils/common.py b/tests/utils/common.py index 313cdc3af..b0b8e271f 100644 --- a/tests/utils/common.py +++ b/tests/utils/common.py @@ -73,7 +73,7 @@ class Settings(object): def __init__(self): # these not be defined and are here only for documentation self.username = None - self.password = None + self.psd = None self.location = None self.ports = None self.speed = None From 3162c8aefc0f6d7160d249ce073daa5a0522d163 Mon Sep 17 00:00:00 2001 From: vhowdhur Date: Tue, 25 Jul 2023 20:54:42 +0530 Subject: [PATCH 23/49] bug fix --- do.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/do.py b/do.py index 80e35995d..6774fc66c 100644 --- a/do.py +++ b/do.py @@ -48,7 +48,7 @@ def test(): ' snappi-ixn-ci-novus100g.lbj.is.keysight.com;1;6"' ), "--username="+username, - "--password=\""+password+"\"", + "--psd=\""+password+"\"", "--ext=ixnetwork", "--speed=speed_100_gbps", "tests/test_pretest.py", From 48218666343d679e0f4bc4b16f959d9a2b8ef7e1 Mon Sep 17 00:00:00 2001 From: vhowdhur Date: Tue, 25 Jul 2023 20:58:41 +0530 Subject: [PATCH 24/49] bug fix --- .github/workflows/publish.yml | 2 +- do.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 998acd903..e93a80fa0 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -34,7 +34,7 @@ jobs: ${{steps.path.outputs.pythonv}} do.py init - name: Run tests run: | - TEST_USERNAME=admin TEST_PASSWORD="1x14c0m!X!$C)M" ${{steps.path.outputs.pythonv}} do.py test + TEST_USERNAME=${{secrets.TEST_USERNAME}} ${{steps.path.outputs.pythonv}} do.py test - name: Get package version id: get_version run: | diff --git a/do.py b/do.py index 6774fc66c..9980e27c5 100644 --- a/do.py +++ b/do.py @@ -38,7 +38,7 @@ def lint(): def test(): coverage_threshold = 67 username = os.environ.get("TEST_USERNAME", "admin") - password = os.environ.get("TEST_PASSWORD", "admin") + password = os.environ.get("TEST_PASSWORD", "1x14c0m!X!$C)M") args = [ '--location="https://snappi-ixn-ci-novus100g.lbj.is.keysight.com:5000"', ( From 4291e4766f4b0c923ea5a70bf39c55d4786ee186 Mon Sep 17 00:00:00 2001 From: vhowdhur Date: Tue, 25 Jul 2023 21:03:29 +0530 Subject: [PATCH 25/49] bug fix --- do.py | 2 -- tests/settings.json | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/do.py b/do.py index 9980e27c5..1d0fe15d8 100644 --- a/do.py +++ b/do.py @@ -38,7 +38,6 @@ def lint(): def test(): coverage_threshold = 67 username = os.environ.get("TEST_USERNAME", "admin") - password = os.environ.get("TEST_PASSWORD", "1x14c0m!X!$C)M") args = [ '--location="https://snappi-ixn-ci-novus100g.lbj.is.keysight.com:5000"', ( @@ -48,7 +47,6 @@ def test(): ' snappi-ixn-ci-novus100g.lbj.is.keysight.com;1;6"' ), "--username="+username, - "--psd=\""+password+"\"", "--ext=ixnetwork", "--speed=speed_100_gbps", "tests/test_pretest.py", diff --git a/tests/settings.json b/tests/settings.json index 42ed1ed2c..a341f61be 100644 --- a/tests/settings.json +++ b/tests/settings.json @@ -1,6 +1,6 @@ { "username": "admin", - "psd": "admin", + "psd": "1x14c0m!X!$C)M", "location": "https://localhost:443", "ports": [ "localhost;1;1", From f8e08a632176597606982104187e686c3a5e37f9 Mon Sep 17 00:00:00 2001 From: vhowdhur Date: Tue, 25 Jul 2023 21:10:03 +0530 Subject: [PATCH 26/49] enabling whole test --- .github/workflows/publish.yml | 2 +- do.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index e93a80fa0..4f1c3cbd1 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -70,7 +70,7 @@ jobs: ${{steps.path.outputs.pythonv}} do.py install_requests ${{steps.path.outputs.pythonv}} ${{steps.path.outputs.pythonv}} do.py check_release_flag ${{ steps.release.outputs.release_flag }} ${{ steps.get_version.outputs.version }} cicd_snappitest: - runs-on: [self-hosted, Linux, Ubuntu, x64] + runs-on: [snappi-ixn-ci-novus100g] needs: cicd steps: - name: Trigger CI/CD snappi-tests diff --git a/do.py b/do.py index 1d0fe15d8..3b7ebaa98 100644 --- a/do.py +++ b/do.py @@ -49,7 +49,7 @@ def test(): "--username="+username, "--ext=ixnetwork", "--speed=speed_100_gbps", - "tests/test_pretest.py", + "tests", '-m "not e2e and not l1_manual and not uhd"', "--cov=./snappi_ixnetwork --cov-report term" " --cov-report html:cov_report", From dc46671a8133c7e0c2f66441df7d2bcb6113f9e0 Mon Sep 17 00:00:00 2001 From: vhowdhur Date: Tue, 25 Jul 2023 21:55:16 +0530 Subject: [PATCH 27/49] linting python code and handling snappi_convergence --- do.py | 10 +- snappi_ixnetwork/capture.py | 6 +- snappi_ixnetwork/device/base.py | 92 +++-- snappi_ixnetwork/device/bgp.py | 78 +++-- snappi_ixnetwork/device/bgpevpn.py | 223 ++++++------ snappi_ixnetwork/device/compactor.py | 27 +- snappi_ixnetwork/device/createixnconfig.py | 37 +- snappi_ixnetwork/device/interface.py | 25 +- snappi_ixnetwork/device/loopbackint.py | 55 +-- snappi_ixnetwork/device/ngpf.py | 208 ++++++----- snappi_ixnetwork/device/utils.py | 16 +- snappi_ixnetwork/device/vxlan.py | 70 ++-- snappi_ixnetwork/lag.py | 15 +- snappi_ixnetwork/logger.py | 10 +- snappi_ixnetwork/objectdb.py | 19 +- snappi_ixnetwork/protocolmetrics.py | 2 +- snappi_ixnetwork/snappi_api.py | 115 +++--- snappi_ixnetwork/snappi_convergence_api.py | 1 - snappi_ixnetwork/trafficitem.py | 34 +- snappi_ixnetwork/validation.py | 4 +- snappi_ixnetwork/vport.py | 27 +- tests/arp/test_arp_packet.py | 43 ++- tests/arp/test_arp_packet_e2e.py | 12 +- tests/bgp/test_bgp_attributes.py | 10 +- tests/bgp/test_bgp_sr_te_1000_policies.py | 1 + tests/bgp/test_bgp_sr_te_policy_v4v6.py | 1 + tests/bgp/test_bgp_sr_te_weighted.py | 1 + tests/bgp/test_bgpv4_stats.py | 2 +- tests/bgp_evpn/test_bgp_evpn.py | 112 +++--- .../test_bgp_evpn_attribute_validation.py | 324 +++++++++-------- .../test_bgpv6_evpn_attribute_validation.py | 327 ++++++++++-------- tests/capture/test_capture_control.py | 2 +- tests/conftest.py | 10 +- tests/convergence/bgp_convergence_config.py | 12 +- tests/errors/test_errors.py | 4 +- tests/ipv6/test_ipv6_fields.py | 3 +- tests/loopback/test_loopback_interface.py | 8 +- tests/pfc/test_global_pause_e2e.py | 2 +- tests/pfc/test_global_unpause_e2e.py | 4 +- tests/pfc/test_pfc_pause_e2e.py | 2 +- tests/pfc/test_pfc_unpause_e2e.py | 4 +- tests/ping/test_ping.py | 15 +- tests/test_compact.py | 1 - tests/test_device_connection.py | 10 +- tests/test_flow_tracking.py | 2 +- tests/test_issue_microsoft.py | 18 +- tests/test_lag.py | 56 +-- tests/test_logger.py | 4 +- tests/traffic/test_api_perf_new.py | 1 + tests/traffic/test_ip_device_and_flow.py | 4 +- tests/traffic/test_traffic_json.py | 2 - tests/utils/common.py | 5 +- tests/vxlan/test_manual_gateway_mac.py | 16 +- tests/vxlan/test_vxlan_b2b.py | 13 +- 54 files changed, 1135 insertions(+), 970 deletions(-) diff --git a/do.py b/do.py index 3b7ebaa98..8083d287d 100644 --- a/do.py +++ b/do.py @@ -46,7 +46,7 @@ def test(): " snappi-ixn-ci-novus100g.lbj.is.keysight.com;1;5" ' snappi-ixn-ci-novus100g.lbj.is.keysight.com;1;6"' ), - "--username="+username, + "--username=" + username, "--ext=ixnetwork", "--speed=speed_100_gbps", "tests", @@ -236,11 +236,13 @@ def get_workflow_id(): def check_release_flag(release_flag=None, release_version=None): - if release_flag == '1': + if release_flag == "1": with open("setup.py") as f: out = f.read() - snappi_convergence = re.findall(r"\"snappi_convergence==(.+)\"",out)[0] - release_version = release_version.replace('v', "") + snappi_convergence = re.findall( + r"\"snappi_convergence==(.+)\"", out + )[0] + release_version = release_version.replace("v", "") with open("version.txt", "w+") as f: f.write("version: {}\n".format(release_version)) f.write("snappi_convergence: {}\n".format(snappi_convergence)) diff --git a/snappi_ixnetwork/capture.py b/snappi_ixnetwork/capture.py index b7c7b7a94..ce41f6c6d 100644 --- a/snappi_ixnetwork/capture.py +++ b/snappi_ixnetwork/capture.py @@ -83,7 +83,9 @@ def config(self): imports.append(capture) for capture_item in self._api.snappi_config.captures: if capture_item.format == "pcap": - self._api.warning("pcap format is not supported for IxNetwork, setting capture format to pcapng") + self._api.warning( + "pcap format is not supported for IxNetwork, setting capture format to pcapng" + ) capture_item.format = "pcapng" if capture_item.port_names is None: continue @@ -348,7 +350,7 @@ def results(self, request): self._api._request("POST", url, payload) path = "%s/capture" % self._api._ixnetwork.Globals.PersistencePath - #Todo: Revert dc to merged capture after fix is available in 9.20 + # Todo: Revert dc to merged capture after fix is available in 9.20 url = "%s/files?absolute=%s&filename=%s" % ( self._api._ixnetwork.href, path, diff --git a/snappi_ixnetwork/device/base.py b/snappi_ixnetwork/device/base.py index a463d2797..b936536ff 100644 --- a/snappi_ixnetwork/device/base.py +++ b/snappi_ixnetwork/device/base.py @@ -1,7 +1,6 @@ from snappi_ixnetwork.logger import get_ixnet_logger -__all__ = ['Base', 'MultiValue', 'PostCalculated'] - +__all__ = ["Base", "MultiValue", "PostCalculated"] class MultiValue(object): @@ -25,9 +24,7 @@ def value(self): value = None if self._key == "connectedTo": value = self._ref_obj.get("xpath") - self.logger.debug("Post Calculated %s - %s" % ( - self._key, value - )) + self.logger.debug("Post Calculated %s - %s" % (self._key, value)) return value @@ -57,7 +54,7 @@ def create_node_elemet(self, ixn_obj, node_name, name=None): - We are setting name as multivalue for farther processing - It will return that newly created dict """ - self.logger.debug("Creating node for %s" %node_name) + self.logger.debug("Creating node for %s" % node_name) node = self.create_node(ixn_obj, node_name) return self.add_element(node, name) @@ -75,14 +72,10 @@ def multivalue(self, value, enum=None): return MultiValue(value) def as_multivalue(self, snappi_obj, name, enum=None): - return self.multivalue( - snappi_obj.get(name), enum - ) + return self.multivalue(snappi_obj.get(name), enum) def post_calculated(self, key, ref_ixnobj=None, ixnobj=None): - return PostCalculated( - key, ref_ixnobj, ixnobj - ) + return PostCalculated(key, ref_ixnobj, ixnobj) def get_name(self, object): name = object.get("name") @@ -106,20 +99,21 @@ def configure_multivalues(self, snappi_obj, ixn_obj, attr_map): # We need to specify product default if model not specify default_value = ixn_map.get("default_value") if default_value is None: - raise NameError("Please specify default_value for ", - snappi_attr) + raise NameError( + "Please specify default_value for ", snappi_attr + ) value = default_value if enum_map is not None and value is not None: value = enum_map[value] - self.logger.debug("ixn_attr %s with enum value %s" % ( - ixn_attr, value - )) + self.logger.debug( + "ixn_attr %s with enum value %s" % (ixn_attr, value) + ) else: ixn_attr = ixn_map value = snappi_obj.get(snappi_attr) - self.logger.debug("ixn_attr %s with value %s" % ( - ixn_attr, value - )) + self.logger.debug( + "ixn_attr %s with value %s" % (ixn_attr, value) + ) ixn_obj[ixn_attr] = self.multivalue(value) def configure_multivalues_with_choice(self, snappi_obj, ixn_obj, attr_map): @@ -130,9 +124,7 @@ def configure_multivalues_with_choice(self, snappi_obj, ixn_obj, attr_map): value = snappi_obj.get(snappi_attr).get("value") if snappi_attr == "gateway_mac": ixn_obj["resolveGateway"] = self.multivalue(False) - self.logger.debug("ixn_attr %s with value %s" % ( - ixn_attr, value - )) + self.logger.debug("ixn_attr %s with value %s" % (ixn_attr, value)) ixn_obj[ixn_attr] = self.multivalue(value) def get_symmetric_nodes(self, parent_list, node_name): @@ -198,8 +190,9 @@ def get_values(self, attr_name, enum_map=None, default=None): value = node.get(attr_name) if value is None: if default is None: - raise NameError("Please specify default_value for ", - attr_name) + raise NameError( + "Please specify default_value for ", attr_name + ) value = default if enum_map is not None: value = enum_map[value] @@ -207,9 +200,9 @@ def get_values(self, attr_name, enum_map=None, default=None): return values def get_multivalues(self, attr_name, enum_map=None, default=None): - return self._base.multivalue(self.get_values( - attr_name, enum_map=enum_map, default=default - )) + return self._base.multivalue( + self.get_values(attr_name, enum_map=enum_map, default=default) + ) def config_values(self, ixn_obj, attr_map): for snappi_attr, ixn_map in attr_map.items(): @@ -219,9 +212,9 @@ def config_values(self, ixn_obj, attr_map): raise NameError("ixn_attr is missing within ", ixn_map) enum_map = ixn_map.get("enum_map") values = self.get_multivalues( - snappi_attr, enum_map=enum_map, default=ixn_map.get( - "default_value" - ) + snappi_attr, + enum_map=enum_map, + default=ixn_map.get("default_value"), ) else: ixn_attr = ixn_map @@ -241,23 +234,18 @@ def get_tab(self, tab_name): if tab_node is None and dummy_value is not None: tab_nodes[idx] = dummy_value - return NodesInfo( - self._max_len, - self._active_list, - tab_nodes - ) + return NodesInfo(self._max_len, self._active_list, tab_nodes) def get_symmetric_nodes(self, node_name): - return self._base.get_symmetric_nodes( - self._symmetric_nodes, node_name - ) + return self._base.get_symmetric_nodes(self._symmetric_nodes, node_name) def get_group_nodes(self, tab_name): """We will pass a attribute names which is array in type Fill with other nodes and active_list as False It will raise error if all elements are not same length Finally return list of NodesInfo - It will use some IxNetwork tab which do not have enable/disable features""" + It will use some IxNetwork tab which do not have enable/disable features + """ dummy_tab = None for node in self._symmetric_nodes: dummy_tab = node.get(tab_name) @@ -279,28 +267,28 @@ def get_group_nodes(self, tab_name): tab_lengths.append(len(tab)) active_list.append(True) if len(set(tab_lengths)) > 1: - raise Exception("All the attributes %s should have same lengths" % tab_name) + raise Exception( + "All the attributes %s should have same lengths" % tab_name + ) for idx in range(tab_lengths[-1]): if len(group_nodes) <= idx: group_nodes.append([tab[idx]]) else: group_nodes[idx].append(tab[idx]) - return active_list, [NodesInfo( - 1, # use dummy one - self._active_list, - group_node - ) for group_node in group_nodes] + return active_list, [ + NodesInfo(1, self._active_list, group_node) # use dummy one + for group_node in group_nodes + ] def get_active_group_nodes(self, tab_name): """It will cover get_group_nodes At the same time it will raise error if None node because IxNetwork do not have active field for those""" - active_list, node_info_list = self.get_group_nodes( - tab_name - ) + active_list, node_info_list = self.get_group_nodes(tab_name) if len(set(active_list)) > 1: - raise Exception("All the attributes %s should configure with equal length" - % tab_name) + raise Exception( + "All the attributes %s should configure with equal length" + % tab_name + ) return node_info_list - diff --git a/snappi_ixnetwork/device/bgp.py b/snappi_ixnetwork/device/bgp.py index f11ccb4ba..837cd1262 100644 --- a/snappi_ixnetwork/device/bgp.py +++ b/snappi_ixnetwork/device/bgp.py @@ -2,15 +2,13 @@ from snappi_ixnetwork.logger import get_ixnet_logger from snappi_ixnetwork.device.bgpevpn import BgpEvpn + class Bgp(Base): _BGP = { "peer_address": "dutIp", "as_type": { "ixn_attr": "type", - "enum_map": { - "ibgp": "internal", - "ebgp": "external" - } + "enum_map": {"ibgp": "internal", "ebgp": "external"}, }, } @@ -19,7 +17,7 @@ class Bgp(Base): "keep_alive_interval": "keepaliveTimer", "update_interval": "updateInterval", "time_to_live": "ttl", - "md5_key": "md5Key" + "md5_key": "md5Key", } _CAPABILITY = { @@ -45,7 +43,7 @@ class Bgp(Base): "ipv6_multicast_mpls_vpn": "ipv6MulticastBgpMplsVpn", "ipv6_unicast_flow_spec": "capabilityipv6UnicastFlowSpec", "ipv6_sr_te_policy": "capabilitySRTEPoliciesV6", - "ipv6_unicast_add_path": "capabilityIpv6UnicastAddPath" + "ipv6_unicast_add_path": "capabilityIpv6UnicastAddPath", } _CAPABILITY_IPv6 = { @@ -57,16 +55,13 @@ class Bgp(Base): "address": "networkAddress", "prefix": "prefixLength", "count": "numberOfAddressesAsy", - "step": "prefixAddrStep" + "step": "prefixAddrStep", } _ROUTE = { - "next_hop_mode" : { + "next_hop_mode": { "ixn_attr": "nextHopType", - "enum_map": { - "local_ip": "sameaslocalip", - "manual": "manually" - } + "enum_map": {"local_ip": "sameaslocalip", "manual": "manually"}, }, "next_hop_address_type": "nextHopIPType", "next_hop_ipv4_address": "ipv4NextHop", @@ -74,7 +69,7 @@ class Bgp(Base): } _COMMUNITY = { - "type" : { + "type": { "ixn_attr": "type", "enum_map": { "manual_as_number": "manual", @@ -83,10 +78,10 @@ class Bgp(Base): "no_export_subconfed": "noexport_subconfed", "llgr_stale": "llgr_stale", "no_llgr": "no_llgr", - } + }, }, "as_number": "asNumber", - "as_custom": "lastTwoOctets" + "as_custom": "lastTwoOctets", } _BGP_AS_MODE = { @@ -141,16 +136,21 @@ def _get_interface_info(self): def _is_valid(self, ip_name): is_invalid = True same_dg_ips, invalid_ips = self._get_interface_info() - self.logger.debug("Validating %s against interface same_dg_ips : %s invalid_ips %s" % ( - ip_name, same_dg_ips, invalid_ips - )) + self.logger.debug( + "Validating %s against interface same_dg_ips : %s invalid_ips %s" + % (ip_name, same_dg_ips, invalid_ips) + ) if ip_name in invalid_ips: - self._ngpf.api.add_error("Multiple IP {name} on top of name Ethernet".format( - name=ip_name - )) + self._ngpf.api.add_error( + "Multiple IP {name} on top of name Ethernet".format( + name=ip_name + ) + ) is_invalid = False if len(same_dg_ips) > 0 and ip_name not in same_dg_ips: - self._ngpf.api.add_error("BGP should not configured on top of different device") + self._ngpf.api.add_error( + "BGP should not configured on top of different device" + ) is_invalid = False return is_invalid @@ -167,8 +167,7 @@ def _config_ipv4_interfaces(self, bgp): if not self._is_valid(ipv4_name): continue ixn_ipv4 = self._ngpf.api.ixn_objects.get_object(ipv4_name) - self._config_bgpv4(ipv4_interface.get("peers"), - ixn_ipv4) + self._config_bgpv4(ipv4_interface.get("peers"), ixn_ipv4) def _config_ipv6_interfaces(self, bgp): self.logger.debug("Configuring BGP IPv6 interfaces") @@ -183,8 +182,7 @@ def _config_ipv6_interfaces(self, bgp): if not self._is_valid(ipv6_name): continue ixn_ipv6 = self._ngpf.api.ixn_objects.get_object(ipv6_name) - self._config_bgpv6(ipv6_interface.get("peers"), - ixn_ipv6) + self._config_bgpv6(ipv6_interface.get("peers"), ixn_ipv6) def _config_as_number(self, bgp_peer, ixn_bgp): as_number_width = bgp_peer.get("as_number_width") @@ -211,7 +209,9 @@ def _config_bgpv4(self, bgp_peers, ixn_ipv4): self.configure_multivalues(advanced, ixn_bgpv4, Bgp._ADVANCED) capability = bgp_peer.get("capability") if capability is not None: - self.configure_multivalues(capability, ixn_bgpv4, Bgp._CAPABILITY) + self.configure_multivalues( + capability, ixn_bgpv4, Bgp._CAPABILITY + ) self._bgp_route_builder(bgp_peer, ixn_bgpv4) self._bgp_evpn.config(bgp_peer, ixn_bgpv4) @@ -231,7 +231,9 @@ def _config_bgpv6(self, bgp_peers, ixn_ipv6): self.configure_multivalues(advanced, ixn_bgpv6, Bgp._ADVANCED) capability = bgp_peer.get("capability") if capability is not None: - self.configure_multivalues(capability, ixn_bgpv6, Bgp._CAPABILITY) + self.configure_multivalues( + capability, ixn_bgpv6, Bgp._CAPABILITY + ) self.configure_multivalues( capability, ixn_bgpv6, Bgp._CAPABILITY_IPv6 ) @@ -245,9 +247,7 @@ def _bgp_route_builder(self, bgp_peer, ixn_bgp): v6_routes = bgp_peer.get("v6_routes") if v6_routes is not None: self._configure_bgpv6_route(v6_routes, ixn_bgp) - self._ngpf.compactor.compact(self._ngpf.working_dg.get( - "networkGroup" - )) + self._ngpf.compactor.compact(self._ngpf.working_dg.get("networkGroup")) def _configure_bgpv4_route(self, v4_routes, ixn_bgp): if v4_routes is None: @@ -293,7 +293,9 @@ def _configure_bgpv6_route(self, v6_routes, ixn_bgp): "connectedTo", ref_ixnobj=ixn_bgp ) self.configure_multivalues(addresse, ixn_ip_pool, Bgp._IP_POOL) - ixn_route = self.create_node_elemet(ixn_ip_pool, "bgpV6IPRouteProperty") + ixn_route = self.create_node_elemet( + ixn_ip_pool, "bgpV6IPRouteProperty" + ) self._ngpf.set_device_info(route, ixn_ip_pool) self._configure_route(route, ixn_route) @@ -306,7 +308,9 @@ def _configure_route(self, route, ixn_route): self.logger.debug("Configuring BGP route advance") multi_exit_discriminator = advanced.get("multi_exit_discriminator") if multi_exit_discriminator is not None: - ixn_route["enableMultiExitDiscriminator"] = self.multivalue(True) + ixn_route["enableMultiExitDiscriminator"] = self.multivalue( + True + ) ixn_route["multiExitDiscriminator"] = self.multivalue( multi_exit_discriminator ) @@ -321,7 +325,9 @@ def _configure_route(self, route, ixn_route): ixn_community = self.create_node_elemet( ixn_route, "bgpCommunitiesList" ) - self.configure_multivalues(community, ixn_community, Bgp._COMMUNITY) + self.configure_multivalues( + community, ixn_community, Bgp._COMMUNITY + ) as_path = route.get("as_path") if as_path is not None: @@ -333,7 +339,9 @@ def _configure_route(self, route, ixn_route): segments = as_path.get("segments") ixn_route["noOfASPathSegmentsPerRouteRange"] = len(segments) for segment in segments: - ixn_segment = self.create_node_elemet(ixn_route, "bgpAsPathSegmentList") + ixn_segment = self.create_node_elemet( + ixn_route, "bgpAsPathSegmentList" + ) ixn_segment["segmentType"] = self.multivalue( segment.get(type), Bgp._BGP_SEG_TYPE ) diff --git a/snappi_ixnetwork/device/bgpevpn.py b/snappi_ixnetwork/device/bgpevpn.py index fd05fd146..9c42dc6f8 100644 --- a/snappi_ixnetwork/device/bgpevpn.py +++ b/snappi_ixnetwork/device/bgpevpn.py @@ -8,10 +8,7 @@ class BgpEvpn(Base): "esi_label": "esiLabel", "active_mode": { "ixn_attr": "enableSingleActive", - "enum_map": { - "single_active": True, - "all_active": False - } + "enum_map": {"single_active": True, "all_active": False}, }, } @@ -25,11 +22,11 @@ class BgpEvpn(Base): "no_advertised": "noadvertised", "no_export_subconfed": "noexport_subconfed", "llgr_stale": "llgr_stale", - "no_llgr": "no_llgr" - } + "no_llgr": "no_llgr", + }, }, "as_number": "asNumber", - "as_custom": "lastTwoOctets" + "as_custom": "lastTwoOctets", } _SEG_EXT_COMMUNITIES = { @@ -42,8 +39,8 @@ class BgpEvpn(Base): "administrator_as_4octet": "administratoras4octet", "opaque": "opaque", "evpn": "evpn", - "administrator_as_2octet_link_bandwidth": "administratoras2octetlinkbw" - } + "administrator_as_2octet_link_bandwidth": "administratoras2octetlinkbw", + }, }, "subtype": { "ixn_attr": "subType", @@ -54,9 +51,9 @@ class BgpEvpn(Base): "extended_bandwidth": "extendedbandwidth", "color": "color", "encapsulation": "encapsulation", - "mac_address": "macaddress" - } - } + "mac_address": "macaddress", + }, + }, } _AS_SET_MODE = { @@ -82,37 +79,37 @@ class BgpEvpn(Base): "ixn_attr": "multicastTunnelType", "enum_map": { "ingress_replication": "tunneltypeingressreplication" - } - } + }, + }, } _COMMON_ROUTE_TYPE = { "as_2octet": "as", "as_4octet": "as4", - "ipv4_address": "ip" + "ipv4_address": "ip", } _BROADCAST_DOMAINS = { "ethernet_tag_id": "ethernetTagId", - "vlan_aware_service": "enableVlanAwareService" + "vlan_aware_service": "enableVlanAwareService", } _MAC_ADDRESS = { "address": "mac", "prefix": "prefixLength", - "count": "numberOfAddressesAsy" + "count": "numberOfAddressesAsy", } _IP_ADDRESS = { "address": "networkAddress", "prefix": "prefixLength", - "count": "numberOfAddressesAsy" + "count": "numberOfAddressesAsy", } _CMAC_PROPERTIES = { "l2vni": "firstLabelStart", "l3vni": "secondLabelStart", - "include_default_gateway": "includeDefaultGatewayExtendedCommunity" + "include_default_gateway": "includeDefaultGatewayExtendedCommunity", } def __init__(self, ngpf): @@ -127,8 +124,7 @@ def config(self, bgp_peer, ixn_bgp): eth_segment_info = self.get_symmetric_nodes( [bgp_peer], "evpn_ethernet_segments" ) - if eth_segment_info.is_all_null or \ - eth_segment_info.max_len == 0: + if eth_segment_info.is_all_null or eth_segment_info.max_len == 0: return self._peer_class = bgp_peer.__class__.__name__ if self._peer_class == "BgpV4Peer": @@ -150,19 +146,13 @@ def _config_advance(self, parent_info, ixn_parent): if advanced.is_all_null: return None - ixn_parent["origin"] = advanced.get_multivalues( - "origin" - ) + ixn_parent["origin"] = advanced.get_multivalues("origin") med_values = [] for node in advanced.symmetric_nodes: - med_values.append( - node.get("multi_exit_discriminator") - ) + med_values.append(node.get("multi_exit_discriminator")) if med_values.count(None) != len(med_values): ixn_parent["enableMultiExitDiscriminator"] = self.multivalue(True) - ixn_parent["multiExitDiscriminator"] = self.multivalue( - med_values - ) + ixn_parent["multiExitDiscriminator"] = self.multivalue(med_values) def _config_communities(self, parent_info, ixn_parent): active_list, communities_info_list = parent_info.get_group_nodes( @@ -174,7 +164,9 @@ def _config_communities(self, parent_info, ixn_parent): ixn_parent["noOfCommunities"] = len(communities_info_list) ixn_parent["enableCommunity"] = self.multivalue(active_list) for communities_info in communities_info_list: - ixn_communities = self.create_node_elemet(ixn_parent, "bgpCommunitiesList") + ixn_communities = self.create_node_elemet( + ixn_parent, "bgpCommunitiesList" + ) communities_info.config_values( ixn_communities, BgpEvpn._SEG_COMMUNITIES ) @@ -186,9 +178,7 @@ def _config_ext_communities(self, parent_info, ixn_parent): if len(ext_communitiesinfo_list) == 0: return None - ixn_parent["noOfExtendedCommunity"] = len( - ext_communitiesinfo_list - ) + ixn_parent["noOfExtendedCommunity"] = len(ext_communitiesinfo_list) ixn_parent["enableExtendedCommunity"] = self.multivalue(active_list) for ext_communitiesinfo in ext_communitiesinfo_list: ixn_ext_communities = self.create_node_elemet( @@ -199,7 +189,9 @@ def _config_ext_communities(self, parent_info, ixn_parent): ) types = ixn_ext_communities.get("type").value sub_types = ixn_ext_communities.get("subType").value - values = ext_communitiesinfo.get_values("value", default="0000000000c8") + values = ext_communitiesinfo.get_values( + "value", default="0000000000c8" + ) idx = 0 opaqueData = list() ip = list() @@ -255,12 +247,22 @@ def _config_ext_communities(self, parent_info, ixn_parent): ixn_ext_communities["opaqueData"] = self.multivalue(opaqueData) ixn_ext_communities["ip"] = self.multivalue(ip) - ixn_ext_communities["assignedNumber2Bytes"] = self.multivalue(assignedNumber2Bytes) - ixn_ext_communities["asNumber2Bytes"] = self.multivalue(asNumber2Bytes) - ixn_ext_communities["asNumber4Bytes"] = self.multivalue(asNumber4Bytes) - ixn_ext_communities["assignedNumber4Bytes"] = self.multivalue(assignedNumber4Bytes) + ixn_ext_communities["assignedNumber2Bytes"] = self.multivalue( + assignedNumber2Bytes + ) + ixn_ext_communities["asNumber2Bytes"] = self.multivalue( + asNumber2Bytes + ) + ixn_ext_communities["asNumber4Bytes"] = self.multivalue( + asNumber4Bytes + ) + ixn_ext_communities["assignedNumber4Bytes"] = self.multivalue( + assignedNumber4Bytes + ) ixn_ext_communities["colorCOBits"] = self.multivalue(colorCOBits) - ixn_ext_communities["colorReservedBits"] = self.multivalue(colorReservedBits) + ixn_ext_communities["colorReservedBits"] = self.multivalue( + colorReservedBits + ) ixn_ext_communities["colorValue"] = self.multivalue(colorValue) def _config_as_path_segments(self, parent_info, ixn_parent): @@ -285,7 +287,9 @@ def _config_as_path_segments(self, parent_info, ixn_parent): ixn_segments["segmentType"] = segments_info.get_multivalues( "type", BgpEvpn._SEGMENT_TYPE ) - active_list, numbers_info_list = segments_info.get_group_nodes("as_numbers") + active_list, numbers_info_list = segments_info.get_group_nodes( + "as_numbers" + ) if len(numbers_info_list) > 0: ixn_segments["numberOfAsNumberInSegment"] = len( numbers_info_list @@ -307,9 +311,9 @@ def _config_eth_segment(self, eth_segment_info, ixn_eth_segments): ) df_election_info = eth_segment_info.get_tab("df_election") if not df_election_info.is_all_null: - ixn_eth_segments["dfElectionTimer"] = df_election_info.get_multivalues( - "election_timer" - ) + ixn_eth_segments[ + "dfElectionTimer" + ] = df_election_info.get_multivalues("election_timer") self._config_advance(eth_segment_info, ixn_eth_segments) self._config_communities(eth_segment_info, ixn_eth_segments) @@ -329,13 +333,9 @@ def _config_evis(self, eth_segment_info, ixn_bgp, ixn_eth_segments): vxlan_info = eth_segment_info.get_symmetric_nodes("evis") ixn_eth_segments["evisCount"] = vxlan_info.max_len if self._peer_class == "BgpV4Peer": - ixn_xvlan = self.create_node_elemet( - ixn_bgp, "bgpIPv4EvpnVXLAN" - ) + ixn_xvlan = self.create_node_elemet(ixn_bgp, "bgpIPv4EvpnVXLAN") else: - ixn_xvlan = self.create_node_elemet( - ixn_bgp, "bgpIPv6EvpnVXLAN" - ) + ixn_xvlan = self.create_node_elemet(ixn_bgp, "bgpIPv6EvpnVXLAN") vxlan_info.config_values(ixn_xvlan, BgpEvpn._VXLAN) # Configure route_distinguisher @@ -344,89 +344,97 @@ def _config_evis(self, eth_segment_info, ixn_bgp, ixn_eth_segments): "rd_type", enum_map=BgpEvpn._COMMON_ROUTE_TYPE ) convert_values = convert_as_values( - rd_types, distinguisher_info.get_values( - "rd_value", default="65101:1" - ) + rd_types, + distinguisher_info.get_values("rd_value", default="65101:1"), ) ixn_xvlan["rdType"] = self.multivalue(rd_types) ixn_xvlan["rdASNumber"] = self.multivalue(convert_values.common_num) ixn_xvlan["rdEvi"] = self.multivalue(convert_values.assign_num) ixn_xvlan["rdIpAddress"] = self.multivalue(convert_values.ip_addr) - ixn_xvlan["autoConfigureRdIpAddress"] = distinguisher_info.get_multivalues( + ixn_xvlan[ + "autoConfigureRdIpAddress" + ] = distinguisher_info.get_multivalues( "auto_config_rd_ip_addr", default=True ) # Configure route_target_export - exports_info_list = vxlan_info.get_active_group_nodes("route_target_export") + exports_info_list = vxlan_info.get_active_group_nodes( + "route_target_export" + ) if len(exports_info_list) > 0: - ixn_xvlan["numRtInExportRouteTargetList"] = len( - exports_info_list - ) + ixn_xvlan["numRtInExportRouteTargetList"] = len(exports_info_list) for exports_info in exports_info_list: - ixn_export = self.create_node_elemet(ixn_xvlan, "bgpExportRouteTargetList") + ixn_export = self.create_node_elemet( + ixn_xvlan, "bgpExportRouteTargetList" + ) rt_types = exports_info.get_values( "rt_type", enum_map=BgpEvpn._COMMON_ROUTE_TYPE ) convert_rt_values = convert_as_values( - rt_types, exports_info.get_values( - "rt_value", default="65101:1" - ) + rt_types, + exports_info.get_values("rt_value", default="65101:1"), ) self._set_target(ixn_export, rt_types, convert_rt_values) # Configure route_target_import - import_info_list = vxlan_info.get_active_group_nodes("route_target_import") + import_info_list = vxlan_info.get_active_group_nodes( + "route_target_import" + ) if len(import_info_list) > 0: ixn_xvlan["importRtListSameAsExportRtList"] = False - ixn_xvlan["numRtInImportRouteTargetList"] = len( - import_info_list - ) + ixn_xvlan["numRtInImportRouteTargetList"] = len(import_info_list) for import_info in import_info_list: - ixn_import = self.create_node_elemet(ixn_xvlan, "bgpImportRouteTargetList") + ixn_import = self.create_node_elemet( + ixn_xvlan, "bgpImportRouteTargetList" + ) rt_types = import_info.get_values( "rt_type", enum_map=BgpEvpn._COMMON_ROUTE_TYPE ) convert_rt_values = convert_as_values( - rt_types, import_info.get_values( - "rt_value", default="65101:1" - ) + rt_types, import_info.get_values("rt_value", default="65101:1") ) self._set_target(ixn_import, rt_types, convert_rt_values) # Configure l3_route_target_export - l3exports_info_list = vxlan_info.get_active_group_nodes("l3_route_target_export") + l3exports_info_list = vxlan_info.get_active_group_nodes( + "l3_route_target_export" + ) if len(l3exports_info_list) > 0: ixn_xvlan["numRtInL3vniExportRouteTargetList"] = len( l3exports_info_list ) for l3exports_info in l3exports_info_list: - ixn_l3export = self.create_node_elemet(ixn_xvlan, "bgpL3VNIExportRouteTargetList") + ixn_l3export = self.create_node_elemet( + ixn_xvlan, "bgpL3VNIExportRouteTargetList" + ) rt_types = l3exports_info.get_values( "rt_type", enum_map=BgpEvpn._COMMON_ROUTE_TYPE ) convert_rt_values = convert_as_values( - rt_types, l3exports_info.get_values( - "rt_value", default="65101:1" - ) + rt_types, + l3exports_info.get_values("rt_value", default="65101:1"), ) self._set_target(ixn_l3export, rt_types, convert_rt_values) # Configure l3_route_target_import - l3import_info_list = vxlan_info.get_active_group_nodes("l3_route_target_import") + l3import_info_list = vxlan_info.get_active_group_nodes( + "l3_route_target_import" + ) if len(l3import_info_list) > 0: ixn_xvlan["l3vniImportRtListSameAsL3vniExportRtList"] = False ixn_xvlan["numRtInL3vniImportRouteTargetList"] = len( l3import_info_list ) for l3import_info in l3import_info_list: - ixn_l3import = self.create_node_elemet(ixn_xvlan, "bgpL3VNIImportRouteTargetList") + ixn_l3import = self.create_node_elemet( + ixn_xvlan, "bgpL3VNIImportRouteTargetList" + ) rt_types = l3import_info.get_values( "rt_type", enum_map=BgpEvpn._COMMON_ROUTE_TYPE ) convert_rt_values = convert_as_values( - rt_types, l3import_info.get_values( - "rt_value", default="65101:1" - ) + rt_types, + l3import_info.get_values("rt_value", default="65101:1"), ) self._set_target(ixn_l3import, rt_types, convert_rt_values) @@ -440,12 +448,16 @@ def _config_evis(self, eth_segment_info, ixn_bgp, ixn_eth_segments): ) if not broadcast_domains_info.is_all_null: if self._peer_class == "BgpV4Peer": - ixn_xvlan["numBroadcastDomainV4"] = broadcast_domains_info.max_len + ixn_xvlan[ + "numBroadcastDomainV4" + ] = broadcast_domains_info.max_len ixn_broadcast_domains = self.create_property( ixn_xvlan, "broadcastDomainV4" ) else: - ixn_xvlan["numBroadcastDomainV6"] = broadcast_domains_info.max_len + ixn_xvlan[ + "numBroadcastDomainV6" + ] = broadcast_domains_info.max_len ixn_broadcast_domains = self.create_property( ixn_xvlan, "broadcastDomainV6" ) @@ -464,9 +476,7 @@ def _get_symetic_address(self, cmac_ip_range_info, address_type): symmetric_nodes = [] dummy_value = None for node in cmac_ip_range_info.symmetric_nodes: - symmetric_nodes.append( - node.get(address_type) - ) + symmetric_nodes.append(node.get(address_type)) if symmetric_nodes[-1] is None: active_list.append(False) else: @@ -478,44 +488,45 @@ def _get_symetic_address(self, cmac_ip_range_info, address_type): for idx in range(len(active_list)): if active_list[idx] is False: symmetric_nodes[idx] = dummy_value - active_list[idx] = cmac_ip_range_info.active_list[idx] \ - and active_list[idx] + active_list[idx] = ( + cmac_ip_range_info.active_list[idx] and active_list[idx] + ) return NodesInfo( - cmac_ip_range_info.max_len, - active_list, - symmetric_nodes + cmac_ip_range_info.max_len, active_list, symmetric_nodes ) - def _config_cmac_ip_range(self, broadcast_domains_info, ixn_broadcast_domains, ixn_xvlan): + def _config_cmac_ip_range( + self, broadcast_domains_info, ixn_broadcast_domains, ixn_xvlan + ): cmac_ip_range_info = broadcast_domains_info.get_symmetric_nodes( "cmac_ip_range" ) if cmac_ip_range_info.is_all_null: return - mac_info = self._get_symetic_address(cmac_ip_range_info, "mac_addresses") - ipv4_info = self._get_symetic_address(cmac_ip_range_info, "ipv4_addresses") - ipv6_info = self._get_symetic_address(cmac_ip_range_info, "ipv6_addresses") + mac_info = self._get_symetic_address( + cmac_ip_range_info, "mac_addresses" + ) + ipv4_info = self._get_symetic_address( + cmac_ip_range_info, "ipv4_addresses" + ) + ipv6_info = self._get_symetic_address( + cmac_ip_range_info, "ipv6_addresses" + ) ixn_broadcast_domains["noOfMacPools"] = cmac_ip_range_info.max_len if mac_info.is_all_null: raise Exception("mac_addresses should configured in cmac_ip_range") names = cmac_ip_range_info.get_values("name") - ixn_ng = self.create_node_elemet( - self._ngpf.working_dg, "networkGroup" - ) + ixn_ng = self.create_node_elemet(self._ngpf.working_dg, "networkGroup") for node in cmac_ip_range_info.symmetric_nodes: - self._ngpf.set_device_info( - node, ixn_ng - ) + self._ngpf.set_device_info(node, ixn_ng) ixn_ng["name"] = names self._ngpf.api.ixn_objects.set_scalable(ixn_ng) ixn_ng["enabled"] = self.multivalue(cmac_ip_range_info.active_list) ixn_mac_pools = self.create_node_elemet( ixn_ng, "macPools", "pool_{}".format(names[0]) ) - mac_info.config_values( - ixn_mac_pools, BgpEvpn._MAC_ADDRESS - ) + mac_info.config_values(ixn_mac_pools, BgpEvpn._MAC_ADDRESS) ixn_connector = self.create_property(ixn_mac_pools, "connector") ixn_connector["connectedTo"] = self.post_calculated( "connectedTo", ref_ixnobj=ixn_xvlan @@ -524,9 +535,7 @@ def _config_cmac_ip_range(self, broadcast_domains_info, ixn_broadcast_domains, i ixn_mac_pools, "cMacProperties", "mac_{}".format(names[0]) ) ixn_mac["enableSecondLabel"] = self.multivalue(True) - cmac_ip_range_info.config_values( - ixn_mac, BgpEvpn._CMAC_PROPERTIES - ) + cmac_ip_range_info.config_values(ixn_mac, BgpEvpn._CMAC_PROPERTIES) self._config_advance(cmac_ip_range_info, ixn_mac) self._config_communities(cmac_ip_range_info, ixn_mac) self._config_ext_communities(cmac_ip_range_info, ixn_mac) @@ -549,5 +558,3 @@ def _config_cmac_ip_range(self, broadcast_domains_info, ixn_broadcast_domains, i ipv6_info.active_list ) ipv6_info.config_values(ixn_ipv6, BgpEvpn._IP_ADDRESS) - - diff --git a/snappi_ixnetwork/device/compactor.py b/snappi_ixnetwork/device/compactor.py index c23cd0ba2..f55ff90e3 100644 --- a/snappi_ixnetwork/device/compactor.py +++ b/snappi_ixnetwork/device/compactor.py @@ -6,9 +6,7 @@ class Compactor(object): def __init__(self, ixnetworkapi): self._api = ixnetworkapi self._unsupported_nodes = [] - self._ignore_keys = [ - "xpath", "name" - ] + self._ignore_keys = ["xpath", "name"] self.logger = get_ixnet_logger(__name__) def compact(self, roots): @@ -29,9 +27,7 @@ def compact(self, roots): for similar_objs in similar_objs_list: if len(similar_objs.objects) > 0: similar_objs.compact(roots) - self.set_scalable( - similar_objs.primary_obj - ) + self.set_scalable(similar_objs.primary_obj) def _comparator(self, src, dst): if type(src) != type(dst): @@ -117,9 +113,7 @@ def append(self, object): def compact(self, roots): multiplier = len(self._objects) + 1 for object in self._objects: - self._value_compactor( - self._primary_obj, object - ) + self._value_compactor(self._primary_obj, object) roots.remove(object) self._primary_obj["multiplier"] = multiplier @@ -130,10 +124,16 @@ def _value_compactor(self, src, dst): src_value = src.get(key) dst_value = dst.get(key) if key == "name": - src_value = src_value if isinstance(src_value, MultiValue) \ + src_value = ( + src_value + if isinstance(src_value, MultiValue) else self.multivalue(src_value) - dst_value = dst_value if isinstance(dst_value, MultiValue) \ + ) + dst_value = ( + dst_value + if isinstance(dst_value, MultiValue) else self.multivalue(dst_value) + ) # todo: fill with product default value for # if dst_value is None: # dst_value = obj.get(key, with_default=True) @@ -141,9 +141,7 @@ def _value_compactor(self, src, dst): for index, dst_dict in enumerate(dst_value): if not isinstance(dst_dict, dict): continue - self._value_compactor( - src_value[index], dst_dict - ) + self._value_compactor(src_value[index], dst_dict) elif isinstance(dst_value, dict): self._value_compactor(src_value, dst_value) elif isinstance(src_value, MultiValue): @@ -156,4 +154,3 @@ def _value_compactor(self, src, dst): else: src_value = [src_value] + dst_value src[key] = self.multivalue(src_value) - diff --git a/snappi_ixnetwork/device/createixnconfig.py b/snappi_ixnetwork/device/createixnconfig.py index c54742e0e..3cea824d4 100644 --- a/snappi_ixnetwork/device/createixnconfig.py +++ b/snappi_ixnetwork/device/createixnconfig.py @@ -1,6 +1,7 @@ from snappi_ixnetwork.device.base import * from snappi_ixnetwork.logger import get_ixnet_logger + class CreateIxnConfig(Base): def __init__(self, ngpf): super(CreateIxnConfig, self).__init__() @@ -15,9 +16,7 @@ def create(self, node, node_name, parent_xpath=""): if not isinstance(element, dict): raise TypeError("Expecting dict") xpath = """{parent_xpath}/{node_name}[{index}]""".format( - parent_xpath=parent_xpath, - node_name=node_name, - index=idx + parent_xpath=parent_xpath, node_name=node_name, index=idx ) element["xpath"] = xpath self._process_element(element, xpath) @@ -29,8 +28,7 @@ def post_calculate(self): def _process_element(self, element, parent_xpath, child_name=None): if child_name is not None and "xpath" in element: child_xpath = """{parent_xpath}/{child_name}""".format( - parent_xpath=parent_xpath, - child_name=child_name + parent_xpath=parent_xpath, child_name=child_name ) element["xpath"] = child_xpath key_to_remove = [] @@ -44,13 +42,14 @@ def _process_element(self, element, parent_xpath, child_name=None): else: element[key] = value elif isinstance(value, PostCalculated): - self._post_calculated_info.append( - [element, key, value] - ) + self._post_calculated_info.append([element, key, value]) elif isinstance(value, dict): self._process_element(value, parent_xpath, key) - elif isinstance(value, list) and len(value) > 0 and \ - isinstance(value[0], dict): + elif ( + isinstance(value, list) + and len(value) > 0 + and isinstance(value[0], dict) + ): if child_name is not None: self.create(value, key, element["xpath"]) else: @@ -63,9 +62,9 @@ def _get_ixn_multivalue(self, value, att_name, xpath): value = value.value ixn_value = { "xpath": "/multivalue[@source = '{xpath} {att_name}']".format( - xpath=xpath, - att_name=att_name - )} + xpath=xpath, att_name=att_name + ) + } if not isinstance(value, list): value = [value] if len(set(value)) == 1: @@ -74,20 +73,16 @@ def _get_ixn_multivalue(self, value, att_name, xpath): else: ixn_value["singleValue"] = { "xpath": "/multivalue[@source = '{xpath} {att_name}']/singleValue".format( - xpath=xpath, - att_name=att_name + xpath=xpath, att_name=att_name ), - "value": value[0] + "value": value[0], } return ixn_value else: ixn_value["valueList"] = { "xpath": "/multivalue[@source = '{xpath} {att_name}']/valueList".format( - xpath=xpath, - att_name=att_name + xpath=xpath, att_name=att_name ), - "values": value + "values": value, } return ixn_value - - diff --git a/snappi_ixnetwork/device/interface.py b/snappi_ixnetwork/device/interface.py index 3cd689b32..f20071891 100644 --- a/snappi_ixnetwork/device/interface.py +++ b/snappi_ixnetwork/device/interface.py @@ -1,6 +1,7 @@ from snappi_ixnetwork.device.base import Base from snappi_ixnetwork.logger import get_ixnet_logger + class Ethernet(Base): _ETHERNET = { "mac": "mac", @@ -16,17 +17,13 @@ class Ethernet(Base): "x9100": "ethertype9100", "x9200": "ethertype9200", "x9300": "ethertype9300", - } + }, }, "priority": "priority", - "id": "vlanId" + "id": "vlanId", } - _IP = { - "address": "address", - "gateway": "gatewayIp", - "prefix": "prefix" - } + _IP = {"address": "address", "gateway": "gatewayIp", "prefix": "prefix"} _GATEWAY_MAC = { "gateway_mac": "manualGatewayMac", @@ -55,7 +52,8 @@ def _configure_vlan(self, ixn_eth, vlans): self.logger.debug("Configuring VLAN") for vlan in vlans: ixn_vlan = self.create_node_elemet( - ixn_eth, "vlan", vlan.get("name")) + ixn_eth, "vlan", vlan.get("name") + ) self.configure_multivalues(vlan, ixn_vlan, Ethernet._VLAN) def _configure_ipv4(self, ixn_eth, ethernet): @@ -78,8 +76,9 @@ def _configure_ipv4(self, ixn_eth, ethernet): self._ngpf.set_device_info(ipv4_address, ixn_ip) self.configure_multivalues(ipv4_address, ixn_ip, Ethernet._IP) if ipv4_address.gateway_mac.choice == "value": - self.configure_multivalues_with_choice(ipv4_address, ixn_ip, - Ethernet._GATEWAY_MAC) + self.configure_multivalues_with_choice( + ipv4_address, ixn_ip, Ethernet._GATEWAY_MAC + ) def _configure_ipv6(self, ixn_eth, ethernet): self.logger.debug("Configuring IPv6 interface") @@ -101,6 +100,6 @@ def _configure_ipv6(self, ixn_eth, ethernet): self._ngpf.set_device_info(ipv6_address, ixn_ip) self.configure_multivalues(ipv6_address, ixn_ip, Ethernet._IP) if ipv6_address.gateway_mac.choice == "value": - self.configure_multivalues_with_choice(ipv6_address, ixn_ip, - Ethernet._GATEWAY_MAC) - + self.configure_multivalues_with_choice( + ipv6_address, ixn_ip, Ethernet._GATEWAY_MAC + ) diff --git a/snappi_ixnetwork/device/loopbackint.py b/snappi_ixnetwork/device/loopbackint.py index f939d5b91..987007b17 100644 --- a/snappi_ixnetwork/device/loopbackint.py +++ b/snappi_ixnetwork/device/loopbackint.py @@ -30,41 +30,42 @@ def _get_vxlan_source_ints(self, device): vxlan = device.get("vxlan") if vxlan is not None: v4_tunnels = vxlan.get("v4_tunnels") - if v4_tunnels is not None and len( - v4_tunnels) > 0: + if v4_tunnels is not None and len(v4_tunnels) > 0: for v4_tunnel in v4_tunnels: vxlan_source_int_list.append( v4_tunnel.get("source_interface") ) v6_tunnels = vxlan.get("v6_tunnels") - if v6_tunnels is not None and len( - v6_tunnels) > 0: + if v6_tunnels is not None and len(v6_tunnels) > 0: for v6_tunnel in v6_tunnels: vxlan_source_int_list.append( v6_tunnel.get("source_interface") ) - return vxlan_source_int_list + return vxlan_source_int_list def _create_dg(self, loop_back, device): self.logger.debug("Configuring DG for loopback interface") eth_name = loop_back.get("eth_name") if eth_name not in self._ngpf.api.ixn_objects.names: - raise Exception("Ethernet %s not present within configuration" - % eth_name) - ixn_parent_dg = self._ngpf.api.ixn_objects.get_working_dg( - eth_name - ) + raise Exception( + "Ethernet %s not present within configuration" % eth_name + ) + ixn_parent_dg = self._ngpf.api.ixn_objects.get_working_dg(eth_name) self._ixn_parent_dgs.append(ixn_parent_dg) ixn_dg = self.create_node_elemet( - ixn_parent_dg, "deviceGroup", "loopback_{}".format(device.get("name")) + ixn_parent_dg, + "deviceGroup", + "loopback_{}".format(device.get("name")), ) ixn_dg["multiplier"] = 1 self._ngpf.working_dg = ixn_dg self._ngpf.set_device_info(device, ixn_dg) return ixn_dg - def _config_ipv4_loopbacks(self, ipv4_loopbacks, device, vxlan_source_int_list): + def _config_ipv4_loopbacks( + self, ipv4_loopbacks, device, vxlan_source_int_list + ): self.logger.debug("Configuring IPv4 loopback interface") for ipv4_loopback in ipv4_loopbacks: ixn_dg = self._create_dg(ipv4_loopback, device) @@ -73,19 +74,23 @@ def _config_ipv4_loopbacks(self, ipv4_loopbacks, device, vxlan_source_int_list): ixn_eth = self.create_node_elemet( ixn_dg, "ethernet", "eth {}".format(name) ) - ixn_v4 = self.create_node_elemet( - ixn_eth, "ipv4", name - ) + ixn_v4 = self.create_node_elemet(ixn_eth, "ipv4", name) self._ngpf.set_device_info(ipv4_loopback, ixn_v4) - ixn_v4["address"] = self.as_multivalue(ipv4_loopback, "address") + ixn_v4["address"] = self.as_multivalue( + ipv4_loopback, "address" + ) else: ixn_v4lb = self.create_node_elemet( ixn_dg, "ipv4Loopback", name ) self._ngpf.set_device_info(ipv4_loopback, ixn_v4lb) - ixn_v4lb["address"] = self.as_multivalue(ipv4_loopback, "address") + ixn_v4lb["address"] = self.as_multivalue( + ipv4_loopback, "address" + ) - def _config_ipv6_loopbacks(self, ipv6_loopbacks, device, vxlan_source_int_list): + def _config_ipv6_loopbacks( + self, ipv6_loopbacks, device, vxlan_source_int_list + ): self.logger.debug("Configuring IPv6 loopback interface") for ipv6_loopback in ipv6_loopbacks: ixn_dg = self._create_dg(ipv6_loopback, device) @@ -94,16 +99,16 @@ def _config_ipv6_loopbacks(self, ipv6_loopbacks, device, vxlan_source_int_list): ixn_eth = self.create_node_elemet( ixn_dg, "ethernet", "eth {}".format(name) ) - ixn_v6 = self.create_node_elemet( - ixn_eth, "ipv6", name - ) + ixn_v6 = self.create_node_elemet(ixn_eth, "ipv6", name) self._ngpf.set_device_info(ipv6_loopback, ixn_v6) - ixn_v6["address"] = self.as_multivalue(ipv6_loopback, "address") + ixn_v6["address"] = self.as_multivalue( + ipv6_loopback, "address" + ) else: ixn_v4lb = self.create_node_elemet( ixn_dg, "ipv6Loopback", ipv6_loopback.get("name") ) self._ngpf.set_device_info(ipv6_loopback, ixn_v4lb) - ixn_v4lb["address"] = self.as_multivalue(ipv6_loopback, "address") - - + ixn_v4lb["address"] = self.as_multivalue( + ipv6_loopback, "address" + ) diff --git a/snappi_ixnetwork/device/ngpf.py b/snappi_ixnetwork/device/ngpf.py index 7894b6113..3539f51c1 100644 --- a/snappi_ixnetwork/device/ngpf.py +++ b/snappi_ixnetwork/device/ngpf.py @@ -28,10 +28,7 @@ class Ngpf(Base): "BgpCMacIpRange": "ethernetVlan", } - _ROUTE_STATE = { - "advertise": True, - "withdraw": False - } + _ROUTE_STATE = {"advertise": True, "withdraw": False} def __init__(self, ixnetworkapi): super(Ngpf, self).__init__() @@ -72,19 +69,15 @@ def config(self): def set_device_info(self, snappi_obj, ixn_obj): name = snappi_obj.get("name") class_name = snappi_obj.__class__.__name__ - self.logger.debug("set_device_info name %s and class_name %s" % ( - name, class_name - )) + self.logger.debug( + "set_device_info name %s and class_name %s" % (name, class_name) + ) try: encap = Ngpf._DEVICE_ENCAP_MAP[class_name] except KeyError: - raise NameError( - "Mapping is missing for {0}".format(class_name) - ) + raise NameError("Mapping is missing for {0}".format(class_name)) self.api.set_device_encap(name, encap) - self.api.set_device_encap( - self.get_name(self.working_dg), encap - ) + self.api.set_device_encap(self.get_name(self.working_dg), encap) self.api.ixn_objects.set(name, ixn_obj) def set_ixn_routes(self, snappi_obj, ixn_obj): @@ -114,42 +107,27 @@ def _configure_topology(self): for device in self.api.snappi_config.devices: self._bgp.config(device) - # Compaction will take place in this order # Step-1: Compact chain DGs for chain_parent_dg in self._chain_parent_dgs: - self.compactor.compact(chain_parent_dg.get( - "deviceGroup" - )) - self._set_dev_compacted(chain_parent_dg.get( - "deviceGroup" - )) + self.compactor.compact(chain_parent_dg.get("deviceGroup")) + self._set_dev_compacted(chain_parent_dg.get("deviceGroup")) # Step-2: Compact VXLAN source_interfaces = self._vxlan.source_interfaces for v4_int in source_interfaces.ipv4: - self.compactor.compact(v4_int.get( - "vxlan" - )) + self.compactor.compact(v4_int.get("vxlan")) for v6_int in source_interfaces.ipv6: - self.compactor.compact(v6_int.get( - "vxlanv6" - )) + self.compactor.compact(v6_int.get("vxlanv6")) # Step-3: First compact all loopback interfaces for ix_parent_dg in self.loopback_parent_dgs: - self.compactor.compact(ix_parent_dg.get( - "deviceGroup" - )) + self.compactor.compact(ix_parent_dg.get("deviceGroup")) # Step-4: Compact root Topology for ixn_topo in self._ixn_topo_objects.values(): - self.compactor.compact(ixn_topo.get( - "deviceGroup" - )) - self._set_dev_compacted(ixn_topo.get( - "deviceGroup" - )) + self.compactor.compact(ixn_topo.get("deviceGroup")) + self._set_dev_compacted(ixn_topo.get("deviceGroup")) def _configure_device_group(self, ixn_topos): """map ethernet with a ixn deviceGroup with multiplier = 1""" @@ -164,7 +142,8 @@ def _configure_device_group(self, ixn_topos): if ethernet.get("connection") and ethernet.get("port_name"): raise Exception( "port_name and connection for ethernet configuration cannot be passed together, use either connection or port_name property. \ - port_name is deprecated and will be removed in future releases.") + port_name is deprecated and will be removed in future releases." + ) if ethernet.get("connection"): connection_choice = ethernet.get("connection").choice if connection_choice == "port_name": @@ -181,13 +160,19 @@ def _configure_device_group(self, ixn_topos): else: port_name = ethernet.get("port_name") if port_name is None: - raise Exception("port_name is not passed for the device {}".format(device.get("name"))) + raise Exception( + "port_name is not passed for the device {}".format( + device.get("name") + ) + ) if port_name in self._ixn_topo_objects: ixn_topo = self._ixn_topo_objects[port_name] else: ixn_topo = self.add_element(ixn_topos) ixn_topo["name"] = self._get_topology_name(port_name) - ixn_topo["ports"] = [self.api.ixn_objects.get_xpath(port_name)] + ixn_topo["ports"] = [ + self.api.ixn_objects.get_xpath(port_name) + ] self._ixn_topo_objects[port_name] = ixn_topo ixn_dg = self.create_node_elemet( ixn_topo, "deviceGroup", device.get("name") @@ -214,7 +199,9 @@ def _configure_device_group(self, ixn_topos): if chin_dgs is None: continue for connected_to, ethernet_list in chin_dgs.items(): - ixn_working_dg = self.api.ixn_objects.get_working_dg(connected_to) + ixn_working_dg = self.api.ixn_objects.get_working_dg( + connected_to + ) self._chain_parent_dgs.append(ixn_working_dg) for ethernet in ethernet_list: ixn_dg = self.create_node_elemet( @@ -225,16 +212,13 @@ def _configure_device_group(self, ixn_topos): self.set_device_info(device, ixn_dg) self._ethernet.config(ethernet, ixn_dg) - def _pushixnconfig(self): self.logger.debug("pushing ixnet config") erros = self.api.get_errors() if len(erros) > 0: return ixn_cnf = json.dumps(self._ixn_config, indent=2) - errata = self._resource_manager.ImportConfig( - ixn_cnf, False - ) + errata = self._resource_manager.ImportConfig(ixn_cnf, False) for item in errata: self.api.warning(item) @@ -244,7 +228,7 @@ def stop_topology(self): self.logger.debug("Stopping topology") self.api._ixnetwork.StopAllProtocols("sync") - def set_protocol_state(self,request): + def set_protocol_state(self, request): if request.state is None: raise Exception("state is None within set_protocol_state") self.logger.debug("Setting protocol with %s" % request.state) @@ -273,27 +257,31 @@ def set_route_state(self, payload): ixn_obj = obj break if ixn_obj is None: - ixn_obj_idx_list[route_info] = list(range( - route_info.index, route_info.index + route_info.multiplier - )) + ixn_obj_idx_list[route_info] = list( + range( + route_info.index, + route_info.index + route_info.multiplier, + ) + ) else: - ixn_obj_idx_list[route_info].extend(list(range( - route_info.index, route_info.index + route_info.multiplier - ))) + ixn_obj_idx_list[route_info].extend( + list( + range( + route_info.index, + route_info.index + route_info.multiplier, + ) + ) + ) imports = [] for obj, index_list in ixn_obj_idx_list.items(): xpath = obj.xpath active = "active" index_list = list(set(index_list)) - object_info = self.select_properties( - xpath, properties=[active] - ) + object_info = self.select_properties(xpath, properties=[active]) values = object_info[active]["values"] for idx in index_list: values[idx] = Ngpf._ROUTE_STATE[payload.state] - imports.append(self.configure_value( - xpath, active, values - )) + imports.append(self.configure_value(xpath, active, values)) self.imports(imports) self.api._ixnetwork.Globals.Topology.ApplyOnTheFly() return names @@ -312,43 +300,66 @@ def set_device_state(self, payload): def _lacp_start_stop_pdu(self, state, index=1, lag_name=None): if lag_name is None: - lag_port_lacp = (self.api._ixnetwork.Lag.find() - .ProtocolStack.find().Ethernet.find() - .Lagportlacp.find()) - if state == 'up': + lag_port_lacp = ( + self.api._ixnetwork.Lag.find() + .ProtocolStack.find() + .Ethernet.find() + .Lagportlacp.find() + ) + if state == "up": lag_port_lacp.LacpStartPDU() - elif state == 'down': + elif state == "down": lag_port_lacp.LacpStopPDU() else: - lag_port_lacp = (self.api._ixnetwork.Lag.find(Name=lag_name) - .ProtocolStack.find().Ethernet.find() - .Lagportlacp.find()) - if state == 'up': + lag_port_lacp = ( + self.api._ixnetwork.Lag.find(Name=lag_name) + .ProtocolStack.find() + .Ethernet.find() + .Lagportlacp.find() + ) + if state == "up": lag_port_lacp.LacpStartPDU(SessionIndices=index) - elif state == 'down': + elif state == "down": lag_port_lacp.LacpStopPDU(SessionIndices=index) def get_states(self, request): self.logger.debug("get_states for %s" % request.choice) if request.choice == "ipv4_neighbors": - ip_objs = self.api._ixnetwork.Topology.find().DeviceGroup.find().Ethernet.find().Ipv4.find() + ip_objs = ( + self.api._ixnetwork.Topology.find() + .DeviceGroup.find() + .Ethernet.find() + .Ipv4.find() + ) resolved_mac_list = self._get_ether_resolved_mac( - ip_objs, self.ether_v4gateway_map, request.ipv4_neighbors, "ipv4" + ip_objs, + self.ether_v4gateway_map, + request.ipv4_neighbors, + "ipv4", ) elif request.choice == "ipv6_neighbors": - ip_objs = self.api._ixnetwork.Topology.find().DeviceGroup.find().Ethernet.find().Ipv6.find() + ip_objs = ( + self.api._ixnetwork.Topology.find() + .DeviceGroup.find() + .Ethernet.find() + .Ipv6.find() + ) resolved_mac_list = self._get_ether_resolved_mac( - ip_objs, self.ether_v6gateway_map, request.ipv6_neighbors, "ipv6" + ip_objs, + self.ether_v6gateway_map, + request.ipv6_neighbors, + "ipv6", ) else: - raise TypeError("get_states only accept ipv4_neighbors or ipv6_neighbors") + raise TypeError( + "get_states only accept ipv4_neighbors or ipv6_neighbors" + ) - return { - "choice": request.choice, - request.choice: resolved_mac_list - } + return {"choice": request.choice, request.choice: resolved_mac_list} - def _get_ether_resolved_mac(self, ip_objs, ether_gateway_map, ip_neighbors, choice): + def _get_ether_resolved_mac( + self, ip_objs, ether_gateway_map, ip_neighbors, choice + ): arp_entries = {} for ip_obj in ip_objs: resolved_mac_list = ip_obj.ResolvedGatewayMac @@ -366,27 +377,34 @@ def _get_ether_resolved_mac(self, ip_objs, ether_gateway_map, ip_neighbors, choi gateway_ips = ether_gateway_map[ethernet_name] for gateway_ip in gateway_ips: if gateway_ip not in arp_entries: - raise Exception("{} not found within current configured gateway ips".format( - gateway_ip - )) + raise Exception( + "{} not found within current configured gateway ips".format( + gateway_ip + ) + ) if choice == "ipv4": - resolved_mac_list.append({ - "ethernet_name": ethernet_name, - "ipv4_address": gateway_ip, - "link_layer_address": arp_entries[gateway_ip] - }) + resolved_mac_list.append( + { + "ethernet_name": ethernet_name, + "ipv4_address": gateway_ip, + "link_layer_address": arp_entries[gateway_ip], + } + ) elif choice == "ipv6": - resolved_mac_list.append({ - "ethernet_name": ethernet_name, - "ipv6_address": gateway_ip, - "link_layer_address": arp_entries[gateway_ip] - }) - self.logger.debug("These are resolved_mac_list: %s" % resolved_mac_list) + resolved_mac_list.append( + { + "ethernet_name": ethernet_name, + "ipv6_address": gateway_ip, + "link_layer_address": arp_entries[gateway_ip], + } + ) + self.logger.debug( + "These are resolved_mac_list: %s" % resolved_mac_list + ) return resolved_mac_list def _get_href(self, xpath): - return xpath.replace('[', '/').\ - replace(']', '') + return xpath.replace("[", "/").replace("]", "") def select_properties(self, xpath, properties=[]): href = self._get_href(xpath) @@ -399,9 +417,9 @@ def select_properties(self, xpath, properties=[]): "inlines": [ { "child": "multivalue", - "properties": ["format", "pattern", "values"] + "properties": ["format", "pattern", "values"], } - ] + ], } ] } @@ -445,5 +463,3 @@ def configure_value(self, source, attribute, value, enum_map=None): "value": value, } return ixn_value - - diff --git a/snappi_ixnetwork/device/utils.py b/snappi_ixnetwork/device/utils.py index 90aaa2be2..318b945ca 100644 --- a/snappi_ixnetwork/device/utils.py +++ b/snappi_ixnetwork/device/utils.py @@ -1,6 +1,7 @@ import re from collections import namedtuple, Mapping + def namedtuple_with_defaults(typename, field_names, default_values=()): T = namedtuple(typename, field_names) T.__new__.__defaults__ = (None,) * len(T._fields) @@ -14,8 +15,8 @@ def namedtuple_with_defaults(typename, field_names, default_values=()): def asdot2plain(asdot): """This returns an ASPLAIN formated ASN given an ASDOT+ format""" - if re.findall(r'\.|\:', asdot): - left, right = re.split(r'\.|\:', asdot) + if re.findall(r"\.|\:", asdot): + left, right = re.split(r"\.|\:", asdot) ret = int(left) * 65536 + int(right) return ret else: @@ -23,9 +24,11 @@ def asdot2plain(asdot): def convert_as_values(as_types, as_values): - ConvertedAsValues = namedtuple_with_defaults("ConvertedAsValues", - ("as_num", "as4_num", "ip_addr", "assign_num", "common_num"), - ([], [], [], [], [])) + ConvertedAsValues = namedtuple_with_defaults( + "ConvertedAsValues", + ("as_num", "as4_num", "ip_addr", "assign_num", "common_num"), + ([], [], [], [], []), + ) convert_values = ConvertedAsValues() for idx, as_type in enumerate(as_types): @@ -45,7 +48,8 @@ def convert_as_values(as_types, as_values): convert_values.ip_addr[idx] = num return convert_values + def hex_to_ipv4(hex_value): bytes = ["".join(x) for x in zip(*[iter(hex_value)] * 2)] bytes = [int(x, 16) for x in bytes] - return ".".join(str(x) for x in reversed(bytes)) \ No newline at end of file + return ".".join(str(x) for x in reversed(bytes)) diff --git a/snappi_ixnetwork/device/vxlan.py b/snappi_ixnetwork/device/vxlan.py index c1ad90311..ae6c687d3 100644 --- a/snappi_ixnetwork/device/vxlan.py +++ b/snappi_ixnetwork/device/vxlan.py @@ -2,10 +2,11 @@ from snappi_ixnetwork.logger import get_ixnet_logger from snappi_ixnetwork.device.utils import namedtuple_with_defaults + class VXLAN(Base): - SourceInterface = namedtuple_with_defaults("SourceInterface", - ("ipv4", "ipv6"), - ([], [])) + SourceInterface = namedtuple_with_defaults( + "SourceInterface", ("ipv4", "ipv6"), ([], []) + ) def __init__(self, ngpf): super(VXLAN, self).__init__() @@ -19,13 +20,11 @@ def source_interfaces(self): def config(self, vxlan): v4_tunnels = vxlan.get("v4_tunnels") - if v4_tunnels is not None and len( - v4_tunnels) > 0: + if v4_tunnels is not None and len(v4_tunnels) > 0: self._config_v4_tunnels(v4_tunnels) v6_tunnels = vxlan.get("v6_tunnels") - if v6_tunnels is not None and len( - v6_tunnels) > 0: + if v6_tunnels is not None and len(v6_tunnels) > 0: self._config_v6_tunnels(v6_tunnels) def _store_source_interface(self, ixn_inter, ip_type): @@ -44,9 +43,11 @@ def _config_v4_tunnels(self, v4_tunnels): self._ngpf.working_dg = ixnet_info.working_dg ip_type = self._ngpf.api.get_device_encap(source_interface) if ip_type != "ipv4": - raise TypeError("source_interface {} should support IPv4".format( - source_interface - )) + raise TypeError( + "source_interface {} should support IPv4".format( + source_interface + ) + ) self._store_source_interface(ixn_inter, ip_type) ixn_vxlan = self.create_node_elemet( ixn_inter, "vxlan", v4_tunnel.get("name") @@ -57,9 +58,7 @@ def _config_v4_tunnels(self, v4_tunnels): destination_ip_mode = v4_tunnel.destination_ip_mode if destination_ip_mode.choice == "unicast": ixn_vxlan["enableStaticInfo"] = True - self._config_v4_unicast( - destination_ip_mode.unicast, ixn_vxlan - ) + self._config_v4_unicast(destination_ip_mode.unicast, ixn_vxlan) else: ixn_vxlan["enableStaticInfo"] = False ixn_vxlan["ipv4_multicast"] = self.as_multivalue( @@ -74,9 +73,11 @@ def _config_v6_tunnels(self, v6_tunnels): self._ngpf.working_dg = ixnet_info.working_dg ip_type = self._ngpf.api.get_device_encap(source_interface) if ip_type != "ipv6": - raise TypeError("source_interface {} should support IPv6".format( - source_interface - )) + raise TypeError( + "source_interface {} should support IPv6".format( + source_interface + ) + ) self._store_source_interface(ixn_inter, ip_type) ixn_vxlan6 = self.create_node_elemet( ixn_inter, "vxlanv6", v6_tunnel.get("name") @@ -98,12 +99,16 @@ def _config_v6_tunnels(self, v6_tunnels): def _get_all_info(self, unicast): ixn_info_count = 0 - AllInfo = namedtuple_with_defaults("AllInfo", - ("remote_vtep_address", - "suppress_arp", - "remote_vm_mac", - "remote_vm_ipv4"), - ([], [], [], [])) + AllInfo = namedtuple_with_defaults( + "AllInfo", + ( + "remote_vtep_address", + "suppress_arp", + "remote_vm_mac", + "remote_vm_ipv4", + ), + ([], [], [], []), + ) all_info = AllInfo() vteps = unicast.vteps for vtep in vteps: @@ -129,11 +134,20 @@ def _config_v4_unicast(self, unicast, ixn_vxlan, v4_tunnel=True): ixn_vxlan["staticInfoCount"] = ixn_info_count if v4_tunnel is True: ixn_unicast = self.create_node_elemet(ixn_vxlan, "vxlanStaticInfo") - ixn_unicast["remoteVtepIpv4"] = self.multivalue(all_info.remote_vtep_address) + ixn_unicast["remoteVtepIpv4"] = self.multivalue( + all_info.remote_vtep_address + ) else: - ixn_unicast = self.create_node_elemet(ixn_vxlan, "vxlanIPv6StaticInfo") - ixn_unicast["remoteVtepUnicastIpv6"] = self.multivalue(all_info.remote_vtep_address) + ixn_unicast = self.create_node_elemet( + ixn_vxlan, "vxlanIPv6StaticInfo" + ) + ixn_unicast["remoteVtepUnicastIpv6"] = self.multivalue( + all_info.remote_vtep_address + ) ixn_unicast["suppressArp"] = self.multivalue(all_info.suppress_arp) - ixn_unicast["remoteVmStaticMac"] = self.multivalue(all_info.remote_vm_mac) - ixn_unicast["remoteVmStaticIpv4"] = self.multivalue(all_info.remote_vm_ipv4) - + ixn_unicast["remoteVmStaticMac"] = self.multivalue( + all_info.remote_vm_mac + ) + ixn_unicast["remoteVmStaticIpv4"] = self.multivalue( + all_info.remote_vm_ipv4 + ) diff --git a/snappi_ixnetwork/lag.py b/snappi_ixnetwork/lag.py index cf5123a22..2079204f8 100644 --- a/snappi_ixnetwork/lag.py +++ b/snappi_ixnetwork/lag.py @@ -51,7 +51,7 @@ class Lag(object): "actor_system_id": { "ixn_attr": "actorSystemId", "default": "00 00 00 00 00 01", - "translate": "_translate_actor_system_id" + "translate": "_translate_actor_system_id", }, "actor_system_priority": { "ixn_attr": "actorSystemPriority", @@ -267,14 +267,10 @@ def _lacp_ports_config(self, name, ports): lacp_port_protocols.append(lacp_port_protocol) if len(ixn_static) > 0: ixn_static.remove() - lacp_xpath = ( - "{0}/protocolStack/ethernet[1]/lagportlacp[1]".format( - ixn_lags[name]["xpath"] - ) - ) - imports.append( - self._set_multivalue(lacp_xpath, "active", True) + lacp_xpath = "{0}/protocolStack/ethernet[1]/lagportlacp[1]".format( + ixn_lags[name]["xpath"] ) + imports.append(self._set_multivalue(lacp_xpath, "active", True)) for lacp_attr in Lag._LACP_PORT_PROTOCOL: attr_values = self._configure_attribute( lacp_attr, Lag._LACP_PORT_PROTOCOL, lacp_port_protocols @@ -333,7 +329,8 @@ def _protocol_config(self): ) ) lacp_port_imports = self._lacp_ports_config( - snappi_lag.name, snappi_lag.ports) + snappi_lag.name, snappi_lag.ports + ) imports += lacp_port_imports else: if len(ixn_lacp) > 0: diff --git a/snappi_ixnetwork/logger.py b/snappi_ixnetwork/logger.py index 12d5b2587..201619ec9 100644 --- a/snappi_ixnetwork/logger.py +++ b/snappi_ixnetwork/logger.py @@ -1,14 +1,16 @@ import sys import logging -APP_LOGGER_NAME = 'snappi_ixnetwork' +APP_LOGGER_NAME = "snappi_ixnetwork" def setup_ixnet_logger(log_level, file_name=None, module_name=None): logger = logging.getLogger(APP_LOGGER_NAME) logger.setLevel(log_level) - formatter = logging.Formatter(fmt="%(asctime)s [%(name)s] [%(levelname)s] %(message)s", - datefmt="%Y-%m-%d %H:%M:%S") + formatter = logging.Formatter( + fmt="%(asctime)s [%(name)s] [%(levelname)s] %(message)s", + datefmt="%Y-%m-%d %H:%M:%S", + ) sh = logging.StreamHandler(sys.stdout) sh.setFormatter(formatter) if len(logger.handlers) > 0: @@ -25,4 +27,4 @@ def setup_ixnet_logger(log_level, file_name=None, module_name=None): def get_ixnet_logger(module_name): module_name = ".".join(str(module_name).split(".")[1:]) - return logging.getLogger(APP_LOGGER_NAME).getChild(module_name) \ No newline at end of file + return logging.getLogger(APP_LOGGER_NAME).getChild(module_name) diff --git a/snappi_ixnetwork/objectdb.py b/snappi_ixnetwork/objectdb.py index 3a949f155..7e3cbe6d7 100644 --- a/snappi_ixnetwork/objectdb.py +++ b/snappi_ixnetwork/objectdb.py @@ -11,17 +11,13 @@ def __init__(self, ixnetworkapi): def get_href(self, name): """Returns an href given a unique configuration name""" obj = self.get(name) - self.logger.debug("get_href %s : %s" %( - name, obj.href - )) + self.logger.debug("get_href %s : %s" % (name, obj.href)) return obj.href def get_xpath(self, name): """Returns an xpath given a unique configuration name""" obj = self.get(name) - self.logger.debug("get_xpath %s : %s" %( - name, obj.xpath - )) + self.logger.debug("get_xpath %s : %s" % (name, obj.xpath)) return obj.xpath def get_object(self, name): @@ -40,9 +36,7 @@ def get(self, name): except KeyError: self.logger.debug("These are existing names %s" % self.names) raise NameError( - "snappi object named {0} not found in internal db".format( - name - ) + "snappi object named {0} not found in internal db".format(name) ) def get_working_dg(self, name): @@ -74,13 +68,15 @@ def set_scalable(self, ixnobject): self.get_working_dg(names[0]), index=index, multiplier=names.count(name), - names=names + names=names, ) class IxNetInfo(object): # index start with 0 and use multiplier for count - def __init__(self, ixnobject, working_dg, index=0, multiplier=1, names=None): + def __init__( + self, ixnobject, working_dg, index=0, multiplier=1, names=None + ): self.ixnobject = ixnobject self.working_dg = working_dg self.index = int(index) @@ -94,4 +90,3 @@ def xpath(self): @property def href(self): return self.ixnobject.get("href") - diff --git a/snappi_ixnetwork/protocolmetrics.py b/snappi_ixnetwork/protocolmetrics.py index d964f490f..1274d546b 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)): + # 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 073380ae4..a1c4cd929 100644 --- a/snappi_ixnetwork/snappi_api.py +++ b/snappi_ixnetwork/snappi_api.py @@ -34,6 +34,7 @@ class Api(snappi.Api): - password (str): The password for Linux IxNetwork API Server This is not required when connecting to single session environments """ + def __init__(self, **kwargs): """Create a session - address (str): The ip address of the TestPlatform to connect to @@ -47,11 +48,12 @@ def __init__(self, **kwargs): username = kwargs.get("username") password = kwargs.get("password") license_servers = kwargs.get("license_servers") - self._log_level = logging.INFO if kwargs.get("loglevel") is None \ + self._log_level = ( + logging.INFO + if kwargs.get("loglevel") is None else kwargs.get("loglevel") - self.logger = setup_ixnet_logger( - self.log_level, module_name=__name__ ) + self.logger = setup_ixnet_logger(self.log_level, module_name=__name__) location = "https://127.0.0.1:11009" if location is None else location self._address, self._port = self._get_addr_port(location) self._username = "admin" if username is None else username @@ -196,13 +198,17 @@ def _request_detail(self): if len(match) == 0: if error.ErrorLevel == "kWarning": warning = "IxNet - {0}".format( - error.Name if error.Description == "" else error.Description + error.Name + if error.Description == "" + else error.Description ) self.info(warning) warnings.append(warning) if error.ErrorLevel == "kError": error = "IxNet - {0}".format( - error.Name if error.Description == "" else error.Description + error.Name + if error.Description == "" + else error.Description ) self.info(error) errors.append(error) @@ -210,8 +216,11 @@ def _request_detail(self): # Need to add this hack as dumping json config throws this exception # Traffic regeneration will be part of set_transmit_state - errors = [error for error in errors - if "before trying to generate BGP EVPN traffic" not in error] + errors = [ + error + for error in errors + if "before trying to generate BGP EVPN traffic" not in error + ] if len(errors) > 0: self._errors = [] @@ -291,8 +300,11 @@ def config_ixnetwork(self, config): if len(self.lag._lags_config) > 0: for lag in self.lag._lags_config: if lag.min_links > len(lag.ports): - self.warning("ports in {0} are less than configured minimum links {1} so {0} is inactive ".format( - lag.name, lag.min_links)) + self.warning( + "ports in {0} are less than configured minimum links {1} so {0} is inactive ".format( + lag.name, lag.min_links + ) + ) self._ixnetwork.Lag.find(Name=lag.name).Stop() def _protocols_exists(self): @@ -302,24 +314,32 @@ def _protocols_exists(self): if len(topos) > 0: dgs = topos.DeviceGroup.find() if len(dgs) > 0: - eth_dev = len(self._ixnetwork.Topology.find() - .DeviceGroup.find() - .Ethernet.find()) + eth_dev = len( + self._ixnetwork.Topology.find() + .DeviceGroup.find() + .Ethernet.find() + ) ethv4v6_dev_count = ethv4v6_dev_count + eth_dev if eth_dev > 0: - v4_dev = len(self._ixnetwork.Topology.find() - .DeviceGroup.find() - .Ethernet.find().Ipv4.find()) + v4_dev = len( + self._ixnetwork.Topology.find() + .DeviceGroup.find() + .Ethernet.find() + .Ipv4.find() + ) ethv4v6_dev_count = ethv4v6_dev_count + v4_dev - v6_dev = len(self._ixnetwork.Topology.find() - .DeviceGroup.find() - .Ethernet.find().Ipv6.find()) + v6_dev = len( + self._ixnetwork.Topology.find() + .DeviceGroup.find() + .Ethernet.find() + .Ipv6.find() + ) ethv4v6_dev_count = ethv4v6_dev_count + v6_dev - if (total_dev > ethv4v6_dev_count): + if total_dev > ethv4v6_dev_count: return True else: return False - + def set_control_state(self, payload): try: control_option = payload.choice @@ -344,7 +364,7 @@ def set_control_state(self, payload): except Exception as err: raise SnappiIxnException(err) return self._request_detail() - + def set_control_action(self, payload): try: control_option = payload.choice @@ -357,19 +377,23 @@ def set_control_action(self, payload): if choice == "ping": res = self.control_action_response() self._connect() - res.response.protocol.ipv4.ping.responses.deserialize(self.ping.results(control_choice, request_payload)) + 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() + 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( @@ -521,7 +545,6 @@ 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: @@ -709,9 +732,7 @@ def _get_restpy_trace(self, log_level): def _connect(self): """Connect to an IxNetwork API Server.""" self._errors = [] - self.logger = setup_ixnet_logger( - self.log_level, module_name=__name__ - ) + self.logger = setup_ixnet_logger(self.log_level, module_name=__name__) if self._assistant is None: platform = TestPlatform(self._address, rest_port=self._port) platform.Authenticate(self._username, self._password) @@ -731,9 +752,7 @@ def _connect(self): RestPort=self._port, UserName=self._username, Password=self._password, - LogLevel=self._get_restpy_trace( - self._log_level - ) + LogLevel=self._get_restpy_trace(self._log_level), ) self._ixnetwork = self._assistant.Session.Ixnetwork self._vport = self._ixnetwork.Vport @@ -1188,9 +1207,10 @@ def select_chassis_card_port(self, location): return results[0]["chassis"][0]["card"][0]["port"][0]["xpath"] def clear_ownership(self, available_hardware_hrefs, location_hrefs): - self.debug("Clearing ownership %s from %s" % ( - available_hardware_hrefs, location_hrefs - )) + self.debug( + "Clearing ownership %s from %s" + % (available_hardware_hrefs, location_hrefs) + ) hrefs = list(available_hardware_hrefs.values()) + list( location_hrefs.values() ) @@ -1230,19 +1250,20 @@ def warning(self, message): def get_version(self): try: import pkg_resources + sdk_version = ( - "snappi-" - + pkg_resources.get_distribution("snappi").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} + "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 + raise SnappiIxnException("unable to get version") diff --git a/snappi_ixnetwork/snappi_convergence_api.py b/snappi_ixnetwork/snappi_convergence_api.py index 1357c65d4..6f4fbe5a2 100644 --- a/snappi_ixnetwork/snappi_convergence_api.py +++ b/snappi_ixnetwork/snappi_convergence_api.py @@ -30,7 +30,6 @@ class Api(snappi_convergence.Api): _TRIGGERED_EVENT = "" def __init__(self, **kwargs): - self._convergence_timeout = 3 self._api = snappiApi(**kwargs) self._event_info = None diff --git a/snappi_ixnetwork/trafficitem.py b/snappi_ixnetwork/trafficitem.py index 8ed949de9..9d7f2ccf8 100644 --- a/snappi_ixnetwork/trafficitem.py +++ b/snappi_ixnetwork/trafficitem.py @@ -375,9 +375,11 @@ def __init__(self, ixnetworkapi): self.logger = get_ixnet_logger(__name__) def _get_search_payload(self, parent, child, properties, filters): - self.logger.debug("Searching parent {} child {} with properties {} filters {}".format( - parent, child, properties, filters - )) + self.logger.debug( + "Searching parent {} child {} with properties {} filters {}".format( + parent, child, properties, filters + ) + ) payload = { "selects": [ { @@ -398,7 +400,7 @@ def _get_search_payload(self, parent, child, properties, filters): self._api.assistant._ixnetwork.href ) self.logger.debug("Return of _get_search_payload:") - self.logger.debug("\turl : %s" %url) + self.logger.debug("\turl : %s" % url) self.logger.debug("\tpayload : %s" % payload) return (url, payload) @@ -537,9 +539,7 @@ def remove_ixn_traffic(self): self.traffic_index = 1 def _gen_dev_endpoint(self, devices, names, endpoints, scalable_endpoints): - self.logger.debug( - "Generating Device Endpoints with names %s" % names - ) + self.logger.debug("Generating Device Endpoints with names %s" % names) while len(names) > 0: gen_name = None name = names[0] @@ -580,9 +580,7 @@ def create_traffic(self, config): devices = self.get_device_info(config) for index, flow in enumerate(flows): flow_name = flow._properties.get("name") - self.logger.debug( - "Creating Traffic Item %s" % flow_name - ) + self.logger.debug("Creating Traffic Item %s" % flow_name) if flow_name is None: raise Exception("name shall not be null for flows") if flow._properties.get("tx_rx") is None: @@ -1045,7 +1043,7 @@ def _config_field_pattern( "decrement": "decrement", "auto": "auto", "generated": "auto", - "custom": "singleValue" + "custom": "singleValue", } def get_value(field_value): @@ -1258,9 +1256,10 @@ def transmit(self, request): elif len(flow_names) > 1: regex = "^(%s)$" % "|".join(self._api.special_char(flow_names)) - self.logger.debug("These %s flows will go into %s state" % ( - flow_names, request.state - )) + self.logger.debug( + "These %s flows will go into %s state" + % (flow_names, request.state) + ) if request.state == "start": if len(self._api._topology.find()) > 0: glob_topo = self._api._globals.Topology.refresh() @@ -1380,9 +1379,10 @@ def results(self, request): raise Exception(msg) req_flow_names = self._api.special_char(req_flow_names) # initialize result values - self.logger.debug("Fetching these column %s for flows %s" %( - self._column_names, req_flow_names - )) + self.logger.debug( + "Fetching these column %s for flows %s" + % (self._column_names, req_flow_names) + ) flow_names = [] flow_rows = {} regfilter = {"property": "name", "regex": ".*"} diff --git a/snappi_ixnetwork/validation.py b/snappi_ixnetwork/validation.py index 75d404874..da212a27c 100644 --- a/snappi_ixnetwork/validation.py +++ b/snappi_ixnetwork/validation.py @@ -56,7 +56,9 @@ def __check_config_objects(self, config_item, item_ids): continue if getattr(item, "parent", None) is not None: item_ids.append(item_id) - self.__check_config_objects(item.parent, item_ids) + self.__check_config_objects( + item.parent, item_ids + ) else: self.__check_config_objects(item, item_ids) else: diff --git a/snappi_ixnetwork/vport.py b/snappi_ixnetwork/vport.py index 96b0218ac..9ddc792b5 100644 --- a/snappi_ixnetwork/vport.py +++ b/snappi_ixnetwork/vport.py @@ -143,11 +143,14 @@ def config(self): self._ixn_vport = self._api._vport self._layer1_check = [] self._api._ixnetwork.StopAllProtocols(arg1="sync") - self._wait_for(lambda: self.is_protocols_stopped(), - """"Protocols are not stopped in {} seconds""".format( - self._interval * self._timeout), - self._interval, - self._timeout) + self._wait_for( + lambda: self.is_protocols_stopped(), + """"Protocols are not stopped in {} seconds""".format( + self._interval * self._timeout + ), + self._interval, + self._timeout, + ) with Timer(self._api, "Ports configuration"): self._delete_vports() self._create_vports() @@ -177,9 +180,10 @@ def is_protocols_stopped(self): eth_list = dgs.Ethernet.find() if len(eth_list) > 0: if len(eth_list.Ipv4.find()) > 0: - if any('up' in status or 'down' in status - for status in - dgs.Ethernet.find().SessionStatus): + if any( + "up" in status or "down" in status + for status in dgs.Ethernet.find().SessionStatus + ): stopped = False return stopped @@ -742,9 +746,10 @@ def results(self, request): ) raise Exception(msg) - self.logger.debug("Extracting %s stats for these ports %s" % ( - self._column_names, port_names - )) + self.logger.debug( + "Extracting %s stats for these ports %s" + % (self._column_names, port_names) + ) port_filter = {"property": "name", "regex": ".*"} port_filter["regex"] = "^(%s)$" % "|".join( self._api.special_char(port_names) diff --git a/tests/arp/test_arp_packet.py b/tests/arp/test_arp_packet.py index f547d0e4f..c0f6039df 100644 --- a/tests/arp/test_arp_packet.py +++ b/tests/arp/test_arp_packet.py @@ -54,12 +54,8 @@ def test_arp_packet(api, b2b_raw_config_vports, utils, tx_vport, rx_vport): target_hardware_addr_list = utils.mac_or_ip_addr_from_counter_pattern( "00:0c:29:e3:53:f4", flow3_step, flow3_count, True ) - sender_protocol_addr_list = [ - "10.10.0.1", "10.10.0.2", "10.10.0.3" - ] - target_protocol_addr_list = [ - "20.20.0.1", "20.20.0.2", "20.20.0.3" - ] + sender_protocol_addr_list = ["10.10.0.1", "10.10.0.2", "10.10.0.3"] + target_protocol_addr_list = ["20.20.0.1", "20.20.0.2", "20.20.0.3"] flow3.tx_rx.port.tx_name = tx_vport.name flow3.tx_rx.port.rx_name = rx_vport.name flow3.packet.ethernet().arp() @@ -82,13 +78,33 @@ def test_arp_packet(api, b2b_raw_config_vports, utils, tx_vport, rx_vport): f2_attrs = { "ethernetARP.header.hardwareType": "{:x}".format(int(hardware_type)), "ethernetARP.header.protocolType": "{:x}".format(int(protocol_type)), - "ethernetARP.header.hardwareAddressLength": "{:x}".format(int(hardware_length)), - "ethernetARP.header.protocolAddressLength": "{:x}".format(int(protocol_length)), + "ethernetARP.header.hardwareAddressLength": "{:x}".format( + int(hardware_length) + ), + "ethernetARP.header.protocolAddressLength": "{:x}".format( + int(protocol_length) + ), "ethernetARP.header.opCode": str(operation), - "ethernetARP.header.srcHardwareAddress": (sender_hardware_addr.lower(), mac_step, str(count)), - "ethernetARP.header.dstHardwareAddress": (target_hardware_addr.lower(), mac_step, str(count)), - "ethernetARP.header.srcIP": (sender_protocol_addr, ip_step, str(count)), - "ethernetARP.header.dstIP": (target_protocol_addr, ip_step, str(count)), + "ethernetARP.header.srcHardwareAddress": ( + sender_hardware_addr.lower(), + mac_step, + str(count), + ), + "ethernetARP.header.dstHardwareAddress": ( + target_hardware_addr.lower(), + mac_step, + str(count), + ), + "ethernetARP.header.srcIP": ( + sender_protocol_addr, + ip_step, + str(count), + ), + "ethernetARP.header.dstIP": ( + target_protocol_addr, + ip_step, + str(count), + ), } utils.validate_config(api, "f2", "ethernetARP", **f2_attrs) @@ -100,5 +116,6 @@ def test_arp_packet(api, b2b_raw_config_vports, utils, tx_vport, rx_vport): } utils.validate_config(api, "f3", "ethernetARP", **f3_attrs) + if __name__ == "__main__": - pytest.main(["-s", __file__]) \ No newline at end of file + pytest.main(["-s", __file__]) diff --git a/tests/arp/test_arp_packet_e2e.py b/tests/arp/test_arp_packet_e2e.py index be916a57e..7e82f293a 100644 --- a/tests/arp/test_arp_packet_e2e.py +++ b/tests/arp/test_arp_packet_e2e.py @@ -81,11 +81,11 @@ def captures_ok(api, cfg, size, utils): [0x00, 0x0C, 0x30, 0xE3, 0x50, 0xEA], ] sender_protocol_addr = [ - [0x0a, 0x01, 0x01, 0x02], - [0x0a, 0x01, 0x01, 0x03], - [0x0a, 0x01, 0x01, 0x04], - [0x0a, 0x01, 0x01, 0x05], - [0x0a, 0x01, 0x01, 0x06], + [0x0A, 0x01, 0x01, 0x02], + [0x0A, 0x01, 0x01, 0x03], + [0x0A, 0x01, 0x01, 0x04], + [0x0A, 0x01, 0x01, 0x05], + [0x0A, 0x01, 0x01, 0x06], ] target_protocol_addr = [ [0x14, 0x01, 0x01, 0x05], @@ -109,4 +109,4 @@ def captures_ok(api, cfg, size, utils): if __name__ == "__main__": - pytest.main(["-s", __file__]) \ No newline at end of file + pytest.main(["-s", __file__]) diff --git a/tests/bgp/test_bgp_attributes.py b/tests/bgp/test_bgp_attributes.py index 4d4d3a8c8..6a1ae6201 100644 --- a/tests/bgp/test_bgp_attributes.py +++ b/tests/bgp/test_bgp_attributes.py @@ -89,7 +89,7 @@ def test_bgp_attributes(api, utils): ipv6.gateway = "2000::2" bgpv6 = device.bgp bgpv6.router_id = "192.0.0.1" - bgpv6_int = bgpv6.ipv6_interfaces.add() + bgpv6_int = bgpv6.ipv6_interfaces.add() bgpv6_int.ipv6_name = ipv6.name bgp6_peer = bgpv6_int.peers.add() bgp6_peer.name = "rx_bgpv6" @@ -183,8 +183,8 @@ def validate_community_config(api, community, aspaths, med, origin): assert last_two_octets == community.split(":")[1] as_paths = bgpv4.AsPathASString - as_paths = as_paths[0].replace('}', '').replace('{', '') - as_paths = as_paths.split(',') + as_paths = as_paths[0].replace("}", "").replace("{", "") + as_paths = as_paths.split(",") as_paths = [int(ele) for ele in as_paths] assert as_paths == aspaths @@ -198,8 +198,8 @@ def validate_community_config(api, community, aspaths, med, origin): assert last_two_octets == community.split(":")[1] as_paths = bgpv6.AsPathASString - as_paths = as_paths[0].replace('}', '').replace('{', '') - as_paths = as_paths.split(',') + as_paths = as_paths[0].replace("}", "").replace("{", "") + as_paths = as_paths.split(",") as_paths = [int(ele) for ele in as_paths] assert as_paths == aspaths diff --git a/tests/bgp/test_bgp_sr_te_1000_policies.py b/tests/bgp/test_bgp_sr_te_1000_policies.py index ef045e12f..b99b4c23c 100644 --- a/tests/bgp/test_bgp_sr_te_1000_policies.py +++ b/tests/bgp/test_bgp_sr_te_1000_policies.py @@ -1,6 +1,7 @@ import pytest from functools import reduce + @pytest.mark.skip("New SR TE model is not available") def test_bgp_sr_te_1000_policies(api): """ diff --git a/tests/bgp/test_bgp_sr_te_policy_v4v6.py b/tests/bgp/test_bgp_sr_te_policy_v4v6.py index 663b8d4ca..00959e75d 100644 --- a/tests/bgp/test_bgp_sr_te_policy_v4v6.py +++ b/tests/bgp/test_bgp_sr_te_policy_v4v6.py @@ -1,5 +1,6 @@ import pytest + @pytest.mark.skip("New SR TE model is not available") def test_bgp_sr_te_policy_v4v6(api): """ diff --git a/tests/bgp/test_bgp_sr_te_weighted.py b/tests/bgp/test_bgp_sr_te_weighted.py index deeca3bcc..df3739234 100644 --- a/tests/bgp/test_bgp_sr_te_weighted.py +++ b/tests/bgp/test_bgp_sr_te_weighted.py @@ -1,5 +1,6 @@ import pytest + @pytest.mark.skip("New SR TE model is not available") def test_bgp_sr_te_weighted(api): """ diff --git a/tests/bgp/test_bgpv4_stats.py b/tests/bgp/test_bgpv4_stats.py index 01db1ba6f..ba0e38fab 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 diff --git a/tests/bgp_evpn/test_bgp_evpn.py b/tests/bgp_evpn/test_bgp_evpn.py index b7fadd207..7e3771674 100644 --- a/tests/bgp_evpn/test_bgp_evpn.py +++ b/tests/bgp_evpn/test_bgp_evpn.py @@ -1,47 +1,49 @@ 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] + 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_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] + 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] + 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] + 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] + 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() @@ -61,15 +63,15 @@ def test_bgp_evpn(api, utils): 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 = 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_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] @@ -78,7 +80,8 @@ def test_bgp_evpn(api, utils): 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.AS_2OCTET + ) tx_es1_evisV4_1.route_distinguisher.rd_value = "100:1" export_rt = tx_es1_evisV4_1.route_target_export.routetarget()[-1] @@ -90,14 +93,14 @@ def test_bgp_evpn(api, utils): 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]) + 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 = ( + 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" @@ -106,15 +109,15 @@ def test_bgp_evpn(api, utils): 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 = 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] + 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] @@ -123,7 +126,8 @@ def test_bgp_evpn(api, utils): 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.AS_2OCTET + ) rx_es1_evisV4_1.route_distinguisher.rd_value = "1000:1" export_rt = rx_es1_evisV4_1.route_target_export.routetarget()[-1] @@ -135,14 +139,14 @@ def test_bgp_evpn(api, utils): 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]) + 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 = ( + 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" diff --git a/tests/bgp_evpn/test_bgp_evpn_attribute_validation.py b/tests/bgp_evpn/test_bgp_evpn_attribute_validation.py index 5ddb889c2..014d553d9 100644 --- a/tests/bgp_evpn/test_bgp_evpn_attribute_validation.py +++ b/tests/bgp_evpn/test_bgp_evpn_attribute_validation.py @@ -16,7 +16,7 @@ def test_bgp_evpn_validation(api, utils): "EnableCommunity": "true", "EnableExtendedCommunity": "true", "EnableAsPathSegments": "true", - "AsSetMode": "includelocalasasasset" + "AsSetMode": "includelocalasasasset", } BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST = { @@ -28,7 +28,7 @@ def test_bgp_evpn_validation(api, utils): BGPV4_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST = { "Type": "opaque", "SubType": "color", - "ColorValue": "200" + "ColorValue": "200", } BGPV4_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST = { @@ -40,80 +40,78 @@ def test_bgp_evpn_validation(api, utils): "UpstreamDownstreamAssignedMplsLabel": 20, "RdASNumber": 1000, "RdEvi": 10, - "MultiExitDiscriminator": 99 + "MultiExitDiscriminator": 99, } BGPV4_EVPN_VXLAN_EXPORT_TARGET = { "TargetAs4Number": "100", - "TargetAssignedNumber": "20" + "TargetAssignedNumber": "20", } BGPV4_EVPN_VXLAN_IMPORT_TARGET = { "TargetAs4Number": "200", - "TargetAssignedNumber": "30" + "TargetAssignedNumber": "30", } BGPV4_EVPN_VXLAN_L3_EXPORT_TARGET = { "TargetAs4Number": "300", - "TargetAssignedNumber": "50" + "TargetAssignedNumber": "50", } BGPV4_EVPN_VXLAN_L3_IMPORT_TARGET = { "TargetAs4Number": "400", - "TargetAssignedNumber": "60" + "TargetAssignedNumber": "60", } - BROADCAST_DOMAIN = { - "EthernetTagId": "5", - "EnableVlanAwareService": "true" - } + BROADCAST_DOMAIN = {"EthernetTagId": "5", "EnableVlanAwareService": "true"} MAC_ADDRESS = { "Mac": "10:11:22:33:44:55", "PrefixLength": "48", - "NumberOfAddressesAsy": "1" + "NumberOfAddressesAsy": "1", } IP_ADDRESS = { "NetworkAddress": "2.2.2.2", "PrefixLength": "24", - "NumberOfAddressesAsy": "1" + "NumberOfAddressesAsy": "1", } IPV6_ADDRESS = { "NetworkAddress": "2000:0:2:1::1", "PrefixLength": "64", - "NumberOfAddressesAsy": "1" + "NumberOfAddressesAsy": "1", } CMAC_PROPERTIES = { "FirstLabelStart": "16", "SecondLabelStart": "20", "MultiExitDiscriminator": "37", - "IncludeDefaultGatewayExtendedCommunity": "true" + "IncludeDefaultGatewayExtendedCommunity": "true", } # Creating Ports config = api.config() - p1 = config.ports.port(name='p1', location=utils.settings.ports[0])[-1] + 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_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_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] + 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() @@ -124,31 +122,35 @@ def test_bgp_evpn_validation(api, utils): 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 = 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_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.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.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"]) + BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["AsNumber"] + ) tx_eth_seg_community.as_custom = int( - BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["LastTwoOctets"]) + 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" @@ -159,49 +161,60 @@ def test_bgp_evpn_validation(api, utils): # 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.AS_2OCTET + ) tx_evi_vxlan.route_distinguisher.rd_value = ( - str(BGPV4_EVPN_VXLAN["RdASNumber"]) + ":" + str( - BGPV4_EVPN_VXLAN["RdEvi"])) + 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"]) + 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"]) + 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"]) + 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"]) + 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"]) + 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.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"]) + BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["AsNumber"] + ) tx_evi_vxlan_comm.as_custom = int( - BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["LastTwoOctets"]) + 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" @@ -209,29 +222,34 @@ def test_bgp_evpn_validation(api, utils): 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 = tx_evi_vxlan.broadcast_domains.broadcastdomain()[ + -1 + ] tx_evpn_brodcast_domain.ethernet_tag_id = int( - BROADCAST_DOMAIN["EthernetTagId"]) + 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 = 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.ipv6_addresses.address = IPV6_ADDRESS[ + "NetworkAddress" + ] tx_broadcast_macrange.advanced.multi_exit_discriminator = int( - CMAC_PROPERTIES["MultiExitDiscriminator"]) + 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"]) + BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["AsNumber"] + ) cmac_comm.as_custom = int( - BGPV4_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["LastTwoOctets"]) + 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" @@ -240,42 +258,50 @@ def test_bgp_evpn_validation(api, utils): 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): + 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()) + ixn.Topology.find() + .DeviceGroup.find() + .DeviceGroup.find() + .Ipv4Loopback.find() + .BgpIpv4Peer.find() + ) for bgp in bgps: assert bgp.EthernetSegmentsCountV4 == 1 assert bgp.BgpEthernetSegmentV4.EvisCount == 1 @@ -284,8 +310,7 @@ def validate_config(api, bgp_eth_seg = bgps[0].BgpEthernetSegmentV4 for attr in BGPV4_EVPN_ETH_SEGMENT: - if attr in ["DfElectionTimer", "EsiLabel", - "MultiExitDiscriminator"]: + if attr in ["DfElectionTimer", "EsiLabel", "MultiExitDiscriminator"]: assert BGPV4_EVPN_ETH_SEGMENT[attr] == int( (getattr(bgp_eth_seg, attr).Values)[0] ) @@ -294,22 +319,25 @@ def validate_config(api, (getattr(bgp_eth_seg, attr).Values)[0] ) - bgp_eth_seg_comm_list = ( - bgps[0].BgpEthernetSegmentV4.BgpCommunitiesList.find()) + 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()) + 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()) + 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] @@ -322,102 +350,104 @@ def validate_config(api, ) bgp_evpn_vxlan_export_target = ( - bgp_evpn_vxlan.BgpExportRouteTargetList.find()) + 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()) + 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()) + 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()) + 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()) + 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()) + 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()) + 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) + 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()) + 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] - ) + assert MAC_ADDRESS[attr] == ((getattr(mac, attr).Values)[0]) - ipv4 = (mac.Ipv4PrefixPools.find()) + ipv4 = mac.Ipv4PrefixPools.find() for attr in IP_ADDRESS: - assert IP_ADDRESS[attr] == ( - (getattr(ipv4, attr).Values)[0] - ) + assert IP_ADDRESS[attr] == ((getattr(ipv4, attr).Values)[0]) - ipv6 = (mac.Ipv6PrefixPools.find()) + ipv6 = mac.Ipv6PrefixPools.find() for attr in IPV6_ADDRESS: - assert IPV6_ADDRESS[attr] == ( - (getattr(ipv6, attr).Values)[0] - ) + assert IPV6_ADDRESS[attr] == ((getattr(ipv6, attr).Values)[0]) - cmac = (mac.CMacProperties.find()) + cmac = mac.CMacProperties.find() for attr in CMAC_PROPERTIES: - assert CMAC_PROPERTIES[attr] == ( - (getattr(cmac, attr).Values)[0] - ) + assert CMAC_PROPERTIES[attr] == ((getattr(cmac, attr).Values)[0]) - cmac_comm_list = ( - cmac.BgpCommunitiesList.find()) + 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()) + 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()) + 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] diff --git a/tests/bgp_evpn/test_bgpv6_evpn_attribute_validation.py b/tests/bgp_evpn/test_bgpv6_evpn_attribute_validation.py index 702534e15..9cba1fa8a 100644 --- a/tests/bgp_evpn/test_bgpv6_evpn_attribute_validation.py +++ b/tests/bgp_evpn/test_bgpv6_evpn_attribute_validation.py @@ -16,7 +16,7 @@ def test_bgpv6_evpn_validation(api, utils): "EnableCommunity": "true", "EnableExtendedCommunity": "true", "EnableAsPathSegments": "true", - "AsSetMode": "includelocalasasasset" + "AsSetMode": "includelocalasasasset", } BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST = { @@ -28,7 +28,7 @@ def test_bgpv6_evpn_validation(api, utils): BGPV6_EVPN_ETH_SEGMENT_EXT_COMMUNITIES_lIST = { "Type": "opaque", "SubType": "color", - "ColorValue": "200" + "ColorValue": "200", } BGPV6_EVPN_ETH_SEGMENT_ASPATH_SEGMENTS_lIST = { @@ -40,80 +40,75 @@ def test_bgpv6_evpn_validation(api, utils): "UpstreamDownstreamAssignedMplsLabel": 20, "RdASNumber": 1000, "RdEvi": 10, - "MultiExitDiscriminator": 99 + "MultiExitDiscriminator": 99, } BGPV6_EVPN_VXLAN_EXPORT_TARGET = { "TargetAs4Number": "100", - "TargetAssignedNumber": "20" + "TargetAssignedNumber": "20", } BGPV6_EVPN_VXLAN_IMPORT_TARGET = { "TargetAs4Number": "200", - "TargetAssignedNumber": "30" + "TargetAssignedNumber": "30", } BGPV6_EVPN_VXLAN_L3_EXPORT_TARGET = { "TargetAs4Number": "300", - "TargetAssignedNumber": "50" + "TargetAssignedNumber": "50", } BGPV6_EVPN_VXLAN_L3_IMPORT_TARGET = { "TargetAs4Number": "400", - "TargetAssignedNumber": "60" + "TargetAssignedNumber": "60", } - BROADCAST_DOMAIN = { - "EthernetTagId": "5", - "EnableVlanAwareService": "true" - } + BROADCAST_DOMAIN = {"EthernetTagId": "5", "EnableVlanAwareService": "true"} MAC_ADDRESS = { "Mac": "10:11:22:33:44:55", "PrefixLength": "48", - "NumberOfAddressesAsy": "1" + "NumberOfAddressesAsy": "1", } IP_ADDRESS = { "NetworkAddress": "2.2.2.2", "PrefixLength": "24", - "NumberOfAddressesAsy": "1" + "NumberOfAddressesAsy": "1", } IPV6_ADDRESS = { "NetworkAddress": "2000:0:2:1::1", "PrefixLength": "64", - "NumberOfAddressesAsy": "1" + "NumberOfAddressesAsy": "1", } CMAC_PROPERTIES = { "FirstLabelStart": "16", "SecondLabelStart": "20", "MultiExitDiscriminator": "37", - "IncludeDefaultGatewayExtendedCommunity": "true" + "IncludeDefaultGatewayExtendedCommunity": "true", } # Creating Ports config = api.config() - p1 = config.ports.port(name='p1', location=utils.settings.ports[0])[-1] + 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_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_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] + 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() @@ -124,31 +119,35 @@ def test_bgpv6_evpn_validation(api, utils): 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 = 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_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.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.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"]) + BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["AsNumber"] + ) tx_eth_seg_community.as_custom = int( - BGPV6_EVPN_ETH_SEGMENT_COMMUNITIES_lIST["LastTwoOctets"]) + 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" @@ -159,49 +158,60 @@ def test_bgpv6_evpn_validation(api, utils): # 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.AS_2OCTET + ) tx_evi_vxlan.route_distinguisher.rd_value = ( - str(BGPV6_EVPN_VXLAN["RdASNumber"]) + ":" + str( - BGPV6_EVPN_VXLAN["RdEvi"])) + 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"]) + 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"]) + 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"]) + 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"]) + 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"]) + 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.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_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" @@ -209,29 +219,32 @@ def test_bgpv6_evpn_validation(api, utils): 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 = tx_evi_vxlan.broadcast_domains.broadcastdomain()[ + -1 + ] tx_evpn_brodcast_domain.ethernet_tag_id = int( - BROADCAST_DOMAIN["EthernetTagId"]) + 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 = 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.ipv6_addresses.address = IPV6_ADDRESS[ + "NetworkAddress" + ] tx_broadcast_macrange.advanced.multi_exit_discriminator = int( - CMAC_PROPERTIES["MultiExitDiscriminator"]) + 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_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" @@ -240,42 +253,50 @@ def test_bgpv6_evpn_validation(api, utils): 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): + 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()) + ixn.Topology.find() + .DeviceGroup.find() + .DeviceGroup.find() + .Ipv6Loopback.find() + .BgpIpv6Peer.find() + ) for bgp in bgps: assert bgp.EthernetSegmentsCountV6 == 1 assert bgp.BgpEthernetSegmentV6.EvisCount == 1 @@ -284,8 +305,7 @@ def validate_config(api, bgp_eth_seg = bgps[0].BgpEthernetSegmentV6 for attr in BGPV6_EVPN_ETH_SEGMENT: - if attr in ["DfElectionTimer", "EsiLabel", - "MultiExitDiscriminator"]: + if attr in ["DfElectionTimer", "EsiLabel", "MultiExitDiscriminator"]: assert BGPV6_EVPN_ETH_SEGMENT[attr] == int( (getattr(bgp_eth_seg, attr).Values)[0] ) @@ -294,22 +314,25 @@ def validate_config(api, (getattr(bgp_eth_seg, attr).Values)[0] ) - bgp_eth_seg_comm_list = ( - bgps[0].BgpEthernetSegmentV6.BgpCommunitiesList.find()) + 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()) + 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()) + 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] @@ -322,102 +345,104 @@ def validate_config(api, ) bgp_evpn_vxlan_export_target = ( - bgp_evpn_vxlan.BgpExportRouteTargetList.find()) + 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()) + 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()) + 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()) + 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()) + 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()) + 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()) + 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) + 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()) + 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] - ) + assert MAC_ADDRESS[attr] == ((getattr(mac, attr).Values)[0]) - ipv4 = (mac.Ipv4PrefixPools.find()) + ipv4 = mac.Ipv4PrefixPools.find() for attr in IP_ADDRESS: - assert IP_ADDRESS[attr] == ( - (getattr(ipv4, attr).Values)[0] - ) + assert IP_ADDRESS[attr] == ((getattr(ipv4, attr).Values)[0]) - ipv6 = (mac.Ipv6PrefixPools.find()) + ipv6 = mac.Ipv6PrefixPools.find() for attr in IPV6_ADDRESS: - assert IPV6_ADDRESS[attr] == ( - (getattr(ipv6, attr).Values)[0] - ) + assert IPV6_ADDRESS[attr] == ((getattr(ipv6, attr).Values)[0]) - cmac = (mac.CMacProperties.find()) + cmac = mac.CMacProperties.find() for attr in CMAC_PROPERTIES: - assert CMAC_PROPERTIES[attr] == ( - (getattr(cmac, attr).Values)[0] - ) + assert CMAC_PROPERTIES[attr] == ((getattr(cmac, attr).Values)[0]) - cmac_comm_list = ( - cmac.BgpCommunitiesList.find()) + 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()) + 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()) + 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] diff --git a/tests/capture/test_capture_control.py b/tests/capture/test_capture_control.py index d2eb0ba16..faff678fb 100644 --- a/tests/capture/test_capture_control.py +++ b/tests/capture/test_capture_control.py @@ -1,10 +1,10 @@ import pytest import dpkt + @pytest.mark.skip( reason="https://github.com/open-traffic-generator/snappi-ixnetwork/issues/525" ) - def test_capture_control(api, utils): """ The test is to check if capture has control packets included. diff --git a/tests/conftest.py b/tests/conftest.py index 8fd61ea04..d5a7ef9b5 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -70,9 +70,7 @@ def settings(): @pytest.fixture(scope="session") def api(): # handle to make API calls - api = snappi.api( - location=utl.settings.location, ext=utl.settings.ext - ) + api = snappi.api(location=utl.settings.location, ext=utl.settings.ext) utl.configure_credentials(api, utl.settings.username, utl.settings.psd) yield api if getattr(api, "assistant", None) is not None: @@ -83,9 +81,11 @@ def api(): def cvg_api(): # handle to make Convergence API calls api = snappi_convergence.api( - location=utl.settings.location, ext=utl.settings.ext + location=utl.settings.location, + ext=utl.settings.ext, + username=utl.settings.username, + password=utl.settings.psd, ) - utl.configure_credentials(api, utl.settings.username, utl.settings.psd) yield api if getattr(api, "assistant", None) is not None: api.assistant.Session.remove() diff --git a/tests/convergence/bgp_convergence_config.py b/tests/convergence/bgp_convergence_config.py index c0acc5143..676c72be1 100644 --- a/tests/convergence/bgp_convergence_config.py +++ b/tests/convergence/bgp_convergence_config.py @@ -24,7 +24,9 @@ def bgp_convergence_config(utils, cvg_api): ly.speed = utils.settings.speed ly.media = utils.settings.media - tx_device, rx_device = config.devices.device(name="tx_device").device(name="rx_device") + tx_device, rx_device = config.devices.device(name="tx_device").device( + name="rx_device" + ) # tx_device config tx_eth = tx_device.ethernets.add() @@ -66,9 +68,7 @@ def bgp_convergence_config(utils, cvg_api): rx_bgpv4_peer.peer_address = "21.1.1.2" rx_bgpv4_peer.as_number = 65200 rx_rr = rx_bgpv4_peer.v4_routes.add(name="rx_rr") - rx_rr.addresses.add( - count=1000, address="200.1.0.1", prefix=32 - ) + rx_rr.addresses.add(count=1000, address="200.1.0.1", prefix=32) # flow config flow = config.flows.flow(name="convergence_test")[-1] @@ -81,9 +81,7 @@ def bgp_convergence_config(utils, cvg_api): # flow2 config rx1_rr = rx_bgpv4_peer.v4_routes.add(name="rx1_rr") - rx1_rr.addresses.add( - count=1000, address="200.1.0.1", prefix=32 - ) + rx1_rr.addresses.add(count=1000, address="200.1.0.1", prefix=32) # flow config flow2 = config.flows.flow(name="background_flow")[-1] diff --git a/tests/errors/test_errors.py b/tests/errors/test_errors.py index be30301ca..7f5297407 100644 --- a/tests/errors/test_errors.py +++ b/tests/errors/test_errors.py @@ -98,9 +98,7 @@ def test_error_list_from_server(api, b2b_raw_config, utils): ipv4 = eth.ipv4_addresses.add() ipv4.name = "%s_ipv4_%d" % (node, i + 1) ipv4.address = addrs["ip_%s" % node][i] - ipv4.gateway = addrs[ - "ip_%s" % ("rx" if node == "tx" else "tx") - ][i] + ipv4.gateway = addrs["ip_%s" % ("rx" if node == "tx" else "tx")][i] ipv4.prefix = 24 f1, f2 = b2b_raw_config.flows.flow(name="TxFlow-2") f1.name = "TxFlow-1" diff --git a/tests/ipv6/test_ipv6_fields.py b/tests/ipv6/test_ipv6_fields.py index 358aa64ed..9459ad999 100644 --- a/tests/ipv6/test_ipv6_fields.py +++ b/tests/ipv6/test_ipv6_fields.py @@ -52,7 +52,6 @@ def test_ipv6_fields(api, b2b_raw_config_vports, utils, tx_vport, rx_vport): src_ip_list = ["2001::1", "2002::1", "2003::1", "2004::1"] dst_ip_list = ["2005::1", "2006::1", "2007::1", "2008::1"] - eth, ipv6 = flow2.packet.ethernet().ipv6() eth.src.value = src eth.dst.value = dst @@ -92,7 +91,7 @@ def test_ipv6_fields(api, b2b_raw_config_vports, utils, tx_vport, rx_vport): step = [1, 2, 4, 2, 2, "1::", "1::"] count = [15, 128, 262144, 128, 128, 1000, 1000] - eth, ipv6 =flow3.packet.ethernet().ipv6() + eth, ipv6 = flow3.packet.ethernet().ipv6() eth.src.value = src eth.dst.value = dst for i, field in enumerate(fields): diff --git a/tests/loopback/test_loopback_interface.py b/tests/loopback/test_loopback_interface.py index 021eb29ae..1edc1eb25 100644 --- a/tests/loopback/test_loopback_interface.py +++ b/tests/loopback/test_loopback_interface.py @@ -61,18 +61,18 @@ def test_loopback_interface(b2b_raw_config, api): def validate_result(api): validate_v4 = { "loop1": { - "address": ['20.20.0.1', '20.20.0.3'], + "address": ["20.20.0.1", "20.20.0.3"], }, "loop2": { - "address": ['20.20.0.2', '20.20.0.4'], + "address": ["20.20.0.2", "20.20.0.4"], }, } validate_v6 = { "loop5": { - "address": ['2222::1', '2222::3'], + "address": ["2222::1", "2222::3"], }, "loop6": { - "address": ['2222::2', '2222::4'], + "address": ["2222::2", "2222::4"], }, } ixn = api._ixnetwork diff --git a/tests/pfc/test_global_pause_e2e.py b/tests/pfc/test_global_pause_e2e.py index 0cebd32f1..9dc87539f 100644 --- a/tests/pfc/test_global_pause_e2e.py +++ b/tests/pfc/test_global_pause_e2e.py @@ -45,7 +45,7 @@ def test_global_pause_e2e(api, settings, utils): tx_ipv4.priority.raw.increment.step = 1 tx_ipv4.priority.raw.increment.count = 256 tx_flow.duration.fixed_packets.packets = packets - tx_flow.duration.fixed_packets.delay.nanoseconds = 10 ** 9 + tx_flow.duration.fixed_packets.delay.nanoseconds = 10**9 tx_flow.size.fixed = size tx_flow.rate.percentage = 100 rx_eth_pause.src.value = "00:AB:BC:AB:BC:AB" diff --git a/tests/pfc/test_global_unpause_e2e.py b/tests/pfc/test_global_unpause_e2e.py index 69b2c9cc2..480fca83a 100644 --- a/tests/pfc/test_global_unpause_e2e.py +++ b/tests/pfc/test_global_unpause_e2e.py @@ -53,7 +53,7 @@ def test_global_unpause_e2e(api, settings, utils): tx_ipv4.priority.raw.increment.step = 1 tx_ipv4.priority.raw.increment.count = 256 tx_flow.duration.fixed_packets.packets = packets - tx_flow.duration.fixed_packets.delay.nanoseconds = 10 ** 9 + tx_flow.duration.fixed_packets.delay.nanoseconds = 10**9 tx_flow.size.fixed = size tx_flow.rate.percentage = 100 rx_eth_pause = rx_flow.packet.ethernetpause()[-1] @@ -71,7 +71,7 @@ def test_global_unpause_e2e(api, settings, utils): rx_eth_unpause.control_op_code.value = "01" rx_eth_unpause.time.value = "FFFF" rx_global_unpause.duration.fixed_seconds.seconds = 10 - rx_global_unpause.duration.fixed_seconds.delay.nanoseconds = (10 ** 9) * 10 + rx_global_unpause.duration.fixed_seconds.delay.nanoseconds = (10**9) * 10 rx_global_unpause.size.fixed = size rx_global_unpause.rate.percentage = 50 diff --git a/tests/pfc/test_pfc_pause_e2e.py b/tests/pfc/test_pfc_pause_e2e.py index cd823b236..4f227a022 100644 --- a/tests/pfc/test_pfc_pause_e2e.py +++ b/tests/pfc/test_pfc_pause_e2e.py @@ -64,7 +64,7 @@ def test_pfc_pause_e2e(api, settings, utils, lossless_priorities): ipv4.dst.value = "1.1.1.1" ipv4.priority.dscp.phb.value = str(i * 8) f.duration.fixed_packets.packets = packets - f.duration.fixed_packets.delay.nanoseconds = 10 ** 9 + f.duration.fixed_packets.delay.nanoseconds = 10**9 f.size.fixed = size f.rate.percentage = 10 rx_pause = config.flows.flow(name="rx_pause")[-1] diff --git a/tests/pfc/test_pfc_unpause_e2e.py b/tests/pfc/test_pfc_unpause_e2e.py index 515be6790..8c7c8ec6a 100644 --- a/tests/pfc/test_pfc_unpause_e2e.py +++ b/tests/pfc/test_pfc_unpause_e2e.py @@ -65,7 +65,7 @@ def test_pfc_unpause_e2e(api, settings, utils, lossless_priorities): ipv4.dst.value = "1.1.1.1" ipv4.priority.dscp.phb.value = str(prio * 8) f.duration.fixed_packets.packets = packets - f.duration.fixed_packets.delay.nanoseconds = 10 ** 9 + f.duration.fixed_packets.delay.nanoseconds = 10**9 f.size.fixed = size f.rate.percentage = 10 @@ -92,7 +92,7 @@ def test_pfc_unpause_e2e(api, settings, utils, lossless_priorities): pfc.pause_class_3.value = "0000" pfc.pause_class_4.value = "0000" rx_unpause.duration.fixed_seconds.seconds = 10 - rx_unpause.duration.fixed_seconds.delay.nanoseconds = (10 ** 9) * 10 + rx_unpause.duration.fixed_seconds.delay.nanoseconds = (10**9) * 10 rx_unpause.size.fixed = size rx_unpause.rate.percentage = 50 diff --git a/tests/ping/test_ping.py b/tests/ping/test_ping.py index 94ec08d44..7ce2925b5 100644 --- a/tests/ping/test_ping.py +++ b/tests/ping/test_ping.py @@ -85,8 +85,10 @@ def test_ping(api, b2b_raw_config): 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 + 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 == "succeeded" @@ -94,9 +96,11 @@ def test_ping(api, b2b_raw_config): 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 + 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": @@ -104,5 +108,6 @@ def test_ping(api, b2b_raw_config): 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_compact.py b/tests/test_compact.py index fe779ab98..7587e2ccd 100644 --- a/tests/test_compact.py +++ b/tests/test_compact.py @@ -195,7 +195,6 @@ def test_compact(api, utils): rx_peer.peer_address = config_values["tx_adds"][i - 1] rx_peer.as_number = 65200 - if i == rx_device_with_rr: rx_rr = rx_peer.v4_routes.add(name="Rx RR {0}".format(i)) rx_rr.addresses.add( diff --git a/tests/test_device_connection.py b/tests/test_device_connection.py index 42c157792..4768194a0 100644 --- a/tests/test_device_connection.py +++ b/tests/test_device_connection.py @@ -24,6 +24,7 @@ def test_connection_portname(api, utils): validate_config(api, p1.name) api._ixnetwork.NewConfig() + def test_device_connection(api, utils): """ Test when both port_name and connection.port_name is set in the config @@ -60,7 +61,7 @@ def test_device_lag_name(api, utils): eth1.name = "eth1" eth1.mac = "00:01:00:00:00:02" api.set_config(config) - assert(api._ixnetwork.Lag.find()[0].Name) == lag1.name + assert (api._ixnetwork.Lag.find()[0].Name) == lag1.name def test_device_without_port_name(api, utils): @@ -74,7 +75,10 @@ def test_device_without_port_name(api, utils): try: api.set_config(config) except Exception as err: - assert(str(err).split('\n ')[-1]) == "port_name is not passed for the device d1" + assert ( + str(err).split("\n ")[-1] + ) == "port_name is not passed for the device d1" + def validate_config(api, port_name): - assert(api._ixnetwork.Vport.find()[0].Name) == port_name \ No newline at end of file + assert (api._ixnetwork.Vport.find()[0].Name) == port_name diff --git a/tests/test_flow_tracking.py b/tests/test_flow_tracking.py index 8597e49ec..7c6ed4251 100644 --- a/tests/test_flow_tracking.py +++ b/tests/test_flow_tracking.py @@ -19,7 +19,7 @@ def test_flow_tracking_stats(api, utils): layer1.name = "test" config.options.port_options.location_preemption = True - + d1, d2, d3, d4 = ( config.devices.device(name="Device1") .device(name="Device2") diff --git a/tests/test_issue_microsoft.py b/tests/test_issue_microsoft.py index de7a5a625..ffa560468 100644 --- a/tests/test_issue_microsoft.py +++ b/tests/test_issue_microsoft.py @@ -65,9 +65,14 @@ def wait_for_arp(snappi_api, max_attempts=10, poll_interval_sec=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)) + import pdb + + pdb.set_trace() + raise Exception( + "ARP is not resolved in {} seconds".format( + max_attempts * poll_interval_sec + ) + ) return attempts @@ -87,10 +92,9 @@ def static_lag(api, utils): ------+ """ config = api.config() - p1, p2 = ( - config.ports.port(name="txp1", location=utils.settings.ports[0]) - .port(name="rxp2", location=utils.settings.ports[1]) - ) + 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", diff --git a/tests/test_lag.py b/tests/test_lag.py index 4a12c0d51..447ffa4be 100644 --- a/tests/test_lag.py +++ b/tests/test_lag.py @@ -118,7 +118,7 @@ def test_lacp_lag(api, utils): "ActorPortPriority": ["100", "101"], "LacpActivity": ["active", "active"], "LacpduPeriodicTimeInterval": ["5", "6"], - "LacpduTimeout": ["12", "13"] + "LacpduTimeout": ["12", "13"], } LAG2_ATTR = { @@ -129,7 +129,7 @@ def test_lacp_lag(api, utils): "ActorPortPriority": ["200", "201"], "LacpActivity": ["active", "active"], "LacpduPeriodicTimeInterval": ["7", "8"], - "LacpduTimeout": ["14", "15"] + "LacpduTimeout": ["14", "15"], } config = api.config() p1, p2, p3, p4 = ( @@ -153,12 +153,14 @@ def test_lacp_lag(api, utils): lag1.protocol.lacp.actor_system_id = "00:11:03:00:00:03" lag1.protocol.lacp.actor_system_priority = int( - LAG1_ATTR["ActorSystemPriority"][0]) + LAG1_ATTR["ActorSystemPriority"][0] + ) lag1.protocol.lacp.actor_key = int(LAG1_ATTR["ActorKey"][0]) lag2.protocol.lacp.actor_system_id = "00:22:03:00:00:03" lag2.protocol.lacp.actor_system_priority = int( - LAG2_ATTR["ActorSystemPriority"][0]) + LAG2_ATTR["ActorSystemPriority"][0] + ) lag2.protocol.lacp.actor_key = int(LAG2_ATTR["ActorKey"][0]) l1_p1.lacp.actor_port_number = int(LAG1_ATTR["ActorPortNumber"][0]) @@ -177,13 +179,17 @@ def test_lacp_lag(api, utils): l2_p2.lacp.actor_activity = LAG2_ATTR["LacpActivity"][1] l1_p1.lacp.lacpdu_periodic_time_interval = int( - LAG1_ATTR["LacpduPeriodicTimeInterval"][0]) + LAG1_ATTR["LacpduPeriodicTimeInterval"][0] + ) l1_p2.lacp.lacpdu_periodic_time_interval = int( - LAG1_ATTR["LacpduPeriodicTimeInterval"][1]) + LAG1_ATTR["LacpduPeriodicTimeInterval"][1] + ) l2_p1.lacp.lacpdu_periodic_time_interval = int( - LAG2_ATTR["LacpduPeriodicTimeInterval"][0]) + LAG2_ATTR["LacpduPeriodicTimeInterval"][0] + ) l2_p2.lacp.lacpdu_periodic_time_interval = int( - LAG2_ATTR["LacpduPeriodicTimeInterval"][1]) + LAG2_ATTR["LacpduPeriodicTimeInterval"][1] + ) l1_p1.lacp.lacpdu_timeout = int(LAG1_ATTR["LacpduTimeout"][0]) l1_p2.lacp.lacpdu_timeout = int(LAG1_ATTR["LacpduTimeout"][1]) @@ -218,7 +224,7 @@ def test_lacp_lag(api, utils): api.set_config(config) utils.wait_for( - lambda: lacp_pdu_status_ok(api, 'up'), "port state as expected" + lambda: lacp_pdu_status_ok(api, "up"), "port state as expected" ) ds = api.device_state() @@ -227,7 +233,7 @@ def test_lacp_lag(api, utils): api.set_device_state(ds) utils.wait_for( - lambda: lacp_pdu_status_ok(api, 'down'), "port state as expected" + lambda: lacp_pdu_status_ok(api, "down"), "port state as expected" ) ds = api.device_state() @@ -236,16 +242,20 @@ def test_lacp_lag(api, utils): api.set_device_state(ds) utils.wait_for( - lambda: lacp_pdu_status_ok(api, 'up'), "port state as expected" + lambda: lacp_pdu_status_ok(api, "up"), "port state as expected" ) validate_lacp_config(api, LAG1_ATTR, LAG2_ATTR) def lacp_pdu_status_ok(api, state): - return (api._ixnetwork.Lag.find() - .ProtocolStack.find().Ethernet.find() - .Lagportlacp.find().SessionStatus)[1] == state + return ( + api._ixnetwork.Lag.find() + .ProtocolStack.find() + .Ethernet.find() + .Lagportlacp.find() + .SessionStatus + )[1] == state def validate_lacp_config(api, LAG1_ATTR, LAG2_ATTR): @@ -272,7 +282,7 @@ def test_static_and_lacp_lag(api, utils): "ActorPortPriority": ["100", "101"], "LacpActivity": ["active", "passive"], "LacpduPeriodicTimeInterval": ["5", "6"], - "LacpduTimeout": ["12", "13"] + "LacpduTimeout": ["12", "13"], } config = api.config() @@ -299,7 +309,8 @@ def test_static_and_lacp_lag(api, utils): lag2.protocol.lacp.actor_system_id = "00:22:03:00:00:03" lag2.protocol.lacp.actor_system_priority = int( - LACP_ATTR["ActorSystemPriority"][0]) + LACP_ATTR["ActorSystemPriority"][0] + ) lag2.protocol.lacp.actor_key = int(LACP_ATTR["ActorKey"][0]) l2_p1.lacp.actor_port_number = int(LACP_ATTR["ActorPortNumber"][0]) @@ -312,9 +323,11 @@ def test_static_and_lacp_lag(api, utils): l2_p2.lacp.actor_activity = LACP_ATTR["LacpActivity"][1] l2_p1.lacp.lacpdu_periodic_time_interval = int( - LACP_ATTR["LacpduPeriodicTimeInterval"][0]) + LACP_ATTR["LacpduPeriodicTimeInterval"][0] + ) l2_p2.lacp.lacpdu_periodic_time_interval = int( - LACP_ATTR["LacpduPeriodicTimeInterval"][1]) + LACP_ATTR["LacpduPeriodicTimeInterval"][1] + ) l2_p1.lacp.lacpdu_timeout = int(LACP_ATTR["LacpduTimeout"][0]) l2_p2.lacp.lacpdu_timeout = int(LACP_ATTR["LacpduTimeout"][1]) @@ -364,9 +377,12 @@ def validate_static_lacp_config(api, LACP_ATTR): lags = api._ixnetwork.Lag.find() assert ( - lags[0].ProtocolStack.find() + lags[0] + .ProtocolStack.find() .Ethernet.find() - .Lagportstaticlag.find().LagId.Values)[0] == "5" + .Lagportstaticlag.find() + .LagId.Values + )[0] == "5" assert lags[1].LagMode.LagProtocol == "lacp" lag_lacp = lags[1].ProtocolStack.find().Ethernet.find().Lagportlacp.find() diff --git a/tests/test_logger.py b/tests/test_logger.py index af5ccf3cd..f40124533 100644 --- a/tests/test_logger.py +++ b/tests/test_logger.py @@ -10,7 +10,7 @@ def test_mac_addrs(b2b_raw_config_vports): api = snappi.api( location=utl.settings.location, ext=utl.settings.ext, - loglevel=logging.DEBUG + loglevel=logging.DEBUG, ) utl.configure_credentials(api, utl.settings.username, utl.settings.psd) @@ -19,4 +19,4 @@ def test_mac_addrs(b2b_raw_config_vports): if __name__ == "__main__": - pytest.main(["-s", __file__]) \ No newline at end of file + pytest.main(["-s", __file__]) diff --git a/tests/traffic/test_api_perf_new.py b/tests/traffic/test_api_perf_new.py index fa5dc233c..a8404f70c 100644 --- a/tests/traffic/test_api_perf_new.py +++ b/tests/traffic/test_api_perf_new.py @@ -5,6 +5,7 @@ CSV_DIR = utils.new_logs_dir() + @pytest.mark.skip(reason="skip to CICD faster") @pytest.mark.parametrize("iterations", [1, 10]) @pytest.mark.parametrize("num_of_flows", [100]) diff --git a/tests/traffic/test_ip_device_and_flow.py b/tests/traffic/test_ip_device_and_flow.py index 94adbfa9f..6683ccf39 100644 --- a/tests/traffic/test_ip_device_and_flow.py +++ b/tests/traffic/test_ip_device_and_flow.py @@ -51,9 +51,7 @@ def test_ip_device_and_flow(api, b2b_raw_config, utils): ip = eth.ipv4_addresses.add() ip.name = "%s_ipv4_%d" % (node, i + 1) ip.address = addrs["ip_%s" % node][i] - ip.gateway = addrs[ - "ip_%s" % ("rx" if node == "tx" else "tx") - ][i] + ip.gateway = addrs["ip_%s" % ("rx" if node == "tx" else "tx")][i] ip.prefix = 24 f1, f2 = b2b_raw_config.flows.flow(name="TxFlow-2") f1.name = "TxFlow-1" diff --git a/tests/traffic/test_traffic_json.py b/tests/traffic/test_traffic_json.py index 48e4daaff..321c1ab9f 100644 --- a/tests/traffic/test_traffic_json.py +++ b/tests/traffic/test_traffic_json.py @@ -321,7 +321,6 @@ def test_create_traffic_raw(): - config = snappi.Api().config() api = MagicMock() tr_obj = TrafficItem(api) @@ -338,7 +337,6 @@ def test_create_traffic_raw(): def test_create_traffic_raw2(): - config = snappi.Api().config() api = MagicMock() tr_obj = TrafficItem(api) diff --git a/tests/utils/common.py b/tests/utils/common.py index b0b8e271f..04f8de25f 100644 --- a/tests/utils/common.py +++ b/tests/utils/common.py @@ -65,6 +65,7 @@ def configure_credentials(api, usr, psd): api.username = usr api.password = psd + class Settings(object): """ Singleton for global settings @@ -143,6 +144,7 @@ def start_traffic(api, cfg, start_capture=True): 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 @@ -151,7 +153,7 @@ def stop_traffic(api, cfg, stop_capture=True): 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 @@ -164,6 +166,7 @@ def stop_traffic(api, cfg, stop_capture=True): 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 e6d510e9e..638a5bb83 100644 --- a/tests/vxlan/test_manual_gateway_mac.py +++ b/tests/vxlan/test_manual_gateway_mac.py @@ -178,14 +178,20 @@ def test_manual_gateway_mac(api, utils): assert ( api._ixnetwork.Topology.find()[0] - .DeviceGroup.find()[0].Ethernet.find()[0] - .Ipv4.find().ManualGatewayMac.Values[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 + api._ixnetwork.Topology.find()[0] + .DeviceGroup.find() + .DeviceGroup.find() + .DeviceGroup.find() + .Ethernet.find()[0] + .Ipv4.find() + .ManualGatewayMac.Values ) == edge2_macs[1:] diff --git a/tests/vxlan/test_vxlan_b2b.py b/tests/vxlan/test_vxlan_b2b.py index cd3534c44..e95168fbd 100644 --- a/tests/vxlan/test_vxlan_b2b.py +++ b/tests/vxlan/test_vxlan_b2b.py @@ -4,17 +4,16 @@ def test_vxlan_b2b(api, utils): config = api.config() - p1, p2 = ( - config.ports - .port(name="tx", location=utils.settings.ports[0]) - .port(name="rx", location=utils.settings.ports[1])) + p1, p2 = config.ports.port( + name="tx", location=utils.settings.ports[0] + ).port(name="rx", location=utils.settings.ports[1]) - d1, d2 = config.devices.device(name='d1').device(name='d2') + 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' + 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" From 75b10483022ae6468e1b04e78910652a8519b5b5 Mon Sep 17 00:00:00 2001 From: vhowdhur Date: Tue, 25 Jul 2023 23:15:17 +0530 Subject: [PATCH 28/49] rectifying snappi convergence --- snappi_ixnetwork/snappi_api.py | 2 +- snappi_ixnetwork/snappi_convergence_api.py | 4 ++++ tests/conftest.py | 3 +-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/snappi_ixnetwork/snappi_api.py b/snappi_ixnetwork/snappi_api.py index a1c4cd929..c00c765ea 100644 --- a/snappi_ixnetwork/snappi_api.py +++ b/snappi_ixnetwork/snappi_api.py @@ -152,7 +152,7 @@ def username(self, value): def password(self): return self._password - @username.setter + @password.setter def password(self, value): self._password = value diff --git a/snappi_ixnetwork/snappi_convergence_api.py b/snappi_ixnetwork/snappi_convergence_api.py index 6f4fbe5a2..e9e976421 100644 --- a/snappi_ixnetwork/snappi_convergence_api.py +++ b/snappi_ixnetwork/snappi_convergence_api.py @@ -35,6 +35,10 @@ def __init__(self, **kwargs): self._event_info = None self.logger = get_ixnet_logger(__name__) + def configure_credentials(self, uid, psd): + self._api.username = uid + self._api.password = psd + def enable_scaling(self, do_compact=False): self._api.do_compact = do_compact diff --git a/tests/conftest.py b/tests/conftest.py index d5a7ef9b5..220856197 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -83,9 +83,8 @@ def cvg_api(): api = snappi_convergence.api( location=utl.settings.location, ext=utl.settings.ext, - username=utl.settings.username, - password=utl.settings.psd, ) + api.configure_credentials(utl.settings.username, utl.settings.psd) yield api if getattr(api, "assistant", None) is not None: api.assistant.Session.remove() From 7dc2b3a9fe6f5c96b045e3ac543b589bc12994e3 Mon Sep 17 00:00:00 2001 From: vhowdhur Date: Wed, 26 Jul 2023 19:53:49 +0530 Subject: [PATCH 29/49] trying to make the password generic --- .github/workflows/publish.yml | 2 +- do.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 4f1c3cbd1..b79ce088e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -34,7 +34,7 @@ jobs: ${{steps.path.outputs.pythonv}} do.py init - name: Run tests run: | - TEST_USERNAME=${{secrets.TEST_USERNAME}} ${{steps.path.outputs.pythonv}} do.py test + TEST_USERNAME=${{secrets.TEST_USERNAME}} TEST_PASSWORD='1x14c0m!X!$C)M' ${{steps.path.outputs.pythonv}} do.py test - name: Get package version id: get_version run: | diff --git a/do.py b/do.py index 8083d287d..3a7ce7820 100644 --- a/do.py +++ b/do.py @@ -38,6 +38,7 @@ def lint(): def test(): coverage_threshold = 67 username = os.environ.get("TEST_USERNAME", "admin") + psd = os.environ.get("TEST_PASSWORD", "admin") args = [ '--location="https://snappi-ixn-ci-novus100g.lbj.is.keysight.com:5000"', ( @@ -47,9 +48,10 @@ def test(): ' snappi-ixn-ci-novus100g.lbj.is.keysight.com;1;6"' ), "--username=" + username, + "--psd='" + psd, "--ext=ixnetwork", "--speed=speed_100_gbps", - "tests", + "tests\\ping\\test_ping.py", '-m "not e2e and not l1_manual and not uhd"', "--cov=./snappi_ixnetwork --cov-report term" " --cov-report html:cov_report", From 07fd53c825ad2e41a4c13de642753f57680e5764 Mon Sep 17 00:00:00 2001 From: vhowdhur Date: Wed, 26 Jul 2023 19:56:42 +0530 Subject: [PATCH 30/49] bug fix --- do.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/do.py b/do.py index 3a7ce7820..8fc8000d8 100644 --- a/do.py +++ b/do.py @@ -48,10 +48,10 @@ def test(): ' snappi-ixn-ci-novus100g.lbj.is.keysight.com;1;6"' ), "--username=" + username, - "--psd='" + psd, + "--psd='" + psd + "'", "--ext=ixnetwork", "--speed=speed_100_gbps", - "tests\\ping\\test_ping.py", + "tests", '-m "not e2e and not l1_manual and not uhd"', "--cov=./snappi_ixnetwork --cov-report term" " --cov-report html:cov_report", From b99a31adde14d17ee36b89f38af0c4fcbd02890f Mon Sep 17 00:00:00 2001 From: vhowdhur Date: Wed, 26 Jul 2023 20:09:50 +0530 Subject: [PATCH 31/49] bug fix --- .github/workflows/publish.yml | 2 +- tests/settings.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b79ce088e..c08606b06 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -34,7 +34,7 @@ jobs: ${{steps.path.outputs.pythonv}} do.py init - name: Run tests run: | - TEST_USERNAME=${{secrets.TEST_USERNAME}} TEST_PASSWORD='1x14c0m!X!$C)M' ${{steps.path.outputs.pythonv}} do.py test + TEST_USERNAME=${{secrets.TEST_USERNAME}} TEST_PASSWORD='${{secrets.TEST_PASSWORD}}' ${{steps.path.outputs.pythonv}} do.py test - name: Get package version id: get_version run: | diff --git a/tests/settings.json b/tests/settings.json index a341f61be..42ed1ed2c 100644 --- a/tests/settings.json +++ b/tests/settings.json @@ -1,6 +1,6 @@ { "username": "admin", - "psd": "1x14c0m!X!$C)M", + "psd": "admin", "location": "https://localhost:443", "ports": [ "localhost;1;1", From d36fbbbd0d52d133ab5c52f8b70498d13549a189 Mon Sep 17 00:00:00 2001 From: vhowdhur Date: Wed, 26 Jul 2023 20:48:02 +0530 Subject: [PATCH 32/49] add support for new runner with novus10g --- .github/workflows/publish.yml | 57 +++++++++++++++++++++++++++++++++-- do.py | 40 +++++++++++++++++------- 2 files changed, 84 insertions(+), 13 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c08606b06..afab4c39e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -6,7 +6,7 @@ on: pull_request: jobs: - cicd: + test_novus_100g: runs-on: [snappi-ixn-ci-novus100g] steps: - name: Checkout source @@ -35,6 +35,58 @@ jobs: - name: Run tests run: | TEST_USERNAME=${{secrets.TEST_USERNAME}} TEST_PASSWORD='${{secrets.TEST_PASSWORD}}' ${{steps.path.outputs.pythonv}} do.py test + + test_novus_10g: + runs-on: [snappi-ixn-ci-novus10g] + steps: + - name: Checkout source + uses: actions/checkout@v2 + with: + ref: ${{ env.BASE_BRANCH }} + # ref: ${{ github.head_ref }} + submodules: recursive + - name: Set python path + id: path + run: echo "::set-output name=pythonv::/home/github-runner/pyenv/.env/bin/python" + - name: Install dependencies + run: | + rm -rf .env + ${{steps.path.outputs.pythonv}} do.py setup + ${{steps.path.outputs.pythonv}} do.py init + - name: Build distribution + run: | + ${{steps.path.outputs.pythonv}} do.py dist + - name: Install package on clean env + run: | + rm -rf .env + ${{steps.path.outputs.pythonv}} do.py setup + ${{steps.path.outputs.pythonv}} do.py install + ${{steps.path.outputs.pythonv}} do.py init + - name: Run tests + run: | + TEST_USERNAME=${{secrets.TEST_USERNAME}} TEST_PASSWORD='${{secrets.TEST_PASSWORD}}' ${{steps.path.outputs.pythonv}} do.py test novus10g + + publish_artifacts: + runs-on: [snappi-ixn-ci-novus100g] + needs: [test_novus_100g, test_novus_10g] + steps: + - name: Checkout source + uses: actions/checkout@v2 + with: + ref: ${{ env.BASE_BRANCH }} + # ref: ${{ github.head_ref }} + submodules: recursive + - name: Set python path + id: path + run: echo "::set-output name=pythonv::/home/github-runner/pyenv/.env/bin/python" + - name: Install dependencies + run: | + rm -rf .env + ${{steps.path.outputs.pythonv}} do.py setup + ${{steps.path.outputs.pythonv}} do.py init + - name: Build distribution + run: | + ${{steps.path.outputs.pythonv}} do.py dist - name: Get package version id: get_version run: | @@ -69,9 +121,10 @@ jobs: run: | ${{steps.path.outputs.pythonv}} do.py install_requests ${{steps.path.outputs.pythonv}} ${{steps.path.outputs.pythonv}} do.py check_release_flag ${{ steps.release.outputs.release_flag }} ${{ steps.get_version.outputs.version }} + cicd_snappitest: runs-on: [snappi-ixn-ci-novus100g] - needs: cicd + needs: test_novus_100g steps: - name: Trigger CI/CD snappi-tests run: | diff --git a/do.py b/do.py index 8fc8000d8..2621a8fdc 100644 --- a/do.py +++ b/do.py @@ -35,22 +35,40 @@ def lint(): ) -def test(): +def test(card="novus100g"): coverage_threshold = 67 username = os.environ.get("TEST_USERNAME", "admin") psd = os.environ.get("TEST_PASSWORD", "admin") - args = [ - '--location="https://snappi-ixn-ci-novus100g.lbj.is.keysight.com:5000"', - ( - '--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"' - ), + + if card == "novus100g": + args = [ + '--location="https://snappi-ixn-ci-novus100g.lbj.is.keysight.com:5000"', + ( + '--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"' + ), + "--speed=speed_100_gbps", + ] + elif card == "novus10g": + args = [ + '--location="https://novus1-715849.ccu.is.keysight.com:5000"', + ( + '--ports="novus1-715849.ccu.is.keysight.com;1;1' + " novus1-715849.ccu.is.keysight.com;1;2" + " novus1-715849.ccu.is.keysight.com;1;5" + ' novus1-715849.ccu.is.keysight.com;1;6"' + ), + "--speed=speed_10_gbps", + ] + else: + raise Exception("card %s is not supported for testing" % card) + + args += [ + "--ext=ixnetwork", "--username=" + username, "--psd='" + psd + "'", - "--ext=ixnetwork", - "--speed=speed_100_gbps", "tests", '-m "not e2e and not l1_manual and not uhd"', "--cov=./snappi_ixnetwork --cov-report term" From 764a7bb2dd74ac116d677eab6f5134aaf1d0678c Mon Sep 17 00:00:00 2001 From: vhowdhur Date: Wed, 26 Jul 2023 20:52:23 +0530 Subject: [PATCH 33/49] bug fix --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index afab4c39e..799092063 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -64,7 +64,7 @@ jobs: ${{steps.path.outputs.pythonv}} do.py init - name: Run tests run: | - TEST_USERNAME=${{secrets.TEST_USERNAME}} TEST_PASSWORD='${{secrets.TEST_PASSWORD}}' ${{steps.path.outputs.pythonv}} do.py test novus10g + TEST_USERNAME=${{secrets.TEST_USERNAME}} ${{steps.path.outputs.pythonv}} do.py test novus10g publish_artifacts: runs-on: [snappi-ixn-ci-novus100g] From 14197b5444441d7c2eba9ba902f2a0c5445b254f Mon Sep 17 00:00:00 2001 From: desaimg1 Date: Thu, 27 Jul 2023 17:55:47 +0530 Subject: [PATCH 34/49] Adding backward compatibility for ping test --- snappi_ixnetwork/ping.py | 137 ++++++++++++++++++++++----------- snappi_ixnetwork/snappi_api.py | 4 +- 2 files changed, 94 insertions(+), 47 deletions(-) diff --git a/snappi_ixnetwork/ping.py b/snappi_ixnetwork/ping.py index 5cb1bf7f3..fc4eb5f45 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, req_type, ping_request): + def results(self, ping_request, req_type=None): responses = [] v4_names = [] for device in self._api._config.devices: @@ -31,49 +31,96 @@ def results(self, req_type, ping_request): for eth in device.ethernets: for ip in eth.ipv6_addresses: v6_names.append(ip.name) - - with Timer(self._api, "Ping requests completed in"): - for endpoint in ping_request.requests: - response = {} - src_name = endpoint.get("src_name") - dst_ip = endpoint.get("dst_ip") - if req_type == "ipv4": - if src_name not in v4_names: - msg = ( - src_name - + """ is not available in the configured v4 interface names """ - + str(v4_names) + if req_type==None : + with Timer(self._api, "Ping requests completed in"): + for endpoint in ping_request.endpoints: + response = {} + req_type = endpoint.parent.choice + src_name = endpoint.get("src_name") + dst_ip = endpoint.get("dst_ip") + if req_type == "ipv4": + if src_name not in v4_names: + msg = ( + src_name + + """ is not available in the configured v4 interface names """ + + str(v4_names) + ) + raise Exception(msg) + ip_obj = ( + self._api._ixnetwork.Topology.find() + .DeviceGroup.find() + .Ethernet.find() + .Ipv4.find(Name=src_name) + ) + elif req_type == "ipv6": + if src_name not in v6_names: + msg = ( + src_name + + """ is not available in the configured v6 interface names """ + + str(v6_names) + ) + raise Exception(msg) + ip_obj = ( + self._api._ixnetwork.Topology.find() + .DeviceGroup.find() + .Ethernet.find() + .Ipv6.find(Name=src_name) + ) + self._api.info("Sending ping to %s" % dst_ip) + ping_status = ip_obj.SendPing(DestIP=dst_ip) + for reply in ping_status: + if dst_ip in reply["arg3"]: + if reply["arg2"]: + response["result"] = "success" + else: + response["result"] = "failure" + response["src_name"] = src_name + response["dst_ip"] = dst_ip + responses.append(response) + return responses + else: + with Timer(self._api, "Ping requests completed in"): + for endpoint in ping_request.requests: + response = {} + src_name = endpoint.get("src_name") + dst_ip = endpoint.get("dst_ip") + if req_type == "ipv4": + if src_name not in v4_names: + msg = ( + src_name + + """ is not available in the configured v4 interface names """ + + str(v4_names) + ) + raise Exception(msg) + ip_obj = ( + self._api._ixnetwork.Topology.find() + .DeviceGroup.find() + .Ethernet.find() + .Ipv4.find(Name=src_name) ) - raise Exception(msg) - ip_obj = ( - self._api._ixnetwork.Topology.find() - .DeviceGroup.find() - .Ethernet.find() - .Ipv4.find(Name=src_name) - ) - elif req_type == "ipv6": - if src_name not in v6_names: - msg = ( - src_name - + """ is not available in the configured v6 interface names """ - + str(v6_names) + elif req_type == "ipv6": + if src_name not in v6_names: + msg = ( + src_name + + """ is not available in the configured v6 interface names """ + + str(v6_names) + ) + raise Exception(msg) + ip_obj = ( + self._api._ixnetwork.Topology.find() + .DeviceGroup.find() + .Ethernet.find() + .Ipv6.find(Name=src_name) ) - raise Exception(msg) - ip_obj = ( - self._api._ixnetwork.Topology.find() - .DeviceGroup.find() - .Ethernet.find() - .Ipv6.find(Name=src_name) - ) - self._api.info("Sending ping to %s" % dst_ip) - ping_status = ip_obj.SendPing(DestIP=dst_ip) - for reply in ping_status: - if dst_ip in reply["arg3"]: - if reply["arg2"]: - response["result"] = "succeeded" - else: - response["result"] = "failed" - response["src_name"] = src_name - response["dst_ip"] = dst_ip - responses.append(response) - return responses + self._api.info("Sending ping to %s" % dst_ip) + ping_status = ip_obj.SendPing(DestIP=dst_ip) + for reply in ping_status: + if dst_ip in reply["arg3"]: + if reply["arg2"]: + response["result"] = "succeeded" + else: + response["result"] = "failed" + response["src_name"] = src_name + response["dst_ip"] = dst_ip + responses.append(response) + return responses diff --git a/snappi_ixnetwork/snappi_api.py b/snappi_ixnetwork/snappi_api.py index c00c765ea..117ca91b8 100644 --- a/snappi_ixnetwork/snappi_api.py +++ b/snappi_ixnetwork/snappi_api.py @@ -378,7 +378,7 @@ def set_control_action(self, payload): res = self.control_action_response() self._connect() res.response.protocol.ipv4.ping.responses.deserialize( - self.ping.results(control_choice, request_payload) + self.ping.results(request_payload, control_choice) ) elif control_choice == "ipv6": choice = choice_obj.get("choice") @@ -387,7 +387,7 @@ def set_control_action(self, payload): res = self.control_action_response() self._connect() res.response.protocol.ipv6.ping.responses.deserialize( - self.ping.results(control_choice, request_payload) + self.ping.results(request_payload, control_choice) ) res.warnings = snappi.Warning() return res From cf33cc9e0d3a76a154611881673f459549fcdc3c Mon Sep 17 00:00:00 2001 From: desaimg1 Date: Fri, 28 Jul 2023 15:04:20 +0530 Subject: [PATCH 35/49] modified failed cases --- snappi_ixnetwork/trafficitem.py | 7 +++++++ tests/test_compact.py | 35 +++++++++++++++++++++++---------- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/snappi_ixnetwork/trafficitem.py b/snappi_ixnetwork/trafficitem.py index 9d7f2ccf8..1a9c6b33d 100644 --- a/snappi_ixnetwork/trafficitem.py +++ b/snappi_ixnetwork/trafficitem.py @@ -1127,6 +1127,13 @@ def _configure_size(self, ce_dict, size): ce["frameSize"]["incrementFrom"] = size.increment.start ce["frameSize"]["incrementTo"] = size.increment.end ce["frameSize"]["incrementStep"] = size.increment.step + elif size.choice == "weight_pairs": + if size.weight_pairs.choice == "predefined": + ce["frameSize"]["type"] = "presetDistribution" + ce["frameSize"]["presetDistribution"] = size.weight_pairs.predefined + elif size.weight_pairs.choice == "custom": + ce["frameSize"]["type"] = "weightedPairs" + ce["frameSize"]["weightedPairs"]=[item for t in zip(size.weight_pairs.custom.size,size.weight_pairs.custom.weight) for item in t] else: print( "Warning - We need to implement this %s choice" diff --git a/tests/test_compact.py b/tests/test_compact.py index 7587e2ccd..7ae35d4d7 100644 --- a/tests/test_compact.py +++ b/tests/test_compact.py @@ -195,6 +195,7 @@ def test_compact(api, utils): rx_peer.peer_address = config_values["tx_adds"][i - 1] rx_peer.as_number = 65200 + if i == rx_device_with_rr: rx_rr = rx_peer.v4_routes.add(name="Rx RR {0}".format(i)) rx_rr.addresses.add( @@ -253,23 +254,37 @@ def test_compact(api, utils): validate_compact_config(api, config_values, rx_device_with_rr) print("Starting all protocols ...") - ps = api.protocol_state() - ps.state = ps.START - api.set_protocol_state(ps) + # 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) + # 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) + # utils.start_traffic(api, config, start_capture=False) utils.wait_for( lambda: stats_ok(api, PACKETS * 3, utils), "stats to be as expected" ) - rs = api.route_state() - rs.names = ["Tx RR 4", "Rx RR 3"] - rs.state = rs.WITHDRAW - api.set_route_state(rs) + # rs = api.route_state() + # rs.names = ["Tx RR 4", "Rx RR 3"] + # rs.state = rs.WITHDRAW + # api.set_route_state(rs) + + cs = api.control_state() + cs.protocol.route.state = cs.protocol.route.WITHDRAW + cs.protocol.route.names = ["Tx RR 4", "Rx RR 3"] + api.set_control_state(cs) + validate_route_withdraw(api, config_values) From d9a8156a8e81462bda6b1373c94f80ad55980e68 Mon Sep 17 00:00:00 2001 From: desaimg1 Date: Fri, 28 Jul 2023 20:53:58 +0530 Subject: [PATCH 36/49] updating latest model code --- tests/test_issue_microsoft.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_issue_microsoft.py b/tests/test_issue_microsoft.py index ffa560468..6aa67c9d0 100644 --- a/tests/test_issue_microsoft.py +++ b/tests/test_issue_microsoft.py @@ -155,9 +155,9 @@ def static_lag(api, utils): 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) + cs = api.control_state() + cs.traffic.flow_transmit.state = cs.traffic.flow_transmit.START + api.set_control_state(cs) utils.wait_for(lambda: utils.is_traffic_stopped(api), "traffic to stop") From b72186aafe241542298a673457eaf3e7d8f258a2 Mon Sep 17 00:00:00 2001 From: desaimg1 Date: Tue, 1 Aug 2023 15:34:36 +0530 Subject: [PATCH 37/49] committing imix e2e tc files --- snappi_ixnetwork/trafficitem.py | 16 ++- tests/imix/test_custom_imix_e2e.py | 102 ++++++++++++++++++ tests/imix/test_imix_predefined_e2e.py | 87 +++++++++++++++ tests/imix/test_ipv6_imix_predefined_e2e.py | 94 ++++++++++++++++ .../imix/test_standard_imix_predefined_e2e.py | 94 ++++++++++++++++ 5 files changed, 391 insertions(+), 2 deletions(-) create mode 100644 tests/imix/test_custom_imix_e2e.py create mode 100644 tests/imix/test_imix_predefined_e2e.py create mode 100644 tests/imix/test_ipv6_imix_predefined_e2e.py create mode 100644 tests/imix/test_standard_imix_predefined_e2e.py diff --git a/snappi_ixnetwork/trafficitem.py b/snappi_ixnetwork/trafficitem.py index 1a9c6b33d..1ebdbaad9 100644 --- a/snappi_ixnetwork/trafficitem.py +++ b/snappi_ixnetwork/trafficitem.py @@ -863,6 +863,9 @@ def _configure_options(self): ): enable_min_frame_size = True break + if flow.size.choice == "weight_pairs": + enable_min_frame_size = True + break if self._api._traffic.EnableMinFrameSize != enable_min_frame_size: self._api._traffic.EnableMinFrameSize = enable_min_frame_size @@ -1130,10 +1133,19 @@ def _configure_size(self, ce_dict, size): elif size.choice == "weight_pairs": if size.weight_pairs.choice == "predefined": ce["frameSize"]["type"] = "presetDistribution" - ce["frameSize"]["presetDistribution"] = size.weight_pairs.predefined + if size.weight_pairs.predefined == "ipv6_imix": + ce["frameSize"]["presetDistribution"] = "ipV6Imix" + elif size.weight_pairs.predefined == "standard_imix": + ce["frameSize"]["presetDistribution"] = "standardImix" + elif size.weight_pairs.predefined == "tcp_imix": + ce["frameSize"]["presetDistribution"] = "tcpImix" + elif size.weight_pairs.predefined == "ipsec_imix": + ce["frameSize"]["presetDistribution"] = "ipSecImix" + else : + ce["frameSize"]["presetDistribution"] = size.weight_pairs.predefined elif size.weight_pairs.choice == "custom": ce["frameSize"]["type"] = "weightedPairs" - ce["frameSize"]["weightedPairs"]=[item for t in zip(size.weight_pairs.custom.size,size.weight_pairs.custom.weight) for item in t] + ce["frameSize"]["weightedPairs"]=[item for t in size.weight_pairs.custom for item in (t.size, t.weight)] else: print( "Warning - We need to implement this %s choice" diff --git a/tests/imix/test_custom_imix_e2e.py b/tests/imix/test_custom_imix_e2e.py new file mode 100644 index 000000000..ed3da5673 --- /dev/null +++ b/tests/imix/test_custom_imix_e2e.py @@ -0,0 +1,102 @@ +import pytest +import time + + +@pytest.mark.e2e +def test_stats_filter_e2e(api, b2b_raw_config, utils): + """ + configure flows with ipv4 imix + - Send ipv4 imix predefined traffic + + + Validation: + 1) Get port statistics based on port name & column names and assert + each port & column has returned the values and assert + 2) Get flow statistics based on flow name & column names and assert + each flow & column has returned the values and assert + """ + + no_of_packets = 1000 + + b2b_raw_config.flows.clear() + config = b2b_raw_config + + d1, d2 = config.devices.device(name="d1").device(name="d2") + + eth1 = d1.ethernets.add() + eth1.name = "eth1" + eth1.port_name = config.ports[0].name + eth1.mac = "00:ad:aa:13:11:01" + + eth2 = d2.ethernets.add() + eth2.name = "eth2" + eth2.port_name = config.ports[1].name + eth2.mac = "00:ad:aa:13:11:02" + + ip1 = eth1.ipv4_addresses.add() + ip1.name = "ipv41" + ip1.address = "10.1.1.1" + ip1.gateway = "10.1.1.2" + + ip2 = eth2.ipv4_addresses.add() + ip2.name = "ipv42" + ip2.address = "10.1.1.2" + ip2.gateway = "10.1.1.1" + + sizes_list = [92, 560, 600] + weights_list = [25.2, 24.8, 50] + + count_weight_pairs = 3 + f1 = config.flows.flow(name="f1")[-1] + f1.tx_rx.device.tx_names = [ip1.name] + f1.tx_rx.device.rx_names = [ip2.name] + for wp_id in range(count_weight_pairs): + wp = f1.size.weight_pairs.custom.add() + wp.size = sizes_list[wp_id] + wp.weight = weights_list[wp_id] + + f1.rate.pps = 1000 + f1.duration.fixed_packets.packets = no_of_packets + f1.metrics.enable = True + eth, ip = f1.packet.ethernet().ipv4() + api.set_config(config) + + utils.start_traffic(api, b2b_raw_config) + + utils.wait_for( + lambda: results_ok(api, utils, no_of_packets), + "stats to be as expected", + timeout_seconds=20, + ) + utils.stop_traffic(api, b2b_raw_config) + captures_ok(api, b2b_raw_config, utils, no_of_packets, config.ports[1].name ) + + +def results_ok(api, utils, packets): + """ + Returns true if stats are as expected, false otherwise. + """ + port_results, flow_results = utils.get_all_stats(api) + print("Checking packet count") + flow_rx = sum([f.frames_rx for f in flow_results]) + frames_ok = flow_rx == packets + print("Checking byte count") + flow_rx = sum([f.bytes_rx for f in flow_results]) + bytes_ok = 300000 <= flow_rx <= 500000 + + print ("fraemes ok {}" .format(frames_ok)) + print ("bytes ok {}".format(bytes_ok)) + return frames_ok and bytes_ok + + +def captures_ok(api, cfg, utils, packets, name): + """ + Returns normally if patterns in captured packets are as expected. + """ + pkt_count = 0 + cap_dict = utils.get_all_captures(api, cfg) + for buf in cap_dict[name]: + assert len(buf) in [92, 560, 600] + pkt_count += 1 + assert pkt_count == packets + diff --git a/tests/imix/test_imix_predefined_e2e.py b/tests/imix/test_imix_predefined_e2e.py new file mode 100644 index 000000000..1a5d90914 --- /dev/null +++ b/tests/imix/test_imix_predefined_e2e.py @@ -0,0 +1,87 @@ +import pytest +import time + + +@pytest.mark.e2e +def test_stats_filter_e2e(api, b2b_raw_config, utils): + """ + configure flows with ipv4 imix + - Send ipv4 imix predefined traffic + + + Validation: + 1) Get port statistics based on port name & column names and assert + each port & column has returned the values and assert + 2) Get flow statistics based on flow name & column names and assert + each flow & column has returned the values and assert + """ + + no_of_packets = 1000 + + b2b_raw_config.flows.clear() + config = b2b_raw_config + + d1, d2 = config.devices.device(name="d1").device(name="d2") + + eth1 = d1.ethernets.add() + eth1.name = "eth1" + eth1.port_name = config.ports[0].name + eth1.mac = "00:ad:aa:13:11:01" + + eth2 = d2.ethernets.add() + eth2.name = "eth2" + eth2.port_name = config.ports[1].name + eth2.mac = "00:ad:aa:13:11:02" + + ip1 = eth1.ipv4_addresses.add() + ip1.name = "ipv41" + ip1.address = "10.1.1.1" + ip1.gateway = "10.1.1.2" + + ip2 = eth2.ipv4_addresses.add() + ip2.name = "ipv42" + ip2.address = "10.1.1.2" + ip2.gateway = "10.1.1.1" + + f1 = config.flows.flow(name="f1")[-1] + f1.tx_rx.device.tx_names = [ip1.name] + f1.tx_rx.device.rx_names = [ip2.name] + f1.size.weight_pairs.predefined = "imix" + f1.rate.pps = 1000 + f1.duration.fixed_packets.packets = no_of_packets + f1.metrics.enable = True + eth, ip = f1.packet.ethernet().ipv4() + api.set_config(config) + + utils.start_traffic(api, b2b_raw_config) + + utils.wait_for( + lambda: results_ok(api, utils, no_of_packets), + "stats to be as expected", + timeout_seconds=20, + ) + utils.stop_traffic(api, b2b_raw_config) + captures_ok(api, b2b_raw_config, utils, no_of_packets, config.ports[1].name ) + + +def results_ok(api, utils, 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) + flow_rx = sum([f.bytes_rx for f in flow_results]) + bytes_ok = 300000 <= flow_rx <= 500000 + return frames_ok and bytes_ok + +def captures_ok(api, cfg, utils, packets, name): + """ + Returns normally if patterns in captured packets are as expected. + """ + pkt_count = 0 + cap_dict = utils.get_all_captures(api, cfg) + for buf in cap_dict[name]: + assert len(buf) in [64, 570, 1518] + pkt_count += 1 + assert pkt_count == packets + diff --git a/tests/imix/test_ipv6_imix_predefined_e2e.py b/tests/imix/test_ipv6_imix_predefined_e2e.py new file mode 100644 index 000000000..b744088ac --- /dev/null +++ b/tests/imix/test_ipv6_imix_predefined_e2e.py @@ -0,0 +1,94 @@ +import pytest +import time + + +@pytest.mark.e2e +def test_stats_filter_e2e(api, b2b_raw_config, utils): + """ + configure flows with ipv4 imix + - Send ipv4 imix predefined traffic + + + Validation: + 1) Get port statistics based on port name & column names and assert + each port & column has returned the values and assert + 2) Get flow statistics based on flow name & column names and assert + each flow & column has returned the values and assert + """ + + no_of_packets = 1000 + + b2b_raw_config.flows.clear() + config = b2b_raw_config + + d1, d2 = config.devices.device(name="d1").device(name="d2") + + eth1 = d1.ethernets.add() + eth1.name = "eth1" + eth1.port_name = config.ports[0].name + eth1.mac = "00:ad:aa:13:11:01" + + eth2 = d2.ethernets.add() + eth2.name = "eth2" + eth2.port_name = config.ports[1].name + eth2.mac = "00:ad:aa:13:11:02" + + ip1 = eth1.ipv4_addresses.add() + ip1.name = "ipv41" + ip1.address = "10.1.1.1" + ip1.gateway = "10.1.1.2" + + ip2 = eth2.ipv4_addresses.add() + ip2.name = "ipv42" + ip2.address = "10.1.1.2" + ip2.gateway = "10.1.1.1" + + f1 = config.flows.flow(name="f1")[-1] + f1.tx_rx.device.tx_names = [ip1.name] + f1.tx_rx.device.rx_names = [ip2.name] + f1.size.weight_pairs.predefined = "ipv6_imix" + f1.rate.pps = 1000 + f1.duration.fixed_packets.packets = no_of_packets + f1.metrics.enable = True + eth, ip = f1.packet.ethernet().ipv4() + api.set_config(config) + + utils.start_traffic(api, b2b_raw_config) + + utils.wait_for( + lambda: results_ok(api, utils, no_of_packets), + "stats to be as expected", + timeout_seconds=20, + ) + utils.stop_traffic(api, b2b_raw_config) + captures_ok(api, b2b_raw_config, utils, no_of_packets, config.ports[1].name ) + + +def results_ok(api, utils, packets): + """ + Returns true if stats are as expected, false otherwise. + """ + port_results, flow_results = utils.get_all_stats(api) + print("Checking packet count") + flow_rx = sum([f.frames_rx for f in flow_results]) + frames_ok = flow_rx == packets + print("Checking byte count") + flow_rx = sum([f.bytes_rx for f in flow_results]) + bytes_ok = 300000 <= flow_rx <= 500000 + + print ("fraemes ok {}" .format(frames_ok)) + print ("bytes ok {}".format(bytes_ok)) + return frames_ok and bytes_ok + + +def captures_ok(api, cfg, utils, packets, name): + """ + Returns normally if patterns in captured packets are as expected. + """ + pkt_count = 0 + cap_dict = utils.get_all_captures(api, cfg) + for buf in cap_dict[name]: + assert len(buf) in [60, 496, 594, 1518] + pkt_count += 1 + assert pkt_count == packets + diff --git a/tests/imix/test_standard_imix_predefined_e2e.py b/tests/imix/test_standard_imix_predefined_e2e.py new file mode 100644 index 000000000..165b84cd9 --- /dev/null +++ b/tests/imix/test_standard_imix_predefined_e2e.py @@ -0,0 +1,94 @@ +import pytest +import time + + +@pytest.mark.e2e +def test_stats_filter_e2e(api, b2b_raw_config, utils): + """ + configure flows with ipv4 imix + - Send ipv4 imix predefined traffic + + + Validation: + 1) Get port statistics based on port name & column names and assert + each port & column has returned the values and assert + 2) Get flow statistics based on flow name & column names and assert + each flow & column has returned the values and assert + """ + + no_of_packets = 1000 + + b2b_raw_config.flows.clear() + config = b2b_raw_config + + d1, d2 = config.devices.device(name="d1").device(name="d2") + + eth1 = d1.ethernets.add() + eth1.name = "eth1" + eth1.port_name = config.ports[0].name + eth1.mac = "00:ad:aa:13:11:01" + + eth2 = d2.ethernets.add() + eth2.name = "eth2" + eth2.port_name = config.ports[1].name + eth2.mac = "00:ad:aa:13:11:02" + + ip1 = eth1.ipv4_addresses.add() + ip1.name = "ipv41" + ip1.address = "10.1.1.1" + ip1.gateway = "10.1.1.2" + + ip2 = eth2.ipv4_addresses.add() + ip2.name = "ipv42" + ip2.address = "10.1.1.2" + ip2.gateway = "10.1.1.1" + + f1 = config.flows.flow(name="f1")[-1] + f1.tx_rx.device.tx_names = [ip1.name] + f1.tx_rx.device.rx_names = [ip2.name] + f1.size.weight_pairs.predefined = "standard_imix" + f1.rate.pps = 1000 + f1.duration.fixed_packets.packets = no_of_packets + f1.metrics.enable = True + eth, ip = f1.packet.ethernet().ipv4() + api.set_config(config) + + utils.start_traffic(api, b2b_raw_config) + + utils.wait_for( + lambda: results_ok(api, utils, no_of_packets), + "stats to be as expected", + timeout_seconds=20, + ) + utils.stop_traffic(api, b2b_raw_config) + captures_ok(api, b2b_raw_config, utils, no_of_packets, config.ports[1].name ) + + +def results_ok(api, utils, packets): + """ + Returns true if stats are as expected, false otherwise. + """ + port_results, flow_results = utils.get_all_stats(api) + print("Checking packet count") + flow_rx = sum([f.frames_rx for f in flow_results]) + frames_ok = flow_rx == packets + print("Checking byte count") + flow_rx = sum([f.bytes_rx for f in flow_results]) + bytes_ok = 300000 <= flow_rx <= 500000 + + print ("fraemes ok {}" .format(frames_ok)) + print ("bytes ok {}".format(bytes_ok)) + return frames_ok and bytes_ok + + +def captures_ok(api, cfg, utils, packets, name): + """ + Returns normally if patterns in captured packets are as expected. + """ + pkt_count = 0 + cap_dict = utils.get_all_captures(api, cfg) + for buf in cap_dict[name]: + assert len(buf) in [58, 62, 594, 1518] + pkt_count += 1 + assert pkt_count == packets + From f98843691476ecff92e9d5e4c8f165a2f4952178 Mon Sep 17 00:00:00 2001 From: Vibaswan Date: Mon, 5 Aug 2024 16:01:01 +0530 Subject: [PATCH 38/49] Update publish.yml --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 799092063..b7dfe7d9e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -2,7 +2,7 @@ name: cicd on: push: - branches: [main] + # branches: [main] pull_request: jobs: From 6531d63fe176dd12aa2dafd5611fd9a5bd7ae481 Mon Sep 17 00:00:00 2001 From: itachary Date: Wed, 7 Aug 2024 08:41:24 +0000 Subject: [PATCH 39/49] Run only 10g --- .github/workflows/publish.yml | 84 +++++++++++++++++------------------ do.py | 20 ++++----- 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b7dfe7d9e..33643457a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -6,35 +6,35 @@ on: pull_request: jobs: - test_novus_100g: - runs-on: [snappi-ixn-ci-novus100g] - steps: - - name: Checkout source - uses: actions/checkout@v2 - with: - ref: ${{ env.BASE_BRANCH }} - # ref: ${{ github.head_ref }} - submodules: recursive - - name: Set python path - id: path - run: echo "::set-output name=pythonv::/home/github-runner/pyenv/.env/bin/python" - - name: Install dependencies - run: | - rm -rf .env - ${{steps.path.outputs.pythonv}} do.py setup - ${{steps.path.outputs.pythonv}} do.py init - - name: Build distribution - run: | - ${{steps.path.outputs.pythonv}} do.py dist - - name: Install package on clean env - run: | - rm -rf .env - ${{steps.path.outputs.pythonv}} do.py setup - ${{steps.path.outputs.pythonv}} do.py install - ${{steps.path.outputs.pythonv}} do.py init - - name: Run tests - run: | - TEST_USERNAME=${{secrets.TEST_USERNAME}} TEST_PASSWORD='${{secrets.TEST_PASSWORD}}' ${{steps.path.outputs.pythonv}} do.py test + # test_novus_100g: + # runs-on: [snappi-ixn-ci-novus100g] + # steps: + # - name: Checkout source + # uses: actions/checkout@v2 + # with: + # ref: ${{ env.BASE_BRANCH }} + # # ref: ${{ github.head_ref }} + # submodules: recursive + # - name: Set python path + # id: path + # run: echo "::set-output name=pythonv::/home/github-runner/pyenv/.env/bin/python" + # - name: Install dependencies + # run: | + # rm -rf .env + # ${{steps.path.outputs.pythonv}} do.py setup + # ${{steps.path.outputs.pythonv}} do.py init + # - name: Build distribution + # run: | + # ${{steps.path.outputs.pythonv}} do.py dist + # - name: Install package on clean env + # run: | + # rm -rf .env + # ${{steps.path.outputs.pythonv}} do.py setup + # ${{steps.path.outputs.pythonv}} do.py install + # ${{steps.path.outputs.pythonv}} do.py init + # - name: Run tests + # run: | + # TEST_USERNAME=${{secrets.TEST_USERNAME}} TEST_PASSWORD='${{secrets.TEST_PASSWORD}}' ${{steps.path.outputs.pythonv}} do.py test test_novus_10g: runs-on: [snappi-ixn-ci-novus10g] @@ -122,16 +122,16 @@ jobs: ${{steps.path.outputs.pythonv}} do.py install_requests ${{steps.path.outputs.pythonv}} ${{steps.path.outputs.pythonv}} do.py check_release_flag ${{ steps.release.outputs.release_flag }} ${{ steps.get_version.outputs.version }} - cicd_snappitest: - runs-on: [snappi-ixn-ci-novus100g] - needs: test_novus_100g - steps: - - name: Trigger CI/CD snappi-tests - run: | - git clone https://github.com/open-traffic-generator/snappi-tests.git - mv version.txt snappi-tests - cd snappi-tests - git add version.txt - git commit --allow-empty -m "Trigger Snappi test from snappi-ixnetwork" - git remote set-url origin https://${{secrets.CI_TOKEN}}@github.com/open-traffic-generator/snappi-tests.git - git push origin main + # cicd_snappitest: + # runs-on: [snappi-ixn-ci-novus100g] + # needs: test_novus_100g + # steps: + # - name: Trigger CI/CD snappi-tests + # run: | + # git clone https://github.com/open-traffic-generator/snappi-tests.git + # mv version.txt snappi-tests + # cd snappi-tests + # git add version.txt + # git commit --allow-empty -m "Trigger Snappi test from snappi-ixnetwork" + # git remote set-url origin https://${{secrets.CI_TOKEN}}@github.com/open-traffic-generator/snappi-tests.git + # git push origin main diff --git a/do.py b/do.py index 2621a8fdc..1ef814d28 100644 --- a/do.py +++ b/do.py @@ -41,16 +41,16 @@ def test(card="novus100g"): psd = os.environ.get("TEST_PASSWORD", "admin") if card == "novus100g": - args = [ - '--location="https://snappi-ixn-ci-novus100g.lbj.is.keysight.com:5000"', - ( - '--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"' - ), - "--speed=speed_100_gbps", - ] + # args = [ + # '--location="https://snappi-ixn-ci-novus100g.lbj.is.keysight.com:5000"', + # ( + # '--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"' + # ), + # "--speed=speed_100_gbps", + # ] elif card == "novus10g": args = [ '--location="https://novus1-715849.ccu.is.keysight.com:5000"', From 2ce1745de849d0435592786c6a8e769f2beb9945 Mon Sep 17 00:00:00 2001 From: itachary Date: Wed, 7 Aug 2024 08:43:44 +0000 Subject: [PATCH 40/49] Run only 10g --- .github/workflows/publish.yml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 33643457a..dec0c3c0c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -122,16 +122,16 @@ jobs: ${{steps.path.outputs.pythonv}} do.py install_requests ${{steps.path.outputs.pythonv}} ${{steps.path.outputs.pythonv}} do.py check_release_flag ${{ steps.release.outputs.release_flag }} ${{ steps.get_version.outputs.version }} - # cicd_snappitest: - # runs-on: [snappi-ixn-ci-novus100g] - # needs: test_novus_100g - # steps: - # - name: Trigger CI/CD snappi-tests - # run: | - # git clone https://github.com/open-traffic-generator/snappi-tests.git - # mv version.txt snappi-tests - # cd snappi-tests - # git add version.txt - # git commit --allow-empty -m "Trigger Snappi test from snappi-ixnetwork" - # git remote set-url origin https://${{secrets.CI_TOKEN}}@github.com/open-traffic-generator/snappi-tests.git - # git push origin main + cicd_snappitest: + runs-on: [snappi-ixn-ci-novus100g] + needs: test_novus_100g + steps: + - name: Trigger CI/CD snappi-tests + run: | + git clone https://github.com/open-traffic-generator/snappi-tests.git + mv version.txt snappi-tests + cd snappi-tests + git add version.txt + git commit --allow-empty -m "Trigger Snappi test from snappi-ixnetwork" + git remote set-url origin https://${{secrets.CI_TOKEN}}@github.com/open-traffic-generator/snappi-tests.git + git push origin main From 764a7043f9200323564eabc6e6ec1478d4cd5a27 Mon Sep 17 00:00:00 2001 From: itachary Date: Wed, 7 Aug 2024 08:44:46 +0000 Subject: [PATCH 41/49] Run only 10g --- .github/workflows/publish.yml | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index dec0c3c0c..f0ef7ba63 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -6,36 +6,6 @@ on: pull_request: jobs: - # test_novus_100g: - # runs-on: [snappi-ixn-ci-novus100g] - # steps: - # - name: Checkout source - # uses: actions/checkout@v2 - # with: - # ref: ${{ env.BASE_BRANCH }} - # # ref: ${{ github.head_ref }} - # submodules: recursive - # - name: Set python path - # id: path - # run: echo "::set-output name=pythonv::/home/github-runner/pyenv/.env/bin/python" - # - name: Install dependencies - # run: | - # rm -rf .env - # ${{steps.path.outputs.pythonv}} do.py setup - # ${{steps.path.outputs.pythonv}} do.py init - # - name: Build distribution - # run: | - # ${{steps.path.outputs.pythonv}} do.py dist - # - name: Install package on clean env - # run: | - # rm -rf .env - # ${{steps.path.outputs.pythonv}} do.py setup - # ${{steps.path.outputs.pythonv}} do.py install - # ${{steps.path.outputs.pythonv}} do.py init - # - name: Run tests - # run: | - # TEST_USERNAME=${{secrets.TEST_USERNAME}} TEST_PASSWORD='${{secrets.TEST_PASSWORD}}' ${{steps.path.outputs.pythonv}} do.py test - test_novus_10g: runs-on: [snappi-ixn-ci-novus10g] steps: From 869e4931d84a7830875b19d6dfe9cd491af86d33 Mon Sep 17 00:00:00 2001 From: itachary Date: Wed, 7 Aug 2024 08:45:22 +0000 Subject: [PATCH 42/49] revert changes --- .github/workflows/publish.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f0ef7ba63..b7dfe7d9e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -6,6 +6,36 @@ on: pull_request: jobs: + test_novus_100g: + runs-on: [snappi-ixn-ci-novus100g] + steps: + - name: Checkout source + uses: actions/checkout@v2 + with: + ref: ${{ env.BASE_BRANCH }} + # ref: ${{ github.head_ref }} + submodules: recursive + - name: Set python path + id: path + run: echo "::set-output name=pythonv::/home/github-runner/pyenv/.env/bin/python" + - name: Install dependencies + run: | + rm -rf .env + ${{steps.path.outputs.pythonv}} do.py setup + ${{steps.path.outputs.pythonv}} do.py init + - name: Build distribution + run: | + ${{steps.path.outputs.pythonv}} do.py dist + - name: Install package on clean env + run: | + rm -rf .env + ${{steps.path.outputs.pythonv}} do.py setup + ${{steps.path.outputs.pythonv}} do.py install + ${{steps.path.outputs.pythonv}} do.py init + - name: Run tests + run: | + TEST_USERNAME=${{secrets.TEST_USERNAME}} TEST_PASSWORD='${{secrets.TEST_PASSWORD}}' ${{steps.path.outputs.pythonv}} do.py test + test_novus_10g: runs-on: [snappi-ixn-ci-novus10g] steps: From e712e366232c0a364492c57686b3eb64fecd3bc4 Mon Sep 17 00:00:00 2001 From: itachary Date: Wed, 7 Aug 2024 08:48:37 +0000 Subject: [PATCH 43/49] Run only 10g --- .github/workflows/publish.yml | 87 ++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 43 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b7dfe7d9e..c57ab765f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -6,35 +6,35 @@ on: pull_request: jobs: - test_novus_100g: - runs-on: [snappi-ixn-ci-novus100g] - steps: - - name: Checkout source - uses: actions/checkout@v2 - with: - ref: ${{ env.BASE_BRANCH }} - # ref: ${{ github.head_ref }} - submodules: recursive - - name: Set python path - id: path - run: echo "::set-output name=pythonv::/home/github-runner/pyenv/.env/bin/python" - - name: Install dependencies - run: | - rm -rf .env - ${{steps.path.outputs.pythonv}} do.py setup - ${{steps.path.outputs.pythonv}} do.py init - - name: Build distribution - run: | - ${{steps.path.outputs.pythonv}} do.py dist - - name: Install package on clean env - run: | - rm -rf .env - ${{steps.path.outputs.pythonv}} do.py setup - ${{steps.path.outputs.pythonv}} do.py install - ${{steps.path.outputs.pythonv}} do.py init - - name: Run tests - run: | - TEST_USERNAME=${{secrets.TEST_USERNAME}} TEST_PASSWORD='${{secrets.TEST_PASSWORD}}' ${{steps.path.outputs.pythonv}} do.py test + # test_novus_100g: + # runs-on: [snappi-ixn-ci-novus100g] + # steps: + # - name: Checkout source + # uses: actions/checkout@v2 + # with: + # ref: ${{ env.BASE_BRANCH }} + # # ref: ${{ github.head_ref }} + # submodules: recursive + # - name: Set python path + # id: path + # run: echo "::set-output name=pythonv::/home/github-runner/pyenv/.env/bin/python" + # - name: Install dependencies + # run: | + # rm -rf .env + # ${{steps.path.outputs.pythonv}} do.py setup + # ${{steps.path.outputs.pythonv}} do.py init + # - name: Build distribution + # run: | + # ${{steps.path.outputs.pythonv}} do.py dist + # - name: Install package on clean env + # run: | + # rm -rf .env + # ${{steps.path.outputs.pythonv}} do.py setup + # ${{steps.path.outputs.pythonv}} do.py install + # ${{steps.path.outputs.pythonv}} do.py init + # - name: Run tests + # run: | + # TEST_USERNAME=${{secrets.TEST_USERNAME}} TEST_PASSWORD='${{secrets.TEST_PASSWORD}}' ${{steps.path.outputs.pythonv}} do.py test test_novus_10g: runs-on: [snappi-ixn-ci-novus10g] @@ -68,7 +68,8 @@ jobs: publish_artifacts: runs-on: [snappi-ixn-ci-novus100g] - needs: [test_novus_100g, test_novus_10g] + needs: [test_novus_10g] + # needs: [test_novus_100g, test_novus_10g] steps: - name: Checkout source uses: actions/checkout@v2 @@ -122,16 +123,16 @@ jobs: ${{steps.path.outputs.pythonv}} do.py install_requests ${{steps.path.outputs.pythonv}} ${{steps.path.outputs.pythonv}} do.py check_release_flag ${{ steps.release.outputs.release_flag }} ${{ steps.get_version.outputs.version }} - cicd_snappitest: - runs-on: [snappi-ixn-ci-novus100g] - needs: test_novus_100g - steps: - - name: Trigger CI/CD snappi-tests - run: | - git clone https://github.com/open-traffic-generator/snappi-tests.git - mv version.txt snappi-tests - cd snappi-tests - git add version.txt - git commit --allow-empty -m "Trigger Snappi test from snappi-ixnetwork" - git remote set-url origin https://${{secrets.CI_TOKEN}}@github.com/open-traffic-generator/snappi-tests.git - git push origin main + # cicd_snappitest: + # runs-on: [snappi-ixn-ci-novus100g] + # needs: test_novus_100g + # steps: + # - name: Trigger CI/CD snappi-tests + # run: | + # git clone https://github.com/open-traffic-generator/snappi-tests.git + # mv version.txt snappi-tests + # cd snappi-tests + # git add version.txt + # git commit --allow-empty -m "Trigger Snappi test from snappi-ixnetwork" + # git remote set-url origin https://${{secrets.CI_TOKEN}}@github.com/open-traffic-generator/snappi-tests.git + # git push origin main From b8ca8ce7301d18ae02684449f336f8fab426768c Mon Sep 17 00:00:00 2001 From: itachary Date: Wed, 7 Aug 2024 08:56:50 +0000 Subject: [PATCH 44/49] Allow unsecure version --- .github/workflows/publish.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c57ab765f..80c2b4de4 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -5,6 +5,9 @@ on: # branches: [main] pull_request: +env: + ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true + jobs: # test_novus_100g: # runs-on: [snappi-ixn-ci-novus100g] From ce9be9cccf10f5084de904a6eab2548a1151d660 Mon Sep 17 00:00:00 2001 From: itachary Date: Wed, 7 Aug 2024 08:58:15 +0000 Subject: [PATCH 45/49] indentation fix --- do.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/do.py b/do.py index 1ef814d28..2621a8fdc 100644 --- a/do.py +++ b/do.py @@ -41,16 +41,16 @@ def test(card="novus100g"): psd = os.environ.get("TEST_PASSWORD", "admin") if card == "novus100g": - # args = [ - # '--location="https://snappi-ixn-ci-novus100g.lbj.is.keysight.com:5000"', - # ( - # '--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"' - # ), - # "--speed=speed_100_gbps", - # ] + args = [ + '--location="https://snappi-ixn-ci-novus100g.lbj.is.keysight.com:5000"', + ( + '--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"' + ), + "--speed=speed_100_gbps", + ] elif card == "novus10g": args = [ '--location="https://novus1-715849.ccu.is.keysight.com:5000"', From be1e54b0b16a97bd75bf9b7b53a3eec2d8fa860a Mon Sep 17 00:00:00 2001 From: itachary Date: Wed, 14 Aug 2024 11:53:58 +0000 Subject: [PATCH 46/49] dummy change --- readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.md b/readme.md index 0f736f532..36ad7439e 100644 --- a/readme.md +++ b/readme.md @@ -78,3 +78,4 @@ while True: if all([m.frames_tx == 10000 == m.frames_rx for m in res.flow_metrics]): break ``` + From 2aa1aebee3d686c367272fadbe66d9752d9af5c0 Mon Sep 17 00:00:00 2001 From: itachary Date: Wed, 14 Aug 2024 13:14:05 +0000 Subject: [PATCH 47/49] Test fix --- tests/vxlan/test_vxlan_b2b_scale.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/vxlan/test_vxlan_b2b_scale.py b/tests/vxlan/test_vxlan_b2b_scale.py index bc443ba83..ef1095909 100644 --- a/tests/vxlan/test_vxlan_b2b_scale.py +++ b/tests/vxlan/test_vxlan_b2b_scale.py @@ -1,5 +1,6 @@ import pytest +@pytest.mark.skip("skip until migrated to snappi") def test_vxlan_b2b_scale(api, utils): """ From 3cccef974ec2ae18f400cd973885037e6bfc46ac Mon Sep 17 00:00:00 2001 From: itachary Date: Wed, 14 Aug 2024 15:31:58 +0000 Subject: [PATCH 48/49] Fixed workflow for publish artifacts --- .github/workflows/publish.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 80c2b4de4..a3e29e077 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -70,7 +70,8 @@ jobs: TEST_USERNAME=${{secrets.TEST_USERNAME}} ${{steps.path.outputs.pythonv}} do.py test novus10g publish_artifacts: - runs-on: [snappi-ixn-ci-novus100g] + # runs-on: [snappi-ixn-ci-novus100g] + runs-on: [snappi-ixn-ci-novus10g] needs: [test_novus_10g] # needs: [test_novus_100g, test_novus_10g] steps: From 7341d3ea1e818817865997325c985823f24e20f7 Mon Sep 17 00:00:00 2001 From: itachary Date: Fri, 16 Aug 2024 08:31:56 +0000 Subject: [PATCH 49/49] Update Test --- tests/vxlan/test_vxlan_b2b.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/vxlan/test_vxlan_b2b.py b/tests/vxlan/test_vxlan_b2b.py index e95168fbd..31ac8efb9 100644 --- a/tests/vxlan/test_vxlan_b2b.py +++ b/tests/vxlan/test_vxlan_b2b.py @@ -1,6 +1,6 @@ import pytest - +@pytest.mark.skip("skip until migrated to snappi") def test_vxlan_b2b(api, utils): config = api.config()