mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-08 10:31:50 -05:00
[tests] check v0.17.1 and v0.18.1 backwards compatibility
This commit is contained in:
parent
ae379cf7d1
commit
8b1460dbd1
10 changed files with 112 additions and 8 deletions
|
@ -35,6 +35,7 @@ cache:
|
|||
- $TRAVIS_BUILD_DIR/depends/built
|
||||
- $TRAVIS_BUILD_DIR/depends/sdk-sources
|
||||
- $TRAVIS_BUILD_DIR/ci/scratch/.ccache
|
||||
- $TRAVIS_BUILD_DIR/releases/$HOST
|
||||
# macOS
|
||||
- $HOME/Library/Caches/Homebrew
|
||||
- /usr/local/Homebrew
|
||||
|
@ -108,7 +109,7 @@ jobs:
|
|||
FILE_ENV="./ci/test/00_setup_env_i686_centos.sh"
|
||||
|
||||
- stage: test
|
||||
name: 'x86_64 Linux [GOAL: install] [bionic] [uses qt5 dev package and some depends packages] [unsigned char]'
|
||||
name: 'x86_64 Linux [GOAL: install] [bionic] [previous releases, uses qt5 dev package and some depends packages] [unsigned char]'
|
||||
env: >-
|
||||
FILE_ENV="./ci/test/00_setup_env_native_qt5.sh"
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ If the repository is not a fresh git clone, you might have to clean files from p
|
|||
|
||||
The ci needs to perform various sysadmin tasks such as installing packages or writing to the user's home directory.
|
||||
While most of the actions are done inside a docker container, this is not possible for all. Thus, cache directories,
|
||||
such as the depends cache or ccache, are mounted as read-write into the docker container. While it should be fine to run
|
||||
such as the depends cache, previous release binaries, or ccache, are mounted as read-write into the docker container. While it should be fine to run
|
||||
the ci system locally on you development box, the ci scripts can generally be assumed to have received less review and
|
||||
testing compared to other parts of the codebase. If you want to keep the work tree clean, you might want to run the ci
|
||||
system in a virtual machine with a Linux operating system of your choice.
|
||||
|
|
|
@ -33,6 +33,7 @@ export HOST=${HOST:-$("$BASE_ROOT_DIR/depends/config.guess")}
|
|||
export USE_BUSY_BOX=${USE_BUSY_BOX:-false}
|
||||
export RUN_UNIT_TESTS=${RUN_UNIT_TESTS:-true}
|
||||
export RUN_FUNCTIONAL_TESTS=${RUN_FUNCTIONAL_TESTS:-true}
|
||||
export TEST_PREVIOUS_RELEASES=${TEST_PREVIOUS_RELEASES:-false}
|
||||
export RUN_FUZZ_TESTS=${RUN_FUZZ_TESTS:-false}
|
||||
export CONTAINER_NAME=${CONTAINER_NAME:-ci_unnamed}
|
||||
export DOCKER_NAME_TAG=${DOCKER_NAME_TAG:-ubuntu:18.04}
|
||||
|
@ -50,6 +51,7 @@ export CCACHE_DIR=${CCACHE_DIR:-$BASE_SCRATCH_DIR/.ccache}
|
|||
export DEPENDS_DIR=${DEPENDS_DIR:-$BASE_ROOT_DIR/depends}
|
||||
# Folder where the build is done (bin and lib).
|
||||
export BASE_OUTDIR=${BASE_OUTDIR:-$BASE_SCRATCH_DIR/out/$HOST}
|
||||
export PREVIOUS_RELEASES_DIR=${PREVIOUS_RELEASES_DIR:-$BASE_ROOT_DIR/releases/$HOST}
|
||||
export SDK_URL=${SDK_URL:-https://bitcoincore.org/depends-sources/sdks}
|
||||
export WINEDEBUG=${WINEDEBUG:-fixme-all}
|
||||
export DOCKER_PACKAGES=${DOCKER_PACKAGES:-build-essential libtool autotools-dev automake pkg-config bsdmainutils curl ca-certificates ccache python3 rsync git procps}
|
||||
|
|
|
@ -11,4 +11,5 @@ export PACKAGES="python3-zmq qtbase5-dev qttools5-dev-tools libdbus-1-dev libhar
|
|||
export DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1 ALLOW_HOST_PACKAGES=1"
|
||||
export TEST_RUNNER_EXTRA="--coverage --extended --exclude feature_dbcrash" # Run extended tests so that coverage does not fail, but exclude the very slow dbcrash
|
||||
export GOAL="install"
|
||||
export TEST_PREVIOUS_RELEASES=true
|
||||
export BITCOIN_CONFIG="--enable-zmq --with-gui=qt5 --enable-glibc-back-compat --enable-reduce-exports --enable-debug CFLAGS=\"-g0 -O2 -funsigned-char\" CXXFLAGS=\"-g0 -O2 -funsigned-char\""
|
||||
|
|
|
@ -40,12 +40,13 @@ fi
|
|||
|
||||
mkdir -p "${BASE_SCRATCH_DIR}"
|
||||
mkdir -p "${CCACHE_DIR}"
|
||||
mkdir -p "${PREVIOUS_RELEASES_DIR}"
|
||||
|
||||
export ASAN_OPTIONS="detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1"
|
||||
export LSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/lsan"
|
||||
export TSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/tsan:log_path=${BASE_SCRATCH_DIR}/sanitizer-output/tsan"
|
||||
export UBSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/ubsan:print_stacktrace=1:halt_on_error=1:report_error_type=1"
|
||||
env | grep -E '^(BITCOIN_CONFIG|BASE_|QEMU_|CCACHE_|WINEDEBUG|LC_ALL|BOOST_TEST_RANDOM|CONFIG_SHELL|(ASAN|LSAN|TSAN|UBSAN)_OPTIONS)' | tee /tmp/env
|
||||
env | grep -E '^(BITCOIN_CONFIG|BASE_|QEMU_|CCACHE_|WINEDEBUG|LC_ALL|BOOST_TEST_RANDOM|CONFIG_SHELL|(ASAN|LSAN|TSAN|UBSAN)_OPTIONS|TEST_PREVIOUS_RELEASES|PREVIOUS_RELEASES_DIR)' | tee /tmp/env
|
||||
if [[ $HOST = *-mingw32 ]]; then
|
||||
DOCKER_ADMIN="--cap-add SYS_ADMIN"
|
||||
elif [[ $BITCOIN_CONFIG = *--with-sanitizers=*address* ]]; then # If ran with (ASan + LSan), Docker needs access to ptrace (https://github.com/google/sanitizers/issues/764)
|
||||
|
@ -62,6 +63,7 @@ if [ -z "$RUN_CI_ON_HOST" ]; then
|
|||
--mount type=bind,src=$BASE_ROOT_DIR,dst=/ro_base,readonly \
|
||||
--mount type=bind,src=$CCACHE_DIR,dst=$CCACHE_DIR \
|
||||
--mount type=bind,src=$DEPENDS_DIR,dst=$DEPENDS_DIR \
|
||||
--mount type=bind,src=$PREVIOUS_RELEASES_DIR,dst=$PREVIOUS_RELEASES_DIR \
|
||||
-w $BASE_ROOT_DIR \
|
||||
--env-file /tmp/env \
|
||||
--name $CONTAINER_NAME \
|
||||
|
|
|
@ -35,3 +35,8 @@ if [ -z "$NO_DEPENDS" ]; then
|
|||
fi
|
||||
DOCKER_EXEC $SHELL_OPTS make $MAKEJOBS -C depends HOST=$HOST $DEP_OPTS
|
||||
fi
|
||||
if [ "$TEST_PREVIOUS_RELEASES" = "true" ]; then
|
||||
BEGIN_FOLD previous-versions
|
||||
DOCKER_EXEC contrib/devtools/previous_release.sh -b -t "$PREVIOUS_RELEASES_DIR" v0.17.1 v0.18.1
|
||||
END_FOLD
|
||||
fi
|
||||
|
|
78
test/functional/feature_backwards_compatibility.py
Executable file
78
test/functional/feature_backwards_compatibility.py
Executable 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()
|
|
@ -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],
|
||||
|
|
|
@ -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.")
|
||||
|
||||
|
|
|
@ -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',
|
||||
|
|
Loading…
Add table
Reference in a new issue