feat(bash): startup-scripts reworked + bash scripts workflow integration (#22401)

This commit is contained in:
Yehonal
2025-07-01 15:35:54 +02:00
committed by GitHub
parent d3130f0d39
commit e1b2689c3a
40 changed files with 4125 additions and 384 deletions

View File

@@ -0,0 +1,335 @@
# AzerothCore Test Framework
This is the centralized test framework for all AzerothCore bash scripts. It provides a unified way to write, run, and manage tests across all modules.
## Structure
```
apps/test-framework/
├── run-tests.sh # Universal test runner (single entry point)
├── README.md # This documentation
├── bats_libs/ # Custom BATS libraries
│ ├── acore-support.bash # Test setup and helpers
│ └── acore-assert.bash # Custom assertions
└── helpers/ # Test utilities
└── test_common.sh # Common test functions and setup
```
## Quick Start
### From any module directory:
```bash
# Run tests for current module
../test-framework/run-tests.sh --dir .
```
### From test-framework directory:
```bash
# Run all tests in all modules
./run-tests.sh --all
# Run tests for specific module
./run-tests.sh startup-scripts
# List available modules
./run-tests.sh --list
# Run tests with debug info
./run-tests.sh --all --debug
```
### From project root:
```bash
# Run all tests
apps/test-framework/run-tests.sh --all
# Run specific module
apps/test-framework/run-tests.sh startup-scripts
# Run with verbose output
apps/test-framework/run-tests.sh startup-scripts --verbose
```
## Usage
### Basic Commands
```bash
# Run all tests
./run-tests.sh --all
# Run tests for specific module
./run-tests.sh startup-scripts
# Run tests matching pattern
./run-tests.sh --filter starter
# Run tests in specific directory
./run-tests.sh --dir apps/docker
# Show available modules
./run-tests.sh --list
# Show test count
./run-tests.sh --count
```
### Output Formats
```bash
# Pretty output (default)
./run-tests.sh --pretty
# TAP output for CI/CD
./run-tests.sh --tap
# Verbose output with debug info
./run-tests.sh --verbose --debug
```
## Writing Tests
### Basic Test Structure
```bash
#!/usr/bin/env bats
# Load the AzerothCore test framework
load '../../test-framework/bats_libs/acore-support'
load '../../test-framework/bats_libs/acore-assert'
setup() {
acore_test_setup # Standard setup
# or
startup_scripts_setup # For startup scripts
# or
compiler_setup # For compiler tests
# or
docker_setup # For docker tests
}
teardown() {
acore_test_teardown
}
@test "my test description" {
run my_command
assert_success
assert_output "expected output"
}
```
### Available Setup Functions
- `acore_test_setup` - Basic setup for all tests
- `startup_scripts_setup` - Setup for startup script tests
- `compiler_setup` - Setup for compiler tests
- `docker_setup` - Setup for docker tests
- `extractor_setup` - Setup for extractor tests
### Custom Assertions
```bash
# Assert binary exists and is executable
assert_binary_exists "$TEST_DIR/bin/authserver"
# Assert server started correctly
assert_acore_server_started "$output" "authserver"
# Assert config was loaded
assert_config_loaded "$output" "authserver.conf"
# Assert build success
assert_build_success "$output"
# Assert timeout occurred (for long-running processes)
assert_timeout "$status"
# Assert log contains content
assert_log_contains "$log_file" "Server started"
```
### Test Environment Variables
When using the framework, these variables are automatically set:
- `$TEST_DIR` - Temporary test directory
- `$AC_TEST_ROOT` - Project root directory
- `$AC_TEST_APPS` - Apps directory
- `$BUILDPATH` - Build directory path
- `$SRCPATH` - Source directory path
- `$BINPATH` - Binary directory path
- `$LOGS_PATH` - Logs directory path
### Helper Functions
```bash
# Create test binary
create_test_binary "authserver" 0 2 "Server started"
# Create test config
create_test_config "authserver.conf" "Database.Info = \"127.0.0.1;3306;root;pass;db\""
# Create AzerothCore specific binaries and configs
create_acore_binaries
create_acore_configs
# Run command with timeout
run_with_timeout 5s my_command
# Wait for condition
wait_for_condition "test -f $TEST_DIR/ready" 10 1
# Debug test failure
debug_on_failure
```
## Module Integration
### Adding Tests to a New Module
1. Create a `test/` directory in your module:
```bash
mkdir apps/my-module/test
```
2. Create test files (ending in `.bats`):
```bash
touch apps/my-module/test/test_my_feature.bats
```
3. Write your tests using the framework (see examples above)
### Running Tests
From your module directory:
```bash
../test-framework/run-tests.sh --dir .
```
From the test framework:
```bash
./run-tests.sh my-module
```
From project root:
```bash
apps/test-framework/run-tests.sh my-module
```
## CI/CD Integration
For continuous integration, use TAP output:
```bash
# In your CI script
cd apps/test-framework
./run-tests.sh --all --tap > test-results.tap
# Or from project root
apps/test-framework/run-tests.sh --all --tap > test-results.tap
```
## Available Commands
All functionality is available through the single `run-tests.sh` script:
### Basic Test Execution
- `./run-tests.sh --all` - Run all tests in all modules
- `./run-tests.sh <module>` - Run tests for specific module
- `./run-tests.sh --dir <path>` - Run tests in specific directory
- `./run-tests.sh --list` - List available modules
- `./run-tests.sh --count` - Show test count
### Output Control
- `./run-tests.sh --verbose` - Verbose output with debug info
- `./run-tests.sh --tap` - TAP output for CI/CD
- `./run-tests.sh --debug` - Debug mode with failure details
- `./run-tests.sh --pretty` - Pretty output (default)
### Test Filtering
- `./run-tests.sh --filter <pattern>` - Run tests matching pattern
- `./run-tests.sh <module> --filter <pattern>` - Filter within module
### Utility Functions
- `./run-tests.sh --help` - Show help message
- Install BATS: Use your system package manager (`apt install bats`, `brew install bats-core`, etc.)
### Direct Script Usage
## Examples
### Running Specific Tests
```bash
# Run only starter-related tests
./run-tests.sh --filter starter
# Run only tests in startup-scripts module
./run-tests.sh startup-scripts
# Run all tests with verbose output
./run-tests.sh --all --verbose
# Run tests in specific directory with debug
./run-tests.sh --dir apps/docker --debug
```
### Development Workflow
```bash
# While developing, run tests frequently from module directory
cd apps/my-module
../test-framework/run-tests.sh --dir .
# Debug failing tests
../test-framework/run-tests.sh --dir . --debug --verbose
# Run specific test pattern
../test-framework/run-tests.sh --dir . --filter my-feature
# From project root - run all tests
apps/test-framework/run-tests.sh --all
# Quick test count check
apps/test-framework/run-tests.sh --count
```
## Benefits
1. **No Boilerplate**: Minimal setup required for new test modules
2. **Consistent Environment**: All tests use the same setup/teardown
3. **Reusable Utilities**: Common functions available across all tests
4. **Centralized Management**: Single place to update test infrastructure
5. **Flexible Execution**: Run tests for one module, multiple modules, or all modules
6. **CI/CD Ready**: TAP output format supported
7. **Easy Debugging**: Built-in debug helpers and verbose output
## Dependencies
- [BATS (Bash Automated Testing System)](https://github.com/bats-core/bats-core)
- Standard Unix utilities (find, grep, timeout, etc.)
Install BATS with your system package manager:
```bash
# Ubuntu/Debian
sudo apt update && sudo apt install bats
# Fedora/RHEL
sudo dnf install bats
# macOS
brew install bats-core
# Arch Linux
sudo pacman -S bats
```
## Contributing
When adding new test utilities:
1. Add common functions to `helpers/test_common.sh`
2. Add BATS-specific helpers to `bats_libs/acore-support.bash`
3. Add custom assertions to `bats_libs/acore-assert.bash`
4. Update this README with new functionality

View File

@@ -0,0 +1,178 @@
#!/usr/bin/env bash
# AzerothCore BATS Assertions Library
# Custom assertions for AzerothCore testing
# Assert that a binary exists and is executable
assert_binary_exists() {
local binary_path="$1"
local message="${2:-Binary should exist and be executable}"
if [[ ! -f "$binary_path" ]]; then
echo "Binary not found: $binary_path"
echo "$message"
return 1
fi
if [[ ! -x "$binary_path" ]]; then
echo "Binary not executable: $binary_path"
echo "$message"
return 1
fi
}
# Assert that output contains specific AzerothCore patterns
assert_acore_server_started() {
local output="$1"
local server_type="$2"
local message="${3:-Server should show startup message}"
if [[ ! "$output" =~ $server_type.*starting ]]; then
echo "Server start message not found for $server_type"
echo "Expected pattern: '$server_type.*starting'"
echo "Actual output: $output"
echo "$message"
return 1
fi
}
# Assert that configuration file was loaded
assert_config_loaded() {
local output="$1"
local config_file="$2"
local message="${3:-Configuration file should be loaded}"
if [[ ! "$output" =~ config.*$config_file ]] && [[ ! "$output" =~ $config_file ]]; then
echo "Configuration file loading not detected: $config_file"
echo "Expected to find: config.*$config_file OR $config_file"
echo "Actual output: $output"
echo "$message"
return 1
fi
}
# Assert that a process exited with expected code
assert_exit_code() {
local actual_code="$1"
local expected_code="$2"
local message="${3:-Process should exit with expected code}"
if [[ "$actual_code" -ne "$expected_code" ]]; then
echo "Expected exit code: $expected_code"
echo "Actual exit code: $actual_code"
echo "$message"
return 1
fi
}
# Assert that output contains specific error pattern
assert_error_message() {
local output="$1"
local error_pattern="$2"
local message="${3:-Output should contain expected error message}"
if [[ ! "$output" =~ $error_pattern ]]; then
echo "Expected error pattern not found: $error_pattern"
echo "Actual output: $output"
echo "$message"
return 1
fi
}
# Assert that a file was created
assert_file_created() {
local file_path="$1"
local message="${2:-File should be created}"
if [[ ! -f "$file_path" ]]; then
echo "File not created: $file_path"
echo "$message"
return 1
fi
}
# Assert that a directory was created
assert_directory_created() {
local dir_path="$1"
local message="${2:-Directory should be created}"
if [[ ! -d "$dir_path" ]]; then
echo "Directory not created: $dir_path"
echo "$message"
return 1
fi
}
# Assert that output contains success message
assert_success_message() {
local output="$1"
local success_pattern="${2:-success|completed|finished|done}"
local message="${3:-Output should contain success message}"
if [[ ! "$output" =~ $success_pattern ]]; then
echo "Success message not found"
echo "Expected pattern: $success_pattern"
echo "Actual output: $output"
echo "$message"
return 1
fi
}
# Assert that build was successful
assert_build_success() {
local output="$1"
local message="${2:-Build should complete successfully}"
local build_success_patterns="Build completed|compilation successful|build.*success|make.*success"
assert_success_message "$output" "$build_success_patterns" "$message"
}
# Assert that server is responsive
assert_server_responsive() {
local output="$1"
local server_type="$2"
local message="${3:-Server should be responsive}"
if [[ ! "$output" =~ $server_type.*initialized ]] && [[ ! "$output" =~ $server_type.*ready ]]; then
echo "Server responsiveness not detected for $server_type"
echo "Expected pattern: '$server_type.*initialized' OR '$server_type.*ready'"
echo "Actual output: $output"
echo "$message"
return 1
fi
}
# Assert that timeout occurred (for long-running processes)
assert_timeout() {
local exit_code="$1"
local message="${2:-Process should timeout as expected}"
if [[ "$exit_code" -ne 124 ]]; then
echo "Expected timeout (exit code 124)"
echo "Actual exit code: $exit_code"
echo "$message"
return 1
fi
}
# Assert that log file contains expected content
assert_log_contains() {
local log_file="$1"
local expected_content="$2"
local message="${3:-Log file should contain expected content}"
if [[ ! -f "$log_file" ]]; then
echo "Log file not found: $log_file"
echo "$message"
return 1
fi
if ! grep -q "$expected_content" "$log_file"; then
echo "Expected content not found in log: $expected_content"
echo "Log file: $log_file"
echo "Log contents:"
cat "$log_file" | head -20
echo "$message"
return 1
fi
}

View File

@@ -0,0 +1,116 @@
#!/usr/bin/env bash
# AzerothCore BATS Support Library
# Additional helper functions for BATS testing
# Load common test utilities
source "$(dirname "${BASH_SOURCE[0]}")/../helpers/test_common.sh"
# Standard setup for all AzerothCore tests
acore_test_setup() {
setup_test_env
create_acore_binaries
create_acore_configs
}
# Standard teardown for all AzerothCore tests
acore_test_teardown() {
cleanup_test_env
}
# Quick setup for startup script tests
startup_scripts_setup() {
acore_test_setup
create_test_script_config "test" "test-server"
# Create additional test binary for startup scripts
create_test_binary "test-server" 0 2 "Test server starting with config:"
# Create the test-server.conf file that tests expect
cat > "$TEST_DIR/test-server.conf" << EOF
# Test server configuration file
# Generated by AzerothCore test framework
Database.Info = "127.0.0.1;3306;acore;acore;acore_world"
LoginDatabaseInfo = "127.0.0.1;3306;acore;acore;acore_auth"
CharacterDatabaseInfo = "127.0.0.1;3306;acore;acore;acore_characters"
EOF
}
# Quick setup for compiler tests
compiler_setup() {
acore_test_setup
# Create mock build tools
create_test_binary "gcc" 0 1
create_test_binary "g++" 0 1
create_test_binary "ninja" 0 2
# Create mock CMake files
mkdir -p "$TEST_DIR/build"
touch "$TEST_DIR/build/CMakeCache.txt"
echo "CMAKE_BUILD_TYPE:STRING=RelWithDebInfo" > "$TEST_DIR/build/CMakeCache.txt"
}
# Quick setup for docker tests
docker_setup() {
acore_test_setup
# Create mock docker commands
create_test_binary "docker" 0 1 "Docker container started"
create_test_binary "docker-compose" 0 2 "Docker Compose services started"
# Create test docker files
cat > "$TEST_DIR/Dockerfile" << 'EOF'
FROM ubuntu:20.04
RUN apt-get update
EOF
cat > "$TEST_DIR/docker-compose.yml" << 'EOF'
version: '3.8'
services:
test-service:
image: ubuntu:20.04
EOF
}
# Quick setup for extractor tests
extractor_setup() {
acore_test_setup
# Create mock client data directories
mkdir -p "$TEST_DIR/client"/{Maps,vmaps,mmaps,dbc}
# Create some test data files
echo "Test map data" > "$TEST_DIR/client/Maps/test.map"
echo "Test DBC data" > "$TEST_DIR/client/dbc/test.dbc"
}
# Helper to run command with timeout and capture output
run_with_timeout() {
local timeout_duration="$1"
shift
run timeout "$timeout_duration" "$@"
}
# Helper to check if a process is running
process_running() {
local process_name="$1"
pgrep -f "$process_name" >/dev/null 2>&1
}
# Helper to wait for a condition
wait_for_condition() {
local condition="$1"
local timeout="${2:-10}"
local interval="${3:-1}"
local count=0
while ! eval "$condition"; do
sleep "$interval"
count=$((count + interval))
if [[ $count -ge $timeout ]]; then
return 1
fi
done
return 0
}

View File

@@ -0,0 +1,143 @@
#!/usr/bin/env bash
# AzerothCore Test Common Utilities
# Shared functions and setup for all BATS tests
export AC_TEST_FRAMEWORK_VERSION="1.0.0"
# Get paths
AC_TEST_FRAMEWORK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
AC_PROJECT_ROOT="$(cd "$AC_TEST_FRAMEWORK_DIR/../.." && pwd)"
# Common test environment setup
setup_test_env() {
export TEST_DIR="$(mktemp -d)"
export AC_TEST_ROOT="$AC_PROJECT_ROOT"
export AC_TEST_APPS="$AC_TEST_ROOT/apps"
# Create standard test directory structure
mkdir -p "$TEST_DIR"/{bin,etc,logs,data,crashes,build}
# Set up test-specific environment variables
export ORIGINAL_PATH="$PATH"
export PATH="$TEST_DIR/bin:$PATH"
# Common environment variables for AzerothCore
export BUILDPATH="$TEST_DIR/build"
export SRCPATH="$AC_TEST_ROOT"
export BINPATH="$TEST_DIR/bin"
export LOGS_PATH="$TEST_DIR/logs"
}
cleanup_test_env() {
if [[ -n "$TEST_DIR" && -d "$TEST_DIR" ]]; then
rm -rf "$TEST_DIR"
fi
if [[ -n "$ORIGINAL_PATH" ]]; then
export PATH="$ORIGINAL_PATH"
fi
}
# Create standard test binary
create_test_binary() {
local binary_name="$1"
local exit_code="${2:-0}"
local runtime="${3:-2}"
local extra_output="${4:-""}"
cat > "$TEST_DIR/bin/$binary_name" << EOF
#!/usr/bin/env bash
echo "$binary_name starting with config: \$2"
echo "$binary_name running for $runtime seconds..."
if [[ -n "$extra_output" ]]; then
echo "$extra_output"
fi
sleep $runtime
echo "$binary_name exiting with code $exit_code"
exit $exit_code
EOF
chmod +x "$TEST_DIR/bin/$binary_name"
}
# Create test configuration file
create_test_config() {
local config_name="$1"
local content="$2"
cat > "$TEST_DIR/etc/$config_name" << EOF
# Test configuration file: $config_name
# Generated by AzerothCore test framework
$content
EOF
}
# Create AzerothCore specific test binaries
create_acore_binaries() {
create_test_binary "authserver" 0 1 "AuthServer initialized"
create_test_binary "worldserver" 0 2 "WorldServer initialized"
create_test_binary "cmake" 0 1 "CMake configured"
create_test_binary "make" 0 2 "Build completed"
create_test_binary "mapextractor" 0 3 "Map extraction completed"
create_test_binary "vmap4extractor" 0 2 "VMap extraction completed"
create_test_binary "vmap4assembler" 0 1 "VMap assembly completed"
create_test_binary "mmaps_generator" 0 5 "MMap generation completed"
}
# Create AzerothCore specific test configs
create_acore_configs() {
create_test_config "authserver.conf" 'Database.Info = "127.0.0.1;3306;acore;acore;acore_auth"
LoginDatabaseInfo = "127.0.0.1;3306;acore;acore;acore_auth"'
create_test_config "worldserver.conf" 'Database.Info = "127.0.0.1;3306;acore;acore;acore_world"
LoginDatabaseInfo = "127.0.0.1;3306;acore;acore;acore_auth"
CharacterDatabaseInfo = "127.0.0.1;3306;acore;acore;acore_characters"'
create_test_config "config.sh" "export BUILDPATH=\"$TEST_DIR/build\"
export SRCPATH=\"$AC_TEST_ROOT\"
export BINPATH=\"$TEST_DIR/bin\"
export LOGS_PATH=\"$TEST_DIR/logs\""
}
# Create a test script configuration (for startup scripts)
create_test_script_config() {
local script_name="$1"
local binary_name="${2:-authserver}"
cat > "$TEST_DIR/conf-$script_name.sh" << EOF
export BINPATH="$TEST_DIR/bin"
export SERVERBIN="$binary_name"
export CONFIG="$TEST_DIR/etc/$binary_name.conf"
export LOGS_PATH="$TEST_DIR/logs"
export LOG_PREFIX_NAME="$script_name"
export SCREEN_NAME="AC-$script_name"
export GDB_ENABLED=0
export WITH_CONSOLE=1
EOF
}
# Debug helper function
debug_on_failure() {
if [[ "$status" -ne 0 ]]; then
echo "Command failed with status: $status" >&3
echo "Output was:" >&3
echo "$output" >&3
if [[ -n "$TEST_DIR" ]]; then
echo "Test directory contents:" >&3
ls -la "$TEST_DIR" >&3 2>/dev/null || true
fi
fi
}
# Print test environment info
print_test_env() {
echo "Test Environment:" >&3
echo " TEST_DIR: $TEST_DIR" >&3
echo " AC_TEST_ROOT: $AC_TEST_ROOT" >&3
echo " AC_TEST_APPS: $AC_TEST_APPS" >&3
echo " PATH: $PATH" >&3
}
# Check if running in test mode
is_test_mode() {
[[ -n "$BATS_TEST_FILENAME" ]] || [[ -n "$TEST_DIR" ]]
}

290
apps/test-framework/run-tests.sh Executable file
View File

@@ -0,0 +1,290 @@
#!/usr/bin/env bash
# AzerothCore Universal Test Runner
# This script provides a unified way to run BATS tests across all modules
# Get the script directory and project root
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
show_help() {
echo -e "${BLUE}AzerothCore Universal Test Runner${NC}"
echo ""
echo "Usage: $0 [OPTIONS] [TEST_MODULES...]"
echo ""
echo "Options:"
echo " -h, --help Show this help message"
echo " -v, --verbose Enable verbose output"
echo " -t, --tap Use TAP output format (for CI/CD)"
echo " -p, --pretty Use pretty output format (default)"
echo " -f, --filter Run only tests matching pattern"
echo " -c, --count Show test count only"
echo " -d, --debug Enable debug mode (shows output on failure)"
echo " -l, --list List available test modules"
echo " --dir <path> Run tests in specific directory"
echo " --all Run all tests in all modules"
echo ""
echo "Test Modules:"
echo " startup-scripts - Startup script tests"
echo " compiler - Compiler script tests"
echo " docker - Docker-related tests"
echo " installer - Installer script tests"
echo ""
echo "Examples:"
echo " $0 # Run tests in current directory"
echo " $0 --all # Run all tests in all modules"
echo " $0 startup-scripts # Run startup-scripts tests only"
echo " $0 --dir apps/docker # Run tests in specific directory"
echo " $0 --verbose startup-scripts # Run with verbose output"
echo " $0 --filter starter # Run only tests matching 'starter'"
echo " $0 --tap # Output in TAP format for CI"
}
# Parse command line arguments
VERBOSE=false
TAP=false
PRETTY=true
FILTER=""
COUNT_ONLY=false
DEBUG=false
LIST_MODULES=false
RUN_ALL=false
TEST_DIRS=()
TEST_MODULES=()
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
show_help
exit 0
;;
-v|--verbose)
VERBOSE=true
shift
;;
-t|--tap)
TAP=true
PRETTY=false
shift
;;
-p|--pretty)
PRETTY=true
TAP=false
shift
;;
-f|--filter)
FILTER="$2"
shift 2
;;
-c|--count)
COUNT_ONLY=true
shift
;;
-d|--debug)
DEBUG=true
shift
;;
-l|--list)
LIST_MODULES=true
shift
;;
--dir)
TEST_DIRS+=("$2")
shift 2
;;
--all)
RUN_ALL=true
shift
;;
*.bats)
# Individual test files
TEST_FILES+=("$1")
shift
;;
*)
# Assume it's a module name
TEST_MODULES+=("$1")
shift
;;
esac
done
# Check if BATS is installed
if ! command -v bats >/dev/null 2>&1; then
echo -e "${RED}Error: BATS is not installed${NC}"
echo "Please install BATS first:"
echo " sudo apt install bats # On Ubuntu/Debian"
echo " brew install bats-core # On macOS"
echo "Or run: make install-bats"
exit 1
fi
# Function to find test directories
find_test_directories() {
local search_paths=()
if [[ "$RUN_ALL" == true ]]; then
# Find all test directories
mapfile -t search_paths < <(find "$PROJECT_ROOT/apps" -type d -name "test" 2>/dev/null)
elif [[ ${#TEST_DIRS[@]} -gt 0 ]]; then
# Use specified directories
for dir in "${TEST_DIRS[@]}"; do
if [[ -d "$PROJECT_ROOT/$dir/test" ]]; then
search_paths+=("$PROJECT_ROOT/$dir/test")
elif [[ -d "$dir/test" ]]; then
search_paths+=("$dir/test")
elif [[ -d "$dir" ]]; then
search_paths+=("$dir")
else
echo -e "${YELLOW}Warning: Test directory not found: $dir${NC}"
fi
done
elif [[ ${#TEST_MODULES[@]} -gt 0 ]]; then
# Use specified modules
for module in "${TEST_MODULES[@]}"; do
if [[ -d "$PROJECT_ROOT/apps/$module/test" ]]; then
search_paths+=("$PROJECT_ROOT/apps/$module/test")
else
echo -e "${YELLOW}Warning: Module test directory not found: $module${NC}"
fi
done
else
# Default: use current directory or startup-scripts if run from test-framework
if [[ "$(basename "$PWD")" == "test-framework" ]]; then
search_paths=("$PROJECT_ROOT/apps/startup-scripts/test")
elif [[ -d "./test" ]]; then
search_paths=("./test")
else
echo -e "${YELLOW}No test directory found. Use --all or specify a module.${NC}"
exit 0
fi
fi
echo "${search_paths[@]}"
}
# Function to list available modules
list_modules() {
echo -e "${BLUE}Available test modules:${NC}"
find "$PROJECT_ROOT/apps" -type d -name "test" 2>/dev/null | while read -r test_dir; do
module_name=$(basename "$(dirname "$test_dir")")
test_count=$(find "$test_dir" -name "*.bats" | wc -l)
echo -e " ${GREEN}$module_name${NC} ($test_count test files)"
done
}
# Show available modules if requested
if [[ "$LIST_MODULES" == true ]]; then
list_modules
exit 0
fi
# Find test directories
TEST_SEARCH_PATHS=($(find_test_directories))
if [[ ${#TEST_SEARCH_PATHS[@]} -eq 0 ]]; then
echo -e "${YELLOW}No test directories found.${NC}"
echo "Use --list to see available modules."
exit 0
fi
# Collect all test files
TEST_FILES=()
for test_dir in "${TEST_SEARCH_PATHS[@]}"; do
if [[ -d "$test_dir" ]]; then
if [[ -n "$FILTER" ]]; then
# Find test files matching filter
mapfile -t filtered_files < <(find "$test_dir" -name "*.bats" -exec grep -l "$FILTER" {} \; 2>/dev/null)
TEST_FILES+=("${filtered_files[@]}")
else
# Use all test files in directory
mapfile -t dir_files < <(find "$test_dir" -name "*.bats" 2>/dev/null)
TEST_FILES+=("${dir_files[@]}")
fi
fi
done
if [[ ${#TEST_FILES[@]} -eq 0 ]]; then
if [[ -n "$FILTER" ]]; then
echo -e "${YELLOW}No test files found matching filter: $FILTER${NC}"
else
echo -e "${YELLOW}No test files found in specified directories.${NC}"
fi
exit 0
fi
# Show test count only
if [[ "$COUNT_ONLY" == true ]]; then
total_tests=0
for file in "${TEST_FILES[@]}"; do
count=$(grep -c "^@test" "$file" 2>/dev/null || echo 0)
total_tests=$((total_tests + count))
done
echo "Total tests: $total_tests"
echo "Test files: ${#TEST_FILES[@]}"
echo "Test directories: ${#TEST_SEARCH_PATHS[@]}"
exit 0
fi
# Build BATS command
BATS_CMD="bats"
# Set output format
if [[ "$TAP" == true ]]; then
BATS_CMD+=" --formatter tap"
elif [[ "$PRETTY" == true ]]; then
BATS_CMD+=" --formatter pretty"
fi
# Enable verbose output
if [[ "$VERBOSE" == true ]]; then
BATS_CMD+=" --verbose-run"
fi
# Add filter if specified
if [[ -n "$FILTER" ]]; then
BATS_CMD+=" --filter '$FILTER'"
fi
# Add test files
BATS_CMD+=" ${TEST_FILES[*]}"
echo -e "${BLUE}Running AzerothCore Tests${NC}"
echo -e "${YELLOW}Test directories: ${TEST_SEARCH_PATHS[*]}${NC}"
echo -e "${YELLOW}Test files: ${#TEST_FILES[@]}${NC}"
if [[ -n "$FILTER" ]]; then
echo -e "${YELLOW}Filter: $FILTER${NC}"
fi
echo ""
# Run tests
if [[ "$DEBUG" == true ]]; then
echo -e "${YELLOW}Command: $BATS_CMD${NC}"
echo ""
fi
# Execute BATS
if eval "$BATS_CMD"; then
echo ""
echo -e "${GREEN}✅ All tests passed!${NC}"
exit 0
else
exit_code=$?
echo ""
echo -e "${RED}❌ Some tests failed!${NC}"
if [[ "$DEBUG" == true ]]; then
echo -e "${YELLOW}Tip: Check the output above for detailed error information${NC}"
echo -e "${YELLOW}You can also run individual tests for more detailed debugging:${NC}"
echo -e "${YELLOW} $0 --verbose --filter <test_name>${NC}"
fi
exit $exit_code
fi