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

Side by Side Diff: mojo/public/cpp/system/tests/simple_watcher_unittest.cc

Issue 2725133002: Mojo: Armed Watchers (Closed)
Patch Set: . Created 3 years, 9 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 2016 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/public/cpp/system/simple_watcher.h"
6
7 #include <memory>
8
9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/macros.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/run_loop.h"
14 #include "base/threading/thread_task_runner_handle.h"
15 #include "mojo/public/c/system/types.h"
16 #include "mojo/public/cpp/system/message_pipe.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 namespace mojo {
20 namespace {
21
22 template <typename Handler>
23 void RunResultHandler(Handler f, MojoResult result) {
24 f(result);
25 }
26
27 template <typename Handler>
28 SimpleWatcher::ReadyCallback OnReady(Handler f) {
29 return base::Bind(&RunResultHandler<Handler>, f);
30 }
31
32 SimpleWatcher::ReadyCallback NotReached() {
33 return OnReady([](MojoResult) { NOTREACHED(); });
34 }
35
36 class SimpleWatcherTest : public testing::Test {
37 public:
38 SimpleWatcherTest() {}
39 ~SimpleWatcherTest() override {}
40
41 private:
42 base::MessageLoop message_loop_;
43
44 DISALLOW_COPY_AND_ASSIGN(SimpleWatcherTest);
45 };
46
47 TEST_F(SimpleWatcherTest, WatchBasic) {
48 ScopedMessagePipeHandle a, b;
49 CreateMessagePipe(nullptr, &a, &b);
50
51 bool notified = false;
52 base::RunLoop run_loop;
53 SimpleWatcher b_watcher(FROM_HERE, SimpleWatcher::ArmingPolicy::AUTOMATIC);
54 EXPECT_EQ(MOJO_RESULT_OK,
55 b_watcher.Watch(b.get(), MOJO_HANDLE_SIGNAL_READABLE,
56 OnReady([&](MojoResult result) {
57 EXPECT_EQ(MOJO_RESULT_OK, result);
58 notified = true;
59 run_loop.Quit();
60 })));
61 EXPECT_TRUE(b_watcher.IsWatching());
62
63 EXPECT_EQ(MOJO_RESULT_OK, WriteMessageRaw(a.get(), "hello", 5, nullptr, 0,
64 MOJO_WRITE_MESSAGE_FLAG_NONE));
65 run_loop.Run();
66 EXPECT_TRUE(notified);
67
68 b_watcher.Cancel();
69 }
70
71 TEST_F(SimpleWatcherTest, WatchUnsatisfiable) {
72 ScopedMessagePipeHandle a, b;
73 CreateMessagePipe(nullptr, &a, &b);
74 a.reset();
75
76 SimpleWatcher b_watcher(FROM_HERE, SimpleWatcher::ArmingPolicy::MANUAL);
77 EXPECT_EQ(
78 MOJO_RESULT_OK,
79 b_watcher.Watch(b.get(), MOJO_HANDLE_SIGNAL_READABLE, NotReached()));
80 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, b_watcher.Arm());
81 }
82
83 TEST_F(SimpleWatcherTest, WatchInvalidHandle) {
84 ScopedMessagePipeHandle a, b;
85 CreateMessagePipe(nullptr, &a, &b);
86 a.reset();
87 b.reset();
88
89 SimpleWatcher b_watcher(FROM_HERE, SimpleWatcher::ArmingPolicy::AUTOMATIC);
90 EXPECT_EQ(
91 MOJO_RESULT_INVALID_ARGUMENT,
92 b_watcher.Watch(b.get(), MOJO_HANDLE_SIGNAL_READABLE, NotReached()));
93 EXPECT_FALSE(b_watcher.IsWatching());
94 }
95
96 TEST_F(SimpleWatcherTest, Cancel) {
97 ScopedMessagePipeHandle a, b;
98 CreateMessagePipe(nullptr, &a, &b);
99
100 base::RunLoop run_loop;
101 SimpleWatcher b_watcher(FROM_HERE, SimpleWatcher::ArmingPolicy::AUTOMATIC);
102 EXPECT_EQ(
103 MOJO_RESULT_OK,
104 b_watcher.Watch(b.get(), MOJO_HANDLE_SIGNAL_READABLE, NotReached()));
105 EXPECT_TRUE(b_watcher.IsWatching());
106 b_watcher.Cancel();
107 EXPECT_FALSE(b_watcher.IsWatching());
108
109 // This should never trigger the watcher.
110 EXPECT_EQ(MOJO_RESULT_OK, WriteMessageRaw(a.get(), "hello", 5, nullptr, 0,
111 MOJO_WRITE_MESSAGE_FLAG_NONE));
112
113 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
114 run_loop.QuitClosure());
115 run_loop.Run();
116 }
117
118 TEST_F(SimpleWatcherTest, CancelOnClose) {
119 ScopedMessagePipeHandle a, b;
120 CreateMessagePipe(nullptr, &a, &b);
121
122 base::RunLoop run_loop;
123 SimpleWatcher b_watcher(FROM_HERE, SimpleWatcher::ArmingPolicy::AUTOMATIC);
124 EXPECT_EQ(MOJO_RESULT_OK,
125 b_watcher.Watch(b.get(), MOJO_HANDLE_SIGNAL_READABLE,
126 OnReady([&](MojoResult result) {
127 EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
128 run_loop.Quit();
129 })));
130 EXPECT_TRUE(b_watcher.IsWatching());
131
132 // This should trigger the watcher above.
133 b.reset();
134
135 run_loop.Run();
136
137 EXPECT_FALSE(b_watcher.IsWatching());
138 }
139
140 TEST_F(SimpleWatcherTest, CancelOnDestruction) {
141 ScopedMessagePipeHandle a, b;
142 CreateMessagePipe(nullptr, &a, &b);
143 base::RunLoop run_loop;
144 {
145 SimpleWatcher b_watcher(FROM_HERE, SimpleWatcher::ArmingPolicy::AUTOMATIC);
146 EXPECT_EQ(
147 MOJO_RESULT_OK,
148 b_watcher.Watch(b.get(), MOJO_HANDLE_SIGNAL_READABLE, NotReached()));
149 EXPECT_TRUE(b_watcher.IsWatching());
150
151 // |b_watcher| should be cancelled when it goes out of scope.
152 }
153
154 // This should never trigger the watcher above.
155 EXPECT_EQ(MOJO_RESULT_OK, WriteMessageRaw(a.get(), "hello", 5, nullptr, 0,
156 MOJO_WRITE_MESSAGE_FLAG_NONE));
157 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
158 run_loop.QuitClosure());
159 run_loop.Run();
160 }
161
162 TEST_F(SimpleWatcherTest, CloseAndCancel) {
163 ScopedMessagePipeHandle a, b;
164 CreateMessagePipe(nullptr, &a, &b);
165
166 SimpleWatcher b_watcher(FROM_HERE, SimpleWatcher::ArmingPolicy::AUTOMATIC);
167 EXPECT_EQ(MOJO_RESULT_OK,
168 b_watcher.Watch(b.get(), MOJO_HANDLE_SIGNAL_READABLE,
169 OnReady([](MojoResult result) { FAIL(); })));
170 EXPECT_TRUE(b_watcher.IsWatching());
171
172 // This should trigger the watcher above...
173 b.reset();
174 // ...but the watcher is cancelled first.
175 b_watcher.Cancel();
176
177 EXPECT_FALSE(b_watcher.IsWatching());
178
179 base::RunLoop().RunUntilIdle();
180 }
181
182 TEST_F(SimpleWatcherTest, UnarmedCancel) {
183 ScopedMessagePipeHandle a, b;
184 CreateMessagePipe(nullptr, &a, &b);
185
186 SimpleWatcher b_watcher(FROM_HERE, SimpleWatcher::ArmingPolicy::MANUAL);
187 base::RunLoop loop;
188 EXPECT_EQ(MOJO_RESULT_OK,
189 b_watcher.Watch(b.get(), MOJO_HANDLE_SIGNAL_READABLE,
190 base::Bind(
191 [](base::RunLoop* loop, MojoResult result) {
192 EXPECT_EQ(result, MOJO_RESULT_CANCELLED);
193 loop->Quit();
194 },
195 &loop)));
196
197 // This message write will not wake up the watcher since the watcher isn't
198 // armed. Instead, the cancellation will dispatch due to the reset below.
199 EXPECT_EQ(MOJO_RESULT_OK, WriteMessageRaw(a.get(), "hello", 5, nullptr, 0,
200 MOJO_WRITE_MESSAGE_FLAG_NONE));
201 b.reset();
202 loop.Run();
203 }
204
205 TEST_F(SimpleWatcherTest, ManualArming) {
206 ScopedMessagePipeHandle a, b;
207 CreateMessagePipe(nullptr, &a, &b);
208
209 SimpleWatcher b_watcher(FROM_HERE, SimpleWatcher::ArmingPolicy::MANUAL);
210 base::RunLoop loop;
211 EXPECT_EQ(MOJO_RESULT_OK,
212 b_watcher.Watch(b.get(), MOJO_HANDLE_SIGNAL_READABLE,
213 base::Bind(
214 [](base::RunLoop* loop, MojoResult result) {
215 EXPECT_EQ(result, MOJO_RESULT_OK);
216 loop->Quit();
217 },
218 &loop)));
219 EXPECT_EQ(MOJO_RESULT_OK, b_watcher.Arm());
220
221 EXPECT_EQ(MOJO_RESULT_OK, WriteMessageRaw(a.get(), "hello", 5, nullptr, 0,
222 MOJO_WRITE_MESSAGE_FLAG_NONE));
223 loop.Run();
224 }
225
226 TEST_F(SimpleWatcherTest, ManualArmOrNotifyWhileSignaled) {
227 ScopedMessagePipeHandle a, b;
228 CreateMessagePipe(nullptr, &a, &b);
229
230 base::RunLoop loop1;
231 SimpleWatcher b_watcher1(FROM_HERE, SimpleWatcher::ArmingPolicy::MANUAL);
232 bool notified1 = false;
233 EXPECT_EQ(MOJO_RESULT_OK,
234 b_watcher1.Watch(
235 b.get(), MOJO_HANDLE_SIGNAL_READABLE,
236 base::Bind(
237 [](base::RunLoop* loop, bool* notified, MojoResult result) {
238 EXPECT_EQ(result, MOJO_RESULT_OK);
239 *notified = true;
240 loop->Quit();
241 },
242 &loop1, &notified1)));
243
244 base::RunLoop loop2;
245 SimpleWatcher b_watcher2(FROM_HERE, SimpleWatcher::ArmingPolicy::MANUAL);
246 bool notified2 = false;
247 EXPECT_EQ(MOJO_RESULT_OK,
248 b_watcher2.Watch(
249 b.get(), MOJO_HANDLE_SIGNAL_READABLE,
250 base::Bind(
251 [](base::RunLoop* loop, bool* notified, MojoResult result) {
252 EXPECT_EQ(result, MOJO_RESULT_OK);
253 *notified = true;
254 loop->Quit();
255 },
256 &loop2, &notified2)));
257
258 // First ensure that |b| is readable.
259 EXPECT_EQ(MOJO_RESULT_OK, b_watcher1.Arm());
260 EXPECT_EQ(MOJO_RESULT_OK, WriteMessageRaw(a.get(), "hello", 5, nullptr, 0,
261 MOJO_WRITE_MESSAGE_FLAG_NONE));
262 loop1.Run();
263
264 EXPECT_TRUE(notified1);
265 EXPECT_FALSE(notified2);
266 notified1 = false;
267
268 // Now verify that ArmOrNotify results in a notification.
269 b_watcher2.ArmOrNotify();
270 loop2.Run();
271
272 EXPECT_FALSE(notified1);
273 EXPECT_TRUE(notified2);
274 }
275
276 } // namespace
277 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698