Skip to content

Commit 35587c3

Browse files
committed
Add in-repo API/e2e test suite (tests-e2e)
Migrate the liblogosdelivery API/wrapper pytest suite into tests-e2e/ and run it in CI (e2e-api-tests.yml) against the built library. Edge senders use the real lightpush path (relay=False).
1 parent 77cb8a6 commit 35587c3

44 files changed

Lines changed: 6173 additions & 4 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ jobs:
4646
- 'tools/**'
4747
- 'tests/all_tests_v2.nim'
4848
- 'tests/**'
49+
- 'tests-e2e/**'
4950
docker:
5051
- 'docker/**'
5152
@@ -205,12 +206,13 @@ jobs:
205206

206207
secrets: inherit
207208

208-
# Send API E2E tests run the wrapper suite against the liblogosdelivery.so
209-
# built by the `build` job (downloaded as the `liblogosdelivery` artifact).
210-
# Gated on `build`, so it is skipped on docker-only PRs where no lib is built.
209+
# Send API E2E tests run the in-repo tests-e2e/ wrapper suite against the
210+
# liblogosdelivery.so built by the `build` job (downloaded as the
211+
# `liblogosdelivery` artifact). Gated on `build`, so it is skipped on
212+
# docker-only PRs where no lib is built.
211213
send-api-e2e-tests:
212214
needs: build
213-
uses: logos-messaging/logos-delivery-interop-tests/.github/workflows/send_api_e2e_PR.yml@SMOKE_TEST_2026.06.25
215+
uses: ./.github/workflows/e2e-api-tests.yml
214216
secrets: inherit
215217

216218
lint:
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: e2e-api-tests
2+
3+
on:
4+
workflow_call:
5+
6+
jobs:
7+
api-e2e:
8+
runs-on: ubuntu-22.04
9+
timeout-minutes: 45
10+
name: api-e2e
11+
steps:
12+
- name: Checkout code
13+
uses: actions/checkout@v4
14+
15+
# Consumes the shared library built by ci.yml's `build` job (same run).
16+
- name: Download liblogosdelivery.so
17+
uses: actions/download-artifact@v4
18+
with:
19+
name: liblogosdelivery
20+
path: tests-e2e/vendor/logos-delivery-python-bindings/lib
21+
22+
- name: Set up Python
23+
uses: actions/setup-python@v5
24+
with:
25+
python-version: '3.12'
26+
cache: 'pip'
27+
cache-dependency-path: tests-e2e/requirements.txt
28+
29+
- name: Install Python deps
30+
run: pip install -r tests-e2e/requirements.txt
31+
32+
- name: Run API/e2e tests (non-docker subset)
33+
working-directory: tests-e2e
34+
run: pytest tests/wrappers_tests -m "not docker_required" --reruns 2

tests-e2e/README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# tests-e2e — logos-delivery API/e2e tests (Python)
2+
3+
End-to-end tests for `liblogosdelivery`, driven through the Python bindings (C-FFI).
4+
Migrated from [`logos-delivery-interop-tests`](https://github.com/logos-messaging/logos-delivery-interop-tests) (the wrapper / send-API suite).
5+
6+
## Layout
7+
8+
- `src/` — test framework (node wrappers, steps, helpers)
9+
- `tests/wrappers_tests/` — the API/e2e scenario tests (`test_s02…s31`)
10+
- `vendor/logos-delivery-python-bindings/waku/wrapper.py` — CFFI binding (`NodeWrapper`); it `dlopen`s `../lib/liblogosdelivery.so`
11+
12+
## Run locally
13+
14+
```bash
15+
# 1. Build the shared library and place it where the binding looks for it
16+
./tests-e2e/scripts/prepare_lib.sh
17+
18+
# 2. Python env + deps
19+
python -m venv .venv && source .venv/bin/activate
20+
pip install -r tests-e2e/requirements.txt
21+
22+
# 3. Run (from tests-e2e/)
23+
cd tests-e2e
24+
pytest tests/wrappers_tests -m "not docker_required" # 18 pure-binding tests
25+
pytest tests/wrappers_tests -m docker_required # 3 tests that also need a Docker nwaku peer (S19/S20/S31)
26+
```
27+
28+
## CI
29+
30+
`.github/workflows/e2e-api-tests.yml` (called from `ci.yml`, `needs: build`) downloads the
31+
`liblogosdelivery` artifact produced by the `build` job and runs the non-docker subset on every PR —
32+
so a protocol change and its e2e test land in the same PR.

tests-e2e/log/.gitkeep

Whitespace-only changes.

tests-e2e/pytest.ini

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[pytest]
2+
addopts = --instafail --tb=short --color=auto
3+
log_level = DEBUG
4+
log_cli = True
5+
norecursedirs =
6+
vendor
7+
nimbledeps
8+
*.egg-info
9+
log_file = log/test.log
10+
log_cli_format = %(asctime)s.%(msecs)03d %(levelname)s [%(name)s] %(message)s
11+
log_file_format = %(asctime)s.%(msecs)03d %(levelname)s [%(name)s] %(message)s
12+
timeout = 300
13+
markers =
14+
smoke: marks tests as smoke test (deselect with '-m "not smoke"')
15+
docker_required: test requires Docker nodes (WakuNode)

tests-e2e/requirements.txt

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
allure-pytest==2.13.2
2+
allure-python-commons==2.13.2
3+
attrs==23.1.0
4+
black==24.3.0
5+
certifi==2024.7.4
6+
cfgv==3.4.0
7+
charset-normalizer==3.3.2
8+
click==8.1.7
9+
distlib==0.3.8
10+
docker==7.0.0
11+
execnet==2.0.2
12+
filelock==3.13.1
13+
identify==2.5.33
14+
idna==3.7
15+
iniconfig==2.0.0
16+
marshmallow==3.20.1
17+
marshmallow-dataclass==8.6.0
18+
mypy-extensions==1.0.0
19+
nodeenv==1.8.0
20+
packaging==23.2
21+
pathspec==0.12.1
22+
platformdirs==4.1.0
23+
pluggy==1.3.0
24+
pre-commit==3.6.2
25+
pyright==1.1.352
26+
pytest==8.0.2
27+
pytest-instafail==0.5.0
28+
pytest-rerunfailures==13.0
29+
pytest-timeout==2.2.0
30+
pytest-xdist==3.5.0
31+
python-dotenv==1.0.1
32+
pytest-dependency==0.6.0
33+
PyYAML==6.0.1
34+
requests==2.31.0
35+
setuptools==70.0.0
36+
tenacity==8.2.3
37+
typeguard==4.1.5
38+
typing-inspect==0.9.0
39+
typing_extensions==4.9.0
40+
urllib3==2.2.2
41+
virtualenv==20.25.0
42+
pytest-shard==0.1.2
43+
result==0.17.0
44+
cffi

tests-e2e/scripts/prepare_lib.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env bash
2+
# Build liblogosdelivery from this repo and place it where the Python binding expects it.
3+
set -euo pipefail
4+
5+
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
6+
LIBDIR="$ROOT/tests-e2e/vendor/logos-delivery-python-bindings/lib"
7+
8+
cd "$ROOT"
9+
make update
10+
make V=1 liblogosdelivery
11+
12+
mkdir -p "$LIBDIR"
13+
if [ -f build/liblogosdelivery.so ]; then
14+
cp build/liblogosdelivery.so "$LIBDIR/liblogosdelivery.so"
15+
elif [ -f build/liblogosdelivery.dylib ]; then
16+
cp build/liblogosdelivery.dylib "$LIBDIR/liblogosdelivery.dylib"
17+
ln -sf liblogosdelivery.dylib "$LIBDIR/liblogosdelivery.so"
18+
else
19+
echo "ERROR: built library not found in build/" >&2
20+
exit 1
21+
fi
22+
echo "Placed liblogosdelivery in $LIBDIR"

tests-e2e/src/__init__.py

Whitespace-only changes.

tests-e2e/src/data_storage.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# We use this class for global variables
2+
class DS:
3+
waku_nodes = []

tests-e2e/src/env_vars.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import os
2+
from dotenv import load_dotenv
3+
4+
load_dotenv() # This will load environment variables from a .env file if it exists
5+
6+
7+
def get_env_var(var_name, default=None):
8+
env_var = os.getenv(var_name, default)
9+
if env_var in [None, ""]:
10+
print(f"{var_name} is not set; using default value: {default}")
11+
env_var = default
12+
print(f"{var_name}: {env_var}")
13+
return env_var
14+
15+
16+
# Configuration constants. Need to be upercase to appear in reports
17+
DEFAULT_NWAKU = "wakuorg/nwaku:latest"
18+
STRESS_ENABLED = False
19+
USE_WRAPPERS = True
20+
NODE_1 = get_env_var("NODE_1", DEFAULT_NWAKU)
21+
NODE_2 = get_env_var("NODE_2", DEFAULT_NWAKU)
22+
ADDITIONAL_NODES = get_env_var("ADDITIONAL_NODES", f"{DEFAULT_NWAKU},{DEFAULT_NWAKU},{DEFAULT_NWAKU}")
23+
# more nodes need to follow the NODE_X pattern
24+
DOCKER_LOG_DIR = get_env_var("DOCKER_LOG_DIR", "./log/docker")
25+
NETWORK_NAME = get_env_var("NETWORK_NAME", "waku")
26+
SUBNET = get_env_var("SUBNET", "172.18.0.0/16")
27+
IP_RANGE = get_env_var("IP_RANGE", "172.18.0.0/24")
28+
GATEWAY = get_env_var("GATEWAY", "172.18.0.1")
29+
RUNNING_IN_CI = get_env_var("CI")
30+
API_REQUEST_TIMEOUT = get_env_var("API_REQUEST_TIMEOUT", 20)
31+
RLN_CREDENTIALS = get_env_var("RLN_CREDENTIALS")
32+
PG_USER = get_env_var("POSTGRES_USER", "postgres")
33+
PG_PASS = get_env_var("POSTGRES_PASSWORD", "test123")
34+
35+
# example for .env file
36+
# RLN_CREDENTIALS = {"rln-relay-cred-password": "password", "rln-relay-eth-client-address": "https://rpc.sepolia.linea.build", "rln-relay-eth-contract-address": "0xB9cd878C90E49F797B4431fBF4fb333108CB90e6", "rln-relay-eth-private-key-1": "", "rln-relay-eth-private-key-2": "", "rln-relay-eth-private-key-3": "", "rln-relay-eth-private-key-4": "", "rln-relay-eth-private-key-5": ""}

0 commit comments

Comments
 (0)