blob: 1f55515758c9b4da72bd59b8ff4e9aac07dd75bf [file] [log] [blame]
Finn Williamse63a0262019-10-22 10:30:49 +01001//
2// Copyright © 2019 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
Finn Williams8a2b4682020-02-26 10:25:26 +00006#include <TimelineCaptureCommandHandler.hpp>
7#include <TimelineDirectoryCaptureCommandHandler.hpp>
8#include <TimelineDecoder.hpp>
Finn Williamse63a0262019-10-22 10:30:49 +01009
10#include <CommandHandlerFunctor.hpp>
11#include <ProfilingService.hpp>
12#include <PacketBuffer.hpp>
13#include <TimelinePacketWriterFactory.hpp>
14
15#include <boost/test/test_tools.hpp>
16#include <boost/test/unit_test_suite.hpp>
17
18BOOST_AUTO_TEST_SUITE(TimelineDecoderTests)
19
20using namespace armnn;
Finn Williams8a2b4682020-02-26 10:25:26 +000021using namespace timelinedecoder;
Finn Williamse63a0262019-10-22 10:30:49 +010022
23void SendTimelinePacketToCommandHandler(const unsigned char* packetBuffer,
24 profiling::CommandHandlerFunctor &CommandHandler)
25{
26 uint32_t uint32_t_size = sizeof(uint32_t);
27 unsigned int offset = 0;
28
29 uint32_t header[2];
30 header[0] = profiling::ReadUint32(packetBuffer, offset);
31 offset += uint32_t_size;
32 header[1] = profiling::ReadUint32(packetBuffer, offset);
33 offset += uint32_t_size;
Finn Williamse63a0262019-10-22 10:30:49 +010034 uint32_t PacketDataLength = header[1] & 0x00FFFFFF;
35
Matteo Martincigh34a407d2019-11-06 15:30:54 +000036 auto uniquePacketData = std::make_unique<unsigned char[]>(PacketDataLength);
Finn Williamse63a0262019-10-22 10:30:49 +010037 std::memcpy(uniquePacketData.get(), packetBuffer + offset, PacketDataLength);
38
Matteo Martincigh34a407d2019-11-06 15:30:54 +000039 armnn::profiling::Packet packet(header[0], PacketDataLength, uniquePacketData);
40
41 BOOST_CHECK(std::memcmp(packetBuffer + offset, packet.GetData(), packet.GetLength()) == 0);
Finn Williamse63a0262019-10-22 10:30:49 +010042
43 CommandHandler(packet);
44}
45
Finn Williams510f6182020-02-21 11:14:08 +000046void PushEntity(TimelineDecoder::Model& model, const ITimelineDecoder::Entity entity)
47{
48 model.m_Entities.emplace_back(entity);
49}
50
51void PushEventClass(TimelineDecoder::Model& model, const ITimelineDecoder::EventClass eventClass)
52{
53 model.m_EventClasses.emplace_back(eventClass);
54}
55
56void PushEvent(TimelineDecoder::Model& model, const ITimelineDecoder::Event event)
57{
58 model.m_Events.emplace_back(event);
59}
60
61void PushLabel(TimelineDecoder::Model& model, const ITimelineDecoder::Label label)
62{
63 model.m_Labels.emplace_back(label);
64}
65
66void PushRelationship(TimelineDecoder::Model& model, const ITimelineDecoder::Relationship relationship)
67{
68 model.m_Relationships.emplace_back(relationship);
69}
70
Matteo Martincigh34a407d2019-11-06 15:30:54 +000071BOOST_AUTO_TEST_CASE(TimelineDirectoryTest)
Finn Williamse63a0262019-10-22 10:30:49 +010072{
Matteo Martincigh34a407d2019-11-06 15:30:54 +000073 uint32_t uint8_t_size = sizeof(uint8_t);
Finn Williamse63a0262019-10-22 10:30:49 +010074 uint32_t uint32_t_size = sizeof(uint32_t);
Matteo Martincigh34a407d2019-11-06 15:30:54 +000075 uint32_t uint64_t_size = sizeof(uint64_t);
76 uint32_t threadId_size = sizeof(std::thread::id);
Finn Williamse63a0262019-10-22 10:30:49 +010077
78 profiling::BufferManager bufferManager(5);
79 profiling::TimelinePacketWriterFactory timelinePacketWriterFactory(bufferManager);
80
81 std::unique_ptr<profiling::ISendTimelinePacket> sendTimelinePacket =
82 timelinePacketWriterFactory.GetSendTimelinePacket();
83
84 profiling::PacketVersionResolver packetVersionResolver;
85
Finn Williamse6a2ccd2020-02-27 16:21:41 +000086 TimelineDecoder timelineDecoder;
87 TimelineCaptureCommandHandler timelineCaptureCommandHandler(
88 1, 1, packetVersionResolver.ResolvePacketVersion(1, 1).GetEncodedValue(), timelineDecoder);
89
Finn Williams8a2b4682020-02-26 10:25:26 +000090 TimelineDirectoryCaptureCommandHandler timelineDirectoryCaptureCommandHandler(
Finn Williamse6a2ccd2020-02-27 16:21:41 +000091 1, 0, packetVersionResolver.ResolvePacketVersion(1, 0).GetEncodedValue(),
92 timelineCaptureCommandHandler, true);
Finn Williamse63a0262019-10-22 10:30:49 +010093
94 sendTimelinePacket->SendTimelineMessageDirectoryPackage();
95 sendTimelinePacket->Commit();
96
97 std::vector<profiling::SwTraceMessage> swTraceBufferMessages;
98
99 unsigned int offset = uint32_t_size * 2;
100
101 std::unique_ptr<profiling::IPacketBuffer> packetBuffer = bufferManager.GetReadableBuffer();
102
Matteo Martincigh34a407d2019-11-06 15:30:54 +0000103 uint8_t readStreamVersion = ReadUint8(packetBuffer, offset);
104 BOOST_CHECK(readStreamVersion == 4);
105 offset += uint8_t_size;
106 uint8_t readPointerBytes = ReadUint8(packetBuffer, offset);
107 BOOST_CHECK(readPointerBytes == uint64_t_size);
108 offset += uint8_t_size;
109 uint8_t readThreadIdBytes = ReadUint8(packetBuffer, offset);
110 BOOST_CHECK(readThreadIdBytes == threadId_size);
111 offset += uint8_t_size;
112
Finn Williamse63a0262019-10-22 10:30:49 +0100113 uint32_t declarationSize = profiling::ReadUint32(packetBuffer, offset);
114 offset += uint32_t_size;
115 for(uint32_t i = 0; i < declarationSize; ++i)
116 {
117 swTraceBufferMessages.push_back(profiling::ReadSwTraceMessage(packetBuffer->GetReadableData(), offset));
118 }
119
120 SendTimelinePacketToCommandHandler(packetBuffer->GetReadableData(), timelineDirectoryCaptureCommandHandler);
121
122 for(uint32_t index = 0; index < declarationSize; ++index)
123 {
124 profiling::SwTraceMessage& bufferMessage = swTraceBufferMessages[index];
125 profiling::SwTraceMessage& handlerMessage = timelineDirectoryCaptureCommandHandler.m_SwTraceMessages[index];
126
Matteo Martincigh34a407d2019-11-06 15:30:54 +0000127 BOOST_CHECK(bufferMessage.m_Name == handlerMessage.m_Name);
128 BOOST_CHECK(bufferMessage.m_UiName == handlerMessage.m_UiName);
129 BOOST_CHECK(bufferMessage.m_Id == handlerMessage.m_Id);
Finn Williamse63a0262019-10-22 10:30:49 +0100130
Matteo Martincigh34a407d2019-11-06 15:30:54 +0000131 BOOST_CHECK(bufferMessage.m_ArgTypes.size() == handlerMessage.m_ArgTypes.size());
132 for(uint32_t i = 0; i < bufferMessage.m_ArgTypes.size(); ++i)
Finn Williamse63a0262019-10-22 10:30:49 +0100133 {
Matteo Martincigh34a407d2019-11-06 15:30:54 +0000134 BOOST_CHECK(bufferMessage.m_ArgTypes[i] == handlerMessage.m_ArgTypes[i]);
Finn Williamse63a0262019-10-22 10:30:49 +0100135 }
136
Matteo Martincigh34a407d2019-11-06 15:30:54 +0000137 BOOST_CHECK(bufferMessage.m_ArgNames.size() == handlerMessage.m_ArgNames.size());
138 for(uint32_t i = 0; i < bufferMessage.m_ArgNames.size(); ++i)
Finn Williamse63a0262019-10-22 10:30:49 +0100139 {
Matteo Martincigh34a407d2019-11-06 15:30:54 +0000140 BOOST_CHECK(bufferMessage.m_ArgNames[i] == handlerMessage.m_ArgNames[i]);
Finn Williamse63a0262019-10-22 10:30:49 +0100141 }
142 }
143}
144
145BOOST_AUTO_TEST_CASE(TimelineCaptureTest)
146{
Finn Williams510f6182020-02-21 11:14:08 +0000147 unsigned int threadIdSize = sizeof(std::thread::id);
Finn Williamse63a0262019-10-22 10:30:49 +0100148 profiling::BufferManager bufferManager(50);
149 profiling::TimelinePacketWriterFactory timelinePacketWriterFactory(bufferManager);
150
151 std::unique_ptr<profiling::ISendTimelinePacket> sendTimelinePacket =
152 timelinePacketWriterFactory.GetSendTimelinePacket();
153
154 profiling::PacketVersionResolver packetVersionResolver;
155
Finn Williams510f6182020-02-21 11:14:08 +0000156 TimelineDecoder timelineDecoder;
157 const TimelineDecoder::Model& model = timelineDecoder.GetModel();
Finn Williamse63a0262019-10-22 10:30:49 +0100158
Finn Williamse6a2ccd2020-02-27 16:21:41 +0000159
Finn Williams8a2b4682020-02-26 10:25:26 +0000160 TimelineCaptureCommandHandler timelineCaptureCommandHandler(
Finn Williams510f6182020-02-21 11:14:08 +0000161 1, 1, packetVersionResolver.ResolvePacketVersion(1, 1).GetEncodedValue(), timelineDecoder, threadIdSize);
Finn Williamse63a0262019-10-22 10:30:49 +0100162
Keith Davis97da5e22020-03-05 16:25:28 +0000163 using Status = ITimelineDecoder::TimelineStatus;
164 BOOST_CHECK(timelineDecoder.SetEntityCallback(PushEntity) == Status::TimelineStatus_Success);
165 BOOST_CHECK(timelineDecoder.SetEventClassCallback(PushEventClass) == Status::TimelineStatus_Success);
166 BOOST_CHECK(timelineDecoder.SetEventCallback(PushEvent) == Status::TimelineStatus_Success);
167 BOOST_CHECK(timelineDecoder.SetLabelCallback(PushLabel) == Status::TimelineStatus_Success);
168 BOOST_CHECK(timelineDecoder.SetRelationshipCallback(PushRelationship) == Status::TimelineStatus_Success);
Finn Williamse63a0262019-10-22 10:30:49 +0100169
Keith Davis97da5e22020-03-05 16:25:28 +0000170 const uint64_t entityGuid = 111111u;
Finn Williams510f6182020-02-21 11:14:08 +0000171 const uint64_t eventClassGuid = 22222u;
172 const uint64_t timestamp = 33333u;
173 const uint64_t eventGuid = 44444u;
Finn Williamse63a0262019-10-22 10:30:49 +0100174
Finn Williams510f6182020-02-21 11:14:08 +0000175 const std::thread::id threadId = std::this_thread::get_id();
Finn Williamse63a0262019-10-22 10:30:49 +0100176
Finn Williams510f6182020-02-21 11:14:08 +0000177 // need to do a bit of work here to extract the value from threadId
178 unsigned char* uCharThreadId = new unsigned char[threadIdSize]();;
179 uint64_t uint64ThreadId;
Finn Williamse63a0262019-10-22 10:30:49 +0100180
Finn Williams510f6182020-02-21 11:14:08 +0000181 profiling::WriteBytes(uCharThreadId, 0, &threadId, threadIdSize);
Finn Williamse63a0262019-10-22 10:30:49 +0100182
Finn Williams510f6182020-02-21 11:14:08 +0000183 if (threadIdSize == 4)
184 {
185 uint64ThreadId = profiling::ReadUint32(uCharThreadId, 0);
186 }
187 else if (threadIdSize == 8)
188 {
189 uint64ThreadId = profiling::ReadUint64(uCharThreadId, 0);
190 }
191 delete[] uCharThreadId;
192
193 const uint64_t labelGuid = 66666u;
Finn Williamse63a0262019-10-22 10:30:49 +0100194 std::string labelName = "test_label";
195
Finn Williams510f6182020-02-21 11:14:08 +0000196 const uint64_t relationshipGuid = 77777u;
197 const uint64_t headGuid = 888888u;
198 const uint64_t tailGuid = 999999u;
Finn Williamse63a0262019-10-22 10:30:49 +0100199
200 for (int i = 0; i < 10; ++i)
201 {
202 // Send entity
203 sendTimelinePacket->SendTimelineEntityBinaryPacket(entityGuid);
204 sendTimelinePacket->Commit();
205 SendTimelinePacketToCommandHandler(bufferManager.GetReadableBuffer()->GetReadableData(),
206 timelineCaptureCommandHandler);
207
208 // Send event class
209 sendTimelinePacket->SendTimelineEventClassBinaryPacket(eventClassGuid);
210 sendTimelinePacket->Commit();
211 SendTimelinePacketToCommandHandler(bufferManager.GetReadableBuffer()->GetReadableData(),
212 timelineCaptureCommandHandler);
213
214 // Send event
215 sendTimelinePacket->SendTimelineEventBinaryPacket(timestamp, threadId, eventGuid);
216 sendTimelinePacket->Commit();
217 SendTimelinePacketToCommandHandler(bufferManager.GetReadableBuffer()->GetReadableData(),
218 timelineCaptureCommandHandler);
219
220 // Send label
221 sendTimelinePacket->SendTimelineLabelBinaryPacket(labelGuid, labelName);
222 sendTimelinePacket->Commit();
223 SendTimelinePacketToCommandHandler(bufferManager.GetReadableBuffer()->GetReadableData(),
224 timelineCaptureCommandHandler);
225
226 // Send relationship
227 profiling::ProfilingRelationshipType relationshipType = profiling::ProfilingRelationshipType::DataLink;
228 sendTimelinePacket->SendTimelineRelationshipBinaryPacket(relationshipType,
229 relationshipGuid,
230 headGuid,
231 tailGuid);
232 sendTimelinePacket->Commit();
233 SendTimelinePacketToCommandHandler(bufferManager.GetReadableBuffer()->GetReadableData(),
234 timelineCaptureCommandHandler);
235 }
236
Finn Williams510f6182020-02-21 11:14:08 +0000237 for (unsigned long i = 0; i < 10; ++i)
Finn Williamse63a0262019-10-22 10:30:49 +0100238 {
Finn Williams510f6182020-02-21 11:14:08 +0000239 BOOST_CHECK(model.m_Entities[i].m_Guid == entityGuid);
Finn Williamse63a0262019-10-22 10:30:49 +0100240
Finn Williams510f6182020-02-21 11:14:08 +0000241 BOOST_CHECK(model.m_EventClasses[i].m_Guid == eventClassGuid);
Finn Williamse63a0262019-10-22 10:30:49 +0100242
Finn Williams510f6182020-02-21 11:14:08 +0000243 BOOST_CHECK(model.m_Events[i].m_TimeStamp == timestamp);
244 BOOST_CHECK(model.m_Events[i].m_ThreadId == uint64ThreadId);
245 BOOST_CHECK(model.m_Events[i].m_Guid == eventGuid);
Finn Williamse63a0262019-10-22 10:30:49 +0100246
Finn Williams510f6182020-02-21 11:14:08 +0000247 BOOST_CHECK(model.m_Labels[i].m_Guid == labelGuid);
248 BOOST_CHECK(model.m_Labels[i].m_Name == labelName);
Finn Williamse63a0262019-10-22 10:30:49 +0100249
Finn Williams510f6182020-02-21 11:14:08 +0000250 BOOST_CHECK(model.m_Relationships[i].m_RelationshipType == ITimelineDecoder::RelationshipType::DataLink);
251 BOOST_CHECK(model.m_Relationships[i].m_Guid == relationshipGuid);
252 BOOST_CHECK(model.m_Relationships[i].m_HeadGuid == headGuid);
253 BOOST_CHECK(model.m_Relationships[i].m_TailGuid == tailGuid);
Finn Williamse63a0262019-10-22 10:30:49 +0100254 }
Finn Williamse63a0262019-10-22 10:30:49 +0100255}
256
Keith Davis5238aff2020-03-11 12:17:05 +0000257BOOST_AUTO_TEST_CASE(TimelineCaptureTestMultipleStringsInBuffer)
258{
259 unsigned int threadIdSize = sizeof(std::thread::id);
260 profiling::BufferManager bufferManager(50);
261 profiling::TimelinePacketWriterFactory timelinePacketWriterFactory(bufferManager);
262
263 std::unique_ptr<profiling::ISendTimelinePacket> sendTimelinePacket =
264 timelinePacketWriterFactory.GetSendTimelinePacket();
265
266 profiling::PacketVersionResolver packetVersionResolver;
267
268 TimelineDecoder timelineDecoder;
269 const TimelineDecoder::Model& model = timelineDecoder.GetModel();
270
271 TimelineCaptureCommandHandler timelineCaptureCommandHandler(
272 1, 1, packetVersionResolver.ResolvePacketVersion(1, 1).GetEncodedValue(), timelineDecoder, threadIdSize);
273
274 using Status = ITimelineDecoder::TimelineStatus;
275 BOOST_CHECK(timelineDecoder.SetEntityCallback(PushEntity) == Status::TimelineStatus_Success);
276 BOOST_CHECK(timelineDecoder.SetEventClassCallback(PushEventClass) == Status::TimelineStatus_Success);
277 BOOST_CHECK(timelineDecoder.SetEventCallback(PushEvent) == Status::TimelineStatus_Success);
278 BOOST_CHECK(timelineDecoder.SetLabelCallback(PushLabel) == Status::TimelineStatus_Success);
279 BOOST_CHECK(timelineDecoder.SetRelationshipCallback(PushRelationship) == Status::TimelineStatus_Success);
280
281 const uint64_t entityGuid = 111111u;
282 const uint64_t eventClassGuid = 22222u;
283 const uint64_t timestamp = 33333u;
284 const uint64_t eventGuid = 44444u;
285
286 const std::thread::id threadId = std::this_thread::get_id();
287
288 // need to do a bit of work here to extract the value from threadId
289 unsigned char* uCharThreadId = new unsigned char[threadIdSize]();;
290 uint64_t uint64ThreadId;
291
292 profiling::WriteBytes(uCharThreadId, 0, &threadId, threadIdSize);
293
294 if ( threadIdSize == 4 )
295 {
296 uint64ThreadId = profiling::ReadUint32(uCharThreadId, 0);
297 } else if ( threadIdSize == 8 )
298 {
299 uint64ThreadId = profiling::ReadUint64(uCharThreadId, 0);
300 }
301 delete[] uCharThreadId;
302
303 const uint64_t labelGuid = 66666u;
304 std::string labelName = "test_label";
305 std::string labelName2 = "test_label2";
306 std::string labelName3 = "test_label32";
307
308 const uint64_t relationshipGuid = 77777u;
309 const uint64_t headGuid = 888888u;
310 const uint64_t tailGuid = 999999u;
311
312 // Check with multiple messages in the same buffer
313 for ( int i = 0; i < 9; ++i )
314 {
315 // Send entity
316 sendTimelinePacket->SendTimelineEntityBinaryPacket(entityGuid);
317 // Send event class
318 sendTimelinePacket->SendTimelineEventClassBinaryPacket(eventClassGuid);
319 // Send event
320 sendTimelinePacket->SendTimelineEventBinaryPacket(timestamp, threadId, eventGuid);
321 // Send label
322 sendTimelinePacket->SendTimelineLabelBinaryPacket(labelGuid, labelName);
323 sendTimelinePacket->SendTimelineLabelBinaryPacket(labelGuid, labelName2);
324 sendTimelinePacket->SendTimelineLabelBinaryPacket(labelGuid, labelName3);
325 // Send relationship
326 profiling::ProfilingRelationshipType relationshipType = profiling::ProfilingRelationshipType::DataLink;
327 sendTimelinePacket->SendTimelineRelationshipBinaryPacket(relationshipType,
328 relationshipGuid,
329 headGuid,
330 tailGuid);
331 }
332
333 sendTimelinePacket->Commit();
334 SendTimelinePacketToCommandHandler(bufferManager.GetReadableBuffer()->GetReadableData(),
335 timelineCaptureCommandHandler);
336
337 for ( unsigned long i = 0; i < 9; ++i )
338 {
339 BOOST_CHECK(model.m_Entities[i].m_Guid == entityGuid);
340
341 BOOST_CHECK(model.m_EventClasses[i].m_Guid == eventClassGuid);
342
343 BOOST_CHECK(model.m_Labels[i].m_Guid == labelGuid);
344
345 BOOST_CHECK(model.m_Events[i].m_TimeStamp == timestamp);
346 BOOST_CHECK(model.m_Events[i].m_ThreadId == uint64ThreadId);
347 BOOST_CHECK(model.m_Events[i].m_Guid == eventGuid);
348
349 BOOST_CHECK(model.m_Relationships[i].m_RelationshipType == ITimelineDecoder::RelationshipType::DataLink);
350 BOOST_CHECK(model.m_Relationships[i].m_Guid == relationshipGuid);
351 BOOST_CHECK(model.m_Relationships[i].m_HeadGuid == headGuid);
352 BOOST_CHECK(model.m_Relationships[i].m_TailGuid == tailGuid);
353 }
354 for ( unsigned long i = 0; i < 9; i += 3 )
355 {
356 BOOST_CHECK(model.m_Labels[i].m_Name == labelName);
357 BOOST_CHECK(model.m_Labels[i+1].m_Name == labelName2);
358 BOOST_CHECK(model.m_Labels[i+2].m_Name == labelName3);
359 }
360}
361
Finn Williamse63a0262019-10-22 10:30:49 +0100362BOOST_AUTO_TEST_SUITE_END()