#!/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())