Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(27)

Side by Side Diff: net/spdy/spdy_stream_unittest.cc

Issue 9582034: Fork SPDY/2 and SPDY/3 versions of our SPDY tests, in preparation for landing (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Fix merge bug Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/spdy/spdy_stream_spdy3_unittest.cc ('k') | net/spdy/spdy_test_util.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/memory/ref_counted.h"
6 #include "net/base/completion_callback.h"
7 #include "net/base/net_log_unittest.h"
8 #include "net/spdy/spdy_stream.h"
9 #include "net/spdy/spdy_http_utils.h"
10 #include "net/spdy/spdy_session.h"
11 #include "net/spdy/spdy_test_util.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 // TODO(ukai): factor out common part with spdy_http_stream_unittest.cc
15 //
16 namespace net {
17
18 namespace {
19
20 class TestSpdyStreamDelegate : public SpdyStream::Delegate {
21 public:
22 TestSpdyStreamDelegate(SpdyStream* stream,
23 IOBufferWithSize* buf,
24 const CompletionCallback& callback)
25 : stream_(stream),
26 buf_(buf),
27 callback_(callback),
28 send_headers_completed_(false),
29 response_(new spdy::SpdyHeaderBlock),
30 data_sent_(0),
31 closed_(false) {}
32 virtual ~TestSpdyStreamDelegate() {}
33
34 virtual bool OnSendHeadersComplete(int status) {
35 send_headers_completed_ = true;
36 return true;
37 }
38 virtual int OnSendBody() {
39 ADD_FAILURE() << "OnSendBody should not be called";
40 return ERR_UNEXPECTED;
41 }
42 virtual int OnSendBodyComplete(int /*status*/, bool* /*eof*/) {
43 ADD_FAILURE() << "OnSendBodyComplete should not be called";
44 return ERR_UNEXPECTED;
45 }
46
47 virtual int OnResponseReceived(const spdy::SpdyHeaderBlock& response,
48 base::Time response_time,
49 int status) {
50 EXPECT_TRUE(send_headers_completed_);
51 *response_ = response;
52 if (buf_) {
53 EXPECT_EQ(ERR_IO_PENDING,
54 stream_->WriteStreamData(buf_.get(), buf_->size(),
55 spdy::DATA_FLAG_NONE));
56 }
57 return status;
58 }
59 virtual void OnDataReceived(const char* buffer, int bytes) {
60 received_data_ += std::string(buffer, bytes);
61 }
62 virtual void OnDataSent(int length) {
63 data_sent_ += length;
64 }
65 virtual void OnClose(int status) {
66 closed_ = true;
67 CompletionCallback callback = callback_;
68 callback_.Reset();
69 callback.Run(OK);
70 }
71 virtual void set_chunk_callback(net::ChunkCallback *) {}
72
73 bool send_headers_completed() const { return send_headers_completed_; }
74 const linked_ptr<spdy::SpdyHeaderBlock>& response() const {
75 return response_;
76 }
77 const std::string& received_data() const { return received_data_; }
78 int data_sent() const { return data_sent_; }
79 bool closed() const { return closed_; }
80
81 private:
82 SpdyStream* stream_;
83 scoped_refptr<IOBufferWithSize> buf_;
84 CompletionCallback callback_;
85 bool send_headers_completed_;
86 linked_ptr<spdy::SpdyHeaderBlock> response_;
87 std::string received_data_;
88 int data_sent_;
89 bool closed_;
90 };
91
92 spdy::SpdyFrame* ConstructSpdyBodyFrame(const char* data, int length) {
93 spdy::SpdyFramer framer;
94 return framer.CreateDataFrame(1, data, length, spdy::DATA_FLAG_NONE);
95 }
96
97 } // anonymous namespace
98
99 class SpdyStreamTest : public testing::Test {
100 protected:
101 SpdyStreamTest() {
102 }
103
104 scoped_refptr<SpdySession> CreateSpdySession() {
105 spdy::SpdyFramer::set_enable_compression_default(false);
106 HostPortPair host_port_pair("www.google.com", 80);
107 HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
108 scoped_refptr<SpdySession> session(
109 session_->spdy_session_pool()->Get(pair, BoundNetLog()));
110 return session;
111 }
112
113 virtual void TearDown() {
114 MessageLoop::current()->RunAllPending();
115 }
116
117 scoped_refptr<HttpNetworkSession> session_;
118 };
119
120 TEST_F(SpdyStreamTest, SendDataAfterOpen) {
121 SpdySessionDependencies session_deps;
122
123 session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps);
124 SpdySessionPoolPeer pool_peer_(session_->spdy_session_pool());
125
126 const SpdyHeaderInfo kSynStartHeader = {
127 spdy::SYN_STREAM,
128 1,
129 0,
130 net::ConvertRequestPriorityToSpdyPriority(LOWEST),
131 spdy::CONTROL_FLAG_NONE,
132 false,
133 spdy::INVALID,
134 NULL,
135 0,
136 spdy::DATA_FLAG_NONE
137 };
138 static const char* const kGetHeaders[] = {
139 "method",
140 "GET",
141 "scheme",
142 "http",
143 "host",
144 "www.google.com",
145 "path",
146 "/",
147 "version",
148 "HTTP/1.1",
149 };
150 scoped_ptr<spdy::SpdyFrame> req(
151 ConstructSpdyPacket(
152 kSynStartHeader, NULL, 0, kGetHeaders, arraysize(kGetHeaders) / 2));
153 scoped_ptr<spdy::SpdyFrame> msg(
154 ConstructSpdyBodyFrame("\0hello!\xff", 8));
155 MockWrite writes[] = {
156 CreateMockWrite(*req),
157 CreateMockWrite(*msg),
158 };
159 writes[0].sequence_number = 0;
160 writes[1].sequence_number = 2;
161
162 scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
163 scoped_ptr<spdy::SpdyFrame> echo(
164 ConstructSpdyBodyFrame("\0hello!\xff", 8));
165 MockRead reads[] = {
166 CreateMockRead(*resp),
167 CreateMockRead(*echo),
168 MockRead(ASYNC, 0, 0), // EOF
169 };
170 reads[0].sequence_number = 1;
171 reads[1].sequence_number = 3;
172 reads[2].sequence_number = 4;
173
174 scoped_ptr<OrderedSocketData> data(
175 new OrderedSocketData(reads, arraysize(reads),
176 writes, arraysize(writes)));
177 MockConnect connect_data(SYNCHRONOUS, OK);
178 data->set_connect_data(connect_data);
179
180 session_deps.socket_factory->AddSocketDataProvider(data.get());
181 SpdySession::SetSSLMode(false);
182
183 scoped_refptr<SpdySession> session(CreateSpdySession());
184 const char* kStreamUrl = "http://www.google.com/";
185 GURL url(kStreamUrl);
186
187 HostPortPair host_port_pair("www.google.com", 80);
188 scoped_refptr<TransportSocketParams> transport_params(
189 new TransportSocketParams(host_port_pair, LOWEST, false, false));
190
191 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
192 EXPECT_EQ(OK, connection->Init(host_port_pair.ToString(), transport_params,
193 LOWEST, CompletionCallback(),
194 session_->GetTransportSocketPool(),
195 BoundNetLog()));
196 session->InitializeWithSocket(connection.release(), false, OK);
197
198 scoped_refptr<SpdyStream> stream;
199 ASSERT_EQ(
200 OK,
201 session->CreateStream(url, LOWEST, &stream, BoundNetLog(),
202 CompletionCallback()));
203 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(8));
204 memcpy(buf->data(), "\0hello!\xff", 8);
205 TestCompletionCallback callback;
206
207 scoped_ptr<TestSpdyStreamDelegate> delegate(
208 new TestSpdyStreamDelegate(stream.get(), buf.get(), callback.callback()));
209 stream->SetDelegate(delegate.get());
210
211 EXPECT_FALSE(stream->HasUrl());
212
213 linked_ptr<spdy::SpdyHeaderBlock> headers(new spdy::SpdyHeaderBlock);
214 (*headers)["method"] = "GET";
215 (*headers)["scheme"] = url.scheme();
216 (*headers)["host"] = url.host();
217 (*headers)["path"] = url.path();
218 (*headers)["version"] = "HTTP/1.1";
219 stream->set_spdy_headers(headers);
220 EXPECT_TRUE(stream->HasUrl());
221 EXPECT_EQ(kStreamUrl, stream->GetUrl().spec());
222
223 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequest(true));
224
225 EXPECT_EQ(OK, callback.WaitForResult());
226
227 EXPECT_TRUE(delegate->send_headers_completed());
228 EXPECT_EQ("200", (*delegate->response())["status"]);
229 EXPECT_EQ("HTTP/1.1", (*delegate->response())["version"]);
230 EXPECT_EQ(std::string("\0hello!\xff", 8), delegate->received_data());
231 EXPECT_EQ(8, delegate->data_sent());
232 EXPECT_TRUE(delegate->closed());
233 }
234
235 TEST_F(SpdyStreamTest, PushedStream) {
236 const char kStreamUrl[] = "http://www.google.com/";
237
238 SpdySessionDependencies session_deps;
239 session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps);
240 SpdySessionPoolPeer pool_peer_(session_->spdy_session_pool());
241 scoped_refptr<SpdySession> spdy_session(CreateSpdySession());
242 BoundNetLog net_log;
243
244 // Conjure up a stream.
245 scoped_refptr<SpdyStream> stream = new SpdyStream(spdy_session,
246 2,
247 true,
248 net_log);
249 EXPECT_FALSE(stream->response_received());
250 EXPECT_FALSE(stream->HasUrl());
251
252 // Set a couple of headers.
253 spdy::SpdyHeaderBlock response;
254 response["url"] = kStreamUrl;
255 stream->OnResponseReceived(response);
256
257 // Send some basic headers.
258 spdy::SpdyHeaderBlock headers;
259 response["status"] = "200";
260 response["version"] = "OK";
261 stream->OnHeaders(headers);
262
263 stream->set_response_received();
264 EXPECT_TRUE(stream->response_received());
265 EXPECT_TRUE(stream->HasUrl());
266 EXPECT_EQ(kStreamUrl, stream->GetUrl().spec());
267 }
268
269 TEST_F(SpdyStreamTest, StreamError) {
270 SpdySessionDependencies session_deps;
271
272 session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps);
273 SpdySessionPoolPeer pool_peer_(session_->spdy_session_pool());
274
275 const SpdyHeaderInfo kSynStartHeader = {
276 spdy::SYN_STREAM,
277 1,
278 0,
279 net::ConvertRequestPriorityToSpdyPriority(LOWEST),
280 spdy::CONTROL_FLAG_NONE,
281 false,
282 spdy::INVALID,
283 NULL,
284 0,
285 spdy::DATA_FLAG_NONE
286 };
287 static const char* const kGetHeaders[] = {
288 "method",
289 "GET",
290 "scheme",
291 "http",
292 "host",
293 "www.google.com",
294 "path",
295 "/",
296 "version",
297 "HTTP/1.1",
298 };
299 scoped_ptr<spdy::SpdyFrame> req(
300 ConstructSpdyPacket(
301 kSynStartHeader, NULL, 0, kGetHeaders, arraysize(kGetHeaders) / 2));
302 scoped_ptr<spdy::SpdyFrame> msg(
303 ConstructSpdyBodyFrame("\0hello!\xff", 8));
304 MockWrite writes[] = {
305 CreateMockWrite(*req),
306 CreateMockWrite(*msg),
307 };
308 writes[0].sequence_number = 0;
309 writes[1].sequence_number = 2;
310
311 scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
312 scoped_ptr<spdy::SpdyFrame> echo(
313 ConstructSpdyBodyFrame("\0hello!\xff", 8));
314 MockRead reads[] = {
315 CreateMockRead(*resp),
316 CreateMockRead(*echo),
317 MockRead(ASYNC, 0, 0), // EOF
318 };
319 reads[0].sequence_number = 1;
320 reads[1].sequence_number = 3;
321 reads[2].sequence_number = 4;
322
323 net::CapturingBoundNetLog log(net::CapturingNetLog::kUnbounded);
324
325 scoped_ptr<OrderedSocketData> data(
326 new OrderedSocketData(reads, arraysize(reads),
327 writes, arraysize(writes)));
328 MockConnect connect_data(SYNCHRONOUS, OK);
329 data->set_connect_data(connect_data);
330
331 session_deps.socket_factory->AddSocketDataProvider(data.get());
332 SpdySession::SetSSLMode(false);
333
334 scoped_refptr<SpdySession> session(CreateSpdySession());
335 const char* kStreamUrl = "http://www.google.com/";
336 GURL url(kStreamUrl);
337
338 HostPortPair host_port_pair("www.google.com", 80);
339 scoped_refptr<TransportSocketParams> transport_params(
340 new TransportSocketParams(host_port_pair, LOWEST, false, false));
341
342 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
343 EXPECT_EQ(OK, connection->Init(host_port_pair.ToString(), transport_params,
344 LOWEST, CompletionCallback(),
345 session_->GetTransportSocketPool(),
346 log.bound()));
347 session->InitializeWithSocket(connection.release(), false, OK);
348
349 scoped_refptr<SpdyStream> stream;
350 ASSERT_EQ(
351 OK,
352 session->CreateStream(url, LOWEST, &stream, log.bound(),
353 CompletionCallback()));
354 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(8));
355 memcpy(buf->data(), "\0hello!\xff", 8);
356 TestCompletionCallback callback;
357
358 scoped_ptr<TestSpdyStreamDelegate> delegate(
359 new TestSpdyStreamDelegate(stream.get(), buf.get(), callback.callback()));
360 stream->SetDelegate(delegate.get());
361
362 EXPECT_FALSE(stream->HasUrl());
363
364 linked_ptr<spdy::SpdyHeaderBlock> headers(new spdy::SpdyHeaderBlock);
365 (*headers)["method"] = "GET";
366 (*headers)["scheme"] = url.scheme();
367 (*headers)["host"] = url.host();
368 (*headers)["path"] = url.path();
369 (*headers)["version"] = "HTTP/1.1";
370 stream->set_spdy_headers(headers);
371 EXPECT_TRUE(stream->HasUrl());
372 EXPECT_EQ(kStreamUrl, stream->GetUrl().spec());
373
374 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequest(true));
375
376 const spdy::SpdyStreamId stream_id = stream->stream_id();
377
378 EXPECT_EQ(OK, callback.WaitForResult());
379
380 EXPECT_TRUE(delegate->send_headers_completed());
381 EXPECT_EQ("200", (*delegate->response())["status"]);
382 EXPECT_EQ("HTTP/1.1", (*delegate->response())["version"]);
383 EXPECT_EQ(std::string("\0hello!\xff", 8), delegate->received_data());
384 EXPECT_EQ(8, delegate->data_sent());
385 EXPECT_TRUE(delegate->closed());
386
387 // Check that the NetLog was filled reasonably.
388 net::CapturingNetLog::EntryList entries;
389 log.GetEntries(&entries);
390 EXPECT_LT(0u, entries.size());
391
392 // Check that we logged SPDY_STREAM_ERROR correctly.
393 int pos = net::ExpectLogContainsSomewhere(
394 entries, 0,
395 net::NetLog::TYPE_SPDY_STREAM_ERROR,
396 net::NetLog::PHASE_NONE);
397
398 CapturingNetLog::Entry entry = entries[pos];
399 NetLogSpdyStreamErrorParameter* request_params =
400 static_cast<NetLogSpdyStreamErrorParameter*>(
401 entry.extra_parameters.get());
402 EXPECT_EQ(stream_id, request_params->stream_id());
403 }
404
405 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_stream_spdy3_unittest.cc ('k') | net/spdy/spdy_test_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698