| Index: net/socket/client_socket_pool_base_unittest.cc
|
| ===================================================================
|
| --- net/socket/client_socket_pool_base_unittest.cc (revision 28729)
|
| +++ net/socket/client_socket_pool_base_unittest.cc (working copy)
|
| @@ -143,31 +143,46 @@
|
| return DoConnect(false /* error */, false /* sync */);
|
| case kMockPendingJob:
|
| set_load_state(LOAD_STATE_CONNECTING);
|
| - MessageLoop::current()->PostTask(
|
| +
|
| + // Depending on execution timings, posting a delayed task can result
|
| + // in the task getting executed the at the earliest possible
|
| + // opportunity or only after returning once from the message loop and
|
| + // then a second call into the message loop. In order to make behavior
|
| + // more deterministic, we change the default delay to 2ms. This should
|
| + // always require us to wait for the second call into the message loop.
|
| + //
|
| + // N.B. The correct fix for this and similar timing problems is to
|
| + // abstract time for the purpose of unittests. Unfortunately, we have
|
| + // a lot of third-party components that directly call the various
|
| + // time functions, so this change would be rather invasive.
|
| + MessageLoop::current()->PostDelayedTask(
|
| FROM_HERE,
|
| method_factory_.NewRunnableMethod(
|
| - &TestConnectJob::DoConnect,
|
| - true /* successful */,
|
| - true /* async */));
|
| + &TestConnectJob::DoConnect,
|
| + true /* successful */,
|
| + true /* async */),
|
| + 2);
|
| return ERR_IO_PENDING;
|
| case kMockPendingFailingJob:
|
| set_load_state(LOAD_STATE_CONNECTING);
|
| - MessageLoop::current()->PostTask(
|
| + MessageLoop::current()->PostDelayedTask(
|
| FROM_HERE,
|
| method_factory_.NewRunnableMethod(
|
| - &TestConnectJob::DoConnect,
|
| - false /* error */,
|
| - true /* async */));
|
| + &TestConnectJob::DoConnect,
|
| + false /* error */,
|
| + true /* async */),
|
| + 2);
|
| return ERR_IO_PENDING;
|
| case kMockWaitingJob:
|
| client_socket_factory_->WaitForSignal(this);
|
| waiting_success_ = true;
|
| return ERR_IO_PENDING;
|
| case kMockAdvancingLoadStateJob:
|
| - MessageLoop::current()->PostTask(
|
| + MessageLoop::current()->PostDelayedTask(
|
| FROM_HERE,
|
| method_factory_.NewRunnableMethod(
|
| - &TestConnectJob::AdvanceLoadState, load_state_));
|
| + &TestConnectJob::AdvanceLoadState, load_state_),
|
| + 2);
|
| return ERR_IO_PENDING;
|
| default:
|
| NOTREACHED();
|
| @@ -396,6 +411,13 @@
|
| }
|
|
|
| virtual void TearDown() {
|
| + // We post all of our delayed tasks with a 2ms delay. I.e. they don't
|
| + // actually become pending until 2ms after they have been created. In order
|
| + // to flush all tasks, we need to wait so that we know there are no
|
| + // soon-to-be-pending tasks waiting.
|
| + PlatformThread::Sleep(10);
|
| + 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.
|
| @@ -715,6 +737,13 @@
|
| connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
|
| EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
|
|
|
| + // We post all of our delayed tasks with a 2ms delay. I.e. they don't
|
| + // actually become pending until 2ms after they have been created. In order
|
| + // to flush all tasks, we need to wait so that we know there are no
|
| + // soon-to-be-pending tasks waiting.
|
| + PlatformThread::Sleep(10);
|
| + MessageLoop::current()->RunAllPending();
|
| +
|
| // The next synchronous request should wait for its turn.
|
| connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
|
| EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
|
| @@ -950,14 +979,26 @@
|
| test_connect_job_factory_->set_job_type(next_job_type_);
|
| handle_->Reset();
|
| within_callback_ = true;
|
| + TestCompletionCallback next_job_callback;
|
| int rv = InitHandle(
|
| - handle_, "a", kDefaultPriority, this, pool_.get(), NULL);
|
| + handle_, "a", kDefaultPriority, &next_job_callback, pool_.get(),
|
| + NULL);
|
| switch (next_job_type_) {
|
| case TestConnectJob::kMockJob:
|
| EXPECT_EQ(OK, rv);
|
| break;
|
| case TestConnectJob::kMockPendingJob:
|
| EXPECT_EQ(ERR_IO_PENDING, rv);
|
| +
|
| + // For pending jobs, wait for new socket to be created. This makes
|
| + // sure there are no more pending operations nor any unclosed sockets
|
| + // when the test finishes.
|
| + // We need to give it a little bit of time to run, so that all the
|
| + // operations that happen on timers (e.g. cleanup of idle
|
| + // connections) can execute.
|
| + MessageLoop::current()->SetNestableTasksAllowed(true);
|
| + PlatformThread::Sleep(10);
|
| + EXPECT_EQ(OK, next_job_callback.WaitForResult());
|
| break;
|
| default:
|
| FAIL() << "Unexpected job type: " << next_job_type_;
|
| @@ -1812,6 +1853,12 @@
|
| req.handle()->Reset();
|
| EXPECT_EQ(OK, req2.WaitForResult());
|
| req2.handle()->Reset();
|
| +
|
| + // We post all of our delayed tasks with a 2ms delay. I.e. they don't
|
| + // actually become pending until 2ms after they have been created. In order
|
| + // to flush all tasks, we need to wait so that we know there are no
|
| + // soon-to-be-pending tasks waiting.
|
| + PlatformThread::Sleep(10);
|
| MessageLoop::current()->RunAllPending();
|
|
|
| ASSERT_EQ(2, pool_->IdleSocketCount());
|
|
|