def send_rfc2544_back2back(self, traffic=None, tests=1, duration=2, lossrate=0.0): """ Send traffic per RFC2544 back2back test specifications. """ traffic_ = self.traffic_defaults.copy() result = {} if traffic: traffic_ = merge_spec(traffic_, traffic) results = get_user_traffic( 'back2back', '%d tests, %d seconds iterations, %f packet loss, multistream ' '%s' % (tests, duration, lossrate, traffic['multistream']), traffic_, ('b2b frames', 'b2b frame loss %')) # builds results by using user-supplied values # and guessing remainder using available info result[ResultsConstants.B2B_FRAMES] = float(results[0]) result[ResultsConstants.B2B_FRAME_LOSS_PERCENT] = float(results[1]) return result
def send_cont_traffic(self, traffic=None, duration=30): """ Send a continuous flow of traffic. """ traffic_ = self.traffic_defaults.copy() result = {} if traffic: traffic_ = merge_spec(traffic_, traffic) results = get_user_traffic( 'continuous', '%dmpps, multistream %s, duration %d' % (traffic['frame_rate'], traffic['multistream'], duration), traffic_, ('frames tx', 'frames rx', 'tx rate %', 'rx rate %', 'min latency', 'max latency', 'avg latency', 'frameloss %')) framesize = traffic_['l2']['framesize'] # builds results by using user-supplied values # and guessing remainder using available info result[ResultsConstants.TX_RATE_FPS] = float(results[0]) / duration result[ResultsConstants.THROUGHPUT_RX_FPS] = float( results[1]) / duration result[ResultsConstants.TX_RATE_MBPS] = (float(results[0]) / duration) \ * (framesize * 8 / 1000000) result[ResultsConstants.THROUGHPUT_RX_MBPS] = (float(results[1]) / duration) \ * (framesize * 8 / 1000000) result[ResultsConstants.TX_RATE_PERCENT] = float(results[2]) result[ResultsConstants.THROUGHPUT_RX_PERCENT] = float(results[3]) result[ResultsConstants.MIN_LATENCY_NS] = float(results[4]) result[ResultsConstants.MAX_LATENCY_NS] = float(results[5]) result[ResultsConstants.AVG_LATENCY_NS] = float(results[6]) result[ResultsConstants.FRAME_LOSS_PERCENT] = float(results[7]) return result
def send_burst_traffic(self, traffic=None, numpkts=100, duration=20): """ Send a burst of traffic. """ traffic_ = self.traffic_defaults.copy() result = {} if traffic: traffic_ = merge_spec(traffic_, traffic) results = get_user_traffic( 'burst', '%dpkts, %dmS' % (numpkts, duration), traffic_, ('frames rx', 'payload errors', 'sequence errors')) # builds results by using user-supplied values where possible # and guessing remainder using available info result[ResultsConstants.TX_FRAMES] = numpkts result[ResultsConstants.RX_FRAMES] = results[0] result[ResultsConstants.TX_BYTES] = traffic_['l2']['framesize'] \ * numpkts result[ResultsConstants.RX_BYTES] = traffic_['l2']['framesize'] \ * results[0] result[ResultsConstants.PAYLOAD_ERR] = results[1] result[ResultsConstants.SEQ_ERR] = results[2] return results
def send_rfc2544_latency(self, traffic=None, tests=1, duration=20, lossrate=0.0, latency=False): """Send traffic per RFC2544 throughput test specifications. See ITrafficGenerator for description """ self._duration = duration self._params.clear() self._params['traffic'] = self.traffic_defaults.copy() if traffic: self._params['traffic'] = merge_spec(self._params['traffic'], traffic) self._setup_json_config(tests, lossrate, '2544_latency') self._start_xena_2544() self._wait_xena_2544_complete() root = ET.parse(os.path.join(_CURR_DIR, "xena2544-report.xml")).getroot() self.start_rfc2544_latency(traffic, 1, self._duration, lossrate) self.wait_rfc2544_latency() root = ET.parse(os.path.join(_CURR_DIR, "xena2544-report.xml")).getroot() return Xena._create_throughput_result(root)
def send_rfc2544_throughput(self, traffic=None, tests=1, duration=20, lossrate=0.0): """See ITrafficGenerator for description """ params = {} params['config'] = { 'tests': tests, 'duration': duration, 'lossrate': lossrate, 'multipleStreams': traffic['multistream'], } params['traffic'] = self.traffic_defaults.copy() if traffic: params['traffic'] = merge_spec(params['traffic'], traffic) for cmd in _build_set_cmds(params): self.run_tcl(cmd) # this will return a list with one result result = self.run_tcl('rfcThroughputTest $config $traffic') return Ixia._create_result(result)
def send_rfc2544_latency(self, traffic=None, tests=1, duration=60, lossrate=0.0): """See ITrafficGenerator for description """ self._logger.info("In Trex send_rfc2544_throughput method") self._params.clear() self._show_packet_data = True self._params['traffic'] = self.traffic_defaults.copy() if traffic: self._params['traffic'] = merge_spec(self._params['traffic'], traffic) if settings.getValue('TRAFFICGEN_TREX_LEARNING_MODE'): self.learning_packets(traffic) binary_bounds = { 'right': traffic['frame_rate'], 'left': 0, 'center': traffic['frame_rate'], } # Loops until the preconfigured differencde between frame rate # of successful and unsuccessful iterations is reached stats_ok = self.run_trials_one(boundaries=binary_bounds, duration=duration, lossrate=lossrate, traffic=traffic) return self.calculate_results_latency(stats_ok)
def send_rfc2544_throughput(self, traffic=None, tests=1, duration=60, lossrate=0.0): """See ITrafficGenerator for description """ self._logger.info("In Trex send_rfc2544_throughput method") self._params.clear() self._show_packet_data = True self._params['traffic'] = self.traffic_defaults.copy() if traffic: self._params['traffic'] = merge_spec( self._params['traffic'], traffic) if settings.getValue('TRAFFICGEN_TREX_LEARNING_MODE'): self.learning_packets(traffic) self._verification_params = copy.deepcopy(traffic) binary_bounds = {'right' : traffic['frame_rate'], 'left' : 0, 'center': traffic['frame_rate'],} # Loops until the preconfigured differencde between frame rate # of successful and unsuccessful iterations is reached stats_ok = self.run_trials(boundaries=binary_bounds, duration=duration, lossrate=lossrate, traffic=traffic) if settings.getValue('TRAFFICGEN_TREX_VERIFICATION_MODE'): verification_iterations = 1 while verification_iterations <= settings.getValue('TRAFFICGEN_TREX_MAXIMUM_VERIFICATION_TRIALS'): self._logger.info('Starting Trex Verification trial for %s seconds at frame rate %s', settings.getValue('TRAFFICGEN_TREX_VERIFICATION_DURATION'), self._verification_params['frame_rate']) stats = self.generate_traffic(self._verification_params, settings.getValue('TRAFFICGEN_TREX_VERIFICATION_DURATION')) verification_lossrate = ((stats["total"]["opackets"] - stats[ "total"]["ipackets"]) * 100) / stats["total"]["opackets"] if verification_lossrate <= lossrate: self._logger.info('Trex Verification passed, %s packets were lost', stats["total"]["opackets"] - stats["total"]["ipackets"]) stats_ok = copy.deepcopy(stats) break else: self._logger.info('Trex Verification failed, %s packets were lost', stats["total"]["opackets"] - stats["total"]["ipackets"]) new_right = self._verification_params['frame_rate'] - settings.getValue( 'TRAFFICGEN_TREX_RFC2544_TPUT_THRESHOLD') self._verification_params['frame_rate'] = new_right binary_bounds = {'right': new_right, 'left': 0, 'center': new_right,} stats_ok = self.run_trials(boundaries=binary_bounds, duration=duration, lossrate=lossrate, traffic=self._verification_params) verification_iterations += 1 else: self._logger.error('Could not pass Trex Verification. Test failed') return self.calculate_results(stats_ok)
def send_burst_traffic(self, traffic=None, duration=20): """Send a burst of traffic. See ITrafficGenerator for description """ self._duration = duration self._params.clear() self._params['traffic'] = self.traffic_defaults.copy() if traffic: self._params['traffic'] = merge_spec(self._params['traffic'], traffic) self._start_traffic_api(traffic['burst_size']) return self._stop_api_traffic()
def start_cont_traffic(self, traffic=None, duration=20): """Non-blocking version of 'send_cont_traffic'. See ITrafficGenerator for description """ self._duration = duration self._params.clear() self._params['traffic'] = self.traffic_defaults.copy() if traffic: self._params['traffic'] = merge_spec(self._params['traffic'], traffic) self._start_traffic_api(-1)
def send_cont_traffic(self, traffic=None, duration=20): """Send a continuous flow of traffic. See ITrafficGenerator for description """ self._duration = duration self._params.clear() self._params['traffic'] = self.traffic_defaults.copy() if traffic: self._params['traffic'] = merge_spec(self._params['traffic'], traffic) self._start_traffic_api(-1) return self._stop_api_traffic()
def start_rfc2544_back2back(self, traffic=None, tests=1, duration=20, lossrate=0.0): """Non-blocking version of 'send_rfc2544_back2back'. See ITrafficGenerator for description """ self._duration = duration self._params.clear() self._params['traffic'] = self.traffic_defaults.copy() if traffic: self._params['traffic'] = merge_spec(self._params['traffic'], traffic) self._setup_json_config(tests, lossrate, '2544_b2b') self._start_xena_2544()
def start_rfc2544_back2back(self, traffic=None, tests=1, duration=2, lossrate=0.0): """Start transmission. """ self.configure() self._bidir = traffic['bidir'] self._params = {} self._params['config'] = { 'binary': True, 'tests': tests, 'duration': duration, 'lossrate': lossrate, 'multipleStreams': traffic['multistream'], 'streamType': traffic['stream_type'], 'rfc2544TestType': 'back2back', 'flowControl': "True" if traffic['flow_control'] else "False", 'learningFrames': "True" if traffic['learning_frames'] else "False", } self._params['traffic'] = self.traffic_defaults.copy() if traffic: self._params['traffic'] = merge_spec(self._params['traffic'], traffic) self._cfg['bidir'] = self._bidir for cmd in _build_set_cmds(self._cfg, prefix='set'): self.run_tcl(cmd) for cmd in _build_set_cmds(self._params): self.run_tcl(cmd) output = self.run_tcl('source {%s}' % self._script) if output: self._logger.critical( 'An error occured when connecting to IxNetwork machine...') raise RuntimeError('Ixia failed to initialise.') 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 send_cont_traffic(self, traffic=None, duration=30): """See ITrafficGenerator for description """ self._logger.info("In Trex send_cont_traffic method") self._params.clear() self._params['traffic'] = self.traffic_defaults.copy() if traffic: self._params['traffic'] = merge_spec(self._params['traffic'], traffic) if settings.getValue('TRAFFICGEN_TREX_LEARNING_MODE'): self.learning_packets(traffic) stats = self.generate_traffic(traffic, duration) return self.calculate_results(stats)
def send_burst_traffic(self, traffic=None, duration=20): """See ITrafficGenerator for description """ self._logger.info("In Trex send_burst_traffic method") self._params.clear() self._params['traffic'] = self.traffic_defaults.copy() if traffic: self._params['traffic'] = merge_spec( self._params['traffic'], traffic) if settings.getValue('TRAFFICGEN_TREX_LEARNING_MODE'): self.learning_packets(traffic) self._logger.info("T-Rex sending traffic") stats = self.generate_traffic(traffic, duration) time.sleep(3) # allow packets to complete before reading stats return self.calculate_results(stats)
def start_cont_traffic(self, traffic=None, duration=30): """Start transmission. """ self.configure() self._bidir = traffic['bidir'] self._params = {} self._params['config'] = { 'binary': False, # don't do binary search and send one stream 'duration': duration, 'framerate': traffic['frame_rate'], 'multipleStreams': traffic['multistream'], 'streamType': traffic['stream_type'], 'rfc2544TestType': 'throughput', 'flowControl': "True" if traffic['flow_control'] else "False", 'learningFrames': "True" if traffic['learning_frames'] else "False", } self._params['traffic'] = self.traffic_defaults.copy() if traffic: self._params['traffic'] = merge_spec(self._params['traffic'], traffic) self._cfg['bidir'] = self._bidir for cmd in _build_set_cmds(self._cfg, prefix='set'): self.run_tcl(cmd) for cmd in _build_set_cmds(self._params): self.run_tcl(cmd) output = self.run_tcl('source {%s}' % self._script) if output: self._logger.critical( 'An error occured when connecting to IxNetwork machine...') raise RuntimeError('Ixia failed to initialise.') 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 send_rfc2544_throughput(self, traffic=None, tests=1, duration=20, lossrate=0.0): """ Send traffic per RFC2544 throughput test specifications. """ traffic_ = self.traffic_defaults.copy() result = {} if traffic: traffic_ = merge_spec(traffic_, traffic) results = get_user_traffic( 'throughput', '%d tests, %d seconds iterations, %f packet loss, multistream ' '%s' % (tests, duration, lossrate, traffic['multistream']), traffic_, ('frames tx', 'frames rx', 'tx rate %', 'rx rate %', 'min latency', 'max latency', 'avg latency', 'frameloss %')) framesize = traffic_['l2']['framesize'] # builds results by using user-supplied values # and guessing remainder using available info result[ResultsConstants.TX_RATE_FPS] = float(results[0]) / duration result[ResultsConstants.THROUGHPUT_RX_FPS] = float( results[1]) / duration result[ResultsConstants.TX_RATE_MBPS] = (float(results[0]) / duration) \ * (framesize * 8 / 1000000) result[ResultsConstants.THROUGHPUT_RX_MBPS] = (float(results[1]) / duration) \ * (framesize * 8 / 1000000) result[ResultsConstants.TX_RATE_PERCENT] = float(results[2]) result[ResultsConstants.THROUGHPUT_RX_PERCENT] = float(results[3]) result[ResultsConstants.MIN_LATENCY_NS] = float(results[4]) result[ResultsConstants.MAX_LATENCY_NS] = float(results[5]) result[ResultsConstants.AVG_LATENCY_NS] = float(results[6]) result[ResultsConstants.FRAME_LOSS_PERCENT] = float(results[7]) return result
def _send_traffic(self, flow, traffic): """Send regular traffic. :param flow: Flow specification :param traffic: Traffic specification :returns: Results from IXIA """ params = {} params['flow'] = flow params['traffic'] = self.traffic_defaults.copy() if traffic: params['traffic'] = merge_spec(params['traffic'], traffic) for cmd in _build_set_cmds(params): self.run_tcl(cmd) result = self.run_tcl('sendTraffic $flow $traffic') return result
def __init__(self, test_cfg): """Pull out fields from test config :param test_cfg: A dictionary of string-value pairs describing the test configuration. Both the key and values strings use well-known values. :param results_dir: Where the csv formatted results are written. """ # make a local copy of test configuration to avoid modification of # original content used in vsperf main script cfg = copy.deepcopy(test_cfg) self._testcase_start_time = time.time() self._hugepages_mounted = False self._traffic_ctl = None self._vnf_ctl = None self._vswitch_ctl = None self._collector = None self._loadgen = None self._output_file = None self._tc_results = None self._settings_original = {} self._settings_paths_modified = False self._testcast_run_time = None self._versions = [] # initialization of step driven specific members self._step_check = False # by default don't check result for step driven testcases self._step_vnf_list = {} self._step_result = [] self._step_status = None self._testcase_run_time = None # store all GUEST_ specific settings to keep original values before their expansion for key in S.__dict__: if key.startswith('GUEST_'): self._settings_original[key] = S.getValue(key) self._update_settings('VSWITCH', cfg.get('vSwitch', S.getValue('VSWITCH'))) self._update_settings('VNF', cfg.get('VNF', S.getValue('VNF'))) self._update_settings('TRAFFICGEN', cfg.get('Trafficgen', S.getValue('TRAFFICGEN'))) test_params = copy.deepcopy(S.getValue('TEST_PARAMS')) tc_test_params = cfg.get('Parameters', S.getValue('TEST_PARAMS')) test_params = merge_spec(test_params, tc_test_params) self._update_settings('TEST_PARAMS', test_params) S.check_test_params() # override all redefined GUEST_ values to have them expanded correctly tmp_test_params = copy.deepcopy(S.getValue('TEST_PARAMS')) for key in tmp_test_params: if key.startswith('GUEST_'): S.setValue(key, S.getValue(key)) S.getValue('TEST_PARAMS').pop(key) # update global settings functions.settings_update_paths() # set test parameters; CLI options take precedence to testcase settings self._logger = logging.getLogger(__name__) self.name = cfg['Name'] self.desc = cfg.get('Description', 'No description given.') self.test = cfg.get('TestSteps', None) bidirectional = S.getValue('TRAFFIC')['bidir'] if not isinstance(S.getValue('TRAFFIC')['bidir'], str): raise TypeError('Bi-dir value must be of type string') bidirectional = bidirectional.title() # Keep things consistent self.deployment = cfg['Deployment'] self._frame_mod = cfg.get('Frame Modification', None) self._tunnel_type = None self._tunnel_operation = None if self.deployment == 'op2p': self._tunnel_operation = cfg['Tunnel Operation'] if 'Tunnel Type' in cfg: self._tunnel_type = cfg['Tunnel Type'] self._tunnel_type = get_test_param('TUNNEL_TYPE', self._tunnel_type) # check if test requires background load and which generator it uses self._load_cfg = cfg.get('Load', None) if self._load_cfg and 'tool' in self._load_cfg: self._loadgen = self._load_cfg['tool'] else: # background load is not requested, so use dummy implementation self._loadgen = "Dummy" if self._frame_mod: self._frame_mod = self._frame_mod.lower() self._results_dir = S.getValue('RESULTS_PATH') # set traffic details, so they can be passed to vswitch and traffic ctls self._traffic = copy.deepcopy(S.getValue('TRAFFIC')) self._traffic.update({ 'bidir': bidirectional, 'tunnel_type': self._tunnel_type, }) self._traffic = functions.check_traffic(self._traffic) # Packet Forwarding mode self._vswitch_none = str( S.getValue('VSWITCH')).strip().lower() == 'none' # trafficgen configuration required for tests of tunneling protocols if self.deployment == "op2p": self._traffic['l2'].update({ 'srcmac': S.getValue('TRAFFICGEN_PORT1_MAC'), 'dstmac': S.getValue('TRAFFICGEN_PORT2_MAC') }) self._traffic['l3'].update({ 'srcip': S.getValue('TRAFFICGEN_PORT1_IP'), 'dstip': S.getValue('TRAFFICGEN_PORT2_IP') }) if self._tunnel_operation == "decapsulation": self._traffic['l2'] = S.getValue(self._tunnel_type.upper() + '_FRAME_L2') self._traffic['l3'] = S.getValue(self._tunnel_type.upper() + '_FRAME_L3') self._traffic['l4'] = S.getValue(self._tunnel_type.upper() + '_FRAME_L4') elif len(S.getValue('NICS')) and \ (S.getValue('NICS')[0]['type'] == 'vf' or S.getValue('NICS')[1]['type'] == 'vf'): mac1 = S.getValue('NICS')[0]['mac'] mac2 = S.getValue('NICS')[1]['mac'] if mac1 and mac2: self._traffic['l2'].update({'srcmac': mac2, 'dstmac': mac1}) else: self._logger.debug("MAC addresses can not be read") # count how many VNFs are involved in TestSteps if self.test: for step in self.test: if step[0].startswith('vnf'): self._step_vnf_list[step[0]] = None
def send_rfc2544_throughput(self, traffic=None, tests=1, duration=20, lossrate=0.0): """Send traffic per RFC2544 throughput test specifications. See ITrafficGenerator for description """ self._duration = duration self._params.clear() self._params['traffic'] = self.traffic_defaults.copy() if traffic: self._params['traffic'] = merge_spec(self._params['traffic'], traffic) self._setup_json_config(tests, lossrate, '2544_throughput') self._start_xena_2544() self._wait_xena_2544_complete() root = ET.parse(os.path.join(_CURR_DIR, "xena2544-report.xml")).getroot() if settings.getValue('TRAFFICGEN_XENA_RFC2544_VERIFY'): # make sure we have a pass before even trying the verify. No need # to run verify on a failed iteration. root = ET.parse( os.path.join(_CURR_DIR, "xena2544-report.xml")).getroot() if root[0][1][0].get('TestState') == "FAIL": self._logger.info('Test failed, skipping verify') return Xena._create_throughput_result(root) # record the previous settings so we can revert to them if needed to # run the binary search again if the verify fails. old_tests = tests old_duration = self._duration old_min = settings.getValue('TRAFFICGEN_XENA_2544_TPUT_MIN_VALUE') # record the original values to restore after execution orig_min = settings.getValue('TRAFFICGEN_XENA_2544_TPUT_MIN_VALUE') orig_max = settings.getValue('TRAFFICGEN_XENA_2544_TPUT_MAX_VALUE') orig_init = settings.getValue('TRAFFICGEN_XENA_2544_TPUT_INIT_VALUE') for attempt in range( 1, settings.getValue( 'TRAFFICGEN_XENA_RFC2544_MAXIMUM_VERIFY_ATTEMPTS')+1): self._logger.info('Running verify attempt %s', attempt) # get the last pass tx rate from the binary search pass_rate = float(root[0][1][0].get('TotalTxRatePcnt')) # run a one pass rfc2544 with the pass rate to see if it passes # the verify duration settings.setValue( 'TRAFFICGEN_XENA_2544_TPUT_INIT_VALUE', pass_rate) settings.setValue( 'TRAFFICGEN_XENA_2544_TPUT_MIN_VALUE', pass_rate) settings.setValue( 'TRAFFICGEN_XENA_2544_TPUT_MAX_VALUE', pass_rate) self.start_rfc2544_throughput( traffic, 1, settings.getValue( 'TRAFFICGEN_XENA_RFC2544_VERIFY_DURATION'), lossrate) self.wait_rfc2544_throughput() root = ET.parse( os.path.join(_CURR_DIR, "xena2544-report.xml")).getroot() # If it passed, report the number of lost frames and exit the # loop if root[0][1][0].get('TestState') == "PASS": self._logger.info('Verify passed, packets lost = %s', root[0][1][0].get('TotalLossFrames')) break elif attempt < settings.getValue( 'TRAFFICGEN_XENA_RFC2544_MAXIMUM_VERIFY_ATTEMPTS'): self._logger.info( 'Verify failed, resuming binary search, packets lost = %s', root[0][1][0].get('TotalLossFrames')) settings.setValue( 'TRAFFICGEN_XENA_2544_TPUT_MAX_VALUE', pass_rate - float(settings.getValue( 'TRAFFICGEN_XENA_2544_TPUT_VALUE_RESOLUTION'))) if settings.getValue( 'TRAFFICGEN_XENA_RFC2544_BINARY_RESTART_SMART_SEARCH'): settings.setValue( 'TRAFFICGEN_XENA_2544_TPUT_INIT_VALUE', (pass_rate - float(old_min)) / 2) else: settings.setValue( 'TRAFFICGEN_XENA_2544_TPUT_INIT_VALUE', pass_rate - float(settings.getValue( 'TRAFFICGEN_XENA_2544_TPUT_VALUE_RESOLUTION'))) settings.setValue( 'TRAFFICGEN_XENA_2544_TPUT_MIN_VALUE', old_min) self._logger.debug( 'RFC2544 Initial rate: %s', settings.getValue('TRAFFICGEN_XENA_2544_TPUT_INIT_VALUE')) self._logger.debug( 'RFC2544 Maximum rate: %s', settings.getValue('TRAFFICGEN_XENA_2544_TPUT_MAX_VALUE')) self._logger.debug( 'RFC2544 Minimum rate: %s', settings.getValue('TRAFFICGEN_XENA_2544_TPUT_MIN_VALUE')) self._duration = old_duration self.start_rfc2544_throughput( traffic, old_tests, self._duration, lossrate) self.wait_rfc2544_throughput() root = ET.parse( os.path.join(_CURR_DIR, "xena2544-report.xml")).getroot() else: self._logger.error( 'Maximum number of verify attempts reached. Reporting last result') #restore original values settings.setValue('TRAFFICGEN_XENA_2544_TPUT_MIN_VALUE', orig_min) settings.setValue('TRAFFICGEN_XENA_2544_TPUT_MAX_VALUE', orig_max) settings.setValue('TRAFFICGEN_XENA_2544_TPUT_INIT_VALUE', orig_init) return Xena._create_throughput_result(root)
def __init__(self, test_cfg): """Pull out fields from test config :param test_cfg: A dictionary of string-value pairs describing the test configuration. Both the key and values strings use well-known values. :param results_dir: Where the csv formatted results are written. """ # make a local copy of test configuration to avoid modification of # original content used in vsperf main script cfg = copy.deepcopy(test_cfg) self._testcase_start_time = time.time() self._testcase_stop_time = self._testcase_start_time self._hugepages_mounted = False self._traffic_ctl = None self._vnf_ctl = None self._pod_ctl = None self._vswitch_ctl = None self._collector = None self._loadgen = None self._output_file = None self._tc_results = None self._settings_paths_modified = False self._testcast_run_time = None self._versions = [] self._k8s = False # initialization of step driven specific members self._step_check = False # by default don't check result for step driven testcases self._step_vnf_list = {} self._step_result = [] self._step_result_mapping = {} self._step_status = None self._step_send_traffic = False # indication if send_traffic was called within test steps self._vnf_list = [] self._testcase_run_time = None S.setValue('VSWITCH', cfg.get('vSwitch', S.getValue('VSWITCH'))) S.setValue('VNF', cfg.get('VNF', S.getValue('VNF'))) S.setValue('TRAFFICGEN', cfg.get('Trafficgen', S.getValue('TRAFFICGEN'))) S.setValue('TUNNEL_TYPE', cfg.get('Tunnel Type', S.getValue('TUNNEL_TYPE'))) test_params = copy.deepcopy(S.getValue('TEST_PARAMS')) tc_test_params = cfg.get('Parameters', S.getValue('TEST_PARAMS')) test_params = merge_spec(test_params, tc_test_params) # ensure that parameters from TC definition have the highest priority, see MAPPING_TC_CFG2CONF for (cfg_param, param) in MAPPING_TC_CFG2CONF.items(): if cfg_param in cfg and param in test_params: del test_params[param] S.setValue('TEST_PARAMS', test_params) S.check_test_params() # override all redefined GUEST_ values to have them expanded correctly tmp_test_params = copy.deepcopy(S.getValue('TEST_PARAMS')) for key in tmp_test_params: if key.startswith('GUEST_'): S.setValue(key, S.getValue(key)) S.getValue('TEST_PARAMS').pop(key) # update global settings functions.settings_update_paths() # set test parameters; CLI options take precedence to testcase settings self._logger = logging.getLogger(__name__) self.name = cfg['Name'] self.desc = cfg.get('Description', 'No description given.') self.test = cfg.get('TestSteps', None) # log testcase name and details tmp_desc = functions.format_description(self.desc, 50) self._logger.info( '############################################################') self._logger.info('# Test: %s', self.name) self._logger.info('# Details: %s', tmp_desc[0]) for i in range(1, len(tmp_desc)): self._logger.info('# %s', tmp_desc[i]) self._logger.info( '############################################################') bidirectional = S.getValue('TRAFFIC')['bidir'] if not isinstance(S.getValue('TRAFFIC')['bidir'], str): raise TypeError('Bi-dir value must be of type string') bidirectional = bidirectional.title() # Keep things consistent self.deployment = cfg['Deployment'] self._frame_mod = cfg.get('Frame Modification', None) self._tunnel_operation = cfg.get('Tunnel Operation', None) # check if test requires background load and which generator it uses self._load_cfg = cfg.get('Load', None) if self._frame_mod: self._frame_mod = self._frame_mod.lower() self._results_dir = S.getValue('RESULTS_PATH') # set traffic details, so they can be passed to vswitch and traffic ctls self._traffic = copy.deepcopy(S.getValue('TRAFFIC')) self._traffic.update({'bidir': bidirectional}) # Packet Forwarding mode self._vswitch_none = str( S.getValue('VSWITCH')).strip().lower() == 'none' # trafficgen configuration required for tests of tunneling protocols if self._tunnel_operation: self._traffic.update({'tunnel_type': S.getValue('TUNNEL_TYPE')}) self._traffic['l2'].update({ 'srcmac': S.getValue('TRAFFICGEN_PORT1_MAC'), 'dstmac': S.getValue('TRAFFICGEN_PORT2_MAC') }) self._traffic['l3'].update({ 'srcip': S.getValue('TRAFFICGEN_PORT1_IP'), 'dstip': S.getValue('TRAFFICGEN_PORT2_IP') }) if self._tunnel_operation == "decapsulation": self._traffic['l2'].update( S.getValue( S.getValue('TUNNEL_TYPE').upper() + '_FRAME_L2')) self._traffic['l3'].update( S.getValue( S.getValue('TUNNEL_TYPE').upper() + '_FRAME_L3')) self._traffic['l4'].update( S.getValue( S.getValue('TUNNEL_TYPE').upper() + '_FRAME_L4')) self._traffic['l2']['dstmac'] = S.getValue('NICS')[1]['mac'] elif len(S.getValue('NICS')) >= 2 and \ (S.getValue('NICS')[0]['type'] == 'vf' or S.getValue('NICS')[1]['type'] == 'vf'): mac1 = S.getValue('NICS')[0]['mac'] mac2 = S.getValue('NICS')[1]['mac'] if mac1 and mac2: self._traffic['l2'].update({'srcmac': mac2, 'dstmac': mac1}) else: self._logger.debug("MAC addresses can not be read") self._traffic = functions.check_traffic(self._traffic) # count how many VNFs are involved in TestSteps if self.test: for step in self.test: if step[0].startswith('vnf'): self._step_vnf_list[step[0]] = None # if llc allocation is required, initialize it. if S.getValue('LLC_ALLOCATION'): self._rmd = rmd.CacheAllocator()
def send_rfc2544_back2back(self, traffic=None, duration=60, lossrate=0.0, tests=1): """Send traffic per RFC2544 back2back test specifications. Send packets at a fixed rate, using ``traffic`` configuration, for duration seconds. :param traffic: Detailed "traffic" spec, see design docs for details :param tests: Number of tests to execute :param duration: Per iteration duration :param lossrate: Acceptable loss percentage :returns: Named tuple of Rx Throughput (fps), Rx Throughput (mbps), Tx Rate (% linerate), Rx Rate (% linerate), Tx Count (frames), Back to Back Count (frames), Frame Loss (frames), Frame Loss (%) :rtype: :class:`Back2BackResult` """ self._logger.info("In moongen send_rfc2544_back2back method") self._params.clear() self._params['traffic'] = self.traffic_defaults.copy() if traffic: self._params['traffic'] = merge_spec(self._params['traffic'], traffic) Moongen.create_moongen_cfg_file(self, traffic, duration=duration, acceptable_loss_pct=lossrate) # Initialize RFC 2544 B2B specific results results = OrderedDict() results[ResultsConstants.B2B_RX_FPS] = 0 results[ResultsConstants.B2B_TX_FPS] = 0 results[ResultsConstants.B2B_RX_PERCENT] = 0 results[ResultsConstants.B2B_TX_PERCENT] = 0 results[ResultsConstants.B2B_TX_COUNT] = 0 results[ResultsConstants.B2B_FRAMES] = 0 results[ResultsConstants.B2B_FRAME_LOSS_FRAMES] = 0 results[ResultsConstants.B2B_FRAME_LOSS_PERCENT] = 0 results[ResultsConstants.SCAL_STREAM_COUNT] = 0 results[ResultsConstants.SCAL_STREAM_TYPE] = 0 results[ResultsConstants.SCAL_PRE_INSTALLED_FLOWS] = 0 for test_run in range(1, tests+1): collected_results = ( Moongen.run_moongen_and_collect_results(self, test_run=test_run)) results[ResultsConstants.B2B_RX_FPS] += ( float(collected_results[ResultsConstants.THROUGHPUT_RX_FPS])) results[ResultsConstants.B2B_RX_PERCENT] += ( float(collected_results[ResultsConstants.THROUGHPUT_RX_PERCENT])) results[ResultsConstants.B2B_TX_FPS] += ( float(collected_results[ResultsConstants.TX_RATE_FPS])) results[ResultsConstants.B2B_TX_PERCENT] += ( float(collected_results[ResultsConstants.TX_RATE_PERCENT])) results[ResultsConstants.B2B_TX_COUNT] += ( int(collected_results[ResultsConstants.B2B_TX_COUNT])) results[ResultsConstants.B2B_FRAMES] += ( int(collected_results[ResultsConstants.B2B_FRAMES])) results[ResultsConstants.B2B_FRAME_LOSS_FRAMES] += ( int(collected_results[ResultsConstants.B2B_FRAME_LOSS_FRAMES])) results[ResultsConstants.B2B_FRAME_LOSS_PERCENT] += ( int(collected_results[ResultsConstants.B2B_FRAME_LOSS_PERCENT])) # Calculate average results results[ResultsConstants.B2B_RX_FPS] = ( results[ResultsConstants.B2B_RX_FPS] / tests) results[ResultsConstants.B2B_RX_PERCENT] = ( results[ResultsConstants.B2B_RX_PERCENT] / tests) results[ResultsConstants.B2B_TX_FPS] = ( results[ResultsConstants.B2B_TX_FPS] / tests) results[ResultsConstants.B2B_TX_PERCENT] = ( results[ResultsConstants.B2B_TX_PERCENT] / tests) results[ResultsConstants.B2B_TX_COUNT] = ( results[ResultsConstants.B2B_TX_COUNT] / tests) results[ResultsConstants.B2B_FRAMES] = ( results[ResultsConstants.B2B_FRAMES] / tests) results[ResultsConstants.B2B_FRAME_LOSS_FRAMES] = ( results[ResultsConstants.B2B_FRAME_LOSS_FRAMES] / tests) results[ResultsConstants.B2B_FRAME_LOSS_PERCENT] = ( results[ResultsConstants.B2B_FRAME_LOSS_PERCENT] / tests) results[ResultsConstants.SCAL_STREAM_COUNT] = 0 results[ResultsConstants.SCAL_STREAM_TYPE] = 0 results[ResultsConstants.SCAL_PRE_INSTALLED_FLOWS] = 0 return results
def send_rfc2544_throughput(self, traffic=None, duration=20, lossrate=0.0, tests=1): # # Send traffic per RFC2544 throughput test specifications. # # Send packets at a variable rate, using ``traffic`` # configuration, until minimum rate at which no packet loss is # detected is found. # # :param traffic: Detailed "traffic" spec, see design docs for details # :param tests: Number of tests to execute # :param duration: Per iteration duration # :param lossrate: Acceptable lossrate percentage # :returns: dictionary of strings with following data: # - Tx Throughput (fps), # - Rx Throughput (fps), # - Tx Throughput (mbps), # - Rx Throughput (mbps), # - Tx Throughput (% linerate), # - Rx Throughput (% linerate), # - Min Latency (ns), # - Max Latency (ns), # - Avg Latency (ns) # self._logger.info("In moongen send_rfc2544_throughput method") self._params.clear() self._params['traffic'] = self.traffic_defaults.copy() if traffic: self._params['traffic'] = merge_spec(self._params['traffic'], traffic) Moongen.create_moongen_cfg_file(self, traffic, duration=duration, acceptable_loss_pct=lossrate) # Initialize RFC 2544 throughput specific results results = OrderedDict() results[ResultsConstants.THROUGHPUT_RX_FPS] = 0 results[ResultsConstants.THROUGHPUT_RX_MBPS] = 0 results[ResultsConstants.THROUGHPUT_RX_PERCENT] = 0 results[ResultsConstants.TX_RATE_FPS] = 0 results[ResultsConstants.TX_RATE_MBPS] = 0 results[ResultsConstants.TX_RATE_PERCENT] = 0 results[ResultsConstants.MIN_LATENCY_NS] = 0 results[ResultsConstants.MAX_LATENCY_NS] = 0 results[ResultsConstants.AVG_LATENCY_NS] = 0 for test_run in range(1, tests+1): collected_results = ( Moongen.run_moongen_and_collect_results(self, test_run=test_run)) results[ResultsConstants.THROUGHPUT_RX_FPS] += ( float(collected_results[ResultsConstants.THROUGHPUT_RX_FPS])) results[ResultsConstants.THROUGHPUT_RX_MBPS] += ( float(collected_results[ResultsConstants.THROUGHPUT_RX_MBPS])) results[ResultsConstants.THROUGHPUT_RX_PERCENT] += ( float(collected_results[ResultsConstants.THROUGHPUT_RX_PERCENT])) results[ResultsConstants.TX_RATE_FPS] += ( float(collected_results[ResultsConstants.TX_RATE_FPS])) results[ResultsConstants.TX_RATE_MBPS] += ( float(collected_results[ResultsConstants.TX_RATE_MBPS])) results[ResultsConstants.TX_RATE_PERCENT] += ( float(collected_results[ResultsConstants.TX_RATE_PERCENT])) results[ResultsConstants.THROUGHPUT_RX_FPS] = ( '{:.6f}'.format(results[ResultsConstants.THROUGHPUT_RX_FPS] / tests)) results[ResultsConstants.THROUGHPUT_RX_MBPS] = ( '{:.3f}'.format(results[ResultsConstants.THROUGHPUT_RX_MBPS] / tests)) results[ResultsConstants.THROUGHPUT_RX_PERCENT] = ( '{:.3f}'.format(results[ResultsConstants.THROUGHPUT_RX_PERCENT] / tests)) results[ResultsConstants.TX_RATE_FPS] = ( '{:.6f}'.format(results[ResultsConstants.TX_RATE_FPS] / tests)) results[ResultsConstants.TX_RATE_MBPS] = ( '{:.3f}'.format(results[ResultsConstants.TX_RATE_MBPS] / tests)) results[ResultsConstants.TX_RATE_PERCENT] = ( '{:.3f}'.format(results[ResultsConstants.TX_RATE_PERCENT] / tests)) results[ResultsConstants.MIN_LATENCY_NS] = ( '{:.3f}'.format(results[ResultsConstants.MIN_LATENCY_NS] / tests)) results[ResultsConstants.MAX_LATENCY_NS] = ( '{:.3f}'.format(results[ResultsConstants.MAX_LATENCY_NS] / tests)) results[ResultsConstants.AVG_LATENCY_NS] = ( '{:.3f}'.format(results[ResultsConstants.AVG_LATENCY_NS] / tests)) return results
def send_cont_traffic(self, traffic=None, duration=20): """Send a continuous flow of traffic Send packets at ``frame rate``, using ``traffic`` configuration, until timeout ``time`` occurs. :param traffic: Detailed "traffic" spec, i.e. IP address, VLAN tags :param duration: Time to wait to receive packets (secs) :returns: dictionary of strings with following data: - Tx Throughput (fps), - Rx Throughput (fps), - Tx Throughput (mbps), - Rx Throughput (mbps), - Tx Throughput (% linerate), - Rx Throughput (% linerate), - Min Latency (ns), - Max Latency (ns), - Avg Latency (ns) """ self._logger.info("In Moongen send_cont_traffic method") self._params.clear() self._params['traffic'] = self.traffic_defaults.copy() if traffic: self._params['traffic'] = merge_spec(self._params['traffic'], traffic) Moongen.create_moongen_cfg_file(self, traffic, duration=duration, acceptable_loss_pct=100.0, one_shot=1) collected_results = Moongen.run_moongen_and_collect_results(self, test_run=1) results = OrderedDict() results[ResultsConstants.THROUGHPUT_RX_FPS] = ( '{:.6f}'.format( float(collected_results[ResultsConstants.THROUGHPUT_RX_FPS]))) results[ResultsConstants.THROUGHPUT_RX_MBPS] = ( '{:.3f}'.format( float(collected_results[ResultsConstants.THROUGHPUT_RX_MBPS]))) results[ResultsConstants.THROUGHPUT_RX_PERCENT] = ( '{:.3f}'.format( float( collected_results[ResultsConstants.THROUGHPUT_RX_PERCENT]))) results[ResultsConstants.TX_RATE_FPS] = ( '{:.3f}'.format( float(collected_results[ResultsConstants.TX_RATE_FPS]))) results[ResultsConstants.TX_RATE_MBPS] = ( '{:.3f}'.format( float(collected_results[ResultsConstants.TX_RATE_MBPS]))) results[ResultsConstants.TX_RATE_PERCENT] = ( '{:.3f}'.format( float(collected_results[ResultsConstants.TX_RATE_PERCENT]))) results[ResultsConstants.MIN_LATENCY_NS] = 0 results[ResultsConstants.MAX_LATENCY_NS] = 0 results[ResultsConstants.AVG_LATENCY_NS] = 0 return results