diff options
author | yzshen@chromium.org <yzshen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-22 00:45:41 +0000 |
---|---|---|
committer | yzshen@chromium.org <yzshen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-22 00:45:41 +0000 |
commit | 82d1f16ab895189640234e5125b29f096de11bb5 (patch) | |
tree | 90ada1cb7d4f583dcb47e5f1cd6955a64b483942 /mojo | |
parent | 1936c46b5190c9e1caf0e102fa5b7a571d8b7f0a (diff) | |
download | chromium_src-82d1f16ab895189640234e5125b29f096de11bb5.zip chromium_src-82d1f16ab895189640234e5125b29f096de11bb5.tar.gz chromium_src-82d1f16ab895189640234e5125b29f096de11bb5.tar.bz2 |
Add some handle read/write helpers to mojo/common/test/test_utils.h
This helps to refactor raw_channel_posix_unittest to run on multiple
platforms.
TEST=mojo_common_unittests,mojo_system_unittests
BUG=None
R=viettrungluu@chromium.org
Review URL: https://codereview.chromium.org/172263006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@252714 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'mojo')
-rw-r--r-- | mojo/common/test/multiprocess_test_base_unittest.cc | 60 | ||||
-rw-r--r-- | mojo/common/test/test_utils.h | 44 | ||||
-rw-r--r-- | mojo/common/test/test_utils_posix.cc | 77 | ||||
-rw-r--r-- | mojo/common/test/test_utils_win.cc | 80 | ||||
-rw-r--r-- | mojo/mojo.gyp | 3 | ||||
-rw-r--r-- | mojo/system/raw_channel_posix_unittest.cc | 28 |
6 files changed, 222 insertions, 70 deletions
diff --git a/mojo/common/test/multiprocess_test_base_unittest.cc b/mojo/common/test/multiprocess_test_base_unittest.cc index 7b0a7ff..659b83d 100644 --- a/mojo/common/test/multiprocess_test_base_unittest.cc +++ b/mojo/common/test/multiprocess_test_base_unittest.cc @@ -6,22 +6,19 @@ #include "base/logging.h" #include "build/build_config.h" +#include "mojo/common/test/test_utils.h" #include "mojo/system/embedder/scoped_platform_handle.h" #if defined(OS_POSIX) #include <fcntl.h> -#include <unistd.h> - -#include "base/posix/eintr_wrapper.h" #endif #if defined(OS_WIN) -#include <windows.h> - #include "base/win/windows_version.h" #endif namespace mojo { +namespace test { namespace { // Returns true and logs a warning on Windows prior to Vista. @@ -46,57 +43,19 @@ bool IsNonBlocking(const embedder::PlatformHandle& handle) { #endif } -// Note: On POSIX, this method sets the handle to block. bool WriteByte(const embedder::PlatformHandle& handle, char c) { -#if defined(OS_WIN) - DWORD num_bytes_written = 0; - OVERLAPPED overlapped = { 0 }; - - if (!WriteFile(handle.handle, &c, 1, &num_bytes_written, &overlapped)) { - if (GetLastError() != ERROR_IO_PENDING) - return false; - - if (GetOverlappedResult(handle.handle, &overlapped, &num_bytes_written, - TRUE)) { - return num_bytes_written == 1; - } - - return false; - } - return num_bytes_written == 1; -#else - // We're lazy. Set it to block. - PCHECK(fcntl(handle.fd, F_SETFL, 0) == 0); - - return HANDLE_EINTR(write(handle.fd, &c, 1)) == 1; -#endif + size_t bytes_written = 0; + BlockingWrite(handle, &c, 1, &bytes_written); + return bytes_written == 1; } -// Note: On POSIX, this method sets the handle to block. bool ReadByte(const embedder::PlatformHandle& handle, char* c) { -#if defined(OS_WIN) - DWORD num_bytes_read = 0; - OVERLAPPED overlapped = { 0 }; - - if (!ReadFile(handle.handle, c, 1, &num_bytes_read, &overlapped)) { - if (GetLastError() != ERROR_IO_PENDING) - return false; - - if (GetOverlappedResult(handle.handle, &overlapped, &num_bytes_read, TRUE)) - return num_bytes_read == 1; - - return false; - } - return num_bytes_read == 1; -#else - // We're lazy. Set it to block. - PCHECK(fcntl(handle.fd, F_SETFL, 0) == 0); - - return HANDLE_EINTR(read(handle.fd, c, 1)) == 1; -#endif + size_t bytes_read = 0; + BlockingRead(handle, c, 1, &bytes_read); + return bytes_read == 1; } -typedef test::MultiprocessTestBase MultiprocessTestBaseTest; +typedef MultiprocessTestBase MultiprocessTestBaseTest; TEST_F(MultiprocessTestBaseTest, RunChild) { if (SkipTest()) @@ -172,4 +131,5 @@ MOJO_MULTIPROCESS_TEST_CHILD_MAIN(PassedChannel) { } } // namespace +} // namespace test } // namespace mojo diff --git a/mojo/common/test/test_utils.h b/mojo/common/test/test_utils.h new file mode 100644 index 0000000..369e2bf --- /dev/null +++ b/mojo/common/test/test_utils.h @@ -0,0 +1,44 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MOJO_COMMON_TEST_TEST_UTILS_H_ +#define MOJO_COMMON_TEST_TEST_UTILS_H_ + +#include <stddef.h> + +namespace mojo { + +namespace embedder { +struct PlatformHandle; +} + +namespace test { + +// On success, |bytes_written| is updated to the number of bytes written; +// otherwise it is untouched. +bool BlockingWrite(const embedder::PlatformHandle& handle, + const void* buffer, + size_t bytes_to_write, + size_t* bytes_written); + +// On success, |bytes_read| is updated to the number of bytes read; otherwise it +// is untouched. +bool BlockingRead(const embedder::PlatformHandle& handle, + void* buffer, + size_t buffer_size, + size_t* bytes_read); + +// If the read is done successfully or would block, the function returns true +// and updates |bytes_read| to the number of bytes read (0 if the read would +// block); otherwise it returns false and leaves |bytes_read| untouched. +// |handle| must already be in non-blocking mode. +bool NonBlockingRead(const embedder::PlatformHandle& handle, + void* buffer, + size_t buffer_size, + size_t* bytes_read); + +} // namespace test +} // namespace mojo + +#endif // MOJO_COMMON_TEST_TEST_UTILS_H_ diff --git a/mojo/common/test/test_utils_posix.cc b/mojo/common/test/test_utils_posix.cc new file mode 100644 index 0000000..e4537d3 --- /dev/null +++ b/mojo/common/test/test_utils_posix.cc @@ -0,0 +1,77 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "mojo/common/test/test_utils.h" + +#include <fcntl.h> +#include <unistd.h> + +#include "base/posix/eintr_wrapper.h" +#include "mojo/system/embedder/platform_handle.h" + +namespace mojo { +namespace test { + +bool BlockingWrite(const embedder::PlatformHandle& handle, + const void* buffer, + size_t bytes_to_write, + size_t* bytes_written) { + int original_flags = fcntl(handle.fd, F_GETFL); + if (original_flags == -1 || + fcntl(handle.fd, F_SETFL, original_flags & (~O_NONBLOCK)) != 0) { + return false; + } + + ssize_t result = HANDLE_EINTR(write(handle.fd, buffer, bytes_to_write)); + + fcntl(handle.fd, F_SETFL, original_flags); + + if (result < 0) + return false; + + *bytes_written = result; + return true; +} + +bool BlockingRead(const embedder::PlatformHandle& handle, + void* buffer, + size_t buffer_size, + size_t* bytes_read) { + int original_flags = fcntl(handle.fd, F_GETFL); + if (original_flags == -1 || + fcntl(handle.fd, F_SETFL, original_flags & (~O_NONBLOCK)) != 0) { + return false; + } + + ssize_t result = HANDLE_EINTR(read(handle.fd, buffer, buffer_size)); + + fcntl(handle.fd, F_SETFL, original_flags); + + if (result < 0) + return false; + + *bytes_read = result; + return true; +} + +bool NonBlockingRead(const embedder::PlatformHandle& handle, + void* buffer, + size_t buffer_size, + size_t* bytes_read) { + ssize_t result = HANDLE_EINTR(read(handle.fd, buffer, buffer_size)); + + if (result < 0) { + if (errno != EAGAIN && errno != EWOULDBLOCK) + return false; + + *bytes_read = 0; + } else { + *bytes_read = result; + } + + return true; +} + +} // namespace test +} // namespace mojo diff --git a/mojo/common/test/test_utils_win.cc b/mojo/common/test/test_utils_win.cc new file mode 100644 index 0000000..5bfbe2b --- /dev/null +++ b/mojo/common/test/test_utils_win.cc @@ -0,0 +1,80 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "mojo/common/test/test_utils.h" + +#include <windows.h> + +#include "mojo/system/embedder/platform_handle.h" + +namespace mojo { +namespace test { + +bool BlockingWrite(const embedder::PlatformHandle& handle, + const void* buffer, + size_t bytes_to_write, + size_t* bytes_written) { + OVERLAPPED overlapped = { 0 }; + DWORD bytes_written_dword = 0; + + if (!WriteFile(handle.handle, buffer, bytes_to_write, &bytes_written_dword, + &overlapped)) { + if (GetLastError() != ERROR_IO_PENDING || + !GetOverlappedResult(handle.handle, &overlapped, &bytes_written_dword, + TRUE)) { + return false; + } + } + + *bytes_written = bytes_written_dword; + return true; +} + +bool BlockingRead(const embedder::PlatformHandle& handle, + void* buffer, + size_t buffer_size, + size_t* bytes_read) { + OVERLAPPED overlapped = { 0 }; + DWORD bytes_read_dword = 0; + + if (!ReadFile(handle.handle, buffer, buffer_size, &bytes_read_dword, + &overlapped)) { + if (GetLastError() != ERROR_IO_PENDING || + !GetOverlappedResult(handle.handle, &overlapped, &bytes_read_dword, + TRUE)) { + return false; + } + } + + *bytes_read = bytes_read_dword; + return true; +} + +bool NonBlockingRead(const embedder::PlatformHandle& handle, + void* buffer, + size_t buffer_size, + size_t* bytes_read) { + OVERLAPPED overlapped = { 0 }; + DWORD bytes_read_dword = 0; + + if (!ReadFile(handle.handle, buffer, buffer_size, &bytes_read_dword, + &overlapped)) { + if (GetLastError() != ERROR_IO_PENDING) + return false; + + CancelIo(handle.handle); + + if (!GetOverlappedResult(handle.handle, &overlapped, &bytes_read_dword, + TRUE)) { + *bytes_read = 0; + return true; + } + } + + *bytes_read = bytes_read_dword; + return true; +} + +} // namespace test +} // namespace mojo diff --git a/mojo/mojo.gyp b/mojo/mojo.gyp index 4c9a5fc..82cd8ab 100644 --- a/mojo/mojo.gyp +++ b/mojo/mojo.gyp @@ -259,6 +259,9 @@ 'sources': [ 'common/test/multiprocess_test_base.cc', 'common/test/multiprocess_test_base.h', + 'common/test/test_utils.h', + 'common/test/test_utils_posix.cc', + 'common/test/test_utils_win.cc', ], }, { diff --git a/mojo/system/raw_channel_posix_unittest.cc b/mojo/system/raw_channel_posix_unittest.cc index 4158bb7..5af66c3 100644 --- a/mojo/system/raw_channel_posix_unittest.cc +++ b/mojo/system/raw_channel_posix_unittest.cc @@ -7,10 +7,7 @@ #include "mojo/system/raw_channel.h" -#include <fcntl.h> -#include <stdint.h> #include <sys/socket.h> -#include <unistd.h> #include <vector> @@ -22,13 +19,13 @@ #include "base/memory/scoped_ptr.h" #include "base/memory/scoped_vector.h" #include "base/message_loop/message_loop.h" -#include "base/posix/eintr_wrapper.h" #include "base/rand_util.h" #include "base/synchronization/lock.h" #include "base/synchronization/waitable_event.h" #include "base/threading/platform_thread.h" // For |Sleep()|. #include "base/threading/simple_thread.h" #include "base/time/time.h" +#include "mojo/common/test/test_utils.h" #include "mojo/system/embedder/platform_channel_pair.h" #include "mojo/system/embedder/platform_handle.h" #include "mojo/system/embedder/scoped_platform_handle.h" @@ -67,10 +64,10 @@ bool WriteTestMessageToHandle(const embedder::PlatformHandle& handle, uint32_t num_bytes) { scoped_ptr<MessageInTransit> message(MakeTestMessage(num_bytes)); - ssize_t write_size = HANDLE_EINTR( - write(handle.fd, message->main_buffer(), message->main_buffer_size())); - bool result = write_size == static_cast<ssize_t>(message->main_buffer_size()); - return result; + size_t write_size = 0; + mojo::test::BlockingWrite( + handle, message->main_buffer(), message->main_buffer_size(), &write_size); + return write_size == message->main_buffer_size(); } // ----------------------------------------------------------------------------- @@ -134,12 +131,9 @@ class TestMessageReaderAndChecker { unsigned char buffer[4096]; for (size_t i = 0; i < kMessageReaderMaxPollIterations;) { - ssize_t read_size = HANDLE_EINTR( - read(handle_.fd, buffer, sizeof(buffer))); - if (read_size < 0) { - PCHECK(errno == EAGAIN || errno == EWOULDBLOCK); - read_size = 0; - } + size_t read_size = 0; + CHECK(mojo::test::NonBlockingRead(handle_, buffer, sizeof(buffer), + &read_size)); // Append newly-read data to |bytes_|. bytes_.insert(bytes_.end(), buffer, buffer + read_size); @@ -285,9 +279,6 @@ class ReadCheckerRawChannelDelegate : public RawChannel::Delegate { // Tests reading (writing using our own custom writer). TEST_F(RawChannelPosixTest, OnReadMessage) { - // We're going to write to |fd(1)|. We'll do so in a blocking manner. - PCHECK(fcntl(handles[1].get().fd, F_SETFL, 0) == 0); - ReadCheckerRawChannelDelegate delegate; scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass(), &delegate, @@ -481,9 +472,6 @@ class FatalErrorRecordingRawChannelDelegate TEST_F(RawChannelPosixTest, OnFatalError) { const size_t kMessageCount = 5; - // We're going to write to |fd(1)|. We'll do so in a blocking manner. - PCHECK(fcntl(handles[1].get().fd, F_SETFL, 0) == 0); - FatalErrorRecordingRawChannelDelegate delegate(2 * kMessageCount); scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass(), &delegate, |