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

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

Issue 1532183002: EDK: Split embedder.* into embedder.* and multiprocess_embedder.*. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years 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/multiprocess_embedder.cc ('k') | mojo/edk/test/scoped_ipc_support.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/multiprocess_embedder.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include <memory> 9 #include <memory>
10 10
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "mojo/edk/embedder/platform_channel_pair.h" 12 #include "mojo/edk/embedder/platform_channel_pair.h"
13 #include "mojo/edk/embedder/test_embedder.h" 13 #include "mojo/edk/embedder/test_embedder.h"
14 #include "mojo/edk/system/test/test_command_line.h" 14 #include "mojo/edk/system/test/test_command_line.h"
15 #include "mojo/edk/system/test/test_io_thread.h" 15 #include "mojo/edk/system/test/test_io_thread.h"
16 #include "mojo/edk/system/test/timeouts.h" 16 #include "mojo/edk/system/test/timeouts.h"
17 #include "mojo/edk/test/multiprocess_test_helper.h" 17 #include "mojo/edk/test/multiprocess_test_helper.h"
18 #include "mojo/edk/test/scoped_ipc_support.h" 18 #include "mojo/edk/test/scoped_ipc_support.h"
19 #include "mojo/edk/util/command_line.h" 19 #include "mojo/edk/util/command_line.h"
20 #include "mojo/edk/util/mutex.h"
21 #include "mojo/edk/util/ref_ptr.h" 20 #include "mojo/edk/util/ref_ptr.h"
22 #include "mojo/edk/util/thread_annotations.h"
23 #include "mojo/edk/util/waitable_event.h" 21 #include "mojo/edk/util/waitable_event.h"
24 #include "mojo/public/c/system/core.h" 22 #include "mojo/public/c/system/functions.h"
23 #include "mojo/public/c/system/types.h"
25 #include "mojo/public/cpp/system/handle.h" 24 #include "mojo/public/cpp/system/handle.h"
26 #include "mojo/public/cpp/system/macros.h" 25 #include "mojo/public/cpp/system/macros.h"
27 #include "mojo/public/cpp/system/message_pipe.h" 26 #include "mojo/public/cpp/system/message_pipe.h"
28 #include "testing/gtest/include/gtest/gtest.h" 27 #include "testing/gtest/include/gtest/gtest.h"
29 28
30 using mojo::platform::PlatformHandleWatcher; 29 using mojo::platform::PlatformHandleWatcher;
31 using mojo::platform::ScopedPlatformHandle; 30 using mojo::platform::ScopedPlatformHandle;
32 using mojo::platform::TaskRunner; 31 using mojo::platform::TaskRunner;
33 using mojo::system::test::TestIOThread; 32 using mojo::system::test::TestIOThread;
34 using mojo::util::ManualResetWaitableEvent; 33 using mojo::util::ManualResetWaitableEvent;
35 using mojo::util::Mutex;
36 using mojo::util::MutexLocker;
37 using mojo::util::RefPtr; 34 using mojo::util::RefPtr;
38 35
39 namespace mojo { 36 namespace mojo {
40 namespace embedder { 37 namespace embedder {
41 namespace { 38 namespace {
42 39
43 const MojoHandleSignals kSignalReadadableWritable = 40 const MojoHandleSignals kSignalReadadableWritable =
44 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE; 41 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE;
45 42
46 const MojoHandleSignals kSignalAll = MOJO_HANDLE_SIGNAL_READABLE | 43 const MojoHandleSignals kSignalAll = MOJO_HANDLE_SIGNAL_READABLE |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 112
116 // Valid after channel creation completion until destruction. 113 // Valid after channel creation completion until destruction.
117 ChannelInfo* channel_info_; 114 ChannelInfo* channel_info_;
118 115
119 // Whether the destructor should wait until the channel is destroyed. 116 // Whether the destructor should wait until the channel is destroyed.
120 bool wait_on_shutdown_; 117 bool wait_on_shutdown_;
121 118
122 MOJO_DISALLOW_COPY_AND_ASSIGN(ScopedTestChannel); 119 MOJO_DISALLOW_COPY_AND_ASSIGN(ScopedTestChannel);
123 }; 120 };
124 121
125 class EmbedderTest : public testing::Test { 122 class MultiprocessEmbedderTest : public testing::Test {
126 public: 123 public:
127 EmbedderTest() : test_io_thread_(TestIOThread::StartMode::AUTO) {} 124 MultiprocessEmbedderTest() : test_io_thread_(TestIOThread::StartMode::AUTO) {}
128 ~EmbedderTest() override {} 125 ~MultiprocessEmbedderTest() override {}
129 126
130 protected: 127 protected:
131 TestIOThread& test_io_thread() { return test_io_thread_; } 128 TestIOThread& test_io_thread() { return test_io_thread_; }
132 const RefPtr<TaskRunner>& test_io_task_runner() { 129 const RefPtr<TaskRunner>& test_io_task_runner() {
133 return test_io_thread_.task_runner(); 130 return test_io_thread_.task_runner();
134 } 131 }
135 PlatformHandleWatcher* test_io_watcher() { 132 PlatformHandleWatcher* test_io_watcher() {
136 return test_io_thread_.platform_handle_watcher(); 133 return test_io_thread_.platform_handle_watcher();
137 } 134 }
138 135
139 private: 136 private:
140 void SetUp() override { test::InitWithSimplePlatformSupport(); } 137 void SetUp() override { test::InitWithSimplePlatformSupport(); }
141 138
142 void TearDown() override { EXPECT_TRUE(test::Shutdown()); } 139 void TearDown() override { EXPECT_TRUE(test::Shutdown()); }
143 140
144 TestIOThread test_io_thread_; 141 TestIOThread test_io_thread_;
145 142
146 MOJO_DISALLOW_COPY_AND_ASSIGN(EmbedderTest); 143 MOJO_DISALLOW_COPY_AND_ASSIGN(MultiprocessEmbedderTest);
147 }; 144 };
148 145
149 TEST_F(EmbedderTest, ChannelsBasic) { 146 TEST_F(MultiprocessEmbedderTest, ChannelsBasic) {
150 mojo::test::ScopedIPCSupport ipc_support(test_io_task_runner().Clone(), 147 mojo::test::ScopedIPCSupport ipc_support(test_io_task_runner().Clone(),
151 test_io_watcher()); 148 test_io_watcher());
152 149
153 PlatformChannelPair channel_pair; 150 PlatformChannelPair channel_pair;
154 ScopedTestChannel server_channel(channel_pair.PassServerHandle()); 151 ScopedTestChannel server_channel(channel_pair.PassServerHandle());
155 MojoHandle server_mp = server_channel.bootstrap_message_pipe(); 152 MojoHandle server_mp = server_channel.bootstrap_message_pipe();
156 EXPECT_NE(server_mp, MOJO_HANDLE_INVALID); 153 EXPECT_NE(server_mp, MOJO_HANDLE_INVALID);
157 ScopedTestChannel client_channel(channel_pair.PassClientHandle()); 154 ScopedTestChannel client_channel(channel_pair.PassClientHandle());
158 MojoHandle client_mp = client_channel.bootstrap_message_pipe(); 155 MojoHandle client_mp = client_channel.bootstrap_message_pipe();
159 EXPECT_NE(client_mp, MOJO_HANDLE_INVALID); 156 EXPECT_NE(client_mp, MOJO_HANDLE_INVALID);
(...skipping 25 matching lines...) Expand all
185 182
186 // By this point, these waits should basically be no-ops (since we've waited 183 // By this point, these waits should basically be no-ops (since we've waited
187 // for the client message pipe to become readable, which implies that both 184 // for the client message pipe to become readable, which implies that both
188 // the server and client channels were completely created). 185 // the server and client channels were completely created).
189 server_channel.WaitForChannelCreationCompletion(); 186 server_channel.WaitForChannelCreationCompletion();
190 client_channel.WaitForChannelCreationCompletion(); 187 client_channel.WaitForChannelCreationCompletion();
191 EXPECT_TRUE(server_channel.channel_info()); 188 EXPECT_TRUE(server_channel.channel_info());
192 EXPECT_TRUE(client_channel.channel_info()); 189 EXPECT_TRUE(client_channel.channel_info());
193 } 190 }
194 191
195 class TestAsyncWaiter { 192 TEST_F(MultiprocessEmbedderTest, ChannelsHandlePassing) {
196 public:
197 TestAsyncWaiter() : wait_result_(MOJO_RESULT_UNKNOWN) {}
198
199 void Awake(MojoResult result) {
200 MutexLocker l(&wait_result_mutex_);
201 wait_result_ = result;
202 event_.Signal();
203 }
204
205 bool TryWait() {
206 return !event_.WaitWithTimeout(mojo::system::test::ActionTimeout());
207 }
208
209 MojoResult wait_result() const {
210 MutexLocker l(&wait_result_mutex_);
211 return wait_result_;
212 }
213
214 private:
215 ManualResetWaitableEvent event_;
216
217 mutable Mutex wait_result_mutex_;
218 MojoResult wait_result_ MOJO_GUARDED_BY(wait_result_mutex_);
219
220 MOJO_DISALLOW_COPY_AND_ASSIGN(TestAsyncWaiter);
221 };
222
223 TEST_F(EmbedderTest, AsyncWait) {
224 ScopedMessagePipeHandle client_mp;
225 ScopedMessagePipeHandle server_mp;
226 EXPECT_EQ(MOJO_RESULT_OK, CreateMessagePipe(nullptr, &client_mp, &server_mp));
227
228 TestAsyncWaiter waiter;
229 EXPECT_EQ(MOJO_RESULT_OK,
230 AsyncWait(client_mp.get().value(), MOJO_HANDLE_SIGNAL_READABLE,
231 [&waiter](MojoResult result) { waiter.Awake(result); }));
232
233 // TODO(vtl): With C++14 lambda captures, we'll be able to avoid this
234 // nonsense.
235 {
236 auto server_mp_value = server_mp.get();
237 test_io_thread().PostTask([server_mp_value]() {
238 static const char kHello[] = "hello";
239 CHECK_EQ(MOJO_RESULT_OK,
240 WriteMessageRaw(server_mp_value, kHello,
241 static_cast<uint32_t>(sizeof(kHello)), nullptr,
242 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
243 });
244 }
245 EXPECT_TRUE(waiter.TryWait());
246 EXPECT_EQ(MOJO_RESULT_OK, waiter.wait_result());
247
248 // If message is in the queue, it does't allow us to wait.
249 TestAsyncWaiter waiter_that_doesnt_wait;
250 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
251 AsyncWait(client_mp.get().value(), MOJO_HANDLE_SIGNAL_READABLE,
252 [&waiter_that_doesnt_wait](MojoResult result) {
253 waiter_that_doesnt_wait.Awake(result);
254 }));
255
256 char buffer[1000];
257 uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer));
258 CHECK_EQ(MOJO_RESULT_OK,
259 ReadMessageRaw(client_mp.get(), buffer, &num_bytes, nullptr, nullptr,
260 MOJO_READ_MESSAGE_FLAG_NONE));
261
262 TestAsyncWaiter unsatisfiable_waiter;
263 EXPECT_EQ(MOJO_RESULT_OK,
264 AsyncWait(client_mp.get().value(), MOJO_HANDLE_SIGNAL_READABLE,
265 [&unsatisfiable_waiter](MojoResult result) {
266 unsatisfiable_waiter.Awake(result);
267 }));
268
269 // TODO(vtl): With C++14 lambda captures, we'll be able to avoid this
270 // nonsense (and use |Close()| rather than |CloseRaw()|).
271 {
272 auto server_mp_value = server_mp.release();
273 test_io_thread().PostTask(
274 [server_mp_value]() { CloseRaw(server_mp_value); });
275 }
276
277 EXPECT_TRUE(unsatisfiable_waiter.TryWait());
278 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
279 unsatisfiable_waiter.wait_result());
280 }
281
282 TEST_F(EmbedderTest, ChannelsHandlePassing) {
283 mojo::test::ScopedIPCSupport ipc_support(test_io_task_runner().Clone(), 193 mojo::test::ScopedIPCSupport ipc_support(test_io_task_runner().Clone(),
284 test_io_watcher()); 194 test_io_watcher());
285 195
286 PlatformChannelPair channel_pair; 196 PlatformChannelPair channel_pair;
287 ScopedTestChannel server_channel(channel_pair.PassServerHandle()); 197 ScopedTestChannel server_channel(channel_pair.PassServerHandle());
288 MojoHandle server_mp = server_channel.bootstrap_message_pipe(); 198 MojoHandle server_mp = server_channel.bootstrap_message_pipe();
289 EXPECT_NE(server_mp, MOJO_HANDLE_INVALID); 199 EXPECT_NE(server_mp, MOJO_HANDLE_INVALID);
290 ScopedTestChannel client_channel(channel_pair.PassClientHandle()); 200 ScopedTestChannel client_channel(channel_pair.PassClientHandle());
291 MojoHandle client_mp = client_channel.bootstrap_message_pipe(); 201 MojoHandle client_mp = client_channel.bootstrap_message_pipe();
292 EXPECT_NE(client_mp, MOJO_HANDLE_INVALID); 202 EXPECT_NE(client_mp, MOJO_HANDLE_INVALID);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 EXPECT_TRUE(client_channel.channel_info()); 311 EXPECT_TRUE(client_channel.channel_info());
402 } 312 }
403 313
404 #if defined(OS_ANDROID) 314 #if defined(OS_ANDROID)
405 // Android multi-process tests are not executing the new process. This is flaky. 315 // Android multi-process tests are not executing the new process. This is flaky.
406 // TODO(vtl): I'm guessing this is true of this test too? 316 // TODO(vtl): I'm guessing this is true of this test too?
407 #define MAYBE_MultiprocessMasterSlave DISABLED_MultiprocessMasterSlave 317 #define MAYBE_MultiprocessMasterSlave DISABLED_MultiprocessMasterSlave
408 #else 318 #else
409 #define MAYBE_MultiprocessMasterSlave MultiprocessMasterSlave 319 #define MAYBE_MultiprocessMasterSlave MultiprocessMasterSlave
410 #endif // defined(OS_ANDROID) 320 #endif // defined(OS_ANDROID)
411 TEST_F(EmbedderTest, MAYBE_MultiprocessMasterSlave) { 321 TEST_F(MultiprocessEmbedderTest, MAYBE_MultiprocessMasterSlave) {
412 mojo::test::ScopedMasterIPCSupport ipc_support(test_io_task_runner().Clone(), 322 mojo::test::ScopedMasterIPCSupport ipc_support(test_io_task_runner().Clone(),
413 test_io_watcher()); 323 test_io_watcher());
414 324
415 mojo::test::MultiprocessTestHelper multiprocess_test_helper; 325 mojo::test::MultiprocessTestHelper multiprocess_test_helper;
416 std::string connection_id; 326 std::string connection_id;
417 ManualResetWaitableEvent event; 327 ManualResetWaitableEvent event;
418 ChannelInfo* channel_info = nullptr; 328 ChannelInfo* channel_info = nullptr;
419 ScopedMessagePipeHandle mp = ConnectToSlave( 329 ScopedMessagePipeHandle mp = ConnectToSlave(
420 nullptr, multiprocess_test_helper.server_platform_handle.Pass(), 330 nullptr, multiprocess_test_helper.server_platform_handle.Pass(),
421 [&event]() { event.Signal(); }, nullptr, &connection_id, &channel_info); 331 [&event]() { event.Signal(); }, nullptr, &connection_id, &channel_info);
(...skipping 23 matching lines...) Expand all
445 355
446 mp.reset(); 356 mp.reset();
447 357
448 EXPECT_TRUE(multiprocess_test_helper.WaitForChildTestShutdown()); 358 EXPECT_TRUE(multiprocess_test_helper.WaitForChildTestShutdown());
449 359
450 EXPECT_FALSE(event.WaitWithTimeout(mojo::system::test::ActionTimeout())); 360 EXPECT_FALSE(event.WaitWithTimeout(mojo::system::test::ActionTimeout()));
451 test_io_thread().PostTaskAndWait( 361 test_io_thread().PostTaskAndWait(
452 [channel_info]() { DestroyChannelOnIOThread(channel_info); }); 362 [channel_info]() { DestroyChannelOnIOThread(channel_info); });
453 } 363 }
454 364
455 TEST_F(EmbedderTest, ChannelShutdownRace_MessagePipeClose) { 365 TEST_F(MultiprocessEmbedderTest, ChannelShutdownRace_MessagePipeClose) {
456 const size_t kIterations = 1000; 366 const size_t kIterations = 1000;
457 mojo::test::ScopedIPCSupport ipc_support(test_io_task_runner().Clone(), 367 mojo::test::ScopedIPCSupport ipc_support(test_io_task_runner().Clone(),
458 test_io_watcher()); 368 test_io_watcher());
459 369
460 for (size_t i = 0; i < kIterations; i++) { 370 for (size_t i = 0; i < kIterations; i++) {
461 PlatformChannelPair channel_pair; 371 PlatformChannelPair channel_pair;
462 std::unique_ptr<ScopedTestChannel> server_channel( 372 std::unique_ptr<ScopedTestChannel> server_channel(
463 new ScopedTestChannel(channel_pair.PassServerHandle())); 373 new ScopedTestChannel(channel_pair.PassServerHandle()));
464 server_channel->WaitForChannelCreationCompletion(); 374 server_channel->WaitForChannelCreationCompletion();
465 server_channel->NoWaitOnShutdown(); 375 server_channel->NoWaitOnShutdown();
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 // 10. (close) 452 // 10. (close)
543 // 11. (wait/cl.) 453 // 11. (wait/cl.)
544 // 12. (wait/cl.) 454 // 12. (wait/cl.)
545 455
546 #if defined(OS_ANDROID) 456 #if defined(OS_ANDROID)
547 // Android multi-process tests are not executing the new process. This is flaky. 457 // Android multi-process tests are not executing the new process. This is flaky.
548 #define MAYBE_MultiprocessChannels DISABLED_MultiprocessChannels 458 #define MAYBE_MultiprocessChannels DISABLED_MultiprocessChannels
549 #else 459 #else
550 #define MAYBE_MultiprocessChannels MultiprocessChannels 460 #define MAYBE_MultiprocessChannels MultiprocessChannels
551 #endif // defined(OS_ANDROID) 461 #endif // defined(OS_ANDROID)
552 TEST_F(EmbedderTest, MAYBE_MultiprocessChannels) { 462 TEST_F(MultiprocessEmbedderTest, MAYBE_MultiprocessChannels) {
553 // TODO(vtl): This should eventually initialize a master process instead, 463 // TODO(vtl): This should eventually initialize a master process instead,
554 // probably. 464 // probably.
555 mojo::test::ScopedIPCSupport ipc_support(test_io_task_runner().Clone(), 465 mojo::test::ScopedIPCSupport ipc_support(test_io_task_runner().Clone(),
556 test_io_watcher()); 466 test_io_watcher());
557 467
558 mojo::test::MultiprocessTestHelper multiprocess_test_helper; 468 mojo::test::MultiprocessTestHelper multiprocess_test_helper;
559 multiprocess_test_helper.StartChild("MultiprocessChannelsClient"); 469 multiprocess_test_helper.StartChild("MultiprocessChannelsClient");
560 470
561 { 471 {
562 ScopedTestChannel server_channel( 472 ScopedTestChannel server_channel(
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
788 698
789 EXPECT_TRUE(test::Shutdown()); 699 EXPECT_TRUE(test::Shutdown());
790 } 700 }
791 701
792 // TODO(vtl): Test immediate write & close. 702 // TODO(vtl): Test immediate write & close.
793 // TODO(vtl): Test broken-connection cases. 703 // TODO(vtl): Test broken-connection cases.
794 704
795 } // namespace 705 } // namespace
796 } // namespace embedder 706 } // namespace embedder
797 } // namespace mojo 707 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/embedder/multiprocess_embedder.cc ('k') | mojo/edk/test/scoped_ipc_support.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698