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; | |
DaveMoore
2014/01/07 23:51:01
Nit: this would be better if you didn't initialize
viettrungluu
2014/01/07 23:56:43
Done.
| |
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 |