message_initializer_1_unittest.cc 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. // Copyright (C) 2012,2015 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <log/message_dictionary.h>
  15. #include <log/message_initializer.h>
  16. #include <boost/lexical_cast.hpp>
  17. #include <boost/scoped_ptr.hpp>
  18. #include <gtest/gtest.h>
  19. #include <string>
  20. using namespace isc;
  21. using namespace isc::log;
  22. using namespace std;
  23. // Declare a set of messages to go into the global dictionary.
  24. namespace {
  25. const char* values1[] = {
  26. "GLOBAL1", "global message one",
  27. "GLOBAL2", "global message two",
  28. NULL
  29. };
  30. const char* values2[] = {
  31. "GLOBAL3", "global message three",
  32. "GLOBAL4", "global message four",
  33. NULL
  34. };
  35. const char* values3[] = {
  36. "GLOBAL7", "global message seven",
  37. "GLOBAL8", "global message eight",
  38. NULL
  39. };
  40. const char* values4[] = {
  41. "GLOBAL8", "global message eight",
  42. "GLOBAL9", "global message nine",
  43. NULL
  44. };
  45. /// @brief Scoped pointer to the @c MessageInitializer object.
  46. typedef boost::scoped_ptr<MessageInitializer> MessageInitializerPtr;
  47. }
  48. // Statically initialize the global dictionary with those messages. Three sets
  49. // are used to check that the declaration of separate initializer objects
  50. // really does combine the messages. (The third set - declaring message IDs
  51. // GLOBAL5 and GLOBAL6) is declared in the separately-compiled file,
  52. // message_identifier_initializer_1a_unittest.cc.)
  53. const MessageInitializer init_message_initializer_unittest_1(values1);
  54. const MessageInitializer init_message_initializer_unittest_2(values2);
  55. // Check that the global dictionary is initialized with the specified
  56. // messages.
  57. TEST(MessageInitializerTest1, messageTest) {
  58. const MessageDictionaryPtr& global = MessageDictionary::globalDictionary();
  59. // Pointers to the message arrays should have been stored, but none of the
  60. // messages should yet be in the dictionary.
  61. for (int i = 1; i <= 6; ++i) {
  62. string symbol = string("GLOBAL") + boost::lexical_cast<std::string>(i);
  63. EXPECT_EQ(string(""), global->getText(symbol));
  64. }
  65. // Load the dictionary - this should clear the message array pending count.
  66. // (N.B. We do not check for a known value before the call, only that the
  67. // value is not zero. This is because libraries against which the test
  68. // is linked may have registered their own message arrays.)
  69. EXPECT_NE(0, MessageInitializer::getPendingCount());
  70. MessageInitializer::loadDictionary();
  71. EXPECT_EQ(0, MessageInitializer::getPendingCount());
  72. // ... and check the messages loaded.
  73. EXPECT_EQ(string("global message one"), global->getText("GLOBAL1"));
  74. EXPECT_EQ(string("global message two"), global->getText("GLOBAL2"));
  75. EXPECT_EQ(string("global message three"), global->getText("GLOBAL3"));
  76. EXPECT_EQ(string("global message four"), global->getText("GLOBAL4"));
  77. EXPECT_EQ(string("global message five"), global->getText("GLOBAL5"));
  78. EXPECT_EQ(string("global message six"), global->getText("GLOBAL6"));
  79. }
  80. // Check that destroying the MessageInitializer causes the relevant
  81. // messages to be removed from the dictionary.
  82. TEST(MessageInitializerTest1, dynamicLoadUnload) {
  83. // Obtain the instance of the global dictionary.
  84. const MessageDictionaryPtr& global = MessageDictionary::globalDictionary();
  85. // Dynamically create the first initializer.
  86. MessageInitializerPtr init1(new MessageInitializer(values3));
  87. EXPECT_EQ(1, MessageInitializer::getPendingCount());
  88. // Dynamically create the second initializer.
  89. MessageInitializerPtr init2(new MessageInitializer(values4));
  90. EXPECT_EQ(2, MessageInitializer::getPendingCount());
  91. // Load messages from both initializers to the global dictionary.
  92. MessageInitializer::loadDictionary();
  93. // There should be no pending messages.
  94. EXPECT_EQ(0, MessageInitializer::getPendingCount());
  95. // Make sure that the messages have been loaded.
  96. EXPECT_EQ("global message seven", global->getText("GLOBAL7"));
  97. EXPECT_EQ("global message eight", global->getText("GLOBAL8"));
  98. EXPECT_EQ("global message nine", global->getText("GLOBAL9"));
  99. // Destroy the first initializer. The first message should be removed.
  100. // The second message should not be removed because it is also held
  101. // by another object.
  102. init1.reset();
  103. EXPECT_TRUE(global->getText("GLOBAL7").empty());
  104. EXPECT_EQ("global message eight", global->getText("GLOBAL8"));
  105. EXPECT_EQ("global message nine", global->getText("GLOBAL9"));
  106. // Destroy the second initializer. Now, all messages should be
  107. // unregistered.
  108. init2.reset();
  109. EXPECT_TRUE(global->getText("GLOBAL7").empty());
  110. EXPECT_TRUE(global->getText("GLOBAL8").empty());
  111. EXPECT_TRUE(global->getText("GLOBAL9").empty());
  112. }
  113. // Check that destroying the MessageInitializer removes pending messages.
  114. TEST(MessageInitializerTest1, dynamicUnloadPending) {
  115. // Obtain the instance of the global dictionary.
  116. const MessageDictionaryPtr& global = MessageDictionary::globalDictionary();
  117. // Dynamically create the first initializer.
  118. MessageInitializerPtr init1(new MessageInitializer(values3));
  119. ASSERT_EQ(1, MessageInitializer::getPendingCount());
  120. // Create second initializer without committing the first set
  121. // of messages to the dictionary.
  122. MessageInitializerPtr init2(new MessageInitializer(values4));
  123. ASSERT_EQ(2, MessageInitializer::getPendingCount());
  124. // Destroy the first initializer and make sure that the number of
  125. // pending message sets drops to 1.
  126. init1.reset();
  127. ASSERT_EQ(1, MessageInitializer::getPendingCount());
  128. // Now destroy the second initializer and make sure that there are
  129. // no pending messages.
  130. init2.reset();
  131. ASSERT_EQ(0, MessageInitializer::getPendingCount());
  132. init1.reset(new MessageInitializer(values3));
  133. ASSERT_EQ(1, MessageInitializer::getPendingCount());
  134. // Load the messages to the dictionary and make sure there are no pending
  135. // messages.
  136. MessageInitializer::loadDictionary();
  137. EXPECT_EQ(0, MessageInitializer::getPendingCount());
  138. // Create the second initializer. There should be one pending set of
  139. // messages.
  140. init2.reset(new MessageInitializer(values4));
  141. ASSERT_EQ(1, MessageInitializer::getPendingCount());
  142. // Make sure that the messages defined by the first initializer
  143. // are in the dictionary.
  144. ASSERT_EQ("global message seven", global->getText("GLOBAL7"));
  145. ASSERT_EQ("global message eight", global->getText("GLOBAL8"));
  146. ASSERT_TRUE(global->getText("GLOBAL9").empty());
  147. // Destroy the second initializer. There should be no pending messages
  148. // now.
  149. init2.reset();
  150. ASSERT_EQ(0, MessageInitializer::getPendingCount());
  151. // Loading the messages should be no-op.
  152. MessageInitializer::loadDictionary();
  153. ASSERT_EQ(0, MessageInitializer::getPendingCount());
  154. // Make sure that the messages loaded from the first initializer
  155. // are not affected.
  156. ASSERT_EQ("global message seven", global->getText("GLOBAL7"));
  157. ASSERT_EQ("global message eight", global->getText("GLOBAL8"));
  158. ASSERT_TRUE(global->getText("GLOBAL9").empty());
  159. // And remove them.
  160. init1.reset();
  161. EXPECT_TRUE(global->getText("GLOBAL7").empty());
  162. EXPECT_TRUE(global->getText("GLOBAL8").empty());
  163. EXPECT_TRUE(global->getText("GLOBAL9").empty());
  164. }
  165. TEST(MessageInitializerTest1, duplicates) {
  166. // Original set should not have dupes
  167. ASSERT_EQ(0, MessageInitializer::getDuplicates().size());
  168. // This just defines 1, but we'll add it a number of times
  169. const char* dupe[] = {
  170. "DUPE", "dupe",
  171. NULL
  172. };
  173. const MessageInitializer init_message_initializer_unittest_1(dupe);
  174. const MessageInitializer init_message_initializer_unittest_2(dupe);
  175. MessageInitializer::loadDictionary();
  176. // Should be a dupe now
  177. ASSERT_EQ(1, MessageInitializer::getDuplicates().size());
  178. // clear them
  179. MessageInitializer::clearDuplicates();
  180. ASSERT_EQ(0, MessageInitializer::getDuplicates().size());
  181. // Do it again to make sure, let's explicitly provide false now
  182. const MessageInitializer init_message_initializer_unittest_3(dupe);
  183. MessageInitializer::loadDictionary(false);
  184. ASSERT_EQ(1, MessageInitializer::getDuplicates().size());
  185. // Loading with ignore_duplicates=true should result in no (reported)
  186. // dupes
  187. MessageInitializer::clearDuplicates();
  188. ASSERT_EQ(0, MessageInitializer::getDuplicates().size());
  189. const MessageInitializer init_message_initializer_unittest_4(dupe);
  190. MessageInitializer::loadDictionary(true);
  191. ASSERT_EQ(0, MessageInitializer::getDuplicates().size());
  192. }