[tests] check v0.17.1 and v0.18.1 backwards compatibility

This commit is contained in:
Sjors Provoost
2019-01-05 20:20:42 +01:00
parent ae379cf7d1
commit 8b1460dbd1
10 changed files with 112 additions and 8 deletions

View File

@@ -0,0 +1,78 @@
#!/usr/bin/env python3
# Copyright (c) 2018-2019 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Backwards compatibility functional test
Test various backwards compatibility scenarios. Download the previous node binaries:
contrib/devtools/previous_release.sh -b v0.18.1 v0.17.1
Due to RPC changes introduced in various versions the below tests
won't work for older versions without some patches or workarounds.
Use only the latest patch version of each release, unless a test specifically
needs an older patch version.
"""
import os
from test_framework.test_framework import BitcoinTestFramework, SkipTest
from test_framework.util import (
assert_equal,
sync_blocks
)
class BackwardsCompatibilityTest(BitcoinTestFramework):
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 4
# Add new version after each release:
self.extra_args = [
[], # Pre-release: use to mine blocks
[], # Pre-release: use to receive coins, swap wallets, etc
[], # v0.18.1
[] # v0.17.1
]
def setup_nodes(self):
if os.getenv("TEST_PREVIOUS_RELEASES") == "false":
raise SkipTest("backwards compatibility tests")
releases_path = os.getenv("PREVIOUS_RELEASES_DIR") or os.getcwd() + "/releases"
if not os.path.isdir(releases_path):
if os.getenv("TEST_PREVIOUS_RELEASES") == "true":
raise AssertionError("TEST_PREVIOUS_RELEASES=1 but releases missing: " + releases_path)
raise SkipTest("This test requires binaries for previous releases")
self.add_nodes(self.num_nodes, extra_args=self.extra_args, versions=[
None,
None,
180100,
170100
], binary=[
self.options.bitcoind,
self.options.bitcoind,
releases_path + "/v0.18.1/bin/bitcoind",
releases_path + "/v0.17.1/bin/bitcoind"
], binary_cli=[
self.options.bitcoincli,
self.options.bitcoincli,
releases_path + "/v0.18.1/bin/bitcoin-cli",
releases_path + "/v0.17.1/bin/bitcoin-cli"
])
self.start_nodes()
def run_test(self):
self.nodes[0].generate(101)
sync_blocks(self.nodes)
# Sanity check the test framework:
res = self.nodes[self.num_nodes - 1].getblockchaininfo()
assert_equal(res['blocks'], 101)
if __name__ == '__main__':
BackwardsCompatibilityTest().main()

View File

@@ -369,7 +369,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
# Public helper methods. These can be accessed by the subclass test scripts.
def add_nodes(self, num_nodes, extra_args=None, *, rpchost=None, binary=None):
def add_nodes(self, num_nodes, extra_args=None, *, rpchost=None, binary=None, binary_cli=None, versions=None):
"""Instantiate TestNode objects.
Should only be called once after the nodes have been specified in
@@ -380,11 +380,17 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
extra_confs = [[]] * num_nodes
if extra_args is None:
extra_args = [[]] * num_nodes
if versions is None:
versions = [None] * num_nodes
if binary is None:
binary = [self.options.bitcoind] * num_nodes
if binary_cli is None:
binary_cli = [self.options.bitcoincli] * num_nodes
assert_equal(len(extra_confs), num_nodes)
assert_equal(len(extra_args), num_nodes)
assert_equal(len(versions), num_nodes)
assert_equal(len(binary), num_nodes)
assert_equal(len(binary_cli), num_nodes)
for i in range(num_nodes):
self.nodes.append(TestNode(
i,
@@ -393,7 +399,8 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
rpchost=rpchost,
timewait=self.rpc_timeout,
bitcoind=binary[i],
bitcoin_cli=self.options.bitcoincli,
bitcoin_cli=binary_cli[i],
version=versions[i],
coverage_dir=self.options.coveragedir,
cwd=self.options.tmpdir,
extra_conf=extra_confs[i],

View File

@@ -60,7 +60,7 @@ class TestNode():
To make things easier for the test writer, any unrecognised messages will
be dispatched to the RPC connection."""
def __init__(self, i, datadir, *, chain, rpchost, timewait, bitcoind, bitcoin_cli, coverage_dir, cwd, extra_conf=None, extra_args=None, use_cli=False, start_perf=False, use_valgrind=False):
def __init__(self, i, datadir, *, chain, rpchost, timewait, bitcoind, bitcoin_cli, coverage_dir, cwd, extra_conf=None, extra_args=None, use_cli=False, start_perf=False, use_valgrind=False, version=None):
"""
Kwargs:
start_perf (bool): If True, begin profiling the node with `perf` as soon as
@@ -84,6 +84,7 @@ class TestNode():
# For those callers that need more flexibility, they can just set the args property directly.
# Note that common args are set in the config file (see initialize_datadir)
self.extra_args = extra_args
self.version = version
# Configuration for logging is set as command-line args rather than in the bitcoin.conf file.
# This means that starting a bitcoind using the temp dir to debug a failed test won't
# spam debug.log.
@@ -91,7 +92,6 @@ class TestNode():
self.binary,
"-datadir=" + self.datadir,
"-logtimemicros",
"-logthreadnames",
"-debug",
"-debugexclude=libevent",
"-debugexclude=leveldb",
@@ -107,6 +107,9 @@ class TestNode():
"--gen-suppressions=all", "--exit-on-first-error=yes",
"--error-exitcode=1", "--quiet"] + self.args
if self.version is None or self.version >= 190000:
self.args.append("-logthreadnames")
self.cli = TestNodeCLI(bitcoin_cli, self.datadir)
self.use_cli = use_cli
self.start_perf = start_perf
@@ -254,7 +257,11 @@ class TestNode():
return
self.log.debug("Stopping node")
try:
self.stop(wait=wait)
# Do not use wait argument when testing older nodes, e.g. in feature_backwards_compatibility.py
if self.version is None or self.version >= 180000:
self.stop(wait=wait)
else:
self.stop()
except http.client.CannotSendRequest:
self.log.exception("Unable to stop node.")

View File

@@ -158,6 +158,7 @@ BASE_SCRIPTS = [
'feature_assumevalid.py',
'example_test.py',
'wallet_txn_doublespend.py',
'feature_backwards_compatibility.py',
'wallet_txn_clone.py --mineblock',
'feature_notifications.py',
'rpc_getblockfilter.py',