Skip to content

Refactor tests to use AssertJ assertions instead of JUnit assertions #75

Refactor tests to use AssertJ assertions instead of JUnit assertions

Refactor tests to use AssertJ assertions instead of JUnit assertions #75

name: Test Python Bindings
on:
# Run on push to bindings/python/ directory
push:
paths:
- 'bindings/python/**'
- '.github/workflows/test-python-bindings.yml'
# Run on pull request affecting bindings/python/
pull_request:
paths:
- 'bindings/python/**'
- '.github/workflows/test-python-bindings.yml'
# Run after release workflow completes
workflow_run:
workflows: ["Release"]
types: [completed]
# Allow being called by other workflows (e.g., release workflow)
workflow_call:
# Allow manual trigger
workflow_dispatch:
permissions:
contents: read
jobs:
# First job: Download ArcadeDB JARs (platform-agnostic)
download-jars:
name: Download ArcadeDB JARs
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Download JARs from ArcadeDB Docker image
shell: bash
run: |
cd bindings/python
# Detect ArcadeDB version from pom.xml (Docker format: X.Y.Z-SNAPSHOT)
ARCADEDB_TAG=$(python3 extract_version.py --format=docker)
echo "📌 ArcadeDB version: $ARCADEDB_TAG"
# Download JARs from official Docker image
echo "📦 Downloading JARs from arcadedata/arcadedb:$ARCADEDB_TAG..."
# Create output directory
mkdir -p src/arcadedb_embedded/jars
# Create a temporary container and copy JARs from it
CONTAINER_ID=$(docker create arcadedata/arcadedb:$ARCADEDB_TAG)
docker cp $CONTAINER_ID:/home/arcadedb/lib/. src/arcadedb_embedded/jars/
docker rm $CONTAINER_ID
# Verify JARs were downloaded
ls -lh src/arcadedb_embedded/jars/
JAR_COUNT=$(ls -1 src/arcadedb_embedded/jars/*.jar 2>/dev/null | wc -l)
echo "✅ Downloaded $JAR_COUNT JAR files"
- name: Remove excluded JARs
shell: bash
run: |
cd bindings/python
JARS_DIR="src/arcadedb_embedded/jars"
EXCLUSIONS_FILE="jar_exclusions.txt"
if [[ -f "$EXCLUSIONS_FILE" ]]; then
echo "🗑️ Removing excluded JARs from jar_exclusions.txt..."
EXCLUSION_COUNT=0
while IFS= read -r pattern || [[ -n "$pattern" ]]; do
# Skip empty lines and comments
if [[ -n "$pattern" ]] && [[ ! "$pattern" =~ ^# ]]; then
echo " Processing pattern: $pattern"
# Remove matching JARs
for jar in "$JARS_DIR"/$pattern; do
if [[ -f "$jar" ]]; then
rm -f "$jar"
echo " - Removed: $(basename "$jar")"
EXCLUSION_COUNT=$((EXCLUSION_COUNT + 1))
fi
done
fi
done < "$EXCLUSIONS_FILE"
JAR_COUNT_AFTER=$(ls -1 "$JARS_DIR"/*.jar 2>/dev/null | wc -l)
echo "✅ Removed $EXCLUSION_COUNT JAR(s), $JAR_COUNT_AFTER remaining"
else
echo "⚠️ No jar_exclusions.txt found, skipping exclusions"
fi
- name: Upload filtered JARs as artifact
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: arcadedb-jars
path: bindings/python/src/arcadedb_embedded/jars/*.jar
retention-days: 1
# Second job: Build and test on each platform
test:
name: Test arcadedb-embedded (${{ matrix.platform }})
runs-on: ${{ matrix.runs-on }}
needs: download-jars
strategy:
# Don't cancel other matrix jobs if one fails
fail-fast: false
matrix:
include:
- platform: linux/amd64
runs-on: ubuntu-24.04
- platform: linux/arm64
runs-on: ubuntu-24.04-arm
- platform: darwin/amd64
runs-on: macos-15-intel
- platform: darwin/arm64
runs-on: macos-15
- platform: windows/amd64
runs-on: windows-2025
- platform: windows/arm64
runs-on: windows-11-arm
steps:
- name: Checkout code
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Set up Python
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: '3.11'
- name: Download ArcadeDB JARs artifact
# Skip for Linux: Docker build downloads JARs from ArcadeDB image directly
# Only needed for native builds (macOS/Windows)
if: matrix.platform != 'linux/amd64' && matrix.platform != 'linux/arm64'
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: arcadedb-jars
path: bindings/python/src/arcadedb_embedded/jars
- name: Set up Java (for native builds on macOS/Windows)
if: matrix.platform != 'linux/amd64' && matrix.platform != 'linux/arm64'
uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0
with:
distribution: 'temurin'
java-version: '21'
- name: Set up Docker Buildx (Linux only)
if: matrix.platform == 'linux/amd64' || matrix.platform == 'linux/arm64'
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Install Python build dependencies
shell: bash
run: |
python -m pip install --upgrade pip
pip install build wheel setuptools
- name: Create python3 symlink (Windows only)
if: matrix.platform == 'windows/amd64' || matrix.platform == 'windows/arm64'
shell: bash
run: |
# On Windows, setup-python doesn't create python3 symlink
# Create it so build scripts work
PYTHON_DIR=$(dirname "$(which python)")
ln -s "$PYTHON_DIR/python.exe" "$PYTHON_DIR/python3.exe" || true
python3 --version
- name: Build and test arcadedb-embedded (${{ matrix.platform }})
shell: bash
run: |
cd bindings/python
echo "🔨 Building arcadedb-embedded for ${{ matrix.platform }}..."
./build.sh ${{ matrix.platform }}
- name: Extract wheel for additional testing
shell: bash
run: |
cd bindings/python
mkdir -p test-install
cp dist/*.whl test-install/
- name: Set up Python for host testing
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: '3.11'
# Note: Java is NOT required for arcadedb-embedded (JRE is bundled)
# This package works without any external Java installation!
- name: Install wheel and test dependencies
shell: bash
run: |
cd bindings/python
pip install test-install/*.whl pytest pytest-cov requests
- name: Run pytest on host
id: pytest
shell: bash
run: |
cd bindings/python
echo "🧪 Testing arcadedb-embedded (with bundled JRE)..."
# Run pytest with JUnit XML output for structured results
set +e # Don't exit on test failures
pytest tests/ -v --tb=short --color=yes --junitxml=test-results.xml
PYTEST_EXIT_CODE=$?
set -e
# Parse JUnit XML for test counts (cross-platform XML parsing)
if [ -f "test-results.xml" ]; then
# Extract counts from testsuite element
PASSED=$(grep -oE 'tests="[0-9]+"' test-results.xml | grep -oE '[0-9]+' | head -1)
FAILED=$(grep -oE 'failures="[0-9]+"' test-results.xml | grep -oE '[0-9]+' | head -1)
SKIPPED=$(grep -oE 'skipped="[0-9]+"' test-results.xml | grep -oE '[0-9]+' | head -1)
# Default to 0 if not found
PASSED=${PASSED:-0}
FAILED=${FAILED:-0}
SKIPPED=${SKIPPED:-0}
echo "passed=$PASSED" >> $GITHUB_OUTPUT
echo "skipped=$SKIPPED" >> $GITHUB_OUTPUT
echo "failed=$FAILED" >> $GITHUB_OUTPUT
echo "✅ Test results: $PASSED passed, $SKIPPED skipped, $FAILED failed"
else
echo "⚠️ test-results.xml not found"
exit 1
fi
# Exit with pytest's exit code
exit $PYTEST_EXIT_CODE
- name: Generate test summary
if: always()
shell: bash
run: |
cd bindings/python
echo "## 🧪 Test Results: arcadedb-embedded (${{ matrix.platform }})" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# Check test status
if [ "${{ steps.pytest.outcome }}" = "success" ]; then
echo "✅ **Status**: PASSED" >> $GITHUB_STEP_SUMMARY
else
echo "❌ **Status**: FAILED" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Metric | Count |" >> $GITHUB_STEP_SUMMARY
echo "|--------|-------|" >> $GITHUB_STEP_SUMMARY
# Show test results
echo "| ✅ Passed | ${{ steps.pytest.outputs.passed || 'N/A' }} |" >> $GITHUB_STEP_SUMMARY
echo "| ⏭️ Skipped | ${{ steps.pytest.outputs.skipped || 'N/A' }} |" >> $GITHUB_STEP_SUMMARY
echo "| ❌ Failed | ${{ steps.pytest.outputs.failed || 'N/A' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 📦 Package Info:" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# Get wheel size and analyze contents
WHEEL_FILE=$(ls dist/*.whl 2>/dev/null | head -n1)
if [ -n "$WHEEL_FILE" ]; then
# Get wheel size (portable way)
if stat -c%s "$WHEEL_FILE" 2>/dev/null; then
# Linux
WHEEL_SIZE_BYTES=$(stat -c%s "$WHEEL_FILE")
else
# macOS/BSD
WHEEL_SIZE_BYTES=$(stat -f%z "$WHEEL_FILE")
fi
WHEEL_SIZE_MB=$(python3 -c "print(f'{$WHEEL_SIZE_BYTES / 1024 / 1024:.1f}')")
# Unzip and analyze components (wheel is a zip file)
TEMP_DIR=$(mktemp -d)
unzip -q "$WHEEL_FILE" -d "$TEMP_DIR"
# Calculate JRE size (look for jre/ directory anywhere)
JRE_DIR=$(find "$TEMP_DIR" -type d -name "jre" | head -n1)
if [ -n "$JRE_DIR" ] && [ -d "$JRE_DIR" ]; then
# Use du with -k for KB (portable across Linux/macOS)
JRE_SIZE_KB=$(du -sk "$JRE_DIR" | cut -f1)
JRE_SIZE_MB=$(python3 -c "print(f'{$JRE_SIZE_KB / 1024:.1f}')")
else
JRE_SIZE_MB="N/A"
fi
# Calculate JAR size (*.jar files)
JAR_COUNT=$(find "$TEMP_DIR" -name "*.jar" | wc -l | tr -d ' ')
if [ "$JAR_COUNT" -gt 0 ]; then
JAR_SIZE_KB=$(find "$TEMP_DIR" -name "*.jar" -exec du -k {} + | awk '{sum+=$1} END {print sum}')
JAR_SIZE_MB=$(python3 -c "print(f'{$JAR_SIZE_KB / 1024:.1f}')")
else
JAR_SIZE_MB="N/A"
fi
# Calculate installed size (total uncompressed)
INSTALLED_SIZE_KB=$(du -sk "$TEMP_DIR" | cut -f1)
INSTALLED_SIZE_MB=$(python3 -c "print(f'{$INSTALLED_SIZE_KB / 1024:.0f}')")
rm -rf "$TEMP_DIR"
echo "- **Wheel Size**: ${WHEEL_SIZE_MB}M (compressed)" >> $GITHUB_STEP_SUMMARY
echo "- **JRE Size**: ${JRE_SIZE_MB}M (uncompressed)" >> $GITHUB_STEP_SUMMARY
echo "- **JARs Size**: ${JAR_SIZE_MB}M (uncompressed)" >> $GITHUB_STEP_SUMMARY
echo "- **Installed Size**: ~${INSTALLED_SIZE_MB}M (total uncompressed)" >> $GITHUB_STEP_SUMMARY
fi
echo "- **Platform**: ${{ matrix.platform }}" >> $GITHUB_STEP_SUMMARY
echo "- **Features**: All ArcadeDB features (some JARs excluded, see jar_exclusions.txt)" >> $GITHUB_STEP_SUMMARY
- name: Upload test results
if: always()
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: test-results-${{ matrix.platform == 'linux/amd64' && 'linux-amd64' || matrix.platform == 'linux/arm64' && 'linux-arm64' || matrix.platform == 'darwin/amd64' && 'darwin-amd64' || matrix.platform == 'darwin/arm64' && 'darwin-arm64' || matrix.platform == 'windows/amd64' && 'windows-amd64' || 'windows-arm64' }}
path: |
bindings/python/pytest-output.txt
bindings/python/.coverage
retention-days: 7
- name: Upload wheel artifact
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: wheel-${{ matrix.platform == 'linux/amd64' && 'linux-amd64' || matrix.platform == 'linux/arm64' && 'linux-arm64' || matrix.platform == 'darwin/amd64' && 'darwin-amd64' || matrix.platform == 'darwin/arm64' && 'darwin-arm64' || matrix.platform == 'windows/amd64' && 'windows-amd64' || 'windows-arm64' }}-test
path: bindings/python/dist/*.whl
retention-days: 7
# Summary job that checks all platforms
test-summary:
name: Test Summary
needs: test
runs-on: ubuntu-24.04
if: always()
steps:
- name: Check test results
run: |
echo "## 🎯 Overall Test Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [ "${{ needs.test.result }}" = "success" ]; then
echo "✅ **All platforms passed testing!**" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "The arcadedb-embedded package has been successfully built and tested." >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Package**: arcadedb-embedded (~160MB with bundled JRE)" >> $GITHUB_STEP_SUMMARY
else
echo "❌ **Some platforms failed testing**" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Please check the individual test jobs for details." >> $GITHUB_STEP_SUMMARY
exit 1
fi