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

Side by Side Diff: third_party/mojo/src/mojo/edk/system/connection_manager_unittest.cc

Issue 1676913002: [mojo] Delete third_party/mojo (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 10 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 // This is really a unit test for |MasterConnectionManager| and
6 // |SlaveConnectionManager| (since they need to be tested together).
7
8 #include "third_party/mojo/src/mojo/edk/system/connection_manager.h"
9
10 #include <stdint.h>
11
12 #include <string>
13
14 #include "base/message_loop/message_loop.h"
15 #include "base/run_loop.h"
16 #include "base/threading/thread_checker.h"
17 #include "mojo/public/cpp/system/macros.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "third_party/mojo/src/mojo/edk/embedder/master_process_delegate.h"
20 #include "third_party/mojo/src/mojo/edk/embedder/platform_channel_pair.h"
21 #include "third_party/mojo/src/mojo/edk/embedder/simple_platform_support.h"
22 #include "third_party/mojo/src/mojo/edk/embedder/slave_process_delegate.h"
23 #include "third_party/mojo/src/mojo/edk/system/master_connection_manager.h"
24 #include "third_party/mojo/src/mojo/edk/system/slave_connection_manager.h"
25 #include "third_party/mojo/src/mojo/edk/test/test_utils.h"
26
27 namespace mojo {
28 namespace system {
29 namespace {
30
31 bool ArePlatformHandlesConnected(const embedder::PlatformHandle& h1,
32 const embedder::PlatformHandle& h2) {
33 const uint32_t w1 = 0xdeadbeef;
34 size_t num_bytes = 0;
35 if (!mojo::test::BlockingWrite(h1, &w1, sizeof(w1), &num_bytes) ||
36 num_bytes != sizeof(w1))
37 return false;
38 uint32_t r = 0;
39 num_bytes = 0;
40 if (!mojo::test::BlockingRead(h2, &r, sizeof(r), &num_bytes) ||
41 num_bytes != sizeof(r))
42 return false;
43 if (r != w1)
44 return false;
45
46 const uint32_t w2 = 0xfeedface;
47 num_bytes = 0;
48 if (!mojo::test::BlockingWrite(h1, &w2, sizeof(w2), &num_bytes) ||
49 num_bytes != sizeof(w2))
50 return false;
51 r = 0;
52 num_bytes = 0;
53 if (!mojo::test::BlockingRead(h2, &r, sizeof(r), &num_bytes) ||
54 num_bytes != sizeof(r))
55 return false;
56 if (r != w2)
57 return false;
58
59 return true;
60 }
61
62 bool IsValidSlaveProcessIdentifier(ProcessIdentifier process_identifier) {
63 return process_identifier != kInvalidProcessIdentifier &&
64 process_identifier != kMasterProcessIdentifier;
65 }
66
67 class TestSlaveInfo {
68 public:
69 explicit TestSlaveInfo(const std::string& name) : name_(name) {}
70 ~TestSlaveInfo() { CHECK(thread_checker_.CalledOnValidThread()); }
71
72 const std::string& name() const { return name_; }
73
74 private:
75 base::ThreadChecker thread_checker_;
76 std::string name_;
77
78 MOJO_DISALLOW_COPY_AND_ASSIGN(TestSlaveInfo);
79 };
80
81 // Connects the given |slave| (with the given |slave_process_delegate|) to the
82 // given master, creating and using a |TestSlaveInfo| with the given
83 // |slave_name|, and returns the process identifier for the slave.
84 ProcessIdentifier ConnectSlave(
85 MasterConnectionManager* master,
86 embedder::SlaveProcessDelegate* slave_process_delegate,
87 SlaveConnectionManager* slave,
88 const std::string& slave_name) {
89 embedder::PlatformChannelPair platform_channel_pair;
90 ProcessIdentifier slave_process_identifier = master->AddSlave(
91 new TestSlaveInfo(slave_name), platform_channel_pair.PassServerHandle());
92 slave->Init(slave_process_delegate, platform_channel_pair.PassClientHandle());
93 return slave_process_identifier;
94 }
95
96 class MockMasterProcessDelegate : public embedder::MasterProcessDelegate {
97 public:
98 MockMasterProcessDelegate()
99 : current_run_loop_(), on_slave_disconnect_calls_(0) {}
100 ~MockMasterProcessDelegate() override {}
101
102 void RunUntilNotified() {
103 CHECK(!current_run_loop_);
104 base::RunLoop run_loop;
105 current_run_loop_ = &run_loop;
106 run_loop.Run();
107 current_run_loop_ = nullptr;
108 }
109
110 unsigned on_slave_disconnect_calls() const {
111 return on_slave_disconnect_calls_;
112 }
113 const std::string& last_slave_disconnect_name() const {
114 return last_slave_disconnect_name_;
115 }
116
117 // |embedder::MasterProcessDelegate| implementation:
118 void OnShutdownComplete() override { NOTREACHED(); }
119
120 void OnSlaveDisconnect(embedder::SlaveInfo slave_info) override {
121 CHECK(thread_checker_.CalledOnValidThread());
122 on_slave_disconnect_calls_++;
123 last_slave_disconnect_name_ =
124 static_cast<TestSlaveInfo*>(slave_info)->name();
125 DVLOG(1) << "Disconnected from slave process "
126 << last_slave_disconnect_name_;
127 delete static_cast<TestSlaveInfo*>(slave_info);
128
129 if (current_run_loop_)
130 current_run_loop_->Quit();
131 }
132
133 private:
134 base::ThreadChecker thread_checker_;
135 base::RunLoop* current_run_loop_;
136
137 unsigned on_slave_disconnect_calls_;
138 std::string last_slave_disconnect_name_;
139
140 MOJO_DISALLOW_COPY_AND_ASSIGN(MockMasterProcessDelegate);
141 };
142
143 class MockSlaveProcessDelegate : public embedder::SlaveProcessDelegate {
144 public:
145 MockSlaveProcessDelegate()
146 : current_run_loop_(), on_master_disconnect_calls_(0) {}
147 ~MockSlaveProcessDelegate() override {}
148
149 void RunUntilNotified() {
150 CHECK(!current_run_loop_);
151 base::RunLoop run_loop;
152 current_run_loop_ = &run_loop;
153 run_loop.Run();
154 current_run_loop_ = nullptr;
155 }
156
157 unsigned on_master_disconnect_calls() const {
158 return on_master_disconnect_calls_;
159 }
160
161 // |embedder::SlaveProcessDelegate| implementation:
162 void OnShutdownComplete() override { NOTREACHED(); }
163
164 void OnMasterDisconnect() override {
165 CHECK(thread_checker_.CalledOnValidThread());
166 on_master_disconnect_calls_++;
167 DVLOG(1) << "Disconnected from master process";
168
169 if (current_run_loop_)
170 current_run_loop_->Quit();
171 }
172
173 private:
174 base::ThreadChecker thread_checker_;
175 base::RunLoop* current_run_loop_;
176
177 unsigned on_master_disconnect_calls_;
178
179 MOJO_DISALLOW_COPY_AND_ASSIGN(MockSlaveProcessDelegate);
180 };
181
182 class ConnectionManagerTest : public testing::Test {
183 protected:
184 ConnectionManagerTest() {}
185 ~ConnectionManagerTest() override {}
186
187 embedder::PlatformSupport* platform_support() { return &platform_support_; }
188
189 base::MessageLoop& message_loop() { return message_loop_; }
190 MockMasterProcessDelegate& master_process_delegate() {
191 return master_process_delegate_;
192 }
193
194 private:
195 embedder::SimplePlatformSupport platform_support_;
196 base::MessageLoop message_loop_;
197 MockMasterProcessDelegate master_process_delegate_;
198
199 MOJO_DISALLOW_COPY_AND_ASSIGN(ConnectionManagerTest);
200 };
201
202 TEST_F(ConnectionManagerTest, BasicConnectSlaves) {
203 MasterConnectionManager master(platform_support());
204 master.Init(&master_process_delegate());
205
206 MockSlaveProcessDelegate slave1_process_delegate;
207 SlaveConnectionManager slave1(platform_support());
208 ProcessIdentifier slave1_id =
209 ConnectSlave(&master, &slave1_process_delegate, &slave1, "slave1");
210 EXPECT_TRUE(IsValidSlaveProcessIdentifier(slave1_id));
211
212 MockSlaveProcessDelegate slave2_process_delegate;
213 SlaveConnectionManager slave2(platform_support());
214 ProcessIdentifier slave2_id =
215 ConnectSlave(&master, &slave2_process_delegate, &slave2, "slave2");
216 EXPECT_TRUE(IsValidSlaveProcessIdentifier(slave2_id));
217 // TODO(vtl): If/when I add the ability to get one's own process identifier,
218 // there'll be more we can check.
219 EXPECT_NE(slave1_id, slave2_id);
220
221 ConnectionIdentifier connection_id = master.GenerateConnectionIdentifier();
222 EXPECT_TRUE(slave1.AllowConnect(connection_id));
223 EXPECT_TRUE(slave2.AllowConnect(connection_id));
224
225 ProcessIdentifier peer1 = kInvalidProcessIdentifier;
226 bool is_first = false;
227 embedder::ScopedPlatformHandle h1;
228 EXPECT_EQ(ConnectionManager::Result::SUCCESS_CONNECT_NEW_CONNECTION,
229 slave1.Connect(connection_id, &peer1, &is_first, &h1));
230 EXPECT_EQ(slave2_id, peer1);
231 EXPECT_TRUE(is_first);
232 EXPECT_TRUE(h1.is_valid());
233 ProcessIdentifier peer2 = kInvalidProcessIdentifier;
234 embedder::ScopedPlatformHandle h2;
235 EXPECT_EQ(ConnectionManager::Result::SUCCESS_CONNECT_NEW_CONNECTION,
236 slave2.Connect(connection_id, &peer2, &is_first, &h2));
237 EXPECT_EQ(slave1_id, peer2);
238 EXPECT_FALSE(is_first);
239 EXPECT_TRUE(h2.is_valid());
240
241 EXPECT_TRUE(ArePlatformHandlesConnected(h1.get(), h2.get()));
242
243 // The process manager shouldn't have gotten any notifications yet. (Spin the
244 // message loop to make sure none were enqueued.)
245 base::RunLoop().RunUntilIdle();
246 EXPECT_EQ(0u, master_process_delegate().on_slave_disconnect_calls());
247
248 slave1.Shutdown();
249
250 // |OnSlaveDisconnect()| should be called once.
251 master_process_delegate().RunUntilNotified();
252 EXPECT_EQ(1u, master_process_delegate().on_slave_disconnect_calls());
253 EXPECT_EQ("slave1", master_process_delegate().last_slave_disconnect_name());
254
255 slave2.Shutdown();
256
257 // |OnSlaveDisconnect()| should be called again.
258 master_process_delegate().RunUntilNotified();
259 EXPECT_EQ(2u, master_process_delegate().on_slave_disconnect_calls());
260 EXPECT_EQ("slave2", master_process_delegate().last_slave_disconnect_name());
261
262 master.Shutdown();
263
264 // None of the above should result in |OnMasterDisconnect()| being called.
265 base::RunLoop().RunUntilIdle();
266 EXPECT_EQ(0u, slave1_process_delegate.on_master_disconnect_calls());
267 EXPECT_EQ(0u, slave2_process_delegate.on_master_disconnect_calls());
268 }
269
270 TEST_F(ConnectionManagerTest, ShutdownMasterBeforeSlave) {
271 MasterConnectionManager master(platform_support());
272 master.Init(&master_process_delegate());
273
274 MockSlaveProcessDelegate slave_process_delegate;
275 SlaveConnectionManager slave(platform_support());
276 ProcessIdentifier slave_id =
277 ConnectSlave(&master, &slave_process_delegate, &slave, "slave");
278 EXPECT_TRUE(IsValidSlaveProcessIdentifier(slave_id));
279
280 // The process manager shouldn't have gotten any notifications yet. (Spin the
281 // message loop to make sure none were enqueued.)
282 base::RunLoop().RunUntilIdle();
283 EXPECT_EQ(0u, master_process_delegate().on_slave_disconnect_calls());
284
285 master.Shutdown();
286
287 // |OnSlaveDisconnect()| should be called.
288 master_process_delegate().RunUntilNotified();
289 EXPECT_EQ(1u, master_process_delegate().on_slave_disconnect_calls());
290 EXPECT_EQ("slave", master_process_delegate().last_slave_disconnect_name());
291
292 // |OnMasterDisconnect()| should also be (or have been) called.
293 slave_process_delegate.RunUntilNotified();
294 EXPECT_EQ(1u, slave_process_delegate.on_master_disconnect_calls());
295
296 slave.Shutdown();
297 }
298
299 TEST_F(ConnectionManagerTest, SlaveCancelConnect) {
300 MasterConnectionManager master(platform_support());
301 master.Init(&master_process_delegate());
302
303 MockSlaveProcessDelegate slave1_process_delegate;
304 SlaveConnectionManager slave1(platform_support());
305 ProcessIdentifier slave1_id =
306 ConnectSlave(&master, &slave1_process_delegate, &slave1, "slave1");
307 EXPECT_TRUE(IsValidSlaveProcessIdentifier(slave1_id));
308
309 MockSlaveProcessDelegate slave2_process_delegate;
310 SlaveConnectionManager slave2(platform_support());
311 ProcessIdentifier slave2_id =
312 ConnectSlave(&master, &slave2_process_delegate, &slave2, "slave2");
313 EXPECT_TRUE(IsValidSlaveProcessIdentifier(slave2_id));
314 EXPECT_NE(slave1_id, slave2_id);
315
316 ConnectionIdentifier connection_id = master.GenerateConnectionIdentifier();
317 EXPECT_TRUE(slave1.AllowConnect(connection_id));
318 EXPECT_TRUE(slave2.AllowConnect(connection_id));
319
320 EXPECT_TRUE(slave1.CancelConnect(connection_id));
321 ProcessIdentifier peer2 = kInvalidProcessIdentifier;
322 bool is_first = false;
323 embedder::ScopedPlatformHandle h2;
324 EXPECT_EQ(ConnectionManager::Result::FAILURE,
325 slave2.Connect(connection_id, &peer2, &is_first, &h2));
326 EXPECT_EQ(kInvalidProcessIdentifier, peer2);
327 EXPECT_FALSE(is_first);
328 EXPECT_FALSE(h2.is_valid());
329
330 slave1.Shutdown();
331 slave2.Shutdown();
332 master.Shutdown();
333 }
334
335 // Tests that pending connections are removed on error.
336 TEST_F(ConnectionManagerTest, ErrorRemovePending) {
337 MasterConnectionManager master(platform_support());
338 master.Init(&master_process_delegate());
339
340 MockSlaveProcessDelegate slave1_process_delegate;
341 SlaveConnectionManager slave1(platform_support());
342 ProcessIdentifier slave1_id =
343 ConnectSlave(&master, &slave1_process_delegate, &slave1, "slave1");
344 EXPECT_TRUE(IsValidSlaveProcessIdentifier(slave1_id));
345
346 MockSlaveProcessDelegate slave2_process_delegate;
347 SlaveConnectionManager slave2(platform_support());
348 ProcessIdentifier slave2_id =
349 ConnectSlave(&master, &slave2_process_delegate, &slave2, "slave2");
350 EXPECT_TRUE(IsValidSlaveProcessIdentifier(slave2_id));
351 EXPECT_NE(slave1_id, slave2_id);
352
353 ConnectionIdentifier connection_id = master.GenerateConnectionIdentifier();
354 EXPECT_TRUE(slave1.AllowConnect(connection_id));
355 EXPECT_TRUE(slave2.AllowConnect(connection_id));
356
357 slave1.Shutdown();
358
359 // |OnSlaveDisconnect()| should be called. After it's called, this means that
360 // the disconnect has been detected and handled, including the removal of the
361 // pending connection.
362 master_process_delegate().RunUntilNotified();
363 EXPECT_EQ(1u, master_process_delegate().on_slave_disconnect_calls());
364
365 ProcessIdentifier peer2 = kInvalidProcessIdentifier;
366 bool is_first = false;
367 embedder::ScopedPlatformHandle h2;
368 EXPECT_EQ(ConnectionManager::Result::FAILURE,
369 slave2.Connect(connection_id, &peer2, &is_first, &h2));
370 EXPECT_EQ(kInvalidProcessIdentifier, peer2);
371 EXPECT_FALSE(is_first);
372 EXPECT_FALSE(h2.is_valid());
373
374 slave2.Shutdown();
375 master.Shutdown();
376 }
377
378 TEST_F(ConnectionManagerTest, ConnectSlaveToSelf) {
379 MasterConnectionManager master(platform_support());
380 master.Init(&master_process_delegate());
381
382 MockSlaveProcessDelegate slave_process_delegate;
383 SlaveConnectionManager slave(platform_support());
384 ProcessIdentifier slave_id =
385 ConnectSlave(&master, &slave_process_delegate, &slave, "slave");
386 EXPECT_TRUE(IsValidSlaveProcessIdentifier(slave_id));
387
388 ConnectionIdentifier connection_id = master.GenerateConnectionIdentifier();
389 EXPECT_TRUE(slave.AllowConnect(connection_id));
390 EXPECT_TRUE(slave.AllowConnect(connection_id));
391
392 ProcessIdentifier peer1 = kInvalidProcessIdentifier;
393 bool is_first = false;
394 embedder::ScopedPlatformHandle h1;
395 EXPECT_EQ(ConnectionManager::Result::SUCCESS_CONNECT_SAME_PROCESS,
396 slave.Connect(connection_id, &peer1, &is_first, &h1));
397 EXPECT_EQ(slave_id, peer1);
398 EXPECT_TRUE(is_first);
399 EXPECT_FALSE(h1.is_valid());
400 ProcessIdentifier peer2 = kInvalidProcessIdentifier;
401 embedder::ScopedPlatformHandle h2;
402 EXPECT_EQ(ConnectionManager::Result::SUCCESS_CONNECT_SAME_PROCESS,
403 slave.Connect(connection_id, &peer2, &is_first, &h2));
404 EXPECT_EQ(slave_id, peer2);
405 EXPECT_FALSE(is_first);
406 EXPECT_FALSE(h2.is_valid());
407
408 slave.Shutdown();
409 master.Shutdown();
410 }
411
412 TEST_F(ConnectionManagerTest, ConnectSlavesTwice) {
413 MasterConnectionManager master(platform_support());
414 master.Init(&master_process_delegate());
415
416 MockSlaveProcessDelegate slave1_process_delegate;
417 SlaveConnectionManager slave1(platform_support());
418 ProcessIdentifier slave1_id =
419 ConnectSlave(&master, &slave1_process_delegate, &slave1, "slave1");
420 EXPECT_TRUE(IsValidSlaveProcessIdentifier(slave1_id));
421
422 MockSlaveProcessDelegate slave2_process_delegate;
423 SlaveConnectionManager slave2(platform_support());
424 ProcessIdentifier slave2_id =
425 ConnectSlave(&master, &slave2_process_delegate, &slave2, "slave2");
426 EXPECT_TRUE(IsValidSlaveProcessIdentifier(slave2_id));
427 EXPECT_NE(slave1_id, slave2_id);
428
429 ConnectionIdentifier connection_id = master.GenerateConnectionIdentifier();
430 EXPECT_TRUE(slave1.AllowConnect(connection_id));
431 EXPECT_TRUE(slave2.AllowConnect(connection_id));
432
433 ProcessIdentifier peer1 = kInvalidProcessIdentifier;
434 bool is_first = false;
435 embedder::ScopedPlatformHandle h1;
436 EXPECT_EQ(ConnectionManager::Result::SUCCESS_CONNECT_NEW_CONNECTION,
437 slave1.Connect(connection_id, &peer1, &is_first, &h1));
438 EXPECT_EQ(slave2_id, peer1);
439 EXPECT_TRUE(is_first);
440 ProcessIdentifier peer2 = kInvalidProcessIdentifier;
441 embedder::ScopedPlatformHandle h2;
442 EXPECT_EQ(ConnectionManager::Result::SUCCESS_CONNECT_NEW_CONNECTION,
443 slave2.Connect(connection_id, &peer2, &is_first, &h2));
444 EXPECT_EQ(slave1_id, peer2);
445 EXPECT_FALSE(is_first);
446
447 EXPECT_TRUE(ArePlatformHandlesConnected(h1.get(), h2.get()));
448
449 // TODO(vtl): Currently, the master doesn't detect the case of connecting a
450 // pair of slaves that are already connected. (Doing so would require more
451 // careful tracking and is prone to races -- especially if we want slaves to
452 // be able to tear down no-longer-needed connections.) But the slaves should
453 // be able to do the tracking themselves (using the peer process identifiers).
454 connection_id = master.GenerateConnectionIdentifier();
455 EXPECT_TRUE(slave1.AllowConnect(connection_id));
456 EXPECT_TRUE(slave2.AllowConnect(connection_id));
457
458 h1.reset();
459 h2.reset();
460 ProcessIdentifier second_peer2 = kInvalidProcessIdentifier;
461 EXPECT_EQ(ConnectionManager::Result::SUCCESS_CONNECT_REUSE_CONNECTION,
462 slave2.Connect(connection_id, &second_peer2, &is_first, &h2));
463 EXPECT_EQ(peer2, second_peer2);
464 EXPECT_TRUE(is_first);
465 EXPECT_FALSE(h2.is_valid());
466 ProcessIdentifier second_peer1 = kInvalidProcessIdentifier;
467 EXPECT_EQ(ConnectionManager::Result::SUCCESS_CONNECT_REUSE_CONNECTION,
468 slave1.Connect(connection_id, &second_peer1, &is_first, &h1));
469 EXPECT_EQ(peer1, second_peer1);
470 EXPECT_FALSE(is_first);
471 EXPECT_FALSE(h1.is_valid());
472
473 slave2.Shutdown();
474 slave1.Shutdown();
475 master.Shutdown();
476 }
477
478 TEST_F(ConnectionManagerTest, OverlappingSlaveConnects) {
479 MasterConnectionManager master(platform_support());
480 master.Init(&master_process_delegate());
481
482 MockSlaveProcessDelegate slave1_process_delegate;
483 SlaveConnectionManager slave1(platform_support());
484 ProcessIdentifier slave1_id =
485 ConnectSlave(&master, &slave1_process_delegate, &slave1, "slave1");
486 EXPECT_TRUE(IsValidSlaveProcessIdentifier(slave1_id));
487
488 MockSlaveProcessDelegate slave2_process_delegate;
489 SlaveConnectionManager slave2(platform_support());
490 ProcessIdentifier slave2_id =
491 ConnectSlave(&master, &slave2_process_delegate, &slave2, "slave2");
492 EXPECT_TRUE(IsValidSlaveProcessIdentifier(slave2_id));
493 EXPECT_NE(slave1_id, slave2_id);
494
495 ConnectionIdentifier connection_id1 = master.GenerateConnectionIdentifier();
496 EXPECT_TRUE(slave1.AllowConnect(connection_id1));
497 EXPECT_TRUE(slave2.AllowConnect(connection_id1));
498
499 ConnectionIdentifier connection_id2 = master.GenerateConnectionIdentifier();
500 EXPECT_TRUE(slave1.AllowConnect(connection_id2));
501 EXPECT_TRUE(slave2.AllowConnect(connection_id2));
502
503 ProcessIdentifier peer1 = kInvalidProcessIdentifier;
504 bool is_first = false;
505 embedder::ScopedPlatformHandle h1;
506 EXPECT_EQ(ConnectionManager::Result::SUCCESS_CONNECT_NEW_CONNECTION,
507 slave1.Connect(connection_id1, &peer1, &is_first, &h1));
508 EXPECT_EQ(slave2_id, peer1);
509 EXPECT_TRUE(is_first);
510 ProcessIdentifier peer2 = kInvalidProcessIdentifier;
511 embedder::ScopedPlatformHandle h2;
512 EXPECT_EQ(ConnectionManager::Result::SUCCESS_CONNECT_NEW_CONNECTION,
513 slave2.Connect(connection_id2, &peer2, &is_first, &h2));
514 EXPECT_EQ(slave1_id, peer2);
515 EXPECT_TRUE(is_first);
516
517 EXPECT_TRUE(ArePlatformHandlesConnected(h1.get(), h2.get()));
518
519 h1.reset();
520 h2.reset();
521 ProcessIdentifier second_peer1 = kInvalidProcessIdentifier;
522 EXPECT_EQ(ConnectionManager::Result::SUCCESS_CONNECT_REUSE_CONNECTION,
523 slave1.Connect(connection_id2, &second_peer1, &is_first, &h1));
524 EXPECT_EQ(peer1, second_peer1);
525 EXPECT_FALSE(is_first);
526 EXPECT_FALSE(h1.is_valid());
527 ProcessIdentifier second_peer2 = kInvalidProcessIdentifier;
528 EXPECT_EQ(ConnectionManager::Result::SUCCESS_CONNECT_REUSE_CONNECTION,
529 slave2.Connect(connection_id1, &second_peer2, &is_first, &h2));
530 EXPECT_EQ(peer2, second_peer2);
531 EXPECT_FALSE(is_first);
532 EXPECT_FALSE(h2.is_valid());
533
534 slave2.Shutdown();
535 slave1.Shutdown();
536 master.Shutdown();
537 }
538
539 TEST_F(ConnectionManagerTest, ConnectMasterToSlave) {
540 MasterConnectionManager master(platform_support());
541 master.Init(&master_process_delegate());
542
543 MockSlaveProcessDelegate slave_process_delegate;
544 SlaveConnectionManager slave(platform_support());
545 ProcessIdentifier slave_id =
546 ConnectSlave(&master, &slave_process_delegate, &slave, "slave");
547 EXPECT_TRUE(IsValidSlaveProcessIdentifier(slave_id));
548
549 ConnectionIdentifier connection_id = master.GenerateConnectionIdentifier();
550 EXPECT_TRUE(master.AllowConnect(connection_id));
551 EXPECT_TRUE(slave.AllowConnect(connection_id));
552
553 ProcessIdentifier master_peer = kInvalidProcessIdentifier;
554 bool is_first = false;
555 embedder::ScopedPlatformHandle master_h;
556 EXPECT_EQ(ConnectionManager::Result::SUCCESS_CONNECT_NEW_CONNECTION,
557 master.Connect(connection_id, &master_peer, &is_first, &master_h));
558 EXPECT_EQ(slave_id, master_peer);
559 EXPECT_TRUE(is_first);
560 EXPECT_TRUE(master_h.is_valid());
561 ProcessIdentifier slave_peer = kInvalidProcessIdentifier;
562 embedder::ScopedPlatformHandle slave_h;
563 EXPECT_EQ(ConnectionManager::Result::SUCCESS_CONNECT_NEW_CONNECTION,
564 slave.Connect(connection_id, &slave_peer, &is_first, &slave_h));
565 EXPECT_EQ(kMasterProcessIdentifier, slave_peer);
566 EXPECT_FALSE(is_first);
567 EXPECT_TRUE(slave_h.is_valid());
568
569 EXPECT_TRUE(ArePlatformHandlesConnected(master_h.get(), slave_h.get()));
570
571 slave.Shutdown();
572 master.Shutdown();
573 }
574
575 TEST_F(ConnectionManagerTest, ConnectMasterToSelf) {
576 MasterConnectionManager master(platform_support());
577 master.Init(&master_process_delegate());
578
579 ConnectionIdentifier connection_id = master.GenerateConnectionIdentifier();
580 EXPECT_TRUE(master.AllowConnect(connection_id));
581 EXPECT_TRUE(master.AllowConnect(connection_id));
582
583 ProcessIdentifier peer1 = kInvalidProcessIdentifier;
584 bool is_first = false;
585 embedder::ScopedPlatformHandle h1;
586 EXPECT_EQ(ConnectionManager::Result::SUCCESS_CONNECT_SAME_PROCESS,
587 master.Connect(connection_id, &peer1, &is_first, &h1));
588 EXPECT_EQ(kMasterProcessIdentifier, peer1);
589 EXPECT_TRUE(is_first);
590 EXPECT_FALSE(h1.is_valid());
591 ProcessIdentifier peer2 = kInvalidProcessIdentifier;
592 embedder::ScopedPlatformHandle h2;
593 EXPECT_EQ(ConnectionManager::Result::SUCCESS_CONNECT_SAME_PROCESS,
594 master.Connect(connection_id, &peer2, &is_first, &h2));
595 EXPECT_EQ(kMasterProcessIdentifier, peer2);
596 EXPECT_FALSE(is_first);
597 EXPECT_FALSE(h2.is_valid());
598
599 EXPECT_EQ(peer1, peer2);
600
601 master.Shutdown();
602 }
603
604 TEST_F(ConnectionManagerTest, MasterCancelConnect) {
605 MasterConnectionManager master(platform_support());
606 master.Init(&master_process_delegate());
607
608 MockSlaveProcessDelegate slave_process_delegate;
609 SlaveConnectionManager slave(platform_support());
610 ProcessIdentifier slave_id =
611 ConnectSlave(&master, &slave_process_delegate, &slave, "slave");
612 EXPECT_TRUE(IsValidSlaveProcessIdentifier(slave_id));
613
614 ConnectionIdentifier connection_id = master.GenerateConnectionIdentifier();
615 EXPECT_TRUE(master.AllowConnect(connection_id));
616 EXPECT_TRUE(slave.AllowConnect(connection_id));
617
618 EXPECT_TRUE(master.CancelConnect(connection_id));
619 ProcessIdentifier peer = kInvalidProcessIdentifier;
620 bool is_first = false;
621 embedder::ScopedPlatformHandle h;
622 EXPECT_EQ(ConnectionManager::Result::FAILURE,
623 slave.Connect(connection_id, &peer, &is_first, &h));
624 EXPECT_EQ(kInvalidProcessIdentifier, peer);
625 EXPECT_FALSE(is_first);
626 EXPECT_FALSE(h.is_valid());
627
628 slave.Shutdown();
629 master.Shutdown();
630 }
631
632 TEST_F(ConnectionManagerTest, AddSlaveThenImmediateShutdown) {
633 MasterConnectionManager master(platform_support());
634 master.Init(&master_process_delegate());
635
636 MockSlaveProcessDelegate slave_process_delegate;
637 SlaveConnectionManager slave(platform_support());
638 embedder::PlatformChannelPair platform_channel_pair;
639 ProcessIdentifier slave_id = master.AddSlave(
640 new TestSlaveInfo("slave"), platform_channel_pair.PassServerHandle());
641 master.Shutdown();
642 EXPECT_TRUE(IsValidSlaveProcessIdentifier(slave_id));
643 // Since we never initialized |slave|, we don't have to shut it down.
644 }
645
646 TEST_F(ConnectionManagerTest, AddSlaveAndBootstrap) {
647 MasterConnectionManager master(platform_support());
648 master.Init(&master_process_delegate());
649
650 embedder::PlatformChannelPair platform_channel_pair;
651 ConnectionIdentifier connection_id = master.GenerateConnectionIdentifier();
652 ProcessIdentifier slave_id = master.AddSlaveAndBootstrap(
653 new TestSlaveInfo("slave"), platform_channel_pair.PassServerHandle(),
654 connection_id);
655 EXPECT_TRUE(IsValidSlaveProcessIdentifier(slave_id));
656
657 embedder::ScopedPlatformHandle h1;
658 ProcessIdentifier master_peer = kInvalidProcessIdentifier;
659 bool is_first = false;
660 EXPECT_EQ(ConnectionManager::Result::SUCCESS_CONNECT_NEW_CONNECTION,
661 master.Connect(connection_id, &master_peer, &is_first, &h1));
662 EXPECT_EQ(slave_id, master_peer);
663 EXPECT_TRUE(is_first);
664 EXPECT_TRUE(h1.is_valid());
665
666 // We can delay creating/initializing |slave| for quite a while.
667 MockSlaveProcessDelegate slave_process_delegate;
668 SlaveConnectionManager slave(platform_support());
669 slave.Init(&slave_process_delegate, platform_channel_pair.PassClientHandle());
670
671 ProcessIdentifier slave_peer = kInvalidProcessIdentifier;
672 embedder::ScopedPlatformHandle h2;
673 EXPECT_EQ(ConnectionManager::Result::SUCCESS_CONNECT_NEW_CONNECTION,
674 slave.Connect(connection_id, &slave_peer, &is_first, &h2));
675 EXPECT_EQ(kMasterProcessIdentifier, slave_peer);
676 EXPECT_FALSE(is_first);
677
678 EXPECT_TRUE(ArePlatformHandlesConnected(h1.get(), h2.get()));
679
680 slave.Shutdown();
681 master.Shutdown();
682 }
683
684 // TODO(vtl): More shutdown cases for |AddSlaveAndBootstrap()|?
685
686 } // namespace
687 } // namespace system
688 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698