TEST_DEPLOYMENT.md•13.8 kB
# Deployment Testing Guide
**Tableau MCP Server - Phase 6**
**Version**: 1.0
**Last Updated**: November 18, 2025
---
## Table of Contents
1. [Overview](#overview)
2. [Pre-Deployment Testing](#pre-deployment-testing)
3. [Post-Deployment Testing](#post-deployment-testing)
4. [MCP Tool Testing](#mcp-tool-testing)
5. [Performance Testing](#performance-testing)
6. [Security Testing](#security-testing)
7. [Integration Testing](#integration-testing)
---
## Overview
This guide provides comprehensive testing procedures for the Tableau MCP Server deployment on Google Cloud Run. Follow these tests after each deployment to ensure everything works correctly.
---
## Pre-Deployment Testing
### Local Docker Build Test
Test Docker build locally before deploying:
```bash
# 1. Build image
docker build -t tableau-mcp-test .
# 2. Check image size
docker images tableau-mcp-test
# Expected: < 500MB (multi-stage build optimization)
# 3. Run container locally
docker run -p 8080:8080 --env-file env.staging.example tableau-mcp-test
# 4. Test health endpoint
curl http://localhost:8080/health
# Expected: {"status":"healthy","timestamp":"..."}
# 5. Stop container
docker stop $(docker ps -q --filter ancestor=tableau-mcp-test)
```
### Environment Configuration Test
Verify environment variables:
```bash
# Check all required variables are set
cat env.staging.example | grep -v "^#" | grep "="
# Required variables:
# - NODE_ENV
# - PORT
# - TABLEAU_SERVER_URL
# - TABLEAU_TOKEN_NAME
# - TABLEAU_TOKEN_VALUE
# - MCP_API_KEY
```
### Secrets Verification
Verify secrets exist before deployment:
```bash
# Check staging secrets
gcloud secrets describe tableau-token-staging
gcloud secrets describe mcp-api-key-staging
# Check production secrets (when deploying to production)
gcloud secrets describe tableau-token-production
gcloud secrets describe mcp-api-key-production
```
---
## Post-Deployment Testing
### 1. Service Status Check
```bash
# Get service status
gcloud run services describe tableau-mcp-staging \
--region=australia-southeast1 \
--format='value(status.conditions[0].status)'
# Expected: True
```
### 2. Health Endpoint Test
```bash
SERVICE_URL=$(gcloud run services describe tableau-mcp-staging \
--region=australia-southeast1 \
--format='value(status.url)')
# Test health endpoint
curl -v $SERVICE_URL/health
# Expected response:
# HTTP 200 OK
# {
# "status": "healthy",
# "timestamp": "2025-11-18T12:34:56.789Z"
# }
```
### 3. Readiness Endpoint Test
```bash
# Test readiness (includes Tableau connectivity)
curl -v $SERVICE_URL/ready
# Expected response:
# HTTP 200 OK
# {
# "status": "ready",
# "tableau": "connected",
# "timestamp": "2025-11-18T12:34:56.789Z"
# }
# If Tableau connection fails:
# HTTP 503 Service Unavailable
# {
# "status": "not ready",
# "tableau": "disconnected",
# "error": "Authentication failed"
# }
```
### 4. Liveness Endpoint Test
```bash
# Test liveness
curl -v $SERVICE_URL/alive
# Expected response:
# HTTP 200 OK
# {
# "status": "alive",
# "uptime": 123.45,
# "timestamp": "2025-11-18T12:34:56.789Z"
# }
```
### 5. Authentication Test
```bash
# Test MCP endpoint WITHOUT API key (should fail)
curl -v $SERVICE_URL/sse
# Expected response:
# HTTP 401 Unauthorized
# {
# "error": "Unauthorized",
# "message": "X-API-Key header is required"
# }
# Test MCP endpoint WITH API key (should connect)
API_KEY=$(gcloud secrets versions access latest --secret=mcp-api-key-staging)
curl -v -H "X-API-Key: $API_KEY" $SERVICE_URL/sse
# Expected response:
# HTTP 200 OK
# Content-Type: text/event-stream
# (SSE connection established)
```
---
## MCP Tool Testing
### Automated Tool Discovery
Test that all 9 tools are discoverable:
```bash
# This requires MCP client testing
# For now, verify in logs that tools are registered
gcloud run logs read tableau-mcp-staging \
--region=australia-southeast1 \
--log-filter='jsonPayload.message=~"MCP server started"' \
--limit=1
# Expected: Log entry showing "9 tools registered"
```
### Manual Tool Testing
For comprehensive tool testing, you'll need to:
1. Configure Cursor with MCP (Phase 7)
2. Test each tool individually
#### Quick Tool Test Checklist
Once Cursor is configured:
**Core Tools:**
- [ ] `tableau_list_workbooks` - Lists all workbooks
- [ ] `tableau_list_views` - Lists views in a workbook
- [ ] `tableau_query_view` - Exports view data
- [ ] `tableau_refresh_extract` - Triggers extract refresh
- [ ] `tableau_search_content` - Searches Tableau content
- [ ] `tableau_get_metadata` - Gets workbook/view metadata
**Advanced Tools:**
- [ ] `tableau_get_dashboard_filters` - Gets dashboard filters
- [ ] `tableau_export_dashboard_pdf` - Exports PDF
- [ ] `tableau_export_dashboard_pptx` - Exports PowerPoint
### Test Commands (via Cursor)
Example prompts to test in Cursor:
```
1. "List all Tableau workbooks"
2. "Show me the views in workbook [WORKBOOK_ID]"
3. "Export data from view [VIEW_ID] as CSV"
4. "Search for dashboards containing 'sales'"
5. "Get metadata for workbook [WORKBOOK_ID]"
6. "What filters are on dashboard [VIEW_ID]?"
7. "Export dashboard [VIEW_ID] as PDF"
```
---
## Performance Testing
### Load Testing
Test service performance under load:
```bash
# Install Apache Bench (if not installed)
# brew install httpd (macOS)
# apt-get install apache2-utils (Linux)
# Test 100 requests, 10 concurrent
ab -n 100 -c 10 -H "X-API-Key: YOUR_API_KEY" $SERVICE_URL/health
# Check results:
# - Requests per second
# - Time per request
# - Failed requests (should be 0)
```
### Latency Testing
Test response times:
```bash
# Test health endpoint latency
time curl -s $SERVICE_URL/health
# Expected: < 500ms for warm instances
# Expected: < 2s for cold start (staging only)
# Test MCP endpoint latency
time curl -s -H "X-API-Key: YOUR_API_KEY" $SERVICE_URL/sse
# Expected: < 1s for connection establishment
```
### Cold Start Testing (Staging Only)
Test cold start behavior:
```bash
# 1. Wait for service to scale to zero (15 minutes of no traffic)
sleep 900
# 2. Make first request (cold start)
time curl -s $SERVICE_URL/health
# Expected: 3-10 seconds (first request after scale-to-zero)
# 3. Make second request (warm instance)
time curl -s $SERVICE_URL/health
# Expected: < 500ms
```
---
## Security Testing
### 1. Authentication Bypass Test
```bash
# Test all endpoints without authentication
# Health endpoint (public, should work)
curl -s $SERVICE_URL/health
# Expected: HTTP 200
# MCP endpoint (protected, should fail)
curl -s $SERVICE_URL/sse
# Expected: HTTP 401 Unauthorized
# Test with invalid API key
curl -s -H "X-API-Key: invalid-key" $SERVICE_URL/sse
# Expected: HTTP 401 Unauthorized
# Test with valid API key
curl -s -H "X-API-Key: YOUR_VALID_KEY" $SERVICE_URL/sse
# Expected: HTTP 200, SSE stream
```
### 2. CORS Testing
```bash
# Test CORS headers
curl -s -H "Origin: https://cursor.sh" \
-H "Access-Control-Request-Method: POST" \
-H "Access-Control-Request-Headers: X-API-Key" \
-X OPTIONS \
$SERVICE_URL/sse
# Expected headers:
# Access-Control-Allow-Origin: https://cursor.sh
# Access-Control-Allow-Methods: GET, POST, OPTIONS
# Access-Control-Allow-Headers: X-API-Key, Content-Type
```
### 3. Secrets Leakage Test
```bash
# Verify secrets are not exposed in logs
gcloud run logs read tableau-mcp-staging \
--region=australia-southeast1 \
--log-filter='textPayload=~"TABLEAU_TOKEN_VALUE"' \
--limit=100
# Expected: No results (secrets should never appear in logs)
# Check for API key in logs
gcloud run logs read tableau-mcp-staging \
--region=australia-southeast1 \
--log-filter='textPayload=~"MCP_API_KEY"' \
--limit=100
# Expected: No results
```
### 4. Rate Limiting Test (Future Enhancement)
```bash
# Current implementation doesn't have rate limiting
# This is recommended for future enhancement
# Test rapid requests
for i in {1..100}; do
curl -s -H "X-API-Key: YOUR_API_KEY" $SERVICE_URL/health &
done
wait
# Monitor for throttling or overload
```
---
## Integration Testing
### Tableau API Integration Test
```bash
# This tests the full chain: Cloud Run → Tableau API
# 1. View logs during health check
gcloud run logs tail tableau-mcp-staging --region=australia-southeast1 &
# 2. Trigger readiness check (tests Tableau connection)
curl -v $SERVICE_URL/ready
# 3. Check logs for Tableau authentication
# Expected: "Authenticated with Tableau successfully" or similar
# Not expected: "Tableau authentication failed"
# 4. Stop log tail
fg
# Press Ctrl+C
```
### MCP Protocol Integration Test
Test MCP protocol compliance (requires MCP client):
```bash
# Using mcp-remote (if installed)
npx -y mcp-remote $SERVICE_URL/sse \
--header "X-API-Key: YOUR_API_KEY"
# Expected: Connection established, tools listed
```
---
## Smoke Test Script
Comprehensive automated smoke test:
```bash
#!/bin/bash
# smoke-test.sh
set -e
SERVICE_URL=$(gcloud run services describe tableau-mcp-staging \
--region=australia-southeast1 \
--format='value(status.url)')
API_KEY=$(gcloud secrets versions access latest --secret=mcp-api-key-staging)
echo "Running smoke tests for: $SERVICE_URL"
echo ""
# Test 1: Health endpoint
echo "[1/5] Testing health endpoint..."
STATUS=$(curl -s -o /dev/null -w "%{http_code}" $SERVICE_URL/health)
if [ "$STATUS" -eq 200 ]; then
echo "✓ Health check passed"
else
echo "✗ Health check failed (HTTP $STATUS)"
exit 1
fi
# Test 2: Readiness endpoint
echo "[2/5] Testing readiness endpoint..."
STATUS=$(curl -s -o /dev/null -w "%{http_code}" $SERVICE_URL/ready)
if [ "$STATUS" -eq 200 ]; then
echo "✓ Readiness check passed"
else
echo "✗ Readiness check failed (HTTP $STATUS)"
exit 1
fi
# Test 3: Liveness endpoint
echo "[3/5] Testing liveness endpoint..."
STATUS=$(curl -s -o /dev/null -w "%{http_code}" $SERVICE_URL/alive)
if [ "$STATUS" -eq 200 ]; then
echo "✓ Liveness check passed"
else
echo "✗ Liveness check failed (HTTP $STATUS)"
exit 1
fi
# Test 4: Authentication (without key, should fail)
echo "[4/5] Testing authentication (should fail)..."
STATUS=$(curl -s -o /dev/null -w "%{http_code}" $SERVICE_URL/sse)
if [ "$STATUS" -eq 401 ]; then
echo "✓ Authentication correctly requires API key"
else
echo "✗ Authentication test failed (HTTP $STATUS, expected 401)"
exit 1
fi
# Test 5: Authentication (with key, should succeed)
echo "[5/5] Testing authentication (should succeed)..."
STATUS=$(curl -s -o /dev/null -w "%{http_code}" -H "X-API-Key: $API_KEY" $SERVICE_URL/sse)
if [ "$STATUS" -eq 200 ]; then
echo "✓ Authentication with API key successful"
else
echo "✗ Authentication with API key failed (HTTP $STATUS)"
exit 1
fi
echo ""
echo "✓ All smoke tests passed!"
```
Usage:
```bash
chmod +x smoke-test.sh
./smoke-test.sh
```
---
## Rollback Testing
Test rollback procedures:
```bash
# 1. List current revisions
gcloud run revisions list --service=tableau-mcp-staging --region=australia-southeast1
# 2. Note current revision
CURRENT_REVISION=$(gcloud run services describe tableau-mcp-staging \
--region=australia-southeast1 \
--format='value(status.latestCreatedRevisionName)')
echo "Current revision: $CURRENT_REVISION"
# 3. Deploy a test change (if testing rollback)
# ./deploy-staging.sh
# 4. Test rollback to previous revision
PREVIOUS_REVISION="tableau-mcp-staging-00001" # Replace with actual
gcloud run services update-traffic tableau-mcp-staging \
--region=australia-southeast1 \
--to-revisions=$PREVIOUS_REVISION=100
# 5. Verify rollback worked
curl -v $SERVICE_URL/health
# 6. Roll forward again
gcloud run services update-traffic tableau-mcp-staging \
--region=australia-southeast1 \
--to-latest
```
---
## Checklist Summary
### Pre-Deployment ✅
- [ ] Docker build succeeds locally
- [ ] Environment variables configured
- [ ] Secrets exist in Secret Manager
- [ ] gcloud authentication working
### Post-Deployment ✅
- [ ] Service status is healthy
- [ ] Health endpoint returns 200
- [ ] Readiness endpoint returns 200
- [ ] Liveness endpoint returns 200
- [ ] Authentication requires API key
- [ ] Authentication works with valid API key
- [ ] Logs are visible in Cloud Logging
### Security ✅
- [ ] MCP endpoint requires authentication
- [ ] Invalid API keys rejected
- [ ] Secrets not visible in logs
- [ ] CORS configured correctly
### Integration ✅
- [ ] Tableau authentication successful
- [ ] MCP protocol working
- [ ] All 9 tools registered
### Performance ✅
- [ ] Response times acceptable
- [ ] No memory issues
- [ ] Cold start time acceptable (staging)
- [ ] Load testing passed
---
## Troubleshooting Failed Tests
### Health Check Fails
```bash
# View service logs
gcloud run logs read tableau-mcp-staging --region=australia-southeast1 --limit=50
# Check environment variables
gcloud run services describe tableau-mcp-staging \
--region=australia-southeast1 \
--format=json | jq '.spec.template.spec.containers[0].env'
```
### Authentication Fails
```bash
# Verify API key secret
gcloud secrets versions access latest --secret=mcp-api-key-staging
# Check server logs for auth errors
gcloud run logs read tableau-mcp-staging \
--region=australia-southeast1 \
--log-filter='jsonPayload.message=~"authentication"' \
--limit=20
```
### Tableau Connection Fails
```bash
# Check Tableau credentials
gcloud secrets versions access latest --secret=tableau-token-staging
# Verify Tableau URL is correct
gcloud run services describe tableau-mcp-staging \
--region=australia-southeast1 \
--format='value(spec.template.spec.containers[0].env[?(@.name=="TABLEAU_SERVER_URL")].value)'
```
---
**Testing Guide Version**: 1.0
**Last Updated**: November 18, 2025
Run these tests after every deployment to ensure service reliability!