| 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 | |
| 31 | using Poco::Util::LoggingConfigurator; |
| 32 | using Poco::Util::PropertyFileConfiguration; |
| 33 | using Poco::LoggingRegistry; |
| 34 | using Poco::Channel; |
| 35 | using Poco::ConsoleChannel; |
| 36 | using Poco::FileChannel; |
| 37 | using Poco::SplitterChannel; |
| 38 | using Poco::FormattingChannel; |
| 39 | using Poco::PatternFormatter; |
| 40 | using Poco::Logger; |
| 41 | using Poco::Message; |
| 42 | using Poco::AutoPtr; |
| 43 | |
| 44 | |
| 45 | LoggingConfiguratorTest::LoggingConfiguratorTest(const std::string& name): CppUnit::TestCase(name) |
| 46 | { |
| 47 | } |
| 48 | |
| 49 | |
| 50 | LoggingConfiguratorTest::~LoggingConfiguratorTest() |
| 51 | { |
| 52 | } |
| 53 | |
| 54 | |
| 55 | void 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 | |
| 114 | void 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 | |
| 157 | void 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 | |
| 200 | void 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 | |
| 243 | void 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 | |
| 287 | void LoggingConfiguratorTest::setUp() |
| 288 | { |
| 289 | LoggingRegistry::defaultRegistry().clear(); |
| 290 | } |
| 291 | |
| 292 | |
| 293 | void LoggingConfiguratorTest::tearDown() |
| 294 | { |
| 295 | } |
| 296 | |
| 297 | |
| 298 | CppUnit::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 | |