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

Side by Side Diff: mojo/system/multiprocess_message_pipe_unittest.cc

Issue 304233011: Mojo: Add multiprocess shared memory passing test. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased tot Created 6 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include <stdio.h>
7 #include <string.h>
7 8
8 #include <string> 9 #include <string>
9 #include <vector> 10 #include <vector>
10 11
11 #include "base/bind.h" 12 #include "base/bind.h"
12 #include "base/file_util.h" 13 #include "base/file_util.h"
13 #include "base/files/file_path.h" 14 #include "base/files/file_path.h"
14 #include "base/files/scoped_file.h" 15 #include "base/files/scoped_file.h"
15 #include "base/location.h" 16 #include "base/location.h"
16 #include "base/logging.h" 17 #include "base/logging.h"
17 #include "base/macros.h" 18 #include "base/macros.h"
18 #include "base/threading/platform_thread.h" // For |Sleep()|. 19 #include "base/threading/platform_thread.h" // For |Sleep()|.
19 #include "build/build_config.h" // TODO(vtl): Remove this. 20 #include "build/build_config.h" // TODO(vtl): Remove this.
20 #include "mojo/common/test/multiprocess_test_helper.h" 21 #include "mojo/common/test/multiprocess_test_helper.h"
21 #include "mojo/common/test/test_utils.h" 22 #include "mojo/common/test/test_utils.h"
22 #include "mojo/embedder/scoped_platform_handle.h" 23 #include "mojo/embedder/scoped_platform_handle.h"
23 #include "mojo/system/channel.h" 24 #include "mojo/system/channel.h"
24 #include "mojo/system/dispatcher.h" 25 #include "mojo/system/dispatcher.h"
25 #include "mojo/system/local_message_pipe_endpoint.h" 26 #include "mojo/system/local_message_pipe_endpoint.h"
26 #include "mojo/system/message_pipe.h" 27 #include "mojo/system/message_pipe.h"
27 #include "mojo/system/platform_handle_dispatcher.h" 28 #include "mojo/system/platform_handle_dispatcher.h"
28 #include "mojo/system/proxy_message_pipe_endpoint.h" 29 #include "mojo/system/proxy_message_pipe_endpoint.h"
29 #include "mojo/system/raw_channel.h" 30 #include "mojo/system/raw_channel.h"
31 #include "mojo/system/raw_shared_buffer.h"
32 #include "mojo/system/shared_buffer_dispatcher.h"
30 #include "mojo/system/test_utils.h" 33 #include "mojo/system/test_utils.h"
31 #include "mojo/system/waiter.h" 34 #include "mojo/system/waiter.h"
32 #include "testing/gtest/include/gtest/gtest.h" 35 #include "testing/gtest/include/gtest/gtest.h"
33 36
34 namespace mojo { 37 namespace mojo {
35 namespace system { 38 namespace system {
36 namespace { 39 namespace {
37 40
38 class ChannelThread { 41 class ChannelThread {
39 public: 42 public:
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 // "quitquitquit"). 276 // "quitquitquit").
274 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, 277 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
275 WaitIfNecessary(mp, MOJO_WAIT_FLAG_READABLE)); 278 WaitIfNecessary(mp, MOJO_WAIT_FLAG_READABLE));
276 279
277 mp->Close(0); 280 mp->Close(0);
278 281
279 EXPECT_EQ(static_cast<int>(kNumMessages % 100), 282 EXPECT_EQ(static_cast<int>(kNumMessages % 100),
280 helper()->WaitForChildShutdown()); 283 helper()->WaitForChildShutdown());
281 } 284 }
282 285
286 MOJO_MULTIPROCESS_TEST_CHILD_MAIN(CheckSharedBuffer) {
287 ChannelThread channel_thread;
288 embedder::ScopedPlatformHandle client_platform_handle =
289 mojo::test::MultiprocessTestHelper::client_platform_handle.Pass();
290 CHECK(client_platform_handle.is_valid());
291 scoped_refptr<MessagePipe> mp(new MessagePipe(
292 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()),
293 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint())));
294 channel_thread.Start(client_platform_handle.Pass(), mp);
295
296 // Wait for the first message from our parent.
297 CHECK_EQ(WaitIfNecessary(mp, MOJO_WAIT_FLAG_READABLE), MOJO_RESULT_OK);
298
299 // It should have a shared buffer.
300 std::string read_buffer(100, '\0');
301 uint32_t num_bytes = static_cast<uint32_t>(read_buffer.size());
302 DispatcherVector dispatchers;
303 uint32_t num_dispatchers = 10; // Maximum number to receive.
304 CHECK_EQ(mp->ReadMessage(0,
305 &read_buffer[0], &num_bytes,
306 &dispatchers, &num_dispatchers,
307 MOJO_READ_MESSAGE_FLAG_NONE),
308 MOJO_RESULT_OK);
309 read_buffer.resize(num_bytes);
310 CHECK_EQ(read_buffer, std::string("go 1"));
311 CHECK_EQ(num_dispatchers, 1u);
312
313 CHECK_EQ(dispatchers[0]->GetType(), Dispatcher::kTypeSharedBuffer);
314
315 scoped_refptr<SharedBufferDispatcher> dispatcher(
316 static_cast<SharedBufferDispatcher*>(dispatchers[0].get()));
317
318 // Make a mapping.
319 scoped_ptr<RawSharedBufferMapping> mapping;
320 CHECK_EQ(dispatcher->MapBuffer(0, 100, MOJO_MAP_BUFFER_FLAG_NONE, &mapping),
321 MOJO_RESULT_OK);
322 CHECK(mapping);
323 CHECK(mapping->base());
324 CHECK_EQ(mapping->length(), 100u);
325
326 // Write some stuff to the shared buffer.
327 static const char kHello[] = "hello";
328 memcpy(mapping->base(), kHello, sizeof(kHello));
329
330 // We should be able to close the dispatcher now.
331 dispatcher->Close();
332
333 // And send a message to signal that we've written stuff.
334 const std::string go2("go 2");
335 CHECK_EQ(mp->WriteMessage(0,
336 &go2[0],
337 static_cast<uint32_t>(go2.size()),
338 NULL,
339 MOJO_WRITE_MESSAGE_FLAG_NONE),
340 MOJO_RESULT_OK);
341
342 // Now wait for our parent to send us a message.
343 CHECK_EQ(WaitIfNecessary(mp, MOJO_WAIT_FLAG_READABLE), MOJO_RESULT_OK);
344
345 read_buffer = std::string(100, '\0');
346 num_bytes = static_cast<uint32_t>(read_buffer.size());
347 CHECK_EQ(mp->ReadMessage(0,
348 &read_buffer[0], &num_bytes,
349 NULL, NULL,
350 MOJO_READ_MESSAGE_FLAG_NONE),
351 MOJO_RESULT_OK);
352 read_buffer.resize(num_bytes);
353 CHECK_EQ(read_buffer, std::string("go 3"));
354
355 // It should have written something to the shared buffer.
356 static const char kWorld[] = "world!!!";
357 CHECK_EQ(memcmp(mapping->base(), kWorld, sizeof(kWorld)), 0);
358
359 // And we're done.
360 mp->Close(0);
361
362 return 0;
363 }
364
365 #if defined(OS_POSIX)
366 #define MAYBE_SharedBufferPassing SharedBufferPassing
367 #else
368 // Not yet implemented (on Windows).
369 #define MAYBE_SharedBufferPassing DISABLED_SharedBufferPassing
370 #endif
371 TEST_F(MultiprocessMessagePipeTest, MAYBE_SharedBufferPassing) {
372 helper()->StartChild("CheckSharedBuffer");
373
374 scoped_refptr<MessagePipe> mp(new MessagePipe(
375 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()),
376 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint())));
377 Init(mp);
378
379 // Make a shared buffer.
380 scoped_refptr<SharedBufferDispatcher> dispatcher;
381 MojoCreateSharedBufferOptions validated_options = {};
382 EXPECT_EQ(MOJO_RESULT_OK,
383 SharedBufferDispatcher::ValidateOptions(NULL, &validated_options));
384 EXPECT_EQ(MOJO_RESULT_OK,
385 SharedBufferDispatcher::Create(validated_options, 100,
386 &dispatcher));
387 ASSERT_TRUE(dispatcher);
388
389 // Make a mapping.
390 scoped_ptr<RawSharedBufferMapping> mapping;
391 EXPECT_EQ(MOJO_RESULT_OK,
392 dispatcher->MapBuffer(0, 100, MOJO_MAP_BUFFER_FLAG_NONE, &mapping));
393 ASSERT_TRUE(mapping);
394 ASSERT_TRUE(mapping->base());
395 ASSERT_EQ(100u, mapping->length());
396
397 // Send the shared buffer.
398 const std::string go1("go 1");
399 DispatcherTransport transport(
400 test::DispatcherTryStartTransport(dispatcher.get()));
401 ASSERT_TRUE(transport.is_valid());
402
403 std::vector<DispatcherTransport> transports;
404 transports.push_back(transport);
405 EXPECT_EQ(MOJO_RESULT_OK,
406 mp->WriteMessage(0,
407 &go1[0],
408 static_cast<uint32_t>(go1.size()),
409 &transports,
410 MOJO_WRITE_MESSAGE_FLAG_NONE));
411 transport.End();
412
413 EXPECT_TRUE(dispatcher->HasOneRef());
414 dispatcher = NULL;
415
416 // Wait for a message from the child.
417 EXPECT_EQ(MOJO_RESULT_OK, WaitIfNecessary(mp, MOJO_WAIT_FLAG_READABLE));
418
419 std::string read_buffer(100, '\0');
420 uint32_t num_bytes = static_cast<uint32_t>(read_buffer.size());
421 EXPECT_EQ(MOJO_RESULT_OK,
422 mp->ReadMessage(0,
423 &read_buffer[0], &num_bytes,
424 NULL, NULL,
425 MOJO_READ_MESSAGE_FLAG_NONE));
426 read_buffer.resize(num_bytes);
427 EXPECT_EQ(std::string("go 2"), read_buffer);
428
429 // After we get it, the child should have written something to the shared
430 // buffer.
431 static const char kHello[] = "hello";
432 EXPECT_EQ(0, memcmp(mapping->base(), kHello, sizeof(kHello)));
433
434 // Now we'll write some stuff to the shared buffer.
435 static const char kWorld[] = "world!!!";
436 memcpy(mapping->base(), kWorld, sizeof(kWorld));
437
438 // And send a message to signal that we've written stuff.
439 const std::string go3("go 3");
440 EXPECT_EQ(MOJO_RESULT_OK,
441 mp->WriteMessage(0,
442 &go3[0],
443 static_cast<uint32_t>(go3.size()),
444 NULL,
445 MOJO_WRITE_MESSAGE_FLAG_NONE));
446
447 // Wait for |mp| to become readable, which should fail.
448 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
449 WaitIfNecessary(mp, MOJO_WAIT_FLAG_READABLE));
450
451 mp->Close(0);
452
453 EXPECT_EQ(0, helper()->WaitForChildShutdown());
454 }
455
283 MOJO_MULTIPROCESS_TEST_CHILD_MAIN(CheckPlatformHandleFile) { 456 MOJO_MULTIPROCESS_TEST_CHILD_MAIN(CheckPlatformHandleFile) {
284 ChannelThread channel_thread; 457 ChannelThread channel_thread;
285 embedder::ScopedPlatformHandle client_platform_handle = 458 embedder::ScopedPlatformHandle client_platform_handle =
286 mojo::test::MultiprocessTestHelper::client_platform_handle.Pass(); 459 mojo::test::MultiprocessTestHelper::client_platform_handle.Pass();
287 CHECK(client_platform_handle.is_valid()); 460 CHECK(client_platform_handle.is_valid());
288 scoped_refptr<MessagePipe> mp(new MessagePipe( 461 scoped_refptr<MessagePipe> mp(new MessagePipe(
289 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()), 462 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()),
290 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()))); 463 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint())));
291 channel_thread.Start(client_platform_handle.Pass(), mp); 464 channel_thread.Start(client_platform_handle.Pass(), mp);
292 465
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 WaitIfNecessary(mp, MOJO_WAIT_FLAG_READABLE)); 547 WaitIfNecessary(mp, MOJO_WAIT_FLAG_READABLE));
375 548
376 mp->Close(0); 549 mp->Close(0);
377 550
378 EXPECT_EQ(0, helper()->WaitForChildShutdown()); 551 EXPECT_EQ(0, helper()->WaitForChildShutdown());
379 } 552 }
380 553
381 } // namespace 554 } // namespace
382 } // namespace system 555 } // namespace system
383 } // namespace mojo 556 } // namespace mojo
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698