From 0ec068f220daf03049a9ffb5ac53118162f50106 Mon Sep 17 00:00:00 2001 From: Narumol Prangnawarat Date: Mon, 30 Sep 2019 16:20:20 +0100 Subject: IVGCVSW-3904 Add more unit tests for send thread with BufferManager * Add timeout parameter to wait for readable data * Write all readable data to the profiling connection when ready to read * Set ready to read when buffer exhaust * Ensure that readable data get written to profiling connection before the send thread is stopped * Add MockWriteProfilingConnection to be able to test WritePacket * Refactor BufferManager and the unit tests Signed-off-by: Narumol Prangnawarat Change-Id: I80ae01bd8d0119a3a3a957069ae8ac521c005a12 --- src/profiling/test/BufferTests.cpp | 33 +++-- src/profiling/test/SendCounterPacketTests.cpp | 195 +++++++++++++++++++++++++- src/profiling/test/SendCounterPacketTests.hpp | 29 ++++ 3 files changed, 248 insertions(+), 9 deletions(-) (limited to 'src/profiling/test') diff --git a/src/profiling/test/BufferTests.cpp b/src/profiling/test/BufferTests.cpp index a2f3c30849..7a06843ab3 100644 --- a/src/profiling/test/BufferTests.cpp +++ b/src/profiling/test/BufferTests.cpp @@ -130,7 +130,9 @@ BOOST_AUTO_TEST_CASE(BufferReserveExceedingSpaceTest) unsigned int reservedSize = 0; // Cannot reserve buffer bigger than maximum buffer size - BOOST_CHECK_THROW(bufferManager.Reserve(1024, reservedSize), armnn::InvalidArgumentException); + auto reservedBuffer = bufferManager.Reserve(1024, reservedSize); + BOOST_TEST(reservedSize == 0); + BOOST_TEST(!reservedBuffer.get()); } BOOST_AUTO_TEST_CASE(BufferExhaustionTest) @@ -144,7 +146,9 @@ BOOST_AUTO_TEST_CASE(BufferExhaustionTest) BOOST_TEST(packetBuffer.get()); // Cannot reserve buffer when buffer is not available - BOOST_CHECK_THROW(bufferManager.Reserve(512, reservedSize), BufferExhaustion); + auto reservedBuffer = bufferManager.Reserve(512, reservedSize); + BOOST_TEST(reservedSize == 0); + BOOST_TEST(!reservedBuffer.get()); } BOOST_AUTO_TEST_CASE(BufferReserveMultipleTest) @@ -173,7 +177,9 @@ BOOST_AUTO_TEST_CASE(BufferReserveMultipleTest) // Cannot reserve when buffer is not available unsigned int reservedSize3 = 0; - BOOST_CHECK_THROW(bufferManager.Reserve(512, reservedSize3), BufferExhaustion); + auto reservedBuffer = bufferManager.Reserve(512, reservedSize3); + BOOST_TEST(reservedSize3 == 0); + BOOST_TEST(!reservedBuffer.get()); } BOOST_AUTO_TEST_CASE(BufferReleaseTest) @@ -195,7 +201,9 @@ BOOST_AUTO_TEST_CASE(BufferReleaseTest) // Cannot reserve when buffer is not available unsigned int reservedSize2 = 0; - BOOST_CHECK_THROW(bufferManager.Reserve(512, reservedSize2), BufferExhaustion); + auto reservedBuffer = bufferManager.Reserve(512, reservedSize2); + BOOST_TEST(reservedSize2 == 0); + BOOST_TEST(!reservedBuffer.get()); bufferManager.Release(packetBuffer0); @@ -222,7 +230,9 @@ BOOST_AUTO_TEST_CASE(BufferCommitTest) BOOST_TEST(packetBuffer1.get()); unsigned int reservedSize2 = 0; - BOOST_CHECK_THROW(bufferManager.Reserve(512, reservedSize2), BufferExhaustion); + auto reservedBuffer = bufferManager.Reserve(512, reservedSize2); + BOOST_TEST(reservedSize2 == 0); + BOOST_TEST(!reservedBuffer.get()); bufferManager.Commit(packetBuffer0, 256); @@ -232,7 +242,10 @@ BOOST_AUTO_TEST_CASE(BufferCommitTest) BOOST_TEST(packetBuffer2->GetSize() == 256); // Buffer not set back to available list after commit - BOOST_CHECK_THROW(bufferManager.Reserve(512, reservedSize2), BufferExhaustion); + unsigned int reservedSize = 0; + reservedBuffer = bufferManager.Reserve(512, reservedSize); + BOOST_TEST(reservedSize == 0); + BOOST_TEST(!reservedBuffer.get()); } BOOST_AUTO_TEST_CASE(BufferMarkReadTest) @@ -252,7 +265,9 @@ BOOST_AUTO_TEST_CASE(BufferMarkReadTest) // Cannot reserve when buffer is not available unsigned int reservedSize2 = 0; - BOOST_CHECK_THROW(bufferManager.Reserve(512, reservedSize2), BufferExhaustion); + auto reservedBuffer = bufferManager.Reserve(512, reservedSize2); + BOOST_TEST(reservedSize2 == 0); + BOOST_TEST(!reservedBuffer.get()); bufferManager.Commit(packetBuffer0, 256); @@ -262,7 +277,9 @@ BOOST_AUTO_TEST_CASE(BufferMarkReadTest) BOOST_TEST(packetBuffer2->GetSize() == 256); // Buffer not set back to available list after commit - BOOST_CHECK_THROW(bufferManager.Reserve(512, reservedSize2), BufferExhaustion); + reservedBuffer = bufferManager.Reserve(512, reservedSize2); + BOOST_TEST(reservedSize2 == 0); + BOOST_TEST(!reservedBuffer.get()); bufferManager.MarkRead(packetBuffer2); diff --git a/src/profiling/test/SendCounterPacketTests.cpp b/src/profiling/test/SendCounterPacketTests.cpp index ba1d470a50..0d21ec0b5d 100644 --- a/src/profiling/test/SendCounterPacketTests.cpp +++ b/src/profiling/test/SendCounterPacketTests.cpp @@ -5,10 +5,11 @@ #include "SendCounterPacketTests.hpp" +#include +#include #include #include #include -#include #include #include @@ -2044,4 +2045,196 @@ BOOST_AUTO_TEST_CASE(SendThreadTest3) BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() <= mockStreamCounterBuffer.GetCommittedSize()); } +BOOST_AUTO_TEST_CASE(SendThreadBufferTest) +{ + MockProfilingConnection mockProfilingConnection; + BufferManager bufferManager(1, 1024); + SendCounterPacket sendCounterPacket(mockProfilingConnection, bufferManager, -1); + sendCounterPacket.Start(); + + // Interleaving writes and reads to/from the buffer with pauses to test that the send thread actually waits for + // something to become available for reading + std::this_thread::sleep_for(std::chrono::seconds(1)); + + // SendStreamMetaDataPacket + sendCounterPacket.SendStreamMetaDataPacket(); + + // Read data from the buffer + // Buffer should become readable after commit by SendStreamMetaDataPacket + auto packetBuffer = bufferManager.GetReadableBuffer(); + BOOST_TEST(packetBuffer.get()); + + std::string processName = GetProcessName().substr(0, 60); + unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast(processName.size()) + 1; + unsigned int streamMetadataPacketsize = 118 + processNameSize; + BOOST_TEST(packetBuffer->GetSize() == streamMetadataPacketsize); + + // Buffer is not available when SendStreamMetaDataPacket already occupied the buffer. + unsigned int reservedSize = 0; + auto reservedBuffer = bufferManager.Reserve(512, reservedSize); + BOOST_TEST(!reservedBuffer.get()); + + // Recommit to be read by sendCounterPacket + bufferManager.Commit(packetBuffer, streamMetadataPacketsize); + + sendCounterPacket.SetReadyToRead(); + + std::this_thread::sleep_for(std::chrono::seconds(1)); + + // The buffer is read by the send thread so it should not be in the readable buffer. + auto readBuffer = bufferManager.GetReadableBuffer(); + BOOST_TEST(!readBuffer); + + // Successfully reserved the buffer with requested size + reservedBuffer = bufferManager.Reserve(512, reservedSize); + BOOST_TEST(reservedSize == 512); + BOOST_TEST(reservedBuffer.get()); + + // Release the buffer to be used by sendCounterPacket + bufferManager.Release(reservedBuffer); + + // SendCounterDirectoryPacket + CounterDirectory counterDirectory; + sendCounterPacket.SendCounterDirectoryPacket(counterDirectory); + + // Read data from the buffer + // Buffer should become readable after commit by SendCounterDirectoryPacket + auto counterDirectoryPacketBuffer = bufferManager.GetReadableBuffer(); + BOOST_TEST(counterDirectoryPacketBuffer.get()); + + // Get the size of the Counter Directory Packet + unsigned int counterDirectoryPacketSize = 32; + BOOST_TEST(counterDirectoryPacketBuffer->GetSize() == counterDirectoryPacketSize); + + // Buffer is not available when SendCounterDirectoryPacket already occupied the buffer. + reservedSize = 0; + reservedBuffer = bufferManager.Reserve(512, reservedSize); + BOOST_TEST(reservedSize == 0); + BOOST_TEST(!reservedBuffer.get()); + + // Recommit to be read by sendCounterPacket + bufferManager.Commit(counterDirectoryPacketBuffer, counterDirectoryPacketSize); + + sendCounterPacket.SetReadyToRead(); + + std::this_thread::sleep_for(std::chrono::seconds(1)); + + // The buffer is read by the send thread so it should not be in the readable buffer. + readBuffer = bufferManager.GetReadableBuffer(); + BOOST_TEST(!readBuffer); + + // Successfully reserved the buffer with requested size + reservedBuffer = bufferManager.Reserve(512, reservedSize); + BOOST_TEST(reservedSize == 512); + BOOST_TEST(reservedBuffer.get()); + + // Release the buffer to be used by sendCounterPacket + bufferManager.Release(reservedBuffer); + + // SendPeriodicCounterCapturePacket + sendCounterPacket.SendPeriodicCounterCapturePacket(123u, + { + { 1u, 23u }, + { 33u, 1207623u } + }); + + // Read data from the buffer + // Buffer should become readable after commit by SendPeriodicCounterCapturePacket + auto periodicCounterCapturePacketBuffer = bufferManager.GetReadableBuffer(); + BOOST_TEST(periodicCounterCapturePacketBuffer.get()); + + // Get the size of the Periodic Counter Capture Packet + unsigned int periodicCounterCapturePacketSize = 28; + BOOST_TEST(periodicCounterCapturePacketBuffer->GetSize() == periodicCounterCapturePacketSize); + + // Buffer is not available when SendPeriodicCounterCapturePacket already occupied the buffer. + reservedSize = 0; + reservedBuffer = bufferManager.Reserve(512, reservedSize); + BOOST_TEST(reservedSize == 0); + BOOST_TEST(!reservedBuffer.get()); + + // Recommit to be read by sendCounterPacket + bufferManager.Commit(periodicCounterCapturePacketBuffer, periodicCounterCapturePacketSize); + + sendCounterPacket.SetReadyToRead(); + + std::this_thread::sleep_for(std::chrono::seconds(1)); + + // The buffer is read by the send thread so it should not be in the readable buffer. + readBuffer = bufferManager.GetReadableBuffer(); + BOOST_TEST(!readBuffer); + + // Successfully reserved the buffer with requested size + reservedBuffer = bufferManager.Reserve(512, reservedSize); + BOOST_TEST(reservedSize == 512); + BOOST_TEST(reservedBuffer.get()); + + sendCounterPacket.Stop(); +} + +BOOST_AUTO_TEST_CASE(SendThreadBufferTest1) +{ + MockWriteProfilingConnection mockProfilingConnection; + BufferManager bufferManager(3, 1024); + SendCounterPacket sendCounterPacket(mockProfilingConnection, bufferManager, -1); + sendCounterPacket.Start(); + + // SendStreamMetaDataPacket + sendCounterPacket.SendStreamMetaDataPacket(); + + // Read data from the buffer + // Buffer should become readable after commit by SendStreamMetaDataPacket + auto packetBuffer = bufferManager.GetReadableBuffer(); + BOOST_TEST(packetBuffer.get()); + + std::string processName = GetProcessName().substr(0, 60); + unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast(processName.size()) + 1; + unsigned int streamMetadataPacketsize = 118 + processNameSize; + BOOST_TEST(packetBuffer->GetSize() == streamMetadataPacketsize); + + // Recommit to be read by sendCounterPacket + bufferManager.Commit(packetBuffer, streamMetadataPacketsize); + + sendCounterPacket.SetReadyToRead(); + + // SendCounterDirectoryPacket + CounterDirectory counterDirectory; + sendCounterPacket.SendCounterDirectoryPacket(counterDirectory); + + sendCounterPacket.SetReadyToRead(); + + // SendPeriodicCounterCapturePacket + sendCounterPacket.SendPeriodicCounterCapturePacket(123u, + { + { 1u, 23u }, + { 33u, 1207623u } + }); + + sendCounterPacket.SetReadyToRead(); + + sendCounterPacket.Stop(); + + // The buffer is read by the send thread so it should not be in the readable buffer. + auto readBuffer = bufferManager.GetReadableBuffer(); + BOOST_TEST(!readBuffer); + + // Successfully reserved the buffer with requested size + unsigned int reservedSize = 0; + auto reservedBuffer = bufferManager.Reserve(512, reservedSize); + BOOST_TEST(reservedSize == 512); + BOOST_TEST(reservedBuffer.get()); + + // Check that data was actually written to the profiling connection in any order + std::vector writtenData = mockProfilingConnection.GetWrittenData(); + std::vector expectedOutput{streamMetadataPacketsize, 32, 28}; + BOOST_TEST(writtenData.size() == 3); + bool foundStreamMetaDataPacket = + std::find(writtenData.begin(), writtenData.end(), streamMetadataPacketsize) != writtenData.end(); + bool foundCounterDirectoryPacket = std::find(writtenData.begin(), writtenData.end(), 32) != writtenData.end(); + bool foundPeriodicCounterCapturePacket = std::find(writtenData.begin(), writtenData.end(), 28) != writtenData.end(); + BOOST_TEST(foundStreamMetaDataPacket); + BOOST_TEST(foundCounterDirectoryPacket); + BOOST_TEST(foundPeriodicCounterCapturePacket); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/profiling/test/SendCounterPacketTests.hpp b/src/profiling/test/SendCounterPacketTests.hpp index 3c3427c4c7..584df5e520 100644 --- a/src/profiling/test/SendCounterPacketTests.hpp +++ b/src/profiling/test/SendCounterPacketTests.hpp @@ -42,6 +42,35 @@ private: bool m_IsOpen; }; +class MockWriteProfilingConnection : public IProfilingConnection +{ +public: + MockWriteProfilingConnection() + : m_IsOpen(true) + {} + + bool IsOpen() override { return m_IsOpen; } + + void Close() override { m_IsOpen = false; } + + bool WritePacket(const unsigned char* buffer, uint32_t length) override + { + m_WrittenData.push_back(length); + return buffer != nullptr && length > 0; + } + + Packet ReadPacket(uint32_t timeout) override { return Packet(); } + + std::vector GetWrittenData() + { + return m_WrittenData; + } + +private: + bool m_IsOpen; + std::vector m_WrittenData; +}; + class MockPacketBuffer : public IPacketBuffer { public: -- cgit v1.2.1