Ben Chan | a55469d | 2014-01-27 16:35:29 -0800 | [diff] [blame] | 1 | // Copyright (c) 2014 The Chromium OS 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 SHILL_TESTING_H_ |
| 6 | #define SHILL_TESTING_H_ |
| 7 | |
| 8 | #include <gmock/gmock.h> |
| 9 | #include <gtest/gtest.h> |
| 10 | |
Prathmesh Prabhu | 303f653 | 2014-08-29 20:17:16 -0700 | [diff] [blame] | 11 | #include "shill/error.h" |
| 12 | #include "shill/logging.h" |
| 13 | |
Ben Chan | a55469d | 2014-01-27 16:35:29 -0800 | [diff] [blame] | 14 | namespace shill { |
| 15 | |
| 16 | // A Google Mock action (similar to testing::ReturnPointee) that takes a pointer |
| 17 | // to a scoped_ptr object, releases and returns the raw pointer managed by the |
| 18 | // scoped_ptr object when the action is invoked. |
| 19 | // |
| 20 | // Example usage: |
| 21 | // |
| 22 | // TEST(FactoryTest, CreateStuff) { |
| 23 | // MockFactory factory; |
| 24 | // scoped_ptr<Stuff> stuff(new Stuff()); |
| 25 | // EXPECT_CALL(factory, CreateStuff()) |
| 26 | // .WillOnce(ReturnAndReleasePointee(&stuff)); |
| 27 | // } |
| 28 | // |
| 29 | // If |factory.CreateStuff()| is called, the ownership of the Stuff object |
| 30 | // managed by |stuff| is transferred to the caller of |factory.CreateStuff()|. |
| 31 | // Otherwise, the Stuff object will be destroyed once |stuff| goes out of |
| 32 | // scope when the test completes. |
| 33 | ACTION_P(ReturnAndReleasePointee, scoped_pointer) { |
| 34 | return scoped_pointer->release(); |
| 35 | } |
| 36 | |
Ben Chan | be277dd | 2014-02-05 17:26:47 -0800 | [diff] [blame] | 37 | MATCHER(IsSuccess, "") { |
| 38 | return arg.IsSuccess(); |
| 39 | } |
| 40 | |
| 41 | MATCHER(IsFailure, "") { |
| 42 | return arg.IsFailure(); |
| 43 | } |
| 44 | |
| 45 | MATCHER_P2(ErrorIs, error_type, error_message, "") { |
| 46 | return error_type == arg.type() && error_message == arg.message(); |
| 47 | } |
| 48 | |
Paul Stewart | d4f2648 | 2014-04-25 19:12:03 -0700 | [diff] [blame] | 49 | MATCHER(IsNullRefPtr, "") { |
| 50 | return !arg.get(); |
| 51 | } |
| 52 | |
| 53 | MATCHER(NotNullRefPtr, "") { |
| 54 | return arg.get(); |
| 55 | } |
| 56 | |
Paul Stewart | f286034 | 2014-05-09 14:29:16 -0700 | [diff] [blame] | 57 | // Use this matcher instead of passing RefPtrs directly into the arguments |
| 58 | // of EXPECT_CALL() because otherwise we may create un-cleaned-up references at |
| 59 | // system teardown. |
| 60 | MATCHER_P(IsRefPtrTo, ref_address, "") { |
| 61 | return arg.get() == ref_address; |
| 62 | } |
| 63 | |
Prathmesh Prabhu | 303f653 | 2014-08-29 20:17:16 -0700 | [diff] [blame] | 64 | template<int error_argument_index> |
| 65 | class SetErrorTypeInArgumentAction { |
| 66 | public: |
| 67 | SetErrorTypeInArgumentAction(Error::Type error_type, bool warn_default) |
| 68 | : error_type_(error_type), |
| 69 | warn_default_(warn_default) {} |
| 70 | |
| 71 | template <typename Result, typename ArgumentTuple> |
| 72 | Result Perform(const ArgumentTuple& args) const { |
| 73 | Error *error_arg = ::std::tr1::get<error_argument_index>(args); |
| 74 | if (error_arg) |
| 75 | error_arg->Populate(error_type_); |
| 76 | |
| 77 | // You should be careful if you see this warning in your log messages: it is |
| 78 | // likely that you want to instead set a non-default expectation on this |
| 79 | // mock, to test the success code-paths. |
| 80 | if (warn_default_) |
| 81 | LOG(WARNING) << "Default action taken: set error to " |
| 82 | << error_type_ |
| 83 | << "(" << (error_arg ? error_arg->message() : "") << ")"; |
| 84 | } |
| 85 | |
| 86 | private: |
| 87 | Error::Type error_type_; |
| 88 | bool warn_default_; |
| 89 | }; |
| 90 | |
| 91 | // Many functions in the the DBus proxy classes take a (shill::Error *) output |
| 92 | // argument that is set to shill::Error::kOperationFailed to notify the caller |
| 93 | // synchronously of error conditions. |
| 94 | // |
| 95 | // If an error is not returned synchronously, a callback (passed as another |
| 96 | // argument to the function) must eventually be called with the result/error. |
| 97 | // Mock classes for these proxies should by default return failure synchronously |
| 98 | // so that callers do not expect the callback to be called. |
| 99 | template<int error_argument_index> |
| 100 | ::testing::PolymorphicAction<SetErrorTypeInArgumentAction<error_argument_index>> |
| 101 | SetOperationFailedInArgumentAndWarn() { |
| 102 | return ::testing::MakePolymorphicAction( |
| 103 | SetErrorTypeInArgumentAction<error_argument_index>( |
| 104 | Error::kOperationFailed, |
| 105 | true)); |
| 106 | } |
| 107 | |
| 108 | // Use this action to set the (shill::Error *) output argument to any |
| 109 | // shill::Error value on mock DBus proxy method calls. |
| 110 | template<int error_argument_index> |
| 111 | ::testing::PolymorphicAction<SetErrorTypeInArgumentAction<error_argument_index>> |
| 112 | SetErrorTypeInArgument(Error::Type error_type) { |
| 113 | return ::testing::MakePolymorphicAction( |
| 114 | SetErrorTypeInArgumentAction<error_argument_index>(error_type, false)); |
| 115 | } |
| 116 | |
Ben Chan | a55469d | 2014-01-27 16:35:29 -0800 | [diff] [blame] | 117 | } // namespace shill |
| 118 | |
| 119 | #endif // SHILL_TESTING_H_ |