230 lines
7.8 KiB
C++
230 lines
7.8 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "UbaFileAccessor.h"
|
|
#include "UbaNetworkBackendTcp.h"
|
|
#include "UbaStorageClient.h"
|
|
#include "UbaStorageServer.h"
|
|
|
|
namespace uba
|
|
{
|
|
bool TestStorage(LoggerWithWriter& logger, const StringBufferBase& testRootDir)
|
|
{
|
|
#if PLATFORM_LINUX
|
|
if (true) // TODO: Revisit this... fails on farm but works locally
|
|
return true;
|
|
#endif
|
|
|
|
StringBuffer<> rootDir;
|
|
rootDir.Append(testRootDir).Append(TCV("Uba"));
|
|
StorageCreateInfo storageInfo(rootDir.data, logger.m_writer);
|
|
storageInfo.casCapacityBytes = 1024ull * 1024 * 1024;
|
|
StorageImpl storage(storageInfo);
|
|
|
|
StringBuffer<> detoursLib;
|
|
GetDirectoryOfCurrentModule(logger, detoursLib);
|
|
detoursLib.EnsureEndsWithSlash().Append(UBA_DETOURS_LIBRARY);
|
|
|
|
storage.LoadCasTable();
|
|
|
|
CasKey key;
|
|
bool deferCreation = false;
|
|
if (!storage.StoreCasFile(key, detoursLib.data, CasKeyZero, deferCreation))
|
|
return logger.Error(TC("Failed to store file %s"), detoursLib.data);
|
|
if (key == CasKeyZero)
|
|
return logger.Error(TC("Failed to find file %s"), detoursLib.data);
|
|
|
|
StringBuffer<> detoursLibCopy(detoursLib);
|
|
detoursLibCopy.Append(TCV(".tmp"));
|
|
|
|
auto deleteFile = MakeGuard([&]() { return DeleteFileW(detoursLibCopy.data); });
|
|
|
|
if (!storage.CopyOrLink(key, detoursLibCopy.data, DefaultAttributes()))
|
|
return logger.Error(TC("Failed to copy cas to file %s"), detoursLibCopy.data);
|
|
|
|
FileHandle original;
|
|
if (!OpenFileSequentialRead(logger, detoursLib.data, original))
|
|
return logger.Error(TC("Failed to open %s for read"), detoursLib.data);
|
|
auto closeOriginal = MakeGuard([&]() { return CloseFile(detoursLib.data, original); });
|
|
|
|
FileHandle copy;
|
|
if (!OpenFileSequentialRead(logger, detoursLibCopy.data, copy))
|
|
return logger.Error(TC("Failed to open %s for read"), detoursLibCopy.data);
|
|
auto closeCopy = MakeGuard([&]() { return CloseFile(detoursLibCopy.data, copy); });
|
|
|
|
u64 originalSize;
|
|
if (!GetFileSizeEx(originalSize, original))
|
|
return logger.Error(TC("Failed to get size of %s"), detoursLib.data);
|
|
u64 copySize;
|
|
if (!GetFileSizeEx(copySize, copy))
|
|
return logger.Error(TC("Failed to get size of %s"), detoursLibCopy.data);
|
|
if (originalSize != copySize)
|
|
return logger.Error(TC("Size mismatch between %s and %s (%llu vs %llu)"), detoursLib.data, detoursLibCopy.data, originalSize, copySize);
|
|
|
|
u8 originalBuffer[64 * 1024];
|
|
u8 copyBuffer[64 * 1024];
|
|
u64 left = originalSize;
|
|
while (left)
|
|
{
|
|
u64 toRead = Min(left, (u64)sizeof(originalBuffer));
|
|
if (!ReadFile(logger, detoursLib.data, original, originalBuffer, toRead))
|
|
return logger.Error(TC("Failed to read %u from %s"), detoursLib.data);
|
|
if (!ReadFile(logger, detoursLibCopy.data, copy, copyBuffer, toRead))
|
|
return logger.Error(TC("Failed to read %u from %s"), detoursLibCopy.data);
|
|
if (memcmp(originalBuffer, copyBuffer, toRead) != 0)
|
|
return logger.Error(TC("Data mismatch between %s and %s"), detoursLib.data, detoursLibCopy.data);
|
|
|
|
left -= toRead;
|
|
}
|
|
|
|
if (!closeOriginal.Execute())
|
|
return logger.Error(TC("Failed to close %s"), detoursLib.data);
|
|
|
|
if (!closeCopy.Execute())
|
|
return logger.Error(TC("Failed to close %s"), detoursLibCopy.data);
|
|
|
|
if (!deleteFile.Execute())
|
|
return logger.Error(TC("Failed to delete %s"), detoursLibCopy.data);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool TestRemoteStorageStore(LoggerWithWriter& logger, const StringBufferBase& testRootDir)
|
|
{
|
|
auto& logWriter = logger.m_writer;
|
|
NetworkBackendTcp serverTcp(logWriter, TC("ServerTcp"));
|
|
NetworkBackendTcp clientTcp(logWriter, TC("ClientTcp"));
|
|
|
|
bool ctorSuccess = true;
|
|
NetworkServer server(ctorSuccess, logWriter);
|
|
NetworkClient client(ctorSuccess, logWriter);
|
|
auto dg = MakeGuard([&]() { client.Disconnect(); });
|
|
|
|
StringBuffer<> rootDir;
|
|
rootDir.Append(testRootDir).Append(TCV("Uba"));
|
|
if (!DeleteAllFiles(logger, rootDir.data))
|
|
return false;
|
|
|
|
StorageServerCreateInfo storageServerInfo(server, rootDir.data, logger.m_writer);
|
|
storageServerInfo.casCapacityBytes = 1024ull * 1024 * 1024;
|
|
StorageServer storageServer(storageServerInfo);
|
|
|
|
auto g = MakeGuard([&]() { server.DisconnectClients(); });
|
|
|
|
rootDir.Append(TCV("Client"));
|
|
if (!DeleteAllFiles(logger, rootDir.data))
|
|
return false;
|
|
|
|
StorageClientCreateInfo storageClientInfo(client, rootDir.data);
|
|
StorageClient storageClient(storageClientInfo);
|
|
storageClient.Start();
|
|
|
|
if (!storageClient.LoadCasTable(true))
|
|
return false;
|
|
|
|
rootDir.EnsureEndsWithSlash();
|
|
|
|
if (!server.StartListen(serverTcp, 1234))
|
|
return logger.Error(TC("Failed to listen"));
|
|
Sleep(100);
|
|
if (!client.Connect(clientTcp, TC("127.0.0.1"), 1234))
|
|
return logger.Error(TC("Failed to connect"));
|
|
auto cg = MakeGuard([&]() { client.Disconnect(); });
|
|
|
|
StringBuffer<> fileName;
|
|
{
|
|
fileName.Append(rootDir).Append(TCV("UbaTestFile"));
|
|
FileAccessor fileHandle(logger, fileName.data);
|
|
if (!fileHandle.CreateWrite())
|
|
return logger.Error(TC("Failed to create file for write"));
|
|
u8 byte = 'H';
|
|
if (!fileHandle.Write(&byte, 1))
|
|
return false;
|
|
if (!fileHandle.Close())
|
|
return false;
|
|
}
|
|
|
|
CasKey key;
|
|
bool storeCompressed = false;
|
|
if (!storageClient.StoreCasFileClient(key, ToStringKeyLower(fileName), fileName.data, FileMappingHandle{}, 0, 0, TC("UbaTestFile"), false, storeCompressed))
|
|
return logger.Error(TC("Failed to store file %s"), fileName.data);
|
|
|
|
fileName.Clear().Append(testRootDir).Append(TCV("Uba")).Append(PathSeparator).Append(TCV("UbaTestFile"));
|
|
if (!storageServer.CopyOrLink(key, fileName.data, DefaultAttributes()))
|
|
return logger.Error(TC("Failed to copy cas to file %s"), fileName.data);
|
|
return true;
|
|
}
|
|
|
|
bool TestRemoteStorageFetch(LoggerWithWriter& logger, const StringBufferBase& testRootDir)
|
|
{
|
|
auto& logWriter = logger.m_writer;
|
|
NetworkBackendTcp serverTcp(logWriter, TC("ServerTcp"));
|
|
NetworkBackendTcp clientTcp(logWriter, TC("ClientTcp"));
|
|
|
|
bool ctorSuccess = true;
|
|
NetworkServer server(ctorSuccess, logWriter);
|
|
NetworkClient client(ctorSuccess, logWriter);
|
|
auto dg = MakeGuard([&]() { client.Disconnect(); });
|
|
|
|
StringBuffer<> rootDir;
|
|
rootDir.Append(testRootDir).Append(TCV("Uba"));
|
|
if (!DeleteAllFiles(logger, rootDir.data))
|
|
return false;
|
|
|
|
StorageServerCreateInfo storageServerInfo(server, rootDir.data, logger.m_writer);
|
|
storageServerInfo.casCapacityBytes = 1024ull * 1024 * 1024;
|
|
storageServerInfo.storeCompressed = false;
|
|
StorageServer storageServer(storageServerInfo);
|
|
|
|
auto g = MakeGuard([&]() { server.DisconnectClients(); });
|
|
|
|
rootDir.Append(TCV("Client"));
|
|
if (!DeleteAllFiles(logger, rootDir.data))
|
|
return false;
|
|
|
|
StorageClientCreateInfo storageClientInfo(client, rootDir.data);
|
|
StorageClient storageClient(storageClientInfo);
|
|
storageClient.Start();
|
|
|
|
if (!storageClient.LoadCasTable(true))
|
|
return false;
|
|
|
|
rootDir.EnsureEndsWithSlash();
|
|
|
|
if (!server.StartListen(serverTcp, 1234))
|
|
return logger.Error(TC("Failed to listen"));
|
|
Sleep(100);
|
|
if (!client.Connect(clientTcp, TC("127.0.0.1"), 1234))
|
|
return logger.Error(TC("Failed to connect"));
|
|
auto cg = MakeGuard([&]() { client.Disconnect(); });
|
|
|
|
StringBuffer<> fileName;
|
|
#if 1
|
|
{
|
|
fileName.Append(rootDir).Append(TCV("UbaTestFile"));
|
|
FileAccessor fileHandle(logger, fileName.data);
|
|
if (!fileHandle.CreateWrite())
|
|
return logger.Error(TC("Failed to create file for write"));
|
|
u8 byte = 'H';
|
|
if (!fileHandle.Write(&byte, 1))
|
|
return false;
|
|
if (!fileHandle.Close())
|
|
return false;
|
|
}
|
|
#else
|
|
fileName.Append(TCV("e:\\dev\\fn\\QAGame\\Saved\\StagedBuilds\\PS5_Temp\\Split\\qagame\\content\\paks\\qagame-ps5.ucas\\.copied"));
|
|
#endif
|
|
|
|
CasKey casKey;
|
|
if (!storageServer.CalculateCasKey(casKey, fileName.data))
|
|
return false;
|
|
|
|
casKey = AsCompressed(casKey, false);
|
|
|
|
Storage::RetrieveResult result;
|
|
if (!storageClient.RetrieveCasFile(result, casKey, fileName.data))
|
|
return logger.Error(TC("Failed to store file %s"), fileName.data);
|
|
|
|
return true;
|
|
}
|
|
}
|