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 os
6
7from telemetry import test
8from telemetry.core import util
9from telemetry.page import page_measurement
10from telemetry.page import page_set
11
12
13def _CreatePageSetFromPath(path):
14  assert os.path.exists(path)
15
16  page_urls = []
17  serving_dirs = set()
18
19  def _AddPage(path):
20    if not path.endswith('.html'):
21      return
22    if '../' in open(path, 'r').read():
23      # If the page looks like it references its parent dir, include it.
24      serving_dirs.add(os.path.dirname(os.path.dirname(path)))
25    page_urls.append('file://' + path.replace('\\', '/'))
26
27  def _AddDir(dir_path, skipped):
28    for candidate_path in os.listdir(dir_path):
29      if candidate_path == 'resources':
30        continue
31      candidate_path = os.path.join(dir_path, candidate_path)
32      if candidate_path.startswith(tuple([os.path.join(path, s)
33                                          for s in skipped])):
34        continue
35      if os.path.isdir(candidate_path):
36        _AddDir(candidate_path, skipped)
37      else:
38        _AddPage(candidate_path)
39
40  if os.path.isdir(path):
41    skipped = []
42    skipped_file = os.path.join(path, 'Skipped')
43    if os.path.exists(skipped_file):
44      for line in open(skipped_file, 'r').readlines():
45        line = line.strip()
46        if line and not line.startswith('#'):
47          skipped.append(line.replace('/', os.sep))
48    _AddDir(path, skipped)
49  else:
50    _AddPage(path)
51  ps = page_set.PageSet(file_path=os.getcwd()+os.sep, serving_dirs=serving_dirs)
52  for url in page_urls:
53    ps.AddPageWithDefaultRunNavigate(url)
54  return ps
55
56
57class _BlinkPerfMeasurement(page_measurement.PageMeasurement):
58  """Tuns a blink performance test and reports the results."""
59  def __init__(self):
60    super(_BlinkPerfMeasurement, self).__init__('')
61    with open(os.path.join(os.path.dirname(__file__),
62                           'blink_perf.js'), 'r') as f:
63      self._blink_perf_js = f.read()
64
65  @property
66  def results_are_the_same_on_every_page(self):
67    return False
68
69  def WillNavigateToPage(self, page, tab):
70    page.script_to_evaluate_on_commit = self._blink_perf_js
71
72  def CustomizeBrowserOptions(self, options):
73    options.AppendExtraBrowserArgs([
74        '--js-flags=--expose_gc',
75        '--enable-experimental-web-platform-features'
76    ])
77
78  def MeasurePage(self, page, tab, results):
79    tab.WaitForJavaScriptExpression('testRunner.isDone', 600)
80
81    log = tab.EvaluateJavaScript('document.getElementById("log").innerHTML')
82
83    for line in log.splitlines():
84      if not line.startswith('values '):
85        continue
86      parts = line.split()
87      values = [float(v.replace(',', '')) for v in parts[1:-1]]
88      units = parts[-1]
89      metric = page.display_name.split('.')[0].replace('/', '_')
90      results.Add(metric, units, values)
91      break
92
93    print log
94
95
96class BlinkPerfAll(test.Test):
97  tag = 'all'
98  test = _BlinkPerfMeasurement
99
100  def CreatePageSet(self, options):
101    path = os.path.join(util.GetChromiumSrcDir(),
102        'third_party', 'WebKit', 'PerformanceTests')
103    return _CreatePageSetFromPath(path)
104
105class BlinkPerfAnimation(test.Test):
106  tag = 'animation'
107  test = _BlinkPerfMeasurement
108
109  def CreatePageSet(self, options):
110    path = os.path.join(util.GetChromiumSrcDir(),
111        'third_party', 'WebKit', 'PerformanceTests', 'Animation')
112    return _CreatePageSetFromPath(path)
113