shill: ScopedMockLog. Useful for testing log messages.
ScopedMockLog provides a way for unittests to validate log messages.
You can set expectations that certain log messages will be emited
by your functions. See mock_log.h for usage information.
BUG=None
TEST=Added new unit tests. Ran all existing tests.
Change-Id: I544dbd9eadb6ca653e7f0fbaa5e8408cdbcf5207
Reviewed-on: https://gerrit.chromium.org/gerrit/22711
Commit-Ready: Gary Morain <gmorain@chromium.org>
Reviewed-by: Gary Morain <gmorain@chromium.org>
Tested-by: Gary Morain <gmorain@chromium.org>
diff --git a/mock_log.h b/mock_log.h
new file mode 100644
index 0000000..da25e76
--- /dev/null
+++ b/mock_log.h
@@ -0,0 +1,94 @@
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SHILL_MOCK_LOG_H_
+#define SHILL_MOCK_LOG_H_
+
+// ScopedMockLog provides a way for unittests to validate log messages. You can
+// set expectations that certain log messages will be emited by your functions.
+// To use ScopedMockLog, simply create a ScopedMockLog in your test and set
+// expectations on its Log() method. When the ScopedMockLog object goes out of
+// scope, the log messages sent to it will be verified against expectations.
+//
+// Note: Use only one ScopedMockLog in a test because more than one won't work!
+//
+// Sample usage:
+//
+// You can verify that a function "DoSomething" emits a specific log text:
+//
+// TEST_F(YourTest, DoesSomething) {
+// ScopedMockLog log;
+// EXPECT_CALL(log, Log(_, _, "Some log message text"));
+// DoSomething(); // Causes "Some log message text" to be logged.
+// }
+//
+// If the function DoSomething() executes something like:
+//
+// LOG(INFO) << "Some log message text";
+//
+// then this will match the expectation.
+//
+// The first two parameters to ScopedMockLog::Log are the log severity and
+// filename. You can use them like this:
+//
+// TEST_F(MockLogTest, MockLogSeverityAndFileAndMessage) {
+// ScopedMockLog log;
+// EXPECT_CALL(log, Log(logging::LOG_INFO, "your_file.cc", "your message"));
+// DoSomething();
+// }
+//
+// You can also use gMock matchers for matching arguments to Log():
+//
+// TEST_F(MockLogTest, MatchWithGmockMatchers) {
+// ScopedMockLog log;
+// EXPECT_CALL(log, Log(::testing::Lt(::logging::LOG_ERROR),
+// ::testing::EndsWith(".cc"),
+// ::testing::StartsWith("Some")));
+// DoSomething();
+// }
+//
+// For some examples, see mock_log_unittest.cc.
+
+#include <string>
+#include <base/logging.h>
+#include <gmock/gmock.h>
+
+namespace shill {
+
+class ScopedMockLog {
+ public:
+ ScopedMockLog();
+ ~ScopedMockLog();
+
+ // Users set expecations on this method. |severity| is defined in
+ // base/logging.h, like logging:::LOG_INFO. |file| is the filename which
+ // issues the log message, like "foo.cc". |user_messages| is the message you
+ // expect to see. Arguments can be ignored by specifying ::testing::_. You
+ // can also specify gMock matchers for arguments.
+ MOCK_METHOD3(Log, void(int severity, const char *file,
+ const std::string &user_message));
+
+ private:
+ // This function gets invoked by the logging subsystem for each message that
+ // is logged. It calls ScopedMockLog::Log() declared above. It must be a
+ // static method because the logging subsystem does not allow for an object to
+ // be passed. See the typedef LogMessageHandlerFunction in base/logging.h for
+ // this function signature.
+ static bool HandleLogMessages(int severity,
+ const char *file,
+ int line,
+ size_t message_start,
+ const std::string &full_message);
+
+ // A pointer to the current ScopedMockLog object.
+ static ScopedMockLog *instance_;
+
+ // A pointer to any pre-existing message hander function in the logging
+ // system. It is invoked after calling ScopedMockLog::Log().
+ ::logging::LogMessageHandlerFunction previous_handler_;
+};
+
+} // namespace shill
+
+#endif // SHILL_MOCK_LOG_H_