int test_keepalive_disconnects_hung() { IT("disconnects a hung connection (takes 30 seconds)"); ShimClient shimClient; shimClient.setAllowConnect(true); byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; shimClient.respond(connack,4); PubSubClient client(server, 1883, callback, shimClient); int rc = client.connect((char*)"client_test1"); IS_TRUE(rc); byte pingreq[] = { 0xC0,0x0 }; shimClient.expect(pingreq,2); for (int i = 0; i < 32; i++) { sleep(1); rc = client.loop(); } IS_FALSE(rc); int state = client.state(); IS_TRUE(state == MQTT_CONNECTION_TIMEOUT); IS_FALSE(shimClient.error()); END_IT }
int test_receive_max_sized_message() { IT("receives an max-sized message"); reset_callback(); ShimClient shimClient; shimClient.setAllowConnect(true); byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; shimClient.respond(connack,4); PubSubClient client(server, 1883, callback, shimClient); int rc = client.connect((char*)"client_test1"); IS_TRUE(rc); byte length = MQTT_MAX_PACKET_SIZE; byte publish[] = {0x30,length-2,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64}; byte bigPublish[length]; memset(bigPublish,'A',length); bigPublish[length] = 'B'; memcpy(bigPublish,publish,16); shimClient.respond(bigPublish,length); rc = client.loop(); IS_TRUE(rc); IS_TRUE(callback_called); IS_TRUE(strcmp(lastTopic,"topic")==0); IS_TRUE(lastLength == length-9); IS_TRUE(memcmp(lastPayload,bigPublish+9,lastLength)==0); IS_FALSE(shimClient.error()); END_IT }
int test_receive_stream() { IT("receives a streamed callback message"); reset_callback(); Stream stream; stream.expect((uint8_t*)"payload",7); ShimClient shimClient; shimClient.setAllowConnect(true); byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; shimClient.respond(connack,4); PubSubClient client(server, 1883, callback, shimClient, stream); int rc = client.connect((char*)"client_test1"); IS_TRUE(rc); byte publish[] = {0x30,0xe,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64}; shimClient.respond(publish,16); rc = client.loop(); IS_TRUE(rc); IS_TRUE(callback_called); IS_TRUE(strcmp(lastTopic,"topic")==0); IS_TRUE(lastLength == 7); IS_FALSE(stream.error()); IS_FALSE(shimClient.error()); END_IT }
int test_publish_retained() { IT("publishes retained"); ShimClient shimClient; shimClient.setAllowConnect(true); byte payload[] = { 0x01,0x02,0x03,0x0,0x05 }; int length = 5; byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; shimClient.respond(connack,4); PubSubClient client(server, 1883, callback, shimClient); int rc = client.connect((char*)"client_test1"); IS_TRUE(rc); byte publish[] = {0x31,0xc,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x1,0x2,0x3,0x0,0x5}; shimClient.expect(publish,14); rc = client.publish((char*)"topic",payload,length,true); IS_TRUE(rc); IS_FALSE(shimClient.error()); END_IT }
int test_connect_fails_on_no_response() { IT("fails to connect if no response received after 15 seconds"); ShimClient shimClient; shimClient.setAllowConnect(true); PubSubClient client(server, 1883, callback, shimClient); int rc = client.connect((char*)"client_test1"); IS_FALSE(rc); END_IT }
int test_connect_fails_no_network() { IT("fails to connect if underlying client doesn't connect"); ShimClient shimClient; shimClient.setAllowConnect(false); PubSubClient client(server, 1883, callback, shimClient); int rc = client.connect((char*)"client_test1"); IS_FALSE(rc); END_IT }
int test_connect_fails_on_bad_rc() { IT("fails to connect if a bad return code is received"); ShimClient shimClient; shimClient.setAllowConnect(true); byte connack[] = { 0x20, 0x02, 0x00, 0x01 }; shimClient.respond(connack,4); PubSubClient client(server, 1883, callback, shimClient); int rc = client.connect((char*)"client_test1"); IS_FALSE(rc); END_IT }
int test_publish_not_connected() { IT("publish fails when not connected"); ShimClient shimClient; PubSubClient client(server, 1883, callback, shimClient); int rc = client.publish((char*)"topic",(char*)"payload"); IS_FALSE(rc); IS_FALSE(shimClient.error()); END_IT }
int test_subscribe_not_connected() { IT("subscribe fails when not connected"); ShimClient shimClient; PubSubClient client(server, 1883, callback, shimClient); int rc = client.subscribe((char*)"topic"); IS_FALSE(rc); IS_FALSE(shimClient.error()); END_IT }
int test_keepalive_pings_idle() { IT("keeps an idle connection alive (takes 1 minute)"); ShimClient shimClient; shimClient.setAllowConnect(true); byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; shimClient.respond(connack,4); PubSubClient client(server, 1883, callback, shimClient); int rc = client.connect((char*)"client_test1"); IS_TRUE(rc); byte pingreq[] = { 0xC0,0x0 }; shimClient.expect(pingreq,2); byte pingresp[] = { 0xD0,0x0 }; shimClient.respond(pingresp,2); for (int i = 0; i < 50; i++) { sleep(1); if ( i == 15 || i == 31 || i == 47) { shimClient.expect(pingreq,2); shimClient.respond(pingresp,2); } rc = client.loop(); IS_TRUE(rc); } IS_FALSE(shimClient.error()); END_IT }
int test_keepalive_pings_with_outbound_qos0() { IT("keeps a connection alive that only sends qos0 (takes 1 minute)"); ShimClient shimClient; shimClient.setAllowConnect(true); byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; shimClient.respond(connack,4); PubSubClient client(server, 1883, callback, shimClient); int rc = client.connect((char*)"client_test1"); IS_TRUE(rc); byte publish[] = {0x30,0xe,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64}; for (int i = 0; i < 50; i++) { TRACE(i<<":"); shimClient.expect(publish,16); rc = client.publish((char*)"topic",(char*)"payload"); IS_TRUE(rc); IS_FALSE(shimClient.error()); sleep(1); if ( i == 15 || i == 31 || i == 47) { byte pingreq[] = { 0xC0,0x0 }; shimClient.expect(pingreq,2); byte pingresp[] = { 0xD0,0x0 }; shimClient.respond(pingresp,2); } rc = client.loop(); IS_TRUE(rc); IS_FALSE(shimClient.error()); } END_IT }
int test_connect_properly_formatted_hostname() { IT("accepts a hostname"); ShimClient shimClient; shimClient.setAllowConnect(true); shimClient.expectConnect((char* const)"localhost",1883); byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; shimClient.respond(connack,4); PubSubClient client((char* const)"localhost", 1883, callback, shimClient); int rc = client.connect((char*)"client_test1"); IS_TRUE(rc); IS_FALSE(shimClient.error()); END_IT }
int test_connect_accepts_username_password() { IT("accepts a username and password"); ShimClient shimClient; shimClient.setAllowConnect(true); byte connect[] = { 0x10,0x26,0x0,0x6,0x4d,0x51,0x49,0x73,0x64,0x70,0x3,0xc2,0x0,0xf,0x0,0xc,0x63,0x6c,0x69,0x65,0x6e,0x74,0x5f,0x74,0x65,0x73,0x74,0x31,0x0,0x4,0x75,0x73,0x65,0x72,0x0,0x4,0x70,0x61,0x73,0x73}; byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; shimClient.expect(connect,0x28); shimClient.respond(connack,4); PubSubClient client(server, 1883, callback, shimClient); int rc = client.connect((char*)"client_test1",(char*)"user",(char*)"pass"); IS_TRUE(rc); IS_FALSE(shimClient.error()); END_IT }
int test_connect_ignores_password_no_username() { IT("ignores a password but no username"); ShimClient shimClient; shimClient.setAllowConnect(true); byte connect[] = {0x10,0x1a,0x0,0x6,0x4d,0x51,0x49,0x73,0x64,0x70,0x3,0x2,0x0,0xf,0x0,0xc,0x63,0x6c,0x69,0x65,0x6e,0x74,0x5f,0x74,0x65,0x73,0x74,0x31}; byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; shimClient.expect(connect,28); shimClient.respond(connack,4); PubSubClient client(server, 1883, callback, shimClient); int rc = client.connect((char*)"client_test1",'\0',(char*)"pass"); IS_TRUE(rc); IS_FALSE(shimClient.error()); END_IT }
int test_connect_with_will_username_password() { IT("accepts a will, username and password"); ShimClient shimClient; shimClient.setAllowConnect(true); byte connect[] = {0x10,0x42,0x0,0x6,0x4d,0x51,0x49,0x73,0x64,0x70,0x3,0xce,0x0,0xf,0x0,0xc,0x63,0x6c,0x69,0x65,0x6e,0x74,0x5f,0x74,0x65,0x73,0x74,0x31,0x0,0x9,0x77,0x69,0x6c,0x6c,0x54,0x6f,0x70,0x69,0x63,0x0,0xb,0x77,0x69,0x6c,0x6c,0x4d,0x65,0x73,0x73,0x61,0x67,0x65,0x0,0x4,0x75,0x73,0x65,0x72,0x0,0x8,0x70,0x61,0x73,0x73,0x77,0x6f,0x72,0x64}; byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; shimClient.expect(connect,0x44); shimClient.respond(connack,4); PubSubClient client(server, 1883, callback, shimClient); int rc = client.connect((char*)"client_test1",(char*)"user",(char*)"password",(char*)"willTopic",1,0,(char*)"willMessage"); IS_TRUE(rc); IS_FALSE(shimClient.error()); END_IT }
int test_subscribe_invalid_qos() { IT("subscribe fails with invalid qos values"); ShimClient shimClient; shimClient.setAllowConnect(true); byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; shimClient.respond(connack,4); PubSubClient client(server, 1883, callback, shimClient); int rc = client.connect((char*)"client_test1"); IS_TRUE(rc); rc = client.subscribe((char*)"topic",2); IS_FALSE(rc); rc = client.subscribe((char*)"topic",254); IS_FALSE(rc); IS_FALSE(shimClient.error()); END_IT }
int test_connect_properly_formatted() { IT("sends a properly formatted connect packet and succeeds"); ShimClient shimClient; shimClient.setAllowConnect(true); byte expectServer[] = { 172, 16, 0, 2 }; shimClient.expectConnect(expectServer,1883); byte connect[] = {0x10,0x18,0x0,0x4,0x4d,0x51,0x54,0x54,0x4,0x2,0x0,0xf,0x0,0xc,0x63,0x6c,0x69,0x65,0x6e,0x74,0x5f,0x74,0x65,0x73,0x74,0x31}; byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; shimClient.expect(connect,26); shimClient.respond(connack,4); PubSubClient client(server, 1883, callback, shimClient); int state = client.state(); IS_TRUE(state == MQTT_DISCONNECTED); int rc = client.connect((char*)"client_test1"); IS_TRUE(rc); IS_FALSE(shimClient.error()); state = client.state(); IS_TRUE(state == MQTT_CONNECTED); END_IT }
int test_keepalive_no_pings_inbound_qos1() { IT("does not send pings for connections with inbound qos1 (takes 1 minute)"); ShimClient shimClient; shimClient.setAllowConnect(true); byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; shimClient.respond(connack,4); PubSubClient client(server, 1883, callback, shimClient); int rc = client.connect((char*)"client_test1"); IS_TRUE(rc); byte publish[] = {0x32,0x10,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x12,0x34,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64}; byte puback[] = {0x40,0x2,0x12,0x34}; for (int i = 0; i < 50; i++) { shimClient.respond(publish,18); shimClient.expect(puback,4); sleep(1); rc = client.loop(); IS_TRUE(rc); IS_FALSE(shimClient.error()); } END_IT }
int test_receive_qos1() { IT("receives a qos1 message"); reset_callback(); ShimClient shimClient; shimClient.setAllowConnect(true); byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; shimClient.respond(connack,4); PubSubClient client(server, 1883, callback, shimClient); int rc = client.connect((char*)"client_test1"); IS_TRUE(rc); byte publish[] = {0x32,0x10,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x12,0x34,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64}; shimClient.respond(publish,18); byte puback[] = {0x40,0x2,0x12,0x34}; shimClient.expect(puback,4); rc = client.loop(); IS_TRUE(rc); IS_TRUE(callback_called); IS_TRUE(strcmp(lastTopic,"topic")==0); IS_TRUE(memcmp(lastPayload,"payload",7)==0); IS_TRUE(lastLength == 7); IS_FALSE(shimClient.error()); END_IT }
int test_publish() { IT("publishes a null-terminated string"); ShimClient shimClient; shimClient.setAllowConnect(true); byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; shimClient.respond(connack,4); PubSubClient client(server, 1883, callback, shimClient); int rc = client.connect((char*)"client_test1"); IS_TRUE(rc); byte publish[] = {0x30,0xe,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64}; shimClient.expect(publish,16); rc = client.publish((char*)"topic",(char*)"payload"); IS_TRUE(rc); IS_FALSE(shimClient.error()); END_IT }
int test_unsubscribe() { IT("unsubscribes"); ShimClient shimClient; shimClient.setAllowConnect(true); byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; shimClient.respond(connack,4); PubSubClient client(server, 1883, callback, shimClient); int rc = client.connect((char*)"client_test1"); IS_TRUE(rc); byte unsubscribe[] = { 0xA2,0x9,0x0,0x2,0x0,0x5,0x74,0x6f,0x70,0x69,0x63 }; shimClient.expect(unsubscribe,12); byte unsuback[] = { 0xB0,0x2,0x0,0x2 }; shimClient.respond(unsuback,4); rc = client.unsubscribe((char*)"topic"); IS_TRUE(rc); IS_FALSE(shimClient.error()); END_IT }
int test_subscribe_qos_1() { IT("subscribes qos 1"); ShimClient shimClient; shimClient.setAllowConnect(true); byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; shimClient.respond(connack,4); PubSubClient client(server, 1883, callback, shimClient); int rc = client.connect((char*)"client_test1"); IS_TRUE(rc); byte subscribe[] = { 0x82,0xa,0x0,0x2,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x1 }; shimClient.expect(subscribe,12); byte suback[] = { 0x90,0x3,0x0,0x2,0x1 }; shimClient.respond(suback,5); rc = client.subscribe((char*)"topic",1); IS_TRUE(rc); IS_FALSE(shimClient.error()); END_IT }
int test_connect_disconnect_connect() { IT("connects, disconnects and connects again"); ShimClient shimClient; shimClient.setAllowConnect(true); byte expectServer[] = { 172, 16, 0, 2 }; shimClient.expectConnect(expectServer,1883); byte connect[] = {0x10,0x18,0x0,0x4,0x4d,0x51,0x54,0x54,0x4,0x2,0x0,0xf,0x0,0xc,0x63,0x6c,0x69,0x65,0x6e,0x74,0x5f,0x74,0x65,0x73,0x74,0x31}; byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; shimClient.expect(connect,26); shimClient.respond(connack,4); PubSubClient client(server, 1883, callback, shimClient); int state = client.state(); IS_TRUE(state == MQTT_DISCONNECTED); int rc = client.connect((char*)"client_test1"); IS_TRUE(rc); IS_FALSE(shimClient.error()); state = client.state(); IS_TRUE(state == MQTT_CONNECTED); byte disconnect[] = {0xE0,0x00}; shimClient.expect(disconnect,2); client.disconnect(); IS_FALSE(client.connected()); IS_FALSE(shimClient.connected()); IS_FALSE(shimClient.error()); state = client.state(); IS_TRUE(state == MQTT_DISCONNECTED); shimClient.expect(connect,28); shimClient.respond(connack,4); rc = client.connect((char*)"client_test1"); IS_TRUE(rc); IS_FALSE(shimClient.error()); state = client.state(); IS_TRUE(state == MQTT_CONNECTED); END_IT }