#!/usr/bin/env python3 """CLI script to generate SPU performance test reports. This script generates reports from existing test_tasks and test_results data without requiring database migration to the new schema. Usage: # List available SPU configurations python scripts/generate_report.py --list # Generate single SPU report python scripts/generate_report.py --spu "2C8Gx1_2C8Gx3_AWS_us-west-2_v8.5.4" --output report.md # Generate comparison report python scripts/generate_report.py --compare "spu_id_1" "spu_id_2" --output comparison.md # Generate comparison with specific workflow types python scripts/generate_report.py --compare "spu_id_1" "spu_id_2" --workflows bench-tpcc bench-sysbench """ import argparse import sys import traceback from pathlib import Path from typing import List, Optional # Add parent directory to path sys.path.insert(0, str(Path(__file__).parent.parent)) from src.services.report import ( export_comparison_to_markdown, export_to_markdown, generate_comparison_report, generate_spu_report, list_available_spus, ) def list_spus(): """List all available SPU configurations in the database.""" print("\n" + "=" * 80) print("Available SPU Configurations") print("=" * 80 + "\n") spus = list_available_spus() if not spus: print("No SPU configurations found in the database.") return for i, spu in enumerate(spus, 1): print(f"{i}. {spu['spu_identifier']}") print(f" Cloud: {spu['cloud_provider']} / {spu['region']}") print(f" Version: {spu['cluster_version']}") print(f" TiDB: {spu['tidb_spu']} x{spu['tidb_count']}") print(f" TiKV: {spu['tikv_spu']} x{spu['tikv_count']}") print(f" Test Count: {spu['test_count']}") print() def generate_single_report(spu_identifier: str, output_path: Optional[str] = None): """Generate a single SPU performance report.""" print(f"\nGenerating report for SPU: {spu_identifier}") # Generate report data report_data = generate_spu_report(spu_identifier) if not report_data: print(f"Error: No data found for SPU identifier: {spu_identifier}") print("\nUse --list to see available SPU configurations.") sys.exit(1) # Export to markdown markdown_content = export_to_markdown(report_data, output_path) if output_path: print(f"✓ Report saved to: {output_path}") else: print("\n" + "=" * 80) print("Report Preview") print("=" * 80 + "\n") # Print first 50 lines for preview lines = markdown_content.split("\n") preview_lines = lines[:50] print("\n".join(preview_lines)) if len(lines) > 50: print(f"\n... ({len(lines) - 50} more lines)") print("\nUse --output to save the full report to a file.") def generate_compare_report( spu_id_1: str, spu_id_2: str, workflow_types: Optional[List[str]] = None, output_path: Optional[str] = None, ): """Generate a comparison report between two SPUs.""" print(f"\nGenerating comparison report:") print(f" SPU 1: {spu_id_1}") print(f" SPU 2: {spu_id_2}") if workflow_types: print(f" Workflows: {', '.join(workflow_types)}") # Generate comparison report comparison_report = generate_comparison_report(spu_id_1, spu_id_2, workflow_types) if not comparison_report: print("Error: Unable to generate comparison report.") print("Please ensure both SPU identifiers exist and have comparable data.") print("\nUse --list to see available SPU configurations.") sys.exit(1) # Export to markdown markdown_content = export_comparison_to_markdown(comparison_report, output_path) if output_path: print(f"✓ Comparison report saved to: {output_path}") else: print("\n" + "=" * 80) print("Comparison Report Preview") print("=" * 80 + "\n") # Print first 50 lines for preview lines = markdown_content.split("\n") preview_lines = lines[:50] print("\n".join(preview_lines)) if len(lines) > 50: print(f"\n... ({len(lines) - 50} more lines)") print("\nUse --output to save the full report to a file.") def main(): """Main entry point for the CLI.""" parser = argparse.ArgumentParser( description="Generate SPU performance test reports", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" Examples: # List available SPU configurations python scripts/generate_report.py --list # Generate single SPU report python scripts/generate_report.py --spu "2C8Gx1_2C8Gx3_AWS_us-west-2_v8.5.4" --output report.md # Generate comparison report python scripts/generate_report.py --compare "spu_1" "spu_2" --output comparison.md # Generate comparison for specific workflows only python scripts/generate_report.py --compare "spu_1" "spu_2" --workflows bench-tpcc bench-sysbench """, ) # Command options parser.add_argument( "--list", action="store_true", help="List all available SPU configurations in the database", ) parser.add_argument("--spu", type=str, help="SPU identifier for single report") parser.add_argument( "--compare", nargs=2, metavar=("SPU_1", "SPU_2"), help="Compare two SPU configurations", ) parser.add_argument( "--workflows", nargs="+", metavar="WORKFLOW_TYPE", help="Workflow types to compare (for --compare only)", ) parser.add_argument( "--output", "-o", type=str, help="Output file path (markdown format)" ) args = parser.parse_args() # Validate arguments if not any([args.list, args.spu, args.compare]): parser.print_help() sys.exit(1) if args.workflows and not args.compare: print("Error: --workflows can only be used with --compare") sys.exit(1) # Execute commands try: if args.list: list_spus() elif args.spu: generate_single_report(args.spu, args.output) elif args.compare: spu_id_1, spu_id_2 = args.compare generate_compare_report(spu_id_1, spu_id_2, args.workflows, args.output) except Exception as e: print(f"\nError: {str(e)}") traceback.print_exc() sys.exit(1) if __name__ == "__main__": main()