chore: reinitialize project with vite architecture
This commit is contained in:
195
scripts/run_stress_tests.py
Normal file
195
scripts/run_stress_tests.py
Normal file
@@ -0,0 +1,195 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Stress Test Runner for MES Dashboard
|
||||
|
||||
Runs comprehensive stress tests including:
|
||||
- Backend API load tests
|
||||
- Frontend browser stress tests
|
||||
|
||||
Usage:
|
||||
python scripts/run_stress_tests.py [options]
|
||||
|
||||
Options:
|
||||
--backend-only Run only backend API tests
|
||||
--frontend-only Run only frontend Playwright tests
|
||||
--quick Quick test with minimal load (good for CI)
|
||||
--heavy Heavy load test (10x normal)
|
||||
--url URL Target URL (default: http://127.0.0.1:5000)
|
||||
--report FILE Save report to file
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
def run_backend_tests(url: str, config: dict) -> dict:
|
||||
"""Run backend API stress tests."""
|
||||
env = os.environ.copy()
|
||||
env['STRESS_TEST_URL'] = url
|
||||
env['STRESS_CONCURRENT_USERS'] = str(config.get('concurrent_users', 10))
|
||||
env['STRESS_REQUESTS_PER_USER'] = str(config.get('requests_per_user', 20))
|
||||
env['STRESS_TIMEOUT'] = str(config.get('timeout', 30))
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("Running Backend API Load Tests")
|
||||
print("=" * 60)
|
||||
print(f" URL: {url}")
|
||||
print(f" Concurrent Users: {config.get('concurrent_users', 10)}")
|
||||
print(f" Requests/User: {config.get('requests_per_user', 20)}")
|
||||
print()
|
||||
|
||||
start_time = time.time()
|
||||
result = subprocess.run(
|
||||
['python', '-m', 'pytest', 'tests/stress/test_api_load.py', '-v', '-s', '--tb=short'],
|
||||
env=env,
|
||||
capture_output=False,
|
||||
cwd=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
)
|
||||
duration = time.time() - start_time
|
||||
|
||||
return {
|
||||
'name': 'Backend API Load Tests',
|
||||
'passed': result.returncode == 0,
|
||||
'duration': duration,
|
||||
'returncode': result.returncode
|
||||
}
|
||||
|
||||
|
||||
def run_frontend_tests(url: str, config: dict) -> dict:
|
||||
"""Run frontend Playwright stress tests."""
|
||||
env = os.environ.copy()
|
||||
env['STRESS_TEST_URL'] = url
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("Running Frontend Playwright Stress Tests")
|
||||
print("=" * 60)
|
||||
print(f" URL: {url}")
|
||||
print()
|
||||
|
||||
start_time = time.time()
|
||||
result = subprocess.run(
|
||||
['python', '-m', 'pytest', 'tests/stress/test_frontend_stress.py', '-v', '-s', '--tb=short'],
|
||||
env=env,
|
||||
capture_output=False,
|
||||
cwd=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
)
|
||||
duration = time.time() - start_time
|
||||
|
||||
return {
|
||||
'name': 'Frontend Playwright Stress Tests',
|
||||
'passed': result.returncode == 0,
|
||||
'duration': duration,
|
||||
'returncode': result.returncode
|
||||
}
|
||||
|
||||
|
||||
def generate_report(results: list, url: str, config: dict) -> str:
|
||||
"""Generate a text report of stress test results."""
|
||||
report_lines = [
|
||||
"=" * 60,
|
||||
"MES Dashboard Stress Test Report",
|
||||
"=" * 60,
|
||||
f"Date: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}",
|
||||
f"Target URL: {url}",
|
||||
f"Configuration: {config}",
|
||||
"",
|
||||
"-" * 60,
|
||||
"Test Results:",
|
||||
"-" * 60,
|
||||
]
|
||||
|
||||
total_duration = 0
|
||||
passed_count = 0
|
||||
|
||||
for result in results:
|
||||
status = "PASSED" if result['passed'] else "FAILED"
|
||||
report_lines.append(f" {result['name']}: {status}")
|
||||
report_lines.append(f" Duration: {result['duration']:.2f}s")
|
||||
total_duration += result['duration']
|
||||
if result['passed']:
|
||||
passed_count += 1
|
||||
|
||||
report_lines.extend([
|
||||
"",
|
||||
"-" * 60,
|
||||
"Summary:",
|
||||
"-" * 60,
|
||||
f" Total Tests: {len(results)}",
|
||||
f" Passed: {passed_count}",
|
||||
f" Failed: {len(results) - passed_count}",
|
||||
f" Total Duration: {total_duration:.2f}s",
|
||||
"=" * 60,
|
||||
])
|
||||
|
||||
return "\n".join(report_lines)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Run MES Dashboard stress tests')
|
||||
parser.add_argument('--backend-only', action='store_true', help='Run only backend tests')
|
||||
parser.add_argument('--frontend-only', action='store_true', help='Run only frontend tests')
|
||||
parser.add_argument('--quick', action='store_true', help='Quick test with minimal load')
|
||||
parser.add_argument('--heavy', action='store_true', help='Heavy load test')
|
||||
parser.add_argument('--url', default='http://127.0.0.1:5000', help='Target URL')
|
||||
parser.add_argument('--report', help='Save report to file')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Configure load levels
|
||||
if args.quick:
|
||||
config = {
|
||||
'concurrent_users': 3,
|
||||
'requests_per_user': 5,
|
||||
'timeout': 30
|
||||
}
|
||||
elif args.heavy:
|
||||
config = {
|
||||
'concurrent_users': 50,
|
||||
'requests_per_user': 50,
|
||||
'timeout': 60
|
||||
}
|
||||
else:
|
||||
config = {
|
||||
'concurrent_users': 10,
|
||||
'requests_per_user': 20,
|
||||
'timeout': 30
|
||||
}
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("MES Dashboard Stress Test Suite")
|
||||
print("=" * 60)
|
||||
print(f"Target: {args.url}")
|
||||
print(f"Mode: {'Quick' if args.quick else 'Heavy' if args.heavy else 'Normal'}")
|
||||
print()
|
||||
|
||||
results = []
|
||||
|
||||
# Run tests based on flags
|
||||
if not args.frontend_only:
|
||||
results.append(run_backend_tests(args.url, config))
|
||||
|
||||
if not args.backend_only:
|
||||
results.append(run_frontend_tests(args.url, config))
|
||||
|
||||
# Generate report
|
||||
report = generate_report(results, args.url, config)
|
||||
print("\n" + report)
|
||||
|
||||
# Save report if requested
|
||||
if args.report:
|
||||
with open(args.report, 'w', encoding='utf-8') as f:
|
||||
f.write(report)
|
||||
print(f"\nReport saved to: {args.report}")
|
||||
|
||||
# Exit with appropriate code
|
||||
all_passed = all(r['passed'] for r in results)
|
||||
sys.exit(0 if all_passed else 1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user