Files
o3de/Code/Tools/AssetProcessor/native/tests/assetdatabase/AssetDatabaseTest.cpp
T
lumberyard-employee-dm 3dec5d3b71 LYN-2537 engine assets (#254)
* LYN-2537 Moved the Engine and Editor folder to be within the EngineAssets folder

* Fixed Documentation in bootstrap.cfg to correct the path to the user project specific registry file

* Adding a newline to the output of AssetCatalog 'Registering asset..., but type is not set' message

* Updating the AssetProcessorPlatformConfig.setreg Scan Folder to detect
the @ENGINEROOT@/EngineAssets/Engine path for engine runtime assets and
@ENGINEROOT@/EngineAssets/Editor path for engine tool assets

* Updating references to Icons and other assets to account for moving the
Engine and Editor folder under a single EngineAssets folder

* Moving the Engine Settings Registry folder from Engine/Registry -> Registry

* Removed the LY_PROJECT_CMAKE_PATH define as it is not portable to other locations. It is hard coded to the project location that was used for the CMake configuration. Furthermore it paths with backslashes within it are treated as escape characters and not a path separator

* Updated the LyTestTools asset_processor.py script to copy the exclude.filetag from the EngineAssets/Engine directory now

* Fixed Atom Shader Preprocessing when running using an External Project

* Updated the TSGenerateAction.cpp to fix the build error with using a renamed variable

* Updated the Install_Common.cmake ly_setup_others function to install the
EngineAssets directory and the each of the Gem's Assets directory while
maintaining the relative directory structure to the Engine Root
Also updated the install step to install the Registry folder at the
engine root

* Fixed the copying of the Registry folder to be in the install root, instead of under a second 'Registry' folder

* Moving the AssetProcessorPlatformConfig.setreg file over to the Registry folder

* Updated the LyTestTools and C++ code to point that the new location of
the AssetProcessorPlatformConfig.setreg file inside of the Registry
folder

* Renamed Test AssetProcessor*Config.ini files to have the .setreg extension

* Converted the AssetProcessor test setreg files from ini format to json
format using the SerializeContextTools convert-ini command

* Updated the AssetProcessor CMakeLists.txt to copy over the test setreg files to the build folder

* Updated the assetprocessor test file list to point at the renamed AsssetProcessor*Config setreg filenames

* Removed the Output Prefix code from the AssetProcessor. The complexity that it brought to the AP code is not needed, as users can replicate the behavior by just moving there assets underneath a another folder, underneath the scan folder

* Adding back support to read the AssetProcessorPlatformConfig.setreg file from the asset root. This is only needed for C++ UnitTests as they run in an environment where the accessing the Engine Settings Registry is not available

* Updating the Install_common.cmake logic to copy any "Assets" folder to
the install layout.
The Script has also been updated to copy over the "Assets" folder in the
Engine Root to the install layout instead of an "EngineAssets" folder

* Updating References to EngineAssets source asset folder in code to be the Assets source folder

* Moved the Engine Source Asset folder of 'EngineAssets' to a new folder name of 'Assets'. This is inline with the naming scheme we use for Gem asset folders

* Adding the EngineFinder.cmake to the AutomatedTesting project to allow it to work in a project centric manner

* Updating the LyTestTools copy_assets_to_project function to be able to copy assets with folders to the temporary project root
Fixed an issue in LyTestTools where the temporary log directory could have shutil.rmtree being called twice on it leading to an exception which fails an automated test

Updated the asset_procesor_gui_tests_2 AddScanFolder test to not use the
output prefix, but instead place the source asset root into a
subdirectory

* Correct the AssetProcessorPlatformConfig Scan Folders for the EngineAssets directory to point at the Assets directory

* Updated the asset procesor batch dependency test scan folder to point at the 'Assets' folder instead of 'EngineAssets'
2021-04-28 21:38:43 -05:00

2385 lines
122 KiB
C++

/*
* 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 <AzCore/std/smart_ptr/unique_ptr.h>
#include <AzToolsFramework/API/AssetDatabaseBus.h>
#include <native/tests/AssetProcessorTest.h>
#include <native/AssetDatabase/AssetDatabase.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;
class AssetDatabaseTestMockDatabaseLocationListener : public AzToolsFramework::AssetDatabase::AssetDatabaseRequests::Bus::Handler
{
public:
MOCK_METHOD1(GetAssetDatabaseLocation, bool(AZStd::string&));
};
class AssetDatabaseTest : public AssetProcessorTest
{
public:
void SetUp() override
{
AssetProcessorTest::SetUp();
m_data.reset(new StaticData());
m_data->m_databaseLocation = ":memory:"; // this special string causes SQLITE to open the database in memory and not touch disk at all.
m_data->m_databaseLocationListener.BusConnect();
ON_CALL(m_data->m_databaseLocationListener, GetAssetDatabaseLocation(_))
.WillByDefault(
DoAll( // set the 0th argument ref (string) to the database location and return true.
SetArgReferee<0>(":memory:"),
Return(true)));
// Initialize the database:
m_data->m_connection.ClearData(); // this is expected to reset/clear/reopen
}
void TearDown() override
{
m_data->m_databaseLocationListener.BusDisconnect();
m_data.reset();
AssetProcessorTest::TearDown();
}
// COVERAGE TEST
// For each of these coverage tests we'll start with the same kind of database, one with
// SCAN FOLDER: rootportkey
// SOURCE: somefile.tif
// JOB: "some job key" runkey: 1 "pc" SUCCEEDED
// Product: "someproduct1.dds" subid: 1
// Product: "someproduct2.dds" subid: 2
// SOURCE: otherfile.tif
// JOB: "some other job key" runkey: 2 "osx" FAILED
// Product: "someproduct3.dds" subid: 3
// Product: "someproduct4.dds" subid: 4
void CreateCoverageTestData()
{
m_data->m_scanFolder = { "c:/O3DE/dev", "dev", "rootportkey" };
ASSERT_TRUE(m_data->m_connection.SetScanFolder(m_data->m_scanFolder));
m_data->m_sourceFile1 = { m_data->m_scanFolder.m_scanFolderID, "somefile.tif", AZ::Uuid::CreateRandom(), "AnalysisFingerprint1"};
m_data->m_sourceFile2 = { m_data->m_scanFolder.m_scanFolderID, "otherfile.tif", AZ::Uuid::CreateRandom(), "AnalysisFingerprint2"};
ASSERT_TRUE(m_data->m_connection.SetSource(m_data->m_sourceFile1));
ASSERT_TRUE(m_data->m_connection.SetSource(m_data->m_sourceFile2));
m_data->m_job1 = { m_data->m_sourceFile1.m_sourceID, "some job key", 123, "pc", AZ::Uuid::CreateRandom(), AzToolsFramework::AssetSystem::JobStatus::Completed, 1 };
m_data->m_job2 = { m_data->m_sourceFile2.m_sourceID, "some other job key", 345, "osx", AZ::Uuid::CreateRandom(), AzToolsFramework::AssetSystem::JobStatus::Failed, 2 };
ASSERT_TRUE(m_data->m_connection.SetJob(m_data->m_job1));
ASSERT_TRUE(m_data->m_connection.SetJob(m_data->m_job2));
m_data->m_product1 = { m_data->m_job1.m_jobID, 1, "someproduct1.dds", AZ::Data::AssetType::CreateRandom() };
m_data->m_product2 = { m_data->m_job1.m_jobID, 2, "someproduct2.dds", AZ::Data::AssetType::CreateRandom() };
m_data->m_product3 = { m_data->m_job2.m_jobID, 3, "someproduct3.dds", AZ::Data::AssetType::CreateRandom() };
m_data->m_product4 = { m_data->m_job2.m_jobID, 4, "someproduct4.dds", AZ::Data::AssetType::CreateRandom() };
ASSERT_TRUE(m_data->m_connection.SetProduct(m_data->m_product1));
ASSERT_TRUE(m_data->m_connection.SetProduct(m_data->m_product2));
ASSERT_TRUE(m_data->m_connection.SetProduct(m_data->m_product3));
ASSERT_TRUE(m_data->m_connection.SetProduct(m_data->m_product4));
}
protected:
void SetAndCheckMissingDependency(
AzToolsFramework::AssetDatabase::MissingProductDependencyDatabaseEntry& updatedMissingDependency,
const AzToolsFramework::AssetDatabase::MissingProductDependencyDatabaseEntry& originalMissingDependency);
struct StaticData
{
// 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<AssetDatabaseTestMockDatabaseLocationListener> m_databaseLocationListener;
AssetProcessor::AssetDatabaseConnection m_connection;
// 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;
SourceDatabaseEntry m_sourceFile1;
SourceDatabaseEntry m_sourceFile2;
JobDatabaseEntry m_job1;
JobDatabaseEntry m_job2;
ProductDatabaseEntry m_product1;
ProductDatabaseEntry m_product2;
ProductDatabaseEntry m_product3;
ProductDatabaseEntry m_product4;
};
// 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;
};
TEST_F(AssetDatabaseTest, UpdateJob_Succeeds)
{
using namespace AzToolsFramework::AssetDatabase;
CreateCoverageTestData();
m_data->m_job1.m_warningCount = 11;
m_data->m_job1.m_errorCount = 22;
ASSERT_TRUE(m_data->m_connection.SetJob(m_data->m_job1));
JobDatabaseEntryContainer jobs;
ASSERT_TRUE(m_data->m_connection.GetJobsBySourceID(m_data->m_job1.m_sourcePK, jobs));
ASSERT_EQ(jobs.size(), 1);
ASSERT_EQ(m_data->m_job1, jobs[0]);
}
TEST_F(AssetDatabaseTest, GetProducts_WithEmptyDatabase_Fails_ReturnsNoProducts)
{
ProductDatabaseEntryContainer products;
EXPECT_FALSE(m_data->m_connection.GetProducts(products));
EXPECT_EQ(products.size(), 0);
}
TEST_F(AssetDatabaseTest, GetProductByProductID_NotFound_Fails_ReturnsNoProducts)
{
AzToolsFramework::AssetDatabase::ProductDatabaseEntry product;
EXPECT_FALSE(m_data->m_connection.GetProductByProductID(3443, product));
EXPECT_EQ(product, AzToolsFramework::AssetDatabase::ProductDatabaseEntry());
}
TEST_F(AssetDatabaseTest, GetProductsLikeProductName_NotFound_Fails_ReturnsNoProducts)
{
ProductDatabaseEntryContainer products;
EXPECT_FALSE(m_data->m_connection.GetProductsLikeProductName("none", AzToolsFramework::AssetDatabase::AssetDatabaseConnection::Raw, products));
EXPECT_EQ(products.size(), 0);
EXPECT_FALSE(m_data->m_connection.GetProductsLikeProductName("none", AzToolsFramework::AssetDatabase::AssetDatabaseConnection::StartsWith, products));
EXPECT_EQ(products.size(), 0);
EXPECT_FALSE(m_data->m_connection.GetProductsLikeProductName("none", AzToolsFramework::AssetDatabase::AssetDatabaseConnection::EndsWith, products));
EXPECT_EQ(products.size(), 0);
EXPECT_FALSE(m_data->m_connection.GetProductsLikeProductName("none", AzToolsFramework::AssetDatabase::AssetDatabaseConnection::Matches, products));
EXPECT_EQ(products.size(), 0);
}
TEST_F(AssetDatabaseTest, GetProductsBySourceID_NotFound_Fails_ReturnsNoProducts)
{
ProductDatabaseEntryContainer products;
EXPECT_FALSE(m_data->m_connection.GetProductsBySourceID(25654, products));
EXPECT_EQ(products.size(), 0);
}
TEST_F(AssetDatabaseTest, SetProduct_InvalidProductID_Fails)
{
// trying to "overwrite" a product that does not exist should fail and emit error.
AZ::Data::AssetType validAssetType1 = AZ::Data::AssetType::CreateRandom();
ProductDatabaseEntry product { 123213, 234234, 1, "SomeProduct1.dds", validAssetType1 };
m_errorAbsorber->Clear();
EXPECT_FALSE(m_data->m_connection.SetProduct(product));
EXPECT_GT(m_errorAbsorber->m_numErrorsAbsorbed, 0);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
// make sure it didn't actually touch the db as a side effect:
ProductDatabaseEntryContainer products;
EXPECT_FALSE(m_data->m_connection.GetProducts(products));
EXPECT_EQ(products.size(), 0);
}
TEST_F(AssetDatabaseTest, SetProduct_InvalidJobPK_Fails)
{
AZ::Data::AssetType validAssetType1 = AZ::Data::AssetType::CreateRandom();
// -1 means insert a new product, but the JobPK is an enforced FK constraint, so this should fail since there
// won't be a Job with the PK of 234234.
ProductDatabaseEntry product{ AzToolsFramework::AssetDatabase::InvalidEntryId, 234234, 1, "SomeProduct1.dds", validAssetType1 };
m_errorAbsorber->Clear();
EXPECT_FALSE(m_data->m_connection.SetProduct(product));
EXPECT_GT(m_errorAbsorber->m_numErrorsAbsorbed, 0);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
// make sure it didn't actually touch the db as a side effect:
ProductDatabaseEntryContainer products;
EXPECT_FALSE(m_data->m_connection.GetProducts(products));
EXPECT_EQ(products.size(), 0);
}
// if we give it a valid command and a -1 product, we expect it to succeed without assert or warning
// and we expect it to tell us (by filling in the entry) what the new PK is.
TEST_F(AssetDatabaseTest, SetProduct_AutoPK_Succeeds)
{
AZ::Data::AssetType validAssetType1 = AZ::Data::AssetType::CreateRandom();
// to add a product legitimately you have to have a full chain of primary keys, chain is:
// ScanFolder --> Source --> job --> product.
// we'll create all of those first (except product) before starting the product test.
//add a scanfolder. None of this has to exist in real disk, this is a db test only.
ScanFolderDatabaseEntry scanFolder{ "c:/O3DE/dev", "dev", "rootportkey" };
EXPECT_TRUE(m_data->m_connection.SetScanFolder(scanFolder));
ASSERT_NE(scanFolder.m_scanFolderID, AzToolsFramework::AssetDatabase::InvalidEntryId);
SourceDatabaseEntry sourceEntry {scanFolder.m_scanFolderID, "somefile.tif", AZ::Uuid::CreateRandom(), "fingerprint1"};
EXPECT_TRUE(m_data->m_connection.SetSource(sourceEntry));
ASSERT_NE(sourceEntry.m_sourceID, AzToolsFramework::AssetDatabase::InvalidEntryId);
JobDatabaseEntry jobEntry{ sourceEntry.m_sourceID, "some job key", 123, "pc", AZ::Uuid::CreateRandom(), AzToolsFramework::AssetSystem::JobStatus::Completed, 1 };
EXPECT_TRUE(m_data->m_connection.SetJob(jobEntry));
ASSERT_NE(jobEntry.m_jobID, AzToolsFramework::AssetDatabase::InvalidEntryId);
// --- set up complete --- perform the test!
ProductDatabaseEntry product{ AzToolsFramework::AssetDatabase::InvalidEntryId, jobEntry.m_jobID, 1, "SomeProduct1.dds", validAssetType1 };
m_errorAbsorber->Clear();
EXPECT_TRUE(m_data->m_connection.SetProduct(product));
ASSERT_NE(product.m_productID, AzToolsFramework::AssetDatabase::InvalidEntryId);
EXPECT_EQ(m_errorAbsorber->m_numErrorsAbsorbed, 0);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
// read it back from the DB and make sure its identical to what was written
ProductDatabaseEntry productFromDB;
EXPECT_TRUE(m_data->m_connection.GetProductByProductID(product.m_productID, productFromDB));
ASSERT_EQ(product, productFromDB);
}
// update an existing job by giving it a specific PK of a known existing item.
TEST_F(AssetDatabaseTest, SetProduct_SpecificPK_Succeeds_DifferentSubID)
{
AZ::Data::AssetType validAssetType1 = AZ::Data::AssetType::CreateRandom();
// to add a product legitimately you have to have a full chain of primary keys, chain is:
// ScanFolder --> Source --> job --> product.
// we'll create all of those first (except product) before starting the product test.
ScanFolderDatabaseEntry scanFolder{ "c:/O3DE/dev", "dev", "rootportkey" };
ASSERT_TRUE(m_data->m_connection.SetScanFolder(scanFolder));
SourceDatabaseEntry sourceEntry{ scanFolder.m_scanFolderID, "somefile.tif", AZ::Uuid::CreateRandom(), "fingerprint1" };
ASSERT_TRUE(m_data->m_connection.SetSource(sourceEntry));
// two different job entries.
JobDatabaseEntry jobEntry{ sourceEntry.m_sourceID, "some job key", 123, "pc", AZ::Uuid::CreateRandom(), AzToolsFramework::AssetSystem::JobStatus::Completed, 1 };
JobDatabaseEntry jobEntry2{ sourceEntry.m_sourceID, "some job key 2", 345, "pc", AZ::Uuid::CreateRandom(), AzToolsFramework::AssetSystem::JobStatus::Completed, 2 };
ASSERT_TRUE(m_data->m_connection.SetJob(jobEntry));
ASSERT_TRUE(m_data->m_connection.SetJob(jobEntry2));
ProductDatabaseEntry product{ AzToolsFramework::AssetDatabase::InvalidEntryId, jobEntry.m_jobID, 1, "SomeProduct1.dds", validAssetType1 };
ASSERT_TRUE(m_data->m_connection.SetProduct(product));
// --- set up complete --- perform the test!
// update all the fields of that product and then write it to the db.
ProductDatabaseEntry newProductData = product; // copy first
// now change all the fields:
newProductData.m_assetType = AZ::Uuid::CreateRandom();
newProductData.m_productName = "different name.dds";
newProductData.m_subID = 2;
newProductData.m_jobPK = jobEntry2.m_jobID; // move it to the other job, too!
// update the product
EXPECT_TRUE(m_data->m_connection.SetProduct(newProductData));
ASSERT_NE(newProductData.m_productID, AzToolsFramework::AssetDatabase::InvalidEntryId);
// it should not have entered a new product but instead overwritten the old one.
ASSERT_EQ(product.m_productID, newProductData.m_productID);
// read it back from DB and verify:
ProductDatabaseEntry productFromDB;
EXPECT_TRUE(m_data->m_connection.GetProductByProductID(newProductData.m_productID, productFromDB));
ASSERT_EQ(newProductData, productFromDB);
ProductDatabaseEntryContainer products;
EXPECT_TRUE(m_data->m_connection.GetProducts(products));
EXPECT_EQ(products.size(), 1);
}
// update an existing job by giving it a subID and JobID which is enough to uniquely identify a product (since products may not have the same subid from the same job).
// this is actually a very common case (same job id, same subID)
TEST_F(AssetDatabaseTest, SetProduct_SpecificPK_Succeeds_SameSubID_SameJobID)
{
ScanFolderDatabaseEntry scanFolder{ "c:/O3DE/dev", "dev", "rootportkey"};
ASSERT_TRUE(m_data->m_connection.SetScanFolder(scanFolder));
SourceDatabaseEntry sourceEntry{ scanFolder.m_scanFolderID, "somefile.tif", AZ::Uuid::CreateRandom(), "fingerprint1" };
ASSERT_TRUE(m_data->m_connection.SetSource(sourceEntry));
JobDatabaseEntry jobEntry{ sourceEntry.m_sourceID, "some job key", 123, "pc", AZ::Uuid::CreateRandom(), AzToolsFramework::AssetSystem::JobStatus::Completed, 1 };
ASSERT_TRUE(m_data->m_connection.SetJob(jobEntry));
ProductDatabaseEntry product{ AzToolsFramework::AssetDatabase::InvalidEntryId, jobEntry.m_jobID, 1, "SomeProduct1.dds", AZ::Data::AssetType::CreateRandom() };
ASSERT_TRUE(m_data->m_connection.SetProduct(product));
// --- set up complete --- perform the test!
// update all the fields of that product and then write it to the db.
ProductDatabaseEntry newProductData = product; // copy first
// now change all the fields:
newProductData.m_assetType = AZ::Uuid::CreateRandom();
newProductData.m_productName = "different name.dds";
newProductData.m_productID = AzToolsFramework::AssetDatabase::InvalidEntryId; // wipe out the product ID, so that we can make sure it returns it.
// we don't change the subID here or the job ID.
// update the product
EXPECT_TRUE(m_data->m_connection.SetProduct(newProductData));
ASSERT_NE(newProductData.m_productID, AzToolsFramework::AssetDatabase::InvalidEntryId);
// it should not have entered a new product but instead overwritten the old one.
EXPECT_EQ(product.m_productID, newProductData.m_productID);
// read it back from DB and verify:
ProductDatabaseEntry productFromDB;
EXPECT_TRUE(m_data->m_connection.GetProductByProductID(newProductData.m_productID, productFromDB));
EXPECT_EQ(newProductData, productFromDB);
ProductDatabaseEntryContainer products;
EXPECT_TRUE(m_data->m_connection.GetProducts(products));
EXPECT_EQ(products.size(), 1);
}
TEST_F(AssetDatabaseTest, GetProductsByJobID_InvalidID_NotFound_ReturnsFalse)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_FALSE(m_data->m_connection.GetProductsByJobID(-1, resultProducts));
EXPECT_EQ(resultProducts.size(), 0);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsByJobID_Valid_ReturnsTrue_FindsProducts)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_TRUE(m_data->m_connection.GetProductsByJobID(m_data->m_job1.m_jobID, resultProducts));
EXPECT_EQ(resultProducts.size(), 2); // should have found the first two products.
// since there is no ordering, we just have to find both of them:
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product1), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product2), resultProducts.end());
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductByJobIDSubId_InvalidID_NotFound_ReturnsFalse)
{
CreateCoverageTestData();
ProductDatabaseEntry resultProduct;
EXPECT_FALSE(m_data->m_connection.GetProductByJobIDSubId(m_data->m_job1.m_jobID, aznumeric_caster(-1), resultProduct));
EXPECT_FALSE(m_data->m_connection.GetProductByJobIDSubId(-1, m_data->m_product1.m_subID, resultProduct));
EXPECT_FALSE(m_data->m_connection.GetProductByJobIDSubId(-1, aznumeric_caster(-1), resultProduct));
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductByJobIDSubId_ValidID_Found_ReturnsTrue)
{
CreateCoverageTestData();
ProductDatabaseEntry resultProduct;
EXPECT_TRUE(m_data->m_connection.GetProductByJobIDSubId(m_data->m_job1.m_jobID, m_data->m_product1.m_subID, resultProduct));
EXPECT_EQ(resultProduct, m_data->m_product1);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductBySourceGuidSubId_InvalidInputs_ProductNotFound)
{
CreateCoverageTestData();
ProductDatabaseEntry resultProduct;
AZ::Uuid invalidGuid = AZ::Uuid::CreateNull();
AZ::s32 invalidSubId = -1;
EXPECT_FALSE(m_data->m_connection.GetProductBySourceGuidSubId(invalidGuid, m_data->m_product1.m_subID, resultProduct));
EXPECT_FALSE(m_data->m_connection.GetProductBySourceGuidSubId(m_data->m_sourceFile1.m_sourceGuid, invalidSubId, resultProduct));
EXPECT_FALSE(m_data->m_connection.GetProductBySourceGuidSubId(invalidGuid, invalidSubId, resultProduct));
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0);
}
TEST_F(AssetDatabaseTest, GetProductBySourceGuidSubId_ValidInputs_ProductFound)
{
CreateCoverageTestData();
ProductDatabaseEntry resultProduct;
EXPECT_TRUE(m_data->m_connection.GetProductBySourceGuidSubId(m_data->m_sourceFile1.m_sourceGuid, m_data->m_product1.m_subID, resultProduct));
EXPECT_EQ(resultProduct, m_data->m_product1);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0);
}
// --------------------------------------------------------------------------------------------------------------------
// ------------------------------------------ GetProductsByProductName ------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
TEST_F(AssetDatabaseTest, GetProductsByProductName_EmptyString_NoResults)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_FALSE(m_data->m_connection.GetProductsByProductName(QString(), resultProducts));
EXPECT_EQ(resultProducts.size(), 0);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsByProductName_NotFound_NoResult)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_FALSE(m_data->m_connection.GetProductsByProductName("akdsuhuksahdsak", resultProducts));
EXPECT_EQ(resultProducts.size(), 0);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsByProductName_CorrectName_ReturnsCorrectResult)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_TRUE(m_data->m_connection.GetProductsByProductName("someproduct4.dds", resultProducts));
EXPECT_EQ(resultProducts.size(), 1);
EXPECT_EQ(resultProducts[0], m_data->m_product4);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
// tests all of the filters (beside name) to make sure they all function as expected.
TEST_F(AssetDatabaseTest, GetProductsByProductName_FilterTest_BuilderGUID)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
// give it a random builder guid. This should make it not match any products:
EXPECT_FALSE(m_data->m_connection.GetProductsByProductName("someproduct4.dds", resultProducts, AZ::Uuid::CreateRandom()));
EXPECT_EQ(resultProducts.size(), 0);
// give it a correct builder guid but the wrong builder. Job2's builder actually built product4.
EXPECT_FALSE(m_data->m_connection.GetProductsByProductName("someproduct4.dds", resultProducts, m_data->m_job1.m_builderGuid));
EXPECT_EQ(resultProducts.size(), 0);
// give it correct data
EXPECT_TRUE(m_data->m_connection.GetProductsByProductName("someproduct4.dds", resultProducts, m_data->m_job2.m_builderGuid));
EXPECT_EQ(resultProducts.size(), 1);
EXPECT_EQ(resultProducts[0], m_data->m_product4);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsByProductName_FilterTest_JobKey)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
// give it a random job key that is not going to match the existing job keys. This should make it not match any products:
EXPECT_FALSE(m_data->m_connection.GetProductsByProductName("someproduct4.dds", resultProducts, AZ::Uuid::CreateNull(), "no matcher"));
EXPECT_EQ(resultProducts.size(), 0);
// give it a correct job key but not one that output that product.
EXPECT_FALSE(m_data->m_connection.GetProductsByProductName("someproduct4.dds", resultProducts, AZ::Uuid::CreateNull(), QString(m_data->m_job1.m_jobKey.c_str())));
EXPECT_EQ(resultProducts.size(), 0);
// give it correct data
EXPECT_TRUE(m_data->m_connection.GetProductsByProductName("someproduct4.dds", resultProducts, AZ::Uuid::CreateNull(), QString(m_data->m_job2.m_jobKey.c_str())));
EXPECT_EQ(resultProducts.size(), 1);
EXPECT_EQ(resultProducts[0], m_data->m_product4);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsByProductName_FilterTest_Platform)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
// give it a platform that is not going to match the existing job platforms. This should make it not match any products:
EXPECT_FALSE(m_data->m_connection.GetProductsByProductName("someproduct4.dds", resultProducts, AZ::Uuid::CreateNull(), QString(), "badplatform"));
EXPECT_EQ(resultProducts.size(), 0);
// give it a correct platform but not one that output that product.
EXPECT_FALSE(m_data->m_connection.GetProductsByProductName("someproduct4.dds", resultProducts, AZ::Uuid::CreateNull(), QString(), "pc")); // its actually osx
EXPECT_EQ(resultProducts.size(), 0);
// give it correct data
EXPECT_TRUE(m_data->m_connection.GetProductsByProductName("someproduct4.dds", resultProducts, AZ::Uuid::CreateNull(), QString(), "osx"));
EXPECT_EQ(resultProducts.size(), 1);
EXPECT_EQ(resultProducts[0], m_data->m_product4);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsByProductName_FilterTest_Status)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
// give it a correct status but not one that output that product.
EXPECT_FALSE(m_data->m_connection.GetProductsByProductName("someproduct4.dds", resultProducts, AZ::Uuid::CreateNull(), QString(), QString(), AzToolsFramework::AssetSystem::JobStatus::Completed)); // its actually failed
EXPECT_EQ(resultProducts.size(), 0);
// give it correct data
EXPECT_TRUE(m_data->m_connection.GetProductsByProductName("someproduct4.dds", resultProducts, AZ::Uuid::CreateNull(), QString(), QString(), AzToolsFramework::AssetSystem::JobStatus::Failed));
EXPECT_EQ(resultProducts.size(), 1);
EXPECT_EQ(resultProducts[0], m_data->m_product4);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
// --------------------------------------------------------------------------------------------------------------------
// ------------------------------------------ GetProductsLikeProductName ----------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
TEST_F(AssetDatabaseTest, GetProductsLikeProductName_EmptyString_NoResults)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_FALSE(m_data->m_connection.GetProductsLikeProductName(QString(), AssetDatabaseConnection::StartsWith, resultProducts));
EXPECT_EQ(resultProducts.size(), 0);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsLikeProductName_NotFound_NoResult)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_FALSE(m_data->m_connection.GetProductsLikeProductName("akdsuhuksahdsak", AssetDatabaseConnection::StartsWith, resultProducts));
EXPECT_EQ(resultProducts.size(), 0);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsLikeProductName_CorrectName_StartsWith_ReturnsCorrectResult)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_TRUE(m_data->m_connection.GetProductsLikeProductName("someproduct4", AssetDatabaseConnection::StartsWith, resultProducts));
EXPECT_EQ(resultProducts.size(), 1);
EXPECT_EQ(resultProducts[0], m_data->m_product4);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsLikeProductName_CorrectName_EndsWith_ReturnsCorrectResult)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_TRUE(m_data->m_connection.GetProductsLikeProductName("product4.dds", AssetDatabaseConnection::EndsWith, resultProducts));
EXPECT_EQ(resultProducts.size(), 1);
EXPECT_EQ(resultProducts[0], m_data->m_product4);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsLikeProductName_CorrectName_Matches_ReturnsCorrectResult)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_TRUE(m_data->m_connection.GetProductsLikeProductName("product4", AssetDatabaseConnection::Matches, resultProducts));
EXPECT_EQ(resultProducts.size(), 1);
EXPECT_EQ(resultProducts[0], m_data->m_product4);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsLikeProductName_CorrectName_StartsWith_ReturnsMany)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
// a very broad search that matches all products.
EXPECT_TRUE(m_data->m_connection.GetProductsLikeProductName("someproduct", AssetDatabaseConnection::StartsWith, resultProducts));
EXPECT_EQ(resultProducts.size(), 4);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
// tests all of the filters (beside name) to make sure they all function as expected.
TEST_F(AssetDatabaseTest, GetProductsLikeProductName_FilterTest_BuilderGUID)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
// give it a random builder guid. This should make it not match any products:
EXPECT_FALSE(m_data->m_connection.GetProductsLikeProductName("someproduct4", AssetDatabaseConnection::StartsWith, resultProducts, AZ::Uuid::CreateRandom()));
EXPECT_EQ(resultProducts.size(), 0);
// give it a correct builder guid but the wrong builder. Job2's builder actually built product4.
EXPECT_FALSE(m_data->m_connection.GetProductsLikeProductName("someproduct4", AssetDatabaseConnection::StartsWith, resultProducts, m_data->m_job1.m_builderGuid));
EXPECT_EQ(resultProducts.size(), 0);
// give it correct data
EXPECT_TRUE(m_data->m_connection.GetProductsLikeProductName("someproduct4", AssetDatabaseConnection::StartsWith, resultProducts, m_data->m_job2.m_builderGuid));
EXPECT_EQ(resultProducts.size(), 1);
EXPECT_EQ(resultProducts[0], m_data->m_product4);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsLikeProductName_FilterTest_JobKey)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
// give it a random job key that is not going to match the existing job keys. This should make it not match any products:
EXPECT_FALSE(m_data->m_connection.GetProductsLikeProductName("someproduct4", AssetDatabaseConnection::StartsWith, resultProducts, AZ::Uuid::CreateNull(), "no matcher"));
EXPECT_EQ(resultProducts.size(), 0);
// give it a correct job key but not one that output that product.
EXPECT_FALSE(m_data->m_connection.GetProductsLikeProductName("someproduct4", AssetDatabaseConnection::StartsWith, resultProducts, AZ::Uuid::CreateNull(), QString(m_data->m_job1.m_jobKey.c_str())));
EXPECT_EQ(resultProducts.size(), 0);
// give it correct data
EXPECT_TRUE(m_data->m_connection.GetProductsLikeProductName("someproduct4", AssetDatabaseConnection::StartsWith, resultProducts, AZ::Uuid::CreateNull(), QString(m_data->m_job2.m_jobKey.c_str())));
EXPECT_EQ(resultProducts.size(), 1);
EXPECT_EQ(resultProducts[0], m_data->m_product4);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsLikeProductName_FilterTest_Platform)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
// give it a platform that is not going to match the existing job platforms. This should make it not match any products:
EXPECT_FALSE(m_data->m_connection.GetProductsLikeProductName("someproduct4", AssetDatabaseConnection::StartsWith, resultProducts, AZ::Uuid::CreateNull(), QString(), "badplatform"));
EXPECT_EQ(resultProducts.size(), 0);
// give it a correct platform but not one that output that product.
EXPECT_FALSE(m_data->m_connection.GetProductsLikeProductName("someproduct4", AssetDatabaseConnection::StartsWith, resultProducts, AZ::Uuid::CreateNull(), QString(), "pc")); // its actually osx
EXPECT_EQ(resultProducts.size(), 0);
// give it correct data
EXPECT_TRUE(m_data->m_connection.GetProductsLikeProductName("someproduct4", AssetDatabaseConnection::StartsWith, resultProducts, AZ::Uuid::CreateNull(), QString(), "osx"));
EXPECT_EQ(resultProducts.size(), 1);
EXPECT_EQ(resultProducts[0], m_data->m_product4);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsLikeProductName_FilterTest_Status)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
// give it a correct status but not one that output that product.
EXPECT_FALSE(m_data->m_connection.GetProductsLikeProductName("someproduct4", AssetDatabaseConnection::StartsWith, resultProducts, AZ::Uuid::CreateNull(), QString(), QString(), AzToolsFramework::AssetSystem::JobStatus::Completed)); // its actually failed
EXPECT_EQ(resultProducts.size(), 0);
// give it correct data
EXPECT_TRUE(m_data->m_connection.GetProductsLikeProductName("someproduct4", AssetDatabaseConnection::StartsWith, resultProducts, AZ::Uuid::CreateNull(), QString(), QString(), AzToolsFramework::AssetSystem::JobStatus::Failed));
EXPECT_EQ(resultProducts.size(), 1);
EXPECT_EQ(resultProducts[0], m_data->m_product4);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
// --------------------------------------------------------------------------------------------------------------------
// --------------------------------------------- GetProductsBySourceID ------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
TEST_F(AssetDatabaseTest, GetProductsBySourceID_NotFound_NoResult)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_FALSE(m_data->m_connection.GetProductsBySourceID(-1, resultProducts));
EXPECT_EQ(resultProducts.size(), 0);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsBySourceID_CorrectID_ReturnsCorrectResult)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_TRUE(m_data->m_connection.GetProductsBySourceID(m_data->m_sourceFile1.m_sourceID, resultProducts));
EXPECT_EQ(resultProducts.size(), 2);
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product1), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product2), resultProducts.end());
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
// tests all of the filters (beside name) to make sure they all function as expected.
TEST_F(AssetDatabaseTest, GetProductsBySourceID_FilterTest_BuilderGUID)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
// give it a random builder guid. This should make it not match any products:
EXPECT_FALSE(m_data->m_connection.GetProductsBySourceID(m_data->m_sourceFile1.m_sourceID, resultProducts, AZ::Uuid::CreateRandom()));
EXPECT_EQ(resultProducts.size(), 0);
// give it a valid data, but the wrong one. Note that job2 was the one that built the other files, not the sourcefile1.
EXPECT_FALSE(m_data->m_connection.GetProductsBySourceID(m_data->m_sourceFile1.m_sourceID, resultProducts, m_data->m_job2.m_builderGuid));
EXPECT_EQ(resultProducts.size(), 0);
// give it correct data
EXPECT_TRUE(m_data->m_connection.GetProductsBySourceID(m_data->m_sourceFile1.m_sourceID, resultProducts, m_data->m_job1.m_builderGuid));
EXPECT_EQ(resultProducts.size(), 2);
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product1), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product2), resultProducts.end());
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsBySourceID_FilterTest_JobKey)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
// give it invalid data that won't match anything
EXPECT_FALSE(m_data->m_connection.GetProductsBySourceID(m_data->m_sourceFile1.m_sourceID, resultProducts, AZ::Uuid::CreateNull(), "no matcher"));
EXPECT_EQ(resultProducts.size(), 0);
// give it a valid data, but the wrong one:
EXPECT_FALSE(m_data->m_connection.GetProductsBySourceID(m_data->m_sourceFile1.m_sourceID, resultProducts, AZ::Uuid::CreateNull(), QString(m_data->m_job2.m_jobKey.c_str())));
EXPECT_EQ(resultProducts.size(), 0);
// give it correct data
EXPECT_TRUE(m_data->m_connection.GetProductsBySourceID(m_data->m_sourceFile1.m_sourceID, resultProducts, AZ::Uuid::CreateNull(), QString(m_data->m_job1.m_jobKey.c_str())));
EXPECT_EQ(resultProducts.size(), 2);
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product1), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product2), resultProducts.end());
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsBySourceID_FilterTest_Platform)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
// give it invalid data that won't match anything
EXPECT_FALSE(m_data->m_connection.GetProductsBySourceID(m_data->m_sourceFile1.m_sourceID, resultProducts, AZ::Uuid::CreateNull(), QString(), "badplatform"));
EXPECT_EQ(resultProducts.size(), 0);
// give it a valid data, but the wrong one:
EXPECT_FALSE(m_data->m_connection.GetProductsBySourceID(m_data->m_sourceFile1.m_sourceID, resultProducts, AZ::Uuid::CreateNull(), QString(), "osx")); // its actually pc
EXPECT_EQ(resultProducts.size(), 0);
// give it correct data
EXPECT_TRUE(m_data->m_connection.GetProductsBySourceID(m_data->m_sourceFile1.m_sourceID, resultProducts, AZ::Uuid::CreateNull(), QString(), "pc"));
EXPECT_EQ(resultProducts.size(), 2);
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product1), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product2), resultProducts.end());
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsBySourceID_FilterTest_Status)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
// give it a valid data, but the wrong one:
EXPECT_FALSE(m_data->m_connection.GetProductsBySourceID(m_data->m_sourceFile1.m_sourceID, resultProducts, AZ::Uuid::CreateNull(), QString(), QString(), AzToolsFramework::AssetSystem::JobStatus::Failed)); // its actually completed
EXPECT_EQ(resultProducts.size(), 0);
// give it correct data
EXPECT_TRUE(m_data->m_connection.GetProductsBySourceID(m_data->m_sourceFile1.m_sourceID, resultProducts, AZ::Uuid::CreateNull(), QString(), QString(), AzToolsFramework::AssetSystem::JobStatus::Completed));
EXPECT_EQ(resultProducts.size(), 2);
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product1), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product2), resultProducts.end());
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
// --------------------------------------------------------------------------------------------------------------------
// -------------------------------------------- GetProductsBySourceName -----------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
TEST_F(AssetDatabaseTest, GetProductsBySourceName_EmptyString_NoResult)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_FALSE(m_data->m_connection.GetProductsBySourceName(QString(), resultProducts));
EXPECT_EQ(resultProducts.size(), 0);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsBySourceName_NotFound_NoResult)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_FALSE(m_data->m_connection.GetProductsBySourceName("blahrga", resultProducts));
EXPECT_EQ(resultProducts.size(), 0);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsBySourceName_CorrectName_ReturnsCorrectResult)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_TRUE(m_data->m_connection.GetProductsBySourceName("somefile.tif", resultProducts)); // this is source1, which results in product1 and product2 via job1
EXPECT_EQ(resultProducts.size(), 2);
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product1), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product2), resultProducts.end());
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
// tests all of the filters (beside name) to make sure they all function as expected.
TEST_F(AssetDatabaseTest, GetProductsBySourceName_FilterTest_BuilderGUID)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
// give it a random builder guid. This should make it not match any products:
EXPECT_FALSE(m_data->m_connection.GetProductsBySourceName("somefile.tif", resultProducts, AZ::Uuid::CreateRandom()));
EXPECT_EQ(resultProducts.size(), 0);
// give it a valid data, but the wrong one. Note that job2 was the one that built the other files, not the sourcefile1.
EXPECT_FALSE(m_data->m_connection.GetProductsBySourceName("somefile.tif", resultProducts, m_data->m_job2.m_builderGuid));
EXPECT_EQ(resultProducts.size(), 0);
// give it correct data
EXPECT_TRUE(m_data->m_connection.GetProductsBySourceName("somefile.tif", resultProducts, m_data->m_job1.m_builderGuid));
EXPECT_EQ(resultProducts.size(), 2);
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product1), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product2), resultProducts.end());
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsBySourceName_FilterTest_JobKey)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
// give it invalid data that won't match anything
EXPECT_FALSE(m_data->m_connection.GetProductsBySourceName("somefile.tif", resultProducts, AZ::Uuid::CreateNull(), "no matcher"));
EXPECT_EQ(resultProducts.size(), 0);
// give it a valid data, but the wrong one:
EXPECT_FALSE(m_data->m_connection.GetProductsBySourceName("somefile.tif", resultProducts, AZ::Uuid::CreateNull(), QString(m_data->m_job2.m_jobKey.c_str())));
EXPECT_EQ(resultProducts.size(), 0);
// give it correct data
EXPECT_TRUE(m_data->m_connection.GetProductsBySourceName("somefile.tif", resultProducts, AZ::Uuid::CreateNull(), QString(m_data->m_job1.m_jobKey.c_str())));
EXPECT_EQ(resultProducts.size(), 2);
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product1), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product2), resultProducts.end());
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsBySourceName_FilterTest_Platform)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
// give it invalid data that won't match anything
EXPECT_FALSE(m_data->m_connection.GetProductsBySourceName("somefile.tif", resultProducts, AZ::Uuid::CreateNull(), QString(), "badplatform"));
EXPECT_EQ(resultProducts.size(), 0);
// give it a valid data, but the wrong one:
EXPECT_FALSE(m_data->m_connection.GetProductsBySourceName("somefile.tif", resultProducts, AZ::Uuid::CreateNull(), QString(), "osx")); // its actually pc
EXPECT_EQ(resultProducts.size(), 0);
// give it correct data
EXPECT_TRUE(m_data->m_connection.GetProductsBySourceName("somefile.tif", resultProducts, AZ::Uuid::CreateNull(), QString(), "pc"));
EXPECT_EQ(resultProducts.size(), 2);
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product1), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product2), resultProducts.end());
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsBySourceName_FilterTest_Status)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
// give it a valid data, but the wrong one:
EXPECT_FALSE(m_data->m_connection.GetProductsBySourceName("somefile.tif", resultProducts, AZ::Uuid::CreateNull(), QString(), QString(), AzToolsFramework::AssetSystem::JobStatus::Failed)); // its actually completed
EXPECT_EQ(resultProducts.size(), 0);
// give it correct data
EXPECT_TRUE(m_data->m_connection.GetProductsBySourceName("somefile.tif", resultProducts, AZ::Uuid::CreateNull(), QString(), QString(), AzToolsFramework::AssetSystem::JobStatus::Completed));
EXPECT_EQ(resultProducts.size(), 2);
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product1), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product2), resultProducts.end());
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
// --------------------------------------------------------------------------------------------------------------------
// -------------------------------------------- GetProductsLikeSourceName ---------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
TEST_F(AssetDatabaseTest, GetProductsLikeSourceName_EmptyString_NoResult)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_FALSE(m_data->m_connection.GetProductsLikeSourceName(QString(), AzToolsFramework::AssetDatabase::AssetDatabaseConnection::Raw, resultProducts));
EXPECT_EQ(resultProducts.size(), 0);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsLikeSourceName_NotFound_NoResult)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_FALSE(m_data->m_connection.GetProductsLikeSourceName("blahrga", AzToolsFramework::AssetDatabase::AssetDatabaseConnection::Raw, resultProducts));
EXPECT_EQ(resultProducts.size(), 0);
// this matches the end of a legit string, but we are using startswith, so it should NOT MATCH
EXPECT_FALSE(m_data->m_connection.GetProductsLikeSourceName("file.tif", AzToolsFramework::AssetDatabase::AssetDatabaseConnection::StartsWith, resultProducts));
EXPECT_EQ(resultProducts.size(), 0);
// this matches the startswith, but should NOT MATCH, because its asking for things that end with it.
EXPECT_FALSE(m_data->m_connection.GetProductsLikeSourceName("somefile", AzToolsFramework::AssetDatabase::AssetDatabaseConnection::EndsWith, resultProducts));
EXPECT_EQ(resultProducts.size(), 0);
// make sure invalid tokens do not crash it or something
EXPECT_FALSE(m_data->m_connection.GetProductsLikeSourceName("%%%%%blahrga%%%%%", AzToolsFramework::AssetDatabase::AssetDatabaseConnection::Matches, resultProducts));
EXPECT_EQ(resultProducts.size(), 0);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsLikeSourceName_StartsWith_CorrectName_ReturnsCorrectResult)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_TRUE(m_data->m_connection.GetProductsLikeSourceName("somefile", AzToolsFramework::AssetDatabase::AssetDatabaseConnection::StartsWith, resultProducts)); // this is source1, which results in product1 and product2 via job1
EXPECT_EQ(resultProducts.size(), 2);
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product1), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product2), resultProducts.end());
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsLikeSourceName_EndsWith_CorrectName_ReturnsCorrectResult)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_TRUE(m_data->m_connection.GetProductsLikeSourceName("omefile.tif", AzToolsFramework::AssetDatabase::AssetDatabaseConnection::EndsWith, resultProducts)); // this is source1, which results in product1 and product2 via job1
EXPECT_EQ(resultProducts.size(), 2);
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product1), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product2), resultProducts.end());
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsLikeSourceName_Matches_CorrectName_ReturnsCorrectResult)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_TRUE(m_data->m_connection.GetProductsLikeSourceName("omefile", AzToolsFramework::AssetDatabase::AssetDatabaseConnection::Matches, resultProducts)); // this is source1, which results in product1 and product2 via job1
EXPECT_EQ(resultProducts.size(), 2);
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product1), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product2), resultProducts.end());
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
// tests all of the filters (beside name) to make sure they all function as expected.
TEST_F(AssetDatabaseTest, GetProductsLikeSourceName_FilterTest_BuilderGUID)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
// give it a random builder guid. This should make it not match any products:
EXPECT_FALSE(m_data->m_connection.GetProductsLikeSourceName("somefile", AzToolsFramework::AssetDatabase::AssetDatabaseConnection::StartsWith, resultProducts, AZ::Uuid::CreateRandom()));
EXPECT_EQ(resultProducts.size(), 0);
// give it a valid data, but the wrong one. Note that job2 was the one that built the other files, not the sourcefile1.
EXPECT_FALSE(m_data->m_connection.GetProductsLikeSourceName("somefile", AzToolsFramework::AssetDatabase::AssetDatabaseConnection::StartsWith, resultProducts, m_data->m_job2.m_builderGuid));
EXPECT_EQ(resultProducts.size(), 0);
// give it correct data
EXPECT_TRUE(m_data->m_connection.GetProductsLikeSourceName("somefile", AzToolsFramework::AssetDatabase::AssetDatabaseConnection::StartsWith, resultProducts, m_data->m_job1.m_builderGuid));
EXPECT_EQ(resultProducts.size(), 2);
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product1), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product2), resultProducts.end());
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsLikeSourceName_FilterTest_JobKey)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
// give it invalid data that won't match anything
EXPECT_FALSE(m_data->m_connection.GetProductsLikeSourceName("somefile", AzToolsFramework::AssetDatabase::AssetDatabaseConnection::StartsWith, resultProducts, AZ::Uuid::CreateNull(), "no matcher"));
EXPECT_EQ(resultProducts.size(), 0);
// give it a valid data, but the wrong one:
EXPECT_FALSE(m_data->m_connection.GetProductsLikeSourceName("somefile", AzToolsFramework::AssetDatabase::AssetDatabaseConnection::StartsWith, resultProducts, AZ::Uuid::CreateNull(), QString(m_data->m_job2.m_jobKey.c_str())));
EXPECT_EQ(resultProducts.size(), 0);
// give it correct data
EXPECT_TRUE(m_data->m_connection.GetProductsLikeSourceName("somefile", AzToolsFramework::AssetDatabase::AssetDatabaseConnection::StartsWith, resultProducts, AZ::Uuid::CreateNull(), QString(m_data->m_job1.m_jobKey.c_str())));
EXPECT_EQ(resultProducts.size(), 2);
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product1), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product2), resultProducts.end());
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsLikeSourceName_FilterTest_Platform)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
// give it invalid data that won't match anything
EXPECT_FALSE(m_data->m_connection.GetProductsLikeSourceName("somefile", AzToolsFramework::AssetDatabase::AssetDatabaseConnection::StartsWith, resultProducts, AZ::Uuid::CreateNull(), QString(), "badplatform"));
EXPECT_EQ(resultProducts.size(), 0);
// give it a valid data, but the wrong one:
EXPECT_FALSE(m_data->m_connection.GetProductsLikeSourceName("somefile", AzToolsFramework::AssetDatabase::AssetDatabaseConnection::StartsWith, resultProducts, AZ::Uuid::CreateNull(), QString(), "osx")); // its actually pc
EXPECT_EQ(resultProducts.size(), 0);
// give it correct data
EXPECT_TRUE(m_data->m_connection.GetProductsLikeSourceName("somefile", AzToolsFramework::AssetDatabase::AssetDatabaseConnection::StartsWith, resultProducts, AZ::Uuid::CreateNull(), QString(), "pc"));
EXPECT_EQ(resultProducts.size(), 2);
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product1), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product2), resultProducts.end());
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetProductsLikeSourceName_FilterTest_Status)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
// give it a valid data, but the wrong one:
EXPECT_FALSE(m_data->m_connection.GetProductsLikeSourceName("somefile", AzToolsFramework::AssetDatabase::AssetDatabaseConnection::StartsWith, resultProducts, AZ::Uuid::CreateNull(), QString(), QString(), AzToolsFramework::AssetSystem::JobStatus::Failed)); // its actually completed
EXPECT_EQ(resultProducts.size(), 0);
// give it correct data
EXPECT_TRUE(m_data->m_connection.GetProductsLikeSourceName("somefile", AzToolsFramework::AssetDatabase::AssetDatabaseConnection::StartsWith, resultProducts, AZ::Uuid::CreateNull(), QString(), QString(), AzToolsFramework::AssetSystem::JobStatus::Completed));
EXPECT_EQ(resultProducts.size(), 2);
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product1), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product2), resultProducts.end());
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
// --------------------------------------------------------------------------------------------------------------------
// -------------------------------------------------- SetProducts ----------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
TEST_F(AssetDatabaseTest, SetProducts_EmptyList_Fails)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer requestProducts;
EXPECT_FALSE(m_data->m_connection.SetProducts(requestProducts));
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, SetProducts_UpdatesProductIDs)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer requestProducts;
ProductDatabaseEntryContainer resultProducts;
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t priorProductCount = resultProducts.size();
requestProducts.push_back({ m_data->m_job1.m_jobID, 5, "someproduct5.dds", AZ::Data::AssetType::CreateRandom() });
requestProducts.push_back({ m_data->m_job1.m_jobID, 6, "someproduct6.dds", AZ::Data::AssetType::CreateRandom() });
EXPECT_TRUE(m_data->m_connection.SetProducts(requestProducts));
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t newProductCount = resultProducts.size();
EXPECT_NE(requestProducts[0].m_productID, AzToolsFramework::AssetDatabase::InvalidEntryId);
EXPECT_NE(requestProducts[1].m_productID, AzToolsFramework::AssetDatabase::InvalidEntryId);
EXPECT_EQ(newProductCount, priorProductCount + 2);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
// --------------------------------------------------------------------------------------------------------------------
// ---------------------------------------------- RemoveProduct(s) ---------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
TEST_F(AssetDatabaseTest, RemoveProduct_InvalidID_Fails_DoesNotCorruptDB)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t priorProductCount = resultProducts.size();
EXPECT_FALSE(m_data->m_connection.RemoveProduct(-1));
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t newProductCount = resultProducts.size();
EXPECT_EQ(newProductCount, priorProductCount);
}
TEST_F(AssetDatabaseTest, RemoveProducts_EmptyList_Fails_DoesNotCorruptDB)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t priorProductCount = resultProducts.size();
resultProducts.clear();
EXPECT_FALSE(m_data->m_connection.RemoveProducts(resultProducts));
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t newProductCount = resultProducts.size();
EXPECT_EQ(newProductCount, priorProductCount);
}
TEST_F(AssetDatabaseTest, RemoveProducts_InvalidProductIDs_Fails_DoesNotCorruptDB)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t priorProductCount = resultProducts.size();
resultProducts.clear();
resultProducts.push_back({ -1, m_data->m_job1.m_jobID, 5, "someproduct5.dds", AZ::Data::AssetType::CreateRandom() });
resultProducts.push_back({ -2, m_data->m_job1.m_jobID, 6, "someproduct5.dds", AZ::Data::AssetType::CreateRandom() });
resultProducts.push_back({ -3, m_data->m_job1.m_jobID, 7, "someproduct5.dds", AZ::Data::AssetType::CreateRandom() });
EXPECT_FALSE(m_data->m_connection.RemoveProducts(resultProducts));
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t newProductCount = resultProducts.size();
EXPECT_EQ(newProductCount, priorProductCount);
}
TEST_F(AssetDatabaseTest, RemoveProduct_CorrectProduct_OnlyRemovesThatProduct)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t priorProductCount = resultProducts.size();
EXPECT_TRUE(m_data->m_connection.RemoveProduct(m_data->m_product1.m_productID));
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t newProductCount = resultProducts.size();
EXPECT_EQ(newProductCount, priorProductCount - 1);
// make sure they're all there except that one.
EXPECT_EQ(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product1), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product2), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product3), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product4), resultProducts.end());
}
TEST_F(AssetDatabaseTest, RemoveProducts_CorrectProduct_OnlyRemovesThoseProducts)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t priorProductCount = resultProducts.size();
resultProducts.clear();
resultProducts.push_back(m_data->m_product1);
resultProducts.push_back(m_data->m_product3);
EXPECT_TRUE(m_data->m_connection.RemoveProducts(resultProducts));
// its also supposed to clear their ids:
EXPECT_EQ(resultProducts[0].m_productID, AzToolsFramework::AssetDatabase::InvalidEntryId);
EXPECT_EQ(resultProducts[1].m_productID, AzToolsFramework::AssetDatabase::InvalidEntryId);
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t newProductCount = resultProducts.size();
EXPECT_EQ(newProductCount, priorProductCount - 2);
// make sure they're all there except those two - (1 and 3) which should be 'eq' to end().
EXPECT_EQ(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product1), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product2), resultProducts.end());
EXPECT_EQ(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product3), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product4), resultProducts.end());
}
// --------------------------------------------------------------------------------------------------------------------
// ---------------------------------------------- RemoveProductsByJobID ---------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
TEST_F(AssetDatabaseTest, RemoveProductsByJobID_InvalidID_Fails_DoesNotCorruptDB)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t priorProductCount = resultProducts.size();
EXPECT_FALSE(m_data->m_connection.RemoveProductsByJobID(-1));
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t newProductCount = resultProducts.size();
EXPECT_EQ(newProductCount, priorProductCount);
}
TEST_F(AssetDatabaseTest, RemoveProductsByJobID_ValidID_OnlyRemovesTheMatchingProducts)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t priorProductCount = resultProducts.size();
EXPECT_TRUE(m_data->m_connection.RemoveProductsByJobID(m_data->m_job1.m_jobID));
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t newProductCount = resultProducts.size();
EXPECT_EQ(newProductCount, priorProductCount - 2);
// both products that belong to the first job should be gone.
EXPECT_EQ(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product1), resultProducts.end());
EXPECT_EQ(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product2), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product3), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product4), resultProducts.end());
}
// --------------------------------------------------------------------------------------------------------------------
// ------------------------------------------ RemoveProductsBySourceID ------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
TEST_F(AssetDatabaseTest, RemoveProductsBySourceID_InvalidSourceID_NoResults)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t priorProductCount = resultProducts.size();
EXPECT_FALSE(m_data->m_connection.RemoveProductsBySourceID(-1));
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t newProductCount = resultProducts.size();
EXPECT_EQ(newProductCount, priorProductCount);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, RemoveProductsBySourceID_Valid_OnlyRemovesTheCorrectOnes)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t priorProductCount = resultProducts.size();
EXPECT_TRUE(m_data->m_connection.RemoveProductsBySourceID(m_data->m_sourceFile1.m_sourceID));
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t newProductCount = resultProducts.size();
EXPECT_EQ(newProductCount, priorProductCount - 2);
// both products that belong to the first source should be gone - but only those!
EXPECT_EQ(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product1), resultProducts.end());
EXPECT_EQ(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product2), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product3), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product4), resultProducts.end());
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
// tests all of the filters (beside name) to make sure they all function as expected.
TEST_F(AssetDatabaseTest, RemoveProductsBySourceID_FilterTest_BuilderGUID)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t priorProductCount = resultProducts.size();
// give it a non-matching builder UUID - it should not delete anything despite the product sourceId being correct.
EXPECT_FALSE(m_data->m_connection.RemoveProductsBySourceID(m_data->m_sourceFile1.m_sourceID, AZ::Uuid::CreateRandom()));
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t newProductCount = resultProducts.size();
EXPECT_EQ(newProductCount, priorProductCount);
// give it a correct data but the wrong builder (a valid, but wrong one)
EXPECT_FALSE(m_data->m_connection.RemoveProductsBySourceID(m_data->m_sourceFile1.m_sourceID, m_data->m_job2.m_builderGuid));
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
newProductCount = resultProducts.size();
EXPECT_EQ(newProductCount, priorProductCount);
// give it correct data, it should delete the first two products:
EXPECT_TRUE(m_data->m_connection.RemoveProductsBySourceID(m_data->m_sourceFile1.m_sourceID, m_data->m_job1.m_builderGuid));
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
newProductCount = resultProducts.size();
EXPECT_EQ(newProductCount, priorProductCount - 2);
// both products that belong to the first source should be gone - but only those!
EXPECT_EQ(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product1), resultProducts.end());
EXPECT_EQ(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product2), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product3), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product4), resultProducts.end());
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, RemoveProductsBySourceID_FilterTest_JobKey)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t priorProductCount = resultProducts.size();
// give it a non-matching job key - it should not delete anything despite the product sourceId being correct.
EXPECT_FALSE(m_data->m_connection.RemoveProductsBySourceID(m_data->m_sourceFile1.m_sourceID, AZ::Uuid::CreateNull(), "random key that wont match"));
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t newProductCount = resultProducts.size();
EXPECT_EQ(newProductCount, priorProductCount);
// give it a correct data but the wrong builder (a valid, but wrong one)
EXPECT_FALSE(m_data->m_connection.RemoveProductsBySourceID(m_data->m_sourceFile1.m_sourceID, AZ::Uuid::CreateNull(), m_data->m_job2.m_jobKey.c_str())); // job2 is not the one that did sourcefile1
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
newProductCount = resultProducts.size();
EXPECT_EQ(newProductCount, priorProductCount);
// give it correct data, it should delete the first two products:
EXPECT_TRUE(m_data->m_connection.RemoveProductsBySourceID(m_data->m_sourceFile1.m_sourceID, AZ::Uuid::CreateNull(), m_data->m_job1.m_jobKey.c_str()));
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
newProductCount = resultProducts.size();
EXPECT_EQ(newProductCount, priorProductCount - 2);
// both products that belong to the first source should be gone - but only those!
EXPECT_EQ(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product1), resultProducts.end());
EXPECT_EQ(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product2), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product3), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product4), resultProducts.end());
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, RemoveProductsBySourceID_FilterTest_Platform)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t priorProductCount = resultProducts.size();
// give it a non-matching job key - it should not delete anything despite the product sourceId being correct.
EXPECT_FALSE(m_data->m_connection.RemoveProductsBySourceID(m_data->m_sourceFile1.m_sourceID, AZ::Uuid::CreateNull(), QString(), "no such platform"));
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t newProductCount = resultProducts.size();
EXPECT_EQ(newProductCount, priorProductCount);
// give it a correct data but the wrong builder (a valid, but wrong one)
EXPECT_FALSE(m_data->m_connection.RemoveProductsBySourceID(m_data->m_sourceFile1.m_sourceID, AZ::Uuid::CreateNull(), QString(), "osx")); // its actually PC
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
newProductCount = resultProducts.size();
EXPECT_EQ(newProductCount, priorProductCount);
// give it correct data, it should delete the first two products:
EXPECT_TRUE(m_data->m_connection.RemoveProductsBySourceID(m_data->m_sourceFile1.m_sourceID, AZ::Uuid::CreateNull(), QString(), "pc"));
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
newProductCount = resultProducts.size();
EXPECT_EQ(newProductCount, priorProductCount - 2);
// both products that belong to the first source should be gone - but only those!
EXPECT_EQ(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product1), resultProducts.end());
EXPECT_EQ(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product2), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product3), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product4), resultProducts.end());
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, RemoveProductsBySourceID_FilterTest_Status)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t priorProductCount = resultProducts.size();
// give it a correct status but not one that output that product.
EXPECT_FALSE(m_data->m_connection.RemoveProductsBySourceID(m_data->m_sourceFile1.m_sourceID, AZ::Uuid::CreateNull(), QString(), QString(), AzToolsFramework::AssetSystem::JobStatus::Failed));
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
size_t newProductCount = resultProducts.size();
EXPECT_EQ(newProductCount, priorProductCount);
// give it correct data
EXPECT_TRUE(m_data->m_connection.RemoveProductsBySourceID(m_data->m_sourceFile1.m_sourceID, AZ::Uuid::CreateNull(), QString(), QString(), AzToolsFramework::AssetSystem::JobStatus::Completed));
resultProducts.clear();
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
newProductCount = resultProducts.size();
EXPECT_EQ(newProductCount, priorProductCount - 2);
// both products that belong to the first source should be gone - but only those!
EXPECT_EQ(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product1), resultProducts.end());
EXPECT_EQ(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product2), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product3), resultProducts.end());
EXPECT_NE(AZStd::find(resultProducts.begin(), resultProducts.end(), m_data->m_product4), resultProducts.end());
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, SetProductDependencies_CorrectnessTest)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
EXPECT_GT(resultProducts.size(), 0);
ProductDependencyDatabaseEntryContainer productDependencies;
AZStd::bitset<64> dependencyFlags = 0xFAA0FEEE;
AZStd::string pathDep = "unresolved/dependency.txt";
AZStd::string platform = "somePlatform";
productDependencies.reserve(200);
// make 100 product dependencies on the first productID
for (AZ::u32 productIndex = 0; productIndex < 100; ++productIndex)
{
ProductDependencyDatabaseEntry entry(resultProducts[0].m_productID, m_data->m_sourceFile1.m_sourceGuid, productIndex, dependencyFlags, platform, true, pathDep);
productDependencies.emplace_back(AZStd::move(entry));
}
// make 100 product dependencies on the second productID
for (AZ::u32 productIndex = 0; productIndex < 100; ++productIndex)
{
ProductDependencyDatabaseEntry entry(resultProducts[1].m_productID, m_data->m_sourceFile2.m_sourceGuid, productIndex, dependencyFlags, platform, true, pathDep);
productDependencies.emplace_back(AZStd::move(entry));
}
// do a bulk insert:
EXPECT_TRUE(m_data->m_connection.SetProductDependencies(productDependencies));
// now, read all the data back and verify each field:
productDependencies.clear();
// searching for the first product should only result in the first 100 results:
EXPECT_TRUE(m_data->m_connection.GetProductDependenciesByProductID(resultProducts[0].m_productID, productDependencies));
EXPECT_EQ(productDependencies.size(), 100);
for (AZ::u32 productIndex = 0; productIndex < 100; ++productIndex)
{
EXPECT_NE(productDependencies[productIndex].m_productDependencyID, AzToolsFramework::AssetDatabase::InvalidEntryId);
EXPECT_EQ(productDependencies[productIndex].m_productPK, resultProducts[0].m_productID);
EXPECT_EQ(productDependencies[productIndex].m_dependencySourceGuid, m_data->m_sourceFile1.m_sourceGuid);
EXPECT_EQ(productDependencies[productIndex].m_dependencySubID, productIndex);
EXPECT_EQ(productDependencies[productIndex].m_dependencyFlags, dependencyFlags);
EXPECT_EQ(productDependencies[productIndex].m_platform, platform);
EXPECT_EQ(productDependencies[productIndex].m_unresolvedPath, pathDep);
}
productDependencies.clear();
// searching for the second product should only result in the second 100 results:
EXPECT_TRUE(m_data->m_connection.GetProductDependenciesByProductID(resultProducts[1].m_productID, productDependencies));
EXPECT_EQ(productDependencies.size(), 100);
for (AZ::u32 productIndex = 0; productIndex < 100; ++productIndex)
{
EXPECT_NE(productDependencies[productIndex].m_productDependencyID, AzToolsFramework::AssetDatabase::InvalidEntryId);
EXPECT_EQ(productDependencies[productIndex].m_productPK, resultProducts[1].m_productID);
EXPECT_EQ(productDependencies[productIndex].m_dependencySourceGuid, m_data->m_sourceFile2.m_sourceGuid);
EXPECT_EQ(productDependencies[productIndex].m_dependencySubID, productIndex);
EXPECT_EQ(productDependencies[productIndex].m_dependencyFlags, dependencyFlags);
EXPECT_EQ(productDependencies[productIndex].m_platform, platform);
EXPECT_EQ(productDependencies[productIndex].m_unresolvedPath, pathDep);
}
// now, we replace the dependencies of the first product with fewer results, with different data:
productDependencies.clear();
for (AZ::u32 productIndex = 0; productIndex < 50; ++productIndex)
{
ProductDependencyDatabaseEntry entry(resultProducts[0].m_productID, m_data->m_sourceFile2.m_sourceGuid, productIndex, dependencyFlags, platform, true);
productDependencies.emplace_back(AZStd::move(entry));
}
EXPECT_TRUE(m_data->m_connection.SetProductDependencies(productDependencies));
// searching for the first product should only result in 50 results, which proves that the original 100 were replaced with the new entries:
productDependencies.clear();
EXPECT_TRUE(m_data->m_connection.GetProductDependenciesByProductID(resultProducts[0].m_productID, productDependencies));
EXPECT_EQ(productDependencies.size(), 50);
for (AZ::u32 productIndex = 0; productIndex < 50; ++productIndex)
{
EXPECT_NE(productDependencies[productIndex].m_productDependencyID, AzToolsFramework::AssetDatabase::InvalidEntryId);
EXPECT_EQ(productDependencies[productIndex].m_productPK, resultProducts[0].m_productID);
EXPECT_EQ(productDependencies[productIndex].m_dependencySourceGuid, m_data->m_sourceFile2.m_sourceGuid); // here we verify that the field has changed.
EXPECT_EQ(productDependencies[productIndex].m_dependencySubID, productIndex);
EXPECT_EQ(productDependencies[productIndex].m_dependencyFlags, dependencyFlags);
EXPECT_EQ(productDependencies[productIndex].m_platform, platform);
EXPECT_EQ(productDependencies[productIndex].m_unresolvedPath, ""); // verify that no path is set if it was not specified in the entry
}
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, AddLargeNumberOfDependencies_PerformanceTest)
{
CreateCoverageTestData();
ProductDatabaseEntryContainer resultProducts;
EXPECT_TRUE(m_data->m_connection.GetProducts(resultProducts));
EXPECT_GT(resultProducts.size(), 0);
ProductDependencyDatabaseEntryContainer productDependencies;
AZStd::bitset<64> dependencyFlags;
AZStd::string platform;
productDependencies.reserve(20000);
for (AZ::u32 productIndex = 0; productIndex < 20000; ++productIndex)
{
ProductDependencyDatabaseEntry entry(resultProducts[0].m_productID, m_data->m_sourceFile1.m_sourceGuid, productIndex, dependencyFlags, platform, true);
productDependencies.emplace_back(AZStd::move(entry));
}
EXPECT_TRUE(m_data->m_connection.SetProductDependencies(productDependencies));
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, MissingDependencyTable_WriteAndReadMissingDependencyByDependencyId_ResultsMatch)
{
CreateCoverageTestData();
// Use a non-zero sub ID to verify it writes and reads correctly.
AZ::Data::AssetId assetId(AZ::Uuid::CreateString("{12209A94-AF18-44BB-8A62-96F35291B2E1}"), 3);
AzToolsFramework::AssetDatabase::MissingProductDependencyDatabaseEntry writeMissingDependency(
// The product ID is a link to another table, it will fail to write this entry if this is invalid.
m_data->m_product1.m_productID,
"Scanner Name",
"1.0.0",
"Source File Fingerprint",
assetId.m_guid,
assetId.m_subId,
"Source String",
"last Scan Time",
0);
EXPECT_TRUE(m_data->m_connection.SetMissingProductDependency(writeMissingDependency));
AzToolsFramework::AssetDatabase::MissingProductDependencyDatabaseEntry readMissingDependency;
EXPECT_TRUE(m_data->m_connection.GetMissingProductDependencyByMissingProductDependencyId(
writeMissingDependency.m_missingProductDependencyId,
readMissingDependency));
EXPECT_EQ(writeMissingDependency, readMissingDependency);
}
TEST_F(AssetDatabaseTest, MissingDependencyTable_UpdateExistingMissingDependencyByDependencyId_ResultsMatch)
{
CreateCoverageTestData();
// Use a non-zero sub ID to verify it writes and reads correctly.
AZ::Data::AssetId assetId(AZ::Uuid::CreateString("{32C32642-5832-4997-A478-F288C734425D}"), 6);
AzToolsFramework::AssetDatabase::MissingProductDependencyDatabaseEntry originalMissingDependency(
// The product ID is a link to another table, it will fail to write this entry if this is invalid.
m_data->m_product3.m_productID,
"Scanner Name",
"1.0.0",
"Source File Fingerprint",
assetId.m_guid,
assetId.m_subId,
"Source String",
"last Scan Time",
0);
EXPECT_TRUE(m_data->m_connection.SetMissingProductDependency(originalMissingDependency));
AzToolsFramework::AssetDatabase::MissingProductDependencyDatabaseEntry readMissingDependency;
EXPECT_TRUE(m_data->m_connection.GetMissingProductDependencyByMissingProductDependencyId(
originalMissingDependency.m_missingProductDependencyId,
readMissingDependency));
EXPECT_EQ(originalMissingDependency, readMissingDependency);
// Test each field separately.
AzToolsFramework::AssetDatabase::MissingProductDependencyDatabaseEntry updatedMissingDependency(originalMissingDependency);
updatedMissingDependency.m_productPK = m_data->m_product1.m_productID;
SetAndCheckMissingDependency(updatedMissingDependency, originalMissingDependency);
updatedMissingDependency.m_scannerId = "Different Scanner Name";
SetAndCheckMissingDependency(updatedMissingDependency, originalMissingDependency);
updatedMissingDependency.m_scannerVersion = "Different Scanner Version";
SetAndCheckMissingDependency(updatedMissingDependency, originalMissingDependency);
updatedMissingDependency.m_sourceFileFingerprint = "Different Fingerprint";
SetAndCheckMissingDependency(updatedMissingDependency, originalMissingDependency);
updatedMissingDependency.m_dependencySourceGuid = AZ::Uuid::CreateString("{6C3ED7B4-E6F1-4163-9141-54F5DC1D9C35}");
SetAndCheckMissingDependency(updatedMissingDependency, originalMissingDependency);
updatedMissingDependency.m_dependencySubId = 3;
SetAndCheckMissingDependency(updatedMissingDependency, originalMissingDependency);
updatedMissingDependency.m_missingDependencyString = "Different Source String";
SetAndCheckMissingDependency(updatedMissingDependency, originalMissingDependency);
updatedMissingDependency.m_lastScanTime = "Different Scan Time";
SetAndCheckMissingDependency(updatedMissingDependency, originalMissingDependency);
updatedMissingDependency.m_scanTimeSecondsSinceEpoch = 1;
SetAndCheckMissingDependency(updatedMissingDependency, originalMissingDependency);
}
void AssetDatabaseTest::SetAndCheckMissingDependency(
AzToolsFramework::AssetDatabase::MissingProductDependencyDatabaseEntry& updatedMissingDependency,
const AzToolsFramework::AssetDatabase::MissingProductDependencyDatabaseEntry& originalMissingDependency)
{
EXPECT_TRUE(m_data->m_connection.SetMissingProductDependency(updatedMissingDependency));
AzToolsFramework::AssetDatabase::MissingProductDependencyDatabaseEntry readMissingDependency;
EXPECT_TRUE(m_data->m_connection.GetMissingProductDependencyByMissingProductDependencyId(
originalMissingDependency.m_missingProductDependencyId,
readMissingDependency));
EXPECT_EQ(updatedMissingDependency, readMissingDependency);
// MissingProductDependencyDatabaseEntry doesn't override the != operator
EXPECT_FALSE(readMissingDependency == originalMissingDependency);
}
TEST_F(AssetDatabaseTest, MissingDependencyTable_WriteAndReadMissingDependenciesByProductId_ResultsMatch)
{
CreateCoverageTestData();
AZStd::vector<AZ::Data::AssetId> assetIds;
assetIds.push_back(AZ::Data::AssetId(AZ::Uuid::CreateString("{FDAC3A8C-26D1-47D9-88B0-647BCED826DB}"), 10));
assetIds.push_back(AZ::Data::AssetId(AZ::Uuid::CreateString("{261E8996-7309-4D18-986F-EC6EDE910A70}"), 20));
assetIds.push_back(AZ::Data::AssetId(AZ::Uuid::CreateString("{2FA88E3A-D6E4-4192-B865-4DDD61AE7492}"), 30));
// The product ID is a link to another table, it will fail to write this entry if this is invalid.
AZ::s64 productPK = m_data->m_product2.m_productID;
AzToolsFramework::AssetDatabase::MissingProductDependencyDatabaseEntryContainer writeMissingDependencies;
writeMissingDependencies.push_back(AzToolsFramework::AssetDatabase::MissingProductDependencyDatabaseEntry(
productPK,
"Scanner 0",
"0.0.0",
"Fingerprint 0",
assetIds[0].m_guid,
assetIds[0].m_subId,
"Source String 0",
"last Scan Time 0",
0));
writeMissingDependencies.push_back(AzToolsFramework::AssetDatabase::MissingProductDependencyDatabaseEntry(
productPK,
"Scanner 1",
"1.1.1",
"Fingerprint 1",
assetIds[1].m_guid,
assetIds[1].m_subId,
"Source String 1",
"last Scan Time 1",
1));
writeMissingDependencies.push_back(AzToolsFramework::AssetDatabase::MissingProductDependencyDatabaseEntry(
productPK,
"Scanner 2",
"2.2.2",
"Fingerprint 2",
assetIds[2].m_guid,
assetIds[2].m_subId,
"Source String 2",
"last Scan Time 2",
2));
EXPECT_TRUE(m_data->m_connection.SetMissingProductDependency(writeMissingDependencies[0]));
EXPECT_TRUE(m_data->m_connection.SetMissingProductDependency(writeMissingDependencies[1]));
EXPECT_TRUE(m_data->m_connection.SetMissingProductDependency(writeMissingDependencies[2]));
AzToolsFramework::AssetDatabase::MissingProductDependencyDatabaseEntryContainer readMissingDependencies;
EXPECT_TRUE(m_data->m_connection.GetMissingProductDependenciesByProductId(productPK, readMissingDependencies));
EXPECT_EQ(readMissingDependencies.size(), writeMissingDependencies.size());
for (int dependencyIndex = 0; dependencyIndex < writeMissingDependencies.size(); ++dependencyIndex)
{
EXPECT_EQ(readMissingDependencies[dependencyIndex], writeMissingDependencies[dependencyIndex]);
}
}
TEST_F(AssetDatabaseTest, MissingDependencyTable_WriteAndDeleteMissingDependencyByDependencyId_MissingDependencyRecordDeleted)
{
CreateCoverageTestData();
// Use a non-zero sub ID to verify it writes and reads correctly.
AZ::Data::AssetId assetId(AZ::Uuid::CreateString("{12209A94-AF18-44BB-8A62-96F35291B2E1}"), 3);
AzToolsFramework::AssetDatabase::MissingProductDependencyDatabaseEntry writeMissingDependency(
// The product ID is a link to another table, it will fail to write this entry if this is invalid.
m_data->m_product1.m_productID,
"Scanner Name",
"1.0.0",
"Source File Fingerprint",
assetId.m_guid,
assetId.m_subId,
"Source String",
"last Scan Time",
0);
EXPECT_TRUE(m_data->m_connection.SetMissingProductDependency(writeMissingDependency));
AzToolsFramework::AssetDatabase::MissingProductDependencyDatabaseEntry readMissingDependency;
EXPECT_TRUE(m_data->m_connection.GetMissingProductDependencyByMissingProductDependencyId(
writeMissingDependency.m_missingProductDependencyId,
readMissingDependency));
// Verify that it was written to the DB before erasing it.
EXPECT_EQ(writeMissingDependency, readMissingDependency);
EXPECT_TRUE(m_data->m_connection.DeleteMissingProductDependencyByProductId(writeMissingDependency.m_missingProductDependencyId));
EXPECT_FALSE(m_data->m_connection.GetMissingProductDependencyByMissingProductDependencyId(
writeMissingDependency.m_missingProductDependencyId,
readMissingDependency));
}
// Verify that clearing missing product dependencies by product ID clears every missing dependency for that product ID.
TEST_F(AssetDatabaseTest, MissingDependencyTable_DeleteMultipleMissingDependenciesForOneProduct_MissingDependencyRecordsDeleted)
{
CreateCoverageTestData();
// Use a non-zero sub ID to verify it writes and reads correctly.
AZ::Data::AssetId assetId(AZ::Uuid::CreateString("{12209A94-AF18-44BB-8A62-96F35291B2E1}"), 3);
AzToolsFramework::AssetDatabase::MissingProductDependencyDatabaseEntry firstMissingDependency(
// The product ID is a link to another table, it will fail to write this entry if this is invalid.
m_data->m_product1.m_productID,
"Scanner Name",
"1.0.0",
"Source File Fingerprint",
assetId.m_guid,
assetId.m_subId,
"Source String",
"last Scan Time",
0);
EXPECT_TRUE(m_data->m_connection.SetMissingProductDependency(firstMissingDependency));
AZ::Data::AssetId secondMissingAssetId(AZ::Uuid::CreateString("{12209A94-FFFF-FFFF-8A62-96F35291B2E1}"), 4);
AzToolsFramework::AssetDatabase::MissingProductDependencyDatabaseEntry secondMissingDependency(
// Use the same product ID as the first missing dependency
m_data->m_product1.m_productID,
"Scanner Name 2",
"1.0.0",
"Source File Fingerprint",
secondMissingAssetId.m_guid,
secondMissingAssetId.m_subId,
"Source String",
"last Scan Time",
0);
EXPECT_TRUE(m_data->m_connection.SetMissingProductDependency(secondMissingDependency));
AZStd::unordered_set<AZ::s64> expectedMissingDependencies;
expectedMissingDependencies.insert(firstMissingDependency.m_missingProductDependencyId);
expectedMissingDependencies.insert(secondMissingDependency.m_missingProductDependencyId);
// Tests can't be ran inside the lambda, so cache results and check after.
bool foundUnexpectedDependency = false;
m_data->m_connection.QueryMissingProductDependencyByProductId(
m_data->m_product1.m_productID,
[&](AzToolsFramework::AssetDatabase::MissingProductDependencyDatabaseEntry& entry)
{
if (expectedMissingDependencies.find(entry.m_missingProductDependencyId) == expectedMissingDependencies.end())
{
foundUnexpectedDependency = true;
}
else
{
expectedMissingDependencies.erase(entry.m_missingProductDependencyId);
}
return true;
});
EXPECT_FALSE(foundUnexpectedDependency);
EXPECT_EQ(expectedMissingDependencies.size(), 0);
EXPECT_TRUE(m_data->m_connection.DeleteMissingProductDependencyByProductId(m_data->m_product1.m_productID));
foundUnexpectedDependency = false;
m_data->m_connection.QueryMissingProductDependencyByProductId(
m_data->m_product1.m_productID,
[&](AzToolsFramework::AssetDatabase::MissingProductDependencyDatabaseEntry& /*entry*/)
{
// No dependencies should be found for this product.
foundUnexpectedDependency = true;
return false;
});
EXPECT_FALSE(foundUnexpectedDependency);
}
// Verify that clearing missing dependencies for one product ID does not clear it for another product ID.
TEST_F(AssetDatabaseTest, MissingDependencyTable_DeleteMissingDependenciesForOneProduct_MissingDependenciesNotDeletedForOtherProduct)
{
CreateCoverageTestData();
// Use a non-zero sub ID to verify it writes and reads correctly.
AZ::Data::AssetId assetId(AZ::Uuid::CreateString("{12209A94-AF18-44BB-8A62-96F35291B2E1}"), 3);
AzToolsFramework::AssetDatabase::MissingProductDependencyDatabaseEntry firstMissingDependency(
// The product ID is a link to another table, it will fail to write this entry if this is invalid.
m_data->m_product1.m_productID,
"Scanner Name",
"1.0.0",
"Source File Fingerprint",
assetId.m_guid,
assetId.m_subId,
"Source String",
"last Scan Time",
0);
EXPECT_TRUE(m_data->m_connection.SetMissingProductDependency(firstMissingDependency));
AZ::Data::AssetId secondMissingAssetId(AZ::Uuid::CreateString("{12209A94-FFFF-FFFF-8A62-96F35291B2E1}"), 4);
AzToolsFramework::AssetDatabase::MissingProductDependencyDatabaseEntry secondMissingDependency(
// Use the same product ID as the first missing dependency
m_data->m_product3.m_productID,
"Scanner Name 2",
"1.0.0",
"Source File Fingerprint",
secondMissingAssetId.m_guid,
secondMissingAssetId.m_subId,
"Source String",
"last Scan Time",
0);
EXPECT_TRUE(m_data->m_connection.SetMissingProductDependency(secondMissingDependency));
// Verify both missing dependencies are set.
size_t dependenciesFound = 0;
m_data->m_connection.QueryMissingProductDependencyByProductId(
m_data->m_product1.m_productID,
[&](AzToolsFramework::AssetDatabase::MissingProductDependencyDatabaseEntry& /*entry*/)
{
++dependenciesFound;
return true;
});
EXPECT_EQ(dependenciesFound, 1);
dependenciesFound = 0;
m_data->m_connection.QueryMissingProductDependencyByProductId(
m_data->m_product3.m_productID,
[&](AzToolsFramework::AssetDatabase::MissingProductDependencyDatabaseEntry& /*entry*/)
{
++dependenciesFound;
return true;
});
EXPECT_EQ(dependenciesFound, 1);
// Delete the first product's missing dependencies.
EXPECT_TRUE(m_data->m_connection.DeleteMissingProductDependencyByProductId(m_data->m_product1.m_productID));
// Verify the first product's missing dependency is gone.
dependenciesFound = 0;
m_data->m_connection.QueryMissingProductDependencyByProductId(
m_data->m_product1.m_productID,
[&](AzToolsFramework::AssetDatabase::MissingProductDependencyDatabaseEntry& /*entry*/)
{
++dependenciesFound;
return false;
});
// No dependencies should be found for this product.
EXPECT_EQ(dependenciesFound, 0);
// Verify the second product's missing dependency is still there.
dependenciesFound = 0;
m_data->m_connection.QueryMissingProductDependencyByProductId(
m_data->m_product3.m_productID,
[&](AzToolsFramework::AssetDatabase::MissingProductDependencyDatabaseEntry& /*entry*/)
{
++dependenciesFound;
return true;
});
EXPECT_EQ(dependenciesFound, 1);
}
TEST_F(AssetDatabaseTest, AddLargeNumberOfSourceDependencies_PerformanceTest)
{
CreateCoverageTestData();
SourceFileDependencyEntryContainer resultSourceDependencies;
resultSourceDependencies.reserve(20000);
AZ::Uuid builderGuid = AZ::Uuid::CreateRandom();
// emit 20,000 source dependencies for the same origin file:
AZStd::string originFile("myfile.txt");
for (AZ::u32 sourceIndex = 0; sourceIndex < 20000; ++sourceIndex)
{
AZStd::string dependentFile = AZStd::string::format("otherfile%i.txt", sourceIndex);
SourceFileDependencyEntry entry(builderGuid, originFile.c_str(), dependentFile.c_str(), SourceFileDependencyEntry::DEP_SourceToSource, true);
resultSourceDependencies.emplace_back(AZStd::move(entry));
}
EXPECT_TRUE(m_data->m_connection.SetSourceFileDependencies(resultSourceDependencies));
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
// read them back
resultSourceDependencies.clear();
EXPECT_TRUE(m_data->m_connection.GetSourceFileDependenciesByBuilderGUIDAndSource(builderGuid, originFile.c_str(), SourceFileDependencyEntry::DEP_SourceToSource, resultSourceDependencies));
EXPECT_EQ(resultSourceDependencies.size(), 20000);
}
TEST_F(AssetDatabaseTest, SourceFileDependencies_CorrectnessTest)
{
CreateCoverageTestData();
AZ::Uuid builderGuid1 = AZ::Uuid::CreateRandom();
AZ::Uuid builderGuid2 = AZ::Uuid::CreateRandom();
SourceFileDependencyEntryContainer entries;
// add the two different kinds of dependencies.
entries.push_back(SourceFileDependencyEntry(builderGuid1, "file1.txt", "file1dependson1.txt", SourceFileDependencyEntry::DEP_SourceToSource, true));
entries.push_back(SourceFileDependencyEntry(builderGuid2, "file1.txt", "file1dependson2.txt", SourceFileDependencyEntry::DEP_SourceToSource, true));
entries.push_back(SourceFileDependencyEntry(builderGuid1, "file1.txt", "file1dependson1job.txt", SourceFileDependencyEntry::DEP_JobToJob, true));
entries.push_back(SourceFileDependencyEntry(builderGuid2, "file1.txt", "file1dependson2job.txt", SourceFileDependencyEntry::DEP_JobToJob, true));
entries.push_back(SourceFileDependencyEntry(builderGuid1, "file2.txt", "file2dependson1.txt", SourceFileDependencyEntry::DEP_SourceToSource, true));
entries.push_back(SourceFileDependencyEntry(builderGuid1, "file2.txt", "file2dependson1job.txt", SourceFileDependencyEntry::DEP_JobToJob, true));
ASSERT_TRUE(m_data->m_connection.SetSourceFileDependencies(entries));
SourceFileDependencyEntryContainer resultEntries;
AZStd::string searchFor;
auto SearchPredicate = [&searchFor](const SourceFileDependencyEntry& element)
{
return element.m_dependsOnSource == searchFor;
};
auto SearchPredicateReverse = [&searchFor](const SourceFileDependencyEntry& element)
{
return element.m_source == searchFor;
};
// ask for only the source-to-source dependencies of file1.txt for builder1
EXPECT_TRUE(m_data->m_connection.GetSourceFileDependenciesByBuilderGUIDAndSource(builderGuid1, "file1.txt", SourceFileDependencyEntry::DEP_SourceToSource, resultEntries));
EXPECT_EQ(resultEntries.size(), 1);
searchFor = "file1dependson1.txt";
EXPECT_NE(AZStd::find_if(resultEntries.begin(), resultEntries.end(), SearchPredicate), resultEntries.end());
resultEntries.clear();
// ask for only the source-to-source dependencies of file1.txt for builder2
EXPECT_TRUE(m_data->m_connection.GetSourceFileDependenciesByBuilderGUIDAndSource(builderGuid2, "file1.txt", SourceFileDependencyEntry::DEP_SourceToSource, resultEntries));
EXPECT_EQ(resultEntries.size(), 1);
searchFor = "file1dependson2.txt";
EXPECT_NE(AZStd::find_if(resultEntries.begin(), resultEntries.end(), SearchPredicate), resultEntries.end());
resultEntries.clear();
// ask for the source-to-source dependencies of file1.txt for ANY builder, we shiould get both.
EXPECT_TRUE(m_data->m_connection.GetDependsOnSourceBySource("file1.txt", SourceFileDependencyEntry::DEP_SourceToSource, resultEntries));
EXPECT_EQ(resultEntries.size(), 2);
searchFor = "file1dependson1.txt";
EXPECT_NE(AZStd::find_if(resultEntries.begin(), resultEntries.end(), SearchPredicate), resultEntries.end());
searchFor = "file1dependson2.txt";
EXPECT_NE(AZStd::find_if(resultEntries.begin(), resultEntries.end(), SearchPredicate), resultEntries.end());
resultEntries.clear();
// now ask for the job-to-job dependencies for builder 1
EXPECT_TRUE(m_data->m_connection.GetSourceFileDependenciesByBuilderGUIDAndSource(builderGuid1, "file1.txt", SourceFileDependencyEntry::DEP_JobToJob, resultEntries));
EXPECT_EQ(resultEntries.size(), 1);
searchFor = "file1dependson1job.txt";
EXPECT_NE(AZStd::find_if(resultEntries.begin(), resultEntries.end(), SearchPredicate), resultEntries.end());
resultEntries.clear();
// now ask for the job-to-job dependencies for builder 2
EXPECT_TRUE(m_data->m_connection.GetSourceFileDependenciesByBuilderGUIDAndSource(builderGuid2, "file1.txt", SourceFileDependencyEntry::DEP_JobToJob, resultEntries));
EXPECT_EQ(resultEntries.size(), 1);
searchFor = "file1dependson2job.txt";
EXPECT_NE(AZStd::find_if(resultEntries.begin(), resultEntries.end(), SearchPredicate), resultEntries.end());
resultEntries.clear();
// now ask for the job-to-job dependencies for any builder
EXPECT_TRUE(m_data->m_connection.GetDependsOnSourceBySource( "file1.txt", SourceFileDependencyEntry::DEP_JobToJob, resultEntries));
EXPECT_EQ(resultEntries.size(), 2);
searchFor = "file1dependson1job.txt";
EXPECT_NE(AZStd::find_if(resultEntries.begin(), resultEntries.end(), SearchPredicate), resultEntries.end());
searchFor = "file1dependson2job.txt";
EXPECT_NE(AZStd::find_if(resultEntries.begin(), resultEntries.end(), SearchPredicate), resultEntries.end());
resultEntries.clear();
// now ask for the reverse dependencies - we should find one source-to-source
EXPECT_TRUE(m_data->m_connection.GetSourceFileDependenciesByDependsOnSource("file1dependson1.txt", SourceFileDependencyEntry::DEP_SourceToSource, resultEntries));
EXPECT_EQ(resultEntries.size(), 1);
searchFor = "file1.txt";
EXPECT_NE(AZStd::find_if(resultEntries.begin(), resultEntries.end(), SearchPredicateReverse), resultEntries.end());
resultEntries.clear();
// now ask for the reverse dependencies - we should find no job-to-job for this:
EXPECT_FALSE(m_data->m_connection.GetSourceFileDependenciesByDependsOnSource("file1dependson1.txt", SourceFileDependencyEntry::DEP_JobToJob, resultEntries));
EXPECT_EQ(resultEntries.size(), 0);
resultEntries.clear();
// now ask for the reverse dependencies - we should find one 'any' type.
EXPECT_TRUE(m_data->m_connection.GetSourceFileDependenciesByDependsOnSource("file1dependson1.txt", SourceFileDependencyEntry::DEP_Any, resultEntries));
EXPECT_EQ(resultEntries.size(), 1);
searchFor = "file1.txt";
EXPECT_NE(AZStd::find_if(resultEntries.begin(), resultEntries.end(), SearchPredicateReverse), resultEntries.end());
resultEntries.clear();
// now try the other file - remember the ID for later
ASSERT_TRUE(m_data->m_connection.GetSourceFileDependenciesByBuilderGUIDAndSource(builderGuid1, "file2.txt", SourceFileDependencyEntry::DEP_SourceToSource, resultEntries));
EXPECT_EQ(resultEntries.size(), 1);
searchFor = "file2dependson1.txt";
EXPECT_NE(AZStd::find_if(resultEntries.begin(), resultEntries.end(), SearchPredicate), resultEntries.end());
AZ::s64 entryIdSource = resultEntries[0].m_sourceDependencyID;
resultEntries.clear();
// and with Job-to-job dependencies
EXPECT_TRUE(m_data->m_connection.GetSourceFileDependenciesByBuilderGUIDAndSource(builderGuid1, "file2.txt", SourceFileDependencyEntry::DEP_JobToJob, resultEntries));
ASSERT_EQ(resultEntries.size(), 1);
EXPECT_EQ(resultEntries[0].m_builderGuid, builderGuid1);
EXPECT_STREQ(resultEntries[0].m_source.c_str(), "file2.txt");
EXPECT_NE(resultEntries[0].m_sourceDependencyID, AzToolsFramework::AssetDatabase::InvalidEntryId);
EXPECT_STREQ(resultEntries[0].m_dependsOnSource.c_str(), "file2dependson1job.txt");
EXPECT_EQ(resultEntries[0].m_typeOfDependency, SourceFileDependencyEntry::DEP_JobToJob);
AZ::s64 entryIdJob = resultEntries[0].m_sourceDependencyID;
resultEntries.clear();
SourceFileDependencyEntry resultValue;
EXPECT_TRUE(m_data->m_connection.GetSourceFileDependencyBySourceDependencyId(entryIdSource, resultValue));
EXPECT_EQ(resultValue.m_sourceDependencyID, entryIdSource);
EXPECT_EQ(resultValue.m_typeOfDependency, SourceFileDependencyEntry::DEP_SourceToSource);
EXPECT_STREQ(resultValue.m_source.c_str(), "file2.txt");
EXPECT_STREQ(resultValue.m_dependsOnSource.c_str(), "file2dependson1.txt");
EXPECT_EQ(resultValue.m_builderGuid, builderGuid1);
EXPECT_TRUE(m_data->m_connection.GetSourceFileDependencyBySourceDependencyId(entryIdJob, resultValue));
EXPECT_EQ(resultValue.m_sourceDependencyID, entryIdJob);
EXPECT_EQ(resultValue.m_typeOfDependency, SourceFileDependencyEntry::DEP_JobToJob);
EXPECT_STREQ(resultValue.m_source.c_str(), "file2.txt");
EXPECT_STREQ(resultValue.m_dependsOnSource.c_str(), "file2dependson1job.txt");
EXPECT_EQ(resultValue.m_builderGuid, builderGuid1);
// removal of source
m_data->m_connection.RemoveSourceFileDependency(entryIdSource);
EXPECT_FALSE(m_data->m_connection.GetSourceFileDependencyBySourceDependencyId(entryIdSource, resultValue));
EXPECT_TRUE(m_data->m_connection.GetSourceFileDependencyBySourceDependencyId(entryIdJob, resultValue));
// removeal of job
m_data->m_connection.RemoveSourceFileDependency(entryIdJob);
EXPECT_FALSE(m_data->m_connection.GetSourceFileDependencyBySourceDependencyId(entryIdSource, resultValue));
EXPECT_FALSE(m_data->m_connection.GetSourceFileDependencyBySourceDependencyId(entryIdJob, resultValue));
}
TEST_F(AssetDatabaseTest, UpdateNonExistentFile_Fails)
{
CreateCoverageTestData();
ASSERT_FALSE(m_data->m_connection.UpdateFileModTimeAndHashByFileNameAndScanFolderId("testfile.txt", m_data->m_scanFolder.m_scanFolderID, 1234, 1111));
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, UpdateExistingFile_Succeeds)
{
CreateCoverageTestData();
FileDatabaseEntry entry;
entry.m_fileName = "testfile.txt";
entry.m_scanFolderPK = m_data->m_scanFolder.m_scanFolderID;
bool entryAlreadyExists;
ASSERT_TRUE(m_data->m_connection.InsertFile(entry, entryAlreadyExists));
ASSERT_FALSE(entryAlreadyExists);
ASSERT_TRUE(m_data->m_connection.UpdateFileModTimeAndHashByFileNameAndScanFolderId("testfile.txt", m_data->m_scanFolder.m_scanFolderID, 1234, 1111));
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0); // not allowed to assert on this
}
TEST_F(AssetDatabaseTest, GetSourceBySourceName_InvalidInput_SourceNotFound)
{
CreateCoverageTestData();
SourceDatabaseEntry resultSource;
EXPECT_FALSE(m_data->m_connection.GetSourceBySourceName("non_existent", resultSource));
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0);
}
TEST_F(AssetDatabaseTest, GetSourceBySourceName_ValidInput_SourceFound)
{
CreateCoverageTestData();
SourceDatabaseEntry resultSource;
EXPECT_TRUE(m_data->m_connection.GetSourceBySourceName("somefile.tif", resultSource));
EXPECT_EQ(resultSource.m_sourceGuid, m_data->m_sourceFile1.m_sourceGuid);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0);
}
TEST_F(AssetDatabaseTest, GetDirectReverseProductDependenciesBySourceGuidSubID_InvalidInput_ProductsNotFound)
{
CreateCoverageTestData();
ProductDependencyDatabaseEntry productDependency;
productDependency.m_productPK = m_data->m_product1.m_productID;
productDependency.m_dependencySourceGuid = m_data->m_sourceFile1.m_sourceGuid;
productDependency.m_dependencySubID = m_data->m_product1.m_subID;
ASSERT_TRUE(m_data->m_connection.SetProductDependency(productDependency));
ProductDatabaseEntryContainer resultProducts;
AZ::Uuid invalidGuid = AZ::Uuid::CreateNull();
AZ::s32 invalidSubId = -1;
EXPECT_FALSE(m_data->m_connection.GetDirectReverseProductDependenciesBySourceGuidSubId(invalidGuid, m_data->m_product1.m_subID, resultProducts));
EXPECT_FALSE(m_data->m_connection.GetDirectReverseProductDependenciesBySourceGuidSubId(m_data->m_sourceFile1.m_sourceGuid, invalidSubId, resultProducts));
EXPECT_FALSE(m_data->m_connection.GetDirectReverseProductDependenciesBySourceGuidSubId(invalidGuid, invalidSubId, resultProducts));
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0);
}
TEST_F(AssetDatabaseTest, GetDirectReverseProductDependenciesBySourceGuidSubID_ValidInput_ProductsFound)
{
CreateCoverageTestData();
ProductDependencyDatabaseEntry productDependency;
productDependency.m_productPK = m_data->m_product1.m_productID;
productDependency.m_dependencySourceGuid = m_data->m_sourceFile1.m_sourceGuid;
productDependency.m_dependencySubID = m_data->m_product1.m_subID;
ASSERT_TRUE(m_data->m_connection.SetProductDependency(productDependency));
ProductDatabaseEntryContainer resultProducts;
EXPECT_TRUE(m_data->m_connection.GetDirectReverseProductDependenciesBySourceGuidSubId(m_data->m_sourceFile1.m_sourceGuid, m_data->m_product1.m_subID, resultProducts));
ASSERT_EQ(resultProducts.size(), 1);
EXPECT_EQ(resultProducts[0], m_data->m_product1);
EXPECT_EQ(m_errorAbsorber->m_numAssertsAbsorbed, 0);
}
TEST_F(AssetDatabaseTest, QueryCombined_Succeeds)
{
// This test specifically checks that the legacy subIds returned by QueryCombined are correctly matched to only the one product that they're associated with
using namespace AzToolsFramework::AssetDatabase;
CreateCoverageTestData();
auto subIds = { 123, 134, 155, 166, 177 };
AZStd::vector<LegacySubIDsEntry> createdLegacySubIds;
for(int subId : subIds)
{
LegacySubIDsEntry subIdEntry;
subIdEntry.m_productPK = m_data->m_product1.m_productID;
subIdEntry.m_subID = subId;
ASSERT_TRUE(m_data->m_connection.CreateOrUpdateLegacySubID(subIdEntry));
createdLegacySubIds.push_back(subIdEntry);
}
AZStd::vector<CombinedDatabaseEntry> results;
auto databaseQueryCallback = [&](AzToolsFramework::AssetDatabase::CombinedDatabaseEntry& combined) -> bool
{
results.push_back(combined);
return true;
};
ASSERT_TRUE(m_data->m_connection.QueryCombined(databaseQueryCallback, AZ::Uuid::CreateNull(), nullptr, nullptr, AzToolsFramework::AssetSystem::JobStatus::Any, /*includeLegacyIds*/ true));
bool foundProductWithLegacyIds = false;
for(const auto& combined : results)
{
if (combined.m_productID == m_data->m_product1.m_productID)
{
foundProductWithLegacyIds = true;
ASSERT_THAT(combined.m_legacySubIDs, testing::UnorderedElementsAreArray(createdLegacySubIds));
}
else
{
ASSERT_EQ(combined.m_legacySubIDs.size(), 0);
}
}
ASSERT_TRUE(foundProductWithLegacyIds);
}
TEST_F(AssetDatabaseTest, InsertFile_Existing_ReturnsExisting)
{
CreateCoverageTestData();
using namespace AzToolsFramework::AssetDatabase;
FileDatabaseEntry fileEntry;
fileEntry.m_fileName = "blah";
fileEntry.m_scanFolderPK = m_data->m_scanFolder.m_scanFolderID;
bool entryAlreadyExists = false;
ASSERT_TRUE(m_data->m_connection.InsertFile(fileEntry, entryAlreadyExists));
ASSERT_FALSE(entryAlreadyExists);
fileEntry.m_fileID = InvalidEntryId; // InsertFile will update the Id, we want to test without a specified Id
ASSERT_TRUE(m_data->m_connection.InsertFile(fileEntry, entryAlreadyExists));
ASSERT_TRUE(entryAlreadyExists);
// Test one more time, with the Id set to a specific entry now
ASSERT_NE(fileEntry.m_fileID, InvalidEntryId);
ASSERT_TRUE(m_data->m_connection.InsertFile(fileEntry, entryAlreadyExists));
ASSERT_TRUE(entryAlreadyExists);
}
class QueryLoggingTraceHandler : public AZ::Debug::TraceMessageBus::Handler
{
public:
QueryLoggingTraceHandler()
{
BusConnect();
}
~QueryLoggingTraceHandler()
{
BusDisconnect();
}
bool OnPrintf(const char* /*window*/, const char* message) override
{
if (m_expectedMessage.compare(message) == 0)
{
m_expectedMessageFound = true;
}
return false; // Return false so it also prints out to the log.
}
AZStd::string m_expectedMessage;
bool m_expectedMessageFound = false;
private:
};
TEST_F(AssetDatabaseTest, LoggingEnabled_InsertFile_LogMessageMatches)
{
using namespace AzToolsFramework::AssetDatabase;
CreateCoverageTestData();
QueryLoggingTraceHandler queryLoggingTraceHandler;
queryLoggingTraceHandler.m_expectedMessage =
"SELECT * FROM Files WHERE ScanFolderPK = :scanfolderpk AND FileName = :filename; = Params :scanfolderpk = `1`, :filename = `blah`\n";
m_data->m_connection.SetQueryLogging(true);
FileDatabaseEntry fileEntry;
fileEntry.m_fileName = "blah";
fileEntry.m_scanFolderPK = m_data->m_scanFolder.m_scanFolderID;
bool entryAlreadyExists = false;
ASSERT_TRUE(m_data->m_connection.InsertFile(fileEntry, entryAlreadyExists));
m_data->m_connection.SetQueryLogging(false);
ASSERT_TRUE(queryLoggingTraceHandler.m_expectedMessageFound);
}
} // end namespace UnitTests