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

Side by Side Diff: mojo/edk/system/channel_manager_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/system/channel_manager.cc ('k') | mojo/edk/system/channel_unittest.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/system/channel_manager.h"
6
7 #include "base/callback.h"
8 #include "base/macros.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/message_loop/message_loop_proxy.h"
11 #include "base/run_loop.h"
12 #include "base/task_runner.h"
13 #include "base/test/test_timeouts.h"
14 #include "base/threading/platform_thread.h"
15 #include "base/threading/simple_thread.h"
16 #include "base/time/time.h"
17 #include "mojo/edk/embedder/platform_channel_pair.h"
18 #include "mojo/edk/embedder/simple_platform_support.h"
19 #include "mojo/edk/system/channel.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 namespace mojo {
23 namespace system {
24 namespace {
25
26 class ChannelManagerTest : public testing::Test {
27 public:
28 ChannelManagerTest() : message_loop_(base::MessageLoop::TYPE_IO) {}
29 ~ChannelManagerTest() override {}
30
31 protected:
32 embedder::SimplePlatformSupport* platform_support() {
33 return &platform_support_;
34 }
35 base::MessageLoop* message_loop() { return &message_loop_; }
36
37 private:
38 embedder::SimplePlatformSupport platform_support_;
39 base::MessageLoop message_loop_;
40
41 DISALLOW_COPY_AND_ASSIGN(ChannelManagerTest);
42 };
43
44 TEST_F(ChannelManagerTest, Basic) {
45 ChannelManager cm;
46
47 // Hang on to a ref to the |Channel|, so that we can check that the
48 // |ChannelManager| takes/releases refs to it.
49 scoped_refptr<Channel> ch(new Channel(platform_support()));
50 ASSERT_TRUE(ch->HasOneRef());
51
52 embedder::PlatformChannelPair channel_pair;
53 ch->Init(RawChannel::Create(channel_pair.PassServerHandle()));
54
55 ChannelId id = cm.AddChannel(ch, base::MessageLoopProxy::current());
56 EXPECT_NE(id, 0u);
57 // |ChannelManager| should take a ref.
58 EXPECT_FALSE(ch->HasOneRef());
59
60 cm.WillShutdownChannel(id);
61 // |ChannelManager| should still have a ref.
62 EXPECT_FALSE(ch->HasOneRef());
63
64 cm.ShutdownChannel(id);
65 // On the "I/O" thread, so shutdown should happen synchronously.
66 // |ChannelManager| should have given up its ref.
67 EXPECT_TRUE(ch->HasOneRef());
68 }
69
70 TEST_F(ChannelManagerTest, TwoChannels) {
71 ChannelManager cm;
72
73 // Hang on to a ref to each |Channel|, so that we can check that the
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
80 embedder::PlatformChannelPair channel_pair;
81 ch1->Init(RawChannel::Create(channel_pair.PassServerHandle()));
82 ch2->Init(RawChannel::Create(channel_pair.PassClientHandle()));
83
84 ChannelId id1 = cm.AddChannel(ch1, base::MessageLoopProxy::current());
85 EXPECT_NE(id1, 0u);
86 EXPECT_FALSE(ch1->HasOneRef());
87
88 ChannelId id2 = cm.AddChannel(ch2, base::MessageLoopProxy::current());
89 EXPECT_NE(id2, 0u);
90 EXPECT_NE(id2, id1);
91 EXPECT_FALSE(ch2->HasOneRef());
92
93 // Calling |WillShutdownChannel()| multiple times (on |id1|) is okay.
94 cm.WillShutdownChannel(id1);
95 cm.WillShutdownChannel(id1);
96 EXPECT_FALSE(ch1->HasOneRef());
97 // Not calling |WillShutdownChannel()| (on |id2|) is okay too.
98
99 cm.ShutdownChannel(id1);
100 EXPECT_TRUE(ch1->HasOneRef());
101 cm.ShutdownChannel(id2);
102 EXPECT_TRUE(ch2->HasOneRef());
103 }
104
105 class OtherThread : public base::SimpleThread {
106 public:
107 // Note: We rely on the main thread keeping *exactly one* reference to
108 // |channel|.
109 OtherThread(scoped_refptr<base::TaskRunner> task_runner,
110 ChannelManager* channel_manager,
111 Channel* channel,
112 base::Closure quit_closure)
113 : base::SimpleThread("other_thread"),
114 task_runner_(task_runner),
115 channel_manager_(channel_manager),
116 channel_(channel),
117 quit_closure_(quit_closure) {}
118 ~OtherThread() override {}
119
120 private:
121 void Run() override {
122 // See comment above constructor.
123 ASSERT_TRUE(channel_->HasOneRef());
124
125 ChannelId id = channel_manager_->AddChannel(make_scoped_refptr(channel_),
126 task_runner_);
127 EXPECT_NE(id, 0u);
128 // |ChannelManager| should take a ref.
129 EXPECT_FALSE(channel_->HasOneRef());
130
131 channel_manager_->WillShutdownChannel(id);
132 // |ChannelManager| should still have a ref.
133 EXPECT_FALSE(channel_->HasOneRef());
134
135 channel_manager_->ShutdownChannel(id);
136 // This doesn't happen synchronously, so we "wait" until it does.
137 // TODO(vtl): Possibly |Channel| should provide some notification of being
138 // shut down.
139 base::TimeTicks start_time(base::TimeTicks::Now());
140 for (;;) {
141 if (channel_->HasOneRef())
142 break;
143
144 // Check, instead of assert, since if things go wrong, dying is more
145 // reliable than tearing down.
146 CHECK_LT(base::TimeTicks::Now() - start_time,
147 TestTimeouts::action_timeout());
148 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(20));
149 }
150
151 CHECK(task_runner_->PostTask(FROM_HERE, quit_closure_));
152 }
153
154 scoped_refptr<base::TaskRunner> task_runner_;
155 ChannelManager* channel_manager_;
156 Channel* channel_;
157 base::Closure quit_closure_;
158
159 DISALLOW_COPY_AND_ASSIGN(OtherThread);
160 };
161
162 TEST_F(ChannelManagerTest, CallsFromOtherThread) {
163 ChannelManager cm;
164
165 // Hang on to a ref to the |Channel|, so that we can check that the
166 // |ChannelManager| takes/releases refs to it.
167 scoped_refptr<Channel> ch(new Channel(platform_support()));
168 ASSERT_TRUE(ch->HasOneRef());
169
170 embedder::PlatformChannelPair channel_pair;
171 ch->Init(RawChannel::Create(channel_pair.PassServerHandle()));
172
173 base::RunLoop run_loop;
174 OtherThread thread(base::MessageLoopProxy::current(), &cm, ch.get(),
175 run_loop.QuitClosure());
176 thread.Start();
177 run_loop.Run();
178 thread.Join();
179 }
180
181 } // namespace
182 } // namespace system
183 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/system/channel_manager.cc ('k') | mojo/edk/system/channel_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698