mirror of
https://github.com/dat515-2025/Group-8.git
synced 2026-03-22 15:12:08 +01:00
113 lines
3.3 KiB
Bash
Executable File
113 lines
3.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# Run tests against a disposable local MariaDB on host port 3307 using Docker Compose.
|
|
# Requirements: Docker, docker compose plugin, Python, Alembic, pytest.
|
|
# Usage:
|
|
# chmod +x ./test-with-ephemeral-mariadb.sh
|
|
# # From 7project/backend directory
|
|
# ./test-with-ephemeral-mariadb.sh [--only-unit|--only-integration|--only-e2e] [pytest-args...]
|
|
# # Examples:
|
|
# ./test-with-ephemeral-mariadb.sh --only-unit -q
|
|
# ./test-with-ephemeral-mariadb.sh --only-integration -k "login"
|
|
# ./test-with-ephemeral-mariadb.sh --only-e2e -vv
|
|
#
|
|
# This script will:
|
|
# 1) Start a MariaDB 11.4 container (ephemeral storage, port 3307)
|
|
# 2) Wait until it's healthy
|
|
# 3) Export env vars expected by the app (DATABASE_URL etc.)
|
|
# 4) Run Alembic migrations
|
|
# 5) Run pytest
|
|
# 6) Tear everything down (containers and tmpfs data)
|
|
|
|
COMPOSE_FILE="docker-compose.test.yml"
|
|
SERVICE_NAME="mariadb"
|
|
CONTAINER_NAME="test-mariadb"
|
|
|
|
if ! command -v docker >/dev/null 2>&1; then
|
|
echo "Docker is required but not found in PATH" >&2
|
|
exit 1
|
|
fi
|
|
if ! docker compose version >/dev/null 2>&1; then
|
|
echo "Docker Compose V2 plugin is required (docker compose)" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Bring up the DB
|
|
echo "Starting MariaDB (port 3307) with docker compose..."
|
|
docker compose -f "$COMPOSE_FILE" up -d
|
|
|
|
# Ensure we clean up on exit
|
|
cleanup() {
|
|
echo "\nTearing down docker compose stack..."
|
|
docker compose -f "$COMPOSE_FILE" down -v || true
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
# Wait for healthy container
|
|
echo -n "Waiting for MariaDB to become healthy"
|
|
for i in {1..60}; do
|
|
status=$(docker inspect -f '{{.State.Health.Status}}' "$CONTAINER_NAME" 2>/dev/null || echo "")
|
|
if [ "$status" = "healthy" ]; then
|
|
echo " -> healthy"
|
|
break
|
|
fi
|
|
echo -n "."
|
|
sleep 1
|
|
if [ $i -eq 60 ]; then
|
|
echo "\nMariaDB did not become healthy in time" >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
# Export env vars for the app/tests (match app/core/db.py expectations)
|
|
export MARIADB_HOST=127.0.0.1
|
|
export MARIADB_PORT=3307
|
|
export MARIADB_DB=group_project
|
|
export MARIADB_USER=appuser
|
|
export MARIADB_PASSWORD=apppass
|
|
export DATABASE_URL="mysql+asyncmy://$MARIADB_USER:$MARIADB_PASSWORD@$MARIADB_HOST:$MARIADB_PORT/$MARIADB_DB"
|
|
export PYTEST_RUN_CONFIG="True"
|
|
|
|
# Determine which tests to run based on flags
|
|
UNIT_TESTS="tests/test_unit_user_service.py"
|
|
INTEGRATION_TESTS="tests/test_integration_app.py"
|
|
E2E_TESTS="tests/test_e2e.py"
|
|
|
|
FLAG_COUNT=0
|
|
TEST_TARGET=""
|
|
declare -a PYTEST_ARGS=()
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--only-unit)
|
|
TEST_TARGET="$UNIT_TESTS"; FLAG_COUNT=$((FLAG_COUNT+1));;
|
|
--only-integration)
|
|
TEST_TARGET="$INTEGRATION_TESTS"; FLAG_COUNT=$((FLAG_COUNT+1));;
|
|
--only-e2e)
|
|
TEST_TARGET="$E2E_TESTS"; FLAG_COUNT=$((FLAG_COUNT+1));;
|
|
*)
|
|
PYTEST_ARGS+=("$arg");;
|
|
esac
|
|
done
|
|
|
|
if [ "$FLAG_COUNT" -gt 1 ]; then
|
|
echo "Error: Use only one of --only-unit, --only-integration, or --only-e2e" >&2
|
|
exit 2
|
|
fi
|
|
|
|
# Run Alembic migrations then tests
|
|
pushd . >/dev/null
|
|
echo "Running Alembic migrations..."
|
|
alembic upgrade head
|
|
|
|
echo "Running pytest..."
|
|
if [ -n "$TEST_TARGET" ]; then
|
|
# Use "${PYTEST_ARGS[@]:-}" to safely expand empty array with 'set -u'
|
|
pytest "$TEST_TARGET" "${PYTEST_ARGS[@]:-}"
|
|
else
|
|
# Use "${PYTEST_ARGS[@]:-}" to safely expand empty array with 'set -u'
|
|
pytest "${PYTEST_ARGS[@]:-}"
|
|
fi
|
|
popd >/dev/null
|
|
|
|
# Cleanup handled by trap |