test(issue-26): no test depends on a third-party MQTT broker

- tests/_local_mqtt.py: in-process MQTT 3.1.1 broker on 127.0.0.1 (what
  the repo uses: protocol level 4, clean session, QoS 0/1, retained).
- conftest: one session broker named by MQTT_BROKER/MQTT_PORT/MQTT_TLS;
  other redirecting/auth MQTT_* dropped and restored afterwards.
- Harnesses of the 22 broker-dependent tests (#18 acceptance1/2/3/5,
  #6 t1_1/2/7/8/14/15/16/20, #19 MQTT loop x2, #33 b3/r3/b7, #30
  s9/s10/r2) use it; the "broker unreachable" skips are gone (a local
  broker that does not deliver is a failure). acceptance1/5 and #19 also
  assert on the subscriber, runner and audit logs the real producers write.
- tests/test_local_mqtt.py: conformance with the real clients and the real
  publish_event -> job_subscriber path (C0), an AST guard against public
  broker literals and MQTT_* deleted without a replacement (C2), and the
  session's broker config (C3).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
GodopuandClaude Opus 5.5 committed 2026-09-30 15:54:58 +00:00
1 parent 80dc2eb45e
commit 2826e709ae
8 files changed
+656 -49

No files matched your search

+32
View File
@@ -1550,3 +1550,35 @@ def delegation_tree_provenance_guard(tmp_path_factory):
"(these would shadow the real tree for any later first-time import):\n "
+ "\n ".join(polluted)
)
# ==============================================================================
# Issue #26: no test reaches a third-party MQTT broker. One in-process broker
# (tests/_local_mqtt.py) per session on 127.0.0.1; MQTT_BROKER/MQTT_PORT/
# MQTT_TLS name it, and every other MQTT_* that would redirect or authenticate
# a client is dropped. Subprocesses inherit it through os.environ; a harness
# that builds its own env takes _local_mqtt.local_broker_env(). Tests that
# deliberately name an unreachable broker (127.0.0.1:9, :65534) still win.
# ==============================================================================
import _local_mqtt # noqa: E402
_MQTT_DROPPED = ("MQTT_HOST", "MQTT_USERNAME", "MQTT_PASSWORD", "MQTT_CA_CERTS", "MQTT_CERTFILE", "MQTT_KEYFILE")
@pytest.fixture(scope="session", autouse=True)
def local_mqtt_broker():
broker = _local_mqtt.start_broker()
keys = tuple(broker.env()) + _MQTT_DROPPED
previous = {k: os.environ.get(k) for k in keys}
for k in _MQTT_DROPPED:
os.environ.pop(k, None)
os.environ.update(broker.env())
try:
yield broker
finally:
for k, v in previous.items():
if v is None:
os.environ.pop(k, None)
else:
os.environ[k] = v
_local_mqtt.stop_broker()