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

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

Issue 129163003: Mojo: DataPipe: Implement "may discard" for two-phase writes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: oops Created 6 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 | Annotate | Revision Log
« no previous file with comments | « mojo/system/local_data_pipe.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "mojo/system/local_data_pipe.h" 5 #include "mojo/system/local_data_pipe.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/memory/ref_counted.h" 10 #include "base/memory/ref_counted.h"
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 175
176 // Query. 176 // Query.
177 num_bytes = 0; 177 num_bytes = 0;
178 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes)); 178 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes));
179 EXPECT_EQ(0u, num_bytes); 179 EXPECT_EQ(0u, num_bytes);
180 180
181 dp->ProducerClose(); 181 dp->ProducerClose();
182 dp->ConsumerClose(); 182 dp->ConsumerClose();
183 } 183 }
184 184
185 // Note: The "basic" waiting tests test that the "wait states" are correct in
186 // various situations; they don't test that waiters are properly awoken on state
187 // changes. (For that, we need to use multiple threads.)
185 TEST(LocalDataPipeTest, BasicProducerWaiting) { 188 TEST(LocalDataPipeTest, BasicProducerWaiting) {
186 // Note: We take advantage of the fact that for |LocalDataPipe|, capacities 189 // Note: We take advantage of the fact that for |LocalDataPipe|, capacities
187 // are strict maximums. This is not guaranteed by the API. 190 // are strict maximums. This is not guaranteed by the API.
188 191
189 const MojoCreateDataPipeOptions options = { 192 const MojoCreateDataPipeOptions options = {
190 kSizeOfOptions, // |struct_size|. 193 kSizeOfOptions, // |struct_size|.
191 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|. 194 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
192 static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|. 195 static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
193 2 * sizeof(int32_t) // |capacity_num_bytes|. 196 2 * sizeof(int32_t) // |capacity_num_bytes|.
194 }; 197 };
195 MojoCreateDataPipeOptions validated_options = { 0 }; 198 MojoCreateDataPipeOptions validated_options = { 0 };
196 EXPECT_EQ(MOJO_RESULT_OK, 199 EXPECT_EQ(MOJO_RESULT_OK,
197 DataPipe::ValidateOptions(&options, &validated_options)); 200 DataPipe::ValidateOptions(&options, &validated_options));
198 201
199 { 202 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
200 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options)); 203 Waiter waiter;
201 Waiter waiter;
202 204
203 // Never readable. 205 // Never readable.
204 waiter.Init(); 206 waiter.Init();
205 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, 207 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
206 dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 12)); 208 dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 12));
207 209
208 // Already writable. 210 // Already writable.
209 waiter.Init(); 211 waiter.Init();
210 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, 212 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
211 dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 34)); 213 dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 34));
212 214
213 // Write two elements. 215 // Write two elements.
214 int32_t elements[2] = { 123, 456 }; 216 int32_t elements[2] = { 123, 456 };
215 uint32_t num_bytes = static_cast<uint32_t>(2u * sizeof(elements[0])); 217 uint32_t num_bytes = static_cast<uint32_t>(2u * sizeof(elements[0]));
216 EXPECT_EQ(MOJO_RESULT_OK, 218 EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerWriteData(elements, &num_bytes, true));
217 dp->ProducerWriteData(elements, &num_bytes, true)); 219 EXPECT_EQ(static_cast<uint32_t>(2u * sizeof(elements[0])), num_bytes);
218 EXPECT_EQ(static_cast<uint32_t>(2u * sizeof(elements[0])), num_bytes);
219 220
220 // Adding a waiter should now succeed. 221 // Adding a waiter should now succeed.
221 waiter.Init(); 222 waiter.Init();
222 EXPECT_EQ(MOJO_RESULT_OK, 223 EXPECT_EQ(MOJO_RESULT_OK,
223 dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 56)); 224 dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 56));
224 // And it shouldn't be writable yet. 225 // And it shouldn't be writable yet.
225 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0)); 226 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0));
226 dp->ProducerRemoveWaiter(&waiter); 227 dp->ProducerRemoveWaiter(&waiter);
227 228
228 // Do it again. 229 // Do it again.
229 waiter.Init(); 230 waiter.Init();
230 EXPECT_EQ(MOJO_RESULT_OK, 231 EXPECT_EQ(MOJO_RESULT_OK,
231 dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 78)); 232 dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 78));
232 233
233 // Read one element. 234 // Read one element.
234 elements[0] = -1; 235 elements[0] = -1;
235 elements[1] = -1; 236 elements[1] = -1;
236 num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0])); 237 num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
237 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerReadData(elements, &num_bytes, true)); 238 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerReadData(elements, &num_bytes, true));
238 EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes); 239 EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
239 EXPECT_EQ(123, elements[0]); 240 EXPECT_EQ(123, elements[0]);
240 EXPECT_EQ(-1, elements[1]); 241 EXPECT_EQ(-1, elements[1]);
241 242
242 // Waiting should now succeed. 243 // Waiting should now succeed.
243 EXPECT_EQ(78, waiter.Wait(1000)); 244 EXPECT_EQ(78, waiter.Wait(1000));
244 dp->ProducerRemoveWaiter(&waiter); 245 dp->ProducerRemoveWaiter(&waiter);
245 246
246 // Try writing, using a two-phase write. 247 // Try writing, using a two-phase write.
247 void* buffer = NULL; 248 void* buffer = NULL;
248 num_bytes = static_cast<uint32_t>(3u * sizeof(elements[0])); 249 num_bytes = static_cast<uint32_t>(3u * sizeof(elements[0]));
249 EXPECT_EQ(MOJO_RESULT_OK, 250 EXPECT_EQ(MOJO_RESULT_OK,
250 dp->ProducerBeginWriteData(&buffer, &num_bytes, false)); 251 dp->ProducerBeginWriteData(&buffer, &num_bytes, false));
251 EXPECT_TRUE(buffer != NULL); 252 EXPECT_TRUE(buffer != NULL);
252 EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes); 253 EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
253 static_cast<int32_t*>(buffer)[0] = 789;
254 EXPECT_EQ(MOJO_RESULT_OK,
255 dp->ProducerEndWriteData(
256 static_cast<uint32_t>(1u * sizeof(elements[0]))));
257 254
258 // Add a waiter. 255 static_cast<int32_t*>(buffer)[0] = 789;
259 waiter.Init(); 256 EXPECT_EQ(MOJO_RESULT_OK,
260 EXPECT_EQ(MOJO_RESULT_OK, 257 dp->ProducerEndWriteData(
261 dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 90)); 258 static_cast<uint32_t>(1u * sizeof(elements[0]))));
262 259
263 // Read one element, using a two-phase read. 260 // Add a waiter.
264 const void* read_buffer = NULL; 261 waiter.Init();
265 num_bytes = 0u; 262 EXPECT_EQ(MOJO_RESULT_OK,
266 EXPECT_EQ(MOJO_RESULT_OK, 263 dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 90));
267 dp->ConsumerBeginReadData(&read_buffer, &num_bytes, false));
268 EXPECT_TRUE(read_buffer != NULL);
269 // Since we only read one element (after having written three in all), the
270 // two-phase read should only allow us to read one. This checks an
271 // implementation detail!
272 EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
273 EXPECT_EQ(456, static_cast<const int32_t*>(read_buffer)[0]);
274 EXPECT_EQ(MOJO_RESULT_OK,
275 dp->ConsumerEndReadData(
276 static_cast<uint32_t>(1u * sizeof(elements[0]))));
277 264
278 // Waiting should succeed. 265 // Read one element, using a two-phase read.
279 EXPECT_EQ(90, waiter.Wait(1000)); 266 const void* read_buffer = NULL;
280 dp->ProducerRemoveWaiter(&waiter); 267 num_bytes = 0u;
268 EXPECT_EQ(MOJO_RESULT_OK,
269 dp->ConsumerBeginReadData(&read_buffer, &num_bytes, false));
270 EXPECT_TRUE(read_buffer != NULL);
271 // Since we only read one element (after having written three in all), the
272 // two-phase read should only allow us to read one. This checks an
273 // implementation detail!
274 EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
275 EXPECT_EQ(456, static_cast<const int32_t*>(read_buffer)[0]);
276 EXPECT_EQ(MOJO_RESULT_OK,
277 dp->ConsumerEndReadData(
278 static_cast<uint32_t>(1u * sizeof(elements[0]))));
281 279
282 // Write one element. 280 // Waiting should succeed.
283 elements[0] = 123; 281 EXPECT_EQ(90, waiter.Wait(1000));
284 num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0])); 282 dp->ProducerRemoveWaiter(&waiter);
285 EXPECT_EQ(MOJO_RESULT_OK,
286 dp->ProducerWriteData(elements, &num_bytes, false));
287 EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
288 283
289 // Add a waiter. 284 // Write one element.
290 waiter.Init(); 285 elements[0] = 123;
291 EXPECT_EQ(MOJO_RESULT_OK, 286 num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
292 dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 12)); 287 EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerWriteData(elements, &num_bytes, false));
288 EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
293 289
294 // Close the consumer. 290 // Add a waiter.
295 dp->ConsumerClose(); 291 waiter.Init();
292 EXPECT_EQ(MOJO_RESULT_OK,
293 dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 12));
296 294
297 // It should now be never-writable. 295 // Close the consumer.
298 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, waiter.Wait(1000)); 296 dp->ConsumerClose();
299 dp->ProducerRemoveWaiter(&waiter);
300 297
301 dp->ProducerClose(); 298 // It should now be never-writable.
302 } 299 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, waiter.Wait(1000));
300 dp->ProducerRemoveWaiter(&waiter);
301
302 dp->ProducerClose();
303 } 303 }
304 304
305 TEST(LocalDataPipeTest, BasicConsumerWaiting) { 305 TEST(LocalDataPipeTest, BasicConsumerWaiting) {
306 const MojoCreateDataPipeOptions options = { 306 const MojoCreateDataPipeOptions options = {
307 kSizeOfOptions, // |struct_size|. 307 kSizeOfOptions, // |struct_size|.
308 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|. 308 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
309 static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|. 309 static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
310 1000 * sizeof(int32_t) // |capacity_num_bytes|. 310 1000 * sizeof(int32_t) // |capacity_num_bytes|.
311 }; 311 };
312 MojoCreateDataPipeOptions validated_options = { 0 }; 312 MojoCreateDataPipeOptions validated_options = { 0 };
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 dp->ProducerClose(); 469 dp->ProducerClose();
470 470
471 // Should be never-readable. 471 // Should be never-readable.
472 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, waiter.Wait(1000)); 472 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, waiter.Wait(1000));
473 dp->ConsumerRemoveWaiter(&waiter); 473 dp->ConsumerRemoveWaiter(&waiter);
474 474
475 dp->ConsumerClose(); 475 dp->ConsumerClose();
476 } 476 }
477 } 477 }
478 478
479 // Tests that data pipes aren't writable/readable during two-phase writes/reads.
480 TEST(LocalDataPipeTest, BasicTwoPhaseWaiting) {
481 const MojoCreateDataPipeOptions options = {
482 kSizeOfOptions, // |struct_size|.
483 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
484 static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
485 1000 * sizeof(int32_t) // |capacity_num_bytes|.
486 };
487 MojoCreateDataPipeOptions validated_options = { 0 };
488 EXPECT_EQ(MOJO_RESULT_OK,
489 DataPipe::ValidateOptions(&options, &validated_options));
490
491 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
492 Waiter waiter;
493
494 // It should be writable.
495 waiter.Init();
496 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
497 dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 0));
498
499 uint32_t num_bytes = static_cast<uint32_t>(1u * sizeof(int32_t));
500 void* write_ptr = NULL;
501 EXPECT_EQ(MOJO_RESULT_OK,
502 dp->ProducerBeginWriteData(&write_ptr, &num_bytes, false));
503 EXPECT_TRUE(write_ptr != NULL);
504 EXPECT_GE(num_bytes, static_cast<uint32_t>(1u * sizeof(int32_t)));
505
506 // At this point, it shouldn't be writable.
507 waiter.Init();
508 EXPECT_EQ(MOJO_RESULT_OK,
509 dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 1));
510 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0));
511 dp->ProducerRemoveWaiter(&waiter);
512
513 // It shouldn't be readable yet either.
514 waiter.Init();
515 EXPECT_EQ(MOJO_RESULT_OK,
516 dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 2));
517 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0));
518 dp->ConsumerRemoveWaiter(&waiter);
519
520 static_cast<int32_t*>(write_ptr)[0] = 123;
521 EXPECT_EQ(MOJO_RESULT_OK,
522 dp->ProducerEndWriteData(
523 static_cast<uint32_t>(1u * sizeof(int32_t))));
524
525 // It should be writable again.
526 waiter.Init();
527 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
528 dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 3));
529
530 // And readable.
531 waiter.Init();
532 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
533 dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 4));
534
535 // Start another two-phase write and check that it's readable even in the
536 // middle of it.
537 num_bytes = static_cast<uint32_t>(1u * sizeof(int32_t));
538 write_ptr = NULL;
539 EXPECT_EQ(MOJO_RESULT_OK,
540 dp->ProducerBeginWriteData(&write_ptr, &num_bytes, false));
541 EXPECT_TRUE(write_ptr != NULL);
542 EXPECT_GE(num_bytes, static_cast<uint32_t>(1u * sizeof(int32_t)));
543
544 // It should be readable.
545 waiter.Init();
546 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
547 dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 5));
548
549 // End the two-phase write without writing anything.
550 EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(0u));
551
552 // Start a two-phase read.
553 num_bytes = static_cast<uint32_t>(1u * sizeof(int32_t));
554 const void* read_ptr = NULL;
555 EXPECT_EQ(MOJO_RESULT_OK,
556 dp->ConsumerBeginReadData(&read_ptr, &num_bytes, false));
557 EXPECT_TRUE(read_ptr != NULL);
558 EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(int32_t)), num_bytes);
559
560 // At this point, it should still be writable.
561 waiter.Init();
562 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
563 dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 6));
564
565 // But not readable.
566 waiter.Init();
567 EXPECT_EQ(MOJO_RESULT_OK,
568 dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 7));
569 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0));
570 dp->ConsumerRemoveWaiter(&waiter);
571
572 // End the two-phase read without reading anything.
573 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(0u));
574
575 // It should be readable again.
576 waiter.Init();
577 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
578 dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 8));
579
580 dp->ProducerClose();
581 dp->ConsumerClose();
582 }
583
584 // Test that a "may discard" data pipe is writable even when it's full.
585 TEST(LocalDataPipeTest, BasicMayDiscardWaiting) {
586 const MojoCreateDataPipeOptions options = {
587 kSizeOfOptions, // |struct_size|.
588 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD, // |flags|.
589 static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
590 1 * sizeof(int32_t) // |capacity_num_bytes|.
591 };
592 MojoCreateDataPipeOptions validated_options = { 0 };
593 EXPECT_EQ(MOJO_RESULT_OK,
594 DataPipe::ValidateOptions(&options, &validated_options));
595
596 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
597 Waiter waiter;
598
599 // Writable.
600 waiter.Init();
601 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
602 dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 0));
603
604 // Not readable.
605 waiter.Init();
606 EXPECT_EQ(MOJO_RESULT_OK,
607 dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 1));
608 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0));
609 dp->ConsumerRemoveWaiter(&waiter);
610
611 uint32_t num_bytes = static_cast<uint32_t>(sizeof(int32_t));
612 int32_t element = 123;
613 EXPECT_EQ(MOJO_RESULT_OK,
614 dp->ProducerWriteData(&element, &num_bytes, false));
615 EXPECT_EQ(static_cast<uint32_t>(sizeof(int32_t)), num_bytes);
616
617 // Still writable (even though it's full.
618 waiter.Init();
619 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
620 dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 2));
621
622 // Now readable.
623 waiter.Init();
624 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
625 dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 3));
626
627 // Overwrite that element.
628 num_bytes = static_cast<uint32_t>(sizeof(int32_t));
629 element = 456;
630 EXPECT_EQ(MOJO_RESULT_OK,
631 dp->ProducerWriteData(&element, &num_bytes, false));
632 EXPECT_EQ(static_cast<uint32_t>(sizeof(int32_t)), num_bytes);
633
634 // Still writable.
635 waiter.Init();
636 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
637 dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 4));
638
639 // And still readable.
640 waiter.Init();
641 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
642 dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 5));
643
644 // Read that element.
645 num_bytes = static_cast<uint32_t>(sizeof(int32_t));
646 element = 0;
647 EXPECT_EQ(MOJO_RESULT_OK,
648 dp->ConsumerReadData(&element, &num_bytes, false));
649 EXPECT_EQ(static_cast<uint32_t>(sizeof(int32_t)), num_bytes);
650 EXPECT_EQ(456, element);
651
652 // Still writable.
653 waiter.Init();
654 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
655 dp->ProducerAddWaiter(&waiter, MOJO_WAIT_FLAG_WRITABLE, 6));
656
657 // No longer readable.
658 waiter.Init();
659 EXPECT_EQ(MOJO_RESULT_OK,
660 dp->ConsumerAddWaiter(&waiter, MOJO_WAIT_FLAG_READABLE, 7));
661 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0));
662 dp->ConsumerRemoveWaiter(&waiter);
663
664 dp->ProducerClose();
665 dp->ConsumerClose();
666 }
667
479 void Seq(int32_t start, size_t count, int32_t* out) { 668 void Seq(int32_t start, size_t count, int32_t* out) {
480 for (size_t i = 0; i < count; i++) 669 for (size_t i = 0; i < count; i++)
481 out[i] = start + static_cast<int32_t>(i); 670 out[i] = start + static_cast<int32_t>(i);
482 } 671 }
483 672
484 TEST(LocalDataPipeTest, MayDiscard) { 673 TEST(LocalDataPipeTest, MayDiscard) {
485 const MojoCreateDataPipeOptions options = { 674 const MojoCreateDataPipeOptions options = {
486 kSizeOfOptions, // |struct_size|. 675 kSizeOfOptions, // |struct_size|.
487 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD, // |flags|. 676 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD, // |flags|.
488 static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|. 677 static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 expected_buffer[2] = 106; 755 expected_buffer[2] = 106;
567 expected_buffer[3] = 107; 756 expected_buffer[3] = 107;
568 expected_buffer[4] = 200; 757 expected_buffer[4] = 200;
569 expected_buffer[5] = 300; 758 expected_buffer[5] = 300;
570 expected_buffer[6] = 301; 759 expected_buffer[6] = 301;
571 expected_buffer[7] = 302; 760 expected_buffer[7] = 302;
572 expected_buffer[8] = 303; 761 expected_buffer[8] = 303;
573 expected_buffer[9] = 304; 762 expected_buffer[9] = 304;
574 EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer))); 763 EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
575 764
576 // TODO(vtl): Test two-phase write when it supports "may discard". 765 // Test two-phase writes, including in all-or-none mode.
766 // Note: Again, the following depends on an implementation detail -- namely
767 // that the write pointer will point at the 5th element of the buffer (and the
768 // buffer has exactly the capacity requested).
769
770 num_bytes = 0u;
771 void* write_ptr = NULL;
772 EXPECT_EQ(MOJO_RESULT_OK,
773 dp->ProducerBeginWriteData(&write_ptr, &num_bytes, false));
774 EXPECT_TRUE(write_ptr != NULL);
775 EXPECT_EQ(6u * sizeof(int32_t), num_bytes);
776 Seq(400, 6, static_cast<int32_t*>(write_ptr));
777 EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(6u * sizeof(int32_t)));
778 // Internally, a circular buffer would now look like:
779 // -, -, -, -, 400, 401, 402, 403, 404, 405
780
781 // |ProducerBeginWriteData()| ignores |*num_bytes| except in "all-or-none"
782 // mode.
783 num_bytes = 6u * sizeof(int32_t);
784 write_ptr = NULL;
785 EXPECT_EQ(MOJO_RESULT_OK,
786 dp->ProducerBeginWriteData(&write_ptr, &num_bytes, false));
787 EXPECT_EQ(4u * sizeof(int32_t), num_bytes);
788 static_cast<int32_t*>(write_ptr)[0] = 500;
789 EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(1u * sizeof(int32_t)));
790 // Internally, a circular buffer would now look like:
791 // 500, -, -, -, 400, 401, 402, 403, 404, 405
792
793 // Requesting a 10-element buffer in all-or-none mode fails at this point.
794 num_bytes = 10u * sizeof(int32_t);
795 write_ptr = NULL;
796 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
797 dp->ProducerBeginWriteData(&write_ptr, &num_bytes, true));
798
799 // But requesting, say, a 5-element (up to 9, really) buffer should be okay.
800 // It will discard two elements.
801 num_bytes = 5u * sizeof(int32_t);
802 write_ptr = NULL;
803 EXPECT_EQ(MOJO_RESULT_OK,
804 dp->ProducerBeginWriteData(&write_ptr, &num_bytes, true));
805 EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
806 // Only write 4 elements though.
807 Seq(600, 4, static_cast<int32_t*>(write_ptr));
808 EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(4u * sizeof(int32_t)));
809 // Internally, a circular buffer would now look like:
810 // 500, 600, 601, 602, 603, -, 402, 403, 404, 405
811
812 // Do this again. Make sure we can get a buffer all the way out to the end of
813 // the internal buffer.
814 num_bytes = 5u * sizeof(int32_t);
815 write_ptr = NULL;
816 EXPECT_EQ(MOJO_RESULT_OK,
817 dp->ProducerBeginWriteData(&write_ptr, &num_bytes, true));
818 EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
819 // Only write 3 elements though.
820 Seq(700, 3, static_cast<int32_t*>(write_ptr));
821 EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(3u * sizeof(int32_t)));
822 // Internally, a circular buffer would now look like:
823 // 500, 600, 601, 602, 603, 700, 701, 702, -, -
824
825 // Read everything.
826 num_bytes = sizeof(buffer);
827 memset(buffer, 0xab, sizeof(buffer));
828 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerReadData(buffer, &num_bytes, false));
829 EXPECT_EQ(8u * sizeof(int32_t), num_bytes);
830 memset(expected_buffer, 0xab, sizeof(expected_buffer));
831 expected_buffer[0] = 500;
832 expected_buffer[1] = 600;
833 expected_buffer[2] = 601;
834 expected_buffer[3] = 602;
835 expected_buffer[4] = 603;
836 expected_buffer[5] = 700;
837 expected_buffer[6] = 701;
838 expected_buffer[7] = 702;
839 EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
577 840
578 dp->ProducerClose(); 841 dp->ProducerClose();
579 dp->ConsumerClose(); 842 dp->ConsumerClose();
580 } 843 }
581 844
582 TEST(LocalDataPipeTest, AllOrNone) { 845 TEST(LocalDataPipeTest, AllOrNone) {
583 const MojoCreateDataPipeOptions options = { 846 const MojoCreateDataPipeOptions options = {
584 kSizeOfOptions, // |struct_size|. 847 kSizeOfOptions, // |struct_size|.
585 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|. 848 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
586 static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|. 849 static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 1057
795 // Read everything. 1058 // Read everything.
796 num_bytes = 10u * sizeof(int32_t); 1059 num_bytes = 10u * sizeof(int32_t);
797 memset(buffer, 0xab, sizeof(buffer)); 1060 memset(buffer, 0xab, sizeof(buffer));
798 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerReadData(buffer, &num_bytes, true)); 1061 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerReadData(buffer, &num_bytes, true));
799 memset(expected_buffer, 0xab, sizeof(expected_buffer)); 1062 memset(expected_buffer, 0xab, sizeof(expected_buffer));
800 EXPECT_EQ(10u * sizeof(int32_t), num_bytes); 1063 EXPECT_EQ(10u * sizeof(int32_t), num_bytes);
801 Seq(300, 10, expected_buffer); 1064 Seq(300, 10, expected_buffer);
802 EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer))); 1065 EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
803 1066
1067 // Note: All-or-none two-phase writes on a "may discard" data pipe are tested
1068 // in LocalDataPipeTest.MayDiscard.
1069
804 dp->ProducerClose(); 1070 dp->ProducerClose();
805 dp->ConsumerClose(); 1071 dp->ConsumerClose();
806 } 1072 }
807 1073
808 TEST(LocalDataPipeTest, TwoPhaseAllOrNone) { 1074 TEST(LocalDataPipeTest, TwoPhaseAllOrNone) {
809 const MojoCreateDataPipeOptions options = { 1075 const MojoCreateDataPipeOptions options = {
810 kSizeOfOptions, // |struct_size|. 1076 kSizeOfOptions, // |struct_size|.
811 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|. 1077 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
812 static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|. 1078 static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
813 10 * sizeof(int32_t) // |capacity_num_bytes|. 1079 10 * sizeof(int32_t) // |capacity_num_bytes|.
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
902 1168
903 // A two-phase read of two should fail, with "failed precondition". 1169 // A two-phase read of two should fail, with "failed precondition".
904 num_bytes = 2u * sizeof(int32_t); 1170 num_bytes = 2u * sizeof(int32_t);
905 read_ptr = NULL; 1171 read_ptr = NULL;
906 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, 1172 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
907 dp->ConsumerBeginReadData(&read_ptr, &num_bytes, true)); 1173 dp->ConsumerBeginReadData(&read_ptr, &num_bytes, true));
908 1174
909 dp->ConsumerClose(); 1175 dp->ConsumerClose();
910 } 1176 }
911 1177
912 // TODO(vtl): Test two-phase read/write with "all or none" and "may discard",
913 // once that's supported.
914
915 // Tests that |ProducerWriteData()| and |ConsumerReadData()| writes and reads, 1178 // Tests that |ProducerWriteData()| and |ConsumerReadData()| writes and reads,
916 // respectively, as much as possible, even if it has to "wrap around" the 1179 // respectively, as much as possible, even if it has to "wrap around" the
917 // internal circular buffer. (Note that the two-phase write and read do not do 1180 // internal circular buffer. (Note that the two-phase write and read do not do
918 // this.) 1181 // this.)
919 TEST(LocalDataPipeTest, WrapAround) { 1182 TEST(LocalDataPipeTest, WrapAround) {
920 unsigned char test_data[1000]; 1183 unsigned char test_data[1000];
921 for (size_t i = 0; i < arraysize(test_data); i++) 1184 for (size_t i = 0; i < arraysize(test_data); i++)
922 test_data[i] = static_cast<unsigned char>(i); 1185 test_data[i] = static_cast<unsigned char>(i);
923 1186
924 const MojoCreateDataPipeOptions options = { 1187 const MojoCreateDataPipeOptions options = {
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
1161 1424
1162 // Ditto for discard. 1425 // Ditto for discard.
1163 num_bytes = 10u; 1426 num_bytes = 10u;
1164 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, 1427 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
1165 dp->ConsumerDiscardData(&num_bytes, false)); 1428 dp->ConsumerDiscardData(&num_bytes, false));
1166 1429
1167 dp->ConsumerClose(); 1430 dp->ConsumerClose();
1168 } 1431 }
1169 } 1432 }
1170 1433
1171 // TODO(vtl): More.
1172
1173 } // namespace 1434 } // namespace
1174 } // namespace system 1435 } // namespace system
1175 } // namespace mojo 1436 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/system/local_data_pipe.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698