summaryrefslogtreecommitdiff
path: root/chromium/tools/perf/measurements/blink_perf.py
blob: 39ed0a29583a5a84f3eba1d2b8d58c034f3a4dd6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# Copyright (c) 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""This measurement runs a blink performance test and reports the results."""

import os
import sys

from telemetry.core import util
from telemetry.page import page_measurement
from telemetry.page import page_set


def CreatePageSetFromPath(path):
  assert os.path.exists(path)

  page_set_dict = {'pages': []}

  def _AddPage(path):
    if not path.endswith('.html'):
      return
    if '../' in open(path, 'r').read():
      # If the page looks like it references its parent dir, include it.
      page_set_dict['serving_dirs'] = [os.path.dirname(os.path.dirname(path))]
    page_set_dict['pages'].append({'url':
                                   'file://' + path.replace('\\', '/')})

  def _AddDir(dir_path, skipped):
    for candidate_path in os.listdir(dir_path):
      if candidate_path == 'resources':
        continue
      candidate_path = os.path.join(dir_path, candidate_path)
      if candidate_path.startswith(tuple([os.path.join(path, s)
                                          for s in skipped])):
        continue
      if os.path.isdir(candidate_path):
        _AddDir(candidate_path, skipped)
      else:
        _AddPage(candidate_path)

  if os.path.isdir(path):
    skipped = []
    skipped_file = os.path.join(path, 'Skipped')
    if os.path.exists(skipped_file):
      for line in open(skipped_file, 'r').readlines():
        line = line.strip()
        if line and not line.startswith('#'):
          skipped.append(line.replace('/', os.sep))
    _AddDir(path, skipped)
  else:
    _AddPage(path)
  return page_set.PageSet.FromDict(page_set_dict, os.getcwd() + os.sep)


class BlinkPerf(page_measurement.PageMeasurement):
  def __init__(self):
    super(BlinkPerf, self).__init__('')
    with open(os.path.join(os.path.dirname(__file__),
                           'blink_perf.js'), 'r') as f:
      self._blink_perf_js = f.read()

  def CreatePageSet(self, args, options):
    if len(args) < 2:
      print 'Must specify a file or directory to run.'
      sys.exit(1)

    page_set_arg = args[1]

    if not os.path.exists(page_set_arg):
      print '%s does not exist.' % page_set_arg
      sys.exit(1)

    return CreatePageSetFromPath(page_set_arg)

  @property
  def results_are_the_same_on_every_page(self):
    return False

  def WillNavigateToPage(self, page, tab):
    page.script_to_evaluate_on_commit = self._blink_perf_js

  def CustomizeBrowserOptions(self, options):
    options.AppendExtraBrowserArg('--js-flags=--expose_gc')

  def MeasurePage(self, page, tab, results):
    def _IsDone():
      return tab.EvaluateJavaScript('testRunner.isDone')
    util.WaitFor(_IsDone, 600)

    log = tab.EvaluateJavaScript('document.getElementById("log").innerHTML')

    for line in log.splitlines():
      if not line.startswith('values '):
        continue
      parts = line.split()
      values = [float(v.replace(',', '')) for v in parts[1:-1]]
      units = parts[-1]
      metric = page.display_url.split('.')[0].replace('/', '_')
      results.Add(metric, units, values)
      break

    print log