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)))
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