Files
DevServer/test_all_apis.py
Hardik Sankhla 2304c3ed12 Initial commit: Complete DevServer monitoring framework
- FastAPI application with OpenTelemetry instrumentation
- Redis caching and Celery task processing
- Docker Compose setup with monitoring stack
- Grafana dashboards and Prometheus metrics
- Jaeger distributed tracing
- Comprehensive documentation in docs/ folder
- Monitoring configuration and troubleshooting guides
2025-10-13 09:55:17 +05:30

276 lines
8.8 KiB
Python

"""
Complete API Test Suite
Tests all endpoints including Redis operations
"""
import requests
import time
import json
from datetime import datetime
BASE_URL = "http://localhost:8000"
print("=" * 70)
print("DevServer API - Complete Test Suite")
print("=" * 70)
print(f"Base URL: {BASE_URL}")
print(f"Started at: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print("=" * 70)
def test_api_info():
"""Test API information endpoint"""
print("\n1. API Information")
print("-" * 70)
response = requests.get(f"{BASE_URL}/")
data = response.json()
print(f" Service: {data['service']}")
print(f" Version: {data['version']}")
print(f" Endpoints: {len(data['endpoints'])} categories")
print(f" Status: {response.status_code}")
def test_health():
"""Test health check"""
print("\n2. Health Check")
print("-" * 70)
response = requests.get(f"{BASE_URL}/health")
data = response.json()
print(f" Status: {data['status']}")
print(f" Redis: {data['redis']}")
print(f" Status: {response.status_code}")
def test_dice_roll():
"""Test dice rolling"""
print("\n3. Dice Roll (FastAPI + Tracing)")
print("-" * 70)
start = time.time()
response = requests.get(f"{BASE_URL}/api/dice/roll")
elapsed = time.time() - start
data = response.json()
print(f" Total rolls: {data['total']}")
print(f" Service: {data['service']}")
print(f" Duration: {elapsed:.3f}s")
print(f" Status: {response.status_code}")
def test_redis_single():
"""Test single Redis operations"""
print("\n4. Redis Single Operations")
print("-" * 70)
# Set
key = f"test_{int(time.time())}"
value = f"hello_world_{int(time.time())}"
response = requests.post(f"{BASE_URL}/api/cache/set", params={
"key": key,
"value": value,
"ttl": 300
})
print(f" SET {key} = {value}")
print(f" Status: {response.status_code}")
# Get
response = requests.get(f"{BASE_URL}/api/cache/{key}")
data = response.json()
print(f" GET {key}")
print(f" Value: {data['value']}")
print(f" Status: {response.status_code}")
# Delete
response = requests.delete(f"{BASE_URL}/api/cache/{key}")
data = response.json()
print(f" DELETE {key}")
print(f" Deleted: {data['deleted']}")
print(f" Status: {response.status_code}")
def test_redis_batch():
"""Test batch Redis operations"""
print("\n5. Redis Batch Operations")
print("-" * 70)
# Batch Set
items = {
f"batch_key_1_{int(time.time())}": "value1",
f"batch_key_2_{int(time.time())}": "value2",
f"batch_key_3_{int(time.time())}": "value3"
}
response = requests.post(f"{BASE_URL}/api/cache/batch-set", json=items)
data = response.json()
print(f" BATCH SET: {len(items)} items")
print(f" Successful: {data['successful']}/{data['total']}")
print(f" Status: {response.status_code}")
# Batch Get
keys = ",".join(items.keys())
response = requests.get(f"{BASE_URL}/api/cache/batch-get", params={"keys": keys})
data = response.json()
print(f" BATCH GET: {len(items)} keys")
print(f" Found: {data['found']}/{data['requested']}")
print(f" Status: {response.status_code}")
def test_redis_stats():
"""Test Redis statistics"""
print("\n6. Redis Statistics")
print("-" * 70)
response = requests.get(f"{BASE_URL}/api/cache/stats")
data = response.json()
stats = data['stats']
print(f" Memory Used: {stats['used_memory']}")
print(f" Total Keys: {stats['total_keys']}")
print(f" Connected Clients: {stats['connected_clients']}")
print(f" Cache Hits: {stats['hits']}")
print(f" Cache Misses: {stats['misses']}")
print(f" Hit Ratio: {stats['hit_ratio_percent']}%")
print(f" Uptime: {stats['uptime_seconds']}s")
print(f" Status: {response.status_code}")
def test_redis_keys():
"""Test listing cache keys"""
print("\n7. List Cache Keys")
print("-" * 70)
response = requests.get(f"{BASE_URL}/api/cache/keys", params={"pattern": "*"})
data = response.json()
print(f" Pattern: {data['pattern']}")
print(f" Keys Found: {data['count']}")
if data['keys'] and len(data['keys']) <= 5:
print(f" Keys: {data['keys']}")
elif data['keys']:
print(f" Sample Keys: {data['keys'][:5]}...")
print(f" Status: {response.status_code}")
def test_celery_fibonacci():
"""Test Celery Fibonacci task"""
print("\n8. Celery Task (Fibonacci Calculation)")
print("-" * 70)
# Create task
n = 15
start = time.time()
response = requests.post(f"{BASE_URL}/api/tasks/fibonacci", params={"n": n})
data = response.json()
task_id = data['task_id']
print(f" Creating Fibonacci({n}) task...")
print(f" Task ID: {task_id}")
print(f" Status: {response.status_code}")
# Wait for completion
print(f" Waiting for task completion...")
max_attempts = 30
for attempt in range(max_attempts):
response = requests.get(f"{BASE_URL}/api/tasks/{task_id}")
data = response.json()
if data['status'] == 'completed':
elapsed = time.time() - start
result = data['result']
print(f" Task completed in {elapsed:.2f}s")
print(f" Fibonacci({n}) = {result['fibonacci']}")
print(f" Calculation time: {result['calculation_time']}")
print(f" Service: {result['service']}")
break
time.sleep(1)
else:
print(f" Task did not complete within {max_attempts}s")
def test_process_workflow():
"""Test combined cache + Celery workflow"""
print("\n9. Data Processing Workflow (Cache + Celery)")
print("-" * 70)
data_payload = {
"user_id": 12345,
"action": "test_workflow",
"timestamp": time.time(),
"data": "sample processing data"
}
# First request - should process with Celery
print(f" First request (cache miss - will use Celery)...")
start1 = time.time()
elapsed1 = 0.0
response = requests.post(f"{BASE_URL}/api/process", json=data_payload)
data1 = response.json()
print(f" Source: {data1['source']}")
if data1['source'] == 'celery_task':
task_id = data1['task_id']
print(f" Task ID: {task_id}")
# Wait for task
for _ in range(30):
response = requests.get(f"{BASE_URL}/api/tasks/{task_id}")
result = response.json()
if result['status'] == 'completed':
elapsed1 = time.time() - start1
print(f" Task completed in {elapsed1:.2f}s")
break
time.sleep(1)
# Second request - should return from cache
print(f" Second request (cache hit - should be instant)...")
start2 = time.time()
response = requests.post(f"{BASE_URL}/api/process", json=data_payload)
data2 = response.json()
elapsed2 = time.time() - start2
print(f" Source: {data2['source']}")
print(f" Duration: {elapsed2:.3f}s")
if data1['source'] == 'celery_task' and data2['source'] == 'cache' and elapsed1 > 0:
speedup = elapsed1 / elapsed2 if elapsed2 > 0 else 0
print(f" Cache speedup: {speedup:.1f}x faster!")
def run_all_tests():
"""Run complete test suite"""
start_time = time.time()
try:
test_api_info()
time.sleep(0.5)
test_health()
time.sleep(0.5)
test_dice_roll()
time.sleep(0.5)
test_redis_single()
time.sleep(0.5)
test_redis_batch()
time.sleep(0.5)
test_redis_stats()
time.sleep(0.5)
test_redis_keys()
time.sleep(0.5)
test_celery_fibonacci()
time.sleep(0.5)
test_process_workflow()
elapsed = time.time() - start_time
print("\n" + "=" * 70)
print(f"All tests completed successfully in {elapsed:.2f}s!")
print("=" * 70)
print("\nNext Steps:")
print(" 1. Open Jaeger UI: http://localhost:16686")
print(" 2. Select service: 'devserver.api.fastapi' or 'devserver.celery.worker'")
print(" 3. Click 'Find Traces' to see distributed tracing")
print(" 4. Explore traces to see request flow across services")
print(" 5. Check logs in ./logs/ directory")
print("=" * 70)
except requests.exceptions.ConnectionError:
print("\nERROR: Cannot connect to DevServer")
print(" Make sure the server is running:")
print(" docker-compose up -d")
except Exception as e:
print(f"\nERROR: {e}")
import traceback
traceback.print_exc()
if __name__ == "__main__":
run_all_tests()