Tools/ChangeLog

22
33 Reviewed by NOBODY (OOPS!).
44
 5 nrwt: allow for multiple http shards
 6 https://bugs.webkit.org/show_bug.cgi?id=63116
 7
 8 * Scripts/webkitpy/layout_tests/layout_package/manager.py:
 9 * Scripts/webkitpy/layout_tests/layout_package/manager_unittest.py:
 10
 112011-06-21 Dirk Pranke <dpranke@chromium.org>
 12
 13 Reviewed by NOBODY (OOPS!).
 14
515 nrwt: make sharding tests needing locks less hard-coded
616 https://bugs.webkit.org/show_bug.cgi?id=63112
717

Tools/Scripts/webkitpy/layout_tests/layout_package/manager.py

@@class Manager:
547547 Two lists of lists of TestInput objects. The first list should
548548 only be run under the server lock, the second can be run whenever.
549549 """
550  # FIXME: We still need to support multiple locked shards.
551550 locked_shards = []
552551 unlocked_shards = []
553552 tests_to_http_lock = []
554553 if not use_real_shards:
555554 for test_file in test_files:
 555 directory = self._get_dir_for_test_file(test_file)
556556 test_input = self._get_test_input_for_file(test_file)
557557 if self._test_requires_lock(test_file):
558  tests_to_http_lock.append(test_input)
 558 locked_shards.append((directory, [test_input]))
559559 else:
560  unlocked_shards.append((".", [test_input]))
 560 unlocked_shards.append((directory, [test_input]))
561561 else:
562562 tests_by_dir = {}
563563 for test_file in test_files:
564564 directory = self._get_dir_for_test_file(test_file)
565565 test_input = self._get_test_input_for_file(test_file)
566  if self._test_requires_lock(test_file):
567  tests_to_http_lock.append(test_input)
568  else:
569  tests_by_dir.setdefault(directory, [])
570  tests_by_dir[directory].append(test_input)
 566 tests_by_dir.setdefault(directory, [])
 567 tests_by_dir[directory].append(test_input)
571568 for directory in tests_by_dir:
572569 test_list = tests_by_dir[directory]
573570 test_list_tuple = (directory, test_list)
574  unlocked_shards.append(test_list_tuple)
 571 if self._test_requires_lock(directory):
 572 locked_shards.append(test_list_tuple)
 573 else:
 574 unlocked_shards.append(test_list_tuple)
575575
576576 # Sort the shards by directory name.
 577 locked_shards.sort(lambda a, b: cmp(a[0], b[0]))
577578 unlocked_shards.sort(lambda a, b: cmp(a[0], b[0]))
578579
579  if tests_to_http_lock:
580  locked_shards.append(("tests_to_http_lock", tests_to_http_lock))
 580 # Put a ceiling on the number of locked shards, so that we
 581 # don't hammer the servers too badly. For now we will
 582 # arbitrarily limit this to no more than a quarter of all workers.
 583 max_locked_shards = max(math.ceil(int(self._options.child_processes) / 4.0), 1)
 584 dirs_per_new_shard = math.ceil(len(locked_shards) / max_locked_shards * 1.0)
 585 new_locked_shards = []
 586 i = 1
 587 j = 1
 588 tests = []
 589 while locked_shards:
 590 shard = locked_shards.pop()
 591 tests.extend(shard[1])
 592 i += 1
 593 if i > dirs_per_new_shard:
 594 new_locked_shards.append(('locked_shard_%d' % j, tests))
 595 i = 0
 596 j += 1
 597 tests = []
 598 if tests:
 599 new_locked_shards.append(('locked_shard_%d' % j, tests))
 600 locked_shards = new_locked_shards
581601
582602 return (locked_shards, unlocked_shards)
583603

@@class Manager:
587607 return True
588608 return False
589609
590  def _num_workers(self, num_shards):
 610 def _num_workers(self, num_shards, num_locked_shards):
591611 num_workers = min(int(self._options.child_processes), num_shards)
592612 driver_name = self._port.driver_name()
593613 if num_workers == 1:
594614 self._printer.print_config("Running 1 %s over %s" %
595615 (driver_name, grammar.pluralize('shard', num_shards)))
596616 else:
597  self._printer.print_config("Running %d %ss in parallel over %d shards" %
598  (num_workers, driver_name, num_shards))
 617 self._printer.print_config("Running %d %ss in parallel over %d shards (%d locked)" %
 618 (num_workers, driver_name, num_shards, num_locked_shards))
599619 return num_workers
600620
601621 def _run_tests(self, file_list, result_summary):

@@class Manager:
632652
633653 all_shards = self._locked_shards + self._unlocked_shards
634654
635  num_workers = self._num_workers(len(all_shards))
 655 num_workers = self._num_workers(len(all_shards), len(self._locked_shards))
636656 manager_connection = manager_worker_broker.get(self._port, self._options,
637657 self, worker.Worker)
638658

Tools/Scripts/webkitpy/layout_tests/layout_package/manager_unittest.py

@@class ManagerWrapper(manager.Manager):
4545
4646class ManagerTest(unittest.TestCase):
4747 def test_shard_tests(self):
 48 # FIXME: Should probably replace this with more interesting tests
 49 # now that the sharding logic is totally different.
 50
4851 # Test that _shard_tests in test_runner.TestRunner really
4952 # put the http tests first in the queue.
5053 port = Mock()

@@class ManagerTest(unittest.TestCase):
5255 manager = ManagerWrapper(port=port, options=Mock(), printer=Mock())
5356
5457 test_list = [
55  "LayoutTests/websocket/tests/unicode.htm",
 58 "LayoutTests/http/tests/websocket/tests/unicode.htm",
5659 "LayoutTests/animations/keyframes.html",
5760 "LayoutTests/http/tests/security/view-source-no-refresh.html",
58  "LayoutTests/websocket/tests/websocket-protocol-ignored.html",
 61 "LayoutTests/http/tests/websocket/tests/websocket-protocol-ignored.html",
5962 "LayoutTests/fast/css/display-none-inline-style-change-crash.html",
6063 "LayoutTests/http/tests/xmlhttprequest/supported-xml-content-types.html",
6164 "LayoutTests/dom/html/level2/html/HTMLAnchorElement03.html",

@@class ManagerTest(unittest.TestCase):
6366 "LayoutTests/dom/html/level2/html/HTMLAnchorElement06.html",
6467 ]
6568
66  expected_tests_to_http_lock = set([
67  'LayoutTests/websocket/tests/unicode.htm',
68  'LayoutTests/http/tests/security/view-source-no-refresh.html',
69  'LayoutTests/websocket/tests/websocket-protocol-ignored.html',
70  'LayoutTests/http/tests/xmlhttprequest/supported-xml-content-types.html',
71  ])
72 
7369 single_locked, single_unlocked = manager._shard_tests(test_list, False)
7470 multi_locked, multi_unlocked = manager._shard_tests(test_list, True)
7571
76  self.assertEqual("tests_to_http_lock", single_locked[0][0])
77  self.assertEqual(expected_tests_to_http_lock, set(single_locked[0][1]))
78  self.assertEqual("tests_to_http_lock", multi_locked[0][0])
79  self.assertEqual(expected_tests_to_http_lock, set(multi_locked[0][1]))
 72 self.assertEqual("http/tests/websocket/tests", single_locked[0][0])
 73 self.assertEqual(set(['LayoutTests/http/tests/websocket/tests/unicode.htm']), set(single_locked[0][1]))
 74 self.assertEqual("http/tests/security", multi_locked[0][0])
 75 self.assertEqual(set(['LayoutTests/http/tests/security/view-source-no-refresh.html']), set(multi_locked[0][1]))
8076
8177
8278class NaturalCompareTest(unittest.TestCase):