1 # Copyright 2016-2017 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.
15 # Invalid name of file, must be used '_' instead '-'
16 # pylint: disable=invalid-name
18 @author Spirent Communications
20 This test automates the RFC2544 tests using the Spirent
21 TestCenter REST APIs. This test supports Python 3.4
31 _LOGGER = logging.getLogger(__name__)
33 GENOME_PKTSIZE_ENCODING = {"a": 64, "b": 128, "c": 256, "d": 512,
34 "e": 1024, "f": 1280, "g": 1518, "h": 2112}
37 def genome2weights(sequence):
38 """ Convert genome sequence to packetsize weights"""
39 weights = collections.defaultdict(int)
40 for char in GENOME_PKTSIZE_ENCODING:
41 charcount = sequence.count(char)
43 weights[GENOME_PKTSIZE_ENCODING[char]] = charcount
48 """Create the directory as specified in path """
49 if not os.path.exists(path):
53 _LOGGER.error("Failed to create directory %s: %s", path, str(ex))
57 def write_histogram_to_csv(results_path, csv_results_file_prefix,
59 """ Write the results of the query to the CSV """
60 filec = os.path.join(results_path, csv_results_file_prefix + ".csv")
61 with open(filec, "wb") as result_file:
63 result_file.write(str(key) + "\n")
64 result_file.write(str(ranges) + "\n")
65 result_file.write(str(counts[key]) + "\n")
68 def write_query_results_to_csv(results_path, csv_results_file_prefix,
70 """ Write the results of the query to the CSV """
71 create_dir(results_path)
72 filec = os.path.join(results_path, csv_results_file_prefix + ".csv")
73 with open(filec, "wb") as result_file:
74 result_file.write(query_results["Columns"].replace(" ", ",") + "\n")
75 for row in (query_results["Output"].replace("} {", ",").
76 replace("{", "").replace("}", "").split(",")):
77 result_file.write(row.replace(" ", ",") + "\n")
80 def write_headers(results_path, file_name, rx_tx):
81 """ Write headers for the live-results files """
82 filec = os.path.join(results_path, file_name + rx_tx)
83 with open(filec, "a") as result_file:
85 result_file.write('Time,RxPrt,DrpFrCnt,SeqRnLen,AvgLat,' +
86 'DrpFrRate,FrCnt,FrRate,MaxLat,MinLat,' +
89 result_file.write('Time,StrId,BlkId,FrCnt,FrRate,ERxFrCnt,' +
90 'OctCnt,OctRate,bitCnt,bitRate\n')
93 def write_rx_live_results_to_file(results_path, file_name, results):
94 """ Write live results from the rx-ports"""
95 filec = os.path.join(results_path, file_name + ".rx")
96 with open(filec, "a") as result_file:
97 result_file.write('{0},{3},{1},{2},{4},{5},{6},{7},{8},{9},{10},{11}\n'
98 .format(time.time(), results['DroppedFrameCount'],
99 results['SeqRunLength'], results['RxPort'],
100 results['AvgLatency'],
101 results['DroppedFrameRate'],
102 results['FrameCount'], results['FrameRate'],
103 results['MaxLatency'], results['MinLatency'],
104 results['OctetCount'], results['OctetRate']))
107 def write_tx_live_results_to_file(results_path, file_name, results):
108 """ Write live results from the tx-ports"""
109 filec = os.path.join(results_path, file_name + ".tx")
110 with open(filec, "a") as result_file:
111 result_file.write('{0},{1},{9},{2},{3},{4},{5},{6},{7},{8}\n'
112 .format(time.time(), results['StreamId'],
113 results['FrameCount'], results['FrameRate'],
114 results['ExpectedRxFrameCount'],
115 results['OctetCount'], results['OctetRate'],
116 results['BitCount'], results['BitRate'],
120 def positive_int(value):
121 """ Positive Integer type for Arguments """
124 raise argparse.ArgumentTypeError(
125 "%s is an invalid positive int value" % value)
129 def percent_float(value):
130 """ Floating type for Arguments """
131 pvalue = float(value)
132 if pvalue < 0.0 or pvalue > 100.0:
133 raise argparse.ArgumentTypeError(
134 "%s not in range [0.0, 100.0]" % pvalue)
138 # pylint: disable=too-many-branches, too-many-statements, too-many-locals
140 """ Read the arguments, Invoke Test and Return the results"""
141 parser = argparse.ArgumentParser()
142 # Required parameters
143 required_named = parser.add_argument_group("required named arguments")
144 required_named.add_argument("--lab_server_addr",
146 help=("The IP address of the"
147 "Spirent Lab Server"),
148 dest="lab_server_addr")
149 required_named.add_argument("--license_server_addr",
151 help=("The IP address of the Spirent"
153 dest="license_server_addr")
154 required_named.add_argument("--east_chassis_addr",
156 help=("The TestCenter chassis IP address to"
157 "use for the east test port"),
158 dest="east_chassis_addr")
159 required_named.add_argument("--east_slot_num",
162 help=("The TestCenter slot number to"
163 "use for the east test port"),
164 dest="east_slot_num")
165 required_named.add_argument("--east_port_num",
168 help=("The TestCenter port number to use"
169 "for the east test port"),
170 dest="east_port_num")
171 required_named.add_argument("--west_chassis_addr",
173 help=("The TestCenter chassis IP address"
174 "to use for the west test port"),
175 dest="west_chassis_addr")
176 required_named.add_argument("--west_slot_num",
179 help=("The TestCenter slot number to use"
180 "for the west test port"),
181 dest="west_slot_num")
182 required_named.add_argument("--west_port_num",
185 help=("The TestCenter port number to"
186 "use for the west test port"),
187 dest="west_port_num")
188 # Optional parameters
189 optional_named = parser.add_argument_group("optional named arguments")
190 optional_named.add_argument("--metric",
192 help=("One among - throughput, latency,\
193 backtoback and frameloss"),
194 choices=["throughput", "latency",
195 "backtoback", "frameloss"],
196 default="throughput",
198 optional_named.add_argument("--test_session_name",
200 default="RFC2544 East-West Throughput",
201 help=("The friendly name to identify"
202 "the Spirent Lab Server test session"),
203 dest="test_session_name")
205 optional_named.add_argument("--test_user_name",
207 default="RFC2544 East-West User",
208 help=("The friendly name to identify the"
209 "Spirent Lab Server test user"),
210 dest="test_user_name")
211 optional_named.add_argument("--results_dir",
214 help="The directory to copy results to",
216 optional_named.add_argument("--vsperf_results_dir",
219 help="The directory to copy results to",
220 dest="vsperf_results_dir")
221 optional_named.add_argument("--csv_results_file_prefix",
223 default="Rfc2544Tput",
224 help="The prefix for the CSV results files",
225 dest="csv_results_file_prefix")
226 optional_named.add_argument("--num_trials",
230 help=("The number of trials to execute during"
233 optional_named.add_argument("--trial_duration_sec",
237 help=("The duration of each trial executed"
239 dest="trial_duration_sec")
240 optional_named.add_argument("--traffic_pattern",
242 choices=["BACKBONE", "MESH", "PAIR"],
244 help="The traffic pattern between endpoints",
245 dest="traffic_pattern")
246 optional_named.add_argument("--traffic_custom",
249 help="The traffic pattern between endpoints",
250 dest="traffic_custom")
251 optional_named.add_argument("--search_mode",
253 choices=["COMBO", "STEP", "BINARY"],
255 help=("The search mode used to find the"
258 optional_named.add_argument("--learning_mode",
260 choices=["AUTO", "L2_LEARNING",
261 "L3_LEARNING", "NONE"],
263 help=("The learning mode used during the test,"
264 "default is 'NONE'"),
265 dest="learning_mode")
266 optional_named.add_argument("--rate_lower_limit_pct",
270 help=("The minimum percent line rate that"
271 "will be used during the test"),
272 dest="rate_lower_limit_pct")
273 optional_named.add_argument("--rate_upper_limit_pct",
277 help=("The maximum percent line rate that"
278 "will be used during the test"),
279 dest="rate_upper_limit_pct")
280 optional_named.add_argument("--rate_initial_pct",
284 help=("If Search Mode is BINARY, the percent"
285 "line rate that will be used at the"
286 "start of the test"),
287 dest="rate_initial_pct")
288 optional_named.add_argument("--rate_step_pct",
292 help=("If SearchMode is STEP, the percent"
293 "load increase per step"),
294 dest="rate_step_pct")
295 optional_named.add_argument("--resolution_pct",
299 help=("The minimum percentage of load"
300 "adjustment between iterations"),
301 dest="resolution_pct")
302 optional_named.add_argument("--frame_size_list",
303 type=lambda s: [int(item)
304 for item in s.split(',')],
307 help="A comma-delimited list of frame sizes",
308 dest="frame_size_list")
309 optional_named.add_argument("--acceptable_frame_loss_pct",
313 help=("The maximum acceptable frame loss"
314 "percent in any iteration"),
315 dest="acceptable_frame_loss_pct")
316 optional_named.add_argument("--east_intf_addr",
318 default="192.85.1.3",
319 help=("The address to assign to the first"
320 "emulated device interface on the first"
322 dest="east_intf_addr")
323 optional_named.add_argument("--east_intf_gateway_addr",
325 default="192.85.1.53",
326 help=("The gateway address to assign to the"
327 "first emulated device interface on the"
329 dest="east_intf_gateway_addr")
330 optional_named.add_argument("--west_intf_addr",
332 default="192.85.1.53",
333 help=("The address to assign to the first"
334 "emulated device interface on the"
336 dest="west_intf_addr")
337 optional_named.add_argument("--west_intf_gateway_addr",
339 default="192.85.1.53",
340 help=("The gateway address to assign to"
341 "the first emulated device interface"
342 "on the first west port"),
343 dest="west_intf_gateway_addr")
344 optional_named.add_argument("--latency_histogram",
347 help="latency histogram is required in output?",
348 dest="latency_histogram")
349 optional_named.add_argument("--imix",
352 help=("IMIX specification as genome"
353 "Encoding - RFC 6985"),
355 optional_named.add_argument("--live_results",
358 help="Live Results required?",
360 optional_named.add_argument("--logfile",
362 default="./traffic_gen.log",
363 help="Log file to log live results",
365 parser.add_argument("-v",
369 help="More output during operation when present",
372 args = parser.parse_args()
375 _LOGGER.debug("Creating results directory")
376 create_dir(args.results_dir)
378 session_name = args.test_session_name
379 user_name = args.test_user_name
380 # pylint: disable=import-error
382 # Load Spirent REST Library
383 from stcrestclient import stchttp
385 stc = stchttp.StcHttp(args.lab_server_addr)
386 session_id = stc.new_session(user_name, session_name)
387 stc.join_session(session_id)
388 except RuntimeError as err:
392 # Get STC system info.
393 tx_port_loc = "//%s/%s/%s" % (args.east_chassis_addr,
396 rx_port_loc = "//%s/%s/%s" % (args.west_chassis_addr,
400 # Retrieve and display the server information
402 _LOGGER.debug("SpirentTestCenter system version: %s",
403 stc.get("system1", "version"))
405 # pylint: disable=too-many-nested-blocks
410 _LOGGER.debug("Bring up license server")
411 license_mgr = stc.get("system1", "children-licenseservermanager")
413 _LOGGER.debug("license_mgr = %s", license_mgr)
414 stc.create("LicenseServer", under=license_mgr, attributes={
415 "server": args.license_server_addr})
417 # Create the root project object
419 _LOGGER.debug("Creating project ...")
420 project = stc.get("System1", "children-Project")
422 # Configure the Result view
423 resultopts = stc.get('project1', 'children-resultoptions')
424 stc.config(resultopts, {'ResultViewMode': 'BASIC'})
426 # Configure any custom traffic parameters
427 if args.traffic_custom == "cont":
429 _LOGGER.debug("Configure Continuous Traffic")
430 stc.create("ContinuousTestConfig", under=project)
434 _LOGGER.debug("Creating ports ...")
435 east_chassis_port = stc.create('port', project)
437 _LOGGER.debug("Configuring TX port ...")
438 stc.config(east_chassis_port, {'location': tx_port_loc})
439 port_list.append(east_chassis_port)
441 west_chassis_port = stc.create('port', project)
443 _LOGGER.debug("Configuring RX port ...")
444 stc.config(west_chassis_port, {'location': rx_port_loc})
445 port_list.append(west_chassis_port)
447 # Create emulated genparam for east port
448 east_device_gen_params = stc.create("EmulatedDeviceGenParams",
452 # Create the DeviceGenEthIIIfParams object
453 stc.create("DeviceGenEthIIIfParams",
454 under=east_device_gen_params,
455 attributes={'UseDefaultPhyMac': True})
457 # Configuring Ipv4 interfaces
458 stc.create("DeviceGenIpv4IfParams",
459 under=east_device_gen_params,
460 attributes={"Addr": args.east_intf_addr,
461 "Gateway": args.east_intf_gateway_addr})
462 # Create Devices using the Device Wizard
463 device_gen_config = stc.perform("DeviceGenConfigExpand",
464 params={"DeleteExisting": "No",
466 east_device_gen_params})
467 # Append to the device list
468 device_list.append(device_gen_config['ReturnList'])
470 # Create emulated genparam for west port
471 west_device_gen_params = stc.create("EmulatedDeviceGenParams",
475 # Create the DeviceGenEthIIIfParams object
476 stc.create("DeviceGenEthIIIfParams",
477 under=west_device_gen_params,
478 attributes={'UseDefaultPhyMac': True})
480 # Configuring Ipv4 interfaces
481 stc.create("DeviceGenIpv4IfParams",
482 under=west_device_gen_params,
483 attributes={"Addr": args.west_intf_addr,
484 "Gateway": args.west_intf_gateway_addr})
485 # Create Devices using the Device Wizard
486 device_gen_config = stc.perform("DeviceGenConfigExpand",
487 params={"DeleteExisting": "No",
489 west_device_gen_params})
490 # Append to the device list
491 device_list.append(device_gen_config['ReturnList'])
493 _LOGGER.debug(device_list)
495 # Configure Histogram
496 if args.latency_histogram:
497 # Generic Configuration
498 histResOptions = stc.get("project1", 'children-ResultOptions')
499 stc.config(histResOptions, {'ResultViewMode': 'HISTOGRAM'})
500 # East Port Configuration
501 histAnaEast = stc.get(east_chassis_port, 'children-Analyzer')
502 histAnaEastConfig = stc.get(histAnaEast, 'children-AnalyzerConfig')
503 stc.config(histAnaEastConfig, {'HistogramMode': 'LATENCY'})
504 eLatHist = stc.get(histAnaEastConfig, 'children-LatencyHistogram')
505 stc.config(eLatHist, {'ConfigMode': 'CONFIG_LIMIT_MODE',
506 'BucketSizeUnit': 'ten_nanoseconds',
508 'DistributionMode': 'CENTERED_MODE'})
509 # West Port Configuration
510 histAnaWest = stc.get(west_chassis_port, 'children-Analyzer')
511 histAnaWestConfig = stc.get(histAnaWest, 'children-AnalyzerConfig')
512 stc.config(histAnaWestConfig, {'HistogramMode': 'LATENCY'})
513 wLatHist = stc.get(histAnaWestConfig, 'children-LatencyHistogram')
514 stc.config(wLatHist, {'ConfigMode': 'CONFIG_LIMIT_MODE',
515 'BucketSizeUnit': 'ten_nanoseconds',
517 'DistributionMode': 'CENTERED_MODE'})
518 gBucketSizeList = stc.get(wLatHist, 'BucketSizeList')
519 # gLimitSizeList = stc.get(wLatHist, 'LimitList')
524 args.frame_size_list = []
525 weights = genome2weights(args.imix)
526 fld = stc.create('FrameLengthDistribution', under=project)
527 def_slots = stc.get(fld, "children-framelengthdistributionslot")
528 stc.perform("Delete", params={"ConfigList": def_slots})
529 for fsize in weights:
530 stc.create('framelengthdistributionslot', under=fld,
531 attributes={'FixedFrameLength': fsize,
532 'Weight': weights[fsize]})
534 # Create the RFC 2544 'metric test
535 if args.metric == "throughput":
537 _LOGGER.debug("Set up the RFC2544 throughput test...")
538 stc.perform("Rfc2544SetupThroughputTestCommand",
539 params={"AcceptableFrameLoss":
540 args.acceptable_frame_loss_pct,
541 "Duration": args.trial_duration_sec,
542 "FrameSizeList": args.frame_size_list,
543 "LearningMode": args.learning_mode,
544 "NumOfTrials": args.num_trials,
545 "RateInitial": args.rate_initial_pct,
546 "RateLowerLimit": args.rate_lower_limit_pct,
547 "RateStep": args.rate_step_pct,
548 "RateUpperLimit": args.rate_upper_limit_pct,
549 "Resolution": args.resolution_pct,
550 "SearchMode": args.search_mode,
551 "TrafficPattern": args.traffic_pattern,
552 "FrameSizeDistributionList": fld})
553 elif args.metric == "backtoback":
554 stc.perform("Rfc2544SetupBackToBackTestCommand",
555 params={"AcceptableFrameLoss":
556 args.acceptable_frame_loss_pct,
557 "Duration": args.trial_duration_sec,
558 "FrameSizeList": args.frame_size_list,
559 "LearningMode": args.learning_mode,
560 "LatencyType": args.latency_type,
561 "NumOfTrials": args.num_trials,
562 "RateInitial": args.rate_initial_pct,
563 "RateLowerLimit": args.rate_lower_limit_pct,
564 "RateStep": args.rate_step_pct,
565 "RateUpperLimit": args.rate_upper_limit_pct,
566 "Resolution": args.resolution_pct,
567 "SearchMode": args.search_mode,
568 "TrafficPattern": args.traffic_pattern})
569 elif args.metric == "frameloss":
570 stc.perform("Rfc2544SetupFrameLossTestCommand",
571 params={"AcceptableFrameLoss":
572 args.acceptable_frame_loss_pct,
573 "Duration": args.trial_duration_sec,
574 "FrameSizeList": args.frame_size_list,
575 "LearningMode": args.learning_mode,
576 "LatencyType": args.latency_type,
577 "NumOfTrials": args.num_trials,
578 "RateInitial": args.rate_initial_pct,
579 "RateLowerLimit": args.rate_lower_limit_pct,
580 "RateStep": args.rate_step_pct,
581 "RateUpperLimit": args.rate_upper_limit_pct,
582 "Resolution": args.resolution_pct,
583 "SearchMode": args.search_mode,
584 "TrafficPattern": args.traffic_pattern})
585 elif args.metric == "latency":
586 stc.perform("Rfc2544SetupLatencyTestCommand",
587 params={"AcceptableFrameLoss":
588 args.acceptable_frame_loss_pct,
589 "Duration": args.trial_duration_sec,
590 "FrameSizeList": args.frame_size_list,
591 "LearningMode": args.learning_mode,
592 "LatencyType": args.latency_type,
593 "NumOfTrials": args.num_trials,
594 "RateInitial": args.rate_initial_pct,
595 "RateLowerLimit": args.rate_lower_limit_pct,
596 "RateStep": args.rate_step_pct,
597 "RateUpperLimit": args.rate_upper_limit_pct,
598 "Resolution": args.resolution_pct,
599 "SearchMode": args.search_mode,
600 "TrafficPattern": args.traffic_pattern})
602 # Save the configuration
603 stc.perform("SaveToTcc", params={"Filename": "2544.tcc"})
604 # Connect to the hardware...
605 stc.perform("AttachPorts", params={"portList": stc.get(
606 "system1.project", "children-port"), "autoConnect": "TRUE"})
607 # Apply configuration.
609 _LOGGER.debug("Apply configuration...")
612 # Register for the results
613 hResDataRx = stc.create('ResultDataSet', under='project1')
614 strmBlockList = stc.get('project1', 'children-streamblock')
615 stc.create('ResultQuery', under=hResDataRx, attributes={
616 'ResultRootList': strmBlockList,
617 'ConfigClassId': 'StreamBlock',
618 'ResultClassId': 'RxStreamSummaryResults',
619 'PropertyIdArray': "RxStreamSummaryResults.RxPort \
620 RxStreamSummaryResults.AvgLatency \
621 RxStreamSummaryResults.BitCount \
622 RxStreamSummaryResults.BitRate \
623 RxStreamSummaryResults.DroppedFrameCount\
624 RxStreamSummaryResults.DroppedFrameRate \
625 RxStreamSummaryResults.FrameCount \
626 RxStreamSummaryResults.FrameRate \
627 RxStreamSummaryResults.MaxLatency \
628 RxStreamSummaryResults.MinLatency \
629 RxStreamSummaryResults.OctetCount \
630 RxStreamSummaryResults.OctetRate \
631 RxStreamSummaryResults.SeqRunLength"})
632 hResDataTx = stc.create('ResultDataSet', under='project1')
633 strmBlockList = stc.get('project1', 'children-streamblock')
634 stc.create('ResultQuery', under=hResDataTx, attributes={
635 'ResultRootList': strmBlockList,
636 'ConfigClassId': 'StreamBlock',
637 'ResultClassId': 'TxStreamResults',
638 'PropertyIdArray': "TxStreamResults.BlockId \
639 TxStreamResults.BitCount \
640 TxStreamResults.BitRate \
641 TxStreamResults.FrameCount \
642 TxStreamResults.FrameRate \
643 TxStreamResults.OctetCount \
644 TxStreamResults.OctetRate"})
645 stc.perform('ResultDataSetSubscribe', params={'ResultDataSet': hResDataRx})
646 stc.perform('ResultDataSetSubscribe', params={'ResultDataSet': hResDataTx})
648 stc.perform('RefreshResultView', params={'ResultDataSet': hResDataTx})
649 hndListRx = stc.get(hResDataRx, 'ResultHandleList')
650 hndListTx = stc.get(hResDataTx, 'ResultHandleList')
653 _LOGGER.debug("Starting the sequencer...")
654 stc.perform("SequencerStart")
656 sequencer = stc.get("system1", "children-sequencer")
657 state = stc.get(sequencer, 'State')
659 # If Live-results are required, we don't wait for the test to complete
660 if args.live_results:
661 write_headers(args.vsperf_results_dir, args.logfile, '.rx')
662 write_headers(args.vsperf_results_dir, args.logfile, '.tx')
663 while state != 'IDLE':
664 state = stc.get(sequencer, 'State')
665 hndListTx = stc.get(hResDataTx, 'ResultHandleList')
667 handles = hndListTx.split(' ')
668 for handle in handles:
669 tx_values = stc.get(handle)
670 write_tx_live_results_to_file(args.vsperf_results_dir,
674 handles = hndListRx.split(' ')
675 for handle in handles:
676 rx_values = stc.get(handle)
677 write_rx_live_results_to_file(args.vsperf_results_dir,
681 # Live results not needed, so just wait!
683 # Wait for sequencer to finish
685 "Starting test... Please wait for the test to complete...")
686 stc.wait_until_complete()
688 _LOGGER.info("The test has completed... Saving results...")
690 # Determine what the results database filename is...
691 lab_server_resultsdb = stc.get(
692 "system1.project.TestResultSetting", "CurrentResultFileName")
694 if not lab_server_resultsdb or 'Results' not in lab_server_resultsdb:
695 _LOGGER.info("Failed to find results.")
700 _LOGGER.debug("The lab server results database is %s",
701 lab_server_resultsdb)
703 # Create Latency Histogram CSV file()
704 if args.latency_histogram:
705 hist_dict_counts = {}
706 for file_url in stc.files():
707 if '-FrameSize-' in file_url:
708 stc.download(file_url)
709 filename = file_url.split('/')[-1]
710 if os.path.exists(os.getcwd() + '/' + filename):
711 conn = sqlite3.connect(os.getcwd() + '/' + filename)
712 # cursor = conn.execute(
713 # 'select * from RxEotStreamResults')
714 # names = [desc[0] for desc in cursor.description]
715 counts = conn.execute("SELECT \
716 HistBin1Count, HistBin2Count,\
717 HistBin3Count, HistBin4Count,\
718 HistBin5Count, HistBin6Count,\
719 HistBin7Count, HistBin8Count,\
720 HistBin9Count, HistBin10Count,\
721 HistBin11Count, HistBin12Count,\
722 HistBin13Count, HistBin14Count, \
723 HistBin15Count, HistBin16Count \
724 from RxEotStreamResults")
725 strs = filename.split('-')
726 key = strs[strs.index('FrameSize')+1]
727 if key in hist_dict_counts:
728 hist_dict_counts[key] = [a+b for a, b in
729 zip(counts.fetchone(),
730 hist_dict_counts[key])]
732 hist_dict_counts[key] = counts.fetchone()
735 write_histogram_to_csv(args.vsperf_results_dir, 'Histogram',
739 stc.perform("CSSynchronizeFiles",
740 params={"DefaultDownloadDir": args.results_dir})
742 resultsdb = args.results_dir + \
743 lab_server_resultsdb.split("/Results")[1]
745 if not os.path.exists(resultsdb):
746 resultsdb = lab_server_resultsdb
747 _LOGGER.info("Failed to create the local summary DB File, using"
748 " the remote DB file instead.")
751 "The local summary DB file has been saved to %s", resultsdb)
753 # The returns the "RFC2544ThroughputTestResultDetailedSummaryView"
754 # table view from the results database.
755 # There are other views available.
757 if args.metric == "throughput":
759 stc.perform("QueryResult",
761 "DatabaseConnectionString":
764 ("RFC2544ThroughputTestResultDetailed"
767 # The returns the "RFC2544BacktoBackTestResultDetailedSummaryView"
768 # table view from the results database.
769 # There are other views available.
770 elif args.metric == "backtoback":
772 stc.perform("QueryResult",
774 "DatabaseConnectionString":
777 ("RFC2544Back2BackTestResultDetailed"
780 # The returns the "RFC2544LatencyTestResultDetailedSummaryView"
781 # table view from the results database.
782 # There are other views available.
783 elif args.metric == "latency":
785 stc.perform("QueryResult",
787 "DatabaseConnectionString":
790 ("RFC2544LatencyTestResultDetailed"
793 # The returns the "RFC2544FrameLossTestResultDetailedSummaryView"
794 # table view from the results database.
795 # There are other views available.
796 elif args.metric == "frameloss":
798 stc.perform("QueryResult",
800 "DatabaseConnectionString":
803 ("RFC2544FrameLossTestResultDetailed"
806 _LOGGER.debug("resultsdict[\"Columns\"]: %s",
807 resultsdict["Columns"])
808 _LOGGER.debug("resultsdict[\"Output\"]: %s", resultsdict["Output"])
809 _LOGGER.debug("Result paths: %s",
810 stc.perform("GetTestResultSettingPaths"))
812 # Write results to csv
813 _LOGGER.debug("Writing CSV file to results directory %s",
815 write_query_results_to_csv(
816 args.results_dir, args.csv_results_file_prefix, resultsdict)
818 except RuntimeError as e:
823 _LOGGER.debug("Destroy session on lab server")
826 _LOGGER.info("Test complete!")
828 if __name__ == "__main__":