aboutsummaryrefslogtreecommitdiff
path: root/test/functional
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional')
-rwxr-xr-xtest/functional/bip9-softforks.py10
-rwxr-xr-xtest/functional/forknotify.py15
-rwxr-xr-xtest/functional/mempool_packages.py12
-rwxr-xr-xtest/functional/net.py54
-rwxr-xr-xtest/functional/test_framework/mininode.py14
-rw-r--r--test/functional/test_framework/util.py2
-rwxr-xr-xtest/functional/test_runner.py94
7 files changed, 164 insertions, 37 deletions
diff --git a/test/functional/bip9-softforks.py b/test/functional/bip9-softforks.py
index 0dffd06e1a..60d262da81 100755
--- a/test/functional/bip9-softforks.py
+++ b/test/functional/bip9-softforks.py
@@ -200,16 +200,14 @@ class BIP9SoftForksTest(ComparisonTestFramework):
yield TestInstance([[block, False]])
# Restart all
- self.test.block_store.close()
+ self.test.clear_all_connections()
stop_nodes(self.nodes)
- shutil.rmtree(self.options.tmpdir)
+ shutil.rmtree(self.options.tmpdir + "/node0")
self.setup_chain()
self.setup_network()
- self.test.block_store = BlockStore(self.options.tmpdir)
- self.test.clear_all_connections()
self.test.add_all_connections(self.nodes)
- NetworkThread().start() # Start up network handling in another thread
-
+ NetworkThread().start()
+ self.test.test_nodes[0].wait_for_verack()
def get_tests(self):
for test in itertools.chain(
diff --git a/test/functional/forknotify.py b/test/functional/forknotify.py
index c2724ba5df..7a365438cc 100755
--- a/test/functional/forknotify.py
+++ b/test/functional/forknotify.py
@@ -3,6 +3,8 @@
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test the -alertnotify option."""
+import os
+import time
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
@@ -41,12 +43,19 @@ class ForkNotifyTest(BitcoinTestFramework):
self.nodes[1].generate(1)
self.sync_all()
+ # Give bitcoind 10 seconds to write the alert notification
+ timeout = 10.0
+ while timeout > 0:
+ if os.path.exists(self.alert_filename) and os.path.getsize(self.alert_filename):
+ break
+ time.sleep(0.1)
+ timeout -= 0.1
+ else:
+ assert False, "-alertnotify did not warn of up-version blocks"
+
with open(self.alert_filename, 'r', encoding='utf8') as f:
alert_text = f.read()
- if len(alert_text) == 0:
- raise AssertionError("-alertnotify did not warn of up-version blocks")
-
# Mine more up-version blocks, should not get more alerts:
self.nodes[1].generate(1)
self.sync_all()
diff --git a/test/functional/mempool_packages.py b/test/functional/mempool_packages.py
index 17e3a9a967..feec8a7fd9 100755
--- a/test/functional/mempool_packages.py
+++ b/test/functional/mempool_packages.py
@@ -101,6 +101,18 @@ class MempoolPackagesTest(BitcoinTestFramework):
assert_equal(mempool[x], v_descendants[x])
assert(chain[0] not in v_descendants.keys())
+ # Check that ancestor modified fees includes fee deltas from
+ # prioritisetransaction
+ self.nodes[0].prioritisetransaction(chain[0], 1000)
+ mempool = self.nodes[0].getrawmempool(True)
+ ancestor_fees = 0
+ for x in chain:
+ ancestor_fees += mempool[x]['fee']
+ assert_equal(mempool[x]['ancestorfees'], ancestor_fees * COIN + 1000)
+
+ # Undo the prioritisetransaction for later tests
+ self.nodes[0].prioritisetransaction(chain[0], -1000)
+
# Check that descendant modified fees includes fee deltas from
# prioritisetransaction
self.nodes[0].prioritisetransaction(chain[-1], 1000)
diff --git a/test/functional/net.py b/test/functional/net.py
new file mode 100755
index 0000000000..e9463c7dc7
--- /dev/null
+++ b/test/functional/net.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python3
+# Copyright (c) 2017 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+"""Test RPC calls related to net.
+
+Tests correspond to code in rpc/net.cpp.
+"""
+
+from decimal import Decimal
+import time
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.authproxy import JSONRPCException
+from test_framework.util import (
+ assert_equal,
+ start_nodes,
+ connect_nodes_bi,
+)
+
+
+class NetTest(BitcoinTestFramework):
+ def __init__(self):
+ super().__init__()
+ self.setup_clean_chain = True
+ self.num_nodes = 2
+
+ def setup_network(self):
+ self.nodes = start_nodes(self.num_nodes, self.options.tmpdir)
+ connect_nodes_bi(self.nodes, 0, 1)
+ self.is_network_split = False
+ self.sync_all()
+
+ def run_test(self):
+ assert_equal(self.nodes[0].getnetworkinfo()['networkactive'], True)
+ assert_equal(self.nodes[0].getnetworkinfo()['connections'], 2) # bilateral connection
+
+ self.nodes[0].setnetworkactive(False)
+ assert_equal(self.nodes[0].getnetworkinfo()['networkactive'], False)
+ timeout = 3
+ while self.nodes[0].getnetworkinfo()['connections'] != 0:
+ # Wait a bit for all sockets to close
+ assert timeout > 0, 'not all connections closed in time'
+ timeout -= 0.1
+ time.sleep(0.1)
+
+ self.nodes[0].setnetworkactive(True)
+ connect_nodes_bi(self.nodes, 0, 1)
+ assert_equal(self.nodes[0].getnetworkinfo()['networkactive'], True)
+ assert_equal(self.nodes[0].getnetworkinfo()['connections'], 2)
+
+
+if __name__ == '__main__':
+ NetTest().main()
diff --git a/test/functional/test_framework/mininode.py b/test/functional/test_framework/mininode.py
index ebb846a237..d57d46f2ff 100755
--- a/test/functional/test_framework/mininode.py
+++ b/test/functional/test_framework/mininode.py
@@ -1749,7 +1749,7 @@ class NodeConn(asyncore.dispatcher):
def send_message(self, message, pushbuf=False):
if self.state != "connected" and not pushbuf:
raise IOError('Not connected, no pushbuf')
- logger.debug("Send message to %s:%d: %s" % (self.dstaddr, self.dstport, repr(message)))
+ self._log_message("send", message)
command = message.command
data = message.serialize()
tmsg = self.MAGIC_BYTES[self.network]
@@ -1771,9 +1771,19 @@ class NodeConn(asyncore.dispatcher):
self.messagemap[b'ping'] = msg_ping_prebip31
if self.last_sent + 30 * 60 < time.time():
self.send_message(self.messagemap[b'ping']())
- logger.debug("Received message from %s:%d: %s" % (self.dstaddr, self.dstport, repr(message)))
+ self._log_message("receive", message)
self.cb.deliver(self, message)
+ def _log_message(self, direction, msg):
+ if direction == "send":
+ log_message = "Send message to "
+ elif direction == "receive":
+ log_message = "Received message from "
+ log_message += "%s:%d: %s" % (self.dstaddr, self.dstport, repr(msg)[:500])
+ if len(log_message) > 500:
+ log_message += "... (msg truncated)"
+ logger.debug(log_message)
+
def disconnect_node(self):
self.disconnect = True
diff --git a/test/functional/test_framework/util.py b/test/functional/test_framework/util.py
index 23ac324510..899b0b5a1b 100644
--- a/test/functional/test_framework/util.py
+++ b/test/functional/test_framework/util.py
@@ -315,7 +315,7 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary=
datadir = os.path.join(dirname, "node"+str(i))
if binary is None:
binary = os.getenv("BITCOIND", "bitcoind")
- args = [ binary, "-datadir="+datadir, "-server", "-keypool=1", "-discover=0", "-rest", "-logtimemicros", "-debug", "-mocktime="+str(get_mocktime()) ]
+ args = [binary, "-datadir=" + datadir, "-server", "-keypool=1", "-discover=0", "-rest", "-logtimemicros", "-debug", "-debugexclude=libevent", "-debugexclude=leveldb", "-mocktime=" + str(get_mocktime())]
if extra_args is not None: args.extend(extra_args)
bitcoind_processes[i] = subprocess.Popen(args, stderr=stderr)
logger.debug("initialize_chain: bitcoind started, waiting for RPC to come up")
diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py
index 37a2ab62a4..c0bbc623a8 100755
--- a/test/functional/test_runner.py
+++ b/test/functional/test_runner.py
@@ -25,6 +25,19 @@ import tempfile
import re
import logging
+# Formatting. Default colors to empty strings.
+BOLD, BLUE, RED, GREY = ("", ""), ("", ""), ("", ""), ("", "")
+TICK = "✓ "
+CROSS = "✖ "
+CIRCLE = "○ "
+if os.name == 'posix':
+ # primitive formatting on supported
+ # terminal via ANSI escape sequences:
+ BOLD = ('\033[0m', '\033[1m')
+ BLUE = ('\033[0m', '\033[0;34m')
+ RED = ('\033[0m', '\033[0;31m')
+ GREY = ('\033[0m', '\033[1;30m')
+
TEST_EXIT_PASSED = 0
TEST_EXIT_SKIPPED = 77
@@ -71,6 +84,7 @@ BASE_SCRIPTS= [
'decodescript.py',
'blockchain.py',
'disablewallet.py',
+ 'net.py',
'keypool.py',
'p2p-mempool.py',
'prioritise_transaction.py',
@@ -230,11 +244,6 @@ def main():
run_tests(test_list, config["environment"]["SRCDIR"], config["environment"]["BUILDDIR"], config["environment"]["EXEEXT"], args.jobs, args.coverage, passon_args)
def run_tests(test_list, src_dir, build_dir, exeext, jobs=1, enable_coverage=False, args=[]):
- BOLD = ("","")
- if os.name == 'posix':
- # primitive formatting on supported
- # terminal via ANSI escape sequences:
- BOLD = ('\033[0m', '\033[1m')
#Set env vars
if "BITCOIND" not in os.environ:
@@ -257,33 +266,26 @@ def run_tests(test_list, src_dir, build_dir, exeext, jobs=1, enable_coverage=Fal
subprocess.check_output([tests_dir + 'create_cache.py'] + flags)
#Run Tests
- all_passed = True
- time_sum = 0
- time0 = time.time()
-
job_queue = TestHandler(jobs, tests_dir, test_list, flags)
+ time0 = time.time()
+ test_results = []
max_len_name = len(max(test_list, key=len))
- results = "\n" + BOLD[1] + "%s | %s | %s\n\n" % ("TEST".ljust(max_len_name), "STATUS ", "DURATION") + BOLD[0]
+
for _ in range(len(test_list)):
- (name, stdout, stderr, status, duration) = job_queue.get_next()
- all_passed = all_passed and status != "Failed"
- time_sum += duration
-
- if status == "Passed":
- logging.debug("\n%s%s%s passed, Duration: %s s" % (BOLD[1], name, BOLD[0], duration))
- elif status == "Skipped":
- logging.debug("\n%s%s%s skipped" % (BOLD[1], name, BOLD[0]))
+ test_result, stdout, stderr = job_queue.get_next()
+ test_results.append(test_result)
+
+ if test_result.status == "Passed":
+ logging.debug("\n%s%s%s passed, Duration: %s s" % (BOLD[1], test_result.name, BOLD[0], test_result.time))
+ elif test_result.status == "Skipped":
+ logging.debug("\n%s%s%s skipped" % (BOLD[1], test_result.name, BOLD[0]))
else:
- print("\n%s%s%s failed, Duration: %s s\n" % (BOLD[1], name, BOLD[0], duration))
+ print("\n%s%s%s failed, Duration: %s s\n" % (BOLD[1], test_result.name, BOLD[0], test_result.time))
print(BOLD[1] + 'stdout:\n' + BOLD[0] + stdout + '\n')
print(BOLD[1] + 'stderr:\n' + BOLD[0] + stderr + '\n')
- results += "%s | %s | %s s\n" % (name.ljust(max_len_name), status.ljust(7), duration)
-
- results += BOLD[1] + "\n%s | %s | %s s (accumulated)" % ("ALL".ljust(max_len_name), str(all_passed).ljust(7), time_sum) + BOLD[0]
- print(results)
- print("\nRuntime: %s s" % (int(time.time() - time0)))
+ print_results(test_results, max_len_name, (int(time.time() - time0)))
if coverage:
coverage.report_rpc_coverage()
@@ -291,8 +293,28 @@ def run_tests(test_list, src_dir, build_dir, exeext, jobs=1, enable_coverage=Fal
logging.debug("Cleaning up coverage data")
coverage.cleanup()
+ all_passed = all(map(lambda test_result: test_result.status == "Passed", test_results))
+
sys.exit(not all_passed)
+def print_results(test_results, max_len_name, runtime):
+ results = "\n" + BOLD[1] + "%s | %s | %s\n\n" % ("TEST".ljust(max_len_name), "STATUS ", "DURATION") + BOLD[0]
+
+ test_results.sort(key=lambda result: result.name.lower())
+ all_passed = True
+ time_sum = 0
+
+ for test_result in test_results:
+ all_passed = all_passed and test_result.status != "Failed"
+ time_sum += test_result.time
+ test_result.padding = max_len_name
+ results += str(test_result)
+
+ status = TICK + "Passed" if all_passed else CROSS + "Failed"
+ results += BOLD[1] + "\n%s | %s | %s s (accumulated) \n" % ("ALL".ljust(max_len_name), status.ljust(9), time_sum) + BOLD[0]
+ results += "Runtime: %s s\n" % (runtime)
+ print(results)
+
class TestHandler:
"""
Trigger the testscrips passed in via the list.
@@ -347,9 +369,31 @@ class TestHandler:
status = "Failed"
self.num_running -= 1
self.jobs.remove(j)
- return name, stdout, stderr, status, int(time.time() - time0)
+
+ return TestResult(name, status, int(time.time() - time0)), stdout, stderr
print('.', end='', flush=True)
+class TestResult():
+ def __init__(self, name, status, time):
+ self.name = name
+ self.status = status
+ self.time = time
+ self.padding = 0
+
+ def __repr__(self):
+ if self.status == "Passed":
+ color = BLUE
+ glyph = TICK
+ elif self.status == "Failed":
+ color = RED
+ glyph = CROSS
+ elif self.status == "Skipped":
+ color = GREY
+ glyph = CIRCLE
+
+ return color[1] + "%s | %s%s | %s s\n" % (self.name.ljust(self.padding), glyph, self.status.ljust(7), self.time) + color[0]
+
+
def check_script_list(src_dir):
"""Check scripts directory.