feat: Add comprehensive test suite and cleanup step
All checks were successful
🚀 Docker Build and Push / build-and-push (15) (push) Successful in 5m54s
🚀 Docker Build and Push / build-and-push (16) (push) Successful in 6m0s
🚀 Docker Build and Push / build-and-push (17) (push) Successful in 5m56s
🚀 Docker Build and Push / build-and-push (18) (push) Successful in 6m4s

- Split validation into 4 granular CI steps (Config, Timescale, Vector, Hybrid)
- Added cleanup step for Docker images in CI
- Created SQL test scripts in tests/ for robustness
This commit is contained in:
2025-12-19 12:51:17 +01:00
parent 4ea4132653
commit df585b765a
5 changed files with 137 additions and 23 deletions

View File

@@ -51,30 +51,23 @@ jobs:
sleep 2 sleep 2
done done
- name: 🧪 Test image - Verify extensions - name: ⚙️ Setup Tests
run: | run: |
# Wait a bit more for init scripts to complete # Wait for valid startup
sleep 5 sleep 10
docker cp tests/ test-pg${{ matrix.pg_version }}:/tmp/tests/
# Check extensions are installed
RESULT=$(docker exec test-pg${{ matrix.pg_version }} psql -U postgres -t -c \ - name: "🧪 Test 1: Configuration"
"SELECT count(*) FROM pg_extension WHERE extname IN ('timescaledb', 'vector', 'vchord');") run: docker exec test-pg${{ matrix.pg_version }} psql -U postgres -f /tmp/tests/test-1-config.sql
EXTENSIONS=$(echo $RESULT | tr -d ' ') - name: "🧪 Test 2: TimescaleDB"
echo "Found $EXTENSIONS extensions" run: docker exec test-pg${{ matrix.pg_version }} psql -U postgres -f /tmp/tests/test-2-timescale.sql
if [ "$EXTENSIONS" -eq "3" ]; then - name: "🧪 Test 3: VectorChord"
echo "✅ All 3 extensions are installed!" run: docker exec test-pg${{ matrix.pg_version }} psql -U postgres -f /tmp/tests/test-3-vector.sql
else
echo "❌ Expected 3 extensions, found $EXTENSIONS" - name: "🧪 Test 4: Hybrid Scenarios"
docker exec test-pg${{ matrix.pg_version }} psql -U postgres -c \ run: docker exec test-pg${{ matrix.pg_version }} psql -U postgres -f /tmp/tests/test-4-hybrid.sql
"SELECT extname, extversion FROM pg_extension;"
exit 1
fi
# Show extension versions
docker exec test-pg${{ matrix.pg_version }} psql -U postgres -c \
"SELECT extname, extversion FROM pg_extension WHERE extname IN ('timescaledb', 'vector', 'vchord');"
- name: 🧹 Cleanup test container - name: 🧹 Cleanup test container
if: always() if: always()
@@ -101,4 +94,10 @@ jobs:
tags: | tags: |
gitea.killinger.fr/maxime.killinger/postgres-ts-vectors:latest gitea.killinger.fr/maxime.killinger/postgres-ts-vectors:latest
- name: 🧹 Cleanup Docker images
if: always()
run: |
docker rmi postgres-ts-vectors:pg${{ matrix.pg_version }}-test || true
docker image prune -f

17
tests/test-1-config.sql Normal file
View File

@@ -0,0 +1,17 @@
-- Test 1: Configuration
\set ON_ERROR_STOP on
SELECT version();
SELECT extname, extversion FROM pg_extension;
DO $$
DECLARE
preload_libs text;
BEGIN
SELECT setting INTO preload_libs FROM pg_settings WHERE name = 'shared_preload_libraries';
IF preload_libs NOT LIKE '%timescaledb%' OR preload_libs NOT LIKE '%vchord%' THEN
RAISE EXCEPTION 'Missing shared_preload_libraries config. Found: %', preload_libs;
END IF;
RAISE NOTICE 'Configuration Check: OK';
END
$$;

View File

@@ -0,0 +1,31 @@
-- Test 2: TimescaleDB
\set ON_ERROR_STOP on
DROP TABLE IF EXISTS sensors CASCADE;
CREATE TABLE sensors (
time TIMESTAMPTZ NOT NULL,
sensor_id INTEGER,
temperature DOUBLE PRECISION
);
-- Convert to hypertable
SELECT create_hypertable('sensors', 'time');
-- Insert data
INSERT INTO sensors (time, sensor_id, temperature) VALUES
(NOW(), 1, 20.0),
(NOW() + INTERVAL '1 hour', 1, 22.0);
-- Query data
DO $$
DECLARE
count int;
BEGIN
SELECT count(*) INTO count FROM sensors;
IF count != 2 THEN
RAISE EXCEPTION 'Hypertable insert failed';
END IF;
RAISE NOTICE 'TimescaleDB Check: OK';
END
$$;

27
tests/test-3-vector.sql Normal file
View File

@@ -0,0 +1,27 @@
-- Test 3: VectorChord / pgvector
\set ON_ERROR_STOP on
DROP TABLE IF EXISTS items;
CREATE TABLE items (
id bigserial PRIMARY KEY,
embedding vector(3)
);
INSERT INTO items (embedding) VALUES ('[1,2,3]'), ('[4,5,6]'), ('[1.1, 2.1, 3.1]');
-- Create VectorChord Index
CREATE INDEX ON items USING vchordrq (embedding vector_l2_ops);
-- Search
DO $$
DECLARE
closest_id int;
BEGIN
SELECT id INTO closest_id FROM items ORDER BY embedding <-> '[1,2,3]' LIMIT 1;
IF closest_id != 1 THEN
RAISE EXCEPTION 'Vector search failed. Expected ID 1, got %', closest_id;
END IF;
RAISE NOTICE 'Vector Check: OK';
END
$$;

40
tests/test-4-hybrid.sql Normal file
View File

@@ -0,0 +1,40 @@
-- Test 4: Hybrid (Timescale + Vector)
\set ON_ERROR_STOP on
DROP TABLE IF EXISTS hybrid_logs;
CREATE TABLE hybrid_logs (
time TIMESTAMPTZ NOT NULL,
msg TEXT,
vec vector(2)
);
SELECT create_hypertable('hybrid_logs', 'time');
INSERT INTO hybrid_logs (time, msg, vec) VALUES
(NOW(), 'log1', '[0,0]'),
(NOW() - INTERVAL '1 day', 'old_log', '[1,1]');
-- Index
CREATE INDEX ON hybrid_logs USING vchordrq (vec vector_l2_ops);
-- Hybrid Query
DO $$
DECLARE
res_count int;
BEGIN
-- Recent logs similar to [0.1, 0.1]
SELECT count(*) INTO res_count
FROM (
SELECT * FROM hybrid_logs
WHERE time > NOW() - INTERVAL '1 hour'
ORDER BY vec <-> '[0.1, 0.1]'
LIMIT 1
) sub;
IF res_count != 1 THEN
RAISE EXCEPTION 'Hybrid query failed';
END IF;
RAISE NOTICE 'Hybrid Check: OK';
END
$$;