Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 83 additions & 90 deletions tests/e2e/smoke-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
# ./smoke-test.sh [--verbose|-v]
#
# Environment Variables:
# C8_WAIT_TIME - Default wait time in seconds after state-changing commands (default: 1)
# Example: C8_WAIT_TIME=2 ./smoke-test.sh
# C8_TIMEOUT - Max seconds to poll for state propagation (default: 30)
# Example: C8_TIMEOUT=60 ./smoke-test.sh

set -euo pipefail

Expand Down Expand Up @@ -43,32 +43,45 @@ TESTS_FAILED=0
# CLI command
C8="node src/index.ts"

# Default wait time after commands that modify state (in seconds)
C8_WAIT_TIME=${C8_WAIT_TIME:-1}
# Max seconds to poll for state to propagate
C8_TIMEOUT=${C8_TIMEOUT:-30}

# Wrapper function for C8 commands that need time to propagate
# Usage: c8_cmd [wait_time] command args...
# If first arg is a number, use it as wait time, otherwise use default
# Use wait_time=0 for read-only commands (list, get, search) to skip waiting
c8_cmd() {
local wait_time="$C8_WAIT_TIME"

# Check if first argument is a number (custom wait time)
if [[ "$1" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
wait_time="$1"
shift
fi

# Execute the command
$C8 "$@"
local exit_code=$?

# Wait for state to propagate if command succeeded
if [ $exit_code -eq 0 ] && [ "$wait_time" != "0" ]; then
sleep "$wait_time"
fi

return $exit_code
# Poll until command output matches pattern or timeout is reached.
# Usage: poll_until <timeout> <pattern> <cmd> [args...]
# Echoes final matching output and returns 0 on success, returns 1 on timeout.
poll_until() {
local timeout="$1" pattern="$2"
shift 2
local interval=1 elapsed=0 output
while [ "$elapsed" -lt "$timeout" ]; do
output=$("$@" 2>&1) || true
if echo "$output" | grep -qE "$pattern"; then
printf '%s\n' "$output"
return 0
fi
sleep "$interval"
elapsed=$((elapsed + interval))
done
return 1
}

# Poll until command output no longer matches pattern or timeout is reached.
# Usage: poll_until_absent <timeout> <pattern> <cmd> [args...]
# Echoes final output and returns 0 on success, returns 1 on timeout.
poll_until_absent() {
local timeout="$1" pattern="$2"
shift 2
local interval=1 elapsed=0 output
while [ "$elapsed" -lt "$timeout" ]; do
output=$("$@" 2>&1) || true
if ! echo "$output" | grep -qE "$pattern"; then
printf '%s\n' "$output"
return 0
fi
sleep "$interval"
elapsed=$((elapsed + interval))
done
return 1
}

echo "🚀 Starting c8ctl E2E Smoke Tests"
Expand Down Expand Up @@ -107,11 +120,6 @@ debug_output() {
fi
}

test_pass() {
TESTS_PASSED=$((TESTS_PASSED + 1))
echo -e "${GREEN}✓ PASS${NC}"
}

cleanup_session() {
# Clean session state between tests
local config_dir="${XDG_CONFIG_HOME:-$HOME/.config}/c8ctl"
Expand All @@ -122,7 +130,7 @@ cleanup_session() {

# Test 1: Help command
test_start "help command works"
if OUTPUT=$(c8_cmd 0 help 2>&1); then
if OUTPUT=$($C8 help 2>&1); then
debug_output "$OUTPUT"
if echo "$OUTPUT" | grep -q "c8ctl - Camunda 8 CLI"; then
test_pass
Expand All @@ -136,26 +144,23 @@ fi
# Test 2: Deploy a process
test_start "deploy process"
cleanup_session
if OUTPUT=$(c8_cmd deploy tests/fixtures/simple.bpmn 2>&1); then
if OUTPUT=$($C8 deploy tests/fixtures/simple.bpmn 2>&1); then
debug_output "$OUTPUT"
if echo "$OUTPUT" | grep -q "Deployment successful"; then
# Extract process definition key from the output table (last column before the end)
PROCESS_KEY=$(echo "$OUTPUT" | grep "simple-process" | awk '{print $NF}')

# List process definitions to verify deployment (wait time handled by c8_cmd)
if LIST_PD=$(c8_cmd 0 list pd 2>&1); then
# Poll until process definition appears in list
if LIST_PD=$(poll_until "$C8_TIMEOUT" "simple-process" $C8 list pd); then
debug_output "$LIST_PD"
# Verify the process ID appears
if ! echo "$LIST_PD" | grep -q "simple-process"; then
test_fail "process ID 'simple-process' not found in list pd"
# Verify the process definition key appears
elif [ -n "$PROCESS_KEY" ] && ! echo "$LIST_PD" | grep -q "$PROCESS_KEY"; then
# Verify the process definition key also appears
if [ -n "$PROCESS_KEY" ] && ! echo "$LIST_PD" | grep -q "$PROCESS_KEY"; then
test_fail "process key $PROCESS_KEY not found in list pd"
else
test_pass
fi
else
test_fail "list pd command failed after deploy"
test_fail "process ID 'simple-process' not found in list pd after ${C8_TIMEOUT}s"
fi
else
test_fail "deploy succeeded but no success message"
Expand All @@ -167,7 +172,7 @@ fi
# Test 3: Create process instance
test_start "create process instance"
cleanup_session
if OUTPUT=$(c8_cmd create pi --id=simple-process 2>&1); then
if OUTPUT=$($C8 create pi --id=simple-process 2>&1); then
debug_output "$OUTPUT"
if echo "$OUTPUT" | grep -q "✓ Process instance created \[Key:"; then
test_pass
Expand All @@ -181,7 +186,7 @@ fi
# Test 4: Run command and list process instances
test_start "run command and list process instances"
cleanup_session
if RUN_OUTPUT=$(c8_cmd run tests/fixtures/simple-timer-event.bpmn 2>&1); then
if RUN_OUTPUT=$($C8 run tests/fixtures/simple-timer-event.bpmn 2>&1); then
debug_output "$RUN_OUTPUT"
# Check for both deployment and instance creation messages
if ! echo "$RUN_OUTPUT" | grep -q "✓ Deployment successful \[Key:"; then
Expand All @@ -195,16 +200,12 @@ if RUN_OUTPUT=$(c8_cmd run tests/fixtures/simple-timer-event.bpmn 2>&1); then
if [ -z "$INSTANCE_KEY" ]; then
test_fail "could not extract instance key from run output"
else
# Verify the instance key appears in list pi (wait time handled by c8_cmd)
if LIST_OUTPUT=$(c8_cmd 0 list pi 2>&1); then
# Poll until the instance key appears in list pi
if LIST_OUTPUT=$(poll_until "$C8_TIMEOUT" "$INSTANCE_KEY" $C8 list pi); then
debug_output "$LIST_OUTPUT"
if echo "$LIST_OUTPUT" | grep -q "$INSTANCE_KEY"; then
test_pass
else
test_fail "instance key $INSTANCE_KEY not found in list pi"
fi
test_pass
else
test_fail "list pi command failed"
test_fail "instance key $INSTANCE_KEY not found in list pi after ${C8_TIMEOUT}s"
fi
fi
fi
Expand All @@ -215,7 +216,7 @@ fi
# Test 5: Get topology
test_start "get topology"
cleanup_session
if OUTPUT=$(c8_cmd 0 get topology 2>&1); then
if OUTPUT=$($C8 get topology 2>&1); then
debug_output "$OUTPUT"
# Verify topology output contains broker information and cluster ID
if ! echo "$OUTPUT" | grep -q "brokers"; then
Expand All @@ -233,43 +234,39 @@ fi
test_start "user task completion"
cleanup_session
# Run process with user task
if RUN_OUTPUT=$(c8_cmd run tests/fixtures/simple-user-task.bpmn 2>&1); then
if RUN_OUTPUT=$($C8 run tests/fixtures/simple-user-task.bpmn 2>&1); then
debug_output "$RUN_OUTPUT"
if ! echo "$RUN_OUTPUT" | grep -q "Process instance created"; then
test_fail "failed to create process instance with user task"
else
# List user tasks and extract the key (wait time handled by c8_cmd)
if LIST_UT=$(c8_cmd 0 list ut 2>&1); then
# Poll until a user task key (leading digits) appears in list ut
if LIST_UT=$(poll_until "$C8_TIMEOUT" "^[0-9]" $C8 list ut); then
debug_output "$LIST_UT"
UT_KEY=$(echo "$LIST_UT" | grep -v "^Key\|^---\|^No user" | awk 'NF {print $1}' | head -n1)

if [ -z "$UT_KEY" ]; then
test_fail "no user task found after running process"
else
# Complete the user task
if COMPLETE_OUTPUT=$(c8_cmd complete ut "$UT_KEY" 2>&1); then
if COMPLETE_OUTPUT=$($C8 complete ut "$UT_KEY" 2>&1); then
debug_output "$COMPLETE_OUTPUT"
if ! echo "$COMPLETE_OUTPUT" | grep -q "completed"; then
test_fail "complete output doesn't contain 'completed'"
else
# Verify user task is no longer in the list
if LIST_UT_AFTER=$(c8_cmd 0 list ut 2>&1); then
# Poll until user task key is no longer in the list
if LIST_UT_AFTER=$(poll_until_absent "$C8_TIMEOUT" "$UT_KEY" $C8 list ut); then
debug_output "$LIST_UT_AFTER"
if echo "$LIST_UT_AFTER" | grep -q "$UT_KEY"; then
test_fail "user task $UT_KEY still in list after completion"
else
test_pass
fi
test_pass
else
test_fail "list ut failed after completion"
test_fail "user task $UT_KEY still in list after ${C8_TIMEOUT}s"
fi
fi
else
test_fail "failed to complete user task $UT_KEY"
fi
fi
else
test_fail "list ut command failed"
test_fail "no user task appeared in list ut after ${C8_TIMEOUT}s"
fi
fi
else
Expand All @@ -279,44 +276,40 @@ fi
# Test 7: Message correlation
test_start "message correlation"
cleanup_session
# Deploy process with c8_cmd for automatic wait
if ! c8_cmd deploy tests/fixtures/simple-message-correlation.bpmn > /dev/null 2>&1; then
# Deploy process for message correlation
if ! $C8 deploy tests/fixtures/simple-message-correlation.bpmn > /dev/null 2>&1; then
test_fail "failed to deploy message correlation process"
else
# Create instance with variables
if CREATE_OUTPUT=$(c8_cmd create pi --id=simple-message-correlation --variables='{"orderId":"1a"}' 2>&1); then
if CREATE_OUTPUT=$($C8 create pi --id=simple-message-correlation --variables='{"orderId":"1a"}' 2>&1); then
debug_output "$CREATE_OUTPUT"
# Extract instance key
INSTANCE_KEY=$(echo "$CREATE_OUTPUT" | grep "Process instance created" | grep -o '\[Key: [0-9]*\]' | grep -o '[0-9]*')

if [ -z "$INSTANCE_KEY" ]; then
test_fail "could not extract instance key"
else
# Verify instance exists and is active
if LIST_PI=$(c8_cmd 0 list pi 2>&1); then
# Poll until the instance appears and is ACTIVE
if LIST_PI=$(poll_until "$C8_TIMEOUT" "$INSTANCE_KEY" $C8 list pi); then
debug_output "$LIST_PI"
if ! echo "$LIST_PI" | grep "$INSTANCE_KEY" | grep -q "ACTIVE"; then
test_fail "instance $INSTANCE_KEY not found or not active"
test_fail "instance $INSTANCE_KEY found but not active"
else
# Publish message with correlation key (use longer wait time for message correlation)
if ! c8_cmd 2 publish msg "msg_1" --correlationKey=1a > /dev/null 2>&1; then
# Publish message to correlate
if ! $C8 publish msg "msg_1" --correlationKey=1a > /dev/null 2>&1; then
test_fail "failed to publish message"
else
# Verify instance is completed (no longer in active list)
if LIST_PI_AFTER=$(c8_cmd 0 list pi 2>&1); then
# Poll until instance is no longer ACTIVE
if LIST_PI_AFTER=$(poll_until_absent "$C8_TIMEOUT" "${INSTANCE_KEY}.*ACTIVE" $C8 list pi); then
debug_output "$LIST_PI_AFTER"
if echo "$LIST_PI_AFTER" | grep "$INSTANCE_KEY" | grep -q "ACTIVE"; then
test_fail "instance $INSTANCE_KEY still active after message"
else
test_pass
fi
test_pass
else
test_fail "list pi failed after message"
test_fail "instance $INSTANCE_KEY still active after ${C8_TIMEOUT}s"
fi
fi
fi
else
test_fail "list pi command failed"
test_fail "instance $INSTANCE_KEY not found in list pi after ${C8_TIMEOUT}s"
fi
fi
else
Expand All @@ -328,20 +321,20 @@ fi
test_start "search process definitions"
cleanup_session
# Search for process definitions deployed in previous tests
if SEARCH_OUTPUT=$(c8_cmd 0 search pd --bpmnProcessId=simple-user-task 2>&1); then
if SEARCH_OUTPUT=$($C8 search pd --bpmnProcessId=simple-user-task 2>&1); then
debug_output "$SEARCH_OUTPUT"
# Verify the deployed process definition appears in search results
if ! echo "$SEARCH_OUTPUT" | grep -q "simple-user-task"; then
test_fail "bpmnProcessId 'simple-user-task' not found in search results"
else
# Test search with wildcard
if WILDCARD_OUTPUT=$(c8_cmd 0 search pd --name='*Message*' 2>&1); then
if WILDCARD_OUTPUT=$($C8 search pd --name='*Message*' 2>&1); then
debug_output "$WILDCARD_OUTPUT"
if ! echo "$WILDCARD_OUTPUT" | grep -q "Message"; then
test_fail "wildcard search --name='*Message*' found no results"
else
# Test search by exact name
if NAME_OUTPUT=$(c8_cmd 0 search pd --name='Simple User Task*' 2>&1); then
if NAME_OUTPUT=$($C8 search pd --name='Simple User Task*' 2>&1); then
debug_output "$NAME_OUTPUT"
if ! echo "$NAME_OUTPUT" | grep -q "simple-user-task"; then
test_fail "search by name 'Simple User Task' found no results"
Expand All @@ -364,27 +357,27 @@ fi
test_start "profile management"
cleanup_session
# Step 1: Create the profile
if ADD_OUTPUT=$(c8_cmd add profile prod --baseUrl=https://camunda.example.com --clientId=xxx --clientSecret=yyy 2>&1); then
if ADD_OUTPUT=$($C8 add profile prod --baseUrl=https://camunda.example.com --clientId=xxx --clientSecret=yyy 2>&1); then
debug_output "$ADD_OUTPUT"
if ! echo "$ADD_OUTPUT" | grep -q "Profile 'prod' added"; then
test_fail "expected success message for profile addition"
else
# Step 2: Validate the existence of the profile
if LIST_OUTPUT=$(c8_cmd 0 list profiles 2>&1); then
if LIST_OUTPUT=$($C8 list profiles 2>&1); then
debug_output "$LIST_OUTPUT"
if ! echo "$LIST_OUTPUT" | grep -q "prod"; then
test_fail "profile 'prod' not found in list after creation"
elif ! echo "$LIST_OUTPUT" | grep -q "https://camunda.example.com"; then
test_fail "base URL not found in profile list"
else
# Step 3: Delete the profile
if REMOVE_OUTPUT=$(c8_cmd remove profile prod 2>&1); then
if REMOVE_OUTPUT=$($C8 remove profile prod 2>&1); then
debug_output "$REMOVE_OUTPUT"
if ! echo "$REMOVE_OUTPUT" | grep -q "Profile 'prod' removed"; then
test_fail "expected success message for profile removal"
else
# Step 4: Evaluate the deleted list
if LIST_AFTER=$(c8_cmd 0 list profiles 2>&1); then
if LIST_AFTER=$($C8 list profiles 2>&1); then
debug_output "$LIST_AFTER"
if echo "$LIST_AFTER" | grep -q "prod"; then
test_fail "profile 'prod' still appears in list after deletion"
Expand Down