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

Side by Side Diff: mojo/public/cpp/bindings/tests/router_unittest.cc

Issue 2532053004: Mojo C++ bindings: remove the single-threaded Router. (Closed)
Patch Set: . Created 4 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
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/public/cpp/bindings/lib/router.h"
6
7 #include <utility>
8
9 #include "base/bind.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/run_loop.h"
12 #include "base/threading/thread_task_runner_handle.h"
13 #include "mojo/public/cpp/bindings/tests/message_queue.h"
14 #include "mojo/public/cpp/bindings/tests/router_test_util.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 namespace mojo {
18 namespace test {
19 namespace {
20
21 class RouterTest : public testing::Test {
22 public:
23 RouterTest() {}
24
25 void SetUp() override {
26 CreateMessagePipe(nullptr, &handle0_, &handle1_);
27 }
28
29 void TearDown() override {}
30
31 void PumpMessages() { base::RunLoop().RunUntilIdle(); }
32
33 protected:
34 ScopedMessagePipeHandle handle0_;
35 ScopedMessagePipeHandle handle1_;
36
37 private:
38 base::MessageLoop loop_;
39 };
40
41 TEST_F(RouterTest, BasicRequestResponse) {
42 internal::Router router0(std::move(handle0_), FilterChain(), false,
43 base::ThreadTaskRunnerHandle::Get(), 0u);
44 internal::Router router1(std::move(handle1_), FilterChain(), false,
45 base::ThreadTaskRunnerHandle::Get(), 0u);
46
47 ResponseGenerator generator;
48 router1.set_incoming_receiver(&generator);
49
50 Message request;
51 AllocRequestMessage(1, "hello", &request);
52
53 MessageQueue message_queue;
54 base::RunLoop run_loop;
55 router0.AcceptWithResponder(
56 &request, new MessageAccumulator(&message_queue, run_loop.QuitClosure()));
57
58 run_loop.Run();
59
60 EXPECT_FALSE(message_queue.IsEmpty());
61
62 Message response;
63 message_queue.Pop(&response);
64
65 EXPECT_EQ(std::string("hello world!"),
66 std::string(reinterpret_cast<const char*>(response.payload())));
67
68 // Send a second message on the pipe.
69 Message request2;
70 AllocRequestMessage(1, "hello again", &request2);
71
72 base::RunLoop run_loop2;
73 router0.AcceptWithResponder(
74 &request2,
75 new MessageAccumulator(&message_queue, run_loop2.QuitClosure()));
76
77 run_loop2.Run();
78
79 EXPECT_FALSE(message_queue.IsEmpty());
80
81 message_queue.Pop(&response);
82
83 EXPECT_EQ(std::string("hello again world!"),
84 std::string(reinterpret_cast<const char*>(response.payload())));
85 }
86
87 TEST_F(RouterTest, BasicRequestResponse_Synchronous) {
88 internal::Router router0(std::move(handle0_), FilterChain(), false,
89 base::ThreadTaskRunnerHandle::Get(), 0u);
90 internal::Router router1(std::move(handle1_), FilterChain(), false,
91 base::ThreadTaskRunnerHandle::Get(), 0u);
92
93 ResponseGenerator generator;
94 router1.set_incoming_receiver(&generator);
95
96 Message request;
97 AllocRequestMessage(1, "hello", &request);
98
99 MessageQueue message_queue;
100 router0.AcceptWithResponder(&request, new MessageAccumulator(&message_queue));
101
102 router1.WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE);
103 router0.WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE);
104
105 EXPECT_FALSE(message_queue.IsEmpty());
106
107 Message response;
108 message_queue.Pop(&response);
109
110 EXPECT_EQ(std::string("hello world!"),
111 std::string(reinterpret_cast<const char*>(response.payload())));
112
113 // Send a second message on the pipe.
114 Message request2;
115 AllocRequestMessage(1, "hello again", &request2);
116
117 router0.AcceptWithResponder(&request2,
118 new MessageAccumulator(&message_queue));
119
120 router1.WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE);
121 router0.WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE);
122
123 EXPECT_FALSE(message_queue.IsEmpty());
124
125 message_queue.Pop(&response);
126
127 EXPECT_EQ(std::string("hello again world!"),
128 std::string(reinterpret_cast<const char*>(response.payload())));
129 }
130
131 // Tests Router using the LazyResponseGenerator. The responses will not be
132 // sent until after the requests have been accepted.
133 TEST_F(RouterTest, LazyResponses) {
134 internal::Router router0(std::move(handle0_), FilterChain(), false,
135 base::ThreadTaskRunnerHandle::Get(), 0u);
136 internal::Router router1(std::move(handle1_), FilterChain(), false,
137 base::ThreadTaskRunnerHandle::Get(), 0u);
138
139 base::RunLoop run_loop;
140 LazyResponseGenerator generator(run_loop.QuitClosure());
141 router1.set_incoming_receiver(&generator);
142
143 Message request;
144 AllocRequestMessage(1, "hello", &request);
145
146 MessageQueue message_queue;
147 base::RunLoop run_loop2;
148 router0.AcceptWithResponder(
149 &request,
150 new MessageAccumulator(&message_queue, run_loop2.QuitClosure()));
151 run_loop.Run();
152
153 // The request has been received but the response has not been sent yet.
154 EXPECT_TRUE(message_queue.IsEmpty());
155
156 // Send the response.
157 EXPECT_TRUE(generator.responder_is_valid());
158 generator.CompleteWithResponse();
159 run_loop2.Run();
160
161 // Check the response.
162 EXPECT_FALSE(message_queue.IsEmpty());
163 Message response;
164 message_queue.Pop(&response);
165 EXPECT_EQ(std::string("hello world!"),
166 std::string(reinterpret_cast<const char*>(response.payload())));
167
168 // Send a second message on the pipe.
169 base::RunLoop run_loop3;
170 LazyResponseGenerator generator2(run_loop3.QuitClosure());
171
172 router1.set_incoming_receiver(&generator2);
173 Message request2;
174 AllocRequestMessage(1, "hello again", &request2);
175
176 base::RunLoop run_loop4;
177 router0.AcceptWithResponder(
178 &request2,
179 new MessageAccumulator(&message_queue, run_loop4.QuitClosure()));
180 run_loop3.Run();
181
182 // The request has been received but the response has not been sent yet.
183 EXPECT_TRUE(message_queue.IsEmpty());
184
185 // Send the second response.
186 EXPECT_TRUE(generator2.responder_is_valid());
187 generator2.CompleteWithResponse();
188 run_loop4.Run();
189
190 // Check the second response.
191 EXPECT_FALSE(message_queue.IsEmpty());
192 message_queue.Pop(&response);
193 EXPECT_EQ(std::string("hello again world!"),
194 std::string(reinterpret_cast<const char*>(response.payload())));
195 }
196
197 void ForwardErrorHandler(bool* called, const base::Closure& callback) {
198 *called = true;
199 callback.Run();
200 }
201
202 // Tests that if the receiving application destroys the responder_ without
203 // sending a response, then we trigger connection error at both sides. Moreover,
204 // both sides still appear to have a valid message pipe handle bound.
205 TEST_F(RouterTest, MissingResponses) {
206 base::RunLoop run_loop0, run_loop1;
207 internal::Router router0(std::move(handle0_), FilterChain(), false,
208 base::ThreadTaskRunnerHandle::Get(), 0u);
209 bool error_handler_called0 = false;
210 router0.set_connection_error_handler(
211 base::Bind(&ForwardErrorHandler, &error_handler_called0,
212 run_loop0.QuitClosure()));
213
214 internal::Router router1(std::move(handle1_), FilterChain(), false,
215 base::ThreadTaskRunnerHandle::Get(), 0u);
216 bool error_handler_called1 = false;
217 router1.set_connection_error_handler(
218 base::Bind(&ForwardErrorHandler, &error_handler_called1,
219 run_loop1.QuitClosure()));
220
221 base::RunLoop run_loop3;
222 LazyResponseGenerator generator(run_loop3.QuitClosure());
223 router1.set_incoming_receiver(&generator);
224 router1.set_incoming_receiver(&generator);
225
226 Message request;
227 AllocRequestMessage(1, "hello", &request);
228
229 MessageQueue message_queue;
230 router0.AcceptWithResponder(&request, new MessageAccumulator(&message_queue));
231 run_loop3.Run();
232
233 // The request has been received but no response has been sent.
234 EXPECT_TRUE(message_queue.IsEmpty());
235
236 // Destroy the responder MessagerReceiver but don't send any response.
237 generator.CompleteWithoutResponse();
238 run_loop0.Run();
239 run_loop1.Run();
240
241 // Check that no response was received.
242 EXPECT_TRUE(message_queue.IsEmpty());
243
244 // Connection error handler is called at both sides.
245 EXPECT_TRUE(error_handler_called0);
246 EXPECT_TRUE(error_handler_called1);
247
248 // The error flag is set at both sides.
249 EXPECT_TRUE(router0.encountered_error());
250 EXPECT_TRUE(router1.encountered_error());
251
252 // The message pipe handle is valid at both sides.
253 EXPECT_TRUE(router0.is_valid());
254 EXPECT_TRUE(router1.is_valid());
255 }
256
257 TEST_F(RouterTest, LateResponse) {
258 // Test that things won't blow up if we try to send a message to a
259 // MessageReceiver, which was given to us via AcceptWithResponder,
260 // after the router has gone away.
261
262 base::RunLoop run_loop;
263 LazyResponseGenerator generator(run_loop.QuitClosure());
264 {
265 internal::Router router0(std::move(handle0_), FilterChain(), false,
266 base::ThreadTaskRunnerHandle::Get(), 0u);
267 internal::Router router1(std::move(handle1_), FilterChain(), false,
268 base::ThreadTaskRunnerHandle::Get(), 0u);
269
270 router1.set_incoming_receiver(&generator);
271
272 Message request;
273 AllocRequestMessage(1, "hello", &request);
274
275 MessageQueue message_queue;
276 router0.AcceptWithResponder(&request,
277 new MessageAccumulator(&message_queue));
278
279 run_loop.Run();
280
281 EXPECT_TRUE(generator.has_responder());
282 }
283
284 EXPECT_FALSE(generator.responder_is_valid());
285 generator.CompleteWithResponse(); // This should end up doing nothing.
286 }
287
288 } // namespace
289 } // namespace test
290 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/public/cpp/bindings/tests/bindings_perftest.cc ('k') | mojo/public/cpp/bindings/tests/validation_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698