Merge #17812: config, net, test: asmap feature refinements and functional tests
pull/764/head1ba3e1cc21
init: move asmap code earlier in init process (Jon Atack)5ba829e12e
rpc: fix getpeerinfo RPCResult `mapped_as` type (Jon Atack)c90b9a2399
net: extract conditional to bool CNetAddr::IsHeNet (Jon Atack)819fb5549b
logging: asmap logging and #include fixups (Jon Atack)dcaf543ba0
test: add functional test for an empty, unparsable asmap (Jon Atack)b8d0412b21
config: separate the asmap finding and parsing checks (Jon Atack)81c38a2497
config: enable passing -asmap an absolute file path (Jon Atack)fbe9b024f0
config: use default value in -asmap config (Jon Atack)08b992675c
test: add feature_asmap functional tests (Jon Atack) Pull request description: This PR builds on PR #16702 to add functional tests / sanity checks and user-facing refinements for passing `-asmap` to configure ASN-based IP bucketing in addrman. As per our review discussion in that PR, the idea here is to handle aspects like functional tests and config arg handling that can help the PR be merged while enabling the author to focus on the bucketing itself. - [x] add feature functional tests to verify node behaviour and debug log output when launching - `bitcoind` with no `-asmap` arg - `bitcoind -asmap=RELATIVE_FILENAME` to the unit test data skeleton asmap - `bitcoind -asmap` with no filename specified using the default asmap file - `bitcoind -asmap` with no filename specified and a missing default asmap file - [x] add the ability to pass absolute path filenames to the `-asmap` config arg in addition to datadir-relative path filenames as per https://github.com/bitcoin/bitcoin/pull/16702#discussion_r361300447, and add test coverage - [x] separate the asmap file finding and parsing checks, which allows adding tests for the case of a found but unparseable or empty asmap - [x] add test for an empty asmap - [x] various asmap fixups - [x] move the asmap init code earlier in the init process to provide immediate feedback when passing an `-asmap` config arg. This speeds up the `feature_asmap` functional test from 60 to 5 seconds! Credit to Wladimir J. van der Laan for the suggestion. ACKs for top commit: practicalswift: ACK1ba3e1cc21
-- diff looks correct fanquake: ACK1ba3e1cc21
Tree-SHA512: e9094460a597ac5597449acfe631c87b71d3ede6a12c7ae61b26d1161b3eefed8e7e25c4fb0505864cebd89300b7c4cf9378060aa9155441029315df15fa3283
commit
d0601e67f1
@ -0,0 +1,106 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2020 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 asmap config argument for ASN-based IP bucketing.
|
||||
|
||||
Verify node behaviour and debug log when launching bitcoind in these cases:
|
||||
|
||||
1. `bitcoind` with no -asmap arg, using /16 prefix for IP bucketing
|
||||
|
||||
2. `bitcoind -asmap=<absolute path>`, using the unit test skeleton asmap
|
||||
|
||||
3. `bitcoind -asmap=<relative path>`, using the unit test skeleton asmap
|
||||
|
||||
4. `bitcoind -asmap/-asmap=` with no file specified, using the default asmap
|
||||
|
||||
5. `bitcoind -asmap` with no file specified and a missing default asmap file
|
||||
|
||||
6. `bitcoind -asmap` with an empty (unparsable) default asmap file
|
||||
|
||||
The tests are order-independent.
|
||||
|
||||
"""
|
||||
import os
|
||||
import shutil
|
||||
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
|
||||
DEFAULT_ASMAP_FILENAME = 'ip_asn.map' # defined in src/init.cpp
|
||||
ASMAP = '../../src/test/data/asmap.raw' # path to unit test skeleton asmap
|
||||
VERSION = 'fec61fa21a9f46f3b17bdcd660d7f4cd90b966aad3aec593c99b35f0aca15853'
|
||||
|
||||
def expected_messages(filename):
|
||||
return ['Opened asmap file "{}" (59 bytes) from disk'.format(filename),
|
||||
'Using asmap version {} for IP bucketing'.format(VERSION)]
|
||||
|
||||
class AsmapTest(BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.setup_clean_chain = False
|
||||
self.num_nodes = 1
|
||||
|
||||
def test_without_asmap_arg(self):
|
||||
self.log.info('Test bitcoind with no -asmap arg passed')
|
||||
self.stop_node(0)
|
||||
with self.node.assert_debug_log(['Using /16 prefix for IP bucketing']):
|
||||
self.start_node(0)
|
||||
|
||||
def test_asmap_with_absolute_path(self):
|
||||
self.log.info('Test bitcoind -asmap=<absolute path>')
|
||||
self.stop_node(0)
|
||||
filename = os.path.join(self.datadir, 'my-map-file.map')
|
||||
shutil.copyfile(self.asmap_raw, filename)
|
||||
with self.node.assert_debug_log(expected_messages(filename)):
|
||||
self.start_node(0, ['-asmap={}'.format(filename)])
|
||||
os.remove(filename)
|
||||
|
||||
def test_asmap_with_relative_path(self):
|
||||
self.log.info('Test bitcoind -asmap=<relative path>')
|
||||
self.stop_node(0)
|
||||
name = 'ASN_map'
|
||||
filename = os.path.join(self.datadir, name)
|
||||
shutil.copyfile(self.asmap_raw, filename)
|
||||
with self.node.assert_debug_log(expected_messages(filename)):
|
||||
self.start_node(0, ['-asmap={}'.format(name)])
|
||||
os.remove(filename)
|
||||
|
||||
def test_default_asmap(self):
|
||||
shutil.copyfile(self.asmap_raw, self.default_asmap)
|
||||
for arg in ['-asmap', '-asmap=']:
|
||||
self.log.info('Test bitcoind {} (using default map file)'.format(arg))
|
||||
self.stop_node(0)
|
||||
with self.node.assert_debug_log(expected_messages(self.default_asmap)):
|
||||
self.start_node(0, [arg])
|
||||
os.remove(self.default_asmap)
|
||||
|
||||
def test_default_asmap_with_missing_file(self):
|
||||
self.log.info('Test bitcoind -asmap with missing default map file')
|
||||
self.stop_node(0)
|
||||
msg = "Error: Could not find asmap file \"{}\"".format(self.default_asmap)
|
||||
self.node.assert_start_raises_init_error(extra_args=['-asmap'], expected_msg=msg)
|
||||
|
||||
def test_empty_asmap(self):
|
||||
self.log.info('Test bitcoind -asmap with empty map file')
|
||||
self.stop_node(0)
|
||||
with open(self.default_asmap, "w", encoding="utf-8") as f:
|
||||
f.write("")
|
||||
msg = "Error: Could not parse asmap file \"{}\"".format(self.default_asmap)
|
||||
self.node.assert_start_raises_init_error(extra_args=['-asmap'], expected_msg=msg)
|
||||
os.remove(self.default_asmap)
|
||||
|
||||
def run_test(self):
|
||||
self.node = self.nodes[0]
|
||||
self.datadir = os.path.join(self.node.datadir, self.chain)
|
||||
self.default_asmap = os.path.join(self.datadir, DEFAULT_ASMAP_FILENAME)
|
||||
self.asmap_raw = os.path.join(os.path.dirname(os.path.realpath(__file__)), ASMAP)
|
||||
|
||||
self.test_without_asmap_arg()
|
||||
self.test_asmap_with_absolute_path()
|
||||
self.test_asmap_with_relative_path()
|
||||
self.test_default_asmap()
|
||||
self.test_default_asmap_with_missing_file()
|
||||
self.test_empty_asmap()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
AsmapTest().main()
|
Loading…
Reference in new issue