[tests] Make random seed logged and settable

This allows tests which use randomness to be reproducibly run on failure.
pull/764/head
John Newbery 6 years ago
parent c5ffe8d515
commit a407b6fdf3

@ -10,6 +10,7 @@ import logging
import argparse import argparse
import os import os
import pdb import pdb
import random
import shutil import shutil
import sys import sys
import tempfile import tempfile
@ -129,6 +130,8 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
help="use bitcoin-cli instead of RPC for all commands") help="use bitcoin-cli instead of RPC for all commands")
parser.add_argument("--perf", dest="perf", default=False, action="store_true", parser.add_argument("--perf", dest="perf", default=False, action="store_true",
help="profile running nodes with perf for the duration of the test") 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.add_options(parser)
self.options = parser.parse_args() self.options = parser.parse_args()
@ -158,6 +161,22 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
self.options.tmpdir = tempfile.mkdtemp(prefix=TMPDIR_PREFIX) self.options.tmpdir = tempfile.mkdtemp(prefix=TMPDIR_PREFIX)
self._start_logging() 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.log.debug('Setting up network thread')
self.network_thread = NetworkThread() self.network_thread = NetworkThread()
self.network_thread.start() self.network_thread.start()

Loading…
Cancel
Save