aboutsummaryrefslogtreecommitdiffstats
path: root/resources/libraries
diff options
context:
space:
mode:
Diffstat (limited to 'resources/libraries')
-rw-r--r--resources/libraries/bash/dut_setup.sh2
-rw-r--r--resources/libraries/python/IPv4Util.py27
-rw-r--r--resources/libraries/python/L2Util.py46
-rw-r--r--resources/libraries/robot/double_qemu_setup.robot99
-rw-r--r--resources/libraries/robot/vxlan.robot2
5 files changed, 170 insertions, 6 deletions
diff --git a/resources/libraries/bash/dut_setup.sh b/resources/libraries/bash/dut_setup.sh
index a5ca415fb5..8d91bc9c99 100644
--- a/resources/libraries/bash/dut_setup.sh
+++ b/resources/libraries/bash/dut_setup.sh
@@ -49,3 +49,5 @@ cmd 'tail -n 50 /var/log/syslog'
echo "[Command_desc] Adding dpdk-input trace"
cmd 'sudo vpp_api_test <<< "exec trace add dpdk-input 100"'
+echo "[Command_desc] Adding vhost-user-input trace"
+cmd 'sudo vpp_api_test <<< "exec trace add vhost-user-input 100"'
diff --git a/resources/libraries/python/IPv4Util.py b/resources/libraries/python/IPv4Util.py
index 5ee73c08fc..4fe711fbff 100644
--- a/resources/libraries/python/IPv4Util.py
+++ b/resources/libraries/python/IPv4Util.py
@@ -18,6 +18,7 @@ from robot.api.deco import keyword
from resources.libraries.python.topology import Topology
from resources.libraries.python.IPv4Setup import get_node
+from resources.libraries.python.ssh import exec_cmd
class IPv4Util(object):
@@ -160,3 +161,29 @@ class IPv4Util(object):
if net is None:
raise ValueError('Link "{0}" not found'.format(link))
return net.get('prefix')
+
+ @staticmethod
+ def send_ping_from_node_to_dst(node, destination, namespace=None,
+ ping_count=3):
+ """Send a ping from node to destination. Optionally, you can define a
+ namespace from where to send a ping.
+
+ :param node: Node to start ping on.
+ :param destination: IPv4 address where to send ping.
+ :param namespace: Namespace to send ping from.
+ :param ping_count: Number of pings to send.
+ :type node: dict
+ :type destination: str
+ :type namespace: str
+ :type ping_count: int
+ :raises RuntimeError: If no response for ping, raise error
+ """
+ cmd = ''
+ if namespace is not None:
+ cmd = 'ip netns exec {0} ping -c{1} {2}'.format(
+ namespace, ping_count, destination)
+ else:
+ cmd = 'ping -c{0} {1}'.format(ping_count, destination)
+ rc, stdout, stderr = exec_cmd(node, cmd, sudo=True)
+ if rc != 0:
+ raise RuntimeError("Ping Not Successful")
diff --git a/resources/libraries/python/L2Util.py b/resources/libraries/python/L2Util.py
index 5903d03549..e44a6b360a 100644
--- a/resources/libraries/python/L2Util.py
+++ b/resources/libraries/python/L2Util.py
@@ -21,7 +21,7 @@ from resources.libraries.python.ssh import exec_cmd_no_error
class L2Util(object):
- """Utilities for l2 configuration"""
+ """Utilities for l2 configuration."""
@staticmethod
def vpp_add_l2fib_entry(node, mac, interface, bd_id):
@@ -203,6 +203,7 @@ class L2Util(object):
:type br_name: str
:type if_1: str
:type if_2: str
+
"""
cmd = 'brctl addbr {0}'.format(br_name)
exec_cmd_no_error(node, cmd, sudo=True)
@@ -212,12 +213,41 @@ class L2Util(object):
exec_cmd_no_error(node, cmd, sudo=True)
@staticmethod
+ def setup_network_namespace(node, namespace_name, interface_name,
+ ip_address, prefix):
+ """Setup namespace on given node and attach interface and IP to
+ this namespace. Applicable also on TG node.
+
+ :param node: Node to set namespace on.
+ :param namespace_name: Namespace name.
+ :param interface_name: Interface name.
+ :param ip_address: IP address of namespace's interface.
+ :param prefix: IP address prefix length.
+ :type node: dict
+ :type namespace_name: str
+ :type vhost_if: str
+ :type ip_address: str
+ :type prefix: int
+
+ """
+ cmd = ('ip netns add {0}'.format(namespace_name))
+ exec_cmd_no_error(node, cmd, sudo=True)
+
+ cmd = ('ip link set dev {0} up netns {1}'.format(interface_name,
+ namespace_name))
+ exec_cmd_no_error(node, cmd, sudo=True)
+
+ cmd = ('ip netns exec {0} ip addr add {1}/{2} dev {3}'.format(
+ namespace_name, ip_address, prefix, interface_name))
+ exec_cmd_no_error(node, cmd, sudo=True)
+
+ @staticmethod
def linux_del_bridge(node, br_name):
"""Delete bridge from linux node.
:param node: Node to delete bridge from.
:param br_name: Bridge name.
- .. note:: The network interface corresponding to the bridge must be
+ ..note:: The network interface corresponding to the bridge must be
down before it can be deleted!
"""
cmd = 'brctl delbr {0}'.format(br_name)
@@ -250,17 +280,22 @@ class L2Util(object):
return data
@staticmethod
- def l2_tag_rewrite(node, interface, tag_rewrite_method):
+ def l2_tag_rewrite(node, interface, tag_rewrite_method, tag1_id=None):
"""Rewrite tags in frame.
:param node: Node to rewrite tags.
:param interface: Interface on which rewrite tags.
:param tag_rewrite_method: Method of tag rewrite.
+ :param tag1_id: Optional tag1 ID for VLAN.
:type node: dict
:type interface: str or int
:type tag_rewrite_method : str
+ :type tag1_id: int
"""
-
+ if tag1_id is None:
+ tag1_id = ''
+ else:
+ tag1_id = 'tag1 {0}'.format(tag1_id)
if isinstance(interface, basestring):
sw_if_index = Topology.get_interface_sw_index(node, interface)
else:
@@ -270,4 +305,5 @@ class L2Util(object):
vat.vat_terminal_exec_cmd_from_template("l2_tag_rewrite.vat",
sw_if_index=sw_if_index,
tag_rewrite_method=
- tag_rewrite_method)
+ tag_rewrite_method,
+ tag1_optional=tag1_id)
diff --git a/resources/libraries/robot/double_qemu_setup.robot b/resources/libraries/robot/double_qemu_setup.robot
new file mode 100644
index 0000000000..167605e943
--- /dev/null
+++ b/resources/libraries/robot/double_qemu_setup.robot
@@ -0,0 +1,99 @@
+# Copyright (c) 2016 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.
+
+*** Keywords ***
+| Setup QEMU Vhost and Run
+| | [Documentation] | Setup Qemu with 4 vhost-user interfaces and 4 namespaces.
+| | ... | Each call will be different object instance.
+| | ...
+| | ... | *Arguments:*
+| | ... | - dut_node - Node where to setup qemu. Type: dict
+| | ... | - sock1 - Socket path for first Vhost-User interface. Type: string
+| | ... | - sock2 - Socket path for second Vhost-User interface. Type: string
+| | ... | - sock3 - Socket path for third Vhost-User interface. Type: string
+| | ... | - sock4 - Socket path for forth Vhost-User interface. Type: string
+| | ... | - ip1 - IP address for namespace 1. Type: string
+| | ... | - ip2 - IP address for namespace 2. Type: string
+| | ... | - ip3 - IP address for namespace 3. Type: string
+| | ... | - ip4 - IP address for namespace 4. Type: string
+| | ... | - prefix_length - IP prefix length. Type: int
+| | ... | - qemu_name - Qemu instance name by which the object will be accessed.
+| | ... | Type: string
+| | ... | - mac_ID - MAC address ID used to differentiate qemu instances and
+| | ... | namespaces assigned to them. Type: string
+| | ...
+| | ... | *Example:*
+| | ...
+| | ... | \| Setup QEMU Vhost And Run\| {nodes['DUT1']} \| /tmp/sock1 \
+| | ... | \| /tmp/sock2 \| /tmp/sock3 \| /tmp/sock4 \| 16.0.0.1 \| 16.0.0.2 \
+| | ... | \| 16.0.0.3 \| 16.0.0.4 \| 24 \| qemu_instance_1 \| 06 \|
+| | ...
+| | [Arguments] | ${dut_node} | ${sock1} | ${sock2} | ${sock3} | ${sock4}
+| | ... | ${ip1} | ${ip2} | ${ip3} | ${ip4} | ${prefix_length}
+| | ... | ${qemu_name} | ${mac_ID}
+| | Import Library | resources.libraries.python.QemuUtils \
+| | ... | WITH NAME | ${qemu_name}
+| | ${qemu_add_vhost}= | Replace Variables | ${qemu_name}.Qemu Add Vhost User If
+| | ${qemu_set_node}= | Replace Variables | ${qemu_name}.Qemu Set Node
+| | ${qemu_start}= | Replace Variables | ${qemu_name}.Qemu Start
+| | Run keyword | ${qemu_add_vhost} | ${sock1} | mac=52:54:00:00:${mac_ID}:01
+| | Run keyword | ${qemu_add_vhost} | ${sock2} | mac=52:54:00:00:${mac_ID}:02
+| | Run keyword | ${qemu_add_vhost} | ${sock3} | mac=52:54:00:00:${mac_ID}:03
+| | Run keyword | ${qemu_add_vhost} | ${sock4} | mac=52:54:00:00:${mac_ID}:04
+| | Run keyword | ${qemu_set_node} | ${dut_node}
+| | ${vm}= | Run keyword | ${qemu_start}
+| | ${vhost1}= | Get Vhost User If Name By Sock | ${vm} | ${sock1}
+| | ${vhost2}= | Get Vhost User If Name By Sock | ${vm} | ${sock2}
+| | ${vhost3}= | Get Vhost User If Name By Sock | ${vm} | ${sock3}
+| | ${vhost4}= | Get Vhost User If Name By Sock | ${vm} | ${sock4}
+| | Set Interface State | ${vm} | ${vhost1} | up
+| | Set Interface State | ${vm} | ${vhost2} | up
+| | Set Interface State | ${vm} | ${vhost3} | up
+| | Set Interface State | ${vm} | ${vhost4} | up
+| | Setup Network Namespace
+| | ... | ${vm} | nmspace1 | ${vhost1} | ${ip1} | ${prefix_length}
+| | Setup Network Namespace
+| | ... | ${vm} | nmspace2 | ${vhost2} | ${ip2} | ${prefix_length}
+| | Setup Network Namespace
+| | ... | ${vm} | nmspace3 | ${vhost3} | ${ip3} | ${prefix_length}
+| | Setup Network Namespace
+| | ... | ${vm} | nmspace4 | ${vhost4} | ${ip4} | ${prefix_length}
+| | Set Test Variable | ${${qemu_name}} | ${vm}
+
+| Qemu Teardown
+| | [Documentation] | Stop specific qemu instance
+| | ... | running on ${dut_node}, ${vm} is VM node info dictionary
+| | ... | returned by qemu_start or None.
+| | ... | *Arguments:*
+| | ... | - dut_node - Node where to clean qemu. Type: dict
+| | ... | - vm - VM node info dictionary. Type: string
+| | ... | - qemu_name - Qemu instance by name. Type: string
+| | ...
+| | ... | *Example:*
+| | ...
+| | ... | \| Qemu Teardown \| ${node['DUT1']} \| ${vm} \| qemu_node_1 \|
+| | ...
+| | [Arguments] | ${dut_node} | ${vm} | ${qemu_name}
+| | ${set_node}= | Replace Variables | ${qemu_name}.Qemu Set Node
+| | ${sys_status}= | Replace Variables | ${qemu_name}.Qemu System Status
+| | ${kill}= | Replace Variables | ${qemu_name}.Qemu Kill
+| | ${sys_pd}= | Replace Variables | ${qemu_name}.Qemu System Powerdown
+| | ${quit}= | Replace Variables | ${qemu_name}.Qemu Quit
+| | ${clear_socks}= | Replace Variables | ${qemu_name}.Qemu Clear Socks
+| | Run Keyword | ${set_node} | ${dut_node}
+| | ${status} | ${value}= | Run Keyword And Ignore Error | ${sys_status}
+| | Run Keyword If | "${status}" == "FAIL" | ${kill}
+| | ... | ELSE IF | "${value}" == "running" | ${sys_pd}
+| | ... | ELSE | ${quit}
+| | Run Keyword | ${clear_socks}
+| | Run Keyword If | ${vm} is not None | Disconnect | ${vm}
diff --git a/resources/libraries/robot/vxlan.robot b/resources/libraries/robot/vxlan.robot
index e3d5f3578e..7b9776948e 100644
--- a/resources/libraries/robot/vxlan.robot
+++ b/resources/libraries/robot/vxlan.robot
@@ -62,7 +62,7 @@
| Interfaces are added to xconnect
| | [Arguments] | ${DUT} | ${INTERFACE_1} | ${INTERFACE_2}
-| | L2 setup xconnect on DUT | ${DUT} | ${INTERFACE_1} | ${INTERFACE_2}
+| | L2 setup xconnect on DUT | ${DUT} | ${INTERFACE_1} | ${INTERFACE_2}
| Vlan interfaces for VXLAN are created
| | [Documentation] | *Create VLAN subinterface on interfaces on DUTs with given VLAN ID.*