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

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

Issue 728783003: Add infrastructure to run tests on android. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Use file_hash Created 6 years, 1 month 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 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 "mojo/edk/embedder/embedder.h" 5 #include "mojo/edk/embedder/embedder.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include "base/bind.h" 9 #include "mojo/edk/embedder/embedder_test_util.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 "mojo/edk/embedder/platform_channel_pair.h" 10 #include "mojo/edk/embedder/platform_channel_pair.h"
17 #include "mojo/edk/embedder/test_embedder.h" 11 #include "mojo/edk/embedder/test_embedder.h"
18 #include "mojo/edk/system/test_utils.h"
19 #include "mojo/edk/test/multiprocess_test_helper.h"
20 #include "mojo/public/c/system/core.h" 12 #include "mojo/public/c/system/core.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 13
23 namespace mojo { 14 namespace mojo {
24 namespace embedder { 15 namespace embedder {
25 namespace { 16 namespace {
26 17
27 class ScopedTestChannel {
28 public:
29 // Creates a channel that lives on a given I/O thread (determined by the given
30 // |TaskRunner|) attached to the given |platform_handle|. After construction,
31 // |bootstrap_message_pipe()| gives the Mojo handle for the bootstrap message
32 // pipe on this channel; it is up to the caller to close this handle.
33 // Note: The I/O thread must outlive this object (and its message loop must
34 // continue pumping messages while this object is alive).
35 ScopedTestChannel(scoped_refptr<base::TaskRunner> io_thread_task_runner,
36 ScopedPlatformHandle platform_handle)
37 : io_thread_task_runner_(io_thread_task_runner),
38 bootstrap_message_pipe_(MOJO_HANDLE_INVALID),
39 did_create_channel_event_(true, false),
40 channel_info_(nullptr) {
41 bootstrap_message_pipe_ =
42 CreateChannel(platform_handle.Pass(), io_thread_task_runner_,
43 base::Bind(&ScopedTestChannel::DidCreateChannel,
44 base::Unretained(this)),
45 nullptr)
46 .release()
47 .value();
48 CHECK_NE(bootstrap_message_pipe_, MOJO_HANDLE_INVALID);
49 }
50
51 // Destructor: Shuts down the channel. (As noted above, for this to happen,
52 // the I/O thread must be alive and pumping messages.)
53 ~ScopedTestChannel() { DestroyChannel(channel_info_); }
54
55 // Waits for channel creation to be completed.
56 void WaitForChannelCreationCompletion() { did_create_channel_event_.Wait(); }
57
58 MojoHandle bootstrap_message_pipe() const { return bootstrap_message_pipe_; }
59
60 // Call only after |WaitForChannelCreationCompletion()|. Use only to check
61 // that it's not null.
62 const ChannelInfo* channel_info() const { return channel_info_; }
63
64 private:
65 void DidCreateChannel(ChannelInfo* channel_info) {
66 CHECK(channel_info);
67 CHECK(!channel_info_);
68 channel_info_ = channel_info;
69 did_create_channel_event_.Signal();
70 }
71
72 scoped_refptr<base::TaskRunner> io_thread_task_runner_;
73
74 // Valid from creation until whenever it gets closed (by the "owner" of this
75 // object).
76 // Note: We don't want use the C++ wrappers here, since we want to test the
77 // API at the lowest level.
78 MojoHandle bootstrap_message_pipe_;
79
80 // Set after channel creation has been completed (i.e., the callback to
81 // |CreateChannel()| has been called).
82 base::WaitableEvent did_create_channel_event_;
83
84 // Valid after channel creation completion until destruction.
85 ChannelInfo* channel_info_;
86
87 DISALLOW_COPY_AND_ASSIGN(ScopedTestChannel);
88 };
89
90 class EmbedderTest : public testing::Test {
91 public:
92 EmbedderTest() : test_io_thread_(base::TestIOThread::kAutoStart) {}
93 ~EmbedderTest() override {}
94
95 protected:
96 base::TestIOThread* test_io_thread() { return &test_io_thread_; }
97
98 private:
99 base::TestIOThread test_io_thread_;
100
101 DISALLOW_COPY_AND_ASSIGN(EmbedderTest);
102 };
103
104 TEST_F(EmbedderTest, ChannelsBasic) { 18 TEST_F(EmbedderTest, ChannelsBasic) {
105 mojo::embedder::test::InitWithSimplePlatformSupport(); 19 mojo::embedder::test::InitWithSimplePlatformSupport();
106 20
107 { 21 {
108 PlatformChannelPair channel_pair; 22 PlatformChannelPair channel_pair;
109 ScopedTestChannel server_channel(test_io_thread()->task_runner(), 23 ScopedTestChannel server_channel(test_io_thread()->task_runner(),
110 channel_pair.PassServerHandle()); 24 channel_pair.PassServerHandle());
111 MojoHandle server_mp = server_channel.bootstrap_message_pipe(); 25 MojoHandle server_mp = server_channel.bootstrap_message_pipe();
112 EXPECT_NE(server_mp, MOJO_HANDLE_INVALID); 26 EXPECT_NE(server_mp, MOJO_HANDLE_INVALID);
113 ScopedTestChannel client_channel(test_io_thread()->task_runner(), 27 ScopedTestChannel client_channel(test_io_thread()->task_runner(),
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 175
262 server_channel.WaitForChannelCreationCompletion(); 176 server_channel.WaitForChannelCreationCompletion();
263 client_channel.WaitForChannelCreationCompletion(); 177 client_channel.WaitForChannelCreationCompletion();
264 EXPECT_TRUE(server_channel.channel_info()); 178 EXPECT_TRUE(server_channel.channel_info());
265 EXPECT_TRUE(client_channel.channel_info()); 179 EXPECT_TRUE(client_channel.channel_info());
266 } 180 }
267 181
268 EXPECT_TRUE(test::Shutdown()); 182 EXPECT_TRUE(test::Shutdown());
269 } 183 }
270 184
271 // The sequence of messages sent is:
272 // server_mp client_mp mp0 mp1 mp2 mp3
273 // 1. "hello"
274 // 2. "world!"
275 // 3. "FOO"
276 // 4. "Bar"+mp1
277 // 5. (close)
278 // 6. (close)
279 // 7. "baz"
280 // 8. (closed)
281 // 9. "quux"+mp2
282 // 10. (close)
283 // 11. (wait/cl.)
284 // 12. (wait/cl.)
285 TEST_F(EmbedderTest, MultiprocessChannels) {
286 mojo::embedder::test::InitWithSimplePlatformSupport();
287 mojo::test::MultiprocessTestHelper multiprocess_test_helper;
288 multiprocess_test_helper.StartChild("MultiprocessChannelsClient");
289
290 {
291 ScopedTestChannel server_channel(
292 test_io_thread()->task_runner(),
293 multiprocess_test_helper.server_platform_handle.Pass());
294 MojoHandle server_mp = server_channel.bootstrap_message_pipe();
295 EXPECT_NE(server_mp, MOJO_HANDLE_INVALID);
296 server_channel.WaitForChannelCreationCompletion();
297 EXPECT_TRUE(server_channel.channel_info());
298
299 // 1. Write a message to |server_mp| (attaching nothing).
300 const char kHello[] = "hello";
301 EXPECT_EQ(MOJO_RESULT_OK,
302 MojoWriteMessage(server_mp, kHello,
303 static_cast<uint32_t>(sizeof(kHello)), nullptr,
304 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
305
306 // TODO(vtl): If the scope were ended immediately here (maybe after closing
307 // |server_mp|), we die with a fatal error in |Channel::HandleLocalError()|.
308
309 // 2. Read a message from |server_mp|.
310 EXPECT_EQ(MOJO_RESULT_OK, MojoWait(server_mp, MOJO_HANDLE_SIGNAL_READABLE,
311 MOJO_DEADLINE_INDEFINITE));
312 char buffer[1000] = {};
313 uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer));
314 EXPECT_EQ(MOJO_RESULT_OK,
315 MojoReadMessage(server_mp, buffer, &num_bytes, nullptr, nullptr,
316 MOJO_READ_MESSAGE_FLAG_NONE));
317 const char kWorld[] = "world!";
318 EXPECT_EQ(sizeof(kWorld), num_bytes);
319 EXPECT_STREQ(kWorld, buffer);
320
321 // Create a new message pipe (endpoints |mp0| and |mp1|).
322 MojoHandle mp0, mp1;
323 EXPECT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(nullptr, &mp0, &mp1));
324
325 // 3. Write something to |mp0|.
326 const char kFoo[] = "FOO";
327 EXPECT_EQ(MOJO_RESULT_OK,
328 MojoWriteMessage(mp0, kFoo, static_cast<uint32_t>(sizeof(kFoo)),
329 nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
330
331 // 4. Write a message to |server_mp|, attaching |mp1|.
332 const char kBar[] = "Bar";
333 EXPECT_EQ(
334 MOJO_RESULT_OK,
335 MojoWriteMessage(server_mp, kBar, static_cast<uint32_t>(sizeof(kBar)),
336 &mp1, 1, MOJO_WRITE_MESSAGE_FLAG_NONE));
337 mp1 = MOJO_HANDLE_INVALID;
338
339 // 5. Close |server_mp|.
340 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(server_mp));
341
342 // 9. Read a message from |mp0|, which should have |mp2| attached.
343 EXPECT_EQ(MOJO_RESULT_OK, MojoWait(mp0, MOJO_HANDLE_SIGNAL_READABLE,
344 MOJO_DEADLINE_INDEFINITE));
345 memset(buffer, 0, sizeof(buffer));
346 num_bytes = static_cast<uint32_t>(sizeof(buffer));
347 MojoHandle mp2 = MOJO_HANDLE_INVALID;
348 uint32_t num_handles = 1;
349 EXPECT_EQ(MOJO_RESULT_OK,
350 MojoReadMessage(mp0, buffer, &num_bytes, &mp2, &num_handles,
351 MOJO_READ_MESSAGE_FLAG_NONE));
352 const char kQuux[] = "quux";
353 EXPECT_EQ(sizeof(kQuux), num_bytes);
354 EXPECT_STREQ(kQuux, buffer);
355 EXPECT_EQ(1u, num_handles);
356 EXPECT_NE(mp2, MOJO_HANDLE_INVALID);
357
358 // 7. Read a message from |mp2|.
359 EXPECT_EQ(MOJO_RESULT_OK, MojoWait(mp2, MOJO_HANDLE_SIGNAL_READABLE,
360 MOJO_DEADLINE_INDEFINITE));
361 memset(buffer, 0, sizeof(buffer));
362 num_bytes = static_cast<uint32_t>(sizeof(buffer));
363 EXPECT_EQ(MOJO_RESULT_OK,
364 MojoReadMessage(mp2, buffer, &num_bytes, nullptr, nullptr,
365 MOJO_READ_MESSAGE_FLAG_NONE));
366 const char kBaz[] = "baz";
367 EXPECT_EQ(sizeof(kBaz), num_bytes);
368 EXPECT_STREQ(kBaz, buffer);
369
370 // 10. Close |mp0|.
371 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(mp0));
372
373 // 12. Wait on |mp2| (which should eventually fail) and then close it.
374 // TODO(vtl): crbug.com/351768
375 #if 0
376 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
377 MojoWait(mp2, MOJO_HANDLE_SIGNAL_READABLE,
378 MOJO_DEADLINE_INDEFINITE));
379 #endif
380 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(mp2));
381 }
382
383 EXPECT_TRUE(multiprocess_test_helper.WaitForChildTestShutdown());
384 EXPECT_TRUE(test::Shutdown());
385 }
386
387 MOJO_MULTIPROCESS_TEST_CHILD_TEST(MultiprocessChannelsClient) {
388 ScopedPlatformHandle client_platform_handle =
389 mojo::test::MultiprocessTestHelper::client_platform_handle.Pass();
390 EXPECT_TRUE(client_platform_handle.is_valid());
391
392 base::TestIOThread test_io_thread(base::TestIOThread::kAutoStart);
393 mojo::embedder::test::InitWithSimplePlatformSupport();
394
395 {
396 ScopedTestChannel client_channel(test_io_thread.task_runner(),
397 client_platform_handle.Pass());
398 MojoHandle client_mp = client_channel.bootstrap_message_pipe();
399 EXPECT_NE(client_mp, MOJO_HANDLE_INVALID);
400 client_channel.WaitForChannelCreationCompletion();
401 CHECK(client_channel.channel_info() != nullptr);
402
403 // 1. Read the first message from |client_mp|.
404 EXPECT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE,
405 MOJO_DEADLINE_INDEFINITE));
406 char buffer[1000] = {};
407 uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer));
408 EXPECT_EQ(MOJO_RESULT_OK,
409 MojoReadMessage(client_mp, buffer, &num_bytes, nullptr, nullptr,
410 MOJO_READ_MESSAGE_FLAG_NONE));
411 const char kHello[] = "hello";
412 EXPECT_EQ(sizeof(kHello), num_bytes);
413 EXPECT_STREQ(kHello, buffer);
414
415 // 2. Write a message to |client_mp| (attaching nothing).
416 const char kWorld[] = "world!";
417 EXPECT_EQ(MOJO_RESULT_OK,
418 MojoWriteMessage(client_mp, kWorld,
419 static_cast<uint32_t>(sizeof(kWorld)), nullptr,
420 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
421
422 // 4. Read a message from |client_mp|, which should have |mp1| attached.
423 EXPECT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE,
424 MOJO_DEADLINE_INDEFINITE));
425 // TODO(vtl): If the scope were to end here (and |client_mp| closed), we'd
426 // die (again due to |Channel::HandleLocalError()|).
427 memset(buffer, 0, sizeof(buffer));
428 num_bytes = static_cast<uint32_t>(sizeof(buffer));
429 MojoHandle mp1 = MOJO_HANDLE_INVALID;
430 uint32_t num_handles = 1;
431 EXPECT_EQ(MOJO_RESULT_OK,
432 MojoReadMessage(client_mp, buffer, &num_bytes, &mp1, &num_handles,
433 MOJO_READ_MESSAGE_FLAG_NONE));
434 const char kBar[] = "Bar";
435 EXPECT_EQ(sizeof(kBar), num_bytes);
436 EXPECT_STREQ(kBar, buffer);
437 EXPECT_EQ(1u, num_handles);
438 EXPECT_NE(mp1, MOJO_HANDLE_INVALID);
439 // TODO(vtl): If the scope were to end here (and the two handles closed),
440 // we'd die due to |Channel::RunRemoteMessagePipeEndpoint()| not handling
441 // write errors (assuming the parent had closed the pipe).
442
443 // 6. Close |client_mp|.
444 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(client_mp));
445
446 // Create a new message pipe (endpoints |mp2| and |mp3|).
447 MojoHandle mp2, mp3;
448 EXPECT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(nullptr, &mp2, &mp3));
449
450 // 7. Write a message to |mp3|.
451 const char kBaz[] = "baz";
452 EXPECT_EQ(MOJO_RESULT_OK,
453 MojoWriteMessage(mp3, kBaz, static_cast<uint32_t>(sizeof(kBaz)),
454 nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
455
456 // 8. Close |mp3|.
457 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(mp3));
458
459 // 9. Write a message to |mp1|, attaching |mp2|.
460 const char kQuux[] = "quux";
461 EXPECT_EQ(MOJO_RESULT_OK,
462 MojoWriteMessage(mp1, kQuux, static_cast<uint32_t>(sizeof(kQuux)),
463 &mp2, 1, MOJO_WRITE_MESSAGE_FLAG_NONE));
464 mp2 = MOJO_HANDLE_INVALID;
465
466 // 3. Read a message from |mp1|.
467 EXPECT_EQ(MOJO_RESULT_OK, MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE,
468 MOJO_DEADLINE_INDEFINITE));
469 memset(buffer, 0, sizeof(buffer));
470 num_bytes = static_cast<uint32_t>(sizeof(buffer));
471 EXPECT_EQ(MOJO_RESULT_OK,
472 MojoReadMessage(mp1, buffer, &num_bytes, nullptr, nullptr,
473 MOJO_READ_MESSAGE_FLAG_NONE));
474 const char kFoo[] = "FOO";
475 EXPECT_EQ(sizeof(kFoo), num_bytes);
476 EXPECT_STREQ(kFoo, buffer);
477
478 // 11. Wait on |mp1| (which should eventually fail) and then close it.
479 EXPECT_EQ(
480 MOJO_RESULT_FAILED_PRECONDITION,
481 MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
482 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(mp1));
483 }
484
485 EXPECT_TRUE(test::Shutdown());
486 }
487
488 // TODO(vtl): Test immediate write & close. 185 // TODO(vtl): Test immediate write & close.
489 // TODO(vtl): Test broken-connection cases. 186 // TODO(vtl): Test broken-connection cases.
490 187
491 } // namespace 188 } // namespace
492 } // namespace embedder 189 } // namespace embedder
493 } // namespace mojo 190 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698