T-REX fixes
[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 """Performance testing 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
22 __all__ = ['TrafficGenerator']
23
24 class TrafficGenerator(object):
25     """Traffic Generator"""
26
27     def __init__(self):
28         self._result = None
29         self._loss = None
30         self._sent = None
31         self._received = None
32
33     @staticmethod
34     def initialize_traffic_generator(node, interface1, interface2):
35         """TG initialization
36         :param node: Traffic generator node
37         :param interface1: PCI address of first interface
38         :param interface2: PCI address of second interface
39         :type node: dict
40         :type interface1: str
41         :type interface2: str
42         :return: nothing
43         """
44
45         trex_path = "/opt/trex-core-1.91"
46
47         if node['type'] != NodeType.TG:
48             raise Exception('Node type is not a TG')
49         if node['subtype'] == NodeSubTypeTG.TREX:
50             ssh = SSH()
51             ssh.connect(node)
52
53             (ret, stdout, stderr) = ssh.exec_command(
54                 "sh -c 'cd {0}/scripts/ && "
55                 "sudo ./trex-cfg'"\
56                 .format(trex_path))
57
58             (ret, stdout, stderr) = ssh.exec_command(
59                 "sh -c 'cd {0}/scripts/ && "
60                 "sudo nohup ./t-rex-64 -i -c 4 --iom 0 > /dev/null 2>&1 &'"
61                 "> /dev/null"\
62                 .format(trex_path))
63
64     @staticmethod
65     def teardown_traffic_generator(node):
66         """TG teardown
67         :param node: Traffic generator node
68         :type node: dict
69         :return: nothing
70         """
71
72         if node['type'] != NodeType.TG:
73             raise Exception('Node type is not a TG')
74         if node['subtype'] == NodeSubTypeTG.TREX:
75             ssh = SSH()
76             ssh.connect(node)
77             (ret, stdout, stderr) = ssh.exec_command(
78                 "sh -c 'sudo pkill t-rex'")
79
80     def send_traffic_on(self, nodes_info, duration, rate,
81                         framesize, traffic_type):
82         """Send traffic from all configured interfaces on TG
83         :param nodes_info: Dictionary containing information on all nodes
84         in topology.
85         :param duration: Duration of test traffic generation in seconds
86         :param rate: Percentage of linerate
87         :param framesize: Frame size (L2) in Bytes
88         :param traffic_type: Traffic profile
89         :type nodes_info: dict
90         :type duration: str
91         :type rate: str
92         :type framesize: str
93         :type traffic_type: str
94         :return: TG output
95         :rtype: str
96         """
97
98         node = nodes_info["TG"]
99
100         if node['type'] != NodeType.TG:
101             raise Exception('Node type is not a TG')
102
103         if node['subtype'] is None:
104             raise Exception('TG subtype not defined')
105
106         ssh = SSH()
107         ssh.connect(node)
108
109         if node['subtype'] == NodeSubTypeTG.TREX:
110             if traffic_type in ["3-node-xconnect", "3-node-bridge"]:
111                 (ret, stdout, stderr) = ssh.exec_command(
112                     "sh -c '/tmp/openvpp-testing/resources/tools/t-rex-stateless.py "
113                     "-d {0} -r {1}% -s {2} "
114                     "--p1_src_start_ip 10.10.10.1 "
115                     "--p1_src_end_ip 10.10.10.254 "
116                     "--p1_dst_start_ip 20.20.20.1 "
117                     "--p2_src_start_ip 20.20.20.1 "
118                     "--p2_src_end_ip 20.20.20.254 "
119                     "--p2_dst_start_ip 10.10.10.1'".\
120                     format(duration, rate, framesize), timeout=int(duration)+60)
121             elif traffic_type in ["3-node-IPv4"]:
122                 (ret, stdout, stderr) = ssh.exec_command(
123                     "sh -c '/tmp/openvpp-testing/resources/tools/t-rex-stateless.py "
124                     "-d {0} -r {1}% -s {2} "
125                     "--p1_src_start_ip 10.10.10.2 "
126                     "--p1_src_end_ip 10.10.10.254 "
127                     "--p1_dst_start_ip 20.20.20.2 "
128                     "--p2_src_start_ip 20.20.20.2 "
129                     "--p2_src_end_ip 20.20.20.254 "
130                     "--p2_dst_start_ip 10.10.10.2'".\
131                     format(duration, rate, framesize),\
132                     timeout=int(duration)+60)
133             else:
134                 raise NotImplementedError('Unsupported traffic type')
135
136         else:
137             raise NotImplementedError("TG subtype not supported")
138
139         logger.trace(ret)
140         logger.trace(stdout)
141         logger.trace(stderr)
142
143         for line in stdout.splitlines():
144             pass
145
146         self._result = line
147         logger.info('TrafficGen result: {0}'.format(self._result))
148
149         self._loss = self._result.split(', ')[3].split('=')[1]
150
151         return self._result
152
153     def no_traffic_loss_occured(self):
154         """Fail is loss occured in traffic run
155         :return: nothing
156         """
157
158         if self._loss is None:
159             raise Exception('The traffic generation has not been issued')
160         if self._loss != '0':
161             raise Exception('Traffic loss occured: {0}'.format(self._loss))