#include "MockDtypes.h" #include "MockSerial.h" #include "MeasurementSession.h" #include "MockStorage.h" #include #include template std::vector parseMessagePack(const uint8_t * data, uint32_t &startTime, uint32_t &startIndex) { int offset = 0; // map header const int expectedMapSize = 3; auto mapHeader = reinterpret_cast(&data[offset]); offset += 1; TEST_ASSERT_MESSAGE( *mapHeader == (0b10000000 | expectedMapSize), "Map Header wrong"); // string255: sessionStartTime auto stringHeader = reinterpret_cast(&data[offset++]); auto stringSize = reinterpret_cast(&data[offset++]); TEST_ASSERT_EQUAL(*stringHeader, '\xd9'); std::string sessionStartTimeStr = std::string((const char*)(&data[offset]), (size_t)(*stringSize)); TEST_ASSERT( sessionStartTimeStr == "sessionStartTime"); offset += *stringSize; //uint32 auto intCode = reinterpret_cast(&data[offset++]); startTime = ntohl(*reinterpret_cast(&data[offset])); offset += 4; // string255: startIndex stringHeader = reinterpret_cast(&data[offset++]); stringSize = reinterpret_cast(&data[offset++]); TEST_ASSERT_MESSAGE(*stringHeader == '\xd9', "String header wrong"); std::string startIndexStr = std::string((const char*)(&data[offset]), (size_t)(*stringSize)); TEST_ASSERT_MESSAGE( startIndexStr == "startIndex", "startIndex string is wrong"); offset += *stringSize; //uint32 intCode = reinterpret_cast(&data[offset++]); startIndex = ntohl(*reinterpret_cast(&data[offset])); offset += 4; // string255: values stringHeader = reinterpret_cast(&data[offset++]); stringSize = reinterpret_cast(&data[offset++]); TEST_ASSERT_MESSAGE(*stringHeader == '\xd9', "String header wrong"); std::string valueStr = std::string((const char*)(&data[offset]), (size_t)(*stringSize)); TEST_ASSERT_MESSAGE( valueStr == "values", "values string is wrong"); offset += *stringSize; // vector auto vectorHeader = reinterpret_cast(&data[offset++]); TEST_ASSERT_MESSAGE( *vectorHeader == '\xc9', "Vector header wrong"); size_t vectorLength = ntohl(*reinterpret_cast(&data[offset])) / sizeof(Measurement_T); offset += 4; offset += 1; // jump over type auto vectorData = reinterpret_cast(&data[offset]); return std::vector(vectorData, vectorData + vectorLength); } void testSessionChunkAdd() { const uint_t size = 16; SessionChunk chunk; for( uint16_t i=0; i < size; ++i) { bool res = chunk.addPoint(i); TEST_ASSERT_MESSAGE(res, "Adding point failed"); TEST_ASSERT_MESSAGE( chunk.numMeasurements() == i+1, "Number of measurements reported wrong"); } bool res = chunk.addPoint(0); TEST_ASSERT_MESSAGE(!res, "Full chunk was not detected"); TEST_ASSERT_MESSAGE(chunk.numMeasurements() == size, "Point appears to be added"); } void testSessionChunkGetterSetter() { const uint_t size = 16; SessionChunk chunk; const uint32_t time = 244213; const uint32_t startIdx = 131; chunk.init(time, startIdx); TEST_ASSERT_MESSAGE( chunk.getStartIndex() == startIdx, "Start Index wrong"); TEST_ASSERT_MESSAGE( chunk.getStartTime() == time, "Start time wrong"); } void testSessionChunkSerialization() { const uint_t size = 16; const uint32_t startTime = 194232; const uint32_t startIndex = 1314; const uint_t fillSize = 12; SessionChunk chunk; chunk.init(startTime, startIndex); for( uint16_t i=0; i < fillSize; ++i) { bool res = chunk.addPoint(i); TEST_ASSERT_MESSAGE(res, "Adding point failed"); TEST_ASSERT_MESSAGE( chunk.numMeasurements() == i+1, "Number of measurements reported wrong"); } std::vector data; VectorAdaptor adaptor( &data ); StreamingMsgPackEncoder encoder(&adaptor); chunk.serialize(encoder); uint32_t readStartTime=0; uint32_t readStartIndex=0; auto result = parseMessagePack(&data[0], readStartTime, readStartIndex); TEST_ASSERT_MESSAGE(startIndex == readStartIndex && startTime == readStartTime, ""); TEST_ASSERT_MESSAGE(result.size() == fillSize, "Wrong result array size"); for( uint16_t i=0; i < fillSize; ++i) { TEST_ASSERT_MESSAGE(result[i] == i, "Wrong array contents"); } } void testSession() { const uint32_t SESSION_SIZE = 128; typedef MeasurementSession MockSession; const uint32_t startTime = 194842; const uint_t fillSize = SESSION_SIZE * 4 + 7; MockSession session; session.init(startTime); for (uint16_t i = 0; i < fillSize; ++i) { session.addPoint(i); } std::vector data; VectorAdaptor adaptor( &data ); StreamingMsgPackEncoder encoder(&adaptor); session.serialize(encoder, 0); uint32_t readStartTime=0; uint32_t readStartIndex=0; auto result = parseMessagePack(&data[0], readStartTime, readStartIndex); TEST_ASSERT_MESSAGE(readStartIndex == 0 && startTime == readStartTime, ""); TEST_ASSERT_MESSAGE(result.size() == fillSize, "Wrong result array size"); for( uint16_t i=0; i < fillSize; ++i) { TEST_ASSERT_MESSAGE(result[i] == i, "Wrong array contents"); } } void testPartialSessionSerialization() { const uint32_t SESSION_SIZE = 128; typedef MeasurementSession MockSession; const uint32_t startTime = 194842; const uint_t fillSize = SESSION_SIZE * 4 + 7; MockSession session; session.init(startTime); for (uint16_t i = 0; i < fillSize; ++i) { session.addPoint(i); } std::vector data; VectorAdaptor adaptor( &data ); StreamingMsgPackEncoder encoder(&adaptor); encoder.setSizeCountMode(true); session.serialize(encoder, 0); auto totalSize = encoder.getContentLength(); std::vector splits = {16, 32, 128, 256, 512, 721, 1024, totalSize}; uint32_t written = 0; data.clear(); for(auto & split : splits) { ChunkedStreamingMsgPackEncoder encoder(&adaptor, written, split); session.serialize(encoder, 0); written = encoder.sentBytes(); } uint32_t readStartTime=0; uint32_t readStartIndex=0; auto result = parseMessagePack(&data[0], readStartTime, readStartIndex); TEST_ASSERT_MESSAGE(readStartIndex == 0 && startTime == readStartTime, ""); TEST_ASSERT_MESSAGE(result.size() == fillSize, "Wrong result array size"); for( uint16_t i=0; i < fillSize; ++i) { TEST_ASSERT_MESSAGE(result[i] == i, "Wrong array contents"); } } void allTests() { UNITY_BEGIN(); RUN_TEST(testSessionChunkAdd); RUN_TEST(testSessionChunkGetterSetter); RUN_TEST(testSessionChunkSerialization); RUN_TEST(testSession); RUN_TEST(testPartialSessionSerialization); UNITY_END(); } #ifdef ARDUINO void setup() { // NOTE!!! Wait for >2 secs // if board doesn't support software reset via Serial.DTR/RTS delay(2000); allTests(); } void loop() { } #else int main(int argc, char**argv) { allTests(); return 0; } #endif