mock dlopen in tests to block unwanted interactions

- explicitly specify files allowed to dlopen()
- use underscore to prefix fake library name that we want dlopen to
return nullptr


Signed-off-by: Artur Harasimiuk <artur.harasimiuk@intel.com>
This commit is contained in:
Artur Harasimiuk
2021-11-18 22:25:02 +00:00
committed by Compute-Runtime-Automation
parent 2e68f0abbd
commit 7eb5b6aa42
8 changed files with 59 additions and 16 deletions

View File

@ -187,7 +187,7 @@ TEST(L0DeviceTest, givenDeviceWithoutFCLCompilerLibraryThenInvalidDependencyRetu
auto neoDevice = std::unique_ptr<NEO::Device>(NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(&hwInfo, 0)); auto neoDevice = std::unique_ptr<NEO::Device>(NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(&hwInfo, 0));
auto oldFclDllName = Os::frontEndDllName; auto oldFclDllName = Os::frontEndDllName;
Os::frontEndDllName = "invalidFCL"; Os::frontEndDllName = "_invalidFCL";
auto device = std::unique_ptr<L0::Device>(Device::create(driverHandle.get(), neoDevice.release(), false, &returnValue)); auto device = std::unique_ptr<L0::Device>(Device::create(driverHandle.get(), neoDevice.release(), false, &returnValue));
ASSERT_NE(nullptr, device); ASSERT_NE(nullptr, device);
@ -205,7 +205,7 @@ TEST(L0DeviceTest, givenDeviceWithoutIGCCompilerLibraryThenInvalidDependencyRetu
auto neoDevice = std::unique_ptr<NEO::Device>(NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(&hwInfo, 0)); auto neoDevice = std::unique_ptr<NEO::Device>(NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(&hwInfo, 0));
auto oldIgcDllName = Os::igcDllName; auto oldIgcDllName = Os::igcDllName;
Os::igcDllName = "invalidIGC"; Os::igcDllName = "_invalidIGC";
auto device = std::unique_ptr<L0::Device>(Device::create(driverHandle.get(), neoDevice.release(), false, &returnValue)); auto device = std::unique_ptr<L0::Device>(Device::create(driverHandle.get(), neoDevice.release(), false, &returnValue));
ASSERT_NE(nullptr, device); ASSERT_NE(nullptr, device);
@ -224,8 +224,8 @@ TEST(L0DeviceTest, givenDeviceWithoutAnyCompilerLibraryThenInvalidDependencyRetu
auto oldFclDllName = Os::frontEndDllName; auto oldFclDllName = Os::frontEndDllName;
auto oldIgcDllName = Os::igcDllName; auto oldIgcDllName = Os::igcDllName;
Os::frontEndDllName = "invalidFCL"; Os::frontEndDllName = "_invalidFCL";
Os::igcDllName = "invalidIGC"; Os::igcDllName = "_invalidIGC";
auto device = std::unique_ptr<L0::Device>(Device::create(driverHandle.get(), neoDevice.release(), false, &returnValue)); auto device = std::unique_ptr<L0::Device>(Device::create(driverHandle.get(), neoDevice.release(), false, &returnValue));
ASSERT_NE(nullptr, device); ASSERT_NE(nullptr, device);

View File

@ -382,8 +382,8 @@ TEST(DriverTest, givenInvalidCompilerEnvironmentThenDependencyUnavailableErrorIs
DriverImp driverImp; DriverImp driverImp;
auto oldFclDllName = Os::frontEndDllName; auto oldFclDllName = Os::frontEndDllName;
auto oldIgcDllName = Os::igcDllName; auto oldIgcDllName = Os::igcDllName;
Os::frontEndDllName = "invalidFCL"; Os::frontEndDllName = "_invalidFCL";
Os::igcDllName = "invalidIGC"; Os::igcDllName = "_invalidIGC";
driverImp.initialize(&result); driverImp.initialize(&result);
EXPECT_EQ(result, ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE); EXPECT_EQ(result, ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE);

View File

@ -34,7 +34,7 @@ TEST(OsLibraryTest, GivenDisableDeepBindFlagWhenOpeningLibraryThenRtldDeepBindFl
VariableBackup<bool> dlOpenCalledBackup{&NEO::SysCalls::dlOpenCalled, false}; VariableBackup<bool> dlOpenCalledBackup{&NEO::SysCalls::dlOpenCalled, false};
DebugManager.flags.DisableDeepBind.set(1); DebugManager.flags.DisableDeepBind.set(1);
auto lib = std::make_unique<Linux::OsLibrary>("abc", nullptr); auto lib = std::make_unique<Linux::OsLibrary>("_abc.so", nullptr);
EXPECT_TRUE(NEO::SysCalls::dlOpenCalled); EXPECT_TRUE(NEO::SysCalls::dlOpenCalled);
EXPECT_EQ(0, NEO::SysCalls::dlOpenFlags & RTLD_DEEPBIND); EXPECT_EQ(0, NEO::SysCalls::dlOpenFlags & RTLD_DEEPBIND);
} }
@ -43,7 +43,7 @@ TEST(OsLibraryTest, GivenInvalidLibraryWhenOpeningLibraryThenDlopenErrorIsReturn
VariableBackup<bool> dlOpenCalledBackup{&NEO::SysCalls::dlOpenCalled, false}; VariableBackup<bool> dlOpenCalledBackup{&NEO::SysCalls::dlOpenCalled, false};
std::string errorValue; std::string errorValue;
auto lib = std::make_unique<Linux::OsLibrary>("abc", &errorValue); auto lib = std::make_unique<Linux::OsLibrary>("_abc.so", &errorValue);
EXPECT_FALSE(errorValue.empty()); EXPECT_FALSE(errorValue.empty());
EXPECT_TRUE(NEO::SysCalls::dlOpenCalled); EXPECT_TRUE(NEO::SysCalls::dlOpenCalled);
} }

View File

@ -20,8 +20,6 @@
#include <memory> #include <memory>
namespace Os { namespace Os {
extern const char *frontEndDllName;
extern const char *igcDllName;
extern const char *testDllName; extern const char *testDllName;
} // namespace Os } // namespace Os
const std::string fakeLibName = "_fake_library_name_"; const std::string fakeLibName = "_fake_library_name_";

View File

@ -87,6 +87,7 @@ if(WIN32)
) )
else() else()
list(APPEND NEO_CORE_tests_mocks list(APPEND NEO_CORE_tests_mocks
${CMAKE_CURRENT_SOURCE_DIR}/linux/mock_dlopen.cpp
${CMAKE_CURRENT_SOURCE_DIR}/linux/mock_drm_allocation.h ${CMAKE_CURRENT_SOURCE_DIR}/linux/mock_drm_allocation.h
${CMAKE_CURRENT_SOURCE_DIR}/linux/mock_drm_command_stream_receiver.h ${CMAKE_CURRENT_SOURCE_DIR}/linux/mock_drm_command_stream_receiver.h
${CMAKE_CURRENT_SOURCE_DIR}/linux/mock_drm_memory_manager.h ${CMAKE_CURRENT_SOURCE_DIR}/linux/mock_drm_memory_manager.h

View File

@ -0,0 +1,47 @@
/*
* Copyright (C) 2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include <cstdio>
#include <cstring>
#include <dlfcn.h>
void *(*dlopenFunc)(const char *filename, int flags) = nullptr;
char *(*dlerrorFunc)() = nullptr;
static char dlerrorString[][16] = {"denied", "fake"};
static int dlopenError = -1;
void *dlopen(const char *filename, int flags) {
if (dlerrorFunc == nullptr) {
dlerrorFunc = reinterpret_cast<decltype(dlerrorFunc)>(dlsym(RTLD_NEXT, "dlerror"));
}
if (dlopenFunc == nullptr) {
dlopenFunc = reinterpret_cast<decltype(dlopenFunc)>(dlsym(RTLD_NEXT, "dlopen"));
}
dlopenError = -1;
if (filename == nullptr ||
strcmp(filename, "libtest_dynamic_lib.so") == 0) {
return dlopenFunc(filename, flags);
}
if (filename[0] == '_') {
dlopenError = 1;
return nullptr;
}
dlopenError = 0;
return nullptr;
}
char *dlerror() {
if (dlerrorFunc == nullptr) {
dlerrorFunc = reinterpret_cast<decltype(dlerrorFunc)>(dlsym(RTLD_NEXT, "dlerror"));
}
if (dlopenError >= 0 && dlopenError < 2) {
return dlerrorString[dlopenError];
}
return dlerrorFunc();
}

View File

@ -16,13 +16,10 @@ namespace Os {
// the runtime unit tests // the runtime unit tests
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#if defined(__linux__) #if defined(__linux__)
const char *frontEndDllName = "libmock_igdfcl.so"; const char *frontEndDllName = "_invalidFCL";
const char *igcDllName = "libmock_igc.so"; const char *igcDllName = "_invalidIGC";
const char *libvaDllName = nullptr; const char *libvaDllName = nullptr;
const char *testDllName = "libtest_dynamic_lib.so"; const char *testDllName = "libtest_dynamic_lib.so";
const char *gmmDllName = "libmock_gmm.so";
const char *gmmInitFuncName = "initMockGmm";
const char *gmmDestroyFuncName = "destroyMockGmm";
const char *metricsLibraryDllName = ""; const char *metricsLibraryDllName = "";
const char *gdiDllName = ""; const char *gdiDllName = "";
const char *dxcoreDllName = ""; const char *dxcoreDllName = "";

View File

@ -633,7 +633,7 @@ TEST(LoadCompilerTest, whenCouldNotLoadLibraryThenReturnFalseAndNullOutputs) {
MockCompilerEnableGuard mock; MockCompilerEnableGuard mock;
std::unique_ptr<NEO::OsLibrary> retLib; std::unique_ptr<NEO::OsLibrary> retLib;
CIF::RAII::UPtr_t<CIF::CIFMain> retMain; CIF::RAII::UPtr_t<CIF::CIFMain> retMain;
bool retVal = loadCompiler<IGC::IgcOclDeviceCtx>("falseName.notRealLib", retLib, retMain); bool retVal = loadCompiler<IGC::IgcOclDeviceCtx>("_falseName.notRealLib", retLib, retMain);
EXPECT_FALSE(retVal); EXPECT_FALSE(retVal);
EXPECT_EQ(nullptr, retLib.get()); EXPECT_EQ(nullptr, retLib.get());
EXPECT_EQ(nullptr, retMain.get()); EXPECT_EQ(nullptr, retMain.get());