| OLD | NEW |
| (Empty) |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 // This file tests the C data pipe API (the functions declared in | |
| 6 // mojo/public/c/include/mojo/system/data_pipe.h). | |
| 7 | |
| 8 #include <mojo/system/data_pipe.h> | |
| 9 | |
| 10 #include <mojo/result.h> | |
| 11 #include <mojo/system/handle.h> | |
| 12 #include <mojo/system/wait.h> | |
| 13 #include <string.h> | |
| 14 | |
| 15 #include "gtest/gtest.h" | |
| 16 | |
| 17 namespace { | |
| 18 | |
| 19 const MojoHandleRights kDefaultDataPipeProducerHandleRights = | |
| 20 MOJO_HANDLE_RIGHT_TRANSFER | MOJO_HANDLE_RIGHT_WRITE | | |
| 21 MOJO_HANDLE_RIGHT_GET_OPTIONS | MOJO_HANDLE_RIGHT_SET_OPTIONS; | |
| 22 const MojoHandleRights kDefaultDataPipeConsumerHandleRights = | |
| 23 MOJO_HANDLE_RIGHT_TRANSFER | MOJO_HANDLE_RIGHT_READ | | |
| 24 MOJO_HANDLE_RIGHT_GET_OPTIONS | MOJO_HANDLE_RIGHT_SET_OPTIONS; | |
| 25 | |
| 26 TEST(DataPipeTest, InvalidHandle) { | |
| 27 MojoDataPipeProducerOptions dpp_options = { | |
| 28 sizeof(MojoDataPipeProducerOptions), 0u}; | |
| 29 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
| 30 MojoSetDataPipeProducerOptions(MOJO_HANDLE_INVALID, &dpp_options)); | |
| 31 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
| 32 MojoGetDataPipeProducerOptions( | |
| 33 MOJO_HANDLE_INVALID, &dpp_options, | |
| 34 static_cast<uint32_t>(sizeof(dpp_options)))); | |
| 35 char buffer[10] = {}; | |
| 36 uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer)); | |
| 37 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
| 38 MojoWriteData(MOJO_HANDLE_INVALID, buffer, &buffer_size, | |
| 39 MOJO_WRITE_DATA_FLAG_NONE)); | |
| 40 void* write_pointer = nullptr; | |
| 41 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
| 42 MojoBeginWriteData(MOJO_HANDLE_INVALID, &write_pointer, | |
| 43 &buffer_size, MOJO_WRITE_DATA_FLAG_NONE)); | |
| 44 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
| 45 MojoEndWriteData(MOJO_HANDLE_INVALID, 1u)); | |
| 46 buffer_size = static_cast<uint32_t>(sizeof(buffer)); | |
| 47 MojoDataPipeConsumerOptions dpc_options = { | |
| 48 sizeof(MojoDataPipeConsumerOptions), 0u}; | |
| 49 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
| 50 MojoSetDataPipeConsumerOptions(MOJO_HANDLE_INVALID, &dpc_options)); | |
| 51 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
| 52 MojoGetDataPipeConsumerOptions( | |
| 53 MOJO_HANDLE_INVALID, &dpc_options, | |
| 54 static_cast<uint32_t>(sizeof(dpc_options)))); | |
| 55 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
| 56 MojoReadData(MOJO_HANDLE_INVALID, buffer, &buffer_size, | |
| 57 MOJO_READ_DATA_FLAG_NONE)); | |
| 58 const void* read_pointer = nullptr; | |
| 59 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
| 60 MojoBeginReadData(MOJO_HANDLE_INVALID, &read_pointer, &buffer_size, | |
| 61 MOJO_READ_DATA_FLAG_NONE)); | |
| 62 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
| 63 MojoEndReadData(MOJO_HANDLE_INVALID, 1u)); | |
| 64 } | |
| 65 | |
| 66 TEST(DataPipeTest, Basic) { | |
| 67 MojoHandle hp = MOJO_HANDLE_INVALID; | |
| 68 MojoHandle hc = MOJO_HANDLE_INVALID; | |
| 69 EXPECT_EQ(MOJO_RESULT_OK, MojoCreateDataPipe(nullptr, &hp, &hc)); | |
| 70 EXPECT_NE(hp, MOJO_HANDLE_INVALID); | |
| 71 EXPECT_NE(hc, MOJO_HANDLE_INVALID); | |
| 72 EXPECT_NE(hp, hc); | |
| 73 | |
| 74 // Both handles should have the correct rights. | |
| 75 MojoHandleRights rights = MOJO_HANDLE_RIGHT_NONE; | |
| 76 EXPECT_EQ(MOJO_RESULT_OK, MojoGetRights(hp, &rights)); | |
| 77 EXPECT_EQ(kDefaultDataPipeProducerHandleRights, rights); | |
| 78 rights = MOJO_HANDLE_RIGHT_NONE; | |
| 79 EXPECT_EQ(MOJO_RESULT_OK, MojoGetRights(hc, &rights)); | |
| 80 EXPECT_EQ(kDefaultDataPipeConsumerHandleRights, rights); | |
| 81 | |
| 82 // Shouldn't be able to duplicate either handle (just test "with reduced | |
| 83 // rights" on one, and without on the other). | |
| 84 MojoHandle handle_denied = MOJO_HANDLE_INVALID; | |
| 85 EXPECT_EQ(MOJO_RESULT_PERMISSION_DENIED, | |
| 86 MojoDuplicateHandleWithReducedRights( | |
| 87 hp, MOJO_HANDLE_RIGHT_DUPLICATE, &handle_denied)); | |
| 88 EXPECT_EQ(MOJO_HANDLE_INVALID, handle_denied); | |
| 89 handle_denied = MOJO_HANDLE_INVALID; | |
| 90 EXPECT_EQ(MOJO_RESULT_PERMISSION_DENIED, | |
| 91 MojoDuplicateHandle(hc, &handle_denied)); | |
| 92 EXPECT_EQ(MOJO_HANDLE_INVALID, handle_denied); | |
| 93 | |
| 94 // The consumer |hc| shouldn't be readable. | |
| 95 MojoHandleSignalsState state; | |
| 96 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, | |
| 97 MojoWait(hc, MOJO_HANDLE_SIGNAL_READABLE, 0, &state)); | |
| 98 EXPECT_EQ(MOJO_HANDLE_SIGNAL_NONE, state.satisfied_signals); | |
| 99 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED | | |
| 100 MOJO_HANDLE_SIGNAL_READ_THRESHOLD, | |
| 101 state.satisfiable_signals); | |
| 102 | |
| 103 // The producer |hp| should be writable. | |
| 104 EXPECT_EQ(MOJO_RESULT_OK, | |
| 105 MojoWait(hp, MOJO_HANDLE_SIGNAL_WRITABLE, 0, &state)); | |
| 106 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_WRITE_THRESHOLD, | |
| 107 state.satisfied_signals); | |
| 108 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED | | |
| 109 MOJO_HANDLE_SIGNAL_WRITE_THRESHOLD, | |
| 110 state.satisfiable_signals); | |
| 111 | |
| 112 // Try to read from |hc|. | |
| 113 char buffer[20] = {}; | |
| 114 uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer)); | |
| 115 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | |
| 116 MojoReadData(hc, buffer, &buffer_size, MOJO_READ_DATA_FLAG_NONE)); | |
| 117 | |
| 118 // Try to begin a two-phase read from |hc|. | |
| 119 const void* read_pointer = nullptr; | |
| 120 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | |
| 121 MojoBeginReadData(hc, &read_pointer, &buffer_size, | |
| 122 MOJO_READ_DATA_FLAG_NONE)); | |
| 123 | |
| 124 // Write to |hp|. | |
| 125 static const char kHello[] = "hello "; | |
| 126 static const uint32_t kHelloLen = static_cast<uint32_t>(strlen(kHello)); | |
| 127 // Don't include terminating null. | |
| 128 buffer_size = kHelloLen; | |
| 129 EXPECT_EQ(MOJO_RESULT_OK, | |
| 130 MojoWriteData(hp, kHello, &buffer_size, MOJO_WRITE_DATA_FLAG_NONE)); | |
| 131 EXPECT_EQ(kHelloLen, buffer_size); | |
| 132 | |
| 133 // |hc| should be(come) readable. | |
| 134 MojoHandleSignals sig = MOJO_HANDLE_SIGNAL_READABLE; | |
| 135 uint32_t result_index = 1; | |
| 136 MojoHandleSignalsState states[1] = {}; | |
| 137 EXPECT_EQ(MOJO_RESULT_OK, MojoWaitMany(&hc, &sig, 1, MOJO_DEADLINE_INDEFINITE, | |
| 138 &result_index, states)); | |
| 139 EXPECT_EQ(0u, result_index); | |
| 140 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_READ_THRESHOLD, | |
| 141 states[0].satisfied_signals); | |
| 142 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED | | |
| 143 MOJO_HANDLE_SIGNAL_READ_THRESHOLD, | |
| 144 states[0].satisfiable_signals); | |
| 145 | |
| 146 // Do a two-phase write to |hp|. | |
| 147 void* write_pointer = nullptr; | |
| 148 ASSERT_EQ(MOJO_RESULT_OK, MojoBeginWriteData(hp, &write_pointer, &buffer_size, | |
| 149 MOJO_WRITE_DATA_FLAG_NONE)); | |
| 150 static const char kWorld[] = "world"; | |
| 151 ASSERT_GE(buffer_size, sizeof(kWorld)); | |
| 152 // Include the terminating null. | |
| 153 memcpy(write_pointer, kWorld, sizeof(kWorld)); | |
| 154 EXPECT_EQ(MOJO_RESULT_OK, | |
| 155 MojoEndWriteData(hp, static_cast<uint32_t>(sizeof(kWorld)))); | |
| 156 | |
| 157 // Read one character from |hc|. | |
| 158 memset(buffer, 0, sizeof(buffer)); | |
| 159 buffer_size = 1; | |
| 160 EXPECT_EQ(MOJO_RESULT_OK, | |
| 161 MojoReadData(hc, buffer, &buffer_size, MOJO_READ_DATA_FLAG_NONE)); | |
| 162 ASSERT_EQ(1u, buffer_size); | |
| 163 EXPECT_EQ('h', buffer[0]); | |
| 164 | |
| 165 // Close |hp|. | |
| 166 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(hp)); | |
| 167 | |
| 168 // |hc| should still be readable. | |
| 169 EXPECT_EQ(MOJO_RESULT_OK, | |
| 170 MojoWait(hc, MOJO_HANDLE_SIGNAL_READABLE, 0, &state)); | |
| 171 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED | | |
| 172 MOJO_HANDLE_SIGNAL_READ_THRESHOLD, | |
| 173 state.satisfied_signals); | |
| 174 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED | | |
| 175 MOJO_HANDLE_SIGNAL_READ_THRESHOLD, | |
| 176 state.satisfiable_signals); | |
| 177 | |
| 178 // Do a two-phase read from |hc|. | |
| 179 read_pointer = nullptr; | |
| 180 ASSERT_EQ(MOJO_RESULT_OK, MojoBeginReadData(hc, &read_pointer, &buffer_size, | |
| 181 MOJO_READ_DATA_FLAG_NONE)); | |
| 182 ASSERT_LE(buffer_size, sizeof(buffer) - 1); | |
| 183 memcpy(&buffer[1], read_pointer, buffer_size); | |
| 184 EXPECT_EQ(MOJO_RESULT_OK, MojoEndReadData(hc, buffer_size)); | |
| 185 EXPECT_STREQ("hello world", buffer); | |
| 186 | |
| 187 // |hc| should no longer be readable. | |
| 188 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
| 189 MojoWait(hc, MOJO_HANDLE_SIGNAL_READABLE, 1000, &state)); | |
| 190 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfied_signals); | |
| 191 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfiable_signals); | |
| 192 | |
| 193 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(hc)); | |
| 194 | |
| 195 // TODO(vtl): Test the other way around -- closing the consumer should make | |
| 196 // the producer never-writable? | |
| 197 } | |
| 198 | |
| 199 TEST(DataPipeTest, WriteThreshold) { | |
| 200 const MojoCreateDataPipeOptions options = { | |
| 201 static_cast<uint32_t>( | |
| 202 sizeof(MojoCreateDataPipeOptions)), // |struct_size|. | |
| 203 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|. | |
| 204 2u, // |element_num_bytes|. | |
| 205 4u // |capacity_num_bytes|. | |
| 206 }; | |
| 207 MojoHandle hp = MOJO_HANDLE_INVALID; | |
| 208 MojoHandle hc = MOJO_HANDLE_INVALID; | |
| 209 EXPECT_EQ(MOJO_RESULT_OK, MojoCreateDataPipe(&options, &hp, &hc)); | |
| 210 EXPECT_NE(hp, MOJO_HANDLE_INVALID); | |
| 211 EXPECT_NE(hc, MOJO_HANDLE_INVALID); | |
| 212 EXPECT_NE(hc, hp); | |
| 213 | |
| 214 MojoDataPipeProducerOptions popts; | |
| 215 static const uint32_t kPoptsSize = static_cast<uint32_t>(sizeof(popts)); | |
| 216 | |
| 217 // Check the current write threshold; should be the default. | |
| 218 memset(&popts, 255, kPoptsSize); | |
| 219 EXPECT_EQ(MOJO_RESULT_OK, | |
| 220 MojoGetDataPipeProducerOptions(hp, &popts, kPoptsSize)); | |
| 221 EXPECT_EQ(kPoptsSize, popts.struct_size); | |
| 222 EXPECT_EQ(0u, popts.write_threshold_num_bytes); | |
| 223 | |
| 224 // Should already have the write threshold signal. | |
| 225 MojoHandleSignalsState state = {}; | |
| 226 EXPECT_EQ(MOJO_RESULT_OK, | |
| 227 MojoWait(hp, MOJO_HANDLE_SIGNAL_WRITE_THRESHOLD, 0, &state)); | |
| 228 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_WRITE_THRESHOLD, | |
| 229 state.satisfied_signals); | |
| 230 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED | | |
| 231 MOJO_HANDLE_SIGNAL_WRITE_THRESHOLD, | |
| 232 state.satisfiable_signals); | |
| 233 | |
| 234 // Try setting the write threshold to something invalid. | |
| 235 popts.struct_size = kPoptsSize; | |
| 236 popts.write_threshold_num_bytes = 1u; | |
| 237 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
| 238 MojoSetDataPipeProducerOptions(hp, &popts)); | |
| 239 // It shouldn't change the options. | |
| 240 memset(&popts, 255, kPoptsSize); | |
| 241 EXPECT_EQ(MOJO_RESULT_OK, | |
| 242 MojoGetDataPipeProducerOptions(hp, &popts, kPoptsSize)); | |
| 243 EXPECT_EQ(kPoptsSize, popts.struct_size); | |
| 244 EXPECT_EQ(0u, popts.write_threshold_num_bytes); | |
| 245 | |
| 246 // Write an element. | |
| 247 static const uint16_t kTestElem = 12345u; | |
| 248 uint32_t num_bytes = 2u; | |
| 249 EXPECT_EQ(MOJO_RESULT_OK, MojoWriteData(hp, &kTestElem, &num_bytes, | |
| 250 MOJO_WRITE_DATA_FLAG_NONE)); | |
| 251 EXPECT_EQ(2u, num_bytes); | |
| 252 | |
| 253 // Should still have the write threshold signal. | |
| 254 EXPECT_EQ(MOJO_RESULT_OK, | |
| 255 MojoWait(hp, MOJO_HANDLE_SIGNAL_WRITE_THRESHOLD, 0, nullptr)); | |
| 256 | |
| 257 // Write another element. | |
| 258 static const uint16_t kAnotherTestElem = 12345u; | |
| 259 num_bytes = 2u; | |
| 260 EXPECT_EQ(MOJO_RESULT_OK, MojoWriteData(hp, &kAnotherTestElem, &num_bytes, | |
| 261 MOJO_WRITE_DATA_FLAG_NONE)); | |
| 262 EXPECT_EQ(2u, num_bytes); | |
| 263 | |
| 264 // Should no longer have the write threshold signal. | |
| 265 state = MojoHandleSignalsState(); | |
| 266 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, | |
| 267 MojoWait(hp, MOJO_HANDLE_SIGNAL_WRITE_THRESHOLD, 0, &state)); | |
| 268 EXPECT_EQ(0u, state.satisfied_signals); | |
| 269 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED | | |
| 270 MOJO_HANDLE_SIGNAL_WRITE_THRESHOLD, | |
| 271 state.satisfiable_signals); | |
| 272 | |
| 273 // Set the write threshold to 2 (one element). | |
| 274 popts.struct_size = kPoptsSize; | |
| 275 popts.write_threshold_num_bytes = 2u; | |
| 276 EXPECT_EQ(MOJO_RESULT_OK, MojoSetDataPipeProducerOptions(hp, &popts)); | |
| 277 // It should actually change the options. | |
| 278 memset(&popts, 255, kPoptsSize); | |
| 279 EXPECT_EQ(MOJO_RESULT_OK, | |
| 280 MojoGetDataPipeProducerOptions(hp, &popts, kPoptsSize)); | |
| 281 EXPECT_EQ(kPoptsSize, popts.struct_size); | |
| 282 EXPECT_EQ(2u, popts.write_threshold_num_bytes); | |
| 283 | |
| 284 // Should still not have the write threshold signal. | |
| 285 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, | |
| 286 MojoWait(hp, MOJO_HANDLE_SIGNAL_WRITE_THRESHOLD, 0, nullptr)); | |
| 287 | |
| 288 // Read an element. | |
| 289 uint16_t read_elem = 0u; | |
| 290 num_bytes = 2u; | |
| 291 EXPECT_EQ(MOJO_RESULT_OK, | |
| 292 MojoReadData(hc, &read_elem, &num_bytes, MOJO_READ_DATA_FLAG_NONE)); | |
| 293 EXPECT_EQ(2u, num_bytes); | |
| 294 EXPECT_EQ(kTestElem, read_elem); | |
| 295 | |
| 296 // Should get the write threshold signal now. | |
| 297 state = MojoHandleSignalsState(); | |
| 298 EXPECT_EQ(MOJO_RESULT_OK, | |
| 299 MojoWait(hp, MOJO_HANDLE_SIGNAL_WRITE_THRESHOLD, 1000, &state)); | |
| 300 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_WRITE_THRESHOLD, | |
| 301 state.satisfied_signals); | |
| 302 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED | | |
| 303 MOJO_HANDLE_SIGNAL_WRITE_THRESHOLD, | |
| 304 state.satisfiable_signals); | |
| 305 | |
| 306 // Set the write threshold to 4 (two elements). | |
| 307 popts.struct_size = kPoptsSize; | |
| 308 popts.write_threshold_num_bytes = 4u; | |
| 309 EXPECT_EQ(MOJO_RESULT_OK, MojoSetDataPipeProducerOptions(hp, &popts)); | |
| 310 | |
| 311 // Should again not have the write threshold signal. | |
| 312 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, | |
| 313 MojoWait(hp, MOJO_HANDLE_SIGNAL_WRITE_THRESHOLD, 0, nullptr)); | |
| 314 | |
| 315 // Close the consumer. | |
| 316 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(hc)); | |
| 317 | |
| 318 // The write threshold signal should now be unsatisfiable. | |
| 319 state = MojoHandleSignalsState(); | |
| 320 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
| 321 MojoWait(hp, MOJO_HANDLE_SIGNAL_WRITE_THRESHOLD, 0, &state)); | |
| 322 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfied_signals); | |
| 323 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfiable_signals); | |
| 324 | |
| 325 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(hp)); | |
| 326 } | |
| 327 | |
| 328 TEST(DataPipeTest, ReadThreshold) { | |
| 329 MojoHandle hp = MOJO_HANDLE_INVALID; | |
| 330 MojoHandle hc = MOJO_HANDLE_INVALID; | |
| 331 EXPECT_EQ(MOJO_RESULT_OK, MojoCreateDataPipe(nullptr, &hp, &hc)); | |
| 332 EXPECT_NE(hp, MOJO_HANDLE_INVALID); | |
| 333 EXPECT_NE(hc, MOJO_HANDLE_INVALID); | |
| 334 EXPECT_NE(hc, hp); | |
| 335 | |
| 336 MojoDataPipeConsumerOptions copts; | |
| 337 static const uint32_t kCoptsSize = static_cast<uint32_t>(sizeof(copts)); | |
| 338 | |
| 339 // Check the current read threshold; should be the default. | |
| 340 memset(&copts, 255, kCoptsSize); | |
| 341 EXPECT_EQ(MOJO_RESULT_OK, | |
| 342 MojoGetDataPipeConsumerOptions(hc, &copts, kCoptsSize)); | |
| 343 EXPECT_EQ(kCoptsSize, copts.struct_size); | |
| 344 EXPECT_EQ(0u, copts.read_threshold_num_bytes); | |
| 345 | |
| 346 // Shouldn't have the read threshold signal yet. | |
| 347 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, | |
| 348 MojoWait(hc, MOJO_HANDLE_SIGNAL_READ_THRESHOLD, 1000, nullptr)); | |
| 349 | |
| 350 // Write a byte to |hp|. | |
| 351 static const char kAByte = 'A'; | |
| 352 uint32_t num_bytes = 1u; | |
| 353 EXPECT_EQ(MOJO_RESULT_OK, | |
| 354 MojoWriteData(hp, &kAByte, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE)); | |
| 355 EXPECT_EQ(1u, num_bytes); | |
| 356 | |
| 357 // Now should have the read threshold signal. | |
| 358 MojoHandleSignalsState state; | |
| 359 EXPECT_EQ(MOJO_RESULT_OK, | |
| 360 MojoWait(hc, MOJO_HANDLE_SIGNAL_READ_THRESHOLD, 1000, &state)); | |
| 361 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_READ_THRESHOLD, | |
| 362 state.satisfied_signals); | |
| 363 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED | | |
| 364 MOJO_HANDLE_SIGNAL_READ_THRESHOLD, | |
| 365 state.satisfiable_signals); | |
| 366 | |
| 367 // Set the read threshold to 3, and then check it. | |
| 368 copts.struct_size = kCoptsSize; | |
| 369 copts.read_threshold_num_bytes = 3u; | |
| 370 EXPECT_EQ(MOJO_RESULT_OK, MojoSetDataPipeConsumerOptions(hc, &copts)); | |
| 371 | |
| 372 memset(&copts, 255, kCoptsSize); | |
| 373 EXPECT_EQ(MOJO_RESULT_OK, | |
| 374 MojoGetDataPipeConsumerOptions(hc, &copts, kCoptsSize)); | |
| 375 EXPECT_EQ(kCoptsSize, copts.struct_size); | |
| 376 EXPECT_EQ(3u, copts.read_threshold_num_bytes); | |
| 377 | |
| 378 // Shouldn't have the read threshold signal again. | |
| 379 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, | |
| 380 MojoWait(hc, MOJO_HANDLE_SIGNAL_READ_THRESHOLD, 0, nullptr)); | |
| 381 | |
| 382 // Write another byte to |hp|. | |
| 383 static const char kBByte = 'B'; | |
| 384 num_bytes = 1u; | |
| 385 EXPECT_EQ(MOJO_RESULT_OK, | |
| 386 MojoWriteData(hp, &kBByte, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE)); | |
| 387 EXPECT_EQ(1u, num_bytes); | |
| 388 | |
| 389 // Still shouldn't have the read threshold signal. | |
| 390 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, | |
| 391 MojoWait(hc, MOJO_HANDLE_SIGNAL_READ_THRESHOLD, 1000, nullptr)); | |
| 392 | |
| 393 // Write a third byte to |hp|. | |
| 394 static const char kCByte = 'C'; | |
| 395 num_bytes = 1u; | |
| 396 EXPECT_EQ(MOJO_RESULT_OK, | |
| 397 MojoWriteData(hp, &kCByte, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE)); | |
| 398 EXPECT_EQ(1u, num_bytes); | |
| 399 | |
| 400 // Now should have the read threshold signal. | |
| 401 EXPECT_EQ(MOJO_RESULT_OK, | |
| 402 MojoWait(hc, MOJO_HANDLE_SIGNAL_READ_THRESHOLD, 1000, nullptr)); | |
| 403 | |
| 404 // Read a byte. | |
| 405 char read_byte = 'x'; | |
| 406 num_bytes = 1u; | |
| 407 EXPECT_EQ(MOJO_RESULT_OK, | |
| 408 MojoReadData(hc, &read_byte, &num_bytes, MOJO_READ_DATA_FLAG_NONE)); | |
| 409 EXPECT_EQ(1u, num_bytes); | |
| 410 EXPECT_EQ(kAByte, read_byte); | |
| 411 | |
| 412 // Shouldn't have the read threshold signal again. | |
| 413 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, | |
| 414 MojoWait(hc, MOJO_HANDLE_SIGNAL_READ_THRESHOLD, 0, nullptr)); | |
| 415 | |
| 416 // Set the read threshold to 2. | |
| 417 copts.struct_size = kCoptsSize; | |
| 418 copts.read_threshold_num_bytes = 2u; | |
| 419 EXPECT_EQ(MOJO_RESULT_OK, MojoSetDataPipeConsumerOptions(hc, &copts)); | |
| 420 | |
| 421 // Should have the read threshold signal again. | |
| 422 EXPECT_EQ(MOJO_RESULT_OK, | |
| 423 MojoWait(hc, MOJO_HANDLE_SIGNAL_READ_THRESHOLD, 0, nullptr)); | |
| 424 | |
| 425 // Set the read threshold to the default by passing null, and check it. | |
| 426 EXPECT_EQ(MOJO_RESULT_OK, MojoSetDataPipeConsumerOptions(hc, nullptr)); | |
| 427 | |
| 428 memset(&copts, 255, kCoptsSize); | |
| 429 EXPECT_EQ(MOJO_RESULT_OK, | |
| 430 MojoGetDataPipeConsumerOptions(hc, &copts, kCoptsSize)); | |
| 431 EXPECT_EQ(kCoptsSize, copts.struct_size); | |
| 432 EXPECT_EQ(0u, copts.read_threshold_num_bytes); | |
| 433 | |
| 434 // Should still have the read threshold signal. | |
| 435 EXPECT_EQ(MOJO_RESULT_OK, | |
| 436 MojoWait(hc, MOJO_HANDLE_SIGNAL_READ_THRESHOLD, 0, nullptr)); | |
| 437 | |
| 438 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(hp)); | |
| 439 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(hc)); | |
| 440 } | |
| 441 | |
| 442 // TODO(vtl): Add multi-threaded tests. | |
| 443 | |
| 444 } // namespace | |
| OLD | NEW |