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, 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 def send_rfc2889_forwarding(self, traffic=None, tests=1, _duration=20):
251 Send traffic per RFC2889 Forwarding test specifications.
253 framesize = settings.getValue("TRAFFICGEN_STC_FRAME_SIZE")
254 if traffic and 'l2' in traffic:
255 if 'framesize' in traffic['l2']:
256 framesize = traffic['l2']['framesize']
257 args = get_rfc2889_common_settings(framesize, tests,
258 traffic['traffic_type'])
259 if settings.getValue("TRAFFICGEN_STC_VERBOSE") == "True":
260 args.append("--verbose")
262 self._logger.debug("Arguments used to call test: %s", args)
263 subprocess.check_call(args)
265 filec = os.path.join(settings.getValue("TRAFFICGEN_STC_RESULTS_DIR"),
267 "TRAFFICGEN_STC_CSV_RESULTS_FILE_PREFIX") +
271 self._logger.info("file: %s", filec)
273 return self.get_rfc2889_forwarding_results(filec)
275 def send_rfc2889_caching(self, traffic=None, tests=1, _duration=20):
277 Send as per RFC2889 Addr-Caching test specifications.
279 framesize = settings.getValue("TRAFFICGEN_STC_FRAME_SIZE")
280 if traffic and 'l2' in traffic:
281 if 'framesize' in traffic['l2']:
282 framesize = traffic['l2']['framesize']
283 common_args = get_rfc2889_common_settings(framesize, tests,
284 traffic['traffic_type'])
285 custom_args = get_rfc2889_custom_settings()
286 args = common_args + custom_args
288 if settings.getValue("TRAFFICGEN_STC_VERBOSE") == "True":
289 args.append("--verbose")
291 self._logger.debug("Arguments used to call test: %s", args)
292 subprocess.check_call(args)
294 filec = os.path.join(settings.getValue("TRAFFICGEN_STC_RESULTS_DIR"),
296 "TRAFFICGEN_STC_CSV_RESULTS_FILE_PREFIX") +
300 self._logger.info("file: %s", filec)
302 return self.get_rfc2889_addr_caching_results(filec)
304 def send_rfc2889_learning(self, traffic=None, tests=1, _duration=20):
306 Send traffic per RFC2889 Addr-Learning test specifications.
308 framesize = settings.getValue("TRAFFICGEN_STC_FRAME_SIZE")
309 if traffic and 'l2' in traffic:
310 if 'framesize' in traffic['l2']:
311 framesize = traffic['l2']['framesize']
312 common_args = get_rfc2889_common_settings(framesize, tests,
313 traffic['traffic_type'])
314 custom_args = get_rfc2889_custom_settings()
315 args = common_args + custom_args
317 if settings.getValue("TRAFFICGEN_STC_VERBOSE") == "True":
318 args.append("--verbose")
320 self._logger.debug("Arguments used to call test: %s", args)
321 subprocess.check_call(args)
323 filec = os.path.join(settings.getValue("TRAFFICGEN_STC_RESULTS_DIR"),
325 "TRAFFICGEN_STC_CSV_RESULTS_FILE_PREFIX") +
329 self._logger.info("file: %s", filec)
331 return self.get_rfc2889_addr_learning_results(filec)
333 def get_rfc2544_results(self, filename):
335 Reads the CSV file and return the results
338 with open(filename, "r") as csvfile:
339 csvreader = csv.DictReader(csvfile)
340 for row in csvreader:
341 self._logger.info("Row: %s", row)
342 tx_fps = ((float(row["TxFrameCount"])) /
343 (float(row["Duration(sec)"])))
344 rx_fps = ((float(row["RxFrameCount"])) /
345 (float(row["Duration(sec)"])))
346 tx_mbps = ((float(row["TxFrameCount"]) *
347 float(row["ConfiguredFrameSize"])) /
348 (float(row["Duration(sec)"]) * 1000000.0))
349 rx_mbps = ((float(row["RxFrameCount"]) *
350 float(row["ConfiguredFrameSize"])) /
351 (float(row["Duration(sec)"]) * 1000000.0))
352 result[ResultsConstants.TX_RATE_FPS] = tx_fps
353 result[ResultsConstants.THROUGHPUT_RX_FPS] = rx_fps
354 result[ResultsConstants.TX_RATE_MBPS] = tx_mbps
355 result[ResultsConstants.THROUGHPUT_RX_MBPS] = rx_mbps
356 result[ResultsConstants.TX_RATE_PERCENT] = float(
357 row["OfferedLoad(%)"])
358 result[ResultsConstants.THROUGHPUT_RX_PERCENT] = float(
359 row["Throughput(%)"])
360 result[ResultsConstants.MIN_LATENCY_NS] = float(
361 row["MinimumLatency(us)"]) * 1000
362 result[ResultsConstants.MAX_LATENCY_NS] = float(
363 row["MaximumLatency(us)"]) * 1000
364 result[ResultsConstants.AVG_LATENCY_NS] = float(
365 row["AverageLatency(us)"]) * 1000
366 result[ResultsConstants.FRAME_LOSS_PERCENT] = float(
370 def send_cont_traffic(self, traffic=None, duration=30):
372 Send Custom - Continuous Test traffic
373 Reuse RFC2544 throughput test specifications along with
374 'custom' configuration
378 framesize = settings.getValue("TRAFFICGEN_STC_FRAME_SIZE")
379 if traffic and 'l2' in traffic:
380 if 'framesize' in traffic['l2']:
381 framesize = traffic['l2']['framesize']
383 stc_common_args = get_stc_common_settings()
384 rfc2544_common_args = get_rfc2544_common_settings()
385 rfc2544_custom_args = get_rfc2544_custom_settings(framesize,
387 args = rfc2544_common_args + stc_common_args + rfc2544_custom_args
389 if settings.getValue("TRAFFICGEN_STC_VERBOSE") == "True":
390 args.append("--verbose")
392 self._logger.debug("Arguments used to call test: %s", args)
393 subprocess.check_call(args)
395 filec = os.path.join(settings.getValue("TRAFFICGEN_STC_RESULTS_DIR"),
397 "TRAFFICGEN_STC_CSV_RESULTS_FILE_PREFIX") +
401 self._logger.info("file: %s", filec)
403 return self.get_rfc2544_results(filec)
405 def send_rfc2544_throughput(self, traffic=None, tests=1, duration=20,
408 Send traffic per RFC2544 throughput test specifications.
411 framesize = settings.getValue("TRAFFICGEN_STC_FRAME_SIZE")
412 if traffic and 'l2' in traffic:
413 if 'framesize' in traffic['l2']:
414 framesize = traffic['l2']['framesize']
416 stc_common_args = get_stc_common_settings()
417 rfc2544_common_args = get_rfc2544_common_settings()
418 rfc2544_custom_args = get_rfc2544_custom_settings(framesize, '',
420 args = rfc2544_common_args + stc_common_args + rfc2544_custom_args
422 if settings.getValue("TRAFFICGEN_STC_VERBOSE") == "True":
423 args.append("--verbose")
425 self._logger.debug("Arguments used to call test: %s", args)
426 subprocess.check_call(args)
428 filec = os.path.join(settings.getValue("TRAFFICGEN_STC_RESULTS_DIR"),
430 "TRAFFICGEN_STC_CSV_RESULTS_FILE_PREFIX") +
434 self._logger.info("file: %s", filec)
436 return self.get_rfc2544_results(filec)
438 def send_rfc2544_back2back(self, traffic=None, tests=1, duration=20,
441 Send traffic per RFC2544 BacktoBack test specifications.
444 framesize = settings.getValue("TRAFFICGEN_STC_FRAME_SIZE")
445 if traffic and 'l2' in traffic:
446 if 'framesize' in traffic['l2']:
447 framesize = traffic['l2']['framesize']
449 stc_common_args = get_stc_common_settings()
450 rfc2544_common_args = get_rfc2544_common_settings()
451 rfc2544_custom_args = get_rfc2544_custom_settings(framesize, '',
453 args = rfc2544_common_args + stc_common_args + rfc2544_custom_args
455 if settings.getValue("TRAFFICGEN_STC_VERBOSE") == "True":
456 args.append("--verbose")
458 self._logger.info("Arguments used to call test: %s", args)
459 subprocess.check_call(args)
461 filecs = os.path.join(settings.getValue("TRAFFICGEN_STC_RESULTS_DIR"),
463 "TRAFFICGEN_STC_CSV_RESULTS_FILE_PREFIX") +
466 self._logger.debug("file: %s", filecs)
468 return self.get_rfc2544_results(filecs)
470 def start_cont_traffic(self, traffic=None, duration=30):
471 raise NotImplementedError('TestCenter start_cont_traffic not implement.')
473 def stop_cont_traffic(self):
474 raise NotImplementedError('TestCenter stop_cont_traffic not implement.')
476 def start_rfc2544_back2back(self, traffic=None, tests=1, duration=20,
478 raise NotImplementedError('TestCenter start_rfc2544_back2back not implement.')
480 def wait_rfc2544_back2back(self):
481 raise NotImplementedError('TestCenter wait_rfc2544_back2back not implement.')
483 def start_rfc2544_throughput(self, traffic=None, tests=1, duration=20,
485 raise NotImplementedError('TestCenter start_rfc2544_throughput not implement.')
487 def wait_rfc2544_throughput(self):
488 raise NotImplementedError('TestCenter wait_rfc2544_throughput not implement.')
490 if __name__ == '__main__':
495 'dstip': '90.90.90.90',
498 with TestCenter() as dev:
499 print(dev.send_rfc2544_throughput(traffic=TRAFFIC))
500 # pylint: disable=no-member
501 print(dev.send_rfc2544_backtoback(traffic=TRAFFIC))