Bug 729098 - Part 1/2: Create xUnit XML results file when executing xpcshell tests; r=khuey
authorGregory Szorc <gps@mozilla.com>
Tue, 06 Mar 2012 15:03:34 -0800
changeset 91293 8ee446a837d52b100974780141f60559694198ec
parent 91292 142a1cfb0dfcf863f70b7d20ebc9b0eaff0b2bad
child 91294 9c66a3ed924a6d6fc3ab192cc14e7e10cfe0bbdf
push id783
push userlsblakk@mozilla.com
push dateTue, 24 Apr 2012 17:33:42 +0000
treeherdermozilla-beta@11faed19f136 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskhuey
bugs729098
milestone13.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 729098 - Part 1/2: Create xUnit XML results file when executing xpcshell tests; r=khuey
config/rules.mk
js/src/config/rules.mk
testing/testsuite-targets.mk
testing/xpcshell/runxpcshelltests.py
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -143,16 +143,19 @@ testxpcsrcdir = $(topsrcdir)/testing/xpc
 # Execute all tests in the $(XPCSHELL_TESTS) directories.
 # See also testsuite-targets.mk 'xpcshell-tests' target for global execution.
 xpcshell-tests:
 	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
 	  -I$(topsrcdir)/build \
 	  $(testxpcsrcdir)/runxpcshelltests.py \
 	  --symbols-path=$(DIST)/crashreporter-symbols \
 	  --build-info-json=$(DEPTH)/mozinfo.json \
+	  --tests-root-dir=$(testxpcobjdir) \
+	  --xunit-file=$(testxpcobjdir)/$(relativesrcdir)/results.xml \
+	  --xunit-suite-name=xpcshell \
 	  $(EXTRA_TEST_ARGS) \
 	  $(LIBXUL_DIST)/bin/xpcshell \
 	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
 
 xpcshell-tests-remote: DM_TRANS?=adb
 xpcshell-tests-remote:
 	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
 	  -I$(topsrcdir)/build \
--- a/js/src/config/rules.mk
+++ b/js/src/config/rules.mk
@@ -143,16 +143,19 @@ testxpcsrcdir = $(topsrcdir)/testing/xpc
 # Execute all tests in the $(XPCSHELL_TESTS) directories.
 # See also testsuite-targets.mk 'xpcshell-tests' target for global execution.
 xpcshell-tests:
 	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
 	  -I$(topsrcdir)/build \
 	  $(testxpcsrcdir)/runxpcshelltests.py \
 	  --symbols-path=$(DIST)/crashreporter-symbols \
 	  --build-info-json=$(DEPTH)/mozinfo.json \
+	  --tests-root-dir=$(testxpcobjdir) \
+	  --xunit-file=$(testxpcobjdir)/$(relativesrcdir)/results.xml \
+	  --xunit-suite-name=xpcshell \
 	  $(EXTRA_TEST_ARGS) \
 	  $(LIBXUL_DIST)/bin/xpcshell \
 	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
 
 xpcshell-tests-remote: DM_TRANS?=adb
 xpcshell-tests-remote:
 	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
 	  -I$(topsrcdir)/build \
--- a/testing/testsuite-targets.mk
+++ b/testing/testsuite-targets.mk
@@ -236,16 +236,19 @@ GARBAGE += $(addsuffix .log,$(MOCHITESTS
 # Usage: |make [TEST_PATH=...] [EXTRA_TEST_ARGS=...] xpcshell-tests|.
 xpcshell-tests:
 	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
 	  -I$(topsrcdir)/build \
 	  $(topsrcdir)/testing/xpcshell/runxpcshelltests.py \
 	  --manifest=$(DEPTH)/_tests/xpcshell/xpcshell.ini \
 	  --build-info-json=$(DEPTH)/mozinfo.json \
 	  --no-logfiles \
+	  --tests-root-dir=$(call core_abspath,_tests/xpcshell) \
+	  --xunit-file=$(call core_abspath,_tests/xpcshell/results.xml) \
+	  --xunit-suite-name=xpcshell \
           $(SYMBOLS_PATH) \
 	  $(TEST_PATH_ARG) $(EXTRA_TEST_ARGS) \
 	  $(LIBXUL_DIST)/bin/xpcshell
 
 REMOTE_XPCSHELL = \
 	rm -f ./$@.log && \
 	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
 	  -I$(topsrcdir)/build \
--- a/testing/xpcshell/runxpcshelltests.py
+++ b/testing/xpcshell/runxpcshelltests.py
@@ -493,17 +493,18 @@ class XPCShellTests(object):
     doc.writexml(fh, addindent="  ", newl="\n", encoding="utf-8")
 
   def runTests(self, xpcshell, xrePath=None, appPath=None, symbolsPath=None,
                manifest=None, testdirs=None, testPath=None,
                interactive=False, verbose=False, keepGoing=False, logfiles=True,
                thisChunk=1, totalChunks=1, debugger=None,
                debuggerArgs=None, debuggerInteractive=False,
                profileName=None, mozInfo=None, shuffle=False,
-               xunitFilename=None, xunitName=None, **otherOptions):
+               testsRootDir=None, xunitFilename=None, xunitName=None,
+               **otherOptions):
     """Run xpcshell tests.
 
     |xpcshell|, is the xpcshell executable to use to run the tests.
     |xrePath|, if provided, is the path to the XRE to use.
     |appPath|, if provided, is the path to an application directory.
     |symbolsPath|, if provided is the path to a directory containing
       breakpad symbols for processing crashes in tests.
     |manifest|, if provided, is a file containing a list of
@@ -518,28 +519,41 @@ class XPCShellTests(object):
     |logfiles|, if set to False, indicates not to save output to log files.
       Non-interactive only option.
     |debuggerInfo|, if set, specifies the debugger and debugger arguments
       that will be used to launch xpcshell.
     |profileName|, if set, specifies the name of the application for the profile
       directory if running only a subset of tests.
     |mozInfo|, if set, specifies specifies build configuration information, either as a filename containing JSON, or a dict.
     |shuffle|, if True, execute tests in random order.
+    |testsRootDir|, absolute path to root directory of all tests. This is used
+      by xUnit generation to determine the package name of the tests.
     |xunitFilename|, if set, specifies the filename to which to write xUnit XML
       results.
     |xunitName|, if outputting an xUnit XML file, the str value to use for the
       testsuite name.
     |otherOptions| may be present for the convenience of subclasses
     """
 
     global gotSIGINT
 
     if testdirs is None:
         testdirs = []
 
+    if xunitFilename is not None or xunitName is not None:
+        if not isinstance(testsRootDir, str):
+            raise Exception("testsRootDir must be a str when outputting xUnit.")
+
+        if not os.path.isabs(testsRootDir):
+            testsRootDir = os.path.abspath(testsRootDir)
+
+        if not os.path.exists(testsRootDir):
+            raise Exception("testsRootDir path does not exists: %s" %
+                    testsRootDir)
+
     self.xpcshell = xpcshell
     self.xrePath = xrePath
     self.appPath = appPath
     self.symbolsPath = symbolsPath
     self.manifest = manifest
     self.testdirs = testdirs
     self.testPath = testPath
     self.interactive = interactive
@@ -593,17 +607,26 @@ class XPCShellTests(object):
       if self.singleFile and not name.endswith(self.singleFile):
         continue
 
       if self.testPath and name.find(self.testPath) == -1:
         continue
 
       self.testCount += 1
 
-      xunitResult = {"classname": "xpcshell", "name": test["name"]}
+      xunitResult = {"name": test["name"], "classname": "xpcshell"}
+      # The xUnit package is defined as the path component between the root
+      # dir and the test with path characters replaced with '.' (using Java
+      # class notation).
+      if testsRootDir is not None:
+          if test["here"].find(testsRootDir) != 0:
+              raise Exception("testsRootDir is not a parent path of %s" %
+                  test["here"])
+          relpath = test["here"][len(testsRootDir):].lstrip("/\\")
+          xunitResult["classname"] = relpath.replace("/", ".").replace("\\", ".")
 
       # Check for skipped tests
       if 'disabled' in test:
         self.log.info("TEST-INFO | skipping %s | %s" %
                       (name, test['disabled']))
 
         xunitResult["skipped"] = True
         xunitResults.append(xunitResult)
@@ -770,16 +793,19 @@ class XPCShellOptions(OptionParser):
                     type="string", dest="manifest", default=None,
                     help="Manifest of test directories to use")
     self.add_option("--no-logfiles",
                     action="store_false", dest="logfiles",
                     help="don't create log files")
     self.add_option("--test-path",
                     type="string", dest="testPath", default=None,
                     help="single path and/or test filename to test")
+    self.add_option("--tests-root-dir",
+                    type="string", dest="testsRootDir", default=None,
+                    help="absolute path to directory where all tests are located. this is typically $(objdir)/_tests")
     self.add_option("--total-chunks",
                     type = "int", dest = "totalChunks", default=1,
                     help = "how many chunks to split the tests up into")
     self.add_option("--this-chunk",
                     type = "int", dest = "thisChunk", default=1,
                     help = "which chunk to run between 1 and --total-chunks")
     self.add_option("--profile-name",
                     type = "string", dest="profileName", default=None,