|
Lines 74-80
def log_stack(stack):
a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py_sec1
|
| 74 |
_log.error(' %s' % line.strip()) |
74 |
_log.error(' %s' % line.strip()) |
| 75 |
|
75 |
|
| 76 |
|
76 |
|
| 77 |
def _process_output(port, options, test_info, test_types, test_args, |
77 |
def _process_output(port, options, test_input, test_types, test_args, |
| 78 |
crash, timeout, test_run_time, actual_checksum, |
78 |
crash, timeout, test_run_time, actual_checksum, |
| 79 |
output, error): |
79 |
output, error): |
| 80 |
"""Receives the output from a DumpRenderTree process, subjects it to a |
80 |
"""Receives the output from a DumpRenderTree process, subjects it to a |
|
Lines 84-90
def _process_output(port, options, test_info, test_types, test_args,
a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py_sec2
|
| 84 |
port: port-specific hooks |
84 |
port: port-specific hooks |
| 85 |
options: command line options argument from optparse |
85 |
options: command line options argument from optparse |
| 86 |
proc: an active DumpRenderTree process |
86 |
proc: an active DumpRenderTree process |
| 87 |
test_info: Object containing the test filename, uri and timeout |
87 |
test_input: Object containing the test filename, uri and timeout |
| 88 |
test_types: list of test types to subject the output to |
88 |
test_types: list of test types to subject the output to |
| 89 |
test_args: arguments to be passed to each test |
89 |
test_args: arguments to be passed to each test |
| 90 |
|
90 |
|
|
Lines 104-115
def _process_output(port, options, test_info, test_types, test_args,
a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py_sec3
|
| 104 |
failures.append(test_failures.FailureTimeout()) |
104 |
failures.append(test_failures.FailureTimeout()) |
| 105 |
|
105 |
|
| 106 |
if crash: |
106 |
if crash: |
| 107 |
_log.debug("Stacktrace for %s:\n%s" % (test_info.filename, error)) |
107 |
_log.debug("Stacktrace for %s:\n%s" % (test_input.filename, error)) |
| 108 |
# Strip off "file://" since RelativeTestFilename expects |
108 |
# Strip off "file://" since RelativeTestFilename expects |
| 109 |
# filesystem paths. |
109 |
# filesystem paths. |
| 110 |
filename = os.path.join(options.results_directory, |
110 |
filename = os.path.join(options.results_directory, |
| 111 |
port.relative_test_filename( |
111 |
port.relative_test_filename( |
| 112 |
test_info.filename)) |
112 |
test_input.filename)) |
| 113 |
filename = os.path.splitext(filename)[0] + "-stack.txt" |
113 |
filename = os.path.splitext(filename)[0] + "-stack.txt" |
| 114 |
port.maybe_make_directory(os.path.split(filename)[0]) |
114 |
port.maybe_make_directory(os.path.split(filename)[0]) |
| 115 |
with codecs.open(filename, "wb", "utf-8") as file: |
115 |
with codecs.open(filename, "wb", "utf-8") as file: |
|
Lines 122-128
def _process_output(port, options, test_info, test_types, test_args,
a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py_sec4
|
| 122 |
time_for_diffs = {} |
122 |
time_for_diffs = {} |
| 123 |
for test_type in test_types: |
123 |
for test_type in test_types: |
| 124 |
start_diff_time = time.time() |
124 |
start_diff_time = time.time() |
| 125 |
new_failures = test_type.compare_output(port, test_info.filename, |
125 |
new_failures = test_type.compare_output(port, test_input.filename, |
| 126 |
output, local_test_args, |
126 |
output, local_test_args, |
| 127 |
options.configuration) |
127 |
options.configuration) |
| 128 |
# Don't add any more failures if we already have a crash, so we don't |
128 |
# Don't add any more failures if we already have a crash, so we don't |
|
Lines 134-140
def _process_output(port, options, test_info, test_types, test_args,
a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py_sec5
|
| 134 |
time.time() - start_diff_time) |
134 |
time.time() - start_diff_time) |
| 135 |
|
135 |
|
| 136 |
total_time_for_all_diffs = time.time() - start_diff_time |
136 |
total_time_for_all_diffs = time.time() - start_diff_time |
| 137 |
return test_results.TestResult(test_info.filename, failures, test_run_time, |
137 |
return test_results.TestResult(test_input.filename, failures, test_run_time, |
| 138 |
total_time_for_all_diffs, time_for_diffs) |
138 |
total_time_for_all_diffs, time_for_diffs) |
| 139 |
|
139 |
|
| 140 |
|
140 |
|
|
Lines 153-174
def _milliseconds_to_seconds(msecs):
a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py_sec6
|
| 153 |
return float(msecs) / 1000.0 |
153 |
return float(msecs) / 1000.0 |
| 154 |
|
154 |
|
| 155 |
|
155 |
|
| 156 |
def _image_hash(test_info, test_args, options): |
156 |
def _should_fetch_expected_checksum(options): |
| 157 |
"""Returns the image hash of the test if it's needed, otherwise None.""" |
157 |
return options.pixel_tests and not (options.new_baseline or options.reset_results) |
| 158 |
if (test_args.new_baseline or test_args.reset_results or not options.pixel_tests): |
|
|
| 159 |
return None |
| 160 |
return test_info.image_hash() |
| 161 |
|
158 |
|
| 162 |
|
159 |
|
| 163 |
class SingleTestThread(threading.Thread): |
160 |
class SingleTestThread(threading.Thread): |
| 164 |
"""Thread wrapper for running a single test file.""" |
161 |
"""Thread wrapper for running a single test file.""" |
| 165 |
|
162 |
|
| 166 |
def __init__(self, port, options, test_info, test_types, test_args): |
163 |
def __init__(self, port, options, test_input, test_types, test_args): |
| 167 |
""" |
164 |
""" |
| 168 |
Args: |
165 |
Args: |
| 169 |
port: object implementing port-specific hooks |
166 |
port: object implementing port-specific hooks |
| 170 |
options: command line argument object from optparse |
167 |
options: command line argument object from optparse |
| 171 |
test_info: Object containing the test filename, uri and timeout |
168 |
test_input: Object containing the test filename, uri and timeout |
| 172 |
test_types: A list of TestType objects to run the test output |
169 |
test_types: A list of TestType objects to run the test output |
| 173 |
against. |
170 |
against. |
| 174 |
test_args: A TestArguments object to pass to each TestType. |
171 |
test_args: A TestArguments object to pass to each TestType. |
|
Lines 177-183
class SingleTestThread(threading.Thread):
a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py_sec7
|
| 177 |
threading.Thread.__init__(self) |
174 |
threading.Thread.__init__(self) |
| 178 |
self._port = port |
175 |
self._port = port |
| 179 |
self._options = options |
176 |
self._options = options |
| 180 |
self._test_info = test_info |
177 |
self._test_input = test_input |
| 181 |
self._test_types = test_types |
178 |
self._test_types = test_types |
| 182 |
self._test_args = test_args |
179 |
self._test_args = test_args |
| 183 |
self._driver = None |
180 |
self._driver = None |
|
Lines 188-205
class SingleTestThread(threading.Thread):
a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py_sec8
|
| 188 |
def _covered_run(self): |
185 |
def _covered_run(self): |
| 189 |
# FIXME: this is a separate routine to work around a bug |
186 |
# FIXME: this is a separate routine to work around a bug |
| 190 |
# in coverage: see http://bitbucket.org/ned/coveragepy/issue/85. |
187 |
# in coverage: see http://bitbucket.org/ned/coveragepy/issue/85. |
| 191 |
test_info = self._test_info |
188 |
|
|
|
189 |
# FIXME: Pull this into TestShellThread._run(). |
| 190 |
test_input = self._test_input |
| 191 |
test_input.uri = self._port.filename_to_uri(test_input.filename) |
| 192 |
if _should_fetch_expected_checksum(self._options): |
| 193 |
test_input.image_checksum = self._port.expected_checksum(test_input.filename) |
| 194 |
|
| 195 |
start = time.time() |
| 192 |
self._driver = self._port.create_driver(self._test_args.png_path, |
196 |
self._driver = self._port.create_driver(self._test_args.png_path, |
| 193 |
self._options) |
197 |
self._options) |
| 194 |
self._driver.start() |
198 |
self._driver.start() |
| 195 |
image_hash = _image_hash(test_info, self._test_args, self._options) |
|
|
| 196 |
start = time.time() |
| 197 |
crash, timeout, actual_checksum, output, error = \ |
199 |
crash, timeout, actual_checksum, output, error = \ |
| 198 |
self._driver.run_test(test_info.uri.strip(), test_info.timeout, |
200 |
self._driver.run_test(test_input.uri, test_input.timeout, |
| 199 |
image_hash) |
201 |
test_input.image_checksum) |
| 200 |
end = time.time() |
202 |
end = time.time() |
| 201 |
self._test_result = _process_output(self._port, self._options, |
203 |
self._test_result = _process_output(self._port, self._options, |
| 202 |
test_info, self._test_types, self._test_args, |
204 |
test_input, self._test_types, self._test_args, |
| 203 |
crash, timeout, end - start, |
205 |
crash, timeout, end - start, |
| 204 |
actual_checksum, output, error) |
206 |
actual_checksum, output, error) |
| 205 |
self._driver.stop() |
207 |
self._driver.stop() |
|
Lines 258-264
class TestShellThread(WatchableThread):
a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py_sec9
|
| 258 |
test_types: A list of TestType objects to run the test output |
260 |
test_types: A list of TestType objects to run the test output |
| 259 |
against. |
261 |
against. |
| 260 |
test_args: A TestArguments object to pass to each TestType. |
262 |
test_args: A TestArguments object to pass to each TestType. |
| 261 |
|
|
|
| 262 |
""" |
263 |
""" |
| 263 |
WatchableThread.__init__(self) |
264 |
WatchableThread.__init__(self) |
| 264 |
self._port = port |
265 |
self._port = port |
|
Lines 402-418
class TestShellThread(WatchableThread):
a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py_sec10
|
| 402 |
self._num_tests_in_current_group = len(self._filename_list) |
403 |
self._num_tests_in_current_group = len(self._filename_list) |
| 403 |
self._current_group_start_time = time.time() |
404 |
self._current_group_start_time = time.time() |
| 404 |
|
405 |
|
| 405 |
test_info = self._filename_list.pop() |
406 |
test_input = self._filename_list.pop() |
| 406 |
|
407 |
|
| 407 |
# We have a url, run tests. |
408 |
# We have a url, run tests. |
| 408 |
batch_count += 1 |
409 |
batch_count += 1 |
| 409 |
self._num_tests += 1 |
410 |
self._num_tests += 1 |
| 410 |
if self._options.run_singly: |
411 |
if self._options.run_singly: |
| 411 |
result = self._run_test_singly(test_info) |
412 |
result = self._run_test_singly(test_input) |
| 412 |
else: |
413 |
else: |
| 413 |
result = self._run_test(test_info) |
414 |
result = self._run_test(test_input) |
| 414 |
|
415 |
|
| 415 |
filename = test_info.filename |
416 |
filename = test_input.filename |
| 416 |
tests_run_file.write(filename + "\n") |
417 |
tests_run_file.write(filename + "\n") |
| 417 |
if result.failures: |
418 |
if result.failures: |
| 418 |
# Check and kill DumpRenderTree if we need to. |
419 |
# Check and kill DumpRenderTree if we need to. |
|
Lines 440-446
class TestShellThread(WatchableThread):
a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py_sec11
|
| 440 |
if test_runner: |
441 |
if test_runner: |
| 441 |
test_runner.update_summary(result_summary) |
442 |
test_runner.update_summary(result_summary) |
| 442 |
|
443 |
|
| 443 |
def _run_test_singly(self, test_info): |
444 |
def _run_test_singly(self, test_input): |
| 444 |
"""Run a test in a separate thread, enforcing a hard time limit. |
445 |
"""Run a test in a separate thread, enforcing a hard time limit. |
| 445 |
|
446 |
|
| 446 |
Since we can only detect the termination of a thread, not any internal |
447 |
Since we can only detect the termination of a thread, not any internal |
|
Lines 448-454
class TestShellThread(WatchableThread):
a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py_sec12
|
| 448 |
files singly. |
449 |
files singly. |
| 449 |
|
450 |
|
| 450 |
Args: |
451 |
Args: |
| 451 |
test_info: Object containing the test filename, uri and timeout |
452 |
test_input: Object containing the test filename, uri and timeout |
| 452 |
|
453 |
|
| 453 |
Returns: |
454 |
Returns: |
| 454 |
A TestResult |
455 |
A TestResult |
|
Lines 456-469
class TestShellThread(WatchableThread):
a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py_sec13
|
| 456 |
""" |
457 |
""" |
| 457 |
worker = SingleTestThread(self._port, |
458 |
worker = SingleTestThread(self._port, |
| 458 |
self._options, |
459 |
self._options, |
| 459 |
test_info, |
460 |
test_input, |
| 460 |
self._test_types, |
461 |
self._test_types, |
| 461 |
self._test_args) |
462 |
self._test_args) |
| 462 |
|
463 |
|
| 463 |
worker.start() |
464 |
worker.start() |
| 464 |
|
465 |
|
| 465 |
thread_timeout = _milliseconds_to_seconds( |
466 |
thread_timeout = _milliseconds_to_seconds( |
| 466 |
_pad_timeout(int(test_info.timeout))) |
467 |
_pad_timeout(int(test_input.timeout))) |
| 467 |
thread._next_timeout = time.time() + thread_timeout |
468 |
thread._next_timeout = time.time() + thread_timeout |
| 468 |
worker.join(thread_timeout) |
469 |
worker.join(thread_timeout) |
| 469 |
if worker.isAlive(): |
470 |
if worker.isAlive(): |
|
Lines 485-501
class TestShellThread(WatchableThread):
a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py_sec14
|
| 485 |
# This gets raised if the worker thread has already exited. |
486 |
# This gets raised if the worker thread has already exited. |
| 486 |
failures = [] |
487 |
failures = [] |
| 487 |
_log.error('Cannot get results of test: %s' % |
488 |
_log.error('Cannot get results of test: %s' % |
| 488 |
test_info.filename) |
489 |
test_input.filename) |
| 489 |
result = test_results.TestResult(test_info.filename, failures=[], |
490 |
result = test_results.TestResult(test_input.filename, failures=[], |
| 490 |
test_run_time=0, total_time_for_all_diffs=0, time_for_diffs=0) |
491 |
test_run_time=0, total_time_for_all_diffs=0, time_for_diffs=0) |
| 491 |
|
492 |
|
| 492 |
return result |
493 |
return result |
| 493 |
|
494 |
|
| 494 |
def _run_test(self, test_info): |
495 |
def _run_test(self, test_input): |
| 495 |
"""Run a single test file using a shared DumpRenderTree process. |
496 |
"""Run a single test file using a shared DumpRenderTree process. |
| 496 |
|
497 |
|
| 497 |
Args: |
498 |
Args: |
| 498 |
test_info: Object containing the test filename, uri and timeout |
499 |
test_input: Object containing the test filename, uri and timeout |
| 499 |
|
500 |
|
| 500 |
Returns: a TestResult object. |
501 |
Returns: a TestResult object. |
| 501 |
""" |
502 |
""" |
|
Lines 504-522
class TestShellThread(WatchableThread):
a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py_sec15
|
| 504 |
# checksums match, so it should be set to a blank value if we |
505 |
# checksums match, so it should be set to a blank value if we |
| 505 |
# are generating a new baseline. (Otherwise, an image from a |
506 |
# are generating a new baseline. (Otherwise, an image from a |
| 506 |
# previous run will be copied into the baseline.) |
507 |
# previous run will be copied into the baseline.) |
| 507 |
image_hash = _image_hash(test_info, self._test_args, self._options) |
508 |
|
|
|
509 |
# FIXME: Pull this into TestShellThread._run(). |
| 510 |
test_input.uri = self._port.filename_to_uri(test_input.filename) |
| 511 |
if _should_fetch_expected_checksum(self._options): |
| 512 |
test_input.image_checksum = self._port.expected_checksum(test_input.filename) |
| 508 |
start = time.time() |
513 |
start = time.time() |
| 509 |
|
514 |
|
| 510 |
thread_timeout = _milliseconds_to_seconds( |
515 |
thread_timeout = _milliseconds_to_seconds( |
| 511 |
_pad_timeout(int(test_info.timeout))) |
516 |
_pad_timeout(int(test_input.timeout))) |
| 512 |
self._next_timeout = start + thread_timeout |
517 |
self._next_timeout = start + thread_timeout |
| 513 |
|
518 |
|
| 514 |
crash, timeout, actual_checksum, output, error = \ |
519 |
crash, timeout, actual_checksum, output, error = \ |
| 515 |
self._driver.run_test(test_info.uri, test_info.timeout, image_hash) |
520 |
self._driver.run_test(test_input.uri, test_input.timeout, test_input.image_checksum) |
| 516 |
end = time.time() |
521 |
end = time.time() |
| 517 |
|
522 |
|
| 518 |
result = _process_output(self._port, self._options, |
523 |
result = _process_output(self._port, self._options, |
| 519 |
test_info, self._test_types, |
524 |
test_input, self._test_types, |
| 520 |
self._test_args, crash, |
525 |
self._test_args, crash, |
| 521 |
timeout, end - start, actual_checksum, |
526 |
timeout, end - start, actual_checksum, |
| 522 |
output, error) |
527 |
output, error) |