Revision: 6248
Author: [email protected]
Date: Mon Jan 10 05:54:42 2011
Log: Enable sharding of individual testsuites in tools/test.py

This patch enables two new flags for the tools/test.py script;
--shard-count - giving the ability to split the tests to be run
into shard-count chunks.
--shard-run - giving the ability to specify which of the shards to actually run.

Example
  tools/test.py -j15 --shard-count=2 --shard-run=1 mozilla
would split the mozilla tests into two chunks and run the tests in the first chunk

Running:
  tools/test.py -j15 --shard-count=2 --shard-run=1 mozilla
  tools/test.py -j15 --shard-count=2 --shard-run=2 mozilla
is equivalent (in terms of test coverage) of just running:
  tools/test.py -j15 mozilla

In addition, tests are now sorted before they are returned from the
test specific ListTests methods (sputnik and mozilla tests where
already sorted before they where returned).

This change is needed to split a single test suite over two slaves on
the waterfall.


Review URL: http://codereview.chromium.org/6127003
http://code.google.com/p/v8/source/detail?r=6248

Modified:
 /branches/bleeding_edge/test/cctest/testcfg.py
 /branches/bleeding_edge/test/es5conform/testcfg.py
 /branches/bleeding_edge/test/message/testcfg.py
 /branches/bleeding_edge/test/mjsunit/testcfg.py
 /branches/bleeding_edge/tools/test.py

=======================================
--- /branches/bleeding_edge/test/cctest/testcfg.py      Tue Dec  7 03:01:02 2010
+++ /branches/bleeding_edge/test/cctest/testcfg.py      Mon Jan 10 05:54:42 2011
@@ -92,6 +92,7 @@
         dependency = relative_path[0] + '/' + dependency
       if self.Contains(path, full_path):
result.append(CcTestCase(full_path, executable, mode, raw_test, dependency, self.context))
+    result.sort()
     return result

   def GetTestStatus(self, sections, defs):
=======================================
--- /branches/bleeding_edge/test/es5conform/testcfg.py Tue Dec 7 03:01:02 2010 +++ /branches/bleeding_edge/test/es5conform/testcfg.py Mon Jan 10 05:54:42 2011
@@ -82,8 +82,10 @@
     for root, dirs, files in os.walk(current_root):
       for dotted in [x  for x in dirs if x.startswith('.')]:
         dirs.remove(dotted)
+      dirs.sort()
       root_path = root[len(self.root):].split(os.path.sep)
       root_path = current_path + [x for x in root_path if x]
+      files.sort()
       for file in files:
         if file.endswith('.js'):
           full_path = root_path + [file[:-3]]
=======================================
--- /branches/bleeding_edge/test/message/testcfg.py     Tue Dec  7 03:01:02 2010
+++ /branches/bleeding_edge/test/message/testcfg.py     Mon Jan 10 05:54:42 2011
@@ -107,6 +107,9 @@
     mjsunit = [current_path + [t] for t in self.Ls(self.root)]
regress = [current_path + ['regress', t] for t in self.Ls(join(self.root, 'regress'))] bugs = [current_path + ['bugs', t] for t in self.Ls(join(self.root, 'bugs'))]
+    mjsunit.sort()
+    regress.sort()
+    bugs.sort()
     all_tests = mjsunit + regress + bugs
     result = []
     for test in all_tests:
=======================================
--- /branches/bleeding_edge/test/mjsunit/testcfg.py     Tue Dec  7 03:01:02 2010
+++ /branches/bleeding_edge/test/mjsunit/testcfg.py     Mon Jan 10 05:54:42 2011
@@ -111,6 +111,12 @@
third_party = [current_path + ['third_party', t] for t in self.Ls(join(self.root, 'third_party'))] tools = [current_path + ['tools', t] for t in self.Ls(join(self.root, 'tools'))] compiler = [current_path + ['compiler', t] for t in self.Ls(join(self.root, 'compiler'))]
+    mjsunit.sort()
+    regress.sort()
+    bugs.sort()
+    third_party.sort()
+    tools.sort()
+    compiler.sort()
     all_tests = mjsunit + regress + bugs + third_party + tools + compiler
     result = []
     for test in all_tests:
=======================================
--- /branches/bleeding_edge/tools/test.py       Thu Dec 16 04:14:56 2010
+++ /branches/bleeding_edge/tools/test.py       Mon Jan 10 05:54:42 2011
@@ -1181,6 +1181,12 @@
   result.add_option("--crankshaft",
                     help="Run with the --crankshaft flag",
                     default=False, action="store_true")
+  result.add_option("--shard-count",
+                    help="Split testsuites into this number of shards",
+                    default=1, type="int")
+  result.add_option("--shard-run",
+                    help="Run this shard from the split up tests.",
+                    default=1, type="int")
   result.add_option("--noprof", help="Disable profiling support",
                     default=False)
   return result
@@ -1302,6 +1308,20 @@
   millis = round(d * 1000) % 1000
   return time.strftime("%M:%S.", time.gmtime(d)) + ("%03i" % millis)

+def ShardTests(tests, options):
+  if options.shard_count < 2:
+    return tests
+  if options.shard_run < 1 or options.shard_run > options.shard_count:
+    print "shard-run not a valid number, should be in [1:shard-count]"
+    print "defaulting back to running all tests"
+    return tests
+  count = 0;
+  shard = []
+  for test in tests:
+    if count % options.shard_count == options.shard_run - 1:
+      shard.append(test);
+    count += 1
+  return shard

 def Main():
   parser = BuildOptions()
@@ -1385,7 +1405,7 @@
         globally_unused_rules = set(unused_rules)
       else:
globally_unused_rules = globally_unused_rules.intersection(unused_rules)
-      all_cases += cases
+      all_cases += ShardTests(cases, options)
       all_unused.append(unused_rules)

   if options.cat:

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to