Skip to content

Fix lazy-deploy extension UUID format #13

Fix lazy-deploy extension UUID format

Fix lazy-deploy extension UUID format #13

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/