|
10 | 10 | import argparse
|
11 | 11 | import os
|
12 | 12 | import pdb
|
| 13 | +import random |
13 | 14 | import shutil
|
14 | 15 | import sys
|
15 | 16 | import tempfile
|
@@ -129,6 +130,8 @@ def main(self):
|
129 | 130 | help="use bitcoin-cli instead of RPC for all commands")
|
130 | 131 | parser.add_argument("--perf", dest="perf", default=False, action="store_true",
|
131 | 132 | help="profile running nodes with perf for the duration of the test")
|
| 133 | + parser.add_argument("--randomseed", type=int, |
| 134 | + help="set a random seed for deterministically reproducing a previous test run") |
132 | 135 | self.add_options(parser)
|
133 | 136 | self.options = parser.parse_args()
|
134 | 137 |
|
@@ -158,6 +161,22 @@ def main(self):
|
158 | 161 | self.options.tmpdir = tempfile.mkdtemp(prefix=TMPDIR_PREFIX)
|
159 | 162 | self._start_logging()
|
160 | 163 |
|
| 164 | + # Seed the PRNG. Note that test runs are reproducible if and only if |
| 165 | + # a single thread accesses the PRNG. For more information, see |
| 166 | + # https://docs.python.org/3/library/random.html#notes-on-reproducibility. |
| 167 | + # The network thread shouldn't access random. If we need to change the |
| 168 | + # network thread to access randomness, it should instantiate its own |
| 169 | + # random.Random object. |
| 170 | + seed = self.options.randomseed |
| 171 | + |
| 172 | + if seed is None: |
| 173 | + seed = random.randrange(sys.maxsize) |
| 174 | + else: |
| 175 | + self.log.debug("User supplied random seed {}".format(seed)) |
| 176 | + |
| 177 | + random.seed(seed) |
| 178 | + self.log.debug("PRNG seed is: {}".format(seed)) |
| 179 | + |
161 | 180 | self.log.debug('Setting up network thread')
|
162 | 181 | self.network_thread = NetworkThread()
|
163 | 182 | self.network_thread.start()
|
|
0 commit comments