Beispiel #1
0
    def __init__(self,
                 logger,
                 server,
                 port=80,
                 user_name=getpass.getuser(),
                 session_name=None):
        """ Init STC REST client.

        :param server: STC REST API server address.
        :param port: STC REST API HTTP port.
        :param user_name: user name, part of session ID.
        :param session_name: session, name part of session ID.

        Add logger to log STC REST commands only.
        This creates a clean REST script that can be used later for debug.
        """

        super(self.__class__, self).__init__()
        debug_print = True if logger.level == 10 else False
        self.ls = stchttp.StcHttp(server, port, debug_print=debug_print)
        if session_name:
            self.session_id = self.ls.join_session(session_name)
        else:
            session_name = 'session' + str(randint(0, 99))
            self.session_id = self.ls.new_session(user_name,
                                                  session_name,
                                                  kill_existing=True)
Beispiel #2
0
    def connect(self):
        addr, port = self._config['stc_server_addr'], self._config[
            'stc_server_port']
        log.info('Connecting to: {}:{}'.format(addr, port))
        self._stc = stchttp.StcHttp(addr, port=port, debug_print=self._verbose)

        if self._state['sid']:
            log.info('Joining existing session {}'.format(self._state['sid']))
            self._stc.join_session(self._state['sid'])
        else:
            sid = ''.join([choice(lowercase) for i in range(10)])
            log.info('Creating new session, "{}" for user {}.'.format(
                sid, self._state['user']))
            self._state['sid'] = self._stc.new_session(self._state['user'],
                                                       sid)

        self._stc.apply()

        chas_addr = self._state['chassis_addr']
        log.info('Connecting to chassis at {}'.format(chas_addr))
        # stc.connect wants a list of addresses for some reason.
        self._stc.connect([chas_addr])
        log.info('Connected.')

        # If not configured with an existing project, create a new one.
        if not self.project_handle:
            log.info('creating new project.')
            data = self._stc.createx('project')
            log.info('created project: {}'.format(
                json.dumps(data, indent=4, sort_keys=True)))
            self._state['project_handle'] = data['handle']
Beispiel #3
0
    def __init__(self, labserver_addr, user_name, session_name):
        self.logger = logging.getLogger(__name__)

        # create connection obj
        self.stc = stchttp.StcHttp(labserver_addr)
        self.user_name = user_name
        self.session_name = session_name

        # create session on labserver
        self.session_id = self.stc.new_session(self.user_name, self.session_name)
        self.stc.join_session(self.session_id)
        return
Beispiel #4
0
    def __init__(self, labserver_ip, user_name, stcv_west_mgmt_ip,
                 stcv_west_test_port_ip, stcv_east_mgmt_ip,
                 stcv_east_test_port_ip, dut_left_ip, dut_right_ip):
        self.labserver_ip = labserver_ip
        self.user_name = user_name
        self.result1 = None
        self.result2 = None
        self.testpass = None

        self.west_stcv = {
            "mgmt_ip": stcv_west_mgmt_ip,
            "test_port_ip": stcv_west_test_port_ip,
            "gw_ip": dut_left_ip,
            "port_location": "//" + stcv_west_mgmt_ip + "/1/1",
            "port": None,
            "gen": None,
            "ana": None,
            "result": None
        }
        self.east_stcv = {
            "mgmt_ip": stcv_east_mgmt_ip,
            "test_port_ip": stcv_east_test_port_ip,
            "gw_ip": dut_right_ip,
            "port_location": "//" + stcv_east_mgmt_ip + "/1/1",
            "port": None,
            "gen": None,
            "ana": None,
            "result": None
        }

        self.stc = stchttp.StcHttp(labserver_ip, port=80)

        #self.user_name = "csu_user"
        time_str = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
        test_name = "simpletraffic - " + time_str
        sess_id = self.user_name + " - " + test_name
        sess_list = self.stc.sessions()
        logger.debug("sess_list: %s", sess_list)
        if sess_id not in sess_list:
            sess_id = self.stc.new_session(self.user_name, test_name)
        self.stc.join_session(sess_id)

        self.sys = "system1"
        self.project = self.stc.get(self.sys, "children-project")

        return
Beispiel #5
0
    def __init__(self, logger: logging.Logger, server, port=80, user_name=getpass.getuser(), session_name=None):
        """Init STC REST client.

        :TODO: Add logger to log STC REST commands only. This creates a clean REST script that can be used later for debug.

        :param logger: Package logger.
        :param server: STC REST API server address.
        :param port: STC REST API HTTP port.
        :param user_name: user name, part of session ID.
        :param session_name: session, name part of session ID.
        """
        debug_print = logger.level == 10
        self.client = stchttp.StcHttp(server, port, debug_print=debug_print)
        if session_name:
            self.session_id = self.client.join_session(session_name)
        else:
            session_name = "session" + str(randint(0, 99))
            self.session_id = self.client.new_session(user_name, session_name, kill_existing=True)
        self.command_rc = None
Beispiel #6
0
    def __init__(self, lab_server_addr, lab_server_port=80):
        try:
            self.stc = stchttp.StcHttp(lab_server_addr, port=lab_server_port)
        except Exception as e:
            LOG.exception(e)
            raise StcTrafficAdapterError('Unable to create adapter - %s' % e)
        self.session = None
        self.project = None
        self.tx_results = None
        self.rx_results = None
        self.tx_port = None
        self.rx_port = None
        self.stream_block = None
        self.arp_needed = None

        self._attempt_to_start_traffic = False
        self._traffic_attempt_lock = Lock()

        self._emission_started = False
        self._emission_lock = Lock()

        self._service_disruption_length = None
        self._service_disruption_lock = Lock()
from __future__ import print_function
import sys
from stcrestclient import stchttp

if len(sys.argv) < 2:
    print('usage: python', sys.argv[0], 'server_addr', file=sys.stderr)
    sys.exit(1)

try:
    stc = stchttp.StcHttp(sys.argv[1])

    # List all current STC sessions.
    sessions = stc.sessions()
    for session in sessions:
        print(' ' * 4, session)

except Exception as e:
    print(e, file=sys.stderr)
    sys.exit(1)
def main():
    """ Read the arguments, Invoke Test and Return the results"""
    parser = argparse.ArgumentParser()
    # Required parameters
    required_named = parser.add_argument_group("required named arguments")
    required_named.add_argument("--lab_server_addr",
                                required=True,
                                help=("The IP address of the"
                                      "Spirent Lab Server"),
                                dest="lab_server_addr")
    required_named.add_argument("--license_server_addr",
                                required=True,
                                help=("The IP address of the Spirent"
                                      "License Server"),
                                dest="license_server_addr")
    required_named.add_argument("--east_chassis_addr",
                                required=True,
                                help=("The TestCenter chassis IP address to"
                                      "use for the east test port"),
                                dest="east_chassis_addr")
    required_named.add_argument("--east_slot_num",
                                type=positive_int,
                                required=True,
                                help=("The TestCenter slot number to"
                                      "use for the east test port"),
                                dest="east_slot_num")
    required_named.add_argument("--east_port_num",
                                type=positive_int,
                                required=True,
                                help=("The TestCenter port number to use"
                                      "for the east test port"),
                                dest="east_port_num")
    required_named.add_argument("--west_chassis_addr",
                                required=True,
                                help=("The TestCenter chassis IP address"
                                      "to use for the west test port"),
                                dest="west_chassis_addr")
    required_named.add_argument("--west_slot_num",
                                type=positive_int,
                                required=True,
                                help=("The TestCenter slot number to use"
                                      "for the west test port"),
                                dest="west_slot_num")
    required_named.add_argument("--west_port_num",
                                type=positive_int,
                                required=True,
                                help=("The TestCenter port number to"
                                      "use for the west test port"),
                                dest="west_port_num")
    # Optional parameters
    optional_named = parser.add_argument_group("optional named arguments")
    optional_named.add_argument(
        "--metric",
        required=False,
        help=("One among - throughput, latency,\
                                      backtoback and frameloss"),
        choices=["throughput", "latency", "backtoback", "frameloss"],
        default="throughput",
        dest="metric")
    optional_named.add_argument("--test_session_name",
                                required=False,
                                default="RFC2544 East-West Throughput",
                                help=("The friendly name to identify"
                                      "the Spirent Lab Server test session"),
                                dest="test_session_name")

    optional_named.add_argument("--test_user_name",
                                required=False,
                                default="RFC2544 East-West User",
                                help=("The friendly name to identify the"
                                      "Spirent Lab Server test user"),
                                dest="test_user_name")
    optional_named.add_argument("--results_dir",
                                required=False,
                                default="./Results",
                                help="The directory to copy results to",
                                dest="results_dir")
    optional_named.add_argument("--vsperf_results_dir",
                                required=False,
                                default="./Results",
                                help="The directory to copy results to",
                                dest="vsperf_results_dir")
    optional_named.add_argument("--csv_results_file_prefix",
                                required=False,
                                default="Rfc2544Tput",
                                help="The prefix for the CSV results files",
                                dest="csv_results_file_prefix")
    optional_named.add_argument("--num_trials",
                                type=positive_int,
                                required=False,
                                default=1,
                                help=("The number of trials to execute during"
                                      "the test"),
                                dest="num_trials")
    optional_named.add_argument("--trial_duration_sec",
                                type=positive_int,
                                required=False,
                                default=60,
                                help=("The duration of each trial executed"
                                      "during the test"),
                                dest="trial_duration_sec")
    optional_named.add_argument("--traffic_pattern",
                                required=False,
                                choices=["BACKBONE", "MESH", "PAIR"],
                                default="PAIR",
                                help="The traffic pattern between endpoints",
                                dest="traffic_pattern")
    optional_named.add_argument("--traffic_custom",
                                required=False,
                                default=None,
                                help="The traffic pattern between endpoints",
                                dest="traffic_custom")
    optional_named.add_argument("--search_mode",
                                required=False,
                                choices=["COMBO", "STEP", "BINARY"],
                                default="BINARY",
                                help=("The search mode used to find the"
                                      "throughput rate"),
                                dest="search_mode")
    optional_named.add_argument(
        "--learning_mode",
        required=False,
        choices=["AUTO", "L2_LEARNING", "L3_LEARNING", "NONE"],
        default="AUTO",
        help=("The learning mode used during the test,"
              "default is 'NONE'"),
        dest="learning_mode")
    optional_named.add_argument("--rate_lower_limit_pct",
                                type=percent_float,
                                required=False,
                                default=1.0,
                                help=("The minimum percent line rate that"
                                      "will be used during the test"),
                                dest="rate_lower_limit_pct")
    optional_named.add_argument("--rate_upper_limit_pct",
                                type=percent_float,
                                required=False,
                                default=99.0,
                                help=("The maximum percent line rate that"
                                      "will be used during the test"),
                                dest="rate_upper_limit_pct")
    optional_named.add_argument("--rate_initial_pct",
                                type=percent_float,
                                required=False,
                                default=99.0,
                                help=("If Search Mode is BINARY, the percent"
                                      "line rate that will be used at the"
                                      "start of the test"),
                                dest="rate_initial_pct")
    optional_named.add_argument("--rate_step_pct",
                                type=percent_float,
                                required=False,
                                default=10.0,
                                help=("If SearchMode is STEP, the percent"
                                      "load increase per step"),
                                dest="rate_step_pct")
    optional_named.add_argument("--resolution_pct",
                                type=percent_float,
                                required=False,
                                default=1.0,
                                help=("The minimum percentage of load"
                                      "adjustment between iterations"),
                                dest="resolution_pct")
    optional_named.add_argument(
        "--frame_size_list",
        type=lambda s: [int(item) for item in s.split(',')],
        required=False,
        default=[256],
        help="A comma-delimited list of frame sizes",
        dest="frame_size_list")
    optional_named.add_argument("--acceptable_frame_loss_pct",
                                type=percent_float,
                                required=False,
                                default=0.0,
                                help=("The maximum acceptable frame loss"
                                      "percent in any iteration"),
                                dest="acceptable_frame_loss_pct")
    optional_named.add_argument("--east_intf_addr",
                                required=False,
                                default="192.85.1.3",
                                help=("The address to assign to the first"
                                      "emulated device interface on the first"
                                      "east port"),
                                dest="east_intf_addr")
    optional_named.add_argument("--east_intf_gateway_addr",
                                required=False,
                                default="192.85.1.53",
                                help=("The gateway address to assign to the"
                                      "first emulated device interface on the"
                                      "first east port"),
                                dest="east_intf_gateway_addr")
    optional_named.add_argument("--west_intf_addr",
                                required=False,
                                default="192.85.1.53",
                                help=("The address to assign to the first"
                                      "emulated device interface on the"
                                      "first west port"),
                                dest="west_intf_addr")
    optional_named.add_argument("--west_intf_gateway_addr",
                                required=False,
                                default="192.85.1.53",
                                help=("The gateway address to assign to"
                                      "the first emulated device interface"
                                      "on the first west port"),
                                dest="west_intf_gateway_addr")
    optional_named.add_argument(
        "--latency_histogram",
        required=False,
        action="store_true",
        help="latency histogram is required in output?",
        dest="latency_histogram")
    optional_named.add_argument("--imix",
                                required=False,
                                default="",
                                help=("IMIX specification as genome"
                                      "Encoding - RFC 6985"),
                                dest="imix")
    optional_named.add_argument("--live_results",
                                required=False,
                                action="store_true",
                                help="Live Results required?",
                                dest="live_results")
    optional_named.add_argument("--logfile",
                                required=False,
                                default="./traffic_gen.log",
                                help="Log file to log live results",
                                dest="logfile")
    parser.add_argument("-v",
                        "--verbose",
                        required=False,
                        default=True,
                        help="More output during operation when present",
                        action="store_true",
                        dest="verbose")
    args = parser.parse_args()

    if args.verbose:
        _LOGGER.debug("Creating results directory")
    create_dir(args.results_dir)

    session_name = args.test_session_name
    user_name = args.test_user_name
    # pylint: disable=import-error
    try:
        # Load Spirent REST Library
        from stcrestclient import stchttp

        stc = stchttp.StcHttp(args.lab_server_addr)
        session_id = stc.new_session(user_name, session_name)
        stc.join_session(session_id)
    except RuntimeError as err:
        _LOGGER.error(err)
        raise

    # Get STC system info.
    tx_port_loc = "//%s/%s/%s" % (args.east_chassis_addr, args.east_slot_num,
                                  args.east_port_num)
    rx_port_loc = "//%s/%s/%s" % (args.west_chassis_addr, args.west_slot_num,
                                  args.west_port_num)

    # Retrieve and display the server information
    if args.verbose:
        _LOGGER.debug("SpirentTestCenter system version: %s",
                      stc.get("system1", "version"))

    # pylint: disable=too-many-nested-blocks
    try:
        device_list = []
        port_list = []
        if args.verbose:
            _LOGGER.debug("Bring up license server")
        license_mgr = stc.get("system1", "children-licenseservermanager")
        if args.verbose:
            _LOGGER.debug("license_mgr = %s", license_mgr)
        stc.create("LicenseServer",
                   under=license_mgr,
                   attributes={"server": args.license_server_addr})

        # Create the root project object
        if args.verbose:
            _LOGGER.debug("Creating project ...")
        project = stc.get("System1", "children-Project")

        # Configure the Result view
        resultopts = stc.get('project1', 'children-resultoptions')
        stc.config(resultopts, {'ResultViewMode': 'BASIC'})

        # Configure any custom traffic parameters
        if args.traffic_custom == "cont":
            if args.verbose:
                _LOGGER.debug("Configure Continuous Traffic")
            stc.create("ContinuousTestConfig", under=project)

        # Create ports
        if args.verbose:
            _LOGGER.debug("Creating ports ...")
        east_chassis_port = stc.create('port', project)
        if args.verbose:
            _LOGGER.debug("Configuring TX port ...")
        stc.config(east_chassis_port, {'location': tx_port_loc})
        port_list.append(east_chassis_port)

        west_chassis_port = stc.create('port', project)
        if args.verbose:
            _LOGGER.debug("Configuring RX port ...")
        stc.config(west_chassis_port, {'location': rx_port_loc})
        port_list.append(west_chassis_port)

        # Create emulated genparam for east port
        east_device_gen_params = stc.create(
            "EmulatedDeviceGenParams",
            under=project,
            attributes={"Port": east_chassis_port})
        # Create the DeviceGenEthIIIfParams object
        stc.create("DeviceGenEthIIIfParams",
                   under=east_device_gen_params,
                   attributes={'UseDefaultPhyMac': True})

        # Configuring Ipv4 interfaces
        stc.create("DeviceGenIpv4IfParams",
                   under=east_device_gen_params,
                   attributes={
                       "Addr": args.east_intf_addr,
                       "Gateway": args.east_intf_gateway_addr
                   })
        # Create Devices using the Device Wizard
        device_gen_config = stc.perform("DeviceGenConfigExpand",
                                        params={
                                            "DeleteExisting": "No",
                                            "GenParams": east_device_gen_params
                                        })
        # Append to the device list
        device_list.append(device_gen_config['ReturnList'])

        # Create emulated genparam for west port
        west_device_gen_params = stc.create(
            "EmulatedDeviceGenParams",
            under=project,
            attributes={"Port": west_chassis_port})
        # Create the DeviceGenEthIIIfParams object
        stc.create("DeviceGenEthIIIfParams",
                   under=west_device_gen_params,
                   attributes={'UseDefaultPhyMac': True})

        # Configuring Ipv4 interfaces
        stc.create("DeviceGenIpv4IfParams",
                   under=west_device_gen_params,
                   attributes={
                       "Addr": args.west_intf_addr,
                       "Gateway": args.west_intf_gateway_addr
                   })
        # Create Devices using the Device Wizard
        device_gen_config = stc.perform("DeviceGenConfigExpand",
                                        params={
                                            "DeleteExisting": "No",
                                            "GenParams": west_device_gen_params
                                        })
        # Append to the device list
        device_list.append(device_gen_config['ReturnList'])
        if args.verbose:
            _LOGGER.debug(device_list)

        # Configure Histogram
        if args.latency_histogram:
            # Generic Configuration
            histResOptions = stc.get("project1", 'children-ResultOptions')
            stc.config(histResOptions, {'ResultViewMode': 'HISTOGRAM'})
            # East Port Configuration
            histAnaEast = stc.get(east_chassis_port, 'children-Analyzer')
            histAnaEastConfig = stc.get(histAnaEast, 'children-AnalyzerConfig')
            stc.config(histAnaEastConfig, {'HistogramMode': 'LATENCY'})
            eLatHist = stc.get(histAnaEastConfig, 'children-LatencyHistogram')
            stc.config(
                eLatHist, {
                    'ConfigMode': 'CONFIG_LIMIT_MODE',
                    'BucketSizeUnit': 'ten_nanoseconds',
                    'Active': 'TRUE',
                    'DistributionMode': 'CENTERED_MODE'
                })
            # West Port Configuration
            histAnaWest = stc.get(west_chassis_port, 'children-Analyzer')
            histAnaWestConfig = stc.get(histAnaWest, 'children-AnalyzerConfig')
            stc.config(histAnaWestConfig, {'HistogramMode': 'LATENCY'})
            wLatHist = stc.get(histAnaWestConfig, 'children-LatencyHistogram')
            stc.config(
                wLatHist, {
                    'ConfigMode': 'CONFIG_LIMIT_MODE',
                    'BucketSizeUnit': 'ten_nanoseconds',
                    'Active': 'TRUE',
                    'DistributionMode': 'CENTERED_MODE'
                })
            gBucketSizeList = stc.get(wLatHist, 'BucketSizeList')
            # gLimitSizeList  = stc.get(wLatHist, 'LimitList')

        # IMIX configuration
        fld = None
        if args.imix:
            args.frame_size_list = []
            weights = genome2weights(args.imix)
            fld = stc.create('FrameLengthDistribution', under=project)
            def_slots = stc.get(fld, "children-framelengthdistributionslot")
            stc.perform("Delete", params={"ConfigList": def_slots})
            for fsize in weights:
                stc.create('framelengthdistributionslot',
                           under=fld,
                           attributes={
                               'FixedFrameLength': fsize,
                               'Weight': weights[fsize]
                           })

        # Create the RFC 2544 'metric test
        if args.metric == "throughput":
            if args.verbose:
                _LOGGER.debug("Set up the RFC2544 throughput test...")
            stc.perform("Rfc2544SetupThroughputTestCommand",
                        params={
                            "AcceptableFrameLoss":
                            args.acceptable_frame_loss_pct,
                            "Duration": args.trial_duration_sec,
                            "FrameSizeList": args.frame_size_list,
                            "LearningMode": args.learning_mode,
                            "NumOfTrials": args.num_trials,
                            "RateInitial": args.rate_initial_pct,
                            "RateLowerLimit": args.rate_lower_limit_pct,
                            "RateStep": args.rate_step_pct,
                            "RateUpperLimit": args.rate_upper_limit_pct,
                            "Resolution": args.resolution_pct,
                            "SearchMode": args.search_mode,
                            "TrafficPattern": args.traffic_pattern,
                            "FrameSizeDistributionList": fld
                        })
        elif args.metric == "backtoback":
            stc.perform("Rfc2544SetupBackToBackTestCommand",
                        params={
                            "AcceptableFrameLoss":
                            args.acceptable_frame_loss_pct,
                            "Duration": args.trial_duration_sec,
                            "FrameSizeList": args.frame_size_list,
                            "LearningMode": args.learning_mode,
                            "LatencyType": args.latency_type,
                            "NumOfTrials": args.num_trials,
                            "RateInitial": args.rate_initial_pct,
                            "RateLowerLimit": args.rate_lower_limit_pct,
                            "RateStep": args.rate_step_pct,
                            "RateUpperLimit": args.rate_upper_limit_pct,
                            "Resolution": args.resolution_pct,
                            "SearchMode": args.search_mode,
                            "TrafficPattern": args.traffic_pattern
                        })
        elif args.metric == "frameloss":
            stc.perform("Rfc2544SetupFrameLossTestCommand",
                        params={
                            "AcceptableFrameLoss":
                            args.acceptable_frame_loss_pct,
                            "Duration": args.trial_duration_sec,
                            "FrameSizeList": args.frame_size_list,
                            "LearningMode": args.learning_mode,
                            "LatencyType": args.latency_type,
                            "NumOfTrials": args.num_trials,
                            "RateInitial": args.rate_initial_pct,
                            "RateLowerLimit": args.rate_lower_limit_pct,
                            "RateStep": args.rate_step_pct,
                            "RateUpperLimit": args.rate_upper_limit_pct,
                            "Resolution": args.resolution_pct,
                            "SearchMode": args.search_mode,
                            "TrafficPattern": args.traffic_pattern
                        })
        elif args.metric == "latency":
            stc.perform("Rfc2544SetupLatencyTestCommand",
                        params={
                            "AcceptableFrameLoss":
                            args.acceptable_frame_loss_pct,
                            "Duration": args.trial_duration_sec,
                            "FrameSizeList": args.frame_size_list,
                            "LearningMode": args.learning_mode,
                            "LatencyType": args.latency_type,
                            "NumOfTrials": args.num_trials,
                            "RateInitial": args.rate_initial_pct,
                            "RateLowerLimit": args.rate_lower_limit_pct,
                            "RateStep": args.rate_step_pct,
                            "RateUpperLimit": args.rate_upper_limit_pct,
                            "Resolution": args.resolution_pct,
                            "SearchMode": args.search_mode,
                            "TrafficPattern": args.traffic_pattern
                        })

        # Save the configuration
        stc.perform("SaveToTcc", params={"Filename": "2544.tcc"})
        # Connect to the hardware...
        stc.perform("AttachPorts",
                    params={
                        "portList": stc.get("system1.project",
                                            "children-port"),
                        "autoConnect": "TRUE"
                    })
        # Apply configuration.
        if args.verbose:
            _LOGGER.debug("Apply configuration...")
        stc.apply()

        # Register for the results
        hResDataRx = stc.create('ResultDataSet', under='project1')
        strmBlockList = stc.get('project1', 'children-streamblock')
        stc.create('ResultQuery',
                   under=hResDataRx,
                   attributes={
                       'ResultRootList':
                       strmBlockList,
                       'ConfigClassId':
                       'StreamBlock',
                       'ResultClassId':
                       'RxStreamSummaryResults',
                       'PropertyIdArray':
                       "RxStreamSummaryResults.RxPort \
                                RxStreamSummaryResults.AvgLatency \
                                RxStreamSummaryResults.BitCount \
                                RxStreamSummaryResults.BitRate \
                                RxStreamSummaryResults.DroppedFrameCount\
                                RxStreamSummaryResults.DroppedFrameRate \
                                RxStreamSummaryResults.FrameCount \
                                RxStreamSummaryResults.FrameRate \
                                RxStreamSummaryResults.MaxLatency \
                                RxStreamSummaryResults.MinLatency \
                                RxStreamSummaryResults.OctetCount \
                                RxStreamSummaryResults.OctetRate \
                                RxStreamSummaryResults.SeqRunLength"
                   })
        hResDataTx = stc.create('ResultDataSet', under='project1')
        strmBlockList = stc.get('project1', 'children-streamblock')
        stc.create('ResultQuery',
                   under=hResDataTx,
                   attributes={
                       'ResultRootList':
                       strmBlockList,
                       'ConfigClassId':
                       'StreamBlock',
                       'ResultClassId':
                       'TxStreamResults',
                       'PropertyIdArray':
                       "TxStreamResults.BlockId \
                                TxStreamResults.BitCount \
                                TxStreamResults.BitRate \
                                TxStreamResults.FrameCount \
                                TxStreamResults.FrameRate \
                                TxStreamResults.OctetCount \
                                TxStreamResults.OctetRate"
                   })
        stc.perform('ResultDataSetSubscribe',
                    params={'ResultDataSet': hResDataRx})
        stc.perform('ResultDataSetSubscribe',
                    params={'ResultDataSet': hResDataTx})
        time.sleep(3)
        stc.perform('RefreshResultView', params={'ResultDataSet': hResDataTx})
        hndListRx = stc.get(hResDataRx, 'ResultHandleList')
        hndListTx = stc.get(hResDataTx, 'ResultHandleList')

        if args.verbose:
            _LOGGER.debug("Starting the sequencer...")
        stc.perform("SequencerStart")

        sequencer = stc.get("system1", "children-sequencer")
        state = stc.get(sequencer, 'State')

        # If Live-results are required, we don't wait for the test to complete
        if args.live_results:
            write_headers(args.vsperf_results_dir, args.logfile, '.rx')
            write_headers(args.vsperf_results_dir, args.logfile, '.tx')
            while state != 'IDLE':
                state = stc.get(sequencer, 'State')
                hndListTx = stc.get(hResDataTx, 'ResultHandleList')
                if hndListTx:
                    handles = hndListTx.split(' ')
                    for handle in handles:
                        tx_values = stc.get(handle)
                        write_tx_live_results_to_file(args.vsperf_results_dir,
                                                      args.logfile, tx_values)
                if hndListRx:
                    handles = hndListRx.split(' ')
                    for handle in handles:
                        rx_values = stc.get(handle)
                        write_rx_live_results_to_file(args.vsperf_results_dir,
                                                      args.logfile, rx_values)
                time.sleep(1)
        # Live results not needed, so just wait!
        else:
            # Wait for sequencer to finish
            _LOGGER.info(
                "Starting test... Please wait for the test to complete...")
            stc.wait_until_complete()

        _LOGGER.info("The test has completed... Saving results...")

        # Determine what the results database filename is...
        lab_server_resultsdb = stc.get("system1.project.TestResultSetting",
                                       "CurrentResultFileName")

        if not lab_server_resultsdb or 'Results' not in lab_server_resultsdb:
            _LOGGER.info("Failed to find results.")
            stc.end_session()
            return

        if args.verbose:
            _LOGGER.debug("The lab server results database is %s",
                          lab_server_resultsdb)

        # Create Latency Histogram CSV file()
        if args.latency_histogram:
            hist_dict_counts = {}
            for file_url in stc.files():
                if '-FrameSize-' in file_url:
                    stc.download(file_url)
                    filename = file_url.split('/')[-1]
                    if os.path.exists(os.getcwd() + '/' + filename):
                        conn = sqlite3.connect(os.getcwd() + '/' + filename)
                        # cursor = conn.execute(
                        #    'select * from RxEotStreamResults')
                        # names = [desc[0] for desc in cursor.description]
                        counts = conn.execute("SELECT \
                                              HistBin1Count, HistBin2Count,\
                                              HistBin3Count, HistBin4Count,\
                                              HistBin5Count, HistBin6Count,\
                                              HistBin7Count, HistBin8Count,\
                                              HistBin9Count, HistBin10Count,\
                                              HistBin11Count, HistBin12Count,\
                                              HistBin13Count, HistBin14Count, \
                                              HistBin15Count, HistBin16Count \
                                              from RxEotStreamResults")
                        strs = filename.split('-')
                        key = strs[strs.index('FrameSize') + 1]
                        if key in hist_dict_counts:
                            hist_dict_counts[key] = [
                                a + b for a, b in zip(counts.fetchone(),
                                                      hist_dict_counts[key])
                            ]
                        else:
                            hist_dict_counts[key] = counts.fetchone()
                        conn.close()

            write_histogram_to_csv(args.vsperf_results_dir, 'Histogram',
                                   hist_dict_counts, gBucketSizeList)

        stc.perform("CSSynchronizeFiles",
                    params={"DefaultDownloadDir": args.results_dir})

        resultsdb = args.results_dir + \
            lab_server_resultsdb.split("/Results")[1]

        if not os.path.exists(resultsdb):
            resultsdb = lab_server_resultsdb
            _LOGGER.info("Failed to create the local summary DB File, using"
                         " the remote DB file instead.")
        else:
            _LOGGER.info("The local summary DB file has been saved to %s",
                         resultsdb)

        # The returns the "RFC2544ThroughputTestResultDetailedSummaryView"
        # table view from the results database.
        # There are other views available.

        if args.metric == "throughput":
            resultsdict = (stc.perform(
                "QueryResult",
                params={
                    "DatabaseConnectionString":
                    resultsdb,
                    "ResultPath": ("RFC2544ThroughputTestResultDetailed"
                                   "SummaryView")
                }))

        # The returns the "RFC2544BacktoBackTestResultDetailedSummaryView"
        # table view from the results database.
        # There are other views available.
        elif args.metric == "backtoback":
            resultsdict = (stc.perform(
                "QueryResult",
                params={
                    "DatabaseConnectionString":
                    resultsdb,
                    "ResultPath": ("RFC2544Back2BackTestResultDetailed"
                                   "SummaryView")
                }))

        # The returns the "RFC2544LatencyTestResultDetailedSummaryView"
        # table view from the results database.
        # There are other views available.
        elif args.metric == "latency":
            resultsdict = (stc.perform("QueryResult",
                                       params={
                                           "DatabaseConnectionString":
                                           resultsdb,
                                           "ResultPath":
                                           ("RFC2544LatencyTestResultDetailed"
                                            "SummaryView")
                                       }))

        # The returns the "RFC2544FrameLossTestResultDetailedSummaryView"
        # table view from the results database.
        # There are other views available.
        elif args.metric == "frameloss":
            resultsdict = (stc.perform(
                "QueryResult",
                params={
                    "DatabaseConnectionString":
                    resultsdb,
                    "ResultPath": ("RFC2544FrameLossTestResultDetailed"
                                   "SummaryView")
                }))
        if args.verbose:
            _LOGGER.debug("resultsdict[\"Columns\"]: %s",
                          resultsdict["Columns"])
            _LOGGER.debug("resultsdict[\"Output\"]: %s", resultsdict["Output"])
            _LOGGER.debug("Result paths: %s",
                          stc.perform("GetTestResultSettingPaths"))

            # Write results to csv
            _LOGGER.debug("Writing CSV file to results directory %s",
                          args.results_dir)
        write_query_results_to_csv(args.results_dir,
                                   args.csv_results_file_prefix, resultsdict)

    except RuntimeError as e:
        stc.end_session()
        _LOGGER.error(e)

    if args.verbose:
        _LOGGER.debug("Destroy session on lab server")
    stc.end_session()

    _LOGGER.info("Test complete!")
def main():
    """ Read the arguments, Invoke Test and Return the results"""
    parser = argparse.ArgumentParser()
    # Required parameters
    required_named = parser.add_argument_group("required named arguments")
    required_named.add_argument("--lab_server_addr",
                                required=True,
                                help=("The IP address of the"
                                      "Spirent Lab Server"),
                                dest="lab_server_addr")
    required_named.add_argument("--license_server_addr",
                                required=True,
                                help=("The IP address of the Spirent"
                                      "License Server"),
                                dest="license_server_addr")
    required_named.add_argument("--east_chassis_addr",
                                required=True,
                                help=("The TestCenter chassis IP address to"
                                      "use for the east test port"),
                                dest="east_chassis_addr")
    required_named.add_argument("--east_slot_num",
                                type=positive_int,
                                required=True,
                                help=("The TestCenter slot number to"
                                      "use for the east test port"),
                                dest="east_slot_num")
    required_named.add_argument("--east_port_num",
                                type=positive_int,
                                required=True,
                                help=("The TestCenter port number to use"
                                      "for the east test port"),
                                dest="east_port_num")
    required_named.add_argument("--west_chassis_addr",
                                required=True,
                                help=("The TestCenter chassis IP address"
                                      "to use for the west test port"),
                                dest="west_chassis_addr")
    required_named.add_argument("--west_slot_num",
                                type=positive_int,
                                required=True,
                                help=("The TestCenter slot number to use"
                                      "for the west test port"),
                                dest="west_slot_num")
    required_named.add_argument("--west_port_num",
                                type=positive_int,
                                required=True,
                                help=("The TestCenter port number to"
                                      "use for the west test port"),
                                dest="west_port_num")
    # Optional parameters
    optional_named = parser.add_argument_group("optional named arguments")
    optional_named.add_argument("--metric",
                                required=False,
                                help=("One among - throughput, latency,\
                                      backtoback and frameloss"),
                                choices=["throughput", "latency",
                                         "backtoback", "frameloss"],
                                default="throughput",
                                dest="metric")
    optional_named.add_argument("--test_session_name",
                                required=False,
                                default="RFC2544 East-West Throughput",
                                help=("The friendly name to identify"
                                      "the Spirent Lab Server test session"),
                                dest="test_session_name")

    optional_named.add_argument("--test_user_name",
                                required=False,
                                default="RFC2544 East-West User",
                                help=("The friendly name to identify the"
                                      "Spirent Lab Server test user"),
                                dest="test_user_name")
    optional_named.add_argument("--results_dir",
                                required=False,
                                default="./Results",
                                help="The directory to copy results to",
                                dest="results_dir")
    optional_named.add_argument("--csv_results_file_prefix",
                                required=False,
                                default="Rfc2544Tput",
                                help="The prefix for the CSV results files",
                                dest="csv_results_file_prefix")
    optional_named.add_argument("--num_trials",
                                type=positive_int,
                                required=False,
                                default=1,
                                help=("The number of trials to execute during"
                                      "the test"),
                                dest="num_trials")
    optional_named.add_argument("--trial_duration_sec",
                                type=positive_int,
                                required=False,
                                default=60,
                                help=("The duration of each trial executed"
                                      "during the test"),
                                dest="trial_duration_sec")
    optional_named.add_argument("--traffic_pattern",
                                required=False,
                                choices=["BACKBONE", "MESH", "PAIR"],
                                default="PAIR",
                                help="The traffic pattern between endpoints",
                                dest="traffic_pattern")
    optional_named.add_argument("--traffic_custom",
                                required=False,
                                default=None,
                                help="The traffic pattern between endpoints",
                                dest="traffic_custom")
    optional_named.add_argument("--search_mode",
                                required=False,
                                choices=["COMBO", "STEP", "BINARY"],
                                default="BINARY",
                                help=("The search mode used to find the"
                                      "throughput rate"),
                                dest="search_mode")
    optional_named.add_argument("--learning_mode",
                                required=False,
                                choices=["AUTO", "L2_LEARNING",
                                         "L3_LEARNING", "NONE"],
                                default="AUTO",
                                help=("The learning mode used during the test,"
                                      "default is 'NONE'"),
                                dest="learning_mode")
    optional_named.add_argument("--rate_lower_limit_pct",
                                type=percent_float,
                                required=False,
                                default=1.0,
                                help=("The minimum percent line rate that"
                                      "will be used during the test"),
                                dest="rate_lower_limit_pct")
    optional_named.add_argument("--rate_upper_limit_pct",
                                type=percent_float,
                                required=False,
                                default=99.0,
                                help=("The maximum percent line rate that"
                                      "will be used during the test"),
                                dest="rate_upper_limit_pct")
    optional_named.add_argument("--rate_initial_pct",
                                type=percent_float,
                                required=False,
                                default=99.0,
                                help=("If Search Mode is BINARY, the percent"
                                      "line rate that will be used at the"
                                      "start of the test"),
                                dest="rate_initial_pct")
    optional_named.add_argument("--rate_step_pct",
                                type=percent_float,
                                required=False,
                                default=10.0,
                                help=("If SearchMode is STEP, the percent"
                                      "load increase per step"),
                                dest="rate_step_pct")
    optional_named.add_argument("--resolution_pct",
                                type=percent_float,
                                required=False,
                                default=1.0,
                                help=("The minimum percentage of load"
                                      "adjustment between iterations"),
                                dest="resolution_pct")
    optional_named.add_argument("--frame_size_list",
                                type=lambda s: [int(item)
                                                for item in s.split(',')],
                                required=False,
                                default=[256],
                                help="A comma-delimited list of frame sizes",
                                dest="frame_size_list")
    optional_named.add_argument("--acceptable_frame_loss_pct",
                                type=percent_float,
                                required=False,
                                default=0.0,
                                help=("The maximum acceptable frame loss"
                                      "percent in any iteration"),
                                dest="acceptable_frame_loss_pct")
    optional_named.add_argument("--east_intf_addr",
                                required=False,
                                default="192.85.1.3",
                                help=("The address to assign to the first"
                                      "emulated device interface on the first"
                                      "east port"),
                                dest="east_intf_addr")
    optional_named.add_argument("--east_intf_gateway_addr",
                                required=False,
                                default="192.85.1.53",
                                help=("The gateway address to assign to the"
                                      "first emulated device interface on the"
                                      "first east port"),
                                dest="east_intf_gateway_addr")
    optional_named.add_argument("--west_intf_addr",
                                required=False,
                                default="192.85.1.53",
                                help=("The address to assign to the first"
                                      "emulated device interface on the"
                                      "first west port"),
                                dest="west_intf_addr")
    optional_named.add_argument("--west_intf_gateway_addr",
                                required=False,
                                default="192.85.1.53",
                                help=("The gateway address to assign to"
                                      "the first emulated device interface"
                                      "on the first west port"),
                                dest="west_intf_gateway_addr")
    parser.add_argument("-v",
                        "--verbose",
                        required=False,
                        default=True,
                        help="More output during operation when present",
                        action="store_true",
                        dest="verbose")
    args = parser.parse_args()

    if args.verbose:
        _LOGGER.debug("Creating results directory")
    create_dir(args.results_dir)

    session_name = args.test_session_name
    user_name = args.test_user_name
    # pylint: disable=import-error
    try:
        # Load Spirent REST Library
        from stcrestclient import stchttp

        stc = stchttp.StcHttp(args.lab_server_addr)
        session_id = stc.new_session(user_name, session_name)
        stc.join_session(session_id)
    except RuntimeError as err:
        _LOGGER.error(err)
        raise

    # Get STC system info.
    tx_port_loc = "//%s/%s/%s" % (args.east_chassis_addr,
                                  args.east_slot_num,
                                  args.east_port_num)
    rx_port_loc = "//%s/%s/%s" % (args.west_chassis_addr,
                                  args.west_slot_num,
                                  args.west_port_num)

    # Retrieve and display the server information
    if args.verbose:
        _LOGGER.debug("SpirentTestCenter system version: %s",
                      stc.get("system1", "version"))

    try:
        device_list = []
        port_list = []
        if args.verbose:
            _LOGGER.debug("Bring up license server")
        license_mgr = stc.get("system1", "children-licenseservermanager")
        if args.verbose:
            _LOGGER.debug("license_mgr = %s", license_mgr)
        stc.create("LicenseServer", under=license_mgr, attributes={
            "server": args.license_server_addr})

        # Create the root project object
        if args.verbose:
            _LOGGER.debug("Creating project ...")
        project = stc.get("System1", "children-Project")

        # Configure any custom traffic parameters
        if args.traffic_custom == "cont":
            if args.verbose:
                _LOGGER.debug("Configure Continuous Traffic")
            stc.create("ContinuousTestConfig", under=project)

        # Create ports
        if args.verbose:
            _LOGGER.debug("Creating ports ...")
        east_chassis_port = stc.create('port', project)
        if args.verbose:
            _LOGGER.debug("Configuring TX port ...")
        stc.config(east_chassis_port, {'location': tx_port_loc})
        port_list.append(east_chassis_port)

        west_chassis_port = stc.create('port', project)
        if args.verbose:
            _LOGGER.debug("Configuring RX port ...")
        stc.config(west_chassis_port, {'location': rx_port_loc})
        port_list.append(west_chassis_port)

        # Create emulated genparam for east port
        east_device_gen_params = stc.create("EmulatedDeviceGenParams",
                                            under=project,
                                            attributes={"Port":
                                                        east_chassis_port})
        # Create the DeviceGenEthIIIfParams object
        stc.create("DeviceGenEthIIIfParams",
                   under=east_device_gen_params)
        # Configuring Ipv4 interfaces
        stc.create("DeviceGenIpv4IfParams",
                   under=east_device_gen_params,
                   attributes={"Addr": args.east_intf_addr,
                               "Gateway": args.east_intf_gateway_addr})
        # Create Devices using the Device Wizard
        device_gen_config = stc.perform("DeviceGenConfigExpand",
                                        params={"DeleteExisting": "No",
                                                "GenParams":
                                                east_device_gen_params})
        # Append to the device list
        device_list.append(device_gen_config['ReturnList'])

        # Create emulated genparam for west port
        west_device_gen_params = stc.create("EmulatedDeviceGenParams",
                                            under=project,
                                            attributes={"Port":
                                                        west_chassis_port})
        # Create the DeviceGenEthIIIfParams object
        stc.create("DeviceGenEthIIIfParams",
                   under=west_device_gen_params)
        # Configuring Ipv4 interfaces
        stc.create("DeviceGenIpv4IfParams",
                   under=west_device_gen_params,
                   attributes={"Addr": args.west_intf_addr,
                               "Gateway": args.west_intf_gateway_addr})
        # Create Devices using the Device Wizard
        device_gen_config = stc.perform("DeviceGenConfigExpand",
                                        params={"DeleteExisting": "No",
                                                "GenParams":
                                                west_device_gen_params})
        # Append to the device list
        device_list.append(device_gen_config['ReturnList'])
        if args.verbose:
            _LOGGER.debug(device_list)

        # Create the RFC 2544 'metric test
        if args.metric == "throughput":
            if args.verbose:
                _LOGGER.debug("Set up the RFC2544 throughput test...")
            stc.perform("Rfc2544SetupThroughputTestCommand",
                        params={"AcceptableFrameLoss":
                                args.acceptable_frame_loss_pct,
                                "Duration": args.trial_duration_sec,
                                "FrameSizeList": args.frame_size_list,
                                "LearningMode": args.learning_mode,
                                "NumOfTrials": args.num_trials,
                                "RateInitial": args.rate_initial_pct,
                                "RateLowerLimit": args.rate_lower_limit_pct,
                                "RateStep": args.rate_step_pct,
                                "RateUpperLimit": args.rate_upper_limit_pct,
                                "Resolution": args.resolution_pct,
                                "SearchMode": args.search_mode,
                                "TrafficPattern": args.traffic_pattern})
        elif args.metric == "backtoback":
            stc.perform("Rfc2544SetupBackToBackTestCommand",
                        params={"AcceptableFrameLoss":
                                args.acceptable_frame_loss_pct,
                                "Duration": args.trial_duration_sec,
                                "FrameSizeList": args.frame_size_list,
                                "LearningMode": args.learning_mode,
                                "LatencyType": args.latency_type,
                                "NumOfTrials": args.num_trials,
                                "RateInitial": args.rate_initial_pct,
                                "RateLowerLimit": args.rate_lower_limit_pct,
                                "RateStep": args.rate_step_pct,
                                "RateUpperLimit": args.rate_upper_limit_pct,
                                "Resolution": args.resolution_pct,
                                "SearchMode": args.search_mode,
                                "TrafficPattern": args.traffic_pattern})
        elif args.metric == "frameloss":
            stc.perform("Rfc2544SetupFrameLossTestCommand",
                        params={"AcceptableFrameLoss":
                                args.acceptable_frame_loss_pct,
                                "Duration": args.trial_duration_sec,
                                "FrameSizeList": args.frame_size_list,
                                "LearningMode": args.learning_mode,
                                "LatencyType": args.latency_type,
                                "NumOfTrials": args.num_trials,
                                "RateInitial": args.rate_initial_pct,
                                "RateLowerLimit": args.rate_lower_limit_pct,
                                "RateStep": args.rate_step_pct,
                                "RateUpperLimit": args.rate_upper_limit_pct,
                                "Resolution": args.resolution_pct,
                                "SearchMode": args.search_mode,
                                "TrafficPattern": args.traffic_pattern})
        elif args.metric == "latency":
            stc.perform("Rfc2544SetupLatencyTestCommand",
                        params={"AcceptableFrameLoss":
                                args.acceptable_frame_loss_pct,
                                "Duration": args.trial_duration_sec,
                                "FrameSizeList": args.frame_size_list,
                                "LearningMode": args.learning_mode,
                                "LatencyType": args.latency_type,
                                "NumOfTrials": args.num_trials,
                                "RateInitial": args.rate_initial_pct,
                                "RateLowerLimit": args.rate_lower_limit_pct,
                                "RateStep": args.rate_step_pct,
                                "RateUpperLimit": args.rate_upper_limit_pct,
                                "Resolution": args.resolution_pct,
                                "SearchMode": args.search_mode,
                                "TrafficPattern": args.traffic_pattern})

        # Save the configuration
        stc.perform("SaveToTcc", params={"Filename": "2544.tcc"})
        # Connect to the hardware...
        stc.perform("AttachPorts", params={"portList": stc.get(
            "system1.project", "children-port"), "autoConnect": "TRUE"})
        # Apply configuration.
        if args.verbose:
            _LOGGER.debug("Apply configuration...")
        stc.apply()

        if args.verbose:
            _LOGGER.debug("Starting the sequencer...")
        stc.perform("SequencerStart")

        # Wait for sequencer to finish
        _LOGGER.info(
            "Starting test... Please wait for the test to complete...")
        stc.wait_until_complete()
        _LOGGER.info("The test has completed... Saving results...")

        # Determine what the results database filename is...
        lab_server_resultsdb = stc.get(
            "system1.project.TestResultSetting", "CurrentResultFileName")

        if args.verbose:
            _LOGGER.debug("The lab server results database is %s",
                          lab_server_resultsdb)

        stc.perform("CSSynchronizeFiles",
                    params={"DefaultDownloadDir": args.results_dir})

        resultsdb = args.results_dir + \
            lab_server_resultsdb.split("/Results")[1]

        if not os.path.exists(resultsdb):
            resultsdb = lab_server_resultsdb
            _LOGGER.info("Failed to create the local summary DB File, using"
                         " the remote DB file instead.")
        else:
            _LOGGER.info(
                "The local summary DB file has been saved to %s", resultsdb)

        # The returns the "RFC2544ThroughputTestResultDetailedSummaryView"
        # table view from the results database.
        # There are other views available.

        if args.metric == "throughput":
            resultsdict = (
                stc.perform("QueryResult",
                            params={
                                "DatabaseConnectionString":
                                resultsdb,
                                "ResultPath":
                                ("RFC2544ThroughputTestResultDetailed"
                                 "SummaryView")}))

        # The returns the "RFC2544BacktoBackTestResultDetailedSummaryView"
        # table view from the results database.
        # There are other views available.
        elif args.metric == "backtoback":
            resultsdict = (
                stc.perform("QueryResult",
                            params={
                                "DatabaseConnectionString":
                                resultsdb,
                                "ResultPath":
                                ("RFC2544Back2BackTestResultDetailed"
                                 "SummaryView")}))

        # The returns the "RFC2544LatencyTestResultDetailedSummaryView"
        # table view from the results database.
        # There are other views available.
        elif args.metric == "latency":
            resultsdict = (
                stc.perform("QueryResult",
                            params={
                                "DatabaseConnectionString":
                                resultsdb,
                                "ResultPath":
                                ("RFC2544LatencyTestResultDetailed"
                                 "SummaryView")}))

        # The returns the "RFC2544FrameLossTestResultDetailedSummaryView"
        # table view from the results database.
        # There are other views available.
        elif args.metric == "frameloss":
            resultsdict = (
                stc.perform("QueryResult",
                            params={
                                "DatabaseConnectionString":
                                resultsdb,
                                "ResultPath":
                                ("RFC2544FrameLossTestResultDetailed"
                                 "SummaryView")}))
        if args.verbose:
            _LOGGER.debug("resultsdict[\"Columns\"]: %s",
                          resultsdict["Columns"])
            _LOGGER.debug("resultsdict[\"Output\"]: %s", resultsdict["Output"])
            _LOGGER.debug("Result paths: %s",
                          stc.perform("GetTestResultSettingPaths"))

            # Write results to csv
            _LOGGER.debug("Writing CSV file to results directory %s",
                          args.results_dir)
        write_query_results_to_csv(
            args.results_dir, args.csv_results_file_prefix, resultsdict)

    except RuntimeError as e:
        _LOGGER.error(e)

    if args.verbose:
        _LOGGER.debug("Destroy session on lab server")
    stc.end_session()

    _LOGGER.info("Test complete!")
#!/usr/bin/env python3

import logging
from stcrestclient import stchttp
from stc_session import StcSession

log = logging.getLogger(__name__)

logging.basicConfig(level=logging.INFO)

try:
    addr = StcSession.default_config['stc_server_addr']
    port = StcSession.default_config['stc_server_port']
    stc = stchttp.StcHttp(addr, port)

    sessions = stc.sessions()
    for session in sessions:
        log.info('Joining session {}'.format(session))
        stc.join_session(session)
        log.info('Ending session {}'.format(session))
        stc.end_session(session)

except Exception as e:
    print(e)
    exit(1)
Beispiel #11
0
def main():
    """ Read the arguments, Invoke Test and Return the results"""
    parser = argparse.ArgumentParser()
    # Required parameters
    required_named = parser.add_argument_group("required named arguments")
    required_named.add_argument("--lab_server_addr",
                                required=True,
                                help=("The IP address of the "
                                      "Spirent Lab Server"),
                                dest="lab_server_addr")
    required_named.add_argument("--license_server_addr",
                                required=True,
                                help=("The IP address of the Spirent "
                                      "License Server"),
                                dest="license_server_addr")
    required_named.add_argument("--location_list",
                                required=True,
                                help=("A comma-delimited list of test port "
                                      "locations"),
                                dest="location_list")
    # Optional parameters
    optional_named = parser.add_argument_group("optional named arguments")
    optional_named.add_argument("--metric",
                                required=False,
                                help=("One among - Forwarding,\
                                      Address Caching and Learning"),
                                choices=["forwarding", "caching",
                                         "learning"],
                                default="forwarding",
                                dest="metric")
    optional_named.add_argument("--test_session_name",
                                required=False,
                                default="Rfc2889Ses",
                                help=("The friendly name to identify "
                                      "the Spirent Lab Server test session"),
                                dest="test_session_name")
    optional_named.add_argument("--test_user_name",
                                required=False,
                                default="Rfc2889Usr",
                                help=("The friendly name to identify the "
                                      "Spirent Lab Server test user"),
                                dest="test_user_name")
    optional_named.add_argument("--results_dir",
                                required=False,
                                default="./Results",
                                help="The directory to copy results to",
                                dest="results_dir")
    optional_named.add_argument("--csv_results_file_prefix",
                                required=False,
                                default="Rfc2889MaxFor",
                                help="The prefix for the CSV results files",
                                dest="csv_results_file_prefix")
    optional_named.add_argument("--num_trials",
                                type=positive_int,
                                required=False,
                                default=1,
                                help=("The number of trials to execute during "
                                      "the test"),
                                dest="num_trials")
    optional_named.add_argument("--trial_duration_sec",
                                type=positive_int,
                                required=False,
                                default=60,
                                help=("The duration of each trial executed "
                                      "during the test"),
                                dest="trial_duration_sec")
    optional_named.add_argument("--traffic_pattern",
                                required=False,
                                choices=["BACKBONE", "MESH", "PAIR"],
                                default="MESH",
                                help="The traffic pattern between endpoints",
                                dest="traffic_pattern")
    optional_named.add_argument("--frame_size_list",
                                type=lambda s: [int(item)
                                                for item in s.split(',')],
                                required=False,
                                default=[256],
                                help="A comma-delimited list of frame sizes",
                                dest="frame_size_list")
    optional_named.add_argument("--min_learning_rate",
                                type=positive_int,
                                required=False,
                                default=1488,
                                help="Lowest learning rate for test",
                                dest="min_learning_rate")
    optional_named.add_argument("--max_learning_rate",
                                type=positive_int,
                                required=False,
                                default=14880,
                                help="Highest learning rate for test",
                                dest="max_learning_rate")
    optional_named.add_argument("--min_num_addrs",
                                type=positive_int,
                                required=False,
                                default=1,
                                help="lowest number of addrs sent to DUT",
                                dest="min_num_addrs")
    optional_named.add_argument("--max_num_addrs",
                                type=positive_int,
                                required=False,
                                default=1000,
                                help="Highest number of addrs sent to DUT",
                                dest="max_num_addrs")
    optional_named.add_argument("--ac_learning_rate",
                                type=positive_int,
                                required=False,
                                default=1000,
                                help="Number of learning frames per sec",
                                dest="ac_learning_rate")
    optional_named.add_argument("--frame_size",
                                type=positive_int,
                                required=False,
                                default=64,
                                help="Frame size for address test",
                                dest="frame_size")
    parser.add_argument("-v",
                        "--verbose",
                        required=False,
                        default=True,
                        help="More output during operation when present",
                        action="store_true",
                        dest="verbose")
    args = parser.parse_args()

    if args.verbose:
        logger.debug("Creating results directory")
    create_dir(args.results_dir)
    locationList = [str(item) for item in args.location_list.split(',')]

    session_name = args.test_session_name
    user_name = args.test_user_name

    # pylint: disable=import-error
    try:
        # Load Spirent REST Library
        from stcrestclient import stchttp

        stc = stchttp.StcHttp(args.lab_server_addr)
        session_id = stc.new_session(user_name, session_name)
        stc.join_session(session_id)
    except RuntimeError as e:
        logger.error(e)
        raise

    # Retrieve and display the server information
    if args.verbose:
        logger.debug("SpirentTestCenter system version: %s",
                     stc.get("system1", "version"))

    try:
        if args.verbose:
            logger.debug("Bring up license server")
        license_mgr = stc.get("system1", "children-licenseservermanager")
        if args.verbose:
            logger.debug("license_mgr = %s", license_mgr)
        stc.create("LicenseServer", under=license_mgr, attributes={
            "server": args.license_server_addr})

        # Create the root project object
        if args.verbose:
            logger.debug("Creating project ...")
        project = stc.get("System1", "children-Project")

        # Create ports
        if args.verbose:
            logger.debug("Creating ports ...")

        for location in locationList:
            stc.perform("CreateAndReservePorts", params={"locationList":
                                                         location,
                                                         "RevokeOwner":
                                                         "FALSE"})

        port_list_get = stc.get("System1.project", "children-port")

        if args.verbose:
            logger.debug("Adding Host Gen PArams")
        gen_params = stc.create("EmulatedDeviceGenParams",
                                under=project,
                                attributes={"Port": port_list_get})

        # Create the DeviceGenEthIIIfParams object
        stc.create("DeviceGenEthIIIfParams",
                   under=gen_params)
        # Configuring Ipv4 interfaces
        stc.create("DeviceGenIpv4IfParams",
                   under=gen_params)

        stc.perform("DeviceGenConfigExpand",
                    params={"DeleteExisting": "No",
                            "GenParams": gen_params})

        if args.verbose:
            logger.debug("Set up the RFC2889 test...")

        if args.metric == "learning":
            stc.perform("Rfc2889SetupAddressLearningRateTestCommand",
                        params={"FrameSize": args.frame_size,
                                "MinLearningRate": args.min_learning_rate,
                                "MaxLearningRate": args.max_learning_rate,
                                "NumOfTrials": args.num_trials})
        elif args.metric == "caching":
            stc.perform("Rfc2889SetupAddressCachingCapacityTestCommand",
                        params={"FrameSize": args.frame_size,
                                "MinNumAddrs": args.min_num_addrs,
                                "MaxNumAddrs": args.max_num_addrs,
                                "LearningRate": args.ac_learning_rate,
                                "NumOfTrials": args.num_trials})
        else:
            stc.perform("Rfc2889SetupMaxForwardingRateTestCommand",
                        params={"Duration": args.trial_duration_sec,
                                "FrameSizeList": args.frame_size_list,
                                "NumOfTrials": args.num_trials,
                                "TrafficPattern": args.traffic_pattern})

        # Save the configuration
        stc.perform("SaveToTcc", params={"Filename": "2889.tcc"})
        # Connect to the hardware...
        stc.perform("AttachPorts", params={"portList": stc.get(
            "system1.project", "children-port"), "autoConnect": "TRUE"})
        # Apply configuration.
        if args.verbose:
            logger.debug("Apply configuration...")
        stc.apply()

        if args.verbose:
            logger.debug("Starting the sequencer...")
        stc.perform("SequencerStart")

        # Wait for sequencer to finish
        logger.info(
            "Starting test... Please wait for the test to complete...")
        stc.wait_until_complete()
        logger.info("The test has completed... Saving results...")

        # Determine what the results database filename is...
        lab_server_resultsdb = stc.get(
            "system1.project.TestResultSetting", "CurrentResultFileName")

        if args.verbose:
            logger.debug("The lab server results database is %s",
                         lab_server_resultsdb)

        if args.metric == "learning":
            resultsdict = (
                stc.perform("QueryResult",
                            params={
                                "DatabaseConnectionString":
                                lab_server_resultsdb,
                                "ResultPath":
                                ("RFC2889AddressLearningRateTestResultDetailed"
                                 "SummaryView")}))
        elif args.metric == "caching":
            resultsdict = (
                stc.perform("QueryResult",
                            params={
                                "DatabaseConnectionString":
                                lab_server_resultsdb,
                                "ResultPath":
                                ("RFC2889AddressCachingCapacityTestResult"
                                 "DetailedSummaryView")}))
        else:
            resultsdict = (
                stc.perform("QueryResult",
                            params={
                                "DatabaseConnectionString":
                                lab_server_resultsdb,
                                "ResultPath":
                                ("RFC2889MaxForwardingRateTestResultDetailed"
                                 "SummaryView")}))

        if args.verbose:
            logger.debug("resultsdict[\"Columns\"]: %s",
                         resultsdict["Columns"])
            logger.debug("resultsdict[\"Output\"]: %s", resultsdict["Output"])
            logger.debug("Result paths: %s",
                         stc.perform("GetTestResultSettingPaths"))

        # Write results to csv
        if args.verbose:
            logger.debug("Writing CSV file to results directory %s",
                         args.results_dir)
        write_query_results_to_csv(
            args.results_dir, args.csv_results_file_prefix, resultsdict)

    except RuntimeError as err:
        logger.error(err)

    if args.verbose:
        logger.debug("Destroy session on lab server")

    stc.end_session()

    logger.info("Test complete!")