Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / tools / telemetry / telemetry / page / page_set.py
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.
4
5 import csv
6 import inspect
7 import os
8
9 from telemetry.core import util
10 from telemetry.page import page as page_module
11 from telemetry.page import page_set_archive_info
12
13 class PageSetError(Exception):
14   pass
15
16
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='',
21                serving_dirs=None):
22     # The default value of file_path is location of the file that define this
23     # page set instance's class.
24     if file_path is None:
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]
29
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
39     self.pages = []
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:
44       if os.path.isabs(sd):
45         self.serving_dirs.add(os.path.realpath(sd))
46       else:
47         self.serving_dirs.add(os.path.realpath(os.path.join(self.base_dir, sd)))
48
49   def AddPage(self, page):
50     assert page.page_set is self
51     self.pages.append(page)
52
53   def AddPageWithDefaultRunNavigate(self, page_url):
54     """ Add a simple page with url equals to page_url that contains only default
55     RunNavigateSteps.
56     """
57     self.AddPage(page_module.Page(
58       page_url, self, self.base_dir))
59
60   @staticmethod
61   def FromFile(file_path):
62     _, ext_name = os.path.splitext(file_path)
63     if ext_name == '.py':
64       return PageSet.FromPythonFile(file_path)
65     else:
66       raise PageSetError("Pageset %s has unsupported file type" % file_path)
67
68   @staticmethod
69   def FromPythonFile(file_path):
70     page_set_classes = []
71     module = util.GetPythonPageSetModule(file_path)
72     for m in dir(module):
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__
81
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):"""
89                                      % file_path)
90     return page_set
91
92   @property
93   def base_dir(self):
94     if os.path.isfile(self.file_path):
95       return os.path.dirname(self.file_path)
96     else:
97       return self.file_path
98
99   @property
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
107
108   @wpr_archive_info.setter
109   def wpr_archive_info(self, value):  # pylint: disable=E0202
110     self._wpr_archive_info = value
111
112   def ContainsOnlyFileURLs(self):
113     for page in self.pages:
114       if not page.is_file:
115         return False
116     return True
117
118   def ReorderPageSet(self, results_file):
119     """Reorders this page set based on the results of a past run."""
120     page_set_dict = {}
121     for page in self.pages:
122       page_set_dict[page.url] = page
123
124     pages = []
125     with open(results_file, 'rb') as csv_file:
126       csv_reader = csv.reader(csv_file)
127       csv_header = csv_reader.next()
128
129       if 'url' not in csv_header:
130         raise Exception('Unusable results_file.')
131
132       url_index = csv_header.index('url')
133
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]])
137         else:
138           raise Exception('Unusable results_file.')
139
140     return pages
141
142   def WprFilePathForPage(self, page):
143     if not self.wpr_archive_info:
144       return None
145     return self.wpr_archive_info.WprFilePathForPage(page)
146
147   def __iter__(self):
148     return self.pages.__iter__()
149
150   def __len__(self):
151     return len(self.pages)
152
153   def __getitem__(self, key):
154     return self.pages[key]
155
156   def __setitem__(self, key, value):
157     self.pages[key] = value