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

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: build fix 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_RESOURCE_EXHAUSTED,
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_RESOURCE_EXHAUSTED,
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_RESOURCE_EXHAUSTED,
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_RESOURCE_EXHAUSTED,
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_RESOURCE_EXHAUSTED,
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_RESOURCE_EXHAUSTED,
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_RESOURCE_EXHAUSTED|, depending on whether it's plausible or
359 // not.
360 EXPECT_NE(MOJO_RESULT_OK,
361 mp->WriteMessage(0,
362 buffer, sizeof(buffer),
363 handles, std::numeric_limits<uint32_t>::max(),
364 MOJO_WRITE_MESSAGE_FLAG_NONE));
365 // Huge handle count (plausibly big).
366 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
367 mp->WriteMessage(0,
368 buffer, sizeof(buffer),
369 handles, std::numeric_limits<uint32_t>::max() /
370 sizeof(handles[0]),
371 MOJO_WRITE_MESSAGE_FLAG_NONE));
372
373 // |ReadMessage|:
374 // Null buffer with nonzero buffer size.
375 uint32_t buffer_size = 1;
376 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
377 mp->ReadMessage(0,
378 NULL, &buffer_size,
379 NULL, NULL,
380 MOJO_READ_MESSAGE_FLAG_NONE));
381 // Null handles with nonzero handle count.
382 buffer_size = static_cast<uint32_t>(sizeof(buffer));
383 uint32_t handle_count = 1;
384 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
385 mp->ReadMessage(0,
386 buffer, &buffer_size,
387 NULL, &handle_count,
388 MOJO_READ_MESSAGE_FLAG_NONE));
389
390 mp->Close(0);
391 mp->Close(1);
392 }
393
394 TEST(MessagePipeTest, BasicWaiting) {
395 scoped_refptr<MessagePipe> mp(new MessagePipe());
396 Waiter waiter;
397
398 int32_t buffer[1];
399 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer));
400 uint32_t buffer_size;
401
402 // Always writable (until the other port is closed).
403 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
404 mp->AddWaiter(0, &waiter, MOJO_WAIT_FLAG_WRITABLE, 0));
405 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
406 mp->AddWaiter(0,
407 &waiter,
408 MOJO_WAIT_FLAG_READABLE | MOJO_WAIT_FLAG_WRITABLE,
409 0));
410
411 // Not yet readable.
412 EXPECT_EQ(MOJO_RESULT_OK,
413 mp->AddWaiter(0, &waiter, MOJO_WAIT_FLAG_READABLE, 1));
414 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0));
415 mp->RemoveWaiter(0, &waiter);
416
417 // Write from port 0 (to port 1), to make port 1 readable.
418 buffer[0] = 123456789;
419 EXPECT_EQ(MOJO_RESULT_OK,
420 mp->WriteMessage(0,
421 buffer, kBufferSize,
422 NULL, 0,
423 MOJO_WRITE_MESSAGE_FLAG_NONE));
424
425 // Port 1 should already be readable now.
426 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
427 mp->AddWaiter(1, &waiter, MOJO_WAIT_FLAG_READABLE, 2));
428 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
429 mp->AddWaiter(1,
430 &waiter,
431 MOJO_WAIT_FLAG_READABLE | MOJO_WAIT_FLAG_WRITABLE,
432 0));
433 // ... and still writable.
434 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
435 mp->AddWaiter(1, &waiter, MOJO_WAIT_FLAG_WRITABLE, 3));
436
437 // Close port 0.
438 mp->Close(0);
439
440 // Now port 1 should not be writable.
441 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
442 mp->AddWaiter(1, &waiter, MOJO_WAIT_FLAG_WRITABLE, 4));
443
444 // But it should still be readable.
445 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
446 mp->AddWaiter(1, &waiter, MOJO_WAIT_FLAG_READABLE, 5));
447
448 // Read from port 1.
449 buffer[0] = 0;
450 buffer_size = kBufferSize;
451 EXPECT_EQ(MOJO_RESULT_OK,
452 mp->ReadMessage(1,
453 buffer, &buffer_size,
454 NULL, NULL,
455 MOJO_READ_MESSAGE_FLAG_NONE));
456 EXPECT_EQ(123456789, buffer[0]);
457
458 // Now port 1 should no longer be readable.
459 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
460 mp->AddWaiter(1, &waiter, MOJO_WAIT_FLAG_READABLE, 6));
461
462 mp->Close(1);
463 }
464
465 TEST(MessagePipeTest, ThreadedWaiting) {
466 int32_t buffer[1];
467 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer));
468
469 MojoResult result;
470
471 // Write to wake up waiter waiting for read.
472 {
473 scoped_refptr<MessagePipe> mp(new MessagePipe());
474 test::SimpleWaiterThread thread(&result);
475
476 EXPECT_EQ(MOJO_RESULT_OK,
477 mp->AddWaiter(1, thread.waiter(), MOJO_WAIT_FLAG_READABLE, 0));
478 thread.Start();
479
480 buffer[0] = 123456789;
481 // Write from port 0 (to port 1), which should wake up the waiter.
482 EXPECT_EQ(MOJO_RESULT_OK,
483 mp->WriteMessage(0,
484 buffer, kBufferSize,
485 NULL, 0,
486 MOJO_WRITE_MESSAGE_FLAG_NONE));
487
488 mp->RemoveWaiter(1, thread.waiter());
489
490 mp->Close(0);
491 mp->Close(1);
492 } // Joins |thread|.
493 // The waiter should have woken up successfully.
494 EXPECT_EQ(0, result);
495
496 // Close to cancel waiter.
497 {
498 scoped_refptr<MessagePipe> mp(new MessagePipe());
499 test::SimpleWaiterThread thread(&result);
500
501 EXPECT_EQ(MOJO_RESULT_OK,
502 mp->AddWaiter(1, thread.waiter(), MOJO_WAIT_FLAG_READABLE, 0));
503 thread.Start();
504
505 // Close port 1 first -- this should result in the waiter being cancelled.
506 mp->CancelAllWaiters(1);
507 mp->Close(1);
508
509 // Port 1 is closed, so |Dispatcher::RemoveWaiter()| wouldn't call into the
510 // |MessagePipe| to remove any waiter.
511
512 mp->Close(0);
513 } // Joins |thread|.
514 EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
515
516 // Close to make waiter un-wake-up-able.
517 {
518 scoped_refptr<MessagePipe> mp(new MessagePipe());
519 test::SimpleWaiterThread thread(&result);
520
521 EXPECT_EQ(MOJO_RESULT_OK,
522 mp->AddWaiter(1, thread.waiter(), MOJO_WAIT_FLAG_READABLE, 0));
523 thread.Start();
524
525 // Close port 0 first -- this should wake the waiter up, since port 1 will
526 // never be readable.
527 mp->CancelAllWaiters(0);
528 mp->Close(0);
529
530 mp->RemoveWaiter(1, thread.waiter());
531
532 mp->CancelAllWaiters(1);
533 mp->Close(1);
534 } // Joins |thread|.
535 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
536 }
537
538 } // namespace
539 } // namespace system
540 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698