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

Side by Side Diff: net/spdy/spdy_proxy_client_socket_unittest.cc

Issue 3578002: Fixes the tests written for http://codereview.chromium.org/3432009/show... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Modified tests to use DeterministicSocketData - v2 Created 10 years, 2 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
« no previous file with comments | « net/spdy/spdy_proxy_client_socket.cc ('k') | net/spdy/spdy_session.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2010 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/spdy/spdy_proxy_client_socket.h"
6
7 #include "base/utf_string_conversions.h"
8 #include "net/base/address_list.h"
9 #include "net/base/net_log.h"
10 #include "net/base/net_log_unittest.h"
11 #include "net/base/mock_host_resolver.h"
12 #include "net/base/test_completion_callback.h"
13 #include "net/base/winsock_init.h"
14 #include "net/http/http_response_info.h"
15 #include "net/http/http_response_headers.h"
16 #include "net/socket/client_socket_factory.h"
17 #include "net/socket/tcp_client_socket.h"
18 #include "net/socket/socket_test_util.h"
19 #include "net/spdy/spdy_protocol.h"
20 #include "net/spdy/spdy_session_pool.h"
21 #include "net/spdy/spdy_test_util.h"
22 #include "testing/platform_test.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24
25 //-----------------------------------------------------------------------------
26
27 namespace {
28
29 static const char kUrl[] = "https://www.google.com/";
30 static const char kOriginHost[] = "www.google.com";
31 static const int kOriginPort = 443;
32 static const char kOriginHostPort[] = "www.google.com:443";
33 static const char kProxyUrl[] = "http://myproxy:6121/";
34 static const char kProxyHost[] = "myproxy";
35 static const int kProxyPort = 6121;
36 static const char kUserAgent[] = "Mozilla/1.0";
37
38 static const int kStreamId = 1;
39
40 static const char kMsg1[] = "\0hello!\xff";
41 static const int kLen1 = 8;
42 static const char kMsg2[] = "\012345678\0";
43 static const int kLen2 = 10;
44 static const char kMsg3[] = "bye!";
45 static const int kLen3 = 4;
46 static const char kMsg33[] = "bye!bye!";
47 static const int kLen33 = kLen3 + kLen3;
48
49 } // anonymous namespace
50
51 namespace net {
52
53 class SpdyProxyClientSocketTest : public PlatformTest {
54 public:
55 SpdyProxyClientSocketTest();
56
57 virtual void TearDown();
58
59 protected:
60 void Initialize(MockRead* reads, size_t reads_count, MockWrite* writes,
61 size_t writes_count);
62 spdy::SpdyFrame* ConstructConnectRequestFrame();
63 spdy::SpdyFrame* ConstructConnectAuthRequestFrame();
64 spdy::SpdyFrame* ConstructConnectReplyFrame();
65 spdy::SpdyFrame* ConstructConnectAuthReplyFrame();
66 spdy::SpdyFrame* ConstructConnectErrorReplyFrame();
67 spdy::SpdyFrame* ConstructBodyFrame(const char* data, int length);
68 scoped_refptr<IOBufferWithSize> CreateBuffer(const char* data, int size);
69 void AssertConnectSucceeds();
70 void AssertConnectFails(int result);
71 void AssertConnectionEstablished();
72 void AssertSyncReadEquals(const char* data, int len);
73 void AssertAsyncReadEquals(const char* data, int len);
74 void AssertReadStarts(const char* data, int len);
75 void AssertReadReturns(const char* data, int len);
76 void AssertAsyncWriteSucceeds(const char* data, int len);
77 void AssertAsyncWriteWithReadsSucceeds(const char* data, int len,
78 int num_reads);
79
80 void AddAuthToCache() {
81 const string16 kFoo(ASCIIToUTF16("foo"));
82 const string16 kBar(ASCIIToUTF16("bar"));
83 session_->auth_cache()->Add(GURL(kProxyUrl), "MyRealm1", "Basic",
84 "Basic realm=MyRealm1", kFoo, kBar, "/");
85 }
86
87 void Run(int steps) {
88 data_->SetStop(data_->sequence_number() + steps);
89 data_->Run();
90 }
91
92 scoped_ptr<SpdyProxyClientSocket> sock_;
93 TestCompletionCallback read_callback_;
94 TestCompletionCallback write_callback_;
95
96
97 private:
98 scoped_refptr<HttpNetworkSession> session_;
99 scoped_refptr<DeterministicSocketData> data_;
100 scoped_refptr<IOBuffer> read_buf_;
101 SpdySessionDependencies session_deps_;
102 MockConnect connect_data_;
103 scoped_refptr<SpdySession> spdy_session_;
104 scoped_refptr<SpdyStream> spdy_stream_;
105 spdy::SpdyFramer framer_;
106
107 std::string user_agent_;
108 GURL url_;
109 HostPortPair proxy_host_port_;
110 HostPortPair endpoint_host_port_pair_;
111 ProxyServer proxy_;
112 HostPortProxyPair endpoint_host_port_proxy_pair_;
113 scoped_refptr<TCPSocketParams> tcp_params_;
114
115 DISALLOW_COPY_AND_ASSIGN(SpdyProxyClientSocketTest);
116 };
117
118 SpdyProxyClientSocketTest::SpdyProxyClientSocketTest()
119 : sock_(NULL),
120 read_callback_(),
121 write_callback_(),
122 session_(NULL),
123 data_(NULL),
124 read_buf_(NULL),
125 session_deps_(),
126 connect_data_(false, OK),
127 spdy_session_(NULL),
128 spdy_stream_(NULL),
129 framer_(),
130 user_agent_(kUserAgent),
131 url_(kUrl),
132 proxy_host_port_(kProxyHost, kProxyPort),
133 endpoint_host_port_pair_(kOriginHost, kOriginPort),
134 proxy_(ProxyServer::SCHEME_HTTPS, proxy_host_port_),
135 endpoint_host_port_proxy_pair_(endpoint_host_port_pair_, proxy_),
136 tcp_params_(new TCPSocketParams(proxy_host_port_, LOWEST, url_, false)) {
137 }
138
139 void SpdyProxyClientSocketTest::TearDown() {
140 if (session_ != NULL)
141 session_->spdy_session_pool()->CloseAllSessions();
142
143 spdy::SpdyFramer::set_enable_compression_default(true);
144 // Empty the current queue.
145 MessageLoop::current()->RunAllPending();
146 PlatformTest::TearDown();
147 }
148
149 void SpdyProxyClientSocketTest::Initialize(MockRead* reads,
150 size_t reads_count,
151 MockWrite* writes,
152 size_t writes_count) {
153 data_ = new DeterministicSocketData(reads, reads_count, writes, writes_count);
154 data_->set_connect_data(connect_data_);
155 data_->SetStop(2);
156
157 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
158 data_.get());
159 session_deps_.host_resolver->set_synchronous_mode(true);
160
161 session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
162 &session_deps_);
163 SpdySession::SetSSLMode(false);
164 spdy::SpdyFramer::set_enable_compression_default(false);
165
166 // Creates a new spdy session
167 spdy_session_ =
168 session_->spdy_session_pool()->Get(endpoint_host_port_proxy_pair_,
169 session_->mutable_spdy_settings(),
170 BoundNetLog());
171
172 // Perform the TCP connect
173 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
174 EXPECT_EQ(OK,
175 connection->Init(endpoint_host_port_pair_.ToString(), tcp_params_,
176 LOWEST, NULL, session_->tcp_socket_pool(),
177 BoundNetLog()));
178 spdy_session_->InitializeWithSocket(connection.release(), false, OK);
179
180 // Create the SPDY Stream
181 ASSERT_EQ(
182 OK,
183 spdy_session_->CreateStream(url_, LOWEST, &spdy_stream_, BoundNetLog(),
184 NULL));
185
186 // Create the SpdyProxyClientSocket
187 sock_.reset(
188 new SpdyProxyClientSocket(spdy_stream_, user_agent_,
189 endpoint_host_port_pair_, url_,
190 proxy_host_port_, session_->auth_cache(),
191 session_->http_auth_handler_factory()));
192 }
193
194 scoped_refptr<IOBufferWithSize> SpdyProxyClientSocketTest::CreateBuffer(
195 const char* data, int size) {
196 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(size));
197 memcpy(buf->data(), data, size);
198 return buf;
199 }
200
201 void SpdyProxyClientSocketTest::AssertConnectSucceeds() {
202 ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(&read_callback_));
203 data_->Run();
204 ASSERT_EQ(OK, read_callback_.WaitForResult());
205 }
206
207 void SpdyProxyClientSocketTest::AssertConnectFails(int result) {
208 ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(&read_callback_));
209 data_->Run();
210 ASSERT_EQ(result, read_callback_.WaitForResult());
211 }
212
213 void SpdyProxyClientSocketTest::AssertConnectionEstablished() {
214 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
215 ASSERT_TRUE(response != NULL);
216 ASSERT_EQ(200, response->headers->response_code());
217 ASSERT_EQ("Connection Established", response->headers->GetStatusText());
218 }
219
220 void SpdyProxyClientSocketTest::AssertSyncReadEquals(const char* data,
221 int len) {
222 scoped_refptr<IOBuffer> buf(new IOBuffer(len));
223 ASSERT_EQ(len, sock_->Read(buf, len, NULL));
224 ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
225 ASSERT_TRUE(sock_->IsConnected());
226 }
227
228 void SpdyProxyClientSocketTest::AssertAsyncReadEquals(const char* data,
229 int len) {
230 data_->SetStop(data_->sequence_number() + 1);
231 // Issue the read, which will be completed asynchronously
232 scoped_refptr<IOBuffer> buf(new IOBuffer(len));
233 ASSERT_EQ(ERR_IO_PENDING, sock_->Read(buf, len, &read_callback_));
234 EXPECT_TRUE(sock_->IsConnected());
235 data_->Run();
236
237 EXPECT_TRUE(sock_->IsConnected());
238
239 // Now the read will return
240 EXPECT_EQ(len, read_callback_.WaitForResult());
241 ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
242 }
243
244 void SpdyProxyClientSocketTest::AssertReadStarts(const char* data, int len) {
245 data_->SetStop(data_->sequence_number() + 1);
246 // Issue the read, which will be completed asynchronously
247 read_buf_ = new IOBuffer(len);
248 ASSERT_EQ(ERR_IO_PENDING, sock_->Read(read_buf_, len, &read_callback_));
249 EXPECT_TRUE(sock_->IsConnected());
250 }
251
252 void SpdyProxyClientSocketTest::AssertReadReturns(const char* data, int len) {
253 EXPECT_TRUE(sock_->IsConnected());
254
255 // Now the read will return
256 EXPECT_EQ(len, read_callback_.WaitForResult());
257 ASSERT_EQ(std::string(data, len), std::string(read_buf_->data(), len));
258 }
259
260 void SpdyProxyClientSocketTest::AssertAsyncWriteSucceeds(const char* data,
261 int len) {
262 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
263
264 data_->SetStop(data_->sequence_number() + 1);
265 EXPECT_EQ(ERR_IO_PENDING, sock_->Write(buf, buf->size(), &write_callback_));
266 data_->Run();
267
268 write_callback_.WaitForResult();
269 }
270
271 void SpdyProxyClientSocketTest::AssertAsyncWriteWithReadsSucceeds(
272 const char* data, int len, int num_reads) {
273 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
274
275 EXPECT_EQ(ERR_IO_PENDING, sock_->Write(buf, buf->size(), &write_callback_));
276
277 for (int i = 0; i < num_reads; i++) {
278 Run(1);
279 AssertSyncReadEquals(kMsg2, kLen2);
280 }
281
282 write_callback_.WaitForResult();
283 }
284
285 // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
286 spdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectRequestFrame() {
287 const SpdyHeaderInfo kSynStartHeader = {
288 spdy::SYN_STREAM,
289 kStreamId,
290 0,
291 net::ConvertRequestPriorityToSpdyPriority(LOWEST),
292 spdy::CONTROL_FLAG_NONE,
293 false,
294 spdy::INVALID,
295 NULL,
296 0,
297 spdy::DATA_FLAG_NONE
298 };
299 const char* const kConnectHeaders[] = {
300 "method", "CONNECT",
301 "url", kOriginHostPort,
302 "host", kOriginHost,
303 "user-agent", kUserAgent,
304 "version", "HTTP/1.1",
305 "proxy-connection", "keep-alive",
306 };
307 return ConstructSpdyPacket(
308 kSynStartHeader, NULL, 0, kConnectHeaders, arraysize(kConnectHeaders)/2);
309 }
310
311 // Constructs a SPDY SYN_STREAM frame for a CONNECT request which includes
312 // Proxy-Authorization headers.
313 spdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthRequestFrame() {
314 const SpdyHeaderInfo kSynStartHeader = {
315 spdy::SYN_STREAM,
316 kStreamId,
317 0,
318 net::ConvertRequestPriorityToSpdyPriority(LOWEST),
319 spdy::CONTROL_FLAG_NONE,
320 false,
321 spdy::INVALID,
322 NULL,
323 0,
324 spdy::DATA_FLAG_NONE
325 };
326 const char* const kConnectHeaders[] = {
327 "method", "CONNECT",
328 "url", kOriginHostPort,
329 "host", kOriginHost,
330 "user-agent", kUserAgent,
331 "version", "HTTP/1.1",
332 "proxy-authorization", "Basic Zm9vOmJhcg==",
333 "proxy-connection", "keep-alive",
334 };
335 return ConstructSpdyPacket(
336 kSynStartHeader, NULL, 0, kConnectHeaders, arraysize(kConnectHeaders)/2);
337 }
338
339 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
340 spdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectReplyFrame() {
341 const char* const kStandardReplyHeaders[] = {
342 "status", "200 Connection Established",
343 "version", "HTTP/1.1"
344 };
345 return ConstructSpdyControlFrame(NULL,
346 0,
347 false,
348 kStreamId,
349 LOWEST,
350 spdy::SYN_REPLY,
351 spdy::CONTROL_FLAG_NONE,
352 kStandardReplyHeaders,
353 arraysize(kStandardReplyHeaders));
354 }
355
356 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
357 spdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthReplyFrame() {
358 const char* const kStandardReplyHeaders[] = {
359 "status", "407 Proxy Authentication Required",
360 "version", "HTTP/1.1",
361 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
362 };
363
364 return ConstructSpdyControlFrame(NULL,
365 0,
366 false,
367 kStreamId,
368 LOWEST,
369 spdy::SYN_REPLY,
370 spdy::CONTROL_FLAG_NONE,
371 kStandardReplyHeaders,
372 arraysize(kStandardReplyHeaders));
373 }
374
375 // Constructs a SPDY SYN_REPLY frame with an HTTP 500 error.
376 spdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectErrorReplyFrame() {
377 const char* const kStandardReplyHeaders[] = {
378 "status", "500 Internal Server Error",
379 "version", "HTTP/1.1",
380 };
381
382 return ConstructSpdyControlFrame(NULL,
383 0,
384 false,
385 kStreamId,
386 LOWEST,
387 spdy::SYN_REPLY,
388 spdy::CONTROL_FLAG_NONE,
389 kStandardReplyHeaders,
390 arraysize(kStandardReplyHeaders));
391 }
392
393 spdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructBodyFrame(const char* data,
394 int length) {
395 return framer_.CreateDataFrame(kStreamId, data, length, spdy::DATA_FLAG_NONE);
396 }
397
398 // ----------- Connect
399
400 TEST_F(SpdyProxyClientSocketTest, ConnectSendsCorrectRequest) {
401 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
402 MockWrite writes[] = {
403 CreateMockWrite(*conn, 0, false),
404 };
405
406 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
407 MockRead reads[] = {
408 CreateMockRead(*resp, 1, false),
409 MockRead(false, 0, 3), // EOF
410 };
411
412 Initialize(reads, arraysize(reads), writes, arraysize(writes));
413
414 ASSERT_FALSE(sock_->IsConnected());
415
416 AssertConnectSucceeds();
417
418 AssertConnectionEstablished();
419 }
420
421 TEST_F(SpdyProxyClientSocketTest, ConnectWithAuthRequested) {
422 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
423 MockWrite writes[] = {
424 CreateMockWrite(*conn, 0, false),
425 };
426
427 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectAuthReplyFrame());
428 MockRead reads[] = {
429 CreateMockRead(*resp, 1, false),
430 MockRead(false, 0, 3), // EOF
431 };
432
433 Initialize(reads, arraysize(reads), writes, arraysize(writes));
434
435 AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
436
437 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
438 ASSERT_TRUE(response != NULL);
439 ASSERT_EQ(407, response->headers->response_code());
440 ASSERT_EQ("Proxy Authentication Required",
441 response->headers->GetStatusText());
442 }
443
444 TEST_F(SpdyProxyClientSocketTest, ConnectWithAuthCredentials) {
445 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectAuthRequestFrame());
446 MockWrite writes[] = {
447 CreateMockWrite(*conn, 0, false),
448 };
449
450 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
451 MockRead reads[] = {
452 CreateMockRead(*resp, 1, false),
453 MockRead(false, 0, 3), // EOF
454 };
455
456 Initialize(reads, arraysize(reads), writes, arraysize(writes));
457 AddAuthToCache();
458
459 AssertConnectSucceeds();
460
461 AssertConnectionEstablished();
462 }
463
464 TEST_F(SpdyProxyClientSocketTest, ConnectFails) {
465 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
466 MockWrite writes[] = {
467 CreateMockWrite(*conn, 0, false),
468 };
469
470 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
471 MockRead reads[] = {
472 MockRead(false, 0, 1), // EOF
473 };
474
475 Initialize(reads, arraysize(reads), writes, arraysize(writes));
476
477 ASSERT_FALSE(sock_->IsConnected());
478
479 AssertConnectFails(ERR_CONNECTION_CLOSED);
480
481 ASSERT_FALSE(sock_->IsConnected());
482 }
483
484 // ----------- WasEverUsed
485
486 TEST_F(SpdyProxyClientSocketTest, WasEverUsedReturnsCorrectValues) {
487 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
488 MockWrite writes[] = {
489 CreateMockWrite(*conn, 0, false),
490 };
491
492 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
493 MockRead reads[] = {
494 CreateMockRead(*resp, 1, false),
495 MockRead(false, 0, 3), // EOF
496 };
497
498 Initialize(reads, arraysize(reads), writes, arraysize(writes));
499
500 EXPECT_FALSE(sock_->WasEverUsed());
501 AssertConnectSucceeds();
502 EXPECT_TRUE(sock_->WasEverUsed());
503 sock_->Disconnect();
504 EXPECT_TRUE(sock_->WasEverUsed());
505 }
506
507 // ----------- GetPeerAddress
508
509 TEST_F(SpdyProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) {
510 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
511 MockWrite writes[] = {
512 CreateMockWrite(*conn, 0, false),
513 };
514
515 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
516 MockRead reads[] = {
517 CreateMockRead(*resp, 1, false),
518 MockRead(false, 0, 3), // EOF
519 };
520
521 Initialize(reads, arraysize(reads), writes, arraysize(writes));
522
523 net::AddressList addr;
524 EXPECT_EQ(ERR_UNEXPECTED, sock_->GetPeerAddress(&addr));
525 AssertConnectSucceeds();
526 EXPECT_TRUE(sock_->IsConnected());
527 EXPECT_EQ(OK, sock_->GetPeerAddress(&addr));
528 sock_->Disconnect();
529 EXPECT_EQ(ERR_UNEXPECTED, sock_->GetPeerAddress(&addr));
530 }
531
532 // ----------- Write
533
534 TEST_F(SpdyProxyClientSocketTest, WriteSendsDataInDataFrame) {
535 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
536 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
537 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
538 MockWrite writes[] = {
539 CreateMockWrite(*conn, 0, false),
540 CreateMockWrite(*msg1, 2, false),
541 CreateMockWrite(*msg2, 3, false),
542 };
543
544 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
545 MockRead reads[] = {
546 CreateMockRead(*resp, 1, false),
547 MockRead(false, 0, 4), // EOF
548 };
549
550 Initialize(reads, arraysize(reads), writes, arraysize(writes));
551
552 AssertConnectSucceeds();
553
554 AssertAsyncWriteSucceeds(kMsg1, kLen1);
555 AssertAsyncWriteSucceeds(kMsg2, kLen2);
556 }
557
558 TEST_F(SpdyProxyClientSocketTest, WriteSplitsLargeDataIntoMultipleFrames) {
559 std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
560 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
561 scoped_ptr<spdy::SpdyFrame> chunk(ConstructBodyFrame(chunk_data.data(),
562 chunk_data.length()));
563 MockWrite writes[] = {
564 CreateMockWrite(*conn, 0, false),
565 CreateMockWrite(*chunk, 2, false),
566 CreateMockWrite(*chunk, 3, false),
567 CreateMockWrite(*chunk, 4, false)
568 };
569
570 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
571 MockRead reads[] = {
572 CreateMockRead(*resp, 1, false),
573 MockRead(false, 0, 5), // EOF
574 };
575
576 Initialize(reads, arraysize(reads), writes, arraysize(writes));
577
578 AssertConnectSucceeds();
579
580 std::string big_data(kMaxSpdyFrameChunkSize * 3, 'x');
581 AssertAsyncWriteSucceeds(big_data.data(), big_data.length());
582 }
583
584 // ----------- Read
585
586 TEST_F(SpdyProxyClientSocketTest, ReadReadsDataInDataFrame) {
587 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
588 MockWrite writes[] = {
589 CreateMockWrite(*conn, 0, false),
590 };
591
592 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
593 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
594 MockRead reads[] = {
595 CreateMockRead(*resp, 1, false),
596 CreateMockRead(*msg1, 2, false),
597 MockRead(false, 0, 3), // EOF
598 };
599
600 Initialize(reads, arraysize(reads), writes, arraysize(writes));
601
602 AssertConnectSucceeds();
603
604 Run(1); // SpdySession consumes the next read and sends it to
605 // sock_ to be buffered.
606 AssertSyncReadEquals(kMsg1, kLen1);
607 }
608
609 TEST_F(SpdyProxyClientSocketTest, ReadDataFromBufferedFrames) {
610 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
611 MockWrite writes[] = {
612 CreateMockWrite(*conn, 0, false),
613 };
614
615 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
616 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
617 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
618 MockRead reads[] = {
619 CreateMockRead(*resp, 1, false),
620 CreateMockRead(*msg1, 2, false),
621 CreateMockRead(*msg2, 3, false),
622 MockRead(false, 0, 4), // EOF
623 };
624
625 Initialize(reads, arraysize(reads), writes, arraysize(writes));
626
627 AssertConnectSucceeds();
628
629 Run(1); // SpdySession consumes the next read and sends it to
630 // sock_ to be buffered.
631 AssertSyncReadEquals(kMsg1, kLen1);
632 Run(1); // SpdySession consumes the next read and sends it to
633 // sock_ to be buffered.
634 AssertSyncReadEquals(kMsg2, kLen2);
635 }
636
637 TEST_F(SpdyProxyClientSocketTest, ReadDataMultipleBufferedFrames) {
638 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
639 MockWrite writes[] = {
640 CreateMockWrite(*conn, 0, false),
641 };
642
643 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
644 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
645 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
646 MockRead reads[] = {
647 CreateMockRead(*resp, 1, false),
648 CreateMockRead(*msg1, 2, false),
649 CreateMockRead(*msg2, 3, false),
650 MockRead(false, 0, 4), // EOF
651 };
652
653 Initialize(reads, arraysize(reads), writes, arraysize(writes));
654
655 AssertConnectSucceeds();
656
657 Run(2); // SpdySession consumes the next two reads and sends then to
658 // sock_ to be buffered.
659 AssertSyncReadEquals(kMsg1, kLen1);
660 AssertSyncReadEquals(kMsg2, kLen2);
661 }
662
663 TEST_F(SpdyProxyClientSocketTest, LargeReadWillMergeDataFromDifferentFrames) {
664 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
665 MockWrite writes[] = {
666 CreateMockWrite(*conn, 0, false),
667 };
668
669 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
670 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
671 scoped_ptr<spdy::SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
672 MockRead reads[] = {
673 CreateMockRead(*resp, 1, false),
674 CreateMockRead(*msg3, 2, false),
675 CreateMockRead(*msg3, 3, false),
676 MockRead(false, 0, 4), // EOF
677 };
678
679 Initialize(reads, arraysize(reads), writes, arraysize(writes));
680
681 AssertConnectSucceeds();
682
683 Run(2); // SpdySession consumes the next two reads and sends then to
684 // sock_ to be buffered.
685 // The payload from two data frames, each with kMsg3 will be combined
686 // together into a single read().
687 AssertSyncReadEquals(kMsg33, kLen33);
688 }
689
690 TEST_F(SpdyProxyClientSocketTest, MultipleShortReadsThenMoreRead) {
691 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
692 MockWrite writes[] = {
693 CreateMockWrite(*conn, 0, false),
694 };
695
696 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
697 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
698 scoped_ptr<spdy::SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
699 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
700 MockRead reads[] = {
701 CreateMockRead(*resp, 1, false),
702 CreateMockRead(*msg1, 2, false),
703 CreateMockRead(*msg3, 3, false),
704 CreateMockRead(*msg3, 4, false),
705 CreateMockRead(*msg2, 5, false),
706 MockRead(false, 0, 6), // EOF
707 };
708
709 Initialize(reads, arraysize(reads), writes, arraysize(writes));
710
711 AssertConnectSucceeds();
712
713 Run(4); // SpdySession consumes the next four reads and sends then to
714 // sock_ to be buffered.
715 AssertSyncReadEquals(kMsg1, kLen1);
716 // The payload from two data frames, each with kMsg3 will be combined
717 // together into a single read().
718 AssertSyncReadEquals(kMsg33, kLen33);
719 AssertSyncReadEquals(kMsg2, kLen2);
720 }
721
722 TEST_F(SpdyProxyClientSocketTest, ReadWillSplitDataFromLargeFrame) {
723 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
724 MockWrite writes[] = {
725 CreateMockWrite(*conn, 0, false),
726 };
727
728 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
729 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
730 scoped_ptr<spdy::SpdyFrame> msg33(ConstructBodyFrame(kMsg33, kLen33));
731 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
732 MockRead reads[] = {
733 CreateMockRead(*resp, 1, false),
734 CreateMockRead(*msg1, 2, false),
735 CreateMockRead(*msg33, 3, false),
736 MockRead(false, 0, 4), // EOF
737 };
738
739 Initialize(reads, arraysize(reads), writes, arraysize(writes));
740
741 AssertConnectSucceeds();
742
743 Run(2); // SpdySession consumes the next two reads and sends then to
744 // sock_ to be buffered.
745 AssertSyncReadEquals(kMsg1, kLen1);
746 // The payload from the single large data frame will be read across
747 // two different reads.
748 AssertSyncReadEquals(kMsg3, kLen3);
749 AssertSyncReadEquals(kMsg3, kLen3);
750 }
751 TEST_F(SpdyProxyClientSocketTest, ReadAuthResponseBody) {
752 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
753 MockWrite writes[] = {
754 CreateMockWrite(*conn, 0, false),
755 };
756
757 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectAuthReplyFrame());
758 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
759 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
760 MockRead reads[] = {
761 CreateMockRead(*resp, 1, false),
762 CreateMockRead(*msg1, 2, false),
763 CreateMockRead(*msg2, 3, false),
764 MockRead(false, 0, 4), // EOF
765 };
766
767 Initialize(reads, arraysize(reads), writes, arraysize(writes));
768
769 AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
770
771 Run(2); // SpdySession consumes the next two reads and sends then to
772 // sock_ to be buffered.
773 AssertSyncReadEquals(kMsg1, kLen1);
774 AssertSyncReadEquals(kMsg2, kLen2);
775 }
776
777 TEST_F(SpdyProxyClientSocketTest, ReadErrorResponseBody) {
778 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
779 MockWrite writes[] = {
780 CreateMockWrite(*conn, 0, false),
781 };
782
783 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectErrorReplyFrame());
784 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
785 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
786 MockRead reads[] = {
787 CreateMockRead(*resp, 1, false),
788 CreateMockRead(*msg1, 2, false),
789 CreateMockRead(*msg2, 3, false),
790 MockRead(false, 0, 4), // EOF
791 };
792
793 Initialize(reads, arraysize(reads), writes, arraysize(writes));
794
795 AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
796
797 Run(2); // SpdySession consumes the next two reads and sends then to
798 // sock_ to be buffered.
799 AssertSyncReadEquals(kMsg1, kLen1);
800 AssertSyncReadEquals(kMsg2, kLen2);
801 }
802
803 // ----------- Reads and Writes
804
805 TEST_F(SpdyProxyClientSocketTest, AsyncReadAroundWrite) {
806 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
807 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
808 MockWrite writes[] = {
809 CreateMockWrite(*conn, 0, false),
810 CreateMockWrite(*msg2, 3, false),
811 };
812
813 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
814 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
815 scoped_ptr<spdy::SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
816 MockRead reads[] = {
817 CreateMockRead(*resp, 1, false),
818 CreateMockRead(*msg1, 2, false), // sync read
819 CreateMockRead(*msg3, 4, false), // async read
820 MockRead(false, 0, 5), // EOF
821 };
822
823 Initialize(reads, arraysize(reads), writes, arraysize(writes));
824
825 AssertConnectSucceeds();
826
827 Run(1);
828 AssertSyncReadEquals(kMsg1, kLen1);
829
830 AssertReadStarts(kMsg3, kLen3);
831 // Read should block until after the write succeeds
832
833 AssertAsyncWriteSucceeds(kMsg2, kLen2); // Runs 1 step
834
835 ASSERT_FALSE(read_callback_.have_result());
836 Run(1);
837 // Now the read will return
838 AssertReadReturns(kMsg3, kLen3);
839 }
840
841 // TODO(rch): augment DeterministicSocketData to permit the scheduling
842 // of an aync write so that we can test an async write around an
843 // async read.
844
845 // ----------- Reading/Writing on Closed socket
846
847 // Reading from an already closed socket should return 0
848 TEST_F(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsZero) {
849 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
850 MockWrite writes[] = {
851 CreateMockWrite(*conn, 0, false),
852 };
853
854 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
855 MockRead reads[] = {
856 CreateMockRead(*resp, 1, false),
857 MockRead(false, 0, 2), // EOF
858 };
859
860 Initialize(reads, arraysize(reads), writes, arraysize(writes));
861
862 AssertConnectSucceeds();
863
864 sock_->Disconnect();
865
866 ASSERT_EQ(0, sock_->Read(NULL, 1, NULL));
867 ASSERT_EQ(ERR_CONNECTION_CLOSED, sock_->Read(NULL, 1, NULL));
868 ASSERT_EQ(ERR_CONNECTION_CLOSED, sock_->Read(NULL, 1, NULL));
869 }
870
871 // Calling Write() on a closed socket is an error
872 TEST_F(SpdyProxyClientSocketTest, WriteOnClosedStream) {
873 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
874 MockWrite writes[] = {
875 CreateMockWrite(*conn, 0, false),
876 };
877
878 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
879 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
880 MockRead reads[] = {
881 CreateMockRead(*resp, 1, false),
882 MockRead(false, 0, 2), // EOF
883 };
884
885 Initialize(reads, arraysize(reads), writes, arraysize(writes));
886
887 AssertConnectSucceeds();
888
889 Run(1); // Read EOF which will close the stream
890 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
891 EXPECT_EQ(ERR_CONNECTION_CLOSED, sock_->Write(buf, buf->size(), NULL));
892 }
893
894 // ----------- Pending read/write when closed
895
896 // If the socket is closed with a pending Write(), the callback
897 // should not be called.
898 TEST_F(SpdyProxyClientSocketTest, DisconnectWithWritePending) {
899 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
900 MockWrite writes[] = {
901 CreateMockWrite(*conn, 0, false),
902 MockWrite(false, 0, 2), // EOF
903 };
904
905 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
906 MockRead reads[] = {
907 CreateMockRead(*resp, 1),
908 MockRead(false, 0, 3), // EOF
909 };
910
911 Initialize(reads, arraysize(reads), writes, arraysize(writes));
912
913 AssertConnectSucceeds();
914
915 EXPECT_TRUE(sock_->IsConnected());
916
917 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
918 EXPECT_EQ(ERR_IO_PENDING, sock_->Write(buf, buf->size(), &write_callback_));
919
920 sock_->Disconnect();
921
922 EXPECT_FALSE(sock_->IsConnected());
923 EXPECT_FALSE(write_callback_.have_result());
924 }
925
926 // If the socket is closed with a pending Read(), the callback
927 // should not be called.
928 TEST_F(SpdyProxyClientSocketTest, DisconnectWithReadPending) {
929 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
930 MockWrite writes[] = {
931 CreateMockWrite(*conn, 0, false),
932 };
933
934 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
935 MockRead reads[] = {
936 CreateMockRead(*resp, 1, false),
937 MockRead(false, 0, 2), // EOF
938 };
939
940 Initialize(reads, arraysize(reads), writes, arraysize(writes));
941
942 AssertConnectSucceeds();
943
944 EXPECT_TRUE(sock_->IsConnected());
945
946 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
947 ASSERT_EQ(ERR_IO_PENDING, sock_->Read(buf, kLen1, &read_callback_));
948
949 sock_->Disconnect();
950
951 EXPECT_FALSE(sock_->IsConnected());
952 EXPECT_FALSE(read_callback_.have_result());
953 }
954
955 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_proxy_client_socket.cc ('k') | net/spdy/spdy_session.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698