AssetProcessorManagerTest.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  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. #pragma once
  9. #include <AzTest/AzTest.h>
  10. #include <AzCore/std/parallel/atomic.h>
  11. #include <qcoreapplication.h>
  12. #include <native/tests/AssetProcessorTest.h>
  13. #include <native/tests/MockAssetDatabaseRequestsHandler.h>
  14. #include <AssetBuilderSDK/AssetBuilderSDK.h>
  15. #include <native/assetprocessor.h>
  16. #include <native/unittests/UnitTestUtils.h>
  17. #include <native/AssetManager/assetProcessorManager.h>
  18. #include <native/utilities/PlatformConfiguration.h>
  19. #include <native/unittests/MockApplicationManager.h>
  20. #include <AssetManager/FileStateCache.h>
  21. #include <AzCore/std/smart_ptr/unique_ptr.h>
  22. #include <QMetaObject>
  23. #include <AzCore/Jobs/JobContext.h>
  24. #include <AzCore/Jobs/JobManager.h>
  25. #if !defined(Q_MOC_RUN)
  26. #include <AzCore/UnitTest/TestTypes.h>
  27. #endif
  28. #include <AzToolsFramework/API/AssetDatabaseBus.h>
  29. #include <tests/UnitTestUtilities.h>
  30. #include "resourcecompiler/rccontroller.h"
  31. class AssetProcessorManager_Test;
  32. class AssetProcessorManager_Test : public AssetProcessor::AssetProcessorManager
  33. {
  34. public:
  35. friend class GTEST_TEST_CLASS_NAME_(
  36. AssetProcessorManagerTest, AssetProcessedImpl_DifferentProductDependenciesPerProduct_SavesCorrectlyToDatabase);
  37. friend class GTEST_TEST_CLASS_NAME_(MultiplatformPathDependencyTest, AssetProcessed_Impl_MultiplatformDependencies);
  38. friend class GTEST_TEST_CLASS_NAME_(MultiplatformPathDependencyTest, AssetProcessed_Impl_MultiplatformDependencies_DeferredResolution);
  39. friend class GTEST_TEST_CLASS_NAME_(MultiplatformPathDependencyTest, SameFilenameForAllPlatforms);
  40. friend class GTEST_TEST_CLASS_NAME_(MultiplatformPathDependencyTest, AssetProcessed_Impl_MultiplatformDependencies_SourcePath);
  41. friend class GTEST_TEST_CLASS_NAME_(AssetProcessorManagerTest, DeleteFolder_SignalsDeleteOfContainedFiles);
  42. friend class GTEST_TEST_CLASS_NAME_(AssetProcessorManagerTest, QueryAbsolutePathDependenciesRecursive_BasicTest);
  43. friend class GTEST_TEST_CLASS_NAME_(AssetProcessorManagerTest, QueryAbsolutePathDependenciesRecursive_WithDifferentTypes_BasicTest);
  44. friend class GTEST_TEST_CLASS_NAME_(AssetProcessorManagerTest, QueryAbsolutePathDependenciesRecursive_Reverse_BasicTest);
  45. friend class GTEST_TEST_CLASS_NAME_(
  46. AssetProcessorManagerTest, QueryAbsolutePathDependenciesRecursive_MissingFiles_ReturnsNoPathWithPlaceholders);
  47. friend class GTEST_TEST_CLASS_NAME_(AssetProcessorManagerTest, QueryAbsolutePathDependenciesRecursive_DependenciesOnNonAssetsIncluded);
  48. friend class GTEST_TEST_CLASS_NAME_(AssetProcessorManagerTest, BuilderDirtiness_BeforeComputingDirtiness_AllDirty);
  49. friend class GTEST_TEST_CLASS_NAME_(AssetProcessorManagerTest, BuilderDirtiness_EmptyDatabase_AllDirty);
  50. friend class GTEST_TEST_CLASS_NAME_(AssetProcessorManagerTest, BuilderDirtiness_SameAsLastTime_NoneDirty);
  51. friend class GTEST_TEST_CLASS_NAME_(AssetProcessorManagerTest, BuilderDirtiness_MoreThanLastTime_NewOneIsDirty);
  52. friend class GTEST_TEST_CLASS_NAME_(AssetProcessorManagerTest, BuilderDirtiness_FewerThanLastTime_Dirty);
  53. friend class GTEST_TEST_CLASS_NAME_(AssetProcessorManagerTest, BuilderDirtiness_ChangedPattern_CountsAsNew);
  54. friend class GTEST_TEST_CLASS_NAME_(AssetProcessorManagerTest, BuilderDirtiness_ChangedPatternType_CountsAsNew);
  55. friend class GTEST_TEST_CLASS_NAME_(AssetProcessorManagerTest, BuilderDirtiness_NewPattern_CountsAsNewBuilder);
  56. friend class GTEST_TEST_CLASS_NAME_(AssetProcessorManagerTest, BuilderDirtiness_NewVersionNumber_IsNotANewBuilder);
  57. friend class GTEST_TEST_CLASS_NAME_(AssetProcessorManagerTest, BuilderDirtiness_NewAnalysisFingerprint_IsNotANewBuilder);
  58. friend class GTEST_TEST_CLASS_NAME_(SourceFileDependenciesTest, UpdateSourceFileDependenciesDatabase_BasicTest);
  59. friend class GTEST_TEST_CLASS_NAME_(SourceFileDependenciesTest, UpdateSourceFileDependenciesDatabase_UpdateTest);
  60. friend class GTEST_TEST_CLASS_NAME_(SourceFileDependenciesTest, UpdateSourceFileDependenciesDatabase_MissingFiles_ByUuid);
  61. friend class GTEST_TEST_CLASS_NAME_(SourceFileDependenciesTest, UpdateSourceFileDependenciesDatabase_MissingFiles_ByName);
  62. friend class GTEST_TEST_CLASS_NAME_(
  63. SourceFileDependenciesTest, UpdateSourceFileDependenciesDatabase_MissingFiles_ByUuid_UpdatesWhenTheyAppear);
  64. friend class GTEST_TEST_CLASS_NAME_(
  65. SourceFileDependenciesTest, UpdateSourceFileDependenciesDatabase_MissingFiles_ByName_UpdatesWhenTheyAppear);
  66. friend class GTEST_TEST_CLASS_NAME_(
  67. AssetProcessorManagerTest, UpdateSourceFileDependenciesDatabase_WildcardMissingFiles_ByName_UpdatesWhenTheyAppear);
  68. friend class GTEST_TEST_CLASS_NAME_(AssetProcessorManagerTest, JobDependencyOrderOnce_MultipleJobs_EmitOK);
  69. friend class GTEST_TEST_CLASS_NAME_(AssetProcessorManagerTest, SourceFileProcessFailure_ClearsFingerprint);
  70. friend class GTEST_TEST_CLASS_NAME_(
  71. AbsolutePathProductDependencyTest, UnresolvedProductPathDependency_AssetProcessedTwice_DoesNotDuplicateDependency);
  72. friend class GTEST_TEST_CLASS_NAME_(
  73. AbsolutePathProductDependencyTest, AbsolutePathProductDependency_RetryDeferredDependenciesWithMatchingSource_DependencyResolves);
  74. friend class GTEST_TEST_CLASS_NAME_(
  75. AbsolutePathProductDependencyTest, UnresolvedProductPathDependency_AssetProcessedTwice_ValidatePathDependenciesMap);
  76. friend class GTEST_TEST_CLASS_NAME_(
  77. AbsolutePathProductDependencyTest,
  78. UnresolvedSourceFileTypeProductPathDependency_DependencyHasNoProductOutput_ValidatePathDependenciesMap);
  79. friend class GTEST_TEST_CLASS_NAME_(DeleteTest, DeleteFolderSharedAcrossTwoScanFolders_CorrectFileAndFolderAreDeletedFromCache);
  80. friend class GTEST_TEST_CLASS_NAME_(MetadataFileTest, MetadataFile_SourceFileExtensionDifferentCase);
  81. friend class AssetProcessorManagerTest;
  82. friend struct JobDependencyTest;
  83. friend struct ChainJobDependencyTest;
  84. friend struct DeleteTest;
  85. friend struct PathDependencyTest;
  86. friend struct DuplicateProductsTest;
  87. friend struct DuplicateProcessTest;
  88. friend struct AbsolutePathProductDependencyTest;
  89. friend struct WildcardSourceDependencyTest;
  90. friend struct SourceFileDependenciesTest;
  91. explicit AssetProcessorManager_Test(AssetProcessor::PlatformConfiguration* config, QObject* parent = nullptr);
  92. ~AssetProcessorManager_Test() override;
  93. bool CheckJobKeyToJobRunKeyMap(AZStd::string jobKey);
  94. int CountDirtyBuilders() const
  95. {
  96. int numDirty = 0;
  97. for (const auto& element : m_builderDataCache)
  98. {
  99. if (element.second.m_isDirty)
  100. {
  101. ++numDirty;
  102. }
  103. }
  104. return numDirty;
  105. }
  106. bool IsBuilderDirty(const AZ::Uuid& builderBusId) const
  107. {
  108. auto finder = m_builderDataCache.find(builderBusId);
  109. if (finder == m_builderDataCache.end())
  110. {
  111. return true;
  112. }
  113. return finder->second.m_isDirty;
  114. }
  115. void RecomputeDirtyBuilders()
  116. {
  117. // Run this twice so the test builder doesn't get counted as a "new" builder and bypass the modtime skipping
  118. ComputeBuilderDirty();
  119. ComputeBuilderDirty();
  120. }
  121. using AssetProcessorManager::m_stateData;
  122. using AssetProcessorManager::ComputeBuilderDirty;
  123. using AssetProcessorManager::m_anyBuilderChange;
  124. using AssetProcessorManager::m_buildersAddedOrRemoved;
  125. };
  126. class AssetProcessorManagerTest
  127. : public AssetProcessor::AssetProcessorTest
  128. {
  129. public:
  130. AssetProcessorManagerTest();
  131. virtual ~AssetProcessorManagerTest()
  132. {
  133. }
  134. // utility function. Blocks and runs the QT event pump for up to millisecondsMax and will break out as soon as the APM is idle.
  135. bool BlockUntilIdle(int millisecondsMax);
  136. protected:
  137. void SetUp() override;
  138. void TearDown() override;
  139. virtual void CreateSourceAndFile(const char* tempFolderRelativePath);
  140. virtual void PopulateDatabase();
  141. QDir m_assetRootDir;
  142. AZStd::unique_ptr<AssetProcessorManager_Test> m_assetProcessorManager;
  143. AZStd::unique_ptr<AssetProcessor::MockApplicationManager> m_mockApplicationManager;
  144. AssetProcessor::MockAssetDatabaseRequestsHandler m_databaseLocationListener;
  145. AZStd::unique_ptr<AssetProcessor::PlatformConfiguration> m_config;
  146. ::UnitTests::MockVirtualFileIO m_virtualFileIO;
  147. AzToolsFramework::UuidUtilComponent m_uuidUtil;
  148. AzToolsFramework::MetadataManager m_metadataManager;
  149. AssetProcessor::UuidManager m_uuidManager;
  150. QString m_gameName;
  151. QDir m_normalizedCacheRootDir;
  152. AZStd::atomic_bool m_isIdling;
  153. QMetaObject::Connection m_idleConnection;
  154. AZ::Uuid m_aUuid;
  155. AZ::Uuid m_bUuid;
  156. AZ::Uuid m_cUuid;
  157. AZ::Uuid m_dUuid;
  158. struct StaticData
  159. {
  160. AZStd::string m_databaseLocation;
  161. AZ::Entity* m_jobManagerEntity{};
  162. AZ::ComponentDescriptor* m_descriptor{};
  163. AZStd::unique_ptr<AZ::SerializeContext> m_serializeContext;
  164. };
  165. AZStd::unique_ptr<StaticData> m_data;
  166. private:
  167. int m_argc;
  168. char** m_argv;
  169. AZStd::unique_ptr<UnitTestUtils::ScopedDir> m_scopeDir;
  170. AZStd::unique_ptr<QCoreApplication> m_qApp;
  171. };
  172. struct AbsolutePathProductDependencyTest
  173. : public AssetProcessorManagerTest
  174. {
  175. void SetUp() override;
  176. AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntry SetAndReadAbsolutePathProductDependencyFromRelativePath(
  177. const AZStd::string& relativePath);
  178. AZStd::string BuildScanFolderRelativePath(const AZStd::string& relativePath) const;
  179. AzToolsFramework::AssetDatabase::ProductDatabaseEntry m_productToHaveDependency;
  180. const AssetProcessor::ScanFolderInfo* m_scanFolderInfo = nullptr;
  181. AZStd::string m_testPlatform = "SomePlatform";
  182. };
  183. struct SourceFileDependenciesTest : AssetProcessorManagerTest
  184. {
  185. void SetUp() override;
  186. void SetupData(
  187. const AZStd::vector<AssetBuilderSDK::SourceFileDependency>& sourceFileDependencies,
  188. const AZStd::vector<AssetBuilderSDK::JobDependency>& jobDependencies,
  189. bool createFile1Dummies,
  190. bool createFile2Dummies,
  191. bool primeMap,
  192. AssetProcessor::AssetProcessorManager::JobToProcessEntry& job);
  193. void PopulateDatabase() override;
  194. auto GetDependencyList();
  195. AssetBuilderSDK::SourceFileDependency MakeSourceDependency(const char* file, bool wildcard = false);
  196. AssetBuilderSDK::SourceFileDependency MakeSourceDependency(AZ::Uuid uuid);
  197. AssetBuilderSDK::JobDependency MakeJobDependency(const char* file);
  198. AssetBuilderSDK::JobDependency MakeJobDependency(AZ::Uuid uuid);
  199. QString m_absPath;
  200. QString m_watchFolderPath;
  201. QString m_dependsOnFile1_Source;
  202. QString m_dependsOnFile2_Source;
  203. QString m_dependsOnFile1_Job;
  204. QString m_dependsOnFile2_Job;
  205. const AssetProcessor::ScanFolderInfo* m_scanFolder = nullptr;
  206. AZ::Uuid m_dummyBuilderUuid;
  207. AZ::Uuid m_sourceFileUuid;
  208. AZ::Uuid m_uuidOfA;
  209. AZ::Uuid m_uuidOfB;
  210. AZ::Uuid m_uuidOfC;
  211. AZ::Uuid m_uuidOfD;
  212. };
  213. struct PathDependencyTest
  214. : public AssetProcessorManagerTest
  215. {
  216. void SetUp() override;
  217. void TearDown() override;
  218. using OutputAssetSet = AZStd::vector<AZStd::vector<const char*>>;
  219. struct TestAsset
  220. {
  221. TestAsset() = default;
  222. TestAsset(const char* name) : m_name(name) {}
  223. AZStd::string m_name;
  224. AZStd::vector<AZ::Data::AssetId> m_products;
  225. };
  226. void CaptureJobs(AZStd::vector<AssetProcessor::JobDetails>& jobDetails, const char* sourceFilePath);
  227. bool ProcessAsset(TestAsset& asset, const OutputAssetSet& outputAssets, const AssetBuilderSDK::ProductPathDependencySet& dependencies = {}, const AZStd::string& folderPath = "subfolder1/", const AZStd::string& extension = ".txt");
  228. void RunWildcardTest(bool useCorrectDatabaseSeparator, AssetBuilderSDK::ProductPathDependencyType pathDependencyType, bool buildDependenciesFirst);
  229. void RunWildcardDependencyTestOnPaths(
  230. const AZStd::string& wildcardDependency,
  231. const AZStd::vector<AZStd::string>& expectedMatchingPaths,
  232. const AZStd::vector<AZStd::string>& expectedNotMatchingPaths);
  233. AssetProcessor::AssetDatabaseConnection* m_sharedConnection{};
  234. };
  235. struct DuplicateProcessTest
  236. : public PathDependencyTest
  237. {
  238. void SetUp() override;
  239. };
  240. struct MultiplatformPathDependencyTest
  241. : public PathDependencyTest
  242. {
  243. void SetUp() override;
  244. };
  245. struct WildcardSourceDependencyTest
  246. : AssetProcessorManagerTest
  247. {
  248. bool Test(const AZStd::string& dependencyPath, AZStd::vector<AZStd::string>& resolvedPaths);
  249. AZStd::vector<AZStd::string> FileAddedTest(const QString& path);
  250. void SetUp() override;
  251. };
  252. struct MetadataFileTest
  253. : public AssetProcessorManagerTest
  254. {
  255. void SetUp() override;
  256. };
  257. struct FingerprintTest
  258. : public AssetProcessorManagerTest
  259. {
  260. void SetUp() override;
  261. void TearDown() override;
  262. void RunFingerprintTest(QString builderFingerprint, QString jobFingerprint, bool expectedResult);
  263. QString m_absolutePath;
  264. UnitTests::MockMultiBuilderInfoHandler m_mockBuilderInfoHandler;
  265. AZStd::vector<AssetProcessor::JobDetails> m_jobResults;
  266. };
  267. struct JobDependencyTest
  268. : public PathDependencyTest
  269. {
  270. void SetUp() override;
  271. void TearDown() override;
  272. struct StaticData
  273. {
  274. UnitTests::MockMultiBuilderInfoHandler m_mockBuilderInfoHandler;
  275. UnitTests::MockMultiBuilderInfoHandler::AssetBuilderExtraInfo m_assetBuilderConfig;
  276. AZ::Uuid m_builderUuid;
  277. };
  278. AZStd::unique_ptr<StaticData> m_data;
  279. };
  280. struct ChainJobDependencyTest
  281. : public PathDependencyTest
  282. {
  283. void SetUp() override;
  284. void TearDown() override;
  285. struct StaticData
  286. {
  287. UnitTests::MockMultiBuilderInfoHandler m_mockBuilderInfoHandler;
  288. AZStd::unique_ptr<AssetProcessor::RCController> m_rcController;
  289. };
  290. static constexpr int ChainLength = 10;
  291. AZStd::unique_ptr<StaticData> m_data;
  292. };
  293. struct DuplicateProductsTest
  294. : public AssetProcessorManagerTest
  295. {
  296. void SetupDuplicateProductsTest(QString& sourceFile, QDir& tempPath, QString& productFile, AZStd::vector<AssetProcessor::JobDetails>& jobDetails, AssetBuilderSDK::ProcessJobResponse& response, bool multipleOutputs, QString extension);
  297. };