Initial commit

This commit is contained in:
alexpete
2021-03-05 11:26:34 -08:00
commit a10351f38d
27091 changed files with 5521199 additions and 0 deletions
@@ -0,0 +1,181 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "FileProcessorTests.h"
namespace UnitTests
{
constexpr int ConnectionBusId = 0;
void FileProcessorTests::SetUp()
{
AssetProcessorTest::SetUp();
ConnectionBus::Handler::BusConnect(ConnectionBusId);
m_data.reset(new StaticData());
m_data->m_databaseLocationListener.BusConnect();
m_data->m_temporarySourceDir = QDir(m_data->m_temporaryDir.path());
// in other unit tests we may open the database called ":memory:" to use an in-memory database instead of one on disk.
// in this test, however, we use a real database, because the file processor shares it and opens its own connection to it.
// ":memory:" databases are one-instance-only, and even if another connection is opened to ":memory:" it would
// not share with others created using ":memory:" and get a unique database instead.
m_data->m_databaseLocation = m_data->m_temporarySourceDir.absoluteFilePath("test_database.sqlite").toUtf8().constData();
ON_CALL(m_data->m_databaseLocationListener, GetAssetDatabaseLocation(_))
.WillByDefault(
DoAll( // set the 0th argument ref (string) to the database location and return true.
SetArgReferee<0>(m_data->m_databaseLocation),
Return(true)));
// Initialize the database:
m_data->m_connection.ClearData(); // this is expected to reset/clear/reopen
m_data->m_config = AZStd::make_unique<AssetProcessor::PlatformConfiguration>();
m_data->m_config->EnablePlatform({ "pc", { "host", "renderer", "desktop" } }, true);
m_data->m_fileProcessor = AZStd::make_unique<FileProcessor>(m_data->m_config.get());
m_data->m_scanFolder = { m_data->m_temporarySourceDir.absolutePath().toUtf8().constData(), "dev", "rootportkey", "" };
ASSERT_TRUE(m_data->m_connection.SetScanFolder(m_data->m_scanFolder));
m_data->m_config->AddScanFolder(ScanFolderInfo(m_data->m_temporarySourceDir.absolutePath(), "dev", "rootportkey", "", false, true, m_data->m_config->GetEnabledPlatforms(), 0, m_data->m_scanFolder.m_scanFolderID));
for (int index = 0; index < 10; ++index)
{
FileDatabaseEntry entry;
entry.m_fileName = AZStd::string::format("somefile_%d.tif", index);
entry.m_isFolder = false;
entry.m_modTime = 0;
entry.m_scanFolderPK = m_data->m_scanFolder.m_scanFolderID;
m_data->m_fileEntries.push_back(entry);
}
}
void FileProcessorTests::TearDown()
{
m_data->m_databaseLocationListener.BusDisconnect();
m_data.reset();
ConnectionBus::Handler::BusDisconnect(ConnectionBusId);
AssetProcessorTest::TearDown();
}
size_t FileProcessorTests::Send([[maybe_unused]] unsigned int serial, [[maybe_unused]] const AzFramework::AssetSystem::BaseAssetProcessorMessage& message)
{
m_data->m_messagesSent++;
return 0;
}
TEST_F(FileProcessorTests, FilesAdded_WhenSentMultipleAdds_ShouldEmitOnlyOneAdd)
{
QSet<AssetFileInfo> scannerFiles;
m_data->m_fileProcessor->AssessAddedFile(m_data->m_temporarySourceDir.absoluteFilePath(m_data->m_fileEntries[0].m_fileName.c_str()));
m_data->m_fileProcessor->AssessAddedFile(m_data->m_temporarySourceDir.absoluteFilePath(m_data->m_fileEntries[0].m_fileName.c_str()));
ASSERT_EQ(m_data->m_messagesSent, 1);
}
TEST_F(FileProcessorTests, FilesFromScanner_ShouldSaveToDatabaseWithoutCreatingDuplicates)
{
QSet<AssetFileInfo> scannerFiles;
auto* scanFolder = m_data->m_config->GetScanFolderByPath(m_data->m_scanFolder.m_scanFolder.c_str());
ASSERT_NE(scanFolder, nullptr);
for (const auto& file : m_data->m_fileEntries)
{
scannerFiles.insert(AssetFileInfo(m_data->m_temporarySourceDir.absoluteFilePath(file.m_fileName.c_str()), QDateTime::fromMSecsSinceEpoch(file.m_modTime), 1234, scanFolder, file.m_isFolder));
}
m_data->m_fileProcessor->AssessFilesFromScanner(scannerFiles);
m_data->m_fileProcessor->Sync();
// Run again to make sure we don't get duplicate entries
m_data->m_fileProcessor->AssessFilesFromScanner(scannerFiles);
m_data->m_fileProcessor->Sync();
FileDatabaseEntryContainer actualEntries;
auto filesFunction = [&actualEntries](AzToolsFramework::AssetDatabase::FileDatabaseEntry& entry)
{
actualEntries.push_back(entry);
return true;
};
ASSERT_TRUE(m_data->m_connection.QueryFilesTable(filesFunction));
ASSERT_THAT(m_data->m_fileEntries, testing::UnorderedElementsAreArray(actualEntries));
}
TEST_F(FileProcessorTests, FilesFromScanner_ShouldHandleChangesBetweenSyncs)
{
QSet<AssetFileInfo> scannerFiles;
auto* scanFolder = m_data->m_config->GetScanFolderByPath(m_data->m_scanFolder.m_scanFolder.c_str());
ASSERT_NE(scanFolder, nullptr);
for (const auto& file : m_data->m_fileEntries)
{
scannerFiles.insert(AssetFileInfo(m_data->m_temporarySourceDir.absoluteFilePath(file.m_fileName.c_str()), QDateTime::fromMSecsSinceEpoch(file.m_modTime), 1234, scanFolder, file.m_isFolder));
}
m_data->m_fileProcessor->AssessFilesFromScanner(scannerFiles);
m_data->m_fileProcessor->Sync();
FileDatabaseEntryContainer actualEntries;
auto filesFunction = [&actualEntries](AzToolsFramework::AssetDatabase::FileDatabaseEntry& entry)
{
actualEntries.push_back(entry);
return true;
};
ASSERT_TRUE(m_data->m_connection.QueryFilesTable(filesFunction));
ASSERT_THAT(m_data->m_fileEntries, testing::UnorderedElementsAreArray(actualEntries));
// Clear the db (we don't have the file IDs in m_fileEntries to remove 1 by 1 so its easier to just remove them all)
for (const auto& file : actualEntries)
{
m_data->m_connection.RemoveFile(file.m_fileID);
}
// Remove two files
m_data->m_fileEntries.erase(m_data->m_fileEntries.begin());
m_data->m_fileEntries.erase(m_data->m_fileEntries.begin());
// Add a file
FileDatabaseEntry entry;
entry.m_fileName = AZStd::string::format("somefile_%d.tif", 11);
entry.m_isFolder = false;
entry.m_modTime = 0;
entry.m_scanFolderPK = m_data->m_scanFolder.m_scanFolderID;
m_data->m_fileEntries.push_back(entry);
scannerFiles.clear();
for (const auto& file : m_data->m_fileEntries)
{
scannerFiles.insert(AssetFileInfo(m_data->m_temporarySourceDir.absoluteFilePath(file.m_fileName.c_str()), QDateTime::fromMSecsSinceEpoch(file.m_modTime), 1234, scanFolder, file.m_isFolder));
}
// Sync again
m_data->m_fileProcessor->AssessFilesFromScanner(scannerFiles);
m_data->m_fileProcessor->Sync();
actualEntries.clear();
ASSERT_TRUE(m_data->m_connection.QueryFilesTable(filesFunction));
ASSERT_THAT(m_data->m_fileEntries, testing::UnorderedElementsAreArray(actualEntries));
}
}
@@ -0,0 +1,114 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzTest/AzTest.h>
#include <AssetBuilderSDK/AssetBuilderSDK.h>
#include "native/tests/AssetProcessorTest.h"
#include "AzToolsFramework/API/AssetDatabaseBus.h"
#include "AssetDatabase/AssetDatabase.h"
#include "FileProcessor/FileProcessor.h"
#include "utilities/PlatformConfiguration.h"
#include <QCoreApplication>
#include <utilities/AssetUtilEBusHelper.h>
namespace UnitTests
{
using namespace testing;
using ::testing::NiceMock;
using namespace AssetProcessor;
using AzToolsFramework::AssetDatabase::ProductDatabaseEntry;
using AzToolsFramework::AssetDatabase::ScanFolderDatabaseEntry;
using AzToolsFramework::AssetDatabase::SourceDatabaseEntry;
using AzToolsFramework::AssetDatabase::SourceFileDependencyEntry;
using AzToolsFramework::AssetDatabase::SourceFileDependencyEntryContainer;
using AzToolsFramework::AssetDatabase::JobDatabaseEntry;
using AzToolsFramework::AssetDatabase::ProductDatabaseEntryContainer;
using AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntry;
using AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntryContainer;
using AzToolsFramework::AssetDatabase::AssetDatabaseConnection;
using AzToolsFramework::AssetDatabase::FileDatabaseEntry;
using AzToolsFramework::AssetDatabase::FileDatabaseEntryContainer;
class FileProcessorTestsMockDatabaseLocationListener : public AzToolsFramework::AssetDatabase::AssetDatabaseRequests::Bus::Handler
{
public:
MOCK_METHOD1(GetAssetDatabaseLocation, bool(AZStd::string&));
};
class FileProcessorTests
: public AssetProcessorTest,
public ConnectionBus::Handler
{
public:
void SetUp() override;
void TearDown() override;
//////////////////////////////////////////////////////////////////////////
// Sends an unsolicited message to the connection
size_t Send(unsigned int serial, const AzFramework::AssetSystem::BaseAssetProcessorMessage& message) override;
// Sends a raw buffer to the connection
size_t SendRaw([[maybe_unused]] unsigned int type, [[maybe_unused]] unsigned int serial, [[maybe_unused]] const QByteArray& data) override { return 0; };
// Sends a message to the connection if the platform match
size_t SendPerPlatform([[maybe_unused]] unsigned int serial, [[maybe_unused]] const AzFramework::AssetSystem::BaseAssetProcessorMessage& message, [[maybe_unused]] const QString& platform) override { return 0; };
// Sends a raw buffer to the connection if the platform match
size_t SendRawPerPlatform([[maybe_unused]] unsigned int type, [[maybe_unused]] unsigned int serial, [[maybe_unused]] const QByteArray& data, [[maybe_unused]] const QString& platform) override { return 0; };
// Sends a message to the connection which expects a response.
unsigned int SendRequest([[maybe_unused]] const AzFramework::AssetSystem::BaseAssetProcessorMessage& message, [[maybe_unused]] const ResponseCallback& callback) override { return 0; };
// Sends a response to the connection
size_t SendResponse([[maybe_unused]] unsigned int serial, [[maybe_unused]] const AzFramework::AssetSystem::BaseAssetProcessorMessage& message) override { return 0; };
// Removes a response handler that is no longer needed
void RemoveResponseHandler([[maybe_unused]] unsigned int serial) override {};
protected:
struct StaticData
{
QTemporaryDir m_temporaryDir;
QDir m_temporarySourceDir;
// these variables are created during SetUp() and destroyed during TearDown() and thus are always available during tests using this fixture:
AZStd::string m_databaseLocation;
NiceMock<FileProcessorTestsMockDatabaseLocationListener> m_databaseLocationListener;
AssetProcessor::AssetDatabaseConnection m_connection;
AZStd::unique_ptr<AssetProcessor::PlatformConfiguration> m_config;
// The following database entry variables are initialized only when you call coverage test data CreateCoverageTestData().
// Tests which don't need or want a pre-made database should not call CreateCoverageTestData() but note that in that case
// these entries will be empty and their identifiers will be -1.
ScanFolderDatabaseEntry m_scanFolder;
AZStd::unique_ptr<FileProcessor> m_fileProcessor;
FileDatabaseEntryContainer m_fileEntries;
QCoreApplication m_coreApp;
int m_argc = 0;
int m_messagesSent = 0;
StaticData() : m_coreApp(m_argc, nullptr)
{
}
};
// we store the above data in a unique_ptr so that its memory can be cleared during TearDown() in one call, before we destroy the memory
// allocator, reducing the chance of missing or forgetting to destroy one in the future.
AZStd::unique_ptr<StaticData> m_data;
};
}