OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 <stddef.h> | 5 #include <stddef.h> |
6 #include <stdint.h> | 6 #include <stdint.h> |
7 | 7 |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/location.h" | 9 #include "base/location.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
12 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
13 #include "mojo/edk/embedder/embedder.h" | 13 #include "mojo/edk/embedder/embedder.h" |
14 #include "mojo/edk/embedder/platform_channel_pair.h" | 14 #include "mojo/edk/embedder/platform_channel_pair.h" |
15 #include "mojo/edk/embedder/simple_platform_support.h" | 15 #include "mojo/edk/embedder/simple_platform_support.h" |
16 #include "mojo/edk/system/test_utils.h" | 16 #include "mojo/edk/system/test_utils.h" |
17 #include "mojo/edk/system/waiter.h" | 17 #include "mojo/edk/system/waiter.h" |
18 #include "mojo/edk/test/multiprocess_test_helper.h" | 18 #include "mojo/edk/test/mojo_test_base.h" |
19 #include "mojo/public/c/system/data_pipe.h" | 19 #include "mojo/public/c/system/data_pipe.h" |
20 #include "mojo/public/c/system/functions.h" | 20 #include "mojo/public/c/system/functions.h" |
21 #include "mojo/public/c/system/message_pipe.h" | 21 #include "mojo/public/c/system/message_pipe.h" |
22 #include "mojo/public/cpp/system/macros.h" | 22 #include "mojo/public/cpp/system/macros.h" |
23 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" |
24 | 24 |
25 namespace mojo { | 25 namespace mojo { |
26 namespace edk { | 26 namespace edk { |
27 namespace { | 27 namespace { |
28 | 28 |
29 const uint32_t kSizeOfOptions = | 29 const uint32_t kSizeOfOptions = |
30 static_cast<uint32_t>(sizeof(MojoCreateDataPipeOptions)); | 30 static_cast<uint32_t>(sizeof(MojoCreateDataPipeOptions)); |
31 | 31 |
32 // In various places, we have to poll (since, e.g., we can't yet wait for a | 32 // In various places, we have to poll (since, e.g., we can't yet wait for a |
33 // certain amount of data to be available). This is the maximum number of | 33 // certain amount of data to be available). This is the maximum number of |
34 // iterations (separated by a short sleep). | 34 // iterations (separated by a short sleep). |
35 // TODO(vtl): Get rid of this. | 35 // TODO(vtl): Get rid of this. |
36 const size_t kMaxPoll = 100; | 36 const size_t kMaxPoll = 100; |
37 | 37 |
38 // Used in Multiprocess test. | 38 // Used in Multiprocess test. |
39 const size_t kMultiprocessCapacity = 37; | 39 const size_t kMultiprocessCapacity = 37; |
40 const char kMultiprocessTestData[] = "hello i'm a string that is 36 bytes"; | 40 const char kMultiprocessTestData[] = "hello i'm a string that is 36 bytes"; |
41 const int kMultiprocessMaxIter = 513; | 41 const int kMultiprocessMaxIter = 5; |
42 | 42 |
43 class DataPipeTest : public testing::Test { | 43 class DataPipeTest : public test::MojoTestBase { |
44 public: | 44 public: |
45 DataPipeTest() : producer_(MOJO_HANDLE_INVALID), | 45 DataPipeTest() : producer_(MOJO_HANDLE_INVALID), |
46 consumer_(MOJO_HANDLE_INVALID) {} | 46 consumer_(MOJO_HANDLE_INVALID) {} |
47 | 47 |
48 ~DataPipeTest() override { | 48 ~DataPipeTest() override { |
49 if (producer_ != MOJO_HANDLE_INVALID) | 49 if (producer_ != MOJO_HANDLE_INVALID) |
50 CHECK_EQ(MOJO_RESULT_OK, MojoClose(producer_)); | 50 CHECK_EQ(MOJO_RESULT_OK, MojoClose(producer_)); |
51 if (consumer_ != MOJO_HANDLE_INVALID) | 51 if (consumer_ != MOJO_HANDLE_INVALID) |
52 CHECK_EQ(MOJO_RESULT_OK, MojoClose(consumer_)); | 52 CHECK_EQ(MOJO_RESULT_OK, MojoClose(consumer_)); |
53 } | 53 } |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
384 static_cast<int32_t*>(buffer)[0] = 789; | 384 static_cast<int32_t*>(buffer)[0] = 789; |
385 ASSERT_EQ(MOJO_RESULT_OK, EndWriteData(static_cast<uint32_t>( | 385 ASSERT_EQ(MOJO_RESULT_OK, EndWriteData(static_cast<uint32_t>( |
386 1u * sizeof(elements[0])))); | 386 1u * sizeof(elements[0])))); |
387 | 387 |
388 // Read one element, using a two-phase read. | 388 // Read one element, using a two-phase read. |
389 const void* read_buffer = nullptr; | 389 const void* read_buffer = nullptr; |
390 num_bytes = 0u; | 390 num_bytes = 0u; |
391 ASSERT_EQ(MOJO_RESULT_OK, | 391 ASSERT_EQ(MOJO_RESULT_OK, |
392 BeginReadData(&read_buffer, &num_bytes, false)); | 392 BeginReadData(&read_buffer, &num_bytes, false)); |
393 EXPECT_TRUE(read_buffer); | 393 EXPECT_TRUE(read_buffer); |
394 // Since we only read one element (after having written three in all), the | 394 // The two-phase read should be able to read at least one element. |
395 // two-phase read should only allow us to read one. This checks an | 395 ASSERT_GE(num_bytes, static_cast<uint32_t>(1u * sizeof(elements[0]))); |
396 // implementation detail! | |
397 ASSERT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes); | |
398 ASSERT_EQ(456, static_cast<const int32_t*>(read_buffer)[0]); | 396 ASSERT_EQ(456, static_cast<const int32_t*>(read_buffer)[0]); |
399 ASSERT_EQ(MOJO_RESULT_OK, EndReadData(static_cast<uint32_t>( | 397 ASSERT_EQ(MOJO_RESULT_OK, EndReadData(static_cast<uint32_t>( |
400 1u * sizeof(elements[0])))); | 398 1u * sizeof(elements[0])))); |
401 | 399 |
402 // Write one element. | 400 // Write one element. |
403 elements[0] = 123; | 401 elements[0] = 123; |
404 num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0])); | 402 num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0])); |
405 ASSERT_EQ(MOJO_RESULT_OK, WriteData(elements, &num_bytes)); | 403 ASSERT_EQ(MOJO_RESULT_OK, WriteData(elements, &num_bytes)); |
406 ASSERT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes); | 404 ASSERT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes); |
407 | 405 |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
553 hss.satisfiable_signals); | 551 hss.satisfiable_signals); |
554 | 552 |
555 // Close the producer. | 553 // Close the producer. |
556 CloseProducer(); | 554 CloseProducer(); |
557 | 555 |
558 // Should still be readable. | 556 // Should still be readable. |
559 hss = MojoHandleSignalsState(); | 557 hss = MojoHandleSignalsState(); |
560 ASSERT_EQ(MOJO_RESULT_OK, | 558 ASSERT_EQ(MOJO_RESULT_OK, |
561 MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE, | 559 MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE, |
562 MOJO_DEADLINE_INDEFINITE, &hss)); | 560 MOJO_DEADLINE_INDEFINITE, &hss)); |
563 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); | 561 ASSERT_TRUE((hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE) != 0); |
564 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, | 562 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, |
565 hss.satisfiable_signals); | 563 hss.satisfiable_signals); |
566 | 564 |
567 // Wait for the peer closed signal. | 565 // Wait for the peer closed signal. |
568 hss = MojoHandleSignalsState(); | 566 hss = MojoHandleSignalsState(); |
569 ASSERT_EQ(MOJO_RESULT_OK, | 567 ASSERT_EQ(MOJO_RESULT_OK, |
570 MojoWait(consumer_, MOJO_HANDLE_SIGNAL_PEER_CLOSED, | 568 MojoWait(consumer_, MOJO_HANDLE_SIGNAL_PEER_CLOSED, |
571 MOJO_DEADLINE_INDEFINITE, &hss)); | 569 MOJO_DEADLINE_INDEFINITE, &hss)); |
572 ASSERT_TRUE((hss.satisfied_signals & MOJO_HANDLE_SIGNAL_PEER_CLOSED) != 0); | 570 ASSERT_TRUE((hss.satisfied_signals & MOJO_HANDLE_SIGNAL_PEER_CLOSED) != 0); |
573 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, | 571 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
945 num_bytes = 1u * sizeof(int32_t); | 943 num_bytes = 1u * sizeof(int32_t); |
946 ASSERT_EQ(MOJO_RESULT_OK, DiscardData(&num_bytes, true)); | 944 ASSERT_EQ(MOJO_RESULT_OK, DiscardData(&num_bytes, true)); |
947 ASSERT_EQ(1u * sizeof(int32_t), num_bytes); | 945 ASSERT_EQ(1u * sizeof(int32_t), num_bytes); |
948 | 946 |
949 // Empty again. | 947 // Empty again. |
950 num_bytes = ~0u; | 948 num_bytes = ~0u; |
951 ASSERT_EQ(MOJO_RESULT_OK, QueryData(&num_bytes)); | 949 ASSERT_EQ(MOJO_RESULT_OK, QueryData(&num_bytes)); |
952 ASSERT_EQ(0u, num_bytes); | 950 ASSERT_EQ(0u, num_bytes); |
953 } | 951 } |
954 | 952 |
955 /* | |
956 jam: this is testing that the implementation uses a circular buffer, which we | |
957 don't use currently. | |
958 // Tests that |ProducerWriteData()| and |ConsumerReadData()| writes and reads, | 953 // Tests that |ProducerWriteData()| and |ConsumerReadData()| writes and reads, |
959 // respectively, as much as possible, even if it may have to "wrap around" the | 954 // respectively, as much as possible, even if it may have to "wrap around" the |
960 // internal circular buffer. (Note that the two-phase write and read need not do | 955 // internal circular buffer. (Note that the two-phase write and read need not do |
961 // this.) | 956 // this.) |
962 TYPED_TEST(DataPipeImplTest, WrapAround) { | 957 TEST_F(DataPipeTest, WrapAround) { |
963 unsigned char test_data[1000]; | 958 unsigned char test_data[1000]; |
964 for (size_t i = 0; i < MOJO_ARRAYSIZE(test_data); i++) | 959 for (size_t i = 0; i < MOJO_ARRAYSIZE(test_data); i++) |
965 test_data[i] = static_cast<unsigned char>(i); | 960 test_data[i] = static_cast<unsigned char>(i); |
966 | 961 |
967 const MojoCreateDataPipeOptions options = { | 962 const MojoCreateDataPipeOptions options = { |
968 kSizeOfOptions, // |struct_size|. | 963 kSizeOfOptions, // |struct_size|. |
969 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|. | 964 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|. |
970 1u, // |element_num_bytes|. | 965 1u, // |element_num_bytes|. |
971 100u // |capacity_num_bytes|. | 966 100u // |capacity_num_bytes|. |
972 }; | 967 }; |
973 MojoCreateDataPipeOptions validated_options = {}; | |
974 // This test won't be valid if |ValidateCreateOptions()| decides to give the | |
975 // pipe more space. | |
976 ASSERT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions( | |
977 &options, &validated_options)); | |
978 ASSERT_EQ(100u, validated_options.capacity_num_bytes); | |
979 this->Create(options); | |
980 this->DoTransfer(); | |
981 | 968 |
982 Waiter waiter; | 969 ASSERT_EQ(MOJO_RESULT_OK, Create(&options)); |
983 HandleSignalsState hss; | 970 MojoHandleSignalsState hss; |
984 | |
985 // Add waiter. | |
986 waiter.Init(); | |
987 ASSERT_EQ(MOJO_RESULT_OK, | |
988 this->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 1, | |
989 nullptr)); | |
990 | 971 |
991 // Write 20 bytes. | 972 // Write 20 bytes. |
992 uint32_t num_bytes = 20u; | 973 uint32_t num_bytes = 20u; |
993 ASSERT_EQ(MOJO_RESULT_OK, | 974 ASSERT_EQ(MOJO_RESULT_OK, WriteData(&test_data[0], &num_bytes, true)); |
994 this->ProducerWriteData(&test_data[0], &num_bytes, false)); | |
995 ASSERT_EQ(20u, num_bytes); | 975 ASSERT_EQ(20u, num_bytes); |
996 | 976 |
997 // Wait for data. | 977 // Wait for data. |
998 // TODO(vtl): (See corresponding TODO in AllOrNone.) | 978 ASSERT_EQ(MOJO_RESULT_OK, |
999 ASSERT_EQ(MOJO_RESULT_OK, waiter.Wait(test::TinyDeadline(), nullptr)); | 979 MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE, |
1000 hss = HandleSignalsState(); | 980 MOJO_DEADLINE_INDEFINITE, &hss)); |
1001 this->ConsumerRemoveAwakable(&waiter, &hss); | 981 ASSERT_TRUE((hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE) != 0); |
1002 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); | |
1003 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, | 982 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, |
1004 hss.satisfiable_signals); | 983 hss.satisfiable_signals); |
1005 | 984 |
1006 // Read 10 bytes. | 985 // Read 10 bytes. |
1007 unsigned char read_buffer[1000] = {0}; | 986 unsigned char read_buffer[1000] = {0}; |
1008 num_bytes = 10u; | 987 num_bytes = 10u; |
1009 ASSERT_EQ(MOJO_RESULT_OK, | 988 ASSERT_EQ(MOJO_RESULT_OK, ReadData(read_buffer, &num_bytes, true)); |
1010 this->ConsumerReadData(read_buffer, &num_bytes, false, false)); | |
1011 ASSERT_EQ(10u, num_bytes); | 989 ASSERT_EQ(10u, num_bytes); |
1012 ASSERT_EQ(0, memcmp(read_buffer, &test_data[0], 10u)); | 990 ASSERT_EQ(0, memcmp(read_buffer, &test_data[0], 10u)); |
1013 | 991 |
1014 if (this->IsStrictCircularBuffer()) { | 992 // Check that a two-phase write can now only write (at most) 80 bytes. (This |
1015 // Check that a two-phase write can now only write (at most) 80 bytes. (This | 993 // checks an implementation detail; this behavior is not guaranteed.) |
1016 // checks an implementation detail; this behavior is not guaranteed.) | 994 void* write_buffer_ptr = nullptr; |
1017 void* write_buffer_ptr = nullptr; | 995 num_bytes = 0u; |
1018 num_bytes = 0u; | 996 ASSERT_EQ(MOJO_RESULT_OK, |
| 997 BeginWriteData(&write_buffer_ptr, &num_bytes, false)); |
| 998 EXPECT_TRUE(write_buffer_ptr); |
| 999 ASSERT_EQ(80u, num_bytes); |
| 1000 ASSERT_EQ(MOJO_RESULT_OK, EndWriteData(0)); |
| 1001 |
| 1002 size_t total_num_bytes = 0; |
| 1003 while (total_num_bytes < 90) { |
| 1004 // Wait to write. |
1019 ASSERT_EQ(MOJO_RESULT_OK, | 1005 ASSERT_EQ(MOJO_RESULT_OK, |
1020 this->ProducerBeginWriteData(&write_buffer_ptr, &num_bytes, | 1006 MojoWait(producer_, MOJO_HANDLE_SIGNAL_WRITABLE, |
1021 false)); | 1007 MOJO_DEADLINE_INDEFINITE, &hss)); |
1022 EXPECT_TRUE(write_buffer_ptr); | 1008 ASSERT_EQ(hss.satisfied_signals, MOJO_HANDLE_SIGNAL_WRITABLE); |
1023 ASSERT_EQ(80u, num_bytes); | 1009 ASSERT_EQ(hss.satisfiable_signals, |
1024 ASSERT_EQ(MOJO_RESULT_OK, this->ProducerEndWriteData(0u)); | 1010 MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED); |
| 1011 |
| 1012 // Write as much as we can. |
| 1013 num_bytes = 100; |
| 1014 ASSERT_EQ(MOJO_RESULT_OK, |
| 1015 WriteData(&test_data[20 + total_num_bytes], &num_bytes, false)); |
| 1016 total_num_bytes += num_bytes; |
1025 } | 1017 } |
1026 | 1018 |
1027 // TODO(vtl): (See corresponding TODO in TwoPhaseAllOrNone.) | |
1028 size_t total_num_bytes = 0; | |
1029 for (size_t i = 0; i < kMaxPoll; i++) { | |
1030 // Write as much data as we can (using |ProducerWriteData()|). We should | |
1031 // write 90 bytes (eventually). | |
1032 num_bytes = 200u; | |
1033 MojoResult result = this->ProducerWriteData( | |
1034 &test_data[20 + total_num_bytes], &num_bytes, false); | |
1035 if (result == MOJO_RESULT_OK) { | |
1036 total_num_bytes += num_bytes; | |
1037 if (total_num_bytes >= 90u) | |
1038 break; | |
1039 } else { | |
1040 ASSERT_EQ(MOJO_RESULT_OUT_OF_RANGE, result); | |
1041 } | |
1042 | |
1043 test::Sleep(test::EpsilonDeadline()); | |
1044 } | |
1045 ASSERT_EQ(90u, total_num_bytes); | 1019 ASSERT_EQ(90u, total_num_bytes); |
1046 | 1020 |
1047 // TODO(vtl): (See corresponding TODO in TwoPhaseAllOrNone.) | 1021 num_bytes = 0; |
1048 for (size_t i = 0; i < kMaxPoll; i++) { | 1022 ASSERT_EQ(MOJO_RESULT_OK, QueryData(&num_bytes)); |
1049 // We have 100. | |
1050 num_bytes = 0u; | |
1051 ASSERT_EQ(MOJO_RESULT_OK, | |
1052 this->ConsumerQueryData(&num_bytes)); | |
1053 if (num_bytes >= 100u) | |
1054 break; | |
1055 | |
1056 test::Sleep(test::EpsilonDeadline()); | |
1057 } | |
1058 ASSERT_EQ(100u, num_bytes); | 1023 ASSERT_EQ(100u, num_bytes); |
1059 | 1024 |
1060 if (this->IsStrictCircularBuffer()) { | 1025 // Check that a two-phase read can now only read (at most) 90 bytes. (This |
1061 // Check that a two-phase read can now only read (at most) 90 bytes. (This | 1026 // checks an implementation detail; this behavior is not guaranteed.) |
1062 // checks an implementation detail; this behavior is not guaranteed.) | 1027 const void* read_buffer_ptr = nullptr; |
1063 const void* read_buffer_ptr = nullptr; | 1028 num_bytes = 0; |
1064 num_bytes = 0u; | 1029 ASSERT_EQ(MOJO_RESULT_OK, BeginReadData(&read_buffer_ptr, &num_bytes, false)); |
1065 ASSERT_EQ(MOJO_RESULT_OK, | 1030 EXPECT_TRUE(read_buffer_ptr); |
1066 this->ConsumerBeginReadData(&read_buffer_ptr, &num_bytes, false)); | 1031 ASSERT_EQ(90u, num_bytes); |
1067 EXPECT_TRUE(read_buffer_ptr); | 1032 ASSERT_EQ(MOJO_RESULT_OK, EndReadData(0)); |
1068 ASSERT_EQ(90u, num_bytes); | |
1069 ASSERT_EQ(MOJO_RESULT_OK, this->ConsumerEndReadData(0u)); | |
1070 } | |
1071 | 1033 |
1072 // Read as much as possible (using |ConsumerReadData()|). We should read 100 | 1034 // Read as much as possible. We should read 100 bytes. |
1073 // bytes. | |
1074 num_bytes = static_cast<uint32_t>(MOJO_ARRAYSIZE(read_buffer) * | 1035 num_bytes = static_cast<uint32_t>(MOJO_ARRAYSIZE(read_buffer) * |
1075 sizeof(read_buffer[0])); | 1036 sizeof(read_buffer[0])); |
1076 memset(read_buffer, 0, num_bytes); | 1037 memset(read_buffer, 0, num_bytes); |
1077 ASSERT_EQ(MOJO_RESULT_OK, | 1038 ASSERT_EQ(MOJO_RESULT_OK, ReadData(read_buffer, &num_bytes)); |
1078 this->ConsumerReadData(read_buffer, &num_bytes, false, false)); | |
1079 ASSERT_EQ(100u, num_bytes); | 1039 ASSERT_EQ(100u, num_bytes); |
1080 ASSERT_EQ(0, memcmp(read_buffer, &test_data[10], 100u)); | 1040 ASSERT_EQ(0, memcmp(read_buffer, &test_data[10], 100u)); |
1081 | |
1082 this->ProducerClose(); | |
1083 this->ConsumerClose(); | |
1084 } | 1041 } |
1085 */ | |
1086 | 1042 |
1087 // Tests the behavior of writing (simple and two-phase), closing the producer, | 1043 // Tests the behavior of writing (simple and two-phase), closing the producer, |
1088 // then reading (simple and two-phase). | 1044 // then reading (simple and two-phase). |
1089 TEST_F(DataPipeTest, WriteCloseProducerRead) { | 1045 TEST_F(DataPipeTest, WriteCloseProducerRead) { |
1090 const char kTestData[] = "hello world"; | 1046 const char kTestData[] = "hello world"; |
1091 const uint32_t kTestDataSize = static_cast<uint32_t>(sizeof(kTestData)); | 1047 const uint32_t kTestDataSize = static_cast<uint32_t>(sizeof(kTestData)); |
1092 | 1048 |
1093 const MojoCreateDataPipeOptions options = { | 1049 const MojoCreateDataPipeOptions options = { |
1094 kSizeOfOptions, // |struct_size|. | 1050 kSizeOfOptions, // |struct_size|. |
1095 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|. | 1051 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|. |
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1710 const uint32_t kTestDataSize = | 1666 const uint32_t kTestDataSize = |
1711 static_cast<uint32_t>(sizeof(kMultiprocessTestData)); | 1667 static_cast<uint32_t>(sizeof(kMultiprocessTestData)); |
1712 const MojoCreateDataPipeOptions options = { | 1668 const MojoCreateDataPipeOptions options = { |
1713 kSizeOfOptions, // |struct_size|. | 1669 kSizeOfOptions, // |struct_size|. |
1714 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|. | 1670 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|. |
1715 1, // |element_num_bytes|. | 1671 1, // |element_num_bytes|. |
1716 kMultiprocessCapacity // |capacity_num_bytes|. | 1672 kMultiprocessCapacity // |capacity_num_bytes|. |
1717 }; | 1673 }; |
1718 ASSERT_EQ(MOJO_RESULT_OK, Create(&options)); | 1674 ASSERT_EQ(MOJO_RESULT_OK, Create(&options)); |
1719 | 1675 |
1720 test::MultiprocessTestHelper multiprocess_test_helper; | 1676 RUN_CHILD_ON_PIPE(MultiprocessClient, server_mp) |
1721 multiprocess_test_helper.StartChild("MultiprocessClient"); | 1677 // Send some data before serialising and sending the data pipe over. |
| 1678 // This is the first write so we don't need to use WriteAllData. |
| 1679 uint32_t num_bytes = kTestDataSize; |
| 1680 ASSERT_EQ(MOJO_RESULT_OK, WriteData(kMultiprocessTestData, &num_bytes, |
| 1681 MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)); |
| 1682 ASSERT_EQ(kTestDataSize, num_bytes); |
1722 | 1683 |
1723 // Send some data before serialising and sending the data pipe over. | 1684 // Send child process the data pipe. |
1724 // This is the first write so we don't need to use WriteAllData. | 1685 ASSERT_EQ(MOJO_RESULT_OK, |
1725 uint32_t num_bytes = kTestDataSize; | 1686 MojoWriteMessage(server_mp, nullptr, 0, &consumer_, 1, |
1726 ASSERT_EQ(MOJO_RESULT_OK, WriteData(kMultiprocessTestData, &num_bytes, | 1687 MOJO_WRITE_MESSAGE_FLAG_NONE)); |
1727 MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)); | |
1728 ASSERT_EQ(kTestDataSize, num_bytes); | |
1729 | 1688 |
1730 MojoHandle server_mp = | 1689 // Send a bunch of data of varying sizes. |
1731 CreateMessagePipe( | 1690 uint8_t buffer[100]; |
1732 std::move(multiprocess_test_helper.server_platform_handle)) | 1691 int seq = 0; |
1733 .release() | 1692 for (int i = 0; i < kMultiprocessMaxIter; ++i) { |
1734 .value(); | 1693 for (uint32_t size = 1; size <= kMultiprocessCapacity; size++) { |
| 1694 for (unsigned int j = 0; j < size; ++j) |
| 1695 buffer[j] = seq + j; |
| 1696 EXPECT_TRUE(WriteAllData(producer_, buffer, size)); |
| 1697 seq += size; |
| 1698 } |
| 1699 } |
1735 | 1700 |
1736 // Send child process the data pipe. | 1701 // Write the test string in again. |
1737 ASSERT_EQ(MOJO_RESULT_OK, MojoWriteMessage(server_mp, nullptr, 0, &consumer_, | 1702 ASSERT_TRUE(WriteAllData(producer_, kMultiprocessTestData, kTestDataSize)); |
1738 1, MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
1739 | 1703 |
1740 // Send a bunch of data of varying sizes. | 1704 // Swap ends. |
1741 uint8_t buffer[100]; | 1705 ASSERT_EQ(MOJO_RESULT_OK, |
1742 int seq = 0; | 1706 MojoWriteMessage(server_mp, nullptr, 0, &producer_, 1, |
1743 for (int i = 0; i < kMultiprocessMaxIter; ++i) { | 1707 MOJO_WRITE_MESSAGE_FLAG_NONE)); |
1744 for (uint32_t size = 1; size <= kMultiprocessCapacity; size++) { | 1708 |
1745 for (unsigned int j = 0; j < size; ++j) | 1709 // Receive the consumer from the other side. |
1746 buffer[j] = seq + j; | 1710 producer_ = MOJO_HANDLE_INVALID; |
1747 EXPECT_TRUE(WriteAllData(producer_, buffer, size)); | 1711 MojoHandleSignalsState hss = MojoHandleSignalsState(); |
1748 seq += size; | 1712 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(server_mp, MOJO_HANDLE_SIGNAL_READABLE, |
| 1713 MOJO_DEADLINE_INDEFINITE, &hss)); |
| 1714 MojoHandle handles[2]; |
| 1715 uint32_t num_handles = MOJO_ARRAYSIZE(handles); |
| 1716 ASSERT_EQ(MOJO_RESULT_OK, |
| 1717 MojoReadMessage(server_mp, nullptr, 0, handles, &num_handles, |
| 1718 MOJO_READ_MESSAGE_FLAG_NONE)); |
| 1719 ASSERT_EQ(1u, num_handles); |
| 1720 consumer_ = handles[0]; |
| 1721 |
| 1722 // Read the test string twice. Once for when we sent it, and once for the |
| 1723 // other end sending it. |
| 1724 for (int i = 0; i < 2; ++i) { |
| 1725 EXPECT_TRUE(ReadAllData(consumer_, buffer, kTestDataSize, i == 1)); |
| 1726 EXPECT_EQ(0, memcmp(buffer, kMultiprocessTestData, kTestDataSize)); |
1749 } | 1727 } |
1750 } | |
1751 | 1728 |
1752 // Write the test string in again. | 1729 WriteMessage(server_mp, "quit"); |
1753 EXPECT_TRUE(WriteAllData(producer_, kMultiprocessTestData, kTestDataSize)); | |
1754 | 1730 |
1755 // Swap ends. | 1731 // Don't have to close the consumer here because it will be done for us. |
1756 ASSERT_EQ(MOJO_RESULT_OK, MojoWriteMessage(server_mp, nullptr, 0, &producer_, | 1732 END_CHILD() |
1757 1, MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
1758 | |
1759 // Receive the consumer from the other side. | |
1760 producer_ = MOJO_HANDLE_INVALID; | |
1761 MojoHandleSignalsState hss = MojoHandleSignalsState(); | |
1762 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(server_mp, MOJO_HANDLE_SIGNAL_READABLE, | |
1763 MOJO_DEADLINE_INDEFINITE, &hss)); | |
1764 MojoHandle handles[2]; | |
1765 uint32_t num_handles = MOJO_ARRAYSIZE(handles); | |
1766 ASSERT_EQ(MOJO_RESULT_OK, | |
1767 MojoReadMessage(server_mp, nullptr, 0, handles, &num_handles, | |
1768 MOJO_READ_MESSAGE_FLAG_NONE)); | |
1769 ASSERT_EQ(1u, num_handles); | |
1770 consumer_ = handles[0]; | |
1771 | |
1772 // Read the test string twice. Once for when we sent it, and once for the | |
1773 // other end sending it. | |
1774 for (int i = 0; i < 2; ++i) { | |
1775 EXPECT_TRUE(ReadAllData(consumer_, buffer, kTestDataSize, i == 1)); | |
1776 EXPECT_EQ(0, memcmp(buffer, kMultiprocessTestData, kTestDataSize)); | |
1777 } | |
1778 | |
1779 // Don't have to close the consumer here because it will be done for us. | |
1780 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(server_mp)); | |
1781 EXPECT_TRUE(multiprocess_test_helper.WaitForChildTestShutdown()); | |
1782 } | 1733 } |
1783 | 1734 |
1784 MOJO_MULTIPROCESS_TEST_CHILD_TEST(MultiprocessClient) { | 1735 DEFINE_TEST_CLIENT_TEST_WITH_PIPE(MultiprocessClient, DataPipeTest, client_mp) { |
1785 ScopedPlatformHandle client_platform_handle = | |
1786 std::move(test::MultiprocessTestHelper::client_platform_handle); | |
1787 const uint32_t kTestDataSize = | 1736 const uint32_t kTestDataSize = |
1788 static_cast<uint32_t>(sizeof(kMultiprocessTestData)); | 1737 static_cast<uint32_t>(sizeof(kMultiprocessTestData)); |
1789 EXPECT_TRUE(client_platform_handle.is_valid()); | |
1790 | |
1791 MojoHandle client_mp = | |
1792 CreateMessagePipe(std::move(client_platform_handle)).release().value(); | |
1793 | 1738 |
1794 // Receive the data pipe from the other side. | 1739 // Receive the data pipe from the other side. |
1795 MojoHandle consumer = MOJO_HANDLE_INVALID; | 1740 MojoHandle consumer = MOJO_HANDLE_INVALID; |
1796 MojoHandleSignalsState hss = MojoHandleSignalsState(); | 1741 MojoHandleSignalsState hss = MojoHandleSignalsState(); |
1797 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE, | 1742 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE, |
1798 MOJO_DEADLINE_INDEFINITE, &hss)); | 1743 MOJO_DEADLINE_INDEFINITE, &hss)); |
1799 MojoHandle handles[2]; | 1744 MojoHandle handles[2]; |
1800 uint32_t num_handles = MOJO_ARRAYSIZE(handles); | 1745 uint32_t num_handles = MOJO_ARRAYSIZE(handles); |
1801 ASSERT_EQ(MOJO_RESULT_OK, | 1746 ASSERT_EQ(MOJO_RESULT_OK, |
1802 MojoReadMessage(client_mp, nullptr, 0, handles, &num_handles, | 1747 MojoReadMessage(client_mp, nullptr, 0, handles, &num_handles, |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1837 MojoReadMessage(client_mp, nullptr, 0, handles, &num_handles, | 1782 MojoReadMessage(client_mp, nullptr, 0, handles, &num_handles, |
1838 MOJO_READ_MESSAGE_FLAG_NONE)); | 1783 MOJO_READ_MESSAGE_FLAG_NONE)); |
1839 ASSERT_EQ(1u, num_handles); | 1784 ASSERT_EQ(1u, num_handles); |
1840 producer = handles[0]; | 1785 producer = handles[0]; |
1841 | 1786 |
1842 // Write the test string one more time. | 1787 // Write the test string one more time. |
1843 EXPECT_TRUE(WriteAllData(producer, kMultiprocessTestData, kTestDataSize)); | 1788 EXPECT_TRUE(WriteAllData(producer, kMultiprocessTestData, kTestDataSize)); |
1844 | 1789 |
1845 // We swapped ends, so close the producer. | 1790 // We swapped ends, so close the producer. |
1846 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(producer)); | 1791 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(producer)); |
1847 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(client_mp)); | 1792 |
| 1793 // Wait to receive a "quit" message before exiting. |
| 1794 EXPECT_EQ("quit", ReadMessage(client_mp)); |
| 1795 } |
| 1796 |
| 1797 DEFINE_TEST_CLIENT_TEST_WITH_PIPE(WriteAndCloseProducer, DataPipeTest, h) { |
| 1798 MojoHandle p; |
| 1799 std::string message = ReadMessageWithHandles(h, &p, 1); |
| 1800 |
| 1801 // Write some data to the producer and close it. |
| 1802 uint32_t num_bytes = static_cast<uint32_t>(message.size()); |
| 1803 EXPECT_EQ(MOJO_RESULT_OK, MojoWriteData(p, message.data(), &num_bytes, |
| 1804 MOJO_WRITE_DATA_FLAG_NONE)); |
| 1805 EXPECT_EQ(num_bytes, static_cast<uint32_t>(message.size())); |
| 1806 |
| 1807 // Close the producer before quitting. |
| 1808 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(p)); |
| 1809 |
| 1810 // Wait for a quit message. |
| 1811 EXPECT_EQ("quit", ReadMessage(h)); |
| 1812 } |
| 1813 |
| 1814 DEFINE_TEST_CLIENT_TEST_WITH_PIPE(ReadAndCloseConsumer, DataPipeTest, h) { |
| 1815 MojoHandle c; |
| 1816 std::string expected_message = ReadMessageWithHandles(h, &c, 1); |
| 1817 |
| 1818 // Wait for the consumer to become readable. |
| 1819 EXPECT_EQ(MOJO_RESULT_OK, MojoWait(c, MOJO_HANDLE_SIGNAL_READABLE, |
| 1820 MOJO_DEADLINE_INDEFINITE, nullptr)); |
| 1821 |
| 1822 // Drain the consumer and expect to find the given message. |
| 1823 uint32_t num_bytes = static_cast<uint32_t>(expected_message.size()); |
| 1824 std::vector<char> bytes(expected_message.size()); |
| 1825 EXPECT_EQ(MOJO_RESULT_OK, MojoReadData(c, bytes.data(), &num_bytes, |
| 1826 MOJO_READ_DATA_FLAG_NONE)); |
| 1827 EXPECT_EQ(num_bytes, static_cast<uint32_t>(bytes.size())); |
| 1828 |
| 1829 std::string message(bytes.data(), bytes.size()); |
| 1830 EXPECT_EQ(expected_message, message); |
| 1831 |
| 1832 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(c)); |
| 1833 |
| 1834 // Wait for a quit message. |
| 1835 EXPECT_EQ("quit", ReadMessage(h)); |
| 1836 } |
| 1837 |
| 1838 TEST_F(DataPipeTest, SendConsumerAndCloseProducer) { |
| 1839 // Create a new data pipe. |
| 1840 MojoHandle p, c; |
| 1841 EXPECT_EQ(MOJO_RESULT_OK, MojoCreateDataPipe(nullptr, &p ,&c)); |
| 1842 |
| 1843 RUN_CHILD_ON_PIPE(WriteAndCloseProducer, producer_client) |
| 1844 RUN_CHILD_ON_PIPE(ReadAndCloseConsumer, consumer_client) |
| 1845 const std::string kMessage = "Hello, world!"; |
| 1846 WriteMessageWithHandles(producer_client, kMessage, &p, 1); |
| 1847 WriteMessageWithHandles(consumer_client, kMessage, &c, 1); |
| 1848 |
| 1849 WriteMessage(consumer_client, "quit"); |
| 1850 END_CHILD() |
| 1851 |
| 1852 WriteMessage(producer_client, "quit"); |
| 1853 END_CHILD() |
1848 } | 1854 } |
1849 | 1855 |
1850 } // namespace | 1856 } // namespace |
1851 } // namespace edk | 1857 } // namespace edk |
1852 } // namespace mojo | 1858 } // namespace mojo |
OLD | NEW |