logging_unittest.cc 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218
  1. // Copyright (c) 2002, Google Inc.
  2. // All rights reserved.
  3. //
  4. // Redistribution and use in source and binary forms, with or without
  5. // modification, are permitted provided that the following conditions are
  6. // met:
  7. //
  8. // * Redistributions of source code must retain the above copyright
  9. // notice, this list of conditions and the following disclaimer.
  10. // * Redistributions in binary form must reproduce the above
  11. // copyright notice, this list of conditions and the following disclaimer
  12. // in the documentation and/or other materials provided with the
  13. // distribution.
  14. // * Neither the name of Google Inc. nor the names of its
  15. // contributors may be used to endorse or promote products derived from
  16. // this software without specific prior written permission.
  17. //
  18. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. //
  30. // Author: Ray Sidney
  31. #include "config_for_unittests.h"
  32. #include "utilities.h"
  33. #include <fcntl.h>
  34. #ifdef HAVE_GLOB_H
  35. # include <glob.h>
  36. #endif
  37. #include <sys/stat.h>
  38. #ifdef HAVE_UNISTD_H
  39. # include <unistd.h>
  40. #endif
  41. #include <iomanip>
  42. #include <iostream>
  43. #include <memory>
  44. #include <queue>
  45. #include <sstream>
  46. #include <string>
  47. #include <vector>
  48. #include <stdio.h>
  49. #include <stdlib.h>
  50. #include "base/commandlineflags.h"
  51. #include "glog/logging.h"
  52. #include "glog/raw_logging.h"
  53. #include "googletest.h"
  54. DECLARE_string(log_backtrace_at); // logging.cc
  55. #ifdef HAVE_LIB_GFLAGS
  56. #include <gflags/gflags.h>
  57. using namespace GFLAGS_NAMESPACE;
  58. #endif
  59. #ifdef HAVE_LIB_GMOCK
  60. #include <gmock/gmock.h>
  61. #include "mock-log.h"
  62. // Introduce several symbols from gmock.
  63. using testing::_;
  64. using testing::AnyNumber;
  65. using testing::HasSubstr;
  66. using testing::AllOf;
  67. using testing::StrNe;
  68. using testing::StrictMock;
  69. using testing::InitGoogleMock;
  70. using GOOGLE_NAMESPACE::glog_testing::ScopedMockLog;
  71. #endif
  72. using namespace std;
  73. using namespace GOOGLE_NAMESPACE;
  74. // Some non-advertised functions that we want to test or use.
  75. _START_GOOGLE_NAMESPACE_
  76. namespace base {
  77. namespace internal {
  78. bool GetExitOnDFatal();
  79. void SetExitOnDFatal(bool value);
  80. } // namespace internal
  81. } // namespace base
  82. _END_GOOGLE_NAMESPACE_
  83. static void TestLogging(bool check_counts);
  84. static void TestRawLogging();
  85. static void LogWithLevels(int v, int severity, bool err, bool alsoerr);
  86. static void TestLoggingLevels();
  87. static void TestLogString();
  88. static void TestLogSink();
  89. static void TestLogToString();
  90. static void TestLogSinkWaitTillSent();
  91. static void TestCHECK();
  92. static void TestDCHECK();
  93. static void TestSTREQ();
  94. static void TestBasename();
  95. static void TestSymlink();
  96. static void TestExtension();
  97. static void TestWrapper();
  98. static void TestErrno();
  99. static void TestTruncate();
  100. static int x = -1;
  101. static void BM_Check1(int n) {
  102. while (n-- > 0) {
  103. CHECK_GE(n, x);
  104. CHECK_GE(n, x);
  105. CHECK_GE(n, x);
  106. CHECK_GE(n, x);
  107. CHECK_GE(n, x);
  108. CHECK_GE(n, x);
  109. CHECK_GE(n, x);
  110. CHECK_GE(n, x);
  111. }
  112. }
  113. BENCHMARK(BM_Check1);
  114. static void CheckFailure(int a, int b, const char* file, int line, const char* msg);
  115. static void BM_Check3(int n) {
  116. while (n-- > 0) {
  117. if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
  118. if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
  119. if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
  120. if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
  121. if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
  122. if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
  123. if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
  124. if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
  125. }
  126. }
  127. BENCHMARK(BM_Check3);
  128. static void BM_Check2(int n) {
  129. if (n == 17) {
  130. x = 5;
  131. }
  132. while (n-- > 0) {
  133. CHECK(n >= x);
  134. CHECK(n >= x);
  135. CHECK(n >= x);
  136. CHECK(n >= x);
  137. CHECK(n >= x);
  138. CHECK(n >= x);
  139. CHECK(n >= x);
  140. CHECK(n >= x);
  141. }
  142. }
  143. BENCHMARK(BM_Check2);
  144. static void CheckFailure(int, int, const char* /* file */, int /* line */,
  145. const char* /* msg */) {
  146. }
  147. static void BM_logspeed(int n) {
  148. while (n-- > 0) {
  149. LOG(INFO) << "test message";
  150. }
  151. }
  152. BENCHMARK(BM_logspeed);
  153. static void BM_vlog(int n) {
  154. while (n-- > 0) {
  155. VLOG(1) << "test message";
  156. }
  157. }
  158. BENCHMARK(BM_vlog);
  159. int main(int argc, char **argv) {
  160. FLAGS_colorlogtostderr = false;
  161. #ifdef HAVE_LIB_GFLAGS
  162. ParseCommandLineFlags(&argc, &argv, true);
  163. #endif
  164. // Make sure stderr is not buffered as stderr seems to be buffered
  165. // on recent windows.
  166. setbuf(stderr, NULL);
  167. // Test some basics before InitGoogleLogging:
  168. CaptureTestStderr();
  169. LogWithLevels(FLAGS_v, FLAGS_stderrthreshold,
  170. FLAGS_logtostderr, FLAGS_alsologtostderr);
  171. LogWithLevels(0, 0, 0, 0); // simulate "before global c-tors"
  172. const string early_stderr = GetCapturedTestStderr();
  173. InitGoogleLogging(argv[0]);
  174. RunSpecifiedBenchmarks();
  175. FLAGS_logtostderr = true;
  176. InitGoogleTest(&argc, argv);
  177. #ifdef HAVE_LIB_GMOCK
  178. InitGoogleMock(&argc, argv);
  179. #endif
  180. // so that death tests run before we use threads
  181. CHECK_EQ(RUN_ALL_TESTS(), 0);
  182. CaptureTestStderr();
  183. // re-emit early_stderr
  184. LogMessage("dummy", LogMessage::kNoLogPrefix, GLOG_INFO).stream() << early_stderr;
  185. TestLogging(true);
  186. TestRawLogging();
  187. TestLoggingLevels();
  188. TestLogString();
  189. TestLogSink();
  190. TestLogToString();
  191. TestLogSinkWaitTillSent();
  192. TestCHECK();
  193. TestDCHECK();
  194. TestSTREQ();
  195. // TODO: The golden test portion of this test is very flakey.
  196. EXPECT_TRUE(
  197. MungeAndDiffTestStderr(FLAGS_test_srcdir + "/src/logging_unittest.err"));
  198. FLAGS_logtostderr = false;
  199. TestBasename();
  200. TestSymlink();
  201. TestExtension();
  202. TestWrapper();
  203. TestErrno();
  204. TestTruncate();
  205. ShutdownGoogleLogging();
  206. fprintf(stdout, "PASS\n");
  207. return 0;
  208. }
  209. void TestLogging(bool check_counts) {
  210. int64 base_num_infos = LogMessage::num_messages(GLOG_INFO);
  211. int64 base_num_warning = LogMessage::num_messages(GLOG_WARNING);
  212. int64 base_num_errors = LogMessage::num_messages(GLOG_ERROR);
  213. LOG(INFO) << string("foo ") << "bar " << 10 << ' ' << 3.4;
  214. for ( int i = 0; i < 10; ++i ) {
  215. int old_errno = errno;
  216. errno = i;
  217. PLOG_EVERY_N(ERROR, 2) << "Plog every 2, iteration " << COUNTER;
  218. errno = old_errno;
  219. LOG_EVERY_N(ERROR, 3) << "Log every 3, iteration " << COUNTER << endl;
  220. LOG_EVERY_N(ERROR, 4) << "Log every 4, iteration " << COUNTER << endl;
  221. LOG_IF_EVERY_N(WARNING, true, 5) << "Log if every 5, iteration " << COUNTER;
  222. LOG_IF_EVERY_N(WARNING, false, 3)
  223. << "Log if every 3, iteration " << COUNTER;
  224. LOG_IF_EVERY_N(INFO, true, 1) << "Log if every 1, iteration " << COUNTER;
  225. LOG_IF_EVERY_N(ERROR, (i < 3), 2)
  226. << "Log if less than 3 every 2, iteration " << COUNTER;
  227. }
  228. LOG_IF(WARNING, true) << "log_if this";
  229. LOG_IF(WARNING, false) << "don't log_if this";
  230. char s[] = "array";
  231. LOG(INFO) << s;
  232. const char const_s[] = "const array";
  233. LOG(INFO) << const_s;
  234. int j = 1000;
  235. LOG(ERROR) << string("foo") << ' '<< j << ' ' << setw(10) << j << " "
  236. << setw(1) << hex << j;
  237. LogMessage("foo", LogMessage::kNoLogPrefix, GLOG_INFO).stream() << "no prefix";
  238. if (check_counts) {
  239. CHECK_EQ(base_num_infos + 14, LogMessage::num_messages(GLOG_INFO));
  240. CHECK_EQ(base_num_warning + 3, LogMessage::num_messages(GLOG_WARNING));
  241. CHECK_EQ(base_num_errors + 15, LogMessage::num_messages(GLOG_ERROR));
  242. }
  243. }
  244. static void NoAllocNewHook() {
  245. CHECK(false) << "unexpected new";
  246. }
  247. struct NewHook {
  248. NewHook() {
  249. g_new_hook = &NoAllocNewHook;
  250. }
  251. ~NewHook() {
  252. g_new_hook = NULL;
  253. }
  254. };
  255. TEST(DeathNoAllocNewHook, logging) {
  256. // tests that NewHook used below works
  257. NewHook new_hook;
  258. ASSERT_DEATH({
  259. new int;
  260. }, "unexpected new");
  261. }
  262. void TestRawLogging() {
  263. string* foo = new string("foo ");
  264. string huge_str(50000, 'a');
  265. FlagSaver saver;
  266. // Check that RAW loggging does not use mallocs.
  267. NewHook new_hook;
  268. RAW_LOG(INFO, "%s%s%d%c%f", foo->c_str(), "bar ", 10, ' ', 3.4);
  269. char s[] = "array";
  270. RAW_LOG(WARNING, "%s", s);
  271. const char const_s[] = "const array";
  272. RAW_LOG(INFO, "%s", const_s);
  273. void* p = reinterpret_cast<void*>(0x12345678);
  274. RAW_LOG(INFO, "ptr %p", p);
  275. p = NULL;
  276. RAW_LOG(INFO, "ptr %p", p);
  277. int j = 1000;
  278. RAW_LOG(ERROR, "%s%d%c%010d%s%1x", foo->c_str(), j, ' ', j, " ", j);
  279. RAW_VLOG(0, "foo %d", j);
  280. #ifdef NDEBUG
  281. RAW_LOG(INFO, "foo %d", j); // so that have same stderr to compare
  282. #else
  283. RAW_DLOG(INFO, "foo %d", j); // test RAW_DLOG in debug mode
  284. #endif
  285. // test how long messages are chopped:
  286. RAW_LOG(WARNING, "Huge string: %s", huge_str.c_str());
  287. RAW_VLOG(0, "Huge string: %s", huge_str.c_str());
  288. FLAGS_v = 0;
  289. RAW_LOG(INFO, "log");
  290. RAW_VLOG(0, "vlog 0 on");
  291. RAW_VLOG(1, "vlog 1 off");
  292. RAW_VLOG(2, "vlog 2 off");
  293. RAW_VLOG(3, "vlog 3 off");
  294. FLAGS_v = 2;
  295. RAW_LOG(INFO, "log");
  296. RAW_VLOG(1, "vlog 1 on");
  297. RAW_VLOG(2, "vlog 2 on");
  298. RAW_VLOG(3, "vlog 3 off");
  299. #ifdef NDEBUG
  300. RAW_DCHECK(1 == 2, " RAW_DCHECK's shouldn't be compiled in normal mode");
  301. #endif
  302. RAW_CHECK(1 == 1, "should be ok");
  303. RAW_DCHECK(true, "should be ok");
  304. delete foo;
  305. }
  306. void LogWithLevels(int v, int severity, bool err, bool alsoerr) {
  307. RAW_LOG(INFO,
  308. "Test: v=%d stderrthreshold=%d logtostderr=%d alsologtostderr=%d",
  309. v, severity, err, alsoerr);
  310. FlagSaver saver;
  311. FLAGS_v = v;
  312. FLAGS_stderrthreshold = severity;
  313. FLAGS_logtostderr = err;
  314. FLAGS_alsologtostderr = alsoerr;
  315. RAW_VLOG(-1, "vlog -1");
  316. RAW_VLOG(0, "vlog 0");
  317. RAW_VLOG(1, "vlog 1");
  318. RAW_LOG(INFO, "log info");
  319. RAW_LOG(WARNING, "log warning");
  320. RAW_LOG(ERROR, "log error");
  321. VLOG(-1) << "vlog -1";
  322. VLOG(0) << "vlog 0";
  323. VLOG(1) << "vlog 1";
  324. LOG(INFO) << "log info";
  325. LOG(WARNING) << "log warning";
  326. LOG(ERROR) << "log error";
  327. VLOG_IF(-1, true) << "vlog_if -1";
  328. VLOG_IF(-1, false) << "don't vlog_if -1";
  329. VLOG_IF(0, true) << "vlog_if 0";
  330. VLOG_IF(0, false) << "don't vlog_if 0";
  331. VLOG_IF(1, true) << "vlog_if 1";
  332. VLOG_IF(1, false) << "don't vlog_if 1";
  333. LOG_IF(INFO, true) << "log_if info";
  334. LOG_IF(INFO, false) << "don't log_if info";
  335. LOG_IF(WARNING, true) << "log_if warning";
  336. LOG_IF(WARNING, false) << "don't log_if warning";
  337. LOG_IF(ERROR, true) << "log_if error";
  338. LOG_IF(ERROR, false) << "don't log_if error";
  339. int c;
  340. c = 1; VLOG_IF(100, c -= 2) << "vlog_if 100 expr"; EXPECT_EQ(c, -1);
  341. c = 1; VLOG_IF(0, c -= 2) << "vlog_if 0 expr"; EXPECT_EQ(c, -1);
  342. c = 1; LOG_IF(INFO, c -= 2) << "log_if info expr"; EXPECT_EQ(c, -1);
  343. c = 1; LOG_IF(ERROR, c -= 2) << "log_if error expr"; EXPECT_EQ(c, -1);
  344. c = 2; VLOG_IF(0, c -= 2) << "don't vlog_if 0 expr"; EXPECT_EQ(c, 0);
  345. c = 2; LOG_IF(ERROR, c -= 2) << "don't log_if error expr"; EXPECT_EQ(c, 0);
  346. c = 3; LOG_IF_EVERY_N(INFO, c -= 4, 1) << "log_if info every 1 expr";
  347. EXPECT_EQ(c, -1);
  348. c = 3; LOG_IF_EVERY_N(ERROR, c -= 4, 1) << "log_if error every 1 expr";
  349. EXPECT_EQ(c, -1);
  350. c = 4; LOG_IF_EVERY_N(ERROR, c -= 4, 3) << "don't log_if info every 3 expr";
  351. EXPECT_EQ(c, 0);
  352. c = 4; LOG_IF_EVERY_N(ERROR, c -= 4, 3) << "don't log_if error every 3 expr";
  353. EXPECT_EQ(c, 0);
  354. c = 5; VLOG_IF_EVERY_N(0, c -= 4, 1) << "vlog_if 0 every 1 expr";
  355. EXPECT_EQ(c, 1);
  356. c = 5; VLOG_IF_EVERY_N(100, c -= 4, 3) << "vlog_if 100 every 3 expr";
  357. EXPECT_EQ(c, 1);
  358. c = 6; VLOG_IF_EVERY_N(0, c -= 6, 1) << "don't vlog_if 0 every 1 expr";
  359. EXPECT_EQ(c, 0);
  360. c = 6; VLOG_IF_EVERY_N(100, c -= 6, 3) << "don't vlog_if 100 every 1 expr";
  361. EXPECT_EQ(c, 0);
  362. }
  363. void TestLoggingLevels() {
  364. LogWithLevels(0, GLOG_INFO, false, false);
  365. LogWithLevels(1, GLOG_INFO, false, false);
  366. LogWithLevels(-1, GLOG_INFO, false, false);
  367. LogWithLevels(0, GLOG_WARNING, false, false);
  368. LogWithLevels(0, GLOG_ERROR, false, false);
  369. LogWithLevels(0, GLOG_FATAL, false, false);
  370. LogWithLevels(0, GLOG_FATAL, true, false);
  371. LogWithLevels(0, GLOG_FATAL, false, true);
  372. LogWithLevels(1, GLOG_WARNING, false, false);
  373. LogWithLevels(1, GLOG_FATAL, false, true);
  374. }
  375. TEST(DeathRawCHECK, logging) {
  376. ASSERT_DEATH(RAW_CHECK(false, "failure 1"),
  377. "RAW: Check false failed: failure 1");
  378. ASSERT_DEBUG_DEATH(RAW_DCHECK(1 == 2, "failure 2"),
  379. "RAW: Check 1 == 2 failed: failure 2");
  380. }
  381. void TestLogString() {
  382. vector<string> errors;
  383. vector<string> *no_errors = NULL;
  384. LOG_STRING(INFO, &errors) << "LOG_STRING: " << "collected info";
  385. LOG_STRING(WARNING, &errors) << "LOG_STRING: " << "collected warning";
  386. LOG_STRING(ERROR, &errors) << "LOG_STRING: " << "collected error";
  387. LOG_STRING(INFO, no_errors) << "LOG_STRING: " << "reported info";
  388. LOG_STRING(WARNING, no_errors) << "LOG_STRING: " << "reported warning";
  389. LOG_STRING(ERROR, NULL) << "LOG_STRING: " << "reported error";
  390. for (size_t i = 0; i < errors.size(); ++i) {
  391. LOG(INFO) << "Captured by LOG_STRING: " << errors[i];
  392. }
  393. }
  394. void TestLogToString() {
  395. string error;
  396. string* no_error = NULL;
  397. LOG_TO_STRING(INFO, &error) << "LOG_TO_STRING: " << "collected info";
  398. LOG(INFO) << "Captured by LOG_TO_STRING: " << error;
  399. LOG_TO_STRING(WARNING, &error) << "LOG_TO_STRING: " << "collected warning";
  400. LOG(INFO) << "Captured by LOG_TO_STRING: " << error;
  401. LOG_TO_STRING(ERROR, &error) << "LOG_TO_STRING: " << "collected error";
  402. LOG(INFO) << "Captured by LOG_TO_STRING: " << error;
  403. LOG_TO_STRING(INFO, no_error) << "LOG_TO_STRING: " << "reported info";
  404. LOG_TO_STRING(WARNING, no_error) << "LOG_TO_STRING: " << "reported warning";
  405. LOG_TO_STRING(ERROR, NULL) << "LOG_TO_STRING: " << "reported error";
  406. }
  407. class TestLogSinkImpl : public LogSink {
  408. public:
  409. vector<string> errors;
  410. virtual void send(LogSeverity severity, const char* /* full_filename */,
  411. const char* base_filename, int line,
  412. const struct tm* tm_time,
  413. const char* message, size_t message_len) {
  414. errors.push_back(
  415. ToString(severity, base_filename, line, tm_time, message, message_len));
  416. }
  417. };
  418. void TestLogSink() {
  419. TestLogSinkImpl sink;
  420. LogSink *no_sink = NULL;
  421. LOG_TO_SINK(&sink, INFO) << "LOG_TO_SINK: " << "collected info";
  422. LOG_TO_SINK(&sink, WARNING) << "LOG_TO_SINK: " << "collected warning";
  423. LOG_TO_SINK(&sink, ERROR) << "LOG_TO_SINK: " << "collected error";
  424. LOG_TO_SINK(no_sink, INFO) << "LOG_TO_SINK: " << "reported info";
  425. LOG_TO_SINK(no_sink, WARNING) << "LOG_TO_SINK: " << "reported warning";
  426. LOG_TO_SINK(NULL, ERROR) << "LOG_TO_SINK: " << "reported error";
  427. LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, INFO)
  428. << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected info";
  429. LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, WARNING)
  430. << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected warning";
  431. LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, ERROR)
  432. << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected error";
  433. LOG_TO_SINK_BUT_NOT_TO_LOGFILE(no_sink, INFO)
  434. << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed info";
  435. LOG_TO_SINK_BUT_NOT_TO_LOGFILE(no_sink, WARNING)
  436. << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed warning";
  437. LOG_TO_SINK_BUT_NOT_TO_LOGFILE(NULL, ERROR)
  438. << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed error";
  439. LOG(INFO) << "Captured by LOG_TO_SINK:";
  440. for (size_t i = 0; i < sink.errors.size(); ++i) {
  441. LogMessage("foo", LogMessage::kNoLogPrefix, GLOG_INFO).stream()
  442. << sink.errors[i];
  443. }
  444. }
  445. // For testing using CHECK*() on anonymous enums.
  446. enum {
  447. CASE_A,
  448. CASE_B
  449. };
  450. void TestCHECK() {
  451. // Tests using CHECK*() on int values.
  452. CHECK(1 == 1);
  453. CHECK_EQ(1, 1);
  454. CHECK_NE(1, 2);
  455. CHECK_GE(1, 1);
  456. CHECK_GE(2, 1);
  457. CHECK_LE(1, 1);
  458. CHECK_LE(1, 2);
  459. CHECK_GT(2, 1);
  460. CHECK_LT(1, 2);
  461. // Tests using CHECK*() on anonymous enums.
  462. // Apple's GCC doesn't like this.
  463. #if !defined(OS_MACOSX)
  464. CHECK_EQ(CASE_A, CASE_A);
  465. CHECK_NE(CASE_A, CASE_B);
  466. CHECK_GE(CASE_A, CASE_A);
  467. CHECK_GE(CASE_B, CASE_A);
  468. CHECK_LE(CASE_A, CASE_A);
  469. CHECK_LE(CASE_A, CASE_B);
  470. CHECK_GT(CASE_B, CASE_A);
  471. CHECK_LT(CASE_A, CASE_B);
  472. #endif
  473. }
  474. void TestDCHECK() {
  475. #ifdef NDEBUG
  476. DCHECK( 1 == 2 ) << " DCHECK's shouldn't be compiled in normal mode";
  477. #endif
  478. DCHECK( 1 == 1 );
  479. DCHECK_EQ(1, 1);
  480. DCHECK_NE(1, 2);
  481. DCHECK_GE(1, 1);
  482. DCHECK_GE(2, 1);
  483. DCHECK_LE(1, 1);
  484. DCHECK_LE(1, 2);
  485. DCHECK_GT(2, 1);
  486. DCHECK_LT(1, 2);
  487. auto_ptr<int64> sptr(new int64);
  488. int64* ptr = DCHECK_NOTNULL(sptr.get());
  489. CHECK_EQ(ptr, sptr.get());
  490. }
  491. void TestSTREQ() {
  492. CHECK_STREQ("this", "this");
  493. CHECK_STREQ(NULL, NULL);
  494. CHECK_STRCASEEQ("this", "tHiS");
  495. CHECK_STRCASEEQ(NULL, NULL);
  496. CHECK_STRNE("this", "tHiS");
  497. CHECK_STRNE("this", NULL);
  498. CHECK_STRCASENE("this", "that");
  499. CHECK_STRCASENE(NULL, "that");
  500. CHECK_STREQ((string("a")+"b").c_str(), "ab");
  501. CHECK_STREQ(string("test").c_str(),
  502. (string("te") + string("st")).c_str());
  503. }
  504. TEST(DeathSTREQ, logging) {
  505. ASSERT_DEATH(CHECK_STREQ(NULL, "this"), "");
  506. ASSERT_DEATH(CHECK_STREQ("this", "siht"), "");
  507. ASSERT_DEATH(CHECK_STRCASEEQ(NULL, "siht"), "");
  508. ASSERT_DEATH(CHECK_STRCASEEQ("this", "siht"), "");
  509. ASSERT_DEATH(CHECK_STRNE(NULL, NULL), "");
  510. ASSERT_DEATH(CHECK_STRNE("this", "this"), "");
  511. ASSERT_DEATH(CHECK_STREQ((string("a")+"b").c_str(), "abc"), "");
  512. }
  513. TEST(CheckNOTNULL, Simple) {
  514. int64 t;
  515. void *ptr = static_cast<void *>(&t);
  516. void *ref = CHECK_NOTNULL(ptr);
  517. EXPECT_EQ(ptr, ref);
  518. CHECK_NOTNULL(reinterpret_cast<char *>(ptr));
  519. CHECK_NOTNULL(reinterpret_cast<unsigned char *>(ptr));
  520. CHECK_NOTNULL(reinterpret_cast<int *>(ptr));
  521. CHECK_NOTNULL(reinterpret_cast<int64 *>(ptr));
  522. }
  523. TEST(DeathCheckNN, Simple) {
  524. ASSERT_DEATH(CHECK_NOTNULL(static_cast<void *>(NULL)), "");
  525. }
  526. // Get list of file names that match pattern
  527. static void GetFiles(const string& pattern, vector<string>* files) {
  528. files->clear();
  529. #if defined(HAVE_GLOB_H)
  530. glob_t g;
  531. const int r = glob(pattern.c_str(), 0, NULL, &g);
  532. CHECK((r == 0) || (r == GLOB_NOMATCH)) << ": error matching " << pattern;
  533. for (size_t i = 0; i < g.gl_pathc; i++) {
  534. files->push_back(string(g.gl_pathv[i]));
  535. }
  536. globfree(&g);
  537. #elif defined(OS_WINDOWS)
  538. WIN32_FIND_DATAA data;
  539. HANDLE handle = FindFirstFileA(pattern.c_str(), &data);
  540. size_t index = pattern.rfind('\\');
  541. if (index == string::npos) {
  542. LOG(FATAL) << "No directory separator.";
  543. }
  544. const string dirname = pattern.substr(0, index + 1);
  545. if (handle == INVALID_HANDLE_VALUE) {
  546. // Finding no files is OK.
  547. return;
  548. }
  549. do {
  550. files->push_back(dirname + data.cFileName);
  551. } while (FindNextFileA(handle, &data));
  552. BOOL result = FindClose(handle);
  553. LOG_SYSRESULT(result);
  554. #else
  555. # error There is no way to do glob.
  556. #endif
  557. }
  558. // Delete files patching pattern
  559. static void DeleteFiles(const string& pattern) {
  560. vector<string> files;
  561. GetFiles(pattern, &files);
  562. for (size_t i = 0; i < files.size(); i++) {
  563. CHECK(unlink(files[i].c_str()) == 0) << ": " << strerror(errno);
  564. }
  565. }
  566. static void CheckFile(const string& name, const string& expected_string) {
  567. vector<string> files;
  568. GetFiles(name + "*", &files);
  569. CHECK_EQ(files.size(), 1UL);
  570. FILE* file = fopen(files[0].c_str(), "r");
  571. CHECK(file != NULL) << ": could not open " << files[0];
  572. char buf[1000];
  573. while (fgets(buf, sizeof(buf), file) != NULL) {
  574. if (strstr(buf, expected_string.c_str()) != NULL) {
  575. fclose(file);
  576. return;
  577. }
  578. }
  579. fclose(file);
  580. LOG(FATAL) << "Did not find " << expected_string << " in " << files[0];
  581. }
  582. static void TestBasename() {
  583. fprintf(stderr, "==== Test setting log file basename\n");
  584. const string dest = FLAGS_test_tmpdir + "/logging_test_basename";
  585. DeleteFiles(dest + "*");
  586. SetLogDestination(GLOG_INFO, dest.c_str());
  587. LOG(INFO) << "message to new base";
  588. FlushLogFiles(GLOG_INFO);
  589. CheckFile(dest, "message to new base");
  590. // Release file handle for the destination file to unlock the file in Windows.
  591. LogToStderr();
  592. DeleteFiles(dest + "*");
  593. }
  594. static void TestSymlink() {
  595. #ifndef OS_WINDOWS
  596. fprintf(stderr, "==== Test setting log file symlink\n");
  597. string dest = FLAGS_test_tmpdir + "/logging_test_symlink";
  598. string sym = FLAGS_test_tmpdir + "/symlinkbase";
  599. DeleteFiles(dest + "*");
  600. DeleteFiles(sym + "*");
  601. SetLogSymlink(GLOG_INFO, "symlinkbase");
  602. SetLogDestination(GLOG_INFO, dest.c_str());
  603. LOG(INFO) << "message to new symlink";
  604. FlushLogFiles(GLOG_INFO);
  605. CheckFile(sym, "message to new symlink");
  606. DeleteFiles(dest + "*");
  607. DeleteFiles(sym + "*");
  608. #endif
  609. }
  610. static void TestExtension() {
  611. fprintf(stderr, "==== Test setting log file extension\n");
  612. string dest = FLAGS_test_tmpdir + "/logging_test_extension";
  613. DeleteFiles(dest + "*");
  614. SetLogDestination(GLOG_INFO, dest.c_str());
  615. SetLogFilenameExtension("specialextension");
  616. LOG(INFO) << "message to new extension";
  617. FlushLogFiles(GLOG_INFO);
  618. CheckFile(dest, "message to new extension");
  619. // Check that file name ends with extension
  620. vector<string> filenames;
  621. GetFiles(dest + "*", &filenames);
  622. CHECK_EQ(filenames.size(), 1UL);
  623. CHECK(strstr(filenames[0].c_str(), "specialextension") != NULL);
  624. // Release file handle for the destination file to unlock the file in Windows.
  625. LogToStderr();
  626. DeleteFiles(dest + "*");
  627. }
  628. struct MyLogger : public base::Logger {
  629. string data;
  630. virtual void Write(bool /* should_flush */,
  631. time_t /* timestamp */,
  632. const char* message,
  633. int length) {
  634. data.append(message, length);
  635. }
  636. virtual void Flush() { }
  637. virtual uint32 LogSize() { return data.length(); }
  638. };
  639. static void TestWrapper() {
  640. fprintf(stderr, "==== Test log wrapper\n");
  641. MyLogger my_logger;
  642. base::Logger* old_logger = base::GetLogger(GLOG_INFO);
  643. base::SetLogger(GLOG_INFO, &my_logger);
  644. LOG(INFO) << "Send to wrapped logger";
  645. FlushLogFiles(GLOG_INFO);
  646. base::SetLogger(GLOG_INFO, old_logger);
  647. CHECK(strstr(my_logger.data.c_str(), "Send to wrapped logger") != NULL);
  648. }
  649. static void TestErrno() {
  650. fprintf(stderr, "==== Test errno preservation\n");
  651. errno = ENOENT;
  652. TestLogging(false);
  653. CHECK_EQ(errno, ENOENT);
  654. }
  655. static void TestOneTruncate(const char *path, int64 limit, int64 keep,
  656. int64 dsize, int64 ksize, int64 expect) {
  657. int fd;
  658. CHECK_ERR(fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0600));
  659. const char *discardstr = "DISCARDME!", *keepstr = "KEEPME!";
  660. // Fill the file with the requested data; first discard data, then kept data
  661. int64 written = 0;
  662. while (written < dsize) {
  663. int bytes = min<int64>(dsize - written, strlen(discardstr));
  664. CHECK_ERR(write(fd, discardstr, bytes));
  665. written += bytes;
  666. }
  667. written = 0;
  668. while (written < ksize) {
  669. int bytes = min<int64>(ksize - written, strlen(keepstr));
  670. CHECK_ERR(write(fd, keepstr, bytes));
  671. written += bytes;
  672. }
  673. TruncateLogFile(path, limit, keep);
  674. // File should now be shorter
  675. struct stat statbuf;
  676. CHECK_ERR(fstat(fd, &statbuf));
  677. CHECK_EQ(statbuf.st_size, expect);
  678. CHECK_ERR(lseek(fd, 0, SEEK_SET));
  679. // File should contain the suffix of the original file
  680. const size_t buf_size = statbuf.st_size + 1;
  681. char* buf = new char[buf_size];
  682. memset(buf, 0, buf_size);
  683. CHECK_ERR(read(fd, buf, buf_size));
  684. const char *p = buf;
  685. int64 checked = 0;
  686. while (checked < expect) {
  687. int bytes = min<int64>(expect - checked, strlen(keepstr));
  688. CHECK(!memcmp(p, keepstr, bytes));
  689. checked += bytes;
  690. }
  691. close(fd);
  692. delete[] buf;
  693. }
  694. static void TestTruncate() {
  695. #ifdef HAVE_UNISTD_H
  696. fprintf(stderr, "==== Test log truncation\n");
  697. string path = FLAGS_test_tmpdir + "/truncatefile";
  698. // Test on a small file
  699. TestOneTruncate(path.c_str(), 10, 10, 10, 10, 10);
  700. // And a big file (multiple blocks to copy)
  701. TestOneTruncate(path.c_str(), 2<<20, 4<<10, 3<<20, 4<<10, 4<<10);
  702. // Check edge-case limits
  703. TestOneTruncate(path.c_str(), 10, 20, 0, 20, 20);
  704. TestOneTruncate(path.c_str(), 10, 0, 0, 0, 0);
  705. TestOneTruncate(path.c_str(), 10, 50, 0, 10, 10);
  706. TestOneTruncate(path.c_str(), 50, 100, 0, 30, 30);
  707. // MacOSX 10.4 doesn't fail in this case.
  708. // Windows doesn't have symlink.
  709. // Let's just ignore this test for these cases.
  710. #if !defined(OS_MACOSX) && !defined(OS_WINDOWS)
  711. // Through a symlink should fail to truncate
  712. string linkname = path + ".link";
  713. unlink(linkname.c_str());
  714. CHECK_ERR(symlink(path.c_str(), linkname.c_str()));
  715. TestOneTruncate(linkname.c_str(), 10, 10, 0, 30, 30);
  716. #endif
  717. // The /proc/self path makes sense only for linux.
  718. #if defined(OS_LINUX)
  719. // Through an open fd symlink should work
  720. int fd;
  721. CHECK_ERR(fd = open(path.c_str(), O_APPEND | O_WRONLY));
  722. char fdpath[64];
  723. snprintf(fdpath, sizeof(fdpath), "/proc/self/fd/%d", fd);
  724. TestOneTruncate(fdpath, 10, 10, 10, 10, 10);
  725. #endif
  726. #endif
  727. }
  728. _START_GOOGLE_NAMESPACE_
  729. namespace glog_internal_namespace_ {
  730. extern // in logging.cc
  731. bool SafeFNMatch_(const char* pattern, size_t patt_len,
  732. const char* str, size_t str_len);
  733. } // namespace glog_internal_namespace_
  734. using glog_internal_namespace_::SafeFNMatch_;
  735. _END_GOOGLE_NAMESPACE_
  736. static bool WrapSafeFNMatch(string pattern, string str) {
  737. pattern += "abc";
  738. str += "defgh";
  739. return SafeFNMatch_(pattern.data(), pattern.size() - 3,
  740. str.data(), str.size() - 5);
  741. }
  742. TEST(SafeFNMatch, logging) {
  743. CHECK(WrapSafeFNMatch("foo", "foo"));
  744. CHECK(!WrapSafeFNMatch("foo", "bar"));
  745. CHECK(!WrapSafeFNMatch("foo", "fo"));
  746. CHECK(!WrapSafeFNMatch("foo", "foo2"));
  747. CHECK(WrapSafeFNMatch("bar/foo.ext", "bar/foo.ext"));
  748. CHECK(WrapSafeFNMatch("*ba*r/fo*o.ext*", "bar/foo.ext"));
  749. CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/baz.ext"));
  750. CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/foo"));
  751. CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/foo.ext.zip"));
  752. CHECK(WrapSafeFNMatch("ba?/*.ext", "bar/foo.ext"));
  753. CHECK(WrapSafeFNMatch("ba?/*.ext", "baZ/FOO.ext"));
  754. CHECK(!WrapSafeFNMatch("ba?/*.ext", "barr/foo.ext"));
  755. CHECK(!WrapSafeFNMatch("ba?/*.ext", "bar/foo.ext2"));
  756. CHECK(WrapSafeFNMatch("ba?/*", "bar/foo.ext2"));
  757. CHECK(WrapSafeFNMatch("ba?/*", "bar/"));
  758. CHECK(!WrapSafeFNMatch("ba?/?", "bar/"));
  759. CHECK(!WrapSafeFNMatch("ba?/*", "bar"));
  760. }
  761. // TestWaitingLogSink will save messages here
  762. // No lock: Accessed only by TestLogSinkWriter thread
  763. // and after its demise by its creator.
  764. static vector<string> global_messages;
  765. // helper for TestWaitingLogSink below.
  766. // Thread that does the logic of TestWaitingLogSink
  767. // It's free to use LOG() itself.
  768. class TestLogSinkWriter : public Thread {
  769. public:
  770. TestLogSinkWriter() : should_exit_(false) {
  771. SetJoinable(true);
  772. Start();
  773. }
  774. // Just buffer it (can't use LOG() here).
  775. void Buffer(const string& message) {
  776. mutex_.Lock();
  777. RAW_LOG(INFO, "Buffering");
  778. messages_.push(message);
  779. mutex_.Unlock();
  780. RAW_LOG(INFO, "Buffered");
  781. }
  782. // Wait for the buffer to clear (can't use LOG() here).
  783. void Wait() {
  784. RAW_LOG(INFO, "Waiting");
  785. mutex_.Lock();
  786. while (!NoWork()) {
  787. mutex_.Unlock();
  788. SleepForMilliseconds(1);
  789. mutex_.Lock();
  790. }
  791. RAW_LOG(INFO, "Waited");
  792. mutex_.Unlock();
  793. }
  794. // Trigger thread exit.
  795. void Stop() {
  796. MutexLock l(&mutex_);
  797. should_exit_ = true;
  798. }
  799. private:
  800. // helpers ---------------
  801. // For creating a "Condition".
  802. bool NoWork() { return messages_.empty(); }
  803. bool HaveWork() { return !messages_.empty() || should_exit_; }
  804. // Thread body; CAN use LOG() here!
  805. virtual void Run() {
  806. while (1) {
  807. mutex_.Lock();
  808. while (!HaveWork()) {
  809. mutex_.Unlock();
  810. SleepForMilliseconds(1);
  811. mutex_.Lock();
  812. }
  813. if (should_exit_ && messages_.empty()) {
  814. mutex_.Unlock();
  815. break;
  816. }
  817. // Give the main thread time to log its message,
  818. // so that we get a reliable log capture to compare to golden file.
  819. // Same for the other sleep below.
  820. SleepForMilliseconds(20);
  821. RAW_LOG(INFO, "Sink got a messages"); // only RAW_LOG under mutex_ here
  822. string message = messages_.front();
  823. messages_.pop();
  824. // Normally this would be some more real/involved logging logic
  825. // where LOG() usage can't be eliminated,
  826. // e.g. pushing the message over with an RPC:
  827. int messages_left = messages_.size();
  828. mutex_.Unlock();
  829. SleepForMilliseconds(20);
  830. // May not use LOG while holding mutex_, because Buffer()
  831. // acquires mutex_, and Buffer is called from LOG(),
  832. // which has its own internal mutex:
  833. // LOG()->LogToSinks()->TestWaitingLogSink::send()->Buffer()
  834. LOG(INFO) << "Sink is sending out a message: " << message;
  835. LOG(INFO) << "Have " << messages_left << " left";
  836. global_messages.push_back(message);
  837. }
  838. }
  839. // data ---------------
  840. Mutex mutex_;
  841. bool should_exit_;
  842. queue<string> messages_; // messages to be logged
  843. };
  844. // A log sink that exercises WaitTillSent:
  845. // it pushes data to a buffer and wakes up another thread to do the logging
  846. // (that other thread can than use LOG() itself),
  847. class TestWaitingLogSink : public LogSink {
  848. public:
  849. TestWaitingLogSink() {
  850. tid_ = pthread_self(); // for thread-specific behavior
  851. AddLogSink(this);
  852. }
  853. ~TestWaitingLogSink() {
  854. RemoveLogSink(this);
  855. writer_.Stop();
  856. writer_.Join();
  857. }
  858. // (re)define LogSink interface
  859. virtual void send(LogSeverity severity, const char* /* full_filename */,
  860. const char* base_filename, int line,
  861. const struct tm* tm_time,
  862. const char* message, size_t message_len) {
  863. // Push it to Writer thread if we are the original logging thread.
  864. // Note: Something like ThreadLocalLogSink is a better choice
  865. // to do thread-specific LogSink logic for real.
  866. if (pthread_equal(tid_, pthread_self())) {
  867. writer_.Buffer(ToString(severity, base_filename, line,
  868. tm_time, message, message_len));
  869. }
  870. }
  871. virtual void WaitTillSent() {
  872. // Wait for Writer thread if we are the original logging thread.
  873. if (pthread_equal(tid_, pthread_self())) writer_.Wait();
  874. }
  875. private:
  876. pthread_t tid_;
  877. TestLogSinkWriter writer_;
  878. };
  879. // Check that LogSink::WaitTillSent can be used in the advertised way.
  880. // We also do golden-stderr comparison.
  881. static void TestLogSinkWaitTillSent() {
  882. { TestWaitingLogSink sink;
  883. // Sleeps give the sink threads time to do all their work,
  884. // so that we get a reliable log capture to compare to the golden file.
  885. LOG(INFO) << "Message 1";
  886. SleepForMilliseconds(60);
  887. LOG(ERROR) << "Message 2";
  888. SleepForMilliseconds(60);
  889. LOG(WARNING) << "Message 3";
  890. SleepForMilliseconds(60);
  891. }
  892. for (size_t i = 0; i < global_messages.size(); ++i) {
  893. LOG(INFO) << "Sink capture: " << global_messages[i];
  894. }
  895. CHECK_EQ(global_messages.size(), 3UL);
  896. }
  897. TEST(Strerror, logging) {
  898. int errcode = EINTR;
  899. char *msg = strdup(strerror(errcode));
  900. const size_t buf_size = strlen(msg) + 1;
  901. char *buf = new char[buf_size];
  902. CHECK_EQ(posix_strerror_r(errcode, NULL, 0), -1);
  903. buf[0] = 'A';
  904. CHECK_EQ(posix_strerror_r(errcode, buf, 0), -1);
  905. CHECK_EQ(buf[0], 'A');
  906. CHECK_EQ(posix_strerror_r(errcode, NULL, buf_size), -1);
  907. #if defined(OS_MACOSX) || defined(OS_FREEBSD) || defined(OS_OPENBSD)
  908. // MacOSX or FreeBSD considers this case is an error since there is
  909. // no enough space.
  910. CHECK_EQ(posix_strerror_r(errcode, buf, 1), -1);
  911. #else
  912. CHECK_EQ(posix_strerror_r(errcode, buf, 1), 0);
  913. #endif
  914. CHECK_STREQ(buf, "");
  915. CHECK_EQ(posix_strerror_r(errcode, buf, buf_size), 0);
  916. CHECK_STREQ(buf, msg);
  917. delete[] buf;
  918. CHECK_EQ(msg, StrError(errcode));
  919. free(msg);
  920. }
  921. // Simple routines to look at the sizes of generated code for LOG(FATAL) and
  922. // CHECK(..) via objdump
  923. void MyFatal() {
  924. LOG(FATAL) << "Failed";
  925. }
  926. void MyCheck(bool a, bool b) {
  927. CHECK_EQ(a, b);
  928. }
  929. #ifdef HAVE_LIB_GMOCK
  930. TEST(DVLog, Basic) {
  931. ScopedMockLog log;
  932. #if NDEBUG
  933. // We are expecting that nothing is logged.
  934. EXPECT_CALL(log, Log(_, _, _)).Times(0);
  935. #else
  936. EXPECT_CALL(log, Log(INFO, __FILE__, "debug log"));
  937. #endif
  938. FLAGS_v = 1;
  939. DVLOG(1) << "debug log";
  940. }
  941. TEST(DVLog, V0) {
  942. ScopedMockLog log;
  943. // We are expecting that nothing is logged.
  944. EXPECT_CALL(log, Log(_, _, _)).Times(0);
  945. FLAGS_v = 0;
  946. DVLOG(1) << "debug log";
  947. }
  948. TEST(LogAtLevel, Basic) {
  949. ScopedMockLog log;
  950. // The function version outputs "logging.h" as a file name.
  951. EXPECT_CALL(log, Log(WARNING, StrNe(__FILE__), "function version"));
  952. EXPECT_CALL(log, Log(INFO, __FILE__, "macro version"));
  953. int severity = WARNING;
  954. LogAtLevel(severity, "function version");
  955. severity = INFO;
  956. // We can use the macro version as a C++ stream.
  957. LOG_AT_LEVEL(severity) << "macro" << ' ' << "version";
  958. }
  959. TEST(TestExitOnDFatal, ToBeOrNotToBe) {
  960. // Check the default setting...
  961. EXPECT_TRUE(base::internal::GetExitOnDFatal());
  962. // Turn off...
  963. base::internal::SetExitOnDFatal(false);
  964. EXPECT_FALSE(base::internal::GetExitOnDFatal());
  965. // We don't die.
  966. {
  967. ScopedMockLog log;
  968. //EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
  969. // LOG(DFATAL) has severity FATAL if debugging, but is
  970. // downgraded to ERROR if not debugging.
  971. const LogSeverity severity =
  972. #ifdef NDEBUG
  973. ERROR;
  974. #else
  975. FATAL;
  976. #endif
  977. EXPECT_CALL(log, Log(severity, __FILE__, "This should not be fatal"));
  978. LOG(DFATAL) << "This should not be fatal";
  979. }
  980. // Turn back on...
  981. base::internal::SetExitOnDFatal(true);
  982. EXPECT_TRUE(base::internal::GetExitOnDFatal());
  983. #ifdef GTEST_HAS_DEATH_TEST
  984. // Death comes on little cats' feet.
  985. EXPECT_DEBUG_DEATH({
  986. LOG(DFATAL) << "This should be fatal in debug mode";
  987. }, "This should be fatal in debug mode");
  988. #endif
  989. }
  990. #ifdef HAVE_STACKTRACE
  991. static void BacktraceAtHelper() {
  992. LOG(INFO) << "Not me";
  993. // The vertical spacing of the next 3 lines is significant.
  994. LOG(INFO) << "Backtrace me";
  995. }
  996. static int kBacktraceAtLine = __LINE__ - 2; // The line of the LOG(INFO) above
  997. TEST(LogBacktraceAt, DoesNotBacktraceWhenDisabled) {
  998. StrictMock<ScopedMockLog> log;
  999. FLAGS_log_backtrace_at = "";
  1000. EXPECT_CALL(log, Log(_, _, "Backtrace me"));
  1001. EXPECT_CALL(log, Log(_, _, "Not me"));
  1002. BacktraceAtHelper();
  1003. }
  1004. TEST(LogBacktraceAt, DoesBacktraceAtRightLineWhenEnabled) {
  1005. StrictMock<ScopedMockLog> log;
  1006. char where[100];
  1007. snprintf(where, 100, "%s:%d", const_basename(__FILE__), kBacktraceAtLine);
  1008. FLAGS_log_backtrace_at = where;
  1009. // The LOG at the specified line should include a stacktrace which includes
  1010. // the name of the containing function, followed by the log message.
  1011. // We use HasSubstr()s instead of ContainsRegex() for environments
  1012. // which don't have regexp.
  1013. EXPECT_CALL(log, Log(_, _, AllOf(HasSubstr("stacktrace:"),
  1014. HasSubstr("BacktraceAtHelper"),
  1015. HasSubstr("main"),
  1016. HasSubstr("Backtrace me"))));
  1017. // Other LOGs should not include a backtrace.
  1018. EXPECT_CALL(log, Log(_, _, "Not me"));
  1019. BacktraceAtHelper();
  1020. }
  1021. #endif // HAVE_STACKTRACE
  1022. #endif // HAVE_LIB_GMOCK
  1023. struct UserDefinedClass {
  1024. bool operator==(const UserDefinedClass&) const { return true; }
  1025. };
  1026. inline ostream& operator<<(ostream& out, const UserDefinedClass&) {
  1027. out << "OK";
  1028. return out;
  1029. }
  1030. TEST(UserDefinedClass, logging) {
  1031. UserDefinedClass u;
  1032. vector<string> buf;
  1033. LOG_STRING(INFO, &buf) << u;
  1034. CHECK_EQ(1UL, buf.size());
  1035. CHECK(buf[0].find("OK") != string::npos);
  1036. // We must be able to compile this.
  1037. CHECK_EQ(u, u);
  1038. }