43 #ifdef HAVE_SYS_WAIT_H
44 # include <sys/wait.h>
59 #include <glog/logging.h>
60 #include <glog/raw_logging.h>
65 #ifdef HAVE_LIB_GFLAGS
66 #include <gflags/gflags.h>
67 using namespace GFLAGS_NAMESPACE;
76 using testing::HasSubstr;
81 using GOOGLE_NAMESPACE::glog_testing::ScopedMockLog;
95 _END_GOOGLE_NAMESPACE_
135 static void CheckFailure(
int a,
int b,
const char* file,
int line,
const char* msg);
180 VLOG(1) <<
"test message";
185 int
main(
int argc,
char **argv) {
186 FLAGS_colorlogtostderr =
false;
187 FLAGS_timestamp_in_logfile_name =
true;
191 setbuf(stderr,
NULL);
211 #ifdef HAVE_LIB_GMOCK
215 #ifdef HAVE_LIB_GFLAGS
245 FLAGS_logtostdout =
true;
259 FLAGS_logtostdout =
false;
272 fprintf(
stdout,
"PASS\n");
282 for (
int i = 0;
i < 10; ++
i ) {
283 int old_errno =
errno;
285 PLOG_EVERY_N(
ERROR, 2) <<
"Plog every 2, iteration " << COUNTER;
288 LOG_EVERY_N(
ERROR, 3) <<
"Log every 3, iteration " << COUNTER << endl;
289 LOG_EVERY_N(
ERROR, 4) <<
"Log every 4, iteration " << COUNTER << endl;
291 LOG_IF_EVERY_N(
WARNING,
true, 5) <<
"Log if every 5, iteration " << COUNTER;
292 LOG_IF_EVERY_N(
WARNING,
false, 3)
293 <<
"Log if every 3, iteration " << COUNTER;
294 LOG_IF_EVERY_N(
INFO,
true, 1) <<
"Log if every 1, iteration " << COUNTER;
295 LOG_IF_EVERY_N(
ERROR, (
i < 3), 2)
296 <<
"Log if less than 3 every 2, iteration " << COUNTER;
298 LOG_IF(
WARNING,
true) <<
"log_if this";
299 LOG_IF(
WARNING,
false) <<
"don't log_if this";
303 const char const_s[] =
"const array";
306 LOG(
ERROR) <<
string(
"foo") <<
' '<< j <<
' ' << setw(10) << j <<
" "
307 << setw(1) << hex << j;
308 LOG(
INFO) <<
"foo " << std::setw(10) << 1.0;
311 google::LogMessage outer(__FILE__, __LINE__,
GLOG_ERROR);
312 outer.stream() <<
"outer";
339 TEST(DeathNoAllocNewHook, logging) {
344 },
"unexpected new");
349 string huge_str(50000,
'a');
356 RAW_LOG(
INFO,
"%s%s%d%c%f",
foo->c_str(),
"bar ", 10,
' ', 3.4);
359 const char const_s[] =
"const array";
360 RAW_LOG(
INFO,
"%s", const_s);
362 RAW_LOG(
INFO,
"ptr %p",
p);
364 RAW_LOG(
INFO,
"ptr %p",
p);
366 RAW_LOG(
ERROR,
"%s%d%c%010d%s%1x",
foo->c_str(), j,
' ', j,
" ", j);
367 RAW_VLOG(0,
"foo %d", j);
370 RAW_LOG(
INFO,
"foo %d", j);
372 RAW_DLOG(
INFO,
"foo %d", j);
376 RAW_LOG(
WARNING,
"Huge string: %s", huge_str.c_str());
377 RAW_VLOG(0,
"Huge string: %s", huge_str.c_str());
380 RAW_LOG(
INFO,
"log");
381 RAW_VLOG(0,
"vlog 0 on");
382 RAW_VLOG(1,
"vlog 1 off");
383 RAW_VLOG(2,
"vlog 2 off");
384 RAW_VLOG(3,
"vlog 3 off");
386 RAW_LOG(
INFO,
"log");
387 RAW_VLOG(1,
"vlog 1 on");
388 RAW_VLOG(2,
"vlog 2 on");
389 RAW_VLOG(3,
"vlog 3 off");
392 RAW_DCHECK(1 == 2,
" RAW_DCHECK's shouldn't be compiled in normal mode");
395 RAW_CHECK(1 == 1,
"should be ok");
396 RAW_DCHECK(
true,
"should be ok");
403 "Test: v=%d stderrthreshold=%d logtostderr=%d alsologtostderr=%d",
413 RAW_VLOG(-1,
"vlog -1");
414 RAW_VLOG(0,
"vlog 0");
415 RAW_VLOG(1,
"vlog 1");
416 RAW_LOG(
INFO,
"log info");
417 RAW_LOG(
WARNING,
"log warning");
418 RAW_LOG(
ERROR,
"log error");
420 VLOG(-1) <<
"vlog -1";
427 VLOG_IF(-1,
true) <<
"vlog_if -1";
428 VLOG_IF(-1,
false) <<
"don't vlog_if -1";
429 VLOG_IF(0,
true) <<
"vlog_if 0";
430 VLOG_IF(0,
false) <<
"don't vlog_if 0";
431 VLOG_IF(1,
true) <<
"vlog_if 1";
432 VLOG_IF(1,
false) <<
"don't vlog_if 1";
433 LOG_IF(
INFO,
true) <<
"log_if info";
434 LOG_IF(
INFO,
false) <<
"don't log_if info";
435 LOG_IF(
WARNING,
true) <<
"log_if warning";
436 LOG_IF(
WARNING,
false) <<
"don't log_if warning";
437 LOG_IF(
ERROR,
true) <<
"log_if error";
438 LOG_IF(
ERROR,
false) <<
"don't log_if error";
441 c = 1; VLOG_IF(100, c -= 2) <<
"vlog_if 100 expr";
EXPECT_EQ(c, -1);
442 c = 1; VLOG_IF(0, c -= 2) <<
"vlog_if 0 expr";
EXPECT_EQ(c, -1);
443 c = 1; LOG_IF(
INFO, c -= 2) <<
"log_if info expr";
EXPECT_EQ(c, -1);
444 c = 1; LOG_IF(
ERROR, c -= 2) <<
"log_if error expr";
EXPECT_EQ(c, -1);
445 c = 2; VLOG_IF(0, c -= 2) <<
"don't vlog_if 0 expr";
EXPECT_EQ(c, 0);
446 c = 2; LOG_IF(
ERROR, c -= 2) <<
"don't log_if error expr";
EXPECT_EQ(c, 0);
448 c = 3; LOG_IF_EVERY_N(
INFO, c -= 4, 1) <<
"log_if info every 1 expr";
450 c = 3; LOG_IF_EVERY_N(
ERROR, c -= 4, 1) <<
"log_if error every 1 expr";
452 c = 4; LOG_IF_EVERY_N(
ERROR, c -= 4, 3) <<
"don't log_if info every 3 expr";
454 c = 4; LOG_IF_EVERY_N(
ERROR, c -= 4, 3) <<
"don't log_if error every 3 expr";
456 c = 5; VLOG_IF_EVERY_N(0, c -= 4, 1) <<
"vlog_if 0 every 1 expr";
458 c = 5; VLOG_IF_EVERY_N(100, c -= 4, 3) <<
"vlog_if 100 every 3 expr";
460 c = 6; VLOG_IF_EVERY_N(0, c -= 6, 1) <<
"don't vlog_if 0 every 1 expr";
462 c = 6; VLOG_IF_EVERY_N(100, c -= 6, 3) <<
"don't vlog_if 100 every 1 expr";
490 #if defined(__GNUC__)
499 "RAW: Check false failed: failure 1");
501 "RAW: Check 1 == 2 failed: failure 2");
506 vector<string> *no_errors =
NULL;
516 for (
size_t i = 0;
i <
errors.size(); ++
i) {
523 string* no_error =
NULL;
525 LOG_TO_STRING(
INFO, &
error) <<
"LOG_TO_STRING: " <<
"collected info";
527 LOG_TO_STRING(
WARNING, &
error) <<
"LOG_TO_STRING: " <<
"collected warning";
529 LOG_TO_STRING(
ERROR, &
error) <<
"LOG_TO_STRING: " <<
"collected error";
532 LOG_TO_STRING(
INFO, no_error) <<
"LOG_TO_STRING: " <<
"reported info";
533 LOG_TO_STRING(
WARNING, no_error) <<
"LOG_TO_STRING: " <<
"reported warning";
534 LOG_TO_STRING(
ERROR,
NULL) <<
"LOG_TO_STRING: " <<
"reported error";
541 const char* base_filename,
int line,
542 const LogMessageTime &logmsgtime,
543 const char*
message,
size_t message_len) {
545 ToString(
severity, base_filename, line, logmsgtime,
message, message_len));
551 LogSink *no_sink =
NULL;
553 LOG_TO_SINK(&sink,
INFO) <<
"LOG_TO_SINK: " <<
"collected info";
554 LOG_TO_SINK(&sink,
WARNING) <<
"LOG_TO_SINK: " <<
"collected warning";
555 LOG_TO_SINK(&sink,
ERROR) <<
"LOG_TO_SINK: " <<
"collected error";
557 LOG_TO_SINK(no_sink,
INFO) <<
"LOG_TO_SINK: " <<
"reported info";
558 LOG_TO_SINK(no_sink,
WARNING) <<
"LOG_TO_SINK: " <<
"reported warning";
559 LOG_TO_SINK(
NULL,
ERROR) <<
"LOG_TO_SINK: " <<
"reported error";
561 LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink,
INFO)
562 <<
"LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " <<
"collected info";
563 LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink,
WARNING)
564 <<
"LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " <<
"collected warning";
565 LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink,
ERROR)
566 <<
"LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " <<
"collected error";
568 LOG_TO_SINK_BUT_NOT_TO_LOGFILE(no_sink,
INFO)
569 <<
"LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " <<
"thrashed info";
570 LOG_TO_SINK_BUT_NOT_TO_LOGFILE(no_sink,
WARNING)
571 <<
"LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " <<
"thrashed warning";
572 LOG_TO_SINK_BUT_NOT_TO_LOGFILE(
NULL,
ERROR)
573 <<
"LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " <<
"thrashed error";
575 LOG(
INFO) <<
"Captured by LOG_TO_SINK:";
576 for (
size_t i = 0;
i < sink.
errors.size(); ++
i) {
602 #if !defined(GLOG_OS_MACOSX)
616 DCHECK( 1 == 2 ) <<
" DCHECK's shouldn't be compiled in normal mode";
629 int64* ptr = DCHECK_NOTNULL(orig_ptr);
635 CHECK_STREQ(
"this",
"this");
637 CHECK_STRCASEEQ(
"this",
"tHiS");
639 CHECK_STRNE(
"this",
"tHiS");
640 CHECK_STRNE(
"this",
NULL);
641 CHECK_STRCASENE(
"this",
"that");
642 CHECK_STRCASENE(
NULL,
"that");
643 CHECK_STREQ((
string(
"a")+
"b").c_str(),
"ab");
644 CHECK_STREQ(
string(
"test").c_str(),
645 (
string(
"te") +
string(
"st")).c_str());
655 ASSERT_DEATH(CHECK_STREQ((
string(
"a")+
"b").c_str(),
"abc"),
"");
660 void *ptr =
static_cast<void *
>(&t);
661 void *
ref = CHECK_NOTNULL(ptr);
663 CHECK_NOTNULL(
reinterpret_cast<char *
>(ptr));
664 CHECK_NOTNULL(
reinterpret_cast<unsigned char *
>(ptr));
665 CHECK_NOTNULL(
reinterpret_cast<int *
>(ptr));
666 CHECK_NOTNULL(
reinterpret_cast<int64 *
>(ptr));
674 static void GetFiles(
const string& pattern, vector<string>* files) {
676 #if defined(HAVE_GLOB_H)
678 const int r = glob(pattern.c_str(), 0,
NULL, &
g);
679 CHECK((
r == 0) || (
r == GLOB_NOMATCH)) <<
": error matching " << pattern;
680 for (
size_t i = 0;
i <
g.gl_pathc;
i++) {
681 files->push_back(
string(
g.gl_pathv[
i]));
684 #elif defined(GLOG_OS_WINDOWS)
685 WIN32_FIND_DATAA
data;
686 HANDLE handle = FindFirstFileA(pattern.c_str(), &
data);
687 size_t index = pattern.rfind(
'\\');
688 if (
index == string::npos) {
689 LOG(
FATAL) <<
"No directory separator.";
691 const string dirname = pattern.substr(0,
index + 1);
692 if (handle == INVALID_HANDLE_VALUE) {
697 files->push_back(dirname +
data.cFileName);
698 }
while (FindNextFileA(handle, &
data));
699 BOOL result = FindClose(handle);
700 LOG_SYSRESULT(result != 0);
702 # error There is no way to do glob.
708 vector<string> files;
710 for (
size_t i = 0;
i < files.size();
i++) {
716 static void CheckFile(
const string&
name,
const string& expected_string,
const bool checkInFileOrNot =
true) {
717 vector<string> files;
721 FILE* file = fopen(files[0].c_str(),
"r");
722 CHECK(file !=
NULL) <<
": could not open " << files[0];
724 while (fgets(
buf,
sizeof(
buf), file) !=
NULL) {
725 char*
first = strstr(
buf, expected_string.c_str());
728 if (checkInFileOrNot != (
first ==
NULL)) {
734 LOG(
FATAL) <<
"Did " << (checkInFileOrNot?
"not " :
"") <<
"find " << expected_string <<
" in " << files[0];
738 fprintf(stderr,
"==== Test setting log file basename\n");
739 const string dest = FLAGS_test_tmpdir +
"/logging_test_basename";
743 LOG(
INFO) <<
"message to new base";
754 fprintf(stderr,
"==== Test setting log file basename without timestamp and appending properly\n");
755 const string dest = FLAGS_test_tmpdir +
"/logging_test_basename_append_when_no_timestamp";
758 ofstream out(
dest.c_str());
759 out <<
"test preexisting content" << endl;
764 FLAGS_timestamp_in_logfile_name=
false;
766 LOG(
INFO) <<
"message to new base, appending to preexisting file";
768 FLAGS_timestamp_in_logfile_name=
true;
772 CheckFile(
dest,
"message to new base, appending to preexisting file");
781 #if defined(HAVE_SYS_WAIT_H) && defined(HAVE_UNISTD_H) && defined(HAVE_FCNTL)
782 fprintf(stderr,
"==== Test setting log file basename and two processes writing - second should fail\n");
783 const string dest = FLAGS_test_tmpdir +
"/logging_test_basename_two_processes_writing";
787 FLAGS_timestamp_in_logfile_name=
false;
789 LOG(
INFO) <<
"message to new base, parent";
795 LOG(
INFO) <<
"message to new base, child - should only appear on STDERR not on the file";
798 }
else if (pid > 0) {
801 FLAGS_timestamp_in_logfile_name=
true;
804 CheckFile(
dest,
"message to new base, child - should only appear on STDERR not on the file",
false);
813 #ifndef GLOG_OS_WINDOWS
814 fprintf(stderr,
"==== Test setting log file symlink\n");
815 string dest = FLAGS_test_tmpdir +
"/logging_test_symlink";
816 string sym = FLAGS_test_tmpdir +
"/symlinkbase";
822 LOG(
INFO) <<
"message to new symlink";
824 CheckFile(sym,
"message to new symlink");
832 fprintf(stderr,
"==== Test setting log file extension\n");
833 string dest = FLAGS_test_tmpdir +
"/logging_test_extension";
838 LOG(
INFO) <<
"message to new extension";
843 vector<string> filenames;
846 CHECK(strstr(filenames[0].c_str(),
"specialextension") !=
NULL);
853 struct MyLogger :
public base::Logger {
869 fprintf(stderr,
"==== Test log wrapper\n");
872 base::Logger* old_logger = base::GetLogger(
GLOG_INFO);
874 LOG(
INFO) <<
"Send to wrapped logger";
878 CHECK(strstr(my_logger.
data.c_str(),
"Send to wrapped logger") !=
NULL);
882 fprintf(stderr,
"==== Test errno preservation\n");
890 size_t dsize,
size_t ksize,
size_t expect) {
892 CHECK_ERR(fd = open(
path, O_RDWR | O_CREAT | O_TRUNC, 0600));
894 const char *discardstr =
"DISCARDME!", *keepstr =
"KEEPME!";
895 const size_t discard_size = strlen(discardstr), keep_size = strlen(keepstr);
899 while (written < dsize) {
900 size_t bytes = min(dsize - written, discard_size);
901 CHECK_ERR(write(fd, discardstr,
bytes));
905 while (written < ksize) {
906 size_t bytes = min(ksize - written, keep_size);
907 CHECK_ERR(write(fd, keepstr,
bytes));
915 CHECK_ERR(fstat(fd, &statbuf));
916 CHECK_EQ(
static_cast<size_t>(statbuf.st_size), expect);
917 CHECK_ERR(lseek(fd, 0, SEEK_SET));
920 const size_t buf_size =
static_cast<size_t>(statbuf.st_size) + 1;
921 char*
buf =
new char[buf_size];
922 memset(
buf, 0, buf_size);
923 CHECK_ERR(read(fd,
buf, buf_size));
927 while (checked < expect) {
928 size_t bytes = min(expect - checked, keep_size);
938 fprintf(stderr,
"==== Test log truncation\n");
939 string path = FLAGS_test_tmpdir +
"/truncatefile";
957 #if !defined(GLOG_OS_MACOSX) && !defined(GLOG_OS_WINDOWS)
959 string linkname =
path +
".link";
960 unlink(linkname.c_str());
961 CHECK_ERR(symlink(
path.c_str(), linkname.c_str()));
966 #if defined(GLOG_OS_LINUX)
969 CHECK_ERR(fd = open(
path.c_str(), O_APPEND | O_WRONLY));
971 snprintf(fdpath,
sizeof(fdpath),
"/proc/self/fd/%d", fd);
980 base::Logger* wrapped_logger) :
981 set_on_destruction_(set_on_destruction),
982 wrapped_logger_(wrapped_logger)
984 *set_on_destruction_ =
false;
987 *set_on_destruction_ =
true;
989 virtual void Write(
bool force_flush,
993 wrapped_logger_->Write(force_flush, timestamp,
message,
length);
995 virtual void Flush() { wrapped_logger_->Flush(); }
998 bool* set_on_destruction_;
999 base::Logger* wrapped_logger_;
1003 bool custom_logger_deleted =
false;
1028 #if defined(HAVE_CXX11_CHRONO) && __cplusplus >= 201103L
1031 size_t m_streamTimes;
1043 const std::chrono::steady_clock::time_point&
end) {
1044 return std::chrono::duration_cast<std::chrono::nanoseconds>((
end -
begin))
1047 #elif defined(GLOG_OS_WINDOWS)
1050 size_t m_streamTimes;
1060 QueryPerformanceFrequency(&freq);
1061 return (
end.QuadPart -
begin.QuadPart) * LONGLONG(1000000000) / freq.QuadPart;
1075 return (
end.tv_sec -
begin.tv_sec) * 1000000000 +
1081 fprintf(stderr,
"==== Test log periodically\n");
1088 LOG_EVERY_T(
INFO, LOG_PERIOD_SEC)
1089 << timeLogger <<
"Timed Message #" << timeLogger.
m_streamTimes;
1101 int64 time_ns = nsBetweenCalls[
idx];
1109 bool SafeFNMatch_(
const char* pattern,
size_t patt_len,
1110 const char*
str,
size_t str_len);
1113 _END_GOOGLE_NAMESPACE_
1118 return SafeFNMatch_(pattern.data(), pattern.size() - 3,
1119 str.data(),
str.size() - 5);
1161 RAW_LOG(
INFO,
"Buffering");
1164 RAW_LOG(
INFO,
"Buffered");
1169 RAW_LOG(
INFO,
"Waiting");
1176 RAW_LOG(
INFO,
"Waited");
1183 should_exit_ =
true;
1192 bool HaveWork() {
return !messages_.empty() || should_exit_; }
1198 while (!HaveWork()) {
1203 if (should_exit_ && messages_.empty()) {
1211 RAW_LOG(
INFO,
"Sink got a messages");
1212 string message = messages_.front();
1217 size_t messages_left = messages_.size();
1225 LOG(
INFO) <<
"Have " << messages_left <<
" left";
1244 tid_ = pthread_self();
1256 const char* base_filename,
int line,
1257 const LogMessageTime &logmsgtime,
1258 const char*
message,
size_t message_len) {
1262 if (pthread_equal(tid_, pthread_self())) {
1263 writer_.Buffer(ToString(
severity, base_filename, line,
1264 logmsgtime,
message, message_len));
1270 if (pthread_equal(tid_, pthread_self())) writer_.Wait();
1302 int errcode =
EINTR;
1303 char *msg = strdup(
strerror(errcode));
1304 const size_t buf_size = strlen(msg) + 1;
1305 char *
buf =
new char[buf_size];
1311 #if defined(GLOG_OS_MACOSX) || defined(GLOG_OS_FREEBSD) || defined(GLOG_OS_OPENBSD)
1318 CHECK_STREQ(
buf,
"");
1320 CHECK_STREQ(
buf, msg);
1336 #ifdef HAVE_LIB_GMOCK
1338 TEST(DVLog, Basic) {
1349 DVLOG(1) <<
"debug log";
1359 DVLOG(1) <<
"debug log";
1362 TEST(LogAtLevel, Basic) {
1370 LogAtLevel(
severity,
"function version");
1374 LOG_AT_LEVEL(
severity) <<
"macro" <<
' ' <<
"version";
1377 TEST(TestExitOnDFatal, ToBeOrNotToBe) {
1398 LOG(DFATAL) <<
"This should not be fatal";
1405 #ifdef GTEST_HAS_DEATH_TEST
1407 EXPECT_DEBUG_DEATH({
1408 LOG(DFATAL) <<
"This should be fatal in debug mode";
1409 },
"This should be fatal in debug mode");
1413 #ifdef HAVE_STACKTRACE
1415 static void BacktraceAtHelper() {
1421 static int kBacktraceAtLine = __LINE__ - 2;
1423 TEST(LogBacktraceAt, DoesNotBacktraceWhenDisabled) {
1424 StrictMock<ScopedMockLog> log;
1426 FLAGS_log_backtrace_at =
"";
1431 BacktraceAtHelper();
1434 TEST(LogBacktraceAt, DoesBacktraceAtRightLineWhenEnabled) {
1435 StrictMock<ScopedMockLog> log;
1439 FLAGS_log_backtrace_at = where;
1446 HasSubstr(
"BacktraceAtHelper"),
1448 HasSubstr(
"Backtrace me"))));
1452 BacktraceAtHelper();
1455 #endif // HAVE_STACKTRACE
1457 #endif // HAVE_LIB_GMOCK
1473 CHECK(
buf[0].find(
"OK") != string::npos);