Skip to content

Commit eed8558

Browse files
committed
test(grafana): add e2e tests for monitoring metrics collection
Add end-to-end tests to verify the Grafana monitoring stack correctly extracts and displays basic PostgreSQL metrics: - tests/grafana/test_grafana_metrics.py: Python test that verifies: - Database size metric (pgwatch_db_size_size_b) - Transaction commit/rollback metrics - Tuple read/write metrics - Grafana datasources and dashboards are loaded - Dashboard queries execute correctly via Grafana proxy - tests/grafana/run_test.sh: Bash runner for local testing with optional CI mode that starts the monitoring stack - .gitlab-ci.yml: New grafana:e2e:dind job that runs on main and feature/* branches using Docker-in-Docker
1 parent de229f0 commit eed8558

File tree

3 files changed

+816
-0
lines changed

3 files changed

+816
-0
lines changed

.gitlab-ci.yml

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,81 @@ cli:node:full:dind:
326326
- if: '$CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH =~ /^feature\//'
327327
allow_failure: false
328328

329+
grafana:e2e:dind:
330+
stage: test
331+
image: python:3.11-alpine
332+
services:
333+
- name: docker:24-dind
334+
command: ["--tls=false"]
335+
variables:
336+
DOCKER_HOST: tcp://docker:2375
337+
DOCKER_TLS_CERTDIR: ""
338+
DOCKER_API_VERSION: "1.43"
339+
GIT_STRATEGY: fetch
340+
# Test configuration
341+
TARGET_DB_URL: "postgresql://postgres:postgres@localhost:55432/target_database"
342+
PROMETHEUS_URL: "http://localhost:59090"
343+
GRAFANA_URL: "http://localhost:3000"
344+
GRAFANA_USER: "monitor"
345+
GRAFANA_PASSWORD: "demo"
346+
COLLECTION_WAIT_SECONDS: "120"
347+
before_script:
348+
- apk add --no-cache bash curl docker-cli docker-compose postgresql-client
349+
- pip install --quiet psycopg requests
350+
- docker version
351+
script:
352+
- |
353+
set -euo pipefail
354+
echo "=== Starting monitoring stack ==="
355+
356+
# Use docker compose
357+
if command -v docker compose >/dev/null 2>&1; then
358+
COMPOSE_CMD="docker compose"
359+
else
360+
COMPOSE_CMD="docker-compose"
361+
fi
362+
363+
# Start core services
364+
$COMPOSE_CMD up -d target-db sink-postgres sink-prometheus pgwatch-prometheus grafana
365+
sleep 15
366+
367+
# Wait for services
368+
echo "Waiting for services to be ready..."
369+
timeout=120
370+
elapsed=0
371+
while [ $elapsed -lt $timeout ]; do
372+
if curl -sf http://localhost:59090/api/v1/status/config >/dev/null 2>&1 && \
373+
curl -sf -u monitor:demo http://localhost:3000/api/health >/dev/null 2>&1; then
374+
echo "Services are ready"
375+
break
376+
fi
377+
sleep 5
378+
elapsed=$((elapsed + 5))
379+
echo " Waiting... ($elapsed/${timeout}s)"
380+
done
381+
382+
# Wait for initial metric collection
383+
echo "Waiting 90s for initial metric collection..."
384+
sleep 90
385+
386+
# Run the e2e tests
387+
echo ""
388+
echo "=== Running Grafana e2e tests ==="
389+
python3 tests/grafana/test_grafana_metrics.py \
390+
--target-db-url "$TARGET_DB_URL" \
391+
--prometheus-url "$PROMETHEUS_URL" \
392+
--grafana-url "$GRAFANA_URL" \
393+
--grafana-user "$GRAFANA_USER" \
394+
--grafana-password "$GRAFANA_PASSWORD" \
395+
--collection-wait 60
396+
after_script:
397+
- docker ps -a || true
398+
- docker compose logs pgwatch-prometheus 2>/dev/null | tail -50 || true
399+
- docker compose down -v || true
400+
rules:
401+
- if: '$CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH =~ /^feature\//'
402+
allow_failure: false
403+
329404
cli:node:integration:
330405
stage: test
331406
image: node:20-alpine

tests/grafana/run_test.sh

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
#!/bin/bash
2+
# E2E test runner for Grafana monitoring metrics
3+
# This script starts the monitoring stack, waits for it to be healthy,
4+
# and runs the e2e tests to verify metrics are being collected and displayed.
5+
6+
set -e
7+
8+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
9+
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
10+
11+
# Default values (can be overridden by environment variables)
12+
TARGET_DB_URL="${TARGET_DB_URL:-postgresql://postgres:postgres@localhost:55432/target_database}"
13+
PROMETHEUS_URL="${PROMETHEUS_URL:-http://localhost:59090}"
14+
GRAFANA_URL="${GRAFANA_URL:-http://localhost:3000}"
15+
GRAFANA_USER="${GRAFANA_USER:-monitor}"
16+
GRAFANA_PASSWORD="${GRAFANA_PASSWORD:-demo}"
17+
TEST_DBNAME="${TEST_DBNAME:-target_database}"
18+
CLUSTER_NAME="${CLUSTER_NAME:-local}"
19+
NODE_NAME="${NODE_NAME:-node-01}"
20+
COLLECTION_WAIT="${COLLECTION_WAIT_SECONDS:-90}"
21+
STARTUP_WAIT="${STARTUP_WAIT_SECONDS:-120}"
22+
23+
# CI mode: if set, start services and wait for health
24+
CI_MODE="${CI_MODE:-false}"
25+
26+
echo "=========================================="
27+
echo "Grafana E2E Metrics Test"
28+
echo "=========================================="
29+
echo ""
30+
echo "Configuration:"
31+
echo " Target DB: $TARGET_DB_URL"
32+
echo " Prometheus URL: $PROMETHEUS_URL"
33+
echo " Grafana URL: $GRAFANA_URL"
34+
echo " Grafana User: $GRAFANA_USER"
35+
echo " Test DB Name: $TEST_DBNAME"
36+
echo " Cluster Name: $CLUSTER_NAME"
37+
echo " Node Name: $NODE_NAME"
38+
echo " Collection Wait: ${COLLECTION_WAIT}s"
39+
echo " CI Mode: $CI_MODE"
40+
echo ""
41+
42+
# Install Python dependencies if needed
43+
install_deps() {
44+
echo "Checking Python dependencies..."
45+
if ! python3 -c "import psycopg" 2>/dev/null; then
46+
echo "Installing psycopg..."
47+
pip3 install --quiet psycopg
48+
fi
49+
50+
if ! python3 -c "import requests" 2>/dev/null; then
51+
echo "Installing requests..."
52+
pip3 install --quiet requests
53+
fi
54+
echo "Dependencies OK"
55+
}
56+
57+
# Wait for a service to be ready
58+
wait_for_service() {
59+
local url="$1"
60+
local name="$2"
61+
local max_wait="${3:-60}"
62+
local auth="${4:-}"
63+
64+
echo "Waiting for $name at $url..."
65+
local waited=0
66+
while [ $waited -lt $max_wait ]; do
67+
if [ -n "$auth" ]; then
68+
if curl -sf -u "$auth" "$url" >/dev/null 2>&1; then
69+
echo " $name is ready"
70+
return 0
71+
fi
72+
else
73+
if curl -sf "$url" >/dev/null 2>&1; then
74+
echo " $name is ready"
75+
return 0
76+
fi
77+
fi
78+
sleep 5
79+
waited=$((waited + 5))
80+
echo " Waiting... ($waited/${max_wait}s)"
81+
done
82+
83+
echo " ERROR: $name not ready after ${max_wait}s"
84+
return 1
85+
}
86+
87+
# Start services in CI mode
88+
start_services() {
89+
echo ""
90+
echo "Starting monitoring stack..."
91+
cd "$PROJECT_ROOT"
92+
93+
# Use docker compose (v2) or docker-compose (v1)
94+
if command -v docker compose >/dev/null 2>&1; then
95+
COMPOSE_CMD="docker compose"
96+
else
97+
COMPOSE_CMD="docker-compose"
98+
fi
99+
100+
# Start core services needed for the test
101+
$COMPOSE_CMD up -d target-db sink-postgres sink-prometheus pgwatch-prometheus grafana
102+
103+
echo "Waiting for services to start..."
104+
sleep 10
105+
106+
# Wait for each service
107+
wait_for_service "http://localhost:59090/api/v1/status/config" "Prometheus" 60
108+
wait_for_service "http://localhost:3000/api/health" "Grafana" 60 "${GRAFANA_USER}:${GRAFANA_PASSWORD}"
109+
110+
# Wait for target-db to be ready
111+
echo "Waiting for target database..."
112+
local waited=0
113+
while [ $waited -lt 60 ]; do
114+
if PGPASSWORD=postgres psql -h localhost -p 55432 -U postgres -d target_database -c "SELECT 1" >/dev/null 2>&1; then
115+
echo " Target database is ready"
116+
break
117+
fi
118+
sleep 5
119+
waited=$((waited + 5))
120+
echo " Waiting... ($waited/60s)"
121+
done
122+
123+
echo ""
124+
echo "Waiting ${STARTUP_WAIT}s for initial metric collection..."
125+
sleep "$STARTUP_WAIT"
126+
}
127+
128+
# Cleanup in CI mode
129+
cleanup_services() {
130+
if [ "$CI_MODE" = "true" ]; then
131+
echo ""
132+
echo "Stopping services..."
133+
cd "$PROJECT_ROOT"
134+
if command -v docker compose >/dev/null 2>&1; then
135+
docker compose down -v || true
136+
else
137+
docker-compose down -v || true
138+
fi
139+
fi
140+
}
141+
142+
# Main execution
143+
main() {
144+
install_deps
145+
146+
if [ "$CI_MODE" = "true" ]; then
147+
start_services
148+
trap cleanup_services EXIT
149+
fi
150+
151+
echo ""
152+
echo "Running e2e tests..."
153+
echo ""
154+
155+
cd "$PROJECT_ROOT"
156+
python3 tests/grafana/test_grafana_metrics.py \
157+
--target-db-url "$TARGET_DB_URL" \
158+
--prometheus-url "$PROMETHEUS_URL" \
159+
--grafana-url "$GRAFANA_URL" \
160+
--grafana-user "$GRAFANA_USER" \
161+
--grafana-password "$GRAFANA_PASSWORD" \
162+
--test-dbname "$TEST_DBNAME" \
163+
--cluster-name "$CLUSTER_NAME" \
164+
--node-name "$NODE_NAME" \
165+
--collection-wait "$COLLECTION_WAIT"
166+
}
167+
168+
main "$@"

0 commit comments

Comments
 (0)