1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
|
/*
* Copyright (C) 2018-2024 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/os_interface/windows/os_library_win.h"
#include "shared/test/common/helpers/variable_backup.h"
#include "shared/test/common/test_macros/hw_test.h"
#include "gtest/gtest.h"
#include <memory>
namespace Os {
extern const char *testDllName;
}
using namespace NEO;
class OsLibraryBackup : public Windows::OsLibrary {
using Type = decltype(Windows::OsLibrary::loadLibraryExA);
using BackupType = VariableBackup<Type>;
using ModuleNameType = decltype(Windows::OsLibrary::getModuleFileNameA);
using ModuleNameBackupType = VariableBackup<ModuleNameType>;
using SystemDirectoryType = decltype(Windows::OsLibrary::getSystemDirectoryA);
using SystemDirectoryBackupType = VariableBackup<SystemDirectoryType>;
struct Backup {
std::unique_ptr<BackupType> bkp1 = nullptr;
std::unique_ptr<ModuleNameBackupType> bkp2 = nullptr;
std::unique_ptr<SystemDirectoryBackupType> bkp3 = nullptr;
};
public:
static std::unique_ptr<Backup> backup(Type newValue, ModuleNameType newModuleName, SystemDirectoryType newSystemDirectoryName) {
std::unique_ptr<Backup> bkp(new Backup());
bkp->bkp1.reset(new BackupType(&OsLibrary::loadLibraryExA, newValue));
bkp->bkp2.reset(new ModuleNameBackupType(&OsLibrary::getModuleFileNameA, newModuleName));
bkp->bkp3.reset(new SystemDirectoryBackupType(&OsLibrary::getSystemDirectoryA, newSystemDirectoryName));
return bkp;
};
};
bool mockWillFailInNonSystem32 = true;
void trimFileName(char *buff, size_t length) {
for (size_t l = length; l > 0; l--) {
if (buff[l - 1] == '\\') {
buff[l] = '\0';
break;
}
}
}
DWORD WINAPI getModuleFileNameAMock(HMODULE hModule, LPSTR lpFilename, DWORD nSize) {
return snprintf(lpFilename, nSize, "z:\\SomeFakeName.dll");
}
HMODULE WINAPI loadLibraryExAMock(LPCSTR lpFileName, HANDLE hFile, DWORD dwFlags) {
if (mockWillFailInNonSystem32 && dwFlags != LOAD_LIBRARY_SEARCH_SYSTEM32)
return NULL;
char fName[MAX_PATH];
auto lenFn = strlen(lpFileName);
strcpy_s(fName, sizeof(fName), lpFileName);
trimFileName(fName, lenFn);
if (dwFlags != LOAD_LIBRARY_SEARCH_SYSTEM32) {
EXPECT_STREQ("z:\\", fName);
}
return (HMODULE)1;
}
UINT WINAPI getSystemDirectoryAMock(LPSTR lpBuffer, UINT uSize) {
const char path[] = "C:\\System";
strcpy_s(lpBuffer, sizeof(path), path);
return sizeof(path) - 1; // do not include terminating null
}
TEST(OSLibraryWinTest, WhenLoadDependencyFailsThenFallbackToSystem32) {
auto bkp = OsLibraryBackup::backup(loadLibraryExAMock, getModuleFileNameAMock, getSystemDirectoryAMock);
std::unique_ptr<OsLibrary> library(OsLibrary::loadFunc(Os::testDllName));
EXPECT_NE(nullptr, library);
}
TEST(OSLibraryWinTest, WhenDependencyLoadsThenProperPathIsConstructed) {
auto bkp = OsLibraryBackup::backup(loadLibraryExAMock, getModuleFileNameAMock, getSystemDirectoryAMock);
VariableBackup<bool> bkpM(&mockWillFailInNonSystem32, false);
std::unique_ptr<OsLibrary> library(OsLibrary::loadFunc(Os::testDllName));
EXPECT_NE(nullptr, library);
}
TEST(OSLibraryWinTest, WhenCreatingFullSystemPathThenProperPathIsConstructed) {
auto bkp = OsLibraryBackup::backup(loadLibraryExAMock, getModuleFileNameAMock, getSystemDirectoryAMock);
VariableBackup<bool> bkpM(&mockWillFailInNonSystem32, false);
auto fullPath = OsLibrary::createFullSystemPath("test");
EXPECT_STREQ("C:\\System\\test", fullPath.c_str());
}
TEST(OSLibraryWinTest, GivenInvalidLibraryWhenOpeningLibraryThenLoadLibraryErrorIsReturned) {
std::string errorValue;
auto lib = std::make_unique<Windows::OsLibrary>("abc", &errorValue);
EXPECT_FALSE(errorValue.empty());
}
TEST(OSLibraryWinTest, GivenNoLastErrorOnWindowsThenErrorStringisEmpty) {
std::string errorValue;
auto lib = std::make_unique<Windows::OsLibrary>(Os::testDllName, &errorValue);
EXPECT_NE(nullptr, lib);
EXPECT_TRUE(errorValue.empty());
lib->getLastErrorString(&errorValue);
EXPECT_TRUE(errorValue.empty());
lib->getLastErrorString(nullptr);
}
|