2025-12-21 10:30:01 +00:00
#!/bin/bash
################################################################################
# OBP-API Test Runner Script
#
2025-12-21 10:59:41 +00:00
# What it does:
# 1. Changes terminal to blue background with "Tests Running" in title
# 2. Runs: mvn clean test
# 3. Shows all test output in real-time
# 4. Updates title bar with: phase, time elapsed, pass/fail counts
# 5. Saves detailed log and summary to test-results/
# 6. Restores terminal to normal when done
2025-12-21 10:30:01 +00:00
#
# Usage: ./run_all_tests.sh
################################################################################
set -e
2025-12-21 10:59:41 +00:00
################################################################################
# TERMINAL STYLING FUNCTIONS
################################################################################
# Set terminal to "test mode" - blue background, special title
set_terminal_style( ) {
local phase = " ${ 1 :- Running } "
2025-12-21 11:58:44 +00:00
echo -ne " \033]0;OBP-API Tests ${ phase } ...\007 " # Title
2025-12-21 10:59:41 +00:00
echo -ne "\033]11;#001f3f\007" # Dark blue background
echo -ne "\033]10;#ffffff\007" # White text
# Print header bar
2025-12-21 11:58:44 +00:00
printf " \033[44m\033[1;37m%- $( tput cols) s\r OBP-API TEST RUNNER ACTIVE - ${ phase } \n%- $( tput cols) s\033[0m\n " " " " "
2025-12-21 10:59:41 +00:00
}
2025-12-21 11:58:44 +00:00
# Update title bar with progress: "Testing: DynamicEntityTest [5m 23s] obp-commons:+38 obp-api:+245"
2025-12-21 10:59:41 +00:00
update_terminal_title( ) {
local phase = " $1 " # Starting, Building, Testing, Complete
local elapsed = " ${ 2 :- } " # Time elapsed (e.g. "5m 23s")
2025-12-21 11:58:44 +00:00
local counts = " ${ 3 :- } " # Module counts (e.g. "obp-commons:+38 obp-api:+245")
local suite = " ${ 4 :- } " # Current test suite name
2025-12-21 10:59:41 +00:00
2025-12-21 11:58:44 +00:00
local title = " OBP-API Tests ${ phase } "
[ -n " $suite " ] && title = " ${ title } : ${ suite } "
title = " ${ title } ... "
2025-12-21 10:59:41 +00:00
[ -n " $elapsed " ] && title = " ${ title } [ ${ elapsed } ] "
2025-12-21 11:58:44 +00:00
[ -n " $counts " ] && title = " ${ title } ${ counts } "
2025-12-21 10:59:41 +00:00
echo -ne " \033]0; ${ title } \007 "
}
# Restore terminal to normal (black background, default title)
restore_terminal_style( ) {
echo -ne "\033]0;Terminal\007\033]11;#000000\007\033]10;#ffffff\007\033[0m"
}
2025-12-21 13:08:05 +00:00
# Cleanup function: stop monitor, restore terminal, remove flag files
cleanup_on_exit( ) {
# Stop background monitor if running
if [ -n " ${ MONITOR_PID :- } " ] ; then
kill $MONITOR_PID 2>/dev/null || true
wait $MONITOR_PID 2>/dev/null || true
fi
# Remove monitor flag file
rm -f " ${ LOG_DIR } /monitor.flag " 2>/dev/null || true
# Restore terminal
restore_terminal_style
}
# Always cleanup on exit (Ctrl+C, errors, or normal completion)
trap cleanup_on_exit EXIT INT TERM
2025-12-21 10:59:41 +00:00
################################################################################
# CONFIGURATION
################################################################################
2025-12-21 10:30:01 +00:00
LOG_DIR = "test-results"
2025-12-21 11:58:44 +00:00
DETAIL_LOG = " ${ LOG_DIR } /last_run.log " # Full Maven output
SUMMARY_LOG = " ${ LOG_DIR } /last_run_summary.log " # Summary only
2025-12-21 10:30:01 +00:00
2025-12-21 10:59:41 +00:00
# Terminal colors
2025-12-21 10:30:01 +00:00
GREEN = '\033[0;32m'
RED = '\033[0;31m'
YELLOW = '\033[1;33m'
BLUE = '\033[0;34m'
2025-12-21 10:59:41 +00:00
NC = '\033[0m'
2025-12-21 10:30:01 +00:00
mkdir -p " ${ LOG_DIR } "
2025-12-21 13:08:05 +00:00
# Delete old log files and stale flag files from previous run
echo "Cleaning up old files..."
if [ -f " ${ DETAIL_LOG } " ] ; then
rm -f " ${ DETAIL_LOG } "
echo " - Removed old detail log"
fi
if [ -f " ${ SUMMARY_LOG } " ] ; then
rm -f " ${ SUMMARY_LOG } "
echo " - Removed old summary log"
fi
if [ -f " ${ LOG_DIR } /monitor.flag " ] ; then
rm -f " ${ LOG_DIR } /monitor.flag "
echo " - Removed stale monitor flag"
fi
if [ -f " ${ LOG_DIR } /warning_analysis.tmp " ] ; then
rm -f " ${ LOG_DIR } /warning_analysis.tmp "
echo " - Removed stale warning analysis"
fi
2025-12-21 13:18:54 +00:00
if [ -f " ${ LOG_DIR } /recent_lines.tmp " ] ; then
rm -f " ${ LOG_DIR } /recent_lines.tmp "
echo " - Removed stale temp file"
fi
2025-12-21 11:58:44 +00:00
2025-12-21 10:59:41 +00:00
################################################################################
# HELPER FUNCTIONS
################################################################################
# Log message to terminal and summary file
2025-12-21 10:30:01 +00:00
log_message( ) {
2025-12-21 10:59:41 +00:00
echo -e " $1 "
echo " [ $( date +"%Y-%m-%d %H:%M:%S" ) ] $1 " | sed 's/\x1b\[[0-9;]*m//g' >> " ${ SUMMARY_LOG } "
2025-12-21 10:30:01 +00:00
}
2025-12-21 10:59:41 +00:00
# Print section header
2025-12-21 10:30:01 +00:00
print_header( ) {
echo ""
echo "================================================================================"
2025-12-21 10:59:41 +00:00
echo " $1 "
2025-12-21 10:30:01 +00:00
echo "================================================================================"
echo ""
}
2025-12-21 11:58:44 +00:00
# Analyze warnings and return top contributors
analyze_warnings( ) {
local log_file = " $1 "
local temp_file = " ${ LOG_DIR } /warning_analysis.tmp "
2025-12-21 13:18:54 +00:00
# Extract and categorize warnings from last 5000 lines (for performance)
# This gives good coverage without scanning entire multi-MB log file
tail -n 5000 " ${ log_file } " 2>/dev/null | grep -i "warning" | \
2025-12-21 11:58:44 +00:00
# Normalize patterns to group similar warnings
sed -E 's/line [0-9]+/line XXX/g' | \
sed -E 's/[0-9]+ warnings?/N warnings/g' | \
sed -E 's/\[WARNING\] .*(src|test)\/[^ ]+/[WARNING] <source-file>/g' | \
sed -E 's/version [0-9]+\.[0-9]+(\.[0-9]+)?/version X.X/g' | \
# Extract the core warning message
sed -E 's/^.*\[WARNING\] *//' | \
sort | uniq -c | sort -rn > " ${ temp_file } "
# Return the temp file path for further processing
echo " ${ temp_file } "
}
# Format and display top warning factors
display_warning_factors( ) {
local analysis_file = " $1 "
local max_display = " ${ 2 :- 10 } "
if [ ! -f " ${ analysis_file } " ] || [ ! -s " ${ analysis_file } " ] ; then
log_message " ${ YELLOW } No detailed warning analysis available ${ NC } "
return
fi
local total_warning_types = $( wc -l < " ${ analysis_file } " )
local displayed = 0
log_message " ${ YELLOW } Top Warning Factors: ${ NC } "
log_message "-------------------"
while IFS = read -r line && [ $displayed -lt $max_display ] ; do
# Extract count and message
local count = $( echo " $line " | awk '{print $1}' )
local message = $( echo " $line " | sed -E 's/^[[:space:]]*[0-9]+[[:space:]]*//' )
# Truncate long messages
if [ ${# message } -gt 80 ] ; then
message = " ${ message : 0 : 77 } ... "
fi
# Format with count prominence
printf " ${ YELLOW } %4d × ${ NC } %s\n " " $count " " $message " | tee -a " ${ SUMMARY_LOG } " > /dev/tty
displayed = $(( displayed + 1 ))
done < " ${ analysis_file } "
if [ $total_warning_types -gt $max_display ] ; then
local remaining = $(( total_warning_types - max_display))
log_message " ... and ${ remaining } more warning type(s) "
fi
# Clean up temp file
rm -f " ${ analysis_file } "
}
2025-12-21 10:59:41 +00:00
################################################################################
# START TEST RUN
################################################################################
set_terminal_style "Starting"
2025-12-21 10:30:01 +00:00
# Start the test run
print_header "OBP-API Test Suite"
log_message " ${ BLUE } Starting test run at $( date) ${ NC } "
log_message " Detail log: ${ DETAIL_LOG } "
log_message " Summary log: ${ SUMMARY_LOG } "
echo ""
# Set Maven options for tests
export MAVEN_OPTS = "-Xss128m -Xms3G -Xmx6G -XX:MaxMetaspaceSize=2G"
log_message " ${ BLUE } Maven Options: ${ MAVEN_OPTS } ${ NC } "
echo ""
2025-12-21 10:59:41 +00:00
# Ensure test properties file exists
2025-12-21 10:30:01 +00:00
PROPS_FILE = "obp-api/src/main/resources/props/test.default.props"
2025-12-21 10:59:41 +00:00
PROPS_TEMPLATE = " ${ PROPS_FILE } .template "
2025-12-21 10:30:01 +00:00
if [ -f " ${ PROPS_FILE } " ] ; then
2025-12-21 11:58:44 +00:00
log_message " ${ GREEN } [OK] Found test.default.props ${ NC } "
2025-12-21 10:30:01 +00:00
else
2025-12-21 11:58:44 +00:00
log_message " ${ YELLOW } [WARNING] test.default.props not found - creating from template ${ NC } "
2025-12-21 10:30:01 +00:00
if [ -f " ${ PROPS_TEMPLATE } " ] ; then
cp " ${ PROPS_TEMPLATE } " " ${ PROPS_FILE } "
2025-12-21 11:58:44 +00:00
log_message " ${ GREEN } [OK] Created test.default.props ${ NC } "
2025-12-21 10:30:01 +00:00
else
2025-12-21 10:59:41 +00:00
log_message " ${ RED } ERROR: ${ PROPS_TEMPLATE } not found! ${ NC } "
2025-12-21 10:30:01 +00:00
exit 1
fi
fi
2025-12-21 10:59:41 +00:00
################################################################################
# RUN TESTS
################################################################################
2025-12-21 10:30:01 +00:00
print_header "Running Tests"
2025-12-21 10:59:41 +00:00
update_terminal_title "Building"
2025-12-21 10:30:01 +00:00
log_message " ${ BLUE } Executing: mvn clean test ${ NC } "
echo ""
START_TIME = $( date +%s)
2025-12-21 11:58:44 +00:00
export START_TIME
# Create flag file to signal background process to stop
MONITOR_FLAG = " ${ LOG_DIR } /monitor.flag "
touch " ${ MONITOR_FLAG } "
2025-12-21 10:30:01 +00:00
2025-12-21 10:59:41 +00:00
# Background process: Monitor log file and update title bar with progress
(
2025-12-21 11:58:44 +00:00
# Wait for log file to be created and have Maven output
while [ ! -f " ${ DETAIL_LOG } " ] || [ ! -s " ${ DETAIL_LOG } " ] ; do
sleep 1
done
2025-12-21 10:59:41 +00:00
phase = "Building"
in_testing = false
2025-12-21 11:58:44 +00:00
# Keep monitoring until flag file is removed
while [ -f " ${ MONITOR_FLAG } " ] ; do
2025-12-21 13:08:05 +00:00
# Use tail to look at recent lines only (last 500 lines for performance)
2025-12-21 13:18:54 +00:00
# This ensures O(1) performance regardless of log file size
2025-12-21 13:08:05 +00:00
recent_lines = $( tail -n 500 " ${ DETAIL_LOG } " 2>/dev/null)
2025-12-21 11:58:44 +00:00
# Switch to "Testing" phase when tests start
2025-12-21 13:08:05 +00:00
if ! $in_testing && echo " $recent_lines " | grep -q "Run starting" 2>/dev/null; then
2025-12-21 11:58:44 +00:00
phase = "Testing"
in_testing = true
fi
2025-12-21 10:59:41 +00:00
2025-12-21 13:08:05 +00:00
# Extract current running test suite from recent lines
suite = ""
if $in_testing ; then
# Find the most recent test suite name (pattern like "SomeTest:")
2025-12-21 13:18:54 +00:00
# Pipe directly to avoid temp file I/O
suite = $( echo " $recent_lines " | grep -E "Test:" | tail -1 | sed 's/\x1b\[[0-9;]*m//g' | sed 's/:$//' | tr -d '\n\r' )
2025-12-21 10:59:41 +00:00
fi
# Calculate elapsed time
duration = $(( $( date +%s) - START_TIME))
minutes = $(( duration / 60 ))
seconds = $(( duration % 60 ))
elapsed = $( printf "%dm %ds" $minutes $seconds )
2025-12-21 13:08:05 +00:00
# Update title: "Testing: DynamicEntityTest [5m 23s]"
update_terminal_title " $phase " " $elapsed " "" " $suite "
2025-12-21 10:59:41 +00:00
sleep 5
done
) &
MONITOR_PID = $!
# Run Maven (all output goes to terminal AND log file)
2025-12-21 10:30:01 +00:00
if mvn clean test 2>& 1 | tee " ${ DETAIL_LOG } " ; then
TEST_RESULT = "SUCCESS"
RESULT_COLOR = " ${ GREEN } "
else
TEST_RESULT = "FAILURE"
RESULT_COLOR = " ${ RED } "
fi
2025-12-21 11:58:44 +00:00
# Stop background monitor by removing flag file
rm -f " ${ MONITOR_FLAG } "
sleep 1
2025-12-21 13:08:05 +00:00
kill $MONITOR_PID 2>/dev/null || true
wait $MONITOR_PID 2>/dev/null || true
2025-12-21 10:59:41 +00:00
2025-12-21 10:30:01 +00:00
END_TIME = $( date +%s)
DURATION = $(( END_TIME - START_TIME))
DURATION_MIN = $(( DURATION / 60 ))
DURATION_SEC = $(( DURATION % 60 ))
2025-12-21 11:58:44 +00:00
# Update title with final results (no suite name for Complete phase)
2025-12-21 10:59:41 +00:00
FINAL_ELAPSED = $( printf "%dm %ds" $DURATION_MIN $DURATION_SEC )
2025-12-21 11:58:44 +00:00
# Build final counts with module context
FINAL_COMMONS = $( sed -n '/Building Open Bank Project Commons/,/Building Open Bank Project API/{/Tests: succeeded/p;}' " ${ DETAIL_LOG } " 2>/dev/null | grep -oP "succeeded \K\d+" | head -1)
FINAL_API = $( sed -n '/Building Open Bank Project API/,/OBP Http4s Runner/{/Tests: succeeded/p;}' " ${ DETAIL_LOG } " 2>/dev/null | grep -oP "succeeded \K\d+" | tail -1)
FINAL_COUNTS = ""
[ -n " $FINAL_COMMONS " ] && FINAL_COUNTS = " commons:+ ${ FINAL_COMMONS } "
[ -n " $FINAL_API " ] && FINAL_COUNTS = " ${ FINAL_COUNTS : + ${ FINAL_COUNTS } } api:+ ${ FINAL_API } "
update_terminal_title "Complete" " $FINAL_ELAPSED " " $FINAL_COUNTS " ""
2025-12-21 10:59:41 +00:00
################################################################################
# GENERATE SUMMARY
################################################################################
2025-12-21 10:30:01 +00:00
print_header "Test Results Summary"
2025-12-21 11:58:44 +00:00
# Extract test statistics (with UNKNOWN fallback if extraction fails)
TOTAL_TESTS = $( grep -E "Total number of tests run:|Tests run:" " ${ DETAIL_LOG } " | tail -1 | grep -oP '\d+' | head -1 || echo "UNKNOWN" )
SUCCEEDED = $( grep -oP "succeeded \K\d+" " ${ DETAIL_LOG } " | tail -1 || echo "UNKNOWN" )
FAILED = $( grep -oP "failed \K\d+" " ${ DETAIL_LOG } " | tail -1 || echo "UNKNOWN" )
ERRORS = $( grep -oP "errors \K\d+" " ${ DETAIL_LOG } " | tail -1 || echo "UNKNOWN" )
SKIPPED = $( grep -oP "(skipped|ignored) \K\d+" " ${ DETAIL_LOG } " | tail -1 || echo "UNKNOWN" )
WARNINGS = $( grep -c "WARNING" " ${ DETAIL_LOG } " || echo "UNKNOWN" )
2025-12-21 10:30:01 +00:00
2025-12-21 10:59:41 +00:00
# Determine build status
2025-12-21 10:30:01 +00:00
if grep -q "BUILD SUCCESS" " ${ DETAIL_LOG } " ; then
BUILD_STATUS = "SUCCESS"
BUILD_COLOR = " ${ GREEN } "
elif grep -q "BUILD FAILURE" " ${ DETAIL_LOG } " ; then
BUILD_STATUS = "FAILURE"
BUILD_COLOR = " ${ RED } "
else
BUILD_STATUS = "UNKNOWN"
BUILD_COLOR = " ${ YELLOW } "
fi
2025-12-21 10:59:41 +00:00
# Print summary
2025-12-21 10:30:01 +00:00
log_message "Test Run Summary"
log_message "================"
2025-12-21 10:59:41 +00:00
log_message " Timestamp: $( date) "
log_message " Duration: ${ DURATION_MIN } m ${ DURATION_SEC } s "
log_message " Build Status: ${ BUILD_COLOR } ${ BUILD_STATUS } ${ NC } "
2025-12-21 10:30:01 +00:00
log_message ""
log_message "Test Statistics:"
2025-12-21 10:59:41 +00:00
log_message " Total: ${ TOTAL_TESTS } "
log_message " ${ GREEN } Succeeded: ${ SUCCEEDED } ${ NC } "
log_message " ${ RED } Failed: ${ FAILED } ${ NC } "
log_message " ${ RED } Errors: ${ ERRORS } ${ NC } "
log_message " ${ YELLOW } Skipped: ${ SKIPPED } ${ NC } "
2025-12-21 11:58:44 +00:00
log_message " ${ YELLOW } Warnings: ${ WARNINGS } ${ NC } "
2025-12-21 10:30:01 +00:00
log_message ""
2025-12-21 11:58:44 +00:00
# Analyze and display warning factors if warnings exist
if [ " ${ WARNINGS } " != "0" ] && [ " ${ WARNINGS } " != "UNKNOWN" ] ; then
warning_analysis = $( analyze_warnings " ${ DETAIL_LOG } " )
display_warning_factors " ${ warning_analysis } " 10
log_message ""
fi
2025-12-21 10:59:41 +00:00
# Show failed tests if any
2025-12-21 10:30:01 +00:00
if [ " ${ FAILED } " != "0" ] || [ " ${ ERRORS } " != "0" ] ; then
2025-12-21 10:59:41 +00:00
log_message " ${ RED } Failed Tests: ${ NC } "
2025-12-21 10:30:01 +00:00
grep -A 5 "FAILED\|ERROR" " ${ DETAIL_LOG } " | head -50 >> " ${ SUMMARY_LOG } "
2025-12-21 10:59:41 +00:00
log_message ""
2025-12-21 10:30:01 +00:00
fi
2025-12-21 10:59:41 +00:00
################################################################################
# FINAL RESULT
################################################################################
2025-12-21 10:30:01 +00:00
print_header "Test Run Complete"
if [ " ${ BUILD_STATUS } " = "SUCCESS" ] && [ " ${ FAILED } " = "0" ] && [ " ${ ERRORS } " = "0" ] ; then
2025-12-21 11:58:44 +00:00
log_message " ${ GREEN } [PASS] All tests passed! ${ NC } "
2025-12-21 10:30:01 +00:00
EXIT_CODE = 0
else
2025-12-21 11:58:44 +00:00
log_message " ${ RED } [FAIL] Tests failed ${ NC } "
2025-12-21 10:30:01 +00:00
EXIT_CODE = 1
fi
log_message ""
2025-12-21 11:58:44 +00:00
log_message "Logs saved to:"
log_message " ${ DETAIL_LOG } "
log_message " ${ SUMMARY_LOG } "
2025-12-21 10:30:01 +00:00
echo ""
exit ${ EXIT_CODE }