Skip to content

Commit 0c73b91

Browse files
authored
test(e2e-http): parametrize compose runner by VECTOR_DB_TYPE / GRAPH_DB_TYPE + 2-combo CI matrix (#1740)
The compose runner ran a single fixed backend shape (Qdrant + PG-graph), so the HTTP E2E suite only proved one of the two production deployment shapes actually boots end-to-end. Connector-level swap correctness is covered by tests/integration/compat (matrixed in compat-test.yml), but that doesn't exercise the full FastAPI lifespan against the alternate backends. Changes: - runners/compose/up.sh: accept VECTOR_DB_TYPE (qdrant|pgvector) and GRAPH_DB_TYPE (postgresql|neo4j|nebula); validate, idempotently rewrite .env so the api container picks them up, activate matching --profile. Defaults preserve historical behavior (qdrant + postgresql). qdrant is always included in the service set because the api container's depends_on requires it healthy regardless of vector backend selection. - envs/docker.env.overrides: set PGVECTOR_DATABASE_URL to the same DSN as DATABASE_URL — required when VECTOR_DB_TYPE=pgvector, harmless when qdrant. - Makefile: add test-http-smoke-compose-{lite,full} shortcuts for the two shapes (Lite = pgvector + postgresql, Full = qdrant + neo4j). - .github/workflows/e2e-http-smoke.yml: convert e2e-http-smoke job to a fail-fast=false matrix over [lite, full]. Provider-aware job is unchanged (defaults), since LLM-provider coverage is orthogonal to graph backend choice and the matrix would double API-cost.
1 parent 20b9071 commit 0c73b91

4 files changed

Lines changed: 91 additions & 6 deletions

File tree

.github/workflows/e2e-http-smoke.yml

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,24 @@ jobs:
1515
timeout-minutes: 45
1616
permissions:
1717
contents: read
18+
strategy:
19+
fail-fast: false
20+
# Two deployment-shape combos. Connector-level "swap one DB" coverage
21+
# already lives in compat-test.yml's matrix (Qdrant/pgvector,
22+
# PG/Neo4j/Nebula); this matrix exists to prove the full HTTP stack
23+
# boots and runs end-to-end under each shape.
24+
matrix:
25+
combo:
26+
- name: lite
27+
vector: pgvector
28+
graph: postgresql
29+
- name: full
30+
vector: qdrant
31+
graph: neo4j
32+
name: e2e-http-smoke (${{ matrix.combo.name }})
33+
env:
34+
VECTOR_DB_TYPE: ${{ matrix.combo.vector }}
35+
GRAPH_DB_TYPE: ${{ matrix.combo.graph }}
1836
steps:
1937
- uses: actions/checkout@v4
2038

@@ -53,7 +71,7 @@ jobs:
5371
if: failure()
5472
uses: actions/upload-artifact@v4
5573
with:
56-
name: e2e-http-bootstrap-artifacts
74+
name: e2e-http-bootstrap-artifacts-${{ matrix.combo.name }}
5775
path: tests/e2e_http/bootstrap/.generated
5876
if-no-files-found: ignore
5977
# The bootstrap directory name starts with "." — actions/upload-artifact@v4
@@ -64,8 +82,8 @@ jobs:
6482
- name: Dump Compose diagnostics on failure
6583
if: failure()
6684
run: |
67-
docker compose -f docker-compose.yml ps || true
68-
docker compose -f docker-compose.yml logs --no-color api postgres redis qdrant es || true
85+
docker compose --profile neo4j --profile nebula -f docker-compose.yml ps || true
86+
docker compose --profile neo4j --profile nebula -f docker-compose.yml logs --no-color || true
6987
7088
- name: Stop Compose stack
7189
if: always()

Makefile

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ help:
5151
@printf " make test-http-full Run full HTTP suite against an existing target\n"
5252
@printf " make test-http-up-compose / test-http-down-compose\n"
5353
@printf " make test-http-smoke-compose / test-http-full-compose\n"
54+
@printf " make test-http-smoke-compose-lite / test-http-smoke-compose-full (DB-combo shortcuts)\n"
5455
@printf " make test-http-up-k8s / test-http-down-k8s\n"
5556
@printf " make test-http-smoke-k8s / test-http-full-k8s\n\n"
5657
@printf "Build / API\n"
@@ -204,6 +205,7 @@ add-license:
204205
.PHONY: test-all test-unit test-integration test-e2e test-e2e-perf \
205206
test-http-bootstrap test-http-smoke test-http-full \
206207
test-http-up-compose test-http-down-compose test-http-smoke-compose test-http-full-compose \
208+
test-http-smoke-compose-lite test-http-smoke-compose-full \
207209
test-http-up-k8s test-http-down-k8s test-http-smoke-k8s test-http-full-k8s
208210
test-all: test-unit test-integration test-e2e
209211

@@ -275,6 +277,18 @@ test-http-smoke-compose:
275277
test-http-full-compose:
276278
@./tests/e2e_http/scripts/run_compose_full.sh
277279

280+
# Backend-combo shortcuts. Lite = single-PG (pgvector + PG-graph) for the
281+
# ApeRAG-Lite deployment; Full = Qdrant vector + Neo4j graph for the
282+
# distributed deployment. Connector-level swap correctness is covered by
283+
# tests/integration/compat/* (see test-compat-graph / test-compat-vector).
284+
test-http-smoke-compose-lite:
285+
@VECTOR_DB_TYPE=pgvector GRAPH_DB_TYPE=postgresql \
286+
./tests/e2e_http/scripts/run_compose_smoke.sh
287+
288+
test-http-smoke-compose-full:
289+
@VECTOR_DB_TYPE=qdrant GRAPH_DB_TYPE=neo4j \
290+
./tests/e2e_http/scripts/run_compose_smoke.sh
291+
278292
test-http-up-k8s:
279293
@./tests/e2e_http/runners/k8s/up.sh
280294

envs/docker.env.overrides

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ NEBULA_USERNAME=root
88
NEBULA_PASSWORD=nebula
99
CELERY_BROKER_URL=redis://default:password@aperag-redis:6379/0
1010
DATABASE_URL="postgresql://postgres:postgres@aperag-postgres:5432/postgres"
11+
PGVECTOR_DATABASE_URL="postgresql://postgres:postgres@aperag-postgres:5432/postgres"
1112
VECTOR_DB_CONTEXT={"url":"http://aperag-qdrant", "port":6333, "distance":"Cosine", "timeout": 1000}
1213
ES_HOST=http://aperag-es:9200
1314
MEMORY_REDIS_URL=redis://default:password@aperag-redis:6379

tests/e2e_http/runners/compose/up.sh

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,71 @@ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." && pwd)"
55
cd "${ROOT_DIR}"
66

77
E2E_BASE_URL="${E2E_BASE_URL:-http://127.0.0.1:8000}"
8-
E2E_COMPOSE_SERVICES="${E2E_COMPOSE_SERVICES:-postgres redis qdrant es api}"
98
E2E_HEALTH_ATTEMPTS="${E2E_HEALTH_ATTEMPTS:-90}"
109
E2E_HEALTH_SLEEP_SECONDS="${E2E_HEALTH_SLEEP_SECONDS:-2}"
1110

11+
# Backend selection. Defaults preserve historical behavior (Qdrant + PG-graph).
12+
VECTOR_DB_TYPE="${VECTOR_DB_TYPE:-qdrant}"
13+
GRAPH_DB_TYPE="${GRAPH_DB_TYPE:-postgresql}"
14+
15+
case "${VECTOR_DB_TYPE}" in
16+
qdrant|pgvector) ;;
17+
*)
18+
echo "VECTOR_DB_TYPE must be one of: qdrant, pgvector (got '${VECTOR_DB_TYPE}')" >&2
19+
exit 2
20+
;;
21+
esac
22+
23+
case "${GRAPH_DB_TYPE}" in
24+
postgresql|neo4j|nebula) ;;
25+
*)
26+
echo "GRAPH_DB_TYPE must be one of: postgresql, neo4j, nebula (got '${GRAPH_DB_TYPE}')" >&2
27+
exit 2
28+
;;
29+
esac
30+
31+
# Always include qdrant in the service set: the api container's depends_on
32+
# requires it healthy regardless of which vector backend is selected. Leaving
33+
# qdrant idle in pgvector mode is cheap and avoids docker-compose surgery.
34+
DEFAULT_SERVICES="postgres redis qdrant es api"
35+
E2E_COMPOSE_SERVICES="${E2E_COMPOSE_SERVICES:-${DEFAULT_SERVICES}}"
36+
37+
profile_flags=()
38+
case "${GRAPH_DB_TYPE}" in
39+
neo4j) profile_flags=(--profile neo4j) ;;
40+
nebula) profile_flags=(--profile nebula) ;;
41+
esac
42+
1243
if [[ ! -f "${ROOT_DIR}/.env" ]]; then
1344
cp "${ROOT_DIR}/envs/env.template" "${ROOT_DIR}/.env"
1445
fi
1546

16-
docker compose -f docker-compose.yml up -d --build ${E2E_COMPOSE_SERVICES}
47+
# Idempotently set or append a KEY=VALUE in .env so the api container's
48+
# env_file pickup reflects the selected backends.
49+
update_env_var() {
50+
local key="$1"
51+
local value="$2"
52+
local file="${ROOT_DIR}/.env"
53+
if grep -qE "^${key}=" "${file}"; then
54+
awk -v k="${key}" -v v="${value}" 'BEGIN{FS=OFS="="} $1==k{print k"="v; next} {print}' \
55+
"${file}" > "${file}.tmp"
56+
mv "${file}.tmp" "${file}"
57+
else
58+
printf '\n%s=%s\n' "${key}" "${value}" >> "${file}"
59+
fi
60+
}
61+
62+
update_env_var VECTOR_DB_TYPE "${VECTOR_DB_TYPE}"
63+
update_env_var GRAPH_DB_TYPE "${GRAPH_DB_TYPE}"
64+
65+
echo "Compose runner starting (vector=${VECTOR_DB_TYPE}, graph=${GRAPH_DB_TYPE}, profiles='${profile_flags[*]:-}')"
66+
67+
# `${array[@]+"${array[@]}"}` is the set -u-safe expansion for an empty array.
68+
docker compose ${profile_flags[@]+"${profile_flags[@]}"} -f docker-compose.yml up -d --build ${E2E_COMPOSE_SERVICES}
1769

1870
for ((i = 1; i <= E2E_HEALTH_ATTEMPTS; i++)); do
1971
if curl --silent --show-error --fail "${E2E_BASE_URL}/health" >/dev/null; then
20-
echo "Compose runner ready at ${E2E_BASE_URL}"
72+
echo "Compose runner ready at ${E2E_BASE_URL} (vector=${VECTOR_DB_TYPE}, graph=${GRAPH_DB_TYPE})"
2173
exit 0
2274
fi
2375
sleep "${E2E_HEALTH_SLEEP_SECONDS}"

0 commit comments

Comments
 (0)