OLD | NEW |
1 # Copyright (C) 2011 Google Inc. All rights reserved. | 1 # Copyright (C) 2011 Google Inc. All rights reserved. |
2 # | 2 # |
3 # Redistribution and use in source and binary forms, with or without | 3 # Redistribution and use in source and binary forms, with or without |
4 # modification, are permitted provided that the following conditions are | 4 # modification, are permitted provided that the following conditions are |
5 # met: | 5 # met: |
6 # | 6 # |
7 # * Redistributions of source code must retain the above copyright | 7 # * Redistributions of source code must retain the above copyright |
8 # notice, this list of conditions and the following disclaimer. | 8 # notice, this list of conditions and the following disclaimer. |
9 # * Redistributions in binary form must reproduce the above | 9 # * Redistributions in binary form must reproduce the above |
10 # copyright notice, this list of conditions and the following disclaimer | 10 # copyright notice, this list of conditions and the following disclaimer |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 self._caller.post('finished_test', result) | 311 self._caller.post('finished_test', result) |
312 | 312 |
313 self._clean_up_after_test(test_input, result) | 313 self._clean_up_after_test(test_input, result) |
314 | 314 |
315 def stop(self): | 315 def stop(self): |
316 _log.debug("%s cleaning up" % self._name) | 316 _log.debug("%s cleaning up" % self._name) |
317 self._kill_driver() | 317 self._kill_driver() |
318 | 318 |
319 def _timeout(self, test_input): | 319 def _timeout(self, test_input): |
320 """Compute the appropriate timeout value for a test.""" | 320 """Compute the appropriate timeout value for a test.""" |
321 # The DumpRenderTree watchdog uses 2.5x the timeout; we want to be | 321 # The driver watchdog uses 2.5x the timeout; we want to be |
322 # larger than that. We also add a little more padding if we're | 322 # larger than that. We also add a little more padding if we're |
323 # running tests in a separate thread. | 323 # running tests in a separate thread. |
324 # | 324 # |
325 # Note that we need to convert the test timeout from a | 325 # Note that we need to convert the test timeout from a |
326 # string value in milliseconds to a float for Python. | 326 # string value in milliseconds to a float for Python. |
327 driver_timeout_sec = 3.0 * float(test_input.timeout) / 1000.0 | 327 driver_timeout_sec = 3.0 * float(test_input.timeout) / 1000.0 |
328 if not self._options.run_singly: | 328 if not self._options.run_singly: |
329 return driver_timeout_sec | 329 return driver_timeout_sec |
330 | 330 |
331 thread_padding_sec = 1.0 | 331 thread_padding_sec = 1.0 |
(...skipping 11 matching lines...) Expand all Loading... |
343 | 343 |
344 def _run_test_with_timeout(self, test_input, timeout, stop_when_done): | 344 def _run_test_with_timeout(self, test_input, timeout, stop_when_done): |
345 if self._options.run_singly: | 345 if self._options.run_singly: |
346 return self._run_test_in_another_thread(test_input, timeout, stop_wh
en_done) | 346 return self._run_test_in_another_thread(test_input, timeout, stop_wh
en_done) |
347 return self._run_test_in_this_thread(test_input, stop_when_done) | 347 return self._run_test_in_this_thread(test_input, stop_when_done) |
348 | 348 |
349 def _clean_up_after_test(self, test_input, result): | 349 def _clean_up_after_test(self, test_input, result): |
350 test_name = test_input.test_name | 350 test_name = test_input.test_name |
351 | 351 |
352 if result.failures: | 352 if result.failures: |
353 # Check and kill DumpRenderTree if we need to. | 353 # Check and kill the driver if we need to. |
354 if any([f.driver_needs_restart() for f in result.failures]): | 354 if any([f.driver_needs_restart() for f in result.failures]): |
355 self._kill_driver() | 355 self._kill_driver() |
356 # Reset the batch count since the shell just bounced. | 356 # Reset the batch count since the shell just bounced. |
357 self._batch_count = 0 | 357 self._batch_count = 0 |
358 | 358 |
359 # Print the error message(s). | 359 # Print the error message(s). |
360 _log.debug("%s %s failed:" % (self._name, test_name)) | 360 _log.debug("%s %s failed:" % (self._name, test_name)) |
361 for f in result.failures: | 361 for f in result.failures: |
362 _log.debug("%s %s" % (self._name, f.message())) | 362 _log.debug("%s %s" % (self._name, f.message())) |
363 elif result.type == test_expectations.SKIP: | 363 elif result.type == test_expectations.SKIP: |
(...skipping 26 matching lines...) Expand all Loading... |
390 def run(self): | 390 def run(self): |
391 self.result = worker._run_single_test(driver, test_input, stop_w
hen_done) | 391 self.result = worker._run_single_test(driver, test_input, stop_w
hen_done) |
392 | 392 |
393 thread = SingleTestThread() | 393 thread = SingleTestThread() |
394 thread.start() | 394 thread.start() |
395 thread.join(thread_timeout_sec) | 395 thread.join(thread_timeout_sec) |
396 result = thread.result | 396 result = thread.result |
397 failures = [] | 397 failures = [] |
398 if thread.isAlive(): | 398 if thread.isAlive(): |
399 # If join() returned with the thread still running, the | 399 # If join() returned with the thread still running, the |
400 # DumpRenderTree is completely hung and there's nothing | 400 # driver is completely hung and there's nothing |
401 # more we can do with it. We have to kill all the | 401 # more we can do with it. We have to kill all the |
402 # DumpRenderTrees to free it up. If we're running more than | 402 # drivers to free it up. If we're running more than |
403 # one DumpRenderTree thread, we'll end up killing the other | 403 # one driver thread, we'll end up killing the other |
404 # DumpRenderTrees too, introducing spurious crashes. We accept | 404 # drivers too, introducing spurious crashes. We accept |
405 # that tradeoff in order to avoid losing the rest of this | 405 # that tradeoff in order to avoid losing the rest of this |
406 # thread's results. | 406 # thread's results. |
407 _log.error('Test thread hung: killing all DumpRenderTrees') | 407 _log.error('Test thread hung: killing all drivers') |
408 failures = [test_failures.FailureTimeout()] | 408 failures = [test_failures.FailureTimeout()] |
409 | 409 |
410 driver.stop() | 410 driver.stop() |
411 | 411 |
412 if not result: | 412 if not result: |
413 result = test_results.TestResult(test_input.test_name, failures=fail
ures, test_run_time=0) | 413 result = test_results.TestResult(test_input.test_name, failures=fail
ures, test_run_time=0) |
414 return result | 414 return result |
415 | 415 |
416 def _run_test_in_this_thread(self, test_input, stop_when_done): | 416 def _run_test_in_this_thread(self, test_input, stop_when_done): |
417 """Run a single test file using a shared DumpRenderTree process. | 417 """Run a single test file using a shared driver process. |
418 | 418 |
419 Args: | 419 Args: |
420 test_input: Object containing the test filename, uri and timeout | 420 test_input: Object containing the test filename, uri and timeout |
421 | 421 |
422 Returns: a TestResult object. | 422 Returns: a TestResult object. |
423 """ | 423 """ |
424 if self._driver and self._driver.has_crashed(): | 424 if self._driver and self._driver.has_crashed(): |
425 self._kill_driver() | 425 self._kill_driver() |
426 if not self._driver: | 426 if not self._driver: |
427 self._driver = self._port.create_driver(self._worker_number) | 427 self._driver = self._port.create_driver(self._worker_number) |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
575 def split_at(seq, index): | 575 def split_at(seq, index): |
576 return (seq[:index], seq[index:]) | 576 return (seq[:index], seq[index:]) |
577 | 577 |
578 num_old_per_new = divide_and_round_up(len(old_shards), max_new_shards) | 578 num_old_per_new = divide_and_round_up(len(old_shards), max_new_shards) |
579 new_shards = [] | 579 new_shards = [] |
580 remaining_shards = old_shards | 580 remaining_shards = old_shards |
581 while remaining_shards: | 581 while remaining_shards: |
582 some_shards, remaining_shards = split_at(remaining_shards, num_old_p
er_new) | 582 some_shards, remaining_shards = split_at(remaining_shards, num_old_p
er_new) |
583 new_shards.append(TestShard('%s_%d' % (shard_name_prefix, len(new_sh
ards) + 1), extract_and_flatten(some_shards))) | 583 new_shards.append(TestShard('%s_%d' % (shard_name_prefix, len(new_sh
ards) + 1), extract_and_flatten(some_shards))) |
584 return new_shards | 584 return new_shards |
OLD | NEW |