#!/bin/bash # test-local.sh - Run full CI test suite locally using Docker # Sprint: SPRINT_20251226_006_CICD # # Usage: # ./devops/scripts/test-local.sh # Run all PR-gating tests # ./devops/scripts/test-local.sh --category Unit # Run specific category # ./devops/scripts/test-local.sh --build-only # Only build, skip tests # ./devops/scripts/test-local.sh --no-docker # Run directly without Docker set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" # Configuration CI_IMAGE="stellaops-ci:local" DOCKERFILE="$REPO_ROOT/devops/docker/Dockerfile.ci" RESULTS_DIR="$REPO_ROOT/TestResults" # Default options USE_DOCKER=true BUILD_ONLY=false SPECIFIC_CATEGORY="" REBUILD_IMAGE=false # PR-gating test categories PR_GATING_CATEGORIES=(Unit Architecture Contract Integration Security Golden) # Parse arguments while [[ $# -gt 0 ]]; do case $1 in --category) SPECIFIC_CATEGORY="$2" shift 2 ;; --build-only) BUILD_ONLY=true shift ;; --no-docker) USE_DOCKER=false shift ;; --rebuild) REBUILD_IMAGE=true shift ;; --help) echo "Usage: $0 [OPTIONS]" echo "" echo "Options:" echo " --category CATEGORY Run only specific test category" echo " --build-only Only build, skip tests" echo " --no-docker Run directly without Docker container" echo " --rebuild Force rebuild of CI Docker image" echo " --help Show this help message" echo "" echo "Available categories: ${PR_GATING_CATEGORIES[*]}" exit 0 ;; *) echo "Unknown option: $1" exit 1 ;; esac done echo "=== StellaOps Local CI Test Runner ===" echo "Repository: $REPO_ROOT" echo "Use Docker: $USE_DOCKER" echo "Build Only: $BUILD_ONLY" echo "Category: ${SPECIFIC_CATEGORY:-All PR-gating}" # Create results directory mkdir -p "$RESULTS_DIR" run_tests() { local category=$1 echo "" echo "=== Running $category tests ===" dotnet test "$REPO_ROOT/src/StellaOps.sln" \ --filter "Category=$category" \ --configuration Release \ --no-build \ --logger "trx;LogFileName=${category}-tests.trx" \ --results-directory "$RESULTS_DIR/$category" \ --verbosity minimal || true } run_build() { echo "" echo "=== Restoring dependencies ===" dotnet restore "$REPO_ROOT/src/StellaOps.sln" echo "" echo "=== Building solution ===" dotnet build "$REPO_ROOT/src/StellaOps.sln" \ --configuration Release \ --no-restore } run_all_tests() { run_build if [[ "$BUILD_ONLY" == "true" ]]; then echo "" echo "=== Build completed (tests skipped) ===" return fi if [[ -n "$SPECIFIC_CATEGORY" ]]; then run_tests "$SPECIFIC_CATEGORY" else for category in "${PR_GATING_CATEGORIES[@]}"; do run_tests "$category" done fi echo "" echo "=== Test Summary ===" find "$RESULTS_DIR" -name "*.trx" -exec echo " Found: {}" \; # Convert TRX to JUnit if trx2junit is available if command -v trx2junit &>/dev/null; then echo "" echo "=== Converting TRX to JUnit ===" find "$RESULTS_DIR" -name "*.trx" -exec trx2junit {} \; 2>/dev/null || true fi } if [[ "$USE_DOCKER" == "true" ]]; then # Check if Docker is available if ! command -v docker &>/dev/null; then echo "Error: Docker is not installed or not in PATH" echo "Use --no-docker to run tests directly" exit 1 fi # Build CI image if needed if [[ "$REBUILD_IMAGE" == "true" ]] || ! docker image inspect "$CI_IMAGE" &>/dev/null; then echo "" echo "=== Building CI Docker image ===" docker build -t "$CI_IMAGE" -f "$DOCKERFILE" "$REPO_ROOT" fi # Run in Docker container echo "" echo "=== Running in Docker container ===" DOCKER_ARGS=( --rm -v "$REPO_ROOT:/src" -v "$RESULTS_DIR:/src/TestResults" -e DOTNET_NOLOGO=1 -e DOTNET_CLI_TELEMETRY_OPTOUT=1 -w /src ) # Mount Docker socket if available (for Testcontainers) if [[ -S /var/run/docker.sock ]]; then DOCKER_ARGS+=(-v /var/run/docker.sock:/var/run/docker.sock) fi # Build test command TEST_CMD="./devops/scripts/test-local.sh --no-docker" if [[ -n "$SPECIFIC_CATEGORY" ]]; then TEST_CMD="$TEST_CMD --category $SPECIFIC_CATEGORY" fi if [[ "$BUILD_ONLY" == "true" ]]; then TEST_CMD="$TEST_CMD --build-only" fi docker run "${DOCKER_ARGS[@]}" "$CI_IMAGE" bash -c "$TEST_CMD" else # Run directly run_all_tests fi echo "" echo "=== Done ===" echo "Results saved to: $RESULTS_DIR"