//
// Copyright © 2017 Arm Ltd. All rights reserved.
// SPDX-License-Identifier: MIT
//

#pragma once

#include <armnn/BackendRegistry.hpp>
#include <armnn/backends/DynamicBackend.hpp>
#include <armnn/backends/ILayerSupport.hpp>
#include <armnn/utility/PolymorphicDowncast.hpp>
#include <backendsCommon/DynamicBackendUtils.hpp>
#include <armnn/backends/TensorHandle.hpp>
#include <armnnUtils/Filesystem.hpp>
#include <reference/workloads/RefConvolution2dWorkload.hpp>
#include <Runtime.hpp>

#include <string>
#include <memory>

#include <doctest/doctest.h>

#if defined(_MSC_VER)
#include <Windows.h>
#endif

#if !defined(DYNAMIC_BACKEND_BUILD_DIR)
#define DYNAMIC_BACKEND_BUILD_DIR fs::path("./")
#endif

static std::string g_TestDirCLI                             = "--dynamic-backend-build-dir";
static std::string g_TestBaseDir                            = "src/backends/backendsCommon/test/";

static std::string g_TestSharedObjectSubDir                 = "testSharedObject/";
static std::string g_TestDynamicBackendSubDir               = "testDynamicBackend/";

static std::string g_TestSharedObjectFileName               = "libTestSharedObject.so";
static std::string g_TestNoSharedObjectFileName             = "libNoSharedObject.txt";

static std::string g_TestValidTestDynamicBackendFileName    = "libValidTestDynamicBackend.so";
static std::string g_TestInvalidTestDynamicBackend1FileName = "libInvalidTestDynamicBackend1.so";
static std::string g_TestInvalidTestDynamicBackend2FileName = "libInvalidTestDynamicBackend2.so";
static std::string g_TestInvalidTestDynamicBackend3FileName = "libInvalidTestDynamicBackend3.so";
static std::string g_TestInvalidTestDynamicBackend4FileName = "libInvalidTestDynamicBackend4.so";
static std::string g_TestInvalidTestDynamicBackend5FileName = "libInvalidTestDynamicBackend5.so";
static std::string g_TestInvalidTestDynamicBackend6FileName = "libInvalidTestDynamicBackend6.so";
static std::string g_TestInvalidTestDynamicBackend7FileName = "libInvalidTestDynamicBackend7.so";

static std::string g_TestValidBackend2FileName              = "Arm_TestValid2_backend.so";
static std::string g_TestValidBackend3FileName              = "Arm_TestValid3_backend.so";
static std::string g_TestValidBackend4FileName              = "Arm_TestValid4_backend.so";
static std::string g_TestValidBackend5FileName              = "Arm_TestValid5_backend.so";
static std::string g_TestInvalidBackend8FileName            = "Arm_TestInvalid8_backend.so";
static std::string g_TestInvalidBackend9FileName            = "Arm_TestInvalid9_backend.so";
static std::string g_TestInvalidBackend10FileName           = "Arm_TestInvalid10_backend.so";
static std::string g_TestInvalidBackend11FileName           = "Arm_TestInvalid11_backend.so";

static std::string g_TestDynamicBackendsSubDir1  = "backendsTestPath1/";
static std::string g_TestDynamicBackendsSubDir2  = "backendsTestPath2/";
static std::string g_TestDynamicBackendsSubDir3  = "backendsTestPath3/";
static std::string g_TestDynamicBackendsSubDir4  = "backendsTestPath4/";
static std::string g_TestDynamicBackendsSubDir5  = "backendsTestPath5/";
static std::string g_TestDynamicBackendsSubDir6  = "backendsTestPath6/";
static std::string g_TestDynamicBackendsSubDir7  = "backendsTestPath7/";
static std::string g_TestDynamicBackendsSubDir8  = "backendsTestPath8/";
static std::string g_TestDynamicBackendsSubDir9  = "backendsTestPath9/";

static std::string g_DynamicBackendsBaseDir                 = "src/backends/dynamic";
static std::string g_ReferenceDynamicBackendSubDir          = "reference/";
static std::string g_ReferenceBackendFileName               = "Arm_CpuRef_backend.so";

// DynamicBackendUtils wrapper class used for testing (allows to directly invoke the protected methods)
class TestDynamicBackendUtils : public armnn::DynamicBackendUtils
{
public:
    static bool IsBackendCompatibleTest(const armnn::BackendVersion& backendApiVersion,
                                        const armnn::BackendVersion& backendVersion)
    {
        return IsBackendCompatibleImpl(backendApiVersion, backendVersion);
    }

    static std::vector<std::string> GetBackendPathsImplTest(const std::string& path)
    {
        return GetBackendPathsImpl(path);
    }

    static armnn::BackendIdSet RegisterDynamicBackendsImplTest(
            armnn::BackendRegistry& backendRegistry,
            const std::vector<armnn::DynamicBackendPtr>& dynamicBackends)
    {
        return RegisterDynamicBackendsImpl(backendRegistry, dynamicBackends);
    }
};

// BackendRegistry wrapper class used for testing (swaps the underlying factory storage)
class TestBackendRegistry : public armnn::BackendRegistry
{
public:
    TestBackendRegistry() : armnn::BackendRegistry()
    {
        Swap(armnn::BackendRegistryInstance(), m_TempStorage);
    }

    ~TestBackendRegistry()
    {
        Swap(armnn::BackendRegistryInstance(), m_TempStorage);
    }

private:
    FactoryStorage m_TempStorage;
};

#if defined(_MSC_VER)
std::string GetUnitTestExecutablePath()
{
    char buffer[MAX_PATH] = "";
    GetModuleFileNameA(NULL, buffer, MAX_PATH);
    fs::path executablePath(buffer);
    return executablePath.parent_path();
}

#else
std::string GetUnitTestExecutablePath()
{
    char buffer[PATH_MAX] = "";
    if (readlink("/proc/self/exe", buffer, PATH_MAX) != -1)
    {
        fs::path executablePath(buffer);
        return executablePath.parent_path();
    }
    return "";
}
#endif

std::string GetBasePath(const std::string& basePath)
{
    using namespace fs;
    // What we're looking for here is the location of the UnitTests executable.
    // Fall back value of current directory.
    path programLocation = GetUnitTestExecutablePath();
    if (!exists(programLocation))
    {
        programLocation = DYNAMIC_BACKEND_BUILD_DIR;
    }

    // This is the base path from the build where the test libraries were built.
    path sharedObjectPath = programLocation.append(basePath);
    REQUIRE_MESSAGE(exists(sharedObjectPath),
                    ("Base path for shared objects does not exist: " + sharedObjectPath.string()));
    return sharedObjectPath.string();
}

std::string GetTestDirectoryBasePath()
{
    return GetBasePath(g_TestBaseDir);
}

std::string GetDynamicBackendsBasePath()
{
    return GetBasePath(g_DynamicBackendsBaseDir);
}

std::string GetTestSubDirectory(const std::string& subdir)
{
    using namespace fs;

    std::string testDynamicBackendsBaseDir = GetTestDirectoryBasePath();
    path testDynamicBackendsBasePath(testDynamicBackendsBaseDir);
    path testDynamicBackendsSubDir = testDynamicBackendsBasePath.append(subdir);
    // Do not check that the sub-directory exists because for testing reasons we may use non-existing paths

    return testDynamicBackendsSubDir.string();
}

std::string GetTestSubDirectory(const std::string& basePath, const std::string& subdir)
{
    using namespace fs;

    path testDynamicBackendsBasePath(basePath);
    path testDynamicBackendsSubDir = testDynamicBackendsBasePath.append(subdir);
    // Do not check that the sub-directory exists because for testing reasons we may use non-existing paths

    return testDynamicBackendsSubDir.string();
}

std::string GetTestFilePath(const std::string& directory, const std::string& fileName)
{
    using namespace fs;

    path directoryPath(directory);
    path fileNamePath = directoryPath.append(fileName);
    CHECK(exists(fileNamePath));

    return fileNamePath.string();
}

void OpenCloseHandleTestImpl()
{
    using namespace armnn;

    std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
    std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);

    void* sharedObjectHandle = nullptr;
    CHECK_NOTHROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
    CHECK((sharedObjectHandle != nullptr));

    DynamicBackendUtils::CloseHandle(sharedObjectHandle);
}

void CloseInvalidHandleTestImpl()
{
    using namespace armnn;

    // This calls must silently handle invalid handles and complete successfully (no segfaults, etc.)
    DynamicBackendUtils::CloseHandle(nullptr);
}

void OpenEmptyFileNameTestImpl()
{
    using namespace armnn;

    void* sharedObjectHandle = nullptr;
    CHECK_THROWS_AS(sharedObjectHandle = DynamicBackendUtils::OpenHandle(""), RuntimeException);
    CHECK((sharedObjectHandle == nullptr));
}

void OpenNotExistingFileTestImpl()
{
    using namespace armnn;

    void* sharedObjectHandle = nullptr;
    CHECK_THROWS_AS(sharedObjectHandle = DynamicBackendUtils::OpenHandle("NotExistingFileName"), RuntimeException);
    CHECK((sharedObjectHandle == nullptr));
}

void OpenNotSharedObjectTestImpl()
{
    using namespace armnn;

    std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
    std::string notSharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestNoSharedObjectFileName);

    void* sharedObjectHandle = nullptr;
    CHECK_THROWS_AS(sharedObjectHandle = DynamicBackendUtils::OpenHandle(notSharedObjectFilePath), RuntimeException);
    CHECK((sharedObjectHandle == nullptr));
}

void GetValidEntryPointTestImpl()
{
    using namespace armnn;

    std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
    std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);

    void* sharedObjectHandle = nullptr;
    CHECK_NOTHROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
    CHECK((sharedObjectHandle != nullptr));

    using TestFunctionType = int(*)(int);
    TestFunctionType testFunctionPointer = nullptr;
    CHECK_NOTHROW(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
                                                                                                    "TestFunction1"));
    CHECK((testFunctionPointer != nullptr));
    CHECK(testFunctionPointer(7) == 7);

    DynamicBackendUtils::CloseHandle(sharedObjectHandle);
}

void GetNameMangledEntryPointTestImpl()
{
    using namespace armnn;

    std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
    std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);

    void* sharedObjectHandle = nullptr;
    CHECK_NOTHROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
    CHECK((sharedObjectHandle != nullptr));

    using TestFunctionType = int(*)(int);
    TestFunctionType testFunctionPointer = nullptr;
    CHECK_THROWS_AS(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
                                                                                                 "TestFunction2"),
                      RuntimeException);
    CHECK((testFunctionPointer == nullptr));

    DynamicBackendUtils::CloseHandle(sharedObjectHandle);
}

void GetNoExternEntryPointTestImpl()
{
    using namespace armnn;

    std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
    std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);

    void* sharedObjectHandle = nullptr;
    CHECK_NOTHROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
    CHECK((sharedObjectHandle != nullptr));

    using TestFunctionType = int(*)(int);
    TestFunctionType testFunctionPointer = nullptr;
    CHECK_THROWS_AS(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
                                                                                                 "TestFunction3"),
                      RuntimeException);
    CHECK((testFunctionPointer == nullptr));

    DynamicBackendUtils::CloseHandle(sharedObjectHandle);
}

void GetNotExistingEntryPointTestImpl()
{
    using namespace armnn;

    std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
    std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);

    void* sharedObjectHandle = nullptr;
    CHECK_NOTHROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
    CHECK((sharedObjectHandle != nullptr));

    using TestFunctionType = int(*)(int);
    TestFunctionType testFunctionPointer = nullptr;
    CHECK_THROWS_AS(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
                                                                                                 "TestFunction4"),
                      RuntimeException);
    CHECK((testFunctionPointer == nullptr));

    DynamicBackendUtils::CloseHandle(sharedObjectHandle);
}

void BackendVersioningTestImpl()
{
    using namespace armnn;

    // The backend API version used for the tests
    BackendVersion backendApiVersion{ 2, 4 };

    // Same backend and backend API versions are compatible with the backend API
    BackendVersion sameBackendVersion{ 2, 4 };
    CHECK(sameBackendVersion == backendApiVersion);
    CHECK(sameBackendVersion <= backendApiVersion);
    CHECK(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, sameBackendVersion) == true);

    // Backend versions that differ from the backend API version by major revision are not compatible
    // with the backend API
    BackendVersion laterMajorBackendVersion{ 3, 4 };
    CHECK(!(laterMajorBackendVersion == backendApiVersion));
    CHECK(!(laterMajorBackendVersion <= backendApiVersion));
    CHECK(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, laterMajorBackendVersion) == false);

    BackendVersion earlierMajorBackendVersion{ 1, 4 };
    CHECK(!(earlierMajorBackendVersion == backendApiVersion));
    CHECK(earlierMajorBackendVersion <= backendApiVersion);
    CHECK(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion,
                                                                earlierMajorBackendVersion) == false);

    // Backend versions with the same major revision but later minor revision than
    // the backend API version are not compatible with the backend API
    BackendVersion laterMinorBackendVersion{ 2, 5 };
    CHECK(!(laterMinorBackendVersion == backendApiVersion));
    CHECK(!(laterMinorBackendVersion <= backendApiVersion));
    CHECK(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, laterMinorBackendVersion) == false);

    // Backend versions with the same major revision but earlier minor revision than
    // the backend API version are compatible with the backend API
    BackendVersion earlierMinorBackendVersion{ 2, 3 };
    CHECK(!(earlierMinorBackendVersion == backendApiVersion));
    CHECK(earlierMinorBackendVersion <= backendApiVersion);
    CHECK(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, earlierMinorBackendVersion) == true);
}

#if defined(ARMNNREF_ENABLED)
void CreateValidDynamicBackendObjectTestImpl()
{
    // Valid shared object handle
    // Correct name mangling
    // Correct interface
    // Correct backend implementation

    using namespace armnn;

    std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);

    // We expect this path to exists so we can load a valid dynamic backend.
    CHECK_MESSAGE(fs::exists(testSubDirectory),
                  ("Base path for shared objects does not exist: " + testSubDirectory));

    std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestValidTestDynamicBackendFileName);

    void* sharedObjectHandle = nullptr;
    CHECK_NOTHROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
    CHECK((sharedObjectHandle != nullptr));

    DynamicBackendPtr dynamicBackend;
    CHECK_NOTHROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)));
    CHECK((dynamicBackend != nullptr));

    BackendId dynamicBackendId;
    CHECK_NOTHROW(dynamicBackendId = dynamicBackend->GetBackendId());
    CHECK((dynamicBackendId == "ValidTestDynamicBackend"));

    BackendVersion dynamicBackendVersion;
    CHECK_NOTHROW(dynamicBackendVersion = dynamicBackend->GetBackendVersion());
    CHECK((dynamicBackendVersion == IBackendInternal::GetApiVersion()));

    IBackendInternalUniquePtr dynamicBackendInstance1;
    CHECK_NOTHROW(dynamicBackendInstance1 = dynamicBackend->GetBackend());
    CHECK((dynamicBackendInstance1 != nullptr));

    BackendRegistry::FactoryFunction dynamicBackendFactoryFunction = nullptr;
    CHECK_NOTHROW(dynamicBackendFactoryFunction = dynamicBackend->GetFactoryFunction());
    CHECK((dynamicBackendFactoryFunction != nullptr));

    IBackendInternalUniquePtr dynamicBackendInstance2;
    CHECK_NOTHROW(dynamicBackendInstance2 = dynamicBackendFactoryFunction());
    CHECK((dynamicBackendInstance2 != nullptr));

    CHECK((dynamicBackendInstance1->GetId() == "ValidTestDynamicBackend"));
    CHECK((dynamicBackendInstance2->GetId() == "ValidTestDynamicBackend"));
}
#endif

void CreateDynamicBackendObjectInvalidHandleTestImpl()
{
    // Invalid (null) shared object handle

    using namespace armnn;

    void* sharedObjectHandle = nullptr;
    DynamicBackendPtr dynamicBackend;
    CHECK_THROWS_AS(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), InvalidArgumentException);
    CHECK((dynamicBackend == nullptr));
}

void CreateDynamicBackendObjectInvalidInterface1TestImpl()
{
    // Valid shared object handle
    // Wrong (not C-style) name mangling

    using namespace armnn;

    std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
    std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend1FileName);

    void* sharedObjectHandle = nullptr;
    CHECK_NOTHROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
    CHECK((sharedObjectHandle != nullptr));

    DynamicBackendPtr dynamicBackend;
    CHECK_THROWS_AS(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
    CHECK((dynamicBackend == nullptr));
}

void CreateDynamicBackendObjectInvalidInterface2TestImpl()
{
    // Valid shared object handle
    // Correct name mangling
    // Wrong interface (missing GetBackendId())

    using namespace armnn;

    std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
    std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend2FileName);

    void* sharedObjectHandle = nullptr;
    CHECK_NOTHROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
    CHECK((sharedObjectHandle != nullptr));

    DynamicBackendPtr dynamicBackend;
    CHECK_THROWS_AS(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
    CHECK((dynamicBackend == nullptr));
}

void CreateDynamicBackendObjectInvalidInterface3TestImpl()
{
    // Valid shared object handle
    // Correct name mangling
    // Wrong interface (missing GetVersion())

    using namespace armnn;

    std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
    std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend3FileName);

    void* sharedObjectHandle = nullptr;
    CHECK_NOTHROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
    CHECK((sharedObjectHandle != nullptr));

    DynamicBackendPtr dynamicBackend;
    CHECK_THROWS_AS(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
    CHECK((dynamicBackend == nullptr));
}

void CreateDynamicBackendObjectInvalidInterface4TestImpl()
{
    // Valid shared object handle
    // Correct name mangling
    // Wrong interface (missing BackendFactory())

    using namespace armnn;

    std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
    std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend4FileName);

    void* sharedObjectHandle = nullptr;
    CHECK_NOTHROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
    CHECK((sharedObjectHandle != nullptr));

    DynamicBackendPtr dynamicBackend;
    CHECK_THROWS_AS(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
    CHECK((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 testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
    std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend5FileName);

    void* sharedObjectHandle = nullptr;
    CHECK_NOTHROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
    CHECK((sharedObjectHandle != nullptr));

    DynamicBackendPtr dynamicBackend;
    CHECK_THROWS_AS(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
    CHECK((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 testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
    std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend6FileName);

    void* sharedObjectHandle = nullptr;
    CHECK_NOTHROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
    CHECK((sharedObjectHandle != nullptr));

    DynamicBackendPtr dynamicBackend;
    CHECK_NOTHROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)));
    CHECK((dynamicBackend != nullptr));

    BackendId dynamicBackendId;
    CHECK_NOTHROW(dynamicBackendId = dynamicBackend->GetBackendId());
    CHECK((dynamicBackendId == "InvalidTestDynamicBackend"));

    BackendVersion dynamicBackendVersion;
    CHECK_NOTHROW(dynamicBackendVersion = dynamicBackend->GetBackendVersion());
    CHECK((dynamicBackendVersion >= BackendVersion({ 1, 0 })));

    IBackendInternalUniquePtr dynamicBackendInstance1;
    CHECK_THROWS_AS(dynamicBackendInstance1 = dynamicBackend->GetBackend(), RuntimeException);
    CHECK((dynamicBackendInstance1 == nullptr));

    BackendRegistry::FactoryFunction dynamicBackendFactoryFunction = nullptr;
    CHECK_NOTHROW(dynamicBackendFactoryFunction = dynamicBackend->GetFactoryFunction());
    CHECK((dynamicBackendFactoryFunction != nullptr));

    IBackendInternalUniquePtr dynamicBackendInstance2;
    CHECK_THROWS_AS(dynamicBackendInstance2 = dynamicBackendFactoryFunction(), RuntimeException);
    CHECK((dynamicBackendInstance2 == 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 testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
    std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend7FileName);

    void* sharedObjectHandle = nullptr;
    CHECK_NOTHROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
    CHECK((sharedObjectHandle != nullptr));

    DynamicBackendPtr dynamicBackend;
    CHECK_THROWS_AS(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
    CHECK((dynamicBackend == nullptr));
}

void GetBackendPathsTestImpl()
{
    using namespace armnn;
    using namespace fs;

    // The test covers four directories:
    // <unit test path>/src/backends/backendsCommon/test/
    //                                                ├─ backendsTestPath1/   -> exists, contains files
    //                                                ├─ backendsTestPath2/   -> exists, contains files
    //                                                ├─ backendsTestPath3/   -> exists, but empty
    //                                                └─ backendsTestPath4/   -> does not exist

    std::string subDir1 = GetTestSubDirectory(g_TestDynamicBackendsSubDir1);
    std::string subDir2 = GetTestSubDirectory(g_TestDynamicBackendsSubDir2);
    std::string subDir3 = GetTestSubDirectory(g_TestDynamicBackendsSubDir3);
    std::string subDir4 = GetTestSubDirectory(g_TestDynamicBackendsSubDir4);

    CHECK(exists(subDir1));
    CHECK(exists(subDir2));
    CHECK(exists(subDir3));
    CHECK(!exists(subDir4));

    // No path
    CHECK(TestDynamicBackendUtils::GetBackendPathsImplTest("").empty());

    // Malformed path
    std::string malformedDir(subDir1 + "/" + subDir1);
    CHECK(TestDynamicBackendUtils::GetBackendPathsImplTest(malformedDir).size()==0);

    // Single valid path
    std::vector<std::string> DynamicBackendPaths2 = TestDynamicBackendUtils::GetBackendPathsImplTest(subDir1);
    CHECK(DynamicBackendPaths2.size() == 1);
    CHECK(DynamicBackendPaths2[0] == subDir1);

    // Multiple equal and valid paths
    std::string multipleEqualDirs(subDir1 + ":" + subDir1);
    std::vector<std::string> DynamicBackendPaths3 = TestDynamicBackendUtils::GetBackendPathsImplTest(multipleEqualDirs);
    CHECK(DynamicBackendPaths3.size() == 1);
    CHECK(DynamicBackendPaths3[0] == subDir1);

    // Multiple empty paths
    CHECK(TestDynamicBackendUtils::GetBackendPathsImplTest(":::").empty());

    // Multiple valid paths
    std::string multipleValidPaths(subDir1 + ":" + subDir2 + ":" + subDir3);
    std::vector<std::string> DynamicBackendPaths5 =
        TestDynamicBackendUtils::GetBackendPathsImplTest(multipleValidPaths);
    CHECK(DynamicBackendPaths5.size() == 3);
    CHECK(DynamicBackendPaths5[0] == subDir1);
    CHECK(DynamicBackendPaths5[1] == subDir2);
    CHECK(DynamicBackendPaths5[2] == subDir3);

    // Valid among empty paths
    std::string validAmongEmptyDirs("::" + subDir1 + ":");
    std::vector<std::string> DynamicBackendPaths6 =
        TestDynamicBackendUtils::GetBackendPathsImplTest(validAmongEmptyDirs);
    CHECK(DynamicBackendPaths6.size() == 1);
    CHECK(DynamicBackendPaths6[0] == subDir1);

    // Invalid among empty paths
    std::string invalidAmongEmptyDirs(":" + subDir4 + "::");
    CHECK(TestDynamicBackendUtils::GetBackendPathsImplTest(invalidAmongEmptyDirs).empty());

    // Valid, invalid and empty paths
    std::string validInvalidEmptyDirs(subDir1 + ":" + subDir4 + ":");
    std::vector<std::string> DynamicBackendPaths8 =
        TestDynamicBackendUtils::GetBackendPathsImplTest(validInvalidEmptyDirs);
    CHECK(DynamicBackendPaths8.size() == 1);
    CHECK(DynamicBackendPaths8[0] == subDir1);

    // Mix of duplicates of valid, invalid and empty paths
    std::string duplicateValidInvalidEmptyDirs(validInvalidEmptyDirs + ":" + validInvalidEmptyDirs + ":" +
                                               subDir2 + ":" + subDir2);
    std::vector<std::string> DynamicBackendPaths9 =
        TestDynamicBackendUtils::GetBackendPathsImplTest(duplicateValidInvalidEmptyDirs);
    CHECK(DynamicBackendPaths9.size() == 2);
    CHECK(DynamicBackendPaths9[0] == subDir1);
    CHECK(DynamicBackendPaths9[1] == subDir2);
}

void GetBackendPathsOverrideTestImpl()
{
    using namespace armnn;
    using namespace fs;

    std::string subDir1 = GetTestSubDirectory(g_TestDynamicBackendsSubDir1);
    std::string subDir4 = GetTestSubDirectory(g_TestDynamicBackendsSubDir4);

    CHECK(exists(subDir1));
    CHECK(!exists(subDir4));

    // Override with valid path
    std::vector<std::string> validResult = DynamicBackendUtils::GetBackendPaths(subDir1);
    CHECK(validResult.size() == 1);
    CHECK(validResult[0] == subDir1);

    // Override with invalid path
    std::vector<std::string> invalidResult = DynamicBackendUtils::GetBackendPaths(subDir4);
    CHECK(invalidResult.empty());
}

void GetSharedObjectsTestImpl()
{
    using namespace armnn;
    using namespace fs;

    // The test covers four directories:
    // <unit test path>/src/backends/backendsCommon/test/
    //                                                ├─ backendsTestPath1/   -> exists, contains files
    //                                                ├─ backendsTestPath2/   -> exists, contains files
    //                                                ├─ backendsTestPath3/   -> exists, but empty
    //                                                └─ backendsTestPath4/   -> does not exist
    //
    // The test sub-directory backendsTestPath1/ contains the following test files:
    //
    // Arm_GpuAcc_backend.so                                       -> valid (basic backend name)
    // Arm_GpuAcc_backend.so.1                                     -> valid (single field version number)
    // Arm_GpuAcc_backend.so.1.2                                   -> valid (multiple field version number)
    // Arm_GpuAcc_backend.so.1.2.3                                 -> valid (multiple field version number)
    // Arm_GpuAcc_backend.so.10.1.27                               -> valid (Multiple digit version)
    // Arm_GpuAcc_backend.so.10.1.33.                              -> not valid (dot not followed by version number)
    // Arm_GpuAcc_backend.so.3.4..5                                -> not valid (dot not followed by version number)
    // Arm_GpuAcc_backend.so.1,1.1                                 -> not valid (comma instead of dot in the version)
    //
    // Arm123_GpuAcc_backend.so                                    -> valid (digits in vendor name are allowed)
    // Arm_GpuAcc456_backend.so                                    -> valid (digits in backend id are allowed)
    // Arm%Co_GpuAcc_backend.so                                    -> not valid (invalid character in vendor name)
    // Arm_Gpu.Acc_backend.so                                      -> not valid (invalid character in backend id)
    //
    // GpuAcc_backend.so                                           -> not valid (missing vendor name)
    // _GpuAcc_backend.so                                          -> not valid (missing vendor name)
    // Arm__backend.so                                             -> not valid (missing backend id)
    // Arm_GpuAcc.so                                               -> not valid (missing "backend" at the end)
    // __backend.so                                                -> not valid (missing vendor name and backend id)
    // __.so                                                       -> not valid (missing all fields)
    //
    // Arm_GpuAcc_backend                                          -> not valid (missing at least ".so" at the end)
    // Arm_GpuAcc_backend_v1.2.so                                  -> not valid (extra version info at the end)
    //
    // The test sub-directory backendsTestPath1/ contains the following test files:
    //
    // Arm_CpuAcc_backend.so                                       -> valid (basic backend name)
    // Arm_CpuAcc_backend.so.1 -> Arm_CpuAcc_backend.so            -> valid (symlink to valid backend file)
    // Arm_CpuAcc_backend.so.1.2 -> Arm_CpuAcc_backend.so.1        -> valid (symlink to valid symlink)
    // Arm_CpuAcc_backend.so.1.2.3 -> Arm_CpuAcc_backend.so.1.2    -> valid (symlink to valid symlink)
    //
    // Arm_no_backend.so -> nothing                                -> not valid (symlink resolves to non-existent file)
    //
    // Arm_GpuAcc_backend.so                                       -> valid (but duplicated from backendsTestPath1/)

    std::string testDynamicBackendsSubDir1 = GetTestSubDirectory(g_TestDynamicBackendsSubDir1);
    std::string testDynamicBackendsSubDir2 = GetTestSubDirectory(g_TestDynamicBackendsSubDir2);
    std::string testDynamicBackendsSubDir3 = GetTestSubDirectory(g_TestDynamicBackendsSubDir3);
    std::string testDynamicBackendsSubDir4 = GetTestSubDirectory(g_TestDynamicBackendsSubDir4);
    CHECK(exists(testDynamicBackendsSubDir1));
    CHECK(exists(testDynamicBackendsSubDir2));
    CHECK(exists(testDynamicBackendsSubDir3));
    CHECK(!exists(testDynamicBackendsSubDir4));

    std::vector<std::string> backendPaths
    {
        testDynamicBackendsSubDir1,
        testDynamicBackendsSubDir2,
        testDynamicBackendsSubDir3,
        testDynamicBackendsSubDir4
    };
    std::vector<std::string> sharedObjects = DynamicBackendUtils::GetSharedObjects(backendPaths);
    std::vector<fs::path> expectedSharedObjects
    {
        path(testDynamicBackendsSubDir1 + "Arm123_GpuAcc_backend.so"),      // Digits in vendor name are allowed
        path(testDynamicBackendsSubDir1 + "Arm_GpuAcc456_backend.so"),      // Digits in backend id are allowed
        path(testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so"),         // Basic backend name
        path(testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.1"),       // Single field version number
        path(testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.1.2"),     // Multiple field version number
        path(testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.1.2.3"),   // Multiple field version number
        path(testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.10.1.27"), // Multiple digit version
        path(testDynamicBackendsSubDir2 + "Arm_CpuAcc_backend.so"),         // Duplicate symlinks removed
        path(testDynamicBackendsSubDir2 + "Arm_GpuAcc_backend.so")          // Duplicates on different paths are allowed
    };

    CHECK(sharedObjects.size() == expectedSharedObjects.size());
    CHECK(fs::equivalent(path(sharedObjects[0]), expectedSharedObjects[0]));
    CHECK(fs::equivalent(path(sharedObjects[1]), expectedSharedObjects[1]));
    CHECK(fs::equivalent(path(sharedObjects[2]), expectedSharedObjects[2]));
    CHECK(fs::equivalent(path(sharedObjects[3]), expectedSharedObjects[3]));
    CHECK(fs::equivalent(path(sharedObjects[4]), expectedSharedObjects[4]));
    CHECK(fs::equivalent(path(sharedObjects[5]), expectedSharedObjects[5]));
    CHECK(fs::equivalent(path(sharedObjects[6]), expectedSharedObjects[6]));
    CHECK(fs::equivalent(path(sharedObjects[7]), expectedSharedObjects[7]));
    CHECK(fs::equivalent(path(sharedObjects[8]), expectedSharedObjects[8]));
}

void CreateDynamicBackendsTestImpl()
{
    using namespace armnn;
    using namespace fs;

    // The test covers four directories:
    // <unit test path>/src/backends/backendsCommon/test/
    //                                                ├─ backendsTestPath5/   -> exists, contains files
    //                                                ├─ backendsTestPath6/   -> exists, contains files
    //                                                ├─ backendsTestPath7/   -> exists, but empty
    //                                                └─ backendsTestPath8/   -> does not exist
    //
    // The test sub-directory backendsTestPath5/ contains the following test files:
    //
    // Arm_TestValid2_backend.so   -> valid (basic backend name)
    // Arm_TestValid3_backend.so   -> valid (basic backend name)
    // Arm_TestInvalid8_backend.so -> not valid (invalid backend id)
    //
    // The test sub-directory backendsTestPath6/ contains the following test files:
    //
    // Arm_TestValid2_backend.so   -> valid (but duplicated from backendsTestPath5/)
    // Arm_TestValid4_backend.so   -> valid (it has a different filename,
    //                                       but it has the same backend id of Arm_TestValid2_backend.so
    //                                       and the same version)
    // Arm_TestValid5_backend.so   -> valid (basic backend name)
    // Arm_TestInvalid9_backend.so -> not valid (it has a different filename,
    //                                           but it has the same backend id of Arm_TestValid2_backend.so
    //                                           and a version incompatible with the Backend API)

    std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
    std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
    std::string testDynamicBackendsSubDir7 = GetTestSubDirectory(g_TestDynamicBackendsSubDir7);
    std::string testDynamicBackendsSubDir8 = GetTestSubDirectory(g_TestDynamicBackendsSubDir8);
    CHECK(exists(testDynamicBackendsSubDir5));
    CHECK(exists(testDynamicBackendsSubDir6));
    CHECK(exists(testDynamicBackendsSubDir7));
    CHECK(!exists(testDynamicBackendsSubDir8));

    std::vector<std::string> backendPaths
    {
        testDynamicBackendsSubDir5,
        testDynamicBackendsSubDir6,
        testDynamicBackendsSubDir7,
        testDynamicBackendsSubDir8
    };
    std::vector<std::string> sharedObjects = DynamicBackendUtils::GetSharedObjects(backendPaths);
    std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends(sharedObjects);

    CHECK(dynamicBackends.size() == 5);
    CHECK((dynamicBackends[0] != nullptr));
    CHECK((dynamicBackends[1] != nullptr));
    CHECK((dynamicBackends[2] != nullptr));
    CHECK((dynamicBackends[3] != nullptr));
    CHECK((dynamicBackends[4] != nullptr));

    // Duplicates are allowed here, they will be skipped later during the backend registration
    CHECK((dynamicBackends[0]->GetBackendId() == "TestValid2"));
    CHECK((dynamicBackends[1]->GetBackendId() == "TestValid3"));
    CHECK((dynamicBackends[2]->GetBackendId() == "TestValid2")); // From duplicate Arm_TestValid2_backend.so
    CHECK((dynamicBackends[3]->GetBackendId() == "TestValid2")); // From Arm_TestValid4_backend.so
    CHECK((dynamicBackends[4]->GetBackendId() == "TestValid5"));
}

void CreateDynamicBackendsNoPathsTestImpl()
{
    using namespace armnn;

    std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends({});

    CHECK(dynamicBackends.empty());
}

void CreateDynamicBackendsAllInvalidTestImpl()
{
    using namespace armnn;

    std::vector<std::string> sharedObjects
    {
        "InvalidSharedObject1",
        "InvalidSharedObject2",
        "InvalidSharedObject3",
    };
    std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends(sharedObjects);

    CHECK(dynamicBackends.empty());
}

void CreateDynamicBackendsMixedTypesTestImpl()
{
    using namespace armnn;
    using namespace fs;

    std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
    std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
    CHECK(exists(testDynamicBackendsSubDir5));
    CHECK(exists(testDynamicBackendsSubDir6));

    std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5,
                                                            g_TestValidBackend2FileName);
    std::string testInvalidBackend8FilePath = GetTestFilePath(testDynamicBackendsSubDir5,
                                                              g_TestInvalidBackend8FileName);
    std::string testInvalidBackend9FilePath = GetTestFilePath(testDynamicBackendsSubDir6,
                                                              g_TestInvalidBackend9FileName);
    CHECK(exists(testValidBackend2FilePath));
    CHECK(exists(testInvalidBackend8FilePath));
    CHECK(exists(testInvalidBackend9FilePath));

    std::vector<std::string> sharedObjects
    {
        testValidBackend2FilePath,   // Arm_TestValid2_backend.so     -> valid (basic backend name)
        testInvalidBackend8FilePath, // Arm_TestInvalid8_backend.so   -> not valid (invalid backend id)
        testInvalidBackend9FilePath, // Arm_TestInvalid9_backend.so   -> not valid (incompatible version)
        "InvalidSharedObject",       // The file does not exist
    };
    std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends(sharedObjects);

    CHECK(dynamicBackends.size() == 1);
    CHECK((dynamicBackends[0] != nullptr));
    CHECK((dynamicBackends[0]->GetBackendId() == "TestValid2"));
}

#if defined(ARMNNREF_ENABLED)
void RegisterSingleDynamicBackendTestImpl()
{
    using namespace armnn;
    using namespace fs;

    // Register one valid dynamic backend

    // Dummy registry used for testing
    BackendRegistry backendRegistry;
    CHECK(backendRegistry.Size() == 0);

    std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
    CHECK(exists(testDynamicBackendsSubDir5));

    std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend2FileName);
    CHECK(exists(testValidBackend2FilePath));

    std::vector<std::string> sharedObjects{ testValidBackend2FilePath };
    std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);

    CHECK(dynamicBackends.size() == 1);
    CHECK((dynamicBackends[0] != nullptr));

    BackendId dynamicBackendId = dynamicBackends[0]->GetBackendId();
    CHECK((dynamicBackendId == "TestValid2"));

    BackendVersion dynamicBackendVersion = dynamicBackends[0]->GetBackendVersion();
    CHECK(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));

    BackendIdSet registeredBackendIds = TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry,
                                                                                                 dynamicBackends);
    CHECK(backendRegistry.Size() == 1);
    CHECK(registeredBackendIds.size() == 1);

    BackendIdSet backendIds = backendRegistry.GetBackendIds();
    CHECK(backendIds.size() == 1);
    CHECK((backendIds.find(dynamicBackendId) != backendIds.end()));
    CHECK((registeredBackendIds.find(dynamicBackendId) != registeredBackendIds.end()));

    auto dynamicBackendFactoryFunction = backendRegistry.GetFactory(dynamicBackendId);
    CHECK((dynamicBackendFactoryFunction != nullptr));

    IBackendInternalUniquePtr dynamicBackend = dynamicBackendFactoryFunction();
    CHECK((dynamicBackend != nullptr));
    CHECK((dynamicBackend->GetId() == dynamicBackendId));
}

void RegisterMultipleDynamicBackendsTestImpl()
{
    using namespace armnn;
    using namespace fs;

    // Register many valid dynamic backends

    std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
    std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
    CHECK(exists(testDynamicBackendsSubDir5));
    CHECK(exists(testDynamicBackendsSubDir6));

    std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend2FileName);
    std::string testValidBackend3FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend3FileName);
    std::string testValidBackend5FilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend5FileName);
    CHECK(exists(testValidBackend2FilePath));
    CHECK(exists(testValidBackend3FilePath));
    CHECK(exists(testValidBackend5FilePath));

    std::vector<std::string> sharedObjects
    {
        testValidBackend2FilePath,
        testValidBackend3FilePath,
        testValidBackend5FilePath
    };
    std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);

    CHECK(dynamicBackends.size() == 3);
    CHECK((dynamicBackends[0] != nullptr));
    CHECK((dynamicBackends[1] != nullptr));
    CHECK((dynamicBackends[2] != nullptr));

    BackendId dynamicBackendId1 = dynamicBackends[0]->GetBackendId();
    BackendId dynamicBackendId2 = dynamicBackends[1]->GetBackendId();
    BackendId dynamicBackendId3 = dynamicBackends[2]->GetBackendId();
    CHECK((dynamicBackendId1 == "TestValid2"));
    CHECK((dynamicBackendId2 == "TestValid3"));
    CHECK((dynamicBackendId3 == "TestValid5"));

    for (size_t i = 0; i < dynamicBackends.size(); i++)
    {
        BackendVersion dynamicBackendVersion = dynamicBackends[i]->GetBackendVersion();
        CHECK(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
    }

    // Dummy registry used for testing
    BackendRegistry backendRegistry;
    CHECK(backendRegistry.Size() == 0);

    BackendIdSet registeredBackendIds = TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry,
                                                                                                 dynamicBackends);
    CHECK(backendRegistry.Size() == 3);
    CHECK(registeredBackendIds.size() == 3);

    BackendIdSet backendIds = backendRegistry.GetBackendIds();
    CHECK(backendIds.size() == 3);
    CHECK((backendIds.find(dynamicBackendId1) != backendIds.end()));
    CHECK((backendIds.find(dynamicBackendId2) != backendIds.end()));
    CHECK((backendIds.find(dynamicBackendId3) != backendIds.end()));
    CHECK((registeredBackendIds.find(dynamicBackendId1) != registeredBackendIds.end()));
    CHECK((registeredBackendIds.find(dynamicBackendId2) != registeredBackendIds.end()));
    CHECK((registeredBackendIds.find(dynamicBackendId3) != registeredBackendIds.end()));

    for (size_t i = 0; i < dynamicBackends.size(); i++)
    {
        BackendId dynamicBackendId = dynamicBackends[i]->GetBackendId();

        auto dynamicBackendFactoryFunction = backendRegistry.GetFactory(dynamicBackendId);
        CHECK((dynamicBackendFactoryFunction != nullptr));

        IBackendInternalUniquePtr dynamicBackend = dynamicBackendFactoryFunction();
        CHECK((dynamicBackend != nullptr));
        CHECK((dynamicBackend->GetId() == dynamicBackendId));
    }
}

void RegisterMixedDynamicBackendsTestImpl()
{
    using namespace armnn;
    using namespace fs;

    // The test covers five directories:
    // <unit test path>/src/backends/backendsCommon/test/
    //                                                ├─ backendsTestPath5/   -> exists, contains files
    //                                                ├─ backendsTestPath6/   -> exists, contains files
    //                                                ├─ backendsTestPath7/   -> exists, but empty
    //                                                ├─ backendsTestPath8/   -> does not exist
    //                                                └─ backendsTestPath9/   -> exists, contains files
    //
    // The test sub-directory backendsTestPath5/ contains the following test files:
    //
    // Arm_TestValid2_backend.so   -> valid (basic backend name)
    // Arm_TestValid3_backend.so   -> valid (basic backend name)
    // Arm_TestInvalid8_backend.so -> not valid (invalid backend id)
    //
    // The test sub-directory backendsTestPath6/ contains the following test files:
    //
    // Arm_TestValid2_backend.so   -> valid (but duplicated from backendsTestPath5/)
    // Arm_TestValid4_backend.so   -> valid (it has a different filename,
    //                                       but it has the same backend id of Arm_TestValid2_backend.so
    //                                       and the same version)
    // Arm_TestValid5_backend.so   -> valid (basic backend name)
    // Arm_TestInvalid9_backend.so -> not valid (it has a different filename,
    //                                           but it has the same backend id of Arm_TestValid2_backend.so
    //                                           and a version incompatible with the Backend API)
    //
    // The test sub-directory backendsTestPath9/ contains the following test files:
    //
    // Arm_TestInvalid10_backend.so -> not valid (empty backend id)
    // Arm_TestInvalid11_backend.so -> not valid ("Unknown" backend id)

    std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
    std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
    std::string testDynamicBackendsSubDir7 = GetTestSubDirectory(g_TestDynamicBackendsSubDir7);
    std::string testDynamicBackendsSubDir8 = GetTestSubDirectory(g_TestDynamicBackendsSubDir8);
    std::string testDynamicBackendsSubDir9 = GetTestSubDirectory(g_TestDynamicBackendsSubDir9);
    CHECK(exists(testDynamicBackendsSubDir5));
    CHECK(exists(testDynamicBackendsSubDir6));
    CHECK(exists(testDynamicBackendsSubDir7));
    CHECK(!exists(testDynamicBackendsSubDir8));
    CHECK(exists(testDynamicBackendsSubDir9));

    std::string testValidBackend2FilePath    = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend2FileName);
    std::string testValidBackend3FilePath    = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend3FileName);
    std::string testValidBackend2DupFilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend2FileName);
    std::string testValidBackend4FilePath    = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend4FileName);
    std::string testValidBackend5FilePath    = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend5FileName);
    std::string testInvalidBackend8FilePath  = GetTestFilePath(testDynamicBackendsSubDir5,
                                                               g_TestInvalidBackend8FileName);
    std::string testInvalidBackend9FilePath  = GetTestFilePath(testDynamicBackendsSubDir6,
                                                               g_TestInvalidBackend9FileName);
    std::string testInvalidBackend10FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
                                                               g_TestInvalidBackend10FileName);
    std::string testInvalidBackend11FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
                                                               g_TestInvalidBackend11FileName);
    CHECK(exists(testValidBackend2FilePath));
    CHECK(exists(testValidBackend3FilePath));
    CHECK(exists(testValidBackend2DupFilePath));
    CHECK(exists(testValidBackend4FilePath));
    CHECK(exists(testValidBackend5FilePath));
    CHECK(exists(testInvalidBackend8FilePath));
    CHECK(exists(testInvalidBackend9FilePath));
    CHECK(exists(testInvalidBackend10FilePath));
    CHECK(exists(testInvalidBackend11FilePath));

    std::vector<std::string> sharedObjects
    {
        testValidBackend2FilePath,
        testValidBackend3FilePath,
        testValidBackend2DupFilePath,
        testValidBackend4FilePath,
        testValidBackend5FilePath,
        testInvalidBackend8FilePath,
        testInvalidBackend9FilePath,
        testInvalidBackend10FilePath,
        testInvalidBackend11FilePath,
        "InvalidSharedObject"
    };
    std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);

    CHECK(dynamicBackends.size() == 7);
    CHECK((dynamicBackends[0] != nullptr));
    CHECK((dynamicBackends[1] != nullptr));
    CHECK((dynamicBackends[2] != nullptr));
    CHECK((dynamicBackends[3] != nullptr));
    CHECK((dynamicBackends[4] != nullptr));
    CHECK((dynamicBackends[5] != nullptr));
    CHECK((dynamicBackends[6] != nullptr));

    BackendId dynamicBackendId1 = dynamicBackends[0]->GetBackendId();
    BackendId dynamicBackendId2 = dynamicBackends[1]->GetBackendId();
    BackendId dynamicBackendId3 = dynamicBackends[2]->GetBackendId();
    BackendId dynamicBackendId4 = dynamicBackends[3]->GetBackendId();
    BackendId dynamicBackendId5 = dynamicBackends[4]->GetBackendId();
    BackendId dynamicBackendId6 = dynamicBackends[5]->GetBackendId();
    BackendId dynamicBackendId7 = dynamicBackends[6]->GetBackendId();
    CHECK((dynamicBackendId1 == "TestValid2"));
    CHECK((dynamicBackendId2 == "TestValid3"));
    CHECK((dynamicBackendId3 == "TestValid2")); // From duplicate Arm_TestValid2_backend.so
    CHECK((dynamicBackendId4 == "TestValid2")); // From Arm_TestValid4_backend.so
    CHECK((dynamicBackendId5 == "TestValid5"));
    CHECK((dynamicBackendId6 == ""));
    CHECK((dynamicBackendId7 == "Unknown"));

    for (size_t i = 0; i < dynamicBackends.size(); i++)
    {
        BackendVersion dynamicBackendVersion = dynamicBackends[i]->GetBackendVersion();
        CHECK(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
    }

    // Dummy registry used for testing
    BackendRegistry backendRegistry;
    CHECK(backendRegistry.Size() == 0);

    std::vector<BackendId> expectedRegisteredbackendIds
    {
        "TestValid2",
        "TestValid3",
        "TestValid5"
    };

    BackendIdSet registeredBackendIds = TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry,
                                                                                                 dynamicBackends);
    CHECK(backendRegistry.Size() == expectedRegisteredbackendIds.size());
    CHECK(registeredBackendIds.size() == expectedRegisteredbackendIds.size());

    BackendIdSet backendIds = backendRegistry.GetBackendIds();
    CHECK(backendIds.size() == expectedRegisteredbackendIds.size());
    for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
    {
        CHECK((backendIds.find(expectedRegisteredbackendId) != backendIds.end()));
        CHECK((registeredBackendIds.find(expectedRegisteredbackendId) != registeredBackendIds.end()));

        auto dynamicBackendFactoryFunction = backendRegistry.GetFactory(expectedRegisteredbackendId);
        CHECK((dynamicBackendFactoryFunction != nullptr));

        IBackendInternalUniquePtr dynamicBackend = dynamicBackendFactoryFunction();
        CHECK((dynamicBackend != nullptr));
        CHECK((dynamicBackend->GetId() == expectedRegisteredbackendId));
    }
}
#endif

void RegisterMultipleInvalidDynamicBackendsTestImpl()
{
    using namespace armnn;
    using namespace fs;

    // Try to register many invalid dynamic backends

    // The test covers one directory:
    // <unit test path>/src/backends/backendsCommon/test/
    //                                                └─ backendsTestPath9/   -> exists, contains files
    //
    // The test sub-directory backendsTestPath9/ contains the following test files:
    //
    // Arm_TestInvalid10_backend.so -> not valid (invalid backend id)
    // Arm_TestInvalid11_backend.so -> not valid (invalid backend id)

    std::string testDynamicBackendsSubDir9 = GetTestSubDirectory(g_TestDynamicBackendsSubDir9);
    CHECK(exists(testDynamicBackendsSubDir9));

    std::string testInvalidBackend10FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
                                                               g_TestInvalidBackend10FileName);
    std::string testInvalidBackend11FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
                                                               g_TestInvalidBackend11FileName);
    CHECK(exists(testInvalidBackend10FilePath));
    CHECK(exists(testInvalidBackend11FilePath));

    std::vector<std::string> sharedObjects
    {
        testInvalidBackend10FilePath,
        testInvalidBackend11FilePath,
        "InvalidSharedObject"
    };
    std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);

    CHECK(dynamicBackends.size() == 2);
    CHECK((dynamicBackends[0] != nullptr));
    CHECK((dynamicBackends[1] != nullptr));

    BackendId dynamicBackendId1 = dynamicBackends[0]->GetBackendId();
    BackendId dynamicBackendId2 = dynamicBackends[1]->GetBackendId();
    CHECK((dynamicBackendId1 == ""));
    CHECK((dynamicBackendId2 == "Unknown"));

    for (size_t i = 0; i < dynamicBackends.size(); i++)
    {
        BackendVersion dynamicBackendVersion = dynamicBackends[i]->GetBackendVersion();
        CHECK(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
    }

    // Dummy registry used for testing
    BackendRegistry backendRegistry;
    CHECK(backendRegistry.Size() == 0);

    // Check that no dynamic backend got registered
    BackendIdSet registeredBackendIds = TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry,
                                                                                                 dynamicBackends);
    CHECK(backendRegistry.Size() == 0);
    CHECK(registeredBackendIds.empty());
}

#if !defined(ARMNN_DYNAMIC_BACKEND_ENABLED)

void RuntimeEmptyTestImpl()
{
    using namespace armnn;

    // Swapping the backend registry storage for testing
    TestBackendRegistry testBackendRegistry;

    const BackendRegistry& backendRegistry = BackendRegistryInstance();
    CHECK(backendRegistry.Size() == 0);

    IRuntime::CreationOptions creationOptions;
    IRuntimePtr runtime = IRuntime::Create(creationOptions);

    const DeviceSpec& deviceSpec = *PolymorphicDowncast<const DeviceSpec*>(&runtime->GetDeviceSpec());
    BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
    CHECK(supportedBackendIds.empty());

    CHECK(backendRegistry.Size() == 0);
}

#endif

void RuntimeDynamicBackendsTestImpl()
{
    using namespace armnn;
    using namespace fs;

    // Swapping the backend registry storage for testing
    TestBackendRegistry testBackendRegistry;

    // This directory contains valid and invalid backends
    std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
    CHECK(exists(testDynamicBackendsSubDir5));

    // Using the path override in CreationOptions to load some test dynamic backends
    IRuntime::CreationOptions creationOptions;
    creationOptions.m_DynamicBackendsPath = testDynamicBackendsSubDir5;
    IRuntimePtr runtime = IRuntime::Create(creationOptions);

    std::vector<BackendId> expectedRegisteredbackendIds
    {
        "TestValid2",
        "TestValid3"
    };

    const BackendRegistry& backendRegistry = BackendRegistryInstance();
    CHECK(backendRegistry.Size() == expectedRegisteredbackendIds.size());

    BackendIdSet backendIds = backendRegistry.GetBackendIds();
    for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
    {
        CHECK((backendIds.find(expectedRegisteredbackendId) != backendIds.end()));
    }

    const DeviceSpec& deviceSpec = *PolymorphicDowncast<const DeviceSpec*>(&runtime->GetDeviceSpec());
    BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
    CHECK(supportedBackendIds.size() == expectedRegisteredbackendIds.size());
    for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
    {
        CHECK((supportedBackendIds.find(expectedRegisteredbackendId) != supportedBackendIds.end()));
    }
}

void RuntimeDuplicateDynamicBackendsTestImpl()
{
    using namespace armnn;
    using namespace fs;

    // Swapping the backend registry storage for testing
    TestBackendRegistry testBackendRegistry;

    // This directory contains valid, invalid and duplicate backends
    std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
    CHECK(exists(testDynamicBackendsSubDir6));

    // Using the path override in CreationOptions to load some test dynamic backends
    IRuntime::CreationOptions creationOptions;
    creationOptions.m_DynamicBackendsPath = testDynamicBackendsSubDir6;
    IRuntimePtr runtime = IRuntime::Create(creationOptions);

    std::vector<BackendId> expectedRegisteredbackendIds
    {
        "TestValid2",
        "TestValid5"
    };

    const BackendRegistry& backendRegistry = BackendRegistryInstance();
    CHECK(backendRegistry.Size() == expectedRegisteredbackendIds.size());

    BackendIdSet backendIds = backendRegistry.GetBackendIds();
    for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
    {
        CHECK((backendIds.find(expectedRegisteredbackendId) != backendIds.end()));
    }

    const DeviceSpec& deviceSpec = *PolymorphicDowncast<const DeviceSpec*>(&runtime->GetDeviceSpec());
    BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
    CHECK(supportedBackendIds.size() == expectedRegisteredbackendIds.size());
    for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
    {
        CHECK((supportedBackendIds.find(expectedRegisteredbackendId) != supportedBackendIds.end()));
    }
}

void RuntimeInvalidDynamicBackendsTestImpl()
{
    using namespace armnn;
    using namespace fs;

    // Swapping the backend registry storage for testing
    TestBackendRegistry testBackendRegistry;

    // This directory contains only invalid backends
    std::string testDynamicBackendsSubDir9 = GetTestSubDirectory(g_TestDynamicBackendsSubDir9);
    CHECK(exists(testDynamicBackendsSubDir9));

    // Using the path override in CreationOptions to load some test dynamic backends
    IRuntime::CreationOptions creationOptions;
    creationOptions.m_DynamicBackendsPath = testDynamicBackendsSubDir9;
    IRuntimePtr runtime = IRuntime::Create(creationOptions);

    const BackendRegistry& backendRegistry = BackendRegistryInstance();
    CHECK(backendRegistry.Size() == 0);

    const DeviceSpec& deviceSpec = *PolymorphicDowncast<const DeviceSpec*>(&runtime->GetDeviceSpec());
    BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
    CHECK(supportedBackendIds.empty());
}

void RuntimeInvalidOverridePathTestImpl()
{
    using namespace armnn;

    // Swapping the backend registry storage for testing
    TestBackendRegistry testBackendRegistry;

    // Using the path override in CreationOptions to load some test dynamic backends
    IRuntime::CreationOptions creationOptions;
    creationOptions.m_DynamicBackendsPath = "InvalidPath";
    IRuntimePtr runtime = IRuntime::Create(creationOptions);

    const BackendRegistry& backendRegistry = BackendRegistryInstance();
    CHECK(backendRegistry.Size() == 0);

    const DeviceSpec& deviceSpec = *PolymorphicDowncast<const DeviceSpec*>(&runtime->GetDeviceSpec());
    BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
    CHECK(supportedBackendIds.empty());
}

#if defined(ARMNNREF_ENABLED)

// This test unit needs the reference backend, it's not available if the reference backend is not built

void CreateReferenceDynamicBackendTestImpl()
{
    using namespace armnn;
    using namespace fs;

    // Swapping the backend registry storage for testing
    TestBackendRegistry testBackendRegistry;

    // This directory contains the reference dynamic backend
    std::string dynamicBackendsBaseDir = GetDynamicBackendsBasePath();
    std::string referenceDynamicBackendSubDir = GetTestSubDirectory(dynamicBackendsBaseDir,
                                                                    g_ReferenceDynamicBackendSubDir);
    CHECK(exists(referenceDynamicBackendSubDir));

    // Check that the reference dynamic backend file exists
    std::string referenceBackendFilePath = GetTestFilePath(referenceDynamicBackendSubDir,
                                                           g_ReferenceBackendFileName);
    CHECK(exists(referenceBackendFilePath));

    // Using the path override in CreationOptions to load the reference dynamic backend
    IRuntime::CreationOptions creationOptions;
    creationOptions.m_DynamicBackendsPath = referenceDynamicBackendSubDir;
    IRuntimePtr runtime = IRuntime::Create(creationOptions);

    const BackendRegistry& backendRegistry = BackendRegistryInstance();
    CHECK(backendRegistry.Size() == 1);

    BackendIdSet backendIds = backendRegistry.GetBackendIds();
    CHECK((backendIds.find("CpuRef") != backendIds.end()));

    const DeviceSpec& deviceSpec = *PolymorphicDowncast<const DeviceSpec*>(&runtime->GetDeviceSpec());
    BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
    CHECK(supportedBackendIds.size() == 1);
    CHECK((supportedBackendIds.find("CpuRef") != supportedBackendIds.end()));

    // Get the factory function
    auto referenceDynamicBackendFactoryFunction = backendRegistry.GetFactory("CpuRef");
    CHECK((referenceDynamicBackendFactoryFunction != nullptr));

    // Use the factory function to create an instance of the reference backend
    IBackendInternalUniquePtr referenceDynamicBackend = referenceDynamicBackendFactoryFunction();
    CHECK((referenceDynamicBackend != nullptr));
    CHECK((referenceDynamicBackend->GetId() == "CpuRef"));

    // Test the backend instance by querying the layer support
    IBackendInternal::ILayerSupportSharedPtr referenceLayerSupport = referenceDynamicBackend->GetLayerSupport();
    CHECK((referenceLayerSupport != nullptr));

    TensorShape inputShape {  1, 16, 16, 16 };
    TensorShape outputShape{  1, 16, 16, 16 };
    TensorShape weightShape{ 16,  1,  1, 16 };
    TensorInfo inputInfo (inputShape,  DataType::Float32);
    TensorInfo outputInfo(outputShape, DataType::Float32);
    TensorInfo weightInfo(weightShape, DataType::Float32);
    Convolution2dDescriptor convolution2dDescriptor;
    bool referenceConvolution2dSupported =
            referenceLayerSupport->IsConvolution2dSupported(inputInfo,
                                                            outputInfo,
                                                            convolution2dDescriptor,
                                                            weightInfo,
                                                            EmptyOptional());
    CHECK(referenceConvolution2dSupported);

    // Test the backend instance by creating a workload
    IBackendInternal::IWorkloadFactoryPtr referenceWorkloadFactory = referenceDynamicBackend->CreateWorkloadFactory();
    CHECK((referenceWorkloadFactory != nullptr));

    // Create dummy settings for the workload
    Convolution2dQueueDescriptor convolution2dQueueDescriptor;
    WorkloadInfo workloadInfo
    {
        { inputInfo },
        { outputInfo }
    };
    convolution2dQueueDescriptor.m_Inputs.push_back(nullptr);
    auto weights = std::make_unique<ScopedTensorHandle>(weightInfo);
    convolution2dQueueDescriptor.m_Weight = weights.get();

    // Create a convolution workload with the dummy settings
    auto workload = referenceWorkloadFactory->CreateWorkload(LayerType::Convolution2d,
                                                             convolution2dQueueDescriptor,
                                                             workloadInfo);
    CHECK((workload != nullptr));
    CHECK(workload.get() == PolymorphicDowncast<RefConvolution2dWorkload*>(workload.get()));
}

#endif

#if defined(SAMPLE_DYNAMIC_BACKEND_ENABLED)

void CheckSampleDynamicBackendLoaded()
{
    using namespace armnn;
    // At this point we expect DYNAMIC_BACKEND_PATHS to include a path to where libArm_SampleDynamic_backend.so is.
    // If it hasn't been loaded there's no point continuing with the rest of the tests.
    BackendIdSet backendIds = BackendRegistryInstance().GetBackendIds();
    if (backendIds.find("SampleDynamic") == backendIds.end())
    {
        std::string message = "The SampleDynamic backend has not been loaded. This may be a build configuration error. "
                              "Ensure a DYNAMIC_BACKEND_PATHS was set at compile time to the location of "
                              "libArm_SampleDynamic_backend.so. "
                              "To disable this test recompile with: -DSAMPLE_DYNAMIC_BACKEND_ENABLED=0";
        FAIL(message);
    }
}

void CreateSampleDynamicBackendTestImpl()
{
    using namespace armnn;
    // Using the path override in CreationOptions to load the reference dynamic backend
    IRuntime::CreationOptions creationOptions;
    IRuntimePtr runtime = IRuntime::Create(creationOptions);
    const BackendRegistry& backendRegistry = BackendRegistryInstance();
    CHECK(backendRegistry.Size() >= 1);
    CheckSampleDynamicBackendLoaded();
    const DeviceSpec& deviceSpec = *PolymorphicDowncast<const DeviceSpec*>(&runtime->GetDeviceSpec());
    BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
    CHECK(supportedBackendIds.size()>= 1);
    CHECK((supportedBackendIds.find("SampleDynamic") != supportedBackendIds.end()));

    // Get the factory function
    auto sampleDynamicBackendFactoryFunction = backendRegistry.GetFactory("SampleDynamic");
    CHECK((sampleDynamicBackendFactoryFunction != nullptr));

    // Use the factory function to create an instance of the dynamic backend
    IBackendInternalUniquePtr sampleDynamicBackend = sampleDynamicBackendFactoryFunction();
    CHECK((sampleDynamicBackend != nullptr));
    CHECK((sampleDynamicBackend->GetId() == "SampleDynamic"));

    // Test the backend instance by querying the layer support
    IBackendInternal::ILayerSupportSharedPtr sampleLayerSupport = sampleDynamicBackend->GetLayerSupport();
    CHECK((sampleLayerSupport != nullptr));

    TensorShape inputShape {  1, 16, 16, 16 };
    TensorShape outputShape{  1, 16, 16, 16 };
    TensorShape weightShape{ 16,  1,  1, 16 };
    TensorInfo inputInfo (inputShape,  DataType::Float32);
    TensorInfo outputInfo(outputShape, DataType::Float32);
    TensorInfo weightInfo(weightShape, DataType::Float32);
    Convolution2dDescriptor convolution2dDescriptor;
    bool sampleConvolution2dSupported =
            sampleLayerSupport->IsConvolution2dSupported(inputInfo,
                                                         outputInfo,
                                                         convolution2dDescriptor,
                                                         weightInfo,
                                                         EmptyOptional());
    CHECK(!sampleConvolution2dSupported);

    // Test the backend instance by creating a workload
    IBackendInternal::IWorkloadFactoryPtr sampleWorkloadFactory = sampleDynamicBackend->CreateWorkloadFactory();
    CHECK((sampleWorkloadFactory != nullptr));

    // Create dummy settings for the workload
    AdditionQueueDescriptor additionQueueDescriptor;
    WorkloadInfo workloadInfo
    {
        { inputInfo, inputInfo },
        { outputInfo }
    };

    // Create a addition workload
    auto workload = sampleWorkloadFactory->CreateAddition(additionQueueDescriptor, workloadInfo);
    CHECK((workload != nullptr));
}

void SampleDynamicBackendEndToEndTestImpl()
{
    using namespace armnn;
    // Create runtime in which test will run
    IRuntime::CreationOptions options;
    IRuntimePtr runtime(IRuntime::Create(options));
    CheckSampleDynamicBackendLoaded();
    // Builds up the structure of the network.
    INetworkPtr net(INetwork::Create());

    IConnectableLayer* input0 = net->AddInputLayer(0);
    IConnectableLayer* input1 = net->AddInputLayer(1);
    IConnectableLayer* add = net->AddAdditionLayer();
    IConnectableLayer* output = net->AddOutputLayer(0);

    input0->GetOutputSlot(0).Connect(add->GetInputSlot(0));
    input1->GetOutputSlot(0).Connect(add->GetInputSlot(1));
    add->GetOutputSlot(0).Connect(output->GetInputSlot(0));

    TensorInfo tensorInfo(TensorShape({2, 1}), DataType::Float32);
    input0->GetOutputSlot(0).SetTensorInfo(tensorInfo);
    input1->GetOutputSlot(0).SetTensorInfo(tensorInfo);
    add->GetOutputSlot(0).SetTensorInfo(tensorInfo);

    // optimize the network
    IOptimizedNetworkPtr optNet = Optimize(*net, {"SampleDynamic"}, runtime->GetDeviceSpec());

    // Loads it into the runtime.
    NetworkId netId;
    runtime->LoadNetwork(netId, std::move(optNet));

    std::vector<float> input0Data{ 5.0f, 3.0f };
    std::vector<float> input1Data{ 10.0f, 8.0f };
    std::vector<float> expectedOutputData{ 15.0f, 11.0f };
    std::vector<float> outputData(2);

    TensorInfo inputTensorInfo = runtime->GetInputTensorInfo(netId, 0);
    inputTensorInfo.SetConstant(true);
    InputTensors inputTensors
        {
            {0,armnn::ConstTensor(inputTensorInfo, input0Data.data())},
            {1,armnn::ConstTensor(inputTensorInfo, input1Data.data())}
        };
    OutputTensors outputTensors
        {
            {0,armnn::Tensor(runtime->GetOutputTensorInfo(netId, 0), outputData.data())}
        };

    // Does the inference.
    runtime->EnqueueWorkload(netId, inputTensors, outputTensors);

    // Checks the results.
    CHECK(outputData == expectedOutputData);
}
#endif
