blob: 00dad380782e2d727cb16fc6c8e42034df88bc60 [file] [log] [blame]
Ferran Balagueraf5c46b2019-08-30 15:49:15 +01001//
Ferran Balaguer1b941722019-08-28 16:57:18 +01002// Copyright © 2019 Arm Ltd. All rights reserved.
Ferran Balagueraf5c46b2019-08-30 15:49:15 +01003// SPDX-License-Identifier: MIT
4//
5
Ferran Balaguer1b941722019-08-28 16:57:18 +01006#include "SendCounterPacketTests.hpp"
Ferran Balagueraf5c46b2019-08-30 15:49:15 +01007
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01008#include <CounterDirectory.hpp>
9#include <BufferManager.hpp>
Matteo Martincigh6db5f202019-09-05 12:02:04 +010010#include <EncodeVersion.hpp>
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +010011#include <ProfilingUtils.hpp>
Matteo Martincigh6db5f202019-09-05 12:02:04 +010012#include <SendCounterPacket.hpp>
13
Ferran Balaguer73882172019-09-02 16:39:42 +010014#include <armnn/Exceptions.hpp>
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +010015#include <armnn/Conversion.hpp>
Ferran Balaguer73882172019-09-02 16:39:42 +010016
Ferran Balagueraf5c46b2019-08-30 15:49:15 +010017#include <boost/test/unit_test.hpp>
Ferran Balaguer47d0fe92019-09-04 16:47:34 +010018#include <boost/numeric/conversion/cast.hpp>
Ferran Balagueraf5c46b2019-08-30 15:49:15 +010019
Francis Murtagh3a161982019-09-04 15:25:02 +010020#include <chrono>
Ferran Balagueraf5c46b2019-08-30 15:49:15 +010021
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +010022using namespace armnn::profiling;
23
Matteo Martincigh5d737fb2019-10-07 13:05:13 +010024namespace
25{
26
27void SetNotConnectedProfilingState(ProfilingStateMachine& profilingStateMachine)
28{
29 ProfilingState currentState = profilingStateMachine.GetCurrentState();
30 switch (currentState)
31 {
32 case ProfilingState::WaitingForAck:
33 profilingStateMachine.TransitionToState(ProfilingState::Active);
34 case ProfilingState::Uninitialised:
35 case ProfilingState::Active:
36 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
37 case ProfilingState::NotConnected:
38 return;
39 default:
40 BOOST_CHECK_MESSAGE(false, "Invalid profiling state");
41 }
42}
43
44void SetWaitingForAckProfilingState(ProfilingStateMachine& profilingStateMachine)
45{
46 ProfilingState currentState = profilingStateMachine.GetCurrentState();
47 switch (currentState)
48 {
49 case ProfilingState::Uninitialised:
50 case ProfilingState::Active:
51 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
52 case ProfilingState::NotConnected:
53 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
54 case ProfilingState::WaitingForAck:
55 return;
56 default:
57 BOOST_CHECK_MESSAGE(false, "Invalid profiling state");
58 }
59}
60
61void SetActiveProfilingState(ProfilingStateMachine& profilingStateMachine)
62{
63 ProfilingState currentState = profilingStateMachine.GetCurrentState();
64 switch (currentState)
65 {
66 case ProfilingState::Uninitialised:
67 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
68 case ProfilingState::NotConnected:
69 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
70 case ProfilingState::WaitingForAck:
71 profilingStateMachine.TransitionToState(ProfilingState::Active);
72 case ProfilingState::Active:
73 return;
74 default:
75 BOOST_CHECK_MESSAGE(false, "Invalid profiling state");
76 }
77}
78
79} // Anonymous namespace
80
Ferran Balagueraf5c46b2019-08-30 15:49:15 +010081BOOST_AUTO_TEST_SUITE(SendCounterPacketTests)
82
Ferran Balagueraf5c46b2019-08-30 15:49:15 +010083BOOST_AUTO_TEST_CASE(MockSendCounterPacketTest)
84{
Narumol Prangnawarat404b2752019-09-24 17:23:16 +010085 MockBufferManager mockBuffer(512);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +010086 MockSendCounterPacket mockSendCounterPacket(mockBuffer);
Ferran Balagueraf5c46b2019-08-30 15:49:15 +010087
Matteo Martincigh5d737fb2019-10-07 13:05:13 +010088 mockSendCounterPacket.SendStreamMetaDataPacket();
Narumol Prangnawarat404b2752019-09-24 17:23:16 +010089
90 auto packetBuffer = mockBuffer.GetReadableBuffer();
91 const char* buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
Ferran Balagueraf5c46b2019-08-30 15:49:15 +010092
93 BOOST_TEST(strcmp(buffer, "SendStreamMetaDataPacket") == 0);
94
Narumol Prangnawarat404b2752019-09-24 17:23:16 +010095 mockBuffer.MarkRead(packetBuffer);
96
Matteo Martincigh6db5f202019-09-05 12:02:04 +010097 CounterDirectory counterDirectory;
Matteo Martincigh5d737fb2019-10-07 13:05:13 +010098 mockSendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
Ferran Balagueraf5c46b2019-08-30 15:49:15 +010099
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100100 packetBuffer = mockBuffer.GetReadableBuffer();
101 buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
102
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100103 BOOST_TEST(strcmp(buffer, "SendCounterDirectoryPacket") == 0);
104
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100105 mockBuffer.MarkRead(packetBuffer);
106
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100107 uint64_t timestamp = 0;
Francis Murtagh3a161982019-09-04 15:25:02 +0100108 std::vector<std::pair<uint16_t, uint32_t>> indexValuePairs;
109
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100110 mockSendCounterPacket.SendPeriodicCounterCapturePacket(timestamp, indexValuePairs);
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100111
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100112 packetBuffer = mockBuffer.GetReadableBuffer();
113 buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
114
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100115 BOOST_TEST(strcmp(buffer, "SendPeriodicCounterCapturePacket") == 0);
116
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100117 mockBuffer.MarkRead(packetBuffer);
118
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100119 uint32_t capturePeriod = 0;
120 std::vector<uint16_t> selectedCounterIds;
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100121 mockSendCounterPacket.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds);
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100122
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100123 packetBuffer = mockBuffer.GetReadableBuffer();
124 buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
125
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100126 BOOST_TEST(strcmp(buffer, "SendPeriodicCounterSelectionPacket") == 0);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100127
128 mockBuffer.MarkRead(packetBuffer);
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100129}
130
Ferran Balaguer73882172019-09-02 16:39:42 +0100131BOOST_AUTO_TEST_CASE(SendPeriodicCounterSelectionPacketTest)
132{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100133 ProfilingStateMachine profilingStateMachine;
134
Ferran Balaguer73882172019-09-02 16:39:42 +0100135 // Error no space left in buffer
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100136 MockBufferManager mockBuffer1(10);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100137 SendCounterPacket sendPacket1(profilingStateMachine, mockBuffer1);
Ferran Balaguer73882172019-09-02 16:39:42 +0100138
139 uint32_t capturePeriod = 1000;
140 std::vector<uint16_t> selectedCounterIds;
141 BOOST_CHECK_THROW(sendPacket1.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds),
Matteo Martincigh24e8f922019-09-19 11:57:46 +0100142 BufferExhaustion);
Ferran Balaguer73882172019-09-02 16:39:42 +0100143
144 // Packet without any counters
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100145 MockBufferManager mockBuffer2(512);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100146 SendCounterPacket sendPacket2(profilingStateMachine, mockBuffer2);
Ferran Balaguer73882172019-09-02 16:39:42 +0100147
148 sendPacket2.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100149 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
Ferran Balaguer73882172019-09-02 16:39:42 +0100150
151 uint32_t headerWord0 = ReadUint32(readBuffer2, 0);
152 uint32_t headerWord1 = ReadUint32(readBuffer2, 4);
153 uint32_t period = ReadUint32(readBuffer2, 8);
154
155 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
156 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
157 BOOST_TEST(headerWord1 == 4); // data lenght
158 BOOST_TEST(period == 1000); // capture period
159
160 // Full packet message
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100161 MockBufferManager mockBuffer3(512);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100162 SendCounterPacket sendPacket3(profilingStateMachine, mockBuffer3);
Ferran Balaguer73882172019-09-02 16:39:42 +0100163
164 selectedCounterIds.reserve(5);
165 selectedCounterIds.emplace_back(100);
166 selectedCounterIds.emplace_back(200);
167 selectedCounterIds.emplace_back(300);
168 selectedCounterIds.emplace_back(400);
169 selectedCounterIds.emplace_back(500);
170 sendPacket3.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100171 auto readBuffer3 = mockBuffer3.GetReadableBuffer();
Ferran Balaguer73882172019-09-02 16:39:42 +0100172
173 headerWord0 = ReadUint32(readBuffer3, 0);
174 headerWord1 = ReadUint32(readBuffer3, 4);
175 period = ReadUint32(readBuffer3, 8);
176
177 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
178 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
179 BOOST_TEST(headerWord1 == 14); // data lenght
180 BOOST_TEST(period == 1000); // capture period
181
182 uint16_t counterId = 0;
183 uint32_t offset = 12;
184
185 // Counter Ids
186 for(const uint16_t& id : selectedCounterIds)
187 {
188 counterId = ReadUint16(readBuffer3, offset);
189 BOOST_TEST(counterId == id);
190 offset += 2;
191 }
192}
193
Francis Murtagh3a161982019-09-04 15:25:02 +0100194BOOST_AUTO_TEST_CASE(SendPeriodicCounterCapturePacketTest)
195{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100196 ProfilingStateMachine profilingStateMachine;
197
Francis Murtagh3a161982019-09-04 15:25:02 +0100198 // Error no space left in buffer
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100199 MockBufferManager mockBuffer1(10);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100200 SendCounterPacket sendPacket1(profilingStateMachine, mockBuffer1);
Francis Murtagh3a161982019-09-04 15:25:02 +0100201
202 auto captureTimestamp = std::chrono::steady_clock::now();
203 uint64_t time = static_cast<uint64_t >(captureTimestamp.time_since_epoch().count());
204 std::vector<std::pair<uint16_t, uint32_t>> indexValuePairs;
205
206 BOOST_CHECK_THROW(sendPacket1.SendPeriodicCounterCapturePacket(time, indexValuePairs),
207 BufferExhaustion);
208
209 // Packet without any counters
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100210 MockBufferManager mockBuffer2(512);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100211 SendCounterPacket sendPacket2(profilingStateMachine, mockBuffer2);
Francis Murtagh3a161982019-09-04 15:25:02 +0100212
213 sendPacket2.SendPeriodicCounterCapturePacket(time, indexValuePairs);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100214 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
Francis Murtagh3a161982019-09-04 15:25:02 +0100215
216 uint32_t headerWord0 = ReadUint32(readBuffer2, 0);
217 uint32_t headerWord1 = ReadUint32(readBuffer2, 4);
218 uint64_t readTimestamp = ReadUint64(readBuffer2, 8);
219
220 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 1); // packet family
221 BOOST_TEST(((headerWord0 >> 19) & 0x3F) == 0); // packet class
222 BOOST_TEST(((headerWord0 >> 16) & 0x3) == 0); // packet type
223 BOOST_TEST(headerWord1 == 8); // data length
224 BOOST_TEST(time == readTimestamp); // capture period
225
226 // Full packet message
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100227 MockBufferManager mockBuffer3(512);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100228 SendCounterPacket sendPacket3(profilingStateMachine, mockBuffer3);
Francis Murtagh3a161982019-09-04 15:25:02 +0100229
230 indexValuePairs.reserve(5);
231 indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t >(0, 100));
232 indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t >(1, 200));
233 indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t >(2, 300));
234 indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t >(3, 400));
235 indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t >(4, 500));
236 sendPacket3.SendPeriodicCounterCapturePacket(time, indexValuePairs);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100237 auto readBuffer3 = mockBuffer3.GetReadableBuffer();
Francis Murtagh3a161982019-09-04 15:25:02 +0100238
239 headerWord0 = ReadUint32(readBuffer3, 0);
240 headerWord1 = ReadUint32(readBuffer3, 4);
241 uint64_t readTimestamp2 = ReadUint64(readBuffer3, 8);
242
243 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 1); // packet family
244 BOOST_TEST(((headerWord0 >> 19) & 0x3F) == 0); // packet class
245 BOOST_TEST(((headerWord0 >> 16) & 0x3) == 0); // packet type
246 BOOST_TEST(headerWord1 == 38); // data length
247 BOOST_TEST(time == readTimestamp2); // capture period
248
249 uint16_t counterIndex = 0;
250 uint32_t counterValue = 100;
251 uint32_t offset = 16;
252
253 // Counter Ids
254 for (auto it = indexValuePairs.begin(), end = indexValuePairs.end(); it != end; ++it)
255 {
256 // Check Counter Index
257 uint16_t readIndex = ReadUint16(readBuffer3, offset);
258 BOOST_TEST(counterIndex == readIndex);
259 counterIndex++;
260 offset += 2;
261
262 // Check Counter Value
263 uint32_t readValue = ReadUint32(readBuffer3, offset);
264 BOOST_TEST(counterValue == readValue);
265 counterValue += 100;
266 offset += 4;
267 }
268
269}
270
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100271BOOST_AUTO_TEST_CASE(SendStreamMetaDataPacketTest)
272{
273 using boost::numeric_cast;
274
275 uint32_t sizeUint32 = numeric_cast<uint32_t>(sizeof(uint32_t));
276
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100277 ProfilingStateMachine profilingStateMachine;
278
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100279 // Error no space left in buffer
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100280 MockBufferManager mockBuffer1(10);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100281 SendCounterPacket sendPacket1(profilingStateMachine, mockBuffer1);
Matteo Martincigh149528e2019-09-05 12:02:04 +0100282 BOOST_CHECK_THROW(sendPacket1.SendStreamMetaDataPacket(), armnn::profiling::BufferExhaustion);
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100283
284 // Full metadata packet
285
286 std::string processName = GetProcessName().substr(0, 60);
287
288 uint32_t infoSize = numeric_cast<uint32_t>(GetSoftwareInfo().size()) > 0 ?
289 numeric_cast<uint32_t>(GetSoftwareInfo().size()) + 1 : 0;
290 uint32_t hardwareVersionSize = numeric_cast<uint32_t>(GetHardwareVersion().size()) > 0 ?
291 numeric_cast<uint32_t>(GetHardwareVersion().size()) + 1 : 0;
292 uint32_t softwareVersionSize = numeric_cast<uint32_t>(GetSoftwareVersion().size()) > 0 ?
293 numeric_cast<uint32_t>(GetSoftwareVersion().size()) + 1 : 0;
294 uint32_t processNameSize = numeric_cast<uint32_t>(processName.size()) > 0 ?
295 numeric_cast<uint32_t>(processName.size()) + 1 : 0;
296
Ferran Balaguer5bf1d322019-09-13 13:31:40 +0100297 uint32_t packetEntries = 6;
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100298
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100299 MockBufferManager mockBuffer2(512);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100300 SendCounterPacket sendPacket2(profilingStateMachine, mockBuffer2);
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100301 sendPacket2.SendStreamMetaDataPacket();
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100302 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100303
304 uint32_t headerWord0 = ReadUint32(readBuffer2, 0);
305 uint32_t headerWord1 = ReadUint32(readBuffer2, sizeUint32);
306
307 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
308 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 0); // packet id
309
310 uint32_t totalLength = numeric_cast<uint32_t>(2 * sizeUint32 + 10 * sizeUint32 + infoSize + hardwareVersionSize +
311 softwareVersionSize + processNameSize + sizeUint32 +
312 2 * packetEntries * sizeUint32);
313
314 BOOST_TEST(headerWord1 == totalLength - (2 * sizeUint32)); // data length
315
316 uint32_t offset = sizeUint32 * 2;
317 BOOST_TEST(ReadUint32(readBuffer2, offset) == SendCounterPacket::PIPE_MAGIC); // pipe_magic
318 offset += sizeUint32;
319 BOOST_TEST(ReadUint32(readBuffer2, offset) == EncodeVersion(1, 0, 0)); // stream_metadata_version
320 offset += sizeUint32;
321 BOOST_TEST(ReadUint32(readBuffer2, offset) == SendCounterPacket::MAX_METADATA_PACKET_LENGTH); // max_data_len
322 offset += sizeUint32;
323 BOOST_TEST(ReadUint32(readBuffer2, offset) == numeric_cast<uint32_t>(getpid())); // pid
324 offset += sizeUint32;
325 uint32_t poolOffset = 10 * sizeUint32;
326 BOOST_TEST(ReadUint32(readBuffer2, offset) == (infoSize ? poolOffset : 0)); // offset_info
327 offset += sizeUint32;
328 poolOffset += infoSize;
329 BOOST_TEST(ReadUint32(readBuffer2, offset) == (hardwareVersionSize ? poolOffset : 0)); // offset_hw_version
330 offset += sizeUint32;
331 poolOffset += hardwareVersionSize;
332 BOOST_TEST(ReadUint32(readBuffer2, offset) == (softwareVersionSize ? poolOffset : 0)); // offset_sw_version
333 offset += sizeUint32;
334 poolOffset += softwareVersionSize;
335 BOOST_TEST(ReadUint32(readBuffer2, offset) == (processNameSize ? poolOffset : 0)); // offset_process_name
336 offset += sizeUint32;
337 poolOffset += processNameSize;
338 BOOST_TEST(ReadUint32(readBuffer2, offset) == (packetEntries ? poolOffset : 0)); // offset_packet_version_table
339 offset += sizeUint32;
340 BOOST_TEST(ReadUint32(readBuffer2, offset) == 0); // reserved
341
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100342 const unsigned char* readData2 = readBuffer2->GetReadableData();
343
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100344 offset += sizeUint32;
345 if (infoSize)
346 {
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100347 BOOST_TEST(strcmp(reinterpret_cast<const char *>(&readData2[offset]), GetSoftwareInfo().c_str()) == 0);
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100348 offset += infoSize;
349 }
350
351 if (hardwareVersionSize)
352 {
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100353 BOOST_TEST(strcmp(reinterpret_cast<const char *>(&readData2[offset]), GetHardwareVersion().c_str()) == 0);
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100354 offset += hardwareVersionSize;
355 }
356
357 if (softwareVersionSize)
358 {
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100359 BOOST_TEST(strcmp(reinterpret_cast<const char *>(&readData2[offset]), GetSoftwareVersion().c_str()) == 0);
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100360 offset += softwareVersionSize;
361 }
362
363 if (processNameSize)
364 {
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100365 BOOST_TEST(strcmp(reinterpret_cast<const char *>(&readData2[offset]), GetProcessName().c_str()) == 0);
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100366 offset += processNameSize;
367 }
368
369 if (packetEntries)
370 {
371 BOOST_TEST((ReadUint32(readBuffer2, offset) >> 16) == packetEntries);
372 offset += sizeUint32;
Ferran Balaguer5bf1d322019-09-13 13:31:40 +0100373 for (uint32_t i = 0; i < packetEntries - 1; ++i)
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100374 {
375 BOOST_TEST(((ReadUint32(readBuffer2, offset) >> 26) & 0x3F) == 0);
376 BOOST_TEST(((ReadUint32(readBuffer2, offset) >> 16) & 0x3FF) == i);
377 offset += sizeUint32;
378 BOOST_TEST(ReadUint32(readBuffer2, offset) == EncodeVersion(1, 0, 0));
379 offset += sizeUint32;
380 }
Ferran Balaguer5bf1d322019-09-13 13:31:40 +0100381
382 BOOST_TEST(((ReadUint32(readBuffer2, offset) >> 26) & 0x3F) == 1);
383 BOOST_TEST(((ReadUint32(readBuffer2, offset) >> 16) & 0x3FF) == 0);
384 offset += sizeUint32;
385 BOOST_TEST(ReadUint32(readBuffer2, offset) == EncodeVersion(1, 0, 0));
386 offset += sizeUint32;
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100387 }
388
389 BOOST_TEST(offset == totalLength);
390}
391
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100392BOOST_AUTO_TEST_CASE(CreateDeviceRecordTest)
393{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100394 ProfilingStateMachine profilingStateMachine;
395
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100396 MockBufferManager mockBuffer(0);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100397 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100398
399 // Create a device for testing
400 uint16_t deviceUid = 27;
401 const std::string deviceName = "some_device";
402 uint16_t deviceCores = 3;
403 const DevicePtr device = std::make_unique<Device>(deviceUid, deviceName, deviceCores);
404
405 // Create a device record
406 SendCounterPacket::DeviceRecord deviceRecord;
407 std::string errorMessage;
408 bool result = sendCounterPacketTest.CreateDeviceRecordTest(device, deviceRecord, errorMessage);
409
410 BOOST_CHECK(result);
411 BOOST_CHECK(errorMessage.empty());
412 BOOST_CHECK(deviceRecord.size() == 6); // Size in words: header [2] + device name [4]
413
414 uint16_t deviceRecordWord0[]
415 {
416 static_cast<uint16_t>(deviceRecord[0] >> 16),
417 static_cast<uint16_t>(deviceRecord[0])
418 };
419 BOOST_CHECK(deviceRecordWord0[0] == deviceUid); // uid
420 BOOST_CHECK(deviceRecordWord0[1] == deviceCores); // cores
421 BOOST_CHECK(deviceRecord[1] == 0); // name_offset
422 BOOST_CHECK(deviceRecord[2] == deviceName.size() + 1); // The length of the SWTrace string (name)
423 BOOST_CHECK(std::memcmp(deviceRecord.data() + 3, deviceName.data(), deviceName.size()) == 0); // name
424}
425
426BOOST_AUTO_TEST_CASE(CreateInvalidDeviceRecordTest)
427{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100428 ProfilingStateMachine profilingStateMachine;
429
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100430 MockBufferManager mockBuffer(0);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100431 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100432
433 // Create a device for testing
434 uint16_t deviceUid = 27;
435 const std::string deviceName = "some€£invalid‡device";
436 uint16_t deviceCores = 3;
437 const DevicePtr device = std::make_unique<Device>(deviceUid, deviceName, deviceCores);
438
439 // Create a device record
440 SendCounterPacket::DeviceRecord deviceRecord;
441 std::string errorMessage;
442 bool result = sendCounterPacketTest.CreateDeviceRecordTest(device, deviceRecord, errorMessage);
443
444 BOOST_CHECK(!result);
445 BOOST_CHECK(!errorMessage.empty());
446 BOOST_CHECK(deviceRecord.empty());
447}
448
449BOOST_AUTO_TEST_CASE(CreateCounterSetRecordTest)
450{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100451 ProfilingStateMachine profilingStateMachine;
452
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100453 MockBufferManager mockBuffer(0);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100454 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100455
456 // Create a counter set for testing
457 uint16_t counterSetUid = 27;
458 const std::string counterSetName = "some_counter_set";
459 uint16_t counterSetCount = 3421;
460 const CounterSetPtr counterSet = std::make_unique<CounterSet>(counterSetUid, counterSetName, counterSetCount);
461
462 // Create a counter set record
463 SendCounterPacket::CounterSetRecord counterSetRecord;
464 std::string errorMessage;
465 bool result = sendCounterPacketTest.CreateCounterSetRecordTest(counterSet, counterSetRecord, errorMessage);
466
467 BOOST_CHECK(result);
468 BOOST_CHECK(errorMessage.empty());
469 BOOST_CHECK(counterSetRecord.size() == 8); // Size in words: header [2] + counter set name [6]
470
471 uint16_t counterSetRecordWord0[]
472 {
473 static_cast<uint16_t>(counterSetRecord[0] >> 16),
474 static_cast<uint16_t>(counterSetRecord[0])
475 };
476 BOOST_CHECK(counterSetRecordWord0[0] == counterSetUid); // uid
477 BOOST_CHECK(counterSetRecordWord0[1] == counterSetCount); // cores
478 BOOST_CHECK(counterSetRecord[1] == 0); // name_offset
479 BOOST_CHECK(counterSetRecord[2] == counterSetName.size() + 1); // The length of the SWTrace string (name)
480 BOOST_CHECK(std::memcmp(counterSetRecord.data() + 3, counterSetName.data(), counterSetName.size()) == 0); // name
481}
482
483BOOST_AUTO_TEST_CASE(CreateInvalidCounterSetRecordTest)
484{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100485 ProfilingStateMachine profilingStateMachine;
486
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100487 MockBufferManager mockBuffer(0);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100488 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100489
490 // Create a counter set for testing
491 uint16_t counterSetUid = 27;
492 const std::string counterSetName = "some invalid_counter€£set";
493 uint16_t counterSetCount = 3421;
494 const CounterSetPtr counterSet = std::make_unique<CounterSet>(counterSetUid, counterSetName, counterSetCount);
495
496 // Create a counter set record
497 SendCounterPacket::CounterSetRecord counterSetRecord;
498 std::string errorMessage;
499 bool result = sendCounterPacketTest.CreateCounterSetRecordTest(counterSet, counterSetRecord, errorMessage);
500
501 BOOST_CHECK(!result);
502 BOOST_CHECK(!errorMessage.empty());
503 BOOST_CHECK(counterSetRecord.empty());
504}
505
506BOOST_AUTO_TEST_CASE(CreateEventRecordTest)
507{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100508 ProfilingStateMachine profilingStateMachine;
509
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100510 MockBufferManager mockBuffer(0);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100511 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100512
513 // Create a counter for testing
514 uint16_t counterUid = 7256;
515 uint16_t maxCounterUid = 132;
516 uint16_t deviceUid = 132;
517 uint16_t counterSetUid = 4497;
518 uint16_t counterClass = 1;
519 uint16_t counterInterpolation = 1;
520 double counterMultiplier = 1234.567f;
521 const std::string counterName = "some_valid_counter";
522 const std::string counterDescription = "a_counter_for_testing";
523 const std::string counterUnits = "Mrads2";
524 const CounterPtr counter = std::make_unique<Counter>(counterUid,
525 maxCounterUid,
526 counterClass,
527 counterInterpolation,
528 counterMultiplier,
529 counterName,
530 counterDescription,
531 counterUnits,
532 deviceUid,
533 counterSetUid);
534 BOOST_ASSERT(counter);
535
536 // Create an event record
537 SendCounterPacket::EventRecord eventRecord;
538 std::string errorMessage;
539 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
540
541 BOOST_CHECK(result);
542 BOOST_CHECK(errorMessage.empty());
543 BOOST_CHECK(eventRecord.size() == 24); // Size in words: header [8] + counter name [6] + description [7] + units [3]
544
545 uint16_t eventRecordWord0[]
546 {
547 static_cast<uint16_t>(eventRecord[0] >> 16),
548 static_cast<uint16_t>(eventRecord[0])
549 };
550 uint16_t eventRecordWord1[]
551 {
552 static_cast<uint16_t>(eventRecord[1] >> 16),
553 static_cast<uint16_t>(eventRecord[1])
554 };
555 uint16_t eventRecordWord2[]
556 {
557 static_cast<uint16_t>(eventRecord[2] >> 16),
558 static_cast<uint16_t>(eventRecord[2])
559 };
560 uint32_t eventRecordWord34[]
561 {
562 eventRecord[3],
563 eventRecord[4]
564 };
565 BOOST_CHECK(eventRecordWord0[0] == maxCounterUid); // max_counter_uid
566 BOOST_CHECK(eventRecordWord0[1] == counterUid); // counter_uid
567 BOOST_CHECK(eventRecordWord1[0] == deviceUid); // device
568 BOOST_CHECK(eventRecordWord1[1] == counterSetUid); // counter_set
569 BOOST_CHECK(eventRecordWord2[0] == counterClass); // class
570 BOOST_CHECK(eventRecordWord2[1] == counterInterpolation); // interpolation
571 BOOST_CHECK(std::memcmp(eventRecordWord34, &counterMultiplier, sizeof(counterMultiplier)) == 0); // multiplier
572
573 ARMNN_NO_CONVERSION_WARN_BEGIN
574 uint32_t counterNameOffset = 0; // The name is the first item in pool
575 uint32_t counterDescriptionOffset = counterNameOffset + // Counter name offset
576 4u + // Counter name length (uint32_t)
577 counterName.size() + // 18u
578 1u + // Null-terminator
579 1u; // Rounding to the next word
580 size_t counterUnitsOffset = counterDescriptionOffset + // Counter description offset
581 4u + // Counter description length (uint32_t)
582 counterDescription.size() + // 21u
583 1u + // Null-terminator
584 2u; // Rounding to the next word
585 ARMNN_NO_CONVERSION_WARN_END
586
587 BOOST_CHECK(eventRecord[5] == counterNameOffset); // name_offset
588 BOOST_CHECK(eventRecord[6] == counterDescriptionOffset); // description_offset
589 BOOST_CHECK(eventRecord[7] == counterUnitsOffset); // units_offset
590
591 auto eventRecordPool = reinterpret_cast<unsigned char*>(eventRecord.data() + 8u); // The start of the pool
592 size_t uint32_t_size = sizeof(uint32_t);
593
594 // The length of the SWTrace string (name)
595 BOOST_CHECK(eventRecordPool[counterNameOffset] == counterName.size() + 1);
596 // The counter name
597 BOOST_CHECK(std::memcmp(eventRecordPool +
598 counterNameOffset + // Offset
599 uint32_t_size /* The length of the name */,
600 counterName.data(),
601 counterName.size()) == 0); // name
602 // The null-terminator at the end of the name
603 BOOST_CHECK(eventRecordPool[counterNameOffset + uint32_t_size + counterName.size()] == '\0');
604
605 // The length of the SWTrace string (description)
606 BOOST_CHECK(eventRecordPool[counterDescriptionOffset] == counterDescription.size() + 1);
607 // The counter description
608 BOOST_CHECK(std::memcmp(eventRecordPool +
609 counterDescriptionOffset + // Offset
610 uint32_t_size /* The length of the description */,
611 counterDescription.data(),
612 counterDescription.size()) == 0); // description
613 // The null-terminator at the end of the description
614 BOOST_CHECK(eventRecordPool[counterDescriptionOffset + uint32_t_size + counterDescription.size()] == '\0');
615
616 // The length of the SWTrace namestring (units)
617 BOOST_CHECK(eventRecordPool[counterUnitsOffset] == counterUnits.size() + 1);
618 // The counter units
619 BOOST_CHECK(std::memcmp(eventRecordPool +
620 counterUnitsOffset + // Offset
621 uint32_t_size /* The length of the units */,
622 counterUnits.data(),
623 counterUnits.size()) == 0); // units
624 // The null-terminator at the end of the units
625 BOOST_CHECK(eventRecordPool[counterUnitsOffset + uint32_t_size + counterUnits.size()] == '\0');
626}
627
628BOOST_AUTO_TEST_CASE(CreateEventRecordNoUnitsTest)
629{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100630 ProfilingStateMachine profilingStateMachine;
631
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100632 MockBufferManager mockBuffer(0);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100633 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100634
635 // Create a counter for testing
636 uint16_t counterUid = 44312;
637 uint16_t maxCounterUid = 345;
638 uint16_t deviceUid = 101;
639 uint16_t counterSetUid = 34035;
640 uint16_t counterClass = 0;
641 uint16_t counterInterpolation = 1;
642 double counterMultiplier = 4435.0023f;
643 const std::string counterName = "some_valid_counter";
644 const std::string counterDescription = "a_counter_for_testing";
645 const CounterPtr counter = std::make_unique<Counter>(counterUid,
646 maxCounterUid,
647 counterClass,
648 counterInterpolation,
649 counterMultiplier,
650 counterName,
651 counterDescription,
652 "",
653 deviceUid,
654 counterSetUid);
655 BOOST_ASSERT(counter);
656
657 // Create an event record
658 SendCounterPacket::EventRecord eventRecord;
659 std::string errorMessage;
660 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
661
662 BOOST_CHECK(result);
663 BOOST_CHECK(errorMessage.empty());
664 BOOST_CHECK(eventRecord.size() == 21); // Size in words: header [8] + counter name [6] + description [7]
665
666 uint16_t eventRecordWord0[]
667 {
668 static_cast<uint16_t>(eventRecord[0] >> 16),
669 static_cast<uint16_t>(eventRecord[0])
670 };
671 uint16_t eventRecordWord1[]
672 {
673 static_cast<uint16_t>(eventRecord[1] >> 16),
674 static_cast<uint16_t>(eventRecord[1])
675 };
676 uint16_t eventRecordWord2[]
677 {
678 static_cast<uint16_t>(eventRecord[2] >> 16),
679 static_cast<uint16_t>(eventRecord[2])
680 };
681 uint32_t eventRecordWord34[]
682 {
683 eventRecord[3],
684 eventRecord[4]
685 };
686 BOOST_CHECK(eventRecordWord0[0] == maxCounterUid); // max_counter_uid
687 BOOST_CHECK(eventRecordWord0[1] == counterUid); // counter_uid
688 BOOST_CHECK(eventRecordWord1[0] == deviceUid); // device
689 BOOST_CHECK(eventRecordWord1[1] == counterSetUid); // counter_set
690 BOOST_CHECK(eventRecordWord2[0] == counterClass); // class
691 BOOST_CHECK(eventRecordWord2[1] == counterInterpolation); // interpolation
692 BOOST_CHECK(std::memcmp(eventRecordWord34, &counterMultiplier, sizeof(counterMultiplier)) == 0); // multiplier
693
694 ARMNN_NO_CONVERSION_WARN_BEGIN
695 uint32_t counterNameOffset = 0; // The name is the first item in pool
696 uint32_t counterDescriptionOffset = counterNameOffset + // Counter name offset
697 4u + // Counter name length (uint32_t)
698 counterName.size() + // 18u
699 1u + // Null-terminator
700 1u; // Rounding to the next word
701 ARMNN_NO_CONVERSION_WARN_END
702
703 BOOST_CHECK(eventRecord[5] == counterNameOffset); // name_offset
704 BOOST_CHECK(eventRecord[6] == counterDescriptionOffset); // description_offset
705 BOOST_CHECK(eventRecord[7] == 0); // units_offset
706
707 auto eventRecordPool = reinterpret_cast<unsigned char*>(eventRecord.data() + 8u); // The start of the pool
708 size_t uint32_t_size = sizeof(uint32_t);
709
710 // The length of the SWTrace string (name)
711 BOOST_CHECK(eventRecordPool[counterNameOffset] == counterName.size() + 1);
712 // The counter name
713 BOOST_CHECK(std::memcmp(eventRecordPool +
714 counterNameOffset + // Offset
715 uint32_t_size, // The length of the name
716 counterName.data(),
717 counterName.size()) == 0); // name
718 // The null-terminator at the end of the name
719 BOOST_CHECK(eventRecordPool[counterNameOffset + uint32_t_size + counterName.size()] == '\0');
720
721 // The length of the SWTrace string (description)
722 BOOST_CHECK(eventRecordPool[counterDescriptionOffset] == counterDescription.size() + 1);
723 // The counter description
724 BOOST_CHECK(std::memcmp(eventRecordPool +
725 counterDescriptionOffset + // Offset
726 uint32_t_size, // The length of the description
727 counterDescription.data(),
728 counterDescription.size()) == 0); // description
729 // The null-terminator at the end of the description
730 BOOST_CHECK(eventRecordPool[counterDescriptionOffset + uint32_t_size + counterDescription.size()] == '\0');
731}
732
733BOOST_AUTO_TEST_CASE(CreateInvalidEventRecordTest1)
734{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100735 ProfilingStateMachine profilingStateMachine;
736
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100737 MockBufferManager mockBuffer(0);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100738 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100739
740 // Create a counter for testing
741 uint16_t counterUid = 7256;
742 uint16_t maxCounterUid = 132;
743 uint16_t deviceUid = 132;
744 uint16_t counterSetUid = 4497;
745 uint16_t counterClass = 1;
746 uint16_t counterInterpolation = 1;
747 double counterMultiplier = 1234.567f;
748 const std::string counterName = "some_invalid_counter £££"; // Invalid name
749 const std::string counterDescription = "a_counter_for_testing";
750 const std::string counterUnits = "Mrads2";
751 const CounterPtr counter = std::make_unique<Counter>(counterUid,
752 maxCounterUid,
753 counterClass,
754 counterInterpolation,
755 counterMultiplier,
756 counterName,
757 counterDescription,
758 counterUnits,
759 deviceUid,
760 counterSetUid);
761 BOOST_ASSERT(counter);
762
763 // Create an event record
764 SendCounterPacket::EventRecord eventRecord;
765 std::string errorMessage;
766 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
767
768 BOOST_CHECK(!result);
769 BOOST_CHECK(!errorMessage.empty());
770 BOOST_CHECK(eventRecord.empty());
771}
772
773BOOST_AUTO_TEST_CASE(CreateInvalidEventRecordTest2)
774{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100775 ProfilingStateMachine profilingStateMachine;
776
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100777 MockBufferManager mockBuffer(0);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100778 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100779
780 // Create a counter for testing
781 uint16_t counterUid = 7256;
782 uint16_t maxCounterUid = 132;
783 uint16_t deviceUid = 132;
784 uint16_t counterSetUid = 4497;
785 uint16_t counterClass = 1;
786 uint16_t counterInterpolation = 1;
787 double counterMultiplier = 1234.567f;
788 const std::string counterName = "some_invalid_counter";
789 const std::string counterDescription = "an invalid d€scription"; // Invalid description
790 const std::string counterUnits = "Mrads2";
791 const CounterPtr counter = std::make_unique<Counter>(counterUid,
792 maxCounterUid,
793 counterClass,
794 counterInterpolation,
795 counterMultiplier,
796 counterName,
797 counterDescription,
798 counterUnits,
799 deviceUid,
800 counterSetUid);
801 BOOST_ASSERT(counter);
802
803 // Create an event record
804 SendCounterPacket::EventRecord eventRecord;
805 std::string errorMessage;
806 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
807
808 BOOST_CHECK(!result);
809 BOOST_CHECK(!errorMessage.empty());
810 BOOST_CHECK(eventRecord.empty());
811}
812
813BOOST_AUTO_TEST_CASE(CreateInvalidEventRecordTest3)
814{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100815 ProfilingStateMachine profilingStateMachine;
816
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100817 MockBufferManager mockBuffer(0);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100818 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100819
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>(counterUid,
832 maxCounterUid,
833 counterClass,
834 counterInterpolation,
835 counterMultiplier,
836 counterName,
837 counterDescription,
838 counterUnits,
839 deviceUid,
840 counterSetUid);
841 BOOST_ASSERT(counter);
842
843 // Create an event record
844 SendCounterPacket::EventRecord eventRecord;
845 std::string errorMessage;
846 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
847
848 BOOST_CHECK(!result);
849 BOOST_CHECK(!errorMessage.empty());
850 BOOST_CHECK(eventRecord.empty());
851}
852
853BOOST_AUTO_TEST_CASE(CreateCategoryRecordTest)
854{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100855 ProfilingStateMachine profilingStateMachine;
856
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100857 MockBufferManager mockBuffer(0);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100858 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100859
860 // Create a category for testing
861 const std::string categoryName = "some_category";
862 uint16_t deviceUid = 1302;
863 uint16_t counterSetUid = 20734;
864 const CategoryPtr category = std::make_unique<Category>(categoryName, deviceUid, counterSetUid);
865 BOOST_ASSERT(category);
866 category->m_Counters = { 11u, 23u, 5670u };
867
868 // Create a collection of counters
869 Counters counters;
870 counters.insert(std::make_pair<uint16_t, CounterPtr>(11,
871 CounterPtr(new Counter(11,
872 1234,
873 0,
874 1,
875 534.0003f,
876 "counter1",
877 "the first counter",
878 "millipi2",
879 0,
880 0))));
881 counters.insert(std::make_pair<uint16_t, CounterPtr>(23,
882 CounterPtr(new Counter(23,
883 344,
884 1,
885 1,
886 534.0003f,
887 "this is counter 2",
888 "the second counter",
889 "",
890 0,
891 0))));
892 counters.insert(std::make_pair<uint16_t, CounterPtr>(5670,
893 CounterPtr(new Counter(5670,
894 31,
895 0,
896 0,
897 534.0003f,
898 "and this is number 3",
899 "the third counter",
900 "blah_per_second",
901 0,
902 0))));
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());
910
911 // Create a category record
912 SendCounterPacket::CategoryRecord categoryRecord;
913 std::string errorMessage;
914 bool result = sendCounterPacketTest.CreateCategoryRecordTest(category, counters, categoryRecord, errorMessage);
915
916 BOOST_CHECK(result);
917 BOOST_CHECK(errorMessage.empty());
918 BOOST_CHECK(categoryRecord.size() == 80); // Size in words: header [4] + event pointer table [3] +
919 // category name [5] + event records [68 = 22 + 20 + 26]
920
921 uint16_t categoryRecordWord0[]
922 {
923 static_cast<uint16_t>(categoryRecord[0] >> 16),
924 static_cast<uint16_t>(categoryRecord[0])
925 };
926 uint16_t categoryRecordWord1[]
927 {
928 static_cast<uint16_t>(categoryRecord[1] >> 16),
929 static_cast<uint16_t>(categoryRecord[1])
930 };
931 BOOST_CHECK(categoryRecordWord0[0] == deviceUid); // device
932 BOOST_CHECK(categoryRecordWord0[1] == counterSetUid); // counter_set
933 BOOST_CHECK(categoryRecordWord1[0] == categoryEventCount); // event_count
934 BOOST_CHECK(categoryRecordWord1[1] == 0); // reserved
935
936 size_t uint32_t_size = sizeof(uint32_t);
937
938 ARMNN_NO_CONVERSION_WARN_BEGIN
939 uint32_t eventPointerTableOffset = 0; // The event pointer table is the first item in pool
940 uint32_t categoryNameOffset = eventPointerTableOffset + // Event pointer table offset
941 categoryEventCount * uint32_t_size; // The size of the event pointer table
942 ARMNN_NO_CONVERSION_WARN_END
943
944 BOOST_CHECK(categoryRecord[2] == eventPointerTableOffset); // event_pointer_table_offset
945 BOOST_CHECK(categoryRecord[3] == categoryNameOffset); // name_offset
946
947 auto categoryRecordPool = reinterpret_cast<unsigned char*>(categoryRecord.data() + 4u); // The start of the pool
948
949 // The event pointer table
950 uint32_t eventRecord0Offset = categoryRecordPool[eventPointerTableOffset + 0 * uint32_t_size];
951 uint32_t eventRecord1Offset = categoryRecordPool[eventPointerTableOffset + 1 * uint32_t_size];
952 uint32_t eventRecord2Offset = categoryRecordPool[eventPointerTableOffset + 2 * uint32_t_size];
953 BOOST_CHECK(eventRecord0Offset == 32);
954 BOOST_CHECK(eventRecord1Offset == 120);
955 BOOST_CHECK(eventRecord2Offset == 200);
956
957 // The length of the SWTrace namestring (name)
958 BOOST_CHECK(categoryRecordPool[categoryNameOffset] == categoryName.size() + 1);
959 // The category name
960 BOOST_CHECK(std::memcmp(categoryRecordPool +
961 categoryNameOffset + // Offset
962 uint32_t_size, // The length of the name
963 categoryName.data(),
964 categoryName.size()) == 0); // name
965 // The null-terminator at the end of the name
966 BOOST_CHECK(categoryRecordPool[categoryNameOffset + uint32_t_size + categoryName.size()] == '\0');
967
968 // For brevity, checking only the UIDs, max counter UIDs and names of the counters in the event records,
969 // as the event records already have a number of unit tests dedicated to them
970
971 // Counter1 UID and max counter UID
972 uint16_t eventRecord0Word0[2] = { 0u, 0u };
973 std::memcpy(eventRecord0Word0, categoryRecordPool + eventRecord0Offset, sizeof(eventRecord0Word0));
974 BOOST_CHECK(eventRecord0Word0[0] == counter1->m_Uid);
975 BOOST_CHECK(eventRecord0Word0[1] == counter1->m_MaxCounterUid);
976
977 // Counter1 name
978 uint32_t counter1NameOffset = 0;
979 std::memcpy(&counter1NameOffset, categoryRecordPool + eventRecord0Offset + 5u * uint32_t_size, uint32_t_size);
980 BOOST_CHECK(counter1NameOffset == 0);
981 // The length of the SWTrace string (name)
982 BOOST_CHECK(categoryRecordPool[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 ] == counter1->m_Name.size() + 1); // The length of the name including the
986 // null-terminator
987 // The counter1 name
988 BOOST_CHECK(std::memcmp(categoryRecordPool + // The beginning of the category pool
989 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.data(),
994 counter1->m_Name.size()) == 0); // name
995 // The null-terminator at the end of the counter1 name
996 BOOST_CHECK(categoryRecordPool[eventRecord0Offset + // Offset to the event record
997 8u * uint32_t_size + // Offset to the event record pool
998 counter1NameOffset + // Offset to the name of the counter
999 uint32_t_size + // The length of the name
1000 counter1->m_Name.size() // The name of the counter
1001 ] == '\0');
1002
1003 // Counter2 name
1004 uint32_t counter2NameOffset = 0;
1005 std::memcpy(&counter2NameOffset, categoryRecordPool + eventRecord1Offset + 5u * uint32_t_size, uint32_t_size);
1006 BOOST_CHECK(counter2NameOffset == 0);
1007 // The length of the SWTrace string (name)
1008 BOOST_CHECK(categoryRecordPool[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 ] == counter2->m_Name.size() + 1); // The length of the name including the
1012 // null-terminator
1013 // The counter2 name
1014 BOOST_CHECK(std::memcmp(categoryRecordPool + // The beginning of the category pool
1015 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.data(),
1020 counter2->m_Name.size()) == 0); // name
1021 // The null-terminator at the end of the counter2 name
1022 BOOST_CHECK(categoryRecordPool[eventRecord1Offset + // Offset to the event record
1023 8u * uint32_t_size + // Offset to the event record pool
1024 counter2NameOffset + // Offset to the name of the counter
1025 uint32_t_size + // The length of the name
1026 counter2->m_Name.size() // The name of the counter
1027 ] == '\0');
1028
1029 // Counter3 name
1030 uint32_t counter3NameOffset = 0;
1031 std::memcpy(&counter3NameOffset, categoryRecordPool + eventRecord2Offset + 5u * uint32_t_size, uint32_t_size);
1032 BOOST_CHECK(counter3NameOffset == 0);
1033 // The length of the SWTrace string (name)
1034 BOOST_CHECK(categoryRecordPool[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 ] == counter3->m_Name.size() + 1); // The length of the name including the
1038 // null-terminator
1039 // The counter3 name
1040 BOOST_CHECK(std::memcmp(categoryRecordPool + // The beginning of the category pool
1041 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.data(),
1046 counter3->m_Name.size()) == 0); // name
1047 // The null-terminator at the end of the counter3 name
1048 BOOST_CHECK(categoryRecordPool[eventRecord2Offset + // Offset to the event record
1049 8u * uint32_t_size + // Offset to the event record pool
1050 counter3NameOffset + // Offset to the name of the counter
1051 uint32_t_size + // The length of the name
1052 counter3->m_Name.size() // The name of the counter
1053 ] == '\0');
1054}
1055
1056BOOST_AUTO_TEST_CASE(CreateInvalidCategoryRecordTest1)
1057{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001058 ProfilingStateMachine profilingStateMachine;
1059
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001060 MockBufferManager mockBuffer(0);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001061 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001062
1063 // Create a category for testing
1064 const std::string categoryName = "some invalid category";
1065 uint16_t deviceUid = 1302;
1066 uint16_t counterSetUid = 20734;
1067 const CategoryPtr category = std::make_unique<Category>(categoryName, deviceUid, counterSetUid);
1068 BOOST_CHECK(category);
1069
1070 // Create a category record
1071 Counters counters;
1072 SendCounterPacket::CategoryRecord categoryRecord;
1073 std::string errorMessage;
1074 bool result = sendCounterPacketTest.CreateCategoryRecordTest(category, counters, categoryRecord, errorMessage);
1075
1076 BOOST_CHECK(!result);
1077 BOOST_CHECK(!errorMessage.empty());
1078 BOOST_CHECK(categoryRecord.empty());
1079}
1080
1081BOOST_AUTO_TEST_CASE(CreateInvalidCategoryRecordTest2)
1082{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001083 ProfilingStateMachine profilingStateMachine;
1084
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001085 MockBufferManager mockBuffer(0);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001086 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001087
1088 // Create a category for testing
1089 const std::string categoryName = "some_category";
1090 uint16_t deviceUid = 1302;
1091 uint16_t counterSetUid = 20734;
1092 const CategoryPtr category = std::make_unique<Category>(categoryName, deviceUid, counterSetUid);
1093 BOOST_CHECK(category);
1094 category->m_Counters = { 11u, 23u, 5670u };
1095
1096 // Create a collection of counters
1097 Counters counters;
1098 counters.insert(std::make_pair<uint16_t, CounterPtr>(11,
1099 CounterPtr(new Counter(11,
1100 1234,
1101 0,
1102 1,
1103 534.0003f,
1104 "count€r1", // Invalid name
1105 "the first counter",
1106 "millipi2",
1107 0,
1108 0))));
1109
1110 Counter* counter1 = counters.find(11)->second.get();
1111 BOOST_CHECK(counter1);
1112
1113 // Create a category record
1114 SendCounterPacket::CategoryRecord categoryRecord;
1115 std::string errorMessage;
1116 bool result = sendCounterPacketTest.CreateCategoryRecordTest(category, counters, categoryRecord, errorMessage);
1117
1118 BOOST_CHECK(!result);
1119 BOOST_CHECK(!errorMessage.empty());
1120 BOOST_CHECK(categoryRecord.empty());
1121}
1122
1123BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest1)
1124{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001125 ProfilingStateMachine profilingStateMachine;
1126
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001127 // The counter directory used for testing
1128 CounterDirectory counterDirectory;
1129
1130 // Register a device
1131 const std::string device1Name = "device1";
1132 const Device* device1 = nullptr;
1133 BOOST_CHECK_NO_THROW(device1 = counterDirectory.RegisterDevice(device1Name, 3));
1134 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1135 BOOST_CHECK(device1);
1136
1137 // Register a device
1138 const std::string device2Name = "device2";
1139 const Device* device2 = nullptr;
1140 BOOST_CHECK_NO_THROW(device2 = counterDirectory.RegisterDevice(device2Name));
1141 BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
1142 BOOST_CHECK(device2);
1143
1144 // Buffer with not enough space
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001145 MockBufferManager mockBuffer(10);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001146 SendCounterPacket sendCounterPacket(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001147 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory),
1148 armnn::profiling::BufferExhaustion);
1149}
1150
1151BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest2)
1152{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001153 ProfilingStateMachine profilingStateMachine;
1154
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001155 // The counter directory used for testing
1156 CounterDirectory counterDirectory;
1157
1158 // Register a device
1159 const std::string device1Name = "device1";
1160 const Device* device1 = nullptr;
1161 BOOST_CHECK_NO_THROW(device1 = counterDirectory.RegisterDevice(device1Name, 3));
1162 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1163 BOOST_CHECK(device1);
1164
1165 // Register a device
1166 const std::string device2Name = "device2";
1167 const Device* device2 = nullptr;
1168 BOOST_CHECK_NO_THROW(device2 = counterDirectory.RegisterDevice(device2Name));
1169 BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
1170 BOOST_CHECK(device2);
1171
1172 // Register a counter set
1173 const std::string counterSet1Name = "counterset1";
1174 const CounterSet* counterSet1 = nullptr;
1175 BOOST_CHECK_NO_THROW(counterSet1 = counterDirectory.RegisterCounterSet(counterSet1Name));
1176 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1177 BOOST_CHECK(counterSet1);
1178
1179 // Register a category associated to "device1" and "counterset1"
1180 const std::string category1Name = "category1";
1181 const Category* category1 = nullptr;
1182 BOOST_CHECK_NO_THROW(category1 = counterDirectory.RegisterCategory(category1Name,
1183 device1->m_Uid,
1184 counterSet1->m_Uid));
1185 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1186 BOOST_CHECK(category1);
1187
1188 // Register a category not associated to "device2" but no counter set
1189 const std::string category2Name = "category2";
1190 const Category* category2 = nullptr;
1191 BOOST_CHECK_NO_THROW(category2 = counterDirectory.RegisterCategory(category2Name,
1192 device2->m_Uid));
1193 BOOST_CHECK(counterDirectory.GetCategoryCount() == 2);
1194 BOOST_CHECK(category2);
1195
1196 // Register a counter associated to "category1"
1197 const Counter* counter1 = nullptr;
1198 BOOST_CHECK_NO_THROW(counter1 = counterDirectory.RegisterCounter(category1Name,
1199 0,
1200 1,
1201 123.45f,
1202 "counter1",
1203 "counter1description",
1204 std::string("counter1units")));
1205 BOOST_CHECK(counterDirectory.GetCounterCount() == 3);
1206 BOOST_CHECK(counter1);
1207
1208 // Register a counter associated to "category1"
1209 const Counter* counter2 = nullptr;
1210 BOOST_CHECK_NO_THROW(counter2 = counterDirectory.RegisterCounter(category1Name,
1211 1,
1212 0,
1213 330.1245656765f,
1214 "counter2",
1215 "counter2description",
1216 std::string("counter2units"),
1217 armnn::EmptyOptional(),
1218 device2->m_Uid,
1219 0));
1220 BOOST_CHECK(counterDirectory.GetCounterCount() == 4);
1221 BOOST_CHECK(counter2);
1222
1223 // Register a counter associated to "category2"
1224 const Counter* counter3 = nullptr;
1225 BOOST_CHECK_NO_THROW(counter3 = counterDirectory.RegisterCounter(category2Name,
1226 1,
1227 1,
1228 0.0000045399f,
1229 "counter3",
1230 "counter3description",
1231 armnn::EmptyOptional(),
1232 5,
1233 device2->m_Uid,
1234 counterSet1->m_Uid));
1235 BOOST_CHECK(counterDirectory.GetCounterCount() == 9);
1236 BOOST_CHECK(counter3);
1237
1238 // Buffer with enough space
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001239 MockBufferManager mockBuffer(1024);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001240 SendCounterPacket sendCounterPacket(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001241 BOOST_CHECK_NO_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory));
1242
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001243 // Get the readable buffer
1244 auto readBuffer = mockBuffer.GetReadableBuffer();
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001245
1246 // Check the packet header
1247 uint32_t packetHeaderWord0 = ReadUint32(readBuffer, 0);
1248 uint32_t packetHeaderWord1 = ReadUint32(readBuffer, 4);
1249 BOOST_TEST(((packetHeaderWord0 >> 26) & 0x3F) == 0); // packet_family
1250 BOOST_TEST(((packetHeaderWord0 >> 16) & 0x3FF) == 2); // packet_id
Matteo Martincighf74ff2f2019-09-24 11:38:32 +01001251 BOOST_TEST(packetHeaderWord1 == 936); // data_length
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001252
1253 // Check the body header
1254 uint32_t bodyHeaderWord0 = ReadUint32(readBuffer, 8);
1255 uint32_t bodyHeaderWord1 = ReadUint32(readBuffer, 12);
1256 uint32_t bodyHeaderWord2 = ReadUint32(readBuffer, 16);
1257 uint32_t bodyHeaderWord3 = ReadUint32(readBuffer, 20);
1258 uint32_t bodyHeaderWord4 = ReadUint32(readBuffer, 24);
1259 uint32_t bodyHeaderWord5 = ReadUint32(readBuffer, 28);
1260 uint16_t deviceRecordCount = static_cast<uint16_t>(bodyHeaderWord0 >> 16);
1261 uint16_t counterSetRecordCount = static_cast<uint16_t>(bodyHeaderWord2 >> 16);
1262 uint16_t categoryRecordCount = static_cast<uint16_t>(bodyHeaderWord4 >> 16);
1263 BOOST_TEST(deviceRecordCount == 2); // device_records_count
1264 BOOST_TEST(bodyHeaderWord1 == 0); // device_records_pointer_table_offset
1265 BOOST_TEST(counterSetRecordCount == 1); // counter_set_count
1266 BOOST_TEST(bodyHeaderWord3 == 8); // counter_set_pointer_table_offset
1267 BOOST_TEST(categoryRecordCount == 2); // categories_count
1268 BOOST_TEST(bodyHeaderWord5 == 12); // categories_pointer_table_offset
1269
1270 // Check the device records pointer table
1271 uint32_t deviceRecordOffset0 = ReadUint32(readBuffer, 32);
1272 uint32_t deviceRecordOffset1 = ReadUint32(readBuffer, 36);
1273 BOOST_TEST(deviceRecordOffset0 == 0); // Device record offset for "device1"
1274 BOOST_TEST(deviceRecordOffset1 == 20); // Device record offset for "device2"
1275
1276 // Check the counter set pointer table
1277 uint32_t counterSetRecordOffset0 = ReadUint32(readBuffer, 40);
1278 BOOST_TEST(counterSetRecordOffset0 == 40); // Counter set record offset for "counterset1"
1279
1280 // Check the category pointer table
1281 uint32_t categoryRecordOffset0 = ReadUint32(readBuffer, 44);
1282 uint32_t categoryRecordOffset1 = ReadUint32(readBuffer, 48);
1283 BOOST_TEST(categoryRecordOffset0 == 64); // Category record offset for "category1"
1284 BOOST_TEST(categoryRecordOffset1 == 476); // Category record offset for "category2"
1285
1286 // Get the device record pool offset
1287 uint32_t uint32_t_size = sizeof(uint32_t);
1288 uint32_t packetBodyPoolOffset = 2u * uint32_t_size + // packet_header
1289 6u * uint32_t_size + // body_header
1290 deviceRecordCount * uint32_t_size + // Size of device_records_pointer_table
1291 counterSetRecordCount * uint32_t_size + // Size of counter_set_pointer_table
1292 categoryRecordCount * uint32_t_size; // Size of categories_pointer_table
1293
1294 // Device record structure/collection used for testing
1295 struct DeviceRecord
1296 {
1297 uint16_t uid;
1298 uint16_t cores;
1299 uint32_t name_offset;
1300 uint32_t name_length;
1301 std::string name;
1302 };
1303 std::vector<DeviceRecord> deviceRecords;
1304 uint32_t deviceRecordsPointerTableOffset = 2u * uint32_t_size + // packet_header
1305 6u * uint32_t_size + // body_header
1306 bodyHeaderWord1; // device_records_pointer_table_offset
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001307
1308 const unsigned char* readData = readBuffer->GetReadableData();
1309
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001310 for (uint32_t i = 0; i < deviceRecordCount; i++)
1311 {
1312 // Get the device record offset
1313 uint32_t deviceRecordOffset = ReadUint32(readBuffer, deviceRecordsPointerTableOffset + i * uint32_t_size);
1314
1315 // Collect the data for the device record
1316 uint32_t deviceRecordWord0 = ReadUint32(readBuffer,
1317 packetBodyPoolOffset + deviceRecordOffset + 0 * uint32_t_size);
1318 uint32_t deviceRecordWord1 = ReadUint32(readBuffer,
1319 packetBodyPoolOffset + deviceRecordOffset + 1 * uint32_t_size);
1320 DeviceRecord deviceRecord;
1321 deviceRecord.uid = static_cast<uint16_t>(deviceRecordWord0 >> 16); // uid
1322 deviceRecord.cores = static_cast<uint16_t>(deviceRecordWord0); // cores
1323 deviceRecord.name_offset = deviceRecordWord1; // name_offset
1324
1325 uint32_t deviceRecordPoolOffset = packetBodyPoolOffset + // Packet body offset
1326 deviceRecordOffset + // Device record offset
1327 2 * uint32_t_size + // Device record header
1328 deviceRecord.name_offset; // Device name offset
1329 uint32_t deviceRecordNameLength = ReadUint32(readBuffer, deviceRecordPoolOffset);
1330 deviceRecord.name_length = deviceRecordNameLength; // name_length
1331 unsigned char deviceRecordNameNullTerminator = // name null-terminator
1332 ReadUint8(readBuffer, deviceRecordPoolOffset + uint32_t_size + deviceRecordNameLength - 1);
1333 BOOST_CHECK(deviceRecordNameNullTerminator == '\0');
1334 std::vector<unsigned char> deviceRecordNameBuffer(deviceRecord.name_length - 1);
1335 std::memcpy(deviceRecordNameBuffer.data(),
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001336 readData + deviceRecordPoolOffset + uint32_t_size, deviceRecordNameBuffer.size());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001337 deviceRecord.name.assign(deviceRecordNameBuffer.begin(), deviceRecordNameBuffer.end()); // name
1338
1339 deviceRecords.push_back(deviceRecord);
1340 }
1341
1342 // Check that the device records are correct
1343 BOOST_CHECK(deviceRecords.size() == 2);
1344 for (const DeviceRecord& deviceRecord : deviceRecords)
1345 {
1346 const Device* device = counterDirectory.GetDevice(deviceRecord.uid);
1347 BOOST_CHECK(device);
1348 BOOST_CHECK(device->m_Uid == deviceRecord.uid);
1349 BOOST_CHECK(device->m_Cores == deviceRecord.cores);
1350 BOOST_CHECK(device->m_Name == deviceRecord.name);
1351 }
1352
1353 // Counter set record structure/collection used for testing
1354 struct CounterSetRecord
1355 {
1356 uint16_t uid;
1357 uint16_t count;
1358 uint32_t name_offset;
1359 uint32_t name_length;
1360 std::string name;
1361 };
1362 std::vector<CounterSetRecord> counterSetRecords;
1363 uint32_t counterSetRecordsPointerTableOffset = 2u * uint32_t_size + // packet_header
1364 6u * uint32_t_size + // body_header
1365 bodyHeaderWord3; // counter_set_pointer_table_offset
1366 for (uint32_t i = 0; i < counterSetRecordCount; i++)
1367 {
1368 // Get the counter set record offset
1369 uint32_t counterSetRecordOffset = ReadUint32(readBuffer,
1370 counterSetRecordsPointerTableOffset + i * uint32_t_size);
1371
1372 // Collect the data for the counter set record
1373 uint32_t counterSetRecordWord0 = ReadUint32(readBuffer,
1374 packetBodyPoolOffset + counterSetRecordOffset + 0 * uint32_t_size);
1375 uint32_t counterSetRecordWord1 = ReadUint32(readBuffer,
1376 packetBodyPoolOffset + counterSetRecordOffset + 1 * uint32_t_size);
1377 CounterSetRecord counterSetRecord;
1378 counterSetRecord.uid = static_cast<uint16_t>(counterSetRecordWord0 >> 16); // uid
1379 counterSetRecord.count = static_cast<uint16_t>(counterSetRecordWord0); // count
1380 counterSetRecord.name_offset = counterSetRecordWord1; // name_offset
1381
1382 uint32_t counterSetRecordPoolOffset = packetBodyPoolOffset + // Packet body offset
1383 counterSetRecordOffset + // Counter set record offset
1384 2 * uint32_t_size + // Counter set record header
1385 counterSetRecord.name_offset; // Counter set name offset
1386 uint32_t counterSetRecordNameLength = ReadUint32(readBuffer, counterSetRecordPoolOffset);
1387 counterSetRecord.name_length = counterSetRecordNameLength; // name_length
1388 unsigned char counterSetRecordNameNullTerminator = // name null-terminator
1389 ReadUint8(readBuffer, counterSetRecordPoolOffset + uint32_t_size + counterSetRecordNameLength - 1);
1390 BOOST_CHECK(counterSetRecordNameNullTerminator == '\0');
1391 std::vector<unsigned char> counterSetRecordNameBuffer(counterSetRecord.name_length - 1);
1392 std::memcpy(counterSetRecordNameBuffer.data(),
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001393 readData + counterSetRecordPoolOffset + uint32_t_size, counterSetRecordNameBuffer.size());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001394 counterSetRecord.name.assign(counterSetRecordNameBuffer.begin(), counterSetRecordNameBuffer.end()); // name
1395
1396 counterSetRecords.push_back(counterSetRecord);
1397 }
1398
1399 // Check that the counter set records are correct
1400 BOOST_CHECK(counterSetRecords.size() == 1);
1401 for (const CounterSetRecord& counterSetRecord : counterSetRecords)
1402 {
1403 const CounterSet* counterSet = counterDirectory.GetCounterSet(counterSetRecord.uid);
1404 BOOST_CHECK(counterSet);
1405 BOOST_CHECK(counterSet->m_Uid == counterSetRecord.uid);
1406 BOOST_CHECK(counterSet->m_Count == counterSetRecord.count);
1407 BOOST_CHECK(counterSet->m_Name == counterSetRecord.name);
1408 }
1409
1410 // Event record structure/collection used for testing
1411 struct EventRecord
1412 {
1413 uint16_t counter_uid;
1414 uint16_t max_counter_uid;
1415 uint16_t device;
1416 uint16_t counter_set;
1417 uint16_t counter_class;
1418 uint16_t interpolation;
1419 double multiplier;
1420 uint32_t name_offset;
1421 uint32_t name_length;
1422 std::string name;
1423 uint32_t description_offset;
1424 uint32_t description_length;
1425 std::string description;
1426 uint32_t units_offset;
1427 uint32_t units_length;
1428 std::string units;
1429 };
1430 // Category record structure/collection used for testing
1431 struct CategoryRecord
1432 {
1433 uint16_t device;
1434 uint16_t counter_set;
1435 uint16_t event_count;
1436 uint32_t event_pointer_table_offset;
1437 uint32_t name_offset;
1438 uint32_t name_length;
1439 std::string name;
1440 std::vector<uint32_t> event_pointer_table;
1441 std::vector<EventRecord> event_records;
1442 };
1443 std::vector<CategoryRecord> categoryRecords;
1444 uint32_t categoryRecordsPointerTableOffset = 2u * uint32_t_size + // packet_header
1445 6u * uint32_t_size + // body_header
1446 bodyHeaderWord5; // categories_pointer_table_offset
1447 for (uint32_t i = 0; i < categoryRecordCount; i++)
1448 {
1449 // Get the category record offset
1450 uint32_t categoryRecordOffset = ReadUint32(readBuffer, categoryRecordsPointerTableOffset + i * uint32_t_size);
1451
1452 // Collect the data for the category record
1453 uint32_t categoryRecordWord0 = ReadUint32(readBuffer,
1454 packetBodyPoolOffset + categoryRecordOffset + 0 * uint32_t_size);
1455 uint32_t categoryRecordWord1 = ReadUint32(readBuffer,
1456 packetBodyPoolOffset + categoryRecordOffset + 1 * uint32_t_size);
1457 uint32_t categoryRecordWord2 = ReadUint32(readBuffer,
1458 packetBodyPoolOffset + categoryRecordOffset + 2 * uint32_t_size);
1459 uint32_t categoryRecordWord3 = ReadUint32(readBuffer,
1460 packetBodyPoolOffset + categoryRecordOffset + 3 * uint32_t_size);
1461 CategoryRecord categoryRecord;
1462 categoryRecord.device = static_cast<uint16_t>(categoryRecordWord0 >> 16); // device
1463 categoryRecord.counter_set = static_cast<uint16_t>(categoryRecordWord0); // counter_set
1464 categoryRecord.event_count = static_cast<uint16_t>(categoryRecordWord1 >> 16); // event_count
1465 categoryRecord.event_pointer_table_offset = categoryRecordWord2; // event_pointer_table_offset
1466 categoryRecord.name_offset = categoryRecordWord3; // name_offset
1467
1468 uint32_t categoryRecordPoolOffset = packetBodyPoolOffset + // Packet body offset
1469 categoryRecordOffset + // Category record offset
1470 4 * uint32_t_size; // Category record header
1471
1472 uint32_t categoryRecordNameLength = ReadUint32(readBuffer,
1473 categoryRecordPoolOffset + categoryRecord.name_offset);
1474 categoryRecord.name_length = categoryRecordNameLength; // name_length
1475 unsigned char categoryRecordNameNullTerminator =
1476 ReadUint8(readBuffer,
1477 categoryRecordPoolOffset +
1478 categoryRecord.name_offset +
1479 uint32_t_size +
1480 categoryRecordNameLength - 1); // name null-terminator
1481 BOOST_CHECK(categoryRecordNameNullTerminator == '\0');
1482 std::vector<unsigned char> categoryRecordNameBuffer(categoryRecord.name_length - 1);
1483 std::memcpy(categoryRecordNameBuffer.data(),
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001484 readData +
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001485 categoryRecordPoolOffset +
1486 categoryRecord.name_offset +
1487 uint32_t_size,
1488 categoryRecordNameBuffer.size());
1489 categoryRecord.name.assign(categoryRecordNameBuffer.begin(), categoryRecordNameBuffer.end()); // name
1490
1491 categoryRecord.event_pointer_table.resize(categoryRecord.event_count);
1492 for (uint32_t eventIndex = 0; eventIndex < categoryRecord.event_count; eventIndex++)
1493 {
1494 uint32_t eventRecordOffset = ReadUint32(readBuffer,
1495 categoryRecordPoolOffset +
1496 categoryRecord.event_pointer_table_offset +
1497 eventIndex * uint32_t_size);
1498 categoryRecord.event_pointer_table[eventIndex] = eventRecordOffset;
1499
1500 // Collect the data for the event record
1501 uint32_t eventRecordWord0 = ReadUint32(readBuffer,
1502 categoryRecordPoolOffset + eventRecordOffset + 0 * uint32_t_size);
1503 uint32_t eventRecordWord1 = ReadUint32(readBuffer,
1504 categoryRecordPoolOffset + eventRecordOffset + 1 * uint32_t_size);
1505 uint32_t eventRecordWord2 = ReadUint32(readBuffer,
1506 categoryRecordPoolOffset + eventRecordOffset + 2 * uint32_t_size);
1507 uint64_t eventRecordWord34 = ReadUint64(readBuffer,
1508 categoryRecordPoolOffset + eventRecordOffset + 3 * uint32_t_size);
1509 uint32_t eventRecordWord5 = ReadUint32(readBuffer,
1510 categoryRecordPoolOffset + eventRecordOffset + 5 * uint32_t_size);
1511 uint32_t eventRecordWord6 = ReadUint32(readBuffer,
1512 categoryRecordPoolOffset + eventRecordOffset + 6 * uint32_t_size);
1513 uint32_t eventRecordWord7 = ReadUint32(readBuffer,
1514 categoryRecordPoolOffset + eventRecordOffset + 7 * uint32_t_size);
1515 EventRecord eventRecord;
1516 eventRecord.counter_uid = static_cast<uint16_t>(eventRecordWord0); // counter_uid
1517 eventRecord.max_counter_uid = static_cast<uint16_t>(eventRecordWord0 >> 16); // max_counter_uid
1518 eventRecord.device = static_cast<uint16_t>(eventRecordWord1 >> 16); // device
1519 eventRecord.counter_set = static_cast<uint16_t>(eventRecordWord1); // counter_set
1520 eventRecord.counter_class = static_cast<uint16_t>(eventRecordWord2 >> 16); // class
1521 eventRecord.interpolation = static_cast<uint16_t>(eventRecordWord2); // interpolation
1522 std::memcpy(&eventRecord.multiplier, &eventRecordWord34, sizeof(eventRecord.multiplier)); // multiplier
1523 eventRecord.name_offset = static_cast<uint32_t>(eventRecordWord5); // name_offset
1524 eventRecord.description_offset = static_cast<uint32_t>(eventRecordWord6); // description_offset
1525 eventRecord.units_offset = static_cast<uint32_t>(eventRecordWord7); // units_offset
1526
1527 uint32_t eventRecordPoolOffset = categoryRecordPoolOffset + // Category record pool offset
1528 eventRecordOffset + // Event record offset
1529 8 * uint32_t_size; // Event record header
1530
1531 uint32_t eventRecordNameLength = ReadUint32(readBuffer,
1532 eventRecordPoolOffset + eventRecord.name_offset);
1533 eventRecord.name_length = eventRecordNameLength; // name_length
1534 unsigned char eventRecordNameNullTerminator =
1535 ReadUint8(readBuffer,
1536 eventRecordPoolOffset +
1537 eventRecord.name_offset +
1538 uint32_t_size +
1539 eventRecordNameLength - 1); // name null-terminator
1540 BOOST_CHECK(eventRecordNameNullTerminator == '\0');
1541 std::vector<unsigned char> eventRecordNameBuffer(eventRecord.name_length - 1);
1542 std::memcpy(eventRecordNameBuffer.data(),
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001543 readData +
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001544 eventRecordPoolOffset +
1545 eventRecord.name_offset +
1546 uint32_t_size,
1547 eventRecordNameBuffer.size());
1548 eventRecord.name.assign(eventRecordNameBuffer.begin(), eventRecordNameBuffer.end()); // name
1549
1550 uint32_t eventRecordDescriptionLength = ReadUint32(readBuffer,
1551 eventRecordPoolOffset + eventRecord.description_offset);
1552 eventRecord.description_length = eventRecordDescriptionLength; // description_length
1553 unsigned char eventRecordDescriptionNullTerminator =
1554 ReadUint8(readBuffer,
1555 eventRecordPoolOffset +
1556 eventRecord.description_offset +
1557 uint32_t_size +
1558 eventRecordDescriptionLength - 1); // description null-terminator
1559 BOOST_CHECK(eventRecordDescriptionNullTerminator == '\0');
1560 std::vector<unsigned char> eventRecordDescriptionBuffer(eventRecord.description_length - 1);
1561 std::memcpy(eventRecordDescriptionBuffer.data(),
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001562 readData +
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001563 eventRecordPoolOffset +
1564 eventRecord.description_offset +
1565 uint32_t_size,
1566 eventRecordDescriptionBuffer.size());
1567 eventRecord.description.assign(eventRecordDescriptionBuffer.begin(),
1568 eventRecordDescriptionBuffer.end()); // description
1569
1570 if (eventRecord.units_offset > 0)
1571 {
1572 uint32_t eventRecordUnitsLength = ReadUint32(readBuffer,
1573 eventRecordPoolOffset + eventRecord.units_offset);
1574 eventRecord.units_length = eventRecordUnitsLength; // units_length
1575 unsigned char eventRecordUnitsNullTerminator =
1576 ReadUint8(readBuffer,
1577 eventRecordPoolOffset +
1578 eventRecord.units_offset +
1579 uint32_t_size +
1580 eventRecordUnitsLength - 1); // units null-terminator
1581 BOOST_CHECK(eventRecordUnitsNullTerminator == '\0');
1582 std::vector<unsigned char> eventRecordUnitsBuffer(eventRecord.units_length - 1);
1583 std::memcpy(eventRecordUnitsBuffer.data(),
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001584 readData +
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001585 eventRecordPoolOffset +
1586 eventRecord.units_offset +
1587 uint32_t_size,
1588 eventRecordUnitsBuffer.size());
1589 eventRecord.units.assign(eventRecordUnitsBuffer.begin(), eventRecordUnitsBuffer.end()); // units
1590 }
1591
1592 categoryRecord.event_records.push_back(eventRecord);
1593 }
1594
1595 categoryRecords.push_back(categoryRecord);
1596 }
1597
1598 // Check that the category records are correct
1599 BOOST_CHECK(categoryRecords.size() == 2);
1600 for (const CategoryRecord& categoryRecord : categoryRecords)
1601 {
1602 const Category* category = counterDirectory.GetCategory(categoryRecord.name);
1603 BOOST_CHECK(category);
1604 BOOST_CHECK(category->m_Name == categoryRecord.name);
1605 BOOST_CHECK(category->m_DeviceUid == categoryRecord.device);
1606 BOOST_CHECK(category->m_CounterSetUid == categoryRecord.counter_set);
1607 BOOST_CHECK(category->m_Counters.size() == categoryRecord.event_count);
1608
1609 // Check that the event records are correct
1610 for (const EventRecord& eventRecord : categoryRecord.event_records)
1611 {
1612 const Counter* counter = counterDirectory.GetCounter(eventRecord.counter_uid);
1613 BOOST_CHECK(counter);
1614 BOOST_CHECK(counter->m_MaxCounterUid == eventRecord.max_counter_uid);
1615 BOOST_CHECK(counter->m_DeviceUid == eventRecord.device);
1616 BOOST_CHECK(counter->m_CounterSetUid == eventRecord.counter_set);
1617 BOOST_CHECK(counter->m_Class == eventRecord.counter_class);
1618 BOOST_CHECK(counter->m_Interpolation == eventRecord.interpolation);
1619 BOOST_CHECK(counter->m_Multiplier == eventRecord.multiplier);
1620 BOOST_CHECK(counter->m_Name == eventRecord.name);
1621 BOOST_CHECK(counter->m_Description == eventRecord.description);
1622 BOOST_CHECK(counter->m_Units == eventRecord.units);
1623 }
1624 }
1625}
1626
1627BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest3)
1628{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001629 ProfilingStateMachine profilingStateMachine;
1630
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001631 // Using a mock counter directory that allows to register invalid objects
1632 MockCounterDirectory counterDirectory;
1633
1634 // Register an invalid device
1635 const std::string deviceName = "inv@lid dev!c€";
1636 const Device* device = nullptr;
1637 BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName, 3));
1638 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1639 BOOST_CHECK(device);
1640
1641 // Buffer with enough space
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001642 MockBufferManager mockBuffer(1024);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001643 SendCounterPacket sendCounterPacket(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001644 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1645}
1646
1647BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest4)
1648{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001649 ProfilingStateMachine profilingStateMachine;
1650
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001651 // Using a mock counter directory that allows to register invalid objects
1652 MockCounterDirectory counterDirectory;
1653
1654 // Register an invalid counter set
1655 const std::string counterSetName = "inv@lid count€rs€t";
1656 const CounterSet* counterSet = nullptr;
1657 BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1658 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1659 BOOST_CHECK(counterSet);
1660
1661 // Buffer with enough space
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001662 MockBufferManager mockBuffer(1024);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001663 SendCounterPacket sendCounterPacket(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001664 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1665}
1666
1667BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest5)
1668{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001669 ProfilingStateMachine profilingStateMachine;
1670
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001671 // Using a mock counter directory that allows to register invalid objects
1672 MockCounterDirectory counterDirectory;
1673
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);
1680
1681 // Buffer with enough space
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001682 MockBufferManager mockBuffer(1024);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001683 SendCounterPacket sendCounterPacket(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001684 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1685}
1686
1687BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest6)
1688{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001689 ProfilingStateMachine profilingStateMachine;
1690
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001691 // Using a mock counter directory that allows to register invalid objects
1692 MockCounterDirectory counterDirectory;
1693
1694 // Register an invalid device
1695 const std::string deviceName = "inv@lid dev!c€";
1696 const Device* device = nullptr;
1697 BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName, 3));
1698 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1699 BOOST_CHECK(device);
1700
1701 // Register an invalid counter set
1702 const std::string counterSetName = "inv@lid count€rs€t";
1703 const CounterSet* counterSet = nullptr;
1704 BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1705 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1706 BOOST_CHECK(counterSet);
1707
1708 // Register an invalid category associated to an invalid device and an invalid counter set
1709 const std::string categoryName = "c@t€gory";
1710 const Category* category = nullptr;
1711 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName,
1712 device->m_Uid,
1713 counterSet->m_Uid));
1714 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1715 BOOST_CHECK(category);
1716
1717 // Buffer with enough space
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001718 MockBufferManager mockBuffer(1024);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001719 SendCounterPacket sendCounterPacket(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001720 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1721}
1722
1723BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest7)
1724{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001725 ProfilingStateMachine profilingStateMachine;
1726
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001727 // Using a mock counter directory that allows to register invalid objects
1728 MockCounterDirectory counterDirectory;
1729
1730 // Register an valid device
1731 const std::string deviceName = "valid device";
1732 const Device* device = nullptr;
1733 BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName, 3));
1734 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1735 BOOST_CHECK(device);
1736
1737 // Register an valid counter set
1738 const std::string counterSetName = "valid counterset";
1739 const CounterSet* counterSet = nullptr;
1740 BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1741 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1742 BOOST_CHECK(counterSet);
1743
1744 // Register an valid category associated to a valid device and a valid counter set
1745 const std::string categoryName = "category";
1746 const Category* category = nullptr;
1747 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName,
1748 device->m_Uid,
1749 counterSet->m_Uid));
1750 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1751 BOOST_CHECK(category);
1752
1753 // Register an invalid counter associated to a valid category
1754 const Counter* counter = nullptr;
1755 BOOST_CHECK_NO_THROW(counter = counterDirectory.RegisterCounter(categoryName,
1756 0,
1757 1,
1758 123.45f,
1759 "counter",
1760 "counter description",
1761 std::string("invalid counter units"),
1762 5,
1763 device->m_Uid,
1764 counterSet->m_Uid));
1765 BOOST_CHECK(counterDirectory.GetCounterCount() == 5);
1766 BOOST_CHECK(counter);
1767
1768 // Buffer with enough space
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001769 MockBufferManager mockBuffer(1024);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001770 SendCounterPacket sendCounterPacket(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001771 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1772}
Ferran Balaguer47d0fe92019-09-04 16:47:34 +01001773
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001774BOOST_AUTO_TEST_CASE(SendThreadTest0)
1775{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001776 ProfilingStateMachine profilingStateMachine;
1777 SetActiveProfilingState(profilingStateMachine);
1778
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001779 MockProfilingConnection mockProfilingConnection;
Matteo Martincigh61d6f732019-10-03 11:21:18 +01001780 MockStreamCounterBuffer mockStreamCounterBuffer(0);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001781 SendCounterPacket sendCounterPacket(profilingStateMachine, mockStreamCounterBuffer);
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001782
1783 // Try to start the send thread many times, it must only start once
1784
Matteo Martincighe61ffd02019-10-07 10:19:35 +01001785 sendCounterPacket.Start(mockProfilingConnection);
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001786 BOOST_CHECK(sendCounterPacket.IsRunning());
Matteo Martincighe61ffd02019-10-07 10:19:35 +01001787 sendCounterPacket.Start(mockProfilingConnection);
1788 sendCounterPacket.Start(mockProfilingConnection);
1789 sendCounterPacket.Start(mockProfilingConnection);
1790 sendCounterPacket.Start(mockProfilingConnection);
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001791 BOOST_CHECK(sendCounterPacket.IsRunning());
1792
1793 std::this_thread::sleep_for(std::chrono::seconds(1));
1794
1795 sendCounterPacket.Stop();
1796 BOOST_CHECK(!sendCounterPacket.IsRunning());
1797}
1798
1799BOOST_AUTO_TEST_CASE(SendThreadTest1)
1800{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001801 ProfilingStateMachine profilingStateMachine;
1802 SetActiveProfilingState(profilingStateMachine);
1803
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001804 unsigned int totalWrittenSize = 0;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001805
1806 MockProfilingConnection mockProfilingConnection;
Matteo Martincigh61d6f732019-10-03 11:21:18 +01001807 MockStreamCounterBuffer mockStreamCounterBuffer(1024);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001808 SendCounterPacket sendCounterPacket(profilingStateMachine, mockStreamCounterBuffer);
Matteo Martincighe61ffd02019-10-07 10:19:35 +01001809 sendCounterPacket.Start(mockProfilingConnection);
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001810
1811 // Interleaving writes and reads to/from the buffer with pauses to test that the send thread actually waits for
1812 // something to become available for reading
1813
1814 std::this_thread::sleep_for(std::chrono::seconds(1));
1815
1816 CounterDirectory counterDirectory;
1817 sendCounterPacket.SendStreamMetaDataPacket();
1818
1819 // Get the size of the Stream Metadata Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001820 std::string processName = GetProcessName().substr(0, 60);
Matteo Martincigh61d6f732019-10-03 11:21:18 +01001821 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001822 unsigned int streamMetadataPacketsize = 118 + processNameSize;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001823 totalWrittenSize += streamMetadataPacketsize;
1824
1825 sendCounterPacket.SetReadyToRead();
1826
1827 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1828
1829 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
1830
1831 // Get the size of the Counter Directory Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001832 unsigned int counterDirectoryPacketSize = 32;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001833 totalWrittenSize += counterDirectoryPacketSize;
1834
1835 sendCounterPacket.SetReadyToRead();
1836
1837 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1838
1839 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
1840 {
1841 { 1u, 23u },
1842 { 33u, 1207623u }
1843 });
1844
1845 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001846 unsigned int periodicCounterCapturePacketSize = 28;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001847 totalWrittenSize += periodicCounterCapturePacketSize;
1848
1849 sendCounterPacket.SetReadyToRead();
1850
1851 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1852
1853 sendCounterPacket.SendPeriodicCounterCapturePacket(44u,
1854 {
1855 { 211u, 923u }
1856 });
1857
1858 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001859 periodicCounterCapturePacketSize = 22;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001860 totalWrittenSize += periodicCounterCapturePacketSize;
1861
1862 sendCounterPacket.SendPeriodicCounterCapturePacket(1234u,
1863 {
1864 { 555u, 23u },
1865 { 556u, 6u },
1866 { 557u, 893454u },
1867 { 558u, 1456623u },
1868 { 559u, 571090u }
1869 });
1870
1871 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001872 periodicCounterCapturePacketSize = 46;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001873 totalWrittenSize += periodicCounterCapturePacketSize;
1874
1875 sendCounterPacket.SendPeriodicCounterCapturePacket(997u,
1876 {
1877 { 88u, 11u },
1878 { 96u, 22u },
1879 { 97u, 33u },
1880 { 999u, 444u }
1881 });
1882
1883 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001884 periodicCounterCapturePacketSize = 40;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001885 totalWrittenSize += periodicCounterCapturePacketSize;
1886
1887 sendCounterPacket.SetReadyToRead();
1888
1889 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1890
1891 sendCounterPacket.SendPeriodicCounterSelectionPacket(1000u, { 1345u, 254u, 4536u, 408u, 54u, 6323u, 428u, 1u, 6u });
1892
1893 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001894 periodicCounterCapturePacketSize = 30;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001895 totalWrittenSize += periodicCounterCapturePacketSize;
1896
1897 sendCounterPacket.SetReadyToRead();
1898
Matteo Martincigh61d6f732019-10-03 11:21:18 +01001899 // To test an exact value of the "read size" in the mock buffer, wait two seconds to allow the send thread to
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001900 // read all what's remaining in the buffer
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001901 std::this_thread::sleep_for(std::chrono::seconds(2));
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001902
1903 sendCounterPacket.Stop();
1904
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001905 BOOST_CHECK(mockStreamCounterBuffer.GetCommittedSize() == totalWrittenSize);
Matteo Martincigh61d6f732019-10-03 11:21:18 +01001906 BOOST_CHECK(mockStreamCounterBuffer.GetReadableSize() == totalWrittenSize);
1907 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() == totalWrittenSize);
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001908}
1909
1910BOOST_AUTO_TEST_CASE(SendThreadTest2)
1911{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001912 ProfilingStateMachine profilingStateMachine;
1913 SetActiveProfilingState(profilingStateMachine);
1914
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001915 unsigned int totalWrittenSize = 0;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001916
1917 MockProfilingConnection mockProfilingConnection;
Matteo Martincigh61d6f732019-10-03 11:21:18 +01001918 MockStreamCounterBuffer mockStreamCounterBuffer(1024);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001919 SendCounterPacket sendCounterPacket(profilingStateMachine, mockStreamCounterBuffer);
Matteo Martincighe61ffd02019-10-07 10:19:35 +01001920 sendCounterPacket.Start(mockProfilingConnection);
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001921
1922 // Adding many spurious "ready to read" signals throughout the test to check that the send thread is
1923 // capable of handling unnecessary read requests
1924
1925 std::this_thread::sleep_for(std::chrono::seconds(1));
1926
1927 sendCounterPacket.SetReadyToRead();
1928
1929 CounterDirectory counterDirectory;
1930 sendCounterPacket.SendStreamMetaDataPacket();
1931
1932 // Get the size of the Stream Metadata Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001933 std::string processName = GetProcessName().substr(0, 60);
Matteo Martincigh61d6f732019-10-03 11:21:18 +01001934 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001935 unsigned int streamMetadataPacketsize = 118 + processNameSize;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001936 totalWrittenSize += streamMetadataPacketsize;
1937
1938 sendCounterPacket.SetReadyToRead();
1939
1940 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1941
1942 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
1943
1944 // Get the size of the Counter Directory Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001945 unsigned int counterDirectoryPacketSize = 32;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001946 totalWrittenSize += counterDirectoryPacketSize;
1947
1948 sendCounterPacket.SetReadyToRead();
1949 sendCounterPacket.SetReadyToRead();
1950
1951 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1952
1953 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
1954 {
1955 { 1u, 23u },
1956 { 33u, 1207623u }
1957 });
1958
1959 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001960 unsigned int periodicCounterCapturePacketSize = 28;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001961 totalWrittenSize += periodicCounterCapturePacketSize;
1962
1963 sendCounterPacket.SetReadyToRead();
1964
1965 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1966
1967 sendCounterPacket.SetReadyToRead();
1968 sendCounterPacket.SetReadyToRead();
1969 sendCounterPacket.SetReadyToRead();
1970
1971 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1972
1973 sendCounterPacket.SetReadyToRead();
1974 sendCounterPacket.SendPeriodicCounterCapturePacket(44u,
1975 {
1976 { 211u, 923u }
1977 });
1978
1979 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001980 periodicCounterCapturePacketSize = 22;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001981 totalWrittenSize += periodicCounterCapturePacketSize;
1982
1983 sendCounterPacket.SendPeriodicCounterCapturePacket(1234u,
1984 {
1985 { 555u, 23u },
1986 { 556u, 6u },
1987 { 557u, 893454u },
1988 { 558u, 1456623u },
1989 { 559u, 571090u }
1990 });
1991
1992 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001993 periodicCounterCapturePacketSize = 46;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001994 totalWrittenSize += periodicCounterCapturePacketSize;
1995
1996 sendCounterPacket.SetReadyToRead();
1997 sendCounterPacket.SendPeriodicCounterCapturePacket(997u,
1998 {
1999 { 88u, 11u },
2000 { 96u, 22u },
2001 { 97u, 33u },
2002 { 999u, 444u }
2003 });
2004
2005 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002006 periodicCounterCapturePacketSize = 40;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002007 totalWrittenSize += periodicCounterCapturePacketSize;
2008
2009 sendCounterPacket.SetReadyToRead();
2010 sendCounterPacket.SetReadyToRead();
2011
2012 std::this_thread::sleep_for(std::chrono::milliseconds(100));
2013
2014 sendCounterPacket.SendPeriodicCounterSelectionPacket(1000u, { 1345u, 254u, 4536u, 408u, 54u, 6323u, 428u, 1u, 6u });
2015
2016 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002017 periodicCounterCapturePacketSize = 30;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002018 totalWrittenSize += periodicCounterCapturePacketSize;
2019
2020 sendCounterPacket.SetReadyToRead();
2021
Matteo Martincigh61d6f732019-10-03 11:21:18 +01002022 // To test an exact value of the "read size" in the mock buffer, wait two seconds to allow the send thread to
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002023 // read all what's remaining in the buffer
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002024 std::this_thread::sleep_for(std::chrono::seconds(2));
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002025
2026 sendCounterPacket.Stop();
2027
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002028 BOOST_CHECK(mockStreamCounterBuffer.GetCommittedSize() == totalWrittenSize);
Matteo Martincigh61d6f732019-10-03 11:21:18 +01002029 BOOST_CHECK(mockStreamCounterBuffer.GetReadableSize() == totalWrittenSize);
2030 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() == totalWrittenSize);
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002031}
2032
2033BOOST_AUTO_TEST_CASE(SendThreadTest3)
2034{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002035 ProfilingStateMachine profilingStateMachine;
2036 SetActiveProfilingState(profilingStateMachine);
2037
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002038 unsigned int totalWrittenSize = 0;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002039
2040 MockProfilingConnection mockProfilingConnection;
Matteo Martincigh61d6f732019-10-03 11:21:18 +01002041 MockStreamCounterBuffer mockStreamCounterBuffer(1024);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002042 SendCounterPacket sendCounterPacket(profilingStateMachine, mockStreamCounterBuffer);
Matteo Martincighe61ffd02019-10-07 10:19:35 +01002043 sendCounterPacket.Start(mockProfilingConnection);
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002044
2045 // Not using pauses or "grace periods" to stress test the send thread
2046
2047 sendCounterPacket.SetReadyToRead();
2048
2049 CounterDirectory counterDirectory;
2050 sendCounterPacket.SendStreamMetaDataPacket();
2051
2052 // Get the size of the Stream Metadata Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002053 std::string processName = GetProcessName().substr(0, 60);
Matteo Martincigh61d6f732019-10-03 11:21:18 +01002054 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002055 unsigned int streamMetadataPacketsize = 118 + processNameSize;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002056 totalWrittenSize += streamMetadataPacketsize;
2057
2058 sendCounterPacket.SetReadyToRead();
2059 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
2060
2061 // Get the size of the Counter Directory Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002062 unsigned int counterDirectoryPacketSize =32;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002063 totalWrittenSize += counterDirectoryPacketSize;
2064
2065 sendCounterPacket.SetReadyToRead();
2066 sendCounterPacket.SetReadyToRead();
2067 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
2068 {
2069 { 1u, 23u },
2070 { 33u, 1207623u }
2071 });
2072
2073 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002074 unsigned int periodicCounterCapturePacketSize = 28;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002075 totalWrittenSize += periodicCounterCapturePacketSize;
2076
2077 sendCounterPacket.SetReadyToRead();
2078 sendCounterPacket.SetReadyToRead();
2079 sendCounterPacket.SetReadyToRead();
2080 sendCounterPacket.SetReadyToRead();
2081 sendCounterPacket.SetReadyToRead();
2082 sendCounterPacket.SendPeriodicCounterCapturePacket(44u,
2083 {
2084 { 211u, 923u }
2085 });
2086
2087 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002088 periodicCounterCapturePacketSize = 22;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002089 totalWrittenSize += periodicCounterCapturePacketSize;
2090
2091 sendCounterPacket.SendPeriodicCounterCapturePacket(1234u,
2092 {
2093 { 555u, 23u },
2094 { 556u, 6u },
2095 { 557u, 893454u },
2096 { 558u, 1456623u },
2097 { 559u, 571090u }
2098 });
2099
2100 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002101 periodicCounterCapturePacketSize = 46;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002102 totalWrittenSize += periodicCounterCapturePacketSize;
2103
2104 sendCounterPacket.SetReadyToRead();
2105 sendCounterPacket.SetReadyToRead();
2106 sendCounterPacket.SendPeriodicCounterCapturePacket(997u,
2107 {
2108 { 88u, 11u },
2109 { 96u, 22u },
2110 { 97u, 33u },
2111 { 999u, 444u }
2112 });
2113
2114 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002115 periodicCounterCapturePacketSize = 40;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002116 totalWrittenSize += periodicCounterCapturePacketSize;
2117
2118 sendCounterPacket.SetReadyToRead();
2119 sendCounterPacket.SetReadyToRead();
2120 sendCounterPacket.SendPeriodicCounterSelectionPacket(1000u, { 1345u, 254u, 4536u, 408u, 54u, 6323u, 428u, 1u, 6u });
2121
2122 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002123 periodicCounterCapturePacketSize = 30;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002124 totalWrittenSize += periodicCounterCapturePacketSize;
2125
2126 sendCounterPacket.SetReadyToRead();
2127
2128 // Abruptly terminating the send thread, the amount of data sent may be less that the amount written (the send
2129 // thread is not guaranteed to flush the buffer)
2130 sendCounterPacket.Stop();
2131
Matteo Martincigh61d6f732019-10-03 11:21:18 +01002132 BOOST_CHECK(mockStreamCounterBuffer.GetCommittedSize() == totalWrittenSize);
2133 BOOST_CHECK(mockStreamCounterBuffer.GetReadableSize() <= totalWrittenSize);
2134 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() <= totalWrittenSize);
2135 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() <= mockStreamCounterBuffer.GetReadableSize());
2136 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() <= mockStreamCounterBuffer.GetCommittedSize());
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002137}
2138
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002139BOOST_AUTO_TEST_CASE(SendThreadBufferTest)
2140{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002141 ProfilingStateMachine profilingStateMachine;
2142 SetActiveProfilingState(profilingStateMachine);
2143
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002144 MockProfilingConnection mockProfilingConnection;
2145 BufferManager bufferManager(1, 1024);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002146 SendCounterPacket sendCounterPacket(profilingStateMachine, bufferManager, -1);
Matteo Martincighe61ffd02019-10-07 10:19:35 +01002147 sendCounterPacket.Start(mockProfilingConnection);
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002148
2149 // Interleaving writes and reads to/from the buffer with pauses to test that the send thread actually waits for
2150 // something to become available for reading
2151 std::this_thread::sleep_for(std::chrono::seconds(1));
2152
2153 // SendStreamMetaDataPacket
2154 sendCounterPacket.SendStreamMetaDataPacket();
2155
2156 // Read data from the buffer
2157 // Buffer should become readable after commit by SendStreamMetaDataPacket
2158 auto packetBuffer = bufferManager.GetReadableBuffer();
2159 BOOST_TEST(packetBuffer.get());
2160
2161 std::string processName = GetProcessName().substr(0, 60);
2162 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
2163 unsigned int streamMetadataPacketsize = 118 + processNameSize;
2164 BOOST_TEST(packetBuffer->GetSize() == streamMetadataPacketsize);
2165
2166 // Buffer is not available when SendStreamMetaDataPacket already occupied the buffer.
2167 unsigned int reservedSize = 0;
2168 auto reservedBuffer = bufferManager.Reserve(512, reservedSize);
2169 BOOST_TEST(!reservedBuffer.get());
2170
2171 // Recommit to be read by sendCounterPacket
2172 bufferManager.Commit(packetBuffer, streamMetadataPacketsize);
2173
2174 sendCounterPacket.SetReadyToRead();
2175
2176 std::this_thread::sleep_for(std::chrono::seconds(1));
2177
2178 // The buffer is read by the send thread so it should not be in the readable buffer.
2179 auto readBuffer = bufferManager.GetReadableBuffer();
2180 BOOST_TEST(!readBuffer);
2181
2182 // Successfully reserved the buffer with requested size
2183 reservedBuffer = bufferManager.Reserve(512, reservedSize);
2184 BOOST_TEST(reservedSize == 512);
2185 BOOST_TEST(reservedBuffer.get());
2186
2187 // Release the buffer to be used by sendCounterPacket
2188 bufferManager.Release(reservedBuffer);
2189
2190 // SendCounterDirectoryPacket
2191 CounterDirectory counterDirectory;
2192 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
2193
2194 // Read data from the buffer
2195 // Buffer should become readable after commit by SendCounterDirectoryPacket
2196 auto counterDirectoryPacketBuffer = bufferManager.GetReadableBuffer();
2197 BOOST_TEST(counterDirectoryPacketBuffer.get());
2198
2199 // Get the size of the Counter Directory Packet
2200 unsigned int counterDirectoryPacketSize = 32;
2201 BOOST_TEST(counterDirectoryPacketBuffer->GetSize() == counterDirectoryPacketSize);
2202
2203 // Buffer is not available when SendCounterDirectoryPacket already occupied the buffer.
2204 reservedSize = 0;
2205 reservedBuffer = bufferManager.Reserve(512, reservedSize);
2206 BOOST_TEST(reservedSize == 0);
2207 BOOST_TEST(!reservedBuffer.get());
2208
2209 // Recommit to be read by sendCounterPacket
2210 bufferManager.Commit(counterDirectoryPacketBuffer, counterDirectoryPacketSize);
2211
2212 sendCounterPacket.SetReadyToRead();
2213
2214 std::this_thread::sleep_for(std::chrono::seconds(1));
2215
2216 // The buffer is read by the send thread so it should not be in the readable buffer.
2217 readBuffer = bufferManager.GetReadableBuffer();
2218 BOOST_TEST(!readBuffer);
2219
2220 // Successfully reserved the buffer with requested size
2221 reservedBuffer = bufferManager.Reserve(512, reservedSize);
2222 BOOST_TEST(reservedSize == 512);
2223 BOOST_TEST(reservedBuffer.get());
2224
2225 // Release the buffer to be used by sendCounterPacket
2226 bufferManager.Release(reservedBuffer);
2227
2228 // SendPeriodicCounterCapturePacket
2229 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
2230 {
2231 { 1u, 23u },
2232 { 33u, 1207623u }
2233 });
2234
2235 // Read data from the buffer
2236 // Buffer should become readable after commit by SendPeriodicCounterCapturePacket
2237 auto periodicCounterCapturePacketBuffer = bufferManager.GetReadableBuffer();
2238 BOOST_TEST(periodicCounterCapturePacketBuffer.get());
2239
2240 // Get the size of the Periodic Counter Capture Packet
2241 unsigned int periodicCounterCapturePacketSize = 28;
2242 BOOST_TEST(periodicCounterCapturePacketBuffer->GetSize() == periodicCounterCapturePacketSize);
2243
2244 // Buffer is not available when SendPeriodicCounterCapturePacket already occupied the buffer.
2245 reservedSize = 0;
2246 reservedBuffer = bufferManager.Reserve(512, reservedSize);
2247 BOOST_TEST(reservedSize == 0);
2248 BOOST_TEST(!reservedBuffer.get());
2249
2250 // Recommit to be read by sendCounterPacket
2251 bufferManager.Commit(periodicCounterCapturePacketBuffer, periodicCounterCapturePacketSize);
2252
2253 sendCounterPacket.SetReadyToRead();
2254
2255 std::this_thread::sleep_for(std::chrono::seconds(1));
2256
2257 // The buffer is read by the send thread so it should not be in the readable buffer.
2258 readBuffer = bufferManager.GetReadableBuffer();
2259 BOOST_TEST(!readBuffer);
2260
2261 // Successfully reserved the buffer with requested size
2262 reservedBuffer = bufferManager.Reserve(512, reservedSize);
2263 BOOST_TEST(reservedSize == 512);
2264 BOOST_TEST(reservedBuffer.get());
2265
2266 sendCounterPacket.Stop();
2267}
2268
2269BOOST_AUTO_TEST_CASE(SendThreadBufferTest1)
2270{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002271 ProfilingStateMachine profilingStateMachine;
2272 SetActiveProfilingState(profilingStateMachine);
2273
2274 MockProfilingConnection mockProfilingConnection;
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002275 BufferManager bufferManager(3, 1024);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002276 SendCounterPacket sendCounterPacket(profilingStateMachine, bufferManager, -1);
Matteo Martincighe61ffd02019-10-07 10:19:35 +01002277 sendCounterPacket.Start(mockProfilingConnection);
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002278
2279 // SendStreamMetaDataPacket
2280 sendCounterPacket.SendStreamMetaDataPacket();
2281
2282 // Read data from the buffer
2283 // Buffer should become readable after commit by SendStreamMetaDataPacket
2284 auto packetBuffer = bufferManager.GetReadableBuffer();
2285 BOOST_TEST(packetBuffer.get());
2286
2287 std::string processName = GetProcessName().substr(0, 60);
2288 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
2289 unsigned int streamMetadataPacketsize = 118 + processNameSize;
2290 BOOST_TEST(packetBuffer->GetSize() == streamMetadataPacketsize);
2291
2292 // Recommit to be read by sendCounterPacket
2293 bufferManager.Commit(packetBuffer, streamMetadataPacketsize);
2294
2295 sendCounterPacket.SetReadyToRead();
2296
2297 // SendCounterDirectoryPacket
2298 CounterDirectory counterDirectory;
2299 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
2300
2301 sendCounterPacket.SetReadyToRead();
2302
2303 // SendPeriodicCounterCapturePacket
2304 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
2305 {
2306 { 1u, 23u },
2307 { 33u, 1207623u }
2308 });
2309
2310 sendCounterPacket.SetReadyToRead();
2311
2312 sendCounterPacket.Stop();
2313
2314 // The buffer is read by the send thread so it should not be in the readable buffer.
2315 auto readBuffer = bufferManager.GetReadableBuffer();
2316 BOOST_TEST(!readBuffer);
2317
2318 // Successfully reserved the buffer with requested size
2319 unsigned int reservedSize = 0;
2320 auto reservedBuffer = bufferManager.Reserve(512, reservedSize);
2321 BOOST_TEST(reservedSize == 512);
2322 BOOST_TEST(reservedBuffer.get());
2323
2324 // Check that data was actually written to the profiling connection in any order
Matteo Martincighd0613b52019-10-09 16:47:04 +01002325 const std::vector<uint32_t> writtenData = mockProfilingConnection.GetWrittenData();
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002326 BOOST_TEST(writtenData.size() == 3);
2327 bool foundStreamMetaDataPacket =
2328 std::find(writtenData.begin(), writtenData.end(), streamMetadataPacketsize) != writtenData.end();
2329 bool foundCounterDirectoryPacket = std::find(writtenData.begin(), writtenData.end(), 32) != writtenData.end();
2330 bool foundPeriodicCounterCapturePacket = std::find(writtenData.begin(), writtenData.end(), 28) != writtenData.end();
2331 BOOST_TEST(foundStreamMetaDataPacket);
2332 BOOST_TEST(foundCounterDirectoryPacket);
2333 BOOST_TEST(foundPeriodicCounterCapturePacket);
2334}
2335
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002336BOOST_AUTO_TEST_CASE(SendThreadSendStreamMetadataPacket1)
2337{
2338 ProfilingStateMachine profilingStateMachine;
2339
2340 MockProfilingConnection mockProfilingConnection;
2341 BufferManager bufferManager(3, 1024);
2342 SendCounterPacket sendCounterPacket(profilingStateMachine, bufferManager);
2343 sendCounterPacket.Start(mockProfilingConnection);
2344
2345 // The profiling state is set to "Uninitialized", so the send thread should throw an exception
2346
2347 // Wait a bit to make sure that the send thread is properly started
2348 std::this_thread::sleep_for(std::chrono::milliseconds(100));
2349
2350 BOOST_CHECK_THROW(sendCounterPacket.Stop(), armnn::RuntimeException);
2351}
2352
2353BOOST_AUTO_TEST_CASE(SendThreadSendStreamMetadataPacket2)
2354{
2355 ProfilingStateMachine profilingStateMachine;
2356 SetNotConnectedProfilingState(profilingStateMachine);
2357
2358 MockProfilingConnection mockProfilingConnection;
2359 BufferManager bufferManager(3, 1024);
2360 SendCounterPacket sendCounterPacket(profilingStateMachine, bufferManager);
2361 sendCounterPacket.Start(mockProfilingConnection);
2362
2363 // The profiling state is set to "NotConnected", so the send thread should throw an exception
2364
2365 // Wait a bit to make sure that the send thread is properly started
2366 std::this_thread::sleep_for(std::chrono::milliseconds(100));
2367
2368 BOOST_CHECK_THROW(sendCounterPacket.Stop(), armnn::RuntimeException);
2369}
2370
2371BOOST_AUTO_TEST_CASE(SendThreadSendStreamMetadataPacket3)
2372{
2373 ProfilingStateMachine profilingStateMachine;
2374 SetWaitingForAckProfilingState(profilingStateMachine);
2375
2376 // Calculate the size of a Stream Metadata packet
2377 std::string processName = GetProcessName().substr(0, 60);
2378 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
2379 unsigned int streamMetadataPacketsize = 118 + processNameSize;
2380
2381 MockProfilingConnection mockProfilingConnection;
2382 BufferManager bufferManager(3, 1024);
2383 SendCounterPacket sendCounterPacket(profilingStateMachine, bufferManager);
2384 sendCounterPacket.Start(mockProfilingConnection);
2385
2386 // The profiling state is set to "WaitingForAck", so the send thread should send a Stream Metadata packet
2387
2388 // Wait for a bit to make sure that we get the packet
2389 std::this_thread::sleep_for(std::chrono::milliseconds(100));
2390
2391 BOOST_CHECK_NO_THROW(sendCounterPacket.Stop());
2392
2393 // Check that the buffer contains one Stream Metadata packet
Matteo Martincighd0613b52019-10-09 16:47:04 +01002394 const std::vector<uint32_t> writtenData = mockProfilingConnection.GetWrittenData();
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002395 BOOST_TEST(writtenData.size() == 1);
2396 BOOST_TEST(writtenData[0] == streamMetadataPacketsize);
2397}
2398
2399BOOST_AUTO_TEST_CASE(SendThreadSendStreamMetadataPacket4)
2400{
2401 ProfilingStateMachine profilingStateMachine;
2402 SetWaitingForAckProfilingState(profilingStateMachine);
2403
2404 // Calculate the size of a Stream Metadata packet
2405 std::string processName = GetProcessName().substr(0, 60);
2406 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
2407 unsigned int streamMetadataPacketsize = 118 + processNameSize;
2408
2409 MockProfilingConnection mockProfilingConnection;
2410 BufferManager bufferManager(3, 1024);
2411 SendCounterPacket sendCounterPacket(profilingStateMachine, bufferManager);
2412 sendCounterPacket.Start(mockProfilingConnection);
2413
2414 // The profiling state is set to "WaitingForAck", so the send thread should send a Stream Metadata packet
2415
2416 // Wait for a bit to make sure that we get the packet
2417 std::this_thread::sleep_for(std::chrono::milliseconds(100));
2418
2419 // Check that the profiling state is still "WaitingForAck"
2420 BOOST_TEST((profilingStateMachine.GetCurrentState() == ProfilingState::WaitingForAck));
2421
2422 // Check that the buffer contains one Stream Metadata packet
Matteo Martincighd0613b52019-10-09 16:47:04 +01002423 const std::vector<uint32_t> writtenData = mockProfilingConnection.GetWrittenData();
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002424 BOOST_TEST(writtenData.size() == 1);
2425 BOOST_TEST(writtenData[0] == streamMetadataPacketsize);
2426
2427 mockProfilingConnection.Clear();
2428
2429 // Try triggering a new buffer read
2430 sendCounterPacket.SetReadyToRead();
2431
2432 // Wait for a bit to make sure that we get the packet
2433 std::this_thread::sleep_for(std::chrono::milliseconds(100));
2434
2435 // Check that the profiling state is still "WaitingForAck"
2436 BOOST_TEST((profilingStateMachine.GetCurrentState() == ProfilingState::WaitingForAck));
2437
2438 // Check that the buffer contains one Stream Metadata packet
2439 BOOST_TEST(writtenData.size() == 1);
2440 BOOST_TEST(writtenData[0] == streamMetadataPacketsize);
2441
2442 BOOST_CHECK_NO_THROW(sendCounterPacket.Stop());
2443}
2444
Ferran Balagueraf5c46b2019-08-30 15:49:15 +01002445BOOST_AUTO_TEST_SUITE_END()