diff --git a/test/lib/11-prop-send-payload-format.py b/test/lib/11-prop-send-payload-format.py new file mode 100755 index 00000000..7e536990 --- /dev/null +++ b/test/lib/11-prop-send-payload-format.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python + +# Test whether a client sends a correct PUBLISH to a topic with QoS 0. + +# The client should connect to port 1888 with keepalive=60, clean session set, +# and client id publish-qos0-test +# The test will send a CONNACK message to the client with rc=0. Upon receiving +# the CONNACK and verifying that rc=0, the client should send a PUBLISH message +# to topic "pub/qos0/test" with payload "message" and QoS=0. If rc!=0, the +# client should exit with an error. +# After sending the PUBLISH message, the client should send a DISCONNECT message. + +import inspect +import os +import socket +import 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 +import mqtt5_props + +port = mosq_test.get_lib_port() + +rc = 1 +keepalive = 60 +connect_packet = mosq_test.gen_connect("prop-test", keepalive=keepalive, proto_ver=5) +connack_packet = mosq_test.gen_connack(rc=0, proto_ver=5) + +props = mqtt5_props.gen_byte_prop(mqtt5_props.PROP_PAYLOAD_FORMAT_INDICATOR, 0x01) +props = mqtt5_props.prop_finalise(props) +publish_packet = mosq_test.gen_publish("prop/qos0", qos=0, payload="message", proto_ver=5, properties=props) + +disconnect_packet = mosq_test.gen_disconnect(proto_ver=5) + +sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) +sock.settimeout(10) +sock.bind(('', port)) +sock.listen(5) + +client_args = sys.argv[1:] +env = dict(os.environ) +env['LD_LIBRARY_PATH'] = '../../lib:../../lib/cpp' +try: + pp = env['PYTHONPATH'] +except KeyError: + pp = '' +env['PYTHONPATH'] = '../../lib/python:'+pp +client = mosq_test.start_client(filename=sys.argv[1].replace('/', '-'), cmd=client_args, env=env, port=port) + +try: + (conn, address) = sock.accept() + conn.settimeout(10) + + if mosq_test.expect_packet(conn, "connect", connect_packet): + conn.send(connack_packet) + + if mosq_test.expect_packet(conn, "publish", publish_packet): + if mosq_test.expect_packet(conn, "disconnect", disconnect_packet): + rc = 0 + + conn.close() +finally: + client.terminate() + client.wait() + if rc: + (stdo, stde) = client.communicate() + print(stde) + sock.close() + +exit(rc) diff --git a/test/lib/Makefile b/test/lib/Makefile index c1107921..b1ef54f4 100644 --- a/test/lib/Makefile +++ b/test/lib/Makefile @@ -20,7 +20,7 @@ test-compile-c : test-compile-cpp : $(MAKE) -C cpp -c cpp : test-compile +c : test-compile ./01-con-discon-success.py $@/01-con-discon-success.test ./01-will-set.py $@/01-will-set.test ./01-unpwd-set.py $@/01-unpwd-set.test @@ -49,6 +49,7 @@ ifeq ($(WITH_TLS),yes) #./08-ssl-fake-cacert.py $@/08-ssl-fake-cacert.test endif ./09-util-topic-tokenise.py $@/09-util-topic-tokenise.test + ./11-prop-send-payload-format.py $@/11-prop-send-payload-format.test clean : $(MAKE) -C c clean diff --git a/test/lib/c/11-prop-send-payload-format.c b/test/lib/c/11-prop-send-payload-format.c new file mode 100644 index 00000000..198ef72f --- /dev/null +++ b/test/lib/c/11-prop-send-payload-format.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include +#include + +static int run = -1; +static int sent_mid = -1; + +void on_connect(struct mosquitto *mosq, void *obj, int rc) +{ + int rc2; + mosquitto_property *proplist = NULL; + + if(rc){ + exit(1); + }else{ + rc2 = mosquitto_property_add_byte(&proplist, MQTT_PROP_PAYLOAD_FORMAT_INDICATOR, 1); + mosquitto_publish_with_properties(mosq, &sent_mid, "prop/qos0", strlen("message"), "message", 0, false, proplist); + } +} + +void on_publish(struct mosquitto *mosq, void *obj, int mid) +{ + if(mid == sent_mid){ + mosquitto_disconnect(mosq); + run = 0; + }else{ + exit(1); + } +} + +int main(int argc, char *argv[]) +{ + int rc; + int tmp; + struct mosquitto *mosq; + + int port = atoi(argv[1]); + + mosquitto_lib_init(); + + mosq = mosquitto_new("prop-test", true, NULL); + mosquitto_connect_callback_set(mosq, on_connect); + mosquitto_publish_callback_set(mosq, on_publish); + tmp = MQTT_PROTOCOL_V5; + mosquitto_opts_set(mosq, MOSQ_OPT_PROTOCOL_VERSION, &tmp); + + rc = mosquitto_connect(mosq, "localhost", port, 60); + + while(run == -1){ + rc = mosquitto_loop(mosq, -1, 1); + } + + mosquitto_lib_cleanup(); + return run; +} diff --git a/test/lib/c/Makefile b/test/lib/c/Makefile index 7d936ff3..45a6c7e7 100644 --- a/test/lib/c/Makefile +++ b/test/lib/c/Makefile @@ -3,7 +3,7 @@ CFLAGS=-I../../../lib -Werror LIBS=../../../lib/libmosquitto.so.1 -all : 01 02 03 04 08 09 +all : 01 02 03 04 08 09 11 01-con-discon-success.test : 01-con-discon-success.c $(CC) $< -o $@ $(CFLAGS) $(LIBS) @@ -86,6 +86,9 @@ all : 01 02 03 04 08 09 09-util-topic-tokenise.test : 09-util-topic-tokenise.c $(CC) $< -o $@ $(CFLAGS) $(LIBS) +11-prop-send-payload-format.test : 11-prop-send-payload-format.c + $(CC) $< -o $@ $(CFLAGS) $(LIBS) + 01 : 01-con-discon-success.test 01-will-set.test 01-unpwd-set.test 01-will-unpwd-set.test 01-no-clean-session.test 01-keepalive-pingreq.test 02 : 02-subscribe-qos0.test 02-subscribe-qos1.test 02-subscribe-qos2.test 02-unsubscribe.test @@ -98,6 +101,8 @@ all : 01 02 03 04 08 09 09 : 09-util-topic-tokenise.test +11 : 11-prop-send-payload-format.test + reallyclean : clean -rm -f *.orig diff --git a/test/lib/ptest.py b/test/lib/ptest.py index c16079f9..82cf15d3 100755 --- a/test/lib/ptest.py +++ b/test/lib/ptest.py @@ -31,6 +31,8 @@ tests = [ ('./08-ssl-connect-cert-auth.py', 'c/08-ssl-connect-cert-auth.test'), ('./08-ssl-connect-no-auth.py', 'c/08-ssl-connect-no-auth.test'), ('./09-util-topic-tokenise.py', 'c/09-util-topic-tokenise.test'), + ('./09-util-utf8-validate.py', 'c/09-util-utf8-validate.test'), + ('./11-prop-send-payload-format.py', 'c/11/prop-send-payload-format.py'), ('./01-con-discon-success.py', 'cpp/01-con-discon-success.test'), ('./01-keepalive-pingreq.py', 'cpp/01-keepalive-pingreq.test'), diff --git a/test/mosq_test.py b/test/mosq_test.py index 85447d06..26fea528 100644 --- a/test/mosq_test.py +++ b/test/mosq_test.py @@ -78,6 +78,8 @@ def packet_matches(name, recvd, expected): print("Expected: "+to_string(expected)) except struct.error: print("Expected (not decoded, len=%d): %s" % (len(expected), expected)) + for i in range(0, len(expected)): + print('%c'%(expected[i]),) return 0 else: @@ -459,8 +461,11 @@ def gen_pingreq(): def gen_pingresp(): return struct.pack('!BB', 208, 0) -def gen_disconnect(): - return struct.pack('!BB', 224, 0) +def gen_disconnect(proto_ver=4): + if proto_ver == 5: + return struct.pack('!BBBB', 224, 2, 0, 0) + else: + return struct.pack('!BB', 224, 0) def pack_remaining_length(remaining_length): s = ""