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

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: Tweak SpdySession::IsReused (erf, got mixed in with a rebase) 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
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 idle_(true),
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 void set_idle(bool idle) { idle_ = idle; }
mmenke 2014/03/18 15:16:55 Think it's worth a comment just what this does (Le
davidben 2014/03/25 19:50:18 Done.
125
123 // Socket implementation. 126 // Socket implementation.
124 virtual int Read( 127 virtual int Read(
125 IOBuffer* /* buf */, int len, 128 IOBuffer* /* buf */, int len,
126 const CompletionCallback& /* callback */) OVERRIDE { 129 const CompletionCallback& /* callback */) OVERRIDE {
130 if (!idle_ && len > 0) {
131 idle_ = true;
132 was_used_to_convey_data_ = true;
133 return 1;
134 }
127 return ERR_UNEXPECTED; 135 return ERR_UNEXPECTED;
128 } 136 }
129 137
130 virtual int Write( 138 virtual int Write(
131 IOBuffer* /* buf */, int len, 139 IOBuffer* /* buf */, int len,
132 const CompletionCallback& /* callback */) OVERRIDE { 140 const CompletionCallback& /* callback */) OVERRIDE {
133 was_used_to_convey_data_ = true; 141 was_used_to_convey_data_ = true;
134 return len; 142 return len;
135 } 143 }
136 virtual bool SetReceiveBufferSize(int32 size) OVERRIDE { return true; } 144 virtual bool SetReceiveBufferSize(int32 size) OVERRIDE { return true; }
137 virtual bool SetSendBufferSize(int32 size) OVERRIDE { return true; } 145 virtual bool SetSendBufferSize(int32 size) OVERRIDE { return true; }
138 146
139 // StreamSocket implementation. 147 // StreamSocket implementation.
140 virtual int Connect(const CompletionCallback& callback) OVERRIDE { 148 virtual int Connect(const CompletionCallback& callback) OVERRIDE {
141 connected_ = true; 149 connected_ = true;
142 return OK; 150 return OK;
143 } 151 }
144 152
145 virtual void Disconnect() OVERRIDE { connected_ = false; } 153 virtual void Disconnect() OVERRIDE { connected_ = false; }
146 virtual bool IsConnected() const OVERRIDE { return connected_; } 154 virtual bool IsConnected() const OVERRIDE { return connected_; }
147 virtual bool IsConnectedAndIdle() const OVERRIDE { return connected_; } 155 virtual bool IsConnectedAndIdle() const OVERRIDE {
156 return connected_ && idle_;
157 }
148 158
149 virtual int GetPeerAddress(IPEndPoint* /* address */) const OVERRIDE { 159 virtual int GetPeerAddress(IPEndPoint* /* address */) const OVERRIDE {
150 return ERR_UNEXPECTED; 160 return ERR_UNEXPECTED;
151 } 161 }
152 162
153 virtual int GetLocalAddress(IPEndPoint* /* address */) const OVERRIDE { 163 virtual int GetLocalAddress(IPEndPoint* /* address */) const OVERRIDE {
154 return ERR_UNEXPECTED; 164 return ERR_UNEXPECTED;
155 } 165 }
156 166
157 virtual const BoundNetLog& NetLog() const OVERRIDE { 167 virtual const BoundNetLog& NetLog() const OVERRIDE {
(...skipping 11 matching lines...) Expand all
169 } 179 }
170 virtual NextProto GetNegotiatedProtocol() const OVERRIDE { 180 virtual NextProto GetNegotiatedProtocol() const OVERRIDE {
171 return kProtoUnknown; 181 return kProtoUnknown;
172 } 182 }
173 virtual bool GetSSLInfo(SSLInfo* ssl_info) OVERRIDE { 183 virtual bool GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {
174 return false; 184 return false;
175 } 185 }
176 186
177 private: 187 private:
178 bool connected_; 188 bool connected_;
189 bool idle_;
179 BoundNetLog net_log_; 190 BoundNetLog net_log_;
180 bool was_used_to_convey_data_; 191 bool was_used_to_convey_data_;
181 192
182 DISALLOW_COPY_AND_ASSIGN(MockClientSocket); 193 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
183 }; 194 };
184 195
185 class TestConnectJob; 196 class TestConnectJob;
186 197
187 class MockClientSocketFactory : public ClientSocketFactory { 198 class MockClientSocketFactory : public ClientSocketFactory {
188 public: 199 public:
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 enum JobType { 249 enum JobType {
239 kMockJob, 250 kMockJob,
240 kMockFailingJob, 251 kMockFailingJob,
241 kMockPendingJob, 252 kMockPendingJob,
242 kMockPendingFailingJob, 253 kMockPendingFailingJob,
243 kMockWaitingJob, 254 kMockWaitingJob,
244 kMockRecoverableJob, 255 kMockRecoverableJob,
245 kMockPendingRecoverableJob, 256 kMockPendingRecoverableJob,
246 kMockAdditionalErrorStateJob, 257 kMockAdditionalErrorStateJob,
247 kMockPendingAdditionalErrorStateJob, 258 kMockPendingAdditionalErrorStateJob,
259 kMockUnreadDataJob,
248 }; 260 };
249 261
250 // The kMockPendingJob uses a slight delay before allowing the connect 262 // The kMockPendingJob uses a slight delay before allowing the connect
251 // to complete. 263 // to complete.
252 static const int kPendingConnectDelay = 2; 264 static const int kPendingConnectDelay = 2;
253 265
254 TestConnectJob(JobType job_type, 266 TestConnectJob(JobType job_type,
255 const std::string& group_name, 267 const std::string& group_name,
256 const TestClientSocketPoolBase::Request& request, 268 const TestClientSocketPoolBase::Request& request,
257 base::TimeDelta timeout_duration, 269 base::TimeDelta timeout_duration,
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 store_additional_error_state_ = true; 377 store_additional_error_state_ = true;
366 base::MessageLoop::current()->PostDelayedTask( 378 base::MessageLoop::current()->PostDelayedTask(
367 FROM_HERE, 379 FROM_HERE,
368 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect), 380 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
369 weak_factory_.GetWeakPtr(), 381 weak_factory_.GetWeakPtr(),
370 false /* error */, 382 false /* error */,
371 true /* async */, 383 true /* async */,
372 false /* recoverable */), 384 false /* recoverable */),
373 base::TimeDelta::FromMilliseconds(2)); 385 base::TimeDelta::FromMilliseconds(2));
374 return ERR_IO_PENDING; 386 return ERR_IO_PENDING;
387 case kMockUnreadDataJob: {
388 int ret = DoConnect(true /* successful */, false /* sync */,
389 false /* recoverable */);
390 static_cast<MockClientSocket*>(socket())->set_idle(false);
mmenke 2014/03/18 15:16:55 Can we just store the socket as a local and avoid
391 return ret;
392 }
375 default: 393 default:
376 NOTREACHED(); 394 NOTREACHED();
377 SetSocket(scoped_ptr<StreamSocket>()); 395 SetSocket(scoped_ptr<StreamSocket>());
378 return ERR_FAILED; 396 return ERR_FAILED;
379 } 397 }
380 } 398 }
381 399
382 int DoConnect(bool succeed, bool was_async, bool recoverable) { 400 int DoConnect(bool succeed, bool was_async, bool recoverable) {
383 int result = OK; 401 int result = OK;
384 if (succeed) { 402 if (succeed) {
(...skipping 3149 matching lines...) Expand 10 before | Expand all | Expand 10 after
3534 callback1.callback(), 3552 callback1.callback(),
3535 pool_.get(), 3553 pool_.get(),
3536 BoundNetLog())); 3554 BoundNetLog()));
3537 3555
3538 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a")); 3556 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3539 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a")); 3557 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3540 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a")); 3558 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3541 3559
3542 ASSERT_EQ(OK, callback1.WaitForResult()); 3560 ASSERT_EQ(OK, callback1.WaitForResult());
3543 3561
3544 // Make sure if a preconneced socket is not fully connected when a request 3562 // Make sure if a preconnected socket is not fully connected when a request
3545 // starts, it has a connect start time. 3563 // starts, it has a connect start time.
3546 TestLoadTimingInfoConnectedNotReused(handle1); 3564 TestLoadTimingInfoConnectedNotReused(handle1);
3547 handle1.Reset(); 3565 handle1.Reset();
3548 3566
3549 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a")); 3567 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3550 } 3568 }
3551 3569
3552 // Checks that fully connected preconnect jobs have no connect times, and are 3570 // Checks that fully connected preconnect jobs have no connect times, and are
3553 // marked as reused. 3571 // marked as reused.
3554 TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) { 3572 TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
3713 ASSERT_EQ(OK, callback.WaitForResult()); 3731 ASSERT_EQ(OK, callback.WaitForResult());
3714 3732
3715 // The hung connect job should still be there, but everything else should be 3733 // The hung connect job should still be there, but everything else should be
3716 // complete. 3734 // complete.
3717 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a")); 3735 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3718 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a")); 3736 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3719 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a")); 3737 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3720 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a")); 3738 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3721 } 3739 }
3722 3740
3741 // Tests that a preconnect that starts out with unread data can still be used.
3742 // http://crbug.com/334467
mmenke 2014/03/18 15:16:55 Suggest a test where a reused socket with unread d
3743 TEST_F(ClientSocketPoolBaseTest, PreconnectWithUnreadData) {
3744 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3745 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
3746
3747 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3748
3749 ASSERT_TRUE(pool_->HasGroup("a"));
3750 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3751 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3752 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3753
3754 // Fail future jobs to be sure that handle receives the preconnected socket
3755 // rather than closing it and making a new one.
3756 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3757 ClientSocketHandle handle;
3758 TestCompletionCallback callback;
3759 EXPECT_EQ(OK, handle.Init("a",
3760 params_,
3761 DEFAULT_PRIORITY,
3762 callback.callback(),
3763 pool_.get(),
3764 BoundNetLog()));
3765
3766 ASSERT_TRUE(pool_->HasGroup("a"));
3767 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3768 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3769 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3770
3771 // Drain the pending read.
3772 EXPECT_EQ(1, handle.socket()->Read(NULL, 1, CompletionCallback()));
3773
3774 TestLoadTimingInfoConnectedReused(handle);
3775 handle.Reset();
3776
3777 // The socket should be usable now that it's idle again.
3778 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3779 }
3780
3723 class MockLayeredPool : public HigherLayeredPool { 3781 class MockLayeredPool : public HigherLayeredPool {
3724 public: 3782 public:
3725 MockLayeredPool(TestClientSocketPool* pool, 3783 MockLayeredPool(TestClientSocketPool* pool,
3726 const std::string& group_name) 3784 const std::string& group_name)
3727 : pool_(pool), 3785 : pool_(pool),
3728 group_name_(group_name), 3786 group_name_(group_name),
3729 can_release_connection_(true) { 3787 can_release_connection_(true) {
3730 pool_->AddHigherLayeredPool(this); 3788 pool_->AddHigherLayeredPool(this);
3731 } 3789 }
3732 3790
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
4058 request(1)->handle()->Reset(); 4116 request(1)->handle()->Reset();
4059 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a")); 4117 ASSERT_EQ(1, pool_->NumConnectJobsInGroup("a"));
4060 4118
4061 EXPECT_EQ(OK, request(2)->WaitForResult()); 4119 EXPECT_EQ(OK, request(2)->WaitForResult());
4062 EXPECT_FALSE(request(1)->have_result()); 4120 EXPECT_FALSE(request(1)->have_result());
4063 } 4121 }
4064 4122
4065 } // namespace 4123 } // namespace
4066 4124
4067 } // namespace net 4125 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698