1//
2// LoggingConfiguratorTest.cpp
3//
4// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
5// and Contributors.
6//
7// SPDX-License-Identifier: BSL-1.0
8//
9
10
11#include "LoggingConfiguratorTest.h"
12#include "Poco/CppUnit/TestCaller.h"
13#include "Poco/CppUnit/TestSuite.h"
14#include "Poco/Util/LoggingConfigurator.h"
15#include "Poco/Util/PropertyFileConfiguration.h"
16#include "Poco/LoggingRegistry.h"
17#include "Poco/ConsoleChannel.h"
18#if defined(_WIN32)
19#include "Poco/WindowsConsoleChannel.h"
20#endif
21#include "Poco/FileChannel.h"
22#include "Poco/SplitterChannel.h"
23#include "Poco/FormattingChannel.h"
24#include "Poco/PatternFormatter.h"
25#include "Poco/Logger.h"
26#include "Poco/Message.h"
27#include "Poco/AutoPtr.h"
28#include <sstream>
29
30
31using Poco::Util::LoggingConfigurator;
32using Poco::Util::PropertyFileConfiguration;
33using Poco::LoggingRegistry;
34using Poco::Channel;
35using Poco::ConsoleChannel;
36using Poco::FileChannel;
37using Poco::SplitterChannel;
38using Poco::FormattingChannel;
39using Poco::PatternFormatter;
40using Poco::Logger;
41using Poco::Message;
42using Poco::AutoPtr;
43
44
45LoggingConfiguratorTest::LoggingConfiguratorTest(const std::string& name): CppUnit::TestCase(name)
46{
47}
48
49
50LoggingConfiguratorTest::~LoggingConfiguratorTest()
51{
52}
53
54
55void LoggingConfiguratorTest::testConfigurator()
56{
57 static const std::string config =
58 "logging.loggers.root.channel = c1\n"
59 "logging.loggers.root.level = warning\n"
60 "logging.loggers.l1.name = logger1\n"
61 "logging.loggers.l1.channel.class = FileChannel\n"
62 "logging.loggers.l1.channel.pattern = %s: [%p] %t\n"
63 "logging.loggers.l1.channel.path = logfile.log\n"
64 "logging.loggers.l1.level = information\n"
65 "logging.loggers.l2.name = logger2\n"
66 "logging.loggers.l2.channel.class = SplitterChannel\n"
67 "logging.loggers.l2.channel.channel1 = c2\n"
68 "logging.loggers.l2.channel.channel2 = c3\n"
69 "logging.loggers.l2.level = debug\n"
70 "logging.channels.c1.class = ConsoleChannel\n"
71 "logging.channels.c1.formatter = f1\n"
72 "logging.channels.c2.class = FileChannel\n"
73 "logging.channels.c2.path = ${system.tempDir}/sample.log\n"
74 "logging.channels.c2.formatter.class = PatternFormatter\n"
75 "logging.channels.c2.formatter.pattern = %s: {%p} %t\n"
76 "logging.channels.c3.class = ConsoleChannel\n"
77 "logging.channels.c3.pattern = %s: [%p] %t\n"
78 "logging.formatters.f1.class = PatternFormatter\n"
79 "logging.formatters.f1.pattern = %s-[%p] %t\n"
80 "logging.formatters.f1.times = UTC\n";
81
82 std::istringstream istr(config);
83 AutoPtr<PropertyFileConfiguration> pConfig = new PropertyFileConfiguration(istr);
84
85 LoggingConfigurator configurator;
86 configurator.configure(pConfig);
87
88 Logger& root = Logger::get("");
89 assertTrue (root.getLevel() == Message::PRIO_WARNING);
90 FormattingChannel::Ptr pFC = root.getChannel().cast<FormattingChannel>();
91 assertNotNull (pFC);
92#if defined(_WIN32) && !defined(_WIN32_WCE)
93 assertTrue (!pFC->getChannel().cast<Poco::WindowsConsoleChannel>().isNull());
94#else
95 assertTrue (!pFC->getChannel().cast<Poco::ConsoleChannel>().isNull());
96#endif
97 assertTrue (!pFC->getFormatter().cast<Poco::PatternFormatter>().isNull());
98 assertTrue ((pFC->getFormatter().cast<PatternFormatter>())->getProperty("pattern") == "%s-[%p] %t");
99
100 Logger& logger1 = Logger::get("logger1");
101 assertTrue (logger1.getLevel() == Message::PRIO_INFORMATION);
102 pFC = logger1.getChannel().cast<FormattingChannel>();
103 assertTrue (!pFC.isNull());
104 assertTrue (!pFC->getChannel().cast<FileChannel>().isNull());
105 assertTrue (!pFC->getFormatter().cast<PatternFormatter>().isNull());
106 assertTrue (pFC->getFormatter().cast<PatternFormatter>()->getProperty("pattern") == "%s: [%p] %t");
107
108 Logger& logger2 = Logger::get("logger2");
109 assertTrue (logger2.getLevel() == Message::PRIO_DEBUG);
110 assertTrue (!logger2.getChannel().cast<SplitterChannel>().isNull());
111}
112
113
114void LoggingConfiguratorTest::testBadConfiguration1()
115{
116 // this is mainly testing for memory leaks in case of
117 // a bad configuration.
118
119 static const std::string config =
120 "logging.loggers.root.channel = c1\n"
121 "logging.loggers.root.level = warning\n"
122 "logging.loggers.l1.name = logger1\n"
123 "logging.loggers.l1.channel.class = FileChannel\n"
124 "logging.loggers.l1.channel.pattern = %s: [%p] %t\n"
125 "logging.loggers.l1.channel.path = logfile.log\n"
126 "logging.loggers.l1.level = information\n"
127 "logging.loggers.l2.name = logger2\n"
128 "logging.loggers.l2.channel.class = UnknownChannel\n"
129 "logging.loggers.l2.level = debug\n"
130 "logging.channels.c1.class = ConsoleChannel\n"
131 "logging.channels.c1.formatter = f1\n"
132 "logging.channels.c2.class = FileChannel\n"
133 "logging.channels.c2.path = ${system.tempDir}/sample.log\n"
134 "logging.channels.c2.formatter.class = PatternFormatter\n"
135 "logging.channels.c2.formatter.pattern = %s: {%p} %t\n"
136 "logging.channels.c3.class = ConsoleChannel\n"
137 "logging.channels.c3.pattern = %s: [%p] %t\n"
138 "logging.formatters.f1.class = PatternFormatter\n"
139 "logging.formatters.f1.pattern = %s-[%p] %t\n"
140 "logging.formatters.f1.times = UTC\n";
141
142 std::istringstream istr(config);
143 AutoPtr<PropertyFileConfiguration> pConfig = new PropertyFileConfiguration(istr);
144
145 LoggingConfigurator configurator;
146 try
147 {
148 configurator.configure(pConfig);
149 fail("bad configuration - must throw");
150 }
151 catch (Poco::Exception&)
152 {
153 }
154}
155
156
157void LoggingConfiguratorTest::testBadConfiguration2()
158{
159 // this is mainly testing for memory leaks in case of
160 // a bad configuration.
161
162 static const std::string config =
163 "logging.loggers.root.channel = c1\n"
164 "logging.loggers.root.level = unknown\n"
165 "logging.loggers.l1.name = logger1\n"
166 "logging.loggers.l1.channel.class = FileChannel\n"
167 "logging.loggers.l1.channel.pattern = %s: [%p] %t\n"
168 "logging.loggers.l1.channel.path = logfile.log\n"
169 "logging.loggers.l1.level = information\n"
170 "logging.loggers.l2.name = logger2\n"
171 "logging.loggers.l2.channel.class = SplitterChannel\n"
172 "logging.loggers.l2.level = debug\n"
173 "logging.channels.c1.class = ConsoleChannel\n"
174 "logging.channels.c1.formatter = f1\n"
175 "logging.channels.c2.class = FileChannel\n"
176 "logging.channels.c2.path = ${system.tempDir}/sample.log\n"
177 "logging.channels.c2.formatter.class = PatternFormatter\n"
178 "logging.channels.c2.formatter.pattern = %s: {%p} %t\n"
179 "logging.channels.c3.class = ConsoleChannel\n"
180 "logging.channels.c3.pattern = %s: [%p] %t\n"
181 "logging.formatters.f1.class = PatternFormatter\n"
182 "logging.formatters.f1.pattern = %s-[%p] %t\n"
183 "logging.formatters.f1.times = UTC\n";
184
185 std::istringstream istr(config);
186 AutoPtr<PropertyFileConfiguration> pConfig = new PropertyFileConfiguration(istr);
187
188 LoggingConfigurator configurator;
189 try
190 {
191 configurator.configure(pConfig);
192 fail("bad configuration - must throw");
193 }
194 catch (Poco::Exception&)
195 {
196 }
197}
198
199
200void LoggingConfiguratorTest::testBadConfiguration3()
201{
202 // this is mainly testing for memory leaks in case of
203 // a bad configuration.
204
205 static const std::string config =
206 "logging.loggers.root.channel = c1\n"
207 "logging.loggers.root.level = warning\n"
208 "logging.loggers.l1.name = logger1\n"
209 "logging.loggers.l1.channel.class = FileChannel\n"
210 "logging.loggers.l1.channel.pattern = %s: [%p] %t\n"
211 "logging.loggers.l1.channel.path = logfile.log\n"
212 "logging.loggers.l1.level = information\n"
213 "logging.loggers.l2.name = logger2\n"
214 "logging.loggers.l2.channel.class = UnknownChannel\n"
215 "logging.loggers.l2.level = debug\n"
216 "logging.channels.c1.class = ConsoleChannel\n"
217 "logging.channels.c1.formatter = f1\n"
218 "logging.channels.c2.class = FileChannel\n"
219 "logging.channels.c2.path = ${system.tempDir}/sample.log\n"
220 "logging.channels.c2.formatter.class = UnknownFormatter\n"
221 "logging.channels.c2.formatter.pattern = %s: {%p} %t\n"
222 "logging.channels.c3.class = ConsoleChannel\n"
223 "logging.channels.c3.pattern = %s: [%p] %t\n"
224 "logging.formatters.f1.class = PatternFormatter\n"
225 "logging.formatters.f1.pattern = %s-[%p] %t\n"
226 "logging.formatters.f1.times = UTC\n";
227
228 std::istringstream istr(config);
229 AutoPtr<PropertyFileConfiguration> pConfig = new PropertyFileConfiguration(istr);
230
231 LoggingConfigurator configurator;
232 try
233 {
234 configurator.configure(pConfig);
235 fail("bad configuration - must throw");
236 }
237 catch (Poco::Exception&)
238 {
239 }
240}
241
242
243void LoggingConfiguratorTest::testBadConfiguration4()
244{
245 // this is mainly testing for memory leaks in case of
246 // a bad configuration.
247
248 static const std::string config =
249 "logging.loggers.root.channel = c1\n"
250 "logging.loggers.root.level = warning\n"
251 "logging.loggers.l1.name = logger1\n"
252 "logging.loggers.l1.channel.class = FileChannel\n"
253 "logging.loggers.l1.channel.pattern = %s: [%p] %t\n"
254 "logging.loggers.l1.channel.path = logfile.log\n"
255 "logging.loggers.l1.level = information\n"
256 "logging.loggers.l2.name = logger2\n"
257 "logging.loggers.l2.channel.class = UnknownChannel\n"
258 "logging.loggers.l2.level = debug\n"
259 "logging.channels.c1.class = ConsoleChannel\n"
260 "logging.channels.c1.formatter = f1\n"
261 "logging.channels.c2.class = FileChannel\n"
262 "logging.channels.c2.path = ${system.tempDir}/sample.log\n"
263 "logging.channels.c2.formatter.class = PatternFormatter\n"
264 "logging.channels.c2.formatter.pattern = %s: {%p} %t\n"
265 "logging.channels.c2.formatter.unknown = FOO\n"
266 "logging.channels.c3.class = ConsoleChannel\n"
267 "logging.channels.c3.pattern = %s: [%p] %t\n"
268 "logging.formatters.f1.class = PatternFormatter\n"
269 "logging.formatters.f1.pattern = %s-[%p] %t\n"
270 "logging.formatters.f1.times = UTC\n";
271
272 std::istringstream istr(config);
273 AutoPtr<PropertyFileConfiguration> pConfig = new PropertyFileConfiguration(istr);
274
275 LoggingConfigurator configurator;
276 try
277 {
278 configurator.configure(pConfig);
279 fail("bad configuration - must throw");
280 }
281 catch (Poco::Exception&)
282 {
283 }
284}
285
286
287void LoggingConfiguratorTest::setUp()
288{
289 LoggingRegistry::defaultRegistry().clear();
290}
291
292
293void LoggingConfiguratorTest::tearDown()
294{
295}
296
297
298CppUnit::Test* LoggingConfiguratorTest::suite()
299{
300 CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("LoggingConfiguratorTest");
301
302 CppUnit_addTest(pSuite, LoggingConfiguratorTest, testConfigurator);
303 CppUnit_addTest(pSuite, LoggingConfiguratorTest, testBadConfiguration1);
304 CppUnit_addTest(pSuite, LoggingConfiguratorTest, testBadConfiguration2);
305 CppUnit_addTest(pSuite, LoggingConfiguratorTest, testBadConfiguration3);
306 CppUnit_addTest(pSuite, LoggingConfiguratorTest, testBadConfiguration4);
307
308 return pSuite;
309}
310