blob: 17931cc79bbb7115f96a1e5edcb6377da4541d7b [file] [log] [blame]
Ferran Balagueraf5c46b2019-08-30 15:49:15 +01001//
Jim Flynn83d08a92020-07-09 13:48:16 +01002// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
Ferran Balagueraf5c46b2019-08-30 15:49:15 +01003// SPDX-License-Identifier: MIT
4//
5
Jim Flynn64063552020-02-14 10:18:08 +00006#include "ProfilingMocks.hpp"
Finn Williamsa0de0562020-04-22 12:27:37 +01007#include "ProfilingTestUtils.hpp"
Ferran Balaguer1b941722019-08-28 16:57:18 +01008#include "SendCounterPacketTests.hpp"
Ferran Balagueraf5c46b2019-08-30 15:49:15 +01009
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +010010#include <BufferManager.hpp>
Sadik Armagan7bbdf9d2019-10-24 10:26:05 +010011#include <CounterDirectory.hpp>
Jim Flynnbbfe6032020-07-20 16:57:44 +010012#include <common/include/EncodeVersion.hpp>
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +010013#include <ProfilingUtils.hpp>
Matteo Martincigh6db5f202019-09-05 12:02:04 +010014#include <SendCounterPacket.hpp>
Rob Hughesbdee4262020-01-07 17:05:24 +000015#include <Processes.hpp>
Matteo Martincigh6db5f202019-09-05 12:02:04 +010016
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +010017#include <armnn/Conversion.hpp>
Rob Hughes122f3252020-01-09 12:46:21 +000018#include <armnn/Utils.hpp>
Ferran Balaguer73882172019-09-02 16:39:42 +010019
Finn Williamse09fc822020-04-29 13:17:30 +010020#include <common/include/Constants.hpp>
Jim Flynn75c14f42022-03-10 22:05:42 +000021#include <common/include/NumericCast.hpp>
Jim Flynnf9db3ef2022-03-08 21:23:44 +000022#include <common/include/ProfilingException.hpp>
Finn Williamse09fc822020-04-29 13:17:30 +010023
Sadik Armagan1625efc2021-06-10 18:24:34 +010024#include <armnn/utility/Assert.hpp>
25
26#include <doctest/doctest.h>
Ferran Balagueraf5c46b2019-08-30 15:49:15 +010027
Francis Murtagh3a161982019-09-04 15:25:02 +010028#include <chrono>
Ferran Balagueraf5c46b2019-08-30 15:49:15 +010029
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000030using namespace arm::pipe;
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +010031
Matteo Martincigh5d737fb2019-10-07 13:05:13 +010032namespace
33{
34
Colm Donelan2ba48d22019-11-29 09:10:59 +000035// A short delay to wait for the thread to process a packet.
Finn Williams09ad6f92019-12-19 17:05:18 +000036uint16_t constexpr WAIT_UNTIL_READABLE_MS = 20;
Colm Donelan2ba48d22019-11-29 09:10:59 +000037
Matteo Martincigh5d737fb2019-10-07 13:05:13 +010038void SetNotConnectedProfilingState(ProfilingStateMachine& profilingStateMachine)
39{
40 ProfilingState currentState = profilingStateMachine.GetCurrentState();
41 switch (currentState)
42 {
43 case ProfilingState::WaitingForAck:
44 profilingStateMachine.TransitionToState(ProfilingState::Active);
Rob Hughes122f3252020-01-09 12:46:21 +000045 ARMNN_FALLTHROUGH;
Matteo Martincigh5d737fb2019-10-07 13:05:13 +010046 case ProfilingState::Uninitialised:
Rob Hughes122f3252020-01-09 12:46:21 +000047 ARMNN_FALLTHROUGH;
Matteo Martincigh5d737fb2019-10-07 13:05:13 +010048 case ProfilingState::Active:
49 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
Rob Hughes122f3252020-01-09 12:46:21 +000050 ARMNN_FALLTHROUGH;
Matteo Martincigh5d737fb2019-10-07 13:05:13 +010051 case ProfilingState::NotConnected:
52 return;
53 default:
Sadik Armagan1625efc2021-06-10 18:24:34 +010054 CHECK_MESSAGE(false, "Invalid profiling state");
Matteo Martincigh5d737fb2019-10-07 13:05:13 +010055 }
56}
57
58void SetWaitingForAckProfilingState(ProfilingStateMachine& profilingStateMachine)
59{
60 ProfilingState currentState = profilingStateMachine.GetCurrentState();
61 switch (currentState)
62 {
63 case ProfilingState::Uninitialised:
Rob Hughes122f3252020-01-09 12:46:21 +000064 ARMNN_FALLTHROUGH;
Matteo Martincigh5d737fb2019-10-07 13:05:13 +010065 case ProfilingState::Active:
66 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
Rob Hughes122f3252020-01-09 12:46:21 +000067 ARMNN_FALLTHROUGH;
Matteo Martincigh5d737fb2019-10-07 13:05:13 +010068 case ProfilingState::NotConnected:
69 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
Rob Hughes122f3252020-01-09 12:46:21 +000070 ARMNN_FALLTHROUGH;
Matteo Martincigh5d737fb2019-10-07 13:05:13 +010071 case ProfilingState::WaitingForAck:
72 return;
73 default:
Sadik Armagan1625efc2021-06-10 18:24:34 +010074 CHECK_MESSAGE(false, "Invalid profiling state");
Matteo Martincigh5d737fb2019-10-07 13:05:13 +010075 }
76}
77
78void SetActiveProfilingState(ProfilingStateMachine& profilingStateMachine)
79{
80 ProfilingState currentState = profilingStateMachine.GetCurrentState();
81 switch (currentState)
82 {
83 case ProfilingState::Uninitialised:
84 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
Rob Hughes122f3252020-01-09 12:46:21 +000085 ARMNN_FALLTHROUGH;
Matteo Martincigh5d737fb2019-10-07 13:05:13 +010086 case ProfilingState::NotConnected:
87 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
Rob Hughes122f3252020-01-09 12:46:21 +000088 ARMNN_FALLTHROUGH;
Matteo Martincigh5d737fb2019-10-07 13:05:13 +010089 case ProfilingState::WaitingForAck:
90 profilingStateMachine.TransitionToState(ProfilingState::Active);
Rob Hughes122f3252020-01-09 12:46:21 +000091 ARMNN_FALLTHROUGH;
Matteo Martincigh5d737fb2019-10-07 13:05:13 +010092 case ProfilingState::Active:
93 return;
94 default:
Sadik Armagan1625efc2021-06-10 18:24:34 +010095 CHECK_MESSAGE(false, "Invalid profiling state");
Matteo Martincigh5d737fb2019-10-07 13:05:13 +010096 }
97}
98
99} // Anonymous namespace
100
Sadik Armagan1625efc2021-06-10 18:24:34 +0100101TEST_SUITE("SendCounterPacketTests")
102{
Finn Williams09ad6f92019-12-19 17:05:18 +0000103using PacketType = MockProfilingConnection::PacketType;
104
Sadik Armagan1625efc2021-06-10 18:24:34 +0100105TEST_CASE("MockSendCounterPacketTest")
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100106{
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100107 MockBufferManager mockBuffer(512);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100108 MockSendCounterPacket mockSendCounterPacket(mockBuffer);
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100109
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100110 mockSendCounterPacket.SendStreamMetaDataPacket();
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100111
112 auto packetBuffer = mockBuffer.GetReadableBuffer();
113 const char* buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100114
Sadik Armagan1625efc2021-06-10 18:24:34 +0100115 CHECK(strcmp(buffer, "SendStreamMetaDataPacket") == 0);
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100116
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100117 mockBuffer.MarkRead(packetBuffer);
118
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100119 CounterDirectory counterDirectory;
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100120 mockSendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100121
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100122 packetBuffer = mockBuffer.GetReadableBuffer();
123 buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
124
Sadik Armagan1625efc2021-06-10 18:24:34 +0100125 CHECK(strcmp(buffer, "SendCounterDirectoryPacket") == 0);
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100126
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100127 mockBuffer.MarkRead(packetBuffer);
128
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100129 uint64_t timestamp = 0;
Finn Williams032bc742020-02-12 11:02:34 +0000130 std::vector<CounterValue> indexValuePairs;
Francis Murtagh3a161982019-09-04 15:25:02 +0100131
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100132 mockSendCounterPacket.SendPeriodicCounterCapturePacket(timestamp, indexValuePairs);
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100133
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100134 packetBuffer = mockBuffer.GetReadableBuffer();
135 buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
136
Sadik Armagan1625efc2021-06-10 18:24:34 +0100137 CHECK(strcmp(buffer, "SendPeriodicCounterCapturePacket") == 0);
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100138
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100139 mockBuffer.MarkRead(packetBuffer);
140
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100141 uint32_t capturePeriod = 0;
142 std::vector<uint16_t> selectedCounterIds;
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100143 mockSendCounterPacket.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds);
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100144
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100145 packetBuffer = mockBuffer.GetReadableBuffer();
146 buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
147
Sadik Armagan1625efc2021-06-10 18:24:34 +0100148 CHECK(strcmp(buffer, "SendPeriodicCounterSelectionPacket") == 0);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100149
150 mockBuffer.MarkRead(packetBuffer);
Ferran Balagueraf5c46b2019-08-30 15:49:15 +0100151}
152
Sadik Armagan1625efc2021-06-10 18:24:34 +0100153TEST_CASE("SendPeriodicCounterSelectionPacketTest")
Ferran Balaguer73882172019-09-02 16:39:42 +0100154{
155 // Error no space left in buffer
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100156 MockBufferManager mockBuffer1(10);
Sadik Armagan3896b472020-02-10 12:24:15 +0000157 SendCounterPacket sendPacket1(mockBuffer1);
Ferran Balaguer73882172019-09-02 16:39:42 +0100158
159 uint32_t capturePeriod = 1000;
160 std::vector<uint16_t> selectedCounterIds;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100161 CHECK_THROWS_AS(sendPacket1.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds),
Matteo Martincigh24e8f922019-09-19 11:57:46 +0100162 BufferExhaustion);
Ferran Balaguer73882172019-09-02 16:39:42 +0100163
164 // Packet without any counters
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100165 MockBufferManager mockBuffer2(512);
Sadik Armagan3896b472020-02-10 12:24:15 +0000166 SendCounterPacket sendPacket2(mockBuffer2);
Ferran Balaguer73882172019-09-02 16:39:42 +0100167
168 sendPacket2.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100169 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
Ferran Balaguer73882172019-09-02 16:39:42 +0100170
171 uint32_t headerWord0 = ReadUint32(readBuffer2, 0);
172 uint32_t headerWord1 = ReadUint32(readBuffer2, 4);
173 uint32_t period = ReadUint32(readBuffer2, 8);
174
Sadik Armagan1625efc2021-06-10 18:24:34 +0100175 CHECK(((headerWord0 >> 26) & 0x3F) == 0); // packet family
176 CHECK(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
177 CHECK(headerWord1 == 4); // data lenght
178 CHECK(period == 1000); // capture period
Ferran Balaguer73882172019-09-02 16:39:42 +0100179
180 // Full packet message
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100181 MockBufferManager mockBuffer3(512);
Sadik Armagan3896b472020-02-10 12:24:15 +0000182 SendCounterPacket sendPacket3(mockBuffer3);
Ferran Balaguer73882172019-09-02 16:39:42 +0100183
184 selectedCounterIds.reserve(5);
185 selectedCounterIds.emplace_back(100);
186 selectedCounterIds.emplace_back(200);
187 selectedCounterIds.emplace_back(300);
188 selectedCounterIds.emplace_back(400);
189 selectedCounterIds.emplace_back(500);
190 sendPacket3.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100191 auto readBuffer3 = mockBuffer3.GetReadableBuffer();
Ferran Balaguer73882172019-09-02 16:39:42 +0100192
193 headerWord0 = ReadUint32(readBuffer3, 0);
194 headerWord1 = ReadUint32(readBuffer3, 4);
195 period = ReadUint32(readBuffer3, 8);
196
Sadik Armagan1625efc2021-06-10 18:24:34 +0100197 CHECK(((headerWord0 >> 26) & 0x3F) == 0); // packet family
198 CHECK(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
199 CHECK(headerWord1 == 14); // data lenght
200 CHECK(period == 1000); // capture period
Ferran Balaguer73882172019-09-02 16:39:42 +0100201
202 uint16_t counterId = 0;
203 uint32_t offset = 12;
204
205 // Counter Ids
206 for(const uint16_t& id : selectedCounterIds)
207 {
208 counterId = ReadUint16(readBuffer3, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100209 CHECK(counterId == id);
Ferran Balaguer73882172019-09-02 16:39:42 +0100210 offset += 2;
211 }
212}
213
Sadik Armagan1625efc2021-06-10 18:24:34 +0100214TEST_CASE("SendPeriodicCounterCapturePacketTest")
Francis Murtagh3a161982019-09-04 15:25:02 +0100215{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100216 ProfilingStateMachine profilingStateMachine;
217
Francis Murtagh3a161982019-09-04 15:25:02 +0100218 // Error no space left in buffer
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100219 MockBufferManager mockBuffer1(10);
Sadik Armagan3896b472020-02-10 12:24:15 +0000220 SendCounterPacket sendPacket1(mockBuffer1);
Francis Murtagh3a161982019-09-04 15:25:02 +0100221
222 auto captureTimestamp = std::chrono::steady_clock::now();
223 uint64_t time = static_cast<uint64_t >(captureTimestamp.time_since_epoch().count());
Finn Williams032bc742020-02-12 11:02:34 +0000224 std::vector<CounterValue> indexValuePairs;
Francis Murtagh3a161982019-09-04 15:25:02 +0100225
Sadik Armagan1625efc2021-06-10 18:24:34 +0100226 CHECK_THROWS_AS(sendPacket1.SendPeriodicCounterCapturePacket(time, indexValuePairs),
Francis Murtagh3a161982019-09-04 15:25:02 +0100227 BufferExhaustion);
228
229 // Packet without any counters
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100230 MockBufferManager mockBuffer2(512);
Sadik Armagan3896b472020-02-10 12:24:15 +0000231 SendCounterPacket sendPacket2(mockBuffer2);
Francis Murtagh3a161982019-09-04 15:25:02 +0100232
233 sendPacket2.SendPeriodicCounterCapturePacket(time, indexValuePairs);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100234 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
Francis Murtagh3a161982019-09-04 15:25:02 +0100235
236 uint32_t headerWord0 = ReadUint32(readBuffer2, 0);
237 uint32_t headerWord1 = ReadUint32(readBuffer2, 4);
238 uint64_t readTimestamp = ReadUint64(readBuffer2, 8);
239
Sadik Armagan1625efc2021-06-10 18:24:34 +0100240 CHECK(((headerWord0 >> 26) & 0x0000003F) == 3); // packet family
241 CHECK(((headerWord0 >> 19) & 0x0000007F) == 0); // packet class
242 CHECK(((headerWord0 >> 16) & 0x00000007) == 0); // packet type
243 CHECK(headerWord1 == 8); // data length
244 CHECK(time == readTimestamp); // capture period
Francis Murtagh3a161982019-09-04 15:25:02 +0100245
246 // Full packet message
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100247 MockBufferManager mockBuffer3(512);
Sadik Armagan3896b472020-02-10 12:24:15 +0000248 SendCounterPacket sendPacket3(mockBuffer3);
Francis Murtagh3a161982019-09-04 15:25:02 +0100249
250 indexValuePairs.reserve(5);
Finn Williams032bc742020-02-12 11:02:34 +0000251 indexValuePairs.emplace_back(CounterValue{0, 100});
252 indexValuePairs.emplace_back(CounterValue{1, 200});
253 indexValuePairs.emplace_back(CounterValue{2, 300});
254 indexValuePairs.emplace_back(CounterValue{3, 400});
255 indexValuePairs.emplace_back(CounterValue{4, 500});
Francis Murtagh3a161982019-09-04 15:25:02 +0100256 sendPacket3.SendPeriodicCounterCapturePacket(time, indexValuePairs);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100257 auto readBuffer3 = mockBuffer3.GetReadableBuffer();
Francis Murtagh3a161982019-09-04 15:25:02 +0100258
259 headerWord0 = ReadUint32(readBuffer3, 0);
260 headerWord1 = ReadUint32(readBuffer3, 4);
261 uint64_t readTimestamp2 = ReadUint64(readBuffer3, 8);
262
Sadik Armagan1625efc2021-06-10 18:24:34 +0100263 CHECK(((headerWord0 >> 26) & 0x0000003F) == 3); // packet family
264 CHECK(((headerWord0 >> 19) & 0x0000007F) == 0); // packet class
265 CHECK(((headerWord0 >> 16) & 0x00000007) == 0); // packet type
266 CHECK(headerWord1 == 38); // data length
267 CHECK(time == readTimestamp2); // capture period
Francis Murtagh3a161982019-09-04 15:25:02 +0100268
269 uint16_t counterIndex = 0;
270 uint32_t counterValue = 100;
271 uint32_t offset = 16;
272
273 // Counter Ids
274 for (auto it = indexValuePairs.begin(), end = indexValuePairs.end(); it != end; ++it)
275 {
276 // Check Counter Index
277 uint16_t readIndex = ReadUint16(readBuffer3, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100278 CHECK(counterIndex == readIndex);
Francis Murtagh3a161982019-09-04 15:25:02 +0100279 counterIndex++;
280 offset += 2;
281
282 // Check Counter Value
283 uint32_t readValue = ReadUint32(readBuffer3, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100284 CHECK(counterValue == readValue);
Francis Murtagh3a161982019-09-04 15:25:02 +0100285 counterValue += 100;
286 offset += 4;
287 }
288
289}
290
Sadik Armagan1625efc2021-06-10 18:24:34 +0100291TEST_CASE("SendStreamMetaDataPacketTest")
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100292{
Jim Flynn75c14f42022-03-10 22:05:42 +0000293 uint32_t sizeUint32 = arm::pipe::numeric_cast<uint32_t>(sizeof(uint32_t));
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100294
295 // Error no space left in buffer
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100296 MockBufferManager mockBuffer1(10);
Sadik Armagan3896b472020-02-10 12:24:15 +0000297 SendCounterPacket sendPacket1(mockBuffer1);
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000298 CHECK_THROWS_AS(sendPacket1.SendStreamMetaDataPacket(), BufferExhaustion);
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100299
300 // Full metadata packet
301
302 std::string processName = GetProcessName().substr(0, 60);
303
Jim Flynn75c14f42022-03-10 22:05:42 +0000304 uint32_t infoSize = arm::pipe::numeric_cast<uint32_t>(GetSoftwareInfo().size()) + 1;
305 uint32_t hardwareVersionSize = arm::pipe::numeric_cast<uint32_t>(GetHardwareVersion().size()) + 1;
306 uint32_t softwareVersionSize = arm::pipe::numeric_cast<uint32_t>(GetSoftwareVersion().size()) + 1;
307 uint32_t processNameSize = arm::pipe::numeric_cast<uint32_t>(processName.size()) + 1;
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100308
Jim Flynn83d08a92020-07-09 13:48:16 +0100309 // Supported Packets
310 // Packet Encoding version 1.0.0
311 // Control packet family
312 // Stream metadata packet (packet family=0; packet id=0)
313 // Connection Acknowledged packet ( packet family=0, packet id=1) Version 1.0.0
314 // Counter Directory packet (packet family=0; packet id=2) Version 1.0.0
315 // Request Counter Directory packet ( packet family=0, packet id=3) Version 1.0.0
316 // Periodic Counter Selection packet ( packet family=0, packet id=4) Version 1.0.0
317 // Per Job Counter Selection packet ( packet family=0, packet id=5) Version 1.0.0
318 // Activate Timeline Reporting (packet family = 0, packet id = 6) Version 1.0.0
319 // Deactivate Timeline Reporting (packet family = 0, packet id = 7) Version 1.0.0
320 // Counter Packet Family
321 // Periodic Counter Capture (packet_family = 3, packet_class = 0, packet_type = 0) Version 1.0.0
322 // Per-Job Counter Capture (packet_family = 3, packet_class = 1, packet_type = 0,1) Version 1.0.0
323 // Timeline Packet Family
324 // Timeline Message Directory (packet_family = 1, packet_class = 0, packet_type = 0) Version 1.0.0
325 // Timeline Message (packet_family = 1, packet_class = 0, packet_type = 1) Version 1.0.0
326 std::vector<std::pair<uint32_t, uint32_t>> packetVersions;
Jim Flynnbbfe6032020-07-20 16:57:44 +0100327 packetVersions.push_back(std::make_pair(ConstructHeader(0, 0), arm::pipe::EncodeVersion(1, 0, 0)));
328 packetVersions.push_back(std::make_pair(ConstructHeader(0, 1), arm::pipe::EncodeVersion(1, 0, 0)));
329 packetVersions.push_back(std::make_pair(ConstructHeader(0, 2), arm::pipe::EncodeVersion(1, 0, 0)));
330 packetVersions.push_back(std::make_pair(ConstructHeader(0, 3), arm::pipe::EncodeVersion(1, 0, 0)));
331 packetVersions.push_back(std::make_pair(ConstructHeader(0, 4), arm::pipe::EncodeVersion(1, 0, 0)));
332 packetVersions.push_back(std::make_pair(ConstructHeader(0, 5), arm::pipe::EncodeVersion(1, 0, 0)));
333 packetVersions.push_back(std::make_pair(ConstructHeader(0, 6), arm::pipe::EncodeVersion(1, 0, 0)));
334 packetVersions.push_back(std::make_pair(ConstructHeader(0, 7), arm::pipe::EncodeVersion(1, 0, 0)));
335 packetVersions.push_back(std::make_pair(ConstructHeader(3, 0, 0), arm::pipe::EncodeVersion(1, 0, 0)));
336 packetVersions.push_back(std::make_pair(ConstructHeader(3, 1, 0), arm::pipe::EncodeVersion(1, 0, 0)));
337 packetVersions.push_back(std::make_pair(ConstructHeader(3, 1, 1), arm::pipe::EncodeVersion(1, 0, 0)));
338 packetVersions.push_back(std::make_pair(ConstructHeader(1, 0, 0), arm::pipe::EncodeVersion(1, 0, 0)));
339 packetVersions.push_back(std::make_pair(ConstructHeader(1, 0, 1), arm::pipe::EncodeVersion(1, 0, 0)));
Jim Flynn83d08a92020-07-09 13:48:16 +0100340
341 uint32_t packetEntries = static_cast<uint32_t>(packetVersions.size());
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100342
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100343 MockBufferManager mockBuffer2(512);
Sadik Armagan3896b472020-02-10 12:24:15 +0000344 SendCounterPacket sendPacket2(mockBuffer2);
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100345 sendPacket2.SendStreamMetaDataPacket();
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100346 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100347
348 uint32_t headerWord0 = ReadUint32(readBuffer2, 0);
349 uint32_t headerWord1 = ReadUint32(readBuffer2, sizeUint32);
350
Sadik Armagan1625efc2021-06-10 18:24:34 +0100351 CHECK(((headerWord0 >> 26) & 0x3F) == 0); // packet family
352 CHECK(((headerWord0 >> 16) & 0x3FF) == 0); // packet id
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100353
Jim Flynn75c14f42022-03-10 22:05:42 +0000354 uint32_t totalLength = arm::pipe::numeric_cast<uint32_t>(2 * sizeUint32 +
Matthew Sloyan371b70e2020-09-11 10:14:57 +0100355 10 * sizeUint32 + infoSize +
356 hardwareVersionSize + softwareVersionSize +
357 processNameSize + sizeUint32 +
358 2 * packetEntries * sizeUint32);
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100359
Sadik Armagan1625efc2021-06-10 18:24:34 +0100360 CHECK(headerWord1 == totalLength - (2 * sizeUint32)); // data length
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100361
362 uint32_t offset = sizeUint32 * 2;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100363 CHECK(ReadUint32(readBuffer2, offset) == arm::pipe::PIPE_MAGIC); // pipe_magic
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100364 offset += sizeUint32;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100365 CHECK(ReadUint32(readBuffer2, offset) == arm::pipe::EncodeVersion(1, 0, 0)); // stream_metadata_version
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100366 offset += sizeUint32;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100367 CHECK(ReadUint32(readBuffer2, offset) == MAX_METADATA_PACKET_LENGTH); // max_data_len
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100368 offset += sizeUint32;
Rob Hughesbdee4262020-01-07 17:05:24 +0000369 int pid = armnnUtils::Processes::GetCurrentId();
Jim Flynn75c14f42022-03-10 22:05:42 +0000370 CHECK(ReadUint32(readBuffer2, offset) == arm::pipe::numeric_cast<uint32_t>(pid));
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100371 offset += sizeUint32;
372 uint32_t poolOffset = 10 * sizeUint32;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100373 CHECK(ReadUint32(readBuffer2, offset) == poolOffset); // offset_info
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100374 offset += sizeUint32;
375 poolOffset += infoSize;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100376 CHECK(ReadUint32(readBuffer2, offset) == poolOffset); // offset_hw_version
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100377 offset += sizeUint32;
378 poolOffset += hardwareVersionSize;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100379 CHECK(ReadUint32(readBuffer2, offset) == poolOffset); // offset_sw_version
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100380 offset += sizeUint32;
381 poolOffset += softwareVersionSize;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100382 CHECK(ReadUint32(readBuffer2, offset) == poolOffset); // offset_process_name
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100383 offset += sizeUint32;
384 poolOffset += processNameSize;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100385 CHECK(ReadUint32(readBuffer2, offset) == poolOffset); // offset_packet_version_table
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100386 offset += sizeUint32;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100387 CHECK(ReadUint32(readBuffer2, offset) == 0); // reserved
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100388
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100389 const unsigned char* readData2 = readBuffer2->GetReadableData();
390
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100391 offset += sizeUint32;
392 if (infoSize)
393 {
Sadik Armagan1625efc2021-06-10 18:24:34 +0100394 CHECK(strcmp(reinterpret_cast<const char *>(&readData2[offset]), GetSoftwareInfo().c_str()) == 0);
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100395 offset += infoSize;
396 }
397
398 if (hardwareVersionSize)
399 {
Sadik Armagan1625efc2021-06-10 18:24:34 +0100400 CHECK(strcmp(reinterpret_cast<const char *>(&readData2[offset]), GetHardwareVersion().c_str()) == 0);
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100401 offset += hardwareVersionSize;
402 }
403
404 if (softwareVersionSize)
405 {
Sadik Armagan1625efc2021-06-10 18:24:34 +0100406 CHECK(strcmp(reinterpret_cast<const char *>(&readData2[offset]), GetSoftwareVersion().c_str()) == 0);
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100407 offset += softwareVersionSize;
408 }
409
410 if (processNameSize)
411 {
Sadik Armagan1625efc2021-06-10 18:24:34 +0100412 CHECK(strcmp(reinterpret_cast<const char *>(&readData2[offset]), GetProcessName().c_str()) == 0);
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100413 offset += processNameSize;
414 }
415
416 if (packetEntries)
417 {
Jim Flynn83d08a92020-07-09 13:48:16 +0100418 uint32_t numberOfEntries = ReadUint32(readBuffer2, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100419 CHECK((numberOfEntries >> 16) == packetEntries);
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100420 offset += sizeUint32;
Jim Flynn83d08a92020-07-09 13:48:16 +0100421 for (std::pair<uint32_t, uint32_t>& packetVersion : packetVersions)
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100422 {
Jim Flynn83d08a92020-07-09 13:48:16 +0100423 uint32_t readPacketId = ReadUint32(readBuffer2, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100424 CHECK(packetVersion.first == readPacketId);
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100425 offset += sizeUint32;
Jim Flynn83d08a92020-07-09 13:48:16 +0100426 uint32_t readVersion = ReadUint32(readBuffer2, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100427 CHECK(packetVersion.second == readVersion);
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100428 offset += sizeUint32;
429 }
430 }
431
Sadik Armagan1625efc2021-06-10 18:24:34 +0100432 CHECK(offset == totalLength);
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100433}
434
Sadik Armagan1625efc2021-06-10 18:24:34 +0100435TEST_CASE("CreateDeviceRecordTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100436{
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100437 MockBufferManager mockBuffer(0);
Sadik Armagan3896b472020-02-10 12:24:15 +0000438 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100439
440 // Create a device for testing
441 uint16_t deviceUid = 27;
442 const std::string deviceName = "some_device";
443 uint16_t deviceCores = 3;
444 const DevicePtr device = std::make_unique<Device>(deviceUid, deviceName, deviceCores);
445
446 // Create a device record
447 SendCounterPacket::DeviceRecord deviceRecord;
448 std::string errorMessage;
449 bool result = sendCounterPacketTest.CreateDeviceRecordTest(device, deviceRecord, errorMessage);
450
Sadik Armagan1625efc2021-06-10 18:24:34 +0100451 CHECK(result);
452 CHECK(errorMessage.empty());
453 CHECK(deviceRecord.size() == 6); // Size in words: header [2] + device name [4]
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100454
455 uint16_t deviceRecordWord0[]
456 {
457 static_cast<uint16_t>(deviceRecord[0] >> 16),
458 static_cast<uint16_t>(deviceRecord[0])
459 };
Sadik Armagan1625efc2021-06-10 18:24:34 +0100460 CHECK(deviceRecordWord0[0] == deviceUid); // uid
461 CHECK(deviceRecordWord0[1] == deviceCores); // cores
462 CHECK(deviceRecord[1] == 8); // name_offset
463 CHECK(deviceRecord[2] == deviceName.size() + 1); // The length of the SWTrace string (name)
464 CHECK(std::memcmp(deviceRecord.data() + 3, deviceName.data(), deviceName.size()) == 0); // name
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100465}
466
Sadik Armagan1625efc2021-06-10 18:24:34 +0100467TEST_CASE("CreateInvalidDeviceRecordTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100468{
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100469 MockBufferManager mockBuffer(0);
Sadik Armagan3896b472020-02-10 12:24:15 +0000470 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100471
472 // Create a device for testing
473 uint16_t deviceUid = 27;
474 const std::string deviceName = "some€£invalid‡device";
475 uint16_t deviceCores = 3;
476 const DevicePtr device = std::make_unique<Device>(deviceUid, deviceName, deviceCores);
477
478 // Create a device record
479 SendCounterPacket::DeviceRecord deviceRecord;
480 std::string errorMessage;
481 bool result = sendCounterPacketTest.CreateDeviceRecordTest(device, deviceRecord, errorMessage);
482
Sadik Armagan1625efc2021-06-10 18:24:34 +0100483 CHECK(!result);
484 CHECK(!errorMessage.empty());
485 CHECK(deviceRecord.empty());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100486}
487
Sadik Armagan1625efc2021-06-10 18:24:34 +0100488TEST_CASE("CreateCounterSetRecordTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100489{
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100490 MockBufferManager mockBuffer(0);
Sadik Armagan3896b472020-02-10 12:24:15 +0000491 SendCounterPacketTest sendCounterPacketTest(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_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
Sadik Armagan1625efc2021-06-10 18:24:34 +0100504 CHECK(result);
505 CHECK(errorMessage.empty());
506 CHECK(counterSetRecord.size() == 8); // Size in words: header [2] + counter set name [6]
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100507
508 uint16_t counterSetRecordWord0[]
509 {
510 static_cast<uint16_t>(counterSetRecord[0] >> 16),
511 static_cast<uint16_t>(counterSetRecord[0])
512 };
Sadik Armagan1625efc2021-06-10 18:24:34 +0100513 CHECK(counterSetRecordWord0[0] == counterSetUid); // uid
514 CHECK(counterSetRecordWord0[1] == counterSetCount); // cores
515 CHECK(counterSetRecord[1] == 8); // name_offset
516 CHECK(counterSetRecord[2] == counterSetName.size() + 1); // The length of the SWTrace string (name)
517 CHECK(std::memcmp(counterSetRecord.data() + 3, counterSetName.data(), counterSetName.size()) == 0); // name
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100518}
519
Sadik Armagan1625efc2021-06-10 18:24:34 +0100520TEST_CASE("CreateInvalidCounterSetRecordTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100521{
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100522 MockBufferManager mockBuffer(0);
Sadik Armagan3896b472020-02-10 12:24:15 +0000523 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100524
525 // Create a counter set for testing
526 uint16_t counterSetUid = 27;
527 const std::string counterSetName = "some invalid_counter€£set";
528 uint16_t counterSetCount = 3421;
529 const CounterSetPtr counterSet = std::make_unique<CounterSet>(counterSetUid, counterSetName, counterSetCount);
530
531 // Create a counter set record
532 SendCounterPacket::CounterSetRecord counterSetRecord;
533 std::string errorMessage;
534 bool result = sendCounterPacketTest.CreateCounterSetRecordTest(counterSet, counterSetRecord, errorMessage);
535
Sadik Armagan1625efc2021-06-10 18:24:34 +0100536 CHECK(!result);
537 CHECK(!errorMessage.empty());
538 CHECK(counterSetRecord.empty());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100539}
540
Sadik Armagan1625efc2021-06-10 18:24:34 +0100541TEST_CASE("CreateEventRecordTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100542{
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100543 MockBufferManager mockBuffer(0);
Sadik Armagan3896b472020-02-10 12:24:15 +0000544 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100545
546 // Create a counter for testing
547 uint16_t counterUid = 7256;
548 uint16_t maxCounterUid = 132;
549 uint16_t deviceUid = 132;
550 uint16_t counterSetUid = 4497;
551 uint16_t counterClass = 1;
552 uint16_t counterInterpolation = 1;
553 double counterMultiplier = 1234.567f;
554 const std::string counterName = "some_valid_counter";
555 const std::string counterDescription = "a_counter_for_testing";
556 const std::string counterUnits = "Mrads2";
Keith Davise394bd92019-12-02 15:12:19 +0000557 const CounterPtr counter = std::make_unique<Counter>(armnn::profiling::BACKEND_ID,
558 counterUid,
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100559 maxCounterUid,
560 counterClass,
561 counterInterpolation,
562 counterMultiplier,
563 counterName,
564 counterDescription,
565 counterUnits,
566 deviceUid,
567 counterSetUid);
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100568 ARMNN_ASSERT(counter);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100569
570 // Create an event record
571 SendCounterPacket::EventRecord eventRecord;
572 std::string errorMessage;
573 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
574
Sadik Armagan1625efc2021-06-10 18:24:34 +0100575 CHECK(result);
576 CHECK(errorMessage.empty());
577 CHECK(eventRecord.size() == 24); // Size in words: header [8] + counter name [6] + description [7] + units [3]
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100578
579 uint16_t eventRecordWord0[]
580 {
581 static_cast<uint16_t>(eventRecord[0] >> 16),
582 static_cast<uint16_t>(eventRecord[0])
583 };
584 uint16_t eventRecordWord1[]
585 {
586 static_cast<uint16_t>(eventRecord[1] >> 16),
587 static_cast<uint16_t>(eventRecord[1])
588 };
589 uint16_t eventRecordWord2[]
590 {
591 static_cast<uint16_t>(eventRecord[2] >> 16),
592 static_cast<uint16_t>(eventRecord[2])
593 };
594 uint32_t eventRecordWord34[]
595 {
596 eventRecord[3],
597 eventRecord[4]
598 };
Finn Williamsd44815f2020-05-01 13:25:55 +0100599
Sadik Armagan1625efc2021-06-10 18:24:34 +0100600 CHECK(eventRecordWord0[0] == maxCounterUid); // max_counter_uid
601 CHECK(eventRecordWord0[1] == counterUid); // counter_uid
602 CHECK(eventRecordWord1[0] == deviceUid); // device
Finn Williamsd44815f2020-05-01 13:25:55 +0100603
Sadik Armagan1625efc2021-06-10 18:24:34 +0100604 CHECK(eventRecordWord1[1] == counterSetUid); // counter_set
605 CHECK(eventRecordWord2[0] == counterClass); // class
606 CHECK(eventRecordWord2[1] == counterInterpolation); // interpolation
607 CHECK(std::memcmp(eventRecordWord34, &counterMultiplier, sizeof(counterMultiplier)) == 0); // multiplier
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100608
609 ARMNN_NO_CONVERSION_WARN_BEGIN
Finn Williamsd44815f2020-05-01 13:25:55 +0100610 uint32_t eventRecordBlockSize = 8u * sizeof(uint32_t);
611 uint32_t counterNameOffset = eventRecordBlockSize; // The name is the first item in pool
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100612 uint32_t counterDescriptionOffset = counterNameOffset + // Counter name offset
613 4u + // Counter name length (uint32_t)
614 counterName.size() + // 18u
615 1u + // Null-terminator
616 1u; // Rounding to the next word
Finn Williamsd44815f2020-05-01 13:25:55 +0100617
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100618 size_t counterUnitsOffset = counterDescriptionOffset + // Counter description offset
619 4u + // Counter description length (uint32_t)
620 counterDescription.size() + // 21u
621 1u + // Null-terminator
Finn Williamsd44815f2020-05-01 13:25:55 +0100622 2u; // Rounding to the next word
623
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100624 ARMNN_NO_CONVERSION_WARN_END
625
Sadik Armagan1625efc2021-06-10 18:24:34 +0100626 CHECK(eventRecord[5] == counterNameOffset); // name_offset
627 CHECK(eventRecord[6] == counterDescriptionOffset); // description_offset
628 CHECK(eventRecord[7] == counterUnitsOffset); // units_offset
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100629
Finn Williamsd44815f2020-05-01 13:25:55 +0100630 // Offsets are relative to the start of the eventRecord
631 auto eventRecordPool = reinterpret_cast<unsigned char*>(eventRecord.data());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100632 size_t uint32_t_size = sizeof(uint32_t);
633
634 // The length of the SWTrace string (name)
Sadik Armagan1625efc2021-06-10 18:24:34 +0100635 CHECK(eventRecordPool[counterNameOffset] == counterName.size() + 1);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100636 // The counter name
Sadik Armagan1625efc2021-06-10 18:24:34 +0100637 CHECK(std::memcmp(eventRecordPool +
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100638 counterNameOffset + // Offset
639 uint32_t_size /* The length of the name */,
640 counterName.data(),
641 counterName.size()) == 0); // name
642 // The null-terminator at the end of the name
Sadik Armagan1625efc2021-06-10 18:24:34 +0100643 CHECK(eventRecordPool[counterNameOffset + uint32_t_size + counterName.size()] == '\0');
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100644
645 // The length of the SWTrace string (description)
Sadik Armagan1625efc2021-06-10 18:24:34 +0100646 CHECK(eventRecordPool[counterDescriptionOffset] == counterDescription.size() + 1);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100647 // The counter description
Sadik Armagan1625efc2021-06-10 18:24:34 +0100648 CHECK(std::memcmp(eventRecordPool +
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100649 counterDescriptionOffset + // Offset
650 uint32_t_size /* The length of the description */,
651 counterDescription.data(),
652 counterDescription.size()) == 0); // description
653 // The null-terminator at the end of the description
Sadik Armagan1625efc2021-06-10 18:24:34 +0100654 CHECK(eventRecordPool[counterDescriptionOffset + uint32_t_size + counterDescription.size()] == '\0');
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100655
656 // The length of the SWTrace namestring (units)
Sadik Armagan1625efc2021-06-10 18:24:34 +0100657 CHECK(eventRecordPool[counterUnitsOffset] == counterUnits.size() + 1);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100658 // The counter units
Sadik Armagan1625efc2021-06-10 18:24:34 +0100659 CHECK(std::memcmp(eventRecordPool +
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100660 counterUnitsOffset + // Offset
661 uint32_t_size /* The length of the units */,
662 counterUnits.data(),
663 counterUnits.size()) == 0); // units
664 // The null-terminator at the end of the units
Sadik Armagan1625efc2021-06-10 18:24:34 +0100665 CHECK(eventRecordPool[counterUnitsOffset + uint32_t_size + counterUnits.size()] == '\0');
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100666}
667
Sadik Armagan1625efc2021-06-10 18:24:34 +0100668TEST_CASE("CreateEventRecordNoUnitsTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100669{
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100670 MockBufferManager mockBuffer(0);
Sadik Armagan3896b472020-02-10 12:24:15 +0000671 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100672
673 // Create a counter for testing
674 uint16_t counterUid = 44312;
675 uint16_t maxCounterUid = 345;
676 uint16_t deviceUid = 101;
677 uint16_t counterSetUid = 34035;
678 uint16_t counterClass = 0;
679 uint16_t counterInterpolation = 1;
680 double counterMultiplier = 4435.0023f;
681 const std::string counterName = "some_valid_counter";
682 const std::string counterDescription = "a_counter_for_testing";
Keith Davise394bd92019-12-02 15:12:19 +0000683 const CounterPtr counter = std::make_unique<Counter>(armnn::profiling::BACKEND_ID,
684 counterUid,
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100685 maxCounterUid,
686 counterClass,
687 counterInterpolation,
688 counterMultiplier,
689 counterName,
690 counterDescription,
691 "",
692 deviceUid,
693 counterSetUid);
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100694 ARMNN_ASSERT(counter);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100695
696 // Create an event record
697 SendCounterPacket::EventRecord eventRecord;
698 std::string errorMessage;
699 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
700
Sadik Armagan1625efc2021-06-10 18:24:34 +0100701 CHECK(result);
702 CHECK(errorMessage.empty());
703 CHECK(eventRecord.size() == 21); // Size in words: header [8] + counter name [6] + description [7]
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100704
705 uint16_t eventRecordWord0[]
706 {
707 static_cast<uint16_t>(eventRecord[0] >> 16),
708 static_cast<uint16_t>(eventRecord[0])
709 };
710 uint16_t eventRecordWord1[]
711 {
712 static_cast<uint16_t>(eventRecord[1] >> 16),
713 static_cast<uint16_t>(eventRecord[1])
714 };
715 uint16_t eventRecordWord2[]
716 {
717 static_cast<uint16_t>(eventRecord[2] >> 16),
718 static_cast<uint16_t>(eventRecord[2])
719 };
720 uint32_t eventRecordWord34[]
721 {
722 eventRecord[3],
723 eventRecord[4]
724 };
Sadik Armagan1625efc2021-06-10 18:24:34 +0100725 CHECK(eventRecordWord0[0] == maxCounterUid); // max_counter_uid
726 CHECK(eventRecordWord0[1] == counterUid); // counter_uid
727 CHECK(eventRecordWord1[0] == deviceUid); // device
728 CHECK(eventRecordWord1[1] == counterSetUid); // counter_set
729 CHECK(eventRecordWord2[0] == counterClass); // class
730 CHECK(eventRecordWord2[1] == counterInterpolation); // interpolation
731 CHECK(std::memcmp(eventRecordWord34, &counterMultiplier, sizeof(counterMultiplier)) == 0); // multiplier
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100732
733 ARMNN_NO_CONVERSION_WARN_BEGIN
Finn Williamsd44815f2020-05-01 13:25:55 +0100734 uint32_t eventRecordBlockSize = 8u * sizeof(uint32_t);
735 uint32_t counterNameOffset = eventRecordBlockSize; // The name is the first item in pool
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100736 uint32_t counterDescriptionOffset = counterNameOffset + // Counter name offset
737 4u + // Counter name length (uint32_t)
738 counterName.size() + // 18u
739 1u + // Null-terminator
740 1u; // Rounding to the next word
741 ARMNN_NO_CONVERSION_WARN_END
742
Sadik Armagan1625efc2021-06-10 18:24:34 +0100743 CHECK(eventRecord[5] == counterNameOffset); // name_offset
744 CHECK(eventRecord[6] == counterDescriptionOffset); // description_offset
745 CHECK(eventRecord[7] == 0); // units_offset
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100746
Finn Williamsd44815f2020-05-01 13:25:55 +0100747 // Offsets are relative to the start of the eventRecord
748 auto eventRecordPool = reinterpret_cast<unsigned char*>(eventRecord.data());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100749 size_t uint32_t_size = sizeof(uint32_t);
750
751 // The length of the SWTrace string (name)
Sadik Armagan1625efc2021-06-10 18:24:34 +0100752 CHECK(eventRecordPool[counterNameOffset] == counterName.size() + 1);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100753 // The counter name
Sadik Armagan1625efc2021-06-10 18:24:34 +0100754 CHECK(std::memcmp(eventRecordPool +
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100755 counterNameOffset + // Offset
756 uint32_t_size, // The length of the name
757 counterName.data(),
758 counterName.size()) == 0); // name
759 // The null-terminator at the end of the name
Sadik Armagan1625efc2021-06-10 18:24:34 +0100760 CHECK(eventRecordPool[counterNameOffset + uint32_t_size + counterName.size()] == '\0');
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100761
762 // The length of the SWTrace string (description)
Sadik Armagan1625efc2021-06-10 18:24:34 +0100763 CHECK(eventRecordPool[counterDescriptionOffset] == counterDescription.size() + 1);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100764 // The counter description
Sadik Armagan1625efc2021-06-10 18:24:34 +0100765 CHECK(std::memcmp(eventRecordPool +
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100766 counterDescriptionOffset + // Offset
767 uint32_t_size, // The length of the description
768 counterDescription.data(),
769 counterDescription.size()) == 0); // description
770 // The null-terminator at the end of the description
Sadik Armagan1625efc2021-06-10 18:24:34 +0100771 CHECK(eventRecordPool[counterDescriptionOffset + uint32_t_size + counterDescription.size()] == '\0');
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100772}
773
Sadik Armagan1625efc2021-06-10 18:24:34 +0100774TEST_CASE("CreateInvalidEventRecordTest1")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100775{
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100776 MockBufferManager mockBuffer(0);
Sadik Armagan3896b472020-02-10 12:24:15 +0000777 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100778
779 // Create a counter for testing
780 uint16_t counterUid = 7256;
781 uint16_t maxCounterUid = 132;
782 uint16_t deviceUid = 132;
783 uint16_t counterSetUid = 4497;
784 uint16_t counterClass = 1;
785 uint16_t counterInterpolation = 1;
786 double counterMultiplier = 1234.567f;
787 const std::string counterName = "some_invalid_counter £££"; // Invalid name
788 const std::string counterDescription = "a_counter_for_testing";
789 const std::string counterUnits = "Mrads2";
Keith Davise394bd92019-12-02 15:12:19 +0000790 const CounterPtr counter = std::make_unique<Counter>(armnn::profiling::BACKEND_ID,
791 counterUid,
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100792 maxCounterUid,
793 counterClass,
794 counterInterpolation,
795 counterMultiplier,
796 counterName,
797 counterDescription,
798 counterUnits,
799 deviceUid,
800 counterSetUid);
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100801 ARMNN_ASSERT(counter);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100802
803 // Create an event record
804 SendCounterPacket::EventRecord eventRecord;
805 std::string errorMessage;
806 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
807
Sadik Armagan1625efc2021-06-10 18:24:34 +0100808 CHECK(!result);
809 CHECK(!errorMessage.empty());
810 CHECK(eventRecord.empty());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100811}
812
Sadik Armagan1625efc2021-06-10 18:24:34 +0100813TEST_CASE("CreateInvalidEventRecordTest2")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100814{
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100815 MockBufferManager mockBuffer(0);
Sadik Armagan3896b472020-02-10 12:24:15 +0000816 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100817
818 // Create a counter for testing
819 uint16_t counterUid = 7256;
820 uint16_t maxCounterUid = 132;
821 uint16_t deviceUid = 132;
822 uint16_t counterSetUid = 4497;
823 uint16_t counterClass = 1;
824 uint16_t counterInterpolation = 1;
825 double counterMultiplier = 1234.567f;
826 const std::string counterName = "some_invalid_counter";
827 const std::string counterDescription = "an invalid d€scription"; // Invalid description
828 const std::string counterUnits = "Mrads2";
Keith Davise394bd92019-12-02 15:12:19 +0000829 const CounterPtr counter = std::make_unique<Counter>(armnn::profiling::BACKEND_ID,
830 counterUid,
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100831 maxCounterUid,
832 counterClass,
833 counterInterpolation,
834 counterMultiplier,
835 counterName,
836 counterDescription,
837 counterUnits,
838 deviceUid,
839 counterSetUid);
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100840 ARMNN_ASSERT(counter);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100841
842 // Create an event record
843 SendCounterPacket::EventRecord eventRecord;
844 std::string errorMessage;
845 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
846
Sadik Armagan1625efc2021-06-10 18:24:34 +0100847 CHECK(!result);
848 CHECK(!errorMessage.empty());
849 CHECK(eventRecord.empty());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100850}
851
Sadik Armagan1625efc2021-06-10 18:24:34 +0100852TEST_CASE("CreateInvalidEventRecordTest3")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100853{
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100854 MockBufferManager mockBuffer(0);
Sadik Armagan3896b472020-02-10 12:24:15 +0000855 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100856
857 // Create a counter for testing
858 uint16_t counterUid = 7256;
859 uint16_t maxCounterUid = 132;
860 uint16_t deviceUid = 132;
861 uint16_t counterSetUid = 4497;
862 uint16_t counterClass = 1;
863 uint16_t counterInterpolation = 1;
864 double counterMultiplier = 1234.567f;
865 const std::string counterName = "some_invalid_counter";
866 const std::string counterDescription = "a valid description";
867 const std::string counterUnits = "Mrad s2"; // Invalid units
Keith Davise394bd92019-12-02 15:12:19 +0000868 const CounterPtr counter = std::make_unique<Counter>(armnn::profiling::BACKEND_ID,
869 counterUid,
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100870 maxCounterUid,
871 counterClass,
872 counterInterpolation,
873 counterMultiplier,
874 counterName,
875 counterDescription,
876 counterUnits,
877 deviceUid,
878 counterSetUid);
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100879 ARMNN_ASSERT(counter);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100880
881 // Create an event record
882 SendCounterPacket::EventRecord eventRecord;
883 std::string errorMessage;
884 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
885
Sadik Armagan1625efc2021-06-10 18:24:34 +0100886 CHECK(!result);
887 CHECK(!errorMessage.empty());
888 CHECK(eventRecord.empty());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100889}
890
Sadik Armagan1625efc2021-06-10 18:24:34 +0100891TEST_CASE("CreateCategoryRecordTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100892{
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100893 MockBufferManager mockBuffer(0);
Sadik Armagan3896b472020-02-10 12:24:15 +0000894 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100895
896 // Create a category for testing
897 const std::string categoryName = "some_category";
Sadik Armagan4c998992020-02-25 12:44:44 +0000898 const CategoryPtr category = std::make_unique<Category>(categoryName);
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100899 ARMNN_ASSERT(category);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100900 category->m_Counters = { 11u, 23u, 5670u };
901
902 // Create a collection of counters
903 Counters counters;
904 counters.insert(std::make_pair<uint16_t, CounterPtr>(11,
Keith Davise394bd92019-12-02 15:12:19 +0000905 CounterPtr(new Counter(armnn::profiling::BACKEND_ID,
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100906 0,
Keith Davise394bd92019-12-02 15:12:19 +0000907 11,
908 0,
909 0,
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100910 534.0003f,
911 "counter1",
912 "the first counter",
913 "millipi2",
914 0,
915 0))));
916 counters.insert(std::make_pair<uint16_t, CounterPtr>(23,
Keith Davise394bd92019-12-02 15:12:19 +0000917 CounterPtr(new Counter(armnn::profiling::BACKEND_ID,
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100918 1,
Keith Davise394bd92019-12-02 15:12:19 +0000919 23,
920 0,
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100921 1,
922 534.0003f,
923 "this is counter 2",
924 "the second counter",
925 "",
926 0,
927 0))));
928 counters.insert(std::make_pair<uint16_t, CounterPtr>(5670,
Keith Davise394bd92019-12-02 15:12:19 +0000929 CounterPtr(new Counter(armnn::profiling::BACKEND_ID,
930 2,
931 5670,
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100932 0,
933 0,
934 534.0003f,
935 "and this is number 3",
936 "the third counter",
937 "blah_per_second",
938 0,
939 0))));
940 Counter* counter1 = counters.find(11)->second.get();
941 Counter* counter2 = counters.find(23)->second.get();
942 Counter* counter3 = counters.find(5670)->second.get();
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100943 ARMNN_ASSERT(counter1);
944 ARMNN_ASSERT(counter2);
945 ARMNN_ASSERT(counter3);
Jim Flynn75c14f42022-03-10 22:05:42 +0000946 uint16_t categoryEventCount = arm::pipe::numeric_cast<uint16_t>(counters.size());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100947
948 // Create a category record
949 SendCounterPacket::CategoryRecord categoryRecord;
950 std::string errorMessage;
951 bool result = sendCounterPacketTest.CreateCategoryRecordTest(category, counters, categoryRecord, errorMessage);
952
Sadik Armagan1625efc2021-06-10 18:24:34 +0100953 CHECK(result);
954 CHECK(errorMessage.empty());
955 CHECK(categoryRecord.size() == 79); // Size in words: header [3] + event pointer table [3] +
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100956 // category name [5] + event records [68 = 22 + 20 + 26]
957
Sadik Armagan4c998992020-02-25 12:44:44 +0000958 uint16_t categoryRecordWord1[]
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100959 {
960 static_cast<uint16_t>(categoryRecord[0] >> 16),
961 static_cast<uint16_t>(categoryRecord[0])
962 };
Sadik Armagan1625efc2021-06-10 18:24:34 +0100963 CHECK(categoryRecordWord1[0] == categoryEventCount); // event_count
964 CHECK(categoryRecordWord1[1] == 0); // reserved
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100965
966 size_t uint32_t_size = sizeof(uint32_t);
967
968 ARMNN_NO_CONVERSION_WARN_BEGIN
Finn Williamsd44815f2020-05-01 13:25:55 +0100969 uint32_t categoryRecordBlockSize = 3u * uint32_t_size;
970 uint32_t eventPointerTableOffset = categoryRecordBlockSize; // The event pointer table is the first item in pool
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100971 uint32_t categoryNameOffset = eventPointerTableOffset + // Event pointer table offset
972 categoryEventCount * uint32_t_size; // The size of the event pointer table
973 ARMNN_NO_CONVERSION_WARN_END
974
Sadik Armagan1625efc2021-06-10 18:24:34 +0100975 CHECK(categoryRecord[1] == eventPointerTableOffset); // event_pointer_table_offset
976 CHECK(categoryRecord[2] == categoryNameOffset); // name_offset
Finn Williamsd44815f2020-05-01 13:25:55 +0100977 // Offsets are relative to the start of the category record
978 auto categoryRecordPool = reinterpret_cast<unsigned char*>(categoryRecord.data());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100979
980 // The event pointer table
981 uint32_t eventRecord0Offset = categoryRecordPool[eventPointerTableOffset + 0 * uint32_t_size];
982 uint32_t eventRecord1Offset = categoryRecordPool[eventPointerTableOffset + 1 * uint32_t_size];
983 uint32_t eventRecord2Offset = categoryRecordPool[eventPointerTableOffset + 2 * uint32_t_size];
Sadik Armagan1625efc2021-06-10 18:24:34 +0100984 CHECK(eventRecord0Offset == 32);
985 CHECK(eventRecord1Offset == 120);
986 CHECK(eventRecord2Offset == 200);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100987
988 // The length of the SWTrace namestring (name)
Sadik Armagan1625efc2021-06-10 18:24:34 +0100989 CHECK(categoryRecordPool[categoryNameOffset] == categoryName.size() + 1);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100990 // The category name
Sadik Armagan1625efc2021-06-10 18:24:34 +0100991 CHECK(std::memcmp(categoryRecordPool +
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100992 categoryNameOffset + // Offset
993 uint32_t_size, // The length of the name
994 categoryName.data(),
995 categoryName.size()) == 0); // name
996 // The null-terminator at the end of the name
Sadik Armagan1625efc2021-06-10 18:24:34 +0100997 CHECK(categoryRecordPool[categoryNameOffset + uint32_t_size + categoryName.size()] == '\0');
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100998
999 // For brevity, checking only the UIDs, max counter UIDs and names of the counters in the event records,
1000 // as the event records already have a number of unit tests dedicated to them
1001
1002 // Counter1 UID and max counter UID
1003 uint16_t eventRecord0Word0[2] = { 0u, 0u };
Finn Williamsd44815f2020-05-01 13:25:55 +01001004 std::memcpy(eventRecord0Word0, categoryRecordPool + categoryRecordBlockSize + eventRecord0Offset,
1005 sizeof(eventRecord0Word0));
Sadik Armagan1625efc2021-06-10 18:24:34 +01001006 CHECK(eventRecord0Word0[0] == counter1->m_Uid);
1007 CHECK(eventRecord0Word0[1] == counter1->m_MaxCounterUid);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001008
1009 // Counter1 name
1010 uint32_t counter1NameOffset = 0;
Finn Williamsd44815f2020-05-01 13:25:55 +01001011 std::memcpy(&counter1NameOffset, categoryRecordPool + eventRecord0Offset + 5u * uint32_t_size, uint32_t_size);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001012 CHECK(counter1NameOffset == 0);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001013 // The length of the SWTrace string (name)
Sadik Armagan1625efc2021-06-10 18:24:34 +01001014 CHECK(categoryRecordPool[eventRecord0Offset + // Offset to the event record
Finn Williamsd44815f2020-05-01 13:25:55 +01001015 categoryRecordBlockSize + // Offset to the end of the category record block
1016 8u * uint32_t_size + // Offset to the event record pool
1017 counter1NameOffset // Offset to the name of the counter
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001018 ] == counter1->m_Name.size() + 1); // The length of the name including the
1019 // null-terminator
1020 // The counter1 name
Sadik Armagan1625efc2021-06-10 18:24:34 +01001021 CHECK(std::memcmp(categoryRecordPool + // The beginning of the category pool
Finn Williamsd44815f2020-05-01 13:25:55 +01001022 categoryRecordBlockSize + // Offset to the end of the category record block
1023 eventRecord0Offset + // Offset to the event record
1024 8u * uint32_t_size + // Offset to the event record pool
1025 counter1NameOffset + // Offset to the name of the counter
1026 uint32_t_size, // The length of the name
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001027 counter1->m_Name.data(),
1028 counter1->m_Name.size()) == 0); // name
1029 // The null-terminator at the end of the counter1 name
Sadik Armagan1625efc2021-06-10 18:24:34 +01001030 CHECK(categoryRecordPool[eventRecord0Offset + // Offset to the event record
Finn Williamsd44815f2020-05-01 13:25:55 +01001031 categoryRecordBlockSize + // Offset to the end of the category record block
1032 8u * uint32_t_size + // Offset to the event record pool
1033 counter1NameOffset + // Offset to the name of the counter
1034 uint32_t_size + // The length of the name
1035 counter1->m_Name.size() // The name of the counter
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001036 ] == '\0');
1037
1038 // Counter2 name
1039 uint32_t counter2NameOffset = 0;
Finn Williamsd44815f2020-05-01 13:25:55 +01001040 std::memcpy(&counter2NameOffset, categoryRecordPool +
1041 categoryRecordBlockSize +
1042 eventRecord1Offset +
1043 5u * uint32_t_size,
1044 uint32_t_size);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001045 CHECK(counter2NameOffset == 8u * uint32_t_size );
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001046 // The length of the SWTrace string (name)
Finn Williamsd44815f2020-05-01 13:25:55 +01001047
Sadik Armagan1625efc2021-06-10 18:24:34 +01001048 CHECK(categoryRecordPool[eventRecord1Offset + // Offset to the event record
Finn Williamsd44815f2020-05-01 13:25:55 +01001049 categoryRecordBlockSize +
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001050 counter2NameOffset // Offset to the name of the counter
1051 ] == counter2->m_Name.size() + 1); // The length of the name including the
1052 // null-terminator
1053 // The counter2 name
Sadik Armagan1625efc2021-06-10 18:24:34 +01001054 CHECK(std::memcmp(categoryRecordPool + // The beginning of the category pool
Finn Williamsd44815f2020-05-01 13:25:55 +01001055 categoryRecordBlockSize + // Offset to the end of the category record block
1056 eventRecord1Offset + // Offset to the event record
1057 counter2NameOffset + // Offset to the name of the counter
1058 uint32_t_size, // The length of the name
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001059 counter2->m_Name.data(),
1060 counter2->m_Name.size()) == 0); // name
Finn Williamsd44815f2020-05-01 13:25:55 +01001061
1062
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001063 // The null-terminator at the end of the counter2 name
Sadik Armagan1625efc2021-06-10 18:24:34 +01001064 CHECK(categoryRecordPool[eventRecord1Offset + // Offset to the event record
Finn Williamsd44815f2020-05-01 13:25:55 +01001065 categoryRecordBlockSize + // Offset to the end of the category record block
1066 counter2NameOffset + // Offset to the name of the counter
1067 uint32_t_size + // The length of the name
1068 counter2->m_Name.size() // The name of the counter
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001069 ] == '\0');
1070
1071 // Counter3 name
1072 uint32_t counter3NameOffset = 0;
1073 std::memcpy(&counter3NameOffset, categoryRecordPool + eventRecord2Offset + 5u * uint32_t_size, uint32_t_size);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001074 CHECK(counter3NameOffset == 0);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001075 // The length of the SWTrace string (name)
Sadik Armagan1625efc2021-06-10 18:24:34 +01001076 CHECK(categoryRecordPool[eventRecord2Offset + // Offset to the event record
Finn Williamsd44815f2020-05-01 13:25:55 +01001077 categoryRecordBlockSize +
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001078 8u * uint32_t_size + // Offset to the event record pool
1079 counter3NameOffset // Offset to the name of the counter
1080 ] == counter3->m_Name.size() + 1); // The length of the name including the
1081 // null-terminator
1082 // The counter3 name
Sadik Armagan1625efc2021-06-10 18:24:34 +01001083 CHECK(std::memcmp(categoryRecordPool + // The beginning of the category pool
Finn Williamsd44815f2020-05-01 13:25:55 +01001084 categoryRecordBlockSize +
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001085 eventRecord2Offset + // Offset to the event record
1086 8u * uint32_t_size + // Offset to the event record pool
1087 counter3NameOffset + // Offset to the name of the counter
1088 uint32_t_size, // The length of the name
1089 counter3->m_Name.data(),
1090 counter3->m_Name.size()) == 0); // name
1091 // The null-terminator at the end of the counter3 name
Sadik Armagan1625efc2021-06-10 18:24:34 +01001092 CHECK(categoryRecordPool[eventRecord2Offset + // Offset to the event record
Finn Williamsd44815f2020-05-01 13:25:55 +01001093 categoryRecordBlockSize +
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001094 8u * uint32_t_size + // Offset to the event record pool
1095 counter3NameOffset + // Offset to the name of the counter
1096 uint32_t_size + // The length of the name
1097 counter3->m_Name.size() // The name of the counter
1098 ] == '\0');
1099}
1100
Sadik Armagan1625efc2021-06-10 18:24:34 +01001101TEST_CASE("CreateInvalidCategoryRecordTest1")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001102{
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001103 MockBufferManager mockBuffer(0);
Sadik Armagan3896b472020-02-10 12:24:15 +00001104 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001105
1106 // Create a category for testing
1107 const std::string categoryName = "some invalid category";
Sadik Armagan4c998992020-02-25 12:44:44 +00001108 const CategoryPtr category = std::make_unique<Category>(categoryName);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001109 CHECK(category);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001110
1111 // Create a category record
1112 Counters counters;
1113 SendCounterPacket::CategoryRecord categoryRecord;
1114 std::string errorMessage;
1115 bool result = sendCounterPacketTest.CreateCategoryRecordTest(category, counters, categoryRecord, errorMessage);
1116
Sadik Armagan1625efc2021-06-10 18:24:34 +01001117 CHECK(!result);
1118 CHECK(!errorMessage.empty());
1119 CHECK(categoryRecord.empty());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001120}
1121
Sadik Armagan1625efc2021-06-10 18:24:34 +01001122TEST_CASE("CreateInvalidCategoryRecordTest2")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001123{
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001124 MockBufferManager mockBuffer(0);
Sadik Armagan3896b472020-02-10 12:24:15 +00001125 SendCounterPacketTest sendCounterPacketTest(mockBuffer);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001126
1127 // Create a category for testing
1128 const std::string categoryName = "some_category";
Sadik Armagan4c998992020-02-25 12:44:44 +00001129 const CategoryPtr category = std::make_unique<Category>(categoryName);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001130 CHECK(category);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001131 category->m_Counters = { 11u, 23u, 5670u };
1132
1133 // Create a collection of counters
1134 Counters counters;
1135 counters.insert(std::make_pair<uint16_t, CounterPtr>(11,
Keith Davise394bd92019-12-02 15:12:19 +00001136 CounterPtr(new Counter(armnn::profiling::BACKEND_ID,
1137 11,
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001138 1234,
1139 0,
1140 1,
1141 534.0003f,
1142 "count€r1", // Invalid name
1143 "the first counter",
1144 "millipi2",
1145 0,
1146 0))));
1147
1148 Counter* counter1 = counters.find(11)->second.get();
Sadik Armagan1625efc2021-06-10 18:24:34 +01001149 CHECK(counter1);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001150
1151 // Create a category record
1152 SendCounterPacket::CategoryRecord categoryRecord;
1153 std::string errorMessage;
1154 bool result = sendCounterPacketTest.CreateCategoryRecordTest(category, counters, categoryRecord, errorMessage);
1155
Sadik Armagan1625efc2021-06-10 18:24:34 +01001156 CHECK(!result);
1157 CHECK(!errorMessage.empty());
1158 CHECK(categoryRecord.empty());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001159}
1160
Sadik Armagan1625efc2021-06-10 18:24:34 +01001161TEST_CASE("SendCounterDirectoryPacketTest1")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001162{
1163 // The counter directory used for testing
1164 CounterDirectory counterDirectory;
1165
1166 // Register a device
1167 const std::string device1Name = "device1";
1168 const Device* device1 = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001169 CHECK_NOTHROW(device1 = counterDirectory.RegisterDevice(device1Name, 3));
1170 CHECK(counterDirectory.GetDeviceCount() == 1);
1171 CHECK(device1);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001172
1173 // Register a device
1174 const std::string device2Name = "device2";
1175 const Device* device2 = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001176 CHECK_NOTHROW(device2 = counterDirectory.RegisterDevice(device2Name));
1177 CHECK(counterDirectory.GetDeviceCount() == 2);
1178 CHECK(device2);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001179
1180 // Buffer with not enough space
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001181 MockBufferManager mockBuffer(10);
Sadik Armagan3896b472020-02-10 12:24:15 +00001182 SendCounterPacket sendCounterPacket(mockBuffer);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001183 CHECK_THROWS_AS(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001184 BufferExhaustion);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001185}
1186
Sadik Armagan1625efc2021-06-10 18:24:34 +01001187TEST_CASE("SendCounterDirectoryPacketTest2")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001188{
1189 // The counter directory used for testing
1190 CounterDirectory counterDirectory;
1191
1192 // Register a device
1193 const std::string device1Name = "device1";
1194 const Device* device1 = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001195 CHECK_NOTHROW(device1 = counterDirectory.RegisterDevice(device1Name, 3));
1196 CHECK(counterDirectory.GetDeviceCount() == 1);
1197 CHECK(device1);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001198
1199 // Register a device
1200 const std::string device2Name = "device2";
1201 const Device* device2 = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001202 CHECK_NOTHROW(device2 = counterDirectory.RegisterDevice(device2Name));
1203 CHECK(counterDirectory.GetDeviceCount() == 2);
1204 CHECK(device2);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001205
1206 // Register a counter set
1207 const std::string counterSet1Name = "counterset1";
1208 const CounterSet* counterSet1 = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001209 CHECK_NOTHROW(counterSet1 = counterDirectory.RegisterCounterSet(counterSet1Name));
1210 CHECK(counterDirectory.GetCounterSetCount() == 1);
1211 CHECK(counterSet1);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001212
1213 // Register a category associated to "device1" and "counterset1"
1214 const std::string category1Name = "category1";
1215 const Category* category1 = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001216 CHECK_NOTHROW(category1 = counterDirectory.RegisterCategory(category1Name));
1217 CHECK(counterDirectory.GetCategoryCount() == 1);
1218 CHECK(category1);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001219
1220 // Register a category not associated to "device2" but no counter set
1221 const std::string category2Name = "category2";
1222 const Category* category2 = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001223 CHECK_NOTHROW(category2 = counterDirectory.RegisterCategory(category2Name));
1224 CHECK(counterDirectory.GetCategoryCount() == 2);
1225 CHECK(category2);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001226
Keith Davis33ed2212020-03-30 10:43:41 +01001227 uint16_t numberOfCores = 4;
Sadik Armagan4c998992020-02-25 12:44:44 +00001228
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001229 // Register a counter associated to "category1"
1230 const Counter* counter1 = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001231 CHECK_NOTHROW(counter1 = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001232 0,
1233 category1Name,
1234 0,
1235 1,
1236 123.45f,
1237 "counter1",
1238 "counter1description",
1239 std::string("counter1units"),
1240 numberOfCores));
Sadik Armagan1625efc2021-06-10 18:24:34 +01001241 CHECK(counterDirectory.GetCounterCount() == 4);
1242 CHECK(counter1);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001243
1244 // Register a counter associated to "category1"
1245 const Counter* counter2 = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001246 CHECK_NOTHROW(counter2 = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001247 4,
1248 category1Name,
1249 1,
1250 0,
1251 330.1245656765f,
1252 "counter2",
1253 "counter2description",
1254 std::string("counter2units"),
1255 armnn::EmptyOptional(),
1256 device2->m_Uid,
1257 0));
Sadik Armagan1625efc2021-06-10 18:24:34 +01001258 CHECK(counterDirectory.GetCounterCount() == 5);
1259 CHECK(counter2);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001260
1261 // Register a counter associated to "category2"
1262 const Counter* counter3 = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001263 CHECK_NOTHROW(counter3 = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001264 5,
1265 category2Name,
1266 1,
1267 1,
1268 0.0000045399f,
1269 "counter3",
1270 "counter3description",
1271 armnn::EmptyOptional(),
1272 numberOfCores,
1273 device2->m_Uid,
1274 counterSet1->m_Uid));
Sadik Armagan1625efc2021-06-10 18:24:34 +01001275 CHECK(counterDirectory.GetCounterCount() == 9);
1276 CHECK(counter3);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001277
1278 // Buffer with enough space
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001279 MockBufferManager mockBuffer(1024);
Sadik Armagan3896b472020-02-10 12:24:15 +00001280 SendCounterPacket sendCounterPacket(mockBuffer);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001281 CHECK_NOTHROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001282
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001283 // Get the readable buffer
1284 auto readBuffer = mockBuffer.GetReadableBuffer();
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001285
1286 // Check the packet header
Finn Williams985fecf2020-04-30 11:06:43 +01001287 const uint32_t packetHeaderWord0 = ReadUint32(readBuffer, 0);
1288 const uint32_t packetHeaderWord1 = ReadUint32(readBuffer, 4);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001289 CHECK(((packetHeaderWord0 >> 26) & 0x3F) == 0); // packet_family
1290 CHECK(((packetHeaderWord0 >> 16) & 0x3FF) == 2); // packet_id
1291 CHECK(packetHeaderWord1 == 432); // data_length
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001292
1293 // Check the body header
Finn Williams985fecf2020-04-30 11:06:43 +01001294 const uint32_t bodyHeaderWord0 = ReadUint32(readBuffer, 8);
1295 const uint32_t bodyHeaderWord1 = ReadUint32(readBuffer, 12);
1296 const uint32_t bodyHeaderWord2 = ReadUint32(readBuffer, 16);
1297 const uint32_t bodyHeaderWord3 = ReadUint32(readBuffer, 20);
1298 const uint32_t bodyHeaderWord4 = ReadUint32(readBuffer, 24);
1299 const uint32_t bodyHeaderWord5 = ReadUint32(readBuffer, 28);
1300 const uint16_t deviceRecordCount = static_cast<uint16_t>(bodyHeaderWord0 >> 16);
1301 const uint16_t counterSetRecordCount = static_cast<uint16_t>(bodyHeaderWord2 >> 16);
1302 const uint16_t categoryRecordCount = static_cast<uint16_t>(bodyHeaderWord4 >> 16);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001303 CHECK(deviceRecordCount == 2); // device_records_count
1304 CHECK(bodyHeaderWord1 == bodyHeaderSize * 4); // device_records_pointer_table_offset
1305 CHECK(counterSetRecordCount == 1); // counter_set_count
1306 CHECK(bodyHeaderWord3 == 8 + bodyHeaderSize * 4); // counter_set_pointer_table_offset
1307 CHECK(categoryRecordCount == 2); // categories_count
1308 CHECK(bodyHeaderWord5 == 12 + bodyHeaderSize * 4); // categories_pointer_table_offset
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001309
1310 // Check the device records pointer table
Finn Williams985fecf2020-04-30 11:06:43 +01001311 const uint32_t deviceRecordOffset0 = ReadUint32(readBuffer, 32);
1312 const uint32_t deviceRecordOffset1 = ReadUint32(readBuffer, 36);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001313 CHECK(deviceRecordOffset0 == 20); // Device record offset for "device1"
1314 CHECK(deviceRecordOffset1 == 40); // Device record offset for "device2"
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001315
1316 // Check the counter set pointer table
Finn Williams985fecf2020-04-30 11:06:43 +01001317 const uint32_t counterSetRecordOffset0 = ReadUint32(readBuffer, 40);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001318 CHECK(counterSetRecordOffset0 == 52); // Counter set record offset for "counterset1"
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001319
1320 // Check the category pointer table
Finn Williams985fecf2020-04-30 11:06:43 +01001321 const uint32_t categoryRecordOffset0 = ReadUint32(readBuffer, 44);
1322 const uint32_t categoryRecordOffset1 = ReadUint32(readBuffer, 48);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001323 CHECK(categoryRecordOffset0 == 72); // Category record offset for "category1"
1324 CHECK(categoryRecordOffset1 == 176); // Category record offset for "category2"
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001325
1326 // Get the device record pool offset
Finn Williams985fecf2020-04-30 11:06:43 +01001327 const uint32_t uint32_t_size = sizeof(uint32_t);
Finn Williamsd44815f2020-05-01 13:25:55 +01001328 const uint32_t packetHeaderSize = 2u * uint32_t_size;
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001329
1330 // Device record structure/collection used for testing
1331 struct DeviceRecord
1332 {
1333 uint16_t uid;
1334 uint16_t cores;
1335 uint32_t name_offset;
1336 uint32_t name_length;
1337 std::string name;
1338 };
1339 std::vector<DeviceRecord> deviceRecords;
Finn Williamsd44815f2020-05-01 13:25:55 +01001340 const uint32_t deviceRecordsPointerTableOffset = packetHeaderSize +
Finn Williams985fecf2020-04-30 11:06:43 +01001341 bodyHeaderWord1; // device_records_pointer_table_offset
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001342
1343 const unsigned char* readData = readBuffer->GetReadableData();
1344
Finn Williamsd44815f2020-05-01 13:25:55 +01001345 uint32_t offset = 0;
1346 std::vector<uint32_t> data(800);
1347
1348 for (uint32_t i = 0; i < 800; i+=uint32_t_size)
1349 {
1350 data[i] = ReadUint32(readBuffer, offset);
1351 offset += uint32_t_size;
1352 }
1353
1354 std::vector<uint32_t> deviceRecordOffsets(deviceRecordCount);
1355 offset = deviceRecordsPointerTableOffset;
1356 for (uint32_t i = 0; i < deviceRecordCount; ++i)
1357 {
1358 // deviceRecordOffset is relative to the start of the deviceRecordsPointerTable
1359 deviceRecordOffsets[i] = ReadUint32(readBuffer, offset) + deviceRecordsPointerTableOffset;
1360 offset += uint32_t_size;
1361 }
1362
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001363 for (uint32_t i = 0; i < deviceRecordCount; i++)
1364 {
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001365 // Collect the data for the device record
Finn Williamsd44815f2020-05-01 13:25:55 +01001366 const uint32_t deviceRecordWord0 = ReadUint32(readBuffer, deviceRecordOffsets[i] + 0 * uint32_t_size);
1367 const uint32_t deviceRecordWord1 = ReadUint32(readBuffer, deviceRecordOffsets[i] + 1 * uint32_t_size);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001368 DeviceRecord deviceRecord;
1369 deviceRecord.uid = static_cast<uint16_t>(deviceRecordWord0 >> 16); // uid
1370 deviceRecord.cores = static_cast<uint16_t>(deviceRecordWord0); // cores
1371 deviceRecord.name_offset = deviceRecordWord1; // name_offset
1372
Finn Williamsd44815f2020-05-01 13:25:55 +01001373 uint32_t deviceRecordPoolOffset = deviceRecordOffsets[i] + // Packet body offset
Finn Williams6be1e9b2020-05-15 11:21:54 +01001374 deviceRecord.name_offset; // Device name offset
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001375 uint32_t deviceRecordNameLength = ReadUint32(readBuffer, deviceRecordPoolOffset);
1376 deviceRecord.name_length = deviceRecordNameLength; // name_length
1377 unsigned char deviceRecordNameNullTerminator = // name null-terminator
1378 ReadUint8(readBuffer, deviceRecordPoolOffset + uint32_t_size + deviceRecordNameLength - 1);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001379 CHECK(deviceRecordNameNullTerminator == '\0');
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001380 std::vector<unsigned char> deviceRecordNameBuffer(deviceRecord.name_length - 1);
1381 std::memcpy(deviceRecordNameBuffer.data(),
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001382 readData + deviceRecordPoolOffset + uint32_t_size, deviceRecordNameBuffer.size());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001383 deviceRecord.name.assign(deviceRecordNameBuffer.begin(), deviceRecordNameBuffer.end()); // name
1384
1385 deviceRecords.push_back(deviceRecord);
1386 }
1387
1388 // Check that the device records are correct
Sadik Armagan1625efc2021-06-10 18:24:34 +01001389 CHECK(deviceRecords.size() == 2);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001390 for (const DeviceRecord& deviceRecord : deviceRecords)
1391 {
1392 const Device* device = counterDirectory.GetDevice(deviceRecord.uid);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001393 CHECK(device);
1394 CHECK(device->m_Uid == deviceRecord.uid);
1395 CHECK(device->m_Cores == deviceRecord.cores);
1396 CHECK(device->m_Name == deviceRecord.name);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001397 }
1398
Finn Williamsd44815f2020-05-01 13:25:55 +01001399
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001400 // Counter set record structure/collection used for testing
1401 struct CounterSetRecord
1402 {
1403 uint16_t uid;
1404 uint16_t count;
1405 uint32_t name_offset;
1406 uint32_t name_length;
1407 std::string name;
1408 };
1409 std::vector<CounterSetRecord> counterSetRecords;
Finn Williams985fecf2020-04-30 11:06:43 +01001410 const uint32_t counterSetRecordsPointerTableOffset = 2u * uint32_t_size + // packet_header
1411 bodyHeaderWord3; // counter_set_pointer_table_offset
Finn Williamsd44815f2020-05-01 13:25:55 +01001412
1413 offset = counterSetRecordsPointerTableOffset;
1414 std::vector<uint32_t> counterSetRecordOffsets(counterSetRecordCount);
1415
1416 for (uint32_t i = 0; i < counterSetRecordCount; ++i)
1417 {
1418 // counterSetRecordOffset is relative to the start of the dcounterSetRecordsPointerTable
1419 counterSetRecordOffsets[i] = ReadUint32(readBuffer, offset) + counterSetRecordsPointerTableOffset;
1420 offset += uint32_t_size;
1421 }
1422
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001423 for (uint32_t i = 0; i < counterSetRecordCount; i++)
1424 {
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001425 // Collect the data for the counter set record
Finn Williamsd44815f2020-05-01 13:25:55 +01001426 const uint32_t counterSetRecordWord0 = ReadUint32(readBuffer, counterSetRecordOffsets[i] + 0 * uint32_t_size);
1427 const uint32_t counterSetRecordWord1 = ReadUint32(readBuffer, counterSetRecordOffsets[i] + 1 * uint32_t_size);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001428 CounterSetRecord counterSetRecord;
1429 counterSetRecord.uid = static_cast<uint16_t>(counterSetRecordWord0 >> 16); // uid
1430 counterSetRecord.count = static_cast<uint16_t>(counterSetRecordWord0); // count
1431 counterSetRecord.name_offset = counterSetRecordWord1; // name_offset
1432
Finn Williamsd44815f2020-05-01 13:25:55 +01001433 uint32_t counterSetRecordPoolOffset = counterSetRecordOffsets[i] + // Packet body offset
Finn Williams6be1e9b2020-05-15 11:21:54 +01001434 counterSetRecord.name_offset; // Counter set name offset
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001435 uint32_t counterSetRecordNameLength = ReadUint32(readBuffer, counterSetRecordPoolOffset);
1436 counterSetRecord.name_length = counterSetRecordNameLength; // name_length
1437 unsigned char counterSetRecordNameNullTerminator = // name null-terminator
1438 ReadUint8(readBuffer, counterSetRecordPoolOffset + uint32_t_size + counterSetRecordNameLength - 1);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001439 CHECK(counterSetRecordNameNullTerminator == '\0');
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001440 std::vector<unsigned char> counterSetRecordNameBuffer(counterSetRecord.name_length - 1);
1441 std::memcpy(counterSetRecordNameBuffer.data(),
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001442 readData + counterSetRecordPoolOffset + uint32_t_size, counterSetRecordNameBuffer.size());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001443 counterSetRecord.name.assign(counterSetRecordNameBuffer.begin(), counterSetRecordNameBuffer.end()); // name
1444
1445 counterSetRecords.push_back(counterSetRecord);
1446 }
1447
1448 // Check that the counter set records are correct
Sadik Armagan1625efc2021-06-10 18:24:34 +01001449 CHECK(counterSetRecords.size() == 1);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001450 for (const CounterSetRecord& counterSetRecord : counterSetRecords)
1451 {
1452 const CounterSet* counterSet = counterDirectory.GetCounterSet(counterSetRecord.uid);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001453 CHECK(counterSet);
1454 CHECK(counterSet->m_Uid == counterSetRecord.uid);
1455 CHECK(counterSet->m_Count == counterSetRecord.count);
1456 CHECK(counterSet->m_Name == counterSetRecord.name);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001457 }
1458
1459 // Event record structure/collection used for testing
1460 struct EventRecord
1461 {
1462 uint16_t counter_uid;
1463 uint16_t max_counter_uid;
1464 uint16_t device;
1465 uint16_t counter_set;
1466 uint16_t counter_class;
1467 uint16_t interpolation;
1468 double multiplier;
1469 uint32_t name_offset;
1470 uint32_t name_length;
1471 std::string name;
1472 uint32_t description_offset;
1473 uint32_t description_length;
1474 std::string description;
1475 uint32_t units_offset;
1476 uint32_t units_length;
1477 std::string units;
1478 };
1479 // Category record structure/collection used for testing
1480 struct CategoryRecord
1481 {
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001482 uint16_t event_count;
1483 uint32_t event_pointer_table_offset;
1484 uint32_t name_offset;
1485 uint32_t name_length;
1486 std::string name;
1487 std::vector<uint32_t> event_pointer_table;
1488 std::vector<EventRecord> event_records;
1489 };
1490 std::vector<CategoryRecord> categoryRecords;
Finn Williams985fecf2020-04-30 11:06:43 +01001491 const uint32_t categoryRecordsPointerTableOffset = 2u * uint32_t_size + // packet_header
1492 bodyHeaderWord5; // categories_pointer_table_offset
Finn Williamsd44815f2020-05-01 13:25:55 +01001493
1494 offset = categoryRecordsPointerTableOffset;
1495 std::vector<uint32_t> categoryRecordOffsets(categoryRecordCount);
1496 for (uint32_t i = 0; i < categoryRecordCount; ++i)
1497 {
1498 // categoryRecordOffset is relative to the start of the categoryRecordsPointerTable
1499 categoryRecordOffsets[i] = ReadUint32(readBuffer, offset) + categoryRecordsPointerTableOffset;
1500 offset += uint32_t_size;
1501 }
1502
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001503 for (uint32_t i = 0; i < categoryRecordCount; i++)
1504 {
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001505 // Collect the data for the category record
Finn Williamsd44815f2020-05-01 13:25:55 +01001506 const uint32_t categoryRecordWord1 = ReadUint32(readBuffer, categoryRecordOffsets[i] + 0 * uint32_t_size);
1507 const uint32_t categoryRecordWord2 = ReadUint32(readBuffer, categoryRecordOffsets[i] + 1 * uint32_t_size);
1508 const uint32_t categoryRecordWord3 = ReadUint32(readBuffer, categoryRecordOffsets[i] + 2 * uint32_t_size);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001509 CategoryRecord categoryRecord;
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001510 categoryRecord.event_count = static_cast<uint16_t>(categoryRecordWord1 >> 16); // event_count
1511 categoryRecord.event_pointer_table_offset = categoryRecordWord2; // event_pointer_table_offset
1512 categoryRecord.name_offset = categoryRecordWord3; // name_offset
1513
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001514 uint32_t categoryRecordNameLength = ReadUint32(readBuffer,
Finn Williamsd44815f2020-05-01 13:25:55 +01001515 categoryRecordOffsets[i] + categoryRecord.name_offset);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001516 categoryRecord.name_length = categoryRecordNameLength; // name_length
1517 unsigned char categoryRecordNameNullTerminator =
1518 ReadUint8(readBuffer,
Finn Williamsd44815f2020-05-01 13:25:55 +01001519 categoryRecordOffsets[i] +
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001520 categoryRecord.name_offset +
1521 uint32_t_size +
1522 categoryRecordNameLength - 1); // name null-terminator
Sadik Armagan1625efc2021-06-10 18:24:34 +01001523 CHECK(categoryRecordNameNullTerminator == '\0');
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001524 std::vector<unsigned char> categoryRecordNameBuffer(categoryRecord.name_length - 1);
1525 std::memcpy(categoryRecordNameBuffer.data(),
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001526 readData +
Finn Williamsd44815f2020-05-01 13:25:55 +01001527 categoryRecordOffsets[i] +
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001528 categoryRecord.name_offset +
1529 uint32_t_size,
1530 categoryRecordNameBuffer.size());
1531 categoryRecord.name.assign(categoryRecordNameBuffer.begin(), categoryRecordNameBuffer.end()); // name
1532
1533 categoryRecord.event_pointer_table.resize(categoryRecord.event_count);
Finn Williamsd44815f2020-05-01 13:25:55 +01001534 offset = categoryRecordOffsets[i] + categoryRecord.event_pointer_table_offset;
1535 for (uint32_t eventOffsetIndex = 0; eventOffsetIndex < categoryRecord.event_count; ++eventOffsetIndex)
1536 {
1537 // eventRecordOffset is relative to the start of the event pointer table
1538 categoryRecord.event_pointer_table[eventOffsetIndex] = ReadUint32(readBuffer, offset) +
1539 categoryRecordOffsets[i] +
1540 categoryRecord.event_pointer_table_offset;
1541 offset += uint32_t_size;
1542 }
1543
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001544 for (uint32_t eventIndex = 0; eventIndex < categoryRecord.event_count; eventIndex++)
1545 {
Finn Williamsd44815f2020-05-01 13:25:55 +01001546 const uint32_t eventOffset = categoryRecord.event_pointer_table[eventIndex];
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001547 // Collect the data for the event record
Finn Williamsd44815f2020-05-01 13:25:55 +01001548 const uint32_t eventRecordWord0 = ReadUint32(readBuffer, eventOffset + 0 * uint32_t_size);
1549 const uint32_t eventRecordWord1 = ReadUint32(readBuffer, eventOffset + 1 * uint32_t_size);
1550 const uint32_t eventRecordWord2 = ReadUint32(readBuffer, eventOffset + 2 * uint32_t_size);
1551 const uint64_t eventRecordWord34 = ReadUint64(readBuffer, eventOffset + 3 * uint32_t_size);
1552 const uint32_t eventRecordWord5 = ReadUint32(readBuffer, eventOffset + 5 * uint32_t_size);
1553 const uint32_t eventRecordWord6 = ReadUint32(readBuffer, eventOffset + 6 * uint32_t_size);
1554 const uint32_t eventRecordWord7 = ReadUint32(readBuffer, eventOffset + 7 * uint32_t_size);
1555
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001556 EventRecord eventRecord;
1557 eventRecord.counter_uid = static_cast<uint16_t>(eventRecordWord0); // counter_uid
1558 eventRecord.max_counter_uid = static_cast<uint16_t>(eventRecordWord0 >> 16); // max_counter_uid
1559 eventRecord.device = static_cast<uint16_t>(eventRecordWord1 >> 16); // device
1560 eventRecord.counter_set = static_cast<uint16_t>(eventRecordWord1); // counter_set
1561 eventRecord.counter_class = static_cast<uint16_t>(eventRecordWord2 >> 16); // class
1562 eventRecord.interpolation = static_cast<uint16_t>(eventRecordWord2); // interpolation
1563 std::memcpy(&eventRecord.multiplier, &eventRecordWord34, sizeof(eventRecord.multiplier)); // multiplier
1564 eventRecord.name_offset = static_cast<uint32_t>(eventRecordWord5); // name_offset
1565 eventRecord.description_offset = static_cast<uint32_t>(eventRecordWord6); // description_offset
1566 eventRecord.units_offset = static_cast<uint32_t>(eventRecordWord7); // units_offset
1567
Finn Williamsd44815f2020-05-01 13:25:55 +01001568 uint32_t eventRecordNameLength = ReadUint32(readBuffer, eventOffset + eventRecord.name_offset);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001569 eventRecord.name_length = eventRecordNameLength; // name_length
1570 unsigned char eventRecordNameNullTerminator =
1571 ReadUint8(readBuffer,
Finn Williamsd44815f2020-05-01 13:25:55 +01001572 eventOffset +
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001573 eventRecord.name_offset +
1574 uint32_t_size +
1575 eventRecordNameLength - 1); // name null-terminator
Sadik Armagan1625efc2021-06-10 18:24:34 +01001576 CHECK(eventRecordNameNullTerminator == '\0');
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001577 std::vector<unsigned char> eventRecordNameBuffer(eventRecord.name_length - 1);
1578 std::memcpy(eventRecordNameBuffer.data(),
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001579 readData +
Finn Williamsd44815f2020-05-01 13:25:55 +01001580 eventOffset +
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001581 eventRecord.name_offset +
1582 uint32_t_size,
1583 eventRecordNameBuffer.size());
1584 eventRecord.name.assign(eventRecordNameBuffer.begin(), eventRecordNameBuffer.end()); // name
1585
1586 uint32_t eventRecordDescriptionLength = ReadUint32(readBuffer,
Finn Williamsd44815f2020-05-01 13:25:55 +01001587 eventOffset + eventRecord.description_offset);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001588 eventRecord.description_length = eventRecordDescriptionLength; // description_length
1589 unsigned char eventRecordDescriptionNullTerminator =
1590 ReadUint8(readBuffer,
Finn Williamsd44815f2020-05-01 13:25:55 +01001591 eventOffset +
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001592 eventRecord.description_offset +
1593 uint32_t_size +
1594 eventRecordDescriptionLength - 1); // description null-terminator
Sadik Armagan1625efc2021-06-10 18:24:34 +01001595 CHECK(eventRecordDescriptionNullTerminator == '\0');
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001596 std::vector<unsigned char> eventRecordDescriptionBuffer(eventRecord.description_length - 1);
1597 std::memcpy(eventRecordDescriptionBuffer.data(),
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001598 readData +
Finn Williamsd44815f2020-05-01 13:25:55 +01001599 eventOffset +
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001600 eventRecord.description_offset +
1601 uint32_t_size,
1602 eventRecordDescriptionBuffer.size());
1603 eventRecord.description.assign(eventRecordDescriptionBuffer.begin(),
1604 eventRecordDescriptionBuffer.end()); // description
1605
1606 if (eventRecord.units_offset > 0)
1607 {
1608 uint32_t eventRecordUnitsLength = ReadUint32(readBuffer,
Finn Williamsd44815f2020-05-01 13:25:55 +01001609 eventOffset + eventRecord.units_offset);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001610 eventRecord.units_length = eventRecordUnitsLength; // units_length
1611 unsigned char eventRecordUnitsNullTerminator =
1612 ReadUint8(readBuffer,
Finn Williamsd44815f2020-05-01 13:25:55 +01001613 eventOffset +
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001614 eventRecord.units_offset +
1615 uint32_t_size +
1616 eventRecordUnitsLength - 1); // units null-terminator
Sadik Armagan1625efc2021-06-10 18:24:34 +01001617 CHECK(eventRecordUnitsNullTerminator == '\0');
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001618 std::vector<unsigned char> eventRecordUnitsBuffer(eventRecord.units_length - 1);
1619 std::memcpy(eventRecordUnitsBuffer.data(),
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001620 readData +
Finn Williamsd44815f2020-05-01 13:25:55 +01001621 eventOffset +
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001622 eventRecord.units_offset +
1623 uint32_t_size,
1624 eventRecordUnitsBuffer.size());
1625 eventRecord.units.assign(eventRecordUnitsBuffer.begin(), eventRecordUnitsBuffer.end()); // units
1626 }
1627
1628 categoryRecord.event_records.push_back(eventRecord);
1629 }
1630
1631 categoryRecords.push_back(categoryRecord);
1632 }
1633
1634 // Check that the category records are correct
Sadik Armagan1625efc2021-06-10 18:24:34 +01001635 CHECK(categoryRecords.size() == 2);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001636 for (const CategoryRecord& categoryRecord : categoryRecords)
1637 {
1638 const Category* category = counterDirectory.GetCategory(categoryRecord.name);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001639 CHECK(category);
1640 CHECK(category->m_Name == categoryRecord.name);
1641 CHECK(category->m_Counters.size() == categoryRecord.event_count + static_cast<size_t>(numberOfCores) -1);
1642 CHECK(category->m_Counters.size() == categoryRecord.event_count + static_cast<size_t>(numberOfCores) -1);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001643
1644 // Check that the event records are correct
1645 for (const EventRecord& eventRecord : categoryRecord.event_records)
1646 {
1647 const Counter* counter = counterDirectory.GetCounter(eventRecord.counter_uid);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001648 CHECK(counter);
1649 CHECK(counter->m_MaxCounterUid == eventRecord.max_counter_uid);
1650 CHECK(counter->m_DeviceUid == eventRecord.device);
1651 CHECK(counter->m_CounterSetUid == eventRecord.counter_set);
1652 CHECK(counter->m_Class == eventRecord.counter_class);
1653 CHECK(counter->m_Interpolation == eventRecord.interpolation);
1654 CHECK(counter->m_Multiplier == eventRecord.multiplier);
1655 CHECK(counter->m_Name == eventRecord.name);
1656 CHECK(counter->m_Description == eventRecord.description);
1657 CHECK(counter->m_Units == eventRecord.units);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001658 }
1659 }
1660}
1661
Sadik Armagan1625efc2021-06-10 18:24:34 +01001662TEST_CASE("SendCounterDirectoryPacketTest3")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001663{
1664 // Using a mock counter directory that allows to register invalid objects
1665 MockCounterDirectory counterDirectory;
1666
1667 // Register an invalid device
1668 const std::string deviceName = "inv@lid dev!c€";
1669 const Device* device = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001670 CHECK_NOTHROW(device = counterDirectory.RegisterDevice(deviceName, 3));
1671 CHECK(counterDirectory.GetDeviceCount() == 1);
1672 CHECK(device);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001673
1674 // Buffer with enough space
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001675 MockBufferManager mockBuffer(1024);
Sadik Armagan3896b472020-02-10 12:24:15 +00001676 SendCounterPacket sendCounterPacket(mockBuffer);
Jim Flynnf9db3ef2022-03-08 21:23:44 +00001677 CHECK_THROWS_AS(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), arm::pipe::ProfilingException);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001678}
1679
Sadik Armagan1625efc2021-06-10 18:24:34 +01001680TEST_CASE("SendCounterDirectoryPacketTest4")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001681{
1682 // Using a mock counter directory that allows to register invalid objects
1683 MockCounterDirectory counterDirectory;
1684
1685 // Register an invalid counter set
1686 const std::string counterSetName = "inv@lid count€rs€t";
1687 const CounterSet* counterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001688 CHECK_NOTHROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1689 CHECK(counterDirectory.GetCounterSetCount() == 1);
1690 CHECK(counterSet);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001691
1692 // Buffer with enough space
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001693 MockBufferManager mockBuffer(1024);
Sadik Armagan3896b472020-02-10 12:24:15 +00001694 SendCounterPacket sendCounterPacket(mockBuffer);
Jim Flynnf9db3ef2022-03-08 21:23:44 +00001695 CHECK_THROWS_AS(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), arm::pipe::ProfilingException);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001696}
1697
Sadik Armagan1625efc2021-06-10 18:24:34 +01001698TEST_CASE("SendCounterDirectoryPacketTest5")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001699{
1700 // Using a mock counter directory that allows to register invalid objects
1701 MockCounterDirectory counterDirectory;
1702
1703 // Register an invalid category
1704 const std::string categoryName = "c@t€gory";
1705 const Category* category = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001706 CHECK_NOTHROW(category = counterDirectory.RegisterCategory(categoryName));
1707 CHECK(counterDirectory.GetCategoryCount() == 1);
1708 CHECK(category);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001709
1710 // Buffer with enough space
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001711 MockBufferManager mockBuffer(1024);
Sadik Armagan3896b472020-02-10 12:24:15 +00001712 SendCounterPacket sendCounterPacket(mockBuffer);
Jim Flynnf9db3ef2022-03-08 21:23:44 +00001713 CHECK_THROWS_AS(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), arm::pipe::ProfilingException);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001714}
1715
Sadik Armagan1625efc2021-06-10 18:24:34 +01001716TEST_CASE("SendCounterDirectoryPacketTest6")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001717{
1718 // Using a mock counter directory that allows to register invalid objects
1719 MockCounterDirectory counterDirectory;
1720
1721 // Register an invalid device
1722 const std::string deviceName = "inv@lid dev!c€";
1723 const Device* device = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001724 CHECK_NOTHROW(device = counterDirectory.RegisterDevice(deviceName, 3));
1725 CHECK(counterDirectory.GetDeviceCount() == 1);
1726 CHECK(device);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001727
1728 // Register an invalid counter set
1729 const std::string counterSetName = "inv@lid count€rs€t";
1730 const CounterSet* counterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001731 CHECK_NOTHROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1732 CHECK(counterDirectory.GetCounterSetCount() == 1);
1733 CHECK(counterSet);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001734
1735 // Register an invalid category associated to an invalid device and an invalid counter set
1736 const std::string categoryName = "c@t€gory";
1737 const Category* category = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001738 CHECK_NOTHROW(category = counterDirectory.RegisterCategory(categoryName));
1739 CHECK(counterDirectory.GetCategoryCount() == 1);
1740 CHECK(category);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001741
1742 // Buffer with enough space
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001743 MockBufferManager mockBuffer(1024);
Sadik Armagan3896b472020-02-10 12:24:15 +00001744 SendCounterPacket sendCounterPacket(mockBuffer);
Jim Flynnf9db3ef2022-03-08 21:23:44 +00001745 CHECK_THROWS_AS(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), arm::pipe::ProfilingException);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001746}
1747
Sadik Armagan1625efc2021-06-10 18:24:34 +01001748TEST_CASE("SendCounterDirectoryPacketTest7")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001749{
1750 // Using a mock counter directory that allows to register invalid objects
1751 MockCounterDirectory counterDirectory;
1752
1753 // Register an valid device
1754 const std::string deviceName = "valid device";
1755 const Device* device = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001756 CHECK_NOTHROW(device = counterDirectory.RegisterDevice(deviceName, 3));
1757 CHECK(counterDirectory.GetDeviceCount() == 1);
1758 CHECK(device);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001759
1760 // Register an valid counter set
1761 const std::string counterSetName = "valid counterset";
1762 const CounterSet* counterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001763 CHECK_NOTHROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1764 CHECK(counterDirectory.GetCounterSetCount() == 1);
1765 CHECK(counterSet);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001766
1767 // Register an valid category associated to a valid device and a valid counter set
1768 const std::string categoryName = "category";
1769 const Category* category = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001770 CHECK_NOTHROW(category = counterDirectory.RegisterCategory(categoryName));
1771 CHECK(counterDirectory.GetCategoryCount() == 1);
1772 CHECK(category);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001773
1774 // Register an invalid counter associated to a valid category
1775 const Counter* counter = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001776 CHECK_NOTHROW(counter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001777 0,
1778 categoryName,
1779 0,
1780 1,
1781 123.45f,
1782 "counter",
1783 "counter description",
1784 std::string("invalid counter units"),
1785 5,
1786 device->m_Uid,
1787 counterSet->m_Uid));
Sadik Armagan1625efc2021-06-10 18:24:34 +01001788 CHECK(counterDirectory.GetCounterCount() == 5);
1789 CHECK(counter);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001790
1791 // Buffer with enough space
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001792 MockBufferManager mockBuffer(1024);
Sadik Armagan3896b472020-02-10 12:24:15 +00001793 SendCounterPacket sendCounterPacket(mockBuffer);
Jim Flynnf9db3ef2022-03-08 21:23:44 +00001794 CHECK_THROWS_AS(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), arm::pipe::ProfilingException);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001795}
Ferran Balaguer47d0fe92019-09-04 16:47:34 +01001796
Sadik Armagan1625efc2021-06-10 18:24:34 +01001797TEST_CASE("SendThreadTest0")
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001798{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001799 ProfilingStateMachine profilingStateMachine;
1800 SetActiveProfilingState(profilingStateMachine);
1801
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001802 MockProfilingConnection mockProfilingConnection;
Matteo Martincigh61d6f732019-10-03 11:21:18 +01001803 MockStreamCounterBuffer mockStreamCounterBuffer(0);
Sadik Armagan3896b472020-02-10 12:24:15 +00001804 SendCounterPacket sendCounterPacket(mockStreamCounterBuffer);
1805 SendThread sendThread(profilingStateMachine, mockStreamCounterBuffer, sendCounterPacket);
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001806
1807 // Try to start the send thread many times, it must only start once
1808
Sadik Armagan3896b472020-02-10 12:24:15 +00001809 sendThread.Start(mockProfilingConnection);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001810 CHECK(sendThread.IsRunning());
Sadik Armagan3896b472020-02-10 12:24:15 +00001811 sendThread.Start(mockProfilingConnection);
1812 sendThread.Start(mockProfilingConnection);
1813 sendThread.Start(mockProfilingConnection);
1814 sendThread.Start(mockProfilingConnection);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001815 CHECK(sendThread.IsRunning());
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001816
Sadik Armagan3896b472020-02-10 12:24:15 +00001817 sendThread.Stop();
Sadik Armagan1625efc2021-06-10 18:24:34 +01001818 CHECK(!sendThread.IsRunning());
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001819}
1820
Sadik Armagan1625efc2021-06-10 18:24:34 +01001821TEST_CASE("SendThreadTest1")
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001822{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001823 ProfilingStateMachine profilingStateMachine;
1824 SetActiveProfilingState(profilingStateMachine);
1825
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001826 unsigned int totalWrittenSize = 0;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001827
1828 MockProfilingConnection mockProfilingConnection;
Matteo Martincigh61d6f732019-10-03 11:21:18 +01001829 MockStreamCounterBuffer mockStreamCounterBuffer(1024);
Sadik Armagan3896b472020-02-10 12:24:15 +00001830 SendCounterPacket sendCounterPacket(mockStreamCounterBuffer);
1831 SendThread sendThread(profilingStateMachine, mockStreamCounterBuffer, sendCounterPacket);
1832 sendThread.Start(mockProfilingConnection);
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001833
1834 // Interleaving writes and reads to/from the buffer with pauses to test that the send thread actually waits for
1835 // something to become available for reading
1836
Colm Donelan2ba48d22019-11-29 09:10:59 +00001837 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001838
1839 CounterDirectory counterDirectory;
1840 sendCounterPacket.SendStreamMetaDataPacket();
1841
Finn Williamsa0de0562020-04-22 12:27:37 +01001842 totalWrittenSize += GetStreamMetaDataPacketSize();
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001843
Sadik Armagan3896b472020-02-10 12:24:15 +00001844 sendThread.SetReadyToRead();
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001845
Colm Donelan2ba48d22019-11-29 09:10:59 +00001846 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001847
1848 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
1849
1850 // Get the size of the Counter Directory Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001851 unsigned int counterDirectoryPacketSize = 32;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001852 totalWrittenSize += counterDirectoryPacketSize;
1853
Sadik Armagan3896b472020-02-10 12:24:15 +00001854 sendThread.SetReadyToRead();
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001855
Colm Donelan2ba48d22019-11-29 09:10:59 +00001856 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001857
1858 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
1859 {
1860 { 1u, 23u },
1861 { 33u, 1207623u }
1862 });
1863
1864 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001865 unsigned int periodicCounterCapturePacketSize = 28;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001866 totalWrittenSize += periodicCounterCapturePacketSize;
1867
Sadik Armagan3896b472020-02-10 12:24:15 +00001868 sendThread.SetReadyToRead();
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001869
Colm Donelan2ba48d22019-11-29 09:10:59 +00001870 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001871
1872 sendCounterPacket.SendPeriodicCounterCapturePacket(44u,
1873 {
1874 { 211u, 923u }
1875 });
1876
1877 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001878 periodicCounterCapturePacketSize = 22;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001879 totalWrittenSize += periodicCounterCapturePacketSize;
1880
1881 sendCounterPacket.SendPeriodicCounterCapturePacket(1234u,
1882 {
1883 { 555u, 23u },
1884 { 556u, 6u },
1885 { 557u, 893454u },
1886 { 558u, 1456623u },
1887 { 559u, 571090u }
1888 });
1889
1890 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001891 periodicCounterCapturePacketSize = 46;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001892 totalWrittenSize += periodicCounterCapturePacketSize;
1893
1894 sendCounterPacket.SendPeriodicCounterCapturePacket(997u,
1895 {
1896 { 88u, 11u },
1897 { 96u, 22u },
1898 { 97u, 33u },
1899 { 999u, 444u }
1900 });
1901
1902 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001903 periodicCounterCapturePacketSize = 40;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001904 totalWrittenSize += periodicCounterCapturePacketSize;
1905
Sadik Armagan3896b472020-02-10 12:24:15 +00001906 sendThread.SetReadyToRead();
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001907
Colm Donelan2ba48d22019-11-29 09:10:59 +00001908 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001909
1910 sendCounterPacket.SendPeriodicCounterSelectionPacket(1000u, { 1345u, 254u, 4536u, 408u, 54u, 6323u, 428u, 1u, 6u });
1911
1912 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001913 periodicCounterCapturePacketSize = 30;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001914 totalWrittenSize += periodicCounterCapturePacketSize;
1915
Sadik Armagan3896b472020-02-10 12:24:15 +00001916 sendThread.SetReadyToRead();
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001917
Finn Williams109c05b2019-11-29 13:56:33 +00001918 // 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 +01001919 // read all what's remaining in the buffer
Colm Donelan2ba48d22019-11-29 09:10:59 +00001920 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001921
Sadik Armagan3896b472020-02-10 12:24:15 +00001922 sendThread.Stop();
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001923
Sadik Armagan1625efc2021-06-10 18:24:34 +01001924 CHECK(mockStreamCounterBuffer.GetCommittedSize() == totalWrittenSize);
1925 CHECK(mockStreamCounterBuffer.GetReadableSize() == totalWrittenSize);
1926 CHECK(mockStreamCounterBuffer.GetReadSize() == totalWrittenSize);
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001927}
1928
Sadik Armagan1625efc2021-06-10 18:24:34 +01001929TEST_CASE("SendThreadTest2")
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001930{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001931 ProfilingStateMachine profilingStateMachine;
1932 SetActiveProfilingState(profilingStateMachine);
1933
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001934 unsigned int totalWrittenSize = 0;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001935
1936 MockProfilingConnection mockProfilingConnection;
Matteo Martincigh61d6f732019-10-03 11:21:18 +01001937 MockStreamCounterBuffer mockStreamCounterBuffer(1024);
Sadik Armagan3896b472020-02-10 12:24:15 +00001938 SendCounterPacket sendCounterPacket(mockStreamCounterBuffer);
1939 SendThread sendThread(profilingStateMachine, mockStreamCounterBuffer, sendCounterPacket);
1940 sendThread.Start(mockProfilingConnection);
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001941
1942 // Adding many spurious "ready to read" signals throughout the test to check that the send thread is
1943 // capable of handling unnecessary read requests
1944
Colm Donelan2ba48d22019-11-29 09:10:59 +00001945 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001946
Sadik Armagan3896b472020-02-10 12:24:15 +00001947 sendThread.SetReadyToRead();
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001948
1949 CounterDirectory counterDirectory;
1950 sendCounterPacket.SendStreamMetaDataPacket();
1951
Finn Williamsa0de0562020-04-22 12:27:37 +01001952 totalWrittenSize += GetStreamMetaDataPacketSize();
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001953
Sadik Armagan3896b472020-02-10 12:24:15 +00001954 sendThread.SetReadyToRead();
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001955
Colm Donelan2ba48d22019-11-29 09:10:59 +00001956 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001957
1958 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
1959
1960 // Get the size of the Counter Directory Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001961 unsigned int counterDirectoryPacketSize = 32;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001962 totalWrittenSize += counterDirectoryPacketSize;
1963
Sadik Armagan3896b472020-02-10 12:24:15 +00001964 sendThread.SetReadyToRead();
1965 sendThread.SetReadyToRead();
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001966
Colm Donelan2ba48d22019-11-29 09:10:59 +00001967 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001968
1969 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
1970 {
1971 { 1u, 23u },
1972 { 33u, 1207623u }
1973 });
1974
1975 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001976 unsigned int periodicCounterCapturePacketSize = 28;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001977 totalWrittenSize += periodicCounterCapturePacketSize;
1978
Sadik Armagan3896b472020-02-10 12:24:15 +00001979 sendThread.SetReadyToRead();
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001980
Colm Donelan2ba48d22019-11-29 09:10:59 +00001981 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001982
Sadik Armagan3896b472020-02-10 12:24:15 +00001983 sendThread.SetReadyToRead();
1984 sendThread.SetReadyToRead();
1985 sendThread.SetReadyToRead();
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001986
Colm Donelan2ba48d22019-11-29 09:10:59 +00001987 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001988
Sadik Armagan3896b472020-02-10 12:24:15 +00001989 sendThread.SetReadyToRead();
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001990 sendCounterPacket.SendPeriodicCounterCapturePacket(44u,
1991 {
1992 { 211u, 923u }
1993 });
1994
1995 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001996 periodicCounterCapturePacketSize = 22;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001997 totalWrittenSize += periodicCounterCapturePacketSize;
1998
1999 sendCounterPacket.SendPeriodicCounterCapturePacket(1234u,
2000 {
2001 { 555u, 23u },
2002 { 556u, 6u },
2003 { 557u, 893454u },
2004 { 558u, 1456623u },
2005 { 559u, 571090u }
2006 });
2007
2008 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002009 periodicCounterCapturePacketSize = 46;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002010 totalWrittenSize += periodicCounterCapturePacketSize;
2011
Sadik Armagan3896b472020-02-10 12:24:15 +00002012 sendThread.SetReadyToRead();
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002013 sendCounterPacket.SendPeriodicCounterCapturePacket(997u,
2014 {
2015 { 88u, 11u },
2016 { 96u, 22u },
2017 { 97u, 33u },
2018 { 999u, 444u }
2019 });
2020
2021 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002022 periodicCounterCapturePacketSize = 40;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002023 totalWrittenSize += periodicCounterCapturePacketSize;
2024
Sadik Armagan3896b472020-02-10 12:24:15 +00002025 sendThread.SetReadyToRead();
2026 sendThread.SetReadyToRead();
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002027
Colm Donelan2ba48d22019-11-29 09:10:59 +00002028 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_UNTIL_READABLE_MS));
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002029
2030 sendCounterPacket.SendPeriodicCounterSelectionPacket(1000u, { 1345u, 254u, 4536u, 408u, 54u, 6323u, 428u, 1u, 6u });
2031
2032 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002033 periodicCounterCapturePacketSize = 30;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002034 totalWrittenSize += periodicCounterCapturePacketSize;
2035
Sadik Armagan3896b472020-02-10 12:24:15 +00002036 sendThread.SetReadyToRead();
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002037
Finn Williams109c05b2019-11-29 13:56:33 +00002038 // 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 +01002039 // read all what's remaining in the buffer
Sadik Armagan3896b472020-02-10 12:24:15 +00002040 sendThread.Stop();
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002041
Sadik Armagan1625efc2021-06-10 18:24:34 +01002042 CHECK(mockStreamCounterBuffer.GetCommittedSize() == totalWrittenSize);
2043 CHECK(mockStreamCounterBuffer.GetReadableSize() == totalWrittenSize);
2044 CHECK(mockStreamCounterBuffer.GetReadSize() == totalWrittenSize);
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002045}
2046
Sadik Armagan1625efc2021-06-10 18:24:34 +01002047TEST_CASE("SendThreadTest3")
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002048{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002049 ProfilingStateMachine profilingStateMachine;
2050 SetActiveProfilingState(profilingStateMachine);
2051
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002052 unsigned int totalWrittenSize = 0;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002053
2054 MockProfilingConnection mockProfilingConnection;
Matteo Martincigh61d6f732019-10-03 11:21:18 +01002055 MockStreamCounterBuffer mockStreamCounterBuffer(1024);
Sadik Armagan3896b472020-02-10 12:24:15 +00002056 SendCounterPacket sendCounterPacket(mockStreamCounterBuffer);
2057 SendThread sendThread(profilingStateMachine, mockStreamCounterBuffer, sendCounterPacket);
2058 sendThread.Start(mockProfilingConnection);
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002059
2060 // Not using pauses or "grace periods" to stress test the send thread
2061
Sadik Armagan3896b472020-02-10 12:24:15 +00002062 sendThread.SetReadyToRead();
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002063
2064 CounterDirectory counterDirectory;
2065 sendCounterPacket.SendStreamMetaDataPacket();
2066
Finn Williamsa0de0562020-04-22 12:27:37 +01002067 totalWrittenSize += GetStreamMetaDataPacketSize();
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002068
Sadik Armagan3896b472020-02-10 12:24:15 +00002069 sendThread.SetReadyToRead();
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002070 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
2071
2072 // Get the size of the Counter Directory Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002073 unsigned int counterDirectoryPacketSize =32;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002074 totalWrittenSize += counterDirectoryPacketSize;
2075
Sadik Armagan3896b472020-02-10 12:24:15 +00002076 sendThread.SetReadyToRead();
2077 sendThread.SetReadyToRead();
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002078 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
2079 {
2080 { 1u, 23u },
2081 { 33u, 1207623u }
2082 });
2083
2084 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002085 unsigned int periodicCounterCapturePacketSize = 28;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002086 totalWrittenSize += periodicCounterCapturePacketSize;
2087
Sadik Armagan3896b472020-02-10 12:24:15 +00002088 sendThread.SetReadyToRead();
2089 sendThread.SetReadyToRead();
2090 sendThread.SetReadyToRead();
2091 sendThread.SetReadyToRead();
2092 sendThread.SetReadyToRead();
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002093 sendCounterPacket.SendPeriodicCounterCapturePacket(44u,
2094 {
2095 { 211u, 923u }
2096 });
2097
2098 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002099 periodicCounterCapturePacketSize = 22;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002100 totalWrittenSize += periodicCounterCapturePacketSize;
2101
2102 sendCounterPacket.SendPeriodicCounterCapturePacket(1234u,
2103 {
2104 { 555u, 23u },
2105 { 556u, 6u },
2106 { 557u, 893454u },
2107 { 558u, 1456623u },
2108 { 559u, 571090u }
2109 });
2110
2111 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002112 periodicCounterCapturePacketSize = 46;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002113 totalWrittenSize += periodicCounterCapturePacketSize;
2114
Sadik Armagan3896b472020-02-10 12:24:15 +00002115 sendThread.SetReadyToRead();
2116 sendThread.SetReadyToRead();
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002117 sendCounterPacket.SendPeriodicCounterCapturePacket(997u,
2118 {
2119 { 88u, 11u },
2120 { 96u, 22u },
2121 { 97u, 33u },
2122 { 999u, 444u }
2123 });
2124
2125 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002126 periodicCounterCapturePacketSize = 40;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002127 totalWrittenSize += periodicCounterCapturePacketSize;
2128
Sadik Armagan3896b472020-02-10 12:24:15 +00002129 sendThread.SetReadyToRead();
2130 sendThread.SetReadyToRead();
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002131 sendCounterPacket.SendPeriodicCounterSelectionPacket(1000u, { 1345u, 254u, 4536u, 408u, 54u, 6323u, 428u, 1u, 6u });
2132
2133 // Get the size of the Periodic Counter Capture Packet
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002134 periodicCounterCapturePacketSize = 30;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002135 totalWrittenSize += periodicCounterCapturePacketSize;
2136
Sadik Armagan3896b472020-02-10 12:24:15 +00002137 sendThread.SetReadyToRead();
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002138
2139 // Abruptly terminating the send thread, the amount of data sent may be less that the amount written (the send
2140 // thread is not guaranteed to flush the buffer)
Sadik Armagan3896b472020-02-10 12:24:15 +00002141 sendThread.Stop();
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002142
Sadik Armagan1625efc2021-06-10 18:24:34 +01002143 CHECK(mockStreamCounterBuffer.GetCommittedSize() == totalWrittenSize);
2144 CHECK(mockStreamCounterBuffer.GetReadableSize() <= totalWrittenSize);
2145 CHECK(mockStreamCounterBuffer.GetReadSize() <= totalWrittenSize);
2146 CHECK(mockStreamCounterBuffer.GetReadSize() <= mockStreamCounterBuffer.GetReadableSize());
2147 CHECK(mockStreamCounterBuffer.GetReadSize() <= mockStreamCounterBuffer.GetCommittedSize());
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002148}
2149
Sadik Armagan1625efc2021-06-10 18:24:34 +01002150TEST_CASE("SendCounterPacketTestWithSendThread")
Sadik Armagan3896b472020-02-10 12:24:15 +00002151{
2152 ProfilingStateMachine profilingStateMachine;
2153 SetWaitingForAckProfilingState(profilingStateMachine);
2154
2155 MockProfilingConnection mockProfilingConnection;
2156 BufferManager bufferManager(1, 1024);
2157 SendCounterPacket sendCounterPacket(bufferManager);
2158 SendThread sendThread(profilingStateMachine, bufferManager, sendCounterPacket, -1);
2159 sendThread.Start(mockProfilingConnection);
2160
Finn Williamsa0de0562020-04-22 12:27:37 +01002161 unsigned int streamMetadataPacketsize = GetStreamMetaDataPacketSize();
Sadik Armagan3896b472020-02-10 12:24:15 +00002162
2163 sendThread.Stop();
2164
2165 // check for packet in ProfilingConnection
Sadik Armagan1625efc2021-06-10 18:24:34 +01002166 CHECK(mockProfilingConnection.CheckForPacket({PacketType::StreamMetaData, streamMetadataPacketsize}) == 1);
Sadik Armagan3896b472020-02-10 12:24:15 +00002167
2168 SetActiveProfilingState(profilingStateMachine);
2169 sendThread.Start(mockProfilingConnection);
2170
2171 // SendCounterDirectoryPacket
2172 CounterDirectory counterDirectory;
2173 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
2174
2175 sendThread.Stop();
2176 unsigned int counterDirectoryPacketSize = 32;
2177 // check for packet in ProfilingConnection
Sadik Armagan1625efc2021-06-10 18:24:34 +01002178 CHECK(mockProfilingConnection.CheckForPacket(
Sadik Armagan3896b472020-02-10 12:24:15 +00002179 {PacketType::CounterDirectory, counterDirectoryPacketSize}) == 1);
2180
2181 sendThread.Start(mockProfilingConnection);
2182
2183 // SendPeriodicCounterCapturePacket
2184 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
2185 {
2186 { 1u, 23u },
2187 { 33u, 1207623u }
2188 });
2189
2190 sendThread.Stop();
2191
2192 unsigned int periodicCounterCapturePacketSize = 28;
Sadik Armagan1625efc2021-06-10 18:24:34 +01002193 CHECK(mockProfilingConnection.CheckForPacket(
Sadik Armagan3896b472020-02-10 12:24:15 +00002194 {PacketType::PeriodicCounterCapture, periodicCounterCapturePacketSize}) == 1);
2195}
2196
Sadik Armagan1625efc2021-06-10 18:24:34 +01002197TEST_CASE("SendThreadBufferTest")
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002198{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002199 ProfilingStateMachine profilingStateMachine;
2200 SetActiveProfilingState(profilingStateMachine);
2201
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002202 MockProfilingConnection mockProfilingConnection;
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002203 BufferManager bufferManager(3, 1024);
Sadik Armagan3896b472020-02-10 12:24:15 +00002204 SendCounterPacket sendCounterPacket(bufferManager);
2205 SendThread sendThread(profilingStateMachine, bufferManager, sendCounterPacket, -1);
2206 sendThread.Start(mockProfilingConnection);
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002207
2208 // SendStreamMetaDataPacket
2209 sendCounterPacket.SendStreamMetaDataPacket();
2210
2211 // Read data from the buffer
2212 // Buffer should become readable after commit by SendStreamMetaDataPacket
2213 auto packetBuffer = bufferManager.GetReadableBuffer();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002214 CHECK(packetBuffer.get());
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002215
Finn Williamsa0de0562020-04-22 12:27:37 +01002216 unsigned int streamMetadataPacketsize = GetStreamMetaDataPacketSize();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002217 CHECK(packetBuffer->GetSize() == streamMetadataPacketsize);
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002218
2219 // Recommit to be read by sendCounterPacket
2220 bufferManager.Commit(packetBuffer, streamMetadataPacketsize);
2221
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002222 // SendCounterDirectoryPacket
2223 CounterDirectory counterDirectory;
2224 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
2225
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002226 // SendPeriodicCounterCapturePacket
2227 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
2228 {
2229 { 1u, 23u },
2230 { 33u, 1207623u }
2231 });
2232
Sadik Armagan3896b472020-02-10 12:24:15 +00002233 sendThread.Stop();
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002234
2235 // The buffer is read by the send thread so it should not be in the readable buffer.
2236 auto readBuffer = bufferManager.GetReadableBuffer();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002237 CHECK(!readBuffer);
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002238
2239 // Successfully reserved the buffer with requested size
2240 unsigned int reservedSize = 0;
2241 auto reservedBuffer = bufferManager.Reserve(512, reservedSize);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002242 CHECK(reservedSize == 512);
2243 CHECK(reservedBuffer.get());
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002244
Finn Williams09ad6f92019-12-19 17:05:18 +00002245 const auto writtenDataSize = mockProfilingConnection.GetWrittenDataSize();
2246 const auto metaDataPacketCount =
2247 mockProfilingConnection.CheckForPacket({PacketType::StreamMetaData, streamMetadataPacketsize});
2248
Sadik Armagan1625efc2021-06-10 18:24:34 +01002249 CHECK(metaDataPacketCount >= 1);
2250 CHECK(mockProfilingConnection.CheckForPacket({PacketType::CounterDirectory, 32}) == 1);
2251 CHECK(mockProfilingConnection.CheckForPacket({PacketType::PeriodicCounterCapture, 28}) == 1);
Finn Williams09ad6f92019-12-19 17:05:18 +00002252 // Check that we only received the packets we expected
Sadik Armagan1625efc2021-06-10 18:24:34 +01002253 CHECK(metaDataPacketCount + 2 == writtenDataSize);
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +01002254}
2255
Sadik Armagan1625efc2021-06-10 18:24:34 +01002256TEST_CASE("SendThreadSendStreamMetadataPacket1")
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002257{
2258 ProfilingStateMachine profilingStateMachine;
2259
2260 MockProfilingConnection mockProfilingConnection;
2261 BufferManager bufferManager(3, 1024);
Sadik Armagan3896b472020-02-10 12:24:15 +00002262 SendCounterPacket sendCounterPacket(bufferManager);
2263 SendThread sendThread(profilingStateMachine, bufferManager, sendCounterPacket);
2264 sendThread.Start(mockProfilingConnection);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002265
2266 // The profiling state is set to "Uninitialized", so the send thread should throw an exception
Jim Flynnf9db3ef2022-03-08 21:23:44 +00002267 CHECK_THROWS_AS(sendThread.Stop(), arm::pipe::ProfilingException);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002268}
2269
Sadik Armagan1625efc2021-06-10 18:24:34 +01002270TEST_CASE("SendThreadSendStreamMetadataPacket2")
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002271{
2272 ProfilingStateMachine profilingStateMachine;
2273 SetNotConnectedProfilingState(profilingStateMachine);
2274
2275 MockProfilingConnection mockProfilingConnection;
2276 BufferManager bufferManager(3, 1024);
Sadik Armagan3896b472020-02-10 12:24:15 +00002277 SendCounterPacket sendCounterPacket(bufferManager);
2278 SendThread sendThread(profilingStateMachine, bufferManager, sendCounterPacket);
2279 sendThread.Start(mockProfilingConnection);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002280
2281 // The profiling state is set to "NotConnected", so the send thread should throw an exception
Jim Flynnf9db3ef2022-03-08 21:23:44 +00002282 CHECK_THROWS_AS(sendThread.Stop(), arm::pipe::ProfilingException);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002283}
2284
Sadik Armagan1625efc2021-06-10 18:24:34 +01002285TEST_CASE("SendThreadSendStreamMetadataPacket3")
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002286{
2287 ProfilingStateMachine profilingStateMachine;
2288 SetWaitingForAckProfilingState(profilingStateMachine);
2289
Finn Williamsa0de0562020-04-22 12:27:37 +01002290 unsigned int streamMetadataPacketsize = GetStreamMetaDataPacketSize();
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002291
2292 MockProfilingConnection mockProfilingConnection;
2293 BufferManager bufferManager(3, 1024);
Sadik Armagan3896b472020-02-10 12:24:15 +00002294 SendCounterPacket sendCounterPacket(bufferManager);
2295 SendThread sendThread(profilingStateMachine, bufferManager, sendCounterPacket);
2296 sendThread.Start(mockProfilingConnection);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002297
2298 // The profiling state is set to "WaitingForAck", so the send thread should send a Stream Metadata packet
Sadik Armagan3896b472020-02-10 12:24:15 +00002299 // Wait for sendThread to join
Sadik Armagan1625efc2021-06-10 18:24:34 +01002300 CHECK_NOTHROW(sendThread.Stop());
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002301
Finn Williams09ad6f92019-12-19 17:05:18 +00002302 // Check that the buffer contains at least one Stream Metadata packet and no other packets
2303 const auto writtenDataSize = mockProfilingConnection.GetWrittenDataSize();
2304
Sadik Armagan1625efc2021-06-10 18:24:34 +01002305 CHECK(writtenDataSize >= 1u);
2306 CHECK(mockProfilingConnection.CheckForPacket(
Finn Williams09ad6f92019-12-19 17:05:18 +00002307 {PacketType::StreamMetaData, streamMetadataPacketsize}) == writtenDataSize);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002308}
2309
Sadik Armagan1625efc2021-06-10 18:24:34 +01002310TEST_CASE("SendThreadSendStreamMetadataPacket4")
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002311{
2312 ProfilingStateMachine profilingStateMachine;
2313 SetWaitingForAckProfilingState(profilingStateMachine);
2314
Finn Williamsa0de0562020-04-22 12:27:37 +01002315 unsigned int streamMetadataPacketsize = GetStreamMetaDataPacketSize();
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002316
2317 MockProfilingConnection mockProfilingConnection;
2318 BufferManager bufferManager(3, 1024);
Sadik Armagan3896b472020-02-10 12:24:15 +00002319 SendCounterPacket sendCounterPacket(bufferManager);
2320 SendThread sendThread(profilingStateMachine, bufferManager, sendCounterPacket);
2321 sendThread.Start(mockProfilingConnection);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002322
2323 // The profiling state is set to "WaitingForAck", so the send thread should send a Stream Metadata packet
Sadik Armagan3896b472020-02-10 12:24:15 +00002324 // Wait for sendThread to join
2325 sendThread.Stop();
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002326
Sadik Armagan3896b472020-02-10 12:24:15 +00002327 sendThread.Start(mockProfilingConnection);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002328 // Check that the profiling state is still "WaitingForAck"
Sadik Armagan1625efc2021-06-10 18:24:34 +01002329 CHECK((profilingStateMachine.GetCurrentState() == ProfilingState::WaitingForAck));
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002330
Finn Williams3e2969d2019-12-06 17:47:36 +00002331 // Check that the buffer contains at least one Stream Metadata packet
Sadik Armagan1625efc2021-06-10 18:24:34 +01002332 CHECK(mockProfilingConnection.CheckForPacket({PacketType::StreamMetaData, streamMetadataPacketsize}) >= 1);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002333
2334 mockProfilingConnection.Clear();
2335
Sadik Armagan3896b472020-02-10 12:24:15 +00002336 sendThread.Stop();
2337 sendThread.Start(mockProfilingConnection);
Finn Williams09ad6f92019-12-19 17:05:18 +00002338
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002339 // Try triggering a new buffer read
Sadik Armagan3896b472020-02-10 12:24:15 +00002340 sendThread.SetReadyToRead();
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002341
Sadik Armagan3896b472020-02-10 12:24:15 +00002342 // Wait for sendThread to join
Sadik Armagan1625efc2021-06-10 18:24:34 +01002343 CHECK_NOTHROW(sendThread.Stop());
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002344
2345 // Check that the profiling state is still "WaitingForAck"
Sadik Armagan1625efc2021-06-10 18:24:34 +01002346 CHECK((profilingStateMachine.GetCurrentState() == ProfilingState::WaitingForAck));
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002347
Finn Williams09ad6f92019-12-19 17:05:18 +00002348 // Check that the buffer contains at least one Stream Metadata packet and no other packets
2349 const auto writtenDataSize = mockProfilingConnection.GetWrittenDataSize();
2350
Sadik Armagan1625efc2021-06-10 18:24:34 +01002351 CHECK(writtenDataSize >= 1u);
2352 CHECK(mockProfilingConnection.CheckForPacket(
Finn Williams09ad6f92019-12-19 17:05:18 +00002353 {PacketType::StreamMetaData, streamMetadataPacketsize}) == writtenDataSize);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002354}
2355
Sadik Armagan1625efc2021-06-10 18:24:34 +01002356}