Add new unit tests
This commit is contained in:
parent
989ca99594
commit
011171cfc3
18
tests/Makefile
Normal file
18
tests/Makefile
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
SRC_PATH=./src
|
||||||
|
OUT_PATH=./bin
|
||||||
|
TEST_SRC=$(wildcard ${SRC_PATH}/*_spec.cpp)
|
||||||
|
TEST_BIN= $(TEST_SRC:${SRC_PATH}/%.cpp=${OUT_PATH}/%)
|
||||||
|
VPATH=${SRC_PATH}
|
||||||
|
SHIM_FILES=${SRC_PATH}/lib/*.cpp
|
||||||
|
PSC_FILE=../PubSubClient/PubSubClient.cpp
|
||||||
|
CC=g++
|
||||||
|
CFLAGS=-I${SRC_PATH}/lib -I../PubSubClient
|
||||||
|
|
||||||
|
all: $(TEST_BIN)
|
||||||
|
|
||||||
|
${OUT_PATH}/%: ${SRC_PATH}/%.cpp ${PSC_FILE} ${SHIM_FILES}
|
||||||
|
mkdir -p ${OUT_PATH}
|
||||||
|
${CC} ${CFLAGS} $^ -o $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -rf ${OUT_PATH}
|
187
tests/src/connect_spec.cpp
Normal file
187
tests/src/connect_spec.cpp
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
#include "PubSubClient.h"
|
||||||
|
#include "ShimClient.h"
|
||||||
|
#include "Buffer.h"
|
||||||
|
#include "BDDTest.h"
|
||||||
|
#include "trace.h"
|
||||||
|
|
||||||
|
|
||||||
|
byte server[] = { 172, 16, 0, 2 };
|
||||||
|
|
||||||
|
void callback(char* topic, byte* payload, unsigned int length) {
|
||||||
|
// handle message arrived
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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_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_properly_formatted() {
|
||||||
|
IT("sends a properly formatted connect packet and succeeds");
|
||||||
|
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");
|
||||||
|
IS_TRUE(rc);
|
||||||
|
IS_TRUE(shimClient.receivedExpected());
|
||||||
|
|
||||||
|
END_IT
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_connect_properly_formatted_hostname() {
|
||||||
|
IT("accepts a hostname");
|
||||||
|
ShimClient shimClient;
|
||||||
|
|
||||||
|
shimClient.setAllowConnect(true);
|
||||||
|
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);
|
||||||
|
|
||||||
|
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_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_TRUE(shimClient.receivedExpected());
|
||||||
|
|
||||||
|
END_IT
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_connect_accepts_username_no_password() {
|
||||||
|
IT("accepts a username but no password");
|
||||||
|
ShimClient shimClient;
|
||||||
|
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 connack[] = { 0x20, 0x02, 0x00, 0x00 };
|
||||||
|
shimClient.expect(connect,0x22);
|
||||||
|
shimClient.respond(connack,4);
|
||||||
|
|
||||||
|
PubSubClient client(server, 1883, callback, shimClient);
|
||||||
|
int rc = client.connect((char*)"client_test1",(char*)"user",'\0');
|
||||||
|
IS_TRUE(rc);
|
||||||
|
IS_TRUE(shimClient.receivedExpected());
|
||||||
|
|
||||||
|
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_TRUE(shimClient.receivedExpected());
|
||||||
|
|
||||||
|
END_IT
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_connect_with_will() {
|
||||||
|
IT("accepts a will");
|
||||||
|
ShimClient shimClient;
|
||||||
|
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 connack[] = { 0x20, 0x02, 0x00, 0x00 };
|
||||||
|
shimClient.expect(connect,0x34);
|
||||||
|
shimClient.respond(connack,4);
|
||||||
|
|
||||||
|
PubSubClient client(server, 1883, callback, shimClient);
|
||||||
|
int rc = client.connect((char*)"client_test1",(char*)"willTopic",1,0,(char*)"willMessage");
|
||||||
|
IS_TRUE(rc);
|
||||||
|
IS_TRUE(shimClient.receivedExpected());
|
||||||
|
|
||||||
|
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_TRUE(shimClient.receivedExpected());
|
||||||
|
|
||||||
|
END_IT
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test_connect_fails_no_network();
|
||||||
|
test_connect_fails_on_no_response();
|
||||||
|
test_connect_properly_formatted();
|
||||||
|
test_connect_fails_on_bad_rc();
|
||||||
|
test_connect_properly_formatted_hostname();
|
||||||
|
test_connect_accepts_username_password();
|
||||||
|
test_connect_accepts_username_no_password();
|
||||||
|
test_connect_ignores_password_no_username();
|
||||||
|
test_connect_with_will();
|
||||||
|
test_connect_with_will_username_password();
|
||||||
|
|
||||||
|
FINISH
|
||||||
|
}
|
22
tests/src/lib/Arduino.h
Normal file
22
tests/src/lib/Arduino.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef Arduino_h
|
||||||
|
#define Arduino_h
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
|
||||||
|
extern "C"{
|
||||||
|
typedef uint8_t byte ;
|
||||||
|
typedef uint8_t boolean ;
|
||||||
|
|
||||||
|
/* sketch */
|
||||||
|
extern void setup( void ) ;
|
||||||
|
extern void loop( void ) ;
|
||||||
|
uint32_t millis( void );
|
||||||
|
uint8_t pgm_read_byte_near(uint8_t*);
|
||||||
|
#define PROGMEM
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // Arduino_h
|
44
tests/src/lib/BDDTest.cpp
Normal file
44
tests/src/lib/BDDTest.cpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#include "BDDTest.h"
|
||||||
|
#include "trace.h"
|
||||||
|
#include <sstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
int testCount = 0;
|
||||||
|
int testPasses = 0;
|
||||||
|
const char* testDescription;
|
||||||
|
|
||||||
|
std::list<std::string> failureList;
|
||||||
|
|
||||||
|
int bddtest_test(const char* file, int line, const char* assertion, int result) {
|
||||||
|
if (!result) {
|
||||||
|
LOG("F");
|
||||||
|
std::ostringstream os;
|
||||||
|
os << " ! "<<testDescription<<"\n " <<file << ":" <<line<<" : "<<assertion<<" ["<<result<<"]";
|
||||||
|
failureList.push_back(os.str());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bddtest_start(const char* description) {
|
||||||
|
TRACE(" - "<<description << "\n");
|
||||||
|
testDescription = description;
|
||||||
|
testCount ++;
|
||||||
|
}
|
||||||
|
void bddtest_end() {
|
||||||
|
LOG(".");
|
||||||
|
testPasses ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bddtest_summary() {
|
||||||
|
for (std::list<std::string>::iterator it = failureList.begin(); it != failureList.end(); it++) {
|
||||||
|
LOG("\n");
|
||||||
|
LOG(*it);
|
||||||
|
}
|
||||||
|
LOG("\n" << std::dec << testPasses << "/" << testCount << " tests passed\n");
|
||||||
|
if (testPasses == testCount) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
21
tests/src/lib/BDDTest.h
Normal file
21
tests/src/lib/BDDTest.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#ifndef bddtest_h
|
||||||
|
#define bddtest_h
|
||||||
|
|
||||||
|
int bddtest_test(const char*, int, const char*, int);
|
||||||
|
void bddtest_start(const char*);
|
||||||
|
void bddtest_end();
|
||||||
|
int bddtest_summary();
|
||||||
|
|
||||||
|
#define TEST(x) { if (!bddtest_test(__FILE__, __LINE__, #x, (x))) return false; }
|
||||||
|
|
||||||
|
#define IT(x) { bddtest_start(x); }
|
||||||
|
#define END_IT { bddtest_end();return true;}
|
||||||
|
|
||||||
|
#define FINISH { return bddtest_summary(); }
|
||||||
|
|
||||||
|
#define IS_TRUE(x) TEST(x)
|
||||||
|
#define IS_FALSE(x) TEST(!(x))
|
||||||
|
#define IS_EQUAL(x,y) TEST(x==y)
|
||||||
|
#define IS_NOT_EQUAL(x,y) TEST(x!=y)
|
||||||
|
|
||||||
|
#endif
|
30
tests/src/lib/Buffer.cpp
Normal file
30
tests/src/lib/Buffer.cpp
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#include "Buffer.h"
|
||||||
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
Buffer::Buffer() {
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer::Buffer(uint8_t* buf, size_t size) {
|
||||||
|
this->add(buf,size);
|
||||||
|
}
|
||||||
|
bool Buffer::available() {
|
||||||
|
return this->pos < this->length;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t Buffer::next() {
|
||||||
|
if (this->available()) {
|
||||||
|
return this->buffer[this->pos++];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Buffer::reset() {
|
||||||
|
this->pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Buffer::add(uint8_t* buf, size_t size) {
|
||||||
|
uint16_t i = 0;
|
||||||
|
for (;i<size;i++) {
|
||||||
|
this->buffer[this->length++] = buf[i];
|
||||||
|
}
|
||||||
|
}
|
23
tests/src/lib/Buffer.h
Normal file
23
tests/src/lib/Buffer.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#ifndef buffer_h
|
||||||
|
#define buffer_h
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
class Buffer {
|
||||||
|
private:
|
||||||
|
uint8_t buffer[1024];
|
||||||
|
uint16_t pos;
|
||||||
|
uint16_t length;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Buffer();
|
||||||
|
Buffer(uint8_t* buf, size_t size);
|
||||||
|
|
||||||
|
virtual bool available();
|
||||||
|
virtual uint8_t next();
|
||||||
|
virtual void reset();
|
||||||
|
|
||||||
|
virtual void add(uint8_t* buf, size_t size);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
21
tests/src/lib/Client.h
Normal file
21
tests/src/lib/Client.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#ifndef client_h
|
||||||
|
#define client_h
|
||||||
|
#include "IPAddress.h"
|
||||||
|
|
||||||
|
class Client {
|
||||||
|
public:
|
||||||
|
virtual int connect(IPAddress ip, uint16_t port) =0;
|
||||||
|
virtual int connect(const char *host, uint16_t port) =0;
|
||||||
|
virtual size_t write(uint8_t) =0;
|
||||||
|
virtual size_t write(const uint8_t *buf, size_t size) =0;
|
||||||
|
virtual int available() = 0;
|
||||||
|
virtual int read() = 0;
|
||||||
|
virtual int read(uint8_t *buf, size_t size) = 0;
|
||||||
|
virtual int peek() = 0;
|
||||||
|
virtual void flush() = 0;
|
||||||
|
virtual void stop() = 0;
|
||||||
|
virtual uint8_t connected() = 0;
|
||||||
|
virtual operator bool() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
11
tests/src/lib/IPAddress.h
Normal file
11
tests/src/lib/IPAddress.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#ifndef IPAddress_h
|
||||||
|
#define IPAddress_h
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
#define IPAddress uint8_t*
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
108
tests/src/lib/ShimClient.cpp
Normal file
108
tests/src/lib/ShimClient.cpp
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
#include "ShimClient.h"
|
||||||
|
#include "trace.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
uint32_t millis(void) {
|
||||||
|
return time(0)*1000;
|
||||||
|
}
|
||||||
|
uint8_t pgm_read_byte_near(uint8_t*) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ShimClient::ShimClient() {
|
||||||
|
this->responseBuffer = new Buffer();
|
||||||
|
this->expectBuffer = new Buffer();
|
||||||
|
this->_allowConnect = true;
|
||||||
|
this->_connected = false;
|
||||||
|
this->_receivedExpected = true;
|
||||||
|
this->expectAnything = true;
|
||||||
|
this->_received = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ShimClient::connect(IPAddress ip, uint16_t port) {
|
||||||
|
if (this->_allowConnect) {
|
||||||
|
this->_connected = true;
|
||||||
|
}
|
||||||
|
return this->_connected;
|
||||||
|
}
|
||||||
|
int ShimClient::connect(const char *host, uint16_t port) {
|
||||||
|
if (this->_allowConnect) {
|
||||||
|
this->_connected = true;
|
||||||
|
}
|
||||||
|
return this->_connected;
|
||||||
|
}
|
||||||
|
size_t ShimClient::write(uint8_t b) { std::cout << "!!not implemented!! " << b; return 1; }
|
||||||
|
size_t ShimClient::write(const uint8_t *buf, size_t size) {
|
||||||
|
this->_received += size;
|
||||||
|
TRACE( "[" << std::dec << (unsigned int)(size) << "] ");
|
||||||
|
uint16_t i=0;
|
||||||
|
for (;i<size;i++) {
|
||||||
|
if (i>0) {
|
||||||
|
TRACE(":");
|
||||||
|
}
|
||||||
|
TRACE(std::hex << (unsigned int)(buf[i]));
|
||||||
|
|
||||||
|
if (!this->expectAnything) {
|
||||||
|
if (this->expectBuffer->available()) {
|
||||||
|
uint8_t expected = this->expectBuffer->next();
|
||||||
|
if (expected != buf[i]) {
|
||||||
|
TRACE("!=" << (unsigned int)expected);
|
||||||
|
this->_receivedExpected = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this->_receivedExpected = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TRACE("\n");
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
int ShimClient::available() {
|
||||||
|
return this->responseBuffer->available();
|
||||||
|
}
|
||||||
|
int ShimClient::read() { return this->responseBuffer->next(); }
|
||||||
|
int ShimClient::read(uint8_t *buf, size_t size) {
|
||||||
|
uint16_t i = 0;
|
||||||
|
for (;i<size;i++) {
|
||||||
|
buf[i] = this->read();
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
int ShimClient::peek() { return 0; }
|
||||||
|
void ShimClient::flush() {}
|
||||||
|
void ShimClient::stop() {
|
||||||
|
this->setConnected(false);
|
||||||
|
}
|
||||||
|
uint8_t ShimClient::connected() { return this->_connected; }
|
||||||
|
ShimClient::operator bool() { return true; }
|
||||||
|
|
||||||
|
|
||||||
|
ShimClient* ShimClient::respond(uint8_t *buf, size_t size) {
|
||||||
|
this->responseBuffer->add(buf,size);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ShimClient* ShimClient::expect(uint8_t *buf, size_t size) {
|
||||||
|
this->expectAnything = false;
|
||||||
|
this->expectBuffer->add(buf,size);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShimClient::setConnected(bool b) {
|
||||||
|
this->_connected = b;
|
||||||
|
}
|
||||||
|
void ShimClient::setAllowConnect(bool b) {
|
||||||
|
this->_allowConnect = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShimClient::receivedExpected() {
|
||||||
|
return !this->expectBuffer->available() && this->_receivedExpected;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t ShimClient::received() {
|
||||||
|
return this->_received;
|
||||||
|
}
|
44
tests/src/lib/ShimClient.h
Normal file
44
tests/src/lib/ShimClient.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#ifndef shimclient_h
|
||||||
|
#define shimclient_h
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
#include "Client.h"
|
||||||
|
#include "IPAddress.h"
|
||||||
|
#include "Buffer.h"
|
||||||
|
|
||||||
|
|
||||||
|
class ShimClient : public Client {
|
||||||
|
private:
|
||||||
|
Buffer* responseBuffer;
|
||||||
|
Buffer* expectBuffer;
|
||||||
|
bool _allowConnect;
|
||||||
|
bool _connected;
|
||||||
|
bool expectAnything;
|
||||||
|
bool _receivedExpected;
|
||||||
|
uint16_t _received;
|
||||||
|
public:
|
||||||
|
ShimClient();
|
||||||
|
virtual int connect(IPAddress ip, uint16_t port);
|
||||||
|
virtual int connect(const char *host, uint16_t port);
|
||||||
|
virtual size_t write(uint8_t);
|
||||||
|
virtual size_t write(const uint8_t *buf, size_t size);
|
||||||
|
virtual int available();
|
||||||
|
virtual int read();
|
||||||
|
virtual int read(uint8_t *buf, size_t size);
|
||||||
|
virtual int peek();
|
||||||
|
virtual void flush();
|
||||||
|
virtual void stop();
|
||||||
|
virtual uint8_t connected();
|
||||||
|
virtual operator bool();
|
||||||
|
|
||||||
|
virtual ShimClient* respond(uint8_t *buf, size_t size);
|
||||||
|
virtual ShimClient* expect(uint8_t *buf, size_t size);
|
||||||
|
|
||||||
|
virtual uint16_t received();
|
||||||
|
virtual bool receivedExpected();
|
||||||
|
|
||||||
|
virtual void setAllowConnect(bool b);
|
||||||
|
virtual void setConnected(bool b);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
93
tests/src/lib/Stream.h
Normal file
93
tests/src/lib/Stream.h
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
Stream.h - base class for character-based streams.
|
||||||
|
Copyright (c) 2010 David A. Mellis. All right reserved.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
parsing functions based on TextFinder library by Michael Margolis
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef Stream_h
|
||||||
|
#define Stream_h
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
// compatability macros for testing
|
||||||
|
/*
|
||||||
|
#define getInt() parseInt()
|
||||||
|
#define getInt(skipChar) parseInt(skipchar)
|
||||||
|
#define getFloat() parseFloat()
|
||||||
|
#define getFloat(skipChar) parseFloat(skipChar)
|
||||||
|
#define getString( pre_string, post_string, buffer, length)
|
||||||
|
readBytesBetween( pre_string, terminator, buffer, length)
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Stream
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read
|
||||||
|
unsigned long _startMillis; // used for timeout measurement
|
||||||
|
int timedRead(); // private method to read stream with timeout
|
||||||
|
int timedPeek(); // private method to peek stream with timeout
|
||||||
|
int peekNextDigit(); // returns the next numeric digit in the stream or -1 if timeout
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual int available() = 0;
|
||||||
|
virtual int read() = 0;
|
||||||
|
virtual int peek() = 0;
|
||||||
|
virtual void flush() = 0;
|
||||||
|
virtual size_t write(uint8_t) = 0;
|
||||||
|
|
||||||
|
Stream() {_timeout=1000;}
|
||||||
|
|
||||||
|
// parsing methods
|
||||||
|
|
||||||
|
void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second
|
||||||
|
|
||||||
|
bool find(char *target); // reads data from the stream until the target string is found
|
||||||
|
// returns true if target string is found, false if timed out (see setTimeout)
|
||||||
|
|
||||||
|
bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found
|
||||||
|
// returns true if target string is found, false if timed out
|
||||||
|
|
||||||
|
bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found
|
||||||
|
|
||||||
|
bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found
|
||||||
|
|
||||||
|
|
||||||
|
long parseInt(); // returns the first valid (long) integer value from the current position.
|
||||||
|
// initial characters that are not digits (or the minus sign) are skipped
|
||||||
|
// integer is terminated by the first character that is not a digit.
|
||||||
|
|
||||||
|
float parseFloat(); // float version of parseInt
|
||||||
|
|
||||||
|
size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
|
||||||
|
// terminates if length characters have been read or timeout (see setTimeout)
|
||||||
|
// returns the number of characters placed in the buffer (0 means no valid data found)
|
||||||
|
|
||||||
|
size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character
|
||||||
|
// terminates if length characters have been read, timeout, or if the terminator character detected
|
||||||
|
// returns the number of characters placed in the buffer (0 means no valid data found)
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
long parseInt(char skipChar); // as above but the given skipChar is ignored
|
||||||
|
// as above but the given skipChar is ignored
|
||||||
|
// this allows format characters (typically commas) in values to be ignored
|
||||||
|
|
||||||
|
float parseFloat(char skipChar); // as above but the given skipChar is ignored
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
10
tests/src/lib/trace.h
Normal file
10
tests/src/lib/trace.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef trace_h
|
||||||
|
#define trace_h
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define LOG(x) {std::cout << x << std::flush; }
|
||||||
|
#define TRACE(x) {if (getenv("TRACE")) { std::cout << x << std::flush; }}
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user