xref: /aosp_15_r20/external/cronet/base/test/mock_log.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2015 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_TEST_MOCK_LOG_H_
6*6777b538SAndroid Build Coastguard Worker #define BASE_TEST_MOCK_LOG_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
9*6777b538SAndroid Build Coastguard Worker 
10*6777b538SAndroid Build Coastguard Worker #include <string>
11*6777b538SAndroid Build Coastguard Worker 
12*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/synchronization/lock.h"
14*6777b538SAndroid Build Coastguard Worker #include "testing/gmock/include/gmock/gmock.h"
15*6777b538SAndroid Build Coastguard Worker 
16*6777b538SAndroid Build Coastguard Worker namespace base {
17*6777b538SAndroid Build Coastguard Worker namespace test {
18*6777b538SAndroid Build Coastguard Worker 
19*6777b538SAndroid Build Coastguard Worker // A MockLog object intercepts LOG() messages issued during its lifespan.  Using
20*6777b538SAndroid Build Coastguard Worker // this together with gMock, it's very easy to test how a piece of code calls
21*6777b538SAndroid Build Coastguard Worker // LOG().  The typical usage:
22*6777b538SAndroid Build Coastguard Worker //
23*6777b538SAndroid Build Coastguard Worker //   TEST(FooTest, LogsCorrectly) {
24*6777b538SAndroid Build Coastguard Worker //     MockLog log;
25*6777b538SAndroid Build Coastguard Worker //
26*6777b538SAndroid Build Coastguard Worker //     // We expect the WARNING "Something bad!" exactly twice.
27*6777b538SAndroid Build Coastguard Worker //     EXPECT_CALL(log, Log(WARNING, _, "Something bad!"))
28*6777b538SAndroid Build Coastguard Worker //         .Times(2);
29*6777b538SAndroid Build Coastguard Worker //
30*6777b538SAndroid Build Coastguard Worker //     // We allow foo.cc to call LOG(INFO) any number of times.
31*6777b538SAndroid Build Coastguard Worker //     EXPECT_CALL(log, Log(INFO, HasSubstr("/foo.cc"), _))
32*6777b538SAndroid Build Coastguard Worker //         .Times(AnyNumber());
33*6777b538SAndroid Build Coastguard Worker //
34*6777b538SAndroid Build Coastguard Worker //     log.StartCapturingLogs();  // Call this after done setting expectations.
35*6777b538SAndroid Build Coastguard Worker //     Foo();  // Exercises the code under test.
36*6777b538SAndroid Build Coastguard Worker //   }
37*6777b538SAndroid Build Coastguard Worker //
38*6777b538SAndroid Build Coastguard Worker // CAVEAT: base/logging does not allow a thread to call LOG() again when it's
39*6777b538SAndroid Build Coastguard Worker // already inside a LOG() call.  Doing so will cause a deadlock.  Therefore,
40*6777b538SAndroid Build Coastguard Worker // it's the user's responsibility to not call LOG() in an action triggered by
41*6777b538SAndroid Build Coastguard Worker // MockLog::Log().  You may call RAW_LOG() instead.
42*6777b538SAndroid Build Coastguard Worker class MockLog {
43*6777b538SAndroid Build Coastguard Worker  public:
44*6777b538SAndroid Build Coastguard Worker   // Creates a MockLog object that is not capturing logs.  If it were to start
45*6777b538SAndroid Build Coastguard Worker   // to capture logs, it could be a problem if some other threads already exist
46*6777b538SAndroid Build Coastguard Worker   // and are logging, as the user hasn't had a chance to set up expectation on
47*6777b538SAndroid Build Coastguard Worker   // this object yet (calling a mock method before setting the expectation is
48*6777b538SAndroid Build Coastguard Worker   // UNDEFINED behavior).
49*6777b538SAndroid Build Coastguard Worker   MockLog();
50*6777b538SAndroid Build Coastguard Worker 
51*6777b538SAndroid Build Coastguard Worker   MockLog(const MockLog&) = delete;
52*6777b538SAndroid Build Coastguard Worker   MockLog& operator=(const MockLog&) = delete;
53*6777b538SAndroid Build Coastguard Worker 
54*6777b538SAndroid Build Coastguard Worker   // When the object is destructed, it stops intercepting logs.
55*6777b538SAndroid Build Coastguard Worker   ~MockLog();
56*6777b538SAndroid Build Coastguard Worker 
57*6777b538SAndroid Build Coastguard Worker   // Starts log capturing if the object isn't already doing so.
58*6777b538SAndroid Build Coastguard Worker   // Otherwise crashes.
59*6777b538SAndroid Build Coastguard Worker   void StartCapturingLogs();
60*6777b538SAndroid Build Coastguard Worker 
61*6777b538SAndroid Build Coastguard Worker   // Stops log capturing if the object is capturing logs.  Otherwise crashes.
62*6777b538SAndroid Build Coastguard Worker   void StopCapturingLogs();
63*6777b538SAndroid Build Coastguard Worker 
64*6777b538SAndroid Build Coastguard Worker   // Log method is invoked for every log message before it's sent to other log
65*6777b538SAndroid Build Coastguard Worker   // destinations (if any).  The method should return true to signal that it
66*6777b538SAndroid Build Coastguard Worker   // handled the message and the message should not be sent to other log
67*6777b538SAndroid Build Coastguard Worker   // destinations.
68*6777b538SAndroid Build Coastguard Worker   MOCK_METHOD5(Log,
69*6777b538SAndroid Build Coastguard Worker                bool(int severity,
70*6777b538SAndroid Build Coastguard Worker                     const char* file,
71*6777b538SAndroid Build Coastguard Worker                     int line,
72*6777b538SAndroid Build Coastguard Worker                     size_t message_start,
73*6777b538SAndroid Build Coastguard Worker                     const std::string& str));
74*6777b538SAndroid Build Coastguard Worker 
75*6777b538SAndroid Build Coastguard Worker  private:
76*6777b538SAndroid Build Coastguard Worker   // The currently active mock log.
77*6777b538SAndroid Build Coastguard Worker   static MockLog* g_instance_;
78*6777b538SAndroid Build Coastguard Worker 
79*6777b538SAndroid Build Coastguard Worker   // Lock protecting access to g_instance_.
80*6777b538SAndroid Build Coastguard Worker   static Lock g_lock;
81*6777b538SAndroid Build Coastguard Worker 
82*6777b538SAndroid Build Coastguard Worker   // Static function which is set as the logging message handler.
83*6777b538SAndroid Build Coastguard Worker   // Called once for each message.
84*6777b538SAndroid Build Coastguard Worker   static bool LogMessageHandler(int severity,
85*6777b538SAndroid Build Coastguard Worker                                 const char* file,
86*6777b538SAndroid Build Coastguard Worker                                 int line,
87*6777b538SAndroid Build Coastguard Worker                                 size_t message_start,
88*6777b538SAndroid Build Coastguard Worker                                 const std::string& str);
89*6777b538SAndroid Build Coastguard Worker 
90*6777b538SAndroid Build Coastguard Worker   // True if this object is currently capturing logs.
91*6777b538SAndroid Build Coastguard Worker   bool is_capturing_logs_;
92*6777b538SAndroid Build Coastguard Worker 
93*6777b538SAndroid Build Coastguard Worker   // The previous handler to restore when the MockLog is destroyed.
94*6777b538SAndroid Build Coastguard Worker   logging::LogMessageHandlerFunction previous_handler_;
95*6777b538SAndroid Build Coastguard Worker };
96*6777b538SAndroid Build Coastguard Worker 
97*6777b538SAndroid Build Coastguard Worker }  // namespace test
98*6777b538SAndroid Build Coastguard Worker }  // namespace base
99*6777b538SAndroid Build Coastguard Worker 
100*6777b538SAndroid Build Coastguard Worker #endif  // BASE_TEST_MOCK_LOG_H_
101