diff --git a/tests/README.md b/tests/README.md index 35b78843..1dd7707d 100644 --- a/tests/README.md +++ b/tests/README.md @@ -11,13 +11,41 @@ and adapted. ### Test dependencies +**Windows** Checklist before running the functional tests: +* Install [`Git`](https://git-scm.com/download/win) +* Install [`VS Code`](https://code.visualstudio.com/Download) +* Install [`Python`](https://www.python.org/downloads/) +* Install [`Microsoft C++ Build tools`](https://visualstudio.microsoft.com/visual-cpp-build-tools/) +* Install [`Rust`](https://www.rust-lang.org/tools/install) +* Install [`Bitcoin Core`](https://bitcoin.org/en/download) + +*Please don't forget to add "C:\Program Files\Bitcoin\daemon\" in the path of the environment variables.* + Functional tests dependencies can be installed like for any Python project. ``` +(Unix) # Create a new virtual environment, preferably. python3 -m venv venv . venv/bin/activate # Get the deps pip install -r tests/requirements.txt +cargo build +``` + +``` +(Windows) +# Please ensure the execution policy for the current session is set to Remote Signed by entering the below command in Powershell. +Get-ExecutionPolicy +#If it is not set then enter: +Set-ExecutionPolicy -ExecutionPolicy RemoteSigned + +# Create a new virtual environment, preferably. +pip install virtualenv +virtualenv venv +.\venv\Scripts\activate +# Get the deps +pip install -r tests/requirements.txt +cargo build ``` ### Test modes @@ -48,6 +76,8 @@ servers: ``` # Adapt `-n`, `-v`, `timeout` and other environment variables to your needs pytest tests/ -vvv -n4 --ignore tests/servers/ +# To run a specific test: +pytest -vvv -k test_name ``` #### With the servers diff --git a/tests/fixtures.py b/tests/fixtures.py index e9d34659..ee058443 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -33,9 +33,10 @@ @pytest.fixture(scope="session") def test_base_dir(): - d = os.getenv("TEST_DIR", "/tmp") + temp = tempfile.gettempdir() + d = os.getenv("TEST_DIR", temp) - directory = tempfile.mkdtemp(prefix="revaultd-tests-", dir=d) + directory = tempfile.mkdtemp(prefix="revaultd-", dir=d) print("Running tests in {}".format(directory)) yield directory diff --git a/tests/test_framework/revaultd.py b/tests/test_framework/revaultd.py index 1fe1ec73..6c0f965e 100644 --- a/tests/test_framework/revaultd.py +++ b/tests/test_framework/revaultd.py @@ -45,9 +45,11 @@ def __init__( os.makedirs(self.datadir_with_network, exist_ok=True) self.conf_file = os.path.join(datadir, "config.toml") - self.cmd_line = [REVAULTD_PATH, "--conf", f"{self.conf_file}"] + self.cmd_line = [REVAULTD_PATH, "--conf", self.conf_file] socket_path = os.path.join(self.datadir_with_network, "revaultd_rpc") - self.rpc = UnixDomainSocketRpc(socket_path) + self.rpc = UnixDomainSocketRpc( + socket_path=socket_path, config_file=self.conf_file + ) noise_secret_file = os.path.join(self.datadir_with_network, "noise_secret") with open(noise_secret_file, "wb") as f: diff --git a/tests/test_framework/utils.py b/tests/test_framework/utils.py index 9d9d76fb..a901af38 100644 --- a/tests/test_framework/utils.py +++ b/tests/test_framework/utils.py @@ -9,6 +9,7 @@ import json import logging import os +import platform import re import socket import subprocess @@ -38,7 +39,9 @@ "..", "servers", "miradord", - "target/debug/miradord", + "target", + "debug", + "miradord", ) MIRADORD_PATH = os.getenv("MIRADORD_PATH", DEFAULT_MIRADORD_PATH) DEFAULT_COORD_PATH = os.path.join( @@ -46,7 +49,9 @@ "..", "servers", "coordinatord", - "target/debug/coordinatord", + "target", + "debug", + "coordinatord", ) COORDINATORD_PATH = os.getenv("COORDINATORD_PATH", DEFAULT_COORD_PATH) DEFAULT_COSIG_PATH = os.path.join( @@ -321,10 +326,11 @@ def __del__(self) -> None: class UnixDomainSocketRpc(object): - def __init__(self, socket_path, logger=logging): + def __init__(self, socket_path, config_file, logger=logging): self.socket_path = socket_path self.logger = logger self.next_id = 0 + self.config_file = config_file def _writeobj(self, sock, obj): s = json.dumps(obj, ensure_ascii=False) @@ -371,26 +377,42 @@ def wrapper(*args, **kwargs): def call(self, method, payload=[]): self.logger.debug("Calling %s with payload %r", method, payload) - # FIXME: we open a new socket for every readobj call... - sock = UnixSocket(self.socket_path) - msg = json.dumps( - { - "jsonrpc": "2.0", - "id": 0, - "method": method, - "params": payload, - } - ) - sock.sock.send(msg.encode()) - this_id = self.next_id - resp = self._readobj(sock) - - self.logger.debug("Received response for %s call: %r", method, resp) - if "id" in resp and resp["id"] != this_id: - raise ValueError( - "Malformed response, id is not {}: {}.".format(this_id, resp) + if platform.system() == "Windows": + bin = os.path.join( + os.path.dirname(__file__), "..", "..", "target", "debug", "revault-cli" + ) + cmd_line = [bin, "--conf", self.config_file, method, *payload] + resp = subprocess.check_output( + cmd_line, + shell=True, + universal_newlines=True, + text=True, + encoding="utf-8", ) - sock.close() + resp = json.loads(resp) + self.logger.debug(f"Received response for {method} call: {resp}") + + else: + # FIXME: we open a new socket for every readobj call... + sock = UnixSocket(self.socket_path) + msg = json.dumps( + { + "jsonrpc": "2.0", + "id": 0, + "method": method, + "params": payload, + } + ) + sock.sock.send(msg.encode()) + this_id = self.next_id + resp = self._readobj(sock) + + self.logger.debug("Received response for %s call: %r", method, resp) + if "id" in resp and resp["id"] != this_id: + raise ValueError( + "Malformed response, id is not {}: {}.".format(this_id, resp) + ) + sock.close() if not isinstance(resp, dict): raise ValueError(