| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/edk/embedder/embedder.h" | 5 #include "mojo/edk/embedder/embedder.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <utility> | 10 #include <utility> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
| 16 #include "base/synchronization/waitable_event.h" | 16 #include "base/synchronization/waitable_event.h" |
| 17 #include "base/test/test_timeouts.h" | 17 #include "base/test/test_timeouts.h" |
| 18 #include "mojo/edk/embedder/embedder.h" | 18 #include "mojo/edk/embedder/embedder.h" |
| 19 #include "mojo/edk/embedder/platform_channel_pair.h" | 19 #include "mojo/edk/embedder/platform_channel_pair.h" |
| 20 #include "mojo/edk/embedder/simple_platform_support.h" | 20 #include "mojo/edk/embedder/simple_platform_support.h" |
| 21 #include "mojo/edk/embedder/test_embedder.h" | 21 #include "mojo/edk/embedder/test_embedder.h" |
| 22 #include "mojo/edk/system/test_utils.h" | 22 #include "mojo/edk/system/test_utils.h" |
| 23 #include "mojo/edk/test/multiprocess_test_helper.h" | 23 #include "mojo/edk/test/mojo_test_base.h" |
| 24 #include "mojo/message_pump/message_pump_mojo.h" | 24 #include "mojo/message_pump/message_pump_mojo.h" |
| 25 #include "mojo/public/c/system/core.h" | 25 #include "mojo/public/c/system/core.h" |
| 26 #include "mojo/public/cpp/system/handle.h" | 26 #include "mojo/public/cpp/system/handle.h" |
| 27 #include "mojo/public/cpp/system/macros.h" | 27 #include "mojo/public/cpp/system/macros.h" |
| 28 #include "mojo/public/cpp/system/message_pipe.h" | 28 #include "mojo/public/cpp/system/message_pipe.h" |
| 29 #include "testing/gtest/include/gtest/gtest.h" | 29 #include "testing/gtest/include/gtest/gtest.h" |
| 30 | 30 |
| 31 namespace mojo { | 31 namespace mojo { |
| 32 namespace edk { | 32 namespace edk { |
| 33 namespace { | 33 namespace { |
| 34 | 34 |
| 35 const MojoHandleSignals kSignalReadadableWritable = | 35 const MojoHandleSignals kSignalReadadableWritable = |
| 36 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE; | 36 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE; |
| 37 | 37 |
| 38 const MojoHandleSignals kSignalAll = MOJO_HANDLE_SIGNAL_READABLE | | 38 const MojoHandleSignals kSignalAll = MOJO_HANDLE_SIGNAL_READABLE | |
| 39 MOJO_HANDLE_SIGNAL_WRITABLE | | 39 MOJO_HANDLE_SIGNAL_WRITABLE | |
| 40 MOJO_HANDLE_SIGNAL_PEER_CLOSED; | 40 MOJO_HANDLE_SIGNAL_PEER_CLOSED; |
| 41 | 41 |
| 42 typedef testing::Test EmbedderTest; | 42 using EmbedderTest = test::MojoTestBase; |
| 43 | 43 |
| 44 TEST_F(EmbedderTest, ChannelBasic) { | 44 TEST_F(EmbedderTest, ChannelBasic) { |
| 45 MojoHandle server_mp, client_mp; | 45 MojoHandle server_mp, client_mp; |
| 46 ASSERT_EQ(MOJO_RESULT_OK, | 46 CreateMessagePipe(&server_mp, &client_mp); |
| 47 MojoCreateMessagePipe(nullptr, &server_mp, &client_mp)); | 47 |
| 48 const std::string kHello = "hello"; |
| 48 | 49 |
| 49 // We can write to a message pipe handle immediately. | 50 // We can write to a message pipe handle immediately. |
| 50 const char kHello[] = "hello"; | 51 WriteMessage(server_mp, kHello); |
| 51 | 52 EXPECT_EQ(kHello, ReadMessage(client_mp)); |
| 52 size_t write_size = sizeof(kHello); | |
| 53 const char* write_buffer = kHello; | |
| 54 ASSERT_EQ(MOJO_RESULT_OK, | |
| 55 MojoWriteMessage(server_mp, write_buffer, | |
| 56 static_cast<uint32_t>(write_size), nullptr, 0, | |
| 57 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 58 | |
| 59 // Now wait for the other side to become readable. | |
| 60 MojoHandleSignalsState state; | |
| 61 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE, | |
| 62 MOJO_DEADLINE_INDEFINITE, &state)); | |
| 63 ASSERT_EQ(kSignalReadadableWritable, state.satisfied_signals); | |
| 64 ASSERT_EQ(kSignalAll, state.satisfiable_signals); | |
| 65 | |
| 66 char read_buffer[1000] = {}; | |
| 67 uint32_t num_bytes = static_cast<uint32_t>(sizeof(read_buffer)); | |
| 68 ASSERT_EQ(MOJO_RESULT_OK, | |
| 69 MojoReadMessage(client_mp, read_buffer, &num_bytes, nullptr, | |
| 70 nullptr, MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 71 ASSERT_EQ(write_size, num_bytes); | |
| 72 EXPECT_STREQ(kHello, read_buffer); | |
| 73 | 53 |
| 74 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(server_mp)); | 54 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(server_mp)); |
| 75 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(client_mp)); | 55 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(client_mp)); |
| 76 } | 56 } |
| 77 | 57 |
| 78 // Test sending a MP which has read messages out of the OS pipe but which have | 58 // Test sending a MP which has read messages out of the OS pipe but which have |
| 79 // not been consumed using MojoReadMessage yet. | 59 // not been consumed using MojoReadMessage yet. |
| 80 TEST_F(EmbedderTest, SendReadableMessagePipe) { | 60 TEST_F(EmbedderTest, SendReadableMessagePipe) { |
| 81 MojoHandle server_mp, client_mp; | 61 MojoHandle server_mp, client_mp; |
| 82 ASSERT_EQ(MOJO_RESULT_OK, | 62 CreateMessagePipe(&server_mp, &client_mp); |
| 83 MojoCreateMessagePipe(nullptr, &server_mp, &client_mp)); | |
| 84 | 63 |
| 85 MojoHandle server_mp2, client_mp2; | 64 MojoHandle server_mp2, client_mp2; |
| 86 MojoCreateMessagePipeOptions options; | 65 CreateMessagePipe(&server_mp2, &client_mp2); |
| 87 options.struct_size = sizeof(MojoCreateMessagePipeOptions); | |
| 88 options.flags = MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_TRANSFERABLE; | |
| 89 ASSERT_EQ(MOJO_RESULT_OK, | |
| 90 MojoCreateMessagePipe(&options, &server_mp2, &client_mp2)); | |
| 91 | 66 |
| 92 // Write to server2 and wait for client2 to be readable before sending it. | 67 // Write to server2 and wait for client2 to be readable before sending it. |
| 93 // client2's MessagePipeDispatcher will have the message below in its | 68 // client2's MessagePipeDispatcher will have the message below in its |
| 94 // message_queue_. For extra measures, also verify that this pending message | 69 // message_queue_. For extra measures, also verify that this pending message |
| 95 // can contain a message pipe. | 70 // can contain a message pipe. |
| 96 MojoHandle server_mp3, client_mp3; | 71 MojoHandle server_mp3, client_mp3; |
| 97 ASSERT_EQ(MOJO_RESULT_OK, | 72 CreateMessagePipe(&server_mp3, &client_mp3); |
| 98 MojoCreateMessagePipe(nullptr, &server_mp3, &client_mp3)); | 73 |
| 99 const char kHello[] = "hello"; | 74 const std::string kHello = "hello"; |
| 100 size_t write_size; | 75 WriteMessageWithHandles(server_mp2, kHello, &client_mp3, 1); |
| 101 const char* write_buffer; | |
| 102 write_buffer = kHello; | |
| 103 write_size = sizeof(kHello); | |
| 104 ASSERT_EQ(MOJO_RESULT_OK, | |
| 105 MojoWriteMessage(server_mp2, write_buffer, | |
| 106 static_cast<uint32_t>(write_size), &client_mp3, 1, | |
| 107 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 108 | 76 |
| 109 MojoHandleSignalsState state; | 77 MojoHandleSignalsState state; |
| 110 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(client_mp2, MOJO_HANDLE_SIGNAL_READABLE, | 78 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(client_mp2, MOJO_HANDLE_SIGNAL_READABLE, |
| 111 MOJO_DEADLINE_INDEFINITE, &state)); | 79 MOJO_DEADLINE_INDEFINITE, &state)); |
| 112 ASSERT_EQ(kSignalReadadableWritable, state.satisfied_signals); | 80 ASSERT_EQ(kSignalReadadableWritable, state.satisfied_signals); |
| 113 ASSERT_EQ(kSignalAll, state.satisfiable_signals); | 81 ASSERT_EQ(kSignalAll, state.satisfiable_signals); |
| 114 | 82 |
| 115 // Now send client2 | 83 // Now send client2 |
| 116 ASSERT_EQ(MOJO_RESULT_OK, | 84 WriteMessageWithHandles(server_mp, kHello, &client_mp2, 1); |
| 117 MojoWriteMessage(server_mp, write_buffer, | |
| 118 static_cast<uint32_t>(write_size), &client_mp2, 1, | |
| 119 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 120 | 85 |
| 86 MojoHandle port; |
| 87 std::string message = ReadMessageWithHandles(client_mp, &port, 1); |
| 88 EXPECT_EQ(kHello, message); |
| 121 | 89 |
| 122 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE, | 90 client_mp2 = port; |
| 123 MOJO_DEADLINE_INDEFINITE, &state)); | 91 message = ReadMessageWithHandles(client_mp2, &client_mp3, 1); |
| 124 ASSERT_EQ(kSignalReadadableWritable, state.satisfied_signals); | 92 EXPECT_EQ(kHello, message); |
| 125 ASSERT_EQ(kSignalAll, state.satisfiable_signals); | |
| 126 | |
| 127 char read_buffer[20000] = {}; | |
| 128 uint32_t num_bytes = static_cast<uint32_t>(sizeof(read_buffer)); | |
| 129 MojoHandle ports[10]; | |
| 130 uint32_t num_ports = arraysize(ports); | |
| 131 ASSERT_EQ(MOJO_RESULT_OK, | |
| 132 MojoReadMessage(client_mp, read_buffer, &num_bytes, &ports[0], | |
| 133 &num_ports, MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 134 ASSERT_EQ(write_size, num_bytes); | |
| 135 EXPECT_STREQ(kHello, read_buffer); | |
| 136 ASSERT_EQ(1u, num_ports); | |
| 137 | |
| 138 | |
| 139 client_mp2 = ports[0]; | |
| 140 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(client_mp2, MOJO_HANDLE_SIGNAL_READABLE, | |
| 141 MOJO_DEADLINE_INDEFINITE, &state)); | |
| 142 ASSERT_EQ(kSignalReadadableWritable, state.satisfied_signals); | |
| 143 ASSERT_EQ(kSignalAll, state.satisfiable_signals); | |
| 144 | |
| 145 | |
| 146 ASSERT_EQ(MOJO_RESULT_OK, | |
| 147 MojoReadMessage(client_mp2, read_buffer, &num_bytes, &client_mp3, | |
| 148 &num_ports, MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 149 ASSERT_EQ(write_size, num_bytes); | |
| 150 EXPECT_STREQ(kHello, read_buffer); | |
| 151 ASSERT_EQ(1u, num_ports); | |
| 152 | |
| 153 | 93 |
| 154 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(server_mp3)); | 94 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(server_mp3)); |
| 155 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(client_mp3)); | 95 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(client_mp3)); |
| 156 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(server_mp2)); | 96 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(server_mp2)); |
| 157 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(client_mp2)); | 97 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(client_mp2)); |
| 158 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(server_mp)); | 98 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(server_mp)); |
| 159 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(client_mp)); | 99 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(client_mp)); |
| 160 } | 100 } |
| 161 | 101 |
| 162 // Verifies that a MP with pending messages to be written can be sent and the | 102 // Verifies that a MP with pending messages to be written can be sent and the |
| 163 // pending messages aren't dropped. | 103 // pending messages aren't dropped. |
| 164 TEST_F(EmbedderTest, SendMessagePipeWithWriteQueue) { | 104 TEST_F(EmbedderTest, SendMessagePipeWithWriteQueue) { |
| 165 MojoHandle server_mp, client_mp; | 105 MojoHandle server_mp, client_mp; |
| 166 ASSERT_EQ(MOJO_RESULT_OK, | 106 CreateMessagePipe(&server_mp, &client_mp); |
| 167 MojoCreateMessagePipe(nullptr, &server_mp, &client_mp)); | |
| 168 | 107 |
| 169 MojoCreateMessagePipeOptions options; | |
| 170 options.struct_size = sizeof(MojoCreateMessagePipeOptions); | |
| 171 options.flags = MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_TRANSFERABLE; | |
| 172 MojoHandle server_mp2, client_mp2; | 108 MojoHandle server_mp2, client_mp2; |
| 173 ASSERT_EQ(MOJO_RESULT_OK, | 109 CreateMessagePipe(&server_mp2, &client_mp2); |
| 174 MojoCreateMessagePipe(&options, &server_mp2, &client_mp2)); | |
| 175 | 110 |
| 176 static const size_t kNumMessages = 1001; | 111 static const size_t kNumMessages = 1001; |
| 177 for (size_t i = 0; i < kNumMessages; i++) { | 112 for (size_t i = 1; i <= kNumMessages; i++) |
| 178 std::string write_buffer(i, 'A' + (i % 26)); | 113 WriteMessage(client_mp2, std::string(i, 'A' + (i % 26))); |
| 179 ASSERT_EQ(MOJO_RESULT_OK, | |
| 180 MojoWriteMessage(client_mp2, write_buffer.data(), | |
| 181 static_cast<uint32_t>(write_buffer.size()), | |
| 182 nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 183 } | |
| 184 | 114 |
| 185 // Now send client2. | 115 // Now send client2. |
| 186 ASSERT_EQ(MOJO_RESULT_OK, | 116 WriteMessageWithHandles(server_mp, "hey", &client_mp2, 1); |
| 187 MojoWriteMessage(server_mp, nullptr, 0, &client_mp2, 1, | |
| 188 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 189 client_mp2 = MOJO_HANDLE_INVALID; | 117 client_mp2 = MOJO_HANDLE_INVALID; |
| 190 | 118 |
| 191 // Read client2 just so we can close it later. | 119 // Read client2 just so we can close it later. |
| 192 MojoHandleSignalsState state; | 120 EXPECT_EQ("hey", ReadMessageWithHandles(client_mp, &client_mp2, 1)); |
| 193 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE, | 121 EXPECT_NE(MOJO_HANDLE_INVALID, client_mp2); |
| 194 MOJO_DEADLINE_INDEFINITE, &state)); | |
| 195 ASSERT_EQ(kSignalReadadableWritable, state.satisfied_signals); | |
| 196 ASSERT_EQ(kSignalAll, state.satisfiable_signals); | |
| 197 | |
| 198 uint32_t num_handles = 1; | |
| 199 ASSERT_EQ(MOJO_RESULT_OK, MojoReadMessage(client_mp, nullptr, 0, &client_mp2, | |
| 200 &num_handles, | |
| 201 MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 202 ASSERT_EQ(1u, num_handles); | |
| 203 | 122 |
| 204 // Now verify that all the messages that were written were sent correctly. | 123 // Now verify that all the messages that were written were sent correctly. |
| 205 for (size_t i = 0; i < kNumMessages; i++) { | 124 for (size_t i = 1; i <= kNumMessages; i++) |
| 206 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(server_mp2, MOJO_HANDLE_SIGNAL_READABLE, | 125 ASSERT_EQ(std::string(i, 'A' + (i % 26)), ReadMessage(server_mp2)); |
| 207 MOJO_DEADLINE_INDEFINITE, &state)); | |
| 208 ASSERT_EQ(kSignalReadadableWritable, state.satisfied_signals); | |
| 209 ASSERT_EQ(kSignalAll, state.satisfiable_signals); | |
| 210 | |
| 211 std::string read_buffer(kNumMessages * 2, '\0'); | |
| 212 uint32_t read_buffer_size = static_cast<uint32_t>(read_buffer.size()); | |
| 213 ASSERT_EQ(MOJO_RESULT_OK, MojoReadMessage(server_mp2, &read_buffer[0], | |
| 214 &read_buffer_size, nullptr, 0, | |
| 215 MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 216 read_buffer.resize(read_buffer_size); | |
| 217 | |
| 218 ASSERT_EQ(std::string(i, 'A' + (i % 26)), read_buffer); | |
| 219 } | |
| 220 | 126 |
| 221 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(server_mp2)); | 127 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(server_mp2)); |
| 222 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(client_mp2)); | 128 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(client_mp2)); |
| 223 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(server_mp)); | 129 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(server_mp)); |
| 224 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(client_mp)); | 130 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(client_mp)); |
| 225 } | 131 } |
| 226 | 132 |
| 227 TEST_F(EmbedderTest, ChannelsHandlePassing) { | 133 TEST_F(EmbedderTest, ChannelsHandlePassing) { |
| 228 MojoHandle server_mp, client_mp; | 134 MojoHandle server_mp, client_mp; |
| 229 ASSERT_EQ(MOJO_RESULT_OK, | 135 CreateMessagePipe(&server_mp, &client_mp); |
| 230 MojoCreateMessagePipe(nullptr, &server_mp, &client_mp)); | |
| 231 EXPECT_NE(server_mp, MOJO_HANDLE_INVALID); | 136 EXPECT_NE(server_mp, MOJO_HANDLE_INVALID); |
| 232 EXPECT_NE(client_mp, MOJO_HANDLE_INVALID); | 137 EXPECT_NE(client_mp, MOJO_HANDLE_INVALID); |
| 233 | 138 |
| 234 MojoHandle h0, h1; | 139 MojoHandle h0, h1; |
| 235 ASSERT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(nullptr, &h0, &h1)); | 140 CreateMessagePipe(&h0, &h1); |
| 236 | 141 |
| 237 // Write a message to |h0| (attaching nothing). | 142 // Write a message to |h0| (attaching nothing). |
| 238 const char kHello[] = "hello"; | 143 const std::string kHello = "hello"; |
| 239 ASSERT_EQ(MOJO_RESULT_OK, | 144 WriteMessage(h0, kHello); |
| 240 MojoWriteMessage(h0, kHello, static_cast<uint32_t>(sizeof(kHello)), | |
| 241 nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 242 | 145 |
| 243 // Write one message to |server_mp|, attaching |h1|. | 146 // Write one message to |server_mp|, attaching |h1|. |
| 244 const char kWorld[] = "world!!!"; | 147 const std::string kWorld = "world!!!"; |
| 245 ASSERT_EQ( | 148 WriteMessageWithHandles(server_mp, kWorld, &h1, 1); |
| 246 MOJO_RESULT_OK, | |
| 247 MojoWriteMessage(server_mp, kWorld, static_cast<uint32_t>(sizeof(kWorld)), | |
| 248 &h1, 1, MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 249 h1 = MOJO_HANDLE_INVALID; | 149 h1 = MOJO_HANDLE_INVALID; |
| 250 | 150 |
| 251 // Write another message to |h0|. | 151 // Write another message to |h0|. |
| 252 const char kFoo[] = "foo"; | 152 const std::string kFoo = "foo"; |
| 253 ASSERT_EQ(MOJO_RESULT_OK, | 153 WriteMessage(h0, kFoo); |
| 254 MojoWriteMessage(h0, kFoo, static_cast<uint32_t>(sizeof(kFoo)), | |
| 255 nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 256 | 154 |
| 257 // Wait for |client_mp| to become readable. | 155 // Wait for |client_mp| to become readable and read a message from it. |
| 258 MojoHandleSignalsState state; | 156 EXPECT_EQ(kWorld, ReadMessageWithHandles(client_mp, &h1, 1)); |
| 259 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE, | 157 EXPECT_NE(h1, MOJO_HANDLE_INVALID); |
| 260 MOJO_DEADLINE_INDEFINITE, &state)); | |
| 261 ASSERT_EQ(kSignalReadadableWritable, state.satisfied_signals); | |
| 262 ASSERT_EQ(kSignalAll, state.satisfiable_signals); | |
| 263 | 158 |
| 264 // Read a message from |client_mp|. | 159 // Wait for |h1| to become readable and read a message from it. |
| 265 char buffer[1000] = {}; | 160 EXPECT_EQ(kHello, ReadMessage(h1)); |
| 266 uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer)); | |
| 267 MojoHandle handles[10] = {}; | |
| 268 uint32_t num_handles = MOJO_ARRAYSIZE(handles); | |
| 269 ASSERT_EQ(MOJO_RESULT_OK, | |
| 270 MojoReadMessage(client_mp, buffer, &num_bytes, handles, | |
| 271 &num_handles, MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 272 ASSERT_EQ(sizeof(kWorld), num_bytes); | |
| 273 EXPECT_STREQ(kWorld, buffer); | |
| 274 ASSERT_EQ(1u, num_handles); | |
| 275 EXPECT_NE(handles[0], MOJO_HANDLE_INVALID); | |
| 276 h1 = handles[0]; | |
| 277 | 161 |
| 278 // Wait for |h1| to become readable. | 162 // Wait for |h1| to become readable (again) and read its second message. |
| 279 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(h1, MOJO_HANDLE_SIGNAL_READABLE, | 163 EXPECT_EQ(kFoo, ReadMessage(h1)); |
| 280 MOJO_DEADLINE_INDEFINITE, &state)); | |
| 281 ASSERT_EQ(kSignalReadadableWritable, state.satisfied_signals); | |
| 282 ASSERT_EQ(kSignalAll, state.satisfiable_signals); | |
| 283 | |
| 284 // Read a message from |h1|. | |
| 285 memset(buffer, 0, sizeof(buffer)); | |
| 286 num_bytes = static_cast<uint32_t>(sizeof(buffer)); | |
| 287 memset(handles, 0, sizeof(handles)); | |
| 288 num_handles = MOJO_ARRAYSIZE(handles); | |
| 289 ASSERT_EQ(MOJO_RESULT_OK, | |
| 290 MojoReadMessage(h1, buffer, &num_bytes, handles, &num_handles, | |
| 291 MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 292 ASSERT_EQ(sizeof(kHello), num_bytes); | |
| 293 EXPECT_STREQ(kHello, buffer); | |
| 294 ASSERT_EQ(0u, num_handles); | |
| 295 | |
| 296 // Wait for |h1| to become readable (again). | |
| 297 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(h1, MOJO_HANDLE_SIGNAL_READABLE, | |
| 298 MOJO_DEADLINE_INDEFINITE, &state)); | |
| 299 ASSERT_EQ(kSignalReadadableWritable, state.satisfied_signals); | |
| 300 ASSERT_EQ(kSignalAll, state.satisfiable_signals); | |
| 301 | |
| 302 // Read the second message from |h1|. | |
| 303 memset(buffer, 0, sizeof(buffer)); | |
| 304 num_bytes = static_cast<uint32_t>(sizeof(buffer)); | |
| 305 ASSERT_EQ(MOJO_RESULT_OK, | |
| 306 MojoReadMessage(h1, buffer, &num_bytes, nullptr, nullptr, | |
| 307 MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 308 ASSERT_EQ(sizeof(kFoo), num_bytes); | |
| 309 EXPECT_STREQ(kFoo, buffer); | |
| 310 | 164 |
| 311 // Write a message to |h1|. | 165 // Write a message to |h1|. |
| 312 const char kBarBaz[] = "barbaz"; | 166 const std::string kBarBaz = "barbaz"; |
| 313 ASSERT_EQ( | 167 WriteMessage(h1, kBarBaz); |
| 314 MOJO_RESULT_OK, | |
| 315 MojoWriteMessage(h1, kBarBaz, static_cast<uint32_t>(sizeof(kBarBaz)), | |
| 316 nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 317 | 168 |
| 318 // Wait for |h0| to become readable. | 169 // Wait for |h0| to become readable and read a message from it. |
| 319 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(h0, MOJO_HANDLE_SIGNAL_READABLE, | 170 EXPECT_EQ(kBarBaz, ReadMessage(h0)); |
| 320 MOJO_DEADLINE_INDEFINITE, &state)); | |
| 321 ASSERT_EQ(kSignalReadadableWritable, state.satisfied_signals); | |
| 322 ASSERT_EQ(kSignalAll, state.satisfiable_signals); | |
| 323 | |
| 324 // Read a message from |h0|. | |
| 325 memset(buffer, 0, sizeof(buffer)); | |
| 326 num_bytes = static_cast<uint32_t>(sizeof(buffer)); | |
| 327 ASSERT_EQ(MOJO_RESULT_OK, | |
| 328 MojoReadMessage(h0, buffer, &num_bytes, nullptr, nullptr, | |
| 329 MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 330 ASSERT_EQ(sizeof(kBarBaz), num_bytes); | |
| 331 EXPECT_STREQ(kBarBaz, buffer); | |
| 332 | 171 |
| 333 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(server_mp)); | 172 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(server_mp)); |
| 334 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(client_mp)); | 173 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(client_mp)); |
| 335 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(h0)); | 174 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(h0)); |
| 336 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(h1)); | 175 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(h1)); |
| 337 } | 176 } |
| 338 | 177 |
| 339 // The sequence of messages sent is: | 178 // The sequence of messages sent is: |
| 340 // server_mp client_mp mp0 mp1 mp2 mp3 | 179 // server_mp client_mp mp0 mp1 mp2 mp3 |
| 341 // 1. "hello" | 180 // 1. "hello" |
| 342 // 2. "world!" | 181 // 2. "world!" |
| 343 // 3. "FOO" | 182 // 3. "FOO" |
| 344 // 4. "Bar"+mp1 | 183 // 4. "Bar"+mp1 |
| 345 // 5. (close) | 184 // 5. (close) |
| 346 // 6. (close) | 185 // 6. (close) |
| 347 // 7. "baz" | 186 // 7. "baz" |
| 348 // 8. (closed) | 187 // 8. (closed) |
| 349 // 9. "quux"+mp2 | 188 // 9. "quux"+mp2 |
| 350 // 10. (close) | 189 // 10. (close) |
| 351 // 11. (wait/cl.) | 190 // 11. (wait/cl.) |
| 352 // 12. (wait/cl.) | 191 // 12. (wait/cl.) |
| 353 | 192 |
| 354 #if defined(OS_ANDROID) | 193 #if defined(OS_ANDROID) |
| 355 // Android multi-process tests are not executing the new process. This is flaky. | 194 // Android multi-process tests are not executing the new process. This is flaky. |
| 356 #define MAYBE_MultiprocessChannels DISABLED_MultiprocessChannels | 195 #define MAYBE_MultiprocessChannels DISABLED_MultiprocessChannels |
| 357 #else | 196 #else |
| 358 #define MAYBE_MultiprocessChannels MultiprocessChannels | 197 #define MAYBE_MultiprocessChannels MultiprocessChannels |
| 359 #endif // defined(OS_ANDROID) | 198 #endif // defined(OS_ANDROID) |
| 360 TEST_F(EmbedderTest, MAYBE_MultiprocessChannels) { | 199 TEST_F(EmbedderTest, MAYBE_MultiprocessChannels) { |
| 361 test::MultiprocessTestHelper multiprocess_test_helper; | 200 RUN_CHILD_ON_PIPE(MultiprocessChannelsClient, server_mp) |
| 362 multiprocess_test_helper.StartChild("MultiprocessChannelsClient"); | |
| 363 | |
| 364 { | |
| 365 MojoHandle server_mp = | |
| 366 CreateMessagePipe( | |
| 367 std::move(multiprocess_test_helper.server_platform_handle)) | |
| 368 .release() | |
| 369 .value(); | |
| 370 | |
| 371 // 1. Write a message to |server_mp| (attaching nothing). | 201 // 1. Write a message to |server_mp| (attaching nothing). |
| 372 const char kHello[] = "hello"; | 202 WriteMessage(server_mp, "hello"); |
| 373 ASSERT_EQ(MOJO_RESULT_OK, | |
| 374 MojoWriteMessage(server_mp, kHello, | |
| 375 static_cast<uint32_t>(sizeof(kHello)), nullptr, | |
| 376 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 377 | |
| 378 // TODO(vtl): If the scope were ended immediately here (maybe after closing | |
| 379 // |server_mp|), we die with a fatal error in |Channel::HandleLocalError()|. | |
| 380 | 203 |
| 381 // 2. Read a message from |server_mp|. | 204 // 2. Read a message from |server_mp|. |
| 382 MojoHandleSignalsState state; | 205 EXPECT_EQ("world!", ReadMessage(server_mp)); |
| 383 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(server_mp, MOJO_HANDLE_SIGNAL_READABLE, | |
| 384 MOJO_DEADLINE_INDEFINITE, &state)); | |
| 385 ASSERT_EQ(kSignalReadadableWritable, state.satisfied_signals); | |
| 386 ASSERT_EQ(kSignalAll, state.satisfiable_signals); | |
| 387 | 206 |
| 388 char buffer[1000] = {}; | 207 // 3. Create a new message pipe (endpoints |mp0| and |mp1|). |
| 389 uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer)); | 208 MojoHandle mp0, mp1; |
| 390 ASSERT_EQ(MOJO_RESULT_OK, | 209 CreateMessagePipe(&mp0, &mp1); |
| 391 MojoReadMessage(server_mp, buffer, &num_bytes, nullptr, nullptr, | |
| 392 MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 393 const char kWorld[] = "world!"; | |
| 394 ASSERT_EQ(sizeof(kWorld), num_bytes); | |
| 395 EXPECT_STREQ(kWorld, buffer); | |
| 396 | 210 |
| 397 // Create a new message pipe (endpoints |mp0| and |mp1|). | 211 // 4. Write something to |mp0|. |
| 398 MojoHandle mp0, mp1; | 212 WriteMessage(mp0, "FOO"); |
| 399 ASSERT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(nullptr, &mp0, &mp1)); | |
| 400 | 213 |
| 401 // 3. Write something to |mp0|. | 214 // 5. Write a message to |server_mp|, attaching |mp1|. |
| 402 const char kFoo[] = "FOO"; | 215 WriteMessageWithHandles(server_mp, "Bar", &mp1, 1); |
| 403 ASSERT_EQ(MOJO_RESULT_OK, | |
| 404 MojoWriteMessage(mp0, kFoo, static_cast<uint32_t>(sizeof(kFoo)), | |
| 405 nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 406 | |
| 407 // 4. Write a message to |server_mp|, attaching |mp1|. | |
| 408 const char kBar[] = "Bar"; | |
| 409 ASSERT_EQ( | |
| 410 MOJO_RESULT_OK, | |
| 411 MojoWriteMessage(server_mp, kBar, static_cast<uint32_t>(sizeof(kBar)), | |
| 412 &mp1, 1, MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 413 mp1 = MOJO_HANDLE_INVALID; | 216 mp1 = MOJO_HANDLE_INVALID; |
| 414 | 217 |
| 415 // 5. Close |server_mp|. | 218 // 6. Read a message from |mp0|, which should have |mp2| attached. |
| 416 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(server_mp)); | |
| 417 | |
| 418 // 9. Read a message from |mp0|, which should have |mp2| attached. | |
| 419 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(mp0, MOJO_HANDLE_SIGNAL_READABLE, | |
| 420 MOJO_DEADLINE_INDEFINITE, &state)); | |
| 421 ASSERT_EQ(kSignalReadadableWritable, state.satisfied_signals); | |
| 422 ASSERT_EQ(kSignalAll, state.satisfiable_signals); | |
| 423 | |
| 424 memset(buffer, 0, sizeof(buffer)); | |
| 425 num_bytes = static_cast<uint32_t>(sizeof(buffer)); | |
| 426 MojoHandle mp2 = MOJO_HANDLE_INVALID; | 219 MojoHandle mp2 = MOJO_HANDLE_INVALID; |
| 427 uint32_t num_handles = 1; | 220 EXPECT_EQ("quux", ReadMessageWithHandles(mp0, &mp2, 1)); |
| 428 ASSERT_EQ(MOJO_RESULT_OK, | |
| 429 MojoReadMessage(mp0, buffer, &num_bytes, &mp2, &num_handles, | |
| 430 MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 431 const char kQuux[] = "quux"; | |
| 432 ASSERT_EQ(sizeof(kQuux), num_bytes); | |
| 433 EXPECT_STREQ(kQuux, buffer); | |
| 434 ASSERT_EQ(1u, num_handles); | |
| 435 EXPECT_NE(mp2, MOJO_HANDLE_INVALID); | |
| 436 | 221 |
| 437 // 7. Read a message from |mp2|. | 222 // 7. Read a message from |mp2|. |
| 438 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(mp2, MOJO_HANDLE_SIGNAL_PEER_CLOSED, | 223 EXPECT_EQ("baz", ReadMessage(mp2)); |
| 439 MOJO_DEADLINE_INDEFINITE, &state)); | |
| 440 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, | |
| 441 state.satisfied_signals); | |
| 442 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, | |
| 443 state.satisfiable_signals); | |
| 444 | 224 |
| 445 memset(buffer, 0, sizeof(buffer)); | 225 // 8. Close |mp0|. |
| 446 num_bytes = static_cast<uint32_t>(sizeof(buffer)); | |
| 447 ASSERT_EQ(MOJO_RESULT_OK, | |
| 448 MojoReadMessage(mp2, buffer, &num_bytes, nullptr, nullptr, | |
| 449 MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 450 const char kBaz[] = "baz"; | |
| 451 ASSERT_EQ(sizeof(kBaz), num_bytes); | |
| 452 EXPECT_STREQ(kBaz, buffer); | |
| 453 | |
| 454 // 10. Close |mp0|. | |
| 455 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(mp0)); | 226 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(mp0)); |
| 456 | 227 |
| 457 // 12. Wait on |mp2| (which should eventually fail) and then close it. | 228 // 9. Tell the client to quit. |
| 458 // TODO(vtl): crbug.com/351768 | 229 WriteMessage(server_mp, "quit"); |
| 459 #if 0 | 230 |
| 231 // 10. Wait on |mp2| (which should eventually fail) and then close it. |
| 232 MojoHandleSignalsState state; |
| 460 ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | 233 ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION, |
| 461 MojoWait(mp2, MOJO_HANDLE_SIGNAL_READABLE, | 234 MojoWait(mp2, MOJO_HANDLE_SIGNAL_READABLE, |
| 462 MOJO_DEADLINE_INDEFINITE, | 235 MOJO_DEADLINE_INDEFINITE, |
| 463 &state)); | 236 &state)); |
| 464 ASSERT_EQ(MOJO_HANDLE_SIGNAL_NONE, state.satisfied_signals); | 237 ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfied_signals); |
| 465 ASSERT_EQ(MOJO_HANDLE_SIGNAL_NONE, state.satisfiable_signals); | 238 ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfiable_signals); |
| 466 #endif | 239 |
| 467 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(mp2)); | 240 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(mp2)); |
| 468 } | 241 END_CHILD() |
| 469 | |
| 470 EXPECT_TRUE(multiprocess_test_helper.WaitForChildTestShutdown()); | |
| 471 } | 242 } |
| 472 | 243 |
| 473 MOJO_MULTIPROCESS_TEST_CHILD_TEST(MultiprocessChannelsClient) { | 244 DEFINE_TEST_CLIENT_TEST_WITH_PIPE(MultiprocessChannelsClient, EmbedderTest, |
| 474 ScopedPlatformHandle client_platform_handle = | 245 client_mp) { |
| 475 std::move(test::MultiprocessTestHelper::client_platform_handle); | |
| 476 EXPECT_TRUE(client_platform_handle.is_valid()); | |
| 477 | |
| 478 MojoHandle client_mp = | |
| 479 CreateMessagePipe(std::move(client_platform_handle)).release().value(); | |
| 480 | |
| 481 // 1. Read the first message from |client_mp|. | 246 // 1. Read the first message from |client_mp|. |
| 482 MojoHandleSignalsState state; | 247 EXPECT_EQ("hello", ReadMessage(client_mp)); |
| 483 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE, | |
| 484 MOJO_DEADLINE_INDEFINITE, &state)); | |
| 485 ASSERT_EQ(kSignalReadadableWritable, state.satisfied_signals); | |
| 486 ASSERT_EQ(kSignalAll, state.satisfiable_signals); | |
| 487 | |
| 488 char buffer[1000] = {}; | |
| 489 uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer)); | |
| 490 ASSERT_EQ(MOJO_RESULT_OK, | |
| 491 MojoReadMessage(client_mp, buffer, &num_bytes, nullptr, nullptr, | |
| 492 MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 493 const char kHello[] = "hello"; | |
| 494 ASSERT_EQ(sizeof(kHello), num_bytes); | |
| 495 EXPECT_STREQ(kHello, buffer); | |
| 496 | 248 |
| 497 // 2. Write a message to |client_mp| (attaching nothing). | 249 // 2. Write a message to |client_mp| (attaching nothing). |
| 498 const char kWorld[] = "world!"; | 250 WriteMessage(client_mp, "world!"); |
| 499 ASSERT_EQ(MOJO_RESULT_OK, | |
| 500 MojoWriteMessage(client_mp, kWorld, | |
| 501 static_cast<uint32_t>(sizeof(kWorld)), nullptr, | |
| 502 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 503 | 251 |
| 504 // 4. Read a message from |client_mp|, which should have |mp1| attached. | 252 // 4. Read a message from |client_mp|, which should have |mp1| attached. |
| 505 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE, | 253 MojoHandle mp1; |
| 506 MOJO_DEADLINE_INDEFINITE, &state)); | 254 EXPECT_EQ("Bar", ReadMessageWithHandles(client_mp, &mp1, 1)); |
| 507 // The other end of the handle may or may not be closed at this point, so we | |
| 508 // can't test MOJO_HANDLE_SIGNAL_WRITABLE or MOJO_HANDLE_SIGNAL_PEER_CLOSED. | |
| 509 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE, | |
| 510 state.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE); | |
| 511 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE, | |
| 512 state.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE); | |
| 513 // TODO(vtl): If the scope were to end here (and |client_mp| closed), we'd | |
| 514 // die (again due to |Channel::HandleLocalError()|). | |
| 515 memset(buffer, 0, sizeof(buffer)); | |
| 516 num_bytes = static_cast<uint32_t>(sizeof(buffer)); | |
| 517 MojoHandle mp1 = MOJO_HANDLE_INVALID; | |
| 518 uint32_t num_handles = 1; | |
| 519 ASSERT_EQ(MOJO_RESULT_OK, | |
| 520 MojoReadMessage(client_mp, buffer, &num_bytes, &mp1, &num_handles, | |
| 521 MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 522 const char kBar[] = "Bar"; | |
| 523 ASSERT_EQ(sizeof(kBar), num_bytes); | |
| 524 EXPECT_STREQ(kBar, buffer); | |
| 525 ASSERT_EQ(1u, num_handles); | |
| 526 EXPECT_NE(mp1, MOJO_HANDLE_INVALID); | |
| 527 // TODO(vtl): If the scope were to end here (and the two handles closed), | |
| 528 // we'd die due to |Channel::RunRemoteMessagePipeEndpoint()| not handling | |
| 529 // write errors (assuming the parent had closed the pipe). | |
| 530 | 255 |
| 531 // 6. Close |client_mp|. | 256 // 5. Create a new message pipe (endpoints |mp2| and |mp3|). |
| 532 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(client_mp)); | 257 MojoHandle mp2, mp3; |
| 258 CreateMessagePipe(&mp2, &mp3); |
| 533 | 259 |
| 534 // Create a new message pipe (endpoints |mp2| and |mp3|). | 260 // 6. Write a message to |mp3|. |
| 535 MojoHandle mp2, mp3; | 261 WriteMessage(mp3, "baz"); |
| 536 ASSERT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(nullptr, &mp2, &mp3)); | |
| 537 | 262 |
| 538 // 7. Write a message to |mp3|. | 263 // 7. Close |mp3|. |
| 539 const char kBaz[] = "baz"; | |
| 540 ASSERT_EQ(MOJO_RESULT_OK, | |
| 541 MojoWriteMessage(mp3, kBaz, static_cast<uint32_t>(sizeof(kBaz)), | |
| 542 nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 543 | |
| 544 // 8. Close |mp3|. | |
| 545 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(mp3)); | 264 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(mp3)); |
| 546 | 265 |
| 547 // 9. Write a message to |mp1|, attaching |mp2|. | 266 // 8. Write a message to |mp1|, attaching |mp2|. |
| 548 const char kQuux[] = "quux"; | 267 WriteMessageWithHandles(mp1, "quux", &mp2, 1); |
| 549 ASSERT_EQ(MOJO_RESULT_OK, | |
| 550 MojoWriteMessage(mp1, kQuux, static_cast<uint32_t>(sizeof(kQuux)), | |
| 551 &mp2, 1, MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 552 mp2 = MOJO_HANDLE_INVALID; | 268 mp2 = MOJO_HANDLE_INVALID; |
| 553 | 269 |
| 554 // 3. Read a message from |mp1|. | 270 // 9. Read a message from |mp1|. |
| 555 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE, | 271 EXPECT_EQ("FOO", ReadMessage(mp1)); |
| 556 MOJO_DEADLINE_INDEFINITE, &state)); | |
| 557 ASSERT_EQ(kSignalReadadableWritable, state.satisfied_signals); | |
| 558 ASSERT_EQ(kSignalAll, state.satisfiable_signals); | |
| 559 | 272 |
| 560 memset(buffer, 0, sizeof(buffer)); | 273 EXPECT_EQ("quit", ReadMessage(client_mp)); |
| 561 num_bytes = static_cast<uint32_t>(sizeof(buffer)); | |
| 562 ASSERT_EQ(MOJO_RESULT_OK, | |
| 563 MojoReadMessage(mp1, buffer, &num_bytes, nullptr, nullptr, | |
| 564 MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 565 const char kFoo[] = "FOO"; | |
| 566 ASSERT_EQ(sizeof(kFoo), num_bytes); | |
| 567 EXPECT_STREQ(kFoo, buffer); | |
| 568 | 274 |
| 569 // 11. Wait on |mp1| (which should eventually fail) and then close it. | 275 // 10. Wait on |mp1| (which should eventually fail) and then close it. |
| 276 MojoHandleSignalsState state; |
| 570 ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | 277 ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION, |
| 571 MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE, | 278 MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE, |
| 572 MOJO_DEADLINE_INDEFINITE, &state)); | 279 MOJO_DEADLINE_INDEFINITE, &state)); |
| 573 ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfied_signals); | 280 ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfied_signals); |
| 574 ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfiable_signals); | 281 ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfiable_signals); |
| 575 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(mp1)); | 282 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(mp1)); |
| 576 } | 283 } |
| 577 | 284 |
| 578 // TODO(vtl): Test immediate write & close. | 285 // TODO(vtl): Test immediate write & close. |
| 579 // TODO(vtl): Test broken-connection cases. | 286 // TODO(vtl): Test broken-connection cases. |
| 580 | 287 |
| 581 } // namespace | 288 } // namespace |
| 582 } // namespace edk | 289 } // namespace edk |
| 583 } // namespace mojo | 290 } // namespace mojo |
| OLD | NEW |