diff options
author | John Newbery <john@johnnewbery.com> | 2019-05-06 13:17:04 -0400 |
---|---|---|
committer | John Newbery <john@johnnewbery.com> | 2019-05-09 11:28:04 -0400 |
commit | a407b6fdf34f77eb347378674da9cf80394897de (patch) | |
tree | d7fa36d7bd95371aa2e2e9ea7e5c36f324caa9c6 /test/functional/test_framework/test_framework.py | |
parent | c5ffe8d5155b21d0099259416436d09fc20d7017 (diff) | |
download | bitcoin-a407b6fdf34f77eb347378674da9cf80394897de.tar.xz |
[tests] Make random seed logged and settable
This allows tests which use randomness to be reproducibly run on failure.
Diffstat (limited to 'test/functional/test_framework/test_framework.py')
-rwxr-xr-x | test/functional/test_framework/test_framework.py | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py index 555d55d97f..2187bf5f5f 100755 --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -10,6 +10,7 @@ import logging import argparse import os import pdb +import random import shutil import sys import tempfile @@ -129,6 +130,8 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): help="use bitcoin-cli instead of RPC for all commands") parser.add_argument("--perf", dest="perf", default=False, action="store_true", help="profile running nodes with perf for the duration of the test") + parser.add_argument("--randomseed", type=int, + help="set a random seed for deterministically reproducing a previous test run") self.add_options(parser) self.options = parser.parse_args() @@ -158,6 +161,22 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): self.options.tmpdir = tempfile.mkdtemp(prefix=TMPDIR_PREFIX) self._start_logging() + # Seed the PRNG. Note that test runs are reproducible if and only if + # a single thread accesses the PRNG. For more information, see + # https://docs.python.org/3/library/random.html#notes-on-reproducibility. + # The network thread shouldn't access random. If we need to change the + # network thread to access randomness, it should instantiate its own + # random.Random object. + seed = self.options.randomseed + + if seed is None: + seed = random.randrange(sys.maxsize) + else: + self.log.debug("User supplied random seed {}".format(seed)) + + random.seed(seed) + self.log.debug("PRNG seed is: {}".format(seed)) + self.log.debug('Setting up network thread') self.network_thread = NetworkThread() self.network_thread.start() |