From 60881d6546a1b8833ff7e5e675bb901112d89c42 Mon Sep 17 00:00:00 2001 From: Ruben Rodriguez Buchillon Date: Tue, 24 Jul 2018 18:57:23 +0800 Subject: stats_manager: more informative nan summary output Now for the formatted output string, if any value a domain is NaN, the domains gets tagged with a * and a help text gets added at the end of the summary to highlight this issue. CQ-DEPEND=CL:1140025 BRANCH=None BUG=chromium:806146, chromium:760267 TEST=unit tests added & pass Change-Id: I30791053bb1645065fa2bfd8305cc840a4a88031 Signed-off-by: Ruben Rodriguez Buchillon Reviewed-on: https://chromium-review.googlesource.com/1140032 Reviewed-by: Mengqi Guo --- extra/usb_power/stats_manager.py | 15 ++++++++++++++- extra/usb_power/stats_manager_unittest.py | 25 +++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/extra/usb_power/stats_manager.py b/extra/usb_power/stats_manager.py index 66dd915a86..2d864e5cc0 100644 --- a/extra/usb_power/stats_manager.py +++ b/extra/usb_power/stats_manager.py @@ -15,6 +15,8 @@ import os import numpy STATS_PREFIX = '@@' +NAN_TAG = '*' +NAN_DESCRIPTION = '%s domains contain NaN samples' % NAN_TAG LONG_UNIT = { '': 'N/A', @@ -68,6 +70,8 @@ class StatsManager(object): _order: list of formatting order for domains. Domains not listed are displayed in sorted order _hide_domains: collection of domains to hide when formatting summary string + _accept_nan: flag to indicate if NaN samples are acceptable + _nan_domains: set to keep track of which domains contain NaN samples _summary: dict of stats per domain (key): min, max, count, mean, stddev _logger = StatsManager logger @@ -86,8 +90,9 @@ class StatsManager(object): self._smid = smid self._order = order self._hide_domains = hide_domains - self._summary = {} self._accept_nan = accept_nan + self._nan_domains = set() + self._summary = {} self._logger = logging.getLogger('StatsManager') def AddSample(self, domain, sample): @@ -110,6 +115,8 @@ class StatsManager(object): if not self._accept_nan and math.isnan(sample): raise StatsManagerError('accept_nan is false. Cannot add NaN sample.') self._data[domain].append(sample) + if math.isnan(sample): + self._nan_domains.add(domain) def SetUnit(self, domain, unit): """Set the unit for a domain. @@ -160,10 +167,14 @@ class StatsManager(object): display_order = [key for key in self._order if key in domains_to_display] domains_to_display -= set(display_order) display_order.extend(sorted(domains_to_display)) + nan_in_output = False for domain in display_order: stats = self._summary[domain] if not domain.endswith(self._unit[domain]): domain = '%s_%s' % (domain, self._unit[domain]) + if domain in self._nan_domains: + domain = '%s%s' % (domain, NAN_TAG) + nan_in_output = True row = [domain] row.append(str(stats['count'])) for entry in headers[2:]: @@ -181,6 +192,8 @@ class StatsManager(object): for i in range(len(row)): formatted_row += row[i].rjust(max_col_width[i] + 2) formatted_lines.append(formatted_row) + if nan_in_output: + formatted_lines.append('%s %s' % (prefix, NAN_DESCRIPTION)) if self._title: line_length = len(formatted_lines[0]) diff --git a/extra/usb_power/stats_manager_unittest.py b/extra/usb_power/stats_manager_unittest.py index ed0b424944..9d0d708af0 100644 --- a/extra/usb_power/stats_manager_unittest.py +++ b/extra/usb_power/stats_manager_unittest.py @@ -173,6 +173,31 @@ class TestStatsManager(unittest.TestCase): for fname in files: self.assertTrue(os.path.basename(fname).startswith(identifier)) + def test_SummaryToStringNaNHelp(self): + """NaN containing row gets tagged with *, help banner gets added.""" + help_banner_exp = '%s %s' % (stats_manager.STATS_PREFIX, + stats_manager.NAN_DESCRIPTION) + nan_domain = 'A-domain' + nan_domain_exp = '%s%s' % (nan_domain, stats_manager.NAN_TAG) + # NaN helper banner is added when a NaN domain is found & domain gets tagged + data = stats_manager.StatsManager() + data.AddSample(nan_domain, float('NaN')) + data.AddSample(nan_domain, 17) + data.AddSample('B-domain', 17) + data.CalculateStats() + summarystr = data.SummaryToString() + self.assertIn(help_banner_exp, summarystr) + self.assertIn(nan_domain_exp, summarystr) + # NaN helper banner is not added when no NaN domain output, no tagging + data = stats_manager.StatsManager() + # nan_domain in this scenario does not contain any NaN + data.AddSample(nan_domain, 19) + data.AddSample('B-domain', 17) + data.CalculateStats() + summarystr = data.SummaryToString() + self.assertNotIn(help_banner_exp, summarystr) + self.assertNotIn(nan_domain_exp, summarystr) + def test_SummaryToStringTitle(self): """Title shows up in SummaryToString if title specified.""" title = 'titulo' -- cgit v1.2.1