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
5import math
6import os
7
8from metrics import power
9from telemetry import benchmark
10from telemetry.page import page_set
11from telemetry.page import page_test
12from telemetry.value import scalar
13
14
15class _DromaeoMeasurement(page_test.PageTest):
16  def __init__(self):
17    super(_DromaeoMeasurement, self).__init__()
18    self._power_metric = None
19
20  def CustomizeBrowserOptions(self, options):
21    power.PowerMetric.CustomizeBrowserOptions(options)
22
23  def WillStartBrowser(self, platform):
24    self._power_metric = power.PowerMetric(platform)
25
26  def DidNavigateToPage(self, page, tab):
27    self._power_metric.Start(page, tab)
28
29  def ValidateAndMeasurePage(self, page, tab, results):
30    tab.WaitForJavaScriptExpression(
31        'window.document.getElementById("pause") &&' +
32        'window.document.getElementById("pause").value == "Run"',
33        120)
34
35    # Start spying on POST request that will report benchmark results, and
36    # intercept result data.
37    tab.ExecuteJavaScript('(function() {' +
38                          '  var real_jquery_ajax_ = window.jQuery;' +
39                          '  window.results_ = "";' +
40                          '  window.jQuery.ajax = function(request) {' +
41                          '    if (request.url == "store.php") {' +
42                          '      window.results_ =' +
43                          '          decodeURIComponent(request.data);' +
44                          '      window.results_ = window.results_.substring(' +
45                          '          window.results_.indexOf("=") + 1, ' +
46                          '          window.results_.lastIndexOf("&"));' +
47                          '      real_jquery_ajax_(request);' +
48                          '    }' +
49                          '  };' +
50                          '})();')
51    # Starts benchmark.
52    tab.ExecuteJavaScript('window.document.getElementById("pause").click();')
53
54    tab.WaitForJavaScriptExpression('!!window.results_', 600)
55
56    self._power_metric.Stop(page, tab)
57    self._power_metric.AddResults(tab, results)
58
59    score = eval(tab.EvaluateJavaScript('window.results_ || "[]"'))
60
61    def Escape(k):
62      chars = [' ', '.', '-', '/', '(', ')', '*']
63      for c in chars:
64        k = k.replace(c, '_')
65      return k
66
67    def AggregateData(container, key, value):
68      if key not in container:
69        container[key] = {'count': 0, 'sum': 0}
70      container[key]['count'] += 1
71      container[key]['sum'] += math.log(value)
72
73    suffix = page.url[page.url.index('?') + 1 :]
74    def AddResult(name, value):
75      important = False
76      if name == suffix:
77        important = True
78      results.AddValue(scalar.ScalarValue(
79          results.current_page, Escape(name), 'runs/s', value, important))
80
81    aggregated = {}
82    for data in score:
83      AddResult('%s/%s' % (data['collection'], data['name']),
84                data['mean'])
85
86      top_name = data['collection'].split('-', 1)[0]
87      AggregateData(aggregated, top_name, data['mean'])
88
89      collection_name = data['collection']
90      AggregateData(aggregated, collection_name, data['mean'])
91
92    for key, value in aggregated.iteritems():
93      AddResult(key, math.exp(value['sum'] / value['count']))
94
95class _DromaeoBenchmark(benchmark.Benchmark):
96  """A base class for Dromaeo benchmarks."""
97  test = _DromaeoMeasurement
98
99  def CreatePageSet(self, options):
100    """Makes a PageSet for Dromaeo benchmarks."""
101    # Subclasses are expected to define class members called query_param and
102    # tag.
103    if not hasattr(self, 'query_param') or not hasattr(self, 'tag'):
104      raise NotImplementedError('query_param or tag not in Dromaeo benchmark.')
105    archive_data_file = '../page_sets/data/dromaeo.%s.json' % self.tag
106    ps = page_set.PageSet(
107        make_javascript_deterministic=False,
108        archive_data_file=archive_data_file,
109        file_path=os.path.abspath(__file__))
110    url = 'http://dromaeo.com?%s' % self.query_param
111    ps.AddPageWithDefaultRunNavigate(url)
112    return ps
113
114
115class DromaeoDomCoreAttr(_DromaeoBenchmark):
116  """Dromaeo DOMCore attr JavaScript benchmark."""
117  tag = 'domcoreattr'
118  query_param = 'dom-attr'
119
120
121class DromaeoDomCoreModify(_DromaeoBenchmark):
122  """Dromaeo DOMCore modify JavaScript benchmark."""
123  tag = 'domcoremodify'
124  query_param = 'dom-modify'
125
126
127class DromaeoDomCoreQuery(_DromaeoBenchmark):
128  """Dromaeo DOMCore query JavaScript benchmark."""
129  tag = 'domcorequery'
130  query_param = 'dom-query'
131
132
133class DromaeoDomCoreTraverse(_DromaeoBenchmark):
134  """Dromaeo DOMCore traverse JavaScript benchmark."""
135  tag = 'domcoretraverse'
136  query_param = 'dom-traverse'
137
138
139class DromaeoJslibAttrJquery(_DromaeoBenchmark):
140  """Dromaeo JSLib attr jquery JavaScript benchmark"""
141  tag = 'jslibattrjquery'
142  query_param = 'jslib-attr-jquery'
143
144
145class DromaeoJslibAttrPrototype(_DromaeoBenchmark):
146  """Dromaeo JSLib attr prototype JavaScript benchmark"""
147  tag = 'jslibattrprototype'
148  query_param = 'jslib-attr-prototype'
149
150
151class DromaeoJslibEventJquery(_DromaeoBenchmark):
152  """Dromaeo JSLib event jquery JavaScript benchmark"""
153  tag = 'jslibeventjquery'
154  query_param = 'jslib-event-jquery'
155
156
157class DromaeoJslibEventPrototype(_DromaeoBenchmark):
158  """Dromaeo JSLib event prototype JavaScript benchmark"""
159  tag = 'jslibeventprototype'
160  query_param = 'jslib-event-prototype'
161
162
163@benchmark.Disabled('xp')  # crbug.com/389731
164class DromaeoJslibModifyJquery(_DromaeoBenchmark):
165  """Dromaeo JSLib modify jquery JavaScript benchmark"""
166  tag = 'jslibmodifyjquery'
167  query_param = 'jslib-modify-jquery'
168
169
170class DromaeoJslibModifyPrototype(_DromaeoBenchmark):
171  """Dromaeo JSLib modify prototype JavaScript benchmark"""
172  tag = 'jslibmodifyprototype'
173  query_param = 'jslib-modify-prototype'
174
175
176class DromaeoJslibStyleJquery(_DromaeoBenchmark):
177  """Dromaeo JSLib style jquery JavaScript benchmark"""
178  tag = 'jslibstylejquery'
179  query_param = 'jslib-style-jquery'
180
181
182class DromaeoJslibStylePrototype(_DromaeoBenchmark):
183  """Dromaeo JSLib style prototype JavaScript benchmark"""
184  tag = 'jslibstyleprototype'
185  query_param = 'jslib-style-prototype'
186
187
188class DromaeoJslibTraverseJquery(_DromaeoBenchmark):
189  """Dromaeo JSLib traverse jquery JavaScript benchmark"""
190  tag = 'jslibtraversejquery'
191  query_param = 'jslib-traverse-jquery'
192
193
194class DromaeoJslibTraversePrototype(_DromaeoBenchmark):
195  """Dromaeo JSLib traverse prototype JavaScript benchmark"""
196  tag = 'jslibtraverseprototype'
197  query_param = 'jslib-traverse-prototype'
198
199
200class DromaeoCSSQueryJquery(_DromaeoBenchmark):
201  """Dromaeo CSS Query jquery JavaScript benchmark"""
202  tag = 'cssqueryjquery'
203  query_param = 'cssquery-jquery'
204
205