SettingsRegistryConsoleUtilsTests.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  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/Name/NameDictionary.h>
  9. #include <AzCore/Console/Console.h>
  10. #include <AzCore/Debug/TraceMessageBus.h>
  11. #include <AzCore/Settings/SettingsRegistryImpl.h>
  12. #include <AzCore/Settings/SettingsRegistryConsoleUtils.h>
  13. #include <AzCore/Settings/SettingsRegistryOriginTracker.h>
  14. #include <AzCore/UnitTest/TestTypes.h>
  15. #include <AzCore/std/string/string.h>
  16. namespace SettingsRegistryConsoleUtilsTests
  17. {
  18. class SettingsRegistryConsoleUtilsFixture
  19. : public UnitTest::LeakDetectionFixture
  20. {
  21. public:
  22. SettingsRegistryConsoleUtilsFixture()
  23. : LeakDetectionFixture()
  24. {
  25. AZ::NameDictionary::Create();
  26. }
  27. ~SettingsRegistryConsoleUtilsFixture()
  28. {
  29. AZ::NameDictionary::Destroy();
  30. }
  31. void SetUp() override
  32. {
  33. m_registry = AZStd::make_unique<AZ::SettingsRegistryImpl>();
  34. m_originTracker = AZStd::make_unique<AZ::SettingsRegistryOriginTracker>(*m_registry);
  35. // Store off the old global settings registry to restore after each test
  36. m_oldSettingsRegistry = AZ::SettingsRegistry::Get();
  37. if (m_oldSettingsRegistry != nullptr)
  38. {
  39. AZ::SettingsRegistry::Unregister(m_oldSettingsRegistry);
  40. }
  41. AZ::SettingsRegistry::Register(m_registry.get());
  42. }
  43. void TearDown() override
  44. {
  45. // Restore the old global settings registry
  46. AZ::SettingsRegistry::Unregister(m_registry.get());
  47. if (m_oldSettingsRegistry != nullptr)
  48. {
  49. AZ::SettingsRegistry::Register(m_oldSettingsRegistry);
  50. m_oldSettingsRegistry = {};
  51. }
  52. m_originTracker.reset();
  53. m_registry.reset();
  54. }
  55. AZStd::unique_ptr<AZ::SettingsRegistryImpl> m_registry;
  56. AZStd::unique_ptr<AZ::SettingsRegistryOriginTracker> m_originTracker;
  57. AZ::SettingsRegistryInterface* m_oldSettingsRegistry{};
  58. };
  59. TEST_F(SettingsRegistryConsoleUtilsFixture, SettingsRegistryCommand_SetValue_Successfully)
  60. {
  61. constexpr const char* settingsKey = "/TestKey";
  62. constexpr const char* expectedValue = "TestValue";
  63. AZ::Console testConsole(*m_registry);
  64. AZ::SettingsRegistryConsoleUtils::ConsoleFunctorHandle handle{
  65. AZ::SettingsRegistryConsoleUtils::RegisterAzConsoleCommands(*m_registry, testConsole) };
  66. EXPECT_TRUE(testConsole.PerformCommand(AZ::SettingsRegistryConsoleUtils::SettingsRegistrySet, { settingsKey, expectedValue }));
  67. AZ::SettingsRegistryInterface::FixedValueString settingsValue;
  68. EXPECT_TRUE(m_registry->Get(settingsValue, settingsKey));
  69. EXPECT_EQ(expectedValue, settingsValue);
  70. }
  71. TEST_F(SettingsRegistryConsoleUtilsFixture, SettingsRegistryCommand_SetValue_DoesNotSetValueAfterHandleDestruction)
  72. {
  73. constexpr const char* settingsKey = "/TestKey";
  74. constexpr const char* expectedValue = "TestValue";
  75. AZ::Console testConsole(*m_registry);
  76. // Scopes the console functor handle so that it destructs and unregisters the console functors
  77. {
  78. [[maybe_unused]] AZ::SettingsRegistryConsoleUtils::ConsoleFunctorHandle handle{
  79. AZ::SettingsRegistryConsoleUtils::RegisterAzConsoleCommands(*m_registry, testConsole) };
  80. }
  81. EXPECT_FALSE(testConsole.PerformCommand(AZ::SettingsRegistryConsoleUtils::SettingsRegistrySet, { settingsKey, expectedValue }));
  82. AZ::SettingsRegistryInterface::FixedValueString settingsValue;
  83. EXPECT_FALSE(m_registry->Get(settingsValue, settingsKey));
  84. EXPECT_NE(expectedValue, settingsValue);
  85. }
  86. TEST_F(SettingsRegistryConsoleUtilsFixture, SettingsRegistryCommand_RemoveKey_RemovesValueSuccessfully)
  87. {
  88. constexpr const char* settingsKey = "/TestKey";
  89. constexpr const char* settingsKey2 = "/TestKey2";
  90. constexpr const char* expectedValue = R"(TestValue)";
  91. constexpr const char* expectedValue2 = R"(Hello World)";
  92. AZ::Console testConsole(*m_registry);
  93. AZ::SettingsRegistryConsoleUtils::ConsoleFunctorHandle handle{
  94. AZ::SettingsRegistryConsoleUtils::RegisterAzConsoleCommands(*m_registry, testConsole) };
  95. // Add settings to settings registry
  96. EXPECT_TRUE(m_registry->Set(settingsKey, expectedValue));
  97. EXPECT_TRUE(m_registry->Set(settingsKey2, expectedValue2));
  98. EXPECT_TRUE(testConsole.PerformCommand(AZ::SettingsRegistryConsoleUtils::SettingsRegistryRemove, { settingsKey, settingsKey2 }));
  99. AZ::SettingsRegistryInterface::FixedValueString settingsValue;
  100. EXPECT_FALSE(m_registry->Get(settingsValue, settingsKey));
  101. EXPECT_FALSE(m_registry->Get(settingsValue, settingsKey2));
  102. }
  103. TEST_F(SettingsRegistryConsoleUtilsFixture, SettingsRegistryCommand_RemoveKey_DoesNotRemoveAfterHandleDestruction)
  104. {
  105. constexpr const char* settingsKey = "/TestKey";
  106. constexpr const char* settingsKey2 = "/TestKey2";
  107. constexpr const char* expectedValue = R"(TestValue)";
  108. constexpr const char* expectedValue2 = R"(Hello World)";
  109. AZ::Console testConsole(*m_registry);
  110. // Add settings to settings registry
  111. EXPECT_TRUE(m_registry->Set(settingsKey, expectedValue));
  112. EXPECT_TRUE(m_registry->Set(settingsKey2, expectedValue2));
  113. AZ::SettingsRegistryInterface::FixedValueString settingsValue;
  114. // Scopes the ConsoleFunctor Handle to make sure it is destroyed before the second PerformCommand call
  115. {
  116. AZ::SettingsRegistryConsoleUtils::ConsoleFunctorHandle handle{
  117. AZ::SettingsRegistryConsoleUtils::RegisterAzConsoleCommands(*m_registry, testConsole) };
  118. // @settingsKey2 should be removed by the remove command
  119. EXPECT_TRUE(testConsole.PerformCommand(AZ::SettingsRegistryConsoleUtils::SettingsRegistryRemove, { settingsKey2 }));
  120. EXPECT_FALSE(m_registry->Get(settingsValue, settingsKey2));
  121. }
  122. // @settingsKey should be remain since the settings registry is no longer registered with the local console
  123. EXPECT_FALSE(testConsole.PerformCommand(AZ::SettingsRegistryConsoleUtils::SettingsRegistryRemove, { settingsKey }));
  124. EXPECT_TRUE(m_registry->Get(settingsValue, settingsKey));
  125. EXPECT_STREQ(expectedValue, settingsValue.c_str());
  126. }
  127. TEST_F(SettingsRegistryConsoleUtilsFixture, SettingsRegistryCommand_DumpValue_SuccessfullyDumpsValueToTraceBus)
  128. {
  129. constexpr const char* settingsKey = "/TestKey";
  130. constexpr const char* settingsKey2 = "/TestKey2";
  131. constexpr const char* expectedValue = R"(TestValue)";
  132. constexpr const char* expectedValue2 = R"(Hello World)";
  133. AZ::Console testConsole(*m_registry);
  134. AZ::SettingsRegistryConsoleUtils::ConsoleFunctorHandle handle{
  135. AZ::SettingsRegistryConsoleUtils::RegisterAzConsoleCommands(*m_registry, testConsole) };
  136. // Add settings to settings registry
  137. EXPECT_TRUE(m_registry->Set(settingsKey, expectedValue));
  138. EXPECT_TRUE(m_registry->Set(settingsKey2, expectedValue2));
  139. // Create a TraceMessageBus Handler for capturing the dumping of the settings
  140. struct SettingsRegistryDumpCommandHandler
  141. : public AZ::Debug::TraceMessageBus::Handler
  142. {
  143. bool OnOutput(const char* window, const char* message) override
  144. {
  145. if (window == AZStd::string_view("SettingsRegistry"))
  146. {
  147. bool foundExpectedValue{};
  148. AZStd::string_view messageView(message);
  149. for (AZStd::string_view expectedValue : m_validValues)
  150. {
  151. if (messageView.find(expectedValue) != AZStd::string_view::npos)
  152. {
  153. foundExpectedValue = true;
  154. break;
  155. }
  156. }
  157. if (!foundExpectedValue)
  158. {
  159. AZ::SettingsRegistryInterface::FixedValueString delimitedExpectedValues;
  160. AZ::StringFunc::Join(delimitedExpectedValues, m_validValues.begin(), m_validValues.end(), ",");
  161. ADD_FAILURE() << "Message:" << message << " Did not contain any of the expected test values: "
  162. << delimitedExpectedValues.c_str();
  163. }
  164. return true;
  165. }
  166. return false;
  167. }
  168. AZStd::fixed_vector<AZStd::string_view, 2> m_validValues;
  169. };
  170. SettingsRegistryDumpCommandHandler traceHandler;
  171. traceHandler.m_validValues = { expectedValue, expectedValue2 };
  172. traceHandler.BusConnect();
  173. EXPECT_TRUE(testConsole.PerformCommand(AZ::SettingsRegistryConsoleUtils::SettingsRegistryDump, { settingsKey }));
  174. EXPECT_TRUE(testConsole.PerformCommand(AZ::SettingsRegistryConsoleUtils::SettingsRegistryDump, { settingsKey2, settingsKey }));
  175. traceHandler.BusDisconnect();
  176. }
  177. TEST_F(SettingsRegistryConsoleUtilsFixture, SettingsRegistryCommand_DumpAll_DumpsEntireSettingsRegistry)
  178. {
  179. constexpr const char* SettingsKey = "TestKey";
  180. constexpr const char* SettingsKey2 = "TestKey2";
  181. constexpr const char* ExpectedValue = R"(TestValue)";
  182. constexpr const char* ExpectedValue2 = R"(Hello World)";
  183. AZ::Console testConsole(*m_registry);
  184. AZ::SettingsRegistryConsoleUtils::ConsoleFunctorHandle handle{
  185. AZ::SettingsRegistryConsoleUtils::RegisterAzConsoleCommands(*m_registry, testConsole) };
  186. // Add settings to settings registry
  187. auto jsonPointerPath = AZ::SettingsRegistryInterface::FixedValueString::format("/%s",
  188. SettingsKey);
  189. EXPECT_TRUE(m_registry->Set(jsonPointerPath, ExpectedValue));
  190. // Second Setting to set
  191. jsonPointerPath = AZ::SettingsRegistryInterface::FixedValueString::format("/%s",
  192. SettingsKey2);
  193. EXPECT_TRUE(m_registry->Set(jsonPointerPath, ExpectedValue2));
  194. // Create a TraceMessageBus Handler for capturing the dumping of the settings
  195. struct SettingsRegistryDumpAllCommandHandler
  196. : public AZ::Debug::TraceMessageBus::Handler
  197. {
  198. SettingsRegistryDumpAllCommandHandler(const char* settingsKey, const char* settingsKey2,
  199. const char* expectedValue, const char* expectedValue2)
  200. : m_settingsKey{ settingsKey }
  201. , m_settingsKey2{ settingsKey2 }
  202. , m_expectedValue{ expectedValue }
  203. , m_expectedValue2{ expectedValue2 }
  204. {
  205. }
  206. bool OnOutput(const char* window, const char* message) override
  207. {
  208. if (window == AZStd::string_view("SettingsRegistry"))
  209. {
  210. rapidjson::Document jsonDocument;
  211. jsonDocument.Parse(message);
  212. // Test for the first key
  213. auto memberIterator = jsonDocument.FindMember(m_settingsKey);
  214. EXPECT_NE(jsonDocument.MemberEnd(), memberIterator);
  215. EXPECT_STREQ(m_expectedValue, memberIterator->value.GetString());
  216. // Test for the second key
  217. memberIterator = jsonDocument.FindMember(m_settingsKey2);
  218. EXPECT_NE(jsonDocument.MemberEnd(), memberIterator);
  219. EXPECT_STREQ(m_expectedValue2, memberIterator->value.GetString());
  220. return true;
  221. }
  222. return false;
  223. }
  224. const char* m_settingsKey{};
  225. const char* m_settingsKey2{};
  226. const char* m_expectedValue{};
  227. const char* m_expectedValue2{};
  228. };
  229. SettingsRegistryDumpAllCommandHandler traceHandler{ SettingsKey, SettingsKey2, ExpectedValue, ExpectedValue2 };
  230. traceHandler.BusConnect();
  231. EXPECT_TRUE(testConsole.PerformCommand(AZ::SettingsRegistryConsoleUtils::SettingsRegistryDumpAll));
  232. traceHandler.BusDisconnect();
  233. }
  234. TEST_F(SettingsRegistryConsoleUtilsFixture, SettingsRegistryCommand_DumpOrigin_Succeeds)
  235. {
  236. constexpr const char* SettingsKey = "TestKey";
  237. constexpr const char* SettingsKey2 = "TestKey2";
  238. constexpr const char* ExpectedValue = R"(TestValue)";
  239. constexpr const char* ExpectedValue2 = R"(Hello World)";
  240. AZ::Console testConsole(*m_registry);
  241. AZ::SettingsRegistryConsoleUtils::ConsoleFunctorHandle handle{ AZ::SettingsRegistryConsoleUtils::RegisterAzConsoleCommands(
  242. *m_originTracker, testConsole) };
  243. // Add settings to settings registry
  244. auto jsonPointerPath = AZ::SettingsRegistryInterface::FixedValueString::format("/%s", SettingsKey);
  245. EXPECT_TRUE(m_registry->Set(jsonPointerPath, ExpectedValue));
  246. // Second Setting to set
  247. jsonPointerPath = AZ::SettingsRegistryInterface::FixedValueString::format("/%s", SettingsKey2);
  248. EXPECT_TRUE(m_registry->Set(jsonPointerPath, ExpectedValue2));
  249. // Create a TraceMessageBus Handler for capturing the dumping of the settings
  250. struct SettingsRegistryDumpOriginCommandHandler : public AZ::Debug::TraceMessageBus::Handler
  251. {
  252. SettingsRegistryDumpOriginCommandHandler(
  253. const char* settingsKey, const char* settingsKey2, const char* expectedValue, const char* expectedValue2)
  254. : m_settingsKey{ settingsKey }
  255. , m_settingsKey2{ settingsKey2 }
  256. , m_expectedValue{ expectedValue }
  257. , m_expectedValue2{ expectedValue2 }
  258. {
  259. }
  260. bool OnOutput(const char* window, const char* message) override
  261. {
  262. if (window == AZStd::string_view("SettingsRegistry"))
  263. {
  264. // Test for in memory origin
  265. AZStd::string_view messageView = message;
  266. EXPECT_TRUE(messageView.contains("<in-memory>"));
  267. }
  268. return false;
  269. }
  270. const char* m_settingsKey{};
  271. const char* m_settingsKey2{};
  272. const char* m_expectedValue{};
  273. const char* m_expectedValue2{};
  274. };
  275. SettingsRegistryDumpOriginCommandHandler traceHandler{ SettingsKey, SettingsKey2, ExpectedValue, ExpectedValue2 };
  276. traceHandler.BusConnect();
  277. EXPECT_TRUE(testConsole.PerformCommand(AZ::SettingsRegistryConsoleUtils::SettingsRegistryDumpOrigin));
  278. traceHandler.BusDisconnect();
  279. }
  280. }