Repository: bitcoin/bitcoin
File: test/functional/test_framework/test_node.py (Python)

Code before:
    def num_test_p2p_connections(self):
        """Return number of test framework p2p connections to the node."""
        return len([peer for peer in self.getpeerinfo() if peer['subver'] == P2P_SUBVERSION])

    def disconnect_p2ps(self):
        """Close all p2p connections to the node.
        The state of the peers (such as txrequests) may not be fully cleared
        yet, even after this method returns."""
        for p in self.p2ps:
            p.peer_disconnect()
        del self.p2ps[:]

        self.wait_until(lambda: self.num_test_p2p_connections() == 0)

    def bumpmocktime(self, seconds):
        """Fast forward using setmocktime to self.mocktime + seconds. Requires setmocktime to have
        been called at some point in the past."""
        assert self.mocktime
        self.mocktime += seconds
        self.setmocktime(self.mocktime)

    def wait_until(self, test_function, timeout=60, check_interval=0.05):
        return wait_until_helper_internal(test_function, timeout=timeout, timeout_factor=self.timeout_factor, check_interval=check_interval)

    def create_unnamed_wallet(self, **kwargs):
        """Create an unnamed wallet on this node since createwallet explicitly disallows that"""
        wallet_name = uuid.uuid4().hex
        self.createwallet(wallet_name=wallet_name, **kwargs)
        self.unloadwallet(wallet_name)
        shutil.move(self.wallets_path / wallet_name / "wallet.dat", self.wallets_path / "wallet.dat")
        shutil.rmtree(self.wallets_path / wallet_name)

class TestNodeCLIAttr:
    def __init__(self, cli, command):
        self.cli = cli
        self.command = command

    def __call__(self, *args, **kwargs):
        return self.cli.send_cli(self.command, *args, **kwargs)

    def get_request(self, *args, **kwargs):
        return lambda: self(*args, **kwargs)


def arg_to_cli(arg):
    if isinstance(arg, bool):
        return str(arg).lower()
    elif arg is None:
        return 'null'
    elif isinstance(arg, dict) or isinstance(arg, list) or isinstance(arg, tuple):
        return json.dumps(arg, default=serialization_fallback)

Review comment (suggestion):
In d65c0dad7a970d7e99bfea8fb77a2b5ba8f91e9b _wallet: disallow unnamed wallets in createwallet and restorewallet_:

```py
"""createwallet disallows empty wallet names, so create a temporary
named wallet and move its wallet.dat to the legacy unnamed-wallet
location."""
```

Code after:
        """Return number of test framework p2p connections to the node."""
        return len([peer for peer in self.getpeerinfo() if peer['subver'] == P2P_SUBVERSION])

    def disconnect_p2ps(self):
        """Close all p2p connections to the node.
        The state of the peers (such as txrequests) may not be fully cleared
        yet, even after this method returns."""
        for p in self.p2ps:
            p.peer_disconnect()
        del self.p2ps[:]

        self.wait_until(lambda: self.num_test_p2p_connections() == 0)

    def bumpmocktime(self, seconds):
        """Fast forward using setmocktime to self.mocktime + seconds. Requires setmocktime to have
        been called at some point in the past."""
        assert self.mocktime
        self.mocktime += seconds
        self.setmocktime(self.mocktime)

    def wait_until(self, test_function, timeout=60, check_interval=0.05):
        return wait_until_helper_internal(test_function, timeout=timeout, timeout_factor=self.timeout_factor, check_interval=check_interval)

class TestNodeCLIAttr:
    def __init__(self, cli, command):
        self.cli = cli
        self.command = command

    def __call__(self, *args, **kwargs):
        return self.cli.send_cli(self.command, *args, **kwargs)

    def get_request(self, *args, **kwargs):
        return lambda: self(*args, **kwargs)


def arg_to_cli(arg):
    if isinstance(arg, bool):
        return str(arg).lower()
    elif arg is None:
        return 'null'
    elif isinstance(arg, dict) or isinstance(arg, list) or isinstance(arg, tuple):
        return json.dumps(arg, default=serialization_fallback)
    else:
        return str(arg)


class TestNodeCLI():
    """Interface to bitcoin-cli for an individual node"""
    def __init__(self, binaries, datadir, rpc_timeout):
        self.options = []
        self.binaries = binaries