1 // 2 // Copyright (C) 2014 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_TESTING_H_ 18 #define SHILL_TESTING_H_ 19 20 #include <gmock/gmock.h> 21 #include <gtest/gtest.h> 22 23 #include "shill/error.h" 24 #include "shill/key_value_store.h" 25 #include "shill/logging.h" 26 27 namespace shill { 28 29 // A Google Mock action (similar to testing::ReturnPointee) that takes a pointer 30 // to a unique_ptr object, releases and returns the raw pointer managed by the 31 // unique_ptr object when the action is invoked. 32 // 33 // Example usage: 34 // 35 // TEST(FactoryTest, CreateStuff) { 36 // MockFactory factory; 37 // unique_ptr<Stuff> stuff(new Stuff()); 38 // EXPECT_CALL(factory, CreateStuff()) 39 // .WillOnce(ReturnAndReleasePointee(&stuff)); 40 // } 41 // 42 // If |factory.CreateStuff()| is called, the ownership of the Stuff object 43 // managed by |stuff| is transferred to the caller of |factory.CreateStuff()|. 44 // Otherwise, the Stuff object will be destroyed once |stuff| goes out of 45 // scope when the test completes. 46 ACTION_P(ReturnAndReleasePointee, unique_pointer) { 47 return unique_pointer->release(); 48 } 49 50 MATCHER(IsSuccess, "") { 51 return arg.IsSuccess(); 52 } 53 54 MATCHER(IsFailure, "") { 55 return arg.IsFailure(); 56 } 57 58 MATCHER_P2(ErrorIs, error_type, error_message, "") { 59 return error_type == arg.type() && error_message == arg.message(); 60 } 61 62 MATCHER_P(ErrorTypeIs, error_type, "") { 63 return error_type == arg.type(); 64 } 65 66 MATCHER(IsNullRefPtr, "") { 67 return !arg.get(); 68 } 69 70 MATCHER(NotNullRefPtr, "") { 71 return arg.get(); 72 } 73 74 // Use this matcher instead of passing RefPtrs directly into the arguments 75 // of EXPECT_CALL() because otherwise we may create un-cleaned-up references at 76 // system teardown. 77 MATCHER_P(IsRefPtrTo, ref_address, "") { 78 return arg.get() == ref_address; 79 } 80 81 MATCHER_P(KeyValueStoreEq, value, "") { 82 bool match = value.properties() == arg.properties(); 83 if (!match) { 84 *result_listener << "\nExpected KeyValueStore:\n" 85 << "\tproperties: " 86 << testing::PrintToString(value.properties()); 87 } 88 return match; 89 } 90 91 template<int error_argument_index> 92 class SetErrorTypeInArgumentAction { 93 public: 94 SetErrorTypeInArgumentAction(Error::Type error_type, bool warn_default) 95 : error_type_(error_type), 96 warn_default_(warn_default) {} 97 98 template <typename Result, typename ArgumentTuple> 99 Result Perform(const ArgumentTuple& args) const { 100 Error* error_arg = ::std::tr1::get<error_argument_index>(args); 101 if (error_arg) 102 error_arg->Populate(error_type_); 103 104 // You should be careful if you see this warning in your log messages: it is 105 // likely that you want to instead set a non-default expectation on this 106 // mock, to test the success code-paths. 107 if (warn_default_) 108 LOG(WARNING) << "Default action taken: set error to " 109 << error_type_ 110 << "(" << (error_arg ? error_arg->message() : "") << ")"; 111 } 112 113 private: 114 Error::Type error_type_; 115 bool warn_default_; 116 }; 117 118 // Many functions in the the DBus proxy classes take a (shill::Error*) output 119 // argument that is set to shill::Error::kOperationFailed to notify the caller 120 // synchronously of error conditions. 121 // 122 // If an error is not returned synchronously, a callback (passed as another 123 // argument to the function) must eventually be called with the result/error. 124 // Mock classes for these proxies should by default return failure synchronously 125 // so that callers do not expect the callback to be called. 126 template<int error_argument_index> 127 ::testing::PolymorphicAction<SetErrorTypeInArgumentAction<error_argument_index>> 128 SetOperationFailedInArgumentAndWarn() { 129 return ::testing::MakePolymorphicAction( 130 SetErrorTypeInArgumentAction<error_argument_index>( 131 Error::kOperationFailed, 132 true)); 133 } 134 135 // Use this action to set the (shill::Error*) output argument to any 136 // shill::Error value on mock DBus proxy method calls. 137 template<int error_argument_index> 138 ::testing::PolymorphicAction<SetErrorTypeInArgumentAction<error_argument_index>> 139 SetErrorTypeInArgument(Error::Type error_type) { 140 return ::testing::MakePolymorphicAction( 141 SetErrorTypeInArgumentAction<error_argument_index>(error_type, false)); 142 } 143 144 } // namespace shill 145 146 #endif // SHILL_TESTING_H_ 147