Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Side by Side Diff: remoting/host/mock_callback.h

Issue 719983002: Reporting of policy errors via host-offline-reason: part 3 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@hor-nohoststatussender
Patch Set: git cl format Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « remoting/host/minimum_heartbeat_supporter.cc ('k') | remoting/host/mock_callback_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef REMOTING_HOST_MOCK_CALLBACK_H_ 5 #ifndef REMOTING_HOST_MOCK_CALLBACK_H_
6 #define REMOTING_HOST_MOCK_CALLBACK_H_ 6 #define REMOTING_HOST_MOCK_CALLBACK_H_
7 7
8 // TODO(lukasza): If possible, move this header file to base/mock_callback.h 8 // TODO(lukasza): If possible, move this header file to base/mock_callback.h
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.h"
12 #include "base/callback.h" 12 #include "base/callback.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/synchronization/lock.h"
13 15
14 #include "testing/gmock/include/gmock/gmock.h" 16 #include "testing/gmock/include/gmock/gmock.h"
15 17
16 namespace remoting { 18 namespace remoting {
17 19
20 // MockCallback<Sig> can be used to mock Callback<Sig> from base/callback.h
21 //
22 // Basic usage example:
23 //
24 // MockCallback<void(int)> mock_callback;
25 // EXPECT_CALL(mock_callback, Run(123)).Times(2);
26 // base::Callback<void(int)> callback = mock_callback.GetCallback();
Wez 2014/12/03 19:45:49 Is it important that GetCallback() is only called
Łukasz Anforowicz 2014/12/03 22:00:44 Sort of. EXPECT_CALL is not thread-safe wrt Callb
27 //
28 // // Use |callback| in the remainder of the test.
29 // // GMock will enforce the expectations from above.
30 //
31 // HasRemainingCallbacks usage example:
Wez 2014/12/03 19:45:49 HasRemainingCallbacks has not been introduced yet,
Łukasz Anforowicz 2014/12/03 22:00:44 Good point. I am not sure about this - Some tests
32 //
33 // MockCallback<int()> mock_callback;
34 // EXPECT_CALL(mock_callback, Run()).WillOnce(Return(123));
35 // HypotheticalFunctionUnderTest(mock_callback.GetCallback());
36 // EXPECT_FALSE(mock_callback.HasRemainingCallbacks())
37 // << "Verify that FunctionUnderTest didn't store the callback "
38 // << "and therefore callers of FunctionUnderTest don't have to "
39 // << "worry about lifetime of arguments bound to the callback";
Wez 2014/12/03 19:45:49 You need to be very clear on the threading semanti
Łukasz Anforowicz 2014/12/03 22:00:44 I don't understand: - HasRemainingCallbacks is thr
40 //
41 // Thread safety notes:
42 //
43 // Calling Run on a Callback returned from MockCallback::GetCallback
44 // - Is *not* thread-safe wrt setting default actions and expectations (via
45 // ON_CALL and EXPECT_CALL gMock macros).
Wez 2014/12/03 19:45:49 This is not very clear; you mean that the call exp
Łukasz Anforowicz 2014/12/03 22:00:44 One cannot call EXPECT_CALL and Run in parallel.
46 // - Is thread-safe wrt other Run calls and destroying MockCallback.
Wez 2014/12/03 19:45:49 What are the semantics if a callback still exists
Łukasz Anforowicz 2014/12/03 22:00:44 This is documented in "What happens when Callback:
47 //
48 // This is similar to the guarantees described at
49 // https://code.google.com/p/googlemock/wiki/CookBook#Using_Google_Mock_and_Th reads
50 // except that the guarantees hold on all platforms.
51 //
52 // What happens when Callback::Run is called after MockCallback is destroyed:
Wez 2014/12/03 19:45:49 This contradicts the GetCallback comment, though.
Łukasz Anforowicz 2014/12/03 22:00:44 Acknowledged.
53 //
54 // - gTest EXPECT failure will be triggered
55 // - gMock's default return value will be returned - see:
56 // https://code.google.com/p/googlemock/wiki/CookBook#Setting_the_Default_Va lue_for_a_Return_Type
57
58 // Implementation notes:
59 //
60 // WeakPtr-like code
61 // -----------------
62 //
63 // Relationship between MockCallback and MockCallbackTracker is similar
64 // to the relationship between WeakPtrFactory<T> and WeakPtr<T>. We don't
65 // use WeakPtrFactory<T> and WeakPtr<T>, because:
Wez 2014/12/03 19:45:49 This comment is very confusing; it's not clear wha
66 // - WeakPtrs can only bind to methods without return values
67 // (enforced by a static assert in bind_internal.h:402).
68 // - WeakPtr impose task-specific, thread-safety-restrictions that are
69 // not present in Callback that MockCallback is mocking.
70 // - For MockCallback we don't necessarily want the behavior where Callbacks
71 // bound to WeakPtr are translated into no-ops, before the bound function
72 // gets to execute. In MockCallback case we want the test to have control of
73 // what happens in this case (i.e. gtest EXPECT, rather than a no-op;
74 // note that we cannot use gtest ASSERT for non-void-returning Run method).
75
18 template <typename Sig> 76 template <typename Sig>
19 class MockCallback; 77 class MockCallback;
20 78
21 template <typename R> 79 template <typename R>
22 class MockCallback<R()> { 80 class MockCallback<R()> {
Wez 2014/12/03 19:45:49 It looks like you should be able to put most of th
Łukasz Anforowicz 2014/12/03 22:00:44 Ack - I'll try this out.
23 public: 81 public:
24 MOCK_CONST_METHOD0_T(Run, R()); 82 MOCK_CONST_METHOD0_T(Run, R());
25 83
26 MockCallback() { 84 MockCallback() : mock_callback_tracker_(new MockCallbackTracker(this)) {}
27 } 85
86 ~MockCallback() { mock_callback_tracker_->MarkMockCallbackAsDead(); }
28 87
29 // Caller of GetCallback has to guarantee that the returned callback 88 // Caller of GetCallback has to guarantee that the returned callback
30 // will not be run after |this| is destroyed. 89 // will not be run after |this| is destroyed.
31 base::Callback<R()> GetCallback() { 90 base::Callback<R()> GetCallback() const {
32 return base::Bind(&MockCallback<R()>::Run, base::Unretained(this)); 91 return base::Bind(&MockCallbackTracker::Run, mock_callback_tracker_);
92 }
93
94 // Returns |true| if callbacks returned by |GetCallback| have not been
95 // destroyed yet.
96 bool HasRemainingCallbacks() const {
97 bool is_tracker_field_the_only_ref = mock_callback_tracker_->HasOneRef();
98 return !is_tracker_field_the_only_ref;
33 } 99 }
34 100
35 private: 101 private:
102 class MockCallbackTracker
103 : public base::RefCountedThreadSafe<MockCallbackTracker> {
104 public:
105 MockCallbackTracker(MockCallback* mock_callback)
106 : mock_callback_(mock_callback), is_mock_callback_alive_(true) {}
107
108 R Run() {
109 base::AutoLock auto_lock(lock_);
110 EXPECT_TRUE(is_mock_callback_alive_)
111 << "MockCallback should be alive when Callback::Run happens.";
112 return is_mock_callback_alive_ ? mock_callback_->Run()
113 : testing::DefaultValue<R>::Get();
114 }
115
116 void MarkMockCallbackAsDead() {
117 base::AutoLock auto_lock(lock_);
118 is_mock_callback_alive_ = false;
119 mock_callback_ = nullptr;
120 }
121
122 private:
123 // Ref-counting helpers.
124 friend class base::RefCountedThreadSafe<MockCallbackTracker>;
125 ~MockCallbackTracker() {}
126
127 MockCallback<R()>* mock_callback_;
128 base::Lock lock_;
129 bool is_mock_callback_alive_;
130 };
131
132 scoped_refptr<MockCallbackTracker> mock_callback_tracker_;
133
36 DISALLOW_COPY_AND_ASSIGN(MockCallback); 134 DISALLOW_COPY_AND_ASSIGN(MockCallback);
37 }; 135 };
38 136
137 template <typename R, typename A1>
138 class MockCallback<R(A1)> {
139 public:
140 MOCK_CONST_METHOD1_T(Run, R(A1));
141
142 MockCallback() : mock_callback_tracker_(new MockCallbackTracker(this)) {}
143
144 ~MockCallback() { mock_callback_tracker_->MarkMockCallbackAsDead(); }
145
146 // Caller of GetCallback has to guarantee that the returned callback
147 // will not be run after |this| is destroyed.
148 base::Callback<R(A1)> GetCallback() const {
149 return base::Bind(&MockCallbackTracker::Run, mock_callback_tracker_);
150 }
151
152 // Returns |true| if callbacks returned by |GetCallback| have not been
153 // destroyed yet.
154 bool HasRemainingCallbacks() const {
155 bool is_tracker_field_the_only_ref = mock_callback_tracker_->HasOneRef();
156 return !is_tracker_field_the_only_ref;
157 }
158
159 private:
160 class MockCallbackTracker
161 : public base::RefCountedThreadSafe<MockCallbackTracker> {
162 public:
163 MockCallbackTracker(MockCallback* mock_callback)
164 : mock_callback_(mock_callback), is_mock_callback_alive_(true) {}
165
166 R Run(A1 a1) {
167 base::AutoLock auto_lock(lock_);
168 EXPECT_TRUE(is_mock_callback_alive_)
169 << "MockCallback should be alive when Callback::Run happens.";
170 return is_mock_callback_alive_ ? mock_callback_->Run(a1)
171 : testing::DefaultValue<R>::Get();
172 }
173
174 void MarkMockCallbackAsDead() {
175 base::AutoLock auto_lock(lock_);
176 is_mock_callback_alive_ = false;
177 mock_callback_ = nullptr;
178 }
179
180 private:
181 // Ref-counting helpers.
182 friend class base::RefCountedThreadSafe<MockCallbackTracker>;
183 ~MockCallbackTracker() {}
184
185 MockCallback<R(A1)>* mock_callback_;
186 base::Lock lock_;
187 bool is_mock_callback_alive_;
188 };
189
190 scoped_refptr<MockCallbackTracker> mock_callback_tracker_;
191
192 DISALLOW_COPY_AND_ASSIGN(MockCallback);
193 };
194
39 typedef MockCallback<void(void)> MockClosure; 195 typedef MockCallback<void(void)> MockClosure;
40 196
41 } // namespace remoting 197 } // namespace remoting
42 198
43 #endif // REMOTING_HOST_MOCK_CALLBACK_H_ 199 #endif // REMOTING_HOST_MOCK_CALLBACK_H_
OLDNEW
« no previous file with comments | « remoting/host/minimum_heartbeat_supporter.cc ('k') | remoting/host/mock_callback_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698