diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/socket/client_socket_pool_base_unittest.cc | 236 | ||||
-rw-r--r-- | net/socket/socket_test_util.cc | 74 | ||||
-rw-r--r-- | net/socket/socket_test_util.h | 69 | ||||
-rw-r--r-- | net/socket/tcp_client_socket_pool_unittest.cc | 387 |
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 |