diff --git a/jmbase/jmbase/support.py b/jmbase/jmbase/support.py index 6097f0f..1fa191c 100644 --- a/jmbase/jmbase/support.py +++ b/jmbase/jmbase/support.py @@ -2,10 +2,12 @@ import logging, sys import binascii import random +import socket from getpass import getpass from os import path, environ from functools import wraps from optparse import IndentedHelpFormatter +from typing import List import urllib.parse as urlparse # JoinMarket version @@ -339,3 +341,18 @@ def random_insert(old, new): for n in new: insertion_index = random.randint(0, len(old)) old[:] = old[:insertion_index] + [n] + old[insertion_index:] + +def get_free_tcp_ports(num_ports: int) -> List[int]: + """ Get first free TCP ports you can bind to on localhost. + """ + sockets = [] + ports = [] + for i in range(num_ports): + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.bind(("", 0)) + s.listen(1) + ports.append(s.getsockname()[1]) + sockets.append(s) + for s in sockets: + s.close() + return ports diff --git a/jmclient/test/test_wallet_rpc.py b/jmclient/test/test_wallet_rpc.py index 9d14c5d..debfa54 100644 --- a/jmclient/test/test_wallet_rpc.py +++ b/jmclient/test/test_wallet_rpc.py @@ -8,6 +8,7 @@ from autobahn.twisted.websocket import WebSocketClientFactory, \ connectWS from jmbase import get_nontor_agent, hextobin, BytesProducer, get_log +from jmbase.support import get_free_tcp_ports from jmbitcoin import CTransaction from jmclient import (load_test_config, jm_single, SegwitWalletFidelityBonds, JMWalletDaemon, validate_address, start_reactor, @@ -39,10 +40,10 @@ class WalletRPCTestBase(object): wallet_structure = [1, 3, 0, 0, 0] # the mean amount of each deposit in the above indices, in btc mean_amt = 2.0 - # the port for the jmwallet daemon - dport = 28183 - # the port for the ws - wss_port = 28283 + # the port for the jmwallet daemon (auto) + dport = None + # the port for the ws (auto) + wss_port = None # how many different wallets we need num_wallet_files = 2 # wallet type @@ -59,6 +60,16 @@ class WalletRPCTestBase(object): # start the daemon; note we are using tcp connections # to avoid storing certs in the test env. # TODO change that. + if self.dport is None and self.wss_port is None: + free_ports = get_free_tcp_ports(2) + self.dport = free_ports[0] + self.wss_port = free_ports[1] + elif self.dport is None: + free_ports = get_free_tcp_ports(1) + self.dport = free_ports[0] + elif self.wss_port is None: + free_ports = get_free_tcp_ports(1) + self.wss_port = free_ports[0] self.daemon = JMWalletDaemonT(self.dport, self.wss_port, tls=False) self.daemon.auth_disabled = False # because we sync and start the wallet service manually here diff --git a/jmclient/test/test_websocket.py b/jmclient/test/test_websocket.py index 511732d..cf89bcf 100644 --- a/jmclient/test/test_websocket.py +++ b/jmclient/test/test_websocket.py @@ -9,6 +9,7 @@ from autobahn.twisted.websocket import WebSocketClientFactory, \ import jwt from jmbase import get_log, hextobin +from jmbase.support import get_free_tcp_ports from jmclient import (JmwalletdWebSocketServerFactory, JmwalletdWebSocketServerProtocol) from jmbitcoin import CTransaction @@ -60,10 +61,13 @@ class WebsocketTestBase(object): """ This tests that a websocket client can connect to our websocket subscription service """ - # the port for the ws - wss_port = 28283 + # the port for the ws (auto) + wss_port = None def setUp(self): + if self.wss_port is None: + free_ports = get_free_tcp_ports(1) + self.wss_port = free_ports[0] self.wss_url = "ws://127.0.0.1:" + str(self.wss_port) self.wss_factory = JmwalletdWebSocketServerFactory(self.wss_url) self.wss_factory.protocol = JmwalletdWebSocketServerProtocol