2023-07-03 21:02:52 +02:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
|
|
# Test whether a bridge topics work correctly after reconnection.
|
|
|
|
|
# Important point here is that persistence is enabled.
|
|
|
|
|
|
|
|
|
|
from mosq_test_helper import *
|
|
|
|
|
|
2026-03-10 13:21:00 +01:00
|
|
|
mosq_test.require_features(["INC_BRIDGE_SUPPORT"])
|
|
|
|
|
|
2023-07-03 21:02:52 +02:00
|
|
|
def write_config(filename, port1, port2, protocol_version):
|
|
|
|
|
with open(filename, 'w') as f:
|
|
|
|
|
f.write("log_type all\n")
|
|
|
|
|
f.write("listener %d\n" % (port2))
|
2026-04-17 08:56:52 +02:00
|
|
|
f.write(f"plugin {mosq_paths.test_plugin('plugin_evt_persist_client_update')}\n")
|
2023-07-03 21:02:52 +02:00
|
|
|
f.write("allow_anonymous true\n")
|
|
|
|
|
f.write("persistent_client_expiration 1d\n")
|
|
|
|
|
f.write("\n")
|
|
|
|
|
f.write("connection connect_only_bridge\n")
|
2026-04-20 00:57:34 +02:00
|
|
|
f.write("address localhost:%d\n" % (port1))
|
2023-07-03 21:02:52 +02:00
|
|
|
f.write("topic bridge/# out\n")
|
|
|
|
|
f.write("bridge_protocol_version %s\n" % (protocol_version))
|
|
|
|
|
f.write("bridge_max_topic_alias 0\n")
|
|
|
|
|
f.write("cleansession false\n")
|
|
|
|
|
f.write("notification_topic bridge_state\n")
|
|
|
|
|
f.write("restart_timeout 300\n")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def do_test(proto_ver):
|
|
|
|
|
bridge_protocol = "mqttv311" if proto_ver == 4 else "mqttv50"
|
|
|
|
|
|
|
|
|
|
(port1, port2) = mosq_test.get_port(2)
|
|
|
|
|
conf_file = '06-bridge-remote-shutdown.conf'
|
|
|
|
|
write_config(conf_file, port1, port2, bridge_protocol)
|
|
|
|
|
|
|
|
|
|
rc = 1
|
2026-05-04 23:54:48 +02:00
|
|
|
connect_packet = mqtt_packets.gen_connect("test-client", proto_ver=proto_ver)
|
|
|
|
|
connack_packet = mqtt_packets.gen_connack(rc=0, proto_ver=proto_ver)
|
2023-07-03 21:02:52 +02:00
|
|
|
mid = 180
|
2026-05-04 23:54:48 +02:00
|
|
|
subscribe_packet = mqtt_packets.gen_subscribe(mid, "#", 0, proto_ver=proto_ver)
|
|
|
|
|
suback_packet = mqtt_packets.gen_suback(mid, 0, proto_ver=proto_ver)
|
|
|
|
|
publish_packet = mqtt_packets.gen_publish("echo_topic", qos=0, payload="sample-message", proto_ver=proto_ver)
|
|
|
|
|
bridge_up_packet = mqtt_packets.gen_publish("bridge_state", qos=0, payload="1", retain=1, proto_ver=proto_ver)
|
|
|
|
|
bridge_down_packet = mqtt_packets.gen_publish("bridge_state", qos=0, payload="0", retain=0, proto_ver=proto_ver)
|
2023-07-03 21:02:52 +02:00
|
|
|
|
|
|
|
|
remote_broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port1, use_conf=False)
|
|
|
|
|
|
2026-04-17 08:56:52 +02:00
|
|
|
local_cmd = [mosq_paths.mosquitto, '-c', conf_file]
|
2023-07-03 21:02:52 +02:00
|
|
|
local_broker = mosq_test.start_broker(cmd=local_cmd, filename=os.path.basename(__file__)+'_local1', use_conf=False, port=port2)
|
|
|
|
|
|
|
|
|
|
rc1 = None
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
sock = mosq_test.do_client_connect(connect_packet, connack_packet, port=port2)
|
|
|
|
|
sock = mosq_test.do_send_receive(sock, subscribe_packet, suback_packet, "suback")
|
|
|
|
|
|
|
|
|
|
mosq_test.expect_packet(sock, "check for bridge up state", bridge_up_packet)
|
|
|
|
|
|
|
|
|
|
rc1, stde1 = mosq_test.terminate_broker(remote_broker)
|
|
|
|
|
|
|
|
|
|
mosq_test.expect_packet(sock, "wait for bridge down state", bridge_down_packet)
|
|
|
|
|
# If we now get a message published to evt/persist/client/update instead of the expected echo
|
|
|
|
|
# the bridge connection was most likely added to the expiry list
|
|
|
|
|
sock = mosq_test.do_send_receive(sock, publish_packet, publish_packet)
|
|
|
|
|
|
|
|
|
|
rc = 0
|
|
|
|
|
|
|
|
|
|
sock.close()
|
|
|
|
|
except mosq_test.TestError:
|
|
|
|
|
|
|
|
|
|
pass
|
|
|
|
|
finally:
|
|
|
|
|
if rc1 is None:
|
|
|
|
|
rc1, stde1 = mosq_test.terminate_broker(remote_broker)
|
|
|
|
|
rc2, stde2 = mosq_test.terminate_broker(local_broker)
|
|
|
|
|
if rc or rc1 or rc2:
|
|
|
|
|
print(f"Remote broker first run rc={rc1}")
|
2026-04-17 21:45:29 +02:00
|
|
|
print(stde1)
|
2023-07-03 21:02:52 +02:00
|
|
|
|
|
|
|
|
print(f"Local broker rc={rc2}")
|
2026-04-17 21:45:29 +02:00
|
|
|
print(stde2)
|
2023-07-03 21:02:52 +02:00
|
|
|
try:
|
|
|
|
|
os.remove(conf_file)
|
|
|
|
|
except OSError:
|
|
|
|
|
pass
|
|
|
|
|
return rc == 0
|
|
|
|
|
|
|
|
|
|
if do_test(proto_ver=4) and do_test(proto_ver=5):
|
|
|
|
|
exit(0)
|
|
|
|
|
|
|
|
|
|
exit(1)
|
|
|
|
|
|