[Reproducible-commits] [reprotest] 04/04: Add other environment variable variations, break variations into functions, and add CLI for variations

Ceridwen ceridwen-guest at moszumanska.debian.org
Mon Jun 6 03:31:48 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 d596754616b1192d259b99d6939b81d5227ca003
Author: Ceridwen <ceridwenv at gmail.com>
Date:   Sun Jun 5 23:31:39 2016 -0400

    Add other environment variable variations, break variations into functions, and add CLI for variations
---
 reprotest/__init__.py | 115 +++++++++++++++++++++++++++++++++++++++++---------
 tests/build.py        |   4 ++
 tests/test.py         |   3 ++
 3 files changed, 102 insertions(+), 20 deletions(-)

diff --git a/reprotest/__init__.py b/reprotest/__init__.py
index b3debe5..f1d5e77 100644
--- a/reprotest/__init__.py
+++ b/reprotest/__init__.py
@@ -2,6 +2,7 @@
 # For details: reprotest/debian/copyright
 
 import argparse
+import logging
 import os
 import pathlib
 import shutil
@@ -13,6 +14,33 @@ import tempfile
 # number, architecture for uname (using linux64), umask, HOME, see
 # also: https://tests.reproducible-builds.org/index_variations.html
 
+def cpu(command, env1, env2, tree1, tree2):
+    return command, env1, env2, tree1, tree2
+
+def domain(command, env1, env2, tree1, tree2):
+    return command, env1, env2, tree1, tree2
+
+def captures_environment(command, env1, env2, tree1, tree2):
+    env2['CAPTURE_ENVIRONMENT'] = 'i_capture_the_environment'
+    return command, env1, env2, tree1, tree2
+
+def filesystem(command, env1, env2, tree1, tree2):
+    return command, env1, env2, tree1, tree2
+
+def group(command, env1, env2, tree1, tree2):
+    return command, env1, env2, tree1, tree2
+
+def home(command, env1, env2, tree1, tree2):
+    env1['HOME'] = '/nonexistent/first-build'
+    env2['HOME'] = '/nonexistent/second-build'
+    return command, env1, env2, tree1, tree2
+
+def host(command, env1, env2, tree1, tree2):
+    return command, env1, env2, tree1, tree2
+
+def kernel(command, env1, env2, tree1, tree2):
+    return command, env1, env2, tree1, tree2
+
 # TODO: if this locale doesn't exist on the system, Python's
 # locales.getlocale() will return (None, None) rather than this
 # locale.  I imagine it will also probably cause false positives with
@@ -23,13 +51,46 @@ import tempfile
 # is to figure out what locales are installed (how?) and use another
 # locale if this one isn't installed.
 
-# 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.
+def locales(command, env1, env2, tree1, tree2):
+    # env1['LANG'] = 'C'
+    env2['LANG'] = 'fr_CH.UTF-8'
+    # env1['LANGUAGE'] = 'en_US:en'
+    # env2['LANGUAGE'] = 'fr_CH:fr'
+    env2['LC_ALL'] = 'fr_CH.UTF-8'
+    return command, env1, env2, tree1, tree2
+
+def namespace(command, env1, env2, tree1, tree2):
+    return command, env1, env2, tree1, tree2
 
-ENVIRONMENT_VARIABLES1 = {'TZ': 'GMT+12'}
+def path(command, env1, env2, tree1, tree2):
+    env2['PATH'] = env1['PATH'] + 'i_capture_the_path'
+    return command, env1, env2, tree1, tree2
 
-ENVIRONMENT_VARIABLES2 = {'TZ': 'GMT-14', 'LANG': 'fr_CH.UTF-8', 'LC_ALL': 'fr_CH.UTF-8'}
+def shell(command, env1, env2, tree1, tree2):
+    return command, env1, env2, tree1, tree2
+
+def time(command, env1, env2, tree1, tree2):
+    return command, env1, env2, tree1, tree2
+
+def timezone(command, env1, env2, tree1, tree2):
+    # 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.
+    env1['TZ'] = 'GMT+12'
+    env2['TZ'] = 'GMT-14'
+    return command, env1, env2, tree1, tree2
+
+def umask(command, env1, env2, tree1, tree2):
+    return command, env1, env2, tree1, tree2
+
+def user(command, env1, env2, tree1, tree2):
+    return command, env1, env2, tree1, tree2
+
+VARIATIONS = {'captures_environment': captures_environment, 'cpu':
+              cpu, 'domain': domain, 'filesystem': filesystem, 'group': group,
+              'home': home, 'host': host, 'kernel': kernel, 'locales': locales,
+              'namespace': namespace, 'path': path, 'shell': shell, 'time': time,
+              'timezone': timezone, 'umask': umask, 'user': user}
 
 def build(command, source_root, built_artifact, artifact_store, **kws):
     return_code = subprocess.call(command, cwd=source_root, **kws)
@@ -40,26 +101,26 @@ def build(command, source_root, built_artifact, artifact_store, **kws):
             artifact_store.write(artifact.read())
             artifact_store.flush()
 
-def check(build_command, source_root, artifact_name):
+def check(build_command, source_root, artifact_name, variations=VARIATIONS):
     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, temp + '/tree1', temp + '/tree1/' + artifact_name,
-              open(temp + '/artifact1', 'wb'), env=env)
-        env.update(ENVIRONMENT_VARIABLES2)
-        # print(env)
-        build(build_command, temp + '/tree2', temp + '/tree2/' + artifact_name,
-              open(temp + '/artifact2', 'wb'), env=env)
+        env1 = os.environ.copy()
+        env2 = env1.copy()
+        tree1 = shutil.copytree(str(source_root), temp + '/tree1')
+        tree2 = shutil.copytree(str(source_root), temp + '/tree2')
+        for variation in variations:
+            build_command, env1, env2, tree1, tree2 = VARIATIONS[variation](build_command, env1, env2, tree1, tree2)
+        build(build_command, tree1, temp + '/tree1/' + artifact_name,
+              open(temp + '/artifact1', 'wb'), env=env1)
+        build(build_command, tree2, temp + '/tree2/' + artifact_name,
+              open(temp + '/artifact2', 'wb'), env=env2)
         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(
+        '-v', '--verbose', action='count', default=0, help='Verbose output.')
     arg_parser.add_argument('build_command', help='Build command to execute.')
     arg_parser.add_argument(
         'artifact', help='Build artifact to test for reproducibility.')
@@ -67,14 +128,28 @@ def main():
     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(
+    arg_parser.add_argument(
         '--variations', help='Build variations to test as a comma-separated list'
         '(without spaces).  Default is to test all available variations.')
+    arg_parser.add_argument(
+        '--dont_vary', help='Build variations *not* 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()
+    logging.basicConfig(
+        format='%(message)s', level=30-10*args.verbose, stream=sys.stdout)
+    variations = VARIATIONS
+    if args.dont_vary and args.variations:
+        print("Use only one of --variations or --dont_vary, not both.")
+        sys.exit(2)
+    elif args.dont_vary:
+        variations = variations - args.dont_vary
+    elif args.variations:
+        variations = args.variations
     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)
+          args.artifact,
+          variations)
diff --git a/tests/build.py b/tests/build.py
index bea0105..628a749 100755
--- a/tests/build.py
+++ b/tests/build.py
@@ -17,10 +17,14 @@ if __name__ == '__main__':
     output = [b'']
     if 'irreproducible' in args:
         output.append(os.urandom(1024))
+    if 'home' in args:
+        output.append(os.path.expanduser('~').encode('ascii'))
     if 'locales' in args:
         # print(locale.getlocale())
         # print([l.encode('ascii') for l in locale.getlocale()])
         output.extend(l.encode('ascii') for l in locale.getlocale())
+    if 'path' in args:
+        output.extend(p.encode('ascii') for p in os.get_exec_path())
     if 'timezone' in args:
         output.append(time.ctime().encode('ascii'))
     with open('artifact', 'wb') as artifact:
diff --git a/tests/test.py b/tests/test.py
index f07b21e..f5f63a2 100644
--- a/tests/test.py
+++ b/tests/test.py
@@ -15,5 +15,8 @@ if __name__ == '__main__':
     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', 'home'], 1)
     test_return_code(['python', 'build.py', 'locales'], 1)
+    test_return_code(['python', 'build.py', 'path'], 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