summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-23 22:11:17 +0000
committerphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-23 22:11:17 +0000
commit75439d3bd966a7df4cf8d2a17984cf35e928d181 (patch)
tree976e6cf1d131867e7daf013077cde624ece5d078 /net
parentd6cb85b66439333ea65dfb26d745c8c8d0049aac (diff)
downloadchromium_src-75439d3bd966a7df4cf8d2a17984cf35e928d181.zip
chromium_src-75439d3bd966a7df4cf8d2a17984cf35e928d181.tar.gz
chromium_src-75439d3bd966a7df4cf8d2a17984cf35e928d181.tar.bz2
Refactoring in socket pool unittests:
- share more code - improve readability - help detect cases we don't test order of all requests made TEST=Covered by net_unittests. http://crbug.com/17445 Review URL: http://codereview.chromium.org/155925 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@21456 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/socket/client_socket_pool_base_unittest.cc236
-rw-r--r--net/socket/socket_test_util.cc74
-rw-r--r--net/socket/socket_test_util.h69
-rw-r--r--net/socket/tcp_client_socket_pool_unittest.cc387
4 files changed, 376 insertions, 390 deletions
diff --git a/net/socket/client_socket_pool_base_unittest.cc b/net/socket/client_socket_pool_base_unittest.cc
index f5ad77e..0d6e3d5 100644
--- a/net/socket/client_socket_pool_base_unittest.cc
+++ b/net/socket/client_socket_pool_base_unittest.cc
@@ -12,6 +12,7 @@
#include "net/socket/client_socket.h"
#include "net/socket/client_socket_factory.h"
#include "net/socket/client_socket_handle.h"
+#include "net/socket/socket_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -92,34 +93,6 @@ class MockClientSocketFactory : public ClientSocketFactory {
std::vector<TestConnectJob*> waiting_jobs_;
};
-class TestSocketRequest : public CallbackRunner< Tuple1<int> > {
- public:
- TestSocketRequest(
- ClientSocketPool* pool,
- std::vector<TestSocketRequest*>* request_order)
- : handle(pool), request_order_(request_order) {}
-
- ClientSocketHandle handle;
-
- int WaitForResult() {
- return callback_.WaitForResult();
- }
-
- virtual void RunWithParams(const Tuple1<int>& params) {
- callback_.RunWithParams(params);
- completion_count++;
- request_order_->push_back(this);
- }
-
- static size_t completion_count;
-
- private:
- std::vector<TestSocketRequest*>* request_order_;
- TestCompletionCallback callback_;
-};
-
-size_t TestSocketRequest::completion_count = 0;
-
class TestConnectJob : public ConnectJob {
public:
enum JobType {
@@ -316,11 +289,10 @@ void MockClientSocketFactory::SignalJobs() {
waiting_jobs_.clear();
}
-class ClientSocketPoolBaseTest : public testing::Test {
+class ClientSocketPoolBaseTest : public ClientSocketPoolTest {
protected:
ClientSocketPoolBaseTest()
- : ignored_request_info_("ignored", 80),
- connect_job_factory_(
+ : connect_job_factory_(
new TestConnectJobFactory(&client_socket_factory_)) {}
void CreatePool(int max_sockets, int max_sockets_per_group) {
@@ -330,15 +302,11 @@ class ClientSocketPoolBaseTest : public testing::Test {
connect_job_factory_);
}
- virtual void SetUp() {
- TestSocketRequest::completion_count = 0;
+ int StartRequest(const std::string& group_name, int priority) {
+ return StartRequestUsingPool(pool_.get(), group_name, priority);
}
virtual void TearDown() {
- // The tests often call Reset() on handles at the end which may post
- // DoReleaseSocket() tasks.
- MessageLoop::current()->RunAllPending();
-
// Need to delete |pool_| before we turn late binding back off. We also need
// to delete |requests_| because the pool is reference counted and requests
// keep reference to it.
@@ -347,75 +315,15 @@ class ClientSocketPoolBaseTest : public testing::Test {
requests_.reset();
ClientSocketPoolBase::EnableLateBindingOfSockets(false);
- }
- int StartRequest(const std::string& group_name, int priority) {
- DCHECK(pool_.get());
- TestSocketRequest* request = new TestSocketRequest(pool_.get(),
- &request_order_);
- requests_.push_back(request);
- int rv = request->handle.Init(group_name, ignored_request_info_, priority,
- request);
- if (rv != ERR_IO_PENDING)
- request_order_.push_back(request);
- return rv;
+ ClientSocketPoolTest::TearDown();
}
- static const int kIndexOutOfBounds;
- static const int kRequestNotFound;
-
- int GetOrderOfRequest(size_t index) {
- index--;
- if (index >= requests_.size())
- return kIndexOutOfBounds;
-
- for (size_t i = 0; i < request_order_.size(); i++)
- if (requests_[index] == request_order_[i])
- return i + 1;
-
- return kRequestNotFound;
- }
-
- enum KeepAlive {
- KEEP_ALIVE,
- NO_KEEP_ALIVE,
- };
-
- bool ReleaseOneConnection(KeepAlive keep_alive) {
- ScopedVector<TestSocketRequest>::iterator i;
- for (i = requests_.begin(); i != requests_.end(); ++i) {
- if ((*i)->handle.is_initialized()) {
- if (keep_alive == NO_KEEP_ALIVE)
- (*i)->handle.socket()->Disconnect();
- (*i)->handle.Reset();
- MessageLoop::current()->RunAllPending();
- return true;
- }
- }
- return false;
- }
-
- void ReleaseAllConnections(KeepAlive keep_alive) {
- bool released_one;
- do {
- released_one = ReleaseOneConnection(keep_alive);
- } while (released_one);
- }
-
- HostResolver::RequestInfo ignored_request_info_;
MockClientSocketFactory client_socket_factory_;
TestConnectJobFactory* const connect_job_factory_;
scoped_refptr<TestClientSocketPool> pool_;
- ScopedVector<TestSocketRequest> requests_;
- std::vector<TestSocketRequest*> request_order_;
};
-// static
-const int ClientSocketPoolBaseTest::kIndexOutOfBounds = -1;
-
-// static
-const int ClientSocketPoolBaseTest::kRequestNotFound = -2;
-
TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
@@ -432,7 +340,7 @@ TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
- TestSocketRequest req(pool_.get(), &request_order_);
+ TestSocketRequest req(pool_.get(), &request_order_, &completion_count_);
int rv = req.handle.Init("a", ignored_request_info_, 0, &req);
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &req.handle));
@@ -446,7 +354,7 @@ TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
- TestSocketRequest req(pool_.get(), &request_order_);
+ TestSocketRequest req(pool_.get(), &request_order_, &completion_count_);
EXPECT_EQ(ERR_CONNECTION_FAILED,
req.handle.Init("a", ignored_request_info_,
kDefaultPriority, &req));
@@ -456,7 +364,7 @@ TEST_F(ClientSocketPoolBaseTest, InitConnectionAsynchronousFailure) {
CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
- TestSocketRequest req(pool_.get(), &request_order_);
+ TestSocketRequest req(pool_.get(), &request_order_, &completion_count_);
EXPECT_EQ(ERR_IO_PENDING,
req.handle.Init("a", ignored_request_info_, 5, &req));
EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &req.handle));
@@ -473,8 +381,7 @@ TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
EXPECT_EQ(static_cast<int>(requests_.size()),
client_socket_factory_.allocation_count());
- EXPECT_EQ(requests_.size() - kDefaultMaxSockets,
- TestSocketRequest::completion_count);
+ EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
@@ -484,8 +391,7 @@ TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
EXPECT_EQ(static_cast<int>(requests_.size()),
client_socket_factory_.allocation_count());
- EXPECT_EQ(requests_.size() - kDefaultMaxSockets,
- TestSocketRequest::completion_count);
+ EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
EXPECT_EQ(1, GetOrderOfRequest(1));
EXPECT_EQ(2, GetOrderOfRequest(2));
@@ -494,6 +400,9 @@ TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
EXPECT_EQ(5, GetOrderOfRequest(5));
EXPECT_EQ(6, GetOrderOfRequest(6));
EXPECT_EQ(7, GetOrderOfRequest(7));
+
+ // Make sure we test order of all requests made.
+ EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
}
TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
@@ -507,8 +416,7 @@ TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
EXPECT_EQ(static_cast<int>(requests_.size()),
client_socket_factory_.allocation_count());
- EXPECT_EQ(requests_.size() - kDefaultMaxSockets,
- TestSocketRequest::completion_count);
+ EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
// Now create a new group and verify that we don't starve it.
EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
@@ -517,14 +425,16 @@ TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
EXPECT_EQ(static_cast<int>(requests_.size()),
client_socket_factory_.allocation_count());
- EXPECT_EQ(requests_.size() - kDefaultMaxSockets,
- TestSocketRequest::completion_count);
+ EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
EXPECT_EQ(1, GetOrderOfRequest(1));
EXPECT_EQ(2, GetOrderOfRequest(2));
EXPECT_EQ(3, GetOrderOfRequest(3));
EXPECT_EQ(4, GetOrderOfRequest(4));
EXPECT_EQ(5, GetOrderOfRequest(5));
+
+ // Make sure we test order of all requests made.
+ EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
}
TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
@@ -547,8 +457,7 @@ TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
// We're re-using one socket for group "a", and one for "b".
EXPECT_EQ(static_cast<int>(requests_.size()) - 2,
client_socket_factory_.allocation_count());
- EXPECT_EQ(requests_.size() - kDefaultMaxSockets,
- TestSocketRequest::completion_count);
+ EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
// First 4 requests don't have to wait, and finish in order.
EXPECT_EQ(1, GetOrderOfRequest(1));
@@ -561,6 +470,9 @@ TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
EXPECT_EQ(7, GetOrderOfRequest(5));
EXPECT_EQ(6, GetOrderOfRequest(6));
EXPECT_EQ(5, GetOrderOfRequest(7));
+
+ // Make sure we test order of all requests made.
+ EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
}
TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
@@ -583,8 +495,7 @@ TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
// We're re-using one socket for group "a", and one for "b".
EXPECT_EQ(static_cast<int>(requests_.size()) - 2,
client_socket_factory_.allocation_count());
- EXPECT_EQ(requests_.size() - kDefaultMaxSockets,
- TestSocketRequest::completion_count);
+ EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
// First 4 requests don't have to wait, and finish in order.
EXPECT_EQ(1, GetOrderOfRequest(1));
@@ -599,6 +510,9 @@ TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
EXPECT_EQ(5, GetOrderOfRequest(5));
EXPECT_EQ(6, GetOrderOfRequest(6));
EXPECT_EQ(7, GetOrderOfRequest(7));
+
+ // Make sure we test order of all requests made.
+ EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
}
// Make sure that we count connecting sockets against the total limit.
@@ -626,6 +540,10 @@ TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
EXPECT_EQ(2, GetOrderOfRequest(2));
EXPECT_EQ(3, GetOrderOfRequest(3));
EXPECT_EQ(4, GetOrderOfRequest(4));
+ EXPECT_EQ(5, GetOrderOfRequest(5));
+
+ // Make sure we test order of all requests made.
+ EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
}
// Inside ClientSocketPoolBase we have a may_have_stalled_group flag,
@@ -695,8 +613,7 @@ TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
EXPECT_EQ(kDefaultMaxSocketsPerGroup,
client_socket_factory_.allocation_count());
- EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup,
- TestSocketRequest::completion_count);
+ EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
EXPECT_EQ(1, GetOrderOfRequest(1));
EXPECT_EQ(2, GetOrderOfRequest(2));
@@ -705,6 +622,9 @@ TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
EXPECT_EQ(3, GetOrderOfRequest(5));
EXPECT_EQ(5, GetOrderOfRequest(6));
EXPECT_EQ(7, GetOrderOfRequest(7));
+
+ // Make sure we test order of all requests made.
+ EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
}
TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
@@ -725,8 +645,7 @@ TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
EXPECT_EQ(static_cast<int>(requests_.size()),
client_socket_factory_.allocation_count());
- EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup,
- TestSocketRequest::completion_count);
+ EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
}
// This test will start up a RequestSocket() and then immediately Cancel() it.
@@ -736,7 +655,7 @@ TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
- TestSocketRequest req(pool_.get(), &request_order_);
+ TestSocketRequest req(pool_.get(), &request_order_, &completion_count_);
EXPECT_EQ(ERR_IO_PENDING,
req.handle.Init("a", ignored_request_info_,
kDefaultPriority, &req));
@@ -747,8 +666,8 @@ TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
- TestSocketRequest req(pool_.get(), &request_order_);
- TestSocketRequest req2(pool_.get(), &request_order_);
+ TestSocketRequest req(pool_.get(), &request_order_, &completion_count_);
+ TestSocketRequest req2(pool_.get(), &request_order_, &completion_count_);
EXPECT_EQ(ERR_IO_PENDING,
req.handle.Init("a", ignored_request_info_,
@@ -769,7 +688,7 @@ TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
ClientSocketHandle handle(pool_.get());
TestCompletionCallback callback;
- TestSocketRequest req(pool_.get(), &request_order_);
+ TestSocketRequest req(pool_.get(), &request_order_, &completion_count_);
EXPECT_EQ(ERR_IO_PENDING,
handle.Init("a", ignored_request_info_,
@@ -809,7 +728,7 @@ TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
EXPECT_EQ(kDefaultMaxSocketsPerGroup,
client_socket_factory_.allocation_count());
EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
- TestSocketRequest::completion_count);
+ completion_count_);
EXPECT_EQ(1, GetOrderOfRequest(1));
EXPECT_EQ(2, GetOrderOfRequest(2));
@@ -818,6 +737,9 @@ TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
EXPECT_EQ(4, GetOrderOfRequest(6));
EXPECT_EQ(6, GetOrderOfRequest(7));
+
+ // Make sure we test order of all requests made.
+ EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
}
class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
@@ -925,8 +847,7 @@ TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
requests_[i]->handle.Reset();
}
- EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup,
- TestSocketRequest::completion_count);
+ EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
}
// Make sure that pending requests get serviced after active requests fail.
@@ -952,7 +873,7 @@ TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
- TestSocketRequest req(pool_.get(), &request_order_);
+ TestSocketRequest req(pool_.get(), &request_order_, &completion_count_);
int rv = req.handle.Init(
"a", ignored_request_info_, kDefaultPriority, &req);
EXPECT_EQ(ERR_IO_PENDING, rv);
@@ -965,7 +886,7 @@ TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
EXPECT_EQ(OK, req.WaitForResult());
EXPECT_FALSE(req.handle.is_reused());
- EXPECT_EQ(1U, TestSocketRequest::completion_count);
+ EXPECT_EQ(1U, completion_count_);
EXPECT_EQ(2, client_socket_factory_.allocation_count());
}
@@ -979,13 +900,13 @@ TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
// Start job 1 (async error).
- TestSocketRequest req1(pool_.get(), &request_order_);
+ TestSocketRequest req1(pool_.get(), &request_order_, &completion_count_);
int rv = req1.handle.Init("a", ignored_request_info_,
kDefaultPriority, &req1);
EXPECT_EQ(ERR_IO_PENDING, rv);
// Start job 2 (async error).
- TestSocketRequest req2(pool_.get(), &request_order_);
+ TestSocketRequest req2(pool_.get(), &request_order_, &completion_count_);
rv = req2.handle.Init("a", ignored_request_info_, kDefaultPriority, &req2);
EXPECT_EQ(ERR_IO_PENDING, rv);
@@ -993,7 +914,7 @@ TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
// Request 3 does not have a ConnectJob yet. It's just pending.
- TestSocketRequest req3(pool_.get(), &request_order_);
+ TestSocketRequest req3(pool_.get(), &request_order_, &completion_count_);
rv = req3.handle.Init("a", ignored_request_info_, kDefaultPriority, &req3);
EXPECT_EQ(ERR_IO_PENDING, rv);
@@ -1020,7 +941,7 @@ TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
// Start job 1 (async OK)
connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
- TestSocketRequest req1(pool_.get(), &request_order_);
+ TestSocketRequest req1(pool_.get(), &request_order_, &completion_count_);
int rv = req1.handle.Init("a", ignored_request_info_, 5, &req1);
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_EQ(OK, req1.WaitForResult());
@@ -1028,7 +949,7 @@ TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
// Job 1 finished OK. Start job 2 (also async OK). Release socket 1.
connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
- TestSocketRequest req2(pool_.get(), &request_order_);
+ TestSocketRequest req2(pool_.get(), &request_order_, &completion_count_);
rv = req2.handle.Init("a", ignored_request_info_, 5, &req2);
EXPECT_EQ(ERR_IO_PENDING, rv);
req1.handle.Reset();
@@ -1037,7 +958,7 @@ TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
// Job 2 is pending. Start request 3 (which has no associated job since it
// will use the idle socket).
- TestSocketRequest req3(pool_.get(), &request_order_);
+ TestSocketRequest req3(pool_.get(), &request_order_, &completion_count_);
rv = req3.handle.Init("a", ignored_request_info_, 5, &req3);
EXPECT_EQ(OK, rv);
@@ -1075,7 +996,7 @@ TEST_F(ClientSocketPoolBaseTest_LateBinding, BasicAsynchronous) {
CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
- TestSocketRequest req(pool_.get(), &request_order_);
+ TestSocketRequest req(pool_.get(), &request_order_, &completion_count_);
int rv = req.handle.Init("a", ignored_request_info_, 0, &req);
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &req.handle));
@@ -1089,7 +1010,7 @@ TEST_F(ClientSocketPoolBaseTest_LateBinding, InitConnectionFailure) {
CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
- TestSocketRequest req(pool_.get(), &request_order_);
+ TestSocketRequest req(pool_.get(), &request_order_, &completion_count_);
EXPECT_EQ(ERR_CONNECTION_FAILED,
req.handle.Init("a", ignored_request_info_,
kDefaultPriority, &req));
@@ -1100,7 +1021,7 @@ TEST_F(ClientSocketPoolBaseTest_LateBinding,
CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
- TestSocketRequest req(pool_.get(), &request_order_);
+ TestSocketRequest req(pool_.get(), &request_order_, &completion_count_);
EXPECT_EQ(ERR_IO_PENDING,
req.handle.Init("a", ignored_request_info_, 5, &req));
EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &req.handle));
@@ -1122,8 +1043,7 @@ TEST_F(ClientSocketPoolBaseTest_LateBinding, PendingRequests) {
EXPECT_EQ(kDefaultMaxSocketsPerGroup,
client_socket_factory_.allocation_count());
- EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup,
- TestSocketRequest::completion_count);
+ EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
EXPECT_EQ(1, GetOrderOfRequest(1));
EXPECT_EQ(2, GetOrderOfRequest(2));
@@ -1132,6 +1052,9 @@ TEST_F(ClientSocketPoolBaseTest_LateBinding, PendingRequests) {
EXPECT_EQ(3, GetOrderOfRequest(5));
EXPECT_EQ(5, GetOrderOfRequest(6));
EXPECT_EQ(7, GetOrderOfRequest(7));
+
+ // Make sure we test order of all requests made.
+ EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
}
TEST_F(ClientSocketPoolBaseTest_LateBinding, PendingRequests_NoKeepAlive) {
@@ -1152,8 +1075,7 @@ TEST_F(ClientSocketPoolBaseTest_LateBinding, PendingRequests_NoKeepAlive) {
EXPECT_EQ(static_cast<int>(requests_.size()),
client_socket_factory_.allocation_count());
- EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup,
- TestSocketRequest::completion_count);
+ EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
}
// This test will start up a RequestSocket() and then immediately Cancel() it.
@@ -1163,7 +1085,7 @@ TEST_F(ClientSocketPoolBaseTest_LateBinding, CancelRequestClearGroup) {
CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
- TestSocketRequest req(pool_.get(), &request_order_);
+ TestSocketRequest req(pool_.get(), &request_order_, &completion_count_);
EXPECT_EQ(ERR_IO_PENDING,
req.handle.Init("a", ignored_request_info_,
kDefaultPriority, &req));
@@ -1174,8 +1096,8 @@ TEST_F(ClientSocketPoolBaseTest_LateBinding, TwoRequestsCancelOne) {
CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
- TestSocketRequest req(pool_.get(), &request_order_);
- TestSocketRequest req2(pool_.get(), &request_order_);
+ TestSocketRequest req(pool_.get(), &request_order_, &completion_count_);
+ TestSocketRequest req2(pool_.get(), &request_order_, &completion_count_);
EXPECT_EQ(ERR_IO_PENDING,
req.handle.Init("a", ignored_request_info_,
@@ -1196,7 +1118,7 @@ TEST_F(ClientSocketPoolBaseTest_LateBinding, ConnectCancelConnect) {
connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
ClientSocketHandle handle(pool_.get());
TestCompletionCallback callback;
- TestSocketRequest req(pool_.get(), &request_order_);
+ TestSocketRequest req(pool_.get(), &request_order_, &completion_count_);
EXPECT_EQ(ERR_IO_PENDING,
handle.Init("a", ignored_request_info_,
@@ -1236,7 +1158,7 @@ TEST_F(ClientSocketPoolBaseTest_LateBinding, CancelRequest) {
EXPECT_EQ(kDefaultMaxSocketsPerGroup,
client_socket_factory_.allocation_count());
EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
- TestSocketRequest::completion_count);
+ completion_count_);
EXPECT_EQ(1, GetOrderOfRequest(1));
EXPECT_EQ(2, GetOrderOfRequest(2));
@@ -1245,6 +1167,9 @@ TEST_F(ClientSocketPoolBaseTest_LateBinding, CancelRequest) {
EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
EXPECT_EQ(4, GetOrderOfRequest(6));
EXPECT_EQ(6, GetOrderOfRequest(7));
+
+ // Make sure we test order of all requests made.
+ EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
}
TEST_F(ClientSocketPoolBaseTest_LateBinding, RequestPendingJobTwice) {
@@ -1306,8 +1231,7 @@ TEST_F(ClientSocketPoolBaseTest_LateBinding,
requests_[i]->handle.Reset();
}
- EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup,
- TestSocketRequest::completion_count);
+ EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
}
// Make sure that pending requests get serviced after active requests fail.
@@ -1335,7 +1259,7 @@ TEST_F(ClientSocketPoolBaseTest_LateBinding,
connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
- TestSocketRequest req(pool_.get(), &request_order_);
+ TestSocketRequest req(pool_.get(), &request_order_, &completion_count_);
int rv = req.handle.Init(
"a", ignored_request_info_, kDefaultPriority, &req);
EXPECT_EQ(ERR_IO_PENDING, rv);
@@ -1348,7 +1272,7 @@ TEST_F(ClientSocketPoolBaseTest_LateBinding,
EXPECT_EQ(OK, req.WaitForResult());
EXPECT_FALSE(req.handle.is_reused());
- EXPECT_EQ(1U, TestSocketRequest::completion_count);
+ EXPECT_EQ(1U, completion_count_);
EXPECT_EQ(2, client_socket_factory_.allocation_count());
}
@@ -1360,7 +1284,7 @@ TEST_F(ClientSocketPoolBaseTest_LateBinding, ReleaseSockets) {
// Start job 1 (async OK)
connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
- TestSocketRequest req1(pool_.get(), &request_order_);
+ TestSocketRequest req1(pool_.get(), &request_order_, &completion_count_);
int rv = req1.handle.Init("a", ignored_request_info_, 5, &req1);
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_EQ(OK, req1.WaitForResult());
@@ -1369,10 +1293,10 @@ TEST_F(ClientSocketPoolBaseTest_LateBinding, ReleaseSockets) {
// without a job.
connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
- TestSocketRequest req2(pool_.get(), &request_order_);
+ TestSocketRequest req2(pool_.get(), &request_order_, &completion_count_);
rv = req2.handle.Init("a", ignored_request_info_, 5, &req2);
EXPECT_EQ(ERR_IO_PENDING, rv);
- TestSocketRequest req3(pool_.get(), &request_order_);
+ TestSocketRequest req3(pool_.get(), &request_order_, &completion_count_);
rv = req3.handle.Init("a", ignored_request_info_, 5, &req3);
EXPECT_EQ(ERR_IO_PENDING, rv);
@@ -1403,18 +1327,18 @@ TEST_F(ClientSocketPoolBaseTest_LateBinding, PendingJobCompletionOrder) {
// First two jobs are async.
connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
- TestSocketRequest req1(pool_.get(), &request_order_);
+ TestSocketRequest req1(pool_.get(), &request_order_, &completion_count_);
int rv = req1.handle.Init("a", ignored_request_info_, 5, &req1);
EXPECT_EQ(ERR_IO_PENDING, rv);
- TestSocketRequest req2(pool_.get(), &request_order_);
+ TestSocketRequest req2(pool_.get(), &request_order_, &completion_count_);
rv = req2.handle.Init("a", ignored_request_info_, 5, &req2);
EXPECT_EQ(ERR_IO_PENDING, rv);
// The pending job is sync.
connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
- TestSocketRequest req3(pool_.get(), &request_order_);
+ TestSocketRequest req3(pool_.get(), &request_order_, &completion_count_);
rv = req3.handle.Init("a", ignored_request_info_, 5, &req3);
EXPECT_EQ(ERR_IO_PENDING, rv);
@@ -1433,14 +1357,14 @@ TEST_F(ClientSocketPoolBaseTest_LateBinding, DISABLED_LoadState) {
connect_job_factory_->set_job_type(
TestConnectJob::kMockAdvancingLoadStateJob);
- TestSocketRequest req1(pool_.get(), &request_order_);
+ TestSocketRequest req1(pool_.get(), &request_order_, &completion_count_);
int rv = req1.handle.Init("a", ignored_request_info_, 5, &req1);
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_EQ(LOAD_STATE_IDLE, req1.handle.GetLoadState());
MessageLoop::current()->RunAllPending();
- TestSocketRequest req2(pool_.get(), &request_order_);
+ TestSocketRequest req2(pool_.get(), &request_order_, &completion_count_);
rv = req2.handle.Init("a", ignored_request_info_, 5, &req2);
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req1.handle.GetLoadState());
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc
index 25de9d3..ca39235 100644
--- a/net/socket/socket_test_util.cc
+++ b/net/socket/socket_test_util.cc
@@ -303,4 +303,78 @@ SSLClientSocket* MockClientSocketFactory::CreateSSLClientSocket(
mock_ssl_sockets_.GetNext());
}
+int TestSocketRequest::WaitForResult() {
+ return callback_.WaitForResult();
+}
+
+void TestSocketRequest::RunWithParams(const Tuple1<int>& params) {
+ callback_.RunWithParams(params);
+ (*completion_count_)++;
+ request_order_->push_back(this);
+}
+
+// static
+const int ClientSocketPoolTest::kIndexOutOfBounds = -1;
+
+// static
+const int ClientSocketPoolTest::kRequestNotFound = -2;
+
+void ClientSocketPoolTest::SetUp() {
+ completion_count_ = 0;
+}
+
+void ClientSocketPoolTest::TearDown() {
+ // The tests often call Reset() on handles at the end which may post
+ // DoReleaseSocket() tasks.
+ MessageLoop::current()->RunAllPending();
+}
+
+int ClientSocketPoolTest::StartRequestUsingPool(ClientSocketPool* socket_pool,
+ const std::string& group_name,
+ int priority) {
+ DCHECK(socket_pool);
+ TestSocketRequest* request = new TestSocketRequest(socket_pool,
+ &request_order_,
+ &completion_count_);
+ requests_.push_back(request);
+ int rv = request->handle.Init(group_name, ignored_request_info_, priority,
+ request);
+ if (rv != ERR_IO_PENDING)
+ request_order_.push_back(request);
+ return rv;
+}
+
+int ClientSocketPoolTest::GetOrderOfRequest(size_t index) {
+ index--;
+ if (index >= requests_.size())
+ return kIndexOutOfBounds;
+
+ for (size_t i = 0; i < request_order_.size(); i++)
+ if (requests_[index] == request_order_[i])
+ return i + 1;
+
+ return kRequestNotFound;
+}
+
+bool ClientSocketPoolTest::ReleaseOneConnection(KeepAlive keep_alive) {
+ ScopedVector<TestSocketRequest>::iterator i;
+ for (i = requests_.begin(); i != requests_.end(); ++i) {
+ if ((*i)->handle.is_initialized()) {
+ if (keep_alive == NO_KEEP_ALIVE)
+ (*i)->handle.socket()->Disconnect();
+ (*i)->handle.Reset();
+ MessageLoop::current()->RunAllPending();
+ return true;
+ }
+ }
+ return false;
+}
+
+void ClientSocketPoolTest::ReleaseAllConnections(KeepAlive keep_alive) {
+ bool released_one;
+ do {
+ released_one = ReleaseOneConnection(keep_alive);
+ } while (released_one);
+}
+
} // namespace net
diff --git a/net/socket/socket_test_util.h b/net/socket/socket_test_util.h
index 93f9625..324b70a 100644
--- a/net/socket/socket_test_util.h
+++ b/net/socket/socket_test_util.h
@@ -12,12 +12,16 @@
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/scoped_ptr.h"
+#include "base/scoped_vector.h"
#include "net/base/address_list.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/base/ssl_config_service.h"
+#include "net/base/test_completion_callback.h"
#include "net/socket/client_socket_factory.h"
+#include "net/socket/client_socket_handle.h"
#include "net/socket/ssl_client_socket.h"
+#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -290,6 +294,71 @@ class MockSSLClientSocket : public MockClientSocket {
net::MockSSLSocket* data_;
};
+class TestSocketRequest : public CallbackRunner< Tuple1<int> > {
+ public:
+ TestSocketRequest(
+ ClientSocketPool* pool,
+ std::vector<TestSocketRequest*>* request_order,
+ size_t* completion_count)
+ : handle(pool),
+ request_order_(request_order),
+ completion_count_(completion_count) {
+ DCHECK(request_order);
+ DCHECK(completion_count);
+ }
+
+ ClientSocketHandle handle;
+
+ int WaitForResult();
+ virtual void RunWithParams(const Tuple1<int>& params);
+
+ private:
+ std::vector<TestSocketRequest*>* request_order_;
+ size_t* completion_count_;
+ TestCompletionCallback callback_;
+};
+
+class ClientSocketPoolTest : public testing::Test {
+ protected:
+ enum KeepAlive {
+ KEEP_ALIVE,
+
+ // A socket will be disconnected in addition to handle being reset.
+ NO_KEEP_ALIVE,
+ };
+
+ static const int kIndexOutOfBounds;
+ static const int kRequestNotFound;
+
+ ClientSocketPoolTest() : ignored_request_info_("ignored", 80) {
+ }
+
+ virtual void SetUp();
+ virtual void TearDown();
+
+ int StartRequestUsingPool(ClientSocketPool* socket_pool,
+ const std::string& group_name,
+ int priority);
+
+ // Provided there were n requests started, takes |index| in range 1..n
+ // and returns order in which that request completed, in range 1..n,
+ // or kIndexOutOfBounds if |index| is out of bounds, or kRequestNotFound
+ // if that request did not complete (for example was canceled).
+ int GetOrderOfRequest(size_t index);
+
+ // Resets first initialized socket handle from |requests_|. If found such
+ // a handle, returns true.
+ bool ReleaseOneConnection(KeepAlive keep_alive);
+
+ // Releases connections until there is nothing to release.
+ void ReleaseAllConnections(KeepAlive keep_alive);
+
+ HostResolver::RequestInfo ignored_request_info_;
+ ScopedVector<TestSocketRequest> requests_;
+ std::vector<TestSocketRequest*> request_order_;
+ size_t completion_count_;
+};
+
} // namespace net
#endif // NET_SOCKET_SOCKET_TEST_UTIL_H_
diff --git a/net/socket/tcp_client_socket_pool_unittest.cc b/net/socket/tcp_client_socket_pool_unittest.cc
index a31afcc..ce7e703 100644
--- a/net/socket/tcp_client_socket_pool_unittest.cc
+++ b/net/socket/tcp_client_socket_pool_unittest.cc
@@ -12,6 +12,7 @@
#include "net/socket/client_socket.h"
#include "net/socket/client_socket_factory.h"
#include "net/socket/client_socket_handle.h"
+#include "net/socket/socket_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -20,16 +21,7 @@ namespace {
const int kMaxSockets = 32;
const int kMaxSocketsPerGroup = 6;
-
-// Note that the first and the last are the same, the first should be handled
-// before the last, since it was inserted first.
-const int kPriorities[10] = { 1, 7, 9, 5, 6, 2, 8, 3, 4, 1 };
-
-// This is the number of extra requests beyond the first few that use up all
-// available sockets in the socket group.
-const int kNumPendingRequests = arraysize(kPriorities);
-
-const int kNumRequests = kMaxSocketsPerGroup + kNumPendingRequests;
+const int kDefaultPriority = 5;
class MockClientSocket : public ClientSocket {
public:
@@ -194,35 +186,7 @@ class MockClientSocketFactory : public ClientSocketFactory {
ClientSocketType client_socket_type_;
};
-class TestSocketRequest : public CallbackRunner< Tuple1<int> > {
- public:
- TestSocketRequest(
- ClientSocketPool* pool,
- std::vector<TestSocketRequest*>* request_order)
- : handle(pool), request_order_(request_order) {}
-
- ClientSocketHandle handle;
-
- int WaitForResult() {
- return callback_.WaitForResult();
- }
-
- virtual void RunWithParams(const Tuple1<int>& params) {
- callback_.RunWithParams(params);
- completion_count++;
- request_order_->push_back(this);
- }
-
- static int completion_count;
-
- private:
- std::vector<TestSocketRequest*>* request_order_;
- TestCompletionCallback callback_;
-};
-
-int TestSocketRequest::completion_count = 0;
-
-class TCPClientSocketPoolTest : public testing::Test {
+class TCPClientSocketPoolTest : public ClientSocketPoolTest {
protected:
TCPClientSocketPoolTest()
: host_resolver_(new MockHostResolver),
@@ -232,20 +196,13 @@ class TCPClientSocketPoolTest : public testing::Test {
&client_socket_factory_)) {
}
- virtual void SetUp() {
- TestSocketRequest::completion_count = 0;
- }
-
- virtual void TearDown() {
- // The tests often call Reset() on handles at the end which may post
- // DoReleaseSocket() tasks.
- MessageLoop::current()->RunAllPending();
+ int StartRequest(const std::string& group_name, int priority) {
+ return StartRequestUsingPool(pool_.get(), group_name, priority);
}
scoped_refptr<MockHostResolver> host_resolver_;
MockClientSocketFactory client_socket_factory_;
scoped_refptr<ClientSocketPool> pool_;
- std::vector<TestSocketRequest*> request_order_;
};
TEST_F(TCPClientSocketPoolTest, Basic) {
@@ -266,7 +223,7 @@ TEST_F(TCPClientSocketPoolTest, Basic) {
TEST_F(TCPClientSocketPoolTest, InitHostResolutionFailure) {
host_resolver_->rules()->AddSimulatedFailure("unresolvable.host.name");
- TestSocketRequest req(pool_.get(), &request_order_);
+ TestSocketRequest req(pool_.get(), &request_order_, &completion_count_);
HostResolver::RequestInfo info("unresolvable.host.name", 80);
EXPECT_EQ(ERR_IO_PENDING, req.handle.Init("a", info, 5, &req));
EXPECT_EQ(ERR_NAME_NOT_RESOLVED, req.WaitForResult());
@@ -275,7 +232,7 @@ TEST_F(TCPClientSocketPoolTest, InitHostResolutionFailure) {
TEST_F(TCPClientSocketPoolTest, InitConnectionFailure) {
client_socket_factory_.set_client_socket_type(
MockClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET);
- TestSocketRequest req(pool_.get(), &request_order_);
+ TestSocketRequest req(pool_.get(), &request_order_, &completion_count_);
HostResolver::RequestInfo info("a", 80);
EXPECT_EQ(ERR_IO_PENDING,
req.handle.Init("a", info, 5, &req));
@@ -288,125 +245,106 @@ TEST_F(TCPClientSocketPoolTest, InitConnectionFailure) {
}
TEST_F(TCPClientSocketPoolTest, PendingRequests) {
- scoped_ptr<TestSocketRequest> reqs[kNumRequests];
-
- for (size_t i = 0; i < arraysize(reqs); ++i)
- reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_));
-
- // Create connections or queue up requests.
-
// First request finishes asynchronously.
- HostResolver::RequestInfo info("www.google.com", 80);
- int rv = reqs[0]->handle.Init("a", info, 5, reqs[0].get());
- EXPECT_EQ(ERR_IO_PENDING, rv);
- EXPECT_EQ(OK, reqs[0]->WaitForResult());
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
+ EXPECT_EQ(OK, requests_[0]->WaitForResult());
// Make all subsequent host resolutions complete synchronously.
host_resolver_->set_synchronous_mode(true);
- // Rest of them finish synchronously.
- for (int i = 1; i < kMaxSocketsPerGroup; ++i) {
- rv = reqs[i]->handle.Init("a", info, 5, reqs[i].get());
- EXPECT_EQ(OK, rv);
- request_order_.push_back(reqs[i].get());
- }
+ // Rest of them finish synchronously, until we reach the per-group limit.
+ EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
+ EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
+ EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
+ EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
+ EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
// The rest are pending since we've used all active sockets.
- for (int i = 0; i < kNumPendingRequests; ++i) {
- rv = reqs[kMaxSocketsPerGroup + i]->handle.Init(
- "a", info, kPriorities[i], reqs[kMaxSocketsPerGroup + i].get());
- EXPECT_EQ(ERR_IO_PENDING, rv);
- }
-
- // Release any connections until we have no connections.
- bool released_one;
- do {
- released_one = false;
- for (size_t i = 0; i < arraysize(reqs); ++i) {
- if (reqs[i]->handle.is_initialized()) {
- reqs[i]->handle.Reset();
- MessageLoop::current()->RunAllPending();
- released_one = true;
- }
- }
- } while (released_one);
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 7));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 9));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 5));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 6));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 8));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
+
+ ReleaseAllConnections(KEEP_ALIVE);
EXPECT_EQ(kMaxSocketsPerGroup, client_socket_factory_.allocation_count());
- EXPECT_EQ(kNumPendingRequests + 1, TestSocketRequest::completion_count);
-
- for (int i = 0; i < kMaxSocketsPerGroup; ++i) {
- EXPECT_EQ(request_order_[i], reqs[i].get()) <<
- "Request " << i << " was not in order.";
- }
-
- for (int i = 0; i < kNumPendingRequests - 1; ++i) {
- int index_in_queue = (kNumPendingRequests - 1) - kPriorities[i];
- EXPECT_EQ(request_order_[kMaxSocketsPerGroup + index_in_queue],
- reqs[kMaxSocketsPerGroup + i].get()) <<
- "Request " << kMaxSocketsPerGroup + i << " was not in order.";
- }
- EXPECT_EQ(request_order_[arraysize(reqs) - 1],
- reqs[arraysize(reqs) - 1].get()) <<
- "The last request with priority 1 should not have been inserted "
- "earlier into the queue.";
+ // One initial asynchronous request and then 10 pending requests.
+ EXPECT_EQ(11U, completion_count_);
+
+ // First part of requests, all with the same priority, finishes in FIFO order.
+ EXPECT_EQ(1, GetOrderOfRequest(1));
+ EXPECT_EQ(2, GetOrderOfRequest(2));
+ EXPECT_EQ(3, GetOrderOfRequest(3));
+ EXPECT_EQ(4, GetOrderOfRequest(4));
+ EXPECT_EQ(5, GetOrderOfRequest(5));
+ EXPECT_EQ(6, GetOrderOfRequest(6));
+
+ // Make sure that rest o the requests complete in the order of priority.
+ EXPECT_EQ(15, GetOrderOfRequest(7));
+ EXPECT_EQ(9, GetOrderOfRequest(8));
+ EXPECT_EQ(7, GetOrderOfRequest(9));
+ EXPECT_EQ(11, GetOrderOfRequest(10));
+ EXPECT_EQ(10, GetOrderOfRequest(11));
+ EXPECT_EQ(14, GetOrderOfRequest(12));
+ EXPECT_EQ(8, GetOrderOfRequest(13));
+ EXPECT_EQ(13, GetOrderOfRequest(14));
+ EXPECT_EQ(12, GetOrderOfRequest(15));
+ EXPECT_EQ(16, GetOrderOfRequest(16));
+
+ // Make sure we test order of all requests made.
+ EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(17));
}
TEST_F(TCPClientSocketPoolTest, PendingRequests_NoKeepAlive) {
- scoped_ptr<TestSocketRequest> reqs[kNumRequests];
- for (size_t i = 0; i < arraysize(reqs); ++i)
- reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_));
-
- // Create connections or queue up requests.
-
// First request finishes asynchronously.
- HostResolver::RequestInfo info("www.google.com", 80);
- int rv = reqs[0]->handle.Init("a", info, 5, reqs[0].get());
- EXPECT_EQ(ERR_IO_PENDING, rv);
- EXPECT_EQ(OK, reqs[0]->WaitForResult());
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
+ EXPECT_EQ(OK, requests_[0]->WaitForResult());
// Make all subsequent host resolutions complete synchronously.
host_resolver_->set_synchronous_mode(true);
- // Rest of them finish synchronously.
- for (int i = 1; i < kMaxSocketsPerGroup; ++i) {
- rv = reqs[i]->handle.Init("a", info, 5, reqs[i].get());
- EXPECT_EQ(OK, rv);
- request_order_.push_back(reqs[i].get());
- }
+ // Rest of them finish synchronously, until we reach the per-group limit.
+ EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
+ EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
+ EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
+ EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
+ EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
// The rest are pending since we've used all active sockets.
- for (int i = 0; i < kNumPendingRequests; ++i) {
- EXPECT_EQ(ERR_IO_PENDING, reqs[kMaxSocketsPerGroup + i]->handle.Init(
- "a", info, 0, reqs[kMaxSocketsPerGroup + i].get()));
- }
-
- // Release any connections until we have no connections.
- bool released_one;
- do {
- released_one = false;
- for (size_t i = 0; i < arraysize(reqs); ++i) {
- if (reqs[i]->handle.is_initialized()) {
- reqs[i]->handle.socket()->Disconnect(); // No keep alive.
- reqs[i]->handle.Reset();
- MessageLoop::current()->RunAllPending();
- released_one = true;
- }
- }
- } while (released_one);
-
- for (int i = kMaxSocketsPerGroup; i < kNumRequests; ++i)
- EXPECT_EQ(OK, reqs[i]->WaitForResult());
-
- EXPECT_EQ(kNumRequests, client_socket_factory_.allocation_count());
- EXPECT_EQ(kNumPendingRequests + 1, TestSocketRequest::completion_count);
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
+
+ ReleaseAllConnections(NO_KEEP_ALIVE);
+
+ // The pending requests should finish successfully.
+ EXPECT_EQ(OK, requests_[6]->WaitForResult());
+ EXPECT_EQ(OK, requests_[7]->WaitForResult());
+ EXPECT_EQ(OK, requests_[8]->WaitForResult());
+ EXPECT_EQ(OK, requests_[9]->WaitForResult());
+ EXPECT_EQ(OK, requests_[10]->WaitForResult());
+
+ EXPECT_EQ(static_cast<int>(requests_.size()),
+ client_socket_factory_.allocation_count());
+
+ // First asynchronous request, and then last 5 pending requests.
+ EXPECT_EQ(6U, completion_count_);
}
// This test will start up a RequestSocket() and then immediately Cancel() it.
// The pending host resolution will eventually complete, and destroy the
// ClientSocketPool which will crash if the group was not cleared properly.
TEST_F(TCPClientSocketPoolTest, CancelRequestClearGroup) {
- TestSocketRequest req(pool_.get(), &request_order_);
+ TestSocketRequest req(pool_.get(), &request_order_, &completion_count_);
HostResolver::RequestInfo info("www.google.com", 80);
EXPECT_EQ(ERR_IO_PENDING, req.handle.Init("a", info, 5, &req));
req.handle.Reset();
@@ -422,8 +360,8 @@ TEST_F(TCPClientSocketPoolTest, CancelRequestClearGroup) {
}
TEST_F(TCPClientSocketPoolTest, TwoRequestsCancelOne) {
- TestSocketRequest req(pool_.get(), &request_order_);
- TestSocketRequest req2(pool_.get(), &request_order_);
+ TestSocketRequest req(pool_.get(), &request_order_, &completion_count_);
+ TestSocketRequest req2(pool_.get(), &request_order_, &completion_count_);
HostResolver::RequestInfo info("www.google.com", 80);
EXPECT_EQ(ERR_IO_PENDING, req.handle.Init("a", info, 5, &req));
@@ -440,7 +378,7 @@ TEST_F(TCPClientSocketPoolTest, ConnectCancelConnect) {
MockClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET);
ClientSocketHandle handle(pool_.get());
TestCompletionCallback callback;
- TestSocketRequest req(pool_.get(), &request_order_);
+ TestSocketRequest req(pool_.get(), &request_order_, &completion_count_);
HostResolver::RequestInfo info("www.google.com", 80);
EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", info, 5, &callback));
@@ -467,75 +405,61 @@ TEST_F(TCPClientSocketPoolTest, ConnectCancelConnect) {
}
TEST_F(TCPClientSocketPoolTest, CancelRequest) {
- scoped_ptr<TestSocketRequest> reqs[kNumRequests];
-
- for (size_t i = 0; i < arraysize(reqs); ++i)
- reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_));
-
- // Create connections or queue up requests.
- HostResolver::RequestInfo info("www.google.com", 80);
-
// First request finishes asynchronously.
- int rv = reqs[0]->handle.Init("a", info, 5, reqs[0].get());
- EXPECT_EQ(ERR_IO_PENDING, rv);
- EXPECT_EQ(OK, reqs[0]->WaitForResult());
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
+ EXPECT_EQ(OK, requests_[0]->WaitForResult());
// Make all subsequent host resolutions complete synchronously.
host_resolver_->set_synchronous_mode(true);
- // Rest of them finish synchronously.
- for (int i = 1; i < kMaxSocketsPerGroup; ++i) {
- rv = reqs[i]->handle.Init("a", info, 5, reqs[i].get());
- EXPECT_EQ(OK, rv);
- request_order_.push_back(reqs[i].get());
- }
-
- // The rest are pending since we've used all active sockets.
- for (int i = 0; i < kNumPendingRequests; ++i) {
- EXPECT_EQ(ERR_IO_PENDING, reqs[kMaxSocketsPerGroup + i]->handle.Init(
- "a", info, kPriorities[i], reqs[kMaxSocketsPerGroup + i].get()));
- }
+ EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
+ EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
+ EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
+ EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
+ EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
+
+ // Reached per-group limit, queue up requests.
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 7));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 9));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 5));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 6));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 8));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
// Cancel a request.
size_t index_to_cancel = kMaxSocketsPerGroup + 2;
- EXPECT_TRUE(!reqs[index_to_cancel]->handle.is_initialized());
- reqs[index_to_cancel]->handle.Reset();
-
- // Release any connections until we have no connections.
- bool released_one;
- do {
- released_one = false;
- for (size_t i = 0; i < arraysize(reqs); ++i) {
- if (reqs[i]->handle.is_initialized()) {
- reqs[i]->handle.Reset();
- MessageLoop::current()->RunAllPending();
- released_one = true;
- }
- }
- } while (released_one);
-
- EXPECT_EQ(kMaxSocketsPerGroup, client_socket_factory_.allocation_count());
- EXPECT_EQ(kNumPendingRequests, TestSocketRequest::completion_count);
-
- for (int i = 0; i < kMaxSocketsPerGroup; ++i) {
- EXPECT_EQ(request_order_[i], reqs[i].get()) <<
- "Request " << i << " was not in order.";
- }
-
- for (int i = 0; i < kNumPendingRequests - 1; ++i) {
- if (i == 2) continue;
- int index_in_queue = (kNumPendingRequests - 1) - kPriorities[i];
- if (kPriorities[i] < kPriorities[index_to_cancel - kMaxSocketsPerGroup])
- index_in_queue--;
- EXPECT_EQ(request_order_[kMaxSocketsPerGroup + index_in_queue],
- reqs[kMaxSocketsPerGroup + i].get()) <<
- "Request " << kMaxSocketsPerGroup + i << " was not in order.";
- }
-
- EXPECT_EQ(request_order_[arraysize(reqs) - 2],
- reqs[arraysize(reqs) - 1].get()) <<
- "The last request with priority 1 should not have been inserted "
- "earlier into the queue.";
+ EXPECT_FALSE(requests_[index_to_cancel]->handle.is_initialized());
+ requests_[index_to_cancel]->handle.Reset();
+
+ ReleaseAllConnections(KEEP_ALIVE);
+
+ EXPECT_EQ(kMaxSocketsPerGroup,
+ client_socket_factory_.allocation_count());
+ EXPECT_EQ(requests_.size() - kMaxSocketsPerGroup, completion_count_);
+
+ EXPECT_EQ(1, GetOrderOfRequest(1));
+ EXPECT_EQ(2, GetOrderOfRequest(2));
+ EXPECT_EQ(3, GetOrderOfRequest(3));
+ EXPECT_EQ(4, GetOrderOfRequest(4));
+ EXPECT_EQ(5, GetOrderOfRequest(5));
+ EXPECT_EQ(6, GetOrderOfRequest(6));
+ EXPECT_EQ(14, GetOrderOfRequest(7));
+ EXPECT_EQ(8, GetOrderOfRequest(8));
+ EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(9)); // Canceled request.
+ EXPECT_EQ(10, GetOrderOfRequest(10));
+ EXPECT_EQ(9, GetOrderOfRequest(11));
+ EXPECT_EQ(13, GetOrderOfRequest(12));
+ EXPECT_EQ(7, GetOrderOfRequest(13));
+ EXPECT_EQ(12, GetOrderOfRequest(14));
+ EXPECT_EQ(11, GetOrderOfRequest(15));
+ EXPECT_EQ(15, GetOrderOfRequest(16));
+
+ // Make sure we test order of all requests made.
+ EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(17));
}
class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
@@ -589,29 +513,29 @@ TEST_F(TCPClientSocketPoolTest, CancelActiveRequestWithPendingRequests) {
client_socket_factory_.set_client_socket_type(
MockClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET);
- scoped_ptr<TestSocketRequest> reqs[kNumRequests];
-
// Queue up all the requests
-
- HostResolver::RequestInfo info("www.google.com", 80);
- for (size_t i = 0; i < arraysize(reqs); ++i) {
- reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_));
- int rv = reqs[i]->handle.Init("a", info, 5, reqs[i].get());
- EXPECT_EQ(ERR_IO_PENDING, rv);
- }
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
// Now, kMaxSocketsPerGroup requests should be active. Let's cancel them.
- for (int i = 0; i < kMaxSocketsPerGroup; ++i)
- reqs[i]->handle.Reset();
+ ASSERT_LE(kMaxSocketsPerGroup, static_cast<int>(requests_.size()));
+ for (int i = 0; i < kMaxSocketsPerGroup; i++)
+ requests_[i]->handle.Reset();
// Let's wait for the rest to complete now.
-
- for (size_t i = kMaxSocketsPerGroup; i < arraysize(reqs); ++i) {
- EXPECT_EQ(OK, reqs[i]->WaitForResult());
- reqs[i]->handle.Reset();
+ for (size_t i = kMaxSocketsPerGroup; i < requests_.size(); ++i) {
+ EXPECT_EQ(OK, requests_[i]->WaitForResult());
+ requests_[i]->handle.Reset();
}
- EXPECT_EQ(kNumPendingRequests, TestSocketRequest::completion_count);
+ EXPECT_EQ(requests_.size() - kMaxSocketsPerGroup, completion_count_);
}
// Make sure that pending requests get serviced after active requests fail.
@@ -619,20 +543,15 @@ TEST_F(TCPClientSocketPoolTest, FailingActiveRequestWithPendingRequests) {
client_socket_factory_.set_client_socket_type(
MockClientSocketFactory::MOCK_PENDING_FAILING_CLIENT_SOCKET);
- scoped_ptr<TestSocketRequest> reqs[kMaxSocketsPerGroup * 2 + 1];
- ASSERT_LE(static_cast<int>(arraysize(reqs)), kMaxSockets);
+ const int kNumRequests = 2 * kMaxSocketsPerGroup + 1;
+ ASSERT_LE(kNumRequests, kMaxSockets); // Otherwise the test will hang.
// Queue up all the requests
+ for (int i = 0; i < kNumRequests; i++)
+ EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
- HostResolver::RequestInfo info("www.google.com", 80);
- for (size_t i = 0; i < arraysize(reqs); ++i) {
- reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_));
- int rv = reqs[i]->handle.Init("a", info, 5, reqs[i].get());
- EXPECT_EQ(ERR_IO_PENDING, rv);
- }
-
- for (size_t i = 0; i < arraysize(reqs); ++i)
- EXPECT_EQ(ERR_CONNECTION_FAILED, reqs[i]->WaitForResult());
+ for (int i = 0; i < kNumRequests; i++)
+ EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
}
} // namespace