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