1 // Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7 #include <config.h>
8 #include <gtest/gtest.h>
9
10 #include <log/macros.h>
11 #include <log/logger_support.h>
12 #include <log/log_messages.h>
13 #include <log/buffer_appender_impl.h>
14
15 #include <log4cplus/loggingmacros.h>
16 #include <log4cplus/logger.h>
17 #include <log4cplus/nullappender.h>
18 #include <log4cplus/spi/loggingevent.h>
19
20 using namespace isc::log;
21 using namespace isc::log::internal;
22
23 namespace isc {
24 namespace log {
25
26 /// \brief Specialized test class
27 ///
28 /// In order to test append() somewhat directly, this
29 /// class implements one more method (addEvent)
30 class TestBufferAppender : public BufferAppender {
31 public:
addEvent(const log4cplus::spi::InternalLoggingEvent & event)32 void addEvent(const log4cplus::spi::InternalLoggingEvent& event) {
33 append(event);
34 }
35 };
36
37 class BufferAppenderTest : public ::testing::Test {
38 protected:
BufferAppenderTest()39 BufferAppenderTest() : buffer_appender1(new TestBufferAppender()),
40 appender1(buffer_appender1),
41 buffer_appender2(new TestBufferAppender()),
42 appender2(buffer_appender2),
43 logger(log4cplus::Logger::getInstance("buffer"))
44 {
45 logger.setLogLevel(log4cplus::TRACE_LOG_LEVEL);
46 }
47
~BufferAppenderTest()48 ~BufferAppenderTest() {
49 // If any log messages are left, we don't care, get rid of them,
50 // by flushing them to a null appender
51 // Given the 'messages should not get lost' approach of the logging
52 // system, not flushing them to a null appender would cause them
53 // to be dumped to stdout as the test is destroyed, making
54 // unnecessarily messy test output.
55 log4cplus::SharedAppenderPtr null_appender(
56 new log4cplus::NullAppender());
57 logger.removeAllAppenders();
58 logger.addAppender(null_appender);
59 buffer_appender1->flush();
60 buffer_appender2->flush();
61 }
62
63 TestBufferAppender* buffer_appender1;
64 log4cplus::SharedAppenderPtr appender1;
65 TestBufferAppender* buffer_appender2;
66 log4cplus::SharedAppenderPtr appender2;
67 log4cplus::Logger logger;
68 };
69
70 // Test that log events are indeed stored, and that they are
71 // flushed to the new appenders of their logger
TEST_F(BufferAppenderTest,flush)72 TEST_F(BufferAppenderTest, flush) {
73 ASSERT_EQ(0, buffer_appender1->getBufferSize());
74 ASSERT_EQ(0, buffer_appender2->getBufferSize());
75
76 // Create a Logger, log a few messages with the first appender
77 logger.addAppender(appender1);
78 LOG4CPLUS_INFO(logger, "Foo");
79 ASSERT_EQ(1, buffer_appender1->getBufferSize());
80 LOG4CPLUS_INFO(logger, "Foo");
81 ASSERT_EQ(2, buffer_appender1->getBufferSize());
82 LOG4CPLUS_INFO(logger, "Foo");
83 ASSERT_EQ(3, buffer_appender1->getBufferSize());
84
85 // Second buffer should still be empty
86 ASSERT_EQ(0, buffer_appender2->getBufferSize());
87
88 // Replace the appender by the second one, and call flush;
89 // this should cause all events to be moved to the second buffer
90 logger.removeAllAppenders();
91 logger.addAppender(appender2);
92 buffer_appender1->flush();
93 ASSERT_EQ(0, buffer_appender1->getBufferSize());
94 ASSERT_EQ(3, buffer_appender2->getBufferSize());
95 }
96
97 // Once flushed, logging new messages with the same buffer should fail
TEST_F(BufferAppenderTest,addAfterFlush)98 TEST_F(BufferAppenderTest, addAfterFlush) {
99 logger.addAppender(appender1);
100 buffer_appender1->flush();
101 EXPECT_THROW(LOG4CPLUS_INFO(logger, "Foo"), LogBufferAddAfterFlush);
102 // It should not have been added
103 ASSERT_EQ(0, buffer_appender1->getBufferSize());
104
105 // But logging should work again as long as a different buffer is used
106 logger.removeAllAppenders();
107 logger.addAppender(appender2);
108 LOG4CPLUS_INFO(logger, "Foo");
109 ASSERT_EQ(1, buffer_appender2->getBufferSize());
110 }
111
TEST_F(BufferAppenderTest,addDirectly)112 TEST_F(BufferAppenderTest, addDirectly) {
113 // A few direct calls
114 log4cplus::spi::InternalLoggingEvent event("buffer",
115 log4cplus::INFO_LOG_LEVEL,
116 "Bar", "file", 123);
117 buffer_appender1->addEvent(event);
118 ASSERT_EQ(1, buffer_appender1->getBufferSize());
119
120 // Do one from a smaller scope to make sure destruction doesn't harm
121 {
122 log4cplus::spi::InternalLoggingEvent event2("buffer",
123 log4cplus::INFO_LOG_LEVEL,
124 "Bar", "file", 123);
125 buffer_appender1->addEvent(event2);
126 }
127 ASSERT_EQ(2, buffer_appender1->getBufferSize());
128
129 // And flush them to the next
130 logger.removeAllAppenders();
131 logger.addAppender(appender2);
132 buffer_appender1->flush();
133 ASSERT_EQ(0, buffer_appender1->getBufferSize());
134 ASSERT_EQ(2, buffer_appender2->getBufferSize());
135 }
136
137 }
138 }
139