[reprotest] 01/01: build: add num_cpu variation
Ximin Luo
infinity0 at debian.org
Fri Nov 24 19:47:49 UTC 2017
This is an automated email from the git hooks/post-receive script.
infinity0 pushed a commit to branch master
in repository reprotest.
commit d5dd4dfe88a467bb65e9cbe6249a9d383eed9b1c
Author: Ximin Luo <infinity0 at debian.org>
Date: Fri Nov 24 20:40:49 2017 +0100
build: add num_cpu variation
---
README.rst | 8 ++++++++
debian/changelog | 2 +-
reprotest/__init__.py | 4 +++-
reprotest/build.py | 25 ++++++++++++++++++++++---
tests/mock_build.py | 2 ++
5 files changed, 36 insertions(+), 5 deletions(-)
diff --git a/README.rst b/README.rst
index 9e712e0..a9f571c 100644
--- a/README.rst
+++ b/README.rst
@@ -284,6 +284,14 @@ We will hopefully lift these assumptions for certain virtual_server contexts,
in future. That would likely allow for smoother operation in those contexts.
The assumptions will remain for the "null" (default) virtual_server however.
+Number of CPUs
+--------------
+
+The control build uses only 1 CPU in order to try to reduce nondeterminism that
+might exist due to multithreading or multiprocessing. If you are sure your
+build is not affected by this (and good builds ought not to be), you can give
+--min-cpus=99999 to use all available cores for both builds.
+
Domain or host
--------------
diff --git a/debian/changelog b/debian/changelog
index af0b9b1..962139e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,7 +1,7 @@
reprotest (0.7.4) UNRELEASED; urgency=medium
* Hopefully fix the autopkgtest tests.
- * Add aslr and domain_host variations.
+ * Add aslr, domain_host, and num_cpu variations.
* Add a --print-sudoers feature.
* Properly drop privs when running the build. (Closes: #877813)
diff --git a/reprotest/__init__.py b/reprotest/__init__.py
index 4494529..3a165ea 100644
--- a/reprotest/__init__.py
+++ b/reprotest/__init__.py
@@ -581,6 +581,8 @@ def cli_parser():
'whitelist and blacklist. You probably want to set --vary=-all as well '
'when setting this flag; see the man page for details. Conflicts with '
'--extra-build and --auto-build.')
+ group1_0.add_argument('--min-cpus', default=1, type=int, metavar='NUM',
+ help='Minimum CPUs to use when fixing num_cpus. Default: %(default)s')
# TODO: remove after reprotest 0.8
group1.add_argument('--dont-vary', default=[], action='append', help=argparse.SUPPRESS)
@@ -767,7 +769,7 @@ def run(argv, dry_run=None):
for extra_build in parsed_args.extra_build:
specs.append(spec.extend(extra_build))
check_func = check
- build_variations = Variations.of(*specs, verbosity=verbosity)
+ build_variations = Variations.of(*specs, verbosity=verbosity, min_cpus=parsed_args.min_cpus)
# Warn about missing programs
if virtual_server_args[0] == "null" and not dry_run:
diff --git a/reprotest/build.py b/reprotest/build.py
index 4c9eba8..70554dd 100644
--- a/reprotest/build.py
+++ b/reprotest/build.py
@@ -300,6 +300,24 @@ def aslr(ctx, build, vary):
return build
return build.append_setup_exec_raw('SETARCH_OPTS="$SETARCH_OPTS -R"')
+def num_cpus(ctx, build, vary):
+ _ = build
+ _ = _.append_setup_exec_raw('CPU_MAX=$(nproc --all)')
+ _ = _.append_setup_exec_raw('CPU_MIN=$({ echo $CPU_MAX; echo %s; } | sort -n | head -n1)' % ctx.min_cpus)
+ if ctx.min_cpus <= 0:
+ raise ValueError("--min-cpus must be a positive integer: " % ctx.min_cpus)
+ if not vary:
+ if ctx.min_cpus == 1:
+ logger.warn("The control build runs on 1 CPU by default, give --min-cpus to increase this.")
+ _ = _.append_setup_exec_raw('CPU_NUM=$CPU_MIN')
+ else:
+ # random number between min_cpus and $(nproc --all)
+ _ = _.append_setup_exec_raw('CPU_NUM=$(shuf -i$CPU_MIN-$CPU_MAX -n1)')
+
+ # select CPU_NUM random cpus from the range 0..$((CPU_MAX-1))
+ cpu_list = "$(echo $(shuf -i0-$((CPU_MAX - 1)) -n$CPU_NUM) | tr ' ' ,)"
+ return _.prepend_to_build_command_raw('taskset', '-a', '-c', cpu_list)
+
# 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
@@ -452,6 +470,7 @@ VARIATIONS = collections.OrderedDict([
('aslr', aslr), # needs to run after kernel which runs "setarch"
# but also as close to the build command as possible, (i.e. earlier in this list)
# otherwise other variations below can affect the address layout
+ ('num_cpus', num_cpus),
('user_group', user_group),
# ('cpu', cpu),
('fileordering', fileordering),
@@ -560,10 +579,10 @@ class VariationSpec(mdiffconf.ImmutableNamespace):
})
-class Variations(collections.namedtuple('_Variations', 'spec verbosity')):
+class Variations(collections.namedtuple('_Variations', 'spec verbosity min_cpus')):
@classmethod
- def of(cls, *specs, zero=VariationSpec.empty(), verbosity=0):
- return [cls(spec, verbosity) for spec in [zero] + list(specs)]
+ def of(cls, *specs, zero=VariationSpec.empty(), verbosity=0, min_cpus=1):
+ return [cls(spec, verbosity, min_cpus) for spec in [zero] + list(specs)]
@property
def replace(self):
diff --git a/tests/mock_build.py b/tests/mock_build.py
index 5b2ea74..536ac5f 100755
--- a/tests/mock_build.py
+++ b/tests/mock_build.py
@@ -49,6 +49,8 @@ if __name__ == '__main__':
output.append(os.path.expanduser('~'))
if 'kernel' in captures:
output.append(subprocess.check_output(['uname', '-r']).decode("utf-8"))
+ if 'num_cpus' in captures:
+ output.append(subprocess.check_output(['nproc']).decode("utf-8"))
if 'locales' in captures:
output.extend(l or '(None)' for l in locale.getlocale())
output.append(subprocess.check_output(['locale']).decode("utf-8"))
--
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