2 // Copyright © 2019 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
6 #include "ProfilingMocks.hpp"
7 #include "ProfilingTestUtils.hpp"
8 #include "SendCounterPacketTests.hpp"
10 #include <BufferManager.hpp>
11 #include <CounterDirectory.hpp>
12 #include <EncodeVersion.hpp>
13 #include <ProfilingUtils.hpp>
14 #include <SendCounterPacket.hpp>
15 #include <Processes.hpp>
17 #include <armnn/Exceptions.hpp>
18 #include <armnn/Conversion.hpp>
19 #include <armnn/Utils.hpp>
21 #include <common/include/Constants.hpp>
24 #include <boost/test/unit_test.hpp>
25 #include <boost/numeric/conversion/cast.hpp>
29 using namespace armnn::profiling;
34 // A short delay to wait for the thread to process a packet.
35 uint16_t constexpr WAIT_UNTIL_READABLE_MS = 20;
37 void SetNotConnectedProfilingState(ProfilingStateMachine& profilingStateMachine)
39 ProfilingState currentState = profilingStateMachine.GetCurrentState();
42 case ProfilingState::WaitingForAck:
43 profilingStateMachine.TransitionToState(ProfilingState::Active);
45 case ProfilingState::Uninitialised:
47 case ProfilingState::Active:
48 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
50 case ProfilingState::NotConnected:
53 BOOST_CHECK_MESSAGE(false, "Invalid profiling state");
57 void SetWaitingForAckProfilingState(ProfilingStateMachine& profilingStateMachine)
59 ProfilingState currentState = profilingStateMachine.GetCurrentState();
62 case ProfilingState::Uninitialised:
64 case ProfilingState::Active:
65 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
67 case ProfilingState::NotConnected:
68 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
70 case ProfilingState::WaitingForAck:
73 BOOST_CHECK_MESSAGE(false, "Invalid profiling state");
77 void SetActiveProfilingState(ProfilingStateMachine& profilingStateMachine)
79 ProfilingState currentState = profilingStateMachine.GetCurrentState();
82 case ProfilingState::Uninitialised:
83 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
85 case ProfilingState::NotConnected:
86 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
88 case ProfilingState::WaitingForAck:
89 profilingStateMachine.TransitionToState(ProfilingState::Active);
91 case ProfilingState::Active:
94 BOOST_CHECK_MESSAGE(false, "Invalid profiling state");
98 } // Anonymous namespace
100 BOOST_AUTO_TEST_SUITE(SendCounterPacketTests)
102 using PacketType = MockProfilingConnection::PacketType;
104 BOOST_AUTO_TEST_CASE(MockSendCounterPacketTest)
106 MockBufferManager mockBuffer(512);
107 MockSendCounterPacket mockSendCounterPacket(mockBuffer);
109 mockSendCounterPacket.SendStreamMetaDataPacket();
111 auto packetBuffer = mockBuffer.GetReadableBuffer();
112 const char* buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
114 BOOST_TEST(strcmp(buffer, "SendStreamMetaDataPacket") == 0);
116 mockBuffer.MarkRead(packetBuffer);
118 CounterDirectory counterDirectory;
119 mockSendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
121 packetBuffer = mockBuffer.GetReadableBuffer();
122 buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
124 BOOST_TEST(strcmp(buffer, "SendCounterDirectoryPacket") == 0);
126 mockBuffer.MarkRead(packetBuffer);
128 uint64_t timestamp = 0;
129 std::vector<CounterValue> indexValuePairs;
131 mockSendCounterPacket.SendPeriodicCounterCapturePacket(timestamp, indexValuePairs);
133 packetBuffer = mockBuffer.GetReadableBuffer();
134 buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
136 BOOST_TEST(strcmp(buffer, "SendPeriodicCounterCapturePacket") == 0);
138 mockBuffer.MarkRead(packetBuffer);
140 uint32_t capturePeriod = 0;
141 std::vector<uint16_t> selectedCounterIds;
142 mockSendCounterPacket.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds);
144 packetBuffer = mockBuffer.GetReadableBuffer();
145 buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
147 BOOST_TEST(strcmp(buffer, "SendPeriodicCounterSelectionPacket") == 0);
149 mockBuffer.MarkRead(packetBuffer);
152 BOOST_AUTO_TEST_CASE(SendPeriodicCounterSelectionPacketTest)
154 // Error no space left in buffer
155 MockBufferManager mockBuffer1(10);
156 SendCounterPacket sendPacket1(mockBuffer1);
158 uint32_t capturePeriod = 1000;
159 std::vector<uint16_t> selectedCounterIds;
160 BOOST_CHECK_THROW(sendPacket1.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds),
163 // Packet without any counters
164 MockBufferManager mockBuffer2(512);
165 SendCounterPacket sendPacket2(mockBuffer2);
167 sendPacket2.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds);
168 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
170 uint32_t headerWord0 = ReadUint32(readBuffer2, 0);
171 uint32_t headerWord1 = ReadUint32(readBuffer2, 4);
172 uint32_t period = ReadUint32(readBuffer2, 8);
174 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
175 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
176 BOOST_TEST(headerWord1 == 4); // data lenght
177 BOOST_TEST(period == 1000); // capture period
179 // Full packet message
180 MockBufferManager mockBuffer3(512);
181 SendCounterPacket sendPacket3(mockBuffer3);
183 selectedCounterIds.reserve(5);
184 selectedCounterIds.emplace_back(100);
185 selectedCounterIds.emplace_back(200);
186 selectedCounterIds.emplace_back(300);
187 selectedCounterIds.emplace_back(400);
188 selectedCounterIds.emplace_back(500);
189 sendPacket3.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds);
190 auto readBuffer3 = mockBuffer3.GetReadableBuffer();
192 headerWord0 = ReadUint32(readBuffer3, 0);
193 headerWord1 = ReadUint32(readBuffer3, 4);
194 period = ReadUint32(readBuffer3, 8);
196 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
197 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
198 BOOST_TEST(headerWord1 == 14); // data lenght
199 BOOST_TEST(period == 1000); // capture period
201 uint16_t counterId = 0;
202 uint32_t offset = 12;
205 for(const uint16_t& id : selectedCounterIds)
207 counterId = ReadUint16(readBuffer3, offset);
208 BOOST_TEST(counterId == id);
213 BOOST_AUTO_TEST_CASE(SendPeriodicCounterCapturePacketTest)
215 ProfilingStateMachine profilingStateMachine;
217 // Error no space left in buffer
218 MockBufferManager mockBuffer1(10);
219 SendCounterPacket sendPacket1(mockBuffer1);
221 auto captureTimestamp = std::chrono::steady_clock::now();
222 uint64_t time = static_cast<uint64_t >(captureTimestamp.time_since_epoch().count());
223 std::vector<CounterValue> indexValuePairs;
225 BOOST_CHECK_THROW(sendPacket1.SendPeriodicCounterCapturePacket(time, indexValuePairs),
228 // Packet without any counters
229 MockBufferManager mockBuffer2(512);
230 SendCounterPacket sendPacket2(mockBuffer2);
232 sendPacket2.SendPeriodicCounterCapturePacket(time, indexValuePairs);
233 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
235 uint32_t headerWord0 = ReadUint32(readBuffer2, 0);
236 uint32_t headerWord1 = ReadUint32(readBuffer2, 4);
237 uint64_t readTimestamp = ReadUint64(readBuffer2, 8);
239 BOOST_TEST(((headerWord0 >> 26) & 0x0000003F) == 3); // packet family
240 BOOST_TEST(((headerWord0 >> 19) & 0x0000007F) == 0); // packet class
241 BOOST_TEST(((headerWord0 >> 16) & 0x00000007) == 0); // packet type
242 BOOST_TEST(headerWord1 == 8); // data length
243 BOOST_TEST(time == readTimestamp); // capture period
245 // Full packet message
246 MockBufferManager mockBuffer3(512);
247 SendCounterPacket sendPacket3(mockBuffer3);
249 indexValuePairs.reserve(5);
250 indexValuePairs.emplace_back(CounterValue{0, 100});
251 indexValuePairs.emplace_back(CounterValue{1, 200});
252 indexValuePairs.emplace_back(CounterValue{2, 300});
253 indexValuePairs.emplace_back(CounterValue{3, 400});
254 indexValuePairs.emplace_back(CounterValue{4, 500});
255 sendPacket3.SendPeriodicCounterCapturePacket(time, indexValuePairs);
256 auto readBuffer3 = mockBuffer3.GetReadableBuffer();
258 headerWord0 = ReadUint32(readBuffer3, 0);
259 headerWord1 = ReadUint32(readBuffer3, 4);
260 uint64_t readTimestamp2 = ReadUint64(readBuffer3, 8);
262 BOOST_TEST(((headerWord0 >> 26) & 0x0000003F) == 3); // packet family
263 BOOST_TEST(((headerWord0 >> 19) & 0x0000007F) == 0); // packet class
264 BOOST_TEST(((headerWord0 >> 16) & 0x00000007) == 0); // packet type
265 BOOST_TEST(headerWord1 == 38); // data length
266 BOOST_TEST(time == readTimestamp2); // capture period
268 uint16_t counterIndex = 0;
269 uint32_t counterValue = 100;
270 uint32_t offset = 16;
273 for (auto it = indexValuePairs.begin(), end = indexValuePairs.end(); it != end; ++it)
275 // Check Counter Index
276 uint16_t readIndex = ReadUint16(readBuffer3, offset);
277 BOOST_TEST(counterIndex == readIndex);
281 // Check Counter Value
282 uint32_t readValue = ReadUint32(readBuffer3, offset);
283 BOOST_TEST(counterValue == readValue);
290 BOOST_AUTO_TEST_CASE(SendStreamMetaDataPacketTest)
292 using boost::numeric_cast;
294 uint32_t sizeUint32 = numeric_cast<uint32_t>(sizeof(uint32_t));
296 // Error no space left in buffer
297 MockBufferManager mockBuffer1(10);
298 SendCounterPacket sendPacket1(mockBuffer1);
299 BOOST_CHECK_THROW(sendPacket1.SendStreamMetaDataPacket(), armnn::profiling::BufferExhaustion);
301 // Full metadata packet
303 std::string processName = GetProcessName().substr(0, 60);
305 uint32_t infoSize = numeric_cast<uint32_t>(GetSoftwareInfo().size()) + 1;
306 uint32_t hardwareVersionSize = numeric_cast<uint32_t>(GetHardwareVersion().size()) + 1;
307 uint32_t softwareVersionSize = numeric_cast<uint32_t>(GetSoftwareVersion().size()) + 1;
308 uint32_t processNameSize = numeric_cast<uint32_t>(processName.size()) + 1;
310 uint32_t packetEntries = 6;
312 MockBufferManager mockBuffer2(512);
313 SendCounterPacket sendPacket2(mockBuffer2);
314 sendPacket2.SendStreamMetaDataPacket();
315 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
317 uint32_t headerWord0 = ReadUint32(readBuffer2, 0);
318 uint32_t headerWord1 = ReadUint32(readBuffer2, sizeUint32);
320 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
321 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 0); // packet id
323 uint32_t totalLength = numeric_cast<uint32_t>(2 * sizeUint32 + 10 * sizeUint32 + infoSize + hardwareVersionSize +
324 softwareVersionSize + processNameSize + sizeUint32 +
325 2 * packetEntries * sizeUint32);
327 BOOST_TEST(headerWord1 == totalLength - (2 * sizeUint32)); // data length
329 uint32_t offset = sizeUint32 * 2;
330 BOOST_TEST(ReadUint32(readBuffer2, offset) == armnnProfiling::PIPE_MAGIC); // pipe_magic
331 offset += sizeUint32;
332 BOOST_TEST(ReadUint32(readBuffer2, offset) == EncodeVersion(1, 0, 0)); // stream_metadata_version
333 offset += sizeUint32;
334 BOOST_TEST(ReadUint32(readBuffer2, offset) == MAX_METADATA_PACKET_LENGTH); // max_data_len
335 offset += sizeUint32;
336 int pid = armnnUtils::Processes::GetCurrentId();
337 BOOST_TEST(ReadUint32(readBuffer2, offset) == numeric_cast<uint32_t>(pid));
338 offset += sizeUint32;
339 uint32_t poolOffset = 10 * sizeUint32;
340 BOOST_TEST(ReadUint32(readBuffer2, offset) == poolOffset); // offset_info
341 offset += sizeUint32;
342 poolOffset += infoSize;
343 BOOST_TEST(ReadUint32(readBuffer2, offset) == poolOffset); // offset_hw_version
344 offset += sizeUint32;
345 poolOffset += hardwareVersionSize;
346 BOOST_TEST(ReadUint32(readBuffer2, offset) == poolOffset); // offset_sw_version
347 offset += sizeUint32;
348 poolOffset += softwareVersionSize;
349 BOOST_TEST(ReadUint32(readBuffer2, offset) == poolOffset); // offset_process_name
350 offset += sizeUint32;
351 poolOffset += processNameSize;
352 BOOST_TEST(ReadUint32(readBuffer2, offset) == poolOffset); // offset_packet_version_table
353 offset += sizeUint32;
354 BOOST_TEST(ReadUint32(readBuffer2, offset) == 0); // reserved
356 const unsigned char* readData2 = readBuffer2->GetReadableData();
358 offset += sizeUint32;
361 BOOST_TEST(strcmp(reinterpret_cast<const char *>(&readData2[offset]), GetSoftwareInfo().c_str()) == 0);
365 if (hardwareVersionSize)
367 BOOST_TEST(strcmp(reinterpret_cast<const char *>(&readData2[offset]), GetHardwareVersion().c_str()) == 0);
368 offset += hardwareVersionSize;
371 if (softwareVersionSize)
373 BOOST_TEST(strcmp(reinterpret_cast<const char *>(&readData2[offset]), GetSoftwareVersion().c_str()) == 0);
374 offset += softwareVersionSize;
379 BOOST_TEST(strcmp(reinterpret_cast<const char *>(&readData2[offset]), GetProcessName().c_str()) == 0);
380 offset += processNameSize;
385 BOOST_TEST((ReadUint32(readBuffer2, offset) >> 16) == packetEntries);
386 offset += sizeUint32;
387 for (uint32_t i = 0; i < packetEntries - 1; ++i)
389 BOOST_TEST(((ReadUint32(readBuffer2, offset) >> 26) & 0x3F) == 0);
390 BOOST_TEST(((ReadUint32(readBuffer2, offset) >> 16) & 0x3FF) == i);
391 offset += sizeUint32;
392 BOOST_TEST(ReadUint32(readBuffer2, offset) == EncodeVersion(1, 0, 0));
393 offset += sizeUint32;
396 BOOST_TEST(((ReadUint32(readBuffer2, offset) >> 26) & 0x3F) == 1);
397 BOOST_TEST(((ReadUint32(readBuffer2, offset) >> 16) & 0x3FF) == 0);
398 offset += sizeUint32;
399 BOOST_TEST(ReadUint32(readBuffer2, offset) == EncodeVersion(1, 0, 0));
400 offset += sizeUint32;
403 BOOST_TEST(offset == totalLength);
406 BOOST_AUTO_TEST_CASE(CreateDeviceRecordTest)
408 MockBufferManager mockBuffer(0);
409 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
411 // Create a device for testing
412 uint16_t deviceUid = 27;
413 const std::string deviceName = "some_device";
414 uint16_t deviceCores = 3;
415 const DevicePtr device = std::make_unique<Device>(deviceUid, deviceName, deviceCores);
417 // Create a device record
418 SendCounterPacket::DeviceRecord deviceRecord;
419 std::string errorMessage;
420 bool result = sendCounterPacketTest.CreateDeviceRecordTest(device, deviceRecord, errorMessage);
423 BOOST_CHECK(errorMessage.empty());
424 BOOST_CHECK(deviceRecord.size() == 6); // Size in words: header [2] + device name [4]
426 uint16_t deviceRecordWord0[]
428 static_cast<uint16_t>(deviceRecord[0] >> 16),
429 static_cast<uint16_t>(deviceRecord[0])
431 BOOST_CHECK(deviceRecordWord0[0] == deviceUid); // uid
432 BOOST_CHECK(deviceRecordWord0[1] == deviceCores); // cores
433 BOOST_CHECK(deviceRecord[1] == 8); // name_offset
434 BOOST_CHECK(deviceRecord[2] == deviceName.size() + 1); // The length of the SWTrace string (name)
435 BOOST_CHECK(std::memcmp(deviceRecord.data() + 3, deviceName.data(), deviceName.size()) == 0); // name
438 BOOST_AUTO_TEST_CASE(CreateInvalidDeviceRecordTest)
440 MockBufferManager mockBuffer(0);
441 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
443 // Create a device for testing
444 uint16_t deviceUid = 27;
445 const std::string deviceName = "some€£invalid‡device";
446 uint16_t deviceCores = 3;
447 const DevicePtr device = std::make_unique<Device>(deviceUid, deviceName, deviceCores);
449 // Create a device record
450 SendCounterPacket::DeviceRecord deviceRecord;
451 std::string errorMessage;
452 bool result = sendCounterPacketTest.CreateDeviceRecordTest(device, deviceRecord, errorMessage);
454 BOOST_CHECK(!result);
455 BOOST_CHECK(!errorMessage.empty());
456 BOOST_CHECK(deviceRecord.empty());
459 BOOST_AUTO_TEST_CASE(CreateCounterSetRecordTest)
461 MockBufferManager mockBuffer(0);
462 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
464 // Create a counter set for testing
465 uint16_t counterSetUid = 27;
466 const std::string counterSetName = "some_counter_set";
467 uint16_t counterSetCount = 3421;
468 const CounterSetPtr counterSet = std::make_unique<CounterSet>(counterSetUid, counterSetName, counterSetCount);
470 // Create a counter set record
471 SendCounterPacket::CounterSetRecord counterSetRecord;
472 std::string errorMessage;
473 bool result = sendCounterPacketTest.CreateCounterSetRecordTest(counterSet, counterSetRecord, errorMessage);
476 BOOST_CHECK(errorMessage.empty());
477 BOOST_CHECK(counterSetRecord.size() == 8); // Size in words: header [2] + counter set name [6]
479 uint16_t counterSetRecordWord0[]
481 static_cast<uint16_t>(counterSetRecord[0] >> 16),
482 static_cast<uint16_t>(counterSetRecord[0])
484 BOOST_CHECK(counterSetRecordWord0[0] == counterSetUid); // uid
485 BOOST_CHECK(counterSetRecordWord0[1] == counterSetCount); // cores
486 BOOST_CHECK(counterSetRecord[1] == 8); // name_offset
487 BOOST_CHECK(counterSetRecord[2] == counterSetName.size() + 1); // The length of the SWTrace string (name)
488 BOOST_CHECK(std::memcmp(counterSetRecord.data() + 3, counterSetName.data(), counterSetName.size()) == 0); // name
491 BOOST_AUTO_TEST_CASE(CreateInvalidCounterSetRecordTest)
493 MockBufferManager mockBuffer(0);
494 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
496 // Create a counter set for testing
497 uint16_t counterSetUid = 27;
498 const std::string counterSetName = "some invalid_counter€£set";
499 uint16_t counterSetCount = 3421;
500 const CounterSetPtr counterSet = std::make_unique<CounterSet>(counterSetUid, counterSetName, counterSetCount);
502 // Create a counter set record
503 SendCounterPacket::CounterSetRecord counterSetRecord;
504 std::string errorMessage;
505 bool result = sendCounterPacketTest.CreateCounterSetRecordTest(counterSet, counterSetRecord, errorMessage);
507 BOOST_CHECK(!result);
508 BOOST_CHECK(!errorMessage.empty());
509 BOOST_CHECK(counterSetRecord.empty());
512 BOOST_AUTO_TEST_CASE(CreateEventRecordTest)
514 MockBufferManager mockBuffer(0);
515 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
517 // Create a counter for testing
518 uint16_t counterUid = 7256;
519 uint16_t maxCounterUid = 132;
520 uint16_t deviceUid = 132;
521 uint16_t counterSetUid = 4497;
522 uint16_t counterClass = 1;
523 uint16_t counterInterpolation = 1;
524 double counterMultiplier = 1234.567f;
525 const std::string counterName = "some_valid_counter";
526 const std::string counterDescription = "a_counter_for_testing";
527 const std::string counterUnits = "Mrads2";
528 const CounterPtr counter = std::make_unique<Counter>(armnn::profiling::BACKEND_ID,
532 counterInterpolation,
539 ARMNN_ASSERT(counter);
541 // Create an event record
542 SendCounterPacket::EventRecord eventRecord;
543 std::string errorMessage;
544 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
547 BOOST_CHECK(errorMessage.empty());
548 BOOST_CHECK(eventRecord.size() == 24); // Size in words: header [8] + counter name [6] + description [7] + units [3]
550 uint16_t eventRecordWord0[]
552 static_cast<uint16_t>(eventRecord[0] >> 16),
553 static_cast<uint16_t>(eventRecord[0])
555 uint16_t eventRecordWord1[]
557 static_cast<uint16_t>(eventRecord[1] >> 16),
558 static_cast<uint16_t>(eventRecord[1])
560 uint16_t eventRecordWord2[]
562 static_cast<uint16_t>(eventRecord[2] >> 16),
563 static_cast<uint16_t>(eventRecord[2])
565 uint32_t eventRecordWord34[]
571 BOOST_CHECK(eventRecordWord0[0] == maxCounterUid); // max_counter_uid
572 BOOST_CHECK(eventRecordWord0[1] == counterUid); // counter_uid
573 BOOST_CHECK(eventRecordWord1[0] == deviceUid); // device
575 BOOST_CHECK(eventRecordWord1[1] == counterSetUid); // counter_set
576 BOOST_CHECK(eventRecordWord2[0] == counterClass); // class
577 BOOST_CHECK(eventRecordWord2[1] == counterInterpolation); // interpolation
578 BOOST_CHECK(std::memcmp(eventRecordWord34, &counterMultiplier, sizeof(counterMultiplier)) == 0); // multiplier
580 ARMNN_NO_CONVERSION_WARN_BEGIN
581 uint32_t eventRecordBlockSize = 8u * sizeof(uint32_t);
582 uint32_t counterNameOffset = eventRecordBlockSize; // The name is the first item in pool
583 uint32_t counterDescriptionOffset = counterNameOffset + // Counter name offset
584 4u + // Counter name length (uint32_t)
585 counterName.size() + // 18u
586 1u + // Null-terminator
587 1u; // Rounding to the next word
589 size_t counterUnitsOffset = counterDescriptionOffset + // Counter description offset
590 4u + // Counter description length (uint32_t)
591 counterDescription.size() + // 21u
592 1u + // Null-terminator
593 2u; // Rounding to the next word
595 ARMNN_NO_CONVERSION_WARN_END
597 BOOST_CHECK(eventRecord[5] == counterNameOffset); // name_offset
598 BOOST_CHECK(eventRecord[6] == counterDescriptionOffset); // description_offset
599 BOOST_CHECK(eventRecord[7] == counterUnitsOffset); // units_offset
601 // Offsets are relative to the start of the eventRecord
602 auto eventRecordPool = reinterpret_cast<unsigned char*>(eventRecord.data());
603 size_t uint32_t_size = sizeof(uint32_t);
605 // The length of the SWTrace string (name)
606 BOOST_CHECK(eventRecordPool[counterNameOffset] == counterName.size() + 1);
608 BOOST_CHECK(std::memcmp(eventRecordPool +
609 counterNameOffset + // Offset
610 uint32_t_size /* The length of the name */,
612 counterName.size()) == 0); // name
613 // The null-terminator at the end of the name
614 BOOST_CHECK(eventRecordPool[counterNameOffset + uint32_t_size + counterName.size()] == '\0');
616 // The length of the SWTrace string (description)
617 BOOST_CHECK(eventRecordPool[counterDescriptionOffset] == counterDescription.size() + 1);
618 // The counter description
619 BOOST_CHECK(std::memcmp(eventRecordPool +
620 counterDescriptionOffset + // Offset
621 uint32_t_size /* The length of the description */,
622 counterDescription.data(),
623 counterDescription.size()) == 0); // description
624 // The null-terminator at the end of the description
625 BOOST_CHECK(eventRecordPool[counterDescriptionOffset + uint32_t_size + counterDescription.size()] == '\0');
627 // The length of the SWTrace namestring (units)
628 BOOST_CHECK(eventRecordPool[counterUnitsOffset] == counterUnits.size() + 1);
630 BOOST_CHECK(std::memcmp(eventRecordPool +
631 counterUnitsOffset + // Offset
632 uint32_t_size /* The length of the units */,
634 counterUnits.size()) == 0); // units
635 // The null-terminator at the end of the units
636 BOOST_CHECK(eventRecordPool[counterUnitsOffset + uint32_t_size + counterUnits.size()] == '\0');
639 BOOST_AUTO_TEST_CASE(CreateEventRecordNoUnitsTest)
641 MockBufferManager mockBuffer(0);
642 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
644 // Create a counter for testing
645 uint16_t counterUid = 44312;
646 uint16_t maxCounterUid = 345;
647 uint16_t deviceUid = 101;
648 uint16_t counterSetUid = 34035;
649 uint16_t counterClass = 0;
650 uint16_t counterInterpolation = 1;
651 double counterMultiplier = 4435.0023f;
652 const std::string counterName = "some_valid_counter";
653 const std::string counterDescription = "a_counter_for_testing";
654 const CounterPtr counter = std::make_unique<Counter>(armnn::profiling::BACKEND_ID,
658 counterInterpolation,
665 ARMNN_ASSERT(counter);
667 // Create an event record
668 SendCounterPacket::EventRecord eventRecord;
669 std::string errorMessage;
670 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
673 BOOST_CHECK(errorMessage.empty());
674 BOOST_CHECK(eventRecord.size() == 21); // Size in words: header [8] + counter name [6] + description [7]
676 uint16_t eventRecordWord0[]
678 static_cast<uint16_t>(eventRecord[0] >> 16),
679 static_cast<uint16_t>(eventRecord[0])
681 uint16_t eventRecordWord1[]
683 static_cast<uint16_t>(eventRecord[1] >> 16),
684 static_cast<uint16_t>(eventRecord[1])
686 uint16_t eventRecordWord2[]
688 static_cast<uint16_t>(eventRecord[2] >> 16),
689 static_cast<uint16_t>(eventRecord[2])
691 uint32_t eventRecordWord34[]
696 BOOST_CHECK(eventRecordWord0[0] == maxCounterUid); // max_counter_uid
697 BOOST_CHECK(eventRecordWord0[1] == counterUid); // counter_uid
698 BOOST_CHECK(eventRecordWord1[0] == deviceUid); // device
699 BOOST_CHECK(eventRecordWord1[1] == counterSetUid); // counter_set
700 BOOST_CHECK(eventRecordWord2[0] == counterClass); // class
701 BOOST_CHECK(eventRecordWord2[1] == counterInterpolation); // interpolation
702 BOOST_CHECK(std::memcmp(eventRecordWord34, &counterMultiplier, sizeof(counterMultiplier)) == 0); // multiplier
704 ARMNN_NO_CONVERSION_WARN_BEGIN
705 uint32_t eventRecordBlockSize = 8u * sizeof(uint32_t);
706 uint32_t counterNameOffset = eventRecordBlockSize; // The name is the first item in pool
707 uint32_t counterDescriptionOffset = counterNameOffset + // Counter name offset
708 4u + // Counter name length (uint32_t)
709 counterName.size() + // 18u
710 1u + // Null-terminator
711 1u; // Rounding to the next word
712 ARMNN_NO_CONVERSION_WARN_END
714 BOOST_CHECK(eventRecord[5] == counterNameOffset); // name_offset
715 BOOST_CHECK(eventRecord[6] == counterDescriptionOffset); // description_offset
716 BOOST_CHECK(eventRecord[7] == 0); // units_offset
718 // Offsets are relative to the start of the eventRecord
719 auto eventRecordPool = reinterpret_cast<unsigned char*>(eventRecord.data());
720 size_t uint32_t_size = sizeof(uint32_t);
722 // The length of the SWTrace string (name)
723 BOOST_CHECK(eventRecordPool[counterNameOffset] == counterName.size() + 1);
725 BOOST_CHECK(std::memcmp(eventRecordPool +
726 counterNameOffset + // Offset
727 uint32_t_size, // The length of the name
729 counterName.size()) == 0); // name
730 // The null-terminator at the end of the name
731 BOOST_CHECK(eventRecordPool[counterNameOffset + uint32_t_size + counterName.size()] == '\0');
733 // The length of the SWTrace string (description)
734 BOOST_CHECK(eventRecordPool[counterDescriptionOffset] == counterDescription.size() + 1);
735 // The counter description
736 BOOST_CHECK(std::memcmp(eventRecordPool +
737 counterDescriptionOffset + // Offset
738 uint32_t_size, // The length of the description
739 counterDescription.data(),
740 counterDescription.size()) == 0); // description
741 // The null-terminator at the end of the description
742 BOOST_CHECK(eventRecordPool[counterDescriptionOffset + uint32_t_size + counterDescription.size()] == '\0');
745 BOOST_AUTO_TEST_CASE(CreateInvalidEventRecordTest1)
747 MockBufferManager mockBuffer(0);
748 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
750 // Create a counter for testing
751 uint16_t counterUid = 7256;
752 uint16_t maxCounterUid = 132;
753 uint16_t deviceUid = 132;
754 uint16_t counterSetUid = 4497;
755 uint16_t counterClass = 1;
756 uint16_t counterInterpolation = 1;
757 double counterMultiplier = 1234.567f;
758 const std::string counterName = "some_invalid_counter £££"; // Invalid name
759 const std::string counterDescription = "a_counter_for_testing";
760 const std::string counterUnits = "Mrads2";
761 const CounterPtr counter = std::make_unique<Counter>(armnn::profiling::BACKEND_ID,
765 counterInterpolation,
772 ARMNN_ASSERT(counter);
774 // Create an event record
775 SendCounterPacket::EventRecord eventRecord;
776 std::string errorMessage;
777 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
779 BOOST_CHECK(!result);
780 BOOST_CHECK(!errorMessage.empty());
781 BOOST_CHECK(eventRecord.empty());
784 BOOST_AUTO_TEST_CASE(CreateInvalidEventRecordTest2)
786 MockBufferManager mockBuffer(0);
787 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
789 // Create a counter for testing
790 uint16_t counterUid = 7256;
791 uint16_t maxCounterUid = 132;
792 uint16_t deviceUid = 132;
793 uint16_t counterSetUid = 4497;
794 uint16_t counterClass = 1;
795 uint16_t counterInterpolation = 1;
796 double counterMultiplier = 1234.567f;
797 const std::string counterName = "some_invalid_counter";
798 const std::string counterDescription = "an invalid d€scription"; // Invalid description
799 const std::string counterUnits = "Mrads2";
800 const CounterPtr counter = std::make_unique<Counter>(armnn::profiling::BACKEND_ID,
804 counterInterpolation,
811 ARMNN_ASSERT(counter);
813 // Create an event record
814 SendCounterPacket::EventRecord eventRecord;
815 std::string errorMessage;
816 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
818 BOOST_CHECK(!result);
819 BOOST_CHECK(!errorMessage.empty());
820 BOOST_CHECK(eventRecord.empty());
823 BOOST_AUTO_TEST_CASE(CreateInvalidEventRecordTest3)
825 MockBufferManager mockBuffer(0);
826 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
828 // Create a counter for testing
829 uint16_t counterUid = 7256;
830 uint16_t maxCounterUid = 132;
831 uint16_t deviceUid = 132;
832 uint16_t counterSetUid = 4497;
833 uint16_t counterClass = 1;
834 uint16_t counterInterpolation = 1;
835 double counterMultiplier = 1234.567f;
836 const std::string counterName = "some_invalid_counter";
837 const std::string counterDescription = "a valid description";
838 const std::string counterUnits = "Mrad s2"; // Invalid units
839 const CounterPtr counter = std::make_unique<Counter>(armnn::profiling::BACKEND_ID,
843 counterInterpolation,
850 ARMNN_ASSERT(counter);
852 // Create an event record
853 SendCounterPacket::EventRecord eventRecord;
854 std::string errorMessage;
855 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
857 BOOST_CHECK(!result);
858 BOOST_CHECK(!errorMessage.empty());
859 BOOST_CHECK(eventRecord.empty());
862 BOOST_AUTO_TEST_CASE(CreateCategoryRecordTest)
864 MockBufferManager mockBuffer(0);
865 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
867 // Create a category for testing
868 const std::string categoryName = "some_category";
869 const CategoryPtr category = std::make_unique<Category>(categoryName);
870 ARMNN_ASSERT(category);
871 category->m_Counters = { 11u, 23u, 5670u };
873 // Create a collection of counters
875 counters.insert(std::make_pair<uint16_t, CounterPtr>(11,
876 CounterPtr(new Counter(armnn::profiling::BACKEND_ID,
887 counters.insert(std::make_pair<uint16_t, CounterPtr>(23,
888 CounterPtr(new Counter(armnn::profiling::BACKEND_ID,
895 "the second counter",
899 counters.insert(std::make_pair<uint16_t, CounterPtr>(5670,
900 CounterPtr(new Counter(armnn::profiling::BACKEND_ID,
906 "and this is number 3",
911 Counter* counter1 = counters.find(11)->second.get();
912 Counter* counter2 = counters.find(23)->second.get();
913 Counter* counter3 = counters.find(5670)->second.get();
914 ARMNN_ASSERT(counter1);
915 ARMNN_ASSERT(counter2);
916 ARMNN_ASSERT(counter3);
917 uint16_t categoryEventCount = boost::numeric_cast<uint16_t>(counters.size());
919 // Create a category record
920 SendCounterPacket::CategoryRecord categoryRecord;
921 std::string errorMessage;
922 bool result = sendCounterPacketTest.CreateCategoryRecordTest(category, counters, categoryRecord, errorMessage);
925 BOOST_CHECK(errorMessage.empty());
926 BOOST_CHECK(categoryRecord.size() == 79); // Size in words: header [3] + event pointer table [3] +
927 // category name [5] + event records [68 = 22 + 20 + 26]
929 uint16_t categoryRecordWord1[]
931 static_cast<uint16_t>(categoryRecord[0] >> 16),
932 static_cast<uint16_t>(categoryRecord[0])
934 BOOST_CHECK(categoryRecordWord1[0] == categoryEventCount); // event_count
935 BOOST_CHECK(categoryRecordWord1[1] == 0); // reserved
937 size_t uint32_t_size = sizeof(uint32_t);
939 ARMNN_NO_CONVERSION_WARN_BEGIN
940 uint32_t categoryRecordBlockSize = 3u * uint32_t_size;
941 uint32_t eventPointerTableOffset = categoryRecordBlockSize; // The event pointer table is the first item in pool
942 uint32_t categoryNameOffset = eventPointerTableOffset + // Event pointer table offset
943 categoryEventCount * uint32_t_size; // The size of the event pointer table
944 ARMNN_NO_CONVERSION_WARN_END
946 BOOST_CHECK(categoryRecord[1] == eventPointerTableOffset); // event_pointer_table_offset
947 BOOST_CHECK(categoryRecord[2] == categoryNameOffset); // name_offset
948 // Offsets are relative to the start of the category record
949 auto categoryRecordPool = reinterpret_cast<unsigned char*>(categoryRecord.data());
951 // The event pointer table
952 uint32_t eventRecord0Offset = categoryRecordPool[eventPointerTableOffset + 0 * uint32_t_size];
953 uint32_t eventRecord1Offset = categoryRecordPool[eventPointerTableOffset + 1 * uint32_t_size];
954 uint32_t eventRecord2Offset = categoryRecordPool[eventPointerTableOffset + 2 * uint32_t_size];
955 BOOST_CHECK(eventRecord0Offset == 32);
956 BOOST_CHECK(eventRecord1Offset == 120);
957 BOOST_CHECK(eventRecord2Offset == 200);
959 // The length of the SWTrace namestring (name)
960 BOOST_CHECK(categoryRecordPool[categoryNameOffset] == categoryName.size() + 1);
962 BOOST_CHECK(std::memcmp(categoryRecordPool +
963 categoryNameOffset + // Offset
964 uint32_t_size, // The length of the name
966 categoryName.size()) == 0); // name
967 // The null-terminator at the end of the name
968 BOOST_CHECK(categoryRecordPool[categoryNameOffset + uint32_t_size + categoryName.size()] == '\0');
970 // For brevity, checking only the UIDs, max counter UIDs and names of the counters in the event records,
971 // as the event records already have a number of unit tests dedicated to them
973 // Counter1 UID and max counter UID
974 uint16_t eventRecord0Word0[2] = { 0u, 0u };
975 std::memcpy(eventRecord0Word0, categoryRecordPool + categoryRecordBlockSize + eventRecord0Offset,
976 sizeof(eventRecord0Word0));
977 BOOST_CHECK(eventRecord0Word0[0] == counter1->m_Uid);
978 BOOST_CHECK(eventRecord0Word0[1] == counter1->m_MaxCounterUid);
981 uint32_t counter1NameOffset = 0;
982 std::memcpy(&counter1NameOffset, categoryRecordPool + eventRecord0Offset + 5u * uint32_t_size, uint32_t_size);
983 BOOST_CHECK(counter1NameOffset == 0);
984 // The length of the SWTrace string (name)
985 BOOST_CHECK(categoryRecordPool[eventRecord0Offset + // Offset to the event record
986 categoryRecordBlockSize + // Offset to the end of the category record block
987 8u * uint32_t_size + // Offset to the event record pool
988 counter1NameOffset // Offset to the name of the counter
989 ] == counter1->m_Name.size() + 1); // The length of the name including the
992 BOOST_CHECK(std::memcmp(categoryRecordPool + // The beginning of the category pool
993 categoryRecordBlockSize + // Offset to the end of the category record block
994 eventRecord0Offset + // Offset to the event record
995 8u * uint32_t_size + // Offset to the event record pool
996 counter1NameOffset + // Offset to the name of the counter
997 uint32_t_size, // The length of the name
998 counter1->m_Name.data(),
999 counter1->m_Name.size()) == 0); // name
1000 // The null-terminator at the end of the counter1 name
1001 BOOST_CHECK(categoryRecordPool[eventRecord0Offset + // Offset to the event record
1002 categoryRecordBlockSize + // Offset to the end of the category record block
1003 8u * uint32_t_size + // Offset to the event record pool
1004 counter1NameOffset + // Offset to the name of the counter
1005 uint32_t_size + // The length of the name
1006 counter1->m_Name.size() // The name of the counter
1010 uint32_t counter2NameOffset = 0;
1011 std::memcpy(&counter2NameOffset, categoryRecordPool +
1012 categoryRecordBlockSize +
1013 eventRecord1Offset +
1016 BOOST_CHECK(counter2NameOffset == 8u * uint32_t_size );
1017 // The length of the SWTrace string (name)
1019 BOOST_CHECK(categoryRecordPool[eventRecord1Offset + // Offset to the event record
1020 categoryRecordBlockSize +
1021 counter2NameOffset // Offset to the name of the counter
1022 ] == counter2->m_Name.size() + 1); // The length of the name including the
1024 // The counter2 name
1025 BOOST_CHECK(std::memcmp(categoryRecordPool + // The beginning of the category pool
1026 categoryRecordBlockSize + // Offset to the end of the category record block
1027 eventRecord1Offset + // Offset to the event record
1028 counter2NameOffset + // Offset to the name of the counter
1029 uint32_t_size, // The length of the name
1030 counter2->m_Name.data(),
1031 counter2->m_Name.size()) == 0); // name
1034 // The null-terminator at the end of the counter2 name
1035 BOOST_CHECK(categoryRecordPool[eventRecord1Offset + // Offset to the event record
1036 categoryRecordBlockSize + // Offset to the end of the category record block
1037 counter2NameOffset + // Offset to the name of the counter
1038 uint32_t_size + // The length of the name
1039 counter2->m_Name.size() // The name of the counter
1043 uint32_t counter3NameOffset = 0;
1044 std::memcpy(&counter3NameOffset, categoryRecordPool + eventRecord2Offset + 5u * uint32_t_size, uint32_t_size);
1045 BOOST_CHECK(counter3NameOffset == 0);
1046 // The length of the SWTrace string (name)
1047 BOOST_CHECK(categoryRecordPool[eventRecord2Offset + // Offset to the event record
1048 categoryRecordBlockSize +
1049 8u * uint32_t_size + // Offset to the event record pool
1050 counter3NameOffset // Offset to the name of the counter
1051 ] == counter3->m_Name.size() + 1); // The length of the name including the
1053 // The counter3 name
1054 BOOST_CHECK(std::memcmp(categoryRecordPool + // The beginning of the category pool
1055 categoryRecordBlockSize +
1056 eventRecord2Offset + // Offset to the event record
1057 8u * uint32_t_size + // Offset to the event record pool
1058 counter3NameOffset + // Offset to the name of the counter
1059 uint32_t_size, // The length of the name
1060 counter3->m_Name.data(),
1061 counter3->m_Name.size()) == 0); // name
1062 // The null-terminator at the end of the counter3 name
1063 BOOST_CHECK(categoryRecordPool[eventRecord2Offset + // Offset to the event record
1064 categoryRecordBlockSize +
1065 8u * uint32_t_size + // Offset to the event record pool
1066 counter3NameOffset + // Offset to the name of the counter
1067 uint32_t_size + // The length of the name
1068 counter3->m_Name.size() // The name of the counter
1072 BOOST_AUTO_TEST_CASE(CreateInvalidCategoryRecordTest1)
1074 MockBufferManager mockBuffer(0);
1075 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
1077 // Create a category for testing
1078 const std::string categoryName = "some invalid category";
1079 const CategoryPtr category = std::make_unique<Category>(categoryName);
1080 BOOST_CHECK(category);
1082 // Create a category record
1084 SendCounterPacket::CategoryRecord categoryRecord;
1085 std::string errorMessage;
1086 bool result = sendCounterPacketTest.CreateCategoryRecordTest(category, counters, categoryRecord, errorMessage);
1088 BOOST_CHECK(!result);
1089 BOOST_CHECK(!errorMessage.empty());
1090 BOOST_CHECK(categoryRecord.empty());
1093 BOOST_AUTO_TEST_CASE(CreateInvalidCategoryRecordTest2)
1095 MockBufferManager mockBuffer(0);
1096 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
1098 // Create a category for testing
1099 const std::string categoryName = "some_category";
1100 const CategoryPtr category = std::make_unique<Category>(categoryName);
1101 BOOST_CHECK(category);
1102 category->m_Counters = { 11u, 23u, 5670u };
1104 // Create a collection of counters
1106 counters.insert(std::make_pair<uint16_t, CounterPtr>(11,
1107 CounterPtr(new Counter(armnn::profiling::BACKEND_ID,
1113 "count€r1", // Invalid name
1114 "the first counter",
1119 Counter* counter1 = counters.find(11)->second.get();
1120 BOOST_CHECK(counter1);
1122 // Create a category record
1123 SendCounterPacket::CategoryRecord categoryRecord;
1124 std::string errorMessage;
1125 bool result = sendCounterPacketTest.CreateCategoryRecordTest(category, counters, categoryRecord, errorMessage);
1127 BOOST_CHECK(!result);
1128 BOOST_CHECK(!errorMessage.empty());
1129 BOOST_CHECK(categoryRecord.empty());
1132 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest1)
1134 // The counter directory used for testing
1135 CounterDirectory counterDirectory;
1137 // Register a device
1138 const std::string device1Name = "device1";
1139 const Device* device1 = nullptr;
1140 BOOST_CHECK_NO_THROW(device1 = counterDirectory.RegisterDevice(device1Name, 3));
1141 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1142 BOOST_CHECK(device1);
1144 // Register a device
1145 const std::string device2Name = "device2";
1146 const Device* device2 = nullptr;
1147 BOOST_CHECK_NO_THROW(device2 = counterDirectory.RegisterDevice(device2Name));
1148 BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
1149 BOOST_CHECK(device2);
1151 // Buffer with not enough space
1152 MockBufferManager mockBuffer(10);
1153 SendCounterPacket sendCounterPacket(mockBuffer);
1154 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory),
1155 armnn::profiling::BufferExhaustion);
1158 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest2)
1160 // The counter directory used for testing
1161 CounterDirectory counterDirectory;
1163 // Register a device
1164 const std::string device1Name = "device1";
1165 const Device* device1 = nullptr;
1166 BOOST_CHECK_NO_THROW(device1 = counterDirectory.RegisterDevice(device1Name, 3));
1167 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1168 BOOST_CHECK(device1);
1170 // Register a device
1171 const std::string device2Name = "device2";
1172 const Device* device2 = nullptr;
1173 BOOST_CHECK_NO_THROW(device2 = counterDirectory.RegisterDevice(device2Name));
1174 BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
1175 BOOST_CHECK(device2);
1177 // Register a counter set
1178 const std::string counterSet1Name = "counterset1";
1179 const CounterSet* counterSet1 = nullptr;
1180 BOOST_CHECK_NO_THROW(counterSet1 = counterDirectory.RegisterCounterSet(counterSet1Name));
1181 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1182 BOOST_CHECK(counterSet1);
1184 // Register a category associated to "device1" and "counterset1"
1185 const std::string category1Name = "category1";
1186 const Category* category1 = nullptr;
1187 BOOST_CHECK_NO_THROW(category1 = counterDirectory.RegisterCategory(category1Name));
1188 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1189 BOOST_CHECK(category1);
1191 // Register a category not associated to "device2" but no counter set
1192 const std::string category2Name = "category2";
1193 const Category* category2 = nullptr;
1194 BOOST_CHECK_NO_THROW(category2 = counterDirectory.RegisterCategory(category2Name));
1195 BOOST_CHECK(counterDirectory.GetCategoryCount() == 2);
1196 BOOST_CHECK(category2);
1198 uint16_t numberOfCores = 4;
1200 // Register a counter associated to "category1"
1201 const Counter* counter1 = nullptr;
1202 BOOST_CHECK_NO_THROW(counter1 = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1209 "counter1description",
1210 std::string("counter1units"),
1212 BOOST_CHECK(counterDirectory.GetCounterCount() == 4);
1213 BOOST_CHECK(counter1);
1215 // Register a counter associated to "category1"
1216 const Counter* counter2 = nullptr;
1217 BOOST_CHECK_NO_THROW(counter2 = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1224 "counter2description",
1225 std::string("counter2units"),
1226 armnn::EmptyOptional(),
1229 BOOST_CHECK(counterDirectory.GetCounterCount() == 5);
1230 BOOST_CHECK(counter2);
1232 // Register a counter associated to "category2"
1233 const Counter* counter3 = nullptr;
1234 BOOST_CHECK_NO_THROW(counter3 = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1241 "counter3description",
1242 armnn::EmptyOptional(),
1245 counterSet1->m_Uid));
1246 BOOST_CHECK(counterDirectory.GetCounterCount() == 9);
1247 BOOST_CHECK(counter3);
1249 // Buffer with enough space
1250 MockBufferManager mockBuffer(1024);
1251 SendCounterPacket sendCounterPacket(mockBuffer);
1252 BOOST_CHECK_NO_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory));
1254 // Get the readable buffer
1255 auto readBuffer = mockBuffer.GetReadableBuffer();
1257 // Check the packet header
1258 const uint32_t packetHeaderWord0 = ReadUint32(readBuffer, 0);
1259 const uint32_t packetHeaderWord1 = ReadUint32(readBuffer, 4);
1260 BOOST_TEST(((packetHeaderWord0 >> 26) & 0x3F) == 0); // packet_family
1261 BOOST_TEST(((packetHeaderWord0 >> 16) & 0x3FF) == 2); // packet_id
1262 BOOST_TEST(packetHeaderWord1 == 432); // data_length
1264 // Check the body header
1265 const uint32_t bodyHeaderWord0 = ReadUint32(readBuffer, 8);
1266 const uint32_t bodyHeaderWord1 = ReadUint32(readBuffer, 12);
1267 const uint32_t bodyHeaderWord2 = ReadUint32(readBuffer, 16);
1268 const uint32_t bodyHeaderWord3 = ReadUint32(readBuffer, 20);
1269 const uint32_t bodyHeaderWord4 = ReadUint32(readBuffer, 24);
1270 const uint32_t bodyHeaderWord5 = ReadUint32(readBuffer, 28);
1271 const uint16_t deviceRecordCount = static_cast<uint16_t>(bodyHeaderWord0 >> 16);
1272 const uint16_t counterSetRecordCount = static_cast<uint16_t>(bodyHeaderWord2 >> 16);
1273 const uint16_t categoryRecordCount = static_cast<uint16_t>(bodyHeaderWord4 >> 16);
1274 BOOST_TEST(deviceRecordCount == 2); // device_records_count
1275 BOOST_TEST(bodyHeaderWord1 == bodyHeaderSize * 4); // device_records_pointer_table_offset
1276 BOOST_TEST(counterSetRecordCount == 1); // counter_set_count
1277 BOOST_TEST(bodyHeaderWord3 == 8 + bodyHeaderSize * 4); // counter_set_pointer_table_offset
1278 BOOST_TEST(categoryRecordCount == 2); // categories_count
1279 BOOST_TEST(bodyHeaderWord5 == 12 + bodyHeaderSize * 4); // categories_pointer_table_offset
1281 // Check the device records pointer table
1282 const uint32_t deviceRecordOffset0 = ReadUint32(readBuffer, 32);
1283 const uint32_t deviceRecordOffset1 = ReadUint32(readBuffer, 36);
1284 BOOST_TEST(deviceRecordOffset0 == 20); // Device record offset for "device1"
1285 BOOST_TEST(deviceRecordOffset1 == 40); // Device record offset for "device2"
1287 // Check the counter set pointer table
1288 const uint32_t counterSetRecordOffset0 = ReadUint32(readBuffer, 40);
1289 BOOST_TEST(counterSetRecordOffset0 == 52); // Counter set record offset for "counterset1"
1291 // Check the category pointer table
1292 const uint32_t categoryRecordOffset0 = ReadUint32(readBuffer, 44);
1293 const uint32_t categoryRecordOffset1 = ReadUint32(readBuffer, 48);
1294 BOOST_TEST(categoryRecordOffset0 == 72); // Category record offset for "category1"
1295 BOOST_TEST(categoryRecordOffset1 == 176); // Category record offset for "category2"
1297 // Get the device record pool offset
1298 const uint32_t uint32_t_size = sizeof(uint32_t);
1299 const uint32_t packetHeaderSize = 2u * uint32_t_size;
1301 // Device record structure/collection used for testing
1306 uint32_t name_offset;
1307 uint32_t name_length;
1310 std::vector<DeviceRecord> deviceRecords;
1311 const uint32_t deviceRecordsPointerTableOffset = packetHeaderSize +
1312 bodyHeaderWord1; // device_records_pointer_table_offset
1314 const unsigned char* readData = readBuffer->GetReadableData();
1316 uint32_t offset = 0;
1317 std::vector<uint32_t> data(800);
1319 for (uint32_t i = 0; i < 800; i+=uint32_t_size)
1321 data[i] = ReadUint32(readBuffer, offset);
1322 offset += uint32_t_size;
1325 std::vector<uint32_t> deviceRecordOffsets(deviceRecordCount);
1326 offset = deviceRecordsPointerTableOffset;
1327 for (uint32_t i = 0; i < deviceRecordCount; ++i)
1329 // deviceRecordOffset is relative to the start of the deviceRecordsPointerTable
1330 deviceRecordOffsets[i] = ReadUint32(readBuffer, offset) + deviceRecordsPointerTableOffset;
1331 offset += uint32_t_size;
1334 for (uint32_t i = 0; i < deviceRecordCount; i++)
1336 // Collect the data for the device record
1337 const uint32_t deviceRecordWord0 = ReadUint32(readBuffer, deviceRecordOffsets[i] + 0 * uint32_t_size);
1338 const uint32_t deviceRecordWord1 = ReadUint32(readBuffer, deviceRecordOffsets[i] + 1 * uint32_t_size);
1339 DeviceRecord deviceRecord;
1340 deviceRecord.uid = static_cast<uint16_t>(deviceRecordWord0 >> 16); // uid
1341 deviceRecord.cores = static_cast<uint16_t>(deviceRecordWord0); // cores
1342 deviceRecord.name_offset = deviceRecordWord1; // name_offset
1344 uint32_t deviceRecordPoolOffset = deviceRecordOffsets[i] + // Packet body offset
1345 deviceRecord.name_offset; // Device name offset
1346 uint32_t deviceRecordNameLength = ReadUint32(readBuffer, deviceRecordPoolOffset);
1347 deviceRecord.name_length = deviceRecordNameLength; // name_length
1348 unsigned char deviceRecordNameNullTerminator = // name null-terminator
1349 ReadUint8(readBuffer, deviceRecordPoolOffset + uint32_t_size + deviceRecordNameLength - 1);
1350 BOOST_CHECK(deviceRecordNameNullTerminator == '\0');
1351 std::vector<unsigned char> deviceRecordNameBuffer(deviceRecord.name_length - 1);
1352 std::memcpy(deviceRecordNameBuffer.data(),
1353 readData + deviceRecordPoolOffset + uint32_t_size, deviceRecordNameBuffer.size());
1354 deviceRecord.name.assign(deviceRecordNameBuffer.begin(), deviceRecordNameBuffer.end()); // name
1356 deviceRecords.push_back(deviceRecord);
1359 // Check that the device records are correct
1360 BOOST_CHECK(deviceRecords.size() == 2);
1361 for (const DeviceRecord& deviceRecord : deviceRecords)
1363 const Device* device = counterDirectory.GetDevice(deviceRecord.uid);
1364 BOOST_CHECK(device);
1365 BOOST_CHECK(device->m_Uid == deviceRecord.uid);
1366 BOOST_CHECK(device->m_Cores == deviceRecord.cores);
1367 BOOST_CHECK(device->m_Name == deviceRecord.name);
1371 // Counter set record structure/collection used for testing
1372 struct CounterSetRecord
1376 uint32_t name_offset;
1377 uint32_t name_length;
1380 std::vector<CounterSetRecord> counterSetRecords;
1381 const uint32_t counterSetRecordsPointerTableOffset = 2u * uint32_t_size + // packet_header
1382 bodyHeaderWord3; // counter_set_pointer_table_offset
1384 offset = counterSetRecordsPointerTableOffset;
1385 std::vector<uint32_t> counterSetRecordOffsets(counterSetRecordCount);
1387 for (uint32_t i = 0; i < counterSetRecordCount; ++i)
1389 // counterSetRecordOffset is relative to the start of the dcounterSetRecordsPointerTable
1390 counterSetRecordOffsets[i] = ReadUint32(readBuffer, offset) + counterSetRecordsPointerTableOffset;
1391 offset += uint32_t_size;
1394 for (uint32_t i = 0; i < counterSetRecordCount; i++)
1396 // Collect the data for the counter set record
1397 const uint32_t counterSetRecordWord0 = ReadUint32(readBuffer, counterSetRecordOffsets[i] + 0 * uint32_t_size);
1398 const uint32_t counterSetRecordWord1 = ReadUint32(readBuffer, counterSetRecordOffsets[i] + 1 * uint32_t_size);
1399 CounterSetRecord counterSetRecord;
1400 counterSetRecord.uid = static_cast<uint16_t>(counterSetRecordWord0 >> 16); // uid
1401 counterSetRecord.count = static_cast<uint16_t>(counterSetRecordWord0); // count
1402 counterSetRecord.name_offset = counterSetRecordWord1; // name_offset
1404 uint32_t counterSetRecordPoolOffset = counterSetRecordOffsets[i] + // Packet body offset
1405 counterSetRecord.name_offset; // Counter set name offset
1406 uint32_t counterSetRecordNameLength = ReadUint32(readBuffer, counterSetRecordPoolOffset);
1407 counterSetRecord.name_length = counterSetRecordNameLength; // name_length
1408 unsigned char counterSetRecordNameNullTerminator = // name null-terminator
1409 ReadUint8(readBuffer, counterSetRecordPoolOffset + uint32_t_size + counterSetRecordNameLength - 1);
1410 BOOST_CHECK(counterSetRecordNameNullTerminator == '\0');
1411 std::vector<unsigned char> counterSetRecordNameBuffer(counterSetRecord.name_length - 1);
1412 std::memcpy(counterSetRecordNameBuffer.data(),
1413 readData + counterSetRecordPoolOffset + uint32_t_size, counterSetRecordNameBuffer.size());
1414 counterSetRecord.name.assign(counterSetRecordNameBuffer.begin(), counterSetRecordNameBuffer.end()); // name
1416 counterSetRecords.push_back(counterSetRecord);
1419 // Check that the counter set records are correct
1420 BOOST_CHECK(counterSetRecords.size() == 1);
1421 for (const CounterSetRecord& counterSetRecord : counterSetRecords)
1423 const CounterSet* counterSet = counterDirectory.GetCounterSet(counterSetRecord.uid);
1424 BOOST_CHECK(counterSet);
1425 BOOST_CHECK(counterSet->m_Uid == counterSetRecord.uid);
1426 BOOST_CHECK(counterSet->m_Count == counterSetRecord.count);
1427 BOOST_CHECK(counterSet->m_Name == counterSetRecord.name);
1430 // Event record structure/collection used for testing
1433 uint16_t counter_uid;
1434 uint16_t max_counter_uid;
1436 uint16_t counter_set;
1437 uint16_t counter_class;
1438 uint16_t interpolation;
1440 uint32_t name_offset;
1441 uint32_t name_length;
1443 uint32_t description_offset;
1444 uint32_t description_length;
1445 std::string description;
1446 uint32_t units_offset;
1447 uint32_t units_length;
1450 // Category record structure/collection used for testing
1451 struct CategoryRecord
1453 uint16_t event_count;
1454 uint32_t event_pointer_table_offset;
1455 uint32_t name_offset;
1456 uint32_t name_length;
1458 std::vector<uint32_t> event_pointer_table;
1459 std::vector<EventRecord> event_records;
1461 std::vector<CategoryRecord> categoryRecords;
1462 const uint32_t categoryRecordsPointerTableOffset = 2u * uint32_t_size + // packet_header
1463 bodyHeaderWord5; // categories_pointer_table_offset
1465 offset = categoryRecordsPointerTableOffset;
1466 std::vector<uint32_t> categoryRecordOffsets(categoryRecordCount);
1467 for (uint32_t i = 0; i < categoryRecordCount; ++i)
1469 // categoryRecordOffset is relative to the start of the categoryRecordsPointerTable
1470 categoryRecordOffsets[i] = ReadUint32(readBuffer, offset) + categoryRecordsPointerTableOffset;
1471 offset += uint32_t_size;
1474 for (uint32_t i = 0; i < categoryRecordCount; i++)
1476 // Collect the data for the category record
1477 const uint32_t categoryRecordWord1 = ReadUint32(readBuffer, categoryRecordOffsets[i] + 0 * uint32_t_size);
1478 const uint32_t categoryRecordWord2 = ReadUint32(readBuffer, categoryRecordOffsets[i] + 1 * uint32_t_size);
1479 const uint32_t categoryRecordWord3 = ReadUint32(readBuffer, categoryRecordOffsets[i] + 2 * uint32_t_size);
1480 CategoryRecord categoryRecord;
1481 categoryRecord.event_count = static_cast<uint16_t>(categoryRecordWord1 >> 16); // event_count
1482 categoryRecord.event_pointer_table_offset = categoryRecordWord2; // event_pointer_table_offset
1483 categoryRecord.name_offset = categoryRecordWord3; // name_offset
1485 uint32_t categoryRecordNameLength = ReadUint32(readBuffer,
1486 categoryRecordOffsets[i] + categoryRecord.name_offset);
1487 categoryRecord.name_length = categoryRecordNameLength; // name_length
1488 unsigned char categoryRecordNameNullTerminator =
1489 ReadUint8(readBuffer,
1490 categoryRecordOffsets[i] +
1491 categoryRecord.name_offset +
1493 categoryRecordNameLength - 1); // name null-terminator
1494 BOOST_CHECK(categoryRecordNameNullTerminator == '\0');
1495 std::vector<unsigned char> categoryRecordNameBuffer(categoryRecord.name_length - 1);
1496 std::memcpy(categoryRecordNameBuffer.data(),
1498 categoryRecordOffsets[i] +
1499 categoryRecord.name_offset +
1501 categoryRecordNameBuffer.size());
1502 categoryRecord.name.assign(categoryRecordNameBuffer.begin(), categoryRecordNameBuffer.end()); // name
1504 categoryRecord.event_pointer_table.resize(categoryRecord.event_count);
1505 offset = categoryRecordOffsets[i] + categoryRecord.event_pointer_table_offset;
1506 for (uint32_t eventOffsetIndex = 0; eventOffsetIndex < categoryRecord.event_count; ++eventOffsetIndex)
1508 // eventRecordOffset is relative to the start of the event pointer table
1509 categoryRecord.event_pointer_table[eventOffsetIndex] = ReadUint32(readBuffer, offset) +
1510 categoryRecordOffsets[i] +
1511 categoryRecord.event_pointer_table_offset;
1512 offset += uint32_t_size;
1515 for (uint32_t eventIndex = 0; eventIndex < categoryRecord.event_count; eventIndex++)
1517 const uint32_t eventOffset = categoryRecord.event_pointer_table[eventIndex];
1518 // Collect the data for the event record
1519 const uint32_t eventRecordWord0 = ReadUint32(readBuffer, eventOffset + 0 * uint32_t_size);
1520 const uint32_t eventRecordWord1 = ReadUint32(readBuffer, eventOffset + 1 * uint32_t_size);
1521 const uint32_t eventRecordWord2 = ReadUint32(readBuffer, eventOffset + 2 * uint32_t_size);
1522 const uint64_t eventRecordWord34 = ReadUint64(readBuffer, eventOffset + 3 * uint32_t_size);
1523 const uint32_t eventRecordWord5 = ReadUint32(readBuffer, eventOffset + 5 * uint32_t_size);
1524 const uint32_t eventRecordWord6 = ReadUint32(readBuffer, eventOffset + 6 * uint32_t_size);
1525 const uint32_t eventRecordWord7 = ReadUint32(readBuffer, eventOffset + 7 * uint32_t_size);
1527 EventRecord eventRecord;
1528 eventRecord.counter_uid = static_cast<uint16_t>(eventRecordWord0); // counter_uid
1529 eventRecord.max_counter_uid = static_cast<uint16_t>(eventRecordWord0 >> 16); // max_counter_uid
1530 eventRecord.device = static_cast<uint16_t>(eventRecordWord1 >> 16); // device
1531 eventRecord.counter_set = static_cast<uint16_t>(eventRecordWord1); // counter_set
1532 eventRecord.counter_class = static_cast<uint16_t>(eventRecordWord2 >> 16); // class
1533 eventRecord.interpolation = static_cast<uint16_t>(eventRecordWord2); // interpolation
1534 std::memcpy(&eventRecord.multiplier, &eventRecordWord34, sizeof(eventRecord.multiplier)); // multiplier
1535 eventRecord.name_offset = static_cast<uint32_t>(eventRecordWord5); // name_offset
1536 eventRecord.description_offset = static_cast<uint32_t>(eventRecordWord6); // description_offset
1537 eventRecord.units_offset = static_cast<uint32_t>(eventRecordWord7); // units_offset
1539 uint32_t eventRecordNameLength = ReadUint32(readBuffer, eventOffset + eventRecord.name_offset);
1540 eventRecord.name_length = eventRecordNameLength; // name_length
1541 unsigned char eventRecordNameNullTerminator =
1542 ReadUint8(readBuffer,
1544 eventRecord.name_offset +
1546 eventRecordNameLength - 1); // name null-terminator
1547 BOOST_CHECK(eventRecordNameNullTerminator == '\0');
1548 std::vector<unsigned char> eventRecordNameBuffer(eventRecord.name_length - 1);
1549 std::memcpy(eventRecordNameBuffer.data(),
1552 eventRecord.name_offset +
1554 eventRecordNameBuffer.size());
1555 eventRecord.name.assign(eventRecordNameBuffer.begin(), eventRecordNameBuffer.end()); // name
1557 uint32_t eventRecordDescriptionLength = ReadUint32(readBuffer,
1558 eventOffset + eventRecord.description_offset);
1559 eventRecord.description_length = eventRecordDescriptionLength; // description_length
1560 unsigned char eventRecordDescriptionNullTerminator =
1561 ReadUint8(readBuffer,
1563 eventRecord.description_offset +
1565 eventRecordDescriptionLength - 1); // description null-terminator
1566 BOOST_CHECK(eventRecordDescriptionNullTerminator == '\0');
1567 std::vector<unsigned char> eventRecordDescriptionBuffer(eventRecord.description_length - 1);
1568 std::memcpy(eventRecordDescriptionBuffer.data(),
1571 eventRecord.description_offset +
1573 eventRecordDescriptionBuffer.size());
1574 eventRecord.description.assign(eventRecordDescriptionBuffer.begin(),
1575 eventRecordDescriptionBuffer.end()); // description
1577 if (eventRecord.units_offset > 0)
1579 uint32_t eventRecordUnitsLength = ReadUint32(readBuffer,
1580 eventOffset + eventRecord.units_offset);
1581 eventRecord.units_length = eventRecordUnitsLength; // units_length
1582 unsigned char eventRecordUnitsNullTerminator =
1583 ReadUint8(readBuffer,
1585 eventRecord.units_offset +
1587 eventRecordUnitsLength - 1); // units null-terminator
1588 BOOST_CHECK(eventRecordUnitsNullTerminator == '\0');
1589 std::vector<unsigned char> eventRecordUnitsBuffer(eventRecord.units_length - 1);
1590 std::memcpy(eventRecordUnitsBuffer.data(),
1593 eventRecord.units_offset +
1595 eventRecordUnitsBuffer.size());
1596 eventRecord.units.assign(eventRecordUnitsBuffer.begin(), eventRecordUnitsBuffer.end()); // units
1599 categoryRecord.event_records.push_back(eventRecord);
1602 categoryRecords.push_back(categoryRecord);
1605 // Check that the category records are correct
1606 BOOST_CHECK(categoryRecords.size() == 2);
1607 for (const CategoryRecord& categoryRecord : categoryRecords)
1609 const Category* category = counterDirectory.GetCategory(categoryRecord.name);
1610 BOOST_CHECK(category);
1611 BOOST_CHECK(category->m_Name == categoryRecord.name);
1612 BOOST_CHECK(category->m_Counters.size() == categoryRecord.event_count + static_cast<size_t>(numberOfCores) -1);
1613 BOOST_CHECK(category->m_Counters.size() == categoryRecord.event_count + static_cast<size_t>(numberOfCores) -1);
1615 // Check that the event records are correct
1616 for (const EventRecord& eventRecord : categoryRecord.event_records)
1618 const Counter* counter = counterDirectory.GetCounter(eventRecord.counter_uid);
1619 BOOST_CHECK(counter);
1620 BOOST_CHECK(counter->m_MaxCounterUid == eventRecord.max_counter_uid);
1621 BOOST_CHECK(counter->m_DeviceUid == eventRecord.device);
1622 BOOST_CHECK(counter->m_CounterSetUid == eventRecord.counter_set);
1623 BOOST_CHECK(counter->m_Class == eventRecord.counter_class);
1624 BOOST_CHECK(counter->m_Interpolation == eventRecord.interpolation);
1625 BOOST_CHECK(counter->m_Multiplier == eventRecord.multiplier);
1626 BOOST_CHECK(counter->m_Name == eventRecord.name);
1627 BOOST_CHECK(counter->m_Description == eventRecord.description);
1628 BOOST_CHECK(counter->m_Units == eventRecord.units);
1633 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest3)
1635 // Using a mock counter directory that allows to register invalid objects
1636 MockCounterDirectory counterDirectory;
1638 // Register an invalid device
1639 const std::string deviceName = "inv@lid dev!c€";
1640 const Device* device = nullptr;
1641 BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName, 3));
1642 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1643 BOOST_CHECK(device);
1645 // Buffer with enough space
1646 MockBufferManager mockBuffer(1024);
1647 SendCounterPacket sendCounterPacket(mockBuffer);
1648 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1651 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest4)
1653 // Using a mock counter directory that allows to register invalid objects
1654 MockCounterDirectory counterDirectory;
1656 // Register an invalid counter set
1657 const std::string counterSetName = "inv@lid count€rs€t";
1658 const CounterSet* counterSet = nullptr;
1659 BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1660 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1661 BOOST_CHECK(counterSet);
1663 // Buffer with enough space
1664 MockBufferManager mockBuffer(1024);
1665 SendCounterPacket sendCounterPacket(mockBuffer);
1666 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1669 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest5)
1671 // Using a mock counter directory that allows to register invalid objects
1672 MockCounterDirectory counterDirectory;
1674 // Register an invalid category
1675 const std::string categoryName = "c@t€gory";
1676 const Category* category = nullptr;
1677 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName));
1678 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1679 BOOST_CHECK(category);
1681 // Buffer with enough space
1682 MockBufferManager mockBuffer(1024);
1683 SendCounterPacket sendCounterPacket(mockBuffer);
1684 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1687 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest6)
1689 // Using a mock counter directory that allows to register invalid objects
1690 MockCounterDirectory counterDirectory;
1692 // Register an invalid device
1693 const std::string deviceName = "inv@lid dev!c€";
1694 const Device* device = nullptr;
1695 BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName, 3));
1696 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1697 BOOST_CHECK(device);
1699 // Register an invalid counter set
1700 const std::string counterSetName = "inv@lid count€rs€t";
1701 const CounterSet* counterSet = nullptr;
1702 BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1703 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1704 BOOST_CHECK(counterSet);
1706 // Register an invalid category associated to an invalid device and an invalid counter set
1707 const std::string categoryName = "c@t€gory";
1708 const Category* category = nullptr;
1709 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName));
1710 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1711 BOOST_CHECK(category);
1713 // Buffer with enough space
1714 MockBufferManager mockBuffer(1024);
1715 SendCounterPacket sendCounterPacket(mockBuffer);
1716 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1719 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest7)
1721 // Using a mock counter directory that allows to register invalid objects
1722 MockCounterDirectory counterDirectory;
1724 // Register an valid device
1725 const std::string deviceName = "valid device";
1726 const Device* device = nullptr;
1727 BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName, 3));
1728 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1729 BOOST_CHECK(device);
1731 // Register an valid counter set
1732 const std::string counterSetName = "valid counterset";
1733 const CounterSet* counterSet = nullptr;
1734 BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1735 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1736 BOOST_CHECK(counterSet);
1738 // Register an valid category associated to a valid device and a valid counter set
1739 const std::string categoryName = "category";
1740 const Category* category = nullptr;
1741 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName));
1742 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1743 BOOST_CHECK(category);
1745 // Register an invalid counter associated to a valid category
1746 const Counter* counter = nullptr;
1747 BOOST_CHECK_NO_THROW(counter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1754 "counter description",
1755 std::string("invalid counter units"),
1758 counterSet->m_Uid));
1759 BOOST_CHECK(counterDirectory.GetCounterCount() == 5);
1760 BOOST_CHECK(counter);
1762 // Buffer with enough space
1763 MockBufferManager mockBuffer(1024);
1764 SendCounterPacket sendCounterPacket(mockBuffer);
1765 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1768 BOOST_AUTO_TEST_CASE(SendThreadTest0)
1770 ProfilingStateMachine profilingStateMachine;
1771 SetActiveProfilingState(profilingStateMachine);
1773 MockProfilingConnection mockProfilingConnection;
1774 MockStreamCounterBuffer mockStreamCounterBuffer(0);
1775 SendCounterPacket sendCounterPacket(mockStreamCounterBuffer);
1776 SendThread sendThread(profilingStateMachine, mockStreamCounterBuffer, sendCounterPacket);
1778 // Try to start the send thread many times, it must only start once
1780 sendThread.Start(mockProfilingConnection);
1781 BOOST_CHECK(sendThread.IsRunning());
1782 sendThread.Start(mockProfilingConnection);
1783 sendThread.Start(mockProfilingConnection);
1784 sendThread.Start(mockProfilingConnection);
1785 sendThread.Start(mockProfilingConnection);
1786 BOOST_CHECK(sendThread.IsRunning());
1789 BOOST_CHECK(!sendThread.IsRunning());
1792 BOOST_AUTO_TEST_CASE(SendThreadTest1)
1794 ProfilingStateMachine profilingStateMachine;
1795 SetActiveProfilingState(profilingStateMachine);
1797 unsigned int totalWrittenSize = 0;
1799 MockProfilingConnection mockProfilingConnection;
1800 MockStreamCounterBuffer mockStreamCounterBuffer(1024);
1801 SendCounterPacket sendCounterPacket(mockStreamCounterBuffer);
1802 SendThread sendThread(profilingStateMachine, mockStreamCounterBuffer, sendCounterPacket);
1803 sendThread.Start(mockProfilingConnection);
1805 // Interleaving writes and reads to/from the buffer with pauses to test that the send thread actually waits for
1806 // something to become available for reading
1808 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
1810 CounterDirectory counterDirectory;
1811 sendCounterPacket.SendStreamMetaDataPacket();
1813 totalWrittenSize += GetStreamMetaDataPacketSize();
1815 sendThread.SetReadyToRead();
1817 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
1819 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
1821 // Get the size of the Counter Directory Packet
1822 unsigned int counterDirectoryPacketSize = 32;
1823 totalWrittenSize += counterDirectoryPacketSize;
1825 sendThread.SetReadyToRead();
1827 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
1829 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
1835 // Get the size of the Periodic Counter Capture Packet
1836 unsigned int periodicCounterCapturePacketSize = 28;
1837 totalWrittenSize += periodicCounterCapturePacketSize;
1839 sendThread.SetReadyToRead();
1841 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
1843 sendCounterPacket.SendPeriodicCounterCapturePacket(44u,
1848 // Get the size of the Periodic Counter Capture Packet
1849 periodicCounterCapturePacketSize = 22;
1850 totalWrittenSize += periodicCounterCapturePacketSize;
1852 sendCounterPacket.SendPeriodicCounterCapturePacket(1234u,
1861 // Get the size of the Periodic Counter Capture Packet
1862 periodicCounterCapturePacketSize = 46;
1863 totalWrittenSize += periodicCounterCapturePacketSize;
1865 sendCounterPacket.SendPeriodicCounterCapturePacket(997u,
1873 // Get the size of the Periodic Counter Capture Packet
1874 periodicCounterCapturePacketSize = 40;
1875 totalWrittenSize += periodicCounterCapturePacketSize;
1877 sendThread.SetReadyToRead();
1879 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
1881 sendCounterPacket.SendPeriodicCounterSelectionPacket(1000u, { 1345u, 254u, 4536u, 408u, 54u, 6323u, 428u, 1u, 6u });
1883 // Get the size of the Periodic Counter Capture Packet
1884 periodicCounterCapturePacketSize = 30;
1885 totalWrittenSize += periodicCounterCapturePacketSize;
1887 sendThread.SetReadyToRead();
1889 // To test an exact value of the "read size" in the mock buffer, wait to allow the send thread to
1890 // read all what's remaining in the buffer
1891 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
1895 BOOST_CHECK(mockStreamCounterBuffer.GetCommittedSize() == totalWrittenSize);
1896 BOOST_CHECK(mockStreamCounterBuffer.GetReadableSize() == totalWrittenSize);
1897 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() == totalWrittenSize);
1900 BOOST_AUTO_TEST_CASE(SendThreadTest2)
1902 ProfilingStateMachine profilingStateMachine;
1903 SetActiveProfilingState(profilingStateMachine);
1905 unsigned int totalWrittenSize = 0;
1907 MockProfilingConnection mockProfilingConnection;
1908 MockStreamCounterBuffer mockStreamCounterBuffer(1024);
1909 SendCounterPacket sendCounterPacket(mockStreamCounterBuffer);
1910 SendThread sendThread(profilingStateMachine, mockStreamCounterBuffer, sendCounterPacket);
1911 sendThread.Start(mockProfilingConnection);
1913 // Adding many spurious "ready to read" signals throughout the test to check that the send thread is
1914 // capable of handling unnecessary read requests
1916 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
1918 sendThread.SetReadyToRead();
1920 CounterDirectory counterDirectory;
1921 sendCounterPacket.SendStreamMetaDataPacket();
1923 totalWrittenSize += GetStreamMetaDataPacketSize();
1925 sendThread.SetReadyToRead();
1927 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
1929 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
1931 // Get the size of the Counter Directory Packet
1932 unsigned int counterDirectoryPacketSize = 32;
1933 totalWrittenSize += counterDirectoryPacketSize;
1935 sendThread.SetReadyToRead();
1936 sendThread.SetReadyToRead();
1938 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
1940 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
1946 // Get the size of the Periodic Counter Capture Packet
1947 unsigned int periodicCounterCapturePacketSize = 28;
1948 totalWrittenSize += periodicCounterCapturePacketSize;
1950 sendThread.SetReadyToRead();
1952 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
1954 sendThread.SetReadyToRead();
1955 sendThread.SetReadyToRead();
1956 sendThread.SetReadyToRead();
1958 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
1960 sendThread.SetReadyToRead();
1961 sendCounterPacket.SendPeriodicCounterCapturePacket(44u,
1966 // Get the size of the Periodic Counter Capture Packet
1967 periodicCounterCapturePacketSize = 22;
1968 totalWrittenSize += periodicCounterCapturePacketSize;
1970 sendCounterPacket.SendPeriodicCounterCapturePacket(1234u,
1979 // Get the size of the Periodic Counter Capture Packet
1980 periodicCounterCapturePacketSize = 46;
1981 totalWrittenSize += periodicCounterCapturePacketSize;
1983 sendThread.SetReadyToRead();
1984 sendCounterPacket.SendPeriodicCounterCapturePacket(997u,
1992 // Get the size of the Periodic Counter Capture Packet
1993 periodicCounterCapturePacketSize = 40;
1994 totalWrittenSize += periodicCounterCapturePacketSize;
1996 sendThread.SetReadyToRead();
1997 sendThread.SetReadyToRead();
1999 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
2001 sendCounterPacket.SendPeriodicCounterSelectionPacket(1000u, { 1345u, 254u, 4536u, 408u, 54u, 6323u, 428u, 1u, 6u });
2003 // Get the size of the Periodic Counter Capture Packet
2004 periodicCounterCapturePacketSize = 30;
2005 totalWrittenSize += periodicCounterCapturePacketSize;
2007 sendThread.SetReadyToRead();
2009 // To test an exact value of the "read size" in the mock buffer, wait to allow the send thread to
2010 // read all what's remaining in the buffer
2013 BOOST_CHECK(mockStreamCounterBuffer.GetCommittedSize() == totalWrittenSize);
2014 BOOST_CHECK(mockStreamCounterBuffer.GetReadableSize() == totalWrittenSize);
2015 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() == totalWrittenSize);
2018 BOOST_AUTO_TEST_CASE(SendThreadTest3)
2020 ProfilingStateMachine profilingStateMachine;
2021 SetActiveProfilingState(profilingStateMachine);
2023 unsigned int totalWrittenSize = 0;
2025 MockProfilingConnection mockProfilingConnection;
2026 MockStreamCounterBuffer mockStreamCounterBuffer(1024);
2027 SendCounterPacket sendCounterPacket(mockStreamCounterBuffer);
2028 SendThread sendThread(profilingStateMachine, mockStreamCounterBuffer, sendCounterPacket);
2029 sendThread.Start(mockProfilingConnection);
2031 // Not using pauses or "grace periods" to stress test the send thread
2033 sendThread.SetReadyToRead();
2035 CounterDirectory counterDirectory;
2036 sendCounterPacket.SendStreamMetaDataPacket();
2038 totalWrittenSize += GetStreamMetaDataPacketSize();
2040 sendThread.SetReadyToRead();
2041 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
2043 // Get the size of the Counter Directory Packet
2044 unsigned int counterDirectoryPacketSize =32;
2045 totalWrittenSize += counterDirectoryPacketSize;
2047 sendThread.SetReadyToRead();
2048 sendThread.SetReadyToRead();
2049 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
2055 // Get the size of the Periodic Counter Capture Packet
2056 unsigned int periodicCounterCapturePacketSize = 28;
2057 totalWrittenSize += periodicCounterCapturePacketSize;
2059 sendThread.SetReadyToRead();
2060 sendThread.SetReadyToRead();
2061 sendThread.SetReadyToRead();
2062 sendThread.SetReadyToRead();
2063 sendThread.SetReadyToRead();
2064 sendCounterPacket.SendPeriodicCounterCapturePacket(44u,
2069 // Get the size of the Periodic Counter Capture Packet
2070 periodicCounterCapturePacketSize = 22;
2071 totalWrittenSize += periodicCounterCapturePacketSize;
2073 sendCounterPacket.SendPeriodicCounterCapturePacket(1234u,
2082 // Get the size of the Periodic Counter Capture Packet
2083 periodicCounterCapturePacketSize = 46;
2084 totalWrittenSize += periodicCounterCapturePacketSize;
2086 sendThread.SetReadyToRead();
2087 sendThread.SetReadyToRead();
2088 sendCounterPacket.SendPeriodicCounterCapturePacket(997u,
2096 // Get the size of the Periodic Counter Capture Packet
2097 periodicCounterCapturePacketSize = 40;
2098 totalWrittenSize += periodicCounterCapturePacketSize;
2100 sendThread.SetReadyToRead();
2101 sendThread.SetReadyToRead();
2102 sendCounterPacket.SendPeriodicCounterSelectionPacket(1000u, { 1345u, 254u, 4536u, 408u, 54u, 6323u, 428u, 1u, 6u });
2104 // Get the size of the Periodic Counter Capture Packet
2105 periodicCounterCapturePacketSize = 30;
2106 totalWrittenSize += periodicCounterCapturePacketSize;
2108 sendThread.SetReadyToRead();
2110 // Abruptly terminating the send thread, the amount of data sent may be less that the amount written (the send
2111 // thread is not guaranteed to flush the buffer)
2114 BOOST_CHECK(mockStreamCounterBuffer.GetCommittedSize() == totalWrittenSize);
2115 BOOST_CHECK(mockStreamCounterBuffer.GetReadableSize() <= totalWrittenSize);
2116 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() <= totalWrittenSize);
2117 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() <= mockStreamCounterBuffer.GetReadableSize());
2118 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() <= mockStreamCounterBuffer.GetCommittedSize());
2121 BOOST_AUTO_TEST_CASE(SendCounterPacketTestWithSendThread)
2123 ProfilingStateMachine profilingStateMachine;
2124 SetWaitingForAckProfilingState(profilingStateMachine);
2126 MockProfilingConnection mockProfilingConnection;
2127 BufferManager bufferManager(1, 1024);
2128 SendCounterPacket sendCounterPacket(bufferManager);
2129 SendThread sendThread(profilingStateMachine, bufferManager, sendCounterPacket, -1);
2130 sendThread.Start(mockProfilingConnection);
2132 unsigned int streamMetadataPacketsize = GetStreamMetaDataPacketSize();
2136 // check for packet in ProfilingConnection
2137 BOOST_CHECK(mockProfilingConnection.CheckForPacket({PacketType::StreamMetaData, streamMetadataPacketsize}) == 1);
2139 SetActiveProfilingState(profilingStateMachine);
2140 sendThread.Start(mockProfilingConnection);
2142 // SendCounterDirectoryPacket
2143 CounterDirectory counterDirectory;
2144 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
2147 unsigned int counterDirectoryPacketSize = 32;
2148 // check for packet in ProfilingConnection
2149 BOOST_CHECK(mockProfilingConnection.CheckForPacket(
2150 {PacketType::CounterDirectory, counterDirectoryPacketSize}) == 1);
2152 sendThread.Start(mockProfilingConnection);
2154 // SendPeriodicCounterCapturePacket
2155 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
2163 unsigned int periodicCounterCapturePacketSize = 28;
2164 BOOST_CHECK(mockProfilingConnection.CheckForPacket(
2165 {PacketType::PeriodicCounterCapture, periodicCounterCapturePacketSize}) == 1);
2168 BOOST_AUTO_TEST_CASE(SendThreadBufferTest)
2170 ProfilingStateMachine profilingStateMachine;
2171 SetActiveProfilingState(profilingStateMachine);
2173 MockProfilingConnection mockProfilingConnection;
2174 BufferManager bufferManager(3, 1024);
2175 SendCounterPacket sendCounterPacket(bufferManager);
2176 SendThread sendThread(profilingStateMachine, bufferManager, sendCounterPacket, -1);
2177 sendThread.Start(mockProfilingConnection);
2179 // SendStreamMetaDataPacket
2180 sendCounterPacket.SendStreamMetaDataPacket();
2182 // Read data from the buffer
2183 // Buffer should become readable after commit by SendStreamMetaDataPacket
2184 auto packetBuffer = bufferManager.GetReadableBuffer();
2185 BOOST_TEST(packetBuffer.get());
2187 unsigned int streamMetadataPacketsize = GetStreamMetaDataPacketSize();
2188 BOOST_TEST(packetBuffer->GetSize() == streamMetadataPacketsize);
2190 // Recommit to be read by sendCounterPacket
2191 bufferManager.Commit(packetBuffer, streamMetadataPacketsize);
2193 // SendCounterDirectoryPacket
2194 CounterDirectory counterDirectory;
2195 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
2197 // SendPeriodicCounterCapturePacket
2198 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
2206 // The buffer is read by the send thread so it should not be in the readable buffer.
2207 auto readBuffer = bufferManager.GetReadableBuffer();
2208 BOOST_TEST(!readBuffer);
2210 // Successfully reserved the buffer with requested size
2211 unsigned int reservedSize = 0;
2212 auto reservedBuffer = bufferManager.Reserve(512, reservedSize);
2213 BOOST_TEST(reservedSize == 512);
2214 BOOST_TEST(reservedBuffer.get());
2216 const auto writtenDataSize = mockProfilingConnection.GetWrittenDataSize();
2217 const auto metaDataPacketCount =
2218 mockProfilingConnection.CheckForPacket({PacketType::StreamMetaData, streamMetadataPacketsize});
2220 BOOST_TEST(metaDataPacketCount >= 1);
2221 BOOST_TEST(mockProfilingConnection.CheckForPacket({PacketType::CounterDirectory, 32}) == 1);
2222 BOOST_TEST(mockProfilingConnection.CheckForPacket({PacketType::PeriodicCounterCapture, 28}) == 1);
2223 // Check that we only received the packets we expected
2224 BOOST_TEST(metaDataPacketCount + 2 == writtenDataSize);
2227 BOOST_AUTO_TEST_CASE(SendThreadSendStreamMetadataPacket1)
2229 ProfilingStateMachine profilingStateMachine;
2231 MockProfilingConnection mockProfilingConnection;
2232 BufferManager bufferManager(3, 1024);
2233 SendCounterPacket sendCounterPacket(bufferManager);
2234 SendThread sendThread(profilingStateMachine, bufferManager, sendCounterPacket);
2235 sendThread.Start(mockProfilingConnection);
2237 // The profiling state is set to "Uninitialized", so the send thread should throw an exception
2238 BOOST_CHECK_THROW(sendThread.Stop(), armnn::RuntimeException);
2241 BOOST_AUTO_TEST_CASE(SendThreadSendStreamMetadataPacket2)
2243 ProfilingStateMachine profilingStateMachine;
2244 SetNotConnectedProfilingState(profilingStateMachine);
2246 MockProfilingConnection mockProfilingConnection;
2247 BufferManager bufferManager(3, 1024);
2248 SendCounterPacket sendCounterPacket(bufferManager);
2249 SendThread sendThread(profilingStateMachine, bufferManager, sendCounterPacket);
2250 sendThread.Start(mockProfilingConnection);
2252 // The profiling state is set to "NotConnected", so the send thread should throw an exception
2253 BOOST_CHECK_THROW(sendThread.Stop(), armnn::RuntimeException);
2256 BOOST_AUTO_TEST_CASE(SendThreadSendStreamMetadataPacket3)
2258 ProfilingStateMachine profilingStateMachine;
2259 SetWaitingForAckProfilingState(profilingStateMachine);
2261 unsigned int streamMetadataPacketsize = GetStreamMetaDataPacketSize();
2263 MockProfilingConnection mockProfilingConnection;
2264 BufferManager bufferManager(3, 1024);
2265 SendCounterPacket sendCounterPacket(bufferManager);
2266 SendThread sendThread(profilingStateMachine, bufferManager, sendCounterPacket);
2267 sendThread.Start(mockProfilingConnection);
2269 // The profiling state is set to "WaitingForAck", so the send thread should send a Stream Metadata packet
2270 // Wait for sendThread to join
2271 BOOST_CHECK_NO_THROW(sendThread.Stop());
2273 // Check that the buffer contains at least one Stream Metadata packet and no other packets
2274 const auto writtenDataSize = mockProfilingConnection.GetWrittenDataSize();
2276 BOOST_TEST(writtenDataSize >= 1);
2277 BOOST_TEST(mockProfilingConnection.CheckForPacket(
2278 {PacketType::StreamMetaData, streamMetadataPacketsize}) == writtenDataSize);
2281 BOOST_AUTO_TEST_CASE(SendThreadSendStreamMetadataPacket4)
2283 ProfilingStateMachine profilingStateMachine;
2284 SetWaitingForAckProfilingState(profilingStateMachine);
2286 unsigned int streamMetadataPacketsize = GetStreamMetaDataPacketSize();
2288 MockProfilingConnection mockProfilingConnection;
2289 BufferManager bufferManager(3, 1024);
2290 SendCounterPacket sendCounterPacket(bufferManager);
2291 SendThread sendThread(profilingStateMachine, bufferManager, sendCounterPacket);
2292 sendThread.Start(mockProfilingConnection);
2294 // The profiling state is set to "WaitingForAck", so the send thread should send a Stream Metadata packet
2295 // Wait for sendThread to join
2298 sendThread.Start(mockProfilingConnection);
2299 // Check that the profiling state is still "WaitingForAck"
2300 BOOST_TEST((profilingStateMachine.GetCurrentState() == ProfilingState::WaitingForAck));
2302 // Check that the buffer contains at least one Stream Metadata packet
2303 BOOST_TEST(mockProfilingConnection.CheckForPacket({PacketType::StreamMetaData, streamMetadataPacketsize}) >= 1);
2305 mockProfilingConnection.Clear();
2308 sendThread.Start(mockProfilingConnection);
2310 // Try triggering a new buffer read
2311 sendThread.SetReadyToRead();
2313 // Wait for sendThread to join
2314 BOOST_CHECK_NO_THROW(sendThread.Stop());
2316 // Check that the profiling state is still "WaitingForAck"
2317 BOOST_TEST((profilingStateMachine.GetCurrentState() == ProfilingState::WaitingForAck));
2319 // Check that the buffer contains at least one Stream Metadata packet and no other packets
2320 const auto writtenDataSize = mockProfilingConnection.GetWrittenDataSize();
2322 BOOST_TEST(writtenDataSize >= 1);
2323 BOOST_TEST(mockProfilingConnection.CheckForPacket(
2324 {PacketType::StreamMetaData, streamMetadataPacketsize}) == writtenDataSize);
2327 BOOST_AUTO_TEST_SUITE_END()