blob: ec4e591836d3199d09ea466fd5df0e11f0f4c459 [file] [log] [blame]
Aron Virginas-Tardfa14772019-09-24 18:24:47 +01001//
2// Copyright © 2019 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#include "../ProfilingConnectionDumpToFileDecorator.hpp"
Keith Davisb10e0812019-10-17 09:52:50 +01007#include <Runtime.hpp>
Aron Virginas-Tardfa14772019-09-24 18:24:47 +01008
9#include <fstream>
10#include <sstream>
11
12#include <boost/core/ignore_unused.hpp>
13#include <boost/numeric/conversion/cast.hpp>
14#include <boost/test/unit_test.hpp>
15
16#if defined(__ANDROID__)
17#define ARMNN_PROFILING_CONNECTION_TEST_DUMP_DIR "/data/local/tmp"
18#else
19#define ARMNN_PROFILING_CONNECTION_TEST_DUMP_DIR "/tmp"
20#endif
21
22using namespace armnn::profiling;
23
24namespace
25{
26
27const std::vector<char> g_Data = { 'd', 'u', 'm', 'm', 'y' };
28const uint32_t g_DataLength = boost::numeric_cast<uint32_t>(g_Data.size());
29const unsigned char* g_DataPtr = reinterpret_cast<const unsigned char*>(g_Data.data());
30
31class DummyProfilingConnection : public IProfilingConnection
32{
33public:
34 DummyProfilingConnection()
35 : m_Open(true)
Matteo Martincigh67ef2a52019-10-10 13:29:02 +010036 , m_PacketData(std::make_unique<unsigned char[]>(g_DataLength))
Aron Virginas-Tardfa14772019-09-24 18:24:47 +010037 {
38 // populate packet data and construct packet
39 std::memcpy(m_PacketData.get(), g_DataPtr, g_DataLength);
40 m_Packet = std::make_unique<Packet>(0u, g_DataLength, m_PacketData);
41 }
42
43 ~DummyProfilingConnection() = default;
44
Matteo Martincigh54fb9572019-10-02 12:50:57 +010045 bool IsOpen() const override
Aron Virginas-Tardfa14772019-09-24 18:24:47 +010046 {
47 return m_Open;
48 }
49
50 void Close() override
51 {
52 m_Open = false;
53 }
54
55 bool WritePacket(const unsigned char* buffer, uint32_t length) override
56 {
57 boost::ignore_unused(buffer);
58 boost::ignore_unused(length);
59 return true;
60 }
61
62 Packet ReadPacket(uint32_t timeout) override
63 {
64 boost::ignore_unused(timeout);
65 return std::move(*m_Packet);
66 }
67
68private:
Matteo Martincigh67ef2a52019-10-10 13:29:02 +010069 bool m_Open;
70 std::unique_ptr<unsigned char[]> m_PacketData;
Aron Virginas-Tardfa14772019-09-24 18:24:47 +010071 std::unique_ptr<Packet> m_Packet;
72};
73
74std::vector<char> ReadDumpFile(const std::string& dumpFileName)
75{
76 std::ifstream input(dumpFileName, std::ios::binary);
77 return std::vector<char>(std::istreambuf_iterator<char>(input), {});
78}
79
80} // anonymous namespace
81
82BOOST_AUTO_TEST_SUITE(ProfilingConnectionDumpToFileDecoratorTests)
83
Aron Virginas-Tardfa14772019-09-24 18:24:47 +010084BOOST_AUTO_TEST_CASE(DumpIncomingInvalidFile)
85{
Keith Davisb10e0812019-10-17 09:52:50 +010086 armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
87 options.m_IncomingCaptureFile = "/";
88 options.m_OutgoingCaptureFile = "";
89 ProfilingConnectionDumpToFileDecorator decorator(std::make_unique<DummyProfilingConnection>(), options, false);
Aron Virginas-Tardfa14772019-09-24 18:24:47 +010090 BOOST_CHECK_THROW(decorator.ReadPacket(0), armnn::RuntimeException);
91}
92
93BOOST_AUTO_TEST_CASE(DumpIncomingInvalidFileIgnoreErrors)
94{
Keith Davisb10e0812019-10-17 09:52:50 +010095 armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
96 options.m_IncomingCaptureFile = "/";
97 options.m_OutgoingCaptureFile = "";
98 ProfilingConnectionDumpToFileDecorator decorator(std::make_unique<DummyProfilingConnection>(), options, true);
Aron Virginas-Tardfa14772019-09-24 18:24:47 +010099 BOOST_CHECK_NO_THROW(decorator.ReadPacket(0));
100}
101
102BOOST_AUTO_TEST_CASE(DumpIncomingValidFile)
103{
104 std::stringstream fileName;
105 fileName << ARMNN_PROFILING_CONNECTION_TEST_DUMP_DIR << "/test_dump_file_incoming.dat";
Keith Davisb10e0812019-10-17 09:52:50 +0100106 armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
107 options.m_IncomingCaptureFile = fileName.str();
108 options.m_OutgoingCaptureFile = "";
Aron Virginas-Tardfa14772019-09-24 18:24:47 +0100109
Keith Davisb10e0812019-10-17 09:52:50 +0100110 ProfilingConnectionDumpToFileDecorator decorator(std::make_unique<DummyProfilingConnection>(), options, false);
Aron Virginas-Tardfa14772019-09-24 18:24:47 +0100111
112 // NOTE: unique_ptr is needed here because operator=() is deleted for Packet
113 std::unique_ptr<Packet> packet;
114 BOOST_CHECK_NO_THROW(packet = std::make_unique<Packet>(decorator.ReadPacket(0)));
115
116 decorator.Close();
117
Keith Davisb10e0812019-10-17 09:52:50 +0100118 std::vector<char> data = ReadDumpFile(options.m_IncomingCaptureFile);
Matteo Martincigh67ef2a52019-10-10 13:29:02 +0100119 const char* packetData = reinterpret_cast<const char*>(packet->GetData());
Aron Virginas-Tardfa14772019-09-24 18:24:47 +0100120
121 // check if the data read back from the dump file matches the original
122 constexpr unsigned int bytesToSkip = 2u * sizeof(uint32_t); // skip header and packet length
123 int diff = std::strncmp(data.data() + bytesToSkip, packetData, g_DataLength);
124 BOOST_CHECK(diff == 0);
125}
126
127BOOST_AUTO_TEST_CASE(DumpOutgoingInvalidFile)
128{
Keith Davisb10e0812019-10-17 09:52:50 +0100129 armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
130 options.m_IncomingCaptureFile = "";
131 options.m_OutgoingCaptureFile = "/";
132 ProfilingConnectionDumpToFileDecorator decorator(std::make_unique<DummyProfilingConnection>(), options, false);
Aron Virginas-Tardfa14772019-09-24 18:24:47 +0100133 BOOST_CHECK_THROW(decorator.WritePacket(g_DataPtr, g_DataLength), armnn::RuntimeException);
134}
135
136BOOST_AUTO_TEST_CASE(DumpOutgoingInvalidFileIgnoreErrors)
137{
Keith Davisb10e0812019-10-17 09:52:50 +0100138 armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
139 options.m_IncomingCaptureFile = "";
140 options.m_OutgoingCaptureFile = "/";
141
142 ProfilingConnectionDumpToFileDecorator decorator(std::make_unique<DummyProfilingConnection>(), options, true);
Aron Virginas-Tardfa14772019-09-24 18:24:47 +0100143 BOOST_CHECK_NO_THROW(decorator.WritePacket(g_DataPtr, g_DataLength));
144
145 bool success = decorator.WritePacket(g_DataPtr, g_DataLength);
146 BOOST_CHECK(!success);
147}
148
149BOOST_AUTO_TEST_CASE(DumpOutgoingValidFile)
150{
151 std::stringstream fileName;
152 fileName << ARMNN_PROFILING_CONNECTION_TEST_DUMP_DIR << "/test_dump_file.dat";
153
Keith Davisb10e0812019-10-17 09:52:50 +0100154 armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
155 options.m_IncomingCaptureFile = "";
156 options.m_OutgoingCaptureFile = fileName.str();
157
158 ProfilingConnectionDumpToFileDecorator decorator(std::make_unique<DummyProfilingConnection>(), options, false);
Aron Virginas-Tardfa14772019-09-24 18:24:47 +0100159
160 bool success = false;
161 BOOST_CHECK_NO_THROW(success = decorator.WritePacket(g_DataPtr, g_DataLength));
162 BOOST_CHECK(success);
163
164 decorator.Close();
165
Keith Davisb10e0812019-10-17 09:52:50 +0100166 std::vector<char> data = ReadDumpFile(options.m_OutgoingCaptureFile);
Aron Virginas-Tardfa14772019-09-24 18:24:47 +0100167
168 // check if the data read back from the dump file matches the original
169 int diff = std::strncmp(data.data(), g_Data.data(), g_DataLength);
170 BOOST_CHECK(diff == 0);
171}
172
173BOOST_AUTO_TEST_SUITE_END()