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 |