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

Run blackbox tests within a container. #389

Open
wants to merge 3 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
3 changes: 3 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
venv
target
.git
88 changes: 88 additions & 0 deletions tests/Containerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Build bitcoind.
# Copied (MIT License) from: https://github.com/kylemanna/docker-bitcoind/blob/5b51b7a168ae6d209b6b8afc91e3cc54ea5dab22/Dockerfile

# Smallest base image, latests stable image
# Alpine would be nice, but it's linked again musl and breaks the bitcoin core download binary
#FROM alpine:latest
FROM ubuntu:latest as builder_bitcoind

# Testing: gosu
#RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing/" >> /etc/apk/repositories \
# && apk add --update --no-cache gnupg gosu gcompat libgcc
RUN apt update \
&& apt install -y --no-install-recommends \
ca-certificates \
wget \
gnupg \
&& apt clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

ARG VERSION=22.0
ARG ARCH=x86_64
ARG BITCOIN_CORE_SIGNATURE=71A3B16735405025D447E8F274810B012346C9A6

# Don't use base image's bitcoin package for a few reasons:
# 1. Would need to use ppa/latest repo for the latest release.
# 2. Some package generates /etc/bitcoin.conf on install and that's dangerous to bake in with Docker Hub.
# 3. Verifying pkg signature from main website should inspire confidence and reduce chance of surprises.
# Instead fetch, verify, and extract to Docker image
RUN cd /tmp \
&& gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys ${BITCOIN_CORE_SIGNATURE} \
&& wget https://bitcoincore.org/bin/bitcoin-core-${VERSION}/SHA256SUMS.asc \
https://bitcoincore.org/bin/bitcoin-core-${VERSION}/SHA256SUMS \
https://bitcoincore.org/bin/bitcoin-core-${VERSION}/bitcoin-${VERSION}-${ARCH}-linux-gnu.tar.gz \
&& gpg --verify --status-fd 1 --verify SHA256SUMS.asc SHA256SUMS 2>/dev/null | grep "^\[GNUPG:\] VALIDSIG.*${BITCOIN_CORE_SIGNATURE}\$" \
&& sha256sum --ignore-missing --check SHA256SUMS \
&& tar -xzvf bitcoin-${VERSION}-${ARCH}-linux-gnu.tar.gz -C /opt \
&& ln -sv bitcoin-${VERSION} /opt/bitcoin \
&& /opt/bitcoin/bin/test_bitcoin --show_progress \
&& rm -v /opt/bitcoin/bin/test_bitcoin /opt/bitcoin/bin/bitcoin-qt

# Build revaultd and associated tools.
FROM docker.io/rust:1.58-buster as builder_revaultd
WORKDIR /revaultd
COPY . .
RUN cargo install --path . \
&& (cd contrib/tools/mscompiler && cargo install --path .) \
&& (cd tests/servers/coordinatord && cargo install --path .) \
&& (cd tests/servers/cosignerd && cargo install --path .) \
&& (cd tests/servers/miradord && cargo install --path .)

# Setup and run blackbox tests.
FROM ubuntu:latest
COPY --from=builder_revaultd /usr/local/cargo/bin/revaultd /usr/local/bin/revaultd
COPY --from=builder_revaultd /usr/local/cargo/bin/mscompiler /usr/local/bin/mscompiler
COPY --from=builder_revaultd /usr/local/cargo/bin/coordinatord /usr/local/bin/coordinatord
COPY --from=builder_revaultd /usr/local/cargo/bin/cosignerd /usr/local/bin/cosignerd
COPY --from=builder_revaultd /usr/local/cargo/bin/miradord /usr/local/bin/miradord

# Setup bitcoind.
ARG GROUP_ID=1000
ARG USER_ID=1000
RUN groupadd -g ${GROUP_ID} bitcoin \
&& useradd -u ${USER_ID} -g bitcoin -d /bitcoin bitcoin
COPY --from=builder_bitcoind /opt/ /opt/
RUN ln -sv /opt/bitcoin/bin/* /usr/local/bin
RUN apt update \
&& apt install -y --no-install-recommends gosu

# Setup revaultd integration tests.
WORKDIR /test-revaultd
COPY ./tests ./tests
RUN apt update \
&& DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends \
python3 python3-venv \
postgresql python3-psycopg2 libpq-dev \
build-essential libssl-dev libffi-dev python-dev
RUN python3 -m venv venv \
&& . venv/bin/activate \
&& pip install -r tests/requirements.txt

# Cleanup.
RUN apt clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

ENV REVAULTD_PATH=revaultd
ENV MSCOMPILER=mscompiler
ENV MIRADORD_PATH=miradord
ENV COORDINATORD_PATH=coordinatord
ENV COSIGNERD_PATH=cosignerd
47 changes: 47 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,53 @@ To run the server-requiring tests, pass the postgres credentials to the framewor
POSTGRES_USER="test" POSTGRES_PASS="test" TEST_DEBUG=1 pytest -vvv -n8 --timeout=1800
```

#### Using the containerized testing environment

Ensure that all git submodules are included in the repository:

```bash
git submodule update --init --recursive
```

Build the container image using podman (docker can also build the container):

```bash
podman build -t revault_blackbox_tests -f ./tests/Containerfile .
```

Start a podman pod to simplify inter-container communication:

```bash
podman pod create --name=revault_test_pod
```

Start postgres within the pod:

```bash
podman run --pod=revault_test_pod --rm -d --name postgres-coordinatord -e POSTGRES_PASSWORD=revault -e POSTGRES_USER=revault -e POSTGRES_DB=coordinator_db postgres:alpine
```

Run the test environment container within the pod:

```bash
podman run --pod=revault_test_pod -it revault_blackbox_tests /bin/bash
```

Activate the Python environment:

```bash
. venv/bin/activate
```

Run the tests:

```bash
pytest tests/ -vvv -n4 --ignore tests/servers/
```

```bash
POSTGRES_USER=revault POSTGRES_PASS=revault pytest -vvv -n8 --timeout=1800
```

### Tips and tricks
#### Logging
Expand Down
11 changes: 9 additions & 2 deletions tests/test_framework/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,8 @@ def get_participants(n_stk, n_man, n_stkman=0, with_cosigs=True):
)


def get_descriptors(stks_xpubs, cosigs_keys, mans_xpubs, mans_thresh, cpfp_xpubs, csv):
def build_mscompiler():
"""Build mscompiler tool."""
# tests/test_framework/../../contrib/tools/mscompiler/target/debug/mscompiler
mscompiler_dir = os.path.abspath(
os.path.join(
Expand All @@ -228,8 +229,14 @@ def get_descriptors(stks_xpubs, cosigs_keys, mans_xpubs, mans_thresh, cpfp_xpubs
raise e
finally:
os.chdir(cwd)
return os.path.join(mscompiler_dir, "target", "debug", "mscompiler")


def get_descriptors(stks_xpubs, cosigs_keys, mans_xpubs, mans_thresh, cpfp_xpubs, csv):
mscompiler_bin = (
os.getenv("MSCOMPILER") if "MSCOMPILER" in os.environ else build_mscompiler()
)

mscompiler_bin = os.path.join(mscompiler_dir, "target", "debug", "mscompiler")
cmd = [
mscompiler_bin,
f"{json.dumps(stks_xpubs)}",
Expand Down
1 change: 1 addition & 0 deletions tests/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,7 @@ def test_batched_cpfp_transaction(revault_network, bitcoind):
wait_for(lambda: len(man.rpc.listvaults(["spent"])["vaults"]) == len(vaults))


@pytest.mark.skipif(not POSTGRES_IS_SETUP, reason="Needs Postgres for servers db")
def test_rbfed_cpfp_transaction(revault_network, bitcoind):
"""We don't have explicit RBF logic, but since we signal for it we should
be able to replace a previous CPFP with a higher-fee, higher-feerate one.
Expand Down
2 changes: 2 additions & 0 deletions tests/test_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ def test_getrevocationtxs(revault_network, bitcoind):
assert txs == n.rpc.getrevocationtxs(deposit)


@pytest.mark.skipif(not POSTGRES_IS_SETUP, reason="Needs Postgres for servers db")
def test_getunvaulttx(revault_network):
revault_network.deploy(3, 1)
mans = revault_network.mans()
Expand Down Expand Up @@ -607,6 +608,7 @@ def test_revocationtxs(revault_network):
assert len(stks[0].rpc.listvaults(["securing"], [deposit])["vaults"]) == 1


@pytest.mark.skipif(not POSTGRES_IS_SETUP, reason="Needs Postgres for servers db")
def test_unvaulttx(revault_network):
"""Sanity checks for the unvaulttx command"""
revault_network.deploy(3, 1)
Expand Down