1 # Copyright 2016 Spirent Communications.
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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.
16 Code to integrate Spirent TestCenter with the vsperf test framework.
18 Provides a model for Spirent TestCenter as a test tool for implementing
19 various performance tests of a virtual switch.
27 from conf import settings
28 from core.results.results_constants import ResultsConstants
29 from tools.pkt_gen import trafficgen
32 def get_stc_common_settings():
34 Return the common Settings
35 These settings would apply to almost all the tests.
37 args = ["--lab_server_addr",
38 settings.getValue("TRAFFICGEN_STC_LAB_SERVER_ADDR"),
39 "--license_server_addr",
40 settings.getValue("TRAFFICGEN_STC_LICENSE_SERVER_ADDR"),
41 "--east_chassis_addr",
42 settings.getValue("TRAFFICGEN_STC_EAST_CHASSIS_ADDR"),
44 settings.getValue("TRAFFICGEN_STC_EAST_SLOT_NUM"),
46 settings.getValue("TRAFFICGEN_STC_EAST_PORT_NUM"),
47 "--west_chassis_addr",
48 settings.getValue("TRAFFICGEN_STC_WEST_CHASSIS_ADDR"),
50 settings.getValue("TRAFFICGEN_STC_WEST_SLOT_NUM"),
52 settings.getValue("TRAFFICGEN_STC_WEST_PORT_NUM"),
53 "--test_session_name",
54 settings.getValue("TRAFFICGEN_STC_TEST_SESSION_NAME"),
56 settings.getValue("TRAFFICGEN_STC_RESULTS_DIR"),
57 "--csv_results_file_prefix",
58 settings.getValue("TRAFFICGEN_STC_CSV_RESULTS_FILE_PREFIX")]
62 def get_rfc2544_common_settings():
64 Retrun Generic RFC 2544 settings.
65 These settings apply to all the 2544 tests
67 args = [settings.getValue("TRAFFICGEN_STC_PYTHON2_PATH"),
69 settings.getValue("TRAFFICGEN_STC_TESTCENTER_PATH"),
71 "TRAFFICGEN_STC_RFC2544_TPUT_TEST_FILE_NAME")),
73 settings.getValue("TRAFFICGEN_STC_RFC2544_METRIC"),
75 settings.getValue("TRAFFICGEN_STC_SEARCH_MODE"),
77 settings.getValue("TRAFFICGEN_STC_LEARNING_MODE"),
78 "--rate_lower_limit_pct",
79 settings.getValue("TRAFFICGEN_STC_RATE_LOWER_LIMIT_PCT"),
80 "--rate_upper_limit_pct",
81 settings.getValue("TRAFFICGEN_STC_RATE_UPPER_LIMIT_PCT"),
83 settings.getValue("TRAFFICGEN_STC_RATE_INITIAL_PCT"),
85 settings.getValue("TRAFFICGEN_STC_RATE_STEP_PCT"),
87 settings.getValue("TRAFFICGEN_STC_RESOLUTION_PCT"),
88 "--acceptable_frame_loss_pct",
89 settings.getValue("TRAFFICGEN_STC_ACCEPTABLE_FRAME_LOSS_PCT"),
91 settings.getValue("TRAFFICGEN_STC_EAST_INTF_ADDR"),
92 "--east_intf_gateway_addr",
93 settings.getValue("TRAFFICGEN_STC_EAST_INTF_GATEWAY_ADDR"),
95 settings.getValue("TRAFFICGEN_STC_WEST_INTF_ADDR"),
96 "--west_intf_gateway_addr",
97 settings.getValue("TRAFFICGEN_STC_WEST_INTF_GATEWAY_ADDR"),
98 "--trial_duration_sec",
99 settings.getValue("TRAFFICGEN_STC_TRIAL_DURATION_SEC"),
101 settings.getValue("TRAFFICGEN_STC_TRAFFIC_PATTERN")]
105 def get_rfc2544_custom_settings(framesize, custom_tr, tests):
107 Return RFC2544 Custom Settings
109 args = ["--frame_size_list",
118 def get_rfc2889_common_settings(framesize, tests, metric):
120 Return RFC2889 common Settings
122 new_metric = metric.replace('rfc2889_', '')
123 args = [settings.getValue("TRAFFICGEN_STC_PYTHON2_PATH"),
125 settings.getValue("TRAFFICGEN_STC_TESTCENTER_PATH"),
127 "TRAFFICGEN_STC_RFC2889_TEST_FILE_NAME")),
129 settings.getValue("TRAFFICGEN_STC_LAB_SERVER_ADDR"),
130 "--license_server_addr",
131 settings.getValue("TRAFFICGEN_STC_LICENSE_SERVER_ADDR"),
133 settings.getValue("TRAFFICGEN_STC_RFC2889_LOCATIONS"),
134 "--test_session_name",
135 settings.getValue("TRAFFICGEN_STC_TEST_SESSION_NAME"),
137 settings.getValue("TRAFFICGEN_STC_RESULTS_DIR"),
138 "--csv_results_file_prefix",
139 settings.getValue("TRAFFICGEN_STC_CSV_RESULTS_FILE_PREFIX"),
150 def get_rfc2889_custom_settings():
152 Return RFC2889 Custom Settings
154 args = ["--min_learning_rate",
155 settings.getValue("TRAFFICGEN_STC_RFC2889_MIN_LR"),
156 "--max_learning_rate",
157 settings.getValue("TRAFFICGEN_STC_RFC2889_MAX_LR"),
159 settings.getValue("TRAFFICGEN_STC_RFC2889_MIN_ADDRS"),
161 settings.getValue("TRAFFICGEN_STC_RFC2889_MAX_ADDRS"),
162 "--ac_learning_rate",
163 settings.getValue("TRAFFICGEN_STC_RFC2889_AC_LR")]
167 class TestCenter(trafficgen.ITrafficGenerator):
171 _logger = logging.getLogger(__name__)
179 def disconnect(self):
185 def send_burst_traffic(self, traffic=None, numpkts=100, duration=20):
191 def get_rfc2889_addr_learning_results(self, filename):
193 Reads the CSV file and return the results
196 with open(filename, "r") as csvfile:
197 csvreader = csv.DictReader(csvfile)
198 for row in csvreader:
199 self._logger.info("Row: %s", row)
200 learn_rate = float(row["OptimalLearningRate"])
201 result[ResultsConstants.OPTIMAL_LEARNING_RATE_FPS] = learn_rate
204 def get_rfc2889_addr_caching_results(self, filename):
206 Reads the CSV file and return the results
209 with open(filename, "r") as csvfile:
210 csvreader = csv.DictReader(csvfile)
211 for row in csvreader:
212 self._logger.info("Row: %s", row)
213 caching_cap = float(row["RxFrameCount"])
214 learn_per = (100.0 - (float(row["PercentFrameLoss(%)"])))
215 result[ResultsConstants.CACHING_CAPACITY_ADDRS] = caching_cap
216 result[ResultsConstants.ADDR_LEARNED_PERCENT] = learn_per
219 def get_rfc2889_forwarding_results(self, filename):
221 Reads the CSV file and return the results
224 with open(filename, "r") as csvfile:
225 csvreader = csv.DictReader(csvfile)
226 for row in csvreader:
227 self._logger.info("Row: %s", row)
228 duration = int((float(row["TxSignatureFrameCount"])) /
229 (float(row["OfferedLoad(fps)"])))
230 tx_fps = (float(row["OfferedLoad(fps)"]))
231 rx_fps = float((float(row["RxFrameCount"])) /
233 tx_mbps = ((tx_fps * float(row["FrameSize"])) /
235 rx_mbps = ((rx_fps * float(row["FrameSize"])) /
237 result[ResultsConstants.TX_RATE_FPS] = tx_fps
238 result[ResultsConstants.THROUGHPUT_RX_FPS] = rx_fps
239 result[ResultsConstants.TX_RATE_MBPS] = tx_mbps
240 result[ResultsConstants.THROUGHPUT_RX_MBPS] = rx_mbps
241 result[ResultsConstants.TX_RATE_PERCENT] = float(
242 row["OfferedLoad(%)"])
243 result[ResultsConstants.FRAME_LOSS_PERCENT] = float(
244 row["PercentFrameLoss(%)"])
245 result[ResultsConstants.FORWARDING_RATE_FPS] = float(
246 row["ForwardingRate(fps)"])
249 # pylint: disable=unused-argument
250 def send_rfc2889_forwarding(self, traffic=None, tests=1, duration=20):
252 Send traffic per RFC2889 Forwarding test specifications.
254 framesize = settings.getValue("TRAFFICGEN_STC_FRAME_SIZE")
255 if traffic and 'l2' in traffic:
256 if 'framesize' in traffic['l2']:
257 framesize = traffic['l2']['framesize']
258 args = get_rfc2889_common_settings(framesize, tests,
259 traffic['traffic_type'])
260 if settings.getValue("TRAFFICGEN_STC_VERBOSE") is "True":
261 args.append("--verbose")
263 self._logger.debug("Arguments used to call test: %s", args)
264 subprocess.check_call(args)
266 filec = os.path.join(settings.getValue("TRAFFICGEN_STC_RESULTS_DIR"),
268 "TRAFFICGEN_STC_CSV_RESULTS_FILE_PREFIX") +
272 self._logger.info("file: %s", filec)
274 return self.get_rfc2889_forwarding_results(filec)
276 def send_rfc2889_caching(self, traffic=None, tests=1, duration=20):
278 Send as per RFC2889 Addr-Caching test specifications.
280 framesize = settings.getValue("TRAFFICGEN_STC_FRAME_SIZE")
281 if traffic and 'l2' in traffic:
282 if 'framesize' in traffic['l2']:
283 framesize = traffic['l2']['framesize']
284 common_args = get_rfc2889_common_settings(framesize, tests,
285 traffic['traffic_type'])
286 custom_args = get_rfc2889_custom_settings()
287 args = common_args + custom_args
289 if settings.getValue("TRAFFICGEN_STC_VERBOSE") is "True":
290 args.append("--verbose")
292 self._logger.debug("Arguments used to call test: %s", args)
293 subprocess.check_call(args)
295 filec = os.path.join(settings.getValue("TRAFFICGEN_STC_RESULTS_DIR"),
297 "TRAFFICGEN_STC_CSV_RESULTS_FILE_PREFIX") +
301 self._logger.info("file: %s", filec)
303 return self.get_rfc2889_addr_caching_results(filec)
305 def send_rfc2889_learning(self, traffic=None, tests=1, duration=20):
307 Send traffic per RFC2889 Addr-Learning test specifications.
309 framesize = settings.getValue("TRAFFICGEN_STC_FRAME_SIZE")
310 if traffic and 'l2' in traffic:
311 if 'framesize' in traffic['l2']:
312 framesize = traffic['l2']['framesize']
313 common_args = get_rfc2889_common_settings(framesize, tests,
314 traffic['traffic_type'])
315 custom_args = get_rfc2889_custom_settings()
316 args = common_args + custom_args
318 if settings.getValue("TRAFFICGEN_STC_VERBOSE") is "True":
319 args.append("--verbose")
321 self._logger.debug("Arguments used to call test: %s", args)
322 subprocess.check_call(args)
324 filec = os.path.join(settings.getValue("TRAFFICGEN_STC_RESULTS_DIR"),
326 "TRAFFICGEN_STC_CSV_RESULTS_FILE_PREFIX") +
330 self._logger.info("file: %s", filec)
332 return self.get_rfc2889_addr_learning_results(filec)
334 def get_rfc2544_results(self, filename):
336 Reads the CSV file and return the results
339 with open(filename, "r") as csvfile:
340 csvreader = csv.DictReader(csvfile)
341 for row in csvreader:
342 self._logger.info("Row: %s", row)
343 tx_fps = ((float(row["TxFrameCount"])) /
344 (float(row["Duration(sec)"])))
345 rx_fps = ((float(row["RxFrameCount"])) /
346 (float(row["Duration(sec)"])))
347 tx_mbps = ((float(row["TxFrameCount"]) *
348 float(row["ConfiguredFrameSize"])) /
349 (float(row["Duration(sec)"]) * 1000000.0))
350 rx_mbps = ((float(row["RxFrameCount"]) *
351 float(row["ConfiguredFrameSize"])) /
352 (float(row["Duration(sec)"]) * 1000000.0))
353 result[ResultsConstants.TX_RATE_FPS] = tx_fps
354 result[ResultsConstants.THROUGHPUT_RX_FPS] = rx_fps
355 result[ResultsConstants.TX_RATE_MBPS] = tx_mbps
356 result[ResultsConstants.THROUGHPUT_RX_MBPS] = rx_mbps
357 result[ResultsConstants.TX_RATE_PERCENT] = float(
358 row["OfferedLoad(%)"])
359 result[ResultsConstants.THROUGHPUT_RX_PERCENT] = float(
360 row["Throughput(%)"])
361 result[ResultsConstants.MIN_LATENCY_NS] = float(
362 row["MinimumLatency(us)"]) * 1000
363 result[ResultsConstants.MAX_LATENCY_NS] = float(
364 row["MaximumLatency(us)"]) * 1000
365 result[ResultsConstants.AVG_LATENCY_NS] = float(
366 row["AverageLatency(us)"]) * 1000
367 result[ResultsConstants.FRAME_LOSS_PERCENT] = float(
371 def send_cont_traffic(self, traffic=None, duration=30):
373 Send Custom - Continuous Test traffic
374 Reuse RFC2544 throughput test specifications along with
375 'custom' configuration
379 framesize = settings.getValue("TRAFFICGEN_STC_FRAME_SIZE")
380 if traffic and 'l2' in traffic:
381 if 'framesize' in traffic['l2']:
382 framesize = traffic['l2']['framesize']
384 stc_common_args = get_stc_common_settings()
385 rfc2544_common_args = get_rfc2544_common_settings()
386 rfc2544_custom_args = get_rfc2544_custom_settings(framesize,
388 args = stc_common_args + rfc2544_common_args + rfc2544_custom_args
390 if settings.getValue("TRAFFICGEN_STC_VERBOSE") is "True":
391 args.append("--verbose")
393 self._logger.debug("Arguments used to call test: %s", args)
394 subprocess.check_call(args)
396 filec = os.path.join(settings.getValue("TRAFFICGEN_STC_RESULTS_DIR"),
398 "TRAFFICGEN_STC_CSV_RESULTS_FILE_PREFIX") +
402 self._logger.info("file: %s", filec)
404 return self.get_rfc2544_results(filec)
406 def send_rfc2544_throughput(self, traffic=None, tests=1, duration=20,
409 Send traffic per RFC2544 throughput test specifications.
412 framesize = settings.getValue("TRAFFICGEN_STC_FRAME_SIZE")
413 if traffic and 'l2' in traffic:
414 if 'framesize' in traffic['l2']:
415 framesize = traffic['l2']['framesize']
417 stc_common_args = get_stc_common_settings()
418 rfc2544_common_args = get_rfc2544_common_settings()
419 rfc2544_custom_args = get_rfc2544_custom_settings(framesize, '',
421 args = stc_common_args + rfc2544_common_args + rfc2544_custom_args
423 if settings.getValue("TRAFFICGEN_STC_VERBOSE") is "True":
424 args.append("--verbose")
426 self._logger.debug("Arguments used to call test: %s", args)
427 subprocess.check_call(args)
429 filec = os.path.join(settings.getValue("TRAFFICGEN_STC_RESULTS_DIR"),
431 "TRAFFICGEN_STC_CSV_RESULTS_FILE_PREFIX") +
435 self._logger.info("file: %s", filec)
437 return self.get_rfc2544_results(filec)
439 def send_rfc2544_back2back(self, traffic=None, tests=1, duration=20,
442 Send traffic per RFC2544 BacktoBack test specifications.
445 framesize = settings.getValue("TRAFFICGEN_STC_FRAME_SIZE")
446 if traffic and 'l2' in traffic:
447 if 'framesize' in traffic['l2']:
448 framesize = traffic['l2']['framesize']
450 stc_common_args = get_stc_common_settings()
451 rfc2544_common_args = get_rfc2544_common_settings()
452 rfc2544_custom_args = get_rfc2544_custom_settings(framesize, '',
454 args = stc_common_args + rfc2544_common_args + rfc2544_custom_args
456 if settings.getValue("TRAFFICGEN_STC_VERBOSE") is "True":
457 args.append("--verbose")
459 self._logger.info("Arguments used to call test: %s", args)
460 subprocess.check_call(args)
462 filecs = os.path.join(settings.getValue("TRAFFICGEN_STC_RESULTS_DIR"),
464 "TRAFFICGEN_STC_CSV_RESULTS_FILE_PREFIX") +
467 self._logger.debug("file: %s", filecs)
469 return self.get_rfc2544_results(filecs)
471 def start_cont_traffic(self, traffic=None, duration=30):
472 raise NotImplementedError('TestCenter start_cont_traffic not implement.')
474 def stop_cont_traffic(self):
475 raise NotImplementedError('TestCenter stop_cont_traffic not implement.')
477 def start_rfc2544_back2back(self, traffic=None, tests=1, duration=20,
479 raise NotImplementedError('TestCenter start_rfc2544_back2back not implement.')
481 def wait_rfc2544_back2back(self):
482 raise NotImplementedError('TestCenter wait_rfc2544_back2back not implement.')
484 def start_rfc2544_throughput(self, traffic=None, tests=1, duration=20,
486 raise NotImplementedError('TestCenter start_rfc2544_throughput not implement.')
488 def wait_rfc2544_throughput(self):
489 raise NotImplementedError('TestCenter wait_rfc2544_throughput not implement.')
491 if __name__ == '__main__':
496 'dstip': '90.90.90.90',
499 with TestCenter() as dev:
500 print(dev.send_rfc2544_throughput(traffic=TRAFFIC))
501 print(dev.send_rfc2544_backtoback(traffic=TRAFFIC))