@@ -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
@@ -1180,7 +1195,7 @@ if [ $broker_pid != $no_pid ]; then
11801195fi
11811196generate_port
11821197broker_log=" ${TMP_DIR} /t27_broker1.log"
1183- ./$broker_bin -p $port -D " $T27_DIR " > " $broker_log " 2>&1 &
1198+ ./$broker_bin -p $port -D " $T27_DIR " $broker_dir_flags > " $broker_log " 2>&1 &
11841199broker_pid=$!
11851200check_broker
11861201# Retain a message
@@ -1193,7 +1208,7 @@ wait $broker_pid 2>/dev/null || true
11931208broker_pid=$no_pid
11941209# Restart against same dir
11951210broker_log=" ${TMP_DIR} /t27_broker2.log"
1196- ./$broker_bin -p $port -D " $T27_DIR " > " $broker_log " 2>&1 &
1211+ ./$broker_bin -p $port -D " $T27_DIR " $broker_dir_flags > " $broker_log " 2>&1 &
11971212broker_pid=$!
11981213check_broker
11991214# Confirm restore line printed (defense in depth: subscriber confirms anyway)
@@ -1254,7 +1269,7 @@ if [ $broker_pid != $no_pid ]; then
12541269fi
12551270generate_port
12561271broker_log=" ${TMP_DIR} /t28_broker.log"
1257- ./$broker_bin -p $port -D " $T28_DIR " > " $broker_log " 2>&1 &
1272+ ./$broker_bin -p $port -D " $T28_DIR " $broker_dir_flags > " $broker_log " 2>&1 &
12581273broker_pid=$!
12591274check_broker
12601275T28_WIPED=no
@@ -1281,6 +1296,8 @@ if [ "$skip_plain" = "yes" ]; then
12811296 echo " SKIP: Offline queue (plain listener disabled)"
12821297elif [ " $has_persist " = " no" ]; then
12831298 echo " SKIP: Offline queue (built without --enable-broker-persist)"
1299+ elif [ " $has_static_memory " = " yes" ]; then
1300+ echo " SKIP: Offline queue (orphan/outbound-queue is dynamic-memory only)"
12841301else
12851302T29_DIR=" ${TMP_DIR} /persist_t29"
12861303mkdir -p " $T29_DIR "
@@ -1291,7 +1308,7 @@ if [ $broker_pid != $no_pid ]; then
12911308fi
12921309generate_port
12931310broker_log=" ${TMP_DIR} /t29_broker.log"
1294- ./$broker_bin -p $port -D " $T29_DIR " > " $broker_log " 2>&1 &
1311+ ./$broker_bin -p $port -D " $T29_DIR " $broker_dir_flags > " $broker_log " 2>&1 &
12951312broker_pid=$!
12961313check_broker
12971314# 1. Persistent sub connects, subscribes; SIGKILL to disconnect
@@ -1317,8 +1334,12 @@ for t29_i in 1 2 3; do
13171334done
13181335sleep 0.5
13191336# 3. Reconnect with same client_id + clean_session=0; receive backlog.
1337+ # Use a generous cmd_timeout_ms (-C 5000) so the client's CONNACK wait
1338+ # survives the orphan-reassociate + reclaim path; 3 ms races on slow
1339+ # CI runners (broker writes CONNACK after client has already closed,
1340+ # leaving the drained PUBLISHes to fail with EPIPE).
13201341timeout 8 ./$sub_bin -T -h 127.0.0.1 -p $port -n " test/offlineq" -q 1 \
1321- -i " t29_sub" -s -x -C 3 -R " ${TMP_DIR} /t29_sub.ready" \
1342+ -i " t29_sub" -s -x -C 5000 -R " ${TMP_DIR} /t29_sub.ready" \
13221343 > " ${TMP_DIR} /t29_sub.log" 2>&1 &
13231344T29_PID=$!
13241345TEST_PIDS+=($T29_PID )
@@ -1346,6 +1367,8 @@ if [ "$skip_plain" = "yes" ]; then
13461367 echo " SKIP: Offline queue restart (plain listener disabled)"
13471368elif [ " $has_persist " = " no" ]; then
13481369 echo " SKIP: Offline queue restart (built without --enable-broker-persist)"
1370+ elif [ " $has_static_memory " = " yes" ]; then
1371+ echo " SKIP: Offline queue restart (orphan/outbound-queue is dynamic-memory only)"
13491372else
13501373T30_DIR=" ${TMP_DIR} /persist_t30"
13511374mkdir -p " $T30_DIR "
@@ -1356,7 +1379,7 @@ if [ $broker_pid != $no_pid ]; then
13561379fi
13571380generate_port
13581381broker_log=" ${TMP_DIR} /t30_broker1.log"
1359- ./$broker_bin -p $port -D " $T30_DIR " > " $broker_log " 2>&1 &
1382+ ./$broker_bin -p $port -D " $T30_DIR " $broker_dir_flags > " $broker_log " 2>&1 &
13601383broker_pid=$!
13611384check_broker
13621385rm -f " ${TMP_DIR} /t30_first.ready"
@@ -1382,14 +1405,16 @@ kill $broker_pid 2>/dev/null
13821405wait $broker_pid 2> /dev/null || true
13831406broker_pid=$no_pid
13841407broker_log=" ${TMP_DIR} /t30_broker2.log"
1385- ./$broker_bin -p $port -D " $T30_DIR " > " $broker_log " 2>&1 &
1408+ ./$broker_bin -p $port -D " $T30_DIR " $broker_dir_flags > " $broker_log " 2>&1 &
13861409broker_pid=$!
13871410check_broker
13881411T30_REPLAY=no
13891412grep -q " persist restore outq loaded=3" " $broker_log " 2> /dev/null \
13901413 && T30_REPLAY=yes
1414+ # Same -C 5000 rationale as Test 29; the restored-from-disk path is
1415+ # even more sensitive to a short client timeout.
13911416timeout 8 ./$sub_bin -T -h 127.0.0.1 -p $port -n " test/restartq" -q 1 \
1392- -i " t30_sub" -s -x -C 3 -R " ${TMP_DIR} /t30_sub.ready" \
1417+ -i " t30_sub" -s -x -C 5000 -R " ${TMP_DIR} /t30_sub.ready" \
13931418 > " ${TMP_DIR} /t30_sub.log" 2>&1 &
13941419T30_PID=$!
13951420TEST_PIDS+=($T30_PID )
@@ -1414,9 +1439,7 @@ fi # has_persist (t30)
14141439# plaintext payload string; round-trip must still work end-to-end.
14151440echo " "
14161441echo " --- Test 31: AES-GCM encrypted persist round-trip ---"
1417- has_persist_encrypt=no
1418- echo " $broker_features " | grep -q " persist-encrypt" && \
1419- has_persist_encrypt=yes
1442+ # has_persist_encrypt was detected at startup.
14201443if [ " $skip_plain " = " yes" ]; then
14211444 echo " SKIP: AES-GCM persist (plain listener disabled)"
14221445elif [ " $has_persist_encrypt " = " no" ]; then
@@ -1433,7 +1456,10 @@ if [ $broker_pid != $no_pid ]; then
14331456fi
14341457generate_port
14351458broker_log=" ${TMP_DIR} /t31_broker1.log"
1436- ./$broker_bin -p $port -D " $T31_DIR " > " $broker_log " 2>&1 &
1459+ # -E dev opts into the development hard-coded key. Production builds
1460+ # install MqttBrokerPersistHooks.derive_key instead and never reach
1461+ # this flag.
1462+ ./$broker_bin -p $port -D " $T31_DIR " -E dev > " $broker_log " 2>&1 &
14371463broker_pid=$!
14381464check_broker
14391465./$pub_bin -T -h 127.0.0.1 -p $port -n " test/secret_t31" \
@@ -1449,7 +1475,7 @@ kill $broker_pid 2>/dev/null
14491475wait $broker_pid 2> /dev/null || true
14501476broker_pid=$no_pid
14511477broker_log=" ${TMP_DIR} /t31_broker2.log"
1452- ./$broker_bin -p $port -D " $T31_DIR " > " $broker_log " 2>&1 &
1478+ ./$broker_bin -p $port -D " $T31_DIR " -E dev > " $broker_log " 2>&1 &
14531479broker_pid=$!
14541480check_broker
14551481rm -f " ${TMP_DIR} /t31_sub.ready"
@@ -1481,15 +1507,14 @@ fi # has_persist_encrypt
14811507# disappear after the broker comes up.
14821508echo " "
14831509echo " --- Test 32: Schema mismatch wipes every namespace ---"
1484- t32_persist_encrypt=no
1485- echo " $broker_features " | grep -q " persist-encrypt" && \
1486- t32_persist_encrypt=yes
14871510if [ " $skip_plain " = " yes" ]; then
14881511 echo " SKIP: Schema wipe full (plain listener disabled)"
14891512elif [ " $has_persist " = " no" ]; then
14901513 echo " SKIP: Schema wipe full (built without --enable-broker-persist)"
1491- elif [ " $t32_persist_encrypt " = " yes" ]; then
1514+ elif [ " $has_persist_encrypt " = " yes" ]; then
14921515 echo " SKIP: Schema wipe full (encrypted build - exercised by plaintext matrix entry)"
1516+ elif [ " $has_static_memory " = " yes" ]; then
1517+ echo " SKIP: Schema wipe full (active wipe skipped in static-memory mode by design)"
14931518else
14941519T32_DIR=" ${TMP_DIR} /persist_t32"
14951520rm -rf " $T32_DIR "
@@ -1509,7 +1534,7 @@ if [ $broker_pid != $no_pid ]; then
15091534fi
15101535generate_port
15111536broker_log=" ${TMP_DIR} /t32_broker.log"
1512- ./$broker_bin -p $port -D " $T32_DIR " > " $broker_log " 2>&1 &
1537+ ./$broker_bin -p $port -D " $T32_DIR " $broker_dir_flags > " $broker_log " 2>&1 &
15131538broker_pid=$!
15141539check_broker
15151540# After wipe-and-restart only the fresh META record should remain.
0 commit comments