Update tests & add travis

This commit is contained in:
Nick O'Leary 2015-08-28 22:16:48 +01:00
parent 9459df9d44
commit 1c54371b1c
14 changed files with 327 additions and 191 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
tests/bin

9
.travis.yml Normal file
View File

@ -0,0 +1,9 @@
language: cpp
compiler:
- g++
script: cd tests && make && make test
os:
- linux

View File

@ -202,6 +202,7 @@ boolean PubSubClient::connect(const char *id, const char *user, const char *pass
} }
return false; return false;
} }
return true;
} }
uint8_t PubSubClient::readByte() { uint8_t PubSubClient::readByte() {

View File

@ -4,15 +4,22 @@ TEST_SRC=$(wildcard ${SRC_PATH}/*_spec.cpp)
TEST_BIN= $(TEST_SRC:${SRC_PATH}/%.cpp=${OUT_PATH}/%) TEST_BIN= $(TEST_SRC:${SRC_PATH}/%.cpp=${OUT_PATH}/%)
VPATH=${SRC_PATH} VPATH=${SRC_PATH}
SHIM_FILES=${SRC_PATH}/lib/*.cpp SHIM_FILES=${SRC_PATH}/lib/*.cpp
PSC_FILE=../PubSubClient/PubSubClient.cpp PSC_FILE=../PubSubClient/src/PubSubClient.cpp
CC=g++ CC=g++
CFLAGS=-I${SRC_PATH}/lib -I../PubSubClient CFLAGS=-I${SRC_PATH}/lib -I../PubSubClient/src
all: $(TEST_BIN) all: $(TEST_BIN)
${OUT_PATH}/%: ${SRC_PATH}/%.cpp ${PSC_FILE} ${SHIM_FILES} ${OUT_PATH}/%: ${SRC_PATH}/%.cpp ${PSC_FILE} ${SHIM_FILES}
mkdir -p ${OUT_PATH} mkdir -p ${OUT_PATH}
${CC} ${CFLAGS} $^ -o $@ ${CC} ${CFLAGS} $^ -o $@
clean: clean:
@rm -rf ${OUT_PATH} @rm -rf ${OUT_PATH}
test:
@bin/connect_spec
@bin/keepalive_spec
@bin/publish_spec
@bin/receive_spec
@bin/subscribe_spec

View File

@ -35,38 +35,38 @@ int test_connect_fails_on_no_response() {
int test_connect_properly_formatted() { int test_connect_properly_formatted() {
IT("sends a properly formatted connect packet and succeeds"); IT("sends a properly formatted connect packet and succeeds");
ShimClient shimClient; ShimClient shimClient;
shimClient.setAllowConnect(true); shimClient.setAllowConnect(true);
byte expectServer[] = { 172, 16, 0, 2 }; byte expectServer[] = { 172, 16, 0, 2 };
shimClient.expectConnect(expectServer,1883); shimClient.expectConnect(expectServer,1883);
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 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 }; byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
shimClient.expect(connect,28); shimClient.expect(connect,26);
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.connect((char*)"client_test1"); int rc = client.connect((char*)"client_test1");
IS_TRUE(rc); IS_TRUE(rc);
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
END_IT END_IT
} }
int test_connect_properly_formatted_hostname() { int test_connect_properly_formatted_hostname() {
IT("accepts a hostname"); IT("accepts a hostname");
ShimClient shimClient; ShimClient shimClient;
shimClient.setAllowConnect(true); shimClient.setAllowConnect(true);
shimClient.expectConnect((char* const)"localhost",1883); shimClient.expectConnect((char* const)"localhost",1883);
byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client((char* const)"localhost", 1883, callback, shimClient); PubSubClient client((char* const)"localhost", 1883, callback, shimClient);
int rc = client.connect((char*)"client_test1"); int rc = client.connect((char*)"client_test1");
IS_TRUE(rc); IS_TRUE(rc);
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
END_IT END_IT
} }
@ -77,7 +77,7 @@ int test_connect_fails_on_bad_rc() {
shimClient.setAllowConnect(true); shimClient.setAllowConnect(true);
byte connack[] = { 0x20, 0x02, 0x00, 0x01 }; byte connack[] = { 0x20, 0x02, 0x00, 0x01 };
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.connect((char*)"client_test1"); int rc = client.connect((char*)"client_test1");
IS_FALSE(rc); IS_FALSE(rc);
@ -88,12 +88,12 @@ int test_connect_accepts_username_password() {
IT("accepts a username and password"); IT("accepts a username and password");
ShimClient shimClient; ShimClient shimClient;
shimClient.setAllowConnect(true); 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 connect[] = { 0x10,0x24,0x0,0x4,0x4d,0x51,0x54,0x54,0x4,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 }; byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
shimClient.expect(connect,0x28); shimClient.expect(connect,0x26);
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.connect((char*)"client_test1",(char*)"user",(char*)"pass"); int rc = client.connect((char*)"client_test1",(char*)"user",(char*)"pass");
IS_TRUE(rc); IS_TRUE(rc);
@ -106,14 +106,14 @@ int test_connect_accepts_username_no_password() {
IT("accepts a username but no password"); IT("accepts a username but no password");
ShimClient shimClient; ShimClient shimClient;
shimClient.setAllowConnect(true); shimClient.setAllowConnect(true);
byte connect[] = { 0x10,0x20,0x0,0x6,0x4d,0x51,0x49,0x73,0x64,0x70,0x3,0x82,0x0,0xf,0x0,0xc,0x63,0x6c,0x69,0x65,0x6e,0x74,0x5f,0x74,0x65,0x73,0x74,0x31,0x0,0x4,0x75,0x73,0x65,0x72}; byte connect[] = { 0x10,0x1e,0x0,0x4,0x4d,0x51,0x54,0x54,0x4,0x82,0x0,0xf,0x0,0xc,0x63,0x6c,0x69,0x65,0x6e,0x74,0x5f,0x74,0x65,0x73,0x74,0x31,0x0,0x4,0x75,0x73,0x65,0x72};
byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
shimClient.expect(connect,0x22); shimClient.expect(connect,0x20);
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.connect((char*)"client_test1",(char*)"user",'\0'); int rc = client.connect((char*)"client_test1",(char*)"user",0);
IS_TRUE(rc); IS_TRUE(rc);
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
@ -124,14 +124,14 @@ int test_connect_ignores_password_no_username() {
IT("ignores a password but no username"); IT("ignores a password but no username");
ShimClient shimClient; ShimClient shimClient;
shimClient.setAllowConnect(true); 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 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 }; byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
shimClient.expect(connect,28); shimClient.expect(connect,26);
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.connect((char*)"client_test1",'\0',(char*)"pass"); int rc = client.connect((char*)"client_test1",0,(char*)"pass");
IS_TRUE(rc); IS_TRUE(rc);
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
@ -142,12 +142,12 @@ int test_connect_with_will() {
IT("accepts a will"); IT("accepts a will");
ShimClient shimClient; ShimClient shimClient;
shimClient.setAllowConnect(true); shimClient.setAllowConnect(true);
byte connect[] = {0x10,0x32,0x0,0x6,0x4d,0x51,0x49,0x73,0x64,0x70,0x3,0xe,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}; byte connect[] = {0x10,0x30,0x0,0x4,0x4d,0x51,0x54,0x54,0x4,0xe,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};
byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
shimClient.expect(connect,0x34); shimClient.expect(connect,0x32);
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.connect((char*)"client_test1",(char*)"willTopic",1,0,(char*)"willMessage"); int rc = client.connect((char*)"client_test1",(char*)"willTopic",1,0,(char*)"willMessage");
IS_TRUE(rc); IS_TRUE(rc);
@ -160,12 +160,12 @@ int test_connect_with_will_username_password() {
IT("accepts a will, username and password"); IT("accepts a will, username and password");
ShimClient shimClient; ShimClient shimClient;
shimClient.setAllowConnect(true); 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 connect[] = {0x10,0x40,0x0,0x4,0x4d,0x51,0x54,0x54,0x4,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 }; byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
shimClient.expect(connect,0x44); shimClient.expect(connect,0x42);
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.connect((char*)"client_test1",(char*)"user",(char*)"password",(char*)"willTopic",1,0,(char*)"willMessage"); int rc = client.connect((char*)"client_test1",(char*)"user",(char*)"password",(char*)"willTopic",1,0,(char*)"willMessage");
IS_TRUE(rc); IS_TRUE(rc);
@ -177,52 +177,54 @@ int test_connect_with_will_username_password() {
int test_connect_disconnect_connect() { int test_connect_disconnect_connect() {
IT("connects, disconnects and connects again"); IT("connects, disconnects and connects again");
ShimClient shimClient; ShimClient shimClient;
shimClient.setAllowConnect(true); shimClient.setAllowConnect(true);
byte expectServer[] = { 172, 16, 0, 2 }; byte expectServer[] = { 172, 16, 0, 2 };
shimClient.expectConnect(expectServer,1883); shimClient.expectConnect(expectServer,1883);
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 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 }; byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
shimClient.expect(connect,28); shimClient.expect(connect,26);
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.connect((char*)"client_test1"); int rc = client.connect((char*)"client_test1");
IS_TRUE(rc); IS_TRUE(rc);
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
byte disconnect[] = {0xE0,0x00}; byte disconnect[] = {0xE0,0x00};
shimClient.expect(disconnect,2); shimClient.expect(disconnect,2);
client.disconnect(); client.disconnect();
IS_FALSE(client.connected()); IS_FALSE(client.connected());
IS_FALSE(shimClient.connected()); IS_FALSE(shimClient.connected());
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
shimClient.expect(connect,28); shimClient.expect(connect,28);
shimClient.respond(connack,4); shimClient.respond(connack,4);
rc = client.connect((char*)"client_test1"); rc = client.connect((char*)"client_test1");
IS_TRUE(rc); IS_TRUE(rc);
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
END_IT END_IT
} }
int main() int main()
{ {
SUITE("Connect");
test_connect_fails_no_network(); test_connect_fails_no_network();
test_connect_fails_on_no_response(); test_connect_fails_on_no_response();
test_connect_properly_formatted(); test_connect_properly_formatted();
test_connect_accepts_username_password();
test_connect_fails_on_bad_rc(); test_connect_fails_on_bad_rc();
test_connect_properly_formatted_hostname(); test_connect_properly_formatted_hostname();
test_connect_accepts_username_password();
test_connect_accepts_username_no_password(); test_connect_accepts_username_no_password();
test_connect_ignores_password_no_username(); test_connect_ignores_password_no_username();
test_connect_with_will(); test_connect_with_will();
test_connect_with_will_username_password(); test_connect_with_will_username_password();
test_connect_disconnect_connect(); test_connect_disconnect_connect();
FINISH FINISH
} }

View File

@ -3,7 +3,7 @@
#include "Buffer.h" #include "Buffer.h"
#include "BDDTest.h" #include "BDDTest.h"
#include "trace.h" #include "trace.h"
#include <unistd.h>
byte server[] = { 172, 16, 0, 2 }; byte server[] = { 172, 16, 0, 2 };
@ -13,49 +13,49 @@ void callback(char* topic, byte* payload, unsigned int length) {
int test_keepalive_pings_idle() { int test_keepalive_pings_idle() {
IT("keeps an idle connection alive"); IT("keeps an idle connection alive (takes 1 minute)");
ShimClient shimClient; ShimClient shimClient;
shimClient.setAllowConnect(true); shimClient.setAllowConnect(true);
byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.connect((char*)"client_test1"); int rc = client.connect((char*)"client_test1");
IS_TRUE(rc); IS_TRUE(rc);
byte pingreq[] = { 0xC0,0x0 }; byte pingreq[] = { 0xC0,0x0 };
shimClient.expect(pingreq,2); shimClient.expect(pingreq,2);
byte pingresp[] = { 0xD0,0x0 }; byte pingresp[] = { 0xD0,0x0 };
shimClient.respond(pingresp,2); shimClient.respond(pingresp,2);
for (int i = 0; i < 50; i++) { for (int i = 0; i < 50; i++) {
sleep(1); sleep(1);
rc = client.loop(); rc = client.loop();
IS_TRUE(rc); IS_TRUE(rc);
} }
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
END_IT END_IT
} }
int test_keepalive_pings_with_outbound_qos0() { int test_keepalive_pings_with_outbound_qos0() {
IT("keeps a connection alive that only sends qos0"); IT("keeps a connection alive that only sends qos0 (takes 1 minute)");
ShimClient shimClient; ShimClient shimClient;
shimClient.setAllowConnect(true); shimClient.setAllowConnect(true);
byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.connect((char*)"client_test1"); int rc = client.connect((char*)"client_test1");
IS_TRUE(rc); IS_TRUE(rc);
byte publish[] = {0x30,0xe,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64}; 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++) { for (int i = 0; i < 50; i++) {
TRACE(i<<":"); TRACE(i<<":");
shimClient.expect(publish,16); shimClient.expect(publish,16);
@ -73,25 +73,25 @@ int test_keepalive_pings_with_outbound_qos0() {
IS_TRUE(rc); IS_TRUE(rc);
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
} }
END_IT END_IT
} }
int test_keepalive_pings_with_inbound_qos0() { int test_keepalive_pings_with_inbound_qos0() {
IT("keeps a connection alive that only receives qos0"); IT("keeps a connection alive that only receives qos0 (takes 1 minute)");
ShimClient shimClient; ShimClient shimClient;
shimClient.setAllowConnect(true); shimClient.setAllowConnect(true);
byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.connect((char*)"client_test1"); int rc = client.connect((char*)"client_test1");
IS_TRUE(rc); IS_TRUE(rc);
byte publish[] = {0x30,0xe,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64}; 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++) { for (int i = 0; i < 50; i++) {
TRACE(i<<":"); TRACE(i<<":");
sleep(1); sleep(1);
@ -106,23 +106,23 @@ int test_keepalive_pings_with_inbound_qos0() {
IS_TRUE(rc); IS_TRUE(rc);
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
} }
END_IT END_IT
} }
int test_keepalive_no_pings_inbound_qos1() { int test_keepalive_no_pings_inbound_qos1() {
IT("does not send pings for connections with inbound qos1"); IT("does not send pings for connections with inbound qos1 (takes 1 minute)");
ShimClient shimClient; ShimClient shimClient;
shimClient.setAllowConnect(true); shimClient.setAllowConnect(true);
byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.connect((char*)"client_test1"); int rc = client.connect((char*)"client_test1");
IS_TRUE(rc); IS_TRUE(rc);
byte publish[] = {0x32,0x10,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x12,0x34,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64}; 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}; byte puback[] = {0x40,0x2,0x12,0x34};
@ -139,27 +139,27 @@ int test_keepalive_no_pings_inbound_qos1() {
} }
int test_keepalive_disconnects_hung() { int test_keepalive_disconnects_hung() {
IT("disconnects a hung connection"); IT("disconnects a hung connection (takes 30 seconds)");
ShimClient shimClient; ShimClient shimClient;
shimClient.setAllowConnect(true); shimClient.setAllowConnect(true);
byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.connect((char*)"client_test1"); int rc = client.connect((char*)"client_test1");
IS_TRUE(rc); IS_TRUE(rc);
byte pingreq[] = { 0xC0,0x0 }; byte pingreq[] = { 0xC0,0x0 };
shimClient.expect(pingreq,2); shimClient.expect(pingreq,2);
for (int i = 0; i < 32; i++) { for (int i = 0; i < 32; i++) {
sleep(1); sleep(1);
rc = client.loop(); rc = client.loop();
} }
IS_FALSE(rc); IS_FALSE(rc);
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
END_IT END_IT
@ -167,11 +167,12 @@ int test_keepalive_disconnects_hung() {
int main() int main()
{ {
SUITE("Keep-alive");
test_keepalive_pings_idle(); test_keepalive_pings_idle();
test_keepalive_pings_with_outbound_qos0(); test_keepalive_pings_with_outbound_qos0();
test_keepalive_pings_with_inbound_qos0(); test_keepalive_pings_with_inbound_qos0();
test_keepalive_no_pings_inbound_qos1(); test_keepalive_no_pings_inbound_qos1();
test_keepalive_disconnects_hung(); test_keepalive_disconnects_hung();
FINISH FINISH
} }

View File

@ -9,25 +9,29 @@ int testCount = 0;
int testPasses = 0; int testPasses = 0;
const char* testDescription; const char* testDescription;
std::list<std::string> failureList; std::list<std::string> failureList;
void bddtest_suite(const char* name) {
LOG(name << "\n");
}
int bddtest_test(const char* file, int line, const char* assertion, int result) { int bddtest_test(const char* file, int line, const char* assertion, int result) {
if (!result) { if (!result) {
LOG("F"); LOG("\n");
std::ostringstream os; std::ostringstream os;
os << " ! "<<testDescription<<"\n " <<file << ":" <<line<<" : "<<assertion<<" ["<<result<<"]"; os << " ! "<<testDescription<<"\n " <<file << ":" <<line<<" : "<<assertion<<" ["<<result<<"]";
failureList.push_back(os.str()); failureList.push_back(os.str());
} }
return result; return result;
} }
void bddtest_start(const char* description) { void bddtest_start(const char* description) {
TRACE(" - "<<description << "\n"); LOG(" - "<<description<<" ");
testDescription = description; testDescription = description;
testCount ++; testCount ++;
} }
void bddtest_end() { void bddtest_end() {
LOG("."); LOG("\n");
testPasses ++; testPasses ++;
} }
@ -35,8 +39,10 @@ int bddtest_summary() {
for (std::list<std::string>::iterator it = failureList.begin(); it != failureList.end(); it++) { for (std::list<std::string>::iterator it = failureList.begin(); it != failureList.end(); it++) {
LOG("\n"); LOG("\n");
LOG(*it); LOG(*it);
LOG("\n");
} }
LOG("\n" << std::dec << testPasses << "/" << testCount << " tests passed\n");
LOG(std::dec << testPasses << "/" << testCount << " tests passed\n\n");
if (testPasses == testCount) { if (testPasses == testCount) {
return 0; return 0;
} }

View File

@ -1,11 +1,13 @@
#ifndef bddtest_h #ifndef bddtest_h
#define bddtest_h #define bddtest_h
void bddtest_suite(const char* name);
int bddtest_test(const char*, int, const char*, int); int bddtest_test(const char*, int, const char*, int);
void bddtest_start(const char*); void bddtest_start(const char*);
void bddtest_end(); void bddtest_end();
int bddtest_summary(); int bddtest_summary();
#define SUITE(x) { bddtest_suite(x); }
#define TEST(x) { if (!bddtest_test(__FILE__, __LINE__, #x, (x))) return false; } #define TEST(x) { if (!bddtest_test(__FILE__, __LINE__, #x, (x))) return false; }
#define IT(x) { bddtest_start(x); } #define IT(x) { bddtest_start(x); }

View File

@ -0,0 +1,44 @@
#include <Arduino.h>
#include <IPAddress.h>
IPAddress::IPAddress()
{
memset(_address, 0, sizeof(_address));
}
IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet)
{
_address[0] = first_octet;
_address[1] = second_octet;
_address[2] = third_octet;
_address[3] = fourth_octet;
}
IPAddress::IPAddress(uint32_t address)
{
memcpy(_address, &address, sizeof(_address));
}
IPAddress::IPAddress(const uint8_t *address)
{
memcpy(_address, address, sizeof(_address));
}
IPAddress& IPAddress::operator=(const uint8_t *address)
{
memcpy(_address, address, sizeof(_address));
return *this;
}
IPAddress& IPAddress::operator=(uint32_t address)
{
memcpy(_address, (const uint8_t *)&address, sizeof(_address));
return *this;
}
bool IPAddress::operator==(const uint8_t* addr)
{
return memcmp(addr, _address, sizeof(_address)) == 0;
}

View File

@ -1,11 +1,72 @@
/*
*
* MIT License:
* Copyright (c) 2011 Adrian McEwen
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* adrianm@mcqn.com 1/1/2011
*/
#ifndef IPAddress_h #ifndef IPAddress_h
#define IPAddress_h #define IPAddress_h
extern "C" {
#define IPAddress uint8_t* // A class to make it easier to handle and pass around IP addresses
} class IPAddress {
private:
uint8_t _address[4]; // IPv4 address
// Access the raw byte array containing the address. Because this returns a pointer
// to the internal structure rather than a copy of the address this function should only
// be used when you know that the usage of the returned uint8_t* will be transient and not
// stored.
uint8_t* raw_address() { return _address; };
public:
// Constructors
IPAddress();
IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet);
IPAddress(uint32_t address);
IPAddress(const uint8_t *address);
// Overloaded cast operator to allow IPAddress objects to be used where a pointer
// to a four-byte uint8_t array is expected
operator uint32_t() { return *((uint32_t*)_address); };
bool operator==(const IPAddress& addr) { return (*((uint32_t*)_address)) == (*((uint32_t*)addr._address)); };
bool operator==(const uint8_t* addr);
// Overloaded index operator to allow getting and setting individual octets of the address
uint8_t operator[](int index) const { return _address[index]; };
uint8_t& operator[](int index) { return _address[index]; };
// Overloaded copy operators to allow initialisation of IPAddress objects from other types
IPAddress& operator=(const uint8_t *address);
IPAddress& operator=(uint32_t address);
friend class EthernetClass;
friend class UDP;
friend class Client;
friend class Server;
friend class DhcpClass;
friend class DNSClient;
};
#endif #endif

View File

@ -26,10 +26,10 @@ int ShimClient::connect(IPAddress ip, uint16_t port) {
this->_connected = true; this->_connected = true;
} }
if (this->_expectedPort !=0) { if (this->_expectedPort !=0) {
if (memcmp(ip,this->_expectedIP,4) != 0) { // if (memcmp(ip,this->_expectedIP,4) != 0) {
TRACE( "ip mismatch\n"); // TRACE( "ip mismatch\n");
this->_error = true; // this->_error = true;
} // }
if (port != this->_expectedPort) { if (port != this->_expectedPort) {
TRACE( "port mismatch\n"); TRACE( "port mismatch\n");
this->_error = true; this->_error = true;
@ -80,7 +80,7 @@ size_t ShimClient::write(const uint8_t *buf, size_t size) {
TRACE(":"); TRACE(":");
} }
TRACE(std::hex << (unsigned int)(buf[i])); TRACE(std::hex << (unsigned int)(buf[i]));
if (!this->expectAnything) { if (!this->expectAnything) {
if (this->expectBuffer->available()) { if (this->expectBuffer->available()) {
uint8_t expected = this->expectBuffer->next(); uint8_t expected = this->expectBuffer->next();
@ -100,7 +100,7 @@ int ShimClient::available() {
return this->responseBuffer->available(); return this->responseBuffer->available();
} }
int ShimClient::read() { return this->responseBuffer->next(); } int ShimClient::read() { return this->responseBuffer->next(); }
int ShimClient::read(uint8_t *buf, size_t size) { int ShimClient::read(uint8_t *buf, size_t size) {
uint16_t i = 0; uint16_t i = 0;
for (;i<size;i++) { for (;i<size;i++) {
buf[i] = this->read(); buf[i] = this->read();
@ -151,4 +151,3 @@ void ShimClient::expectConnect(const char *host, uint16_t port) {
this->_expectedHost = host; this->_expectedHost = host;
this->_expectedPort = port; this->_expectedPort = port;
} }

View File

@ -15,20 +15,20 @@ int test_publish() {
IT("publishes a null-terminated string"); IT("publishes a null-terminated string");
ShimClient shimClient; ShimClient shimClient;
shimClient.setAllowConnect(true); shimClient.setAllowConnect(true);
byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.connect((char*)"client_test1"); int rc = client.connect((char*)"client_test1");
IS_TRUE(rc); IS_TRUE(rc);
byte publish[] = {0x30,0xe,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64}; byte publish[] = {0x30,0xe,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64};
shimClient.expect(publish,16); shimClient.expect(publish,16);
rc = client.publish((char*)"topic",(char*)"payload"); rc = client.publish((char*)"topic",(char*)"payload");
IS_TRUE(rc); IS_TRUE(rc);
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
END_IT END_IT
@ -39,23 +39,23 @@ int test_publish_bytes() {
IT("publishes a byte array"); IT("publishes a byte array");
ShimClient shimClient; ShimClient shimClient;
shimClient.setAllowConnect(true); shimClient.setAllowConnect(true);
byte payload[] = { 0x01,0x02,0x03,0x0,0x05 }; byte payload[] = { 0x01,0x02,0x03,0x0,0x05 };
int length = 5; int length = 5;
byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.connect((char*)"client_test1"); int rc = client.connect((char*)"client_test1");
IS_TRUE(rc); IS_TRUE(rc);
byte publish[] = {0x30,0xc,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x1,0x2,0x3,0x0,0x5}; byte publish[] = {0x30,0xc,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x1,0x2,0x3,0x0,0x5};
shimClient.expect(publish,14); shimClient.expect(publish,14);
rc = client.publish((char*)"topic",payload,length); rc = client.publish((char*)"topic",payload,length);
IS_TRUE(rc); IS_TRUE(rc);
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
END_IT END_IT
@ -66,23 +66,23 @@ int test_publish_retained() {
IT("publishes retained"); IT("publishes retained");
ShimClient shimClient; ShimClient shimClient;
shimClient.setAllowConnect(true); shimClient.setAllowConnect(true);
byte payload[] = { 0x01,0x02,0x03,0x0,0x05 }; byte payload[] = { 0x01,0x02,0x03,0x0,0x05 };
int length = 5; int length = 5;
byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.connect((char*)"client_test1"); int rc = client.connect((char*)"client_test1");
IS_TRUE(rc); IS_TRUE(rc);
byte publish[] = {0x31,0xc,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x1,0x2,0x3,0x0,0x5}; byte publish[] = {0x31,0xc,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x1,0x2,0x3,0x0,0x5};
shimClient.expect(publish,14); shimClient.expect(publish,14);
rc = client.publish((char*)"topic",payload,length,true); rc = client.publish((char*)"topic",payload,length,true);
IS_TRUE(rc); IS_TRUE(rc);
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
END_IT END_IT
@ -91,12 +91,12 @@ int test_publish_retained() {
int test_publish_not_connected() { int test_publish_not_connected() {
IT("publish fails when not connected"); IT("publish fails when not connected");
ShimClient shimClient; ShimClient shimClient;
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.publish((char*)"topic",(char*)"payload"); int rc = client.publish((char*)"topic",(char*)"payload");
IS_FALSE(rc); IS_FALSE(rc);
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
END_IT END_IT
@ -107,23 +107,23 @@ int test_publish_P() {
IT("publishes using PROGMEM"); IT("publishes using PROGMEM");
ShimClient shimClient; ShimClient shimClient;
shimClient.setAllowConnect(true); shimClient.setAllowConnect(true);
byte payload[] = { 0x01,0x02,0x03,0x0,0x05 }; byte payload[] = { 0x01,0x02,0x03,0x0,0x05 };
int length = 5; int length = 5;
byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.connect((char*)"client_test1"); int rc = client.connect((char*)"client_test1");
IS_TRUE(rc); IS_TRUE(rc);
byte publish[] = {0x31,0xc,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x1,0x2,0x3,0x0,0x5}; byte publish[] = {0x31,0xc,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x1,0x2,0x3,0x0,0x5};
shimClient.expect(publish,14); shimClient.expect(publish,14);
rc = client.publish_P((char*)"topic",payload,length,true); rc = client.publish_P((char*)"topic",payload,length,true);
IS_TRUE(rc); IS_TRUE(rc);
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
END_IT END_IT
@ -132,11 +132,12 @@ int test_publish_P() {
int main() int main()
{ {
SUITE("Publish");
test_publish(); test_publish();
test_publish_bytes(); test_publish_bytes();
test_publish_retained(); test_publish_retained();
test_publish_not_connected(); test_publish_not_connected();
test_publish_P(); test_publish_P();
FINISH FINISH
} }

View File

@ -29,29 +29,29 @@ void callback(char* topic, byte* payload, unsigned int length) {
int test_receive_callback() { int test_receive_callback() {
IT("receives a callback message"); IT("receives a callback message");
reset_callback(); reset_callback();
ShimClient shimClient; ShimClient shimClient;
shimClient.setAllowConnect(true); shimClient.setAllowConnect(true);
byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.connect((char*)"client_test1"); int rc = client.connect((char*)"client_test1");
IS_TRUE(rc); IS_TRUE(rc);
byte publish[] = {0x30,0xe,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64}; byte publish[] = {0x30,0xe,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64};
shimClient.respond(publish,16); shimClient.respond(publish,16);
rc = client.loop(); rc = client.loop();
IS_TRUE(rc); IS_TRUE(rc);
IS_TRUE(callback_called); IS_TRUE(callback_called);
IS_TRUE(strcmp(lastTopic,"topic")==0); IS_TRUE(strcmp(lastTopic,"topic")==0);
IS_TRUE(memcmp(lastPayload,"payload",7)==0); IS_TRUE(memcmp(lastPayload,"payload",7)==0);
IS_TRUE(lastLength == 7); IS_TRUE(lastLength == 7);
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
END_IT END_IT
@ -60,31 +60,31 @@ int test_receive_callback() {
int test_receive_stream() { int test_receive_stream() {
IT("receives a streamed callback message"); IT("receives a streamed callback message");
reset_callback(); reset_callback();
Stream stream; Stream stream;
stream.expect((uint8_t*)"payload",7); stream.expect((uint8_t*)"payload",7);
ShimClient shimClient; ShimClient shimClient;
shimClient.setAllowConnect(true); shimClient.setAllowConnect(true);
byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client(server, 1883, callback, shimClient, stream); PubSubClient client(server, 1883, callback, shimClient, stream);
int rc = client.connect((char*)"client_test1"); int rc = client.connect((char*)"client_test1");
IS_TRUE(rc); IS_TRUE(rc);
byte publish[] = {0x30,0xe,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64}; byte publish[] = {0x30,0xe,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64};
shimClient.respond(publish,16); shimClient.respond(publish,16);
rc = client.loop(); rc = client.loop();
IS_TRUE(rc); IS_TRUE(rc);
IS_TRUE(callback_called); IS_TRUE(callback_called);
IS_TRUE(strcmp(lastTopic,"topic")==0); IS_TRUE(strcmp(lastTopic,"topic")==0);
IS_TRUE(lastLength == 7); IS_TRUE(lastLength == 7);
IS_FALSE(stream.error()); IS_FALSE(stream.error());
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
@ -94,17 +94,17 @@ int test_receive_stream() {
int test_receive_max_sized_message() { int test_receive_max_sized_message() {
IT("receives an max-sized message"); IT("receives an max-sized message");
reset_callback(); reset_callback();
ShimClient shimClient; ShimClient shimClient;
shimClient.setAllowConnect(true); shimClient.setAllowConnect(true);
byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.connect((char*)"client_test1"); int rc = client.connect((char*)"client_test1");
IS_TRUE(rc); IS_TRUE(rc);
byte length = MQTT_MAX_PACKET_SIZE; 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 publish[] = {0x30,length-2,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64};
byte bigPublish[length]; byte bigPublish[length];
@ -112,16 +112,16 @@ int test_receive_max_sized_message() {
bigPublish[length] = 'B'; bigPublish[length] = 'B';
memcpy(bigPublish,publish,16); memcpy(bigPublish,publish,16);
shimClient.respond(bigPublish,length); shimClient.respond(bigPublish,length);
rc = client.loop(); rc = client.loop();
IS_TRUE(rc); IS_TRUE(rc);
IS_TRUE(callback_called); IS_TRUE(callback_called);
IS_TRUE(strcmp(lastTopic,"topic")==0); IS_TRUE(strcmp(lastTopic,"topic")==0);
IS_TRUE(lastLength == length-9); IS_TRUE(lastLength == length-9);
IS_TRUE(memcmp(lastPayload,bigPublish+9,lastLength)==0); IS_TRUE(memcmp(lastPayload,bigPublish+9,lastLength)==0);
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
END_IT END_IT
@ -130,17 +130,17 @@ int test_receive_max_sized_message() {
int test_receive_oversized_message() { int test_receive_oversized_message() {
IT("drops an oversized message"); IT("drops an oversized message");
reset_callback(); reset_callback();
ShimClient shimClient; ShimClient shimClient;
shimClient.setAllowConnect(true); shimClient.setAllowConnect(true);
byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.connect((char*)"client_test1"); int rc = client.connect((char*)"client_test1");
IS_TRUE(rc); IS_TRUE(rc);
byte length = MQTT_MAX_PACKET_SIZE+1; byte length = MQTT_MAX_PACKET_SIZE+1;
byte publish[] = {0x30,length-2,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64}; byte publish[] = {0x30,length-2,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64};
byte bigPublish[length]; byte bigPublish[length];
@ -148,13 +148,13 @@ int test_receive_oversized_message() {
bigPublish[length] = 'B'; bigPublish[length] = 'B';
memcpy(bigPublish,publish,16); memcpy(bigPublish,publish,16);
shimClient.respond(bigPublish,length); shimClient.respond(bigPublish,length);
rc = client.loop(); rc = client.loop();
IS_TRUE(rc); IS_TRUE(rc);
IS_FALSE(callback_called); IS_FALSE(callback_called);
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
END_IT END_IT
@ -163,38 +163,38 @@ int test_receive_oversized_message() {
int test_receive_oversized_stream_message() { int test_receive_oversized_stream_message() {
IT("drops an oversized message"); IT("drops an oversized message");
reset_callback(); reset_callback();
Stream stream; Stream stream;
ShimClient shimClient; ShimClient shimClient;
shimClient.setAllowConnect(true); shimClient.setAllowConnect(true);
byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client(server, 1883, callback, shimClient, stream); PubSubClient client(server, 1883, callback, shimClient, stream);
int rc = client.connect((char*)"client_test1"); int rc = client.connect((char*)"client_test1");
IS_TRUE(rc); IS_TRUE(rc);
byte length = MQTT_MAX_PACKET_SIZE+1; byte length = MQTT_MAX_PACKET_SIZE+1;
byte publish[] = {0x30,length-2,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64}; byte publish[] = {0x30,length-2,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64};
byte bigPublish[length]; byte bigPublish[length];
memset(bigPublish,'A',length); memset(bigPublish,'A',length);
bigPublish[length] = 'B'; bigPublish[length] = 'B';
memcpy(bigPublish,publish,16); memcpy(bigPublish,publish,16);
shimClient.respond(bigPublish,length); shimClient.respond(bigPublish,length);
stream.expect(bigPublish+9,length-9); stream.expect(bigPublish+9,length-9);
rc = client.loop(); rc = client.loop();
IS_TRUE(rc); IS_TRUE(rc);
IS_TRUE(callback_called); IS_TRUE(callback_called);
IS_TRUE(strcmp(lastTopic,"topic")==0); IS_TRUE(strcmp(lastTopic,"topic")==0);
IS_TRUE(lastLength == length-9); IS_TRUE(lastLength == length-9);
IS_FALSE(stream.error()); IS_FALSE(stream.error());
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
@ -204,32 +204,32 @@ int test_receive_oversized_stream_message() {
int test_receive_qos1() { int test_receive_qos1() {
IT("receives a qos1 message"); IT("receives a qos1 message");
reset_callback(); reset_callback();
ShimClient shimClient; ShimClient shimClient;
shimClient.setAllowConnect(true); shimClient.setAllowConnect(true);
byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.connect((char*)"client_test1"); int rc = client.connect((char*)"client_test1");
IS_TRUE(rc); IS_TRUE(rc);
byte publish[] = {0x32,0x10,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x12,0x34,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64}; byte publish[] = {0x32,0x10,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x12,0x34,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64};
shimClient.respond(publish,18); shimClient.respond(publish,18);
byte puback[] = {0x40,0x2,0x12,0x34}; byte puback[] = {0x40,0x2,0x12,0x34};
shimClient.expect(puback,4); shimClient.expect(puback,4);
rc = client.loop(); rc = client.loop();
IS_TRUE(rc); IS_TRUE(rc);
IS_TRUE(callback_called); IS_TRUE(callback_called);
IS_TRUE(strcmp(lastTopic,"topic")==0); IS_TRUE(strcmp(lastTopic,"topic")==0);
IS_TRUE(memcmp(lastPayload,"payload",7)==0); IS_TRUE(memcmp(lastPayload,"payload",7)==0);
IS_TRUE(lastLength == 7); IS_TRUE(lastLength == 7);
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
END_IT END_IT
@ -237,12 +237,13 @@ int test_receive_qos1() {
int main() int main()
{ {
SUITE("Receive");
test_receive_callback(); test_receive_callback();
test_receive_stream(); test_receive_stream();
test_receive_max_sized_message(); test_receive_max_sized_message();
test_receive_oversized_message(); test_receive_oversized_message();
test_receive_oversized_stream_message(); test_receive_oversized_stream_message();
test_receive_qos1(); test_receive_qos1();
FINISH FINISH
} }

View File

@ -20,7 +20,7 @@ int test_subscribe_no_qos() {
byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.connect((char*)"client_test1"); int rc = client.connect((char*)"client_test1");
IS_TRUE(rc); IS_TRUE(rc);
@ -29,10 +29,10 @@ int test_subscribe_no_qos() {
shimClient.expect(subscribe,12); shimClient.expect(subscribe,12);
byte suback[] = { 0x90,0x3,0x0,0x2,0x0 }; byte suback[] = { 0x90,0x3,0x0,0x2,0x0 };
shimClient.respond(suback,5); shimClient.respond(suback,5);
rc = client.subscribe((char*)"topic"); rc = client.subscribe((char*)"topic");
IS_TRUE(rc); IS_TRUE(rc);
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
END_IT END_IT
@ -45,7 +45,7 @@ int test_subscribe_qos_1() {
byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.connect((char*)"client_test1"); int rc = client.connect((char*)"client_test1");
IS_TRUE(rc); IS_TRUE(rc);
@ -54,10 +54,10 @@ int test_subscribe_qos_1() {
shimClient.expect(subscribe,12); shimClient.expect(subscribe,12);
byte suback[] = { 0x90,0x3,0x0,0x2,0x1 }; byte suback[] = { 0x90,0x3,0x0,0x2,0x1 };
shimClient.respond(suback,5); shimClient.respond(suback,5);
rc = client.subscribe((char*)"topic",1); rc = client.subscribe((char*)"topic",1);
IS_TRUE(rc); IS_TRUE(rc);
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
END_IT END_IT
@ -66,12 +66,12 @@ int test_subscribe_qos_1() {
int test_subscribe_not_connected() { int test_subscribe_not_connected() {
IT("subscribe fails when not connected"); IT("subscribe fails when not connected");
ShimClient shimClient; ShimClient shimClient;
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.subscribe((char*)"topic"); int rc = client.subscribe((char*)"topic");
IS_FALSE(rc); IS_FALSE(rc);
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
END_IT END_IT
@ -84,16 +84,16 @@ int test_subscribe_invalid_qos() {
byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.connect((char*)"client_test1"); int rc = client.connect((char*)"client_test1");
IS_TRUE(rc); IS_TRUE(rc);
rc = client.subscribe((char*)"topic",2); rc = client.subscribe((char*)"topic",2);
IS_FALSE(rc); IS_FALSE(rc);
rc = client.subscribe((char*)"topic",254); rc = client.subscribe((char*)"topic",254);
IS_FALSE(rc); IS_FALSE(rc);
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
END_IT END_IT
@ -106,7 +106,7 @@ int test_unsubscribe() {
byte connack[] = { 0x20, 0x02, 0x00, 0x00 }; byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
shimClient.respond(connack,4); shimClient.respond(connack,4);
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.connect((char*)"client_test1"); int rc = client.connect((char*)"client_test1");
IS_TRUE(rc); IS_TRUE(rc);
@ -115,10 +115,10 @@ int test_unsubscribe() {
shimClient.expect(unsubscribe,12); shimClient.expect(unsubscribe,12);
byte unsuback[] = { 0xB0,0x2,0x0,0x2 }; byte unsuback[] = { 0xB0,0x2,0x0,0x2 };
shimClient.respond(unsuback,4); shimClient.respond(unsuback,4);
rc = client.unsubscribe((char*)"topic"); rc = client.unsubscribe((char*)"topic");
IS_TRUE(rc); IS_TRUE(rc);
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
END_IT END_IT
@ -127,12 +127,12 @@ int test_unsubscribe() {
int test_unsubscribe_not_connected() { int test_unsubscribe_not_connected() {
IT("unsubscribe fails when not connected"); IT("unsubscribe fails when not connected");
ShimClient shimClient; ShimClient shimClient;
PubSubClient client(server, 1883, callback, shimClient); PubSubClient client(server, 1883, callback, shimClient);
int rc = client.unsubscribe((char*)"topic"); int rc = client.unsubscribe((char*)"topic");
IS_FALSE(rc); IS_FALSE(rc);
IS_FALSE(shimClient.error()); IS_FALSE(shimClient.error());
END_IT END_IT
@ -140,6 +140,7 @@ int test_unsubscribe_not_connected() {
int main() int main()
{ {
SUITE("Subscribe");
test_subscribe_no_qos(); test_subscribe_no_qos();
test_subscribe_qos_1(); test_subscribe_qos_1();
test_subscribe_not_connected(); test_subscribe_not_connected();