CSIT-786 L2FIB scale testing
[csit.git] / resources / traffic_profiles / trex / profile_trex_stateless_base_class.py
1 # Copyright (c) 2017 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 """Base class for stream profiles for T-rex traffic generator.
15 """
16
17 import sys
18 import socket
19 import struct
20
21 from random import choice
22 from string import letters
23
24 from trex_stl_lib.api import *
25
26
27 class TrafficStreamsBaseClass(object):
28     """Base class for stream profiles for T-rex traffic generator.
29     """
30
31     STREAM_TABLE = {
32         'IMIX_v4': [
33             {'size': 60, 'pps': 28, 'isg': 0},
34             {'size': 590, 'pps': 20, 'isg': 0.1},
35             {'size': 1514, 'pps': 4, 'isg': 0.2}
36         ],
37         'IMIX_v4_1': [
38             {'size': 64, 'pps': 28, 'isg': 0},
39             {'size': 570, 'pps': 16, 'isg': 0.1},
40             {'size': 1518, 'pps': 4, 'isg': 0.2}
41         ]
42     }
43
44     def __init__(self):
45
46         # Default value of frame size, it will be overwritten by the value of
47         # "framesize" parameter of "get_streams" method.
48         self.framesize = 64
49
50         # If needed, add your own parameters.
51
52     def _gen_payload(self, length):
53         """Generate payload.
54
55         If needed, implement your own algorithm.
56
57         :param length: Length of generated payload.
58         :type length: int
59         :returns: The generated payload.
60         :rtype: str
61         """
62
63         payload = ""
64         for _ in range(length):
65             payload += choice(letters)
66
67         return payload
68
69     def _get_start_end_ipv6(self, start_ip, end_ip):
70         """Get start host and number of hosts from IPv6 as integer.
71
72         :param start_ip: Start IPv6.
73         :param end_ip: End IPv6.
74         :type start_ip: string
75         :type end_ip: string
76         :return: Start host, number of hosts.
77         :rtype tuple of int
78         :raises: ValueError if start_ip is greater then end_ip.
79         :raises: socket.error if the IP addresses are not valid IPv6 addresses.
80         """
81
82         try:
83             ip1 = socket.inet_pton(socket.AF_INET6, start_ip)
84             ip2 = socket.inet_pton(socket.AF_INET6, end_ip)
85
86             hi1, lo1 = struct.unpack('!QQ', ip1)
87             hi2, lo2 = struct.unpack('!QQ', ip2)
88
89             if ((hi1 << 64) | lo1) > ((hi2 << 64) | lo2):
90                 raise ValueError("IPv6: start_ip is greater then end_ip")
91
92             return lo1, abs(int(lo1) - int(lo2))
93
94         except socket.error as err:
95             print(err)
96             raise
97
98     def define_packets(self):
99         """Define the packets to be sent from the traffic generator.
100
101         This method MUST return:
102
103             return base_pkt_a, base_pkt_b, vm1, vm2
104
105             vm1 and vm2 CAN be None.
106
107         :returns: Packets to be sent from the traffic generator.
108         :rtype: tuple
109         """
110         raise NotImplementedError
111
112     def create_streams(self):
113         """Create traffic streams.
114
115         Implement your own traffic streams.
116
117         :returns: Traffic streams.
118         :rtype: list
119         """
120
121         base_pkt_a, base_pkt_b, vm1, vm2 = self.define_packets()
122
123         # In most cases you will not have to change the code below:
124
125         # Frame size is defined as an integer, e.g. 64, 1518:
126         if isinstance(self.framesize, int):
127
128             # Create a base packet and pad it to size
129             payload_len = max(0, self.framesize - len(base_pkt_a) - 4)  # No FCS
130
131             # Direction 0 --> 1
132             pkt_a = STLPktBuilder(
133                 pkt=base_pkt_a / self._gen_payload(payload_len),
134                 vm=vm1)
135             # Direction 1 --> 0
136             pkt_b = STLPktBuilder(
137                 pkt=base_pkt_b / self._gen_payload(payload_len),
138                 vm=vm2)
139
140             # Packets for latency measurement:
141             # Direction 0 --> 1
142             pkt_lat_a = STLPktBuilder(
143                 pkt=base_pkt_a / self._gen_payload(payload_len))
144             # Direction 1 --> 0
145             pkt_lat_b = STLPktBuilder(
146                 pkt=base_pkt_b / self._gen_payload(payload_len))
147
148             # Create the streams:
149             # Direction 0 --> 1
150             stream1 = STLStream(packet=pkt_a, mode=STLTXCont(pps=9000))
151             # Direction 1 --> 0
152             # second traffic stream with a phase of 10ns (inter-stream gap)
153             stream2 = STLStream(packet=pkt_b, isg=10.0,
154                                 mode=STLTXCont(pps=9000))
155
156             # Streams for latency measurement:
157             # Direction 0 --> 1
158             lat_stream1 = STLStream(packet=pkt_lat_a,
159                                     flow_stats=STLFlowLatencyStats(pg_id=0),
160                                     mode=STLTXCont(pps=9000))
161             # Direction 1 --> 0
162             # second traffic stream with a phase of 10ns (inter-stream gap)
163             lat_stream2 = STLStream(packet=pkt_lat_b, isg=10.0,
164                                     flow_stats=STLFlowLatencyStats(pg_id=1),
165                                     mode=STLTXCont(pps=9000))
166
167             return [stream1, stream2, lat_stream1, lat_stream2]
168
169         # Frame size is defined as a string, e.g.IMIX_v4_1:
170         elif isinstance(self.framesize, str):
171
172             stream1 = []
173             stream2 = []
174
175             for stream in self.STREAM_TABLE[self.framesize]:
176                 payload_len_a = max(0, stream['size'] - len(base_pkt_a) - 4)
177                 payload_len_b = max(0, stream['size'] - len(base_pkt_b) - 4)
178                 # Create a base packet and pad it to size
179                 pkt_a = STLPktBuilder(
180                     pkt=base_pkt_a / self._gen_payload(payload_len_a),
181                     vm=vm1)
182                 pkt_b = STLPktBuilder(
183                     pkt=base_pkt_b / self._gen_payload(payload_len_b),
184                     vm=vm2)
185
186                 # Create the streams:
187                 stream1.append(STLStream(packet=pkt_a,
188                                          isg=stream['isg'],
189                                          mode=STLTXCont(pps=stream['pps'])))
190                 stream2.append(STLStream(packet=pkt_b,
191                                          isg=stream['isg'],
192                                          mode=STLTXCont(pps=stream['pps'])))
193             streams = list()
194             streams.extend(stream1)
195             streams.extend(stream2)
196
197             return streams
198
199     def get_streams(self, **kwargs):
200         """Get traffic streams created by "create_streams" method.
201
202         If needed, add your own parameters.
203
204         :param kwargs: Key-value pairs used by "create_streams" method while
205         creating streams.
206         :returns: Traffic streams.
207         :rtype: list
208         """
209
210         self.framesize = kwargs['framesize']
211
212         return self.create_streams()