blob: cdc8353808d857c1f03eb86506aa3b0ef7450804 [file] [log] [blame]
Ben Chana55469d2014-01-27 16:35:29 -08001// 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 Prabhu303f6532014-08-29 20:17:16 -070011#include "shill/error.h"
12#include "shill/logging.h"
13
Ben Chana55469d2014-01-27 16:35:29 -080014namespace 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.
33ACTION_P(ReturnAndReleasePointee, scoped_pointer) {
34 return scoped_pointer->release();
35}
36
Ben Chanbe277dd2014-02-05 17:26:47 -080037MATCHER(IsSuccess, "") {
38 return arg.IsSuccess();
39}
40
41MATCHER(IsFailure, "") {
42 return arg.IsFailure();
43}
44
45MATCHER_P2(ErrorIs, error_type, error_message, "") {
46 return error_type == arg.type() && error_message == arg.message();
47}
48
Paul Stewartd4f26482014-04-25 19:12:03 -070049MATCHER(IsNullRefPtr, "") {
50 return !arg.get();
51}
52
53MATCHER(NotNullRefPtr, "") {
54 return arg.get();
55}
56
Paul Stewartf2860342014-05-09 14:29:16 -070057// 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.
60MATCHER_P(IsRefPtrTo, ref_address, "") {
61 return arg.get() == ref_address;
62}
63
Prathmesh Prabhu303f6532014-08-29 20:17:16 -070064template<int error_argument_index>
65class 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.
99template<int error_argument_index>
100::testing::PolymorphicAction<SetErrorTypeInArgumentAction<error_argument_index>>
101SetOperationFailedInArgumentAndWarn() {
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.
110template<int error_argument_index>
111::testing::PolymorphicAction<SetErrorTypeInArgumentAction<error_argument_index>>
112SetErrorTypeInArgument(Error::Type error_type) {
113 return ::testing::MakePolymorphicAction(
114 SetErrorTypeInArgumentAction<error_argument_index>(error_type, false));
115}
116
Ben Chana55469d2014-01-27 16:35:29 -0800117} // namespace shill
118
119#endif // SHILL_TESTING_H_