Files
customer-installer/test_postgrest_api.sh

208 lines
8.1 KiB
Bash
Raw Normal View History

#!/usr/bin/env bash
set -Eeuo pipefail
# PostgREST API Testing Script
# Tests the Supabase-compatible REST API for vector storage
# Color codes
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# Configuration
CTID="${1:-769276659}"
CT_IP="${2:-192.168.45.45}"
JWT_SECRET="${3:-IM9/HRQR9mw63lU/1G7vXPMe7q0n3oLcr35dryv0ToU=}"
ANON_KEY="${4:-eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlzcyI6InN1cGFiYXNlIiwiaWF0IjoxNzAwMDAwMDAwLCJleHAiOjIwMDAwMDAwMDB9.6eAdv5-GWC35tHju8V_7is02G3HaoQfVk2UCDC1Tf5o}"
SERVICE_KEY="${5:-eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoic2VydmljZV9yb2xlIiwiaXNzIjoic3VwYWJhc2UiLCJpYXQiOjE3MDAwMDAwMDAsImV4cCI6MjAwMDAwMDAwMH0.jBMTvYi7DxgwtxEmUzsDfKd66LJoFlmPAYiGCTXYKmc}"
TESTS_PASSED=0
TESTS_FAILED=0
print_test() { echo -e "${BLUE}[TEST]${NC} $1"; }
print_pass() { echo -e "${GREEN}[PASS]${NC} $1"; ((TESTS_PASSED++)); }
print_fail() { echo -e "${RED}[FAIL]${NC} $1"; ((TESTS_FAILED++)); }
print_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE}PostgREST API Test Suite${NC}"
echo -e "${BLUE}========================================${NC}"
echo ""
# Test 1: PostgREST root endpoint
print_test "Testing PostgREST root endpoint..."
ROOT_RESPONSE=$(curl -s -o /dev/null -w '%{http_code}' "http://${CT_IP}:3000/" 2>/dev/null || echo "000")
if [[ "$ROOT_RESPONSE" == "200" ]]; then
print_pass "PostgREST root endpoint accessible (HTTP ${ROOT_RESPONSE})"
else
print_fail "PostgREST root endpoint not accessible (HTTP ${ROOT_RESPONSE})"
fi
# Test 2: List tables via PostgREST
print_test "Listing available tables via PostgREST..."
TABLES_RESPONSE=$(curl -s "http://${CT_IP}:3000/" \
-H "apikey: ${ANON_KEY}" \
-H "Authorization: Bearer ${ANON_KEY}" 2>/dev/null || echo "")
if echo "$TABLES_RESPONSE" | grep -q "documents"; then
print_pass "Documents table is exposed via PostgREST"
else
print_fail "Documents table not found in PostgREST response"
fi
# Test 3: Query documents table (should be empty initially)
print_test "Querying documents table..."
DOCS_RESPONSE=$(curl -s "http://${CT_IP}:3000/documents?select=*" \
-H "apikey: ${ANON_KEY}" \
-H "Authorization: Bearer ${ANON_KEY}" \
-H "Content-Type: application/json" 2>/dev/null || echo "[]")
if [[ "$DOCS_RESPONSE" == "[]" ]] || echo "$DOCS_RESPONSE" | grep -q '\['; then
DOC_COUNT=$(echo "$DOCS_RESPONSE" | grep -o '"id"' | wc -l || echo "0")
print_pass "Documents table accessible (${DOC_COUNT} documents)"
else
print_fail "Failed to query documents table: ${DOCS_RESPONSE}"
fi
# Test 4: Test with service role key (higher privileges)
print_test "Testing with service role key..."
SERVICE_RESPONSE=$(curl -s "http://${CT_IP}:3000/documents?select=count" \
-H "apikey: ${SERVICE_KEY}" \
-H "Authorization: Bearer ${SERVICE_KEY}" \
-H "Content-Type: application/json" 2>/dev/null || echo "error")
if [[ "$SERVICE_RESPONSE" != "error" ]]; then
print_pass "Service role key authentication successful"
else
print_fail "Service role key authentication failed"
fi
# Test 5: Test CORS headers
print_test "Checking CORS headers..."
CORS_RESPONSE=$(curl -s -I "http://${CT_IP}:3000/documents" \
-H "Origin: http://example.com" \
-H "apikey: ${ANON_KEY}" 2>/dev/null || echo "")
if echo "$CORS_RESPONSE" | grep -qi "access-control-allow-origin"; then
print_pass "CORS headers present"
else
print_info "CORS headers not found (may be expected depending on configuration)"
fi
# Test 6: Test RPC function (match_documents)
print_test "Testing match_documents RPC function..."
RPC_RESPONSE=$(curl -s -X POST "http://${CT_IP}:3000/rpc/match_documents" \
-H "apikey: ${SERVICE_KEY}" \
-H "Authorization: Bearer ${SERVICE_KEY}" \
-H "Content-Type: application/json" \
-d '{"query_embedding":"[0.1,0.2,0.3]","match_count":5}' 2>/dev/null || echo "error")
# This will fail if no documents exist, but we're testing if the function is accessible
if echo "$RPC_RESPONSE" | grep -q "error\|code" && ! echo "$RPC_RESPONSE" | grep -q "PGRST"; then
print_info "match_documents function exists (no documents to match yet)"
elif [[ "$RPC_RESPONSE" == "[]" ]]; then
print_pass "match_documents function accessible (empty result)"
else
print_info "RPC response: ${RPC_RESPONSE:0:100}"
fi
# Test 7: Check PostgREST schema cache
print_test "Checking PostgREST schema introspection..."
SCHEMA_RESPONSE=$(curl -s "http://${CT_IP}:3000/" \
-H "apikey: ${ANON_KEY}" \
-H "Accept: application/openapi+json" 2>/dev/null || echo "{}")
if echo "$SCHEMA_RESPONSE" | grep -q "openapi\|swagger"; then
print_pass "PostgREST OpenAPI schema available"
else
print_info "OpenAPI schema not available (may require specific configuration)"
fi
# Test 8: Test PostgreSQL connection from PostgREST
print_test "Verifying PostgREST database connection..."
PG_CONN=$(pct exec "${CTID}" -- bash -lc "docker logs customer-postgrest 2>&1 | grep -i 'listening\|connection\|ready' | tail -3" || echo "")
if [[ -n "$PG_CONN" ]]; then
print_pass "PostgREST has database connection logs"
print_info "Recent logs: ${PG_CONN:0:100}"
else
print_info "No connection logs found (may be normal)"
fi
# Test 9: Test invalid authentication
print_test "Testing authentication rejection with invalid key..."
INVALID_RESPONSE=$(curl -s -o /dev/null -w '%{http_code}' "http://${CT_IP}:3000/documents" \
-H "apikey: invalid_key_12345" \
-H "Authorization: Bearer invalid_key_12345" 2>/dev/null || echo "000")
if [[ "$INVALID_RESPONSE" == "401" ]] || [[ "$INVALID_RESPONSE" == "403" ]]; then
print_pass "Invalid authentication properly rejected (HTTP ${INVALID_RESPONSE})"
else
print_info "Authentication response: HTTP ${INVALID_RESPONSE}"
fi
# Test 10: Check PostgREST container health
print_test "Checking PostgREST container health..."
POSTGREST_HEALTH=$(pct exec "${CTID}" -- bash -lc "docker inspect customer-postgrest --format='{{.State.Health.Status}}'" 2>/dev/null || echo "unknown")
if [[ "$POSTGREST_HEALTH" == "healthy" ]] || [[ "$POSTGREST_HEALTH" == "unknown" ]]; then
print_pass "PostgREST container is healthy"
else
print_fail "PostgREST container health: ${POSTGREST_HEALTH}"
fi
# Test 11: Test content negotiation
print_test "Testing content negotiation (JSON)..."
JSON_RESPONSE=$(curl -s "http://${CT_IP}:3000/documents?limit=1" \
-H "apikey: ${ANON_KEY}" \
-H "Accept: application/json" 2>/dev/null || echo "")
if echo "$JSON_RESPONSE" | grep -q '\[' || [[ "$JSON_RESPONSE" == "[]" ]]; then
print_pass "JSON content type supported"
else
print_fail "JSON content negotiation failed"
fi
# Test 12: Check PostgREST version
print_test "Checking PostgREST version..."
VERSION=$(pct exec "${CTID}" -- bash -lc "docker exec customer-postgrest postgrest --version 2>/dev/null" || echo "unknown")
if [[ "$VERSION" != "unknown" ]]; then
print_pass "PostgREST version: ${VERSION}"
else
print_info "Could not determine PostgREST version"
fi
# Test 13: Test from inside n8n container (internal network)
print_test "Testing PostgREST from n8n container (internal network)..."
INTERNAL_TEST=$(pct exec "${CTID}" -- bash -lc "docker exec n8n curl -s -o /dev/null -w '%{http_code}' 'http://postgrest:3000/'" 2>/dev/null || echo "000")
if [[ "$INTERNAL_TEST" == "200" ]]; then
print_pass "PostgREST accessible from n8n container (HTTP ${INTERNAL_TEST})"
else
print_fail "PostgREST not accessible from n8n container (HTTP ${INTERNAL_TEST})"
fi
# Summary
echo ""
echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE}PostgREST Test Summary${NC}"
echo -e "${BLUE}========================================${NC}"
TOTAL=$((TESTS_PASSED + TESTS_FAILED))
echo -e "Total Tests: ${TOTAL}"
echo -e "${GREEN}Passed: ${TESTS_PASSED}${NC}"
echo -e "${RED}Failed: ${TESTS_FAILED}${NC}"
echo ""
if [[ $TESTS_FAILED -eq 0 ]]; then
echo -e "${GREEN}✓ All PostgREST tests passed!${NC}"
echo ""
echo -e "${BLUE}API Endpoints:${NC}"
echo -e " Base URL: http://${CT_IP}:3000"
echo -e " Documents: http://${CT_IP}:3000/documents"
echo -e " RPC: http://${CT_IP}:3000/rpc/match_documents"
echo ""
exit 0
else
echo -e "${YELLOW}⚠ Some tests failed. Review output above.${NC}"
exit 1
fi