refactor: cleanup around IGC library name mocking logic

This patchset improves mocking of IGC library name and adds
safety mechanism to ensure that global IGC library name gets
restored before test finishes.

Related-To: NEO-12747

Signed-off-by: Chodor, Jaroslaw <jaroslaw.chodor@intel.com>
This commit is contained in:
Chodor, Jaroslaw
2024-10-23 19:55:38 +00:00
committed by Compute-Runtime-Automation
parent 428e2132b0
commit 22fe217567
11 changed files with 72 additions and 61 deletions

View File

@@ -417,7 +417,7 @@ if(NOT DEFINED AOT_CONFIG_HEADERS_DIR)
endif()
# Intel Graphics Compiler detection
include(cmake/find_igc.cmake)
include(cmake${BRANCH_DIR_SUFFIX}/find_igc.cmake)
# GmmLib detection
include(cmake/find_gmmlib.cmake)

View File

@@ -26,6 +26,8 @@
#include "shared/test/common/helpers/raii_product_helper.h"
#include "shared/test/common/libult/ult_command_stream_receiver.h"
#include "shared/test/common/mocks/mock_command_stream_receiver.h"
#include "shared/test/common/mocks/mock_compiler_product_helper.h"
#include "shared/test/common/mocks/mock_compilers.h"
#include "shared/test/common/mocks/mock_device.h"
#include "shared/test/common/mocks/mock_driver_info.h"
#include "shared/test/common/mocks/mock_memory_manager.h"
@@ -321,16 +323,12 @@ TEST(L0DeviceTest, givenDeviceWithoutIGCCompilerLibraryThenInvalidDependencyIsNo
auto hwInfo = *NEO::defaultHwInfo;
auto neoDevice = std::unique_ptr<NEO::Device>(NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(&hwInfo, 0));
auto oldIgcDllName = Os::igcDllName;
Os::igcDllName = "_invalidIGC";
auto igcNameGuard = NEO::pushIgcDllName("_invalidIGC");
auto mockDevice = reinterpret_cast<NEO::MockDevice *>(neoDevice.get());
mockDevice->setPreemptionMode(NEO::PreemptionMode::Initial);
auto device = std::unique_ptr<L0::Device>(Device::create(driverHandle.get(), neoDevice.release(), false, &returnValue));
ASSERT_NE(nullptr, device);
EXPECT_EQ(returnValue, ZE_RESULT_SUCCESS);
Os::igcDllName = oldIgcDllName;
}
TEST(L0DeviceTest, givenDeviceWithoutAnyCompilerLibraryThenInvalidDependencyIsNotReturned) {
@@ -342,18 +340,15 @@ TEST(L0DeviceTest, givenDeviceWithoutAnyCompilerLibraryThenInvalidDependencyIsNo
auto neoDevice = std::unique_ptr<NEO::Device>(NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(&hwInfo, 0));
auto oldFclDllName = Os::frontEndDllName;
auto oldIgcDllName = Os::igcDllName;
Os::frontEndDllName = "_invalidFCL";
Os::igcDllName = "_invalidIGC";
auto igcNameGuard = NEO::pushIgcDllName("_invalidIGC");
auto mockDevice = reinterpret_cast<NEO::MockDevice *>(neoDevice.get());
mockDevice->setPreemptionMode(NEO::PreemptionMode::Initial);
auto device = std::unique_ptr<L0::Device>(Device::create(driverHandle.get(), neoDevice.release(), false, &returnValue));
Os::frontEndDllName = oldFclDllName;
ASSERT_NE(nullptr, device);
EXPECT_EQ(returnValue, ZE_RESULT_SUCCESS);
Os::igcDllName = oldIgcDllName;
Os::frontEndDllName = oldFclDllName;
}
TEST(L0DeviceTest, givenDeviceWithoutIGCCompilerLibraryAndMidThreadPreemptionThenInvalidDependencyIsReturned) {
@@ -364,8 +359,7 @@ TEST(L0DeviceTest, givenDeviceWithoutIGCCompilerLibraryAndMidThreadPreemptionThe
std::unique_ptr<DriverHandleImp> driverHandle(new DriverHandleImp);
auto hwInfo = *NEO::defaultHwInfo;
auto oldIgcDllName = Os::igcDllName;
Os::igcDllName = "_invalidIGC";
auto igcNameGuard = NEO::pushIgcDllName("_invalidIGC");
auto neoDevice = std::unique_ptr<NEO::Device>(NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(&hwInfo, 0));
auto mockDevice = reinterpret_cast<NEO::MockDevice *>(neoDevice.get());
mockDevice->setPreemptionMode(NEO::PreemptionMode::MidThread);
@@ -373,8 +367,6 @@ TEST(L0DeviceTest, givenDeviceWithoutIGCCompilerLibraryAndMidThreadPreemptionThe
auto device = std::unique_ptr<L0::Device>(Device::create(driverHandle.get(), neoDevice.release(), false, &returnValue));
ASSERT_NE(nullptr, device);
EXPECT_EQ(returnValue, ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE);
Os::igcDllName = oldIgcDllName;
}
TEST(L0DeviceTest, givenDeviceWithoutAnyCompilerLibraryAndMidThreadPreemptionThenInvalidDependencyIsReturned) {
@@ -386,9 +378,8 @@ TEST(L0DeviceTest, givenDeviceWithoutAnyCompilerLibraryAndMidThreadPreemptionThe
auto hwInfo = *NEO::defaultHwInfo;
auto oldFclDllName = Os::frontEndDllName;
auto oldIgcDllName = Os::igcDllName;
Os::frontEndDllName = "_invalidFCL";
Os::igcDllName = "_invalidIGC";
auto igcNameGuard = NEO::pushIgcDllName("_invalidIGC");
auto neoDevice = std::unique_ptr<NEO::Device>(NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(&hwInfo, 0));
auto mockDevice = reinterpret_cast<NEO::MockDevice *>(neoDevice.get());
mockDevice->setPreemptionMode(NEO::PreemptionMode::MidThread);
@@ -397,7 +388,6 @@ TEST(L0DeviceTest, givenDeviceWithoutAnyCompilerLibraryAndMidThreadPreemptionThe
ASSERT_NE(nullptr, device);
EXPECT_EQ(returnValue, ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE);
Os::igcDllName = oldIgcDllName;
Os::frontEndDllName = oldFclDllName;
}

View File

@@ -905,13 +905,11 @@ TEST(DriverTest, givenInvalidCompilerEnvironmentThenDependencyUnavailableErrorIs
ze_result_t result = ZE_RESULT_ERROR_UNINITIALIZED;
DriverImp driverImp;
auto oldFclDllName = Os::frontEndDllName;
auto oldIgcDllName = Os::igcDllName;
Os::frontEndDllName = "_invalidFCL";
Os::igcDllName = "_invalidIGC";
auto igcNameGuard = NEO::pushIgcDllName("_invalidIGC");
driverImp.initialize(&result);
EXPECT_EQ(result, ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE);
Os::igcDllName = oldIgcDllName;
Os::frontEndDllName = oldFclDllName;
ASSERT_EQ(nullptr, L0::globalDriver);
@@ -929,13 +927,11 @@ TEST(DriverTest, givenInvalidCompilerEnvironmentAndEnableProgramDebuggingWithVal
ze_result_t result = ZE_RESULT_ERROR_UNINITIALIZED;
DriverImp driverImp;
auto oldFclDllName = Os::frontEndDllName;
auto oldIgcDllName = Os::igcDllName;
Os::frontEndDllName = "_invalidFCL";
Os::igcDllName = "_invalidIGC";
auto igcNameGuard = NEO::pushIgcDllName("_invalidIGC");
driverImp.initialize(&result);
EXPECT_EQ(result, ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE);
Os::igcDllName = oldIgcDllName;
Os::frontEndDllName = oldFclDllName;
ASSERT_EQ(nullptr, L0::globalDriver);

View File

@@ -27,6 +27,7 @@
#include "shared/test/common/helpers/mock_file_io.h"
#include "shared/test/common/libult/ult_command_stream_receiver.h"
#include "shared/test/common/mocks/mock_compiler_product_helper.h"
#include "shared/test/common/mocks/mock_compilers.h"
#include "shared/test/common/mocks/mock_device.h"
#include "shared/test/common/mocks/mock_elf.h"
#include "shared/test/common/mocks/mock_graphics_allocation.h"
@@ -3471,9 +3472,8 @@ HWTEST_F(ModuleTranslationUnitTest, WithNoCompilerWhenCallingBuildFromSpirvThenF
auto &rootDeviceEnvironment = this->neoDevice->executionEnvironment->rootDeviceEnvironments[this->neoDevice->getRootDeviceIndex()];
rootDeviceEnvironment->compilerInterface.reset(nullptr);
auto oldFclDllName = Os::frontEndDllName;
auto oldIgcDllName = Os::igcDllName;
Os::frontEndDllName = "_invalidFCL";
Os::igcDllName = "_invalidIGC";
auto igcNameGuard = NEO::pushIgcDllName("_invalidIGC");
L0::ModuleTranslationUnit moduleTu(this->device);
moduleTu.options = "abcd";
@@ -3481,7 +3481,6 @@ HWTEST_F(ModuleTranslationUnitTest, WithNoCompilerWhenCallingBuildFromSpirvThenF
ze_result_t result = ZE_RESULT_SUCCESS;
result = moduleTu.buildFromSpirV("", 0U, nullptr, "", nullptr);
EXPECT_EQ(result, ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE);
Os::igcDllName = oldIgcDllName;
Os::frontEndDllName = oldFclDllName;
}
@@ -3489,9 +3488,8 @@ HWTEST_F(ModuleTranslationUnitTest, WithNoCompilerWhenCallingCompileGenBinaryThe
auto &rootDeviceEnvironment = this->neoDevice->executionEnvironment->rootDeviceEnvironments[this->neoDevice->getRootDeviceIndex()];
rootDeviceEnvironment->compilerInterface.reset(nullptr);
auto oldFclDllName = Os::frontEndDllName;
auto oldIgcDllName = Os::igcDllName;
Os::frontEndDllName = "_invalidFCL";
Os::igcDllName = "_invalidIGC";
auto igcNameGuard = NEO::pushIgcDllName("_invalidIGC");
L0::ModuleTranslationUnit moduleTu(this->device);
moduleTu.options = "abcd";
@@ -3500,7 +3498,6 @@ HWTEST_F(ModuleTranslationUnitTest, WithNoCompilerWhenCallingCompileGenBinaryThe
TranslationInput inputArgs = {IGC::CodeType::spirV, IGC::CodeType::oclGenBin};
result = moduleTu.compileGenBinary(inputArgs, false);
EXPECT_EQ(result, ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE);
Os::igcDllName = oldIgcDllName;
Os::frontEndDllName = oldFclDllName;
}
@@ -3508,9 +3505,8 @@ HWTEST_F(ModuleTranslationUnitTest, WithNoCompilerWhenCallingStaticLinkSpirVThen
auto &rootDeviceEnvironment = this->neoDevice->executionEnvironment->rootDeviceEnvironments[this->neoDevice->getRootDeviceIndex()];
rootDeviceEnvironment->compilerInterface.reset(nullptr);
auto oldFclDllName = Os::frontEndDllName;
auto oldIgcDllName = Os::igcDllName;
Os::frontEndDllName = "_invalidFCL";
Os::igcDllName = "_invalidIGC";
auto igcNameGuard = NEO::pushIgcDllName("_invalidIGC");
L0::ModuleTranslationUnit moduleTu(this->device);
moduleTu.options = "abcd";
@@ -3521,7 +3517,6 @@ HWTEST_F(ModuleTranslationUnitTest, WithNoCompilerWhenCallingStaticLinkSpirVThen
std::vector<const ze_module_constants_t *> specConstants;
result = moduleTu.staticLinkSpirV(inputSpirVs, inputModuleSizes, "", "", specConstants);
EXPECT_EQ(result, ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE);
Os::igcDllName = oldIgcDllName;
Os::frontEndDllName = oldFclDllName;
}

View File

@@ -91,6 +91,7 @@ set(IGDRCL_SRCS_offline_compiler_tests
${NEO_SHARED_DIRECTORY}/memory_manager/deferred_deleter.cpp
${NEO_SHARED_DIRECTORY}/memory_manager/deferred_deleter.h
${NEO_SHARED_TEST_DIRECTORY}/common/mocks/mock_compilers.cpp
${NEO_SHARED_TEST_DIRECTORY}/common/mocks${BRANCH_DIR_SUFFIX}/mock_igc_path.cpp
${NEO_SHARED_TEST_DIRECTORY}/common/mocks/mock_os_library.cpp
${NEO_SHARED_TEST_DIRECTORY}/common/mocks/mock_os_library.h
${NEO_SHARED_TEST_DIRECTORY}/common/mocks/mock_compilers.h

View File

@@ -11,6 +11,7 @@
#include "shared/source/debug_settings/debug_settings_manager.h"
#include "shared/source/os_interface/os_inc_base.h"
#include "shared/test/common/helpers/debug_manager_state_restore.h"
#include "shared/test/common/mocks/mock_compilers.h"
#include "mock/mock_ocloc_igc_facade.h"
@@ -23,6 +24,8 @@ TEST_F(OclocIgcFacadeTest, GivenMissingIgcLibraryWhenPreparingIgcThenFailureIsRe
mockIgcFacade.shouldFailLoadingOfIgcLib = true;
::testing::internal::CaptureStdout();
std::string libName = "invalidigc.so";
auto igcNameGuard = NEO::pushIgcDllName(libName.c_str());
const auto igcPreparationResult{mockIgcFacade.initialize(hwInfo)};
const auto output{::testing::internal::GetCapturedStdout()};
@@ -30,7 +33,7 @@ TEST_F(OclocIgcFacadeTest, GivenMissingIgcLibraryWhenPreparingIgcThenFailureIsRe
EXPECT_FALSE(mockIgcFacade.isInitialized());
std::stringstream expectedErrorMessage;
expectedErrorMessage << "Error! Loading of IGC library has failed! Filename: " << Os::igcDllName << "\n";
expectedErrorMessage << "Error! Loading of IGC library has failed! Filename: " << libName << "\n";
EXPECT_EQ(expectedErrorMessage.str(), output);
}

View File

@@ -1673,6 +1673,8 @@ TEST_F(OfflineCompilerTests, givenValidArgumentsAndIgcInitFailureWhenInitIsPerfo
gEnvironment->devicePrefix.c_str()};
MockOfflineCompiler mockOfflineCompiler{};
std::string libName = "invalidigc.so";
auto igcNameGuard = NEO::pushIgcDllName(libName.c_str());
mockOfflineCompiler.mockIgcFacade->shouldFailLoadingOfIgcLib = true;
testing::internal::CaptureStdout();
const auto initResult = mockOfflineCompiler.initialize(argv.size(), argv);
@@ -1684,7 +1686,7 @@ TEST_F(OfflineCompilerTests, givenValidArgumentsAndIgcInitFailureWhenInitIsPerfo
output = testing::internal::GetCapturedStdout();
std::stringstream expectedErrorMessage;
expectedErrorMessage << "Error! Loading of IGC library has failed! Filename: " << Os::igcDllName << "\n"
expectedErrorMessage << "Error! Loading of IGC library has failed! Filename: " << libName << "\n"
<< "Error! IGC initialization failure. Error code = -6\n";
EXPECT_EQ(OCLOC_OUT_OF_HOST_MEMORY, buildResult);
@@ -1773,28 +1775,6 @@ TEST_F(OfflineCompilerTests, givenExcludeIrArgumentWhenGeneratingElfBinaryFromPa
EXPECT_FALSE(hasIR);
}
TEST_F(OfflineCompilerTests, givenLackOfExcludeIrArgumentWhenCompilingKernelThenIrShouldBeIncluded) {
std::vector<std::string> argv = {
"ocloc",
"-file",
clFiles + "copybuffer.cl",
"-device",
gEnvironment->devicePrefix.c_str()};
MockOfflineCompiler mockOfflineCompiler{};
mockOfflineCompiler.initialize(argv.size(), argv);
const auto buildResult{mockOfflineCompiler.build()};
ASSERT_EQ(OCLOC_SUCCESS, buildResult);
std::string errorReason{};
std::string warning{};
auto hasIR = containsAnyIRSection(mockOfflineCompiler.elfBinary, errorReason, warning);
ASSERT_TRUE(errorReason.empty());
ASSERT_TRUE(warning.empty());
EXPECT_TRUE(hasIR);
}
TEST_F(OfflineCompilerTests, givenZeroSizeInputFileWhenInitializationIsPerformedThenInvalidFileIsReturned) {
std::vector<std::string> argv = {
"ocloc",

View File

@@ -65,6 +65,7 @@ set(NEO_CORE_tests_mocks
${CMAKE_CURRENT_SOURCE_DIR}/mock_gmm_resource_info.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_graphics_allocation.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_host_ptr_manager.h
${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}/mock_igc_path.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mock_gfx_core_helper.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_kmd_notify_helper.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_product_helper.cpp

View File

@@ -70,9 +70,8 @@ void MockCompilerEnableGuard::Enable() {
if (enabled == false) {
// load mock from self (don't load dynamic libraries)
this->oldFclDllName = Os::frontEndDllName;
this->oldIgcDllName = Os::igcDllName;
Os::frontEndDllName = "";
Os::igcDllName = "";
igcNameGuard = pushIgcDllName("");
MockCIFMain::setGlobalCreatorFunc<NEO::MockIgcOclDeviceCtx>(NEO::MockIgcOclDeviceCtx::Create);
MockCIFMain::setGlobalCreatorFunc<NEO::MockFclOclDeviceCtx>(NEO::MockFclOclDeviceCtx::Create);
if (fclDebugVars == nullptr) {
@@ -89,7 +88,7 @@ void MockCompilerEnableGuard::Enable() {
void MockCompilerEnableGuard::Disable() {
if (enabled) {
Os::frontEndDllName = this->oldFclDllName;
Os::igcDllName = this->oldIgcDllName;
igcNameGuard.reset();
MockCIFMain::removeGlobalCreatorFunc<NEO::MockIgcOclDeviceCtx>();
MockCIFMain::removeGlobalCreatorFunc<NEO::MockFclOclDeviceCtx>();

View File

@@ -19,6 +19,11 @@
namespace NEO {
struct PopIgcDllNameGuard {
~PopIgcDllNameGuard();
};
[[nodiscard]] std::unique_ptr<PopIgcDllNameGuard> pushIgcDllName(const char *name);
struct MockCompilerDebugVars {
enum class SipAddressingType {
unknown,
@@ -61,9 +66,9 @@ struct MockCompilerEnableGuard {
void Disable(); // NOLINT(readability-identifier-naming)
const char *oldFclDllName;
const char *oldIgcDllName;
bool enabled = false;
std::unique_ptr<PopIgcDllNameGuard> igcNameGuard;
};
void setFclDebugVars(MockCompilerDebugVars &dbgv);

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2024 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/utilities/stackvec.h"
#include "shared/test/common/mocks/mock_compilers.h"
#include <memory>
namespace Os {
extern const char *igcDllName;
} // namespace Os
namespace NEO {
StackVec<const char *, 32> prevIgcDllName;
bool popIgcDllName() {
if (prevIgcDllName.empty()) {
return false;
}
Os::igcDllName = *prevIgcDllName.rbegin();
prevIgcDllName.pop_back();
return true;
}
PopIgcDllNameGuard::~PopIgcDllNameGuard() {
popIgcDllName();
}
[[nodiscard]] std::unique_ptr<PopIgcDllNameGuard> pushIgcDllName(const char *name) {
prevIgcDllName.push_back(Os::igcDllName);
Os::igcDllName = name;
return std::make_unique<PopIgcDllNameGuard>();
}
} // namespace NEO