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

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

Issue 169643006: Use sockets with unread data if they've never been used before. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: mmenke comments Created 6 years, 9 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/socket/client_socket_pool_base.cc ('k') | net/socket/socks5_client_socket.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/socket/client_socket_pool_base.h" 5 #include "net/socket/client_socket_pool_base.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 ~TestSocketParams() {} 109 ~TestSocketParams() {}
110 110
111 const bool ignore_limits_; 111 const bool ignore_limits_;
112 }; 112 };
113 typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase; 113 typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
114 114
115 class MockClientSocket : public StreamSocket { 115 class MockClientSocket : public StreamSocket {
116 public: 116 public:
117 explicit MockClientSocket(net::NetLog* net_log) 117 explicit MockClientSocket(net::NetLog* net_log)
118 : connected_(false), 118 : connected_(false),
119 has_unread_data_(false),
119 net_log_(BoundNetLog::Make(net_log, net::NetLog::SOURCE_SOCKET)), 120 net_log_(BoundNetLog::Make(net_log, net::NetLog::SOURCE_SOCKET)),
120 was_used_to_convey_data_(false) { 121 was_used_to_convey_data_(false) {
121 } 122 }
122 123
124 // Sets whether the socket has unread data. If true, the next call to Read()
125 // will return 1 byte and IsConnectedAndIdle() will return false.
126 void set_has_unread_data(bool has_unread_data) {
127 has_unread_data_ = has_unread_data;
128 }
129
123 // Socket implementation. 130 // Socket implementation.
124 virtual int Read( 131 virtual int Read(
125 IOBuffer* /* buf */, int len, 132 IOBuffer* /* buf */, int len,
126 const CompletionCallback& /* callback */) OVERRIDE { 133 const CompletionCallback& /* callback */) OVERRIDE {
134 if (has_unread_data_ && len > 0) {
135 has_unread_data_ = false;
136 was_used_to_convey_data_ = true;
137 return 1;
138 }
127 return ERR_UNEXPECTED; 139 return ERR_UNEXPECTED;
128 } 140 }
129 141
130 virtual int Write( 142 virtual int Write(
131 IOBuffer* /* buf */, int len, 143 IOBuffer* /* buf */, int len,
132 const CompletionCallback& /* callback */) OVERRIDE { 144 const CompletionCallback& /* callback */) OVERRIDE {
133 was_used_to_convey_data_ = true; 145 was_used_to_convey_data_ = true;
134 return len; 146 return len;
135 } 147 }
136 virtual bool SetReceiveBufferSize(int32 size) OVERRIDE { return true; } 148 virtual bool SetReceiveBufferSize(int32 size) OVERRIDE { return true; }
137 virtual bool SetSendBufferSize(int32 size) OVERRIDE { return true; } 149 virtual bool SetSendBufferSize(int32 size) OVERRIDE { return true; }
138 150
139 // StreamSocket implementation. 151 // StreamSocket implementation.
140 virtual int Connect(const CompletionCallback& callback) OVERRIDE { 152 virtual int Connect(const CompletionCallback& callback) OVERRIDE {
141 connected_ = true; 153 connected_ = true;
142 return OK; 154 return OK;
143 } 155 }
144 156
145 virtual void Disconnect() OVERRIDE { connected_ = false; } 157 virtual void Disconnect() OVERRIDE { connected_ = false; }
146 virtual bool IsConnected() const OVERRIDE { return connected_; } 158 virtual bool IsConnected() const OVERRIDE { return connected_; }
147 virtual bool IsConnectedAndIdle() const OVERRIDE { return connected_; } 159 virtual bool IsConnectedAndIdle() const OVERRIDE {
160 return connected_ && !has_unread_data_;
161 }
148 162
149 virtual int GetPeerAddress(IPEndPoint* /* address */) const OVERRIDE { 163 virtual int GetPeerAddress(IPEndPoint* /* address */) const OVERRIDE {
150 return ERR_UNEXPECTED; 164 return ERR_UNEXPECTED;
151 } 165 }
152 166
153 virtual int GetLocalAddress(IPEndPoint* /* address */) const OVERRIDE { 167 virtual int GetLocalAddress(IPEndPoint* /* address */) const OVERRIDE {
154 return ERR_UNEXPECTED; 168 return ERR_UNEXPECTED;
155 } 169 }
156 170
157 virtual const BoundNetLog& NetLog() const OVERRIDE { 171 virtual const BoundNetLog& NetLog() const OVERRIDE {
(...skipping 11 matching lines...) Expand all
169 } 183 }
170 virtual NextProto GetNegotiatedProtocol() const OVERRIDE { 184 virtual NextProto GetNegotiatedProtocol() const OVERRIDE {
171 return kProtoUnknown; 185 return kProtoUnknown;
172 } 186 }
173 virtual bool GetSSLInfo(SSLInfo* ssl_info) OVERRIDE { 187 virtual bool GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {
174 return false; 188 return false;
175 } 189 }
176 190
177 private: 191 private:
178 bool connected_; 192 bool connected_;
193 bool has_unread_data_;
179 BoundNetLog net_log_; 194 BoundNetLog net_log_;
180 bool was_used_to_convey_data_; 195 bool was_used_to_convey_data_;
181 196
182 DISALLOW_COPY_AND_ASSIGN(MockClientSocket); 197 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
183 }; 198 };
184 199
185 class TestConnectJob; 200 class TestConnectJob;
186 201
187 class MockClientSocketFactory : public ClientSocketFactory { 202 class MockClientSocketFactory : public ClientSocketFactory {
188 public: 203 public:
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 enum JobType { 253 enum JobType {
239 kMockJob, 254 kMockJob,
240 kMockFailingJob, 255 kMockFailingJob,
241 kMockPendingJob, 256 kMockPendingJob,
242 kMockPendingFailingJob, 257 kMockPendingFailingJob,
243 kMockWaitingJob, 258 kMockWaitingJob,
244 kMockRecoverableJob, 259 kMockRecoverableJob,
245 kMockPendingRecoverableJob, 260 kMockPendingRecoverableJob,
246 kMockAdditionalErrorStateJob, 261 kMockAdditionalErrorStateJob,
247 kMockPendingAdditionalErrorStateJob, 262 kMockPendingAdditionalErrorStateJob,
263 kMockUnreadDataJob,
248 }; 264 };
249 265
250 // The kMockPendingJob uses a slight delay before allowing the connect 266 // The kMockPendingJob uses a slight delay before allowing the connect
251 // to complete. 267 // to complete.
252 static const int kPendingConnectDelay = 2; 268 static const int kPendingConnectDelay = 2;
253 269
254 TestConnectJob(JobType job_type, 270 TestConnectJob(JobType job_type,
255 const std::string& group_name, 271 const std::string& group_name,
256 const TestClientSocketPoolBase::Request& request, 272 const TestClientSocketPoolBase::Request& request,
257 base::TimeDelta timeout_duration, 273 base::TimeDelta timeout_duration,
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 store_additional_error_state_ = true; 381 store_additional_error_state_ = true;
366 base::MessageLoop::current()->PostDelayedTask( 382 base::MessageLoop::current()->PostDelayedTask(
367 FROM_HERE, 383 FROM_HERE,
368 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect), 384 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
369 weak_factory_.GetWeakPtr(), 385 weak_factory_.GetWeakPtr(),
370 false /* error */, 386 false /* error */,
371 true /* async */, 387 true /* async */,
372 false /* recoverable */), 388 false /* recoverable */),
373 base::TimeDelta::FromMilliseconds(2)); 389 base::TimeDelta::FromMilliseconds(2));
374 return ERR_IO_PENDING; 390 return ERR_IO_PENDING;
391 case kMockUnreadDataJob: {
392 int ret = DoConnect(true /* successful */, false /* sync */,
393 false /* recoverable */);
394 static_cast<MockClientSocket*>(socket())->set_has_unread_data(true);
395 return ret;
396 }
375 default: 397 default:
376 NOTREACHED(); 398 NOTREACHED();
377 SetSocket(scoped_ptr<StreamSocket>()); 399 SetSocket(scoped_ptr<StreamSocket>());
378 return ERR_FAILED; 400 return ERR_FAILED;
379 } 401 }
380 } 402 }
381 403
382 int DoConnect(bool succeed, bool was_async, bool recoverable) { 404 int DoConnect(bool succeed, bool was_async, bool recoverable) {
383 int result = OK; 405 int result = OK;
384 if (succeed) { 406 if (succeed) {
(...skipping 3149 matching lines...) Expand 10 before | Expand all | Expand 10 after
3534 callback1.callback(), 3556 callback1.callback(),
3535 pool_.get(), 3557 pool_.get(),
3536 BoundNetLog())); 3558 BoundNetLog()));
3537 3559
3538 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a")); 3560 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3539 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a")); 3561 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3540 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a")); 3562 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3541 3563
3542 ASSERT_EQ(OK, callback1.WaitForResult()); 3564 ASSERT_EQ(OK, callback1.WaitForResult());
3543 3565
3544 // Make sure if a preconneced socket is not fully connected when a request 3566 // Make sure if a preconnected socket is not fully connected when a request
3545 // starts, it has a connect start time. 3567 // starts, it has a connect start time.
3546 TestLoadTimingInfoConnectedNotReused(handle1); 3568 TestLoadTimingInfoConnectedNotReused(handle1);
3547 handle1.Reset(); 3569 handle1.Reset();
3548 3570
3549 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a")); 3571 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3550 } 3572 }
3551 3573
3552 // Checks that fully connected preconnect jobs have no connect times, and are 3574 // Checks that fully connected preconnect jobs have no connect times, and are
3553 // marked as reused. 3575 // marked as reused.
3554 TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) { 3576 TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
3713 ASSERT_EQ(OK, callback.WaitForResult()); 3735 ASSERT_EQ(OK, callback.WaitForResult());
3714 3736
3715 // The hung connect job should still be there, but everything else should be 3737 // The hung connect job should still be there, but everything else should be
3716 // complete. 3738 // complete.
3717 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a")); 3739 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3718 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a")); 3740 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3719 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a")); 3741 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3720 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a")); 3742 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3721 } 3743 }
3722 3744
3745 // Tests that a preconnect that starts out with unread data can still be used.
3746 // http://crbug.com/334467
3747 TEST_F(ClientSocketPoolBaseTest, PreconnectWithUnreadData) {
3748 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3749 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
3750
3751 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3752
3753 ASSERT_TRUE(pool_->HasGroup("a"));
3754 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3755 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3756 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3757
3758 // Fail future jobs to be sure that handle receives the preconnected socket
3759 // rather than closing it and making a new one.
3760 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3761 ClientSocketHandle handle;
3762 TestCompletionCallback callback;
3763 EXPECT_EQ(OK, handle.Init("a",
3764 params_,
3765 DEFAULT_PRIORITY,
3766 callback.callback(),
3767 pool_.get(),
3768 BoundNetLog()));
3769
3770 ASSERT_TRUE(pool_->HasGroup("a"));
3771 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3772 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3773 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3774
3775 // Drain the pending read.
3776 EXPECT_EQ(1, handle.socket()->Read(NULL, 1, CompletionCallback()));
3777
3778 TestLoadTimingInfoConnectedReused(handle);
3779 handle.Reset();
3780
3781 // The socket should be usable now that it's idle again.
3782 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3783 }
3784
3723 class MockLayeredPool : public HigherLayeredPool { 3785 class MockLayeredPool : public HigherLayeredPool {
3724 public: 3786 public:
3725 MockLayeredPool(TestClientSocketPool* pool, 3787 MockLayeredPool(TestClientSocketPool* pool,
3726 const std::string& group_name) 3788 const std::string& group_name)
3727 : pool_(pool), 3789 : pool_(pool),
3728 group_name_(group_name), 3790 group_name_(group_name),
3729 can_release_connection_(true) { 3791 can_release_connection_(true) {
3730 pool_->AddHigherLayeredPool(this); 3792 pool_->AddHigherLayeredPool(this);
3731 } 3793 }
3732 3794
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
4058 request(1)->handle()->Reset(); 4120 request(1)->handle()->Reset();
4059 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a")); 4121 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4060 4122
4061 EXPECT_EQ(OK, request(2)->WaitForResult()); 4123 EXPECT_EQ(OK, request(2)->WaitForResult());
4062 EXPECT_FALSE(request(1)->have_result()); 4124 EXPECT_FALSE(request(1)->have_result());
4063 } 4125 }
4064 4126
4065 } // namespace 4127 } // namespace
4066 4128
4067 } // namespace net 4129 } // namespace net
OLDNEW
« no previous file with comments | « net/socket/client_socket_pool_base.cc ('k') | net/socket/socks5_client_socket.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698