Changeset 90417 in webkit
- Timestamp:
- Jul 5, 2011 5:07:12 PM (13 years ago)
- Location:
- trunk/Tools
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Tools/ChangeLog
r90416 r90417 1 2011-07-05 Dirk Pranke <dpranke@chromium.org> 2 3 Re-land nrwt: make sharding tests needing locks less hard-coded 4 https://bugs.webkit.org/show_bug.cgi?id=63112 5 6 Reviewed by Ojan Vafai. 7 8 * Scripts/webkitpy/layout_tests/layout_package/manager.py: 9 * Scripts/webkitpy/layout_tests/layout_package/manager_unittest.py: 10 1 11 2011-07-05 Adam Barth <abarth@webkit.org> 2 12 -
trunk/Tools/Scripts/webkitpy/layout_tests/layout_package/manager.py
r90413 r90417 238 238 239 239 240 class Manager :240 class Manager(object): 241 241 """A class for managing running a series of tests on a series of layout 242 242 test files.""" … … 266 266 self.LAYOUT_TESTS_DIRECTORY = "LayoutTests" + self._fs.sep 267 267 self._has_http_lock = False 268 269 self._remaining_locked_shards = [] 268 270 269 271 # disable wss server. need to install pyOpenSSL on buildbots. … … 543 545 544 546 Return: 545 A list of lists of TestInput objects. 546 """ 547 # FIXME: when we added http locking, we changed how this works such 548 # that we always lump all of the HTTP threads into a single shard. 549 # That will slow down experimental-fully-parallel, but it's unclear 550 # what the best alternative is completely revamping how we track 551 # when to grab the lock. 552 553 test_lists = [] 547 Two lists of lists of TestInput objects. The first list should 548 only be run under the server lock, the second can be run whenever. 549 """ 550 # FIXME: We still need to support multiple locked shards. 551 locked_shards = [] 552 unlocked_shards = [] 554 553 tests_to_http_lock = [] 555 554 if not use_real_shards: … … 559 558 tests_to_http_lock.append(test_input) 560 559 else: 561 test_lists.append((".", [test_input]))560 unlocked_shards.append((".", [test_input])) 562 561 else: 563 562 tests_by_dir = {} … … 573 572 test_list = tests_by_dir[directory] 574 573 test_list_tuple = (directory, test_list) 575 test_lists.append(test_list_tuple)574 unlocked_shards.append(test_list_tuple) 576 575 577 576 # Sort the shards by directory name. 578 test_lists.sort(lambda a, b: cmp(a[0], b[0])) 579 580 # Put the http tests first. There are only a couple hundred of them, 581 # but each http test takes a very long time to run, so sorting by the 582 # number of tests doesn't accurately capture how long they take to run. 577 unlocked_shards.sort(lambda a, b: cmp(a[0], b[0])) 578 583 579 if tests_to_http_lock: 584 test_lists.insert(0, ("tests_to_http_lock", tests_to_http_lock))585 586 return test_lists580 locked_shards = [("tests_to_http_lock", tests_to_http_lock)] 581 582 return (locked_shards, unlocked_shards) 587 583 588 584 def _contains_tests(self, subdir): … … 629 625 630 626 self._printer.print_update('Sharding tests ...') 631 test_lists = self._shard_tests(file_list,627 locked_shards, unlocked_shards = self._shard_tests(file_list, 632 628 int(self._options.child_processes) > 1 and not self._options.experimental_fully_parallel) 633 629 634 # FIXME: we need a less hard-coded way of figuring out if we need to 635 # start the servers. 636 if test_lists[0][0] == 'tests_to_http_lock': 630 # FIXME: We don't have a good way to coordinate the workers so that 631 # they don't try to run the shards that need a lock if we don't actually 632 # have the lock. The easiest solution at the moment is to grab the 633 # lock at the beginning of the run, and then run all of the locked 634 # shards first. This minimizes the time spent holding the lock, but 635 # means that we won't be running tests while we're waiting for the lock. 636 # If this becomes a problem in practice we'll need to change this. 637 638 all_shards = locked_shards + unlocked_shards 639 self._remaining_locked_shards = locked_shards 640 if locked_shards: 637 641 self.start_servers_with_lock() 638 642 639 num_workers = self._num_workers(len( test_lists))643 num_workers = self._num_workers(len(all_shards)) 640 644 manager_connection = manager_worker_broker.get(self._port, self._options, 641 645 self, worker.Worker) … … 659 663 660 664 self._printer.print_update("Starting testing ...") 661 for test_list in test_lists:662 manager_connection.post_message('test_list', test_list[0], test_list[1])665 for shard in all_shards: 666 manager_connection.post_message('test_list', shard[0], shard[1]) 663 667 664 668 # We post one 'stop' message for each worker. Because the stop message … … 1341 1345 self._group_stats[list_name] = (num_tests, elapsed_time) 1342 1346 1347 def find(name, test_lists): 1348 for i in range(len(test_lists)): 1349 if test_lists[i][0] == name: 1350 return i 1351 return -1 1352 1353 index = find(list_name, self._remaining_locked_shards) 1354 if index >= 0: 1355 self._remaining_locked_shards.pop(index) 1356 if not self._remaining_locked_shards: 1357 self.stop_servers_with_lock() 1358 1343 1359 def handle_finished_test(self, source, result, elapsed_time): 1344 1360 worker_state = self._worker_states[source] -
trunk/Tools/Scripts/webkitpy/layout_tests/layout_package/manager_unittest.py
r90413 r90417 29 29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 30 31 """Unit tests for manager. Manager()."""31 """Unit tests for manager.py.""" 32 32 33 import StringIO 33 34 import unittest 34 35 35 36 from webkitpy.common.system import filesystem_mock 37 from webkitpy.common.system import outputcapture 36 38 from webkitpy.thirdparty.mock import Mock 37 39 40 from webkitpy import layout_tests 41 from webkitpy.layout_tests import run_webkit_tests 38 42 from webkitpy.layout_tests.layout_package.manager import Manager, natural_sort_key, path_key, TestRunInterruptedException 43 from webkitpy.layout_tests.layout_package import printing 39 44 from webkitpy.layout_tests.layout_package.result_summary import ResultSummary 40 45 from webkitpy.tool.mocktool import MockOptions … … 73 78 ]) 74 79 75 # FIXME: Ideally the HTTP tests don't have to all be in one shard. 76 single_thread_results = manager._shard_tests(test_list, False) 77 multi_thread_results = manager._shard_tests(test_list, True) 80 single_locked, single_unlocked = manager._shard_tests(test_list, False) 81 multi_locked, multi_unlocked = manager._shard_tests(test_list, True) 78 82 79 self.assertEqual("tests_to_http_lock", single_thread_results[0][0]) 80 self.assertEqual(expected_tests_to_http_lock, set(single_thread_results[0][1])) 81 self.assertEqual("tests_to_http_lock", multi_thread_results[0][0]) 82 self.assertEqual(expected_tests_to_http_lock, set(multi_thread_results[0][1])) 83 self.assertEqual("tests_to_http_lock", single_locked[0][0]) 84 self.assertEqual(expected_tests_to_http_lock, set(single_locked[0][1])) 85 self.assertEqual("tests_to_http_lock", multi_locked[0][0]) 86 self.assertEqual(expected_tests_to_http_lock, set(multi_locked[0][1])) 87 88 def test_http_locking(tester): 89 class LockCheckingManager(Manager): 90 def __init__(self, port, options, printer): 91 super(LockCheckingManager, self).__init__(port, options, printer) 92 self._finished_list_called = False 93 94 def handle_finished_list(self, source, list_name, num_tests, elapsed_time): 95 if not self._finished_list_called: 96 tester.assertEquals(list_name, 'tests_to_http_lock') 97 tester.assertTrue(self._remaining_locked_shards) 98 tester.assertTrue(self._has_http_lock) 99 100 super(LockCheckingManager, self).handle_finished_list(source, list_name, num_tests, elapsed_time) 101 102 if not self._finished_list_called: 103 tester.assertEquals(self._remaining_locked_shards, []) 104 tester.assertFalse(self._has_http_lock) 105 self._finished_list_called = True 106 107 options, args = run_webkit_tests.parse_args(['--platform=test', '--print=nothing', 'http/tests/passes', 'passes']) 108 port = layout_tests.port.get(port_name=options.platform, options=options) 109 run_webkit_tests._set_up_derived_options(port, options) 110 printer = printing.Printer(port, options, StringIO.StringIO(), StringIO.StringIO(), 111 configure_logging=True) 112 manager = LockCheckingManager(port, options, printer) 113 manager.collect_tests(args, []) 114 manager.parse_expectations() 115 result_summary = manager.set_up_run() 116 num_unexpected_results = manager.run(result_summary) 117 manager.clean_up_run() 118 printer.cleanup() 119 tester.assertEquals(num_unexpected_results, 0) 83 120 84 121 def test_interrupt_if_at_failure_limits(self):
Note: See TracChangeset
for help on using the changeset viewer.