QualitySystemComponentTests.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  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 <AzCore/UnitTest/TestTypes.h>
  9. #include <AzCore/Console/Console.h>
  10. #include <AzCore/Settings/SettingsRegistry.h>
  11. #include <AzCore/Settings/SettingsRegistryImpl.h>
  12. #include <AzCore/Settings/SettingsRegistryMergeUtils.h>
  13. #include <AzCore/Serialization/SerializeContext.h>
  14. #include <AzCore/UserSettings/UserSettingsComponent.h>
  15. #include <AzFramework/Application/Application.h>
  16. #include <AzFramework/Quality/QualitySystemComponent.h>
  17. #include <AzFramework/Quality/QualityCVarGroup.h>
  18. namespace UnitTest
  19. {
  20. class QualitySystemComponentTestFixture : public LeakDetectionFixture
  21. {
  22. public:
  23. QualitySystemComponentTestFixture()
  24. : LeakDetectionFixture()
  25. {
  26. }
  27. protected:
  28. void SetUp() override
  29. {
  30. using FixedValueString = AZ::SettingsRegistryInterface::FixedValueString;
  31. m_settingsRegistry = AZStd::make_unique<AZ::SettingsRegistryImpl>();
  32. AZ::SettingsRegistry::Register(m_settingsRegistry.get());
  33. m_application = AZStd::make_unique<AzFramework::Application>();
  34. // setup the runtime paths for the FileTagComponent
  35. auto projectPathKey = FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) + "/project_path";
  36. AZ::IO::FixedMaxPath enginePath;
  37. m_settingsRegistry->Get(enginePath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder);
  38. m_settingsRegistry->Set(projectPathKey, (enginePath / "AutomatedTesting").Native());
  39. AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*m_settingsRegistry);
  40. m_console = AZ::Interface<AZ::IConsole>::Get();
  41. }
  42. void TearDown() override
  43. {
  44. m_application->Stop();
  45. m_application.reset();
  46. AZ::SettingsRegistry::Unregister(m_settingsRegistry.get());
  47. m_settingsRegistry.reset();
  48. }
  49. void StartApplicationWithSettings(AZStd::string_view settings)
  50. {
  51. auto result = m_settingsRegistry->MergeSettings(settings,
  52. AZ::SettingsRegistryInterface::Format::JsonMergePatch,
  53. "");
  54. ASSERT_TRUE(result);
  55. // When the application starts and activates the QualitySystemComponent
  56. // it will register CVARS based on what is in the registry
  57. AZ::ComponentApplication::Descriptor desc;
  58. AZ::ComponentApplication::StartupParameters startupParameters;
  59. startupParameters.m_loadSettingsRegistry = false;
  60. startupParameters.m_loadAssetCatalog = false;
  61. m_application->Start(desc, startupParameters);
  62. // Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
  63. // shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash
  64. // in the unit tests.
  65. AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize);
  66. }
  67. AZ::IConsole* m_console;
  68. AZStd::unique_ptr<AzFramework::Application> m_application;
  69. AZStd::unique_ptr<AZ::SettingsRegistryInterface> m_settingsRegistry;
  70. };
  71. TEST_F(QualitySystemComponentTestFixture, QualitySystem_Registers_Group_CVars)
  72. {
  73. // when the quality system component registers group cvars
  74. StartApplicationWithSettings(R"(
  75. {
  76. "O3DE": {
  77. "Quality": {
  78. "Groups": {
  79. "q_test": {
  80. "Levels": [ "low", "high" ],
  81. "Default": 1,
  82. "Description": "q_test quality group",
  83. "Settings": {
  84. "q_test_sub": [0,1]
  85. }
  86. },
  87. "q_test_sub": {
  88. "Levels": [ "low", "high" ],
  89. "Default": 0,
  90. "Description": "q_test_sub quality group",
  91. "Settings": {
  92. "a_cvar": [123,234]
  93. }
  94. }
  95. }
  96. }
  97. }
  98. }
  99. )");
  100. // expect the cvars are created with their default values
  101. auto value = AzFramework::QualityLevel::LevelFromDeviceRules;
  102. EXPECT_EQ(m_console->GetCvarValue("q_test", value), AZ::GetValueResult::Success);
  103. EXPECT_EQ(value, AzFramework::QualityLevel{1});
  104. EXPECT_EQ(m_console->GetCvarValue("q_test_sub", value), AZ::GetValueResult::Success);
  105. EXPECT_EQ(value, AzFramework::QualityLevel::DefaultQualityLevel);
  106. }
  107. AZ_CVAR(int32_t, a_setting, 0, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "Example integer setting 1");
  108. AZ_CVAR(AZ::CVarFixedString, b_setting, "default", nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "Example string setting 2");
  109. AZ_CVAR(int32_t, c_setting, -1, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "Example integer setting 3");
  110. AZ_CVAR(int32_t, d_setting, -2, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "Example integer setting 4");
  111. TEST_F(QualitySystemComponentTestFixture, QualitySystem_Loads_Group_Level)
  112. {
  113. // when the quality system component registers group cvars
  114. StartApplicationWithSettings(R"(
  115. {
  116. "O3DE": {
  117. "Quality": {
  118. "DefaultGroup":"q_test",
  119. "Groups": {
  120. "q_test": {
  121. "Levels": [ "low", "medium", "high", "veryhigh"],
  122. "Default": 2,
  123. "Description": "q_test quality group",
  124. "Settings": {
  125. "a_setting": [0,1,2,3],
  126. "b_setting": ["a","b","c","d"],
  127. "q_test_sub": [0,1,1,1]
  128. }
  129. },
  130. "q_test_sub": {
  131. "Levels": [ "low", "high" ],
  132. "Default": "DefaultQualityLevel",
  133. "Description": "q_test_sub quality group",
  134. "Settings": {
  135. "c_setting": [123,234],
  136. "d_setting": [42] // test missing high level setting
  137. }
  138. }
  139. }
  140. }
  141. }
  142. }
  143. )");
  144. auto value = AzFramework::QualityLevel::LevelFromDeviceRules;
  145. int32_t intValue = -42;
  146. AZ::CVarFixedString stringValue;
  147. // expect the value defaults
  148. EXPECT_EQ(m_console->GetCvarValue("a_setting", intValue), AZ::GetValueResult::Success);
  149. EXPECT_EQ(intValue, 0);
  150. EXPECT_EQ(m_console->GetCvarValue("b_setting", stringValue), AZ::GetValueResult::Success);
  151. EXPECT_EQ(stringValue, "default");
  152. EXPECT_EQ(m_console->GetCvarValue("c_setting", intValue), AZ::GetValueResult::Success);
  153. EXPECT_EQ(intValue, -1);
  154. EXPECT_EQ(m_console->GetCvarValue("d_setting", intValue), AZ::GetValueResult::Success);
  155. EXPECT_EQ(intValue, -2);
  156. // when the default group is loaded
  157. AzFramework::QualitySystemEvents::Bus::Broadcast(
  158. &AzFramework::QualitySystemEvents::LoadDefaultQualityGroup,
  159. AzFramework::QualityLevel::LevelFromDeviceRules);
  160. // expect the values are set based on the default for q_test which is 2
  161. EXPECT_EQ(m_console->GetCvarValue("q_test", value), AZ::GetValueResult::Success);
  162. EXPECT_EQ(value, AzFramework::QualityLevel{2});
  163. EXPECT_EQ(m_console->GetCvarValue("a_setting", intValue), AZ::GetValueResult::Success);
  164. EXPECT_EQ(intValue, 2);
  165. EXPECT_EQ(m_console->GetCvarValue("b_setting", stringValue), AZ::GetValueResult::Success);
  166. EXPECT_EQ(stringValue, "c");
  167. EXPECT_EQ(m_console->GetCvarValue("q_test_sub", value), AZ::GetValueResult::Success);
  168. EXPECT_EQ(value, AzFramework::QualityLevel{1});
  169. EXPECT_EQ(m_console->GetCvarValue("c_setting", intValue), AZ::GetValueResult::Success);
  170. EXPECT_EQ(intValue, 234);
  171. EXPECT_EQ(m_console->GetCvarValue("d_setting", intValue), AZ::GetValueResult::Success);
  172. EXPECT_EQ(intValue, 42);
  173. // when the group level 1 is loaded ("medium" which is "high" for q_test_sub)
  174. m_console->PerformCommand("q_test", { "1" });
  175. // expect the values are set based on the group level settings
  176. EXPECT_EQ(m_console->GetCvarValue("a_setting", intValue), AZ::GetValueResult::Success);
  177. EXPECT_EQ(intValue, 1);
  178. EXPECT_EQ(m_console->GetCvarValue("b_setting", stringValue), AZ::GetValueResult::Success);
  179. EXPECT_EQ(stringValue, "b");
  180. EXPECT_EQ(m_console->GetCvarValue("q_test_sub", value), AZ::GetValueResult::Success);
  181. EXPECT_EQ(value, AzFramework::QualityLevel{1});
  182. EXPECT_EQ(m_console->GetCvarValue("c_setting", intValue), AZ::GetValueResult::Success);
  183. EXPECT_EQ(intValue, 234);
  184. // d_settings doesn't specify a value for "high" so it should use highest available setting
  185. // which is "low" -> 42
  186. EXPECT_EQ(m_console->GetCvarValue("d_setting", intValue), AZ::GetValueResult::Success);
  187. EXPECT_EQ(intValue, 42);
  188. // when the group level 0 is loaded (low) using mixed-case name
  189. m_console->PerformCommand("q_test", { "LoW" });
  190. // settings at index 0 are correctly loaded
  191. EXPECT_EQ(m_console->GetCvarValue("a_setting", intValue), AZ::GetValueResult::Success);
  192. EXPECT_EQ(intValue, 0);
  193. EXPECT_EQ(m_console->GetCvarValue("b_setting", stringValue), AZ::GetValueResult::Success);
  194. EXPECT_EQ(stringValue, "a");
  195. EXPECT_EQ(m_console->GetCvarValue("q_test_sub", value), AZ::GetValueResult::Success);
  196. EXPECT_EQ(value, AzFramework::QualityLevel{0});
  197. EXPECT_EQ(m_console->GetCvarValue("c_setting", intValue), AZ::GetValueResult::Success);
  198. EXPECT_EQ(intValue, 123);
  199. EXPECT_EQ(m_console->GetCvarValue("d_setting", intValue), AZ::GetValueResult::Success);
  200. EXPECT_EQ(intValue, 42);
  201. }
  202. } // namespace UnitTest