diff options
author | erikchen@google.com <erikchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-16 15:19:47 +0000 |
---|---|---|
committer | erikchen@google.com <erikchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-16 15:19:47 +0000 |
commit | 3caf554212d8db1afbf58b0ae71bc41383c89467 (patch) | |
tree | f592a65d783502520d12b5a80d68427cc38f9fd7 /net/spdy | |
parent | 84251a024847edcad19780a672e719ca9a810a3e (diff) | |
download | chromium_src-3caf554212d8db1afbf58b0ae71bc41383c89467.zip chromium_src-3caf554212d8db1afbf58b0ae71bc41383c89467.tar.gz chromium_src-3caf554212d8db1afbf58b0ae71bc41383c89467.tar.bz2 |
spdy network tests now use http network transaction (production code).
BUG=NONE
TEST=net_unittests
Review URL: http://codereview.chromium.org/2804045
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@52670 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/spdy')
-rw-r--r-- | net/spdy/spdy_network_transaction_unittest.cc | 951 |
1 files changed, 347 insertions, 604 deletions
diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc index 5235427..88b3533 100644 --- a/net/spdy/spdy_network_transaction_unittest.cc +++ b/net/spdy/spdy_network_transaction_unittest.cc @@ -31,7 +31,7 @@ namespace net { namespace { // Helper to manage the lifetimes of the dependencies for a -// SpdyNetworkTransaction. +// HttpNetworkTransaction. class SessionDependencies { public: // Default set of dependencies -- "null" proxy service. @@ -85,6 +85,9 @@ class SpdyNetworkTransactionTest : public PlatformTest { // By default, all tests turn off compression. EnableCompression(false); google_get_request_initialized_ = false; + HttpNetworkTransaction::SetUseAlternateProtocols(true); + HttpNetworkTransaction::SetNextProtos( + "\x08http/1.1\x07http1.1\x06spdy/1\x04spdy"); } virtual void TearDown() { @@ -106,60 +109,168 @@ class SpdyNetworkTransactionTest : public PlatformTest { spdy::SpdyFramer::set_enable_compression_default(enabled); } - TransactionHelperResult TransactionHelper(const HttpRequestInfo& request, - DelayedSocketData* data, - const BoundNetLog& log) { - SessionDependencies session_deps; - HttpNetworkSession* session = CreateSession(&session_deps); - return TransactionHelperWithSession(request, data, log, &session_deps, - session); - } - - TransactionHelperResult TransactionHelperWithSession( - const HttpRequestInfo& request, DelayedSocketData* data, - const BoundNetLog& log, SessionDependencies* session_deps, - HttpNetworkSession* session) { - CHECK(session); - CHECK(session_deps); - - TransactionHelperResult out; + class StartTransactionCallback; + class DeleteSessionCallback; + + // A helper class that handles all the initial npn/ssl setup. + class NormalSpdyTransactionHelper { + public: + NormalSpdyTransactionHelper(const HttpRequestInfo& request, + const BoundNetLog& log) + : request_(request), session_(CreateSession(&session_deps_)), + log_(log), add_data_allowed_(true) {} + + void RunPreTestSetup() { + // Disallow future calls to AddData + add_data_allowed_ = false; + + // Set up http data. + MockRead data_reads[] = { + MockRead("HTTP/1.1 200 OK\r\n"), + MockRead("Alternate-Protocol: 443:npn-spdy/1\r\n\r\n"), + MockRead("hello world"), + MockRead(true, OK), + }; + first_transaction_.reset( + new StaticSocketDataProvider(data_reads, arraysize(data_reads), + NULL, 0)); + session_deps_.socket_factory.AddSocketDataProvider( + first_transaction_.get()); + + // Set up actual test data. Also add one SSLSocketDataProvider per + // DataProvider. + for(DataVector::iterator it = data_vector_.begin(); + it != data_vector_.end(); ++it) { + linked_ptr<SSLSocketDataProvider> ssl_( + new SSLSocketDataProvider(true, OK)); + ssl_->next_proto_status = SSLClientSocket::kNextProtoNegotiated; + ssl_->next_proto = "spdy/1"; + ssl_->was_npn_negotiated = true; + ssl_vector_.push_back(ssl_); + session_deps_.socket_factory.AddSSLSocketDataProvider(ssl_.get()); + session_deps_.socket_factory.AddSocketDataProvider(*it); + } - // We disable SSL for this test. - SpdySession::SetSSLMode(false); + // We first send an http request. The Alternate-Protocol header switches + // the HttpNetworkTransaction into SSL/SPDY mode. + trans_http_.reset(new HttpNetworkTransaction(session_)); + int rv = trans_http_->Start(&request_, &callback, log_); + EXPECT_EQ(ERR_IO_PENDING, rv); + EXPECT_EQ(OK, callback.WaitForResult()); + const HttpResponseInfo* response = trans_http_->GetResponseInfo(); + EXPECT_TRUE(response != NULL); + EXPECT_TRUE(response->headers != NULL); + EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); + std::string response_data; + EXPECT_EQ(OK, ReadTransaction(trans_http_.get(), &response_data)); + EXPECT_EQ("hello world", response_data); + + // We're now ready to use SSL-npn SPDY. + trans_.reset(new HttpNetworkTransaction(session_)); + } - scoped_ptr<SpdyNetworkTransaction> trans( - new SpdyNetworkTransaction(session)); + // Start the transaction, read some data, finish. + void RunDefaultTest() { + output_.rv = trans_->Start(&request_, &callback, log_); - session_deps->socket_factory.AddSocketDataProvider(data); + // We expect an IO Pending or some sort of error. + EXPECT_LT(output_.rv, 0); + if (output_.rv != ERR_IO_PENDING) + return; - TestCompletionCallback callback; + output_.rv = callback.WaitForResult(); + if (output_.rv != OK) { + session_->spdy_session_pool()->ClearSessions(); + return; + } - out.rv = trans->Start(&request, &callback, log); - EXPECT_LT(out.rv, 0); // We expect an IO Pending or some sort of error. - if (out.rv != ERR_IO_PENDING) - return out; + // Verify responses. + const HttpResponseInfo* response = trans_->GetResponseInfo(); + ASSERT_TRUE(response != NULL); + ASSERT_TRUE(response->headers != NULL); + EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); + EXPECT_TRUE(response->was_fetched_via_spdy); + EXPECT_TRUE(response->was_npn_negotiated); + EXPECT_TRUE(response->was_alternate_protocol_available); + output_.status_line = response->headers->GetStatusLine(); + output_.response_info = *response; // Make a copy so we can verify. + output_.rv = ReadTransaction(trans_.get(), &output_.response_data); + EXPECT_EQ(OK, output_.rv); + return; + } - out.rv = callback.WaitForResult(); - if (out.rv != OK) { - session->spdy_session_pool()->ClearSessions(); - return out; + // Most tests will want to call this function. In particular, the MockReads + // should end with an empty read, and that read needs to be processed to + // ensure proper deletion of the spdy_session_pool. + void VerifyDataConsumed() { + for(DataVector::iterator it = data_vector_.begin(); + it != data_vector_.end(); ++it) { + EXPECT_TRUE((*it)->at_read_eof()) << "Read count: " + << (*it)->read_count() + << " Read index: " + << (*it)->read_index(); + EXPECT_TRUE((*it)->at_write_eof()) << "Write count: " + << (*it)->write_count() + << " Write index: " + << (*it)->write_index(); + } } - const HttpResponseInfo* response = trans->GetResponseInfo(); - EXPECT_TRUE(response->headers != NULL); - EXPECT_TRUE(response->was_fetched_via_spdy); - out.status_line = response->headers->GetStatusLine(); - out.response_info = *response; // Make a copy so we can verify. + // Occasionally a test will expect to error out before certain reads are + // processed. In that case we want to explicitly ensure that the reads were + // not processed. + void VerifyDataNotConsumed() { + for(DataVector::iterator it = data_vector_.begin(); + it != data_vector_.end(); ++it) { + EXPECT_TRUE(!(*it)->at_read_eof()) << "Read count: " + << (*it)->read_count() + << " Read index: " + << (*it)->read_index(); + EXPECT_TRUE(!(*it)->at_write_eof()) << "Write count: " + << (*it)->write_count() + << " Write index: " + << (*it)->write_index(); - out.rv = ReadTransaction(trans.get(), &out.response_data); - EXPECT_EQ(OK, out.rv); + } + } - // Verify that we consumed all test data. - EXPECT_TRUE(data->at_read_eof()); - EXPECT_TRUE(data->at_write_eof()); + void RunToCompletion(StaticSocketDataProvider* data) { + AddData(data); + RunPreTestSetup(); + RunDefaultTest(); + VerifyDataConsumed(); + } + // Only call AddData before calling RunPreTestSetup!! + void AddData(StaticSocketDataProvider* data) { + EXPECT_TRUE(add_data_allowed_); + data_vector_.push_back(data); + } - return out; - } + void SetSession(scoped_refptr<HttpNetworkSession>& session) { + session_ = session; + } + HttpNetworkTransaction* trans() { return trans_.get(); } + void ResetTrans() { trans_.reset(); } + TransactionHelperResult& output() { return output_; } + HttpRequestInfo& request() { return request_; } + scoped_refptr<HttpNetworkSession>& session() { return session_; } + + private: + typedef std::vector<StaticSocketDataProvider*> DataVector; + typedef std::vector<linked_ptr<SSLSocketDataProvider> > SSLVector; + HttpRequestInfo request_; + SessionDependencies session_deps_; + scoped_refptr<HttpNetworkSession> session_; + TransactionHelperResult output_; + scoped_ptr<StaticSocketDataProvider> first_transaction_; + SSLVector ssl_vector_; + TestCompletionCallback callback; + scoped_ptr<HttpNetworkTransaction> trans_; + scoped_ptr<HttpNetworkTransaction> trans_http_; + DataVector data_vector_; + const BoundNetLog& log_; + bool add_data_allowed_; + }; void ConnectStatusHelperWithExpectedStatus(const MockRead& status, int expected_status); @@ -183,12 +294,12 @@ class SpdyNetworkTransactionTest : public PlatformTest { //----------------------------------------------------------------------------- -// Verify SpdyNetworkTransaction constructor. +// Verify HttpNetworkTransaction constructor. TEST_F(SpdyNetworkTransactionTest, Constructor) { SessionDependencies session_deps; scoped_refptr<HttpNetworkSession> session = CreateSession(&session_deps); - scoped_ptr<HttpTransaction> trans(new SpdyNetworkTransaction(session)); + scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); } TEST_F(SpdyNetworkTransactionTest, Get) { @@ -207,9 +318,10 @@ TEST_F(SpdyNetworkTransactionTest, Get) { scoped_refptr<DelayedSocketData> data( new DelayedSocketData(1, reads, arraysize(reads), writes, arraysize(writes))); - TransactionHelperResult out = TransactionHelper(CreateGetRequest(), - data.get(), - BoundNetLog()); + NormalSpdyTransactionHelper helper(CreateGetRequest(), + BoundNetLog()); + helper.RunToCompletion(data.get()); + TransactionHelperResult out = helper.output(); EXPECT_EQ(OK, out.rv); EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); EXPECT_EQ("hello!", out.response_data); @@ -243,8 +355,10 @@ TEST_F(SpdyNetworkTransactionTest, Post) { scoped_refptr<DelayedSocketData> data( new DelayedSocketData(2, reads, arraysize(reads), writes, arraysize(writes))); - TransactionHelperResult out = TransactionHelper(request, data.get(), - BoundNetLog()); + NormalSpdyTransactionHelper helper(request, + BoundNetLog()); + helper.RunToCompletion(data.get()); + TransactionHelperResult out = helper.output(); EXPECT_EQ(OK, out.rv); EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); EXPECT_EQ("hello!", out.response_data); @@ -278,7 +392,10 @@ TEST_F(SpdyNetworkTransactionTest, EmptyPost) { new DelayedSocketData(1, reads, arraysize(reads), writes, arraysize(writes))); - TransactionHelperResult out = TransactionHelper(request, data, BoundNetLog()); + NormalSpdyTransactionHelper helper(request, + BoundNetLog()); + helper.RunToCompletion(data.get()); + TransactionHelperResult out = helper.output(); EXPECT_EQ(OK, out.rv); EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); EXPECT_EQ("hello!", out.response_data); @@ -312,8 +429,13 @@ TEST_F(SpdyNetworkTransactionTest, PostWithEarlySynReply) { scoped_refptr<DelayedSocketData> data( new DelayedSocketData(0, reads, arraysize(reads), writes, arraysize(writes))); - TransactionHelperResult out = TransactionHelper(request, data.get(), - BoundNetLog()); + NormalSpdyTransactionHelper helper(request, + BoundNetLog()); + helper.AddData(data.get()); + helper.RunPreTestSetup(); + helper.RunDefaultTest(); + helper.VerifyDataNotConsumed(); + TransactionHelperResult out = helper.output(); EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv); } @@ -327,21 +449,16 @@ TEST_F(SpdyNetworkTransactionTest, ResponseWithoutSynReply) { scoped_refptr<DelayedSocketData> data( new DelayedSocketData(1, reads, arraysize(reads), NULL, 0)); - TransactionHelperResult out = TransactionHelper(CreateGetRequest(), - data.get(), - BoundNetLog()); + NormalSpdyTransactionHelper helper(CreateGetRequest(), + BoundNetLog()); + helper.RunToCompletion(data.get()); + TransactionHelperResult out = helper.output(); EXPECT_EQ(ERR_SYN_REPLY_NOT_RECEIVED, out.rv); } // Test that the transaction doesn't crash when we get two replies on the same // stream ID. See http://crbug.com/45639. TEST_F(SpdyNetworkTransactionTest, ResponseWithTwoSynReplies) { - SessionDependencies session_deps; - HttpNetworkSession* session = CreateSession(&session_deps); - - // We disable SSL for this test. - SpdySession::SetSSLMode(false); - scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0)); MockWrite writes[] = { CreateMockWrite(*req) }; @@ -354,20 +471,19 @@ TEST_F(SpdyNetworkTransactionTest, ResponseWithTwoSynReplies) { MockRead(true, 0, 0) // EOF }; - HttpRequestInfo request; - request.method = "GET"; - request.url = GURL("http://www.google.com/"); - request.load_flags = 0; scoped_refptr<DelayedSocketData> data( new DelayedSocketData(1, reads, arraysize(reads), writes, arraysize(writes))); - session_deps.socket_factory.AddSocketDataProvider(data.get()); - scoped_ptr<SpdyNetworkTransaction> trans( - new SpdyNetworkTransaction(session)); + NormalSpdyTransactionHelper helper(CreateGetRequest(), + BoundNetLog()); + helper.AddData(data.get()); + helper.RunPreTestSetup(); + + HttpNetworkTransaction* trans = helper.trans(); TestCompletionCallback callback; - int rv = trans->Start(&request, &callback, BoundNetLog()); + int rv = trans->Start(&helper.request(), &callback, BoundNetLog()); EXPECT_EQ(ERR_IO_PENDING, rv); rv = callback.WaitForResult(); EXPECT_EQ(OK, rv); @@ -376,8 +492,10 @@ TEST_F(SpdyNetworkTransactionTest, ResponseWithTwoSynReplies) { EXPECT_TRUE(response->headers != NULL); EXPECT_TRUE(response->was_fetched_via_spdy); std::string response_data; - rv = ReadTransaction(trans.get(), &response_data); + rv = ReadTransaction(trans, &response_data); EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, rv); + + helper.VerifyDataConsumed(); } TEST_F(SpdyNetworkTransactionTest, CancelledTransaction) { @@ -385,7 +503,6 @@ TEST_F(SpdyNetworkTransactionTest, CancelledTransaction) { scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0)); MockWrite writes[] = { CreateMockWrite(*req), - MockRead(true, 0, 0) // EOF }; scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0)); @@ -393,42 +510,43 @@ TEST_F(SpdyNetworkTransactionTest, CancelledTransaction) { CreateMockRead(*resp), // This following read isn't used by the test, except during the // RunAllPending() call at the end since the SpdySession survives the - // SpdyNetworkTransaction and still tries to continue Read()'ing. Any + // HttpNetworkTransaction and still tries to continue Read()'ing. Any // MockRead will do here. MockRead(true, 0, 0) // EOF }; - // We disable SSL for this test. - SpdySession::SetSSLMode(false); - - SessionDependencies session_deps; - scoped_ptr<SpdyNetworkTransaction> trans( - new SpdyNetworkTransaction(CreateSession(&session_deps))); - StaticSocketDataProvider data(reads, arraysize(reads), writes, arraysize(writes)); - session_deps.socket_factory.AddSocketDataProvider(&data); - TestCompletionCallback callback; + NormalSpdyTransactionHelper helper(CreateGetRequest(), + BoundNetLog()); + helper.AddData(&data); + helper.RunPreTestSetup(); + HttpNetworkTransaction* trans = helper.trans(); + TestCompletionCallback callback; int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); EXPECT_EQ(ERR_IO_PENDING, rv); - trans.reset(); // Cancel the transaction. + helper.ResetTrans(); // Cancel the transaction. // Flush the MessageLoop while the SessionDependencies (in particular, the // MockClientSocketFactory) are still alive. MessageLoop::current()->RunAllPending(); + helper.VerifyDataNotConsumed(); } -class StartTransactionCallback : public CallbackRunner< Tuple1<int> > { +class SpdyNetworkTransactionTest::StartTransactionCallback + : public CallbackRunner< Tuple1<int> > { public: explicit StartTransactionCallback( - const scoped_refptr<HttpNetworkSession>& session) - : session_(session) {} + scoped_refptr<HttpNetworkSession>& session, + NormalSpdyTransactionHelper& helper) + : session_(session), helper_(helper) {} // We try to start another transaction, which should succeed. virtual void RunWithParams(const Tuple1<int>& params) { - scoped_ptr<HttpTransaction> trans(new SpdyNetworkTransaction(session_)); + scoped_ptr<HttpNetworkTransaction> trans( + new HttpNetworkTransaction(session_)); TestCompletionCallback callback; HttpRequestInfo request; request.method = "GET"; @@ -436,10 +554,12 @@ class StartTransactionCallback : public CallbackRunner< Tuple1<int> > { request.load_flags = 0; int rv = trans->Start(&request, &callback, BoundNetLog()); EXPECT_EQ(ERR_IO_PENDING, rv); + rv = callback.WaitForResult(); } private: - const scoped_refptr<HttpNetworkSession>& session_; + scoped_refptr<HttpNetworkSession>& session_; + NormalSpdyTransactionHelper& helper_; }; // Verify that the client can correctly deal with the user callback attempting @@ -465,54 +585,58 @@ TEST_F(SpdyNetworkTransactionTest, StartTransactionOnReadCallback) { MockRead(true, ERR_IO_PENDING, 3), // Force a pause MockRead(true, reinterpret_cast<const char*>(kGetBodyFrame2), arraysize(kGetBodyFrame2), 4), - MockRead(true, 0, 0, 5), // EOF + MockRead(true, ERR_IO_PENDING, 5), // Force a pause + MockRead(true, 0, 0, 6), // EOF }; MockRead reads2[] = { CreateMockRead(*resp, 2), MockRead(true, 0, 0, 3), // EOF }; - // We disable SSL for this test. - SpdySession::SetSSLMode(false); - - SessionDependencies session_deps; - scoped_refptr<HttpNetworkSession> session = CreateSession(&session_deps); - scoped_ptr<HttpTransaction> trans(new SpdyNetworkTransaction(session)); scoped_refptr<OrderedSocketData> data( new OrderedSocketData(reads, arraysize(reads), writes, arraysize(writes))); - scoped_refptr<OrderedSocketData> data2( - new OrderedSocketData(reads2, arraysize(reads2), + scoped_refptr<DelayedSocketData> data2( + new DelayedSocketData(0, reads2, arraysize(reads2), writes2, arraysize(writes2))); - session_deps.socket_factory.AddSocketDataProvider(data); - session_deps.socket_factory.AddSocketDataProvider(data2); + + NormalSpdyTransactionHelper helper(CreateGetRequest(), + BoundNetLog()); + helper.AddData(data.get()); + helper.AddData(data2.get()); + helper.RunPreTestSetup(); + HttpNetworkTransaction* trans = helper.trans(); // Start the transaction with basic parameters. TestCompletionCallback callback; - int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); + int rv = trans->Start(&helper.request(), &callback, BoundNetLog()); EXPECT_EQ(ERR_IO_PENDING, rv); rv = callback.WaitForResult(); - StartTransactionCallback callback2(session); + StartTransactionCallback callback2(helper.session(), helper); const int kSize = 3000; scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(kSize); rv = trans->Read(buf, kSize, &callback2); + // This forces an err_IO_pending, which sets the callback. + data->CompleteRead(); + // This finishes the read. data->CompleteRead(); - data2->CompleteRead(); + helper.VerifyDataConsumed(); } -class DeleteSessionCallback : public CallbackRunner< Tuple1<int> > { +class SpdyNetworkTransactionTest::DeleteSessionCallback + : public CallbackRunner< Tuple1<int> > { public: - explicit DeleteSessionCallback(SpdyNetworkTransaction* trans1) : - trans(trans1) {} + explicit DeleteSessionCallback(NormalSpdyTransactionHelper& helper) : + helper_(helper) {} // We kill the transaction, which deletes the session and stream. virtual void RunWithParams(const Tuple1<int>& params) { - delete trans; + helper_.ResetTrans(); } private: - const SpdyNetworkTransaction* trans; + NormalSpdyTransactionHelper& helper_; }; // Verify that the client can correctly deal with the user callback deleting the @@ -531,31 +655,25 @@ TEST_F(SpdyNetworkTransactionTest, DeleteSessionOnReadCallback) { MockRead(true, 0, 0, 5), // EOF }; - HttpRequestInfo request; - request.method = "GET"; - request.url = GURL("http://www.google.com/"); - request.load_flags = 0; - - // We disable SSL for this test. - SpdySession::SetSSLMode(false); - - SessionDependencies session_deps; - SpdyNetworkTransaction * trans = - new SpdyNetworkTransaction(CreateSession(&session_deps)); scoped_refptr<OrderedSocketData> data( new OrderedSocketData(reads, arraysize(reads), writes, arraysize(writes))); - session_deps.socket_factory.AddSocketDataProvider(data); + + NormalSpdyTransactionHelper helper(CreateGetRequest(), + BoundNetLog()); + helper.AddData(data.get()); + helper.RunPreTestSetup(); + HttpNetworkTransaction* trans = helper.trans(); // Start the transaction with basic parameters. TestCompletionCallback callback; - int rv = trans->Start(&request, &callback, BoundNetLog()); + int rv = trans->Start(&helper.request(), &callback, BoundNetLog()); EXPECT_EQ(ERR_IO_PENDING, rv); rv = callback.WaitForResult(); // Setup a user callback which will delete the session, and clear out the // memory holding the stream object. Note that the callback deletes trans. - DeleteSessionCallback callback2(trans); + DeleteSessionCallback callback2(helper); const int kSize = 3000; scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(kSize); rv = trans->Read(buf, kSize, &callback2); @@ -564,6 +682,7 @@ TEST_F(SpdyNetworkTransactionTest, DeleteSessionOnReadCallback) { // Finish running rest of tasks. MessageLoop::current()->RunAllPending(); + helper.VerifyDataConsumed(); } // Verify that various SynReply headers parse correctly through the @@ -625,9 +744,11 @@ TEST_F(SpdyNetworkTransactionTest, SynReplyHeaders) { scoped_refptr<DelayedSocketData> data( new DelayedSocketData(1, reads, arraysize(reads), writes, arraysize(writes))); - TransactionHelperResult out = TransactionHelper(CreateGetRequest(), - data.get(), - BoundNetLog()); + NormalSpdyTransactionHelper helper(CreateGetRequest(), + BoundNetLog()); + helper.RunToCompletion(data.get()); + TransactionHelperResult out = helper.output(); + EXPECT_EQ(OK, out.rv); EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); EXPECT_EQ("hello!", out.response_data); @@ -770,9 +891,11 @@ TEST_F(SpdyNetworkTransactionTest, SynReplyHeadersVary) { scoped_refptr<DelayedSocketData> data( new DelayedSocketData(1, reads, arraysize(reads), writes, arraysize(writes))); - TransactionHelperResult out = TransactionHelper(request, - data.get(), - BoundNetLog()); + NormalSpdyTransactionHelper helper(request, + BoundNetLog()); + helper.RunToCompletion(data.get()); + TransactionHelperResult out = helper.output(); + EXPECT_EQ(OK, out.rv) << i; EXPECT_EQ("HTTP/1.1 200 OK", out.status_line) << i; EXPECT_EQ("hello!", out.response_data) << i; @@ -855,7 +978,6 @@ TEST_F(SpdyNetworkTransactionTest, InvalidSynReply) { scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0)); MockWrite writes[] = { CreateMockWrite(*req), - MockWrite(true, 0, 0) // EOF }; scoped_ptr<spdy::SpdyFrame> resp( @@ -873,9 +995,10 @@ TEST_F(SpdyNetworkTransactionTest, InvalidSynReply) { scoped_refptr<DelayedSocketData> data( new DelayedSocketData(1, reads, arraysize(reads), writes, arraysize(writes))); - TransactionHelperResult out = TransactionHelper(CreateGetRequest(), - data.get(), - BoundNetLog()); + NormalSpdyTransactionHelper helper(CreateGetRequest(), + BoundNetLog()); + helper.RunToCompletion(data.get()); + TransactionHelperResult out = helper.output(); EXPECT_EQ(ERR_INVALID_RESPONSE, out.rv); } } @@ -911,302 +1034,14 @@ TEST_F(SpdyNetworkTransactionTest, DISABLED_CorruptFrameSessionError) { scoped_refptr<DelayedSocketData> data( new DelayedSocketData(1, reads, arraysize(reads), writes, arraysize(writes))); - TransactionHelperResult out = TransactionHelper(CreateGetRequest(), - data.get(), - BoundNetLog()); + NormalSpdyTransactionHelper helper(CreateGetRequest(), + BoundNetLog()); + helper.RunToCompletion(data.get()); + TransactionHelperResult out = helper.output(); EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv); } } -// Server push: -// ------------ -// Client: Send the original SYN request. -// Server: Receive the SYN request. -// Server: Send a SYN reply, with X-Associated-Content and URL(s). -// Server: For each URL, send a SYN_STREAM with the URL and a stream ID, -// followed by one or more Data frames (the last one with a FIN). -// Client: Requests the URL(s). -// Client: Receives the SYN_STREAMs, and the associated Data frames, and -// associates the URLs with the incoming stream IDs. -// -// There are three possibilities when the client tries to send the second -// request (which doesn't make it to the wire): -// -// 1. The push data has arrived and is complete. -// 2. The push data has started arriving, but hasn't finished. -// 3. The push data has not yet arrived. - -// Enum for ServerPush. -enum TestTypes { - // Simulate that the server sends the first request, notifying the client - // that it *will* push the second stream. But the client issues the - // request for the second stream before the push data arrives. - PUSH_AFTER_REQUEST, - // Simulate that the server is sending the pushed stream data before the - // client requests it. The SpdySession will buffer the response and then - // deliver the data when the client does make the request. - PUSH_BEFORE_REQUEST, - // Simulate that the server is sending the pushed stream data before the - // client requests it, but the stream has not yet finished when the request - // occurs. The SpdySession will buffer the response and then deliver the - // data when the response is complete. - PUSH_DURING_REQUEST, - DONE -}; - -// Creates and processes a SpdyNetworkTransaction for server push, based on -// |session|. -// |data| holds the expected writes, and the reads. -// |url| is the web page we want. In pass 2, it contains the resource we expect -// to be pushed. -// |expected_data| is the data we expect to get in response. -// |test_type| is one of PUSH_AFTER_REQUEST, PUSH_BEFORE_REQUEST, or -// PUSH_DURING_REQUEST, indicating the type of test we're running. -// |pass| is 1 for the first request, and 2 for the request for the push data. -// |response| is the response information for the request. It will be used to -// verify the response time stamps. -static void MakeRequest(scoped_refptr<HttpNetworkSession> session, - scoped_refptr<OrderedSocketData> data, - const GURL& url, - const std::string& expected_data, - int test_type, - int pass, - HttpResponseInfo* response) { - SpdyNetworkTransaction trans(session.get()); - - HttpRequestInfo request; - request.method = "GET"; - request.url = url; - request.load_flags = 0; - TestCompletionCallback callback; - - // Allows the STOP_LOOP flag to work. - data->SetCompletionCallback(&callback); - // Sends a request. In pass 1, this goes on the wire; in pass 2, it is - // preempted by the push data. - int rv = trans.Start(&request, &callback, BoundNetLog()); - EXPECT_EQ(ERR_IO_PENDING, rv); - - // In the case where we are pushing beforehand, complete the next read now. - if ((pass == 2) && (test_type == PUSH_AFTER_REQUEST)) { - data->CompleteRead(); - } - - // Process messages until either a FIN or a STOP_LOOP is encountered. - rv = callback.WaitForResult(); - if ((pass == 2) && (test_type == PUSH_DURING_REQUEST)) { - // We should be in the middle of a request, so we're pending. - EXPECT_EQ(ERR_IO_PENDING, rv); - } else { - EXPECT_EQ(OK, rv); - } - - // Verify the SYN_REPLY. - // Copy the response info, because trans goes away - *response = *trans.GetResponseInfo(); - EXPECT_TRUE(response->headers != NULL); - EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); - - // In the case where we are Complete the next read now. - if (((pass == 1) && - ((test_type == PUSH_BEFORE_REQUEST) || - (test_type == PUSH_DURING_REQUEST)))) { - data->CompleteRead(); - } - - // Verify the body. - std::string response_data; - rv = ReadTransaction(&trans, &response_data); - EXPECT_EQ(OK, rv); - EXPECT_EQ(expected_data, response_data); - // Remove callback, so that if another STOP_LOOP occurs, there is no crash. - data->SetCompletionCallback(NULL); -} - -TEST_F(SpdyNetworkTransactionTest, ServerPush) { - spdy::SpdyFramer framer; - - // Reply with the X-Associated-Content header. - const char* const kSynReplyHeaders[] = { - "x-associated-content", "1??http://www.google.com/foo.dat", - }; - scoped_ptr<spdy::SpdyFrame> syn_reply( - ConstructSpdyGetSynReply(kSynReplyHeaders, 1)); - - const char* const kSynPushHeaders[] = { - "path", "/foo.dat", - "status", "200", - "url", "/foo.dat", - "version", "HTTP/1.1", - }; - spdy::SpdyHeaderBlock headers; - AppendHeadersToSpdyFrame(kSynPushHeaders, 4, &headers); - scoped_ptr<spdy::SpdyFrame> syn_push( - framer.CreateSynStream(2, // Stream ID - 0, // Associated stream ID - SPDY_PRIORITY_LOWEST, - spdy::CONTROL_FLAG_NONE, - false, - &headers)); - - // Body for stream 2 - const char syn_body_data1[] = "hello"; - const char syn_body_data2[] = "hello my darling hello my baby"; - const char* syn_body_data = NULL; - - scoped_ptr<spdy::SpdyFrame> push_body_frame( - framer.CreateDataFrame(2, syn_body_data1, strlen(syn_body_data1), - spdy::DATA_FLAG_FIN)); - scoped_ptr<spdy::SpdyFrame> push_body_frame1( - framer.CreateDataFrame(2, syn_body_data2, strlen(syn_body_data2), - spdy::DATA_FLAG_FIN)); - - scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0)); - MockWrite writes[] = { CreateMockWrite(*req) }; - - // This array is for request before and after push is received. The push - // body is only one 'packet', to allow the initial transaction to read all - // the push data before . - scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame()); - MockRead reads1[] = { - CreateMockRead(*syn_reply.get(), 2), // 0 - CreateMockRead(*body.get(), 1), // 1 - MockRead(true, ERR_IO_PENDING, 4), // Force a pause // 2 - CreateMockRead(*syn_push.get(), 5), // 3 - CreateMockRead(*push_body_frame.get(), 6), // 4 - MockRead(true, ERR_IO_PENDING, 7), // Force a pause // 5 - MockRead(true, 0, 0, 8) // EOF // 6 - }; - - // This array is for request while push is being received. It extends - // the push body so we can 'interrupt' it. - scoped_array<MockRead> chopped_reads( - ChopReadFrame(*push_body_frame1.get(), 4)); - chopped_reads[0].sequence_number = 5; - // Force a pause by skipping a sequence number. - chopped_reads[1].sequence_number = 7; - chopped_reads[2].sequence_number = 8; - chopped_reads[3].sequence_number = 9; - MockRead reads2[] = { - CreateMockRead(*syn_reply.get(), 2), // 0 - CreateMockRead(*body.get(), 3), // 1 - CreateMockRead(*syn_push.get(), 4), // 2 - chopped_reads[0], // 3 - chopped_reads[1], // 4 - chopped_reads[2], // 5 - chopped_reads[3], // 6 - MockRead(true, ERR_IO_PENDING, MockRead::STOPLOOP | 10), // 7 - // So we can do a final CompleteRead(), which cleans up memory. - MockRead(true, NULL, 0, 11) // 8 - }; - - // We disable SSL for this test. - SpdySession::SetSSLMode(false); - - base::Time zero_time = base::Time::FromInternalValue(0); - for (int test_type = PUSH_AFTER_REQUEST; test_type < DONE; ++test_type) { - DLOG(INFO) << "Test " << test_type; - - // Select the data to use. - MockRead* reads = NULL; - size_t num_reads = 0; - size_t num_writes = arraysize(writes); - int first_push_data_frame = 0; - if (test_type == PUSH_DURING_REQUEST) { - reads = reads2; - num_reads = arraysize(reads2); - syn_body_data = syn_body_data2; - first_push_data_frame = 3; - } else { - reads = reads1; - num_reads = arraysize(reads1); - syn_body_data = syn_body_data1; - first_push_data_frame = 4; - } - // Clear timestamp data - for (size_t w = 0; w < num_writes; ++w) { - writes[w].time_stamp = zero_time; - } - for (size_t r = 0; r < num_reads; ++r) { - reads[r].time_stamp = zero_time; - } - - // Setup a mock session. - SessionDependencies session_deps; - scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); - scoped_refptr<OrderedSocketData> data( - new OrderedSocketData(reads, num_reads, writes, num_writes)); - session_deps.socket_factory.AddSocketDataProvider(data.get()); - HttpResponseInfo response1; - HttpResponseInfo response2; - - DLOG(INFO) << "Sending request 1"; - - // Issue the first request. - MakeRequest(session, - data, - GURL("http://www.google.com/"), - "hello!", - test_type, - 1, - &response1); - - DLOG(INFO) << "Sending X-Associated-Content request"; - - // This value should be set to something later than the one in - // 'response1.request_time'. - base::Time request1_time = writes[0].time_stamp; - // We don't have a |writes| entry for the second request, - // so put in Now() as the request time. It's not as accurate, - // but it will work. - base::Time request2_time = base::Time::Now(); - - // Issue a second request for the X-Associated-Content. - MakeRequest(session, - data, - GURL("http://www.google.com/foo.dat"), - syn_body_data, - test_type, - 2, - &response2); - - // Complete the next read now and teardown. - data->CompleteRead(); - - // Verify that we consumed all test data. - EXPECT_TRUE(data->at_read_eof()); - EXPECT_TRUE(data->at_write_eof()); - - // Check the timings - - // Verify that all the time stamps were set. - EXPECT_GE(response1.request_time.ToInternalValue(), - zero_time.ToInternalValue()); - EXPECT_GE(response2.request_time.ToInternalValue(), - zero_time.ToInternalValue()); - EXPECT_GE(response1.response_time.ToInternalValue(), - zero_time.ToInternalValue()); - EXPECT_GE(response2.response_time.ToInternalValue(), - zero_time.ToInternalValue()); - - // Verify that the values make sense. - // First request. - EXPECT_LE(response1.request_time.ToInternalValue(), - request1_time.ToInternalValue()); - EXPECT_LE(response1.response_time.ToInternalValue(), - reads[1].time_stamp.ToInternalValue()); - - // Push request. - EXPECT_GE(response2.request_time.ToInternalValue(), - request2_time.ToInternalValue()); - // The response time should be between the server push SYN and DATA. - EXPECT_GE(response2.response_time.ToInternalValue(), - reads[first_push_data_frame - 1].time_stamp.ToInternalValue()); - EXPECT_LE(response2.response_time.ToInternalValue(), - reads[first_push_data_frame].time_stamp.ToInternalValue()); - } -} - // Test that we shutdown correctly on write errors. TEST_F(SpdyNetworkTransactionTest, WriteError) { scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0)); @@ -1215,23 +1050,15 @@ TEST_F(SpdyNetworkTransactionTest, WriteError) { MockWrite(true, req->data(), 10), // Followed by ERROR! MockWrite(true, ERR_FAILED), - MockWrite(true, 0, 0) // EOF - }; - - scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0)); - scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame()); - MockRead reads[] = { - CreateMockRead(*resp.get(), 2), - CreateMockRead(*body), - MockRead(true, 0, 0) // EOF }; scoped_refptr<DelayedSocketData> data( - new DelayedSocketData(2, reads, arraysize(reads), + new DelayedSocketData(2, NULL, 0, writes, arraysize(writes))); - TransactionHelperResult out = TransactionHelper(CreateGetRequest(), - data.get(), - BoundNetLog()); + NormalSpdyTransactionHelper helper(CreateGetRequest(), + BoundNetLog()); + helper.RunToCompletion(data.get()); + TransactionHelperResult out = helper.output(); EXPECT_EQ(ERR_FAILED, out.rv); data->Reset(); } @@ -1254,47 +1081,15 @@ TEST_F(SpdyNetworkTransactionTest, PartialWrite) { scoped_refptr<DelayedSocketData> data( new DelayedSocketData(kChunks, reads, arraysize(reads), writes.get(), kChunks)); - TransactionHelperResult out = TransactionHelper(CreateGetRequest(), - data.get(), - BoundNetLog()); + NormalSpdyTransactionHelper helper(CreateGetRequest(), + BoundNetLog()); + helper.RunToCompletion(data.get()); + TransactionHelperResult out = helper.output(); EXPECT_EQ(OK, out.rv); EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); EXPECT_EQ("hello!", out.response_data); } -TEST_F(SpdyNetworkTransactionTest, ConnectFailure) { - MockConnect connects[] = { - MockConnect(true, ERR_NAME_NOT_RESOLVED), - MockConnect(false, ERR_NAME_NOT_RESOLVED), - MockConnect(true, ERR_INTERNET_DISCONNECTED), - MockConnect(false, ERR_INTERNET_DISCONNECTED) - }; - - for (size_t index = 0; index < arraysize(connects); ++index) { - scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0)); - MockWrite writes[] = { - CreateMockWrite(*req), - MockWrite(true, 0, 0) // EOF - }; - - scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0)); - scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame()); - MockRead reads[] = { - CreateMockRead(*resp), - CreateMockRead(*body), - MockRead(true, 0, 0) // EOF - }; - - scoped_refptr<DelayedSocketData> data( - new DelayedSocketData(connects[index], 1, reads, arraysize(reads), - writes, arraysize(writes))); - TransactionHelperResult out = TransactionHelper(CreateGetRequest(), - data.get(), - BoundNetLog()); - EXPECT_EQ(connects[index].result, out.rv); - } -} - // In this test, we enable compression, but get a uncompressed SynReply from // the server. Verify that teardown is all clean. TEST_F(SpdyNetworkTransactionTest, DecompressFailureOnSynReply) { @@ -1304,7 +1099,6 @@ TEST_F(SpdyNetworkTransactionTest, DecompressFailureOnSynReply) { scoped_ptr<spdy::SpdyFrame> compressed(ConstructSpdyGet(NULL, 0, true)); MockWrite writes[] = { CreateMockWrite(*compressed), - MockWrite(true, 0, 0) // EOF }; scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0)); @@ -1318,9 +1112,10 @@ TEST_F(SpdyNetworkTransactionTest, DecompressFailureOnSynReply) { scoped_refptr<DelayedSocketData> data( new DelayedSocketData(1, reads, arraysize(reads), writes, arraysize(writes))); - TransactionHelperResult out = TransactionHelper(CreateGetRequest(), - data.get(), - BoundNetLog()); + NormalSpdyTransactionHelper helper(CreateGetRequest(), + BoundNetLog()); + helper.RunToCompletion(data.get()); + TransactionHelperResult out = helper.output(); EXPECT_EQ(ERR_SYN_REPLY_NOT_RECEIVED, out.rv); data->Reset(); @@ -1345,27 +1140,21 @@ TEST_F(SpdyNetworkTransactionTest, NetLog) { scoped_refptr<DelayedSocketData> data( new DelayedSocketData(1, reads, arraysize(reads), writes, arraysize(writes))); - TransactionHelperResult out = TransactionHelper(CreateGetRequest(), - data.get(), - log.bound()); + NormalSpdyTransactionHelper helper(CreateGetRequest(), + log.bound()); + helper.RunToCompletion(data.get()); + TransactionHelperResult out = helper.output(); EXPECT_EQ(OK, out.rv); EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); EXPECT_EQ("hello!", out.response_data); // Check that the NetLog was filled reasonably. - // This test is intentionally non-specific about the exact ordering of - // the log; instead we just check to make sure that certain events exist. + // This test is intentionally non-specific about the exact ordering of the + // log; instead we just check to make sure that certain events exist, and that + // they are in the right order. EXPECT_LT(0u, log.entries().size()); int pos = 0; - // We know the first event at position 0. - EXPECT_TRUE(net::LogContainsBeginEvent( - log.entries(), 0, net::NetLog::TYPE_SPDY_TRANSACTION_INIT_CONNECTION)); - // For the rest of the events, allow additional events in the middle, - // but expect these to be logged in order. pos = net::ExpectLogContainsSomewhere(log.entries(), 0, - net::NetLog::TYPE_SPDY_TRANSACTION_INIT_CONNECTION, - net::NetLog::PHASE_END); - pos = net::ExpectLogContainsSomewhere(log.entries(), pos + 1, net::NetLog::TYPE_SPDY_TRANSACTION_SEND_REQUEST, net::NetLog::PHASE_BEGIN); pos = net::ExpectLogContainsSomewhere(log.entries(), pos + 1, @@ -1425,25 +1214,18 @@ TEST_F(SpdyNetworkTransactionTest, BufferFull) { new DelayedSocketData(1, reads, arraysize(reads), writes, arraysize(writes))); - // For this test, we can't use the TransactionHelper, because we are - // going to tightly control how the IOs fly. - - TransactionHelperResult out; - - // We disable SSL for this test. - SpdySession::SetSSLMode(false); - - SessionDependencies session_deps; - scoped_ptr<SpdyNetworkTransaction> trans( - new SpdyNetworkTransaction(CreateSession(&session_deps))); - - session_deps.socket_factory.AddSocketDataProvider(data); TestCompletionCallback callback; + NormalSpdyTransactionHelper helper(CreateGetRequest(), + BoundNetLog()); + helper.AddData(data.get()); + helper.RunPreTestSetup(); + HttpNetworkTransaction* trans = helper.trans(); int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); EXPECT_EQ(ERR_IO_PENDING, rv); + TransactionHelperResult out = helper.output(); out.rv = callback.WaitForResult(); EXPECT_EQ(out.rv, OK); @@ -1479,10 +1261,8 @@ TEST_F(SpdyNetworkTransactionTest, BufferFull) { // MockClientSocketFactory) are still alive. MessageLoop::current()->RunAllPending(); - // Verify that we consumed all test data. - EXPECT_TRUE(data->at_read_eof()); - EXPECT_TRUE(data->at_write_eof()); + helper.VerifyDataConsumed(); EXPECT_EQ(OK, out.rv); EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); @@ -1526,25 +1306,17 @@ TEST_F(SpdyNetworkTransactionTest, Buffering) { new DelayedSocketData(1, reads, arraysize(reads), writes, arraysize(writes))); - // For this test, we can't use the TransactionHelper, because we are - // going to tightly control how the IOs fly. - - TransactionHelperResult out; - - // We disable SSL for this test. - SpdySession::SetSSLMode(false); - - SessionDependencies session_deps; - scoped_ptr<SpdyNetworkTransaction> trans( - new SpdyNetworkTransaction(CreateSession(&session_deps))); - - session_deps.socket_factory.AddSocketDataProvider(data); + NormalSpdyTransactionHelper helper(CreateGetRequest(), + BoundNetLog()); + helper.AddData(data.get()); + helper.RunPreTestSetup(); + HttpNetworkTransaction* trans = helper.trans(); TestCompletionCallback callback; - int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); EXPECT_EQ(ERR_IO_PENDING, rv); + TransactionHelperResult out = helper.output(); out.rv = callback.WaitForResult(); EXPECT_EQ(out.rv, OK); @@ -1586,8 +1358,7 @@ TEST_F(SpdyNetworkTransactionTest, Buffering) { MessageLoop::current()->RunAllPending(); // Verify that we consumed all test data. - EXPECT_TRUE(data->at_read_eof()); - EXPECT_TRUE(data->at_write_eof()); + helper.VerifyDataConsumed(); EXPECT_EQ(OK, out.rv); EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); @@ -1630,25 +1401,17 @@ TEST_F(SpdyNetworkTransactionTest, BufferedAll) { new DelayedSocketData(1, reads, arraysize(reads), writes, arraysize(writes))); - // For this test, we can't use the TransactionHelper, because we are - // going to tightly control how the IOs fly. - - TransactionHelperResult out; - - // We disable SSL for this test. - SpdySession::SetSSLMode(false); - - SessionDependencies session_deps; - scoped_ptr<SpdyNetworkTransaction> trans( - new SpdyNetworkTransaction(CreateSession(&session_deps))); - - session_deps.socket_factory.AddSocketDataProvider(data); + NormalSpdyTransactionHelper helper(CreateGetRequest(), + BoundNetLog()); + helper.AddData(data.get()); + helper.RunPreTestSetup(); + HttpNetworkTransaction* trans = helper.trans(); TestCompletionCallback callback; - int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); EXPECT_EQ(ERR_IO_PENDING, rv); + TransactionHelperResult out = helper.output(); out.rv = callback.WaitForResult(); EXPECT_EQ(out.rv, OK); @@ -1686,8 +1449,7 @@ TEST_F(SpdyNetworkTransactionTest, BufferedAll) { MessageLoop::current()->RunAllPending(); // Verify that we consumed all test data. - EXPECT_TRUE(data->at_read_eof()); - EXPECT_TRUE(data->at_write_eof()); + helper.VerifyDataConsumed(); EXPECT_EQ(OK, out.rv); EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); @@ -1727,25 +1489,18 @@ TEST_F(SpdyNetworkTransactionTest, BufferedClosed) { new DelayedSocketData(1, reads, arraysize(reads), writes, arraysize(writes))); - // For this test, we can't use the TransactionHelper, because we are - // going to tightly control how the IOs fly. - - TransactionHelperResult out; - - // We disable SSL for this test. - SpdySession::SetSSLMode(false); - - SessionDependencies session_deps; - scoped_ptr<SpdyNetworkTransaction> trans( - new SpdyNetworkTransaction(CreateSession(&session_deps))); - - session_deps.socket_factory.AddSocketDataProvider(data); + NormalSpdyTransactionHelper helper(CreateGetRequest(), + BoundNetLog()); + helper.AddData(data.get()); + helper.RunPreTestSetup(); + HttpNetworkTransaction* trans = helper.trans(); TestCompletionCallback callback; int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); EXPECT_EQ(ERR_IO_PENDING, rv); + TransactionHelperResult out = helper.output(); out.rv = callback.WaitForResult(); EXPECT_EQ(out.rv, OK); @@ -1788,8 +1543,7 @@ TEST_F(SpdyNetworkTransactionTest, BufferedClosed) { MessageLoop::current()->RunAllPending(); // Verify that we consumed all test data. - EXPECT_TRUE(data->at_read_eof()); - EXPECT_TRUE(data->at_write_eof()); + helper.VerifyDataConsumed(); } // Verify the case where we buffer data and cancel the transaction. @@ -1815,24 +1569,17 @@ TEST_F(SpdyNetworkTransactionTest, BufferedCancelled) { new DelayedSocketData(1, reads, arraysize(reads), writes, arraysize(writes))); - // For this test, we can't use the TransactionHelper, because we are - // going to tightly control how the IOs fly. - TransactionHelperResult out; - - // We disable SSL for this test. - SpdySession::SetSSLMode(false); - - SessionDependencies session_deps; - scoped_ptr<SpdyNetworkTransaction> trans( - new SpdyNetworkTransaction(CreateSession(&session_deps))); - - session_deps.socket_factory.AddSocketDataProvider(data); - + NormalSpdyTransactionHelper helper(CreateGetRequest(), + BoundNetLog()); + helper.AddData(data.get()); + helper.RunPreTestSetup(); + HttpNetworkTransaction* trans = helper.trans(); TestCompletionCallback callback; int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog()); EXPECT_EQ(ERR_IO_PENDING, rv); + TransactionHelperResult out = helper.output(); out.rv = callback.WaitForResult(); EXPECT_EQ(out.rv, OK); @@ -1854,7 +1601,7 @@ TEST_F(SpdyNetworkTransactionTest, BufferedCancelled) { data->CompleteRead(); // Destroy the transaction, causing the stream to get cancelled // and orphaning the buffered IO task. - trans.reset(); + helper.ResetTrans(); break; } // We shouldn't get here in this test. @@ -1864,6 +1611,9 @@ TEST_F(SpdyNetworkTransactionTest, BufferedCancelled) { // Flush the MessageLoop; this will cause the buffered IO task // to run for the final time. MessageLoop::current()->RunAllPending(); + + // Verify that we consumed all test data. + helper.VerifyDataConsumed(); } // Test that if the server requests persistence of settings, that we save @@ -1886,12 +1636,12 @@ TEST_F(SpdyNetworkTransactionTest, SettingsSaved) { "version", "HTTP/1.1" }; - SessionDependencies session_deps; - scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); + NormalSpdyTransactionHelper helper(CreateGetRequest(), + BoundNetLog()); // Verify that no settings exist initially. - HostPortPair host_port_pair("www.google.com", 80); - EXPECT_TRUE(session->spdy_settings().Get(host_port_pair).empty()); + HostPortPair host_port_pair("www.google.com", 443); + EXPECT_TRUE(helper.session()->spdy_settings().Get(host_port_pair).empty()); // Construct the request. scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0)); @@ -1942,9 +1692,8 @@ TEST_F(SpdyNetworkTransactionTest, SettingsSaved) { scoped_refptr<DelayedSocketData> data( new DelayedSocketData(1, reads, arraysize(reads), writes, arraysize(writes))); - TransactionHelperResult out = TransactionHelperWithSession( - CreateGetRequest(), data.get(), BoundNetLog(), - &session_deps, session.get()); + helper.RunToCompletion(data.get()); + TransactionHelperResult out = helper.output(); EXPECT_EQ(OK, out.rv); EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); EXPECT_EQ("hello!", out.response_data); @@ -1952,7 +1701,7 @@ TEST_F(SpdyNetworkTransactionTest, SettingsSaved) { { // Verify we had two persisted settings. spdy::SpdySettings saved_settings = - session->spdy_settings().Get(host_port_pair); + helper.session()->spdy_settings().Get(host_port_pair); ASSERT_EQ(2u, saved_settings.size()); // Verify the first persisted setting. @@ -1991,12 +1740,12 @@ TEST_F(SpdyNetworkTransactionTest, SettingsPlayback) { "version", "HTTP/1.1" }; - SessionDependencies session_deps; - scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); + NormalSpdyTransactionHelper helper(CreateGetRequest(), + BoundNetLog()); // Verify that no settings exist initially. - HostPortPair host_port_pair("www.google.com", 80); - EXPECT_TRUE(session->spdy_settings().Get(host_port_pair).empty()); + HostPortPair host_port_pair("www.google.com", 443); + EXPECT_TRUE(helper.session()->spdy_settings().Get(host_port_pair).empty()); unsigned int kSampleId1 = 0x1; unsigned int kSampleValue1 = 0x0a0a0a0a; @@ -2015,14 +1764,14 @@ TEST_F(SpdyNetworkTransactionTest, SettingsPlayback) { setting.set_id(kSampleId2); settings.push_back(std::make_pair(setting, kSampleValue2)); - session->mutable_spdy_settings()->Set(host_port_pair, settings); + helper.session()->mutable_spdy_settings()->Set(host_port_pair, settings); } - EXPECT_EQ(2u, session->spdy_settings().Get(host_port_pair).size()); + EXPECT_EQ(2u, helper.session()->spdy_settings().Get(host_port_pair).size()); // Construct the SETTINGS frame. const spdy::SpdySettings& settings = - session->spdy_settings().Get(host_port_pair); + helper.session()->spdy_settings().Get(host_port_pair); scoped_ptr<spdy::SpdyFrame> settings_frame(ConstructSpdySettings(settings)); // Construct the request. @@ -2051,9 +1800,8 @@ TEST_F(SpdyNetworkTransactionTest, SettingsPlayback) { scoped_refptr<DelayedSocketData> data( new DelayedSocketData(2, reads, arraysize(reads), writes, arraysize(writes))); - TransactionHelperResult out = TransactionHelperWithSession( - CreateGetRequest(), data.get(), BoundNetLog(), - &session_deps, session.get()); + helper.RunToCompletion(data.get()); + TransactionHelperResult out = helper.output(); EXPECT_EQ(OK, out.rv); EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); EXPECT_EQ("hello!", out.response_data); @@ -2061,7 +1809,7 @@ TEST_F(SpdyNetworkTransactionTest, SettingsPlayback) { { // Verify we had two persisted settings. spdy::SpdySettings saved_settings = - session->spdy_settings().Get(host_port_pair); + helper.session()->spdy_settings().Get(host_port_pair); ASSERT_EQ(2u, saved_settings.size()); // Verify the first persisted setting. @@ -2093,9 +1841,10 @@ TEST_F(SpdyNetworkTransactionTest, GoAwayWithActiveStream) { scoped_refptr<DelayedSocketData> data( new DelayedSocketData(1, reads, arraysize(reads), writes, arraysize(writes))); - TransactionHelperResult out = TransactionHelper(CreateGetRequest(), - data.get(), - BoundNetLog()); + NormalSpdyTransactionHelper helper(CreateGetRequest(), + BoundNetLog()); + helper.RunToCompletion(data.get()); + TransactionHelperResult out = helper.output(); EXPECT_EQ(ERR_CONNECTION_CLOSED, out.rv); } @@ -2112,22 +1861,17 @@ TEST_F(SpdyNetworkTransactionTest, CloseWithActiveStream) { scoped_refptr<DelayedSocketData> data( new DelayedSocketData(1, reads, arraysize(reads), writes, arraysize(writes))); - TransactionHelperResult out; - - // We disable SSL for this test. - SpdySession::SetSSLMode(false); - BoundNetLog log; - SessionDependencies session_deps; - HttpNetworkSession* session = CreateSession(&session_deps); - scoped_ptr<SpdyNetworkTransaction> trans( - new SpdyNetworkTransaction(session)); - - session_deps.socket_factory.AddSocketDataProvider(data); + NormalSpdyTransactionHelper helper(CreateGetRequest(), + log); + helper.AddData(data.get()); + helper.RunPreTestSetup(); + HttpNetworkTransaction* trans = helper.trans(); TestCompletionCallback callback; - + TransactionHelperResult out; out.rv = trans->Start(&CreateGetRequest(), &callback, log); + EXPECT_EQ(out.rv, ERR_IO_PENDING); out.rv = callback.WaitForResult(); EXPECT_EQ(out.rv, OK); @@ -2135,12 +1879,11 @@ TEST_F(SpdyNetworkTransactionTest, CloseWithActiveStream) { const HttpResponseInfo* response = trans->GetResponseInfo(); EXPECT_TRUE(response->headers != NULL); EXPECT_TRUE(response->was_fetched_via_spdy); - out.rv = ReadTransaction(trans.get(), &out.response_data); + out.rv = ReadTransaction(trans, &out.response_data); EXPECT_EQ(ERR_CONNECTION_CLOSED, out.rv); // Verify that we consumed all test data. - EXPECT_TRUE(data->at_read_eof()); - EXPECT_TRUE(data->at_write_eof()); + helper.VerifyDataConsumed(); } } // namespace net |