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>
67
#include <gmock/gmock.h>
69
// Introduce several symbols from gmock.
71
using testing::AnyNumber;
72
using testing::HasSubstr;
75
using testing::StrictMock;
76
using testing::InitGoogleMock;
77
using GOOGLE_NAMESPACE::glog_testing::ScopedMockLog;
81
using namespace GOOGLE_NAMESPACE;
83
// Some non-advertised functions that we want to test or use.
84
_START_GOOGLE_NAMESPACE_
87
bool GetExitOnDFatal();
88
void SetExitOnDFatal(bool value);
89
} // namespace internal
91
_END_GOOGLE_NAMESPACE_
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();
112
static void BM_Check1(int n) {
124
BENCHMARK(BM_Check1);
126
static void CheckFailure(int a, int b, const char* file, int line, const char* msg);
127
static void BM_Check3(int n) {
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");
139
BENCHMARK(BM_Check3);
141
static void BM_Check2(int n) {
156
BENCHMARK(BM_Check2);
158
static void CheckFailure(int, int, const char* /* file */, int /* line */,
159
const char* /* msg */) {
162
static void BM_logspeed(int n) {
164
LOG(INFO) << "test message";
167
BENCHMARK(BM_logspeed);
169
static void BM_vlog(int n) {
171
VLOG(1) << "test message";
176
int main(int argc, char **argv) {
177
#ifdef HAVE_LIB_GFLAGS
178
ParseCommandLineFlags(&argc, &argv, true);
181
// Test some basics before InitGoogleLogging:
183
LogWithLevels(FLAGS_v, FLAGS_stderrthreshold,
184
FLAGS_logtostderr, FLAGS_alsologtostderr);
185
LogWithLevels(0, 0, 0, 0); // simulate "before global c-tors"
186
const string early_stderr = GetCapturedTestStderr();
188
InitGoogleLogging(argv[0]);
190
RunSpecifiedBenchmarks();
192
FLAGS_logtostderr = true;
194
InitGoogleTest(&argc, argv);
195
#ifdef HAVE_LIB_GMOCK
196
InitGoogleMock(&argc, argv);
199
// so that death tests run before we use threads
200
CHECK_EQ(RUN_ALL_TESTS(), 0);
204
// re-emit early_stderr
205
LogMessage("dummy", LogMessage::kNoLogPrefix, GLOG_INFO).stream() << early_stderr;
213
TestLogSinkWaitTillSent();
218
// TODO: The golden test portion of this test is very flakey.
220
MungeAndDiffTestStderr(FLAGS_test_srcdir + "/src/logging_unittest.err"));
222
FLAGS_logtostderr = false;
231
ShutdownGoogleLogging();
233
fprintf(stdout, "PASS\n");
237
void TestLogging(bool check_counts) {
238
int64 base_num_infos = LogMessage::num_messages(GLOG_INFO);
239
int64 base_num_warning = LogMessage::num_messages(GLOG_WARNING);
240
int64 base_num_errors = LogMessage::num_messages(GLOG_ERROR);
242
LOG(INFO) << string("foo ") << "bar " << 10 << ' ' << 3.4;
243
for ( int i = 0; i < 10; ++i ) {
244
int old_errno = errno;
246
PLOG_EVERY_N(ERROR, 2) << "Plog every 2, iteration " << COUNTER;
249
LOG_EVERY_N(ERROR, 3) << "Log every 3, iteration " << COUNTER << endl;
250
LOG_EVERY_N(ERROR, 4) << "Log every 4, iteration " << COUNTER << endl;
252
LOG_IF_EVERY_N(WARNING, true, 5) << "Log if every 5, iteration " << COUNTER;
253
LOG_IF_EVERY_N(WARNING, false, 3)
254
<< "Log if every 3, iteration " << COUNTER;
255
LOG_IF_EVERY_N(INFO, true, 1) << "Log if every 1, iteration " << COUNTER;
256
LOG_IF_EVERY_N(ERROR, (i < 3), 2)
257
<< "Log if less than 3 every 2, iteration " << COUNTER;
259
LOG_IF(WARNING, true) << "log_if this";
260
LOG_IF(WARNING, false) << "don't log_if this";
264
const char const_s[] = "const array";
265
LOG(INFO) << const_s;
267
LOG(ERROR) << string("foo") << ' '<< j << ' ' << setw(10) << j << " "
268
<< setw(1) << hex << j;
270
LogMessage("foo", LogMessage::kNoLogPrefix, GLOG_INFO).stream() << "no prefix";
273
CHECK_EQ(base_num_infos + 14, LogMessage::num_messages(GLOG_INFO));
274
CHECK_EQ(base_num_warning + 3, LogMessage::num_messages(GLOG_WARNING));
275
CHECK_EQ(base_num_errors + 15, LogMessage::num_messages(GLOG_ERROR));
279
static void NoAllocNewHook() {
280
CHECK(false) << "unexpected new";
285
g_new_hook = &NoAllocNewHook;
292
TEST(DeathNoAllocNewHook, logging) {
293
// tests that NewHook used below works
297
}, "unexpected new");
300
void TestRawLogging() {
301
string* foo = new string("foo ");
302
string huge_str(50000, 'a');
306
// Check that RAW loggging does not use mallocs.
309
RAW_LOG(INFO, "%s%s%d%c%f", foo->c_str(), "bar ", 10, ' ', 3.4);
311
RAW_LOG(WARNING, "%s", s);
312
const char const_s[] = "const array";
313
RAW_LOG(INFO, "%s", const_s);
314
void* p = reinterpret_cast<void*>(0x12345678);
315
RAW_LOG(INFO, "ptr %p", p);
317
RAW_LOG(INFO, "ptr %p", p);
319
RAW_LOG(ERROR, "%s%d%c%010d%s%1x", foo->c_str(), j, ' ', j, " ", j);
320
RAW_VLOG(0, "foo %d", j);
323
RAW_LOG(INFO, "foo %d", j); // so that have same stderr to compare
325
RAW_DLOG(INFO, "foo %d", j); // test RAW_DLOG in debug mode
328
// test how long messages are chopped:
329
RAW_LOG(WARNING, "Huge string: %s", huge_str.c_str());
330
RAW_VLOG(0, "Huge string: %s", huge_str.c_str());
333
RAW_LOG(INFO, "log");
334
RAW_VLOG(0, "vlog 0 on");
335
RAW_VLOG(1, "vlog 1 off");
336
RAW_VLOG(2, "vlog 2 off");
337
RAW_VLOG(3, "vlog 3 off");
339
RAW_LOG(INFO, "log");
340
RAW_VLOG(1, "vlog 1 on");
341
RAW_VLOG(2, "vlog 2 on");
342
RAW_VLOG(3, "vlog 3 off");
345
RAW_DCHECK(1 == 2, " RAW_DCHECK's shouldn't be compiled in normal mode");
348
RAW_CHECK(1 == 1, "should be ok");
349
RAW_DCHECK(true, "should be ok");
354
void LogWithLevels(int v, int severity, bool err, bool alsoerr) {
356
"Test: v=%d stderrthreshold=%d logtostderr=%d alsologtostderr=%d",
357
v, severity, err, alsoerr);
362
FLAGS_stderrthreshold = severity;
363
FLAGS_logtostderr = err;
364
FLAGS_alsologtostderr = alsoerr;
366
RAW_VLOG(-1, "vlog -1");
367
RAW_VLOG(0, "vlog 0");
368
RAW_VLOG(1, "vlog 1");
369
RAW_LOG(INFO, "log info");
370
RAW_LOG(WARNING, "log warning");
371
RAW_LOG(ERROR, "log error");
373
VLOG(-1) << "vlog -1";
376
LOG(INFO) << "log info";
377
LOG(WARNING) << "log warning";
378
LOG(ERROR) << "log error";
380
VLOG_IF(-1, true) << "vlog_if -1";
381
VLOG_IF(-1, false) << "don't vlog_if -1";
382
VLOG_IF(0, true) << "vlog_if 0";
383
VLOG_IF(0, false) << "don't vlog_if 0";
384
VLOG_IF(1, true) << "vlog_if 1";
385
VLOG_IF(1, false) << "don't vlog_if 1";
386
LOG_IF(INFO, true) << "log_if info";
387
LOG_IF(INFO, false) << "don't log_if info";
388
LOG_IF(WARNING, true) << "log_if warning";
389
LOG_IF(WARNING, false) << "don't log_if warning";
390
LOG_IF(ERROR, true) << "log_if error";
391
LOG_IF(ERROR, false) << "don't log_if error";
394
c = 1; VLOG_IF(100, c -= 2) << "vlog_if 100 expr"; EXPECT_EQ(c, -1);
395
c = 1; VLOG_IF(0, c -= 2) << "vlog_if 0 expr"; EXPECT_EQ(c, -1);
396
c = 1; LOG_IF(INFO, c -= 2) << "log_if info expr"; EXPECT_EQ(c, -1);
397
c = 1; LOG_IF(ERROR, c -= 2) << "log_if error expr"; EXPECT_EQ(c, -1);
398
c = 2; VLOG_IF(0, c -= 2) << "don't vlog_if 0 expr"; EXPECT_EQ(c, 0);
399
c = 2; LOG_IF(ERROR, c -= 2) << "don't log_if error expr"; EXPECT_EQ(c, 0);
401
c = 3; LOG_IF_EVERY_N(INFO, c -= 4, 1) << "log_if info every 1 expr";
403
c = 3; LOG_IF_EVERY_N(ERROR, c -= 4, 1) << "log_if error every 1 expr";
405
c = 4; LOG_IF_EVERY_N(ERROR, c -= 4, 3) << "don't log_if info every 3 expr";
407
c = 4; LOG_IF_EVERY_N(ERROR, c -= 4, 3) << "don't log_if error every 3 expr";
409
c = 5; VLOG_IF_EVERY_N(0, c -= 4, 1) << "vlog_if 0 every 1 expr";
411
c = 5; VLOG_IF_EVERY_N(100, c -= 4, 3) << "vlog_if 100 every 3 expr";
413
c = 6; VLOG_IF_EVERY_N(0, c -= 6, 1) << "don't vlog_if 0 every 1 expr";
415
c = 6; VLOG_IF_EVERY_N(100, c -= 6, 3) << "don't vlog_if 100 every 1 expr";
419
void TestLoggingLevels() {
420
LogWithLevels(0, GLOG_INFO, false, false);
421
LogWithLevels(1, GLOG_INFO, false, false);
422
LogWithLevels(-1, GLOG_INFO, false, false);
423
LogWithLevels(0, GLOG_WARNING, false, false);
424
LogWithLevels(0, GLOG_ERROR, false, false);
425
LogWithLevels(0, GLOG_FATAL, false, false);
426
LogWithLevels(0, GLOG_FATAL, true, false);
427
LogWithLevels(0, GLOG_FATAL, false, true);
428
LogWithLevels(1, GLOG_WARNING, false, false);
429
LogWithLevels(1, GLOG_FATAL, false, true);
432
TEST(DeathRawCHECK, logging) {
433
ASSERT_DEATH(RAW_CHECK(false, "failure 1"),
434
"RAW: Check false failed: failure 1");
435
ASSERT_DEBUG_DEATH(RAW_DCHECK(1 == 2, "failure 2"),
436
"RAW: Check 1 == 2 failed: failure 2");
439
void TestLogString() {
440
vector<string> errors;
441
vector<string> *no_errors = NULL;
443
LOG_STRING(INFO, &errors) << "LOG_STRING: " << "collected info";
444
LOG_STRING(WARNING, &errors) << "LOG_STRING: " << "collected warning";
445
LOG_STRING(ERROR, &errors) << "LOG_STRING: " << "collected error";
447
LOG_STRING(INFO, no_errors) << "LOG_STRING: " << "reported info";
448
LOG_STRING(WARNING, no_errors) << "LOG_STRING: " << "reported warning";
449
LOG_STRING(ERROR, NULL) << "LOG_STRING: " << "reported error";
451
for (size_t i = 0; i < errors.size(); ++i) {
452
LOG(INFO) << "Captured by LOG_STRING: " << errors[i];
456
void TestLogToString() {
458
string* no_error = NULL;
460
LOG_TO_STRING(INFO, &error) << "LOG_TO_STRING: " << "collected info";
461
LOG(INFO) << "Captured by LOG_TO_STRING: " << error;
462
LOG_TO_STRING(WARNING, &error) << "LOG_TO_STRING: " << "collected warning";
463
LOG(INFO) << "Captured by LOG_TO_STRING: " << error;
464
LOG_TO_STRING(ERROR, &error) << "LOG_TO_STRING: " << "collected error";
465
LOG(INFO) << "Captured by LOG_TO_STRING: " << error;
467
LOG_TO_STRING(INFO, no_error) << "LOG_TO_STRING: " << "reported info";
468
LOG_TO_STRING(WARNING, no_error) << "LOG_TO_STRING: " << "reported warning";
469
LOG_TO_STRING(ERROR, NULL) << "LOG_TO_STRING: " << "reported error";
472
class TestLogSinkImpl : public LogSink {
474
vector<string> errors;
475
virtual void send(LogSeverity severity, const char* /* full_filename */,
476
const char* base_filename, int line,
477
const struct tm* tm_time,
478
const char* message, size_t message_len) {
480
ToString(severity, base_filename, line, tm_time, message, message_len));
485
TestLogSinkImpl sink;
486
LogSink *no_sink = NULL;
488
LOG_TO_SINK(&sink, INFO) << "LOG_TO_SINK: " << "collected info";
489
LOG_TO_SINK(&sink, WARNING) << "LOG_TO_SINK: " << "collected warning";
490
LOG_TO_SINK(&sink, ERROR) << "LOG_TO_SINK: " << "collected error";
492
LOG_TO_SINK(no_sink, INFO) << "LOG_TO_SINK: " << "reported info";
493
LOG_TO_SINK(no_sink, WARNING) << "LOG_TO_SINK: " << "reported warning";
494
LOG_TO_SINK(NULL, ERROR) << "LOG_TO_SINK: " << "reported error";
496
LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, INFO)
497
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected info";
498
LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, WARNING)
499
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected warning";
500
LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, ERROR)
501
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected error";
503
LOG_TO_SINK_BUT_NOT_TO_LOGFILE(no_sink, INFO)
504
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed info";
505
LOG_TO_SINK_BUT_NOT_TO_LOGFILE(no_sink, WARNING)
506
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed warning";
507
LOG_TO_SINK_BUT_NOT_TO_LOGFILE(NULL, ERROR)
508
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed error";
510
LOG(INFO) << "Captured by LOG_TO_SINK:";
511
for (size_t i = 0; i < sink.errors.size(); ++i) {
512
LogMessage("foo", LogMessage::kNoLogPrefix, GLOG_INFO).stream()
517
// For testing using CHECK*() on anonymous enums.
524
// Tests using CHECK*() on int values.
535
// Tests using CHECK*() on anonymous enums.
536
// Apple's GCC doesn't like this.
537
#if !defined(OS_MACOSX)
538
CHECK_EQ(CASE_A, CASE_A);
539
CHECK_NE(CASE_A, CASE_B);
540
CHECK_GE(CASE_A, CASE_A);
541
CHECK_GE(CASE_B, CASE_A);
542
CHECK_LE(CASE_A, CASE_A);
543
CHECK_LE(CASE_A, CASE_B);
544
CHECK_GT(CASE_B, CASE_A);
545
CHECK_LT(CASE_A, CASE_B);
551
DCHECK( 1 == 2 ) << " DCHECK's shouldn't be compiled in normal mode";
563
auto_ptr<int64> sptr(new int64);
564
int64* ptr = DCHECK_NOTNULL(sptr.get());
565
CHECK_EQ(ptr, sptr.get());
569
CHECK_STREQ("this", "this");
570
CHECK_STREQ(NULL, NULL);
571
CHECK_STRCASEEQ("this", "tHiS");
572
CHECK_STRCASEEQ(NULL, NULL);
573
CHECK_STRNE("this", "tHiS");
574
CHECK_STRNE("this", NULL);
575
CHECK_STRCASENE("this", "that");
576
CHECK_STRCASENE(NULL, "that");
577
CHECK_STREQ((string("a")+"b").c_str(), "ab");
578
CHECK_STREQ(string("test").c_str(),
579
(string("te") + string("st")).c_str());
582
TEST(DeathSTREQ, logging) {
583
ASSERT_DEATH(CHECK_STREQ(NULL, "this"), "");
584
ASSERT_DEATH(CHECK_STREQ("this", "siht"), "");
585
ASSERT_DEATH(CHECK_STRCASEEQ(NULL, "siht"), "");
586
ASSERT_DEATH(CHECK_STRCASEEQ("this", "siht"), "");
587
ASSERT_DEATH(CHECK_STRNE(NULL, NULL), "");
588
ASSERT_DEATH(CHECK_STRNE("this", "this"), "");
589
ASSERT_DEATH(CHECK_STREQ((string("a")+"b").c_str(), "abc"), "");
592
TEST(CheckNOTNULL, Simple) {
594
void *ptr = static_cast<void *>(&t);
595
void *ref = CHECK_NOTNULL(ptr);
597
CHECK_NOTNULL(reinterpret_cast<char *>(ptr));
598
CHECK_NOTNULL(reinterpret_cast<unsigned char *>(ptr));
599
CHECK_NOTNULL(reinterpret_cast<int *>(ptr));
600
CHECK_NOTNULL(reinterpret_cast<int64 *>(ptr));
603
TEST(DeathCheckNN, Simple) {
604
ASSERT_DEATH(CHECK_NOTNULL(static_cast<void *>(NULL)), "");
607
// Get list of file names that match pattern
608
static void GetFiles(const string& pattern, vector<string>* files) {
610
#if defined(HAVE_GLOB_H)
612
const int r = glob(pattern.c_str(), 0, NULL, &g);
613
CHECK((r == 0) || (r == GLOB_NOMATCH)) << ": error matching " << pattern;
614
for (size_t i = 0; i < g.gl_pathc; i++) {
615
files->push_back(string(g.gl_pathv[i]));
618
#elif defined(OS_WINDOWS)
619
WIN32_FIND_DATAA data;
620
HANDLE handle = FindFirstFileA(pattern.c_str(), &data);
621
size_t index = pattern.rfind('\\');
622
if (index == string::npos) {
623
LOG(FATAL) << "No directory separator.";
625
const string dirname = pattern.substr(0, index + 1);
626
if (FAILED(handle)) {
627
// Finding no files is OK.
631
files->push_back(dirname + data.cFileName);
632
} while (FindNextFileA(handle, &data));
633
LOG_SYSRESULT(FindClose(handle));
635
# error There is no way to do glob.
639
// Delete files patching pattern
640
static void DeleteFiles(const string& pattern) {
641
vector<string> files;
642
GetFiles(pattern, &files);
643
for (size_t i = 0; i < files.size(); i++) {
644
CHECK(unlink(files[i].c_str()) == 0) << ": " << strerror(errno);
648
static void CheckFile(const string& name, const string& expected_string) {
649
vector<string> files;
650
GetFiles(name + "*", &files);
651
CHECK_EQ(files.size(), 1UL);
653
FILE* file = fopen(files[0].c_str(), "r");
654
CHECK(file != NULL) << ": could not open " << files[0];
656
while (fgets(buf, sizeof(buf), file) != NULL) {
657
if (strstr(buf, expected_string.c_str()) != NULL) {
663
LOG(FATAL) << "Did not find " << expected_string << " in " << files[0];
666
static void TestBasename() {
667
fprintf(stderr, "==== Test setting log file basename\n");
668
const string dest = FLAGS_test_tmpdir + "/logging_test_basename";
669
DeleteFiles(dest + "*");
671
SetLogDestination(GLOG_INFO, dest.c_str());
672
LOG(INFO) << "message to new base";
673
FlushLogFiles(GLOG_INFO);
675
CheckFile(dest, "message to new base");
677
// Release file handle for the destination file to unlock the file in Windows.
679
DeleteFiles(dest + "*");
682
static void TestSymlink() {
684
fprintf(stderr, "==== Test setting log file symlink\n");
685
string dest = FLAGS_test_tmpdir + "/logging_test_symlink";
686
string sym = FLAGS_test_tmpdir + "/symlinkbase";
687
DeleteFiles(dest + "*");
688
DeleteFiles(sym + "*");
690
SetLogSymlink(GLOG_INFO, "symlinkbase");
691
SetLogDestination(GLOG_INFO, dest.c_str());
692
LOG(INFO) << "message to new symlink";
693
FlushLogFiles(GLOG_INFO);
694
CheckFile(sym, "message to new symlink");
696
DeleteFiles(dest + "*");
697
DeleteFiles(sym + "*");
701
static void TestExtension() {
702
fprintf(stderr, "==== Test setting log file extension\n");
703
string dest = FLAGS_test_tmpdir + "/logging_test_extension";
704
DeleteFiles(dest + "*");
706
SetLogDestination(GLOG_INFO, dest.c_str());
707
SetLogFilenameExtension("specialextension");
708
LOG(INFO) << "message to new extension";
709
FlushLogFiles(GLOG_INFO);
710
CheckFile(dest, "message to new extension");
712
// Check that file name ends with extension
713
vector<string> filenames;
714
GetFiles(dest + "*", &filenames);
715
CHECK_EQ(filenames.size(), 1UL);
716
CHECK(strstr(filenames[0].c_str(), "specialextension") != NULL);
718
// Release file handle for the destination file to unlock the file in Windows.
720
DeleteFiles(dest + "*");
723
struct MyLogger : public base::Logger {
726
virtual void Write(bool /* should_flush */,
727
time_t /* timestamp */,
730
data.append(message, length);
733
virtual void Flush() { }
735
virtual uint32 LogSize() { return data.length(); }
738
static void TestWrapper() {
739
fprintf(stderr, "==== Test log wrapper\n");
742
base::Logger* old_logger = base::GetLogger(GLOG_INFO);
743
base::SetLogger(GLOG_INFO, &my_logger);
744
LOG(INFO) << "Send to wrapped logger";
745
FlushLogFiles(GLOG_INFO);
746
base::SetLogger(GLOG_INFO, old_logger);
748
CHECK(strstr(my_logger.data.c_str(), "Send to wrapped logger") != NULL);
751
static void TestErrno() {
752
fprintf(stderr, "==== Test errno preservation\n");
756
CHECK_EQ(errno, ENOENT);
759
static void TestOneTruncate(const char *path, int64 limit, int64 keep,
760
int64 dsize, int64 ksize, int64 expect) {
762
CHECK_ERR(fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0600));
764
const char *discardstr = "DISCARDME!", *keepstr = "KEEPME!";
766
// Fill the file with the requested data; first discard data, then kept data
768
while (written < dsize) {
769
int bytes = min<int64>(dsize - written, strlen(discardstr));
770
CHECK_ERR(write(fd, discardstr, bytes));
774
while (written < ksize) {
775
int bytes = min<int64>(ksize - written, strlen(keepstr));
776
CHECK_ERR(write(fd, keepstr, bytes));
780
TruncateLogFile(path, limit, keep);
782
// File should now be shorter
784
CHECK_ERR(fstat(fd, &statbuf));
785
CHECK_EQ(statbuf.st_size, expect);
786
CHECK_ERR(lseek(fd, 0, SEEK_SET));
788
// File should contain the suffix of the original file
789
const size_t buf_size = statbuf.st_size + 1;
790
char* buf = new char[buf_size];
791
memset(buf, 0, buf_size);
792
CHECK_ERR(read(fd, buf, buf_size));
796
while (checked < expect) {
797
int bytes = min<int64>(expect - checked, strlen(keepstr));
798
CHECK(!memcmp(p, keepstr, bytes));
805
static void TestTruncate() {
807
fprintf(stderr, "==== Test log truncation\n");
808
string path = FLAGS_test_tmpdir + "/truncatefile";
810
// Test on a small file
811
TestOneTruncate(path.c_str(), 10, 10, 10, 10, 10);
813
// And a big file (multiple blocks to copy)
814
TestOneTruncate(path.c_str(), 2<<20, 4<<10, 3<<20, 4<<10, 4<<10);
816
// Check edge-case limits
817
TestOneTruncate(path.c_str(), 10, 20, 0, 20, 20);
818
TestOneTruncate(path.c_str(), 10, 0, 0, 0, 0);
819
TestOneTruncate(path.c_str(), 10, 50, 0, 10, 10);
820
TestOneTruncate(path.c_str(), 50, 100, 0, 30, 30);
822
// MacOSX 10.4 doesn't fail in this case.
823
// Windows doesn't have symlink.
824
// Let's just ignore this test for these cases.
825
#if !defined(OS_MACOSX) && !defined(OS_WINDOWS)
826
// Through a symlink should fail to truncate
827
string linkname = path + ".link";
828
unlink(linkname.c_str());
829
CHECK_ERR(symlink(path.c_str(), linkname.c_str()));
830
TestOneTruncate(linkname.c_str(), 10, 10, 0, 30, 30);
833
// The /proc/self path makes sense only for linux.
834
#if defined(OS_LINUX)
835
// Through an open fd symlink should work
837
CHECK_ERR(fd = open(path.c_str(), O_APPEND | O_WRONLY));
839
snprintf(fdpath, sizeof(fdpath), "/proc/self/fd/%d", fd);
840
TestOneTruncate(fdpath, 10, 10, 10, 10, 10);
846
_START_GOOGLE_NAMESPACE_
847
namespace glog_internal_namespace_ {
848
extern // in logging.cc
849
bool SafeFNMatch_(const char* pattern, size_t patt_len,
850
const char* str, size_t str_len);
851
} // namespace glog_internal_namespace_
852
using glog_internal_namespace_::SafeFNMatch_;
853
_END_GOOGLE_NAMESPACE_
855
static bool WrapSafeFNMatch(string pattern, string str) {
858
return SafeFNMatch_(pattern.data(), pattern.size() - 3,
859
str.data(), str.size() - 5);
862
TEST(SafeFNMatch, logging) {
863
CHECK(WrapSafeFNMatch("foo", "foo"));
864
CHECK(!WrapSafeFNMatch("foo", "bar"));
865
CHECK(!WrapSafeFNMatch("foo", "fo"));
866
CHECK(!WrapSafeFNMatch("foo", "foo2"));
867
CHECK(WrapSafeFNMatch("bar/foo.ext", "bar/foo.ext"));
868
CHECK(WrapSafeFNMatch("*ba*r/fo*o.ext*", "bar/foo.ext"));
869
CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/baz.ext"));
870
CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/foo"));
871
CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/foo.ext.zip"));
872
CHECK(WrapSafeFNMatch("ba?/*.ext", "bar/foo.ext"));
873
CHECK(WrapSafeFNMatch("ba?/*.ext", "baZ/FOO.ext"));
874
CHECK(!WrapSafeFNMatch("ba?/*.ext", "barr/foo.ext"));
875
CHECK(!WrapSafeFNMatch("ba?/*.ext", "bar/foo.ext2"));
876
CHECK(WrapSafeFNMatch("ba?/*", "bar/foo.ext2"));
877
CHECK(WrapSafeFNMatch("ba?/*", "bar/"));
878
CHECK(!WrapSafeFNMatch("ba?/?", "bar/"));
879
CHECK(!WrapSafeFNMatch("ba?/*", "bar"));
882
// TestWaitingLogSink will save messages here
883
// No lock: Accessed only by TestLogSinkWriter thread
884
// and after its demise by its creator.
885
static vector<string> global_messages;
887
// helper for TestWaitingLogSink below.
888
// Thread that does the logic of TestWaitingLogSink
889
// It's free to use LOG() itself.
890
class TestLogSinkWriter : public Thread {
893
TestLogSinkWriter() : should_exit_(false) {
898
// Just buffer it (can't use LOG() here).
899
void Buffer(const string& message) {
901
RAW_LOG(INFO, "Buffering");
902
messages_.push(message);
904
RAW_LOG(INFO, "Buffered");
907
// Wait for the buffer to clear (can't use LOG() here).
909
RAW_LOG(INFO, "Waiting");
913
SleepForMilliseconds(1);
916
RAW_LOG(INFO, "Waited");
920
// Trigger thread exit.
922
MutexLock l(&mutex_);
928
// helpers ---------------
930
// For creating a "Condition".
931
bool NoWork() { return messages_.empty(); }
932
bool HaveWork() { return !messages_.empty() || should_exit_; }
934
// Thread body; CAN use LOG() here!
938
while (!HaveWork()) {
940
SleepForMilliseconds(1);
943
if (should_exit_ && messages_.empty()) {
947
// Give the main thread time to log its message,
948
// so that we get a reliable log capture to compare to golden file.
949
// Same for the other sleep below.
950
SleepForMilliseconds(20);
951
RAW_LOG(INFO, "Sink got a messages"); // only RAW_LOG under mutex_ here
952
string message = messages_.front();
954
// Normally this would be some more real/involved logging logic
955
// where LOG() usage can't be eliminated,
956
// e.g. pushing the message over with an RPC:
957
int messages_left = messages_.size();
959
SleepForMilliseconds(20);
960
// May not use LOG while holding mutex_, because Buffer()
961
// acquires mutex_, and Buffer is called from LOG(),
962
// which has its own internal mutex:
963
// LOG()->LogToSinks()->TestWaitingLogSink::send()->Buffer()
964
LOG(INFO) << "Sink is sending out a message: " << message;
965
LOG(INFO) << "Have " << messages_left << " left";
966
global_messages.push_back(message);
970
// data ---------------
974
queue<string> messages_; // messages to be logged
977
// A log sink that exercises WaitTillSent:
978
// it pushes data to a buffer and wakes up another thread to do the logging
979
// (that other thread can than use LOG() itself),
980
class TestWaitingLogSink : public LogSink {
983
TestWaitingLogSink() {
984
tid_ = pthread_self(); // for thread-specific behavior
987
~TestWaitingLogSink() {
993
// (re)define LogSink interface
995
virtual void send(LogSeverity severity, const char* /* full_filename */,
996
const char* base_filename, int line,
997
const struct tm* tm_time,
998
const char* message, size_t message_len) {
999
// Push it to Writer thread if we are the original logging thread.
1000
// Note: Something like ThreadLocalLogSink is a better choice
1001
// to do thread-specific LogSink logic for real.
1002
if (pthread_equal(tid_, pthread_self())) {
1003
writer_.Buffer(ToString(severity, base_filename, line,
1004
tm_time, message, message_len));
1007
virtual void WaitTillSent() {
1008
// Wait for Writer thread if we are the original logging thread.
1009
if (pthread_equal(tid_, pthread_self())) writer_.Wait();
1015
TestLogSinkWriter writer_;
1018
// Check that LogSink::WaitTillSent can be used in the advertised way.
1019
// We also do golden-stderr comparison.
1020
static void TestLogSinkWaitTillSent() {
1021
{ TestWaitingLogSink sink;
1022
// Sleeps give the sink threads time to do all their work,
1023
// so that we get a reliable log capture to compare to the golden file.
1024
LOG(INFO) << "Message 1";
1025
SleepForMilliseconds(60);
1026
LOG(ERROR) << "Message 2";
1027
SleepForMilliseconds(60);
1028
LOG(WARNING) << "Message 3";
1029
SleepForMilliseconds(60);
1031
for (size_t i = 0; i < global_messages.size(); ++i) {
1032
LOG(INFO) << "Sink capture: " << global_messages[i];
1034
CHECK_EQ(global_messages.size(), 3UL);
1037
TEST(Strerror, logging) {
1038
int errcode = EINTR;
1039
char *msg = strdup(strerror(errcode));
1040
const size_t buf_size = strlen(msg) + 1;
1041
char *buf = new char[buf_size];
1042
CHECK_EQ(posix_strerror_r(errcode, NULL, 0), -1);
1044
CHECK_EQ(posix_strerror_r(errcode, buf, 0), -1);
1045
CHECK_EQ(buf[0], 'A');
1046
CHECK_EQ(posix_strerror_r(errcode, NULL, buf_size), -1);
1047
#if defined(OS_MACOSX) || defined(OS_FREEBSD) || defined(OS_OPENBSD)
1048
// MacOSX or FreeBSD considers this case is an error since there is
1050
CHECK_EQ(posix_strerror_r(errcode, buf, 1), -1);
1052
CHECK_EQ(posix_strerror_r(errcode, buf, 1), 0);
1054
CHECK_STREQ(buf, "");
1055
CHECK_EQ(posix_strerror_r(errcode, buf, buf_size), 0);
1056
CHECK_STREQ(buf, msg);
1061
// Simple routines to look at the sizes of generated code for LOG(FATAL) and
1062
// CHECK(..) via objdump
1064
LOG(FATAL) << "Failed";
1066
void MyCheck(bool a, bool b) {
1070
#ifdef HAVE_LIB_GMOCK
1072
TEST(DVLog, Basic) {
1076
// We are expecting that nothing is logged.
1077
EXPECT_CALL(log, Log(_, _, _)).Times(0);
1079
EXPECT_CALL(log, Log(INFO, __FILE__, "debug log"));
1083
DVLOG(1) << "debug log";
1089
// We are expecting that nothing is logged.
1090
EXPECT_CALL(log, Log(_, _, _)).Times(0);
1093
DVLOG(1) << "debug log";
1096
TEST(LogAtLevel, Basic) {
1099
// The function version outputs "logging.h" as a file name.
1100
EXPECT_CALL(log, Log(WARNING, StrNe(__FILE__), "function version"));
1101
EXPECT_CALL(log, Log(INFO, __FILE__, "macro version"));
1103
int severity = WARNING;
1104
LogAtLevel(severity, "function version");
1107
// We can use the macro version as a C++ stream.
1108
LOG_AT_LEVEL(severity) << "macro" << ' ' << "version";
1111
TEST(TestExitOnDFatal, ToBeOrNotToBe) {
1112
// Check the default setting...
1113
EXPECT_TRUE(base::internal::GetExitOnDFatal());
1116
base::internal::SetExitOnDFatal(false);
1117
EXPECT_FALSE(base::internal::GetExitOnDFatal());
1122
//EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
1123
// LOG(DFATAL) has severity FATAL if debugging, but is
1124
// downgraded to ERROR if not debugging.
1125
const LogSeverity severity =
1131
EXPECT_CALL(log, Log(severity, __FILE__, "This should not be fatal"));
1132
LOG(DFATAL) << "This should not be fatal";
1136
base::internal::SetExitOnDFatal(true);
1137
EXPECT_TRUE(base::internal::GetExitOnDFatal());
1139
#ifdef GTEST_HAS_DEATH_TEST
1140
// Death comes on little cats' feet.
1141
EXPECT_DEBUG_DEATH({
1142
LOG(DFATAL) << "This should be fatal in debug mode";
1143
}, "This should be fatal in debug mode");
1147
#ifdef HAVE_STACKTRACE
1149
static void BacktraceAtHelper() {
1150
LOG(INFO) << "Not me";
1152
// The vertical spacing of the next 3 lines is significant.
1153
LOG(INFO) << "Backtrace me";
1155
static int kBacktraceAtLine = __LINE__ - 2; // The line of the LOG(INFO) above
1157
TEST(LogBacktraceAt, DoesNotBacktraceWhenDisabled) {
1158
StrictMock<ScopedMockLog> log;
1160
FLAGS_log_backtrace_at = "";
1162
EXPECT_CALL(log, Log(_, _, "Backtrace me"));
1163
EXPECT_CALL(log, Log(_, _, "Not me"));
1165
BacktraceAtHelper();
1168
TEST(LogBacktraceAt, DoesBacktraceAtRightLineWhenEnabled) {
1169
StrictMock<ScopedMockLog> log;
1172
snprintf(where, 100, "%s:%d", const_basename(__FILE__), kBacktraceAtLine);
1173
FLAGS_log_backtrace_at = where;
1175
// The LOG at the specified line should include a stacktrace which includes
1176
// the name of the containing function, followed by the log message.
1177
// We use HasSubstr()s instead of ContainsRegex() for environments
1178
// which don't have regexp.
1179
EXPECT_CALL(log, Log(_, _, AllOf(HasSubstr("stacktrace:"),
1180
HasSubstr("BacktraceAtHelper"),
1182
HasSubstr("Backtrace me"))));
1183
// Other LOGs should not include a backtrace.
1184
EXPECT_CALL(log, Log(_, _, "Not me"));
1186
BacktraceAtHelper();
1189
#endif // HAVE_STACKTRACE
1191
#endif // HAVE_LIB_GMOCK
1193
struct UserDefinedClass {
1194
bool operator==(const UserDefinedClass&) const { return true; }
1197
inline ostream& operator<<(ostream& out, const UserDefinedClass&) {
1202
TEST(UserDefinedClass, logging) {
1205
LOG_STRING(INFO, &buf) << u;
1206
CHECK_EQ(1UL, buf.size());
1207
CHECK(buf[0].find("OK") != string::npos);
1209
// We must be able to compile this.