Ctrl K
ComunidadGuías…

run_tests.sh

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/bin/bash
# Calibre-Web Automated - Interactive Test Runner
# Copyright (C) 2024-2025 Calibre-Web Automated contributors
# SPDX-License-Identifier: GPL-3.0-or-later

set -e

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
MAGENTA='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
BOLD='\033[1m'

# Script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"

# Activate venv if it exists
if [ -d ".venv" ]; then
    source .venv/bin/activate
fi

# Test configuration
# Default to 8085 to avoid conflicts with production CWA on 8083
TEST_PORT="${CWA_TEST_PORT:-8085}"

# Determine pytest command (python3 -m pytest works in more environments)
if command -v pytest &> /dev/null; then
    PYTEST="pytest"
else
    PYTEST="python3 -m pytest"
fi

# Check dependencies
check_dependencies() {
    local missing_deps=0
    
    # Check Docker
    if ! command -v docker &> /dev/null; then
        print_warning "Docker not found - integration tests will fail"
        missing_deps=1
    elif ! docker info &> /dev/null; then
        print_warning "Docker daemon not running - integration tests will fail"
        missing_deps=1
    fi
    
    # Check Python venv
    if [ ! -d ".venv" ]; then
        print_warning "Virtual environment not found"
        echo "  Run: python3 -m venv .venv && source .venv/bin/activate && pip install -r requirements.txt"
        missing_deps=1
    fi
    
    # Check pytest
    if ! command -v pytest &> /dev/null && ! python3 -c "import pytest" &> /dev/null; then
        print_warning "pytest not installed"
        echo "  Run: pip install pytest pytest-timeout pytest-flask pytest-mock faker testcontainers"
        missing_deps=1
    fi
    
    if [ $missing_deps -eq 1 ]; then
        echo ""
        read -p "Continue anyway? [y/N]: " -n 1 -r
        echo
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            exit 1
        fi
    fi
}

# Print header
print_header() {
    clear
    echo -e "${BOLD}${CYAN}"
    echo "╔════════════════════════════════════════════════════════════╗"
    echo "║                                                            ║"
    echo "║        Calibre-Web Automated - Test Suite Runner           ║"
    echo "║                                                            ║"
    echo "╚════════════════════════════════════════════════════════════╝"
    echo "Setup Guide:"
    echo "https://github.com/crocodilestick/Calibre-Web-Automated/wiki/Testing-Quick-Setup"
    echo -e "${NC}"
}

# Print section header
print_section() {
    echo -e "\n${BOLD}${BLUE}▶ $1${NC}"
}

# Print success message
print_success() {
    echo -e "${GREEN}✓${NC} $1"
}

# Print error message
print_error() {
    echo -e "${RED}✗${NC} $1"
}

# Print warning message
print_warning() {
    echo -e "${YELLOW}⚠${NC} $1"
}

# Print info message
print_info() {
    echo -e "${CYAN}ℹ${NC} $1"
}

# Check if running inside Docker
check_environment() {
    if [ -f /.dockerenv ]; then
        ENVIRONMENT="docker"
        print_info "Running inside Docker container (Dev Container detected)"
        DEFAULT_MODE="dind"
    else
        ENVIRONMENT="host"
        print_info "Running on host machine"
        DEFAULT_MODE="bind"
    fi
}

# Show main menu
show_menu() {
    print_header
    check_environment
    check_dependencies
    
    echo ""
    echo -e "${BOLD}Select Test Mode:${NC}"
    echo ""
    echo -e "  ${BOLD}1)${NC} Integration Tests (Bind Mount Mode)"
    echo "     └─ Standard mode - uses temporary directories"
    echo "     └─ Best for: Local development, CI/CD"
    echo ""
    echo -e "  ${BOLD}2)${NC} Integration Tests (Docker Volume Mode)"
    echo "     └─ DinD compatible - uses Docker volumes"
    echo "     └─ Best for: Dev containers, Docker-in-Docker"
    echo ""
    echo -e "  ${BOLD}3)${NC} Docker Startup Tests"
    echo "     └─ Tests container initialization and health"
    echo ""
    echo -e "  ${BOLD}4)${NC} All Tests (Full Suite)"
    echo "     └─ Run everything available"
    echo ""
    echo -e "  ${BOLD}5)${NC} Quick Test (Single Integration Test)"
    echo "     └─ Fast verification - runs one test"
    echo ""
    echo -e "  ${BOLD}6)${NC} Custom Test Selection"
    echo "     └─ Choose specific test file or pattern"
    echo ""
    echo -e "  ${BOLD}7)${NC} Show Test Info & Status"
    echo ""
    echo -e "  ${BOLD}q)${NC} Quit"
    echo ""
    echo -ne "${BOLD}Enter your choice [1-7, q]:${NC} "
}

# Run integration tests in bind mount mode
run_integration_bind() {
    print_header
    print_section "Running Integration Tests (Bind Mount Mode)"
    echo ""
    
    print_info "Starting test container with bind mounts..."
    print_info "This will take ~3-4 minutes"
    echo ""
    
    # Check if pytest is available
    if ! command -v pytest &> /dev/null; then
        print_error "pytest not found! Installing..."
        pip install -q pytest pytest-timeout pytest-flask pytest-mock faker
    fi
    
    # Run tests
    echo -e "${YELLOW}═══════════════════════════════════════════════════════════${NC}"
    
    if pytest tests/integration/test_ingest_pipeline.py -v --tb=short; then
        echo -e "${YELLOW}═══════════════════════════════════════════════════════════${NC}"
        echo ""
        print_success "All integration tests passed!"
    else
        echo -e "${YELLOW}═══════════════════════════════════════════════════════════${NC}"
        echo ""
        print_error "Some tests failed. Check output above."
    fi
    
    echo ""
    read -p "Press Enter to continue..."
}

# Run integration tests in Docker volume mode
run_integration_dind() {
    print_header
    print_section "Running Integration Tests (Docker Volume Mode)"
    echo ""
    
    print_info "Starting test container with Docker volumes..."
    print_info "This will take ~3-4 minutes"
    print_warning "Note: One test (cwa_db_tracks_import) will be skipped"
    echo ""
    
    # Check if pytest is available
    if ! command -v pytest &> /dev/null; then
        print_error "pytest not found! Installing..."
        pip install -q pytest pytest-timeout pytest-flask pytest-mock faker
    fi
    
    # Run tests with volume mode enabled
    echo -e "${YELLOW}═══════════════════════════════════════════════════════════${NC}"
    
    if USE_DOCKER_VOLUMES=true pytest tests/integration/test_ingest_pipeline.py -v --tb=short; then
        echo -e "${YELLOW}═══════════════════════════════════════════════════════════${NC}"
        echo ""
        print_success "All runnable tests passed! (19/20, 1 skipped)"
    else
        echo -e "${YELLOW}═══════════════════════════════════════════════════════════${NC}"
        echo ""
        print_error "Some tests failed. Check output above."
    fi
    
    echo ""
    read -p "Press Enter to continue..."
}

# Run Docker startup tests
run_docker_tests() {
    print_header
    print_section "Running Docker Startup Tests"
    echo ""
    
    print_info "Testing container initialization..."
    echo ""
    
    if [ ! -f tests/docker/test_container_startup.py ]; then
        print_error "Docker tests not found at tests/docker/test_container_startup.py"
        echo ""
        read -p "Press Enter to continue..."
        return
    fi
    
    echo -e "${YELLOW}═══════════════════════════════════════════════════════════${NC}"
    
    if pytest tests/docker/ -v --tb=short; then
        echo -e "${YELLOW}═══════════════════════════════════════════════════════════${NC}"
        echo ""
        print_success "Docker tests passed!"
    else
        echo -e "${YELLOW}═══════════════════════════════════════════════════════════${NC}"
        echo ""
        print_error "Some Docker tests failed."
    fi
    
    echo ""
    read -p "Press Enter to continue..."
}

# Run all tests
run_all_tests() {
    print_header
    print_section "Running Full Test Suite"
    echo ""
    
    print_info "This will run all available tests"
    print_warning "Estimated time: 5-7 minutes"
    echo ""
    echo -ne "Continue? [y/N]: "
    read -r confirm
    
    if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
        return
    fi
    
    echo ""
    echo -e "${YELLOW}═══════════════════════════════════════════════════════════${NC}"
    
    # Determine mode based on environment
    if [ "$DEFAULT_MODE" = "dind" ]; then
        print_info "Using Docker Volume mode (DinD environment detected)"
        USE_DOCKER_VOLUMES=true $PYTEST tests/ -v --tb=short || true
    else
        print_info "Using Bind Mount mode"
        $PYTEST tests/ -v --tb=short || true
    fi
    
    echo -e "${YELLOW}═══════════════════════════════════════════════════════════${NC}"
    echo ""
    read -p "Press Enter to continue..."
}

# Run quick test
run_quick_test() {
    print_header
    print_section "Quick Test - Single Integration Test"
    echo ""
    
    print_info "Running: test_ingest_epub_already_target_format"
    print_info "This verifies basic ingest functionality (~30 seconds)"
    echo ""
    
    echo -e "${YELLOW}═══════════════════════════════════════════════════════════${NC}"
    
    if [ "$DEFAULT_MODE" = "dind" ]; then
        USE_DOCKER_VOLUMES=true $PYTEST tests/integration/test_ingest_pipeline.py::TestBookIngestInContainer::test_ingest_epub_already_target_format -v
    else
        $PYTEST tests/integration/test_ingest_pipeline.py::TestBookIngestInContainer::test_ingest_epub_already_target_format -v
    fi
    
    echo -e "${YELLOW}═══════════════════════════════════════════════════════════${NC}"
    echo ""
    read -p "Press Enter to continue..."
}

# Custom test selection
run_custom_test() {
    print_header
    print_section "Custom Test Selection"
    echo ""
    
    echo "Available test files:"
    echo "  1) tests/integration/test_ingest_pipeline.py (20 tests)"
    echo "  2) tests/docker/test_container_startup.py (9 tests)"
    echo ""
    echo "Or enter a custom pytest pattern (e.g., tests/integration/ -k metadata)"
    echo ""
    echo -ne "Enter choice [1-2 or custom pattern]: "
    read -r choice
    
    case $choice in
        1)
            TEST_PATH="tests/integration/test_ingest_pipeline.py"
            ;;
        2)
            TEST_PATH="tests/docker/test_container_startup.py"
            ;;
        *)
            TEST_PATH="$choice"
            ;;
    esac
    
    echo ""
    print_info "Running: $TEST_PATH"
    echo ""
    echo -e "${YELLOW}═══════════════════════════════════════════════════════════${NC}"
    
    if [ "$DEFAULT_MODE" = "dind" ]; then
        USE_DOCKER_VOLUMES=true $PYTEST $TEST_PATH -v
    else
        $PYTEST $TEST_PATH -v
    fi
    
    echo -e "${YELLOW}═══════════════════════════════════════════════════════════${NC}"
    echo ""
    read -p "Press Enter to continue..."
}

# Show test information
show_info() {
    print_header
    print_section "Test Suite Information"
    echo ""
    
    print_info "Test Environment: $ENVIRONMENT"
    print_info "Default Mode: $DEFAULT_MODE"
    echo ""
    
    echo -e "${BOLD}Available Tests:${NC}"
    echo ""
    
    # Count tests
    echo "📊 Integration Tests:"
    $PYTEST tests/integration/ --collect-only -q 2>/dev/null | tail -1 || echo "  (pytest needed to count)"
    echo ""
    
    if [ -d tests/docker ]; then
        echo "🐳 Docker Tests:"
        $PYTEST tests/docker/ --collect-only -q 2>/dev/null | tail -1 || echo "  (pytest needed to count)"
        echo ""
    fi
    
    echo -e "${BOLD}Test Modes:${NC}"
    echo ""
    echo -e "• ${BOLD}Bind Mount Mode${NC} (Default on host)"
    echo "  └─ Uses temporary directories"
    echo "  └─ 20/20 integration tests pass"
    echo "  └─ Faster cleanup"
    echo ""
    echo -e "• ${BOLD}Docker Volume Mode${NC} (Default in dev containers)"
    echo "  └─ Uses Docker volumes via docker cp"
    echo "  └─ 19/20 integration tests pass (1 skipped)"
    echo "  └─ Required for Docker-in-Docker"
    echo ""
    
    echo -e "${BOLD}Documentation:${NC}"
    echo "  • tests/DOCKER_VOLUMES.md - Volume mode details"
    echo "  • HYBRID_DOCKER_IMPLEMENTATION.md - Implementation notes"
    echo "  • DIND_MODE_COMPLETE.md - Completion summary"
    echo ""
    
    read -p "Press Enter to continue..."
}

# Main loop
main() {
    # Check for required dependencies
    if ! command -v docker &> /dev/null; then
        print_header
        print_error "Docker is required but not found!"
        echo ""
        echo "Please install Docker and try again."
        exit 1
    fi
    
    while true; do
        show_menu
        read -r choice
        
        case $choice in
            1)
                run_integration_bind
                ;;
            2)
                run_integration_dind
                ;;
            3)
                run_docker_tests
                ;;
            4)
                run_all_tests
                ;;
            5)
                run_quick_test
                ;;
            6)
                run_custom_test
                ;;
            7)
                show_info
                ;;
            q|Q)
                print_header
                print_success "Goodbye!"
                echo ""
                exit 0
                ;;
            *)
                print_header
                print_error "Invalid choice. Please try again."
                sleep 2
                ;;
        esac
    done
}

# Run main function
main