fix: refactor Windows cl_cache and add extra safety layers
What's changed: - Add early return when open existing config fails due to different error than `ERROR_FILE_NOT_FOUND` - Swich `ReadFileEx` to `ReadFile` - Add `SetFilePointer` to make sure we're reading from the beginning of the file - Pass `overlapped` to `WriteFile` to make sure we're writing from the beginning of the file Related-To: NEO-8092 Signed-off-by: Fabian Zwolinski <fabian.zwolinski@intel.com>
This commit is contained in:
parent
d27d81f206
commit
7c80f49176
|
@ -103,6 +103,10 @@ void CompilerCache::lockConfigFileAndReadSize(const std::string &configFilePath,
|
|||
NULL);
|
||||
|
||||
if (std::get<void *>(handle) == INVALID_HANDLE_VALUE) {
|
||||
if (SysCalls::getLastError() != ERROR_FILE_NOT_FOUND) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "PID %d [Cache failure]: Open config file failed! error code: %lu\n", NEO::SysCalls::getProcessId(), SysCalls::getLastError());
|
||||
return;
|
||||
}
|
||||
std::get<void *>(handle) = NEO::SysCalls::createFileA(configFilePath.c_str(),
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
|
@ -132,11 +136,6 @@ void CompilerCache::lockConfigFileAndReadSize(const std::string &configFilePath,
|
|||
MAXDWORD,
|
||||
&overlapped);
|
||||
|
||||
if (result == FALSE && SysCalls::getLastError() == ERROR_IO_PENDING) { // if file is already locked by somebody else
|
||||
DWORD numberOfBytesTransmitted = 0;
|
||||
result = NEO::SysCalls::getOverlappedResult(std::get<void *>(handle), &overlapped, &numberOfBytesTransmitted, TRUE);
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
std::get<void *>(handle) = INVALID_HANDLE_VALUE;
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "PID %d [Cache failure]: Lock config file failed! error code: %lu\n", NEO::SysCalls::getProcessId(), SysCalls::getLastError());
|
||||
|
@ -150,8 +149,24 @@ void CompilerCache::lockConfigFileAndReadSize(const std::string &configFilePath,
|
|||
directorySize += static_cast<size_t>(file.fileSize);
|
||||
}
|
||||
} else {
|
||||
memset(&overlapped, 0, sizeof(overlapped));
|
||||
result = NEO::SysCalls::readFileEx(std::get<void *>(handle), &directorySize, sizeof(directorySize), &overlapped, NULL);
|
||||
DWORD fPointer = NEO::SysCalls::setFilePointer(std::get<void *>(handle),
|
||||
0,
|
||||
NULL,
|
||||
FILE_BEGIN);
|
||||
if (fPointer != 0) {
|
||||
directorySize = 0;
|
||||
unlockFileAndClose(std::get<void *>(handle));
|
||||
std::get<void *>(handle) = INVALID_HANDLE_VALUE;
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "PID %d [Cache failure]: File pointer move failed! error code: %lu\n", NEO::SysCalls::getProcessId(), SysCalls::getLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD numOfBytesRead = 0;
|
||||
result = NEO::SysCalls::readFile(std::get<void *>(handle),
|
||||
&directorySize,
|
||||
sizeof(directorySize),
|
||||
&numOfBytesRead,
|
||||
NULL);
|
||||
|
||||
if (!result) {
|
||||
directorySize = 0;
|
||||
|
@ -235,10 +250,6 @@ bool CompilerCache::cacheBinary(const std::string &kernelFileHash, const char *p
|
|||
lockConfigFileAndReadSize(configFilePath, hConfigFile, directorySize);
|
||||
|
||||
if (std::get<void *>(hConfigFile) == INVALID_HANDLE_VALUE) {
|
||||
if (SysCalls::getLastError() == ERROR_HANDLE_EOF) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "PID %d [Cache info]: deleting the corrupted config file\n", NEO::SysCalls::getProcessId());
|
||||
SysCalls::deleteFileA(configFilePath.c_str());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -274,11 +285,12 @@ bool CompilerCache::cacheBinary(const std::string &kernelFileHash, const char *p
|
|||
directorySize += binarySize;
|
||||
|
||||
DWORD sizeWritten = 0;
|
||||
OVERLAPPED overlapped = {0};
|
||||
auto result = NEO::SysCalls::writeFile(std::get<void *>(hConfigFile),
|
||||
&directorySize,
|
||||
(DWORD)sizeof(directorySize),
|
||||
&sizeWritten,
|
||||
NULL);
|
||||
&overlapped);
|
||||
|
||||
if (!result) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "PID %d [Cache failure]: Writing to config file failed! error code: %lu\n", NEO::SysCalls::getProcessId(), SysCalls::getLastError());
|
||||
|
|
|
@ -104,8 +104,8 @@ HRESULT shGetKnownFolderPath(REFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken
|
|||
return SHGetKnownFolderPath(rfid, dwFlags, hToken, ppszPat);
|
||||
}
|
||||
|
||||
BOOL readFileEx(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) {
|
||||
return ReadFileEx(hFile, lpBuffer, nNumberOfBytesToRead, lpOverlapped, lpCompletionRoutine);
|
||||
BOOL readFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped) {
|
||||
return ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
|
||||
}
|
||||
|
||||
BOOL writeFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped) {
|
||||
|
@ -128,6 +128,10 @@ DWORD getFileAttributesA(LPCSTR lpFileName) {
|
|||
return GetFileAttributesA(lpFileName);
|
||||
}
|
||||
|
||||
DWORD setFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod) {
|
||||
return SetFilePointer(hFile, lDistanceToMove, lpDistanceToMoveHigh, dwMoveMethod);
|
||||
}
|
||||
|
||||
void coTaskMemFree(LPVOID pv) {
|
||||
CoTaskMemFree(pv);
|
||||
}
|
||||
|
|
|
@ -28,12 +28,13 @@ BOOL createDirectoryA(LPCSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttribu
|
|||
HANDLE createFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
|
||||
BOOL deleteFileA(LPCSTR lpFileName);
|
||||
HRESULT shGetKnownFolderPath(REFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPat);
|
||||
BOOL readFileEx(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
|
||||
BOOL readFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);
|
||||
BOOL writeFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped);
|
||||
HANDLE findFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData);
|
||||
BOOL findNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData);
|
||||
BOOL findClose(HANDLE hFindFile);
|
||||
DWORD getFileAttributesA(LPCSTR lpFileName);
|
||||
DWORD setFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod);
|
||||
|
||||
void coTaskMemFree(LPVOID pv);
|
||||
|
||||
|
|
|
@ -68,10 +68,10 @@ HRESULT shGetKnownFolderPathResult = 0;
|
|||
extern const size_t shGetKnownFolderSetPathSize = 50;
|
||||
wchar_t shGetKnownFolderSetPath[shGetKnownFolderSetPathSize];
|
||||
|
||||
bool callBaseReadFileEx = true;
|
||||
BOOL readFileExResult = TRUE;
|
||||
size_t readFileExCalled = 0u;
|
||||
size_t readFileExBufferData = 0u;
|
||||
bool callBaseReadFile = true;
|
||||
BOOL readFileResult = TRUE;
|
||||
size_t readFileCalled = 0u;
|
||||
size_t readFileBufferData = 0u;
|
||||
|
||||
size_t writeFileCalled = 0u;
|
||||
BOOL writeFileResult = true;
|
||||
|
@ -90,6 +90,9 @@ size_t findCloseCalled = 0u;
|
|||
size_t getFileAttributesCalled = 0u;
|
||||
DWORD getFileAttributesResult = TRUE;
|
||||
|
||||
size_t setFilePointerCalled = 0u;
|
||||
DWORD setFilePointerResult = 0;
|
||||
|
||||
bool pathExists(const std::string &path) {
|
||||
std::string tempP1 = path;
|
||||
if (!path.empty() && path.back() == PATH_SEPARATOR) {
|
||||
|
@ -214,15 +217,15 @@ HRESULT shGetKnownFolderPath(REFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken
|
|||
return shGetKnownFolderPathResult;
|
||||
}
|
||||
|
||||
BOOL readFileEx(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) {
|
||||
readFileExCalled++;
|
||||
if (callBaseReadFileEx) {
|
||||
return ReadFileEx(hFile, lpBuffer, nNumberOfBytesToRead, lpOverlapped, lpCompletionRoutine);
|
||||
BOOL readFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped) {
|
||||
readFileCalled++;
|
||||
if (callBaseReadFile) {
|
||||
return ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
|
||||
}
|
||||
if (lpBuffer) {
|
||||
*static_cast<size_t *>(lpBuffer) = readFileExBufferData;
|
||||
*static_cast<size_t *>(lpBuffer) = readFileBufferData;
|
||||
}
|
||||
return readFileExResult;
|
||||
return readFileResult;
|
||||
}
|
||||
|
||||
BOOL writeFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped) {
|
||||
|
@ -261,6 +264,11 @@ DWORD getFileAttributesA(LPCSTR lpFileName) {
|
|||
return getFileAttributesResult;
|
||||
}
|
||||
|
||||
DWORD setFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod) {
|
||||
setFilePointerCalled++;
|
||||
return setFilePointerResult;
|
||||
}
|
||||
|
||||
void coTaskMemFree(LPVOID pv) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -109,10 +109,10 @@ extern HANDLE createFileAResults[];
|
|||
extern size_t deleteFileACalled;
|
||||
extern std::string deleteFiles[];
|
||||
|
||||
extern bool callBaseReadFileEx;
|
||||
extern BOOL readFileExResult;
|
||||
extern size_t readFileExCalled;
|
||||
extern size_t readFileExBufferData;
|
||||
extern bool callBaseReadFile;
|
||||
extern BOOL readFileResult;
|
||||
extern size_t readFileCalled;
|
||||
extern size_t readFileBufferData;
|
||||
|
||||
extern size_t writeFileCalled;
|
||||
extern BOOL writeFileResult;
|
||||
|
@ -130,6 +130,9 @@ extern size_t findCloseCalled;
|
|||
|
||||
extern size_t getFileAttributesCalled;
|
||||
extern DWORD getFileAttributesResult;
|
||||
|
||||
extern size_t setFilePointerCalled;
|
||||
extern DWORD setFilePointerResult;
|
||||
} // namespace SysCalls
|
||||
|
||||
struct CompilerCacheWindowsTest : public ::testing::Test {
|
||||
|
@ -144,17 +147,19 @@ struct CompilerCacheWindowsTest : public ::testing::Test {
|
|||
unlockFileExResultBackup(&SysCalls::unlockFileExResult),
|
||||
createFileACalledBackup(&SysCalls::createFileACalled),
|
||||
deleteFileACalledBackup(&SysCalls::deleteFileACalled),
|
||||
callBaseReadFileExBackup(&SysCalls::callBaseReadFileEx),
|
||||
readFileExResultBackup(&SysCalls::readFileExResult),
|
||||
readFileExCalledBackup(&SysCalls::readFileExCalled),
|
||||
readFileExBufferDataBackup(&SysCalls::readFileExBufferData),
|
||||
callBaseReadFileBackup(&SysCalls::callBaseReadFile),
|
||||
readFileResultBackup(&SysCalls::readFileResult),
|
||||
readFileCalledBackup(&SysCalls::readFileCalled),
|
||||
readFileBufferDataBackup(&SysCalls::readFileBufferData),
|
||||
writeFileCalledBackup(&SysCalls::writeFileCalled),
|
||||
writeFileResultBackup(&SysCalls::writeFileResult),
|
||||
writeFileNumberOfBytesWrittenBackup(&SysCalls::writeFileNumberOfBytesWritten),
|
||||
findFirstFileAResultBackup(&SysCalls::findFirstFileAResult),
|
||||
findNextFileACalledBackup(&SysCalls::findNextFileACalled),
|
||||
getFileAttributesCalledBackup(&SysCalls::getFileAttributesCalled),
|
||||
getFileAttributesResultBackup(&SysCalls::getFileAttributesResult) {}
|
||||
getFileAttributesResultBackup(&SysCalls::getFileAttributesResult),
|
||||
setFilePointerCalledBackup(&SysCalls::setFilePointerCalled),
|
||||
setFilePointerResultBackup(&SysCalls::setFilePointerResult) {}
|
||||
|
||||
void SetUp() override {
|
||||
SysCalls::closeHandleCalled = 0u;
|
||||
|
@ -163,10 +168,11 @@ struct CompilerCacheWindowsTest : public ::testing::Test {
|
|||
SysCalls::unlockFileExCalled = 0u;
|
||||
SysCalls::createFileACalled = 0u;
|
||||
SysCalls::deleteFileACalled = 0u;
|
||||
SysCalls::readFileExCalled = 0u;
|
||||
SysCalls::readFileCalled = 0u;
|
||||
SysCalls::writeFileCalled = 0u;
|
||||
SysCalls::findNextFileACalled = 0u;
|
||||
SysCalls::getFileAttributesCalled = 0u;
|
||||
SysCalls::setFilePointerCalled = 0u;
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
|
@ -193,10 +199,10 @@ struct CompilerCacheWindowsTest : public ::testing::Test {
|
|||
VariableBackup<BOOL> unlockFileExResultBackup;
|
||||
VariableBackup<size_t> createFileACalledBackup;
|
||||
VariableBackup<size_t> deleteFileACalledBackup;
|
||||
VariableBackup<bool> callBaseReadFileExBackup;
|
||||
VariableBackup<BOOL> readFileExResultBackup;
|
||||
VariableBackup<size_t> readFileExCalledBackup;
|
||||
VariableBackup<size_t> readFileExBufferDataBackup;
|
||||
VariableBackup<bool> callBaseReadFileBackup;
|
||||
VariableBackup<BOOL> readFileResultBackup;
|
||||
VariableBackup<size_t> readFileCalledBackup;
|
||||
VariableBackup<size_t> readFileBufferDataBackup;
|
||||
VariableBackup<size_t> writeFileCalledBackup;
|
||||
VariableBackup<BOOL> writeFileResultBackup;
|
||||
VariableBackup<DWORD> writeFileNumberOfBytesWrittenBackup;
|
||||
|
@ -204,6 +210,8 @@ struct CompilerCacheWindowsTest : public ::testing::Test {
|
|||
VariableBackup<size_t> findNextFileACalledBackup;
|
||||
VariableBackup<size_t> getFileAttributesCalledBackup;
|
||||
VariableBackup<DWORD> getFileAttributesResultBackup;
|
||||
VariableBackup<size_t> setFilePointerCalledBackup;
|
||||
VariableBackup<DWORD> setFilePointerResultBackup;
|
||||
};
|
||||
|
||||
TEST_F(CompilerCacheWindowsTest, GivenCompilerCacheWithOneMegabyteWhenEvictCacheIsCalledThenDeleteTwoOldestFiles) {
|
||||
|
@ -258,9 +266,9 @@ TEST_F(CompilerCacheWindowsTest, givenLockConfigFileAndReadSizeWhenOpenExistingC
|
|||
SysCalls::createFileAResults[0] = reinterpret_cast<HANDLE>(0x1234);
|
||||
SysCalls::lockFileExResult = TRUE;
|
||||
|
||||
SysCalls::callBaseReadFileEx = false;
|
||||
SysCalls::readFileExResult = TRUE;
|
||||
SysCalls::readFileExBufferData = readCacheDirSize;
|
||||
SysCalls::callBaseReadFile = false;
|
||||
SysCalls::readFileResult = TRUE;
|
||||
SysCalls::readFileBufferData = readCacheDirSize;
|
||||
|
||||
const size_t cacheSize = MemoryConstants::megaByte - 2u;
|
||||
CompilerCacheMockWindows cache({true, ".cl_cache", "somePath\\cl_cache", cacheSize});
|
||||
|
@ -272,7 +280,7 @@ TEST_F(CompilerCacheWindowsTest, givenLockConfigFileAndReadSizeWhenOpenExistingC
|
|||
EXPECT_EQ(1u, SysCalls::createFileACalled);
|
||||
EXPECT_EQ(1u, SysCalls::lockFileExCalled);
|
||||
|
||||
EXPECT_EQ(1u, SysCalls::readFileExCalled);
|
||||
EXPECT_EQ(1u, SysCalls::readFileCalled);
|
||||
EXPECT_EQ(readCacheDirSize, directorySize);
|
||||
|
||||
EXPECT_EQ(0u, SysCalls::unlockFileExCalled);
|
||||
|
@ -286,8 +294,8 @@ TEST_F(CompilerCacheWindowsTest, givenLockConfigFileAndReadSizeWhenOpenExistingC
|
|||
SysCalls::createFileAResults[0] = reinterpret_cast<HANDLE>(0x1234);
|
||||
SysCalls::lockFileExResult = FALSE;
|
||||
|
||||
SysCalls::callBaseReadFileEx = false;
|
||||
SysCalls::readFileExResult = TRUE;
|
||||
SysCalls::callBaseReadFile = false;
|
||||
SysCalls::readFileResult = TRUE;
|
||||
|
||||
const size_t cacheSize = MemoryConstants::megaByte - 2u;
|
||||
CompilerCacheMockWindows cache({true, ".cl_cache", "somePath\\cl_cache", cacheSize});
|
||||
|
@ -305,12 +313,47 @@ TEST_F(CompilerCacheWindowsTest, givenLockConfigFileAndReadSizeWhenOpenExistingC
|
|||
EXPECT_EQ(1u, SysCalls::createFileACalled);
|
||||
EXPECT_EQ(1u, SysCalls::lockFileExCalled);
|
||||
|
||||
EXPECT_EQ(0u, SysCalls::readFileExCalled);
|
||||
EXPECT_EQ(0u, SysCalls::readFileCalled);
|
||||
|
||||
EXPECT_EQ(0u, SysCalls::unlockFileExCalled);
|
||||
EXPECT_EQ(0u, SysCalls::closeHandleCalled);
|
||||
}
|
||||
|
||||
TEST_F(CompilerCacheWindowsTest, givenLockConfigFileAndReadSizeWhenOpenExistingConfigWhenSetFilePointerFailsThenErrorIsPrintedAndFileIsUnlockedAndClosed) {
|
||||
DebugManagerStateRestore restore;
|
||||
NEO::DebugManager.flags.PrintDebugMessages.set(1);
|
||||
|
||||
SysCalls::createFileAResults[0] = reinterpret_cast<HANDLE>(0x1234);
|
||||
SysCalls::lockFileExResult = TRUE;
|
||||
|
||||
SysCalls::setFilePointerResult = 8;
|
||||
|
||||
const size_t cacheSize = MemoryConstants::megaByte - 2u;
|
||||
CompilerCacheMockWindows cache({true, ".cl_cache", "somePath\\cl_cache", cacheSize});
|
||||
|
||||
UnifiedHandle configFileHandle{nullptr};
|
||||
size_t directorySize = 0u;
|
||||
|
||||
::testing::internal::CaptureStderr();
|
||||
cache.lockConfigFileAndReadSize("somePath\\cl_cache\\config.file", configFileHandle, directorySize);
|
||||
auto capturedStderr = ::testing::internal::GetCapturedStderr();
|
||||
|
||||
std::string expectedStderrSubstr("[Cache failure]: File pointer move failed! error code:");
|
||||
EXPECT_TRUE(hasSubstr(capturedStderr, expectedStderrSubstr));
|
||||
|
||||
EXPECT_EQ(INVALID_HANDLE_VALUE, std::get<void *>(configFileHandle));
|
||||
EXPECT_EQ(0u, directorySize);
|
||||
|
||||
EXPECT_EQ(1u, SysCalls::createFileACalled);
|
||||
EXPECT_EQ(1u, SysCalls::lockFileExCalled);
|
||||
EXPECT_EQ(1u, SysCalls::setFilePointerCalled);
|
||||
|
||||
EXPECT_EQ(0u, SysCalls::readFileCalled);
|
||||
|
||||
EXPECT_EQ(1u, SysCalls::unlockFileExCalled);
|
||||
EXPECT_EQ(1u, SysCalls::closeHandleCalled);
|
||||
}
|
||||
|
||||
TEST_F(CompilerCacheWindowsTest, givenLockConfigFileAndReadSizeWhenOpenExistingConfigWhenReadFileFailsThenErrorIsPrintedAndFileIsUnlockedAndClosed) {
|
||||
DebugManagerStateRestore restore;
|
||||
NEO::DebugManager.flags.PrintDebugMessages.set(1);
|
||||
|
@ -318,8 +361,8 @@ TEST_F(CompilerCacheWindowsTest, givenLockConfigFileAndReadSizeWhenOpenExistingC
|
|||
SysCalls::createFileAResults[0] = reinterpret_cast<HANDLE>(0x1234);
|
||||
SysCalls::lockFileExResult = TRUE;
|
||||
|
||||
SysCalls::callBaseReadFileEx = false;
|
||||
SysCalls::readFileExResult = FALSE;
|
||||
SysCalls::callBaseReadFile = false;
|
||||
SysCalls::readFileResult = FALSE;
|
||||
|
||||
const size_t cacheSize = MemoryConstants::megaByte - 2u;
|
||||
CompilerCacheMockWindows cache({true, ".cl_cache", "somePath\\cl_cache", cacheSize});
|
||||
|
@ -337,21 +380,23 @@ TEST_F(CompilerCacheWindowsTest, givenLockConfigFileAndReadSizeWhenOpenExistingC
|
|||
EXPECT_EQ(1u, SysCalls::createFileACalled);
|
||||
EXPECT_EQ(1u, SysCalls::lockFileExCalled);
|
||||
|
||||
EXPECT_EQ(1u, SysCalls::readFileExCalled);
|
||||
EXPECT_EQ(1u, SysCalls::readFileCalled);
|
||||
|
||||
EXPECT_EQ(1u, SysCalls::unlockFileExCalled);
|
||||
EXPECT_EQ(1u, SysCalls::closeHandleCalled);
|
||||
}
|
||||
|
||||
TEST_F(CompilerCacheWindowsTest, givenLockConfigFileAndReadSizeWhenOpenExistingConfigFailsThenCreateNewConfigFileAndCountDirectorySize) {
|
||||
TEST_F(CompilerCacheWindowsTest, givenLockConfigFileAndReadSizeWhenOpenExistingConfigFailsDueToFileNotFoundThenCreateNewConfigFileAndCountDirectorySize) {
|
||||
const size_t readCacheDirSize = 840 * MemoryConstants::kiloByte;
|
||||
SysCalls::createFileAResults[0] = INVALID_HANDLE_VALUE;
|
||||
SysCalls::createFileAResults[1] = reinterpret_cast<HANDLE>(0x1234);
|
||||
SysCalls::lockFileExResult = TRUE;
|
||||
|
||||
SysCalls::callBaseReadFileEx = false;
|
||||
SysCalls::readFileExResult = TRUE;
|
||||
SysCalls::readFileExBufferData = readCacheDirSize;
|
||||
SysCalls::callBaseReadFile = false;
|
||||
SysCalls::readFileResult = TRUE;
|
||||
SysCalls::readFileBufferData = readCacheDirSize;
|
||||
|
||||
SysCalls::getLastErrorResult = ERROR_FILE_NOT_FOUND;
|
||||
|
||||
WIN32_FIND_DATAA filesData[4];
|
||||
DWORD cacheFileSize = (MemoryConstants::megaByte / 6) + 10;
|
||||
|
@ -383,11 +428,65 @@ TEST_F(CompilerCacheWindowsTest, givenLockConfigFileAndReadSizeWhenOpenExistingC
|
|||
|
||||
EXPECT_EQ(expectedDirectorySize, directorySize);
|
||||
|
||||
EXPECT_EQ(0u, SysCalls::readFileExCalled);
|
||||
EXPECT_EQ(0u, SysCalls::readFileCalled);
|
||||
EXPECT_EQ(0u, SysCalls::unlockFileExCalled);
|
||||
EXPECT_EQ(0u, SysCalls::closeHandleCalled);
|
||||
}
|
||||
|
||||
TEST_F(CompilerCacheWindowsTest, givenLockConfigFileAndReadSizeWhenOpenExistingConfigFailsThenPrintErrorMessageAndEarlyReturn) {
|
||||
DebugManagerStateRestore restore;
|
||||
NEO::DebugManager.flags.PrintDebugMessages.set(1);
|
||||
|
||||
const size_t readCacheDirSize = 840 * MemoryConstants::kiloByte;
|
||||
SysCalls::createFileAResults[0] = INVALID_HANDLE_VALUE;
|
||||
SysCalls::createFileAResults[1] = reinterpret_cast<HANDLE>(0x1234);
|
||||
SysCalls::lockFileExResult = TRUE;
|
||||
|
||||
SysCalls::callBaseReadFile = false;
|
||||
SysCalls::readFileResult = TRUE;
|
||||
SysCalls::readFileBufferData = readCacheDirSize;
|
||||
|
||||
SysCalls::getLastErrorResult = ERROR_FILE_NOT_FOUND + 1;
|
||||
|
||||
WIN32_FIND_DATAA filesData[4];
|
||||
DWORD cacheFileSize = (MemoryConstants::megaByte / 6) + 10;
|
||||
|
||||
filesData[0].ftLastAccessTime.dwLowDateTime = 6u;
|
||||
filesData[1].ftLastAccessTime.dwLowDateTime = 4u;
|
||||
filesData[2].ftLastAccessTime.dwLowDateTime = 8u;
|
||||
filesData[3].ftLastAccessTime.dwLowDateTime = 2u;
|
||||
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
snprintf(filesData[i].cFileName, MAX_PATH, "file_%zu.cl_cache", i);
|
||||
filesData[i].nFileSizeHigh = 0;
|
||||
filesData[i].nFileSizeLow = cacheFileSize;
|
||||
filesData[i].ftLastAccessTime.dwHighDateTime = 0;
|
||||
|
||||
SysCalls::findNextFileAFileData[i] = filesData[i];
|
||||
}
|
||||
|
||||
const size_t cacheSize = MemoryConstants::megaByte - 2u;
|
||||
CompilerCacheMockWindows cache({true, ".cl_cache", "somePath\\cl_cache", cacheSize});
|
||||
|
||||
UnifiedHandle configFileHandle{nullptr};
|
||||
size_t directorySize = 0u;
|
||||
::testing::internal::CaptureStderr();
|
||||
cache.lockConfigFileAndReadSize("somePath\\cl_cache\\config.file", configFileHandle, directorySize);
|
||||
auto capturedStderr = ::testing::internal::GetCapturedStderr();
|
||||
|
||||
std::string expectedStderrSubstr("[Cache failure]: Open config file failed! error code:");
|
||||
|
||||
EXPECT_TRUE(hasSubstr(capturedStderr, expectedStderrSubstr));
|
||||
|
||||
EXPECT_EQ(INVALID_HANDLE_VALUE, std::get<void *>(configFileHandle));
|
||||
EXPECT_EQ(1u, SysCalls::createFileACalled);
|
||||
EXPECT_EQ(0u, SysCalls::lockFileExCalled);
|
||||
EXPECT_EQ(0u, SysCalls::readFileCalled);
|
||||
EXPECT_EQ(0u, SysCalls::unlockFileExCalled);
|
||||
EXPECT_EQ(0u, SysCalls::closeHandleCalled);
|
||||
EXPECT_EQ(0u, directorySize);
|
||||
}
|
||||
|
||||
TEST_F(CompilerCacheWindowsTest, givenCreateUniqueTempFileAndWriteDataWhenCreateAndWriteTempFileSucceedsThenBinaryIsWritten) {
|
||||
SysCalls::getTempFileNameAResult = 6u;
|
||||
SysCalls::createFileAResults[0] = reinterpret_cast<HANDLE>(0x1234);
|
||||
|
@ -578,44 +677,6 @@ TEST_F(CompilerCacheWindowsTest, givenCacheBinaryWhenCacheAlreadyExistsThenDoNot
|
|||
EXPECT_EQ(0u, SysCalls::writeFileCalled);
|
||||
}
|
||||
|
||||
TEST_F(CompilerCacheWindowsTest, givenEmptyConfigFileWhenCacheBinaryAndReadConfigFailsWithEOFErrorThenConfigIsDeletedAndErrorIsPrinted) {
|
||||
DebugManagerStateRestore restore;
|
||||
NEO::DebugManager.flags.PrintDebugMessages.set(1);
|
||||
|
||||
SysCalls::getLastErrorResult = ERROR_HANDLE_EOF;
|
||||
|
||||
SysCalls::createFileAResults[0] = reinterpret_cast<HANDLE>(0x1234);
|
||||
SysCalls::lockFileExResult = TRUE;
|
||||
|
||||
SysCalls::callBaseReadFileEx = false;
|
||||
SysCalls::readFileExResult = FALSE;
|
||||
|
||||
const size_t cacheSize = MemoryConstants::megaByte - 2u;
|
||||
CompilerCacheMockWindows cache({true, ".cl_cache", "somePath\\cl_cache", cacheSize});
|
||||
|
||||
const std::string kernelFileHash = "7e3291364d8df42";
|
||||
const char *binary = "123456";
|
||||
const size_t binarySize = strlen(binary);
|
||||
|
||||
::testing::internal::CaptureStderr();
|
||||
auto result = cache.cacheBinary(kernelFileHash, binary, binarySize);
|
||||
auto capturedStderr = ::testing::internal::GetCapturedStderr();
|
||||
|
||||
std::string expectedStderrSubstr1("[Cache failure]: Read config failed! error code:");
|
||||
EXPECT_TRUE(hasSubstr(capturedStderr, expectedStderrSubstr1));
|
||||
|
||||
std::string expectedStderrSubstr2("[Cache info]: deleting the corrupted config file");
|
||||
EXPECT_TRUE(hasSubstr(capturedStderr, expectedStderrSubstr2));
|
||||
|
||||
EXPECT_FALSE(result);
|
||||
EXPECT_EQ(1u, SysCalls::createFileACalled);
|
||||
EXPECT_EQ(1u, SysCalls::lockFileExCalled);
|
||||
EXPECT_EQ(1u, SysCalls::readFileExCalled);
|
||||
EXPECT_EQ(1u, SysCalls::unlockFileExCalled);
|
||||
EXPECT_EQ(1u, SysCalls::closeHandleCalled);
|
||||
EXPECT_EQ(1u, SysCalls::deleteFileACalled);
|
||||
}
|
||||
|
||||
TEST_F(CompilerCacheWindowsTest, givenCacheBinaryWhenWriteToConfigFileFailsThenErrorIsPrinted) {
|
||||
DebugManagerStateRestore restore;
|
||||
NEO::DebugManager.flags.PrintDebugMessages.set(1);
|
||||
|
|
Loading…
Reference in New Issue