aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatteo Martincigh <matteo.martincigh@arm.com>2019-07-24 14:56:13 +0100
committerMatteo Martincigh <matteo.martincigh@arm.com>2019-07-30 13:17:35 +0100
commitbc2e210785a63e8360839e4ded5d2c15c2dffaf5 (patch)
treee9e4e75bab72ce7c7e599cfb86a6508a001d86bc
parent986c186468e6023b234c24bd10ed9687f9eea0da (diff)
downloadarmnn-bc2e210785a63e8360839e4ded5d2c15c2dffaf5.tar.gz
IVGCVSW-3561 Test the DynamicBackend class
* Added unit test for valid dynamic backends * Added unit tests for various cases of invalid dynamic backends (invalid handle, malformed backends, incompatible version, etc.) Signed-off-by: Matteo Martincigh <matteo.martincigh@arm.com> Change-Id: I4c3b33702bb0faac2bbebe224f69908639b4fc54
-rw-r--r--src/backends/backendsCommon/DynamicBackend.cpp8
-rw-r--r--src/backends/backendsCommon/test/CMakeLists.txt49
-rw-r--r--src/backends/backendsCommon/test/DynamicBackendTests.cpp21
-rw-r--r--src/backends/backendsCommon/test/DynamicBackendTests.hpp209
-rw-r--r--src/backends/backendsCommon/test/TestDynamicBackend.cpp95
-rw-r--r--src/backends/backendsCommon/test/TestDynamicBackend.hpp67
6 files changed, 445 insertions, 4 deletions
diff --git a/src/backends/backendsCommon/DynamicBackend.cpp b/src/backends/backendsCommon/DynamicBackend.cpp
index 410265eb38..06d819b9a7 100644
--- a/src/backends/backendsCommon/DynamicBackend.cpp
+++ b/src/backends/backendsCommon/DynamicBackend.cpp
@@ -45,7 +45,13 @@ BackendId DynamicBackend::GetBackendId()
throw RuntimeException("GetBackendId error: invalid function pointer");
}
- return BackendId(m_BackendIdFunction());
+ const char* backendId = m_BackendIdFunction();
+ if (backendId == nullptr)
+ {
+ throw RuntimeException("GetBackendId error: invalid backend id");
+ }
+
+ return BackendId(backendId);
}
BackendVersion DynamicBackend::GetBackendVersion()
diff --git a/src/backends/backendsCommon/test/CMakeLists.txt b/src/backends/backendsCommon/test/CMakeLists.txt
index 4131b9e787..8c9644ff94 100644
--- a/src/backends/backendsCommon/test/CMakeLists.txt
+++ b/src/backends/backendsCommon/test/CMakeLists.txt
@@ -75,3 +75,52 @@ list(APPEND armnnTestSharedObject_sources
add_library_ex(armnnTestSharedObject SHARED ${armnnTestSharedObject_sources})
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/libarmnnNoSharedObject.txt "This is not a shared object")
+
+# Dummy dynamic backends for testing.
+# Both a valid and a number of invalid dummy dynamic backends (covering various use cases) share the
+# same source code. The various test cases are put together in the code using compiler directives.
+
+list(APPEND armnnTestDynamicBackend_sources
+ TestDynamicBackend.cpp
+ TestDynamicBackend.hpp
+)
+
+add_library_ex(armnnValidTestDynamicBackend SHARED ${armnnTestDynamicBackend_sources})
+target_compile_definitions(armnnValidTestDynamicBackend PRIVATE -DVALID_TEST_DYNAMIC_BACKEND)
+target_include_directories(armnnValidTestDynamicBackend PRIVATE ${PROJECT_SOURCE_DIR}/src/armnn)
+target_include_directories(armnnValidTestDynamicBackend PRIVATE ${PROJECT_SOURCE_DIR}/src/backends)
+
+add_library_ex(armnnInvalidTestDynamicBackend1 SHARED ${armnnTestDynamicBackend_sources})
+target_compile_definitions(armnnInvalidTestDynamicBackend1 PRIVATE -DINVALID_TEST_DYNAMIC_BACKEND_1)
+target_include_directories(armnnInvalidTestDynamicBackend1 PRIVATE ${PROJECT_SOURCE_DIR}/src/armnn)
+target_include_directories(armnnInvalidTestDynamicBackend1 PRIVATE ${PROJECT_SOURCE_DIR}/src/backends)
+
+add_library_ex(armnnInvalidTestDynamicBackend2 SHARED ${armnnTestDynamicBackend_sources})
+target_compile_definitions(armnnInvalidTestDynamicBackend2 PRIVATE -DINVALID_TEST_DYNAMIC_BACKEND_2)
+target_include_directories(armnnInvalidTestDynamicBackend2 PRIVATE ${PROJECT_SOURCE_DIR}/src/armnn)
+target_include_directories(armnnInvalidTestDynamicBackend2 PRIVATE ${PROJECT_SOURCE_DIR}/src/backends)
+
+add_library_ex(armnnInvalidTestDynamicBackend3 SHARED ${armnnTestDynamicBackend_sources})
+target_compile_definitions(armnnInvalidTestDynamicBackend3 PRIVATE -DINVALID_TEST_DYNAMIC_BACKEND_3)
+target_include_directories(armnnInvalidTestDynamicBackend3 PRIVATE ${PROJECT_SOURCE_DIR}/src/armnn)
+target_include_directories(armnnInvalidTestDynamicBackend3 PRIVATE ${PROJECT_SOURCE_DIR}/src/backends)
+
+add_library_ex(armnnInvalidTestDynamicBackend4 SHARED ${armnnTestDynamicBackend_sources})
+target_compile_definitions(armnnInvalidTestDynamicBackend4 PRIVATE -DINVALID_TEST_DYNAMIC_BACKEND_4)
+target_include_directories(armnnInvalidTestDynamicBackend4 PRIVATE ${PROJECT_SOURCE_DIR}/src/armnn)
+target_include_directories(armnnInvalidTestDynamicBackend4 PRIVATE ${PROJECT_SOURCE_DIR}/src/backends)
+
+add_library_ex(armnnInvalidTestDynamicBackend5 SHARED ${armnnTestDynamicBackend_sources})
+target_compile_definitions(armnnInvalidTestDynamicBackend5 PRIVATE -DINVALID_TEST_DYNAMIC_BACKEND_5)
+target_include_directories(armnnInvalidTestDynamicBackend5 PRIVATE ${PROJECT_SOURCE_DIR}/src/armnn)
+target_include_directories(armnnInvalidTestDynamicBackend5 PRIVATE ${PROJECT_SOURCE_DIR}/src/backends)
+
+add_library_ex(armnnInvalidTestDynamicBackend6 SHARED ${armnnTestDynamicBackend_sources})
+target_compile_definitions(armnnInvalidTestDynamicBackend6 PRIVATE -DINVALID_TEST_DYNAMIC_BACKEND_6)
+target_include_directories(armnnInvalidTestDynamicBackend6 PRIVATE ${PROJECT_SOURCE_DIR}/src/armnn)
+target_include_directories(armnnInvalidTestDynamicBackend6 PRIVATE ${PROJECT_SOURCE_DIR}/src/backends)
+
+add_library_ex(armnnInvalidTestDynamicBackend7 SHARED ${armnnTestDynamicBackend_sources})
+target_compile_definitions(armnnInvalidTestDynamicBackend7 PRIVATE -DINVALID_TEST_DYNAMIC_BACKEND_7)
+target_include_directories(armnnInvalidTestDynamicBackend7 PRIVATE ${PROJECT_SOURCE_DIR}/src/armnn)
+target_include_directories(armnnInvalidTestDynamicBackend7 PRIVATE ${PROJECT_SOURCE_DIR}/src/backends)
diff --git a/src/backends/backendsCommon/test/DynamicBackendTests.cpp b/src/backends/backendsCommon/test/DynamicBackendTests.cpp
index 30622b6b3b..10a650af7e 100644
--- a/src/backends/backendsCommon/test/DynamicBackendTests.cpp
+++ b/src/backends/backendsCommon/test/DynamicBackendTests.cpp
@@ -5,6 +5,8 @@
#include "DynamicBackendTests.hpp"
+#include <test/UnitTests.hpp>
+
BOOST_AUTO_TEST_SUITE(DynamicBackendTests)
ARMNN_SIMPLE_TEST_CASE(OpenCloseHandle, OpenCloseHandleTestImpl);
@@ -19,4 +21,23 @@ ARMNN_SIMPLE_TEST_CASE(GetNotExistingEntryPoint, GetNotExistingEntryPointTestImp
ARMNN_SIMPLE_TEST_CASE(BackendVersioning, BackendVersioningTestImpl);
+ARMNN_SIMPLE_TEST_CASE(CreateValidDynamicBackendObject, CreateValidDynamicBackendObjectTestImpl);
+
+ARMNN_SIMPLE_TEST_CASE(CreateDynamicBackendObjectInvalidHandle,
+ CreateDynamicBackendObjectInvalidHandleTestImpl);
+ARMNN_SIMPLE_TEST_CASE(CreateDynamicBackendObjectInvalidInterface1,
+ CreateDynamicBackendObjectInvalidInterface1TestImpl);
+ARMNN_SIMPLE_TEST_CASE(CreateDynamicBackendObjectInvalidInterface2,
+ CreateDynamicBackendObjectInvalidInterface2TestImpl);
+ARMNN_SIMPLE_TEST_CASE(CreateDynamicBackendObjectInvalidInterface3,
+ CreateDynamicBackendObjectInvalidInterface3TestImpl);
+ARMNN_SIMPLE_TEST_CASE(CreateDynamicBackendObjectInvalidInterface4,
+ CreateDynamicBackendObjectInvalidInterface4TestImpl);
+ARMNN_SIMPLE_TEST_CASE(CreateDynamicBackendObjectInvalidInterface5,
+ CreateDynamicBackendObjectInvalidInterface5TestImpl);
+ARMNN_SIMPLE_TEST_CASE(CreateDynamicBackendObjectInvalidInterface6,
+ CreateDynamicBackendObjectInvalidInterface6TestImpl);
+ARMNN_SIMPLE_TEST_CASE(CreateDynamicBackendObjectInvalidInterface7,
+ CreateDynamicBackendObjectInvalidInterface7TestImpl);
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/backends/backendsCommon/test/DynamicBackendTests.hpp b/src/backends/backendsCommon/test/DynamicBackendTests.hpp
index 9835113458..1b3edc5e22 100644
--- a/src/backends/backendsCommon/test/DynamicBackendTests.hpp
+++ b/src/backends/backendsCommon/test/DynamicBackendTests.hpp
@@ -5,17 +5,27 @@
#pragma once
+#include <backendsCommon/DynamicBackend.hpp>
#include <backendsCommon/DynamicBackendUtils.hpp>
-#include <test/UnitTests.hpp>
+#include <string>
+#include <memory>
#include <string>
#include <boost/test/unit_test.hpp>
#include <boost/filesystem.hpp>
-static std::string g_TestSharedObjectSubDir = "src/backends/backendsCommon/test/";
-static std::string g_TestSharedObjectFileName = "libarmnnTestSharedObject.so";
+static std::string g_TestSharedObjectSubDir = "src/backends/backendsCommon/test/";
+static std::string g_TestSharedObjectFileName = "libarmnnTestSharedObject.so";
+static std::string g_TestValidTestDynamicBackendFileName = "libarmnnValidTestDynamicBackend.so";
+static std::string g_TestInvalidTestDynamicBackend1FileName = "libarmnnInvalidTestDynamicBackend1.so";
+static std::string g_TestInvalidTestDynamicBackend2FileName = "libarmnnInvalidTestDynamicBackend2.so";
+static std::string g_TestInvalidTestDynamicBackend3FileName = "libarmnnInvalidTestDynamicBackend3.so";
+static std::string g_TestInvalidTestDynamicBackend4FileName = "libarmnnInvalidTestDynamicBackend4.so";
+static std::string g_TestInvalidTestDynamicBackend5FileName = "libarmnnInvalidTestDynamicBackend5.so";
+static std::string g_TestInvalidTestDynamicBackend6FileName = "libarmnnInvalidTestDynamicBackend6.so";
+static std::string g_TestInvalidTestDynamicBackend7FileName = "libarmnnInvalidTestDynamicBackend7.so";
std::string GetTestFilePath(const std::string& fileName)
{
@@ -209,3 +219,196 @@ void BackendVersioningTestImpl()
BOOST_TEST(earlierMinorBackendVersion <= backendApiVersion);
BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, earlierMinorBackendVersion) == true);
}
+
+void CreateValidDynamicBackendObjectTestImpl()
+{
+ // Valid shared object handle
+ // Correct name mangling
+ // Correct interface
+ // Correct backend implementation
+
+ using namespace armnn;
+
+ std::string sharedObjectFilePath = GetTestFilePath(g_TestValidTestDynamicBackendFileName);
+
+ void* sharedObjectHandle = nullptr;
+ BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
+ BOOST_TEST((sharedObjectHandle != nullptr));
+
+ std::unique_ptr<DynamicBackend> dynamicBackend;
+ BOOST_CHECK_NO_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)));
+ BOOST_TEST((dynamicBackend != nullptr));
+
+ BackendId dynamicBackendId;
+ BOOST_CHECK_NO_THROW(dynamicBackendId = dynamicBackend->GetBackendId());
+ BOOST_TEST((dynamicBackendId == "ValidTestDynamicBackend"));
+
+ BackendVersion dynamicBackendVersion;
+ BOOST_CHECK_NO_THROW(dynamicBackendVersion = dynamicBackend->GetBackendVersion());
+ BOOST_TEST((dynamicBackendVersion == BackendVersion({ 1, 0 })));
+
+ IBackendInternalUniquePtr dynamicBackendInstance;
+ BOOST_CHECK_NO_THROW(dynamicBackendInstance = dynamicBackend->GetBackend());
+ BOOST_TEST((dynamicBackendInstance != nullptr));
+
+ BOOST_TEST((dynamicBackendInstance->GetId() == "ValidTestDynamicBackend"));
+}
+
+void CreateDynamicBackendObjectInvalidHandleTestImpl()
+{
+ // Invalid (null) shared object handle
+
+ using namespace armnn;
+
+ void* sharedObjectHandle = nullptr;
+ std::unique_ptr<DynamicBackend> dynamicBackend;
+ BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), InvalidArgumentException);
+ BOOST_TEST((dynamicBackend == nullptr));
+}
+
+void CreateDynamicBackendObjectInvalidInterface1TestImpl()
+{
+ // Valid shared object handle
+ // Wrong (not C-style) name mangling
+
+ using namespace armnn;
+
+ std::string sharedObjectFilePath = GetTestFilePath(g_TestInvalidTestDynamicBackend1FileName);
+
+ void* sharedObjectHandle = nullptr;
+ BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
+ BOOST_TEST((sharedObjectHandle != nullptr));
+
+ std::unique_ptr<DynamicBackend> dynamicBackend;
+ BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
+ BOOST_TEST((dynamicBackend == nullptr));
+}
+
+void CreateDynamicBackendObjectInvalidInterface2TestImpl()
+{
+ // Valid shared object handle
+ // Correct name mangling
+ // Wrong interface (missing GetBackendId())
+
+ using namespace armnn;
+
+ std::string sharedObjectFilePath = GetTestFilePath(g_TestInvalidTestDynamicBackend2FileName);
+
+ void* sharedObjectHandle = nullptr;
+ BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
+ BOOST_TEST((sharedObjectHandle != nullptr));
+
+ std::unique_ptr<DynamicBackend> dynamicBackend;
+ BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
+ BOOST_TEST((dynamicBackend == nullptr));
+}
+
+void CreateDynamicBackendObjectInvalidInterface3TestImpl()
+{
+ // Valid shared object handle
+ // Correct name mangling
+ // Wrong interface (missing GetVersion())
+
+ using namespace armnn;
+
+ std::string sharedObjectFilePath = GetTestFilePath(g_TestInvalidTestDynamicBackend3FileName);
+
+ void* sharedObjectHandle = nullptr;
+ BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
+ BOOST_TEST((sharedObjectHandle != nullptr));
+
+ std::unique_ptr<DynamicBackend> dynamicBackend;
+ BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
+ BOOST_TEST((dynamicBackend == nullptr));
+}
+
+void CreateDynamicBackendObjectInvalidInterface4TestImpl()
+{
+ // Valid shared object handle
+ // Correct name mangling
+ // Wrong interface (missing BackendFactory())
+
+ using namespace armnn;
+
+ std::string sharedObjectFilePath = GetTestFilePath(g_TestInvalidTestDynamicBackend4FileName);
+
+ void* sharedObjectHandle = nullptr;
+ BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
+ BOOST_TEST((sharedObjectHandle != nullptr));
+
+ std::unique_ptr<DynamicBackend> dynamicBackend;
+ BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
+ BOOST_TEST((dynamicBackend == nullptr));
+}
+
+void CreateDynamicBackendObjectInvalidInterface5TestImpl()
+{
+ // Valid shared object handle
+ // Correct name mangling
+ // Correct interface
+ // Invalid (null) backend id returned by GetBackendId()
+
+ using namespace armnn;
+
+ std::string sharedObjectFilePath = GetTestFilePath(g_TestInvalidTestDynamicBackend5FileName);
+
+ void* sharedObjectHandle = nullptr;
+ BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
+ BOOST_TEST((sharedObjectHandle != nullptr));
+
+ std::unique_ptr<DynamicBackend> dynamicBackend;
+ BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
+ BOOST_TEST((dynamicBackend == nullptr));
+}
+
+void CreateDynamicBackendObjectInvalidInterface6TestImpl()
+{
+ // Valid shared object handle
+ // Correct name mangling
+ // Correct interface
+ // Invalid (null) backend instance returned by BackendFactory()
+
+ using namespace armnn;
+
+ std::string sharedObjectFilePath = GetTestFilePath(g_TestInvalidTestDynamicBackend6FileName);
+
+ void* sharedObjectHandle = nullptr;
+ BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
+ BOOST_TEST((sharedObjectHandle != nullptr));
+
+ std::unique_ptr<DynamicBackend> dynamicBackend;
+ BOOST_CHECK_NO_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)));
+ BOOST_TEST((dynamicBackend != nullptr));
+
+ BackendId dynamicBackendId;
+ BOOST_CHECK_NO_THROW(dynamicBackendId = dynamicBackend->GetBackendId());
+ BOOST_TEST((dynamicBackendId == "InvalidTestDynamicBackend"));
+
+ BackendVersion dynamicBackendVersion;
+ BOOST_CHECK_NO_THROW(dynamicBackendVersion = dynamicBackend->GetBackendVersion());
+ BOOST_TEST((dynamicBackendVersion == BackendVersion({ 1, 0 })));
+
+ IBackendInternalUniquePtr dynamicBackendInstance;
+ BOOST_CHECK_THROW(dynamicBackendInstance = dynamicBackend->GetBackend(), RuntimeException);
+ BOOST_TEST((dynamicBackendInstance == nullptr));
+}
+
+void CreateDynamicBackendObjectInvalidInterface7TestImpl()
+{
+ // Valid shared object handle
+ // Correct name mangling
+ // Correct interface
+ // Invalid (incompatible backend API version) backend instance returned by BackendFactory()
+
+ using namespace armnn;
+
+ std::string sharedObjectFilePath = GetTestFilePath(g_TestInvalidTestDynamicBackend7FileName);
+
+ void* sharedObjectHandle = nullptr;
+ BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
+ BOOST_TEST((sharedObjectHandle != nullptr));
+
+ std::unique_ptr<DynamicBackend> dynamicBackend;
+ BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
+ BOOST_TEST((dynamicBackend == nullptr));
+}
diff --git a/src/backends/backendsCommon/test/TestDynamicBackend.cpp b/src/backends/backendsCommon/test/TestDynamicBackend.cpp
new file mode 100644
index 0000000000..7fd996fae8
--- /dev/null
+++ b/src/backends/backendsCommon/test/TestDynamicBackend.cpp
@@ -0,0 +1,95 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include "TestDynamicBackend.hpp"
+
+#include <backendsCommon/IBackendInternal.hpp>
+
+constexpr const char* TestDynamicBackendId()
+{
+#if defined(VALID_TEST_DYNAMIC_BACKEND)
+
+ return "ValidTestDynamicBackend";
+
+#else
+
+ return "InvalidTestDynamicBackend";
+
+#endif
+}
+
+class TestDynamicBackend : public armnn::IBackendInternal
+{
+public:
+ TestDynamicBackend()
+ : m_BackendId(TestDynamicBackendId())
+ {}
+
+ const armnn::BackendId& GetId() const override
+ {
+ return m_BackendId;
+ }
+ IWorkloadFactoryPtr CreateWorkloadFactory(const IMemoryManagerSharedPtr& memoryManager) const override
+ {
+ return IWorkloadFactoryPtr{};
+ }
+ ILayerSupportSharedPtr GetLayerSupport() const override
+ {
+ return ILayerSupportSharedPtr{};
+ }
+
+private:
+ armnn::BackendId m_BackendId;
+};
+
+const char* GetBackendId()
+{
+#if defined(INVALID_TEST_DYNAMIC_BACKEND_5)
+
+ // Return an invalid backend id
+ return nullptr;
+
+#else
+
+ // Return a valid backend id
+ return TestDynamicBackendId();
+
+#endif
+}
+
+void GetVersion(uint32_t* outMajor, uint32_t* outMinor)
+{
+ if (!outMajor || !outMinor)
+ {
+ return;
+ }
+
+#if defined(INVALID_TEST_DYNAMIC_BACKEND_7)
+
+ *outMajor = 0;
+ *outMinor = 7;
+
+#else
+
+ *outMajor = 1;
+ *outMinor = 0;
+
+#endif
+}
+
+void* BackendFactory()
+{
+#if defined(INVALID_TEST_DYNAMIC_BACKEND_6)
+
+ // Return an invalid backend instance
+ return nullptr;
+
+#else
+
+ // Return a non-null backend instance
+ return new TestDynamicBackend();
+
+#endif
+}
diff --git a/src/backends/backendsCommon/test/TestDynamicBackend.hpp b/src/backends/backendsCommon/test/TestDynamicBackend.hpp
new file mode 100644
index 0000000000..599ca16636
--- /dev/null
+++ b/src/backends/backendsCommon/test/TestDynamicBackend.hpp
@@ -0,0 +1,67 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#pragma once
+
+#include <cstdint>
+
+#if defined(VALID_TEST_DYNAMIC_BACKEND)
+
+// Correct dynamic backend interface
+extern "C"
+{
+const char* GetBackendId();
+void GetVersion(uint32_t* outMajor, uint32_t* outMinor);
+void* BackendFactory();
+}
+
+#elif defined(INVALID_TEST_DYNAMIC_BACKEND_1)
+
+// Wrong external linkage: expected C-style name mangling
+extern const char* GetBackendId();
+extern void GetVersion(uint32_t* outMajor, uint32_t* outMinor);
+extern void* BackendFactory();
+
+#else
+
+extern "C"
+{
+
+#if defined(INVALID_TEST_DYNAMIC_BACKEND_2)
+
+// Invalid interface: missing "GetBackendId()"
+void GetVersion(uint32_t* outMajor, uint32_t* outMinor);
+void* BackendFactory();
+
+#elif defined(INVALID_TEST_DYNAMIC_BACKEND_3)
+
+// Invalid interface: missing "GetVersion()"
+const char* GetBackendId();
+void* BackendFactory();
+
+#elif defined(INVALID_TEST_DYNAMIC_BACKEND_4)
+
+// Invalid interface: missing "BackendFactory()"
+const char* GetBackendId();
+void GetVersion(uint32_t* outMajor, uint32_t* outMinor);
+
+#elif defined(INVALID_TEST_DYNAMIC_BACKEND_5) || \
+ defined(INVALID_TEST_DYNAMIC_BACKEND_6) || \
+ defined(INVALID_TEST_DYNAMIC_BACKEND_7)
+
+// The interface is correct, the corresponding invalid changes are in the TestDynamicBackend.cpp file
+const char* GetBackendId();
+void GetVersion(uint32_t* outMajor, uint32_t* outMinor);
+void* BackendFactory();
+
+#else
+
+#error "Invalid or missing configuration macro for the TestDynamicBackend object"
+
+#endif
+
+}
+
+#endif