1 // Copyright 2011 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <sstream>
6 #include <string>
7 
8 #include "build/build_config.h"
9 #include "partition_alloc/partition_alloc_base/debug/debugging_buildflags.h"
10 #include "partition_alloc/partition_alloc_base/logging.h"
11 
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 
15 namespace partition_alloc::internal::logging {
16 
17 namespace {
18 
19 using ::testing::_;
20 using ::testing::Return;
21 
22 class MockLogSource {
23  public:
24   MOCK_METHOD0(Log, const char*());
25 };
26 
TEST(PALoggingTest,BasicLogging)27 TEST(PALoggingTest, BasicLogging) {
28   MockLogSource mock_log_source;
29   constexpr int kTimes =
30 #if BUILDFLAG(PA_DCHECK_IS_ON)
31       16;
32 #else
33       8;
34 #endif
35   EXPECT_CALL(mock_log_source, Log())
36       .Times(kTimes)
37       .WillRepeatedly(Return("log message"));
38 
39   SetMinLogLevel(LOGGING_INFO);
40 
41   EXPECT_TRUE(PA_LOG_IS_ON(INFO));
42   EXPECT_EQ(BUILDFLAG(PA_DCHECK_IS_ON), PA_DLOG_IS_ON(INFO));
43   EXPECT_TRUE(PA_VLOG_IS_ON(0));
44 
45   PA_LOG(INFO) << mock_log_source.Log();
46   PA_LOG_IF(INFO, true) << mock_log_source.Log();
47   PA_PLOG(INFO) << mock_log_source.Log();
48   PA_PLOG_IF(INFO, true) << mock_log_source.Log();
49   PA_VLOG(0) << mock_log_source.Log();
50   PA_VLOG_IF(0, true) << mock_log_source.Log();
51   PA_VPLOG(0) << mock_log_source.Log();
52   PA_VPLOG_IF(0, true) << mock_log_source.Log();
53 
54   PA_DLOG(INFO) << mock_log_source.Log();
55   PA_DLOG_IF(INFO, true) << mock_log_source.Log();
56   PA_DPLOG(INFO) << mock_log_source.Log();
57   PA_DPLOG_IF(INFO, true) << mock_log_source.Log();
58   PA_DVLOG(0) << mock_log_source.Log();
59   PA_DVLOG_IF(0, true) << mock_log_source.Log();
60   PA_DVPLOG(0) << mock_log_source.Log();
61   PA_DVPLOG_IF(0, true) << mock_log_source.Log();
62 }
63 
TEST(PALoggingTest,LogIsOn)64 TEST(PALoggingTest, LogIsOn) {
65   SetMinLogLevel(LOGGING_INFO);
66   EXPECT_TRUE(PA_LOG_IS_ON(INFO));
67   EXPECT_TRUE(PA_LOG_IS_ON(WARNING));
68   EXPECT_TRUE(PA_LOG_IS_ON(ERROR));
69   EXPECT_TRUE(PA_LOG_IS_ON(FATAL));
70   EXPECT_TRUE(PA_LOG_IS_ON(DFATAL));
71 
72   SetMinLogLevel(LOGGING_WARNING);
73   EXPECT_FALSE(PA_LOG_IS_ON(INFO));
74   EXPECT_TRUE(PA_LOG_IS_ON(WARNING));
75   EXPECT_TRUE(PA_LOG_IS_ON(ERROR));
76   EXPECT_TRUE(PA_LOG_IS_ON(FATAL));
77   EXPECT_TRUE(PA_LOG_IS_ON(DFATAL));
78 
79   SetMinLogLevel(LOGGING_ERROR);
80   EXPECT_FALSE(PA_LOG_IS_ON(INFO));
81   EXPECT_FALSE(PA_LOG_IS_ON(WARNING));
82   EXPECT_TRUE(PA_LOG_IS_ON(ERROR));
83   EXPECT_TRUE(PA_LOG_IS_ON(FATAL));
84   EXPECT_TRUE(PA_LOG_IS_ON(DFATAL));
85 
86   SetMinLogLevel(LOGGING_FATAL + 1);
87   EXPECT_FALSE(PA_LOG_IS_ON(INFO));
88   EXPECT_FALSE(PA_LOG_IS_ON(WARNING));
89   EXPECT_FALSE(PA_LOG_IS_ON(ERROR));
90   // PA_LOG_IS_ON(FATAL) should always be true.
91   EXPECT_TRUE(PA_LOG_IS_ON(FATAL));
92   // If BUILDFLAG(PA_DCHECK_IS_ON) then DFATAL is FATAL.
93   EXPECT_EQ(BUILDFLAG(PA_DCHECK_IS_ON), PA_LOG_IS_ON(DFATAL));
94 }
95 
TEST(PALoggingTest,LoggingIsLazyBySeverity)96 TEST(PALoggingTest, LoggingIsLazyBySeverity) {
97   MockLogSource mock_log_source;
98   EXPECT_CALL(mock_log_source, Log()).Times(0);
99 
100   SetMinLogLevel(LOGGING_WARNING);
101 
102   EXPECT_FALSE(PA_LOG_IS_ON(INFO));
103   EXPECT_FALSE(PA_DLOG_IS_ON(INFO));
104   EXPECT_FALSE(PA_VLOG_IS_ON(1));
105 
106   PA_LOG(INFO) << mock_log_source.Log();
107   PA_LOG_IF(INFO, false) << mock_log_source.Log();
108   PA_PLOG(INFO) << mock_log_source.Log();
109   PA_PLOG_IF(INFO, false) << mock_log_source.Log();
110   PA_VLOG(1) << mock_log_source.Log();
111   PA_VLOG_IF(1, true) << mock_log_source.Log();
112   PA_VPLOG(1) << mock_log_source.Log();
113   PA_VPLOG_IF(1, true) << mock_log_source.Log();
114 
115   PA_DLOG(INFO) << mock_log_source.Log();
116   PA_DLOG_IF(INFO, true) << mock_log_source.Log();
117   PA_DPLOG(INFO) << mock_log_source.Log();
118   PA_DPLOG_IF(INFO, true) << mock_log_source.Log();
119   PA_DVLOG(1) << mock_log_source.Log();
120   PA_DVLOG_IF(1, true) << mock_log_source.Log();
121   PA_DVPLOG(1) << mock_log_source.Log();
122   PA_DVPLOG_IF(1, true) << mock_log_source.Log();
123 }
124 
125 // Always log-to-stderr(RawLog) if message handler is not assigned.
TEST(PALoggingTest,LogIsAlwaysToStdErr)126 TEST(PALoggingTest, LogIsAlwaysToStdErr) {
127   MockLogSource mock_log_source_stderr;
128   SetMinLogLevel(LOGGING_INFO);
129   EXPECT_TRUE(PA_LOG_IS_ON(INFO));
130   EXPECT_CALL(mock_log_source_stderr, Log()).Times(1).WillOnce(Return("foo"));
131   PA_LOG(INFO) << mock_log_source_stderr.Log();
132 }
133 
TEST(PALoggingTest,DebugLoggingReleaseBehavior)134 TEST(PALoggingTest, DebugLoggingReleaseBehavior) {
135 #if BUILDFLAG(PA_DCHECK_IS_ON)
136   int debug_only_variable = 1;
137 #endif
138   // These should avoid emitting references to |debug_only_variable|
139   // in release mode.
140   PA_DLOG_IF(INFO, debug_only_variable) << "test";
141   PA_DLOG_ASSERT(debug_only_variable) << "test";
142   PA_DPLOG_IF(INFO, debug_only_variable) << "test";
143   PA_DVLOG_IF(1, debug_only_variable) << "test";
144 }
145 
146 }  // namespace
147 
148 }  // namespace partition_alloc::internal::logging
149