bug 1463425 - Fix flake8/pep8 issue by hand in config/ r=gps
authorSylvestre Ledru <sledru@mozilla.com>
Tue, 22 May 2018 06:22:46 -0700
changeset 419630 da3c81f986fa63b42a2874b1791eddcdbfbe8424
parent 419629 fba6f974041a3d3c22ef95c44f6e4262e8e5c52f
child 419631 f6f59b7657ac5abdeb8e733d367bc3f8d3169036
push id103570
push userebalazs@mozilla.com
push dateThu, 24 May 2018 09:44:40 +0000
treeherdermozilla-inbound@10aff8fde3f2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgps
bugs1463425
milestone62.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 1463425 - Fix flake8/pep8 issue by hand in config/ r=gps MozReview-Commit-ID: 6B60uh4n2nY
config/MozZipFile.py
config/check_js_msg_encoding.py
config/check_js_opcode.py
config/check_source_count.py
config/check_spidermonkey_style.py
config/check_vanilla_allocations.py
config/createprecomplete.py
config/external/ffi/preprocess_libffi_asm.py
config/external/ffi/subst_header.py
config/find_OOM_errors.py
config/make-stl-wrappers.py
config/make-system-wrappers.py
config/nsinstall.py
config/printconfigsetting.py
config/rebuild_check.py
config/tests/unit-mozunit.py
config/tests/unit-printprereleasesuffix.py
config/tests/unitMozZipFile.py
--- a/config/MozZipFile.py
+++ b/config/MozZipFile.py
@@ -54,17 +54,17 @@ class ZipFile(zipfile.ZipFile):
         # Now to the point why we overwrote this in the first place,
         # remember the entry numbers if we already had this entry.
         # Optimizations:
         # If the entry to overwrite is the last one, just reuse that.
         # If we store uncompressed and the new content has the same size
         # as the old, reuse the existing entry.
 
         doSeek = False  # store if we need to seek to the eof after overwriting
-        if self.NameToInfo.has_key(zinfo.filename):
+        if zinfo.filename in self.NameToInfo:
             # Find the last ZipInfo with our name.
             # Last, because that's catching multiple overwrites
             i = len(self.filelist)
             while i > 0:
                 i -= 1
                 if self.filelist[i].filename == zinfo.filename:
                     break
             zi = self.filelist[i]
--- a/config/check_js_msg_encoding.py
+++ b/config/check_js_msg_encoding.py
@@ -1,18 +1,18 @@
 # vim: set ts=8 sts=4 et sw=4 tw=99:
 # 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 script checks encoding of the files that define JSErrorFormatStrings.
 #
 # JSErrorFormatString.format member should be in ASCII encoding.
-#----------------------------------------------------------------------------
+# ----------------------------------------------------------------------------
 
 from __future__ import print_function
 
 import os
 import sys
 
 from mozversioncontrol import get_repository_from_env
 
@@ -36,17 +36,17 @@ def log_fail(filename, text):
                                                        text))
 
 
 def check_single_file(filename):
     with open(filename, 'rb') as f:
         data = f.read()
         try:
             data.decode(expected_encoding)
-        except:
+        except Exception:
             log_fail(filename, 'not in {} encoding'.format(expected_encoding))
 
     log_pass(filename, 'ok')
     return True
 
 
 def check_files():
     result = True
--- a/config/check_js_opcode.py
+++ b/config/check_js_opcode.py
@@ -1,16 +1,16 @@
 # vim: set ts=8 sts=4 et sw=4 tw=99:
 # 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 script checks bytecode documentation in js/src/vm/Opcodes.h
-#----------------------------------------------------------------------------
+# ----------------------------------------------------------------------------
 
 from __future__ import print_function
 
 import os
 import sys
 
 scriptname = os.path.basename(__file__)
 topsrcdir = os.path.dirname(os.path.dirname(__file__))
--- a/config/check_source_count.py
+++ b/config/check_source_count.py
@@ -6,17 +6,16 @@
 
 # Usage: check_source_count.py SEARCH_TERM COUNT ERROR_LOCATION REPLACEMENT [FILES...]
 #   Checks that FILES contains exactly COUNT matches of SEARCH_TERM. If it does
 #   not, an error message is printed, quoting ERROR_LOCATION, which should
 #   probably be the filename and line number of the erroneous call to
 #   check_source_count.py.
 from __future__ import print_function
 import sys
-import os
 import re
 
 search_string = sys.argv[1]
 expected_count = int(sys.argv[2])
 error_location = sys.argv[3]
 replacement = sys.argv[4]
 files = sys.argv[5:]
 
--- a/config/check_spidermonkey_style.py
+++ b/config/check_spidermonkey_style.py
@@ -1,14 +1,14 @@
 # vim: set ts=8 sts=4 et sw=4 tw=99:
 # 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 script checks various aspects of SpiderMonkey code style.  The current checks are as
 # follows.
 #
 # We check the following things in headers.
 #
 # - No cyclic dependencies.
 #
 # - No normal header should #include a inlines.h/-inl.h file.
@@ -28,17 +28,17 @@
 #   - Each one should be in the correct section.
 #   - Alphabetical order should be used within sections.
 #   - Sections should be in the right order.
 #   Note that the presence of #if/#endif blocks complicates things, to the
 #   point that it's not always clear where a conditionally-compiled #include
 #   statement should go, even to a human.  Therefore, we check the #include
 #   statements within each #if/#endif block (including nested ones) in
 #   isolation, but don't try to do any order checking between such blocks.
-#----------------------------------------------------------------------------
+# ----------------------------------------------------------------------------
 
 from __future__ import print_function
 
 import difflib
 import os
 import re
 import sys
 
@@ -335,17 +335,17 @@ def check_style(enable_fixup):
         print(diffline, end='')
 
     return ok
 
 
 def module_name(name):
     '''Strip the trailing .cpp, .h, inlines.h or -inl.h from a filename.'''
 
-    return name.replace('inlines.h', '').replace('-inl.h', '').replace('.h', '').replace('.cpp', '')
+    return name.replace('inlines.h', '').replace('-inl.h', '').replace('.h', '').replace('.cpp', '')  # NOQA: E501
 
 
 def is_module_header(enclosing_inclname, header_inclname):
     '''Determine if an included name is the "module header", i.e. should be
     first in the file.'''
 
     module = module_name(enclosing_inclname)
 
@@ -768,18 +768,18 @@ def main():
         # Sort #include directives in-place.  Fixup mode doesn't solve
         # all possible silliness that the script checks for; it's just a
         # hack for the common case where renaming a header causes style
         # errors.
         fixup = True
     elif sys.argv[1:] == []:
         fixup = False
     else:
-        print("TEST-UNEXPECTED-FAIL | check_spidermonkey_style.py | unexpected command line options: " +
-              repr(sys.argv[1:]))
+        print("TEST-UNEXPECTED-FAIL | check_spidermonkey_style.py | unexpected command "
+              "line options: " + repr(sys.argv[1:]))
         sys.exit(1)
 
     ok = check_style(fixup)
 
     if ok:
         print('TEST-PASS | check_spidermonkey_style.py | ok')
     else:
         print('TEST-UNEXPECTED-FAIL | check_spidermonkey_style.py | ' +
--- a/config/check_vanilla_allocations.py
+++ b/config/check_vanilla_allocations.py
@@ -1,14 +1,14 @@
 # vim: set ts=8 sts=4 et sw=4 tw=79:
 # 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/.
 
-#----------------------------------------------------------------------------
+# ----------------------------------------------------------------------------
 # All heap allocations in SpiderMonkey must go through js_malloc, js_calloc,
 # js_realloc, and js_free.  This is so that any embedder who uses a custom
 # allocator (by defining JS_USE_CUSTOM_ALLOCATOR) will see all heap allocation
 # go through that custom allocator.
 #
 # Therefore, the presence of any calls to "vanilla" allocation/free functions
 # (e.g. malloc(), free()) is a bug.
 #
@@ -29,17 +29,17 @@
 # are present.  If given the --aggressive flag, it will also check for
 # malloc/calloc/realloc/free.
 #
 # Note:  We don't check for |operator delete| and |operator delete[]|.  These
 # can be present somehow due to virtual destructors, but this is not too
 # because vanilla delete/delete[] calls don't make sense without corresponding
 # vanilla new/new[] calls, and any explicit calls will be caught by Valgrind's
 # mismatched alloc/free checking.
-#----------------------------------------------------------------------------
+# ----------------------------------------------------------------------------
 
 from __future__ import print_function
 
 import argparse
 import re
 import subprocess
 import sys
 import buildconfig
--- a/config/createprecomplete.py
+++ b/config/createprecomplete.py
@@ -1,17 +1,16 @@
 # Any copyright is dedicated to the Public Domain.
 # http://creativecommons.org/publicdomain/zero/1.0/
 
 # Creates the precomplete file containing the remove and rmdir application
 # update instructions which is used to remove files and directories that are no
 # longer present in a complete update. The current working directory is used for
 # the location to enumerate and to create the precomplete file.
 
-import sys
 import os
 
 
 def get_build_entries(root_path):
     """ Iterates through the root_path, creating a list for each file and
         directory. Excludes any file paths ending with channel-prefs.js.
     """
     rel_file_path_set = set()
--- a/config/external/ffi/preprocess_libffi_asm.py
+++ b/config/external/ffi/preprocess_libffi_asm.py
@@ -6,16 +6,17 @@
 
 import buildconfig
 import mozpack.path as mozpath
 import os
 import re
 import shlex
 import subprocess
 
+
 def main(output, input_asm, defines, includes):
     defines = shlex.split(defines)
     includes = shlex.split(includes)
     # CPP uses -E which generates #line directives. -EP suppresses them.
     cpp = buildconfig.substs['CPP'] + ['-EP']
     input_asm = mozpath.relpath(input_asm, os.getcwd())
     args = cpp + defines + includes + [input_asm]
     print(' '.join(args))
--- a/config/external/ffi/subst_header.py
+++ b/config/external/ffi/subst_header.py
@@ -3,23 +3,25 @@
 # This Souce Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distibuted with this
 # file, You can obtain one at http://mozilla.og/MPL/2.0/.
 
 import sys
 import buildconfig
 from mozbuild.preprocessor import Preprocessor
 
+
 def main(output, input_file):
     pp = Preprocessor()
     pp.context.update({
         'FFI_EXEC_TRAMPOLINE_TABLE': '0',
         'HAVE_LONG_DOUBLE': '0',
         'TARGET': buildconfig.substs['FFI_TARGET'],
         'VERSION': '',
     })
     pp.do_filter('substitution')
     pp.setMarker(None)
     pp.out = output
     pp.do_include(input_file)
 
+
 if __name__ == '__main__':
     main(*sys.agv[1:])
--- a/config/find_OOM_errors.py
+++ b/config/find_OOM_errors.py
@@ -11,23 +11,21 @@ allocation during OOM (out-of-memory) co
 """
 
 help = """Check for regressions only. This runs a set of files with a known
 number of OOM errors (specified by REGRESSION_COUNT), and exits with a non-zero
 result if more or less errors are found. See js/src/Makefile.in for invocation.
 """
 
 
-import hashlib
 import re
 import shlex
 import subprocess
 import sys
 import threading
-import time
 
 from optparse import OptionParser
 
 #####################################################################
 # Utility functions
 #####################################################################
 
 
@@ -64,17 +62,17 @@ def run(args, stdin=None):
         stderr_worker = ThreadWorker(proc.stderr)
         stdout_worker.start()
         stderr_worker.start()
 
         proc.wait()
         stdout_worker.join()
         stderr_worker.join()
 
-    except KeyboardInterrupt as e:
+    except KeyboardInterrupt:
         sys.exit(-1)
 
     stdout, stderr = stdout_worker.all, stderr_worker.all
     result = (stdout, stderr, proc.returncode)
     return result
 
 
 def get_js_files():
@@ -130,17 +128,17 @@ def clean_voutput(err):
     err = re.sub(r"^\s+by 0x[0-9A-Fa-f]+: ", "by: ", err, flags=re.MULTILINE)
     err = re.sub(r"^\s+at 0x[0-9A-Fa-f]+: ", "at: ", err, flags=re.MULTILINE)
     err = re.sub(
         r"(^\s+Address 0x)[0-9A-Fa-f]+( is not stack'd)", r"\1\2", err, flags=re.MULTILINE)
     err = re.sub(r"(^\s+Invalid write of size )\d+",
                  r"\1x", err, flags=re.MULTILINE)
     err = re.sub(r"(^\s+Invalid read of size )\d+",
                  r"\1x", err, flags=re.MULTILINE)
-    err = re.sub(r"(^\s+Address 0x)[0-9A-Fa-f]+( is )\d+( bytes inside a block of size )[0-9,]+( free'd)",
+    err = re.sub(r"(^\s+Address 0x)[0-9A-Fa-f]+( is )\d+( bytes inside a block of size )[0-9,]+( free'd)",  # NOQA: E501
                  r"\1\2\3\4", err, flags=re.MULTILINE)
 
     # Skip the repeating bit due to the segfault
     lines = []
     for l in err.split('\n'):
         if l == " Process terminating with default action of signal 11 (SIGSEGV)":
             break
         lines.append(l)
@@ -165,17 +163,17 @@ def remove_failed_allocation_backtraces(
             lines.append(l)
 
     err = '\n'.join(lines)
 
     return err
 
 
 def clean_output(err):
-    err = re.sub(r"^js\(\d+,0x[0-9a-f]+\) malloc: \*\*\* error for object 0x[0-9a-f]+: pointer being freed was not allocated\n\*\*\* set a breakppoint in malloc_error_break to debug\n$",
+    err = re.sub(r"^js\(\d+,0x[0-9a-f]+\) malloc: \*\*\* error for object 0x[0-9a-f]+: pointer being freed was not allocated\n\*\*\* set a breakpoint in malloc_error_break to debug\n$",  # NOQA: E501
                  "pointer being freed was not allocated", err, flags=re.MULTILINE)
 
     return err
 
 
 #####################################################################
 # Consts, etc
 #####################################################################
@@ -208,30 +206,30 @@ whitelist.add(r"('', 'out of memory\nout
 # Options
 parser = OptionParser(usage=usage)
 parser.add_option("-r", "--regression", action="store", metavar="REGRESSION_COUNT", help=help,
                   type="int", dest="regression", default=None)
 
 (OPTIONS, args) = parser.parse_args()
 
 
-if OPTIONS.regression != None:
+if OPTIONS.regression is not None:
     # TODO: This should be expanded as we get a better hang of the OOM problems.
     # For now, we'll just check that the number of OOMs in one short file does not
     # increase.
     files = ["../jit-test/tests/arguments/args-createontrace.js"]
 else:
     files = get_js_files()
 
     # Use a command-line arg to reduce the set of files
     if len(args):
         files = [f for f in files if f.find(args[0]) != -1]
 
 
-if OPTIONS.regression == None:
+if OPTIONS.regression is None:
     # Don't use a logfile, this is automated for tinderbox.
     log = file("../OOM_log", "w")
 
 
 num_failures = 0
 for f in files:
 
     # Run it once to establish boundaries
@@ -240,33 +238,33 @@ for f in files:
     max = re.match(".*OOM max count: (\d+).*", out,
                    flags=re.DOTALL).groups()[0]
     max = int(max)
 
     # OOMs don't recover well for the first 20 allocations or so.
     # TODO: revisit this.
     for i in range(20, max):
 
-        if OPTIONS.regression == None:
+        if OPTIONS.regression is None:
             print("Testing allocation {0}/{1} in {2}".format(i, max, f))
         else:
             # something short for tinderbox, no space or \n
             sys.stdout.write('.')
 
         command = (command_template + ' -A {0}').format(f, i)
         out, err, exit = run(command)
 
         # Success (5 is SM's exit code for controlled errors)
         if exit == 5 and err.find("out of memory") != -1:
             continue
 
         # Failure
         else:
 
-            if OPTIONS.regression != None:
+            if OPTIONS.regression is not None:
                 # Just count them
                 num_failures += 1
                 continue
 
             #########################################################################
             # The regression tests ends above. The rest of this is for running  the
             # script manually.
             #########################################################################
@@ -335,23 +333,23 @@ for f in files:
 
             log.write("\n")
 
             log.write("Valgrind info:\n" + vout)
             log.write("\n")
             log.write("\n")
             log.flush()
 
-    if OPTIONS.regression == None:
+    if OPTIONS.regression is None:
         count_lines()
 
 print()
 
 # Do the actual regression check
-if OPTIONS.regression != None:
+if OPTIONS.regression is not None:
     expected_num_failures = OPTIONS.regression
 
     if num_failures != expected_num_failures:
 
         print("TEST-UNEXPECTED-FAIL |", end='')
         if num_failures > expected_num_failures:
             print("More out-of-memory errors were found ({0}) than expected ({1}). "
                   "This probably means an allocation site has been added without a "
--- a/config/make-stl-wrappers.py
+++ b/config/make-stl-wrappers.py
@@ -1,16 +1,14 @@
 # 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/.
 from __future__ import print_function
 import os
-import re
 import string
-import sys
 from mozbuild.util import FileAvoidWrite
 
 
 def find_in_path(file, searchpath):
     for dir in searchpath.split(os.pathsep):
         f = os.path.join(dir, file)
         if os.path.exists(f):
             return f
--- a/config/make-system-wrappers.py
+++ b/config/make-system-wrappers.py
@@ -1,14 +1,13 @@
 # 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/.
 from __future__ import print_function
 import os
-import sys
 from mozbuild.util import FileAvoidWrite
 
 header_template = '''#pragma GCC system_header
 #pragma GCC visibility push(default)
 #include_next <%(header)s>
 #pragma GCC visibility pop
 '''
 
--- a/config/nsinstall.py
+++ b/config/nsinstall.py
@@ -11,17 +11,16 @@
 # all related options.
 from __future__ import print_function
 from optparse import OptionParser
 import mozfile
 import os
 import os.path
 import sys
 import shutil
-import stat
 
 
 def _nsinstall_internal(argv):
     usage = "usage: %prog [options] arg1 [arg2 ...] target-directory"
     p = OptionParser(usage=usage)
 
     p.add_option('-D', action="store_true",
                  help="Create a single directory only")
@@ -52,17 +51,17 @@ def _nsinstall_internal(argv):
                  help="Set group (NOT SUPPORTED)", metavar="group")
 
     (options, args) = p.parse_args(argv)
 
     if options.m:
         # mode is specified
         try:
             options.m = int(options.m, 8)
-        except:
+        except Exception:
             sys.stderr.write('nsinstall: {0} is not a valid mode\n'
                              .format(options.m))
             return 1
 
     # just create one directory?
     def maybe_create_dir(dir, mode, try_again):
         dir = os.path.abspath(dir)
         if os.path.exists(dir):
@@ -84,17 +83,17 @@ def _nsinstall_internal(argv):
                 return maybe_create_dir(dir, mode, False)
             print(
                 "nsinstall: failed to create directory {0}: {1}".format(dir, e))
             return 1
         else:
             return 0
 
     if options.X:
-        options.X = [os.path.abspath(p) for p in options.X]
+        options.X = [os.path.abspath(path) for path in options.X]
 
     if options.D:
         return maybe_create_dir(args[0], options.m, True)
 
     # nsinstall arg1 [...] directory
     if len(args) < 2:
         p.error('not enough arguments')
 
--- a/config/printconfigsetting.py
+++ b/config/printconfigsetting.py
@@ -5,27 +5,27 @@
 import configobj
 import sys
 import re
 from StringIO import StringIO
 
 try:
     (file, section, key) = sys.argv[1:]
 except ValueError:
-    print "Usage: printconfigsetting.py <file> <section> <setting>"
+    print("Usage: printconfigsetting.py <file> <section> <setting>")
     sys.exit(1)
 
 with open(file) as fh:
     content = re.sub('^\s*;', '#', fh.read(), flags=re.M)
 
 c = configobj.ConfigObj(StringIO(content))
 
 try:
     s = c[section]
 except KeyError:
     print >>sys.stderr, "Section [%s] not found." % section
     sys.exit(1)
 
 try:
-    print s[key]
+    print(s[key])
 except KeyError:
     print >>sys.stderr, "Key %s not found." % key
     sys.exit(1)
--- a/config/rebuild_check.py
+++ b/config/rebuild_check.py
@@ -15,35 +15,35 @@ def mtime(path):
         raise
 
 
 def rebuild_check(args):
     target = args[0]
     deps = args[1:]
     t = mtime(target)
     if t < 0:
-        print target
+        print(target)
         return
 
     newer = []
     removed = []
     for dep in deps:
         deptime = mtime(dep)
         if deptime < 0:
             removed.append(dep)
         elif mtime(dep) > t:
             newer.append(dep)
 
     if newer and removed:
-        print 'Rebuilding %s because %s changed and %s was removed' % (
-            target, ', '.join(newer), ', '.join(removed))
+        print('Rebuilding %s because %s changed and %s was removed' % (
+            target, ', '.join(newer), ', '.join(removed)))
     elif newer:
-        print 'Rebuilding %s because %s changed' % (target, ', '.join(newer))
+        print('Rebuilding %s because %s changed' % (target, ', '.join(newer)))
     elif removed:
-        print 'Rebuilding %s because %s was removed' % (
-            target, ', '.join(removed))
+        print('Rebuilding %s because %s was removed' % (
+            target, ', '.join(removed)))
     else:
-        print 'Rebuilding %s for an unknown reason' % target
+        print('Rebuilding %s for an unknown reason' % target)
 
 
 if __name__ == '__main__':
     import sys
     rebuild_check(sys.argv[1:])
--- a/config/tests/unit-mozunit.py
+++ b/config/tests/unit-mozunit.py
@@ -1,13 +1,12 @@
 # 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/.
 
-import sys
 import os
 from mozunit import main, MockedOpen
 import unittest
 from tempfile import mkstemp
 
 
 class TestMozUnit(unittest.TestCase):
     def test_mocked_open(self):
--- a/config/tests/unit-printprereleasesuffix.py
+++ b/config/tests/unit-printprereleasesuffix.py
@@ -1,12 +1,10 @@
 import unittest
 
-import sys
-import os.path
 import mozunit
 
 from printprereleasesuffix import get_prerelease_suffix
 
 
 class TestGetPreReleaseSuffix(unittest.TestCase):
     """
     Unit tests for the get_prerelease_suffix function
--- a/config/tests/unitMozZipFile.py
+++ b/config/tests/unitMozZipFile.py
@@ -1,27 +1,26 @@
 # 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/.
 
 import unittest
 
 import shutil
 import os
-import re
 import sys
 import random
 import copy
 from string import letters
 
 '''
 Test case infrastructure for MozZipFile.
 
 This isn't really a unit test, but a test case generator and runner.
-For a given set of files, lengths, and number of writes, we create 
+For a given set of files, lengths, and number of writes, we create
 a testcase for every combination of the three. There are some
 symmetries used to reduce the number of test cases, the first file
 written is always the first file, the second is either the first or
 the second, the third is one of the first three. That is, if we
 had 4 files, but only three writes, the fourth file would never even
 get tried.
 
 The content written to the jars is pseudorandom with a fixed seed.