Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / base / async_socket_io_handler_unittest.cc
blob2b0e3c25c30af9d09949c3bda4248846a61caf4f
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/async_socket_io_handler.h"
7 #include "base/bind.h"
8 #include "testing/gtest/include/gtest/gtest.h"
10 namespace {
11 const char kAsyncSocketIoTestString[] = "Hello, AsyncSocketIoHandler";
12 const size_t kAsyncSocketIoTestStringLength =
13 arraysize(kAsyncSocketIoTestString);
15 class TestSocketReader {
16 public:
17 // Set |number_of_reads_before_quit| to >0 when you expect a specific number
18 // of Read operations to complete. Once that number is reached, the current
19 // message loop will be Quit(). Set |number_of_reads_before_quit| to -1 if
20 // callbacks should not be counted.
21 TestSocketReader(base::CancelableSyncSocket* socket,
22 int number_of_reads_before_quit,
23 bool issue_reads_from_callback,
24 bool expect_eof)
25 : socket_(socket), buffer_(),
26 number_of_reads_before_quit_(number_of_reads_before_quit),
27 callbacks_received_(0),
28 issue_reads_from_callback_(issue_reads_from_callback),
29 expect_eof_(expect_eof) {
30 io_handler.Initialize(socket_->handle(),
31 base::Bind(&TestSocketReader::OnRead,
32 base::Unretained(this)));
34 ~TestSocketReader() {}
36 bool IssueRead() {
37 return io_handler.Read(&buffer_[0], sizeof(buffer_));
40 const char* buffer() const { return &buffer_[0]; }
42 int callbacks_received() const { return callbacks_received_; }
44 private:
45 void OnRead(int bytes_read) {
46 if (!expect_eof_) {
47 EXPECT_GT(bytes_read, 0);
48 } else {
49 EXPECT_GE(bytes_read, 0);
51 ++callbacks_received_;
52 if (number_of_reads_before_quit_ == callbacks_received_) {
53 base::MessageLoop::current()->Quit();
54 } else if (issue_reads_from_callback_) {
55 IssueRead();
59 base::AsyncSocketIoHandler io_handler;
60 base::CancelableSyncSocket* socket_; // Ownership lies outside the class.
61 char buffer_[kAsyncSocketIoTestStringLength];
62 int number_of_reads_before_quit_;
63 int callbacks_received_;
64 bool issue_reads_from_callback_;
65 bool expect_eof_;
68 // Workaround to be able to use a base::Closure for sending data.
69 // Send() returns int but a closure must return void.
70 void SendData(base::CancelableSyncSocket* socket,
71 const void* buffer,
72 size_t length) {
73 socket->Send(buffer, length);
76 } // end namespace.
78 // Tests doing a pending read from a socket and use an IO handler to get
79 // notified of data.
80 TEST(AsyncSocketIoHandlerTest, AsynchronousReadWithMessageLoop) {
81 base::MessageLoopForIO loop;
83 base::CancelableSyncSocket pair[2];
84 ASSERT_TRUE(base::CancelableSyncSocket::CreatePair(&pair[0], &pair[1]));
86 TestSocketReader reader(&pair[0], 1, false, false);
87 EXPECT_TRUE(reader.IssueRead());
89 pair[1].Send(kAsyncSocketIoTestString, kAsyncSocketIoTestStringLength);
90 base::MessageLoop::current()->Run();
91 EXPECT_EQ(strcmp(reader.buffer(), kAsyncSocketIoTestString), 0);
92 EXPECT_EQ(1, reader.callbacks_received());
95 // Tests doing a read from a socket when we know that there is data in the
96 // socket. Here we want to make sure that any async 'can read' notifications
97 // won't trip us off and that the synchronous case works as well.
98 TEST(AsyncSocketIoHandlerTest, SynchronousReadWithMessageLoop) {
99 base::MessageLoopForIO loop;
101 base::CancelableSyncSocket pair[2];
102 ASSERT_TRUE(base::CancelableSyncSocket::CreatePair(&pair[0], &pair[1]));
104 TestSocketReader reader(&pair[0], -1, false, false);
106 pair[1].Send(kAsyncSocketIoTestString, kAsyncSocketIoTestStringLength);
107 base::MessageLoop::current()->PostDelayedTask(FROM_HERE,
108 base::MessageLoop::QuitClosure(),
109 base::TimeDelta::FromMilliseconds(100));
110 base::MessageLoop::current()->Run();
112 EXPECT_TRUE(reader.IssueRead());
113 EXPECT_EQ(strcmp(reader.buffer(), kAsyncSocketIoTestString), 0);
114 // We've now verified that the read happened synchronously, but it's not
115 // guaranteed that the callback has been issued since the callback will be
116 // called asynchronously even though the read may have been done.
117 // So we call RunUntilIdle() to allow any event notifications or APC's on
118 // Windows, to execute before checking the count of how many callbacks we've
119 // received.
120 base::MessageLoop::current()->RunUntilIdle();
121 EXPECT_EQ(1, reader.callbacks_received());
124 // Calls Read() from within a callback to test that simple read "loops" work.
125 TEST(AsyncSocketIoHandlerTest, ReadFromCallback) {
126 base::MessageLoopForIO loop;
128 base::CancelableSyncSocket pair[2];
129 ASSERT_TRUE(base::CancelableSyncSocket::CreatePair(&pair[0], &pair[1]));
131 const int kReadOperationCount = 10;
132 TestSocketReader reader(&pair[0], kReadOperationCount, true, false);
133 EXPECT_TRUE(reader.IssueRead());
135 // Issue sends on an interval to satisfy the Read() requirements.
136 int64 milliseconds = 0;
137 for (int i = 0; i < kReadOperationCount; ++i) {
138 base::MessageLoop::current()->PostDelayedTask(FROM_HERE,
139 base::Bind(&SendData, &pair[1], kAsyncSocketIoTestString,
140 kAsyncSocketIoTestStringLength),
141 base::TimeDelta::FromMilliseconds(milliseconds));
142 milliseconds += 10;
145 base::MessageLoop::current()->PostDelayedTask(FROM_HERE,
146 base::MessageLoop::QuitClosure(),
147 base::TimeDelta::FromMilliseconds(100 + milliseconds));
149 base::MessageLoop::current()->Run();
150 EXPECT_EQ(kReadOperationCount, reader.callbacks_received());
153 // Calls Read() then close other end, check that a correct callback is received.
154 TEST(AsyncSocketIoHandlerTest, ReadThenClose) {
155 base::MessageLoopForIO loop;
157 base::CancelableSyncSocket pair[2];
158 ASSERT_TRUE(base::CancelableSyncSocket::CreatePair(&pair[0], &pair[1]));
160 const int kReadOperationCount = 1;
161 TestSocketReader reader(&pair[0], kReadOperationCount, false, true);
162 EXPECT_TRUE(reader.IssueRead());
164 pair[1].Close();
166 base::MessageLoop::current()->Run();
167 EXPECT_EQ(kReadOperationCount, reader.callbacks_received());