1 //
2 // Copyright (C) 2012 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #ifndef SHILL_MOCK_LOG_H_
18 #define SHILL_MOCK_LOG_H_
19 
20 // ScopedMockLog provides a way for unittests to validate log messages.  You can
21 // set expectations that certain log messages will be emited by your functions.
22 // To use ScopedMockLog, simply create a ScopedMockLog in your test and set
23 // expectations on its Log() method.  When the ScopedMockLog object goes out of
24 // scope, the log messages sent to it will be verified against expectations.
25 //
26 // Note: Use only one ScopedMockLog in a test because more than one won't work!
27 //
28 // Sample usage:
29 //
30 // You can verify that a function "DoSomething" emits a specific log text:
31 //
32 //   TEST_F(YourTest, DoesSomething) {
33 //     ScopedMockLog log;
34 //     EXPECT_CALL(log, Log(_, _, "Some log message text"));
35 //     DoSomething();  // Causes "Some log message text" to be logged.
36 //   }
37 //
38 // If the function DoSomething() executes something like:
39 //
40 //   LOG(INFO) << "Some log message text";
41 //
42 // then this will match the expectation.
43 //
44 // The first two parameters to ScopedMockLog::Log are the log severity and
45 // filename.  You can use them like this:
46 //
47 //   TEST_F(MockLogTest, MockLogSeverityAndFileAndMessage) {
48 //     ScopedMockLog log;
49 //     EXPECT_CALL(log, Log(logging::LOG_INFO, "your_file.cc", "your message"));
50 //     DoSomething();
51 //   }
52 //
53 // You can also use gMock matchers for matching arguments to Log():
54 //
55 //   TEST_F(MockLogTest, MatchWithGmockMatchers) {
56 //     ScopedMockLog log;
57 //     EXPECT_CALL(log, Log(::testing::Lt(::logging::LOG_ERROR),
58 //                          ::testing::EndsWith(".cc"),
59 //                          ::testing::StartsWith("Some")));
60 //     DoSomething();
61 //   }
62 //
63 // For some examples, see mock_log_unittest.cc.
64 
65 #include <string>
66 #include <gmock/gmock.h>
67 
68 #include "shill/logging.h"
69 
70 namespace shill {
71 
72 class ScopedMockLog {
73  public:
74   ScopedMockLog();
75   virtual ~ScopedMockLog();
76 
77   // Users set expecations on this method.  |severity| is defined in
78   // base/logging.h, like logging:::LOG_INFO.  |file| is the filename which
79   // issues the log message, like "foo.cc".  |user_messages| is the message you
80   // expect to see.  Arguments can be ignored by specifying ::testing::_.  You
81   // can also specify gMock matchers for arguments.
82   MOCK_METHOD3(Log, void(int severity, const char* file,
83                          const std::string& user_message));
84 
85  private:
86   // This function gets invoked by the logging subsystem for each message that
87   // is logged.  It calls ScopedMockLog::Log() declared above.  It must be a
88   // static method because the logging subsystem does not allow for an object to
89   // be passed.  See the typedef LogMessageHandlerFunction in base/logging.h for
90   // this function signature.
91   static bool HandleLogMessages(int severity,
92                                 const char* file,
93                                 int line,
94                                 size_t message_start,
95                                 const std::string& full_message);
96 
97   // A pointer to the current ScopedMockLog object.
98   static ScopedMockLog* instance_;
99 
100   // A pointer to any pre-existing message hander function in the logging
101   // system.  It is invoked after calling ScopedMockLog::Log().
102   ::logging::LogMessageHandlerFunction previous_handler_;
103 };
104 
105 // A NiceScopedMockLog is the same as ScopedMockLog, except it creates an
106 // implicit expectation on any Log() call.  This allows tests to avoid having
107 // to explictly expect log messages they don't care about.
108 class NiceScopedMockLog : public ScopedMockLog {
109  public:
110   NiceScopedMockLog();
111   ~NiceScopedMockLog() override;
112 };
113 
114 }  // namespace shill
115 
116 #endif  // SHILL_MOCK_LOG_H_
117