spdy_http_stream_unittest.cc revision dc0f95d653279beabeb9817299e2902918ba123e
1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/spdy/spdy_http_stream.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/spdy/spdy_session.h"
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/spdy/spdy_test_util.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace net {
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SpdyHttpStreamTest : public testing::Test {
133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick public:
143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  OrderedSocketData* data() { return data_; }
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  SpdyHttpStreamTest() {}
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void EnableCompression(bool enabled) {
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    spdy::SpdyFramer::set_enable_compression_default(enabled);
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void TearDown() {
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop::current()->RunAllPending();
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int InitSession(MockRead* reads, size_t reads_count,
263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                  MockWrite* writes, size_t writes_count,
273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                  HostPortPair& host_port_pair) {
283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    data_ = new OrderedSocketData(reads, reads_count, writes, writes_count);
303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    session_deps_.socket_factory->AddSocketDataProvider(data_.get());
313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    http_session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
32dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    session_ = http_session_->spdy_session_pool()->Get(pair, BoundNetLog());
333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    tcp_params_ = new TCPSocketParams(host_port_pair.host(),
343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                      host_port_pair.port(),
353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                      MEDIUM, GURL(), false);
363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    TestCompletionCallback callback;
373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ(ERR_IO_PENDING,
393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick              connection->Init(host_port_pair.ToString(), tcp_params_, MEDIUM,
403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                &callback, http_session_->tcp_socket_pool(),
413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                BoundNetLog()));
423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ(OK, callback.WaitForResult());
433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return session_->InitializeWithSocket(connection.release(), false, OK);
443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  SpdySessionDependencies session_deps_;
463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_refptr<OrderedSocketData> data_;
473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_refptr<HttpNetworkSession> http_session_;
483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_refptr<SpdySession> session_;
493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_refptr<TCPSocketParams> tcp_params_;
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(SpdyHttpStreamTest, SendRequest) {
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EnableCompression(false);
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SpdySession::SetSSLMode(false);
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockWrite writes[] = {
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CreateMockWrite(*req.get(), 1),
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockRead reads[] = {
623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    CreateMockRead(*resp, 2),
633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    MockRead(false, 0, 3)  // EOF
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HostPortPair host_port_pair("www.google.com", 80);
673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(OK, InitSession(reads, arraysize(reads), writes, arraysize(writes),
693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      host_port_pair));
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HttpRequestInfo request;
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  request.method = "GET";
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  request.url = GURL("http://www.google.com/");
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestCompletionCallback callback;
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HttpResponseInfo response;
76513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  HttpRequestHeaders headers;
773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  BoundNetLog net_log;
783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<SpdyHttpStream> http_stream(
793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      new SpdyHttpStream(session_.get(), true));
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      OK,
823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      http_stream->InitializeStream(&request, net_log, NULL));
833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(ERR_IO_PENDING,
85513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch            http_stream->SendRequest(headers, NULL, &response, &callback));
863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(http_session_->spdy_session_pool()->HasSession(pair));
873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // This triggers the MockWrite and read 2
893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  callback.WaitForResult();
903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // This triggers read 3. The empty read causes the session to shut down.
923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  data()->CompleteRead();
933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Because we abandoned the stream, we don't expect to find a session in the
953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // pool anymore.
96dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_FALSE(http_session_->spdy_session_pool()->HasSession(pair));
97dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(data()->at_read_eof());
98dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(data()->at_write_eof());
99dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
100dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
101dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST_F(SpdyHttpStreamTest, SendChunkedPost) {
102dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EnableCompression(false);
103dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  SpdySession::SetSSLMode(false);
104dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  UploadDataStream::set_merge_chunks(false);
105dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
106dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  scoped_ptr<spdy::SpdyFrame> req(ConstructChunkedSpdyPost(NULL, 0));
107dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  scoped_ptr<spdy::SpdyFrame> chunk1(ConstructSpdyBodyFrame(1, false));
108dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  scoped_ptr<spdy::SpdyFrame> chunk2(ConstructSpdyBodyFrame(1, true));
109dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  MockWrite writes[] = {
110dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    CreateMockWrite(*req.get(), 1),
111dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    CreateMockWrite(*chunk1, 2),  // POST upload frames
112dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    CreateMockWrite(*chunk2, 3),
113dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  };
114dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
115dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  MockRead reads[] = {
116dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    CreateMockRead(*resp, 4),
117dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    CreateMockRead(*chunk1, 5),
118dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    CreateMockRead(*chunk2, 5),
119dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    MockRead(false, 0, 6)  // EOF
120dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  };
121dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
122dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  HostPortPair host_port_pair("www.google.com", 80);
123dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
124dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(OK, InitSession(reads, arraysize(reads), writes, arraysize(writes),
125dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                            host_port_pair));
126dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
127dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  HttpRequestInfo request;
128dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  request.method = "POST";
129dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  request.url = GURL("http://www.google.com/");
130dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  request.upload_data = new UploadData();
131dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  request.upload_data->set_is_chunked(true);
132dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  request.upload_data->AppendChunk(kUploadData, kUploadDataSize, false);
133dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  request.upload_data->AppendChunk(kUploadData, kUploadDataSize, true);
134dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  TestCompletionCallback callback;
135dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  HttpResponseInfo response;
136dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  HttpRequestHeaders headers;
137dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  BoundNetLog net_log;
138dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  SpdyHttpStream http_stream(session_.get(), true);
139dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(
140dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      OK,
141dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      http_stream.InitializeStream(&request, net_log, NULL));
142dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
143dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  UploadDataStream* upload_stream =
144dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      UploadDataStream::Create(request.upload_data, NULL);
145dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(ERR_IO_PENDING, http_stream.SendRequest(
146dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      headers, upload_stream, &response, &callback));
147dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(http_session_->spdy_session_pool()->HasSession(pair));
148dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
149dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // This triggers the MockWrite and read 2
150dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  callback.WaitForResult();
151dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
152dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // This triggers read 3. The empty read causes the session to shut down.
153dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  data()->CompleteRead();
154dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  MessageLoop::current()->RunAllPending();
155dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
156dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Because we abandoned the stream, we don't expect to find a session in the
157dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // pool anymore.
158dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_FALSE(http_session_->spdy_session_pool()->HasSession(pair));
1593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(data()->at_read_eof());
1603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(data()->at_write_eof());
1613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
1623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test case for bug: http://code.google.com/p/chromium/issues/detail?id=50058
1643345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(SpdyHttpStreamTest, SpdyURLTest) {
1653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EnableCompression(false);
1663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  SpdySession::SetSSLMode(false);
1673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const char * const full_url = "http://www.google.com/foo?query=what#anchor";
1693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const char * const base_url = "http://www.google.com/foo?query=what";
1703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(base_url, false, 1, LOWEST));
1713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  MockWrite writes[] = {
1723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    CreateMockWrite(*req.get(), 1),
1733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  };
1743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
1753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  MockRead reads[] = {
1763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    CreateMockRead(*resp, 2),
1773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    MockRead(false, 0, 3)  // EOF
1783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  };
1793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HostPortPair host_port_pair("www.google.com", 80);
1813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
1823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(OK, InitSession(reads, arraysize(reads), writes, arraysize(writes),
1833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      host_port_pair));
1843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HttpRequestInfo request;
1863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  request.method = "GET";
1873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  request.url = GURL(full_url);
1883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback;
1893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HttpResponseInfo response;
190513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  HttpRequestHeaders headers;
1913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  BoundNetLog net_log;
1923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<SpdyHttpStream> http_stream(new SpdyHttpStream(session_, true));
1933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_EQ(
1943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      OK,
1953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      http_stream->InitializeStream(&request, net_log, NULL));
1963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING,
198513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch            http_stream->SendRequest(headers, NULL, &response, &callback));
1993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  spdy::SpdyHeaderBlock* spdy_header =
2013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    http_stream->stream()->spdy_headers().get();
2023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(spdy_header != NULL);
2033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (spdy_header->find("url") != spdy_header->end())
2043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ("/foo?query=what", spdy_header->find("url")->second);
2053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  else
2063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    FAIL() << "No url is set in spdy_header!";
2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // This triggers the MockWrite and read 2
2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  callback.WaitForResult();
2103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // This triggers read 3. The empty read causes the session to shut down.
2123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  data()->CompleteRead();
2133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Because we abandoned the stream, we don't expect to find a session in the
2153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // pool anymore.
216dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_FALSE(http_session_->spdy_session_pool()->HasSession(pair));
2173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(data()->at_read_eof());
2183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(data()->at_write_eof());
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(willchan): Write a longer test for SpdyStream that exercises all
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// methods.
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace net
225