Skip to content

Commit 4454c52

Browse files
committed
QA: Adapt BitcoinTestFramework for chains other than "regtest"
1 parent a06be15 commit 4454c52

17 files changed

+72
-68
lines changed

test/functional/combine_logs.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ def main():
2323
parser = argparse.ArgumentParser(usage='%(prog)s [options] <test temporary directory>', description=__doc__)
2424
parser.add_argument('-c', '--color', dest='color', action='store_true', help='outputs the combined log with events colored by source (requires posix terminal colors. Use less -r for viewing)')
2525
parser.add_argument('--html', dest='html', action='store_true', help='outputs the combined log as html. Requires jinja2. pip install jinja2')
26+
parser.add_argument('--chain', dest='chain', help='selected chain in the tests (default: regtest)', default='regtest')
2627
args, unknown_args = parser.parse_known_args()
2728

2829
if args.color and os.name != 'posix':
@@ -38,19 +39,19 @@ def main():
3839
print("Unexpected arguments" + str(unknown_args))
3940
sys.exit(1)
4041

41-
log_events = read_logs(unknown_args[0])
42+
log_events = read_logs(unknown_args[0], args.chain)
4243

4344
print_logs(log_events, color=args.color, html=args.html)
4445

45-
def read_logs(tmp_dir):
46+
def read_logs(tmp_dir, chain):
4647
"""Reads log files.
4748
4849
Delegates to generator function get_log_events() to provide individual log events
4950
for each of the input log files."""
5051

5152
files = [("test", "%s/test_framework.log" % tmp_dir)]
5253
for i in itertools.count():
53-
logfile = "{}/node{}/regtest/debug.log".format(tmp_dir, i)
54+
logfile = "{}/node{}/{}/debug.log".format(tmp_dir, i, chain)
5455
if not os.path.isfile(logfile):
5556
break
5657
files.append(("node%d" % i, logfile))

test/functional/feature_blocksdir.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def set_test_params(self):
1919
def run_test(self):
2020
self.stop_node(0)
2121
shutil.rmtree(self.nodes[0].datadir)
22-
initialize_datadir(self.options.tmpdir, 0)
22+
initialize_datadir(self.options.tmpdir, 0, self.chain)
2323
self.log.info("Starting with non exiting blocksdir ...")
2424
blocksdir_path = os.path.join(self.options.tmpdir, 'blocksdir')
2525
self.nodes[0].assert_start_raises_init_error(["-blocksdir=" + blocksdir_path], 'Error: Specified blocks directory "{}" does not exist.'.format(blocksdir_path))
@@ -28,8 +28,8 @@ def run_test(self):
2828
self.start_node(0, ["-blocksdir=" + blocksdir_path])
2929
self.log.info("mining blocks..")
3030
self.nodes[0].generate(10)
31-
assert os.path.isfile(os.path.join(blocksdir_path, "regtest", "blocks", "blk00000.dat"))
32-
assert os.path.isdir(os.path.join(self.nodes[0].datadir, "regtest", "blocks", "index"))
31+
assert os.path.isfile(os.path.join(blocksdir_path, self.chain, "blocks", "blk00000.dat"))
32+
assert os.path.isdir(os.path.join(self.nodes[0].datadir, self.chain, "blocks", "index"))
3333

3434

3535
if __name__ == '__main__':

test/functional/feature_config_args.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,13 @@ def run_test(self):
6565
# Temporarily disabled, because this test would access the user's home dir (~/.bitcoin)
6666
#self.start_node(0, ['-conf='+conf_file, '-wallet=w1'])
6767
#self.stop_node(0)
68-
#assert os.path.exists(os.path.join(new_data_dir, 'regtest', 'wallets', 'w1'))
68+
#assert os.path.exists(os.path.join(new_data_dir, self.chain, 'wallets', 'w1'))
6969

7070
# Ensure command line argument overrides datadir in conf
7171
os.mkdir(new_data_dir_2)
7272
self.nodes[0].datadir = new_data_dir_2
7373
self.start_node(0, ['-datadir='+new_data_dir_2, '-conf='+conf_file, '-wallet=w2'])
74-
assert os.path.exists(os.path.join(new_data_dir_2, 'regtest', 'wallets', 'w2'))
74+
assert os.path.exists(os.path.join(new_data_dir_2, self.chain, 'wallets', 'w2'))
7575

7676
if __name__ == '__main__':
7777
ConfArgsTest().main()

test/functional/feature_logging.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def set_test_params(self):
1616
self.setup_clean_chain = True
1717

1818
def relative_log_path(self, name):
19-
return os.path.join(self.nodes[0].datadir, "regtest", name)
19+
return os.path.join(self.nodes[0].datadir, self.chain, name)
2020

2121
def run_test(self):
2222
# test default log file name

test/functional/feature_pruning.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def set_test_params(self):
4646
def setup_network(self):
4747
self.setup_nodes()
4848

49-
self.prunedir = os.path.join(self.nodes[2].datadir, 'regtest', 'blocks', '')
49+
self.prunedir = os.path.join(self.nodes[2].datadir, self.chain, 'blocks', '')
5050

5151
connect_nodes(self.nodes[0], 1)
5252
connect_nodes(self.nodes[1], 2)
@@ -257,7 +257,7 @@ def prune(index, expected_ret=None):
257257
assert_equal(ret, expected_ret)
258258

259259
def has_block(index):
260-
return os.path.isfile(os.path.join(self.nodes[node_number].datadir, "regtest", "blocks", "blk{:05}.dat".format(index)))
260+
return os.path.isfile(os.path.join(self.nodes[node_number].datadir, self.chain, "blocks", "blk{:05}.dat".format(index)))
261261

262262
# should not prune because chain tip of node 3 (995) < PruneAfterHeight (1000)
263263
assert_raises_rpc_error(-1, "Blockchain is too short for pruning", node.pruneblockchain, height(500))

test/functional/interface_bitcoin_cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def run_test(self):
2828
rpc_response = self.nodes[0].getblockchaininfo()
2929
assert_equal(cli_response, rpc_response)
3030

31-
user, password = get_auth_cookie(self.nodes[0].datadir)
31+
user, password = get_auth_cookie(self.nodes[0].datadir, self.chain)
3232

3333
self.log.info("Test -stdinrpcpass option")
3434
assert_equal(0, self.nodes[0].cli('-rpcuser=%s' % user, '-stdinrpcpass', input=password).getblockcount())

test/functional/mempool_persist.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,8 @@ def run_test(self):
9494
self.start_node(0)
9595
wait_until(lambda: len(self.nodes[0].getrawmempool()) == 5)
9696

97-
mempooldat0 = os.path.join(self.nodes[0].datadir, 'regtest', 'mempool.dat')
98-
mempooldat1 = os.path.join(self.nodes[1].datadir, 'regtest', 'mempool.dat')
97+
mempooldat0 = os.path.join(self.nodes[0].datadir, self.chain, 'mempool.dat')
98+
mempooldat1 = os.path.join(self.nodes[1].datadir, self.chain, 'mempool.dat')
9999
self.log.debug("Remove the mempool.dat file. Verify that savemempool to disk via RPC re-creates it")
100100
os.remove(mempooldat0)
101101
self.nodes[0].savemempool()

test/functional/mining_basic.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def run_test(self):
3737
self.log.info('getmininginfo')
3838
mining_info = node.getmininginfo()
3939
assert_equal(mining_info['blocks'], 200)
40-
assert_equal(mining_info['chain'], 'regtest')
40+
assert_equal(mining_info['chain'], self.chain)
4141
assert_equal(mining_info['currentblocktx'], 0)
4242
assert_equal(mining_info['currentblockweight'], 0)
4343
assert_equal(mining_info['difficulty'], Decimal('4.656542373906925E-10'))

test/functional/rpc_bind.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def run_allowip_test(self, allow_ips, rpchost, rpcport):
5252
self.nodes[0].rpchost = None
5353
self.start_nodes([base_args])
5454
# connect to node through non-loopback interface
55-
node = get_rpc_proxy(rpc_url(self.nodes[0].datadir, 0, "%s:%d" % (rpchost, rpcport)), 0, coveragedir=self.options.coveragedir)
55+
node = get_rpc_proxy(rpc_url(self.nodes[0].datadir, 0, self.chain, "%s:%d" % (rpchost, rpcport)), 0, coveragedir=self.options.coveragedir)
5656
node.getnetworkinfo()
5757
self.stop_nodes()
5858

test/functional/rpc_scantxoutset.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def run_test(self):
4747

4848
self.log.info("Stop node, remove wallet, mine again some blocks...")
4949
self.stop_node(0)
50-
shutil.rmtree(os.path.join(self.nodes[0].datadir, "regtest", 'wallets'))
50+
shutil.rmtree(os.path.join(self.nodes[0].datadir, self.chain, 'wallets'))
5151
self.start_node(0)
5252
self.nodes[0].generate(110)
5353

test/functional/test_framework/test_framework.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
8282

8383
def __init__(self):
8484
"""Sets test framework defaults. Do not override this method. Instead, override the set_test_params() method"""
85+
self.chain = "regtest"
8586
self.setup_clean_chain = False
8687
self.nodes = []
8788
self.network_thread = None
@@ -267,7 +268,7 @@ def add_nodes(self, num_nodes, extra_args=None, *, rpchost=None, binary=None):
267268
assert_equal(len(extra_args), num_nodes)
268269
assert_equal(len(binary), num_nodes)
269270
for i in range(num_nodes):
270-
self.nodes.append(TestNode(i, get_datadir_path(self.options.tmpdir, i), rpchost=rpchost, timewait=self.rpc_timewait, bitcoind=binary[i], bitcoin_cli=self.options.bitcoincli, mocktime=self.mocktime, coverage_dir=self.options.coveragedir, extra_conf=extra_confs[i], extra_args=extra_args[i], use_cli=self.options.usecli))
271+
self.nodes.append(TestNode(i, get_datadir_path(self.options.tmpdir, i), self.chain, rpchost=rpchost, timewait=self.rpc_timewait, bitcoind=binary[i], bitcoin_cli=self.options.bitcoincli, mocktime=self.mocktime, coverage_dir=self.options.coveragedir, extra_conf=extra_confs[i], extra_args=extra_args[i], use_cli=self.options.usecli))
271272

272273
def start_node(self, i, *args, **kwargs):
273274
"""Start a bitcoind"""
@@ -414,11 +415,11 @@ def _initialize_chain(self):
414415

415416
# Create cache directories, run bitcoinds:
416417
for i in range(MAX_NODES):
417-
datadir = initialize_datadir(self.options.cachedir, i)
418+
datadir = initialize_datadir(self.options.cachedir, i, self.chain)
418419
args = [self.options.bitcoind, "-datadir=" + datadir]
419420
if i > 0:
420421
args.append("-connect=127.0.0.1:" + str(p2p_port(0)))
421-
self.nodes.append(TestNode(i, get_datadir_path(self.options.cachedir, i), extra_conf=["bind=127.0.0.1"], extra_args=[], rpchost=None, timewait=self.rpc_timewait, bitcoind=self.options.bitcoind, bitcoin_cli=self.options.bitcoincli, mocktime=self.mocktime, coverage_dir=None))
422+
self.nodes.append(TestNode(i, get_datadir_path(self.options.cachedir, i), self.chain, extra_conf=["bind=127.0.0.1"], extra_args=[], rpchost=None, timewait=self.rpc_timewait, bitcoind=self.options.bitcoind, bitcoin_cli=self.options.bitcoincli, mocktime=self.mocktime, coverage_dir=None))
422423
self.nodes[i].args = args
423424
self.start_node(i)
424425

@@ -450,7 +451,7 @@ def _initialize_chain(self):
450451
self.disable_mocktime()
451452

452453
def cache_path(n, *paths):
453-
return os.path.join(get_datadir_path(self.options.cachedir, n), "regtest", *paths)
454+
return os.path.join(get_datadir_path(self.options.cachedir, n), self.chain, *paths)
454455

455456
for i in range(MAX_NODES):
456457
for entry in os.listdir(cache_path(i)):
@@ -461,15 +462,15 @@ def cache_path(n, *paths):
461462
from_dir = get_datadir_path(self.options.cachedir, i)
462463
to_dir = get_datadir_path(self.options.tmpdir, i)
463464
shutil.copytree(from_dir, to_dir)
464-
initialize_datadir(self.options.tmpdir, i) # Overwrite port/rpcport in bitcoin.conf
465+
initialize_datadir(self.options.tmpdir, i, self.chain) # Overwrite port/rpcport in bitcoin.conf
465466

466467
def _initialize_chain_clean(self):
467468
"""Initialize empty blockchain for use by the test.
468469
469470
Create an empty blockchain and num_nodes wallets.
470471
Useful if a test case wants complete control over initialization."""
471472
for i in range(self.num_nodes):
472-
initialize_datadir(self.options.tmpdir, i)
473+
initialize_datadir(self.options.tmpdir, i, self.chain)
473474

474475

475476
class SkipTest(Exception):

test/functional/test_framework/test_node.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,12 @@ class TestNode():
5757
To make things easier for the test writer, any unrecognised messages will
5858
be dispatched to the RPC connection."""
5959

60-
def __init__(self, i, datadir, *, rpchost, timewait, bitcoind, bitcoin_cli, mocktime, coverage_dir, extra_conf=None, extra_args=None, use_cli=False):
60+
def __init__(self, i, datadir, chain, *, rpchost, timewait, bitcoind, bitcoin_cli, mocktime, coverage_dir, extra_conf=None, extra_args=None, use_cli=False):
6161
self.index = i
6262
self.datadir = datadir
6363
self.stdout_dir = os.path.join(self.datadir, "stdout")
6464
self.stderr_dir = os.path.join(self.datadir, "stderr")
65+
self.chain = chain
6566
self.rpchost = rpchost
6667
self.rpc_timeout = timewait
6768
self.binary = bitcoind
@@ -83,7 +84,7 @@ def __init__(self, i, datadir, *, rpchost, timewait, bitcoind, bitcoin_cli, mock
8384
"-uacomment=testnode%d" % i
8485
]
8586

86-
self.cli = TestNodeCLI(bitcoin_cli, self.datadir)
87+
self.cli = TestNodeCLI(bitcoin_cli, self.datadir, self.chain)
8788
self.use_cli = use_cli
8889

8990
self.running = False
@@ -138,7 +139,7 @@ def start(self, extra_args=None, *, stdout=None, stderr=None, **kwargs):
138139
# Delete any existing cookie file -- if such a file exists (eg due to
139140
# unclean shutdown), it will get overwritten anyway by bitcoind, and
140141
# potentially interfere with our attempt to authenticate
141-
delete_cookie_file(self.datadir)
142+
delete_cookie_file(self.datadir, self.chain)
142143

143144
# add environment variable LIBC_FATAL_STDERR_=1 so that libc errors are written to stderr and not the terminal
144145
subp_env = dict(os.environ, LIBC_FATAL_STDERR_="1")
@@ -157,7 +158,7 @@ def wait_for_rpc_connection(self):
157158
raise FailedToStartError(self._node_msg(
158159
'bitcoind exited with status {} during initialization'.format(self.process.returncode)))
159160
try:
160-
self.rpc = get_rpc_proxy(rpc_url(self.datadir, self.index, self.rpchost), self.index, timeout=self.rpc_timeout, coveragedir=self.coverage_dir)
161+
self.rpc = get_rpc_proxy(rpc_url(self.datadir, self.index, self.chain, self.rpchost), self.index, timeout=self.rpc_timeout, coveragedir=self.coverage_dir)
161162
self.rpc.getblockcount()
162163
# If the call to getblockcount() succeeds then the RPC connection is up
163164
self.rpc_connected = True
@@ -325,16 +326,17 @@ def get_request(self, *args, **kwargs):
325326
class TestNodeCLI():
326327
"""Interface to bitcoin-cli for an individual node"""
327328

328-
def __init__(self, binary, datadir):
329+
def __init__(self, binary, datadir, chain):
329330
self.options = []
330331
self.binary = binary
331332
self.datadir = datadir
333+
self.chain = chain
332334
self.input = None
333335
self.log = logging.getLogger('TestFramework.bitcoincli')
334336

335337
def __call__(self, *options, input=None):
336338
# TestNodeCLI is callable with bitcoin-cli command-line options
337-
cli = TestNodeCLI(self.binary, self.datadir)
339+
cli = TestNodeCLI(self.binary, self.datadir, self.chain)
338340
cli.options = [str(o) for o in options]
339341
cli.input = input
340342
return cli
@@ -356,7 +358,7 @@ def send_cli(self, command=None, *args, **kwargs):
356358
pos_args = [str(arg).lower() if type(arg) is bool else str(arg) for arg in args]
357359
named_args = [str(key) + "=" + str(value) for (key, value) in kwargs.items()]
358360
assert not (pos_args and named_args), "Cannot use positional arguments and named arguments in the same bitcoin-cli call"
359-
p_args = [self.binary, "-datadir=" + self.datadir] + self.options
361+
p_args = [self.binary, "-datadir=" + self.datadir, "-chain=" + self.chain] + self.options
360362
if named_args:
361363
p_args += ["-named"]
362364
if command is not None:

test/functional/test_framework/util.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -273,8 +273,8 @@ def p2p_port(n):
273273
def rpc_port(n):
274274
return PORT_MIN + PORT_RANGE + n + (MAX_NODES * PortSeed.n) % (PORT_RANGE - 1 - MAX_NODES)
275275

276-
def rpc_url(datadir, i, rpchost=None):
277-
rpc_u, rpc_p = get_auth_cookie(datadir)
276+
def rpc_url(datadir, i, chain, rpchost=None):
277+
rpc_u, rpc_p = get_auth_cookie(datadir, chain)
278278
host = '127.0.0.1'
279279
port = rpc_port(i)
280280
if rpchost:
@@ -288,13 +288,16 @@ def rpc_url(datadir, i, rpchost=None):
288288
# Node functions
289289
################
290290

291-
def initialize_datadir(dirname, n):
291+
def get_datadir_path(dirname, n):
292+
return os.path.join(dirname, "node" + str(n))
293+
294+
def initialize_datadir(dirname, n, chain):
292295
datadir = get_datadir_path(dirname, n)
293296
if not os.path.isdir(datadir):
294297
os.makedirs(datadir)
295298
with open(os.path.join(datadir, "bitcoin.conf"), 'w', encoding='utf8') as f:
296-
f.write("regtest=1\n")
297-
f.write("[regtest]\n")
299+
f.write("chain=%s\n" % chain)
300+
f.write("[%s]\n" % chain)
298301
f.write("port=" + str(p2p_port(n)) + "\n")
299302
f.write("rpcport=" + str(rpc_port(n)) + "\n")
300303
f.write("server=1\n")
@@ -306,15 +309,12 @@ def initialize_datadir(dirname, n):
306309
os.makedirs(os.path.join(datadir, 'stdout'), exist_ok=True)
307310
return datadir
308311

309-
def get_datadir_path(dirname, n):
310-
return os.path.join(dirname, "node" + str(n))
311-
312312
def append_config(datadir, options):
313313
with open(os.path.join(datadir, "bitcoin.conf"), 'a', encoding='utf8') as f:
314314
for option in options:
315315
f.write(option + "\n")
316316

317-
def get_auth_cookie(datadir):
317+
def get_auth_cookie(datadir, chain):
318318
user = None
319319
password = None
320320
if os.path.isfile(os.path.join(datadir, "bitcoin.conf")):
@@ -326,8 +326,8 @@ def get_auth_cookie(datadir):
326326
if line.startswith("rpcpassword="):
327327
assert password is None # Ensure that there is only one rpcpassword line
328328
password = line.split("=")[1].strip("\n")
329-
if os.path.isfile(os.path.join(datadir, "regtest", ".cookie")):
330-
with open(os.path.join(datadir, "regtest", ".cookie"), 'r', encoding="ascii") as f:
329+
if os.path.isfile(os.path.join(datadir, chain, ".cookie")):
330+
with open(os.path.join(datadir, chain, ".cookie"), 'r', encoding="ascii") as f:
331331
userpass = f.read()
332332
split_userpass = userpass.split(':')
333333
user = split_userpass[0]
@@ -337,10 +337,10 @@ def get_auth_cookie(datadir):
337337
return user, password
338338

339339
# If a cookie file exists in the given datadir, delete it.
340-
def delete_cookie_file(datadir):
341-
if os.path.isfile(os.path.join(datadir, "regtest", ".cookie")):
340+
def delete_cookie_file(datadir, chain):
341+
if os.path.isfile(os.path.join(datadir, chain, ".cookie")):
342342
logger.debug("Deleting leftover cookie file")
343-
os.remove(os.path.join(datadir, "regtest", ".cookie"))
343+
os.remove(os.path.join(datadir, chain, ".cookie"))
344344

345345
def get_bip9_status(node, key):
346346
info = node.getblockchaininfo()

0 commit comments

Comments
 (0)