~ubuntu-branches/ubuntu/saucy/google-glog/saucy-proposed

« back to all changes in this revision

Viewing changes to .pc/errnos.diff/src/logging_unittest.cc

  • Committer: Package Import Robot
  • Author(s): Daigo Moriwaki
  • Date: 2012-06-21 21:07:21 UTC
  • Revision ID: package-import@ubuntu.com-20120621210721-zjzpuk5ectscubqp
Tags: 0.3.2-3
* debian/control:
  - Adds Laszlo Boszormenyi (GCS) into Uploaders.
  - Build-Depends on libunwind8 as before.
  - Corrected descriptions.
  - libgoogle-glog-dev depends on libgflags-dev as well.
    (Closes: #676605)
* Adds debian/patches/20120617_fix_test_on_ppc.diff:
  Fixes to make a test run on powerpc.
  (Closes: #645744)
* debian/rules: Freshens autotools by using autotools-dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright (c) 2002, Google Inc.
2
 
// All rights reserved.
3
 
//
4
 
// Redistribution and use in source and binary forms, with or without
5
 
// modification, are permitted provided that the following conditions are
6
 
// met:
7
 
//
8
 
//     * Redistributions of source code must retain the above copyright
9
 
// notice, this list of conditions and the following disclaimer.
10
 
//     * Redistributions in binary form must reproduce the above
11
 
// copyright notice, this list of conditions and the following disclaimer
12
 
// in the documentation and/or other materials provided with the
13
 
// distribution.
14
 
//     * Neither the name of Google Inc. nor the names of its
15
 
// contributors may be used to endorse or promote products derived from
16
 
// this software without specific prior written permission.
17
 
//
18
 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
 
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
 
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
 
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
 
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
 
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
 
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
 
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
 
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
 
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
 
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
 
//
30
 
// Author: Ray Sidney
31
 
 
32
 
#include "config_for_unittests.h"
33
 
#include "utilities.h"
34
 
 
35
 
#include <fcntl.h>
36
 
#ifdef HAVE_GLOB_H
37
 
# include <glob.h>
38
 
#endif
39
 
#include <sys/stat.h>
40
 
#ifdef HAVE_UNISTD_H
41
 
# include <unistd.h>
42
 
#endif
43
 
 
44
 
#include <iomanip>
45
 
#include <iostream>
46
 
#include <memory>
47
 
#include <queue>
48
 
#include <sstream>
49
 
#include <string>
50
 
#include <vector>
51
 
 
52
 
#include <stdio.h>
53
 
#include <stdlib.h>
54
 
 
55
 
#include "base/commandlineflags.h"
56
 
#include "glog/logging.h"
57
 
#include "glog/raw_logging.h"
58
 
#include "googletest.h"
59
 
 
60
 
DECLARE_string(log_backtrace_at);  // logging.cc
61
 
 
62
 
#ifdef HAVE_LIB_GFLAGS
63
 
#include <gflags/gflags.h>
64
 
#endif
65
 
 
66
 
#ifdef HAVE_LIB_GMOCK
67
 
#include <gmock/gmock.h>
68
 
#include "mock-log.h"
69
 
// Introduce several symbols from gmock.
70
 
using testing::_;
71
 
using testing::AnyNumber;
72
 
using testing::HasSubstr;
73
 
using testing::AllOf;
74
 
using testing::StrNe;
75
 
using testing::StrictMock;
76
 
using testing::InitGoogleMock;
77
 
using GOOGLE_NAMESPACE::glog_testing::ScopedMockLog;
78
 
#endif
79
 
 
80
 
using namespace std;
81
 
using namespace GOOGLE_NAMESPACE;
82
 
 
83
 
// Some non-advertised functions that we want to test or use.
84
 
_START_GOOGLE_NAMESPACE_
85
 
namespace base {
86
 
namespace internal {
87
 
bool GetExitOnDFatal();
88
 
void SetExitOnDFatal(bool value);
89
 
}  // namespace internal
90
 
}  // namespace base
91
 
_END_GOOGLE_NAMESPACE_
92
 
 
93
 
static void TestLogging(bool check_counts);
94
 
static void TestRawLogging();
95
 
static void LogWithLevels(int v, int severity, bool err, bool alsoerr);
96
 
static void TestLoggingLevels();
97
 
static void TestLogString();
98
 
static void TestLogSink();
99
 
static void TestLogToString();
100
 
static void TestLogSinkWaitTillSent();
101
 
static void TestCHECK();
102
 
static void TestDCHECK();
103
 
static void TestSTREQ();
104
 
static void TestBasename();
105
 
static void TestSymlink();
106
 
static void TestExtension();
107
 
static void TestWrapper();
108
 
static void TestErrno();
109
 
static void TestTruncate();
110
 
 
111
 
static int x = -1;
112
 
static void BM_Check1(int n) {
113
 
  while (n-- > 0) {
114
 
    CHECK_GE(n, x);
115
 
    CHECK_GE(n, x);
116
 
    CHECK_GE(n, x);
117
 
    CHECK_GE(n, x);
118
 
    CHECK_GE(n, x);
119
 
    CHECK_GE(n, x);
120
 
    CHECK_GE(n, x);
121
 
    CHECK_GE(n, x);
122
 
  }
123
 
}
124
 
BENCHMARK(BM_Check1);
125
 
 
126
 
static void CheckFailure(int a, int b, const char* file, int line, const char* msg);
127
 
static void BM_Check3(int n) {
128
 
  while (n-- > 0) {
129
 
    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
130
 
    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
131
 
    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
132
 
    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
133
 
    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
134
 
    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
135
 
    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
136
 
    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
137
 
  }
138
 
}
139
 
BENCHMARK(BM_Check3);
140
 
 
141
 
static void BM_Check2(int n) {
142
 
  if (n == 17) {
143
 
    x = 5;
144
 
  }
145
 
  while (n-- > 0) {
146
 
    CHECK(n >= x);
147
 
    CHECK(n >= x);
148
 
    CHECK(n >= x);
149
 
    CHECK(n >= x);
150
 
    CHECK(n >= x);
151
 
    CHECK(n >= x);
152
 
    CHECK(n >= x);
153
 
    CHECK(n >= x);
154
 
  }
155
 
}
156
 
BENCHMARK(BM_Check2);
157
 
 
158
 
static void CheckFailure(int, int, const char* /* file */, int /* line */,
159
 
                         const char* /* msg */) {
160
 
}
161
 
 
162
 
static void BM_logspeed(int n) {
163
 
  while (n-- > 0) {
164
 
    LOG(INFO) << "test message";
165
 
  }
166
 
}
167
 
BENCHMARK(BM_logspeed);
168
 
 
169
 
static void BM_vlog(int n) {
170
 
  while (n-- > 0) {
171
 
    VLOG(1) << "test message";
172
 
  }
173
 
}
174
 
BENCHMARK(BM_vlog);
175
 
 
176
 
int main(int argc, char **argv) {
177
 
#ifdef HAVE_LIB_GFLAGS
178
 
  ParseCommandLineFlags(&argc, &argv, true);
179
 
#endif
180
 
 
181
 
  // Test some basics before InitGoogleLogging:
182
 
  CaptureTestStderr();
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();
187
 
 
188
 
  InitGoogleLogging(argv[0]);
189
 
 
190
 
  RunSpecifiedBenchmarks();
191
 
 
192
 
  FLAGS_logtostderr = true;
193
 
 
194
 
  InitGoogleTest(&argc, argv);
195
 
#ifdef HAVE_LIB_GMOCK
196
 
  InitGoogleMock(&argc, argv);
197
 
#endif
198
 
 
199
 
  // so that death tests run before we use threads
200
 
  CHECK_EQ(RUN_ALL_TESTS(), 0);
201
 
 
202
 
  CaptureTestStderr();
203
 
 
204
 
  // re-emit early_stderr
205
 
  LogMessage("dummy", LogMessage::kNoLogPrefix, GLOG_INFO).stream() << early_stderr;
206
 
 
207
 
  TestLogging(true);
208
 
  TestRawLogging();
209
 
  TestLoggingLevels();
210
 
  TestLogString();
211
 
  TestLogSink();
212
 
  TestLogToString();
213
 
  TestLogSinkWaitTillSent();
214
 
  TestCHECK();
215
 
  TestDCHECK();
216
 
  TestSTREQ();
217
 
 
218
 
  // TODO: The golden test portion of this test is very flakey.
219
 
  EXPECT_TRUE(
220
 
      MungeAndDiffTestStderr(FLAGS_test_srcdir + "/src/logging_unittest.err"));
221
 
 
222
 
  FLAGS_logtostderr = false;
223
 
 
224
 
  TestBasename();
225
 
  TestSymlink();
226
 
  TestExtension();
227
 
  TestWrapper();
228
 
  TestErrno();
229
 
  TestTruncate();
230
 
 
231
 
  ShutdownGoogleLogging();
232
 
 
233
 
  fprintf(stdout, "PASS\n");
234
 
  return 0;
235
 
}
236
 
 
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);
241
 
 
242
 
  LOG(INFO) << string("foo ") << "bar " << 10 << ' ' << 3.4;
243
 
  for ( int i = 0; i < 10; ++i ) {
244
 
    int old_errno = errno;
245
 
    errno = i;
246
 
    PLOG_EVERY_N(ERROR, 2) << "Plog every 2, iteration " << COUNTER;
247
 
    errno = old_errno;
248
 
 
249
 
    LOG_EVERY_N(ERROR, 3) << "Log every 3, iteration " << COUNTER << endl;
250
 
    LOG_EVERY_N(ERROR, 4) << "Log every 4, iteration " << COUNTER << endl;
251
 
 
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;
258
 
  }
259
 
  LOG_IF(WARNING, true) << "log_if this";
260
 
  LOG_IF(WARNING, false) << "don't log_if this";
261
 
 
262
 
  char s[] = "array";
263
 
  LOG(INFO) << s;
264
 
  const char const_s[] = "const array";
265
 
  LOG(INFO) << const_s;
266
 
  int j = 1000;
267
 
  LOG(ERROR) << string("foo") << ' '<< j << ' ' << setw(10) << j << " "
268
 
             << setw(1) << hex << j;
269
 
 
270
 
  LogMessage("foo", LogMessage::kNoLogPrefix, GLOG_INFO).stream() << "no prefix";
271
 
 
272
 
  if (check_counts) {
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));
276
 
  }
277
 
}
278
 
 
279
 
static void NoAllocNewHook() {
280
 
  CHECK(false) << "unexpected new";
281
 
}
282
 
 
283
 
struct NewHook {
284
 
  NewHook() {
285
 
    g_new_hook = &NoAllocNewHook;
286
 
  }
287
 
  ~NewHook() {
288
 
    g_new_hook = NULL;
289
 
  }
290
 
};
291
 
 
292
 
TEST(DeathNoAllocNewHook, logging) {
293
 
  // tests that NewHook used below works
294
 
  NewHook new_hook;
295
 
  ASSERT_DEATH({
296
 
    new int;
297
 
  }, "unexpected new");
298
 
}
299
 
 
300
 
void TestRawLogging() {
301
 
  string* foo = new string("foo ");
302
 
  string huge_str(50000, 'a');
303
 
 
304
 
  FlagSaver saver;
305
 
 
306
 
  // Check that RAW loggging does not use mallocs.
307
 
  NewHook new_hook;
308
 
 
309
 
  RAW_LOG(INFO, "%s%s%d%c%f", foo->c_str(), "bar ", 10, ' ', 3.4);
310
 
  char s[] = "array";
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);
316
 
  p = NULL;
317
 
  RAW_LOG(INFO, "ptr %p", p);
318
 
  int j = 1000;
319
 
  RAW_LOG(ERROR, "%s%d%c%010d%s%1x", foo->c_str(), j, ' ', j, " ", j);
320
 
  RAW_VLOG(0, "foo %d", j);
321
 
 
322
 
#ifdef NDEBUG
323
 
  RAW_LOG(INFO, "foo %d", j);  // so that have same stderr to compare
324
 
#else
325
 
  RAW_DLOG(INFO, "foo %d", j);  // test RAW_DLOG in debug mode
326
 
#endif
327
 
 
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());
331
 
 
332
 
  FLAGS_v = 0;
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");
338
 
  FLAGS_v = 2;
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");
343
 
 
344
 
#ifdef NDEBUG
345
 
  RAW_DCHECK(1 == 2, " RAW_DCHECK's shouldn't be compiled in normal mode");
346
 
#endif
347
 
 
348
 
  RAW_CHECK(1 == 1, "should be ok");
349
 
  RAW_DCHECK(true, "should be ok");
350
 
 
351
 
  delete foo;
352
 
}
353
 
 
354
 
void LogWithLevels(int v, int severity, bool err, bool alsoerr) {
355
 
  RAW_LOG(INFO,
356
 
          "Test: v=%d stderrthreshold=%d logtostderr=%d alsologtostderr=%d",
357
 
          v, severity, err, alsoerr);
358
 
 
359
 
  FlagSaver saver;
360
 
 
361
 
  FLAGS_v = v;
362
 
  FLAGS_stderrthreshold = severity;
363
 
  FLAGS_logtostderr = err;
364
 
  FLAGS_alsologtostderr = alsoerr;
365
 
 
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");
372
 
 
373
 
  VLOG(-1) << "vlog -1";
374
 
  VLOG(0) << "vlog 0";
375
 
  VLOG(1) << "vlog 1";
376
 
  LOG(INFO) << "log info";
377
 
  LOG(WARNING) << "log warning";
378
 
  LOG(ERROR) << "log error";
379
 
 
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";
392
 
 
393
 
  int c;
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);
400
 
 
401
 
  c = 3; LOG_IF_EVERY_N(INFO, c -= 4, 1) << "log_if info every 1 expr";
402
 
  EXPECT_EQ(c, -1);
403
 
  c = 3; LOG_IF_EVERY_N(ERROR, c -= 4, 1) << "log_if error every 1 expr";
404
 
  EXPECT_EQ(c, -1);
405
 
  c = 4; LOG_IF_EVERY_N(ERROR, c -= 4, 3) << "don't log_if info every 3 expr";
406
 
  EXPECT_EQ(c, 0);
407
 
  c = 4; LOG_IF_EVERY_N(ERROR, c -= 4, 3) << "don't log_if error every 3 expr";
408
 
  EXPECT_EQ(c, 0);
409
 
  c = 5; VLOG_IF_EVERY_N(0, c -= 4, 1) << "vlog_if 0 every 1 expr";
410
 
  EXPECT_EQ(c, 1);
411
 
  c = 5; VLOG_IF_EVERY_N(100, c -= 4, 3) << "vlog_if 100 every 3 expr";
412
 
  EXPECT_EQ(c, 1);
413
 
  c = 6; VLOG_IF_EVERY_N(0, c -= 6, 1) << "don't vlog_if 0 every 1 expr";
414
 
  EXPECT_EQ(c, 0);
415
 
  c = 6; VLOG_IF_EVERY_N(100, c -= 6, 3) << "don't vlog_if 100 every 1 expr";
416
 
  EXPECT_EQ(c, 0);
417
 
}
418
 
 
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);
430
 
}
431
 
 
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");
437
 
}
438
 
 
439
 
void TestLogString() {
440
 
  vector<string> errors;
441
 
  vector<string> *no_errors = NULL;
442
 
 
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";
446
 
 
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";
450
 
 
451
 
  for (size_t i = 0; i < errors.size(); ++i) {
452
 
    LOG(INFO) << "Captured by LOG_STRING:  " << errors[i];
453
 
  }
454
 
}
455
 
 
456
 
void TestLogToString() {
457
 
  string error;
458
 
  string* no_error = NULL;
459
 
 
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;
466
 
 
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";
470
 
}
471
 
 
472
 
class TestLogSinkImpl : public LogSink {
473
 
 public:
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) {
479
 
    errors.push_back(
480
 
      ToString(severity, base_filename, line, tm_time, message, message_len));
481
 
  }
482
 
};
483
 
 
484
 
void TestLogSink() {
485
 
  TestLogSinkImpl sink;
486
 
  LogSink *no_sink = NULL;
487
 
 
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";
491
 
 
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";
495
 
 
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";
502
 
 
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";
509
 
 
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()
513
 
      << sink.errors[i];
514
 
  }
515
 
}
516
 
 
517
 
// For testing using CHECK*() on anonymous enums.
518
 
enum {
519
 
  CASE_A,
520
 
  CASE_B
521
 
};
522
 
 
523
 
void TestCHECK() {
524
 
  // Tests using CHECK*() on int values.
525
 
  CHECK(1 == 1);
526
 
  CHECK_EQ(1, 1);
527
 
  CHECK_NE(1, 2);
528
 
  CHECK_GE(1, 1);
529
 
  CHECK_GE(2, 1);
530
 
  CHECK_LE(1, 1);
531
 
  CHECK_LE(1, 2);
532
 
  CHECK_GT(2, 1);
533
 
  CHECK_LT(1, 2);
534
 
 
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);
546
 
#endif
547
 
}
548
 
 
549
 
void TestDCHECK() {
550
 
#ifdef NDEBUG
551
 
  DCHECK( 1 == 2 ) << " DCHECK's shouldn't be compiled in normal mode";
552
 
#endif
553
 
  DCHECK( 1 == 1 );
554
 
  DCHECK_EQ(1, 1);
555
 
  DCHECK_NE(1, 2);
556
 
  DCHECK_GE(1, 1);
557
 
  DCHECK_GE(2, 1);
558
 
  DCHECK_LE(1, 1);
559
 
  DCHECK_LE(1, 2);
560
 
  DCHECK_GT(2, 1);
561
 
  DCHECK_LT(1, 2);
562
 
 
563
 
  auto_ptr<int64> sptr(new int64);
564
 
  int64* ptr = DCHECK_NOTNULL(sptr.get());
565
 
  CHECK_EQ(ptr, sptr.get());
566
 
}
567
 
 
568
 
void TestSTREQ() {
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());
580
 
}
581
 
 
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"), "");
590
 
}
591
 
 
592
 
TEST(CheckNOTNULL, Simple) {
593
 
  int64 t;
594
 
  void *ptr = static_cast<void *>(&t);
595
 
  void *ref = CHECK_NOTNULL(ptr);
596
 
  EXPECT_EQ(ptr, ref);
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));
601
 
}
602
 
 
603
 
TEST(DeathCheckNN, Simple) {
604
 
  ASSERT_DEATH(CHECK_NOTNULL(static_cast<void *>(NULL)), "");
605
 
}
606
 
 
607
 
// Get list of file names that match pattern
608
 
static void GetFiles(const string& pattern, vector<string>* files) {
609
 
  files->clear();
610
 
#if defined(HAVE_GLOB_H)
611
 
  glob_t g;
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]));
616
 
  }
617
 
  globfree(&g);
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.";
624
 
  }
625
 
  const string dirname = pattern.substr(0, index + 1);
626
 
  if (FAILED(handle)) {
627
 
    // Finding no files is OK.
628
 
    return;
629
 
  }
630
 
  do {
631
 
    files->push_back(dirname + data.cFileName);
632
 
  } while (FindNextFileA(handle, &data));
633
 
  LOG_SYSRESULT(FindClose(handle));
634
 
#else
635
 
# error There is no way to do glob.
636
 
#endif
637
 
}
638
 
 
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);
645
 
  }
646
 
}
647
 
 
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);
652
 
 
653
 
  FILE* file = fopen(files[0].c_str(), "r");
654
 
  CHECK(file != NULL) << ": could not open " << files[0];
655
 
  char buf[1000];
656
 
  while (fgets(buf, sizeof(buf), file) != NULL) {
657
 
    if (strstr(buf, expected_string.c_str()) != NULL) {
658
 
      fclose(file);
659
 
      return;
660
 
    }
661
 
  }
662
 
  fclose(file);
663
 
  LOG(FATAL) << "Did not find " << expected_string << " in " << files[0];
664
 
}
665
 
 
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 + "*");
670
 
 
671
 
  SetLogDestination(GLOG_INFO, dest.c_str());
672
 
  LOG(INFO) << "message to new base";
673
 
  FlushLogFiles(GLOG_INFO);
674
 
 
675
 
  CheckFile(dest, "message to new base");
676
 
 
677
 
  // Release file handle for the destination file to unlock the file in Windows.
678
 
  LogToStderr();
679
 
  DeleteFiles(dest + "*");
680
 
}
681
 
 
682
 
static void TestSymlink() {
683
 
#ifndef OS_WINDOWS
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 + "*");
689
 
 
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");
695
 
 
696
 
  DeleteFiles(dest + "*");
697
 
  DeleteFiles(sym + "*");
698
 
#endif
699
 
}
700
 
 
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 + "*");
705
 
 
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");
711
 
 
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);
717
 
 
718
 
  // Release file handle for the destination file to unlock the file in Windows.
719
 
  LogToStderr();
720
 
  DeleteFiles(dest + "*");
721
 
}
722
 
 
723
 
struct MyLogger : public base::Logger {
724
 
  string data;
725
 
 
726
 
  virtual void Write(bool /* should_flush */,
727
 
                     time_t /* timestamp */,
728
 
                     const char* message,
729
 
                     int length) {
730
 
    data.append(message, length);
731
 
  }
732
 
 
733
 
  virtual void Flush() { }
734
 
 
735
 
  virtual uint32 LogSize() { return data.length(); }
736
 
};
737
 
 
738
 
static void TestWrapper() {
739
 
  fprintf(stderr, "==== Test log wrapper\n");
740
 
 
741
 
  MyLogger my_logger;
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);
747
 
 
748
 
  CHECK(strstr(my_logger.data.c_str(), "Send to wrapped logger") != NULL);
749
 
}
750
 
 
751
 
static void TestErrno() {
752
 
  fprintf(stderr, "==== Test errno preservation\n");
753
 
 
754
 
  errno = ENOENT;
755
 
  TestLogging(false);
756
 
  CHECK_EQ(errno, ENOENT);
757
 
}
758
 
 
759
 
static void TestOneTruncate(const char *path, int64 limit, int64 keep,
760
 
                            int64 dsize, int64 ksize, int64 expect) {
761
 
  int fd;
762
 
  CHECK_ERR(fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0600));
763
 
 
764
 
  const char *discardstr = "DISCARDME!", *keepstr = "KEEPME!";
765
 
 
766
 
  // Fill the file with the requested data; first discard data, then kept data
767
 
  int64 written = 0;
768
 
  while (written < dsize) {
769
 
    int bytes = min<int64>(dsize - written, strlen(discardstr));
770
 
    CHECK_ERR(write(fd, discardstr, bytes));
771
 
    written += bytes;
772
 
  }
773
 
  written = 0;
774
 
  while (written < ksize) {
775
 
    int bytes = min<int64>(ksize - written, strlen(keepstr));
776
 
    CHECK_ERR(write(fd, keepstr, bytes));
777
 
    written += bytes;
778
 
  }
779
 
 
780
 
  TruncateLogFile(path, limit, keep);
781
 
 
782
 
  // File should now be shorter
783
 
  struct stat statbuf;
784
 
  CHECK_ERR(fstat(fd, &statbuf));
785
 
  CHECK_EQ(statbuf.st_size, expect);
786
 
  CHECK_ERR(lseek(fd, 0, SEEK_SET));
787
 
 
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));
793
 
 
794
 
  const char *p = buf;
795
 
  int64 checked = 0;
796
 
  while (checked < expect) {
797
 
    int bytes = min<int64>(expect - checked, strlen(keepstr));
798
 
    CHECK(!memcmp(p, keepstr, bytes));
799
 
    checked += bytes;
800
 
  }
801
 
  close(fd);
802
 
  delete[] buf;
803
 
}
804
 
 
805
 
static void TestTruncate() {
806
 
#ifdef HAVE_UNISTD_H
807
 
  fprintf(stderr, "==== Test log truncation\n");
808
 
  string path = FLAGS_test_tmpdir + "/truncatefile";
809
 
 
810
 
  // Test on a small file
811
 
  TestOneTruncate(path.c_str(), 10, 10, 10, 10, 10);
812
 
 
813
 
  // And a big file (multiple blocks to copy)
814
 
  TestOneTruncate(path.c_str(), 2<<20, 4<<10, 3<<20, 4<<10, 4<<10);
815
 
 
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);
821
 
 
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);
831
 
#endif
832
 
 
833
 
  // The /proc/self path makes sense only for linux.
834
 
#if defined(OS_LINUX)
835
 
  // Through an open fd symlink should work
836
 
  int fd;
837
 
  CHECK_ERR(fd = open(path.c_str(), O_APPEND | O_WRONLY));
838
 
  char fdpath[64];
839
 
  snprintf(fdpath, sizeof(fdpath), "/proc/self/fd/%d", fd);
840
 
  TestOneTruncate(fdpath, 10, 10, 10, 10, 10);
841
 
#endif
842
 
 
843
 
#endif
844
 
}
845
 
 
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_
854
 
 
855
 
static bool WrapSafeFNMatch(string pattern, string str) {
856
 
  pattern += "abc";
857
 
  str += "defgh";
858
 
  return SafeFNMatch_(pattern.data(), pattern.size() - 3,
859
 
                      str.data(), str.size() - 5);
860
 
}
861
 
 
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"));
880
 
}
881
 
 
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;
886
 
 
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 {
891
 
 public:
892
 
 
893
 
  TestLogSinkWriter() : should_exit_(false) {
894
 
    SetJoinable(true);
895
 
    Start();
896
 
  }
897
 
 
898
 
  // Just buffer it (can't use LOG() here).
899
 
  void Buffer(const string& message) {
900
 
    mutex_.Lock();
901
 
    RAW_LOG(INFO, "Buffering");
902
 
    messages_.push(message);
903
 
    mutex_.Unlock();
904
 
    RAW_LOG(INFO, "Buffered");
905
 
  }
906
 
 
907
 
  // Wait for the buffer to clear (can't use LOG() here).
908
 
  void Wait() {
909
 
    RAW_LOG(INFO, "Waiting");
910
 
    mutex_.Lock();
911
 
    while (!NoWork()) {
912
 
      mutex_.Unlock();
913
 
      SleepForMilliseconds(1);
914
 
      mutex_.Lock();
915
 
    }
916
 
    RAW_LOG(INFO, "Waited");
917
 
    mutex_.Unlock();
918
 
  }
919
 
 
920
 
  // Trigger thread exit.
921
 
  void Stop() {
922
 
    MutexLock l(&mutex_);
923
 
    should_exit_ = true;
924
 
  }
925
 
 
926
 
 private:
927
 
 
928
 
  // helpers ---------------
929
 
 
930
 
  // For creating a "Condition".
931
 
  bool NoWork() { return messages_.empty(); }
932
 
  bool HaveWork() { return !messages_.empty() || should_exit_; }
933
 
 
934
 
  // Thread body; CAN use LOG() here!
935
 
  virtual void Run() {
936
 
    while (1) {
937
 
      mutex_.Lock();
938
 
      while (!HaveWork()) {
939
 
        mutex_.Unlock();
940
 
        SleepForMilliseconds(1);
941
 
        mutex_.Lock();
942
 
      }
943
 
      if (should_exit_ && messages_.empty()) {
944
 
        mutex_.Unlock();
945
 
        break;
946
 
      }
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();
953
 
      messages_.pop();
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();
958
 
      mutex_.Unlock();
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);
967
 
    }
968
 
  }
969
 
 
970
 
  // data ---------------
971
 
 
972
 
  Mutex mutex_;
973
 
  bool should_exit_;
974
 
  queue<string> messages_;  // messages to be logged
975
 
};
976
 
 
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 {
981
 
 public:
982
 
 
983
 
  TestWaitingLogSink() {
984
 
    tid_ = pthread_self();  // for thread-specific behavior
985
 
    AddLogSink(this);
986
 
  }
987
 
  ~TestWaitingLogSink() {
988
 
    RemoveLogSink(this);
989
 
    writer_.Stop();
990
 
    writer_.Join();
991
 
  }
992
 
 
993
 
  // (re)define LogSink interface
994
 
 
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));
1005
 
    }
1006
 
  }
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();
1010
 
  }
1011
 
 
1012
 
 private:
1013
 
 
1014
 
  pthread_t tid_;
1015
 
  TestLogSinkWriter writer_;
1016
 
};
1017
 
 
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);
1030
 
  }
1031
 
  for (size_t i = 0; i < global_messages.size(); ++i) {
1032
 
    LOG(INFO) << "Sink capture: " << global_messages[i];
1033
 
  }
1034
 
  CHECK_EQ(global_messages.size(), 3UL);
1035
 
}
1036
 
 
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);
1043
 
  buf[0] = 'A';
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
1049
 
  // no enough space.
1050
 
  CHECK_EQ(posix_strerror_r(errcode, buf, 1), -1);
1051
 
#else
1052
 
  CHECK_EQ(posix_strerror_r(errcode, buf, 1), 0);
1053
 
#endif
1054
 
  CHECK_STREQ(buf, "");
1055
 
  CHECK_EQ(posix_strerror_r(errcode, buf, buf_size), 0);
1056
 
  CHECK_STREQ(buf, msg);
1057
 
  free(msg);
1058
 
  delete[] buf;
1059
 
}
1060
 
 
1061
 
// Simple routines to look at the sizes of generated code for LOG(FATAL) and
1062
 
// CHECK(..) via objdump
1063
 
void MyFatal() {
1064
 
  LOG(FATAL) << "Failed";
1065
 
}
1066
 
void MyCheck(bool a, bool b) {
1067
 
  CHECK_EQ(a, b);
1068
 
}
1069
 
 
1070
 
#ifdef HAVE_LIB_GMOCK
1071
 
 
1072
 
TEST(DVLog, Basic) {
1073
 
  ScopedMockLog log;
1074
 
 
1075
 
#if NDEBUG
1076
 
  // We are expecting that nothing is logged.
1077
 
  EXPECT_CALL(log, Log(_, _, _)).Times(0);
1078
 
#else
1079
 
  EXPECT_CALL(log, Log(INFO, __FILE__, "debug log"));
1080
 
#endif
1081
 
 
1082
 
  FLAGS_v = 1;
1083
 
  DVLOG(1) << "debug log";
1084
 
}
1085
 
 
1086
 
TEST(DVLog, V0) {
1087
 
  ScopedMockLog log;
1088
 
 
1089
 
  // We are expecting that nothing is logged.
1090
 
  EXPECT_CALL(log, Log(_, _, _)).Times(0);
1091
 
 
1092
 
  FLAGS_v = 0;
1093
 
  DVLOG(1) << "debug log";
1094
 
}
1095
 
 
1096
 
TEST(LogAtLevel, Basic) {
1097
 
  ScopedMockLog log;
1098
 
 
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"));
1102
 
 
1103
 
  int severity = WARNING;
1104
 
  LogAtLevel(severity, "function version");
1105
 
 
1106
 
  severity = INFO;
1107
 
  // We can use the macro version as a C++ stream.
1108
 
  LOG_AT_LEVEL(severity) << "macro" << ' ' << "version";
1109
 
}
1110
 
 
1111
 
TEST(TestExitOnDFatal, ToBeOrNotToBe) {
1112
 
  // Check the default setting...
1113
 
  EXPECT_TRUE(base::internal::GetExitOnDFatal());
1114
 
 
1115
 
  // Turn off...
1116
 
  base::internal::SetExitOnDFatal(false);
1117
 
  EXPECT_FALSE(base::internal::GetExitOnDFatal());
1118
 
 
1119
 
  // We don't die.
1120
 
  {
1121
 
    ScopedMockLog log;
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 =
1126
 
#ifdef NDEBUG
1127
 
        ERROR;
1128
 
#else
1129
 
        FATAL;
1130
 
#endif
1131
 
    EXPECT_CALL(log, Log(severity, __FILE__, "This should not be fatal"));
1132
 
    LOG(DFATAL) << "This should not be fatal";
1133
 
  }
1134
 
 
1135
 
  // Turn back on...
1136
 
  base::internal::SetExitOnDFatal(true);
1137
 
  EXPECT_TRUE(base::internal::GetExitOnDFatal());
1138
 
 
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");
1144
 
#endif
1145
 
}
1146
 
 
1147
 
#ifdef HAVE_STACKTRACE
1148
 
 
1149
 
static void BacktraceAtHelper() {
1150
 
  LOG(INFO) << "Not me";
1151
 
 
1152
 
// The vertical spacing of the next 3 lines is significant.
1153
 
  LOG(INFO) << "Backtrace me";
1154
 
}
1155
 
static int kBacktraceAtLine = __LINE__ - 2;  // The line of the LOG(INFO) above
1156
 
 
1157
 
TEST(LogBacktraceAt, DoesNotBacktraceWhenDisabled) {
1158
 
  StrictMock<ScopedMockLog> log;
1159
 
 
1160
 
  FLAGS_log_backtrace_at = "";
1161
 
 
1162
 
  EXPECT_CALL(log, Log(_, _, "Backtrace me"));
1163
 
  EXPECT_CALL(log, Log(_, _, "Not me"));
1164
 
 
1165
 
  BacktraceAtHelper();
1166
 
}
1167
 
 
1168
 
TEST(LogBacktraceAt, DoesBacktraceAtRightLineWhenEnabled) {
1169
 
  StrictMock<ScopedMockLog> log;
1170
 
 
1171
 
  char where[100];
1172
 
  snprintf(where, 100, "%s:%d", const_basename(__FILE__), kBacktraceAtLine);
1173
 
  FLAGS_log_backtrace_at = where;
1174
 
 
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"),
1181
 
                                   HasSubstr("main"),
1182
 
                                   HasSubstr("Backtrace me"))));
1183
 
  // Other LOGs should not include a backtrace.
1184
 
  EXPECT_CALL(log, Log(_, _, "Not me"));
1185
 
 
1186
 
  BacktraceAtHelper();
1187
 
}
1188
 
 
1189
 
#endif // HAVE_STACKTRACE
1190
 
 
1191
 
#endif // HAVE_LIB_GMOCK
1192
 
 
1193
 
struct UserDefinedClass {
1194
 
  bool operator==(const UserDefinedClass&) const { return true; }
1195
 
};
1196
 
 
1197
 
inline ostream& operator<<(ostream& out, const UserDefinedClass&) {
1198
 
  out << "OK";
1199
 
  return out;
1200
 
}
1201
 
 
1202
 
TEST(UserDefinedClass, logging) {
1203
 
  UserDefinedClass u;
1204
 
  vector<string> buf;
1205
 
  LOG_STRING(INFO, &buf) << u;
1206
 
  CHECK_EQ(1UL, buf.size());
1207
 
  CHECK(buf[0].find("OK") != string::npos);
1208
 
 
1209
 
  // We must be able to compile this.
1210
 
  CHECK_EQ(u, u);
1211
 
}