name: Integration Tests on: push: branches: - master - main pull_request: branches: - master - main env: CARGO_TERM_COLOR: always DATABASE_URL: postgresql://readur:readur@localhost:5432/readur jobs: integration-tests: name: Integration Tests runs-on: ubuntu-latest services: postgres: image: postgres:17 credentials: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} env: POSTGRES_USER: readur POSTGRES_PASSWORD: readur POSTGRES_DB: readur ports: - 5432:5432 options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 steps: - name: Free disk space run: | echo "Initial disk usage:" df -h # Remove unnecessary packages and files to free up space sudo rm -rf /usr/share/dotnet sudo rm -rf /opt/ghc sudo rm -rf "/usr/local/share/boost" sudo rm -rf "$AGENT_TOOLSDIRECTORY" sudo rm -rf /usr/local/lib/android sudo rm -rf /opt/hostedtoolcache/CodeQL sudo rm -rf /usr/share/swift sudo apt-get clean sudo docker system prune -af --volumes # Set TMPDIR to use runner's work directory which has more space echo "TMPDIR=${{ runner.temp }}" >> $GITHUB_ENV echo "Disk usage after cleanup:" df -h echo "Temp directory set to: ${{ runner.temp }}" - name: Login to Docker Hub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Checkout code uses: actions/checkout@v5 - name: Pre-pull Docker images for testcontainers run: | echo "Pre-pulling Docker images that testcontainers will use..." # Only pull the specific version we're using to save space docker pull postgres:latest docker pull postgres:15 docker pull postgres:15-alpine docker pull postgres:17 echo "Images pulled successfully. These are now in local Docker cache." echo "Testcontainers will use the local cached images." - name: Remove local env files to prevent conflicts run: | # Remove or rename env files so they don't override CI environment variables [ -f .env ] && mv .env .env.backup || true [ -f .env.test ] && mv .env.test .env.test.backup || true echo "Removed local env files to ensure CI env vars take precedence" - name: Install system dependencies run: | sudo apt-get update sudo apt-get install -y \ tesseract-ocr \ tesseract-ocr-eng \ tesseract-ocr-spa \ tesseract-ocr-fra \ tesseract-ocr-deu \ tesseract-ocr-ita \ tesseract-ocr-por \ libtesseract-dev \ libleptonica-dev \ pkg-config \ libclang-dev \ ocrmypdf \ clang \ antiword \ catdoc - name: Setup Rust uses: dtolnay/rust-toolchain@stable - name: Build readur binary run: cargo build --release - name: Start readur server run: | echo "Starting server with DATABASE_URL: $DATABASE_URL" ./target/release/readur > server.log 2>&1 & echo $! > readur.pid sleep 2 echo "Server started with PID: $(cat readur.pid)" env: DATABASE_URL: ${{ env.DATABASE_URL }} JWT_SECRET: test-secret-key SERVER_ADDRESS: 0.0.0.0:8000 UPLOAD_PATH: ./uploads WATCH_FOLDER: ./watch DEBUG: 1 - name: Wait for server to be ready run: | for i in {1..30}; do if curl -f http://localhost:8000/api/health > /dev/null 2>&1; then echo "Readur server is ready" break fi echo "Waiting for readur server... ($i/30)" sleep 2 done # Verify the server is actually running if ! curl -f http://localhost:8000/api/health > /dev/null 2>&1; then echo "ERROR: Server failed to start properly!" if [ -f readur.pid ]; then echo "Server PID: $(cat readur.pid)" ps aux | grep $(cat readur.pid) || echo "Process not found" fi exit 1 fi - name: Wait for PostgreSQL to be ready run: | until pg_isready -h localhost -p 5432 -U readur; do echo "Waiting for PostgreSQL..." sleep 1 done echo "PostgreSQL is ready!" - name: Verify database connection run: | echo "Testing database connection..." PGPASSWORD=readur psql -h localhost -p 5432 -U readur -d readur -c "SELECT version();" echo "Database connection successful!" - name: Setup WebDAV server for stress tests run: | # Install Dufs WebDAV server (WebDAV is supported by default) cargo install dufs # Create WebDAV test directory mkdir -p ${{ runner.temp }}/webdav-server # Start Dufs server in background with WebDAV support dufs ${{ runner.temp }}/webdav-server \ --bind 0.0.0.0:8080 \ --enable-cors \ --allow-all \ --auth testuser:testpass123@/:rw \ --log-file dufs.log & echo $! > dufs.pid # Wait for server to start for i in {1..30}; do # Test with basic auth header instead of URL auth response=$(curl -s -o /dev/null -w "%{http_code}" -u testuser:testpass123 http://localhost:8080/ || echo "000") if [ "$response" = "200" ] || [ "$response" = "401" ] || [ "$response" = "403" ]; then echo "WebDAV server is ready (HTTP $response)" break fi echo "Waiting for WebDAV server... (attempt $i/30, HTTP response: $response)" sleep 1 done # Final verification if ! curl -s -u testuser:testpass123 http://localhost:8080/ > /dev/null; then echo "WARNING: WebDAV server may require authentication adjustments" cat /tmp/dufs.log || true fi env: WEBDAV_SERVER_URL: http://localhost:8080 WEBDAV_USERNAME: testuser WEBDAV_PASSWORD: testpass123 - name: Run integration tests run: | echo "Running tests with DATABASE_URL: $DATABASE_URL" echo "Environment check:" env | grep -E "(DATABASE_URL|JWT_SECRET|API_URL|TMPDIR)" | sort echo "Disk usage before tests:" df -h # Run tests with explicit temp directory # Run all tests including stress tests (with stress-testing feature enabled) cargo test --test '*' --features "test-utils stress-testing" --no-fail-fast -- --test-threads=1 --nocapture env: DATABASE_URL: ${{ env.DATABASE_URL }} TEST_DATABASE_URL: ${{ env.DATABASE_URL }} API_URL: http://localhost:8000 JWT_SECRET: test-secret-key SERVER_ADDRESS: 0.0.0.0:8000 UPLOAD_PATH: ./uploads WATCH_FOLDER: ./watch RUST_LOG: debug RUST_BACKTRACE: 1 DEBUG: 1 TESTCONTAINERS_RYUK_DISABLED: true DOCKER_HOST: unix:///var/run/docker.sock WEBDAV_SERVER_URL: http://localhost:8080 WEBDAV_USERNAME: testuser WEBDAV_PASSWORD: testpass123 - name: Print server logs on failure if: failure() run: | echo "=== Disk usage on failure ===" df -h echo "=== Temp directory usage ===" du -sh ${{ runner.temp }} || echo "Could not check temp directory" echo "=== Server logs ===" cat server.log || echo "No server logs found" echo "=== End of server logs ===" - name: Stop servers if: always() run: | # Stop readur server if [ -f readur.pid ]; then kill $(cat readur.pid) || true rm readur.pid fi # Stop WebDAV server if [ -f dufs.pid ]; then kill $(cat dufs.pid) || true rm dufs.pid fi frontend-integration-tests: name: Frontend Integration Tests runs-on: ubuntu-latest defaults: run: working-directory: ./frontend steps: - name: Checkout code uses: actions/checkout@v5 - name: Setup Node.js uses: actions/setup-node@v6 with: node-version: "24" cache: "npm" cache-dependency-path: frontend/package-lock.json - name: Install dependencies run: npm install - name: Run frontend integration tests run: npm run test:integration