| 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 // This file tests the C++ Mojo system core wrappers. | 5 // This file tests the C++ Mojo system core wrappers. |
| 6 // TODO(vtl): Split this test into more reasonable units/files. | 6 // TODO(vtl): Split this test into more reasonable units/files. |
| 7 | 7 |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 | 9 |
| 10 #include <map> | 10 #include <map> |
| 11 #include <vector> |
| 11 | 12 |
| 12 #include "mojo/public/cpp/system/buffer.h" | 13 #include "mojo/public/cpp/system/buffer.h" |
| 13 #include "mojo/public/cpp/system/data_pipe.h" | 14 #include "mojo/public/cpp/system/data_pipe.h" |
| 14 #include "mojo/public/cpp/system/handle.h" | 15 #include "mojo/public/cpp/system/handle.h" |
| 15 #include "mojo/public/cpp/system/macros.h" | 16 #include "mojo/public/cpp/system/macros.h" |
| 16 #include "mojo/public/cpp/system/message_pipe.h" | 17 #include "mojo/public/cpp/system/message_pipe.h" |
| 17 #include "mojo/public/cpp/system/time.h" | 18 #include "mojo/public/cpp/system/time.h" |
| 18 #include "mojo/public/cpp/system/wait.h" | 19 #include "mojo/public/cpp/system/wait.h" |
| 19 #include "mojo/public/cpp/system/wait_set.h" | 20 #include "mojo/public/cpp/system/wait_set.h" |
| 20 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
| 21 | 22 |
| 22 namespace mojo { | 23 namespace mojo { |
| 23 namespace { | 24 namespace { |
| 24 | 25 |
| 25 TEST(CoreTest, GetTimeTicksNow) { | |
| 26 const MojoTimeTicks start = GetTimeTicksNow(); | |
| 27 EXPECT_NE(static_cast<MojoTimeTicks>(0), start) | |
| 28 << "GetTimeTicksNow should return nonzero value"; | |
| 29 } | |
| 30 | |
| 31 TEST(CoreTest, Basic) { | 26 TEST(CoreTest, Basic) { |
| 32 // Basic |Handle| implementation: | 27 // |Wait|/|WaitMany|: |
| 33 { | |
| 34 EXPECT_EQ(MOJO_HANDLE_INVALID, kInvalidHandleValue); | |
| 35 | |
| 36 Handle h0; | |
| 37 EXPECT_EQ(kInvalidHandleValue, h0.value()); | |
| 38 EXPECT_EQ(kInvalidHandleValue, *h0.mutable_value()); | |
| 39 EXPECT_FALSE(h0.is_valid()); | |
| 40 | |
| 41 Handle h1(static_cast<MojoHandle>(123)); | |
| 42 EXPECT_EQ(static_cast<MojoHandle>(123), h1.value()); | |
| 43 EXPECT_EQ(static_cast<MojoHandle>(123), *h1.mutable_value()); | |
| 44 EXPECT_TRUE(h1.is_valid()); | |
| 45 *h1.mutable_value() = static_cast<MojoHandle>(456); | |
| 46 EXPECT_EQ(static_cast<MojoHandle>(456), h1.value()); | |
| 47 EXPECT_TRUE(h1.is_valid()); | |
| 48 | |
| 49 h1.swap(h0); | |
| 50 EXPECT_EQ(static_cast<MojoHandle>(456), h0.value()); | |
| 51 EXPECT_TRUE(h0.is_valid()); | |
| 52 EXPECT_FALSE(h1.is_valid()); | |
| 53 | |
| 54 h1.set_value(static_cast<MojoHandle>(789)); | |
| 55 h0.swap(h1); | |
| 56 EXPECT_EQ(static_cast<MojoHandle>(789), h0.value()); | |
| 57 EXPECT_TRUE(h0.is_valid()); | |
| 58 EXPECT_EQ(static_cast<MojoHandle>(456), h1.value()); | |
| 59 EXPECT_TRUE(h1.is_valid()); | |
| 60 | |
| 61 // Make sure copy constructor works. | |
| 62 Handle h2(h0); | |
| 63 EXPECT_EQ(static_cast<MojoHandle>(789), h2.value()); | |
| 64 // And assignment. | |
| 65 h2 = h1; | |
| 66 EXPECT_EQ(static_cast<MojoHandle>(456), h2.value()); | |
| 67 | |
| 68 // Make sure that we can put |Handle|s into |std::map|s. | |
| 69 h0 = Handle(static_cast<MojoHandle>(987)); | |
| 70 h1 = Handle(static_cast<MojoHandle>(654)); | |
| 71 h2 = Handle(static_cast<MojoHandle>(321)); | |
| 72 Handle h3; | |
| 73 std::map<Handle, int> handle_to_int; | |
| 74 handle_to_int[h0] = 0; | |
| 75 handle_to_int[h1] = 1; | |
| 76 handle_to_int[h2] = 2; | |
| 77 handle_to_int[h3] = 3; | |
| 78 | |
| 79 EXPECT_EQ(4u, handle_to_int.size()); | |
| 80 EXPECT_FALSE(handle_to_int.find(h0) == handle_to_int.end()); | |
| 81 EXPECT_EQ(0, handle_to_int[h0]); | |
| 82 EXPECT_FALSE(handle_to_int.find(h1) == handle_to_int.end()); | |
| 83 EXPECT_EQ(1, handle_to_int[h1]); | |
| 84 EXPECT_FALSE(handle_to_int.find(h2) == handle_to_int.end()); | |
| 85 EXPECT_EQ(2, handle_to_int[h2]); | |
| 86 EXPECT_FALSE(handle_to_int.find(h3) == handle_to_int.end()); | |
| 87 EXPECT_EQ(3, handle_to_int[h3]); | |
| 88 EXPECT_TRUE(handle_to_int.find(Handle(static_cast<MojoHandle>(13579))) == | |
| 89 handle_to_int.end()); | |
| 90 | |
| 91 // TODO(vtl): With C++11, support |std::unordered_map|s, etc. (Or figure out | |
| 92 // how to support the variations of |hash_map|.) | |
| 93 } | |
| 94 | |
| 95 // |Handle|/|ScopedHandle| functions: | |
| 96 { | 28 { |
| 97 ScopedHandle h; | 29 ScopedHandle h; |
| 98 | 30 |
| 99 EXPECT_EQ(kInvalidHandleValue, h.get().value()); | |
| 100 | |
| 101 // This should be a no-op. | |
| 102 Close(h.Pass()); | |
| 103 | |
| 104 // It should still be invalid. | |
| 105 EXPECT_EQ(kInvalidHandleValue, h.get().value()); | |
| 106 | |
| 107 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | 31 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, |
| 108 Wait(h.get(), ~MOJO_HANDLE_SIGNAL_NONE, 1000000, nullptr)); | 32 Wait(h.get(), ~MOJO_HANDLE_SIGNAL_NONE, 1000000, nullptr)); |
| 109 | 33 |
| 110 std::vector<Handle> wh; | 34 std::vector<Handle> wh; |
| 111 wh.push_back(h.get()); | 35 wh.push_back(h.get()); |
| 112 std::vector<MojoHandleSignals> sigs; | 36 std::vector<MojoHandleSignals> sigs; |
| 113 sigs.push_back(~MOJO_HANDLE_SIGNAL_NONE); | 37 sigs.push_back(~MOJO_HANDLE_SIGNAL_NONE); |
| 114 WaitManyResult wait_many_result = | 38 WaitManyResult wait_many_result = |
| 115 WaitMany(wh, sigs, MOJO_DEADLINE_INDEFINITE, nullptr); | 39 WaitMany(wh, sigs, MOJO_DEADLINE_INDEFINITE, nullptr); |
| 116 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, wait_many_result.result); | 40 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, wait_many_result.result); |
| 117 EXPECT_TRUE(wait_many_result.IsIndexValid()); | 41 EXPECT_TRUE(wait_many_result.IsIndexValid()); |
| 118 EXPECT_FALSE(wait_many_result.AreSignalsStatesValid()); | 42 EXPECT_FALSE(wait_many_result.AreSignalsStatesValid()); |
| 119 | 43 |
| 120 // Make sure that our specialized template correctly handles |NULL| as well | 44 // Make sure that our specialized template correctly handles |NULL| as well |
| 121 // as |nullptr|. | 45 // as |nullptr|. |
| 122 wait_many_result = WaitMany(wh, sigs, MOJO_DEADLINE_INDEFINITE, NULL); | 46 wait_many_result = WaitMany(wh, sigs, MOJO_DEADLINE_INDEFINITE, NULL); |
| 123 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, wait_many_result.result); | 47 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, wait_many_result.result); |
| 124 EXPECT_EQ(0u, wait_many_result.index); | 48 EXPECT_EQ(0u, wait_many_result.index); |
| 125 EXPECT_TRUE(wait_many_result.IsIndexValid()); | 49 EXPECT_TRUE(wait_many_result.IsIndexValid()); |
| 126 EXPECT_FALSE(wait_many_result.AreSignalsStatesValid()); | 50 EXPECT_FALSE(wait_many_result.AreSignalsStatesValid()); |
| 127 } | 51 } |
| 128 | 52 |
| 129 // |MakeScopedHandle| (just compilation tests): | 53 // |MakeScopedHandle| (just compilation tests): |
| 130 { | 54 { |
| 131 EXPECT_FALSE(MakeScopedHandle(Handle()).is_valid()); | |
| 132 EXPECT_FALSE(MakeScopedHandle(MessagePipeHandle()).is_valid()); | 55 EXPECT_FALSE(MakeScopedHandle(MessagePipeHandle()).is_valid()); |
| 133 EXPECT_FALSE(MakeScopedHandle(DataPipeProducerHandle()).is_valid()); | |
| 134 EXPECT_FALSE(MakeScopedHandle(DataPipeConsumerHandle()).is_valid()); | |
| 135 EXPECT_FALSE(MakeScopedHandle(SharedBufferHandle()).is_valid()); | 56 EXPECT_FALSE(MakeScopedHandle(SharedBufferHandle()).is_valid()); |
| 136 } | 57 } |
| 137 | 58 |
| 138 // |MessagePipeHandle|/|ScopedMessagePipeHandle| functions: | 59 // |MessagePipeHandle|/|ScopedMessagePipeHandle| functions: |
| 139 { | 60 { |
| 140 MessagePipeHandle h_invalid; | 61 MessagePipeHandle h_invalid; |
| 141 EXPECT_FALSE(h_invalid.is_valid()); | 62 EXPECT_FALSE(h_invalid.is_valid()); |
| 142 EXPECT_EQ( | 63 EXPECT_EQ( |
| 143 MOJO_RESULT_INVALID_ARGUMENT, | 64 MOJO_RESULT_INVALID_ARGUMENT, |
| 144 WriteMessageRaw( | 65 WriteMessageRaw( |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 MOJO_WRITE_MESSAGE_FLAG_NONE)); | 386 MOJO_WRITE_MESSAGE_FLAG_NONE)); |
| 466 // |h3_value| should actually be invalid now. | 387 // |h3_value| should actually be invalid now. |
| 467 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(h3_value)); | 388 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(h3_value)); |
| 468 | 389 |
| 469 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h2.release().value())); | 390 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h2.release().value())); |
| 470 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h0.release().value())); | 391 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h0.release().value())); |
| 471 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h1.release().value())); | 392 EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h1.release().value())); |
| 472 } | 393 } |
| 473 } | 394 } |
| 474 | 395 |
| 475 TEST(CoreTest, ScopedHandleMoveCtor) { | |
| 476 ScopedSharedBufferHandle buffer1; | |
| 477 EXPECT_EQ(MOJO_RESULT_OK, CreateSharedBuffer(nullptr, 1024, &buffer1)); | |
| 478 EXPECT_TRUE(buffer1.is_valid()); | |
| 479 | |
| 480 ScopedSharedBufferHandle buffer2; | |
| 481 EXPECT_EQ(MOJO_RESULT_OK, CreateSharedBuffer(nullptr, 1024, &buffer2)); | |
| 482 EXPECT_TRUE(buffer2.is_valid()); | |
| 483 | |
| 484 // If this fails to close buffer1, ScopedHandleBase::CloseIfNecessary() will | |
| 485 // assert. | |
| 486 buffer1 = buffer2.Pass(); | |
| 487 | |
| 488 EXPECT_TRUE(buffer1.is_valid()); | |
| 489 EXPECT_FALSE(buffer2.is_valid()); | |
| 490 } | |
| 491 | |
| 492 TEST(CoreTest, ScopedHandleMoveCtorSelf) { | |
| 493 ScopedSharedBufferHandle buffer1; | |
| 494 EXPECT_EQ(MOJO_RESULT_OK, CreateSharedBuffer(nullptr, 1024, &buffer1)); | |
| 495 EXPECT_TRUE(buffer1.is_valid()); | |
| 496 | |
| 497 buffer1 = buffer1.Pass(); | |
| 498 | |
| 499 EXPECT_TRUE(buffer1.is_valid()); | |
| 500 } | |
| 501 | |
| 502 TEST(CoreTest, WaitManyResult) { | 396 TEST(CoreTest, WaitManyResult) { |
| 503 { | 397 { |
| 504 WaitManyResult wmr(MOJO_RESULT_OK); | 398 WaitManyResult wmr(MOJO_RESULT_OK); |
| 505 EXPECT_FALSE(wmr.IsIndexValid()); | 399 EXPECT_FALSE(wmr.IsIndexValid()); |
| 506 EXPECT_TRUE(wmr.AreSignalsStatesValid()); | 400 EXPECT_TRUE(wmr.AreSignalsStatesValid()); |
| 507 EXPECT_EQ(MOJO_RESULT_OK, wmr.result); | 401 EXPECT_EQ(MOJO_RESULT_OK, wmr.result); |
| 508 } | 402 } |
| 509 | 403 |
| 510 { | 404 { |
| 511 WaitManyResult wmr(MOJO_RESULT_FAILED_PRECONDITION); | 405 WaitManyResult wmr(MOJO_RESULT_FAILED_PRECONDITION); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 536 | 430 |
| 537 { | 431 { |
| 538 WaitManyResult wmr(MOJO_RESULT_FAILED_PRECONDITION, 5u); | 432 WaitManyResult wmr(MOJO_RESULT_FAILED_PRECONDITION, 5u); |
| 539 EXPECT_TRUE(wmr.IsIndexValid()); | 433 EXPECT_TRUE(wmr.IsIndexValid()); |
| 540 EXPECT_TRUE(wmr.AreSignalsStatesValid()); | 434 EXPECT_TRUE(wmr.AreSignalsStatesValid()); |
| 541 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, wmr.result); | 435 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, wmr.result); |
| 542 EXPECT_EQ(5u, wmr.index); | 436 EXPECT_EQ(5u, wmr.index); |
| 543 } | 437 } |
| 544 } | 438 } |
| 545 | 439 |
| 546 TEST(CoreTest, DataPipe) { | |
| 547 ScopedDataPipeProducerHandle ph; | |
| 548 ScopedDataPipeConsumerHandle ch; | |
| 549 | |
| 550 ASSERT_EQ(MOJO_RESULT_OK, CreateDataPipe(nullptr, &ph, &ch)); | |
| 551 ASSERT_TRUE(ph.get().is_valid()); | |
| 552 ASSERT_TRUE(ch.get().is_valid()); | |
| 553 | |
| 554 uint32_t read_threshold = 123u; | |
| 555 EXPECT_EQ(MOJO_RESULT_OK, | |
| 556 GetDataPipeConsumerOptions(ch.get(), &read_threshold)); | |
| 557 EXPECT_EQ(0u, read_threshold); | |
| 558 | |
| 559 EXPECT_EQ(MOJO_RESULT_OK, SetDataPipeConsumerOptions(ch.get(), 2u)); | |
| 560 | |
| 561 EXPECT_EQ(MOJO_RESULT_OK, | |
| 562 GetDataPipeConsumerOptions(ch.get(), &read_threshold)); | |
| 563 EXPECT_EQ(2u, read_threshold); | |
| 564 | |
| 565 // Write a byte. | |
| 566 static const char kA = 'A'; | |
| 567 uint32_t num_bytes = 1u; | |
| 568 EXPECT_EQ(MOJO_RESULT_OK, | |
| 569 WriteDataRaw(ph.get(), &kA, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE)); | |
| 570 | |
| 571 // Waiting for "read threshold" should fail. (Wait a nonzero amount, in case | |
| 572 // there's some latency.) | |
| 573 MojoHandleSignalsState state; | |
| 574 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, | |
| 575 Wait(ch.get(), MOJO_HANDLE_SIGNAL_READ_THRESHOLD, 1000, &state)); | |
| 576 // ... but it should be readable. | |
| 577 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, state.satisfied_signals); | |
| 578 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED | | |
| 579 MOJO_HANDLE_SIGNAL_READ_THRESHOLD, | |
| 580 state.satisfiable_signals); | |
| 581 | |
| 582 // Do a two-phase write of another byte. | |
| 583 void* write_buffer = nullptr; | |
| 584 num_bytes = 0u; | |
| 585 ASSERT_EQ(MOJO_RESULT_OK, | |
| 586 BeginWriteDataRaw(ph.get(), &write_buffer, &num_bytes, | |
| 587 MOJO_WRITE_DATA_FLAG_NONE)); | |
| 588 ASSERT_TRUE(write_buffer); | |
| 589 ASSERT_GT(num_bytes, 0u); | |
| 590 static_cast<char*>(write_buffer)[0] = 'B'; | |
| 591 EXPECT_EQ(MOJO_RESULT_OK, EndWriteDataRaw(ph.get(), 1u)); | |
| 592 | |
| 593 // Now waiting for "read threshold" should succeed. (Wait a nonzero amount, in | |
| 594 // case there's some latency.) | |
| 595 state = MojoHandleSignalsState(); | |
| 596 EXPECT_EQ(MOJO_RESULT_OK, | |
| 597 Wait(ch.get(), MOJO_HANDLE_SIGNAL_READ_THRESHOLD, 1000, &state)); | |
| 598 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_READ_THRESHOLD, | |
| 599 state.satisfied_signals); | |
| 600 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED | | |
| 601 MOJO_HANDLE_SIGNAL_READ_THRESHOLD, | |
| 602 state.satisfiable_signals); | |
| 603 | |
| 604 // Read a byte. | |
| 605 char read_byte = 'x'; | |
| 606 num_bytes = 1u; | |
| 607 EXPECT_EQ(MOJO_RESULT_OK, ReadDataRaw(ch.get(), &read_byte, &num_bytes, | |
| 608 MOJO_READ_DATA_FLAG_NONE)); | |
| 609 EXPECT_EQ(1u, num_bytes); | |
| 610 EXPECT_EQ('A', read_byte); | |
| 611 | |
| 612 // Waiting for "read threshold" should now fail. | |
| 613 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, | |
| 614 Wait(ch.get(), MOJO_HANDLE_SIGNAL_READ_THRESHOLD, 0, nullptr)); | |
| 615 | |
| 616 // Reset the read threshold/options. | |
| 617 EXPECT_EQ(MOJO_RESULT_OK, SetDataPipeConsumerOptionsToDefault(ch.get())); | |
| 618 | |
| 619 // Waiting for "read threshold" should now succeed. | |
| 620 EXPECT_EQ(MOJO_RESULT_OK, | |
| 621 Wait(ch.get(), MOJO_HANDLE_SIGNAL_READ_THRESHOLD, 0, nullptr)); | |
| 622 | |
| 623 // Do a two-phase read. | |
| 624 const void* read_buffer = nullptr; | |
| 625 num_bytes = 0u; | |
| 626 ASSERT_EQ(MOJO_RESULT_OK, BeginReadDataRaw(ch.get(), &read_buffer, &num_bytes, | |
| 627 MOJO_READ_DATA_FLAG_NONE)); | |
| 628 ASSERT_TRUE(read_buffer); | |
| 629 ASSERT_EQ(1u, num_bytes); | |
| 630 EXPECT_EQ('B', static_cast<const char*>(read_buffer)[0]); | |
| 631 EXPECT_EQ(MOJO_RESULT_OK, EndReadDataRaw(ch.get(), 1u)); | |
| 632 | |
| 633 // Waiting for "read" should now fail (time out). | |
| 634 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, | |
| 635 Wait(ch.get(), MOJO_HANDLE_SIGNAL_READ_THRESHOLD, 1000, nullptr)); | |
| 636 | |
| 637 // Close the producer. | |
| 638 ph.reset(); | |
| 639 | |
| 640 // Waiting for "read" should now fail. | |
| 641 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
| 642 Wait(ch.get(), MOJO_HANDLE_SIGNAL_READ_THRESHOLD, 1000, nullptr)); | |
| 643 } | |
| 644 | |
| 645 } // namespace | 440 } // namespace |
| 646 } // namespace mojo | 441 } // namespace mojo |
| OLD | NEW |