blob: b4af705fcd86330dfb8d305c06acc7beac16b3ca [file] [log] [blame]
Matteo Martincighac60d282019-07-25 15:25:44 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#pragma once
7
Matteo Martincighbc2e2102019-07-24 14:56:13 +01008#include <backendsCommon/DynamicBackend.hpp>
Matteo Martincighac60d282019-07-25 15:25:44 +01009#include <backendsCommon/DynamicBackendUtils.hpp>
10
Matteo Martincighbc2e2102019-07-24 14:56:13 +010011#include <string>
12#include <memory>
Matteo Martincigh986c1862019-07-26 15:12:47 +010013#include <string>
14
Matteo Martincighac60d282019-07-25 15:25:44 +010015#include <boost/test/unit_test.hpp>
Matteo Martincigh986c1862019-07-26 15:12:47 +010016#include <boost/filesystem.hpp>
Matteo Martincigha77d80e2019-07-31 11:05:16 +010017#include <boost/dll.hpp>
Matteo Martincigh986c1862019-07-26 15:12:47 +010018
Matteo Martincighd0dc7702019-08-01 17:09:03 +010019static std::string g_TestBaseDir = "src/backends/backendsCommon/test/";
Matteo Martincigh986c1862019-07-26 15:12:47 +010020
Matteo Martincighd0dc7702019-08-01 17:09:03 +010021static std::string g_TestSharedObjectSubDir = "testSharedObject/";
22static std::string g_TestDynamicBackendSubDir = "testDynamicBackend/";
23
24static std::string g_TestSharedObjectFileName = "libTestSharedObject.so";
25static std::string g_TestNoSharedObjectFileName = "libNoSharedObject.txt";
26
27static std::string g_TestValidTestDynamicBackendFileName = "libValidTestDynamicBackend.so";
28static std::string g_TestInvalidTestDynamicBackend1FileName = "libInvalidTestDynamicBackend1.so";
29static std::string g_TestInvalidTestDynamicBackend2FileName = "libInvalidTestDynamicBackend2.so";
30static std::string g_TestInvalidTestDynamicBackend3FileName = "libInvalidTestDynamicBackend3.so";
31static std::string g_TestInvalidTestDynamicBackend4FileName = "libInvalidTestDynamicBackend4.so";
32static std::string g_TestInvalidTestDynamicBackend5FileName = "libInvalidTestDynamicBackend5.so";
33static std::string g_TestInvalidTestDynamicBackend6FileName = "libInvalidTestDynamicBackend6.so";
34static std::string g_TestInvalidTestDynamicBackend7FileName = "libInvalidTestDynamicBackend7.so";
35
Matteo Martincighe7d44982019-08-05 12:16:47 +010036static std::string g_TestDynamicBackendsFileParsingSubDir1 = "backendsTestPath1/";
37static std::string g_TestDynamicBackendsFileParsingSubDir2 = "backendsTestPath2/";
38static std::string g_TestDynamicBackendsFileParsingSubDir3 = "backendsTestPath3/";
39static std::string g_TestDynamicBackendsFileParsingSubDir4 = "backendsTestPath4/";
40
Matteo Martincighd0dc7702019-08-01 17:09:03 +010041std::string GetTestDirectoryBasePath()
Matteo Martincigh986c1862019-07-26 15:12:47 +010042{
43 using namespace boost::filesystem;
44
Matteo Martincigha77d80e2019-07-31 11:05:16 +010045 path programLocation = boost::dll::program_location().parent_path();
Matteo Martincighd0dc7702019-08-01 17:09:03 +010046 path sharedObjectPath = programLocation.append(g_TestBaseDir);
47 BOOST_CHECK(exists(sharedObjectPath));
Matteo Martincigh986c1862019-07-26 15:12:47 +010048
Matteo Martincighd0dc7702019-08-01 17:09:03 +010049 return sharedObjectPath.string();
50}
51
52std::string GetTestSubDirectory(const std::string& subdir)
53{
54 using namespace boost::filesystem;
55
56 std::string testDynamicBackendsBaseDir = GetTestDirectoryBasePath();
57 path testDynamicBackendsBasePath(testDynamicBackendsBaseDir);
58 path testDynamicBackendsSubDir = testDynamicBackendsBasePath.append(subdir);
59 // Do not check that the sub-directory exists because for testing reasons we may use non-existing paths
60
61 return testDynamicBackendsSubDir.string();
62}
63
64std::string GetTestFilePath(const std::string& directory, const std::string& fileName)
65{
66 using namespace boost::filesystem;
67
68 path directoryPath(directory);
69 path fileNamePath = directoryPath.append(fileName);
70 BOOST_CHECK(exists(fileNamePath));
71
72 return fileNamePath.string();
Matteo Martincigh986c1862019-07-26 15:12:47 +010073}
74
75void OpenCloseHandleTestImpl()
76{
77 using namespace armnn;
78
Matteo Martincighd0dc7702019-08-01 17:09:03 +010079 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
80 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +010081
82 void* sharedObjectHandle = nullptr;
83 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
84 BOOST_TEST((sharedObjectHandle != nullptr));
85
86 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
87}
88
89void CloseInvalidHandleTestImpl()
90{
91 using namespace armnn;
92
93 // This calls must silently handle invalid handles and complete successfully (no segfaults, etc.)
94 DynamicBackendUtils::CloseHandle(nullptr);
95}
96
97void OpenEmptyFileNameTestImpl()
98{
99 using namespace armnn;
100
101 void* sharedObjectHandle = nullptr;
102 BOOST_CHECK_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(""), RuntimeException);
103 BOOST_TEST((sharedObjectHandle == nullptr));
104}
105
106void OpenNotExistingFileTestImpl()
107{
108 using namespace armnn;
109
110 void* sharedObjectHandle = nullptr;
111 BOOST_CHECK_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle("NotExistingFileName"), RuntimeException);
112 BOOST_TEST((sharedObjectHandle == nullptr));
113}
114
115void OpenNotSharedObjectTestImpl()
116{
117 using namespace armnn;
118
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100119 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
120 std::string notSharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestNoSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100121
122 void* sharedObjectHandle = nullptr;
123 BOOST_CHECK_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(notSharedObjectFilePath), RuntimeException);
124 BOOST_TEST((sharedObjectHandle == nullptr));
125}
126
127void GetValidEntryPointTestImpl()
128{
129 using namespace armnn;
130
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100131 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
132 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100133
134 void* sharedObjectHandle = nullptr;
135 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
136 BOOST_TEST((sharedObjectHandle != nullptr));
137
138 using TestFunctionType = int(*)(int);
139 TestFunctionType testFunctionPointer = nullptr;
140 BOOST_CHECK_NO_THROW(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
141 "TestFunction1"));
142 BOOST_TEST((testFunctionPointer != nullptr));
143 BOOST_TEST(testFunctionPointer(7) == 7);
144
145 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
146}
147
148void GetNameMangledEntryPointTestImpl()
149{
150 using namespace armnn;
151
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100152 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
153 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100154
155 void* sharedObjectHandle = nullptr;
156 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
157 BOOST_TEST((sharedObjectHandle != nullptr));
158
159 using TestFunctionType = int(*)(int);
160 TestFunctionType testFunctionPointer = nullptr;
161 BOOST_CHECK_THROW(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
162 "TestFunction2"),
163 RuntimeException);
164 BOOST_TEST((testFunctionPointer == nullptr));
165
166 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
167}
168
169void GetNoExternEntryPointTestImpl()
170{
171 using namespace armnn;
172
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100173 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
174 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100175
176 void* sharedObjectHandle = nullptr;
177 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
178 BOOST_TEST((sharedObjectHandle != nullptr));
179
180 using TestFunctionType = int(*)(int);
181 TestFunctionType testFunctionPointer = nullptr;
182 BOOST_CHECK_THROW(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
183 "TestFunction3"),
184 RuntimeException);
185 BOOST_TEST((testFunctionPointer == nullptr));
186
187 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
188}
189
190void GetNotExistingEntryPointTestImpl()
191{
192 using namespace armnn;
193
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100194 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
195 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100196
197 void* sharedObjectHandle = nullptr;
198 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
199 BOOST_TEST((sharedObjectHandle != nullptr));
200
201 using TestFunctionType = int(*)(int);
202 TestFunctionType testFunctionPointer = nullptr;
203 BOOST_CHECK_THROW(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
204 "TestFunction4"),
205 RuntimeException);
206 BOOST_TEST((testFunctionPointer == nullptr));
207
208 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
209}
Matteo Martincighac60d282019-07-25 15:25:44 +0100210
211void BackendVersioningTestImpl()
212{
Matteo Martincigh986c1862019-07-26 15:12:47 +0100213 using namespace armnn;
214
215 class TestDynamicBackendUtils : public DynamicBackendUtils
Matteo Martincighac60d282019-07-25 15:25:44 +0100216 {
217 public:
Matteo Martincigh986c1862019-07-26 15:12:47 +0100218 static bool IsBackendCompatibleTest(const BackendVersion& backendApiVersion,
219 const BackendVersion& backendVersion)
Matteo Martincighac60d282019-07-25 15:25:44 +0100220 {
221 return IsBackendCompatibleImpl(backendApiVersion, backendVersion);
222 }
223 };
224
225 // The backend API version used for the tests
Matteo Martincigh986c1862019-07-26 15:12:47 +0100226 BackendVersion backendApiVersion{ 2, 4 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100227
228 // Same backend and backend API versions are compatible with the backend API
Matteo Martincigh986c1862019-07-26 15:12:47 +0100229 BackendVersion sameBackendVersion{ 2, 4 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100230 BOOST_TEST(sameBackendVersion == backendApiVersion);
231 BOOST_TEST(sameBackendVersion <= backendApiVersion);
232 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, sameBackendVersion) == true);
233
234 // Backend versions that differ from the backend API version by major revision are not compatible
235 // with the backend API
Matteo Martincigh986c1862019-07-26 15:12:47 +0100236 BackendVersion laterMajorBackendVersion{ 3, 4 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100237 BOOST_TEST(!(laterMajorBackendVersion == backendApiVersion));
238 BOOST_TEST(!(laterMajorBackendVersion <= backendApiVersion));
239 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, laterMajorBackendVersion) == false);
240
Matteo Martincigh986c1862019-07-26 15:12:47 +0100241 BackendVersion earlierMajorBackendVersion{ 1, 4 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100242 BOOST_TEST(!(earlierMajorBackendVersion == backendApiVersion));
243 BOOST_TEST(earlierMajorBackendVersion <= backendApiVersion);
244 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion,
245 earlierMajorBackendVersion) == false);
246
247 // Backend versions with the same major revision but later minor revision than
248 // the backend API version are not compatible with the backend API
Matteo Martincigh986c1862019-07-26 15:12:47 +0100249 BackendVersion laterMinorBackendVersion{ 2, 5 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100250 BOOST_TEST(!(laterMinorBackendVersion == backendApiVersion));
251 BOOST_TEST(!(laterMinorBackendVersion <= backendApiVersion));
252 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, laterMinorBackendVersion) == false);
253
254 // Backend versions with the same major revision but earlier minor revision than
255 // the backend API version are compatible with the backend API
Matteo Martincigh986c1862019-07-26 15:12:47 +0100256 BackendVersion earlierMinorBackendVersion{ 2, 3 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100257 BOOST_TEST(!(earlierMinorBackendVersion == backendApiVersion));
258 BOOST_TEST(earlierMinorBackendVersion <= backendApiVersion);
259 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, earlierMinorBackendVersion) == true);
260}
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100261
262void CreateValidDynamicBackendObjectTestImpl()
263{
264 // Valid shared object handle
265 // Correct name mangling
266 // Correct interface
267 // Correct backend implementation
268
269 using namespace armnn;
270
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100271 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
272 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestValidTestDynamicBackendFileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100273
274 void* sharedObjectHandle = nullptr;
275 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
276 BOOST_TEST((sharedObjectHandle != nullptr));
277
278 std::unique_ptr<DynamicBackend> dynamicBackend;
279 BOOST_CHECK_NO_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)));
280 BOOST_TEST((dynamicBackend != nullptr));
281
282 BackendId dynamicBackendId;
283 BOOST_CHECK_NO_THROW(dynamicBackendId = dynamicBackend->GetBackendId());
284 BOOST_TEST((dynamicBackendId == "ValidTestDynamicBackend"));
285
286 BackendVersion dynamicBackendVersion;
287 BOOST_CHECK_NO_THROW(dynamicBackendVersion = dynamicBackend->GetBackendVersion());
288 BOOST_TEST((dynamicBackendVersion == BackendVersion({ 1, 0 })));
289
290 IBackendInternalUniquePtr dynamicBackendInstance;
291 BOOST_CHECK_NO_THROW(dynamicBackendInstance = dynamicBackend->GetBackend());
292 BOOST_TEST((dynamicBackendInstance != nullptr));
293
294 BOOST_TEST((dynamicBackendInstance->GetId() == "ValidTestDynamicBackend"));
295}
296
297void CreateDynamicBackendObjectInvalidHandleTestImpl()
298{
299 // Invalid (null) shared object handle
300
301 using namespace armnn;
302
303 void* sharedObjectHandle = nullptr;
304 std::unique_ptr<DynamicBackend> dynamicBackend;
305 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), InvalidArgumentException);
306 BOOST_TEST((dynamicBackend == nullptr));
307}
308
309void CreateDynamicBackendObjectInvalidInterface1TestImpl()
310{
311 // Valid shared object handle
312 // Wrong (not C-style) name mangling
313
314 using namespace armnn;
315
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100316 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
317 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend1FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100318
319 void* sharedObjectHandle = nullptr;
320 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
321 BOOST_TEST((sharedObjectHandle != nullptr));
322
323 std::unique_ptr<DynamicBackend> dynamicBackend;
324 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
325 BOOST_TEST((dynamicBackend == nullptr));
326}
327
328void CreateDynamicBackendObjectInvalidInterface2TestImpl()
329{
330 // Valid shared object handle
331 // Correct name mangling
332 // Wrong interface (missing GetBackendId())
333
334 using namespace armnn;
335
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100336 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
337 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend2FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100338
339 void* sharedObjectHandle = nullptr;
340 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
341 BOOST_TEST((sharedObjectHandle != nullptr));
342
343 std::unique_ptr<DynamicBackend> dynamicBackend;
344 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
345 BOOST_TEST((dynamicBackend == nullptr));
346}
347
348void CreateDynamicBackendObjectInvalidInterface3TestImpl()
349{
350 // Valid shared object handle
351 // Correct name mangling
352 // Wrong interface (missing GetVersion())
353
354 using namespace armnn;
355
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100356 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
357 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend3FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100358
359 void* sharedObjectHandle = nullptr;
360 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
361 BOOST_TEST((sharedObjectHandle != nullptr));
362
363 std::unique_ptr<DynamicBackend> dynamicBackend;
364 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
365 BOOST_TEST((dynamicBackend == nullptr));
366}
367
368void CreateDynamicBackendObjectInvalidInterface4TestImpl()
369{
370 // Valid shared object handle
371 // Correct name mangling
372 // Wrong interface (missing BackendFactory())
373
374 using namespace armnn;
375
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100376 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
377 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend4FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100378
379 void* sharedObjectHandle = nullptr;
380 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
381 BOOST_TEST((sharedObjectHandle != nullptr));
382
383 std::unique_ptr<DynamicBackend> dynamicBackend;
384 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
385 BOOST_TEST((dynamicBackend == nullptr));
386}
387
388void CreateDynamicBackendObjectInvalidInterface5TestImpl()
389{
390 // Valid shared object handle
391 // Correct name mangling
392 // Correct interface
393 // Invalid (null) backend id returned by GetBackendId()
394
395 using namespace armnn;
396
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100397 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
398 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend5FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100399
400 void* sharedObjectHandle = nullptr;
401 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
402 BOOST_TEST((sharedObjectHandle != nullptr));
403
404 std::unique_ptr<DynamicBackend> dynamicBackend;
405 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
406 BOOST_TEST((dynamicBackend == nullptr));
407}
408
409void CreateDynamicBackendObjectInvalidInterface6TestImpl()
410{
411 // Valid shared object handle
412 // Correct name mangling
413 // Correct interface
414 // Invalid (null) backend instance returned by BackendFactory()
415
416 using namespace armnn;
417
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100418 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
419 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend6FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100420
421 void* sharedObjectHandle = nullptr;
422 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
423 BOOST_TEST((sharedObjectHandle != nullptr));
424
425 std::unique_ptr<DynamicBackend> dynamicBackend;
426 BOOST_CHECK_NO_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)));
427 BOOST_TEST((dynamicBackend != nullptr));
428
429 BackendId dynamicBackendId;
430 BOOST_CHECK_NO_THROW(dynamicBackendId = dynamicBackend->GetBackendId());
431 BOOST_TEST((dynamicBackendId == "InvalidTestDynamicBackend"));
432
433 BackendVersion dynamicBackendVersion;
434 BOOST_CHECK_NO_THROW(dynamicBackendVersion = dynamicBackend->GetBackendVersion());
435 BOOST_TEST((dynamicBackendVersion == BackendVersion({ 1, 0 })));
436
437 IBackendInternalUniquePtr dynamicBackendInstance;
438 BOOST_CHECK_THROW(dynamicBackendInstance = dynamicBackend->GetBackend(), RuntimeException);
439 BOOST_TEST((dynamicBackendInstance == nullptr));
440}
441
442void CreateDynamicBackendObjectInvalidInterface7TestImpl()
443{
444 // Valid shared object handle
445 // Correct name mangling
446 // Correct interface
447 // Invalid (incompatible backend API version) backend instance returned by BackendFactory()
448
449 using namespace armnn;
450
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100451 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
452 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend7FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100453
454 void* sharedObjectHandle = nullptr;
455 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
456 BOOST_TEST((sharedObjectHandle != nullptr));
457
458 std::unique_ptr<DynamicBackend> dynamicBackend;
459 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
460 BOOST_TEST((dynamicBackend == nullptr));
461}
Matteo Martincighe7d44982019-08-05 12:16:47 +0100462
463void GetBackendPathsTestImpl()
464{
465 using namespace armnn;
466 using namespace boost::filesystem;
467
468 // The test covers four directories:
469 // <unit test path>/src/backends/backendsCommon/test/
470 // ├─ backendsTestPath1/ -> existing, contains files
471 // ├─ backendsTestPath2/ -> existing, contains files
472 // ├─ backendsTestPath3/ -> existing, but empty
473 // └─ backendsTestPath4/ -> not existing
474
475 std::string subDir1 = GetTestSubDirectory(g_TestDynamicBackendsFileParsingSubDir1);
476 std::string subDir2 = GetTestSubDirectory(g_TestDynamicBackendsFileParsingSubDir2);
477 std::string subDir3 = GetTestSubDirectory(g_TestDynamicBackendsFileParsingSubDir3);
478 std::string subDir4 = GetTestSubDirectory(g_TestDynamicBackendsFileParsingSubDir4);
479
480 BOOST_CHECK(exists(subDir1));
481 BOOST_CHECK(exists(subDir2));
482 BOOST_CHECK(exists(subDir3));
483 BOOST_CHECK(!exists(subDir4));
484
485 class TestDynamicBackendUtils : public DynamicBackendUtils
486 {
487 public:
488 static std::vector<std::string> GetBackendPathsImplTest(const std::string& path)
489 {
490 return GetBackendPathsImpl(path);
491 }
492 };
493
494 // No path
495 BOOST_TEST(TestDynamicBackendUtils::GetBackendPathsImplTest("").empty());
496
497 // Malformed path
498 std::string malformedDir(subDir1 + "/" + subDir1);
499 BOOST_TEST(TestDynamicBackendUtils::GetBackendPathsImplTest(malformedDir).size()==0);
500
501 // Single valid path
502 std::vector<std::string> DynamicBackendPaths2 = TestDynamicBackendUtils::GetBackendPathsImplTest(subDir1);
503 BOOST_TEST(DynamicBackendPaths2.size() == 1);
504 BOOST_TEST(DynamicBackendPaths2[0] == subDir1);
505
506 // Multiple equal and valid paths
507 std::string multipleEqualDirs(subDir1 + ":" + subDir1);
508 std::vector<std::string> DynamicBackendPaths3 = TestDynamicBackendUtils::GetBackendPathsImplTest(multipleEqualDirs);
509 BOOST_TEST(DynamicBackendPaths3.size() == 1);
510 BOOST_TEST(DynamicBackendPaths3[0] == subDir1);
511
512 // Multiple empty paths
513 BOOST_TEST(TestDynamicBackendUtils::GetBackendPathsImplTest(":::").empty());
514
515 // Multiple valid paths
516 std::string multipleValidPaths(subDir1 + ":" + subDir2 + ":" + subDir3);
517 std::vector<std::string> DynamicBackendPaths5 =
518 TestDynamicBackendUtils::GetBackendPathsImplTest(multipleValidPaths);
519 BOOST_TEST(DynamicBackendPaths5.size() == 3);
520 BOOST_TEST(DynamicBackendPaths5[0] == subDir1);
521 BOOST_TEST(DynamicBackendPaths5[1] == subDir2);
522 BOOST_TEST(DynamicBackendPaths5[2] == subDir3);
523
524 // Valid among empty paths
525 std::string validAmongEmptyDirs("::" + subDir1 + ":");
526 std::vector<std::string> DynamicBackendPaths6 =
527 TestDynamicBackendUtils::GetBackendPathsImplTest(validAmongEmptyDirs);
528 BOOST_TEST(DynamicBackendPaths6.size() == 1);
529 BOOST_TEST(DynamicBackendPaths6[0] == subDir1);
530
531 // Invalid among empty paths
532 std::string invalidAmongEmptyDirs(":" + subDir4 + "::");
533 BOOST_TEST(TestDynamicBackendUtils::GetBackendPathsImplTest(invalidAmongEmptyDirs).empty());
534
535 // Valid, invalid and empty paths
536 std::string validInvalidEmptyDirs(subDir1 + ":" + subDir4 + ":");
537 std::vector<std::string> DynamicBackendPaths8 =
538 TestDynamicBackendUtils::GetBackendPathsImplTest(validInvalidEmptyDirs);
539 BOOST_TEST(DynamicBackendPaths8.size() == 1);
540 BOOST_TEST(DynamicBackendPaths8[0] == subDir1);
541
542 // Mix of duplicates of valid, invalid and empty paths
543 std::string duplicateValidInvalidEmptyDirs(validInvalidEmptyDirs + ":" + validInvalidEmptyDirs + ":" +
544 subDir2 + ":" + subDir2);
545 std::vector<std::string> DynamicBackendPaths9 =
546 TestDynamicBackendUtils::GetBackendPathsImplTest(duplicateValidInvalidEmptyDirs);
547 BOOST_TEST(DynamicBackendPaths9.size() == 2);
548 BOOST_TEST(DynamicBackendPaths9[0] == subDir1);
549 BOOST_TEST(DynamicBackendPaths9[1] == subDir2);
550}
551
552void GetBackendPathsOverrideTestImpl()
553{
554 using namespace armnn;
555 using namespace boost::filesystem;
556
557 std::string subDir1 = GetTestSubDirectory(g_TestDynamicBackendsFileParsingSubDir1);
558 std::string subDir4 = GetTestSubDirectory(g_TestDynamicBackendsFileParsingSubDir4);
559
560 BOOST_CHECK(exists(subDir1));
561 BOOST_CHECK(!exists(subDir4));
562
563 // Override with valid path
564 std::vector<std::string> validResult = DynamicBackendUtils::GetBackendPaths(subDir1);
565 BOOST_TEST(validResult.size() == 1);
566 BOOST_TEST(validResult[0] == subDir1);
567
568 // Override with invalid path
569 std::vector<std::string> invalidResult = DynamicBackendUtils::GetBackendPaths(subDir4);
570 BOOST_TEST(invalidResult.empty());
571}
Jan Eilers4a539fc2019-07-25 17:08:37 +0100572
573void GetSharedObjectsTestImpl()
574{
575 using namespace armnn;
576 using namespace boost::filesystem;
577
578 //
579 // The test sub-directory backendsTestPath1/ contains the following test files:
580 //
581 // Arm_GpuAcc_backend.so -> valid (basic backend name)
582 // Arm_GpuAcc_backend.so.1 -> valid (single field version number)
583 // Arm_GpuAcc_backend.so.1.2 -> valid (multiple field version number)
584 // Arm_GpuAcc_backend.so.1.2.3 -> valid (multiple field version number)
585 // Arm_GpuAcc_backend.so.10.1.27 -> valid (Multiple digit version)
586 // Arm_GpuAcc_backend.so.10.1.33. -> not valid (dot not followed by version number)
587 // Arm_GpuAcc_backend.so.3.4..5 -> not valid (dot not followed by version number)
588 // Arm_GpuAcc_backend.so.1,1.1 -> not valid (comma instead of dot in the version)
589 //
590 // Arm123_GpuAcc_backend.so -> valid (digits in vendor name are allowed)
591 // Arm_GpuAcc456_backend.so -> valid (digits in backend id are allowed)
592 // Arm%Co_GpuAcc_backend.so -> not valid (invalid character in vendor name)
593 // Arm_Gpu.Acc_backend.so -> not valid (invalid character in backend id)
594 //
595 // GpuAcc_backend.so -> not valid (missing vendor name)
596 // _GpuAcc_backend.so -> not valid (missing vendor name)
597 // Arm__backend.so -> not valid (missing backend id)
598 // Arm_GpuAcc.so -> not valid (missing "backend" at the end)
599 // __backend.so -> not valid (missing vendor name and backend id)
600 // __.so -> not valid (missing all fields)
601 //
602 // Arm_GpuAcc_backend -> not valid (missing at least ".so" at the end)
603 // Arm_GpuAcc_backend_v1.2.so -> not valid (extra version info at the end)
604 //
605 // The test sub-directory backendsTestPath1/ contains the following test files:
606 //
607 // Arm_CpuAcc_backend.so -> valid (basic backend name)
608 // Arm_CpuAcc_backend.so.1 -> Arm_CpuAcc_backend.so -> valid (symlink to valid backend file)
609 // Arm_CpuAcc_backend.so.1.2 -> Arm_CpuAcc_backend.so.1 -> valid (symlink to valid symlink)
610 // Arm_CpuAcc_backend.so.1.2.3 -> Arm_CpuAcc_backend.so.1.2 -> valid (symlink to valid symlink)
611 //
612 // Arm_no_backend.so -> nothing -> not valid (symlink resolves to non-existent file)
613 //
614 // Arm_GpuAcc_backend.so -> valid (but duplicated from backendsTestPath1/)
615
616 std::string testDynamicBackendsSubDir1 = GetTestSubDirectory(g_TestDynamicBackendsFileParsingSubDir1);
617 std::string testDynamicBackendsSubDir2 = GetTestSubDirectory(g_TestDynamicBackendsFileParsingSubDir2);
618 std::string testDynamicBackendsSubDir3 = GetTestSubDirectory(g_TestDynamicBackendsFileParsingSubDir3);
619 std::string testDynamicBackendsSubDir4 = GetTestSubDirectory(g_TestDynamicBackendsFileParsingSubDir4);
620 BOOST_CHECK(exists(testDynamicBackendsSubDir1));
621 BOOST_CHECK(exists(testDynamicBackendsSubDir2));
622 BOOST_CHECK(exists(testDynamicBackendsSubDir3));
623 BOOST_CHECK(!exists(testDynamicBackendsSubDir4));
624
625 std::vector<std::string> backendPaths
626 {
627 testDynamicBackendsSubDir1,
628 testDynamicBackendsSubDir2,
629 testDynamicBackendsSubDir3,
630 testDynamicBackendsSubDir4
631 };
632 std::vector<std::string> sharedObjects = DynamicBackendUtils::GetSharedObjects(backendPaths);
633 std::unordered_set<std::string> expectedSharedObjects
634 {
635 testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so", // Basic backend name
636 testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.1", // Single field version number
637 testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.1.2", // Multiple field version number
638 testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.1.2.3", // Multiple field version number
639 testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.10.1.27", // Multiple digit version
640 testDynamicBackendsSubDir1 + "Arm123_GpuAcc_backend.so", // Digits in vendor name are allowed
641 testDynamicBackendsSubDir1 + "Arm_GpuAcc456_backend.so", // Digits in backend id are allowed
642 testDynamicBackendsSubDir2 + "Arm_CpuAcc_backend.so", // Duplicate symlinks removed
643 testDynamicBackendsSubDir2 + "Arm_GpuAcc_backend.so" // Duplicates on different paths are allowed
644 };
645
646 BOOST_TEST(sharedObjects.size() == expectedSharedObjects.size());
647 for (const std::string& sharedObject : sharedObjects)
648 {
649 auto it = expectedSharedObjects.find(sharedObject);
650 BOOST_TEST((it != expectedSharedObjects.end()));
651 }
652}