OLD | NEW |
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 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 expected_buffer[8] = 303; | 572 expected_buffer[8] = 303; |
573 expected_buffer[9] = 304; | 573 expected_buffer[9] = 304; |
574 EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer))); | 574 EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer))); |
575 | 575 |
576 // TODO(vtl): Test two-phase write when it supports "may discard". | 576 // TODO(vtl): Test two-phase write when it supports "may discard". |
577 | 577 |
578 dp->ProducerClose(); | 578 dp->ProducerClose(); |
579 dp->ConsumerClose(); | 579 dp->ConsumerClose(); |
580 } | 580 } |
581 | 581 |
582 // TODO(vtl): More "all or none" tests (without and with "may discard"). | 582 TEST(LocalDataPipeTest, AllOrNone) { |
| 583 const MojoCreateDataPipeOptions options = { |
| 584 kSizeOfOptions, // |struct_size|. |
| 585 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|. |
| 586 static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|. |
| 587 10 * sizeof(int32_t) // |capacity_num_bytes|. |
| 588 }; |
| 589 MojoCreateDataPipeOptions validated_options = { 0 }; |
| 590 EXPECT_EQ(MOJO_RESULT_OK, |
| 591 DataPipe::ValidateOptions(&options, &validated_options)); |
| 592 |
| 593 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options)); |
| 594 |
| 595 // Try writing way too much. |
| 596 uint32_t num_bytes = 20u * sizeof(int32_t); |
| 597 int32_t buffer[100]; |
| 598 Seq(0, arraysize(buffer), buffer); |
| 599 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE, |
| 600 dp->ProducerWriteData(buffer, &num_bytes, true)); |
| 601 |
| 602 // Should still be empty. |
| 603 num_bytes = ~0u; |
| 604 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes)); |
| 605 EXPECT_EQ(0u, num_bytes); |
| 606 |
| 607 // Write some data. |
| 608 num_bytes = 5u * sizeof(int32_t); |
| 609 Seq(100, arraysize(buffer), buffer); |
| 610 EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerWriteData(buffer, &num_bytes, true)); |
| 611 EXPECT_EQ(5u * sizeof(int32_t), num_bytes); |
| 612 |
| 613 // Half full. |
| 614 num_bytes = 0u; |
| 615 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes)); |
| 616 EXPECT_EQ(5u * sizeof(int32_t), num_bytes); |
| 617 |
| 618 // Too much. |
| 619 num_bytes = 6u * sizeof(int32_t); |
| 620 Seq(200, arraysize(buffer), buffer); |
| 621 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE, |
| 622 dp->ProducerWriteData(buffer, &num_bytes, true)); |
| 623 |
| 624 // Try reading too much. |
| 625 num_bytes = 11u * sizeof(int32_t); |
| 626 memset(buffer, 0xab, sizeof(buffer)); |
| 627 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE, |
| 628 dp->ConsumerReadData(buffer, &num_bytes, true)); |
| 629 int32_t expected_buffer[100]; |
| 630 memset(expected_buffer, 0xab, sizeof(expected_buffer)); |
| 631 EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer))); |
| 632 |
| 633 // Try discarding too much. |
| 634 num_bytes = 11u * sizeof(int32_t); |
| 635 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE, |
| 636 dp->ConsumerDiscardData(&num_bytes, true)); |
| 637 |
| 638 // Just a little. |
| 639 num_bytes = 2u * sizeof(int32_t); |
| 640 Seq(300, arraysize(buffer), buffer); |
| 641 EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerWriteData(buffer, &num_bytes, true)); |
| 642 EXPECT_EQ(2u * sizeof(int32_t), num_bytes); |
| 643 |
| 644 // Just right. |
| 645 num_bytes = 3u * sizeof(int32_t); |
| 646 Seq(400, arraysize(buffer), buffer); |
| 647 EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerWriteData(buffer, &num_bytes, true)); |
| 648 EXPECT_EQ(3u * sizeof(int32_t), num_bytes); |
| 649 |
| 650 // Exactly full. |
| 651 num_bytes = 0u; |
| 652 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes)); |
| 653 EXPECT_EQ(10u * sizeof(int32_t), num_bytes); |
| 654 |
| 655 // Read half. |
| 656 num_bytes = 5u * sizeof(int32_t); |
| 657 memset(buffer, 0xab, sizeof(buffer)); |
| 658 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerReadData(buffer, &num_bytes, true)); |
| 659 EXPECT_EQ(5u * sizeof(int32_t), num_bytes); |
| 660 memset(expected_buffer, 0xab, sizeof(expected_buffer)); |
| 661 Seq(100, 5, expected_buffer); |
| 662 EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer))); |
| 663 |
| 664 // Try reading too much again. |
| 665 num_bytes = 6u * sizeof(int32_t); |
| 666 memset(buffer, 0xab, sizeof(buffer)); |
| 667 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE, |
| 668 dp->ConsumerReadData(buffer, &num_bytes, true)); |
| 669 memset(expected_buffer, 0xab, sizeof(expected_buffer)); |
| 670 EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer))); |
| 671 |
| 672 // Try discarding too much again. |
| 673 num_bytes = 6u * sizeof(int32_t); |
| 674 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE, |
| 675 dp->ConsumerDiscardData(&num_bytes, true)); |
| 676 |
| 677 // Discard a little. |
| 678 num_bytes = 2u * sizeof(int32_t); |
| 679 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerDiscardData(&num_bytes, true)); |
| 680 EXPECT_EQ(2u * sizeof(int32_t), num_bytes); |
| 681 |
| 682 // Three left. |
| 683 num_bytes = 0u; |
| 684 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes)); |
| 685 EXPECT_EQ(3u * sizeof(int32_t), num_bytes); |
| 686 |
| 687 // Close the producer, then test producer-closed cases. |
| 688 dp->ProducerClose(); |
| 689 |
| 690 // Try reading too much; "failed precondition" since the producer is closed. |
| 691 num_bytes = 4u * sizeof(int32_t); |
| 692 memset(buffer, 0xab, sizeof(buffer)); |
| 693 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, |
| 694 dp->ConsumerReadData(buffer, &num_bytes, true)); |
| 695 memset(expected_buffer, 0xab, sizeof(expected_buffer)); |
| 696 EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer))); |
| 697 |
| 698 // Try discarding too much; "failed precondition" again. |
| 699 num_bytes = 4u * sizeof(int32_t); |
| 700 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, |
| 701 dp->ConsumerDiscardData(&num_bytes, true)); |
| 702 |
| 703 // Read a little. |
| 704 num_bytes = 2u * sizeof(int32_t); |
| 705 memset(buffer, 0xab, sizeof(buffer)); |
| 706 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerReadData(buffer, &num_bytes, true)); |
| 707 EXPECT_EQ(2u * sizeof(int32_t), num_bytes); |
| 708 memset(expected_buffer, 0xab, sizeof(expected_buffer)); |
| 709 Seq(400, 2, expected_buffer); |
| 710 EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer))); |
| 711 |
| 712 // Discard the remaining element. |
| 713 num_bytes = 1u * sizeof(int32_t); |
| 714 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerDiscardData(&num_bytes, true)); |
| 715 EXPECT_EQ(1u * sizeof(int32_t), num_bytes); |
| 716 |
| 717 // Empty again. |
| 718 num_bytes = ~0u; |
| 719 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes)); |
| 720 EXPECT_EQ(0u, num_bytes); |
| 721 |
| 722 dp->ConsumerClose(); |
| 723 } |
| 724 |
| 725 TEST(LocalDataPipeTest, AllOrNoneMayDiscard) { |
| 726 const MojoCreateDataPipeOptions options = { |
| 727 kSizeOfOptions, // |struct_size|. |
| 728 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD, // |flags|. |
| 729 static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|. |
| 730 10 * sizeof(int32_t) // |capacity_num_bytes|. |
| 731 }; |
| 732 MojoCreateDataPipeOptions validated_options = { 0 }; |
| 733 EXPECT_EQ(MOJO_RESULT_OK, |
| 734 DataPipe::ValidateOptions(&options, &validated_options)); |
| 735 |
| 736 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options)); |
| 737 |
| 738 // Try writing way too much. |
| 739 uint32_t num_bytes = 20u * sizeof(int32_t); |
| 740 int32_t buffer[100]; |
| 741 Seq(0, arraysize(buffer), buffer); |
| 742 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE, |
| 743 dp->ProducerWriteData(buffer, &num_bytes, true)); |
| 744 |
| 745 // Write some stuff. |
| 746 num_bytes = 5u * sizeof(int32_t); |
| 747 Seq(100, arraysize(buffer), buffer); |
| 748 EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerWriteData(buffer, &num_bytes, true)); |
| 749 EXPECT_EQ(5u * sizeof(int32_t), num_bytes); |
| 750 |
| 751 // Write lots of stuff (discarding all but "104"). |
| 752 num_bytes = 9u * sizeof(int32_t); |
| 753 Seq(200, arraysize(buffer), buffer); |
| 754 EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerWriteData(buffer, &num_bytes, true)); |
| 755 EXPECT_EQ(9u * sizeof(int32_t), num_bytes); |
| 756 |
| 757 // Read one. |
| 758 num_bytes = 1u * sizeof(int32_t); |
| 759 memset(buffer, 0xab, sizeof(buffer)); |
| 760 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerReadData(buffer, &num_bytes, true)); |
| 761 EXPECT_EQ(1u * sizeof(int32_t), num_bytes); |
| 762 int32_t expected_buffer[100]; |
| 763 memset(expected_buffer, 0xab, sizeof(expected_buffer)); |
| 764 expected_buffer[0] = 104; |
| 765 EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer))); |
| 766 |
| 767 // Try reading too many. |
| 768 num_bytes = 10u * sizeof(int32_t); |
| 769 memset(buffer, 0xab, sizeof(buffer)); |
| 770 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE, |
| 771 dp->ConsumerReadData(buffer, &num_bytes, true)); |
| 772 memset(expected_buffer, 0xab, sizeof(expected_buffer)); |
| 773 EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer))); |
| 774 |
| 775 // Try discarding too many. |
| 776 num_bytes = 10u * sizeof(int32_t); |
| 777 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE, |
| 778 dp->ConsumerDiscardData(&num_bytes, true)); |
| 779 |
| 780 // Discard a bunch. |
| 781 num_bytes = 4u * sizeof(int32_t); |
| 782 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerDiscardData(&num_bytes, true)); |
| 783 |
| 784 // Half full. |
| 785 num_bytes = 0u; |
| 786 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes)); |
| 787 EXPECT_EQ(5u * sizeof(int32_t), num_bytes); |
| 788 |
| 789 // Write as much as possible. |
| 790 num_bytes = 10u * sizeof(int32_t); |
| 791 Seq(300, arraysize(buffer), buffer); |
| 792 EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerWriteData(buffer, &num_bytes, true)); |
| 793 EXPECT_EQ(10u * sizeof(int32_t), num_bytes); |
| 794 |
| 795 // Read everything. |
| 796 num_bytes = 10u * sizeof(int32_t); |
| 797 memset(buffer, 0xab, sizeof(buffer)); |
| 798 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerReadData(buffer, &num_bytes, true)); |
| 799 memset(expected_buffer, 0xab, sizeof(expected_buffer)); |
| 800 EXPECT_EQ(10u * sizeof(int32_t), num_bytes); |
| 801 Seq(300, 10, expected_buffer); |
| 802 EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer))); |
| 803 |
| 804 dp->ProducerClose(); |
| 805 dp->ConsumerClose(); |
| 806 } |
| 807 |
| 808 TEST(LocalDataPipeTest, TwoPhaseAllOrNone) { |
| 809 const MojoCreateDataPipeOptions options = { |
| 810 kSizeOfOptions, // |struct_size|. |
| 811 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|. |
| 812 static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|. |
| 813 10 * sizeof(int32_t) // |capacity_num_bytes|. |
| 814 }; |
| 815 MojoCreateDataPipeOptions validated_options = { 0 }; |
| 816 EXPECT_EQ(MOJO_RESULT_OK, |
| 817 DataPipe::ValidateOptions(&options, &validated_options)); |
| 818 |
| 819 scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options)); |
| 820 |
| 821 // Try writing way too much (two-phase). |
| 822 uint32_t num_bytes = 20u * sizeof(int32_t); |
| 823 void* write_ptr = NULL; |
| 824 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE, |
| 825 dp->ProducerBeginWriteData(&write_ptr, &num_bytes, true)); |
| 826 |
| 827 // Try reading way too much (two-phase). |
| 828 num_bytes = 20u * sizeof(int32_t); |
| 829 const void* read_ptr = NULL; |
| 830 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE, |
| 831 dp->ConsumerBeginReadData(&read_ptr, &num_bytes, true)); |
| 832 |
| 833 // Write half (two-phase). |
| 834 num_bytes = 5u * sizeof(int32_t); |
| 835 write_ptr = NULL; |
| 836 EXPECT_EQ(MOJO_RESULT_OK, |
| 837 dp->ProducerBeginWriteData(&write_ptr, &num_bytes, true)); |
| 838 // May provide more space than requested. |
| 839 EXPECT_GE(num_bytes, 5u * sizeof(int32_t)); |
| 840 EXPECT_TRUE(write_ptr != NULL); |
| 841 Seq(0, 5, static_cast<int32_t*>(write_ptr)); |
| 842 EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(5u * sizeof(int32_t))); |
| 843 |
| 844 // Read one (two-phase). |
| 845 num_bytes = 1u * sizeof(int32_t); |
| 846 read_ptr = NULL; |
| 847 EXPECT_EQ(MOJO_RESULT_OK, |
| 848 dp->ConsumerBeginReadData(&read_ptr, &num_bytes, true)); |
| 849 EXPECT_GE(num_bytes, 1u * sizeof(int32_t)); |
| 850 EXPECT_EQ(0, static_cast<const int32_t*>(read_ptr)[0]); |
| 851 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(1u * sizeof(int32_t))); |
| 852 |
| 853 // We should have four left, leaving room for six. |
| 854 num_bytes = 0u; |
| 855 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes)); |
| 856 EXPECT_EQ(4u * sizeof(int32_t), num_bytes); |
| 857 |
| 858 // Assuming a tight circular buffer of the specified capacity, we can't do a |
| 859 // two-phase write of six now. |
| 860 num_bytes = 6u * sizeof(int32_t); |
| 861 write_ptr = NULL; |
| 862 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE, |
| 863 dp->ProducerBeginWriteData(&write_ptr, &num_bytes, true)); |
| 864 |
| 865 // Write six elements (simple), filling the buffer. |
| 866 num_bytes = 6u * sizeof(int32_t); |
| 867 int32_t buffer[100]; |
| 868 Seq(100, 6, buffer); |
| 869 EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerWriteData(buffer, &num_bytes, true)); |
| 870 EXPECT_EQ(6u * sizeof(int32_t), num_bytes); |
| 871 |
| 872 // We have ten. |
| 873 num_bytes = 0u; |
| 874 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(&num_bytes)); |
| 875 EXPECT_EQ(10u * sizeof(int32_t), num_bytes); |
| 876 |
| 877 // But a two-phase read of ten should fail. |
| 878 num_bytes = 10u * sizeof(int32_t); |
| 879 read_ptr = NULL; |
| 880 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE, |
| 881 dp->ConsumerBeginReadData(&read_ptr, &num_bytes, true)); |
| 882 |
| 883 // Close the producer. |
| 884 dp->ProducerClose(); |
| 885 |
| 886 // A two-phase read of nine should work. |
| 887 num_bytes = 9u * sizeof(int32_t); |
| 888 read_ptr = NULL; |
| 889 EXPECT_EQ(MOJO_RESULT_OK, |
| 890 dp->ConsumerBeginReadData(&read_ptr, &num_bytes, true)); |
| 891 EXPECT_GE(num_bytes, 9u * sizeof(int32_t)); |
| 892 EXPECT_EQ(1, static_cast<const int32_t*>(read_ptr)[0]); |
| 893 EXPECT_EQ(2, static_cast<const int32_t*>(read_ptr)[1]); |
| 894 EXPECT_EQ(3, static_cast<const int32_t*>(read_ptr)[2]); |
| 895 EXPECT_EQ(4, static_cast<const int32_t*>(read_ptr)[3]); |
| 896 EXPECT_EQ(100, static_cast<const int32_t*>(read_ptr)[4]); |
| 897 EXPECT_EQ(101, static_cast<const int32_t*>(read_ptr)[5]); |
| 898 EXPECT_EQ(102, static_cast<const int32_t*>(read_ptr)[6]); |
| 899 EXPECT_EQ(103, static_cast<const int32_t*>(read_ptr)[7]); |
| 900 EXPECT_EQ(104, static_cast<const int32_t*>(read_ptr)[8]); |
| 901 EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(9u * sizeof(int32_t))); |
| 902 |
| 903 // A two-phase read of two should fail, with "failed precondition". |
| 904 num_bytes = 2u * sizeof(int32_t); |
| 905 read_ptr = NULL; |
| 906 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, |
| 907 dp->ConsumerBeginReadData(&read_ptr, &num_bytes, true)); |
| 908 |
| 909 dp->ConsumerClose(); |
| 910 } |
| 911 |
| 912 // TODO(vtl): Test two-phase read/write with "all or none" and "may discard", |
| 913 // once that's supported. |
583 | 914 |
584 // Tests that |ProducerWriteData()| and |ConsumerReadData()| writes and reads, | 915 // Tests that |ProducerWriteData()| and |ConsumerReadData()| writes and reads, |
585 // respectively, as much as possible, even if it has to "wrap around" the | 916 // respectively, as much as possible, even if it has to "wrap around" the |
586 // internal circular buffer. (Note that the two-phase write and read do not do | 917 // internal circular buffer. (Note that the two-phase write and read do not do |
587 // this.) | 918 // this.) |
588 TEST(LocalDataPipeTest, WrapAround) { | 919 TEST(LocalDataPipeTest, WrapAround) { |
589 unsigned char test_data[1000]; | 920 unsigned char test_data[1000]; |
590 for (size_t i = 0; i < arraysize(test_data); i++) | 921 for (size_t i = 0; i < arraysize(test_data); i++) |
591 test_data[i] = static_cast<unsigned char>(i); | 922 test_data[i] = static_cast<unsigned char>(i); |
592 | 923 |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
835 | 1166 |
836 dp->ConsumerClose(); | 1167 dp->ConsumerClose(); |
837 } | 1168 } |
838 } | 1169 } |
839 | 1170 |
840 // TODO(vtl): More. | 1171 // TODO(vtl): More. |
841 | 1172 |
842 } // namespace | 1173 } // namespace |
843 } // namespace system | 1174 } // namespace system |
844 } // namespace mojo | 1175 } // namespace mojo |
OLD | NEW |