// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include #include "RandomStringGenerator.hpp" #include "LoggerBuffer.hpp" #include #include using namespace std; void TestBuffer(const LoggerBuffer &buffer, size_t capacity, size_t numOfMsgs) { const bool isEmpty = buffer.isEmpty(); REQUIRE((numOfMsgs == 0 ? isEmpty : !isEmpty)); const bool isFull = buffer.isFull(); REQUIRE((capacity > 0 && capacity == numOfMsgs ? isFull : !isFull)); REQUIRE(buffer.getCapacity() == capacity); REQUIRE(buffer.getSize() == numOfMsgs); } size_t GetNumOfBytes(vector::const_iterator startIt, vector::const_iterator endIt) { size_t numOfBytes = 0; for (; startIt != endIt; ++startIt) { numOfBytes += startIt->length(); } return numOfBytes; } TEST_CASE("LoggerBuffer tests") { const size_t capacity = 100; LoggerBuffer buffer(capacity); RandomStringGenerator randomStringGenerator; auto putMsgFunc = [&](const auto &msg) { buffer.put(msg); }; auto getMsgFunc = [&](const auto &originalMsg) { const auto [result, msg] = buffer.get(); REQUIRE(result); REQUIRE(msg == originalMsg); }; auto putAllMsgsFunc = [&](const vector &msgs) { for_each(msgs.begin(), msgs.end(), putMsgFunc); }; auto getAllMsgsFunc = [&](const vector &msgs) { for_each(msgs.begin(), msgs.end(), getMsgFunc); }; auto checkLostBytes = [&](size_t numOfBytes, const string &originalMsg) { const auto [result, msg] = buffer.get(); REQUIRE(result); REQUIRE(msg.find(originalMsg) != string::npos); REQUIRE(msg.find(to_string(numOfBytes)) != string::npos); REQUIRE(msg.find(LoggerBuffer::lostBytesMessage) != string::npos); }; SECTION("calling get on empty buffer should return false") { const auto [result, _] = buffer.get(); REQUIRE(!result); TestBuffer(buffer, capacity, 0); } SECTION("after putting one msg in buffer, get should return this msg") { const string originalMsg = randomStringGenerator.getRandomString(); buffer.put(originalMsg); TestBuffer(buffer, capacity, 1); const auto [result, msg] = buffer.get(); REQUIRE(result); REQUIRE(msg == originalMsg); TestBuffer(buffer, capacity, 0); } SECTION("after filling whole buffer with msgs, caliling get repeatedly should return all these msgs back") { const auto msgs = randomStringGenerator.createRandomStringVector(capacity); putAllMsgsFunc(msgs); TestBuffer(buffer, capacity, msgs.size()); getAllMsgsFunc(msgs); TestBuffer(buffer, capacity, 0); } SECTION("buffer should be empty after resetting it") { const auto msgs = randomStringGenerator.createRandomStringVector(capacity); putAllMsgsFunc(msgs); TestBuffer(buffer, capacity, msgs.size()); buffer.reset(); TestBuffer(buffer, capacity, 0); } SECTION("when more msgs are put into buffer than its capacity, only last msgs should be returned with get and " "first msg should contain lost bytes message") { const size_t numOfMsgsAboveCapacity = 13; const auto msgs = randomStringGenerator.createRandomStringVector(capacity + numOfMsgsAboveCapacity); putAllMsgsFunc(msgs); auto firstLostMsgIt = msgs.begin(); auto firstMsgInBufferIt = firstLostMsgIt + numOfMsgsAboveCapacity; const auto numOfLostBytes = GetNumOfBytes(firstLostMsgIt, firstMsgInBufferIt); checkLostBytes(numOfLostBytes, *firstMsgInBufferIt); for_each(firstMsgInBufferIt + 1, msgs.end(), getMsgFunc); TestBuffer(buffer, capacity, 0); } SECTION("each get should reduce number of msgs in buffer") { size_t numOfMsgsInBuffer = capacity; const auto msgs = randomStringGenerator.createRandomStringVector(capacity); auto getStartIt = msgs.begin(); putAllMsgsFunc(msgs); TestBuffer(buffer, capacity, capacity); size_t numOfMsgsToGet = 15; for_each(getStartIt, getStartIt + numOfMsgsToGet, getMsgFunc); numOfMsgsInBuffer -= numOfMsgsToGet; TestBuffer(buffer, capacity, numOfMsgsInBuffer); getStartIt += numOfMsgsToGet; numOfMsgsToGet = 34; for_each(getStartIt, getStartIt + numOfMsgsToGet, getMsgFunc); numOfMsgsInBuffer -= numOfMsgsToGet; TestBuffer(buffer, capacity, numOfMsgsInBuffer); getStartIt += numOfMsgsToGet; for_each(getStartIt, msgs.end(), getMsgFunc); TestBuffer(buffer, capacity, 0); } SECTION("put get put get") { const auto msgs = randomStringGenerator.createRandomStringVector(capacity); auto putStartIt = msgs.begin(); auto getStartIt = msgs.begin(); size_t numOfMsgsToPut = 37; for_each(putStartIt, putStartIt + numOfMsgsToPut, putMsgFunc); putStartIt += numOfMsgsToPut; size_t numOfMsgsInBuffer = numOfMsgsToPut; TestBuffer(buffer, capacity, numOfMsgsInBuffer); size_t numOfMsgsToGet = 25; for_each(getStartIt, getStartIt + numOfMsgsToGet, getMsgFunc); getStartIt += numOfMsgsToGet; numOfMsgsInBuffer -= numOfMsgsToGet; TestBuffer(buffer, capacity, numOfMsgsInBuffer); numOfMsgsToPut = msgs.end() - putStartIt; for_each(putStartIt, msgs.end(), putMsgFunc); numOfMsgsInBuffer += numOfMsgsToPut; TestBuffer(buffer, capacity, numOfMsgsInBuffer); for_each(getStartIt, msgs.end(), getMsgFunc); TestBuffer(buffer, capacity, 0); } SECTION("put get put get - with buffer overflow") { const size_t numOfMsgsAboveCapacity = 43; const auto msgs = randomStringGenerator.createRandomStringVector(capacity + numOfMsgsAboveCapacity); auto putStartIt = msgs.begin(); auto getStartIt = msgs.begin(); size_t numOfMsgsToPut = 77; for_each(putStartIt, putStartIt + numOfMsgsToPut, putMsgFunc); putStartIt += numOfMsgsToPut; size_t numOfMsgsInBuffer = numOfMsgsToPut; TestBuffer(buffer, capacity, numOfMsgsInBuffer); size_t numOfMsgsToGet = 15; for_each(getStartIt, getStartIt + numOfMsgsToGet, getMsgFunc); getStartIt += numOfMsgsToGet; numOfMsgsInBuffer -= numOfMsgsToGet; TestBuffer(buffer, capacity, numOfMsgsInBuffer); numOfMsgsToPut = msgs.end() - putStartIt; // put rest of msgs - more than buffer can hold for_each(putStartIt, msgs.end(), putMsgFunc); numOfMsgsInBuffer = capacity; TestBuffer(buffer, capacity, numOfMsgsInBuffer); auto firstLostMsgIt = getStartIt; auto firstMsgInBufferIt = firstLostMsgIt + numOfMsgsAboveCapacity - numOfMsgsToGet; const auto numOfLostBytes = GetNumOfBytes(firstLostMsgIt, firstMsgInBufferIt); checkLostBytes(numOfLostBytes, *firstMsgInBufferIt); for_each(firstMsgInBufferIt + 1, msgs.end(), getMsgFunc); TestBuffer(buffer, capacity, 0); } }