def handle_tracer_class(self, event): s = Structure(event[Parser.F_MESSAGE]) # TODO only for debugging #print("tracer class:", repr(s)) name = s.name[:-len('.class')] record = { 'class': s, 'scope': {}, 'value': {}, } self.records[name] = record for k, v in s.values.items(): if v.name == 'scope': # TODO only for debugging #print("scope: [%s]=%s" % (k, v)) record['scope'][k] = v elif v.name == 'value': # skip non numeric and those without min/max if (v.values['type'] in _NUMERIC_TYPES and 'min' in v.values and 'max' in v.values): # TODO only for debugging #print("value: [%s]=%s" % (k, v)) record['value'][k] = v
def handle_tracer_entry(self, event): if event[Parser.F_FUNCTION]: return msg = event[Parser.F_MESSAGE] p = msg.find(',') if p == -1: return entry_name = msg[:p] if entry_name not in _HANDLED_CLASSES: return try: s = Structure(msg) except ValueError: logger.warning("failed to parse: '%s'", msg) return if entry_name == 'new-element': ix = int(s.values['ix']) self.element_names[ix] = s.values['name'] self.element_info[ix] = 'Element Type: %s' % s.values['type'] elif entry_name == 'new-pad': pad_type = s.values['type'] if self.show_ghost_pads or pad_type not in [ 'GstGhostPad', 'GstProxyPad' ]: parent_ix = int(s.values['parent-ix']) parent_name = self.element_names.get(parent_ix, '') ix = int(s.values['ix']) self.pad_names[ix] = '%s.%s' % (parent_name, s.values['name']) self.pad_info[ix] = '(%s, Pad Type: %s)' % ( self.element_info.get(parent_ix, ''), pad_type) elif entry_name == 'event': self._log_event(s) else: # 'buffer' self._log_buffer(s)
def test_regressions(self): for s in REGRESSIONS: structure = Structure(s)
def test_nested_structure_has_sub_structure(self): structure = Structure(NESTED_STRUCTURE) self.assertEqual(structure.types['nested'], 'structure') self.assertIsInstance(structure.values['nested'], Structure)
def test_parses_nested_structure(self): structure = Structure(NESTED_STRUCTURE) self.assertEqual(structure.text, NESTED_STRUCTURE)
def test_parses_boolean_value(self): structure = Structure(MISC_TYPES_STRUCTURE) self.assertEqual(structure.values['key3'], True)
def test_parses_int_value(self): structure = Structure(MISC_TYPES_STRUCTURE) self.assertEqual(structure.values['key2'], 5)
def test_handles_bad_key(self): structure = None with self.assertRaises(ValueError): structure = Structure(BAD_KEY)
def test_parses_key(self): structure = Structure(SINGLE_VALUE_STRUCTURE) self.assertIn('key', structure.types) self.assertIn('key', structure.values)
def test_parses_name(self): structure = Structure(SINGLE_VALUE_STRUCTURE) self.assertEqual(structure.name, 'foo')
def test_parses_single_value_structure(self): structure = Structure(SINGLE_VALUE_STRUCTURE) self.assertEqual(structure.text, SINGLE_VALUE_STRUCTURE)
def test_parses_name_in_empty_structure(self): structure = Structure(EMPTY_STRUCTURE) self.assertEqual(structure.name, 'foo')
def test_parses_empty_structure(self): structure = Structure(EMPTY_STRUCTURE) self.assertEqual(structure.text, EMPTY_STRUCTURE)
def test_handles_bad_type2(self): structure = None with self.assertRaises(ValueError): structure = Structure(BAD_TYPE2)
def test_parses_type(self): structure = Structure(SINGLE_VALUE_STRUCTURE) self.assertEqual(structure.types['key'], 'string')
def handle_tracer_class(self, event): s = Structure(event[Parser.F_MESSAGE]) print(s.name)
def test_parses_string_value(self): structure = Structure(MISC_TYPES_STRUCTURE) self.assertEqual(structure.values['key1'], 'value')
def handle_tracer_entry(self, event): # use first field in message (structure-id) if none if event[Parser.F_FUNCTION]: return msg = event[Parser.F_MESSAGE] p = msg.find(',') if p == -1: return entry_name = msg[:p] if self.classes: if not any([fnmatch(entry_name, c) for c in self.classes]): return record = self.records.get(entry_name) if not record: return try: s = Structure(msg) except ValueError: logger.warning("failed to parse: '%s'", msg) return # aggregate event based on class for sk, sv in record['scope'].items(): # look up bin by scope (or create new) key = (_SCOPE_RELATED_TO[sv.values['related-to']] + ":" + str(s.values[sk])) scope = self.data.get(key) if not scope: scope = {} self.data[key] = scope for vk, vv in record['value'].items(): # skip optional fields if not vk in s.values: continue if not s.values.get('have-' + vk, True): continue key = entry_name + "/" + vk data = scope.get(key) if not data: data = {'num': 0} if not '_FLAGS_AGGREGATED' in vv.values.get('flags', ''): data['sum'] = 0 if 'max' in vv.values and 'min' in vv.values: data['min'] = int(vv.values['max']) data['max'] = int(vv.values['min']) else: # aggregated: don't average, collect first value data['min'] = int(s.values[vk]) scope[key] = data # update min/max/sum and count via value dv = int(s.values[vk]) data['num'] += 1 if 'sum' in data: data['sum'] += dv if 'min' in data: data['min'] = min(dv, data['min']) if 'max' in data: data['max'] = max(dv, data['max']) else: # aggregated: collect last value data['max'] = dv
def test_handles_bad_name(self): structure = None with self.assertRaises(ValueError): structure = Structure(BAD_NAME)