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 12namespace net { 13namespace 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. 39class 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