Revert "Merged all Chromoting Host code into remoting_core.dll (Windows)."
[chromium-blink-merge.git] / net / spdy / spdy_stream_spdy2_unittest.cc
blob602ff31fbe22a350de47356523a187f128e0c3f9
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.
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/buffered_spdy_framer.h"
9 #include "net/spdy/spdy_stream.h"
10 #include "net/spdy/spdy_http_utils.h"
11 #include "net/spdy/spdy_session.h"
12 #include "net/spdy/spdy_stream_test_util.h"
13 #include "net/spdy/spdy_test_util_spdy2.h"
14 #include "net/spdy/spdy_websocket_test_util_spdy2.h"
15 #include "testing/gtest/include/gtest/gtest.h"
17 using namespace net::test_spdy2;
19 // TODO(ukai): factor out common part with spdy_http_stream_unittest.cc
21 namespace net {
23 namespace {
25 SpdyFrame* ConstructSpdyBodyFrame(const char* data, int length) {
26 BufferedSpdyFramer framer(2, false);
27 return framer.CreateDataFrame(1, data, length, DATA_FLAG_NONE);
30 } // anonymous namespace
32 namespace test {
34 class SpdyStreamSpdy2Test : public testing::Test {
35 protected:
36 SpdyStreamSpdy2Test() {
39 scoped_refptr<SpdySession> CreateSpdySession() {
40 HostPortPair host_port_pair("www.google.com", 80);
41 HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
42 scoped_refptr<SpdySession> session(
43 session_->spdy_session_pool()->Get(pair, BoundNetLog()));
44 return session;
47 virtual void TearDown() {
48 MessageLoop::current()->RunUntilIdle();
51 scoped_refptr<HttpNetworkSession> session_;
54 TEST_F(SpdyStreamSpdy2Test, SendDataAfterOpen) {
55 SpdySessionDependencies session_deps;
57 session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps);
58 SpdySessionPoolPeer pool_peer_(session_->spdy_session_pool());
60 const SpdyHeaderInfo kSynStartHeader = {
61 SYN_STREAM,
64 ConvertRequestPriorityToSpdyPriority(LOWEST, 2),
65 CONTROL_FLAG_NONE,
66 false,
67 INVALID,
68 NULL,
70 DATA_FLAG_NONE
72 static const char* const kGetHeaders[] = {
73 "method",
74 "GET",
75 "scheme",
76 "http",
77 "host",
78 "www.google.com",
79 "url",
80 "/",
81 "version",
82 "HTTP/1.1",
84 scoped_ptr<SpdyFrame> req(
85 ConstructSpdyPacket(
86 kSynStartHeader, NULL, 0, kGetHeaders, arraysize(kGetHeaders) / 2));
87 scoped_ptr<SpdyFrame> msg(
88 ConstructSpdyBodyFrame("\0hello!\xff", 8));
89 MockWrite writes[] = {
90 CreateMockWrite(*req),
91 CreateMockWrite(*msg),
93 writes[0].sequence_number = 0;
94 writes[1].sequence_number = 2;
96 scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
97 scoped_ptr<SpdyFrame> echo(
98 ConstructSpdyBodyFrame("\0hello!\xff", 8));
99 MockRead reads[] = {
100 CreateMockRead(*resp),
101 CreateMockRead(*echo),
102 MockRead(ASYNC, 0, 0), // EOF
104 reads[0].sequence_number = 1;
105 reads[1].sequence_number = 3;
106 reads[2].sequence_number = 4;
108 OrderedSocketData data(reads, arraysize(reads),
109 writes, arraysize(writes));
110 MockConnect connect_data(SYNCHRONOUS, OK);
111 data.set_connect_data(connect_data);
113 session_deps.socket_factory->AddSocketDataProvider(&data);
115 scoped_refptr<SpdySession> session(CreateSpdySession());
116 const char* kStreamUrl = "http://www.google.com/";
117 GURL url(kStreamUrl);
119 HostPortPair host_port_pair("www.google.com", 80);
120 scoped_refptr<TransportSocketParams> transport_params(
121 new TransportSocketParams(host_port_pair, LOWEST, false, false,
122 OnHostResolutionCallback()));
124 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
125 EXPECT_EQ(OK, connection->Init(host_port_pair.ToString(), transport_params,
126 LOWEST, CompletionCallback(),
127 session_->GetTransportSocketPool(
128 HttpNetworkSession::NORMAL_SOCKET_POOL),
129 BoundNetLog()));
130 session->InitializeWithSocket(connection.release(), false, OK);
132 scoped_refptr<SpdyStream> stream;
133 ASSERT_EQ(
135 session->CreateStream(url, LOWEST, &stream, BoundNetLog(),
136 CompletionCallback()));
137 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(8));
138 memcpy(buf->data(), "\0hello!\xff", 8);
139 TestCompletionCallback callback;
141 scoped_ptr<TestSpdyStreamDelegate> delegate(
142 new TestSpdyStreamDelegate(
143 stream.get(), NULL, buf.get(), callback.callback()));
144 stream->SetDelegate(delegate.get());
146 EXPECT_FALSE(stream->HasUrl());
148 scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
149 (*headers)["method"] = "GET";
150 (*headers)["scheme"] = url.scheme();
151 (*headers)["host"] = url.host();
152 (*headers)["url"] = url.path();
153 (*headers)["version"] = "HTTP/1.1";
154 stream->set_spdy_headers(headers.Pass());
155 EXPECT_TRUE(stream->HasUrl());
156 EXPECT_EQ(kStreamUrl, stream->GetUrl().spec());
158 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequest(true));
160 EXPECT_EQ(OK, callback.WaitForResult());
162 EXPECT_TRUE(delegate->send_headers_completed());
163 EXPECT_EQ("200", (*delegate->response())["status"]);
164 EXPECT_EQ("HTTP/1.1", (*delegate->response())["version"]);
165 EXPECT_EQ(std::string("\0hello!\xff", 8), delegate->received_data());
166 EXPECT_EQ(8, delegate->data_sent());
167 EXPECT_TRUE(delegate->closed());
170 TEST_F(SpdyStreamSpdy2Test, SendHeaderAndDataAfterOpen) {
171 SpdySessionDependencies session_deps;
173 session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps);
174 SpdySessionPoolPeer pool_peer_(session_->spdy_session_pool());
176 scoped_ptr<SpdyFrame> expected_request(ConstructSpdyWebSocketSynStream(
178 "/chat",
179 "server.example.com",
180 "http://example.com"));
181 scoped_ptr<SpdyFrame> expected_headers(ConstructSpdyWebSocketHeadersFrame(
182 1, "6", true));
183 scoped_ptr<SpdyFrame> expected_message(ConstructSpdyBodyFrame("hello!", 6));
184 MockWrite writes[] = {
185 CreateMockWrite(*expected_request),
186 CreateMockWrite(*expected_headers),
187 CreateMockWrite(*expected_message)
189 writes[0].sequence_number = 0;
190 writes[1].sequence_number = 2;
191 writes[1].sequence_number = 3;
193 scoped_ptr<SpdyFrame> response(
194 ConstructSpdyWebSocketSynReply(1));
195 MockRead reads[] = {
196 CreateMockRead(*response),
197 MockRead(ASYNC, 0, 0), // EOF
199 reads[0].sequence_number = 1;
200 reads[1].sequence_number = 4;
202 OrderedSocketData data(reads, arraysize(reads),
203 writes, arraysize(writes));
204 MockConnect connect_data(SYNCHRONOUS, OK);
205 data.set_connect_data(connect_data);
207 session_deps.socket_factory->AddSocketDataProvider(&data);
209 scoped_refptr<SpdySession> session(CreateSpdySession());
210 const char* kStreamUrl = "ws://server.example.com/chat";
211 GURL url(kStreamUrl);
213 HostPortPair host_port_pair("server.example.com", 80);
214 scoped_refptr<TransportSocketParams> transport_params(
215 new TransportSocketParams(host_port_pair, LOWEST, false, false,
216 OnHostResolutionCallback()));
218 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
219 EXPECT_EQ(OK, connection->Init(host_port_pair.ToString(), transport_params,
220 LOWEST, CompletionCallback(),
221 session_->GetTransportSocketPool(
222 HttpNetworkSession::NORMAL_SOCKET_POOL),
223 BoundNetLog()));
224 session->InitializeWithSocket(connection.release(), false, OK);
226 scoped_refptr<SpdyStream> stream;
227 ASSERT_EQ(
229 session->CreateStream(url, HIGHEST, &stream, BoundNetLog(),
230 CompletionCallback()));
231 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(6));
232 memcpy(buf->data(), "hello!", 6);
233 TestCompletionCallback callback;
234 scoped_ptr<SpdyHeaderBlock> message_headers(new SpdyHeaderBlock);
235 (*message_headers)["opcode"] = "1";
236 (*message_headers)["length"] = "6";
237 (*message_headers)["fin"] = "1";
239 scoped_ptr<TestSpdyStreamDelegate> delegate(
240 new TestSpdyStreamDelegate(stream.get(),
241 message_headers.release(),
242 buf.get(),
243 callback.callback()));
244 stream->SetDelegate(delegate.get());
246 EXPECT_FALSE(stream->HasUrl());
248 scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
249 (*headers)["path"] = url.path();
250 (*headers)["host"] = url.host();
251 (*headers)["version"] = "WebSocket/13";
252 (*headers)["scheme"] = url.scheme();
253 (*headers)["origin"] = "http://example.com";
254 stream->set_spdy_headers(headers.Pass());
255 EXPECT_TRUE(stream->HasUrl());
257 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequest(true));
259 EXPECT_EQ(OK, callback.WaitForResult());
261 EXPECT_TRUE(delegate->send_headers_completed());
262 EXPECT_EQ("101", (*delegate->response())["status"]);
263 EXPECT_EQ(1, delegate->headers_sent());
264 EXPECT_EQ(std::string(), delegate->received_data());
265 EXPECT_EQ(6, delegate->data_sent());
268 TEST_F(SpdyStreamSpdy2Test, PushedStream) {
269 const char kStreamUrl[] = "http://www.google.com/";
271 SpdySessionDependencies session_deps;
272 session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps);
273 SpdySessionPoolPeer pool_peer_(session_->spdy_session_pool());
274 scoped_refptr<SpdySession> spdy_session(CreateSpdySession());
276 MockRead reads[] = {
277 MockRead(ASYNC, 0, 0), // EOF
280 OrderedSocketData data(reads, arraysize(reads), NULL, 0);
281 MockConnect connect_data(SYNCHRONOUS, OK);
282 data.set_connect_data(connect_data);
284 session_deps.socket_factory->AddSocketDataProvider(&data);
286 HostPortPair host_port_pair("www.google.com", 80);
287 scoped_refptr<TransportSocketParams> transport_params(
288 new TransportSocketParams(host_port_pair, LOWEST, false, false,
289 OnHostResolutionCallback()));
291 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
292 EXPECT_EQ(OK, connection->Init(host_port_pair.ToString(), transport_params,
293 LOWEST, CompletionCallback(),
294 session_->GetTransportSocketPool(
295 HttpNetworkSession::NORMAL_SOCKET_POOL),
296 BoundNetLog()));
297 spdy_session->InitializeWithSocket(connection.release(), false, OK);
298 BoundNetLog net_log;
300 // Conjure up a stream.
301 scoped_refptr<SpdyStream> stream = new SpdyStream(spdy_session,
302 true,
303 net_log);
304 stream->set_stream_id(2);
305 EXPECT_FALSE(stream->response_received());
306 EXPECT_FALSE(stream->HasUrl());
308 // Set a couple of headers.
309 SpdyHeaderBlock response;
310 response["url"] = kStreamUrl;
311 stream->OnResponseReceived(response);
313 // Send some basic headers.
314 SpdyHeaderBlock headers;
315 response["status"] = "200";
316 response["version"] = "OK";
317 stream->OnHeaders(headers);
319 stream->set_response_received();
320 EXPECT_TRUE(stream->response_received());
321 EXPECT_TRUE(stream->HasUrl());
322 EXPECT_EQ(kStreamUrl, stream->GetUrl().spec());
325 TEST_F(SpdyStreamSpdy2Test, StreamError) {
326 SpdySessionDependencies session_deps;
328 session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps);
329 SpdySessionPoolPeer pool_peer_(session_->spdy_session_pool());
331 const SpdyHeaderInfo kSynStartHeader = {
332 SYN_STREAM,
335 ConvertRequestPriorityToSpdyPriority(LOWEST, 2),
336 CONTROL_FLAG_NONE,
337 false,
338 INVALID,
339 NULL,
341 DATA_FLAG_NONE
343 static const char* const kGetHeaders[] = {
344 "method",
345 "GET",
346 "scheme",
347 "http",
348 "host",
349 "www.google.com",
350 "url",
351 "/",
352 "version",
353 "HTTP/1.1",
355 scoped_ptr<SpdyFrame> req(
356 ConstructSpdyPacket(
357 kSynStartHeader, NULL, 0, kGetHeaders, arraysize(kGetHeaders) / 2));
358 scoped_ptr<SpdyFrame> msg(
359 ConstructSpdyBodyFrame("\0hello!\xff", 8));
360 MockWrite writes[] = {
361 CreateMockWrite(*req),
362 CreateMockWrite(*msg),
364 writes[0].sequence_number = 0;
365 writes[1].sequence_number = 2;
367 scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
368 scoped_ptr<SpdyFrame> echo(
369 ConstructSpdyBodyFrame("\0hello!\xff", 8));
370 MockRead reads[] = {
371 CreateMockRead(*resp),
372 CreateMockRead(*echo),
373 MockRead(ASYNC, 0, 0), // EOF
375 reads[0].sequence_number = 1;
376 reads[1].sequence_number = 3;
377 reads[2].sequence_number = 4;
379 CapturingBoundNetLog log;
381 OrderedSocketData data(reads, arraysize(reads),
382 writes, arraysize(writes));
383 MockConnect connect_data(SYNCHRONOUS, OK);
384 data.set_connect_data(connect_data);
386 session_deps.socket_factory->AddSocketDataProvider(&data);
388 scoped_refptr<SpdySession> session(CreateSpdySession());
389 const char* kStreamUrl = "http://www.google.com/";
390 GURL url(kStreamUrl);
392 HostPortPair host_port_pair("www.google.com", 80);
393 scoped_refptr<TransportSocketParams> transport_params(
394 new TransportSocketParams(host_port_pair, LOWEST, false, false,
395 OnHostResolutionCallback()));
397 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
398 EXPECT_EQ(OK, connection->Init(host_port_pair.ToString(), transport_params,
399 LOWEST, CompletionCallback(),
400 session_->GetTransportSocketPool(
401 HttpNetworkSession::NORMAL_SOCKET_POOL),
402 log.bound()));
403 session->InitializeWithSocket(connection.release(), false, OK);
405 scoped_refptr<SpdyStream> stream;
406 ASSERT_EQ(
408 session->CreateStream(url, LOWEST, &stream, log.bound(),
409 CompletionCallback()));
410 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(8));
411 memcpy(buf->data(), "\0hello!\xff", 8);
412 TestCompletionCallback callback;
414 scoped_ptr<TestSpdyStreamDelegate> delegate(
415 new TestSpdyStreamDelegate(
416 stream.get(), NULL, buf.get(), callback.callback()));
417 stream->SetDelegate(delegate.get());
419 EXPECT_FALSE(stream->HasUrl());
421 scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
422 (*headers)["method"] = "GET";
423 (*headers)["scheme"] = url.scheme();
424 (*headers)["host"] = url.host();
425 (*headers)["url"] = url.path();
426 (*headers)["version"] = "HTTP/1.1";
427 stream->set_spdy_headers(headers.Pass());
428 EXPECT_TRUE(stream->HasUrl());
429 EXPECT_EQ(kStreamUrl, stream->GetUrl().spec());
431 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequest(true));
433 EXPECT_EQ(OK, callback.WaitForResult());
435 const SpdyStreamId stream_id = stream->stream_id();
437 EXPECT_TRUE(delegate->send_headers_completed());
438 EXPECT_EQ("200", (*delegate->response())["status"]);
439 EXPECT_EQ("HTTP/1.1", (*delegate->response())["version"]);
440 EXPECT_EQ(std::string("\0hello!\xff", 8), delegate->received_data());
441 EXPECT_EQ(8, delegate->data_sent());
442 EXPECT_TRUE(delegate->closed());
444 // Check that the NetLog was filled reasonably.
445 net::CapturingNetLog::CapturedEntryList entries;
446 log.GetEntries(&entries);
447 EXPECT_LT(0u, entries.size());
449 // Check that we logged SPDY_STREAM_ERROR correctly.
450 int pos = net::ExpectLogContainsSomewhere(
451 entries, 0,
452 net::NetLog::TYPE_SPDY_STREAM_ERROR,
453 net::NetLog::PHASE_NONE);
455 int stream_id2;
456 ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &stream_id2));
457 EXPECT_EQ(static_cast<int>(stream_id), stream_id2);
460 } //namespace test
462 } // namespace net