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