2 // Copyright 2002 Google, Inc.
3 // All Rights Reserved.
7 #include "config_for_unittests.h"
26 #include "base/commandlineflags.h"
27 #include "glog/logging.h"
28 #include "glog/raw_logging.h"
29 #include "googletest.h"
32 using namespace GOOGLE_NAMESPACE;
34 static void TestLogging(bool check_counts);
35 static void TestRawLogging();
36 static void LogWithLevels(int v, int severity, bool err, bool alsoerr);
37 static void TestLoggingLevels();
38 static void TestLogString();
39 static void TestLogSink();
40 static void TestLogSinkWaitTillSent();
41 static void TestCHECK();
42 static void TestDCHECK();
43 static void TestSTREQ();
44 static void TestBasename();
45 static void TestSymlink();
46 static void TestExtension();
47 static void TestWrapper();
48 static void TestErrno();
49 static void TestTruncate();
52 static void BM_Check1(int n) {
66 static void CheckFailure(int a, int b, const char* file, int line, const char* msg);
67 static void BM_Check3(int n) {
69 if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
70 if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
71 if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
72 if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
73 if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
74 if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
75 if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
76 if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
81 static void BM_Check2(int n) {
98 static void CheckFailure(int a, int b, const char* file, int line, const char* msg) {
101 int main(int argc, char **argv) {
102 // Test some basics before InitGoogleLogging:
104 LogWithLevels(FLAGS_v, FLAGS_stderrthreshold,
105 FLAGS_logtostderr, FLAGS_alsologtostderr);
106 LogWithLevels(0, 0, 0, 0); // simulate "before global c-tors"
107 const string early_stderr = GetCapturedTestStderr();
109 FLAGS_logtostderr = true;
111 InitGoogleLogging(argv[0]);
113 RunSpecifiedBenchmarks();
115 InitGoogleTest(&argc, argv);
117 // so that death tests run before we use threads
118 CHECK_EQ(RUN_ALL_TESTS(), 0);
122 // re-emit early_stderr
123 LogMessage("dummy", LogMessage::kNoLogPrefix, INFO).stream() << early_stderr;
130 TestLogSinkWaitTillSent();
135 // TODO: The golden test portion of this test is very flakey.
137 MungeAndDiffTestStderr(FLAGS_test_srcdir + "/src/logging_unittest.err"));
139 FLAGS_logtostderr = false;
152 void TestLogging(bool check_counts) {
153 int64 base_num_infos = LogMessage::num_messages(INFO);
154 int64 base_num_warning = LogMessage::num_messages(WARNING);
155 int64 base_num_errors = LogMessage::num_messages(ERROR);
157 LOG(INFO) << string("foo ") << "bar " << 10 << ' ' << 3.4;
158 for ( int i = 0; i < 10; ++i ) {
159 int old_errno = errno;
161 PLOG_EVERY_N(ERROR, 2) << "Plog every 2, iteration " << COUNTER;
164 LOG_EVERY_N(ERROR, 3) << "Log every 3, iteration " << COUNTER << endl;
165 LOG_EVERY_N(ERROR, 4) << "Log every 4, iteration " << COUNTER << endl;
167 LOG_IF_EVERY_N(WARNING, true, 5) << "Log if every 5, iteration " << COUNTER;
168 LOG_IF_EVERY_N(WARNING, false, 3)
169 << "Log if every 3, iteration " << COUNTER;
170 LOG_IF_EVERY_N(INFO, true, 1) << "Log if every 1, iteration " << COUNTER;
171 LOG_IF_EVERY_N(ERROR, (i < 3), 2)
172 << "Log if less than 3 every 2, iteration " << COUNTER;
174 LOG_IF(WARNING, true) << "log_if this";
175 LOG_IF(WARNING, false) << "don't log_if this";
179 const char const_s[] = "const array";
180 LOG(INFO) << const_s;
182 LOG(ERROR) << string("foo") << ' '<< j << ' ' << setw(10) << j << " "
183 << setw(1) << hex << j;
185 LogMessage("foo", LogMessage::kNoLogPrefix, INFO).stream() << "no prefix";
188 CHECK_EQ(base_num_infos + 14, LogMessage::num_messages(INFO));
189 CHECK_EQ(base_num_warning + 3, LogMessage::num_messages(WARNING));
190 CHECK_EQ(base_num_errors + 15, LogMessage::num_messages(ERROR));
194 static void NoAllocNewHook() {
195 CHECK(false) << "unexpected new";
200 g_new_hook = &NoAllocNewHook;
207 TEST(DeathNoAllocNewHook, logging) {
208 // tests that NewHook used below works
212 }, "unexpected new");
215 void TestRawLogging() {
216 string* foo = new string("foo ");
217 string huge_str(50000, 'a');
221 // Check that RAW loggging does not use mallocs.
224 RAW_LOG(INFO, "%s%s%d%c%f", foo->c_str(), "bar ", 10, ' ', 3.4);
226 RAW_LOG(WARNING, "%s", s);
227 const char const_s[] = "const array";
228 RAW_LOG(INFO, "%s", const_s);
229 void* p = reinterpret_cast<void*>(0x12345678);
230 RAW_LOG(INFO, "ptr %p", p);
232 RAW_LOG(INFO, "ptr %p", p);
234 RAW_LOG(ERROR, "%s%d%c%010d%s%1x", foo->c_str(), j, ' ', j, " ", j);
235 RAW_VLOG(0, "foo %d", j);
238 RAW_LOG(INFO, "foo %d", j); // so that have same stderr to compare
240 RAW_DLOG(INFO, "foo %d", j); // test RAW_DLOG in debug mode
243 // test how long messages are chopped:
244 RAW_LOG(WARNING, "Huge string: %s", huge_str.c_str());
245 RAW_VLOG(0, "Huge string: %s", huge_str.c_str());
248 RAW_LOG(INFO, "log");
249 RAW_VLOG(0, "vlog 0 on");
250 RAW_VLOG(1, "vlog 1 off");
251 RAW_VLOG(2, "vlog 2 off");
252 RAW_VLOG(3, "vlog 3 off");
254 RAW_LOG(INFO, "log");
255 RAW_VLOG(1, "vlog 1 on");
256 RAW_VLOG(2, "vlog 2 on");
257 RAW_VLOG(3, "vlog 3 off");
260 RAW_DCHECK(1 == 2, " RAW_DCHECK's shouldn't be compiled in normal mode");
263 RAW_CHECK(1 == 1, "should be ok");
264 RAW_DCHECK(true, "should be ok");
269 void LogWithLevels(int v, int severity, bool err, bool alsoerr) {
271 "Test: v=%d stderrthreshold=%d logtostderr=%d alsologtostderr=%d",
272 v, severity, err, alsoerr);
277 FLAGS_stderrthreshold = severity;
278 FLAGS_logtostderr = err;
279 FLAGS_alsologtostderr = alsoerr;
281 RAW_VLOG(-1, "vlog -1");
282 RAW_VLOG(0, "vlog 0");
283 RAW_VLOG(1, "vlog 1");
284 RAW_LOG(INFO, "log info");
285 RAW_LOG(WARNING, "log warning");
286 RAW_LOG(ERROR, "log error");
288 VLOG(-1) << "vlog -1";
291 LOG(INFO) << "log info";
292 LOG(WARNING) << "log warning";
293 LOG(ERROR) << "log error";
295 VLOG_IF(-1, true) << "vlog_if -1";
296 VLOG_IF(-1, false) << "don't vlog_if -1";
297 VLOG_IF(0, true) << "vlog_if 0";
298 VLOG_IF(0, false) << "don't vlog_if 0";
299 VLOG_IF(1, true) << "vlog_if 1";
300 VLOG_IF(1, false) << "don't vlog_if 1";
301 LOG_IF(INFO, true) << "log_if info";
302 LOG_IF(INFO, false) << "don't log_if info";
303 LOG_IF(WARNING, true) << "log_if warning";
304 LOG_IF(WARNING, false) << "don't log_if warning";
305 LOG_IF(ERROR, true) << "log_if error";
306 LOG_IF(ERROR, false) << "don't log_if error";
309 c = 1; VLOG_IF(100, c -= 2) << "vlog_if 100 expr"; EXPECT_EQ(c, -1);
310 c = 1; VLOG_IF(0, c -= 2) << "vlog_if 0 expr"; EXPECT_EQ(c, -1);
311 c = 1; LOG_IF(INFO, c -= 2) << "log_if info expr"; EXPECT_EQ(c, -1);
312 c = 1; LOG_IF(ERROR, c -= 2) << "log_if error expr"; EXPECT_EQ(c, -1);
313 c = 2; VLOG_IF(0, c -= 2) << "don't vlog_if 0 expr"; EXPECT_EQ(c, 0);
314 c = 2; LOG_IF(ERROR, c -= 2) << "don't log_if error expr"; EXPECT_EQ(c, 0);
316 c = 3; LOG_IF_EVERY_N(INFO, c -= 4, 1) << "log_if info every 1 expr";
318 c = 3; LOG_IF_EVERY_N(ERROR, c -= 4, 1) << "log_if error every 1 expr";
320 c = 4; LOG_IF_EVERY_N(ERROR, c -= 4, 3) << "don't log_if info every 3 expr";
322 c = 4; LOG_IF_EVERY_N(ERROR, c -= 4, 3) << "don't log_if error every 3 expr";
324 c = 5; VLOG_IF_EVERY_N(0, c -= 4, 1) << "vlog_if 0 every 1 expr";
326 c = 5; VLOG_IF_EVERY_N(100, c -= 4, 3) << "vlog_if 100 every 3 expr";
328 c = 6; VLOG_IF_EVERY_N(0, c -= 6, 1) << "don't vlog_if 0 every 1 expr";
330 c = 6; VLOG_IF_EVERY_N(100, c -= 6, 3) << "don't vlog_if 100 every 1 expr";
334 void TestLoggingLevels() {
335 LogWithLevels(0, INFO, false, false);
336 LogWithLevels(1, INFO, false, false);
337 LogWithLevels(-1, INFO, false, false);
338 LogWithLevels(0, WARNING, false, false);
339 LogWithLevels(0, ERROR, false, false);
340 LogWithLevels(0, FATAL, false, false);
341 LogWithLevels(0, FATAL, true, false);
342 LogWithLevels(0, FATAL, false, true);
343 LogWithLevels(1, WARNING, false, false);
344 LogWithLevels(1, FATAL, false, true);
347 TEST(DeathRawCHECK, logging) {
348 ASSERT_DEATH(RAW_CHECK(false, "failure 1"),
349 "RAW: Check false failed: failure 1");
350 ASSERT_DEBUG_DEATH(RAW_DCHECK(1 == 2, "failure 2"),
351 "RAW: Check 1 == 2 failed: failure 2");
354 void TestLogString() {
355 vector<string> errors;
356 vector<string> *no_errors = NULL;
358 LOG_STRING(INFO, &errors) << "LOG_STRING: " << "collected info";
359 LOG_STRING(WARNING, &errors) << "LOG_STRING: " << "collected warning";
360 LOG_STRING(ERROR, &errors) << "LOG_STRING: " << "collected error";
362 LOG_STRING(INFO, no_errors) << "LOG_STRING: " << "reported info";
363 LOG_STRING(WARNING, no_errors) << "LOG_STRING: " << "reported warning";
364 LOG_STRING(ERROR, NULL) << "LOG_STRING: " << "reported error";
366 for (size_t i = 0; i < errors.size(); ++i) {
367 LOG(INFO) << "Captured by LOG_STRING: " << errors[i];
371 class TestLogSinkImpl : public LogSink {
373 vector<string> errors;
374 virtual void send(LogSeverity severity, const char* full_filename,
375 const char* base_filename, int line,
376 const struct tm* tm_time,
377 const char* message, size_t message_len) {
379 ToString(severity, base_filename, line, tm_time, message, message_len));
384 TestLogSinkImpl sink;
385 LogSink *no_sink = NULL;
387 LOG_TO_SINK(&sink, INFO) << "LOG_TO_SINK: " << "collected info";
388 LOG_TO_SINK(&sink, WARNING) << "LOG_TO_SINK: " << "collected warning";
389 LOG_TO_SINK(&sink, ERROR) << "LOG_TO_SINK: " << "collected error";
391 LOG_TO_SINK(no_sink, INFO) << "LOG_TO_SINK: " << "reported info";
392 LOG_TO_SINK(no_sink, WARNING) << "LOG_TO_SINK: " << "reported warning";
393 LOG_TO_SINK(NULL, ERROR) << "LOG_TO_SINK: " << "reported error";
395 LOG(INFO) << "Captured by LOG_TO_SINK:";
396 for (size_t i = 0; i < sink.errors.size(); ++i) {
397 LogMessage("foo", LogMessage::kNoLogPrefix, INFO).stream()
402 // For testing using CHECK*() on anonymous enums.
409 // Tests using CHECK*() on int values.
420 // Tests using CHECK*() on anonymous enums.
421 // Apple's GCC doesn't like this.
422 #if !defined(OS_MACOSX)
423 CHECK_EQ(CASE_A, CASE_A);
424 CHECK_NE(CASE_A, CASE_B);
425 CHECK_GE(CASE_A, CASE_A);
426 CHECK_GE(CASE_B, CASE_A);
427 CHECK_LE(CASE_A, CASE_A);
428 CHECK_LE(CASE_A, CASE_B);
429 CHECK_GT(CASE_B, CASE_A);
430 CHECK_LT(CASE_A, CASE_B);
436 DCHECK( 1 == 2 ) << " DCHECK's shouldn't be compiled in normal mode";
450 CHECK_STREQ("this", "this");
451 CHECK_STREQ(NULL, NULL);
452 CHECK_STRCASEEQ("this", "tHiS");
453 CHECK_STRCASEEQ(NULL, NULL);
454 CHECK_STRNE("this", "tHiS");
455 CHECK_STRNE("this", NULL);
456 CHECK_STRCASENE("this", "that");
457 CHECK_STRCASENE(NULL, "that");
458 CHECK_STREQ((string("a")+"b").c_str(), "ab");
459 CHECK_STREQ(string("test").c_str(),
460 (string("te") + string("st")).c_str());
463 TEST(DeathSTREQ, logging) {
464 ASSERT_DEATH(CHECK_STREQ(NULL, "this"), "");
465 ASSERT_DEATH(CHECK_STREQ("this", "siht"), "");
466 ASSERT_DEATH(CHECK_STRCASEEQ(NULL, "siht"), "");
467 ASSERT_DEATH(CHECK_STRCASEEQ("this", "siht"), "");
468 ASSERT_DEATH(CHECK_STRNE(NULL, NULL), "");
469 ASSERT_DEATH(CHECK_STRNE("this", "this"), "");
470 ASSERT_DEATH(CHECK_STREQ((string("a")+"b").c_str(), "abc"), "");
473 TEST(CheckNOTNULL, Simple) {
475 void *ptr = static_cast<void *>(&t);
476 void *ref = CHECK_NOTNULL(ptr);
478 CHECK_NOTNULL(reinterpret_cast<char *>(&t));
479 CHECK_NOTNULL(reinterpret_cast<unsigned char *>(&t));
480 CHECK_NOTNULL(reinterpret_cast<int *>(&t));
481 CHECK_NOTNULL(reinterpret_cast<int64 *>(&t));
484 TEST(DeathCheckNN, Simple) {
485 ASSERT_DEATH(CHECK_NOTNULL(static_cast<void *>(NULL)), "");
488 // Get list of file names that match pattern
489 static void GetFiles(const string& pattern, vector<string>* files) {
491 #if defined(HAVE_GLOB_H)
493 const int r = glob(pattern.c_str(), 0, NULL, &g);
494 CHECK((r == 0) || (r == GLOB_NOMATCH)) << ": error matching " << pattern;
495 for (int i = 0; i < g.gl_pathc; i++) {
496 files->push_back(string(g.gl_pathv[i]));
499 #elif defined(OS_WINDOWS)
500 WIN32_FIND_DATAA data;
501 HANDLE handle = FindFirstFileA(pattern.c_str(), &data);
502 size_t index = pattern.rfind('\\');
503 if (index == string::npos) {
504 LOG(FATAL) << "No directory separator.";
506 const string dirname = pattern.substr(0, index + 1);
507 if (FAILED(handle)) {
508 // Finding no files is OK.
512 files->push_back(dirname + data.cFileName);
513 } while (FindNextFileA(handle, &data));
514 LOG_SYSRESULT(FindClose(handle));
516 # error There is no way to do glob.
520 // Delete files patching pattern
521 static void DeleteFiles(const string& pattern) {
522 vector<string> files;
523 GetFiles(pattern, &files);
524 for (size_t i = 0; i < files.size(); i++) {
525 CHECK(unlink(files[i].c_str()) == 0) << ": " << strerror(errno);
529 static void CheckFile(const string& name, const string& expected_string) {
530 vector<string> files;
531 GetFiles(name + "*", &files);
532 CHECK_EQ(files.size(), 1);
534 FILE* file = fopen(files[0].c_str(), "r");
535 CHECK(file != NULL) << ": could not open " << files[0];
537 while (fgets(buf, sizeof(buf), file) != NULL) {
538 if (strstr(buf, expected_string.c_str()) != NULL) {
544 LOG(FATAL) << "Did not find " << expected_string << " in " << files[0];
547 static void TestBasename() {
548 fprintf(stderr, "==== Test setting log file basename\n");
549 const string dest = FLAGS_test_tmpdir + "/logging_test_basename";
550 DeleteFiles(dest + "*");
552 SetLogDestination(INFO, dest.c_str());
553 LOG(INFO) << "message to new base";
556 CheckFile(dest, "message to new base");
558 // Release file handle for the destination file to unlock the file in Windows.
560 DeleteFiles(dest + "*");
563 static void TestSymlink() {
565 fprintf(stderr, "==== Test setting log file symlink\n");
566 string dest = FLAGS_test_tmpdir + "/logging_test_symlink";
567 string sym = FLAGS_test_tmpdir + "/symlinkbase";
568 DeleteFiles(dest + "*");
569 DeleteFiles(sym + "*");
571 SetLogSymlink(INFO, "symlinkbase");
572 SetLogDestination(INFO, dest.c_str());
573 LOG(INFO) << "message to new symlink";
575 CheckFile(sym, "message to new symlink");
577 DeleteFiles(dest + "*");
578 DeleteFiles(sym + "*");
582 static void TestExtension() {
583 fprintf(stderr, "==== Test setting log file extension\n");
584 string dest = FLAGS_test_tmpdir + "/logging_test_extension";
585 DeleteFiles(dest + "*");
587 SetLogDestination(INFO, dest.c_str());
588 SetLogFilenameExtension("specialextension");
589 LOG(INFO) << "message to new extension";
591 CheckFile(dest, "message to new extension");
593 // Check that file name ends with extension
594 vector<string> filenames;
595 GetFiles(dest + "*", &filenames);
596 CHECK_EQ(filenames.size(), 1);
597 CHECK(strstr(filenames[0].c_str(), "specialextension") != NULL);
599 // Release file handle for the destination file to unlock the file in Windows.
601 DeleteFiles(dest + "*");
604 struct MyLogger : public base::Logger {
607 virtual void Write(bool should_flush,
611 data.append(message, length);
614 virtual void Flush() { }
616 virtual uint32 LogSize() { return data.length(); }
619 static void TestWrapper() {
620 fprintf(stderr, "==== Test log wrapper\n");
623 base::Logger* old_logger = base::GetLogger(INFO);
624 base::SetLogger(INFO, &my_logger);
625 LOG(INFO) << "Send to wrapped logger";
627 base::SetLogger(INFO, old_logger);
629 CHECK(strstr(my_logger.data.c_str(), "Send to wrapped logger") != NULL);
632 static void TestErrno() {
633 fprintf(stderr, "==== Test errno preservation\n");
637 CHECK_EQ(errno, ENOENT);
640 static void TestOneTruncate(const char *path, int64 limit, int64 keep,
641 int64 dsize, int64 ksize, int64 expect) {
643 CHECK_ERR(fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0600));
645 const char *discardstr = "DISCARDME!", *keepstr = "KEEPME!";
647 // Fill the file with the requested data; first discard data, then kept data
649 while (written < dsize) {
650 int bytes = min<int64>(dsize - written, strlen(discardstr));
651 CHECK_ERR(write(fd, discardstr, bytes));
655 while (written < ksize) {
656 int bytes = min<int64>(ksize - written, strlen(keepstr));
657 CHECK_ERR(write(fd, keepstr, bytes));
661 TruncateLogFile(path, limit, keep);
663 // File should now be shorter
665 CHECK_ERR(fstat(fd, &statbuf));
666 CHECK_EQ(statbuf.st_size, expect);
667 CHECK_ERR(lseek(fd, 0, SEEK_SET));
669 // File should contain the suffix of the original file
670 int buf_size = statbuf.st_size + 1;
671 char* buf = new char[buf_size];
672 memset(buf, 0, sizeof(buf));
673 CHECK_ERR(read(fd, buf, buf_size));
677 while (checked < expect) {
678 int bytes = min<int64>(expect - checked, strlen(keepstr));
679 CHECK(!memcmp(p, keepstr, bytes));
686 static void TestTruncate() {
688 fprintf(stderr, "==== Test log truncation\n");
689 string path = FLAGS_test_tmpdir + "/truncatefile";
691 // Test on a small file
692 TestOneTruncate(path.c_str(), 10, 10, 10, 10, 10);
694 // And a big file (multiple blocks to copy)
695 TestOneTruncate(path.c_str(), 2<<20, 4<<10, 3<<20, 4<<10, 4<<10);
697 // Check edge-case limits
698 TestOneTruncate(path.c_str(), 10, 20, 0, 20, 20);
699 TestOneTruncate(path.c_str(), 10, 0, 0, 0, 0);
700 TestOneTruncate(path.c_str(), 10, 50, 0, 10, 10);
701 TestOneTruncate(path.c_str(), 50, 100, 0, 30, 30);
703 // MacOSX 10.4 doesn't fail in this case.
704 // Windows doesn't have symlink.
705 // Let's just ignore this test for these cases.
706 #if !defined(OS_MACOSX) && !defined(OS_WINDOWS)
707 // Through a symlink should fail to truncate
708 string linkname = path + ".link";
709 unlink(linkname.c_str());
710 CHECK_ERR(symlink(path.c_str(), linkname.c_str()));
711 TestOneTruncate(linkname.c_str(), 10, 10, 0, 30, 30);
714 // The /proc/self path makes sense only for linux.
715 #if defined(OS_LINUX)
716 // Through an open fd symlink should work
718 CHECK_ERR(fd = open(path.c_str(), O_APPEND | O_WRONLY));
720 snprintf(fdpath, sizeof(fdpath), "/proc/self/fd/%d", fd);
721 TestOneTruncate(fdpath, 10, 10, 10, 10, 10);
727 _START_GOOGLE_NAMESPACE_
728 namespace glog_internal_namespace_ {
729 extern // in logging.cc
730 bool SafeFNMatch_(const char* pattern, size_t patt_len,
731 const char* str, size_t str_len);
732 } // namespace glog_internal_namespace_
733 using glog_internal_namespace_::SafeFNMatch_;
734 _END_GOOGLE_NAMESPACE_
736 static bool WrapSafeFNMatch(string pattern, string str) {
739 return SafeFNMatch_(pattern.data(), pattern.size() - 3,
740 str.data(), str.size() - 5);
743 TEST(SafeFNMatch, logging) {
744 CHECK(WrapSafeFNMatch("foo", "foo"));
745 CHECK(!WrapSafeFNMatch("foo", "bar"));
746 CHECK(!WrapSafeFNMatch("foo", "fo"));
747 CHECK(!WrapSafeFNMatch("foo", "foo2"));
748 CHECK(WrapSafeFNMatch("bar/foo.ext", "bar/foo.ext"));
749 CHECK(WrapSafeFNMatch("*ba*r/fo*o.ext*", "bar/foo.ext"));
750 CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/baz.ext"));
751 CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/foo"));
752 CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/foo.ext.zip"));
753 CHECK(WrapSafeFNMatch("ba?/*.ext", "bar/foo.ext"));
754 CHECK(WrapSafeFNMatch("ba?/*.ext", "baZ/FOO.ext"));
755 CHECK(!WrapSafeFNMatch("ba?/*.ext", "barr/foo.ext"));
756 CHECK(!WrapSafeFNMatch("ba?/*.ext", "bar/foo.ext2"));
757 CHECK(WrapSafeFNMatch("ba?/*", "bar/foo.ext2"));
758 CHECK(WrapSafeFNMatch("ba?/*", "bar/"));
759 CHECK(!WrapSafeFNMatch("ba?/?", "bar/"));
760 CHECK(!WrapSafeFNMatch("ba?/*", "bar"));
763 // TestWaitingLogSink will save messages here
764 // No lock: Accessed only by TestLogSinkWriter thread
765 // and after its demise by its creator.
766 static vector<string> global_messages;
768 // helper for TestWaitingLogSink below.
769 // Thread that does the logic of TestWaitingLogSink
770 // It's free to use LOG() itself.
771 class TestLogSinkWriter : public Thread {
774 TestLogSinkWriter() : should_exit_(false) {
779 // Just buffer it (can't use LOG() here).
780 void Buffer(const string& message) {
782 RAW_LOG(INFO, "Buffering");
783 messages_.push(message);
785 RAW_LOG(INFO, "Buffered");
788 // Wait for the buffer to clear (can't use LOG() here).
790 RAW_LOG(INFO, "Waiting");
794 SleepForMilliseconds(1);
797 RAW_LOG(INFO, "Waited");
801 // Trigger thread exit.
803 MutexLock l(&mutex_);
809 // helpers ---------------
811 // For creating a "Condition".
812 bool NoWork() { return messages_.empty(); }
813 bool HaveWork() { return !messages_.empty() || should_exit_; }
815 // Thread body; CAN use LOG() here!
819 while (!HaveWork()) {
821 SleepForMilliseconds(1);
824 if (should_exit_ && messages_.empty()) {
828 // Give the main thread time to log its message,
829 // so that we get a reliable log capture to compare to golden file.
830 // Same for the other sleep below.
831 SleepForMilliseconds(20);
832 RAW_LOG(INFO, "Sink got a messages"); // only RAW_LOG under mutex_ here
833 string message = messages_.front();
835 // Normally this would be some more real/involved logging logic
836 // where LOG() usage can't be eliminated,
837 // e.g. pushing the message over with an RPC:
838 int messages_left = messages_.size();
840 SleepForMilliseconds(20);
841 // May not use LOG while holding mutex_, because Buffer()
842 // acquires mutex_, and Buffer is called from LOG(),
843 // which has its own internal mutex:
844 // LOG()->LogToSinks()->TestWaitingLogSink::send()->Buffer()
845 LOG(INFO) << "Sink is sending out a message: " << message;
846 LOG(INFO) << "Have " << messages_left << " left";
847 global_messages.push_back(message);
851 // data ---------------
855 queue<string> messages_; // messages to be logged
858 // A log sink that exercises WaitTillSent:
859 // it pushes data to a buffer and wakes up another thread to do the logging
860 // (that other thread can than use LOG() itself),
861 class TestWaitingLogSink : public LogSink {
864 TestWaitingLogSink() {
865 tid_ = pthread_self(); // for thread-specific behavior
868 ~TestWaitingLogSink() {
874 // (re)define LogSink interface
876 virtual void send(LogSeverity severity, const char* full_filename,
877 const char* base_filename, int line,
878 const struct tm* tm_time,
879 const char* message, size_t message_len) {
880 // Push it to Writer thread if we are the original logging thread.
881 // Note: Something like ThreadLocalLogSink is a better choice
882 // to do thread-specific LogSink logic for real.
883 if (pthread_equal(tid_, pthread_self())) {
884 writer_.Buffer(ToString(severity, base_filename, line,
885 tm_time, message, message_len));
888 virtual void WaitTillSent() {
889 // Wait for Writer thread if we are the original logging thread.
890 if (pthread_equal(tid_, pthread_self())) writer_.Wait();
896 TestLogSinkWriter writer_;
899 // Check that LogSink::WaitTillSent can be used in the advertised way.
900 // We also do golden-stderr comparison.
901 static void TestLogSinkWaitTillSent() {
902 { TestWaitingLogSink sink;
903 // Sleeps give the sink threads time to do all their work,
904 // so that we get a reliable log capture to compare to the golden file.
905 LOG(INFO) << "Message 1";
906 SleepForMilliseconds(60);
907 LOG(ERROR) << "Message 2";
908 SleepForMilliseconds(60);
909 LOG(WARNING) << "Message 3";
910 SleepForMilliseconds(60);
912 for (size_t i = 0; i < global_messages.size(); ++i) {
913 LOG(INFO) << "Sink capture: " << global_messages[i];
915 CHECK_EQ(global_messages.size(), 3);
918 TEST(Strerror, logging) {
920 char *msg = strdup(strerror(errcode));
921 int buf_size = strlen(msg) + 1;
922 char *buf = new char[buf_size];
923 CHECK_EQ(posix_strerror_r(errcode, NULL, 0), -1);
925 CHECK_EQ(posix_strerror_r(errcode, buf, 0), -1);
926 CHECK_EQ(buf[0], 'A');
927 CHECK_EQ(posix_strerror_r(errcode, NULL, buf_size), -1);
928 #if defined(OS_MACOSX) || defined(OS_FREEBSD)
929 // MacOSX or FreeBSD considers this case is an error since there is
931 CHECK_EQ(posix_strerror_r(errcode, buf, 1), -1);
933 CHECK_EQ(posix_strerror_r(errcode, buf, 1), 0);
935 CHECK_STREQ(buf, "");
936 CHECK_EQ(posix_strerror_r(errcode, buf, buf_size), 0);
937 CHECK_STREQ(buf, msg);
942 // Simple routines to look at the sizes of generated code for LOG(FATAL) and
943 // CHECK(..) via objdump
945 LOG(FATAL) << "Failed";
947 void MyCheck(bool a, bool b) {
951 struct UserDefinedClass {
952 bool operator==(const UserDefinedClass& rhs) const { return true; }
955 inline ostream& operator<<(ostream& out, const UserDefinedClass& u) {
960 TEST(UserDefinedClass, logging) {
963 LOG_STRING(INFO, &buf) << u;
964 CHECK_EQ(1, buf.size());
965 CHECK(buf[0].find("OK") != string::npos);
967 // We must be able to compile this.