Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(185)

Side by Side Diff: net/socket/sctp_client_socket_unittest.cc

Issue 6800009: Attn: Mike Belshe Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2011 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.
4
5 #include "net/socket/sctp_client_socket.h"
6
7 #include <netinet/in.h>
8
9 #include "base/basictypes.h"
10 #include "net/base/address_list.h"
11 #include "net/base/host_resolver.h"
12 #include "net/base/io_buffer.h"
13 #include "net/base/listen_socket.h"
14 #include "net/base/net_log.h"
15 #include "net/base/net_log_unittest.h"
16 #include "net/base/net_errors.h"
17 #include "net/base/test_completion_callback.h"
18 #include "net/base/winsock_init.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "testing/platform_test.h"
21
22 namespace net {
23
24 namespace {
25
26 const char kServerReply[] = "HTTP/1.1 404 Not Found";
27
28 class SCTPClientSocketTest
29 : public PlatformTest, public ListenSocket::ListenSocketDelegate {
Mike Belshe 2011/04/06 18:32:53 Since this is a clone of TCPClientSocketTest, lets
30 public:
31 SCTPClientSocketTest()
32 : listen_port_(0),
33 net_log_(CapturingNetLog::kUnbounded) {
34 }
35
36 // ListenSocket needs to know the protocol if we're allowing non-TCP protocols
37 virtual int protocol() {return IPPROTO_SCTP; }
38
39 // Implement ListenSocketDelegate methods
40 virtual void DidAccept(ListenSocket* server, ListenSocket* connection) {
41 connected_sock_ = connection;
42 }
43 virtual void DidRead(ListenSocket*, const char* str, int len) {
44 // TODO(dkegel): this might not be long enough to tickle some bugs.
45 connected_sock_->Send(kServerReply,
46 arraysize(kServerReply) - 1,
47 false /* don't append line feed */);
48 }
49 virtual void DidClose(ListenSocket* sock) {}
50
51 // Testcase hooks
52 virtual void SetUp();
53
54 void CloseServerSocket() {
55 // delete the connected_sock_, which will close it.
56 connected_sock_ = NULL;
57 }
58
59 void PauseServerReads() {
60 connected_sock_->PauseReads();
61 }
62
63 void ResumeServerReads() {
64 connected_sock_->ResumeReads();
65 }
66
67 protected:
68 int listen_port_;
69 CapturingNetLog net_log_;
70 scoped_ptr<SCTPClientSocket> sock_;
71
72 private:
73 scoped_refptr<ListenSocket> listen_sock_;
74 scoped_refptr<ListenSocket> connected_sock_;
75 };
76
77 void SCTPClientSocketTest::SetUp() {
78 PlatformTest::SetUp();
79
80 // Find a free port to listen on
81 ListenSocket *sock = NULL;
82 int port;
83 // Range of ports to listen on. Shouldn't need to try many.
84 const int kMinPort = 10100;
85 const int kMaxPort = 10200;
86 #if defined(OS_WIN)
87 EnsureWinsockInit();
88 #endif
89 for (port = kMinPort; port < kMaxPort; port++) {
90 sock = ListenSocket::Listen("127.0.0.1", port, this);
91 if (sock)
92 break;
93 }
94 ASSERT_TRUE(sock != NULL);
95 listen_sock_ = sock;
96 listen_port_ = port;
97
98 AddressList addr;
99 scoped_ptr<HostResolver> resolver(
100 CreateSystemHostResolver(HostResolver::kDefaultParallelism,
101 NULL, NULL));
102 HostResolver::RequestInfo info(HostPortPair("localhost", listen_port_));
103 int rv = resolver->Resolve(info, &addr, NULL, NULL, BoundNetLog());
104 CHECK_EQ(rv, OK);
105 sock_.reset(new SCTPClientSocket(addr, &net_log_, NetLog::Source()));
106 }
107
108 TEST_F(SCTPClientSocketTest, Connect) {
109 TestCompletionCallback callback;
110 EXPECT_FALSE(sock_->IsConnected());
111
112 int rv = sock_->Connect(&callback);
113
114 net::CapturingNetLog::EntryList net_log_entries;
115 net_log_.GetEntries(&net_log_entries);
116 EXPECT_TRUE(net::LogContainsBeginEvent(
117 net_log_entries, 0, net::NetLog::TYPE_SOCKET_ALIVE));
118 EXPECT_TRUE(net::LogContainsBeginEvent(
119 net_log_entries, 1, net::NetLog::TYPE_SCTP_CONNECT));
120 if (rv != OK) {
121 ASSERT_EQ(rv, ERR_IO_PENDING);
122 rv = callback.WaitForResult();
123 EXPECT_EQ(rv, OK);
124 }
125
126 EXPECT_TRUE(sock_->IsConnected());
127 net_log_.GetEntries(&net_log_entries);
128 EXPECT_TRUE(net::LogContainsEndEvent(
129 net_log_entries, -1, net::NetLog::TYPE_SCTP_CONNECT));
130
131 sock_->Disconnect();
132 EXPECT_FALSE(sock_->IsConnected());
133 }
134
135 // TODO(wtc): Add unit tests for IsConnectedAndIdle:
136 // - Server closes a connection.
137 // - Server sends data unexpectedly.
138
139 TEST_F(SCTPClientSocketTest, Read) {
140 TestCompletionCallback callback;
141 int rv = sock_->Connect(&callback);
142 if (rv != OK) {
143 ASSERT_EQ(rv, ERR_IO_PENDING);
144
145 rv = callback.WaitForResult();
146 EXPECT_EQ(rv, OK);
147 }
148
149 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
150 scoped_refptr<IOBuffer> request_buffer(
151 new IOBuffer(arraysize(request_text) - 1));
152 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
153
154 rv = sock_->Write(request_buffer, arraysize(request_text) - 1, &callback);
155 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
156
157 if (rv == ERR_IO_PENDING) {
158 rv = callback.WaitForResult();
159 EXPECT_EQ(rv, static_cast<int>(arraysize(request_text) - 1));
160 }
161
162 scoped_refptr<IOBuffer> buf(new IOBuffer(4096));
163 uint32 bytes_read = 0;
164 while (bytes_read < arraysize(kServerReply) - 1) {
165 rv = sock_->Read(buf, 4096, &callback);
166 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
167
168 if (rv == ERR_IO_PENDING)
169 rv = callback.WaitForResult();
170
171 ASSERT_GE(rv, 0);
172 bytes_read += rv;
173 }
174
175 // All data has been read now. Read once more to force an ERR_IO_PENDING, and
176 // then close the server socket, and note the close.
177
178 rv = sock_->Read(buf, 4096, &callback);
179 ASSERT_EQ(ERR_IO_PENDING, rv);
180 CloseServerSocket();
181 EXPECT_EQ(0, callback.WaitForResult());
182 }
183
184 TEST_F(SCTPClientSocketTest, Read_SmallChunks) {
185 TestCompletionCallback callback;
186 int rv = sock_->Connect(&callback);
187 if (rv != OK) {
188 ASSERT_EQ(rv, ERR_IO_PENDING);
189
190 rv = callback.WaitForResult();
191 EXPECT_EQ(rv, OK);
192 }
193
194 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
195 scoped_refptr<IOBuffer> request_buffer(
196 new IOBuffer(arraysize(request_text) - 1));
197 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
198
199 rv = sock_->Write(request_buffer, arraysize(request_text) - 1, &callback);
200 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
201
202 if (rv == ERR_IO_PENDING) {
203 rv = callback.WaitForResult();
204 EXPECT_EQ(rv, static_cast<int>(arraysize(request_text) - 1));
205 }
206
207 scoped_refptr<IOBuffer> buf(new IOBuffer(1));
208 uint32 bytes_read = 0;
209 while (bytes_read < arraysize(kServerReply) - 1) {
210 rv = sock_->Read(buf, 1, &callback);
211 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
212
213 if (rv == ERR_IO_PENDING)
214 rv = callback.WaitForResult();
215
216 ASSERT_EQ(1, rv);
217 bytes_read += rv;
218 }
219
220 // All data has been read now. Read once more to force an ERR_IO_PENDING, and
221 // then close the server socket, and note the close.
222
223 rv = sock_->Read(buf, 1, &callback);
224 ASSERT_EQ(ERR_IO_PENDING, rv);
225 CloseServerSocket();
226 EXPECT_EQ(0, callback.WaitForResult());
227 }
228
229 TEST_F(SCTPClientSocketTest, Read_Interrupted) {
230 TestCompletionCallback callback;
231 int rv = sock_->Connect(&callback);
232 if (rv != OK) {
233 ASSERT_EQ(ERR_IO_PENDING, rv);
234
235 rv = callback.WaitForResult();
236 EXPECT_EQ(rv, OK);
237 }
238
239 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
240 scoped_refptr<IOBuffer> request_buffer(
241 new IOBuffer(arraysize(request_text) - 1));
242 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
243
244 rv = sock_->Write(request_buffer, arraysize(request_text) - 1, &callback);
245 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
246
247 if (rv == ERR_IO_PENDING) {
248 rv = callback.WaitForResult();
249 EXPECT_EQ(rv, static_cast<int>(arraysize(request_text) - 1));
250 }
251
252 // Do a partial read and then exit. This test should not crash!
253 scoped_refptr<IOBuffer> buf(new IOBuffer(16));
254 rv = sock_->Read(buf, 16, &callback);
255 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
256
257 if (rv == ERR_IO_PENDING)
258 rv = callback.WaitForResult();
259
260 EXPECT_NE(0, rv);
261 }
262
263 /*
264 TEST_F(SCTPClientSocketTest, DISABLED_FullDuplex_ReadFirst) {
265 TestCompletionCallback callback;
266 int rv = sock_->Connect(&callback);
267 if (rv != OK) {
268 ASSERT_EQ(rv, ERR_IO_PENDING);
269
270 rv = callback.WaitForResult();
271 EXPECT_EQ(rv, OK);
272 }
273
274 // Read first. There's no data, so it should return ERR_IO_PENDING.
275 const int kBufLen = 4096;
276 scoped_refptr<IOBuffer> buf(new IOBuffer(kBufLen));
277 rv = sock_->Read(buf, kBufLen, &callback);
278 EXPECT_EQ(ERR_IO_PENDING, rv);
279
280 PauseServerReads();
281 const int kWriteBufLen = 64 * 1024;
282 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kWriteBufLen));
283 char* request_data = request_buffer->data();
284 memset(request_data, 'A', kWriteBufLen);
285 TestCompletionCallback write_callback;
286
287 while (true) {
288 rv = sock_->Write(request_buffer, kWriteBufLen, &write_callback);
289 ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
290
291 if (rv == ERR_IO_PENDING) {
292 ResumeServerReads();
293 rv = write_callback.WaitForResult();
294 break;
295 }
296 }
297
298 // At this point, both read and write have returned ERR_IO_PENDING, and the
299 // write callback has executed. We wait for the read callback to run now to
300 // make sure that the socket can handle full duplex communications.
301
302 rv = callback.WaitForResult();
303 EXPECT_GE(rv, 0);
304 }
305
306 TEST_F(SCTPClientSocketTest, DISABLED_FullDuplex_WriteFirst) {
307 TestCompletionCallback callback;
308 int rv = sock_->Connect(&callback);
309 if (rv != OK) {
310 ASSERT_EQ(ERR_IO_PENDING, rv);
311
312 rv = callback.WaitForResult();
313 EXPECT_EQ(OK, rv);
314 }
315
316 PauseServerReads();
317 const int kWriteBufLen = 64 * 1024;
318 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kWriteBufLen));
319 char* request_data = request_buffer->data();
320 memset(request_data, 'A', kWriteBufLen);
321 TestCompletionCallback write_callback;
322
323 while (true) {
324 rv = sock_->Write(request_buffer, kWriteBufLen, &write_callback);
325 ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
326
327 if (rv == ERR_IO_PENDING)
328 break;
329 }
330
331 // Now we have the Write() blocked on ERR_IO_PENDING. It's time to force the
332 // Read() to block on ERR_IO_PENDING too.
333
334 const int kBufLen = 4096;
335 scoped_refptr<IOBuffer> buf(new IOBuffer(kBufLen));
336 while (true) {
337 rv = sock_->Read(buf, kBufLen, &callback);
338 ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
339 if (rv == ERR_IO_PENDING)
340 break;
341 }
342
343 // At this point, both read and write have returned ERR_IO_PENDING. Now we
344 // run the write and read callbacks to make sure they can handle full duplex
345 // communications.
346
347 ResumeServerReads();
348 rv = write_callback.WaitForResult();
349 EXPECT_GE(rv, 0);
350
351 // It's possible the read is blocked because it's already read all the data.
352 // Close the server socket, so there will at least be a 0-byte read.
353 CloseServerSocket();
354
355 rv = callback.WaitForResult();
356 EXPECT_GE(rv, 0);
357 }
358 */
359
360 } // namespace
361
362 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698