OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 #include <stdint.h> | 5 #include <stdint.h> |
6 #include <utility> | 6 #include <utility> |
7 | 7 |
8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
9 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
10 #include "mojo/public/cpp/bindings/binding.h" | 10 #include "mojo/public/cpp/bindings/binding.h" |
11 #include "mojo/public/cpp/bindings/strong_binding.h" | 11 #include "mojo/public/cpp/bindings/strong_binding.h" |
12 #include "mojo/public/cpp/test_support/test_utils.h" | 12 #include "mojo/public/cpp/test_support/test_utils.h" |
13 #include "mojo/public/interfaces/bindings/tests/sample_factory.mojom.h" | 13 #include "mojo/public/interfaces/bindings/tests/sample_factory.mojom.h" |
14 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
15 | 15 |
16 namespace mojo { | 16 namespace mojo { |
17 namespace test { | 17 namespace test { |
18 namespace { | 18 namespace { |
19 | 19 |
20 const char kText1[] = "hello"; | 20 const char kText1[] = "hello"; |
21 const char kText2[] = "world"; | 21 const char kText2[] = "world"; |
22 | 22 |
23 class StringRecorder { | 23 void RecordString(std::string* storage, |
24 public: | 24 const base::Closure& closure, |
25 StringRecorder(std::string* buf, const base::Closure& closure) | 25 String str) { |
26 : buf_(buf), closure_(closure) {} | 26 *storage = str.PassStorage(); |
27 void Run(const String& a) const { | 27 closure.Run(); |
28 *buf_ = a.To<std::string>(); | 28 } |
29 closure_.Run(); | |
30 } | |
31 | 29 |
32 private: | 30 base::Callback<void(mojo::String)> MakeStringRecorder( |
33 std::string* buf_; | 31 std::string* storage, |
34 base::Closure closure_; | 32 const base::Closure& closure) { |
35 }; | 33 return base::Bind(&RecordString, storage, closure); |
| 34 } |
36 | 35 |
37 class ImportedInterfaceImpl : public imported::ImportedInterface { | 36 class ImportedInterfaceImpl : public imported::ImportedInterface { |
38 public: | 37 public: |
39 ImportedInterfaceImpl( | 38 ImportedInterfaceImpl( |
40 InterfaceRequest<imported::ImportedInterface> request, | 39 InterfaceRequest<imported::ImportedInterface> request, |
41 const base::Closure& closure) | 40 const base::Closure& closure) |
42 : binding_(this, std::move(request)), closure_(closure) {} | 41 : binding_(this, std::move(request)), closure_(closure) {} |
43 | 42 |
44 void DoSomething() override { | 43 void DoSomething() override { |
45 do_something_count_++; | 44 do_something_count_++; |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 HandlePassingTest() {} | 158 HandlePassingTest() {} |
160 | 159 |
161 void TearDown() override { PumpMessages(); } | 160 void TearDown() override { PumpMessages(); } |
162 | 161 |
163 void PumpMessages() { loop_.RunUntilIdle(); } | 162 void PumpMessages() { loop_.RunUntilIdle(); } |
164 | 163 |
165 private: | 164 private: |
166 base::MessageLoop loop_; | 165 base::MessageLoop loop_; |
167 }; | 166 }; |
168 | 167 |
169 struct DoStuffCallback { | 168 void DoStuff(bool* got_response, |
170 DoStuffCallback(bool* got_response, | 169 std::string* got_text_reply, |
171 std::string* got_text_reply, | 170 const base::Closure& closure, |
172 const base::Closure& closure) | 171 sample::ResponsePtr response, |
173 : got_response(got_response), | 172 String text_reply) { |
174 got_text_reply(got_text_reply), | 173 *got_text_reply = text_reply; |
175 closure(closure) {} | |
176 | 174 |
177 void Run(sample::ResponsePtr response, const String& text_reply) const { | 175 if (response->pipe.is_valid()) { |
178 *got_text_reply = text_reply; | 176 std::string text2; |
| 177 EXPECT_TRUE(ReadTextMessage(response->pipe.get(), &text2)); |
179 | 178 |
180 if (response->pipe.is_valid()) { | 179 // Ensure that simply accessing response.pipe does not close it. |
181 std::string text2; | 180 EXPECT_TRUE(response->pipe.is_valid()); |
182 EXPECT_TRUE(ReadTextMessage(response->pipe.get(), &text2)); | |
183 | 181 |
184 // Ensure that simply accessing response.pipe does not close it. | 182 EXPECT_EQ(std::string(kText2), text2); |
185 EXPECT_TRUE(response->pipe.is_valid()); | |
186 | 183 |
187 EXPECT_EQ(std::string(kText2), text2); | 184 // Do some more tests of handle passing: |
188 | 185 ScopedMessagePipeHandle p = std::move(response->pipe); |
189 // Do some more tests of handle passing: | 186 EXPECT_TRUE(p.is_valid()); |
190 ScopedMessagePipeHandle p = std::move(response->pipe); | 187 EXPECT_FALSE(response->pipe.is_valid()); |
191 EXPECT_TRUE(p.is_valid()); | |
192 EXPECT_FALSE(response->pipe.is_valid()); | |
193 } | |
194 | |
195 *got_response = true; | |
196 closure.Run(); | |
197 } | 188 } |
198 | 189 |
199 bool* got_response; | 190 *got_response = true; |
200 std::string* got_text_reply; | 191 closure.Run(); |
201 base::Closure closure; | 192 } |
202 }; | 193 |
| 194 void DoStuff2(bool* got_response, |
| 195 std::string* got_text_reply, |
| 196 const base::Closure& closure, |
| 197 String text_reply) { |
| 198 *got_response = true; |
| 199 *got_text_reply = text_reply; |
| 200 closure.Run(); |
| 201 } |
203 | 202 |
204 TEST_F(HandlePassingTest, Basic) { | 203 TEST_F(HandlePassingTest, Basic) { |
205 sample::FactoryPtr factory; | 204 sample::FactoryPtr factory; |
206 SampleFactoryImpl factory_impl(GetProxy(&factory)); | 205 SampleFactoryImpl factory_impl(GetProxy(&factory)); |
207 | 206 |
208 MessagePipe pipe0; | 207 MessagePipe pipe0; |
209 EXPECT_TRUE(WriteTextMessage(pipe0.handle1.get(), kText1)); | 208 EXPECT_TRUE(WriteTextMessage(pipe0.handle1.get(), kText1)); |
210 | 209 |
211 MessagePipe pipe1; | 210 MessagePipe pipe1; |
212 EXPECT_TRUE(WriteTextMessage(pipe1.handle1.get(), kText2)); | 211 EXPECT_TRUE(WriteTextMessage(pipe1.handle1.get(), kText2)); |
213 | 212 |
214 imported::ImportedInterfacePtr imported; | 213 imported::ImportedInterfacePtr imported; |
215 base::RunLoop run_loop; | 214 base::RunLoop run_loop; |
216 ImportedInterfaceImpl imported_impl(GetProxy(&imported), | 215 ImportedInterfaceImpl imported_impl(GetProxy(&imported), |
217 run_loop.QuitClosure()); | 216 run_loop.QuitClosure()); |
218 | 217 |
219 sample::RequestPtr request(sample::Request::New()); | 218 sample::RequestPtr request(sample::Request::New()); |
220 request->x = 1; | 219 request->x = 1; |
221 request->pipe = std::move(pipe1.handle0); | 220 request->pipe = std::move(pipe1.handle0); |
222 request->obj = std::move(imported); | 221 request->obj = std::move(imported); |
223 bool got_response = false; | 222 bool got_response = false; |
224 std::string got_text_reply; | 223 std::string got_text_reply; |
225 base::RunLoop run_loop2; | 224 base::RunLoop run_loop2; |
226 DoStuffCallback cb(&got_response, &got_text_reply, run_loop2.QuitClosure()); | 225 factory->DoStuff(std::move(request), std::move(pipe0.handle0), |
227 factory->DoStuff(std::move(request), std::move(pipe0.handle0), cb); | 226 base::Bind(&DoStuff, &got_response, &got_text_reply, |
| 227 run_loop2.QuitClosure())); |
228 | 228 |
229 EXPECT_FALSE(*cb.got_response); | 229 EXPECT_FALSE(got_response); |
230 int count_before = ImportedInterfaceImpl::do_something_count(); | 230 int count_before = ImportedInterfaceImpl::do_something_count(); |
231 | 231 |
232 run_loop.Run(); | 232 run_loop.Run(); |
233 run_loop2.Run(); | 233 run_loop2.Run(); |
234 | 234 |
235 EXPECT_TRUE(*cb.got_response); | 235 EXPECT_TRUE(got_response); |
236 EXPECT_EQ(kText1, *cb.got_text_reply); | 236 EXPECT_EQ(kText1, got_text_reply); |
237 EXPECT_EQ(1, ImportedInterfaceImpl::do_something_count() - count_before); | 237 EXPECT_EQ(1, ImportedInterfaceImpl::do_something_count() - count_before); |
238 } | 238 } |
239 | 239 |
240 TEST_F(HandlePassingTest, PassInvalid) { | 240 TEST_F(HandlePassingTest, PassInvalid) { |
241 sample::FactoryPtr factory; | 241 sample::FactoryPtr factory; |
242 SampleFactoryImpl factory_impl(GetProxy(&factory)); | 242 SampleFactoryImpl factory_impl(GetProxy(&factory)); |
243 | 243 |
244 sample::RequestPtr request(sample::Request::New()); | 244 sample::RequestPtr request(sample::Request::New()); |
245 request->x = 1; | 245 request->x = 1; |
246 bool got_response = false; | 246 bool got_response = false; |
247 std::string got_text_reply; | 247 std::string got_text_reply; |
248 base::RunLoop run_loop; | 248 base::RunLoop run_loop; |
249 DoStuffCallback cb(&got_response, &got_text_reply, run_loop.QuitClosure()); | 249 factory->DoStuff(std::move(request), ScopedMessagePipeHandle(), |
250 factory->DoStuff(std::move(request), ScopedMessagePipeHandle(), cb); | 250 base::Bind(&DoStuff, &got_response, &got_text_reply, |
| 251 run_loop.QuitClosure())); |
251 | 252 |
252 EXPECT_FALSE(*cb.got_response); | 253 EXPECT_FALSE(got_response); |
253 | 254 |
254 run_loop.Run(); | 255 run_loop.Run(); |
255 | 256 |
256 EXPECT_TRUE(*cb.got_response); | 257 EXPECT_TRUE(got_response); |
257 } | 258 } |
258 | 259 |
259 struct DoStuff2Callback { | |
260 DoStuff2Callback(bool* got_response, | |
261 std::string* got_text_reply, | |
262 const base::Closure& closure) | |
263 : got_response(got_response), | |
264 got_text_reply(got_text_reply), | |
265 closure(closure) {} | |
266 | |
267 void Run(const String& text_reply) const { | |
268 *got_response = true; | |
269 *got_text_reply = text_reply; | |
270 closure.Run(); | |
271 } | |
272 | |
273 bool* got_response; | |
274 std::string* got_text_reply; | |
275 base::Closure closure; | |
276 }; | |
277 | |
278 // Verifies DataPipeConsumer can be passed and read from. | 260 // Verifies DataPipeConsumer can be passed and read from. |
279 TEST_F(HandlePassingTest, DataPipe) { | 261 TEST_F(HandlePassingTest, DataPipe) { |
280 sample::FactoryPtr factory; | 262 sample::FactoryPtr factory; |
281 SampleFactoryImpl factory_impl(GetProxy(&factory)); | 263 SampleFactoryImpl factory_impl(GetProxy(&factory)); |
282 | 264 |
283 // Writes a string to a data pipe and passes the data pipe (consumer) to the | 265 // Writes a string to a data pipe and passes the data pipe (consumer) to the |
284 // factory. | 266 // factory. |
285 ScopedDataPipeProducerHandle producer_handle; | 267 ScopedDataPipeProducerHandle producer_handle; |
286 ScopedDataPipeConsumerHandle consumer_handle; | 268 ScopedDataPipeConsumerHandle consumer_handle; |
287 MojoCreateDataPipeOptions options = {sizeof(MojoCreateDataPipeOptions), | 269 MojoCreateDataPipeOptions options = {sizeof(MojoCreateDataPipeOptions), |
288 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, | 270 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, |
289 1, | 271 1, |
290 1024}; | 272 1024}; |
291 ASSERT_EQ(MOJO_RESULT_OK, | 273 ASSERT_EQ(MOJO_RESULT_OK, |
292 CreateDataPipe(&options, &producer_handle, &consumer_handle)); | 274 CreateDataPipe(&options, &producer_handle, &consumer_handle)); |
293 std::string expected_text_reply = "got it"; | 275 std::string expected_text_reply = "got it"; |
294 // +1 for \0. | 276 // +1 for \0. |
295 uint32_t data_size = static_cast<uint32_t>(expected_text_reply.size() + 1); | 277 uint32_t data_size = static_cast<uint32_t>(expected_text_reply.size() + 1); |
296 ASSERT_EQ(MOJO_RESULT_OK, | 278 ASSERT_EQ(MOJO_RESULT_OK, |
297 WriteDataRaw(producer_handle.get(), | 279 WriteDataRaw(producer_handle.get(), |
298 expected_text_reply.c_str(), | 280 expected_text_reply.c_str(), |
299 &data_size, | 281 &data_size, |
300 MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)); | 282 MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)); |
301 | 283 |
302 bool got_response = false; | 284 bool got_response = false; |
303 std::string got_text_reply; | 285 std::string got_text_reply; |
304 base::RunLoop run_loop; | 286 base::RunLoop run_loop; |
305 DoStuff2Callback cb(&got_response, &got_text_reply, run_loop.QuitClosure()); | 287 factory->DoStuff2(std::move(consumer_handle), |
306 factory->DoStuff2(std::move(consumer_handle), cb); | 288 base::Bind(&DoStuff2, &got_response, &got_text_reply, |
| 289 run_loop.QuitClosure())); |
307 | 290 |
308 EXPECT_FALSE(*cb.got_response); | 291 EXPECT_FALSE(got_response); |
309 | 292 |
310 run_loop.Run(); | 293 run_loop.Run(); |
311 | 294 |
312 EXPECT_TRUE(*cb.got_response); | 295 EXPECT_TRUE(got_response); |
313 EXPECT_EQ(expected_text_reply, *cb.got_text_reply); | 296 EXPECT_EQ(expected_text_reply, got_text_reply); |
314 } | 297 } |
315 | 298 |
316 TEST_F(HandlePassingTest, PipesAreClosed) { | 299 TEST_F(HandlePassingTest, PipesAreClosed) { |
317 sample::FactoryPtr factory; | 300 sample::FactoryPtr factory; |
318 SampleFactoryImpl factory_impl(GetProxy(&factory)); | 301 SampleFactoryImpl factory_impl(GetProxy(&factory)); |
319 | 302 |
320 MessagePipe extra_pipe; | 303 MessagePipe extra_pipe; |
321 | 304 |
322 MojoHandle handle0_value = extra_pipe.handle0.get().value(); | 305 MojoHandle handle0_value = extra_pipe.handle0.get().value(); |
323 MojoHandle handle1_value = extra_pipe.handle1.get().value(); | 306 MojoHandle handle1_value = extra_pipe.handle1.get().value(); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 | 347 |
365 ASSERT_TRUE(object1); | 348 ASSERT_TRUE(object1); |
366 object1->SetName("object1"); | 349 object1->SetName("object1"); |
367 | 350 |
368 sample::NamedObjectPtr object2; | 351 sample::NamedObjectPtr object2; |
369 factory->CreateNamedObject(GetProxy(&object2)); | 352 factory->CreateNamedObject(GetProxy(&object2)); |
370 object2->SetName("object2"); | 353 object2->SetName("object2"); |
371 | 354 |
372 base::RunLoop run_loop, run_loop2; | 355 base::RunLoop run_loop, run_loop2; |
373 std::string name1; | 356 std::string name1; |
374 object1->GetName(StringRecorder(&name1, run_loop.QuitClosure())); | 357 object1->GetName(MakeStringRecorder(&name1, run_loop.QuitClosure())); |
375 | 358 |
376 std::string name2; | 359 std::string name2; |
377 object2->GetName(StringRecorder(&name2, run_loop2.QuitClosure())); | 360 object2->GetName(MakeStringRecorder(&name2, run_loop2.QuitClosure())); |
378 | 361 |
379 run_loop.Run(); | 362 run_loop.Run(); |
380 run_loop2.Run(); | 363 run_loop2.Run(); |
381 | 364 |
382 EXPECT_EQ(std::string("object1"), name1); | 365 EXPECT_EQ(std::string("object1"), name1); |
383 EXPECT_EQ(std::string("object2"), name2); | 366 EXPECT_EQ(std::string("object2"), name2); |
384 } | 367 } |
385 | 368 |
386 } // namespace | 369 } // namespace |
387 } // namespace test | 370 } // namespace test |
388 } // namespace mojo | 371 } // namespace mojo |
OLD | NEW |