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

Side by Side Diff: mojo/system/message_pipe_unittest.cc

Issue 23621056: Initial in-process implementation of some Mojo primitives. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: wip18.1 Created 7 years, 2 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 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/system/message_pipe.h"
6
7 #include <limits>
8
9 #include "base/memory/ref_counted.h"
10 #include "base/threading/platform_thread.h" // For |Sleep()|.
11 #include "base/time/time.h"
12 #include "mojo/system/waiter.h"
13 #include "mojo/system/waiter_test_utils.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace mojo {
17 namespace system {
18 namespace {
19
20 // Tests:
21 // - only default flags
22 // - reading messages from a port
23 // - when there are no/one/two messages available for that port
24 // - with buffer size 0 (and null buffer) -- should get size
25 // - with too-small buffer -- should get size
26 // - also verify that buffers aren't modified when/where they shouldn't be
27 // - writing messages to a port
28 // - in the obvious scenarios (as above)
29 // - to a port that's been closed
30 // - writing a message to a port, closing the other (would be the source) port,
31 // and reading it
32 TEST(MessagePipeTest, Basic) {
33 scoped_refptr<MessagePipe> mp(new MessagePipe());
34
35 int32_t buffer[2];
36 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer));
37 uint32_t buffer_size;
38
39 // Nothing to read yet on port 0.
40 buffer[0] = 123;
41 buffer[1] = 456;
42 buffer_size = kBufferSize;
43 EXPECT_EQ(MOJO_RESULT_NOT_FOUND,
44 mp->ReadMessage(0,
45 buffer, &buffer_size,
46 NULL, NULL,
47 MOJO_READ_MESSAGE_FLAG_NONE));
48 EXPECT_EQ(kBufferSize, buffer_size);
49 EXPECT_EQ(123, buffer[0]);
50 EXPECT_EQ(456, buffer[1]);
51
52 // Ditto for port 1.
53 buffer[0] = 123;
54 buffer[1] = 456;
55 buffer_size = kBufferSize;
56 EXPECT_EQ(MOJO_RESULT_NOT_FOUND,
57 mp->ReadMessage(1,
58 buffer, &buffer_size,
59 NULL, NULL,
60 MOJO_READ_MESSAGE_FLAG_NONE));
61
62 // Write from port 1 (to port 0).
63 buffer[0] = 789012345;
64 buffer[1] = 0;
65 EXPECT_EQ(MOJO_RESULT_OK,
66 mp->WriteMessage(1,
67 buffer, static_cast<uint32_t>(sizeof(buffer[0])),
68 NULL, 0,
69 MOJO_WRITE_MESSAGE_FLAG_NONE));
70
71 // Read from port 0.
72 buffer[0] = 123;
73 buffer[1] = 456;
74 buffer_size = kBufferSize;
75 EXPECT_EQ(MOJO_RESULT_OK,
76 mp->ReadMessage(0,
77 buffer, &buffer_size,
78 NULL, NULL,
79 MOJO_READ_MESSAGE_FLAG_NONE));
80 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
81 EXPECT_EQ(789012345, buffer[0]);
82 EXPECT_EQ(456, buffer[1]);
83
84 // Read again from port 0 -- it should be empty.
85 buffer_size = kBufferSize;
86 EXPECT_EQ(MOJO_RESULT_NOT_FOUND,
87 mp->ReadMessage(0,
88 buffer, &buffer_size,
89 NULL, NULL,
90 MOJO_READ_MESSAGE_FLAG_NONE));
91
92 // Write two messages from port 0 (to port 1).
93 buffer[0] = 123456789;
94 buffer[1] = 0;
95 EXPECT_EQ(MOJO_RESULT_OK,
96 mp->WriteMessage(0,
97 buffer, static_cast<uint32_t>(sizeof(buffer[0])),
98 NULL, 0,
99 MOJO_WRITE_MESSAGE_FLAG_NONE));
100 buffer[0] = 234567890;
101 buffer[1] = 0;
102 EXPECT_EQ(MOJO_RESULT_OK,
103 mp->WriteMessage(0,
104 buffer, static_cast<uint32_t>(sizeof(buffer[0])),
105 NULL, 0,
106 MOJO_WRITE_MESSAGE_FLAG_NONE));
107
108 // Read from port 1 with buffer size 0 (should get the size of next message).
109 // Also test that giving a null buffer is okay when the buffer size is 0.
110 buffer_size = 0;
111 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
112 mp->ReadMessage(1,
113 NULL, &buffer_size,
114 NULL, NULL,
115 MOJO_READ_MESSAGE_FLAG_NONE));
116 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
117
118 // Read from port 1 with buffer size 1 (too small; should get the size of next
119 // message).
120 buffer[0] = 123;
121 buffer[1] = 456;
122 buffer_size = 1;
123 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
124 mp->ReadMessage(1,
125 buffer, &buffer_size,
126 NULL, NULL,
127 MOJO_READ_MESSAGE_FLAG_NONE));
128 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
129 EXPECT_EQ(123, buffer[0]);
130 EXPECT_EQ(456, buffer[1]);
131
132 // Read from port 1.
133 buffer[0] = 123;
134 buffer[1] = 456;
135 buffer_size = kBufferSize;
136 EXPECT_EQ(MOJO_RESULT_OK,
137 mp->ReadMessage(1,
138 buffer, &buffer_size,
139 NULL, NULL,
140 MOJO_READ_MESSAGE_FLAG_NONE));
141 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
142 EXPECT_EQ(123456789, buffer[0]);
143 EXPECT_EQ(456, buffer[1]);
144
145 // Read again from port 1.
146 buffer[0] = 123;
147 buffer[1] = 456;
148 buffer_size = kBufferSize;
149 EXPECT_EQ(MOJO_RESULT_OK,
150 mp->ReadMessage(1,
151 buffer, &buffer_size,
152 NULL, NULL,
153 MOJO_READ_MESSAGE_FLAG_NONE));
154 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
155 EXPECT_EQ(234567890, buffer[0]);
156 EXPECT_EQ(456, buffer[1]);
157
158 // Read again from port 1 -- it should be empty.
159 buffer_size = kBufferSize;
160 EXPECT_EQ(MOJO_RESULT_NOT_FOUND,
161 mp->ReadMessage(1,
162 buffer, &buffer_size,
163 NULL, NULL,
164 MOJO_READ_MESSAGE_FLAG_NONE));
165
166 // Write from port 0 (to port 1).
167 buffer[0] = 345678901;
168 buffer[1] = 0;
169 EXPECT_EQ(MOJO_RESULT_OK,
170 mp->WriteMessage(0,
171 buffer, static_cast<uint32_t>(sizeof(buffer[0])),
172 NULL, 0,
173 MOJO_WRITE_MESSAGE_FLAG_NONE));
174
175 // Close port 0.
176 mp->Close(0);
177
178 // Try to write from port 1 (to port 0).
179 buffer[0] = 456789012;
180 buffer[1] = 0;
181 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
182 mp->WriteMessage(1,
183 buffer, static_cast<uint32_t>(sizeof(buffer[0])),
184 NULL, 0,
185 MOJO_WRITE_MESSAGE_FLAG_NONE));
186
187 // Read from port 1; should still get message (even though port 0 was closed).
188 buffer[0] = 123;
189 buffer[1] = 456;
190 buffer_size = kBufferSize;
191 EXPECT_EQ(MOJO_RESULT_OK,
192 mp->ReadMessage(1,
193 buffer, &buffer_size,
194 NULL, NULL,
195 MOJO_READ_MESSAGE_FLAG_NONE));
196 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
197 EXPECT_EQ(345678901, buffer[0]);
198 EXPECT_EQ(456, buffer[1]);
199
200 // Read again from port 1 -- it should be empty.
201 buffer_size = kBufferSize;
202 EXPECT_EQ(MOJO_RESULT_NOT_FOUND,
203 mp->ReadMessage(1,
204 buffer, &buffer_size,
205 NULL, NULL,
206 MOJO_READ_MESSAGE_FLAG_NONE));
207
208 mp->Close(1);
209 }
210
211 TEST(MessagePipeTest, DiscardMode) {
212 scoped_refptr<MessagePipe> mp(new MessagePipe());
213
214 int32_t buffer[2];
215 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer));
216 uint32_t buffer_size;
217
218 // Write from port 1 (to port 0).
219 buffer[0] = 789012345;
220 buffer[1] = 0;
221 EXPECT_EQ(MOJO_RESULT_OK,
222 mp->WriteMessage(1,
223 buffer, static_cast<uint32_t>(sizeof(buffer[0])),
224 NULL, 0,
225 MOJO_WRITE_MESSAGE_FLAG_NONE));
226
227 // Read/discard from port 0 (no buffer); get size.
228 buffer_size = 0;
229 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
230 mp->ReadMessage(0,
231 NULL, &buffer_size,
232 NULL, NULL,
233 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
234 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
235
236 // Read again from port 0 -- it should be empty.
237 buffer_size = kBufferSize;
238 EXPECT_EQ(MOJO_RESULT_NOT_FOUND,
239 mp->ReadMessage(0,
240 buffer, &buffer_size,
241 NULL, NULL,
242 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
243
244 // Write from port 1 (to port 0).
245 buffer[0] = 890123456;
246 buffer[1] = 0;
247 EXPECT_EQ(MOJO_RESULT_OK,
248 mp->WriteMessage(1,
249 buffer, static_cast<uint32_t>(sizeof(buffer[0])),
250 NULL, 0,
251 MOJO_WRITE_MESSAGE_FLAG_NONE));
252
253 // Read from port 0 (buffer big enough).
254 buffer[0] = 123;
255 buffer[1] = 456;
256 buffer_size = kBufferSize;
257 EXPECT_EQ(MOJO_RESULT_OK,
258 mp->ReadMessage(0,
259 buffer, &buffer_size,
260 NULL, NULL,
261 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
262 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
263 EXPECT_EQ(890123456, buffer[0]);
264 EXPECT_EQ(456, buffer[1]);
265
266 // Read again from port 0 -- it should be empty.
267 buffer_size = kBufferSize;
268 EXPECT_EQ(MOJO_RESULT_NOT_FOUND,
269 mp->ReadMessage(0,
270 buffer, &buffer_size,
271 NULL, NULL,
272 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
273
274 // Write from port 1 (to port 0).
275 buffer[0] = 901234567;
276 buffer[1] = 0;
277 EXPECT_EQ(MOJO_RESULT_OK,
278 mp->WriteMessage(1,
279 buffer, static_cast<uint32_t>(sizeof(buffer[0])),
280 NULL, 0,
281 MOJO_WRITE_MESSAGE_FLAG_NONE));
282
283 // Read/discard from port 0 (buffer too small); get size.
284 buffer_size = 1;
285 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
286 mp->ReadMessage(0,
287 buffer, &buffer_size,
288 NULL, NULL,
289 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
290 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
291
292 // Read again from port 0 -- it should be empty.
293 buffer_size = kBufferSize;
294 EXPECT_EQ(MOJO_RESULT_NOT_FOUND,
295 mp->ReadMessage(0,
296 buffer, &buffer_size,
297 NULL, NULL,
298 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
299
300 // Write from port 1 (to port 0).
301 buffer[0] = 123456789;
302 buffer[1] = 0;
303 EXPECT_EQ(MOJO_RESULT_OK,
304 mp->WriteMessage(1,
305 buffer, static_cast<uint32_t>(sizeof(buffer[0])),
306 NULL, 0,
307 MOJO_WRITE_MESSAGE_FLAG_NONE));
308
309 // Discard from port 0.
310 buffer_size = 1;
311 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
312 mp->ReadMessage(0,
313 NULL, NULL,
314 NULL, NULL,
315 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
316
317 // Read again from port 0 -- it should be empty.
318 buffer_size = kBufferSize;
319 EXPECT_EQ(MOJO_RESULT_NOT_FOUND,
320 mp->ReadMessage(0,
321 buffer, &buffer_size,
322 NULL, NULL,
323 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
324
325 mp->Close(0);
326 mp->Close(1);
327 }
328
329 TEST(MessagePipeTest, InvalidParams) {
330 scoped_refptr<MessagePipe> mp(new MessagePipe());
331
332 char buffer[1];
333 MojoHandle handles[1];
334
335 // |WriteMessage|:
336 // Null buffer with nonzero buffer size.
337 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
338 mp->WriteMessage(0,
339 NULL, 1,
340 NULL, 0,
341 MOJO_WRITE_MESSAGE_FLAG_NONE));
342 // Huge buffer size.
343 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
344 mp->WriteMessage(0,
345 buffer, std::numeric_limits<uint32_t>::max(),
346 NULL, 0,
347 MOJO_WRITE_MESSAGE_FLAG_NONE));
348
349 // Null handles with nonzero handle count.
350 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
351 mp->WriteMessage(0,
352 buffer, sizeof(buffer),
353 NULL, 1,
354 MOJO_WRITE_MESSAGE_FLAG_NONE));
355 // Huge handle count (implausibly big on some systems -- more than can be
356 // stored in a 32-bit address space).
357 // Note: This may return either |MOJO_RESULT_INVALID_ARGUMENT| or
358 // |MOJO_RESULT_OUT_OF_RANGE|, depending on whether it's plausible or not.
359 EXPECT_NE(MOJO_RESULT_OK,
360 mp->WriteMessage(0,
361 buffer, sizeof(buffer),
362 handles, std::numeric_limits<uint32_t>::max(),
363 MOJO_WRITE_MESSAGE_FLAG_NONE));
364 // Huge handle count (plausibly big).
365 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
366 mp->WriteMessage(0,
367 buffer, sizeof(buffer),
368 handles, std::numeric_limits<uint32_t>::max() /
369 sizeof(handles[0]),
370 MOJO_WRITE_MESSAGE_FLAG_NONE));
371
372 // |ReadMessage|:
373 // Null buffer with nonzero buffer size.
374 uint32_t buffer_size = 1;
375 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
376 mp->ReadMessage(0,
377 NULL, &buffer_size,
378 NULL, NULL,
379 MOJO_READ_MESSAGE_FLAG_NONE));
380 // Null handles with nonzero handle count.
381 buffer_size = static_cast<uint32_t>(sizeof(buffer));
382 uint32_t handle_count = 1;
383 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
384 mp->ReadMessage(0,
385 buffer, &buffer_size,
386 NULL, &handle_count,
387 MOJO_READ_MESSAGE_FLAG_NONE));
388
389 mp->Close(0);
390 mp->Close(1);
391 }
392
393 TEST(MessagePipeTest, BasicWaiting) {
394 scoped_refptr<MessagePipe> mp(new MessagePipe());
395 Waiter waiter;
396
397 int32_t buffer[1];
398 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer));
399 uint32_t buffer_size;
400
401 // Always writable (until the other port is closed).
402 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
403 mp->AddWaiter(0, &waiter, MOJO_WAIT_FLAG_WRITABLE, 0));
404 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
405 mp->AddWaiter(0,
406 &waiter,
407 MOJO_WAIT_FLAG_READABLE | MOJO_WAIT_FLAG_WRITABLE,
408 0));
409
410 // Not yet readable.
411 EXPECT_EQ(MOJO_RESULT_OK,
412 mp->AddWaiter(0, &waiter, MOJO_WAIT_FLAG_READABLE, 1));
413 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0));
414 mp->RemoveWaiter(0, &waiter);
415
416 // Write from port 0 (to port 1), to make port 1 readable.
417 buffer[0] = 123456789;
418 EXPECT_EQ(MOJO_RESULT_OK,
419 mp->WriteMessage(0,
420 buffer, kBufferSize,
421 NULL, 0,
422 MOJO_WRITE_MESSAGE_FLAG_NONE));
423
424 // Port 1 should already be readable now.
425 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
426 mp->AddWaiter(1, &waiter, MOJO_WAIT_FLAG_READABLE, 2));
427 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
428 mp->AddWaiter(1,
429 &waiter,
430 MOJO_WAIT_FLAG_READABLE | MOJO_WAIT_FLAG_WRITABLE,
431 0));
432 // ... and still writable.
433 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
434 mp->AddWaiter(1, &waiter, MOJO_WAIT_FLAG_WRITABLE, 3));
435
436 // Close port 0.
437 mp->Close(0);
438
439 // Now port 1 should not be writable.
440 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
441 mp->AddWaiter(1, &waiter, MOJO_WAIT_FLAG_WRITABLE, 4));
442
443 // But it should still be readable.
444 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
445 mp->AddWaiter(1, &waiter, MOJO_WAIT_FLAG_READABLE, 5));
446
447 // Read from port 1.
448 buffer[0] = 0;
449 buffer_size = kBufferSize;
450 EXPECT_EQ(MOJO_RESULT_OK,
451 mp->ReadMessage(1,
452 buffer, &buffer_size,
453 NULL, NULL,
454 MOJO_READ_MESSAGE_FLAG_NONE));
455 EXPECT_EQ(123456789, buffer[0]);
456
457 // Now port 1 should no longer be readable.
458 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
459 mp->AddWaiter(1, &waiter, MOJO_WAIT_FLAG_READABLE, 6));
460
461 mp->Close(1);
462 }
463
464 TEST(MessagePipeTest, ThreadedWaiting) {
465 int32_t buffer[1];
466 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer));
467
468 MojoResult result;
469
470 // Write to wake up waiter waiting for read.
471 {
472 scoped_refptr<MessagePipe> mp(new MessagePipe());
473 test::SimpleWaiterThread thread(&result);
474
475 EXPECT_EQ(MOJO_RESULT_OK,
476 mp->AddWaiter(1, thread.waiter(), MOJO_WAIT_FLAG_READABLE, 0));
477 thread.Start();
478
479 buffer[0] = 123456789;
480 // Write from port 0 (to port 1), which should wake up the waiter.
481 EXPECT_EQ(MOJO_RESULT_OK,
482 mp->WriteMessage(0,
483 buffer, kBufferSize,
484 NULL, 0,
485 MOJO_WRITE_MESSAGE_FLAG_NONE));
486
487 mp->RemoveWaiter(1, thread.waiter());
488
489 mp->Close(0);
490 mp->Close(1);
491 } // Joins |thread|.
492 // The waiter should have woken up successfully.
493 EXPECT_EQ(0, result);
494
495 // Close to cancel waiter.
496 {
497 scoped_refptr<MessagePipe> mp(new MessagePipe());
498 test::SimpleWaiterThread thread(&result);
499
500 EXPECT_EQ(MOJO_RESULT_OK,
501 mp->AddWaiter(1, thread.waiter(), MOJO_WAIT_FLAG_READABLE, 0));
502 thread.Start();
503
504 // Close port 1 first -- this should result in the waiter being cancelled.
505 mp->CancelAllWaiters(1);
506 mp->Close(1);
507
508 // Port 1 is closed, so |Dispatcher::RemoveWaiter()| wouldn't call into the
509 // |MessagePipe| to remove any waiter.
510
511 mp->Close(0);
512 } // Joins |thread|.
513 EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
514
515 // Close to make waiter un-wake-up-able.
516 {
517 scoped_refptr<MessagePipe> mp(new MessagePipe());
518 test::SimpleWaiterThread thread(&result);
519
520 EXPECT_EQ(MOJO_RESULT_OK,
521 mp->AddWaiter(1, thread.waiter(), MOJO_WAIT_FLAG_READABLE, 0));
522 thread.Start();
523
524 // Close port 0 first -- this should wake the waiter up, since port 1 will
525 // never be readable.
526 mp->CancelAllWaiters(0);
527 mp->Close(0);
528
529 mp->RemoveWaiter(1, thread.waiter());
530
531 mp->CancelAllWaiters(1);
532 mp->Close(1);
533 } // Joins |thread|.
534 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
535 }
536
537 } // namespace
538 } // namespace system
539 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698