| Index: media/audio/async_socket_io_handler_unittest.cc
|
| diff --git a/media/audio/async_socket_io_handler_unittest.cc b/media/audio/async_socket_io_handler_unittest.cc
|
| index c9caa9f5db05242b48565988bd2f1687c3118c7c..87481984f0b5ae3eabde9a858e6833483ea90b64 100644
|
| --- a/media/audio/async_socket_io_handler_unittest.cc
|
| +++ b/media/audio/async_socket_io_handler_unittest.cc
|
| @@ -14,33 +14,58 @@ const size_t kAsyncSocketIoTestStringLength =
|
|
|
| class TestSocketReader {
|
| public:
|
| - TestSocketReader(base::CancelableSyncSocket* socket, bool quit_on_read)
|
| - : socket_(socket), buffer_(), quit_on_read_(quit_on_read) {
|
| - io_handler.Initialize(socket_->handle());
|
| + // Set |number_of_reads_before_quit| to >0 when you expect a specific number
|
| + // of Read operations to complete. Once that number is reached, the current
|
| + // message loop will be Quit(). Set |number_of_reads_before_quit| to -1 if
|
| + // callbacks should not be counted.
|
| + TestSocketReader(base::CancelableSyncSocket* socket,
|
| + int number_of_reads_before_quit,
|
| + bool issue_reads_from_callback)
|
| + : socket_(socket), buffer_(),
|
| + number_of_reads_before_quit_(number_of_reads_before_quit),
|
| + callbacks_received_(0),
|
| + issue_reads_from_callback_(issue_reads_from_callback) {
|
| + io_handler.Initialize(socket_->handle(),
|
| + base::Bind(&TestSocketReader::OnRead,
|
| + base::Unretained(this)));
|
| }
|
| ~TestSocketReader() {}
|
|
|
| bool IssueRead() {
|
| - return io_handler.Read(&buffer_[0], sizeof(buffer_),
|
| - base::Bind(&TestSocketReader::OnRead,
|
| - base::Unretained(this)));
|
| + return io_handler.Read(&buffer_[0], sizeof(buffer_));
|
| }
|
|
|
| const char* buffer() const { return &buffer_[0]; }
|
|
|
| + int callbacks_received() const { return callbacks_received_; }
|
| +
|
| private:
|
| void OnRead(int bytes_read) {
|
| EXPECT_GT(bytes_read, 0);
|
| - if (quit_on_read_)
|
| + ++callbacks_received_;
|
| + if (number_of_reads_before_quit_ == callbacks_received_) {
|
| MessageLoop::current()->Quit();
|
| + } else if (issue_reads_from_callback_) {
|
| + IssueRead();
|
| + }
|
| }
|
|
|
| media::AsyncSocketIoHandler io_handler;
|
| base::CancelableSyncSocket* socket_; // Ownership lies outside the class.
|
| char buffer_[kAsyncSocketIoTestStringLength];
|
| - bool quit_on_read_;
|
| + int number_of_reads_before_quit_;
|
| + int callbacks_received_;
|
| + bool issue_reads_from_callback_;
|
| };
|
|
|
| +// Workaround to be able to use a base::Closure for sending data.
|
| +// Send() returns int but a closure must return void.
|
| +void SendData(base::CancelableSyncSocket* socket,
|
| + const void* buffer,
|
| + size_t length) {
|
| + socket->Send(buffer, length);
|
| +}
|
| +
|
| } // end namespace.
|
|
|
| // Tests doing a pending read from a socket and use an IO handler to get
|
| @@ -51,12 +76,13 @@ TEST(AsyncSocketIoHandlerTest, AsynchronousReadWithMessageLoop) {
|
| base::CancelableSyncSocket pair[2];
|
| ASSERT_TRUE(base::CancelableSyncSocket::CreatePair(&pair[0], &pair[1]));
|
|
|
| - TestSocketReader reader(&pair[0], true);
|
| + TestSocketReader reader(&pair[0], 1, false);
|
| EXPECT_TRUE(reader.IssueRead());
|
|
|
| pair[1].Send(kAsyncSocketIoTestString, kAsyncSocketIoTestStringLength);
|
| MessageLoop::current()->Run();
|
| EXPECT_EQ(strcmp(reader.buffer(), kAsyncSocketIoTestString), 0);
|
| + EXPECT_EQ(1, reader.callbacks_received());
|
| }
|
|
|
| // Tests doing a read from a socket when we know that there is data in the
|
| @@ -68,7 +94,7 @@ TEST(AsyncSocketIoHandlerTest, SynchronousReadWithMessageLoop) {
|
| base::CancelableSyncSocket pair[2];
|
| ASSERT_TRUE(base::CancelableSyncSocket::CreatePair(&pair[0], &pair[1]));
|
|
|
| - TestSocketReader reader(&pair[0], false);
|
| + TestSocketReader reader(&pair[0], -1, false);
|
|
|
| pair[1].Send(kAsyncSocketIoTestString, kAsyncSocketIoTestStringLength);
|
| MessageLoop::current()->PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(),
|
| @@ -77,4 +103,40 @@ TEST(AsyncSocketIoHandlerTest, SynchronousReadWithMessageLoop) {
|
|
|
| EXPECT_TRUE(reader.IssueRead());
|
| EXPECT_EQ(strcmp(reader.buffer(), kAsyncSocketIoTestString), 0);
|
| + // We've now verified that the read happened synchronously, but it's not
|
| + // guaranteed that the callback has been issued since the callback will be
|
| + // called asynchronously even though the read may have been done.
|
| + // So we call RunAllPending() to allow any event notifications or APC's on
|
| + // Windows, to execute before checking the count of how many callbacks we've
|
| + // received.
|
| + MessageLoop::current()->RunAllPending();
|
| + EXPECT_EQ(1, reader.callbacks_received());
|
| +}
|
| +
|
| +// Calls Read() from within a callback to test that simple read "loops" work.
|
| +TEST(AsyncSocketIoHandlerTest, ReadFromCallback) {
|
| + MessageLoopForIO loop;
|
| +
|
| + base::CancelableSyncSocket pair[2];
|
| + ASSERT_TRUE(base::CancelableSyncSocket::CreatePair(&pair[0], &pair[1]));
|
| +
|
| + const int kReadOperationCount = 10;
|
| + TestSocketReader reader(&pair[0], kReadOperationCount, true);
|
| + EXPECT_TRUE(reader.IssueRead());
|
| +
|
| + // Issue sends on an interval to satisfy the Read() requirements.
|
| + int64 milliseconds = 0;
|
| + for (int i = 0; i < kReadOperationCount; ++i) {
|
| + MessageLoop::current()->PostDelayedTask(FROM_HERE,
|
| + base::Bind(&SendData, &pair[1], kAsyncSocketIoTestString,
|
| + kAsyncSocketIoTestStringLength),
|
| + base::TimeDelta::FromMilliseconds(milliseconds));
|
| + milliseconds += 10;
|
| + }
|
| +
|
| + MessageLoop::current()->PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(),
|
| + base::TimeDelta::FromMilliseconds(100 + milliseconds));
|
| +
|
| + MessageLoop::current()->Run();
|
| + EXPECT_EQ(kReadOperationCount, reader.callbacks_received());
|
| }
|
|
|