#!/bin/bash # Performance Analysis Tool for Bash Buddy # Analyzes test logs and benchmark data to generate insights # Color definitions RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[0;33m' BLUE='\033[0;34m' MAGENTA='\033[0;35m' CYAN='\033[0;36m' BOLD='\033[1m' NC='\033[0m' # Get script directory SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PERF_LOG_DIR="$SCRIPT_DIR/performance" TEST_LOG_DIR="$SCRIPT_DIR/logs" REPORT_DIR="$SCRIPT_DIR/reports" mkdir -p "$REPORT_DIR" # ============================================================================ # FUNCTIONS # ============================================================================ print_header() { echo -e "${BOLD}${CYAN}" echo "═══════════════════════════════════════════════════════════" echo " Bash Buddy Performance Analysis" echo " $(date '+%Y-%m-%d %H:%M:%S')" echo "═══════════════════════════════════════════════════════════" echo -e "${NC}" } analyze_benchmarks() { local bench_file="$PERF_LOG_DIR/benchmarks.csv" if [ ! -f "$bench_file" ]; then echo -e "${RED}No benchmark data found${NC}" return 1 fi echo -e "\n${BOLD}${BLUE}Benchmark Analysis${NC}" echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}\n" # Skip header tail -n +2 "$bench_file" | while IFS='|' read -r timestamp name avg_ms min_ms max_ms success iterations; do echo -e "${CYAN}$name${NC}" echo -e " Timestamp: $timestamp" echo -e " Average: ${GREEN}${avg_ms}ms${NC}" echo -e " Range: ${min_ms}ms - ${max_ms}ms" echo -e " Success: $success/$iterations iterations" echo "" done } generate_performance_report() { local bench_file="$PERF_LOG_DIR/benchmarks.csv" local report_file="$REPORT_DIR/performance-report.md" echo "# Bash Buddy Performance Report" > "$report_file" echo "" >> "$report_file" echo "**Generated:** $(date '+%Y-%m-%d %H:%M:%S')" >> "$report_file" echo "" >> "$report_file" if [ ! -f "$bench_file" ]; then echo "No benchmark data available" >> "$report_file" return 1 fi echo "## Benchmark Results" >> "$report_file" echo "" >> "$report_file" echo "| Benchmark | Avg (ms) | Min (ms) | Max (ms) | Success Rate |" >> "$report_file" echo "|-----------|----------|----------|----------|--------------|" >> "$report_file" # Skip header and process data tail -n +2 "$bench_file" | while IFS='|' read -r timestamp name avg_ms min_ms max_ms success iterations; do local success_rate=$(echo "scale=1; $success * 100 / $iterations" | bc) echo "| $name | $avg_ms | $min_ms | $max_ms | ${success_rate}% |" >> "$report_file" done echo "" >> "$report_file" echo "## Performance Targets" >> "$report_file" echo "" >> "$report_file" echo "| Mode | Target | Status |" >> "$report_file" echo "|------|--------|--------|" >> "$report_file" # Analyze against targets tail -n +2 "$bench_file" | while IFS='|' read -r timestamp name avg_ms min_ms max_ms success iterations; do local status="✅" local target="<100ms" if [[ "$name" == *"AI"* ]]; then target="<15000ms" if [ "$avg_ms" -gt 15000 ]; then status="❌" fi elif [ "$avg_ms" -gt 100 ]; then status="⚠️" fi echo "| $name | $target | $status ($avg_ms ms) |" >> "$report_file" done echo "" >> "$report_file" # Summary statistics echo "## Summary Statistics" >> "$report_file" echo "" >> "$report_file" local total_benchmarks=$(tail -n +2 "$bench_file" | wc -l) local fast_count=$(tail -n +2 "$bench_file" | awk -F'|' '$3 < 100 {count++} END {print count}') local slow_count=$(tail -n +2 "$bench_file" | awk -F'|' '$3 >= 100 && $3 < 1000 {count++} END {print count}') echo "- **Total Benchmarks:** $total_benchmarks" >> "$report_file" echo "- **Fast (<100ms):** $fast_count" >> "$report_file" echo "- **Moderate (100-1000ms):** $slow_count" >> "$report_file" echo -e "\n${GREEN}Performance report generated: $report_file${NC}" } analyze_test_results() { local json_report="$TEST_LOG_DIR/test-report.json" if [ ! -f "$json_report" ]; then echo -e "${YELLOW}No test report found${NC}" return 1 fi echo -e "\n${BOLD}${BLUE}Test Results Analysis${NC}" echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}\n" # Parse JSON report (using jq if available) if command -v jq &> /dev/null; then local total=$(jq -r '.summary.total' "$json_report") local passed=$(jq -r '.summary.passed' "$json_report") local failed=$(jq -r '.summary.failed' "$json_report") local skipped=$(jq -r '.summary.skipped' "$json_report") echo -e "${BOLD}Summary:${NC}" echo -e " Total: $total" echo -e " ${GREEN}Passed: $passed${NC}" echo -e " ${RED}Failed: $failed${NC}" echo -e " ${YELLOW}Skipped: $skipped${NC}" if [ "$total" -gt 0 ]; then local pass_rate=$(echo "scale=1; $passed * 100 / $total" | bc) echo -e "\n${BOLD}Pass Rate: ${pass_rate}%${NC}" fi # Show slowest tests echo -e "\n${YELLOW}Slowest Tests:${NC}" jq -r '.tests[] | select(.result == "PASSED") | "\(.duration_ms)|\(.name)"' "$json_report" | \ sort -rn | head -5 | while IFS='|' read -r time name; do echo -e " ${time}ms - $name" done # Show fastest tests echo -e "\n${GREEN}Fastest Tests:${NC}" jq -r '.tests[] | select(.result == "PASSED") | "\(.duration_ms)|\(.name)"' "$json_report" | \ sort -n | head -5 | while IFS='|' read -r time name; do echo -e " ${time}ms - $name" done # Show failed tests if any local failed_tests=$(jq -r '.tests[] | select(.result == "FAILED") | .name' "$json_report") if [ -n "$failed_tests" ]; then echo -e "\n${RED}Failed Tests:${NC}" echo "$failed_tests" | while read -r name; do echo -e " ✗ $name" done fi else echo -e "${YELLOW}Install jq for detailed JSON analysis${NC}" # Basic analysis without jq grep -E "total|passed|failed|skipped" "$json_report" fi } generate_html_report() { local html_file="$REPORT_DIR/performance-report.html" cat > "$html_file" << 'EOF'
Generated: TIMESTAMP
| Benchmark | Average | Min | Max | Status |
|---|