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 <stdio.h> |
6 | 7 |
7 #include <string> | 8 #include <string> |
| 9 #include <vector> |
8 | 10 |
9 #include "base/basictypes.h" | |
10 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/file_util.h" |
| 13 #include "base/files/file_path.h" |
| 14 #include "base/files/scoped_file.h" |
11 #include "base/location.h" | 15 #include "base/location.h" |
12 #include "base/logging.h" | 16 #include "base/logging.h" |
| 17 #include "base/macros.h" |
13 #include "base/threading/platform_thread.h" // For |Sleep()|. | 18 #include "base/threading/platform_thread.h" // For |Sleep()|. |
| 19 #include "build/build_config.h" // TODO(vtl): Remove this. |
14 #include "mojo/common/test/multiprocess_test_helper.h" | 20 #include "mojo/common/test/multiprocess_test_helper.h" |
| 21 #include "mojo/common/test/test_utils.h" |
15 #include "mojo/embedder/scoped_platform_handle.h" | 22 #include "mojo/embedder/scoped_platform_handle.h" |
16 #include "mojo/system/channel.h" | 23 #include "mojo/system/channel.h" |
| 24 #include "mojo/system/dispatcher.h" |
17 #include "mojo/system/local_message_pipe_endpoint.h" | 25 #include "mojo/system/local_message_pipe_endpoint.h" |
18 #include "mojo/system/message_pipe.h" | 26 #include "mojo/system/message_pipe.h" |
| 27 #include "mojo/system/platform_handle_dispatcher.h" |
19 #include "mojo/system/proxy_message_pipe_endpoint.h" | 28 #include "mojo/system/proxy_message_pipe_endpoint.h" |
20 #include "mojo/system/raw_channel.h" | 29 #include "mojo/system/raw_channel.h" |
21 #include "mojo/system/test_utils.h" | 30 #include "mojo/system/test_utils.h" |
22 #include "mojo/system/waiter.h" | 31 #include "mojo/system/waiter.h" |
23 #include "testing/gtest/include/gtest/gtest.h" | 32 #include "testing/gtest/include/gtest/gtest.h" |
24 | 33 |
25 namespace mojo { | 34 namespace mojo { |
26 namespace system { | 35 namespace system { |
27 namespace { | 36 namespace { |
28 | 37 |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 | 179 |
171 std::string write_buffer = read_buffer + read_buffer; | 180 std::string write_buffer = read_buffer + read_buffer; |
172 CHECK_EQ(mp->WriteMessage(0, | 181 CHECK_EQ(mp->WriteMessage(0, |
173 write_buffer.data(), | 182 write_buffer.data(), |
174 static_cast<uint32_t>(write_buffer.size()), | 183 static_cast<uint32_t>(write_buffer.size()), |
175 NULL, | 184 NULL, |
176 MOJO_WRITE_MESSAGE_FLAG_NONE), | 185 MOJO_WRITE_MESSAGE_FLAG_NONE), |
177 MOJO_RESULT_OK); | 186 MOJO_RESULT_OK); |
178 } | 187 } |
179 | 188 |
180 | |
181 mp->Close(0); | 189 mp->Close(0); |
182 return rv; | 190 return rv; |
183 } | 191 } |
184 | 192 |
185 // Sends "hello" to child, and expects "hellohello" back. | 193 // Sends "hello" to child, and expects "hellohello" back. |
186 TEST_F(MultiprocessMessagePipeTest, Basic) { | 194 TEST_F(MultiprocessMessagePipeTest, Basic) { |
187 helper()->StartChild("EchoEcho"); | 195 helper()->StartChild("EchoEcho"); |
188 | 196 |
189 scoped_refptr<MessagePipe> mp(new MessagePipe( | 197 scoped_refptr<MessagePipe> mp(new MessagePipe( |
190 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()), | 198 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()), |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 // "quitquitquit"). | 273 // "quitquitquit"). |
266 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | 274 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, |
267 WaitIfNecessary(mp, MOJO_WAIT_FLAG_READABLE)); | 275 WaitIfNecessary(mp, MOJO_WAIT_FLAG_READABLE)); |
268 | 276 |
269 mp->Close(0); | 277 mp->Close(0); |
270 | 278 |
271 EXPECT_EQ(static_cast<int>(kNumMessages % 100), | 279 EXPECT_EQ(static_cast<int>(kNumMessages % 100), |
272 helper()->WaitForChildShutdown()); | 280 helper()->WaitForChildShutdown()); |
273 } | 281 } |
274 | 282 |
| 283 MOJO_MULTIPROCESS_TEST_CHILD_MAIN(CheckPlatformHandleFile) { |
| 284 ChannelThread channel_thread; |
| 285 embedder::ScopedPlatformHandle client_platform_handle = |
| 286 mojo::test::MultiprocessTestHelper::client_platform_handle.Pass(); |
| 287 CHECK(client_platform_handle.is_valid()); |
| 288 scoped_refptr<MessagePipe> mp(new MessagePipe( |
| 289 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()), |
| 290 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()))); |
| 291 channel_thread.Start(client_platform_handle.Pass(), mp); |
| 292 |
| 293 CHECK_EQ(WaitIfNecessary(mp, MOJO_WAIT_FLAG_READABLE), MOJO_RESULT_OK); |
| 294 |
| 295 std::string read_buffer(100, '\0'); |
| 296 uint32_t num_bytes = static_cast<uint32_t>(read_buffer.size()); |
| 297 DispatcherVector dispatchers; |
| 298 uint32_t num_dispatchers = 10; // Maximum number to receive. |
| 299 CHECK_EQ(mp->ReadMessage(0, |
| 300 &read_buffer[0], &num_bytes, |
| 301 &dispatchers, &num_dispatchers, |
| 302 MOJO_READ_MESSAGE_FLAG_NONE), |
| 303 MOJO_RESULT_OK); |
| 304 mp->Close(0); |
| 305 |
| 306 read_buffer.resize(num_bytes); |
| 307 CHECK_EQ(read_buffer, std::string("hello")); |
| 308 CHECK_EQ(num_dispatchers, 1u); |
| 309 |
| 310 CHECK_EQ(dispatchers[0]->GetType(), Dispatcher::kTypePlatformHandle); |
| 311 |
| 312 scoped_refptr<PlatformHandleDispatcher> dispatcher( |
| 313 static_cast<PlatformHandleDispatcher*>(dispatchers[0].get())); |
| 314 embedder::ScopedPlatformHandle h = dispatcher->PassPlatformHandle().Pass(); |
| 315 CHECK(h.is_valid()); |
| 316 dispatcher->Close(); |
| 317 |
| 318 base::ScopedFILE fp(mojo::test::FILEFromPlatformHandle(h.Pass(), "r")); |
| 319 CHECK(fp); |
| 320 std::string fread_buffer(100, '\0'); |
| 321 size_t bytes_read = fread(&fread_buffer[0], 1, fread_buffer.size(), fp.get()); |
| 322 fread_buffer.resize(bytes_read); |
| 323 CHECK_EQ(fread_buffer, "world"); |
| 324 |
| 325 return 0; |
| 326 } |
| 327 |
| 328 #if defined(OS_POSIX) |
| 329 #if defined(OS_MACOSX) |
| 330 // TODO(vtl): Apparently, cmsgs on SOCK_STREAM AF_UNIX sockets don't work the |
| 331 // way I thought they work, at least on Mac. (The non-control data gets merged |
| 332 // with subsequent data.) |
| 333 #define MAYBE_PlatformHandlePassing DISABLED_PlatformHandlePassing |
| 334 #else |
| 335 #define MAYBE_PlatformHandlePassing PlatformHandlePassing |
| 336 #endif |
| 337 #else |
| 338 // Not yet implemented (on Windows). |
| 339 #define MAYBE_PlatformHandlePassing DISABLED_PlatformHandlePassing |
| 340 #endif |
| 341 TEST_F(MultiprocessMessagePipeTest, MAYBE_PlatformHandlePassing) { |
| 342 helper()->StartChild("CheckPlatformHandleFile"); |
| 343 |
| 344 scoped_refptr<MessagePipe> mp(new MessagePipe( |
| 345 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()), |
| 346 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()))); |
| 347 Init(mp); |
| 348 |
| 349 base::FilePath unused; |
| 350 base::ScopedFILE fp(CreateAndOpenTemporaryFile(&unused)); |
| 351 const std::string world("world"); |
| 352 ASSERT_EQ(fwrite(&world[0], 1, world.size(), fp.get()), world.size()); |
| 353 fflush(fp.get()); |
| 354 rewind(fp.get()); |
| 355 |
| 356 embedder::ScopedPlatformHandle h( |
| 357 mojo::test::PlatformHandleFromFILE(fp.Pass())); |
| 358 scoped_refptr<PlatformHandleDispatcher> dispatcher( |
| 359 new PlatformHandleDispatcher(h.Pass())); |
| 360 |
| 361 const std::string hello("hello"); |
| 362 DispatcherTransport transport( |
| 363 test::DispatcherTryStartTransport(dispatcher.get())); |
| 364 ASSERT_TRUE(transport.is_valid()); |
| 365 |
| 366 std::vector<DispatcherTransport> transports; |
| 367 transports.push_back(transport); |
| 368 EXPECT_EQ(MOJO_RESULT_OK, |
| 369 mp->WriteMessage(0, |
| 370 &hello[0], |
| 371 static_cast<uint32_t>(hello.size()), |
| 372 &transports, |
| 373 MOJO_WRITE_MESSAGE_FLAG_NONE)); |
| 374 transport.End(); |
| 375 |
| 376 EXPECT_TRUE(dispatcher->HasOneRef()); |
| 377 dispatcher = NULL; |
| 378 |
| 379 // Wait for it to become readable, which should fail. |
| 380 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, |
| 381 WaitIfNecessary(mp, MOJO_WAIT_FLAG_READABLE)); |
| 382 |
| 383 mp->Close(0); |
| 384 |
| 385 EXPECT_EQ(0, helper()->WaitForChildShutdown()); |
| 386 } |
| 387 |
275 } // namespace | 388 } // namespace |
276 } // namespace system | 389 } // namespace system |
277 } // namespace mojo | 390 } // namespace mojo |
OLD | NEW |