blob: cd9cf06e7e64395bf5b243efbd55d142bf57eab0 [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 <BufferManager.hpp>
Sadik Armagan7bbdf9d2019-10-24 10:26:05 +01009#include <CounterDirectory.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
Colm Donelan2ba48d22019-11-29 09:10:59 +000027// A short delay to wait for the thread to process a packet.
28uint16_t constexpr WAIT_UNTIL_READABLE_MS = 100;
29
Matteo Martincigh5d737fb2019-10-07 13:05:13 +010030void SetNotConnectedProfilingState(ProfilingStateMachine& profilingStateMachine)
31{
32 ProfilingState currentState = profilingStateMachine.GetCurrentState();
33 switch (currentState)
34 {
35 case ProfilingState::WaitingForAck:
36 profilingStateMachine.TransitionToState(ProfilingState::Active);
37 case ProfilingState::Uninitialised:
38 case ProfilingState::Active:
39 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
40 case ProfilingState::NotConnected:
41 return;
42 default:
43 BOOST_CHECK_MESSAGE(false, "Invalid profiling state");
44 }
45}
46
47void SetWaitingForAckProfilingState(ProfilingStateMachine& profilingStateMachine)
48{
49 ProfilingState currentState = profilingStateMachine.GetCurrentState();
50 switch (currentState)
51 {
52 case ProfilingState::Uninitialised:
53 case ProfilingState::Active:
54 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
55 case ProfilingState::NotConnected:
56 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
57 case ProfilingState::WaitingForAck:
58 return;
59 default:
60 BOOST_CHECK_MESSAGE(false, "Invalid profiling state");
61 }
62}
63
64void SetActiveProfilingState(ProfilingStateMachine& profilingStateMachine)
65{
66 ProfilingState currentState = profilingStateMachine.GetCurrentState();
67 switch (currentState)
68 {
69 case ProfilingState::Uninitialised:
70 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
71 case ProfilingState::NotConnected:
72 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
73 case ProfilingState::WaitingForAck:
74 profilingStateMachine.TransitionToState(ProfilingState::Active);
75 case ProfilingState::Active:
76 return;
77 default:
78 BOOST_CHECK_MESSAGE(false, "Invalid profiling state");
79 }
80}
81
82} // Anonymous namespace
83
Ferran Balagueraf5c46b2019-08-30 15:49:15 +010084BOOST_AUTO_TEST_SUITE(SendCounterPacketTests)
85
Ferran Balagueraf5c46b2019-08-30 15:49:15 +010086BOOST_AUTO_TEST_CASE(MockSendCounterPacketTest)
87{
Narumol Prangnawarat404b2752019-09-24 17:23:16 +010088 MockBufferManager mockBuffer(512);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +010089 MockSendCounterPacket mockSendCounterPacket(mockBuffer);
Ferran Balagueraf5c46b2019-08-30 15:49:15 +010090
Matteo Martincigh5d737fb2019-10-07 13:05:13 +010091 mockSendCounterPacket.SendStreamMetaDataPacket();
Narumol Prangnawarat404b2752019-09-24 17:23:16 +010092
93 auto packetBuffer = mockBuffer.GetReadableBuffer();
94 const char* buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
Ferran Balagueraf5c46b2019-08-30 15:49:15 +010095
96 BOOST_TEST(strcmp(buffer, "SendStreamMetaDataPacket") == 0);
97
Narumol Prangnawarat404b2752019-09-24 17:23:16 +010098 mockBuffer.MarkRead(packetBuffer);
99
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100100 CounterDirectory counterDirectory;
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100101 mockSendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100102
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100103 packetBuffer = mockBuffer.GetReadableBuffer();
104 buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
105
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100106 BOOST_TEST(strcmp(buffer, "SendCounterDirectoryPacket") == 0);
107
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100108 mockBuffer.MarkRead(packetBuffer);
109
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100110 uint64_t timestamp = 0;
Francis Murtagh3a161982019-09-04 15:25:02 +0100111 std::vector<std::pair<uint16_t, uint32_t>> indexValuePairs;
112
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100113 mockSendCounterPacket.SendPeriodicCounterCapturePacket(timestamp, indexValuePairs);
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100114
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100115 packetBuffer = mockBuffer.GetReadableBuffer();
116 buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
117
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100118 BOOST_TEST(strcmp(buffer, "SendPeriodicCounterCapturePacket") == 0);
119
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100120 mockBuffer.MarkRead(packetBuffer);
121
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100122 uint32_t capturePeriod = 0;
123 std::vector<uint16_t> selectedCounterIds;
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100124 mockSendCounterPacket.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds);
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100125
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100126 packetBuffer = mockBuffer.GetReadableBuffer();
127 buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
128
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100129 BOOST_TEST(strcmp(buffer, "SendPeriodicCounterSelectionPacket") == 0);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100130
131 mockBuffer.MarkRead(packetBuffer);
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100132}
133
Ferran Balaguer73882172019-09-02 16:39:42 +0100134BOOST_AUTO_TEST_CASE(SendPeriodicCounterSelectionPacketTest)
135{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100136 ProfilingStateMachine profilingStateMachine;
137
Ferran Balaguer73882172019-09-02 16:39:42 +0100138 // Error no space left in buffer
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100139 MockBufferManager mockBuffer1(10);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100140 SendCounterPacket sendPacket1(profilingStateMachine, mockBuffer1);
Ferran Balaguer73882172019-09-02 16:39:42 +0100141
142 uint32_t capturePeriod = 1000;
143 std::vector<uint16_t> selectedCounterIds;
144 BOOST_CHECK_THROW(sendPacket1.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds),
Matteo Martincigh24e8f922019-09-19 11:57:46 +0100145 BufferExhaustion);
Ferran Balaguer73882172019-09-02 16:39:42 +0100146
147 // Packet without any counters
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100148 MockBufferManager mockBuffer2(512);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100149 SendCounterPacket sendPacket2(profilingStateMachine, mockBuffer2);
Ferran Balaguer73882172019-09-02 16:39:42 +0100150
151 sendPacket2.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100152 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
Ferran Balaguer73882172019-09-02 16:39:42 +0100153
154 uint32_t headerWord0 = ReadUint32(readBuffer2, 0);
155 uint32_t headerWord1 = ReadUint32(readBuffer2, 4);
156 uint32_t period = ReadUint32(readBuffer2, 8);
157
158 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
159 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
160 BOOST_TEST(headerWord1 == 4); // data lenght
161 BOOST_TEST(period == 1000); // capture period
162
163 // Full packet message
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100164 MockBufferManager mockBuffer3(512);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100165 SendCounterPacket sendPacket3(profilingStateMachine, mockBuffer3);
Ferran Balaguer73882172019-09-02 16:39:42 +0100166
167 selectedCounterIds.reserve(5);
168 selectedCounterIds.emplace_back(100);
169 selectedCounterIds.emplace_back(200);
170 selectedCounterIds.emplace_back(300);
171 selectedCounterIds.emplace_back(400);
172 selectedCounterIds.emplace_back(500);
173 sendPacket3.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100174 auto readBuffer3 = mockBuffer3.GetReadableBuffer();
Ferran Balaguer73882172019-09-02 16:39:42 +0100175
176 headerWord0 = ReadUint32(readBuffer3, 0);
177 headerWord1 = ReadUint32(readBuffer3, 4);
178 period = ReadUint32(readBuffer3, 8);
179
180 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
181 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
182 BOOST_TEST(headerWord1 == 14); // data lenght
183 BOOST_TEST(period == 1000); // capture period
184
185 uint16_t counterId = 0;
186 uint32_t offset = 12;
187
188 // Counter Ids
189 for(const uint16_t& id : selectedCounterIds)
190 {
191 counterId = ReadUint16(readBuffer3, offset);
192 BOOST_TEST(counterId == id);
193 offset += 2;
194 }
195}
196
Francis Murtagh3a161982019-09-04 15:25:02 +0100197BOOST_AUTO_TEST_CASE(SendPeriodicCounterCapturePacketTest)
198{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100199 ProfilingStateMachine profilingStateMachine;
200
Francis Murtagh3a161982019-09-04 15:25:02 +0100201 // Error no space left in buffer
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100202 MockBufferManager mockBuffer1(10);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100203 SendCounterPacket sendPacket1(profilingStateMachine, mockBuffer1);
Francis Murtagh3a161982019-09-04 15:25:02 +0100204
205 auto captureTimestamp = std::chrono::steady_clock::now();
206 uint64_t time = static_cast<uint64_t >(captureTimestamp.time_since_epoch().count());
207 std::vector<std::pair<uint16_t, uint32_t>> indexValuePairs;
208
209 BOOST_CHECK_THROW(sendPacket1.SendPeriodicCounterCapturePacket(time, indexValuePairs),
210 BufferExhaustion);
211
212 // Packet without any counters
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100213 MockBufferManager mockBuffer2(512);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100214 SendCounterPacket sendPacket2(profilingStateMachine, mockBuffer2);
Francis Murtagh3a161982019-09-04 15:25:02 +0100215
216 sendPacket2.SendPeriodicCounterCapturePacket(time, indexValuePairs);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100217 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
Francis Murtagh3a161982019-09-04 15:25:02 +0100218
219 uint32_t headerWord0 = ReadUint32(readBuffer2, 0);
220 uint32_t headerWord1 = ReadUint32(readBuffer2, 4);
221 uint64_t readTimestamp = ReadUint64(readBuffer2, 8);
222
Jim Flynnfc365622019-12-04 10:07:20 +0000223 BOOST_TEST(((headerWord0 >> 26) & 0x0000003F) == 3); // packet family
Matteo Martincigh8d9590e2019-10-15 09:35:29 +0100224 BOOST_TEST(((headerWord0 >> 19) & 0x0000007F) == 0); // packet class
225 BOOST_TEST(((headerWord0 >> 16) & 0x00000007) == 0); // packet type
226 BOOST_TEST(headerWord1 == 8); // data length
227 BOOST_TEST(time == readTimestamp); // capture period
Francis Murtagh3a161982019-09-04 15:25:02 +0100228
229 // Full packet message
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100230 MockBufferManager mockBuffer3(512);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100231 SendCounterPacket sendPacket3(profilingStateMachine, mockBuffer3);
Francis Murtagh3a161982019-09-04 15:25:02 +0100232
233 indexValuePairs.reserve(5);
234 indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t >(0, 100));
235 indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t >(1, 200));
236 indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t >(2, 300));
237 indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t >(3, 400));
238 indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t >(4, 500));
239 sendPacket3.SendPeriodicCounterCapturePacket(time, indexValuePairs);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100240 auto readBuffer3 = mockBuffer3.GetReadableBuffer();
Francis Murtagh3a161982019-09-04 15:25:02 +0100241
242 headerWord0 = ReadUint32(readBuffer3, 0);
243 headerWord1 = ReadUint32(readBuffer3, 4);
244 uint64_t readTimestamp2 = ReadUint64(readBuffer3, 8);
245
Jim Flynnfc365622019-12-04 10:07:20 +0000246 BOOST_TEST(((headerWord0 >> 26) & 0x0000003F) == 3); // packet family
Matteo Martincigh8d9590e2019-10-15 09:35:29 +0100247 BOOST_TEST(((headerWord0 >> 19) & 0x0000007F) == 0); // packet class
248 BOOST_TEST(((headerWord0 >> 16) & 0x00000007) == 0); // packet type
249 BOOST_TEST(headerWord1 == 38); // data length
250 BOOST_TEST(time == readTimestamp2); // capture period
Francis Murtagh3a161982019-09-04 15:25:02 +0100251
252 uint16_t counterIndex = 0;
253 uint32_t counterValue = 100;
254 uint32_t offset = 16;
255
256 // Counter Ids
257 for (auto it = indexValuePairs.begin(), end = indexValuePairs.end(); it != end; ++it)
258 {
259 // Check Counter Index
260 uint16_t readIndex = ReadUint16(readBuffer3, offset);
261 BOOST_TEST(counterIndex == readIndex);
262 counterIndex++;
263 offset += 2;
264
265 // Check Counter Value
266 uint32_t readValue = ReadUint32(readBuffer3, offset);
267 BOOST_TEST(counterValue == readValue);
268 counterValue += 100;
269 offset += 4;
270 }
271
272}
273
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100274BOOST_AUTO_TEST_CASE(SendStreamMetaDataPacketTest)
275{
276 using boost::numeric_cast;
277
278 uint32_t sizeUint32 = numeric_cast<uint32_t>(sizeof(uint32_t));
279
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100280 ProfilingStateMachine profilingStateMachine;
281
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100282 // Error no space left in buffer
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100283 MockBufferManager mockBuffer1(10);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100284 SendCounterPacket sendPacket1(profilingStateMachine, mockBuffer1);
Matteo Martincigh149528e2019-09-05 12:02:04 +0100285 BOOST_CHECK_THROW(sendPacket1.SendStreamMetaDataPacket(), armnn::profiling::BufferExhaustion);
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100286
287 // Full metadata packet
288
289 std::string processName = GetProcessName().substr(0, 60);
290
291 uint32_t infoSize = numeric_cast<uint32_t>(GetSoftwareInfo().size()) > 0 ?
292 numeric_cast<uint32_t>(GetSoftwareInfo().size()) + 1 : 0;
293 uint32_t hardwareVersionSize = numeric_cast<uint32_t>(GetHardwareVersion().size()) > 0 ?
294 numeric_cast<uint32_t>(GetHardwareVersion().size()) + 1 : 0;
295 uint32_t softwareVersionSize = numeric_cast<uint32_t>(GetSoftwareVersion().size()) > 0 ?
296 numeric_cast<uint32_t>(GetSoftwareVersion().size()) + 1 : 0;
297 uint32_t processNameSize = numeric_cast<uint32_t>(processName.size()) > 0 ?
298 numeric_cast<uint32_t>(processName.size()) + 1 : 0;
299
Ferran Balaguer5bf1d322019-09-13 13:31:40 +0100300 uint32_t packetEntries = 6;
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100301
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100302 MockBufferManager mockBuffer2(512);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100303 SendCounterPacket sendPacket2(profilingStateMachine, mockBuffer2);
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100304 sendPacket2.SendStreamMetaDataPacket();
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100305 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100306
307 uint32_t headerWord0 = ReadUint32(readBuffer2, 0);
308 uint32_t headerWord1 = ReadUint32(readBuffer2, sizeUint32);
309
310 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
311 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 0); // packet id
312
313 uint32_t totalLength = numeric_cast<uint32_t>(2 * sizeUint32 + 10 * sizeUint32 + infoSize + hardwareVersionSize +
314 softwareVersionSize + processNameSize + sizeUint32 +
315 2 * packetEntries * sizeUint32);
316
317 BOOST_TEST(headerWord1 == totalLength - (2 * sizeUint32)); // data length
318
319 uint32_t offset = sizeUint32 * 2;
320 BOOST_TEST(ReadUint32(readBuffer2, offset) == SendCounterPacket::PIPE_MAGIC); // pipe_magic
321 offset += sizeUint32;
322 BOOST_TEST(ReadUint32(readBuffer2, offset) == EncodeVersion(1, 0, 0)); // stream_metadata_version
323 offset += sizeUint32;
Sadik Armagan7bbdf9d2019-10-24 10:26:05 +0100324 BOOST_TEST(ReadUint32(readBuffer2, offset) == MAX_METADATA_PACKET_LENGTH); // max_data_len
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100325 offset += sizeUint32;
326 BOOST_TEST(ReadUint32(readBuffer2, offset) == numeric_cast<uint32_t>(getpid())); // pid
327 offset += sizeUint32;
328 uint32_t poolOffset = 10 * sizeUint32;
329 BOOST_TEST(ReadUint32(readBuffer2, offset) == (infoSize ? poolOffset : 0)); // offset_info
330 offset += sizeUint32;
331 poolOffset += infoSize;
332 BOOST_TEST(ReadUint32(readBuffer2, offset) == (hardwareVersionSize ? poolOffset : 0)); // offset_hw_version
333 offset += sizeUint32;
334 poolOffset += hardwareVersionSize;
335 BOOST_TEST(ReadUint32(readBuffer2, offset) == (softwareVersionSize ? poolOffset : 0)); // offset_sw_version
336 offset += sizeUint32;
337 poolOffset += softwareVersionSize;
338 BOOST_TEST(ReadUint32(readBuffer2, offset) == (processNameSize ? poolOffset : 0)); // offset_process_name
339 offset += sizeUint32;
340 poolOffset += processNameSize;
341 BOOST_TEST(ReadUint32(readBuffer2, offset) == (packetEntries ? poolOffset : 0)); // offset_packet_version_table
342 offset += sizeUint32;
343 BOOST_TEST(ReadUint32(readBuffer2, offset) == 0); // reserved
344
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100345 const unsigned char* readData2 = readBuffer2->GetReadableData();
346
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100347 offset += sizeUint32;
348 if (infoSize)
349 {
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100350 BOOST_TEST(strcmp(reinterpret_cast<const char *>(&readData2[offset]), GetSoftwareInfo().c_str()) == 0);
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100351 offset += infoSize;
352 }
353
354 if (hardwareVersionSize)
355 {
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100356 BOOST_TEST(strcmp(reinterpret_cast<const char *>(&readData2[offset]), GetHardwareVersion().c_str()) == 0);
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100357 offset += hardwareVersionSize;
358 }
359
360 if (softwareVersionSize)
361 {
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100362 BOOST_TEST(strcmp(reinterpret_cast<const char *>(&readData2[offset]), GetSoftwareVersion().c_str()) == 0);
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100363 offset += softwareVersionSize;
364 }
365
366 if (processNameSize)
367 {
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100368 BOOST_TEST(strcmp(reinterpret_cast<const char *>(&readData2[offset]), GetProcessName().c_str()) == 0);
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100369 offset += processNameSize;
370 }
371
372 if (packetEntries)
373 {
374 BOOST_TEST((ReadUint32(readBuffer2, offset) >> 16) == packetEntries);
375 offset += sizeUint32;
Ferran Balaguer5bf1d322019-09-13 13:31:40 +0100376 for (uint32_t i = 0; i < packetEntries - 1; ++i)
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100377 {
378 BOOST_TEST(((ReadUint32(readBuffer2, offset) >> 26) & 0x3F) == 0);
379 BOOST_TEST(((ReadUint32(readBuffer2, offset) >> 16) & 0x3FF) == i);
380 offset += sizeUint32;
381 BOOST_TEST(ReadUint32(readBuffer2, offset) == EncodeVersion(1, 0, 0));
382 offset += sizeUint32;
383 }
Ferran Balaguer5bf1d322019-09-13 13:31:40 +0100384
385 BOOST_TEST(((ReadUint32(readBuffer2, offset) >> 26) & 0x3F) == 1);
386 BOOST_TEST(((ReadUint32(readBuffer2, offset) >> 16) & 0x3FF) == 0);
387 offset += sizeUint32;
388 BOOST_TEST(ReadUint32(readBuffer2, offset) == EncodeVersion(1, 0, 0));
389 offset += sizeUint32;
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100390 }
391
392 BOOST_TEST(offset == totalLength);
393}
394
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100395BOOST_AUTO_TEST_CASE(CreateDeviceRecordTest)
396{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100397 ProfilingStateMachine profilingStateMachine;
398
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100399 MockBufferManager mockBuffer(0);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100400 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100401
402 // Create a device for testing
403 uint16_t deviceUid = 27;
404 const std::string deviceName = "some_device";
405 uint16_t deviceCores = 3;
406 const DevicePtr device = std::make_unique<Device>(deviceUid, deviceName, deviceCores);
407
408 // Create a device record
409 SendCounterPacket::DeviceRecord deviceRecord;
410 std::string errorMessage;
411 bool result = sendCounterPacketTest.CreateDeviceRecordTest(device, deviceRecord, errorMessage);
412
413 BOOST_CHECK(result);
414 BOOST_CHECK(errorMessage.empty());
415 BOOST_CHECK(deviceRecord.size() == 6); // Size in words: header [2] + device name [4]
416
417 uint16_t deviceRecordWord0[]
418 {
419 static_cast<uint16_t>(deviceRecord[0] >> 16),
420 static_cast<uint16_t>(deviceRecord[0])
421 };
422 BOOST_CHECK(deviceRecordWord0[0] == deviceUid); // uid
423 BOOST_CHECK(deviceRecordWord0[1] == deviceCores); // cores
424 BOOST_CHECK(deviceRecord[1] == 0); // name_offset
425 BOOST_CHECK(deviceRecord[2] == deviceName.size() + 1); // The length of the SWTrace string (name)
426 BOOST_CHECK(std::memcmp(deviceRecord.data() + 3, deviceName.data(), deviceName.size()) == 0); // name
427}
428
429BOOST_AUTO_TEST_CASE(CreateInvalidDeviceRecordTest)
430{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100431 ProfilingStateMachine profilingStateMachine;
432
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100433 MockBufferManager mockBuffer(0);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100434 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100435
436 // Create a device for testing
437 uint16_t deviceUid = 27;
438 const std::string deviceName = "some€£invalid‡device";
439 uint16_t deviceCores = 3;
440 const DevicePtr device = std::make_unique<Device>(deviceUid, deviceName, deviceCores);
441
442 // Create a device record
443 SendCounterPacket::DeviceRecord deviceRecord;
444 std::string errorMessage;
445 bool result = sendCounterPacketTest.CreateDeviceRecordTest(device, deviceRecord, errorMessage);
446
447 BOOST_CHECK(!result);
448 BOOST_CHECK(!errorMessage.empty());
449 BOOST_CHECK(deviceRecord.empty());
450}
451
452BOOST_AUTO_TEST_CASE(CreateCounterSetRecordTest)
453{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100454 ProfilingStateMachine profilingStateMachine;
455
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100456 MockBufferManager mockBuffer(0);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100457 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100458
459 // Create a counter set for testing
460 uint16_t counterSetUid = 27;
461 const std::string counterSetName = "some_counter_set";
462 uint16_t counterSetCount = 3421;
463 const CounterSetPtr counterSet = std::make_unique<CounterSet>(counterSetUid, counterSetName, counterSetCount);
464
465 // Create a counter set record
466 SendCounterPacket::CounterSetRecord counterSetRecord;
467 std::string errorMessage;
468 bool result = sendCounterPacketTest.CreateCounterSetRecordTest(counterSet, counterSetRecord, errorMessage);
469
470 BOOST_CHECK(result);
471 BOOST_CHECK(errorMessage.empty());
472 BOOST_CHECK(counterSetRecord.size() == 8); // Size in words: header [2] + counter set name [6]
473
474 uint16_t counterSetRecordWord0[]
475 {
476 static_cast<uint16_t>(counterSetRecord[0] >> 16),
477 static_cast<uint16_t>(counterSetRecord[0])
478 };
479 BOOST_CHECK(counterSetRecordWord0[0] == counterSetUid); // uid
480 BOOST_CHECK(counterSetRecordWord0[1] == counterSetCount); // cores
481 BOOST_CHECK(counterSetRecord[1] == 0); // name_offset
482 BOOST_CHECK(counterSetRecord[2] == counterSetName.size() + 1); // The length of the SWTrace string (name)
483 BOOST_CHECK(std::memcmp(counterSetRecord.data() + 3, counterSetName.data(), counterSetName.size()) == 0); // name
484}
485
486BOOST_AUTO_TEST_CASE(CreateInvalidCounterSetRecordTest)
487{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100488 ProfilingStateMachine profilingStateMachine;
489
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100490 MockBufferManager mockBuffer(0);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100491 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100492
493 // Create a counter set for testing
494 uint16_t counterSetUid = 27;
495 const std::string counterSetName = "some invalid_counter€£set";
496 uint16_t counterSetCount = 3421;
497 const CounterSetPtr counterSet = std::make_unique<CounterSet>(counterSetUid, counterSetName, counterSetCount);
498
499 // Create a counter set record
500 SendCounterPacket::CounterSetRecord counterSetRecord;
501 std::string errorMessage;
502 bool result = sendCounterPacketTest.CreateCounterSetRecordTest(counterSet, counterSetRecord, errorMessage);
503
504 BOOST_CHECK(!result);
505 BOOST_CHECK(!errorMessage.empty());
506 BOOST_CHECK(counterSetRecord.empty());
507}
508
509BOOST_AUTO_TEST_CASE(CreateEventRecordTest)
510{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100511 ProfilingStateMachine profilingStateMachine;
512
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100513 MockBufferManager mockBuffer(0);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100514 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100515
516 // Create a counter for testing
517 uint16_t counterUid = 7256;
518 uint16_t maxCounterUid = 132;
519 uint16_t deviceUid = 132;
520 uint16_t counterSetUid = 4497;
521 uint16_t counterClass = 1;
522 uint16_t counterInterpolation = 1;
523 double counterMultiplier = 1234.567f;
524 const std::string counterName = "some_valid_counter";
525 const std::string counterDescription = "a_counter_for_testing";
526 const std::string counterUnits = "Mrads2";
527 const CounterPtr counter = std::make_unique<Counter>(counterUid,
528 maxCounterUid,
529 counterClass,
530 counterInterpolation,
531 counterMultiplier,
532 counterName,
533 counterDescription,
534 counterUnits,
535 deviceUid,
536 counterSetUid);
537 BOOST_ASSERT(counter);
538
539 // Create an event record
540 SendCounterPacket::EventRecord eventRecord;
541 std::string errorMessage;
542 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
543
544 BOOST_CHECK(result);
545 BOOST_CHECK(errorMessage.empty());
546 BOOST_CHECK(eventRecord.size() == 24); // Size in words: header [8] + counter name [6] + description [7] + units [3]
547
548 uint16_t eventRecordWord0[]
549 {
550 static_cast<uint16_t>(eventRecord[0] >> 16),
551 static_cast<uint16_t>(eventRecord[0])
552 };
553 uint16_t eventRecordWord1[]
554 {
555 static_cast<uint16_t>(eventRecord[1] >> 16),
556 static_cast<uint16_t>(eventRecord[1])
557 };
558 uint16_t eventRecordWord2[]
559 {
560 static_cast<uint16_t>(eventRecord[2] >> 16),
561 static_cast<uint16_t>(eventRecord[2])
562 };
563 uint32_t eventRecordWord34[]
564 {
565 eventRecord[3],
566 eventRecord[4]
567 };
568 BOOST_CHECK(eventRecordWord0[0] == maxCounterUid); // max_counter_uid
569 BOOST_CHECK(eventRecordWord0[1] == counterUid); // counter_uid
570 BOOST_CHECK(eventRecordWord1[0] == deviceUid); // device
571 BOOST_CHECK(eventRecordWord1[1] == counterSetUid); // counter_set
572 BOOST_CHECK(eventRecordWord2[0] == counterClass); // class
573 BOOST_CHECK(eventRecordWord2[1] == counterInterpolation); // interpolation
574 BOOST_CHECK(std::memcmp(eventRecordWord34, &counterMultiplier, sizeof(counterMultiplier)) == 0); // multiplier
575
576 ARMNN_NO_CONVERSION_WARN_BEGIN
577 uint32_t counterNameOffset = 0; // The name is the first item in pool
578 uint32_t counterDescriptionOffset = counterNameOffset + // Counter name offset
579 4u + // Counter name length (uint32_t)
580 counterName.size() + // 18u
581 1u + // Null-terminator
582 1u; // Rounding to the next word
583 size_t counterUnitsOffset = counterDescriptionOffset + // Counter description offset
584 4u + // Counter description length (uint32_t)
585 counterDescription.size() + // 21u
586 1u + // Null-terminator
587 2u; // Rounding to the next word
588 ARMNN_NO_CONVERSION_WARN_END
589
590 BOOST_CHECK(eventRecord[5] == counterNameOffset); // name_offset
591 BOOST_CHECK(eventRecord[6] == counterDescriptionOffset); // description_offset
592 BOOST_CHECK(eventRecord[7] == counterUnitsOffset); // units_offset
593
594 auto eventRecordPool = reinterpret_cast<unsigned char*>(eventRecord.data() + 8u); // The start of the pool
595 size_t uint32_t_size = sizeof(uint32_t);
596
597 // The length of the SWTrace string (name)
598 BOOST_CHECK(eventRecordPool[counterNameOffset] == counterName.size() + 1);
599 // The counter name
600 BOOST_CHECK(std::memcmp(eventRecordPool +
601 counterNameOffset + // Offset
602 uint32_t_size /* The length of the name */,
603 counterName.data(),
604 counterName.size()) == 0); // name
605 // The null-terminator at the end of the name
606 BOOST_CHECK(eventRecordPool[counterNameOffset + uint32_t_size + counterName.size()] == '\0');
607
608 // The length of the SWTrace string (description)
609 BOOST_CHECK(eventRecordPool[counterDescriptionOffset] == counterDescription.size() + 1);
610 // The counter description
611 BOOST_CHECK(std::memcmp(eventRecordPool +
612 counterDescriptionOffset + // Offset
613 uint32_t_size /* The length of the description */,
614 counterDescription.data(),
615 counterDescription.size()) == 0); // description
616 // The null-terminator at the end of the description
617 BOOST_CHECK(eventRecordPool[counterDescriptionOffset + uint32_t_size + counterDescription.size()] == '\0');
618
619 // The length of the SWTrace namestring (units)
620 BOOST_CHECK(eventRecordPool[counterUnitsOffset] == counterUnits.size() + 1);
621 // The counter units
622 BOOST_CHECK(std::memcmp(eventRecordPool +
623 counterUnitsOffset + // Offset
624 uint32_t_size /* The length of the units */,
625 counterUnits.data(),
626 counterUnits.size()) == 0); // units
627 // The null-terminator at the end of the units
628 BOOST_CHECK(eventRecordPool[counterUnitsOffset + uint32_t_size + counterUnits.size()] == '\0');
629}
630
631BOOST_AUTO_TEST_CASE(CreateEventRecordNoUnitsTest)
632{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100633 ProfilingStateMachine profilingStateMachine;
634
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100635 MockBufferManager mockBuffer(0);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100636 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100637
638 // Create a counter for testing
639 uint16_t counterUid = 44312;
640 uint16_t maxCounterUid = 345;
641 uint16_t deviceUid = 101;
642 uint16_t counterSetUid = 34035;
643 uint16_t counterClass = 0;
644 uint16_t counterInterpolation = 1;
645 double counterMultiplier = 4435.0023f;
646 const std::string counterName = "some_valid_counter";
647 const std::string counterDescription = "a_counter_for_testing";
648 const CounterPtr counter = std::make_unique<Counter>(counterUid,
649 maxCounterUid,
650 counterClass,
651 counterInterpolation,
652 counterMultiplier,
653 counterName,
654 counterDescription,
655 "",
656 deviceUid,
657 counterSetUid);
658 BOOST_ASSERT(counter);
659
660 // Create an event record
661 SendCounterPacket::EventRecord eventRecord;
662 std::string errorMessage;
663 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
664
665 BOOST_CHECK(result);
666 BOOST_CHECK(errorMessage.empty());
667 BOOST_CHECK(eventRecord.size() == 21); // Size in words: header [8] + counter name [6] + description [7]
668
669 uint16_t eventRecordWord0[]
670 {
671 static_cast<uint16_t>(eventRecord[0] >> 16),
672 static_cast<uint16_t>(eventRecord[0])
673 };
674 uint16_t eventRecordWord1[]
675 {
676 static_cast<uint16_t>(eventRecord[1] >> 16),
677 static_cast<uint16_t>(eventRecord[1])
678 };
679 uint16_t eventRecordWord2[]
680 {
681 static_cast<uint16_t>(eventRecord[2] >> 16),
682 static_cast<uint16_t>(eventRecord[2])
683 };
684 uint32_t eventRecordWord34[]
685 {
686 eventRecord[3],
687 eventRecord[4]
688 };
689 BOOST_CHECK(eventRecordWord0[0] == maxCounterUid); // max_counter_uid
690 BOOST_CHECK(eventRecordWord0[1] == counterUid); // counter_uid
691 BOOST_CHECK(eventRecordWord1[0] == deviceUid); // device
692 BOOST_CHECK(eventRecordWord1[1] == counterSetUid); // counter_set
693 BOOST_CHECK(eventRecordWord2[0] == counterClass); // class
694 BOOST_CHECK(eventRecordWord2[1] == counterInterpolation); // interpolation
695 BOOST_CHECK(std::memcmp(eventRecordWord34, &counterMultiplier, sizeof(counterMultiplier)) == 0); // multiplier
696
697 ARMNN_NO_CONVERSION_WARN_BEGIN
698 uint32_t counterNameOffset = 0; // The name is the first item in pool
699 uint32_t counterDescriptionOffset = counterNameOffset + // Counter name offset
700 4u + // Counter name length (uint32_t)
701 counterName.size() + // 18u
702 1u + // Null-terminator
703 1u; // Rounding to the next word
704 ARMNN_NO_CONVERSION_WARN_END
705
706 BOOST_CHECK(eventRecord[5] == counterNameOffset); // name_offset
707 BOOST_CHECK(eventRecord[6] == counterDescriptionOffset); // description_offset
708 BOOST_CHECK(eventRecord[7] == 0); // units_offset
709
710 auto eventRecordPool = reinterpret_cast<unsigned char*>(eventRecord.data() + 8u); // The start of the pool
711 size_t uint32_t_size = sizeof(uint32_t);
712
713 // The length of the SWTrace string (name)
714 BOOST_CHECK(eventRecordPool[counterNameOffset] == counterName.size() + 1);
715 // The counter name
716 BOOST_CHECK(std::memcmp(eventRecordPool +
717 counterNameOffset + // Offset
718 uint32_t_size, // The length of the name
719 counterName.data(),
720 counterName.size()) == 0); // name
721 // The null-terminator at the end of the name
722 BOOST_CHECK(eventRecordPool[counterNameOffset + uint32_t_size + counterName.size()] == '\0');
723
724 // The length of the SWTrace string (description)
725 BOOST_CHECK(eventRecordPool[counterDescriptionOffset] == counterDescription.size() + 1);
726 // The counter description
727 BOOST_CHECK(std::memcmp(eventRecordPool +
728 counterDescriptionOffset + // Offset
729 uint32_t_size, // The length of the description
730 counterDescription.data(),
731 counterDescription.size()) == 0); // description
732 // The null-terminator at the end of the description
733 BOOST_CHECK(eventRecordPool[counterDescriptionOffset + uint32_t_size + counterDescription.size()] == '\0');
734}
735
736BOOST_AUTO_TEST_CASE(CreateInvalidEventRecordTest1)
737{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100738 ProfilingStateMachine profilingStateMachine;
739
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100740 MockBufferManager mockBuffer(0);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100741 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100742
743 // Create a counter for testing
744 uint16_t counterUid = 7256;
745 uint16_t maxCounterUid = 132;
746 uint16_t deviceUid = 132;
747 uint16_t counterSetUid = 4497;
748 uint16_t counterClass = 1;
749 uint16_t counterInterpolation = 1;
750 double counterMultiplier = 1234.567f;
751 const std::string counterName = "some_invalid_counter £££"; // Invalid name
752 const std::string counterDescription = "a_counter_for_testing";
753 const std::string counterUnits = "Mrads2";
754 const CounterPtr counter = std::make_unique<Counter>(counterUid,
755 maxCounterUid,
756 counterClass,
757 counterInterpolation,
758 counterMultiplier,
759 counterName,
760 counterDescription,
761 counterUnits,
762 deviceUid,
763 counterSetUid);
764 BOOST_ASSERT(counter);
765
766 // Create an event record
767 SendCounterPacket::EventRecord eventRecord;
768 std::string errorMessage;
769 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
770
771 BOOST_CHECK(!result);
772 BOOST_CHECK(!errorMessage.empty());
773 BOOST_CHECK(eventRecord.empty());
774}
775
776BOOST_AUTO_TEST_CASE(CreateInvalidEventRecordTest2)
777{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100778 ProfilingStateMachine profilingStateMachine;
779
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100780 MockBufferManager mockBuffer(0);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100781 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100782
783 // Create a counter for testing
784 uint16_t counterUid = 7256;
785 uint16_t maxCounterUid = 132;
786 uint16_t deviceUid = 132;
787 uint16_t counterSetUid = 4497;
788 uint16_t counterClass = 1;
789 uint16_t counterInterpolation = 1;
790 double counterMultiplier = 1234.567f;
791 const std::string counterName = "some_invalid_counter";
792 const std::string counterDescription = "an invalid d€scription"; // Invalid description
793 const std::string counterUnits = "Mrads2";
794 const CounterPtr counter = std::make_unique<Counter>(counterUid,
795 maxCounterUid,
796 counterClass,
797 counterInterpolation,
798 counterMultiplier,
799 counterName,
800 counterDescription,
801 counterUnits,
802 deviceUid,
803 counterSetUid);
804 BOOST_ASSERT(counter);
805
806 // Create an event record
807 SendCounterPacket::EventRecord eventRecord;
808 std::string errorMessage;
809 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
810
811 BOOST_CHECK(!result);
812 BOOST_CHECK(!errorMessage.empty());
813 BOOST_CHECK(eventRecord.empty());
814}
815
816BOOST_AUTO_TEST_CASE(CreateInvalidEventRecordTest3)
817{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100818 ProfilingStateMachine profilingStateMachine;
819
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100820 MockBufferManager mockBuffer(0);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100821 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100822
823 // Create a counter for testing
824 uint16_t counterUid = 7256;
825 uint16_t maxCounterUid = 132;
826 uint16_t deviceUid = 132;
827 uint16_t counterSetUid = 4497;
828 uint16_t counterClass = 1;
829 uint16_t counterInterpolation = 1;
830 double counterMultiplier = 1234.567f;
831 const std::string counterName = "some_invalid_counter";
832 const std::string counterDescription = "a valid description";
833 const std::string counterUnits = "Mrad s2"; // Invalid units
834 const CounterPtr counter = std::make_unique<Counter>(counterUid,
835 maxCounterUid,
836 counterClass,
837 counterInterpolation,
838 counterMultiplier,
839 counterName,
840 counterDescription,
841 counterUnits,
842 deviceUid,
843 counterSetUid);
844 BOOST_ASSERT(counter);
845
846 // Create an event record
847 SendCounterPacket::EventRecord eventRecord;
848 std::string errorMessage;
849 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
850
851 BOOST_CHECK(!result);
852 BOOST_CHECK(!errorMessage.empty());
853 BOOST_CHECK(eventRecord.empty());
854}
855
856BOOST_AUTO_TEST_CASE(CreateCategoryRecordTest)
857{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100858 ProfilingStateMachine profilingStateMachine;
859
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100860 MockBufferManager mockBuffer(0);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100861 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100862
863 // Create a category for testing
864 const std::string categoryName = "some_category";
865 uint16_t deviceUid = 1302;
866 uint16_t counterSetUid = 20734;
867 const CategoryPtr category = std::make_unique<Category>(categoryName, deviceUid, counterSetUid);
868 BOOST_ASSERT(category);
869 category->m_Counters = { 11u, 23u, 5670u };
870
871 // Create a collection of counters
872 Counters counters;
873 counters.insert(std::make_pair<uint16_t, CounterPtr>(11,
874 CounterPtr(new Counter(11,
875 1234,
876 0,
877 1,
878 534.0003f,
879 "counter1",
880 "the first counter",
881 "millipi2",
882 0,
883 0))));
884 counters.insert(std::make_pair<uint16_t, CounterPtr>(23,
885 CounterPtr(new Counter(23,
886 344,
887 1,
888 1,
889 534.0003f,
890 "this is counter 2",
891 "the second counter",
892 "",
893 0,
894 0))));
895 counters.insert(std::make_pair<uint16_t, CounterPtr>(5670,
896 CounterPtr(new Counter(5670,
897 31,
898 0,
899 0,
900 534.0003f,
901 "and this is number 3",
902 "the third counter",
903 "blah_per_second",
904 0,
905 0))));
906 Counter* counter1 = counters.find(11)->second.get();
907 Counter* counter2 = counters.find(23)->second.get();
908 Counter* counter3 = counters.find(5670)->second.get();
909 BOOST_ASSERT(counter1);
910 BOOST_ASSERT(counter2);
911 BOOST_ASSERT(counter3);
912 uint16_t categoryEventCount = boost::numeric_cast<uint16_t>(counters.size());
913
914 // Create a category record
915 SendCounterPacket::CategoryRecord categoryRecord;
916 std::string errorMessage;
917 bool result = sendCounterPacketTest.CreateCategoryRecordTest(category, counters, categoryRecord, errorMessage);
918
919 BOOST_CHECK(result);
920 BOOST_CHECK(errorMessage.empty());
921 BOOST_CHECK(categoryRecord.size() == 80); // Size in words: header [4] + event pointer table [3] +
922 // category name [5] + event records [68 = 22 + 20 + 26]
923
924 uint16_t categoryRecordWord0[]
925 {
926 static_cast<uint16_t>(categoryRecord[0] >> 16),
927 static_cast<uint16_t>(categoryRecord[0])
928 };
929 uint16_t categoryRecordWord1[]
930 {
931 static_cast<uint16_t>(categoryRecord[1] >> 16),
932 static_cast<uint16_t>(categoryRecord[1])
933 };
934 BOOST_CHECK(categoryRecordWord0[0] == deviceUid); // device
935 BOOST_CHECK(categoryRecordWord0[1] == counterSetUid); // counter_set
936 BOOST_CHECK(categoryRecordWord1[0] == categoryEventCount); // event_count
937 BOOST_CHECK(categoryRecordWord1[1] == 0); // reserved
938
939 size_t uint32_t_size = sizeof(uint32_t);
940
941 ARMNN_NO_CONVERSION_WARN_BEGIN
942 uint32_t eventPointerTableOffset = 0; // The event pointer table is the first item in pool
943 uint32_t categoryNameOffset = eventPointerTableOffset + // Event pointer table offset
944 categoryEventCount * uint32_t_size; // The size of the event pointer table
945 ARMNN_NO_CONVERSION_WARN_END
946
947 BOOST_CHECK(categoryRecord[2] == eventPointerTableOffset); // event_pointer_table_offset
948 BOOST_CHECK(categoryRecord[3] == categoryNameOffset); // name_offset
949
950 auto categoryRecordPool = reinterpret_cast<unsigned char*>(categoryRecord.data() + 4u); // The start of the pool
951
952 // The event pointer table
953 uint32_t eventRecord0Offset = categoryRecordPool[eventPointerTableOffset + 0 * uint32_t_size];
954 uint32_t eventRecord1Offset = categoryRecordPool[eventPointerTableOffset + 1 * uint32_t_size];
955 uint32_t eventRecord2Offset = categoryRecordPool[eventPointerTableOffset + 2 * uint32_t_size];
956 BOOST_CHECK(eventRecord0Offset == 32);
957 BOOST_CHECK(eventRecord1Offset == 120);
958 BOOST_CHECK(eventRecord2Offset == 200);
959
960 // The length of the SWTrace namestring (name)
961 BOOST_CHECK(categoryRecordPool[categoryNameOffset] == categoryName.size() + 1);
962 // The category name
963 BOOST_CHECK(std::memcmp(categoryRecordPool +
964 categoryNameOffset + // Offset
965 uint32_t_size, // The length of the name
966 categoryName.data(),
967 categoryName.size()) == 0); // name
968 // The null-terminator at the end of the name
969 BOOST_CHECK(categoryRecordPool[categoryNameOffset + uint32_t_size + categoryName.size()] == '\0');
970
971 // For brevity, checking only the UIDs, max counter UIDs and names of the counters in the event records,
972 // as the event records already have a number of unit tests dedicated to them
973
974 // Counter1 UID and max counter UID
975 uint16_t eventRecord0Word0[2] = { 0u, 0u };
976 std::memcpy(eventRecord0Word0, categoryRecordPool + eventRecord0Offset, sizeof(eventRecord0Word0));
977 BOOST_CHECK(eventRecord0Word0[0] == counter1->m_Uid);
978 BOOST_CHECK(eventRecord0Word0[1] == counter1->m_MaxCounterUid);
979
980 // Counter1 name
981 uint32_t counter1NameOffset = 0;
982 std::memcpy(&counter1NameOffset, categoryRecordPool + eventRecord0Offset + 5u * uint32_t_size, uint32_t_size);
983 BOOST_CHECK(counter1NameOffset == 0);
984 // The length of the SWTrace string (name)
985 BOOST_CHECK(categoryRecordPool[eventRecord0Offset + // Offset to the event record
986 8u * uint32_t_size + // Offset to the event record pool
987 counter1NameOffset // Offset to the name of the counter
988 ] == counter1->m_Name.size() + 1); // The length of the name including the
989 // null-terminator
990 // The counter1 name
991 BOOST_CHECK(std::memcmp(categoryRecordPool + // The beginning of the category pool
992 eventRecord0Offset + // Offset to the event record
993 8u * uint32_t_size + // Offset to the event record pool
994 counter1NameOffset + // Offset to the name of the counter
995 uint32_t_size, // The length of the name
996 counter1->m_Name.data(),
997 counter1->m_Name.size()) == 0); // name
998 // The null-terminator at the end of the counter1 name
999 BOOST_CHECK(categoryRecordPool[eventRecord0Offset + // Offset to the event record
1000 8u * uint32_t_size + // Offset to the event record pool
1001 counter1NameOffset + // Offset to the name of the counter
1002 uint32_t_size + // The length of the name
1003 counter1->m_Name.size() // The name of the counter
1004 ] == '\0');
1005
1006 // Counter2 name
1007 uint32_t counter2NameOffset = 0;
1008 std::memcpy(&counter2NameOffset, categoryRecordPool + eventRecord1Offset + 5u * uint32_t_size, uint32_t_size);
1009 BOOST_CHECK(counter2NameOffset == 0);
1010 // The length of the SWTrace string (name)
1011 BOOST_CHECK(categoryRecordPool[eventRecord1Offset + // Offset to the event record
1012 8u * uint32_t_size + // Offset to the event record pool
1013 counter2NameOffset // Offset to the name of the counter
1014 ] == counter2->m_Name.size() + 1); // The length of the name including the
1015 // null-terminator
1016 // The counter2 name
1017 BOOST_CHECK(std::memcmp(categoryRecordPool + // The beginning of the category pool
1018 eventRecord1Offset + // Offset to the event record
1019 8u * uint32_t_size + // Offset to the event record pool
1020 counter2NameOffset + // Offset to the name of the counter
1021 uint32_t_size, // The length of the name
1022 counter2->m_Name.data(),
1023 counter2->m_Name.size()) == 0); // name
1024 // The null-terminator at the end of the counter2 name
1025 BOOST_CHECK(categoryRecordPool[eventRecord1Offset + // Offset to the event record
1026 8u * uint32_t_size + // Offset to the event record pool
1027 counter2NameOffset + // Offset to the name of the counter
1028 uint32_t_size + // The length of the name
1029 counter2->m_Name.size() // The name of the counter
1030 ] == '\0');
1031
1032 // Counter3 name
1033 uint32_t counter3NameOffset = 0;
1034 std::memcpy(&counter3NameOffset, categoryRecordPool + eventRecord2Offset + 5u * uint32_t_size, uint32_t_size);
1035 BOOST_CHECK(counter3NameOffset == 0);
1036 // The length of the SWTrace string (name)
1037 BOOST_CHECK(categoryRecordPool[eventRecord2Offset + // Offset to the event record
1038 8u * uint32_t_size + // Offset to the event record pool
1039 counter3NameOffset // Offset to the name of the counter
1040 ] == counter3->m_Name.size() + 1); // The length of the name including the
1041 // null-terminator
1042 // The counter3 name
1043 BOOST_CHECK(std::memcmp(categoryRecordPool + // The beginning of the category pool
1044 eventRecord2Offset + // Offset to the event record
1045 8u * uint32_t_size + // Offset to the event record pool
1046 counter3NameOffset + // Offset to the name of the counter
1047 uint32_t_size, // The length of the name
1048 counter3->m_Name.data(),
1049 counter3->m_Name.size()) == 0); // name
1050 // The null-terminator at the end of the counter3 name
1051 BOOST_CHECK(categoryRecordPool[eventRecord2Offset + // Offset to the event record
1052 8u * uint32_t_size + // Offset to the event record pool
1053 counter3NameOffset + // Offset to the name of the counter
1054 uint32_t_size + // The length of the name
1055 counter3->m_Name.size() // The name of the counter
1056 ] == '\0');
1057}
1058
1059BOOST_AUTO_TEST_CASE(CreateInvalidCategoryRecordTest1)
1060{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001061 ProfilingStateMachine profilingStateMachine;
1062
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001063 MockBufferManager mockBuffer(0);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001064 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001065
1066 // Create a category for testing
1067 const std::string categoryName = "some invalid category";
1068 uint16_t deviceUid = 1302;
1069 uint16_t counterSetUid = 20734;
1070 const CategoryPtr category = std::make_unique<Category>(categoryName, deviceUid, counterSetUid);
1071 BOOST_CHECK(category);
1072
1073 // Create a category record
1074 Counters counters;
1075 SendCounterPacket::CategoryRecord categoryRecord;
1076 std::string errorMessage;
1077 bool result = sendCounterPacketTest.CreateCategoryRecordTest(category, counters, categoryRecord, errorMessage);
1078
1079 BOOST_CHECK(!result);
1080 BOOST_CHECK(!errorMessage.empty());
1081 BOOST_CHECK(categoryRecord.empty());
1082}
1083
1084BOOST_AUTO_TEST_CASE(CreateInvalidCategoryRecordTest2)
1085{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001086 ProfilingStateMachine profilingStateMachine;
1087
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001088 MockBufferManager mockBuffer(0);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001089 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001090
1091 // Create a category for testing
1092 const std::string categoryName = "some_category";
1093 uint16_t deviceUid = 1302;
1094 uint16_t counterSetUid = 20734;
1095 const CategoryPtr category = std::make_unique<Category>(categoryName, deviceUid, counterSetUid);
1096 BOOST_CHECK(category);
1097 category->m_Counters = { 11u, 23u, 5670u };
1098
1099 // Create a collection of counters
1100 Counters counters;
1101 counters.insert(std::make_pair<uint16_t, CounterPtr>(11,
1102 CounterPtr(new Counter(11,
1103 1234,
1104 0,
1105 1,
1106 534.0003f,
1107 "count€r1", // Invalid name
1108 "the first counter",
1109 "millipi2",
1110 0,
1111 0))));
1112
1113 Counter* counter1 = counters.find(11)->second.get();
1114 BOOST_CHECK(counter1);
1115
1116 // Create a category record
1117 SendCounterPacket::CategoryRecord categoryRecord;
1118 std::string errorMessage;
1119 bool result = sendCounterPacketTest.CreateCategoryRecordTest(category, counters, categoryRecord, errorMessage);
1120
1121 BOOST_CHECK(!result);
1122 BOOST_CHECK(!errorMessage.empty());
1123 BOOST_CHECK(categoryRecord.empty());
1124}
1125
1126BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest1)
1127{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001128 ProfilingStateMachine profilingStateMachine;
1129
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001130 // The counter directory used for testing
1131 CounterDirectory counterDirectory;
1132
1133 // Register a device
1134 const std::string device1Name = "device1";
1135 const Device* device1 = nullptr;
1136 BOOST_CHECK_NO_THROW(device1 = counterDirectory.RegisterDevice(device1Name, 3));
1137 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1138 BOOST_CHECK(device1);
1139
1140 // Register a device
1141 const std::string device2Name = "device2";
1142 const Device* device2 = nullptr;
1143 BOOST_CHECK_NO_THROW(device2 = counterDirectory.RegisterDevice(device2Name));
1144 BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
1145 BOOST_CHECK(device2);
1146
1147 // Buffer with not enough space
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001148 MockBufferManager mockBuffer(10);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001149 SendCounterPacket sendCounterPacket(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001150 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory),
1151 armnn::profiling::BufferExhaustion);
1152}
1153
1154BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest2)
1155{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001156 ProfilingStateMachine profilingStateMachine;
1157
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001158 // The counter directory used for testing
1159 CounterDirectory counterDirectory;
1160
1161 // Register a device
1162 const std::string device1Name = "device1";
1163 const Device* device1 = nullptr;
1164 BOOST_CHECK_NO_THROW(device1 = counterDirectory.RegisterDevice(device1Name, 3));
1165 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1166 BOOST_CHECK(device1);
1167
1168 // Register a device
1169 const std::string device2Name = "device2";
1170 const Device* device2 = nullptr;
1171 BOOST_CHECK_NO_THROW(device2 = counterDirectory.RegisterDevice(device2Name));
1172 BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
1173 BOOST_CHECK(device2);
1174
1175 // Register a counter set
1176 const std::string counterSet1Name = "counterset1";
1177 const CounterSet* counterSet1 = nullptr;
1178 BOOST_CHECK_NO_THROW(counterSet1 = counterDirectory.RegisterCounterSet(counterSet1Name));
1179 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1180 BOOST_CHECK(counterSet1);
1181
1182 // Register a category associated to "device1" and "counterset1"
1183 const std::string category1Name = "category1";
1184 const Category* category1 = nullptr;
1185 BOOST_CHECK_NO_THROW(category1 = counterDirectory.RegisterCategory(category1Name,
1186 device1->m_Uid,
1187 counterSet1->m_Uid));
1188 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1189 BOOST_CHECK(category1);
1190
1191 // Register a category not associated to "device2" but no counter set
1192 const std::string category2Name = "category2";
1193 const Category* category2 = nullptr;
1194 BOOST_CHECK_NO_THROW(category2 = counterDirectory.RegisterCategory(category2Name,
1195 device2->m_Uid));
1196 BOOST_CHECK(counterDirectory.GetCategoryCount() == 2);
1197 BOOST_CHECK(category2);
1198
1199 // Register a counter associated to "category1"
1200 const Counter* counter1 = nullptr;
1201 BOOST_CHECK_NO_THROW(counter1 = counterDirectory.RegisterCounter(category1Name,
1202 0,
1203 1,
1204 123.45f,
1205 "counter1",
1206 "counter1description",
1207 std::string("counter1units")));
1208 BOOST_CHECK(counterDirectory.GetCounterCount() == 3);
1209 BOOST_CHECK(counter1);
1210
1211 // Register a counter associated to "category1"
1212 const Counter* counter2 = nullptr;
1213 BOOST_CHECK_NO_THROW(counter2 = counterDirectory.RegisterCounter(category1Name,
1214 1,
1215 0,
1216 330.1245656765f,
1217 "counter2",
1218 "counter2description",
1219 std::string("counter2units"),
1220 armnn::EmptyOptional(),
1221 device2->m_Uid,
1222 0));
1223 BOOST_CHECK(counterDirectory.GetCounterCount() == 4);
1224 BOOST_CHECK(counter2);
1225
1226 // Register a counter associated to "category2"
1227 const Counter* counter3 = nullptr;
1228 BOOST_CHECK_NO_THROW(counter3 = counterDirectory.RegisterCounter(category2Name,
1229 1,
1230 1,
1231 0.0000045399f,
1232 "counter3",
1233 "counter3description",
1234 armnn::EmptyOptional(),
1235 5,
1236 device2->m_Uid,
1237 counterSet1->m_Uid));
1238 BOOST_CHECK(counterDirectory.GetCounterCount() == 9);
1239 BOOST_CHECK(counter3);
1240
1241 // Buffer with enough space
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001242 MockBufferManager mockBuffer(1024);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001243 SendCounterPacket sendCounterPacket(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001244 BOOST_CHECK_NO_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory));
1245
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001246 // Get the readable buffer
1247 auto readBuffer = mockBuffer.GetReadableBuffer();
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001248
1249 // Check the packet header
1250 uint32_t packetHeaderWord0 = ReadUint32(readBuffer, 0);
1251 uint32_t packetHeaderWord1 = ReadUint32(readBuffer, 4);
1252 BOOST_TEST(((packetHeaderWord0 >> 26) & 0x3F) == 0); // packet_family
1253 BOOST_TEST(((packetHeaderWord0 >> 16) & 0x3FF) == 2); // packet_id
Matteo Martincighf74ff2f2019-09-24 11:38:32 +01001254 BOOST_TEST(packetHeaderWord1 == 936); // data_length
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001255
1256 // Check the body header
1257 uint32_t bodyHeaderWord0 = ReadUint32(readBuffer, 8);
1258 uint32_t bodyHeaderWord1 = ReadUint32(readBuffer, 12);
1259 uint32_t bodyHeaderWord2 = ReadUint32(readBuffer, 16);
1260 uint32_t bodyHeaderWord3 = ReadUint32(readBuffer, 20);
1261 uint32_t bodyHeaderWord4 = ReadUint32(readBuffer, 24);
1262 uint32_t bodyHeaderWord5 = ReadUint32(readBuffer, 28);
1263 uint16_t deviceRecordCount = static_cast<uint16_t>(bodyHeaderWord0 >> 16);
1264 uint16_t counterSetRecordCount = static_cast<uint16_t>(bodyHeaderWord2 >> 16);
1265 uint16_t categoryRecordCount = static_cast<uint16_t>(bodyHeaderWord4 >> 16);
1266 BOOST_TEST(deviceRecordCount == 2); // device_records_count
1267 BOOST_TEST(bodyHeaderWord1 == 0); // device_records_pointer_table_offset
1268 BOOST_TEST(counterSetRecordCount == 1); // counter_set_count
1269 BOOST_TEST(bodyHeaderWord3 == 8); // counter_set_pointer_table_offset
1270 BOOST_TEST(categoryRecordCount == 2); // categories_count
1271 BOOST_TEST(bodyHeaderWord5 == 12); // categories_pointer_table_offset
1272
1273 // Check the device records pointer table
1274 uint32_t deviceRecordOffset0 = ReadUint32(readBuffer, 32);
1275 uint32_t deviceRecordOffset1 = ReadUint32(readBuffer, 36);
1276 BOOST_TEST(deviceRecordOffset0 == 0); // Device record offset for "device1"
1277 BOOST_TEST(deviceRecordOffset1 == 20); // Device record offset for "device2"
1278
1279 // Check the counter set pointer table
1280 uint32_t counterSetRecordOffset0 = ReadUint32(readBuffer, 40);
1281 BOOST_TEST(counterSetRecordOffset0 == 40); // Counter set record offset for "counterset1"
1282
1283 // Check the category pointer table
1284 uint32_t categoryRecordOffset0 = ReadUint32(readBuffer, 44);
1285 uint32_t categoryRecordOffset1 = ReadUint32(readBuffer, 48);
1286 BOOST_TEST(categoryRecordOffset0 == 64); // Category record offset for "category1"
1287 BOOST_TEST(categoryRecordOffset1 == 476); // Category record offset for "category2"
1288
1289 // Get the device record pool offset
1290 uint32_t uint32_t_size = sizeof(uint32_t);
1291 uint32_t packetBodyPoolOffset = 2u * uint32_t_size + // packet_header
1292 6u * uint32_t_size + // body_header
1293 deviceRecordCount * uint32_t_size + // Size of device_records_pointer_table
1294 counterSetRecordCount * uint32_t_size + // Size of counter_set_pointer_table
1295 categoryRecordCount * uint32_t_size; // Size of categories_pointer_table
1296
1297 // Device record structure/collection used for testing
1298 struct DeviceRecord
1299 {
1300 uint16_t uid;
1301 uint16_t cores;
1302 uint32_t name_offset;
1303 uint32_t name_length;
1304 std::string name;
1305 };
1306 std::vector<DeviceRecord> deviceRecords;
1307 uint32_t deviceRecordsPointerTableOffset = 2u * uint32_t_size + // packet_header
1308 6u * uint32_t_size + // body_header
1309 bodyHeaderWord1; // device_records_pointer_table_offset
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001310
1311 const unsigned char* readData = readBuffer->GetReadableData();
1312
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001313 for (uint32_t i = 0; i < deviceRecordCount; i++)
1314 {
1315 // Get the device record offset
1316 uint32_t deviceRecordOffset = ReadUint32(readBuffer, deviceRecordsPointerTableOffset + i * uint32_t_size);
1317
1318 // Collect the data for the device record
1319 uint32_t deviceRecordWord0 = ReadUint32(readBuffer,
1320 packetBodyPoolOffset + deviceRecordOffset + 0 * uint32_t_size);
1321 uint32_t deviceRecordWord1 = ReadUint32(readBuffer,
1322 packetBodyPoolOffset + deviceRecordOffset + 1 * uint32_t_size);
1323 DeviceRecord deviceRecord;
1324 deviceRecord.uid = static_cast<uint16_t>(deviceRecordWord0 >> 16); // uid
1325 deviceRecord.cores = static_cast<uint16_t>(deviceRecordWord0); // cores
1326 deviceRecord.name_offset = deviceRecordWord1; // name_offset
1327
1328 uint32_t deviceRecordPoolOffset = packetBodyPoolOffset + // Packet body offset
1329 deviceRecordOffset + // Device record offset
1330 2 * uint32_t_size + // Device record header
1331 deviceRecord.name_offset; // Device name offset
1332 uint32_t deviceRecordNameLength = ReadUint32(readBuffer, deviceRecordPoolOffset);
1333 deviceRecord.name_length = deviceRecordNameLength; // name_length
1334 unsigned char deviceRecordNameNullTerminator = // name null-terminator
1335 ReadUint8(readBuffer, deviceRecordPoolOffset + uint32_t_size + deviceRecordNameLength - 1);
1336 BOOST_CHECK(deviceRecordNameNullTerminator == '\0');
1337 std::vector<unsigned char> deviceRecordNameBuffer(deviceRecord.name_length - 1);
1338 std::memcpy(deviceRecordNameBuffer.data(),
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001339 readData + deviceRecordPoolOffset + uint32_t_size, deviceRecordNameBuffer.size());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001340 deviceRecord.name.assign(deviceRecordNameBuffer.begin(), deviceRecordNameBuffer.end()); // name
1341
1342 deviceRecords.push_back(deviceRecord);
1343 }
1344
1345 // Check that the device records are correct
1346 BOOST_CHECK(deviceRecords.size() == 2);
1347 for (const DeviceRecord& deviceRecord : deviceRecords)
1348 {
1349 const Device* device = counterDirectory.GetDevice(deviceRecord.uid);
1350 BOOST_CHECK(device);
1351 BOOST_CHECK(device->m_Uid == deviceRecord.uid);
1352 BOOST_CHECK(device->m_Cores == deviceRecord.cores);
1353 BOOST_CHECK(device->m_Name == deviceRecord.name);
1354 }
1355
1356 // Counter set record structure/collection used for testing
1357 struct CounterSetRecord
1358 {
1359 uint16_t uid;
1360 uint16_t count;
1361 uint32_t name_offset;
1362 uint32_t name_length;
1363 std::string name;
1364 };
1365 std::vector<CounterSetRecord> counterSetRecords;
1366 uint32_t counterSetRecordsPointerTableOffset = 2u * uint32_t_size + // packet_header
1367 6u * uint32_t_size + // body_header
1368 bodyHeaderWord3; // counter_set_pointer_table_offset
1369 for (uint32_t i = 0; i < counterSetRecordCount; i++)
1370 {
1371 // Get the counter set record offset
1372 uint32_t counterSetRecordOffset = ReadUint32(readBuffer,
1373 counterSetRecordsPointerTableOffset + i * uint32_t_size);
1374
1375 // Collect the data for the counter set record
1376 uint32_t counterSetRecordWord0 = ReadUint32(readBuffer,
1377 packetBodyPoolOffset + counterSetRecordOffset + 0 * uint32_t_size);
1378 uint32_t counterSetRecordWord1 = ReadUint32(readBuffer,
1379 packetBodyPoolOffset + counterSetRecordOffset + 1 * uint32_t_size);
1380 CounterSetRecord counterSetRecord;
1381 counterSetRecord.uid = static_cast<uint16_t>(counterSetRecordWord0 >> 16); // uid
1382 counterSetRecord.count = static_cast<uint16_t>(counterSetRecordWord0); // count
1383 counterSetRecord.name_offset = counterSetRecordWord1; // name_offset
1384
1385 uint32_t counterSetRecordPoolOffset = packetBodyPoolOffset + // Packet body offset
1386 counterSetRecordOffset + // Counter set record offset
1387 2 * uint32_t_size + // Counter set record header
1388 counterSetRecord.name_offset; // Counter set name offset
1389 uint32_t counterSetRecordNameLength = ReadUint32(readBuffer, counterSetRecordPoolOffset);
1390 counterSetRecord.name_length = counterSetRecordNameLength; // name_length
1391 unsigned char counterSetRecordNameNullTerminator = // name null-terminator
1392 ReadUint8(readBuffer, counterSetRecordPoolOffset + uint32_t_size + counterSetRecordNameLength - 1);
1393 BOOST_CHECK(counterSetRecordNameNullTerminator == '\0');
1394 std::vector<unsigned char> counterSetRecordNameBuffer(counterSetRecord.name_length - 1);
1395 std::memcpy(counterSetRecordNameBuffer.data(),
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001396 readData + counterSetRecordPoolOffset + uint32_t_size, counterSetRecordNameBuffer.size());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001397 counterSetRecord.name.assign(counterSetRecordNameBuffer.begin(), counterSetRecordNameBuffer.end()); // name
1398
1399 counterSetRecords.push_back(counterSetRecord);
1400 }
1401
1402 // Check that the counter set records are correct
1403 BOOST_CHECK(counterSetRecords.size() == 1);
1404 for (const CounterSetRecord& counterSetRecord : counterSetRecords)
1405 {
1406 const CounterSet* counterSet = counterDirectory.GetCounterSet(counterSetRecord.uid);
1407 BOOST_CHECK(counterSet);
1408 BOOST_CHECK(counterSet->m_Uid == counterSetRecord.uid);
1409 BOOST_CHECK(counterSet->m_Count == counterSetRecord.count);
1410 BOOST_CHECK(counterSet->m_Name == counterSetRecord.name);
1411 }
1412
1413 // Event record structure/collection used for testing
1414 struct EventRecord
1415 {
1416 uint16_t counter_uid;
1417 uint16_t max_counter_uid;
1418 uint16_t device;
1419 uint16_t counter_set;
1420 uint16_t counter_class;
1421 uint16_t interpolation;
1422 double multiplier;
1423 uint32_t name_offset;
1424 uint32_t name_length;
1425 std::string name;
1426 uint32_t description_offset;
1427 uint32_t description_length;
1428 std::string description;
1429 uint32_t units_offset;
1430 uint32_t units_length;
1431 std::string units;
1432 };
1433 // Category record structure/collection used for testing
1434 struct CategoryRecord
1435 {
1436 uint16_t device;
1437 uint16_t counter_set;
1438 uint16_t event_count;
1439 uint32_t event_pointer_table_offset;
1440 uint32_t name_offset;
1441 uint32_t name_length;
1442 std::string name;
1443 std::vector<uint32_t> event_pointer_table;
1444 std::vector<EventRecord> event_records;
1445 };
1446 std::vector<CategoryRecord> categoryRecords;
1447 uint32_t categoryRecordsPointerTableOffset = 2u * uint32_t_size + // packet_header
1448 6u * uint32_t_size + // body_header
1449 bodyHeaderWord5; // categories_pointer_table_offset
1450 for (uint32_t i = 0; i < categoryRecordCount; i++)
1451 {
1452 // Get the category record offset
1453 uint32_t categoryRecordOffset = ReadUint32(readBuffer, categoryRecordsPointerTableOffset + i * uint32_t_size);
1454
1455 // Collect the data for the category record
1456 uint32_t categoryRecordWord0 = ReadUint32(readBuffer,
1457 packetBodyPoolOffset + categoryRecordOffset + 0 * uint32_t_size);
1458 uint32_t categoryRecordWord1 = ReadUint32(readBuffer,
1459 packetBodyPoolOffset + categoryRecordOffset + 1 * uint32_t_size);
1460 uint32_t categoryRecordWord2 = ReadUint32(readBuffer,
1461 packetBodyPoolOffset + categoryRecordOffset + 2 * uint32_t_size);
1462 uint32_t categoryRecordWord3 = ReadUint32(readBuffer,
1463 packetBodyPoolOffset + categoryRecordOffset + 3 * uint32_t_size);
1464 CategoryRecord categoryRecord;
1465 categoryRecord.device = static_cast<uint16_t>(categoryRecordWord0 >> 16); // device
1466 categoryRecord.counter_set = static_cast<uint16_t>(categoryRecordWord0); // counter_set
1467 categoryRecord.event_count = static_cast<uint16_t>(categoryRecordWord1 >> 16); // event_count
1468 categoryRecord.event_pointer_table_offset = categoryRecordWord2; // event_pointer_table_offset
1469 categoryRecord.name_offset = categoryRecordWord3; // name_offset
1470
1471 uint32_t categoryRecordPoolOffset = packetBodyPoolOffset + // Packet body offset
1472 categoryRecordOffset + // Category record offset
1473 4 * uint32_t_size; // Category record header
1474
1475 uint32_t categoryRecordNameLength = ReadUint32(readBuffer,
1476 categoryRecordPoolOffset + categoryRecord.name_offset);
1477 categoryRecord.name_length = categoryRecordNameLength; // name_length
1478 unsigned char categoryRecordNameNullTerminator =
1479 ReadUint8(readBuffer,
1480 categoryRecordPoolOffset +
1481 categoryRecord.name_offset +
1482 uint32_t_size +
1483 categoryRecordNameLength - 1); // name null-terminator
1484 BOOST_CHECK(categoryRecordNameNullTerminator == '\0');
1485 std::vector<unsigned char> categoryRecordNameBuffer(categoryRecord.name_length - 1);
1486 std::memcpy(categoryRecordNameBuffer.data(),
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001487 readData +
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001488 categoryRecordPoolOffset +
1489 categoryRecord.name_offset +
1490 uint32_t_size,
1491 categoryRecordNameBuffer.size());
1492 categoryRecord.name.assign(categoryRecordNameBuffer.begin(), categoryRecordNameBuffer.end()); // name
1493
1494 categoryRecord.event_pointer_table.resize(categoryRecord.event_count);
1495 for (uint32_t eventIndex = 0; eventIndex < categoryRecord.event_count; eventIndex++)
1496 {
1497 uint32_t eventRecordOffset = ReadUint32(readBuffer,
1498 categoryRecordPoolOffset +
1499 categoryRecord.event_pointer_table_offset +
1500 eventIndex * uint32_t_size);
1501 categoryRecord.event_pointer_table[eventIndex] = eventRecordOffset;
1502
1503 // Collect the data for the event record
1504 uint32_t eventRecordWord0 = ReadUint32(readBuffer,
1505 categoryRecordPoolOffset + eventRecordOffset + 0 * uint32_t_size);
1506 uint32_t eventRecordWord1 = ReadUint32(readBuffer,
1507 categoryRecordPoolOffset + eventRecordOffset + 1 * uint32_t_size);
1508 uint32_t eventRecordWord2 = ReadUint32(readBuffer,
1509 categoryRecordPoolOffset + eventRecordOffset + 2 * uint32_t_size);
1510 uint64_t eventRecordWord34 = ReadUint64(readBuffer,
1511 categoryRecordPoolOffset + eventRecordOffset + 3 * uint32_t_size);
1512 uint32_t eventRecordWord5 = ReadUint32(readBuffer,
1513 categoryRecordPoolOffset + eventRecordOffset + 5 * uint32_t_size);
1514 uint32_t eventRecordWord6 = ReadUint32(readBuffer,
1515 categoryRecordPoolOffset + eventRecordOffset + 6 * uint32_t_size);
1516 uint32_t eventRecordWord7 = ReadUint32(readBuffer,
1517 categoryRecordPoolOffset + eventRecordOffset + 7 * uint32_t_size);
1518 EventRecord eventRecord;
1519 eventRecord.counter_uid = static_cast<uint16_t>(eventRecordWord0); // counter_uid
1520 eventRecord.max_counter_uid = static_cast<uint16_t>(eventRecordWord0 >> 16); // max_counter_uid
1521 eventRecord.device = static_cast<uint16_t>(eventRecordWord1 >> 16); // device
1522 eventRecord.counter_set = static_cast<uint16_t>(eventRecordWord1); // counter_set
1523 eventRecord.counter_class = static_cast<uint16_t>(eventRecordWord2 >> 16); // class
1524 eventRecord.interpolation = static_cast<uint16_t>(eventRecordWord2); // interpolation
1525 std::memcpy(&eventRecord.multiplier, &eventRecordWord34, sizeof(eventRecord.multiplier)); // multiplier
1526 eventRecord.name_offset = static_cast<uint32_t>(eventRecordWord5); // name_offset
1527 eventRecord.description_offset = static_cast<uint32_t>(eventRecordWord6); // description_offset
1528 eventRecord.units_offset = static_cast<uint32_t>(eventRecordWord7); // units_offset
1529
1530 uint32_t eventRecordPoolOffset = categoryRecordPoolOffset + // Category record pool offset
1531 eventRecordOffset + // Event record offset
1532 8 * uint32_t_size; // Event record header
1533
1534 uint32_t eventRecordNameLength = ReadUint32(readBuffer,
1535 eventRecordPoolOffset + eventRecord.name_offset);
1536 eventRecord.name_length = eventRecordNameLength; // name_length
1537 unsigned char eventRecordNameNullTerminator =
1538 ReadUint8(readBuffer,
1539 eventRecordPoolOffset +
1540 eventRecord.name_offset +
1541 uint32_t_size +
1542 eventRecordNameLength - 1); // name null-terminator
1543 BOOST_CHECK(eventRecordNameNullTerminator == '\0');
1544 std::vector<unsigned char> eventRecordNameBuffer(eventRecord.name_length - 1);
1545 std::memcpy(eventRecordNameBuffer.data(),
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001546 readData +
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001547 eventRecordPoolOffset +
1548 eventRecord.name_offset +
1549 uint32_t_size,
1550 eventRecordNameBuffer.size());
1551 eventRecord.name.assign(eventRecordNameBuffer.begin(), eventRecordNameBuffer.end()); // name
1552
1553 uint32_t eventRecordDescriptionLength = ReadUint32(readBuffer,
1554 eventRecordPoolOffset + eventRecord.description_offset);
1555 eventRecord.description_length = eventRecordDescriptionLength; // description_length
1556 unsigned char eventRecordDescriptionNullTerminator =
1557 ReadUint8(readBuffer,
1558 eventRecordPoolOffset +
1559 eventRecord.description_offset +
1560 uint32_t_size +
1561 eventRecordDescriptionLength - 1); // description null-terminator
1562 BOOST_CHECK(eventRecordDescriptionNullTerminator == '\0');
1563 std::vector<unsigned char> eventRecordDescriptionBuffer(eventRecord.description_length - 1);
1564 std::memcpy(eventRecordDescriptionBuffer.data(),
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001565 readData +
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001566 eventRecordPoolOffset +
1567 eventRecord.description_offset +
1568 uint32_t_size,
1569 eventRecordDescriptionBuffer.size());
1570 eventRecord.description.assign(eventRecordDescriptionBuffer.begin(),
1571 eventRecordDescriptionBuffer.end()); // description
1572
1573 if (eventRecord.units_offset > 0)
1574 {
1575 uint32_t eventRecordUnitsLength = ReadUint32(readBuffer,
1576 eventRecordPoolOffset + eventRecord.units_offset);
1577 eventRecord.units_length = eventRecordUnitsLength; // units_length
1578 unsigned char eventRecordUnitsNullTerminator =
1579 ReadUint8(readBuffer,
1580 eventRecordPoolOffset +
1581 eventRecord.units_offset +
1582 uint32_t_size +
1583 eventRecordUnitsLength - 1); // units null-terminator
1584 BOOST_CHECK(eventRecordUnitsNullTerminator == '\0');
1585 std::vector<unsigned char> eventRecordUnitsBuffer(eventRecord.units_length - 1);
1586 std::memcpy(eventRecordUnitsBuffer.data(),
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001587 readData +
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001588 eventRecordPoolOffset +
1589 eventRecord.units_offset +
1590 uint32_t_size,
1591 eventRecordUnitsBuffer.size());
1592 eventRecord.units.assign(eventRecordUnitsBuffer.begin(), eventRecordUnitsBuffer.end()); // units
1593 }
1594
1595 categoryRecord.event_records.push_back(eventRecord);
1596 }
1597
1598 categoryRecords.push_back(categoryRecord);
1599 }
1600
1601 // Check that the category records are correct
1602 BOOST_CHECK(categoryRecords.size() == 2);
1603 for (const CategoryRecord& categoryRecord : categoryRecords)
1604 {
1605 const Category* category = counterDirectory.GetCategory(categoryRecord.name);
1606 BOOST_CHECK(category);
1607 BOOST_CHECK(category->m_Name == categoryRecord.name);
1608 BOOST_CHECK(category->m_DeviceUid == categoryRecord.device);
1609 BOOST_CHECK(category->m_CounterSetUid == categoryRecord.counter_set);
1610 BOOST_CHECK(category->m_Counters.size() == categoryRecord.event_count);
1611
1612 // Check that the event records are correct
1613 for (const EventRecord& eventRecord : categoryRecord.event_records)
1614 {
1615 const Counter* counter = counterDirectory.GetCounter(eventRecord.counter_uid);
1616 BOOST_CHECK(counter);
1617 BOOST_CHECK(counter->m_MaxCounterUid == eventRecord.max_counter_uid);
1618 BOOST_CHECK(counter->m_DeviceUid == eventRecord.device);
1619 BOOST_CHECK(counter->m_CounterSetUid == eventRecord.counter_set);
1620 BOOST_CHECK(counter->m_Class == eventRecord.counter_class);
1621 BOOST_CHECK(counter->m_Interpolation == eventRecord.interpolation);
1622 BOOST_CHECK(counter->m_Multiplier == eventRecord.multiplier);
1623 BOOST_CHECK(counter->m_Name == eventRecord.name);
1624 BOOST_CHECK(counter->m_Description == eventRecord.description);
1625 BOOST_CHECK(counter->m_Units == eventRecord.units);
1626 }
1627 }
1628}
1629
1630BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest3)
1631{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001632 ProfilingStateMachine profilingStateMachine;
1633
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001634 // Using a mock counter directory that allows to register invalid objects
1635 MockCounterDirectory counterDirectory;
1636
1637 // Register an invalid device
1638 const std::string deviceName = "inv@lid dev!c€";
1639 const Device* device = nullptr;
1640 BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName, 3));
1641 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1642 BOOST_CHECK(device);
1643
1644 // Buffer with enough space
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001645 MockBufferManager mockBuffer(1024);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001646 SendCounterPacket sendCounterPacket(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001647 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1648}
1649
1650BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest4)
1651{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001652 ProfilingStateMachine profilingStateMachine;
1653
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001654 // Using a mock counter directory that allows to register invalid objects
1655 MockCounterDirectory counterDirectory;
1656
1657 // Register an invalid counter set
1658 const std::string counterSetName = "inv@lid count€rs€t";
1659 const CounterSet* counterSet = nullptr;
1660 BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1661 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1662 BOOST_CHECK(counterSet);
1663
1664 // Buffer with enough space
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001665 MockBufferManager mockBuffer(1024);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001666 SendCounterPacket sendCounterPacket(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001667 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1668}
1669
1670BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest5)
1671{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001672 ProfilingStateMachine profilingStateMachine;
1673
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001674 // Using a mock counter directory that allows to register invalid objects
1675 MockCounterDirectory counterDirectory;
1676
1677 // Register an invalid category
1678 const std::string categoryName = "c@t€gory";
1679 const Category* category = nullptr;
1680 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName));
1681 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1682 BOOST_CHECK(category);
1683
1684 // Buffer with enough space
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001685 MockBufferManager mockBuffer(1024);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001686 SendCounterPacket sendCounterPacket(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001687 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1688}
1689
1690BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest6)
1691{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001692 ProfilingStateMachine profilingStateMachine;
1693
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001694 // Using a mock counter directory that allows to register invalid objects
1695 MockCounterDirectory counterDirectory;
1696
1697 // Register an invalid device
1698 const std::string deviceName = "inv@lid dev!c€";
1699 const Device* device = nullptr;
1700 BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName, 3));
1701 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1702 BOOST_CHECK(device);
1703
1704 // Register an invalid counter set
1705 const std::string counterSetName = "inv@lid count€rs€t";
1706 const CounterSet* counterSet = nullptr;
1707 BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1708 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1709 BOOST_CHECK(counterSet);
1710
1711 // Register an invalid category associated to an invalid device and an invalid counter set
1712 const std::string categoryName = "c@t€gory";
1713 const Category* category = nullptr;
1714 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName,
1715 device->m_Uid,
1716 counterSet->m_Uid));
1717 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1718 BOOST_CHECK(category);
1719
1720 // Buffer with enough space
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001721 MockBufferManager mockBuffer(1024);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001722 SendCounterPacket sendCounterPacket(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001723 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1724}
1725
1726BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest7)
1727{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001728 ProfilingStateMachine profilingStateMachine;
1729
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001730 // Using a mock counter directory that allows to register invalid objects
1731 MockCounterDirectory counterDirectory;
1732
1733 // Register an valid device
1734 const std::string deviceName = "valid device";
1735 const Device* device = nullptr;
1736 BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName, 3));
1737 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1738 BOOST_CHECK(device);
1739
1740 // Register an valid counter set
1741 const std::string counterSetName = "valid counterset";
1742 const CounterSet* counterSet = nullptr;
1743 BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1744 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1745 BOOST_CHECK(counterSet);
1746
1747 // Register an valid category associated to a valid device and a valid counter set
1748 const std::string categoryName = "category";
1749 const Category* category = nullptr;
1750 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName,
1751 device->m_Uid,
1752 counterSet->m_Uid));
1753 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1754 BOOST_CHECK(category);
1755
1756 // Register an invalid counter associated to a valid category
1757 const Counter* counter = nullptr;
1758 BOOST_CHECK_NO_THROW(counter = counterDirectory.RegisterCounter(categoryName,
1759 0,
1760 1,
1761 123.45f,
1762 "counter",
1763 "counter description",
1764 std::string("invalid counter units"),
1765 5,
1766 device->m_Uid,
1767 counterSet->m_Uid));
1768 BOOST_CHECK(counterDirectory.GetCounterCount() == 5);
1769 BOOST_CHECK(counter);
1770
1771 // Buffer with enough space
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001772 MockBufferManager mockBuffer(1024);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001773 SendCounterPacket sendCounterPacket(profilingStateMachine, mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001774 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1775}
Ferran Balaguer47d0fe92019-09-04 16:47:34 +01001776
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001777BOOST_AUTO_TEST_CASE(SendThreadTest0)
1778{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001779 ProfilingStateMachine profilingStateMachine;
1780 SetActiveProfilingState(profilingStateMachine);
1781
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001782 MockProfilingConnection mockProfilingConnection;
Matteo Martincigh61d6f732019-10-03 11:21:18 +01001783 MockStreamCounterBuffer mockStreamCounterBuffer(0);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001784 SendCounterPacket sendCounterPacket(profilingStateMachine, mockStreamCounterBuffer);
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001785
1786 // Try to start the send thread many times, it must only start once
1787
Matteo Martincighe61ffd02019-10-07 10:19:35 +01001788 sendCounterPacket.Start(mockProfilingConnection);
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001789 BOOST_CHECK(sendCounterPacket.IsRunning());
Matteo Martincighe61ffd02019-10-07 10:19:35 +01001790 sendCounterPacket.Start(mockProfilingConnection);
1791 sendCounterPacket.Start(mockProfilingConnection);
1792 sendCounterPacket.Start(mockProfilingConnection);
1793 sendCounterPacket.Start(mockProfilingConnection);
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001794 BOOST_CHECK(sendCounterPacket.IsRunning());
1795
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001796 sendCounterPacket.Stop();
1797 BOOST_CHECK(!sendCounterPacket.IsRunning());
1798}
1799
1800BOOST_AUTO_TEST_CASE(SendThreadTest1)
1801{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001802 ProfilingStateMachine profilingStateMachine;
1803 SetActiveProfilingState(profilingStateMachine);
1804
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001805 unsigned int totalWrittenSize = 0;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001806
1807 MockProfilingConnection mockProfilingConnection;
Matteo Martincigh61d6f732019-10-03 11:21:18 +01001808 MockStreamCounterBuffer mockStreamCounterBuffer(1024);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001809 SendCounterPacket sendCounterPacket(profilingStateMachine, mockStreamCounterBuffer);
Matteo Martincighe61ffd02019-10-07 10:19:35 +01001810 sendCounterPacket.Start(mockProfilingConnection);
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001811
1812 // Interleaving writes and reads to/from the buffer with pauses to test that the send thread actually waits for
1813 // something to become available for reading
1814
Colm Donelan2ba48d22019-11-29 09:10:59 +00001815 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001816
1817 CounterDirectory counterDirectory;
1818 sendCounterPacket.SendStreamMetaDataPacket();
1819
1820 // Get the size of the Stream Metadata Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001821 std::string processName = GetProcessName().substr(0, 60);
Matteo Martincigh61d6f732019-10-03 11:21:18 +01001822 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001823 unsigned int streamMetadataPacketsize = 118 + processNameSize;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001824 totalWrittenSize += streamMetadataPacketsize;
1825
1826 sendCounterPacket.SetReadyToRead();
1827
Colm Donelan2ba48d22019-11-29 09:10:59 +00001828 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001829
1830 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
1831
1832 // Get the size of the Counter Directory Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001833 unsigned int counterDirectoryPacketSize = 32;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001834 totalWrittenSize += counterDirectoryPacketSize;
1835
1836 sendCounterPacket.SetReadyToRead();
1837
Colm Donelan2ba48d22019-11-29 09:10:59 +00001838 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001839
1840 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
1841 {
1842 { 1u, 23u },
1843 { 33u, 1207623u }
1844 });
1845
1846 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001847 unsigned int periodicCounterCapturePacketSize = 28;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001848 totalWrittenSize += periodicCounterCapturePacketSize;
1849
1850 sendCounterPacket.SetReadyToRead();
1851
Colm Donelan2ba48d22019-11-29 09:10:59 +00001852 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001853
1854 sendCounterPacket.SendPeriodicCounterCapturePacket(44u,
1855 {
1856 { 211u, 923u }
1857 });
1858
1859 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001860 periodicCounterCapturePacketSize = 22;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001861 totalWrittenSize += periodicCounterCapturePacketSize;
1862
1863 sendCounterPacket.SendPeriodicCounterCapturePacket(1234u,
1864 {
1865 { 555u, 23u },
1866 { 556u, 6u },
1867 { 557u, 893454u },
1868 { 558u, 1456623u },
1869 { 559u, 571090u }
1870 });
1871
1872 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001873 periodicCounterCapturePacketSize = 46;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001874 totalWrittenSize += periodicCounterCapturePacketSize;
1875
1876 sendCounterPacket.SendPeriodicCounterCapturePacket(997u,
1877 {
1878 { 88u, 11u },
1879 { 96u, 22u },
1880 { 97u, 33u },
1881 { 999u, 444u }
1882 });
1883
1884 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001885 periodicCounterCapturePacketSize = 40;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001886 totalWrittenSize += periodicCounterCapturePacketSize;
1887
1888 sendCounterPacket.SetReadyToRead();
1889
Colm Donelan2ba48d22019-11-29 09:10:59 +00001890 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001891
1892 sendCounterPacket.SendPeriodicCounterSelectionPacket(1000u, { 1345u, 254u, 4536u, 408u, 54u, 6323u, 428u, 1u, 6u });
1893
1894 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001895 periodicCounterCapturePacketSize = 30;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001896 totalWrittenSize += periodicCounterCapturePacketSize;
1897
1898 sendCounterPacket.SetReadyToRead();
1899
Finn Williams109c05b2019-11-29 13:56:33 +00001900 // To test an exact value of the "read size" in the mock buffer, wait to allow the send thread to
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001901 // read all what's remaining in the buffer
Colm Donelan2ba48d22019-11-29 09:10:59 +00001902 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001903
1904 sendCounterPacket.Stop();
1905
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001906 BOOST_CHECK(mockStreamCounterBuffer.GetCommittedSize() == totalWrittenSize);
Matteo Martincigh61d6f732019-10-03 11:21:18 +01001907 BOOST_CHECK(mockStreamCounterBuffer.GetReadableSize() == totalWrittenSize);
1908 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() == totalWrittenSize);
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001909}
1910
1911BOOST_AUTO_TEST_CASE(SendThreadTest2)
1912{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001913 ProfilingStateMachine profilingStateMachine;
1914 SetActiveProfilingState(profilingStateMachine);
1915
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001916 unsigned int totalWrittenSize = 0;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001917
1918 MockProfilingConnection mockProfilingConnection;
Matteo Martincigh61d6f732019-10-03 11:21:18 +01001919 MockStreamCounterBuffer mockStreamCounterBuffer(1024);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001920 SendCounterPacket sendCounterPacket(profilingStateMachine, mockStreamCounterBuffer);
Matteo Martincighe61ffd02019-10-07 10:19:35 +01001921 sendCounterPacket.Start(mockProfilingConnection);
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001922
1923 // Adding many spurious "ready to read" signals throughout the test to check that the send thread is
1924 // capable of handling unnecessary read requests
1925
Colm Donelan2ba48d22019-11-29 09:10:59 +00001926 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001927
1928 sendCounterPacket.SetReadyToRead();
1929
1930 CounterDirectory counterDirectory;
1931 sendCounterPacket.SendStreamMetaDataPacket();
1932
1933 // Get the size of the Stream Metadata Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001934 std::string processName = GetProcessName().substr(0, 60);
Matteo Martincigh61d6f732019-10-03 11:21:18 +01001935 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001936 unsigned int streamMetadataPacketsize = 118 + processNameSize;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001937 totalWrittenSize += streamMetadataPacketsize;
1938
1939 sendCounterPacket.SetReadyToRead();
1940
Colm Donelan2ba48d22019-11-29 09:10:59 +00001941 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001942
1943 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
1944
1945 // Get the size of the Counter Directory Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001946 unsigned int counterDirectoryPacketSize = 32;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001947 totalWrittenSize += counterDirectoryPacketSize;
1948
1949 sendCounterPacket.SetReadyToRead();
1950 sendCounterPacket.SetReadyToRead();
1951
Colm Donelan2ba48d22019-11-29 09:10:59 +00001952 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001953
1954 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
1955 {
1956 { 1u, 23u },
1957 { 33u, 1207623u }
1958 });
1959
1960 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001961 unsigned int periodicCounterCapturePacketSize = 28;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001962 totalWrittenSize += periodicCounterCapturePacketSize;
1963
1964 sendCounterPacket.SetReadyToRead();
1965
Colm Donelan2ba48d22019-11-29 09:10:59 +00001966 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001967
1968 sendCounterPacket.SetReadyToRead();
1969 sendCounterPacket.SetReadyToRead();
1970 sendCounterPacket.SetReadyToRead();
1971
Colm Donelan2ba48d22019-11-29 09:10:59 +00001972 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001973
1974 sendCounterPacket.SetReadyToRead();
1975 sendCounterPacket.SendPeriodicCounterCapturePacket(44u,
1976 {
1977 { 211u, 923u }
1978 });
1979
1980 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001981 periodicCounterCapturePacketSize = 22;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001982 totalWrittenSize += periodicCounterCapturePacketSize;
1983
1984 sendCounterPacket.SendPeriodicCounterCapturePacket(1234u,
1985 {
1986 { 555u, 23u },
1987 { 556u, 6u },
1988 { 557u, 893454u },
1989 { 558u, 1456623u },
1990 { 559u, 571090u }
1991 });
1992
1993 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001994 periodicCounterCapturePacketSize = 46;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001995 totalWrittenSize += periodicCounterCapturePacketSize;
1996
1997 sendCounterPacket.SetReadyToRead();
1998 sendCounterPacket.SendPeriodicCounterCapturePacket(997u,
1999 {
2000 { 88u, 11u },
2001 { 96u, 22u },
2002 { 97u, 33u },
2003 { 999u, 444u }
2004 });
2005
2006 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002007 periodicCounterCapturePacketSize = 40;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002008 totalWrittenSize += periodicCounterCapturePacketSize;
2009
2010 sendCounterPacket.SetReadyToRead();
2011 sendCounterPacket.SetReadyToRead();
2012
Colm Donelan2ba48d22019-11-29 09:10:59 +00002013 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002014
2015 sendCounterPacket.SendPeriodicCounterSelectionPacket(1000u, { 1345u, 254u, 4536u, 408u, 54u, 6323u, 428u, 1u, 6u });
2016
2017 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002018 periodicCounterCapturePacketSize = 30;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002019 totalWrittenSize += periodicCounterCapturePacketSize;
2020
2021 sendCounterPacket.SetReadyToRead();
2022
Finn Williams109c05b2019-11-29 13:56:33 +00002023 // To test an exact value of the "read size" in the mock buffer, wait to allow the send thread to
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002024 // read all what's remaining in the buffer
Colm Donelan2ba48d22019-11-29 09:10:59 +00002025 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002026
2027 sendCounterPacket.Stop();
2028
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002029 BOOST_CHECK(mockStreamCounterBuffer.GetCommittedSize() == totalWrittenSize);
Matteo Martincigh61d6f732019-10-03 11:21:18 +01002030 BOOST_CHECK(mockStreamCounterBuffer.GetReadableSize() == totalWrittenSize);
2031 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() == totalWrittenSize);
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002032}
2033
2034BOOST_AUTO_TEST_CASE(SendThreadTest3)
2035{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002036 ProfilingStateMachine profilingStateMachine;
2037 SetActiveProfilingState(profilingStateMachine);
2038
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002039 unsigned int totalWrittenSize = 0;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002040
2041 MockProfilingConnection mockProfilingConnection;
Matteo Martincigh61d6f732019-10-03 11:21:18 +01002042 MockStreamCounterBuffer mockStreamCounterBuffer(1024);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002043 SendCounterPacket sendCounterPacket(profilingStateMachine, mockStreamCounterBuffer);
Matteo Martincighe61ffd02019-10-07 10:19:35 +01002044 sendCounterPacket.Start(mockProfilingConnection);
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002045
2046 // Not using pauses or "grace periods" to stress test the send thread
2047
2048 sendCounterPacket.SetReadyToRead();
2049
2050 CounterDirectory counterDirectory;
2051 sendCounterPacket.SendStreamMetaDataPacket();
2052
2053 // Get the size of the Stream Metadata Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002054 std::string processName = GetProcessName().substr(0, 60);
Matteo Martincigh61d6f732019-10-03 11:21:18 +01002055 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002056 unsigned int streamMetadataPacketsize = 118 + processNameSize;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002057 totalWrittenSize += streamMetadataPacketsize;
2058
2059 sendCounterPacket.SetReadyToRead();
2060 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
2061
2062 // Get the size of the Counter Directory Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002063 unsigned int counterDirectoryPacketSize =32;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002064 totalWrittenSize += counterDirectoryPacketSize;
2065
2066 sendCounterPacket.SetReadyToRead();
2067 sendCounterPacket.SetReadyToRead();
2068 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
2069 {
2070 { 1u, 23u },
2071 { 33u, 1207623u }
2072 });
2073
2074 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002075 unsigned int periodicCounterCapturePacketSize = 28;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002076 totalWrittenSize += periodicCounterCapturePacketSize;
2077
2078 sendCounterPacket.SetReadyToRead();
2079 sendCounterPacket.SetReadyToRead();
2080 sendCounterPacket.SetReadyToRead();
2081 sendCounterPacket.SetReadyToRead();
2082 sendCounterPacket.SetReadyToRead();
2083 sendCounterPacket.SendPeriodicCounterCapturePacket(44u,
2084 {
2085 { 211u, 923u }
2086 });
2087
2088 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002089 periodicCounterCapturePacketSize = 22;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002090 totalWrittenSize += periodicCounterCapturePacketSize;
2091
2092 sendCounterPacket.SendPeriodicCounterCapturePacket(1234u,
2093 {
2094 { 555u, 23u },
2095 { 556u, 6u },
2096 { 557u, 893454u },
2097 { 558u, 1456623u },
2098 { 559u, 571090u }
2099 });
2100
2101 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002102 periodicCounterCapturePacketSize = 46;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002103 totalWrittenSize += periodicCounterCapturePacketSize;
2104
2105 sendCounterPacket.SetReadyToRead();
2106 sendCounterPacket.SetReadyToRead();
2107 sendCounterPacket.SendPeriodicCounterCapturePacket(997u,
2108 {
2109 { 88u, 11u },
2110 { 96u, 22u },
2111 { 97u, 33u },
2112 { 999u, 444u }
2113 });
2114
2115 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002116 periodicCounterCapturePacketSize = 40;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002117 totalWrittenSize += periodicCounterCapturePacketSize;
2118
2119 sendCounterPacket.SetReadyToRead();
2120 sendCounterPacket.SetReadyToRead();
2121 sendCounterPacket.SendPeriodicCounterSelectionPacket(1000u, { 1345u, 254u, 4536u, 408u, 54u, 6323u, 428u, 1u, 6u });
2122
2123 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002124 periodicCounterCapturePacketSize = 30;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002125 totalWrittenSize += periodicCounterCapturePacketSize;
2126
2127 sendCounterPacket.SetReadyToRead();
2128
2129 // Abruptly terminating the send thread, the amount of data sent may be less that the amount written (the send
2130 // thread is not guaranteed to flush the buffer)
2131 sendCounterPacket.Stop();
2132
Matteo Martincigh61d6f732019-10-03 11:21:18 +01002133 BOOST_CHECK(mockStreamCounterBuffer.GetCommittedSize() == totalWrittenSize);
2134 BOOST_CHECK(mockStreamCounterBuffer.GetReadableSize() <= totalWrittenSize);
2135 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() <= totalWrittenSize);
2136 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() <= mockStreamCounterBuffer.GetReadableSize());
2137 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() <= mockStreamCounterBuffer.GetCommittedSize());
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002138}
2139
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002140BOOST_AUTO_TEST_CASE(SendThreadBufferTest)
2141{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002142 ProfilingStateMachine profilingStateMachine;
2143 SetActiveProfilingState(profilingStateMachine);
2144
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002145 MockProfilingConnection mockProfilingConnection;
2146 BufferManager bufferManager(1, 1024);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002147 SendCounterPacket sendCounterPacket(profilingStateMachine, bufferManager, -1);
Matteo Martincighe61ffd02019-10-07 10:19:35 +01002148 sendCounterPacket.Start(mockProfilingConnection);
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002149
2150 // Interleaving writes and reads to/from the buffer with pauses to test that the send thread actually waits for
2151 // something to become available for reading
Colm Donelan2ba48d22019-11-29 09:10:59 +00002152 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002153
2154 // SendStreamMetaDataPacket
2155 sendCounterPacket.SendStreamMetaDataPacket();
2156
2157 // Read data from the buffer
2158 // Buffer should become readable after commit by SendStreamMetaDataPacket
2159 auto packetBuffer = bufferManager.GetReadableBuffer();
2160 BOOST_TEST(packetBuffer.get());
2161
2162 std::string processName = GetProcessName().substr(0, 60);
2163 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
2164 unsigned int streamMetadataPacketsize = 118 + processNameSize;
2165 BOOST_TEST(packetBuffer->GetSize() == streamMetadataPacketsize);
2166
2167 // Buffer is not available when SendStreamMetaDataPacket already occupied the buffer.
2168 unsigned int reservedSize = 0;
2169 auto reservedBuffer = bufferManager.Reserve(512, reservedSize);
2170 BOOST_TEST(!reservedBuffer.get());
2171
2172 // Recommit to be read by sendCounterPacket
2173 bufferManager.Commit(packetBuffer, streamMetadataPacketsize);
2174
2175 sendCounterPacket.SetReadyToRead();
2176
Colm Donelan2ba48d22019-11-29 09:10:59 +00002177 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002178
2179 // The buffer is read by the send thread so it should not be in the readable buffer.
2180 auto readBuffer = bufferManager.GetReadableBuffer();
2181 BOOST_TEST(!readBuffer);
2182
2183 // Successfully reserved the buffer with requested size
2184 reservedBuffer = bufferManager.Reserve(512, reservedSize);
2185 BOOST_TEST(reservedSize == 512);
2186 BOOST_TEST(reservedBuffer.get());
2187
2188 // Release the buffer to be used by sendCounterPacket
2189 bufferManager.Release(reservedBuffer);
2190
2191 // SendCounterDirectoryPacket
2192 CounterDirectory counterDirectory;
2193 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
2194
2195 // Read data from the buffer
2196 // Buffer should become readable after commit by SendCounterDirectoryPacket
2197 auto counterDirectoryPacketBuffer = bufferManager.GetReadableBuffer();
2198 BOOST_TEST(counterDirectoryPacketBuffer.get());
2199
2200 // Get the size of the Counter Directory Packet
2201 unsigned int counterDirectoryPacketSize = 32;
2202 BOOST_TEST(counterDirectoryPacketBuffer->GetSize() == counterDirectoryPacketSize);
2203
2204 // Buffer is not available when SendCounterDirectoryPacket already occupied the buffer.
2205 reservedSize = 0;
2206 reservedBuffer = bufferManager.Reserve(512, reservedSize);
2207 BOOST_TEST(reservedSize == 0);
2208 BOOST_TEST(!reservedBuffer.get());
2209
2210 // Recommit to be read by sendCounterPacket
2211 bufferManager.Commit(counterDirectoryPacketBuffer, counterDirectoryPacketSize);
2212
2213 sendCounterPacket.SetReadyToRead();
2214
Colm Donelan2ba48d22019-11-29 09:10:59 +00002215 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002216
2217 // The buffer is read by the send thread so it should not be in the readable buffer.
2218 readBuffer = bufferManager.GetReadableBuffer();
2219 BOOST_TEST(!readBuffer);
2220
2221 // Successfully reserved the buffer with requested size
2222 reservedBuffer = bufferManager.Reserve(512, reservedSize);
2223 BOOST_TEST(reservedSize == 512);
2224 BOOST_TEST(reservedBuffer.get());
2225
2226 // Release the buffer to be used by sendCounterPacket
2227 bufferManager.Release(reservedBuffer);
2228
2229 // SendPeriodicCounterCapturePacket
2230 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
2231 {
2232 { 1u, 23u },
2233 { 33u, 1207623u }
2234 });
2235
2236 // Read data from the buffer
2237 // Buffer should become readable after commit by SendPeriodicCounterCapturePacket
2238 auto periodicCounterCapturePacketBuffer = bufferManager.GetReadableBuffer();
2239 BOOST_TEST(periodicCounterCapturePacketBuffer.get());
2240
2241 // Get the size of the Periodic Counter Capture Packet
2242 unsigned int periodicCounterCapturePacketSize = 28;
2243 BOOST_TEST(periodicCounterCapturePacketBuffer->GetSize() == periodicCounterCapturePacketSize);
2244
2245 // Buffer is not available when SendPeriodicCounterCapturePacket already occupied the buffer.
2246 reservedSize = 0;
2247 reservedBuffer = bufferManager.Reserve(512, reservedSize);
2248 BOOST_TEST(reservedSize == 0);
2249 BOOST_TEST(!reservedBuffer.get());
2250
2251 // Recommit to be read by sendCounterPacket
2252 bufferManager.Commit(periodicCounterCapturePacketBuffer, periodicCounterCapturePacketSize);
2253
2254 sendCounterPacket.SetReadyToRead();
2255
Colm Donelan2ba48d22019-11-29 09:10:59 +00002256 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002257
2258 // The buffer is read by the send thread so it should not be in the readable buffer.
2259 readBuffer = bufferManager.GetReadableBuffer();
2260 BOOST_TEST(!readBuffer);
2261
2262 // Successfully reserved the buffer with requested size
2263 reservedBuffer = bufferManager.Reserve(512, reservedSize);
2264 BOOST_TEST(reservedSize == 512);
2265 BOOST_TEST(reservedBuffer.get());
2266
2267 sendCounterPacket.Stop();
2268}
2269
2270BOOST_AUTO_TEST_CASE(SendThreadBufferTest1)
2271{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002272 ProfilingStateMachine profilingStateMachine;
2273 SetActiveProfilingState(profilingStateMachine);
2274
2275 MockProfilingConnection mockProfilingConnection;
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002276 BufferManager bufferManager(3, 1024);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002277 SendCounterPacket sendCounterPacket(profilingStateMachine, bufferManager, -1);
Matteo Martincighe61ffd02019-10-07 10:19:35 +01002278 sendCounterPacket.Start(mockProfilingConnection);
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002279
2280 // SendStreamMetaDataPacket
2281 sendCounterPacket.SendStreamMetaDataPacket();
2282
2283 // Read data from the buffer
2284 // Buffer should become readable after commit by SendStreamMetaDataPacket
2285 auto packetBuffer = bufferManager.GetReadableBuffer();
2286 BOOST_TEST(packetBuffer.get());
2287
2288 std::string processName = GetProcessName().substr(0, 60);
2289 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
2290 unsigned int streamMetadataPacketsize = 118 + processNameSize;
2291 BOOST_TEST(packetBuffer->GetSize() == streamMetadataPacketsize);
2292
2293 // Recommit to be read by sendCounterPacket
2294 bufferManager.Commit(packetBuffer, streamMetadataPacketsize);
2295
2296 sendCounterPacket.SetReadyToRead();
2297
2298 // SendCounterDirectoryPacket
2299 CounterDirectory counterDirectory;
2300 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
2301
2302 sendCounterPacket.SetReadyToRead();
2303
2304 // SendPeriodicCounterCapturePacket
2305 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
2306 {
2307 { 1u, 23u },
2308 { 33u, 1207623u }
2309 });
2310
2311 sendCounterPacket.SetReadyToRead();
2312
2313 sendCounterPacket.Stop();
2314
2315 // The buffer is read by the send thread so it should not be in the readable buffer.
2316 auto readBuffer = bufferManager.GetReadableBuffer();
2317 BOOST_TEST(!readBuffer);
2318
2319 // Successfully reserved the buffer with requested size
2320 unsigned int reservedSize = 0;
2321 auto reservedBuffer = bufferManager.Reserve(512, reservedSize);
2322 BOOST_TEST(reservedSize == 512);
2323 BOOST_TEST(reservedBuffer.get());
2324
2325 // Check that data was actually written to the profiling connection in any order
Matteo Martincighd0613b52019-10-09 16:47:04 +01002326 const std::vector<uint32_t> writtenData = mockProfilingConnection.GetWrittenData();
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002327 BOOST_TEST(writtenData.size() == 3);
2328 bool foundStreamMetaDataPacket =
2329 std::find(writtenData.begin(), writtenData.end(), streamMetadataPacketsize) != writtenData.end();
2330 bool foundCounterDirectoryPacket = std::find(writtenData.begin(), writtenData.end(), 32) != writtenData.end();
2331 bool foundPeriodicCounterCapturePacket = std::find(writtenData.begin(), writtenData.end(), 28) != writtenData.end();
2332 BOOST_TEST(foundStreamMetaDataPacket);
2333 BOOST_TEST(foundCounterDirectoryPacket);
2334 BOOST_TEST(foundPeriodicCounterCapturePacket);
2335}
2336
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002337BOOST_AUTO_TEST_CASE(SendThreadSendStreamMetadataPacket1)
2338{
2339 ProfilingStateMachine profilingStateMachine;
2340
2341 MockProfilingConnection mockProfilingConnection;
2342 BufferManager bufferManager(3, 1024);
2343 SendCounterPacket sendCounterPacket(profilingStateMachine, bufferManager);
2344 sendCounterPacket.Start(mockProfilingConnection);
2345
2346 // The profiling state is set to "Uninitialized", so the send thread should throw an exception
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002347 BOOST_CHECK_THROW(sendCounterPacket.Stop(), armnn::RuntimeException);
2348}
2349
2350BOOST_AUTO_TEST_CASE(SendThreadSendStreamMetadataPacket2)
2351{
2352 ProfilingStateMachine profilingStateMachine;
2353 SetNotConnectedProfilingState(profilingStateMachine);
2354
2355 MockProfilingConnection mockProfilingConnection;
2356 BufferManager bufferManager(3, 1024);
2357 SendCounterPacket sendCounterPacket(profilingStateMachine, bufferManager);
2358 sendCounterPacket.Start(mockProfilingConnection);
2359
2360 // The profiling state is set to "NotConnected", so the send thread should throw an exception
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002361 BOOST_CHECK_THROW(sendCounterPacket.Stop(), armnn::RuntimeException);
2362}
2363
2364BOOST_AUTO_TEST_CASE(SendThreadSendStreamMetadataPacket3)
2365{
2366 ProfilingStateMachine profilingStateMachine;
2367 SetWaitingForAckProfilingState(profilingStateMachine);
2368
2369 // Calculate the size of a Stream Metadata packet
2370 std::string processName = GetProcessName().substr(0, 60);
2371 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
2372 unsigned int streamMetadataPacketsize = 118 + processNameSize;
2373
2374 MockProfilingConnection mockProfilingConnection;
2375 BufferManager bufferManager(3, 1024);
2376 SendCounterPacket sendCounterPacket(profilingStateMachine, bufferManager);
2377 sendCounterPacket.Start(mockProfilingConnection);
2378
2379 // The profiling state is set to "WaitingForAck", so the send thread should send a Stream Metadata packet
Finn Williams109c05b2019-11-29 13:56:33 +00002380 // Wait for sendCounterPacket to join
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002381 BOOST_CHECK_NO_THROW(sendCounterPacket.Stop());
2382
2383 // Check that the buffer contains one Stream Metadata packet
Matteo Martincighd0613b52019-10-09 16:47:04 +01002384 const std::vector<uint32_t> writtenData = mockProfilingConnection.GetWrittenData();
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002385 BOOST_TEST(writtenData.size() == 1);
2386 BOOST_TEST(writtenData[0] == streamMetadataPacketsize);
2387}
2388
2389BOOST_AUTO_TEST_CASE(SendThreadSendStreamMetadataPacket4)
2390{
2391 ProfilingStateMachine profilingStateMachine;
2392 SetWaitingForAckProfilingState(profilingStateMachine);
2393
2394 // Calculate the size of a Stream Metadata packet
2395 std::string processName = GetProcessName().substr(0, 60);
2396 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
2397 unsigned int streamMetadataPacketsize = 118 + processNameSize;
2398
2399 MockProfilingConnection mockProfilingConnection;
2400 BufferManager bufferManager(3, 1024);
2401 SendCounterPacket sendCounterPacket(profilingStateMachine, bufferManager);
2402 sendCounterPacket.Start(mockProfilingConnection);
2403
2404 // The profiling state is set to "WaitingForAck", so the send thread should send a Stream Metadata packet
Finn Williams109c05b2019-11-29 13:56:33 +00002405 // Wait for sendCounterPacket to join
2406 sendCounterPacket.Stop();
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002407
Finn Williams109c05b2019-11-29 13:56:33 +00002408 sendCounterPacket.Start(mockProfilingConnection);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002409 // Check that the profiling state is still "WaitingForAck"
2410 BOOST_TEST((profilingStateMachine.GetCurrentState() == ProfilingState::WaitingForAck));
2411
2412 // Check that the buffer contains one Stream Metadata packet
Matteo Martincighd0613b52019-10-09 16:47:04 +01002413 const std::vector<uint32_t> writtenData = mockProfilingConnection.GetWrittenData();
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002414 BOOST_TEST(writtenData.size() == 1);
2415 BOOST_TEST(writtenData[0] == streamMetadataPacketsize);
2416
2417 mockProfilingConnection.Clear();
2418
2419 // Try triggering a new buffer read
2420 sendCounterPacket.SetReadyToRead();
2421
Finn Williams109c05b2019-11-29 13:56:33 +00002422 // Wait for sendCounterPacket to join
2423 BOOST_CHECK_NO_THROW(sendCounterPacket.Stop());
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002424
2425 // Check that the profiling state is still "WaitingForAck"
2426 BOOST_TEST((profilingStateMachine.GetCurrentState() == ProfilingState::WaitingForAck));
2427
2428 // Check that the buffer contains one Stream Metadata packet
2429 BOOST_TEST(writtenData.size() == 1);
2430 BOOST_TEST(writtenData[0] == streamMetadataPacketsize);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002431}
2432
Ferran Balagueraf5c46b2019-08-30 15:49:15 +01002433BOOST_AUTO_TEST_SUITE_END()