• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2014 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 sys
6import os
7
8
9def _AddToPathIfNeeded(path):
10  if path not in sys.path:
11    sys.path.insert(0, path)
12
13
14def _IsRunningInAppEngine():
15  # Cloud workers run on appengine but in a managed vm, which gives them full
16  # access to the filesystem. Since they manage their own checkout of catapult
17  # to do trace processing, they need the paths properly setup.
18  if 'PI_CLOUD_WORKER' in os.environ:
19    return False
20  if 'SERVER_SOFTWARE' not in os.environ:
21    return False
22  if os.environ['SERVER_SOFTWARE'].startswith('Google App Engine/'):
23    return True
24  if os.environ['SERVER_SOFTWARE'].startswith('Development/'):
25    return True
26  return False
27
28
29def UpdateSysPathIfNeeded():
30  p = PerfInsightsProject()
31
32  _AddToPathIfNeeded(p.perf_insights_third_party_path)
33
34  # TODO(fmeawad): We should add catapult projects even inside
35  # appengine, see issue #1246
36  if not _IsRunningInAppEngine():
37    _AddToPathIfNeeded(p.catapult_path)
38    _AddToPathIfNeeded(p.tracing_root_path)
39    _AddToPathIfNeeded(p.py_vulcanize_path)
40
41    import tracing_project
42    tracing_project.UpdateSysPathIfNeeded()
43
44
45def _FindAllFilesRecursive(source_paths):
46  assert isinstance(source_paths, list)
47  all_filenames = set()
48  for source_path in source_paths:
49    for dirpath, _, filenames in os.walk(source_path):
50      for f in filenames:
51        if f.startswith('.'):
52          continue
53        x = os.path.abspath(os.path.join(dirpath, f))
54        all_filenames.add(x)
55  return all_filenames
56
57
58def _IsFilenameATest(x):  # pylint: disable=unused-argument
59  if x.endswith('_test.js'):
60    return True
61
62  if x.endswith('_test.html'):
63    return True
64
65  if x.endswith('_unittest.js'):
66    return True
67
68  if x.endswith('_unittest.html'):
69    return True
70
71  # TODO(nduca): Add content test?
72  return False
73
74
75class PerfInsightsProject(object):
76  catapult_path = os.path.abspath(
77      os.path.join(os.path.dirname(__file__), os.path.pardir))
78
79  perf_insights_root_path = os.path.join(catapult_path, 'perf_insights')
80  perf_insights_src_path = os.path.join(
81      perf_insights_root_path, 'perf_insights')
82  perf_insights_ui_path = os.path.join(perf_insights_src_path, 'ui')
83  perf_insights_test_data_path = os.path.join(
84      perf_insights_root_path, 'test_data')
85  perf_insights_examples_path = os.path.join(
86      perf_insights_root_path, 'perf_insights_examples')
87
88  perf_insights_third_party_path = os.path.join(
89      perf_insights_root_path, 'third_party')
90
91  tracing_root_path = os.path.join(catapult_path, 'tracing')
92
93  py_vulcanize_path = os.path.join(catapult_path, 'third_party', 'py_vulcanize')
94
95  def __init__(self):  # pylint: disable=unused-argument
96    self._source_paths = None
97
98  @property
99  def source_paths(self):
100    # We lazily init of source_paths because for perf_insights_project's
101    # UpdateSysPathIfNeeded to run, the PerfInsightsProject must be __init__'d,
102    # because thats where we centralize the various directory names.
103    # And, for source_paths to be set up, we need the UpdateSysPathIfNeeded to
104    # have run! We use laziness to resolve this cyclic dependency.
105    if self._source_paths is None:
106      self._source_paths = []
107      self._source_paths.append(self.perf_insights_root_path)
108
109      import tracing_project as tracing_project_module
110      tracing_project = tracing_project_module.TracingProject()
111      self._source_paths.extend(tracing_project.source_paths)
112
113    return self._source_paths
114
115  def GetAbsPathFromHRef(self, href):
116    for source_path in self.source_paths:
117      candidate = os.path.abspath(os.path.join(source_path, href[1:]))
118      if os.path.exists(candidate):
119        return candidate
120    return None
121
122  def CreateVulcanizer(self):
123    from py_vulcanize import project as project_module
124    return project_module.Project(self.source_paths)
125
126  def IsD8CompatibleFile(self, filename):
127    if filename.startswith(self.perf_insights_ui_path):
128      return False
129    return True
130
131  def FindAllTestModuleRelPaths(self, pred=None):
132    if pred is None:
133      pred = lambda x: True
134    all_filenames = _FindAllFilesRecursive([self.perf_insights_src_path,
135                                            self.perf_insights_examples_path])
136    test_module_filenames = [x for x in all_filenames if
137                             _IsFilenameATest(x) and pred(x)]
138    test_module_filenames.sort()
139
140    return [os.path.relpath(x, self.perf_insights_root_path)
141            for x in test_module_filenames]
142
143  def FindAllD8TestModuleRelPaths(self):
144    return self.FindAllTestModuleRelPaths(pred=self.IsD8CompatibleFile)
145