DelayRelocationTests.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <QCoreApplication>
  9. #include <native/tests/assetmanager/DelayRelocationTests.h>
  10. #include <native/unittests/UnitTestUtils.h>
  11. #include <AzFramework/IO/LocalFileIO.h>
  12. namespace UnitTests
  13. {
  14. void DelayRelocationTests::SetUp()
  15. {
  16. AssetManagerTestingBase::SetUp();
  17. using namespace AssetBuilderSDK;
  18. m_uuidInterface = AZ::Interface<AssetProcessor::IUuidRequests>::Get();
  19. ASSERT_TRUE(m_uuidInterface);
  20. m_uuidInterface->EnableGenerationForTypes({ ".stage1" });
  21. m_assetProcessorManager->SetMetaCreationDelay(MetadataProcessingDelayMs);
  22. CreateBuilder("stage1", "*.stage1", "stage2", false, ProductOutputFlags::ProductAsset);
  23. ProcessFileMultiStage(1, true);
  24. QCoreApplication::processEvents();
  25. }
  26. TEST_F(DelayRelocationTests, DeleteMetadata_WithDelay_MetadataIsRecreated)
  27. {
  28. bool delayed = false;
  29. QObject::connect(
  30. m_assetProcessorManager.get(),
  31. &AssetProcessor::AssetProcessorManager::ProcessingDelayed,
  32. [&delayed](QString)
  33. {
  34. delayed = true;
  35. });
  36. auto expectedMetadataPath = AzToolsFramework::MetadataManager::ToMetadataPath(m_testFilePath);
  37. EXPECT_TRUE(AZ::IO::FileIOBase::GetInstance()->Exists(expectedMetadataPath.c_str())) << expectedMetadataPath.c_str();
  38. AZ::IO::FileIOBase::GetInstance()->Remove(expectedMetadataPath.c_str());
  39. m_uuidInterface->FileRemoved(expectedMetadataPath);
  40. // Reprocess
  41. QMetaObject::invokeMethod(
  42. m_assetProcessorManager.get(), "AssessDeletedFile", Qt::QueuedConnection, Q_ARG(QString, expectedMetadataPath.c_str()));
  43. QCoreApplication::processEvents();
  44. // Reset state
  45. m_jobDetailsList.clear();
  46. m_fileCompiled = false;
  47. m_fileFailed = false;
  48. RunFile(0, 1);
  49. // Check the metadata file has been recreated
  50. EXPECT_TRUE(AZ::IO::FileIOBase::GetInstance()->Exists(expectedMetadataPath.c_str())) << expectedMetadataPath.c_str();
  51. EXPECT_TRUE(delayed);
  52. }
  53. TEST_F(DelayRelocationTests, RenameSource_WithDelay_MetadataIsCreated)
  54. {
  55. bool delayed = false;
  56. QObject::connect(
  57. m_assetProcessorManager.get(),
  58. &AssetProcessor::AssetProcessorManager::ProcessingDelayed,
  59. [&delayed](QString)
  60. {
  61. delayed = true;
  62. });
  63. auto oldPath = m_testFilePath;
  64. AZ::IO::Path scanFolderDir(m_scanfolder.m_scanFolder);
  65. AZStd::string testFilename = "renamed.stage1";
  66. AZStd::string newPath = (scanFolderDir / testFilename).AsPosix().c_str();
  67. AZ::IO::FileIOBase::GetInstance()->Rename(oldPath.c_str(), newPath.c_str());
  68. m_uuidInterface->FileRemoved(oldPath.c_str());
  69. // Process the delete first
  70. QMetaObject::invokeMethod(
  71. m_assetProcessorManager.get(), "AssessDeletedFile", Qt::QueuedConnection, Q_ARG(QString, oldPath.c_str()));
  72. QCoreApplication::processEvents();
  73. // Reset state
  74. m_jobDetailsList.clear();
  75. m_fileCompiled = false;
  76. m_fileFailed = false;
  77. RunFile(0, 1);
  78. EXPECT_FALSE(delayed);
  79. QMetaObject::invokeMethod(m_assetProcessorManager.get(), "AssessAddedFile", Qt::QueuedConnection, Q_ARG(QString, newPath.c_str()));
  80. QCoreApplication::processEvents();
  81. // Reset state
  82. m_jobDetailsList.clear();
  83. m_fileCompiled = false;
  84. m_fileFailed = false;
  85. RunFile(1, 1);
  86. // Check the metadata file has been created
  87. auto expectedMetadataPath = AzToolsFramework::MetadataManager::ToMetadataPath(newPath);
  88. EXPECT_TRUE(AZ::IO::SystemFile::Exists(expectedMetadataPath.c_str())) << expectedMetadataPath.c_str();
  89. EXPECT_TRUE(delayed);
  90. }
  91. TEST_F(DelayRelocationTests, RenameSource_RenameMetadataDuringDelay_NoMetadataCreated)
  92. {
  93. auto oldPath = m_testFilePath;
  94. AZ::IO::Path scanFolderDir(m_scanfolder.m_scanFolder);
  95. AZStd::string testFilename = "renamed.stage1";
  96. AZStd::string newPath = (scanFolderDir / testFilename).AsPosix().c_str();
  97. bool delayed = false;
  98. auto originalUuid = AssetUtilities::GetSourceUuid(AssetProcessor::SourceAssetReference(oldPath.c_str()));
  99. ASSERT_TRUE(originalUuid);
  100. QObject::connect(
  101. m_assetProcessorManager.get(),
  102. &AssetProcessor::AssetProcessorManager::ProcessingDelayed,
  103. [&delayed, oldPath, newPath, this](QString)
  104. {
  105. delayed = true;
  106. // During the delay period, rename the metadata file
  107. AZ::IO::FileIOBase::GetInstance()->Rename(
  108. AzToolsFramework::MetadataManager::ToMetadataPath(oldPath).c_str(),
  109. AzToolsFramework::MetadataManager::ToMetadataPath(newPath).c_str());
  110. m_uuidInterface->FileRemoved(AzToolsFramework::MetadataManager::ToMetadataPath(oldPath));
  111. });
  112. AZ::IO::FileIOBase::GetInstance()->Rename(oldPath.c_str(), newPath.c_str());
  113. m_uuidInterface->FileRemoved(oldPath.c_str());
  114. // Process the delete first
  115. QMetaObject::invokeMethod(
  116. m_assetProcessorManager.get(), "AssessDeletedFile", Qt::QueuedConnection, Q_ARG(QString, oldPath.c_str()));
  117. QCoreApplication::processEvents();
  118. // Reset state
  119. m_jobDetailsList.clear();
  120. m_fileCompiled = false;
  121. m_fileFailed = false;
  122. RunFile(0, 1);
  123. EXPECT_FALSE(delayed);
  124. QMetaObject::invokeMethod(m_assetProcessorManager.get(), "AssessAddedFile", Qt::QueuedConnection, Q_ARG(QString, newPath.c_str()));
  125. QCoreApplication::processEvents();
  126. // Reset state
  127. m_jobDetailsList.clear();
  128. m_fileCompiled = false;
  129. m_fileFailed = false;
  130. RunFile(1, 1);
  131. auto expectedMetadataPath = AzToolsFramework::MetadataManager::ToMetadataPath(newPath);
  132. EXPECT_TRUE(AZ::IO::SystemFile::Exists(expectedMetadataPath.c_str())) << expectedMetadataPath.c_str();
  133. EXPECT_TRUE(delayed);
  134. // Verify that the metadata file we renamed didn't get overwritten
  135. auto currentUuid = AssetUtilities::GetSourceUuid(AssetProcessor::SourceAssetReference(newPath.c_str()));
  136. ASSERT_TRUE(currentUuid);
  137. EXPECT_EQ(originalUuid.GetValue(), currentUuid.GetValue());
  138. }
  139. TEST_F(DelayRelocationTests, PrepareForFileMove_RenameSourceAndMetadata_MovedWithoutRecreating)
  140. {
  141. m_assetProcessorManager->SetMetaCreationDelay(0);
  142. auto* updateInterface = AZ::Interface<AssetProcessor::IMetadataUpdates>::Get();
  143. ASSERT_TRUE(updateInterface);
  144. AZ::IO::Path oldPath = m_testFilePath;
  145. AZ::IO::Path scanFolderDir(m_scanfolder.m_scanFolder);
  146. AZStd::string testFilename = "renamed.stage1";
  147. auto newPath = scanFolderDir / testFilename;
  148. updateInterface->PrepareForFileMove(oldPath, newPath);
  149. auto oldMetadataPath = AzToolsFramework::MetadataManager::ToMetadataPath(oldPath);
  150. auto newMetadataPath = AzToolsFramework::MetadataManager::ToMetadataPath(newPath);
  151. AZ::IO::FileIOBase::GetInstance()->Rename(oldMetadataPath.c_str(), newMetadataPath.c_str());
  152. m_uuidInterface->FileRemoved(oldMetadataPath.c_str());
  153. // Process the delete first
  154. QMetaObject::invokeMethod(
  155. m_assetProcessorManager.get(), "AssessDeletedFile", Qt::QueuedConnection, Q_ARG(QString, oldMetadataPath.c_str()));
  156. QCoreApplication::processEvents();
  157. // For the below tests, since AP is expected to not complete the analysis, don't use RunFile
  158. // Just execute CheckSource and make sure it produced no work
  159. // Reset state
  160. m_jobDetailsList.clear();
  161. m_fileCompiled = false;
  162. m_fileFailed = false;
  163. m_assetProcessorManager->CheckActiveFiles(1);
  164. QCoreApplication::processEvents(); // execute CheckSource
  165. m_assetProcessorManager->CheckActiveFiles(0);
  166. m_assetProcessorManager->CheckFilesToExamine(0);
  167. QMetaObject::invokeMethod(m_assetProcessorManager.get(), "AssessAddedFile", Qt::QueuedConnection, Q_ARG(QString, newMetadataPath.c_str()));
  168. QCoreApplication::processEvents();
  169. // Reset state
  170. m_jobDetailsList.clear();
  171. m_fileCompiled = false;
  172. m_fileFailed = false;
  173. m_assetProcessorManager->CheckActiveFiles(1);
  174. QCoreApplication::processEvents(); // execute CheckSource
  175. m_assetProcessorManager->CheckActiveFiles(0);
  176. m_assetProcessorManager->CheckFilesToExamine(0);
  177. EXPECT_FALSE(AZ::IO::FileIOBase::GetInstance()->Exists(oldMetadataPath.c_str()));
  178. // Now move the source file
  179. AZ::IO::FileIOBase::GetInstance()->Rename(oldPath.c_str(), newPath.c_str());
  180. m_uuidInterface->FileRemoved(oldPath.c_str());
  181. // Process the delete first
  182. QMetaObject::invokeMethod(
  183. m_assetProcessorManager.get(), "AssessDeletedFile", Qt::QueuedConnection, Q_ARG(QString, oldPath.c_str()));
  184. QCoreApplication::processEvents();
  185. RunFile(0, 1);
  186. QMetaObject::invokeMethod(
  187. m_assetProcessorManager.get(), "AssessAddedFile", Qt::QueuedConnection, Q_ARG(QString, newPath.c_str()));
  188. QCoreApplication::processEvents();
  189. // Reset state
  190. m_jobDetailsList.clear();
  191. m_fileCompiled = false;
  192. m_fileFailed = false;
  193. RunFile(1, 1);
  194. EXPECT_FALSE(AZ::IO::FileIOBase::GetInstance()->Exists(oldPath.c_str()));
  195. EXPECT_FALSE(AZ::IO::FileIOBase::GetInstance()->Exists(oldMetadataPath.c_str()));
  196. }
  197. } // namespace UnitTests