bug 421611 - Need to be able to run tests on arbitrary build. add a package target for reftest. r=bsmedberg
authorTed Mielczarek <ted.mielczarek@gmail.com>
Wed, 11 Mar 2009 11:56:58 -0400
changeset 26052 5ff0bc2194db798390f015bee56b6b8df3f295ec
parent 26051 dbd5b5c6710c796ddffa8271022c1ac09039aea7
child 26053 39d814ba2422d104d99c05bca65b4998468bf990
push idunknown
push userunknown
push dateunknown
reviewersbsmedberg
bugs421611
milestone1.9.2a1pre
bug 421611 - Need to be able to run tests on arbitrary build. add a package target for reftest. r=bsmedberg
layout/tools/reftest/Makefile.in
layout/tools/reftest/print-manifest-dirs.py
layout/tools/reftest/reftest.js
testing/testsuite-targets.mk
--- a/layout/tools/reftest/Makefile.in
+++ b/layout/tools/reftest/Makefile.in
@@ -86,8 +86,20 @@ GARBAGE += automation.py
 
 # copy harness and the reftest extension bits to $(_DEST_DIR)
 copy-harness: $(_HARNESS_FILES)
 	$(INSTALL) $(_HARNESS_FILES) $(_DEST_DIR)
 	(cd $(DIST)/xpi-stage && tar $(TAR_CREATE_FLAGS) - reftest) | (cd $(_DEST_DIR) && tar -xf -)
 	$(INSTALL) $(DIST)/bin/components/httpd.js $(_DEST_DIR)/reftest/components
 	$(INSTALL) $(DIST)/bin/components/test_necko.xpt $(_DEST_DIR)/reftest/components
 
+PKG_STAGE = $(DIST)/test-package-stage
+
+# stage harness and tests for packaging
+stage-package:
+	$(NSINSTALL) -D $(PKG_STAGE)/reftest && $(NSINSTALL) -D $(PKG_STAGE)/reftest/tests
+	@(cd $(DEPTH)/_tests/reftest/ && tar $(TAR_CREATE_FLAGS) - *) | (cd $(PKG_STAGE)/reftest && tar -xf -)
+	$(PYTHON) $(topsrcdir)/layout/tools/reftest/print-manifest-dirs.py \
+          $(topsrcdir) \
+          $(topsrcdir)/layout/reftests/reftest.list \
+          $(topsrcdir)/testing/crashtest/crashtests.list \
+          | (cd $(topsrcdir) && xargs tar $(TAR_CREATE_FLAGS) -) \
+          | (cd $(PKG_STAGE)/reftest/tests && tar -xf -)
new file mode 100644
--- /dev/null
+++ b/layout/tools/reftest/print-manifest-dirs.py
@@ -0,0 +1,103 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2009
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Ted Mielczarek <ted.mielczarek@gmail.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# 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 *****
+
+import sys, os.path, re
+
+commentRE = re.compile(r"\s+#")
+conditionsRE = re.compile(r"^(fails|random|skip|asserts)")
+httpRE = re.compile(r"HTTP\((\.\.(\/\.\.)*)\)")
+
+def parseManifest(manifest, dirs):
+  """Parse the reftest manifest |manifest|, adding all directories containing
+  tests (and the dirs containing the manifests themselves) to the set |dirs|."""
+  manifestdir = os.path.dirname(os.path.abspath(manifest))
+  dirs.add(manifestdir)
+  f = file(manifest)
+  for line in f:
+    if line[0] == '#':
+      continue # entire line was a comment
+    m = commentRE.search(line)
+    if m:
+      line = line[:m.start()]
+    line = line.strip()
+    if not line:
+      continue
+    items = line.split()
+    while conditionsRE.match(items[0]):
+      del items[0]
+    if items[0] == "HTTP":
+      del items[0]
+    m = httpRE.match(items[0])
+    if m:
+      # need to package the dir referenced here
+      d = os.path.normpath(os.path.join(manifestdir, m.group(1)))
+      dirs.add(d)
+      del items[0]
+
+    if items[0] == "include":
+      parseManifest(os.path.join(manifestdir, items[1]), dirs)
+      continue
+    elif items[0] == "load":
+      testURLs = [items[1]]
+    elif items[0] == "==" or items[0] == "!=":
+      testURLs = items[1:3]
+    for u in testURLs:
+      if u.startswith("about:") or u.startswith("data:"):
+        # can't very well package about: or data: URIs
+        continue
+      d = os.path.dirname(os.path.normpath(os.path.join(manifestdir, u)))
+      dirs.add(d)
+  f.close()
+
+def printTestDirs(topsrcdir, topmanifests):
+  """Parse |topmanifests| and print a list of directories containing the tests
+  within (and the manifests including those tests), relative to |topsrcdir|."""
+  dirs = set()
+  for manifest in topmanifests:
+    parseManifest(manifest, dirs)
+  for dir in sorted(dirs):
+    d = dir[len(topsrcdir):].replace('\\','/')
+    if d[0] == '/':
+      d = d[1:]
+    print d
+
+if __name__ == '__main__':
+  if len(sys.argv) < 3:
+    print >>sys.stderr, "Usage: %s topsrcdir reftest.list [reftest.list]*" % sys.argv[0]
+    sys.exit(1)
+  printTestDirs(sys.argv[1], sys.argv[2:])
--- a/layout/tools/reftest/reftest.js
+++ b/layout/tools/reftest/reftest.js
@@ -206,16 +206,18 @@ function ReadTopManifest(aFileURL)
 {
     gURLs = new Array();
     var url = gIOService.newURI(aFileURL, null, null);
     if (!url || !url.schemeIs("file"))
         throw "Expected a file URL for the manifest.";
     ReadManifest(url);
 }
 
+// Note: If you materially change the reftest manifest parsing,
+// please keep the parser in print-manifest-dirs.py in sync.
 function ReadManifest(aURL)
 {
     var listURL = aURL.QueryInterface(CI.nsIFileURL);
 
     var secMan = CC[NS_SCRIPTSECURITYMANAGER_CONTRACTID]
                      .getService(CI.nsIScriptSecurityManager);
 
     var fis = CC[NS_LOCALFILEINPUTSTREAM_CONTRACTID].
--- a/testing/testsuite-targets.mk
+++ b/testing/testsuite-targets.mk
@@ -80,19 +80,22 @@ crashtest:
 	$(call RUN_REFTEST,$(topsrcdir)/testing/crashtest/crashtests.list)
 	$(CHECK_TEST_ERROR)
 
 # Package up the tests and test harnesses
 include $(topsrcdir)/toolkit/mozapps/installer/package-name.mk
 
 PKG_STAGE = $(DIST)/test-package-stage
 
-package-tests: stage-mochitest
+package-tests: stage-mochitest stage-reftest
 	@(cd $(PKG_STAGE) && tar $(TAR_CREATE_FLAGS) - *) | bzip2 -f > $(DIST)/$(PKG_PATH)$(TEST_PACKAGE)
 
 make-stage-dir:
 	rm -rf $(PKG_STAGE) && $(NSINSTALL) -D $(PKG_STAGE) && $(NSINSTALL) -D $(PKG_STAGE)/bin && $(NSINSTALL) -D $(PKG_STAGE)/bin/components && $(NSINSTALL) -D $(PKG_STAGE)/certs
 
 stage-mochitest: make-stage-dir
 	$(MAKE) -C $(DEPTH)/testing/mochitest stage-package
 
+stage-reftest: make-stage-dir
+	$(MAKE) -C $(DEPTH)/layout/tools/reftest stage-package
+
 .PHONY: mochitest mochitest-plain mochitest-chrome mochitest-a11y \
   package-tests make-stage-dir stage-mochitest