m_Socket[0].fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
if (m_Socket[0].fd == -1)
{
- throw armnn::Exception(std::string(": Socket construction failed: ") + strerror(errno));
+ throw armnn::RuntimeException(std::string("Socket construction failed: ") + strerror(errno));
}
// Connect to the named unix domain socket.
if (0 != connect(m_Socket[0].fd, reinterpret_cast<const sockaddr*>(&server), sizeof(sockaddr_un)))
{
close(m_Socket[0].fd);
- throw armnn::Exception(std::string(": Cannot connect to stream socket: ") + strerror(errno));
+ throw armnn::RuntimeException(std::string("Cannot connect to stream socket: ") + strerror(errno));
}
// Our socket will only be interested in polling reads.
if (0 != fcntl(m_Socket[0].fd, F_SETFL, currentFlags | O_NONBLOCK))
{
close(m_Socket[0].fd);
- throw armnn::Exception(std::string(": Failed to set socket as non blocking: ") + strerror(errno));
+ throw armnn::RuntimeException(std::string("Failed to set socket as non blocking: ") + strerror(errno));
}
}
bool SocketProfilingConnection::IsOpen()
{
- if (m_Socket[0].fd > 0)
- {
- return true;
- }
- return false;
+ return m_Socket[0].fd > 0;
}
void SocketProfilingConnection::Close()
{
- if (0 == close(m_Socket[0].fd))
- {
- memset(m_Socket, 0, sizeof(m_Socket));
- }
- else
+ if (close(m_Socket[0].fd) != 0)
{
- throw armnn::Exception(std::string(": Cannot close stream socket: ") + strerror(errno));
+ throw armnn::RuntimeException(std::string("Cannot close stream socket: ") + strerror(errno));
}
+
+ memset(m_Socket, 0, sizeof(m_Socket));
}
-bool SocketProfilingConnection::WritePacket(const char* buffer, uint32_t length)
+bool SocketProfilingConnection::WritePacket(const unsigned char* buffer, uint32_t length)
{
- if (-1 == write(m_Socket[0].fd, buffer, length))
+ if (buffer == nullptr || length == 0)
{
return false;
}
- return true;
+
+ return write(m_Socket[0].fd, buffer, length) != -1;
}
Packet SocketProfilingConnection::ReadPacket(uint32_t timeout)
{
- // Poll for data on the socket or until timeout.
+ // Poll for data on the socket or until timeout occurs
int pollResult = poll(m_Socket, 1, static_cast<int>(timeout));
- if (pollResult > 0)
+
+ switch (pollResult)
{
- // Normal poll return but it could still contain an error signal.
+ case -1: // Error
+ throw armnn::RuntimeException(std::string("Read failure from socket: ") + strerror(errno));
+
+ case 0: // Timeout
+ throw armnn::RuntimeException("Timeout while reading from socket");
+
+ default: // Normal poll return but it could still contain an error signal
+
+ // Check if the socket reported an error
if (m_Socket[0].revents & (POLLNVAL | POLLERR | POLLHUP))
{
- throw armnn::Exception(std::string(": Read failure from socket: ") + strerror(errno));
+ throw armnn::Exception(std::string("Socket 0 reported an error: ") + strerror(errno));
+ }
+
+ // Check if there is data to read
+ if (!(m_Socket[0].revents & (POLLIN)))
+ {
+ // No data to read from the socket. Silently ignore and continue
+ return Packet();
}
- else if (m_Socket[0].revents & (POLLIN)) // There is data to read.
+
+ // There is data to read, read the header first
+ char header[8] = {};
+ if (8 != recv(m_Socket[0].fd, &header, sizeof(header), 0))
{
- // Read the header first.
- char header[8];
- if (8 != recv(m_Socket[0].fd, &header, sizeof header, 0))
- {
- // What do we do here if there's not a valid 8 byte header to read?
- throw armnn::Exception(": Received packet did not contains a valid MIPE header. ");
- }
- // stream_metadata_identifier is the first 4 bytes.
- uint32_t metadataIdentifier = static_cast<uint32_t>(header[0]) << 24 |
- static_cast<uint32_t>(header[1]) << 16 |
- static_cast<uint32_t>(header[2]) << 8 |
- static_cast<uint32_t>(header[3]);
- // data_length is the next 4 bytes.
- uint32_t dataLength = static_cast<uint32_t>(header[4]) << 24 |
- static_cast<uint32_t>(header[5]) << 16 |
- static_cast<uint32_t>(header[6]) << 8 |
- static_cast<uint32_t>(header[7]);
-
- std::unique_ptr<char[]> packetData;
- if (dataLength > 0)
- {
- packetData = std::make_unique<char[]>(dataLength);
- }
-
- if (dataLength != recv(m_Socket[0].fd, packetData.get(), dataLength, 0))
- {
- // What do we do here if we can't read in a full packet?
- throw armnn::Exception(": Invalid MIPE packet.");
- }
- return {metadataIdentifier, dataLength, packetData};
+ // What do we do here if there's not a valid 8 byte header to read?
+ throw armnn::RuntimeException("The received packet did not contains a valid MIPE header");
}
- else // Some unknown return signal.
+
+ // stream_metadata_identifier is the first 4 bytes
+ uint32_t metadataIdentifier = 0;
+ std::memcpy(&metadataIdentifier, header, sizeof(metadataIdentifier));
+
+ // data_length is the next 4 bytes
+ uint32_t dataLength = 0;
+ std::memcpy(&dataLength, header + 4u, sizeof(dataLength));
+
+ std::unique_ptr<char[]> packetData;
+ if (dataLength > 0)
{
- throw armnn::Exception(": Poll returned an unexpected event." );
+ packetData = std::make_unique<char[]>(dataLength);
}
- }
- else if (pollResult == -1)
- {
- throw armnn::Exception(std::string(": Read failure from socket: ") + strerror(errno));
- }
- else // it's 0 so a timeout.
- {
- throw armnn::TimeoutException(": Timeout while reading from socket.");
+
+ if (dataLength != recv(m_Socket[0].fd, packetData.get(), dataLength, 0))
+ {
+ // What do we do here if we can't read in a full packet?
+ throw armnn::RuntimeException("Invalid MIPE packet");
+ }
+
+ return Packet(metadataIdentifier, dataLength, packetData);
}
}
#include <EncodeVersion.hpp>
#include <ProfilingUtils.hpp>
#include <SendCounterPacket.hpp>
+#include <CounterDirectory.hpp>
#include <armnn/Exceptions.hpp>
#include <armnn/Conversion.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <chrono>
-#include <iostream>
using namespace armnn::profiling;
+size_t GetDataLength(const MockStreamCounterBuffer& mockStreamCounterBuffer, size_t packetOffset)
+{
+ // The data length is the written in the second byte
+ return ReadUint32(mockStreamCounterBuffer.GetBuffer(),
+ boost::numeric_cast<unsigned int>(packetOffset + sizeof(uint32_t)));
+}
+
+size_t GetPacketSize(const MockStreamCounterBuffer& mockStreamCounterBuffer, size_t packetOffset)
+{
+ // The packet size is the data length plus the size of the packet header (always two words big)
+ return GetDataLength(mockStreamCounterBuffer, packetOffset) + 2 * sizeof(uint32_t);
+}
+
BOOST_AUTO_TEST_SUITE(SendCounterPacketTests)
BOOST_AUTO_TEST_CASE(MockSendCounterPacketTest)
BOOST_AUTO_TEST_CASE(SendPeriodicCounterSelectionPacketTest)
{
// Error no space left in buffer
+ MockProfilingConnection mockProfilingConnection;
MockBuffer mockBuffer1(10);
- SendCounterPacket sendPacket1(mockBuffer1);
+ SendCounterPacket sendPacket1(mockProfilingConnection, mockBuffer1);
uint32_t capturePeriod = 1000;
std::vector<uint16_t> selectedCounterIds;
BOOST_CHECK_THROW(sendPacket1.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds),
- armnn::profiling::BufferExhaustion);
+ BufferExhaustion);
// Packet without any counters
MockBuffer mockBuffer2(512);
- SendCounterPacket sendPacket2(mockBuffer2);
+ SendCounterPacket sendPacket2(mockProfilingConnection, mockBuffer2);
sendPacket2.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds);
unsigned int sizeRead = 0;
// Full packet message
MockBuffer mockBuffer3(512);
- SendCounterPacket sendPacket3(mockBuffer3);
+ SendCounterPacket sendPacket3(mockProfilingConnection, mockBuffer3);
selectedCounterIds.reserve(5);
selectedCounterIds.emplace_back(100);
BOOST_AUTO_TEST_CASE(SendPeriodicCounterCapturePacketTest)
{
// Error no space left in buffer
+ MockProfilingConnection mockProfilingConnection;
MockBuffer mockBuffer1(10);
- SendCounterPacket sendPacket1(mockBuffer1);
+ SendCounterPacket sendPacket1(mockProfilingConnection, mockBuffer1);
auto captureTimestamp = std::chrono::steady_clock::now();
uint64_t time = static_cast<uint64_t >(captureTimestamp.time_since_epoch().count());
// Packet without any counters
MockBuffer mockBuffer2(512);
- SendCounterPacket sendPacket2(mockBuffer2);
+ SendCounterPacket sendPacket2(mockProfilingConnection, mockBuffer2);
sendPacket2.SendPeriodicCounterCapturePacket(time, indexValuePairs);
unsigned int sizeRead = 0;
// Full packet message
MockBuffer mockBuffer3(512);
- SendCounterPacket sendPacket3(mockBuffer3);
+ SendCounterPacket sendPacket3(mockProfilingConnection, mockBuffer3);
indexValuePairs.reserve(5);
indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t >(0, 100));
uint32_t sizeUint32 = numeric_cast<uint32_t>(sizeof(uint32_t));
// Error no space left in buffer
+ MockProfilingConnection mockProfilingConnection;
MockBuffer mockBuffer1(10);
- SendCounterPacket sendPacket1(mockBuffer1);
+ SendCounterPacket sendPacket1(mockProfilingConnection, mockBuffer1);
BOOST_CHECK_THROW(sendPacket1.SendStreamMetaDataPacket(), armnn::profiling::BufferExhaustion);
// Full metadata packet
uint32_t packetEntries = 6;
MockBuffer mockBuffer2(512);
- SendCounterPacket sendPacket2(mockBuffer2);
+ SendCounterPacket sendPacket2(mockProfilingConnection, mockBuffer2);
sendPacket2.SendStreamMetaDataPacket();
unsigned int sizeRead = 0;
const unsigned char* readBuffer2 = mockBuffer2.GetReadBuffer(sizeRead);
BOOST_AUTO_TEST_CASE(CreateDeviceRecordTest)
{
+ MockProfilingConnection mockProfilingConnection;
MockBuffer mockBuffer(0);
- SendCounterPacketTest sendCounterPacketTest(mockBuffer);
+ SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer);
// Create a device for testing
uint16_t deviceUid = 27;
BOOST_AUTO_TEST_CASE(CreateInvalidDeviceRecordTest)
{
+ MockProfilingConnection mockProfilingConnection;
MockBuffer mockBuffer(0);
- SendCounterPacketTest sendCounterPacketTest(mockBuffer);
+ SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer);
// Create a device for testing
uint16_t deviceUid = 27;
BOOST_AUTO_TEST_CASE(CreateCounterSetRecordTest)
{
+ MockProfilingConnection mockProfilingConnection;
MockBuffer mockBuffer(0);
- SendCounterPacketTest sendCounterPacketTest(mockBuffer);
+ SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer);
// Create a counter set for testing
uint16_t counterSetUid = 27;
BOOST_AUTO_TEST_CASE(CreateInvalidCounterSetRecordTest)
{
+ MockProfilingConnection mockProfilingConnection;
MockBuffer mockBuffer(0);
- SendCounterPacketTest sendCounterPacketTest(mockBuffer);
+ SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer);
// Create a counter set for testing
uint16_t counterSetUid = 27;
BOOST_AUTO_TEST_CASE(CreateEventRecordTest)
{
+ MockProfilingConnection mockProfilingConnection;
MockBuffer mockBuffer(0);
- SendCounterPacketTest sendCounterPacketTest(mockBuffer);
+ SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer);
// Create a counter for testing
uint16_t counterUid = 7256;
BOOST_AUTO_TEST_CASE(CreateEventRecordNoUnitsTest)
{
+ MockProfilingConnection mockProfilingConnection;
MockBuffer mockBuffer(0);
- SendCounterPacketTest sendCounterPacketTest(mockBuffer);
+ SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer);
// Create a counter for testing
uint16_t counterUid = 44312;
BOOST_AUTO_TEST_CASE(CreateInvalidEventRecordTest1)
{
+ MockProfilingConnection mockProfilingConnection;
MockBuffer mockBuffer(0);
- SendCounterPacketTest sendCounterPacketTest(mockBuffer);
+ SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer);
// Create a counter for testing
uint16_t counterUid = 7256;
BOOST_AUTO_TEST_CASE(CreateInvalidEventRecordTest2)
{
+ MockProfilingConnection mockProfilingConnection;
MockBuffer mockBuffer(0);
- SendCounterPacketTest sendCounterPacketTest(mockBuffer);
+ SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer);
// Create a counter for testing
uint16_t counterUid = 7256;
BOOST_AUTO_TEST_CASE(CreateInvalidEventRecordTest3)
{
+ MockProfilingConnection mockProfilingConnection;
MockBuffer mockBuffer(0);
- SendCounterPacketTest sendCounterPacketTest(mockBuffer);
+ SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer);
// Create a counter for testing
uint16_t counterUid = 7256;
BOOST_AUTO_TEST_CASE(CreateCategoryRecordTest)
{
+ MockProfilingConnection mockProfilingConnection;
MockBuffer mockBuffer(0);
- SendCounterPacketTest sendCounterPacketTest(mockBuffer);
+ SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer);
// Create a category for testing
const std::string categoryName = "some_category";
BOOST_AUTO_TEST_CASE(CreateInvalidCategoryRecordTest1)
{
+ MockProfilingConnection mockProfilingConnection;
MockBuffer mockBuffer(0);
- SendCounterPacketTest sendCounterPacketTest(mockBuffer);
+ SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer);
// Create a category for testing
const std::string categoryName = "some invalid category";
BOOST_AUTO_TEST_CASE(CreateInvalidCategoryRecordTest2)
{
+ MockProfilingConnection mockProfilingConnection;
MockBuffer mockBuffer(0);
- SendCounterPacketTest sendCounterPacketTest(mockBuffer);
+ SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer);
// Create a category for testing
const std::string categoryName = "some_category";
BOOST_CHECK(device2);
// Buffer with not enough space
+ MockProfilingConnection mockProfilingConnection;
MockBuffer mockBuffer(10);
- SendCounterPacket sendCounterPacket(mockBuffer);
+ SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer);
BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory),
armnn::profiling::BufferExhaustion);
}
BOOST_CHECK(counter3);
// Buffer with enough space
+ MockProfilingConnection mockProfilingConnection;
MockBuffer mockBuffer(1024);
- SendCounterPacket sendCounterPacket(mockBuffer);
+ SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer);
BOOST_CHECK_NO_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory));
// Get the read buffer
BOOST_CHECK(device);
// Buffer with enough space
+ MockProfilingConnection mockProfilingConnection;
MockBuffer mockBuffer(1024);
- SendCounterPacket sendCounterPacket(mockBuffer);
+ SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer);
BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
}
BOOST_CHECK(counterSet);
// Buffer with enough space
+ MockProfilingConnection mockProfilingConnection;
MockBuffer mockBuffer(1024);
- SendCounterPacket sendCounterPacket(mockBuffer);
+ SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer);
BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
}
BOOST_CHECK(category);
// Buffer with enough space
+ MockProfilingConnection mockProfilingConnection;
MockBuffer mockBuffer(1024);
- SendCounterPacket sendCounterPacket(mockBuffer);
+ SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer);
BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
}
BOOST_CHECK(category);
// Buffer with enough space
+ MockProfilingConnection mockProfilingConnection;
MockBuffer mockBuffer(1024);
- SendCounterPacket sendCounterPacket(mockBuffer);
+ SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer);
BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
}
BOOST_CHECK(counter);
// Buffer with enough space
+ MockProfilingConnection mockProfilingConnection;
MockBuffer mockBuffer(1024);
- SendCounterPacket sendCounterPacket(mockBuffer);
+ SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer);
BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
}
+BOOST_AUTO_TEST_CASE(SendThreadTest0)
+{
+ MockProfilingConnection mockProfilingConnection;
+ MockStreamCounterBuffer mockStreamCounterBuffer(0);
+ SendCounterPacket sendCounterPacket(mockProfilingConnection, mockStreamCounterBuffer);
+
+ // Try to start the send thread many times, it must only start once
+
+ sendCounterPacket.Start();
+ BOOST_CHECK(sendCounterPacket.IsRunning());
+ sendCounterPacket.Start();
+ sendCounterPacket.Start();
+ sendCounterPacket.Start();
+ sendCounterPacket.Start();
+ BOOST_CHECK(sendCounterPacket.IsRunning());
+
+ std::this_thread::sleep_for(std::chrono::seconds(1));
+
+ sendCounterPacket.Stop();
+ BOOST_CHECK(!sendCounterPacket.IsRunning());
+}
+
+BOOST_AUTO_TEST_CASE(SendThreadTest1)
+{
+ size_t totalWrittenSize = 0;
+
+ MockProfilingConnection mockProfilingConnection;
+ MockStreamCounterBuffer mockStreamCounterBuffer(100);
+ SendCounterPacket sendCounterPacket(mockProfilingConnection, mockStreamCounterBuffer);
+ 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));
+
+ CounterDirectory counterDirectory;
+ sendCounterPacket.SendStreamMetaDataPacket();
+
+ // Get the size of the Stream Metadata Packet
+ size_t streamMetadataPacketsize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize);
+ totalWrittenSize += streamMetadataPacketsize;
+
+ sendCounterPacket.SetReadyToRead();
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+ sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
+
+ // Get the size of the Counter Directory Packet
+ size_t counterDirectoryPacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize);
+ totalWrittenSize += counterDirectoryPacketSize;
+
+ sendCounterPacket.SetReadyToRead();
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+ sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
+ {
+ { 1u, 23u },
+ { 33u, 1207623u }
+ });
+
+ // Get the size of the Periodic Counter Capture Packet
+ size_t periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize);
+ totalWrittenSize += periodicCounterCapturePacketSize;
+
+ sendCounterPacket.SetReadyToRead();
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+ sendCounterPacket.SendPeriodicCounterCapturePacket(44u,
+ {
+ { 211u, 923u }
+ });
+
+ // Get the size of the Periodic Counter Capture Packet
+ periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize);
+ totalWrittenSize += periodicCounterCapturePacketSize;
+
+ sendCounterPacket.SendPeriodicCounterCapturePacket(1234u,
+ {
+ { 555u, 23u },
+ { 556u, 6u },
+ { 557u, 893454u },
+ { 558u, 1456623u },
+ { 559u, 571090u }
+ });
+
+ // Get the size of the Periodic Counter Capture Packet
+ periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize);
+ totalWrittenSize += periodicCounterCapturePacketSize;
+
+ sendCounterPacket.SendPeriodicCounterCapturePacket(997u,
+ {
+ { 88u, 11u },
+ { 96u, 22u },
+ { 97u, 33u },
+ { 999u, 444u }
+ });
+
+ // Get the size of the Periodic Counter Capture Packet
+ periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize);
+ totalWrittenSize += periodicCounterCapturePacketSize;
+
+ sendCounterPacket.SetReadyToRead();
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+ sendCounterPacket.SendPeriodicCounterSelectionPacket(1000u, { 1345u, 254u, 4536u, 408u, 54u, 6323u, 428u, 1u, 6u });
+
+ // Get the size of the Periodic Counter Capture Packet
+ periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize);
+ totalWrittenSize += periodicCounterCapturePacketSize;
+
+ sendCounterPacket.SetReadyToRead();
+
+ // To test an exact value of the "read size" in the mock buffer, wait a second to allow the send thread to
+ // read all what's remaining in the buffer
+ std::this_thread::sleep_for(std::chrono::seconds(1));
+
+ sendCounterPacket.Stop();
+
+ BOOST_CHECK(mockStreamCounterBuffer.GetBufferSize() == totalWrittenSize);
+ BOOST_CHECK(mockStreamCounterBuffer.GetCommittedSize() == totalWrittenSize);
+ BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() == totalWrittenSize);
+}
+
+BOOST_AUTO_TEST_CASE(SendThreadTest2)
+{
+ size_t totalWrittenSize = 0;
+
+ MockProfilingConnection mockProfilingConnection;
+ MockStreamCounterBuffer mockStreamCounterBuffer(100);
+ SendCounterPacket sendCounterPacket(mockProfilingConnection, mockStreamCounterBuffer);
+ sendCounterPacket.Start();
+
+ // Adding many spurious "ready to read" signals throughout the test to check that the send thread is
+ // capable of handling unnecessary read requests
+
+ std::this_thread::sleep_for(std::chrono::seconds(1));
+
+ sendCounterPacket.SetReadyToRead();
+
+ CounterDirectory counterDirectory;
+ sendCounterPacket.SendStreamMetaDataPacket();
+
+ // Get the size of the Stream Metadata Packet
+ size_t streamMetadataPacketsize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize);
+ totalWrittenSize += streamMetadataPacketsize;
+
+ sendCounterPacket.SetReadyToRead();
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+ sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
+
+ // Get the size of the Counter Directory Packet
+ size_t counterDirectoryPacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize);
+ totalWrittenSize += counterDirectoryPacketSize;
+
+ sendCounterPacket.SetReadyToRead();
+ sendCounterPacket.SetReadyToRead();
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+ sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
+ {
+ { 1u, 23u },
+ { 33u, 1207623u }
+ });
+
+ // Get the size of the Periodic Counter Capture Packet
+ size_t periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize);
+ totalWrittenSize += periodicCounterCapturePacketSize;
+
+ sendCounterPacket.SetReadyToRead();
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+ sendCounterPacket.SetReadyToRead();
+ sendCounterPacket.SetReadyToRead();
+ sendCounterPacket.SetReadyToRead();
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+ sendCounterPacket.SetReadyToRead();
+ sendCounterPacket.SendPeriodicCounterCapturePacket(44u,
+ {
+ { 211u, 923u }
+ });
+
+ // Get the size of the Periodic Counter Capture Packet
+ periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize);
+ totalWrittenSize += periodicCounterCapturePacketSize;
+
+ sendCounterPacket.SendPeriodicCounterCapturePacket(1234u,
+ {
+ { 555u, 23u },
+ { 556u, 6u },
+ { 557u, 893454u },
+ { 558u, 1456623u },
+ { 559u, 571090u }
+ });
+
+ // Get the size of the Periodic Counter Capture Packet
+ periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize);
+ totalWrittenSize += periodicCounterCapturePacketSize;
+
+ sendCounterPacket.SetReadyToRead();
+ sendCounterPacket.SendPeriodicCounterCapturePacket(997u,
+ {
+ { 88u, 11u },
+ { 96u, 22u },
+ { 97u, 33u },
+ { 999u, 444u }
+ });
+
+ // Get the size of the Periodic Counter Capture Packet
+ periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize);
+ totalWrittenSize += periodicCounterCapturePacketSize;
+
+ sendCounterPacket.SetReadyToRead();
+ sendCounterPacket.SetReadyToRead();
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+ sendCounterPacket.SendPeriodicCounterSelectionPacket(1000u, { 1345u, 254u, 4536u, 408u, 54u, 6323u, 428u, 1u, 6u });
+
+ // Get the size of the Periodic Counter Capture Packet
+ periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize);
+ totalWrittenSize += periodicCounterCapturePacketSize;
+
+ sendCounterPacket.SetReadyToRead();
+
+ // To test an exact value of the "read size" in the mock buffer, wait a second to allow the send thread to
+ // read all what's remaining in the buffer
+ std::this_thread::sleep_for(std::chrono::seconds(1));
+
+ sendCounterPacket.Stop();
+
+ BOOST_CHECK(mockStreamCounterBuffer.GetBufferSize() == totalWrittenSize);
+ BOOST_CHECK(mockStreamCounterBuffer.GetCommittedSize() == totalWrittenSize);
+ BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() == totalWrittenSize);
+}
+
+BOOST_AUTO_TEST_CASE(SendThreadTest3)
+{
+ size_t totalWrittenSize = 0;
+
+ MockProfilingConnection mockProfilingConnection;
+ MockStreamCounterBuffer mockStreamCounterBuffer(100);
+ SendCounterPacket sendCounterPacket(mockProfilingConnection, mockStreamCounterBuffer);
+ sendCounterPacket.Start();
+
+ // Not using pauses or "grace periods" to stress test the send thread
+
+ sendCounterPacket.SetReadyToRead();
+
+ CounterDirectory counterDirectory;
+ sendCounterPacket.SendStreamMetaDataPacket();
+
+ // Get the size of the Stream Metadata Packet
+ size_t streamMetadataPacketsize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize);
+ totalWrittenSize += streamMetadataPacketsize;
+
+ sendCounterPacket.SetReadyToRead();
+ sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
+
+ // Get the size of the Counter Directory Packet
+ size_t counterDirectoryPacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize);
+ totalWrittenSize += counterDirectoryPacketSize;
+
+ sendCounterPacket.SetReadyToRead();
+ sendCounterPacket.SetReadyToRead();
+ sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
+ {
+ { 1u, 23u },
+ { 33u, 1207623u }
+ });
+
+ // Get the size of the Periodic Counter Capture Packet
+ size_t periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize);
+ totalWrittenSize += periodicCounterCapturePacketSize;
+
+ sendCounterPacket.SetReadyToRead();
+ sendCounterPacket.SetReadyToRead();
+ sendCounterPacket.SetReadyToRead();
+ sendCounterPacket.SetReadyToRead();
+ sendCounterPacket.SetReadyToRead();
+ sendCounterPacket.SendPeriodicCounterCapturePacket(44u,
+ {
+ { 211u, 923u }
+ });
+
+ // Get the size of the Periodic Counter Capture Packet
+ periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize);
+ totalWrittenSize += periodicCounterCapturePacketSize;
+
+ sendCounterPacket.SendPeriodicCounterCapturePacket(1234u,
+ {
+ { 555u, 23u },
+ { 556u, 6u },
+ { 557u, 893454u },
+ { 558u, 1456623u },
+ { 559u, 571090u }
+ });
+
+ // Get the size of the Periodic Counter Capture Packet
+ periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize);
+ totalWrittenSize += periodicCounterCapturePacketSize;
+
+ sendCounterPacket.SetReadyToRead();
+ sendCounterPacket.SetReadyToRead();
+ sendCounterPacket.SendPeriodicCounterCapturePacket(997u,
+ {
+ { 88u, 11u },
+ { 96u, 22u },
+ { 97u, 33u },
+ { 999u, 444u }
+ });
+
+ // Get the size of the Periodic Counter Capture Packet
+ periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize);
+ totalWrittenSize += periodicCounterCapturePacketSize;
+
+ sendCounterPacket.SetReadyToRead();
+ sendCounterPacket.SetReadyToRead();
+ sendCounterPacket.SendPeriodicCounterSelectionPacket(1000u, { 1345u, 254u, 4536u, 408u, 54u, 6323u, 428u, 1u, 6u });
+
+ // Get the size of the Periodic Counter Capture Packet
+ periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize);
+ totalWrittenSize += periodicCounterCapturePacketSize;
+
+ sendCounterPacket.SetReadyToRead();
+
+ // Abruptly terminating the send thread, the amount of data sent may be less that the amount written (the send
+ // thread is not guaranteed to flush the buffer)
+ sendCounterPacket.Stop();
+
+ BOOST_CHECK(mockStreamCounterBuffer.GetBufferSize() == totalWrittenSize);
+ BOOST_CHECK(mockStreamCounterBuffer.GetCommittedSize() == totalWrittenSize);
+ BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() <= totalWrittenSize);
+}
+
BOOST_AUTO_TEST_SUITE_END()