aboutsummaryrefslogtreecommitdiff
path: root/test/functional/test_runner.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional/test_runner.py')
-rwxr-xr-xtest/functional/test_runner.py87
1 files changed, 53 insertions, 34 deletions
diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py
index 13c687fd92..3f990924ec 100755
--- a/test/functional/test_runner.py
+++ b/test/functional/test_runner.py
@@ -29,7 +29,7 @@ import re
import logging
# Formatting. Default colors to empty strings.
-BOLD, BLUE, RED, GREY = ("", ""), ("", ""), ("", ""), ("", "")
+BOLD, GREEN, RED, GREY = ("", ""), ("", ""), ("", ""), ("", "")
try:
# Make sure python thinks it can write unicode to its stdout
"\u2713".encode("utf_8").decode(sys.stdout.encoding)
@@ -41,11 +41,27 @@ except UnicodeDecodeError:
CROSS = "x "
CIRCLE = "o "
-if os.name == 'posix':
+if os.name != 'nt' or sys.getwindowsversion() >= (10, 0, 14393):
+ if os.name == 'nt':
+ import ctypes
+ kernel32 = ctypes.windll.kernel32
+ ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4
+ STD_OUTPUT_HANDLE = -11
+ STD_ERROR_HANDLE = -12
+ # Enable ascii color control to stdout
+ stdout = kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
+ stdout_mode = ctypes.c_int32()
+ kernel32.GetConsoleMode(stdout, ctypes.byref(stdout_mode))
+ kernel32.SetConsoleMode(stdout, stdout_mode.value | ENABLE_VIRTUAL_TERMINAL_PROCESSING)
+ # Enable ascii color control to stderr
+ stderr = kernel32.GetStdHandle(STD_ERROR_HANDLE)
+ stderr_mode = ctypes.c_int32()
+ kernel32.GetConsoleMode(stderr, ctypes.byref(stderr_mode))
+ kernel32.SetConsoleMode(stderr, stderr_mode.value | ENABLE_VIRTUAL_TERMINAL_PROCESSING)
# primitive formatting on supported
# terminal via ANSI escape sequences:
BOLD = ('\033[0m', '\033[1m')
- BLUE = ('\033[0m', '\033[0;34m')
+ GREEN = ('\033[0m', '\033[0;32m')
RED = ('\033[0m', '\033[0;31m')
GREY = ('\033[0m', '\033[1;30m')
@@ -58,9 +74,12 @@ TRAVIS_TIMEOUT_DURATION = 20 * 60
BASE_SCRIPTS = [
# Scripts that are run by the travis build process.
# Longest test should go first, to favor running tests in parallel
+ 'feature_fee_estimation.py',
'wallet_hd.py',
'wallet_backup.py',
# vv Tests less than 5m vv
+ 'mining_getblocktemplate_longpoll.py',
+ 'feature_maxuploadtarget.py',
'feature_block.py',
'rpc_fundrawtransaction.py',
'p2p_compactblocks.py',
@@ -69,6 +88,7 @@ BASE_SCRIPTS = [
'wallet_basic.py',
'wallet_labels.py',
'p2p_segwit.py',
+ 'p2p_timeouts.py',
'wallet_dump.py',
'wallet_listtransactions.py',
# vv Tests less than 60s vv
@@ -82,6 +102,8 @@ BASE_SCRIPTS = [
'feature_csv_activation.py',
'rpc_rawtransaction.py',
'wallet_address_types.py',
+ 'feature_bip68_sequence.py',
+ 'p2p_feefilter.py',
'feature_reindex.py',
# vv Tests less than 30s vv
'wallet_keypool_topup.py',
@@ -118,11 +140,18 @@ BASE_SCRIPTS = [
'p2p_invalid_locator.py',
'p2p_invalid_block.py',
'p2p_invalid_tx.py',
+ 'feature_assumevalid.py',
+ 'example_test.py',
+ 'wallet_txn_doublespend.py',
+ 'wallet_txn_clone.py --mineblock',
+ 'feature_notifications.py',
+ 'rpc_invalidateblock.py',
+ 'feature_rbf.py',
+ 'mempool_packages.py',
'rpc_createmultisig.py',
'feature_versionbits_warning.py',
'rpc_preciousblock.py',
'wallet_importprunedfunds.py',
- 'rpc_zmq.py',
'rpc_signmessage.py',
'feature_nulldummy.py',
'mempool_accept.py',
@@ -145,6 +174,7 @@ BASE_SCRIPTS = [
'rpc_getblockstats.py',
'p2p_fingerprint.py',
'feature_uacomment.py',
+ 'feature_filelock.py',
'p2p_unrequested_blocks.py',
'feature_includeconf.py',
'rpc_scantxoutset.py',
@@ -162,26 +192,7 @@ EXTENDED_SCRIPTS = [
# These tests are not run by the travis build process.
# Longest test should go first, to favor running tests in parallel
'feature_pruning.py',
- # vv Tests less than 20m vv
- 'feature_fee_estimation.py',
- # vv Tests less than 5m vv
- 'feature_maxuploadtarget.py',
- 'mempool_packages.py',
'feature_dbcrash.py',
- # vv Tests less than 2m vv
- 'feature_bip68_sequence.py',
- 'mining_getblocktemplate_longpoll.py',
- 'p2p_timeouts.py',
- # vv Tests less than 60s vv
- 'p2p_feefilter.py',
- # vv Tests less than 30s vv
- 'feature_assumevalid.py',
- 'example_test.py',
- 'wallet_txn_doublespend.py',
- 'wallet_txn_clone.py --mineblock',
- 'feature_notifications.py',
- 'rpc_invalidateblock.py',
- 'feature_rbf.py',
]
# Place EXTENDED_SCRIPTS first since it has the 3 longest running tests
@@ -232,12 +243,15 @@ def main():
# Create base test directory
tmpdir = "%s/test_runner_₿_🏃_%s" % (args.tmpdirprefix, datetime.datetime.now().strftime("%Y%m%d_%H%M%S"))
+
+ # If we fixed the command-line and filename encoding issue on Windows, these two lines could be removed
+ if config["environment"]["EXEEXT"] == ".exe":
+ tmpdir = "%s/test_runner_%s" % (args.tmpdirprefix, datetime.datetime.now().strftime("%Y%m%d_%H%M%S"))
+
os.makedirs(tmpdir)
logging.debug("Temporary test directory at %s" % tmpdir)
- enable_wallet = config["components"].getboolean("ENABLE_WALLET")
- enable_utils = config["components"].getboolean("ENABLE_UTILS")
enable_bitcoind = config["components"].getboolean("ENABLE_BITCOIND")
if config["environment"]["EXEEXT"] == ".exe" and not args.force:
@@ -246,9 +260,9 @@ def main():
print("Tests currently disabled on Windows by default. Use --force option to enable")
sys.exit(0)
- if not (enable_wallet and enable_utils and enable_bitcoind):
- print("No functional tests to run. Wallet, utils, and bitcoind must all be enabled")
- print("Rerun `configure` with -enable-wallet, -with-utils and -with-daemon and rerun make")
+ if not enable_bitcoind:
+ print("No functional tests to run.")
+ print("Rerun ./configure with --with-daemon and then make")
sys.exit(0)
# Build list of tests
@@ -271,11 +285,13 @@ def main():
# Remove the test cases that the user has explicitly asked to exclude.
if args.exclude:
- exclude_tests = [re.sub("\.py$", "", test) + ".py" for test in args.exclude.split(',')]
+ exclude_tests = [test.split('.py')[0] for test in args.exclude.split(',')]
for exclude_test in exclude_tests:
- if exclude_test in test_list:
- test_list.remove(exclude_test)
- else:
+ # Remove <test_name>.py and <test_name>.py --arg from the test list
+ exclude_list = [test for test in test_list if test.split('.py')[0] == exclude_test]
+ for exclude_item in exclude_list:
+ test_list.remove(exclude_item)
+ if not exclude_list:
print("{}WARNING!{} Test '{}' not found in current test list.".format(BOLD[1], BOLD[0], exclude_test))
if not test_list:
@@ -366,7 +382,10 @@ def run_tests(test_list, src_dir, build_dir, tmpdir, jobs=1, enable_coverage=Fal
print('\n============')
print('{}Combined log for {}:{}'.format(BOLD[1], testdir, BOLD[0]))
print('============\n')
- combined_logs, _ = subprocess.Popen([sys.executable, os.path.join(tests_dir, 'combine_logs.py'), '-c', testdir], universal_newlines=True, stdout=subprocess.PIPE).communicate()
+ combined_logs_args = [sys.executable, os.path.join(tests_dir, 'combine_logs.py'), testdir]
+ if BOLD[0]:
+ combined_logs_args += ['--color']
+ combined_logs, _ = subprocess.Popen(combined_logs_args, universal_newlines=True, stdout=subprocess.PIPE).communicate()
print("\n".join(deque(combined_logs.splitlines(), combined_logs_len)))
if failfast:
@@ -505,7 +524,7 @@ class TestResult():
def __repr__(self):
if self.status == "Passed":
- color = BLUE
+ color = GREEN
glyph = TICK
elif self.status == "Failed":
color = RED