24bec0af6c75c6dcfc3ac7142d19c4208154ba73
[csit.git] / resources / libraries / python / TrafficGenerator.py
1 # Copyright (c) 2016 Cisco and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
5 #
6 #     http://www.apache.org/licenses/LICENSE-2.0
7 #
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
13
14 """Traffic generator library."""
15
16 from robot.api import logger
17
18 from resources.libraries.python.ssh import SSH
19 from resources.libraries.python.topology import NodeType
20 from resources.libraries.python.topology import NodeSubTypeTG
21 from resources.libraries.python.topology import Topology
22
23 __all__ = ['TrafficGenerator']
24
25 class TrafficGenerator(object):
26     """Traffic Generator"""
27
28     def __init__(self):
29         self._result = None
30         self._loss = None
31         self._sent = None
32         self._received = None
33
34     @staticmethod
35     def initialize_traffic_generator(node, interface1, interface2):
36         """TG initialization
37         :param node: Traffic generator node
38         :param interface1: PCI address of first interface
39         :param interface2: PCI address of second interface
40         :type node: dict
41         :type interface1: str
42         :type interface2: str
43         :return: nothing
44         """
45
46         if node['type'] != NodeType.TG:
47             raise Exception('Node type is not a TG')
48         if node['subtype'] == NodeSubTypeTG.TREX:
49             ssh = SSH()
50             ssh.connect(node)
51
52             (ret, stdout, stderr) = ssh.exec_command(
53                 "sh -c 'cd /opt/trex-core-1.88/scripts/ && "
54                 "--bind=igb_uio {0} {1}".format(interface1, interface2))
55             (ret, stdout, stderr) = ssh.exec_command(
56                 "sh -c 'cd /opt/trex-core-1.88/scripts/ && "
57                 "sudo nohup ./t-rex-64 -i -c 4 --iom 0 > /dev/null 2>&1 &'")
58
59     @staticmethod
60     def teardown_traffic_generator(node):
61         """TG teardown
62         :param node: Traffic generator node
63         :type node: dict
64         :return: nothing
65         """
66
67         if node['type'] != NodeType.TG:
68             raise Exception('Node type is not a TG')
69         if node['subtype'] == NodeSubTypeTG.TREX:
70             ssh = SSH()
71             ssh.connect(node)
72             (ret, stdout, stderr) = ssh.exec_command(
73                 "sh -c 'sudo pkill t-rex'")
74
75     def send_traffic_on(self, nodes_info, duration, rate,
76                         framesize, traffic_type):
77         """Send traffic from all configured interfaces on TG
78         :param nodes_info: Dictionary containing information on all nodes
79         in topology.
80         :param duration: Duration of test traffic generation in seconds
81         :param rate: Percentage of linerate
82         :param framesize: Frame size (L2) in Bytes
83         :param traffic_type: Traffic profile
84         :type nodes_info: dict
85         :type duration: str
86         :type rate: str
87         :type framesize: str
88         :type traffic_type: str
89         :return: TG output
90         :rtype: str
91         """
92
93         node = nodes_info["TG"]
94
95         if node['type'] != NodeType.TG:
96             raise Exception('Node type is not a TG')
97
98         if node['subtype'] is None:
99             raise Exception('TG subtype not defined')
100
101         ssh = SSH()
102         ssh.connect(node)
103
104         tg_port3_src_mac = Topology.get_interface_mac_by_port_key(node, "port3")
105         _, adj_int = Topology.\
106             get_adjacent_node_and_interface_by_key(nodes_info, node, "port3")
107         tg_port3_dst_mac = adj_int['mac_address']
108
109         tg_port5_src_mac = Topology.get_interface_mac_by_port_key(node, "port5")
110         _, adj_int = Topology.\
111             get_adjacent_node_and_interface_by_key(nodes_info, node, "port5")
112         tg_port5_dst_mac = adj_int['mac_address']
113
114
115         if node['subtype'] == NodeSubTypeTG.TREX:
116             if traffic_type in ["3-node-xconnect", "3-node-bridge"]:
117                 (ret, stdout, stderr) = ssh.exec_command(
118                     "sh -c '/tmp/openvpp-testing/resources/tools/t-rex-stateless.py "
119                     "-d {0} -r {1}% -s {2} "
120                     "--p1_src_mac 52:00:00:00:00:01 "
121                     "--p1_dst_mac 52:00:00:00:00:02 "
122                     "--p1_src_start_ip 10.10.10.1 "
123                     "--p1_src_end_ip 10.10.10.254 "
124                     "--p1_dst_start_ip 20.20.20.1 "
125                     "--p1_dst_end_ip 20.20.20.254 "
126                     "--p2_src_mac 52:00:00:00:00:02 "
127                     "--p2_dst_mac 52:00:00:00:00:01 "
128                     "--p2_src_start_ip 20.20.20.1 "
129                     "--p2_src_end_ip 20.20.20.254 "
130                     "--p2_dst_start_ip 10.10.10.1 "
131                     "--p2_dst_end_ip 10.10.10.254'".\
132                     format(duration, rate, framesize), timeout=int(duration)+60)
133             elif traffic_type in ["3-node-IPv4"]:
134                 (ret, stdout, stderr) = ssh.exec_command(
135                     "sh -c '/tmp/openvpp-testing/resources/tools/t-rex-stateless.py "
136                     "-d {0} -r {1}% -s {2} "
137                     "--p1_src_mac {3} "
138                     "--p1_dst_mac {4} "
139                     "--p1_src_start_ip 10.10.10.2 "
140                     "--p1_src_end_ip 10.10.10.254 "
141                     "--p1_dst_start_ip 20.20.20.2 "
142                     "--p1_dst_end_ip 20.20.20.2 "
143                     "--p2_src_mac {5} "
144                     "--p2_dst_mac {6} "
145                     "--p2_src_start_ip 20.20.20.2 "
146                     "--p2_src_end_ip 20.20.20.254 "
147                     "--p2_dst_start_ip 10.10.10.2 "
148                     "--p2_dst_end_ip 10.10.10.2'".\
149                     format(duration, rate, framesize,\
150                            tg_port3_src_mac, tg_port3_dst_mac,\
151                            tg_port5_src_mac, tg_port5_dst_mac),\
152                            timeout=int(duration)+60)
153             else:
154                 raise NotImplementedError('Unsupported traffic type')
155
156         else:
157             raise NotImplementedError("TG subtype not supported")
158
159         logger.trace(ret)
160         logger.trace(stdout)
161         logger.trace(stderr)
162
163         for line in stdout.splitlines():
164             pass
165
166         self._result = line
167         logger.info('TrafficGen result: {0}'.format(self._result))
168
169         self._loss = self._result.split(', ')[3].split('=')[1]
170
171         return self._result
172
173     def no_traffic_loss_occured(self):
174         """Fail is loss occured in traffic run
175         :return: nothing
176         """
177
178         if self._loss is None:
179             raise Exception('The traffic generation has not been issued')
180         if self._loss != '0':
181             raise Exception('Traffic loss occured: {0}'.format(self._loss))