#!/bin/bash # Test script for Deno Subhosting migration # Usage: ./scripts/test-deno-subhosting.sh [API_URL] set -e API_URL="${1:-http://localhost:7130}" PASS=0 FAIL=0 # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color log_info() { echo -e "${YELLOW}[INFO]${NC} $1"; } log_pass() { echo -e "${GREEN}[PASS]${NC} $1"; PASS=$((PASS+1)); } log_fail() { echo -e "${RED}[FAIL]${NC} $1"; FAIL=$((FAIL+1)); } # Poll for deployment completion, sets DEPLOY_URL and DEPLOY_STATUS wait_for_deployment() { local max_attempts=${1:-30} local attempt=0 DEPLOY_URL="" DEPLOY_STATUS="" while [ $attempt -lt $max_attempts ]; do LIST_RESPONSE=$(curl -s "$API_URL/api/functions") DEPLOY_STATUS=$(echo "$LIST_RESPONSE" | grep -o '"deployment":{[^}]*}' | grep -o '"status":"[^"]*"' | cut -d'"' -f4) DEPLOY_URL=$(echo "$LIST_RESPONSE" | grep -o '"deployment":{[^}]*}' | grep -o '"url":"[^"]*"' | cut -d'"' -f4) if [ "$DEPLOY_STATUS" = "success" ]; then return 0 elif [ "$DEPLOY_STATUS" = "failed" ]; then return 1 fi echo -n "." sleep 2 attempt=$((attempt+1)) done return 1 } # ----------------------------------------------------------------------------- # Prerequisites Check # ----------------------------------------------------------------------------- log_info "Checking prerequisites..." # Check if API is reachable if ! curl -s "$API_URL/api/health" > /dev/null 2>&1; then log_fail "API not reachable at $API_URL" echo "Make sure the backend is running: cd backend && npm run dev" exit 1 fi log_pass "API reachable at $API_URL" # ----------------------------------------------------------------------------- # Test 1: Create Function # ----------------------------------------------------------------------------- log_info "Test 1: Creating test function..." CREATE_RESPONSE=$(curl -s -X POST "$API_URL/api/functions" \ -H "Content-Type: application/json" \ -d '{ "name": "subhosting-test", "slug": "subhosting-test", "code": "export default async function(req: Request) {\n const url = new URL(req.url);\n return new Response(JSON.stringify({\n message: \"Hello from Deno Subhosting!\",\n path: url.pathname,\n timestamp: new Date().toISOString()\n }), {\n headers: { \"Content-Type\": \"application/json\" }\n });\n}", "status": "active" }') if echo "$CREATE_RESPONSE" | grep -q '"slug":"subhosting-test"'; then log_pass "Function created successfully" else log_fail "Failed to create function: $CREATE_RESPONSE" fi # ----------------------------------------------------------------------------- # Test 2: Wait for Deployment # ----------------------------------------------------------------------------- log_info "Test 2: Waiting for deployment to complete..." if wait_for_deployment 30; then log_pass "Deployment succeeded: $DEPLOY_URL" else if [ "$DEPLOY_STATUS" = "failed" ]; then log_fail "Deployment failed" else log_fail "Deployment timed out" fi fi # ----------------------------------------------------------------------------- # Test 3: Invoke Function on Deno Subhosting # ----------------------------------------------------------------------------- if [ -n "$DEPLOY_URL" ] && [ "$DEPLOY_STATUS" = "success" ]; then log_info "Test 3: Invoking function on Deno Subhosting..." INVOKE_RESPONSE=$(curl -s "$DEPLOY_URL/subhosting-test" 2>/dev/null || echo "CURL_FAILED") if echo "$INVOKE_RESPONSE" | grep -q '"message":"Hello from Deno Subhosting!"'; then log_pass "Function invoked successfully on Deno Subhosting" echo "Response: $INVOKE_RESPONSE" else log_fail "Function invocation failed: $INVOKE_RESPONSE" fi else log_info "Skipping invocation test (deployment not successful)" fi # ----------------------------------------------------------------------------- # Test 4: Update Function # ----------------------------------------------------------------------------- log_info "Test 4: Updating function..." UPDATE_RESPONSE=$(curl -s -X PATCH "$API_URL/api/functions/subhosting-test" \ -H "Content-Type: application/json" \ -d '{ "code": "export default async function(req: Request) {\n return new Response(JSON.stringify({\n message: \"Updated function!\",\n version: 2\n }), {\n headers: { \"Content-Type\": \"application/json\" }\n });\n}" }') if echo "$UPDATE_RESPONSE" | grep -q '"slug":"subhosting-test"'; then log_pass "Function updated successfully" else log_fail "Failed to update function: $UPDATE_RESPONSE" fi # Wait for redeployment and get new deployment URL log_info "Waiting for redeployment..." if wait_for_deployment 30; then UPDATED_RESPONSE=$(curl -s "$DEPLOY_URL/subhosting-test" 2>/dev/null || echo "CURL_FAILED") if echo "$UPDATED_RESPONSE" | grep -q '"version":2'; then log_pass "Updated function works on Deno Subhosting" else log_fail "Updated function not reflecting changes: $UPDATED_RESPONSE" fi else log_fail "Redeployment failed or timed out" fi # ----------------------------------------------------------------------------- # Test 5: Create Function with Secret Access # ----------------------------------------------------------------------------- log_info "Test 5: Creating function that accesses secrets..." SECRET_FUNC_RESPONSE=$(curl -s -X POST "$API_URL/api/functions" \ -H "Content-Type: application/json" \ -d '{ "name": "secret-test", "slug": "secret-test", "code": "export default async function(req: Request) {\n const envKeys = Object.keys(Deno.env.toObject()).filter(k => !k.startsWith(\"DENO_\"));\n return new Response(JSON.stringify({\n message: \"Secret test\",\n availableEnvVars: envKeys.length,\n hasSecrets: envKeys.length > 0\n }), {\n headers: { \"Content-Type\": \"application/json\" }\n });\n}", "status": "active" }') if echo "$SECRET_FUNC_RESPONSE" | grep -q '"slug":"secret-test"'; then log_pass "Secret test function created" else log_fail "Failed to create secret test function: $SECRET_FUNC_RESPONSE" fi # Wait for deployment sleep 10 if [ -n "$DEPLOY_URL" ]; then SECRET_RESPONSE=$(curl -s "$DEPLOY_URL/secret-test" 2>/dev/null || echo "CURL_FAILED") log_info "Secret test response: $SECRET_RESPONSE" fi # ----------------------------------------------------------------------------- # Test 6: List Functions with Deployment Info # ----------------------------------------------------------------------------- log_info "Test 6: Checking list functions includes deployment info..." LIST_FINAL=$(curl -s "$API_URL/api/functions") if echo "$LIST_FINAL" | grep -q '"deployment"'; then log_pass "List functions includes deployment info" echo "$LIST_FINAL" | jq '.deployment' 2>/dev/null || echo "Deployment info present" else log_fail "List functions missing deployment info" fi # ----------------------------------------------------------------------------- # Test 7: Delete Function # ----------------------------------------------------------------------------- log_info "Test 7: Deleting test functions..." curl -s -X DELETE "$API_URL/api/functions/subhosting-test" > /dev/null curl -s -X DELETE "$API_URL/api/functions/secret-test" > /dev/null log_pass "Functions deleted (cleanup)" # Wait for redeployment without deleted functions sleep 5 # Verify functions are gone from Deno Subhosting if [ -n "$DEPLOY_URL" ]; then GONE_RESPONSE=$(curl -s "$DEPLOY_URL/subhosting-test" 2>/dev/null || echo "CURL_FAILED") if echo "$GONE_RESPONSE" | grep -q '"error":"Function not found"'; then log_pass "Deleted function no longer accessible on Deno Subhosting" else log_info "Function may still be cached: $GONE_RESPONSE" fi fi # ----------------------------------------------------------------------------- # Summary # ----------------------------------------------------------------------------- echo "" echo "============================================" echo "Test Summary" echo "============================================" echo -e "${GREEN}Passed: $PASS${NC}" echo -e "${RED}Failed: $FAIL${NC}" echo "============================================" if [ $FAIL -gt 0 ]; then exit 1 fi