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