Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions tasks/test-pgtap.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#!/usr/bin/env bash
#MISE description="Run pgTAP tests with pg_prove"
#USAGE flag "--postgres <version>" help="Run tests for specified Postgres version" default="17" {
#USAGE choices "14" "15" "16" "17"
#USAGE }

set -euo pipefail

POSTGRES_VERSION=${usage_postgres}

connection_url=postgresql://${POSTGRES_USER:-$USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}
container_name=postgres-${POSTGRES_VERSION}

fail_if_postgres_not_running () {
containers=$(docker ps --filter "name=^${container_name}$" --quiet)
if [ -z "${containers}" ]; then
echo "error: Docker container for PostgreSQL is not running"
echo "error: Try running 'mise run postgres:up ${container_name}' to start the container"
exit 65
fi
}

# setup
fail_if_postgres_not_running
mise run build --force
mise run reset --force --postgres ${POSTGRES_VERSION}

echo
echo '###############################################'
echo '# Installing release/cipherstash-encrypt.sql'
echo '###############################################'
echo

# Install EQL
cat release/cipherstash-encrypt.sql | docker exec -i ${container_name} psql ${connection_url} -f-

# Install test helpers
cat tests/test_helpers.sql | docker exec -i ${container_name} psql ${connection_url} -f-
cat tests/ore.sql | docker exec -i ${container_name} psql ${connection_url} -f-
cat tests/ste_vec.sql | docker exec -i ${container_name} psql ${connection_url} -f-

echo
echo '###############################################'
echo '# Installing pgTAP'
echo '###############################################'
echo

# Install pgTAP
cat tests/install_pgtap.sql | docker exec -i ${container_name} psql ${connection_url} -f-

echo
echo '###############################################'
echo '# Running pgTAP structure tests'
echo '###############################################'
echo

# Run structure tests with pg_prove
if [ -d "tests/pgtap/structure" ]; then
docker exec -i ${container_name} pg_prove -v -d ${connection_url} /tests/pgtap/structure/*.sql 2>/dev/null || {
# Fallback: copy tests to container and run
for test_file in tests/pgtap/structure/*.sql; do
if [ -f "$test_file" ]; then
echo "Running: $test_file"
cat "$test_file" | docker exec -i ${container_name} psql ${connection_url} -f-
fi
done
}
fi

echo
echo '###############################################'
echo '# Running pgTAP functionality tests'
echo '###############################################'
echo

# Run functionality tests with pg_prove
if [ -d "tests/pgtap/functionality" ]; then
docker exec -i ${container_name} pg_prove -v -d ${connection_url} /tests/pgtap/functionality/*.sql 2>/dev/null || {
# Fallback: copy tests to container and run
for test_file in tests/pgtap/functionality/*.sql; do
if [ -f "$test_file" ]; then
echo "Running: $test_file"
cat "$test_file" | docker exec -i ${container_name} psql ${connection_url} -f-
fi
done
}
fi

echo
echo '###############################################'
echo "# ✅ ALL PGTAP TESTS PASSED "
echo '###############################################'
echo
16 changes: 16 additions & 0 deletions tests/Dockerfile.pgtap
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
ARG POSTGRES_VERSION=17
FROM postgres:${POSTGRES_VERSION}

# Install build dependencies and pgTAP
RUN apt-get update && apt-get install -y \
build-essential \
postgresql-server-dev-${PG_MAJOR} \
git \
&& rm -rf /var/lib/apt/lists/*

# Install pgTAP
RUN git clone https://github.com/theory/pgtap.git /tmp/pgtap \
&& cd /tmp/pgtap \
&& make \
&& make install \
&& rm -rf /tmp/pgtap
30 changes: 25 additions & 5 deletions tests/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
services:
postgres: &postgres
container_name: postgres
image: postgres
build:
context: .
dockerfile: Dockerfile.pgtap
args:
POSTGRES_VERSION: "17"
ports:
- 7432:7432
environment:
Expand All @@ -26,24 +30,40 @@ services:

postgres-17:
<<: *postgres
image: postgres:17
build:
context: .
dockerfile: Dockerfile.pgtap
args:
POSTGRES_VERSION: "17"
container_name: postgres-17
#volumes: # uncomment if you need to inspect the container contents
#- ./pg/data-17:/var/lib/postgresql/data

postgres-16:
<<: *postgres
image: postgres:16
build:
context: .
dockerfile: Dockerfile.pgtap
args:
POSTGRES_VERSION: "16"
container_name: postgres-16

postgres-15:
<<: *postgres
image: postgres:15
build:
context: .
dockerfile: Dockerfile.pgtap
args:
POSTGRES_VERSION: "15"
container_name: postgres-15

postgres-14:
<<: *postgres
image: postgres:14
build:
context: .
dockerfile: Dockerfile.pgtap
args:
POSTGRES_VERSION: "14"
container_name: postgres-14

networks:
Expand Down
5 changes: 5 additions & 0 deletions tests/install_pgtap.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- Install pgTAP extension for testing
CREATE EXTENSION IF NOT EXISTS pgtap;

-- Verify pgTAP installation
SELECT * FROM pg_available_extensions WHERE name = 'pgtap';
167 changes: 167 additions & 0 deletions tests/pgtap/functionality/comparison_test.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
-- Test EQL comparison operators
-- Tests <, <=, >, >= operators for encrypted data with ORE indexes

BEGIN;

-- Plan: count of tests to run
SELECT plan(12);

-- Setup test data
SELECT lives_ok(
'SELECT create_table_with_encrypted()',
'Should create table with encrypted column'
);

SELECT lives_ok(
'SELECT seed_encrypted_json()',
'Should seed encrypted data'
);

-- Test 1: Less than operator with ORE index
DO $$
DECLARE
e eql_v2_encrypted;
BEGIN
e := create_encrypted_ore_json(42);

PERFORM ok(
(SELECT count(*) FROM encrypted WHERE e < e) >= 1,
'Less than operator < works with ORE encrypted data'
);
END;
$$ LANGUAGE plpgsql;

-- Test 2: Less than or equal operator with ORE index
DO $$
DECLARE
e eql_v2_encrypted;
BEGIN
e := create_encrypted_ore_json(42);

PERFORM ok(
(SELECT count(*) FROM encrypted WHERE e <= e) >= 1,
'Less than or equal operator <= works with ORE encrypted data'
);
END;
$$ LANGUAGE plpgsql;

-- Test 3: Greater than operator with ORE index
DO $$
DECLARE
e eql_v2_encrypted;
BEGIN
e := create_encrypted_ore_json(1);

PERFORM ok(
(SELECT count(*) FROM encrypted WHERE e > e) >= 1,
'Greater than operator > works with ORE encrypted data'
);
END;
$$ LANGUAGE plpgsql;

-- Test 4: Greater than or equal operator with ORE index
DO $$
DECLARE
e eql_v2_encrypted;
BEGIN
e := create_encrypted_ore_json(1);

PERFORM ok(
(SELECT count(*) FROM encrypted WHERE e >= e) >= 1,
'Greater than or equal operator >= works with ORE encrypted data'
);
END;
$$ LANGUAGE plpgsql;

-- Test 5: Not equal operator
DO $$
DECLARE
e eql_v2_encrypted;
BEGIN
e := create_encrypted_json(1, 'hm');

PERFORM ok(
(SELECT count(*) FROM encrypted WHERE e <> e) >= 1,
'Not equal operator <> works with encrypted data'
);
END;
$$ LANGUAGE plpgsql;

-- Test 6: eql_v2.lt() function
DO $$
DECLARE
e eql_v2_encrypted;
BEGIN
e := create_encrypted_ore_json(42);

PERFORM ok(
(SELECT count(*) FROM encrypted WHERE eql_v2.lt(e, e)) >= 1,
'eql_v2.lt() function works with ORE encrypted data'
);
END;
$$ LANGUAGE plpgsql;

-- Test 7: eql_v2.lte() function
DO $$
DECLARE
e eql_v2_encrypted;
BEGIN
e := create_encrypted_ore_json(42);

PERFORM ok(
(SELECT count(*) FROM encrypted WHERE eql_v2.lte(e, e)) >= 1,
'eql_v2.lte() function works with ORE encrypted data'
);
END;
$$ LANGUAGE plpgsql;

-- Test 8: eql_v2.gt() function
DO $$
DECLARE
e eql_v2_encrypted;
BEGIN
e := create_encrypted_ore_json(1);

PERFORM ok(
(SELECT count(*) FROM encrypted WHERE eql_v2.gt(e, e)) >= 1,
'eql_v2.gt() function works with ORE encrypted data'
);
END;
$$ LANGUAGE plpgsql;

-- Test 9: eql_v2.gte() function
DO $$
DECLARE
e eql_v2_encrypted;
BEGIN
e := create_encrypted_ore_json(1);

PERFORM ok(
(SELECT count(*) FROM encrypted WHERE eql_v2.gte(e, e)) >= 1,
'eql_v2.gte() function works with ORE encrypted data'
);
END;
$$ LANGUAGE plpgsql;

-- Test 10: eql_v2.neq() function
DO $$
DECLARE
e eql_v2_encrypted;
BEGIN
e := create_encrypted_json(1, 'hm');

PERFORM ok(
(SELECT count(*) FROM encrypted WHERE eql_v2.neq(e, e)) >= 1,
'eql_v2.neq() function works with encrypted data'
);
END;
$$ LANGUAGE plpgsql;

-- Cleanup
SELECT lives_ok(
'SELECT drop_table_with_encrypted()',
'Should drop test table'
);

SELECT finish();
ROLLBACK;
Loading