Loading src/device/service/drivers/xr/cm/cm_connection.py +8 −1 Original line number Diff line number Diff line Loading @@ -61,7 +61,14 @@ class HttpResult: def __str__(self): status_code = self.status_code if self.status_code is not None else "<not executed>" return f"{self.method} {self.url} {self.params}, status {status_code}" if self.text: if len(self.text) > 1024: body_text = self.text[:1024] + "..." else: body_text = self.text else: body_text = "NONE" return f"{self.method} {self.url} {self.params}, status {status_code}, body {body_text}" def process_http_response(self, response: requests.Response, permit_empty_body:bool = False): LOGGER.info(f"process_http_response(): {self.method}: {self.url} qparams={self.params} ==> {response.status_code}") # FIXME: params Loading src/device/service/drivers/xr/cm/connection.py +10 −3 Original line number Diff line number Diff line Loading @@ -79,6 +79,9 @@ class Connection: state = from_json["state"] self.name = state["name"] if "name" in state else None #Name is optional self.serviceMode = state["serviceMode"] # Implicit transport capacity is a string, where value "none" has special meaning. # So "none" is correct value, not "None" for missing attribute self.implicitTransportCapacity = config["implicitTransportCapacity"] if "implicitTransportCapacity" in config else "none" self.mc = config["mc"] if "mc" in config else None self.vlan_filter = state["outerVID"] if "outerVID" in state else None self.href = from_json["href"] Loading @@ -100,12 +103,15 @@ class Connection: # VLANs to interface names. Correspondingly cm-cli user has to know # to use VLANs on low level test APIs when using VTI mode. self.serviceMode = self.__guess_service_mode_from_emulated_enpoints() if self.serviceMode == "portMode": if self.serviceMode == "XR-L1": self.vlan_filter = None self.mc = None self.implicitTransportCapacity ="portMode" else: self.vlan_filter = str(self.__guess_vlan_id()) + " " # Needs to be in string format, can contain ranges, regexp is buggy, trailin space is needed for single VLAN self.mc = "matchOuterVID" # String "none" has a special meaning for implicitTransportCapacity self.implicitTransportCapacity ="none" self.cm_data = None else: Loading @@ -120,8 +126,8 @@ class Connection: def __guess_service_mode_from_emulated_enpoints(self): for ep in self.endpoints: if ep.vlan is not None: return "vtiP2pSymmetric" return "portMode" return "XR-VTI-P2P" return "XR-L1" def __guess_vlan_id(self) -> int: vlans = [] Loading @@ -140,6 +146,7 @@ class Connection: cfg = {} set_optional_parameter(cfg, "name", self.name) cfg["serviceMode"] = self.serviceMode cfg["implicitTransportCapacity"] = self.implicitTransportCapacity if self.endpoints: cfg["endpoints"] = [ep.create_config() for ep in self.endpoints] set_optional_parameter(cfg, "outerVID", self.vlan_filter) Loading src/device/service/drivers/xr/cm/tests/resources/connections-expanded.json +8 −4 Original line number Diff line number Diff line Loading @@ -2,7 +2,8 @@ { "config": { "name": "FooBar123", "serviceMode": "portMode" "serviceMode": "XR-L1", "implicitTransportCapacity": "portMode" }, "endpoints": [ { Loading Loading @@ -141,12 +142,14 @@ "createdBy": "host", "lifecycleState": "configured", "name": "FooBar123", "serviceMode": "portMode" "serviceMode": "XR-L1", "implicitTransportCapacity": "portMode" } }, { "config": { "serviceMode": "portMode" "serviceMode": "XR-L1", "implicitTransportCapacity": "portMode" }, "endpoints": [ { Loading Loading @@ -284,7 +287,8 @@ "state": { "createdBy": "host", "lifecycleState": "configured", "serviceMode": "portMode" "serviceMode": "XR-L1", "implicitTransportCapacity": "portMode" } } ] No newline at end of file src/device/service/drivers/xr/cm/tests/resources/single-connection-2022-12.json 0 → 100644 +160 −0 Original line number Diff line number Diff line [ { "config": { "implicitTransportCapacity": "portMode", "name": "test2", "serviceMode": "XR-L1" }, "endpoints": [ { "acs": [], "config": { "selector": { "moduleIfSelectorByModuleName": { "moduleClientIfAid": "XR-T2", "moduleName": "XR HUB 1" } } }, "href": "/network-connections/38675444-3f08-4dbe-a9c4-523ef309a518/endpoints/4801ecf5-fe37-4b8e-864f-2a0409210cb0", "id": "4801ecf5-fe37-4b8e-864f-2a0409210cb0", "parentId": "38675444-3f08-4dbe-a9c4-523ef309a518", "rt": [ "cm.network-connection.endpoint" ], "state": { "capacity": 100, "hostPort": { "chassisId": "192.168.100.1", "chassisIdSubtype": "networkAddress", "name": "", "portDescr": "et-1/0/0:1", "portId": "et-1/0/0:1", "portIdSubtype": "interfaceName", "portSourceMAC": "58:00:BB:00:00:12", "sysName": "SanJose" }, "moduleIf": { "clientIfAid": "XR-T2", "clientIfColId": 2, "clientIfPortSpeed": 100, "currentRole": "hub", "macAddress": "00:0B:F8:00:00:01", "moduleId": "68c23c59-3bcf-4d35-7042-a4a2d8a73e3f", "moduleName": "XR HUB 1", "serialNumber": "000000009" } } }, { "acs": [], "config": { "selector": { "moduleIfSelectorByModuleName": { "moduleClientIfAid": "XR-T1", "moduleName": "XR LEAF 2" } } }, "href": "/network-connections/38675444-3f08-4dbe-a9c4-523ef309a518/endpoints/123fc228-59ed-423e-8537-c189f3434a38", "id": "123fc228-59ed-423e-8537-c189f3434a38", "parentId": "38675444-3f08-4dbe-a9c4-523ef309a518", "rt": [ "cm.network-connection.endpoint" ], "state": { "capacity": 100, "hostPort": { "chassisId": "192.168.101.2", "chassisIdSubtype": "networkAddress", "name": "", "portDescr": "et-0/0/0:0", "portId": "et-0/0/0:0", "portIdSubtype": "interfaceName", "portSourceMAC": "58:00:BB:00:12:01", "sysName": "Cupertino" }, "moduleIf": { "clientIfAid": "XR-T1", "clientIfColId": 1, "clientIfPortSpeed": 100, "currentRole": "leaf", "macAddress": "00:0B:F8:00:01:02", "moduleId": "095a7a6b-1f69-4d2e-5581-cdffbb85e40f", "moduleName": "XR LEAF 2", "serialNumber": "00000000C" } } } ], "href": "/network-connections/38675444-3f08-4dbe-a9c4-523ef309a518", "id": "38675444-3f08-4dbe-a9c4-523ef309a518", "lcs": [ { "config": { "clientAid": "XR-T2", "direction": "txRx", "dscgAid": "XRCARRIERDSCG-3", "moduleId": "68c23c59-3bcf-4d35-7042-a4a2d8a73e3f" }, "href": "/lcs/0d5929d8-6498-4c54-b38b-43c6cb85a18b", "id": "0d5929d8-6498-4c54-b38b-43c6cb85a18b", "parentIds": [ "38675444-3f08-4dbe-a9c4-523ef309a518" ], "rt": [ "cm.network-connection.local-connection" ], "state": { "clientAid": "XR-T2", "colId": 2, "direction": "txRx", "dscgAid": "XRCARRIERDSCG-3", "lcAid": "XRLC-3", "lineAid": "", "macAddress": "00:0B:F8:00:00:01", "moduleId": "68c23c59-3bcf-4d35-7042-a4a2d8a73e3f", "remoteClientId": "", "remoteModuleId": "" } }, { "config": { "clientAid": "XR-T1", "direction": "txRx", "dscgAid": "XRCARRIERDSCG-3", "moduleId": "095a7a6b-1f69-4d2e-5581-cdffbb85e40f" }, "href": "/lcs/1d6cc8bf-de89-4950-a01d-4b4522c65f8c", "id": "1d6cc8bf-de89-4950-a01d-4b4522c65f8c", "parentIds": [ "38675444-3f08-4dbe-a9c4-523ef309a518" ], "rt": [ "cm.network-connection.local-connection" ], "state": { "clientAid": "XR-T1", "colId": 1, "direction": "txRx", "dscgAid": "XRCARRIERDSCG-3", "lcAid": "XRLC-3", "lineAid": "", "macAddress": "00:0B:F8:00:01:02", "moduleId": "095a7a6b-1f69-4d2e-5581-cdffbb85e40f", "remoteClientId": "", "remoteModuleId": "" } } ], "rt": [ "cm.network-connection" ], "state": { "createdBy": "cm", "lifecycleState": "configured", "name": "test2", "serviceMode": "XR-L1" } } ] No newline at end of file src/device/service/drivers/xr/cm/tests/test_connection.py +8 −8 Original line number Diff line number Diff line Loading @@ -29,21 +29,21 @@ def test_connection_json(): connection = Connection(j[0]) assert connection.name == "FooBar123" assert "name: FooBar123, id: /network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03, service-mode: portMode, end-points: [(XR LEAF 1|XR-T1, 0), (XR HUB 1|XR-T1, 0)]" == str(connection) assert "name: FooBar123, id: /network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03, service-mode: XR-L1, end-points: [(XR LEAF 1|XR-T1, 0), (XR HUB 1|XR-T1, 0)]" == str(connection) config = connection.create_config() expected_config = {'name': 'FooBar123', 'serviceMode': 'portMode', 'endpoints': [{'selector': {'ifSelectorByModuleName': {'moduleName': 'XR LEAF 1', 'moduleClientIfAid': 'XR-T1'}}}, {'selector': {'ifSelectorByModuleName': {'moduleName': 'XR HUB 1', 'moduleClientIfAid': 'XR-T1'}}}]} expected_config = {'name': 'FooBar123', 'serviceMode': 'XR-L1', 'implicitTransportCapacity': 'portMode', 'endpoints': [{'selector': {'moduleIfSelectorByModuleName': {'moduleName': 'XR LEAF 1', 'moduleClientIfAid': 'XR-T1'}}}, {'selector': {'moduleIfSelectorByModuleName': {'moduleName': 'XR HUB 1', 'moduleClientIfAid': 'XR-T1'}}}]} assert config == expected_config # Remove mandatory key from leaf endpoint. It will not be parsed, but hub endpoint will del j[0]["endpoints"][0]["state"]["moduleIf"]["clientIfAid"] connection = Connection(j[0]) assert "name: FooBar123, id: /network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03, service-mode: portMode, end-points: [(XR HUB 1|XR-T1, 0)]" == str(connection) assert "name: FooBar123, id: /network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03, service-mode: XR-L1, end-points: [(XR HUB 1|XR-T1, 0)]" == str(connection) # Remove Name, it is optional (although TF will always configure it) del j[0]["state"]["name"] connection = Connection(j[0]) assert "name: <NO NAME>, id: /network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03, service-mode: portMode, end-points: [(XR HUB 1|XR-T1, 0)]" == str(connection) assert "name: <NO NAME>, id: /network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03, service-mode: XR-L1, end-points: [(XR HUB 1|XR-T1, 0)]" == str(connection) # Remove mandatory key, will raise an exception del j[0]["state"] Loading @@ -66,14 +66,14 @@ def test_connection_ep_change_compute(): new_connection = Connection(from_tf_service=TFService("FooBar123", "XR LEAF 1|XR-T1", "XR HUB 1|changed here", 0)) ep_deletes, ep_creates, ep_updates = new_connection.get_endpoint_updates(existing_connection) assert ep_deletes == ['/network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03/endpoints/1d58ba8f-4d51-4213-83e1-97a0e0bdd388'] assert ep_creates == [{'selector': {'ifSelectorByModuleName': {'moduleClientIfAid': 'changed here', 'moduleName': 'XR HUB 1'}}}] assert ep_creates == [{'selector': {'moduleIfSelectorByModuleName': {'moduleClientIfAid': 'changed here', 'moduleName': 'XR HUB 1'}}}] assert not ep_updates # Change one of the endpoints and capacity new_connection = Connection(from_tf_service=TFService("FooBar123", "XR LEAF 1|XR-T1", "XR HUB 1|changed here", 125)) ep_deletes, ep_creates, ep_updates = new_connection.get_endpoint_updates(existing_connection) assert ep_deletes == ['/network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03/endpoints/1d58ba8f-4d51-4213-83e1-97a0e0bdd388'] assert ep_creates == [{'selector': {'ifSelectorByModuleName': {'moduleClientIfAid': 'changed here', 'moduleName': 'XR HUB 1'}}, "capacity": 125}] assert ep_creates == [{'selector': {'moduleIfSelectorByModuleName': {'moduleClientIfAid': 'changed here', 'moduleName': 'XR HUB 1'}}, "capacity": 125}] assert ep_updates == [('/network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03/endpoints/230516d0-7e38-44b1-b174-1ba7d4454ee6', {'capacity': 125})] # No change at all Loading @@ -93,13 +93,13 @@ def test_connection_ep_change_compute(): def test_connection_from_service(): # Port mode connection = Connection(from_tf_service=TFService("FooBar123", "XR LEAF 1|XR-T1", "XR HUB 1|XR-T1", 0)) assert connection.create_config() == {'name': 'TF:FooBar123', 'serviceMode': 'portMode', 'endpoints': [{'selector': {'ifSelectorByModuleName': {'moduleName': 'XR LEAF 1', 'moduleClientIfAid': 'XR-T1'}}}, {'selector': {'ifSelectorByModuleName': {'moduleName': 'XR HUB 1', 'moduleClientIfAid': 'XR-T1'}}}]} assert connection.create_config() == {'name': 'TF:FooBar123', 'serviceMode': 'XR-L1', 'implicitTransportCapacity': 'portMode', 'endpoints': [{'selector': {'moduleIfSelectorByModuleName': {'moduleName': 'XR LEAF 1', 'moduleClientIfAid': 'XR-T1'}}}, {'selector': {'moduleIfSelectorByModuleName': {'moduleName': 'XR HUB 1', 'moduleClientIfAid': 'XR-T1'}}}]} # VTI mode connection = Connection(from_tf_service=TFService("FooBar123", "XR LEAF 1|XR-T1.A", "XR HUB 1|XR-T1.100", 0)) # In endpoint selectors VLANs are note present (CM does not know about them, encoding them to aids is purely internal to Teraflow) # However VLAN adds outerVID and some other fields assert connection.create_config() == {'name': 'TF:FooBar123', 'serviceMode': 'vtiP2pSymmetric', 'endpoints': [{'selector': {'ifSelectorByModuleName': {'moduleName': 'XR LEAF 1', 'moduleClientIfAid': 'XR-T1'}}}, {'selector': {'ifSelectorByModuleName': {'moduleName': 'XR HUB 1', 'moduleClientIfAid': 'XR-T1'}}}], 'outerVID': '100 ', 'mc': 'matchOuterVID'} assert connection.create_config() == {'name': 'TF:FooBar123', 'serviceMode': 'XR-VTI-P2P', 'implicitTransportCapacity': 'none', 'endpoints': [{'selector': {'moduleIfSelectorByModuleName': {'moduleName': 'XR LEAF 1', 'moduleClientIfAid': 'XR-T1'}}}, {'selector': {'moduleIfSelectorByModuleName': {'moduleName': 'XR HUB 1', 'moduleClientIfAid': 'XR-T1'}}}], 'outerVID': '100 ', 'mc': 'matchOuterVID'} # Invalid configuration, differring VLANs on different sides with pytest.raises(InconsistentVlanConfiguration) as _e_info: Loading Loading
src/device/service/drivers/xr/cm/cm_connection.py +8 −1 Original line number Diff line number Diff line Loading @@ -61,7 +61,14 @@ class HttpResult: def __str__(self): status_code = self.status_code if self.status_code is not None else "<not executed>" return f"{self.method} {self.url} {self.params}, status {status_code}" if self.text: if len(self.text) > 1024: body_text = self.text[:1024] + "..." else: body_text = self.text else: body_text = "NONE" return f"{self.method} {self.url} {self.params}, status {status_code}, body {body_text}" def process_http_response(self, response: requests.Response, permit_empty_body:bool = False): LOGGER.info(f"process_http_response(): {self.method}: {self.url} qparams={self.params} ==> {response.status_code}") # FIXME: params Loading
src/device/service/drivers/xr/cm/connection.py +10 −3 Original line number Diff line number Diff line Loading @@ -79,6 +79,9 @@ class Connection: state = from_json["state"] self.name = state["name"] if "name" in state else None #Name is optional self.serviceMode = state["serviceMode"] # Implicit transport capacity is a string, where value "none" has special meaning. # So "none" is correct value, not "None" for missing attribute self.implicitTransportCapacity = config["implicitTransportCapacity"] if "implicitTransportCapacity" in config else "none" self.mc = config["mc"] if "mc" in config else None self.vlan_filter = state["outerVID"] if "outerVID" in state else None self.href = from_json["href"] Loading @@ -100,12 +103,15 @@ class Connection: # VLANs to interface names. Correspondingly cm-cli user has to know # to use VLANs on low level test APIs when using VTI mode. self.serviceMode = self.__guess_service_mode_from_emulated_enpoints() if self.serviceMode == "portMode": if self.serviceMode == "XR-L1": self.vlan_filter = None self.mc = None self.implicitTransportCapacity ="portMode" else: self.vlan_filter = str(self.__guess_vlan_id()) + " " # Needs to be in string format, can contain ranges, regexp is buggy, trailin space is needed for single VLAN self.mc = "matchOuterVID" # String "none" has a special meaning for implicitTransportCapacity self.implicitTransportCapacity ="none" self.cm_data = None else: Loading @@ -120,8 +126,8 @@ class Connection: def __guess_service_mode_from_emulated_enpoints(self): for ep in self.endpoints: if ep.vlan is not None: return "vtiP2pSymmetric" return "portMode" return "XR-VTI-P2P" return "XR-L1" def __guess_vlan_id(self) -> int: vlans = [] Loading @@ -140,6 +146,7 @@ class Connection: cfg = {} set_optional_parameter(cfg, "name", self.name) cfg["serviceMode"] = self.serviceMode cfg["implicitTransportCapacity"] = self.implicitTransportCapacity if self.endpoints: cfg["endpoints"] = [ep.create_config() for ep in self.endpoints] set_optional_parameter(cfg, "outerVID", self.vlan_filter) Loading
src/device/service/drivers/xr/cm/tests/resources/connections-expanded.json +8 −4 Original line number Diff line number Diff line Loading @@ -2,7 +2,8 @@ { "config": { "name": "FooBar123", "serviceMode": "portMode" "serviceMode": "XR-L1", "implicitTransportCapacity": "portMode" }, "endpoints": [ { Loading Loading @@ -141,12 +142,14 @@ "createdBy": "host", "lifecycleState": "configured", "name": "FooBar123", "serviceMode": "portMode" "serviceMode": "XR-L1", "implicitTransportCapacity": "portMode" } }, { "config": { "serviceMode": "portMode" "serviceMode": "XR-L1", "implicitTransportCapacity": "portMode" }, "endpoints": [ { Loading Loading @@ -284,7 +287,8 @@ "state": { "createdBy": "host", "lifecycleState": "configured", "serviceMode": "portMode" "serviceMode": "XR-L1", "implicitTransportCapacity": "portMode" } } ] No newline at end of file
src/device/service/drivers/xr/cm/tests/resources/single-connection-2022-12.json 0 → 100644 +160 −0 Original line number Diff line number Diff line [ { "config": { "implicitTransportCapacity": "portMode", "name": "test2", "serviceMode": "XR-L1" }, "endpoints": [ { "acs": [], "config": { "selector": { "moduleIfSelectorByModuleName": { "moduleClientIfAid": "XR-T2", "moduleName": "XR HUB 1" } } }, "href": "/network-connections/38675444-3f08-4dbe-a9c4-523ef309a518/endpoints/4801ecf5-fe37-4b8e-864f-2a0409210cb0", "id": "4801ecf5-fe37-4b8e-864f-2a0409210cb0", "parentId": "38675444-3f08-4dbe-a9c4-523ef309a518", "rt": [ "cm.network-connection.endpoint" ], "state": { "capacity": 100, "hostPort": { "chassisId": "192.168.100.1", "chassisIdSubtype": "networkAddress", "name": "", "portDescr": "et-1/0/0:1", "portId": "et-1/0/0:1", "portIdSubtype": "interfaceName", "portSourceMAC": "58:00:BB:00:00:12", "sysName": "SanJose" }, "moduleIf": { "clientIfAid": "XR-T2", "clientIfColId": 2, "clientIfPortSpeed": 100, "currentRole": "hub", "macAddress": "00:0B:F8:00:00:01", "moduleId": "68c23c59-3bcf-4d35-7042-a4a2d8a73e3f", "moduleName": "XR HUB 1", "serialNumber": "000000009" } } }, { "acs": [], "config": { "selector": { "moduleIfSelectorByModuleName": { "moduleClientIfAid": "XR-T1", "moduleName": "XR LEAF 2" } } }, "href": "/network-connections/38675444-3f08-4dbe-a9c4-523ef309a518/endpoints/123fc228-59ed-423e-8537-c189f3434a38", "id": "123fc228-59ed-423e-8537-c189f3434a38", "parentId": "38675444-3f08-4dbe-a9c4-523ef309a518", "rt": [ "cm.network-connection.endpoint" ], "state": { "capacity": 100, "hostPort": { "chassisId": "192.168.101.2", "chassisIdSubtype": "networkAddress", "name": "", "portDescr": "et-0/0/0:0", "portId": "et-0/0/0:0", "portIdSubtype": "interfaceName", "portSourceMAC": "58:00:BB:00:12:01", "sysName": "Cupertino" }, "moduleIf": { "clientIfAid": "XR-T1", "clientIfColId": 1, "clientIfPortSpeed": 100, "currentRole": "leaf", "macAddress": "00:0B:F8:00:01:02", "moduleId": "095a7a6b-1f69-4d2e-5581-cdffbb85e40f", "moduleName": "XR LEAF 2", "serialNumber": "00000000C" } } } ], "href": "/network-connections/38675444-3f08-4dbe-a9c4-523ef309a518", "id": "38675444-3f08-4dbe-a9c4-523ef309a518", "lcs": [ { "config": { "clientAid": "XR-T2", "direction": "txRx", "dscgAid": "XRCARRIERDSCG-3", "moduleId": "68c23c59-3bcf-4d35-7042-a4a2d8a73e3f" }, "href": "/lcs/0d5929d8-6498-4c54-b38b-43c6cb85a18b", "id": "0d5929d8-6498-4c54-b38b-43c6cb85a18b", "parentIds": [ "38675444-3f08-4dbe-a9c4-523ef309a518" ], "rt": [ "cm.network-connection.local-connection" ], "state": { "clientAid": "XR-T2", "colId": 2, "direction": "txRx", "dscgAid": "XRCARRIERDSCG-3", "lcAid": "XRLC-3", "lineAid": "", "macAddress": "00:0B:F8:00:00:01", "moduleId": "68c23c59-3bcf-4d35-7042-a4a2d8a73e3f", "remoteClientId": "", "remoteModuleId": "" } }, { "config": { "clientAid": "XR-T1", "direction": "txRx", "dscgAid": "XRCARRIERDSCG-3", "moduleId": "095a7a6b-1f69-4d2e-5581-cdffbb85e40f" }, "href": "/lcs/1d6cc8bf-de89-4950-a01d-4b4522c65f8c", "id": "1d6cc8bf-de89-4950-a01d-4b4522c65f8c", "parentIds": [ "38675444-3f08-4dbe-a9c4-523ef309a518" ], "rt": [ "cm.network-connection.local-connection" ], "state": { "clientAid": "XR-T1", "colId": 1, "direction": "txRx", "dscgAid": "XRCARRIERDSCG-3", "lcAid": "XRLC-3", "lineAid": "", "macAddress": "00:0B:F8:00:01:02", "moduleId": "095a7a6b-1f69-4d2e-5581-cdffbb85e40f", "remoteClientId": "", "remoteModuleId": "" } } ], "rt": [ "cm.network-connection" ], "state": { "createdBy": "cm", "lifecycleState": "configured", "name": "test2", "serviceMode": "XR-L1" } } ] No newline at end of file
src/device/service/drivers/xr/cm/tests/test_connection.py +8 −8 Original line number Diff line number Diff line Loading @@ -29,21 +29,21 @@ def test_connection_json(): connection = Connection(j[0]) assert connection.name == "FooBar123" assert "name: FooBar123, id: /network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03, service-mode: portMode, end-points: [(XR LEAF 1|XR-T1, 0), (XR HUB 1|XR-T1, 0)]" == str(connection) assert "name: FooBar123, id: /network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03, service-mode: XR-L1, end-points: [(XR LEAF 1|XR-T1, 0), (XR HUB 1|XR-T1, 0)]" == str(connection) config = connection.create_config() expected_config = {'name': 'FooBar123', 'serviceMode': 'portMode', 'endpoints': [{'selector': {'ifSelectorByModuleName': {'moduleName': 'XR LEAF 1', 'moduleClientIfAid': 'XR-T1'}}}, {'selector': {'ifSelectorByModuleName': {'moduleName': 'XR HUB 1', 'moduleClientIfAid': 'XR-T1'}}}]} expected_config = {'name': 'FooBar123', 'serviceMode': 'XR-L1', 'implicitTransportCapacity': 'portMode', 'endpoints': [{'selector': {'moduleIfSelectorByModuleName': {'moduleName': 'XR LEAF 1', 'moduleClientIfAid': 'XR-T1'}}}, {'selector': {'moduleIfSelectorByModuleName': {'moduleName': 'XR HUB 1', 'moduleClientIfAid': 'XR-T1'}}}]} assert config == expected_config # Remove mandatory key from leaf endpoint. It will not be parsed, but hub endpoint will del j[0]["endpoints"][0]["state"]["moduleIf"]["clientIfAid"] connection = Connection(j[0]) assert "name: FooBar123, id: /network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03, service-mode: portMode, end-points: [(XR HUB 1|XR-T1, 0)]" == str(connection) assert "name: FooBar123, id: /network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03, service-mode: XR-L1, end-points: [(XR HUB 1|XR-T1, 0)]" == str(connection) # Remove Name, it is optional (although TF will always configure it) del j[0]["state"]["name"] connection = Connection(j[0]) assert "name: <NO NAME>, id: /network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03, service-mode: portMode, end-points: [(XR HUB 1|XR-T1, 0)]" == str(connection) assert "name: <NO NAME>, id: /network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03, service-mode: XR-L1, end-points: [(XR HUB 1|XR-T1, 0)]" == str(connection) # Remove mandatory key, will raise an exception del j[0]["state"] Loading @@ -66,14 +66,14 @@ def test_connection_ep_change_compute(): new_connection = Connection(from_tf_service=TFService("FooBar123", "XR LEAF 1|XR-T1", "XR HUB 1|changed here", 0)) ep_deletes, ep_creates, ep_updates = new_connection.get_endpoint_updates(existing_connection) assert ep_deletes == ['/network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03/endpoints/1d58ba8f-4d51-4213-83e1-97a0e0bdd388'] assert ep_creates == [{'selector': {'ifSelectorByModuleName': {'moduleClientIfAid': 'changed here', 'moduleName': 'XR HUB 1'}}}] assert ep_creates == [{'selector': {'moduleIfSelectorByModuleName': {'moduleClientIfAid': 'changed here', 'moduleName': 'XR HUB 1'}}}] assert not ep_updates # Change one of the endpoints and capacity new_connection = Connection(from_tf_service=TFService("FooBar123", "XR LEAF 1|XR-T1", "XR HUB 1|changed here", 125)) ep_deletes, ep_creates, ep_updates = new_connection.get_endpoint_updates(existing_connection) assert ep_deletes == ['/network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03/endpoints/1d58ba8f-4d51-4213-83e1-97a0e0bdd388'] assert ep_creates == [{'selector': {'ifSelectorByModuleName': {'moduleClientIfAid': 'changed here', 'moduleName': 'XR HUB 1'}}, "capacity": 125}] assert ep_creates == [{'selector': {'moduleIfSelectorByModuleName': {'moduleClientIfAid': 'changed here', 'moduleName': 'XR HUB 1'}}, "capacity": 125}] assert ep_updates == [('/network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03/endpoints/230516d0-7e38-44b1-b174-1ba7d4454ee6', {'capacity': 125})] # No change at all Loading @@ -93,13 +93,13 @@ def test_connection_ep_change_compute(): def test_connection_from_service(): # Port mode connection = Connection(from_tf_service=TFService("FooBar123", "XR LEAF 1|XR-T1", "XR HUB 1|XR-T1", 0)) assert connection.create_config() == {'name': 'TF:FooBar123', 'serviceMode': 'portMode', 'endpoints': [{'selector': {'ifSelectorByModuleName': {'moduleName': 'XR LEAF 1', 'moduleClientIfAid': 'XR-T1'}}}, {'selector': {'ifSelectorByModuleName': {'moduleName': 'XR HUB 1', 'moduleClientIfAid': 'XR-T1'}}}]} assert connection.create_config() == {'name': 'TF:FooBar123', 'serviceMode': 'XR-L1', 'implicitTransportCapacity': 'portMode', 'endpoints': [{'selector': {'moduleIfSelectorByModuleName': {'moduleName': 'XR LEAF 1', 'moduleClientIfAid': 'XR-T1'}}}, {'selector': {'moduleIfSelectorByModuleName': {'moduleName': 'XR HUB 1', 'moduleClientIfAid': 'XR-T1'}}}]} # VTI mode connection = Connection(from_tf_service=TFService("FooBar123", "XR LEAF 1|XR-T1.A", "XR HUB 1|XR-T1.100", 0)) # In endpoint selectors VLANs are note present (CM does not know about them, encoding them to aids is purely internal to Teraflow) # However VLAN adds outerVID and some other fields assert connection.create_config() == {'name': 'TF:FooBar123', 'serviceMode': 'vtiP2pSymmetric', 'endpoints': [{'selector': {'ifSelectorByModuleName': {'moduleName': 'XR LEAF 1', 'moduleClientIfAid': 'XR-T1'}}}, {'selector': {'ifSelectorByModuleName': {'moduleName': 'XR HUB 1', 'moduleClientIfAid': 'XR-T1'}}}], 'outerVID': '100 ', 'mc': 'matchOuterVID'} assert connection.create_config() == {'name': 'TF:FooBar123', 'serviceMode': 'XR-VTI-P2P', 'implicitTransportCapacity': 'none', 'endpoints': [{'selector': {'moduleIfSelectorByModuleName': {'moduleName': 'XR LEAF 1', 'moduleClientIfAid': 'XR-T1'}}}, {'selector': {'moduleIfSelectorByModuleName': {'moduleName': 'XR HUB 1', 'moduleClientIfAid': 'XR-T1'}}}], 'outerVID': '100 ', 'mc': 'matchOuterVID'} # Invalid configuration, differring VLANs on different sides with pytest.raises(InconsistentVlanConfiguration) as _e_info: Loading