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

Side by Side Diff: net/spdy/spdy_websocket_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_websocket_stream_spdy3_unittest.cc ('k') | net/spdy/spdy_websocket_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 "net/spdy/spdy_websocket_stream.h"
6
7 #include <string>
8 #include <vector>
9
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "net/base/completion_callback.h"
13 #include "net/proxy/proxy_server.h"
14 #include "net/spdy/spdy_http_utils.h"
15 #include "net/spdy/spdy_protocol.h"
16 #include "net/spdy/spdy_session.h"
17 #include "net/spdy/spdy_test_util.h"
18 #include "net/spdy/spdy_websocket_test_util.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 namespace {
22
23 struct SpdyWebSocketStreamEvent {
24 enum EventType {
25 EVENT_CREATED,
26 EVENT_SENT_HEADERS,
27 EVENT_RECEIVED_HEADER,
28 EVENT_SENT_DATA,
29 EVENT_RECEIVED_DATA,
30 EVENT_CLOSE,
31 };
32 SpdyWebSocketStreamEvent(EventType type,
33 const spdy::SpdyHeaderBlock& headers,
34 int result,
35 const std::string& data)
36 : event_type(type),
37 headers(headers),
38 result(result),
39 data(data) {}
40
41 EventType event_type;
42 spdy::SpdyHeaderBlock headers;
43 int result;
44 std::string data;
45 };
46
47 } // namespace
48
49 namespace net {
50
51 class SpdyWebSocketStreamEventRecorder : public SpdyWebSocketStream::Delegate {
52 public:
53 explicit SpdyWebSocketStreamEventRecorder(const CompletionCallback& callback)
54 : callback_(callback) {}
55 virtual ~SpdyWebSocketStreamEventRecorder() {}
56
57 typedef base::Callback<void(SpdyWebSocketStreamEvent*)> StreamEventCallback;
58
59 void SetOnCreated(const StreamEventCallback& callback) {
60 on_created_ = callback;
61 }
62 void SetOnSentHeaders(const StreamEventCallback& callback) {
63 on_sent_headers_ = callback;
64 }
65 void SetOnReceivedHeader(
66 const StreamEventCallback& callback) {
67 on_received_header_ = callback;
68 }
69 void SetOnSentData(const StreamEventCallback& callback) {
70 on_sent_data_ = callback;
71 }
72 void SetOnReceivedData(
73 const StreamEventCallback& callback) {
74 on_received_data_ = callback;
75 }
76 void SetOnClose(const StreamEventCallback& callback) {
77 on_close_ = callback;
78 }
79
80 virtual void OnCreatedSpdyStream(int result) {
81 events_.push_back(
82 SpdyWebSocketStreamEvent(SpdyWebSocketStreamEvent::EVENT_CREATED,
83 spdy::SpdyHeaderBlock(),
84 result,
85 std::string()));
86 if (!on_created_.is_null())
87 on_created_.Run(&events_.back());
88 }
89 virtual void OnSentSpdyHeaders(int result) {
90 events_.push_back(
91 SpdyWebSocketStreamEvent(SpdyWebSocketStreamEvent::EVENT_SENT_HEADERS,
92 spdy::SpdyHeaderBlock(),
93 result,
94 std::string()));
95 if (!on_sent_data_.is_null())
96 on_sent_data_.Run(&events_.back());
97 }
98 virtual int OnReceivedSpdyResponseHeader(
99 const spdy::SpdyHeaderBlock& headers, int status) {
100 events_.push_back(
101 SpdyWebSocketStreamEvent(
102 SpdyWebSocketStreamEvent::EVENT_RECEIVED_HEADER,
103 headers,
104 status,
105 std::string()));
106 if (!on_received_header_.is_null())
107 on_received_header_.Run(&events_.back());
108 return status;
109 }
110 virtual void OnSentSpdyData(int amount_sent) {
111 events_.push_back(
112 SpdyWebSocketStreamEvent(
113 SpdyWebSocketStreamEvent::EVENT_SENT_DATA,
114 spdy::SpdyHeaderBlock(),
115 amount_sent,
116 std::string()));
117 if (!on_sent_data_.is_null())
118 on_sent_data_.Run(&events_.back());
119 }
120 virtual void OnReceivedSpdyData(const char* data, int length) {
121 events_.push_back(
122 SpdyWebSocketStreamEvent(
123 SpdyWebSocketStreamEvent::EVENT_RECEIVED_DATA,
124 spdy::SpdyHeaderBlock(),
125 length,
126 std::string(data, length)));
127 if (!on_received_data_.is_null())
128 on_received_data_.Run(&events_.back());
129 }
130 virtual void OnCloseSpdyStream() {
131 events_.push_back(
132 SpdyWebSocketStreamEvent(
133 SpdyWebSocketStreamEvent::EVENT_CLOSE,
134 spdy::SpdyHeaderBlock(),
135 OK,
136 std::string()));
137 if (!on_close_.is_null())
138 on_close_.Run(&events_.back());
139 if (!callback_.is_null())
140 callback_.Run(OK);
141 }
142
143 const std::vector<SpdyWebSocketStreamEvent>& GetSeenEvents() const {
144 return events_;
145 }
146
147 private:
148 std::vector<SpdyWebSocketStreamEvent> events_;
149 StreamEventCallback on_created_;
150 StreamEventCallback on_sent_headers_;
151 StreamEventCallback on_received_header_;
152 StreamEventCallback on_sent_data_;
153 StreamEventCallback on_received_data_;
154 StreamEventCallback on_close_;
155 CompletionCallback callback_;
156
157 DISALLOW_COPY_AND_ASSIGN(SpdyWebSocketStreamEventRecorder);
158 };
159
160 class SpdyWebSocketStreamTest : public testing::Test {
161 public:
162 OrderedSocketData* data() { return data_.get(); }
163
164 void DoSendHelloFrame(SpdyWebSocketStreamEvent* event) {
165 websocket_stream_->SendData(kMessageFrame, kMessageFrameLength);
166 }
167
168 void DoSendClosingFrame(SpdyWebSocketStreamEvent* event) {
169 websocket_stream_->SendData(kClosingFrame, kClosingFrameLength);
170 }
171
172 void DoClose(SpdyWebSocketStreamEvent* event) {
173 websocket_stream_->Close();
174 }
175
176 void DoSync(SpdyWebSocketStreamEvent* event) {
177 sync_callback_.SetResult(OK);
178 }
179
180 protected:
181 SpdyWebSocketStreamTest() {}
182 virtual ~SpdyWebSocketStreamTest() {}
183
184 virtual void SetUp() {
185 EnableCompression(false);
186 SpdySession::SetSSLMode(false);
187
188 host_port_pair_.set_host("example.com");
189 host_port_pair_.set_port(80);
190 host_port_proxy_pair_.first = host_port_pair_;
191 host_port_proxy_pair_.second = ProxyServer::Direct();
192
193 const size_t max_concurrent_streams = 1;
194 spdy::SettingsFlagsAndId id(0);
195 id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS);
196
197 id.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST);
198 spdy_settings_to_set_.push_back(
199 spdy::SpdySetting(id, max_concurrent_streams));
200
201 id.set_flags(spdy::SETTINGS_FLAG_PERSISTED);
202 spdy_settings_to_send_.push_back(
203 spdy::SpdySetting(id, max_concurrent_streams));
204 }
205 virtual void TearDown() {
206 MessageLoop::current()->RunAllPending();
207 }
208
209 void EnableCompression(bool enabled) {
210 spdy::SpdyFramer::set_enable_compression_default(enabled);
211 }
212 void Prepare(spdy::SpdyStreamId stream_id) {
213 stream_id_ = stream_id;
214
215 const char* const request_headers[] = {
216 "url", "ws://example.com/echo",
217 "origin", "http://example.com/wsdemo",
218 };
219
220 int request_header_count = arraysize(request_headers) / 2;
221
222 const char* const response_headers[] = {
223 "sec-websocket-location", "ws://example.com/echo",
224 "sec-websocket-origin", "http://example.com/wsdemo",
225 };
226
227 int response_header_count = arraysize(response_headers) / 2;
228
229 request_frame_.reset(ConstructSpdyWebSocketHandshakeRequestFrame(
230 request_headers,
231 request_header_count,
232 stream_id_,
233 HIGHEST));
234 response_frame_.reset(ConstructSpdyWebSocketHandshakeResponseFrame(
235 response_headers,
236 response_header_count,
237 stream_id_,
238 HIGHEST));
239
240 message_frame_.reset(ConstructSpdyWebSocketDataFrame(
241 kMessageFrame,
242 kMessageFrameLength,
243 stream_id_,
244 false));
245
246 closing_frame_.reset(ConstructSpdyWebSocketDataFrame(
247 kClosingFrame,
248 kClosingFrameLength,
249 stream_id_,
250 false));
251 }
252 int InitSession(MockRead* reads, size_t reads_count,
253 MockWrite* writes, size_t writes_count,
254 bool throttling) {
255 data_.reset(new OrderedSocketData(reads, reads_count,
256 writes, writes_count));
257 session_deps_.socket_factory->AddSocketDataProvider(data_.get());
258 http_session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
259 SpdySessionPool* spdy_session_pool(http_session_->spdy_session_pool());
260
261 if (throttling) {
262 // Set max concurrent streams to 1.
263 spdy_session_pool->http_server_properties()->SetSpdySettings(
264 host_port_pair_, spdy_settings_to_set_);
265 }
266
267 EXPECT_FALSE(spdy_session_pool->HasSession(host_port_proxy_pair_));
268 session_ = spdy_session_pool->Get(host_port_proxy_pair_, BoundNetLog());
269 EXPECT_TRUE(spdy_session_pool->HasSession(host_port_proxy_pair_));
270 transport_params_ = new TransportSocketParams(host_port_pair_, MEDIUM,
271 false, false);
272 TestCompletionCallback callback;
273 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
274 EXPECT_EQ(ERR_IO_PENDING,
275 connection->Init(host_port_pair_.ToString(), transport_params_,
276 MEDIUM, callback.callback(),
277 http_session_->GetTransportSocketPool(),
278 BoundNetLog()));
279 EXPECT_EQ(OK, callback.WaitForResult());
280 return session_->InitializeWithSocket(connection.release(), false, OK);
281 }
282 void SendRequest() {
283 linked_ptr<spdy::SpdyHeaderBlock> headers(new spdy::SpdyHeaderBlock);
284 (*headers)["url"] = "ws://example.com/echo";
285 (*headers)["origin"] = "http://example.com/wsdemo";
286
287 websocket_stream_->SendRequest(headers);
288 }
289
290 spdy::SpdySettings spdy_settings_to_set_;
291 spdy::SpdySettings spdy_settings_to_send_;
292 SpdySessionDependencies session_deps_;
293 scoped_ptr<OrderedSocketData> data_;
294 scoped_refptr<HttpNetworkSession> http_session_;
295 scoped_refptr<SpdySession> session_;
296 scoped_refptr<TransportSocketParams> transport_params_;
297 scoped_ptr<SpdyWebSocketStream> websocket_stream_;
298 spdy::SpdyStreamId stream_id_;
299 scoped_ptr<spdy::SpdyFrame> request_frame_;
300 scoped_ptr<spdy::SpdyFrame> response_frame_;
301 scoped_ptr<spdy::SpdyFrame> message_frame_;
302 scoped_ptr<spdy::SpdyFrame> closing_frame_;
303 HostPortPair host_port_pair_;
304 HostPortProxyPair host_port_proxy_pair_;
305 TestCompletionCallback completion_callback_;
306 TestCompletionCallback sync_callback_;
307
308 static const char kMessageFrame[];
309 static const char kClosingFrame[];
310 static const size_t kMessageFrameLength;
311 static const size_t kClosingFrameLength;
312 };
313
314 const char SpdyWebSocketStreamTest::kMessageFrame[] = "\0hello\xff";
315 const char SpdyWebSocketStreamTest::kClosingFrame[] = "\xff\0";
316 const size_t SpdyWebSocketStreamTest::kMessageFrameLength =
317 arraysize(SpdyWebSocketStreamTest::kMessageFrame) - 1;
318 const size_t SpdyWebSocketStreamTest::kClosingFrameLength =
319 arraysize(SpdyWebSocketStreamTest::kClosingFrame) - 1;
320
321 TEST_F(SpdyWebSocketStreamTest, Basic) {
322 Prepare(1);
323 MockWrite writes[] = {
324 CreateMockWrite(*request_frame_.get(), 1),
325 CreateMockWrite(*message_frame_.get(), 3),
326 CreateMockWrite(*closing_frame_.get(), 5)
327 };
328
329 MockRead reads[] = {
330 CreateMockRead(*response_frame_.get(), 2),
331 CreateMockRead(*message_frame_.get(), 4),
332 // Skip sequence 6 to notify closing has been sent.
333 CreateMockRead(*closing_frame_.get(), 7),
334 MockRead(SYNCHRONOUS, 0, 8) // EOF cause OnCloseSpdyStream event.
335 };
336
337 EXPECT_EQ(OK, InitSession(reads, arraysize(reads),
338 writes, arraysize(writes), false));
339
340 SpdyWebSocketStreamEventRecorder delegate(completion_callback_.callback());
341 delegate.SetOnReceivedHeader(
342 base::Bind(&SpdyWebSocketStreamTest::DoSendHelloFrame,
343 base::Unretained(this)));
344 delegate.SetOnReceivedData(
345 base::Bind(&SpdyWebSocketStreamTest::DoSendClosingFrame,
346 base::Unretained(this)));
347
348 websocket_stream_.reset(new SpdyWebSocketStream(session_, &delegate));
349
350 BoundNetLog net_log;
351 GURL url("ws://example.com/echo");
352 ASSERT_EQ(OK, websocket_stream_->InitializeStream(url, HIGHEST, net_log));
353
354 ASSERT_TRUE(websocket_stream_->stream_);
355 EXPECT_EQ(stream_id_, websocket_stream_->stream_->stream_id());
356
357 SendRequest();
358
359 completion_callback_.WaitForResult();
360
361 websocket_stream_.reset();
362
363 const std::vector<SpdyWebSocketStreamEvent>& events =
364 delegate.GetSeenEvents();
365 ASSERT_EQ(7U, events.size());
366
367 EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_HEADERS,
368 events[0].event_type);
369 EXPECT_LT(0, events[0].result);
370 EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_HEADER,
371 events[1].event_type);
372 EXPECT_EQ(OK, events[1].result);
373 EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_DATA,
374 events[2].event_type);
375 EXPECT_EQ(static_cast<int>(kMessageFrameLength), events[2].result);
376 EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_DATA,
377 events[3].event_type);
378 EXPECT_EQ(static_cast<int>(kMessageFrameLength), events[3].result);
379 EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_DATA,
380 events[4].event_type);
381 EXPECT_EQ(static_cast<int>(kClosingFrameLength), events[4].result);
382 EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_DATA,
383 events[5].event_type);
384 EXPECT_EQ(static_cast<int>(kClosingFrameLength), events[5].result);
385 EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_CLOSE,
386 events[6].event_type);
387 EXPECT_EQ(OK, events[6].result);
388
389 // EOF close SPDY session.
390 EXPECT_TRUE(!http_session_->spdy_session_pool()->HasSession(
391 host_port_proxy_pair_));
392 EXPECT_TRUE(data()->at_read_eof());
393 EXPECT_TRUE(data()->at_write_eof());
394 }
395
396 TEST_F(SpdyWebSocketStreamTest, DestructionBeforeClose) {
397 Prepare(1);
398 MockWrite writes[] = {
399 CreateMockWrite(*request_frame_.get(), 1),
400 CreateMockWrite(*message_frame_.get(), 3)
401 };
402
403 MockRead reads[] = {
404 CreateMockRead(*response_frame_.get(), 2),
405 CreateMockRead(*message_frame_.get(), 4),
406 MockRead(ASYNC, ERR_IO_PENDING, 5)
407 };
408
409 EXPECT_EQ(OK, InitSession(reads, arraysize(reads),
410 writes, arraysize(writes), false));
411
412 SpdyWebSocketStreamEventRecorder delegate(completion_callback_.callback());
413 delegate.SetOnReceivedHeader(
414 base::Bind(&SpdyWebSocketStreamTest::DoSendHelloFrame,
415 base::Unretained(this)));
416 delegate.SetOnReceivedData(
417 base::Bind(&SpdyWebSocketStreamTest::DoSync, base::Unretained(this)));
418
419 websocket_stream_.reset(new SpdyWebSocketStream(session_, &delegate));
420
421 BoundNetLog net_log;
422 GURL url("ws://example.com/echo");
423 ASSERT_EQ(OK, websocket_stream_->InitializeStream(url, HIGHEST, net_log));
424
425 SendRequest();
426
427 sync_callback_.WaitForResult();
428
429 // WebSocketStream destruction remove its SPDY stream from the session.
430 EXPECT_TRUE(session_->IsStreamActive(stream_id_));
431 websocket_stream_.reset();
432 EXPECT_FALSE(session_->IsStreamActive(stream_id_));
433
434 const std::vector<SpdyWebSocketStreamEvent>& events =
435 delegate.GetSeenEvents();
436 ASSERT_GE(4U, events.size());
437
438 EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_HEADERS,
439 events[0].event_type);
440 EXPECT_LT(0, events[0].result);
441 EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_HEADER,
442 events[1].event_type);
443 EXPECT_EQ(OK, events[1].result);
444 EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_DATA,
445 events[2].event_type);
446 EXPECT_EQ(static_cast<int>(kMessageFrameLength), events[2].result);
447 EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_DATA,
448 events[3].event_type);
449 EXPECT_EQ(static_cast<int>(kMessageFrameLength), events[3].result);
450
451 EXPECT_TRUE(http_session_->spdy_session_pool()->HasSession(
452 host_port_proxy_pair_));
453 EXPECT_TRUE(data()->at_read_eof());
454 EXPECT_TRUE(data()->at_write_eof());
455 }
456
457 TEST_F(SpdyWebSocketStreamTest, DestructionAfterExplicitClose) {
458 Prepare(1);
459 MockWrite writes[] = {
460 CreateMockWrite(*request_frame_.get(), 1),
461 CreateMockWrite(*message_frame_.get(), 3),
462 CreateMockWrite(*closing_frame_.get(), 5)
463 };
464
465 MockRead reads[] = {
466 CreateMockRead(*response_frame_.get(), 2),
467 CreateMockRead(*message_frame_.get(), 4),
468 MockRead(ASYNC, ERR_IO_PENDING, 6)
469 };
470
471 EXPECT_EQ(OK, InitSession(reads, arraysize(reads),
472 writes, arraysize(writes), false));
473
474 SpdyWebSocketStreamEventRecorder delegate(completion_callback_.callback());
475 delegate.SetOnReceivedHeader(
476 base::Bind(&SpdyWebSocketStreamTest::DoSendHelloFrame,
477 base::Unretained(this)));
478 delegate.SetOnReceivedData(
479 base::Bind(&SpdyWebSocketStreamTest::DoClose, base::Unretained(this)));
480
481 websocket_stream_.reset(new SpdyWebSocketStream(session_, &delegate));
482
483 BoundNetLog net_log;
484 GURL url("ws://example.com/echo");
485 ASSERT_EQ(OK, websocket_stream_->InitializeStream(url, HIGHEST, net_log));
486
487 SendRequest();
488
489 completion_callback_.WaitForResult();
490
491 // SPDY stream has already been removed from the session by Close().
492 EXPECT_FALSE(session_->IsStreamActive(stream_id_));
493 websocket_stream_.reset();
494
495 const std::vector<SpdyWebSocketStreamEvent>& events =
496 delegate.GetSeenEvents();
497 ASSERT_EQ(5U, events.size());
498
499 EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_HEADERS,
500 events[0].event_type);
501 EXPECT_LT(0, events[0].result);
502 EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_HEADER,
503 events[1].event_type);
504 EXPECT_EQ(OK, events[1].result);
505 EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_DATA,
506 events[2].event_type);
507 EXPECT_EQ(static_cast<int>(kMessageFrameLength), events[2].result);
508 EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_DATA,
509 events[3].event_type);
510 EXPECT_EQ(static_cast<int>(kMessageFrameLength), events[3].result);
511 EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_CLOSE, events[4].event_type);
512
513 EXPECT_TRUE(http_session_->spdy_session_pool()->HasSession(
514 host_port_proxy_pair_));
515 }
516
517 TEST_F(SpdyWebSocketStreamTest, IOPending) {
518 Prepare(3);
519 scoped_ptr<spdy::SpdyFrame> settings_frame(
520 ConstructSpdySettings(spdy_settings_to_send_));
521 MockWrite writes[] = {
522 // Setting throttling make SpdySession send settings frame automatically.
523 CreateMockWrite(*settings_frame.get(), 1),
524 CreateMockWrite(*request_frame_.get(), 3),
525 CreateMockWrite(*message_frame_.get(), 6),
526 CreateMockWrite(*closing_frame_.get(), 9)
527 };
528
529 MockRead reads[] = {
530 CreateMockRead(*settings_frame.get(), 2),
531 CreateMockRead(*response_frame_.get(), 4),
532 // Skip sequence 5 (I/O Pending)
533 CreateMockRead(*message_frame_.get(), 7),
534 // Skip sequence 8 (I/O Pending)
535 CreateMockRead(*closing_frame_.get(), 10),
536 MockRead(SYNCHRONOUS, 0, 11) // EOF cause OnCloseSpdyStream event.
537 };
538
539 EXPECT_EQ(OK, InitSession(reads, arraysize(reads),
540 writes, arraysize(writes), true));
541
542 // Create a dummy WebSocketStream which cause ERR_IO_PENDING to another
543 // WebSocketStream under test.
544 SpdyWebSocketStreamEventRecorder block_delegate((CompletionCallback()));
545
546 scoped_ptr<SpdyWebSocketStream> block_stream(
547 new SpdyWebSocketStream(session_, &block_delegate));
548 BoundNetLog block_net_log;
549 GURL block_url("ws://example.com/block");
550 ASSERT_EQ(OK,
551 block_stream->InitializeStream(block_url, HIGHEST, block_net_log));
552
553 // Create a WebSocketStream under test.
554 SpdyWebSocketStreamEventRecorder delegate(completion_callback_.callback());
555 delegate.SetOnCreated(
556 base::Bind(&SpdyWebSocketStreamTest::DoSync, base::Unretained(this)));
557 delegate.SetOnReceivedHeader(
558 base::Bind(&SpdyWebSocketStreamTest::DoSendHelloFrame,
559 base::Unretained(this)));
560 delegate.SetOnReceivedData(
561 base::Bind(&SpdyWebSocketStreamTest::DoSendClosingFrame,
562 base::Unretained(this)));
563
564 websocket_stream_.reset(new SpdyWebSocketStream(session_, &delegate));
565 BoundNetLog net_log;
566 GURL url("ws://example.com/echo");
567 ASSERT_EQ(ERR_IO_PENDING, websocket_stream_->InitializeStream(
568 url, HIGHEST, net_log));
569
570 // Delete the fist stream to allow create the second stream.
571 block_stream.reset();
572 ASSERT_EQ(OK, sync_callback_.WaitForResult());
573
574 SendRequest();
575
576 completion_callback_.WaitForResult();
577
578 websocket_stream_.reset();
579
580 const std::vector<SpdyWebSocketStreamEvent>& block_events =
581 block_delegate.GetSeenEvents();
582 ASSERT_EQ(0U, block_events.size());
583
584 const std::vector<SpdyWebSocketStreamEvent>& events =
585 delegate.GetSeenEvents();
586 ASSERT_EQ(8U, events.size());
587 EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_CREATED,
588 events[0].event_type);
589 EXPECT_EQ(0, events[0].result);
590 EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_HEADERS,
591 events[1].event_type);
592 EXPECT_LT(0, events[1].result);
593 EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_HEADER,
594 events[2].event_type);
595 EXPECT_EQ(OK, events[2].result);
596 EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_DATA,
597 events[3].event_type);
598 EXPECT_EQ(static_cast<int>(kMessageFrameLength), events[3].result);
599 EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_DATA,
600 events[4].event_type);
601 EXPECT_EQ(static_cast<int>(kMessageFrameLength), events[4].result);
602 EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_SENT_DATA,
603 events[5].event_type);
604 EXPECT_EQ(static_cast<int>(kClosingFrameLength), events[5].result);
605 EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_RECEIVED_DATA,
606 events[6].event_type);
607 EXPECT_EQ(static_cast<int>(kClosingFrameLength), events[6].result);
608 EXPECT_EQ(SpdyWebSocketStreamEvent::EVENT_CLOSE,
609 events[7].event_type);
610 EXPECT_EQ(OK, events[7].result);
611
612 // EOF close SPDY session.
613 EXPECT_TRUE(!http_session_->spdy_session_pool()->HasSession(
614 host_port_proxy_pair_));
615 EXPECT_TRUE(data()->at_read_eof());
616 EXPECT_TRUE(data()->at_write_eof());
617 }
618
619 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_websocket_stream_spdy3_unittest.cc ('k') | net/spdy/spdy_websocket_test_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698