diff options
author | pmikus <peter.mikus@protonmail.ch> | 2023-08-25 08:30:01 +0000 |
---|---|---|
committer | Peter Mikus <peter.mikus@protonmail.ch> | 2023-09-21 06:25:22 +0000 |
commit | ae2461388f4751093dd07ffa3ce25fae0e706f1c (patch) | |
tree | df057cfcfa4f6932f0e392daf5f0457b62b481d6 /resources/libraries | |
parent | f67c6ca7cb2fa7c0a62f34931d69db71ba1092ff (diff) |
feat(core): Multilink backend
Signed-off-by: pmikus <peter.mikus@protonmail.ch>
Change-Id: I8d168979ab9722e0056e97edb228f29cbfa245e3
Diffstat (limited to 'resources/libraries')
-rw-r--r-- | resources/libraries/python/IPTopology.py | 97 | ||||
-rw-r--r-- | resources/libraries/python/TrafficGenerator.py | 101 | ||||
-rw-r--r-- | resources/libraries/robot/ip/ip4.robot | 64 | ||||
-rw-r--r-- | resources/libraries/robot/shared/default.robot | 1 | ||||
-rw-r--r-- | resources/libraries/robot/shared/suite_setup.robot | 14 |
5 files changed, 155 insertions, 122 deletions
diff --git a/resources/libraries/python/IPTopology.py b/resources/libraries/python/IPTopology.py new file mode 100644 index 0000000000..1e5a18042d --- /dev/null +++ b/resources/libraries/python/IPTopology.py @@ -0,0 +1,97 @@ +# Copyright (c) 2023 Cisco and/or its affiliates. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""IP Topology Library.""" + +from robot.libraries.BuiltIn import BuiltIn + +from resources.libraries.python.IPUtil import IPUtil + + +class IPTopology: + """IP Topology Library.""" + + @staticmethod + def initialize_ipv4_forwarding(count=1, parallel_links=1): + """ + Custom setup of IPv4 forwarding with scalability of IP routes on all + DUT nodes in 2-node / 3-node circular topology. + + :param count: Number of routes to configure. + :param parallel_links: Number of parallel links to configure. + :type count: int + :type parallel_links: int + """ + topology = BuiltIn().get_variable_value("&{topology_info}") + dut = topology["duts"][-1] + ifl = BuiltIn().get_variable_value("${int}") + + for l, i in zip(range(parallel_links), range(1, parallel_links*2, 2)): + dut1_int1 = BuiltIn().get_variable_value(f"${{DUT1_{ifl}{i}}}[0]") + dut1_int2 = BuiltIn().get_variable_value(f"${{DUT1_{ifl}{i+1}}}[0]") + dut_int1 = BuiltIn().get_variable_value(f"${{{dut}_{ifl}{i}}}[0]") + dut_int2 = BuiltIn().get_variable_value(f"${{{dut}_{ifl}{i+1}}}[0]") + + IPUtil.vpp_add_ip_neighbor( + topology["DUT1"], dut1_int1, f"1.{l}.1.1", + topology[f"TG_pf{i}_mac"][0] + ) + if dut == "DUT2": + dut_mac1 = BuiltIn().get_variable_value( + f"${{{dut}_{ifl}{i}_mac}}[0]" + ) + IPUtil.vpp_add_ip_neighbor( + topology["DUT1"], dut1_int2, f"3.{l}.3.2", dut_mac1 + ) + dut_mac2 = BuiltIn().get_variable_value( + f"${{DUT1_{ifl}{i+1}_mac}}[0]" + ) + IPUtil.vpp_add_ip_neighbor( + topology["DUT2"], dut_int1, f"3.{l}.3.1", dut_mac2 + ) + IPUtil.vpp_add_ip_neighbor( + topology[dut], dut_int2, f"2.{l}.2.1", + topology[f"TG_pf{i}_mac"][0] + ) + + IPUtil.vpp_interface_set_ip_address( + topology["DUT1"], dut1_int1, f"1.{l}.1.2", 30 + ) + if dut == "DUT2": + IPUtil.vpp_interface_set_ip_address( + topology["DUT1"], dut1_int2, f"3.{l}.3.1", 30 + ) + IPUtil.vpp_interface_set_ip_address( + topology["DUT2"], dut_int1, f"3.{l}.3.2", 30 + ) + IPUtil.vpp_interface_set_ip_address( + topology[dut], dut_int2, f"2.{l}.2.2", 30 + ) + + IPUtil.vpp_route_add( + topology["DUT1"], f"{i}0.0.0.0", 32, gateway=f"1.{l}.1.1", + interface=dut1_int1, count=count + ) + if dut == "DUT2": + IPUtil.vpp_route_add( + topology["DUT1"], f"{i+1}0.0.0.0", 32, gateway=f"3.{l}.3.2", + interface=dut1_int2, count=count + ) + IPUtil.vpp_route_add( + topology["DUT2"], f"{i}0.0.0.0", 32, gateway=f"3.{l}.3.1", + interface=dut_int1, count=count + ) + IPUtil.vpp_route_add( + topology[dut], f"{i+1}0.0.0.0", 32, gateway=f"2.{l}.2.1", + interface=dut_int2, count=count + ) diff --git a/resources/libraries/python/TrafficGenerator.py b/resources/libraries/python/TrafficGenerator.py index afb9388111..4543bae87b 100644 --- a/resources/libraries/python/TrafficGenerator.py +++ b/resources/libraries/python/TrafficGenerator.py @@ -278,64 +278,69 @@ class TrafficGenerator(AbstractMeasurer): else: return "none" - def initialize_traffic_generator( - self, tg_node, tg_if1, tg_if2, tg_if1_adj_node, tg_if1_adj_if, - tg_if2_adj_node, tg_if2_adj_if, osi_layer, tg_if1_dst_mac=None, - tg_if2_dst_mac=None): + def initialize_traffic_generator(self, osi_layer, parallel_links=1): """TG initialization. - :param tg_node: Traffic generator node. - :param tg_if1: TG - name of first interface. - :param tg_if2: TG - name of second interface. - :param tg_if1_adj_node: TG if1 adjecent node. - :param tg_if1_adj_if: TG if1 adjecent interface. - :param tg_if2_adj_node: TG if2 adjecent node. - :param tg_if2_adj_if: TG if2 adjecent interface. :param osi_layer: 'L2', 'L3' or 'L7' - OSI Layer testing type. - :param tg_if1_dst_mac: Interface 1 destination MAC address. - :param tg_if2_dst_mac: Interface 2 destination MAC address. - :type tg_node: dict - :type tg_if1: str - :type tg_if2: str - :type tg_if1_adj_node: dict - :type tg_if1_adj_if: str - :type tg_if2_adj_node: dict - :type tg_if2_adj_if: str + :param parallel_links: Number of parallel links to configure. :type osi_layer: str - :type tg_if1_dst_mac: str - :type tg_if2_dst_mac: str - :returns: nothing - :raises RuntimeError: In case of issue during initialization. + :type parallel_links: int + :raises ValueError: If OSI layer is unknown. """ - subtype = check_subtype(tg_node) + if osi_layer not in ("L2", "L3", "L7"): + raise ValueError("Unknown OSI layer!") + + topology = BuiltIn().get_variable_value("&{topology_info}") + self._node = topology["TG"] + subtype = check_subtype(self._node) + if subtype == NodeSubTypeTG.TREX: - self._node = tg_node + trex_topology = list() self._mode = TrexMode.ASTF if osi_layer == "L7" else TrexMode.STL - if osi_layer == "L2": - tg_if1_adj_addr = Topology().get_interface_mac(tg_node, tg_if2) - tg_if2_adj_addr = Topology().get_interface_mac(tg_node, tg_if1) - elif osi_layer in ("L3", "L7"): - tg_if1_adj_addr = Topology().get_interface_mac( - tg_if1_adj_node, tg_if1_adj_if + for l in range(1, parallel_links*2, 2): + tg_if1_adj_addr = topology[f"TG_pf{l+1}_mac"][0] + tg_if2_adj_addr = topology[f"TG_pf{l}_mac"][0] + if osi_layer in ("L3", "L7"): + ifl = BuiltIn().get_variable_value("${int}") + last = topology["duts_count"] + tg_if1_adj_addr = Topology().get_interface_mac( + topology["DUT1"], + BuiltIn().get_variable_value( + f"${{DUT1_{ifl}{l}}}[0]" + ) + ) + tg_if2_adj_addr = Topology().get_interface_mac( + topology[f"DUT{last}"], + BuiltIn().get_variable_value( + f"${{DUT{last}_{ifl}{l+1}}}[0]" + ) + ) + + trex_topology.append( + dict( + interface=topology[f"TG_pf{l}"][0], + dst_mac=tg_if1_adj_addr + ) ) - tg_if2_adj_addr = Topology().get_interface_mac( - tg_if2_adj_node, tg_if2_adj_if + trex_topology.append( + dict( + interface=topology[f"TG_pf{l+1}"][0], + dst_mac=tg_if2_adj_addr + ) ) - else: - raise ValueError("Unknown OSI layer!") - - tg_topology = list() - tg_topology.append(dict(interface=tg_if1, dst_mac=tg_if1_adj_addr)) - tg_topology.append(dict(interface=tg_if2, dst_mac=tg_if2_adj_addr)) - if1_pci = Topology().get_interface_pci_addr(self._node, tg_if1) - if2_pci = Topology().get_interface_pci_addr(self._node, tg_if2) - if min(if1_pci, if2_pci) != if1_pci: - self._ifaces_reordered = True - tg_topology.reverse() - - TrexInitConfig.init_trex_startup_configuration(tg_node, tg_topology) - TrafficGenerator.startup_trex(tg_node, osi_layer, subtype=subtype) + if1_pci = topology[f"TG_pf{l}_pci"][0] + if2_pci = topology[f"TG_pf{l+1}_pci"][0] + if min(if1_pci, if2_pci) != if1_pci: + self._ifaces_reordered = True + trex_topology.reverse() + + TrexInitConfig.init_trex_startup_configuration( + self._node, trex_topology + ) + TrafficGenerator.startup_trex( + self._node, osi_layer, subtype=subtype + ) @staticmethod def startup_trex(tg_node, osi_layer, subtype=None): diff --git a/resources/libraries/robot/ip/ip4.robot b/resources/libraries/robot/ip/ip4.robot index 1d4e3e22b6..e3ebd0e289 100644 --- a/resources/libraries/robot/ip/ip4.robot +++ b/resources/libraries/robot/ip/ip4.robot @@ -1,4 +1,4 @@ -# Copyright (c) 2022 Cisco and/or its affiliates. +# Copyright (c) 2023 Cisco and/or its affiliates. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: @@ -12,9 +12,6 @@ # limitations under the License. *** Settings *** -| Library | resources.libraries.python.InterfaceUtil -| Library | resources.libraries.python.IPUtil -| | Documentation | IPv4 keywords *** Keywords *** @@ -98,65 +95,6 @@ | | ... | Vpp Route Add | ${dut2} | ${remote_host2_ip} | ${remote_host_mask} | | ... | gateway=1.1.1.1 | interface=${DUT2_${int}1}[0] -| Initialize IPv4 forwarding with scaling in circular topology -| | [Documentation] -| | ... | Custom setup of IPv4 topology with scalability of ip routes on all -| | ... | DUT nodes in 2-node / 3-node circular topology -| | -| | ... | *Arguments:* -| | ... | - count - IP route count. Type: integer -| | -| | ... | *Return:* -| | ... | - No value returned -| | -| | ... | *Example:* -| | -| | ... | \| Initialize IPv4 forwarding with scaling in 3-node circular \ -| | ... | topology \| 100000 \| -| | -| | [Arguments] | ${count} -| | -| | ${dut2_status} | ${value}= | Run Keyword And Ignore Error -| | ... | Variable Should Exist | ${dut2} -| | -| | Set interfaces in path up -| | -| | VPP Add IP Neighbor -| | ... | ${dut1} | ${DUT1_${int}1}[0] | 1.1.1.1 | ${TG_pf1_mac}[0] -| | Run Keyword If | '${dut2_status}' == 'PASS' -| | ... | VPP Add IP Neighbor -| | ... | ${dut1} | ${DUT1_${int}2}[0] | 2.2.2.2 | ${DUT2_${int}1_mac}[0] -| | Run Keyword If | '${dut2_status}' == 'PASS' -| | ... | VPP Add IP Neighbor -| | ... | ${dut2} | ${DUT2_${int}1}[0] | 2.2.2.1 | ${DUT1_${int}2_mac}[0] -| | ${dut}= | Run Keyword If | '${dut2_status}' == 'PASS' -| | ... | Set Variable | ${dut2} -| | ... | ELSE | Set Variable | ${dut1} -| | ${dut_if2}= | Run Keyword If | '${dut2_status}' == 'PASS' -| | ... | Set Variable | ${DUT2_${int}2}[0] -| | ... | ELSE | Set Variable | ${DUT1_${int}2}[0] -| | VPP Add IP Neighbor -| | ... | ${dut} | ${dut_if2} | 3.3.3.1 | ${TG_pf2_mac}[0] -| | VPP Interface Set IP Address -| | ... | ${dut1} | ${DUT1_${int}1}[0] | 1.1.1.2 | 30 -| | Run Keyword If | '${dut2_status}' == 'PASS' -| | ... | VPP Interface Set IP Address | ${dut1} | ${DUT1_${int}2}[0] | 2.2.2.1 -| | ... | 30 -| | Run Keyword If | '${dut2_status}' == 'PASS' -| | ... | VPP Interface Set IP Address | ${dut2} | ${DUT2_${int}1}[0] | 2.2.2.2 -| | ... | 30 -| | VPP Interface Set IP Address | ${dut} | ${dut_if2} | 3.3.3.2 | 30 -| | Vpp Route Add | ${dut1} | 10.0.0.0 | 32 | gateway=1.1.1.1 -| | ... | interface=${DUT1_${int}1}[0] | count=${count} -| | Run Keyword If | '${dut2_status}' == 'PASS' -| | ... | Vpp Route Add | ${dut1} | 20.0.0.0 | 32 | gateway=2.2.2.2 -| | ... | interface=${DUT1_${int}2}[0] | count=${count} -| | Run Keyword If | '${dut2_status}' == 'PASS' -| | ... | Vpp Route Add | ${dut2} | 10.0.0.0 | 32 | gateway=2.2.2.1 -| | ... | interface=${DUT2_${int}1}[0] | count=${count} -| | Vpp Route Add | ${dut} | 20.0.0.0 | 32 | gateway=3.3.3.1 -| | ... | interface=${dut_if2} | count=${count} - | Initialize IPv4 routing with memif pairs | | [Documentation] | | ... | Create pairs of Memif interfaces on all defined VPP nodes. Put each diff --git a/resources/libraries/robot/shared/default.robot b/resources/libraries/robot/shared/default.robot index c17b7ac441..65e6613680 100644 --- a/resources/libraries/robot/shared/default.robot +++ b/resources/libraries/robot/shared/default.robot @@ -28,6 +28,7 @@ | Library | resources.libraries.python.FlowUtil | Library | resources.libraries.python.L2Util | Library | resources.libraries.python.InterfaceUtil +| Library | resources.libraries.python.IPTopology | Library | resources.libraries.python.IPUtil | Library | resources.libraries.python.IPv6Util | Library | resources.libraries.python.IrqUtil diff --git a/resources/libraries/robot/shared/suite_setup.robot b/resources/libraries/robot/shared/suite_setup.robot index 438a39fb0e..4616ae08be 100644 --- a/resources/libraries/robot/shared/suite_setup.robot +++ b/resources/libraries/robot/shared/suite_setup.robot @@ -241,26 +241,18 @@ | | ${type} = | Get TG Type | ${nodes}[TG] | | ${version} = | Get TG Version | ${nodes}[TG] | | Export TG Type And Version | ${type} | ${version} -| | Initialize traffic generator -| | ... | ${tg} | ${TG_pf1}[0] | ${TG_pf2}[0] -| | ... | ${dut1} | ${DUT1_${int}1}[0] -| | ... | ${dut${duts_count}} | ${DUT${duts_count}_${int}2}[0] -| | ... | ${osi_layer} +| | Initialize traffic generator | ${osi_layer} | Additional Suite Setup Action For performance_tg_nic | | [Documentation] | | ... | Additional Setup for suites which uses performance measurement -| | ... | for L1 cross connect tests +| | ... | for L1 cross connect tests. | | | | ${type} = | Get TG Type | ${nodes}[TG] | | ${version} = | Get TG Version | ${nodes}[TG] | | Export Dut Type And Version | ${type} | ${version} | | Export TG Type And Version | ${type} | ${version} -| | Initialize traffic generator -| | ... | ${tg} | ${TG_pf1}[0] | ${TG_pf2}[0] -| | ... | ${tg} | ${TG_pf2}[0] -| | ... | ${tg} | ${TG_pf1}[0] -| | ... | ${osi_layer} +| | Initialize traffic generator | "L2" | Additional Suite Setup Action For iPerf3 | | [Documentation] |