aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rwxr-xr-xtest/functional/feature_bip68_sequence.py4
-rwxr-xr-xtest/functional/feature_nulldummy.py2
-rwxr-xr-xtest/functional/interface_bitcoin_cli.py47
-rwxr-xr-xtest/functional/mempool_reorg.py26
-rwxr-xr-xtest/functional/p2p_compactblocks.py10
-rwxr-xr-xtest/functional/p2p_segwit.py10
-rwxr-xr-xtest/functional/test_framework/messages.py8
-rw-r--r--test/functional/test_framework/script.py8
-rwxr-xr-xtest/functional/test_framework/test_node.py2
-rwxr-xr-xtest/functional/wallet_importmulti.py9
-rwxr-xr-xtest/functional/wallet_txn_clone.py2
-rwxr-xr-xtest/fuzz/test_runner.py73
12 files changed, 142 insertions, 59 deletions
diff --git a/test/functional/feature_bip68_sequence.py b/test/functional/feature_bip68_sequence.py
index fe45ed34b5..549e8b2029 100755
--- a/test/functional/feature_bip68_sequence.py
+++ b/test/functional/feature_bip68_sequence.py
@@ -324,7 +324,7 @@ class BIP68Test(BitcoinTestFramework):
block.solve()
tip = block.sha256
height += 1
- self.nodes[0].submitblock(ToHex(block))
+ assert_equal(None if i == 1 else 'inconclusive', self.nodes[0].submitblock(ToHex(block)))
cur_time += 1
mempool = self.nodes[0].getrawmempool()
@@ -381,7 +381,7 @@ class BIP68Test(BitcoinTestFramework):
add_witness_commitment(block)
block.solve()
- self.nodes[0].submitblock(block.serialize().hex())
+ assert_equal(None, self.nodes[0].submitblock(block.serialize().hex()))
assert_equal(self.nodes[0].getbestblockhash(), block.hash)
def activateCSV(self):
diff --git a/test/functional/feature_nulldummy.py b/test/functional/feature_nulldummy.py
index 12471c5088..ff55cb76d9 100755
--- a/test/functional/feature_nulldummy.py
+++ b/test/functional/feature_nulldummy.py
@@ -111,7 +111,7 @@ class NULLDUMMYTest(BitcoinTestFramework):
witness and add_witness_commitment(block)
block.rehash()
block.solve()
- node.submitblock(block.serialize().hex())
+ assert_equal(None if accept else 'block-validation-failed', node.submitblock(block.serialize().hex()))
if (accept):
assert_equal(node.getbestblockhash(), block.hash)
self.tip = block.sha256
diff --git a/test/functional/interface_bitcoin_cli.py b/test/functional/interface_bitcoin_cli.py
index 2e80d7a248..1c94305220 100755
--- a/test/functional/interface_bitcoin_cli.py
+++ b/test/functional/interface_bitcoin_cli.py
@@ -3,6 +3,7 @@
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test bitcoin-cli"""
+from decimal import Decimal
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, assert_raises_process_error, get_auth_cookie
@@ -51,7 +52,7 @@ class TestBitcoinCli(BitcoinTestFramework):
self.log.info("Test -getinfo returns expected network and blockchain info")
if self.is_wallet_compiled():
self.nodes[0].encryptwallet(password)
- cli_get_info = self.nodes[0].cli().send_cli('-getinfo')
+ cli_get_info = self.nodes[0].cli('-getinfo').send_cli()
network_info = self.nodes[0].getnetworkinfo()
blockchain_info = self.nodes[0].getblockchaininfo()
assert_equal(cli_get_info['version'], network_info['version'])
@@ -72,12 +73,52 @@ class TestBitcoinCli(BitcoinTestFramework):
assert_equal(cli_get_info['paytxfee'], wallet_info['paytxfee'])
assert_equal(cli_get_info['relayfee'], network_info['relayfee'])
assert_equal(self.nodes[0].cli.getwalletinfo(), wallet_info)
+
+ # Setup to test -getinfo and -rpcwallet= with multiple wallets.
+ wallets = ['', 'Encrypted', 'secret']
+ amounts = [Decimal('59.999928'), Decimal(9), Decimal(31)]
+ self.nodes[0].createwallet(wallet_name=wallets[1])
+ self.nodes[0].createwallet(wallet_name=wallets[2])
+ w1 = self.nodes[0].get_wallet_rpc(wallets[0])
+ w2 = self.nodes[0].get_wallet_rpc(wallets[1])
+ w3 = self.nodes[0].get_wallet_rpc(wallets[2])
+ w1.walletpassphrase(password, self.rpc_timeout)
+ w1.sendtoaddress(w2.getnewaddress(), amounts[1])
+ w1.sendtoaddress(w3.getnewaddress(), amounts[2])
+
+ # Mine a block to confirm; adds a block reward (50 BTC) to the default wallet.
+ self.nodes[0].generate(1)
+
+ self.log.info("Test -getinfo with multiple wallets loaded returns no balance")
+ assert_equal(set(self.nodes[0].listwallets()), set(wallets))
+ assert 'balance' not in self.nodes[0].cli('-getinfo').send_cli().keys()
+
+ self.log.info("Test -getinfo with multiple wallets and -rpcwallet returns specified wallet balance")
+ for i in range(len(wallets)):
+ cli_get_info = self.nodes[0].cli('-getinfo').send_cli('-rpcwallet={}'.format(wallets[i]))
+ assert_equal(cli_get_info['balance'], amounts[i])
+
+ self.log.info("Test -getinfo with multiple wallets and -rpcwallet=non-existing-wallet returns no balance")
+ assert 'balance' not in self.nodes[0].cli('-getinfo').send_cli('-rpcwallet=does-not-exist').keys()
+
+ self.log.info("Test -getinfo after unloading all wallets except a non-default one returns its balance")
+ self.nodes[0].unloadwallet(wallets[0])
+ self.nodes[0].unloadwallet(wallets[2])
+ assert_equal(self.nodes[0].listwallets(), [wallets[1]])
+ assert_equal(self.nodes[0].cli('-getinfo').send_cli()['balance'], amounts[1])
+
+ self.log.info("Test -getinfo -rpcwallet=remaining-non-default-wallet returns its balance")
+ assert_equal(self.nodes[0].cli('-getinfo').send_cli('-rpcwallet={}'.format(wallets[1]))['balance'], amounts[1])
+
+ self.log.info("Test -getinfo with -rpcwallet=unloaded wallet returns no balance")
+ assert 'balance' not in self.nodes[0].cli('-getinfo').send_cli('-rpcwallet={}'.format(wallets[2])).keys()
else:
self.log.info("*** Wallet not compiled; cli getwalletinfo and -getinfo wallet tests skipped")
+ self.nodes[0].generate(1) # maintain block parity with the wallet_compiled conditional branch
self.log.info("Test -version with node stopped")
self.stop_node(0)
- cli_response = self.nodes[0].cli().send_cli('-version')
+ cli_response = self.nodes[0].cli('-version').send_cli()
assert "{} RPC client version".format(self.config['environment']['PACKAGE_NAME']) in cli_response
self.log.info("Test -rpcwait option successfully waits for RPC connection")
@@ -85,7 +126,7 @@ class TestBitcoinCli(BitcoinTestFramework):
self.nodes[0].wait_for_cookie_credentials() # ensure cookie file is available to avoid race condition
blocks = self.nodes[0].cli('-rpcwait').send_cli('getblockcount')
self.nodes[0].wait_for_rpc_connection()
- assert_equal(blocks, BLOCKS)
+ assert_equal(blocks, BLOCKS + 1)
if __name__ == '__main__':
diff --git a/test/functional/mempool_reorg.py b/test/functional/mempool_reorg.py
index 2d23343fd5..8e1f87e42c 100755
--- a/test/functional/mempool_reorg.py
+++ b/test/functional/mempool_reorg.py
@@ -16,6 +16,12 @@ from test_framework.util import assert_equal, assert_raises_rpc_error
class MempoolCoinbaseTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
+ self.extra_args = [
+ [
+ '-whitelist=noban@127.0.0.1', # immediate tx relay
+ ],
+ []
+ ]
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
@@ -38,17 +44,21 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
# 3. Indirect (coinbase and child both in chain) : spend_103 and spend_103_1
# Use invalidatblock to make all of the above coinbase spends invalid (immature coinbase),
# and make sure the mempool code behaves correctly.
- b = [ self.nodes[0].getblockhash(n) for n in range(101, 105) ]
- coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ]
+ b = [self.nodes[0].getblockhash(n) for n in range(101, 105)]
+ coinbase_txids = [self.nodes[0].getblock(h)['tx'][0] for h in b]
spend_101_raw = create_raw_transaction(self.nodes[0], coinbase_txids[1], node1_address, amount=49.99)
spend_102_raw = create_raw_transaction(self.nodes[0], coinbase_txids[2], node0_address, amount=49.99)
spend_103_raw = create_raw_transaction(self.nodes[0], coinbase_txids[3], node0_address, amount=49.99)
# Create a transaction which is time-locked to two blocks in the future
- timelock_tx = self.nodes[0].createrawtransaction([{"txid": coinbase_txids[0], "vout": 0}], {node0_address: 49.99})
- # Set the time lock
- timelock_tx = timelock_tx.replace("ffffffff", "11111191", 1)
- timelock_tx = timelock_tx[:-8] + hex(self.nodes[0].getblockcount() + 2)[2:] + "000000"
+ timelock_tx = self.nodes[0].createrawtransaction(
+ inputs=[{
+ "txid": coinbase_txids[0],
+ "vout": 0,
+ }],
+ outputs={node0_address: 49.99},
+ locktime=self.nodes[0].getblockcount() + 2,
+ )
timelock_tx = self.nodes[0].signrawtransactionwithwallet(timelock_tx)["hex"]
# This will raise an exception because the timelock transaction is too immature to spend
assert_raises_rpc_error(-26, "non-final", self.nodes[0].sendrawtransaction, timelock_tx)
@@ -67,6 +77,10 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
# Broadcast and mine 103_1:
spend_103_1_id = self.nodes[0].sendrawtransaction(spend_103_1_raw)
last_block = self.nodes[0].generate(1)
+ # Sync blocks, so that peer 1 gets the block before timelock_tx
+ # Otherwise, peer 1 would put the timelock_tx in recentRejects
+ self.sync_all()
+
# Time-locked transaction can now be spent
timelock_tx_id = self.nodes[0].sendrawtransaction(timelock_tx)
diff --git a/test/functional/p2p_compactblocks.py b/test/functional/p2p_compactblocks.py
index 7905cf5018..66e6f8c424 100755
--- a/test/functional/p2p_compactblocks.py
+++ b/test/functional/p2p_compactblocks.py
@@ -378,8 +378,6 @@ class CompactBlocksTest(BitcoinTestFramework):
# request
for announce in ["inv", "header"]:
block = self.build_block_on_tip(node, segwit=segwit)
- with mininode_lock:
- test_node.last_message.pop("getdata", None)
if announce == "inv":
test_node.send_message(msg_inv([CInv(2, block.sha256)]))
@@ -387,10 +385,8 @@ class CompactBlocksTest(BitcoinTestFramework):
test_node.send_header_for_blocks([block])
else:
test_node.send_header_for_blocks([block])
- wait_until(lambda: "getdata" in test_node.last_message, timeout=30, lock=mininode_lock)
- assert_equal(len(test_node.last_message["getdata"].inv), 1)
+ test_node.wait_for_getdata([block.sha256], timeout=30)
assert_equal(test_node.last_message["getdata"].inv[0].type, 4)
- assert_equal(test_node.last_message["getdata"].inv[0].hash, block.sha256)
# Send back a compactblock message that omits the coinbase
comp_block = HeaderAndShortIDs()
@@ -567,10 +563,8 @@ class CompactBlocksTest(BitcoinTestFramework):
assert_equal(int(node.getbestblockhash(), 16), block.hashPrevBlock)
# We should receive a getdata request
- wait_until(lambda: "getdata" in test_node.last_message, timeout=10, lock=mininode_lock)
- assert_equal(len(test_node.last_message["getdata"].inv), 1)
+ test_node.wait_for_getdata([block.sha256], timeout=10)
assert test_node.last_message["getdata"].inv[0].type == 2 or test_node.last_message["getdata"].inv[0].type == 2 | MSG_WITNESS_FLAG
- assert_equal(test_node.last_message["getdata"].inv[0].hash, block.sha256)
# Deliver the block
if version == 2:
diff --git a/test/functional/p2p_segwit.py b/test/functional/p2p_segwit.py
index fcf61eea3e..dbdce6552a 100755
--- a/test/functional/p2p_segwit.py
+++ b/test/functional/p2p_segwit.py
@@ -862,13 +862,13 @@ class SegWitTest(BitcoinTestFramework):
# We can't send over the p2p network, because this is too big to relay
# TODO: repeat this test with a block that can be relayed
- self.nodes[0].submitblock(block.serialize().hex())
+ assert_equal('bad-witness-nonce-size', self.nodes[0].submitblock(block.serialize().hex()))
assert self.nodes[0].getbestblockhash() != block.hash
block.vtx[0].wit.vtxinwit[0].scriptWitness.stack.pop()
assert get_virtual_size(block) < MAX_BLOCK_BASE_SIZE
- self.nodes[0].submitblock(block.serialize().hex())
+ assert_equal(None, self.nodes[0].submitblock(block.serialize().hex()))
assert self.nodes[0].getbestblockhash() == block.hash
@@ -975,14 +975,14 @@ class SegWitTest(BitcoinTestFramework):
add_witness_commitment(block, nonce=1)
block.vtx[0].wit = CTxWitness() # drop the nonce
block.solve()
- self.nodes[0].submitblock(block.serialize().hex())
+ assert_equal('bad-witness-merkle-match', self.nodes[0].submitblock(block.serialize().hex()))
assert self.nodes[0].getbestblockhash() != block.hash
# Now redo commitment with the standard nonce, but let bitcoind fill it in.
add_witness_commitment(block, nonce=0)
block.vtx[0].wit = CTxWitness()
block.solve()
- self.nodes[0].submitblock(block.serialize().hex())
+ assert_equal(None, self.nodes[0].submitblock(block.serialize().hex()))
assert_equal(self.nodes[0].getbestblockhash(), block.hash)
# This time, add a tx with non-empty witness, but don't supply
@@ -997,7 +997,7 @@ class SegWitTest(BitcoinTestFramework):
block_2.vtx[0].vout.pop()
block_2.vtx[0].wit = CTxWitness()
- self.nodes[0].submitblock(block_2.serialize().hex())
+ assert_equal('bad-txnmrklroot', self.nodes[0].submitblock(block_2.serialize().hex()))
# Tip should not advance!
assert self.nodes[0].getbestblockhash() != block_2.hash
diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py
index 33fba1c69a..4855f62a8f 100755
--- a/test/functional/test_framework/messages.py
+++ b/test/functional/test_framework/messages.py
@@ -603,16 +603,16 @@ class CBlock(CBlockHeader):
__slots__ = ("vtx",)
def __init__(self, header=None):
- super(CBlock, self).__init__(header)
+ super().__init__(header)
self.vtx = []
def deserialize(self, f):
- super(CBlock, self).deserialize(f)
+ super().deserialize(f)
self.vtx = deser_vector(f, CTransaction)
def serialize(self, with_witness=True):
r = b""
- r += super(CBlock, self).serialize()
+ r += super().serialize()
if with_witness:
r += ser_vector(self.vtx, "serialize_with_witness")
else:
@@ -752,7 +752,7 @@ class P2PHeaderAndShortIDs:
class P2PHeaderAndShortWitnessIDs(P2PHeaderAndShortIDs):
__slots__ = ()
def serialize(self):
- return super(P2PHeaderAndShortWitnessIDs, self).serialize(with_witness=True)
+ return super().serialize(with_witness=True)
# Calculate the BIP 152-compact blocks shortid for a given transaction hash
def calculate_shortid(k0, k1, tx_hash):
diff --git a/test/functional/test_framework/script.py b/test/functional/test_framework/script.py
index 016a2b4f0f..e475ed8596 100644
--- a/test/functional/test_framework/script.py
+++ b/test/functional/test_framework/script.py
@@ -97,7 +97,7 @@ class CScriptOp(int):
return _opcode_instances[n]
except IndexError:
assert len(_opcode_instances) == n
- _opcode_instances.append(super(CScriptOp, cls).__new__(cls, n))
+ _opcode_instances.append(super().__new__(cls, n))
return _opcode_instances[n]
# Populate opcode instance table
@@ -372,7 +372,7 @@ class CScriptTruncatedPushDataError(CScriptInvalidError):
"""Invalid pushdata due to truncation"""
def __init__(self, msg, data):
self.data = data
- super(CScriptTruncatedPushDataError, self).__init__(msg)
+ super().__init__(msg)
# This is used, eg, for blockchain heights in coinbase scripts (bip34)
@@ -458,14 +458,14 @@ class CScript(bytes):
def __new__(cls, value=b''):
if isinstance(value, bytes) or isinstance(value, bytearray):
- return super(CScript, cls).__new__(cls, value)
+ return super().__new__(cls, value)
else:
def coerce_iterable(iterable):
for instance in iterable:
yield cls.__coerce_instance(instance)
# Annoyingly on both python2 and python3 bytes.join() always
# returns a bytes instance even when subclassed.
- return super(CScript, cls).__new__(cls, b''.join(coerce_iterable(value)))
+ return super().__new__(cls, b''.join(coerce_iterable(value)))
def raw_iter(self):
"""Raw iteration
diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py
index de724407a0..c0075fd8ec 100755
--- a/test/functional/test_framework/test_node.py
+++ b/test/functional/test_framework/test_node.py
@@ -582,7 +582,7 @@ class TestNodeCLI():
if command is not None:
p_args += [command]
p_args += pos_args + named_args
- self.log.debug("Running bitcoin-cli command: %s" % command)
+ self.log.debug("Running bitcoin-cli {}".format(p_args[2:]))
process = subprocess.Popen(p_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
cli_stdout, cli_stderr = process.communicate(input=self.input)
returncode = process.poll()
diff --git a/test/functional/wallet_importmulti.py b/test/functional/wallet_importmulti.py
index f152fcd1a4..bd4fcdabcf 100755
--- a/test/functional/wallet_importmulti.py
+++ b/test/functional/wallet_importmulti.py
@@ -32,6 +32,7 @@ from test_framework.wallet_util import (
test_address,
)
+
class ImportMultiTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
@@ -51,7 +52,7 @@ class ImportMultiTest(BitcoinTestFramework):
result = self.nodes[1].importmulti([req])
observed_warnings = []
if 'warnings' in result[0]:
- observed_warnings = result[0]['warnings']
+ observed_warnings = result[0]['warnings']
assert_equal("\n".join(sorted(warnings)), "\n".join(sorted(observed_warnings)))
assert_equal(result[0]['success'], success)
if error_code is not None:
@@ -63,6 +64,7 @@ class ImportMultiTest(BitcoinTestFramework):
self.nodes[0].generate(1)
self.nodes[1].generate(1)
timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
+ self.nodes[1].syncwithvalidationinterfacequeue()
node0_address1 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
@@ -257,6 +259,7 @@ class ImportMultiTest(BitcoinTestFramework):
self.nodes[1].sendtoaddress(multisig.p2sh_addr, 10.00)
self.nodes[1].generate(1)
timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
+ self.nodes[1].syncwithvalidationinterfacequeue()
self.log.info("Should import a p2sh")
self.test_importmulti({"scriptPubKey": {"address": multisig.p2sh_addr},
@@ -277,6 +280,7 @@ class ImportMultiTest(BitcoinTestFramework):
self.nodes[1].sendtoaddress(multisig.p2sh_addr, 10.00)
self.nodes[1].generate(1)
timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
+ self.nodes[1].syncwithvalidationinterfacequeue()
self.log.info("Should import a p2sh with respective redeem script")
self.test_importmulti({"scriptPubKey": {"address": multisig.p2sh_addr},
@@ -297,6 +301,7 @@ class ImportMultiTest(BitcoinTestFramework):
self.nodes[1].sendtoaddress(multisig.p2sh_addr, 10.00)
self.nodes[1].generate(1)
timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
+ self.nodes[1].syncwithvalidationinterfacequeue()
self.log.info("Should import a p2sh with respective redeem script and private keys")
self.test_importmulti({"scriptPubKey": {"address": multisig.p2sh_addr},
@@ -322,6 +327,7 @@ class ImportMultiTest(BitcoinTestFramework):
self.nodes[1].sendtoaddress(multisig.p2sh_addr, 10.00)
self.nodes[1].generate(1)
timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
+ self.nodes[1].syncwithvalidationinterfacequeue()
self.log.info("Should import a p2sh with respective redeem script and private keys")
self.test_importmulti({"scriptPubKey": {"address": multisig.p2sh_addr},
@@ -851,5 +857,6 @@ class ImportMultiTest(BitcoinTestFramework):
addr = wrpc.getnewaddress('', 'bech32')
assert_equal(addr, addresses[i])
+
if __name__ == '__main__':
ImportMultiTest().main()
diff --git a/test/functional/wallet_txn_clone.py b/test/functional/wallet_txn_clone.py
index 99559090ee..ad23206c90 100755
--- a/test/functional/wallet_txn_clone.py
+++ b/test/functional/wallet_txn_clone.py
@@ -29,7 +29,7 @@ class TxnMallTest(BitcoinTestFramework):
def setup_network(self):
# Start with split network:
- super(TxnMallTest, self).setup_network()
+ super().setup_network()
disconnect_nodes(self.nodes[1], 2)
disconnect_nodes(self.nodes[2], 1)
diff --git a/test/fuzz/test_runner.py b/test/fuzz/test_runner.py
index 2455d3a3c3..e2454c4237 100755
--- a/test/fuzz/test_runner.py
+++ b/test/fuzz/test_runner.py
@@ -5,12 +5,13 @@
"""Run fuzz test targets.
"""
+from concurrent.futures import ThreadPoolExecutor, as_completed
import argparse
import configparser
+import logging
import os
-import sys
import subprocess
-import logging
+import sys
def main():
@@ -36,6 +37,12 @@ def main():
help="A comma-separated list of targets to exclude",
)
parser.add_argument(
+ '--par',
+ type=int,
+ default=4,
+ help='How many targets to merge or execute in parallel.',
+ )
+ parser.add_argument(
'seed_dir',
help='The seed corpus to run on (must contain subfolders for each fuzz target).',
)
@@ -124,25 +131,29 @@ def main():
logging.error("subprocess timed out: Currently only libFuzzer is supported")
sys.exit(1)
- if args.m_dir:
- merge_inputs(
+ with ThreadPoolExecutor(max_workers=args.par) as fuzz_pool:
+ if args.m_dir:
+ merge_inputs(
+ fuzz_pool=fuzz_pool,
+ corpus=args.seed_dir,
+ test_list=test_list_selection,
+ build_dir=config["environment"]["BUILDDIR"],
+ merge_dir=args.m_dir,
+ )
+ return
+
+ run_once(
+ fuzz_pool=fuzz_pool,
corpus=args.seed_dir,
test_list=test_list_selection,
build_dir=config["environment"]["BUILDDIR"],
- merge_dir=args.m_dir,
+ use_valgrind=args.valgrind,
)
- return
-
- run_once(
- corpus=args.seed_dir,
- test_list=test_list_selection,
- build_dir=config["environment"]["BUILDDIR"],
- use_valgrind=args.valgrind,
- )
-def merge_inputs(*, corpus, test_list, build_dir, merge_dir):
+def merge_inputs(*, fuzz_pool, corpus, test_list, build_dir, merge_dir):
logging.info("Merge the inputs in the passed dir into the seed_dir. Passed dir {}".format(merge_dir))
+ jobs = []
for t in test_list:
args = [
os.path.join(build_dir, 'src', 'test', 'fuzz', t),
@@ -153,12 +164,20 @@ def merge_inputs(*, corpus, test_list, build_dir, merge_dir):
]
os.makedirs(os.path.join(corpus, t), exist_ok=True)
os.makedirs(os.path.join(merge_dir, t), exist_ok=True)
- logging.debug('Run {} with args {}'.format(t, args))
- output = subprocess.run(args, check=True, stderr=subprocess.PIPE, universal_newlines=True).stderr
- logging.debug('Output: {}'.format(output))
+ def job(t, args):
+ output = 'Run {} with args {}\n'.format(t, " ".join(args))
+ output += subprocess.run(args, check=True, stderr=subprocess.PIPE, universal_newlines=True).stderr
+ logging.debug(output)
+
+ jobs.append(fuzz_pool.submit(job, t, args))
+
+ for future in as_completed(jobs):
+ future.result()
-def run_once(*, corpus, test_list, build_dir, use_valgrind):
+
+def run_once(*, fuzz_pool, corpus, test_list, build_dir, use_valgrind):
+ jobs = []
for t in test_list:
corpus_path = os.path.join(corpus, t)
os.makedirs(corpus_path, exist_ok=True)
@@ -169,10 +188,18 @@ def run_once(*, corpus, test_list, build_dir, use_valgrind):
]
if use_valgrind:
args = ['valgrind', '--quiet', '--error-exitcode=1'] + args
- logging.debug('Run {} with args {}'.format(t, args))
- result = subprocess.run(args, stderr=subprocess.PIPE, universal_newlines=True)
- output = result.stderr
- logging.debug('Output: {}'.format(output))
+
+ def job(t, args):
+ output = 'Run {} with args {}'.format(t, args)
+ result = subprocess.run(args, stderr=subprocess.PIPE, universal_newlines=True)
+ output += result.stderr
+ return output, result
+
+ jobs.append(fuzz_pool.submit(job, t, args))
+
+ for future in as_completed(jobs):
+ output, result = future.result()
+ logging.debug(output)
try:
result.check_returncode()
except subprocess.CalledProcessError as e:
@@ -180,7 +207,7 @@ def run_once(*, corpus, test_list, build_dir, use_valgrind):
logging.info(e.stdout)
if e.stderr:
logging.info(e.stderr)
- logging.info("Target \"{}\" failed with exit code {}: {}".format(t, e.returncode, " ".join(args)))
+ logging.info("Target \"{}\" failed with exit code {}".format(" ".join(result.args), e.returncode))
sys.exit(1)