Bug 485736 - Add (TUnit) 'xpcshell-tests' |make| target, using |runxpcshelltests.py| new '--manifest' option; (Dv1a) Add |EXTRA_TEST_ARGS| support, enhance |--test| feature; r=ted.mielczarek
authorSerge Gautherie <sgautherie.bz@free.fr>
Tue, 28 Apr 2009 01:37:02 +0200
changeset 27868 5a8a199bd62aeadef2cfe34a585630c22033111e
parent 27867 5e3157d1c28ce9d36a8ebb1e915ea708b5bef645
child 27869 37f01fdbb22e90774f95da1f4ff56be809134139
push idunknown
push userunknown
push dateunknown
reviewersted
bugs485736
milestone1.9.2a1pre
Bug 485736 - Add (TUnit) 'xpcshell-tests' |make| target, using |runxpcshelltests.py| new '--manifest' option; (Dv1a) Add |EXTRA_TEST_ARGS| support, enhance |--test| feature; r=ted.mielczarek
testing/testsuite-targets.mk
testing/xpcshell/runxpcshelltests.py
--- a/testing/testsuite-targets.mk
+++ b/testing/testsuite-targets.mk
@@ -32,40 +32,47 @@
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 
-# Usage: |make [EXTRA_TEST_ARGS=...] mochitest*|.
+# Shortcut for mochitest* and xpcshell-tests targets,
+# replaces 'EXTRA_TEST_ARGS=--test-path=...'.
+ifdef TEST_PATH
+TEST_PATH_ARG := --test-path=$(TEST_PATH)
+else
+TEST_PATH_ARG :=
+endif
+
+
+# Usage: |make [TEST_PATH=...] [EXTRA_TEST_ARGS=...] mochitest*|.
 mochitest:: mochitest-plain mochitest-chrome mochitest-a11y
 
-RUN_MOCHITEST = rm -f ./$@.log && $(PYTHON) _tests/testing/mochitest/runtests.py --autorun --close-when-done --console-level=INFO --log-file=./$@.log --file-level=INFO $(MOCHITEST_PATH) $(EXTRA_TEST_ARGS)
+RUN_MOCHITEST = \
+	rm -f ./$@.log && \
+	$(PYTHON) _tests/testing/mochitest/runtests.py --autorun --close-when-done \
+	  --console-level=INFO --log-file=./$@.log --file-level=INFO \
+	  $(TEST_PATH_ARG) $(EXTRA_TEST_ARGS)
 
 ifndef NO_FAIL_ON_TEST_ERRORS
 define CHECK_TEST_ERROR
   @errors=`grep "TEST-UNEXPECTED-" $@.log` ;\
   if test "$$errors" ; then \
 	  echo "$@ failed:"; \
 	  echo "$$errors"; \
 	  exit 1; \
   else \
 	  echo "$@ passed"; \
   fi
 endef
 endif
 
-ifdef TEST_PATH
-MOCHITEST_PATH = --test-path=$(TEST_PATH)
-else
-MOCHITEST_PATH =
-endif
-
 mochitest-plain:
 	$(RUN_MOCHITEST)
 	$(CHECK_TEST_ERROR)
 
 mochitest-chrome:
 	$(RUN_MOCHITEST) --chrome
 	$(CHECK_TEST_ERROR)
 
@@ -83,20 +90,22 @@ reftest:
 
 crashtest:
 	$(call RUN_REFTEST,$(topsrcdir)/testing/crashtest/crashtests.list)
 	$(CHECK_TEST_ERROR)
 
 
 # Execute all xpcshell tests in the directories listed in the manifest.
 # See also config/rules.mk 'xpcshell-tests' target for local execution.
+# Usage: |make [TEST_PATH=...] [EXTRA_TEST_ARGS=...] xpcshell-tests|.
 xpcshell-tests:
 	$(PYTHON) -u \
 	  $(topsrcdir)/testing/xpcshell/runxpcshelltests.py \
 	  --manifest=$(DEPTH)/_tests/xpcshell/all-test-dirs.list \
+	  $(TEST_PATH_ARG) $(EXTRA_TEST_ARGS) \
 	  $(DIST)/bin/xpcshell
 
 
 # Package up the tests and test harnesses
 include $(topsrcdir)/toolkit/mozapps/installer/package-name.mk
 
 PKG_STAGE = $(DIST)/test-package-stage
 
--- a/testing/xpcshell/runxpcshelltests.py
+++ b/testing/xpcshell/runxpcshelltests.py
@@ -54,23 +54,23 @@ def readManifest(manifest):
       path = os.path.join(manifestdir, dir)
       if os.path.isdir(path):
         testdirs.append(path)
     f.close()
   except:
     pass # just eat exceptions
   return testdirs
 
-def runTests(xpcshell, testdirs=[], xrePath=None, testFile=None,
+def runTests(xpcshell, testdirs=[], xrePath=None, testPath=None,
              manifest=None, interactive=False):
   """Run the tests in |testdirs| using the |xpcshell| executable.
 
   |xrePath|, if provided, is the path to the XRE to use.
-  |testFile|, if provided, indicates a single test to run.
-  |manifeest|, if provided, is a file containing a list of
+  |testPath|, if provided, indicates a single path and/or test to run.
+  |manifest|, if provided, is a file containing a list of
     test directories to run.
   |interactive|, if set to True, indicates to provide an xpcshell prompt
     instead of automatically executing  the test.
   """
 
   if not testdirs and not manifest:
     # nothing to test!
     print >>sys.stderr, "Error: No test dirs or test manifest specified!"
@@ -120,51 +120,63 @@ def runTests(xpcshell, testdirs=[], xreP
   args = [xpcshell, '-g', xrePath, '-j', '-s']
 
   headfiles = ['-f', os.path.join(testharnessdir, 'head.js'),
                '-e', 'function do_load_httpd_js() {load("%s");}' % httpdJSPath]
   tailfiles = ['-f', os.path.join(testharnessdir, 'tail.js')]
   if not interactive:
     tailfiles += ['-e', '_execute_test();']
 
-  # when --test is specified, it can either be just a filename or
-  # testdir/filename. This is for convenience when there's only one
-  # test dir.
-  singleDir = None
-  if testFile and testFile.find('/') != -1:
-    # directory was specified
-    bits = testFile.split('/', 1)
-    singleDir = bits[0]
-    testFile = bits[1]
+  # |testPath| will be the optional path only, or |None|.
+  # |singleFile| will be the optional test only, or |None|.
+  singleFile = None
+  if testPath:
+    if testPath.endswith('.js'):
+      # Split into path and file.
+      if testPath.find('/') == -1:
+        # Test only.
+        singleFile = testPath
+        testPath = None
+      else:
+        # Both path and test.
+        # Reuse |testPath| temporarily.
+        testPath = testPath.rsplit('/', 1)
+        singleFile = testPath[1]
+        testPath = testPath[0]
+    else:
+      # Path only.
+      # Simply remove optional ending separator.
+      testPath = testPath.rstrip("/")
 
   if manifest is not None:
     testdirs = readManifest(os.path.abspath(manifest))
 
   # Process each test directory individually.
   success = True
   for testdir in testdirs:
-    if singleDir and singleDir != os.path.basename(testdir):
+    if testPath and not testdir.endswith(testPath):
       continue
+
     testdir = os.path.abspath(testdir)
 
     # get the list of head and tail files from the directory
     testheadfiles = []
     for f in sorted(glob(os.path.join(testdir, "head_*.js"))):
       if os.path.isfile(f):
         testheadfiles += ['-f', f]
     testtailfiles = []
     for f in sorted(glob(os.path.join(testdir, "tail_*.js"))):
       if os.path.isfile(f):
         testtailfiles += ['-f', f]
 
     # if a single test file was specified, we only want to execute that test
     testfiles = sorted(glob(os.path.join(testdir, "test_*.js")))
-    if testFile:
-      if testFile in [os.path.basename(x) for x in testfiles]:
-        testfiles = [os.path.join(testdir, testFile)]
+    if singleFile:
+      if singleFile in [os.path.basename(x) for x in testfiles]:
+        testfiles = [os.path.join(testdir, singleFile)]
       else: # not in this dir? skip it
         continue
 
     # Now execute each test individually.
     for test in testfiles:
       pstdout = PIPE
       pstderr = STDOUT
       interactiveargs = []
@@ -201,39 +213,39 @@ def runTests(xpcshell, testdirs=[], xreP
   return success
 
 def main():
   """Process command line arguments and call runTests() to do the real work."""
   parser = OptionParser()
   parser.add_option("--xre-path",
                     action="store", type="string", dest="xrePath", default=None,
                     help="absolute path to directory containing XRE (probably xulrunner)")
-  parser.add_option("--test",
-                    action="store", type="string", dest="testFile",
-                    default=None, help="single test filename to test")
+  parser.add_option("--test-path",
+                    action="store", type="string", dest="testPath",
+                    default=None, help="single path and/or test filename to test")
   parser.add_option("--interactive",
                     action="store_true", dest="interactive", default=False,
                     help="don't automatically run tests, drop to an xpcshell prompt")
   parser.add_option("--manifest",
                     action="store", type="string", dest="manifest",
                     default=None, help="Manifest of test directories to use")
   options, args = parser.parse_args()
 
   if len(args) < 2 and options.manifest is None or \
      (len(args) < 1 and options.manifest is not None):
     print >>sys.stderr, """Usage: %s <path to xpcshell> <test dirs>
   or: %s --manifest=test.manifest <path to xpcshell>""" % (sys.argv[0],
                                                            sys.argv[0])
     sys.exit(1)
 
-  if options.interactive and not options.testFile:
+  if options.interactive and not options.testPath:
     print >>sys.stderr, "Error: You must specify a test filename in interactive mode!"
     sys.exit(1)
 
   if not runTests(args[0], testdirs=args[1:],
                   xrePath=options.xrePath,
-                  testFile=options.testFile,
+                  testPath=options.testPath,
                   interactive=options.interactive,
                   manifest=options.manifest):
     sys.exit(1)
 
 if __name__ == '__main__':
   main()