15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "mojo/embedder/embedder.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <string.h>
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/bind.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/location.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/logging.h"
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/macros.h"
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/message_loop/message_loop.h"
14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/synchronization/waitable_event.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/test/test_io_thread.h"
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "mojo/common/test/multiprocess_test_helper.h"
1723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "mojo/embedder/platform_channel_pair.h"
1823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "mojo/embedder/test_embedder.h"
19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "mojo/public/c/system/core.h"
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "mojo/system/test_utils.h"
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace mojo {
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace embedder {
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class ScopedTestChannel {
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public:
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Creates a channel that lives on a given I/O thread (determined by the given
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // |TaskRunner|) attached to the given |platform_handle|. After construction,
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // |bootstrap_message_pipe()| gives the Mojo handle for the bootstrap message
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // pipe on this channel; it is up to the caller to close this handle.
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Note: The I/O thread must outlive this object (and its message loop must
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // continue pumping messages while this object is alive).
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ScopedTestChannel(scoped_refptr<base::TaskRunner> io_thread_task_runner,
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    ScopedPlatformHandle platform_handle)
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      : io_thread_task_runner_(io_thread_task_runner),
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        bootstrap_message_pipe_(MOJO_HANDLE_INVALID),
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        did_create_channel_event_(true, false),
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        channel_info_(nullptr) {
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bootstrap_message_pipe_ =
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        CreateChannel(platform_handle.Pass(),
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      io_thread_task_runner_,
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      base::Bind(&ScopedTestChannel::DidCreateChannel,
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 base::Unretained(this)),
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      nullptr)
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            .release()
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            .value();
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CHECK_NE(bootstrap_message_pipe_, MOJO_HANDLE_INVALID);
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Destructor: Shuts down the channel. (As noted above, for this to happen,
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // the I/O thread must be alive and pumping messages.)
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ~ScopedTestChannel() {
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    system::test::PostTaskAndWait(
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        io_thread_task_runner_,
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        FROM_HERE,
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::Bind(&ScopedTestChannel::DestroyChannel, base::Unretained(this)));
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Waits for channel creation to be completed.
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void WaitForChannelCreationCompletion() { did_create_channel_event_.Wait(); }
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MojoHandle bootstrap_message_pipe() const { return bootstrap_message_pipe_; }
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Call only after |WaitForChannelCreationCompletion()|. Use only to check
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // that it's not null.
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const ChannelInfo* channel_info() const { return channel_info_; }
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private:
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void DidCreateChannel(ChannelInfo* channel_info) {
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CHECK(channel_info);
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CHECK(!channel_info_);
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    channel_info_ = channel_info;
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    did_create_channel_event_.Signal();
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void DestroyChannel() {
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CHECK(channel_info_);
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DestroyChannelOnIOThread(channel_info_);
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    channel_info_ = nullptr;
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_refptr<base::TaskRunner> io_thread_task_runner_;
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Valid from creation until whenever it gets closed (by the "owner" of this
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // object).
8823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Note: We don't want use the C++ wrappers here, since we want to test the
8923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // API at the lowest level.
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MojoHandle bootstrap_message_pipe_;
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Set after channel creation has been completed (i.e., the callback to
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // |CreateChannel()| has been called).
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::WaitableEvent did_create_channel_event_;
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Valid after channel creation completion until destruction.
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ChannelInfo* channel_info_;
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ScopedTestChannel);
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class EmbedderTest : public testing::Test {
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public:
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EmbedderTest() : test_io_thread_(base::TestIOThread::kAutoStart) {}
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual ~EmbedderTest() {}
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) protected:
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::TestIOThread* test_io_thread() { return &test_io_thread_; }
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private:
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::TestIOThread test_io_thread_;
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(EmbedderTest);
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(EmbedderTest, ChannelsBasic) {
11703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  mojo::embedder::test::InitWithSimplePlatformSupport();
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  {
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    PlatformChannelPair channel_pair;
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ScopedTestChannel server_channel(test_io_thread()->task_runner(),
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                     channel_pair.PassServerHandle());
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MojoHandle server_mp = server_channel.bootstrap_message_pipe();
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_NE(server_mp, MOJO_HANDLE_INVALID);
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ScopedTestChannel client_channel(test_io_thread()->task_runner(),
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                     channel_pair.PassClientHandle());
127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MojoHandle client_mp = client_channel.bootstrap_message_pipe();
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_NE(client_mp, MOJO_HANDLE_INVALID);
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // We can write to a message pipe handle immediately.
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const char kHello[] = "hello";
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK,
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              MojoWriteMessage(server_mp,
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               kHello,
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               static_cast<uint32_t>(sizeof(kHello)),
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               nullptr,
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               0,
138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                               MOJO_WRITE_MESSAGE_FLAG_NONE));
139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Now wait for the other side to become readable.
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        MOJO_RESULT_OK,
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        MojoWait(
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            client_mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    char buffer[1000] = {};
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer));
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK,
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              MojoReadMessage(client_mp,
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              buffer,
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              &num_bytes,
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              nullptr,
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              nullptr,
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              MOJO_READ_MESSAGE_FLAG_NONE));
155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(sizeof(kHello), num_bytes);
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_STREQ(kHello, buffer);
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK, MojoClose(server_mp));
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK, MojoClose(client_mp));
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // By this point, these waits should basically be no-ops (since we've waited
162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // for the client message pipe to become readable, which implies that both
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // the server and client channels were completely created).
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    server_channel.WaitForChannelCreationCompletion();
165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    client_channel.WaitForChannelCreationCompletion();
1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_TRUE(server_channel.channel_info());
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_TRUE(client_channel.channel_info());
168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(test::Shutdown());
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(EmbedderTest, ChannelsHandlePassing) {
17403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  mojo::embedder::test::InitWithSimplePlatformSupport();
175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  {
177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    PlatformChannelPair channel_pair;
178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ScopedTestChannel server_channel(test_io_thread()->task_runner(),
179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                     channel_pair.PassServerHandle());
180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MojoHandle server_mp = server_channel.bootstrap_message_pipe();
181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_NE(server_mp, MOJO_HANDLE_INVALID);
182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ScopedTestChannel client_channel(test_io_thread()->task_runner(),
183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                     channel_pair.PassClientHandle());
184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MojoHandle client_mp = client_channel.bootstrap_message_pipe();
185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_NE(client_mp, MOJO_HANDLE_INVALID);
186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MojoHandle h0, h1;
1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(nullptr, &h0, &h1));
189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Write a message to |h0| (attaching nothing).
191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const char kHello[] = "hello";
192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK,
1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              MojoWriteMessage(h0,
1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               kHello,
1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               static_cast<uint32_t>(sizeof(kHello)),
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               nullptr,
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               0,
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                               MOJO_WRITE_MESSAGE_FLAG_NONE));
199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Write one message to |server_mp|, attaching |h1|.
201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const char kWorld[] = "world!!!";
202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK,
2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              MojoWriteMessage(server_mp,
2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               kWorld,
2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               static_cast<uint32_t>(sizeof(kWorld)),
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               &h1,
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               1,
208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                               MOJO_WRITE_MESSAGE_FLAG_NONE));
209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    h1 = MOJO_HANDLE_INVALID;
210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Write another message to |h0|.
212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const char kFoo[] = "foo";
213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK,
2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              MojoWriteMessage(h0,
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               kFoo,
2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               static_cast<uint32_t>(sizeof(kFoo)),
2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               nullptr,
2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               0,
219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                               MOJO_WRITE_MESSAGE_FLAG_NONE));
220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Wait for |client_mp| to become readable.
2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(
2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        MOJO_RESULT_OK,
2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        MojoWait(
2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            client_mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Read a message from |client_mp|.
228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    char buffer[1000] = {};
229a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer));
230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MojoHandle handles[10] = {};
231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    uint32_t num_handles = arraysize(handles);
232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK,
2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              MojoReadMessage(client_mp,
2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              buffer,
2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              &num_bytes,
2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              handles,
2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              &num_handles,
2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              MOJO_READ_MESSAGE_FLAG_NONE));
239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(sizeof(kWorld), num_bytes);
240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_STREQ(kWorld, buffer);
241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(1u, num_handles);
242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_NE(handles[0], MOJO_HANDLE_INVALID);
243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    h1 = handles[0];
244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Wait for |h1| to become readable.
2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(
2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        MOJO_RESULT_OK,
2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        MojoWait(h1, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Read a message from |h1|.
251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    memset(buffer, 0, sizeof(buffer));
252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    num_bytes = static_cast<uint32_t>(sizeof(buffer));
253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    memset(handles, 0, sizeof(handles));
254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    num_handles = arraysize(handles);
255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK,
2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              MojoReadMessage(h1,
2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              buffer,
2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              &num_bytes,
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              handles,
2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              &num_handles,
261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              MOJO_READ_MESSAGE_FLAG_NONE));
262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(sizeof(kHello), num_bytes);
263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_STREQ(kHello, buffer);
264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(0u, num_handles);
265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Wait for |h1| to become readable (again).
2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(
2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        MOJO_RESULT_OK,
2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        MojoWait(h1, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Read the second message from |h1|.
272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    memset(buffer, 0, sizeof(buffer));
273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    num_bytes = static_cast<uint32_t>(sizeof(buffer));
2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(MOJO_RESULT_OK,
2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              MojoReadMessage(h1,
2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              buffer,
2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              &num_bytes,
2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              nullptr,
2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              nullptr,
2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              MOJO_READ_MESSAGE_FLAG_NONE));
281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(sizeof(kFoo), num_bytes);
282a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_STREQ(kFoo, buffer);
283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Write a message to |h1|.
285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const char kBarBaz[] = "barbaz";
286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK,
2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              MojoWriteMessage(h1,
2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               kBarBaz,
2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               static_cast<uint32_t>(sizeof(kBarBaz)),
2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               nullptr,
2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               0,
292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                               MOJO_WRITE_MESSAGE_FLAG_NONE));
293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Wait for |h0| to become readable.
2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(
2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        MOJO_RESULT_OK,
2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        MojoWait(h0, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
298a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Read a message from |h0|.
300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    memset(buffer, 0, sizeof(buffer));
301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    num_bytes = static_cast<uint32_t>(sizeof(buffer));
3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(MOJO_RESULT_OK,
3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              MojoReadMessage(h0,
3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              buffer,
3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              &num_bytes,
3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              nullptr,
3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              nullptr,
3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              MOJO_READ_MESSAGE_FLAG_NONE));
309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(sizeof(kBarBaz), num_bytes);
310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_STREQ(kBarBaz, buffer);
311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK, MojoClose(server_mp));
313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK, MojoClose(client_mp));
314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h0));
315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h1));
316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
317a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    server_channel.WaitForChannelCreationCompletion();
318a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    client_channel.WaitForChannelCreationCompletion();
3191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_TRUE(server_channel.channel_info());
3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_TRUE(client_channel.channel_info());
321a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(test::Shutdown());
324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// The sequence of messages sent is:
327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)//       server_mp   client_mp   mp0         mp1         mp2         mp3
328a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)//   1.  "hello"
329a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)//   2.              "world!"
330a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)//   3.                          "FOO"
331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)//   4.  "Bar"+mp1
332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)//   5.  (close)
333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)//   6.              (close)
334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)//   7.                                                              "baz"
335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)//   8.                                                              (closed)
336a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)//   9.                                      "quux"+mp2
337a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)//  10.                          (close)
338a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)//  11.                                      (wait/cl.)
339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)//  12.                                                  (wait/cl.)
340a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(EmbedderTest, MultiprocessChannels) {
34103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  mojo::embedder::test::InitWithSimplePlatformSupport();
342a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  mojo::test::MultiprocessTestHelper multiprocess_test_helper;
343a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  multiprocess_test_helper.StartChild("MultiprocessChannelsClient");
344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
345a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  {
346a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ScopedTestChannel server_channel(
347a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        test_io_thread()->task_runner(),
348a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        multiprocess_test_helper.server_platform_handle.Pass());
349a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MojoHandle server_mp = server_channel.bootstrap_message_pipe();
350a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_NE(server_mp, MOJO_HANDLE_INVALID);
351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    server_channel.WaitForChannelCreationCompletion();
3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_TRUE(server_channel.channel_info());
353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // 1. Write a message to |server_mp| (attaching nothing).
355a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const char kHello[] = "hello";
356a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK,
3575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              MojoWriteMessage(server_mp,
3585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               kHello,
3595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               static_cast<uint32_t>(sizeof(kHello)),
3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               nullptr,
3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               0,
362a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                               MOJO_WRITE_MESSAGE_FLAG_NONE));
363a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
364a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // TODO(vtl): If the scope were ended immediately here (maybe after closing
365a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // |server_mp|), we die with a fatal error in |Channel::HandleLocalError()|.
366a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
367a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // 2. Read a message from |server_mp|.
3685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(
3695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        MOJO_RESULT_OK,
3705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        MojoWait(
3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            server_mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
372a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    char buffer[1000] = {};
373a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer));
374a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK,
3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              MojoReadMessage(server_mp,
3765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              buffer,
3775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              &num_bytes,
3781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              nullptr,
3791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              nullptr,
380a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              MOJO_READ_MESSAGE_FLAG_NONE));
381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const char kWorld[] = "world!";
382a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(sizeof(kWorld), num_bytes);
383a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_STREQ(kWorld, buffer);
384a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
385a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Create a new message pipe (endpoints |mp0| and |mp1|).
386a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MojoHandle mp0, mp1;
3871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(nullptr, &mp0, &mp1));
388a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
389a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // 3. Write something to |mp0|.
390a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const char kFoo[] = "FOO";
391a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK,
3925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              MojoWriteMessage(mp0,
3935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               kFoo,
3945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               static_cast<uint32_t>(sizeof(kFoo)),
3951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               nullptr,
3965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               0,
397a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                               MOJO_WRITE_MESSAGE_FLAG_NONE));
398a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
399a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // 4. Write a message to |server_mp|, attaching |mp1|.
400a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const char kBar[] = "Bar";
401a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK,
4025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              MojoWriteMessage(server_mp,
4035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               kBar,
4045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               static_cast<uint32_t>(sizeof(kBar)),
4055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               &mp1,
4065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               1,
407a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                               MOJO_WRITE_MESSAGE_FLAG_NONE));
408a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    mp1 = MOJO_HANDLE_INVALID;
409a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
410a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // 5. Close |server_mp|.
411a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK, MojoClose(server_mp));
412a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
413a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // 9. Read a message from |mp0|, which should have |mp2| attached.
4145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(
4155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        MOJO_RESULT_OK,
4165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        MojoWait(mp0, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
417a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    memset(buffer, 0, sizeof(buffer));
418a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    num_bytes = static_cast<uint32_t>(sizeof(buffer));
419a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MojoHandle mp2 = MOJO_HANDLE_INVALID;
420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    uint32_t num_handles = 1;
421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK,
4225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              MojoReadMessage(mp0,
4235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              buffer,
4245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              &num_bytes,
4255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              &mp2,
4265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              &num_handles,
427a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              MOJO_READ_MESSAGE_FLAG_NONE));
428a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const char kQuux[] = "quux";
429a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(sizeof(kQuux), num_bytes);
430a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_STREQ(kQuux, buffer);
431a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(1u, num_handles);
432a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_NE(mp2, MOJO_HANDLE_INVALID);
433a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
434a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // 7. Read a message from |mp2|.
4355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(
4365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        MOJO_RESULT_OK,
4375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        MojoWait(mp2, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
438a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    memset(buffer, 0, sizeof(buffer));
439a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    num_bytes = static_cast<uint32_t>(sizeof(buffer));
4401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(MOJO_RESULT_OK,
4411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              MojoReadMessage(mp2,
4421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              buffer,
4431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              &num_bytes,
4441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              nullptr,
4451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              nullptr,
4461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              MOJO_READ_MESSAGE_FLAG_NONE));
447a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const char kBaz[] = "baz";
448a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(sizeof(kBaz), num_bytes);
449a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_STREQ(kBaz, buffer);
450a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
451a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // 10. Close |mp0|.
452a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK, MojoClose(mp0));
453a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
4545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// 12. Wait on |mp2| (which should eventually fail) and then close it.
455a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// TODO(vtl): crbug.com/351768
456a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if 0
457a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
458f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              MojoWait(mp2, MOJO_HANDLE_SIGNAL_READABLE,
459f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                       MOJO_DEADLINE_INDEFINITE));
460a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif
461a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK, MojoClose(mp2));
462a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
463a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
464a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(multiprocess_test_helper.WaitForChildTestShutdown());
465a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(test::Shutdown());
466a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
467a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
468a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)MOJO_MULTIPROCESS_TEST_CHILD_TEST(MultiprocessChannelsClient) {
4696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ScopedPlatformHandle client_platform_handle =
470a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      mojo::test::MultiprocessTestHelper::client_platform_handle.Pass();
471a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(client_platform_handle.is_valid());
472a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
4731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::TestIOThread test_io_thread(base::TestIOThread::kAutoStart);
47403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  mojo::embedder::test::InitWithSimplePlatformSupport();
475a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
476a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  {
477a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ScopedTestChannel client_channel(test_io_thread.task_runner(),
478a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                     client_platform_handle.Pass());
479a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MojoHandle client_mp = client_channel.bootstrap_message_pipe();
480a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_NE(client_mp, MOJO_HANDLE_INVALID);
481a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    client_channel.WaitForChannelCreationCompletion();
4821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    CHECK(client_channel.channel_info() != nullptr);
483a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
484a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // 1. Read the first message from |client_mp|.
4855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(
4865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        MOJO_RESULT_OK,
4875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        MojoWait(
4885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            client_mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
489a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    char buffer[1000] = {};
490a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer));
491a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK,
4925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              MojoReadMessage(client_mp,
4935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              buffer,
4945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              &num_bytes,
4951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              nullptr,
4961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              nullptr,
497a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              MOJO_READ_MESSAGE_FLAG_NONE));
498a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const char kHello[] = "hello";
499a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(sizeof(kHello), num_bytes);
500a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_STREQ(kHello, buffer);
501a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
502a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // 2. Write a message to |client_mp| (attaching nothing).
503a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const char kWorld[] = "world!";
504a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK,
5055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              MojoWriteMessage(client_mp,
5065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               kWorld,
5075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               static_cast<uint32_t>(sizeof(kWorld)),
5081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               nullptr,
5095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               0,
510a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                               MOJO_WRITE_MESSAGE_FLAG_NONE));
511a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
512a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // 4. Read a message from |client_mp|, which should have |mp1| attached.
5135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(
5145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        MOJO_RESULT_OK,
5155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        MojoWait(
5165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            client_mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
517a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // TODO(vtl): If the scope were to end here (and |client_mp| closed), we'd
518a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // die (again due to |Channel::HandleLocalError()|).
519a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    memset(buffer, 0, sizeof(buffer));
520a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    num_bytes = static_cast<uint32_t>(sizeof(buffer));
521a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MojoHandle mp1 = MOJO_HANDLE_INVALID;
522a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    uint32_t num_handles = 1;
523a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK,
5245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              MojoReadMessage(client_mp,
5255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              buffer,
5265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              &num_bytes,
5275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              &mp1,
5285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              &num_handles,
529a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              MOJO_READ_MESSAGE_FLAG_NONE));
530a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const char kBar[] = "Bar";
531a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(sizeof(kBar), num_bytes);
532a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_STREQ(kBar, buffer);
533a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(1u, num_handles);
534a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_NE(mp1, MOJO_HANDLE_INVALID);
535a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // TODO(vtl): If the scope were to end here (and the two handles closed),
536a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // we'd die due to |Channel::RunRemoteMessagePipeEndpoint()| not handling
537a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // write errors (assuming the parent had closed the pipe).
538a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
539a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // 6. Close |client_mp|.
540a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK, MojoClose(client_mp));
541a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
542a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Create a new message pipe (endpoints |mp2| and |mp3|).
543a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MojoHandle mp2, mp3;
5441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(nullptr, &mp2, &mp3));
545a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
546a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // 7. Write a message to |mp3|.
547a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const char kBaz[] = "baz";
548a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK,
5495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              MojoWriteMessage(mp3,
5505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               kBaz,
5515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               static_cast<uint32_t>(sizeof(kBaz)),
5521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               nullptr,
5535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               0,
554a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                               MOJO_WRITE_MESSAGE_FLAG_NONE));
555a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
556a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // 8. Close |mp3|.
557a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK, MojoClose(mp3));
558a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
559a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // 9. Write a message to |mp1|, attaching |mp2|.
560a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const char kQuux[] = "quux";
561a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK,
5625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              MojoWriteMessage(mp1,
5635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               kQuux,
5645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               static_cast<uint32_t>(sizeof(kQuux)),
5655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               &mp2,
5665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               1,
567a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                               MOJO_WRITE_MESSAGE_FLAG_NONE));
568a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    mp2 = MOJO_HANDLE_INVALID;
569a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
570a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // 3. Read a message from |mp1|.
5715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(
5725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        MOJO_RESULT_OK,
5735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
574a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    memset(buffer, 0, sizeof(buffer));
575a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    num_bytes = static_cast<uint32_t>(sizeof(buffer));
5761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(MOJO_RESULT_OK,
5771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              MojoReadMessage(mp1,
5781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              buffer,
5791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              &num_bytes,
5801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              nullptr,
5811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              nullptr,
5821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              MOJO_READ_MESSAGE_FLAG_NONE));
583a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const char kFoo[] = "FOO";
584a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(sizeof(kFoo), num_bytes);
585a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_STREQ(kFoo, buffer);
586a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
587a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // 11. Wait on |mp1| (which should eventually fail) and then close it.
5885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(
5895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        MOJO_RESULT_FAILED_PRECONDITION,
5905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
591a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(MOJO_RESULT_OK, MojoClose(mp1));
592a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
5935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(test::Shutdown());
5955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TODO(vtl): Test immediate write & close.
5985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TODO(vtl): Test broken-connection cases.
5995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
6015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace embedder
6025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace mojo
603