mirror of
https://git.linux-kernel.at/oliver/ivatar.git
synced 2025-11-12 03:06:24 +00:00
Enhance performance tests
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Libravatar Deployment Verification Script
|
||||
|
||||
@@ -18,6 +17,7 @@ Usage:
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import random
|
||||
import ssl
|
||||
import subprocess
|
||||
@@ -54,12 +54,19 @@ class Colors:
|
||||
|
||||
|
||||
def colored_print(message: str, color: str = Colors.NC) -> None:
|
||||
"""Print a colored message."""
|
||||
print(f"{color}{message}{Colors.NC}")
|
||||
"""Print a colored message with immediate flush."""
|
||||
print(f"{color}{message}{Colors.NC}", flush=True)
|
||||
|
||||
|
||||
def get_current_commit_hash() -> Optional[str]:
|
||||
"""Get the current commit hash from git."""
|
||||
"""Get the current commit hash from git or CI environment."""
|
||||
# First try GitLab CI environment variable (most reliable in CI)
|
||||
ci_commit = os.environ.get("CI_COMMIT_SHA")
|
||||
if ci_commit:
|
||||
colored_print(f"Using CI commit hash: {ci_commit}", Colors.BLUE)
|
||||
return ci_commit
|
||||
|
||||
# Fallback to git command
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["git", "rev-parse", "HEAD"],
|
||||
@@ -67,8 +74,11 @@ def get_current_commit_hash() -> Optional[str]:
|
||||
text=True,
|
||||
check=True,
|
||||
)
|
||||
return result.stdout.strip()
|
||||
commit_hash = result.stdout.strip()
|
||||
colored_print(f"Using git commit hash: {commit_hash}", Colors.BLUE)
|
||||
return commit_hash
|
||||
except (subprocess.CalledProcessError, FileNotFoundError):
|
||||
colored_print("Could not determine current commit hash", Colors.RED)
|
||||
return None
|
||||
|
||||
|
||||
@@ -82,16 +92,44 @@ def is_commit_newer_or_equal(commit1: str, commit2: str) -> Optional[bool]:
|
||||
None if comparison fails
|
||||
"""
|
||||
try:
|
||||
# Use git merge-base to check if commit1 is reachable from commit2
|
||||
# If commit1 is newer or equal, it should be reachable from commit2
|
||||
subprocess.run(
|
||||
["git", "merge-base", "--is-ancestor", commit2, commit1],
|
||||
capture_output=True,
|
||||
check=True,
|
||||
)
|
||||
return True
|
||||
# First try to get commit timestamps for comparison
|
||||
try:
|
||||
result1 = subprocess.run(
|
||||
["git", "show", "-s", "--format=%ct", commit1],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
)
|
||||
result2 = subprocess.run(
|
||||
["git", "show", "-s", "--format=%ct", commit2],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
)
|
||||
|
||||
timestamp1 = int(result1.stdout.strip())
|
||||
timestamp2 = int(result2.stdout.strip())
|
||||
|
||||
colored_print(f"Commit {commit1[:8]} timestamp: {timestamp1}", Colors.BLUE)
|
||||
colored_print(f"Commit {commit2[:8]} timestamp: {timestamp2}", Colors.BLUE)
|
||||
|
||||
# commit1 is newer if it has a later timestamp
|
||||
return timestamp1 >= timestamp2
|
||||
|
||||
except (subprocess.CalledProcessError, ValueError):
|
||||
# Fallback to merge-base if timestamp comparison fails
|
||||
colored_print("Timestamp comparison failed, trying merge-base", Colors.YELLOW)
|
||||
|
||||
# Use git merge-base to check if commit2 is ancestor of commit1
|
||||
subprocess.run(
|
||||
["git", "merge-base", "--is-ancestor", commit2, commit1],
|
||||
capture_output=True,
|
||||
check=True,
|
||||
)
|
||||
return True
|
||||
|
||||
except subprocess.CalledProcessError:
|
||||
# If the above fails, try the reverse - check if commit2 is newer
|
||||
# If the above fails, try the reverse
|
||||
try:
|
||||
subprocess.run(
|
||||
["git", "merge-base", "--is-ancestor", commit1, commit2],
|
||||
@@ -100,8 +138,11 @@ def is_commit_newer_or_equal(commit1: str, commit2: str) -> Optional[bool]:
|
||||
)
|
||||
return False
|
||||
except subprocess.CalledProcessError:
|
||||
# If both fail, we can't determine the relationship
|
||||
colored_print("Git comparison failed - shallow clone or missing commits", Colors.YELLOW)
|
||||
return None
|
||||
except Exception as e:
|
||||
colored_print(f"Git comparison error: {e}", Colors.RED)
|
||||
return None
|
||||
|
||||
|
||||
def make_request(
|
||||
@@ -346,17 +387,30 @@ def test_deployment(
|
||||
|
||||
# Check if we're looking for a specific version and compare
|
||||
current_commit = get_current_commit_hash()
|
||||
version_ok = True
|
||||
|
||||
if current_commit and deployed_commit != "Unknown":
|
||||
colored_print(f"Expected commit: {current_commit[:8]}...", Colors.BLUE)
|
||||
colored_print(f"Deployed commit: {deployed_commit[:8]}...", Colors.BLUE)
|
||||
|
||||
if deployed_commit == current_commit:
|
||||
colored_print(
|
||||
"✅ Exact version match - deployment is up to date!",
|
||||
Colors.GREEN,
|
||||
)
|
||||
elif deployed_commit.startswith(current_commit[:8]) or current_commit.startswith(deployed_commit[:8]):
|
||||
# Handle case where we have short vs long commit hashes
|
||||
colored_print(
|
||||
"✅ Version match (short hash) - deployment is up to date!",
|
||||
Colors.GREEN,
|
||||
)
|
||||
else:
|
||||
# Check if deployed version is newer
|
||||
# Check if deployed version is newer using git
|
||||
comparison = is_commit_newer_or_equal(
|
||||
deployed_commit, current_commit
|
||||
)
|
||||
colored_print(f"Commit comparison result: {comparison}", Colors.BLUE)
|
||||
|
||||
if comparison is True:
|
||||
colored_print(
|
||||
"ℹ️ Note: A newer version is already deployed (this is fine!)",
|
||||
@@ -364,43 +418,66 @@ def test_deployment(
|
||||
)
|
||||
elif comparison is False:
|
||||
colored_print(
|
||||
"⚠️ Warning: Deployed version appears to be older than expected",
|
||||
f"⚠️ Deployed version ({deployed_commit[:8]}) is older than expected ({current_commit[:8]})",
|
||||
Colors.YELLOW,
|
||||
)
|
||||
else:
|
||||
colored_print(
|
||||
"⚠️ Warning: Could not determine version relationship",
|
||||
f"Waiting for deployment to update... (attempt {attempt}/{max_retries})",
|
||||
Colors.BLUE,
|
||||
)
|
||||
version_ok = False
|
||||
else:
|
||||
# Git comparison failed - use simple string comparison as fallback
|
||||
colored_print(
|
||||
"⚠️ Git comparison failed - using string comparison fallback",
|
||||
Colors.YELLOW,
|
||||
)
|
||||
|
||||
# Run functionality tests
|
||||
colored_print("Running basic functionality tests...", Colors.YELLOW)
|
||||
|
||||
# Test avatar redirect
|
||||
if test_avatar_redirect(base_url):
|
||||
colored_print("✅ Invalid avatar redirects correctly", Colors.GREEN)
|
||||
|
||||
# If commits are different, assume we need to wait
|
||||
# This is safer than proceeding with wrong version
|
||||
colored_print(
|
||||
f"⚠️ Deployed version ({deployed_commit[:8]}) differs from expected ({current_commit[:8]})",
|
||||
Colors.YELLOW,
|
||||
)
|
||||
colored_print(
|
||||
f"Waiting for deployment to update... (attempt {attempt}/{max_retries})",
|
||||
Colors.BLUE,
|
||||
)
|
||||
version_ok = False
|
||||
|
||||
# Only proceed with functionality tests if version is correct
|
||||
if not version_ok:
|
||||
# Version is not correct, skip tests and retry
|
||||
pass # Will continue to retry logic below
|
||||
else:
|
||||
colored_print("❌ Invalid avatar redirect failed", Colors.RED)
|
||||
return False
|
||||
# Run functionality tests
|
||||
colored_print("Running basic functionality tests...", Colors.YELLOW)
|
||||
|
||||
# Test avatar sizing
|
||||
if test_avatar_sizing(base_url):
|
||||
pass # Success messages are printed within the function
|
||||
else:
|
||||
return False
|
||||
# Test avatar redirect
|
||||
if test_avatar_redirect(base_url):
|
||||
colored_print("✅ Invalid avatar redirects correctly", Colors.GREEN)
|
||||
else:
|
||||
colored_print("❌ Invalid avatar redirect failed", Colors.RED)
|
||||
return False
|
||||
|
||||
# Test stats endpoint
|
||||
if test_stats_endpoint(base_url):
|
||||
colored_print("✅ Stats endpoint working", Colors.GREEN)
|
||||
else:
|
||||
colored_print("❌ Stats endpoint failed", Colors.RED)
|
||||
return False
|
||||
# Test avatar sizing
|
||||
if test_avatar_sizing(base_url):
|
||||
pass # Success messages are printed within the function
|
||||
else:
|
||||
return False
|
||||
|
||||
colored_print(
|
||||
f"🎉 {name} deployment verification completed successfully!",
|
||||
Colors.GREEN,
|
||||
)
|
||||
return True
|
||||
# Test stats endpoint
|
||||
if test_stats_endpoint(base_url):
|
||||
colored_print("✅ Stats endpoint working", Colors.GREEN)
|
||||
else:
|
||||
colored_print("❌ Stats endpoint failed", Colors.RED)
|
||||
return False
|
||||
|
||||
colored_print(
|
||||
f"🎉 {name} deployment verification completed successfully!",
|
||||
Colors.GREEN,
|
||||
)
|
||||
return True
|
||||
else:
|
||||
colored_print(f"{name} site not responding yet...", Colors.YELLOW)
|
||||
|
||||
@@ -408,7 +485,11 @@ def test_deployment(
|
||||
colored_print(
|
||||
f"Waiting {retry_delay} seconds before next attempt...", Colors.BLUE
|
||||
)
|
||||
time.sleep(retry_delay)
|
||||
# Show progress during wait
|
||||
for remaining in range(retry_delay, 0, -1):
|
||||
print(f"\r⏳ Retrying in {remaining:2d} seconds...", end="", flush=True)
|
||||
time.sleep(1)
|
||||
print("\r" + " " * 30 + "\r", end="", flush=True) # Clear the line
|
||||
|
||||
colored_print(
|
||||
f"❌ FAILED: {name} deployment verification timed out after {max_retries} attempts",
|
||||
|
||||
Reference in New Issue
Block a user