From 22f284671df22899de680998e2152fa8061fbc59 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 20 Nov 2018 17:58:12 +0000 Subject: [PATCH] Request-response test with/without correlation data --- test/lib/03-request-response-correlation.py | 99 +++++++++++++++++++ test/lib/03-request-response.py | 96 ++++++++++++++++++ test/lib/Makefile | 2 + test/lib/c/03-request-response-1.c | 61 ++++++++++++ test/lib/c/03-request-response-2.c | 68 +++++++++++++ .../lib/c/03-request-response-correlation-1.c | 62 ++++++++++++ test/lib/c/Makefile | 11 ++- test/lib/ptest.py | 6 +- 8 files changed, 400 insertions(+), 5 deletions(-) create mode 100755 test/lib/03-request-response-correlation.py create mode 100755 test/lib/03-request-response.py create mode 100644 test/lib/c/03-request-response-1.c create mode 100644 test/lib/c/03-request-response-2.c create mode 100644 test/lib/c/03-request-response-correlation-1.c diff --git a/test/lib/03-request-response-correlation.py b/test/lib/03-request-response-correlation.py new file mode 100755 index 00000000..43b055a1 --- /dev/null +++ b/test/lib/03-request-response-correlation.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python + +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() + + +resp_topic = "response/topic" +pub_topic = "request/topic" + +rc = 1 +keepalive = 60 +connect1_packet = mosq_test.gen_connect("request-test", keepalive=keepalive, proto_ver=5) +connect2_packet = mosq_test.gen_connect("response-test", keepalive=keepalive, proto_ver=5) +connack_packet = mosq_test.gen_connack(rc=0, proto_ver=5) + +mid = 1 +subscribe1_packet = mosq_test.gen_subscribe(mid, resp_topic, 0, proto_ver=5) +subscribe2_packet = mosq_test.gen_subscribe(mid, pub_topic, 0, proto_ver=5) +suback_packet = mosq_test.gen_suback(mid, 0, proto_ver=5) + + +props = mqtt5_props.gen_string_prop(mqtt5_props.PROP_RESPONSE_TOPIC, resp_topic) +props += mqtt5_props.gen_string_prop(mqtt5_props.PROP_CORRELATION_DATA, "corridor") +props = mqtt5_props.prop_finalise(props) +publish1_packet = mosq_test.gen_publish(pub_topic, qos=0, payload="action", proto_ver=5, properties=props) + +props = mqtt5_props.gen_string_prop(mqtt5_props.PROP_CORRELATION_DATA, "corridor") +props = mqtt5_props.prop_finalise(props) +publish2_packet = mosq_test.gen_publish(resp_topic, qos=0, payload="a response", proto_ver=5, properties=props) + + +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) + +env = dict(os.environ) +env['LD_LIBRARY_PATH'] = '../../lib:../../lib/cpp' +try: + pp = env['PYTHONPATH'] +except KeyError: + pp = '' +env['PYTHONPATH'] = '../../lib/python:'+pp +client1 = mosq_test.start_client(filename="03-request-response-correlation-1.log", cmd=["c/03-request-response-correlation-1.test"], env=env, port=port) + +try: + (conn1, address) = sock.accept() + conn1.settimeout(10) + + client2 = mosq_test.start_client(filename="03-request-response-2.log", cmd=["c/03-request-response-2.test"], env=env, port=port) + (conn2, address) = sock.accept() + conn2.settimeout(10) + + if mosq_test.expect_packet(conn1, "connect1", connect1_packet): + conn1.send(connack_packet) + + if mosq_test.expect_packet(conn2, "connect2", connect2_packet): + conn2.send(connack_packet) + + if mosq_test.expect_packet(conn1, "subscribe1", subscribe1_packet): + conn1.send(suback_packet) + + if mosq_test.expect_packet(conn2, "subscribe2", subscribe2_packet): + conn2.send(suback_packet) + + if mosq_test.expect_packet(conn1, "publish1", publish1_packet): + conn2.send(publish1_packet) + + if mosq_test.expect_packet(conn2, "publish2", publish2_packet): + rc = 0 + + conn1.close() + conn2.close() +finally: + client1.terminate() + client1.wait() + client2.terminate() + client2.wait() + if rc: + (stdo, stde) = client1.communicate() + print(stde) + (stdo, stde) = client2.communicate() + print(stde) + sock.close() + +exit(rc) diff --git a/test/lib/03-request-response.py b/test/lib/03-request-response.py new file mode 100755 index 00000000..6ff04861 --- /dev/null +++ b/test/lib/03-request-response.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python + +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() + + +resp_topic = "response/topic" +pub_topic = "request/topic" + +rc = 1 +keepalive = 60 +connect1_packet = mosq_test.gen_connect("request-test", keepalive=keepalive, proto_ver=5) +connect2_packet = mosq_test.gen_connect("response-test", keepalive=keepalive, proto_ver=5) +connack_packet = mosq_test.gen_connack(rc=0, proto_ver=5) + +mid = 1 +subscribe1_packet = mosq_test.gen_subscribe(mid, resp_topic, 0, proto_ver=5) +subscribe2_packet = mosq_test.gen_subscribe(mid, pub_topic, 0, proto_ver=5) +suback_packet = mosq_test.gen_suback(mid, 0, proto_ver=5) + + +props = mqtt5_props.gen_string_prop(mqtt5_props.PROP_RESPONSE_TOPIC, resp_topic) +props = mqtt5_props.prop_finalise(props) +publish1_packet = mosq_test.gen_publish(pub_topic, qos=0, payload="action", proto_ver=5, properties=props) + +publish2_packet = mosq_test.gen_publish(resp_topic, qos=0, payload="a response", 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) + +env = dict(os.environ) +env['LD_LIBRARY_PATH'] = '../../lib:../../lib/cpp' +try: + pp = env['PYTHONPATH'] +except KeyError: + pp = '' +env['PYTHONPATH'] = '../../lib/python:'+pp +client1 = mosq_test.start_client(filename="03-request-response-1.log", cmd=["c/03-request-response-1.test"], env=env, port=port) + +try: + (conn1, address) = sock.accept() + conn1.settimeout(10) + + client2 = mosq_test.start_client(filename="03-request-response-2.log", cmd=["c/03-request-response-2.test"], env=env, port=port) + (conn2, address) = sock.accept() + conn2.settimeout(10) + + if mosq_test.expect_packet(conn1, "connect1", connect1_packet): + conn1.send(connack_packet) + + if mosq_test.expect_packet(conn2, "connect2", connect2_packet): + conn2.send(connack_packet) + + if mosq_test.expect_packet(conn1, "subscribe1", subscribe1_packet): + conn1.send(suback_packet) + + if mosq_test.expect_packet(conn2, "subscribe2", subscribe2_packet): + conn2.send(suback_packet) + + if mosq_test.expect_packet(conn1, "publish1", publish1_packet): + conn2.send(publish1_packet) + + if mosq_test.expect_packet(conn2, "publish2", publish2_packet): + rc = 0 + + conn1.close() + conn2.close() +finally: + client1.terminate() + client1.wait() + client2.terminate() + client2.wait() + if rc: + (stdo, stde) = client1.communicate() + print(stde) + (stdo, stde) = client2.communicate() + print(stde) + sock.close() + +exit(rc) diff --git a/test/lib/Makefile b/test/lib/Makefile index bf5a931f..c1107921 100644 --- a/test/lib/Makefile +++ b/test/lib/Makefile @@ -38,6 +38,8 @@ c cpp : test-compile ./03-publish-c2b-qos2-disconnect.py $@/03-publish-c2b-qos2-disconnect.test ./03-publish-b2c-qos1.py $@/03-publish-b2c-qos1.test ./03-publish-b2c-qos2.py $@/03-publish-b2c-qos2.test + ./03-request-response.py $@/03-request-response.test + ./03-request-response-correlation.py $@/03-request-response-correlation.test ./04-retain-qos0.py $@/04-retain-qos0.test ifeq ($(WITH_TLS),yes) ./08-ssl-connect-no-auth.py $@/08-ssl-connect-no-auth.test diff --git a/test/lib/c/03-request-response-1.c b/test/lib/c/03-request-response-1.c new file mode 100644 index 00000000..5c7b5bf5 --- /dev/null +++ b/test/lib/c/03-request-response-1.c @@ -0,0 +1,61 @@ +#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) +{ + if(rc){ + exit(1); + }else{ + mosquitto_subscribe(mosq, NULL, "response/topic", 0); + } +} + +void on_subscribe(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos) +{ + mosquitto_property *props = NULL; + mosquitto_property_add_string(&props, MQTT_PROP_RESPONSE_TOPIC, "response/topic"); + mosquitto_publish_with_properties(mosq, NULL, "request/topic", 6, "action", 0, 0, props); + mosquitto_property_free_all(&props); +} + +void on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg) +{ + if(!strcmp(msg->payload, "a response")){ + run = 0; + }else{ + run = 1; + } +} + +int main(int argc, char *argv[]) +{ + int rc; + struct mosquitto *mosq; + int ver = PROTOCOL_VERSION_v5; + + int port = atoi(argv[1]); + + mosquitto_lib_init(); + + mosq = mosquitto_new("request-test", true, NULL); + mosquitto_opts_set(mosq, MOSQ_OPT_PROTOCOL_VERSION, &ver); + mosquitto_connect_callback_set(mosq, on_connect); + mosquitto_subscribe_callback_set(mosq, on_subscribe); + mosquitto_message_callback_set(mosq, on_message); + + 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/03-request-response-2.c b/test/lib/c/03-request-response-2.c new file mode 100644 index 00000000..8763496f --- /dev/null +++ b/test/lib/c/03-request-response-2.c @@ -0,0 +1,68 @@ +#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) +{ + if(rc){ + exit(1); + }else{ + mosquitto_subscribe(mosq, NULL, "request/topic", 0); + } +} + +void on_message_v5(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg, const mosquitto_property *props) +{ + const mosquitto_property *p_resp, *p_corr = NULL; + char *resp_topic = NULL; + int rc; + + if(!strcmp(msg->topic, "request/topic")){ + p_resp = mosquitto_property_get_property(props, MQTT_PROP_RESPONSE_TOPIC, false); + if(p_resp){ + p_corr = mosquitto_property_get_property(props, MQTT_PROP_CORRELATION_DATA, false); + if(mosquitto_property_read_string(p_resp, &resp_topic) == MOSQ_ERR_SUCCESS){ + rc = mosquitto_publish_with_properties(mosq, NULL, resp_topic, strlen("a response"), "a response", 0, false, p_corr); + free(resp_topic); + } + } + } +} + +void on_publish(struct mosquitto *mosq, void *obj, int mid) +{ + run = 0; +} + + +int main(int argc, char *argv[]) +{ + int rc; + struct mosquitto *mosq; + int ver = PROTOCOL_VERSION_v5; + + int port = atoi(argv[1]); + + mosquitto_lib_init(); + + mosq = mosquitto_new("response-test", true, NULL); + mosquitto_opts_set(mosq, MOSQ_OPT_PROTOCOL_VERSION, &ver); + mosquitto_connect_callback_set(mosq, on_connect); + mosquitto_publish_callback_set(mosq, on_publish); + mosquitto_message_v5_callback_set(mosq, on_message_v5); + + 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/03-request-response-correlation-1.c b/test/lib/c/03-request-response-correlation-1.c new file mode 100644 index 00000000..77245256 --- /dev/null +++ b/test/lib/c/03-request-response-correlation-1.c @@ -0,0 +1,62 @@ +#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) +{ + if(rc){ + exit(1); + }else{ + mosquitto_subscribe(mosq, NULL, "response/topic", 0); + } +} + +void on_subscribe(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos) +{ + mosquitto_property *props = NULL; + mosquitto_property_add_string(&props, MQTT_PROP_RESPONSE_TOPIC, "response/topic"); + mosquitto_property_add_binary(&props, MQTT_PROP_CORRELATION_DATA, "corridor", 8); + mosquitto_publish_with_properties(mosq, NULL, "request/topic", 6, "action", 0, 0, props); + mosquitto_property_free_all(&props); +} + +void on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg) +{ + if(!strcmp(msg->payload, "a response")){ + run = 0; + }else{ + run = 1; + } +} + +int main(int argc, char *argv[]) +{ + int rc; + struct mosquitto *mosq; + int ver = PROTOCOL_VERSION_v5; + + int port = atoi(argv[1]); + + mosquitto_lib_init(); + + mosq = mosquitto_new("request-test", true, NULL); + mosquitto_opts_set(mosq, MOSQ_OPT_PROTOCOL_VERSION, &ver); + mosquitto_connect_callback_set(mosq, on_connect); + mosquitto_subscribe_callback_set(mosq, on_subscribe); + mosquitto_message_callback_set(mosq, on_message); + + 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 9678766a..7d936ff3 100644 --- a/test/lib/c/Makefile +++ b/test/lib/c/Makefile @@ -53,6 +53,15 @@ all : 01 02 03 04 08 09 03-publish-b2c-qos1.test : 03-publish-b2c-qos1.c $(CC) $< -o $@ $(CFLAGS) $(LIBS) +03-request-response-1.test : 03-request-response-1.c + $(CC) $< -o $@ $(CFLAGS) $(LIBS) + +03-request-response-2.test : 03-request-response-2.c + $(CC) $< -o $@ $(CFLAGS) $(LIBS) + +03-request-response-correlation-1.test : 03-request-response-correlation-1.c + $(CC) $< -o $@ $(CFLAGS) $(LIBS) + 03-publish-b2c-qos2.test : 03-publish-b2c-qos2.c $(CC) $< -o $@ $(CFLAGS) $(LIBS) @@ -81,7 +90,7 @@ all : 01 02 03 04 08 09 02 : 02-subscribe-qos0.test 02-subscribe-qos1.test 02-subscribe-qos2.test 02-unsubscribe.test -03 : 03-publish-qos0.test 03-publish-qos0-no-payload.test 03-publish-c2b-qos1-disconnect.test 03-publish-c2b-qos2.test 03-publish-c2b-qos2-disconnect.test 03-publish-b2c-qos1.test 03-publish-b2c-qos2.test +03 : 03-publish-qos0.test 03-publish-qos0-no-payload.test 03-publish-c2b-qos1-disconnect.test 03-publish-c2b-qos2.test 03-publish-c2b-qos2-disconnect.test 03-publish-b2c-qos1.test 03-publish-b2c-qos2.test 03-request-response-1.test 03-request-response-2.test 03-request-response-correlation-1.test 04 : 04-retain-qos0.test diff --git a/test/lib/ptest.py b/test/lib/ptest.py index 42821379..c16079f9 100755 --- a/test/lib/ptest.py +++ b/test/lib/ptest.py @@ -23,14 +23,14 @@ tests = [ ('./03-publish-c2b-qos2.py', 'c/03-publish-c2b-qos2.test'), ('./03-publish-qos0-no-payload.py', 'c/03-publish-qos0-no-payload.test'), ('./03-publish-qos0.py', 'c/03-publish-qos0.test'), + ('./03-request-response.py', 'c/03-request-response.test'), + ('./03-request-response-correlation.py', 'c/03-request-response-correlation.test'), ('./04-retain-qos0.py', 'c/04-retain-qos0.test'), ('./08-ssl-bad-cacert.py', 'c/08-ssl-bad-cacert.test'), ('./08-ssl-connect-cert-auth-enc.py', 'c/08-ssl-connect-cert-auth-enc.test'), ('./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-matching.py', 'c/09-util-topic-matching.test'), ('./09-util-topic-tokenise.py', 'c/09-util-topic-tokenise.test'), - ('./09-util-utf8-validate.py', 'c/09-util-utf8-validate.test'), ('./01-con-discon-success.py', 'cpp/01-con-discon-success.test'), ('./01-keepalive-pingreq.py', 'cpp/01-keepalive-pingreq.test'), @@ -54,9 +54,7 @@ tests = [ ('./08-ssl-connect-cert-auth-enc.py', 'cpp/08-ssl-connect-cert-auth-enc.test'), ('./08-ssl-connect-cert-auth.py', 'cpp/08-ssl-connect-cert-auth.test'), ('./08-ssl-connect-no-auth.py', 'cpp/08-ssl-connect-no-auth.test'), - ('./09-util-topic-matching.py', 'cpp/09-util-topic-matching.test'), ('./09-util-topic-tokenise.py', 'cpp/09-util-topic-tokenise.test'), - ('./09-util-utf8-validate.py', 'cpp/09-util-utf8-validate.test'), ] minport = 1888