Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(74)

Side by Side Diff: tools/testing/run_selenium.py

Issue 9958051: Add support for Dromaeo tests in perf scripts. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/testing/perf_testing/run_perf_tests.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 2
3 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 3 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
4 # for details. All rights reserved. Use of this source code is governed by a 4 # for details. All rights reserved. Use of this source code is governed by a
5 # BSD-style license that can be found in the LICENSE file. 5 # BSD-style license that can be found in the LICENSE file.
6 # 6 #
7 7
8 """Script to actually open a browser and perform the test, and reports back with 8 """Script to actually open a browser and perform the test, and reports back with
9 the result. It uses Selenium WebDriver when possible for running the tests. It 9 the result. It uses Selenium WebDriver when possible for running the tests. It
10 uses Selenium RC for Safari. 10 uses Selenium RC for Safari.
(...skipping 15 matching lines...) Expand all
26 stdin: --terminate 26 stdin: --terminate
27 $ 27 $
28 """ 28 """
29 29
30 import os 30 import os
31 import optparse 31 import optparse
32 import platform 32 import platform
33 import selenium 33 import selenium
34 from selenium.webdriver.support.ui import WebDriverWait 34 from selenium.webdriver.support.ui import WebDriverWait
35 import shutil 35 import shutil
36 import signal
36 import socket 37 import socket
37 import sys 38 import sys
38 import time 39 import time
39 import signal
40 40
41 TIMEOUT_ERROR_MSG = 'FAIL (timeout)' 41 TIMEOUT_ERROR_MSG = 'FAIL (timeout)'
42 42
43 def perf_test_done(driver): 43 def correctness_test_done(source):
44 """Checks if the performance test has completed.""" 44 """Checks if test has completed."""
45 return perf_test_done_helper(driver.page_source) 45 return ('PASS' in source) or ('FAIL' in source)
46 46
47 def perf_test_done_helper(source): 47 def perf_test_done(source):
48 """Tests to see if our performance test is done by printing a score.""" 48 """Tests to see if our performance test is done by printing a score."""
49 #This code is written this way to work around a current instability in the 49 #This code is written this way to work around a current instability in the
50 # python webdriver bindings if you call driver.get_element_by_id. 50 # python webdriver bindings if you call driver.get_element_by_id.
51 #TODO(efortuna): Access these elements in a nicer way using DOM parser. 51 #TODO(efortuna): Access these elements in a nicer way using DOM parser.
52 string = '<div id="status">' 52 string = '<div id="status">'
53 index = source.find(string) 53 index = source.find(string)
54 end_index = source.find('</div>', index+1) 54 end_index = source.find('</div>', index+1)
55 source = source[index + len(string):end_index] 55 source = source[index + len(string):end_index]
56 return 'Score:' in source 56 return 'Score:' in source
57 57
58 def run_test_in_browser(browser, html_out, timeout, is_perf): 58 def dromaeo_test_done(source):
59 """Tests to see if our performance test is done by printing a score."""
60 #TODO(efortuna): Access these elements in a nicer way using DOM parser.
61 string = '<span class="left">'
62 index = source.find(string)
63 end_index = source.find('</span>', index+1)
64 source = source[index + len(string):end_index]
65 return '0:00' in source
66
67 # TODO(vsm): Ideally, this wouldn't live in this file.
68 CONFIGURATIONS = {
69 'correctness': correctness_test_done,
70 'perf': perf_test_done,
71 'dromaeo': dromaeo_test_done
72 }
73
74 def run_test_in_browser(browser, html_out, timeout, config):
59 """Run the desired test in the browser using Selenium 2.0 WebDriver syntax, 75 """Run the desired test in the browser using Selenium 2.0 WebDriver syntax,
60 and wait for the test to complete. This is the newer syntax, that currently 76 and wait for the test to complete. This is the newer syntax, that currently
61 supports Firefox, Chrome, IE, Opera (and some mobile browsers).""" 77 supports Firefox, Chrome, IE, Opera (and some mobile browsers)."""
62 if isinstance(browser, selenium.selenium): 78 if isinstance(browser, selenium.selenium):
63 return run_test_in_browser_selenium_rc(browser, html_out, timeout, is_perf) 79 return run_test_in_browser_selenium_rc(browser, html_out, timeout, config)
64 80
65 browser.get("file://" + html_out) 81 browser.get("file://" + html_out)
66 source = '' 82 source = ''
67 try: 83 try:
68 if is_perf: 84 test_done = CONFIGURATIONS[config]
69 # We're running a performance test. 85 element = WebDriverWait(browser, float(timeout)).until(
70 element = WebDriverWait(browser, float(timeout)).until(perf_test_done) 86 lambda driver: test_done(driver.page_source))
71 else:
72 element = WebDriverWait(browser, float(timeout)).until(
73 lambda driver : ('PASS' in driver.page_source) or
74 ('FAIL' in driver.page_source))
75 source = browser.page_source 87 source = browser.page_source
76 except selenium.common.exceptions.TimeoutException: 88 except selenium.common.exceptions.TimeoutException:
77 source = TIMEOUT_ERROR_MSG 89 source = TIMEOUT_ERROR_MSG
78 return source 90 return source
79 91
80 def run_test_in_browser_selenium_rc(sel, html_out, timeout, is_perf): 92 def run_test_in_browser_selenium_rc(sel, html_out, timeout, config):
81 """ Run the desired test in the browser using Selenium 1.0 syntax, and wait 93 """ Run the desired test in the browser using Selenium 1.0 syntax, and wait
82 for the test to complete. This is used for Safari, since it is not currently 94 for the test to complete. This is used for Safari, since it is not currently
83 supported on Selenium 2.0.""" 95 supported on Selenium 2.0."""
84 sel.open('file://' + html_out) 96 sel.open('file://' + html_out)
85 source = sel.get_html_source() 97 source = sel.get_html_source()
86 def end_condition(source): 98 end_condition = CONFIGURATIONS[config]
87 return 'PASS' in source or 'FAIL' in source
88 if is_perf:
89 end_condition = perf_test_done_helper
90 99
91 elapsed = 0 100 elapsed = 0
92 while (not end_condition(source)) and elapsed <= timeout: 101 while (not end_condition(source)) and elapsed <= timeout:
93 sec = .25 102 sec = .25
94 time.sleep(sec) 103 time.sleep(sec)
95 elapsed += sec 104 elapsed += sec
96 source = sel.get_html_source() 105 source = sel.get_html_source()
97 return source 106 return source
98 107
99 def parse_args(args=None): 108 def parse_args(args=None):
100 parser = optparse.OptionParser() 109 parser = optparse.OptionParser()
101 parser.add_option('--out', dest='out', 110 parser.add_option('--out', dest='out',
102 help = 'The path for html output file that we will running our test from', 111 help = 'The path for html output file that we will running our test from',
103 action = 'store', default = '') 112 action = 'store', default = '')
104 parser.add_option('--browser', dest='browser', 113 parser.add_option('--browser', dest='browser',
105 help = 'The browser type (default = chrome)', 114 help = 'The browser type (default = chrome)',
106 action = 'store', default = 'chrome') 115 action = 'store', default = 'chrome')
107 # TODO(efortuna): Put this back up to be more than the default timeout in 116 # TODO(efortuna): Put this back up to be more than the default timeout in
108 # test.dart. Right now it needs to be less than 60 so that when test.dart 117 # test.dart. Right now it needs to be less than 60 so that when test.dart
109 # times out, this script also closes the browser windows. 118 # times out, this script also closes the browser windows.
110 parser.add_option('--timeout', dest = 'timeout', 119 parser.add_option('--timeout', dest = 'timeout',
111 help = 'Amount of time (seconds) to wait before timeout', type = 'int', 120 help = 'Amount of time (seconds) to wait before timeout', type = 'int',
112 action = 'store', default=58) 121 action = 'store', default=58)
113 parser.add_option('--perf', dest = 'is_perf', 122 parser.add_option('--perf', dest = 'is_perf',
114 help = 'Add this flag if we are running a browser performance test', 123 help = 'Add this flag if we are running a browser performance test',
115 action = 'store_true', default=False) 124 action = 'store_true', default=False)
125 # TODO(vsm): Abstract this out better.
126 parser.add_option('--dromaeo', dest = 'is_dromaeo',
127 help = 'Add this flag if we are running a browser performance test',
128 action = 'store_true', default=False)
116 args, ignored = parser.parse_args(args=args) 129 args, ignored = parser.parse_args(args=args)
117 return args.out, args.browser, args.timeout, args.is_perf 130 if args.is_perf:
131 config = 'perf'
132 elif args.is_dromaeo:
133 config = 'dromaeo'
134 else:
135 config = 'correctness'
136 return args.out, args.browser, args.timeout, config
118 137
119 def start_browser(browser, html_out): 138 def start_browser(browser, html_out):
120 if browser == 'chrome': 139 if browser == 'chrome':
121 # Note: you need ChromeDriver *in your path* to run Chrome, in addition to 140 # Note: you need ChromeDriver *in your path* to run Chrome, in addition to
122 # installing Chrome. Also note that the build bot runs have a different path 141 # installing Chrome. Also note that the build bot runs have a different path
123 # from a normal user -- check the build logs. 142 # from a normal user -- check the build logs.
124 return selenium.webdriver.Chrome() 143 return selenium.webdriver.Chrome()
125 elif browser == 'ff': 144 elif browser == 'ff':
126 profile = selenium.webdriver.firefox.firefox_profile.FirefoxProfile() 145 profile = selenium.webdriver.firefox.firefox_profile.FirefoxProfile()
127 profile.set_preference('dom.max_script_run_time', 0) 146 profile.set_preference('dom.max_script_run_time', 0)
(...skipping 30 matching lines...) Expand all
158 177
159 # A timeout exception is thrown if nothing happens within the time limit. 178 # A timeout exception is thrown if nothing happens within the time limit.
160 if browser != 'chrome': 179 if browser != 'chrome':
161 browser.close() 180 browser.close()
162 try: 181 try:
163 browser.quit() 182 browser.quit()
164 except selenium.common.exceptions.WebDriverException: 183 except selenium.common.exceptions.WebDriverException:
165 # TODO(efortuna): Figure out why this crashes.... and avoid? 184 # TODO(efortuna): Figure out why this crashes.... and avoid?
166 pass 185 pass
167 186
168 def report_results(is_perf, source): 187 def report_results(config, source):
169 if is_perf: 188 # TODO(vsm): Add a failure check for Dromaeo.
189 if config != 'correctness':
170 # We're running a performance test. 190 # We're running a performance test.
171 print source 191 print source.encode('utf8')
192 sys.stdout.flush()
172 if 'NaN' in source: 193 if 'NaN' in source:
173 return 1 194 return 1
174 else: 195 else:
175 return 0 196 return 0
176 else: 197 else:
177 # We're running a correctness test. Mark test as passing if all individual 198 # We're running a correctness test. Mark test as passing if all individual
178 # test cases pass. 199 # test cases pass.
179 if 'FAIL' not in source and 'PASS' in source: 200 if 'FAIL' not in source and 'PASS' in source:
180 print 'Content-Type: text/plain\nPASS' 201 print 'Content-Type: text/plain\nPASS'
181 return 0 202 return 0
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 # TODO(jmesserly): It'd be nice to shutdown gracefully in the event of a 238 # TODO(jmesserly): It'd be nice to shutdown gracefully in the event of a
218 # SIGTERM. Unfortunately dart:io cannot send SIGTERM, see dartbug.com/1756. 239 # SIGTERM. Unfortunately dart:io cannot send SIGTERM, see dartbug.com/1756.
219 signal.signal(signal.SIGTERM, lambda number, frame: close_browser(browser)) 240 signal.signal(signal.SIGTERM, lambda number, frame: close_browser(browser))
220 241
221 try: 242 try:
222 while True: 243 while True:
223 line = sys.stdin.readline() 244 line = sys.stdin.readline()
224 if line == '--terminate\n': 245 if line == '--terminate\n':
225 break 246 break
226 247
227 html_out, browser_name, timeout, is_perf = parse_args(line.split()) 248 html_out, browser_name, timeout, config = parse_args(line.split())
228 249
229 # Sanity checks that test.dart is passing flags we can handle. 250 # Sanity checks that test.dart is passing flags we can handle.
230 if is_perf: 251 if config != 'correctness':
231 print 'Batch test runner not compatible with perf testing' 252 print 'Batch test runner not compatible with perf testing'
232 return 1 253 return 1
233 if browser and current_browser_name != browser_name: 254 if browser and current_browser_name != browser_name:
234 print('Batch test runner got multiple browsers: %s and %s' 255 print('Batch test runner got multiple browsers: %s and %s'
235 % (current_browser_name, browser_name)) 256 % (current_browser_name, browser_name))
236 return 1 257 return 1
237 258
238 # Start the browser on the first run 259 # Start the browser on the first run
239 if browser is None: 260 if browser is None:
240 current_browser_name = browser_name 261 current_browser_name = browser_name
241 browser = start_browser(browser_name, html_out) 262 browser = start_browser(browser_name, html_out)
242 263
243 source = run_test_in_browser(browser, html_out, timeout, is_perf) 264 source = run_test_in_browser(browser, html_out, timeout, config)
244 265
245 # Test is done. Write end token to stderr and flush. 266 # Test is done. Write end token to stderr and flush.
246 sys.stderr.write('>>> EOF STDERR\n') 267 sys.stderr.write('>>> EOF STDERR\n')
247 sys.stderr.flush() 268 sys.stderr.flush()
248 269
249 # print one of: 270 # print one of:
250 # >>> TEST {PASS, FAIL, OK, CRASH, FAIL, TIMEOUT} 271 # >>> TEST {PASS, FAIL, OK, CRASH, FAIL, TIMEOUT}
251 status = report_results(is_perf, source) 272 status = report_results(config, source)
252 if status == 0: 273 if status == 0:
253 print '>>> TEST PASS' 274 print '>>> TEST PASS'
254 elif source == TIMEOUT_ERROR_MSG: 275 elif source == TIMEOUT_ERROR_MSG:
255 print '>>> TEST TIMEOUT' 276 print '>>> TEST TIMEOUT'
256 else: 277 else:
257 print '>>> TEST FAIL' 278 print '>>> TEST FAIL'
258 sys.stdout.flush() 279 sys.stdout.flush()
259 finally: 280 finally:
260 close_browser(browser) 281 close_browser(browser)
261 282
262 283
263 def main(args): 284 def main(args):
264 # Run in batch mode if the --batch flag is passed. 285 # Run in batch mode if the --batch flag is passed.
265 # TODO(jmesserly): reconcile with the existing args parsing 286 # TODO(jmesserly): reconcile with the existing args parsing
266 if '--batch' in args: 287 if '--batch' in args:
267 return run_batch_tests() 288 return run_batch_tests()
268 289
269 # Run a single test 290 # Run a single test
270 html_out, browser_name, timeout, is_perf = parse_args() 291 html_out, browser_name, timeout, config = parse_args()
271 browser = start_browser(browser_name, html_out) 292 browser = start_browser(browser_name, html_out)
272 293
273 try: 294 try:
274 output = run_test_in_browser(browser, html_out, timeout, is_perf) 295 output = run_test_in_browser(browser, html_out, timeout, config)
275 return report_results(is_perf, output) 296 return report_results(config, output)
276 finally: 297 finally:
277 close_browser(browser) 298 close_browser(browser)
278 299
279 if __name__ == "__main__": 300 if __name__ == "__main__":
280 sys.exit(main(sys.argv)) 301 sys.exit(main(sys.argv))
OLDNEW
« no previous file with comments | « tools/testing/perf_testing/run_perf_tests.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698