[Reproducible-commits] [reprotest] 02/04: Copy the source tree to new temporary directories before building.

Ceridwen ceridwen-guest at moszumanska.debian.org
Mon Jun 6 03:31:47 UTC 2016


This is an automated email from the git hooks/post-receive script.

ceridwen-guest pushed a commit to branch master
in repository reprotest.

commit 3f7a0ece48ff3f2e2b33c653857842d3676decbc
Author: Ceridwen <ceridwenv at gmail.com>
Date:   Sun Jun 5 11:45:26 2016 -0400

    Copy the source tree to new temporary directories before building.
    
    This ensures that each build starts with a clean version of the
    original source tree and allows use of disorderfs.
---
 reprotest/__init__.py | 56 ++++++++++++++++++++++++++++++++++-----------------
 tests/build.py        |  2 +-
 tests/test.py         | 17 ++++++----------
 3 files changed, 44 insertions(+), 31 deletions(-)

diff --git a/reprotest/__init__.py b/reprotest/__init__.py
index 4aa9e2c..b3debe5 100644
--- a/reprotest/__init__.py
+++ b/reprotest/__init__.py
@@ -3,12 +3,15 @@
 
 import argparse
 import os
+import pathlib
+import shutil
 import subprocess
 import sys
 import tempfile
 
-# TODO: what happens when these environment variables are set on
-# Windows?  Hopefully nothing?
+# time zone, locales, disorderfs, host name, user/group, shell, CPU
+# number, architecture for uname (using linux64), umask, HOME, see
+# also: https://tests.reproducible-builds.org/index_variations.html
 
 # TODO: if this locale doesn't exist on the system, Python's
 # locales.getlocale() will return (None, None) rather than this
@@ -18,45 +21,60 @@ import tempfile
 # for this locale to be encoded into the dependencies so installing it
 # installs the right locale.  A weaker but still reasonable solution
 # is to figure out what locales are installed (how?) and use another
-# locale if this one isn't installed.  
+# locale if this one isn't installed.
 
-# TODO: is this time zone location actually system-independent?
+# These time zones are theoretically in the POSIX time zone format
+# (http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08),
+# so they should be cross-platform compatible.
 
-ENVIRONMENT_VARIABLES1 = {'TZ': '/usr/share/zoneinfo/Etc/GMT+12'}
+ENVIRONMENT_VARIABLES1 = {'TZ': 'GMT+12'}
 
-ENVIRONMENT_VARIABLES2 = {'TZ': '/usr/share/zoneinfo/Etc/GMT-14', 'LANG': 'fr_CH.UTF-8', 'LC_ALL': 'fr_CH.UTF-8'}
+ENVIRONMENT_VARIABLES2 = {'TZ': 'GMT-14', 'LANG': 'fr_CH.UTF-8', 'LC_ALL': 'fr_CH.UTF-8'}
 
-def build(command, artifact_name, temp, **kws):
-    return_code = subprocess.call(command, **kws)
+def build(command, source_root, built_artifact, artifact_store, **kws):
+    return_code = subprocess.call(command, cwd=source_root, **kws)
     if return_code != 0:
         sys.exit(2)
     else:
-        with open(artifact_name, 'rb') as artifact:
-            temp.write(artifact.read())
-            temp.flush()
+        with open(built_artifact, 'rb') as artifact:
+            artifact_store.write(artifact.read())
+            artifact_store.flush()
 
-def check(build_command, artifact_name):
+def check(build_command, source_root, artifact_name):
     with tempfile.TemporaryDirectory() as temp:
+        shutil.copytree(str(source_root), temp + '/tree1')
+        shutil.copytree(str(source_root), temp + '/tree2')
         env = os.environ.copy()
         # print(env)
         env.update(ENVIRONMENT_VARIABLES1)
         # print(env)
-        build(build_command, artifact_name, open(temp + '/b1', 'wb'),
-              env=env)
+        build(build_command, temp + '/tree1', temp + '/tree1/' + artifact_name,
+              open(temp + '/artifact1', 'wb'), env=env)
         env.update(ENVIRONMENT_VARIABLES2)
         # print(env)
-        build(build_command, artifact_name, open(temp + '/b2', 'wb'),
-              env=env)
-        sys.exit(subprocess.call(['diffoscope', temp + '/b1', temp + '/b2']))
+        build(build_command, temp + '/tree2', temp + '/tree2/' + artifact_name,
+              open(temp + '/artifact2', 'wb'), env=env)
+        sys.exit(subprocess.call(['diffoscope', temp + '/artifact1', temp + '/artifact2']))
 
 def main():
     arg_parser = argparse.ArgumentParser(
         description='Build packages and check them for reproducibility.',
         formatter_class=argparse.RawDescriptionHelpFormatter)
     arg_parser.add_argument('build_command', help='Build command to execute.')
-    arg_parse.add_argument(
+    arg_parser.add_argument(
         'artifact', help='Build artifact to test for reproducibility.')
+    # Reprotest will copy this tree and then run the build command.
+    arg_parser.add_argument('--source_root', type=pathlib.Path,
+                           help='Root of the source tree, if not the'
+                           'current working directory.')
+    arg_parser.add_arguments(
+        '--variations', help='Build variations to test as a comma-separated list'
+        '(without spaces).  Default is to test all available variations.')
     # Argparse exits with status code 2 if something goes wrong, which
     # is already the right status exit code for reprotest.
     args = arg_parser.parse_args()
-    check(args.build_command.split(), args.artifact)
+    check(args.build_command.split(),
+          # If a source root isn't provided, assume it's the current
+          # working directory.
+          args.source_root if args.source_root else pathlib.Path.cwd(),
+          args.artifact)
diff --git a/tests/build.py b/tests/build.py
old mode 100644
new mode 100755
index 513da97..bea0105
--- a/tests/build.py
+++ b/tests/build.py
@@ -23,5 +23,5 @@ if __name__ == '__main__':
         output.extend(l.encode('ascii') for l in locale.getlocale())
     if 'timezone' in args:
         output.append(time.ctime().encode('ascii'))
-    with open('tests/artifact', 'wb') as artifact:
+    with open('artifact', 'wb') as artifact:
         artifact.write(b''.join(output))
diff --git a/tests/test.py b/tests/test.py
index c254c86..f07b21e 100644
--- a/tests/test.py
+++ b/tests/test.py
@@ -7,18 +7,13 @@ import reprotest
 
 def test_return_code(command, code):
     try:
-        reprotest.check(command, 'tests/artifact')
+        reprotest.check(command, 'tests/', 'artifact')
     except SystemExit as system_exit:
         assert(system_exit.args[0] == code)
 
 if __name__ == '__main__':
-    try:
-        test_return_code(['python', 'tests/build.py'], 0)
-        test_return_code(['python', 'tests/fails.py'], 2)
-        test_return_code(['python', 'tests/build.py', 'irreproducible'], 1)
-        test_return_code(['python', 'tests/build.py', 'locales'], 1)
-        test_return_code(['python', 'tests/build.py', 'timezone'], 1)
-    finally:
-        # Clean up random binary file created as part of the test.
-        if os.path.isfile('tests/artifact'):
-            os.remove('tests/artifact')
+    test_return_code(['python', 'build.py'], 0)
+    test_return_code(['python', 'fails.py'], 2)
+    test_return_code(['python', 'build.py', 'irreproducible'], 1)
+    test_return_code(['python', 'build.py', 'locales'], 1)
+    test_return_code(['python', 'build.py', 'timezone'], 1)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/reprotest.git



More information about the Reproducible-commits mailing list