Merge branch 'development' into memory/benchmarks

Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>
This commit is contained in:
Esteban Papp
2021-12-07 15:47:29 -08:00
1784 changed files with 25936 additions and 108873 deletions
+9 -20
View File
@@ -1392,7 +1392,7 @@ namespace UnitTest
EXPECT_TRUE(done);
}
// Fixture for thread-driller-bus related calls
// Fixture for thread-event-bus related calls
// exists only to categorize the tests.
class ThreadEventsBus :
public AllocatorsFixture
@@ -1438,44 +1438,33 @@ namespace UnitTest
TEST_F(ThreadEventsBus, Broadcasts_BothBusses)
{
ThreadEventCounter<AZStd::ThreadEventBus::Handler> eventBusCounter;
ThreadEventCounter<AZStd::ThreadDrillerEventBus::Handler> drillerBusCounter;
auto thread_function = [&]()
{
; // intentionally left blank
};
eventBusCounter.Connect();
drillerBusCounter.Connect();
AZStd::thread starter = AZStd::thread(thread_function);
starter.join();
EXPECT_EQ(drillerBusCounter.m_enterCount, 1);
EXPECT_EQ(drillerBusCounter.m_exitCount, 1);
EXPECT_EQ(eventBusCounter.m_enterCount, 1);
EXPECT_EQ(eventBusCounter.m_exitCount, 1);
eventBusCounter.Disconnect();
drillerBusCounter.Disconnect();
}
// this class tests for deadlocks caused by interactions between the thread
// driller bus and the other driller busses.
// Client code (ie, not part of the driller system) can connec to the
// ThreadEventBus and be told when threads are started and stopped
// However, if they instead listen to the ThreadDrillerEventBus, a deadlock condition
// could be caused if they lock a mutex that another thread needs in order to proceed.
// This test makes sure that using the ThreadEventBus (ie, the one meant for client code)
// instead of the ThreadDrillerEventBus (the one meant only for profilers) does NOT cause
// a deadlock.
// This class tests for deadlocks caused by multiple threads interacting with the ThreadEventBus.
// Client code can connect to the ThreadEventBus and be told when threads are started and stopped.
// A deadlock condition could be caused if they lock a mutex that another thread needs in order to proceed.
// This test makes sure that using the ThreadEventBus does NOT cause a deadlock.
// We will simulate this series of events by doing the following
// 1. Main thread listens on the ThreadEventBus
// 2. OnThreadExit will lock a mutex, perform an allocation, unlock a mutex
// 3. The thread itself will lock the mutex, perform an allocation, unlock the mutex.
// As long as there is no cross talk between the client and the driller busses, the
// above operation should not deadlock.
// but if there is, then a deadlock can occur where one thread will be unable to perform
// its allocation because the other is in OnThreadExit()
// and the other will not be able to perform OnThreadExit() because it cannot lock the mutex.
// As long as there is no cross talk between threads, the above operation should not deadlock.
// If there is, then a deadlock can occur where one thread will be unable to perform
// its allocation because the other is in OnThreadExit() and the other will not be able to perform
// OnThreadExit() because it cannot lock the mutex.
class ThreadEventsDeathTest :
public AllocatorsFixture
@@ -8,6 +8,7 @@
#include "UserTypes.h"
#include <AzCore/std/typetraits/internal/is_template_copy_constructible.h>
#include <AzCore/std/containers/forward_list.h>
#include <AzCore/std/containers/set.h>
#include <AzCore/std/containers/unordered_set.h>
#include <AzCore/std/containers/map.h>
@@ -26,6 +26,7 @@
#include <AzCore/std/functional.h>
#include <AzCore/std/parallel/condition_variable.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzCore/UnitTest/Mocks/MockFileIOBase.h>
#include <AZTestShared/Utils/Utils.h>
#include <Streamer/IStreamerMock.h>
#include <Tests/Asset/BaseAssetManagerTest.h>
@@ -131,8 +132,8 @@ namespace UnitTest
* This will test the aspect of the system where ObjectStreams and asset jobs loading dependent
* assets will do the work in their own thread.
*/
class AssetJobsFloodTest
: public BaseAssetManagerTest
class AssetJobsFloodTest : public DisklessAssetManagerBase
{
public:
TestAssetManager* m_testAssetManager{ nullptr };
@@ -183,15 +184,14 @@ namespace UnitTest
void SetUp() override
{
BaseAssetManagerTest::SetUp();
DisklessAssetManagerBase::SetUp();
SetupTest();
}
void TearDown() override
{
TearDownTest();
AssetManager::Destroy();
BaseAssetManagerTest::TearDown();
DisklessAssetManagerBase::TearDown();
}
void SetupAssets()
@@ -257,9 +257,9 @@ namespace UnitTest
AssetWithSerializedData ap2;
AssetWithSerializedData ap3;
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset4.txt", AZ::DataStream::ST_XML, &ap1, m_serializeContext));
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset5.txt", AZ::DataStream::ST_XML, &ap2, m_serializeContext));
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset6.txt", AZ::DataStream::ST_XML, &ap3, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset4.txt", &ap1, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset5.txt", &ap2, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset6.txt", &ap3, m_serializeContext));
AssetWithAssetReference assetWithPreload1;
AssetWithAssetReference assetWithPreload2;
@@ -273,11 +273,11 @@ namespace UnitTest
noLoadAsset.m_asset = m_testAssetManager->CreateAsset<AssetWithSerializedData>(MyAsset2Id, AssetLoadBehavior::NoLoad);
EXPECT_EQ(m_assetHandlerAndCatalog->m_numCreations, 4);
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset1.txt", AZ::DataStream::ST_XML, &assetWithPreload1, m_serializeContext));
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset2.txt", AZ::DataStream::ST_XML, &assetWithPreload2, m_serializeContext));
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset3.txt", AZ::DataStream::ST_XML, &assetWithPreload3, m_serializeContext));
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "DelayLoadAsset.txt", AZ::DataStream::ST_XML, &delayedAsset, m_serializeContext));
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "NoLoadAsset.txt", AZ::DataStream::ST_XML, &noLoadAsset, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset1.txt", &assetWithPreload1, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset2.txt", &assetWithPreload2, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset3.txt", &assetWithPreload3, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("DelayLoadAsset.txt", &delayedAsset, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("NoLoadAsset.txt", &noLoadAsset, m_serializeContext));
AssetWithQueueAndPreLoadReferences preLoadRoot;
AssetWithQueueAndPreLoadReferences preLoadA;
@@ -297,16 +297,16 @@ namespace UnitTest
preLoadBrokenA.m_preLoad = m_testAssetManager->CreateAsset<AssetWithAssetReference>(PreloadBrokenDepBId, AssetLoadBehavior::PreLoad);
preLoadBrokenB.m_preLoad = m_testAssetManager->CreateAsset<AssetWithAssetReference>(PreloadAssetNoDataId, AssetLoadBehavior::PreLoad);
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "PreLoadRoot.txt", AZ::DataStream::ST_XML, &preLoadRoot, m_serializeContext));
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "PreLoadA.txt", AZ::DataStream::ST_XML, &preLoadA, m_serializeContext));
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "PreLoadB.txt", AZ::DataStream::ST_XML, &noRefs, m_serializeContext));
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "PreLoadC.txt", AZ::DataStream::ST_XML, &noRefs, m_serializeContext));
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "QueueLoadA.txt", AZ::DataStream::ST_XML, &queueLoadA, m_serializeContext));
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "QueueLoadB.txt", AZ::DataStream::ST_XML, &noRefs, m_serializeContext));
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "QueueLoadC.txt", AZ::DataStream::ST_XML, &noRefs, m_serializeContext));
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "PreLoadBrokenA.txt", AZ::DataStream::ST_XML, &preLoadBrokenA, m_serializeContext));
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "PreLoadBrokenB.txt", AZ::DataStream::ST_XML, &preLoadBrokenB, m_serializeContext));
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "PreLoadNoData.txt", AZ::DataStream::ST_XML, &noRefs, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("PreLoadRoot.txt", &preLoadRoot, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("PreLoadA.txt", &preLoadA, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("PreLoadB.txt", &noRefs, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("PreLoadC.txt", &noRefs, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("QueueLoadA.txt", &queueLoadA, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("QueueLoadB.txt", &noRefs, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("QueueLoadC.txt", &noRefs, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("PreLoadBrokenA.txt", &preLoadBrokenA, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("PreLoadBrokenB.txt", &preLoadBrokenB, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("PreLoadNoData.txt", &noRefs, m_serializeContext));
AssetWithQueueAndPreLoadReferences circularA;
AssetWithQueueAndPreLoadReferences circularB;
@@ -318,43 +318,15 @@ namespace UnitTest
circularC.m_preLoad = m_testAssetManager->CreateAsset<AssetWithAssetReference>(CircularBId, AssetLoadBehavior::PreLoad);
circularD.m_preLoad = circularC.m_preLoad;
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "CircularA.txt", AZ::DataStream::ST_XML, &circularA, m_serializeContext));
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "CircularB.txt", AZ::DataStream::ST_XML, &circularB, m_serializeContext));
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "CircularC.txt", AZ::DataStream::ST_XML, &circularC, m_serializeContext));
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "CircularD.txt", AZ::DataStream::ST_XML, &circularD, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("CircularA.txt", &circularA, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("CircularB.txt", &circularB, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("CircularC.txt", &circularC, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("CircularD.txt", &circularD, m_serializeContext));
m_assetHandlerAndCatalog->m_numCreations = 0;
}
}
void TearDownTest()
{
DeleteAssetFromDisk(GetTestFolderPath() + "TestAsset4.txt");
DeleteAssetFromDisk(GetTestFolderPath() + "TestAsset5.txt");
DeleteAssetFromDisk(GetTestFolderPath() + "TestAsset6.txt");
DeleteAssetFromDisk(GetTestFolderPath() + "TestAsset1.txt");
DeleteAssetFromDisk(GetTestFolderPath() + "TestAsset2.txt");
DeleteAssetFromDisk(GetTestFolderPath() + "TestAsset3.txt");
DeleteAssetFromDisk(GetTestFolderPath() + "DelayLoadAsset.txt");
DeleteAssetFromDisk(GetTestFolderPath() + "NoLoadAsset.txt");
DeleteAssetFromDisk(GetTestFolderPath() + "PreLoadRoot.txt");
DeleteAssetFromDisk(GetTestFolderPath() + "PreLoadA.txt");
DeleteAssetFromDisk(GetTestFolderPath() + "PreLoadB.txt");
DeleteAssetFromDisk(GetTestFolderPath() + "PreLoadC.txt");
DeleteAssetFromDisk(GetTestFolderPath() + "QueueLoadA.txt");
DeleteAssetFromDisk(GetTestFolderPath() + "QueueLoadB.txt");
DeleteAssetFromDisk(GetTestFolderPath() + "QueueLoadC.txt");
DeleteAssetFromDisk(GetTestFolderPath() + "PreLoadBrokenA.txt");
DeleteAssetFromDisk(GetTestFolderPath() + "PreLoadBrokenB.txt");
DeleteAssetFromDisk(GetTestFolderPath() + "PreLoadNoData.txt");
DeleteAssetFromDisk(GetTestFolderPath() + "CircularA.txt");
DeleteAssetFromDisk(GetTestFolderPath() + "CircularB.txt");
DeleteAssetFromDisk(GetTestFolderPath() + "CircularC.txt");
DeleteAssetFromDisk(GetTestFolderPath() + "CircularD.txt");
}
void CheckFinishedCreationsAndDestructions()
{
// Make sure asset jobs have finished before validating the number of destroyed assets, because it's possible that the asset job
@@ -367,7 +339,7 @@ namespace UnitTest
};
static constexpr AZStd::chrono::seconds MaxDispatchTimeoutSeconds = BaseAssetManagerTest::DefaultTimeoutSeconds * 12;
template <typename Pred>
bool DispatchEventsUntilCondition(AZ::Data::AssetManager& assetManager, Pred&& conditionPredicate,
AZStd::chrono::seconds logIntervalSeconds = BaseAssetManagerTest::DefaultTimeoutSeconds,
@@ -608,7 +580,7 @@ namespace UnitTest
AZ::Data::AssetData::AssetStatus expected_base_status = AZ::Data::AssetData::AssetStatus::Ready;
EXPECT_EQ(baseStatus, expected_base_status);
}
TEST_F(AssetJobsFloodTest, RapidAcquireAndRelease)
{
auto assetUuids = {
@@ -641,7 +613,7 @@ namespace UnitTest
{
Asset<AssetWithAssetReference> asset1 =
m_testAssetManager->GetAsset(assetUuid, azrtti_typeid<AssetWithAssetReference>(), AZ::Data::AssetLoadBehavior::PreLoad);
if (checkLoaded)
{
asset1.BlockUntilLoadComplete();
@@ -714,8 +686,8 @@ namespace UnitTest
AssetWithSerializedData ap;
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "a.txt", AZ::DataStream::ST_XML, &ap, m_serializeContext));
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "b.txt", AZ::DataStream::ST_XML, &ap, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("a.txt", &ap, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("b.txt", &ap, m_serializeContext));
}
auto& assetManager = AssetManager::Instance();
@@ -778,7 +750,7 @@ namespace UnitTest
* Verify that loads without using the Asset Container still work correctly
*/
class AssetContainerDisableTest
: public BaseAssetManagerTest
: public DisklessAssetManagerBase
{
public:
static inline const AZ::Uuid MyAsset1Id{ "{5B29FE2B-6B41-48C9-826A-C723951B0560}" };
@@ -797,7 +769,7 @@ namespace UnitTest
void SetUp() override
{
BaseAssetManagerTest::SetUp();
DisklessAssetManagerBase::SetUp();
SetupTest();
}
@@ -807,7 +779,7 @@ namespace UnitTest
AssetManager::Instance().UnregisterHandler(m_assetHandlerAndCatalog);
delete m_assetHandlerAndCatalog;
AssetManager::Destroy();
BaseAssetManagerTest::TearDown();
DisklessAssetManagerBase::TearDown();
}
void SetupAssets()
@@ -849,9 +821,9 @@ namespace UnitTest
AssetWithSerializedData ap2;
AssetWithSerializedData ap3;
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset4.txt", AZ::DataStream::ST_XML, &ap1, m_serializeContext));
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset5.txt", AZ::DataStream::ST_XML, &ap2, m_serializeContext));
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset6.txt", AZ::DataStream::ST_XML, &ap3, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset4.txt", &ap1, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset5.txt", &ap2, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset6.txt", &ap3, m_serializeContext));
AssetWithAssetReference assetWithPreload1;
AssetWithAssetReference assetWithPreload2;
@@ -862,9 +834,9 @@ namespace UnitTest
assetWithPreload3.m_asset = m_testAssetManager->CreateAsset<AssetWithSerializedData>(MyAsset6Id, AssetLoadBehavior::PreLoad);
EXPECT_EQ(m_assetHandlerAndCatalog->m_numCreations, 3);
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset1.txt", AZ::DataStream::ST_XML, &assetWithPreload1, m_serializeContext));
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset2.txt", AZ::DataStream::ST_XML, &assetWithPreload2, m_serializeContext));
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset3.txt", AZ::DataStream::ST_XML, &assetWithPreload3, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset1.txt", &assetWithPreload1, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset2.txt", &assetWithPreload2, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset3.txt", &assetWithPreload3, m_serializeContext));
m_assetHandlerAndCatalog->m_numCreations = 0;
}
@@ -942,11 +914,11 @@ namespace UnitTest
m_testAssetManager->SetParallelDependentLoadingEnabled(true);
}
#if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS || AZ_TRAIT_DISABLE_FAILED_ASSET_LOAD_TESTS
#if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
TEST_F(AssetJobsFloodTest, DISABLED_LoadTest_SameAsset_DifferentFilters)
#else
TEST_F(AssetJobsFloodTest, LoadTest_SameAsset_DifferentFilters)
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS || AZ_TRAIT_DISABLE_FAILED_ASSET_LOAD_TESTS
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
{
m_assetHandlerAndCatalog->AssetCatalogRequestBus::Handler::BusConnect();
@@ -1291,11 +1263,11 @@ namespace UnitTest
m_assetHandlerAndCatalog->AssetCatalogRequestBus::Handler::BusDisconnect();
}
#if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS || AZ_TRAIT_DISABLE_FAILED_ASSET_LOAD_TESTS
#if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
TEST_F(AssetJobsFloodTest, DISABLED_AssetWithNoLoadReference_LoadDependencies_NoLoadNotLoaded)
#else
TEST_F(AssetJobsFloodTest, AssetWithNoLoadReference_LoadDependencies_NoLoadNotLoaded)
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS || AZ_TRAIT_DISABLE_FAILED_ASSET_LOAD_TESTS
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
{
m_assetHandlerAndCatalog->AssetCatalogRequestBus::Handler::BusConnect();
// Setup has already created/destroyed assets
@@ -1332,11 +1304,11 @@ namespace UnitTest
m_assetHandlerAndCatalog->AssetCatalogRequestBus::Handler::BusDisconnect();
}
#if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS || AZ_TRAIT_DISABLE_FAILED_ASSET_LOAD_TESTS
#if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
TEST_F(AssetJobsFloodTest, DISABLED_AssetWithNoLoadReference_LoadContainerDependencies_LoadAllLoadsNoLoad)
#else
TEST_F(AssetJobsFloodTest, AssetWithNoLoadReference_LoadContainerDependencies_LoadAllLoadsNoLoad)
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS || AZ_TRAIT_DISABLE_FAILED_ASSET_LOAD_TESTS
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
{
m_assetHandlerAndCatalog->AssetCatalogRequestBus::Handler::BusConnect();
// Setup has already created/destroyed assets
@@ -1371,11 +1343,11 @@ namespace UnitTest
m_assetHandlerAndCatalog->AssetCatalogRequestBus::Handler::BusDisconnect();
}
#if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS || AZ_TRAIT_DISABLE_FAILED_ASSET_LOAD_TESTS
#if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
TEST_F(AssetJobsFloodTest, DISABLED_AssetWithNoLoadReference_LoadDependencies_BehaviorObeyed)
#else
TEST_F(AssetJobsFloodTest, AssetWithNoLoadReference_LoadDependencies_BehaviorObeyed)
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS || AZ_TRAIT_DISABLE_FAILED_ASSET_LOAD_TESTS
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
{
m_assetHandlerAndCatalog->AssetCatalogRequestBus::Handler::BusConnect();
// Setup has already created/destroyed assets
@@ -2014,11 +1986,12 @@ namespace UnitTest
CheckFinishedCreationsAndDestructions();
m_assetHandlerAndCatalog->AssetCatalogRequestBus::Handler::BusDisconnect();
}
/**
* Run multiple threads that get and release assets simultaneously to test AssetManager's thread safety
*/
class AssetJobsMultithreadedTest
: public BaseAssetManagerTest
: public DisklessAssetManagerBase
{
public:
static inline const AZ::Uuid MyAsset1Id{ "{5B29FE2B-6B41-48C9-826A-C723951B0560}" };
@@ -2028,6 +2001,7 @@ namespace UnitTest
static inline const AZ::Uuid MyAsset5Id{ "{D9CDAB04-D206-431E-BDC0-1DD615D56197}" };
static inline const AZ::Uuid MyAsset6Id{ "{B2F139C3-5032-4B52-ADCA-D52A8F88E043}" };
// Initialize the Job Manager with 2 threads for the Asset Manager to use.
size_t GetNumJobManagerThreads() const override { return 2; }
@@ -2078,9 +2052,9 @@ namespace UnitTest
AssetWithSerializedData ap2;
AssetWithSerializedData ap3;
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset4.txt", AZ::DataStream::ST_XML, &ap1, &context));
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset5.txt", AZ::DataStream::ST_XML, &ap2, &context));
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset6.txt", AZ::DataStream::ST_XML, &ap3, &context));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset4.txt", &ap1, &context));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset5.txt", &ap2, &context));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset6.txt", &ap3, &context));
AssetWithAssetReference assetWithPreload1;
AssetWithAssetReference assetWithPreload2;
@@ -2089,9 +2063,9 @@ namespace UnitTest
assetWithPreload2.m_asset = AssetManager::Instance().CreateAsset<AssetWithSerializedData>(MyAsset5Id, AssetLoadBehavior::PreLoad);
assetWithPreload3.m_asset = AssetManager::Instance().CreateAsset<AssetWithSerializedData>(MyAsset6Id, AssetLoadBehavior::PreLoad);
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset1.txt", AZ::DataStream::ST_XML, &assetWithPreload1, &context));
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset2.txt", AZ::DataStream::ST_XML, &assetWithPreload2, &context));
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset3.txt", AZ::DataStream::ST_XML, &assetWithPreload3, &context));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset1.txt", &assetWithPreload1, &context));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset2.txt", &assetWithPreload2, &context));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset3.txt", &assetWithPreload3, &context));
EXPECT_TRUE(assetHandlerAndCatalog->m_numCreations == 3);
assetHandlerAndCatalog->m_numCreations = 0;
@@ -2191,22 +2165,22 @@ namespace UnitTest
// A will be saved to disk with MyAsset1Id
AssetWithAssetReference a;
a.m_asset = AssetManager::Instance().CreateAsset<AssetWithSerializedData>(MyAsset2Id);
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset1.txt", AZ::DataStream::ST_XML, &a, &context));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset1.txt", &a, &context));
AssetWithAssetReference b;
b.m_asset = AssetManager::Instance().CreateAsset<AssetWithSerializedData>(MyAsset3Id);
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset2.txt", AZ::DataStream::ST_XML, &b, &context));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset2.txt", &b, &context));
AssetWithAssetReference c;
c.m_asset = AssetManager::Instance().CreateAsset<AssetWithSerializedData>(MyAsset4Id);
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset3.txt", AZ::DataStream::ST_XML, &c, &context));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset3.txt", &c, &context));
AssetWithAssetReference d;
d.m_asset = AssetManager::Instance().CreateAsset<AssetWithSerializedData>(MyAsset5Id);
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset4.txt", AZ::DataStream::ST_XML, &d, &context));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset4.txt", &d, &context));
AssetWithAssetReference e;
e.m_asset = AssetManager::Instance().CreateAsset<AssetWithSerializedData>(MyAsset6Id);
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset5.txt", AZ::DataStream::ST_XML, &e, &context));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset5.txt", &e, &context));
AssetWithAssetReference f;
f.m_asset = AssetManager::Instance().CreateAsset<AssetWithSerializedData>(MyAsset1Id); // refer back to asset1
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset6.txt", AZ::DataStream::ST_XML, &f, &context));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset6.txt", &f, &context));
EXPECT_TRUE(assetHandlerAndCatalog->m_numCreations == 6);
assetHandlerAndCatalog->m_numCreations = 0;
@@ -2347,26 +2321,26 @@ namespace UnitTest
// AssetD is MYASSETD
AssetWithSerializedData d;
d.m_data = 42;
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset4.txt", AZ::DataStream::ST_XML, &d, &context));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset4.txt", &d, &context));
// AssetC is MYASSETC
AssetWithAssetReference c;
c.m_asset = db.CreateAsset<AssetWithSerializedData>(AssetId(MyAssetDId)); // point at D
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset3.txt", AZ::DataStream::ST_XML, &c, &context));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset3.txt", &c, &context));
// AssetB is MYASSETB
AssetWithAssetReference b;
b.m_asset = db.CreateAsset<AssetWithAssetReference>(AssetId(MyAssetCId)); // point at C
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset2.txt", AZ::DataStream::ST_XML, &b, &context));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset2.txt", &b, &context));
// AssetA will be written to disk as MYASSETA
AssetWithAssetReference a;
a.m_asset = db.CreateAsset<AssetWithAssetReference>(AssetId(MyAssetBId)); // point at B
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset1.txt", AZ::DataStream::ST_XML, &a, &context));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset1.txt", &a, &context));
}
const size_t numThreads = 4;
AZStd::atomic_int threadCount(numThreads);
constexpr size_t NumThreads = 4;
AZStd::atomic_int threadCount(NumThreads);
AZStd::condition_variable cv;
AZStd::vector<AZStd::thread> threads;
AZStd::atomic_bool keepDispatching(true);
@@ -2381,7 +2355,7 @@ namespace UnitTest
AZStd::thread dispatchThread(dispatch);
for (size_t threadIdx = 0; threadIdx < numThreads; ++threadIdx)
for (size_t threadIdx = 0; threadIdx < NumThreads; ++threadIdx)
{
threads.emplace_back([&threadCount, &db, &cv]()
{
@@ -2569,7 +2543,6 @@ namespace UnitTest
#if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
TEST_F(AssetJobsMultithreadedTest, DISABLED_ParallelDeepAssetReferences)
#else
// temporarily disabled until sporadic failures can be root caused
TEST_F(AssetJobsMultithreadedTest, ParallelDeepAssetReferences)
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
{
@@ -2577,7 +2550,7 @@ namespace UnitTest
}
class AssetManagerTests
: public BaseAssetManagerTest
: public DisklessAssetManagerBase
{
protected:
static inline const AZ::Uuid MyAsset1Id{ "{5B29FE2B-6B41-48C9-826A-C723951B0560}" };
@@ -2592,7 +2565,7 @@ namespace UnitTest
void SetUp() override
{
BaseAssetManagerTest::SetUp();
DisklessAssetManagerBase::SetUp();
m_console = AZStd::make_unique<AZ::Console>();
AZ::Interface<AZ::IConsole>::Register(m_console.get());
@@ -2631,7 +2604,7 @@ namespace UnitTest
AssetManager::Destroy();
AZ::Interface<AZ::IConsole>::Unregister(m_console.get());
m_console = nullptr;
BaseAssetManagerTest::TearDown();
DisklessAssetManagerBase::TearDown();
}
};
@@ -2982,7 +2955,7 @@ namespace UnitTest
* the middle of loading. The tests help ensure that assets can't get stuck in perpetual loading states.
**/
class AssetManagerClearAssetReferenceTests
: public BaseAssetManagerTest
: public DisklessAssetManagerBase
{
protected:
static inline const AZ::Uuid RootAssetId{ "{AB13F568-C676-41FE-A7E9-341F71A78104}" };
@@ -3001,7 +2974,7 @@ namespace UnitTest
void SetUp() override
{
BaseAssetManagerTest::SetUp();
DisklessAssetManagerBase::SetUp();
// create the database
AssetManager::Descriptor desc;
@@ -3039,21 +3012,18 @@ namespace UnitTest
// Create and save the dependent asset first, so that we can get a reference to it.
AssetWithSerializedData dependentBlockingAsset;
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "DependentPreloadBlockingAsset.txt",
AZ::DataStream::ST_XML, &dependentBlockingAsset, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("DependentPreloadBlockingAsset.txt", &dependentBlockingAsset, m_serializeContext));
AssetWithAssetReference dependentAsset;
dependentAsset.m_asset = AssetManager::Instance().CreateAsset<AssetWithAssetReference>(
NestedDependentPreloadBlockingAssetId, AssetLoadBehavior::PreLoad);
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "DependentPreloadAsset.txt",
AZ::DataStream::ST_XML, &dependentAsset, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("DependentPreloadAsset.txt", &dependentAsset, m_serializeContext));
// Create and save the top-level asset.
AssetWithAssetReference rootAsset;
rootAsset.m_asset = AssetManager::Instance().CreateAsset<AssetWithAssetReference>(
DependentPreloadAssetId, AssetLoadBehavior::PreLoad);
EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "RootAsset.txt",
AZ::DataStream::ST_XML, &rootAsset, m_serializeContext));
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("RootAsset.txt", &rootAsset, m_serializeContext));
}
void TearDown() override
@@ -3065,7 +3035,7 @@ namespace UnitTest
delete m_assetHandlerAndCatalog;
AssetManager::Destroy();
BaseAssetManagerTest::TearDown();
DisklessAssetManagerBase::TearDown();
}
};
@@ -165,4 +165,254 @@ namespace UnitTest
EXPECT_FALSE(AssetManager::Instance().HasActiveJobsOrStreamerRequests());
}
MemoryStreamerWrapper::MemoryStreamerWrapper()
{
using ::testing::_;
using ::testing::NiceMock;
using ::testing::Return;
ON_CALL(m_mockStreamer, SuspendProcessing()).WillByDefault([this]()
{
m_suspended = true;
});
ON_CALL(m_mockStreamer, ResumeProcessing()).WillByDefault([this]()
{
AZStd::unique_lock lock(m_mutex);
m_suspended = false;
while (!m_processingQueue.empty())
{
FileRequestHandle requestHandle = m_processingQueue.front();
m_processingQueue.pop();
const auto& onCompleteCallback = GetReadRequest(requestHandle)->m_callback;
if (onCompleteCallback)
{
onCompleteCallback(requestHandle);
}
}
});
ON_CALL(m_mockStreamer, Read(_, ::testing::An<IStreamerTypes::RequestMemoryAllocator&>(), _, _, _, _))
.WillByDefault(
[this](
[[maybe_unused]] AZStd::string_view relativePath, IStreamerTypes::RequestMemoryAllocator& allocator, size_t size,
AZStd::chrono::microseconds deadline, IStreamerTypes::Priority priority, [[maybe_unused]] size_t offset)
{
AZStd::unique_lock lock(m_mutex);
ReadRequest request;
// Save off the requested deadline and priority
request.m_deadline = deadline;
request.m_priority = priority;
request.m_data = allocator.Allocate(size, size, 8);
const auto* virtualFile = FindFile(relativePath);
AZ_Assert(
virtualFile->size() == size, "Streamer read request size did not match size of saved file: %d vs %d (%.*s)",
virtualFile->size(), size,
relativePath.size(), relativePath.data());
AZ_Assert(size > 0, "Size is zero %.*s", relativePath.size(), relativePath.data());
memcpy(request.m_data.m_address, virtualFile->data(), size);
// Create a real file request result and return it
request.m_request = m_context.GetNewExternalRequest();
m_readRequests.push_back(request);
return request.m_request;
});
ON_CALL(m_mockStreamer, SetRequestCompleteCallback(_, _))
.WillByDefault([this](FileRequestPtr& request, AZ::IO::IStreamer::OnCompleteCallback callback) -> FileRequestPtr&
{
// Save off the callback just so that we can call it when the request is "done"
AZStd::unique_lock lock(m_mutex);
ReadRequest* readRequest = GetReadRequest(request);
readRequest->m_callback = callback;
return request;
});
ON_CALL(m_mockStreamer, QueueRequest(_))
.WillByDefault([this](const auto& fileRequest)
{
if (!m_suspended)
{
decltype(ReadRequest::m_callback) onCompleteCallback;
AZStd::unique_lock lock(m_mutex);
ReadRequest* readRequest = GetReadRequest(fileRequest);
onCompleteCallback = readRequest->m_callback;
if (onCompleteCallback)
{
onCompleteCallback(fileRequest);
m_readRequests.erase(readRequest);
}
}
else
{
AZStd::unique_lock lock(m_mutex);
m_processingQueue.push(fileRequest);
}
});
ON_CALL(m_mockStreamer, GetRequestStatus(_))
.WillByDefault([]([[maybe_unused]] FileRequestHandle request)
{
// Return whatever request status has been set in this class
return IO::IStreamerTypes::RequestStatus::Completed;
});
ON_CALL(m_mockStreamer, GetReadRequestResult(_, _, _, _))
.WillByDefault([this](
[[maybe_unused]] FileRequestHandle request, void*& buffer, AZ::u64& numBytesRead,
IStreamerTypes::ClaimMemory claimMemory)
{
// Make sure the requestor plans to free the data buffer we allocated.
EXPECT_EQ(claimMemory, IStreamerTypes::ClaimMemory::Yes);
AZStd::unique_lock lock(m_mutex);
ReadRequest* readRequest = GetReadRequest(request);
// Provide valid data buffer results.
numBytesRead = readRequest->m_data.m_size;
buffer = readRequest->m_data.m_address;
return true;
});
ON_CALL(m_mockStreamer, RescheduleRequest(_, _, _))
.WillByDefault([this](IO::FileRequestPtr target, AZStd::chrono::microseconds newDeadline, IO::IStreamerTypes::Priority newPriority)
{
AZStd::unique_lock lock(m_mutex);
ReadRequest* readRequest = GetReadRequest(target);
readRequest->m_deadline = newDeadline;
readRequest->m_priority = newPriority;
return target;
});
}
ReadRequest* MemoryStreamerWrapper::GetReadRequest(FileRequestHandle request)
{
auto itr = AZStd::find_if(
m_readRequests.begin(), m_readRequests.end(),
[request](const ReadRequest& searchItem) -> bool
{
return (searchItem.m_request == request);
});
return itr;
}
AZStd::vector<char>* MemoryStreamerWrapper::FindFile(AZStd::string_view path)
{
auto itr = m_virtualFiles.find(path);
if (itr == m_virtualFiles.end())
{
// Path didn't work as-is, does it have the test folder prefixed? If so try removing it
if (AZ::StringFunc::StartsWith(path, GetTestFolderPath()))
{
AZStd::string_view pathWithoutFolder = path;
pathWithoutFolder = AZ::StringFunc::LStrip(pathWithoutFolder, GetTestFolderPath().c_str());
itr = m_virtualFiles.find(pathWithoutFolder);
}
else // Path isn't prefixed, so try adding it
{
itr = m_virtualFiles.find(GetTestFolderPath().append(path));
}
}
if (itr != m_virtualFiles.end())
{
return &itr->second;
}
// Currently no test expects a file not to exist so we assert to make it easy to quickly find where something went wrong
// If we ever need to test for a non-existent file this assert should just be conditionally disabled for that specific test
AZ_Assert(false, "Failed to find virtual file %*.s", path.size(), path.data())
return nullptr;
}
void DisklessAssetManagerBase::SetUp()
{
using ::testing::_;
using ::testing::NiceMock;
using ::testing::Return;
BaseAssetManagerTest::SetUp();
ON_CALL(m_fileIO, Size(::testing::Matcher<const char*>(::testing::_), _))
.WillByDefault(
[this](const char* path, u64& size)
{
AZStd::scoped_lock lock(m_streamerWrapper->m_mutex);
const auto* file = m_streamerWrapper->FindFile(path);
if (file)
{
size = file->size();
return ResultCode::Success;
}
AZ_Error("DisklessAssetManagerBase", false, "Failed to find virtual file %.*s", path);
return ResultCode::Error;
});
m_prevFileIO = IO::FileIOBase::GetInstance();
IO::FileIOBase::SetInstance(nullptr);
IO::FileIOBase::SetInstance(&m_fileIO);
}
void DisklessAssetManagerBase::TearDown()
{
IO::FileIOBase::SetInstance(nullptr);
IO::FileIOBase::SetInstance(m_prevFileIO);
BaseAssetManagerTest::TearDown();
}
IO::IStreamer* DisklessAssetManagerBase::CreateStreamer()
{
m_streamerWrapper = AZStd::make_unique<MemoryStreamerWrapper>();
return &(m_streamerWrapper->m_mockStreamer);
}
void DisklessAssetManagerBase::DestroyStreamer(IO::IStreamer*)
{
m_streamerWrapper = nullptr;
}
void DisklessAssetManagerBase::WriteAssetToDisk(const AZStd::string& assetName, const AZStd::string&)
{
AZStd::string assetFileName = GetTestFolderPath() + assetName;
AssetWithCustomData asset;
EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile(assetFileName, &asset, m_serializeContext));
}
void DisklessAssetManagerBase::DeleteAssetFromDisk(const AZStd::string&)
{
}
}
@@ -20,7 +20,8 @@
#include <Tests/Asset/TestAssetTypes.h>
#include <Tests/SerializeContextFixture.h>
#include <Tests/TestCatalog.h>
#include <AzCore/UnitTest/Mocks/MockFileIOBase.h>
#include <Streamer/IStreamerMock.h>
namespace UnitTest
{
@@ -58,7 +59,11 @@ namespace UnitTest
// Subclasses can optionally override the streamer creation and destruction
virtual IO::IStreamer* CreateStreamer() { return aznew IO::Streamer(AZStd::thread_desc{}, StreamerComponent::CreateStreamerStack()); }
virtual void DestroyStreamer(IO::IStreamer* streamer) { delete streamer; }
virtual void DestroyStreamer(IO::IStreamer* streamer)
{
delete streamer;
streamer = nullptr;
}
void SetUp() override;
void TearDown() override;
@@ -66,8 +71,8 @@ namespace UnitTest
static void SuppressTraceOutput(bool suppress);
// Helper methods to create and destroy actual assets on the disk for true end-to-end asset loading.
void WriteAssetToDisk(const AZStd::string& assetName, const AZStd::string& assetIdGuid);
void DeleteAssetFromDisk(const AZStd::string& assetName);
virtual void WriteAssetToDisk(const AZStd::string& assetName, const AZStd::string& assetIdGuid);
virtual void DeleteAssetFromDisk(const AZStd::string& assetName);
void BlockUntilAssetJobsAreComplete();
@@ -82,4 +87,57 @@ namespace UnitTest
AZStd::vector<AZStd::string> m_assetsWritten;
};
struct ReadRequest
{
AZStd::chrono::milliseconds m_deadline{};
AZ::IO::IStreamerTypes::Priority m_priority{};
IO::IStreamerTypes::RequestMemoryAllocatorResult m_data{ nullptr, 0, IO::IStreamerTypes::MemoryType::ReadWrite };
AZ::IO::IStreamer::OnCompleteCallback m_callback;
IO::FileRequestPtr m_request;
};
struct MemoryStreamerWrapper
{
MemoryStreamerWrapper();
~MemoryStreamerWrapper() = default;
ReadRequest* GetReadRequest(IO::FileRequestHandle request);
template<typename TObject>
bool WriteMemoryFile(const AZStd::string& filePath, TObject* object, AZ::SerializeContext* context)
{
auto& buffer = m_virtualFiles[filePath];
ByteContainerStream stream(&buffer);
return AZ::Utils::SaveObjectToStream(stream, DataStream::StreamType::ST_XML, object, context);
}
AZStd::vector<char>* FindFile(AZStd::string_view path);
::testing::NiceMock<StreamerMock> m_mockStreamer;
IO::StreamerContext m_context;
AZStd::atomic_bool m_suspended{ false };
AZStd::recursive_mutex m_mutex;
AZStd::queue<FileRequestHandle> m_processingQueue; // Keeps tracks of requests that have been queued while processing is suspended
AZStd::vector<ReadRequest> m_readRequests;
AZStd::unordered_map<AZStd::string, AZStd::vector<char>> m_virtualFiles;
};
struct DisklessAssetManagerBase : BaseAssetManagerTest
{
void SetUp() override;
void TearDown() override;
IO::IStreamer* CreateStreamer() override;
void DestroyStreamer(IO::IStreamer*) override;
void WriteAssetToDisk(const AZStd::string& assetName, const AZStd::string& assetIdGuid) override;
void DeleteAssetFromDisk(const AZStd::string& assetName) override;
AZStd::unique_ptr<MemoryStreamerWrapper> m_streamerWrapper;
::testing::NiceMock<MockFileIOBase> m_fileIO;
IO::FileIOBase* m_prevFileIO{};
};
}
@@ -175,7 +175,6 @@ namespace UnitTest
ComponentApplication componentApp;
ComponentApplication::Descriptor desc;
desc.m_useExistingAllocator = true;
desc.m_enableDrilling = false; // we already created a memory driller for the test (AllocatorsFixture)
ComponentApplication::StartupParameters startupParams;
startupParams.m_allocator = &AZ::AllocatorInstance<AZ::SystemAllocator>::Get();
Entity* systemEntity = componentApp.Create(desc, startupParams);
@@ -631,7 +630,6 @@ namespace UnitTest
ComponentApplication::Descriptor desc;
desc.m_useExistingAllocator = true;
desc.m_enableDrilling = false; // we already created a memory driller for the test (AllocatorsFixture in Components)
ComponentApplication::StartupParameters startupParams;
startupParams.m_allocator = &AZ::AllocatorInstance<AZ::SystemAllocator>::Get();
@@ -0,0 +1,185 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#if defined(HAVE_BENCHMARK)
#include <AzCore/DOM/DomUtils.h>
#include <AzCore/DOM/Backends/JSON/JsonBackend.h>
#include <AzCore/DOM/Backends/JSON/JsonSerializationUtils.h>
#include <AzCore/JSON/document.h>
#include <AzCore/Name/NameDictionary.h>
#include <AzCore/Serialization/Json/JsonUtils.h>
#include <AzCore/UnitTest/TestTypes.h>
namespace Benchmark
{
class DomJsonBenchmark : public UnitTest::AllocatorsBenchmarkFixture
{
public:
void SetUp(const ::benchmark::State& st) override
{
UnitTest::AllocatorsBenchmarkFixture::SetUp(st);
AZ::NameDictionary::Create();
}
void SetUp(::benchmark::State& st) override
{
UnitTest::AllocatorsBenchmarkFixture::SetUp(st);
AZ::NameDictionary::Create();
}
void TearDown(::benchmark::State& st) override
{
AZ::NameDictionary::Destroy();
UnitTest::AllocatorsBenchmarkFixture::TearDown(st);
}
void TearDown(const ::benchmark::State& st) override
{
AZ::NameDictionary::Destroy();
UnitTest::AllocatorsBenchmarkFixture::TearDown(st);
}
AZStd::string GenerateDomJsonBenchmarkPayload(int64_t entryCount, int64_t stringTemplateLength)
{
rapidjson::Document document;
document.SetObject();
AZStd::string entryTemplate;
while (entryTemplate.size() < static_cast<size_t>(stringTemplateLength))
{
entryTemplate += "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor ";
}
entryTemplate.resize(stringTemplateLength);
AZStd::string buffer;
auto createString = [&](int n) -> rapidjson::Value
{
buffer = AZStd::string::format("#%i %s", n, entryTemplate.c_str());
return rapidjson::Value(buffer.data(), static_cast<rapidjson::SizeType>(buffer.size()), document.GetAllocator());
};
auto createEntry = [&](int n) -> rapidjson::Value
{
rapidjson::Value entry(rapidjson::kObjectType);
entry.AddMember("string", createString(n), document.GetAllocator());
entry.AddMember("int", rapidjson::Value(n), document.GetAllocator());
entry.AddMember("double", rapidjson::Value(static_cast<double>(n) * 0.5), document.GetAllocator());
entry.AddMember("bool", rapidjson::Value(n % 2 == 0), document.GetAllocator());
entry.AddMember("null", rapidjson::Value(rapidjson::kNullType), document.GetAllocator());
return entry;
};
auto createArray = [&]() -> rapidjson::Value
{
rapidjson::Value array;
array.SetArray();
for (int i = 0; i < entryCount; ++i)
{
array.PushBack(createEntry(i), document.GetAllocator());
}
return array;
};
auto createObject = [&]() -> rapidjson::Value
{
rapidjson::Value object;
object.SetObject();
for (int i = 0; i < entryCount; ++i)
{
buffer = AZStd::string::format("Key%i", i);
rapidjson::Value key;
key.SetString(buffer.data(), static_cast<rapidjson::SizeType>(buffer.length()), document.GetAllocator());
object.AddMember(key.Move(), createArray(), document.GetAllocator());
}
return object;
};
document.SetObject();
document.AddMember("entries", createObject(), document.GetAllocator());
AZStd::string serializedJson;
auto result = AZ::JsonSerializationUtils::WriteJsonString(document, serializedJson);
AZ_Assert(result.IsSuccess(), "Failed to serialize generated JSON");
return serializedJson;
}
};
// Helper macro for registering JSON benchmarks
#define BENCHMARK_REGISTER_JSON(BaseClass, Method) \
BENCHMARK_REGISTER_F(BaseClass, Method) \
->Args({ 10, 5 }) \
->Args({ 10, 500 }) \
->Args({ 100, 5 }) \
->Args({ 100, 500 }) \
->Unit(benchmark::kMillisecond);
BENCHMARK_DEFINE_F(DomJsonBenchmark, DomDeserializeToDocumentInPlace)(benchmark::State& state)
{
AZ::Dom::JsonBackend backend;
AZStd::string serializedPayload = GenerateDomJsonBenchmarkPayload(state.range(0), state.range(1));
for (auto _ : state)
{
state.PauseTiming();
AZStd::string payloadCopy = serializedPayload;
state.ResumeTiming();
auto result = AZ::Dom::Json::WriteToRapidJsonDocument(
[&](AZ::Dom::Visitor& visitor)
{
return AZ::Dom::Utils::ReadFromStringInPlace(backend, payloadCopy, visitor);
});
benchmark::DoNotOptimize(result.GetValue());
}
state.SetBytesProcessed(serializedPayload.size() * state.iterations());
}
BENCHMARK_REGISTER_JSON(DomJsonBenchmark, DomDeserializeToDocumentInPlace)
BENCHMARK_DEFINE_F(DomJsonBenchmark, DomDeserializeToDocument)(benchmark::State& state)
{
AZ::Dom::JsonBackend backend;
AZStd::string serializedPayload = GenerateDomJsonBenchmarkPayload(state.range(0), state.range(1));
for (auto _ : state)
{
auto result = AZ::Dom::Json::WriteToRapidJsonDocument(
[&](AZ::Dom::Visitor& visitor)
{
return AZ::Dom::Utils::ReadFromString(backend, serializedPayload, AZ::Dom::Lifetime::Temporary, visitor);
});
benchmark::DoNotOptimize(result.GetValue());
}
state.SetBytesProcessed(serializedPayload.size() * state.iterations());
}
BENCHMARK_REGISTER_JSON(DomJsonBenchmark, DomDeserializeToDocument)
BENCHMARK_DEFINE_F(DomJsonBenchmark, JsonUtilsDeserializeToDocument)(benchmark::State& state)
{
AZ::Dom::JsonBackend backend;
AZStd::string serializedPayload = GenerateDomJsonBenchmarkPayload(state.range(0), state.range(1));
for (auto _ : state)
{
auto result = AZ::JsonSerializationUtils::ReadJsonString(serializedPayload);
benchmark::DoNotOptimize(result.GetValue());
}
state.SetBytesProcessed(serializedPayload.size() * state.iterations());
}
BENCHMARK_REGISTER_JSON(DomJsonBenchmark, JsonUtilsDeserializeToDocument)
#undef BENCHMARK_REGISTER_JSON
} // namespace Benchmark
#endif // defined(HAVE_BENCHMARK)
@@ -0,0 +1,219 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/DOM/Backends/JSON/JsonBackend.h>
#include <AzCore/DOM/Backends/JSON/JsonSerializationUtils.h>
#include <AzCore/DOM/DomUtils.h>
#include <AzCore/Name/NameDictionary.h>
#include <AzCore/Serialization/Json/JsonSerialization.h>
#include <AzCore/Serialization/Json/JsonUtils.h>
#include <AzCore/UnitTest/TestTypes.h>
namespace AZ::Dom::Tests
{
class DomJsonTests : public UnitTest::AllocatorsFixture
{
public:
void SetUp() override
{
UnitTest::AllocatorsFixture::SetUp();
NameDictionary::Create();
m_document = AZStd::make_unique<rapidjson::Document>();
}
void TearDown() override
{
m_document.reset();
NameDictionary::Destroy();
UnitTest::AllocatorsFixture::TearDown();
}
rapidjson::Value CreateString(const AZStd::string& text)
{
rapidjson::Value key;
key.SetString(text.c_str(), static_cast<rapidjson::SizeType>(text.length()), m_document->GetAllocator());
return key;
}
template<class T>
void AddValue(const AZStd::string& key, T value)
{
m_document->AddMember(CreateString(key), rapidjson::Value(value), m_document->GetAllocator());
}
// Validate round-trip serialization to and from rapidjson::Document and a UTF-8 encoded string
void PerformSerializationChecks()
{
// Generate a canonical serializaed representation of this document using rapidjson
// This will be pretty-printed using the same rapidjson pretty printer we use, so should be binary identical
// to any output generated by the visitor API
AZStd::string canonicalSerializedDocument;
AZ::JsonSerializationUtils::WriteJsonString(*m_document, canonicalSerializedDocument);
auto visitDocumentFn = [this](AZ::Dom::Visitor& visitor)
{
return Json::VisitRapidJsonValue(*m_document, visitor, Lifetime::Temporary);
};
// Document -> Document
{
auto result = Json::WriteToRapidJsonDocument(visitDocumentFn);
EXPECT_TRUE(result.IsSuccess());
EXPECT_EQ(AZ::JsonSerialization::Compare(*m_document, result.GetValue()), AZ::JsonSerializerCompareResult::Equal);
}
// Document -> string
{
AZStd::string serializedDocument;
JsonBackend backend;
auto result = backend.WriteToBuffer(serializedDocument, visitDocumentFn);
EXPECT_TRUE(result.IsSuccess());
EXPECT_EQ(canonicalSerializedDocument, serializedDocument);
}
// string -> Document
{
auto result = Json::WriteToRapidJsonDocument(
[&canonicalSerializedDocument](AZ::Dom::Visitor& visitor)
{
JsonBackend backend;
return Dom::Utils::ReadFromString(backend, canonicalSerializedDocument, Lifetime::Temporary, visitor);
});
EXPECT_TRUE(result.IsSuccess());
EXPECT_EQ(AZ::JsonSerialization::Compare(*m_document, result.GetValue()), JsonSerializerCompareResult::Equal);
}
// string -> string
{
AZStd::string serializedDocument;
JsonBackend backend;
auto result = backend.WriteToBuffer(
serializedDocument,
[&backend, &canonicalSerializedDocument](AZ::Dom::Visitor& visitor)
{
return Dom::Utils::ReadFromString(backend, canonicalSerializedDocument, Lifetime::Temporary, visitor);
});
EXPECT_TRUE(result.IsSuccess());
EXPECT_EQ(canonicalSerializedDocument, serializedDocument);
}
}
AZStd::unique_ptr<rapidjson::Document> m_document;
};
TEST_F(DomJsonTests, EmptyArray)
{
m_document->SetArray();
PerformSerializationChecks();
}
TEST_F(DomJsonTests, SimpleArray)
{
m_document->SetArray();
for (int i = 0; i < 5; ++i)
{
m_document->PushBack(i, m_document->GetAllocator());
}
PerformSerializationChecks();
}
TEST_F(DomJsonTests, NestedArrays)
{
m_document->SetArray();
for (int j = 0; j < 7; ++j)
{
rapidjson::Value nestedArray(rapidjson::kArrayType);
for (int i = 0; i < 5; ++i)
{
nestedArray.PushBack(i, m_document->GetAllocator());
}
m_document->PushBack(nestedArray.Move(), m_document->GetAllocator());
}
PerformSerializationChecks();
}
TEST_F(DomJsonTests, EmptyObject)
{
m_document->SetObject();
PerformSerializationChecks();
}
TEST_F(DomJsonTests, SimpleObject)
{
m_document->SetObject();
for (int i = 0; i < 5; ++i)
{
m_document->AddMember(CreateString(AZStd::string::format("Key%i", i)), rapidjson::Value(i), m_document->GetAllocator());
}
PerformSerializationChecks();
}
TEST_F(DomJsonTests, NestedObjects)
{
m_document->SetObject();
for (int j = 0; j < 7; ++j)
{
rapidjson::Value nestedObject(rapidjson::kObjectType);
for (int i = 0; i < 5; ++i)
{
nestedObject.AddMember(CreateString(AZStd::string::format("Key%i", i)), rapidjson::Value(i), m_document->GetAllocator());
}
m_document->AddMember(CreateString(AZStd::string::format("Obj%i", j)), nestedObject.Move(), m_document->GetAllocator());
}
PerformSerializationChecks();
}
TEST_F(DomJsonTests, Int64)
{
m_document->SetObject();
AddValue("int64_min", AZStd::numeric_limits<int64_t>::min());
AddValue("int64_max", AZStd::numeric_limits<int64_t>::max());
PerformSerializationChecks();
}
TEST_F(DomJsonTests, Uint64)
{
m_document->SetObject();
AddValue("uint64_min", AZStd::numeric_limits<uint64_t>::min());
AddValue("uint64_max", AZStd::numeric_limits<uint64_t>::max());
PerformSerializationChecks();
}
TEST_F(DomJsonTests, Double)
{
m_document->SetObject();
AddValue("double_min", AZStd::numeric_limits<double>::min());
AddValue("double_max", AZStd::numeric_limits<double>::max());
PerformSerializationChecks();
}
TEST_F(DomJsonTests, Null)
{
m_document->SetObject();
m_document->AddMember(CreateString("null_value"), rapidjson::Value(rapidjson::kNullType), m_document->GetAllocator());
PerformSerializationChecks();
}
TEST_F(DomJsonTests, Bool)
{
m_document->SetObject();
AddValue("true_value", true);
AddValue("false_value", false);
PerformSerializationChecks();
}
TEST_F(DomJsonTests, String)
{
m_document->SetObject();
m_document->AddMember(CreateString("empty_string"), CreateString(""), m_document->GetAllocator());
m_document->AddMember(CreateString("short_string"), CreateString("test"), m_document->GetAllocator());
m_document->AddMember(
CreateString("long_string"), CreateString("abcdefghijklmnopqrstuvwxyz0123456789"), m_document->GetAllocator());
PerformSerializationChecks();
}
} // namespace AZ::Dom::Tests
+5 -4
View File
@@ -7,7 +7,7 @@
*/
#include <AzCore/Debug/StackTracer.h>
#include <AzCore/Debug/TraceMessagesDrillerBus.h>
#include <AzCore/Debug/TraceMessageBus.h>
#include <AzCore/Debug/Profiler.h>
#include <AzCore/std/parallel/thread.h>
#include <AzCore/Math/Crc.h>
@@ -104,7 +104,7 @@ namespace UnitTest
}
class TraceTest
: public AZ::Debug::TraceMessageDrillerBus::Handler
: public AZ::Debug::TraceMessageBus::Handler
, public ::testing::Test
{
int m_numTracePrintfs;
@@ -113,12 +113,13 @@ namespace UnitTest
: m_numTracePrintfs(0) {}
//////////////////////////////////////////////////////////////////////////
// TraceMessagesDrillerBus
void OnPrintf(const char* windowName, const char* message) override
// TraceMessageBus
bool OnPrintf(const char* windowName, const char* message) override
{
(void)windowName;
(void)message;
++m_numTracePrintfs;
return false;
}
//////////////////////////////////////////////////////////////////////////
@@ -1,169 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/Debug/AssetTrackingTypesImpl.h>
#include <AzCore/Debug/AssetTracking.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzCore/std/smart_ptr/unique_ptr.h>
using namespace AZ;
namespace UnitTest
{
namespace
{
struct TestData
{
};
using AssetTree = AZ::Debug::AssetTree<TestData>;
using AllocationTable = AZ::Debug::AllocationTable<TestData>;
struct AssetTrackingTestEnvironment
{
AssetTrackingTestEnvironment() : m_table(m_mutex)
{
}
AZStd::mutex m_mutex;
AssetTree m_tree;
AllocationTable m_table;
AZStd::unique_ptr<AZ::Debug::AssetTracking> m_assetTracking;
};
}
class AssetTrackingTests
: public ::testing::Test
{
public:
void SetUp() override
{
AZ::AllocatorInstance<AZ::Debug::AssetTrackingAllocator>::Create();
m_env.reset(new AssetTrackingTestEnvironment);
m_env->m_assetTracking.reset(aznew AZ::Debug::AssetTracking(&m_env->m_tree, &m_env->m_table));
}
void TearDown() override
{
m_env.reset();
AZ::AllocatorInstance<AZ::Debug::AssetTrackingAllocator>::Destroy();
}
void RunTests()
{
TestAssetScopes();
TestScopedAllocation();
TestScopeAttach();
}
private:
void TestAssetScopes()
{
const char* debugScopeText;
{
AZ_ASSET_NAMED_SCOPE("TestAssetScopes.1");
{
AZ_ASSET_NAMED_SCOPE("TestAssetScopes.2");
{
AZ_ASSET_NAMED_SCOPE("TestAssetScopes.3");
debugScopeText = AZ::Debug::AssetTracking::GetDebugScope();
EXPECT_STREQ(debugScopeText, "TestAssetScopes.3\nTestAssetScopes.2\nTestAssetScopes.1\n");
}
debugScopeText = AZ::Debug::AssetTracking::GetDebugScope();
EXPECT_STREQ(debugScopeText, "TestAssetScopes.2\nTestAssetScopes.1\n");
}
debugScopeText = AZ::Debug::AssetTracking::GetDebugScope();
EXPECT_STREQ(debugScopeText, "TestAssetScopes.1\n");
}
}
void TestScopedAllocation()
{
void* TEST_POINTER = (void*)0xDEADBEEFull;
static const size_t TEST_SIZE = 32;
{
AZ_ASSET_NAMED_SCOPE("TestScopedAllocation.1");
AZ::Debug::AssetTreeNodeBase* activeAsset = m_env->m_assetTracking->GetCurrentThreadAsset();
m_env->m_table.Get().emplace(TEST_POINTER, AllocationTable::RecordType{ activeAsset, (uint32_t)TEST_SIZE, TestData() });
}
auto& rootAsset = m_env->m_tree.m_rootAssets;
auto itr = rootAsset.m_children.find("TestScopedAllocation.1");
EXPECT_EQ(&rootAsset, &m_env->m_tree.GetRoot());
ASSERT_NE(itr, rootAsset.m_children.end());
EXPECT_EQ(itr->second.m_primaryinfo->m_id->m_id, "TestScopedAllocation.1");
EXPECT_EQ(&itr->second, m_env->m_table.FindAllocation(TEST_POINTER));
auto allocationRecord = m_env->m_table.Get().find(TEST_POINTER);
ASSERT_NE(allocationRecord, m_env->m_table.Get().end());
EXPECT_EQ(allocationRecord->second.m_asset, &itr->second);
EXPECT_EQ(allocationRecord->second.m_size, TEST_SIZE);
// Test realocation
void* TEST_REALLOC_POINTER = (void*)0xDEADC0DEull;
static const size_t TEST_REALLOC_SIZE = 128;
m_env->m_table.ReallocateAllocation(TEST_POINTER, TEST_REALLOC_POINTER, TEST_REALLOC_SIZE);
allocationRecord = m_env->m_table.Get().find(TEST_POINTER);
EXPECT_EQ(allocationRecord, m_env->m_table.Get().end());
allocationRecord = m_env->m_table.Get().find(TEST_REALLOC_POINTER);
ASSERT_NE(allocationRecord, m_env->m_table.Get().end());
EXPECT_EQ(allocationRecord->second.m_asset, &itr->second);
EXPECT_EQ(allocationRecord->second.m_size, TEST_REALLOC_SIZE);
// Test resize
static const size_t TEST_RESIZE_SIZE = 1024;
m_env->m_table.ResizeAllocation(TEST_REALLOC_POINTER, TEST_RESIZE_SIZE);
EXPECT_EQ(allocationRecord->second.m_size, TEST_RESIZE_SIZE);
}
void TestScopeAttach()
{
void* TEST_POINTER = (void*)0xDEADBEEFull;
static const size_t TEST_SIZE = 32;
AZ::Debug::AssetTreeNodeBase* originatingAsset;
{
AZ_ASSET_ATTACH_TO_SCOPE(TEST_POINTER);
EXPECT_EQ(m_env->m_assetTracking->GetCurrentThreadAsset(), nullptr);
}
{
AZ_ASSET_NAMED_SCOPE("TestScopeAttach.1");
{
AZ_ASSET_NAMED_SCOPE("TestScopeAttach.2");
{
originatingAsset = m_env->m_assetTracking->GetCurrentThreadAsset();
EXPECT_NE(originatingAsset, nullptr);
m_env->m_table.Get().emplace(TEST_POINTER, AllocationTable::RecordType{ originatingAsset, (uint32_t)TEST_SIZE, TestData() });
}
}
}
EXPECT_EQ(m_env->m_assetTracking->GetCurrentThreadAsset(), nullptr);
{
AZ_ASSET_ATTACH_TO_SCOPE(TEST_POINTER);
EXPECT_EQ(m_env->m_assetTracking->GetCurrentThreadAsset(), originatingAsset);
}
}
AZStd::unique_ptr<AssetTrackingTestEnvironment> m_env;
};
TEST_F(AssetTrackingTests, Test)
{
RunTests();
}
}
+6 -6
View File
@@ -2500,7 +2500,7 @@ namespace UnitTest
namespace RoutingTest
{
class DrillerInterceptor : public EBusVersion1::Router
class EBusInterceptor : public EBusVersion1::Router
{
public:
void OnEvent(int a) override
@@ -2555,20 +2555,20 @@ namespace UnitTest
TEST_F(EBus, Routing)
{
using namespace RoutingTest;
DrillerInterceptor driller;
EBusInterceptor interceptor;
EBusVersion1Handler v1Handler;
v1Handler.BusConnect();
driller.BusRouterConnect();
interceptor.BusRouterConnect();
EBusVersion1::Broadcast(&EBusVersion1::Events::OnEvent, 1020);
EXPECT_EQ(1, driller.m_numOnEvent);
EXPECT_EQ(1, interceptor.m_numOnEvent);
EXPECT_EQ(1, v1Handler.m_numOnEvent);
driller.BusRouterDisconnect();
interceptor.BusRouterDisconnect();
EBusVersion1::Broadcast(&EBusVersion1::Events::OnEvent, 1020);
EXPECT_EQ(1, driller.m_numOnEvent);
EXPECT_EQ(1, interceptor.m_numOnEvent);
EXPECT_EQ(2, v1Handler.m_numOnEvent);
// routing events
@@ -402,17 +402,18 @@ namespace UnitTest
AllocatorsFixture::SetUp();
AZ::ComponentApplication::Descriptor desc;
desc.m_useExistingAllocator = true;
desc.m_enableDrilling = false; // we already created a memory driller for the test (AllocatorsFixture)
m_app.Create(desc);
m_app.reset(aznew AZ::ComponentApplication);
m_app->Create(desc);
}
void TearDown() override
{
m_app.Destroy();
m_app->Destroy();
m_app.reset();
AllocatorsFixture::TearDown();
}
AZ::ComponentApplication m_app;
AZStd::unique_ptr<AZ::ComponentApplication> m_app;
};
TEST_F(MATH_TransformApplicationFixture, DeserializingOldFormat)
+2 -7
View File
@@ -12,8 +12,6 @@
#include <AzCore/Memory/HeapSchema.h>
#include <AzCore/Memory/HphaSchema.h>
#include <AzCore/Driller/Driller.h>
#include <AzCore/Memory/MemoryDriller.h>
#include <AzCore/Memory/AllocationRecords.h>
#include <AzCore/Debug/StackTracer.h>
#include <AzCore/UnitTest/TestTypes.h>
@@ -44,16 +42,13 @@ namespace UnitTest
void SetUp() override
{
AZ::AllocatorManager::Instance().SetDefaultTrackingMode(AZ::Debug::AllocationRecords::RECORD_FULL);
m_drillerManager = Debug::DrillerManager::Create();
m_drillerManager->Register(aznew MemoryDriller);
AZ::AllocatorManager::Instance().EnterProfilingMode();
}
void TearDown() override
{
Debug::DrillerManager::Destroy(m_drillerManager);
AZ::AllocatorManager::Instance().ExitProfilingMode();
AZ::AllocatorManager::Instance().SetDefaultTrackingMode(AZ::Debug::AllocationRecords::RECORD_NO_RECORDS);
}
protected:
Debug::DrillerManager* m_drillerManager = nullptr;
};
class SystemAllocatorTest
@@ -270,8 +270,7 @@ namespace UnitTest
void SetUp() override
{
m_drillerManager = AZ::Debug::DrillerManager::Create();
m_drillerManager->Register(aznew AZ::Debug::MemoryDriller);
AZ::AllocatorManager::Instance().EnterProfilingMode();
AZ::AllocatorManager::Instance().SetDefaultTrackingMode(AZ::Debug::AllocationRecords::RECORD_FULL);
if (azrtti_typeid<AllocatorType>() != azrtti_typeid<AZ::SystemAllocator>()) // simplifies instead of template specialization
@@ -292,7 +291,7 @@ namespace UnitTest
// Other allocators need the SystemAllocator in order to work
AZ::AllocatorInstance<AZ::SystemAllocator>::Destroy();
}
AZ::Debug::DrillerManager::Destroy(m_drillerManager);
AZ::AllocatorManager::Instance().ExitProfilingMode();
m_busRedirector.BusDisconnect();
EXPECT_EQ(m_leakExpected, m_leakDetected);
@@ -352,7 +351,6 @@ namespace UnitTest
};
BusRedirector m_busRedirector;
AZ::Debug::DrillerManager* m_drillerManager = nullptr;
bool m_leakDetected = false;
bool m_leakExpected = false;
};
+1
View File
@@ -17,6 +17,7 @@
#include <AzCore/std/containers/fixed_unordered_map.h>
#include <AzCore/std/containers/fixed_unordered_set.h>
#include <AzCore/std/containers/fixed_vector.h>
#include <AzCore/std/containers/forward_list.h>
#include <AzCore/std/containers/map.h>
#include <AzCore/std/containers/set.h>
#include <AzCore/std/containers/unordered_map.h>
@@ -11,6 +11,7 @@
#include <AzCore/std/containers/list.h>
#include <AzCore/std/containers/set.h>
#include <AzCore/std/containers/vector.h>
#include <AzCore/std/containers/forward_list.h>
#include <AzCore/std/iterator.h>
#include <Tests/Serialization/Json/JsonSerializerConformityTests.h>
#include <Tests/Serialization/Json/TestCases_Classes.h>
@@ -13,7 +13,7 @@
#include <AzCore/std/string/string.h>
#include <AzCore/std/parallel/thread.h>
#include <AzCore/std/parallel/shared_spin_mutex.h>
#include <AzCore/Debug/TraceMessagesDrillerBus.h>
#include <AzCore/Debug/TraceMessageBus.h>
#include <AzCore/Statistics/StatisticalProfilerProxy.h>
@@ -468,28 +468,29 @@ namespace UnitTest
/** Trace message handler to track messages during tests
*/
struct MyTraceMessageSink final
: public AZ::Debug::TraceMessageDrillerBus::Handler
: public AZ::Debug::TraceMessageBus::Handler
{
MyTraceMessageSink()
{
AZ::Debug::TraceMessageDrillerBus::Handler::BusConnect();
AZ::Debug::TraceMessageBus::Handler::BusConnect();
}
~MyTraceMessageSink()
{
AZ::Debug::TraceMessageDrillerBus::Handler::BusDisconnect();
AZ::Debug::TraceMessageBus::Handler::BusDisconnect();
}
//////////////////////////////////////////////////////////////////////////
// TraceMessageDrillerBus
void OnPrintf(const char* window, const char* message) override
// TraceMessageBus
bool OnPrintf(const char* window, const char* message) override
{
OnOutput(window, message);
return OnOutput(window, message);
}
void OnOutput(const char* window, const char* message) override
bool OnOutput(const char* window, const char* message) override
{
printf("%s: %s\n", window, message);
return false;
}
}; //struct MyTraceMessageSink
@@ -258,7 +258,6 @@ namespace AZ
m_application = aznew GemTestApplication();
AZ::ComponentApplication::Descriptor appDesc;
appDesc.m_useExistingAllocator = true;
appDesc.m_enableDrilling = false;
auto m_systemEntity = m_application->Create(appDesc);
m_systemEntity->AddComponent(aznew AZ::StreamerComponent());
m_systemEntity->Init();
+6 -2
View File
@@ -167,7 +167,8 @@ namespace UnitTest
if (!info.m_streamName.empty())
{
AZStd::string fullName = GetTestFolderPath() + info.m_streamName;
info.m_dataLen = static_cast<size_t>(IO::SystemFile::Length(fullName.c_str()));
IO::FileIOBase* io = IO::FileIOBase::GetInstance();
io->Size(fullName.c_str(), info.m_dataLen);
}
else
{
@@ -187,8 +188,11 @@ namespace UnitTest
if (!info.m_streamName.empty())
{
IO::FileIOBase* io = AZ::IO::FileIOBase::GetInstance();
AZStd::string fullName = GetTestFolderPath() + info.m_streamName;
info.m_dataLen = static_cast<size_t>(IO::SystemFile::Length(fullName.c_str()));
io->Size(fullName.c_str(), info.m_dataLen);
}
else
{
@@ -69,7 +69,6 @@ set(FILES
TickBusTest.cpp
UUIDTests.cpp
XML.cpp
Debug/AssetTracking.cpp
Debug/LocalFileEventLoggerTests.cpp
Debug/Trace.cpp
Debug/UnhandledExceptions.cpp
@@ -214,6 +213,8 @@ set(FILES
AZStd/Variant.cpp
AZStd/VariantSerialization.cpp
AZStd/VectorAndArray.cpp
DOM/DomJsonTests.cpp
DOM/DomJsonBenchmarks.cpp
)
# Prevent the following files from being grouped in UNITY builds