2016-05-06 11:23:48 +02:00
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
2014-10-23 03:48:19 +02:00
# Distributed under the MIT software license, see the accompanying
2014-04-07 17:29:36 +02:00
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
2020-06-11 10:39:04 +02:00
""" Test running dashd with the -rpcbind and -rpcallowip options. """
2014-04-07 17:29:36 +02:00
2017-03-24 13:57:36 +01:00
import sys
Merge #13054: tests: Enable automatic detection of undefined names in Python tests scripts. Remove wildcard imports.
68400d8b96 tests: Use explicit imports (practicalswift)
Pull request description:
Enable automatic detection of undefined names in Python tests scripts. Remove wildcard imports.
Wildcard imports make it unclear which names are present in the namespace, confusing both readers and many automated tools.
An additional benefit of not using wildcard imports in tests scripts is that readers of a test script then can infer the rough testing scope just by looking at the imports.
Before this commit:
```
$ contrib/devtools/lint-python.sh | head -10
./test/functional/feature_rbf.py:8:1: F403 'from test_framework.util import *' used; unable to detect undefined names
./test/functional/feature_rbf.py:9:1: F403 'from test_framework.script import *' used; unable to detect undefined names
./test/functional/feature_rbf.py:10:1: F403 'from test_framework.mininode import *' used; unable to detect undefined names
./test/functional/feature_rbf.py:15:12: F405 bytes_to_hex_str may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
./test/functional/feature_rbf.py:17:58: F405 CScript may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
./test/functional/feature_rbf.py:25:13: F405 COIN may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
./test/functional/feature_rbf.py:26:31: F405 satoshi_round may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
./test/functional/feature_rbf.py:26:60: F405 COIN may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
./test/functional/feature_rbf.py:30:41: F405 satoshi_round may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
./test/functional/feature_rbf.py:30:68: F405 COIN may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
$
```
After this commit:
```
$ contrib/devtools/lint-python.sh | head -10
$
```
Tree-SHA512: 3f826d39cffb6438388e5efcb20a9622ff8238247e882d68f7b38609877421b2a8e10e9229575f8eb6a8fa42dec4256986692e92922c86171f750a0e887438d9
2018-08-13 14:24:43 +02:00
from test_framework . netutil import all_interfaces , addr_to_hex , get_bind_addrs , test_ipv6_local
2017-06-02 11:32:55 +02:00
from test_framework . test_framework import BitcoinTestFramework , SkipTest
Merge #13054: tests: Enable automatic detection of undefined names in Python tests scripts. Remove wildcard imports.
68400d8b96 tests: Use explicit imports (practicalswift)
Pull request description:
Enable automatic detection of undefined names in Python tests scripts. Remove wildcard imports.
Wildcard imports make it unclear which names are present in the namespace, confusing both readers and many automated tools.
An additional benefit of not using wildcard imports in tests scripts is that readers of a test script then can infer the rough testing scope just by looking at the imports.
Before this commit:
```
$ contrib/devtools/lint-python.sh | head -10
./test/functional/feature_rbf.py:8:1: F403 'from test_framework.util import *' used; unable to detect undefined names
./test/functional/feature_rbf.py:9:1: F403 'from test_framework.script import *' used; unable to detect undefined names
./test/functional/feature_rbf.py:10:1: F403 'from test_framework.mininode import *' used; unable to detect undefined names
./test/functional/feature_rbf.py:15:12: F405 bytes_to_hex_str may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
./test/functional/feature_rbf.py:17:58: F405 CScript may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
./test/functional/feature_rbf.py:25:13: F405 COIN may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
./test/functional/feature_rbf.py:26:31: F405 satoshi_round may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
./test/functional/feature_rbf.py:26:60: F405 COIN may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
./test/functional/feature_rbf.py:30:41: F405 satoshi_round may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
./test/functional/feature_rbf.py:30:68: F405 COIN may be undefined, or defined from star imports: test_framework.mininode, test_framework.script, test_framework.util
$
```
After this commit:
```
$ contrib/devtools/lint-python.sh | head -10
$
```
Tree-SHA512: 3f826d39cffb6438388e5efcb20a9622ff8238247e882d68f7b38609877421b2a8e10e9229575f8eb6a8fa42dec4256986692e92922c86171f750a0e887438d9
2018-08-13 14:24:43 +02:00
from test_framework . util import assert_equal , assert_raises_rpc_error , get_rpc_proxy , rpc_port , rpc_url
2014-04-07 17:29:36 +02:00
2016-07-31 17:22:17 +02:00
class RPCBindTest ( BitcoinTestFramework ) :
2017-09-01 18:47:13 +02:00
def set_test_params ( self ) :
2016-07-31 17:22:17 +02:00
self . setup_clean_chain = True
2018-03-07 14:51:58 +01:00
self . bind_to_localhost_only = False
2016-07-31 17:22:17 +02:00
self . num_nodes = 1
2019-12-09 19:52:38 +01:00
self . supports_cli = False
2014-06-27 10:05:46 +02:00
2016-07-31 17:22:17 +02:00
def setup_network ( self ) :
2017-09-01 18:47:13 +02:00
self . add_nodes ( self . num_nodes , None )
2014-04-07 17:29:36 +02:00
2020-07-09 16:06:44 +02:00
def add_options ( self , parser ) :
2021-07-04 00:41:23 +02:00
parser . add_argument ( " --ipv4 " , action = ' store_true ' , dest = " run_ipv4 " , help = " Run ipv4 tests only " , default = False )
parser . add_argument ( " --ipv6 " , action = ' store_true ' , dest = " run_ipv6 " , help = " Run ipv6 tests only " , default = False )
parser . add_argument ( " --nonloopback " , action = ' store_true ' , dest = " run_nonloopback " , help = " Run non-loopback tests only " , default = False )
2020-07-09 16:06:44 +02:00
2016-07-31 17:22:17 +02:00
def run_bind_test ( self , allow_ips , connect_to , addresses , expected ) :
'''
Start a node with requested rpcallowip and rpcbind parameters ,
then try to connect , and check if the set of bound addresses
matches the expected set .
'''
2017-09-01 18:47:13 +02:00
self . log . info ( " Bind test for %s " % str ( addresses ) )
2016-07-31 17:22:17 +02:00
expected = [ ( addr_to_hex ( addr ) , port ) for ( addr , port ) in expected ]
base_args = [ ' -disablewallet ' , ' -nolisten ' ]
if allow_ips :
base_args + = [ ' -rpcallowip= ' + x for x in allow_ips ]
binds = [ ' -rpcbind= ' + addr for addr in addresses ]
2017-09-01 18:47:13 +02:00
self . nodes [ 0 ] . rpchost = connect_to
self . start_node ( 0 , base_args + binds )
2017-08-15 23:34:07 +02:00
pid = self . nodes [ 0 ] . process . pid
2017-02-23 10:40:44 +01:00
assert_equal ( set ( get_bind_addrs ( pid ) ) , set ( expected ) )
2017-06-02 12:08:48 +02:00
self . stop_nodes ( )
2016-07-31 17:22:17 +02:00
def run_allowip_test ( self , allow_ips , rpchost , rpcport ) :
'''
2016-09-26 15:02:55 +02:00
Start a node with rpcallow IP , and request getnetworkinfo
2016-07-31 17:22:17 +02:00
at a non - localhost IP .
'''
2017-09-01 18:47:13 +02:00
self . log . info ( " Allow IP test for %s : %d " % ( rpchost , rpcport ) )
2018-12-04 13:05:55 +01:00
node_args = \
[ ' -disablewallet ' , ' -nolisten ' ] + \
[ ' -rpcallowip= ' + x for x in allow_ips ] + \
[ ' -rpcbind= ' + addr for addr in [ ' 127.0.0.1 ' , " %s : %d " % ( rpchost , rpcport ) ] ] # Bind to localhost as well so start_nodes doesn't hang
2017-09-01 18:47:13 +02:00
self . nodes [ 0 ] . rpchost = None
2018-12-04 13:05:55 +01:00
self . start_nodes ( [ node_args ] )
2017-02-23 10:40:44 +01:00
# connect to node through non-loopback interface
2021-01-22 15:58:07 +01:00
node = get_rpc_proxy ( rpc_url ( self . nodes [ 0 ] . datadir , 0 , self . chain , " %s : %d " % ( rpchost , rpcport ) ) , 0 , coveragedir = self . options . coveragedir )
2017-02-23 10:40:44 +01:00
node . getnetworkinfo ( )
2017-06-02 12:08:48 +02:00
self . stop_nodes ( )
2016-07-31 17:22:17 +02:00
def run_test ( self ) :
# due to OS-specific network stats queries, this test works only on Linux
2020-07-09 16:06:44 +02:00
if sum ( [ self . options . run_ipv4 , self . options . run_ipv6 , self . options . run_nonloopback ] ) > 1 :
raise AssertionError ( " Only one of --ipv4, --ipv6 and --nonloopback can be set " )
self . log . info ( " Check for linux " )
2017-03-24 13:57:36 +01:00
if not sys . platform . startswith ( ' linux ' ) :
2020-07-09 16:06:44 +02:00
raise SkipTest ( " This test can only be run on linux. " )
self . log . info ( " Check for ipv6 " )
have_ipv6 = test_ipv6_local ( )
2019-01-02 14:15:50 +01:00
if not have_ipv6 and not ( self . options . run_ipv4 or self . options . run_nonloopback ) :
2020-07-09 16:06:44 +02:00
raise SkipTest ( " This test requires ipv6 support. " )
self . log . info ( " Check for non-loopback interface " )
self . non_loopback_ip = None
2016-07-31 17:22:17 +02:00
for name , ip in all_interfaces ( ) :
if ip != ' 127.0.0.1 ' :
2020-07-09 16:06:44 +02:00
self . non_loopback_ip = ip
2016-07-31 17:22:17 +02:00
break
2020-07-09 16:06:44 +02:00
if self . non_loopback_ip is None and self . options . run_nonloopback :
raise SkipTest ( " This test requires a non-loopback ip address. " )
self . defaultport = rpc_port ( 0 )
if not self . options . run_nonloopback :
self . _run_loopback_tests ( )
if not self . options . run_ipv4 and not self . options . run_ipv6 :
self . _run_nonloopback_tests ( )
def _run_loopback_tests ( self ) :
if self . options . run_ipv4 :
# check only IPv4 localhost (explicit)
self . run_bind_test ( [ ' 127.0.0.1 ' ] , ' 127.0.0.1 ' , [ ' 127.0.0.1 ' ] ,
[ ( ' 127.0.0.1 ' , self . defaultport ) ] )
# check only IPv4 localhost (explicit) with alternative port
self . run_bind_test ( [ ' 127.0.0.1 ' ] , ' 127.0.0.1:32171 ' , [ ' 127.0.0.1:32171 ' ] ,
[ ( ' 127.0.0.1 ' , 32171 ) ] )
# check only IPv4 localhost (explicit) with multiple alternative ports on same host
self . run_bind_test ( [ ' 127.0.0.1 ' ] , ' 127.0.0.1:32171 ' , [ ' 127.0.0.1:32171 ' , ' 127.0.0.1:32172 ' ] ,
[ ( ' 127.0.0.1 ' , 32171 ) , ( ' 127.0.0.1 ' , 32172 ) ] )
else :
# check default without rpcallowip (IPv4 and IPv6 localhost)
self . run_bind_test ( None , ' 127.0.0.1 ' , [ ] ,
[ ( ' 127.0.0.1 ' , self . defaultport ) , ( ' ::1 ' , self . defaultport ) ] )
2018-12-04 13:05:55 +01:00
# check default with rpcallowip (IPv4 and IPv6 localhost)
2020-07-09 16:06:44 +02:00
self . run_bind_test ( [ ' 127.0.0.1 ' ] , ' 127.0.0.1 ' , [ ] ,
2018-12-04 13:05:55 +01:00
[ ( ' 127.0.0.1 ' , self . defaultport ) , ( ' ::1 ' , self . defaultport ) ] )
2020-07-09 16:06:44 +02:00
# check only IPv6 localhost (explicit)
self . run_bind_test ( [ ' [::1] ' ] , ' [::1] ' , [ ' [::1] ' ] ,
[ ( ' ::1 ' , self . defaultport ) ] )
# check both IPv4 and IPv6 localhost (explicit)
self . run_bind_test ( [ ' 127.0.0.1 ' ] , ' 127.0.0.1 ' , [ ' 127.0.0.1 ' , ' [::1] ' ] ,
[ ( ' 127.0.0.1 ' , self . defaultport ) , ( ' ::1 ' , self . defaultport ) ] )
def _run_nonloopback_tests ( self ) :
self . log . info ( " Using interface %s for testing " % self . non_loopback_ip )
2016-07-31 17:22:17 +02:00
# check only non-loopback interface
2020-07-09 16:06:44 +02:00
self . run_bind_test ( [ self . non_loopback_ip ] , self . non_loopback_ip , [ self . non_loopback_ip ] ,
[ ( self . non_loopback_ip , self . defaultport ) ] )
2016-07-31 17:22:17 +02:00
# Check that with invalid rpcallowip, we are denied
2020-07-09 16:06:44 +02:00
self . run_allowip_test ( [ self . non_loopback_ip ] , self . non_loopback_ip , self . defaultport )
assert_raises_rpc_error ( - 342 , " non-JSON HTTP response with ' 403 Forbidden ' from server " , self . run_allowip_test , [ ' 1.1.1.1 ' ] , self . non_loopback_ip , self . defaultport )
2014-04-07 17:29:36 +02:00
if __name__ == ' __main__ ' :
2016-08-22 10:20:43 +02:00
RPCBindTest ( ) . main ( )