#!/usr/bin/env bash # # UAT Pre-Flight Check: Validate API Readiness # # This script checks that all required API endpoints exist and return expected # responses before running UAT scenarios. # # Usage: # ./validate_api_readiness.sh [API_URL] # # Example: # ./validate_api_readiness.sh http://localhost:18180 set -euo pipefail # Validate required dependencies for cmd in curl grep; do if ! command -v "$cmd" &> /dev/null; then echo "ERROR: Required command '$cmd' is not installed." exit 1 fi done API_URL="${1:-http://localhost:18180}" TIMEOUT=5 echo "╔══════════════════════════════════════════════════════════════╗" echo "║ UAT Pre-Flight Check: API Readiness Validation ║" echo "╚══════════════════════════════════════════════════════════════╝" echo echo "Target API: $API_URL" echo "Timeout: ${TIMEOUT}s per check" echo # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color PASSED=0 FAILED=0 WARNINGS=0 # Helper: Check if endpoint exists and returns expected status check_endpoint() { local method="$1" local path="$2" local expected_status="$3" local description="$4" local data="${5:-}" echo -n " [$method $path] $description... " if [ "$method" = "GET" ]; then response=$(curl -s -w "\n%{http_code}" --max-time "$TIMEOUT" "$API_URL$path" 2>&1 || echo "000") else response=$(curl -s -w "\n%{http_code}" -X "$method" --max-time "$TIMEOUT" \ -H "Content-Type: application/json" \ -d "$data" \ "$API_URL$path" 2>&1 || echo "000") fi status=$(echo "$response" | tail -n1) if [ "$status" = "$expected_status" ]; then echo -e "${GREEN}✓${NC} ($status)" ((PASSED++)) return 0 elif [ "$status" = "000" ]; then echo -e "${RED}✗ Connection failed${NC}" ((FAILED++)) return 1 else echo -e "${YELLOW}⚠ Unexpected status: $status (expected $expected_status)${NC}" ((WARNINGS++)) return 1 fi } # 1. Health Check echo "1. Basic Connectivity" check_endpoint "GET" "/v1/health" "200" "Health check endpoint" echo # 2. Core API Endpoints echo "2. Core API Endpoints (UAT Dependencies)" check_endpoint "GET" "/v1/skeptic?subject=test&predicate=test" "404" "Skeptic query endpoint (expects 404 for empty DB)" check_endpoint "GET" "/v1/layered?subject=test&predicate=test" "404" "Layered query endpoint (expects 404 for empty DB)" check_endpoint "GET" "/v1/query?subject=test&predicate=test" "404" "Generic query endpoint (expects 404 for empty DB)" echo # 3. Assertion Creation (with invalid data to check endpoint exists) echo "3. Assertion Creation Endpoint" invalid_assertion='{"subject":"test","predicate":"test","object":{"type":"Text","value":"test"},"confidence":0.5,"source_class":"Clinical","source_hash":"0000000000000000000000000000000000000000000000000000000000000000","signatures":[]}' # This should fail validation (empty signatures), but endpoint should exist echo -n " [POST /v1/assert] Assertion endpoint... " response=$(curl -s -w "\n%{http_code}" --max-time "$TIMEOUT" \ -X POST "$API_URL/v1/assert" \ -H "Content-Type: application/json" \ -d "$invalid_assertion" 2>&1 || echo "000") status=$(echo "$response" | tail -n1) if [ "$status" = "400" ] || [ "$status" = "201" ]; then echo -e "${GREEN}✓${NC} (endpoint exists, got $status)" ((PASSED++)) elif [ "$status" = "000" ]; then echo -e "${RED}✗ Connection failed${NC}" ((FAILED++)) else echo -e "${YELLOW}⚠ Unexpected status: $status${NC}" ((WARNINGS++)) fi echo # 4. OpenAPI Documentation echo "4. OpenAPI Documentation" check_endpoint "GET" "/api-docs/openapi.json" "200" "OpenAPI spec" check_endpoint "GET" "/swagger-ui/index.html" "200" "Swagger UI" echo # 5. Required Data Structures (check OpenAPI schema) echo "5. Data Structure Validation" echo -n " Fetching OpenAPI spec... " openapi=$(curl -s --max-time "$TIMEOUT" "$API_URL/api-docs/openapi.json" 2>/dev/null || echo "{}") if [ "$openapi" != "{}" ]; then echo -e "${GREEN}✓${NC}" ((PASSED++)) # Check for required schemas echo -n " Checking CreateAssertionRequest schema... " if echo "$openapi" | grep -q "CreateAssertionRequest"; then echo -e "${GREEN}✓${NC}" ((PASSED++)) else echo -e "${YELLOW}⚠ Missing${NC}" ((WARNINGS++)) fi echo -n " Checking SkepticResponse schema... " if echo "$openapi" | grep -q "SkepticResponse"; then echo -e "${GREEN}✓${NC}" ((PASSED++)) else echo -e "${YELLOW}⚠ Missing${NC}" ((WARNINGS++)) fi echo -n " Checking LayeredQueryResponse schema... " if echo "$openapi" | grep -q "LayeredQueryResponse"; then echo -e "${GREEN}✓${NC}" ((PASSED++)) else echo -e "${YELLOW}⚠ Missing${NC}" ((WARNINGS++)) fi else echo -e "${RED}✗ Failed to fetch${NC}" ((FAILED++)) fi echo # 6. Source Class Support echo "6. Source Class Validation" echo " Expected source classes: Regulatory, Clinical, Expert, Crowd, Anecdotal" echo -n " Checking via OpenAPI... " if echo "$openapi" | grep -q "Regulatory"; then echo -e "${GREEN}✓${NC}" ((PASSED++)) else echo -e "${YELLOW}⚠ Source classes not documented${NC}" ((WARNINGS++)) fi echo # Summary echo "╔══════════════════════════════════════════════════════════════╗" echo "║ Summary ║" echo "╚══════════════════════════════════════════════════════════════╝" echo echo -e " ${GREEN}Passed:${NC} $PASSED" echo -e " ${YELLOW}Warnings:${NC} $WARNINGS" echo -e " ${RED}Failed:${NC} $FAILED" echo if [ "$FAILED" -gt 0 ]; then echo -e "${RED}❌ API is NOT ready for UAT execution${NC}" echo echo "Common issues:" echo " - API server not running (check: cargo run -p stemedb-api)" echo " - Wrong API URL (current: $API_URL)" echo " - Firewall blocking connections" echo " - API still starting up (wait a few seconds and retry)" exit 1 elif [ "$WARNINGS" -gt 0 ]; then echo -e "${YELLOW}⚠️ API is mostly ready, but some checks failed${NC}" echo echo "You can proceed with UAT, but some scenarios may fail." echo "Review the warnings above." exit 0 else echo -e "${GREEN}✅ API is READY for UAT execution${NC}" echo echo "Next steps:" echo " 1. Run all UAT scenarios:" echo " STEMEDB_API_URL=$API_URL cargo test --test consumer_health_uat run_all_uat_scenarios -- --ignored --nocapture" echo echo " 2. Run individual scenarios:" echo " STEMEDB_API_URL=$API_URL cargo test --test consumer_health_uat uat_glp1_muscle_loss_contradiction -- --ignored --nocapture" exit 0 fi