JSON and Tasmota HTTP unit testing...

This commit is contained in:
openshwprojects
2022-11-17 09:42:19 +01:00
parent 999cfa48fb
commit ffc266531e
3 changed files with 273 additions and 10 deletions

View File

@@ -440,13 +440,14 @@ int postany(http_request_t* request, const char* str, int len) {
if (NULL == str) {
// fd will be NULL for unit tests where HTTP packet is faked locally
if (request->fd != 0) {
if (request->replylen > 0) {
send(request->fd, request->reply, request->replylen, 0);
}
request->reply[0] = 0;
request->replylen = 0;
if (request->fd == 0) {
return request->replylen;
}
if (request->replylen > 0) {
send(request->fd, request->reply, request->replylen, 0);
}
request->reply[0] = 0;
request->replylen = 0;
return 0;
}

View File

@@ -2,6 +2,9 @@
#include "selftest_local.h"
#include "../httpserver/new_http.h"
//#define JSMN_HEADER
///#include "../jsmn/jsmn.h"
#include "../cJSON/cJSON.h"
// "GET /index?tgl=1 HTTP/1.1\r\n"
const char *http_get_template1 = "GET /%s HTTP/1.1\r\n"
@@ -21,6 +24,10 @@ const char *http_get_template1 = "GET /%s HTTP/1.1\r\n"
"\r\n"
"\r\n";
//jsmn_parser parser;
cJSON *g_json;
cJSON *g_sec_power;
const char *Helper_GetPastHTTPHeader(const char *s) {
while (*s) {
if (!strncmp(s, "\r\n\r\n",4)) {
@@ -30,12 +37,15 @@ const char *Helper_GetPastHTTPHeader(const char *s) {
}
return 0;
}
static char outbuf[8192];
static char buffer[8192];
static const char *replyAt;
//static jsmntok_t tokens[256]; /* We expect no more than qq JSON tokens */
void Test_FakeHTTPClientPacket(const char *tg) {
int iResult;
int len;
const char *replyAt;
http_request_t request;
@@ -57,22 +67,272 @@ void Test_FakeHTTPClientPacket(const char *tg) {
printf("Test_FakeHTTPClientPacket fake bytes sent: %d \n", iResult);
len = HTTP_ProcessPacket(&request);
outbuf[request.replylen] = 0;
printf("Test_FakeHTTPClientPacket fake bytes received: %d \n", len);
replyAt = Helper_GetPastHTTPHeader(outbuf);
}
void Test_Http() {
void Test_FakeHTTPClientPacket_JSON(const char *tg) {
int r;
Test_FakeHTTPClientPacket(tg);
//jsmn_init(&parser);
//r = jsmn_parse(&parser, replyAt, strlen(replyAt), tokens, 256);
if (g_json) {
cJSON_Delete(g_json);
}
g_json = cJSON_Parse(replyAt);
g_sec_power = cJSON_GetObjectItemCaseSensitive(g_json, "POWER");
}
cJSON *Test_GetJSONValue_Generic(const char *keyword, const char *obj) {
cJSON *tmp;
cJSON *parent;
if (obj == 0 || obj[0] == 0) {
parent = g_json;
}
else {
parent = cJSON_GetObjectItemCaseSensitive(g_json, obj);
}
if (parent == 0)
return 0;
tmp = cJSON_GetObjectItemCaseSensitive(parent, keyword);
if (tmp == 0)
return 0;
return tmp;
}
const char *Test_GetJSONValue_Integer(const char *keyword, const char *obj) {
cJSON *tmp;
tmp = Test_GetJSONValue_Generic(keyword, obj);
if (tmp == 0) {
return -999999;
}
printf("Test_GetJSONValue_Integer will return %i for %s\n", tmp->valueint, keyword);
return tmp->valueint;
}
const char *Test_GetJSONValue_String(const char *keyword, const char *obj) {
cJSON *tmp;
tmp = Test_GetJSONValue_Generic(keyword, obj);
if (tmp == 0) {
return "";
}
printf("Test_GetJSONValue_String will return %s for %s\n", tmp->valuestring, keyword);
return tmp->valuestring;
}
void Test_Http_SingleRelayOnChannel1() {
CMD_ExecuteCommand("clearAll", 0);
PIN_SetPinRoleForPinIndex(9, IOR_Relay);
PIN_SetPinChannelForPinIndex(9, 1);
Test_FakeHTTPClientPacket_JSON("cm?cmnd=POWER");
SELFTEST_ASSERT_JSON_VALUE_STRING(0, "POWER", "OFF");
Test_FakeHTTPClientPacket("index?tgl=1");
Test_FakeHTTPClientPacket("cm?cmnd=POWER");
// read power
Test_FakeHTTPClientPacket_JSON("cm?cmnd=POWER");
SELFTEST_ASSERT_JSON_VALUE_STRING(0, "POWER", "ON");
Test_FakeHTTPClientPacket("cm?cmnd=STATUS");
// set power ON
Test_FakeHTTPClientPacket_JSON("cm?cmnd=POWER%20ON");
SELFTEST_ASSERT_JSON_VALUE_STRING(0, "POWER", "ON");
// set power OFF
Test_FakeHTTPClientPacket_JSON("cm?cmnd=POWER%20OFF");
SELFTEST_ASSERT_JSON_VALUE_STRING(0, "POWER", "OFF");
// set power OFF
Test_FakeHTTPClientPacket_JSON("cm?cmnd=POWER%20OFF");
SELFTEST_ASSERT_JSON_VALUE_STRING(0, "POWER", "OFF");
// In STATUS register, power is encoded as integer...
Test_FakeHTTPClientPacket_JSON("cm?cmnd=STATUS");
SELFTEST_ASSERT_JSON_VALUE_INTEGER("Status", "Power", 0);
// set power ON
Test_FakeHTTPClientPacket_JSON("cm?cmnd=POWER%20ON");
SELFTEST_ASSERT_JSON_VALUE_STRING(0, "POWER", "ON");
// In STATUS register, power is encoded as integer...
Test_FakeHTTPClientPacket_JSON("cm?cmnd=STATUS");
SELFTEST_ASSERT_JSON_VALUE_INTEGER("Status", "Power", 1);
}
void Test_Http_TwoRelays() {
CMD_ExecuteCommand("clearAll", 0);
PIN_SetPinRoleForPinIndex(9, IOR_Relay);
PIN_SetPinChannelForPinIndex(9, 1);
PIN_SetPinRoleForPinIndex(10, IOR_Relay);
PIN_SetPinChannelForPinIndex(10, 2);
// Channel 1 Off
// Channel 2 Off
// In STATUS register, power is encoded as integer...
Test_FakeHTTPClientPacket_JSON("cm?cmnd=STATUS");
SELFTEST_ASSERT_JSON_VALUE_INTEGER("Status", "Power", 0);
Test_FakeHTTPClientPacket("index?tgl=1");
// Channel 1 On
// Channel 2 Off
// In STATUS register, power is encoded as integer...
Test_FakeHTTPClientPacket_JSON("cm?cmnd=STATUS");
SELFTEST_ASSERT_JSON_VALUE_INTEGER("Status", "Power", 0b1);
Test_FakeHTTPClientPacket("index?tgl=2");
// Channel 1 On
// Channel 2 On
// In STATUS register, power is encoded as integer...
Test_FakeHTTPClientPacket_JSON("cm?cmnd=STATUS");
SELFTEST_ASSERT_JSON_VALUE_INTEGER("Status", "Power", 0b11);
Test_FakeHTTPClientPacket("index?tgl=1");
// Channel 1 Off
// Channel 2 On
// In STATUS register, power is encoded as integer...
Test_FakeHTTPClientPacket_JSON("cm?cmnd=STATUS");
SELFTEST_ASSERT_JSON_VALUE_INTEGER("Status", "Power", 0b10);
}
void Test_Http_FourRelays() {
CMD_ExecuteCommand("clearAll", 0);
PIN_SetPinRoleForPinIndex(9, IOR_Relay);
PIN_SetPinChannelForPinIndex(9, 1);
PIN_SetPinRoleForPinIndex(10, IOR_Relay);
PIN_SetPinChannelForPinIndex(10, 2);
PIN_SetPinRoleForPinIndex(11, IOR_Relay);
PIN_SetPinChannelForPinIndex(11, 3);
PIN_SetPinRoleForPinIndex(12, IOR_Relay);
PIN_SetPinChannelForPinIndex(12, 4);
// Channel 1 Off
// Channel 2 Off
// Channel 3 Off
// Channel 4 Off
// In STATUS register, power is encoded as integer...
Test_FakeHTTPClientPacket_JSON("cm?cmnd=STATUS");
SELFTEST_ASSERT_JSON_VALUE_INTEGER("Status", "Power", 0);
Test_FakeHTTPClientPacket("index?tgl=3");
// Channel 1 Off
// Channel 2 Off
// Channel 3 On
// Channel 4 Off
// In STATUS register, power is encoded as integer...
Test_FakeHTTPClientPacket_JSON("cm?cmnd=STATUS");
SELFTEST_ASSERT_JSON_VALUE_INTEGER("Status", "Power", 0b0100);
Test_FakeHTTPClientPacket("index?tgl=2");
// Channel 1 Off
// Channel 2 On
// Channel 3 On
// Channel 4 Off
// In STATUS register, power is encoded as integer...
Test_FakeHTTPClientPacket_JSON("cm?cmnd=STATUS");
SELFTEST_ASSERT_JSON_VALUE_INTEGER("Status", "Power", 0b0110);
Test_FakeHTTPClientPacket("index?tgl=4");
// Channel 1 Off
// Channel 2 On
// Channel 3 On
// Channel 4 On
// In STATUS register, power is encoded as integer...
Test_FakeHTTPClientPacket_JSON("cm?cmnd=STATUS");
SELFTEST_ASSERT_JSON_VALUE_INTEGER("Status", "Power", 0b1110);
}
/*
StatusSTS sample from Tasmota:
"StatusSTS":{
"Time":"2022-11-17T09:35:58",
"Uptime":"5T11:36:54",
"UptimeSec":473814,
"Heap":24,
"SleepMode":"Dynamic",
"Sleep":10,
"LoadAvg":99,
"MqttCount":3,
"POWER":"ON",
"Dimmer":80,
"Color":"144,114,204",
"HSBColor":"260,44,80",
"Channel":[
57,
45,
80
],
"Scheme":0,
"Fade":"OFF",
"Speed":1,
"LedTable":"ON",
"Wifi":{
"AP":1,
"SSId":"DLINK_FastNet",
"BSSId":"30:B5:C2:5D:70:72",
"Channel":11,
"Mode":"11n",
"RSSI":54,
"Signal":-73,
"LinkCount":1,
"Downtime":"0T00:00:03"
}
}
*/
void Test_Http_LED_SingleChannel() {
CMD_ExecuteCommand("clearAll", 0);
PIN_SetPinRoleForPinIndex(24, IOR_PWM);
PIN_SetPinChannelForPinIndex(24, 1);
CMD_ExecuteCommand("led_enableAll 1", 0);
CMD_ExecuteCommand("led_dimmer 100", 0);
// StatusSTS contains POWER and Dimmer
Test_FakeHTTPClientPacket_JSON("cm?cmnd=STATUS");
SELFTEST_ASSERT_JSON_VALUE_INTEGER("StatusSTS", "Dimmer", 100);
SELFTEST_ASSERT_JSON_VALUE_STRING("StatusSTS", "POWER", "ON");
CMD_ExecuteCommand("led_enableAll 0", 0);
// StatusSTS contains POWER and Dimmer
Test_FakeHTTPClientPacket_JSON("cm?cmnd=STATUS");
SELFTEST_ASSERT_JSON_VALUE_INTEGER("StatusSTS", "Dimmer", 100);
SELFTEST_ASSERT_JSON_VALUE_STRING("StatusSTS", "POWER", "OFF");
CMD_ExecuteCommand("led_dimmer 61", 0);
// StatusSTS contains POWER and Dimmer
Test_FakeHTTPClientPacket_JSON("cm?cmnd=STATUS");
SELFTEST_ASSERT_JSON_VALUE_INTEGER("StatusSTS", "Dimmer", 61);
SELFTEST_ASSERT_JSON_VALUE_STRING("StatusSTS", "POWER", "OFF");
CMD_ExecuteCommand("led_enableAll 1", 0);
// StatusSTS contains POWER and Dimmer
Test_FakeHTTPClientPacket_JSON("cm?cmnd=STATUS");
SELFTEST_ASSERT_JSON_VALUE_INTEGER("StatusSTS", "Dimmer", 61);
SELFTEST_ASSERT_JSON_VALUE_STRING("StatusSTS", "POWER", "ON");
}
void Test_Http() {
Test_Http_SingleRelayOnChannel1();
Test_Http_TwoRelays();
Test_Http_FourRelays();
Test_Http_LED_SingleChannel();
}

View File

@@ -17,6 +17,8 @@ void SelfTest_Failed(const char *file, int line, const char *exp);
#define SELFTEST_ASSERT_ARGUMENT(argumentIndex, res) SELFTEST_ASSERT(!strcmp(Tokenizer_GetArg(argumentIndex), res));
#define SELFTEST_ASSERT_ARGUMENT_INTEGER(argumentIndex, res) SELFTEST_ASSERT((Tokenizer_GetArgInteger(argumentIndex)== res));
#define SELFTEST_ASSERT_ARGUMENTS_COUNT(wantedCount) SELFTEST_ASSERT((Tokenizer_GetArgsCount()==wantedCount));
#define SELFTEST_ASSERT_JSON_VALUE_STRING(obj, varName, res) SELFTEST_ASSERT(!strcmp(Test_GetJSONValue_String(varName,obj), res));
#define SELFTEST_ASSERT_JSON_VALUE_INTEGER(obj, varName, res) SELFTEST_ASSERT((Test_GetJSONValue_Integer(varName,obj) == res));
//#define FLOAT_EQUALS (a,b) (abs(a-b)<0.001f)
inline bool Float_Equals(float a, float b) {