#!/bin/bash # End-to-end test script for Sequential Thinking Age Wrapper set -e echo "๐Ÿงช Sequential Thinking Wrapper E2E Tests" echo "========================================" echo "" # Configuration WRAPPER_URL="${WRAPPER_URL:-http://localhost:8443}" JWT_TOKEN="${JWT_TOKEN:-}" AGE_RECIPIENT="${AGE_RECIPIENT:-}" AGE_IDENTITY="${AGE_IDENTITY:-}" # Color codes GREEN='\033[0;32m' RED='\033[0;31m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # Test counters TESTS_RUN=0 TESTS_PASSED=0 TESTS_FAILED=0 # Helper functions pass() { echo -e "${GREEN}โœ“${NC} $1" ((TESTS_PASSED++)) } fail() { echo -e "${RED}โœ—${NC} $1" ((TESTS_FAILED++)) } warn() { echo -e "${YELLOW}โš ${NC} $1" } test_start() { ((TESTS_RUN++)) echo "" echo "Test $TESTS_RUN: $1" echo "---" } # Test 1: Health Check test_start "Health endpoint" if curl -sf "$WRAPPER_URL/health" > /dev/null 2>&1; then pass "Health check passed" else fail "Health check failed" fi # Test 2: Readiness Check test_start "Readiness endpoint" if curl -sf "$WRAPPER_URL/ready" > /dev/null 2>&1; then pass "Readiness check passed" else fail "Readiness check failed" fi # Test 3: Metrics Endpoint test_start "Metrics endpoint" if curl -sf "$WRAPPER_URL/metrics" | grep -q "seqthink_requests_total"; then pass "Metrics endpoint accessible" else fail "Metrics endpoint failed" fi # Test 4: Unauthorized Request (no token) test_start "Unauthorized request rejection" HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$WRAPPER_URL/mcp/tool" \ -H "Content-Type: application/json" \ -d '{"tool":"test"}') if [ "$HTTP_CODE" = "401" ]; then pass "Unauthorized request correctly rejected (401)" else warn "Expected 401, got $HTTP_CODE (may be policy disabled)" fi # Test 5: Invalid Authorization Header test_start "Invalid authorization header" HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$WRAPPER_URL/mcp/tool" \ -H "Authorization: InvalidFormat" \ -H "Content-Type: application/json" \ -d '{"tool":"test"}') if [ "$HTTP_CODE" = "401" ]; then pass "Invalid auth header correctly rejected (401)" else warn "Expected 401, got $HTTP_CODE (may be policy disabled)" fi # Test 6: JWT Token Validation (if token provided) if [ -n "$JWT_TOKEN" ]; then test_start "JWT token validation" # Check if age keys are available if [ -n "$AGE_RECIPIENT" ] && [ -n "$AGE_IDENTITY" ]; then # Test with encryption test_start "Encrypted request with valid JWT" # Create test payload TEST_PAYLOAD='{"tool":"mcp__sequential-thinking__sequentialthinking","payload":{"thought":"Test thought","thoughtNumber":1,"totalThoughts":1,"nextThoughtNeeded":false}}' # Encrypt payload ENCRYPTED_PAYLOAD=$(echo "$TEST_PAYLOAD" | age -r "$AGE_RECIPIENT" 2>/dev/null) if [ $? -eq 0 ]; then # Send encrypted request HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$WRAPPER_URL/mcp/tool" \ -H "Authorization: Bearer $JWT_TOKEN" \ -H "Content-Type: application/age" \ -d "$ENCRYPTED_PAYLOAD") if [ "$HTTP_CODE" = "200" ]; then pass "Encrypted request with JWT succeeded" else fail "Encrypted request failed with HTTP $HTTP_CODE" fi else fail "Failed to encrypt test payload" fi else # Test without encryption (plaintext mode) test_start "Plaintext request with valid JWT" HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$WRAPPER_URL/mcp/tool" \ -H "Authorization: Bearer $JWT_TOKEN" \ -H "Content-Type: application/json" \ -d '{"tool":"mcp__sequential-thinking__sequentialthinking","payload":{"thought":"Test","thoughtNumber":1,"totalThoughts":1,"nextThoughtNeeded":false}}') if [ "$HTTP_CODE" = "200" ]; then pass "Plaintext request with JWT succeeded" else warn "Request failed with HTTP $HTTP_CODE" fi fi else warn "JWT_TOKEN not set - skipping authenticated tests" fi # Test 7: Content-Type Validation (if encryption enabled) if [ -n "$AGE_RECIPIENT" ]; then test_start "Content-Type validation for encrypted mode" HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$WRAPPER_URL/mcp/tool" \ -H "Authorization: Bearer ${JWT_TOKEN:-dummy}" \ -H "Content-Type: application/json" \ -d '{"tool":"test"}') if [ "$HTTP_CODE" = "415" ]; then pass "Incorrect Content-Type correctly rejected (415)" else warn "Expected 415, got $HTTP_CODE" fi fi # Test 8: Metrics Collection test_start "Metrics collection" METRICS=$(curl -s "$WRAPPER_URL/metrics") if echo "$METRICS" | grep -q "seqthink_requests_total"; then REQUEST_COUNT=$(echo "$METRICS" | grep "^seqthink_requests_total" | awk '{print $2}') pass "Request metrics collected (total: $REQUEST_COUNT)" else fail "Request metrics not found" fi if echo "$METRICS" | grep -q "seqthink_errors_total"; then ERROR_COUNT=$(echo "$METRICS" | grep "^seqthink_errors_total" | awk '{print $2}') pass "Error metrics collected (total: $ERROR_COUNT)" else fail "Error metrics not found" fi if echo "$METRICS" | grep -q "seqthink_policy_denials_total"; then DENIAL_COUNT=$(echo "$METRICS" | grep "^seqthink_policy_denials_total" | awk '{print $2}') pass "Policy denial metrics collected (total: $DENIAL_COUNT)" else warn "Policy denial metrics not found (may be policy disabled)" fi # Test 9: SSE Endpoint (basic check) test_start "SSE endpoint availability" # Just check if endpoint exists, don't try to consume stream HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 2 "$WRAPPER_URL/mcp/sse" 2>/dev/null || echo "timeout") if [ "$HTTP_CODE" = "401" ] || [ "$HTTP_CODE" = "200" ]; then pass "SSE endpoint exists (HTTP $HTTP_CODE)" else warn "SSE endpoint check inconclusive (HTTP $HTTP_CODE)" fi # Summary echo "" echo "========================================" echo "Test Summary" echo "========================================" echo "Tests Run: $TESTS_RUN" echo -e "${GREEN}Tests Passed: $TESTS_PASSED${NC}" if [ $TESTS_FAILED -gt 0 ]; then echo -e "${RED}Tests Failed: $TESTS_FAILED${NC}" fi echo "" if [ $TESTS_FAILED -eq 0 ]; then echo -e "${GREEN}โœ“ All tests passed!${NC}" exit 0 else echo -e "${RED}โœ— Some tests failed${NC}" exit 1 fi