From a8e1095abc866a5407d987fda358924c922c7fb2 Mon Sep 17 00:00:00 2001 From: jay brown Date: Fri, 8 Aug 2025 12:38:43 -0700 Subject: [PATCH] manual tests --- scripts/manual_tests/readme.md | 4 + scripts/manual_tests/test.pdf | Bin 0 -> 68240 bytes scripts/manual_tests/test_zip_upload.sh | 306 ++++++++++++++++++ .../manual_tests/upload_single_document.sh | 67 ++++ 4 files changed, 377 insertions(+) create mode 100644 scripts/manual_tests/readme.md create mode 100644 scripts/manual_tests/test.pdf create mode 100755 scripts/manual_tests/test_zip_upload.sh create mode 100755 scripts/manual_tests/upload_single_document.sh diff --git a/scripts/manual_tests/readme.md b/scripts/manual_tests/readme.md new file mode 100644 index 00000000..da1f66ea --- /dev/null +++ b/scripts/manual_tests/readme.md @@ -0,0 +1,4 @@ +# Manual tests +The assets in this directory are not part of the automated tests. +They are manual tests for debugging and demo purposes so that +the tests can be paused and interacted with. diff --git a/scripts/manual_tests/test.pdf b/scripts/manual_tests/test.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f3a3fb900bc73ecc435d362b1a7ae6f1539fc381 GIT binary patch literal 68240 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 literal 0 HcmV?d00001 diff --git a/scripts/manual_tests/test_zip_upload.sh b/scripts/manual_tests/test_zip_upload.sh new file mode 100755 index 00000000..74b2e40a --- /dev/null +++ b/scripts/manual_tests/test_zip_upload.sh @@ -0,0 +1,306 @@ +#!/bin/bash + +# Test script for ZIP batch upload functionality +# This script exercises all batch endpoints with a running deployment +# use: task compose:up (or compose:refresh if you have made service changes) +# connect to the db like this +# jdbc:postgresql://localhost:5432/query_orchestration +# +# then to look at the assets +# List all buckets: +# aws --endpoint-url=http://localhost:4566 s3 ls +# +# List contents of a specific bucket: +# aws --endpoint-url=http://localhost:4566 s3 ls s3://documentin/ +# +# List recursively to see all files in subdirectories: +# aws --endpoint-url=http://localhost:4566 s3 ls s3://documentin/ --recursive +# +# REST API operations tested: +# - GET /metrics - Check service health +# - POST /client - Create new test client +# - POST /client/{CLIENT_ID}/document/batch - Upload ZIP file with multiple PDFs +# - GET /client/{CLIENT_ID}/document/batch/{BATCH_ID} - Get batch status and details +# - GET /client/{CLIENT_ID}/document/batch - List all batches for client with pagination +# - POST /client/{CLIENT_ID}/document/batch (invalid) - Test error handling with non-ZIP file +# - DELETE /client/{CLIENT_ID}/document/batch/{BATCH_ID} - Cancel/delete batch processing + +set -e # Exit on any error + +# Configuration +BASE_URL="http://localhost:8080" +CLIENT_ID="test_client_$(date +%s)" +ZIP_FILE="test_batch.zip" +TEST_PDF_COUNT=3 + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# Logging functions +log_info() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +# Check if service is running +check_service() { + log_info "Checking if queryAPI service is running..." + if ! curl -s "$BASE_URL/metrics" > /dev/null 2>&1; then + log_error "queryAPI service is not running at $BASE_URL" + log_info "Please start the stack with: task compose:up" + exit 1 + fi + log_info "Service is running" +} + +# Create test ZIP file with PDFs +create_test_zip() { + log_info "Creating test ZIP file with $TEST_PDF_COUNT PDFs..." + + # Remove existing file if it exists + rm -f "$ZIP_FILE" + + # Create temporary directory for PDF files + temp_dir=$(mktemp -d) + + # Create test PDF files + for i in $(seq 1 $TEST_PDF_COUNT); do + pdf_file="$temp_dir/test${i}.pdf" + cat > "$pdf_file" << EOF +%PDF-1.4 +%Test content for test${i}.pdf +1 0 obj +<< +/Type /Catalog +/Pages 2 0 R +>> +endobj +2 0 obj +<< +/Type /Pages +/Kids [3 0 R] +/Count 1 +>> +endobj +3 0 obj +<< +/Type /Page +/Parent 2 0 R +/MediaBox [0 0 612 792] +>> +endobj +xref +0 4 +0000000000 65535 f +0000000010 00000 n +0000000053 00000 n +0000000125 00000 n +trailer +<< +/Size 4 +/Root 1 0 R +>> +startxref +284 +%%EOF +EOF + done + + # Create ZIP file using absolute path + current_dir=$(pwd) + cd "$temp_dir" + zip -q "$current_dir/$ZIP_FILE" *.pdf + cd "$current_dir" + + # Cleanup temp directory + rm -rf "$temp_dir" + + file_size=$(stat -f%z "$ZIP_FILE" 2>/dev/null || stat -c%s "$ZIP_FILE" 2>/dev/null || echo "unknown") + log_info "Created $ZIP_FILE with $TEST_PDF_COUNT PDFs ($file_size bytes)" +} + +# Create client (idempotent) +create_client() { + log_info "Creating/checking client: $CLIENT_ID" + + # Try to create client, ignore if already exists + response=$(curl -s -w "\n%{http_code}" -X POST "$BASE_URL/client" \ + -H "Content-Type: application/json" \ + -d "{\"id\":\"$CLIENT_ID\",\"name\":\"Test Client $CLIENT_ID\"}" 2>/dev/null || echo "000") + + http_code=$(echo "$response" | tail -n1) + + if [ "$http_code" = "201" ] || [ "$http_code" = "200" ]; then + log_info "Client created/exists: $CLIENT_ID" + elif [ "$http_code" = "409" ] || [ "$http_code" = "400" ]; then + log_info "Client already exists or duplicate name: $CLIENT_ID" + else + log_warn "Unexpected response when creating client (HTTP $http_code), continuing anyway..." + fi +} + +# Upload ZIP batch +upload_batch() { + log_info "Uploading ZIP batch..." + + response=$(curl -s -w "\n%{http_code}" -X POST "$BASE_URL/client/$CLIENT_ID/document/batch" \ + -F "archive=@$ZIP_FILE" 2>/dev/null) + + http_code=$(echo "$response" | tail -n1) + response_body=$(echo "$response" | head -n -1) + + if [ "$http_code" = "202" ]; then + BATCH_ID=$(echo "$response_body" | grep -o '"batch_id":"[^"]*"' | cut -d'"' -f4) + STATUS_URL=$(echo "$response_body" | grep -o '"status_url":"[^"]*"' | cut -d'"' -f4) + log_info "Batch uploaded successfully" + log_info "Batch ID: $BATCH_ID" + log_info "Status URL: $STATUS_URL" + return 0 + else + log_error "Failed to upload batch (HTTP $http_code)" + echo "$response_body" + return 1 + fi +} + +# Get batch status +get_batch_status() { + log_info "Getting batch status..." + + response=$(curl -s -w "\n%{http_code}" "$BASE_URL/client/$CLIENT_ID/document/batch/$BATCH_ID" 2>/dev/null) + + http_code=$(echo "$response" | tail -n1) + response_body=$(echo "$response" | head -n -1) + + if [ "$http_code" = "200" ]; then + status=$(echo "$response_body" | grep -o '"status":"[^"]*"' | cut -d'"' -f4) + filename=$(echo "$response_body" | grep -o '"originalFilename":"[^"]*"' | cut -d'"' -f4) + log_info "Batch status: $status" + log_info "Original filename: $filename" + echo "$response_body" | python3 -m json.tool 2>/dev/null || echo "$response_body" + return 0 + else + log_error "Failed to get batch status (HTTP $http_code)" + echo "$response_body" + return 1 + fi +} + +# List batches for client +list_batches() { + log_info "Listing batches for client..." + + response=$(curl -s -w "\n%{http_code}" "$BASE_URL/client/$CLIENT_ID/document/batch?limit=10&offset=0" 2>/dev/null) + + http_code=$(echo "$response" | tail -n1) + response_body=$(echo "$response" | head -n -1) + + if [ "$http_code" = "200" ]; then + batch_count=$(echo "$response_body" | grep -o '"totalCount":[0-9]*' | cut -d':' -f2) + log_info "Found $batch_count batches" + echo "$response_body" | python3 -m json.tool 2>/dev/null || echo "$response_body" + return 0 + else + log_error "Failed to list batches (HTTP $http_code)" + echo "$response_body" + return 1 + fi +} + +# Test invalid file upload +test_invalid_file() { + log_info "Testing invalid file upload (should fail)..." + + # Create invalid file + echo "This is not a ZIP file" > invalid.txt + + response=$(curl -s -w "\n%{http_code}" -X POST "$BASE_URL/client/$CLIENT_ID/document/batch" \ + -F "archive=@invalid.txt" 2>/dev/null) + + http_code=$(echo "$response" | tail -n1) + response_body=$(echo "$response" | head -n -1) + + # Cleanup + rm -f invalid.txt + + if [ "$http_code" = "400" ]; then + log_info "Invalid file correctly rejected (HTTP $http_code)" + return 0 + else + log_warn "Expected HTTP 400 for invalid file, got HTTP $http_code" + echo "$response_body" + return 1 + fi +} + +# Cancel batch +cancel_batch() { + log_info "Canceling batch..." + + response=$(curl -s -w "\n%{http_code}" -X DELETE "$BASE_URL/client/$CLIENT_ID/document/batch/$BATCH_ID" 2>/dev/null) + + http_code=$(echo "$response" | tail -n1) + + if [ "$http_code" = "204" ]; then + log_info "Batch canceled successfully" + return 0 + elif [ "$http_code" = "404" ]; then + log_warn "Batch not found or already completed (HTTP $http_code)" + return 0 + else + log_error "Failed to cancel batch (HTTP $http_code)" + return 1 + fi +} + +# Cleanup function +cleanup() { + log_info "Cleaning up..." + rm -f "$ZIP_FILE" invalid.txt + log_info "Cleanup complete" +} + +# Main test flow +main() { + log_info "Starting ZIP batch upload test..." + log_info "Using client ID: $CLIENT_ID" + + # Setup trap for cleanup + trap cleanup EXIT + + # Run tests + check_service + create_test_zip + create_client + + if upload_batch; then + sleep 1 # Brief pause to let the system process + get_batch_status + list_batches + test_invalid_file + cancel_batch + + # Verify cancellation + sleep 1 + log_info "Verifying batch was canceled..." + get_batch_status + + log_info "✅ All tests completed successfully!" + else + log_error "❌ Batch upload failed, skipping remaining tests" + exit 1 + fi +} + +# Run main function +main "$@" \ No newline at end of file diff --git a/scripts/manual_tests/upload_single_document.sh b/scripts/manual_tests/upload_single_document.sh new file mode 100755 index 00000000..43f15be3 --- /dev/null +++ b/scripts/manual_tests/upload_single_document.sh @@ -0,0 +1,67 @@ +#!/bin/bash + +# Configuration +API_URL="http://localhost:8080" +CLIENT_ID="AAA" # The client ID is AAA +PDF_FILE="./test.pdf" + +# Colors for output +GREEN='\033[0;32m' +RED='\033[0;31m' +NC='\033[0m' # No Color + +echo "Document Upload Script" +echo "=====================" + +# Check if test.pdf exists +if [ ! -f "$PDF_FILE" ]; then + echo -e "${RED}Error: $PDF_FILE not found${NC}" + echo "Please create a test.pdf file first" + exit 1 +fi + +# Check if API is running +echo "Checking if API is running..." +if ! curl -s -f "$API_URL/health" > /dev/null 2>&1; then + echo -e "${RED}Error: API is not running at $API_URL${NC}" + echo "Please start the API with: DISABLE_AUTH=true go run ./cmd/queryAPI" + exit 1 +fi + +echo -e "${GREEN}API is running${NC}" + +# Verify client exists by trying to get its details +echo "Verifying client with ID '$CLIENT_ID' exists..." +CLIENT_CHECK=$(curl -s -o /dev/null -w "%{http_code}" "$API_URL/client/$CLIENT_ID") + +if [ "$CLIENT_CHECK" != "200" ]; then + echo -e "${RED}Error: Client with ID '$CLIENT_ID' not found${NC}" + echo "Please ensure the client exists in the database" + exit 1 +else + echo -e "${GREEN}Client '$CLIENT_ID' verified${NC}" +fi + +# Upload document +echo "Uploading document..." +# Try different approaches based on what the server expects +# Using explicit content type for the file field +UPLOAD_RESPONSE=$(curl -s -w "\n%{http_code}" -X POST "$API_URL/client/$CLIENT_ID/document" \ + -F "file=@$PDF_FILE;type=application/octet-stream" \ + -F "filename=test.pdf") + +HTTP_CODE=$(echo "$UPLOAD_RESPONSE" | tail -n1) +RESPONSE_BODY=$(echo "$UPLOAD_RESPONSE" | sed '$d') + +if [ "$HTTP_CODE" = "200" ]; then + echo -e "${GREEN}Document uploaded successfully!${NC}" + echo "Response: $RESPONSE_BODY" +else + echo -e "${RED}Error: Upload failed with HTTP $HTTP_CODE${NC}" + echo "Response: $RESPONSE_BODY" + exit 1 +fi + +echo "" +echo "You can check the uploaded documents with:" +echo "curl $API_URL/client/$CLIENT_ID/document" \ No newline at end of file