Ejemplo n.º 1
0
    def reserve(self, location=None, force=False, wait_for_up=True, timeout=40):
        """ Reserve physical port.

        :param location: port location in the form ip/slot/port.
        :param force: whether to revoke existing reservation (True) or not (False).
        :param wait_for_up: True - wait for port to come up, False - return immediately.
        :param timeout: how long (seconds) to wait for port to come up.

        :todo: seems like reserve takes forever even if port is already owned by the user.
            should test for ownership and take it forcefully only if really needed?
        """

        if location:
            self.location = location
            self.set_attributes(location=self.location)
        else:
            self.location = self.get_attribute('Location')

        if not is_local_host(self.location):
            self.api.perform('AttachPorts', PortList=self.obj_ref(), AutoConnect=True, RevokeOwner=force)
            self.api.apply()
            self.activephy = StcObject(parent=self, objRef=self.get_attribute('activephy-Targets'))
            self.activephy.get_attributes()
            if wait_for_up:
                self.wait_for_states(timeout, 'UP', 'DOWN', 'ADMIN_DOWN')
Ejemplo n.º 2
0
    def subscribe(self, view, config_type=None):
        """ Subscribe to statistics view.

        :parama view: statistics view to subscribe to.
        :parama config_type: configuration type to subscribe to.
        """

        if view.lower() in view_2_config_type:
            if not config_type:
                config_type = view_2_config_type[view.lower()]
            rds = self.project.api.subscribe(
                Parent=self.project.obj_ref(),
                ResultParent=self.project.obj_ref(),
                ConfigType=config_type,
                ResultType=view)
            self.rds = StcObject(objType='ResultDataSet',
                                 parent=self.project,
                                 objRef=rds)
        else:
            self.project.get_children('DynamicResultView')
            drv = self.project.get_object_by_name(view)
            rc = self.project.command('SubscribeDynamicResultView',
                                      DynamicResultView=drv.ref)
            self.rds = StcObject(objType='DynamicResultView',
                                 parent=self.project,
                                 objRef=rc['DynamicResultView'])
Ejemplo n.º 3
0
    def subscribe(self, view: str, config_type: Optional[str] = None) -> None:
        """Subscribe to statistics view.

        :param view: statistics view to subscribe to.
        :param config_type: configuration type to subscribe to.
        """
        if view.lower() in view_2_config_type:
            if not config_type:
                config_type = view_2_config_type[view.lower()]
            rds = StcObject.project.api.subscribe(
                Parent=StcObject.project.ref,
                ResultParent=StcObject.project.ref,
                ConfigType=config_type,
                ResultType=view)
            self.rds = StcObject(objType="ResultDataSet",
                                 parent=StcObject.project,
                                 objRef=rds)
        else:
            StcObject.project.get_children("DynamicResultView")
            drv = StcObject.project.get_object_by_name(view)
            rc = StcObject.project.command("SubscribeDynamicResultView",
                                           DynamicResultView=drv.ref)
            self.rds = StcObject(objType="DynamicResultView",
                                 parent=StcObject.project,
                                 objRef=rc["DynamicResultView"])
Ejemplo n.º 4
0
    def set_media_type(self, media_type):
        """ Set media type for dual phy 1G ports.

        :param media_type: requested media type - EthernetCopper or EthernetFiber.
        """

        if media_type != self.activephy.obj_type():
            new_phy = StcObject(parent=self, objType=media_type)
            self.set_targets(apply_=True, ActivePhy=new_phy.obj_ref())
            self.activephy = new_phy
Ejemplo n.º 5
0
    def __init__(self, logger, api_wrapper):
        """ Set all kinds of application level objects - logger, api, etc.

        :param logger: python logger (e.g. logging.getLogger('log'))
        :param api_wrapper: api wrapper object inheriting and implementing StcApi base class.
        """

        super(self.__class__, self).__init__(logger, api_wrapper)

        StcObject.logger = self.logger
        StcObject.str_2_class = TYPE_2_OBJECT

        self.system = StcObject(objType='system', objRef='system1', parent=None)
        self.system.api = self.api
        self.system.logger = self.logger
        self.system.project = None
Ejemplo n.º 6
0
    def testBuildEmulation(self):
        """ Build simple BGP configuration. """
        self.logger.info(StcTestOffline.testBuildEmulation.__doc__.strip())

        stc_port = StcPort(name='Port 1', parent=self.stc.project)
        stc_dev = StcDevice(name='Device 1', parent=stc_port)
        stc_eth = StcObject(objType='EthIIIf', parent=stc_dev)
        stc_eth.set_attributes(SourceMac='00:11:22:33:44:55')
        stc_ip = StcObject(objType='Ipv4If', parent=stc_dev)
        stc_ip.set_attributes(Address='1.2.3.4', PrefixLength=16)
        StcObject(objType='BgpRouterConfig', parent=stc_dev)

        test_name = inspect.stack()[0][3]
        self.stc.save_config(
            path.join(path.dirname(__file__), 'configs', test_name + '.tcc'))
Ejemplo n.º 7
0
def test_stream_under_project(logger: logging.Logger, stc: StcApp) -> None:
    """Build simple config with ports under project object."""
    logger.info(test_stream_under_project.__doc__.strip())

    for port_name in ("Port 1", "Port 2"):
        logger.info(f'Create Port "{port_name}"')
        stc_port = StcPort(name=port_name, parent=stc.project)

        for sb_name in (port_name + " StreamBlock 1",
                        port_name + " StreamBlock 2"):
            logger.info(f'Build StreamBlock "{sb_name}"')
            stc_sb = StcStream(name=sb_name, parent=stc_port)
            stc_eth = StcObject(objType="ethernet:ethernetii", parent=stc_sb)
            stc_eth.set_attributes(DstMac="00:10:20:30:40:50")

    test_name = inspect.stack()[0][3]
    stc.save_config(
        Path(__file__).parent.joinpath("configs/temp",
                                       test_name + ".tcc").as_posix())
Ejemplo n.º 8
0
    def testStreamUnderProject(self):
        """ Build simple config with ports under project object. """
        self.logger.info(StcTestOffline.testBuildConfig.__doc__.strip())

        for port_name in ('Port 1', 'Port 2'):
            self.logger.info('Create Port "%s"', port_name)
            stc_port = StcPort(name=port_name, parent=self.stc.project)

            for sb_name in (port_name + ' StreamBlock 1',
                            port_name + ' StreamBlock 2'):
                self.logger.info('Build StreamBlock "%s"', sb_name)
                stc_sb = StcStream(name=sb_name, parent=stc_port)
                stc_eth = StcObject(objType='ethernet:ethernetii',
                                    parent=stc_sb)
                stc_eth.set_attributes(DstMac='00:10:20:30:40:50')

        test_name = inspect.stack()[0][3]
        self.stc.save_config(
            path.join(path.dirname(__file__), 'configs', test_name + '.tcc'))
Ejemplo n.º 9
0
def test_build_emulation(logger: logging.Logger, stc: StcApp) -> None:
    """Build simple BGP configuration."""
    logger.info(test_build_emulation.__doc__.strip())

    stc_port = StcPort(name="Port 1", parent=stc.project)
    stc_dev = StcDevice(name="Device 1", parent=stc_port)
    stc_eth = StcObject(objType="EthIIIf", parent=stc_dev)
    stc_eth.set_attributes(SourceMac="00:11:22:33:44:55")
    stc_ip = StcObject(objType="Ipv4If", parent=stc_dev)
    stc_ip.set_attributes(Address="1.2.3.4", PrefixLength=16)
    StcObject(objType="BgpRouterConfig", parent=stc_dev)

    test_name = inspect.stack()[0][3]
    stc.save_config(
        Path(__file__).parent.joinpath("configs/temp",
                                       test_name + ".tcc").as_posix())
Ejemplo n.º 10
0
    def __init__(self, logger: logging.Logger,
                 api_wrapper: Union[StcRestWrapper, StcTclWrapper]) -> None:
        """Set all kinds of application level objects - logger, api, etc.

        :param logger: python logger (e.g. logging.getLogger('log'))
        :param api_wrapper: api wrapper object inheriting and implementing StcApi base class.
        """

        super().__init__(logger, api_wrapper)

        StcObject.logger = self.logger
        StcObject.str_2_class = TYPE_2_OBJECT

        self.system = StcObject(parent=None,
                                objType="system",
                                objRef="system1")
        self.system.api = self.api
        self.system.logger = self.logger
        self.lab_server = None
        self.project: StcProject = None
        self.hw = None
Ejemplo n.º 11
0
def test_build_config(logger: logging.Logger, stc: StcApp) -> None:
    """Build simple config from scratch."""
    logger.info(test_build_config.__doc__.strip())

    for port_name in ("Port 1", "Port 2"):
        logger.info('Create Port "%s"', port_name)
        stc_port = StcPort(name=port_name, parent=stc.project)

        for dev_name in (port_name + " Device 1", port_name + " Device 2"):
            logger.info('Build Device "%s"', dev_name)
            stc_dev = StcDevice(name=dev_name, parent=stc_port)
            stc_eth = StcObject(objType="EthIIIf", parent=stc_dev)
            stc_eth.set_attributes(SourceMac="00:11:22:33:44:55")
            stc_dev.set_attributes(TopLevelIf=stc_eth.ref,
                                   PrimaryIf=stc_eth.ref)
            # stc_ip = StcObject(objType="Ipv4If", parent=stc_dev)
            # stc_ip.set_attributes(Address="1.2.3.4", PrefixLength=16)

        for sb_name in (port_name + " StreamBlock 1",
                        port_name + " StreamBlock 2"):
            logger.info('Build StreamBlock "%s"', sb_name)
            stc_sb = StcStream(name=sb_name, parent=stc_port)
            stc_eth = StcObject(objType="ethernet:ethernetii", parent=stc_sb)
            stc_eth.set_attributes(DstMac="00:10:20:30:40:50")

    stc_ports = stc.project.get_children("port")
    assert len(stc_ports) == 2
    for stc_port in stc_ports:
        assert len(stc_port.get_children("generator")) == 1
        assert len(stc_port.get_children("generator", "analyzer")) == 2
        assert len(stc_port.get_children("emulateddevice")) == 2
        assert len(
            stc_port.get_children("emulateddevice", "generator",
                                  "analyzer")) == 4
    for stc_port in stc_ports:
        assert len(stc_port.get_children("streamblock")) == 2

    stc.api.apply()

    test_name = inspect.stack()[0][3]
    stc.save_config(
        Path(__file__).parent.joinpath("configs/temp",
                                       test_name + ".tcc").as_posix())
class StcStats(object):
    """ Represents statistics view.

    The statistics dictionary represents a table:
    Statistics Name | Object 1 Value | Object 2 Value | ...
    object          |                |                |
    parents         |                |                |
    topLevelName    |                |                |
    Stat 1          |                |                |
    ...

    For example, generatorportresults statistics for two ports might look like the following:
    Statistics Name     | Object 1 Value           | Object 2 Value
    object              | analyzerportresults1     | analyzerportresults2
    parents             | project1/port1/analyzer1 | project1/port2/analyzer2
    topLevelName        | Port 1                   | Port 2
    GeneratorFrameCount | 1000                     | 2000
    ...
    """

    statistics = {}

    def __init__(self, project, view):
        """ Subscribe to view with default configuration type as defined by config_2_type.

        :param project: parent project object for all statistics.
        :param view: statistics view to subscribe to. If view is None it is the test responsibility to subscribe with
            specific config_type.
        """

        super(StcStats, self).__init__()
        self.project = project
        if view:
            self.subscribe(view)
        self.statistics = {}

    def subscribe(self, view, config_type=None):
        """ Subscribe to statistics view.

        :parama view: statistics view to subscribe to.
        :parama config_type: configuration type to subscribe to.
        """

        if view.lower() in view_2_config_type:
            if not config_type:
                config_type = view_2_config_type[view.lower()]
            rds = self.project.api.subscribe(Parent=self.project.obj_ref(), ResultParent=self.project.obj_ref(),
                                             ConfigType=config_type, ResultType=view)
            self.rds = StcObject(objType='ResultDataSet', parent=self.project, objRef=rds)
        else:
            self.project.get_children('DynamicResultView')
            drv = self.project.get_object_by_name(view)
            rc = self.project.command('SubscribeDynamicResultView', DynamicResultView=drv.ref)
            self.rds = StcObject(objType='DynamicResultView', parent=self.project, objRef=rc['DynamicResultView'])

    def unsubscribe(self):
        """ UnSubscribe from statistics view. """

        self.project.api.unsubscribe(self.rds.obj_ref())

    def read_stats(self, *stats):
        """ Reads the statistics view from STC and saves it in statistics dictionary.

        :param stats: list of statistics names to read, empty list will read all statistics.
            Relevant for system (not dynamic) result views only.

        :todo: add support for user statistics.
        """

        self.statistics = {}
        if self.rds.type == 'dynamicresultview':
            self._read_custom_view()
        else:
            self._read_view(*stats)

    def get_stats(self, row='topLevelName'):
        """
        :param row: requested row (== statistic name)
        :returns: all statistics values for the requested row.
        """
        return self.statistics[row]

    def get_object_stats(self, obj_id, obj_id_stat='topLevelName'):
        """
        :param obj_id: requested object ID.
        :param obj_id_stat: which statistics name to use as object ID, sometimes topLevelName is
            not meaningful and it is better to use other unique identifier like stream ID.
        :returns: all statistics values for the requested object ID.
        """

        obj_statistics = {}
        for counter in self.statistics.keys():
            if self.statistics[counter]:
                obj_statistics[counter] = self.get_stat(obj_id, counter, obj_id_stat)
        return obj_statistics

    def get_stat(self, obj_id, counter, obj_id_stat='topLevelName'):
        """
        :param obj_id: requested object id.
        :param counter: requested statistics (note that some statistics are not counters).
        :param obj_id_stat: which statistics name to use as object ID, sometimes topLevelName is
            not meaningful and it is better to use other unique identifier like stream ID.
        :returns: the value of the requested counter for the requested object ID.
        """
        obj_index = self.statistics[obj_id_stat].index(obj_id)
        return self.statistics[counter][obj_index]

    def get_counter(self, obj_id, counter, obj_id_stat='topLevelName'):
        """
        :param obj_id: requested object ID.
        :param counter: requested statistics (note that some statistics are not counters).
        :param obj_id_stat: which statistics name to use as object ID, sometimes topLevelName is
            not meaningful and it is better to use other unique identifier like stream ID.
        :returns: the int value of the requested counter for the requested object ID.
        """
        return int(self.get_stat(obj_id, counter, obj_id_stat))

    def get_all_stats(self, obj_id_stat='topLevelName'):
        all_statistics = OrderedDict()
        for obj_name in self.statistics[obj_id_stat]:
            all_statistics[obj_name] = self.get_object_stats(obj_name)
        return all_statistics

    def _read_custom_view(self):

        self.project.command('RefreshResultView', ResultDataSet=self.rds.ref)
        self.project.command('UpdateDynamicResultViewCommand', DynamicResultView=self.rds.ref)
        presentationResultQuery = self.rds.get_child('PresentationResultQuery')
        selectedProperties = presentationResultQuery.get_list_attribute('SelectProperties')
        self.objs_stats = []
        for rvd in presentationResultQuery.get_children('ResultViewData'):
            self.objs_stats.append(rvd.get_list_attribute('ResultData')[:len(selectedProperties)])
            self._get_result_data(rvd, len(selectedProperties))
        self.statistics = dict(zip(selectedProperties, zip(*self.objs_stats)))

    def _get_result_data(self, rvd, num_columns):
        self.project.command('ExpandResultViewDataCommand', ResultViewData=rvd.ref)
        for child_rvd in rvd.get_children('ResultViewData'):
            if is_false(child_rvd.get_attribute('IsDummy')):
                self.objs_stats.append(child_rvd.get_list_attribute('ResultData')[:num_columns])
            self._get_result_data(child_rvd, num_columns)

    def _read_view(self, *stats):

        objs_stats = []
        self.project.command('RefreshResultView', ResultDataSet=self.rds.obj_ref())
        for page_number in range(1, int(self.rds.get_attribute('TotalPageCount')) + 1):
            self.rds.set_attributes(PageNumber=page_number)
            for results in self.rds.get_objects_from_attribute('ResultHandleList'):
                parent = results.get_object_from_attribute('parent')
                parents = parent.obj_ref()
                name = ''
                while parent != self.project:
                    if not name and parent.obj_type().lower() in ('port', 'emulateddevice', 'streamblock'):
                        name = parent.get_name()
                    parent = parent.get_object_from_attribute('parent')
                    parents = parent.obj_ref() + '/' + parents
                obj_stats = ({'object': results.obj_ref(), 'parents': parents, 'topLevelName': name})
                obj_stats.update(results.get_attributes(*stats))
                obj_stats.pop('parent', None)
                obj_stats.pop('Name', None)
                obj_stats.pop('resultchild-Sources', None)
                objs_stats.append(obj_stats.values())
                keys = obj_stats.keys()
        if objs_stats:
            self.statistics = dict(zip(keys, zip(*objs_stats)))
Ejemplo n.º 13
0
 def get_arp_cache(self):
     return StcObject.get_arp_cache(self)
Ejemplo n.º 14
0
 def send_arp_ns(self):
     StcObject.send_arp_ns(self)
Ejemplo n.º 15
0
 def send_arp_ns(self) -> None:
     """Run ARP on all ports."""
     StcObject.send_arp_ns(*self.project.ports.values())
Ejemplo n.º 16
0
 def send_arp_ns(self):
     """ Send ARP/ND for the port. """
     StcObject.send_arp_ns(self)
Ejemplo n.º 17
0
class StcApp(TgnApp):
    """TestCenter driver. Equivalent to TestCenter Application."""
    def __init__(self, logger: logging.Logger,
                 api_wrapper: Union[StcRestWrapper, StcTclWrapper]) -> None:
        """Set all kinds of application level objects - logger, api, etc.

        :param logger: python logger (e.g. logging.getLogger('log'))
        :param api_wrapper: api wrapper object inheriting and implementing StcApi base class.
        """

        super().__init__(logger, api_wrapper)

        StcObject.logger = self.logger
        StcObject.str_2_class = TYPE_2_OBJECT

        self.system = StcObject(parent=None,
                                objType="system",
                                objRef="system1")
        self.system.api = self.api
        self.system.logger = self.logger
        self.lab_server = None
        self.project: StcProject = None
        self.hw = None

    def connect(self, lab_server=None) -> None:
        """Create object and (optionally) connect to lab server.

        :param lab_server: optional lab server address.
        """
        self.lab_server = lab_server
        if self.lab_server:
            self.api.perform("CSTestSessionConnect",
                             Host=self.lab_server,
                             CreateNewTestSession=True)

        # Every object creation/retrieval must come AFTER we connect to lab server (if needed).
        self.project = StcProject(parent=self.system)
        StcObject.project = self.project
        self.hw = self.system.get_child("PhysicalChassisManager")

    def disconnect(self, terminate=True) -> None:
        """Disconnect from lab server (if used) and reset configuration.

        :param terminate: True - terminate session, False - leave session on server.
        """
        self.reset_config()
        if type(self.api) == StcRestWrapper:
            self.api.disconnect(terminate)
        if self.lab_server:
            self.api.perform("CSTestSessionDisconnect", Terminate=terminate)

    def load_config(self, config_file_name: str) -> None:
        """Load configuration file from tcc or xml.

        Configuration file type is extracted from the file suffix - xml or tcc.

        :param config_file_name: full path to the configuration file.
        """

        if type(self.api) == StcRestWrapper:
            self.api.client.upload(config_file_name)
            config_file_name = path.basename(config_file_name)
        ext = path.splitext(config_file_name)[-1].lower()
        if ext == ".tcc":
            self.api.perform(
                "LoadFromDatabase",
                DatabaseConnectionString=path.normpath(config_file_name))
        elif ext == ".xml":
            self.api.perform("LoadFromXml",
                             FileName=path.normpath(config_file_name))
        else:
            raise ValueError(f"Configuration file type {ext} not supported.")
        self.project.objects = {}
        self.project.get_children("port")

    def reset_config(self):
        self.api.perform("ResetConfig", config="system1")

    def save_config(self,
                    config_file_name: str,
                    server_folder: Optional[str] = "c:\\temp") -> None:
        """Save configuration file as tcc or xml.

        Configuration file type is extracted from the file suffix - xml or tcc.

        :param config_file_name: full path to the configuration file.
        :param server_folder: folder on the server where the system will save the files before download.
        """
        if type(self.api) == StcRestWrapper:
            config_file_name_full_path = config_file_name
            config_file_name = server_folder + "\\" + path.basename(
                config_file_name)
        ext = path.splitext(config_file_name)[-1].lower()
        if ext == ".tcc":
            rc = self.api.perform("SaveToTcc",
                                  FileName=path.normpath(config_file_name))
        elif ext == ".xml":
            rc = self.api.perform("SaveAsXml",
                                  FileName=path.normpath(config_file_name))
        else:
            raise ValueError(
                "Configuration file type {0} not supported.".format(ext))
        if type(self.api) == StcRestWrapper:
            self.api.client.download(rc["FileName"],
                                     config_file_name_full_path)

    def clear_results(self) -> None:
        self.project.clear_results()

    #
    # Online commands.
    # All commands assume that all ports are reserved and port objects exist under project.
    #

    def send_arp_ns(self) -> None:
        """Run ARP on all ports."""
        StcObject.send_arp_ns(*self.project.ports.values())

    def get_arp_cache(self):
        return StcObject.get_arp_cache(
            *self.project.get_objects_or_children_by_type("port"))

    #
    # Devices commands.
    #

    def start_devices(self) -> None:
        """Start all devices.

        It is the test responsibility to wait for devices to reach required state.
        """
        self._command_devices("DeviceStart")

    def stop_devices(self) -> None:
        """Stop all devices."""
        self._command_devices("DeviceStop")

    def _command_devices(self, command) -> None:
        self.project.command_devices(command, 4)
        self.project.test_command_rc("Status")
        time.sleep(4)

    #
    # Traffic commands.
    #

    def start_traffic(self, blocking: Optional[bool] = False) -> None:
        """Start traffic on all ports."""
        self.project.start_ports(blocking)

    def stop_traffic(self) -> None:
        """Stop traffic on all ports."""
        self.project.stop_ports()

    def wait_traffic(self) -> None:
        """Wait for traffic to end on all ports."""
        self.project.wait_traffic()

    #
    # Sequencer commands.
    #

    def sequencer_command(self, command: StcSequencerOperation) -> None:
        """Perform sequencer command.

        :param command: sequencer command.
        """
        if command != StcSequencerOperation.wait:
            self.project.command(command.value)
        else:
            self.project.wait()
Ejemplo n.º 18
0
    def testBuildConfig(self):
        """ Build simple config from scratch. """
        self.logger.info(StcTestOffline.testBuildConfig.__doc__.strip())

        for port_name in ('Port 1', 'Port 2'):
            self.logger.info('Create Port "%s"', port_name)
            stc_port = StcPort(name=port_name, parent=self.stc.project)

            for dev_name in (port_name + ' Device 1', port_name + ' Device 2'):
                self.logger.info('Build Device "%s"', dev_name)
                stc_dev = StcDevice(name=dev_name, parent=stc_port)
                stc_eth = StcObject(objType='EthIIIf', parent=stc_dev)
                stc_eth.set_attributes(SourceMac='00:11:22:33:44:55')
                stc_ip = StcObject(objType='Ipv4If', parent=stc_dev)
                stc_ip.set_attributes(Address='1.2.3.4', PrefixLength=16)

            for sb_name in (port_name + ' StreamBlock 1',
                            port_name + ' StreamBlock 2'):
                self.logger.info('Build StreamBlock "%s"', sb_name)
                stc_sb = StcStream(name=sb_name, parent=stc_port)
                stc_eth = StcObject(objType='ethernet:ethernetii',
                                    parent=stc_sb)
                stc_eth.set_attributes(DstMac='00:10:20:30:40:50')

        stc_ports = self.stc.project.get_children('port')
        assert (len(stc_ports) == 2)
        for stc_port in stc_ports:
            assert (len(stc_port.get_children('generator')) == 1)
            assert (len(stc_port.get_children('generator', 'analyzer')) == 2)
            assert (len(stc_port.get_children('emulateddevice')) == 2)
            assert (len(
                stc_port.get_children('emulateddevice', 'generator',
                                      'analyzer')) == 4)
        for stc_port in stc_ports:
            assert (len(stc_port.get_children('streamblock')) == 2)

        test_name = inspect.stack()[0][3]
        self.stc.save_config(
            path.join(path.dirname(__file__), 'configs', test_name + '.tcc'))
Ejemplo n.º 19
0
 def __init__(self, **data):
     self.port = StcPort(name=data['name'], parent=data['parent'])
     data['objType'] = 'lag'
     data['parent'] = self.port
     super(self.__class__, self).__init__(**data)
     StcObject(objType='LacpGroupConfig', parent=self)
Ejemplo n.º 20
0
 def get_arp_cache(self):
     return StcObject.get_arp_cache(
         *self.project.get_objects_or_children_by_type('port'))
Ejemplo n.º 21
0
 def get_arp_cache(self):
     """ Send ARP/ND for the port. """
     return StcObject.get_arp_cache(self)
Ejemplo n.º 22
0
 def add_ports(self, *ports):
     for stc_port in ports:
         self.append_attribute('PortSetMember-targets', stc_port.obj_ref())
         StcObject(objType='LacpPortConfig', parent=stc_port)
     self.api.apply()
Ejemplo n.º 23
0
 def send_arp_ns(self):
     StcObject.send_arp_ns(
         *self.project.get_objects_or_children_by_type('port'))
Ejemplo n.º 24
0
class StcStats:
    """Represents statistics view.

    The statistics dictionary represents a table:
    Statistics Name | Object 1 Value | Object 2 Value | ...
    object          |                |                |
    parents         |                |                |
    topLevelName    |                |                |
    Stat 1          |                |                |
    ...

    For example, generatorportresults statistics for two ports might look like the following:
    Statistics Name     | Object 1 Value           | Object 2 Value
    object              | analyzerportresults1     | analyzerportresults2
    parents             | project1/port1/analyzer1 | project1/port2/analyzer2
    topLevelName        | Port 1                   | Port 2
    GeneratorFrameCount | 1000                     | 2000
    ...
    """
    def __init__(self, view: str) -> None:
        """Subscribe to view with default configuration type as defined by config_2_type.

        :param view: statistics view to subscribe to. If view is None it is the test responsibility to subscribe with
            specific config_type.
        """
        self.rds = None
        self.statistics = TgnObjectsDict()
        if view:
            self.subscribe(view)

    def subscribe(self, view: str, config_type: Optional[str] = None) -> None:
        """Subscribe to statistics view.

        :param view: statistics view to subscribe to.
        :param config_type: configuration type to subscribe to.
        """
        if view.lower() in view_2_config_type:
            if not config_type:
                config_type = view_2_config_type[view.lower()]
            rds = StcObject.project.api.subscribe(
                Parent=StcObject.project.ref,
                ResultParent=StcObject.project.ref,
                ConfigType=config_type,
                ResultType=view)
            self.rds = StcObject(objType="ResultDataSet",
                                 parent=StcObject.project,
                                 objRef=rds)
        else:
            StcObject.project.get_children("DynamicResultView")
            drv = StcObject.project.get_object_by_name(view)
            rc = StcObject.project.command("SubscribeDynamicResultView",
                                           DynamicResultView=drv.ref)
            self.rds = StcObject(objType="DynamicResultView",
                                 parent=StcObject.project,
                                 objRef=rc["DynamicResultView"])

    def unsubscribe(self) -> None:
        """UnSubscribe from statistics view."""
        StcObject.project.api.unsubscribe(self.rds.ref)

    def read_stats(
            self,
            obj_id_stat: Optional[str] = "topLevelName") -> TgnObjectsDict:
        """Reads the statistics view from STC and saves it in statistics dictionary.

        :param obj_id_stat: which statistics name to use as object ID, sometimes topLevelName is
            not meaningful and it is better to use other unique identifier like stream ID.
        """
        self.statistics = TgnObjectsDict()
        if self.rds.type == "dynamicresultview":
            self._read_custom_view()
        else:
            self._read_view(obj_id_stat)
        return self.statistics

    def get_column_stats(self, name: str) -> TgnObjectsDict:
        """Returns all statistics values for the requested statistics.

        N/A for custom views.

        :param name: requested statistic name.
        """
        column_statistics = TgnObjectsDict()
        for obj, obj_values in self.statistics.items():
            column_statistics[obj] = obj_values[name]
        return column_statistics

    #
    # Private methods.
    #

    def _read_custom_view(self):

        StcObject.project.command("RefreshResultView",
                                  ResultDataSet=self.rds.ref)
        StcObject.project.command("UpdateDynamicResultViewCommand",
                                  DynamicResultView=self.rds.ref)
        presentationResultQuery = self.rds.get_child("PresentationResultQuery")
        selectedProperties = presentationResultQuery.get_list_attribute(
            "SelectProperties")
        self.objs_stats = []
        for rvd in presentationResultQuery.get_children("ResultViewData"):
            self.objs_stats.append(
                rvd.get_list_attribute("ResultData")[:len(selectedProperties)])
            self._get_result_data(rvd, len(selectedProperties))
        self.statistics = dict(zip(selectedProperties, zip(*self.objs_stats)))

    def _get_result_data(self, rvd, num_columns):
        StcObject.project.command("ExpandResultViewDataCommand",
                                  ResultViewData=rvd.ref)
        for child_rvd in rvd.get_children("ResultViewData"):
            if is_false(child_rvd.get_attribute("IsDummy")):
                self.objs_stats.append(
                    child_rvd.get_list_attribute("ResultData")[:num_columns])
            self._get_result_data(child_rvd, num_columns)

    def _read_view(self, obj_id_stat: Optional[str] = "topLevelName") -> None:

        StcObject.project.command("RefreshResultView",
                                  ResultDataSet=self.rds.ref)
        for page_number in range(
                1,
                int(self.rds.get_attribute("TotalPageCount")) + 1):
            self.rds.set_attributes(PageNumber=page_number)
            for results in self.rds.get_objects_from_attribute(
                    "ResultHandleList"):
                parent = results.get_object_from_attribute("parent")
                parents = parent.ref
                name = ""
                while parent != StcObject.project:
                    if not name and parent.obj_type().lower() in (
                            "port", "emulateddevice", "streamblock"):
                        name = parent.get_name()
                    parent = parent.get_object_from_attribute("parent")
                    parents = parent.ref + "/" + parents
                obj_stats = {
                    "object": results.ref,
                    "parents": parents,
                    "topLevelName": name
                }
                obj_stats.update(results.get_attributes())
                obj_stats.pop("parent", None)
                obj_stats.pop("Name", None)
                obj_stats.pop("resultchild-Sources", None)
                for stat in obj_stats:
                    try:
                        obj_stats[stat] = int(obj_stats[stat])
                    except ValueError:
                        pass
                self.statistics[StcObject.project.get_object_by_name(
                    obj_stats[obj_id_stat])] = obj_stats
Ejemplo n.º 25
0
class StcApp(TgnApp):
    """ TestCenter driver. Equivalent to TestCenter Application. """
    def __init__(self, logger, api_wrapper):
        """ Set all kinds of application level objects - logger, api, etc.

        :param logger: python logger (e.g. logging.getLogger('log'))
        :param api_wrapper: api wrapper object inheriting and implementing StcApi base class.
        """

        super(StcApp, self).__init__(logger, api_wrapper)

        StcObject.logger = self.logger
        StcObject.str_2_class = TYPE_2_OBJECT

        self.system = StcObject(objType='system',
                                objRef='system1',
                                parent=None)
        self.system.api = self.api
        self.system.logger = self.logger
        self.system.project = None

    def connect(self, lab_server=None):
        """ Create object and (optionally) connect to lab server.

        :param lab_server: optional lab server address.
        """

        self.lab_server = lab_server
        if self.lab_server:
            self.api.perform('CSTestSessionConnect',
                             Host=self.lab_server,
                             CreateNewTestSession=True)

        # Every object creation/retrieval must come AFTER we connect to lab server (if needed).
        self.hw = self.system.get_child('PhysicalChassisManager')
        self.project = StcProject(parent=self.system)
        self.project.project = self.project

    def disconnect(self, terminate=True):
        """ Disconnect from lab server (if used) and reset configuration.

        :param terminate: True - terminate session, False - leave session on server.
        """

        self.reset_config()
        if type(self.api) == StcRestWrapper:
            self.api.disconnect(terminate)
        if self.lab_server:
            self.api.perform('CSTestSessionDisconnect', Terminate=terminate)

    def load_config(self, config_file_name):
        """ Load configuration file from tcc or xml.

        Configuration file type is extracted from the file suffix - xml or tcc.

        :param config_file_name: full path to the configuration file.
        """

        if type(self.api) == StcRestWrapper:
            self.api.ls.upload(config_file_name)
            config_file_name = path.basename(config_file_name)
        ext = path.splitext(config_file_name)[-1].lower()
        if ext == '.tcc':
            self.api.perform(
                'LoadFromDatabase',
                DatabaseConnectionString=path.normpath(config_file_name))
        elif ext == '.xml':
            self.api.perform('LoadFromXml',
                             FileName=path.normpath(config_file_name))
        else:
            raise ValueError(
                'Configuration file type {} not supported.'.format(ext))
        self.project.objects = {}
        self.project.get_children('port')

    def reset_config(self):
        self.api.perform('ResetConfig', config='system1')

    def save_config(self, config_file_name, server_folder='c:\\temp'):
        """ Save configuration file as tcc or xml.

        Configuration file type is extracted from the file suffix - xml or tcc.
        :param config_file_name: full path to the configuration file.
        :param server_temp_folder: folder on the server where the system will save the files before download.
        """

        if type(self.api) == StcRestWrapper:
            config_file_name_full_path = config_file_name
            config_file_name = server_folder + '\\' + path.basename(
                config_file_name)
        ext = path.splitext(config_file_name)[-1].lower()
        if ext == '.tcc':
            rc = self.api.perform('SaveToTcc',
                                  FileName=path.normpath(config_file_name))
        elif ext == '.xml':
            rc = self.api.perform('SaveAsXml',
                                  FileName=path.normpath(config_file_name))
        else:
            raise ValueError(
                'Configuration file type {0} not supported.'.format(ext))
        if type(self.api) == StcRestWrapper:
            self.api.ls.download(rc['FileName'], config_file_name_full_path)

    def clear_results(self):
        self.project.clear_results()

    #
    # Online commands.
    # All commands assume that all ports are reserved and port objects exist under project.
    #

    def send_arp_ns(self):
        StcObject.send_arp_ns(
            *self.project.get_objects_or_children_by_type('port'))

    def get_arp_cache(self):
        return StcObject.get_arp_cache(
            *self.project.get_objects_or_children_by_type('port'))

    #
    # Devices commands.
    #

    def start_devices(self):
        """ Start all devices.

        It is the test responsibility to wait for devices to reach required state.
        """
        self._command_devices('DeviceStart')

    def stop_devices(self):
        self._command_devices('DeviceStop')

    def _command_devices(self, command):
        self.project.command_devices(command, 4)
        self.project.test_command_rc('Status')
        time.sleep(4)

    #
    # Traffic commands.
    #

    def start_traffic(self, blocking=False):
        self.project.start_ports(blocking)

    def stop_traffic(self):
        self.project.stop_ports()

    def wait_traffic(self):
        self.project.wait_traffic()

    #
    # Sequencer commands.
    #

    def sequencer_command(self, command):
        """ Perform sequencer command.

        :param command: sequencer command.
        :type command: testcenter.stc_app.StcSequencerOperation
        """
        if command != StcSequencerOperation.wait:
            self.project.command(command.value)
        else:
            self.project.wait()
Ejemplo n.º 26
0
class StcPort(StcObject):
    """ Represent STC port. """

    def __init__(self, **data):
        data['objType'] = 'port'
        super(StcPort, self).__init__(**data)
        self.generator = self.get_child('generator')

    def get_devices(self):
        """
        :return: dictionary {name: object} of all emulated devices.
        """

        return {o.obj_name(): o for o in self.get_objects_or_children_by_type('EmulatedDevice')}

    def get_stream_blocks(self):
        """
        :return: dictionary {name: object} of all streams.
        """

        return {o.obj_name(): o for o in self.get_objects_or_children_by_type('StreamBlock')}

    def reserve(self, location=None, force=False, wait_for_up=True, timeout=40):
        """ Reserve physical port.

        :param location: port location in the form ip/slot/port.
        :param force: whether to revoke existing reservation (True) or not (False).
        :param wait_for_up: True - wait for port to come up, False - return immediately.
        :param timeout: how long (seconds) to wait for port to come up.

        :todo: seems like reserve takes forever even if port is already owned by the user.
            should test for ownership and take it forcefully only if really needed?
        """

        if location:
            self.location = location
            self.set_attributes(location=self.location)
        else:
            self.location = self.get_attribute('Location')

        if not is_local_host(self.location):
            self.api.perform('AttachPorts', PortList=self.obj_ref(), AutoConnect=True, RevokeOwner=force)
            self.api.apply()
            self.activephy = StcObject(parent=self, objRef=self.get_attribute('activephy-Targets'))
            self.activephy.get_attributes()
            if wait_for_up:
                self.wait_for_states(timeout, 'UP', 'DOWN', 'ADMIN_DOWN')

    def wait_for_states(self, timeout=40, *states):
        """ Wait until port reaches requested state(s).

        :param timeout: how long (seconds) to wait for port to come up.
        :param states: list of requested states.
        """

        for _ in range(timeout):
            if self.activephy.get_attribute('LinkStatus') in states:
                return
            time.sleep(1)
        raise TgnError('Failed to reserve port, port is {} after {} seconds'.
                       format(self.activephy.get_attribute('LinkStatus'), timeout))

    def release(self):
        """ Release the physical port reserved for the port. """

        if not is_local_host(self.location):
            self.api.perform('ReleasePort', portList=self.obj_ref())

    def is_online(self):
        """
        :returns: Port link status.
                  True - port is up.
                  False - port is offline.
        """

        return self.activephy.get_attribute('LinkStatus').lower() == 'up'

    def is_running(self):
        """
        :returns: Returns running state of the port.
                  True -- port is running.
                  False -- port is not running.
        """
        return self.generator.get_attribute('state') == 'RUNNING'

    def send_arp_ns(self):
        """ Send ARP/ND for the port. """
        StcObject.send_arp_ns(self)

    def get_arp_cache(self):
        """ Send ARP/ND for the port. """
        return StcObject.get_arp_cache(self)

    def start(self, blocking=False):
        """ Start port traffic.

        :param blocking: True - wait for traffic end. False - return immidately.
        """
        self.project.start_ports(blocking, self)

    def stop(self):
        """ Stop port traffic. """
        self.project.stop_ports(self)

    def wait(self):
        """ Wait for traffic end. """
        self.project.wait_traffic(self)

    def clear_results(self):
        """ Clear all port results. """
        self.project.clear_results(self)

    def set_media_type(self, media_type):
        """ Set media type for dual phy 1G ports.

        :param media_type: requested media type - EthernetCopper or EthernetFiber.
        """

        if media_type != self.activephy.obj_type():
            new_phy = StcObject(parent=self, objType=media_type)
            self.set_targets(apply_=True, ActivePhy=new_phy.obj_ref())
            self.activephy = new_phy

    #
    # Override inherited methods.
    #

    # Special implementation since we want to remove the 'offile' tag that STC adds even if the
    # 'Append Location to Name' check-box is unchecked.
    def get_name(self):
        """
        :returns: port name without the 'offilne' tag added by STC.
        """
        return re.sub(' \(offline\)$', '', self.get_attribute('Name'))

    # Special implementation since we want emulateddevices under their port while in STC they are
    # under project.
    def get_children(self, *types):
        """ Get all port children including emulateddevices.

        Note: get_children() is not supported.
        """
        children_objs = []
        types = tuple(t.lower() for t in types)
        if 'emulateddevice' in types:
            if not self.project.get_objects_by_type('emulateddevice'):
                self.project.get_children('emulateddevice')
            children_objs = self.get_objects_by_type('emulateddevice')
            types = tuple(t for t in types if t != 'emulateddevice')
        if types:
            children_objs.extend(super(StcPort, self).get_children(*types))
        return children_objs