Skip to content

Commit f6804e2

Browse files
committed
chore(aio): add simple testinfra test for postgrest
1 parent 86122e0 commit f6804e2

File tree

8 files changed

+140
-5
lines changed

8 files changed

+140
-5
lines changed

.github/workflows/testinfra.yml

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: Testinfra Integration Tests
2+
3+
on:
4+
pull_request:
5+
workflow_dispatch:
6+
7+
jobs:
8+
build:
9+
strategy:
10+
matrix:
11+
include:
12+
- runner: [self-hosted, X64]
13+
arch: amd64
14+
- runner: arm-runner
15+
arch: arm64
16+
runs-on: ${{ matrix.runner }}
17+
timeout-minutes: 30
18+
steps:
19+
- uses: actions/checkout@v3
20+
21+
- run: docker context create builders
22+
- uses: docker/setup-buildx-action@v3
23+
with:
24+
endpoint: builders
25+
26+
- name: Run aio integration tests
27+
run: |
28+
pip3 install docker pytest pytest-testinfra
29+
pytest -vv testinfra/test_all_in_one.py

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,8 @@ venv/
55
docker/cache/
66

77
ansible/image-manifest*.json
8+
9+
# Byte-compiled / optimized / DLL files
10+
__pycache__/
11+
*.py[cod]
12+
*$py.class

docker/all-in-one/README.md

+6-3
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,24 @@ All Supabase backend services bundled in a single Docker image for quick local t
55
## Build
66

77
```bash
8-
docker build . -t supabase/all-in-one
8+
# cwd: repo root
9+
docker build -f docker/all-in-one/Dockerfile -t supabase/all-in-one .
910
```
1011

1112
## Run
1213

1314
```bash
14-
docker run --rm \
15+
docker run --rm -it \
1516
-e POSTGRES_PASSWORD=postgres \
1617
-e JWT_SECRET=super-secret-jwt-token-with-at-least-32-characters-long \
1718
-e ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE \
1819
-e SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q \
1920
-e ADMIN_API_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoic3VwYWJhc2VfYWRtaW4iLCJpc3MiOiJzdXBhYmFzZS1kZW1vIiwiaWF0IjoxNjQxNzY5MjAwLCJleHAiOjE3OTk1MzU2MDB9.Y9mSNVuTw2TdfryoaqM5wySvwQemGGWfSe9ixcklVfM \
21+
-e DATA_VOLUME_MOUNTPOINT=/data \
22+
-e MACHINE_TYPE=shared_cpu_1x_512m \
2023
-p 5432:5432 \
2124
-p 8000:8000 \
22-
-it supabase/all-in-one
25+
supabase/all-in-one
2326
```
2427

2528
Use bind mount to start from an existing physical backup: `-v $(pwd)/data:/var/lib/postgresql/data`

docker/all-in-one/etc/gotrue.env

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
API_EXTERNAL_URL=api_external_url
12
GOTRUE_API_HOST=gotrue_api_host
23
GOTRUE_SITE_URL=gotrue_site_url
34
GOTRUE_DB_DRIVER=postgres

docker/all-in-one/healthcheck.sh

+4-2
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,7 @@ fail2ban-client status
3737
# prometheus exporter up
3838
curl -sSfI "http://localhost:$PGEXPORTER_PORT/metrics"
3939

40-
# vector is up
41-
curl -sSfI "http://localhost:$VECTOR_API_PORT/health"
40+
# vector is up (if starting logflare)
41+
if [ -n "${LOGFLARE_API_KEY:-}" ]; then
42+
curl -sSfI "http://localhost:$VECTOR_API_PORT/health"
43+
fi

docker/all-in-one/init/configure-gotrue.sh

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ touch /var/log/services/gotrue.log
55

66
/usr/local/bin/configure-shim.sh /dist/gotrue /opt/gotrue/gotrue
77

8+
sed -i "s|api_external_url|${API_EXTERNAL_URL:-http://localhost}|g" /etc/gotrue.env
89
sed -i "s|gotrue_api_host|${GOTRUE_API_HOST:-0.0.0.0}|g" /etc/gotrue.env
910
sed -i "s|gotrue_site_url|$GOTRUE_SITE_URL|g" /etc/gotrue.env
1011
sed -i "s|gotrue_jwt_secret|$JWT_SECRET|g" /etc/gotrue.env

testinfra/README.md

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Testinfra Integration Tests
2+
3+
## Prerequisites
4+
5+
```sh
6+
pip3 install docker pytest pytest-testinfra
7+
```
8+
9+
## Running locally
10+
11+
```sh
12+
# cwd: repo root
13+
# docker must be running
14+
pytest -vv testinfra/*.py
15+
```

testinfra/test_all_in_one.py

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
from docker.models.containers import Container
2+
from time import sleep
3+
from typing import cast
4+
import docker
5+
import pytest
6+
import subprocess
7+
import testinfra
8+
9+
all_in_one_image_tag = "supabase/all-in-one:testinfra"
10+
all_in_one_envs = {
11+
"POSTGRES_PASSWORD": "postgres",
12+
"JWT_SECRET": "super-secret-jwt-token-with-at-least-32-characters-long",
13+
"ANON_KEY": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE",
14+
"SERVICE_ROLE_KEY": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q",
15+
"ADMIN_API_KEY": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoic3VwYWJhc2VfYWRtaW4iLCJpc3MiOiJzdXBhYmFzZS1kZW1vIiwiaWF0IjoxNjQxNzY5MjAwLCJleHAiOjE3OTk1MzU2MDB9.Y9mSNVuTw2TdfryoaqM5wySvwQemGGWfSe9ixcklVfM",
16+
"DATA_VOLUME_MOUNTPOINT": "/data",
17+
"MACHINE_TYPE": "shared_cpu_1x_512m",
18+
}
19+
20+
# TODO: spin up local Logflare for Vector tests.
21+
22+
23+
# scope='session' uses the same container for all the tests;
24+
# scope='function' uses a new container per test function.
25+
@pytest.fixture(scope="session")
26+
def host(request):
27+
# We build the image with the Docker CLI in path instead of using docker-py
28+
# (official Docker SDK for Python) because the latter doesn't use BuildKit,
29+
# so things like `ARG TARGETARCH` don't work:
30+
# - https://github.com/docker/docker-py/issues/2230
31+
# - https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope
32+
subprocess.check_call(
33+
[
34+
"docker",
35+
"buildx",
36+
"build",
37+
"--file",
38+
"docker/all-in-one/Dockerfile",
39+
"--load",
40+
"--tag",
41+
all_in_one_image_tag,
42+
".",
43+
]
44+
)
45+
46+
docker_client = docker.from_env()
47+
container = cast(
48+
Container,
49+
docker_client.containers.run(
50+
all_in_one_image_tag,
51+
detach=True,
52+
environment=all_in_one_envs,
53+
ports={
54+
"5432/tcp": 5432,
55+
"8000/tcp": 8000,
56+
},
57+
),
58+
)
59+
60+
def get_health(container: Container) -> str:
61+
inspect_results = docker_client.api.inspect_container(container.name)
62+
return inspect_results["State"]["Health"]["Status"]
63+
64+
while True:
65+
health = get_health(container)
66+
if health == "healthy":
67+
break
68+
sleep(1)
69+
70+
# return a testinfra connection to the container
71+
yield testinfra.get_host("docker://" + cast(str, container.name))
72+
73+
# at the end of the test suite, destroy the container
74+
container.remove(v=True, force=True)
75+
76+
77+
def test_postgrest_service(host):
78+
postgrest = host.supervisor("services:postgrest")
79+
assert postgrest.is_running

0 commit comments

Comments
 (0)