#!/bin/bash # Test runner script for conmon BATS tests set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" # Default values CONMON_BINARY="${CONMON_BINARY:-$PROJECT_ROOT/bin/conmon}" RUNTIME_BINARY="${RUNTIME_BINARY:-/usr/bin/runc}" BATS_OPTIONS="${BATS_OPTIONS:-}" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color usage() { cat << EOF Usage: $0 [OPTIONS] [TEST_FILES...] Run conmon BATS tests. OPTIONS: -h, --help Show this help message -c, --conmon BINARY Path to conmon binary (default: $CONMON_BINARY) -r, --runtime BINARY Path to runtime binary (default: $RUNTIME_BINARY) -v, --verbose Verbose output -t, --tap Output in TAP format -j, --jobs N Run tests in parallel with N jobs --filter PATTERN Run only tests matching PATTERN EXAMPLES: $0 Run all tests $0 01-basic.bats Run only basic tests $0 --verbose Run all tests with verbose output $0 --filter "version" Run only tests with 'version' in the name ENVIRONMENT VARIABLES: CONMON_BINARY Path to conmon binary RUNTIME_BINARY Path to runtime binary BATS_OPTIONS Additional options to pass to bats EOF } log_info() { echo -e "${GREEN}[INFO]${NC} $*" } log_warn() { echo -e "${YELLOW}[WARN]${NC} $*" } log_error() { echo -e "${RED}[ERROR]${NC} $*" >&2 } check_dependencies() { local missing_deps=() if ! command -v bats >/dev/null 2>&1; then missing_deps+=("bats") fi if [[ ! -x "$CONMON_BINARY" ]]; then missing_deps+=("conmon binary at $CONMON_BINARY") fi if [[ ! -x "$RUNTIME_BINARY" ]]; then missing_deps+=("runtime binary at $RUNTIME_BINARY") fi if [[ ${#missing_deps[@]} -gt 0 ]]; then log_error "Missing dependencies:" printf ' - %s\n' "${missing_deps[@]}" return 1 fi } main() { local verbose=false local tap=false local jobs="" local filter="" local test_files=() # Parse command line arguments while [[ $# -gt 0 ]]; do case $1 in -h|--help) usage exit 0 ;; -c|--conmon) CONMON_BINARY="$2" shift 2 ;; -r|--runtime) RUNTIME_BINARY="$2" shift 2 ;; -v|--verbose) verbose=true shift ;; -t|--tap) tap=true shift ;; -j|--jobs) jobs="$2" shift 2 ;; --filter) filter="$2" shift 2 ;; *.bats) test_files+=("$1") shift ;; *) log_error "Unknown option: $1" usage exit 1 ;; esac done # Set up BATS options local bats_args=() if [[ "$verbose" == true ]]; then bats_args+=("--verbose-run") fi if [[ "$tap" == true ]]; then bats_args+=("--tap") fi if [[ -n "$jobs" ]]; then bats_args+=("--jobs" "$jobs") fi if [[ -n "$filter" ]]; then bats_args+=("--filter" "$filter") fi # Add any additional BATS options from environment if [[ -n "$BATS_OPTIONS" ]]; then read -ra additional_opts <<< "$BATS_OPTIONS" bats_args+=("${additional_opts[@]}") fi # Check dependencies log_info "Checking dependencies..." if ! check_dependencies; then exit 1 fi # Determine test files to run if [[ ${#test_files[@]} -eq 0 ]]; then # Run all .bats files in test directory mapfile -t test_files < <(find "$SCRIPT_DIR" -name "*.bats" | sort) else # Convert relative paths to absolute paths local resolved_files=() for file in "${test_files[@]}"; do if [[ "$file" =~ ^/ ]]; then resolved_files+=("$file") elif [[ "$file" =~ test/ ]]; then # Already prefixed with test/, use from project root resolved_files+=("$PROJECT_ROOT/$file") else # Add test/ prefix resolved_files+=("$SCRIPT_DIR/$file") fi done test_files=("${resolved_files[@]}") fi # Verify test files exist for file in "${test_files[@]}"; do if [[ ! -f "$file" ]]; then log_error "Test file not found: $file" exit 1 fi done # Export environment variables for tests export CONMON_BINARY export RUNTIME_BINARY log_info "Running tests with:" log_info " conmon binary: $CONMON_BINARY" log_info " runtime binary: $RUNTIME_BINARY" log_info " test files: ${test_files[*]}" # Run the tests log_info "Starting test execution..." if bats "${bats_args[@]}" "${test_files[@]}"; then log_info "All tests passed!" exit 0 else log_error "Some tests failed!" exit 1 fi } # Only run main if script is executed directly if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then main "$@" fi