307 lines
9.9 KiB
Python
Executable File
307 lines
9.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Webhook feature test script
|
|
Used to verify all features of Gitea Webhook Ambassador
|
|
"""
|
|
|
|
import asyncio
|
|
import json
|
|
import httpx
|
|
import time
|
|
from datetime import datetime
|
|
|
|
# Test configuration
|
|
BASE_URL = "http://localhost:8000"
|
|
WEBHOOK_SECRET = "your-secret-key-here-make-it-long-and-random"
|
|
|
|
# Test data
|
|
TEST_WEBHOOK_DATA = {
|
|
"ref": "refs/heads/dev",
|
|
"before": "abc1234567890abcdef1234567890abcdef123456",
|
|
"after": "def1234567890abcdef1234567890abcdef123456",
|
|
"compare_url": "https://gitea.freeleaps.com/freeleaps/test-project/compare/abc123...def123",
|
|
"commits": [
|
|
{
|
|
"id": "def1234567890abcdef1234567890abcdef123456",
|
|
"message": "feat: add new feature",
|
|
"url": "https://gitea.freeleaps.com/freeleaps/test-project/commit/def1234567890abcdef1234567890abcdef123456",
|
|
"author": {
|
|
"id": 1,
|
|
"login": "developer",
|
|
"full_name": "Test Developer",
|
|
"email": "dev@freeleaps.com"
|
|
}
|
|
}
|
|
],
|
|
"repository": {
|
|
"id": 1,
|
|
"name": "test-project",
|
|
"owner": {
|
|
"id": 1,
|
|
"login": "freeleaps",
|
|
"full_name": "Freeleaps Team",
|
|
"email": "team@freeleaps.com"
|
|
},
|
|
"full_name": "freeleaps/test-project",
|
|
"private": False,
|
|
"clone_url": "https://gitea.freeleaps.com/freeleaps/test-project.git",
|
|
"ssh_url": "git@gitea.freeleaps.com:freeleaps/test-project.git",
|
|
"html_url": "https://gitea.freeleaps.com/freeleaps/test-project",
|
|
"default_branch": "main"
|
|
},
|
|
"pusher": {
|
|
"id": 1,
|
|
"login": "developer",
|
|
"full_name": "Test Developer",
|
|
"email": "dev@freeleaps.com"
|
|
}
|
|
}
|
|
|
|
|
|
async def test_health_check():
|
|
"""Test health check"""
|
|
print("🔍 Testing health check...")
|
|
|
|
async with httpx.AsyncClient() as client:
|
|
try:
|
|
response = await client.get(f"{BASE_URL}/health")
|
|
if response.status_code == 200:
|
|
data = response.json()
|
|
print(f"✅ Health check passed: {data['status']}")
|
|
return True
|
|
else:
|
|
print(f"❌ Health check failed: {response.status_code}")
|
|
return False
|
|
except Exception as e:
|
|
print(f"❌ Health check exception: {e}")
|
|
return False
|
|
|
|
|
|
async def test_queue_status():
|
|
"""Test queue status"""
|
|
print("🔍 Testing queue status...")
|
|
|
|
async with httpx.AsyncClient() as client:
|
|
try:
|
|
response = await client.get(f"{BASE_URL}/health/queue")
|
|
if response.status_code == 200:
|
|
data = response.json()
|
|
print(f"✅ Queue status: {data['queue_stats']}")
|
|
return True
|
|
else:
|
|
print(f"❌ Queue status check failed: {response.status_code}")
|
|
return False
|
|
except Exception as e:
|
|
print(f"❌ Queue status exception: {e}")
|
|
return False
|
|
|
|
|
|
async def test_webhook_endpoint():
|
|
"""Test webhook endpoint"""
|
|
print("🔍 Testing webhook endpoint...")
|
|
|
|
headers = {
|
|
"Content-Type": "application/json",
|
|
"X-Gitea-Signature": WEBHOOK_SECRET
|
|
}
|
|
|
|
async with httpx.AsyncClient() as client:
|
|
try:
|
|
response = await client.post(
|
|
f"{BASE_URL}/webhook/gitea",
|
|
headers=headers,
|
|
json=TEST_WEBHOOK_DATA
|
|
)
|
|
|
|
print(f"📊 Response status: {response.status_code}")
|
|
print(f"📊 Response content: {response.text}")
|
|
|
|
if response.status_code in [200, 202]:
|
|
print("✅ Webhook endpoint test passed")
|
|
return True
|
|
else:
|
|
print(f"❌ Webhook endpoint test failed: {response.status_code}")
|
|
return False
|
|
|
|
except Exception as e:
|
|
print(f"❌ Webhook endpoint exception: {e}")
|
|
return False
|
|
|
|
|
|
async def test_metrics_endpoint():
|
|
"""Test metrics endpoint"""
|
|
print("🔍 Testing metrics endpoint...")
|
|
|
|
async with httpx.AsyncClient() as client:
|
|
try:
|
|
response = await client.get(f"{BASE_URL}/metrics")
|
|
if response.status_code == 200:
|
|
print("✅ Metrics endpoint test passed")
|
|
# Print some key metrics
|
|
content = response.text
|
|
for line in content.split('\n'):
|
|
if 'webhook_requests_total' in line or 'queue_size' in line:
|
|
print(f"📊 {line}")
|
|
return True
|
|
else:
|
|
print(f"❌ Metrics endpoint test failed: {response.status_code}")
|
|
return False
|
|
except Exception as e:
|
|
print(f"❌ Metrics endpoint exception: {e}")
|
|
return False
|
|
|
|
|
|
async def test_deduplication():
|
|
"""Test deduplication feature"""
|
|
print("🔍 Testing deduplication feature...")
|
|
|
|
headers = {
|
|
"Content-Type": "application/json",
|
|
"X-Gitea-Signature": WEBHOOK_SECRET
|
|
}
|
|
|
|
async with httpx.AsyncClient() as client:
|
|
try:
|
|
# First request
|
|
print("📤 Sending first request...")
|
|
response1 = await client.post(
|
|
f"{BASE_URL}/webhook/gitea",
|
|
headers=headers,
|
|
json=TEST_WEBHOOK_DATA
|
|
)
|
|
print(f"📊 First response: {response1.status_code}")
|
|
|
|
# Wait one second
|
|
await asyncio.sleep(1)
|
|
|
|
# Second request (same data, should be deduplicated)
|
|
print("📤 Sending second request (same data)...")
|
|
response2 = await client.post(
|
|
f"{BASE_URL}/webhook/gitea",
|
|
headers=headers,
|
|
json=TEST_WEBHOOK_DATA
|
|
)
|
|
print(f"📊 Second response: {response2.status_code}")
|
|
|
|
# Modify commit hash, send third request
|
|
modified_data = TEST_WEBHOOK_DATA.copy()
|
|
modified_data["after"] = "ghi1234567890abcdef1234567890abcdef123456"
|
|
|
|
print("📤 Sending third request (different commit hash)...")
|
|
response3 = await client.post(
|
|
f"{BASE_URL}/webhook/gitea",
|
|
headers=headers,
|
|
json=modified_data
|
|
)
|
|
print(f"📊 Third response: {response3.status_code}")
|
|
|
|
print("✅ Deduplication feature test completed")
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"❌ Deduplication feature exception: {e}")
|
|
return False
|
|
|
|
|
|
async def test_invalid_webhook():
|
|
"""Test invalid webhook requests"""
|
|
print("🔍 Testing invalid webhook requests...")
|
|
|
|
async with httpx.AsyncClient() as client:
|
|
try:
|
|
# Test missing signature
|
|
print("📤 Testing missing signature...")
|
|
response1 = await client.post(
|
|
f"{BASE_URL}/webhook/gitea",
|
|
headers={"Content-Type": "application/json"},
|
|
json=TEST_WEBHOOK_DATA
|
|
)
|
|
print(f"📊 Missing signature response: {response1.status_code}")
|
|
|
|
# Test wrong signature
|
|
print("📤 Testing wrong signature...")
|
|
response2 = await client.post(
|
|
f"{BASE_URL}/webhook/gitea",
|
|
headers={
|
|
"Content-Type": "application/json",
|
|
"X-Gitea-Signature": "wrong-secret"
|
|
},
|
|
json=TEST_WEBHOOK_DATA
|
|
)
|
|
print(f"📊 Wrong signature response: {response2.status_code}")
|
|
|
|
# Test invalid JSON
|
|
print("📤 Testing invalid JSON...")
|
|
response3 = await client.post(
|
|
f"{BASE_URL}/webhook/gitea",
|
|
headers={
|
|
"Content-Type": "application/json",
|
|
"X-Gitea-Signature": WEBHOOK_SECRET
|
|
},
|
|
content="invalid json"
|
|
)
|
|
print(f"📊 Invalid JSON response: {response3.status_code}")
|
|
|
|
print("✅ Invalid request tests completed")
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"❌ Invalid request tests exception: {e}")
|
|
return False
|
|
|
|
|
|
async def main():
|
|
"""Main test function"""
|
|
print("🚀 Starting Gitea Webhook Ambassador feature tests")
|
|
print("=" * 50)
|
|
|
|
tests = [
|
|
("Health Check", test_health_check),
|
|
("Queue Status", test_queue_status),
|
|
("Webhook Endpoint", test_webhook_endpoint),
|
|
("Metrics", test_metrics_endpoint),
|
|
("Deduplication", test_deduplication),
|
|
("Invalid Requests", test_invalid_webhook),
|
|
]
|
|
|
|
results = []
|
|
|
|
for test_name, test_func in tests:
|
|
print(f"\n🧪 {test_name}")
|
|
print("-" * 30)
|
|
|
|
try:
|
|
result = await test_func()
|
|
results.append((test_name, result))
|
|
except Exception as e:
|
|
print(f"❌ {test_name} test exception: {e}")
|
|
results.append((test_name, False))
|
|
|
|
# Wait a bit before next test
|
|
await asyncio.sleep(1)
|
|
|
|
# Output test results
|
|
print("\n" + "=" * 50)
|
|
print("📊 Test Results Summary")
|
|
print("=" * 50)
|
|
|
|
passed = 0
|
|
total = len(results)
|
|
|
|
for test_name, result in results:
|
|
status = "✅ Passed" if result else "❌ Failed"
|
|
print(f"{test_name}: {status}")
|
|
if result:
|
|
passed += 1
|
|
|
|
print(f"\n📈 Overall: {passed}/{total} tests passed")
|
|
|
|
if passed == total:
|
|
print("🎉 All tests passed! Service is running normally.")
|
|
else:
|
|
print("⚠️ Some tests failed, please check service configuration and logs.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
# Run tests
|
|
asyncio.run(main()) |