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 3 // found in the LICENSE file. 4 5 #include "mojo/system/core.h" 6 7 #include <stdint.h> 8 9 #include <limits> 10 11 #include "base/threading/platform_thread.h" 12 #include "base/time/time.h" 13 #include "mojo/system/core_test_base.h" 14 15 namespace mojo { 16 namespace system { 17 namespace { 18 19 const MojoHandleSignalsState kEmptyMojoHandleSignalsState = {0u, 0u}; 20 const MojoHandleSignalsState kFullMojoHandleSignalsState = {~0u, ~0u}; 21 22 typedef test::CoreTestBase CoreTest; 23 24 TEST_F(CoreTest, GetTimeTicksNow) { 25 const MojoTimeTicks start = core()->GetTimeTicksNow(); 26 EXPECT_NE(static_cast<MojoTimeTicks>(0), start) 27 << "GetTimeTicksNow should return nonzero value"; 28 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(15)); 29 const MojoTimeTicks finish = core()->GetTimeTicksNow(); 30 // Allow for some fuzz in sleep. 31 EXPECT_GE((finish - start), static_cast<MojoTimeTicks>(8000)) 32 << "Sleeping should result in increasing time ticks"; 33 } 34 35 TEST_F(CoreTest, Basic) { 36 MockHandleInfo info; 37 38 EXPECT_EQ(0u, info.GetCtorCallCount()); 39 MojoHandle h = CreateMockHandle(&info); 40 EXPECT_EQ(1u, info.GetCtorCallCount()); 41 EXPECT_NE(h, MOJO_HANDLE_INVALID); 42 43 EXPECT_EQ(0u, info.GetWriteMessageCallCount()); 44 EXPECT_EQ(MOJO_RESULT_OK, 45 core()->WriteMessage(h, 46 NullUserPointer(), 47 0, 48 NullUserPointer(), 49 0, 50 MOJO_WRITE_MESSAGE_FLAG_NONE)); 51 EXPECT_EQ(1u, info.GetWriteMessageCallCount()); 52 53 EXPECT_EQ(0u, info.GetReadMessageCallCount()); 54 uint32_t num_bytes = 0; 55 EXPECT_EQ(MOJO_RESULT_OK, 56 core()->ReadMessage(h, 57 NullUserPointer(), 58 MakeUserPointer(&num_bytes), 59 NullUserPointer(), 60 NullUserPointer(), 61 MOJO_READ_MESSAGE_FLAG_NONE)); 62 EXPECT_EQ(1u, info.GetReadMessageCallCount()); 63 EXPECT_EQ(MOJO_RESULT_OK, 64 core()->ReadMessage(h, 65 NullUserPointer(), 66 NullUserPointer(), 67 NullUserPointer(), 68 NullUserPointer(), 69 MOJO_READ_MESSAGE_FLAG_NONE)); 70 EXPECT_EQ(2u, info.GetReadMessageCallCount()); 71 72 EXPECT_EQ(0u, info.GetWriteDataCallCount()); 73 EXPECT_EQ( 74 MOJO_RESULT_UNIMPLEMENTED, 75 core()->WriteData( 76 h, NullUserPointer(), NullUserPointer(), MOJO_WRITE_DATA_FLAG_NONE)); 77 EXPECT_EQ(1u, info.GetWriteDataCallCount()); 78 79 EXPECT_EQ(0u, info.GetBeginWriteDataCallCount()); 80 EXPECT_EQ( 81 MOJO_RESULT_UNIMPLEMENTED, 82 core()->BeginWriteData( 83 h, NullUserPointer(), NullUserPointer(), MOJO_WRITE_DATA_FLAG_NONE)); 84 EXPECT_EQ(1u, info.GetBeginWriteDataCallCount()); 85 86 EXPECT_EQ(0u, info.GetEndWriteDataCallCount()); 87 EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED, core()->EndWriteData(h, 0)); 88 EXPECT_EQ(1u, info.GetEndWriteDataCallCount()); 89 90 EXPECT_EQ(0u, info.GetReadDataCallCount()); 91 EXPECT_EQ( 92 MOJO_RESULT_UNIMPLEMENTED, 93 core()->ReadData( 94 h, NullUserPointer(), NullUserPointer(), MOJO_READ_DATA_FLAG_NONE)); 95 EXPECT_EQ(1u, info.GetReadDataCallCount()); 96 97 EXPECT_EQ(0u, info.GetBeginReadDataCallCount()); 98 EXPECT_EQ( 99 MOJO_RESULT_UNIMPLEMENTED, 100 core()->BeginReadData( 101 h, NullUserPointer(), NullUserPointer(), MOJO_READ_DATA_FLAG_NONE)); 102 EXPECT_EQ(1u, info.GetBeginReadDataCallCount()); 103 104 EXPECT_EQ(0u, info.GetEndReadDataCallCount()); 105 EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED, core()->EndReadData(h, 0)); 106 EXPECT_EQ(1u, info.GetEndReadDataCallCount()); 107 108 EXPECT_EQ(0u, info.GetAddWaiterCallCount()); 109 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, 110 core()->Wait(h, 111 ~MOJO_HANDLE_SIGNAL_NONE, 112 MOJO_DEADLINE_INDEFINITE, 113 NullUserPointer())); 114 EXPECT_EQ(1u, info.GetAddWaiterCallCount()); 115 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, 116 core()->Wait(h, ~MOJO_HANDLE_SIGNAL_NONE, 0, NullUserPointer())); 117 EXPECT_EQ(2u, info.GetAddWaiterCallCount()); 118 MojoHandleSignalsState hss = kFullMojoHandleSignalsState; 119 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, 120 core()->Wait(h, 121 ~MOJO_HANDLE_SIGNAL_NONE, 122 MOJO_DEADLINE_INDEFINITE, 123 MakeUserPointer(&hss))); 124 EXPECT_EQ(3u, info.GetAddWaiterCallCount()); 125 EXPECT_EQ(0u, hss.satisfied_signals); 126 EXPECT_EQ(0u, hss.satisfiable_signals); 127 EXPECT_EQ( 128 MOJO_RESULT_FAILED_PRECONDITION, 129 core()->Wait(h, ~MOJO_HANDLE_SIGNAL_NONE, 10 * 1000, NullUserPointer())); 130 EXPECT_EQ(4u, info.GetAddWaiterCallCount()); 131 hss = kFullMojoHandleSignalsState; 132 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, 133 core()->Wait( 134 h, ~MOJO_HANDLE_SIGNAL_NONE, 10 * 1000, MakeUserPointer(&hss))); 135 EXPECT_EQ(5u, info.GetAddWaiterCallCount()); 136 EXPECT_EQ(0u, hss.satisfied_signals); 137 EXPECT_EQ(0u, hss.satisfiable_signals); 138 139 MojoHandleSignals handle_signals = ~MOJO_HANDLE_SIGNAL_NONE; 140 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, 141 core()->WaitMany(MakeUserPointer(&h), 142 MakeUserPointer(&handle_signals), 143 1, 144 MOJO_DEADLINE_INDEFINITE, 145 NullUserPointer(), 146 NullUserPointer())); 147 EXPECT_EQ(6u, info.GetAddWaiterCallCount()); 148 uint32_t result_index = static_cast<uint32_t>(-1); 149 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, 150 core()->WaitMany(MakeUserPointer(&h), 151 MakeUserPointer(&handle_signals), 152 1, 153 MOJO_DEADLINE_INDEFINITE, 154 MakeUserPointer(&result_index), 155 NullUserPointer())); 156 EXPECT_EQ(7u, info.GetAddWaiterCallCount()); 157 EXPECT_EQ(0u, result_index); 158 hss = kFullMojoHandleSignalsState; 159 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, 160 core()->WaitMany(MakeUserPointer(&h), 161 MakeUserPointer(&handle_signals), 162 1, 163 MOJO_DEADLINE_INDEFINITE, 164 NullUserPointer(), 165 MakeUserPointer(&hss))); 166 EXPECT_EQ(8u, info.GetAddWaiterCallCount()); 167 EXPECT_EQ(0u, hss.satisfied_signals); 168 EXPECT_EQ(0u, hss.satisfiable_signals); 169 result_index = static_cast<uint32_t>(-1); 170 hss = kFullMojoHandleSignalsState; 171 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, 172 core()->WaitMany(MakeUserPointer(&h), 173 MakeUserPointer(&handle_signals), 174 1, 175 MOJO_DEADLINE_INDEFINITE, 176 MakeUserPointer(&result_index), 177 MakeUserPointer(&hss))); 178 EXPECT_EQ(9u, info.GetAddWaiterCallCount()); 179 EXPECT_EQ(0u, result_index); 180 EXPECT_EQ(0u, hss.satisfied_signals); 181 EXPECT_EQ(0u, hss.satisfiable_signals); 182 183 EXPECT_EQ(0u, info.GetDtorCallCount()); 184 EXPECT_EQ(0u, info.GetCloseCallCount()); 185 EXPECT_EQ(0u, info.GetCancelAllWaitersCallCount()); 186 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h)); 187 EXPECT_EQ(1u, info.GetCancelAllWaitersCallCount()); 188 EXPECT_EQ(1u, info.GetCloseCallCount()); 189 EXPECT_EQ(1u, info.GetDtorCallCount()); 190 191 // No waiters should ever have ever been added. 192 EXPECT_EQ(0u, info.GetRemoveWaiterCallCount()); 193 } 194 195 TEST_F(CoreTest, InvalidArguments) { 196 // |Close()|: 197 { 198 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(MOJO_HANDLE_INVALID)); 199 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(10)); 200 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(1000000000)); 201 202 // Test a double-close. 203 MockHandleInfo info; 204 MojoHandle h = CreateMockHandle(&info); 205 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h)); 206 EXPECT_EQ(1u, info.GetCloseCallCount()); 207 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(h)); 208 EXPECT_EQ(1u, info.GetCloseCallCount()); 209 } 210 211 // |Wait()|: 212 { 213 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, 214 core()->Wait(MOJO_HANDLE_INVALID, 215 ~MOJO_HANDLE_SIGNAL_NONE, 216 MOJO_DEADLINE_INDEFINITE, 217 NullUserPointer())); 218 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, 219 core()->Wait(10, 220 ~MOJO_HANDLE_SIGNAL_NONE, 221 MOJO_DEADLINE_INDEFINITE, 222 NullUserPointer())); 223 224 MojoHandleSignalsState hss = kFullMojoHandleSignalsState; 225 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, 226 core()->Wait(MOJO_HANDLE_INVALID, 227 ~MOJO_HANDLE_SIGNAL_NONE, 228 MOJO_DEADLINE_INDEFINITE, 229 MakeUserPointer(&hss))); 230 // On invalid argument, it shouldn't modify the handle signals state. 231 EXPECT_EQ(kFullMojoHandleSignalsState.satisfied_signals, 232 hss.satisfied_signals); 233 EXPECT_EQ(kFullMojoHandleSignalsState.satisfiable_signals, 234 hss.satisfiable_signals); 235 hss = kFullMojoHandleSignalsState; 236 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, 237 core()->Wait(10, 238 ~MOJO_HANDLE_SIGNAL_NONE, 239 MOJO_DEADLINE_INDEFINITE, 240 MakeUserPointer(&hss))); 241 // On invalid argument, it shouldn't modify the handle signals state. 242 EXPECT_EQ(kFullMojoHandleSignalsState.satisfied_signals, 243 hss.satisfied_signals); 244 EXPECT_EQ(kFullMojoHandleSignalsState.satisfiable_signals, 245 hss.satisfiable_signals); 246 } 247 248 // |WaitMany()|: 249 { 250 MojoHandle handles[2] = {MOJO_HANDLE_INVALID, MOJO_HANDLE_INVALID}; 251 MojoHandleSignals signals[2] = {~MOJO_HANDLE_SIGNAL_NONE, 252 ~MOJO_HANDLE_SIGNAL_NONE}; 253 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, 254 core()->WaitMany(MakeUserPointer(handles), 255 MakeUserPointer(signals), 256 0, 257 MOJO_DEADLINE_INDEFINITE, 258 NullUserPointer(), 259 NullUserPointer())); 260 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, 261 core()->WaitMany(NullUserPointer(), 262 MakeUserPointer(signals), 263 0, 264 MOJO_DEADLINE_INDEFINITE, 265 NullUserPointer(), 266 NullUserPointer())); 267 // If |num_handles| is invalid, it should leave |result_index| and 268 // |signals_states| alone. 269 // (We use -1 internally; make sure that doesn't leak.) 270 uint32_t result_index = 123; 271 MojoHandleSignalsState hss = kFullMojoHandleSignalsState; 272 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, 273 core()->WaitMany(NullUserPointer(), 274 MakeUserPointer(signals), 275 0, 276 MOJO_DEADLINE_INDEFINITE, 277 MakeUserPointer(&result_index), 278 MakeUserPointer(&hss))); 279 EXPECT_EQ(123u, result_index); 280 EXPECT_EQ(kFullMojoHandleSignalsState.satisfied_signals, 281 hss.satisfied_signals); 282 EXPECT_EQ(kFullMojoHandleSignalsState.satisfiable_signals, 283 hss.satisfiable_signals); 284 285 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, 286 core()->WaitMany(MakeUserPointer(handles), 287 NullUserPointer(), 288 0, 289 MOJO_DEADLINE_INDEFINITE, 290 NullUserPointer(), 291 NullUserPointer())); 292 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, 293 core()->WaitMany(MakeUserPointer(handles), 294 MakeUserPointer(signals), 295 1, 296 MOJO_DEADLINE_INDEFINITE, 297 NullUserPointer(), 298 NullUserPointer())); 299 // But if a handle is bad, then it should set |result_index| but still leave 300 // |signals_states| alone. 301 result_index = static_cast<uint32_t>(-1); 302 hss = kFullMojoHandleSignalsState; 303 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, 304 core()->WaitMany(MakeUserPointer(handles), 305 MakeUserPointer(signals), 306 1, 307 MOJO_DEADLINE_INDEFINITE, 308 MakeUserPointer(&result_index), 309 MakeUserPointer(&hss))); 310 EXPECT_EQ(0u, result_index); 311 EXPECT_EQ(kFullMojoHandleSignalsState.satisfied_signals, 312 hss.satisfied_signals); 313 EXPECT_EQ(kFullMojoHandleSignalsState.satisfiable_signals, 314 hss.satisfiable_signals); 315 316 MockHandleInfo info[2]; 317 handles[0] = CreateMockHandle(&info[0]); 318 319 result_index = static_cast<uint32_t>(-1); 320 hss = kFullMojoHandleSignalsState; 321 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, 322 core()->WaitMany(MakeUserPointer(handles), 323 MakeUserPointer(signals), 324 1, 325 MOJO_DEADLINE_INDEFINITE, 326 MakeUserPointer(&result_index), 327 MakeUserPointer(&hss))); 328 EXPECT_EQ(0u, result_index); 329 EXPECT_EQ(0u, hss.satisfied_signals); 330 EXPECT_EQ(0u, hss.satisfiable_signals); 331 332 // On invalid argument, it'll leave |signals_states| alone. 333 result_index = static_cast<uint32_t>(-1); 334 hss = kFullMojoHandleSignalsState; 335 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, 336 core()->WaitMany(MakeUserPointer(handles), 337 MakeUserPointer(signals), 338 2, 339 MOJO_DEADLINE_INDEFINITE, 340 MakeUserPointer(&result_index), 341 MakeUserPointer(&hss))); 342 EXPECT_EQ(1u, result_index); 343 EXPECT_EQ(kFullMojoHandleSignalsState.satisfied_signals, 344 hss.satisfied_signals); 345 EXPECT_EQ(kFullMojoHandleSignalsState.satisfiable_signals, 346 hss.satisfiable_signals); 347 handles[1] = handles[0] + 1; // Invalid handle. 348 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, 349 core()->WaitMany(MakeUserPointer(handles), 350 MakeUserPointer(signals), 351 2, 352 MOJO_DEADLINE_INDEFINITE, 353 NullUserPointer(), 354 NullUserPointer())); 355 handles[1] = CreateMockHandle(&info[1]); 356 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, 357 core()->WaitMany(MakeUserPointer(handles), 358 MakeUserPointer(signals), 359 2, 360 MOJO_DEADLINE_INDEFINITE, 361 NullUserPointer(), 362 NullUserPointer())); 363 364 // TODO(vtl): Test one where we get "failed precondition" only for the 365 // second handle (and the first one is valid to wait on). 366 367 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(handles[0])); 368 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(handles[1])); 369 } 370 371 // |CreateMessagePipe()|: Nothing to check (apart from things that cause 372 // death). 373 374 // |WriteMessage()|: 375 // Only check arguments checked by |Core|, namely |handle|, |handles|, and 376 // |num_handles|. 377 { 378 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, 379 core()->WriteMessage(MOJO_HANDLE_INVALID, 380 NullUserPointer(), 381 0, 382 NullUserPointer(), 383 0, 384 MOJO_WRITE_MESSAGE_FLAG_NONE)); 385 386 MockHandleInfo info; 387 MojoHandle h = CreateMockHandle(&info); 388 MojoHandle handles[2] = {MOJO_HANDLE_INVALID, MOJO_HANDLE_INVALID}; 389 390 // Huge handle count (implausibly big on some systems -- more than can be 391 // stored in a 32-bit address space). 392 // Note: This may return either |MOJO_RESULT_INVALID_ARGUMENT| or 393 // |MOJO_RESULT_RESOURCE_EXHAUSTED|, depending on whether it's plausible or 394 // not. 395 EXPECT_NE(MOJO_RESULT_OK, 396 core()->WriteMessage(h, 397 NullUserPointer(), 398 0, 399 MakeUserPointer(handles), 400 std::numeric_limits<uint32_t>::max(), 401 MOJO_WRITE_MESSAGE_FLAG_NONE)); 402 EXPECT_EQ(0u, info.GetWriteMessageCallCount()); 403 404 // Huge handle count (plausibly big). 405 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, 406 core()->WriteMessage( 407 h, 408 NullUserPointer(), 409 0, 410 MakeUserPointer(handles), 411 std::numeric_limits<uint32_t>::max() / sizeof(handles[0]), 412 MOJO_WRITE_MESSAGE_FLAG_NONE)); 413 EXPECT_EQ(0u, info.GetWriteMessageCallCount()); 414 415 // Invalid handle in |handles|. 416 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, 417 core()->WriteMessage(h, 418 NullUserPointer(), 419 0, 420 MakeUserPointer(handles), 421 1, 422 MOJO_WRITE_MESSAGE_FLAG_NONE)); 423 EXPECT_EQ(0u, info.GetWriteMessageCallCount()); 424 425 // Two invalid handles in |handles|. 426 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, 427 core()->WriteMessage(h, 428 NullUserPointer(), 429 0, 430 MakeUserPointer(handles), 431 2, 432 MOJO_WRITE_MESSAGE_FLAG_NONE)); 433 EXPECT_EQ(0u, info.GetWriteMessageCallCount()); 434 435 // Can't send a handle over itself. 436 handles[0] = h; 437 EXPECT_EQ(MOJO_RESULT_BUSY, 438 core()->WriteMessage(h, 439 NullUserPointer(), 440 0, 441 MakeUserPointer(handles), 442 1, 443 MOJO_WRITE_MESSAGE_FLAG_NONE)); 444 EXPECT_EQ(0u, info.GetWriteMessageCallCount()); 445 446 MockHandleInfo info2; 447 MojoHandle h2 = CreateMockHandle(&info2); 448 449 // This is "okay", but |MockDispatcher| doesn't implement it. 450 handles[0] = h2; 451 EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED, 452 core()->WriteMessage(h, 453 NullUserPointer(), 454 0, 455 MakeUserPointer(handles), 456 1, 457 MOJO_WRITE_MESSAGE_FLAG_NONE)); 458 EXPECT_EQ(1u, info.GetWriteMessageCallCount()); 459 460 // One of the |handles| is still invalid. 461 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, 462 core()->WriteMessage(h, 463 NullUserPointer(), 464 0, 465 MakeUserPointer(handles), 466 2, 467 MOJO_WRITE_MESSAGE_FLAG_NONE)); 468 EXPECT_EQ(1u, info.GetWriteMessageCallCount()); 469 470 // One of the |handles| is the same as |handle|. 471 handles[1] = h; 472 EXPECT_EQ(MOJO_RESULT_BUSY, 473 core()->WriteMessage(h, 474 NullUserPointer(), 475 0, 476 MakeUserPointer(handles), 477 2, 478 MOJO_WRITE_MESSAGE_FLAG_NONE)); 479 EXPECT_EQ(1u, info.GetWriteMessageCallCount()); 480 481 // Can't send a handle twice in the same message. 482 handles[1] = h2; 483 EXPECT_EQ(MOJO_RESULT_BUSY, 484 core()->WriteMessage(h, 485 NullUserPointer(), 486 0, 487 MakeUserPointer(handles), 488 2, 489 MOJO_WRITE_MESSAGE_FLAG_NONE)); 490 EXPECT_EQ(1u, info.GetWriteMessageCallCount()); 491 492 // Note: Since we never successfully sent anything with it, |h2| should 493 // still be valid. 494 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h2)); 495 496 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h)); 497 } 498 499 // |ReadMessage()|: 500 // Only check arguments checked by |Core|, namely |handle|, |handles|, and 501 // |num_handles|. 502 { 503 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, 504 core()->ReadMessage(MOJO_HANDLE_INVALID, 505 NullUserPointer(), 506 NullUserPointer(), 507 NullUserPointer(), 508 NullUserPointer(), 509 MOJO_READ_MESSAGE_FLAG_NONE)); 510 511 MockHandleInfo info; 512 MojoHandle h = CreateMockHandle(&info); 513 514 // Okay. 515 uint32_t handle_count = 0; 516 EXPECT_EQ(MOJO_RESULT_OK, 517 core()->ReadMessage(h, 518 NullUserPointer(), 519 NullUserPointer(), 520 NullUserPointer(), 521 MakeUserPointer(&handle_count), 522 MOJO_READ_MESSAGE_FLAG_NONE)); 523 // Checked by |Core|, shouldn't go through to the dispatcher. 524 EXPECT_EQ(1u, info.GetReadMessageCallCount()); 525 526 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h)); 527 } 528 } 529 530 // These test invalid arguments that should cause death if we're being paranoid 531 // about checking arguments (which we would want to do if, e.g., we were in a 532 // true "kernel" situation, but we might not want to do otherwise for 533 // performance reasons). Probably blatant errors like passing in null pointers 534 // (for required pointer arguments) will still cause death, but perhaps not 535 // predictably. 536 TEST_F(CoreTest, InvalidArgumentsDeath) { 537 const char kMemoryCheckFailedRegex[] = "Check failed"; 538 539 // |WaitMany()|: 540 { 541 MojoHandle handle = MOJO_HANDLE_INVALID; 542 MojoHandleSignals signals = ~MOJO_HANDLE_SIGNAL_NONE; 543 EXPECT_DEATH_IF_SUPPORTED(core()->WaitMany(NullUserPointer(), 544 MakeUserPointer(&signals), 545 1, 546 MOJO_DEADLINE_INDEFINITE, 547 NullUserPointer(), 548 NullUserPointer()), 549 kMemoryCheckFailedRegex); 550 EXPECT_DEATH_IF_SUPPORTED(core()->WaitMany(MakeUserPointer(&handle), 551 NullUserPointer(), 552 1, 553 MOJO_DEADLINE_INDEFINITE, 554 NullUserPointer(), 555 NullUserPointer()), 556 kMemoryCheckFailedRegex); 557 // TODO(vtl): |result_index| and |signals_states| are optional. Test them 558 // with non-null invalid pointers? 559 } 560 561 // |CreateMessagePipe()|: 562 { 563 MojoHandle h; 564 EXPECT_DEATH_IF_SUPPORTED( 565 core()->CreateMessagePipe( 566 NullUserPointer(), NullUserPointer(), NullUserPointer()), 567 kMemoryCheckFailedRegex); 568 EXPECT_DEATH_IF_SUPPORTED( 569 core()->CreateMessagePipe( 570 NullUserPointer(), MakeUserPointer(&h), NullUserPointer()), 571 kMemoryCheckFailedRegex); 572 EXPECT_DEATH_IF_SUPPORTED( 573 core()->CreateMessagePipe( 574 NullUserPointer(), NullUserPointer(), MakeUserPointer(&h)), 575 kMemoryCheckFailedRegex); 576 } 577 578 // |WriteMessage()|: 579 // Only check arguments checked by |Core|, namely |handle|, |handles|, and 580 // |num_handles|. 581 { 582 MockHandleInfo info; 583 MojoHandle h = CreateMockHandle(&info); 584 585 // Null |handles| with nonzero |num_handles|. 586 EXPECT_DEATH_IF_SUPPORTED( 587 core()->WriteMessage(h, 588 NullUserPointer(), 589 0, 590 NullUserPointer(), 591 1, 592 MOJO_WRITE_MESSAGE_FLAG_NONE), 593 kMemoryCheckFailedRegex); 594 595 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h)); 596 } 597 598 // |ReadMessage()|: 599 // Only check arguments checked by |Core|, namely |handle|, |handles|, and 600 // |num_handles|. 601 { 602 MockHandleInfo info; 603 MojoHandle h = CreateMockHandle(&info); 604 605 uint32_t handle_count = 1; 606 EXPECT_DEATH_IF_SUPPORTED( 607 core()->ReadMessage(h, 608 NullUserPointer(), 609 NullUserPointer(), 610 NullUserPointer(), 611 MakeUserPointer(&handle_count), 612 MOJO_READ_MESSAGE_FLAG_NONE), 613 kMemoryCheckFailedRegex); 614 615 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h)); 616 } 617 } 618 619 // TODO(vtl): test |Wait()| and |WaitMany()| properly 620 // - including |WaitMany()| with the same handle more than once (with 621 // same/different signals) 622 623 TEST_F(CoreTest, MessagePipe) { 624 MojoHandle h[2]; 625 MojoHandleSignalsState hss[2]; 626 uint32_t result_index; 627 628 EXPECT_EQ( 629 MOJO_RESULT_OK, 630 core()->CreateMessagePipe( 631 NullUserPointer(), MakeUserPointer(&h[0]), MakeUserPointer(&h[1]))); 632 // Should get two distinct, valid handles. 633 EXPECT_NE(h[0], MOJO_HANDLE_INVALID); 634 EXPECT_NE(h[1], MOJO_HANDLE_INVALID); 635 EXPECT_NE(h[0], h[1]); 636 637 // Neither should be readable. 638 MojoHandleSignals signals[2] = {MOJO_HANDLE_SIGNAL_READABLE, 639 MOJO_HANDLE_SIGNAL_READABLE}; 640 result_index = static_cast<uint32_t>(-1); 641 hss[0] = kEmptyMojoHandleSignalsState; 642 hss[1] = kEmptyMojoHandleSignalsState; 643 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, 644 core()->WaitMany(MakeUserPointer(h), 645 MakeUserPointer(signals), 646 2, 647 0, 648 MakeUserPointer(&result_index), 649 MakeUserPointer(hss))); 650 EXPECT_EQ(static_cast<uint32_t>(-1), result_index); 651 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals); 652 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 653 hss[0].satisfiable_signals); 654 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[1].satisfied_signals); 655 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 656 hss[1].satisfiable_signals); 657 658 // Try to read anyway. 659 char buffer[1] = {'a'}; 660 uint32_t buffer_size = 1; 661 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, 662 core()->ReadMessage(h[0], 663 UserPointer<void>(buffer), 664 MakeUserPointer(&buffer_size), 665 NullUserPointer(), 666 NullUserPointer(), 667 MOJO_READ_MESSAGE_FLAG_NONE)); 668 // Check that it left its inputs alone. 669 EXPECT_EQ('a', buffer[0]); 670 EXPECT_EQ(1u, buffer_size); 671 672 // Both should be writable. 673 hss[0] = kEmptyMojoHandleSignalsState; 674 EXPECT_EQ(MOJO_RESULT_OK, 675 core()->Wait(h[0], 676 MOJO_HANDLE_SIGNAL_WRITABLE, 677 1000000000, 678 MakeUserPointer(&hss[0]))); 679 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals); 680 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 681 hss[0].satisfiable_signals); 682 hss[0] = kEmptyMojoHandleSignalsState; 683 EXPECT_EQ(MOJO_RESULT_OK, 684 core()->Wait(h[1], 685 MOJO_HANDLE_SIGNAL_WRITABLE, 686 1000000000, 687 MakeUserPointer(&hss[0]))); 688 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals); 689 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 690 hss[0].satisfiable_signals); 691 692 // Also check that |h[1]| is writable using |WaitMany()|. 693 signals[0] = MOJO_HANDLE_SIGNAL_READABLE; 694 signals[1] = MOJO_HANDLE_SIGNAL_WRITABLE; 695 result_index = static_cast<uint32_t>(-1); 696 hss[0] = kEmptyMojoHandleSignalsState; 697 hss[1] = kEmptyMojoHandleSignalsState; 698 EXPECT_EQ(MOJO_RESULT_OK, 699 core()->WaitMany(MakeUserPointer(h), 700 MakeUserPointer(signals), 701 2, 702 MOJO_DEADLINE_INDEFINITE, 703 MakeUserPointer(&result_index), 704 MakeUserPointer(hss))); 705 EXPECT_EQ(1u, result_index); 706 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals); 707 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 708 hss[0].satisfiable_signals); 709 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[1].satisfied_signals); 710 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 711 hss[1].satisfiable_signals); 712 713 // Write to |h[1]|. 714 buffer[0] = 'b'; 715 EXPECT_EQ(MOJO_RESULT_OK, 716 core()->WriteMessage(h[1], 717 UserPointer<const void>(buffer), 718 1, 719 NullUserPointer(), 720 0, 721 MOJO_WRITE_MESSAGE_FLAG_NONE)); 722 723 // Check that |h[0]| is now readable. 724 signals[0] = MOJO_HANDLE_SIGNAL_READABLE; 725 signals[1] = MOJO_HANDLE_SIGNAL_READABLE; 726 result_index = static_cast<uint32_t>(-1); 727 hss[0] = kEmptyMojoHandleSignalsState; 728 hss[1] = kEmptyMojoHandleSignalsState; 729 EXPECT_EQ(MOJO_RESULT_OK, 730 core()->WaitMany(MakeUserPointer(h), 731 MakeUserPointer(signals), 732 2, 733 MOJO_DEADLINE_INDEFINITE, 734 MakeUserPointer(&result_index), 735 MakeUserPointer(hss))); 736 EXPECT_EQ(0u, result_index); 737 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 738 hss[0].satisfied_signals); 739 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 740 hss[0].satisfiable_signals); 741 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[1].satisfied_signals); 742 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 743 hss[1].satisfiable_signals); 744 745 // Read from |h[0]|. 746 // First, get only the size. 747 buffer_size = 0; 748 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, 749 core()->ReadMessage(h[0], 750 NullUserPointer(), 751 MakeUserPointer(&buffer_size), 752 NullUserPointer(), 753 NullUserPointer(), 754 MOJO_READ_MESSAGE_FLAG_NONE)); 755 EXPECT_EQ(1u, buffer_size); 756 // Then actually read it. 757 buffer[0] = 'c'; 758 buffer_size = 1; 759 EXPECT_EQ(MOJO_RESULT_OK, 760 core()->ReadMessage(h[0], 761 UserPointer<void>(buffer), 762 MakeUserPointer(&buffer_size), 763 NullUserPointer(), 764 NullUserPointer(), 765 MOJO_READ_MESSAGE_FLAG_NONE)); 766 EXPECT_EQ('b', buffer[0]); 767 EXPECT_EQ(1u, buffer_size); 768 769 // |h[0]| should no longer be readable. 770 hss[0] = kEmptyMojoHandleSignalsState; 771 EXPECT_EQ( 772 MOJO_RESULT_DEADLINE_EXCEEDED, 773 core()->Wait( 774 h[0], MOJO_HANDLE_SIGNAL_READABLE, 0, MakeUserPointer(&hss[0]))); 775 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals); 776 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 777 hss[0].satisfiable_signals); 778 779 // Write to |h[0]|. 780 buffer[0] = 'd'; 781 EXPECT_EQ(MOJO_RESULT_OK, 782 core()->WriteMessage(h[0], 783 UserPointer<const void>(buffer), 784 1, 785 NullUserPointer(), 786 0, 787 MOJO_WRITE_MESSAGE_FLAG_NONE)); 788 789 // Close |h[0]|. 790 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h[0])); 791 792 // Check that |h[1]| is no longer writable (and will never be). 793 hss[0] = kEmptyMojoHandleSignalsState; 794 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, 795 core()->Wait(h[1], 796 MOJO_HANDLE_SIGNAL_WRITABLE, 797 1000000000, 798 MakeUserPointer(&hss[0]))); 799 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss[0].satisfied_signals); 800 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss[0].satisfiable_signals); 801 802 // Check that |h[1]| is still readable (for the moment). 803 hss[0] = kEmptyMojoHandleSignalsState; 804 EXPECT_EQ(MOJO_RESULT_OK, 805 core()->Wait(h[1], 806 MOJO_HANDLE_SIGNAL_READABLE, 807 1000000000, 808 MakeUserPointer(&hss[0]))); 809 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss[0].satisfied_signals); 810 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss[0].satisfiable_signals); 811 812 // Discard a message from |h[1]|. 813 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, 814 core()->ReadMessage(h[1], 815 NullUserPointer(), 816 NullUserPointer(), 817 NullUserPointer(), 818 NullUserPointer(), 819 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)); 820 821 // |h[1]| is no longer readable (and will never be). 822 hss[0] = kFullMojoHandleSignalsState; 823 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, 824 core()->Wait(h[1], 825 MOJO_HANDLE_SIGNAL_READABLE, 826 1000000000, 827 MakeUserPointer(&hss[0]))); 828 EXPECT_EQ(0u, hss[0].satisfied_signals); 829 EXPECT_EQ(0u, hss[0].satisfiable_signals); 830 831 // Try writing to |h[1]|. 832 buffer[0] = 'e'; 833 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, 834 core()->WriteMessage(h[1], 835 UserPointer<const void>(buffer), 836 1, 837 NullUserPointer(), 838 0, 839 MOJO_WRITE_MESSAGE_FLAG_NONE)); 840 841 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h[1])); 842 } 843 844 // Tests passing a message pipe handle. 845 TEST_F(CoreTest, MessagePipeBasicLocalHandlePassing1) { 846 const char kHello[] = "hello"; 847 const uint32_t kHelloSize = static_cast<uint32_t>(sizeof(kHello)); 848 const char kWorld[] = "world!!!"; 849 const uint32_t kWorldSize = static_cast<uint32_t>(sizeof(kWorld)); 850 char buffer[100]; 851 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); 852 uint32_t num_bytes; 853 MojoHandle handles[10]; 854 uint32_t num_handles; 855 MojoHandleSignalsState hss; 856 MojoHandle h_received; 857 858 MojoHandle h_passing[2]; 859 EXPECT_EQ(MOJO_RESULT_OK, 860 core()->CreateMessagePipe(NullUserPointer(), 861 MakeUserPointer(&h_passing[0]), 862 MakeUserPointer(&h_passing[1]))); 863 864 // Make sure that |h_passing[]| work properly. 865 EXPECT_EQ(MOJO_RESULT_OK, 866 core()->WriteMessage(h_passing[0], 867 UserPointer<const void>(kHello), 868 kHelloSize, 869 NullUserPointer(), 870 0, 871 MOJO_WRITE_MESSAGE_FLAG_NONE)); 872 hss = kEmptyMojoHandleSignalsState; 873 EXPECT_EQ(MOJO_RESULT_OK, 874 core()->Wait(h_passing[1], 875 MOJO_HANDLE_SIGNAL_READABLE, 876 1000000000, 877 MakeUserPointer(&hss))); 878 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 879 hss.satisfied_signals); 880 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 881 hss.satisfiable_signals); 882 num_bytes = kBufferSize; 883 num_handles = arraysize(handles); 884 EXPECT_EQ(MOJO_RESULT_OK, 885 core()->ReadMessage(h_passing[1], 886 UserPointer<void>(buffer), 887 MakeUserPointer(&num_bytes), 888 MakeUserPointer(handles), 889 MakeUserPointer(&num_handles), 890 MOJO_READ_MESSAGE_FLAG_NONE)); 891 EXPECT_EQ(kHelloSize, num_bytes); 892 EXPECT_STREQ(kHello, buffer); 893 EXPECT_EQ(0u, num_handles); 894 895 // Make sure that you can't pass either of the message pipe's handles over 896 // itself. 897 EXPECT_EQ(MOJO_RESULT_BUSY, 898 core()->WriteMessage(h_passing[0], 899 UserPointer<const void>(kHello), 900 kHelloSize, 901 MakeUserPointer(&h_passing[0]), 902 1, 903 MOJO_WRITE_MESSAGE_FLAG_NONE)); 904 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, 905 core()->WriteMessage(h_passing[0], 906 UserPointer<const void>(kHello), 907 kHelloSize, 908 MakeUserPointer(&h_passing[1]), 909 1, 910 MOJO_WRITE_MESSAGE_FLAG_NONE)); 911 912 MojoHandle h_passed[2]; 913 EXPECT_EQ(MOJO_RESULT_OK, 914 core()->CreateMessagePipe(NullUserPointer(), 915 MakeUserPointer(&h_passed[0]), 916 MakeUserPointer(&h_passed[1]))); 917 918 // Make sure that |h_passed[]| work properly. 919 EXPECT_EQ(MOJO_RESULT_OK, 920 core()->WriteMessage(h_passed[0], 921 UserPointer<const void>(kHello), 922 kHelloSize, 923 NullUserPointer(), 924 0, 925 MOJO_WRITE_MESSAGE_FLAG_NONE)); 926 hss = kEmptyMojoHandleSignalsState; 927 EXPECT_EQ(MOJO_RESULT_OK, 928 core()->Wait(h_passed[1], 929 MOJO_HANDLE_SIGNAL_READABLE, 930 1000000000, 931 MakeUserPointer(&hss))); 932 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 933 hss.satisfied_signals); 934 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 935 hss.satisfiable_signals); 936 num_bytes = kBufferSize; 937 num_handles = arraysize(handles); 938 EXPECT_EQ(MOJO_RESULT_OK, 939 core()->ReadMessage(h_passed[1], 940 UserPointer<void>(buffer), 941 MakeUserPointer(&num_bytes), 942 MakeUserPointer(handles), 943 MakeUserPointer(&num_handles), 944 MOJO_READ_MESSAGE_FLAG_NONE)); 945 EXPECT_EQ(kHelloSize, num_bytes); 946 EXPECT_STREQ(kHello, buffer); 947 EXPECT_EQ(0u, num_handles); 948 949 // Send |h_passed[1]| from |h_passing[0]| to |h_passing[1]|. 950 EXPECT_EQ(MOJO_RESULT_OK, 951 core()->WriteMessage(h_passing[0], 952 UserPointer<const void>(kWorld), 953 kWorldSize, 954 MakeUserPointer(&h_passed[1]), 955 1, 956 MOJO_WRITE_MESSAGE_FLAG_NONE)); 957 hss = kEmptyMojoHandleSignalsState; 958 EXPECT_EQ(MOJO_RESULT_OK, 959 core()->Wait(h_passing[1], 960 MOJO_HANDLE_SIGNAL_READABLE, 961 1000000000, 962 MakeUserPointer(&hss))); 963 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 964 hss.satisfied_signals); 965 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 966 hss.satisfiable_signals); 967 num_bytes = kBufferSize; 968 num_handles = arraysize(handles); 969 EXPECT_EQ(MOJO_RESULT_OK, 970 core()->ReadMessage(h_passing[1], 971 UserPointer<void>(buffer), 972 MakeUserPointer(&num_bytes), 973 MakeUserPointer(handles), 974 MakeUserPointer(&num_handles), 975 MOJO_READ_MESSAGE_FLAG_NONE)); 976 EXPECT_EQ(kWorldSize, num_bytes); 977 EXPECT_STREQ(kWorld, buffer); 978 EXPECT_EQ(1u, num_handles); 979 h_received = handles[0]; 980 EXPECT_NE(h_received, MOJO_HANDLE_INVALID); 981 EXPECT_NE(h_received, h_passing[0]); 982 EXPECT_NE(h_received, h_passing[1]); 983 EXPECT_NE(h_received, h_passed[0]); 984 985 // Note: We rely on the Mojo system not re-using handle values very often. 986 EXPECT_NE(h_received, h_passed[1]); 987 988 // |h_passed[1]| should no longer be valid; check that trying to close it 989 // fails. See above note. 990 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(h_passed[1])); 991 992 // Write to |h_passed[0]|. Should receive on |h_received|. 993 EXPECT_EQ(MOJO_RESULT_OK, 994 core()->WriteMessage(h_passed[0], 995 UserPointer<const void>(kHello), 996 kHelloSize, 997 NullUserPointer(), 998 0, 999 MOJO_WRITE_MESSAGE_FLAG_NONE)); 1000 hss = kEmptyMojoHandleSignalsState; 1001 EXPECT_EQ(MOJO_RESULT_OK, 1002 core()->Wait(h_received, 1003 MOJO_HANDLE_SIGNAL_READABLE, 1004 1000000000, 1005 MakeUserPointer(&hss))); 1006 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 1007 hss.satisfied_signals); 1008 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 1009 hss.satisfiable_signals); 1010 num_bytes = kBufferSize; 1011 num_handles = arraysize(handles); 1012 EXPECT_EQ(MOJO_RESULT_OK, 1013 core()->ReadMessage(h_received, 1014 UserPointer<void>(buffer), 1015 MakeUserPointer(&num_bytes), 1016 MakeUserPointer(handles), 1017 MakeUserPointer(&num_handles), 1018 MOJO_READ_MESSAGE_FLAG_NONE)); 1019 EXPECT_EQ(kHelloSize, num_bytes); 1020 EXPECT_STREQ(kHello, buffer); 1021 EXPECT_EQ(0u, num_handles); 1022 1023 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[0])); 1024 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[1])); 1025 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h_passed[0])); 1026 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h_received)); 1027 } 1028 1029 TEST_F(CoreTest, DataPipe) { 1030 MojoHandle ph, ch; // p is for producer and c is for consumer. 1031 MojoHandleSignalsState hss; 1032 1033 EXPECT_EQ(MOJO_RESULT_OK, 1034 core()->CreateDataPipe( 1035 NullUserPointer(), MakeUserPointer(&ph), MakeUserPointer(&ch))); 1036 // Should get two distinct, valid handles. 1037 EXPECT_NE(ph, MOJO_HANDLE_INVALID); 1038 EXPECT_NE(ch, MOJO_HANDLE_INVALID); 1039 EXPECT_NE(ph, ch); 1040 1041 // Producer should be never-readable, but already writable. 1042 hss = kEmptyMojoHandleSignalsState; 1043 EXPECT_EQ( 1044 MOJO_RESULT_FAILED_PRECONDITION, 1045 core()->Wait(ph, MOJO_HANDLE_SIGNAL_READABLE, 0, MakeUserPointer(&hss))); 1046 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals); 1047 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfiable_signals); 1048 hss = kEmptyMojoHandleSignalsState; 1049 EXPECT_EQ( 1050 MOJO_RESULT_OK, 1051 core()->Wait(ph, MOJO_HANDLE_SIGNAL_WRITABLE, 0, MakeUserPointer(&hss))); 1052 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals); 1053 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfiable_signals); 1054 1055 // Consumer should be never-writable, and not yet readable. 1056 hss = kFullMojoHandleSignalsState; 1057 EXPECT_EQ( 1058 MOJO_RESULT_FAILED_PRECONDITION, 1059 core()->Wait(ch, MOJO_HANDLE_SIGNAL_WRITABLE, 0, MakeUserPointer(&hss))); 1060 EXPECT_EQ(0u, hss.satisfied_signals); 1061 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals); 1062 hss = kFullMojoHandleSignalsState; 1063 EXPECT_EQ( 1064 MOJO_RESULT_DEADLINE_EXCEEDED, 1065 core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 0, MakeUserPointer(&hss))); 1066 EXPECT_EQ(0u, hss.satisfied_signals); 1067 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals); 1068 1069 // Write. 1070 char elements[2] = {'A', 'B'}; 1071 uint32_t num_bytes = 2u; 1072 EXPECT_EQ(MOJO_RESULT_OK, 1073 core()->WriteData(ph, 1074 UserPointer<const void>(elements), 1075 MakeUserPointer(&num_bytes), 1076 MOJO_WRITE_DATA_FLAG_NONE)); 1077 EXPECT_EQ(2u, num_bytes); 1078 1079 // Consumer should now be readable. 1080 hss = kEmptyMojoHandleSignalsState; 1081 EXPECT_EQ( 1082 MOJO_RESULT_OK, 1083 core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 0, MakeUserPointer(&hss))); 1084 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); 1085 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals); 1086 1087 // Read one character. 1088 elements[0] = -1; 1089 elements[1] = -1; 1090 num_bytes = 1u; 1091 EXPECT_EQ(MOJO_RESULT_OK, 1092 core()->ReadData(ch, 1093 UserPointer<void>(elements), 1094 MakeUserPointer(&num_bytes), 1095 MOJO_READ_DATA_FLAG_NONE)); 1096 EXPECT_EQ('A', elements[0]); 1097 EXPECT_EQ(-1, elements[1]); 1098 1099 // Two-phase write. 1100 void* write_ptr = nullptr; 1101 num_bytes = 0u; 1102 ASSERT_EQ(MOJO_RESULT_OK, 1103 core()->BeginWriteData(ph, 1104 MakeUserPointer(&write_ptr), 1105 MakeUserPointer(&num_bytes), 1106 MOJO_WRITE_DATA_FLAG_NONE)); 1107 // We count on the default options providing a decent buffer size. 1108 ASSERT_GE(num_bytes, 3u); 1109 1110 // Trying to do a normal write during a two-phase write should fail. 1111 elements[0] = 'X'; 1112 num_bytes = 1u; 1113 EXPECT_EQ(MOJO_RESULT_BUSY, 1114 core()->WriteData(ph, 1115 UserPointer<const void>(elements), 1116 MakeUserPointer(&num_bytes), 1117 MOJO_WRITE_DATA_FLAG_NONE)); 1118 1119 // Actually write the data, and complete it now. 1120 static_cast<char*>(write_ptr)[0] = 'C'; 1121 static_cast<char*>(write_ptr)[1] = 'D'; 1122 static_cast<char*>(write_ptr)[2] = 'E'; 1123 EXPECT_EQ(MOJO_RESULT_OK, core()->EndWriteData(ph, 3u)); 1124 1125 // Query how much data we have. 1126 num_bytes = 0; 1127 EXPECT_EQ(MOJO_RESULT_OK, 1128 core()->ReadData(ch, 1129 NullUserPointer(), 1130 MakeUserPointer(&num_bytes), 1131 MOJO_READ_DATA_FLAG_QUERY)); 1132 EXPECT_EQ(4u, num_bytes); 1133 1134 // Try to discard ten characters, in all-or-none mode. Should fail. 1135 num_bytes = 10; 1136 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE, 1137 core()->ReadData( 1138 ch, 1139 NullUserPointer(), 1140 MakeUserPointer(&num_bytes), 1141 MOJO_READ_DATA_FLAG_DISCARD | MOJO_READ_DATA_FLAG_ALL_OR_NONE)); 1142 1143 // Discard two characters. 1144 num_bytes = 2; 1145 EXPECT_EQ(MOJO_RESULT_OK, 1146 core()->ReadData( 1147 ch, 1148 NullUserPointer(), 1149 MakeUserPointer(&num_bytes), 1150 MOJO_READ_DATA_FLAG_DISCARD | MOJO_READ_DATA_FLAG_ALL_OR_NONE)); 1151 1152 // Read the remaining two characters, in two-phase mode (all-or-none). 1153 const void* read_ptr = nullptr; 1154 num_bytes = 2; 1155 ASSERT_EQ(MOJO_RESULT_OK, 1156 core()->BeginReadData(ch, 1157 MakeUserPointer(&read_ptr), 1158 MakeUserPointer(&num_bytes), 1159 MOJO_READ_DATA_FLAG_ALL_OR_NONE)); 1160 // Note: Count on still being able to do the contiguous read here. 1161 ASSERT_EQ(2u, num_bytes); 1162 1163 // Discarding right now should fail. 1164 num_bytes = 1; 1165 EXPECT_EQ(MOJO_RESULT_BUSY, 1166 core()->ReadData(ch, 1167 NullUserPointer(), 1168 MakeUserPointer(&num_bytes), 1169 MOJO_READ_DATA_FLAG_DISCARD)); 1170 1171 // Actually check our data and end the two-phase read. 1172 EXPECT_EQ('D', static_cast<const char*>(read_ptr)[0]); 1173 EXPECT_EQ('E', static_cast<const char*>(read_ptr)[1]); 1174 EXPECT_EQ(MOJO_RESULT_OK, core()->EndReadData(ch, 2u)); 1175 1176 // Consumer should now be no longer readable. 1177 hss = kFullMojoHandleSignalsState; 1178 EXPECT_EQ( 1179 MOJO_RESULT_DEADLINE_EXCEEDED, 1180 core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 0, MakeUserPointer(&hss))); 1181 EXPECT_EQ(0u, hss.satisfied_signals); 1182 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals); 1183 1184 // TODO(vtl): More. 1185 1186 // Close the producer. 1187 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(ph)); 1188 1189 // The consumer should now be never-readable. 1190 hss = kFullMojoHandleSignalsState; 1191 EXPECT_EQ( 1192 MOJO_RESULT_FAILED_PRECONDITION, 1193 core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 0, MakeUserPointer(&hss))); 1194 EXPECT_EQ(0u, hss.satisfied_signals); 1195 EXPECT_EQ(0u, hss.satisfiable_signals); 1196 1197 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(ch)); 1198 } 1199 1200 // Tests passing data pipe producer and consumer handles. 1201 TEST_F(CoreTest, MessagePipeBasicLocalHandlePassing2) { 1202 const char kHello[] = "hello"; 1203 const uint32_t kHelloSize = static_cast<uint32_t>(sizeof(kHello)); 1204 const char kWorld[] = "world!!!"; 1205 const uint32_t kWorldSize = static_cast<uint32_t>(sizeof(kWorld)); 1206 char buffer[100]; 1207 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); 1208 uint32_t num_bytes; 1209 MojoHandle handles[10]; 1210 uint32_t num_handles; 1211 MojoHandleSignalsState hss; 1212 1213 MojoHandle h_passing[2]; 1214 EXPECT_EQ(MOJO_RESULT_OK, 1215 core()->CreateMessagePipe(NullUserPointer(), 1216 MakeUserPointer(&h_passing[0]), 1217 MakeUserPointer(&h_passing[1]))); 1218 1219 MojoHandle ph, ch; 1220 EXPECT_EQ(MOJO_RESULT_OK, 1221 core()->CreateDataPipe( 1222 NullUserPointer(), MakeUserPointer(&ph), MakeUserPointer(&ch))); 1223 1224 // Send |ch| from |h_passing[0]| to |h_passing[1]|. 1225 EXPECT_EQ(MOJO_RESULT_OK, 1226 core()->WriteMessage(h_passing[0], 1227 UserPointer<const void>(kHello), 1228 kHelloSize, 1229 MakeUserPointer(&ch), 1230 1, 1231 MOJO_WRITE_MESSAGE_FLAG_NONE)); 1232 hss = kEmptyMojoHandleSignalsState; 1233 EXPECT_EQ(MOJO_RESULT_OK, 1234 core()->Wait(h_passing[1], 1235 MOJO_HANDLE_SIGNAL_READABLE, 1236 1000000000, 1237 MakeUserPointer(&hss))); 1238 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 1239 hss.satisfied_signals); 1240 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 1241 hss.satisfiable_signals); 1242 num_bytes = kBufferSize; 1243 num_handles = arraysize(handles); 1244 EXPECT_EQ(MOJO_RESULT_OK, 1245 core()->ReadMessage(h_passing[1], 1246 UserPointer<void>(buffer), 1247 MakeUserPointer(&num_bytes), 1248 MakeUserPointer(handles), 1249 MakeUserPointer(&num_handles), 1250 MOJO_READ_MESSAGE_FLAG_NONE)); 1251 EXPECT_EQ(kHelloSize, num_bytes); 1252 EXPECT_STREQ(kHello, buffer); 1253 EXPECT_EQ(1u, num_handles); 1254 MojoHandle ch_received = handles[0]; 1255 EXPECT_NE(ch_received, MOJO_HANDLE_INVALID); 1256 EXPECT_NE(ch_received, h_passing[0]); 1257 EXPECT_NE(ch_received, h_passing[1]); 1258 EXPECT_NE(ch_received, ph); 1259 1260 // Note: We rely on the Mojo system not re-using handle values very often. 1261 EXPECT_NE(ch_received, ch); 1262 1263 // |ch| should no longer be valid; check that trying to close it fails. See 1264 // above note. 1265 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(ch)); 1266 1267 // Write to |ph|. Should receive on |ch_received|. 1268 num_bytes = kWorldSize; 1269 EXPECT_EQ(MOJO_RESULT_OK, 1270 core()->WriteData(ph, 1271 UserPointer<const void>(kWorld), 1272 MakeUserPointer(&num_bytes), 1273 MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)); 1274 hss = kEmptyMojoHandleSignalsState; 1275 EXPECT_EQ(MOJO_RESULT_OK, 1276 core()->Wait(ch_received, 1277 MOJO_HANDLE_SIGNAL_READABLE, 1278 1000000000, 1279 MakeUserPointer(&hss))); 1280 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); 1281 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals); 1282 num_bytes = kBufferSize; 1283 EXPECT_EQ(MOJO_RESULT_OK, 1284 core()->ReadData(ch_received, 1285 UserPointer<void>(buffer), 1286 MakeUserPointer(&num_bytes), 1287 MOJO_READ_MESSAGE_FLAG_NONE)); 1288 EXPECT_EQ(kWorldSize, num_bytes); 1289 EXPECT_STREQ(kWorld, buffer); 1290 1291 // Now pass |ph| in the same direction. 1292 EXPECT_EQ(MOJO_RESULT_OK, 1293 core()->WriteMessage(h_passing[0], 1294 UserPointer<const void>(kWorld), 1295 kWorldSize, 1296 MakeUserPointer(&ph), 1297 1, 1298 MOJO_WRITE_MESSAGE_FLAG_NONE)); 1299 hss = kEmptyMojoHandleSignalsState; 1300 EXPECT_EQ(MOJO_RESULT_OK, 1301 core()->Wait(h_passing[1], 1302 MOJO_HANDLE_SIGNAL_READABLE, 1303 1000000000, 1304 MakeUserPointer(&hss))); 1305 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 1306 hss.satisfied_signals); 1307 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 1308 hss.satisfiable_signals); 1309 num_bytes = kBufferSize; 1310 num_handles = arraysize(handles); 1311 EXPECT_EQ(MOJO_RESULT_OK, 1312 core()->ReadMessage(h_passing[1], 1313 UserPointer<void>(buffer), 1314 MakeUserPointer(&num_bytes), 1315 MakeUserPointer(handles), 1316 MakeUserPointer(&num_handles), 1317 MOJO_READ_MESSAGE_FLAG_NONE)); 1318 EXPECT_EQ(kWorldSize, num_bytes); 1319 EXPECT_STREQ(kWorld, buffer); 1320 EXPECT_EQ(1u, num_handles); 1321 MojoHandle ph_received = handles[0]; 1322 EXPECT_NE(ph_received, MOJO_HANDLE_INVALID); 1323 EXPECT_NE(ph_received, h_passing[0]); 1324 EXPECT_NE(ph_received, h_passing[1]); 1325 EXPECT_NE(ph_received, ch_received); 1326 1327 // Again, rely on the Mojo system not re-using handle values very often. 1328 EXPECT_NE(ph_received, ph); 1329 1330 // |ph| should no longer be valid; check that trying to close it fails. See 1331 // above note. 1332 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(ph)); 1333 1334 // Write to |ph_received|. Should receive on |ch_received|. 1335 num_bytes = kHelloSize; 1336 EXPECT_EQ(MOJO_RESULT_OK, 1337 core()->WriteData(ph_received, 1338 UserPointer<const void>(kHello), 1339 MakeUserPointer(&num_bytes), 1340 MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)); 1341 hss = kEmptyMojoHandleSignalsState; 1342 EXPECT_EQ(MOJO_RESULT_OK, 1343 core()->Wait(ch_received, 1344 MOJO_HANDLE_SIGNAL_READABLE, 1345 1000000000, 1346 MakeUserPointer(&hss))); 1347 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); 1348 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals); 1349 num_bytes = kBufferSize; 1350 EXPECT_EQ(MOJO_RESULT_OK, 1351 core()->ReadData(ch_received, 1352 UserPointer<void>(buffer), 1353 MakeUserPointer(&num_bytes), 1354 MOJO_READ_MESSAGE_FLAG_NONE)); 1355 EXPECT_EQ(kHelloSize, num_bytes); 1356 EXPECT_STREQ(kHello, buffer); 1357 1358 ph = ph_received; 1359 ph_received = MOJO_HANDLE_INVALID; 1360 ch = ch_received; 1361 ch_received = MOJO_HANDLE_INVALID; 1362 1363 // Make sure that |ph| can't be sent if it's in a two-phase write. 1364 void* write_ptr = nullptr; 1365 num_bytes = 0; 1366 ASSERT_EQ(MOJO_RESULT_OK, 1367 core()->BeginWriteData(ph, 1368 MakeUserPointer(&write_ptr), 1369 MakeUserPointer(&num_bytes), 1370 MOJO_WRITE_DATA_FLAG_NONE)); 1371 ASSERT_GE(num_bytes, 1u); 1372 EXPECT_EQ(MOJO_RESULT_BUSY, 1373 core()->WriteMessage(h_passing[0], 1374 UserPointer<const void>(kHello), 1375 kHelloSize, 1376 MakeUserPointer(&ph), 1377 1, 1378 MOJO_WRITE_MESSAGE_FLAG_NONE)); 1379 1380 // But |ch| can, even if |ph| is in a two-phase write. 1381 EXPECT_EQ(MOJO_RESULT_OK, 1382 core()->WriteMessage(h_passing[0], 1383 UserPointer<const void>(kHello), 1384 kHelloSize, 1385 MakeUserPointer(&ch), 1386 1, 1387 MOJO_WRITE_MESSAGE_FLAG_NONE)); 1388 ch = MOJO_HANDLE_INVALID; 1389 EXPECT_EQ(MOJO_RESULT_OK, 1390 core()->Wait(h_passing[1], 1391 MOJO_HANDLE_SIGNAL_READABLE, 1392 1000000000, 1393 NullUserPointer())); 1394 num_bytes = kBufferSize; 1395 num_handles = arraysize(handles); 1396 EXPECT_EQ(MOJO_RESULT_OK, 1397 core()->ReadMessage(h_passing[1], 1398 UserPointer<void>(buffer), 1399 MakeUserPointer(&num_bytes), 1400 MakeUserPointer(handles), 1401 MakeUserPointer(&num_handles), 1402 MOJO_READ_MESSAGE_FLAG_NONE)); 1403 EXPECT_EQ(kHelloSize, num_bytes); 1404 EXPECT_STREQ(kHello, buffer); 1405 EXPECT_EQ(1u, num_handles); 1406 ch = handles[0]; 1407 EXPECT_NE(ch, MOJO_HANDLE_INVALID); 1408 1409 // Complete the two-phase write. 1410 static_cast<char*>(write_ptr)[0] = 'x'; 1411 EXPECT_EQ(MOJO_RESULT_OK, core()->EndWriteData(ph, 1)); 1412 1413 // Wait for |ch| to be readable. 1414 hss = kEmptyMojoHandleSignalsState; 1415 EXPECT_EQ( 1416 MOJO_RESULT_OK, 1417 core()->Wait( 1418 ch, MOJO_HANDLE_SIGNAL_READABLE, 1000000000, MakeUserPointer(&hss))); 1419 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); 1420 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals); 1421 1422 // Make sure that |ch| can't be sent if it's in a two-phase read. 1423 const void* read_ptr = nullptr; 1424 num_bytes = 1; 1425 ASSERT_EQ(MOJO_RESULT_OK, 1426 core()->BeginReadData(ch, 1427 MakeUserPointer(&read_ptr), 1428 MakeUserPointer(&num_bytes), 1429 MOJO_READ_DATA_FLAG_ALL_OR_NONE)); 1430 EXPECT_EQ(MOJO_RESULT_BUSY, 1431 core()->WriteMessage(h_passing[0], 1432 UserPointer<const void>(kHello), 1433 kHelloSize, 1434 MakeUserPointer(&ch), 1435 1, 1436 MOJO_WRITE_MESSAGE_FLAG_NONE)); 1437 1438 // But |ph| can, even if |ch| is in a two-phase read. 1439 EXPECT_EQ(MOJO_RESULT_OK, 1440 core()->WriteMessage(h_passing[0], 1441 UserPointer<const void>(kWorld), 1442 kWorldSize, 1443 MakeUserPointer(&ph), 1444 1, 1445 MOJO_WRITE_MESSAGE_FLAG_NONE)); 1446 ph = MOJO_HANDLE_INVALID; 1447 hss = kEmptyMojoHandleSignalsState; 1448 EXPECT_EQ(MOJO_RESULT_OK, 1449 core()->Wait(h_passing[1], 1450 MOJO_HANDLE_SIGNAL_READABLE, 1451 1000000000, 1452 MakeUserPointer(&hss))); 1453 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 1454 hss.satisfied_signals); 1455 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 1456 hss.satisfiable_signals); 1457 num_bytes = kBufferSize; 1458 num_handles = arraysize(handles); 1459 EXPECT_EQ(MOJO_RESULT_OK, 1460 core()->ReadMessage(h_passing[1], 1461 UserPointer<void>(buffer), 1462 MakeUserPointer(&num_bytes), 1463 MakeUserPointer(handles), 1464 MakeUserPointer(&num_handles), 1465 MOJO_READ_MESSAGE_FLAG_NONE)); 1466 EXPECT_EQ(kWorldSize, num_bytes); 1467 EXPECT_STREQ(kWorld, buffer); 1468 EXPECT_EQ(1u, num_handles); 1469 ph = handles[0]; 1470 EXPECT_NE(ph, MOJO_HANDLE_INVALID); 1471 1472 // Complete the two-phase read. 1473 EXPECT_EQ('x', static_cast<const char*>(read_ptr)[0]); 1474 EXPECT_EQ(MOJO_RESULT_OK, core()->EndReadData(ch, 1)); 1475 1476 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[0])); 1477 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[1])); 1478 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(ph)); 1479 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(ch)); 1480 } 1481 1482 // TODO(vtl): Test |DuplicateBufferHandle()| and |MapBuffer()|. 1483 1484 } // namespace 1485 } // namespace system 1486 } // namespace mojo 1487