/thirdparty/breakpad/third_party/glog/src/logging_unittest.cc

http://github.com/tomahawk-player/tomahawk · C++ · 1210 lines · 911 code · 180 blank · 119 comment · 58 complexity · a40288f6bebb3a090f7bcfa29a527585 MD5 · raw file

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