@@ -164,6 +164,21 @@ echo "$broker_features" | grep -q "wildcards" && has_wildcards=yes
164164echo " $broker_features " | grep -q " insecure" && has_insecure=yes
165165echo " $broker_features " | grep -q " tls" && has_tls=yes
166166echo " $broker_features " | grep -q " persist" && has_persist=yes
167+ has_persist_encrypt=no
168+ echo " $broker_features " | grep -q " persist-encrypt" && \
169+ has_persist_encrypt=yes
170+ has_static_memory=no
171+ echo " $broker_features " | grep -q " static-memory" && \
172+ has_static_memory=yes
173+
174+ # Persist-encrypt builds refuse to start without an explicit key source.
175+ # CLI tests opt into the development key with -E dev (NOT for production
176+ # - the key is a fixed pattern in the binary). For non-encrypt builds
177+ # this stays empty so the unknown -E option doesn't trigger usage.
178+ broker_dir_flags=" "
179+ if [ " $has_persist_encrypt " = " yes" ]; then
180+ broker_dir_flags=" -E dev"
181+ fi
167182
168183# Determine if plain (non-TLS) tests can run
169184skip_plain=no
@@ -1182,7 +1197,7 @@ if [ $broker_pid != $no_pid ]; then
11821197fi
11831198generate_port
11841199broker_log=" ${TMP_DIR} /t27_broker1.log"
1185- ./$broker_bin -p $port -D " $T27_DIR " > " $broker_log " 2>&1 &
1200+ ./$broker_bin -p $port -D " $T27_DIR " $broker_dir_flags > " $broker_log " 2>&1 &
11861201broker_pid=$!
11871202check_broker
11881203# Retain a message
@@ -1195,7 +1210,7 @@ wait $broker_pid 2>/dev/null || true
11951210broker_pid=$no_pid
11961211# Restart against same dir
11971212broker_log=" ${TMP_DIR} /t27_broker2.log"
1198- ./$broker_bin -p $port -D " $T27_DIR " > " $broker_log " 2>&1 &
1213+ ./$broker_bin -p $port -D " $T27_DIR " $broker_dir_flags > " $broker_log " 2>&1 &
11991214broker_pid=$!
12001215check_broker
12011216# Confirm restore line printed (defense in depth: subscriber confirms anyway)
@@ -1256,7 +1271,7 @@ if [ $broker_pid != $no_pid ]; then
12561271fi
12571272generate_port
12581273broker_log=" ${TMP_DIR} /t28_broker.log"
1259- ./$broker_bin -p $port -D " $T28_DIR " > " $broker_log " 2>&1 &
1274+ ./$broker_bin -p $port -D " $T28_DIR " $broker_dir_flags > " $broker_log " 2>&1 &
12601275broker_pid=$!
12611276check_broker
12621277T28_WIPED=no
@@ -1283,6 +1298,8 @@ if [ "$skip_plain" = "yes" ]; then
12831298 echo " SKIP: Offline queue (plain listener disabled)"
12841299elif [ " $has_persist " = " no" ]; then
12851300 echo " SKIP: Offline queue (built without --enable-broker-persist)"
1301+ elif [ " $has_static_memory " = " yes" ]; then
1302+ echo " SKIP: Offline queue (orphan/outbound-queue is dynamic-memory only)"
12861303else
12871304T29_DIR=" ${TMP_DIR} /persist_t29"
12881305mkdir -p " $T29_DIR "
@@ -1293,7 +1310,7 @@ if [ $broker_pid != $no_pid ]; then
12931310fi
12941311generate_port
12951312broker_log=" ${TMP_DIR} /t29_broker.log"
1296- ./$broker_bin -p $port -D " $T29_DIR " > " $broker_log " 2>&1 &
1313+ ./$broker_bin -p $port -D " $T29_DIR " $broker_dir_flags > " $broker_log " 2>&1 &
12971314broker_pid=$!
12981315check_broker
12991316# 1. Persistent sub connects, subscribes; SIGKILL to disconnect
@@ -1319,8 +1336,12 @@ for t29_i in 1 2 3; do
13191336done
13201337sleep 0.5
13211338# 3. Reconnect with same client_id + clean_session=0; receive backlog.
1339+ # Use a generous cmd_timeout_ms (-C 5000) so the client's CONNACK wait
1340+ # survives the orphan-reassociate + reclaim path; 3 ms races on slow
1341+ # CI runners (broker writes CONNACK after client has already closed,
1342+ # leaving the drained PUBLISHes to fail with EPIPE).
13221343timeout 8 ./$sub_bin -T -h 127.0.0.1 -p $port -n " test/offlineq" -q 1 \
1323- -i " t29_sub" -s -x -C 3 -R " ${TMP_DIR} /t29_sub.ready" \
1344+ -i " t29_sub" -s -x -C 5000 -R " ${TMP_DIR} /t29_sub.ready" \
13241345 > " ${TMP_DIR} /t29_sub.log" 2>&1 &
13251346T29_PID=$!
13261347TEST_PIDS+=($T29_PID )
@@ -1348,6 +1369,8 @@ if [ "$skip_plain" = "yes" ]; then
13481369 echo " SKIP: Offline queue restart (plain listener disabled)"
13491370elif [ " $has_persist " = " no" ]; then
13501371 echo " SKIP: Offline queue restart (built without --enable-broker-persist)"
1372+ elif [ " $has_static_memory " = " yes" ]; then
1373+ echo " SKIP: Offline queue restart (orphan/outbound-queue is dynamic-memory only)"
13511374else
13521375T30_DIR=" ${TMP_DIR} /persist_t30"
13531376mkdir -p " $T30_DIR "
@@ -1358,7 +1381,7 @@ if [ $broker_pid != $no_pid ]; then
13581381fi
13591382generate_port
13601383broker_log=" ${TMP_DIR} /t30_broker1.log"
1361- ./$broker_bin -p $port -D " $T30_DIR " > " $broker_log " 2>&1 &
1384+ ./$broker_bin -p $port -D " $T30_DIR " $broker_dir_flags > " $broker_log " 2>&1 &
13621385broker_pid=$!
13631386check_broker
13641387rm -f " ${TMP_DIR} /t30_first.ready"
@@ -1384,14 +1407,16 @@ kill $broker_pid 2>/dev/null
13841407wait $broker_pid 2> /dev/null || true
13851408broker_pid=$no_pid
13861409broker_log=" ${TMP_DIR} /t30_broker2.log"
1387- ./$broker_bin -p $port -D " $T30_DIR " > " $broker_log " 2>&1 &
1410+ ./$broker_bin -p $port -D " $T30_DIR " $broker_dir_flags > " $broker_log " 2>&1 &
13881411broker_pid=$!
13891412check_broker
13901413T30_REPLAY=no
13911414grep -q " persist restore outq loaded=3" " $broker_log " 2> /dev/null \
13921415 && T30_REPLAY=yes
1416+ # Same -C 5000 rationale as Test 29; the restored-from-disk path is
1417+ # even more sensitive to a short client timeout.
13931418timeout 8 ./$sub_bin -T -h 127.0.0.1 -p $port -n " test/restartq" -q 1 \
1394- -i " t30_sub" -s -x -C 3 -R " ${TMP_DIR} /t30_sub.ready" \
1419+ -i " t30_sub" -s -x -C 5000 -R " ${TMP_DIR} /t30_sub.ready" \
13951420 > " ${TMP_DIR} /t30_sub.log" 2>&1 &
13961421T30_PID=$!
13971422TEST_PIDS+=($T30_PID )
@@ -1416,9 +1441,7 @@ fi # has_persist (t30)
14161441# plaintext payload string; round-trip must still work end-to-end.
14171442echo " "
14181443echo " --- Test 31: AES-GCM encrypted persist round-trip ---"
1419- has_persist_encrypt=no
1420- echo " $broker_features " | grep -q " persist-encrypt" && \
1421- has_persist_encrypt=yes
1444+ # has_persist_encrypt was detected at startup.
14221445if [ " $skip_plain " = " yes" ]; then
14231446 echo " SKIP: AES-GCM persist (plain listener disabled)"
14241447elif [ " $has_persist_encrypt " = " no" ]; then
@@ -1435,7 +1458,10 @@ if [ $broker_pid != $no_pid ]; then
14351458fi
14361459generate_port
14371460broker_log=" ${TMP_DIR} /t31_broker1.log"
1438- ./$broker_bin -p $port -D " $T31_DIR " > " $broker_log " 2>&1 &
1461+ # -E dev opts into the development hard-coded key. Production builds
1462+ # install MqttBrokerPersistHooks.derive_key instead and never reach
1463+ # this flag.
1464+ ./$broker_bin -p $port -D " $T31_DIR " -E dev > " $broker_log " 2>&1 &
14391465broker_pid=$!
14401466check_broker
14411467./$pub_bin -T -h 127.0.0.1 -p $port -n " test/secret_t31" \
@@ -1451,7 +1477,7 @@ kill $broker_pid 2>/dev/null
14511477wait $broker_pid 2> /dev/null || true
14521478broker_pid=$no_pid
14531479broker_log=" ${TMP_DIR} /t31_broker2.log"
1454- ./$broker_bin -p $port -D " $T31_DIR " > " $broker_log " 2>&1 &
1480+ ./$broker_bin -p $port -D " $T31_DIR " -E dev > " $broker_log " 2>&1 &
14551481broker_pid=$!
14561482check_broker
14571483rm -f " ${TMP_DIR} /t31_sub.ready"
@@ -1483,15 +1509,14 @@ fi # has_persist_encrypt
14831509# disappear after the broker comes up.
14841510echo " "
14851511echo " --- Test 32: Schema mismatch wipes every namespace ---"
1486- t32_persist_encrypt=no
1487- echo " $broker_features " | grep -q " persist-encrypt" && \
1488- t32_persist_encrypt=yes
14891512if [ " $skip_plain " = " yes" ]; then
14901513 echo " SKIP: Schema wipe full (plain listener disabled)"
14911514elif [ " $has_persist " = " no" ]; then
14921515 echo " SKIP: Schema wipe full (built without --enable-broker-persist)"
1493- elif [ " $t32_persist_encrypt " = " yes" ]; then
1516+ elif [ " $has_persist_encrypt " = " yes" ]; then
14941517 echo " SKIP: Schema wipe full (encrypted build - exercised by plaintext matrix entry)"
1518+ elif [ " $has_static_memory " = " yes" ]; then
1519+ echo " SKIP: Schema wipe full (active wipe skipped in static-memory mode by design)"
14951520else
14961521T32_DIR=" ${TMP_DIR} /persist_t32"
14971522rm -rf " $T32_DIR "
@@ -1511,7 +1536,7 @@ if [ $broker_pid != $no_pid ]; then
15111536fi
15121537generate_port
15131538broker_log=" ${TMP_DIR} /t32_broker.log"
1514- ./$broker_bin -p $port -D " $T32_DIR " > " $broker_log " 2>&1 &
1539+ ./$broker_bin -p $port -D " $T32_DIR " $broker_dir_flags > " $broker_log " 2>&1 &
15151540broker_pid=$!
15161541check_broker
15171542# After wipe-and-restart only the fresh META record should remain.
0 commit comments