Chromium Code Reviews| Index: net/http/http_network_transaction_unittest.cc |
| diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc |
| index 0f37ed291a2e39bd66f3e0bcdd6ba8eb8974840a..524a5643bfb2e4bb89c063da0cb5104231e2deed 100644 |
| --- a/net/http/http_network_transaction_unittest.cc |
| +++ b/net/http/http_network_transaction_unittest.cc |
| @@ -404,6 +404,26 @@ INSTANTIATE_TEST_CASE_P( |
| namespace { |
| +class BeforeNetworkStartHandler { |
| + public: |
| + BeforeNetworkStartHandler(bool defer) |
|
mmenke
2014/01/07 15:26:23
explicit
jkarlin
2014/01/07 16:19:32
Done.
|
| + : defer_on_before_network_start_(defer), |
| + observed_before_network_start_(false) {} |
| + |
| + void OnBeforeNetworkStart(bool* defer) { |
| + *defer = defer_on_before_network_start_; |
| + observed_before_network_start_ = true; |
| + } |
| + |
| + bool observed_before_network_start() const { |
| + return observed_before_network_start_; |
| + } |
| + |
| + private: |
| + bool defer_on_before_network_start_; |
|
mmenke
2014/01/07 15:26:23
const?
jkarlin
2014/01/07 16:19:32
Done.
|
| + bool observed_before_network_start_; |
|
mmenke
2014/01/07 15:26:23
DISALLOW_COPY_AND_ASSIGN?
jkarlin
2014/01/07 16:19:32
Done.
|
| +}; |
| + |
| // Fill |str| with a long header list that consumes >= |size| bytes. |
| void FillLargeHeadersString(std::string* str, int size) { |
| const char* row = |
| @@ -1343,6 +1363,100 @@ TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) { |
| EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv); |
| } |
| +// Test that network access can be deferred and resumed. |
| +TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) { |
| + HttpRequestInfo request; |
| + request.method = "GET"; |
| + request.url = GURL("http://www.google.com/"); |
| + request.load_flags = 0; |
| + |
| + scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); |
| + scoped_ptr<HttpTransaction> trans( |
| + new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); |
| + |
| + // Defer on OnBeforeNetworkStart. |
| + BeforeNetworkStartHandler net_start_handler(true); // defer |
| + trans->SetBeforeNetworkStartCallback( |
| + base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart, |
| + base::Unretained(&net_start_handler))); |
| + |
| + MockRead data_reads[] = {MockRead("HTTP/1.0 200 OK\r\n"), |
| + MockRead("Connection: keep-alive\r\n"), |
| + MockRead("Content-Length: 100\r\n\r\n"), |
| + MockRead("hello"), |
| + MockRead(SYNCHRONOUS, 0), }; |
| + StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); |
| + session_deps_.socket_factory->AddSocketDataProvider(&data); |
| + |
| + TestCompletionCallback callback; |
| + |
| + int rv = trans->Start(&request, callback.callback(), BoundNetLog()); |
| + EXPECT_EQ(ERR_IO_PENDING, rv); |
| + base::MessageLoop::current()->RunUntilIdle(); |
| + |
| + // Should have deferred for network start. |
| + EXPECT_TRUE(net_start_handler.observed_before_network_start()); |
| + EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState()); |
| + EXPECT_TRUE(trans->GetResponseInfo() == NULL); |
| + |
| + trans->ResumeNetworkStart(); |
| + rv = callback.WaitForResult(); |
| + EXPECT_EQ(OK, rv); |
| + EXPECT_TRUE(trans->GetResponseInfo() != NULL); |
| + |
| + scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100)); |
| + rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback()); |
| + if (rv == ERR_IO_PENDING) |
| + rv = callback.WaitForResult(); |
| + EXPECT_EQ(5, rv); |
| + rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback()); |
| + EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv); |
| + |
| + trans.reset(); |
| + base::MessageLoop::current()->RunUntilIdle(); |
| + EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); |
| +} |
| + |
| +// Test that network use can be deferred and canceled. |
| +TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) { |
| + HttpRequestInfo request; |
| + request.method = "GET"; |
| + request.url = GURL("http://www.google.com/"); |
| + request.load_flags = 0; |
| + |
| + scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); |
| + scoped_ptr<HttpTransaction> trans( |
| + new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); |
| + |
| + // Defer on OnBeforeNetworkStart. |
| + BeforeNetworkStartHandler net_start_handler(true); // defer |
| + trans->SetBeforeNetworkStartCallback( |
| + base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart, |
| + base::Unretained(&net_start_handler))); |
| + |
| + MockRead data_reads[] = {MockRead("HTTP/1.0 200 OK\r\n"), |
| + MockRead("Connection: keep-alive\r\n"), |
| + MockRead("Content-Length: 100\r\n\r\n"), |
| + MockRead("hello"), |
| + MockRead(SYNCHRONOUS, 0), }; |
| + StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); |
| + session_deps_.socket_factory->AddSocketDataProvider(&data); |
| + |
| + TestCompletionCallback callback; |
| + |
| + int rv = trans->Start(&request, callback.callback(), BoundNetLog()); |
| + EXPECT_EQ(ERR_IO_PENDING, rv); |
| + base::MessageLoop::current()->RunUntilIdle(); |
| + |
| + // Should have deferred for network start. |
| + EXPECT_TRUE(net_start_handler.observed_before_network_start()); |
| + EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState()); |
| + EXPECT_TRUE(trans->GetResponseInfo() == NULL); |
| + |
| + trans.reset(); // Cancel the transaction here. |
| + base::MessageLoop::current()->RunUntilIdle(); |
|
mmenke
2014/01/07 15:26:23
Are these needed? TearDown() already does its fai
jkarlin
2014/01/07 16:19:32
Fair enough. Removed.
|
| +} |
| + |
| // Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression |
| // tests. There was a bug causing HttpNetworkTransaction to hang in the |
| // destructor in such situations. |