Bug 1208320 - Produce mozharness test archive via mozpack; r?glandium draft
authorGregory Szorc <gps@mozilla.com>
Wed, 30 Sep 2015 11:34:33 -0700
changeset 297631 39134a5f52b8cdd204459c58024f9881106513b1
parent 297630 733b4e3cbf00eee6b90913d57e30a97c6b464abe
child 297632 ca64fa293f9096370e8b77df03978bc685d2f1ab
push id5977
push usergszorc@mozilla.com
push dateWed, 30 Sep 2015 18:40:40 +0000
reviewersglandium
bugs1208320
milestone44.0a1
Bug 1208320 - Produce mozharness test archive via mozpack; r?glandium Test archive generation currently copies a bunch of files into a staging area then runs `zip` to produce ZIP files. There are 2 concerns with this approach: 1) We incur a lot of extra I/O to copy files so everything is rooted in a single tree so the `zip` invocation and paths are simple. 2) ZIP files inherit properties from the local filesystem (including mtime), making ZIP files non-deterministic. This commit introduces a new mozbuild action for producing test archives. It does so using the mozpack file finder and JAR writer, which are used throughout the build to deterministically produce ZIP/JAR files from files in multiple source directories. We implement support for producing the mozharness archive. This archive does not involve files that are staged, so no I/O is saved. In fact, the switch from `zip` to Python likely makes this slightly slower. However, we do have deterministic archives now. Additional archives will be ported over in subsequent commits.
python/mozbuild/mozbuild/action/test_archive.py
testing/testsuite-targets.mk
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/action/test_archive.py
@@ -0,0 +1,66 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# This action is used to produce test archives.
+#
+# Ideally, the data in this file should be defined in moz.build files.
+# It is defined inline because this was easiest to make test archive
+# generation faster.
+
+from __future__ import absolute_import, print_function, unicode_literals
+
+import argparse
+import os
+import sys
+
+from mozpack.files import FileFinder
+from mozpack.mozjar import JarWriter
+
+import buildconfig
+
+
+ARCHIVE_FILES = {
+    'mozharness': [
+        {
+            'source': buildconfig.topsrcdir,
+            'base': 'testing',
+            'pattern': 'mozharness/**',
+        },
+    ],
+}
+
+
+def find_files(archive):
+    for entry in ARCHIVE_FILES[archive]:
+        source = entry['source']
+        base = entry['base']
+        pattern = entry['pattern']
+
+        finder = FileFinder(os.path.join(source, base),
+                            find_executables=False,
+                            find_dotfiles=True)
+
+        for f in finder.find(pattern):
+            yield f
+
+
+def main(argv):
+    parser = argparse.ArgumentParser(
+        description='Produce test archives')
+    parser.add_argument('archive', help='Which archive to generate')
+    parser.add_argument('outputfile', help='File to write output to')
+
+    args = parser.parse_args(argv)
+
+    if not args.outputfile.endswith('.zip'):
+        raise Exception('expected zip output file')
+
+    with open(args.outputfile, 'wb') as fh:
+        with JarWriter(fileobj=fh, optimize=False) as writer:
+            for p, f in find_files(args.archive):
+                writer.add(p.encode('utf-8'), f.read(), mode=f.mode)
+
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv[1:]))
--- a/testing/testsuite-targets.mk
+++ b/testing/testsuite-targets.mk
@@ -423,19 +423,18 @@ test-packages-manifest:
       --dest-file $(MOZ_TEST_PACKAGES_FILE) \
       $(call PKG_ARG,common) \
       $(foreach pkg,$(TEST_PKGS),$(call PKG_ARG,$(pkg)))
 
 package-tests-prepare-dest:
 	@rm -f '$(DIST)/$(PKG_PATH)$(TEST_PACKAGE)'
 	$(NSINSTALL) -D $(DIST)/$(PKG_PATH)
 
-package-tests-mozharness: stage-all package-tests-prepare-dest
-	cd $(topsrcdir)/testing/ && \
-	  zip -rq9D $(abspath $(DIST))/$(PKG_PATH)mozharness.zip mozharness
+package-tests-mozharness: package-tests-prepare-dest
+	$(call py_action,test_archive,mozharness $(abspath $(DIST))/$(PKG_PATH)/mozharness.zip)
 package-tests: package-tests-mozharness
 
 package-tests-common: stage-all package-tests-prepare-dest
 	cd $(abspath $(PKG_STAGE)) && \
 	  zip -rq9D '$(abspath $(DIST))/$(PKG_PATH)$(TEST_PACKAGE)' \
 	  * -x \*/.mkdir.done \*.pyc $(foreach name,$(TEST_PKGS),$(name)\*)
 package-tests: package-tests-common