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.
        Use only after each p2p has sent a version message to ensure the wait works."""
        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):
        return wait_until_helper_internal(test_function, timeout=timeout, timeout_factor=self.timeout_factor)


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):
        return json.dumps(arg, default=serialization_fallback)
    else:
        return str(arg)


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

Review comment (suggestion):
f04529fc40f2f7c8e4e63d892cdcbe6c91dfbf96: Any reason to make this a member method, when it doesn't use any member fields? I'd say it would be fine to either make this a global, standalone, util function. Otherwise, if you want to make it a member, it would be good to also add it to the other classes, like test_framework. Then, always use it from the outer-most scope.

For example, it is a bit confusing to call `self.nodes[0].p2ps[0].ensure_for(...)`, when `self.ensure_for(...)` is identical, or even just `ensure_for(...)`.

Code after:

    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.
        Use only after each p2p has sent a version message to ensure the wait works."""
        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):
        return json.dumps(arg, default=serialization_fallback)
    else:
        return str(arg)


class TestNodeCLI():
    """Interface to bitcoin-cli for an individual node"""
    def __init__(self, binary, datadir):