From 24fb566168e3dd6ceada9ece3fd7c5efda389aad Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 1 Aug 2018 19:26:12 +0100 Subject: [PATCH] Add test for issue #874. --- .../02-subscribe-persistence-flipflop.py | 90 +++++++++++++++++++ test/broker/Makefile | 1 + test/broker/ptest.py | 1 + test/mosq_test.py | 21 +++-- 4 files changed, 107 insertions(+), 6 deletions(-) create mode 100755 test/broker/02-subscribe-persistence-flipflop.py diff --git a/test/broker/02-subscribe-persistence-flipflop.py b/test/broker/02-subscribe-persistence-flipflop.py new file mode 100755 index 00000000..36b91099 --- /dev/null +++ b/test/broker/02-subscribe-persistence-flipflop.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python + +# Test switching between persistence and a clean session. +# +# Bug #874: +# +# +# mosquitto_sub -i sub -t 'topic' -v -p 29883 -q 1 -d -c +# ^C +# mosquitto_sub -i sub -t 'topic' -v -p 29883 -q 1 -d +# ^C +# +# SUBSCRIBE to topic is no longer respected by mosquitto +# +# run: +# +# mosquitto_sub -i sub -t 'topic' -v -p 29883 -q 1 -d -c +# +# and in a separate shell +# +# mosquitto_pub -i pub -t topic -m 'hello' -p 29883 -q 1 +# +# sub does not receive the message + + +import inspect, os, sys +# From http://stackoverflow.com/questions/279237/python-import-a-module-from-a-folder +cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],".."))) +if cmd_subfolder not in sys.path: + sys.path.insert(0, cmd_subfolder) + +import mosq_test + +rc = 1 +keepalive = 60 +connect_packet_sub_persistent = mosq_test.gen_connect("flipflop-test", keepalive=keepalive, clean_session=False) +connect_packet_sub_clean = mosq_test.gen_connect("flipflop-test", keepalive=keepalive, clean_session=True) +connack_packet_sub = mosq_test.gen_connack(rc=0) + +connect_packet_pub = mosq_test.gen_connect("flipflop-test-pub", keepalive=keepalive) +connack_packet_pub = mosq_test.gen_connack(rc=0) + +mid=1 +subscribe_packet = mosq_test.gen_subscribe(mid, "flipflop/test", 1) +suback_packet = mosq_test.gen_suback(mid, 1) + +mid=1 +publish_packet = mosq_test.gen_publish("flipflop/test", qos=1, mid=mid, payload="message") +puback_packet = mosq_test.gen_puback(mid) + + +port = mosq_test.get_port() +broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port) + +try: + # mosquitto_sub -i sub -t 'topic' -q 1 -d -c + sub_sock = mosq_test.do_client_connect(connect_packet_sub_persistent, connack_packet_sub, port=port) + mosq_test.do_send_receive(sub_sock, subscribe_packet, suback_packet, "subscribe persistent 1") + # And disconnect + sub_sock.close() + + # mosquitto_sub -i sub -t 'topic' -q 1 -d + sub_sock = mosq_test.do_client_connect(connect_packet_sub_clean, connack_packet_sub, port=port) + mosq_test.do_send_receive(sub_sock, subscribe_packet, suback_packet, "subscribe clean") + # And disconnect + sub_sock.close() + + # mosquitto_sub -i sub -t 'topic' -v -q 1 -d -c + sub_sock = mosq_test.do_client_connect(connect_packet_sub_persistent, connack_packet_sub, port=port) + mosq_test.do_send_receive(sub_sock, subscribe_packet, suback_packet, "subscribe persistent 2") + + # and in a separate shell + # + # mosquitto_pub -i pub -t topic -m 'hello' -p 29883 -q 1 + pub_sock = mosq_test.do_client_connect(connect_packet_pub, connack_packet_pub, port=port) + mosq_test.do_send_receive(pub_sock, publish_packet, puback_packet, "publish") + + if mosq_test.expect_packet(sub_sock, "publish receive", publish_packet): + rc = 0 + + sub_sock.close() +finally: + broker.terminate() + broker.wait() + (stdo, stde) = broker.communicate() + if rc: + print(stde) + +exit(rc) + diff --git a/test/broker/Makefile b/test/broker/Makefile index 4abf37ab..bb772d8a 100644 --- a/test/broker/Makefile +++ b/test/broker/Makefile @@ -50,6 +50,7 @@ endif ./02-unsubscribe-qos2.py ./02-unsubscribe-invalid-no-topic.py ./02-subscribe-invalid-utf8.py + ./02-subscribe-persistence-flipflop.py 03 : ./03-publish-qos1.py diff --git a/test/broker/ptest.py b/test/broker/ptest.py index 87e5759f..0c194c1a 100755 --- a/test/broker/ptest.py +++ b/test/broker/ptest.py @@ -33,6 +33,7 @@ tests = [ (1, './02-unsubscribe-qos2.py'), (1, './02-unsubscribe-invalid-no-topic.py'), (1, './02-subscribe-invalid-utf8.py'), + (1, './02-subscribe-persistence-flipflop.py'), (1, './03-publish-qos1.py'), (1, './03-publish-qos2.py'), diff --git a/test/mosq_test.py b/test/mosq_test.py index dc1ba532..a28f2eb1 100644 --- a/test/mosq_test.py +++ b/test/mosq_test.py @@ -54,6 +54,7 @@ def start_client(filename, cmd, env, port=1888): cmd = cmd + [str(port)] return subprocess.Popen(cmd, env=env) + def expect_packet(sock, name, expected): if len(expected) > 0: rlen = len(expected) @@ -63,6 +64,7 @@ def expect_packet(sock, name, expected): packet_recvd = sock.recv(rlen) return packet_matches(name, packet_recvd, expected) + def packet_matches(name, recvd, expected): if recvd != expected: print("FAIL: Received incorrect "+name+".") @@ -79,18 +81,25 @@ def packet_matches(name, recvd, expected): else: return 1 -def do_client_connect(connect_packet, connack_packet, hostname="localhost", port=1888, timeout=60, connack_error="connack"): - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sock.settimeout(timeout) - sock.connect((hostname, port)) - sock.send(connect_packet) - if expect_packet(sock, connack_error, connack_packet): +def do_send_receive(sock, send_packet, receive_packet, error_string="send receive error"): + sock.send(send_packet) + + if expect_packet(sock, error_string, receive_packet): return sock else: sock.close() raise ValueError + +def do_client_connect(connect_packet, connack_packet, hostname="localhost", port=1888, timeout=60, connack_error="connack"): + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.settimeout(timeout) + sock.connect((hostname, port)) + + return do_send_receive(sock, connect_packet, connack_packet, connack_error) + + def remaining_length(packet): l = min(5, len(packet)) all_bytes = struct.unpack("!"+"B"*l, packet[:l])