398 lines
10 KiB
Bash
Executable File
398 lines
10 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# RuVector-Postgres Docker Test Script
|
|
# Quick start script for building and running tests in Docker
|
|
#
|
|
# Usage:
|
|
# ./scripts/docker-test.sh # Run all tests
|
|
# ./scripts/docker-test.sh --build # Build only
|
|
# ./scripts/docker-test.sh --benchmark # Run benchmarks
|
|
# ./scripts/docker-test.sh --matrix # Run matrix tests (all PG versions)
|
|
# ./scripts/docker-test.sh --clean # Clean up containers and volumes
|
|
|
|
set -e
|
|
set -u
|
|
set -o pipefail
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
CYAN='\033[0;36m'
|
|
NC='\033[0m'
|
|
|
|
# Script configuration
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
DOCKER_DIR="$(cd "${SCRIPT_DIR}/../docker" && pwd)"
|
|
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)"
|
|
|
|
# Default configuration
|
|
PG_VERSION="${PG_VERSION:-17}"
|
|
COMPOSE_FILE="${DOCKER_DIR}/docker-compose.yml"
|
|
COMPOSE_PROJECT="ruvector"
|
|
|
|
# Logging 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"; }
|
|
log_header() {
|
|
echo ""
|
|
echo -e "${CYAN}============================================================${NC}"
|
|
echo -e "${CYAN} $1${NC}"
|
|
echo -e "${CYAN}============================================================${NC}"
|
|
echo ""
|
|
}
|
|
|
|
# Show usage
|
|
show_usage() {
|
|
cat << EOF
|
|
RuVector-Postgres Docker Test Script
|
|
|
|
Usage: $0 [OPTIONS] [COMMAND]
|
|
|
|
Commands:
|
|
test Run test suite (default)
|
|
benchmark Run performance benchmarks
|
|
matrix Run tests for all PostgreSQL versions
|
|
build Build Docker images only
|
|
clean Clean up containers, images, and volumes
|
|
shell Open development shell
|
|
logs Show container logs
|
|
|
|
Options:
|
|
-p, --pg-version VERSION PostgreSQL version (14, 15, 16, 17) [default: 17]
|
|
-v, --verbose Enable verbose output
|
|
-k, --keep Keep containers running after tests
|
|
-f, --follow Follow logs after starting
|
|
--no-cache Build without Docker cache
|
|
-h, --help Show this help message
|
|
|
|
Environment Variables:
|
|
PG_VERSION PostgreSQL version [default: 17]
|
|
RUST_VERSION Rust version [default: 1.83]
|
|
POSTGRES_PORT Host port for PostgreSQL [default: 5432]
|
|
COMPARE_BASELINE Compare benchmarks to baseline [default: false]
|
|
|
|
Examples:
|
|
# Run tests with default PostgreSQL 17
|
|
$0 test
|
|
|
|
# Run tests with PostgreSQL 16
|
|
$0 --pg-version 16 test
|
|
|
|
# Run benchmarks
|
|
$0 benchmark
|
|
|
|
# Run matrix tests (all PG versions)
|
|
$0 matrix
|
|
|
|
# Build images without cache
|
|
$0 --no-cache build
|
|
|
|
# Open development shell
|
|
$0 shell
|
|
|
|
# Clean up everything
|
|
$0 clean
|
|
EOF
|
|
}
|
|
|
|
# Docker Compose wrapper
|
|
dc() {
|
|
docker compose -f "${COMPOSE_FILE}" -p "${COMPOSE_PROJECT}" "$@"
|
|
}
|
|
|
|
# Build Docker images
|
|
cmd_build() {
|
|
log_header "Building Docker Images"
|
|
log_info "PostgreSQL Version: ${PG_VERSION}"
|
|
log_info "Docker Context: ${PROJECT_ROOT}"
|
|
|
|
local build_args="--build-arg PG_VERSION=${PG_VERSION}"
|
|
if [ "${NO_CACHE:-false}" == "true" ]; then
|
|
build_args="${build_args} --no-cache"
|
|
fi
|
|
|
|
cd "${PROJECT_ROOT}"
|
|
|
|
# Build main PostgreSQL image
|
|
log_info "Building ruvector-postgres image..."
|
|
DOCKER_BUILDKIT=1 docker build \
|
|
${build_args} \
|
|
-f crates/ruvector-postgres/docker/Dockerfile \
|
|
-t "ruvector-postgres:pg${PG_VERSION}" \
|
|
--progress=plain \
|
|
.
|
|
|
|
log_success "Docker images built successfully"
|
|
}
|
|
|
|
# Run test suite
|
|
cmd_test() {
|
|
log_header "Running Test Suite"
|
|
log_info "PostgreSQL Version: ${PG_VERSION}"
|
|
|
|
cd "${DOCKER_DIR}"
|
|
|
|
# Start PostgreSQL and wait for it to be healthy
|
|
log_info "Starting PostgreSQL..."
|
|
PG_VERSION=${PG_VERSION} dc up -d postgres
|
|
|
|
log_info "Waiting for PostgreSQL to be ready..."
|
|
local max_wait=60
|
|
local waited=0
|
|
while [ ${waited} -lt ${max_wait} ]; do
|
|
if dc exec -T postgres pg_isready -U ruvector -d ruvector_test &>/dev/null; then
|
|
log_success "PostgreSQL is ready!"
|
|
break
|
|
fi
|
|
echo -n "."
|
|
sleep 2
|
|
waited=$((waited + 2))
|
|
done
|
|
echo ""
|
|
|
|
if [ ${waited} -ge ${max_wait} ]; then
|
|
log_error "PostgreSQL failed to start within ${max_wait} seconds"
|
|
dc logs postgres
|
|
exit 1
|
|
fi
|
|
|
|
# Run test runner
|
|
log_info "Running tests..."
|
|
PG_VERSION=${PG_VERSION} dc run --rm test-runner
|
|
|
|
# Collect results
|
|
log_info "Test results available in: ruvector-test-results volume"
|
|
|
|
if [ "${KEEP_RUNNING:-false}" != "true" ]; then
|
|
log_info "Stopping containers..."
|
|
dc down
|
|
else
|
|
log_info "Containers kept running. Stop with: docker-compose -f ${COMPOSE_FILE} down"
|
|
fi
|
|
|
|
log_success "Test suite completed!"
|
|
}
|
|
|
|
# Run benchmarks
|
|
cmd_benchmark() {
|
|
log_header "Running Performance Benchmarks"
|
|
log_info "PostgreSQL Version: ${PG_VERSION}"
|
|
|
|
cd "${DOCKER_DIR}"
|
|
|
|
# Start PostgreSQL
|
|
log_info "Starting PostgreSQL..."
|
|
PG_VERSION=${PG_VERSION} dc up -d postgres
|
|
|
|
log_info "Waiting for PostgreSQL..."
|
|
sleep 10
|
|
|
|
# Run benchmarks
|
|
log_info "Running benchmarks..."
|
|
PG_VERSION=${PG_VERSION} dc --profile benchmark run --rm benchmark
|
|
|
|
log_info "Benchmark results available in: ruvector-benchmark-results volume"
|
|
|
|
if [ "${KEEP_RUNNING:-false}" != "true" ]; then
|
|
dc down
|
|
fi
|
|
|
|
log_success "Benchmarks completed!"
|
|
}
|
|
|
|
# Run matrix tests (all PG versions)
|
|
cmd_matrix() {
|
|
log_header "Running Matrix Tests (All PostgreSQL Versions)"
|
|
|
|
local versions=(14 15 16 17)
|
|
local failed=()
|
|
|
|
for version in "${versions[@]}"; do
|
|
log_header "Testing PostgreSQL ${version}"
|
|
|
|
if PG_VERSION=${version} cmd_test; then
|
|
log_success "PostgreSQL ${version}: PASSED"
|
|
else
|
|
log_error "PostgreSQL ${version}: FAILED"
|
|
failed+=("${version}")
|
|
fi
|
|
done
|
|
|
|
echo ""
|
|
log_header "Matrix Test Summary"
|
|
|
|
if [ ${#failed[@]} -eq 0 ]; then
|
|
log_success "All PostgreSQL versions passed!"
|
|
return 0
|
|
else
|
|
log_error "Failed versions: ${failed[*]}"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Open development shell
|
|
cmd_shell() {
|
|
log_header "Opening Development Shell"
|
|
|
|
cd "${DOCKER_DIR}"
|
|
|
|
# Start PostgreSQL
|
|
log_info "Starting PostgreSQL..."
|
|
PG_VERSION=${PG_VERSION} dc up -d postgres
|
|
|
|
log_info "Waiting for PostgreSQL..."
|
|
sleep 5
|
|
|
|
# Start dev shell
|
|
log_info "Opening shell..."
|
|
PG_VERSION=${PG_VERSION} dc --profile dev run --rm dev
|
|
}
|
|
|
|
# Show logs
|
|
cmd_logs() {
|
|
cd "${DOCKER_DIR}"
|
|
|
|
if [ -n "${1:-}" ]; then
|
|
dc logs -f "$1"
|
|
else
|
|
dc logs -f
|
|
fi
|
|
}
|
|
|
|
# Clean up
|
|
cmd_clean() {
|
|
log_header "Cleaning Up Docker Resources"
|
|
|
|
cd "${DOCKER_DIR}"
|
|
|
|
log_info "Stopping all containers..."
|
|
dc down --volumes --remove-orphans 2>/dev/null || true
|
|
dc --profile benchmark down --volumes 2>/dev/null || true
|
|
dc --profile dev down --volumes 2>/dev/null || true
|
|
dc --profile matrix down --volumes 2>/dev/null || true
|
|
|
|
log_info "Removing images..."
|
|
docker rmi ruvector-postgres:pg14 2>/dev/null || true
|
|
docker rmi ruvector-postgres:pg15 2>/dev/null || true
|
|
docker rmi ruvector-postgres:pg16 2>/dev/null || true
|
|
docker rmi ruvector-postgres:pg17 2>/dev/null || true
|
|
|
|
log_info "Removing volumes..."
|
|
docker volume rm ruvector-postgres-data 2>/dev/null || true
|
|
docker volume rm ruvector-cargo-cache 2>/dev/null || true
|
|
docker volume rm ruvector-cargo-git 2>/dev/null || true
|
|
docker volume rm ruvector-target-cache 2>/dev/null || true
|
|
docker volume rm ruvector-test-results 2>/dev/null || true
|
|
docker volume rm ruvector-benchmark-results 2>/dev/null || true
|
|
|
|
log_info "Pruning unused Docker resources..."
|
|
docker system prune -f
|
|
|
|
log_success "Cleanup completed!"
|
|
}
|
|
|
|
# Main function
|
|
main() {
|
|
local command="test"
|
|
local verbose=false
|
|
|
|
# Parse arguments
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
test|benchmark|matrix|build|clean|shell|logs)
|
|
command="$1"
|
|
shift
|
|
;;
|
|
-p|--pg-version)
|
|
PG_VERSION="$2"
|
|
shift 2
|
|
;;
|
|
-v|--verbose)
|
|
verbose=true
|
|
set -x
|
|
shift
|
|
;;
|
|
-k|--keep)
|
|
export KEEP_RUNNING=true
|
|
shift
|
|
;;
|
|
-f|--follow)
|
|
export FOLLOW_LOGS=true
|
|
shift
|
|
;;
|
|
--no-cache)
|
|
export NO_CACHE=true
|
|
shift
|
|
;;
|
|
-h|--help)
|
|
show_usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
log_error "Unknown option: $1"
|
|
show_usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Validate PG version
|
|
case "${PG_VERSION}" in
|
|
14|15|16|17) ;;
|
|
*)
|
|
log_error "Invalid PostgreSQL version: ${PG_VERSION}"
|
|
log_error "Valid versions: 14, 15, 16, 17"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
export PG_VERSION
|
|
|
|
# Check Docker
|
|
if ! command -v docker &> /dev/null; then
|
|
log_error "Docker is not installed. Please install Docker first."
|
|
exit 1
|
|
fi
|
|
|
|
if ! docker info &> /dev/null; then
|
|
log_error "Docker daemon is not running. Please start Docker."
|
|
exit 1
|
|
fi
|
|
|
|
# Execute command
|
|
case "${command}" in
|
|
test)
|
|
cmd_test
|
|
;;
|
|
benchmark)
|
|
cmd_benchmark
|
|
;;
|
|
matrix)
|
|
cmd_matrix
|
|
;;
|
|
build)
|
|
cmd_build
|
|
;;
|
|
clean)
|
|
cmd_clean
|
|
;;
|
|
shell)
|
|
cmd_shell
|
|
;;
|
|
logs)
|
|
cmd_logs "${2:-}"
|
|
;;
|
|
*)
|
|
log_error "Unknown command: ${command}"
|
|
show_usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Run main
|
|
main "$@"
|