Chromium Code Reviews| 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.To<std::string>(); |
|
yzshen1
2016/06/18 00:01:18
nit: str.PassStorage()
Ken Rockot(use gerrit already)
2016/06/18 03:24:26
Done
| |
| 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 |