summaryrefslogtreecommitdiffstats
path: root/src/lib/log/tests/message_initializer_1_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/log/tests/message_initializer_1_unittest.cc')
-rw-r--r--src/lib/log/tests/message_initializer_1_unittest.cc251
1 files changed, 251 insertions, 0 deletions
diff --git a/src/lib/log/tests/message_initializer_1_unittest.cc b/src/lib/log/tests/message_initializer_1_unittest.cc
new file mode 100644
index 0000000..c34139a
--- /dev/null
+++ b/src/lib/log/tests/message_initializer_1_unittest.cc
@@ -0,0 +1,251 @@
+// Copyright (C) 2012-2020 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <config.h>
+
+#include <log/message_dictionary.h>
+#include <log/message_initializer.h>
+#include <boost/lexical_cast.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <gtest/gtest.h>
+#include <string>
+
+using namespace isc;
+using namespace isc::log;
+using namespace std;
+
+// Declare a set of messages to go into the global dictionary.
+
+namespace {
+const char* values1[] = {
+ "GLOBAL1", "global message one",
+ "GLOBAL2", "global message two",
+ NULL
+};
+
+const char* values2[] = {
+ "GLOBAL3", "global message three",
+ "GLOBAL4", "global message four",
+ NULL
+};
+
+const char* values3[] = {
+ "GLOBAL7", "global message seven",
+ "GLOBAL8", "global message eight",
+ NULL
+};
+
+const char* values4[] = {
+ "GLOBAL8", "global message eight",
+ "GLOBAL9", "global message nine",
+ NULL
+};
+
+/// @brief Scoped pointer to the @c MessageInitializer object.
+typedef boost::scoped_ptr<MessageInitializer> MessageInitializerPtr;
+
+}
+
+// Statically initialize the global dictionary with those messages. Three sets
+// are used to check that the declaration of separate initializer objects
+// really does combine the messages. (The third set - declaring message IDs
+// GLOBAL5 and GLOBAL6) is declared in the separately-compiled file,
+// message_identifier_initializer_1a_unittest.cc.)
+
+const MessageInitializer init_message_initializer_unittest_1(values1);
+const MessageInitializer init_message_initializer_unittest_2(values2);
+
+// Check that the global dictionary is initialized with the specified
+// messages.
+
+namespace {
+void
+messageTest() {
+ static bool done = false;
+
+ // Execute once.
+ if (done) {
+ return;
+ } else {
+ done = true;
+ }
+
+ const MessageDictionaryPtr& global = MessageDictionary::globalDictionary();
+
+ // Pointers to the message arrays should have been stored, but none of the
+ // messages should yet be in the dictionary.
+ for (int i = 1; i <= 6; ++i) {
+ string symbol = string("GLOBAL") + boost::lexical_cast<std::string>(i);
+ EXPECT_EQ(string(""), global->getText(symbol));
+ }
+
+ // Load the dictionary - this should clear the message array pending count.
+ // (N.B. We do not check for a known value before the call, only that the
+ // value is not zero. This is because libraries against which the test
+ // is linked may have registered their own message arrays.)
+ EXPECT_NE(0, MessageInitializer::getPendingCount());
+ MessageInitializer::loadDictionary();
+ EXPECT_EQ(0, MessageInitializer::getPendingCount());
+
+ // ... and check the messages loaded.
+ EXPECT_EQ(string("global message one"), global->getText("GLOBAL1"));
+ EXPECT_EQ(string("global message two"), global->getText("GLOBAL2"));
+ EXPECT_EQ(string("global message three"), global->getText("GLOBAL3"));
+ EXPECT_EQ(string("global message four"), global->getText("GLOBAL4"));
+ EXPECT_EQ(string("global message five"), global->getText("GLOBAL5"));
+ EXPECT_EQ(string("global message six"), global->getText("GLOBAL6"));
+}
+}
+
+// Check that destroying the MessageInitializer causes the relevant
+// messages to be removed from the dictionary.
+
+TEST(MessageInitializerTest1, dynamicLoadUnload) {
+ // Try first messageTest.
+ messageTest();
+
+ // Obtain the instance of the global dictionary.
+ const MessageDictionaryPtr& global = MessageDictionary::globalDictionary();
+
+ // Dynamically create the first initializer.
+ MessageInitializerPtr init1(new MessageInitializer(values3));
+ EXPECT_EQ(1, MessageInitializer::getPendingCount());
+
+ // Dynamically create the second initializer.
+ MessageInitializerPtr init2(new MessageInitializer(values4));
+ EXPECT_EQ(2, MessageInitializer::getPendingCount());
+
+ // Load messages from both initializers to the global dictionary.
+ MessageInitializer::loadDictionary();
+ // There should be no pending messages.
+ EXPECT_EQ(0, MessageInitializer::getPendingCount());
+
+ // Make sure that the messages have been loaded.
+ EXPECT_EQ("global message seven", global->getText("GLOBAL7"));
+ EXPECT_EQ("global message eight", global->getText("GLOBAL8"));
+ EXPECT_EQ("global message nine", global->getText("GLOBAL9"));
+
+ // Destroy the first initializer. The first message should be removed.
+ // The second message should not be removed because it is also held
+ // by another object.
+ init1.reset();
+ EXPECT_TRUE(global->getText("GLOBAL7").empty());
+ EXPECT_EQ("global message eight", global->getText("GLOBAL8"));
+ EXPECT_EQ("global message nine", global->getText("GLOBAL9"));
+
+ // Destroy the second initializer. Now, all messages should be
+ // unregistered.
+ init2.reset();
+ EXPECT_TRUE(global->getText("GLOBAL7").empty());
+ EXPECT_TRUE(global->getText("GLOBAL8").empty());
+ EXPECT_TRUE(global->getText("GLOBAL9").empty());
+}
+
+// Check that destroying the MessageInitializer removes pending messages.
+
+TEST(MessageInitializerTest1, dynamicUnloadPending) {
+ // Try first messageTest.
+ messageTest();
+
+ // Obtain the instance of the global dictionary.
+ const MessageDictionaryPtr& global = MessageDictionary::globalDictionary();
+
+ // Dynamically create the first initializer.
+ MessageInitializerPtr init1(new MessageInitializer(values3));
+ ASSERT_EQ(1, MessageInitializer::getPendingCount());
+
+ // Create second initializer without committing the first set
+ // of messages to the dictionary.
+ MessageInitializerPtr init2(new MessageInitializer(values4));
+ ASSERT_EQ(2, MessageInitializer::getPendingCount());
+
+ // Destroy the first initializer and make sure that the number of
+ // pending message sets drops to 1.
+ init1.reset();
+ ASSERT_EQ(1, MessageInitializer::getPendingCount());
+
+ // Now destroy the second initializer and make sure that there are
+ // no pending messages.
+ init2.reset();
+ ASSERT_EQ(0, MessageInitializer::getPendingCount());
+
+ init1.reset(new MessageInitializer(values3));
+ ASSERT_EQ(1, MessageInitializer::getPendingCount());
+
+ // Load the messages to the dictionary and make sure there are no pending
+ // messages.
+ MessageInitializer::loadDictionary();
+ EXPECT_EQ(0, MessageInitializer::getPendingCount());
+
+ // Create the second initializer. There should be one pending set of
+ // messages.
+ init2.reset(new MessageInitializer(values4));
+ ASSERT_EQ(1, MessageInitializer::getPendingCount());
+
+ // Make sure that the messages defined by the first initializer
+ // are in the dictionary.
+ ASSERT_EQ("global message seven", global->getText("GLOBAL7"));
+ ASSERT_EQ("global message eight", global->getText("GLOBAL8"));
+ ASSERT_TRUE(global->getText("GLOBAL9").empty());
+
+ // Destroy the second initializer. There should be no pending messages
+ // now.
+ init2.reset();
+ ASSERT_EQ(0, MessageInitializer::getPendingCount());
+
+ // Loading the messages should be no-op.
+ MessageInitializer::loadDictionary();
+ ASSERT_EQ(0, MessageInitializer::getPendingCount());
+
+ // Make sure that the messages loaded from the first initializer
+ // are not affected.
+ ASSERT_EQ("global message seven", global->getText("GLOBAL7"));
+ ASSERT_EQ("global message eight", global->getText("GLOBAL8"));
+ ASSERT_TRUE(global->getText("GLOBAL9").empty());
+
+ // And remove them.
+ init1.reset();
+ EXPECT_TRUE(global->getText("GLOBAL7").empty());
+ EXPECT_TRUE(global->getText("GLOBAL8").empty());
+ EXPECT_TRUE(global->getText("GLOBAL9").empty());
+}
+
+TEST(MessageInitializerTest1, duplicates) {
+ // Try first messageTest.
+ messageTest();
+
+ // Original set should not have dupes
+ ASSERT_EQ(0, MessageInitializer::getDuplicates().size());
+
+ // This just defines 1, but we'll add it a number of times
+ const char* dupe[] = {
+ "DUPE", "dupe",
+ NULL
+ };
+ const MessageInitializer init_message_initializer_unittest_1(dupe);
+ const MessageInitializer init_message_initializer_unittest_2(dupe);
+
+ MessageInitializer::loadDictionary();
+ // Should be a dupe now
+ ASSERT_EQ(1, MessageInitializer::getDuplicates().size());
+
+ // clear them
+ MessageInitializer::clearDuplicates();
+ ASSERT_EQ(0, MessageInitializer::getDuplicates().size());
+
+ // Do it again to make sure, let's explicitly provide false now
+ const MessageInitializer init_message_initializer_unittest_3(dupe);
+ MessageInitializer::loadDictionary(false);
+ ASSERT_EQ(1, MessageInitializer::getDuplicates().size());
+
+ // Loading with ignore_duplicates=true should result in no (reported)
+ // dupes
+ MessageInitializer::clearDuplicates();
+ ASSERT_EQ(0, MessageInitializer::getDuplicates().size());
+ const MessageInitializer init_message_initializer_unittest_4(dupe);
+ MessageInitializer::loadDictionary(true);
+ ASSERT_EQ(0, MessageInitializer::getDuplicates().size());
+}