Chris Jerdonek  committed 6ff87d1

Implement and document {randomseed} and --randomseed (still need tests).

  • Participants
  • Parent commits f7f70c5
  • Branches default

Comments (0)

Files changed (5)

File doc/config.txt

     the directory where sdist-packages will be copied to so that
     they may be accessed by other processes or tox runs.
+.. _randomseed:
+    .. versionadded:: 1.6.1
+    a random integer in the range 1 to 4294967295 (the maximum value allowed
+    for the PYTHONHASHSEED_ environment variable).  You can also
+    provide an explicit value via the ``--randomseed`` command-line option
+    to ``tox``.
 substitutions for virtualenv-related sections

File doc/example/basic.txt

 from the ``subdir`` below the directory where your ``tox.ini``
 file resides.
+Another use case is setting PYTHONHASHSEED_ to a :ref:`random value
+<randomseed>` generated by ``tox``::
+    [testenv]
+    setenv =
+        PYTHONHASHSEED = {randomseed}
 Integration with setuptools/distribute test commands

File doc/links.txt

 .. _devpi:
 .. _Python:
 .. _virtualenv:
 .. _virtualenv3:
 .. _virtualenv5:
-commands=echo {posargs}
+commands=echo {randomseed}
 commands=py.test  --junitxml={envlogdir}/junit-{envname}.xml {posargs}

File tox/

 import argparse
 import distutils.sysconfig
 import os
+import random
 import sys
 import re
 import shlex
         basepython = "python" + ".".join(_name[2:4])
     defaultenvs[_name] = basepython
-def parseconfig(args=None, pkg=None):
+# A makeseed function can be passed in during unit-testing for
+# deterministic test results.
+def parseconfig(args=None, pkg=None, makeseed=None):
     if args is None:
         args = sys.argv[1:]
+    if makeseed is None:
+        makeseed = lambda: random.randint(1, 4294967295)
     parser = prepare_parse(pkg)
     opts = parser.parse_args(args)
     config = Config()
             feedback("toxini file %r not found" %(basename), sysexit=True)
-        parseini(config, inipath)
+        parseini(config, inipath, makeseed)
     except tox.exception.InterpreterNotFound:
         exn = sys.exc_info()[1]
         # Use stdout to match test expectations
              "all commands and results involved.  This will turn off "
              "pass-through output from running test commands which is "
              "instead captured into the json result file.")
+    # We choose 1 to 4294967295 because it is the range of PYTHONHASHSEED.
+    parser.add_argument("--randomseed", action="store", type=int, metavar="N",
+        help="the integer {randomseed} to use in tox.ini.  Defaults "
+             "to a random integer in the range 1 to 4294967295.")
     parser.add_argument("args", nargs="*",
         help="additional arguments available to command positional substition")
     return parser
         return None
 class parseini:
-    def __init__(self, config, inipath):
+    def __init__(self, config, inipath, makeseed):
         config.toxinipath = inipath
         config.toxinidir = toxinidir = config.toxinipath.dirpath()
             raise ValueError("invalid context")
+        randomseed = config.option.randomseed
+        if randomseed is None:
+            randomseed = makeseed()
+        reader.addsubstitions(randomseed=randomseed)