"QA: Runtime Providers"
Manual QA checklist for verifying the three runtime providers work correctly.
Run these from the demo_servers/ directory after building LuCLI (./build.sh).
Prerequisites
# Build LuCLI
./build.sh install
# Verify binary
lucli --version
# Clean up any leftover servers from previous runs
lucli server list
lucli server stop --all 2>/dev/null
1. Lucee Express (default runtime)
1a. Basic start/stop
mkdir -p demo_servers/qa-express && cd demo_servers/qa-express
cat > lucee.json << 'EOF'
{
"name": "qa-express",
"version": "6.2.2.91",
"port": 8180,
"webroot": "./",
"openBrowser": false
}
EOF
echo '<cfoutput>Express OK - #now()#</cfoutput>' > index.cfm
# Start server
lucli server start
# VERIFY: Server starts without errors
# VERIFY: "Starting server 'qa-express' on:" message shows port 8180
# Test HTTP response
curl -s http://localhost:8180/index.cfm
# VERIFY: Response contains "Express OK"
# Check server status
lucli server status
# VERIFY: Shows "qa-express" as RUNNING
# Check CATALINA_HOME != CATALINA_BASE
ls ~/.lucli/servers/qa-express/conf/server.xml
# VERIFY: server.xml exists in CATALINA_BASE
# Stop server
lucli server stop
# VERIFY: Server stops cleanly
1b. Express with explicit runtime config
cd demo_servers/qa-express
cat > lucee.json << 'EOF'
{
"name": "qa-express-explicit",
"version": "6.2.2.91",
"port": 8181,
"webroot": "./",
"openBrowser": false,
"runtime": {
"type": "lucee-express",
"variant": "standard"
}
}
EOF
lucli server start
curl -s http://localhost:8181/index.cfm
# VERIFY: Response contains "Express OK"
lucli server stop
1c. Express foreground mode
cd demo_servers/qa-express
lucli server run
# VERIFY: Server output appears in terminal
# VERIFY: "Running server 'qa-express' in foreground mode:" message
# VERIFY: Ctrl+C stops the server cleanly
1d. Express with force replace
cd demo_servers/qa-express
lucli server start
lucli server stop
lucli server start --force
# VERIFY: Server recreates CATALINA_BASE and starts fresh
lucli server stop
2. External Tomcat
2a. Setup
You need a Tomcat installation. If you don't have one:
# Option A: Homebrew
brew install tomcat
# Find your CATALINA_HOME
# Homebrew Tomcat 10: /opt/homebrew/opt/tomcat/libexec
# Homebrew Tomcat 9: /opt/homebrew/opt/tomcat@9/libexec
ls /opt/homebrew/opt/tomcat/libexec/bin/catalina.sh
# Option B: Download manually
# https://tomcat.apache.org/download-10.cgi
Set your Tomcat path for the tests below:
export MY_TOMCAT_HOME="/opt/homebrew/opt/tomcat/libexec"
# Adjust this path to your actual Tomcat installation
2b. Basic external Tomcat start/stop
mkdir -p demo_servers/qa-tomcat && cd demo_servers/qa-tomcat
cat > lucee.json << 'EOF'
{
"name": "qa-tomcat",
"version": "7.0.0.242-RC",
"port": 8280,
"webroot": "./",
"openBrowser": false,
"runtime": {
"type": "tomcat",
"catalinaHome": "${CATALINA_HOME_PLACEHOLDER}"
}
}
EOF
# Replace placeholder with actual path
sed -i '' "s|\${CATALINA_HOME_PLACEHOLDER}|$MY_TOMCAT_HOME|g" lucee.json
echo '<cfoutput>Tomcat OK - #now()# - CATALINA_HOME=#server.system.environment.CATALINA_HOME#</cfoutput>' > index.cfm
lucli server start
# VERIFY: "Using runtime.type="tomcat"" message
# VERIFY: "Detected Tomcat version: XX.x" message
# VERIFY: "Lucee X.x is compatible with Tomcat XX.x" message
# VERIFY: "Deploying Lucee JAR to server instance" message
# VERIFY: Port details show 8280
curl -s http://localhost:8280/index.cfm
# VERIFY: Response contains "Tomcat OK"
# VERIFY: CATALINA_HOME matches your Tomcat installation path
# Verify CATALINA_BASE structure
ls ~/.lucli/servers/qa-tomcat/
# VERIFY: Has conf/, lib/, logs/, lucee-server/, lucee-web/, bin/, temp/, work/
ls ~/.lucli/servers/qa-tomcat/lib/
# VERIFY: Contains lucee-7.0.0.242-RC.jar (or whatever version)
cat ~/.lucli/servers/qa-tomcat/conf/server.xml | grep 'port="8280"'
# VERIFY: server.xml contains the configured port
grep CFMLServlet ~/.lucli/servers/qa-tomcat/conf/web.xml
# VERIFY: Lucee servlets are present in web.xml
lucli server stop
# VERIFY: Server stops cleanly
2c. Tomcat version compatibility check
cd demo_servers/qa-tomcat
# Test INCOMPATIBLE combination (Lucee 6 + Tomcat 10+)
cat > lucee.json << EOF
{
"name": "qa-tomcat-compat",
"version": "6.2.2.91",
"port": 8281,
"webroot": "./",
"openBrowser": false,
"runtime": {
"type": "tomcat",
"catalinaHome": "$MY_TOMCAT_HOME"
}
}
EOF
lucli server start
# VERIFY (if Tomcat 10+): Error "Lucee 6.2.2.91 is not compatible with Tomcat XX"
# VERIFY: Error message suggests solutions (upgrade Lucee or use Tomcat 9)
# VERIFY (if Tomcat 9): Server starts normally (6.x is compatible with 9.x)
2d. Missing catalinaHome
cd demo_servers/qa-tomcat
cat > lucee.json << 'EOF'
{
"name": "qa-tomcat-missing",
"port": 8282,
"webroot": "./",
"openBrowser": false,
"runtime": {
"type": "tomcat",
"catalinaHome": "/nonexistent/path/to/tomcat"
}
}
EOF
lucli server start
# VERIFY: Error "CATALINA_HOME does not exist: /nonexistent/path/to/tomcat"
2e. Invalid Tomcat installation
mkdir -p /tmp/fake-tomcat
cd demo_servers/qa-tomcat
cat > lucee.json << 'EOF'
{
"name": "qa-tomcat-invalid",
"port": 8283,
"webroot": "./",
"openBrowser": false,
"runtime": {
"type": "tomcat",
"catalinaHome": "/tmp/fake-tomcat"
}
}
EOF
lucli server start
# VERIFY: Error about missing bin/ or lib/ directory
rm -rf /tmp/fake-tomcat
2f. Tomcat with CATALINA_HOME env var fallback
cd demo_servers/qa-tomcat
cat > lucee.json << 'EOF'
{
"name": "qa-tomcat-env",
"version": "7.0.0.242-RC",
"port": 8284,
"webroot": "./",
"openBrowser": false,
"runtime": {
"type": "tomcat"
}
}
EOF
CATALINA_HOME="$MY_TOMCAT_HOME" lucli server start
# VERIFY: Server starts using CATALINA_HOME from environment
lucli server stop
2g. Tomcat with HTTPS
cd demo_servers/qa-tomcat
cat > lucee.json << EOF
{
"name": "qa-tomcat-https",
"version": "7.0.0.242-RC",
"port": 8285,
"webroot": "./",
"openBrowser": false,
"https": {
"enabled": true,
"port": 8443,
"redirect": false
},
"runtime": {
"type": "tomcat",
"catalinaHome": "$MY_TOMCAT_HOME"
}
}
EOF
lucli server start
# VERIFY: Port details show both HTTP 8285 and HTTPS 8443
curl -sk https://localhost:8443/index.cfm
# VERIFY: HTTPS response works (self-signed cert)
lucli server stop
2h. Dry-run preview
cd demo_servers/qa-tomcat
cat > lucee.json << EOF
{
"name": "qa-tomcat-dryrun",
"version": "7.0.0.242-RC",
"port": 8286,
"webroot": "./",
"openBrowser": false,
"runtime": {
"type": "tomcat",
"catalinaHome": "$MY_TOMCAT_HOME"
}
}
EOF
lucli server start --dry-run
# VERIFY: Shows configuration preview without starting the server
# VERIFY: No server instance directory created
3. Docker
3a. Prerequisites
docker --version
# VERIFY: Docker is installed and running
3b. Basic Docker start/stop
mkdir -p demo_servers/qa-docker && cd demo_servers/qa-docker
cat > lucee.json << 'EOF'
{
"name": "qa-docker",
"version": "6.2.2.91",
"port": 8380,
"webroot": "./",
"openBrowser": false,
"runtime": {
"type": "docker"
}
}
EOF
echo '<cfoutput>Docker OK - #now()#</cfoutput>' > index.cfm
lucli server start
# VERIFY: "Using runtime.type="docker"" message
# VERIFY: Docker container starts
docker ps | grep lucli-qa-docker
# VERIFY: Container "lucli-qa-docker" is running
curl -s http://localhost:8380/index.cfm
# VERIFY: Response contains "Docker OK" (may take a moment for Lucee to warm up)
lucli server stop
# VERIFY: Container stops
docker ps | grep lucli-qa-docker
# VERIFY: Container no longer running
3c. Docker with custom image/tag
cd demo_servers/qa-docker
cat > lucee.json << 'EOF'
{
"name": "qa-docker-custom",
"port": 8381,
"webroot": "./",
"openBrowser": false,
"runtime": {
"type": "docker",
"image": "lucee/lucee",
"tag": "latest",
"containerName": "my-custom-lucee"
}
}
EOF
lucli server start
docker ps | grep my-custom-lucee
# VERIFY: Container uses the custom name
lucli server stop
4. Cross-runtime checks
4a. Server list shows runtime type
# Start one of each type (adjust ports to avoid conflicts)
cd demo_servers/qa-express && lucli server start
cd demo_servers/qa-tomcat && lucli server start # if external Tomcat is configured
lucli server list
# VERIFY: Each server shows in the list
# VERIFY: Ports are correct for each
lucli server stop --all
4b. Force replace cleans up properly
cd demo_servers/qa-express
lucli server start
lucli server stop
ls ~/.lucli/servers/qa-express/conf/server.xml
# VERIFY: Config exists from first run
lucli server start --force
# VERIFY: Old config is replaced
lucli server stop
5. Cleanup
# Stop all test servers
lucli server stop --all 2>/dev/null
# Remove test projects
rm -rf demo_servers/qa-express
rm -rf demo_servers/qa-tomcat
rm -rf demo_servers/qa-docker
# Remove server instances
rm -rf ~/.lucli/servers/qa-express*
rm -rf ~/.lucli/servers/qa-tomcat*
rm -rf ~/.lucli/servers/qa-docker*
Test matrix summary
| Test | Express | Tomcat | Docker |
|---|---|---|---|
| Start/stop | 1a | 2b | 3b |
| HTTP response | 1a | 2b | 3b |
| CATALINA_BASE structure | 1a | 2b | — |
| Foreground mode | 1c | — | — |
| Force replace | 1d | — | 4b |
| Version compatibility | — | 2c | — |
| Missing/invalid config | — | 2d, 2e | — |
| Env var fallback | — | 2f | — |
| HTTPS | — | 2g | — |
| Dry-run | — | 2h | — |
| Custom image/container | — | — | 3c |
| Server list | 4a | 4a | 4a |