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