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

Side by Side Diff: mojo/public/cpp/bindings/tests/binding_callback_unittest.cc

Issue 2250183003: Make the fuchsia mojo/public repo the source of truth. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 4 years, 4 months 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
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium 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 #include "build/build_config.h"
6 #include "gtest/gtest.h"
7 #include "mojo/public/cpp/bindings/binding.h"
8 #include "mojo/public/cpp/bindings/interface_ptr.h"
9 #include "mojo/public/cpp/bindings/string.h"
10 #include "mojo/public/cpp/system/message_pipe.h"
11 #include "mojo/public/cpp/utility/run_loop.h"
12 #include "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.h"
13
14 ///////////////////////////////////////////////////////////////////////////////
15 //
16 // The tests in this file are designed to test the interaction between a
17 // Callback and its associated Binding. If a Callback is deleted before
18 // being used we DCHECK fail--unless the associated Binding has already
19 // been closed or deleted. This contract must be explained to the Mojo
20 // application developer. For example it is the developer's responsibility to
21 // ensure that the Binding is destroyed before an unused Callback is destroyed.
22 //
23 ///////////////////////////////////////////////////////////////////////////////
24
25 namespace mojo {
26 namespace test {
27 namespace {
28
29 // A Runnable object that saves the last value it sees via the
30 // provided int32_t*. Used on the client side.
31 class ValueSaver {
32 public:
33 explicit ValueSaver(int32_t* last_value_seen)
34 : last_value_seen_(last_value_seen) {}
35 void Run(int32_t x) const { *last_value_seen_ = x; }
36
37 private:
38 int32_t* const last_value_seen_;
39 };
40
41 // An implementation of sample::Provider used on the server side.
42 // It only implements one of the methods: EchoInt().
43 // All it does is save the values and Callbacks it sees.
44 class InterfaceImpl : public sample::Provider {
45 public:
46 InterfaceImpl()
47 : last_server_value_seen_(0),
48 callback_saved_(new Callback<void(int32_t)>()) {}
49
50 ~InterfaceImpl() override {
51 if (callback_saved_) {
52 delete callback_saved_;
53 }
54 }
55
56 // Run's the callback previously saved from the last invocation
57 // of |EchoInt()|.
58 bool RunCallback() {
59 if (callback_saved_) {
60 callback_saved_->Run(last_server_value_seen_);
61 return true;
62 }
63 return false;
64 }
65
66 // Delete's the previously saved callback.
67 void DeleteCallback() {
68 delete callback_saved_;
69 callback_saved_ = nullptr;
70 }
71
72 // sample::Provider implementation
73
74 // Saves its two input values in member variables and does nothing else.
75 void EchoInt(int32_t x, const Callback<void(int32_t)>& callback) override {
76 last_server_value_seen_ = x;
77 *callback_saved_ = callback;
78 }
79
80 void EchoString(const String& a,
81 const Callback<void(String)>& callback) override {
82 MOJO_CHECK(false) << "Not implemented.";
83 }
84
85 void EchoStrings(const String& a,
86 const String& b,
87 const Callback<void(String, String)>& callback) override {
88 MOJO_CHECK(false) << "Not implemented.";
89 }
90
91 void EchoMessagePipeHandle(
92 ScopedMessagePipeHandle a,
93 const Callback<void(ScopedMessagePipeHandle)>& callback) override {
94 MOJO_CHECK(false) << "Not implemented.";
95 }
96
97 void EchoEnum(sample::Enum a,
98 const Callback<void(sample::Enum)>& callback) override {
99 MOJO_CHECK(false) << "Not implemented.";
100 }
101
102 void resetLastServerValueSeen() { last_server_value_seen_ = 0; }
103
104 int32_t last_server_value_seen() const { return last_server_value_seen_; }
105
106 private:
107 int32_t last_server_value_seen_;
108 Callback<void(int32_t)>* callback_saved_;
109 };
110
111 class BindingCallbackTest : public testing::Test {
112 public:
113 ~BindingCallbackTest() override {}
114
115 protected:
116 int32_t last_client_callback_value_seen_;
117 sample::ProviderPtr interface_ptr_;
118
119 void PumpMessages() { loop_.RunUntilIdle(); }
120
121 private:
122 RunLoop loop_;
123 };
124
125 // Tests that the InterfacePtr and the Binding can communicate with each
126 // other normally.
127 TEST_F(BindingCallbackTest, Basic) {
128 // Create the ServerImpl and the Binding.
129 InterfaceImpl server_impl;
130 Binding<sample::Provider> binding(&server_impl, GetProxy(&interface_ptr_));
131
132 // Initialize the test values.
133 server_impl.resetLastServerValueSeen();
134 last_client_callback_value_seen_ = 0;
135
136 // Invoke the Echo method.
137 interface_ptr_->EchoInt(7, ValueSaver(&last_client_callback_value_seen_));
138 PumpMessages();
139
140 // Check that server saw the correct value, but the client has not yet.
141 EXPECT_EQ(7, server_impl.last_server_value_seen());
142 EXPECT_EQ(0, last_client_callback_value_seen_);
143
144 // Now run the Callback.
145 server_impl.RunCallback();
146 PumpMessages();
147
148 // Check that the client has now seen the correct value.
149 EXPECT_EQ(7, last_client_callback_value_seen_);
150
151 // Initialize the test values again.
152 server_impl.resetLastServerValueSeen();
153 last_client_callback_value_seen_ = 0;
154
155 // Invoke the Echo method again.
156 interface_ptr_->EchoInt(13, ValueSaver(&last_client_callback_value_seen_));
157 PumpMessages();
158
159 // Check that server saw the correct value, but the client has not yet.
160 EXPECT_EQ(13, server_impl.last_server_value_seen());
161 EXPECT_EQ(0, last_client_callback_value_seen_);
162
163 // Now run the Callback again.
164 server_impl.RunCallback();
165 PumpMessages();
166
167 // Check that the client has now seen the correct value again.
168 EXPECT_EQ(13, last_client_callback_value_seen_);
169 }
170
171 // Tests that running the Callback after the Binding has been deleted
172 // results in a clean failure.
173 TEST_F(BindingCallbackTest, DeleteBindingThenRunCallback) {
174 // Create the ServerImpl.
175 InterfaceImpl server_impl;
176 {
177 // Create the binding in an inner scope so it can be deleted first.
178 Binding<sample::Provider> binding(&server_impl, GetProxy(&interface_ptr_));
179
180 // Initialize the test values.
181 server_impl.resetLastServerValueSeen();
182 last_client_callback_value_seen_ = 0;
183
184 // Invoke the Echo method.
185 interface_ptr_->EchoInt(7, ValueSaver(&last_client_callback_value_seen_));
186 PumpMessages();
187 }
188 // The binding has now been destroyed and the pipe is closed.
189
190 // Check that server saw the correct value, but the client has not yet.
191 EXPECT_EQ(7, server_impl.last_server_value_seen());
192 EXPECT_EQ(0, last_client_callback_value_seen_);
193
194 // Now try to run the Callback. This should do nothing since the pipe
195 // is closed.
196 EXPECT_TRUE(server_impl.RunCallback());
197 PumpMessages();
198
199 // Check that the client has still not seen the correct value.
200 EXPECT_EQ(0, last_client_callback_value_seen_);
201
202 // Attempt to invoke the method again and confirm that an error was
203 // encountered.
204 interface_ptr_->EchoInt(13, ValueSaver(&last_client_callback_value_seen_));
205 PumpMessages();
206 EXPECT_TRUE(interface_ptr_.encountered_error());
207 }
208
209 // Tests that deleting a Callback without running it after the corresponding
210 // binding has already been deleted does not result in a crash.
211 TEST_F(BindingCallbackTest, DeleteBindingThenDeleteCallback) {
212 // Create the ServerImpl.
213 InterfaceImpl server_impl;
214 {
215 // Create the binding in an inner scope so it can be deleted first.
216 Binding<sample::Provider> binding(&server_impl, GetProxy(&interface_ptr_));
217
218 // Initialize the test values.
219 server_impl.resetLastServerValueSeen();
220 last_client_callback_value_seen_ = 0;
221
222 // Invoke the Echo method.
223 interface_ptr_->EchoInt(7, ValueSaver(&last_client_callback_value_seen_));
224 PumpMessages();
225 }
226 // The binding has now been destroyed and the pipe is closed.
227
228 // Check that server saw the correct value, but the client has not yet.
229 EXPECT_EQ(7, server_impl.last_server_value_seen());
230 EXPECT_EQ(0, last_client_callback_value_seen_);
231
232 // Delete the callback without running it. This should not
233 // cause a problem because the insfrastructure can detect that the
234 // binding has already been destroyed and the pipe is closed.
235 server_impl.DeleteCallback();
236 }
237
238 // Tests that closing a Binding allows us to delete a callback
239 // without running it without encountering a crash.
240 TEST_F(BindingCallbackTest, CloseBindingBeforeDeletingCallback) {
241 // Create the ServerImpl and the Binding.
242 InterfaceImpl server_impl;
243 Binding<sample::Provider> binding(&server_impl, GetProxy(&interface_ptr_));
244
245 // Initialize the test values.
246 server_impl.resetLastServerValueSeen();
247 last_client_callback_value_seen_ = 0;
248
249 // Invoke the Echo method.
250 interface_ptr_->EchoInt(7, ValueSaver(&last_client_callback_value_seen_));
251 PumpMessages();
252
253 // Check that server saw the correct value, but the client has not yet.
254 EXPECT_EQ(7, server_impl.last_server_value_seen());
255 EXPECT_EQ(0, last_client_callback_value_seen_);
256
257 // Now close the Binding.
258 binding.Close();
259
260 // Delete the callback without running it. This should not
261 // cause a crash because the insfrastructure can detect that the
262 // binding has already been closed.
263 server_impl.DeleteCallback();
264
265 // Check that the client has still not seen the correct value.
266 EXPECT_EQ(0, last_client_callback_value_seen_);
267 }
268
269 // Tests that deleting a Callback without using it before the
270 // Binding has been destroyed or closed results in a DCHECK.
271 TEST_F(BindingCallbackTest, DeleteCallbackBeforeBindingDeathTest) {
272 // Create the ServerImpl and the Binding.
273 InterfaceImpl server_impl;
274 Binding<sample::Provider> binding(&server_impl, GetProxy(&interface_ptr_));
275
276 // Initialize the test values.
277 server_impl.resetLastServerValueSeen();
278 last_client_callback_value_seen_ = 0;
279
280 // Invoke the Echo method.
281 interface_ptr_->EchoInt(7, ValueSaver(&last_client_callback_value_seen_));
282 PumpMessages();
283
284 // Check that server saw the correct value, but the client has not yet.
285 EXPECT_EQ(7, server_impl.last_server_value_seen());
286 EXPECT_EQ(0, last_client_callback_value_seen_);
287
288 #if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
289 // Delete the callback without running it. This should cause a crash in debug
290 // builds due to a DCHECK.
291 EXPECT_DEATH_IF_SUPPORTED(server_impl.DeleteCallback(),
292 "Check failed: !callback_was_dropped.");
293 #endif
294 }
295
296 } // namespace
297 } // namespace test
298 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/public/cpp/bindings/tests/array_unittest.cc ('k') | mojo/public/cpp/bindings/tests/binding_set_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698