2adf6c903d0a96b2ea45f973e1b5c63e29fcb172
[vswitchperf.git] / tools / pkt_gen / testcenter / testcenter.py
1 # Copyright 2016 Spirent Communications.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #   http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 """
16 Code to integrate Spirent TestCenter with the vsperf test framework.
17
18 Provides a model for Spirent TestCenter as a test tool for implementing
19 various performance tests of a virtual switch.
20 """
21
22 import csv
23 import logging
24 import os
25 import subprocess
26
27 from conf import settings
28 from core.results.results_constants import ResultsConstants
29 from tools.pkt_gen import trafficgen
30
31
32 class TestCenter(trafficgen.ITrafficGenerator):
33     """
34     Spirent TestCenter
35     """
36     _logger = logging.getLogger(__name__)
37
38     def connect(self):
39         """
40         Do nothing.
41         """
42         return self
43
44     def disconnect(self):
45         """
46         Do nothing.
47         """
48         pass
49
50     def send_burst_traffic(self, traffic=None, numpkts=100, duration=20):
51         """
52         Do nothing.
53         """
54         return None
55
56     def send_cont_traffic(self, traffic=None, duration=30):
57         """
58         Do nothing.
59         """
60         return None
61
62     def send_rfc2544_throughput(self, traffic=None, trials=3, duration=20,
63                                 lossrate=0.0):
64         """
65         Send traffic per RFC2544 throughput test specifications.
66         """
67         verbose = False
68         framesize = settings.getValue("TRAFFICGEN_STC_FRAME_SIZE")
69         if traffic and 'l2' in traffic:
70             if 'framesize' in traffic['l2']:
71                 framesize = traffic['l2']['framesize']
72         args = [settings.getValue("TRAFFICGEN_STC_PYTHON2_PATH"),
73                 os.path.join(
74                     settings.getValue("TRAFFICGEN_STC_TESTCENTER_PATH"),
75                     settings.getValue(
76                         "TRAFFICGEN_STC_RFC2544_TPUT_TEST_FILE_NAME")),
77                 "--lab_server_addr",
78                 settings.getValue("TRAFFICGEN_STC_LAB_SERVER_ADDR"),
79                 "--license_server_addr",
80                 settings.getValue("TRAFFICGEN_STC_LICENSE_SERVER_ADDR"),
81                 "--east_chassis_addr",
82                 settings.getValue("TRAFFICGEN_STC_EAST_CHASSIS_ADDR"),
83                 "--east_slot_num",
84                 settings.getValue("TRAFFICGEN_STC_EAST_SLOT_NUM"),
85                 "--east_port_num",
86                 settings.getValue("TRAFFICGEN_STC_EAST_PORT_NUM"),
87                 "--west_chassis_addr",
88                 settings.getValue("TRAFFICGEN_STC_WEST_CHASSIS_ADDR"),
89                 "--west_slot_num",
90                 settings.getValue("TRAFFICGEN_STC_WEST_SLOT_NUM"),
91                 "--west_port_num",
92                 settings.getValue("TRAFFICGEN_STC_WEST_PORT_NUM"),
93                 "--test_session_name",
94                 settings.getValue("TRAFFICGEN_STC_TEST_SESSION_NAME"),
95                 "--results_dir",
96                 settings.getValue("TRAFFICGEN_STC_RESULTS_DIR"),
97                 "--csv_results_file_prefix",
98                 settings.getValue("TRAFFICGEN_STC_CSV_RESULTS_FILE_PREFIX"),
99                 "--num_trials",
100                 settings.getValue("TRAFFICGEN_STC_NUMBER_OF_TRIALS"),
101                 "--trial_duration_sec",
102                 settings.getValue("TRAFFICGEN_STC_TRIAL_DURATION_SEC"),
103                 "--traffic_pattern",
104                 settings.getValue("TRAFFICGEN_STC_TRAFFIC_PATTERN"),
105                 "--search_mode",
106                 settings.getValue("TRAFFICGEN_STC_SEARCH_MODE"),
107                 "--learning_mode",
108                 settings.getValue("TRAFFICGEN_STC_LEARNING_MODE"),
109                 "--rate_lower_limit_pct",
110                 settings.getValue("TRAFFICGEN_STC_RATE_LOWER_LIMIT_PCT"),
111                 "--rate_upper_limit_pct",
112                 settings.getValue("TRAFFICGEN_STC_RATE_UPPER_LIMIT_PCT"),
113                 "--rate_initial_pct",
114                 settings.getValue("TRAFFICGEN_STC_RATE_INITIAL_PCT"),
115                 "--rate_step_pct",
116                 settings.getValue("TRAFFICGEN_STC_RATE_STEP_PCT"),
117                 "--resolution_pct",
118                 settings.getValue("TRAFFICGEN_STC_RESOLUTION_PCT"),
119                 "--frame_size_list",
120                 str(framesize),
121                 "--acceptable_frame_loss_pct",
122                 settings.getValue("TRAFFICGEN_STC_ACCEPTABLE_FRAME_LOSS_PCT"),
123                 "--east_intf_addr",
124                 settings.getValue("TRAFFICGEN_STC_EAST_INTF_ADDR"),
125                 "--east_intf_gateway_addr",
126                 settings.getValue("TRAFFICGEN_STC_EAST_INTF_GATEWAY_ADDR"),
127                 "--west_intf_addr",
128                 settings.getValue("TRAFFICGEN_STC_WEST_INTF_ADDR"),
129                 "--west_intf_gateway_addr",
130                 settings.getValue("TRAFFICGEN_STC_WEST_INTF_GATEWAY_ADDR")]
131
132         if settings.getValue("TRAFFICGEN_STC_VERBOSE") is "True":
133             args.append("--verbose")
134             verbose = True
135             self._logger.debug("Arguments used to call test: %s", args)
136         subprocess.check_call(args)
137
138         filec = os.path.join(settings.getValue("TRAFFICGEN_STC_RESULTS_DIR"),
139                              settings.getValue(
140                                  "TRAFFICGEN_STC_CSV_RESULTS_FILE_PREFIX") +
141                              ".csv")
142
143         if verbose:
144             self._logger.info("file: %s", filec)
145
146         result = {}
147
148         with open(filec, "r") as csvfile:
149             csvreader = csv.DictReader(csvfile)
150             for row in csvreader:
151                 self._logger.info("Row: %s", row)
152                 tx_fps = ((float(row["TxFrameCount"])) /
153                           (float(row["Duration(sec)"])))
154                 rx_fps = ((float(row["RxFrameCount"])) /
155                           (float(row["Duration(sec)"])))
156                 tx_mbps = ((float(row["TxFrameCount"]) *
157                             float(row["ConfiguredFrameSize"])) /
158                            (float(row["Duration(sec)"]) * 1000000.0))
159                 rx_mbps = ((float(row["RxFrameCount"]) *
160                             float(row["ConfiguredFrameSize"])) /
161                            (float(row["Duration(sec)"]) * 1000000.0))
162                 result[ResultsConstants.TX_RATE_FPS] = tx_fps
163                 result[ResultsConstants.THROUGHPUT_RX_FPS] = rx_fps
164                 result[ResultsConstants.TX_RATE_MBPS] = tx_mbps
165                 result[ResultsConstants.THROUGHPUT_RX_MBPS] = rx_mbps
166                 result[ResultsConstants.TX_RATE_PERCENT] = float(
167                     row["OfferedLoad(%)"])
168                 result[ResultsConstants.THROUGHPUT_RX_PERCENT] = float(
169                     row["Throughput(%)"])
170                 result[ResultsConstants.MIN_LATENCY_NS] = float(
171                     row["MinimumLatency(us)"]) * 1000
172                 result[ResultsConstants.MAX_LATENCY_NS] = float(
173                     row["MaximumLatency(us)"]) * 1000
174                 result[ResultsConstants.AVG_LATENCY_NS] = float(
175                     row["AverageLatency(us)"]) * 1000
176                 result[ResultsConstants.FRAME_LOSS_PERCENT] = float(
177                     row["PercentLoss"])
178         return result
179
180     def send_rfc2544_back2back(self, traffic=None, trials=1, duration=20,
181                                lossrate=0.0):
182         """
183         Send traffic per RFC2544 BacktoBack test specifications.
184         """
185         verbose = False
186         framesize = settings.getValue("TRAFFICGEN_STC_FRAME_SIZE")
187         if traffic and 'l2' in traffic:
188             if 'framesize' in traffic['l2']:
189                 framesize = traffic['l2']['framesize']
190         args = [settings.getValue("TRAFFICGEN_STC_PYTHON2_PATH"),
191                 os.path.join(
192                     settings.getValue("TRAFFICGEN_STC_TESTCENTER_PATH"),
193                     settings.getValue(
194                         "TRAFFICGEN_STC_RFC2544_B2B_TEST_FILE_NAME")),
195                 "--metric",
196                 settings.getValue("TRAFFICGEN_STC_RFC2544_METRIC"),
197                 "--lab_server_addr",
198                 settings.getValue("TRAFFICGEN_STC_LAB_SERVER_ADDR"),
199                 "--license_server_addr",
200                 settings.getValue("TRAFFICGEN_STC_LICENSE_SERVER_ADDR"),
201                 "--east_chassis_addr",
202                 settings.getValue("TRAFFICGEN_STC_EAST_CHASSIS_ADDR"),
203                 "--east_slot_num",
204                 settings.getValue("TRAFFICGEN_STC_EAST_SLOT_NUM"),
205                 "--east_port_num",
206                 settings.getValue("TRAFFICGEN_STC_EAST_PORT_NUM"),
207                 "--west_chassis_addr",
208                 settings.getValue("TRAFFICGEN_STC_WEST_CHASSIS_ADDR"),
209                 "--west_slot_num",
210                 settings.getValue("TRAFFICGEN_STC_WEST_SLOT_NUM"),
211                 "--west_port_num",
212                 settings.getValue("TRAFFICGEN_STC_WEST_PORT_NUM"),
213                 "--test_session_name",
214                 settings.getValue("TRAFFICGEN_STC_TEST_SESSION_NAME"),
215                 "--results_dir",
216                 settings.getValue("TRAFFICGEN_STC_RESULTS_DIR"),
217                 "--csv_results_file_prefix",
218                 settings.getValue("TRAFFICGEN_STC_CSV_RESULTS_FILE_PREFIX"),
219                 "--num_trials",
220                 settings.getValue("TRAFFICGEN_STC_NUMBER_OF_TRIALS"),
221                 "--trial_duration_sec",
222                 settings.getValue("TRAFFICGEN_STC_TRIAL_DURATION_SEC"),
223                 "--traffic_pattern",
224                 settings.getValue("TRAFFICGEN_STC_TRAFFIC_PATTERN"),
225                 "--search_mode",
226                 settings.getValue("TRAFFICGEN_STC_SEARCH_MODE"),
227                 "--learning_mode",
228                 settings.getValue("TRAFFICGEN_STC_LEARNING_MODE"),
229                 "--latency_type",
230                 settings.getValue("TRAFFICGEN_STC_LATENCY_TYPE"),
231                 "--rate_lower_limit_pct",
232                 settings.getValue("TRAFFICGEN_STC_RATE_LOWER_LIMIT_PCT"),
233                 "--rate_upper_limit_pct",
234                 settings.getValue("TRAFFICGEN_STC_RATE_UPPER_LIMIT_PCT"),
235                 "--rate_initial_pct",
236                 settings.getValue("TRAFFICGEN_STC_RATE_INITIAL_PCT"),
237                 "--rate_step_pct",
238                 settings.getValue("TRAFFICGEN_STC_RATE_STEP_PCT"),
239                 "--resolution_pct",
240                 settings.getValue("TRAFFICGEN_STC_RESOLUTION_PCT"),
241                 "--frame_size_list",
242                 str(framesize),
243                 "--acceptable_frame_loss_pct",
244                 settings.getValue("TRAFFICGEN_STC_ACCEPTABLE_FRAME_LOSS_PCT"),
245                 "--east_intf_addr",
246                 settings.getValue("TRAFFICGEN_STC_EAST_INTF_ADDR"),
247                 "--east_intf_gateway_addr",
248                 settings.getValue("TRAFFICGEN_STC_EAST_INTF_GATEWAY_ADDR"),
249                 "--west_intf_addr",
250                 settings.getValue("TRAFFICGEN_STC_WEST_INTF_ADDR"),
251                 "--west_intf_gateway_addr",
252                 settings.getValue("TRAFFICGEN_STC_WEST_INTF_GATEWAY_ADDR")]
253
254         if settings.getValue("TRAFFICGEN_STC_VERBOSE") is "True":
255             args.append("--verbose")
256             verbose = True
257             self._logger.info("Arguments used to call test: %s", args)
258         subprocess.check_call(args)
259
260         filecs = os.path.join(settings.getValue("TRAFFICGEN_STC_RESULTS_DIR"),
261                               settings.getValue(
262                                   "TRAFFICGEN_STC_CSV_RESULTS_FILE_PREFIX") +
263                               ".csv")
264         if verbose:
265             self._logger.debug("file: %s", filecs)
266
267         result = {}
268
269         with open(filecs, "r") as csvfile:
270             csvreader = csv.DictReader(csvfile)
271             for row in csvreader:
272                 self._logger.info("Row: %s", row)
273                 tx_fps = ((float(row["TxFrameCount"])) /
274                           (float(row["Duration(sec)"])))
275                 rx_fps = ((float(row["RxFrameCount"])) /
276                           (float(row["Duration(sec)"])))
277                 tx_mbps = ((float(row["TxFrameCount"]) *
278                             float(row["ConfiguredFrameSize"])) /
279                            (float(row["Duration(sec)"]) * 1000000.0))
280                 rx_mbps = ((float(row["RxFrameCount"]) *
281                             float(row["ConfiguredFrameSize"])) /
282                            (float(row["Duration(sec)"]) * 1000000.0))
283                 result[ResultsConstants.TX_RATE_FPS] = tx_fps
284                 result[ResultsConstants.THROUGHPUT_RX_FPS] = rx_fps
285                 result[ResultsConstants.TX_RATE_MBPS] = tx_mbps
286                 result[ResultsConstants.THROUGHPUT_RX_MBPS] = rx_mbps
287                 result[ResultsConstants.TX_RATE_PERCENT] = float(
288                     row["OfferedLoad(%)"])
289                 result[ResultsConstants.THROUGHPUT_RX_PERCENT] = float(
290                     row["Throughput(%)"])
291                 result[ResultsConstants.MIN_LATENCY_NS] = float(
292                     row["MinimumLatency(us)"]) * 1000
293                 result[ResultsConstants.MAX_LATENCY_NS] = float(
294                     row["MaximumLatency(us)"]) * 1000
295                 result[ResultsConstants.AVG_LATENCY_NS] = float(
296                     row["AverageLatency(us)"]) * 1000
297                 result[ResultsConstants.FRAME_LOSS_PERCENT] = float(
298                     row["PercentLoss"])
299         return result
300
301 if __name__ == '__main__':
302     TRAFFIC = {
303         'l3': {
304             'proto': 'tcp',
305             'srcip': '1.1.1.1',
306             'dstip': '90.90.90.90',
307         },
308     }
309     with TestCenter() as dev:
310         print(dev.send_rfc2544_throughput(traffic=TRAFFIC))
311         print(dev.send_rfc2544_backtoback(traffic=TRAFFIC))