Index: tools/telemetry/telemetry/page/page_set.py |
diff --git a/tools/telemetry/telemetry/page/page_set.py b/tools/telemetry/telemetry/page/page_set.py |
index f97cb0d69cf900979e158d5dc2fcf0105a6dad92..10d38f2fd1aff2274c9f055f436ec028c169aecb 100644 |
--- a/tools/telemetry/telemetry/page/page_set.py |
+++ b/tools/telemetry/telemetry/page/page_set.py |
@@ -3,47 +3,67 @@ |
# found in the LICENSE file. |
import csv |
+import imp |
+import inspect |
import json |
import logging |
import os |
+from telemetry.core import camel_case |
from telemetry.page import cloud_storage |
from telemetry.page import page as page_module |
from telemetry.page import page_set_archive_info |
-class PageSet(object): |
- def __init__(self, file_path='', attributes=None): |
- self.file_path = file_path |
+class PageSetError(Exception): |
+ pass |
+ |
+def _RenamePageSubMethod(method_name): |
+ assert method_name.startswith("Run") |
+ method_name = method_name[3:] |
+ return camel_case.ToUnderscore(method_name) |
+class PageSet(object): |
+ def __init__(self, description='', archive_data_file='', |
+ credentials_path=None, user_agent_type=None, |
+ make_javascript_deterministic=True, wpr_archive_info=None, |
+ pages=None, serving_dirs=None): |
# These attributes can be set dynamically by the page set. |
- self.description = '' |
- self.archive_data_file = '' |
- self.credentials_path = None |
- self.user_agent_type = None |
- self.make_javascript_deterministic = True |
+ self.description = description |
+ self.archive_data_file = archive_data_file |
+ self.credentials_path = credentials_path |
+ self.user_agent_type = user_agent_type |
+ self.make_javascript_deterministic = make_javascript_deterministic |
+ self.wpr_archive_info = wpr_archive_info |
+ if pages: |
+ self.pages = pages |
+ else: |
+ self.pages = [] |
+ if serving_dirs: |
+ self.serving_dirs = serving_dirs |
+ else: |
+ self.serving_dirs = set() |
+ # This attribute will be set by FromFile methods |
+ self.file_path = '' |
self.navigate_steps = {'action': 'navigate'} |
+ def _InitializeFromDict(self, attributes): |
if attributes: |
for k, v in attributes.iteritems(): |
setattr(self, k, v) |
- |
- # Create a PageSetArchiveInfo object. |
+ # Create a PageSetArchiveInfo object. |
if self.archive_data_file: |
self.wpr_archive_info = page_set_archive_info.PageSetArchiveInfo.FromFile( |
os.path.join(self._base_dir, self.archive_data_file)) |
- else: |
- self.wpr_archive_info = None |
# Create a Page object for every page. |
self.pages = [] |
if attributes and 'pages' in attributes: |
for page_attributes in attributes['pages']: |
url = page_attributes.pop('url') |
- |
page = page_module.Page( |
url, self, attributes=page_attributes, base_dir=self._base_dir) |
- self.pages.append(page) |
+ self.AddPage(page) |
# Prepend _base_dir to our serving dirs. |
# Always use realpath to ensure no duplicates in set. |
@@ -54,7 +74,9 @@ class PageSet(object): |
for serving_dir in attributes['serving_dirs']: |
self.serving_dirs.add( |
os.path.realpath(os.path.join(self._base_dir, serving_dir))) |
+ self._Initialize() |
+ def _Initialize(self): |
# Attempt to download the credentials file. |
if self.credentials_path: |
try: |
@@ -84,16 +106,62 @@ class PageSet(object): |
continue |
cloud_storage.GetIfChanged(path) |
- @classmethod |
- def FromFile(cls, file_path): |
+ def AddPage(self, page): |
+ self.pages.append(page) |
+ |
+ @staticmethod |
+ def FromFile(file_path): |
+ if file_path.endswith('.json'): |
+ return PageSet.FromJSONFile(file_path) |
+ elif file_path.endswith('.py'): |
+ return PageSet.FromPythonFile(file_path) |
+ else: |
+ raise PageSetError("Pageset %s has unsupported file type" % file_path) |
+ |
+ @staticmethod |
+ def FromPythonFile(file_path): |
+ module = imp.load_source('page_set_module', file_path) |
+ page_set_classes = [] |
+ for m in dir(module): |
+ if m.startswith('PageSet') and m != 'PageSet': |
+ page_set_classes.append(getattr(module, m)) |
+ if len(page_set_classes) != 1: |
+ raise PageSetError("Pageset file needs to contain exactly 1 pageset class" |
+ " with prefix 'PageSet'") |
+ page_set = page_set_classes[0]() |
+ #pylint: disable=W0212 |
nduca
2014/03/06 22:41:45
we typically put lint supressions on the same line
|
+ page_set._Initialize() |
+ page_set.file_path = file_path |
+ for page in page_set.pages: |
+ page.page_set = page_set |
+ page_class = page.__class__ |
+ |
+ for method_name, method in inspect.getmembers(page_class, |
+ predicate=inspect.ismethod): |
nduca
2014/03/06 22:41:45
indentation
|
+ if method_name.startswith("Run"): |
+ args, _, _, _ = inspect.getargspec(method) |
+ if not (args[0] == "self" and args[1] == "action_runner"): |
+ raise PageSetError("""Definition of Run<...> method of all |
+pages in %s must be in the form of def Run<...>(self, action_runner):""" |
+ % file_path) |
+ setattr(page_class, _RenamePageSubMethod(method_name), method) |
+ return page_set |
+ |
+ |
+ @staticmethod |
+ def FromJSONFile(file_path): |
with open(file_path, 'r') as f: |
contents = f.read() |
data = json.loads(contents) |
- return cls.FromDict(data, file_path) |
+ return PageSet.FromDict(data, file_path) |
- @classmethod |
- def FromDict(cls, data, file_path): |
- return cls(file_path, data) |
+ @staticmethod |
+ def FromDict(attributes, file_path=''): |
+ page_set = PageSet() |
+ page_set.file_path = file_path |
+ #pylint: disable=W0212 |
+ page_set._InitializeFromDict(attributes) |
+ return page_set |
@property |
def _base_dir(self): |
@@ -126,7 +194,7 @@ class PageSet(object): |
for csv_row in csv_reader: |
if csv_row[url_index] in page_set_dict: |
- pages.append(page_set_dict[csv_row[url_index]]) |
+ self.AddPage(page_set_dict[csv_row[url_index]]) |
else: |
raise Exception('Unusable results_file.') |
@@ -137,6 +205,9 @@ class PageSet(object): |
return None |
return self.wpr_archive_info.WprFilePathForPage(page) |
+ def AddCustomizeBrowserOptions(self, options): |
+ pass |
+ |
def __iter__(self): |
return self.pages.__iter__() |