Home | History | Annotate | Download | only in metrics
      1 # Copyright 2013 The Chromium Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 """This is a helper module to get and manipulate histogram data.
      6 
      7 The histogram data is the same data as is visible from "chrome://histograms".
      8 More information can be found at: chromium/src/base/metrics/histogram.h
      9 """
     10 
     11 import json
     12 import logging
     13 
     14 BROWSER_HISTOGRAM = 'browser_histogram'
     15 RENDERER_HISTOGRAM = 'renderer_histogram'
     16 
     17 
     18 def CustomizeBrowserOptions(options):
     19   """Allows histogram collection."""
     20   options.AppendExtraBrowserArgs(['--enable-stats-collection-bindings'])
     21 
     22 
     23 def SubtractHistogram(histogram_json, start_histogram_json):
     24   """Subtracts a previous histogram from a histogram.
     25 
     26   Both parameters and the returned result are json serializations.
     27   """
     28   start_histogram = json.loads(start_histogram_json)
     29   # It's ok if the start histogram is empty (we had no data, maybe even no
     30   # histogram at all, at the start of the test).
     31   if 'buckets' not in start_histogram:
     32     return histogram_json
     33 
     34   histogram = json.loads(histogram_json)
     35   if ('pid' in start_histogram and 'pid' in histogram
     36       and start_histogram['pid'] != histogram['pid']):
     37     raise Exception(
     38         'Trying to compare histograms from different processes (%d and %d)'
     39         % (start_histogram['pid'], histogram['pid']))
     40 
     41   start_histogram_buckets = dict()
     42   for b in start_histogram['buckets']:
     43     start_histogram_buckets[b['low']] = b['count']
     44 
     45   new_buckets = []
     46   for b in histogram['buckets']:
     47     new_bucket = b
     48     low = b['low']
     49     if low in start_histogram_buckets:
     50       new_bucket['count'] = b['count'] - start_histogram_buckets[low]
     51       if new_bucket['count'] < 0:
     52         logging.error('Histogram subtraction error, starting histogram most '
     53                       'probably invalid.')
     54     if new_bucket['count']:
     55       new_buckets.append(new_bucket)
     56   histogram['buckets'] = new_buckets
     57   histogram['count'] -= start_histogram['count']
     58 
     59   return json.dumps(histogram)
     60 
     61 
     62 def GetHistogram(histogram_type, histogram_name, tab):
     63   """Get a json serialization of a histogram."""
     64   assert histogram_type in [BROWSER_HISTOGRAM, RENDERER_HISTOGRAM]
     65   function = 'getHistogram'
     66   if histogram_type == BROWSER_HISTOGRAM:
     67     function = 'getBrowserHistogram'
     68   histogram_json = tab.EvaluateJavaScript(
     69       'statsCollectionController.%s("%s")' %
     70       (function, histogram_name))
     71   if histogram_json:
     72     return histogram_json
     73   return None
     74 
     75 
     76 def GetHistogramCount(histogram_type, histogram_name, tab):
     77   """Get the count of events for the given histograms."""
     78   histogram_json = GetHistogram(histogram_type, histogram_name, tab)
     79   histogram = json.loads(histogram_json)
     80   if 'count' in histogram:
     81     return histogram['count']
     82   else:
     83     return 0
     84 
     85 def GetHistogramSum(histogram_type, histogram_name, tab):
     86   """Get the sum of events for the given histograms."""
     87   histogram_json = GetHistogram(histogram_type, histogram_name, tab)
     88   histogram = json.loads(histogram_json)
     89   if 'sum' in histogram:
     90     return histogram['sum']
     91   else:
     92     return 0
     93