mirror of
https://github.com/HDFGroup/hdf5.git
synced 2026-09-25 04:09:44 +03:00
FFM build requires Java 25, Jextract 25. Generates FFM bindings during configure. JNI is default when the requirements are not met or can be forced. Presets added for maven and FFM - JNI is default selection. Enhanced Maven options will work with either JNI or FFM New Workflows for testing and maven uploads. Extensive documentation changes for java.
474 lines
18 KiB
YAML
474 lines
18 KiB
YAML
name: Java Examples Maven Testing
|
|
|
|
on:
|
|
workflow_call:
|
|
inputs:
|
|
build_mode:
|
|
description: "release vs. debug build"
|
|
required: true
|
|
type: string
|
|
maven_artifacts_version:
|
|
description: "HDF5 Maven artifacts version to test against"
|
|
required: true
|
|
type: string
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
# Parallel testing by platform and example category
|
|
test-examples-linux:
|
|
name: "Test Examples Linux (${{ matrix.category }})"
|
|
runs-on: ubuntu-latest
|
|
continue-on-error: true # Non-blocking failures
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
category: [H5D, H5T, H5G, TUTR]
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v5.0.0
|
|
|
|
- name: Download Maven artifacts (Linux)
|
|
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
|
|
with:
|
|
name: maven-staging-artifacts-linux-x86_64
|
|
path: ./maven-artifacts
|
|
continue-on-error: true
|
|
|
|
- name: Set up JDK 21
|
|
uses: actions/setup-java@v5
|
|
with:
|
|
java-version: '21'
|
|
distribution: 'temurin'
|
|
|
|
- name: Cache Maven dependencies
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: ~/.m2/repository
|
|
key: ${{ runner.os }}-maven-examples-${{ hashFiles('**/pom-examples.xml*') }}
|
|
restore-keys: |
|
|
${{ runner.os }}-maven-examples-
|
|
${{ runner.os }}-maven-
|
|
|
|
- name: Identify HDF5 JAR files
|
|
run: |
|
|
echo "=== Identifying HDF5 JAR files ==="
|
|
|
|
# Find HDF5 JAR files (not dependencies)
|
|
HDF5_JARS=$(find ./maven-artifacts -name "*hdf5*.jar" -o -name "jarhdf5*.jar")
|
|
DEP_JARS=$(find ./maven-artifacts -name "*.jar" ! -name "*hdf5*" ! -name "jarhdf5*")
|
|
|
|
echo "HDF5 JARs found:"
|
|
echo "$HDF5_JARS"
|
|
echo ""
|
|
echo "Dependency JARs found:"
|
|
echo "$DEP_JARS"
|
|
|
|
if [ -z "$HDF5_JARS" ]; then
|
|
echo "❌ No HDF5 JAR files found!"
|
|
echo "All available JARs:"
|
|
find ./maven-artifacts -name "*.jar"
|
|
exit 1
|
|
fi
|
|
|
|
- name: Test Examples Category ${{ matrix.category }}
|
|
id: test-examples
|
|
run: |
|
|
cd HDF5Examples/JAVA/${{ matrix.category }}
|
|
|
|
echo "=== Testing ${{ matrix.category }} Examples ==="
|
|
|
|
# Create test results directory
|
|
mkdir -p ../../../test-results/${{ matrix.category }}
|
|
|
|
FAILED_EXAMPLES=""
|
|
TOTAL_EXAMPLES=0
|
|
PASSED_EXAMPLES=0
|
|
|
|
# Test each Java example in the category
|
|
for java_file in *.java; do
|
|
if [ -f "$java_file" ]; then
|
|
TOTAL_EXAMPLES=$((TOTAL_EXAMPLES + 1))
|
|
example_name=$(basename "$java_file" .java)
|
|
echo "--- Testing $example_name ---"
|
|
|
|
# Build classpath (use platform-specific artifacts)
|
|
MAVEN_ARTIFACTS_DIR="../../../maven-artifacts"
|
|
HDF5_JAR=$(find "$MAVEN_ARTIFACTS_DIR" -name "*hdf5*.jar" -o -name "jarhdf5*.jar" | head -1)
|
|
DEP_JARS=$(find "$MAVEN_ARTIFACTS_DIR" -name "slf4j-api*.jar" -o -name "slf4j-simple*.jar")
|
|
|
|
if [ -z "$HDF5_JAR" ]; then
|
|
echo "❌ No HDF5 JAR found"
|
|
find "$MAVEN_ARTIFACTS_DIR" -name "*.jar" | head -10
|
|
continue
|
|
fi
|
|
|
|
CLASSPATH="$HDF5_JAR"
|
|
for dep_jar in $DEP_JARS; do
|
|
CLASSPATH="$CLASSPATH:$dep_jar"
|
|
done
|
|
|
|
# Compile the example
|
|
if javac -cp "$CLASSPATH" "$java_file"; then
|
|
echo "✓ Compilation successful for $example_name"
|
|
|
|
# Run the example and capture output
|
|
if timeout 30s java -cp ".:$CLASSPATH" "$example_name" > "../../../test-results/${{ matrix.category }}/${example_name}.output" 2>&1; then
|
|
# Validate output using pattern matching
|
|
output_file="../../../test-results/${{ matrix.category }}/${example_name}.output"
|
|
|
|
# Check for common success patterns
|
|
if grep -q -i -E "(dataset|datatype|group|success|created|written|read)" "$output_file" && \
|
|
! grep -q -i -E "(error|exception|failed|cannot)" "$output_file"; then
|
|
echo "✓ Execution and validation successful for $example_name"
|
|
PASSED_EXAMPLES=$((PASSED_EXAMPLES + 1))
|
|
else
|
|
echo "✗ Output validation failed for $example_name"
|
|
FAILED_EXAMPLES="$FAILED_EXAMPLES $example_name"
|
|
echo "Output:"
|
|
cat "$output_file"
|
|
fi
|
|
else
|
|
# Check if failure is due to expected native library issue (acceptable for Maven-only testing)
|
|
output_file="../../../test-results/${{ matrix.category }}/${example_name}.output"
|
|
if grep -q "UnsatisfiedLinkError.*hdf5_java.*java.library.path" "$output_file"; then
|
|
echo "✓ Expected native library error for Maven-only testing: $example_name"
|
|
echo " (This confirms JAR structure is correct)"
|
|
PASSED_EXAMPLES=$((PASSED_EXAMPLES + 1))
|
|
else
|
|
echo "✗ Unexpected execution failure for $example_name"
|
|
FAILED_EXAMPLES="$FAILED_EXAMPLES $example_name"
|
|
echo "Output:"
|
|
cat "$output_file"
|
|
fi
|
|
fi
|
|
else
|
|
echo "✗ Compilation failed for $example_name"
|
|
FAILED_EXAMPLES="$FAILED_EXAMPLES $example_name"
|
|
fi
|
|
echo ""
|
|
fi
|
|
done
|
|
|
|
# Summary
|
|
echo "=== ${{ matrix.category }} Summary ==="
|
|
echo "Total examples: $TOTAL_EXAMPLES"
|
|
echo "Passed: $PASSED_EXAMPLES"
|
|
echo "Failed: $((TOTAL_EXAMPLES - PASSED_EXAMPLES))"
|
|
|
|
if [ -n "$FAILED_EXAMPLES" ]; then
|
|
echo "Failed examples:$FAILED_EXAMPLES"
|
|
echo "failed-examples=$FAILED_EXAMPLES" >> $GITHUB_OUTPUT
|
|
echo "test-status=FAILED" >> $GITHUB_OUTPUT
|
|
else
|
|
echo "All examples passed!"
|
|
echo "test-status=PASSED" >> $GITHUB_OUTPUT
|
|
fi
|
|
|
|
echo "total-examples=$TOTAL_EXAMPLES" >> $GITHUB_OUTPUT
|
|
echo "passed-examples=$PASSED_EXAMPLES" >> $GITHUB_OUTPUT
|
|
|
|
- name: Upload failure artifacts (Linux ${{ matrix.category }})
|
|
if: steps.test-examples.outputs.test-status == 'FAILED'
|
|
uses: actions/upload-artifact@v5
|
|
with:
|
|
name: java-examples-failure-linux-${{ matrix.category }}-${{ github.run_id }}
|
|
path: |
|
|
test-results/${{ matrix.category }}/
|
|
HDF5Examples/JAVA/${{ matrix.category }}/*.class
|
|
HDF5Examples/JAVA/${{ matrix.category }}/*.h5
|
|
retention-days: 7
|
|
|
|
test-examples-windows:
|
|
name: "Test Examples Windows (${{ matrix.category }})"
|
|
runs-on: windows-latest
|
|
continue-on-error: true
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
category: [H5D, H5T, H5G, TUTR]
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v5.0.0
|
|
|
|
- name: Download Maven artifacts (Windows)
|
|
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
|
|
with:
|
|
name: maven-staging-artifacts-windows-x86_64
|
|
path: ./maven-artifacts
|
|
continue-on-error: true
|
|
|
|
- name: Set up JDK 21
|
|
uses: actions/setup-java@v5
|
|
with:
|
|
java-version: '21'
|
|
distribution: 'temurin'
|
|
|
|
- name: Cache Maven dependencies
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: ~/.m2/repository
|
|
key: ${{ runner.os }}-maven-examples-${{ hashFiles('**/pom-examples.xml*') }}
|
|
|
|
- name: Test Examples Category ${{ matrix.category }}
|
|
id: test-examples
|
|
shell: pwsh
|
|
run: |
|
|
cd HDF5Examples/JAVA/${{ matrix.category }}
|
|
|
|
Write-Host "=== Testing ${{ matrix.category }} Examples ==="
|
|
|
|
# Create test results directory
|
|
New-Item -ItemType Directory -Force -Path "../../../test-results/${{ matrix.category }}"
|
|
|
|
$FAILED_EXAMPLES = @()
|
|
$TOTAL_EXAMPLES = 0
|
|
$PASSED_EXAMPLES = 0
|
|
|
|
# Test each Java example in the category
|
|
Get-ChildItem -Filter "*.java" | ForEach-Object {
|
|
$TOTAL_EXAMPLES++
|
|
$example_name = $_.BaseName
|
|
Write-Host "--- Testing $example_name ---"
|
|
|
|
# Compile the example
|
|
$compile_result = javac -cp "../../../maven-artifacts/*.jar" $_.Name
|
|
if ($LASTEXITCODE -eq 0) {
|
|
Write-Host "✓ Compilation successful for $example_name"
|
|
|
|
# Run the example and capture output
|
|
$timeout_cmd = "timeout 30s java -cp '.;../../../maven-artifacts/*' $example_name"
|
|
$output_file = "../../../test-results/${{ matrix.category }}/${example_name}.output"
|
|
|
|
try {
|
|
& cmd /c "$timeout_cmd > `"$output_file`" 2>&1"
|
|
if ($LASTEXITCODE -eq 0) {
|
|
# Validate output using pattern matching
|
|
$content = Get-Content $output_file -Raw
|
|
if (($content -match "(?i)(dataset|datatype|group|success|created|written|read)") -and
|
|
($content -notmatch "(?i)(error|exception|failed|cannot)")) {
|
|
Write-Host "✓ Execution and validation successful for $example_name"
|
|
$PASSED_EXAMPLES++
|
|
} else {
|
|
Write-Host "✗ Output validation failed for $example_name"
|
|
$FAILED_EXAMPLES += $example_name
|
|
Write-Host "Output:"
|
|
Get-Content $output_file
|
|
}
|
|
} else {
|
|
Write-Host "✗ Execution failed for $example_name"
|
|
$FAILED_EXAMPLES += $example_name
|
|
}
|
|
} catch {
|
|
Write-Host "✗ Execution failed for $example_name"
|
|
$FAILED_EXAMPLES += $example_name
|
|
}
|
|
} else {
|
|
Write-Host "✗ Compilation failed for $example_name"
|
|
$FAILED_EXAMPLES += $example_name
|
|
}
|
|
Write-Host ""
|
|
}
|
|
|
|
# Summary
|
|
Write-Host "=== ${{ matrix.category }} Summary ==="
|
|
Write-Host "Total examples: $TOTAL_EXAMPLES"
|
|
Write-Host "Passed: $PASSED_EXAMPLES"
|
|
Write-Host "Failed: $($TOTAL_EXAMPLES - $PASSED_EXAMPLES)"
|
|
|
|
if ($FAILED_EXAMPLES.Count -gt 0) {
|
|
Write-Host "Failed examples: $($FAILED_EXAMPLES -join ' ')"
|
|
echo "failed-examples=$($FAILED_EXAMPLES -join ' ')" >> $env:GITHUB_OUTPUT
|
|
echo "test-status=FAILED" >> $env:GITHUB_OUTPUT
|
|
} else {
|
|
Write-Host "All examples passed!"
|
|
echo "test-status=PASSED" >> $env:GITHUB_OUTPUT
|
|
}
|
|
|
|
echo "total-examples=$TOTAL_EXAMPLES" >> $env:GITHUB_OUTPUT
|
|
echo "passed-examples=$PASSED_EXAMPLES" >> $env:GITHUB_OUTPUT
|
|
|
|
- name: Upload failure artifacts (Windows ${{ matrix.category }})
|
|
if: steps.test-examples.outputs.test-status == 'FAILED'
|
|
uses: actions/upload-artifact@v5
|
|
with:
|
|
name: java-examples-failure-windows-${{ matrix.category }}-${{ github.run_id }}
|
|
path: |
|
|
test-results/${{ matrix.category }}/
|
|
HDF5Examples/JAVA/${{ matrix.category }}/*.class
|
|
HDF5Examples/JAVA/${{ matrix.category }}/*.h5
|
|
|
|
test-examples-macos:
|
|
name: "Test Examples macOS (${{ matrix.category }})"
|
|
runs-on: macos-latest
|
|
continue-on-error: true
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
category: [H5D, H5T, H5G, TUTR]
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v5.0.0
|
|
|
|
- name: Download Maven artifacts (macOS aarch64)
|
|
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
|
|
with:
|
|
name: maven-staging-artifacts-macos-aarch64
|
|
path: ./maven-artifacts
|
|
continue-on-error: true
|
|
|
|
- name: Set up JDK 21
|
|
uses: actions/setup-java@v5
|
|
with:
|
|
java-version: '21'
|
|
distribution: 'temurin'
|
|
|
|
- name: Cache Maven dependencies
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: ~/.m2/repository
|
|
key: ${{ runner.os }}-maven-examples-${{ hashFiles('**/pom-examples.xml*') }}
|
|
|
|
- name: Test Examples Category ${{ matrix.category }}
|
|
id: test-examples
|
|
run: |
|
|
cd HDF5Examples/JAVA/${{ matrix.category }}
|
|
|
|
echo "=== Testing ${{ matrix.category }} Examples ==="
|
|
|
|
# Create test results directory
|
|
mkdir -p ../../../test-results/${{ matrix.category }}
|
|
|
|
FAILED_EXAMPLES=""
|
|
TOTAL_EXAMPLES=0
|
|
PASSED_EXAMPLES=0
|
|
|
|
# Test each Java example in the category
|
|
for java_file in *.java; do
|
|
if [ -f "$java_file" ]; then
|
|
TOTAL_EXAMPLES=$((TOTAL_EXAMPLES + 1))
|
|
example_name=$(basename "$java_file" .java)
|
|
echo "--- Testing $example_name ---"
|
|
|
|
# Build classpath (use platform-specific artifacts)
|
|
MAVEN_ARTIFACTS_DIR="../../../maven-artifacts"
|
|
HDF5_JAR=$(find "$MAVEN_ARTIFACTS_DIR" -name "*hdf5*.jar" -o -name "jarhdf5*.jar" | head -1)
|
|
DEP_JARS=$(find "$MAVEN_ARTIFACTS_DIR" -name "slf4j-api*.jar" -o -name "slf4j-simple*.jar")
|
|
|
|
if [ -z "$HDF5_JAR" ]; then
|
|
echo "❌ No HDF5 JAR found"
|
|
find "$MAVEN_ARTIFACTS_DIR" -name "*.jar" | head -10
|
|
continue
|
|
fi
|
|
|
|
CLASSPATH="$HDF5_JAR"
|
|
for dep_jar in $DEP_JARS; do
|
|
CLASSPATH="$CLASSPATH:$dep_jar"
|
|
done
|
|
|
|
# Compile the example
|
|
if javac -cp "$CLASSPATH" "$java_file"; then
|
|
echo "✓ Compilation successful for $example_name"
|
|
|
|
# Run the example and capture output
|
|
if timeout 30s java -cp ".:$CLASSPATH" "$example_name" > "../../../test-results/${{ matrix.category }}/${example_name}.output" 2>&1; then
|
|
# Validate output using pattern matching
|
|
output_file="../../../test-results/${{ matrix.category }}/${example_name}.output"
|
|
|
|
# Check for common success patterns
|
|
if grep -q -i -E "(dataset|datatype|group|success|created|written|read)" "$output_file" && \
|
|
! grep -q -i -E "(error|exception|failed|cannot)" "$output_file"; then
|
|
echo "✓ Execution and validation successful for $example_name"
|
|
PASSED_EXAMPLES=$((PASSED_EXAMPLES + 1))
|
|
else
|
|
echo "✗ Output validation failed for $example_name"
|
|
FAILED_EXAMPLES="$FAILED_EXAMPLES $example_name"
|
|
fi
|
|
else
|
|
echo "✗ Execution failed for $example_name"
|
|
FAILED_EXAMPLES="$FAILED_EXAMPLES $example_name"
|
|
fi
|
|
else
|
|
echo "✗ Compilation failed for $example_name"
|
|
FAILED_EXAMPLES="$FAILED_EXAMPLES $example_name"
|
|
fi
|
|
echo ""
|
|
fi
|
|
done
|
|
|
|
# Summary
|
|
echo "=== ${{ matrix.category }} Summary ==="
|
|
echo "Total examples: $TOTAL_EXAMPLES"
|
|
echo "Passed: $PASSED_EXAMPLES"
|
|
echo "Failed: $((TOTAL_EXAMPLES - PASSED_EXAMPLES))"
|
|
|
|
if [ -n "$FAILED_EXAMPLES" ]; then
|
|
echo "Failed examples:$FAILED_EXAMPLES"
|
|
echo "failed-examples=$FAILED_EXAMPLES" >> $GITHUB_OUTPUT
|
|
echo "test-status=FAILED" >> $GITHUB_OUTPUT
|
|
else
|
|
echo "All examples passed!"
|
|
echo "test-status=PASSED" >> $GITHUB_OUTPUT
|
|
fi
|
|
|
|
echo "total-examples=$TOTAL_EXAMPLES" >> $GITHUB_OUTPUT
|
|
echo "passed-examples=$PASSED_EXAMPLES" >> $GITHUB_OUTPUT
|
|
|
|
- name: Upload failure artifacts (macOS ${{ matrix.category }})
|
|
if: steps.test-examples.outputs.test-status == 'FAILED'
|
|
uses: actions/upload-artifact@v5
|
|
with:
|
|
name: java-examples-failure-macos-${{ matrix.category }}-${{ github.run_id }}
|
|
path: |
|
|
test-results/${{ matrix.category }}/
|
|
HDF5Examples/JAVA/${{ matrix.category }}/*.class
|
|
HDF5Examples/JAVA/${{ matrix.category }}/*.h5
|
|
|
|
analyze-cross-platform-failures:
|
|
name: "Analyze Cross-Platform Failures"
|
|
runs-on: ubuntu-latest
|
|
needs: [test-examples-linux, test-examples-windows, test-examples-macos]
|
|
if: always()
|
|
steps:
|
|
- name: Collect Test Results
|
|
run: |
|
|
echo "=== Java Examples Testing Summary ==="
|
|
|
|
# Collect results from matrix outputs (this would need to be enhanced
|
|
# to actually collect the outputs from the matrix jobs)
|
|
|
|
echo "Cross-platform failure analysis:"
|
|
echo "- Examples failing on multiple platforms require attention"
|
|
echo "- Single-platform failures may be platform-specific issues"
|
|
|
|
# This step would analyze patterns in failures across platforms
|
|
# and generate appropriate alerts/issues for multi-platform failures
|
|
|
|
- name: Generate Test Summary Report
|
|
run: |
|
|
cat > java-examples-test-summary.md << 'EOF'
|
|
# Java Examples Maven Testing Summary
|
|
|
|
**Build Mode**: ${{ inputs.build_mode }}
|
|
**Maven Version**: ${{ inputs.maven_artifacts_version }}
|
|
**Date**: $(date -u +"%Y-%m-%d %H:%M:%S UTC")
|
|
|
|
## Platform Results
|
|
- **Linux**: See individual category results
|
|
- **Windows**: See individual category results
|
|
- **macOS**: See individual category results
|
|
|
|
## Cross-Platform Analysis
|
|
Examples failing on multiple platforms require investigation.
|
|
|
|
EOF
|
|
|
|
echo "Test summary report generated"
|
|
|
|
- name: Upload Test Summary
|
|
uses: actions/upload-artifact@v5
|
|
with:
|
|
name: java-examples-test-summary-${{ github.run_id }}
|
|
path: java-examples-test-summary.md
|
|
retention-days: 30 |