Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows functional test #268

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
5 changes: 3 additions & 2 deletions tests/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions tests/test_framework/revaultd.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
66 changes: 44 additions & 22 deletions tests/test_framework/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import json
import logging
import os
import platform
import re
import socket
import subprocess
Expand Down Expand Up @@ -38,15 +39,19 @@
"..",
"servers",
"miradord",
"target/debug/miradord",
"target",
"debug",
"miradord",
)
MIRADORD_PATH = os.getenv("MIRADORD_PATH", DEFAULT_MIRADORD_PATH)
DEFAULT_COORD_PATH = os.path.join(
os.path.dirname(__file__),
"..",
"servers",
"coordinatord",
"target/debug/coordinatord",
"target",
"debug",
"coordinatord",
)
COORDINATORD_PATH = os.getenv("COORDINATORD_PATH", DEFAULT_COORD_PATH)
DEFAULT_COSIG_PATH = os.path.join(
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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(
Expand Down