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