X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=testcases%2Ftestcase.py;h=0effce75abc16d583332f534815e0ef37fab2d9b;hb=refs%2Fchanges%2F63%2F11063%2F5;hp=d470d951551e093a2280198ffe48d9ac41ebb8de;hpb=da081ab2603eb34baf7d7fe7b61f681ef15d865e;p=vswitchperf.git diff --git a/testcases/testcase.py b/testcases/testcase.py index d470d951..0effce75 100644 --- a/testcases/testcase.py +++ b/testcases/testcase.py @@ -16,20 +16,19 @@ import csv import os +import time import logging import subprocess import copy -import time from collections import OrderedDict -from core.results.results_constants import ResultsConstants import core.component_factory as component_factory from core.loader import Loader +from core.results.results_constants import ResultsConstants from tools import tasks from tools import hugepages -from tools.report import report -from conf import settings as S from tools.pkt_gen.trafficgen.trafficgenhelper import TRAFFIC_DEFAULTS +from conf import settings as S from conf import get_test_param class TestCase(object): @@ -46,24 +45,44 @@ class TestCase(object): :param results_dir: Where the csv formatted results are written. """ 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 # 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 = cfg.get('biDirectional', False) + bidirectional = cfg.get('biDirectional', TRAFFIC_DEFAULTS['bidir']) bidirectional = get_test_param('bidirectional', bidirectional) - traffic_type = cfg.get('Traffic Type', 'rfc2544') + traffic_type = cfg.get('Traffic Type', TRAFFIC_DEFAULTS['traffic_type']) traffic_type = get_test_param('traffic_type', traffic_type) - framerate = cfg.get('iLoad', 100) + framerate = cfg.get('iLoad', TRAFFIC_DEFAULTS['frame_rate']) framerate = get_test_param('iload', framerate) 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) + + # identify guest loopback method, so it can be added into reports self.guest_loopback = [] if self.deployment in ['pvp', 'pvvp']: @@ -78,11 +97,11 @@ class TestCase(object): # read configuration of streams; CLI parameter takes precedence to # testcase definition - multistream = cfg.get('MultiStream', 0) + multistream = cfg.get('MultiStream', TRAFFIC_DEFAULTS['multistream']) multistream = get_test_param('multistream', multistream) - stream_type = cfg.get('Stream Type', 'L4') + stream_type = cfg.get('Stream Type', TRAFFIC_DEFAULTS['stream_type']) stream_type = get_test_param('stream_type', stream_type) - pre_installed_flows = cfg.get('Pre-installed Flows', 'No') + pre_installed_flows = cfg.get('Pre-installed Flows', TRAFFIC_DEFAULTS['pre_installed_flows']) pre_installed_flows = get_test_param('pre-installed_flows', pre_installed_flows) # check if test requires background load and which generator it uses @@ -100,8 +119,9 @@ class TestCase(object): # set traffic details, so they can be passed to vswitch and traffic ctls self._traffic = copy.deepcopy(TRAFFIC_DEFAULTS) self._traffic.update({'traffic_type': traffic_type, - 'flow_type': cfg.get('Flow Type', 'port'), + 'flow_type': cfg.get('Flow Type', TRAFFIC_DEFAULTS['flow_type']), 'bidir': bidirectional, + 'tunnel_type': self._tunnel_type, 'multistream': int(multistream), 'stream_type': stream_type, 'pre_installed_flows' : pre_installed_flows, @@ -117,10 +137,8 @@ class TestCase(object): # Packet Forwarding mode self._vswitch_none = 'none' == S.getValue('VSWITCH').strip().lower() - def run(self): - """Run the test - - All setup and teardown through controllers is included. + def run_initialize(self): + """ Prepare test execution environment """ self._logger.debug(self.name) @@ -130,36 +148,86 @@ class TestCase(object): # copy sources of l2 forwarding tools into VM shared dir if needed self._copy_fwd_tools_for_guest() + 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') + + self._logger.debug("Controllers:") loader = Loader() - traffic_ctl = component_factory.create_traffic( + self._traffic_ctl = component_factory.create_traffic( self._traffic['traffic_type'], loader.get_trafficgen_class()) - vnf_ctl = component_factory.create_vnf( + + self._vnf_ctl = component_factory.create_vnf( self.deployment, loader.get_vnf_class()) if self._vswitch_none: - vswitch_ctl = component_factory.create_pktfwd( + self._vswitch_ctl = component_factory.create_pktfwd( loader.get_pktfwd_class()) else: - vswitch_ctl = component_factory.create_vswitch( + self._vswitch_ctl = component_factory.create_vswitch( self.deployment, loader.get_vswitch_class(), - self._traffic) + self._traffic, + self._tunnel_operation) - collector = component_factory.create_collector( + self._collector = component_factory.create_collector( loader.get_collector_class(), self._results_dir, self.name) - loadgen = component_factory.create_loadgen( + self._loadgen = component_factory.create_loadgen( self._loadgen, self._load_cfg) + self._output_file = os.path.join(self._results_dir, "result_" + self.name + + "_" + self.deployment + ".csv") + self._logger.debug("Setup:") - with vswitch_ctl, loadgen: - with vnf_ctl, collector: + + def run_finalize(self): + """ Tear down test execution environment and record test results + """ + # umount hugepages if mounted + self._umount_hugepages() + + def run_report(self): + """ Report test results + """ + self._logger.debug("self._collector Results:") + self._collector.print_results() + + if S.getValue('mode') != 'trafficgen-off': + self._logger.debug("Traffic Results:") + self._traffic_ctl.print_results() + + self._tc_results = self._append_results(self._traffic_ctl.get_results()) + TestCase._write_result_to_file(self._tc_results, self._output_file) + + def run(self): + """Run the test + + All setup and teardown through controllers is included. + """ + # prepare test execution environment + self.run_initialize() + + with self._vswitch_ctl, self._loadgen: + with self._vnf_ctl, self._collector: if not self._vswitch_none: - self._add_flows(vswitch_ctl) + self._add_flows() # run traffic generator if requested, otherwise wait for manual termination if S.getValue('mode') == 'trafficgen-off': @@ -167,30 +235,28 @@ class TestCase(object): self._logger.debug("All is set. Please run traffic generator manually.") input(os.linesep + "Press Enter to terminate vswitchperf..." + os.linesep + os.linesep) else: - with traffic_ctl: - traffic_ctl.send_traffic(self._traffic) + if S.getValue('mode') == 'trafficgen-pause': + time.sleep(2) + true_vals = ('yes', 'y', 'ye', None) + while True: + choice = input(os.linesep + 'Transmission paused, should' + ' transmission be resumed? ' + os.linesep).lower() + if not choice or choice not in true_vals: + print('Please respond with \'yes\' or \'y\' ', end='') + else: + break + with self._traffic_ctl: + self._traffic_ctl.send_traffic(self._traffic) # dump vswitch flows before they are affected by VNF termination if not self._vswitch_none: - vswitch_ctl.dump_vswitch_flows() + self._vswitch_ctl.dump_vswitch_flows() - # umount hugepages if mounted - self._umount_hugepages() - - self._logger.debug("Collector Results:") - collector.print_results() - - if S.getValue('mode') != 'trafficgen-off': - self._logger.debug("Traffic Results:") - traffic_ctl.print_results() - - output_file = os.path.join(self._results_dir, "result_" + self.name + - "_" + self.deployment + ".csv") + # tear down test execution environment and log results + self.run_finalize() - tc_results = self._append_results(traffic_ctl.get_results()) - TestCase._write_result_to_file(tc_results, output_file) - - report.generate(output_file, tc_results, collector.get_results()) + # report test results + self.run_report() def _append_results(self, results): """ @@ -211,7 +277,8 @@ class TestCase(object): item[ResultsConstants.SCAL_PRE_INSTALLED_FLOWS] = self._traffic['pre_installed_flows'] if len(self.guest_loopback): item[ResultsConstants.GUEST_LOOPBACK] = ' '.join(self.guest_loopback) - + if self._tunnel_type: + item[ResultsConstants.TUNNEL_TYPE] = self._tunnel_type return results def _copy_fwd_tools_for_guest(self): @@ -222,9 +289,13 @@ class TestCase(object): while counter < self.deployment.count('v'): guest_dir = S.getValue('GUEST_SHARE_DIR')[counter] - # create shared dir if it doesn't exist - if not os.path.exists(guest_dir): - os.makedirs(guest_dir) + # remove shared dir if it exists to avoid issues with file consistency + if os.path.exists(guest_dir): + tasks.run_task(['rm', '-f', '-r', guest_dir], self._logger, + 'Removing content of shared directory...', True) + + # directory to share files between host and guest + os.makedirs(guest_dir) # copy sources into shared dir only if neccessary if 'testpmd' in self.guest_loopback or 'l2fwd' in self.guest_loopback: @@ -288,7 +359,6 @@ class TestCase(object): for result in results: writer.writerow(result) - @staticmethod def _get_unique_keys(list_of_dicts): """Gets unique key values as ordered list of strings in given dicts @@ -304,13 +374,10 @@ class TestCase(object): return list(result.keys()) - - def _add_flows(self, vswitch_ctl): + def _add_flows(self): """Add flows to the vswitch - - :param vswitch_ctl vswitch controller """ - vswitch = vswitch_ctl.get_vswitch() + vswitch = self._vswitch_ctl.get_vswitch() # TODO BOM 15-08-07 the frame mod code assumes that the # physical ports are ports 1 & 2. The actual numbers # need to be retrived from the vSwitch and the metadata value