logger_unittest.cc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. // Copyright (C) 2011, 2014, 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 <config.h>
  15. #include <gtest/gtest.h>
  16. #include <util/unittests/resource.h>
  17. #include <util/unittests/check_valgrind.h>
  18. #include <log/logger.h>
  19. #include <log/logger_manager.h>
  20. #include <log/logger_name.h>
  21. #include <log/log_messages.h>
  22. #include <log/interprocess/interprocess_sync_file.h>
  23. #include <log/tests/log_test_messages.h>
  24. #include <iostream>
  25. #include <string>
  26. using namespace isc;
  27. using namespace isc::log;
  28. using namespace std;
  29. /// \brief Logger Test
  30. ///
  31. /// As the logger is only a shell around the implementation, this tests also
  32. /// checks the logger implementation class as well.
  33. class LoggerTest : public ::testing::Test {
  34. public:
  35. LoggerTest() {
  36. // Initialization of logging is done in main()
  37. }
  38. ~LoggerTest() {
  39. LoggerManager::reset();
  40. }
  41. };
  42. // Check version
  43. TEST_F(LoggerTest, Version) {
  44. EXPECT_NO_THROW(Logger::getVersion());
  45. }
  46. // Checks that the logger is named correctly.
  47. TEST_F(LoggerTest, Name) {
  48. // Create a logger
  49. Logger logger("alpha");
  50. // ... and check the name
  51. EXPECT_EQ(getRootLoggerName() + string(".alpha"), logger.getName());
  52. }
  53. // This test attempts to get two instances of a logger with the same name
  54. // and checks that they are in fact the same logger.
  55. TEST_F(LoggerTest, GetLogger) {
  56. const char* name1 = "alpha";
  57. const char* name2 = "beta";
  58. // Instantiate two loggers that should be the same
  59. Logger logger1(name1);
  60. Logger logger2(name1);
  61. // And check they equal
  62. EXPECT_TRUE(logger1 == logger2);
  63. // Instantiate another logger with another name and check that it
  64. // is different to the previously instantiated ones.
  65. Logger logger3(name2);
  66. EXPECT_FALSE(logger1 == logger3);
  67. }
  68. // Check that the logger levels are get set properly.
  69. TEST_F(LoggerTest, Severity) {
  70. // Create a logger
  71. Logger logger("alpha");
  72. // Now check the levels
  73. logger.setSeverity(isc::log::NONE);
  74. EXPECT_EQ(isc::log::NONE, logger.getSeverity());
  75. logger.setSeverity(isc::log::FATAL);
  76. EXPECT_EQ(isc::log::FATAL, logger.getSeverity());
  77. logger.setSeverity(isc::log::ERROR);
  78. EXPECT_EQ(isc::log::ERROR, logger.getSeverity());
  79. logger.setSeverity(isc::log::WARN);
  80. EXPECT_EQ(isc::log::WARN, logger.getSeverity());
  81. logger.setSeverity(isc::log::INFO);
  82. EXPECT_EQ(isc::log::INFO, logger.getSeverity());
  83. logger.setSeverity(isc::log::DEBUG);
  84. EXPECT_EQ(isc::log::DEBUG, logger.getSeverity());
  85. logger.setSeverity(isc::log::DEFAULT);
  86. EXPECT_EQ(isc::log::DEFAULT, logger.getSeverity());
  87. }
  88. // Check that the debug level is set correctly.
  89. TEST_F(LoggerTest, DebugLevels) {
  90. // Create a logger
  91. Logger logger("alpha");
  92. // Debug level should be 0 if not at debug severity
  93. logger.setSeverity(isc::log::NONE, 20);
  94. EXPECT_EQ(0, logger.getDebugLevel());
  95. logger.setSeverity(isc::log::INFO, 42);
  96. EXPECT_EQ(0, logger.getDebugLevel());
  97. // Should be the value set if the severity is set to DEBUG though.
  98. logger.setSeverity(isc::log::DEBUG, 32);
  99. EXPECT_EQ(32, logger.getDebugLevel());
  100. logger.setSeverity(isc::log::DEBUG, 97);
  101. EXPECT_EQ(97, logger.getDebugLevel());
  102. // Try the limits
  103. logger.setSeverity(isc::log::DEBUG, -1);
  104. EXPECT_EQ(0, logger.getDebugLevel());
  105. logger.setSeverity(isc::log::DEBUG, 0);
  106. EXPECT_EQ(0, logger.getDebugLevel());
  107. logger.setSeverity(isc::log::DEBUG, 1);
  108. EXPECT_EQ(1, logger.getDebugLevel());
  109. logger.setSeverity(isc::log::DEBUG, 98);
  110. EXPECT_EQ(98, logger.getDebugLevel());
  111. logger.setSeverity(isc::log::DEBUG, 99);
  112. EXPECT_EQ(99, logger.getDebugLevel());
  113. logger.setSeverity(isc::log::DEBUG, 100);
  114. EXPECT_EQ(99, logger.getDebugLevel());
  115. }
  116. // Check that changing the parent and child severity does not affect the
  117. // other.
  118. TEST_F(LoggerTest, SeverityInheritance) {
  119. // Create two loggers. We cheat here as we know that the underlying
  120. // implementation will set a parent-child relationship if the loggers
  121. // are named <parent> and <parent>.<child>.
  122. Logger parent("alpha");
  123. Logger child("alpha.beta");
  124. // By default, newly created loggers should have a level of DEFAULT
  125. // (i.e. default to parent)
  126. EXPECT_EQ(isc::log::DEFAULT, parent.getSeverity());
  127. EXPECT_EQ(isc::log::DEFAULT, child.getSeverity());
  128. // Set the severity of the parent to debug and check what is
  129. // reported by the child.
  130. parent.setSeverity(isc::log::DEBUG, 42);
  131. EXPECT_EQ(42, parent.getDebugLevel());
  132. EXPECT_EQ(0, child.getDebugLevel());
  133. EXPECT_EQ(42, child.getEffectiveDebugLevel());
  134. // Setting the child to DEBUG severity should set its own
  135. // debug level.
  136. child.setSeverity(isc::log::DEBUG, 53);
  137. EXPECT_EQ(53, child.getDebugLevel());
  138. EXPECT_EQ(53, child.getEffectiveDebugLevel());
  139. // If the child severity is set to something other than DEBUG,
  140. // the debug level should be reported as 0.
  141. child.setSeverity(isc::log::ERROR);
  142. EXPECT_EQ(0, child.getDebugLevel());
  143. EXPECT_EQ(0, child.getEffectiveDebugLevel());
  144. }
  145. // Check that changing the parent and child debug level does not affect
  146. // the other.
  147. TEST_F(LoggerTest, DebugLevelInheritance) {
  148. // Create two loggers. We cheat here as we know that the underlying
  149. // implementation will set a parent-child relationship if the loggers
  150. // are named <parent> and <parent>.<child>.
  151. Logger parent("alpha");
  152. Logger child("alpha.beta");
  153. // By default, newly created loggers should have a level of DEFAULT
  154. // (i.e. default to parent)
  155. EXPECT_EQ(isc::log::DEFAULT, parent.getSeverity());
  156. EXPECT_EQ(isc::log::DEFAULT, child.getSeverity());
  157. // Set the severity of the child to something other than the default -
  158. // check it changes and that of the parent does not.
  159. child.setSeverity(isc::log::INFO);
  160. EXPECT_EQ(isc::log::DEFAULT, parent.getSeverity());
  161. EXPECT_EQ(isc::log::INFO, child.getSeverity());
  162. // Reset the child severity and set that of the parent
  163. child.setSeverity(isc::log::DEFAULT);
  164. EXPECT_EQ(isc::log::DEFAULT, parent.getSeverity());
  165. EXPECT_EQ(isc::log::DEFAULT, child.getSeverity());
  166. parent.setSeverity(isc::log::WARN);
  167. EXPECT_EQ(isc::log::WARN, parent.getSeverity());
  168. EXPECT_EQ(isc::log::DEFAULT, child.getSeverity());
  169. }
  170. // Check that severity is inherited.
  171. TEST_F(LoggerTest, EffectiveSeverityInheritance) {
  172. // Create two loggers. We cheat here as we know that the underlying
  173. // implementation will set a parent-child relationship if the loggers
  174. // are named <parent> and <parent>.<child>.
  175. Logger parent("test6");
  176. Logger child("test6.beta");
  177. // By default, newly created loggers should have a level of DEFAULT
  178. // (i.e. default to parent) and the root should have a default severity
  179. // of INFO. However, the latter is only enforced when created by the
  180. // RootLogger class, so explicitly set it for the parent for now.
  181. parent.setSeverity(isc::log::INFO);
  182. EXPECT_EQ(isc::log::INFO, parent.getEffectiveSeverity());
  183. EXPECT_EQ(isc::log::DEFAULT, child.getSeverity());
  184. EXPECT_EQ(isc::log::INFO, child.getEffectiveSeverity());
  185. // Set the severity of the child to something other than the default -
  186. // check it changes and that of the parent does not.
  187. child.setSeverity(isc::log::FATAL);
  188. EXPECT_EQ(isc::log::INFO, parent.getEffectiveSeverity());
  189. EXPECT_EQ(isc::log::FATAL, child.getEffectiveSeverity());
  190. // Reset the child severity and check again.
  191. child.setSeverity(isc::log::DEFAULT);
  192. EXPECT_EQ(isc::log::INFO, parent.getEffectiveSeverity());
  193. EXPECT_EQ(isc::log::INFO, child.getEffectiveSeverity());
  194. // Change the parent's severity and check it is reflects in the child.
  195. parent.setSeverity(isc::log::WARN);
  196. EXPECT_EQ(isc::log::WARN, parent.getEffectiveSeverity());
  197. EXPECT_EQ(isc::log::WARN, child.getEffectiveSeverity());
  198. }
  199. // Test the isXxxxEnabled methods.
  200. TEST_F(LoggerTest, IsXxxEnabled) {
  201. Logger logger("test7");
  202. logger.setSeverity(isc::log::INFO);
  203. EXPECT_FALSE(logger.isDebugEnabled());
  204. EXPECT_TRUE(logger.isInfoEnabled());
  205. EXPECT_TRUE(logger.isWarnEnabled());
  206. EXPECT_TRUE(logger.isErrorEnabled());
  207. EXPECT_TRUE(logger.isFatalEnabled());
  208. logger.setSeverity(isc::log::WARN);
  209. EXPECT_FALSE(logger.isDebugEnabled());
  210. EXPECT_FALSE(logger.isInfoEnabled());
  211. EXPECT_TRUE(logger.isWarnEnabled());
  212. EXPECT_TRUE(logger.isErrorEnabled());
  213. EXPECT_TRUE(logger.isFatalEnabled());
  214. logger.setSeverity(isc::log::ERROR);
  215. EXPECT_FALSE(logger.isDebugEnabled());
  216. EXPECT_FALSE(logger.isInfoEnabled());
  217. EXPECT_FALSE(logger.isWarnEnabled());
  218. EXPECT_TRUE(logger.isErrorEnabled());
  219. EXPECT_TRUE(logger.isFatalEnabled());
  220. logger.setSeverity(isc::log::FATAL);
  221. EXPECT_FALSE(logger.isDebugEnabled());
  222. EXPECT_FALSE(logger.isInfoEnabled());
  223. EXPECT_FALSE(logger.isWarnEnabled());
  224. EXPECT_FALSE(logger.isErrorEnabled());
  225. EXPECT_TRUE(logger.isFatalEnabled());
  226. // Check various debug levels
  227. logger.setSeverity(isc::log::DEBUG);
  228. EXPECT_TRUE(logger.isDebugEnabled());
  229. EXPECT_TRUE(logger.isInfoEnabled());
  230. EXPECT_TRUE(logger.isWarnEnabled());
  231. EXPECT_TRUE(logger.isErrorEnabled());
  232. EXPECT_TRUE(logger.isFatalEnabled());
  233. logger.setSeverity(isc::log::DEBUG, 45);
  234. EXPECT_TRUE(logger.isDebugEnabled());
  235. EXPECT_TRUE(logger.isInfoEnabled());
  236. EXPECT_TRUE(logger.isWarnEnabled());
  237. EXPECT_TRUE(logger.isErrorEnabled());
  238. EXPECT_TRUE(logger.isFatalEnabled());
  239. // Create a child logger with no severity set, and check that it reflects
  240. // the severity of the parent logger.
  241. Logger child("test7.child");
  242. logger.setSeverity(isc::log::FATAL);
  243. EXPECT_FALSE(child.isDebugEnabled());
  244. EXPECT_FALSE(child.isInfoEnabled());
  245. EXPECT_FALSE(child.isWarnEnabled());
  246. EXPECT_FALSE(child.isErrorEnabled());
  247. EXPECT_TRUE(child.isFatalEnabled());
  248. logger.setSeverity(isc::log::INFO);
  249. EXPECT_FALSE(child.isDebugEnabled());
  250. EXPECT_TRUE(child.isInfoEnabled());
  251. EXPECT_TRUE(child.isWarnEnabled());
  252. EXPECT_TRUE(child.isErrorEnabled());
  253. EXPECT_TRUE(child.isFatalEnabled());
  254. }
  255. // Within the Debug level there are 100 debug levels. Test that we know
  256. // when to issue a debug message.
  257. TEST_F(LoggerTest, IsDebugEnabledLevel) {
  258. Logger logger("test8");
  259. int MID_LEVEL = (MIN_DEBUG_LEVEL + MAX_DEBUG_LEVEL) / 2;
  260. logger.setSeverity(isc::log::DEBUG);
  261. EXPECT_TRUE(logger.isDebugEnabled(MIN_DEBUG_LEVEL));
  262. EXPECT_FALSE(logger.isDebugEnabled(MID_LEVEL));
  263. EXPECT_FALSE(logger.isDebugEnabled(MAX_DEBUG_LEVEL));
  264. logger.setSeverity(isc::log::DEBUG, MIN_DEBUG_LEVEL);
  265. EXPECT_TRUE(logger.isDebugEnabled(MIN_DEBUG_LEVEL));
  266. EXPECT_FALSE(logger.isDebugEnabled(MID_LEVEL));
  267. EXPECT_FALSE(logger.isDebugEnabled(MAX_DEBUG_LEVEL));
  268. logger.setSeverity(isc::log::DEBUG, MID_LEVEL);
  269. EXPECT_TRUE(logger.isDebugEnabled(MIN_DEBUG_LEVEL));
  270. EXPECT_TRUE(logger.isDebugEnabled(MID_LEVEL - 1));
  271. EXPECT_TRUE(logger.isDebugEnabled(MID_LEVEL));
  272. EXPECT_FALSE(logger.isDebugEnabled(MID_LEVEL + 1));
  273. EXPECT_FALSE(logger.isDebugEnabled(MAX_DEBUG_LEVEL));
  274. logger.setSeverity(isc::log::DEBUG, MAX_DEBUG_LEVEL);
  275. EXPECT_TRUE(logger.isDebugEnabled(MIN_DEBUG_LEVEL));
  276. EXPECT_TRUE(logger.isDebugEnabled(MID_LEVEL));
  277. EXPECT_TRUE(logger.isDebugEnabled(MAX_DEBUG_LEVEL));
  278. }
  279. // Check that loggers with invalid names give an error.
  280. TEST_F(LoggerTest, LoggerNameLength) {
  281. // Null name
  282. EXPECT_THROW(Logger(NULL), LoggerNameNull);
  283. // Declare space for the logger name. The length of names checked
  284. // will range from 0 through MAX_LOGGER_NAME_SIZE + 1: to allow for
  285. // the trailing null, at least one more byte than the longest name size
  286. // must be reserved.
  287. char name[Logger::MAX_LOGGER_NAME_SIZE + 2];
  288. // Zero-length name should throw an exception
  289. name[0] = '\0';
  290. EXPECT_THROW({
  291. Logger dummy(name);
  292. }, LoggerNameError);
  293. // Work through all valid names.
  294. for (size_t i = 0; i < Logger::MAX_LOGGER_NAME_SIZE; ++i) {
  295. // Append a character to the name and check that a logger with that
  296. // name can be created without throwing an exception.
  297. name[i] = 'X';
  298. name[i + 1] = '\0';
  299. EXPECT_NO_THROW({
  300. Logger dummy(name);
  301. }) << "Size of logger name is " << (i + 1);
  302. }
  303. // ... and check that an overly long name throws an exception.
  304. name[Logger::MAX_LOGGER_NAME_SIZE] = 'X';
  305. name[Logger::MAX_LOGGER_NAME_SIZE + 1] = '\0';
  306. EXPECT_THROW({
  307. Logger dummy(name);
  308. }, LoggerNameError);
  309. }
  310. TEST_F(LoggerTest, setInterprocessSync) {
  311. // Create a logger
  312. Logger logger("alpha");
  313. EXPECT_THROW(logger.setInterprocessSync(NULL), BadInterprocessSync);
  314. }
  315. class MockSync : public isc::log::interprocess::InterprocessSync {
  316. public:
  317. /// \brief Constructor
  318. MockSync(const std::string& component_name) :
  319. InterprocessSync(component_name), was_locked_(false),
  320. was_unlocked_(false)
  321. {}
  322. bool wasLocked() const {
  323. return (was_locked_);
  324. }
  325. bool wasUnlocked() const {
  326. return (was_unlocked_);
  327. }
  328. protected:
  329. bool lock() {
  330. was_locked_ = true;
  331. return (true);
  332. }
  333. bool tryLock() {
  334. return (true);
  335. }
  336. bool unlock() {
  337. was_unlocked_ = true;
  338. return (true);
  339. }
  340. private:
  341. bool was_locked_;
  342. bool was_unlocked_;
  343. };
  344. // Checks that the logger logs exclusively and other Kea components
  345. // are locked out.
  346. TEST_F(LoggerTest, Lock) {
  347. // Create a logger
  348. Logger logger("alpha");
  349. // Setup our own mock sync object so that we can intercept the lock
  350. // call and check if a lock has been taken.
  351. MockSync* sync = new MockSync("logger");
  352. logger.setInterprocessSync(sync);
  353. // Log a message and put things into play.
  354. logger.setSeverity(isc::log::INFO, 100);
  355. logger.info(LOG_LOCK_TEST_MESSAGE);
  356. EXPECT_TRUE(sync->wasLocked());
  357. EXPECT_TRUE(sync->wasUnlocked());
  358. }