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

Side by Side Diff: mojo/edk/embedder/embedder_unittest.cc

Issue 814543006: Move //mojo/{public, edk} underneath //third_party (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 11 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
« no previous file with comments | « mojo/edk/embedder/embedder_internal.h ('k') | mojo/edk/embedder/entrypoints.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "mojo/edk/embedder/embedder.h"
6
7 #include <string.h>
8
9 #include "base/bind.h"
10 #include "base/location.h"
11 #include "base/logging.h"
12 #include "base/macros.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/synchronization/waitable_event.h"
15 #include "base/test/test_io_thread.h"
16 #include "base/test/test_timeouts.h"
17 #include "mojo/edk/embedder/platform_channel_pair.h"
18 #include "mojo/edk/embedder/test_embedder.h"
19 #include "mojo/edk/system/test_utils.h"
20 #include "mojo/edk/test/multiprocess_test_helper.h"
21 #include "mojo/public/c/system/core.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23
24 namespace mojo {
25 namespace embedder {
26 namespace {
27
28 const MojoHandleSignals kSignalReadadableWritable =
29 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE;
30
31 const MojoHandleSignals kSignalAll = MOJO_HANDLE_SIGNAL_READABLE |
32 MOJO_HANDLE_SIGNAL_WRITABLE |
33 MOJO_HANDLE_SIGNAL_PEER_CLOSED;
34
35 class ScopedTestChannel {
36 public:
37 // Creates a channel that lives on a given I/O thread (determined by the given
38 // |TaskRunner|) attached to the given |platform_handle|. After construction,
39 // |bootstrap_message_pipe()| gives the Mojo handle for the bootstrap message
40 // pipe on this channel; it is up to the caller to close this handle.
41 // Note: The I/O thread must outlive this object (and its message loop must
42 // continue pumping messages while this object is alive).
43 ScopedTestChannel(scoped_refptr<base::TaskRunner> io_thread_task_runner,
44 ScopedPlatformHandle platform_handle)
45 : io_thread_task_runner_(io_thread_task_runner),
46 bootstrap_message_pipe_(MOJO_HANDLE_INVALID),
47 did_create_channel_event_(true, false),
48 channel_info_(nullptr) {
49 bootstrap_message_pipe_ =
50 CreateChannel(platform_handle.Pass(), io_thread_task_runner_,
51 base::Bind(&ScopedTestChannel::DidCreateChannel,
52 base::Unretained(this)),
53 nullptr)
54 .release()
55 .value();
56 CHECK_NE(bootstrap_message_pipe_, MOJO_HANDLE_INVALID);
57 }
58
59 // Destructor: Shuts down the channel. (As noted above, for this to happen,
60 // the I/O thread must be alive and pumping messages.)
61 ~ScopedTestChannel() { DestroyChannel(channel_info_); }
62
63 // Waits for channel creation to be completed.
64 void WaitForChannelCreationCompletion() { did_create_channel_event_.Wait(); }
65
66 MojoHandle bootstrap_message_pipe() const { return bootstrap_message_pipe_; }
67
68 // Call only after |WaitForChannelCreationCompletion()|. Use only to check
69 // that it's not null.
70 const ChannelInfo* channel_info() const { return channel_info_; }
71
72 private:
73 void DidCreateChannel(ChannelInfo* channel_info) {
74 CHECK(channel_info);
75 CHECK(!channel_info_);
76 channel_info_ = channel_info;
77 did_create_channel_event_.Signal();
78 }
79
80 scoped_refptr<base::TaskRunner> io_thread_task_runner_;
81
82 // Valid from creation until whenever it gets closed (by the "owner" of this
83 // object).
84 // Note: We don't want use the C++ wrappers here, since we want to test the
85 // API at the lowest level.
86 MojoHandle bootstrap_message_pipe_;
87
88 // Set after channel creation has been completed (i.e., the callback to
89 // |CreateChannel()| has been called).
90 base::WaitableEvent did_create_channel_event_;
91
92 // Valid after channel creation completion until destruction.
93 ChannelInfo* channel_info_;
94
95 DISALLOW_COPY_AND_ASSIGN(ScopedTestChannel);
96 };
97
98 class EmbedderTest : public testing::Test {
99 public:
100 EmbedderTest() : test_io_thread_(base::TestIOThread::kAutoStart) {}
101 ~EmbedderTest() override {}
102
103 protected:
104 base::TestIOThread* test_io_thread() { return &test_io_thread_; }
105
106 private:
107 base::TestIOThread test_io_thread_;
108
109 DISALLOW_COPY_AND_ASSIGN(EmbedderTest);
110 };
111
112 TEST_F(EmbedderTest, ChannelsBasic) {
113 mojo::embedder::test::InitWithSimplePlatformSupport();
114
115 {
116 PlatformChannelPair channel_pair;
117 ScopedTestChannel server_channel(test_io_thread()->task_runner(),
118 channel_pair.PassServerHandle());
119 MojoHandle server_mp = server_channel.bootstrap_message_pipe();
120 EXPECT_NE(server_mp, MOJO_HANDLE_INVALID);
121 ScopedTestChannel client_channel(test_io_thread()->task_runner(),
122 channel_pair.PassClientHandle());
123 MojoHandle client_mp = client_channel.bootstrap_message_pipe();
124 EXPECT_NE(client_mp, MOJO_HANDLE_INVALID);
125
126 // We can write to a message pipe handle immediately.
127 const char kHello[] = "hello";
128 EXPECT_EQ(MOJO_RESULT_OK,
129 MojoWriteMessage(server_mp, kHello,
130 static_cast<uint32_t>(sizeof(kHello)), nullptr,
131 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
132
133 // Now wait for the other side to become readable.
134 MojoHandleSignalsState state;
135 EXPECT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE,
136 MOJO_DEADLINE_INDEFINITE, &state));
137 EXPECT_EQ(kSignalReadadableWritable, state.satisfied_signals);
138 EXPECT_EQ(kSignalAll, state.satisfiable_signals);
139
140 char buffer[1000] = {};
141 uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer));
142 EXPECT_EQ(MOJO_RESULT_OK,
143 MojoReadMessage(client_mp, buffer, &num_bytes, nullptr, nullptr,
144 MOJO_READ_MESSAGE_FLAG_NONE));
145 EXPECT_EQ(sizeof(kHello), num_bytes);
146 EXPECT_STREQ(kHello, buffer);
147
148 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(server_mp));
149 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(client_mp));
150
151 // By this point, these waits should basically be no-ops (since we've waited
152 // for the client message pipe to become readable, which implies that both
153 // the server and client channels were completely created).
154 server_channel.WaitForChannelCreationCompletion();
155 client_channel.WaitForChannelCreationCompletion();
156 EXPECT_TRUE(server_channel.channel_info());
157 EXPECT_TRUE(client_channel.channel_info());
158 }
159
160 EXPECT_TRUE(test::Shutdown());
161 }
162
163 class TestAsyncWaiter {
164 public:
165 TestAsyncWaiter() : event_(true, false), wait_result_(MOJO_RESULT_UNKNOWN) {}
166
167 void Awake(MojoResult result) {
168 base::AutoLock l(wait_result_lock_);
169 wait_result_ = result;
170 event_.Signal();
171 }
172
173 bool TryWait() { return event_.TimedWait(TestTimeouts::action_timeout()); }
174
175 MojoResult wait_result() const {
176 base::AutoLock l(wait_result_lock_);
177 return wait_result_;
178 }
179
180 private:
181 base::WaitableEvent event_;
182
183 mutable base::Lock wait_result_lock_;
184 MojoResult wait_result_;
185
186 DISALLOW_COPY_AND_ASSIGN(TestAsyncWaiter);
187 };
188
189 void WriteHello(MessagePipeHandle pipe) {
190 static const char kHello[] = "hello";
191 CHECK_EQ(MOJO_RESULT_OK,
192 WriteMessageRaw(pipe, kHello, static_cast<uint32_t>(sizeof(kHello)),
193 nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
194 }
195
196 void CloseScopedHandle(ScopedMessagePipeHandle handle) {
197 // Do nothing and the destructor will close it.
198 }
199
200 TEST_F(EmbedderTest, AsyncWait) {
201 mojo::embedder::test::InitWithSimplePlatformSupport();
202
203 {
204 ScopedMessagePipeHandle client_mp;
205 ScopedMessagePipeHandle server_mp;
206 EXPECT_EQ(MOJO_RESULT_OK,
207 mojo::CreateMessagePipe(nullptr, &client_mp, &server_mp));
208
209 TestAsyncWaiter waiter;
210 EXPECT_EQ(MOJO_RESULT_OK,
211 AsyncWait(client_mp.get().value(), MOJO_HANDLE_SIGNAL_READABLE,
212 base::Bind(&TestAsyncWaiter::Awake,
213 base::Unretained(&waiter))));
214
215 test_io_thread()->task_runner()->PostTask(
216 FROM_HERE, base::Bind(&WriteHello, server_mp.get()));
217 EXPECT_TRUE(waiter.TryWait());
218 EXPECT_EQ(MOJO_RESULT_OK, waiter.wait_result());
219
220 // If message is in the queue, it does't allow us to wait.
221 TestAsyncWaiter waiter_that_doesnt_wait;
222 EXPECT_EQ(
223 MOJO_RESULT_ALREADY_EXISTS,
224 AsyncWait(client_mp.get().value(), MOJO_HANDLE_SIGNAL_READABLE,
225 base::Bind(&TestAsyncWaiter::Awake,
226 base::Unretained(&waiter_that_doesnt_wait))));
227
228 char buffer[1000];
229 uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer));
230 CHECK_EQ(MOJO_RESULT_OK,
231 ReadMessageRaw(client_mp.get(), buffer, &num_bytes, nullptr,
232 nullptr, MOJO_READ_MESSAGE_FLAG_NONE));
233
234 TestAsyncWaiter unsatisfiable_waiter;
235 EXPECT_EQ(MOJO_RESULT_OK,
236 AsyncWait(client_mp.get().value(), MOJO_HANDLE_SIGNAL_READABLE,
237 base::Bind(&TestAsyncWaiter::Awake,
238 base::Unretained(&unsatisfiable_waiter))));
239
240 test_io_thread()->task_runner()->PostTask(
241 FROM_HERE,
242 base::Bind(&CloseScopedHandle, base::Passed(server_mp.Pass())));
243
244 EXPECT_TRUE(unsatisfiable_waiter.TryWait());
245 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
246 unsatisfiable_waiter.wait_result());
247 }
248
249 EXPECT_TRUE(test::Shutdown());
250 }
251
252 TEST_F(EmbedderTest, ChannelsHandlePassing) {
253 mojo::embedder::test::InitWithSimplePlatformSupport();
254
255 {
256 PlatformChannelPair channel_pair;
257 ScopedTestChannel server_channel(test_io_thread()->task_runner(),
258 channel_pair.PassServerHandle());
259 MojoHandle server_mp = server_channel.bootstrap_message_pipe();
260 EXPECT_NE(server_mp, MOJO_HANDLE_INVALID);
261 ScopedTestChannel client_channel(test_io_thread()->task_runner(),
262 channel_pair.PassClientHandle());
263 MojoHandle client_mp = client_channel.bootstrap_message_pipe();
264 EXPECT_NE(client_mp, MOJO_HANDLE_INVALID);
265
266 MojoHandle h0, h1;
267 EXPECT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(nullptr, &h0, &h1));
268
269 // Write a message to |h0| (attaching nothing).
270 const char kHello[] = "hello";
271 EXPECT_EQ(
272 MOJO_RESULT_OK,
273 MojoWriteMessage(h0, kHello, static_cast<uint32_t>(sizeof(kHello)),
274 nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
275
276 // Write one message to |server_mp|, attaching |h1|.
277 const char kWorld[] = "world!!!";
278 EXPECT_EQ(MOJO_RESULT_OK,
279 MojoWriteMessage(server_mp, kWorld,
280 static_cast<uint32_t>(sizeof(kWorld)), &h1, 1,
281 MOJO_WRITE_MESSAGE_FLAG_NONE));
282 h1 = MOJO_HANDLE_INVALID;
283
284 // Write another message to |h0|.
285 const char kFoo[] = "foo";
286 EXPECT_EQ(MOJO_RESULT_OK,
287 MojoWriteMessage(h0, kFoo, static_cast<uint32_t>(sizeof(kFoo)),
288 nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
289
290 // Wait for |client_mp| to become readable.
291 MojoHandleSignalsState state;
292 EXPECT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE,
293 MOJO_DEADLINE_INDEFINITE, &state));
294 EXPECT_EQ(kSignalReadadableWritable, state.satisfied_signals);
295 EXPECT_EQ(kSignalAll, state.satisfiable_signals);
296
297 // Read a message from |client_mp|.
298 char buffer[1000] = {};
299 uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer));
300 MojoHandle handles[10] = {};
301 uint32_t num_handles = arraysize(handles);
302 EXPECT_EQ(MOJO_RESULT_OK,
303 MojoReadMessage(client_mp, buffer, &num_bytes, handles,
304 &num_handles, MOJO_READ_MESSAGE_FLAG_NONE));
305 EXPECT_EQ(sizeof(kWorld), num_bytes);
306 EXPECT_STREQ(kWorld, buffer);
307 EXPECT_EQ(1u, num_handles);
308 EXPECT_NE(handles[0], MOJO_HANDLE_INVALID);
309 h1 = handles[0];
310
311 // Wait for |h1| to become readable.
312 EXPECT_EQ(MOJO_RESULT_OK, MojoWait(h1, MOJO_HANDLE_SIGNAL_READABLE,
313 MOJO_DEADLINE_INDEFINITE, &state));
314 EXPECT_EQ(kSignalReadadableWritable, state.satisfied_signals);
315 EXPECT_EQ(kSignalAll, state.satisfiable_signals);
316
317 // Read a message from |h1|.
318 memset(buffer, 0, sizeof(buffer));
319 num_bytes = static_cast<uint32_t>(sizeof(buffer));
320 memset(handles, 0, sizeof(handles));
321 num_handles = arraysize(handles);
322 EXPECT_EQ(MOJO_RESULT_OK,
323 MojoReadMessage(h1, buffer, &num_bytes, handles, &num_handles,
324 MOJO_READ_MESSAGE_FLAG_NONE));
325 EXPECT_EQ(sizeof(kHello), num_bytes);
326 EXPECT_STREQ(kHello, buffer);
327 EXPECT_EQ(0u, num_handles);
328
329 // Wait for |h1| to become readable (again).
330 EXPECT_EQ(MOJO_RESULT_OK, MojoWait(h1, MOJO_HANDLE_SIGNAL_READABLE,
331 MOJO_DEADLINE_INDEFINITE, &state));
332 EXPECT_EQ(kSignalReadadableWritable, state.satisfied_signals);
333 EXPECT_EQ(kSignalAll, state.satisfiable_signals);
334
335 // Read the second message from |h1|.
336 memset(buffer, 0, sizeof(buffer));
337 num_bytes = static_cast<uint32_t>(sizeof(buffer));
338 EXPECT_EQ(MOJO_RESULT_OK,
339 MojoReadMessage(h1, buffer, &num_bytes, nullptr, nullptr,
340 MOJO_READ_MESSAGE_FLAG_NONE));
341 EXPECT_EQ(sizeof(kFoo), num_bytes);
342 EXPECT_STREQ(kFoo, buffer);
343
344 // Write a message to |h1|.
345 const char kBarBaz[] = "barbaz";
346 EXPECT_EQ(
347 MOJO_RESULT_OK,
348 MojoWriteMessage(h1, kBarBaz, static_cast<uint32_t>(sizeof(kBarBaz)),
349 nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
350
351 // Wait for |h0| to become readable.
352 EXPECT_EQ(MOJO_RESULT_OK, MojoWait(h0, MOJO_HANDLE_SIGNAL_READABLE,
353 MOJO_DEADLINE_INDEFINITE, &state));
354 EXPECT_EQ(kSignalReadadableWritable, state.satisfied_signals);
355 EXPECT_EQ(kSignalAll, state.satisfiable_signals);
356
357 // Read a message from |h0|.
358 memset(buffer, 0, sizeof(buffer));
359 num_bytes = static_cast<uint32_t>(sizeof(buffer));
360 EXPECT_EQ(MOJO_RESULT_OK,
361 MojoReadMessage(h0, buffer, &num_bytes, nullptr, nullptr,
362 MOJO_READ_MESSAGE_FLAG_NONE));
363 EXPECT_EQ(sizeof(kBarBaz), num_bytes);
364 EXPECT_STREQ(kBarBaz, buffer);
365
366 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(server_mp));
367 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(client_mp));
368 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h0));
369 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h1));
370
371 server_channel.WaitForChannelCreationCompletion();
372 client_channel.WaitForChannelCreationCompletion();
373 EXPECT_TRUE(server_channel.channel_info());
374 EXPECT_TRUE(client_channel.channel_info());
375 }
376
377 EXPECT_TRUE(test::Shutdown());
378 }
379
380 // The sequence of messages sent is:
381 // server_mp client_mp mp0 mp1 mp2 mp3
382 // 1. "hello"
383 // 2. "world!"
384 // 3. "FOO"
385 // 4. "Bar"+mp1
386 // 5. (close)
387 // 6. (close)
388 // 7. "baz"
389 // 8. (closed)
390 // 9. "quux"+mp2
391 // 10. (close)
392 // 11. (wait/cl.)
393 // 12. (wait/cl.)
394
395 #if defined(OS_ANDROID)
396 // Android multi-process tests are not executing the new process. This is flaky.
397 #define MAYBE_MultiprocessChannels DISABLED_MultiprocessChannels
398 #else
399 #define MAYBE_MultiprocessChannels MultiprocessChannels
400 #endif // defined(OS_ANDROID)
401 TEST_F(EmbedderTest, MAYBE_MultiprocessChannels) {
402 mojo::embedder::test::InitWithSimplePlatformSupport();
403 mojo::test::MultiprocessTestHelper multiprocess_test_helper;
404 multiprocess_test_helper.StartChild("MultiprocessChannelsClient");
405
406 {
407 ScopedTestChannel server_channel(
408 test_io_thread()->task_runner(),
409 multiprocess_test_helper.server_platform_handle.Pass());
410 MojoHandle server_mp = server_channel.bootstrap_message_pipe();
411 EXPECT_NE(server_mp, MOJO_HANDLE_INVALID);
412 server_channel.WaitForChannelCreationCompletion();
413 EXPECT_TRUE(server_channel.channel_info());
414
415 // 1. Write a message to |server_mp| (attaching nothing).
416 const char kHello[] = "hello";
417 EXPECT_EQ(MOJO_RESULT_OK,
418 MojoWriteMessage(server_mp, kHello,
419 static_cast<uint32_t>(sizeof(kHello)), nullptr,
420 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
421
422 // TODO(vtl): If the scope were ended immediately here (maybe after closing
423 // |server_mp|), we die with a fatal error in |Channel::HandleLocalError()|.
424
425 // 2. Read a message from |server_mp|.
426 MojoHandleSignalsState state;
427 EXPECT_EQ(MOJO_RESULT_OK, MojoWait(server_mp, MOJO_HANDLE_SIGNAL_READABLE,
428 MOJO_DEADLINE_INDEFINITE, &state));
429 EXPECT_EQ(kSignalReadadableWritable, state.satisfied_signals);
430 EXPECT_EQ(kSignalAll, state.satisfiable_signals);
431
432 char buffer[1000] = {};
433 uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer));
434 EXPECT_EQ(MOJO_RESULT_OK,
435 MojoReadMessage(server_mp, buffer, &num_bytes, nullptr, nullptr,
436 MOJO_READ_MESSAGE_FLAG_NONE));
437 const char kWorld[] = "world!";
438 EXPECT_EQ(sizeof(kWorld), num_bytes);
439 EXPECT_STREQ(kWorld, buffer);
440
441 // Create a new message pipe (endpoints |mp0| and |mp1|).
442 MojoHandle mp0, mp1;
443 EXPECT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(nullptr, &mp0, &mp1));
444
445 // 3. Write something to |mp0|.
446 const char kFoo[] = "FOO";
447 EXPECT_EQ(MOJO_RESULT_OK,
448 MojoWriteMessage(mp0, kFoo, static_cast<uint32_t>(sizeof(kFoo)),
449 nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
450
451 // 4. Write a message to |server_mp|, attaching |mp1|.
452 const char kBar[] = "Bar";
453 EXPECT_EQ(
454 MOJO_RESULT_OK,
455 MojoWriteMessage(server_mp, kBar, static_cast<uint32_t>(sizeof(kBar)),
456 &mp1, 1, MOJO_WRITE_MESSAGE_FLAG_NONE));
457 mp1 = MOJO_HANDLE_INVALID;
458
459 // 5. Close |server_mp|.
460 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(server_mp));
461
462 // 9. Read a message from |mp0|, which should have |mp2| attached.
463 EXPECT_EQ(MOJO_RESULT_OK, MojoWait(mp0, MOJO_HANDLE_SIGNAL_READABLE,
464 MOJO_DEADLINE_INDEFINITE, &state));
465 EXPECT_EQ(kSignalReadadableWritable, state.satisfied_signals);
466 EXPECT_EQ(kSignalAll, state.satisfiable_signals);
467
468 memset(buffer, 0, sizeof(buffer));
469 num_bytes = static_cast<uint32_t>(sizeof(buffer));
470 MojoHandle mp2 = MOJO_HANDLE_INVALID;
471 uint32_t num_handles = 1;
472 EXPECT_EQ(MOJO_RESULT_OK,
473 MojoReadMessage(mp0, buffer, &num_bytes, &mp2, &num_handles,
474 MOJO_READ_MESSAGE_FLAG_NONE));
475 const char kQuux[] = "quux";
476 EXPECT_EQ(sizeof(kQuux), num_bytes);
477 EXPECT_STREQ(kQuux, buffer);
478 EXPECT_EQ(1u, num_handles);
479 EXPECT_NE(mp2, MOJO_HANDLE_INVALID);
480
481 // 7. Read a message from |mp2|.
482 EXPECT_EQ(MOJO_RESULT_OK, MojoWait(mp2, MOJO_HANDLE_SIGNAL_READABLE,
483 MOJO_DEADLINE_INDEFINITE, &state));
484 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
485 state.satisfied_signals);
486 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
487 state.satisfiable_signals);
488
489 memset(buffer, 0, sizeof(buffer));
490 num_bytes = static_cast<uint32_t>(sizeof(buffer));
491 EXPECT_EQ(MOJO_RESULT_OK,
492 MojoReadMessage(mp2, buffer, &num_bytes, nullptr, nullptr,
493 MOJO_READ_MESSAGE_FLAG_NONE));
494 const char kBaz[] = "baz";
495 EXPECT_EQ(sizeof(kBaz), num_bytes);
496 EXPECT_STREQ(kBaz, buffer);
497
498 // 10. Close |mp0|.
499 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(mp0));
500
501 // 12. Wait on |mp2| (which should eventually fail) and then close it.
502 // TODO(vtl): crbug.com/351768
503 #if 0
504 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
505 MojoWait(mp2, MOJO_HANDLE_SIGNAL_READABLE,
506 MOJO_DEADLINE_INDEFINITE,
507 &state));
508 EXPECT_EQ(MOJO_HANDLE_SIGNAL_NONE, state.satisfied_signals);
509 EXPECT_EQ(MOJO_HANDLE_SIGNAL_NONE, state.satisfiable_signals);
510 #endif
511 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(mp2));
512 }
513
514 EXPECT_TRUE(multiprocess_test_helper.WaitForChildTestShutdown());
515 EXPECT_TRUE(test::Shutdown());
516 }
517
518 MOJO_MULTIPROCESS_TEST_CHILD_TEST(MultiprocessChannelsClient) {
519 ScopedPlatformHandle client_platform_handle =
520 mojo::test::MultiprocessTestHelper::client_platform_handle.Pass();
521 EXPECT_TRUE(client_platform_handle.is_valid());
522
523 base::TestIOThread test_io_thread(base::TestIOThread::kAutoStart);
524 mojo::embedder::test::InitWithSimplePlatformSupport();
525
526 {
527 ScopedTestChannel client_channel(test_io_thread.task_runner(),
528 client_platform_handle.Pass());
529 MojoHandle client_mp = client_channel.bootstrap_message_pipe();
530 EXPECT_NE(client_mp, MOJO_HANDLE_INVALID);
531 client_channel.WaitForChannelCreationCompletion();
532 CHECK(client_channel.channel_info() != nullptr);
533
534 // 1. Read the first message from |client_mp|.
535 MojoHandleSignalsState state;
536 EXPECT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE,
537 MOJO_DEADLINE_INDEFINITE, &state));
538 EXPECT_EQ(kSignalReadadableWritable, state.satisfied_signals);
539 EXPECT_EQ(kSignalAll, state.satisfiable_signals);
540
541 char buffer[1000] = {};
542 uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer));
543 EXPECT_EQ(MOJO_RESULT_OK,
544 MojoReadMessage(client_mp, buffer, &num_bytes, nullptr, nullptr,
545 MOJO_READ_MESSAGE_FLAG_NONE));
546 const char kHello[] = "hello";
547 EXPECT_EQ(sizeof(kHello), num_bytes);
548 EXPECT_STREQ(kHello, buffer);
549
550 // 2. Write a message to |client_mp| (attaching nothing).
551 const char kWorld[] = "world!";
552 EXPECT_EQ(MOJO_RESULT_OK,
553 MojoWriteMessage(client_mp, kWorld,
554 static_cast<uint32_t>(sizeof(kWorld)), nullptr,
555 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
556
557 // 4. Read a message from |client_mp|, which should have |mp1| attached.
558 EXPECT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE,
559 MOJO_DEADLINE_INDEFINITE, &state));
560 // The other end of the handle may or may not be closed at this point, so we
561 // can't test MOJO_HANDLE_SIGNAL_WRITABLE or MOJO_HANDLE_SIGNAL_PEER_CLOSED.
562 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE,
563 state.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE);
564 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE,
565 state.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE);
566 // TODO(vtl): If the scope were to end here (and |client_mp| closed), we'd
567 // die (again due to |Channel::HandleLocalError()|).
568 memset(buffer, 0, sizeof(buffer));
569 num_bytes = static_cast<uint32_t>(sizeof(buffer));
570 MojoHandle mp1 = MOJO_HANDLE_INVALID;
571 uint32_t num_handles = 1;
572 EXPECT_EQ(MOJO_RESULT_OK,
573 MojoReadMessage(client_mp, buffer, &num_bytes, &mp1, &num_handles,
574 MOJO_READ_MESSAGE_FLAG_NONE));
575 const char kBar[] = "Bar";
576 EXPECT_EQ(sizeof(kBar), num_bytes);
577 EXPECT_STREQ(kBar, buffer);
578 EXPECT_EQ(1u, num_handles);
579 EXPECT_NE(mp1, MOJO_HANDLE_INVALID);
580 // TODO(vtl): If the scope were to end here (and the two handles closed),
581 // we'd die due to |Channel::RunRemoteMessagePipeEndpoint()| not handling
582 // write errors (assuming the parent had closed the pipe).
583
584 // 6. Close |client_mp|.
585 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(client_mp));
586
587 // Create a new message pipe (endpoints |mp2| and |mp3|).
588 MojoHandle mp2, mp3;
589 EXPECT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(nullptr, &mp2, &mp3));
590
591 // 7. Write a message to |mp3|.
592 const char kBaz[] = "baz";
593 EXPECT_EQ(MOJO_RESULT_OK,
594 MojoWriteMessage(mp3, kBaz, static_cast<uint32_t>(sizeof(kBaz)),
595 nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
596
597 // 8. Close |mp3|.
598 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(mp3));
599
600 // 9. Write a message to |mp1|, attaching |mp2|.
601 const char kQuux[] = "quux";
602 EXPECT_EQ(MOJO_RESULT_OK,
603 MojoWriteMessage(mp1, kQuux, static_cast<uint32_t>(sizeof(kQuux)),
604 &mp2, 1, MOJO_WRITE_MESSAGE_FLAG_NONE));
605 mp2 = MOJO_HANDLE_INVALID;
606
607 // 3. Read a message from |mp1|.
608 EXPECT_EQ(MOJO_RESULT_OK, MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE,
609 MOJO_DEADLINE_INDEFINITE, &state));
610 EXPECT_EQ(kSignalReadadableWritable, state.satisfied_signals);
611 EXPECT_EQ(kSignalAll, state.satisfiable_signals);
612
613 memset(buffer, 0, sizeof(buffer));
614 num_bytes = static_cast<uint32_t>(sizeof(buffer));
615 EXPECT_EQ(MOJO_RESULT_OK,
616 MojoReadMessage(mp1, buffer, &num_bytes, nullptr, nullptr,
617 MOJO_READ_MESSAGE_FLAG_NONE));
618 const char kFoo[] = "FOO";
619 EXPECT_EQ(sizeof(kFoo), num_bytes);
620 EXPECT_STREQ(kFoo, buffer);
621
622 // 11. Wait on |mp1| (which should eventually fail) and then close it.
623 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
624 MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE,
625 MOJO_DEADLINE_INDEFINITE, &state));
626 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfied_signals);
627 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfiable_signals);
628 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(mp1));
629 }
630
631 EXPECT_TRUE(test::Shutdown());
632 }
633
634 // TODO(vtl): Test immediate write & close.
635 // TODO(vtl): Test broken-connection cases.
636
637 } // namespace
638 } // namespace embedder
639 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/embedder/embedder_internal.h ('k') | mojo/edk/embedder/entrypoints.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698