1 // Copyright (c) 2002, Google Inc.
2 // All rights reserved.
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
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
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.
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.
32 #include "config_for_unittests.h"
33 #include "utilities.h"
55 #include "base/commandlineflags.h"
56 #include "glog/logging.h"
57 #include "glog/raw_logging.h"
58 #include "googletest.h"
60 DECLARE_string(log_backtrace_at); // logging.cc
62 #ifdef HAVE_LIB_GFLAGS
63 #include <gflags/gflags.h>
64 using namespace GFLAGS_NAMESPACE;
68 #include <gmock/gmock.h>
70 // Introduce several symbols from gmock.
72 using testing::AnyNumber;
73 using testing::HasSubstr;
76 using testing::StrictMock;
77 using testing::InitGoogleMock;
78 using GOOGLE_NAMESPACE::glog_testing::ScopedMockLog;
82 using namespace GOOGLE_NAMESPACE;
84 // Some non-advertised functions that we want to test or use.
85 _START_GOOGLE_NAMESPACE_
88 bool GetExitOnDFatal();
89 void SetExitOnDFatal(bool value);
90 } // namespace internal
92 _END_GOOGLE_NAMESPACE_
94 static void TestLogging(bool check_counts);
95 static void TestRawLogging();
96 static void LogWithLevels(int v, int severity, bool err, bool alsoerr);
97 static void TestLoggingLevels();
98 static void TestLogString();
99 static void TestLogSink();
100 static void TestLogToString();
101 static void TestLogSinkWaitTillSent();
102 static void TestCHECK();
103 static void TestDCHECK();
104 static void TestSTREQ();
105 static void TestBasename();
106 static void TestSymlink();
107 static void TestExtension();
108 static void TestWrapper();
109 static void TestErrno();
110 static void TestTruncate();
113 static void BM_Check1(int n) {
125 BENCHMARK(BM_Check1);
127 static void CheckFailure(int a, int b, const char* file, int line, const char* msg);
128 static void BM_Check3(int n) {
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 if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
140 BENCHMARK(BM_Check3);
142 static void BM_Check2(int n) {
157 BENCHMARK(BM_Check2);
159 static void CheckFailure(int, int, const char* /* file */, int /* line */,
160 const char* /* msg */) {
163 static void BM_logspeed(int n) {
165 LOG(INFO) << "test message";
168 BENCHMARK(BM_logspeed);
170 static void BM_vlog(int n) {
172 VLOG(1) << "test message";
177 int main(int argc, char **argv) {
178 FLAGS_colorlogtostderr = false;
179 #ifdef HAVE_LIB_GFLAGS
180 ParseCommandLineFlags(&argc, &argv, true);
182 // Make sure stderr is not buffered as stderr seems to be buffered
183 // on recent windows.
184 setbuf(stderr, NULL);
186 // Test some basics before InitGoogleLogging:
188 LogWithLevels(FLAGS_v, FLAGS_stderrthreshold,
189 FLAGS_logtostderr, FLAGS_alsologtostderr);
190 LogWithLevels(0, 0, 0, 0); // simulate "before global c-tors"
191 const string early_stderr = GetCapturedTestStderr();
193 InitGoogleLogging(argv[0]);
195 RunSpecifiedBenchmarks();
197 FLAGS_logtostderr = true;
199 InitGoogleTest(&argc, argv);
200 #ifdef HAVE_LIB_GMOCK
201 InitGoogleMock(&argc, argv);
204 // so that death tests run before we use threads
205 CHECK_EQ(RUN_ALL_TESTS(), 0);
209 // re-emit early_stderr
210 LogMessage("dummy", LogMessage::kNoLogPrefix, GLOG_INFO).stream() << early_stderr;
218 TestLogSinkWaitTillSent();
223 // TODO: The golden test portion of this test is very flakey.
225 MungeAndDiffTestStderr(FLAGS_test_srcdir + "/src/logging_unittest.err"));
227 FLAGS_logtostderr = false;
236 ShutdownGoogleLogging();
238 fprintf(stdout, "PASS\n");
242 void TestLogging(bool check_counts) {
243 int64 base_num_infos = LogMessage::num_messages(GLOG_INFO);
244 int64 base_num_warning = LogMessage::num_messages(GLOG_WARNING);
245 int64 base_num_errors = LogMessage::num_messages(GLOG_ERROR);
247 LOG(INFO) << string("foo ") << "bar " << 10 << ' ' << 3.4;
248 for ( int i = 0; i < 10; ++i ) {
249 int old_errno = errno;
251 PLOG_EVERY_N(ERROR, 2) << "Plog every 2, iteration " << COUNTER;
254 LOG_EVERY_N(ERROR, 3) << "Log every 3, iteration " << COUNTER << endl;
255 LOG_EVERY_N(ERROR, 4) << "Log every 4, iteration " << COUNTER << endl;
257 LOG_IF_EVERY_N(WARNING, true, 5) << "Log if every 5, iteration " << COUNTER;
258 LOG_IF_EVERY_N(WARNING, false, 3)
259 << "Log if every 3, iteration " << COUNTER;
260 LOG_IF_EVERY_N(INFO, true, 1) << "Log if every 1, iteration " << COUNTER;
261 LOG_IF_EVERY_N(ERROR, (i < 3), 2)
262 << "Log if less than 3 every 2, iteration " << COUNTER;
264 LOG_IF(WARNING, true) << "log_if this";
265 LOG_IF(WARNING, false) << "don't log_if this";
269 const char const_s[] = "const array";
270 LOG(INFO) << const_s;
272 LOG(ERROR) << string("foo") << ' '<< j << ' ' << setw(10) << j << " "
273 << setw(1) << hex << j;
275 LogMessage("foo", LogMessage::kNoLogPrefix, GLOG_INFO).stream() << "no prefix";
278 CHECK_EQ(base_num_infos + 14, LogMessage::num_messages(GLOG_INFO));
279 CHECK_EQ(base_num_warning + 3, LogMessage::num_messages(GLOG_WARNING));
280 CHECK_EQ(base_num_errors + 15, LogMessage::num_messages(GLOG_ERROR));
284 static void NoAllocNewHook() {
285 CHECK(false) << "unexpected new";
290 g_new_hook = &NoAllocNewHook;
297 TEST(DeathNoAllocNewHook, logging) {
298 // tests that NewHook used below works
302 }, "unexpected new");
305 void TestRawLogging() {
306 string* foo = new string("foo ");
307 string huge_str(50000, 'a');
311 // Check that RAW loggging does not use mallocs.
314 RAW_LOG(INFO, "%s%s%d%c%f", foo->c_str(), "bar ", 10, ' ', 3.4);
316 RAW_LOG(WARNING, "%s", s);
317 const char const_s[] = "const array";
318 RAW_LOG(INFO, "%s", const_s);
319 void* p = reinterpret_cast<void*>(0x12345678);
320 RAW_LOG(INFO, "ptr %p", p);
322 RAW_LOG(INFO, "ptr %p", p);
324 RAW_LOG(ERROR, "%s%d%c%010d%s%1x", foo->c_str(), j, ' ', j, " ", j);
325 RAW_VLOG(0, "foo %d", j);
328 RAW_LOG(INFO, "foo %d", j); // so that have same stderr to compare
330 RAW_DLOG(INFO, "foo %d", j); // test RAW_DLOG in debug mode
333 // test how long messages are chopped:
334 RAW_LOG(WARNING, "Huge string: %s", huge_str.c_str());
335 RAW_VLOG(0, "Huge string: %s", huge_str.c_str());
338 RAW_LOG(INFO, "log");
339 RAW_VLOG(0, "vlog 0 on");
340 RAW_VLOG(1, "vlog 1 off");
341 RAW_VLOG(2, "vlog 2 off");
342 RAW_VLOG(3, "vlog 3 off");
344 RAW_LOG(INFO, "log");
345 RAW_VLOG(1, "vlog 1 on");
346 RAW_VLOG(2, "vlog 2 on");
347 RAW_VLOG(3, "vlog 3 off");
350 RAW_DCHECK(1 == 2, " RAW_DCHECK's shouldn't be compiled in normal mode");
353 RAW_CHECK(1 == 1, "should be ok");
354 RAW_DCHECK(true, "should be ok");
359 void LogWithLevels(int v, int severity, bool err, bool alsoerr) {
361 "Test: v=%d stderrthreshold=%d logtostderr=%d alsologtostderr=%d",
362 v, severity, err, alsoerr);
367 FLAGS_stderrthreshold = severity;
368 FLAGS_logtostderr = err;
369 FLAGS_alsologtostderr = alsoerr;
371 RAW_VLOG(-1, "vlog -1");
372 RAW_VLOG(0, "vlog 0");
373 RAW_VLOG(1, "vlog 1");
374 RAW_LOG(INFO, "log info");
375 RAW_LOG(WARNING, "log warning");
376 RAW_LOG(ERROR, "log error");
378 VLOG(-1) << "vlog -1";
381 LOG(INFO) << "log info";
382 LOG(WARNING) << "log warning";
383 LOG(ERROR) << "log error";
385 VLOG_IF(-1, true) << "vlog_if -1";
386 VLOG_IF(-1, false) << "don't vlog_if -1";
387 VLOG_IF(0, true) << "vlog_if 0";
388 VLOG_IF(0, false) << "don't vlog_if 0";
389 VLOG_IF(1, true) << "vlog_if 1";
390 VLOG_IF(1, false) << "don't vlog_if 1";
391 LOG_IF(INFO, true) << "log_if info";
392 LOG_IF(INFO, false) << "don't log_if info";
393 LOG_IF(WARNING, true) << "log_if warning";
394 LOG_IF(WARNING, false) << "don't log_if warning";
395 LOG_IF(ERROR, true) << "log_if error";
396 LOG_IF(ERROR, false) << "don't log_if error";
399 c = 1; VLOG_IF(100, c -= 2) << "vlog_if 100 expr"; EXPECT_EQ(c, -1);
400 c = 1; VLOG_IF(0, c -= 2) << "vlog_if 0 expr"; EXPECT_EQ(c, -1);
401 c = 1; LOG_IF(INFO, c -= 2) << "log_if info expr"; EXPECT_EQ(c, -1);
402 c = 1; LOG_IF(ERROR, c -= 2) << "log_if error expr"; EXPECT_EQ(c, -1);
403 c = 2; VLOG_IF(0, c -= 2) << "don't vlog_if 0 expr"; EXPECT_EQ(c, 0);
404 c = 2; LOG_IF(ERROR, c -= 2) << "don't log_if error expr"; EXPECT_EQ(c, 0);
406 c = 3; LOG_IF_EVERY_N(INFO, c -= 4, 1) << "log_if info every 1 expr";
408 c = 3; LOG_IF_EVERY_N(ERROR, c -= 4, 1) << "log_if error every 1 expr";
410 c = 4; LOG_IF_EVERY_N(ERROR, c -= 4, 3) << "don't log_if info every 3 expr";
412 c = 4; LOG_IF_EVERY_N(ERROR, c -= 4, 3) << "don't log_if error every 3 expr";
414 c = 5; VLOG_IF_EVERY_N(0, c -= 4, 1) << "vlog_if 0 every 1 expr";
416 c = 5; VLOG_IF_EVERY_N(100, c -= 4, 3) << "vlog_if 100 every 3 expr";
418 c = 6; VLOG_IF_EVERY_N(0, c -= 6, 1) << "don't vlog_if 0 every 1 expr";
420 c = 6; VLOG_IF_EVERY_N(100, c -= 6, 3) << "don't vlog_if 100 every 1 expr";
424 void TestLoggingLevels() {
425 LogWithLevels(0, GLOG_INFO, false, false);
426 LogWithLevels(1, GLOG_INFO, false, false);
427 LogWithLevels(-1, GLOG_INFO, false, false);
428 LogWithLevels(0, GLOG_WARNING, false, false);
429 LogWithLevels(0, GLOG_ERROR, false, false);
430 LogWithLevels(0, GLOG_FATAL, false, false);
431 LogWithLevels(0, GLOG_FATAL, true, false);
432 LogWithLevels(0, GLOG_FATAL, false, true);
433 LogWithLevels(1, GLOG_WARNING, false, false);
434 LogWithLevels(1, GLOG_FATAL, false, true);
437 TEST(DeathRawCHECK, logging) {
438 ASSERT_DEATH(RAW_CHECK(false, "failure 1"),
439 "RAW: Check false failed: failure 1");
440 ASSERT_DEBUG_DEATH(RAW_DCHECK(1 == 2, "failure 2"),
441 "RAW: Check 1 == 2 failed: failure 2");
444 void TestLogString() {
445 vector<string> errors;
446 vector<string> *no_errors = NULL;
448 LOG_STRING(INFO, &errors) << "LOG_STRING: " << "collected info";
449 LOG_STRING(WARNING, &errors) << "LOG_STRING: " << "collected warning";
450 LOG_STRING(ERROR, &errors) << "LOG_STRING: " << "collected error";
452 LOG_STRING(INFO, no_errors) << "LOG_STRING: " << "reported info";
453 LOG_STRING(WARNING, no_errors) << "LOG_STRING: " << "reported warning";
454 LOG_STRING(ERROR, NULL) << "LOG_STRING: " << "reported error";
456 for (size_t i = 0; i < errors.size(); ++i) {
457 LOG(INFO) << "Captured by LOG_STRING: " << errors[i];
461 void TestLogToString() {
463 string* no_error = NULL;
465 LOG_TO_STRING(INFO, &error) << "LOG_TO_STRING: " << "collected info";
466 LOG(INFO) << "Captured by LOG_TO_STRING: " << error;
467 LOG_TO_STRING(WARNING, &error) << "LOG_TO_STRING: " << "collected warning";
468 LOG(INFO) << "Captured by LOG_TO_STRING: " << error;
469 LOG_TO_STRING(ERROR, &error) << "LOG_TO_STRING: " << "collected error";
470 LOG(INFO) << "Captured by LOG_TO_STRING: " << error;
472 LOG_TO_STRING(INFO, no_error) << "LOG_TO_STRING: " << "reported info";
473 LOG_TO_STRING(WARNING, no_error) << "LOG_TO_STRING: " << "reported warning";
474 LOG_TO_STRING(ERROR, NULL) << "LOG_TO_STRING: " << "reported error";
477 class TestLogSinkImpl : public LogSink {
479 vector<string> errors;
480 virtual void send(LogSeverity severity, const char* /* full_filename */,
481 const char* base_filename, int line,
482 const struct tm* tm_time,
483 const char* message, size_t message_len) {
485 ToString(severity, base_filename, line, tm_time, message, message_len));
490 TestLogSinkImpl sink;
491 LogSink *no_sink = NULL;
493 LOG_TO_SINK(&sink, INFO) << "LOG_TO_SINK: " << "collected info";
494 LOG_TO_SINK(&sink, WARNING) << "LOG_TO_SINK: " << "collected warning";
495 LOG_TO_SINK(&sink, ERROR) << "LOG_TO_SINK: " << "collected error";
497 LOG_TO_SINK(no_sink, INFO) << "LOG_TO_SINK: " << "reported info";
498 LOG_TO_SINK(no_sink, WARNING) << "LOG_TO_SINK: " << "reported warning";
499 LOG_TO_SINK(NULL, ERROR) << "LOG_TO_SINK: " << "reported error";
501 LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, INFO)
502 << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected info";
503 LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, WARNING)
504 << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected warning";
505 LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, ERROR)
506 << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected error";
508 LOG_TO_SINK_BUT_NOT_TO_LOGFILE(no_sink, INFO)
509 << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed info";
510 LOG_TO_SINK_BUT_NOT_TO_LOGFILE(no_sink, WARNING)
511 << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed warning";
512 LOG_TO_SINK_BUT_NOT_TO_LOGFILE(NULL, ERROR)
513 << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed error";
515 LOG(INFO) << "Captured by LOG_TO_SINK:";
516 for (size_t i = 0; i < sink.errors.size(); ++i) {
517 LogMessage("foo", LogMessage::kNoLogPrefix, GLOG_INFO).stream()
522 // For testing using CHECK*() on anonymous enums.
529 // Tests using CHECK*() on int values.
540 // Tests using CHECK*() on anonymous enums.
541 // Apple's GCC doesn't like this.
542 #if !defined(OS_MACOSX)
543 CHECK_EQ(CASE_A, CASE_A);
544 CHECK_NE(CASE_A, CASE_B);
545 CHECK_GE(CASE_A, CASE_A);
546 CHECK_GE(CASE_B, CASE_A);
547 CHECK_LE(CASE_A, CASE_A);
548 CHECK_LE(CASE_A, CASE_B);
549 CHECK_GT(CASE_B, CASE_A);
550 CHECK_LT(CASE_A, CASE_B);
556 DCHECK( 1 == 2 ) << " DCHECK's shouldn't be compiled in normal mode";
568 auto_ptr<int64> sptr(new int64);
569 int64* ptr = DCHECK_NOTNULL(sptr.get());
570 CHECK_EQ(ptr, sptr.get());
574 CHECK_STREQ("this", "this");
575 CHECK_STREQ(NULL, NULL);
576 CHECK_STRCASEEQ("this", "tHiS");
577 CHECK_STRCASEEQ(NULL, NULL);
578 CHECK_STRNE("this", "tHiS");
579 CHECK_STRNE("this", NULL);
580 CHECK_STRCASENE("this", "that");
581 CHECK_STRCASENE(NULL, "that");
582 CHECK_STREQ((string("a")+"b").c_str(), "ab");
583 CHECK_STREQ(string("test").c_str(),
584 (string("te") + string("st")).c_str());
587 TEST(DeathSTREQ, logging) {
588 ASSERT_DEATH(CHECK_STREQ(NULL, "this"), "");
589 ASSERT_DEATH(CHECK_STREQ("this", "siht"), "");
590 ASSERT_DEATH(CHECK_STRCASEEQ(NULL, "siht"), "");
591 ASSERT_DEATH(CHECK_STRCASEEQ("this", "siht"), "");
592 ASSERT_DEATH(CHECK_STRNE(NULL, NULL), "");
593 ASSERT_DEATH(CHECK_STRNE("this", "this"), "");
594 ASSERT_DEATH(CHECK_STREQ((string("a")+"b").c_str(), "abc"), "");
597 TEST(CheckNOTNULL, Simple) {
599 void *ptr = static_cast<void *>(&t);
600 void *ref = CHECK_NOTNULL(ptr);
602 CHECK_NOTNULL(reinterpret_cast<char *>(ptr));
603 CHECK_NOTNULL(reinterpret_cast<unsigned char *>(ptr));
604 CHECK_NOTNULL(reinterpret_cast<int *>(ptr));
605 CHECK_NOTNULL(reinterpret_cast<int64 *>(ptr));
608 TEST(DeathCheckNN, Simple) {
609 ASSERT_DEATH(CHECK_NOTNULL(static_cast<void *>(NULL)), "");
612 // Get list of file names that match pattern
613 static void GetFiles(const string& pattern, vector<string>* files) {
615 #if defined(HAVE_GLOB_H)
617 const int r = glob(pattern.c_str(), 0, NULL, &g);
618 CHECK((r == 0) || (r == GLOB_NOMATCH)) << ": error matching " << pattern;
619 for (size_t i = 0; i < g.gl_pathc; i++) {
620 files->push_back(string(g.gl_pathv[i]));
623 #elif defined(OS_WINDOWS)
624 WIN32_FIND_DATAA data;
625 HANDLE handle = FindFirstFileA(pattern.c_str(), &data);
626 size_t index = pattern.rfind('\\');
627 if (index == string::npos) {
628 LOG(FATAL) << "No directory separator.";
630 const string dirname = pattern.substr(0, index + 1);
631 if (handle == INVALID_HANDLE_VALUE) {
632 // Finding no files is OK.
636 files->push_back(dirname + data.cFileName);
637 } while (FindNextFileA(handle, &data));
638 BOOL result = FindClose(handle);
639 LOG_SYSRESULT(result);
641 # error There is no way to do glob.
645 // Delete files patching pattern
646 static void DeleteFiles(const string& pattern) {
647 vector<string> files;
648 GetFiles(pattern, &files);
649 for (size_t i = 0; i < files.size(); i++) {
650 CHECK(unlink(files[i].c_str()) == 0) << ": " << strerror(errno);
654 static void CheckFile(const string& name, const string& expected_string) {
655 vector<string> files;
656 GetFiles(name + "*", &files);
657 CHECK_EQ(files.size(), 1UL);
659 FILE* file = fopen(files[0].c_str(), "r");
660 CHECK(file != NULL) << ": could not open " << files[0];
662 while (fgets(buf, sizeof(buf), file) != NULL) {
663 if (strstr(buf, expected_string.c_str()) != NULL) {
669 LOG(FATAL) << "Did not find " << expected_string << " in " << files[0];
672 static void TestBasename() {
673 fprintf(stderr, "==== Test setting log file basename\n");
674 const string dest = FLAGS_test_tmpdir + "/logging_test_basename";
675 DeleteFiles(dest + "*");
677 SetLogDestination(GLOG_INFO, dest.c_str());
678 LOG(INFO) << "message to new base";
679 FlushLogFiles(GLOG_INFO);
681 CheckFile(dest, "message to new base");
683 // Release file handle for the destination file to unlock the file in Windows.
685 DeleteFiles(dest + "*");
688 static void TestSymlink() {
690 fprintf(stderr, "==== Test setting log file symlink\n");
691 string dest = FLAGS_test_tmpdir + "/logging_test_symlink";
692 string sym = FLAGS_test_tmpdir + "/symlinkbase";
693 DeleteFiles(dest + "*");
694 DeleteFiles(sym + "*");
696 SetLogSymlink(GLOG_INFO, "symlinkbase");
697 SetLogDestination(GLOG_INFO, dest.c_str());
698 LOG(INFO) << "message to new symlink";
699 FlushLogFiles(GLOG_INFO);
700 CheckFile(sym, "message to new symlink");
702 DeleteFiles(dest + "*");
703 DeleteFiles(sym + "*");
707 static void TestExtension() {
708 fprintf(stderr, "==== Test setting log file extension\n");
709 string dest = FLAGS_test_tmpdir + "/logging_test_extension";
710 DeleteFiles(dest + "*");
712 SetLogDestination(GLOG_INFO, dest.c_str());
713 SetLogFilenameExtension("specialextension");
714 LOG(INFO) << "message to new extension";
715 FlushLogFiles(GLOG_INFO);
716 CheckFile(dest, "message to new extension");
718 // Check that file name ends with extension
719 vector<string> filenames;
720 GetFiles(dest + "*", &filenames);
721 CHECK_EQ(filenames.size(), 1UL);
722 CHECK(strstr(filenames[0].c_str(), "specialextension") != NULL);
724 // Release file handle for the destination file to unlock the file in Windows.
726 DeleteFiles(dest + "*");
729 struct MyLogger : public base::Logger {
732 virtual void Write(bool /* should_flush */,
733 time_t /* timestamp */,
736 data.append(message, length);
739 virtual void Flush() { }
741 virtual uint32 LogSize() { return data.length(); }
744 static void TestWrapper() {
745 fprintf(stderr, "==== Test log wrapper\n");
748 base::Logger* old_logger = base::GetLogger(GLOG_INFO);
749 base::SetLogger(GLOG_INFO, &my_logger);
750 LOG(INFO) << "Send to wrapped logger";
751 FlushLogFiles(GLOG_INFO);
752 base::SetLogger(GLOG_INFO, old_logger);
754 CHECK(strstr(my_logger.data.c_str(), "Send to wrapped logger") != NULL);
757 static void TestErrno() {
758 fprintf(stderr, "==== Test errno preservation\n");
762 CHECK_EQ(errno, ENOENT);
765 static void TestOneTruncate(const char *path, int64 limit, int64 keep,
766 int64 dsize, int64 ksize, int64 expect) {
768 CHECK_ERR(fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0600));
770 const char *discardstr = "DISCARDME!", *keepstr = "KEEPME!";
771 const size_t discard_size = strlen(discardstr), keep_size = strlen(keepstr);
773 // Fill the file with the requested data; first discard data, then kept data
775 while (written < dsize) {
776 int bytes = min<int64>(dsize - written, discard_size);
777 CHECK_ERR(write(fd, discardstr, bytes));
781 while (written < ksize) {
782 int bytes = min<int64>(ksize - written, keep_size);
783 CHECK_ERR(write(fd, keepstr, bytes));
787 TruncateLogFile(path, limit, keep);
789 // File should now be shorter
791 CHECK_ERR(fstat(fd, &statbuf));
792 CHECK_EQ(statbuf.st_size, expect);
793 CHECK_ERR(lseek(fd, 0, SEEK_SET));
795 // File should contain the suffix of the original file
796 const size_t buf_size = statbuf.st_size + 1;
797 char* buf = new char[buf_size];
798 memset(buf, 0, buf_size);
799 CHECK_ERR(read(fd, buf, buf_size));
803 while (checked < expect) {
804 int bytes = min<int64>(expect - checked, keep_size);
805 CHECK(!memcmp(p, keepstr, bytes));
812 static void TestTruncate() {
814 fprintf(stderr, "==== Test log truncation\n");
815 string path = FLAGS_test_tmpdir + "/truncatefile";
817 // Test on a small file
818 TestOneTruncate(path.c_str(), 10, 10, 10, 10, 10);
820 // And a big file (multiple blocks to copy)
821 TestOneTruncate(path.c_str(), 2<<20, 4<<10, 3<<20, 4<<10, 4<<10);
823 // Check edge-case limits
824 TestOneTruncate(path.c_str(), 10, 20, 0, 20, 20);
825 TestOneTruncate(path.c_str(), 10, 0, 0, 0, 0);
826 TestOneTruncate(path.c_str(), 10, 50, 0, 10, 10);
827 TestOneTruncate(path.c_str(), 50, 100, 0, 30, 30);
829 // MacOSX 10.4 doesn't fail in this case.
830 // Windows doesn't have symlink.
831 // Let's just ignore this test for these cases.
832 #if !defined(OS_MACOSX) && !defined(OS_WINDOWS)
833 // Through a symlink should fail to truncate
834 string linkname = path + ".link";
835 unlink(linkname.c_str());
836 CHECK_ERR(symlink(path.c_str(), linkname.c_str()));
837 TestOneTruncate(linkname.c_str(), 10, 10, 0, 30, 30);
840 // The /proc/self path makes sense only for linux.
841 #if defined(OS_LINUX)
842 // Through an open fd symlink should work
844 CHECK_ERR(fd = open(path.c_str(), O_APPEND | O_WRONLY));
846 snprintf(fdpath, sizeof(fdpath), "/proc/self/fd/%d", fd);
847 TestOneTruncate(fdpath, 10, 10, 10, 10, 10);
853 _START_GOOGLE_NAMESPACE_
854 namespace glog_internal_namespace_ {
855 extern // in logging.cc
856 bool SafeFNMatch_(const char* pattern, size_t patt_len,
857 const char* str, size_t str_len);
858 } // namespace glog_internal_namespace_
859 using glog_internal_namespace_::SafeFNMatch_;
860 _END_GOOGLE_NAMESPACE_
862 static bool WrapSafeFNMatch(string pattern, string str) {
865 return SafeFNMatch_(pattern.data(), pattern.size() - 3,
866 str.data(), str.size() - 5);
869 TEST(SafeFNMatch, logging) {
870 CHECK(WrapSafeFNMatch("foo", "foo"));
871 CHECK(!WrapSafeFNMatch("foo", "bar"));
872 CHECK(!WrapSafeFNMatch("foo", "fo"));
873 CHECK(!WrapSafeFNMatch("foo", "foo2"));
874 CHECK(WrapSafeFNMatch("bar/foo.ext", "bar/foo.ext"));
875 CHECK(WrapSafeFNMatch("*ba*r/fo*o.ext*", "bar/foo.ext"));
876 CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/baz.ext"));
877 CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/foo"));
878 CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/foo.ext.zip"));
879 CHECK(WrapSafeFNMatch("ba?/*.ext", "bar/foo.ext"));
880 CHECK(WrapSafeFNMatch("ba?/*.ext", "baZ/FOO.ext"));
881 CHECK(!WrapSafeFNMatch("ba?/*.ext", "barr/foo.ext"));
882 CHECK(!WrapSafeFNMatch("ba?/*.ext", "bar/foo.ext2"));
883 CHECK(WrapSafeFNMatch("ba?/*", "bar/foo.ext2"));
884 CHECK(WrapSafeFNMatch("ba?/*", "bar/"));
885 CHECK(!WrapSafeFNMatch("ba?/?", "bar/"));
886 CHECK(!WrapSafeFNMatch("ba?/*", "bar"));
889 // TestWaitingLogSink will save messages here
890 // No lock: Accessed only by TestLogSinkWriter thread
891 // and after its demise by its creator.
892 static vector<string> global_messages;
894 // helper for TestWaitingLogSink below.
895 // Thread that does the logic of TestWaitingLogSink
896 // It's free to use LOG() itself.
897 class TestLogSinkWriter : public Thread {
900 TestLogSinkWriter() : should_exit_(false) {
905 // Just buffer it (can't use LOG() here).
906 void Buffer(const string& message) {
908 RAW_LOG(INFO, "Buffering");
909 messages_.push(message);
911 RAW_LOG(INFO, "Buffered");
914 // Wait for the buffer to clear (can't use LOG() here).
916 RAW_LOG(INFO, "Waiting");
920 SleepForMilliseconds(1);
923 RAW_LOG(INFO, "Waited");
927 // Trigger thread exit.
929 MutexLock l(&mutex_);
935 // helpers ---------------
937 // For creating a "Condition".
938 bool NoWork() { return messages_.empty(); }
939 bool HaveWork() { return !messages_.empty() || should_exit_; }
941 // Thread body; CAN use LOG() here!
945 while (!HaveWork()) {
947 SleepForMilliseconds(1);
950 if (should_exit_ && messages_.empty()) {
954 // Give the main thread time to log its message,
955 // so that we get a reliable log capture to compare to golden file.
956 // Same for the other sleep below.
957 SleepForMilliseconds(20);
958 RAW_LOG(INFO, "Sink got a messages"); // only RAW_LOG under mutex_ here
959 string message = messages_.front();
961 // Normally this would be some more real/involved logging logic
962 // where LOG() usage can't be eliminated,
963 // e.g. pushing the message over with an RPC:
964 int messages_left = messages_.size();
966 SleepForMilliseconds(20);
967 // May not use LOG while holding mutex_, because Buffer()
968 // acquires mutex_, and Buffer is called from LOG(),
969 // which has its own internal mutex:
970 // LOG()->LogToSinks()->TestWaitingLogSink::send()->Buffer()
971 LOG(INFO) << "Sink is sending out a message: " << message;
972 LOG(INFO) << "Have " << messages_left << " left";
973 global_messages.push_back(message);
977 // data ---------------
981 queue<string> messages_; // messages to be logged
984 // A log sink that exercises WaitTillSent:
985 // it pushes data to a buffer and wakes up another thread to do the logging
986 // (that other thread can than use LOG() itself),
987 class TestWaitingLogSink : public LogSink {
990 TestWaitingLogSink() {
991 tid_ = pthread_self(); // for thread-specific behavior
994 ~TestWaitingLogSink() {
1000 // (re)define LogSink interface
1002 virtual void send(LogSeverity severity, const char* /* full_filename */,
1003 const char* base_filename, int line,
1004 const struct tm* tm_time,
1005 const char* message, size_t message_len) {
1006 // Push it to Writer thread if we are the original logging thread.
1007 // Note: Something like ThreadLocalLogSink is a better choice
1008 // to do thread-specific LogSink logic for real.
1009 if (pthread_equal(tid_, pthread_self())) {
1010 writer_.Buffer(ToString(severity, base_filename, line,
1011 tm_time, message, message_len));
1014 virtual void WaitTillSent() {
1015 // Wait for Writer thread if we are the original logging thread.
1016 if (pthread_equal(tid_, pthread_self())) writer_.Wait();
1022 TestLogSinkWriter writer_;
1025 // Check that LogSink::WaitTillSent can be used in the advertised way.
1026 // We also do golden-stderr comparison.
1027 static void TestLogSinkWaitTillSent() {
1028 { TestWaitingLogSink sink;
1029 // Sleeps give the sink threads time to do all their work,
1030 // so that we get a reliable log capture to compare to the golden file.
1031 LOG(INFO) << "Message 1";
1032 SleepForMilliseconds(60);
1033 LOG(ERROR) << "Message 2";
1034 SleepForMilliseconds(60);
1035 LOG(WARNING) << "Message 3";
1036 SleepForMilliseconds(60);
1038 for (size_t i = 0; i < global_messages.size(); ++i) {
1039 LOG(INFO) << "Sink capture: " << global_messages[i];
1041 CHECK_EQ(global_messages.size(), 3UL);
1044 TEST(Strerror, logging) {
1045 int errcode = EINTR;
1046 char *msg = strdup(strerror(errcode));
1047 const size_t buf_size = strlen(msg) + 1;
1048 char *buf = new char[buf_size];
1049 CHECK_EQ(posix_strerror_r(errcode, NULL, 0), -1);
1051 CHECK_EQ(posix_strerror_r(errcode, buf, 0), -1);
1052 CHECK_EQ(buf[0], 'A');
1053 CHECK_EQ(posix_strerror_r(errcode, NULL, buf_size), -1);
1054 #if defined(OS_MACOSX) || defined(OS_FREEBSD) || defined(OS_OPENBSD)
1055 // MacOSX or FreeBSD considers this case is an error since there is
1057 CHECK_EQ(posix_strerror_r(errcode, buf, 1), -1);
1059 CHECK_EQ(posix_strerror_r(errcode, buf, 1), 0);
1061 CHECK_STREQ(buf, "");
1062 CHECK_EQ(posix_strerror_r(errcode, buf, buf_size), 0);
1063 CHECK_STREQ(buf, msg);
1065 CHECK_EQ(msg, StrError(errcode));
1069 // Simple routines to look at the sizes of generated code for LOG(FATAL) and
1070 // CHECK(..) via objdump
1072 LOG(FATAL) << "Failed";
1074 void MyCheck(bool a, bool b) {
1078 #ifdef HAVE_LIB_GMOCK
1080 TEST(DVLog, Basic) {
1084 // We are expecting that nothing is logged.
1085 EXPECT_CALL(log, Log(_, _, _)).Times(0);
1087 EXPECT_CALL(log, Log(INFO, __FILE__, "debug log"));
1091 DVLOG(1) << "debug log";
1097 // We are expecting that nothing is logged.
1098 EXPECT_CALL(log, Log(_, _, _)).Times(0);
1101 DVLOG(1) << "debug log";
1104 TEST(LogAtLevel, Basic) {
1107 // The function version outputs "logging.h" as a file name.
1108 EXPECT_CALL(log, Log(WARNING, StrNe(__FILE__), "function version"));
1109 EXPECT_CALL(log, Log(INFO, __FILE__, "macro version"));
1111 int severity = WARNING;
1112 LogAtLevel(severity, "function version");
1115 // We can use the macro version as a C++ stream.
1116 LOG_AT_LEVEL(severity) << "macro" << ' ' << "version";
1119 TEST(TestExitOnDFatal, ToBeOrNotToBe) {
1120 // Check the default setting...
1121 EXPECT_TRUE(base::internal::GetExitOnDFatal());
1124 base::internal::SetExitOnDFatal(false);
1125 EXPECT_FALSE(base::internal::GetExitOnDFatal());
1130 //EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
1131 // LOG(DFATAL) has severity FATAL if debugging, but is
1132 // downgraded to ERROR if not debugging.
1133 const LogSeverity severity =
1139 EXPECT_CALL(log, Log(severity, __FILE__, "This should not be fatal"));
1140 LOG(DFATAL) << "This should not be fatal";
1144 base::internal::SetExitOnDFatal(true);
1145 EXPECT_TRUE(base::internal::GetExitOnDFatal());
1147 #ifdef GTEST_HAS_DEATH_TEST
1148 // Death comes on little cats' feet.
1149 EXPECT_DEBUG_DEATH({
1150 LOG(DFATAL) << "This should be fatal in debug mode";
1151 }, "This should be fatal in debug mode");
1155 #ifdef HAVE_STACKTRACE
1157 static void BacktraceAtHelper() {
1158 LOG(INFO) << "Not me";
1160 // The vertical spacing of the next 3 lines is significant.
1161 LOG(INFO) << "Backtrace me";
1163 static int kBacktraceAtLine = __LINE__ - 2; // The line of the LOG(INFO) above
1165 TEST(LogBacktraceAt, DoesNotBacktraceWhenDisabled) {
1166 StrictMock<ScopedMockLog> log;
1168 FLAGS_log_backtrace_at = "";
1170 EXPECT_CALL(log, Log(_, _, "Backtrace me"));
1171 EXPECT_CALL(log, Log(_, _, "Not me"));
1173 BacktraceAtHelper();
1176 TEST(LogBacktraceAt, DoesBacktraceAtRightLineWhenEnabled) {
1177 StrictMock<ScopedMockLog> log;
1180 snprintf(where, 100, "%s:%d", const_basename(__FILE__), kBacktraceAtLine);
1181 FLAGS_log_backtrace_at = where;
1183 // The LOG at the specified line should include a stacktrace which includes
1184 // the name of the containing function, followed by the log message.
1185 // We use HasSubstr()s instead of ContainsRegex() for environments
1186 // which don't have regexp.
1187 EXPECT_CALL(log, Log(_, _, AllOf(HasSubstr("stacktrace:"),
1188 HasSubstr("BacktraceAtHelper"),
1190 HasSubstr("Backtrace me"))));
1191 // Other LOGs should not include a backtrace.
1192 EXPECT_CALL(log, Log(_, _, "Not me"));
1194 BacktraceAtHelper();
1197 #endif // HAVE_STACKTRACE
1199 #endif // HAVE_LIB_GMOCK
1201 struct UserDefinedClass {
1202 bool operator==(const UserDefinedClass&) const { return true; }
1205 inline ostream& operator<<(ostream& out, const UserDefinedClass&) {
1210 TEST(UserDefinedClass, logging) {
1213 LOG_STRING(INFO, &buf) << u;
1214 CHECK_EQ(1UL, buf.size());
1215 CHECK(buf[0].find("OK") != string::npos);
1217 // We must be able to compile this.