Upstream version 7.35.144.0
[platform/framework/web/crosswalk.git] / src / tools / telemetry / telemetry / page / page_test_runner.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 import os
5 import sys
6
7 from telemetry import test as test_module
8 from telemetry.core import browser_options
9 from telemetry.core import discover
10 from telemetry.page import page_test as page_test_module
11 from telemetry.page import page_runner
12 from telemetry.page import page_set
13
14 def Main(env):
15   """Turns a PageTest into a command-line program.
16
17   Args:
18     base_dir: Path to directory containing tests and ProfileCreators.
19   """
20   runner = PageTestRunner()
21   sys.exit(runner.Run(env))
22
23 class PageTestRunner(object):
24   def __init__(self):
25     self._parser = None
26     self._options = None
27     self._args = None
28
29   @property
30   def test_class(self):
31     return page_test_module.PageTest
32
33   @property
34   def test_class_name(self):
35     return 'test'
36
37   def Run(self, env):
38     test, ps, expectations = self.ParseCommandLine(sys.argv, env)
39     results = page_runner.Run(test, ps, expectations, self._options)
40     results.PrintSummary()
41     return min(255, len(results.failures + results.errors))
42
43   def FindTestConstructors(self, base_dirs):
44     # Look for both Tests and PageTests, but Tests get priority, because
45     test_constructors = {}
46     for base_dir in base_dirs:
47       test_constructors.update(discover.DiscoverClasses(
48           base_dir, base_dir, self.test_class))
49     for base_dir in base_dirs:
50       test_constructors.update(discover.DiscoverClasses(
51           base_dir, base_dir, test_module.Test, index_by_class_name=True))
52     return test_constructors
53
54   def FindTestName(self, test_constructors, args):
55     """Find the test name in an arbitrary argument list.
56
57     We can't use the optparse parser, because the test may add its own
58     command-line options. If the user passed in any of those, the
59     optparse parsing will fail.
60
61     Returns:
62       test_name or None
63     """
64     test_name = None
65     for arg in args:
66       if arg in test_constructors:
67         test_name = arg
68
69     return test_name
70
71   def GetPageSet(self, env):
72     if len(self._args) < 2:
73       page_set_filenames = []
74       for perf_path in env.base_paths:
75         # Check if page_sets subfolder is present, and get all page_sets
76         # files if present.
77         page_set_dir = os.path.join(perf_path, "page_sets")
78         if not os.path.exists(page_set_dir):
79           continue
80         page_set_filenames += discover.GetAllPageSetFilenames(page_set_dir)
81       page_set_list = ',\n'.join(
82           sorted([os.path.relpath(f) for f in page_set_filenames]))
83       self.PrintParseError(
84           'No page set, file, or URL specified.\n'
85           'Available page sets:\n'
86           '%s' % page_set_list)
87
88     page_set_arg = self._args[1]
89
90     # We've been given a URL. Create a page set with just that URL.
91     if (page_set_arg.startswith('http://') or
92         page_set_arg.startswith('https://')):
93       self._options.allow_live_sites = True
94       return page_set.PageSet.FromDict({
95           'pages': [{'url': page_set_arg}]
96           }, os.path.dirname(__file__))
97
98     # We've been given a page set JSON or PYTHON. Load it.
99     if page_set_arg.endswith('.json') or page_set_arg.endswith('.py'):
100       return page_set.PageSet.FromFile(page_set_arg)
101
102     # We've been given a file or directory. Create a page set containing it.
103     if os.path.exists(page_set_arg):
104       page_set_dict = {'pages': []}
105
106       def _AddFile(file_path):
107         page_set_dict['pages'].append({'url': 'file://' + file_path})
108
109       def _AddDir(dir_path):
110         for path in os.listdir(dir_path):
111           path = os.path.join(dir_path, path)
112           _AddPath(path)
113
114       def _AddPath(path):
115         if os.path.isdir(path):
116           _AddDir(path)
117         else:
118           _AddFile(path)
119
120       _AddPath(page_set_arg)
121       return page_set.PageSet.FromDict(page_set_dict, os.getcwd() + os.sep)
122
123     raise Exception('Did not understand "%s". Pass a page set, file or URL.' %
124                     page_set_arg)
125
126   def ParseCommandLine(self, args, env):
127     self._options = browser_options.BrowserFinderOptions()
128     self._parser = self._options.CreateParser(
129         '%%prog [options] %s page_set' % self.test_class_name)
130
131     test_constructors = self.FindTestConstructors(env.base_paths)
132     test_name = self.FindTestName(test_constructors, args)
133     test = None
134     if test_name:
135       test = test_constructors[test_name]()
136       if isinstance(test, test_module.Test):
137         page_test = test.test()
138         test.AddCommandLineArgs(self._parser)
139       else:
140         page_test = test
141         page_test.AddCommandLineArgs(self._parser)
142     page_runner.AddCommandLineArgs(self._parser)
143
144     _, self._args = self._parser.parse_args()
145
146     if len(self._args) < 1:
147       error_message = 'No %s specified.\nAvailable %ss:\n' % (
148           self.test_class_name, self.test_class_name)
149       test_list_string = ',\n'.join(sorted(test_constructors.keys()))
150       self.PrintParseError(error_message + test_list_string)
151
152     if not test:
153       error_message = 'No %s named %s.\nAvailable %ss:\n' % (
154           self.test_class_name, self._args[0], self.test_class_name)
155       test_list_string = ',\n'.join(sorted(test_constructors.keys()))
156       self.PrintParseError(error_message + test_list_string)
157
158     if isinstance(test, test_module.Test):
159       ps = test.CreatePageSet(self._options)
160       expectations = test.CreateExpectations(ps)
161       test.ProcessCommandLineArgs(self._parser, self._options)
162     else:
163       ps = self.GetPageSet(env)
164       expectations = test.CreateExpectations(ps)
165       page_test.ProcessCommandLineArgs(self._parser, self._options)
166     page_runner.ProcessCommandLineArgs(self._parser, self._options)
167
168     if len(self._args) > 2:
169       self.PrintParseError('Too many arguments.')
170
171
172     return page_test, ps, expectations
173
174   def PrintParseError(self, message):
175     self._parser.error(message)