Skip to content

test:Add comprehensive unit and integration tests for security, QR co… #18

test:Add comprehensive unit and integration tests for security, QR co…

test:Add comprehensive unit and integration tests for security, QR co… #18

Workflow file for this run

name: Docker Compose CI/CD
on:
push:
branches: '**'
pull_request:
branches: [ 'main' ]
workflow_dispatch:
inputs:
run_tests:
description: 'Run integration tests'
required: false
default: true
type: boolean
env:
COMPOSE_HTTP_TIMEOUT: 300
COMPOSE_PROJECT_NAME: acfc-ci
jobs:
docker-validation:
name: Docker Compose Validation & Testing
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver-opts: network=host
- name: Validate docker-compose.yml syntax
run: |
docker compose -f docker-compose.yml config --quiet
echo "✅ docker-compose.yml syntax is valid"
- name: Create .env file for CI
run: |
cat > .env << EOF
# CI Environment Variables
DB_HOST=localhost
DB_PORT=3306
DB_NAME=acfc_db
DB_USER=acfc_user
DB_PASSWORD=secure_password
MYSQL_ROOT_PASSWORD=root_secure_password
MYSQL_DATABASE=acfc_db
MYSQL_USER=acfc_user
MYSQL_PASSWORD=exemple_pwd
DB_ROOT_PASSWORD=root_secure_password
DB_HOST=acfc-db
MONGO_INITDB_DATABASE=acfc_logs
MONGO_INITDB_ROOT_USERNAME=admin
MONGO_INITDB_ROOT_PASSWORD=changeme
MONGO_HOST=acfc-logs
MONGO_PORT=27017
SESSION_PASSKEY=change_me_to_a_random_long_secret
API_SECRET=replace_with_real_secret
EOF
- name: Build all Docker images
run: |
echo "🔨 Building Docker images..."
docker compose -f docker-compose.yml build --parallel --no-cache
echo "✅ All images built successfully"
- name: Start services and wait for readiness
run: |
echo "🚀 Starting services..."
docker compose -f docker-compose.yml up -d
echo "⏳ Waiting for services to be ready..."
# Wait for database to be healthy (longer timeout for CI)
echo "Waiting for MariaDB to be healthy..."
timeout 180s bash -c 'until docker compose -f docker-compose.yml ps acfc-db | grep -q "healthy"; do echo "Waiting for DB..."; sleep 5; done'
echo "✅ MariaDB is healthy"
# Wait for MongoDB to be ready (using mongo client instead of mongosh)
echo "Waiting for MongoDB to be ready..."
timeout 120s bash -c 'until docker compose -f docker-compose.yml exec -T acfc-logs mongo --eval "db.adminCommand(\"ping\")" > /dev/null 2>&1 || docker compose -f docker-compose.yml exec -T acfc-logs mongosh --eval "db.adminCommand(\"ping\")" > /dev/null 2>&1; do echo "Waiting for MongoDB..."; sleep 5; done'
echo "✅ MongoDB is ready"
# Wait for Flask app to respond (try health endpoint first, then root)
echo "Waiting for Flask app to respond..."
timeout 90s bash -c 'until curl -f http://localhost:5000/health > /dev/null 2>&1; do echo "Waiting for Flask app..."; sleep 3; done'
echo "✅ Flask app is responding"
echo "✅ All services are ready"
- name: Run service health checks
run: |
echo "🔍 Running health checks..."
# Check container status
echo "Container status:"
docker compose -f docker-compose.yml ps
# Test database connection
echo "Testing MariaDB connection..."
docker compose -f docker-compose.yml exec -T acfc-db mariadb -u acfc_user -psecure_password -e "SELECT 1 as test;" acfc_db || {
echo "❌ MariaDB connection failed"
exit 1
}
echo "✅ MariaDB connection successful"
# Test MongoDB connection (try both mongo and mongosh)
echo "Testing MongoDB connection..."
docker compose -f docker-compose.yml exec -T acfc-logs mongo --eval "db.adminCommand('ping')" || \
docker compose -f docker-compose.yml exec -T acfc-logs mongosh --eval "db.adminCommand('ping')" || {
echo "❌ MongoDB connection failed"
exit 1
}
echo "✅ MongoDB connection successful"
# Test Flask app endpoint
echo "Testing Flask app endpoints..."
if curl -f http://localhost:5000/health > /dev/null 2>&1; then
echo "✅ Flask health endpoint OK"
elif curl -f http://localhost:5000/ > /dev/null 2>&1; then
echo "✅ Flask root endpoint OK"
else
echo "❌ Flask app is not responding"
exit 1
fi
echo "✅ All health checks passed"
- name: Run integration tests
if: github.event.inputs.run_tests != 'false'
run: |
echo "🧪 Running integration tests..."
# Test database connectivity from app
docker compose -f docker-compose.yml exec -T acfc-app python -c "
import sys
try:
from app_acfc.modeles import db
print('✅ Database connection successful')
except Exception as e:
print(f'❌ Database connection failed: {e}')
sys.exit(1)
" || echo "⚠️ Database test skipped (no db module found)"
# Test web endpoints
echo "Testing web endpoints..."
curl -f -s http://localhost:5000/ > /dev/null && echo "✅ Root endpoint OK" || echo "❌ Root endpoint failed"
curl -f -s http://localhost:80/ > /dev/null && echo "✅ Nginx proxy OK" || echo "⚠️ Nginx proxy not responding"
echo "✅ Integration tests completed"
- name: Collect container logs
if: always()
run: |
echo "📋 Collecting container logs..."
mkdir -p logs
docker compose -f docker-compose.yml logs --no-color acfc-app > logs/app.log 2>&1 || true
docker compose -f docker-compose.yml logs --no-color acfc-db > logs/database.log 2>&1 || true
docker compose -f docker-compose.yml logs --no-color acfc-logs > logs/mongodb.log 2>&1 || true
docker compose -f docker-compose.yml logs --no-color acfc-nginx > logs/nginx.log 2>&1 || true
# Get container status
docker compose -f docker-compose.yml ps > logs/containers-status.txt 2>&1 || true
echo "📋 Logs collected"
- name: Upload logs and artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: docker-logs-${{ github.run_number }}
path: logs/
retention-days: 7
- name: Cleanup containers
if: always()
run: |
echo "🧹 Cleaning up..."
docker compose -f docker-compose.yml down --volumes --remove-orphans
docker system prune -f
echo "✅ Cleanup completed"
- name: Report results
if: always()
run: |
if [ "${{ job.status }}" == "success" ]; then
echo "🎉 Docker Compose validation completed successfully!"
echo "✅ All services started and responded correctly"
echo "✅ Health checks passed"
echo "✅ Integration tests passed"
else
echo "❌ Docker Compose validation failed"
echo "📋 Check the uploaded logs for details"
exit 1
fi