1 # Copyright (c) 2012 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.
9 from telemetry.core import util
10 from telemetry.page import page as page_module
11 from telemetry.page import page_set_archive_info
13 class PageSetError(Exception):
17 class PageSet(object):
18 def __init__(self, file_path=None, description='', archive_data_file='',
19 credentials_path=None, user_agent_type=None,
20 make_javascript_deterministic=True, startup_url='',
22 # The default value of file_path is location of the file that define this
23 # page set instance's class.
25 file_path = inspect.getfile(self.__class__)
26 # Turn pyc file into py files if we can
27 if file_path.endswith('.pyc') and os.path.exists(file_path[:-1]):
28 file_path = file_path[:-1]
30 self.file_path = file_path
31 # These attributes can be set dynamically by the page set.
32 self.description = description
33 self.archive_data_file = archive_data_file
34 self.credentials_path = credentials_path
35 self.user_agent_type = user_agent_type
36 self.make_javascript_deterministic = make_javascript_deterministic
37 self._wpr_archive_info = None
38 self.startup_url = startup_url
40 self.serving_dirs = set()
41 serving_dirs = [] if serving_dirs is None else serving_dirs
42 # Makes sure that page_set's serving_dirs are absolute paths
43 for sd in serving_dirs:
45 self.serving_dirs.add(os.path.realpath(sd))
47 self.serving_dirs.add(os.path.realpath(os.path.join(self.base_dir, sd)))
49 def AddPage(self, page):
50 assert page.page_set is self
51 self.pages.append(page)
53 def AddPageWithDefaultRunNavigate(self, page_url):
54 """ Add a simple page with url equals to page_url that contains only default
57 self.AddPage(page_module.Page(
58 page_url, self, self.base_dir))
61 def FromFile(file_path):
62 _, ext_name = os.path.splitext(file_path)
64 return PageSet.FromPythonFile(file_path)
66 raise PageSetError("Pageset %s has unsupported file type" % file_path)
69 def FromPythonFile(file_path):
71 module = util.GetPythonPageSetModule(file_path)
73 if m.endswith('PageSet') and m != 'PageSet':
74 page_set_classes.append(getattr(module, m))
75 if len(page_set_classes) != 1:
76 raise PageSetError("Pageset file needs to contain exactly 1 pageset class"
77 " with prefix 'PageSet'")
78 page_set = page_set_classes[0]()
79 for page in page_set.pages:
80 page_class = page.__class__
82 for method_name, method in inspect.getmembers(page_class,
83 predicate=inspect.ismethod):
84 if method_name.startswith("Run"):
85 args, _, _, _ = inspect.getargspec(method)
86 if not (args[0] == "self" and args[1] == "action_runner"):
87 raise PageSetError("""Definition of Run<...> method of all
88 pages in %s must be in the form of def Run<...>(self, action_runner):"""
94 if os.path.isfile(self.file_path):
95 return os.path.dirname(self.file_path)
100 def wpr_archive_info(self): # pylint: disable=E0202
101 """Lazily constructs wpr_archive_info if it's not set and returns it."""
102 if self.archive_data_file and not self._wpr_archive_info:
103 self._wpr_archive_info = (
104 page_set_archive_info.PageSetArchiveInfo.FromFile(
105 os.path.join(self.base_dir, self.archive_data_file)))
106 return self._wpr_archive_info
108 @wpr_archive_info.setter
109 def wpr_archive_info(self, value): # pylint: disable=E0202
110 self._wpr_archive_info = value
112 def ContainsOnlyFileURLs(self):
113 for page in self.pages:
118 def ReorderPageSet(self, results_file):
119 """Reorders this page set based on the results of a past run."""
121 for page in self.pages:
122 page_set_dict[page.url] = page
125 with open(results_file, 'rb') as csv_file:
126 csv_reader = csv.reader(csv_file)
127 csv_header = csv_reader.next()
129 if 'url' not in csv_header:
130 raise Exception('Unusable results_file.')
132 url_index = csv_header.index('url')
134 for csv_row in csv_reader:
135 if csv_row[url_index] in page_set_dict:
136 self.AddPage(page_set_dict[csv_row[url_index]])
138 raise Exception('Unusable results_file.')
142 def WprFilePathForPage(self, page):
143 if not self.wpr_archive_info:
145 return self.wpr_archive_info.WprFilePathForPage(page)
148 return self.pages.__iter__()
151 return len(self.pages)
153 def __getitem__(self, key):
154 return self.pages[key]
156 def __setitem__(self, key, value):
157 self.pages[key] = value