AudioControlBuilderTest.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  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 <AzTest/AzTest.h>
  9. #include <AzTest/Utils.h>
  10. #include <AudioControlBuilderComponent.h>
  11. #include <AzCore/IO/FileIO.h>
  12. #include <AzFramework/IO/LocalFileIO.h>
  13. #include <AzToolsFramework/Application/ToolsApplication.h>
  14. #include <AzCore/PlatformId/PlatformId.h>
  15. #include <AzCore/UserSettings/UserSettingsComponent.h>
  16. using namespace AudioControlBuilder;
  17. namespace UnitTest
  18. {
  19. class AudioControlBuilderTests
  20. : public ::testing::Test
  21. {
  22. protected:
  23. void SetUp() override
  24. {
  25. m_app.Start(AZ::ComponentApplication::Descriptor());
  26. // Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
  27. // shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash
  28. // in the unit tests.
  29. AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize);
  30. if constexpr (AZ::g_currentPlatform == AZ::PlatformID::PLATFORM_WINDOWS_64)
  31. {
  32. m_currentPlatform = "pc";
  33. }
  34. else
  35. {
  36. m_currentPlatform = AZ::GetPlatformName(AZ::g_currentPlatform);
  37. AZStd::to_lower(m_currentPlatform.begin(), m_currentPlatform.end());
  38. }
  39. AZ::IO::FileIOBase::GetInstance()->SetAlias("@engroot@", AZ::Test::GetEngineRootPath().data());
  40. }
  41. void TearDown() override
  42. {
  43. m_app.Stop();
  44. }
  45. AZStd::string GetFullPath(AZStd::string_view fileName)
  46. {
  47. constexpr char testFileFolder[] = "@exefolder@/Test.Assets/Gems/AudioEngineWwise/";
  48. return AZStd::string::format("%s%.*s", testFileFolder, aznumeric_cast<int>(fileName.size()), fileName.data());
  49. }
  50. void TestFailureCase(AudioControlBuilderWorker* worker, AZStd::string_view fileName, bool expectedResult = false)
  51. {
  52. AssetBuilderSDK::ProductPathDependencySet resolvedPaths;
  53. AZStd::vector<AssetBuilderSDK::ProductDependency> productDependencies;
  54. AssetBuilderSDK::ProcessJobRequest request;
  55. request.m_fullPath = GetFullPath(fileName);
  56. request.m_sourceFile = fileName;
  57. request.m_platformInfo.m_identifier = m_currentPlatform;
  58. bool result = worker->ParseProductDependencies(request, productDependencies, resolvedPaths);
  59. ASSERT_EQ(result, expectedResult);
  60. ASSERT_EQ(resolvedPaths.size(), 0);
  61. ASSERT_EQ(productDependencies.size(), 0);
  62. }
  63. void TestSuccessCase(
  64. AudioControlBuilderWorker* worker,
  65. AZStd::string_view fileName,
  66. const AZStd::vector<const char*>& expectedPathDependencies,
  67. const AZStd::vector<AssetBuilderSDK::ProductDependency>& expectedProductDependencies)
  68. {
  69. AssetBuilderSDK::ProductPathDependencySet resolvedPaths;
  70. AZStd::vector<AssetBuilderSDK::ProductDependency> productDependencies;
  71. size_t referencedFilePathsCount = expectedPathDependencies.size();
  72. size_t referencedProductDependenciesCount = expectedProductDependencies.size();
  73. AssetBuilderSDK::ProductPathDependencySet expectedResolvedPaths;
  74. for (const char* path : expectedPathDependencies)
  75. {
  76. expectedResolvedPaths.emplace(path, AssetBuilderSDK::ProductPathDependencyType::ProductFile);
  77. }
  78. AssetBuilderSDK::ProcessJobRequest request;
  79. request.m_fullPath = GetFullPath(fileName);
  80. request.m_sourceFile = fileName;
  81. request.m_platformInfo.m_identifier = m_currentPlatform;
  82. bool result = worker->ParseProductDependencies(request, productDependencies, resolvedPaths);
  83. ASSERT_TRUE(result);
  84. ASSERT_EQ(resolvedPaths.size(), referencedFilePathsCount);
  85. ASSERT_EQ(productDependencies.size(), referencedProductDependenciesCount);
  86. if (referencedFilePathsCount > 0)
  87. {
  88. for (const AssetBuilderSDK::ProductPathDependency& dependency : expectedResolvedPaths)
  89. {
  90. ASSERT_TRUE(resolvedPaths.find(dependency) != resolvedPaths.end()) << "Expected path dependency is not found in the process result";
  91. }
  92. }
  93. if (referencedProductDependenciesCount > 0)
  94. {
  95. for (const AssetBuilderSDK::ProductDependency& dependency : productDependencies)
  96. {
  97. bool expectedDependencyExists = false;
  98. for (const AssetBuilderSDK::ProductDependency& expectedProductDependency : expectedProductDependencies)
  99. {
  100. if (expectedProductDependency.m_dependencyId == dependency.m_dependencyId
  101. && expectedProductDependency.m_flags == dependency.m_flags)
  102. {
  103. expectedDependencyExists = true;
  104. break;
  105. }
  106. }
  107. ASSERT_TRUE(expectedDependencyExists) << "Expected product dependency is not found in the process result";
  108. }
  109. }
  110. }
  111. void TestSuccessCase(AudioControlBuilderWorker* worker, AZStd::string_view fileName, const char* expectedFile)
  112. {
  113. AZStd::vector<const char*> expectedFiles;
  114. expectedFiles.push_back(expectedFile);
  115. AZStd::vector<AssetBuilderSDK::ProductDependency> expectedProductDependencies;
  116. TestSuccessCase(worker, fileName, expectedFiles, expectedProductDependencies);
  117. }
  118. void TestSuccessCaseNoDependencies(AudioControlBuilderWorker* worker, AZStd::string_view fileName)
  119. {
  120. AZStd::vector<const char*> expectedFiles;
  121. AZStd::vector<AssetBuilderSDK::ProductDependency> expectedProductDependencies;
  122. TestSuccessCase(worker, fileName, expectedFiles, expectedProductDependencies);
  123. }
  124. private:
  125. AzToolsFramework::ToolsApplication m_app;
  126. AZStd::string m_currentPlatform;
  127. };
  128. TEST_F(AudioControlBuilderTests, TestAudioControl_EmptyFile_NoProductDependencies)
  129. {
  130. // Tests passing an empty file in
  131. // Should output 0 dependency and return false
  132. AZStd::string fileName = "AudioControls/EmptyControl.xml";
  133. AudioControlBuilderWorker builderWorker;
  134. TestFailureCase(&builderWorker, fileName);
  135. }
  136. TEST_F(AudioControlBuilderTests, TestAudioControl_NoPreloadsDefined_NoProductDependencies)
  137. {
  138. AZStd::string fileName = "AudioControls/MissingPreloads.xml";
  139. AudioControlBuilderWorker builderWorker;
  140. TestSuccessCaseNoDependencies(&builderWorker, fileName);
  141. }
  142. TEST_F(AudioControlBuilderTests, TestAudioControl_MissingWwiseFileNode_NoProductDependencies)
  143. {
  144. AZStd::string fileName = "AudioControls/MissingWwiseFileNode.xml";
  145. AudioControlBuilderWorker builderWorker;
  146. TestSuccessCaseNoDependencies(&builderWorker, fileName);
  147. }
  148. TEST_F(AudioControlBuilderTests, TestAudioControl_MultiplePreloadsMultipleBanks_MultipleProductDependencies)
  149. {
  150. AZStd::vector<const char*> expectedPaths = {
  151. "sounds/wwise/test_bank1.bnk",
  152. "sounds/wwise/test_bank2.bnk",
  153. "sounds/wwise/test_bank3.bnk",
  154. "sounds/wwise/test_bank4.bnk"
  155. };
  156. AZStd::string fileName = "AudioControls/MultiplePreloadsMultipleBanks.xml";
  157. AudioControlBuilderWorker builderWorker;
  158. AZStd::vector<AssetBuilderSDK::ProductDependency> expectedProductDependencies;
  159. TestSuccessCase(&builderWorker, fileName, expectedPaths, expectedProductDependencies);
  160. }
  161. TEST_F(AudioControlBuilderTests, TestAudioControl_MultiplePreloadsOneBank_MultipleProductDependencies)
  162. {
  163. AZStd::vector<const char*> expectedPaths = {
  164. "sounds/wwise/test_bank1.bnk",
  165. "sounds/wwise/test_bank2.bnk"
  166. };
  167. AZStd::string fileName = "AudioControls/MultiplePreloadsOneBank.xml";
  168. AudioControlBuilderWorker builderWorker;
  169. AZStd::vector<AssetBuilderSDK::ProductDependency> expectedProductDependencies;
  170. TestSuccessCase(&builderWorker, fileName, expectedPaths, expectedProductDependencies);
  171. }
  172. TEST_F(AudioControlBuilderTests, TestAudioControl_OnePreloadMultipleBanks_MultipleProductDependencies)
  173. {
  174. AZStd::vector<const char*> expectedPaths = {
  175. "sounds/wwise/test_bank1.bnk",
  176. "sounds/wwise/test_bank2.bnk"
  177. };
  178. AZStd::string fileName = "AudioControls/OnePreloadMultipleBanks.xml";
  179. AudioControlBuilderWorker builderWorker;
  180. AZStd::vector<AssetBuilderSDK::ProductDependency> expectedProductDependencies;
  181. TestSuccessCase(&builderWorker, fileName, expectedPaths, expectedProductDependencies);
  182. }
  183. TEST_F(AudioControlBuilderTests, TestAudioControl_OnePreloadOneBank_OneProductDependency)
  184. {
  185. AZStd::vector<const char*> expectedPaths = {
  186. "sounds/wwise/test_bank1.bnk"
  187. };
  188. AZStd::string fileName = "AudioControls/OnePreloadOneBank.xml";
  189. AudioControlBuilderWorker builderWorker;
  190. AZStd::vector<AssetBuilderSDK::ProductDependency> expectedProductDependencies;
  191. TestSuccessCase(&builderWorker, fileName, expectedPaths, expectedProductDependencies);
  192. }
  193. // Legacy format tests...
  194. namespace Legacy
  195. {
  196. TEST_F(AudioControlBuilderTests, LegacyTestAudioControl_MissingConfigGroupNameAttribute_NoProductDependencies)
  197. {
  198. AZStd::string fileName = "AudioControls/Legacy/MissingConfigGroupNameAttribute.xml";
  199. AudioControlBuilderWorker builderWorker;
  200. TestSuccessCaseNoDependencies(&builderWorker, fileName);
  201. }
  202. TEST_F(AudioControlBuilderTests, LegacyTestAudioControl_MissingPlatformNameAttribute_NoProductDependencies)
  203. {
  204. AZStd::string fileName = "AudioControls/Legacy/MissingPlatformNameAttributeOnePreload.xml";
  205. AudioControlBuilderWorker builderWorker;
  206. TestSuccessCaseNoDependencies(&builderWorker, fileName);
  207. }
  208. TEST_F(AudioControlBuilderTests, LegacyTestAudioControl_MissingAtlPlatformsNode_NoProductDependencies)
  209. {
  210. AZStd::string fileName = "AudioControls/Legacy/MissingAtlPlatformsNode.xml";
  211. AudioControlBuilderWorker builderWorker;
  212. TestSuccessCaseNoDependencies(&builderWorker, fileName);
  213. }
  214. TEST_F(AudioControlBuilderTests, LegacyTestAudioControl_MissingPlatformNode_NoProductDependencies)
  215. {
  216. AZStd::string fileName = "AudioControls/Legacy/MissingPlatformNode.xml";
  217. AudioControlBuilderWorker builderWorker;
  218. TestSuccessCaseNoDependencies(&builderWorker, fileName);
  219. }
  220. TEST_F(AudioControlBuilderTests, LegacyTestAudioControl_MissingWwiseFileNode_NoProductDependencies)
  221. {
  222. AZStd::string fileName = "AudioControls/Legacy/MissingWwiseFileNode.xml";
  223. AudioControlBuilderWorker builderWorker;
  224. TestSuccessCaseNoDependencies(&builderWorker, fileName);
  225. }
  226. TEST_F(AudioControlBuilderTests, LegacyTestAudioControl_OnePreloadOneBank_OneProductDependency)
  227. {
  228. AZStd::string fileName = "AudioControls/Legacy/OnePreloadOneBank.xml";
  229. AudioControlBuilderWorker builderWorker;
  230. TestSuccessCase(&builderWorker, fileName, "sounds/wwise/test_bank1.bnk");
  231. }
  232. TEST_F(AudioControlBuilderTests, LegacyTestAudioControl_OnePreloadMultipleBanks_MultipleProductDependencies)
  233. {
  234. AZStd::vector<const char*> expectedPaths = {
  235. "sounds/wwise/test_bank1.bnk",
  236. "sounds/wwise/test_bank2.bnk"
  237. };
  238. AZStd::string fileName = "AudioControls/Legacy/OnePreloadMultipleBanks.xml";
  239. AudioControlBuilderWorker builderWorker;
  240. AZStd::vector<AssetBuilderSDK::ProductDependency> expectedProductDependencies;
  241. TestSuccessCase(&builderWorker, fileName, expectedPaths, expectedProductDependencies);
  242. }
  243. TEST_F(AudioControlBuilderTests, LegacyTestAudioControl_MultiplePreloadsOneBankEach_MultipleProductDependencies)
  244. {
  245. AZStd::vector<const char*> expectedPaths = {
  246. "sounds/wwise/test_bank1.bnk",
  247. "sounds/wwise/test_bank2.bnk"
  248. };
  249. AZStd::string fileName = "AudioControls/Legacy/MultiplePreloadsOneBank.xml";
  250. AudioControlBuilderWorker builderWorker;
  251. AZStd::vector<AssetBuilderSDK::ProductDependency> expectedProductDependencies;
  252. TestSuccessCase(&builderWorker, fileName, expectedPaths, expectedProductDependencies);
  253. }
  254. TEST_F(AudioControlBuilderTests, LegacyTestAudioControl_MultiplePreloadsMultipleBanksEach_MultipleProductDependencies)
  255. {
  256. AZStd::vector<const char*> expectedPaths = {
  257. "sounds/wwise/test_bank1.bnk",
  258. "sounds/wwise/test_bank2.bnk",
  259. "sounds/wwise/test_bank3.bnk",
  260. "sounds/wwise/test_bank4.bnk"
  261. };
  262. AZStd::string fileName = "AudioControls/Legacy/MultiplePreloadsMultipleBanks.xml";
  263. AudioControlBuilderWorker builderWorker;
  264. AZStd::vector<AssetBuilderSDK::ProductDependency> expectedProductDependencies;
  265. TestSuccessCase(&builderWorker, fileName, expectedPaths, expectedProductDependencies);
  266. }
  267. TEST_F(AudioControlBuilderTests, LegacyTestAudioControl_NoConfigGroups_NoProductDependencies)
  268. {
  269. AZStd::string fileName = "AudioControls/Legacy/NoConfigGroups.xml";
  270. AudioControlBuilderWorker builderWorker;
  271. TestSuccessCaseNoDependencies(&builderWorker, fileName);
  272. }
  273. TEST_F(AudioControlBuilderTests, LegacyTestAudioControl_WrongConfigGroup_NoProductDependencies)
  274. {
  275. AZStd::string fileName = "AudioControls/Legacy/WrongConfigGroup.xml";
  276. AudioControlBuilderWorker builderWorker;
  277. TestSuccessCaseNoDependencies(&builderWorker, fileName);
  278. }
  279. } // namespace Legacy
  280. } // namespace UnitTest