Merge commit 'd803bfe2b1fe7f5e219e50ac20d6801a0a58ac75' as 'vendor/ruvector'
This commit is contained in:
363
vendor/ruvector/crates/ruvector-postgres/docker/run-tests.sh
vendored
Executable file
363
vendor/ruvector/crates/ruvector-postgres/docker/run-tests.sh
vendored
Executable file
@@ -0,0 +1,363 @@
|
||||
#!/usr/bin/env bash
|
||||
# RuVector-Postgres Test Runner
|
||||
# Builds Docker image, runs tests, and cleans up
|
||||
|
||||
set -e # Exit on error
|
||||
set -u # Exit on undefined variable
|
||||
set -o pipefail # Exit on pipe failure
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Configuration
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)"
|
||||
CONTAINER_NAME="ruvector-postgres-test"
|
||||
IMAGE_NAME="ruvector-postgres:test"
|
||||
POSTGRES_PORT="${POSTGRES_PORT:-5433}"
|
||||
POSTGRES_USER="${POSTGRES_USER:-ruvector}"
|
||||
POSTGRES_PASSWORD="${POSTGRES_PASSWORD:-ruvector}"
|
||||
POSTGRES_DB="${POSTGRES_DB:-ruvector_test}"
|
||||
|
||||
# Detect OS
|
||||
OS_TYPE="$(uname -s)"
|
||||
case "${OS_TYPE}" in
|
||||
Linux*) PLATFORM="linux";;
|
||||
Darwin*) PLATFORM="macos";;
|
||||
*) PLATFORM="unknown";;
|
||||
esac
|
||||
|
||||
# Functions
|
||||
log_info() {
|
||||
echo -e "${BLUE}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_success() {
|
||||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
log_info "Cleaning up containers and volumes..."
|
||||
docker stop "${CONTAINER_NAME}" 2>/dev/null || true
|
||||
docker rm "${CONTAINER_NAME}" 2>/dev/null || true
|
||||
if [ "${KEEP_VOLUMES:-false}" != "true" ]; then
|
||||
docker volume rm "${CONTAINER_NAME}_data" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
wait_for_postgres() {
|
||||
log_info "Waiting for PostgreSQL to be healthy..."
|
||||
local max_attempts=30
|
||||
local attempt=1
|
||||
|
||||
while [ ${attempt} -le ${max_attempts} ]; do
|
||||
if docker exec "${CONTAINER_NAME}" pg_isready -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" &>/dev/null; then
|
||||
log_success "PostgreSQL is ready!"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo -n "."
|
||||
sleep 1
|
||||
attempt=$((attempt + 1))
|
||||
done
|
||||
|
||||
log_error "PostgreSQL failed to become ready after ${max_attempts} seconds"
|
||||
docker logs "${CONTAINER_NAME}"
|
||||
return 1
|
||||
}
|
||||
|
||||
build_image() {
|
||||
log_info "Building Docker image: ${IMAGE_NAME}"
|
||||
log_info "Platform: ${PLATFORM}"
|
||||
|
||||
cd "${PROJECT_ROOT}"
|
||||
|
||||
# Build with BuildKit for better caching
|
||||
DOCKER_BUILDKIT=1 docker build \
|
||||
-f crates/ruvector-postgres/docker/Dockerfile \
|
||||
-t "${IMAGE_NAME}" \
|
||||
--build-arg BUILDKIT_INLINE_CACHE=1 \
|
||||
--progress=plain \
|
||||
.
|
||||
|
||||
log_success "Docker image built successfully"
|
||||
}
|
||||
|
||||
start_container() {
|
||||
log_info "Starting PostgreSQL container: ${CONTAINER_NAME}"
|
||||
|
||||
# Create volume for data persistence
|
||||
docker volume create "${CONTAINER_NAME}_data" || true
|
||||
|
||||
# Start container
|
||||
docker run -d \
|
||||
--name "${CONTAINER_NAME}" \
|
||||
-p "${POSTGRES_PORT}:5432" \
|
||||
-e POSTGRES_USER="${POSTGRES_USER}" \
|
||||
-e POSTGRES_PASSWORD="${POSTGRES_PASSWORD}" \
|
||||
-e POSTGRES_DB="${POSTGRES_DB}" \
|
||||
-v "${CONTAINER_NAME}_data:/var/lib/postgresql/data" \
|
||||
--health-cmd="pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}" \
|
||||
--health-interval=5s \
|
||||
--health-timeout=5s \
|
||||
--health-retries=5 \
|
||||
"${IMAGE_NAME}"
|
||||
|
||||
log_success "Container started"
|
||||
}
|
||||
|
||||
run_tests() {
|
||||
log_info "Running test suite..."
|
||||
|
||||
# Export connection string for tests
|
||||
export DATABASE_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${POSTGRES_PORT}/${POSTGRES_DB}"
|
||||
|
||||
log_info "Connection string: ${DATABASE_URL}"
|
||||
|
||||
# Run pgrx tests
|
||||
cd "${PROJECT_ROOT}/crates/ruvector-postgres"
|
||||
|
||||
log_info "Running pgrx tests..."
|
||||
if cargo pgrx test pg16; then
|
||||
log_success "All tests passed!"
|
||||
return 0
|
||||
else
|
||||
log_error "Tests failed!"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
run_integration_tests() {
|
||||
log_info "Running integration tests via SQL..."
|
||||
|
||||
# Wait a bit more for full initialization
|
||||
sleep 2
|
||||
|
||||
# Test extension loading
|
||||
log_info "Testing extension installation..."
|
||||
docker exec -it "${CONTAINER_NAME}" psql -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" -c "CREATE EXTENSION IF NOT EXISTS ruvector_postgres;" || {
|
||||
log_error "Failed to create extension"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Test basic vector operations
|
||||
log_info "Testing basic vector operations..."
|
||||
docker exec -it "${CONTAINER_NAME}" psql -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" << 'EOF'
|
||||
-- Test vector creation
|
||||
SELECT '[1,2,3]'::vector;
|
||||
|
||||
-- Test distance functions
|
||||
SELECT vector_l2_distance('[1,2,3]'::vector, '[4,5,6]'::vector);
|
||||
SELECT vector_cosine_distance('[1,2,3]'::vector, '[4,5,6]'::vector);
|
||||
SELECT vector_inner_product('[1,2,3]'::vector, '[4,5,6]'::vector);
|
||||
|
||||
-- Test table creation with vector column
|
||||
CREATE TABLE IF NOT EXISTS test_vectors (
|
||||
id SERIAL PRIMARY KEY,
|
||||
embedding vector(3)
|
||||
);
|
||||
|
||||
-- Insert test data
|
||||
INSERT INTO test_vectors (embedding) VALUES
|
||||
('[1,2,3]'::vector),
|
||||
('[4,5,6]'::vector),
|
||||
('[7,8,9]'::vector);
|
||||
|
||||
-- Test similarity search
|
||||
SELECT * FROM test_vectors ORDER BY embedding <-> '[1,2,3]'::vector LIMIT 3;
|
||||
|
||||
-- Cleanup
|
||||
DROP TABLE test_vectors;
|
||||
EOF
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
log_success "Integration tests passed!"
|
||||
return 0
|
||||
else
|
||||
log_error "Integration tests failed!"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
collect_results() {
|
||||
log_info "Collecting test results..."
|
||||
|
||||
# Create results directory
|
||||
local results_dir="${PROJECT_ROOT}/test-results"
|
||||
mkdir -p "${results_dir}"
|
||||
|
||||
# Export container logs
|
||||
docker logs "${CONTAINER_NAME}" > "${results_dir}/postgres.log" 2>&1
|
||||
|
||||
# Export test database dump (if needed)
|
||||
if [ "${EXPORT_DB:-false}" == "true" ]; then
|
||||
log_info "Exporting database dump..."
|
||||
docker exec "${CONTAINER_NAME}" pg_dump -U "${POSTGRES_USER}" "${POSTGRES_DB}" > "${results_dir}/test_db_dump.sql"
|
||||
fi
|
||||
|
||||
log_success "Results collected in ${results_dir}"
|
||||
}
|
||||
|
||||
show_usage() {
|
||||
cat << EOF
|
||||
RuVector-Postgres Test Runner
|
||||
|
||||
Usage: $0 [OPTIONS]
|
||||
|
||||
Options:
|
||||
-b, --build-only Build Docker image only, don't run tests
|
||||
-t, --test-only Run tests only (skip build)
|
||||
-i, --integration Run integration tests only
|
||||
-k, --keep-running Keep container running after tests
|
||||
-c, --clean Clean up before starting
|
||||
-v, --keep-volumes Keep volumes after cleanup
|
||||
-p, --port PORT PostgreSQL port (default: 5433)
|
||||
-h, --help Show this help message
|
||||
|
||||
Environment Variables:
|
||||
POSTGRES_PORT PostgreSQL port (default: 5433)
|
||||
POSTGRES_USER PostgreSQL user (default: ruvector)
|
||||
POSTGRES_PASSWORD PostgreSQL password (default: ruvector)
|
||||
POSTGRES_DB PostgreSQL database (default: ruvector_test)
|
||||
KEEP_VOLUMES Keep volumes after cleanup (default: false)
|
||||
EXPORT_DB Export database dump (default: false)
|
||||
|
||||
Examples:
|
||||
# Run full test suite
|
||||
$0
|
||||
|
||||
# Build and keep container running for debugging
|
||||
$0 --keep-running
|
||||
|
||||
# Run integration tests only
|
||||
$0 --integration --test-only
|
||||
|
||||
# Clean rebuild
|
||||
$0 --clean --build-only
|
||||
EOF
|
||||
}
|
||||
|
||||
main() {
|
||||
local build_only=false
|
||||
local test_only=false
|
||||
local integration_only=false
|
||||
local keep_running=false
|
||||
local clean_first=false
|
||||
|
||||
# Parse arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-b|--build-only)
|
||||
build_only=true
|
||||
shift
|
||||
;;
|
||||
-t|--test-only)
|
||||
test_only=true
|
||||
shift
|
||||
;;
|
||||
-i|--integration)
|
||||
integration_only=true
|
||||
shift
|
||||
;;
|
||||
-k|--keep-running)
|
||||
keep_running=true
|
||||
shift
|
||||
;;
|
||||
-c|--clean)
|
||||
clean_first=true
|
||||
shift
|
||||
;;
|
||||
-v|--keep-volumes)
|
||||
KEEP_VOLUMES=true
|
||||
shift
|
||||
;;
|
||||
-p|--port)
|
||||
POSTGRES_PORT="$2"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
show_usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
log_error "Unknown option: $1"
|
||||
show_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Setup trap for cleanup
|
||||
if [ "${keep_running}" != "true" ]; then
|
||||
trap cleanup EXIT
|
||||
fi
|
||||
|
||||
log_info "RuVector-Postgres Test Runner"
|
||||
log_info "Platform: ${PLATFORM}"
|
||||
log_info "PostgreSQL Port: ${POSTGRES_PORT}"
|
||||
|
||||
# Clean if requested
|
||||
if [ "${clean_first}" == "true" ]; then
|
||||
cleanup
|
||||
fi
|
||||
|
||||
# Build phase
|
||||
if [ "${test_only}" != "true" ]; then
|
||||
build_image
|
||||
fi
|
||||
|
||||
if [ "${build_only}" == "true" ]; then
|
||||
log_success "Build complete!"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Test phase
|
||||
start_container
|
||||
wait_for_postgres
|
||||
|
||||
local test_result=0
|
||||
|
||||
if [ "${integration_only}" == "true" ]; then
|
||||
run_integration_tests || test_result=$?
|
||||
else
|
||||
# Run both pgrx and integration tests
|
||||
run_integration_tests || test_result=$?
|
||||
|
||||
if [ ${test_result} -eq 0 ]; then
|
||||
# Only run pgrx tests if integration tests passed
|
||||
run_tests || test_result=$?
|
||||
fi
|
||||
fi
|
||||
|
||||
collect_results
|
||||
|
||||
if [ "${keep_running}" == "true" ]; then
|
||||
log_info "Container is still running: ${CONTAINER_NAME}"
|
||||
log_info "Connection: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${POSTGRES_PORT}/${POSTGRES_DB}"
|
||||
log_info "To stop: docker stop ${CONTAINER_NAME}"
|
||||
trap - EXIT # Disable cleanup trap
|
||||
fi
|
||||
|
||||
if [ ${test_result} -eq 0 ]; then
|
||||
log_success "All tests completed successfully!"
|
||||
exit 0
|
||||
else
|
||||
log_error "Tests failed with exit code ${test_result}"
|
||||
exit ${test_result}
|
||||
fi
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user