From 3907ffc173d3de79490798dcf8faabc213cfe87a Mon Sep 17 00:00:00 2001 From: amzn-mike Date: Fri, 16 Apr 2021 13:50:39 -0500 Subject: [PATCH] Add unit test --- .../Tests/Asset/AssetManagerLoadingTests.cpp | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/Code/Framework/AzCore/Tests/Asset/AssetManagerLoadingTests.cpp b/Code/Framework/AzCore/Tests/Asset/AssetManagerLoadingTests.cpp index 18e193304a..15f2b0bf86 100644 --- a/Code/Framework/AzCore/Tests/Asset/AssetManagerLoadingTests.cpp +++ b/Code/Framework/AzCore/Tests/Asset/AssetManagerLoadingTests.cpp @@ -575,6 +575,91 @@ namespace UnitTest EXPECT_EQ(baseStatus, expected_base_status); } + struct DebugListener : AZ::Interface::Registrar + { + void AssetStatusUpdate(AZ::Data::AssetId id, AZ::Data::AssetData::AssetStatus status) override + { + AZ::Debug::Trace::Output( + "", AZStd::string::format("Status %s - %d\n", id.ToString().c_str(), static_cast(status)).c_str()); + } + void ReleaseAsset(AZ::Data::AssetId id) override + { + AZ::Debug::Trace::Output( + "", AZStd::string::format("Release %s\n", id.ToString().c_str()).c_str()); + } + }; + + TEST_F(AssetJobsFloodTest, Cancel) + { + DebugListener listener; + auto assetUuids = { + MyAsset1Id, + //MyAsset2Id, + //MyAsset3Id, + }; + + AZStd::vector threads; + AZStd::mutex mutex; + AZStd::atomic threadCount((int)assetUuids.size()); + AZStd::condition_variable cv; + AZStd::atomic_bool keepDispatching(true); + + auto dispatch = [&keepDispatching]() { + while (keepDispatching) + { + AssetManager::Instance().DispatchEvents(); + } + }; + + AZStd::thread dispatchThread(dispatch); + + for (const auto& assetUuid : assetUuids) + { + threads.emplace_back([this, &threadCount, &cv, assetUuid]() { + bool checkLoaded = true; + + for (int i = 0; i < 1000; i++) + { + Asset asset1 = + m_testAssetManager->GetAsset(assetUuid, azrtti_typeid(), AZ::Data::AssetLoadBehavior::PreLoad); + + if (checkLoaded) + { + asset1.BlockUntilLoadComplete(); + + EXPECT_TRUE(asset1.IsReady()) << "Iteration " << i << " failed. Asset status: " << static_cast(asset1.GetStatus()); + } + + checkLoaded = !checkLoaded; + } + + threadCount--; + cv.notify_one(); + }); + } + + bool timedOut = false; + + // Used to detect a deadlock. If we wait for more than 5 seconds, it's likely a deadlock has occurred + while (threadCount > 0 && !timedOut) + { + AZStd::unique_lock lock(mutex); + timedOut = (AZStd::cv_status::timeout == cv.wait_until(lock, AZStd::chrono::system_clock::now() + DefaultTimeoutSeconds * 20000)); + } + + ASSERT_EQ(threadCount, 0) << "Thread count is non-zero, a thread has likely deadlocked. Test will not shut down cleanly."; + + for (auto& thread : threads) + { + thread.join(); + } + + keepDispatching = false; + dispatchThread.join(); + + AssetManager::Destroy(); + } + #if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS TEST_F(AssetJobsFloodTest, DISABLED_AssetLoadBehaviorIsPreserved) #else