summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-12 03:38:43 +0000
committerakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-12 03:38:43 +0000
commit6fe2e9952f1eb1ca1e52bb1f1080577f10772474 (patch)
tree66a591f3884a3e7b427246cc8a6cbdeef49be035
parent1ead4aab1101e2c48b2c65a83dd8c873b253871b (diff)
downloadchromium_src-6fe2e9952f1eb1ca1e52bb1f1080577f10772474.zip
chromium_src-6fe2e9952f1eb1ca1e52bb1f1080577f10772474.tar.gz
chromium_src-6fe2e9952f1eb1ca1e52bb1f1080577f10772474.tar.bz2
[SPDY] Merge the SpdyHttpStream unit tests and parametrize them on a NextProto
Add (partial) support for SPDY/3.1 and SPDY/4a2 for SpdyHttpStream unit tests. BUG=226192 R=rch@chromium.org Review URL: https://codereview.chromium.org/16705004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@205702 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--net/net.gyp3
-rw-r--r--net/spdy/spdy_http_stream_spdy2_unittest.cc540
-rw-r--r--net/spdy/spdy_http_stream_unittest.cc (renamed from net/spdy/spdy_http_stream_spdy3_unittest.cc)197
-rw-r--r--net/spdy/spdy_session_unittest.cc1
-rw-r--r--net/spdy/spdy_stream_unittest.cc1
5 files changed, 99 insertions, 643 deletions
diff --git a/net/net.gyp b/net/net.gyp
index 62839f2..096dab0 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -1754,8 +1754,7 @@
'spdy/spdy_frame_reader_test.cc',
'spdy/spdy_framer_test.cc',
'spdy/spdy_header_block_unittest.cc',
- 'spdy/spdy_http_stream_spdy3_unittest.cc',
- 'spdy/spdy_http_stream_spdy2_unittest.cc',
+ 'spdy/spdy_http_stream_unittest.cc',
'spdy/spdy_http_utils_unittest.cc',
'spdy/spdy_network_transaction_spdy3_unittest.cc',
'spdy/spdy_network_transaction_spdy2_unittest.cc',
diff --git a/net/spdy/spdy_http_stream_spdy2_unittest.cc b/net/spdy/spdy_http_stream_spdy2_unittest.cc
deleted file mode 100644
index 581d530..0000000
--- a/net/spdy/spdy_http_stream_spdy2_unittest.cc
+++ /dev/null
@@ -1,540 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/spdy/spdy_http_stream.h"
-
-#include "crypto/ec_private_key.h"
-#include "crypto/ec_signature_creator.h"
-#include "crypto/signature_creator.h"
-#include "net/base/capturing_net_log.h"
-#include "net/base/load_timing_info.h"
-#include "net/base/load_timing_info_test_util.h"
-#include "net/base/upload_data_stream.h"
-#include "net/base/upload_element_reader.h"
-#include "net/cert/asn1_util.h"
-#include "net/http/http_request_info.h"
-#include "net/http/http_response_headers.h"
-#include "net/http/http_response_info.h"
-#include "net/socket/next_proto.h"
-#include "net/spdy/spdy_session.h"
-#include "net/spdy/spdy_test_util_spdy2.h"
-#include "net/ssl/default_server_bound_cert_store.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using namespace net::test_spdy2;
-
-namespace net {
-
-namespace {
-
-// Tests the load timing of a stream that's connected and is not the first
-// request sent on a connection.
-void TestLoadTimingReused(const HttpStream& stream) {
- LoadTimingInfo load_timing_info;
- EXPECT_TRUE(stream.GetLoadTimingInfo(&load_timing_info));
-
- EXPECT_TRUE(load_timing_info.socket_reused);
- EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
-
- ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
- ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
-}
-
-// Tests the load timing of a stream that's connected and using a fresh
-// connection.
-void TestLoadTimingNotReused(const HttpStream& stream) {
- LoadTimingInfo load_timing_info;
- EXPECT_TRUE(stream.GetLoadTimingInfo(&load_timing_info));
-
- EXPECT_FALSE(load_timing_info.socket_reused);
- EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
-
- ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
- CONNECT_TIMING_HAS_DNS_TIMES);
- ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
-}
-
-} // namespace
-
-class SpdyHttpStreamSpdy2Test : public testing::Test {
- public:
- SpdyHttpStreamSpdy2Test()
- : spdy_util_(kProtoSPDY2),
- session_deps_(kProtoSPDY2) {
- session_deps_.net_log = &net_log_;
- }
-
- DeterministicSocketData* deterministic_data() {
- return deterministic_data_.get();
- }
-
- OrderedSocketData* data() { return data_.get(); }
-
- protected:
- virtual void TearDown() OVERRIDE {
- crypto::ECSignatureCreator::SetFactoryForTesting(NULL);
- base::MessageLoop::current()->RunUntilIdle();
- }
-
- // Initializes the session using DeterministicSocketData. It's advisable
- // to use this function rather than the OrderedSocketData, since the
- // DeterministicSocketData behaves in a reasonable manner.
- int InitSessionDeterministic(MockRead* reads, size_t reads_count,
- MockWrite* writes, size_t writes_count,
- HostPortPair& host_port_pair) {
- SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
- kPrivacyModeDisabled);
- deterministic_data_.reset(
- new DeterministicSocketData(reads, reads_count, writes, writes_count));
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(
- deterministic_data_.get());
- http_session_ =
- SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_);
- session_ = http_session_->spdy_session_pool()->Get(key, BoundNetLog());
- transport_params_ = new TransportSocketParams(host_port_pair,
- MEDIUM, false, false,
- OnHostResolutionCallback());
- TestCompletionCallback callback;
- scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
- EXPECT_EQ(ERR_IO_PENDING,
- connection->Init(host_port_pair.ToString(),
- transport_params_,
- MEDIUM,
- callback.callback(),
- http_session_->GetTransportSocketPool(
- HttpNetworkSession::NORMAL_SOCKET_POOL),
- BoundNetLog()));
- EXPECT_EQ(OK, callback.WaitForResult());
- return session_->InitializeWithSocket(connection.release(), false, OK);
- }
-
- // Initializes the session using the finicky OrderedSocketData class.
- int InitSession(MockRead* reads, size_t reads_count,
- MockWrite* writes, size_t writes_count,
- HostPortPair& host_port_pair) {
- SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
- kPrivacyModeDisabled);
- data_.reset(new OrderedSocketData(reads, reads_count,
- writes, writes_count));
- session_deps_.socket_factory->AddSocketDataProvider(data_.get());
- http_session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
- session_ = http_session_->spdy_session_pool()->Get(key, BoundNetLog());
- transport_params_ = new TransportSocketParams(host_port_pair,
- MEDIUM, false, false,
- OnHostResolutionCallback());
- TestCompletionCallback callback;
- scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
- EXPECT_EQ(ERR_IO_PENDING,
- connection->Init(host_port_pair.ToString(),
- transport_params_,
- MEDIUM,
- callback.callback(),
- http_session_->GetTransportSocketPool(
- HttpNetworkSession::NORMAL_SOCKET_POOL),
- BoundNetLog()));
- EXPECT_EQ(OK, callback.WaitForResult());
- return session_->InitializeWithSocket(connection.release(), false, OK);
- }
-
- SpdyTestUtil spdy_util_;
- CapturingNetLog net_log_;
- SpdySessionDependencies session_deps_;
- scoped_ptr<OrderedSocketData> data_;
- scoped_ptr<DeterministicSocketData> deterministic_data_;
- scoped_refptr<HttpNetworkSession> http_session_;
- scoped_refptr<SpdySession> session_;
- scoped_refptr<TransportSocketParams> transport_params_;
-};
-
-// SpdyHttpStream::GetUploadProgress() should still work even before the
-// stream is initialized.
-TEST_F(SpdyHttpStreamSpdy2Test, GetUploadProgressBeforeInitialization) {
- SpdyHttpStream stream(NULL, false);
- UploadProgress progress = stream.GetUploadProgress();
- EXPECT_EQ(0u, progress.size());
- EXPECT_EQ(0u, progress.position());
-}
-
-TEST_F(SpdyHttpStreamSpdy2Test, SendRequest) {
- scoped_ptr<SpdyFrame> req(
- spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
- MockWrite writes[] = {
- CreateMockWrite(*req.get(), 1),
- };
- scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
- MockRead reads[] = {
- CreateMockRead(*resp, 2),
- MockRead(SYNCHRONOUS, 0, 3) // EOF
- };
-
- HostPortPair host_port_pair("www.google.com", 80);
- SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
- kPrivacyModeDisabled);
- EXPECT_EQ(OK, InitSession(reads, arraysize(reads), writes, arraysize(writes),
- host_port_pair));
-
- HttpRequestInfo request;
- request.method = "GET";
- request.url = GURL("http://www.google.com/");
- TestCompletionCallback callback;
- HttpResponseInfo response;
- HttpRequestHeaders headers;
- BoundNetLog net_log;
- scoped_ptr<SpdyHttpStream> http_stream(
- new SpdyHttpStream(session_.get(), true));
- // Make sure getting load timing information the stream early does not crash.
- LoadTimingInfo load_timing_info;
- EXPECT_FALSE(http_stream->GetLoadTimingInfo(&load_timing_info));
-
- ASSERT_EQ(
- OK,
- http_stream->InitializeStream(&request, DEFAULT_PRIORITY,
- net_log, CompletionCallback()));
- EXPECT_FALSE(http_stream->GetLoadTimingInfo(&load_timing_info));
-
- EXPECT_EQ(ERR_IO_PENDING, http_stream->SendRequest(headers, &response,
- callback.callback()));
- EXPECT_TRUE(http_session_->spdy_session_pool()->HasSession(key));
- EXPECT_FALSE(http_stream->GetLoadTimingInfo(&load_timing_info));
-
- // This triggers the MockWrite and read 2
- callback.WaitForResult();
-
- // Can get timing information once the stream connects.
- TestLoadTimingNotReused(*http_stream);
-
- // This triggers read 3. The empty read causes the session to shut down.
- data()->CompleteRead();
-
- // Because we abandoned the stream, we don't expect to find a session in the
- // pool anymore.
- EXPECT_FALSE(http_session_->spdy_session_pool()->HasSession(key));
- EXPECT_TRUE(data()->at_read_eof());
- EXPECT_TRUE(data()->at_write_eof());
-
- TestLoadTimingNotReused(*http_stream);
- http_stream->Close(true);
- // Test that there's no crash when trying to get the load timing after the
- // stream has been closed.
- TestLoadTimingNotReused(*http_stream);
-}
-
-TEST_F(SpdyHttpStreamSpdy2Test, LoadTimingTwoRequests) {
- scoped_ptr<SpdyFrame> req1(
- spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
- scoped_ptr<SpdyFrame> req2(
- spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
- MockWrite writes[] = {
- CreateMockWrite(*req1, 0),
- CreateMockWrite(*req2, 1),
- };
- scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1));
- scoped_ptr<SpdyFrame> body1(ConstructSpdyBodyFrame(1, "", 0, true));
- scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
- scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(3, "", 0, true));
- MockRead reads[] = {
- CreateMockRead(*resp1, 2),
- CreateMockRead(*body1, 3),
- CreateMockRead(*resp2, 4),
- CreateMockRead(*body2, 5),
- MockRead(ASYNC, 0, 6) // EOF
- };
-
- HostPortPair host_port_pair("www.google.com", 80);
- SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
- kPrivacyModeDisabled);
- ASSERT_EQ(OK, InitSessionDeterministic(reads, arraysize(reads),
- writes, arraysize(writes),
- host_port_pair));
-
- HttpRequestInfo request1;
- request1.method = "GET";
- request1.url = GURL("http://www.google.com/");
- TestCompletionCallback callback1;
- HttpResponseInfo response1;
- HttpRequestHeaders headers1;
- scoped_ptr<SpdyHttpStream> http_stream1(
- new SpdyHttpStream(session_.get(), true));
-
- ASSERT_EQ(OK,
- http_stream1->InitializeStream(&request1, DEFAULT_PRIORITY,
- BoundNetLog(),
- CompletionCallback()));
- EXPECT_EQ(ERR_IO_PENDING, http_stream1->SendRequest(headers1, &response1,
- callback1.callback()));
- EXPECT_TRUE(http_session_->spdy_session_pool()->HasSession(key));
-
- HttpRequestInfo request2;
- request2.method = "GET";
- request2.url = GURL("http://www.google.com/");
- TestCompletionCallback callback2;
- HttpResponseInfo response2;
- HttpRequestHeaders headers2;
- scoped_ptr<SpdyHttpStream> http_stream2(
- new SpdyHttpStream(session_.get(), true));
-
- ASSERT_EQ(OK,
- http_stream2->InitializeStream(&request2, DEFAULT_PRIORITY,
- BoundNetLog(),
- CompletionCallback()));
- EXPECT_EQ(ERR_IO_PENDING, http_stream2->SendRequest(headers2, &response2,
- callback2.callback()));
- EXPECT_TRUE(http_session_->spdy_session_pool()->HasSession(key));
-
- // First write.
- deterministic_data()->RunFor(1);
- EXPECT_LE(0, callback1.WaitForResult());
-
- TestLoadTimingNotReused(*http_stream1);
- LoadTimingInfo load_timing_info1;
- LoadTimingInfo load_timing_info2;
- EXPECT_TRUE(http_stream1->GetLoadTimingInfo(&load_timing_info1));
- EXPECT_FALSE(http_stream2->GetLoadTimingInfo(&load_timing_info2));
-
- // Second write.
- deterministic_data()->RunFor(1);
- EXPECT_LE(0, callback2.WaitForResult());
- TestLoadTimingReused(*http_stream2);
- EXPECT_TRUE(http_stream2->GetLoadTimingInfo(&load_timing_info2));
- EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
-
- // All the reads.
- deterministic_data()->RunFor(6);
-
- // Read stream 1 to completion, before making sure we can still read load
- // timing from both streams.
- scoped_refptr<IOBuffer> buf1(new IOBuffer(1));
- ASSERT_EQ(
- 0, http_stream1->ReadResponseBody(buf1.get(), 1, callback1.callback()));
-
- // Stream 1 has been read to completion.
- TestLoadTimingNotReused(*http_stream1);
- // Stream 2 still has queued body data.
- TestLoadTimingReused(*http_stream2);
-}
-
-TEST_F(SpdyHttpStreamSpdy2Test, SendChunkedPost) {
- scoped_ptr<SpdyFrame> req(ConstructChunkedSpdyPost(NULL, 0));
- scoped_ptr<SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
- MockWrite writes[] = {
- CreateMockWrite(*req.get(), 0),
- CreateMockWrite(*body, 1), // POST upload frame
- };
- scoped_ptr<SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
- MockRead reads[] = {
- CreateMockRead(*resp, 2),
- CreateMockRead(*body, 3),
- MockRead(SYNCHRONOUS, 0, 4) // EOF
- };
-
- HostPortPair host_port_pair("www.google.com", 80);
- SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
- kPrivacyModeDisabled);
- EXPECT_EQ(OK, InitSession(reads, arraysize(reads), writes, arraysize(writes),
- host_port_pair));
-
- UploadDataStream upload_stream(UploadDataStream::CHUNKED, 0);
- const int kFirstChunkSize = kUploadDataSize/2;
- upload_stream.AppendChunk(kUploadData, kFirstChunkSize, false);
- upload_stream.AppendChunk(kUploadData + kFirstChunkSize,
- kUploadDataSize - kFirstChunkSize, true);
-
- HttpRequestInfo request;
- request.method = "POST";
- request.url = GURL("http://www.google.com/");
- request.upload_data_stream = &upload_stream;
-
- ASSERT_EQ(OK, upload_stream.Init(CompletionCallback()));
-
- TestCompletionCallback callback;
- HttpResponseInfo response;
- HttpRequestHeaders headers;
- BoundNetLog net_log;
- SpdyHttpStream http_stream(session_.get(), true);
- ASSERT_EQ(
- OK,
- http_stream.InitializeStream(&request, DEFAULT_PRIORITY,
- net_log, CompletionCallback()));
-
- EXPECT_EQ(ERR_IO_PENDING, http_stream.SendRequest(
- headers, &response, callback.callback()));
- EXPECT_TRUE(http_session_->spdy_session_pool()->HasSession(key));
-
- // This results in writing the post body and reading the response headers.
- callback.WaitForResult();
-
- // This triggers reading the body and the EOF, causing the session to shut
- // down.
- data()->CompleteRead();
- base::MessageLoop::current()->RunUntilIdle();
-
- // Because we abandoned the stream, we don't expect to find a session in the
- // pool anymore.
- EXPECT_FALSE(http_session_->spdy_session_pool()->HasSession(key));
- EXPECT_TRUE(data()->at_read_eof());
- EXPECT_TRUE(data()->at_write_eof());
-}
-
-// Test to ensure the SpdyStream state machine does not get confused when a
-// chunk becomes available while a write is pending.
-TEST_F(SpdyHttpStreamSpdy2Test, DelayedSendChunkedPost) {
- const char kUploadData1[] = "12345678";
- const int kUploadData1Size = arraysize(kUploadData1)-1;
- scoped_ptr<SpdyFrame> req(ConstructChunkedSpdyPost(NULL, 0));
- scoped_ptr<SpdyFrame> chunk1(ConstructSpdyBodyFrame(1, false));
- scoped_ptr<SpdyFrame> chunk2(
- ConstructSpdyBodyFrame(1, kUploadData1, kUploadData1Size, false));
- scoped_ptr<SpdyFrame> chunk3(ConstructSpdyBodyFrame(1, true));
- MockWrite writes[] = {
- CreateMockWrite(*req.get(), 0),
- CreateMockWrite(*chunk1, 1), // POST upload frames
- CreateMockWrite(*chunk2, 2),
- CreateMockWrite(*chunk3, 3),
- };
- scoped_ptr<SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
- MockRead reads[] = {
- CreateMockRead(*resp, 4),
- CreateMockRead(*chunk1, 5),
- CreateMockRead(*chunk2, 6),
- CreateMockRead(*chunk3, 7),
- MockRead(ASYNC, 0, 8) // EOF
- };
-
- HostPortPair host_port_pair("www.google.com", 80);
- SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
- kPrivacyModeDisabled);
-
- ASSERT_EQ(OK, InitSessionDeterministic(reads, arraysize(reads),
- writes, arraysize(writes),
- host_port_pair));
-
- UploadDataStream upload_stream(UploadDataStream::CHUNKED, 0);
-
- HttpRequestInfo request;
- request.method = "POST";
- request.url = GURL("http://www.google.com/");
- request.upload_data_stream = &upload_stream;
-
- ASSERT_EQ(OK, upload_stream.Init(CompletionCallback()));
- upload_stream.AppendChunk(kUploadData, kUploadDataSize, false);
-
- BoundNetLog net_log;
- scoped_ptr<SpdyHttpStream> http_stream(
- new SpdyHttpStream(session_.get(), true));
- ASSERT_EQ(OK, http_stream->InitializeStream(&request, DEFAULT_PRIORITY,
- net_log, CompletionCallback()));
-
- HttpRequestHeaders headers;
- HttpResponseInfo response;
- TestCompletionCallback callback;
- // This will attempt to Write() the initial request and headers, which will
- // complete asynchronously.
- EXPECT_EQ(ERR_IO_PENDING, http_stream->SendRequest(headers, &response,
- callback.callback()));
- EXPECT_TRUE(http_session_->spdy_session_pool()->HasSession(key));
-
- // Complete the initial request write and the first chunk.
- deterministic_data()->RunFor(2);
- ASSERT_TRUE(callback.have_result());
- EXPECT_EQ(OK, callback.WaitForResult());
-
- // Now append the final two chunks which will enqueue two more writes.
- upload_stream.AppendChunk(kUploadData1, kUploadData1Size, false);
- upload_stream.AppendChunk(kUploadData, kUploadDataSize, true);
-
- // Finish writing all the chunks.
- deterministic_data()->RunFor(2);
-
- // Read response headers.
- deterministic_data()->RunFor(1);
- ASSERT_EQ(OK, http_stream->ReadResponseHeaders(callback.callback()));
-
- // Read and check |chunk1| response.
- deterministic_data()->RunFor(1);
- scoped_refptr<IOBuffer> buf1(new IOBuffer(kUploadDataSize));
- ASSERT_EQ(kUploadDataSize,
- http_stream->ReadResponseBody(
- buf1.get(), kUploadDataSize, callback.callback()));
- EXPECT_EQ(kUploadData, std::string(buf1->data(), kUploadDataSize));
-
- // Read and check |chunk2| response.
- deterministic_data()->RunFor(1);
- scoped_refptr<IOBuffer> buf2(new IOBuffer(kUploadData1Size));
- ASSERT_EQ(kUploadData1Size,
- http_stream->ReadResponseBody(
- buf2.get(), kUploadData1Size, callback.callback()));
- EXPECT_EQ(kUploadData1, std::string(buf2->data(), kUploadData1Size));
-
- // Read and check |chunk3| response.
- deterministic_data()->RunFor(1);
- scoped_refptr<IOBuffer> buf3(new IOBuffer(kUploadDataSize));
- ASSERT_EQ(kUploadDataSize,
- http_stream->ReadResponseBody(
- buf3.get(), kUploadDataSize, callback.callback()));
- EXPECT_EQ(kUploadData, std::string(buf3->data(), kUploadDataSize));
-
- // Finish reading the |EOF|.
- deterministic_data()->RunFor(1);
- ASSERT_TRUE(response.headers.get());
- ASSERT_EQ(200, response.headers->response_code());
- EXPECT_TRUE(deterministic_data()->at_read_eof());
- EXPECT_TRUE(deterministic_data()->at_write_eof());
-}
-
-// Test case for bug: http://code.google.com/p/chromium/issues/detail?id=50058
-TEST_F(SpdyHttpStreamSpdy2Test, SpdyURLTest) {
- const char * const full_url = "http://www.google.com/foo?query=what#anchor";
- const char * const base_url = "http://www.google.com/foo?query=what";
- scoped_ptr<SpdyFrame> req(
- spdy_util_.ConstructSpdyGet(base_url, false, 1, LOWEST));
- MockWrite writes[] = {
- CreateMockWrite(*req.get(), 1),
- };
- scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
- MockRead reads[] = {
- CreateMockRead(*resp, 2),
- MockRead(SYNCHRONOUS, 0, 3) // EOF
- };
-
- HostPortPair host_port_pair("www.google.com", 80);
- SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
- kPrivacyModeDisabled);
- EXPECT_EQ(OK, InitSession(reads, arraysize(reads), writes, arraysize(writes),
- host_port_pair));
-
- HttpRequestInfo request;
- request.method = "GET";
- request.url = GURL(full_url);
- TestCompletionCallback callback;
- HttpResponseInfo response;
- HttpRequestHeaders headers;
- BoundNetLog net_log;
- scoped_ptr<SpdyHttpStream> http_stream(
- new SpdyHttpStream(session_.get(), true));
- ASSERT_EQ(OK,
- http_stream->InitializeStream(
- &request, DEFAULT_PRIORITY, net_log, CompletionCallback()));
-
- EXPECT_EQ(ERR_IO_PENDING, http_stream->SendRequest(headers, &response,
- callback.callback()));
-
- EXPECT_EQ(base_url, http_stream->stream()->GetUrl().spec());
-
- // This triggers the MockWrite and read 2
- callback.WaitForResult();
-
- // This triggers read 3. The empty read causes the session to shut down.
- data()->CompleteRead();
-
- // Because we abandoned the stream, we don't expect to find a session in the
- // pool anymore.
- EXPECT_FALSE(http_session_->spdy_session_pool()->HasSession(key));
- EXPECT_TRUE(data()->at_read_eof());
- EXPECT_TRUE(data()->at_write_eof());
-}
-
-// TODO(willchan): Write a longer test for SpdyStream that exercises all
-// methods.
-
-} // namespace net
diff --git a/net/spdy/spdy_http_stream_spdy3_unittest.cc b/net/spdy/spdy_http_stream_unittest.cc
index b14606b..6405b8f 100644
--- a/net/spdy/spdy_http_stream_spdy3_unittest.cc
+++ b/net/spdy/spdy_http_stream_unittest.cc
@@ -22,15 +22,14 @@
#include "net/http/http_response_headers.h"
#include "net/http/http_response_info.h"
#include "net/socket/next_proto.h"
+#include "net/socket/socket_test_util.h"
#include "net/spdy/spdy_credential_builder.h"
#include "net/spdy/spdy_http_utils.h"
#include "net/spdy/spdy_session.h"
-#include "net/spdy/spdy_test_util_spdy3.h"
+#include "net/spdy/spdy_test_util_common.h"
#include "net/ssl/default_server_bound_cert_store.h"
#include "testing/gtest/include/gtest/gtest.h"
-using namespace net::test_spdy3;
-
namespace net {
namespace {
@@ -64,11 +63,12 @@ void TestLoadTimingNotReused(const HttpStream& stream) {
} // namespace
-class SpdyHttpStreamSpdy3Test : public testing::Test {
+class SpdyHttpStreamSpdy2Test : public testing::Test,
+ public testing::WithParamInterface<NextProto> {
public:
- SpdyHttpStreamSpdy3Test()
- : spdy_util_(kProtoSPDY3),
- session_deps_(kProtoSPDY3) {
+ SpdyHttpStreamSpdy2Test()
+ : spdy_util_(GetParam()),
+ session_deps_(GetParam()) {
session_deps_.net_log = &net_log_;
}
@@ -80,6 +80,7 @@ class SpdyHttpStreamSpdy3Test : public testing::Test {
protected:
virtual void TearDown() OVERRIDE {
+ crypto::ECSignatureCreator::SetFactoryForTesting(NULL);
base::MessageLoop::current()->RunUntilIdle();
}
@@ -157,32 +158,40 @@ class SpdyHttpStreamSpdy3Test : public testing::Test {
scoped_refptr<SpdySession> session_;
scoped_refptr<TransportSocketParams> transport_params_;
- // The SendChunkedPost test is run with SPDY/3 and SPDY/4.
- //
- // TODO(akalin): Find a less clunky way to do this once we unfork
- // the SPDY tests.
- void RunSendChunkedPostTest(SpdyMajorVersion spdy_version);
-
private:
MockECSignatureCreatorFactory ec_signature_creator_factory_;
};
+INSTANTIATE_TEST_CASE_P(
+ NextProto,
+ SpdyHttpStreamSpdy2Test,
+ testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2));
+
+// TODO(akalin): Don't early-exit in the tests below for values >
+// kProtoSPDY3.
+
// SpdyHttpStream::GetUploadProgress() should still work even before the
// stream is initialized.
-TEST_F(SpdyHttpStreamSpdy3Test, GetUploadProgressBeforeInitialization) {
+TEST_P(SpdyHttpStreamSpdy2Test, GetUploadProgressBeforeInitialization) {
+ if (GetParam() > kProtoSPDY3)
+ return;
+
SpdyHttpStream stream(NULL, false);
UploadProgress progress = stream.GetUploadProgress();
EXPECT_EQ(0u, progress.size());
EXPECT_EQ(0u, progress.position());
}
-TEST_F(SpdyHttpStreamSpdy3Test, SendRequest) {
+TEST_P(SpdyHttpStreamSpdy2Test, SendRequest) {
+ if (GetParam() > kProtoSPDY3)
+ return;
+
scoped_ptr<SpdyFrame> req(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
MockWrite writes[] = {
CreateMockWrite(*req.get(), 1),
};
- scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+ scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
MockRead reads[] = {
CreateMockRead(*resp, 2),
MockRead(SYNCHRONOUS, 0, 3) // EOF
@@ -240,7 +249,10 @@ TEST_F(SpdyHttpStreamSpdy3Test, SendRequest) {
TestLoadTimingNotReused(*http_stream);
}
-TEST_F(SpdyHttpStreamSpdy3Test, LoadTimingTwoRequests) {
+TEST_P(SpdyHttpStreamSpdy2Test, LoadTimingTwoRequests) {
+ if (GetParam() > kProtoSPDY3)
+ return;
+
scoped_ptr<SpdyFrame> req1(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
scoped_ptr<SpdyFrame> req2(
@@ -249,10 +261,14 @@ TEST_F(SpdyHttpStreamSpdy3Test, LoadTimingTwoRequests) {
CreateMockWrite(*req1, 0),
CreateMockWrite(*req2, 1),
};
- scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1));
- scoped_ptr<SpdyFrame> body1(ConstructSpdyBodyFrame(1, "", 0, true));
- scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
- scoped_ptr<SpdyFrame> body2(ConstructSpdyBodyFrame(3, "", 0, true));
+ scoped_ptr<SpdyFrame> resp1(
+ spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+ scoped_ptr<SpdyFrame> body1(
+ spdy_util_.ConstructSpdyBodyFrame(1, "", 0, true));
+ scoped_ptr<SpdyFrame> resp2(
+ spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
+ scoped_ptr<SpdyFrame> body2(
+ spdy_util_.ConstructSpdyBodyFrame(3, "", 0, true));
MockRead reads[] = {
CreateMockRead(*resp1, 2),
CreateMockRead(*body1, 3),
@@ -334,28 +350,26 @@ TEST_F(SpdyHttpStreamSpdy3Test, LoadTimingTwoRequests) {
TestLoadTimingReused(*http_stream2);
}
-void SpdyHttpStreamSpdy3Test::RunSendChunkedPostTest(
- SpdyMajorVersion spdy_version) {
- BufferedSpdyFramer framer(spdy_version, false);
+TEST_P(SpdyHttpStreamSpdy2Test, SendChunkedPost) {
+ BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
scoped_ptr<SpdyFrame> initial_window_update(
framer.CreateWindowUpdate(
kSessionFlowControlStreamId,
kDefaultInitialRecvWindowSize - kSpdySessionInitialWindowSize));
scoped_ptr<SpdyFrame> req(
- ConstructChunkedSpdyPostWithVersion(spdy_version, NULL, 0));
+ spdy_util_.ConstructChunkedSpdyPost(NULL, 0));
scoped_ptr<SpdyFrame> body(
framer.CreateDataFrame(1, kUploadData, kUploadDataSize, DATA_FLAG_FIN));
std::vector<MockWrite> writes;
int seq = 0;
- if (spdy_version == SPDY4) {
+ if (GetParam() >= kProtoSPDY31) {
writes.push_back(CreateMockWrite(*initial_window_update, seq++));
}
writes.push_back(CreateMockWrite(*req, seq++));
writes.push_back(CreateMockWrite(*body, seq++)); // POST upload frame
- scoped_ptr<SpdyFrame> resp(
- ConstructSpdyPostSynReplyWithVersion(spdy_version, NULL, 0));
+ scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
std::vector<MockRead> reads;
reads.push_back(CreateMockRead(*resp, seq++));
reads.push_back(CreateMockRead(*body, seq++));
@@ -367,7 +381,7 @@ void SpdyHttpStreamSpdy3Test::RunSendChunkedPostTest(
EXPECT_EQ(OK, InitSession(vector_as_array(&reads), reads.size(),
vector_as_array(&writes), writes.size(),
host_port_pair));
- EXPECT_EQ(spdy_version, session_->GetProtocolVersion());
+ EXPECT_EQ(spdy_util_.spdy_version(), session_->GetProtocolVersion());
UploadDataStream upload_stream(UploadDataStream::CHUNKED, 0);
const int kFirstChunkSize = kUploadDataSize/2;
@@ -411,32 +425,27 @@ void SpdyHttpStreamSpdy3Test::RunSendChunkedPostTest(
EXPECT_TRUE(data()->at_write_eof());
}
-TEST_F(SpdyHttpStreamSpdy3Test, SendChunkedPost) {
- RunSendChunkedPostTest(SPDY3);
-}
-
-TEST_F(SpdyHttpStreamSpdy3Test, SendChunkedPost4) {
- session_deps_.protocol = kProtoSPDY4a2;
- RunSendChunkedPostTest(SPDY4);
-}
-
// Test to ensure the SpdyStream state machine does not get confused when a
// chunk becomes available while a write is pending.
-TEST_F(SpdyHttpStreamSpdy3Test, DelayedSendChunkedPost) {
+TEST_P(SpdyHttpStreamSpdy2Test, DelayedSendChunkedPost) {
+ if (GetParam() > kProtoSPDY3)
+ return;
+
const char kUploadData1[] = "12345678";
const int kUploadData1Size = arraysize(kUploadData1)-1;
- scoped_ptr<SpdyFrame> req(ConstructChunkedSpdyPost(NULL, 0));
- scoped_ptr<SpdyFrame> chunk1(ConstructSpdyBodyFrame(1, false));
+ scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0));
+ scoped_ptr<SpdyFrame> chunk1(spdy_util_.ConstructSpdyBodyFrame(1, false));
scoped_ptr<SpdyFrame> chunk2(
- ConstructSpdyBodyFrame(1, kUploadData1, kUploadData1Size, false));
- scoped_ptr<SpdyFrame> chunk3(ConstructSpdyBodyFrame(1, true));
+ spdy_util_.ConstructSpdyBodyFrame(
+ 1, kUploadData1, kUploadData1Size, false));
+ scoped_ptr<SpdyFrame> chunk3(spdy_util_.ConstructSpdyBodyFrame(1, true));
MockWrite writes[] = {
CreateMockWrite(*req.get(), 0),
CreateMockWrite(*chunk1, 1), // POST upload frames
CreateMockWrite(*chunk2, 2),
CreateMockWrite(*chunk3, 3),
};
- scoped_ptr<SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
+ scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
MockRead reads[] = {
CreateMockRead(*resp, 4),
CreateMockRead(*chunk1, 5),
@@ -528,14 +537,17 @@ TEST_F(SpdyHttpStreamSpdy3Test, DelayedSendChunkedPost) {
// Test the receipt of a WINDOW_UPDATE frame while waiting for a chunk to be
// made available is handled correctly.
-TEST_F(SpdyHttpStreamSpdy3Test, DelayedSendChunkedPostWithWindowUpdate) {
- scoped_ptr<SpdyFrame> req(ConstructChunkedSpdyPost(NULL, 0));
- scoped_ptr<SpdyFrame> chunk1(ConstructSpdyBodyFrame(1, true));
+TEST_P(SpdyHttpStreamSpdy2Test, DelayedSendChunkedPostWithWindowUpdate) {
+ if (GetParam() != kProtoSPDY3)
+ return;
+
+ scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0));
+ scoped_ptr<SpdyFrame> chunk1(spdy_util_.ConstructSpdyBodyFrame(1, true));
MockWrite writes[] = {
CreateMockWrite(*req.get(), 0),
CreateMockWrite(*chunk1, 1),
};
- scoped_ptr<SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
+ scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
scoped_ptr<SpdyFrame> window_update(
spdy_util_.ConstructSpdyWindowUpdate(1, kUploadDataSize));
MockRead reads[] = {
@@ -642,7 +654,10 @@ TEST_F(SpdyHttpStreamSpdy3Test, DelayedSendChunkedPostWithWindowUpdate) {
}
// Test case for bug: http://code.google.com/p/chromium/issues/detail?id=50058
-TEST_F(SpdyHttpStreamSpdy3Test, SpdyURLTest) {
+TEST_P(SpdyHttpStreamSpdy2Test, SpdyURLTest) {
+ if (GetParam() > kProtoSPDY3)
+ return;
+
const char * const full_url = "http://www.google.com/foo?query=what#anchor";
const char * const base_url = "http://www.google.com/foo?query=what";
scoped_ptr<SpdyFrame> req(
@@ -650,7 +665,7 @@ TEST_F(SpdyHttpStreamSpdy3Test, SpdyURLTest) {
MockWrite writes[] = {
CreateMockWrite(*req.get(), 1),
};
- scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+ scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
MockRead reads[] = {
CreateMockRead(*resp, 2),
MockRead(SYNCHRONOUS, 0, 3) // EOF
@@ -714,20 +729,22 @@ void GetECServerBoundCertAndProof(
EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, cert_type);
SpdyCredential credential;
- SpdyCredentialBuilder::Build(MockClientSocket::kTlsUnique, cert_type, key,
- *cert, 2, &credential);
+ EXPECT_EQ(OK,
+ SpdyCredentialBuilder::Build(
+ MockClientSocket::kTlsUnique, cert_type, key,
+ *cert, 2, &credential));
+ ASSERT_FALSE(credential.certs.empty());
cert->assign(credential.certs[0]);
proof->assign(credential.proof);
}
-} // namespace
-
// Constructs a standard SPDY SYN_STREAM frame for a GET request with
// a credential set.
-SpdyFrame* ConstructCredentialRequestFrame(size_t slot, const GURL& url,
+SpdyFrame* ConstructCredentialRequestFrame(NextProto next_proto,
+ size_t slot, const GURL& url,
SpdyStreamId stream_id) {
- SpdyTestUtil util(kProtoSPDY3);
+ SpdyTestUtil util(next_proto);
const SpdyHeaderInfo syn_headers = {
SYN_STREAM,
@@ -743,47 +760,19 @@ SpdyFrame* ConstructCredentialRequestFrame(size_t slot, const GURL& url,
DATA_FLAG_NONE
};
- // TODO(rch): this is ugly. Clean up.
- std::string str_path = url.PathForRequest();
- std::string str_scheme = url.scheme();
- std::string str_host = url.host();
- if (url.has_port()) {
- str_host += ":";
- str_host += url.port();
- }
- scoped_ptr<char[]> req(new char[str_path.size() + 1]);
- scoped_ptr<char[]> scheme(new char[str_scheme.size() + 1]);
- scoped_ptr<char[]> host(new char[str_host.size() + 1]);
- memcpy(req.get(), str_path.c_str(), str_path.size());
- memcpy(scheme.get(), str_scheme.c_str(), str_scheme.size());
- memcpy(host.get(), str_host.c_str(), str_host.size());
- req.get()[str_path.size()] = '\0';
- scheme.get()[str_scheme.size()] = '\0';
- host.get()[str_host.size()] = '\0';
-
- const char* const headers[] = {
- ":method",
- "GET",
- ":path",
- req.get(),
- ":host",
- host.get(),
- ":scheme",
- scheme.get(),
- ":version",
- "HTTP/1.1"
- };
- return util.ConstructSpdyFrame(
- syn_headers, NULL, 0, headers, arraysize(headers)/2);
+ scoped_ptr<SpdyHeaderBlock> headers(util.ConstructGetHeaderBlock(url.spec()));
+ return util.ConstructSpdyFrame(syn_headers, headers.Pass());
}
+} // namespace
+
// TODO(rch): When openssl supports server bound certifictes, this
// guard can be removed
#if !defined(USE_OPENSSL)
// Test that if we request a resource for a new origin on a session that
// used domain bound certificates, that we send a CREDENTIAL frame for
// the new domain before we send the new request.
-void SpdyHttpStreamSpdy3Test::TestSendCredentials(
+void SpdyHttpStreamSpdy2Test::TestSendCredentials(
ServerBoundCertService* server_bound_cert_service,
const std::string& cert,
const std::string& proof) {
@@ -796,19 +785,19 @@ void SpdyHttpStreamSpdy3Test::TestSendCredentials(
cred.certs.push_back(cert);
scoped_ptr<SpdyFrame> req(ConstructCredentialRequestFrame(
- 1, GURL(kUrl1), 1));
+ GetParam(), 1, GURL(kUrl1), 1));
scoped_ptr<SpdyFrame> credential(
spdy_util_.ConstructSpdyCredential(cred));
scoped_ptr<SpdyFrame> req2(ConstructCredentialRequestFrame(
- 2, GURL(kUrl2), 3));
+ GetParam(), 2, GURL(kUrl2), 3));
MockWrite writes[] = {
CreateMockWrite(*req.get(), 0),
CreateMockWrite(*credential.get(), 2),
CreateMockWrite(*req2.get(), 3),
};
- scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
- scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
+ scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+ scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
MockRead reads[] = {
CreateMockRead(*resp, 1),
CreateMockRead(*resp2, 4),
@@ -827,7 +816,7 @@ void SpdyHttpStreamSpdy3Test::TestSendCredentials(
SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
ssl.channel_id_sent = true;
ssl.server_bound_cert_service = server_bound_cert_service;
- ssl.protocol_negotiated = kProtoSPDY3;
+ ssl.protocol_negotiated = GetParam();
socket_factory->AddSSLSocketDataProvider(&ssl);
http_session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
&session_deps_);
@@ -907,7 +896,10 @@ void SpdyHttpStreamSpdy3Test::TestSendCredentials(
ASSERT_EQ(200, response.headers->response_code());
}
-TEST_F(SpdyHttpStreamSpdy3Test, SendCredentialsEC) {
+TEST_P(SpdyHttpStreamSpdy2Test, SendCredentialsEC) {
+ if (GetParam() != kProtoSPDY3)
+ return;
+
scoped_refptr<base::SequencedWorkerPool> sequenced_worker_pool =
new base::SequencedWorkerPool(1, "SpdyHttpStreamSpdy3Test");
scoped_ptr<ServerBoundCertService> server_bound_cert_service(
@@ -924,7 +916,10 @@ TEST_F(SpdyHttpStreamSpdy3Test, SendCredentialsEC) {
sequenced_worker_pool->Shutdown();
}
-TEST_F(SpdyHttpStreamSpdy3Test, DontSendCredentialsForHttpUrlsEC) {
+TEST_P(SpdyHttpStreamSpdy2Test, DontSendCredentialsForHttpUrlsEC) {
+ if (GetParam() != kProtoSPDY3)
+ return;
+
scoped_refptr<base::SequencedWorkerPool> sequenced_worker_pool =
new base::SequencedWorkerPool(1, "SpdyHttpStreamSpdy3Test");
scoped_ptr<ServerBoundCertService> server_bound_cert_service(
@@ -945,16 +940,16 @@ TEST_F(SpdyHttpStreamSpdy3Test, DontSendCredentialsForHttpUrlsEC) {
cred.certs.push_back(cert);
scoped_ptr<SpdyFrame> req(ConstructCredentialRequestFrame(
- 0, GURL(kUrl1), 1));
+ GetParam(), 0, GURL(kUrl1), 1));
scoped_ptr<SpdyFrame> req2(ConstructCredentialRequestFrame(
- 0, GURL(kUrl2), 3));
+ GetParam(), 0, GURL(kUrl2), 3));
MockWrite writes[] = {
CreateMockWrite(*req.get(), 0),
CreateMockWrite(*req2.get(), 2),
};
- scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
- scoped_ptr<SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
+ scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+ scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
MockRead reads[] = {
CreateMockRead(*resp, 1),
CreateMockRead(*resp2, 3),
@@ -975,7 +970,7 @@ TEST_F(SpdyHttpStreamSpdy3Test, DontSendCredentialsForHttpUrlsEC) {
SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
ssl.channel_id_sent = true;
ssl.server_bound_cert_service = server_bound_cert_service.get();
- ssl.protocol_negotiated = kProtoSPDY3;
+ ssl.protocol_negotiated = GetParam();
socket_factory->AddSSLSocketDataProvider(&ssl);
http_session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
&session_deps_);
diff --git a/net/spdy/spdy_session_unittest.cc b/net/spdy/spdy_session_unittest.cc
index b189220..df66fe3a 100644
--- a/net/spdy/spdy_session_unittest.cc
+++ b/net/spdy/spdy_session_unittest.cc
@@ -17,6 +17,7 @@
#include "net/dns/host_cache.h"
#include "net/socket/client_socket_pool_manager.h"
#include "net/socket/next_proto.h"
+#include "net/socket/socket_test_util.h"
#include "net/spdy/spdy_http_utils.h"
#include "net/spdy/spdy_session_pool.h"
#include "net/spdy/spdy_session_test_util.h"
diff --git a/net/spdy/spdy_stream_unittest.cc b/net/spdy/spdy_stream_unittest.cc
index 9992c18..df3c372 100644
--- a/net/spdy/spdy_stream_unittest.cc
+++ b/net/spdy/spdy_stream_unittest.cc
@@ -14,6 +14,7 @@
#include "net/base/net_log_unittest.h"
#include "net/base/request_priority.h"
#include "net/socket/next_proto.h"
+#include "net/socket/socket_test_util.h"
#include "net/spdy/buffered_spdy_framer.h"
#include "net/spdy/spdy_http_utils.h"
#include "net/spdy/spdy_protocol.h"