You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by be...@apache.org on 2011/06/05 11:10:34 UTC

svn commit: r1132266 [14/18] - in /incubator/mesos/trunk/third_party/libprocess: ./ third_party/glog-0.3.1/ third_party/glog-0.3.1/doc/ third_party/glog-0.3.1/m4/ third_party/glog-0.3.1/packages/ third_party/glog-0.3.1/packages/deb/ third_party/glog-0....

Added: incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/logging_striptest10.cc
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/logging_striptest10.cc?rev=1132266&view=auto
==============================================================================
--- incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/logging_striptest10.cc (added)
+++ incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/logging_striptest10.cc Sun Jun  5 09:10:30 2011
@@ -0,0 +1,35 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Sergey Ioffe
+
+#define GOOGLE_STRIP_LOG 10
+
+// Include the actual test.
+#include "logging_striptest_main.cc"

Added: incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/logging_striptest2.cc
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/logging_striptest2.cc?rev=1132266&view=auto
==============================================================================
--- incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/logging_striptest2.cc (added)
+++ incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/logging_striptest2.cc Sun Jun  5 09:10:30 2011
@@ -0,0 +1,35 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Sergey Ioffe
+
+#define GOOGLE_STRIP_LOG 2
+
+// Include the actual test.
+#include "logging_striptest_main.cc"

Added: incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/logging_striptest_main.cc
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/logging_striptest_main.cc?rev=1132266&view=auto
==============================================================================
--- incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/logging_striptest_main.cc (added)
+++ incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/logging_striptest_main.cc Sun Jun  5 09:10:30 2011
@@ -0,0 +1,68 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Sergey Ioffe
+
+// The common part of the striplog tests.
+
+#include <stdio.h>
+#include <string>
+#include <iosfwd>
+#include "glog/logging.h"
+#include "base/commandlineflags.h"
+#include "config.h"
+
+DECLARE_bool(logtostderr);
+
+using std::string;
+using namespace GOOGLE_NAMESPACE;
+
+int CheckNoReturn(bool b) {
+  string s;
+  if (b) {
+    LOG(FATAL) << "Fatal";
+  } else {
+    return 0;
+  }
+}
+
+struct A { };
+std::ostream &operator<<(std::ostream &str, const A&) {return str;}
+
+int main(int argc, char* argv[]) {
+  FLAGS_logtostderr = true;
+  InitGoogleLogging(argv[0]);
+  LOG(INFO) << "TESTMESSAGE INFO";
+  LOG(WARNING) << 2 << "something" << "TESTMESSAGE WARNING"
+               << 1 << 'c' << A() << std::endl;
+  LOG(ERROR) << "TESTMESSAGE ERROR";
+  bool flag = true;
+  (flag ? LOG(INFO) : LOG(ERROR)) << "TESTMESSAGE COND";
+  LOG(FATAL) << "TESTMESSAGE FATAL";
+}

Added: incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/logging_unittest.cc
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/logging_unittest.cc?rev=1132266&view=auto
==============================================================================
--- incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/logging_unittest.cc (added)
+++ incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/logging_unittest.cc Sun Jun  5 09:10:30 2011
@@ -0,0 +1,1210 @@
+// Copyright (c) 2002, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Ray Sidney
+
+#include "config_for_unittests.h"
+#include "utilities.h"
+
+#include <fcntl.h>
+#ifdef HAVE_GLOB_H
+# include <glob.h>
+#endif
+#include <sys/stat.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#include <iomanip>
+#include <iostream>
+#include <memory>
+#include <queue>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "base/commandlineflags.h"
+#include "glog/logging.h"
+#include "glog/raw_logging.h"
+#include "googletest.h"
+
+DECLARE_string(log_backtrace_at);  // logging.cc
+
+#ifdef HAVE_LIB_GFLAGS
+#include <gflags/gflags.h>
+#endif
+
+#ifdef HAVE_LIB_GMOCK
+#include <gmock/gmock.h>
+#include "mock-log.h"
+// Introduce several symbols from gmock.
+using testing::_;
+using testing::AnyNumber;
+using testing::HasSubstr;
+using testing::AllOf;
+using testing::StrNe;
+using testing::StrictMock;
+using testing::InitGoogleMock;
+using GOOGLE_NAMESPACE::glog_testing::ScopedMockLog;
+#endif
+
+using namespace std;
+using namespace GOOGLE_NAMESPACE;
+
+// Some non-advertised functions that we want to test or use.
+_START_GOOGLE_NAMESPACE_
+namespace base {
+namespace internal {
+bool GetExitOnDFatal();
+void SetExitOnDFatal(bool value);
+}  // namespace internal
+}  // namespace base
+_END_GOOGLE_NAMESPACE_
+
+static void TestLogging(bool check_counts);
+static void TestRawLogging();
+static void LogWithLevels(int v, int severity, bool err, bool alsoerr);
+static void TestLoggingLevels();
+static void TestLogString();
+static void TestLogSink();
+static void TestLogToString();
+static void TestLogSinkWaitTillSent();
+static void TestCHECK();
+static void TestDCHECK();
+static void TestSTREQ();
+static void TestBasename();
+static void TestSymlink();
+static void TestExtension();
+static void TestWrapper();
+static void TestErrno();
+static void TestTruncate();
+
+static int x = -1;
+static void BM_Check1(int n) {
+  while (n-- > 0) {
+    CHECK_GE(n, x);
+    CHECK_GE(n, x);
+    CHECK_GE(n, x);
+    CHECK_GE(n, x);
+    CHECK_GE(n, x);
+    CHECK_GE(n, x);
+    CHECK_GE(n, x);
+    CHECK_GE(n, x);
+  }
+}
+BENCHMARK(BM_Check1);
+
+static void CheckFailure(int a, int b, const char* file, int line, const char* msg);
+static void BM_Check3(int n) {
+  while (n-- > 0) {
+    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
+    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
+    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
+    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
+    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
+    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
+    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
+    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
+  }
+}
+BENCHMARK(BM_Check3);
+
+static void BM_Check2(int n) {
+  if (n == 17) {
+    x = 5;
+  }
+  while (n-- > 0) {
+    CHECK(n >= x);
+    CHECK(n >= x);
+    CHECK(n >= x);
+    CHECK(n >= x);
+    CHECK(n >= x);
+    CHECK(n >= x);
+    CHECK(n >= x);
+    CHECK(n >= x);
+  }
+}
+BENCHMARK(BM_Check2);
+
+static void CheckFailure(int a, int b, const char* file, int line, const char* msg) {
+}
+
+static void BM_logspeed(int n) {
+  while (n-- > 0) {
+    LOG(INFO) << "test message";
+  }
+}
+BENCHMARK(BM_logspeed);
+
+static void BM_vlog(int n) {
+  while (n-- > 0) {
+    VLOG(1) << "test message";
+  }
+}
+BENCHMARK(BM_vlog);
+
+int main(int argc, char **argv) {
+#ifdef HAVE_LIB_GFLAGS
+  ParseCommandLineFlags(&argc, &argv, true);
+#endif
+
+  // Test some basics before InitGoogleLogging:
+  CaptureTestStderr();
+  LogWithLevels(FLAGS_v, FLAGS_stderrthreshold,
+                FLAGS_logtostderr, FLAGS_alsologtostderr);
+  LogWithLevels(0, 0, 0, 0);  // simulate "before global c-tors"
+  const string early_stderr = GetCapturedTestStderr();
+
+  InitGoogleLogging(argv[0]);
+
+  RunSpecifiedBenchmarks();
+
+  FLAGS_logtostderr = true;
+
+  InitGoogleTest(&argc, argv);
+#ifdef HAVE_LIB_GMOCK
+  InitGoogleMock(&argc, argv);
+#endif
+
+  // so that death tests run before we use threads
+  CHECK_EQ(RUN_ALL_TESTS(), 0);
+
+  CaptureTestStderr();
+
+  // re-emit early_stderr
+  LogMessage("dummy", LogMessage::kNoLogPrefix, INFO).stream() << early_stderr;
+
+  TestLogging(true);
+  TestRawLogging();
+  TestLoggingLevels();
+  TestLogString();
+  TestLogSink();
+  TestLogToString();
+  TestLogSinkWaitTillSent();
+  TestCHECK();
+  TestDCHECK();
+  TestSTREQ();
+
+  // TODO: The golden test portion of this test is very flakey.
+  EXPECT_TRUE(
+      MungeAndDiffTestStderr(FLAGS_test_srcdir + "/src/logging_unittest.err"));
+
+  FLAGS_logtostderr = false;
+
+  TestBasename();
+  TestSymlink();
+  TestExtension();
+  TestWrapper();
+  TestErrno();
+  TestTruncate();
+
+  ShutdownGoogleLogging();
+
+  fprintf(stdout, "PASS\n");
+  return 0;
+}
+
+void TestLogging(bool check_counts) {
+  int64 base_num_infos   = LogMessage::num_messages(INFO);
+  int64 base_num_warning = LogMessage::num_messages(WARNING);
+  int64 base_num_errors  = LogMessage::num_messages(ERROR);
+
+  LOG(INFO) << string("foo ") << "bar " << 10 << ' ' << 3.4;
+  for ( int i = 0; i < 10; ++i ) {
+    int old_errno = errno;
+    errno = i;
+    PLOG_EVERY_N(ERROR, 2) << "Plog every 2, iteration " << COUNTER;
+    errno = old_errno;
+
+    LOG_EVERY_N(ERROR, 3) << "Log every 3, iteration " << COUNTER << endl;
+    LOG_EVERY_N(ERROR, 4) << "Log every 4, iteration " << COUNTER << endl;
+
+    LOG_IF_EVERY_N(WARNING, true, 5) << "Log if every 5, iteration " << COUNTER;
+    LOG_IF_EVERY_N(WARNING, false, 3)
+        << "Log if every 3, iteration " << COUNTER;
+    LOG_IF_EVERY_N(INFO, true, 1) << "Log if every 1, iteration " << COUNTER;
+    LOG_IF_EVERY_N(ERROR, (i < 3), 2)
+        << "Log if less than 3 every 2, iteration " << COUNTER;
+  }
+  LOG_IF(WARNING, true) << "log_if this";
+  LOG_IF(WARNING, false) << "don't log_if this";
+
+  char s[] = "array";
+  LOG(INFO) << s;
+  const char const_s[] = "const array";
+  LOG(INFO) << const_s;
+  int j = 1000;
+  LOG(ERROR) << string("foo") << ' '<< j << ' ' << setw(10) << j << " "
+             << setw(1) << hex << j;
+
+  LogMessage("foo", LogMessage::kNoLogPrefix, INFO).stream() << "no prefix";
+
+  if (check_counts) {
+    CHECK_EQ(base_num_infos   + 14, LogMessage::num_messages(INFO));
+    CHECK_EQ(base_num_warning + 3,  LogMessage::num_messages(WARNING));
+    CHECK_EQ(base_num_errors  + 15, LogMessage::num_messages(ERROR));
+  }
+}
+
+static void NoAllocNewHook() {
+  CHECK(false) << "unexpected new";
+}
+
+struct NewHook {
+  NewHook() {
+    g_new_hook = &NoAllocNewHook;
+  }
+  ~NewHook() {
+    g_new_hook = NULL;
+  }
+};
+
+TEST(DeathNoAllocNewHook, logging) {
+  // tests that NewHook used below works
+  NewHook new_hook;
+  ASSERT_DEATH({
+    new int;
+  }, "unexpected new");
+}
+
+void TestRawLogging() {
+  string* foo = new string("foo ");
+  string huge_str(50000, 'a');
+
+  FlagSaver saver;
+
+  // Check that RAW loggging does not use mallocs.
+  NewHook new_hook;
+
+  RAW_LOG(INFO, "%s%s%d%c%f", foo->c_str(), "bar ", 10, ' ', 3.4);
+  char s[] = "array";
+  RAW_LOG(WARNING, "%s", s);
+  const char const_s[] = "const array";
+  RAW_LOG(INFO, "%s", const_s);
+  void* p = reinterpret_cast<void*>(0x12345678);
+  RAW_LOG(INFO, "ptr %p", p);
+  p = NULL;
+  RAW_LOG(INFO, "ptr %p", p);
+  int j = 1000;
+  RAW_LOG(ERROR, "%s%d%c%010d%s%1x", foo->c_str(), j, ' ', j, " ", j);
+  RAW_VLOG(0, "foo %d", j);
+
+#ifdef NDEBUG
+  RAW_LOG(INFO, "foo %d", j);  // so that have same stderr to compare
+#else
+  RAW_DLOG(INFO, "foo %d", j);  // test RAW_DLOG in debug mode
+#endif
+
+  // test how long messages are chopped:
+  RAW_LOG(WARNING, "Huge string: %s", huge_str.c_str());
+  RAW_VLOG(0, "Huge string: %s", huge_str.c_str());
+
+  FLAGS_v = 0;
+  RAW_LOG(INFO, "log");
+  RAW_VLOG(0, "vlog 0 on");
+  RAW_VLOG(1, "vlog 1 off");
+  RAW_VLOG(2, "vlog 2 off");
+  RAW_VLOG(3, "vlog 3 off");
+  FLAGS_v = 2;
+  RAW_LOG(INFO, "log");
+  RAW_VLOG(1, "vlog 1 on");
+  RAW_VLOG(2, "vlog 2 on");
+  RAW_VLOG(3, "vlog 3 off");
+
+#ifdef NDEBUG
+  RAW_DCHECK(1 == 2, " RAW_DCHECK's shouldn't be compiled in normal mode");
+#endif
+
+  RAW_CHECK(1 == 1, "should be ok");
+  RAW_DCHECK(true, "should be ok");
+
+  delete foo;
+}
+
+void LogWithLevels(int v, int severity, bool err, bool alsoerr) {
+  RAW_LOG(INFO,
+          "Test: v=%d stderrthreshold=%d logtostderr=%d alsologtostderr=%d",
+          v, severity, err, alsoerr);
+
+  FlagSaver saver;
+
+  FLAGS_v = v;
+  FLAGS_stderrthreshold = severity;
+  FLAGS_logtostderr = err;
+  FLAGS_alsologtostderr = alsoerr;
+
+  RAW_VLOG(-1, "vlog -1");
+  RAW_VLOG(0, "vlog 0");
+  RAW_VLOG(1, "vlog 1");
+  RAW_LOG(INFO, "log info");
+  RAW_LOG(WARNING, "log warning");
+  RAW_LOG(ERROR, "log error");
+
+  VLOG(-1) << "vlog -1";
+  VLOG(0) << "vlog 0";
+  VLOG(1) << "vlog 1";
+  LOG(INFO) << "log info";
+  LOG(WARNING) << "log warning";
+  LOG(ERROR) << "log error";
+
+  VLOG_IF(-1, true) << "vlog_if -1";
+  VLOG_IF(-1, false) << "don't vlog_if -1";
+  VLOG_IF(0, true) << "vlog_if 0";
+  VLOG_IF(0, false) << "don't vlog_if 0";
+  VLOG_IF(1, true) << "vlog_if 1";
+  VLOG_IF(1, false) << "don't vlog_if 1";
+  LOG_IF(INFO, true) << "log_if info";
+  LOG_IF(INFO, false) << "don't log_if info";
+  LOG_IF(WARNING, true) << "log_if warning";
+  LOG_IF(WARNING, false) << "don't log_if warning";
+  LOG_IF(ERROR, true) << "log_if error";
+  LOG_IF(ERROR, false) << "don't log_if error";
+
+  int c;
+  c = 1; VLOG_IF(100, c -= 2) << "vlog_if 100 expr"; EXPECT_EQ(c, -1);
+  c = 1; VLOG_IF(0, c -= 2) << "vlog_if 0 expr"; EXPECT_EQ(c, -1);
+  c = 1; LOG_IF(INFO, c -= 2) << "log_if info expr"; EXPECT_EQ(c, -1);
+  c = 1; LOG_IF(ERROR, c -= 2) << "log_if error expr"; EXPECT_EQ(c, -1);
+  c = 2; VLOG_IF(0, c -= 2) << "don't vlog_if 0 expr"; EXPECT_EQ(c, 0);
+  c = 2; LOG_IF(ERROR, c -= 2) << "don't log_if error expr"; EXPECT_EQ(c, 0);
+
+  c = 3; LOG_IF_EVERY_N(INFO, c -= 4, 1) << "log_if info every 1 expr";
+  EXPECT_EQ(c, -1);
+  c = 3; LOG_IF_EVERY_N(ERROR, c -= 4, 1) << "log_if error every 1 expr";
+  EXPECT_EQ(c, -1);
+  c = 4; LOG_IF_EVERY_N(ERROR, c -= 4, 3) << "don't log_if info every 3 expr";
+  EXPECT_EQ(c, 0);
+  c = 4; LOG_IF_EVERY_N(ERROR, c -= 4, 3) << "don't log_if error every 3 expr";
+  EXPECT_EQ(c, 0);
+  c = 5; VLOG_IF_EVERY_N(0, c -= 4, 1) << "vlog_if 0 every 1 expr";
+  EXPECT_EQ(c, 1);
+  c = 5; VLOG_IF_EVERY_N(100, c -= 4, 3) << "vlog_if 100 every 3 expr";
+  EXPECT_EQ(c, 1);
+  c = 6; VLOG_IF_EVERY_N(0, c -= 6, 1) << "don't vlog_if 0 every 1 expr";
+  EXPECT_EQ(c, 0);
+  c = 6; VLOG_IF_EVERY_N(100, c -= 6, 3) << "don't vlog_if 100 every 1 expr";
+  EXPECT_EQ(c, 0);
+}
+
+void TestLoggingLevels() {
+  LogWithLevels(0, INFO, false, false);
+  LogWithLevels(1, INFO, false, false);
+  LogWithLevels(-1, INFO, false, false);
+  LogWithLevels(0, WARNING, false, false);
+  LogWithLevels(0, ERROR, false, false);
+  LogWithLevels(0, FATAL, false, false);
+  LogWithLevels(0, FATAL, true, false);
+  LogWithLevels(0, FATAL, false, true);
+  LogWithLevels(1, WARNING, false, false);
+  LogWithLevels(1, FATAL, false, true);
+}
+
+TEST(DeathRawCHECK, logging) {
+  ASSERT_DEATH(RAW_CHECK(false, "failure 1"),
+               "RAW: Check false failed: failure 1");
+  ASSERT_DEBUG_DEATH(RAW_DCHECK(1 == 2, "failure 2"),
+               "RAW: Check 1 == 2 failed: failure 2");
+}
+
+void TestLogString() {
+  vector<string> errors;
+  vector<string> *no_errors = NULL;
+
+  LOG_STRING(INFO, &errors) << "LOG_STRING: " << "collected info";
+  LOG_STRING(WARNING, &errors) << "LOG_STRING: " << "collected warning";
+  LOG_STRING(ERROR, &errors) << "LOG_STRING: " << "collected error";
+
+  LOG_STRING(INFO, no_errors) << "LOG_STRING: " << "reported info";
+  LOG_STRING(WARNING, no_errors) << "LOG_STRING: " << "reported warning";
+  LOG_STRING(ERROR, NULL) << "LOG_STRING: " << "reported error";
+
+  for (size_t i = 0; i < errors.size(); ++i) {
+    LOG(INFO) << "Captured by LOG_STRING:  " << errors[i];
+  }
+}
+
+void TestLogToString() {
+  string error;
+  string* no_error = NULL;
+
+  LOG_TO_STRING(INFO, &error) << "LOG_TO_STRING: " << "collected info";
+  LOG(INFO) << "Captured by LOG_TO_STRING:  " << error;
+  LOG_TO_STRING(WARNING, &error) << "LOG_TO_STRING: " << "collected warning";
+  LOG(INFO) << "Captured by LOG_TO_STRING:  " << error;
+  LOG_TO_STRING(ERROR, &error) << "LOG_TO_STRING: " << "collected error";
+  LOG(INFO) << "Captured by LOG_TO_STRING:  " << error;
+
+  LOG_TO_STRING(INFO, no_error) << "LOG_TO_STRING: " << "reported info";
+  LOG_TO_STRING(WARNING, no_error) << "LOG_TO_STRING: " << "reported warning";
+  LOG_TO_STRING(ERROR, NULL) << "LOG_TO_STRING: " << "reported error";
+}
+
+class TestLogSinkImpl : public LogSink {
+ public:
+  vector<string> errors;
+  virtual void send(LogSeverity severity, const char* full_filename,
+                    const char* base_filename, int line,
+                    const struct tm* tm_time,
+                    const char* message, size_t message_len) {
+    errors.push_back(
+      ToString(severity, base_filename, line, tm_time, message, message_len));
+  }
+};
+
+void TestLogSink() {
+  TestLogSinkImpl sink;
+  LogSink *no_sink = NULL;
+
+  LOG_TO_SINK(&sink, INFO) << "LOG_TO_SINK: " << "collected info";
+  LOG_TO_SINK(&sink, WARNING) << "LOG_TO_SINK: " << "collected warning";
+  LOG_TO_SINK(&sink, ERROR) << "LOG_TO_SINK: " << "collected error";
+
+  LOG_TO_SINK(no_sink, INFO) << "LOG_TO_SINK: " << "reported info";
+  LOG_TO_SINK(no_sink, WARNING) << "LOG_TO_SINK: " << "reported warning";
+  LOG_TO_SINK(NULL, ERROR) << "LOG_TO_SINK: " << "reported error";
+
+  LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, INFO)
+      << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected info";
+  LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, WARNING)
+      << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected warning";
+  LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, ERROR)
+      << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected error";
+
+  LOG_TO_SINK_BUT_NOT_TO_LOGFILE(no_sink, INFO)
+      << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed info";
+  LOG_TO_SINK_BUT_NOT_TO_LOGFILE(no_sink, WARNING)
+      << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed warning";
+  LOG_TO_SINK_BUT_NOT_TO_LOGFILE(NULL, ERROR)
+      << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed error";
+
+  LOG(INFO) << "Captured by LOG_TO_SINK:";
+  for (size_t i = 0; i < sink.errors.size(); ++i) {
+    LogMessage("foo", LogMessage::kNoLogPrefix, INFO).stream()
+      << sink.errors[i];
+  }
+}
+
+// For testing using CHECK*() on anonymous enums.
+enum {
+  CASE_A,
+  CASE_B
+};
+
+void TestCHECK() {
+  // Tests using CHECK*() on int values.
+  CHECK(1 == 1);
+  CHECK_EQ(1, 1);
+  CHECK_NE(1, 2);
+  CHECK_GE(1, 1);
+  CHECK_GE(2, 1);
+  CHECK_LE(1, 1);
+  CHECK_LE(1, 2);
+  CHECK_GT(2, 1);
+  CHECK_LT(1, 2);
+
+  // Tests using CHECK*() on anonymous enums.
+  // Apple's GCC doesn't like this.
+#if !defined(OS_MACOSX)
+  CHECK_EQ(CASE_A, CASE_A);
+  CHECK_NE(CASE_A, CASE_B);
+  CHECK_GE(CASE_A, CASE_A);
+  CHECK_GE(CASE_B, CASE_A);
+  CHECK_LE(CASE_A, CASE_A);
+  CHECK_LE(CASE_A, CASE_B);
+  CHECK_GT(CASE_B, CASE_A);
+  CHECK_LT(CASE_A, CASE_B);
+#endif
+}
+
+void TestDCHECK() {
+#ifdef NDEBUG
+  DCHECK( 1 == 2 ) << " DCHECK's shouldn't be compiled in normal mode";
+#endif
+  DCHECK( 1 == 1 );
+  DCHECK_EQ(1, 1);
+  DCHECK_NE(1, 2);
+  DCHECK_GE(1, 1);
+  DCHECK_GE(2, 1);
+  DCHECK_LE(1, 1);
+  DCHECK_LE(1, 2);
+  DCHECK_GT(2, 1);
+  DCHECK_LT(1, 2);
+
+  auto_ptr<int64> sptr(new int64);
+  int64* ptr = DCHECK_NOTNULL(sptr.get());
+  CHECK_EQ(ptr, sptr.get());
+}
+
+void TestSTREQ() {
+  CHECK_STREQ("this", "this");
+  CHECK_STREQ(NULL, NULL);
+  CHECK_STRCASEEQ("this", "tHiS");
+  CHECK_STRCASEEQ(NULL, NULL);
+  CHECK_STRNE("this", "tHiS");
+  CHECK_STRNE("this", NULL);
+  CHECK_STRCASENE("this", "that");
+  CHECK_STRCASENE(NULL, "that");
+  CHECK_STREQ((string("a")+"b").c_str(), "ab");
+  CHECK_STREQ(string("test").c_str(),
+              (string("te") + string("st")).c_str());
+}
+
+TEST(DeathSTREQ, logging) {
+  ASSERT_DEATH(CHECK_STREQ(NULL, "this"), "");
+  ASSERT_DEATH(CHECK_STREQ("this", "siht"), "");
+  ASSERT_DEATH(CHECK_STRCASEEQ(NULL, "siht"), "");
+  ASSERT_DEATH(CHECK_STRCASEEQ("this", "siht"), "");
+  ASSERT_DEATH(CHECK_STRNE(NULL, NULL), "");
+  ASSERT_DEATH(CHECK_STRNE("this", "this"), "");
+  ASSERT_DEATH(CHECK_STREQ((string("a")+"b").c_str(), "abc"), "");
+}
+
+TEST(CheckNOTNULL, Simple) {
+  int64 t;
+  void *ptr = static_cast<void *>(&t);
+  void *ref = CHECK_NOTNULL(ptr);
+  EXPECT_EQ(ptr, ref);
+  CHECK_NOTNULL(reinterpret_cast<char *>(ptr));
+  CHECK_NOTNULL(reinterpret_cast<unsigned char *>(ptr));
+  CHECK_NOTNULL(reinterpret_cast<int *>(ptr));
+  CHECK_NOTNULL(reinterpret_cast<int64 *>(ptr));
+}
+
+TEST(DeathCheckNN, Simple) {
+  ASSERT_DEATH(CHECK_NOTNULL(static_cast<void *>(NULL)), "");
+}
+
+// Get list of file names that match pattern
+static void GetFiles(const string& pattern, vector<string>* files) {
+  files->clear();
+#if defined(HAVE_GLOB_H)
+  glob_t g;
+  const int r = glob(pattern.c_str(), 0, NULL, &g);
+  CHECK((r == 0) || (r == GLOB_NOMATCH)) << ": error matching " << pattern;
+  for (int i = 0; i < g.gl_pathc; i++) {
+    files->push_back(string(g.gl_pathv[i]));
+  }
+  globfree(&g);
+#elif defined(OS_WINDOWS)
+  WIN32_FIND_DATAA data;
+  HANDLE handle = FindFirstFileA(pattern.c_str(), &data);
+  size_t index = pattern.rfind('\\');
+  if (index == string::npos) {
+    LOG(FATAL) << "No directory separator.";
+  }
+  const string dirname = pattern.substr(0, index + 1);
+  if (FAILED(handle)) {
+    // Finding no files is OK.
+    return;
+  }
+  do {
+    files->push_back(dirname + data.cFileName);
+  } while (FindNextFileA(handle, &data));
+  LOG_SYSRESULT(FindClose(handle));
+#else
+# error There is no way to do glob.
+#endif
+}
+
+// Delete files patching pattern
+static void DeleteFiles(const string& pattern) {
+  vector<string> files;
+  GetFiles(pattern, &files);
+  for (size_t i = 0; i < files.size(); i++) {
+    CHECK(unlink(files[i].c_str()) == 0) << ": " << strerror(errno);
+  }
+}
+
+static void CheckFile(const string& name, const string& expected_string) {
+  vector<string> files;
+  GetFiles(name + "*", &files);
+  CHECK_EQ(files.size(), 1);
+
+  FILE* file = fopen(files[0].c_str(), "r");
+  CHECK(file != NULL) << ": could not open " << files[0];
+  char buf[1000];
+  while (fgets(buf, sizeof(buf), file) != NULL) {
+    if (strstr(buf, expected_string.c_str()) != NULL) {
+      fclose(file);
+      return;
+    }
+  }
+  fclose(file);
+  LOG(FATAL) << "Did not find " << expected_string << " in " << files[0];
+}
+
+static void TestBasename() {
+  fprintf(stderr, "==== Test setting log file basename\n");
+  const string dest = FLAGS_test_tmpdir + "/logging_test_basename";
+  DeleteFiles(dest + "*");
+
+  SetLogDestination(INFO, dest.c_str());
+  LOG(INFO) << "message to new base";
+  FlushLogFiles(INFO);
+
+  CheckFile(dest, "message to new base");
+
+  // Release file handle for the destination file to unlock the file in Windows.
+  LogToStderr();
+  DeleteFiles(dest + "*");
+}
+
+static void TestSymlink() {
+#ifndef OS_WINDOWS
+  fprintf(stderr, "==== Test setting log file symlink\n");
+  string dest = FLAGS_test_tmpdir + "/logging_test_symlink";
+  string sym = FLAGS_test_tmpdir + "/symlinkbase";
+  DeleteFiles(dest + "*");
+  DeleteFiles(sym + "*");
+
+  SetLogSymlink(INFO, "symlinkbase");
+  SetLogDestination(INFO, dest.c_str());
+  LOG(INFO) << "message to new symlink";
+  FlushLogFiles(INFO);
+  CheckFile(sym, "message to new symlink");
+
+  DeleteFiles(dest + "*");
+  DeleteFiles(sym + "*");
+#endif
+}
+
+static void TestExtension() {
+  fprintf(stderr, "==== Test setting log file extension\n");
+  string dest = FLAGS_test_tmpdir + "/logging_test_extension";
+  DeleteFiles(dest + "*");
+
+  SetLogDestination(INFO, dest.c_str());
+  SetLogFilenameExtension("specialextension");
+  LOG(INFO) << "message to new extension";
+  FlushLogFiles(INFO);
+  CheckFile(dest, "message to new extension");
+
+  // Check that file name ends with extension
+  vector<string> filenames;
+  GetFiles(dest + "*", &filenames);
+  CHECK_EQ(filenames.size(), 1);
+  CHECK(strstr(filenames[0].c_str(), "specialextension") != NULL);
+
+  // Release file handle for the destination file to unlock the file in Windows.
+  LogToStderr();
+  DeleteFiles(dest + "*");
+}
+
+struct MyLogger : public base::Logger {
+  string data;
+
+  virtual void Write(bool should_flush,
+                     time_t timestamp,
+                     const char* message,
+                     int length) {
+    data.append(message, length);
+  }
+
+  virtual void Flush() { }
+
+  virtual uint32 LogSize() { return data.length(); }
+};
+
+static void TestWrapper() {
+  fprintf(stderr, "==== Test log wrapper\n");
+
+  MyLogger my_logger;
+  base::Logger* old_logger = base::GetLogger(INFO);
+  base::SetLogger(INFO, &my_logger);
+  LOG(INFO) << "Send to wrapped logger";
+  FlushLogFiles(INFO);
+  base::SetLogger(INFO, old_logger);
+
+  CHECK(strstr(my_logger.data.c_str(), "Send to wrapped logger") != NULL);
+}
+
+static void TestErrno() {
+  fprintf(stderr, "==== Test errno preservation\n");
+
+  errno = ENOENT;
+  TestLogging(false);
+  CHECK_EQ(errno, ENOENT);
+}
+
+static void TestOneTruncate(const char *path, int64 limit, int64 keep,
+                            int64 dsize, int64 ksize, int64 expect) {
+  int fd;
+  CHECK_ERR(fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0600));
+
+  const char *discardstr = "DISCARDME!", *keepstr = "KEEPME!";
+
+  // Fill the file with the requested data; first discard data, then kept data
+  int64 written = 0;
+  while (written < dsize) {
+    int bytes = min<int64>(dsize - written, strlen(discardstr));
+    CHECK_ERR(write(fd, discardstr, bytes));
+    written += bytes;
+  }
+  written = 0;
+  while (written < ksize) {
+    int bytes = min<int64>(ksize - written, strlen(keepstr));
+    CHECK_ERR(write(fd, keepstr, bytes));
+    written += bytes;
+  }
+
+  TruncateLogFile(path, limit, keep);
+
+  // File should now be shorter
+  struct stat statbuf;
+  CHECK_ERR(fstat(fd, &statbuf));
+  CHECK_EQ(statbuf.st_size, expect);
+  CHECK_ERR(lseek(fd, 0, SEEK_SET));
+
+  // File should contain the suffix of the original file
+  int buf_size = statbuf.st_size + 1;
+  char* buf = new char[buf_size];
+  memset(buf, 0, sizeof(buf));
+  CHECK_ERR(read(fd, buf, buf_size));
+
+  const char *p = buf;
+  int64 checked = 0;
+  while (checked < expect) {
+    int bytes = min<int64>(expect - checked, strlen(keepstr));
+    CHECK(!memcmp(p, keepstr, bytes));
+    checked += bytes;
+  }
+  close(fd);
+  delete[] buf;
+}
+
+static void TestTruncate() {
+#ifdef HAVE_UNISTD_H
+  fprintf(stderr, "==== Test log truncation\n");
+  string path = FLAGS_test_tmpdir + "/truncatefile";
+
+  // Test on a small file
+  TestOneTruncate(path.c_str(), 10, 10, 10, 10, 10);
+
+  // And a big file (multiple blocks to copy)
+  TestOneTruncate(path.c_str(), 2<<20, 4<<10, 3<<20, 4<<10, 4<<10);
+
+  // Check edge-case limits
+  TestOneTruncate(path.c_str(), 10, 20, 0, 20, 20);
+  TestOneTruncate(path.c_str(), 10, 0, 0, 0, 0);
+  TestOneTruncate(path.c_str(), 10, 50, 0, 10, 10);
+  TestOneTruncate(path.c_str(), 50, 100, 0, 30, 30);
+
+  // MacOSX 10.4 doesn't fail in this case.
+  // Windows doesn't have symlink.
+  // Let's just ignore this test for these cases.
+#if !defined(OS_MACOSX) && !defined(OS_WINDOWS)
+  // Through a symlink should fail to truncate
+  string linkname = path + ".link";
+  unlink(linkname.c_str());
+  CHECK_ERR(symlink(path.c_str(), linkname.c_str()));
+  TestOneTruncate(linkname.c_str(), 10, 10, 0, 30, 30);
+#endif
+
+  // The /proc/self path makes sense only for linux.
+#if defined(OS_LINUX)
+  // Through an open fd symlink should work
+  int fd;
+  CHECK_ERR(fd = open(path.c_str(), O_APPEND | O_WRONLY));
+  char fdpath[64];
+  snprintf(fdpath, sizeof(fdpath), "/proc/self/fd/%d", fd);
+  TestOneTruncate(fdpath, 10, 10, 10, 10, 10);
+#endif
+
+#endif
+}
+
+_START_GOOGLE_NAMESPACE_
+namespace glog_internal_namespace_ {
+extern  // in logging.cc
+bool SafeFNMatch_(const char* pattern, size_t patt_len,
+                  const char* str, size_t str_len);
+} // namespace glog_internal_namespace_
+using glog_internal_namespace_::SafeFNMatch_;
+_END_GOOGLE_NAMESPACE_
+
+static bool WrapSafeFNMatch(string pattern, string str) {
+  pattern += "abc";
+  str += "defgh";
+  return SafeFNMatch_(pattern.data(), pattern.size() - 3,
+                      str.data(), str.size() - 5);
+}
+
+TEST(SafeFNMatch, logging) {
+  CHECK(WrapSafeFNMatch("foo", "foo"));
+  CHECK(!WrapSafeFNMatch("foo", "bar"));
+  CHECK(!WrapSafeFNMatch("foo", "fo"));
+  CHECK(!WrapSafeFNMatch("foo", "foo2"));
+  CHECK(WrapSafeFNMatch("bar/foo.ext", "bar/foo.ext"));
+  CHECK(WrapSafeFNMatch("*ba*r/fo*o.ext*", "bar/foo.ext"));
+  CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/baz.ext"));
+  CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/foo"));
+  CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/foo.ext.zip"));
+  CHECK(WrapSafeFNMatch("ba?/*.ext", "bar/foo.ext"));
+  CHECK(WrapSafeFNMatch("ba?/*.ext", "baZ/FOO.ext"));
+  CHECK(!WrapSafeFNMatch("ba?/*.ext", "barr/foo.ext"));
+  CHECK(!WrapSafeFNMatch("ba?/*.ext", "bar/foo.ext2"));
+  CHECK(WrapSafeFNMatch("ba?/*", "bar/foo.ext2"));
+  CHECK(WrapSafeFNMatch("ba?/*", "bar/"));
+  CHECK(!WrapSafeFNMatch("ba?/?", "bar/"));
+  CHECK(!WrapSafeFNMatch("ba?/*", "bar"));
+}
+
+// TestWaitingLogSink will save messages here
+// No lock: Accessed only by TestLogSinkWriter thread
+// and after its demise by its creator.
+static vector<string> global_messages;
+
+// helper for TestWaitingLogSink below.
+// Thread that does the logic of TestWaitingLogSink
+// It's free to use LOG() itself.
+class TestLogSinkWriter : public Thread {
+ public:
+
+  TestLogSinkWriter() : should_exit_(false) {
+    SetJoinable(true);
+    Start();
+  }
+
+  // Just buffer it (can't use LOG() here).
+  void Buffer(const string& message) {
+    mutex_.Lock();
+    RAW_LOG(INFO, "Buffering");
+    messages_.push(message);
+    mutex_.Unlock();
+    RAW_LOG(INFO, "Buffered");
+  }
+
+  // Wait for the buffer to clear (can't use LOG() here).
+  void Wait() {
+    RAW_LOG(INFO, "Waiting");
+    mutex_.Lock();
+    while (!NoWork()) {
+      mutex_.Unlock();
+      SleepForMilliseconds(1);
+      mutex_.Lock();
+    }
+    RAW_LOG(INFO, "Waited");
+    mutex_.Unlock();
+  }
+
+  // Trigger thread exit.
+  void Stop() {
+    MutexLock l(&mutex_);
+    should_exit_ = true;
+  }
+
+ private:
+
+  // helpers ---------------
+
+  // For creating a "Condition".
+  bool NoWork() { return messages_.empty(); }
+  bool HaveWork() { return !messages_.empty() || should_exit_; }
+
+  // Thread body; CAN use LOG() here!
+  virtual void Run() {
+    while (1) {
+      mutex_.Lock();
+      while (!HaveWork()) {
+        mutex_.Unlock();
+        SleepForMilliseconds(1);
+        mutex_.Lock();
+      }
+      if (should_exit_ && messages_.empty()) {
+        mutex_.Unlock();
+        break;
+      }
+      // Give the main thread time to log its message,
+      // so that we get a reliable log capture to compare to golden file.
+      // Same for the other sleep below.
+      SleepForMilliseconds(20);
+      RAW_LOG(INFO, "Sink got a messages");  // only RAW_LOG under mutex_ here
+      string message = messages_.front();
+      messages_.pop();
+      // Normally this would be some more real/involved logging logic
+      // where LOG() usage can't be eliminated,
+      // e.g. pushing the message over with an RPC:
+      int messages_left = messages_.size();
+      mutex_.Unlock();
+      SleepForMilliseconds(20);
+      // May not use LOG while holding mutex_, because Buffer()
+      // acquires mutex_, and Buffer is called from LOG(),
+      // which has its own internal mutex:
+      // LOG()->LogToSinks()->TestWaitingLogSink::send()->Buffer()
+      LOG(INFO) << "Sink is sending out a message: " << message;
+      LOG(INFO) << "Have " << messages_left << " left";
+      global_messages.push_back(message);
+    }
+  }
+
+  // data ---------------
+
+  Mutex mutex_;
+  bool should_exit_;
+  queue<string> messages_;  // messages to be logged
+};
+
+// A log sink that exercises WaitTillSent:
+// it pushes data to a buffer and wakes up another thread to do the logging
+// (that other thread can than use LOG() itself),
+class TestWaitingLogSink : public LogSink {
+ public:
+
+  TestWaitingLogSink() {
+    tid_ = pthread_self();  // for thread-specific behavior
+    AddLogSink(this);
+  }
+  ~TestWaitingLogSink() {
+    RemoveLogSink(this);
+    writer_.Stop();
+    writer_.Join();
+  }
+
+  // (re)define LogSink interface
+
+  virtual void send(LogSeverity severity, const char* full_filename,
+                    const char* base_filename, int line,
+                    const struct tm* tm_time,
+                    const char* message, size_t message_len) {
+    // Push it to Writer thread if we are the original logging thread.
+    // Note: Something like ThreadLocalLogSink is a better choice
+    //       to do thread-specific LogSink logic for real.
+    if (pthread_equal(tid_, pthread_self())) {
+      writer_.Buffer(ToString(severity, base_filename, line,
+                              tm_time, message, message_len));
+    }
+  }
+  virtual void WaitTillSent() {
+    // Wait for Writer thread if we are the original logging thread.
+    if (pthread_equal(tid_, pthread_self()))  writer_.Wait();
+  }
+
+ private:
+
+  pthread_t tid_;
+  TestLogSinkWriter writer_;
+};
+
+// Check that LogSink::WaitTillSent can be used in the advertised way.
+// We also do golden-stderr comparison.
+static void TestLogSinkWaitTillSent() {
+  { TestWaitingLogSink sink;
+    // Sleeps give the sink threads time to do all their work,
+    // so that we get a reliable log capture to compare to the golden file.
+    LOG(INFO) << "Message 1";
+    SleepForMilliseconds(60);
+    LOG(ERROR) << "Message 2";
+    SleepForMilliseconds(60);
+    LOG(WARNING) << "Message 3";
+    SleepForMilliseconds(60);
+  }
+  for (size_t i = 0; i < global_messages.size(); ++i) {
+    LOG(INFO) << "Sink capture: " << global_messages[i];
+  }
+  CHECK_EQ(global_messages.size(), 3);
+}
+
+TEST(Strerror, logging) {
+  int errcode = EINTR;
+  char *msg = strdup(strerror(errcode));
+  int buf_size = strlen(msg) + 1;
+  char *buf = new char[buf_size];
+  CHECK_EQ(posix_strerror_r(errcode, NULL, 0), -1);
+  buf[0] = 'A';
+  CHECK_EQ(posix_strerror_r(errcode, buf, 0), -1);
+  CHECK_EQ(buf[0], 'A');
+  CHECK_EQ(posix_strerror_r(errcode, NULL, buf_size), -1);
+#if defined(OS_MACOSX) || defined(OS_FREEBSD) || defined(OS_OPENBSD)
+  // MacOSX or FreeBSD considers this case is an error since there is
+  // no enough space.
+  CHECK_EQ(posix_strerror_r(errcode, buf, 1), -1);
+#else
+  CHECK_EQ(posix_strerror_r(errcode, buf, 1), 0);
+#endif
+  CHECK_STREQ(buf, "");
+  CHECK_EQ(posix_strerror_r(errcode, buf, buf_size), 0);
+  CHECK_STREQ(buf, msg);
+  free(msg);
+  delete[] buf;
+}
+
+// Simple routines to look at the sizes of generated code for LOG(FATAL) and
+// CHECK(..) via objdump
+void MyFatal() {
+  LOG(FATAL) << "Failed";
+}
+void MyCheck(bool a, bool b) {
+  CHECK_EQ(a, b);
+}
+
+#ifdef HAVE_LIB_GMOCK
+
+TEST(DVLog, Basic) {
+  ScopedMockLog log;
+
+#if NDEBUG
+  // We are expecting that nothing is logged.
+  EXPECT_CALL(log, Log(_, _, _)).Times(0);
+#else
+  EXPECT_CALL(log, Log(INFO, __FILE__, "debug log"));
+#endif
+
+  FLAGS_v = 1;
+  DVLOG(1) << "debug log";
+}
+
+TEST(DVLog, V0) {
+  ScopedMockLog log;
+
+  // We are expecting that nothing is logged.
+  EXPECT_CALL(log, Log(_, _, _)).Times(0);
+
+  FLAGS_v = 0;
+  DVLOG(1) << "debug log";
+}
+
+TEST(LogAtLevel, Basic) {
+  ScopedMockLog log;
+
+  // The function version outputs "logging.h" as a file name.
+  EXPECT_CALL(log, Log(WARNING, StrNe(__FILE__), "function version"));
+  EXPECT_CALL(log, Log(INFO, __FILE__, "macro version"));
+
+  int severity = WARNING;
+  LogAtLevel(severity, "function version");
+
+  severity = INFO;
+  // We can use the macro version as a C++ stream.
+  LOG_AT_LEVEL(severity) << "macro" << ' ' << "version";
+}
+
+TEST(TestExitOnDFatal, ToBeOrNotToBe) {
+  // Check the default setting...
+  EXPECT_TRUE(base::internal::GetExitOnDFatal());
+
+  // Turn off...
+  base::internal::SetExitOnDFatal(false);
+  EXPECT_FALSE(base::internal::GetExitOnDFatal());
+
+  // We don't die.
+  {
+    ScopedMockLog log;
+    //EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
+    // LOG(DFATAL) has severity FATAL if debugging, but is
+    // downgraded to ERROR if not debugging.
+    const LogSeverity severity =
+#ifdef NDEBUG
+        ERROR;
+#else
+        FATAL;
+#endif
+    EXPECT_CALL(log, Log(severity, __FILE__, "This should not be fatal"));
+    LOG(DFATAL) << "This should not be fatal";
+  }
+
+  // Turn back on...
+  base::internal::SetExitOnDFatal(true);
+  EXPECT_TRUE(base::internal::GetExitOnDFatal());
+
+#ifdef GTEST_HAS_DEATH_TEST
+  // Death comes on little cats' feet.
+  EXPECT_DEBUG_DEATH({
+      LOG(DFATAL) << "This should be fatal in debug mode";
+    }, "This should be fatal in debug mode");
+#endif
+}
+
+#ifdef HAVE_STACKTRACE
+
+static void BacktraceAtHelper() {
+  LOG(INFO) << "Not me";
+
+// The vertical spacing of the next 3 lines is significant.
+  LOG(INFO) << "Backtrace me";
+}
+static int kBacktraceAtLine = __LINE__ - 2;  // The line of the LOG(INFO) above
+
+TEST(LogBacktraceAt, DoesNotBacktraceWhenDisabled) {
+  StrictMock<ScopedMockLog> log;
+
+  FLAGS_log_backtrace_at = "";
+
+  EXPECT_CALL(log, Log(_, _, "Backtrace me"));
+  EXPECT_CALL(log, Log(_, _, "Not me"));
+
+  BacktraceAtHelper();
+}
+
+TEST(LogBacktraceAt, DoesBacktraceAtRightLineWhenEnabled) {
+  StrictMock<ScopedMockLog> log;
+
+  char where[100];
+  snprintf(where, 100, "%s:%d", const_basename(__FILE__), kBacktraceAtLine);
+  FLAGS_log_backtrace_at = where;
+
+  // The LOG at the specified line should include a stacktrace which includes
+  // the name of the containing function, followed by the log message.
+  // We use HasSubstr()s instead of ContainsRegex() for environments
+  // which don't have regexp.
+  EXPECT_CALL(log, Log(_, _, AllOf(HasSubstr("stacktrace:"),
+                                   HasSubstr("BacktraceAtHelper"),
+                                   HasSubstr("main"),
+                                   HasSubstr("Backtrace me"))));
+  // Other LOGs should not include a backtrace.
+  EXPECT_CALL(log, Log(_, _, "Not me"));
+
+  BacktraceAtHelper();
+}
+
+#endif // HAVE_STACKTRACE
+
+#endif // HAVE_LIB_GMOCK
+
+struct UserDefinedClass {
+  bool operator==(const UserDefinedClass& rhs) const { return true; }
+};
+
+inline ostream& operator<<(ostream& out, const UserDefinedClass& u) {
+  out << "OK";
+  return out;
+}
+
+TEST(UserDefinedClass, logging) {
+  UserDefinedClass u;
+  vector<string> buf;
+  LOG_STRING(INFO, &buf) << u;
+  CHECK_EQ(1, buf.size());
+  CHECK(buf[0].find("OK") != string::npos);
+
+  // We must be able to compile this.
+  CHECK_EQ(u, u);
+}

Added: incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/logging_unittest.err
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/logging_unittest.err?rev=1132266&view=auto
==============================================================================
--- incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/logging_unittest.err (added)
+++ incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/logging_unittest.err Sun Jun  5 09:10:30 2011
@@ -0,0 +1,305 @@
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=2 logtostderr=0 alsologtostderr=0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
+WARNING: Logging before InitGoogleLogging() is written to STDERR
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=0 logtostderr=0 alsologtostderr=0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] foo bar 10 3.4
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 1: __SUCCESS__ [0]
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 3, iteration 1
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 4, iteration 1
+WDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 5, iteration 1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 1
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Log if less than 3 every 2, iteration 1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 2
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 3: __ENOENT__ [2]
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 3
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Log if less than 3 every 2, iteration 3
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 3, iteration 4
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 4
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 5: __EINTR__ [4]
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 4, iteration 5
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 5
+WDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 5, iteration 6
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 6
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 7: __ENXIO__ [6]
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 3, iteration 7
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 7
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 8
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 9: __ENOEXEC__ [8]
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 4, iteration 9
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 9
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 3, iteration 10
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 10
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if this
+IDATE TIME__ THREADID logging_unittest.cc:LINE] array
+IDATE TIME__ THREADID logging_unittest.cc:LINE] const array
+EDATE TIME__ THREADID logging_unittest.cc:LINE] foo 1000 0000001000 3e8
+no prefix
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: foo bar 10 3.400000
+WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: array
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: const array
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: ptr 0x12345678
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: ptr __NULLP__
+EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: foo 1000 0000001000 3e8
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: foo 1000
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: foo 1000
+WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: RAW_LOG ERROR: The Message was too long!
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: RAW_LOG ERROR: The Message was too long!
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0 on
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 1 on
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 2 on
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=0 logtostderr=0 alsologtostderr=0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=1 stderrthreshold=0 logtostderr=0 alsologtostderr=0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=-1 stderrthreshold=0 logtostderr=0 alsologtostderr=0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=1 logtostderr=0 alsologtostderr=0
+WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log error
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=2 logtostderr=0 alsologtostderr=0
+EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log error
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=3 logtostderr=0 alsologtostderr=0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=3 logtostderr=1 alsologtostderr=0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=3 logtostderr=0 alsologtostderr=1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=1 stderrthreshold=1 logtostderr=0 alsologtostderr=0
+WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log error
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=1 stderrthreshold=3 logtostderr=0 alsologtostderr=1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_STRING: reported info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_STRING: reported warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_STRING: reported error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_STRING:  LOG_STRING: collected info
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_STRING:  LOG_STRING: collected warning
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_STRING:  LOG_STRING: collected error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: reported info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: reported warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: reported error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_SINK:
+IDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: collected info
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_STRING:  LOG_TO_STRING: collected info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: collected warning
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_STRING:  LOG_TO_STRING: collected warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: collected error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_STRING:  LOG_TO_STRING: collected error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: reported info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: reported warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: reported error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Message 1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffering
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffered
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waiting
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Sink got a messages
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waited
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Sink is sending out a message: IDATE TIME__ THREADID logging_unittest.cc:LINE] Message 1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Have 0 left
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Message 2
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffering
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffered
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waiting
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Sink got a messages
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waited
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Sink is sending out a message: EDATE TIME__ THREADID logging_unittest.cc:LINE] Message 2
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Have 0 left
+WDATE TIME__ THREADID logging_unittest.cc:LINE] Message 3
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffering
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffered
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waiting
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Sink got a messages
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waited
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Sink is sending out a message: WDATE TIME__ THREADID logging_unittest.cc:LINE] Message 3
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Have 0 left
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Sink capture: IDATE TIME__ THREADID logging_unittest.cc:LINE] Message 1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Sink capture: EDATE TIME__ THREADID logging_unittest.cc:LINE] Message 2
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Sink capture: WDATE TIME__ THREADID logging_unittest.cc:LINE] Message 3

Added: incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/mock-log.h
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/mock-log.h?rev=1132266&view=auto
==============================================================================
--- incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/mock-log.h (added)
+++ incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/mock-log.h Sun Jun  5 09:10:30 2011
@@ -0,0 +1,155 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Zhanyong Wan
+//
+// Defines the ScopedMockLog class (using Google C++ Mocking
+// Framework), which is convenient for testing code that uses LOG().
+
+#ifndef GLOG_SRC_MOCK_LOG_H_
+#define GLOG_SRC_MOCK_LOG_H_
+
+// For GOOGLE_NAMESPACE. This must go first so we get _XOPEN_SOURCE.
+#include "utilities.h"
+
+#include <string>
+
+#include <gmock/gmock.h>
+
+#include "glog/logging.h"
+
+_START_GOOGLE_NAMESPACE_
+namespace glog_testing {
+
+// A ScopedMockLog object intercepts LOG() messages issued during its
+// lifespan.  Using this together with Google C++ Mocking Framework,
+// it's very easy to test how a piece of code calls LOG().  The
+// typical usage:
+//
+//   TEST(FooTest, LogsCorrectly) {
+//     ScopedMockLog log;
+//
+//     // We expect the WARNING "Something bad!" exactly twice.
+//     EXPECT_CALL(log, Log(WARNING, _, "Something bad!"))
+//         .Times(2);
+//
+//     // We allow foo.cc to call LOG(INFO) any number of times.
+//     EXPECT_CALL(log, Log(INFO, HasSubstr("/foo.cc"), _))
+//         .Times(AnyNumber());
+//
+//     Foo();  // Exercises the code under test.
+//   }
+class ScopedMockLog : public GOOGLE_NAMESPACE::LogSink {
+ public:
+  // When a ScopedMockLog object is constructed, it starts to
+  // intercept logs.
+  ScopedMockLog() { AddLogSink(this); }
+
+  // When the object is destructed, it stops intercepting logs.
+  virtual ~ScopedMockLog() { RemoveLogSink(this); }
+
+  // Implements the mock method:
+  //
+  //   void Log(LogSeverity severity, const string& file_path,
+  //            const string& message);
+  //
+  // The second argument to Send() is the full path of the source file
+  // in which the LOG() was issued.
+  //
+  // Note, that in a multi-threaded environment, all LOG() messages from a
+  // single thread will be handled in sequence, but that cannot be guaranteed
+  // for messages from different threads. In fact, if the same or multiple
+  // expectations are matched on two threads concurrently, their actions will
+  // be executed concurrently as well and may interleave.
+  MOCK_METHOD3(Log, void(GOOGLE_NAMESPACE::LogSeverity severity,
+                         const std::string& file_path,
+                         const std::string& message));
+
+ private:
+  // Implements the send() virtual function in class LogSink.
+  // Whenever a LOG() statement is executed, this function will be
+  // invoked with information presented in the LOG().
+  //
+  // The method argument list is long and carries much information a
+  // test usually doesn't care about, so we trim the list before
+  // forwarding the call to Log(), which is much easier to use in
+  // tests.
+  //
+  // We still cannot call Log() directly, as it may invoke other LOG()
+  // messages, either due to Invoke, or due to an error logged in
+  // Google C++ Mocking Framework code, which would trigger a deadlock
+  // since a lock is held during send().
+  //
+  // Hence, we save the message for WaitTillSent() which will be called after
+  // the lock on send() is released, and we'll call Log() inside
+  // WaitTillSent(). Since while a single send() call may be running at a
+  // time, multiple WaitTillSent() calls (along with the one send() call) may
+  // be running simultaneously, we ensure thread-safety of the exchange between
+  // send() and WaitTillSent(), and that for each message, LOG(), send(),
+  // WaitTillSent() and Log() are executed in the same thread.
+  virtual void send(GOOGLE_NAMESPACE::LogSeverity severity,
+                    const char* full_filename,
+                    const char* base_filename, int line, const tm* tm_time,
+                    const char* message, size_t message_len) {
+    // We are only interested in the log severity, full file name, and
+    // log message.
+    message_info_.severity = severity;
+    message_info_.file_path = full_filename;
+    message_info_.message = std::string(message, message_len);
+  }
+
+  // Implements the WaitTillSent() virtual function in class LogSink.
+  // It will be executed after send() and after the global logging lock is
+  // released, so calls within it (or rather within the Log() method called
+  // within) may also issue LOG() statements.
+  //
+  // LOG(), send(), WaitTillSent() and Log() will occur in the same thread for
+  // a given log message.
+  virtual void WaitTillSent() {
+    // First, and very importantly, we save a copy of the message being
+    // processed before calling Log(), since Log() may indirectly call send()
+    // and WaitTillSent() in the same thread again.
+    MessageInfo message_info = message_info_;
+    Log(message_info.severity, message_info.file_path, message_info.message);
+  }
+
+  // All relevant information about a logged message that needs to be passed
+  // from send() to WaitTillSent().
+  struct MessageInfo {
+    GOOGLE_NAMESPACE::LogSeverity severity;
+    std::string file_path;
+    std::string message;
+  };
+  MessageInfo message_info_;
+};
+
+}  // namespace glog_testing
+_END_GOOGLE_NAMESPACE_
+
+#endif  // GLOG_SRC_MOCK_LOG_H_

Added: incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/mock-log_test.cc
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/mock-log_test.cc?rev=1132266&view=auto
==============================================================================
--- incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/mock-log_test.cc (added)
+++ incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/mock-log_test.cc Sun Jun  5 09:10:30 2011
@@ -0,0 +1,106 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Zhanyong Wan
+
+// Tests the ScopedMockLog class.
+
+#include "mock-log.h"
+
+#include <string>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+namespace {
+
+using GOOGLE_NAMESPACE::INFO;
+using GOOGLE_NAMESPACE::WARNING;
+using GOOGLE_NAMESPACE::ERROR;
+using GOOGLE_NAMESPACE::glog_testing::ScopedMockLog;
+using std::string;
+using testing::_;
+using testing::HasSubstr;
+using testing::InSequence;
+using testing::InvokeWithoutArgs;
+
+// Tests that ScopedMockLog intercepts LOG()s when it's alive.
+TEST(ScopedMockLogTest, InterceptsLog) {
+  ScopedMockLog log;
+
+  InSequence s;
+  EXPECT_CALL(log, Log(WARNING, HasSubstr("/mock-log_test.cc"), "Fishy."));
+  EXPECT_CALL(log, Log(INFO, _, "Working..."))
+      .Times(2);
+  EXPECT_CALL(log, Log(ERROR, _, "Bad!!"));
+
+  LOG(WARNING) << "Fishy.";
+  LOG(INFO) << "Working...";
+  LOG(INFO) << "Working...";
+  LOG(ERROR) << "Bad!!";
+}
+
+void LogBranch() {
+  LOG(INFO) << "Logging a branch...";
+}
+
+void LogTree() {
+  LOG(INFO) << "Logging the whole tree...";
+}
+
+void LogForest() {
+  LOG(INFO) << "Logging the entire forest.";
+  LOG(INFO) << "Logging the entire forest..";
+  LOG(INFO) << "Logging the entire forest...";
+}
+
+// The purpose of the following test is to verify that intercepting logging
+// continues to work properly if a LOG statement is executed within the scope
+// of a mocked call.
+TEST(ScopedMockLogTest, LogDuringIntercept) {
+  ScopedMockLog log;
+  InSequence s;
+  EXPECT_CALL(log, Log(INFO, __FILE__, "Logging a branch..."))
+      .WillOnce(InvokeWithoutArgs(LogTree));
+  EXPECT_CALL(log, Log(INFO, __FILE__, "Logging the whole tree..."))
+      .WillOnce(InvokeWithoutArgs(LogForest));
+  EXPECT_CALL(log, Log(INFO, __FILE__, "Logging the entire forest."));
+  EXPECT_CALL(log, Log(INFO, __FILE__, "Logging the entire forest.."));
+  EXPECT_CALL(log, Log(INFO, __FILE__, "Logging the entire forest..."));
+  LogBranch();
+}
+
+}  // namespace
+
+int main(int argc, char **argv) {
+  GOOGLE_NAMESPACE::InitGoogleLogging(argv[0]);
+  testing::InitGoogleMock(&argc, argv);
+
+  return RUN_ALL_TESTS();
+}

Added: incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/raw_logging.cc
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/raw_logging.cc?rev=1132266&view=auto
==============================================================================
--- incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/raw_logging.cc (added)
+++ incubator/mesos/trunk/third_party/libprocess/third_party/glog-0.3.1/src/raw_logging.cc Sun Jun  5 09:10:30 2011
@@ -0,0 +1,172 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Maxim Lifantsev
+//
+// logging_unittest.cc covers the functionality herein
+
+#include "utilities.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <errno.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>               // for close() and write()
+#endif
+#include <fcntl.h>                 // for open()
+#include <time.h>
+#include "config.h"
+#include "glog/logging.h"          // To pick up flag settings etc.
+#include "glog/raw_logging.h"
+#include "base/commandlineflags.h"
+
+#ifdef HAVE_STACKTRACE
+# include "stacktrace.h"
+#endif
+
+#if defined(HAVE_SYSCALL_H)
+#include <syscall.h>                 // for syscall()
+#elif defined(HAVE_SYS_SYSCALL_H)
+#include <sys/syscall.h>                 // for syscall()
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if defined(HAVE_SYSCALL_H) || defined(HAVE_SYS_SYSCALL_H)
+# define safe_write(fd, s, len)  syscall(SYS_write, fd, s, len)
+#else
+  // Not so safe, but what can you do?
+# define safe_write(fd, s, len)  write(fd, s, len)
+#endif
+
+_START_GOOGLE_NAMESPACE_
+
+// Data for RawLog__ below. We simply pick up the latest
+// time data created by a normal log message to avoid calling
+// localtime_r which can allocate memory.
+static struct ::tm last_tm_time_for_raw_log;
+static int last_usecs_for_raw_log;
+
+void RawLog__SetLastTime(const struct ::tm& t, int usecs) {
+  memcpy(&last_tm_time_for_raw_log, &t, sizeof(last_tm_time_for_raw_log));
+  last_usecs_for_raw_log = usecs;
+}
+
+// CAVEAT: vsnprintf called from *DoRawLog below has some (exotic) code paths
+// that invoke malloc() and getenv() that might acquire some locks.
+// If this becomes a problem we should reimplement a subset of vsnprintf
+// that does not need locks and malloc.
+
+// Helper for RawLog__ below.
+// *DoRawLog writes to *buf of *size and move them past the written portion.
+// It returns true iff there was no overflow or error.
+static bool DoRawLog(char** buf, int* size, const char* format, ...) {
+  va_list ap;
+  va_start(ap, format);
+  int n = vsnprintf(*buf, *size, format, ap);
+  va_end(ap);
+  if (n < 0 || n > *size) return false;
+  *size -= n;
+  *buf += n;
+  return true;
+}
+
+// Helper for RawLog__ below.
+inline static bool VADoRawLog(char** buf, int* size,
+                              const char* format, va_list ap) {
+  int n = vsnprintf(*buf, *size, format, ap);
+  if (n < 0 || n > *size) return false;
+  *size -= n;
+  *buf += n;
+  return true;
+}
+
+static const int kLogBufSize = 3000;
+static bool crashed = false;
+static CrashReason crash_reason;
+static char crash_buf[kLogBufSize + 1] = { 0 };  // Will end in '\0'
+
+void RawLog__(LogSeverity severity, const char* file, int line,
+              const char* format, ...) {
+  if (!(FLAGS_logtostderr || severity >= FLAGS_stderrthreshold ||
+        FLAGS_alsologtostderr || !IsGoogleLoggingInitialized())) {
+    return;  // this stderr log message is suppressed
+  }
+  // can't call localtime_r here: it can allocate
+  struct ::tm& t = last_tm_time_for_raw_log;
+  char buffer[kLogBufSize];
+  char* buf = buffer;
+  int size = sizeof(buffer);
+
+  // NOTE: this format should match the specification in base/logging.h
+  DoRawLog(&buf, &size, "%c%02d%02d %02d:%02d:%02d.%06d %5u %s:%d] RAW: ",
+           LogSeverityNames[severity][0],
+           1 + t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec,
+           last_usecs_for_raw_log,
+           static_cast<unsigned int>(GetTID()),
+           const_basename(const_cast<char *>(file)), line);
+
+  // Record the position and size of the buffer after the prefix
+  const char* msg_start = buf;
+  const int msg_size = size;
+
+  va_list ap;
+  va_start(ap, format);
+  bool no_chop = VADoRawLog(&buf, &size, format, ap);
+  va_end(ap);
+  if (no_chop) {
+    DoRawLog(&buf, &size, "\n");
+  } else {
+    DoRawLog(&buf, &size, "RAW_LOG ERROR: The Message was too long!\n");
+  }
+  // We make a raw syscall to write directly to the stderr file descriptor,
+  // avoiding FILE buffering (to avoid invoking malloc()), and bypassing
+  // libc (to side-step any libc interception).
+  // We write just once to avoid races with other invocations of RawLog__.
+  safe_write(STDERR_FILENO, buffer, strlen(buffer));
+  if (severity == FATAL)  {
+    if (!sync_val_compare_and_swap(&crashed, false, true)) {
+      crash_reason.filename = file;
+      crash_reason.line_number = line;
+      memcpy(crash_buf, msg_start, msg_size);  // Don't include prefix
+      crash_reason.message = crash_buf;
+#ifdef HAVE_STACKTRACE
+      crash_reason.depth =
+          GetStackTrace(crash_reason.stack, ARRAYSIZE(crash_reason.stack), 1);
+#else
+      crash_reason.depth = 0;
+#endif
+      SetCrashReason(&crash_reason);
+    }
+    LogMessage::Fail();  // abort()
+  }
+}
+
+_END_GOOGLE_NAMESPACE_