2 // Copyright © 2019 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
6 #include "ProfilingMocks.hpp"
7 #include "SendCounterPacketTests.hpp"
9 #include <BufferManager.hpp>
10 #include <CounterDirectory.hpp>
11 #include <EncodeVersion.hpp>
12 #include <ProfilingUtils.hpp>
13 #include <SendCounterPacket.hpp>
14 #include <Processes.hpp>
16 #include <armnn/Exceptions.hpp>
17 #include <armnn/Conversion.hpp>
18 #include <armnn/Utils.hpp>
20 #include <boost/test/unit_test.hpp>
21 #include <boost/numeric/conversion/cast.hpp>
25 using namespace armnn::profiling;
30 // A short delay to wait for the thread to process a packet.
31 uint16_t constexpr WAIT_UNTIL_READABLE_MS = 20;
33 void SetNotConnectedProfilingState(ProfilingStateMachine& profilingStateMachine)
35 ProfilingState currentState = profilingStateMachine.GetCurrentState();
38 case ProfilingState::WaitingForAck:
39 profilingStateMachine.TransitionToState(ProfilingState::Active);
41 case ProfilingState::Uninitialised:
43 case ProfilingState::Active:
44 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
46 case ProfilingState::NotConnected:
49 BOOST_CHECK_MESSAGE(false, "Invalid profiling state");
53 void SetWaitingForAckProfilingState(ProfilingStateMachine& profilingStateMachine)
55 ProfilingState currentState = profilingStateMachine.GetCurrentState();
58 case ProfilingState::Uninitialised:
60 case ProfilingState::Active:
61 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
63 case ProfilingState::NotConnected:
64 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
66 case ProfilingState::WaitingForAck:
69 BOOST_CHECK_MESSAGE(false, "Invalid profiling state");
73 void SetActiveProfilingState(ProfilingStateMachine& profilingStateMachine)
75 ProfilingState currentState = profilingStateMachine.GetCurrentState();
78 case ProfilingState::Uninitialised:
79 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
81 case ProfilingState::NotConnected:
82 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
84 case ProfilingState::WaitingForAck:
85 profilingStateMachine.TransitionToState(ProfilingState::Active);
87 case ProfilingState::Active:
90 BOOST_CHECK_MESSAGE(false, "Invalid profiling state");
94 } // Anonymous namespace
96 BOOST_AUTO_TEST_SUITE(SendCounterPacketTests)
98 using PacketType = MockProfilingConnection::PacketType;
100 BOOST_AUTO_TEST_CASE(MockSendCounterPacketTest)
102 MockBufferManager mockBuffer(512);
103 MockSendCounterPacket mockSendCounterPacket(mockBuffer);
105 mockSendCounterPacket.SendStreamMetaDataPacket();
107 auto packetBuffer = mockBuffer.GetReadableBuffer();
108 const char* buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
110 BOOST_TEST(strcmp(buffer, "SendStreamMetaDataPacket") == 0);
112 mockBuffer.MarkRead(packetBuffer);
114 CounterDirectory counterDirectory;
115 mockSendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
117 packetBuffer = mockBuffer.GetReadableBuffer();
118 buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
120 BOOST_TEST(strcmp(buffer, "SendCounterDirectoryPacket") == 0);
122 mockBuffer.MarkRead(packetBuffer);
124 uint64_t timestamp = 0;
125 std::vector<CounterValue> indexValuePairs;
127 mockSendCounterPacket.SendPeriodicCounterCapturePacket(timestamp, indexValuePairs);
129 packetBuffer = mockBuffer.GetReadableBuffer();
130 buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
132 BOOST_TEST(strcmp(buffer, "SendPeriodicCounterCapturePacket") == 0);
134 mockBuffer.MarkRead(packetBuffer);
136 uint32_t capturePeriod = 0;
137 std::vector<uint16_t> selectedCounterIds;
138 mockSendCounterPacket.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds);
140 packetBuffer = mockBuffer.GetReadableBuffer();
141 buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
143 BOOST_TEST(strcmp(buffer, "SendPeriodicCounterSelectionPacket") == 0);
145 mockBuffer.MarkRead(packetBuffer);
148 BOOST_AUTO_TEST_CASE(SendPeriodicCounterSelectionPacketTest)
150 // Error no space left in buffer
151 MockBufferManager mockBuffer1(10);
152 SendCounterPacket sendPacket1(mockBuffer1);
154 uint32_t capturePeriod = 1000;
155 std::vector<uint16_t> selectedCounterIds;
156 BOOST_CHECK_THROW(sendPacket1.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds),
159 // Packet without any counters
160 MockBufferManager mockBuffer2(512);
161 SendCounterPacket sendPacket2(mockBuffer2);
163 sendPacket2.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds);
164 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
166 uint32_t headerWord0 = ReadUint32(readBuffer2, 0);
167 uint32_t headerWord1 = ReadUint32(readBuffer2, 4);
168 uint32_t period = ReadUint32(readBuffer2, 8);
170 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
171 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
172 BOOST_TEST(headerWord1 == 4); // data lenght
173 BOOST_TEST(period == 1000); // capture period
175 // Full packet message
176 MockBufferManager mockBuffer3(512);
177 SendCounterPacket sendPacket3(mockBuffer3);
179 selectedCounterIds.reserve(5);
180 selectedCounterIds.emplace_back(100);
181 selectedCounterIds.emplace_back(200);
182 selectedCounterIds.emplace_back(300);
183 selectedCounterIds.emplace_back(400);
184 selectedCounterIds.emplace_back(500);
185 sendPacket3.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds);
186 auto readBuffer3 = mockBuffer3.GetReadableBuffer();
188 headerWord0 = ReadUint32(readBuffer3, 0);
189 headerWord1 = ReadUint32(readBuffer3, 4);
190 period = ReadUint32(readBuffer3, 8);
192 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
193 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
194 BOOST_TEST(headerWord1 == 14); // data lenght
195 BOOST_TEST(period == 1000); // capture period
197 uint16_t counterId = 0;
198 uint32_t offset = 12;
201 for(const uint16_t& id : selectedCounterIds)
203 counterId = ReadUint16(readBuffer3, offset);
204 BOOST_TEST(counterId == id);
209 BOOST_AUTO_TEST_CASE(SendPeriodicCounterCapturePacketTest)
211 ProfilingStateMachine profilingStateMachine;
213 // Error no space left in buffer
214 MockBufferManager mockBuffer1(10);
215 SendCounterPacket sendPacket1(mockBuffer1);
217 auto captureTimestamp = std::chrono::steady_clock::now();
218 uint64_t time = static_cast<uint64_t >(captureTimestamp.time_since_epoch().count());
219 std::vector<CounterValue> indexValuePairs;
221 BOOST_CHECK_THROW(sendPacket1.SendPeriodicCounterCapturePacket(time, indexValuePairs),
224 // Packet without any counters
225 MockBufferManager mockBuffer2(512);
226 SendCounterPacket sendPacket2(mockBuffer2);
228 sendPacket2.SendPeriodicCounterCapturePacket(time, indexValuePairs);
229 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
231 uint32_t headerWord0 = ReadUint32(readBuffer2, 0);
232 uint32_t headerWord1 = ReadUint32(readBuffer2, 4);
233 uint64_t readTimestamp = ReadUint64(readBuffer2, 8);
235 BOOST_TEST(((headerWord0 >> 26) & 0x0000003F) == 3); // packet family
236 BOOST_TEST(((headerWord0 >> 19) & 0x0000007F) == 0); // packet class
237 BOOST_TEST(((headerWord0 >> 16) & 0x00000007) == 0); // packet type
238 BOOST_TEST(headerWord1 == 8); // data length
239 BOOST_TEST(time == readTimestamp); // capture period
241 // Full packet message
242 MockBufferManager mockBuffer3(512);
243 SendCounterPacket sendPacket3(mockBuffer3);
245 indexValuePairs.reserve(5);
246 indexValuePairs.emplace_back(CounterValue{0, 100});
247 indexValuePairs.emplace_back(CounterValue{1, 200});
248 indexValuePairs.emplace_back(CounterValue{2, 300});
249 indexValuePairs.emplace_back(CounterValue{3, 400});
250 indexValuePairs.emplace_back(CounterValue{4, 500});
251 sendPacket3.SendPeriodicCounterCapturePacket(time, indexValuePairs);
252 auto readBuffer3 = mockBuffer3.GetReadableBuffer();
254 headerWord0 = ReadUint32(readBuffer3, 0);
255 headerWord1 = ReadUint32(readBuffer3, 4);
256 uint64_t readTimestamp2 = ReadUint64(readBuffer3, 8);
258 BOOST_TEST(((headerWord0 >> 26) & 0x0000003F) == 3); // packet family
259 BOOST_TEST(((headerWord0 >> 19) & 0x0000007F) == 0); // packet class
260 BOOST_TEST(((headerWord0 >> 16) & 0x00000007) == 0); // packet type
261 BOOST_TEST(headerWord1 == 38); // data length
262 BOOST_TEST(time == readTimestamp2); // capture period
264 uint16_t counterIndex = 0;
265 uint32_t counterValue = 100;
266 uint32_t offset = 16;
269 for (auto it = indexValuePairs.begin(), end = indexValuePairs.end(); it != end; ++it)
271 // Check Counter Index
272 uint16_t readIndex = ReadUint16(readBuffer3, offset);
273 BOOST_TEST(counterIndex == readIndex);
277 // Check Counter Value
278 uint32_t readValue = ReadUint32(readBuffer3, offset);
279 BOOST_TEST(counterValue == readValue);
286 BOOST_AUTO_TEST_CASE(SendStreamMetaDataPacketTest)
288 using boost::numeric_cast;
290 uint32_t sizeUint32 = numeric_cast<uint32_t>(sizeof(uint32_t));
292 // Error no space left in buffer
293 MockBufferManager mockBuffer1(10);
294 SendCounterPacket sendPacket1(mockBuffer1);
295 BOOST_CHECK_THROW(sendPacket1.SendStreamMetaDataPacket(), armnn::profiling::BufferExhaustion);
297 // Full metadata packet
299 std::string processName = GetProcessName().substr(0, 60);
301 uint32_t infoSize = numeric_cast<uint32_t>(GetSoftwareInfo().size()) > 0 ?
302 numeric_cast<uint32_t>(GetSoftwareInfo().size()) + 1 : 0;
303 uint32_t hardwareVersionSize = numeric_cast<uint32_t>(GetHardwareVersion().size()) > 0 ?
304 numeric_cast<uint32_t>(GetHardwareVersion().size()) + 1 : 0;
305 uint32_t softwareVersionSize = numeric_cast<uint32_t>(GetSoftwareVersion().size()) > 0 ?
306 numeric_cast<uint32_t>(GetSoftwareVersion().size()) + 1 : 0;
307 uint32_t processNameSize = numeric_cast<uint32_t>(processName.size()) > 0 ?
308 numeric_cast<uint32_t>(processName.size()) + 1 : 0;
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) == SendCounterPacket::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) == (infoSize ? poolOffset : 0)); // offset_info
341 offset += sizeUint32;
342 poolOffset += infoSize;
343 BOOST_TEST(ReadUint32(readBuffer2, offset) == (hardwareVersionSize ? poolOffset : 0)); // offset_hw_version
344 offset += sizeUint32;
345 poolOffset += hardwareVersionSize;
346 BOOST_TEST(ReadUint32(readBuffer2, offset) == (softwareVersionSize ? poolOffset : 0)); // offset_sw_version
347 offset += sizeUint32;
348 poolOffset += softwareVersionSize;
349 BOOST_TEST(ReadUint32(readBuffer2, offset) == (processNameSize ? poolOffset : 0)); // offset_process_name
350 offset += sizeUint32;
351 poolOffset += processNameSize;
352 BOOST_TEST(ReadUint32(readBuffer2, offset) == (packetEntries ? poolOffset : 0)); // 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] == 0); // 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] == 0); // 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 BOOST_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[]
570 BOOST_CHECK(eventRecordWord0[0] == maxCounterUid); // max_counter_uid
571 BOOST_CHECK(eventRecordWord0[1] == counterUid); // counter_uid
572 BOOST_CHECK(eventRecordWord1[0] == deviceUid); // device
573 BOOST_CHECK(eventRecordWord1[1] == counterSetUid); // counter_set
574 BOOST_CHECK(eventRecordWord2[0] == counterClass); // class
575 BOOST_CHECK(eventRecordWord2[1] == counterInterpolation); // interpolation
576 BOOST_CHECK(std::memcmp(eventRecordWord34, &counterMultiplier, sizeof(counterMultiplier)) == 0); // multiplier
578 ARMNN_NO_CONVERSION_WARN_BEGIN
579 uint32_t counterNameOffset = 0; // The name is the first item in pool
580 uint32_t counterDescriptionOffset = counterNameOffset + // Counter name offset
581 4u + // Counter name length (uint32_t)
582 counterName.size() + // 18u
583 1u + // Null-terminator
584 1u; // Rounding to the next word
585 size_t counterUnitsOffset = counterDescriptionOffset + // Counter description offset
586 4u + // Counter description length (uint32_t)
587 counterDescription.size() + // 21u
588 1u + // Null-terminator
589 2u; // Rounding to the next word
590 ARMNN_NO_CONVERSION_WARN_END
592 BOOST_CHECK(eventRecord[5] == counterNameOffset); // name_offset
593 BOOST_CHECK(eventRecord[6] == counterDescriptionOffset); // description_offset
594 BOOST_CHECK(eventRecord[7] == counterUnitsOffset); // units_offset
596 auto eventRecordPool = reinterpret_cast<unsigned char*>(eventRecord.data() + 8u); // The start of the pool
597 size_t uint32_t_size = sizeof(uint32_t);
599 // The length of the SWTrace string (name)
600 BOOST_CHECK(eventRecordPool[counterNameOffset] == counterName.size() + 1);
602 BOOST_CHECK(std::memcmp(eventRecordPool +
603 counterNameOffset + // Offset
604 uint32_t_size /* The length of the name */,
606 counterName.size()) == 0); // name
607 // The null-terminator at the end of the name
608 BOOST_CHECK(eventRecordPool[counterNameOffset + uint32_t_size + counterName.size()] == '\0');
610 // The length of the SWTrace string (description)
611 BOOST_CHECK(eventRecordPool[counterDescriptionOffset] == counterDescription.size() + 1);
612 // The counter description
613 BOOST_CHECK(std::memcmp(eventRecordPool +
614 counterDescriptionOffset + // Offset
615 uint32_t_size /* The length of the description */,
616 counterDescription.data(),
617 counterDescription.size()) == 0); // description
618 // The null-terminator at the end of the description
619 BOOST_CHECK(eventRecordPool[counterDescriptionOffset + uint32_t_size + counterDescription.size()] == '\0');
621 // The length of the SWTrace namestring (units)
622 BOOST_CHECK(eventRecordPool[counterUnitsOffset] == counterUnits.size() + 1);
624 BOOST_CHECK(std::memcmp(eventRecordPool +
625 counterUnitsOffset + // Offset
626 uint32_t_size /* The length of the units */,
628 counterUnits.size()) == 0); // units
629 // The null-terminator at the end of the units
630 BOOST_CHECK(eventRecordPool[counterUnitsOffset + uint32_t_size + counterUnits.size()] == '\0');
633 BOOST_AUTO_TEST_CASE(CreateEventRecordNoUnitsTest)
635 MockBufferManager mockBuffer(0);
636 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
638 // Create a counter for testing
639 uint16_t counterUid = 44312;
640 uint16_t maxCounterUid = 345;
641 uint16_t deviceUid = 101;
642 uint16_t counterSetUid = 34035;
643 uint16_t counterClass = 0;
644 uint16_t counterInterpolation = 1;
645 double counterMultiplier = 4435.0023f;
646 const std::string counterName = "some_valid_counter";
647 const std::string counterDescription = "a_counter_for_testing";
648 const CounterPtr counter = std::make_unique<Counter>(armnn::profiling::BACKEND_ID,
652 counterInterpolation,
659 BOOST_ASSERT(counter);
661 // Create an event record
662 SendCounterPacket::EventRecord eventRecord;
663 std::string errorMessage;
664 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
667 BOOST_CHECK(errorMessage.empty());
668 BOOST_CHECK(eventRecord.size() == 21); // Size in words: header [8] + counter name [6] + description [7]
670 uint16_t eventRecordWord0[]
672 static_cast<uint16_t>(eventRecord[0] >> 16),
673 static_cast<uint16_t>(eventRecord[0])
675 uint16_t eventRecordWord1[]
677 static_cast<uint16_t>(eventRecord[1] >> 16),
678 static_cast<uint16_t>(eventRecord[1])
680 uint16_t eventRecordWord2[]
682 static_cast<uint16_t>(eventRecord[2] >> 16),
683 static_cast<uint16_t>(eventRecord[2])
685 uint32_t eventRecordWord34[]
690 BOOST_CHECK(eventRecordWord0[0] == maxCounterUid); // max_counter_uid
691 BOOST_CHECK(eventRecordWord0[1] == counterUid); // counter_uid
692 BOOST_CHECK(eventRecordWord1[0] == deviceUid); // device
693 BOOST_CHECK(eventRecordWord1[1] == counterSetUid); // counter_set
694 BOOST_CHECK(eventRecordWord2[0] == counterClass); // class
695 BOOST_CHECK(eventRecordWord2[1] == counterInterpolation); // interpolation
696 BOOST_CHECK(std::memcmp(eventRecordWord34, &counterMultiplier, sizeof(counterMultiplier)) == 0); // multiplier
698 ARMNN_NO_CONVERSION_WARN_BEGIN
699 uint32_t counterNameOffset = 0; // The name is the first item in pool
700 uint32_t counterDescriptionOffset = counterNameOffset + // Counter name offset
701 4u + // Counter name length (uint32_t)
702 counterName.size() + // 18u
703 1u + // Null-terminator
704 1u; // Rounding to the next word
705 ARMNN_NO_CONVERSION_WARN_END
707 BOOST_CHECK(eventRecord[5] == counterNameOffset); // name_offset
708 BOOST_CHECK(eventRecord[6] == counterDescriptionOffset); // description_offset
709 BOOST_CHECK(eventRecord[7] == 0); // units_offset
711 auto eventRecordPool = reinterpret_cast<unsigned char*>(eventRecord.data() + 8u); // The start of the pool
712 size_t uint32_t_size = sizeof(uint32_t);
714 // The length of the SWTrace string (name)
715 BOOST_CHECK(eventRecordPool[counterNameOffset] == counterName.size() + 1);
717 BOOST_CHECK(std::memcmp(eventRecordPool +
718 counterNameOffset + // Offset
719 uint32_t_size, // The length of the name
721 counterName.size()) == 0); // name
722 // The null-terminator at the end of the name
723 BOOST_CHECK(eventRecordPool[counterNameOffset + uint32_t_size + counterName.size()] == '\0');
725 // The length of the SWTrace string (description)
726 BOOST_CHECK(eventRecordPool[counterDescriptionOffset] == counterDescription.size() + 1);
727 // The counter description
728 BOOST_CHECK(std::memcmp(eventRecordPool +
729 counterDescriptionOffset + // Offset
730 uint32_t_size, // The length of the description
731 counterDescription.data(),
732 counterDescription.size()) == 0); // description
733 // The null-terminator at the end of the description
734 BOOST_CHECK(eventRecordPool[counterDescriptionOffset + uint32_t_size + counterDescription.size()] == '\0');
737 BOOST_AUTO_TEST_CASE(CreateInvalidEventRecordTest1)
739 MockBufferManager mockBuffer(0);
740 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
742 // Create a counter for testing
743 uint16_t counterUid = 7256;
744 uint16_t maxCounterUid = 132;
745 uint16_t deviceUid = 132;
746 uint16_t counterSetUid = 4497;
747 uint16_t counterClass = 1;
748 uint16_t counterInterpolation = 1;
749 double counterMultiplier = 1234.567f;
750 const std::string counterName = "some_invalid_counter £££"; // Invalid name
751 const std::string counterDescription = "a_counter_for_testing";
752 const std::string counterUnits = "Mrads2";
753 const CounterPtr counter = std::make_unique<Counter>(armnn::profiling::BACKEND_ID,
757 counterInterpolation,
764 BOOST_ASSERT(counter);
766 // Create an event record
767 SendCounterPacket::EventRecord eventRecord;
768 std::string errorMessage;
769 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
771 BOOST_CHECK(!result);
772 BOOST_CHECK(!errorMessage.empty());
773 BOOST_CHECK(eventRecord.empty());
776 BOOST_AUTO_TEST_CASE(CreateInvalidEventRecordTest2)
778 MockBufferManager mockBuffer(0);
779 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
781 // Create a counter for testing
782 uint16_t counterUid = 7256;
783 uint16_t maxCounterUid = 132;
784 uint16_t deviceUid = 132;
785 uint16_t counterSetUid = 4497;
786 uint16_t counterClass = 1;
787 uint16_t counterInterpolation = 1;
788 double counterMultiplier = 1234.567f;
789 const std::string counterName = "some_invalid_counter";
790 const std::string counterDescription = "an invalid d€scription"; // Invalid description
791 const std::string counterUnits = "Mrads2";
792 const CounterPtr counter = std::make_unique<Counter>(armnn::profiling::BACKEND_ID,
796 counterInterpolation,
803 BOOST_ASSERT(counter);
805 // Create an event record
806 SendCounterPacket::EventRecord eventRecord;
807 std::string errorMessage;
808 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
810 BOOST_CHECK(!result);
811 BOOST_CHECK(!errorMessage.empty());
812 BOOST_CHECK(eventRecord.empty());
815 BOOST_AUTO_TEST_CASE(CreateInvalidEventRecordTest3)
817 MockBufferManager mockBuffer(0);
818 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
820 // Create a counter for testing
821 uint16_t counterUid = 7256;
822 uint16_t maxCounterUid = 132;
823 uint16_t deviceUid = 132;
824 uint16_t counterSetUid = 4497;
825 uint16_t counterClass = 1;
826 uint16_t counterInterpolation = 1;
827 double counterMultiplier = 1234.567f;
828 const std::string counterName = "some_invalid_counter";
829 const std::string counterDescription = "a valid description";
830 const std::string counterUnits = "Mrad s2"; // Invalid units
831 const CounterPtr counter = std::make_unique<Counter>(armnn::profiling::BACKEND_ID,
835 counterInterpolation,
842 BOOST_ASSERT(counter);
844 // Create an event record
845 SendCounterPacket::EventRecord eventRecord;
846 std::string errorMessage;
847 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
849 BOOST_CHECK(!result);
850 BOOST_CHECK(!errorMessage.empty());
851 BOOST_CHECK(eventRecord.empty());
854 BOOST_AUTO_TEST_CASE(CreateCategoryRecordTest)
856 MockBufferManager mockBuffer(0);
857 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
859 // Create a category for testing
860 const std::string categoryName = "some_category";
861 const CategoryPtr category = std::make_unique<Category>(categoryName);
862 BOOST_ASSERT(category);
863 category->m_Counters = { 11u, 23u, 5670u };
865 // Create a collection of counters
867 counters.insert(std::make_pair<uint16_t, CounterPtr>(11,
868 CounterPtr(new Counter(armnn::profiling::BACKEND_ID,
879 counters.insert(std::make_pair<uint16_t, CounterPtr>(23,
880 CounterPtr(new Counter(armnn::profiling::BACKEND_ID,
887 "the second counter",
891 counters.insert(std::make_pair<uint16_t, CounterPtr>(5670,
892 CounterPtr(new Counter(armnn::profiling::BACKEND_ID,
898 "and this is number 3",
903 Counter* counter1 = counters.find(11)->second.get();
904 Counter* counter2 = counters.find(23)->second.get();
905 Counter* counter3 = counters.find(5670)->second.get();
906 BOOST_ASSERT(counter1);
907 BOOST_ASSERT(counter2);
908 BOOST_ASSERT(counter3);
909 uint16_t categoryEventCount = boost::numeric_cast<uint16_t>(counters.size());
911 // Create a category record
912 SendCounterPacket::CategoryRecord categoryRecord;
913 std::string errorMessage;
914 bool result = sendCounterPacketTest.CreateCategoryRecordTest(category, counters, categoryRecord, errorMessage);
917 BOOST_CHECK(errorMessage.empty());
918 BOOST_CHECK(categoryRecord.size() == 79); // Size in words: header [3] + event pointer table [3] +
919 // category name [5] + event records [68 = 22 + 20 + 26]
921 uint16_t categoryRecordWord1[]
923 static_cast<uint16_t>(categoryRecord[0] >> 16),
924 static_cast<uint16_t>(categoryRecord[0])
926 BOOST_CHECK(categoryRecordWord1[0] == categoryEventCount); // event_count
927 BOOST_CHECK(categoryRecordWord1[1] == 0); // reserved
929 size_t uint32_t_size = sizeof(uint32_t);
931 ARMNN_NO_CONVERSION_WARN_BEGIN
932 uint32_t eventPointerTableOffset = 0; // The event pointer table is the first item in pool
933 uint32_t categoryNameOffset = eventPointerTableOffset + // Event pointer table offset
934 categoryEventCount * uint32_t_size; // The size of the event pointer table
935 ARMNN_NO_CONVERSION_WARN_END
937 BOOST_CHECK(categoryRecord[1] == eventPointerTableOffset); // event_pointer_table_offset
938 BOOST_CHECK(categoryRecord[2] == categoryNameOffset); // name_offset
940 auto categoryRecordPool = reinterpret_cast<unsigned char*>(categoryRecord.data() + 3u); // The start of the pool
942 // The event pointer table
943 uint32_t eventRecord0Offset = categoryRecordPool[eventPointerTableOffset + 0 * uint32_t_size];
944 uint32_t eventRecord1Offset = categoryRecordPool[eventPointerTableOffset + 1 * uint32_t_size];
945 uint32_t eventRecord2Offset = categoryRecordPool[eventPointerTableOffset + 2 * uint32_t_size];
946 BOOST_CHECK(eventRecord0Offset == 32);
947 BOOST_CHECK(eventRecord1Offset == 120);
948 BOOST_CHECK(eventRecord2Offset == 200);
950 // The length of the SWTrace namestring (name)
951 BOOST_CHECK(categoryRecordPool[categoryNameOffset] == categoryName.size() + 1);
953 BOOST_CHECK(std::memcmp(categoryRecordPool +
954 categoryNameOffset + // Offset
955 uint32_t_size, // The length of the name
957 categoryName.size()) == 0); // name
958 // The null-terminator at the end of the name
959 BOOST_CHECK(categoryRecordPool[categoryNameOffset + uint32_t_size + categoryName.size()] == '\0');
961 // For brevity, checking only the UIDs, max counter UIDs and names of the counters in the event records,
962 // as the event records already have a number of unit tests dedicated to them
964 // Counter1 UID and max counter UID
965 uint16_t eventRecord0Word0[2] = { 0u, 0u };
966 std::memcpy(eventRecord0Word0, categoryRecordPool + eventRecord0Offset, sizeof(eventRecord0Word0));
967 BOOST_CHECK(eventRecord0Word0[0] == counter1->m_Uid);
968 BOOST_CHECK(eventRecord0Word0[1] == counter1->m_MaxCounterUid);
971 uint32_t counter1NameOffset = 0;
972 std::memcpy(&counter1NameOffset, categoryRecordPool + eventRecord0Offset + 5u * uint32_t_size, uint32_t_size);
973 BOOST_CHECK(counter1NameOffset == 0);
974 // The length of the SWTrace string (name)
975 BOOST_CHECK(categoryRecordPool[eventRecord0Offset + // Offset to the event record
976 8u * uint32_t_size + // Offset to the event record pool
977 counter1NameOffset // Offset to the name of the counter
978 ] == counter1->m_Name.size() + 1); // The length of the name including the
981 BOOST_CHECK(std::memcmp(categoryRecordPool + // The beginning of the category pool
982 eventRecord0Offset + // Offset to the event record
983 8u * uint32_t_size + // Offset to the event record pool
984 counter1NameOffset + // Offset to the name of the counter
985 uint32_t_size, // The length of the name
986 counter1->m_Name.data(),
987 counter1->m_Name.size()) == 0); // name
988 // The null-terminator at the end of the counter1 name
989 BOOST_CHECK(categoryRecordPool[eventRecord0Offset + // Offset to the event record
990 8u * uint32_t_size + // Offset to the event record pool
991 counter1NameOffset + // Offset to the name of the counter
992 uint32_t_size + // The length of the name
993 counter1->m_Name.size() // The name of the counter
997 uint32_t counter2NameOffset = 0;
998 std::memcpy(&counter2NameOffset, categoryRecordPool + eventRecord1Offset + 5u * uint32_t_size, uint32_t_size);
999 BOOST_CHECK(counter2NameOffset == 0);
1000 // The length of the SWTrace string (name)
1001 BOOST_CHECK(categoryRecordPool[eventRecord1Offset + // Offset to the event record
1002 8u * uint32_t_size + // Offset to the event record pool
1003 counter2NameOffset // Offset to the name of the counter
1004 ] == counter2->m_Name.size() + 1); // The length of the name including the
1006 // The counter2 name
1007 BOOST_CHECK(std::memcmp(categoryRecordPool + // The beginning of the category pool
1008 eventRecord1Offset + // Offset to the event record
1009 8u * uint32_t_size + // Offset to the event record pool
1010 counter2NameOffset + // Offset to the name of the counter
1011 uint32_t_size, // The length of the name
1012 counter2->m_Name.data(),
1013 counter2->m_Name.size()) == 0); // name
1014 // The null-terminator at the end of the counter2 name
1015 BOOST_CHECK(categoryRecordPool[eventRecord1Offset + // Offset to the event record
1016 8u * uint32_t_size + // Offset to the event record pool
1017 counter2NameOffset + // Offset to the name of the counter
1018 uint32_t_size + // The length of the name
1019 counter2->m_Name.size() // The name of the counter
1023 uint32_t counter3NameOffset = 0;
1024 std::memcpy(&counter3NameOffset, categoryRecordPool + eventRecord2Offset + 5u * uint32_t_size, uint32_t_size);
1025 BOOST_CHECK(counter3NameOffset == 0);
1026 // The length of the SWTrace string (name)
1027 BOOST_CHECK(categoryRecordPool[eventRecord2Offset + // Offset to the event record
1028 8u * uint32_t_size + // Offset to the event record pool
1029 counter3NameOffset // Offset to the name of the counter
1030 ] == counter3->m_Name.size() + 1); // The length of the name including the
1032 // The counter3 name
1033 BOOST_CHECK(std::memcmp(categoryRecordPool + // The beginning of the category pool
1034 eventRecord2Offset + // Offset to the event record
1035 8u * uint32_t_size + // Offset to the event record pool
1036 counter3NameOffset + // Offset to the name of the counter
1037 uint32_t_size, // The length of the name
1038 counter3->m_Name.data(),
1039 counter3->m_Name.size()) == 0); // name
1040 // The null-terminator at the end of the counter3 name
1041 BOOST_CHECK(categoryRecordPool[eventRecord2Offset + // Offset to the event record
1042 8u * uint32_t_size + // Offset to the event record pool
1043 counter3NameOffset + // Offset to the name of the counter
1044 uint32_t_size + // The length of the name
1045 counter3->m_Name.size() // The name of the counter
1049 BOOST_AUTO_TEST_CASE(CreateInvalidCategoryRecordTest1)
1051 MockBufferManager mockBuffer(0);
1052 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
1054 // Create a category for testing
1055 const std::string categoryName = "some invalid category";
1056 const CategoryPtr category = std::make_unique<Category>(categoryName);
1057 BOOST_CHECK(category);
1059 // Create a category record
1061 SendCounterPacket::CategoryRecord categoryRecord;
1062 std::string errorMessage;
1063 bool result = sendCounterPacketTest.CreateCategoryRecordTest(category, counters, categoryRecord, errorMessage);
1065 BOOST_CHECK(!result);
1066 BOOST_CHECK(!errorMessage.empty());
1067 BOOST_CHECK(categoryRecord.empty());
1070 BOOST_AUTO_TEST_CASE(CreateInvalidCategoryRecordTest2)
1072 MockBufferManager mockBuffer(0);
1073 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
1075 // Create a category for testing
1076 const std::string categoryName = "some_category";
1077 const CategoryPtr category = std::make_unique<Category>(categoryName);
1078 BOOST_CHECK(category);
1079 category->m_Counters = { 11u, 23u, 5670u };
1081 // Create a collection of counters
1083 counters.insert(std::make_pair<uint16_t, CounterPtr>(11,
1084 CounterPtr(new Counter(armnn::profiling::BACKEND_ID,
1090 "count€r1", // Invalid name
1091 "the first counter",
1096 Counter* counter1 = counters.find(11)->second.get();
1097 BOOST_CHECK(counter1);
1099 // Create a category record
1100 SendCounterPacket::CategoryRecord categoryRecord;
1101 std::string errorMessage;
1102 bool result = sendCounterPacketTest.CreateCategoryRecordTest(category, counters, categoryRecord, errorMessage);
1104 BOOST_CHECK(!result);
1105 BOOST_CHECK(!errorMessage.empty());
1106 BOOST_CHECK(categoryRecord.empty());
1109 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest1)
1111 // The counter directory used for testing
1112 CounterDirectory counterDirectory;
1114 // Register a device
1115 const std::string device1Name = "device1";
1116 const Device* device1 = nullptr;
1117 BOOST_CHECK_NO_THROW(device1 = counterDirectory.RegisterDevice(device1Name, 3));
1118 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1119 BOOST_CHECK(device1);
1121 // Register a device
1122 const std::string device2Name = "device2";
1123 const Device* device2 = nullptr;
1124 BOOST_CHECK_NO_THROW(device2 = counterDirectory.RegisterDevice(device2Name));
1125 BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
1126 BOOST_CHECK(device2);
1128 // Buffer with not enough space
1129 MockBufferManager mockBuffer(10);
1130 SendCounterPacket sendCounterPacket(mockBuffer);
1131 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory),
1132 armnn::profiling::BufferExhaustion);
1135 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest2)
1137 // The counter directory used for testing
1138 CounterDirectory counterDirectory;
1140 // Register a device
1141 const std::string device1Name = "device1";
1142 const Device* device1 = nullptr;
1143 BOOST_CHECK_NO_THROW(device1 = counterDirectory.RegisterDevice(device1Name, 3));
1144 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1145 BOOST_CHECK(device1);
1147 // Register a device
1148 const std::string device2Name = "device2";
1149 const Device* device2 = nullptr;
1150 BOOST_CHECK_NO_THROW(device2 = counterDirectory.RegisterDevice(device2Name));
1151 BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
1152 BOOST_CHECK(device2);
1154 // Register a counter set
1155 const std::string counterSet1Name = "counterset1";
1156 const CounterSet* counterSet1 = nullptr;
1157 BOOST_CHECK_NO_THROW(counterSet1 = counterDirectory.RegisterCounterSet(counterSet1Name));
1158 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1159 BOOST_CHECK(counterSet1);
1161 // Register a category associated to "device1" and "counterset1"
1162 const std::string category1Name = "category1";
1163 const Category* category1 = nullptr;
1164 BOOST_CHECK_NO_THROW(category1 = counterDirectory.RegisterCategory(category1Name));
1165 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1166 BOOST_CHECK(category1);
1168 // Register a category not associated to "device2" but no counter set
1169 const std::string category2Name = "category2";
1170 const Category* category2 = nullptr;
1171 BOOST_CHECK_NO_THROW(category2 = counterDirectory.RegisterCategory(category2Name));
1172 BOOST_CHECK(counterDirectory.GetCategoryCount() == 2);
1173 BOOST_CHECK(category2);
1175 uint16_t numberOfCores = 4;
1177 // Register a counter associated to "category1"
1178 const Counter* counter1 = nullptr;
1179 BOOST_CHECK_NO_THROW(counter1 = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1186 "counter1description",
1187 std::string("counter1units"),
1189 BOOST_CHECK(counterDirectory.GetCounterCount() == 4);
1190 BOOST_CHECK(counter1);
1192 // Register a counter associated to "category1"
1193 const Counter* counter2 = nullptr;
1194 BOOST_CHECK_NO_THROW(counter2 = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1201 "counter2description",
1202 std::string("counter2units"),
1203 armnn::EmptyOptional(),
1206 BOOST_CHECK(counterDirectory.GetCounterCount() == 5);
1207 BOOST_CHECK(counter2);
1209 // Register a counter associated to "category2"
1210 const Counter* counter3 = nullptr;
1211 BOOST_CHECK_NO_THROW(counter3 = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1218 "counter3description",
1219 armnn::EmptyOptional(),
1222 counterSet1->m_Uid));
1223 BOOST_CHECK(counterDirectory.GetCounterCount() == 9);
1224 BOOST_CHECK(counter3);
1226 // Buffer with enough space
1227 MockBufferManager mockBuffer(1024);
1228 SendCounterPacket sendCounterPacket(mockBuffer);
1229 BOOST_CHECK_NO_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory));
1231 // Get the readable buffer
1232 auto readBuffer = mockBuffer.GetReadableBuffer();
1234 // Check the packet header
1235 uint32_t packetHeaderWord0 = ReadUint32(readBuffer, 0);
1236 uint32_t packetHeaderWord1 = ReadUint32(readBuffer, 4);
1237 BOOST_TEST(((packetHeaderWord0 >> 26) & 0x3F) == 0); // packet_family
1238 BOOST_TEST(((packetHeaderWord0 >> 16) & 0x3FF) == 2); // packet_id
1239 BOOST_TEST(packetHeaderWord1 == 432); // data_length
1241 // Check the body header
1242 uint32_t bodyHeaderWord0 = ReadUint32(readBuffer, 8);
1243 uint32_t bodyHeaderWord1 = ReadUint32(readBuffer, 12);
1244 uint32_t bodyHeaderWord2 = ReadUint32(readBuffer, 16);
1245 uint32_t bodyHeaderWord3 = ReadUint32(readBuffer, 20);
1246 uint32_t bodyHeaderWord4 = ReadUint32(readBuffer, 24);
1247 uint32_t bodyHeaderWord5 = ReadUint32(readBuffer, 28);
1248 uint16_t deviceRecordCount = static_cast<uint16_t>(bodyHeaderWord0 >> 16);
1249 uint16_t counterSetRecordCount = static_cast<uint16_t>(bodyHeaderWord2 >> 16);
1250 uint16_t categoryRecordCount = static_cast<uint16_t>(bodyHeaderWord4 >> 16);
1251 BOOST_TEST(deviceRecordCount == 2); // device_records_count
1252 BOOST_TEST(bodyHeaderWord1 == 0); // device_records_pointer_table_offset
1253 BOOST_TEST(counterSetRecordCount == 1); // counter_set_count
1254 BOOST_TEST(bodyHeaderWord3 == 8); // counter_set_pointer_table_offset
1255 BOOST_TEST(categoryRecordCount == 2); // categories_count
1256 BOOST_TEST(bodyHeaderWord5 == 12); // categories_pointer_table_offset
1258 // Check the device records pointer table
1259 uint32_t deviceRecordOffset0 = ReadUint32(readBuffer, 32);
1260 uint32_t deviceRecordOffset1 = ReadUint32(readBuffer, 36);
1261 BOOST_TEST(deviceRecordOffset0 == 0); // Device record offset for "device1"
1262 BOOST_TEST(deviceRecordOffset1 == 20); // Device record offset for "device2"
1264 // Check the counter set pointer table
1265 uint32_t counterSetRecordOffset0 = ReadUint32(readBuffer, 40);
1266 BOOST_TEST(counterSetRecordOffset0 == 40); // Counter set record offset for "counterset1"
1268 // Check the category pointer table
1269 uint32_t categoryRecordOffset0 = ReadUint32(readBuffer, 44);
1270 uint32_t categoryRecordOffset1 = ReadUint32(readBuffer, 48);
1271 BOOST_TEST(categoryRecordOffset0 == 64); // Category record offset for "category1"
1272 BOOST_TEST(categoryRecordOffset1 == 168); // Category record offset for "category2"
1274 // Get the device record pool offset
1275 uint32_t uint32_t_size = sizeof(uint32_t);
1276 uint32_t packetBodyPoolOffset = 2u * uint32_t_size + // packet_header
1277 6u * uint32_t_size + // body_header
1278 deviceRecordCount * uint32_t_size + // Size of device_records_pointer_table
1279 counterSetRecordCount * uint32_t_size + // Size of counter_set_pointer_table
1280 categoryRecordCount * uint32_t_size; // Size of categories_pointer_table
1282 // Device record structure/collection used for testing
1287 uint32_t name_offset;
1288 uint32_t name_length;
1291 std::vector<DeviceRecord> deviceRecords;
1292 uint32_t deviceRecordsPointerTableOffset = 2u * uint32_t_size + // packet_header
1293 6u * uint32_t_size + // body_header
1294 bodyHeaderWord1; // device_records_pointer_table_offset
1296 const unsigned char* readData = readBuffer->GetReadableData();
1298 for (uint32_t i = 0; i < deviceRecordCount; i++)
1300 // Get the device record offset
1301 uint32_t deviceRecordOffset = ReadUint32(readBuffer, deviceRecordsPointerTableOffset + i * uint32_t_size);
1303 // Collect the data for the device record
1304 uint32_t deviceRecordWord0 = ReadUint32(readBuffer,
1305 packetBodyPoolOffset + deviceRecordOffset + 0 * uint32_t_size);
1306 uint32_t deviceRecordWord1 = ReadUint32(readBuffer,
1307 packetBodyPoolOffset + deviceRecordOffset + 1 * uint32_t_size);
1308 DeviceRecord deviceRecord;
1309 deviceRecord.uid = static_cast<uint16_t>(deviceRecordWord0 >> 16); // uid
1310 deviceRecord.cores = static_cast<uint16_t>(deviceRecordWord0); // cores
1311 deviceRecord.name_offset = deviceRecordWord1; // name_offset
1313 uint32_t deviceRecordPoolOffset = packetBodyPoolOffset + // Packet body offset
1314 deviceRecordOffset + // Device record offset
1315 2 * uint32_t_size + // Device record header
1316 deviceRecord.name_offset; // Device name offset
1317 uint32_t deviceRecordNameLength = ReadUint32(readBuffer, deviceRecordPoolOffset);
1318 deviceRecord.name_length = deviceRecordNameLength; // name_length
1319 unsigned char deviceRecordNameNullTerminator = // name null-terminator
1320 ReadUint8(readBuffer, deviceRecordPoolOffset + uint32_t_size + deviceRecordNameLength - 1);
1321 BOOST_CHECK(deviceRecordNameNullTerminator == '\0');
1322 std::vector<unsigned char> deviceRecordNameBuffer(deviceRecord.name_length - 1);
1323 std::memcpy(deviceRecordNameBuffer.data(),
1324 readData + deviceRecordPoolOffset + uint32_t_size, deviceRecordNameBuffer.size());
1325 deviceRecord.name.assign(deviceRecordNameBuffer.begin(), deviceRecordNameBuffer.end()); // name
1327 deviceRecords.push_back(deviceRecord);
1330 // Check that the device records are correct
1331 BOOST_CHECK(deviceRecords.size() == 2);
1332 for (const DeviceRecord& deviceRecord : deviceRecords)
1334 const Device* device = counterDirectory.GetDevice(deviceRecord.uid);
1335 BOOST_CHECK(device);
1336 BOOST_CHECK(device->m_Uid == deviceRecord.uid);
1337 BOOST_CHECK(device->m_Cores == deviceRecord.cores);
1338 BOOST_CHECK(device->m_Name == deviceRecord.name);
1341 // Counter set record structure/collection used for testing
1342 struct CounterSetRecord
1346 uint32_t name_offset;
1347 uint32_t name_length;
1350 std::vector<CounterSetRecord> counterSetRecords;
1351 uint32_t counterSetRecordsPointerTableOffset = 2u * uint32_t_size + // packet_header
1352 6u * uint32_t_size + // body_header
1353 bodyHeaderWord3; // counter_set_pointer_table_offset
1354 for (uint32_t i = 0; i < counterSetRecordCount; i++)
1356 // Get the counter set record offset
1357 uint32_t counterSetRecordOffset = ReadUint32(readBuffer,
1358 counterSetRecordsPointerTableOffset + i * uint32_t_size);
1360 // Collect the data for the counter set record
1361 uint32_t counterSetRecordWord0 = ReadUint32(readBuffer,
1362 packetBodyPoolOffset + counterSetRecordOffset + 0 * uint32_t_size);
1363 uint32_t counterSetRecordWord1 = ReadUint32(readBuffer,
1364 packetBodyPoolOffset + counterSetRecordOffset + 1 * uint32_t_size);
1365 CounterSetRecord counterSetRecord;
1366 counterSetRecord.uid = static_cast<uint16_t>(counterSetRecordWord0 >> 16); // uid
1367 counterSetRecord.count = static_cast<uint16_t>(counterSetRecordWord0); // count
1368 counterSetRecord.name_offset = counterSetRecordWord1; // name_offset
1370 uint32_t counterSetRecordPoolOffset = packetBodyPoolOffset + // Packet body offset
1371 counterSetRecordOffset + // Counter set record offset
1372 2 * uint32_t_size + // Counter set record header
1373 counterSetRecord.name_offset; // Counter set name offset
1374 uint32_t counterSetRecordNameLength = ReadUint32(readBuffer, counterSetRecordPoolOffset);
1375 counterSetRecord.name_length = counterSetRecordNameLength; // name_length
1376 unsigned char counterSetRecordNameNullTerminator = // name null-terminator
1377 ReadUint8(readBuffer, counterSetRecordPoolOffset + uint32_t_size + counterSetRecordNameLength - 1);
1378 BOOST_CHECK(counterSetRecordNameNullTerminator == '\0');
1379 std::vector<unsigned char> counterSetRecordNameBuffer(counterSetRecord.name_length - 1);
1380 std::memcpy(counterSetRecordNameBuffer.data(),
1381 readData + counterSetRecordPoolOffset + uint32_t_size, counterSetRecordNameBuffer.size());
1382 counterSetRecord.name.assign(counterSetRecordNameBuffer.begin(), counterSetRecordNameBuffer.end()); // name
1384 counterSetRecords.push_back(counterSetRecord);
1387 // Check that the counter set records are correct
1388 BOOST_CHECK(counterSetRecords.size() == 1);
1389 for (const CounterSetRecord& counterSetRecord : counterSetRecords)
1391 const CounterSet* counterSet = counterDirectory.GetCounterSet(counterSetRecord.uid);
1392 BOOST_CHECK(counterSet);
1393 BOOST_CHECK(counterSet->m_Uid == counterSetRecord.uid);
1394 BOOST_CHECK(counterSet->m_Count == counterSetRecord.count);
1395 BOOST_CHECK(counterSet->m_Name == counterSetRecord.name);
1398 // Event record structure/collection used for testing
1401 uint16_t counter_uid;
1402 uint16_t max_counter_uid;
1404 uint16_t counter_set;
1405 uint16_t counter_class;
1406 uint16_t interpolation;
1408 uint32_t name_offset;
1409 uint32_t name_length;
1411 uint32_t description_offset;
1412 uint32_t description_length;
1413 std::string description;
1414 uint32_t units_offset;
1415 uint32_t units_length;
1418 // Category record structure/collection used for testing
1419 struct CategoryRecord
1421 uint16_t event_count;
1422 uint32_t event_pointer_table_offset;
1423 uint32_t name_offset;
1424 uint32_t name_length;
1426 std::vector<uint32_t> event_pointer_table;
1427 std::vector<EventRecord> event_records;
1429 std::vector<CategoryRecord> categoryRecords;
1430 uint32_t categoryRecordsPointerTableOffset = 2u * uint32_t_size + // packet_header
1431 6u * uint32_t_size + // body_header
1432 bodyHeaderWord5; // categories_pointer_table_offset
1433 for (uint32_t i = 0; i < categoryRecordCount; i++)
1435 // Get the category record offset
1436 uint32_t categoryRecordOffset = ReadUint32(readBuffer, categoryRecordsPointerTableOffset + i * uint32_t_size);
1438 // Collect the data for the category record
1439 uint32_t categoryRecordWord1 = ReadUint32(readBuffer,
1440 packetBodyPoolOffset + categoryRecordOffset + 0 * uint32_t_size);
1441 uint32_t categoryRecordWord2 = ReadUint32(readBuffer,
1442 packetBodyPoolOffset + categoryRecordOffset + 1 * uint32_t_size);
1443 uint32_t categoryRecordWord3 = ReadUint32(readBuffer,
1444 packetBodyPoolOffset + categoryRecordOffset + 2 * uint32_t_size);
1445 CategoryRecord categoryRecord;
1446 categoryRecord.event_count = static_cast<uint16_t>(categoryRecordWord1 >> 16); // event_count
1447 categoryRecord.event_pointer_table_offset = categoryRecordWord2; // event_pointer_table_offset
1448 categoryRecord.name_offset = categoryRecordWord3; // name_offset
1450 uint32_t categoryRecordPoolOffset = packetBodyPoolOffset + // Packet body offset
1451 categoryRecordOffset + // Category record offset
1452 3 * uint32_t_size; // Category record header
1454 uint32_t categoryRecordNameLength = ReadUint32(readBuffer,
1455 categoryRecordPoolOffset + categoryRecord.name_offset);
1456 categoryRecord.name_length = categoryRecordNameLength; // name_length
1457 unsigned char categoryRecordNameNullTerminator =
1458 ReadUint8(readBuffer,
1459 categoryRecordPoolOffset +
1460 categoryRecord.name_offset +
1462 categoryRecordNameLength - 1); // name null-terminator
1463 BOOST_CHECK(categoryRecordNameNullTerminator == '\0');
1464 std::vector<unsigned char> categoryRecordNameBuffer(categoryRecord.name_length - 1);
1465 std::memcpy(categoryRecordNameBuffer.data(),
1467 categoryRecordPoolOffset +
1468 categoryRecord.name_offset +
1470 categoryRecordNameBuffer.size());
1471 categoryRecord.name.assign(categoryRecordNameBuffer.begin(), categoryRecordNameBuffer.end()); // name
1473 categoryRecord.event_pointer_table.resize(categoryRecord.event_count);
1474 for (uint32_t eventIndex = 0; eventIndex < categoryRecord.event_count; eventIndex++)
1476 uint32_t eventRecordOffset = ReadUint32(readBuffer,
1477 categoryRecordPoolOffset +
1478 categoryRecord.event_pointer_table_offset +
1479 eventIndex * uint32_t_size);
1480 categoryRecord.event_pointer_table[eventIndex] = eventRecordOffset;
1482 // Collect the data for the event record
1483 uint32_t eventRecordWord0 = ReadUint32(readBuffer,
1484 categoryRecordPoolOffset + eventRecordOffset + 0 * uint32_t_size);
1485 uint32_t eventRecordWord1 = ReadUint32(readBuffer,
1486 categoryRecordPoolOffset + eventRecordOffset + 1 * uint32_t_size);
1487 uint32_t eventRecordWord2 = ReadUint32(readBuffer,
1488 categoryRecordPoolOffset + eventRecordOffset + 2 * uint32_t_size);
1489 uint64_t eventRecordWord34 = ReadUint64(readBuffer,
1490 categoryRecordPoolOffset + eventRecordOffset + 3 * uint32_t_size);
1491 uint32_t eventRecordWord5 = ReadUint32(readBuffer,
1492 categoryRecordPoolOffset + eventRecordOffset + 5 * uint32_t_size);
1493 uint32_t eventRecordWord6 = ReadUint32(readBuffer,
1494 categoryRecordPoolOffset + eventRecordOffset + 6 * uint32_t_size);
1495 uint32_t eventRecordWord7 = ReadUint32(readBuffer,
1496 categoryRecordPoolOffset + eventRecordOffset + 7 * uint32_t_size);
1497 EventRecord eventRecord;
1498 eventRecord.counter_uid = static_cast<uint16_t>(eventRecordWord0); // counter_uid
1499 eventRecord.max_counter_uid = static_cast<uint16_t>(eventRecordWord0 >> 16); // max_counter_uid
1500 eventRecord.device = static_cast<uint16_t>(eventRecordWord1 >> 16); // device
1501 eventRecord.counter_set = static_cast<uint16_t>(eventRecordWord1); // counter_set
1502 eventRecord.counter_class = static_cast<uint16_t>(eventRecordWord2 >> 16); // class
1503 eventRecord.interpolation = static_cast<uint16_t>(eventRecordWord2); // interpolation
1504 std::memcpy(&eventRecord.multiplier, &eventRecordWord34, sizeof(eventRecord.multiplier)); // multiplier
1505 eventRecord.name_offset = static_cast<uint32_t>(eventRecordWord5); // name_offset
1506 eventRecord.description_offset = static_cast<uint32_t>(eventRecordWord6); // description_offset
1507 eventRecord.units_offset = static_cast<uint32_t>(eventRecordWord7); // units_offset
1509 uint32_t eventRecordPoolOffset = categoryRecordPoolOffset + // Category record pool offset
1510 eventRecordOffset + // Event record offset
1511 8 * uint32_t_size; // Event record header
1513 uint32_t eventRecordNameLength = ReadUint32(readBuffer,
1514 eventRecordPoolOffset + eventRecord.name_offset);
1515 eventRecord.name_length = eventRecordNameLength; // name_length
1516 unsigned char eventRecordNameNullTerminator =
1517 ReadUint8(readBuffer,
1518 eventRecordPoolOffset +
1519 eventRecord.name_offset +
1521 eventRecordNameLength - 1); // name null-terminator
1522 BOOST_CHECK(eventRecordNameNullTerminator == '\0');
1523 std::vector<unsigned char> eventRecordNameBuffer(eventRecord.name_length - 1);
1524 std::memcpy(eventRecordNameBuffer.data(),
1526 eventRecordPoolOffset +
1527 eventRecord.name_offset +
1529 eventRecordNameBuffer.size());
1530 eventRecord.name.assign(eventRecordNameBuffer.begin(), eventRecordNameBuffer.end()); // name
1532 uint32_t eventRecordDescriptionLength = ReadUint32(readBuffer,
1533 eventRecordPoolOffset + eventRecord.description_offset);
1534 eventRecord.description_length = eventRecordDescriptionLength; // description_length
1535 unsigned char eventRecordDescriptionNullTerminator =
1536 ReadUint8(readBuffer,
1537 eventRecordPoolOffset +
1538 eventRecord.description_offset +
1540 eventRecordDescriptionLength - 1); // description null-terminator
1541 BOOST_CHECK(eventRecordDescriptionNullTerminator == '\0');
1542 std::vector<unsigned char> eventRecordDescriptionBuffer(eventRecord.description_length - 1);
1543 std::memcpy(eventRecordDescriptionBuffer.data(),
1545 eventRecordPoolOffset +
1546 eventRecord.description_offset +
1548 eventRecordDescriptionBuffer.size());
1549 eventRecord.description.assign(eventRecordDescriptionBuffer.begin(),
1550 eventRecordDescriptionBuffer.end()); // description
1552 if (eventRecord.units_offset > 0)
1554 uint32_t eventRecordUnitsLength = ReadUint32(readBuffer,
1555 eventRecordPoolOffset + eventRecord.units_offset);
1556 eventRecord.units_length = eventRecordUnitsLength; // units_length
1557 unsigned char eventRecordUnitsNullTerminator =
1558 ReadUint8(readBuffer,
1559 eventRecordPoolOffset +
1560 eventRecord.units_offset +
1562 eventRecordUnitsLength - 1); // units null-terminator
1563 BOOST_CHECK(eventRecordUnitsNullTerminator == '\0');
1564 std::vector<unsigned char> eventRecordUnitsBuffer(eventRecord.units_length - 1);
1565 std::memcpy(eventRecordUnitsBuffer.data(),
1567 eventRecordPoolOffset +
1568 eventRecord.units_offset +
1570 eventRecordUnitsBuffer.size());
1571 eventRecord.units.assign(eventRecordUnitsBuffer.begin(), eventRecordUnitsBuffer.end()); // units
1574 categoryRecord.event_records.push_back(eventRecord);
1577 categoryRecords.push_back(categoryRecord);
1580 // Check that the category records are correct
1581 BOOST_CHECK(categoryRecords.size() == 2);
1582 for (const CategoryRecord& categoryRecord : categoryRecords)
1584 const Category* category = counterDirectory.GetCategory(categoryRecord.name);
1585 BOOST_CHECK(category);
1586 BOOST_CHECK(category->m_Name == categoryRecord.name);
1587 BOOST_CHECK(category->m_Counters.size() == categoryRecord.event_count + static_cast<size_t>(numberOfCores) -1);
1588 BOOST_CHECK(category->m_Counters.size() == categoryRecord.event_count + static_cast<size_t>(numberOfCores) -1);
1590 // Check that the event records are correct
1591 for (const EventRecord& eventRecord : categoryRecord.event_records)
1593 const Counter* counter = counterDirectory.GetCounter(eventRecord.counter_uid);
1594 BOOST_CHECK(counter);
1595 BOOST_CHECK(counter->m_MaxCounterUid == eventRecord.max_counter_uid);
1596 BOOST_CHECK(counter->m_DeviceUid == eventRecord.device);
1597 BOOST_CHECK(counter->m_CounterSetUid == eventRecord.counter_set);
1598 BOOST_CHECK(counter->m_Class == eventRecord.counter_class);
1599 BOOST_CHECK(counter->m_Interpolation == eventRecord.interpolation);
1600 BOOST_CHECK(counter->m_Multiplier == eventRecord.multiplier);
1601 BOOST_CHECK(counter->m_Name == eventRecord.name);
1602 BOOST_CHECK(counter->m_Description == eventRecord.description);
1603 BOOST_CHECK(counter->m_Units == eventRecord.units);
1608 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest3)
1610 // Using a mock counter directory that allows to register invalid objects
1611 MockCounterDirectory counterDirectory;
1613 // Register an invalid device
1614 const std::string deviceName = "inv@lid dev!c€";
1615 const Device* device = nullptr;
1616 BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName, 3));
1617 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1618 BOOST_CHECK(device);
1620 // Buffer with enough space
1621 MockBufferManager mockBuffer(1024);
1622 SendCounterPacket sendCounterPacket(mockBuffer);
1623 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1626 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest4)
1628 // Using a mock counter directory that allows to register invalid objects
1629 MockCounterDirectory counterDirectory;
1631 // Register an invalid counter set
1632 const std::string counterSetName = "inv@lid count€rs€t";
1633 const CounterSet* counterSet = nullptr;
1634 BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1635 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1636 BOOST_CHECK(counterSet);
1638 // Buffer with enough space
1639 MockBufferManager mockBuffer(1024);
1640 SendCounterPacket sendCounterPacket(mockBuffer);
1641 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1644 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest5)
1646 // Using a mock counter directory that allows to register invalid objects
1647 MockCounterDirectory counterDirectory;
1649 // Register an invalid category
1650 const std::string categoryName = "c@t€gory";
1651 const Category* category = nullptr;
1652 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName));
1653 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1654 BOOST_CHECK(category);
1656 // Buffer with enough space
1657 MockBufferManager mockBuffer(1024);
1658 SendCounterPacket sendCounterPacket(mockBuffer);
1659 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1662 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest6)
1664 // Using a mock counter directory that allows to register invalid objects
1665 MockCounterDirectory counterDirectory;
1667 // Register an invalid device
1668 const std::string deviceName = "inv@lid dev!c€";
1669 const Device* device = nullptr;
1670 BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName, 3));
1671 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1672 BOOST_CHECK(device);
1674 // Register an invalid counter set
1675 const std::string counterSetName = "inv@lid count€rs€t";
1676 const CounterSet* counterSet = nullptr;
1677 BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1678 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1679 BOOST_CHECK(counterSet);
1681 // Register an invalid category associated to an invalid device and an invalid counter set
1682 const std::string categoryName = "c@t€gory";
1683 const Category* category = nullptr;
1684 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName));
1685 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1686 BOOST_CHECK(category);
1688 // Buffer with enough space
1689 MockBufferManager mockBuffer(1024);
1690 SendCounterPacket sendCounterPacket(mockBuffer);
1691 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1694 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest7)
1696 // Using a mock counter directory that allows to register invalid objects
1697 MockCounterDirectory counterDirectory;
1699 // Register an valid device
1700 const std::string deviceName = "valid device";
1701 const Device* device = nullptr;
1702 BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName, 3));
1703 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1704 BOOST_CHECK(device);
1706 // Register an valid counter set
1707 const std::string counterSetName = "valid counterset";
1708 const CounterSet* counterSet = nullptr;
1709 BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1710 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1711 BOOST_CHECK(counterSet);
1713 // Register an valid category associated to a valid device and a valid counter set
1714 const std::string categoryName = "category";
1715 const Category* category = nullptr;
1716 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName));
1717 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1718 BOOST_CHECK(category);
1720 // Register an invalid counter associated to a valid category
1721 const Counter* counter = nullptr;
1722 BOOST_CHECK_NO_THROW(counter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1729 "counter description",
1730 std::string("invalid counter units"),
1733 counterSet->m_Uid));
1734 BOOST_CHECK(counterDirectory.GetCounterCount() == 5);
1735 BOOST_CHECK(counter);
1737 // Buffer with enough space
1738 MockBufferManager mockBuffer(1024);
1739 SendCounterPacket sendCounterPacket(mockBuffer);
1740 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1743 BOOST_AUTO_TEST_CASE(SendThreadTest0)
1745 ProfilingStateMachine profilingStateMachine;
1746 SetActiveProfilingState(profilingStateMachine);
1748 MockProfilingConnection mockProfilingConnection;
1749 MockStreamCounterBuffer mockStreamCounterBuffer(0);
1750 SendCounterPacket sendCounterPacket(mockStreamCounterBuffer);
1751 SendThread sendThread(profilingStateMachine, mockStreamCounterBuffer, sendCounterPacket);
1753 // Try to start the send thread many times, it must only start once
1755 sendThread.Start(mockProfilingConnection);
1756 BOOST_CHECK(sendThread.IsRunning());
1757 sendThread.Start(mockProfilingConnection);
1758 sendThread.Start(mockProfilingConnection);
1759 sendThread.Start(mockProfilingConnection);
1760 sendThread.Start(mockProfilingConnection);
1761 BOOST_CHECK(sendThread.IsRunning());
1764 BOOST_CHECK(!sendThread.IsRunning());
1767 BOOST_AUTO_TEST_CASE(SendThreadTest1)
1769 ProfilingStateMachine profilingStateMachine;
1770 SetActiveProfilingState(profilingStateMachine);
1772 unsigned int totalWrittenSize = 0;
1774 MockProfilingConnection mockProfilingConnection;
1775 MockStreamCounterBuffer mockStreamCounterBuffer(1024);
1776 SendCounterPacket sendCounterPacket(mockStreamCounterBuffer);
1777 SendThread sendThread(profilingStateMachine, mockStreamCounterBuffer, sendCounterPacket);
1778 sendThread.Start(mockProfilingConnection);
1780 // Interleaving writes and reads to/from the buffer with pauses to test that the send thread actually waits for
1781 // something to become available for reading
1783 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
1785 CounterDirectory counterDirectory;
1786 sendCounterPacket.SendStreamMetaDataPacket();
1788 // Get the size of the Stream Metadata Packet
1789 std::string processName = GetProcessName().substr(0, 60);
1790 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
1791 unsigned int streamMetadataPacketsize = 118 + processNameSize;
1792 totalWrittenSize += streamMetadataPacketsize;
1794 sendThread.SetReadyToRead();
1796 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
1798 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
1800 // Get the size of the Counter Directory Packet
1801 unsigned int counterDirectoryPacketSize = 32;
1802 totalWrittenSize += counterDirectoryPacketSize;
1804 sendThread.SetReadyToRead();
1806 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
1808 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
1814 // Get the size of the Periodic Counter Capture Packet
1815 unsigned int periodicCounterCapturePacketSize = 28;
1816 totalWrittenSize += periodicCounterCapturePacketSize;
1818 sendThread.SetReadyToRead();
1820 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
1822 sendCounterPacket.SendPeriodicCounterCapturePacket(44u,
1827 // Get the size of the Periodic Counter Capture Packet
1828 periodicCounterCapturePacketSize = 22;
1829 totalWrittenSize += periodicCounterCapturePacketSize;
1831 sendCounterPacket.SendPeriodicCounterCapturePacket(1234u,
1840 // Get the size of the Periodic Counter Capture Packet
1841 periodicCounterCapturePacketSize = 46;
1842 totalWrittenSize += periodicCounterCapturePacketSize;
1844 sendCounterPacket.SendPeriodicCounterCapturePacket(997u,
1852 // Get the size of the Periodic Counter Capture Packet
1853 periodicCounterCapturePacketSize = 40;
1854 totalWrittenSize += periodicCounterCapturePacketSize;
1856 sendThread.SetReadyToRead();
1858 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
1860 sendCounterPacket.SendPeriodicCounterSelectionPacket(1000u, { 1345u, 254u, 4536u, 408u, 54u, 6323u, 428u, 1u, 6u });
1862 // Get the size of the Periodic Counter Capture Packet
1863 periodicCounterCapturePacketSize = 30;
1864 totalWrittenSize += periodicCounterCapturePacketSize;
1866 sendThread.SetReadyToRead();
1868 // To test an exact value of the "read size" in the mock buffer, wait to allow the send thread to
1869 // read all what's remaining in the buffer
1870 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
1874 BOOST_CHECK(mockStreamCounterBuffer.GetCommittedSize() == totalWrittenSize);
1875 BOOST_CHECK(mockStreamCounterBuffer.GetReadableSize() == totalWrittenSize);
1876 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() == totalWrittenSize);
1879 BOOST_AUTO_TEST_CASE(SendThreadTest2)
1881 ProfilingStateMachine profilingStateMachine;
1882 SetActiveProfilingState(profilingStateMachine);
1884 unsigned int totalWrittenSize = 0;
1886 MockProfilingConnection mockProfilingConnection;
1887 MockStreamCounterBuffer mockStreamCounterBuffer(1024);
1888 SendCounterPacket sendCounterPacket(mockStreamCounterBuffer);
1889 SendThread sendThread(profilingStateMachine, mockStreamCounterBuffer, sendCounterPacket);
1890 sendThread.Start(mockProfilingConnection);
1892 // Adding many spurious "ready to read" signals throughout the test to check that the send thread is
1893 // capable of handling unnecessary read requests
1895 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
1897 sendThread.SetReadyToRead();
1899 CounterDirectory counterDirectory;
1900 sendCounterPacket.SendStreamMetaDataPacket();
1902 // Get the size of the Stream Metadata Packet
1903 std::string processName = GetProcessName().substr(0, 60);
1904 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
1905 unsigned int streamMetadataPacketsize = 118 + processNameSize;
1906 totalWrittenSize += streamMetadataPacketsize;
1908 sendThread.SetReadyToRead();
1910 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
1912 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
1914 // Get the size of the Counter Directory Packet
1915 unsigned int counterDirectoryPacketSize = 32;
1916 totalWrittenSize += counterDirectoryPacketSize;
1918 sendThread.SetReadyToRead();
1919 sendThread.SetReadyToRead();
1921 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
1923 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
1929 // Get the size of the Periodic Counter Capture Packet
1930 unsigned int periodicCounterCapturePacketSize = 28;
1931 totalWrittenSize += periodicCounterCapturePacketSize;
1933 sendThread.SetReadyToRead();
1935 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
1937 sendThread.SetReadyToRead();
1938 sendThread.SetReadyToRead();
1939 sendThread.SetReadyToRead();
1941 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
1943 sendThread.SetReadyToRead();
1944 sendCounterPacket.SendPeriodicCounterCapturePacket(44u,
1949 // Get the size of the Periodic Counter Capture Packet
1950 periodicCounterCapturePacketSize = 22;
1951 totalWrittenSize += periodicCounterCapturePacketSize;
1953 sendCounterPacket.SendPeriodicCounterCapturePacket(1234u,
1962 // Get the size of the Periodic Counter Capture Packet
1963 periodicCounterCapturePacketSize = 46;
1964 totalWrittenSize += periodicCounterCapturePacketSize;
1966 sendThread.SetReadyToRead();
1967 sendCounterPacket.SendPeriodicCounterCapturePacket(997u,
1975 // Get the size of the Periodic Counter Capture Packet
1976 periodicCounterCapturePacketSize = 40;
1977 totalWrittenSize += periodicCounterCapturePacketSize;
1979 sendThread.SetReadyToRead();
1980 sendThread.SetReadyToRead();
1982 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
1984 sendCounterPacket.SendPeriodicCounterSelectionPacket(1000u, { 1345u, 254u, 4536u, 408u, 54u, 6323u, 428u, 1u, 6u });
1986 // Get the size of the Periodic Counter Capture Packet
1987 periodicCounterCapturePacketSize = 30;
1988 totalWrittenSize += periodicCounterCapturePacketSize;
1990 sendThread.SetReadyToRead();
1992 // To test an exact value of the "read size" in the mock buffer, wait to allow the send thread to
1993 // read all what's remaining in the buffer
1996 BOOST_CHECK(mockStreamCounterBuffer.GetCommittedSize() == totalWrittenSize);
1997 BOOST_CHECK(mockStreamCounterBuffer.GetReadableSize() == totalWrittenSize);
1998 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() == totalWrittenSize);
2001 BOOST_AUTO_TEST_CASE(SendThreadTest3)
2003 ProfilingStateMachine profilingStateMachine;
2004 SetActiveProfilingState(profilingStateMachine);
2006 unsigned int totalWrittenSize = 0;
2008 MockProfilingConnection mockProfilingConnection;
2009 MockStreamCounterBuffer mockStreamCounterBuffer(1024);
2010 SendCounterPacket sendCounterPacket(mockStreamCounterBuffer);
2011 SendThread sendThread(profilingStateMachine, mockStreamCounterBuffer, sendCounterPacket);
2012 sendThread.Start(mockProfilingConnection);
2014 // Not using pauses or "grace periods" to stress test the send thread
2016 sendThread.SetReadyToRead();
2018 CounterDirectory counterDirectory;
2019 sendCounterPacket.SendStreamMetaDataPacket();
2021 // Get the size of the Stream Metadata Packet
2022 std::string processName = GetProcessName().substr(0, 60);
2023 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
2024 unsigned int streamMetadataPacketsize = 118 + processNameSize;
2025 totalWrittenSize += streamMetadataPacketsize;
2027 sendThread.SetReadyToRead();
2028 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
2030 // Get the size of the Counter Directory Packet
2031 unsigned int counterDirectoryPacketSize =32;
2032 totalWrittenSize += counterDirectoryPacketSize;
2034 sendThread.SetReadyToRead();
2035 sendThread.SetReadyToRead();
2036 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
2042 // Get the size of the Periodic Counter Capture Packet
2043 unsigned int periodicCounterCapturePacketSize = 28;
2044 totalWrittenSize += periodicCounterCapturePacketSize;
2046 sendThread.SetReadyToRead();
2047 sendThread.SetReadyToRead();
2048 sendThread.SetReadyToRead();
2049 sendThread.SetReadyToRead();
2050 sendThread.SetReadyToRead();
2051 sendCounterPacket.SendPeriodicCounterCapturePacket(44u,
2056 // Get the size of the Periodic Counter Capture Packet
2057 periodicCounterCapturePacketSize = 22;
2058 totalWrittenSize += periodicCounterCapturePacketSize;
2060 sendCounterPacket.SendPeriodicCounterCapturePacket(1234u,
2069 // Get the size of the Periodic Counter Capture Packet
2070 periodicCounterCapturePacketSize = 46;
2071 totalWrittenSize += periodicCounterCapturePacketSize;
2073 sendThread.SetReadyToRead();
2074 sendThread.SetReadyToRead();
2075 sendCounterPacket.SendPeriodicCounterCapturePacket(997u,
2083 // Get the size of the Periodic Counter Capture Packet
2084 periodicCounterCapturePacketSize = 40;
2085 totalWrittenSize += periodicCounterCapturePacketSize;
2087 sendThread.SetReadyToRead();
2088 sendThread.SetReadyToRead();
2089 sendCounterPacket.SendPeriodicCounterSelectionPacket(1000u, { 1345u, 254u, 4536u, 408u, 54u, 6323u, 428u, 1u, 6u });
2091 // Get the size of the Periodic Counter Capture Packet
2092 periodicCounterCapturePacketSize = 30;
2093 totalWrittenSize += periodicCounterCapturePacketSize;
2095 sendThread.SetReadyToRead();
2097 // Abruptly terminating the send thread, the amount of data sent may be less that the amount written (the send
2098 // thread is not guaranteed to flush the buffer)
2101 BOOST_CHECK(mockStreamCounterBuffer.GetCommittedSize() == totalWrittenSize);
2102 BOOST_CHECK(mockStreamCounterBuffer.GetReadableSize() <= totalWrittenSize);
2103 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() <= totalWrittenSize);
2104 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() <= mockStreamCounterBuffer.GetReadableSize());
2105 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() <= mockStreamCounterBuffer.GetCommittedSize());
2108 BOOST_AUTO_TEST_CASE(SendCounterPacketTestWithSendThread)
2110 ProfilingStateMachine profilingStateMachine;
2111 SetWaitingForAckProfilingState(profilingStateMachine);
2113 MockProfilingConnection mockProfilingConnection;
2114 BufferManager bufferManager(1, 1024);
2115 SendCounterPacket sendCounterPacket(bufferManager);
2116 SendThread sendThread(profilingStateMachine, bufferManager, sendCounterPacket, -1);
2117 sendThread.Start(mockProfilingConnection);
2119 std::string processName = GetProcessName().substr(0, 60);
2120 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
2121 unsigned int streamMetadataPacketsize = 118 + processNameSize;
2125 // check for packet in ProfilingConnection
2126 BOOST_CHECK(mockProfilingConnection.CheckForPacket({PacketType::StreamMetaData, streamMetadataPacketsize}) == 1);
2128 SetActiveProfilingState(profilingStateMachine);
2129 sendThread.Start(mockProfilingConnection);
2131 // SendCounterDirectoryPacket
2132 CounterDirectory counterDirectory;
2133 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
2136 unsigned int counterDirectoryPacketSize = 32;
2137 // check for packet in ProfilingConnection
2138 BOOST_CHECK(mockProfilingConnection.CheckForPacket(
2139 {PacketType::CounterDirectory, counterDirectoryPacketSize}) == 1);
2141 sendThread.Start(mockProfilingConnection);
2143 // SendPeriodicCounterCapturePacket
2144 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
2152 unsigned int periodicCounterCapturePacketSize = 28;
2153 BOOST_CHECK(mockProfilingConnection.CheckForPacket(
2154 {PacketType::PeriodicCounterCapture, periodicCounterCapturePacketSize}) == 1);
2157 BOOST_AUTO_TEST_CASE(SendThreadBufferTest)
2159 ProfilingStateMachine profilingStateMachine;
2160 SetActiveProfilingState(profilingStateMachine);
2162 MockProfilingConnection mockProfilingConnection;
2163 BufferManager bufferManager(3, 1024);
2164 SendCounterPacket sendCounterPacket(bufferManager);
2165 SendThread sendThread(profilingStateMachine, bufferManager, sendCounterPacket, -1);
2166 sendThread.Start(mockProfilingConnection);
2168 // SendStreamMetaDataPacket
2169 sendCounterPacket.SendStreamMetaDataPacket();
2171 // Read data from the buffer
2172 // Buffer should become readable after commit by SendStreamMetaDataPacket
2173 auto packetBuffer = bufferManager.GetReadableBuffer();
2174 BOOST_TEST(packetBuffer.get());
2176 std::string processName = GetProcessName().substr(0, 60);
2177 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
2178 unsigned int streamMetadataPacketsize = 118 + processNameSize;
2179 BOOST_TEST(packetBuffer->GetSize() == streamMetadataPacketsize);
2181 // Recommit to be read by sendCounterPacket
2182 bufferManager.Commit(packetBuffer, streamMetadataPacketsize);
2184 // SendCounterDirectoryPacket
2185 CounterDirectory counterDirectory;
2186 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
2188 // SendPeriodicCounterCapturePacket
2189 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
2197 // The buffer is read by the send thread so it should not be in the readable buffer.
2198 auto readBuffer = bufferManager.GetReadableBuffer();
2199 BOOST_TEST(!readBuffer);
2201 // Successfully reserved the buffer with requested size
2202 unsigned int reservedSize = 0;
2203 auto reservedBuffer = bufferManager.Reserve(512, reservedSize);
2204 BOOST_TEST(reservedSize == 512);
2205 BOOST_TEST(reservedBuffer.get());
2207 const auto writtenDataSize = mockProfilingConnection.GetWrittenDataSize();
2208 const auto metaDataPacketCount =
2209 mockProfilingConnection.CheckForPacket({PacketType::StreamMetaData, streamMetadataPacketsize});
2211 BOOST_TEST(metaDataPacketCount >= 1);
2212 BOOST_TEST(mockProfilingConnection.CheckForPacket({PacketType::CounterDirectory, 32}) == 1);
2213 BOOST_TEST(mockProfilingConnection.CheckForPacket({PacketType::PeriodicCounterCapture, 28}) == 1);
2214 // Check that we only received the packets we expected
2215 BOOST_TEST(metaDataPacketCount + 2 == writtenDataSize);
2218 BOOST_AUTO_TEST_CASE(SendThreadSendStreamMetadataPacket1)
2220 ProfilingStateMachine profilingStateMachine;
2222 MockProfilingConnection mockProfilingConnection;
2223 BufferManager bufferManager(3, 1024);
2224 SendCounterPacket sendCounterPacket(bufferManager);
2225 SendThread sendThread(profilingStateMachine, bufferManager, sendCounterPacket);
2226 sendThread.Start(mockProfilingConnection);
2228 // The profiling state is set to "Uninitialized", so the send thread should throw an exception
2229 BOOST_CHECK_THROW(sendThread.Stop(), armnn::RuntimeException);
2232 BOOST_AUTO_TEST_CASE(SendThreadSendStreamMetadataPacket2)
2234 ProfilingStateMachine profilingStateMachine;
2235 SetNotConnectedProfilingState(profilingStateMachine);
2237 MockProfilingConnection mockProfilingConnection;
2238 BufferManager bufferManager(3, 1024);
2239 SendCounterPacket sendCounterPacket(bufferManager);
2240 SendThread sendThread(profilingStateMachine, bufferManager, sendCounterPacket);
2241 sendThread.Start(mockProfilingConnection);
2243 // The profiling state is set to "NotConnected", so the send thread should throw an exception
2244 BOOST_CHECK_THROW(sendThread.Stop(), armnn::RuntimeException);
2247 BOOST_AUTO_TEST_CASE(SendThreadSendStreamMetadataPacket3)
2249 ProfilingStateMachine profilingStateMachine;
2250 SetWaitingForAckProfilingState(profilingStateMachine);
2252 // Calculate the size of a Stream Metadata packet
2253 std::string processName = GetProcessName().substr(0, 60);
2254 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
2255 unsigned int streamMetadataPacketsize = 118 + processNameSize;
2257 MockProfilingConnection mockProfilingConnection;
2258 BufferManager bufferManager(3, 1024);
2259 SendCounterPacket sendCounterPacket(bufferManager);
2260 SendThread sendThread(profilingStateMachine, bufferManager, sendCounterPacket);
2261 sendThread.Start(mockProfilingConnection);
2263 // The profiling state is set to "WaitingForAck", so the send thread should send a Stream Metadata packet
2264 // Wait for sendThread to join
2265 BOOST_CHECK_NO_THROW(sendThread.Stop());
2267 // Check that the buffer contains at least one Stream Metadata packet and no other packets
2268 const auto writtenDataSize = mockProfilingConnection.GetWrittenDataSize();
2270 BOOST_TEST(writtenDataSize >= 1);
2271 BOOST_TEST(mockProfilingConnection.CheckForPacket(
2272 {PacketType::StreamMetaData, streamMetadataPacketsize}) == writtenDataSize);
2275 BOOST_AUTO_TEST_CASE(SendThreadSendStreamMetadataPacket4)
2277 ProfilingStateMachine profilingStateMachine;
2278 SetWaitingForAckProfilingState(profilingStateMachine);
2280 // Calculate the size of a Stream Metadata packet
2281 std::string processName = GetProcessName().substr(0, 60);
2282 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
2283 unsigned int streamMetadataPacketsize = 118 + processNameSize;
2285 MockProfilingConnection mockProfilingConnection;
2286 BufferManager bufferManager(3, 1024);
2287 SendCounterPacket sendCounterPacket(bufferManager);
2288 SendThread sendThread(profilingStateMachine, bufferManager, sendCounterPacket);
2289 sendThread.Start(mockProfilingConnection);
2291 // The profiling state is set to "WaitingForAck", so the send thread should send a Stream Metadata packet
2292 // Wait for sendThread to join
2295 sendThread.Start(mockProfilingConnection);
2296 // Check that the profiling state is still "WaitingForAck"
2297 BOOST_TEST((profilingStateMachine.GetCurrentState() == ProfilingState::WaitingForAck));
2299 // Check that the buffer contains at least one Stream Metadata packet
2300 BOOST_TEST(mockProfilingConnection.CheckForPacket({PacketType::StreamMetaData, streamMetadataPacketsize}) >= 1);
2302 mockProfilingConnection.Clear();
2305 sendThread.Start(mockProfilingConnection);
2307 // Try triggering a new buffer read
2308 sendThread.SetReadyToRead();
2310 // Wait for sendThread to join
2311 BOOST_CHECK_NO_THROW(sendThread.Stop());
2313 // Check that the profiling state is still "WaitingForAck"
2314 BOOST_TEST((profilingStateMachine.GetCurrentState() == ProfilingState::WaitingForAck));
2316 // Check that the buffer contains at least one Stream Metadata packet and no other packets
2317 const auto writtenDataSize = mockProfilingConnection.GetWrittenDataSize();
2319 BOOST_TEST(writtenDataSize >= 1);
2320 BOOST_TEST(mockProfilingConnection.CheckForPacket(
2321 {PacketType::StreamMetaData, streamMetadataPacketsize}) == writtenDataSize);
2324 BOOST_AUTO_TEST_SUITE_END()