| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 contains tests that are shared between different implementations of | 5 // This file contains tests that are shared between different implementations of |
| 6 // |DataPipeImpl|. | 6 // |DataPipeImpl|. |
| 7 | 7 |
| 8 #include "mojo/edk/system/data_pipe_impl.h" | 8 #include "mojo/edk/system/data_pipe_impl.h" |
| 9 | 9 |
| 10 #include <stdint.h> | 10 #include <stdint.h> |
| 11 | 11 |
| 12 #include <memory> | 12 #include <memory> |
| 13 #include <utility> | 13 #include <utility> |
| 14 | 14 |
| 15 #include "base/logging.h" | 15 #include "base/logging.h" |
| 16 #include "mojo/edk/embedder/platform_channel_pair.h" | 16 #include "mojo/edk/embedder/platform_channel_pair.h" |
| 17 #include "mojo/edk/embedder/simple_platform_support.h" | 17 #include "mojo/edk/embedder/simple_platform_support.h" |
| 18 #include "mojo/edk/platform/thread_utils.h" |
| 18 #include "mojo/edk/system/channel.h" | 19 #include "mojo/edk/system/channel.h" |
| 19 #include "mojo/edk/system/channel_endpoint.h" | 20 #include "mojo/edk/system/channel_endpoint.h" |
| 20 #include "mojo/edk/system/data_pipe.h" | 21 #include "mojo/edk/system/data_pipe.h" |
| 21 #include "mojo/edk/system/data_pipe_consumer_dispatcher.h" | 22 #include "mojo/edk/system/data_pipe_consumer_dispatcher.h" |
| 22 #include "mojo/edk/system/data_pipe_producer_dispatcher.h" | 23 #include "mojo/edk/system/data_pipe_producer_dispatcher.h" |
| 23 #include "mojo/edk/system/memory.h" | 24 #include "mojo/edk/system/memory.h" |
| 24 #include "mojo/edk/system/message_pipe.h" | 25 #include "mojo/edk/system/message_pipe.h" |
| 25 #include "mojo/edk/system/raw_channel.h" | 26 #include "mojo/edk/system/raw_channel.h" |
| 26 #include "mojo/edk/system/test/sleep.h" | |
| 27 #include "mojo/edk/system/test/test_io_thread.h" | 27 #include "mojo/edk/system/test/test_io_thread.h" |
| 28 #include "mojo/edk/system/test/timeouts.h" | 28 #include "mojo/edk/system/test/timeouts.h" |
| 29 #include "mojo/edk/system/waiter.h" | 29 #include "mojo/edk/system/waiter.h" |
| 30 #include "mojo/edk/util/ref_ptr.h" | 30 #include "mojo/edk/util/ref_ptr.h" |
| 31 #include "mojo/public/cpp/system/macros.h" | 31 #include "mojo/public/cpp/system/macros.h" |
| 32 #include "testing/gtest/include/gtest/gtest.h" | 32 #include "testing/gtest/include/gtest/gtest.h" |
| 33 | 33 |
| 34 using mojo::platform::ThreadSleep; |
| 34 using mojo::util::MakeRefCounted; | 35 using mojo::util::MakeRefCounted; |
| 35 using mojo::util::RefPtr; | 36 using mojo::util::RefPtr; |
| 36 | 37 |
| 37 namespace mojo { | 38 namespace mojo { |
| 38 namespace system { | 39 namespace system { |
| 39 namespace { | 40 namespace { |
| 40 | 41 |
| 41 const MojoHandleSignals kAllSignals = MOJO_HANDLE_SIGNAL_READABLE | | 42 const MojoHandleSignals kAllSignals = MOJO_HANDLE_SIGNAL_READABLE | |
| 42 MOJO_HANDLE_SIGNAL_WRITABLE | | 43 MOJO_HANDLE_SIGNAL_WRITABLE | |
| 43 MOJO_HANDLE_SIGNAL_PEER_CLOSED; | 44 MOJO_HANDLE_SIGNAL_PEER_CLOSED; |
| (...skipping 1496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1540 | 1541 |
| 1541 // TODO(vtl): Hack (see also the TODO above): We can't currently wait for a | 1542 // TODO(vtl): Hack (see also the TODO above): We can't currently wait for a |
| 1542 // specified amount of data to be available, so poll. | 1543 // specified amount of data to be available, so poll. |
| 1543 for (size_t i = 0; i < kMaxPoll; i++) { | 1544 for (size_t i = 0; i < kMaxPoll; i++) { |
| 1544 num_bytes = 0u; | 1545 num_bytes = 0u; |
| 1545 EXPECT_EQ(MOJO_RESULT_OK, | 1546 EXPECT_EQ(MOJO_RESULT_OK, |
| 1546 this->ConsumerQueryData(MakeUserPointer(&num_bytes))); | 1547 this->ConsumerQueryData(MakeUserPointer(&num_bytes))); |
| 1547 if (num_bytes >= 10u * sizeof(int32_t)) | 1548 if (num_bytes >= 10u * sizeof(int32_t)) |
| 1548 break; | 1549 break; |
| 1549 | 1550 |
| 1550 test::Sleep(test::EpsilonTimeout()); | 1551 ThreadSleep(test::EpsilonTimeout()); |
| 1551 } | 1552 } |
| 1552 EXPECT_EQ(10u * sizeof(int32_t), num_bytes); | 1553 EXPECT_EQ(10u * sizeof(int32_t), num_bytes); |
| 1553 | 1554 |
| 1554 // Read half. | 1555 // Read half. |
| 1555 num_bytes = 5u * sizeof(int32_t); | 1556 num_bytes = 5u * sizeof(int32_t); |
| 1556 memset(buffer, 0xab, sizeof(buffer)); | 1557 memset(buffer, 0xab, sizeof(buffer)); |
| 1557 EXPECT_EQ(MOJO_RESULT_OK, | 1558 EXPECT_EQ(MOJO_RESULT_OK, |
| 1558 this->ConsumerReadData(UserPointer<void>(buffer), | 1559 this->ConsumerReadData(UserPointer<void>(buffer), |
| 1559 MakeUserPointer(&num_bytes), true, false)); | 1560 MakeUserPointer(&num_bytes), true, false)); |
| 1560 EXPECT_EQ(5u * sizeof(int32_t), num_bytes); | 1561 EXPECT_EQ(5u * sizeof(int32_t), num_bytes); |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1727 UserPointer<const void>(&test_data[20 + total_num_bytes]), | 1728 UserPointer<const void>(&test_data[20 + total_num_bytes]), |
| 1728 MakeUserPointer(&num_bytes), false); | 1729 MakeUserPointer(&num_bytes), false); |
| 1729 if (result == MOJO_RESULT_OK) { | 1730 if (result == MOJO_RESULT_OK) { |
| 1730 total_num_bytes += num_bytes; | 1731 total_num_bytes += num_bytes; |
| 1731 if (total_num_bytes >= 90u) | 1732 if (total_num_bytes >= 90u) |
| 1732 break; | 1733 break; |
| 1733 } else { | 1734 } else { |
| 1734 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE, result); | 1735 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE, result); |
| 1735 } | 1736 } |
| 1736 | 1737 |
| 1737 test::Sleep(test::EpsilonTimeout()); | 1738 ThreadSleep(test::EpsilonTimeout()); |
| 1738 } | 1739 } |
| 1739 EXPECT_EQ(90u, total_num_bytes); | 1740 EXPECT_EQ(90u, total_num_bytes); |
| 1740 | 1741 |
| 1741 // TODO(vtl): (See corresponding TODO in TwoPhaseAllOrNone.) | 1742 // TODO(vtl): (See corresponding TODO in TwoPhaseAllOrNone.) |
| 1742 for (size_t i = 0; i < kMaxPoll; i++) { | 1743 for (size_t i = 0; i < kMaxPoll; i++) { |
| 1743 // We have 100. | 1744 // We have 100. |
| 1744 num_bytes = 0u; | 1745 num_bytes = 0u; |
| 1745 EXPECT_EQ(MOJO_RESULT_OK, | 1746 EXPECT_EQ(MOJO_RESULT_OK, |
| 1746 this->ConsumerQueryData(MakeUserPointer(&num_bytes))); | 1747 this->ConsumerQueryData(MakeUserPointer(&num_bytes))); |
| 1747 if (num_bytes >= 100u) | 1748 if (num_bytes >= 100u) |
| 1748 break; | 1749 break; |
| 1749 | 1750 |
| 1750 test::Sleep(test::EpsilonTimeout()); | 1751 ThreadSleep(test::EpsilonTimeout()); |
| 1751 } | 1752 } |
| 1752 EXPECT_EQ(100u, num_bytes); | 1753 EXPECT_EQ(100u, num_bytes); |
| 1753 | 1754 |
| 1754 if (this->IsStrictCircularBuffer()) { | 1755 if (this->IsStrictCircularBuffer()) { |
| 1755 // Check that a two-phase read can now only read (at most) 90 bytes. (This | 1756 // Check that a two-phase read can now only read (at most) 90 bytes. (This |
| 1756 // checks an implementation detail; this behavior is not guaranteed.) | 1757 // checks an implementation detail; this behavior is not guaranteed.) |
| 1757 const void* read_buffer_ptr = nullptr; | 1758 const void* read_buffer_ptr = nullptr; |
| 1758 num_bytes = 0u; | 1759 num_bytes = 0u; |
| 1759 EXPECT_EQ(MOJO_RESULT_OK, | 1760 EXPECT_EQ(MOJO_RESULT_OK, |
| 1760 this->ConsumerBeginReadData(MakeUserPointer(&read_buffer_ptr), | 1761 this->ConsumerBeginReadData(MakeUserPointer(&read_buffer_ptr), |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1818 EXPECT_GT(num_bytes, 0u); | 1819 EXPECT_GT(num_bytes, 0u); |
| 1819 | 1820 |
| 1820 // TODO(vtl): (See corresponding TODO in TwoPhaseAllOrNone.) | 1821 // TODO(vtl): (See corresponding TODO in TwoPhaseAllOrNone.) |
| 1821 for (size_t i = 0; i < kMaxPoll; i++) { | 1822 for (size_t i = 0; i < kMaxPoll; i++) { |
| 1822 num_bytes = 0u; | 1823 num_bytes = 0u; |
| 1823 EXPECT_EQ(MOJO_RESULT_OK, | 1824 EXPECT_EQ(MOJO_RESULT_OK, |
| 1824 this->ConsumerQueryData(MakeUserPointer(&num_bytes))); | 1825 this->ConsumerQueryData(MakeUserPointer(&num_bytes))); |
| 1825 if (num_bytes >= 2u * kTestDataSize) | 1826 if (num_bytes >= 2u * kTestDataSize) |
| 1826 break; | 1827 break; |
| 1827 | 1828 |
| 1828 test::Sleep(test::EpsilonTimeout()); | 1829 ThreadSleep(test::EpsilonTimeout()); |
| 1829 } | 1830 } |
| 1830 EXPECT_EQ(2u * kTestDataSize, num_bytes); | 1831 EXPECT_EQ(2u * kTestDataSize, num_bytes); |
| 1831 | 1832 |
| 1832 // Start two-phase read. | 1833 // Start two-phase read. |
| 1833 const void* read_buffer_ptr = nullptr; | 1834 const void* read_buffer_ptr = nullptr; |
| 1834 num_bytes = 0u; | 1835 num_bytes = 0u; |
| 1835 EXPECT_EQ(MOJO_RESULT_OK, | 1836 EXPECT_EQ(MOJO_RESULT_OK, |
| 1836 this->ConsumerBeginReadData(MakeUserPointer(&read_buffer_ptr), | 1837 this->ConsumerBeginReadData(MakeUserPointer(&read_buffer_ptr), |
| 1837 MakeUserPointer(&num_bytes))); | 1838 MakeUserPointer(&num_bytes))); |
| 1838 EXPECT_TRUE(read_buffer_ptr); | 1839 EXPECT_TRUE(read_buffer_ptr); |
| (...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2302 EXPECT_EQ(MOJO_RESULT_OK, | 2303 EXPECT_EQ(MOJO_RESULT_OK, |
| 2303 this->ConsumerQueryData(MakeUserPointer(&num_bytes))); | 2304 this->ConsumerQueryData(MakeUserPointer(&num_bytes))); |
| 2304 EXPECT_EQ(0u, num_bytes); | 2305 EXPECT_EQ(0u, num_bytes); |
| 2305 | 2306 |
| 2306 // Try "ending" a two-phase write when one isn't active. | 2307 // Try "ending" a two-phase write when one isn't active. |
| 2307 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | 2308 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, |
| 2308 this->ProducerEndWriteData(1u * sizeof(int32_t))); | 2309 this->ProducerEndWriteData(1u * sizeof(int32_t))); |
| 2309 | 2310 |
| 2310 // Wait a bit, to make sure that if a signal were (incorrectly) sent, it'd | 2311 // Wait a bit, to make sure that if a signal were (incorrectly) sent, it'd |
| 2311 // have time to propagate. | 2312 // have time to propagate. |
| 2312 test::Sleep(test::EpsilonTimeout()); | 2313 ThreadSleep(test::EpsilonTimeout()); |
| 2313 | 2314 |
| 2314 // Still no data. | 2315 // Still no data. |
| 2315 num_bytes = 1000u; | 2316 num_bytes = 1000u; |
| 2316 EXPECT_EQ(MOJO_RESULT_OK, | 2317 EXPECT_EQ(MOJO_RESULT_OK, |
| 2317 this->ConsumerQueryData(MakeUserPointer(&num_bytes))); | 2318 this->ConsumerQueryData(MakeUserPointer(&num_bytes))); |
| 2318 EXPECT_EQ(0u, num_bytes); | 2319 EXPECT_EQ(0u, num_bytes); |
| 2319 | 2320 |
| 2320 // Try ending a two-phase write with an invalid amount (too much). | 2321 // Try ending a two-phase write with an invalid amount (too much). |
| 2321 void* write_ptr = nullptr; | 2322 void* write_ptr = nullptr; |
| 2322 num_bytes = 0u; | 2323 num_bytes = 0u; |
| 2323 EXPECT_EQ(MOJO_RESULT_OK, | 2324 EXPECT_EQ(MOJO_RESULT_OK, |
| 2324 this->ProducerBeginWriteData(MakeUserPointer(&write_ptr), | 2325 this->ProducerBeginWriteData(MakeUserPointer(&write_ptr), |
| 2325 MakeUserPointer(&num_bytes))); | 2326 MakeUserPointer(&num_bytes))); |
| 2326 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | 2327 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, |
| 2327 this->ProducerEndWriteData(num_bytes + | 2328 this->ProducerEndWriteData(num_bytes + |
| 2328 static_cast<uint32_t>(sizeof(int32_t)))); | 2329 static_cast<uint32_t>(sizeof(int32_t)))); |
| 2329 | 2330 |
| 2330 // But the two-phase write still ended. | 2331 // But the two-phase write still ended. |
| 2331 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, this->ProducerEndWriteData(0u)); | 2332 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, this->ProducerEndWriteData(0u)); |
| 2332 | 2333 |
| 2333 // Wait a bit (as above). | 2334 // Wait a bit (as above). |
| 2334 test::Sleep(test::EpsilonTimeout()); | 2335 ThreadSleep(test::EpsilonTimeout()); |
| 2335 | 2336 |
| 2336 // Still no data. | 2337 // Still no data. |
| 2337 num_bytes = 1000u; | 2338 num_bytes = 1000u; |
| 2338 EXPECT_EQ(MOJO_RESULT_OK, | 2339 EXPECT_EQ(MOJO_RESULT_OK, |
| 2339 this->ConsumerQueryData(MakeUserPointer(&num_bytes))); | 2340 this->ConsumerQueryData(MakeUserPointer(&num_bytes))); |
| 2340 EXPECT_EQ(0u, num_bytes); | 2341 EXPECT_EQ(0u, num_bytes); |
| 2341 | 2342 |
| 2342 // Try ending a two-phase write with an invalid amount (not a multiple of the | 2343 // Try ending a two-phase write with an invalid amount (not a multiple of the |
| 2343 // element size). | 2344 // element size). |
| 2344 write_ptr = nullptr; | 2345 write_ptr = nullptr; |
| 2345 num_bytes = 0u; | 2346 num_bytes = 0u; |
| 2346 EXPECT_EQ(MOJO_RESULT_OK, | 2347 EXPECT_EQ(MOJO_RESULT_OK, |
| 2347 this->ProducerBeginWriteData(MakeUserPointer(&write_ptr), | 2348 this->ProducerBeginWriteData(MakeUserPointer(&write_ptr), |
| 2348 MakeUserPointer(&num_bytes))); | 2349 MakeUserPointer(&num_bytes))); |
| 2349 EXPECT_GE(num_bytes, 1u); | 2350 EXPECT_GE(num_bytes, 1u); |
| 2350 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, this->ProducerEndWriteData(1u)); | 2351 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, this->ProducerEndWriteData(1u)); |
| 2351 | 2352 |
| 2352 // But the two-phase write still ended. | 2353 // But the two-phase write still ended. |
| 2353 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, this->ProducerEndWriteData(0u)); | 2354 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, this->ProducerEndWriteData(0u)); |
| 2354 | 2355 |
| 2355 // Wait a bit (as above). | 2356 // Wait a bit (as above). |
| 2356 test::Sleep(test::EpsilonTimeout()); | 2357 ThreadSleep(test::EpsilonTimeout()); |
| 2357 | 2358 |
| 2358 // Still no data. | 2359 // Still no data. |
| 2359 num_bytes = 1000u; | 2360 num_bytes = 1000u; |
| 2360 EXPECT_EQ(MOJO_RESULT_OK, | 2361 EXPECT_EQ(MOJO_RESULT_OK, |
| 2361 this->ConsumerQueryData(MakeUserPointer(&num_bytes))); | 2362 this->ConsumerQueryData(MakeUserPointer(&num_bytes))); |
| 2362 EXPECT_EQ(0u, num_bytes); | 2363 EXPECT_EQ(0u, num_bytes); |
| 2363 | 2364 |
| 2364 // Add waiter. | 2365 // Add waiter. |
| 2365 waiter.Init(); | 2366 waiter.Init(); |
| 2366 ASSERT_EQ(MOJO_RESULT_OK, | 2367 ASSERT_EQ(MOJO_RESULT_OK, |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2462 | 2463 |
| 2463 // TODO(vtl): Hack: We can't currently wait for a specified amount of data to | 2464 // TODO(vtl): Hack: We can't currently wait for a specified amount of data to |
| 2464 // be available, so poll. | 2465 // be available, so poll. |
| 2465 for (size_t i = 0; i < kMaxPoll; i++) { | 2466 for (size_t i = 0; i < kMaxPoll; i++) { |
| 2466 num_bytes = 0u; | 2467 num_bytes = 0u; |
| 2467 EXPECT_EQ(MOJO_RESULT_OK, | 2468 EXPECT_EQ(MOJO_RESULT_OK, |
| 2468 this->ConsumerQueryData(MakeUserPointer(&num_bytes))); | 2469 this->ConsumerQueryData(MakeUserPointer(&num_bytes))); |
| 2469 if (num_bytes >= kTestDataSize) | 2470 if (num_bytes >= kTestDataSize) |
| 2470 break; | 2471 break; |
| 2471 | 2472 |
| 2472 test::Sleep(test::EpsilonTimeout()); | 2473 ThreadSleep(test::EpsilonTimeout()); |
| 2473 } | 2474 } |
| 2474 EXPECT_EQ(kTestDataSize, num_bytes); | 2475 EXPECT_EQ(kTestDataSize, num_bytes); |
| 2475 | 2476 |
| 2476 const void* read_buffer_ptr = nullptr; | 2477 const void* read_buffer_ptr = nullptr; |
| 2477 num_bytes = 0u; | 2478 num_bytes = 0u; |
| 2478 EXPECT_EQ(MOJO_RESULT_OK, | 2479 EXPECT_EQ(MOJO_RESULT_OK, |
| 2479 this->ConsumerBeginReadData(MakeUserPointer(&read_buffer_ptr), | 2480 this->ConsumerBeginReadData(MakeUserPointer(&read_buffer_ptr), |
| 2480 MakeUserPointer(&num_bytes))); | 2481 MakeUserPointer(&num_bytes))); |
| 2481 EXPECT_EQ(kTestDataSize, num_bytes); | 2482 EXPECT_EQ(kTestDataSize, num_bytes); |
| 2482 EXPECT_EQ(0, memcmp(read_buffer_ptr, kTestData, kTestDataSize)); | 2483 EXPECT_EQ(0, memcmp(read_buffer_ptr, kTestData, kTestDataSize)); |
| 2483 | 2484 |
| 2484 // Close the producer. | 2485 // Close the producer. |
| 2485 this->ProducerClose(); | 2486 this->ProducerClose(); |
| 2486 | 2487 |
| 2487 // Note: This tiny sleep is to allow/encourage a certain race. In particular, | 2488 // Note: This tiny sleep is to allow/encourage a certain race. In particular, |
| 2488 // for the remote producer case in | 2489 // for the remote producer case in |
| 2489 // |RemoteProducerDataPipeImpl::MarkDataAsConsumed()| (caused by | 2490 // |RemoteProducerDataPipeImpl::MarkDataAsConsumed()| (caused by |
| 2490 // |ConsumerEndReadData()| below) we want |producer_open()| to be false but | 2491 // |ConsumerEndReadData()| below) we want |producer_open()| to be false but |
| 2491 // the call to |channel_endpoint_->EnqueueMessage()| to fail. (This race can | 2492 // the call to |channel_endpoint_->EnqueueMessage()| to fail. (This race can |
| 2492 // occur without the sleep, but is much less likely.) | 2493 // occur without the sleep, but is much less likely.) |
| 2493 test::Sleep(10u); | 2494 ThreadSleep(10u); |
| 2494 | 2495 |
| 2495 EXPECT_EQ(MOJO_RESULT_OK, this->ConsumerEndReadData(num_bytes)); | 2496 EXPECT_EQ(MOJO_RESULT_OK, this->ConsumerEndReadData(num_bytes)); |
| 2496 | 2497 |
| 2497 this->ConsumerClose(); | 2498 this->ConsumerClose(); |
| 2498 } | 2499 } |
| 2499 | 2500 |
| 2500 } // namespace | 2501 } // namespace |
| 2501 } // namespace system | 2502 } // namespace system |
| 2502 } // namespace mojo | 2503 } // namespace mojo |
| OLD | NEW |