blob: ba1e6cfa5af4e52a114d7f033f29137049b2013c [file] [log] [blame]
Francis Murtagh1f7db452019-08-14 09:49:34 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
Ferran Balaguer1b941722019-08-28 16:57:18 +01006#include "SendCounterPacketTests.hpp"
Teresa Charlin9bab4962019-09-06 12:28:35 +01007
Matteo Martincigh8a837172019-10-04 17:01:07 +01008#include <CommandHandler.hpp>
Matteo Martincigh6db5f202019-09-05 12:02:04 +01009#include <CommandHandlerKey.hpp>
10#include <CommandHandlerFunctor.hpp>
11#include <CommandHandlerRegistry.hpp>
Sadik Armaganb5f01b22019-09-18 17:29:00 +010012#include <ConnectionAcknowledgedCommandHandler.hpp>
Matteo Martincigh6db5f202019-09-05 12:02:04 +010013#include <CounterDirectory.hpp>
14#include <EncodeVersion.hpp>
15#include <Holder.hpp>
Matteo Martincighe0e6efc2019-10-04 17:17:42 +010016#include <ICounterValues.hpp>
Matteo Martincigh6db5f202019-09-05 12:02:04 +010017#include <Packet.hpp>
18#include <PacketVersionResolver.hpp>
Francis Murtaghfcb8ef62019-09-20 15:40:09 +010019#include <PeriodicCounterCapture.hpp>
Matteo Martincigh6db5f202019-09-05 12:02:04 +010020#include <PeriodicCounterSelectionCommandHandler.hpp>
21#include <ProfilingStateMachine.hpp>
22#include <ProfilingService.hpp>
23#include <ProfilingUtils.hpp>
Narumol Prangnawarat48033692019-09-20 12:04:55 +010024#include <RequestCounterDirectoryCommandHandler.hpp>
Teresa Charlin9bab4962019-09-06 12:28:35 +010025#include <Runtime.hpp>
Matteo Martincigh6db5f202019-09-05 12:02:04 +010026#include <SocketProfilingConnection.hpp>
Keith Davis02356de2019-08-26 18:28:17 +010027
Matteo Martincigh6db5f202019-09-05 12:02:04 +010028#include <armnn/Conversion.hpp>
Ferran Balaguer1b941722019-08-28 16:57:18 +010029
Sadik Armaganbd9e2c52019-09-26 23:13:31 +010030#include <boost/algorithm/string.hpp>
Ferran Balaguer1b941722019-08-28 16:57:18 +010031#include <boost/numeric/conversion/cast.hpp>
Sadik Armaganbd9e2c52019-09-26 23:13:31 +010032#include <boost/test/unit_test.hpp>
Francis Murtagh1f7db452019-08-14 09:49:34 +010033
Nikhil Rajbc626052019-08-15 15:49:45 +010034#include <cstdint>
35#include <cstring>
Sadik Armaganbd9e2c52019-09-26 23:13:31 +010036#include <iostream>
Aron Virginas-Tare898db92019-08-22 12:56:34 +010037#include <limits>
Francis Murtagh11f99b42019-08-16 11:28:52 +010038#include <map>
Aron Virginas-Tare898db92019-08-22 12:56:34 +010039#include <random>
Nikhil Raj3ecc5102019-09-03 15:55:33 +010040#include <thread>
Matteo Martincigh24e8f922019-09-19 11:57:46 +010041#include <chrono>
Francis Murtagh1f7db452019-08-14 09:49:34 +010042
Aron Virginas-Tare898db92019-08-22 12:56:34 +010043using namespace armnn::profiling;
44
Matteo Martincigh8a837172019-10-04 17:01:07 +010045BOOST_AUTO_TEST_SUITE(ExternalProfiling)
46
Francis Murtagh1f7db452019-08-14 09:49:34 +010047BOOST_AUTO_TEST_CASE(CheckCommandHandlerKeyComparisons)
48{
49 CommandHandlerKey testKey0(1, 1);
50 CommandHandlerKey testKey1(1, 1);
51 CommandHandlerKey testKey2(1, 1);
52 CommandHandlerKey testKey3(0, 0);
53 CommandHandlerKey testKey4(2, 2);
54 CommandHandlerKey testKey5(0, 2);
55
56 BOOST_CHECK(testKey1<testKey4);
57 BOOST_CHECK(testKey1>testKey3);
58 BOOST_CHECK(testKey1<=testKey4);
59 BOOST_CHECK(testKey1>=testKey3);
60 BOOST_CHECK(testKey1<=testKey2);
61 BOOST_CHECK(testKey1>=testKey2);
62 BOOST_CHECK(testKey1==testKey2);
63 BOOST_CHECK(testKey1==testKey1);
64
65 BOOST_CHECK(!(testKey1==testKey5));
66 BOOST_CHECK(!(testKey1!=testKey1));
67 BOOST_CHECK(testKey1!=testKey5);
68
69 BOOST_CHECK(testKey1==testKey2 && testKey2==testKey1);
70 BOOST_CHECK(testKey0==testKey1 && testKey1==testKey2 && testKey0==testKey2);
71
72 BOOST_CHECK(testKey1.GetPacketId()==1);
73 BOOST_CHECK(testKey1.GetVersion()==1);
74
75 std::vector<CommandHandlerKey> vect =
Aron Virginas-Tare898db92019-08-22 12:56:34 +010076 {
77 CommandHandlerKey(0,1), CommandHandlerKey(2,0), CommandHandlerKey(1,0),
78 CommandHandlerKey(2,1), CommandHandlerKey(1,1), CommandHandlerKey(0,1),
79 CommandHandlerKey(2,0), CommandHandlerKey(0,0)
80 };
Francis Murtagh1f7db452019-08-14 09:49:34 +010081
82 std::sort(vect.begin(), vect.end());
83
84 std::vector<CommandHandlerKey> expectedVect =
Aron Virginas-Tare898db92019-08-22 12:56:34 +010085 {
86 CommandHandlerKey(0,0), CommandHandlerKey(0,1), CommandHandlerKey(0,1),
87 CommandHandlerKey(1,0), CommandHandlerKey(1,1), CommandHandlerKey(2,0),
88 CommandHandlerKey(2,0), CommandHandlerKey(2,1)
89 };
Francis Murtagh1f7db452019-08-14 09:49:34 +010090
91 BOOST_CHECK(vect == expectedVect);
92}
93
FinnWilliamsArm4833cea2019-09-17 16:53:53 +010094class TestProfilingConnectionBase :public IProfilingConnection
95{
96public:
97 TestProfilingConnectionBase() = default;
98 ~TestProfilingConnectionBase() = default;
99
Matteo Martincigh8a837172019-10-04 17:01:07 +0100100 bool IsOpen() { return true; }
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100101
Matteo Martincigh8a837172019-10-04 17:01:07 +0100102 void Close() {}
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100103
Matteo Martincigh8a837172019-10-04 17:01:07 +0100104 bool WritePacket(const unsigned char* buffer, uint32_t length) { return false; }
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100105
106 Packet ReadPacket(uint32_t timeout)
107 {
108 std::this_thread::sleep_for(std::chrono::milliseconds(timeout));
109 std::unique_ptr<char[]> packetData;
110 //Return connection acknowledged packet
111 return {65536 ,0 , packetData};
112 }
113};
114
Matteo Martincigh8a837172019-10-04 17:01:07 +0100115class TestProfilingConnectionTimeoutError : public TestProfilingConnectionBase
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100116{
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100117public:
118 Packet ReadPacket(uint32_t timeout) {
119 if (readRequests < 3)
120 {
121 readRequests++;
122 throw armnn::TimeoutException(": Simulate a timeout");
123 }
124 std::this_thread::sleep_for(std::chrono::milliseconds(timeout));
125 std::unique_ptr<char[]> packetData;
126 //Return connection acknowledged packet after three timeouts
127 return {65536 ,0 , packetData};
128 }
Matteo Martincigh8a837172019-10-04 17:01:07 +0100129
130private:
131 int readRequests = 0;
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100132};
133
134class TestProfilingConnectionArmnnError :public TestProfilingConnectionBase
135{
136public:
137
138 Packet ReadPacket(uint32_t timeout)
139 {
140 std::this_thread::sleep_for(std::chrono::milliseconds(timeout));
141 throw armnn::Exception(": Simulate a non timeout error");
142 }
143};
144
Matteo Martincigh8a837172019-10-04 17:01:07 +0100145BOOST_AUTO_TEST_CASE(CheckCommandHandler)
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100146{
Matteo Martincigh8a837172019-10-04 17:01:07 +0100147 PacketVersionResolver packetVersionResolver;
148 ProfilingStateMachine profilingStateMachine;
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100149
Matteo Martincigh8a837172019-10-04 17:01:07 +0100150 TestProfilingConnectionBase testProfilingConnectionBase;
151 TestProfilingConnectionTimeoutError testProfilingConnectionTimeOutError;
152 TestProfilingConnectionArmnnError testProfilingConnectionArmnnError;
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100153
Matteo Martincigh8a837172019-10-04 17:01:07 +0100154 ConnectionAcknowledgedCommandHandler connectionAcknowledgedCommandHandler(1, 4194304, profilingStateMachine);
155 CommandHandlerRegistry commandHandlerRegistry;
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100156
Matteo Martincigh8a837172019-10-04 17:01:07 +0100157 commandHandlerRegistry.RegisterFunctor(&connectionAcknowledgedCommandHandler, 1, 4194304);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100158
Matteo Martincigh8a837172019-10-04 17:01:07 +0100159 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
160 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100161
Matteo Martincigh8a837172019-10-04 17:01:07 +0100162 CommandHandler commandHandler0(1,
163 true,
164 commandHandlerRegistry,
165 packetVersionResolver);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100166
Matteo Martincigh8a837172019-10-04 17:01:07 +0100167 commandHandler0.Start(testProfilingConnectionBase);
168 commandHandler0.Start(testProfilingConnectionBase);
169 commandHandler0.Start(testProfilingConnectionBase);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100170
Matteo Martincigh8a837172019-10-04 17:01:07 +0100171 commandHandler0.Stop();
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100172
Matteo Martincigh8a837172019-10-04 17:01:07 +0100173 BOOST_CHECK(profilingStateMachine.GetCurrentState() == ProfilingState::Active);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100174
Matteo Martincigh8a837172019-10-04 17:01:07 +0100175 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
176 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
177 // commandHandler1 should give up after one timeout
178 CommandHandler commandHandler1(1,
179 true,
180 commandHandlerRegistry,
181 packetVersionResolver);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100182
Matteo Martincigh8a837172019-10-04 17:01:07 +0100183 commandHandler1.Start(testProfilingConnectionTimeOutError);
Matteo Martincigh88813932019-10-04 14:40:04 +0100184
Matteo Martincigh8a837172019-10-04 17:01:07 +0100185 std::this_thread::sleep_for(std::chrono::milliseconds(100));
Matteo Martincigh88813932019-10-04 14:40:04 +0100186
Matteo Martincigh8a837172019-10-04 17:01:07 +0100187 BOOST_CHECK(!commandHandler1.IsRunning());
188 commandHandler1.Stop();
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100189
Matteo Martincigh8a837172019-10-04 17:01:07 +0100190 BOOST_CHECK(profilingStateMachine.GetCurrentState() == ProfilingState::WaitingForAck);
191 // Now commandHandler1 should persist after a timeout
192 commandHandler1.SetStopAfterTimeout(false);
193 commandHandler1.Start(testProfilingConnectionTimeOutError);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100194
Matteo Martincigh8a837172019-10-04 17:01:07 +0100195 for (int i = 0; i < 100; i++)
196 {
197 if (profilingStateMachine.GetCurrentState() == ProfilingState::Active)
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100198 {
Matteo Martincigh8a837172019-10-04 17:01:07 +0100199 break;
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100200 }
201
Matteo Martincigh8a837172019-10-04 17:01:07 +0100202 std::this_thread::sleep_for(std::chrono::milliseconds(5));
203 }
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100204
Matteo Martincigh8a837172019-10-04 17:01:07 +0100205 commandHandler1.Stop();
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100206
Matteo Martincigh8a837172019-10-04 17:01:07 +0100207 BOOST_CHECK(profilingStateMachine.GetCurrentState() == ProfilingState::Active);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100208
Matteo Martincigh8a837172019-10-04 17:01:07 +0100209 CommandHandler commandHandler2(1,
210 false,
211 commandHandlerRegistry,
212 packetVersionResolver);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100213
Matteo Martincigh8a837172019-10-04 17:01:07 +0100214 commandHandler2.Start(testProfilingConnectionArmnnError);
215
216 for (int i = 0; i < 100; i++)
217 {
218 if (!commandHandler2.IsRunning())
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100219 {
Matteo Martincigh8a837172019-10-04 17:01:07 +0100220 // commandHandler2 should stop once it encounters a non timing error
221 return;
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100222 }
223
Matteo Martincigh8a837172019-10-04 17:01:07 +0100224 std::this_thread::sleep_for(std::chrono::milliseconds(5));
225 }
226
227 BOOST_ERROR("commandHandler2 has failed to stop");
228 commandHandler2.Stop();
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100229}
230
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100231BOOST_AUTO_TEST_CASE(CheckEncodeVersion)
232{
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100233 Version version1(12);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100234
235 BOOST_CHECK(version1.GetMajor() == 0);
236 BOOST_CHECK(version1.GetMinor() == 0);
237 BOOST_CHECK(version1.GetPatch() == 12);
238
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100239 Version version2(4108);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100240
241 BOOST_CHECK(version2.GetMajor() == 0);
242 BOOST_CHECK(version2.GetMinor() == 1);
243 BOOST_CHECK(version2.GetPatch() == 12);
244
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100245 Version version3(4198412);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100246
247 BOOST_CHECK(version3.GetMajor() == 1);
248 BOOST_CHECK(version3.GetMinor() == 1);
249 BOOST_CHECK(version3.GetPatch() == 12);
250
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100251 Version version4(0);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100252
253 BOOST_CHECK(version4.GetMajor() == 0);
254 BOOST_CHECK(version4.GetMinor() == 0);
255 BOOST_CHECK(version4.GetPatch() == 0);
256
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100257 Version version5(1, 0, 0);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100258 BOOST_CHECK(version5.GetEncodedValue() == 4194304);
259}
260
Nikhil Rajbc626052019-08-15 15:49:45 +0100261BOOST_AUTO_TEST_CASE(CheckPacketClass)
262{
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100263 uint32_t length = 4;
264 std::unique_ptr<char[]> packetData0 = std::make_unique<char[]>(length);
265 std::unique_ptr<char[]> packetData1 = std::make_unique<char[]>(0);
266 std::unique_ptr<char[]> nullPacketData;
Nikhil Rajbc626052019-08-15 15:49:45 +0100267
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100268 Packet packetTest0(472580096, length, packetData0);
Nikhil Rajbc626052019-08-15 15:49:45 +0100269
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100270 BOOST_CHECK(packetTest0.GetHeader() == 472580096);
271 BOOST_CHECK(packetTest0.GetPacketFamily() == 7);
272 BOOST_CHECK(packetTest0.GetPacketId() == 43);
273 BOOST_CHECK(packetTest0.GetLength() == length);
274 BOOST_CHECK(packetTest0.GetPacketType() == 3);
275 BOOST_CHECK(packetTest0.GetPacketClass() == 5);
Nikhil Rajbc626052019-08-15 15:49:45 +0100276
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100277 BOOST_CHECK_THROW(Packet packetTest1(472580096, 0, packetData1), armnn::Exception);
278 BOOST_CHECK_NO_THROW(Packet packetTest2(472580096, 0, nullPacketData));
Nikhil Rajbc626052019-08-15 15:49:45 +0100279
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100280 Packet packetTest3(472580096, 0, nullPacketData);
281 BOOST_CHECK(packetTest3.GetLength() == 0);
282 BOOST_CHECK(packetTest3.GetData() == nullptr);
283
284 const char* packetTest0Data = packetTest0.GetData();
285 Packet packetTest4(std::move(packetTest0));
286
287 BOOST_CHECK(packetTest0.GetData() == nullptr);
288 BOOST_CHECK(packetTest4.GetData() == packetTest0Data);
289
290 BOOST_CHECK(packetTest4.GetHeader() == 472580096);
291 BOOST_CHECK(packetTest4.GetPacketFamily() == 7);
292 BOOST_CHECK(packetTest4.GetPacketId() == 43);
293 BOOST_CHECK(packetTest4.GetLength() == length);
294 BOOST_CHECK(packetTest4.GetPacketType() == 3);
295 BOOST_CHECK(packetTest4.GetPacketClass() == 5);
Nikhil Rajbc626052019-08-15 15:49:45 +0100296}
297
Francis Murtagh94d79152019-08-16 17:45:07 +0100298// Create Derived Classes
299class TestFunctorA : public CommandHandlerFunctor
300{
301public:
302 using CommandHandlerFunctor::CommandHandlerFunctor;
303
304 int GetCount() { return m_Count; }
305
306 void operator()(const Packet& packet) override
307 {
308 m_Count++;
309 }
310
311private:
312 int m_Count = 0;
313};
314
315class TestFunctorB : public TestFunctorA
316{
317 using TestFunctorA::TestFunctorA;
318};
319
320class TestFunctorC : public TestFunctorA
321{
322 using TestFunctorA::TestFunctorA;
323};
324
Francis Murtagh11f99b42019-08-16 11:28:52 +0100325BOOST_AUTO_TEST_CASE(CheckCommandHandlerFunctor)
326{
Francis Murtagh11f99b42019-08-16 11:28:52 +0100327 // Hard code the version as it will be the same during a single profiling session
328 uint32_t version = 1;
329
330 TestFunctorA testFunctorA(461, version);
331 TestFunctorB testFunctorB(963, version);
332 TestFunctorC testFunctorC(983, version);
333
334 CommandHandlerKey keyA(testFunctorA.GetPacketId(), testFunctorA.GetVersion());
335 CommandHandlerKey keyB(testFunctorB.GetPacketId(), testFunctorB.GetVersion());
336 CommandHandlerKey keyC(testFunctorC.GetPacketId(), testFunctorC.GetVersion());
337
338 // Create the unwrapped map to simulate the Command Handler Registry
339 std::map<CommandHandlerKey, CommandHandlerFunctor*> registry;
340
341 registry.insert(std::make_pair(keyB, &testFunctorB));
342 registry.insert(std::make_pair(keyA, &testFunctorA));
343 registry.insert(std::make_pair(keyC, &testFunctorC));
344
345 // Check the order of the map is correct
346 auto it = registry.begin();
347 BOOST_CHECK(it->first==keyA);
348 it++;
349 BOOST_CHECK(it->first==keyB);
350 it++;
351 BOOST_CHECK(it->first==keyC);
352
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100353 std::unique_ptr<char[]> packetDataA;
354 std::unique_ptr<char[]> packetDataB;
355 std::unique_ptr<char[]> packetDataC;
356
357 Packet packetA(500000000, 0, packetDataA);
358 Packet packetB(600000000, 0, packetDataB);
359 Packet packetC(400000000, 0, packetDataC);
Francis Murtagh11f99b42019-08-16 11:28:52 +0100360
361 // Check the correct operator of derived class is called
362 registry.at(CommandHandlerKey(packetA.GetPacketId(), version))->operator()(packetA);
363 BOOST_CHECK(testFunctorA.GetCount() == 1);
364 BOOST_CHECK(testFunctorB.GetCount() == 0);
365 BOOST_CHECK(testFunctorC.GetCount() == 0);
366
367 registry.at(CommandHandlerKey(packetB.GetPacketId(), version))->operator()(packetB);
368 BOOST_CHECK(testFunctorA.GetCount() == 1);
369 BOOST_CHECK(testFunctorB.GetCount() == 1);
370 BOOST_CHECK(testFunctorC.GetCount() == 0);
371
372 registry.at(CommandHandlerKey(packetC.GetPacketId(), version))->operator()(packetC);
373 BOOST_CHECK(testFunctorA.GetCount() == 1);
374 BOOST_CHECK(testFunctorB.GetCount() == 1);
375 BOOST_CHECK(testFunctorC.GetCount() == 1);
376}
377
Francis Murtagh94d79152019-08-16 17:45:07 +0100378BOOST_AUTO_TEST_CASE(CheckCommandHandlerRegistry)
379{
380 // Hard code the version as it will be the same during a single profiling session
381 uint32_t version = 1;
382
383 TestFunctorA testFunctorA(461, version);
384 TestFunctorB testFunctorB(963, version);
385 TestFunctorC testFunctorC(983, version);
386
387 // Create the Command Handler Registry
388 CommandHandlerRegistry registry;
389
390 // Register multiple different derived classes
391 registry.RegisterFunctor(&testFunctorA, testFunctorA.GetPacketId(), testFunctorA.GetVersion());
392 registry.RegisterFunctor(&testFunctorB, testFunctorB.GetPacketId(), testFunctorB.GetVersion());
393 registry.RegisterFunctor(&testFunctorC, testFunctorC.GetPacketId(), testFunctorC.GetVersion());
394
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100395 std::unique_ptr<char[]> packetDataA;
396 std::unique_ptr<char[]> packetDataB;
397 std::unique_ptr<char[]> packetDataC;
398
399 Packet packetA(500000000, 0, packetDataA);
400 Packet packetB(600000000, 0, packetDataB);
401 Packet packetC(400000000, 0, packetDataC);
Francis Murtagh94d79152019-08-16 17:45:07 +0100402
403 // Check the correct operator of derived class is called
404 registry.GetFunctor(packetA.GetPacketId(), version)->operator()(packetA);
405 BOOST_CHECK(testFunctorA.GetCount() == 1);
406 BOOST_CHECK(testFunctorB.GetCount() == 0);
407 BOOST_CHECK(testFunctorC.GetCount() == 0);
408
409 registry.GetFunctor(packetB.GetPacketId(), version)->operator()(packetB);
410 BOOST_CHECK(testFunctorA.GetCount() == 1);
411 BOOST_CHECK(testFunctorB.GetCount() == 1);
412 BOOST_CHECK(testFunctorC.GetCount() == 0);
413
414 registry.GetFunctor(packetC.GetPacketId(), version)->operator()(packetC);
415 BOOST_CHECK(testFunctorA.GetCount() == 1);
416 BOOST_CHECK(testFunctorB.GetCount() == 1);
417 BOOST_CHECK(testFunctorC.GetCount() == 1);
418
419 // Re-register an existing key with a new function
420 registry.RegisterFunctor(&testFunctorC, testFunctorA.GetPacketId(), version);
421 registry.GetFunctor(packetA.GetPacketId(), version)->operator()(packetC);
422 BOOST_CHECK(testFunctorA.GetCount() == 1);
423 BOOST_CHECK(testFunctorB.GetCount() == 1);
424 BOOST_CHECK(testFunctorC.GetCount() == 2);
425
426 // Check that non-existent key returns nullptr for its functor
427 BOOST_CHECK_THROW(registry.GetFunctor(0, 0), armnn::Exception);
428}
429
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100430BOOST_AUTO_TEST_CASE(CheckPacketVersionResolver)
431{
432 // Set up random number generator for generating packetId values
433 std::random_device device;
434 std::mt19937 generator(device());
435 std::uniform_int_distribution<uint32_t> distribution(std::numeric_limits<uint32_t>::min(),
436 std::numeric_limits<uint32_t>::max());
437
438 // NOTE: Expected version is always 1.0.0, regardless of packetId
439 const Version expectedVersion(1, 0, 0);
440
441 PacketVersionResolver packetVersionResolver;
442
443 constexpr unsigned int numTests = 10u;
444
445 for (unsigned int i = 0u; i < numTests; ++i)
446 {
447 const uint32_t packetId = distribution(generator);
448 Version resolvedVersion = packetVersionResolver.ResolvePacketVersion(packetId);
449
450 BOOST_TEST(resolvedVersion == expectedVersion);
451 }
452}
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100453void ProfilingCurrentStateThreadImpl(ProfilingStateMachine& states)
454{
455 ProfilingState newState = ProfilingState::NotConnected;
456 states.GetCurrentState();
457 states.TransitionToState(newState);
458}
459
460BOOST_AUTO_TEST_CASE(CheckProfilingStateMachine)
461{
462 ProfilingStateMachine profilingState1(ProfilingState::Uninitialised);
463 profilingState1.TransitionToState(ProfilingState::Uninitialised);
464 BOOST_CHECK(profilingState1.GetCurrentState() == ProfilingState::Uninitialised);
465
466 ProfilingStateMachine profilingState2(ProfilingState::Uninitialised);
467 profilingState2.TransitionToState(ProfilingState::NotConnected);
468 BOOST_CHECK(profilingState2.GetCurrentState() == ProfilingState::NotConnected);
469
470 ProfilingStateMachine profilingState3(ProfilingState::NotConnected);
471 profilingState3.TransitionToState(ProfilingState::NotConnected);
472 BOOST_CHECK(profilingState3.GetCurrentState() == ProfilingState::NotConnected);
473
474 ProfilingStateMachine profilingState4(ProfilingState::NotConnected);
475 profilingState4.TransitionToState(ProfilingState::WaitingForAck);
476 BOOST_CHECK(profilingState4.GetCurrentState() == ProfilingState::WaitingForAck);
477
478 ProfilingStateMachine profilingState5(ProfilingState::WaitingForAck);
479 profilingState5.TransitionToState(ProfilingState::WaitingForAck);
480 BOOST_CHECK(profilingState5.GetCurrentState() == ProfilingState::WaitingForAck);
481
482 ProfilingStateMachine profilingState6(ProfilingState::WaitingForAck);
483 profilingState6.TransitionToState(ProfilingState::Active);
484 BOOST_CHECK(profilingState6.GetCurrentState() == ProfilingState::Active);
485
486 ProfilingStateMachine profilingState7(ProfilingState::Active);
487 profilingState7.TransitionToState(ProfilingState::NotConnected);
488 BOOST_CHECK(profilingState7.GetCurrentState() == ProfilingState::NotConnected);
489
490 ProfilingStateMachine profilingState8(ProfilingState::Active);
491 profilingState8.TransitionToState(ProfilingState::Active);
492 BOOST_CHECK(profilingState8.GetCurrentState() == ProfilingState::Active);
493
494 ProfilingStateMachine profilingState9(ProfilingState::Uninitialised);
495 BOOST_CHECK_THROW(profilingState9.TransitionToState(ProfilingState::WaitingForAck),
496 armnn::Exception);
497
498 ProfilingStateMachine profilingState10(ProfilingState::Uninitialised);
499 BOOST_CHECK_THROW(profilingState10.TransitionToState(ProfilingState::Active),
500 armnn::Exception);
501
502 ProfilingStateMachine profilingState11(ProfilingState::NotConnected);
503 BOOST_CHECK_THROW(profilingState11.TransitionToState(ProfilingState::Uninitialised),
504 armnn::Exception);
505
506 ProfilingStateMachine profilingState12(ProfilingState::NotConnected);
507 BOOST_CHECK_THROW(profilingState12.TransitionToState(ProfilingState::Active),
508 armnn::Exception);
509
510 ProfilingStateMachine profilingState13(ProfilingState::WaitingForAck);
511 BOOST_CHECK_THROW(profilingState13.TransitionToState(ProfilingState::Uninitialised),
512 armnn::Exception);
513
514 ProfilingStateMachine profilingState14(ProfilingState::WaitingForAck);
515 BOOST_CHECK_THROW(profilingState14.TransitionToState(ProfilingState::NotConnected),
516 armnn::Exception);
517
518 ProfilingStateMachine profilingState15(ProfilingState::Active);
519 BOOST_CHECK_THROW(profilingState15.TransitionToState(ProfilingState::Uninitialised),
520 armnn::Exception);
521
522 ProfilingStateMachine profilingState16(armnn::profiling::ProfilingState::Active);
523 BOOST_CHECK_THROW(profilingState16.TransitionToState(ProfilingState::WaitingForAck),
524 armnn::Exception);
525
526 ProfilingStateMachine profilingState17(ProfilingState::Uninitialised);
527
528 std::thread thread1 (ProfilingCurrentStateThreadImpl,std::ref(profilingState17));
529 std::thread thread2 (ProfilingCurrentStateThreadImpl,std::ref(profilingState17));
530 std::thread thread3 (ProfilingCurrentStateThreadImpl,std::ref(profilingState17));
531 std::thread thread4 (ProfilingCurrentStateThreadImpl,std::ref(profilingState17));
532 std::thread thread5 (ProfilingCurrentStateThreadImpl,std::ref(profilingState17));
533
534 thread1.join();
535 thread2.join();
536 thread3.join();
537 thread4.join();
538 thread5.join();
539
540 BOOST_TEST((profilingState17.GetCurrentState() == ProfilingState::NotConnected));
541}
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100542
Jim Flynn8355ec92019-09-17 12:29:50 +0100543void CaptureDataWriteThreadImpl(Holder& holder, uint32_t capturePeriod, const std::vector<uint16_t>& counterIds)
Francis Murtagh68f78d82019-09-04 16:42:29 +0100544{
545 holder.SetCaptureData(capturePeriod, counterIds);
546}
547
Francis Murtaghbd707162019-09-09 11:26:44 +0100548void CaptureDataReadThreadImpl(const Holder& holder, CaptureData& captureData)
Francis Murtagh68f78d82019-09-04 16:42:29 +0100549{
550 captureData = holder.GetCaptureData();
551}
552
553BOOST_AUTO_TEST_CASE(CheckCaptureDataHolder)
554{
Francis Murtaghbd707162019-09-09 11:26:44 +0100555 std::map<uint32_t, std::vector<uint16_t>> periodIdMap;
556 std::vector<uint16_t> counterIds;
Jim Flynn8355ec92019-09-17 12:29:50 +0100557 uint32_t numThreads = 10;
558 for (uint32_t i = 0; i < numThreads; ++i)
Francis Murtaghbd707162019-09-09 11:26:44 +0100559 {
560 counterIds.emplace_back(i);
561 periodIdMap.insert(std::make_pair(i, counterIds));
562 }
Francis Murtagh68f78d82019-09-04 16:42:29 +0100563
Jim Flynn8355ec92019-09-17 12:29:50 +0100564 // Verify the read and write threads set the holder correctly
565 // and retrieve the expected values
Francis Murtagh68f78d82019-09-04 16:42:29 +0100566 Holder holder;
567 BOOST_CHECK((holder.GetCaptureData()).GetCapturePeriod() == 0);
568 BOOST_CHECK(((holder.GetCaptureData()).GetCounterIds()).empty());
569
570 // Check Holder functions
Francis Murtaghbd707162019-09-09 11:26:44 +0100571 std::thread thread1(CaptureDataWriteThreadImpl, std::ref(holder), 2, std::ref(periodIdMap[2]));
Francis Murtagh68f78d82019-09-04 16:42:29 +0100572 thread1.join();
Francis Murtaghbd707162019-09-09 11:26:44 +0100573 BOOST_CHECK((holder.GetCaptureData()).GetCapturePeriod() == 2);
574 BOOST_CHECK((holder.GetCaptureData()).GetCounterIds() == periodIdMap[2]);
Jim Flynn8355ec92019-09-17 12:29:50 +0100575 // NOTE: now that we have some initial values in the holder we don't have to worry
576 // in the multi-threaded section below about a read thread accessing the holder
577 // before any write thread has gotten to it so we read period = 0, counterIds empty
578 // instead of period = 0, counterIds = {0} as will the case when write thread 0
579 // has executed.
Francis Murtagh68f78d82019-09-04 16:42:29 +0100580
581 CaptureData captureData;
582 std::thread thread2(CaptureDataReadThreadImpl, std::ref(holder), std::ref(captureData));
583 thread2.join();
Jim Flynn8355ec92019-09-17 12:29:50 +0100584 BOOST_CHECK(captureData.GetCapturePeriod() == 2);
Francis Murtaghbd707162019-09-09 11:26:44 +0100585 BOOST_CHECK(captureData.GetCounterIds() == periodIdMap[2]);
Francis Murtagh68f78d82019-09-04 16:42:29 +0100586
Jim Flynn8355ec92019-09-17 12:29:50 +0100587 std::map<uint32_t, CaptureData> captureDataIdMap;
588 for (uint32_t i = 0; i < numThreads; ++i)
589 {
590 CaptureData perThreadCaptureData;
591 captureDataIdMap.insert(std::make_pair(i, perThreadCaptureData));
592 }
593
Francis Murtaghbd707162019-09-09 11:26:44 +0100594 std::vector<std::thread> threadsVect;
Jim Flynn8355ec92019-09-17 12:29:50 +0100595 std::vector<std::thread> readThreadsVect;
596 for (uint32_t i = 0; i < numThreads; ++i)
Francis Murtaghbd707162019-09-09 11:26:44 +0100597 {
598 threadsVect.emplace_back(std::thread(CaptureDataWriteThreadImpl,
599 std::ref(holder),
600 i,
Jim Flynn8355ec92019-09-17 12:29:50 +0100601 std::ref(periodIdMap[i])));
Francis Murtagh06965692019-09-05 16:29:01 +0100602
Jim Flynn8355ec92019-09-17 12:29:50 +0100603 // Verify that the CaptureData goes into the thread in a virgin state
604 BOOST_CHECK(captureDataIdMap.at(i).GetCapturePeriod() == 0);
605 BOOST_CHECK(captureDataIdMap.at(i).GetCounterIds().empty());
606 readThreadsVect.emplace_back(std::thread(CaptureDataReadThreadImpl,
607 std::ref(holder),
608 std::ref(captureDataIdMap.at(i))));
Francis Murtaghbd707162019-09-09 11:26:44 +0100609 }
610
Jim Flynn8355ec92019-09-17 12:29:50 +0100611 for (uint32_t i = 0; i < numThreads; ++i)
Francis Murtaghbd707162019-09-09 11:26:44 +0100612 {
613 threadsVect[i].join();
Francis Murtaghbd707162019-09-09 11:26:44 +0100614 readThreadsVect[i].join();
615 }
Francis Murtagh68f78d82019-09-04 16:42:29 +0100616
Jim Flynn8355ec92019-09-17 12:29:50 +0100617 // Look at the CaptureData that each read thread has filled
618 // the capture period it read should match the counter ids entry
619 for (uint32_t i = 0; i < numThreads; ++i)
620 {
621 CaptureData perThreadCaptureData = captureDataIdMap.at(i);
622 BOOST_CHECK(perThreadCaptureData.GetCounterIds() == periodIdMap.at(perThreadCaptureData.GetCapturePeriod()));
623 }
Matthew Bentham46d1c622019-09-13 12:45:04 +0100624}
Francis Murtagh68f78d82019-09-04 16:42:29 +0100625
Matthew Bentham46d1c622019-09-13 12:45:04 +0100626BOOST_AUTO_TEST_CASE(CaptureDataMethods)
627{
Jim Flynn8355ec92019-09-17 12:29:50 +0100628 // Check CaptureData setter and getter functions
Matthew Bentham46d1c622019-09-13 12:45:04 +0100629 std::vector<uint16_t> counterIds = {42, 29, 13};
Jim Flynn8355ec92019-09-17 12:29:50 +0100630 CaptureData captureData;
631 BOOST_CHECK(captureData.GetCapturePeriod() == 0);
632 BOOST_CHECK((captureData.GetCounterIds()).empty());
633 captureData.SetCapturePeriod(150);
634 captureData.SetCounterIds(counterIds);
635 BOOST_CHECK(captureData.GetCapturePeriod() == 150);
636 BOOST_CHECK(captureData.GetCounterIds() == counterIds);
Francis Murtagh68f78d82019-09-04 16:42:29 +0100637
Jim Flynn8355ec92019-09-17 12:29:50 +0100638 // Check assignment operator
Francis Murtagh68f78d82019-09-04 16:42:29 +0100639 CaptureData secondCaptureData;
Francis Murtagh68f78d82019-09-04 16:42:29 +0100640
Jim Flynn8355ec92019-09-17 12:29:50 +0100641 secondCaptureData = captureData;
642 BOOST_CHECK(secondCaptureData.GetCapturePeriod() == 150);
Matthew Bentham46d1c622019-09-13 12:45:04 +0100643 BOOST_CHECK(secondCaptureData.GetCounterIds() == counterIds);
Francis Murtagh68f78d82019-09-04 16:42:29 +0100644
645 // Check copy constructor
Jim Flynn8355ec92019-09-17 12:29:50 +0100646 CaptureData copyConstructedCaptureData(captureData);
Francis Murtagh68f78d82019-09-04 16:42:29 +0100647
Jim Flynn8355ec92019-09-17 12:29:50 +0100648 BOOST_CHECK(copyConstructedCaptureData.GetCapturePeriod() == 150);
Matthew Bentham46d1c622019-09-13 12:45:04 +0100649 BOOST_CHECK(copyConstructedCaptureData.GetCounterIds() == counterIds);
Keith Davis02356de2019-08-26 18:28:17 +0100650}
Francis Murtagh68f78d82019-09-04 16:42:29 +0100651
Keith Davis02356de2019-08-26 18:28:17 +0100652BOOST_AUTO_TEST_CASE(CheckProfilingServiceDisabled)
653{
654 armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
Matteo Martincigha84edee2019-10-02 12:50:57 +0100655 ProfilingService& profilingService = ProfilingService::Instance();
656 profilingService.ResetExternalProfilingOptions(options, true);
657 BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
658 profilingService.Run();
659 BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis02356de2019-08-26 18:28:17 +0100660}
661
Matteo Martincigha84edee2019-10-02 12:50:57 +0100662struct cerr_redirect
663{
Sadik Armaganbd9e2c52019-09-26 23:13:31 +0100664 cerr_redirect(std::streambuf* new_buffer)
Matteo Martincigha84edee2019-10-02 12:50:57 +0100665 : old(std::cerr.rdbuf(new_buffer)) {}
666 ~cerr_redirect() { std::cerr.rdbuf(old); }
Sadik Armaganbd9e2c52019-09-26 23:13:31 +0100667
668private:
669 std::streambuf* old;
670};
671
Keith Davis02356de2019-08-26 18:28:17 +0100672BOOST_AUTO_TEST_CASE(CheckProfilingServiceEnabled)
673{
674 armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
675 options.m_EnableProfiling = true;
Matteo Martincigha84edee2019-10-02 12:50:57 +0100676 ProfilingService& profilingService = ProfilingService::Instance();
677 profilingService.ResetExternalProfilingOptions(options, true);
678 BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis02356de2019-08-26 18:28:17 +0100679
Sadik Armaganbd9e2c52019-09-26 23:13:31 +0100680 // As there is no daemon running a connection cannot be made so expect a std::cerr to console
681 std::stringstream ss;
682 cerr_redirect guard(ss.rdbuf());
Matteo Martincigha84edee2019-10-02 12:50:57 +0100683 profilingService.Run();
Sadik Armaganbd9e2c52019-09-26 23:13:31 +0100684 BOOST_CHECK(boost::contains(ss.str(), "Cannot connect to stream socket: Connection refused"));
685}
Keith Davis02356de2019-08-26 18:28:17 +0100686
687BOOST_AUTO_TEST_CASE(CheckProfilingServiceEnabledRuntime)
688{
689 armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
Matteo Martincigha84edee2019-10-02 12:50:57 +0100690 ProfilingService& profilingService = ProfilingService::Instance();
691 profilingService.ResetExternalProfilingOptions(options, true);
692 BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
693 profilingService.Run();
694 BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100695 options.m_EnableProfiling = true;
Matteo Martincigha84edee2019-10-02 12:50:57 +0100696 profilingService.ResetExternalProfilingOptions(options);
697 BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Sadik Armaganbd9e2c52019-09-26 23:13:31 +0100698
699 // As there is no daemon running a connection cannot be made so expect a std::cerr to console
700 std::stringstream ss;
701 cerr_redirect guard(ss.rdbuf());
Matteo Martincigha84edee2019-10-02 12:50:57 +0100702 profilingService.Run();
Sadik Armaganbd9e2c52019-09-26 23:13:31 +0100703 BOOST_CHECK(boost::contains(ss.str(), "Cannot connect to stream socket: Connection refused"));
Francis Murtagh68f78d82019-09-04 16:42:29 +0100704}
705
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100706BOOST_AUTO_TEST_CASE(CheckProfilingServiceCounterDirectory)
707{
708 armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
Matteo Martincigha84edee2019-10-02 12:50:57 +0100709 ProfilingService& profilingService = ProfilingService::Instance();
710 profilingService.ResetExternalProfilingOptions(options, true);
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100711
Matteo Martincigha84edee2019-10-02 12:50:57 +0100712 const ICounterDirectory& counterDirectory0 = profilingService.GetCounterDirectory();
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100713 BOOST_CHECK(counterDirectory0.GetCounterCount() == 0);
714
715 options.m_EnableProfiling = true;
Matteo Martincigha84edee2019-10-02 12:50:57 +0100716 profilingService.ResetExternalProfilingOptions(options);
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100717
Matteo Martincigha84edee2019-10-02 12:50:57 +0100718 const ICounterDirectory& counterDirectory1 = profilingService.GetCounterDirectory();
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100719 BOOST_CHECK(counterDirectory1.GetCounterCount() != 0);
720}
721
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100722BOOST_AUTO_TEST_CASE(CheckProfilingServiceCounterValues)
723{
724 armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
725 options.m_EnableProfiling = true;
Matteo Martincigha84edee2019-10-02 12:50:57 +0100726 ProfilingService& profilingService = ProfilingService::Instance();
727 profilingService.ResetExternalProfilingOptions(options, true);
728
729 const ICounterDirectory& counterDirectory = profilingService.GetCounterDirectory();
730 const Counters& counters = counterDirectory.GetCounters();
731 BOOST_CHECK(!counters.empty());
732
733 // Get the UID of the first counter for testing
734 uint16_t counterUid = counters.begin()->first;
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100735
736 ProfilingService* profilingServicePtr = &profilingService;
737 std::vector<std::thread> writers;
738
Matteo Martincigha84edee2019-10-02 12:50:57 +0100739 for (int i = 0; i < 100 ; ++i)
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100740 {
Matteo Martincigha84edee2019-10-02 12:50:57 +0100741 // Increment and decrement the first counter
742 writers.push_back(std::thread(&ProfilingService::IncrementCounterValue, profilingServicePtr, counterUid));
743 writers.push_back(std::thread(&ProfilingService::DecrementCounterValue, profilingServicePtr, counterUid));
744 // Add 10 and subtract 5 from the first counter
745 writers.push_back(std::thread(&ProfilingService::AddCounterValue, profilingServicePtr, counterUid, 10));
746 writers.push_back(std::thread(&ProfilingService::SubtractCounterValue, profilingServicePtr, counterUid, 5));
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100747 }
748
749 std::for_each(writers.begin(), writers.end(), mem_fn(&std::thread::join));
750
Matteo Martincigha84edee2019-10-02 12:50:57 +0100751 uint32_t counterValue = 0;
752 BOOST_CHECK_NO_THROW(counterValue = profilingService.GetCounterValue(counterUid));
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100753 BOOST_CHECK(counterValue == 500);
754
Matteo Martincigha84edee2019-10-02 12:50:57 +0100755 BOOST_CHECK_NO_THROW(profilingService.SetCounterValue(counterUid, 0));
756 BOOST_CHECK_NO_THROW(counterValue = profilingService.GetCounterValue(counterUid));
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100757 BOOST_CHECK(counterValue == 0);
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100758}
759
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100760BOOST_AUTO_TEST_CASE(CheckProfilingObjectUids)
Matteo Martincighab173e92019-09-05 12:02:04 +0100761{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100762 uint16_t uid = 0;
763 BOOST_CHECK_NO_THROW(uid = GetNextUid());
764 BOOST_CHECK(uid >= 1);
765
766 uint16_t nextUid = 0;
767 BOOST_CHECK_NO_THROW(nextUid = GetNextUid());
768 BOOST_CHECK(nextUid > uid);
769
770 std::vector<uint16_t> counterUids;
771 BOOST_CHECK_NO_THROW(counterUids = GetNextCounterUids(0));
772 BOOST_CHECK(counterUids.size() == 1);
773 BOOST_CHECK(counterUids[0] >= 0);
774
775 std::vector<uint16_t> nextCounterUids;
776 BOOST_CHECK_NO_THROW(nextCounterUids = GetNextCounterUids(1));
777 BOOST_CHECK(nextCounterUids.size() == 1);
778 BOOST_CHECK(nextCounterUids[0] > counterUids[0]);
779
780 std::vector<uint16_t> counterUidsMultiCore;
781 uint16_t numberOfCores = 13;
782 BOOST_CHECK_NO_THROW(counterUidsMultiCore = GetNextCounterUids(numberOfCores));
783 BOOST_CHECK(counterUidsMultiCore.size() == numberOfCores);
784 BOOST_CHECK(counterUidsMultiCore.front() >= nextCounterUids[0]);
785 for (size_t i = 1; i < numberOfCores; i ++)
786 {
787 BOOST_CHECK(counterUidsMultiCore[i] == counterUidsMultiCore[i - 1] + 1);
788 }
789 BOOST_CHECK(counterUidsMultiCore.back() == counterUidsMultiCore.front() + numberOfCores - 1);
Matteo Martincighab173e92019-09-05 12:02:04 +0100790}
791
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100792BOOST_AUTO_TEST_CASE(CheckCounterDirectoryRegisterCategory)
Matteo Martincighab173e92019-09-05 12:02:04 +0100793{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100794 CounterDirectory counterDirectory;
795 BOOST_CHECK(counterDirectory.GetCategoryCount() == 0);
796 BOOST_CHECK(counterDirectory.GetDeviceCount() == 0);
797 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 0);
798 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
Matteo Martincighab173e92019-09-05 12:02:04 +0100799
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100800 // Register a category with an invalid name
801 const Category* noCategory = nullptr;
802 BOOST_CHECK_THROW(noCategory = counterDirectory.RegisterCategory(""), armnn::InvalidArgumentException);
803 BOOST_CHECK(counterDirectory.GetCategoryCount() == 0);
804 BOOST_CHECK(!noCategory);
Matteo Martincighab173e92019-09-05 12:02:04 +0100805
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100806 // Register a category with an invalid name
807 BOOST_CHECK_THROW(noCategory = counterDirectory.RegisterCategory("invalid category"),
808 armnn::InvalidArgumentException);
809 BOOST_CHECK(counterDirectory.GetCategoryCount() == 0);
810 BOOST_CHECK(!noCategory);
811
812 // Register a new category
813 const std::string categoryName = "some_category";
814 const Category* category = nullptr;
815 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName));
816 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
817 BOOST_CHECK(category);
818 BOOST_CHECK(category->m_Name == categoryName);
819 BOOST_CHECK(category->m_Counters.empty());
820 BOOST_CHECK(category->m_DeviceUid == 0);
821 BOOST_CHECK(category->m_CounterSetUid == 0);
822
823 // Get the registered category
824 const Category* registeredCategory = counterDirectory.GetCategory(categoryName);
825 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
826 BOOST_CHECK(registeredCategory);
827 BOOST_CHECK(registeredCategory == category);
828
829 // Try to get a category not registered
830 const Category* notRegisteredCategory = counterDirectory.GetCategory("not_registered_category");
831 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
832 BOOST_CHECK(!notRegisteredCategory);
833
834 // Register a category already registered
835 const Category* anotherCategory = nullptr;
836 BOOST_CHECK_THROW(anotherCategory = counterDirectory.RegisterCategory(categoryName),
837 armnn::InvalidArgumentException);
838 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
839 BOOST_CHECK(!anotherCategory);
840
841 // Register a device for testing
842 const std::string deviceName = "some_device";
843 const Device* device = nullptr;
844 BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName));
845 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
846 BOOST_CHECK(device);
847 BOOST_CHECK(device->m_Uid >= 1);
848 BOOST_CHECK(device->m_Name == deviceName);
849 BOOST_CHECK(device->m_Cores == 0);
850
851 // Register a new category not associated to any device
852 const std::string categoryWoDeviceName = "some_category_without_device";
853 const Category* categoryWoDevice = nullptr;
854 BOOST_CHECK_NO_THROW(categoryWoDevice = counterDirectory.RegisterCategory(categoryWoDeviceName, 0));
855 BOOST_CHECK(counterDirectory.GetCategoryCount() == 2);
856 BOOST_CHECK(categoryWoDevice);
857 BOOST_CHECK(categoryWoDevice->m_Name == categoryWoDeviceName);
858 BOOST_CHECK(categoryWoDevice->m_Counters.empty());
859 BOOST_CHECK(categoryWoDevice->m_DeviceUid == 0);
860 BOOST_CHECK(categoryWoDevice->m_CounterSetUid == 0);
861
862 // Register a new category associated to an invalid device
863 const std::string categoryWInvalidDeviceName = "some_category_with_invalid_device";
864
865 ARMNN_NO_CONVERSION_WARN_BEGIN
866 uint16_t invalidDeviceUid = device->m_Uid + 10;
867 ARMNN_NO_CONVERSION_WARN_END
868
869 const Category* categoryWInvalidDevice = nullptr;
870 BOOST_CHECK_THROW(categoryWInvalidDevice
871 = counterDirectory.RegisterCategory(categoryWInvalidDeviceName,
872 invalidDeviceUid),
873 armnn::InvalidArgumentException);
874 BOOST_CHECK(counterDirectory.GetCategoryCount() == 2);
875 BOOST_CHECK(!categoryWInvalidDevice);
876
877 // Register a new category associated to a valid device
878 const std::string categoryWValidDeviceName = "some_category_with_valid_device";
879 const Category* categoryWValidDevice = nullptr;
880 BOOST_CHECK_NO_THROW(categoryWValidDevice
881 = counterDirectory.RegisterCategory(categoryWValidDeviceName,
882 device->m_Uid));
883 BOOST_CHECK(counterDirectory.GetCategoryCount() == 3);
884 BOOST_CHECK(categoryWValidDevice);
885 BOOST_CHECK(categoryWValidDevice != category);
886 BOOST_CHECK(categoryWValidDevice->m_Name == categoryWValidDeviceName);
887 BOOST_CHECK(categoryWValidDevice->m_DeviceUid == device->m_Uid);
888 BOOST_CHECK(categoryWValidDevice->m_CounterSetUid == 0);
889
890 // Register a counter set for testing
891 const std::string counterSetName = "some_counter_set";
892 const CounterSet* counterSet = nullptr;
893 BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
894 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
895 BOOST_CHECK(counterSet);
896 BOOST_CHECK(counterSet->m_Uid >= 1);
897 BOOST_CHECK(counterSet->m_Name == counterSetName);
898 BOOST_CHECK(counterSet->m_Count == 0);
899
900 // Register a new category not associated to any counter set
901 const std::string categoryWoCounterSetName = "some_category_without_counter_set";
902 const Category* categoryWoCounterSet = nullptr;
903 BOOST_CHECK_NO_THROW(categoryWoCounterSet
904 = counterDirectory.RegisterCategory(categoryWoCounterSetName,
905 armnn::EmptyOptional(),
906 0));
907 BOOST_CHECK(counterDirectory.GetCategoryCount() == 4);
908 BOOST_CHECK(categoryWoCounterSet);
909 BOOST_CHECK(categoryWoCounterSet->m_Name == categoryWoCounterSetName);
910 BOOST_CHECK(categoryWoCounterSet->m_DeviceUid == 0);
911 BOOST_CHECK(categoryWoCounterSet->m_CounterSetUid == 0);
912
913 // Register a new category associated to an invalid counter set
914 const std::string categoryWInvalidCounterSetName = "some_category_with_invalid_counter_set";
915
916 ARMNN_NO_CONVERSION_WARN_BEGIN
917 uint16_t invalidCunterSetUid = counterSet->m_Uid + 10;
918 ARMNN_NO_CONVERSION_WARN_END
919
920 const Category* categoryWInvalidCounterSet = nullptr;
921 BOOST_CHECK_THROW(categoryWInvalidCounterSet
922 = counterDirectory.RegisterCategory(categoryWInvalidCounterSetName,
923 armnn::EmptyOptional(),
924 invalidCunterSetUid),
925 armnn::InvalidArgumentException);
926 BOOST_CHECK(counterDirectory.GetCategoryCount() == 4);
927 BOOST_CHECK(!categoryWInvalidCounterSet);
928
929 // Register a new category associated to a valid counter set
930 const std::string categoryWValidCounterSetName = "some_category_with_valid_counter_set";
931 const Category* categoryWValidCounterSet = nullptr;
932 BOOST_CHECK_NO_THROW(categoryWValidCounterSet
933 = counterDirectory.RegisterCategory(categoryWValidCounterSetName,
934 armnn::EmptyOptional(),
935 counterSet->m_Uid));
936 BOOST_CHECK(counterDirectory.GetCategoryCount() == 5);
937 BOOST_CHECK(categoryWValidCounterSet);
938 BOOST_CHECK(categoryWValidCounterSet != category);
939 BOOST_CHECK(categoryWValidCounterSet->m_Name == categoryWValidCounterSetName);
940 BOOST_CHECK(categoryWValidCounterSet->m_DeviceUid == 0);
941 BOOST_CHECK(categoryWValidCounterSet->m_CounterSetUid == counterSet->m_Uid);
942
943 // Register a new category associated to a valid device and counter set
944 const std::string categoryWValidDeviceAndValidCounterSetName = "some_category_with_valid_device_and_counter_set";
945 const Category* categoryWValidDeviceAndValidCounterSet = nullptr;
946 BOOST_CHECK_NO_THROW(categoryWValidDeviceAndValidCounterSet
947 = counterDirectory.RegisterCategory(categoryWValidDeviceAndValidCounterSetName,
948 device->m_Uid,
949 counterSet->m_Uid));
950 BOOST_CHECK(counterDirectory.GetCategoryCount() == 6);
951 BOOST_CHECK(categoryWValidDeviceAndValidCounterSet);
952 BOOST_CHECK(categoryWValidDeviceAndValidCounterSet != category);
953 BOOST_CHECK(categoryWValidDeviceAndValidCounterSet->m_Name == categoryWValidDeviceAndValidCounterSetName);
954 BOOST_CHECK(categoryWValidDeviceAndValidCounterSet->m_DeviceUid == device->m_Uid);
955 BOOST_CHECK(categoryWValidDeviceAndValidCounterSet->m_CounterSetUid == counterSet->m_Uid);
956}
957
958BOOST_AUTO_TEST_CASE(CheckCounterDirectoryRegisterDevice)
959{
960 CounterDirectory counterDirectory;
961 BOOST_CHECK(counterDirectory.GetCategoryCount() == 0);
962 BOOST_CHECK(counterDirectory.GetDeviceCount() == 0);
963 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 0);
964 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
965
966 // Register a device with an invalid name
967 const Device* noDevice = nullptr;
968 BOOST_CHECK_THROW(noDevice = counterDirectory.RegisterDevice(""), armnn::InvalidArgumentException);
969 BOOST_CHECK(counterDirectory.GetDeviceCount() == 0);
970 BOOST_CHECK(!noDevice);
971
972 // Register a device with an invalid name
973 BOOST_CHECK_THROW(noDevice = counterDirectory.RegisterDevice("inv@lid nam€"), armnn::InvalidArgumentException);
974 BOOST_CHECK(counterDirectory.GetDeviceCount() == 0);
975 BOOST_CHECK(!noDevice);
976
977 // Register a new device with no cores or parent category
978 const std::string deviceName = "some_device";
979 const Device* device = nullptr;
980 BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName));
981 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
982 BOOST_CHECK(device);
983 BOOST_CHECK(device->m_Name == deviceName);
984 BOOST_CHECK(device->m_Uid >= 1);
985 BOOST_CHECK(device->m_Cores == 0);
986
Matteo Martincigh657ab2d2019-09-18 10:53:24 +0100987 // Try getting an unregistered device
988 const Device* unregisteredDevice = counterDirectory.GetDevice(9999);
989 BOOST_CHECK(!unregisteredDevice);
990
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100991 // Get the registered device
992 const Device* registeredDevice = counterDirectory.GetDevice(device->m_Uid);
993 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
994 BOOST_CHECK(registeredDevice);
995 BOOST_CHECK(registeredDevice == device);
996
Matteo Martincigh657ab2d2019-09-18 10:53:24 +0100997 // Register a device with the name of a device already registered
998 const Device* deviceSameName = nullptr;
999 BOOST_CHECK_THROW(deviceSameName = counterDirectory.RegisterDevice(deviceName), armnn::InvalidArgumentException);
1000 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1001 BOOST_CHECK(!deviceSameName);
1002
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001003 // Register a new device with cores and no parent category
1004 const std::string deviceWCoresName = "some_device_with_cores";
1005 const Device* deviceWCores = nullptr;
1006 BOOST_CHECK_NO_THROW(deviceWCores = counterDirectory.RegisterDevice(deviceWCoresName, 2));
1007 BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
1008 BOOST_CHECK(deviceWCores);
1009 BOOST_CHECK(deviceWCores->m_Name == deviceWCoresName);
1010 BOOST_CHECK(deviceWCores->m_Uid >= 1);
1011 BOOST_CHECK(deviceWCores->m_Uid > device->m_Uid);
1012 BOOST_CHECK(deviceWCores->m_Cores == 2);
1013
1014 // Get the registered device
1015 const Device* registeredDeviceWCores = counterDirectory.GetDevice(deviceWCores->m_Uid);
1016 BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
1017 BOOST_CHECK(registeredDeviceWCores);
1018 BOOST_CHECK(registeredDeviceWCores == deviceWCores);
1019 BOOST_CHECK(registeredDeviceWCores != device);
1020
1021 // Register a new device with cores and invalid parent category
1022 const std::string deviceWCoresWInvalidParentCategoryName = "some_device_with_cores_with_invalid_parent_category";
1023 const Device* deviceWCoresWInvalidParentCategory = nullptr;
1024 BOOST_CHECK_THROW(deviceWCoresWInvalidParentCategory
1025 = counterDirectory.RegisterDevice(deviceWCoresWInvalidParentCategoryName,
1026 3,
1027 std::string("")),
1028 armnn::InvalidArgumentException);
1029 BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
1030 BOOST_CHECK(!deviceWCoresWInvalidParentCategory);
1031
1032 // Register a new device with cores and invalid parent category
1033 const std::string deviceWCoresWInvalidParentCategoryName2 = "some_device_with_cores_with_invalid_parent_category2";
1034 const Device* deviceWCoresWInvalidParentCategory2 = nullptr;
1035 BOOST_CHECK_THROW(deviceWCoresWInvalidParentCategory2
1036 = counterDirectory.RegisterDevice(deviceWCoresWInvalidParentCategoryName2,
1037 3,
1038 std::string("invalid_parent_category")),
1039 armnn::InvalidArgumentException);
1040 BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
1041 BOOST_CHECK(!deviceWCoresWInvalidParentCategory2);
1042
1043 // Register a category for testing
1044 const std::string categoryName = "some_category";
1045 const Category* category = nullptr;
1046 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName));
1047 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1048 BOOST_CHECK(category);
1049 BOOST_CHECK(category->m_Name == categoryName);
1050 BOOST_CHECK(category->m_Counters.empty());
1051 BOOST_CHECK(category->m_DeviceUid == 0);
1052 BOOST_CHECK(category->m_CounterSetUid == 0);
1053
1054 // Register a new device with cores and valid parent category
1055 const std::string deviceWCoresWValidParentCategoryName = "some_device_with_cores_with_valid_parent_category";
1056 const Device* deviceWCoresWValidParentCategory = nullptr;
1057 BOOST_CHECK_NO_THROW(deviceWCoresWValidParentCategory
1058 = counterDirectory.RegisterDevice(deviceWCoresWValidParentCategoryName,
1059 4,
1060 categoryName));
1061 BOOST_CHECK(counterDirectory.GetDeviceCount() == 3);
1062 BOOST_CHECK(deviceWCoresWValidParentCategory);
1063 BOOST_CHECK(deviceWCoresWValidParentCategory->m_Name == deviceWCoresWValidParentCategoryName);
1064 BOOST_CHECK(deviceWCoresWValidParentCategory->m_Uid >= 1);
1065 BOOST_CHECK(deviceWCoresWValidParentCategory->m_Uid > device->m_Uid);
1066 BOOST_CHECK(deviceWCoresWValidParentCategory->m_Uid > deviceWCores->m_Uid);
1067 BOOST_CHECK(deviceWCoresWValidParentCategory->m_Cores == 4);
1068 BOOST_CHECK(category->m_DeviceUid == deviceWCoresWValidParentCategory->m_Uid);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001069
1070 // Register a device associated to a category already associated to a different device
1071 const std::string deviceSameCategoryName = "some_device_with_invalid_parent_category";
1072 const Device* deviceSameCategory = nullptr;
1073 BOOST_CHECK_THROW(deviceSameCategory = counterDirectory.RegisterDevice(deviceSameCategoryName, 0, categoryName),
1074 armnn::InvalidArgumentException);
1075 BOOST_CHECK(counterDirectory.GetDeviceCount() == 3);
1076 BOOST_CHECK(!deviceSameCategory);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001077}
1078
1079BOOST_AUTO_TEST_CASE(CheckCounterDirectoryRegisterCounterSet)
1080{
1081 CounterDirectory counterDirectory;
1082 BOOST_CHECK(counterDirectory.GetCategoryCount() == 0);
1083 BOOST_CHECK(counterDirectory.GetDeviceCount() == 0);
1084 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 0);
1085 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1086
1087 // Register a counter set with an invalid name
1088 const CounterSet* noCounterSet = nullptr;
1089 BOOST_CHECK_THROW(noCounterSet = counterDirectory.RegisterCounterSet(""), armnn::InvalidArgumentException);
1090 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 0);
1091 BOOST_CHECK(!noCounterSet);
1092
1093 // Register a counter set with an invalid name
1094 BOOST_CHECK_THROW(noCounterSet = counterDirectory.RegisterCounterSet("invalid name"),
1095 armnn::InvalidArgumentException);
1096 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 0);
1097 BOOST_CHECK(!noCounterSet);
1098
1099 // Register a new counter set with no count or parent category
1100 const std::string counterSetName = "some_counter_set";
1101 const CounterSet* counterSet = nullptr;
1102 BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1103 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1104 BOOST_CHECK(counterSet);
1105 BOOST_CHECK(counterSet->m_Name == counterSetName);
1106 BOOST_CHECK(counterSet->m_Uid >= 1);
1107 BOOST_CHECK(counterSet->m_Count == 0);
1108
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001109 // Try getting an unregistered counter set
1110 const CounterSet* unregisteredCounterSet = counterDirectory.GetCounterSet(9999);
1111 BOOST_CHECK(!unregisteredCounterSet);
1112
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001113 // Get the registered counter set
1114 const CounterSet* registeredCounterSet = counterDirectory.GetCounterSet(counterSet->m_Uid);
1115 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1116 BOOST_CHECK(registeredCounterSet);
1117 BOOST_CHECK(registeredCounterSet == counterSet);
1118
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001119 // Register a counter set with the name of a counter set already registered
1120 const CounterSet* counterSetSameName = nullptr;
1121 BOOST_CHECK_THROW(counterSetSameName = counterDirectory.RegisterCounterSet(counterSetName),
1122 armnn::InvalidArgumentException);
1123 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1124 BOOST_CHECK(!counterSetSameName);
1125
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001126 // Register a new counter set with count and no parent category
1127 const std::string counterSetWCountName = "some_counter_set_with_count";
1128 const CounterSet* counterSetWCount = nullptr;
1129 BOOST_CHECK_NO_THROW(counterSetWCount = counterDirectory.RegisterCounterSet(counterSetWCountName, 37));
1130 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 2);
1131 BOOST_CHECK(counterSetWCount);
1132 BOOST_CHECK(counterSetWCount->m_Name == counterSetWCountName);
1133 BOOST_CHECK(counterSetWCount->m_Uid >= 1);
1134 BOOST_CHECK(counterSetWCount->m_Uid > counterSet->m_Uid);
1135 BOOST_CHECK(counterSetWCount->m_Count == 37);
1136
1137 // Get the registered counter set
1138 const CounterSet* registeredCounterSetWCount = counterDirectory.GetCounterSet(counterSetWCount->m_Uid);
1139 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 2);
1140 BOOST_CHECK(registeredCounterSetWCount);
1141 BOOST_CHECK(registeredCounterSetWCount == counterSetWCount);
1142 BOOST_CHECK(registeredCounterSetWCount != counterSet);
1143
1144 // Register a new counter set with count and invalid parent category
1145 const std::string counterSetWCountWInvalidParentCategoryName = "some_counter_set_with_count_"
1146 "with_invalid_parent_category";
1147 const CounterSet* counterSetWCountWInvalidParentCategory = nullptr;
1148 BOOST_CHECK_THROW(counterSetWCountWInvalidParentCategory
1149 = counterDirectory.RegisterCounterSet(counterSetWCountWInvalidParentCategoryName,
1150 42,
1151 std::string("")),
1152 armnn::InvalidArgumentException);
1153 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 2);
1154 BOOST_CHECK(!counterSetWCountWInvalidParentCategory);
1155
1156 // Register a new counter set with count and invalid parent category
1157 const std::string counterSetWCountWInvalidParentCategoryName2 = "some_counter_set_with_count_"
1158 "with_invalid_parent_category2";
1159 const CounterSet* counterSetWCountWInvalidParentCategory2 = nullptr;
1160 BOOST_CHECK_THROW(counterSetWCountWInvalidParentCategory2
1161 = counterDirectory.RegisterCounterSet(counterSetWCountWInvalidParentCategoryName2,
1162 42,
1163 std::string("invalid_parent_category")),
1164 armnn::InvalidArgumentException);
1165 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 2);
1166 BOOST_CHECK(!counterSetWCountWInvalidParentCategory2);
1167
1168 // Register a category for testing
1169 const std::string categoryName = "some_category";
1170 const Category* category = nullptr;
1171 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName));
1172 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1173 BOOST_CHECK(category);
1174 BOOST_CHECK(category->m_Name == categoryName);
1175 BOOST_CHECK(category->m_Counters.empty());
1176 BOOST_CHECK(category->m_DeviceUid == 0);
1177 BOOST_CHECK(category->m_CounterSetUid == 0);
1178
1179 // Register a new counter set with count and valid parent category
1180 const std::string counterSetWCountWValidParentCategoryName = "some_counter_set_with_count_"
1181 "with_valid_parent_category";
1182 const CounterSet* counterSetWCountWValidParentCategory = nullptr;
1183 BOOST_CHECK_NO_THROW(counterSetWCountWValidParentCategory
1184 = counterDirectory.RegisterCounterSet(counterSetWCountWValidParentCategoryName,
1185 42,
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001186 categoryName));
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001187 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 3);
1188 BOOST_CHECK(counterSetWCountWValidParentCategory);
1189 BOOST_CHECK(counterSetWCountWValidParentCategory->m_Name == counterSetWCountWValidParentCategoryName);
1190 BOOST_CHECK(counterSetWCountWValidParentCategory->m_Uid >= 1);
1191 BOOST_CHECK(counterSetWCountWValidParentCategory->m_Uid > counterSet->m_Uid);
1192 BOOST_CHECK(counterSetWCountWValidParentCategory->m_Uid > counterSetWCount->m_Uid);
1193 BOOST_CHECK(counterSetWCountWValidParentCategory->m_Count == 42);
1194 BOOST_CHECK(category->m_CounterSetUid == counterSetWCountWValidParentCategory->m_Uid);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001195
1196 // Register a counter set associated to a category already associated to a different counter set
1197 const std::string counterSetSameCategoryName = "some_counter_set_with_invalid_parent_category";
1198 const CounterSet* counterSetSameCategory = nullptr;
1199 BOOST_CHECK_THROW(counterSetSameCategory = counterDirectory.RegisterCounterSet(counterSetSameCategoryName,
1200 0,
1201 categoryName),
1202 armnn::InvalidArgumentException);
1203 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 3);
1204 BOOST_CHECK(!counterSetSameCategory);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001205}
1206
1207BOOST_AUTO_TEST_CASE(CheckCounterDirectoryRegisterCounter)
1208{
1209 CounterDirectory counterDirectory;
1210 BOOST_CHECK(counterDirectory.GetCategoryCount() == 0);
1211 BOOST_CHECK(counterDirectory.GetDeviceCount() == 0);
1212 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 0);
1213 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1214
1215 // Register a counter with an invalid parent category name
1216 const Counter* noCounter = nullptr;
1217 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("",
1218 0,
1219 1,
1220 123.45f,
1221 "valid name",
1222 "valid description"),
1223 armnn::InvalidArgumentException);
1224 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1225 BOOST_CHECK(!noCounter);
1226
1227 // Register a counter with an invalid parent category name
1228 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("invalid parent category",
1229 0,
1230 1,
1231 123.45f,
1232 "valid name",
1233 "valid description"),
1234 armnn::InvalidArgumentException);
1235 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1236 BOOST_CHECK(!noCounter);
1237
1238 // Register a counter with an invalid class
1239 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
1240 2,
1241 1,
1242 123.45f,
1243 "valid name",
1244 "valid description"),
1245 armnn::InvalidArgumentException);
1246 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1247 BOOST_CHECK(!noCounter);
1248
1249 // Register a counter with an invalid interpolation
1250 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
1251 0,
1252 3,
1253 123.45f,
1254 "valid name",
1255 "valid description"),
1256 armnn::InvalidArgumentException);
1257 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1258 BOOST_CHECK(!noCounter);
1259
1260 // Register a counter with an invalid multiplier
1261 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
1262 0,
1263 1,
1264 .0f,
1265 "valid name",
1266 "valid description"),
1267 armnn::InvalidArgumentException);
1268 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1269 BOOST_CHECK(!noCounter);
1270
1271 // Register a counter with an invalid name
1272 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
1273 0,
1274 1,
1275 123.45f,
1276 "",
1277 "valid description"),
1278 armnn::InvalidArgumentException);
1279 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1280 BOOST_CHECK(!noCounter);
1281
1282 // Register a counter with an invalid name
1283 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
1284 0,
1285 1,
1286 123.45f,
1287 "invalid nam€",
1288 "valid description"),
1289 armnn::InvalidArgumentException);
1290 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1291 BOOST_CHECK(!noCounter);
1292
1293 // Register a counter with an invalid description
1294 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
1295 0,
1296 1,
1297 123.45f,
1298 "valid name",
1299 ""),
1300 armnn::InvalidArgumentException);
1301 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1302 BOOST_CHECK(!noCounter);
1303
1304 // Register a counter with an invalid description
1305 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
1306 0,
1307 1,
1308 123.45f,
1309 "valid name",
1310 "inv@lid description"),
1311 armnn::InvalidArgumentException);
1312 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1313 BOOST_CHECK(!noCounter);
1314
1315 // Register a counter with an invalid unit2
1316 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
1317 0,
1318 1,
1319 123.45f,
1320 "valid name",
1321 "valid description",
1322 std::string("Mb/s2")),
1323 armnn::InvalidArgumentException);
1324 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1325 BOOST_CHECK(!noCounter);
1326
1327 // Register a counter with a non-existing parent category name
1328 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("invalid_parent_category",
1329 0,
1330 1,
1331 123.45f,
1332 "valid name",
1333 "valid description"),
1334 armnn::InvalidArgumentException);
1335 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1336 BOOST_CHECK(!noCounter);
1337
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001338 // Try getting an unregistered counter
1339 const Counter* unregisteredCounter = counterDirectory.GetCounter(9999);
1340 BOOST_CHECK(!unregisteredCounter);
1341
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001342 // Register a category for testing
1343 const std::string categoryName = "some_category";
1344 const Category* category = nullptr;
1345 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName));
1346 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1347 BOOST_CHECK(category);
1348 BOOST_CHECK(category->m_Name == categoryName);
1349 BOOST_CHECK(category->m_Counters.empty());
1350 BOOST_CHECK(category->m_DeviceUid == 0);
1351 BOOST_CHECK(category->m_CounterSetUid == 0);
1352
1353 // Register a counter with a valid parent category name
1354 const Counter* counter = nullptr;
1355 BOOST_CHECK_NO_THROW(counter = counterDirectory.RegisterCounter(categoryName,
1356 0,
1357 1,
1358 123.45f,
1359 "valid name",
1360 "valid description"));
1361 BOOST_CHECK(counterDirectory.GetCounterCount() == 1);
1362 BOOST_CHECK(counter);
1363 BOOST_CHECK(counter->m_Uid >= 0);
1364 BOOST_CHECK(counter->m_MaxCounterUid == counter->m_Uid);
1365 BOOST_CHECK(counter->m_Class == 0);
1366 BOOST_CHECK(counter->m_Interpolation == 1);
1367 BOOST_CHECK(counter->m_Multiplier == 123.45f);
1368 BOOST_CHECK(counter->m_Name == "valid name");
1369 BOOST_CHECK(counter->m_Description == "valid description");
1370 BOOST_CHECK(counter->m_Units == "");
1371 BOOST_CHECK(counter->m_DeviceUid == 0);
1372 BOOST_CHECK(counter->m_CounterSetUid == 0);
1373 BOOST_CHECK(category->m_Counters.size() == 1);
1374 BOOST_CHECK(category->m_Counters.back() == counter->m_Uid);
1375
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001376 // Register a counter with a name of a counter already registered for the given parent category name
1377 const Counter* counterSameName = nullptr;
1378 BOOST_CHECK_THROW(counterSameName = counterDirectory.RegisterCounter(categoryName,
1379 0,
1380 0,
1381 1.0f,
1382 "valid name",
1383 "valid description"),
1384 armnn::InvalidArgumentException);
1385 BOOST_CHECK(counterDirectory.GetCounterCount() == 1);
1386 BOOST_CHECK(!counterSameName);
1387
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001388 // Register a counter with a valid parent category name and units
1389 const Counter* counterWUnits = nullptr;
1390 BOOST_CHECK_NO_THROW(counterWUnits = counterDirectory.RegisterCounter(categoryName,
1391 0,
1392 1,
1393 123.45f,
1394 "valid name 2",
1395 "valid description",
1396 std::string("Mnnsq2"))); // Units
1397 BOOST_CHECK(counterDirectory.GetCounterCount() == 2);
1398 BOOST_CHECK(counterWUnits);
1399 BOOST_CHECK(counterWUnits->m_Uid >= 0);
1400 BOOST_CHECK(counterWUnits->m_Uid > counter->m_Uid);
1401 BOOST_CHECK(counterWUnits->m_MaxCounterUid == counterWUnits->m_Uid);
1402 BOOST_CHECK(counterWUnits->m_Class == 0);
1403 BOOST_CHECK(counterWUnits->m_Interpolation == 1);
1404 BOOST_CHECK(counterWUnits->m_Multiplier == 123.45f);
1405 BOOST_CHECK(counterWUnits->m_Name == "valid name 2");
1406 BOOST_CHECK(counterWUnits->m_Description == "valid description");
1407 BOOST_CHECK(counterWUnits->m_Units == "Mnnsq2");
1408 BOOST_CHECK(counterWUnits->m_DeviceUid == 0);
1409 BOOST_CHECK(counterWUnits->m_CounterSetUid == 0);
1410 BOOST_CHECK(category->m_Counters.size() == 2);
1411 BOOST_CHECK(category->m_Counters.back() == counterWUnits->m_Uid);
1412
1413 // Register a counter with a valid parent category name and not associated with a device
1414 const Counter* counterWoDevice = nullptr;
1415 BOOST_CHECK_NO_THROW(counterWoDevice = counterDirectory.RegisterCounter(categoryName,
1416 0,
1417 1,
1418 123.45f,
1419 "valid name 3",
1420 "valid description",
1421 armnn::EmptyOptional(), // Units
1422 armnn::EmptyOptional(), // Number of cores
1423 0)); // Device UID
1424 BOOST_CHECK(counterDirectory.GetCounterCount() == 3);
1425 BOOST_CHECK(counterWoDevice);
1426 BOOST_CHECK(counterWoDevice->m_Uid >= 0);
1427 BOOST_CHECK(counterWoDevice->m_Uid > counter->m_Uid);
1428 BOOST_CHECK(counterWoDevice->m_MaxCounterUid == counterWoDevice->m_Uid);
1429 BOOST_CHECK(counterWoDevice->m_Class == 0);
1430 BOOST_CHECK(counterWoDevice->m_Interpolation == 1);
1431 BOOST_CHECK(counterWoDevice->m_Multiplier == 123.45f);
1432 BOOST_CHECK(counterWoDevice->m_Name == "valid name 3");
1433 BOOST_CHECK(counterWoDevice->m_Description == "valid description");
1434 BOOST_CHECK(counterWoDevice->m_Units == "");
1435 BOOST_CHECK(counterWoDevice->m_DeviceUid == 0);
1436 BOOST_CHECK(counterWoDevice->m_CounterSetUid == 0);
1437 BOOST_CHECK(category->m_Counters.size() == 3);
1438 BOOST_CHECK(category->m_Counters.back() == counterWoDevice->m_Uid);
1439
1440 // Register a counter with a valid parent category name and associated to an invalid device
1441 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter(categoryName,
1442 0,
1443 1,
1444 123.45f,
1445 "valid name 4",
1446 "valid description",
1447 armnn::EmptyOptional(), // Units
1448 armnn::EmptyOptional(), // Number of cores
1449 100), // Device UID
1450 armnn::InvalidArgumentException);
1451 BOOST_CHECK(counterDirectory.GetCounterCount() == 3);
1452 BOOST_CHECK(!noCounter);
1453
1454 // Register a device for testing
1455 const std::string deviceName = "some_device";
1456 const Device* device = nullptr;
1457 BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName));
1458 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1459 BOOST_CHECK(device);
1460 BOOST_CHECK(device->m_Name == deviceName);
1461 BOOST_CHECK(device->m_Uid >= 1);
1462 BOOST_CHECK(device->m_Cores == 0);
1463
1464 // Register a counter with a valid parent category name and associated to a device
1465 const Counter* counterWDevice = nullptr;
1466 BOOST_CHECK_NO_THROW(counterWDevice = counterDirectory.RegisterCounter(categoryName,
1467 0,
1468 1,
1469 123.45f,
1470 "valid name 5",
1471 "valid description",
1472 armnn::EmptyOptional(), // Units
1473 armnn::EmptyOptional(), // Number of cores
1474 device->m_Uid)); // Device UID
1475 BOOST_CHECK(counterDirectory.GetCounterCount() == 4);
1476 BOOST_CHECK(counterWDevice);
1477 BOOST_CHECK(counterWDevice->m_Uid >= 0);
1478 BOOST_CHECK(counterWDevice->m_Uid > counter->m_Uid);
1479 BOOST_CHECK(counterWDevice->m_MaxCounterUid == counterWDevice->m_Uid);
1480 BOOST_CHECK(counterWDevice->m_Class == 0);
1481 BOOST_CHECK(counterWDevice->m_Interpolation == 1);
1482 BOOST_CHECK(counterWDevice->m_Multiplier == 123.45f);
1483 BOOST_CHECK(counterWDevice->m_Name == "valid name 5");
1484 BOOST_CHECK(counterWDevice->m_Description == "valid description");
1485 BOOST_CHECK(counterWDevice->m_Units == "");
1486 BOOST_CHECK(counterWDevice->m_DeviceUid == device->m_Uid);
1487 BOOST_CHECK(counterWDevice->m_CounterSetUid == 0);
1488 BOOST_CHECK(category->m_Counters.size() == 4);
1489 BOOST_CHECK(category->m_Counters.back() == counterWDevice->m_Uid);
1490
1491 // Register a counter with a valid parent category name and not associated with a counter set
1492 const Counter* counterWoCounterSet = nullptr;
1493 BOOST_CHECK_NO_THROW(counterWoCounterSet
1494 = counterDirectory.RegisterCounter(categoryName,
1495 0,
1496 1,
1497 123.45f,
1498 "valid name 6",
1499 "valid description",
1500 armnn::EmptyOptional(), // Units
1501 armnn::EmptyOptional(), // Number of cores
1502 armnn::EmptyOptional(), // Device UID
1503 0)); // Counter set UID
1504 BOOST_CHECK(counterDirectory.GetCounterCount() == 5);
1505 BOOST_CHECK(counterWoCounterSet);
1506 BOOST_CHECK(counterWoCounterSet->m_Uid >= 0);
1507 BOOST_CHECK(counterWoCounterSet->m_Uid > counter->m_Uid);
1508 BOOST_CHECK(counterWoCounterSet->m_MaxCounterUid == counterWoCounterSet->m_Uid);
1509 BOOST_CHECK(counterWoCounterSet->m_Class == 0);
1510 BOOST_CHECK(counterWoCounterSet->m_Interpolation == 1);
1511 BOOST_CHECK(counterWoCounterSet->m_Multiplier == 123.45f);
1512 BOOST_CHECK(counterWoCounterSet->m_Name == "valid name 6");
1513 BOOST_CHECK(counterWoCounterSet->m_Description == "valid description");
1514 BOOST_CHECK(counterWoCounterSet->m_Units == "");
1515 BOOST_CHECK(counterWoCounterSet->m_DeviceUid == 0);
1516 BOOST_CHECK(counterWoCounterSet->m_CounterSetUid == 0);
1517 BOOST_CHECK(category->m_Counters.size() == 5);
1518 BOOST_CHECK(category->m_Counters.back() == counterWoCounterSet->m_Uid);
1519
1520 // Register a counter with a valid parent category name and associated to an invalid counter set
1521 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter(categoryName,
1522 0,
1523 1,
1524 123.45f,
1525 "valid name 7",
1526 "valid description",
1527 armnn::EmptyOptional(), // Units
1528 armnn::EmptyOptional(), // Number of cores
1529 armnn::EmptyOptional(), // Device UID
1530 100), // Counter set UID
1531 armnn::InvalidArgumentException);
1532 BOOST_CHECK(counterDirectory.GetCounterCount() == 5);
1533 BOOST_CHECK(!noCounter);
1534
1535 // Register a counter with a valid parent category name and with a given number of cores
1536 const Counter* counterWNumberOfCores = nullptr;
1537 uint16_t numberOfCores = 15;
1538 BOOST_CHECK_NO_THROW(counterWNumberOfCores
1539 = counterDirectory.RegisterCounter(categoryName,
1540 0,
1541 1,
1542 123.45f,
1543 "valid name 8",
1544 "valid description",
1545 armnn::EmptyOptional(), // Units
1546 numberOfCores, // Number of cores
1547 armnn::EmptyOptional(), // Device UID
1548 armnn::EmptyOptional())); // Counter set UID
1549 BOOST_CHECK(counterDirectory.GetCounterCount() == 20);
1550 BOOST_CHECK(counterWNumberOfCores);
1551 BOOST_CHECK(counterWNumberOfCores->m_Uid >= 0);
1552 BOOST_CHECK(counterWNumberOfCores->m_Uid > counter->m_Uid);
1553 BOOST_CHECK(counterWNumberOfCores->m_MaxCounterUid == counterWNumberOfCores->m_Uid + numberOfCores - 1);
1554 BOOST_CHECK(counterWNumberOfCores->m_Class == 0);
1555 BOOST_CHECK(counterWNumberOfCores->m_Interpolation == 1);
1556 BOOST_CHECK(counterWNumberOfCores->m_Multiplier == 123.45f);
1557 BOOST_CHECK(counterWNumberOfCores->m_Name == "valid name 8");
1558 BOOST_CHECK(counterWNumberOfCores->m_Description == "valid description");
1559 BOOST_CHECK(counterWNumberOfCores->m_Units == "");
1560 BOOST_CHECK(counterWNumberOfCores->m_DeviceUid == 0);
1561 BOOST_CHECK(counterWNumberOfCores->m_CounterSetUid == 0);
1562 BOOST_CHECK(category->m_Counters.size() == 20);
1563 for (size_t i = 0; i < numberOfCores; i ++)
1564 {
1565 BOOST_CHECK(category->m_Counters[category->m_Counters.size() - numberOfCores + i] ==
1566 counterWNumberOfCores->m_Uid + i);
1567 }
1568
1569 // Register a multi-core device for testing
1570 const std::string multiCoreDeviceName = "some_multi_core_device";
1571 const Device* multiCoreDevice = nullptr;
1572 BOOST_CHECK_NO_THROW(multiCoreDevice = counterDirectory.RegisterDevice(multiCoreDeviceName, 4));
1573 BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
1574 BOOST_CHECK(multiCoreDevice);
1575 BOOST_CHECK(multiCoreDevice->m_Name == multiCoreDeviceName);
1576 BOOST_CHECK(multiCoreDevice->m_Uid >= 1);
1577 BOOST_CHECK(multiCoreDevice->m_Cores == 4);
1578
1579 // Register a counter with a valid parent category name and associated to the multi-core device
1580 const Counter* counterWMultiCoreDevice = nullptr;
1581 BOOST_CHECK_NO_THROW(counterWMultiCoreDevice
1582 = counterDirectory.RegisterCounter(categoryName,
1583 0,
1584 1,
1585 123.45f,
1586 "valid name 9",
1587 "valid description",
1588 armnn::EmptyOptional(), // Units
1589 armnn::EmptyOptional(), // Number of cores
1590 multiCoreDevice->m_Uid, // Device UID
1591 armnn::EmptyOptional())); // Counter set UID
1592 BOOST_CHECK(counterDirectory.GetCounterCount() == 24);
1593 BOOST_CHECK(counterWMultiCoreDevice);
1594 BOOST_CHECK(counterWMultiCoreDevice->m_Uid >= 0);
1595 BOOST_CHECK(counterWMultiCoreDevice->m_Uid > counter->m_Uid);
1596 BOOST_CHECK(counterWMultiCoreDevice->m_MaxCounterUid ==
1597 counterWMultiCoreDevice->m_Uid + multiCoreDevice->m_Cores - 1);
1598 BOOST_CHECK(counterWMultiCoreDevice->m_Class == 0);
1599 BOOST_CHECK(counterWMultiCoreDevice->m_Interpolation == 1);
1600 BOOST_CHECK(counterWMultiCoreDevice->m_Multiplier == 123.45f);
1601 BOOST_CHECK(counterWMultiCoreDevice->m_Name == "valid name 9");
1602 BOOST_CHECK(counterWMultiCoreDevice->m_Description == "valid description");
1603 BOOST_CHECK(counterWMultiCoreDevice->m_Units == "");
1604 BOOST_CHECK(counterWMultiCoreDevice->m_DeviceUid == multiCoreDevice->m_Uid);
1605 BOOST_CHECK(counterWMultiCoreDevice->m_CounterSetUid == 0);
1606 BOOST_CHECK(category->m_Counters.size() == 24);
1607 for (size_t i = 0; i < 4; i ++)
1608 {
1609 BOOST_CHECK(category->m_Counters[category->m_Counters.size() - 4 + i] == counterWMultiCoreDevice->m_Uid + i);
1610 }
1611
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001612 // Register a multi-core device associate to a parent category for testing
1613 const std::string multiCoreDeviceNameWParentCategory = "some_multi_core_device_with_parent_category";
1614 const Device* multiCoreDeviceWParentCategory = nullptr;
1615 BOOST_CHECK_NO_THROW(multiCoreDeviceWParentCategory =
1616 counterDirectory.RegisterDevice(multiCoreDeviceNameWParentCategory, 2, categoryName));
1617 BOOST_CHECK(counterDirectory.GetDeviceCount() == 3);
1618 BOOST_CHECK(multiCoreDeviceWParentCategory);
1619 BOOST_CHECK(multiCoreDeviceWParentCategory->m_Name == multiCoreDeviceNameWParentCategory);
1620 BOOST_CHECK(multiCoreDeviceWParentCategory->m_Uid >= 1);
1621 BOOST_CHECK(multiCoreDeviceWParentCategory->m_Cores == 2);
1622
1623 // Register a counter with a valid parent category name and getting the number of cores of the multi-core device
1624 // associated to that category
1625 const Counter* counterWMultiCoreDeviceWParentCategory = nullptr;
1626 BOOST_CHECK_NO_THROW(counterWMultiCoreDeviceWParentCategory
1627 = counterDirectory.RegisterCounter(categoryName,
1628 0,
1629 1,
1630 123.45f,
1631 "valid name 10",
1632 "valid description",
1633 armnn::EmptyOptional(), // Units
1634 armnn::EmptyOptional(), // Number of cores
1635 armnn::EmptyOptional(), // Device UID
1636 armnn::EmptyOptional())); // Counter set UID
1637 BOOST_CHECK(counterDirectory.GetCounterCount() == 26);
1638 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory);
1639 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_Uid >= 0);
1640 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_Uid > counter->m_Uid);
1641 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_MaxCounterUid ==
1642 counterWMultiCoreDeviceWParentCategory->m_Uid + multiCoreDeviceWParentCategory->m_Cores - 1);
1643 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_Class == 0);
1644 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_Interpolation == 1);
1645 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_Multiplier == 123.45f);
1646 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_Name == "valid name 10");
1647 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_Description == "valid description");
1648 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_Units == "");
1649 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_DeviceUid == 0);
1650 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_CounterSetUid == 0);
1651 BOOST_CHECK(category->m_Counters.size() == 26);
1652 for (size_t i = 0; i < 2; i ++)
1653 {
1654 BOOST_CHECK(category->m_Counters[category->m_Counters.size() - 2 + i] ==
1655 counterWMultiCoreDeviceWParentCategory->m_Uid + i);
1656 }
1657
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001658 // Register a counter set for testing
1659 const std::string counterSetName = "some_counter_set";
1660 const CounterSet* counterSet = nullptr;
1661 BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1662 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1663 BOOST_CHECK(counterSet);
1664 BOOST_CHECK(counterSet->m_Name == counterSetName);
1665 BOOST_CHECK(counterSet->m_Uid >= 1);
1666 BOOST_CHECK(counterSet->m_Count == 0);
1667
1668 // Register a counter with a valid parent category name and associated to a counter set
1669 const Counter* counterWCounterSet = nullptr;
1670 BOOST_CHECK_NO_THROW(counterWCounterSet
1671 = counterDirectory.RegisterCounter(categoryName,
1672 0,
1673 1,
1674 123.45f,
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001675 "valid name 11",
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001676 "valid description",
1677 armnn::EmptyOptional(), // Units
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001678 0, // Number of cores
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001679 armnn::EmptyOptional(), // Device UID
1680 counterSet->m_Uid)); // Counter set UID
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001681 BOOST_CHECK(counterDirectory.GetCounterCount() == 27);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001682 BOOST_CHECK(counterWCounterSet);
1683 BOOST_CHECK(counterWCounterSet->m_Uid >= 0);
1684 BOOST_CHECK(counterWCounterSet->m_Uid > counter->m_Uid);
1685 BOOST_CHECK(counterWCounterSet->m_MaxCounterUid == counterWCounterSet->m_Uid);
1686 BOOST_CHECK(counterWCounterSet->m_Class == 0);
1687 BOOST_CHECK(counterWCounterSet->m_Interpolation == 1);
1688 BOOST_CHECK(counterWCounterSet->m_Multiplier == 123.45f);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001689 BOOST_CHECK(counterWCounterSet->m_Name == "valid name 11");
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001690 BOOST_CHECK(counterWCounterSet->m_Description == "valid description");
1691 BOOST_CHECK(counterWCounterSet->m_Units == "");
1692 BOOST_CHECK(counterWCounterSet->m_DeviceUid == 0);
1693 BOOST_CHECK(counterWCounterSet->m_CounterSetUid == counterSet->m_Uid);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001694 BOOST_CHECK(category->m_Counters.size() == 27);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001695 BOOST_CHECK(category->m_Counters.back() == counterWCounterSet->m_Uid);
1696
1697 // Register a counter with a valid parent category name and associated to a device and a counter set
1698 const Counter* counterWDeviceWCounterSet = nullptr;
1699 BOOST_CHECK_NO_THROW(counterWDeviceWCounterSet
1700 = counterDirectory.RegisterCounter(categoryName,
1701 0,
1702 1,
1703 123.45f,
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001704 "valid name 12",
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001705 "valid description",
1706 armnn::EmptyOptional(), // Units
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001707 1, // Number of cores
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001708 device->m_Uid, // Device UID
1709 counterSet->m_Uid)); // Counter set UID
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001710 BOOST_CHECK(counterDirectory.GetCounterCount() == 28);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001711 BOOST_CHECK(counterWDeviceWCounterSet);
1712 BOOST_CHECK(counterWDeviceWCounterSet->m_Uid >= 0);
1713 BOOST_CHECK(counterWDeviceWCounterSet->m_Uid > counter->m_Uid);
1714 BOOST_CHECK(counterWDeviceWCounterSet->m_MaxCounterUid == counterWDeviceWCounterSet->m_Uid);
1715 BOOST_CHECK(counterWDeviceWCounterSet->m_Class == 0);
1716 BOOST_CHECK(counterWDeviceWCounterSet->m_Interpolation == 1);
1717 BOOST_CHECK(counterWDeviceWCounterSet->m_Multiplier == 123.45f);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001718 BOOST_CHECK(counterWDeviceWCounterSet->m_Name == "valid name 12");
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001719 BOOST_CHECK(counterWDeviceWCounterSet->m_Description == "valid description");
1720 BOOST_CHECK(counterWDeviceWCounterSet->m_Units == "");
1721 BOOST_CHECK(counterWDeviceWCounterSet->m_DeviceUid == device->m_Uid);
1722 BOOST_CHECK(counterWDeviceWCounterSet->m_CounterSetUid == counterSet->m_Uid);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001723 BOOST_CHECK(category->m_Counters.size() == 28);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001724 BOOST_CHECK(category->m_Counters.back() == counterWDeviceWCounterSet->m_Uid);
1725
1726 // Register another category for testing
1727 const std::string anotherCategoryName = "some_other_category";
1728 const Category* anotherCategory = nullptr;
1729 BOOST_CHECK_NO_THROW(anotherCategory = counterDirectory.RegisterCategory(anotherCategoryName));
1730 BOOST_CHECK(counterDirectory.GetCategoryCount() == 2);
1731 BOOST_CHECK(anotherCategory);
1732 BOOST_CHECK(anotherCategory != category);
1733 BOOST_CHECK(anotherCategory->m_Name == anotherCategoryName);
1734 BOOST_CHECK(anotherCategory->m_Counters.empty());
1735 BOOST_CHECK(anotherCategory->m_DeviceUid == 0);
1736 BOOST_CHECK(anotherCategory->m_CounterSetUid == 0);
1737
1738 // Register a counter to the other category
1739 const Counter* anotherCounter = nullptr;
1740 BOOST_CHECK_NO_THROW(anotherCounter = counterDirectory.RegisterCounter(anotherCategoryName,
1741 1,
1742 0,
1743 .00043f,
1744 "valid name",
1745 "valid description",
1746 armnn::EmptyOptional(), // Units
1747 armnn::EmptyOptional(), // Number of cores
1748 device->m_Uid, // Device UID
1749 counterSet->m_Uid)); // Counter set UID
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001750 BOOST_CHECK(counterDirectory.GetCounterCount() == 29);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001751 BOOST_CHECK(anotherCounter);
1752 BOOST_CHECK(anotherCounter->m_Uid >= 0);
1753 BOOST_CHECK(anotherCounter->m_MaxCounterUid == anotherCounter->m_Uid);
1754 BOOST_CHECK(anotherCounter->m_Class == 1);
1755 BOOST_CHECK(anotherCounter->m_Interpolation == 0);
1756 BOOST_CHECK(anotherCounter->m_Multiplier == .00043f);
1757 BOOST_CHECK(anotherCounter->m_Name == "valid name");
1758 BOOST_CHECK(anotherCounter->m_Description == "valid description");
1759 BOOST_CHECK(anotherCounter->m_Units == "");
1760 BOOST_CHECK(anotherCounter->m_DeviceUid == device->m_Uid);
1761 BOOST_CHECK(anotherCounter->m_CounterSetUid == counterSet->m_Uid);
1762 BOOST_CHECK(anotherCategory->m_Counters.size() == 1);
1763 BOOST_CHECK(anotherCategory->m_Counters.back() == anotherCounter->m_Uid);
Matteo Martincighab173e92019-09-05 12:02:04 +01001764}
1765
Ferran Balaguer1b941722019-08-28 16:57:18 +01001766BOOST_AUTO_TEST_CASE(CounterSelectionCommandHandlerParseData)
1767{
1768 using boost::numeric_cast;
1769
1770 class TestCaptureThread : public IPeriodicCounterCapture
1771 {
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01001772 void Start() override {}
1773 void Stop() override {}
Ferran Balaguer1b941722019-08-28 16:57:18 +01001774 };
1775
1776 const uint32_t packetId = 0x40000;
1777
1778 uint32_t version = 1;
1779 Holder holder;
1780 TestCaptureThread captureThread;
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001781 MockBufferManager mockBuffer(512);
Matteo Martincighe61ffd02019-10-07 10:19:35 +01001782 SendCounterPacket sendCounterPacket(mockBuffer);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001783
1784 uint32_t sizeOfUint32 = numeric_cast<uint32_t>(sizeof(uint32_t));
1785 uint32_t sizeOfUint16 = numeric_cast<uint32_t>(sizeof(uint16_t));
1786
1787 // Data with period and counters
1788 uint32_t period1 = 10;
1789 uint32_t dataLength1 = 8;
Ferran Balaguer1b941722019-08-28 16:57:18 +01001790 uint32_t offset = 0;
1791
FinnWilliamsArma0c78712019-09-16 12:06:47 +01001792 std::unique_ptr<char[]> uniqueData1 = std::make_unique<char[]>(dataLength1);
1793 unsigned char* data1 = reinterpret_cast<unsigned char*>(uniqueData1.get());
1794
Ferran Balaguer1b941722019-08-28 16:57:18 +01001795 WriteUint32(data1, offset, period1);
1796 offset += sizeOfUint32;
1797 WriteUint16(data1, offset, 4000);
1798 offset += sizeOfUint16;
1799 WriteUint16(data1, offset, 5000);
1800
FinnWilliamsArma0c78712019-09-16 12:06:47 +01001801 Packet packetA(packetId, dataLength1, uniqueData1);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001802
1803 PeriodicCounterSelectionCommandHandler commandHandler(packetId, version, holder, captureThread,
1804 sendCounterPacket);
1805 commandHandler(packetA);
1806
1807 std::vector<uint16_t> counterIds = holder.GetCaptureData().GetCounterIds();
1808
1809 BOOST_TEST(holder.GetCaptureData().GetCapturePeriod() == period1);
1810 BOOST_TEST(counterIds.size() == 2);
1811 BOOST_TEST(counterIds[0] == 4000);
1812 BOOST_TEST(counterIds[1] == 5000);
1813
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001814 auto readBuffer = mockBuffer.GetReadableBuffer();
Ferran Balaguer1b941722019-08-28 16:57:18 +01001815
1816 offset = 0;
1817
1818 uint32_t headerWord0 = ReadUint32(readBuffer, offset);
1819 offset += sizeOfUint32;
1820 uint32_t headerWord1 = ReadUint32(readBuffer, offset);
1821 offset += sizeOfUint32;
1822 uint32_t period = ReadUint32(readBuffer, offset);
1823
1824 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
1825 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
1826 BOOST_TEST(headerWord1 == 8); // data lenght
1827 BOOST_TEST(period == 10); // capture period
1828
1829 uint16_t counterId = 0;
1830 offset += sizeOfUint32;
1831 counterId = ReadUint16(readBuffer, offset);
1832 BOOST_TEST(counterId == 4000);
1833 offset += sizeOfUint16;
1834 counterId = ReadUint16(readBuffer, offset);
1835 BOOST_TEST(counterId == 5000);
1836
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001837 mockBuffer.MarkRead(readBuffer);
1838
Ferran Balaguer1b941722019-08-28 16:57:18 +01001839 // Data with period only
1840 uint32_t period2 = 11;
1841 uint32_t dataLength2 = 4;
Ferran Balaguer1b941722019-08-28 16:57:18 +01001842
FinnWilliamsArma0c78712019-09-16 12:06:47 +01001843 std::unique_ptr<char[]> uniqueData2 = std::make_unique<char[]>(dataLength2);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001844
FinnWilliamsArma0c78712019-09-16 12:06:47 +01001845 WriteUint32(reinterpret_cast<unsigned char*>(uniqueData2.get()), 0, period2);
1846
1847 Packet packetB(packetId, dataLength2, uniqueData2);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001848
1849 commandHandler(packetB);
1850
1851 counterIds = holder.GetCaptureData().GetCounterIds();
1852
1853 BOOST_TEST(holder.GetCaptureData().GetCapturePeriod() == period2);
1854 BOOST_TEST(counterIds.size() == 0);
1855
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001856 readBuffer = mockBuffer.GetReadableBuffer();
Ferran Balaguer1b941722019-08-28 16:57:18 +01001857
1858 offset = 0;
1859
1860 headerWord0 = ReadUint32(readBuffer, offset);
1861 offset += sizeOfUint32;
1862 headerWord1 = ReadUint32(readBuffer, offset);
1863 offset += sizeOfUint32;
1864 period = ReadUint32(readBuffer, offset);
1865
1866 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
1867 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
1868 BOOST_TEST(headerWord1 == 4); // data lenght
1869 BOOST_TEST(period == 11); // capture period
Ferran Balaguer1b941722019-08-28 16:57:18 +01001870}
1871
Sadik Armaganb5f01b22019-09-18 17:29:00 +01001872BOOST_AUTO_TEST_CASE(CheckConnectionAcknowledged)
1873{
1874 using boost::numeric_cast;
1875
1876 const uint32_t connectionPacketId = 0x10000;
1877 const uint32_t version = 1;
1878
1879 uint32_t sizeOfUint32 = numeric_cast<uint32_t>(sizeof(uint32_t));
1880 uint32_t sizeOfUint16 = numeric_cast<uint32_t>(sizeof(uint16_t));
1881
1882 // Data with period and counters
1883 uint32_t period1 = 10;
1884 uint32_t dataLength1 = 8;
1885 uint32_t offset = 0;
1886
1887 std::unique_ptr<char[]> uniqueData1 = std::make_unique<char[]>(dataLength1);
1888 unsigned char* data1 = reinterpret_cast<unsigned char*>(uniqueData1.get());
1889
1890 WriteUint32(data1, offset, period1);
1891 offset += sizeOfUint32;
1892 WriteUint16(data1, offset, 4000);
1893 offset += sizeOfUint16;
1894 WriteUint16(data1, offset, 5000);
1895
1896 Packet packetA(connectionPacketId, dataLength1, uniqueData1);
1897
1898 ProfilingStateMachine profilingState(ProfilingState::Uninitialised);
1899 BOOST_CHECK(profilingState.GetCurrentState() == ProfilingState::Uninitialised);
1900
1901 ConnectionAcknowledgedCommandHandler commandHandler(connectionPacketId, version, profilingState);
1902
1903 // command handler received packet on ProfilingState::Uninitialised
1904 BOOST_CHECK_THROW(commandHandler(packetA), armnn::Exception);
1905
1906 profilingState.TransitionToState(ProfilingState::NotConnected);
1907 BOOST_CHECK(profilingState.GetCurrentState() == ProfilingState::NotConnected);
1908 // command handler received packet on ProfilingState::NotConnected
1909 BOOST_CHECK_THROW(commandHandler(packetA), armnn::Exception);
1910
1911 profilingState.TransitionToState(ProfilingState::WaitingForAck);
1912 BOOST_CHECK(profilingState.GetCurrentState() == ProfilingState::WaitingForAck);
1913 // command handler received packet on ProfilingState::WaitingForAck
1914 commandHandler(packetA);
1915 BOOST_CHECK(profilingState.GetCurrentState() == ProfilingState::Active);
1916
1917 // command handler received packet on ProfilingState::Active
1918 commandHandler(packetA);
1919 BOOST_CHECK(profilingState.GetCurrentState() == ProfilingState::Active);
1920
1921 // command handler received different packet
1922 const uint32_t differentPacketId = 0x40000;
1923 Packet packetB(differentPacketId, dataLength1, uniqueData1);
1924 ConnectionAcknowledgedCommandHandler differentCommandHandler(differentPacketId, version, profilingState);
1925 BOOST_CHECK_THROW(differentCommandHandler(packetB), armnn::Exception);
1926}
1927
Teresa Charlin9bab4962019-09-06 12:28:35 +01001928BOOST_AUTO_TEST_CASE(CheckSocketProfilingConnection)
1929{
1930 // Check that creating a SocketProfilingConnection results in an exception as the Gator UDS doesn't exist.
1931 BOOST_CHECK_THROW(new SocketProfilingConnection(), armnn::Exception);
1932}
1933
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001934BOOST_AUTO_TEST_CASE(SwTraceIsValidCharTest)
1935{
1936 // Only ASCII 7-bit encoding supported
1937 for (unsigned char c = 0; c < 128; c++)
1938 {
1939 BOOST_CHECK(SwTraceCharPolicy::IsValidChar(c));
1940 }
1941
1942 // Not ASCII
1943 for (unsigned char c = 255; c >= 128; c++)
1944 {
1945 BOOST_CHECK(!SwTraceCharPolicy::IsValidChar(c));
1946 }
1947}
1948
1949BOOST_AUTO_TEST_CASE(SwTraceIsValidNameCharTest)
1950{
1951 // Only alpha-numeric and underscore ASCII 7-bit encoding supported
1952 const unsigned char validChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
1953 for (unsigned char i = 0; i < sizeof(validChars) / sizeof(validChars[0]) - 1; i++)
1954 {
1955 BOOST_CHECK(SwTraceNameCharPolicy::IsValidChar(validChars[i]));
1956 }
1957
1958 // Non alpha-numeric chars
1959 for (unsigned char c = 0; c < 48; c++)
1960 {
1961 BOOST_CHECK(!SwTraceNameCharPolicy::IsValidChar(c));
1962 }
1963 for (unsigned char c = 58; c < 65; c++)
1964 {
1965 BOOST_CHECK(!SwTraceNameCharPolicy::IsValidChar(c));
1966 }
1967 for (unsigned char c = 91; c < 95; c++)
1968 {
1969 BOOST_CHECK(!SwTraceNameCharPolicy::IsValidChar(c));
1970 }
1971 for (unsigned char c = 96; c < 97; c++)
1972 {
1973 BOOST_CHECK(!SwTraceNameCharPolicy::IsValidChar(c));
1974 }
1975 for (unsigned char c = 123; c < 128; c++)
1976 {
1977 BOOST_CHECK(!SwTraceNameCharPolicy::IsValidChar(c));
1978 }
1979
1980 // Not ASCII
1981 for (unsigned char c = 255; c >= 128; c++)
1982 {
1983 BOOST_CHECK(!SwTraceNameCharPolicy::IsValidChar(c));
1984 }
1985}
1986
1987BOOST_AUTO_TEST_CASE(IsValidSwTraceStringTest)
1988{
1989 // Valid SWTrace strings
1990 BOOST_CHECK(IsValidSwTraceString<SwTraceCharPolicy>(""));
1991 BOOST_CHECK(IsValidSwTraceString<SwTraceCharPolicy>("_"));
1992 BOOST_CHECK(IsValidSwTraceString<SwTraceCharPolicy>("0123"));
1993 BOOST_CHECK(IsValidSwTraceString<SwTraceCharPolicy>("valid_string"));
1994 BOOST_CHECK(IsValidSwTraceString<SwTraceCharPolicy>("VALID_string_456"));
1995 BOOST_CHECK(IsValidSwTraceString<SwTraceCharPolicy>(" "));
1996 BOOST_CHECK(IsValidSwTraceString<SwTraceCharPolicy>("valid string"));
1997 BOOST_CHECK(IsValidSwTraceString<SwTraceCharPolicy>("!$%"));
1998 BOOST_CHECK(IsValidSwTraceString<SwTraceCharPolicy>("valid|\\~string#123"));
1999
2000 // Invalid SWTrace strings
2001 BOOST_CHECK(!IsValidSwTraceString<SwTraceCharPolicy>("€£"));
2002 BOOST_CHECK(!IsValidSwTraceString<SwTraceCharPolicy>("invalid‡string"));
2003 BOOST_CHECK(!IsValidSwTraceString<SwTraceCharPolicy>("12Ž34"));
2004}
2005
2006BOOST_AUTO_TEST_CASE(IsValidSwTraceNameStringTest)
2007{
2008 // Valid SWTrace name strings
2009 BOOST_CHECK(IsValidSwTraceString<SwTraceNameCharPolicy>(""));
2010 BOOST_CHECK(IsValidSwTraceString<SwTraceNameCharPolicy>("_"));
2011 BOOST_CHECK(IsValidSwTraceString<SwTraceNameCharPolicy>("0123"));
2012 BOOST_CHECK(IsValidSwTraceString<SwTraceNameCharPolicy>("valid_string"));
2013 BOOST_CHECK(IsValidSwTraceString<SwTraceNameCharPolicy>("VALID_string_456"));
2014
2015 // Invalid SWTrace name strings
2016 BOOST_CHECK(!IsValidSwTraceString<SwTraceNameCharPolicy>(" "));
2017 BOOST_CHECK(!IsValidSwTraceString<SwTraceNameCharPolicy>("invalid string"));
2018 BOOST_CHECK(!IsValidSwTraceString<SwTraceNameCharPolicy>("!$%"));
2019 BOOST_CHECK(!IsValidSwTraceString<SwTraceNameCharPolicy>("invalid|\\~string#123"));
2020 BOOST_CHECK(!IsValidSwTraceString<SwTraceNameCharPolicy>("€£"));
2021 BOOST_CHECK(!IsValidSwTraceString<SwTraceNameCharPolicy>("invalid‡string"));
2022 BOOST_CHECK(!IsValidSwTraceString<SwTraceNameCharPolicy>("12Ž34"));
2023}
2024
2025template <typename SwTracePolicy>
2026void StringToSwTraceStringTestHelper(const std::string& testString, std::vector<uint32_t> buffer, size_t expectedSize)
2027{
2028 // Convert the test string to a SWTrace string
2029 BOOST_CHECK(StringToSwTraceString<SwTracePolicy>(testString, buffer));
2030
2031 // The buffer must contain at least the length of the string
2032 BOOST_CHECK(!buffer.empty());
2033
2034 // The buffer must be of the expected size (in words)
2035 BOOST_CHECK(buffer.size() == expectedSize);
2036
2037 // The first word of the byte must be the length of the string including the null-terminator
2038 BOOST_CHECK(buffer[0] == testString.size() + 1);
2039
2040 // The contents of the buffer must match the test string
2041 BOOST_CHECK(std::memcmp(testString.data(), buffer.data() + 1, testString.size()) == 0);
2042
2043 // The buffer must include the null-terminator at the end of the string
2044 size_t nullTerminatorIndex = sizeof(uint32_t) + testString.size();
2045 BOOST_CHECK(reinterpret_cast<unsigned char*>(buffer.data())[nullTerminatorIndex] == '\0');
2046}
2047
2048BOOST_AUTO_TEST_CASE(StringToSwTraceStringTest)
2049{
2050 std::vector<uint32_t> buffer;
2051
2052 // Valid SWTrace strings (expected size in words)
2053 StringToSwTraceStringTestHelper<SwTraceCharPolicy>("", buffer, 2);
2054 StringToSwTraceStringTestHelper<SwTraceCharPolicy>("_", buffer, 2);
2055 StringToSwTraceStringTestHelper<SwTraceCharPolicy>("0123", buffer, 3);
2056 StringToSwTraceStringTestHelper<SwTraceCharPolicy>("valid_string", buffer, 5);
2057 StringToSwTraceStringTestHelper<SwTraceCharPolicy>("VALID_string_456", buffer, 6);
2058 StringToSwTraceStringTestHelper<SwTraceCharPolicy>(" ", buffer, 2);
2059 StringToSwTraceStringTestHelper<SwTraceCharPolicy>("valid string", buffer, 5);
2060 StringToSwTraceStringTestHelper<SwTraceCharPolicy>("!$%", buffer, 2);
2061 StringToSwTraceStringTestHelper<SwTraceCharPolicy>("valid|\\~string#123", buffer, 6);
2062
2063 // Invalid SWTrace strings
2064 BOOST_CHECK(!StringToSwTraceString<SwTraceCharPolicy>("€£", buffer));
2065 BOOST_CHECK(buffer.empty());
2066 BOOST_CHECK(!StringToSwTraceString<SwTraceCharPolicy>("invalid‡string", buffer));
2067 BOOST_CHECK(buffer.empty());
2068 BOOST_CHECK(!StringToSwTraceString<SwTraceCharPolicy>("12Ž34", buffer));
2069 BOOST_CHECK(buffer.empty());
2070}
2071
2072BOOST_AUTO_TEST_CASE(StringToSwTraceNameStringTest)
2073{
2074 std::vector<uint32_t> buffer;
2075
2076 // Valid SWTrace namestrings (expected size in words)
2077 StringToSwTraceStringTestHelper<SwTraceNameCharPolicy>("", buffer, 2);
2078 StringToSwTraceStringTestHelper<SwTraceNameCharPolicy>("_", buffer, 2);
2079 StringToSwTraceStringTestHelper<SwTraceNameCharPolicy>("0123", buffer, 3);
2080 StringToSwTraceStringTestHelper<SwTraceNameCharPolicy>("valid_string", buffer, 5);
2081 StringToSwTraceStringTestHelper<SwTraceNameCharPolicy>("VALID_string_456", buffer, 6);
2082
2083 // Invalid SWTrace namestrings
2084 BOOST_CHECK(!StringToSwTraceString<SwTraceNameCharPolicy>(" ", buffer));
2085 BOOST_CHECK(buffer.empty());
2086 BOOST_CHECK(!StringToSwTraceString<SwTraceNameCharPolicy>("invalid string", buffer));
2087 BOOST_CHECK(buffer.empty());
2088 BOOST_CHECK(!StringToSwTraceString<SwTraceNameCharPolicy>("!$%", buffer));
2089 BOOST_CHECK(buffer.empty());
2090 BOOST_CHECK(!StringToSwTraceString<SwTraceNameCharPolicy>("invalid|\\~string#123", buffer));
2091 BOOST_CHECK(buffer.empty());
2092 BOOST_CHECK(!StringToSwTraceString<SwTraceNameCharPolicy>("€£", buffer));
2093 BOOST_CHECK(buffer.empty());
2094 BOOST_CHECK(!StringToSwTraceString<SwTraceNameCharPolicy>("invalid‡string", buffer));
2095 BOOST_CHECK(buffer.empty());
2096 BOOST_CHECK(!StringToSwTraceString<SwTraceNameCharPolicy>("12Ž34", buffer));
2097 BOOST_CHECK(buffer.empty());
2098}
2099
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002100BOOST_AUTO_TEST_CASE(CheckPeriodicCounterCaptureThread)
2101{
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002102 class CaptureReader : public IReadCounterValues
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002103 {
2104 public:
2105 CaptureReader() {}
2106
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002107 uint16_t GetCounterCount() const override
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002108 {
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002109 return boost::numeric_cast<uint16_t>(m_Data.size());
2110 }
2111
2112 uint32_t GetCounterValue(uint16_t index) const override
2113 {
2114 if (m_Data.find(index) == m_Data.end())
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002115 {
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002116 return 0;
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002117 }
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002118
2119 return m_Data.at(index);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002120 }
2121
2122 void SetCounterValue(uint16_t index, uint32_t value)
2123 {
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002124 if (m_Data.find(index) == m_Data.end())
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002125 {
2126 m_Data.insert(std::pair<uint16_t, uint32_t>(index, value));
2127 }
2128 else
2129 {
2130 m_Data.at(index) = value;
2131 }
2132 }
2133
2134 private:
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002135 std::unordered_map<uint16_t, uint32_t> m_Data;
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002136 };
2137
2138 Holder data;
2139 std::vector<uint16_t> captureIds1 = { 0, 1 };
2140 std::vector<uint16_t> captureIds2;
2141
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002142 MockBufferManager mockBuffer(512);
Matteo Martincighe61ffd02019-10-07 10:19:35 +01002143 SendCounterPacket sendCounterPacket(mockBuffer);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002144
2145 std::vector<uint16_t> counterIds;
2146 CaptureReader captureReader;
2147
2148 unsigned int valueA = 10;
2149 unsigned int valueB = 15;
2150 unsigned int numSteps = 5;
2151
2152 PeriodicCounterCapture periodicCounterCapture(std::ref(data), std::ref(sendCounterPacket), captureReader);
2153
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002154 for (unsigned int i = 0; i < numSteps; ++i)
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002155 {
2156 data.SetCaptureData(1, captureIds1);
2157 captureReader.SetCounterValue(0, valueA * (i + 1));
2158 captureReader.SetCounterValue(1, valueB * (i + 1));
2159
2160 periodicCounterCapture.Start();
2161
2162 std::this_thread::sleep_for(std::chrono::milliseconds(200));
2163
2164 periodicCounterCapture.Start();
2165
2166 data.SetCaptureData(0, captureIds2);
2167
2168 periodicCounterCapture.Start();
2169 }
2170
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002171 periodicCounterCapture.Stop();
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002172
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002173 auto buffer = mockBuffer.GetReadableBuffer();
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002174
2175 uint32_t headerWord0 = ReadUint32(buffer, 0);
2176 uint32_t headerWord1 = ReadUint32(buffer, 4);
2177
2178 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 1); // packet family
2179 BOOST_TEST(((headerWord0 >> 19) & 0x3F) == 0); // packet class
2180 BOOST_TEST(((headerWord0 >> 16) & 0x3) == 0); // packet type
2181 BOOST_TEST(headerWord1 == 20); // data length
2182
2183 uint32_t offset = 16;
2184 uint16_t readIndex = ReadUint16(buffer, offset);
2185 BOOST_TEST(0 == readIndex);
2186
2187 offset += 2;
2188 uint32_t readValue = ReadUint32(buffer, offset);
2189 BOOST_TEST((valueA * numSteps) == readValue);
2190
2191 offset += 4;
2192 readIndex = ReadUint16(buffer, offset);
2193 BOOST_TEST(1 == readIndex);
2194
2195 offset += 2;
2196 readValue = ReadUint32(buffer, offset);
2197 BOOST_TEST((valueB * numSteps) == readValue);
2198}
2199
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002200BOOST_AUTO_TEST_CASE(RequestCounterDirectoryCommandHandlerTest0)
2201{
2202 using boost::numeric_cast;
2203
2204 const uint32_t packetId = 0x30000;
2205 const uint32_t version = 1;
2206
2207 std::unique_ptr<char[]> packetData;
2208
2209 Packet packetA(packetId, 0, packetData);
2210
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002211 MockBufferManager mockBuffer(1024);
Matteo Martincighe61ffd02019-10-07 10:19:35 +01002212 SendCounterPacket sendCounterPacket(mockBuffer);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002213
2214 CounterDirectory counterDirectory;
2215
2216 RequestCounterDirectoryCommandHandler commandHandler(packetId, version, counterDirectory, sendCounterPacket);
2217 commandHandler(packetA);
2218
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002219 auto readBuffer = mockBuffer.GetReadableBuffer();
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002220
2221 uint32_t headerWord0 = ReadUint32(readBuffer, 0);
2222 uint32_t headerWord1 = ReadUint32(readBuffer, 4);
2223
2224 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
2225 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 2); // packet id
Matteo Martincighf74ff2f2019-09-24 11:38:32 +01002226 BOOST_TEST(headerWord1 == 24); // data length
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002227
2228 uint32_t bodyHeaderWord0 = ReadUint32(readBuffer, 8);
2229 uint16_t deviceRecordCount = numeric_cast<uint16_t>(bodyHeaderWord0 >> 16);
2230 BOOST_TEST(deviceRecordCount == 0); // device_records_count
2231}
2232
2233BOOST_AUTO_TEST_CASE(RequestCounterDirectoryCommandHandlerTest1)
2234{
2235 using boost::numeric_cast;
2236
2237 const uint32_t packetId = 0x30000;
2238 const uint32_t version = 1;
2239
2240 std::unique_ptr<char[]> packetData;
2241
2242 Packet packetA(packetId, 0, packetData);
2243
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002244 MockBufferManager mockBuffer(1024);
Matteo Martincighe61ffd02019-10-07 10:19:35 +01002245 SendCounterPacket sendCounterPacket(mockBuffer);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002246
2247 CounterDirectory counterDirectory;
2248 const Device* device = counterDirectory.RegisterDevice("deviceA", 1);
2249 const CounterSet* counterSet = counterDirectory.RegisterCounterSet("countersetA");
2250 counterDirectory.RegisterCategory("categoryA", device->m_Uid, counterSet->m_Uid);
2251 counterDirectory.RegisterCounter("categoryA", 0, 1, 2.0f, "counterA", "descA");
2252 counterDirectory.RegisterCounter("categoryA", 1, 1, 3.0f, "counterB", "descB");
2253
2254 RequestCounterDirectoryCommandHandler commandHandler(packetId, version, counterDirectory, sendCounterPacket);
2255 commandHandler(packetA);
2256
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002257 auto readBuffer = mockBuffer.GetReadableBuffer();
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002258
2259 uint32_t headerWord0 = ReadUint32(readBuffer, 0);
2260 uint32_t headerWord1 = ReadUint32(readBuffer, 4);
2261
2262 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
2263 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 2); // packet id
Matteo Martincighf74ff2f2019-09-24 11:38:32 +01002264 BOOST_TEST(headerWord1 == 240); // data length
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002265
2266 uint32_t bodyHeaderWord0 = ReadUint32(readBuffer, 8);
2267 uint32_t bodyHeaderWord1 = ReadUint32(readBuffer, 12);
2268 uint32_t bodyHeaderWord2 = ReadUint32(readBuffer, 16);
2269 uint32_t bodyHeaderWord3 = ReadUint32(readBuffer, 20);
2270 uint32_t bodyHeaderWord4 = ReadUint32(readBuffer, 24);
2271 uint32_t bodyHeaderWord5 = ReadUint32(readBuffer, 28);
2272 uint16_t deviceRecordCount = numeric_cast<uint16_t>(bodyHeaderWord0 >> 16);
2273 uint16_t counterSetRecordCount = numeric_cast<uint16_t>(bodyHeaderWord2 >> 16);
2274 uint16_t categoryRecordCount = numeric_cast<uint16_t>(bodyHeaderWord4 >> 16);
2275 BOOST_TEST(deviceRecordCount == 1); // device_records_count
2276 BOOST_TEST(bodyHeaderWord1 == 0); // device_records_pointer_table_offset
2277 BOOST_TEST(counterSetRecordCount == 1); // counter_set_count
2278 BOOST_TEST(bodyHeaderWord3 == 4); // counter_set_pointer_table_offset
2279 BOOST_TEST(categoryRecordCount == 1); // categories_count
2280 BOOST_TEST(bodyHeaderWord5 == 8); // categories_pointer_table_offset
2281
2282 uint32_t deviceRecordOffset = ReadUint32(readBuffer, 32);
2283 BOOST_TEST(deviceRecordOffset == 0);
2284
2285 uint32_t counterSetRecordOffset = ReadUint32(readBuffer, 36);
2286 BOOST_TEST(counterSetRecordOffset == 20);
2287
2288 uint32_t categoryRecordOffset = ReadUint32(readBuffer, 40);
2289 BOOST_TEST(categoryRecordOffset == 44);
2290}
2291
Francis Murtagh1f7db452019-08-14 09:49:34 +01002292BOOST_AUTO_TEST_SUITE_END()