#!/bin/bash # Comprehensive Test Runner # This script runs tests against both SQLite and PostgreSQL backends set -e # 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' # No Color # Configuration SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" # Test results tracking SQLITE_RESULT=0 POSTGRES_RESULT=0 TOTAL_START_TIME=$(date +%s) # Function to print colored output print_info() { echo -e "${BLUE}[INFO]${NC} $1" } print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } print_header() { echo -e "${CYAN}============================================${NC}" echo -e "${CYAN} $1${NC}" echo -e "${CYAN}============================================${NC}" } # Function to format time duration format_duration() { local duration=$1 local minutes=$((duration / 60)) local seconds=$((duration % 60)) if [[ $minutes -gt 0 ]]; then echo "${minutes}m ${seconds}s" else echo "${seconds}s" fi } # Function to show usage usage() { echo "Usage: $0 [OPTIONS] [TEST_ARGS]" echo "" echo "Options:" echo " -h, --help Show this help message" echo " -s, --sqlite Run only SQLite tests" echo " -p, --postgres Run only PostgreSQL tests" echo " -c, --clean Clean start for all backends" echo " -k, --keep Keep PostgreSQL container running" echo " -f, --fail-fast Stop on first failure" echo " -v, --verbose Enable verbose output" echo " --stats Show database statistics" echo " --parallel Run tests in parallel (experimental)" echo "" echo "Examples:" echo " $0 # Run tests on both backends" echo " $0 --sqlite # Run only SQLite tests" echo " $0 --postgres --keep # Run PostgreSQL tests, keep container" echo " $0 --clean storage::tests # Clean start, test only storage module" echo " $0 --fail-fast # Stop on first backend failure" } # Function to run SQLite tests run_sqlite_tests() { print_header "RUNNING SQLITE TESTS" local start_time=$(date +%s) local args=() if [[ "$CLEAN_START" == "true" ]]; then args+=("--clean") fi if [[ "$SHOW_STATS" == "true" ]]; then args+=("--stats" "--optimize") fi if [[ "$VERBOSE" == "true" ]]; then args+=("--verbose") fi # Add test arguments if [[ ${#TEST_ARGS[@]} -gt 0 ]]; then args+=("--" "${TEST_ARGS[@]}") fi # Run SQLite tests if "$SCRIPT_DIR/test-sqlite.sh" "${args[@]}"; then local end_time=$(date +%s) local duration=$((end_time - start_time)) print_success "SQLite tests completed in $(format_duration $duration)" SQLITE_RESULT=0 else local end_time=$(date +%s) local duration=$((end_time - start_time)) print_error "SQLite tests failed after $(format_duration $duration)" SQLITE_RESULT=1 if [[ "$FAIL_FAST" == "true" ]]; then print_error "Fail-fast enabled, stopping execution" exit 1 fi fi } # Function to run PostgreSQL tests run_postgres_tests() { print_header "RUNNING POSTGRESQL TESTS" local start_time=$(date +%s) local args=() if [[ "$CLEAN_START" == "true" ]]; then args+=("--clean") fi if [[ "$KEEP_CONTAINER" == "true" ]]; then args+=("--keep") fi if [[ "$VERBOSE" == "true" ]]; then args+=("--verbose") fi # Add test arguments if [[ ${#TEST_ARGS[@]} -gt 0 ]]; then args+=("--" "${TEST_ARGS[@]}") fi # Run PostgreSQL tests if "$SCRIPT_DIR/test-postgres.sh" "${args[@]}"; then local end_time=$(date +%s) local duration=$((end_time - start_time)) print_success "PostgreSQL tests completed in $(format_duration $duration)" POSTGRES_RESULT=0 else local end_time=$(date +%s) local duration=$((end_time - start_time)) print_error "PostgreSQL tests failed after $(format_duration $duration)" POSTGRES_RESULT=1 if [[ "$FAIL_FAST" == "true" ]]; then print_error "Fail-fast enabled, stopping execution" exit 1 fi fi } # Function to run tests in parallel run_parallel_tests() { print_header "RUNNING TESTS IN PARALLEL" print_warning "Parallel testing is experimental and may cause resource conflicts" local sqlite_pid="" local postgres_pid="" # Start SQLite tests in background if [[ "$RUN_SQLITE" == "true" ]]; then print_info "Starting SQLite tests in background..." run_sqlite_tests & sqlite_pid=$! fi # Start PostgreSQL tests in background if [[ "$RUN_POSTGRES" == "true" ]]; then print_info "Starting PostgreSQL tests in background..." run_postgres_tests & postgres_pid=$! fi # Wait for both to complete if [[ -n "$sqlite_pid" ]]; then wait $sqlite_pid SQLITE_RESULT=$? fi if [[ -n "$postgres_pid" ]]; then wait $postgres_pid POSTGRES_RESULT=$? fi } # Function to show test summary show_summary() { local total_end_time=$(date +%s) local total_duration=$((total_end_time - TOTAL_START_TIME)) print_header "TEST SUMMARY" echo -e "Total execution time: $(format_duration $total_duration)" echo "" if [[ "$RUN_SQLITE" == "true" ]]; then if [[ $SQLITE_RESULT -eq 0 ]]; then echo -e "SQLite tests: ${GREEN}✓ PASSED${NC}" else echo -e "SQLite tests: ${RED}✗ FAILED${NC}" fi fi if [[ "$RUN_POSTGRES" == "true" ]]; then if [[ $POSTGRES_RESULT -eq 0 ]]; then echo -e "PostgreSQL tests: ${GREEN}✓ PASSED${NC}" else echo -e "PostgreSQL tests: ${RED}✗ FAILED${NC}" fi fi echo "" local total_failures=$((SQLITE_RESULT + POSTGRES_RESULT)) if [[ $total_failures -eq 0 ]]; then print_success "All tests passed!" return 0 else print_error "$total_failures backend(s) failed" return 1 fi } # Function to check prerequisites check_prerequisites() { # Check if we're in the right directory if [[ ! -f "Cargo.toml" ]] || [[ ! -d "src" ]]; then print_error "This script must be run from the project root directory" exit 1 fi # Check if test scripts exist if [[ ! -f "$SCRIPT_DIR/test-sqlite.sh" ]]; then print_error "SQLite test script not found: $SCRIPT_DIR/test-sqlite.sh" exit 1 fi if [[ ! -f "$SCRIPT_DIR/test-postgres.sh" ]]; then print_error "PostgreSQL test script not found: $SCRIPT_DIR/test-postgres.sh" exit 1 fi } # Parse command line arguments RUN_SQLITE=true RUN_POSTGRES=true CLEAN_START=false KEEP_CONTAINER=false FAIL_FAST=false VERBOSE=false SHOW_STATS=false PARALLEL=false TEST_ARGS=() while [[ $# -gt 0 ]]; do case $1 in -h|--help) usage exit 0 ;; -s|--sqlite) RUN_SQLITE=true RUN_POSTGRES=false shift ;; -p|--postgres) RUN_SQLITE=false RUN_POSTGRES=true shift ;; -c|--clean) CLEAN_START=true shift ;; -k|--keep) KEEP_CONTAINER=true shift ;; -f|--fail-fast) FAIL_FAST=true shift ;; -v|--verbose) VERBOSE=true shift ;; --stats) SHOW_STATS=true shift ;; --parallel) PARALLEL=true shift ;; --) shift TEST_ARGS+=("$@") break ;; *) TEST_ARGS+=("$1") shift ;; esac done # Enable verbose output if requested if [[ "$VERBOSE" == "true" ]]; then set -x fi # Main execution main() { print_header "SHOWCASE TEST RUNNER" # Pre-flight checks check_prerequisites # Show configuration print_info "Test configuration:" echo " SQLite tests: $(if [[ "$RUN_SQLITE" == "true" ]]; then echo "enabled"; else echo "disabled"; fi)" echo " PostgreSQL tests: $(if [[ "$RUN_POSTGRES" == "true" ]]; then echo "enabled"; else echo "disabled"; fi)" echo " Clean start: $(if [[ "$CLEAN_START" == "true" ]]; then echo "yes"; else echo "no"; fi)" echo " Fail fast: $(if [[ "$FAIL_FAST" == "true" ]]; then echo "yes"; else echo "no"; fi)" echo " Parallel mode: $(if [[ "$PARALLEL" == "true" ]]; then echo "yes"; else echo "no"; fi)" if [[ ${#TEST_ARGS[@]} -gt 0 ]]; then echo " Test arguments: ${TEST_ARGS[*]}" fi echo "" # Run tests if [[ "$PARALLEL" == "true" ]]; then run_parallel_tests else # Sequential execution if [[ "$RUN_SQLITE" == "true" ]]; then run_sqlite_tests fi if [[ "$RUN_POSTGRES" == "true" ]]; then run_postgres_tests fi fi # Show summary and exit with appropriate code if show_summary; then exit 0 else exit 1 fi } # Change to project root directory cd "$PROJECT_ROOT" # Run main function main "$@"