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

Side by Side Diff: mojo/edk/system/channel_manager_unittest.cc

Issue 885453003: Remove ChannelManager::AddChannel(). (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 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
« no previous file with comments | « mojo/edk/system/channel_manager.cc ('k') | no next file » | 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 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/system/channel_manager.h" 5 #include "mojo/edk/system/channel_manager.h"
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "base/macros.h" 8 #include "base/macros.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/message_loop/message_loop_proxy.h" 10 #include "base/message_loop/message_loop_proxy.h"
11 #include "base/run_loop.h" 11 #include "base/run_loop.h"
12 #include "base/task_runner.h" 12 #include "base/task_runner.h"
13 #include "base/test/test_timeouts.h" 13 #include "base/test/test_timeouts.h"
14 #include "base/threading/platform_thread.h" 14 #include "base/threading/platform_thread.h"
15 #include "base/threading/simple_thread.h" 15 #include "base/threading/simple_thread.h"
16 #include "base/time/time.h" 16 #include "base/time/time.h"
17 #include "mojo/edk/embedder/platform_channel_pair.h" 17 #include "mojo/edk/embedder/platform_channel_pair.h"
18 #include "mojo/edk/embedder/simple_platform_support.h" 18 #include "mojo/edk/embedder/simple_platform_support.h"
19 #include "mojo/edk/system/channel.h" 19 #include "mojo/edk/system/channel.h"
20 #include "mojo/edk/system/channel_endpoint.h"
21 #include "mojo/edk/system/message_pipe_dispatcher.h"
20 #include "testing/gtest/include/gtest/gtest.h" 22 #include "testing/gtest/include/gtest/gtest.h"
21 23
22 namespace mojo { 24 namespace mojo {
23 namespace system { 25 namespace system {
24 namespace { 26 namespace {
25 27
26 class ChannelManagerTest : public testing::Test { 28 class ChannelManagerTest : public testing::Test {
27 public: 29 public:
28 ChannelManagerTest() : message_loop_(base::MessageLoop::TYPE_IO) {} 30 ChannelManagerTest() : message_loop_(base::MessageLoop::TYPE_IO) {}
29 ~ChannelManagerTest() override {} 31 ~ChannelManagerTest() override {}
30 32
31 protected: 33 protected:
32 embedder::SimplePlatformSupport* platform_support() { 34 embedder::SimplePlatformSupport* platform_support() {
33 return &platform_support_; 35 return &platform_support_;
34 } 36 }
35 base::MessageLoop* message_loop() { return &message_loop_; } 37 base::MessageLoop* message_loop() { return &message_loop_; }
36 38
37 private: 39 private:
38 embedder::SimplePlatformSupport platform_support_; 40 embedder::SimplePlatformSupport platform_support_;
39 base::MessageLoop message_loop_; 41 base::MessageLoop message_loop_;
40 42
41 DISALLOW_COPY_AND_ASSIGN(ChannelManagerTest); 43 DISALLOW_COPY_AND_ASSIGN(ChannelManagerTest);
42 }; 44 };
43 45
44 TEST_F(ChannelManagerTest, Basic) { 46 TEST_F(ChannelManagerTest, Basic) {
45 ChannelManager cm(platform_support()); 47 ChannelManager cm(platform_support());
46 48
47 // Hang on to a ref to the |Channel|, so that we can check that the 49 embedder::PlatformChannelPair channel_pair;
48 // |ChannelManager| takes/releases refs to it.
49 scoped_refptr<Channel> ch(new Channel(platform_support()));
50 ASSERT_TRUE(ch->HasOneRef());
51 50
52 embedder::PlatformChannelPair channel_pair; 51 scoped_refptr<ChannelEndpoint> cep;
yzshen1 2015/02/04 17:26:39 nit: naming variables like this is probably disfav
53 ch->Init(RawChannel::Create(channel_pair.PassServerHandle())); 52 scoped_refptr<MessagePipeDispatcher> d =
53 MessagePipeDispatcher::CreateRemoteMessagePipe(&cep);
54 const ChannelId id = 1;
55 cm.CreateChannelOnIOThread(id, channel_pair.PassServerHandle(), cep);
56 cep = nullptr;
54 57
55 const ChannelId id = 1; 58 scoped_refptr<Channel> ch = cm.GetChannel(id);
56 cm.AddChannel(id, ch, base::MessageLoopProxy::current()); 59 EXPECT_TRUE(ch);
57 // |ChannelManager| should take a ref. 60 // |ChannelManager| should have a ref.
58 EXPECT_FALSE(ch->HasOneRef()); 61 EXPECT_FALSE(ch->HasOneRef());
59 62
60 cm.WillShutdownChannel(id); 63 cm.WillShutdownChannel(id);
61 // |ChannelManager| should still have a ref. 64 // |ChannelManager| should still have a ref.
62 EXPECT_FALSE(ch->HasOneRef()); 65 EXPECT_FALSE(ch->HasOneRef());
63 66
64 cm.ShutdownChannel(id); 67 cm.ShutdownChannel(id);
65 // On the "I/O" thread, so shutdown should happen synchronously. 68 // On the "I/O" thread, so shutdown should happen synchronously.
66 // |ChannelManager| should have given up its ref. 69 // |ChannelManager| should have given up its ref.
67 EXPECT_TRUE(ch->HasOneRef()); 70 EXPECT_TRUE(ch->HasOneRef());
71
72 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
68 } 73 }
69 74
70 TEST_F(ChannelManagerTest, TwoChannels) { 75 TEST_F(ChannelManagerTest, TwoChannels) {
71 ChannelManager cm(platform_support()); 76 ChannelManager cm(platform_support());
72 77
73 // Hang on to a ref to each |Channel|, so that we can check that the 78 embedder::PlatformChannelPair channel_pair;
74 // |ChannelManager| takes/releases refs to them.
75 scoped_refptr<Channel> ch1(new Channel(platform_support()));
76 ASSERT_TRUE(ch1->HasOneRef());
77 scoped_refptr<Channel> ch2(new Channel(platform_support()));
78 ASSERT_TRUE(ch2->HasOneRef());
79 79
80 embedder::PlatformChannelPair channel_pair; 80 scoped_refptr<ChannelEndpoint> cep1;
81 ch1->Init(RawChannel::Create(channel_pair.PassServerHandle())); 81 scoped_refptr<MessagePipeDispatcher> d1 =
82 ch2->Init(RawChannel::Create(channel_pair.PassClientHandle())); 82 MessagePipeDispatcher::CreateRemoteMessagePipe(&cep1);
83 const ChannelId id1 = 1;
84 cm.CreateChannelOnIOThread(id1, channel_pair.PassServerHandle(), cep1);
85 cep1 = nullptr;
83 86
84 const ChannelId id1 = 1; 87 scoped_refptr<ChannelEndpoint> cep2;
85 cm.AddChannel(id1, ch1, base::MessageLoopProxy::current()); 88 scoped_refptr<MessagePipeDispatcher> d2 =
86 EXPECT_FALSE(ch1->HasOneRef()); 89 MessagePipeDispatcher::CreateRemoteMessagePipe(&cep2);
90 const ChannelId id2 = 2;
91 cm.CreateChannelOnIOThread(id2, channel_pair.PassClientHandle(), cep2);
92 cep2 = nullptr;
87 93
88 const ChannelId id2 = 2; 94 scoped_refptr<Channel> ch1 = cm.GetChannel(id1);
89 cm.AddChannel(id2, ch2, base::MessageLoopProxy::current()); 95 EXPECT_TRUE(ch1);
90 EXPECT_FALSE(ch2->HasOneRef()); 96
97 scoped_refptr<Channel> ch2 = cm.GetChannel(id2);
98 EXPECT_TRUE(ch2);
91 99
92 // Calling |WillShutdownChannel()| multiple times (on |id1|) is okay. 100 // Calling |WillShutdownChannel()| multiple times (on |id1|) is okay.
93 cm.WillShutdownChannel(id1); 101 cm.WillShutdownChannel(id1);
94 cm.WillShutdownChannel(id1); 102 cm.WillShutdownChannel(id1);
95 EXPECT_FALSE(ch1->HasOneRef()); 103 EXPECT_FALSE(ch1->HasOneRef());
96 // Not calling |WillShutdownChannel()| (on |id2|) is okay too. 104 // Not calling |WillShutdownChannel()| (on |id2|) is okay too.
97 105
98 cm.ShutdownChannel(id1); 106 cm.ShutdownChannel(id1);
99 EXPECT_TRUE(ch1->HasOneRef()); 107 EXPECT_TRUE(ch1->HasOneRef());
100 cm.ShutdownChannel(id2); 108 cm.ShutdownChannel(id2);
101 EXPECT_TRUE(ch2->HasOneRef()); 109 EXPECT_TRUE(ch2->HasOneRef());
110
111 EXPECT_EQ(MOJO_RESULT_OK, d1->Close());
112 EXPECT_EQ(MOJO_RESULT_OK, d2->Close());
102 } 113 }
103 114
104 class OtherThread : public base::SimpleThread { 115 class OtherThread : public base::SimpleThread {
105 public: 116 public:
106 // Note: We rely on the main thread keeping *exactly one* reference to 117 // Note: There should be no other refs to the channel identified by
107 // |channel|. 118 // |channel_id| outside the channel manager.
108 OtherThread(scoped_refptr<base::TaskRunner> task_runner, 119 OtherThread(scoped_refptr<base::TaskRunner> task_runner,
109 ChannelManager* channel_manager, 120 ChannelManager* channel_manager,
110 Channel* channel, 121 ChannelId channel_id,
111 base::Closure quit_closure) 122 base::Closure quit_closure)
112 : base::SimpleThread("other_thread"), 123 : base::SimpleThread("other_thread"),
113 task_runner_(task_runner), 124 task_runner_(task_runner),
114 channel_manager_(channel_manager), 125 channel_manager_(channel_manager),
115 channel_(channel), 126 channel_id_(channel_id),
116 quit_closure_(quit_closure) {} 127 quit_closure_(quit_closure) {}
117 ~OtherThread() override {} 128 ~OtherThread() override {}
118 129
119 private: 130 private:
120 void Run() override { 131 void Run() override {
121 // See comment above constructor. 132 // TODO(vtl): Once we have a way of creating a channel from off the I/O
122 ASSERT_TRUE(channel_->HasOneRef()); 133 // thread, do that here instead.
123 134
124 // You can use any unique, nonzero value as the ID. 135 // You can use any unique, nonzero value as the ID.
125 const ChannelId id = 136 scoped_refptr<Channel> ch = channel_manager_->GetChannel(channel_id_);
126 static_cast<ChannelId>(reinterpret_cast<uintptr_t>(channel_)); 137 // |ChannelManager| should have a ref.
127 channel_manager_->AddChannel(id, make_scoped_refptr(channel_), 138 EXPECT_FALSE(ch->HasOneRef());
128 task_runner_);
129 // |ChannelManager| should take a ref.
130 EXPECT_FALSE(channel_->HasOneRef());
131 139
132 channel_manager_->WillShutdownChannel(id); 140 channel_manager_->WillShutdownChannel(channel_id_);
133 // |ChannelManager| should still have a ref. 141 // |ChannelManager| should still have a ref.
134 EXPECT_FALSE(channel_->HasOneRef()); 142 EXPECT_FALSE(ch->HasOneRef());
135 143
136 channel_manager_->ShutdownChannel(id); 144 channel_manager_->ShutdownChannel(channel_id_);
137 // This doesn't happen synchronously, so we "wait" until it does. 145 // This doesn't happen synchronously, so we "wait" until it does.
138 // TODO(vtl): Possibly |Channel| should provide some notification of being 146 // TODO(vtl): Probably |Channel| should provide some notification of being
139 // shut down. 147 // shut down.
140 base::TimeTicks start_time(base::TimeTicks::Now()); 148 base::TimeTicks start_time(base::TimeTicks::Now());
141 for (;;) { 149 for (;;) {
142 if (channel_->HasOneRef()) 150 if (ch->HasOneRef())
143 break; 151 break;
144 152
145 // Check, instead of assert, since if things go wrong, dying is more 153 // Check, instead of assert, since if things go wrong, dying is more
146 // reliable than tearing down. 154 // reliable than tearing down.
147 CHECK_LT(base::TimeTicks::Now() - start_time, 155 CHECK_LT(base::TimeTicks::Now() - start_time,
148 TestTimeouts::action_timeout()); 156 TestTimeouts::action_timeout());
149 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(20)); 157 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(20));
150 } 158 }
151 159
152 CHECK(task_runner_->PostTask(FROM_HERE, quit_closure_)); 160 CHECK(task_runner_->PostTask(FROM_HERE, quit_closure_));
153 } 161 }
154 162
155 scoped_refptr<base::TaskRunner> task_runner_; 163 scoped_refptr<base::TaskRunner> task_runner_;
156 ChannelManager* channel_manager_; 164 ChannelManager* channel_manager_;
157 Channel* channel_; 165 ChannelId channel_id_;
158 base::Closure quit_closure_; 166 base::Closure quit_closure_;
159 167
160 DISALLOW_COPY_AND_ASSIGN(OtherThread); 168 DISALLOW_COPY_AND_ASSIGN(OtherThread);
161 }; 169 };
162 170
163 TEST_F(ChannelManagerTest, CallsFromOtherThread) { 171 TEST_F(ChannelManagerTest, CallsFromOtherThread) {
164 ChannelManager cm(platform_support()); 172 ChannelManager cm(platform_support());
165 173
166 // Hang on to a ref to the |Channel|, so that we can check that the 174 embedder::PlatformChannelPair channel_pair;
167 // |ChannelManager| takes/releases refs to it.
168 scoped_refptr<Channel> ch(new Channel(platform_support()));
169 ASSERT_TRUE(ch->HasOneRef());
170 175
171 embedder::PlatformChannelPair channel_pair; 176 scoped_refptr<ChannelEndpoint> cep;
172 ch->Init(RawChannel::Create(channel_pair.PassServerHandle())); 177 scoped_refptr<MessagePipeDispatcher> d =
178 MessagePipeDispatcher::CreateRemoteMessagePipe(&cep);
179 const ChannelId id = 1;
180 cm.CreateChannelOnIOThread(id, channel_pair.PassServerHandle(), cep);
181 cep = nullptr;
173 182
174 base::RunLoop run_loop; 183 base::RunLoop run_loop;
175 OtherThread thread(base::MessageLoopProxy::current(), &cm, ch.get(), 184 OtherThread thread(base::MessageLoopProxy::current(), &cm, id,
176 run_loop.QuitClosure()); 185 run_loop.QuitClosure());
177 thread.Start(); 186 thread.Start();
178 run_loop.Run(); 187 run_loop.Run();
179 thread.Join(); 188 thread.Join();
189
190 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
180 } 191 }
181 192
182 } // namespace 193 } // namespace
183 } // namespace system 194 } // namespace system
184 } // namespace mojo 195 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/system/channel_manager.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698