#!/bin/bash # Test script for validating Java FFM and JNI implementations across different Java versions # Usage: test-java-implementations.sh [java_version] [implementation] [test_mode] set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" # Default values JAVA_VERSION="${1:-24}" IMPLEMENTATION="${2:-auto}" # auto, ffm, jni TEST_MODE="${3:-build}" # build, maven, full # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Logging functions log_info() { echo -e "${BLUE}[INFO]${NC} $1" } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } # Test matrix configuration declare -A JAVA_VERSIONS=( ["11"]="JNI only" ["17"]="JNI only" ["21"]="JNI only" ["24"]="JNI default, FFM optional" ["25"]="JNI default, FFM optional" ) declare -A TEST_PRESETS_FFM=( ["build"]="ci-StdShar-GNUC-FFM" ["maven"]="ci-MinShar-GNUC-Maven-FFM" ) declare -A TEST_PRESETS_JNI=( ["build"]="ci-StdShar-GNUC" ["maven"]="ci-MinShar-GNUC-Maven" ) # Validate Java version support validate_java_version() { local version=$1 local impl=$2 if [[ ! ${JAVA_VERSIONS[$version]+_} ]]; then log_error "Unsupported Java version: $version" log_info "Supported versions: ${!JAVA_VERSIONS[@]}" return 1 fi if [[ $version -lt 25 && "$impl" == "ffm" ]]; then log_error "FFM implementation requires Java 25, got Java $version" return 1 fi log_info "Java $version validation: ${JAVA_VERSIONS[$version]}" return 0 } # Determine implementation based on Java version and user preference determine_implementation() { local version=$1 local requested=$2 case "$requested" in "auto") # JNI is default for HDF5 2.0, regardless of Java version echo "jni" ;; "ffm") if [[ $version -ge 25 ]]; then echo "ffm" else log_error "FFM requires Java 25+, got Java $version" return 1 fi ;; "jni") echo "jni" ;; *) log_error "Invalid implementation: $requested (use auto, ffm, or jni)" return 1 ;; esac } # Create build directory with unique name create_build_dir() { local impl=$1 local mode=$2 BUILD_DIR="${PROJECT_ROOT}/build-test-java${JAVA_VERSION}-${impl}-${mode}" if [[ -d "$BUILD_DIR" ]]; then log_warning "Removing existing build directory: $BUILD_DIR" rm -rf "$BUILD_DIR" fi mkdir -p "$BUILD_DIR" log_info "Created build directory: $BUILD_DIR" } # Test basic build configuration test_build_config() { local impl=$1 local preset_key="build" log_info "Testing $impl build configuration..." if [[ "$impl" == "ffm" ]]; then preset=${TEST_PRESETS_FFM[$preset_key]} else preset=${TEST_PRESETS_JNI[$preset_key]} fi log_info "Using preset: $preset" cd "$PROJECT_ROOT" # Configure with preset if ! cmake --preset "$preset" -B "$BUILD_DIR"; then log_error "CMake configuration failed for $impl implementation" return 1 fi # Verify implementation detection # Note: CMake uses HDF5_ENABLE_JNI (not HDF5_ENABLE_FFM) # JNI enabled (ON or not set) = JNI implementation # JNI disabled (OFF) = FFM implementation if [ "$impl" = "jni" ]; then # For JNI, verify it's not explicitly disabled if grep -q "HDF5_ENABLE_JNI:BOOL=OFF" "$BUILD_DIR/CMakeCache.txt"; then log_error "Implementation detection failed - expected JNI but found HDF5_ENABLE_JNI=OFF" cat "$BUILD_DIR/CMakeCache.txt" | grep "HDF5_ENABLE_JNI" || true return 1 fi log_info "JNI implementation verified (HDF5_ENABLE_JNI not OFF)" elif [ "$impl" = "ffm" ]; then # For FFM, verify JNI is explicitly disabled if ! grep -q "HDF5_ENABLE_JNI:BOOL=OFF" "$BUILD_DIR/CMakeCache.txt"; then log_error "Implementation detection failed - expected HDF5_ENABLE_JNI=OFF for FFM" cat "$BUILD_DIR/CMakeCache.txt" | grep "HDF5_ENABLE_JNI" || true return 1 fi log_info "FFM implementation verified (HDF5_ENABLE_JNI=OFF)" fi log_success "Build configuration test passed for $impl" return 0 } # Test Maven artifact generation test_maven_artifacts() { local impl=$1 local preset_key="maven" log_info "Testing $impl Maven artifact generation..." if [[ "$impl" == "ffm" ]]; then preset=${TEST_PRESETS_FFM[$preset_key]} expected_artifact="hdf5-java-ffm" else preset=${TEST_PRESETS_JNI[$preset_key]} expected_artifact="hdf5-java-jni" fi cd "$PROJECT_ROOT" # Configure with Maven preset if ! cmake --preset "$preset" -B "$BUILD_DIR"; then log_error "Maven configuration failed for $impl implementation" return 1 fi # Build the project if ! cmake --build "$BUILD_DIR" --parallel 4; then log_error "Build failed for $impl implementation" return 1 fi # Verify artifact generation jar_pattern="$BUILD_DIR/java/**/target/${expected_artifact}-*.jar" if ! ls $jar_pattern 1> /dev/null 2>&1; then log_error "Expected JAR artifact not found: $expected_artifact" log_info "Looking for JARs in build directory:" find "$BUILD_DIR" -name "*.jar" -type f || true return 1 fi # Verify JAR manifest jar_file=$(ls $jar_pattern | head -1) log_info "Checking JAR manifest: $jar_file" if ! unzip -q -c "$jar_file" META-INF/MANIFEST.MF | grep -q "HDF5-Java-Implementation: ${impl^^}"; then log_error "JAR manifest missing implementation metadata" unzip -q -c "$jar_file" META-INF/MANIFEST.MF || true return 1 fi log_success "Maven artifact test passed for $impl" return 0 } # Test POM file generation test_pom_generation() { local impl=$1 log_info "Testing POM file generation for $impl..." if [[ "$impl" == "ffm" ]]; then expected_artifact="hdf5-java-ffm" expected_desc="Java Foreign Function" else expected_artifact="hdf5-java-jni" expected_desc="Java Native Interface" fi # Find generated POM file pom_file=$(find "$BUILD_DIR" -name "pom.xml" -path "*/java/*" | head -1) if [[ ! -f "$pom_file" ]]; then log_error "POM file not found for $impl implementation" return 1 fi log_info "Checking POM file: $pom_file" # Verify artifact ID if ! grep -q "$expected_artifact" "$pom_file"; then log_error "POM artifact ID incorrect - expected $expected_artifact" grep "" "$pom_file" || true return 1 fi # Verify description if ! grep -q "$expected_desc" "$pom_file"; then log_error "POM description missing expected text: $expected_desc" grep "" "$pom_file" || true return 1 fi log_success "POM generation test passed for $impl" return 0 } # Run comprehensive test suite run_test_suite() { local impl=$1 local mode=$2 log_info "Running test suite for Java $JAVA_VERSION with $impl implementation (mode: $mode)" case "$mode" in "build") create_build_dir "$impl" "build" test_build_config "$impl" ;; "maven") create_build_dir "$impl" "maven" test_maven_artifacts "$impl" test_pom_generation "$impl" ;; "full") create_build_dir "$impl" "build" test_build_config "$impl" create_build_dir "$impl" "maven" test_maven_artifacts "$impl" test_pom_generation "$impl" ;; *) log_error "Invalid test mode: $mode (use build, maven, or full)" return 1 ;; esac } # Cleanup function cleanup() { if [[ -n "${BUILD_DIR:-}" && -d "$BUILD_DIR" ]]; then log_info "Cleaning up build directory: $BUILD_DIR" rm -rf "$BUILD_DIR" fi } # Main execution main() { log_info "Java Implementation Test Suite" log_info "==============================" log_info "Java Version: $JAVA_VERSION" log_info "Implementation: $IMPLEMENTATION" log_info "Test Mode: $TEST_MODE" log_info "" # Validate inputs if ! validate_java_version "$JAVA_VERSION" "$IMPLEMENTATION"; then exit 1 fi # Determine actual implementation actual_impl=$(determine_implementation "$JAVA_VERSION" "$IMPLEMENTATION") if [[ $? -ne 0 ]]; then exit 1 fi log_info "Selected implementation: $actual_impl" log_info "" # Set trap for cleanup trap cleanup EXIT # Run tests if run_test_suite "$actual_impl" "$TEST_MODE"; then log_success "All tests passed for Java $JAVA_VERSION with $actual_impl implementation!" exit 0 else log_error "Tests failed for Java $JAVA_VERSION with $actual_impl implementation" exit 1 fi } # Help function show_help() { cat << EOF Java Implementation Test Suite Usage: $0 [java_version] [implementation] [test_mode] Arguments: java_version Java version to test (11, 17, 21, 24, 25) [default: 24] (25+ required for FFM) implementation Implementation to test (auto, ffm, jni) [default: auto] test_mode Test mode (build, maven, full) [default: build] Examples: $0 # Test Java 25 with auto implementation (JNI - default) $0 25 ffm build # Test Java 25 with FFM (optional), build only $0 11 jni maven # Test Java 11 with JNI, Maven artifacts $0 25 auto full # Test Java 25 with auto selection (JNI), full suite Test Modes: build - Basic build configuration test maven - Maven artifact generation and validation full - Both build and Maven tests Supported Matrix: EOF for version in "${!JAVA_VERSIONS[@]}"; do echo " Java $version: ${JAVA_VERSIONS[$version]}" done } # Check for help request if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then show_help exit 0 fi # Run main function main