OLD | NEW |
---|---|
(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 #include "mojo/public/cpp/bindings/interface_ptr.h" | |
jamesr
2015/03/16 21:05:56
nit: blank line after copyright header
rudominer
2015/03/16 22:57:19
Done.
| |
5 #include "mojo/public/cpp/environment/environment.h" | |
6 #include "mojo/public/cpp/test_support/test_support.h" | |
7 #include "mojo/public/cpp/utility/run_loop.h" | |
8 #include "mojo/public/interfaces/bindings/tests/binding_callback_test_interfaces .mojom.h" | |
9 #include "testing/gtest/include/gtest/gtest.h" | |
10 | |
11 /////////////////////////////////////////////////////////////////////////////// | |
12 // | |
13 // The tests in this file are designed to test the interaction between a | |
14 // Callback and its associated Binding. If a Callback is deleted before | |
15 // being used we DCHECK fail--unless the associated Binding has already | |
16 // been closed or deleted. This contract must be explained to the Mojo | |
17 // application developer. For example it is his responsibility to ensure that | |
jamesr
2015/03/16 21:05:57
nit: avoid gendered pronouns like "his" in documen
rudominer
2015/03/16 22:57:19
Done.
| |
18 // the Binding is destroyed before an unused Callback is destroyed. | |
19 // | |
20 /////////////////////////////////////////////////////////////////////////////// | |
21 | |
22 namespace mojo { | |
23 namespace test { | |
24 namespace { | |
25 | |
26 // A Runnable object that saves the last value it sees via the | |
27 // provided int32_t*. Used on the client side. | |
28 class ValueSaver { | |
29 public: | |
30 explicit ValueSaver(int32_t* last_value_seen) | |
31 : last_value_seen_(last_value_seen) {} | |
32 void Run(int32_t x) const { *last_value_seen_ = x; } | |
33 | |
34 private: | |
35 mutable int32_t* last_value_seen_; | |
jamesr
2015/03/16 21:05:57
this can be const as the pointer value isn't chang
rudominer
2015/03/16 22:57:19
Done.
| |
36 }; | |
37 | |
38 // An implementation of BindingCallbackTestInterface used on the server side. | |
39 // All it does is save the values and Callbacks it sees. | |
40 class BindingCallbackTestInterfaceImpl : public BindingCallbackTestInterface { | |
41 public: | |
42 BindingCallbackTestInterfaceImpl() | |
43 : last_server_value_seen(0), | |
44 callback_saved(new Callback<void(int32_t)>()) {} | |
45 | |
46 ~BindingCallbackTestInterfaceImpl() override { | |
47 if (callback_saved) { | |
48 delete callback_saved; | |
49 } | |
50 } | |
51 | |
52 // Run's the callback previously saved from the last invocation | |
53 // of |EchoInt()|. | |
54 bool RunCallback() { | |
55 if (callback_saved) { | |
56 callback_saved->Run(last_server_value_seen); | |
57 return true; | |
58 } | |
59 return false; | |
60 } | |
61 | |
62 // Delete's the previously saved callback. | |
63 void DeleteCallback() { | |
64 delete callback_saved; | |
65 callback_saved = nullptr; | |
66 } | |
67 | |
68 // Saves its two input values in member variables and does nothing else. | |
69 void EchoInt(int32_t x, const Callback<void(int32_t)>& callback) { | |
70 last_server_value_seen = x; | |
71 *callback_saved = callback; | |
72 } | |
73 | |
74 int last_server_value_seen; | |
jamesr
2015/03/16 21:05:56
s/int/int32_t/
if you want these to be private si
rudominer
2015/03/16 22:57:19
Done.
| |
75 Callback<void(int32_t)>* callback_saved; | |
76 }; | |
77 | |
78 class BindingCallbackTest : public testing::Test { | |
79 public: | |
80 ~BindingCallbackTest() override {} | |
81 | |
82 protected: | |
83 int last_client_callback_value_seen_; | |
84 ScopedMessagePipeHandle handle_client_; | |
jamesr
2015/03/16 21:05:56
can these have more specific types (i.e. are these
rudominer
2015/03/16 22:57:20
Help me out here. I'm not familiar with any more s
| |
85 ScopedMessagePipeHandle handle_server_; | |
86 BindingCallbackTestInterfacePtr interface_ptr_; | |
87 | |
88 void PumpMessages() { loop_.RunUntilIdle(); } | |
89 void SetUp() { | |
90 CreateMessagePipe(nullptr, &handle_client_, &handle_server_); | |
91 // Create the client InterfacePtr. | |
92 interface_ptr_ = | |
93 MakeProxy<BindingCallbackTestInterface>(handle_client_.Pass()); | |
94 } | |
95 | |
96 private: | |
97 Environment env_; | |
98 RunLoop loop_; | |
99 }; | |
100 | |
101 // Tests that the InterfacePtr and the Binding can communicate with each | |
102 // other normally. | |
103 TEST_F(BindingCallbackTest, Basic) { | |
104 // Create the ServerImpl and the Binding. | |
105 BindingCallbackTestInterfaceImpl server_impl; | |
106 Binding<BindingCallbackTestInterface> binding( | |
107 &server_impl, | |
108 MakeRequest<BindingCallbackTestInterface>(handle_server_.Pass())); | |
109 | |
110 // Initialize the test values. | |
111 server_impl.last_server_value_seen = 0; | |
112 last_client_callback_value_seen_ = 0; | |
113 | |
114 // Invoke the Echo method. | |
115 interface_ptr_->EchoInt(7, ValueSaver(&last_client_callback_value_seen_)); | |
116 PumpMessages(); | |
117 | |
118 // Check that server saw the correct value, but the client has not yet. | |
119 EXPECT_EQ(7, server_impl.last_server_value_seen); | |
120 EXPECT_EQ(0, last_client_callback_value_seen_); | |
121 | |
122 // Now run the Callback. | |
123 server_impl.RunCallback(); | |
124 PumpMessages(); | |
125 | |
126 // Check that the client has now seen the correct value. | |
127 EXPECT_EQ(7, last_client_callback_value_seen_); | |
128 | |
129 // Initialize the test values again. | |
130 server_impl.last_server_value_seen = 0; | |
131 last_client_callback_value_seen_ = 0; | |
132 | |
133 // Invoke the Echo method again. | |
134 interface_ptr_->EchoInt(13, ValueSaver(&last_client_callback_value_seen_)); | |
135 PumpMessages(); | |
136 | |
137 // Check that server saw the correct value, but the client has not yet. | |
138 EXPECT_EQ(13, server_impl.last_server_value_seen); | |
139 EXPECT_EQ(0, last_client_callback_value_seen_); | |
140 | |
141 // Now run the Callback again. | |
142 server_impl.RunCallback(); | |
143 PumpMessages(); | |
144 | |
145 // Check that the client has now seen the correct value again. | |
146 EXPECT_EQ(13, last_client_callback_value_seen_); | |
147 } | |
148 | |
149 // Tests that running the Callback after the Binding has been deleted | |
150 // results in a clean failure. | |
151 TEST_F(BindingCallbackTest, DeleteBindingThenRunCallback) { | |
152 // Create the ServerImpl. | |
153 BindingCallbackTestInterfaceImpl server_impl; | |
154 { | |
155 // Create the binding in an inner scope so it can be deleted first. | |
156 Binding<BindingCallbackTestInterface> binding( | |
157 &server_impl, | |
158 MakeRequest<BindingCallbackTestInterface>(handle_server_.Pass())); | |
159 | |
160 // Initialize the test values. | |
161 server_impl.last_server_value_seen = 0; | |
162 last_client_callback_value_seen_ = 0; | |
163 | |
164 // Invoke the Echo method. | |
165 interface_ptr_->EchoInt(7, ValueSaver(&last_client_callback_value_seen_)); | |
166 PumpMessages(); | |
167 } | |
168 // The binding has now been destroyed and the pipe is closed. | |
169 | |
170 // Check that server saw the correct value, but the client has not yet. | |
171 EXPECT_EQ(7, server_impl.last_server_value_seen); | |
172 EXPECT_EQ(0, last_client_callback_value_seen_); | |
173 | |
174 // Now try to run the Callback. This should do nothing since the pipe | |
175 // is closed. | |
176 EXPECT_TRUE(server_impl.RunCallback()); | |
177 PumpMessages(); | |
178 | |
179 // Check that the client has still not seen the correct value. | |
180 EXPECT_EQ(0, last_client_callback_value_seen_); | |
181 | |
182 // Attempt to invoke the method again and confirm that an error was | |
183 // encountered. | |
184 interface_ptr_->EchoInt(13, ValueSaver(&last_client_callback_value_seen_)); | |
185 PumpMessages(); | |
186 EXPECT_TRUE(interface_ptr_.encountered_error()); | |
187 } | |
188 | |
189 // Tests that deleting a Callback without running it after the corresponding | |
190 // binding has already been deleted does not result in a crash. | |
191 TEST_F(BindingCallbackTest, DeleteBindingThenDeleteCallback) { | |
192 // Create the ServerImpl. | |
193 BindingCallbackTestInterfaceImpl server_impl; | |
194 { | |
195 // Create the binding in an inner scope so it can be deleted first. | |
196 Binding<BindingCallbackTestInterface> binding( | |
197 &server_impl, | |
198 MakeRequest<BindingCallbackTestInterface>(handle_server_.Pass())); | |
199 | |
200 // Initialize the test values. | |
201 server_impl.last_server_value_seen = 0; | |
202 last_client_callback_value_seen_ = 0; | |
203 | |
204 // Invoke the Echo method. | |
205 interface_ptr_->EchoInt(7, ValueSaver(&last_client_callback_value_seen_)); | |
206 PumpMessages(); | |
207 } | |
208 // The binding has now been destroyed and the pipe is closed. | |
209 | |
210 // Check that server saw the correct value, but the client has not yet. | |
211 EXPECT_EQ(7, server_impl.last_server_value_seen); | |
212 EXPECT_EQ(0, last_client_callback_value_seen_); | |
213 | |
214 // Delete the callback without running it. This should not | |
215 // cause a problem because the insfrastructure can detect that the | |
216 // binding has already been destroyed and the pipe is closed. | |
217 server_impl.DeleteCallback(); | |
218 } | |
219 | |
220 // Tests that closing a Binding allows us to delete a callback | |
221 // without running it without encountering a crash. | |
222 TEST_F(BindingCallbackTest, CloseBindingBeforeDeletingCallback) { | |
223 // Create the ServerImpl and the Binding. | |
224 BindingCallbackTestInterfaceImpl server_impl; | |
225 Binding<BindingCallbackTestInterface> binding( | |
226 &server_impl, | |
227 MakeRequest<BindingCallbackTestInterface>(handle_server_.Pass())); | |
228 | |
229 // Initialize the test values. | |
230 server_impl.last_server_value_seen = 0; | |
231 last_client_callback_value_seen_ = 0; | |
232 | |
233 // Invoke the Echo method. | |
234 interface_ptr_->EchoInt(7, ValueSaver(&last_client_callback_value_seen_)); | |
235 PumpMessages(); | |
236 | |
237 // Check that server saw the correct value, but the client has not yet. | |
238 EXPECT_EQ(7, server_impl.last_server_value_seen); | |
239 EXPECT_EQ(0, last_client_callback_value_seen_); | |
240 | |
241 // Now close the Binding. | |
242 binding.Close(); | |
243 | |
244 // Delete the callback without running it. This should not | |
245 // cause a crash because the insfrastructure can detect that the | |
246 // binding has already been closed. | |
247 server_impl.DeleteCallback(); | |
248 | |
249 // Check that the client has still not seen the correct value. | |
250 EXPECT_EQ(0, last_client_callback_value_seen_); | |
251 } | |
252 | |
253 // Tests that deleting a Callback without using it before the | |
254 // Binding has been destroyed or closed results in a DCHECK. | |
255 TEST_F(BindingCallbackTest, DeleteCallbackBeforeBindingDeathTest) { | |
256 // Create the ServerImpl and the Binding. | |
257 BindingCallbackTestInterfaceImpl server_impl; | |
258 Binding<BindingCallbackTestInterface> binding( | |
259 &server_impl, | |
260 MakeRequest<BindingCallbackTestInterface>(handle_server_.Pass())); | |
261 | |
262 // Initialize the test values. | |
263 server_impl.last_server_value_seen = 0; | |
264 last_client_callback_value_seen_ = 0; | |
265 | |
266 // Invoke the Echo method. | |
267 interface_ptr_->EchoInt(7, ValueSaver(&last_client_callback_value_seen_)); | |
268 PumpMessages(); | |
269 | |
270 // Check that server saw the correct value, but the client has not yet. | |
271 EXPECT_EQ(7, server_impl.last_server_value_seen); | |
272 EXPECT_EQ(0, last_client_callback_value_seen_); | |
273 | |
274 // Delete the callback without running it. This should cause a crash | |
275 // due to a DCHECK. | |
276 EXPECT_DEATH(server_impl.DeleteCallback(), "Check failed: was_run_"); | |
277 } | |
278 | |
279 } // namespace | |
280 } // namespace test | |
281 } // namespace mojo | |
OLD | NEW |