From b12d21d5850ade955a54e6296e387871c4b7560f Mon Sep 17 00:00:00 2001 From: Ancuta Enache Date: Fri, 28 Feb 2020 10:24:21 +0200 Subject: Ixia Live Results This patch collects Ixia live results and copy the results file from generator machine to local server 1. Traffic Item Statistics are collected during traffic running 2. Results file is copied from traffic generator machine to local server 3. Fixed pylint errors and made b2b test running working 4. Replacing sleeping times with traffic state verifications JIRA: VSPERF-609 Signed-off-by: Ancuta Enache Change-Id: I351c3a5435a71acfd1b6bc85bc6c0731d2529cd8 --- 3rd_party/ixia/ixnetrfc2544.tcl | 131 ++++++++++++++++++++++++++++++---------- tools/pkt_gen/ixnet/ixnet.py | 76 +++++++++++++++++------ 2 files changed, 156 insertions(+), 51 deletions(-) diff --git a/3rd_party/ixia/ixnetrfc2544.tcl b/3rd_party/ixia/ixnetrfc2544.tcl index 435f335f..07c7b9f5 100644 --- a/3rd_party/ixia/ixnetrfc2544.tcl +++ b/3rd_party/ixia/ixnetrfc2544.tcl @@ -43,7 +43,7 @@ lappend auto_path [list $lib_path] # verify that the IXIA chassis spec is given -set reqVars [list "machine" "port" "user" "chassis" "card" "port1" "port2" "output_dir" "bidir"] +set reqVars [list "machine" "port" "user" "chassis" "card" "port1" "port2" "output_dir" "bidir" "frame_size_list"] set rfc2544test "" foreach var $reqVars { @@ -59,6 +59,7 @@ foreach var $reqVars { set ::IxNserver $machine set ::IxNport $port set ::biDirect $bidir +set frameSizeList $frame_size_list # change to windows path format and append directory set output_dir [string map {"/" "\\"} $output_dir] @@ -66,14 +67,17 @@ set output_dir "$output_dir\\rfctests" puts "Output directory is $output_dir" proc startRfc2544Test { testSpec trafficSpec } { - # Start RFC2544 quicktest. + # Start RFC2544 quickte"$output_dir\\rfctests"st. # Configure global variables. See documentation on 'global' for more # information on why this is necessary # https://www.tcl.tk/man/tcl8.5/tutorial/Tcl13.html global rfc2544test + global qt + global frameSizeList global sg_rfc2544throughput global sg_rfc2544back2back + global output_dir # Suffix for stack names # This variable should be incremented after setting sg_stack like: @@ -163,30 +167,18 @@ proc startRfc2544Test { testSpec trafficSpec } { set trafficSpec_vlan [dict get $trafficSpec vlan] set frameSize [dict get $trafficSpec_l2 framesize] - set srcMac [dict get $trafficSpec_l2 srcmac] + set srcMac [dict get $trafficSpec_l2 srcmac] set dstMac [dict get $trafficSpec_l2 dstmac] + set srcPort [dict get $trafficSpec_l4 srcport] + set dstPort [dict get $trafficSpec_l4 dstport] set proto [dict get $trafficSpec_l3 proto] set srcIp [dict get $trafficSpec_l3 srcip] set dstIp [dict get $trafficSpec_l3 dstip] + set vlanEnabled [dict get $trafficSpec_vlan enabled] + set l3Enabled [dict get $trafficSpec_l3 enabled] + set l4Enabled [dict get $trafficSpec_l4 enabled] - set srcPort [dict get $trafficSpec_l4 srcport] - set dstPort [dict get $trafficSpec_l4 dstport] - - set l3Enabled [dict get $trafficSpec_l3 enabled] - set l4Enabled [dict get $trafficSpec_l4 enabled] - set vlanEnabled [dict get $trafficSpec_vlan enabled] - - if {$vlanEnabled == 1 } { - # these keys won't exist if vlan wasn't enabled - set vlanId [dict get $trafficSpec_vlan id] - set vlanUserPrio [dict get $trafficSpec_vlan priority] - set vlanCfi [dict get $trafficSpec_vlan cfi] - } else { - set vlanId 0 - set vlanUserPrio 0 - set vlanCfi 0 - } if {$frameSize < 68 } { if {$rfc2544TestType == "back2back"} { @@ -281,7 +273,7 @@ proc startRfc2544Test { testSpec trafficSpec } { -csvLogPollIntervalMultiplier 1 \ -pollInterval 2 \ -guardrailEnabled True \ - -enableCsvLogging False \ + -enableCsvLogging False\ -dataStorePollingIntervalMultiplier 1 \ -maxNumberOfStatsPerCustomGraph 16 \ -additionalFcoeStat1 fcoeInvalidDelimiter \ @@ -373,7 +365,7 @@ proc startRfc2544Test { testSpec trafficSpec } { -useDefaultRootPath False \ -outputRootPath $::output_dir sg_commit - set sg_top [lindex [ixNet remapIds $sg_top] 0] + #set sg_top [lindex [ixNet remapIds $sg_top] 0] set ixNetSG_Stack(0) $sg_top ### @@ -1353,7 +1345,7 @@ proc startRfc2544Test { testSpec trafficSpec } { -destinationMacMode manual ixNet setMultiAttrs $sg_configElement/frameSize \ -weightedPairs {} \ - -fixedSize 64 \ + -fixedSize $frameSizeList \ -incrementFrom 64 \ -randomMin 64 \ -randomMax 1518 \ @@ -3080,7 +3072,7 @@ proc startRfc2544Test { testSpec trafficSpec } { ixNet setMultiAttrs $sg_tracking \ -offset 0 \ -oneToOneMesh False \ - -trackBy {} \ + -trackBy {trackingenabled0} \ -values {} \ -fieldWidth thirtyTwoBits \ -protocolOffset {Root.0} @@ -6276,12 +6268,16 @@ proc startRfc2544Test { testSpec trafficSpec } { # if {$rfc2544TestType == "throughput"} { set sg_rfc2544throughput [ixNet add $ixNetSG_Stack(0)/quickTest rfc2544throughput] + ixNet commit ixNet setMultiAttrs $sg_rfc2544throughput \ -name {QuickTest1} \ -mode existingMode \ -inputParameters {{}} + ixNet commit + set sizes [join $frameSizeList ","] + set sg_rfc2544throughput [lindex [ixNet remapIds $sg_rfc2544throughput] 0] ixNet setMultiAttrs $sg_rfc2544throughput/testConfig \ - -protocolItem {} \ + -protocolItem [list ] \ -enableMinFrameSize True \ -framesize $frameSize \ -reportTputRateUnit mbps \ @@ -6293,7 +6289,7 @@ proc startRfc2544Test { testSpec trafficSpec } { -tolerance 0 \ -frameLossUnit {0} \ -staggeredStart False \ - -framesizeList $frameSize \ + -framesizeList $sizes \ -frameSizeMode custom \ -rateSelect percentMaxRate \ -percentMaxRate 100 \ @@ -6318,7 +6314,7 @@ proc startRfc2544Test { testSpec trafficSpec } { -txDelay 2 \ -delayAfterTransmit 2 \ -minRandomFrameSize 64 \ - -maxRandomFrameSize 1518 \ + -maxRandomFrameSize 128 \ -countRandomFrameSize 1 \ -minIncrementFrameSize 64 \ -stepIncrementFrameSize 64 \ @@ -6415,9 +6411,9 @@ proc startRfc2544Test { testSpec trafficSpec } { -dataErrorThresholdValue 0 \ -dataErrorThresholdMode average sg_commit + ixNet commit set sg_rfc2544throughput [lindex [ixNet remapIds $sg_rfc2544throughput] 0] set ixNetSG_Stack(1) $sg_rfc2544throughput - # # configuring the object that corresponds to /quickTest/rfc2544throughput:1/protocols # @@ -6438,6 +6434,12 @@ proc startRfc2544Test { testSpec trafficSpec } { -includeMode inTest \ -itemType trafficItem sg_commit + + # + # configuring the results folder that corresponds to /quickTest/rfc2544throughput:1 + # + ixNet setAttr $sg_rfc2544throughput -resultPath $output_dir + ixNet commit set sg_trafficSelection [lindex [ixNet remapIds $sg_trafficSelection] 0] ixNet commit @@ -6466,7 +6468,7 @@ proc startRfc2544Test { testSpec trafficSpec } { -tolerance 0 \ -frameLossUnit {0} \ -staggeredStart False \ - -framesizeList $frameSize \ + -framesizeList [list $frameSize] \ -frameSizeMode custom \ -rateSelect percentMaxRate \ -percentMaxRate 100 \ @@ -6611,14 +6613,74 @@ proc startRfc2544Test { testSpec trafficSpec } { } ixNet exec apply $rfc2544test after 5000 - # # starting the RFC2544 Throughput test # puts "Starting test..." ixNet exec start $rfc2544test + puts "Checking if [ixNet getA $rfc2544test -name] started...." + set count 0 + while { [ixNet getA $rfc2544test/results -isRunning] eq false } { + after 1000 + if { $count > 60 } { error "QT failed to start after 1 minute" } + incr count + } + puts "Looking for statistics" + set results_file_name "Traffic Item Statistics" + set results_file_path [getResultFile $results_file_name] + return $results_file_path +} + +proc getResultFile { viewName } { + global output_dir + puts "Sleeping 20 seconds to have $viewName view" + after 20000 + set root [ixNet getRoot] + set views [ixNet getList $root/statistics view] + foreach view $views { + if { [ixNet getA $view -caption] eq $viewName } { + set trafficView $view + break + } + } + puts "Checking that the $viewName view is ready" + set count 0 + while { [ixNet getA $trafficView/data -isReady] eq false } { + after 1000 + if { $count > 2 } { break } + incr count + } + puts "Success! $viewName view is ready! " + puts "Changing the CSV path" + set setAttr [ixNet setA $root/statistics -csvFilePath $output_dir] + if { $setAttr != "::ixNet::OK"} { + error "Error" + } + ixNet commit + puts "Enabling CSV logging" + set setAttr [ixNet setA $trafficView -enableCsvLogging True] + if { $setAttr != "::ixNet::OK"} { + error "Error" + } + ixNet commit + puts "Enabled CSV logging" + puts "Getting CSV file name for $trafficView view" + set csv_path [ixNet getA $root/statistics -csvFilePath] + set csv_name [ixNet getA $trafficView -csvFileName] + ixNet commit + return [file join $csv_path $csv_name] +} + +proc copyFileResults { sourceFile destFile } { + puts "Coping the file $sourceFile to $destFile..." + set source [dict get $sourceFile source_file] + set dest [dict get $destFile dest_file] + if {[catch {ixNet exec copyFile [ixNet readFrom "$source" -ixNetRelative] [ixNet writeTo "$dest" -overwrite]} errMsg]} { + error "Error while copying results : '$errMsg'" + } } + proc waitForRfc2544Test { } { # Wait for- and return results of- RFC2544 quicktest. @@ -6626,7 +6688,14 @@ proc waitForRfc2544Test { } { puts "Waiting for test to complete..." set result [ixNet exec waitForTest $rfc2544test] + puts "Checking if [ixNet getA $rfc2544test -name] stopped" + set count 0 + while { [ixNet getA $rfc2544test/results -isRunning] eq true } { + after 1000 + if { $count > 60 } { error "QT failed to stop after 1 minute it finished" } + incr count + } puts "Finished Test" return "$result" -} +} \ No newline at end of file diff --git a/tools/pkt_gen/ixnet/ixnet.py b/tools/pkt_gen/ixnet/ixnet.py index 87fb2c65..93d9bb47 100755 --- a/tools/pkt_gen/ixnet/ixnet.py +++ b/tools/pkt_gen/ixnet/ixnet.py @@ -83,6 +83,7 @@ import logging import os import re import csv +import random from collections import OrderedDict from tools.pkt_gen import trafficgen @@ -129,7 +130,7 @@ def _build_set_cmds(values, prefix='dict set'): if isinstance(value, list): value = '{{{}}}'.format(' '.join(str(x) for x in value)) - yield ' '.join([prefix, 'set', key, value]).strip() + yield ' '.join([prefix, key, value]).strip() continue # tcl doesn't recognise the strings "True" or "False", only "1" @@ -176,10 +177,9 @@ class IxNet(trafficgen.ITrafficGenerator): :returns: Output of command, where applicable. """ self._logger.debug('%s%s', trafficgen.CMD_PREFIX, cmd) - output = self._tclsh.eval(cmd) - return output.split() + return output def configure(self): """Configure system for IxNetwork. @@ -199,6 +199,8 @@ class IxNet(trafficgen.ITrafficGenerator): 'port2': settings.getValue('TRAFFICGEN_IXIA_PORT2'), 'output_dir': settings.getValue('TRAFFICGEN_IXNET_TESTER_RESULT_DIR'), + 'frame_size_list': + settings.getValue('TRAFFICGEN_PKT_SIZES'), } self._logger.debug('IXIA configuration configuration : %s', self._cfg) @@ -256,11 +258,12 @@ class IxNet(trafficgen.ITrafficGenerator): 'An error occured when connecting to IxNetwork machine...') raise RuntimeError('Ixia failed to initialise.') - self.run_tcl('startRfc2544Test $config $traffic') + results_path = self.run_tcl('startRfc2544Test $config $traffic') if output: self._logger.critical( 'Failed to start continuous traffic test') raise RuntimeError('Continuous traffic test failed to start.') + return results_path def stop_cont_traffic(self): """See ITrafficGenerator for description @@ -271,9 +274,12 @@ class IxNet(trafficgen.ITrafficGenerator): lossrate=0.0): """See ITrafficGenerator for description """ - self.start_rfc2544_throughput(traffic, tests, duration, lossrate) - - return self.wait_rfc2544_throughput() + results_file = self.start_rfc2544_throughput(traffic, tests, duration, lossrate) + run_result = self.wait_rfc2544_throughput() + dest_file_name = 'Traffic_Item_Statistics_' + str(random.randrange(1, 100)) + '.csv' + self.copy_results_file(results_file, + os.path.join(settings.getValue('RESULTS_PATH'), dest_file_name)) + return run_result def start_rfc2544_throughput(self, traffic=None, tests=1, duration=20, lossrate=0.0): @@ -313,12 +319,14 @@ class IxNet(trafficgen.ITrafficGenerator): 'An error occured when connecting to IxNetwork machine...') raise RuntimeError('Ixia failed to initialise.') - self.run_tcl('startRfc2544Test $config $traffic') + results_file = self.run_tcl('startRfc2544Test $config $traffic') if output: self._logger.critical( 'Failed to start RFC2544 test') raise RuntimeError('RFC2544 test failed to start.') + return results_file + def wait_rfc2544_throughput(self): """See ITrafficGenerator for description """ @@ -397,12 +405,34 @@ class IxNet(trafficgen.ITrafficGenerator): return results output = self.run_tcl('waitForRfc2544Test') - # the run_tcl function will return a list with one element. We extract # that one element (a string representation of an IXIA-specific Tcl # datatype), parse it to find the path of the results file then parse # the results file - return parse_ixnet_rfc_results(parse_result_string(output[0])) + test_result = parse_ixnet_rfc_results(parse_result_string(output)) + return test_result + + def copy_results_file(self, source_file=None, dest_file=None): + """Copy a file from a source address to destination + """ + dest_dict = {} + source_dict = {} + srcfile = '' + if isinstance(source_file, list): + for i in source_file: + srcfile = srcfile + ' ' + i + else: + srcfile = source_file + + source = (srcfile.replace("\\", "/")).strip() + source_dict['source_file'] = {'source_file': '\"{}\"'.format(source)} + dest_dict['dest_file'] = {'dest_file': '{}'.format(dest_file)} + for cmd in _build_set_cmds(source_dict): + self.run_tcl(cmd) + for cmd in _build_set_cmds(dest_dict): + self.run_tcl(cmd) + self.run_tcl('copyFileResults $source_file $dest_file') + return dest_dict['dest_file'] def send_rfc2544_back2back(self, traffic=None, tests=1, duration=2, lossrate=0.0): @@ -411,9 +441,12 @@ class IxNet(trafficgen.ITrafficGenerator): # NOTE 2 seconds is the recommended duration for a back 2 back # test in RFC2544. 50 trials is the recommended number from the # RFC also. - self.start_rfc2544_back2back(traffic, tests, duration, lossrate) - - return self.wait_rfc2544_back2back() + b2b_results_file = self.start_rfc2544_back2back(traffic, tests, duration, lossrate) + b2b_run_result = self.wait_rfc2544_back2back() + dest_file_name = 'Traffic_Item_Statistics_' + str(random.randrange(1, 100)) + '.csv' + self.copy_results_file(b2b_results_file, + os.path.join(settings.getValue('RESULTS_PATH'), dest_file_name)) + return b2b_run_result def start_rfc2544_back2back(self, traffic=None, tests=1, duration=2, lossrate=0.0): @@ -453,15 +486,18 @@ class IxNet(trafficgen.ITrafficGenerator): 'An error occured when connecting to IxNetwork machine...') raise RuntimeError('Ixia failed to initialise.') - self.run_tcl('startRfc2544Test $config $traffic') + results_file = self.run_tcl('startRfc2544Test $config $traffic') if output: self._logger.critical( 'Failed to start RFC2544 test') raise RuntimeError('RFC2544 test failed to start.') + return results_file + def wait_rfc2544_back2back(self): """Wait for results. """ + def parse_result_string(results): """Get path to results file from output @@ -487,7 +523,7 @@ class IxNet(trafficgen.ITrafficGenerator): # transform path into something useful path = result_path.group(1).replace('\\', '/') - path = os.path.join(path, 'iteration.csv') + path = os.path.join(path, 'AggregateResults.csv') path = path.replace( settings.getValue('TRAFFICGEN_IXNET_TESTER_RESULT_DIR'), settings.getValue('TRAFFICGEN_IXNET_DUT_RESULT_DIR')) @@ -511,11 +547,11 @@ class IxNet(trafficgen.ITrafficGenerator): for row in reader: # if back2back count higher than previously found, store it # Note: row[N] here refers to the Nth column of a row - if float(row[14]) <= self._params['config']['lossrate']: - if int(row[12]) > \ + if float(row[10]) <= self._params['config']['lossrate']: + if int(float(row[8])) > \ int(results[ResultsConstants.B2B_FRAMES]): - results[ResultsConstants.B2B_FRAMES] = int(row[12]) - results[ResultsConstants.B2B_FRAME_LOSS_PERCENT] = float(row[14]) + results[ResultsConstants.B2B_FRAMES] = int(float(row[8])) + results[ResultsConstants.B2B_FRAME_LOSS_PERCENT] = float(row[10]) return results @@ -526,7 +562,7 @@ class IxNet(trafficgen.ITrafficGenerator): # datatype), parse it to find the path of the results file then parse # the results file - return parse_ixnet_rfc_results(parse_result_string(output[0])) + return parse_ixnet_rfc_results(parse_result_string(output)) def send_burst_traffic(self, traffic=None, duration=20): return NotImplementedError('IxNet does not implement send_burst_traffic') -- cgit 1.2.3-korg