Fix lazy-deploy extension UUID format #13
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Deployment Timing Tests | |
| # Tests for LDEV-5478 / LDEV-5960 - deploy folder timing issues | |
| # Verifies that extensions in the deploy folder are fully initialized before requests are served | |
| on: | |
| workflow_dispatch: | |
| push: | |
| branches: | |
| - deployment-tests | |
| paths: | |
| - 'custom/deployment-tests/**' | |
| - '.github/workflows/deployment-tests.yml' | |
| env: | |
| EXPRESS_TEMPLATE_URL: https://cdn.lucee.org/express-templates/lucee-tomcat-11.0.13-template.zip | |
| jobs: | |
| # Build the test extension | |
| build-extensions: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up JDK 11 | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: 11 | |
| distribution: temurin | |
| - name: Cache Maven packages | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.m2 | |
| key: maven-cache-extensions | |
| - name: Build slow-startup extension | |
| run: | | |
| cd custom/deployment-tests/extensions/slow-startup | |
| mvn package -q | |
| ls -la target/ | |
| echo "Extension built:" | |
| unzip -l target/*.lex | |
| - name: Build lazy-deploy extension | |
| run: | | |
| cd custom/deployment-tests/extensions/lazy-deploy | |
| mvn package -q | |
| ls -la target/ | |
| echo "Extension built:" | |
| unzip -l target/*.lex | |
| - name: Upload slow-startup extension | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: slow-startup-extension | |
| path: custom/deployment-tests/extensions/slow-startup/target/*.lex | |
| retention-days: 1 | |
| - name: Upload lazy-deploy extension | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: lazy-deploy-extension | |
| path: custom/deployment-tests/extensions/lazy-deploy/target/*.lex | |
| retention-days: 1 | |
| # Build Lucee from source (for build-from-source entries) | |
| build-lucee: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - name: "7.1-native" | |
| repo: "zspitzer/Lucee" | |
| ref: "LDEV-1402-native-debugger" | |
| steps: | |
| - name: Checkout Lucee | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: ${{ matrix.repo }} | |
| ref: ${{ matrix.ref }} | |
| path: lucee | |
| - name: Get commit SHA | |
| id: get-commit | |
| run: | | |
| cd lucee | |
| echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT | |
| echo "short_sha=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT | |
| - name: Cache Lucee JAR | |
| id: cache-lucee | |
| uses: actions/cache@v4 | |
| with: | |
| path: lucee-jar/ | |
| key: lucee-${{ matrix.name }}-${{ steps.get-commit.outputs.sha }} | |
| - name: Set up JDK 21 | |
| if: steps.cache-lucee.outputs.cache-hit != 'true' | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: 21 | |
| distribution: temurin | |
| - name: Cache Maven packages | |
| if: steps.cache-lucee.outputs.cache-hit != 'true' | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.m2 | |
| key: lucee-maven-${{ hashFiles('lucee/**/pom.xml') }} | |
| restore-keys: lucee-maven- | |
| - name: Build Lucee | |
| if: steps.cache-lucee.outputs.cache-hit != 'true' | |
| run: | | |
| cd lucee/loader | |
| ant fast | |
| mkdir -p ../../lucee-jar | |
| cp target/lucee-*.jar ../../lucee-jar/ | |
| - name: Upload Lucee JAR | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: lucee-${{ matrix.name }} | |
| path: lucee-jar/lucee-*.jar | |
| retention-days: 1 | |
| # Test deployment timing | |
| test-deploy-timing: | |
| needs: [build-extensions, build-lucee] | |
| if: always() && needs.build-extensions.result == 'success' | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # Download from CDN - immediate (should fail - bug exists) | |
| - name: "7.0-snapshot-immediate" | |
| source: "download" | |
| luceeVersion: "7.0/snapshot/jar" | |
| delay: 0 | |
| - name: "6.2-snapshot-immediate" | |
| source: "download" | |
| luceeVersion: "6.2/snapshot/jar" | |
| delay: 0 | |
| # Download from CDN - delayed (should pass - proves extension works) | |
| - name: "7.0-snapshot-delayed" | |
| source: "download" | |
| luceeVersion: "7.0/snapshot/jar" | |
| delay: 10 | |
| - name: "6.2-snapshot-delayed" | |
| source: "download" | |
| luceeVersion: "6.2/snapshot/jar" | |
| delay: 10 | |
| # Build from source - immediate | |
| - name: "7.1-native-immediate" | |
| source: "build" | |
| artifactName: "7.1-native" | |
| delay: 0 | |
| # Build from source - delayed | |
| - name: "7.1-native-delayed" | |
| source: "build" | |
| artifactName: "7.1-native" | |
| delay: 10 | |
| # Stress tests - hit multiple endpoints in parallel immediately | |
| - name: "7.0-snapshot-stress" | |
| source: "download" | |
| luceeVersion: "7.0/snapshot/jar" | |
| delay: 0 | |
| testMode: "stress" | |
| - name: "6.2-snapshot-stress" | |
| source: "download" | |
| luceeVersion: "6.2/snapshot/jar" | |
| delay: 0 | |
| testMode: "stress" | |
| - name: "7.1-native-stress" | |
| source: "build" | |
| artifactName: "7.1-native" | |
| delay: 0 | |
| testMode: "stress" | |
| # Lazy deploy tests - NO startup hook, should expose LDEV-5960 | |
| - name: "7.0-lazy-immediate" | |
| source: "download" | |
| luceeVersion: "7.0/snapshot/jar" | |
| delay: 0 | |
| extension: "lazy-deploy" | |
| testPage: "test-lazy-deploy.cfm" | |
| - name: "7.0-lazy-delayed" | |
| source: "download" | |
| luceeVersion: "7.0/snapshot/jar" | |
| delay: 10 | |
| extension: "lazy-deploy" | |
| testPage: "test-lazy-deploy.cfm" | |
| - name: "6.2-lazy-immediate" | |
| source: "download" | |
| luceeVersion: "6.2/snapshot/jar" | |
| delay: 0 | |
| extension: "lazy-deploy" | |
| testPage: "test-lazy-deploy.cfm" | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up JDK 21 | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: 21 | |
| distribution: temurin | |
| - name: Download slow-startup extension | |
| if: matrix.extension != 'lazy-deploy' | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: slow-startup-extension | |
| path: extensions/ | |
| - name: Download lazy-deploy extension | |
| if: matrix.extension == 'lazy-deploy' | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: lazy-deploy-extension | |
| path: extensions/ | |
| - name: Download Lucee Express template | |
| run: | | |
| curl -L -o express-template.zip "$EXPRESS_TEMPLATE_URL" | |
| unzip -q express-template.zip -d express | |
| # Download Lucee JAR from CDN | |
| - name: Download Lucee JAR (from CDN) | |
| if: matrix.source == 'download' | |
| run: | | |
| LUCEE_FILENAME=$(curl -s "https://update.lucee.org/rest/update/provider/latest/${{ matrix.luceeVersion }}/filename" | tr -d '"') | |
| echo "Lucee filename: $LUCEE_FILENAME" | |
| LUCEE_URL="https://cdn.lucee.org/$LUCEE_FILENAME" | |
| echo "Downloading from: $LUCEE_URL" | |
| curl -L -f -o lucee.jar "$LUCEE_URL" | |
| if ! unzip -t lucee.jar > /dev/null 2>&1; then | |
| echo "ERROR: Downloaded JAR is corrupt!" | |
| exit 1 | |
| fi | |
| rm -f express/lib/lucee-*.jar | |
| cp lucee.jar express/lib/ | |
| # Download Lucee JAR from build artifact | |
| - name: Download Lucee JAR (from build) | |
| if: matrix.source == 'build' | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: lucee-${{ matrix.artifactName }} | |
| path: lucee-jar/ | |
| - name: Install built Lucee JAR | |
| if: matrix.source == 'build' | |
| run: | | |
| rm -f express/lib/lucee-*.jar | |
| cp lucee-jar/lucee-*.jar express/lib/ | |
| echo "Installed JAR:" | |
| ls -la express/lib/lucee-*.jar | |
| - name: Prepare test environment | |
| run: | | |
| echo "## Test: ${{ matrix.name }}" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| # Copy test script to webroot | |
| TEST_PAGE="${{ matrix.testPage }}" | |
| if [ -z "$TEST_PAGE" ]; then | |
| TEST_PAGE="test-slow-startup.cfm" | |
| fi | |
| cp "custom/deployment-tests/$TEST_PAGE" express/webapps/ROOT/ | |
| echo "Test page: $TEST_PAGE" | |
| # Copy extension to deploy folder BEFORE starting Lucee | |
| mkdir -p express/lucee-server/deploy/ | |
| cp extensions/*.lex express/lucee-server/deploy/ | |
| echo "Extension in deploy folder:" | |
| ls -la express/lucee-server/deploy/ | |
| # Configure trace logging | |
| echo 'export LUCEE_LOGGING_FORCE_LEVEL=trace' >> express/bin/setenv.sh | |
| chmod +x express/bin/setenv.sh | |
| # Configure Tomcat port | |
| sed -i 's/port="8080"/port="8888"/g' express/conf/server.xml | |
| - name: Start Lucee and test | |
| id: test | |
| run: | | |
| cd express | |
| echo "Starting Lucee Express..." | |
| ./bin/catalina.sh start | |
| echo "Lucee started" | |
| # Apply delay if configured (0 = immediate, 30 = delayed) | |
| if [ "${{ matrix.delay }}" -gt 0 ]; then | |
| echo "Waiting ${{ matrix.delay }} seconds before first request..." | |
| sleep ${{ matrix.delay }} | |
| else | |
| echo "Making immediate request (no delay)..." | |
| fi | |
| # Stress test mode - hit multiple endpoints in parallel | |
| if [ "${{ matrix.testMode }}" = "stress" ]; then | |
| echo "=== STRESS TEST MODE ===" | |
| echo "Waiting for Tomcat to accept connections..." | |
| for i in {1..60}; do | |
| if curl -s -o /dev/null http://127.0.0.1:8888/ 2>/dev/null; then | |
| echo "Tomcat responding after $i seconds" | |
| break | |
| fi | |
| sleep 1 | |
| done | |
| echo "Firing parallel requests to all endpoints..." | |
| # Hit all endpoints in parallel | |
| curl -s -o /tmp/ext.txt -w "%{http_code}" http://127.0.0.1:8888/test-slow-startup.cfm > /tmp/ext_code.txt 2>&1 & | |
| PID1=$! | |
| curl -s -o /tmp/admin.txt -w "%{http_code}" http://127.0.0.1:8888/lucee/admin/index.cfm > /tmp/admin_code.txt 2>&1 & | |
| PID2=$! | |
| curl -s -o /tmp/res.txt -w "%{http_code}" http://127.0.0.1:8888/lucee/res/js/admin.js.cfm > /tmp/res_code.txt 2>&1 & | |
| PID3=$! | |
| wait $PID1 $PID2 $PID3 | |
| EXT_CODE=$(cat /tmp/ext_code.txt) | |
| ADMIN_CODE=$(cat /tmp/admin_code.txt) | |
| RES_CODE=$(cat /tmp/res_code.txt) | |
| echo "Extension endpoint: $EXT_CODE" | |
| echo "Admin endpoint: $ADMIN_CODE" | |
| echo "Resource endpoint: $RES_CODE" | |
| FAILED=0 | |
| echo "### Stress Test Results" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| if [ "$EXT_CODE" = "200" ]; then | |
| echo "✅ Extension: PASSED" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "❌ Extension: FAILED ($EXT_CODE)" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| cat /tmp/ext.txt >> $GITHUB_STEP_SUMMARY 2>/dev/null || echo "(no response)" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| FAILED=1 | |
| fi | |
| if [ "$ADMIN_CODE" = "200" ]; then | |
| echo "✅ Admin: PASSED" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "❌ Admin: FAILED ($ADMIN_CODE)" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| cat /tmp/admin.txt >> $GITHUB_STEP_SUMMARY 2>/dev/null || echo "(no response)" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| FAILED=1 | |
| fi | |
| if [ "$RES_CODE" = "200" ]; then | |
| echo "✅ Resource: PASSED" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "❌ Resource: FAILED ($RES_CODE)" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| cat /tmp/res.txt >> $GITHUB_STEP_SUMMARY 2>/dev/null || echo "(no response)" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| FAILED=1 | |
| fi | |
| if [ "$FAILED" = "1" ]; then | |
| echo "STRESS TEST FAILED" | |
| exit 1 | |
| else | |
| echo "STRESS TEST PASSED - all endpoints responded 200" | |
| exit 0 | |
| fi | |
| fi | |
| # Normal test mode - single endpoint | |
| TEST_PAGE="${{ matrix.testPage }}" | |
| if [ -z "$TEST_PAGE" ]; then | |
| TEST_PAGE="test-slow-startup.cfm" | |
| fi | |
| for i in {1..60}; do | |
| echo "Attempt $i..." | |
| HTTP_CODE=$(curl -s -o /tmp/response.txt -w "%{http_code}" "http://127.0.0.1:8888/$TEST_PAGE" 2>/dev/null) || HTTP_CODE="000" | |
| echo "HTTP Code: $HTTP_CODE" | |
| if [ "$HTTP_CODE" != "000" ] && [ -f /tmp/response.txt ]; then | |
| echo "=== Response ===" | |
| cat /tmp/response.txt | |
| echo "" | |
| echo "================" | |
| if [ "$HTTP_CODE" = "200" ]; then | |
| echo "TEST PASSED: Extension ready on first request" | |
| echo "### Result: PASSED" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| cat /tmp/response.txt >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| exit 0 | |
| else | |
| echo "TEST FAILED: Extension NOT ready - LDEV-5478 reproduced!" | |
| echo "### Result: FAILED (LDEV-5478 reproduced)" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| cat /tmp/response.txt >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| exit 1 | |
| fi | |
| fi | |
| sleep 1 | |
| done | |
| echo "TEST INCONCLUSIVE: Tomcat never responded" | |
| echo "### Result: INCONCLUSIVE (Tomcat timeout)" >> $GITHUB_STEP_SUMMARY | |
| exit 1 | |
| - name: Stop Lucee | |
| if: always() | |
| run: | | |
| cd express | |
| ./bin/shutdown.sh || true | |
| - name: Show catalina.out | |
| if: always() | |
| run: | | |
| echo "=== catalina.out ===" | |
| cat express/logs/catalina.out || echo "No catalina.out found" | |
| - name: Upload logs on failure | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: lucee-logs-${{ matrix.name }} | |
| path: | | |
| express/logs/ | |
| express/lucee-server/context/logs/ |