logging_unittest.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. // Copyright (c) 2011 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "butil/basictypes.h"
  5. #include "butil/logging.h"
  6. #include <gtest/gtest.h>
  7. #include <gflags/gflags.h>
  8. #if !BRPC_WITH_GLOG
  9. namespace logging {
  10. DECLARE_bool(crash_on_fatal_log);
  11. DECLARE_int32(v);
  12. namespace {
  13. // Needs to be global since log assert handlers can't maintain state.
  14. int log_sink_call_count = 0;
  15. #if !defined(OFFICIAL_BUILD) || defined(DCHECK_ALWAYS_ON) || !defined(NDEBUG)
  16. void LogSink(const std::string& str) {
  17. ++log_sink_call_count;
  18. }
  19. #endif
  20. // Class to make sure any manipulations we do to the min log level are
  21. // contained (i.e., do not affect other unit tests).
  22. class LogStateSaver {
  23. public:
  24. LogStateSaver() : old_min_log_level_(GetMinLogLevel()) {}
  25. ~LogStateSaver() {
  26. SetMinLogLevel(old_min_log_level_);
  27. SetLogAssertHandler(NULL);
  28. log_sink_call_count = 0;
  29. }
  30. private:
  31. int old_min_log_level_;
  32. DISALLOW_COPY_AND_ASSIGN(LogStateSaver);
  33. };
  34. class LoggingTest : public testing::Test {
  35. public:
  36. virtual void SetUp() {
  37. _old_crash_on_fatal_log = ::logging::FLAGS_crash_on_fatal_log;
  38. ::logging::FLAGS_crash_on_fatal_log = true;
  39. }
  40. virtual void TearDown() {
  41. ::logging::FLAGS_crash_on_fatal_log = _old_crash_on_fatal_log;
  42. if (::logging::FLAGS_v != 0) {
  43. // Clear -verbose to avoid affecting other tests.
  44. ASSERT_FALSE(GFLAGS_NS::SetCommandLineOption("v", "0").empty());
  45. ASSERT_FALSE(GFLAGS_NS::SetCommandLineOption("vmodule", "").empty());
  46. }
  47. }
  48. private:
  49. bool _old_crash_on_fatal_log;
  50. LogStateSaver log_state_saver_;
  51. };
  52. TEST_F(LoggingTest, LogIsOn) {
  53. #if defined(NDEBUG)
  54. const bool kDfatalIsFatal = false;
  55. #else // defined(NDEBUG)
  56. const bool kDfatalIsFatal = true;
  57. #endif // defined(NDEBUG)
  58. SetMinLogLevel(BLOG_INFO);
  59. EXPECT_TRUE(LOG_IS_ON(INFO));
  60. EXPECT_TRUE(LOG_IS_ON(WARNING));
  61. EXPECT_TRUE(LOG_IS_ON(ERROR));
  62. EXPECT_TRUE(LOG_IS_ON(FATAL));
  63. EXPECT_TRUE(LOG_IS_ON(DFATAL));
  64. SetMinLogLevel(BLOG_WARNING);
  65. EXPECT_FALSE(LOG_IS_ON(INFO));
  66. EXPECT_TRUE(LOG_IS_ON(WARNING));
  67. EXPECT_TRUE(LOG_IS_ON(ERROR));
  68. EXPECT_TRUE(LOG_IS_ON(FATAL));
  69. EXPECT_TRUE(LOG_IS_ON(DFATAL));
  70. SetMinLogLevel(BLOG_ERROR);
  71. EXPECT_FALSE(LOG_IS_ON(INFO));
  72. EXPECT_FALSE(LOG_IS_ON(WARNING));
  73. EXPECT_TRUE(LOG_IS_ON(ERROR));
  74. EXPECT_TRUE(LOG_IS_ON(FATAL));
  75. EXPECT_TRUE(LOG_IS_ON(DFATAL));
  76. // LOG_IS_ON(FATAL) should always be true.
  77. SetMinLogLevel(BLOG_FATAL + 1);
  78. EXPECT_FALSE(LOG_IS_ON(INFO));
  79. EXPECT_FALSE(LOG_IS_ON(WARNING));
  80. EXPECT_FALSE(LOG_IS_ON(ERROR));
  81. EXPECT_TRUE(LOG_IS_ON(FATAL));
  82. EXPECT_TRUE(kDfatalIsFatal == LOG_IS_ON(DFATAL));
  83. }
  84. TEST_F(LoggingTest, DebugLoggingReleaseBehavior) {
  85. #if !defined(NDEBUG)
  86. int debug_only_variable = 1;
  87. #endif
  88. // These should avoid emitting references to |debug_only_variable|
  89. // in release mode.
  90. DLOG_IF(INFO, debug_only_variable) << "test";
  91. DLOG_ASSERT(debug_only_variable) << "test";
  92. DPLOG_IF(INFO, debug_only_variable) << "test";
  93. DVLOG_IF(1, debug_only_variable) << "test";
  94. }
  95. TEST_F(LoggingTest, Dcheck) {
  96. #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
  97. // Release build.
  98. EXPECT_FALSE(DCHECK_IS_ON());
  99. EXPECT_FALSE(DLOG_IS_ON(DCHECK));
  100. #elif defined(NDEBUG) && defined(DCHECK_ALWAYS_ON)
  101. // Release build with real DCHECKS.
  102. SetLogAssertHandler(&LogSink);
  103. EXPECT_TRUE(DCHECK_IS_ON());
  104. EXPECT_FALSE(DLOG_IS_ON(DCHECK));
  105. #else
  106. // Debug build.
  107. SetLogAssertHandler(&LogSink);
  108. EXPECT_TRUE(DCHECK_IS_ON());
  109. EXPECT_TRUE(DLOG_IS_ON(DCHECK));
  110. #endif
  111. EXPECT_EQ(0, log_sink_call_count);
  112. DCHECK(false);
  113. EXPECT_EQ(DCHECK_IS_ON() ? 1 : 0, log_sink_call_count);
  114. DPCHECK(false);
  115. EXPECT_EQ(DCHECK_IS_ON() ? 2 : 0, log_sink_call_count);
  116. DCHECK_EQ(0, 1);
  117. EXPECT_EQ(DCHECK_IS_ON() ? 3 : 0, log_sink_call_count);
  118. }
  119. TEST_F(LoggingTest, DcheckReleaseBehavior) {
  120. int some_variable = 1;
  121. // These should still reference |some_variable| so we don't get
  122. // unused variable warnings.
  123. DCHECK(some_variable) << "test";
  124. DPCHECK(some_variable) << "test";
  125. DCHECK_EQ(some_variable, 1) << "test";
  126. }
  127. TEST_F(LoggingTest, streaming_log_sanity) {
  128. ::logging::FLAGS_crash_on_fatal_log = false;
  129. LOG(WARNING) << 1 << 1.1f << 2l << "apple" << noflush;
  130. LOG(WARNING) << " orange" << noflush;
  131. ASSERT_EQ("11.12apple orange", LOG_STREAM(WARNING).content_str());
  132. ASSERT_EQ("", LOG_STREAM(WARNING).content_str());
  133. LOG(FATAL) << 1 << 1.1f << 2l << "apple" << noflush;
  134. LOG(FATAL) << " orange" << noflush;
  135. ASSERT_EQ("11.12apple orange", LOG_STREAM(FATAL).content_str());
  136. ASSERT_EQ("", LOG_STREAM(FATAL).content_str());
  137. LOG(TRACE) << 1 << 1.1f << 2l << "apple" << noflush;
  138. LOG(TRACE) << " orange" << noflush;
  139. ASSERT_EQ("11.12apple orange", LOG_STREAM(TRACE).content_str());
  140. ASSERT_EQ("", LOG_STREAM(TRACE).content_str());
  141. LOG(NOTICE) << 1 << 1.1f << 2l << "apple" << noflush;
  142. LOG(DEBUG) << 1 << 1.1f << 2l << "apple" << noflush;
  143. LOG(FATAL) << 1 << 1.1f << 2l << "apple";
  144. LOG(ERROR) << 1 << 1.1f << 2l << "apple";
  145. LOG(WARNING) << 1 << 1.1f << 2l << "apple";
  146. LOG(INFO) << 1 << 1.1f << 2l << "apple";
  147. LOG(TRACE) << 1 << 1.1f << 2l << "apple";
  148. LOG(NOTICE) << 2 << 2.2f << 3l << "orange" << noflush;
  149. ASSERT_EQ("11.12apple22.23orange", LOG_STREAM(NOTICE).content_str());
  150. LOG(DEBUG) << 1 << 1.1f << 2l << "apple";
  151. errno = EINVAL;
  152. PLOG(FATAL) << "Error occurred" << noflush;
  153. ASSERT_EQ("Error occurred: Invalid argument", PLOG_STREAM(FATAL).content_str());
  154. errno = 0;
  155. PLOG(FATAL) << "Error occurred" << noflush;
  156. #if defined(OS_LINUX)
  157. ASSERT_EQ("Error occurred: Success", PLOG_STREAM(FATAL).content_str());
  158. #else
  159. ASSERT_EQ("Error occurred: Undefined error: 0", PLOG_STREAM(FATAL).content_str());
  160. #endif
  161. errno = EINTR;
  162. PLOG(FATAL) << "Error occurred" << noflush;
  163. ASSERT_EQ("Error occurred: Interrupted system call",
  164. PLOG_STREAM(FATAL).content_str());
  165. }
  166. TEST_F(LoggingTest, log_at) {
  167. ::logging::StringSink log_str;
  168. ::logging::LogSink* old_sink = ::logging::SetLogSink(&log_str);
  169. LOG_AT(WARNING, "specified_file.cc", 12345) << "file/line is specified";
  170. // the file:line part should be using the argument given by us.
  171. ASSERT_NE(std::string::npos, log_str.find("specified_file.cc:12345"));
  172. // restore the old sink.
  173. ::logging::SetLogSink(old_sink);
  174. }
  175. #define VLOG_NE(verbose_level) VLOG(verbose_level) << noflush
  176. #define VLOG2_NE(virtual_path, verbose_level) \
  177. VLOG2(virtual_path, verbose_level) << noflush
  178. TEST_F(LoggingTest, vlog_sanity) {
  179. ::logging::FLAGS_crash_on_fatal_log = false;
  180. EXPECT_FALSE(GFLAGS_NS::SetCommandLineOption("v", "1").empty());
  181. EXPECT_FALSE(GFLAGS_NS::SetCommandLineOption("vmodule",
  182. "logging_unittest=1").empty());
  183. EXPECT_FALSE(GFLAGS_NS::SetCommandLineOption("vmodule",
  184. "logging_UNITTEST=2").empty());
  185. for (int i = 0; i < 10; ++i) {
  186. VLOG_NE(i) << "vlog " << i;
  187. }
  188. EXPECT_EQ("vlog 1vlog 2", LOG_STREAM(VERBOSE).content_str());
  189. EXPECT_EQ("vlog 0", LOG_STREAM(INFO).content_str());
  190. VLOG_NE(-1) << "nothing";
  191. EXPECT_EQ("", LOG_STREAM(VERBOSE).content_str());
  192. // VLOG(0) is LOG(INFO)
  193. VLOG_NE(0) << "always on";
  194. EXPECT_EQ("always on", LOG_STREAM(INFO).content_str());
  195. EXPECT_FALSE(GFLAGS_NS::SetCommandLineOption("vmodule",
  196. "logging_unittest=0").empty());
  197. for (int i = 0; i < 10; ++i) {
  198. VLOG_NE(i) << "vlog " << i;
  199. }
  200. EXPECT_EQ("", LOG_STREAM(VERBOSE).content_str());
  201. EXPECT_EQ("vlog 0", LOG_STREAM(INFO).content_str());
  202. EXPECT_FALSE(GFLAGS_NS::SetCommandLineOption("vmodule",
  203. "logging_unittest=0,logging_unittest=1").empty());
  204. for (int i = 0; i < 10; ++i) {
  205. VLOG_NE(i) << "vlog " << i;
  206. }
  207. EXPECT_EQ("vlog 1", LOG_STREAM(VERBOSE).content_str());
  208. EXPECT_EQ("vlog 0", LOG_STREAM(INFO).content_str());
  209. EXPECT_FALSE(GFLAGS_NS::SetCommandLineOption("vmodule",
  210. "logging_unittest=1,logging_unittest=0").empty());
  211. for (int i = 0; i < 10; ++i) {
  212. VLOG_NE(i) << "vlog " << i;
  213. }
  214. EXPECT_EQ("", LOG_STREAM(VERBOSE).content_str());
  215. EXPECT_EQ("vlog 0", LOG_STREAM(INFO).content_str());
  216. EXPECT_FALSE(GFLAGS_NS::SetCommandLineOption("vmodule", "").empty());
  217. for (int i = 0; i < 10; ++i) {
  218. VLOG_NE(i) << "vlog " << i;
  219. }
  220. EXPECT_EQ("vlog 1", LOG_STREAM(VERBOSE).content_str());
  221. EXPECT_EQ("vlog 0", LOG_STREAM(INFO).content_str());
  222. EXPECT_FALSE(GFLAGS_NS::SetCommandLineOption("vmodule",
  223. "logg?ng_*=2").empty());
  224. for (int i = 0; i < 10; ++i) {
  225. VLOG_NE(i) << "vlog " << i;
  226. }
  227. EXPECT_EQ("vlog 1vlog 2", LOG_STREAM(VERBOSE).content_str());
  228. EXPECT_EQ("vlog 0", LOG_STREAM(INFO).content_str());
  229. EXPECT_FALSE(GFLAGS_NS::SetCommandLineOption("vmodule",
  230. "foo=3,logging_unittest=3, logg?ng_*=2 , logging_*=1 ").empty());
  231. for (int i = 0; i < 10; ++i) {
  232. VLOG_NE(i) << "vlog " << i;
  233. }
  234. EXPECT_EQ("vlog 1vlog 2vlog 3", LOG_STREAM(VERBOSE).content_str());
  235. EXPECT_EQ("vlog 0", LOG_STREAM(INFO).content_str());
  236. for (int i = 0; i < 10; ++i) {
  237. VLOG_IF(i, i % 2 == 1) << "vlog " << i << noflush;
  238. }
  239. EXPECT_EQ("vlog 1vlog 3", LOG_STREAM(VERBOSE).content_str());
  240. EXPECT_FALSE(GFLAGS_NS::SetCommandLineOption(
  241. "vmodule",
  242. "foo/bar0/0=2,foo/bar/1=3, 2=4, foo/*/3=5, */ba?/4=6,"
  243. "/5=7,/foo/bar/6=8,foo2/bar/7=9,foo/bar/8=9").empty());
  244. VLOG2_NE("foo/bar/0", 2) << " vlog0";
  245. VLOG2_NE("foo/bar0/0", 2) << " vlog0.0";
  246. VLOG2_NE("foo/bar/1", 3) << " vlog1";
  247. VLOG2_NE("foo/bar/2", 4) << " vlog2";
  248. VLOG2_NE("foo/bar2/2", 4) << " vlog2.2";
  249. VLOG2_NE("foo/bar/3", 5) << " vlog3";
  250. VLOG2_NE("foo/bar/4", 6) << " vlog4";
  251. VLOG2_NE("foo/bar/5", 7) << " vlog5";
  252. VLOG2_NE("foo/bar/6", 8) << " vlog6";
  253. VLOG2_NE("foo/bar/7", 9) << " vlog7";
  254. VLOG2_NE("foo/bar/8", 10) << " vlog8";
  255. VLOG2_NE("foo/bar/9", 11) << " vlog9";
  256. EXPECT_EQ(" vlog0.0 vlog1 vlog2 vlog2.2 vlog3 vlog4",
  257. LOG_STREAM(VERBOSE).content_str());
  258. // Make sure verbose log is not flushed to other levels.
  259. ASSERT_TRUE(LOG_STREAM(FATAL).content_str().empty());
  260. ASSERT_TRUE(LOG_STREAM(ERROR).content_str().empty());
  261. ASSERT_TRUE(LOG_STREAM(WARNING).content_str().empty());
  262. ASSERT_TRUE(LOG_STREAM(NOTICE).content_str().empty());
  263. ASSERT_TRUE(LOG_STREAM(INFO).content_str().empty());
  264. }
  265. TEST_F(LoggingTest, check) {
  266. ::logging::FLAGS_crash_on_fatal_log = false;
  267. CHECK(1 < 2);
  268. CHECK(1 > 2);
  269. int a = 1;
  270. int b = 2;
  271. CHECK(a > b) << "bad! a=" << a << " b=" << b;
  272. CHECK_EQ(a, b) << "a=" << a << " b=" << b;
  273. CHECK_EQ(1, 1) << "a=" << a << " b=" << b;
  274. CHECK_NE(2, 1);
  275. CHECK_NE(1, 2) << "blah0";
  276. CHECK_NE(2, 2) << "blah1";
  277. CHECK_LT(2, 3);
  278. CHECK_LT(3, 2) << "blah2";
  279. CHECK_LT(3, 3) << "blah3";
  280. CHECK_LE(2, 3);
  281. CHECK_LE(3, 2) << "blah4";
  282. CHECK_LE(3, 3);
  283. CHECK_GT(3, 2);
  284. CHECK_GT(1, 2) << "1 can't be greater than 2";
  285. CHECK_GT(3, 3) << "blah5";
  286. CHECK_GE(3, 2);
  287. CHECK_GE(2, 3) << "blah6";
  288. CHECK_GE(3, 3);
  289. }
  290. int foo(int* p) {
  291. return ++*p;
  292. }
  293. TEST_F(LoggingTest, debug_level) {
  294. ::logging::FLAGS_crash_on_fatal_log = false;
  295. int run_foo = 0;
  296. LOG(DEBUG) << foo(&run_foo) << noflush;
  297. LOG(DEBUG) << foo(&run_foo);
  298. DLOG(FATAL) << foo(&run_foo);
  299. DLOG(WARNING) << foo(&run_foo);
  300. DLOG(TRACE) << foo(&run_foo);
  301. DLOG(NOTICE) << foo(&run_foo);
  302. DLOG(DEBUG) << foo(&run_foo);
  303. EXPECT_FALSE(GFLAGS_NS::SetCommandLineOption("vmodule", "").empty());
  304. EXPECT_FALSE(GFLAGS_NS::SetCommandLineOption("v", "1").empty());
  305. DVLOG(1) << foo(&run_foo);
  306. DVLOG2("a/b/c", 1) << foo(&run_foo);
  307. #ifdef NDEBUG
  308. ASSERT_EQ(0, run_foo);
  309. #else
  310. ASSERT_EQ(9, run_foo);
  311. #endif
  312. }
  313. static void need_ostream(std::ostream& os, const char* s) {
  314. os << s;
  315. }
  316. TEST_F(LoggingTest, as_ostream) {
  317. ::logging::FLAGS_crash_on_fatal_log = false;
  318. need_ostream(LOG_STREAM(WARNING) << noflush, "hello");
  319. ASSERT_EQ("hello", LOG_STREAM(WARNING).content_str());
  320. need_ostream(LOG_STREAM(WARNING), "hello");
  321. ASSERT_EQ("", LOG_STREAM(WARNING).content_str());
  322. need_ostream(LOG_STREAM(INFO) << noflush, "world");
  323. ASSERT_EQ("world", LOG_STREAM(INFO).content_str());
  324. need_ostream(LOG_STREAM(INFO), "world");
  325. ASSERT_EQ("", LOG_STREAM(INFO).content_str());
  326. LOG(WARNING) << 1.123456789;
  327. const std::streamsize saved_prec = LOG_STREAM(WARNING).precision(2);
  328. LOG(WARNING) << 1.123456789;
  329. LOG_STREAM(WARNING).precision(saved_prec);
  330. LOG(WARNING) << 1.123456789;
  331. }
  332. TEST_F(LoggingTest, limited_logging) {
  333. for (int i = 0; i < 100000; ++i) {
  334. LOG_ONCE(INFO) << "HEHE1";
  335. LOG_ONCE(INFO) << "HEHE2";
  336. VLOG_ONCE(1) << "VHEHE3";
  337. VLOG_ONCE(1) << "VHEHE4";
  338. LOG_EVERY_N(INFO, 10000) << "i1=" << i;
  339. LOG_EVERY_N(INFO, 5000) << "i2=" << i;
  340. VLOG_EVERY_N(1, 10000) << "vi3=" << i;
  341. VLOG_EVERY_N(1, 5000) << "vi4=" << i;
  342. }
  343. for (int i = 0; i < 300; ++i) {
  344. LOG_EVERY_SECOND(INFO) << "i1=" << i;
  345. LOG_EVERY_SECOND(INFO) << "i2=" << i;
  346. VLOG_EVERY_SECOND(1) << "vi3=" << i;
  347. VLOG_EVERY_SECOND(1) << "vi4=" << i;
  348. usleep(10000);
  349. }
  350. }
  351. } // namespace
  352. } // namespace logging
  353. #endif