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

Side by Side Diff: net/websockets/websocket_basic_stream_test.cc

Issue 18792002: WebSocketBasicStream framing logic (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Fixes from tyoshino code review. Created 7 years, 4 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
OLDNEW
(Empty)
1 // Copyright 2013 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 // Tests for WebSocketBasicStream. Note that we do not attempt to verify that
6 // frame parsing itself functions correctly, as that is covered by the
7 // WebSocketFrameParser tests.
8
9 #include "net/websockets/websocket_basic_stream.h"
10
11 #include "base/basictypes.h"
tyoshino (SeeGerritForStatus) 2013/08/22 21:08:43 add base/port.h
Adam Rice 2013/08/23 06:05:18 Done.
12 #include "net/base/capturing_net_log.h"
13 #include "net/base/test_completion_callback.h"
14 #include "net/socket/socket_test_util.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 namespace net {
18 namespace {
19
tyoshino (SeeGerritForStatus) 2013/08/22 21:08:43 please add - tests for empty frame cases - frame w
Adam Rice 2013/08/23 06:05:18 Done.
20 const char kSampleFrame[] = "\x81\x06Sample";
21 const size_t kSampleFrameSize = arraysize(kSampleFrame) - 1;
22 const char kPartialLargeFrame[] =
23 "\x81\x7F\x00\x00\x00\x00\x7F\xFF\xFF\xFF"
24 "chromiunum ad pasco per loca insanis pullum manducat frumenti";
25 const size_t kPartialLargeFrameSize = arraysize(kPartialLargeFrame) - 1;
26 const size_t kLargeFrameHeaderSize = 10;
27 const size_t kLargeFrameDeclaredPayloadSize = 0x7FFFFFFF;
28 const char kMultipleFrames[] = "\x81\x01X\x81\x01Y\x81\x01Z";
29 const size_t kMultipleFramesSize = arraysize(kMultipleFrames) - 1;
30 // This frame encodes a payload length of 7 in two bytes, which is always
31 // invalid.
32 const char kInvalidFrame[] = "\x81\x7E\x00\x07Invalid";
33 const size_t kInvalidFrameSize = arraysize(kInvalidFrame) - 1;
34 const char kWriteFrame[] = "\x81\x85\x00\x00\x00\x00Write";
35 const size_t kWriteFrameSize = arraysize(kWriteFrame) - 1;
36 const WebSocketMaskingKey kNulMaskingKey = {{'\0', '\0', '\0', '\0'}};
37
38 // Generates a ScopedVector<WebSocketFrameChunk> which will have a wire format
39 // matching kWriteFrame.
40 ScopedVector<WebSocketFrameChunk> GenerateWriteFrame() {
41 scoped_ptr<WebSocketFrameChunk> chunk(new WebSocketFrameChunk);
42 const size_t payload_size =
43 kWriteFrameSize - (WebSocketFrameHeader::kBaseHeaderSize +
44 WebSocketFrameHeader::kMaskingKeyLength);
45 chunk->data = new IOBufferWithSize(payload_size);
46 memcpy(chunk->data->data(),
47 kWriteFrame + kWriteFrameSize - payload_size,
48 payload_size);
49 chunk->final_chunk = true;
50 scoped_ptr<WebSocketFrameHeader> header(
51 new WebSocketFrameHeader(WebSocketFrameHeader::kOpCodeText));
52 header->final = true;
53 header->masked = true;
54 header->payload_length = payload_size;
55 chunk->header = header.Pass();
56 ScopedVector<WebSocketFrameChunk> chunks;
57 chunks.push_back(chunk.release());
58 return chunks.Pass();
59 }
60
61 // A masking key generator function which generates the identity mask,
62 // ie. "\0\0\0\0".
63 WebSocketMaskingKey GenerateNulMaskingKey() { return kNulMaskingKey; }
64
65 // Base class for WebSocketBasicStream test fixtures.
66 class WebSocketBasicStreamTest : public ::testing::Test {
67 protected:
68 scoped_ptr<WebSocketBasicStream> stream_;
69 CapturingNetLog net_log_;
70 };
71
72 // A fixture for tests which only perform normal socket operations.
73 class WebSocketBasicStreamSocketTest : public WebSocketBasicStreamTest {
74 protected:
75 virtual ~WebSocketBasicStreamSocketTest() {
76 // stream_ has a reference to socket_data_ (via MockTCPClientSocket) and so
77 // should be destroyed first.
78 stream_.reset();
79 }
80
81 scoped_ptr<StreamSocket> MakeMockTCPClientSocket(MockRead reads[],
82 size_t reads_count,
83 MockWrite writes[],
84 size_t writes_count) {
85 // Nothing in WebSocketBasicStream should be caring about what the address
86 // is. Set it to 8.8.8.8:80.
87 AddressList address_list(IPEndPoint(IPAddressNumber(4, 8), 80));
88 socket_data_.reset(
89 new StaticSocketDataProvider(reads, reads_count, writes, writes_count));
90 socket_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
91 scoped_ptr<MockTCPClientSocket> socket(
92 new MockTCPClientSocket(address_list, &net_log_, socket_data_.get()));
93 CHECK_EQ(OK, socket->Connect(cb_.callback()));
94 return socket.PassAs<StreamSocket>();
95 }
96
97 scoped_ptr<ClientSocketHandle> MakeTransportSocket(
98 scoped_ptr<StreamSocket> socket) {
99 scoped_ptr<ClientSocketHandle> transport_socket(new ClientSocketHandle);
100 transport_socket->SetSocket(socket.Pass());
101 return transport_socket.Pass();
102 }
103
104 void SetHttpReadBuffer(const char* data, size_t size) {
105 http_read_buffer_ = new GrowableIOBuffer;
106 http_read_buffer_->SetCapacity(size);
107 memcpy(http_read_buffer_->data(), data, size);
108 http_read_buffer_->set_offset(size);
109 }
110
111 void CreateStream(MockRead reads[],
112 size_t reads_count,
113 MockWrite writes[],
114 size_t writes_count) {
115 stream_ = WebSocketBasicStream::CreateWebSocketBasicStreamForTesting(
116 MakeTransportSocket(
117 MakeMockTCPClientSocket(reads, reads_count, writes, writes_count)),
118 http_read_buffer_,
119 sub_protocol_,
120 extensions_,
121 &GenerateNulMaskingKey);
122 }
123
124 template <size_t N>
125 void CreateReadOnly(MockRead (&reads)[N]) {
126 CreateStream(reads, N, NULL, 0);
127 }
128
129 template <size_t N>
130 void CreateWriteOnly(MockWrite (&writes)[N]) {
131 CreateStream(NULL, 0, writes, N);
132 }
133
134 void CreateNullStream() { CreateStream(NULL, 0, NULL, 0); }
135
136 scoped_ptr<SocketDataProvider> socket_data_;
137 ScopedVector<WebSocketFrameChunk> frame_chunks_;
138 TestCompletionCallback cb_;
139 scoped_refptr<GrowableIOBuffer> http_read_buffer_;
140 std::string sub_protocol_;
141 std::string extensions_;
142 };
143
144 TEST_F(WebSocketBasicStreamSocketTest, ConstructionWorks) {
145 CreateNullStream();
146 }
147
148 TEST_F(WebSocketBasicStreamSocketTest, SyncReadWorks) {
149 MockRead reads[] = {MockRead(SYNCHRONOUS, kSampleFrame, kSampleFrameSize)};
150 CreateReadOnly(reads);
151 int result = stream_->ReadFrames(&frame_chunks_, cb_.callback());
152 EXPECT_EQ(OK, result);
153 ASSERT_EQ(1U, frame_chunks_.size());
154 ASSERT_TRUE(frame_chunks_[0]->header);
155 EXPECT_EQ(GG_UINT64_C(6), frame_chunks_[0]->header->payload_length);
156 EXPECT_TRUE(frame_chunks_[0]->header->final);
157 EXPECT_TRUE(frame_chunks_[0]->final_chunk);
158 }
159
160 TEST_F(WebSocketBasicStreamSocketTest, AsyncReadWorks) {
161 MockRead reads[] = {MockRead(ASYNC, kSampleFrame, kSampleFrameSize)};
162 CreateReadOnly(reads);
163 int result = stream_->ReadFrames(&frame_chunks_, cb_.callback());
164 ASSERT_EQ(ERR_IO_PENDING, result);
165 EXPECT_EQ(OK, cb_.WaitForResult());
166 ASSERT_EQ(1U, frame_chunks_.size());
167 ASSERT_TRUE(frame_chunks_[0]->header);
168 EXPECT_EQ(GG_UINT64_C(6), frame_chunks_[0]->header->payload_length);
169 // Don't repeat all the tests from SyncReadWorks; just enough to be sure the
170 // frame was really read.
171 }
172
173 // ReadFrames will not return a frame whose header has not been wholly received.
174 TEST_F(WebSocketBasicStreamSocketTest, HeaderFragmentedSync) {
175 MockRead reads[] = {
176 MockRead(SYNCHRONOUS, kSampleFrame, 1),
177 MockRead(SYNCHRONOUS, kSampleFrame + 1, kSampleFrameSize - 1)};
178 CreateReadOnly(reads);
179 int result = stream_->ReadFrames(&frame_chunks_, cb_.callback());
180 ASSERT_EQ(OK, result);
181 ASSERT_EQ(1U, frame_chunks_.size());
182 ASSERT_TRUE(frame_chunks_[0]->header);
183 EXPECT_EQ(GG_UINT64_C(6), frame_chunks_[0]->header->payload_length);
184 }
185
186 // The same behaviour applies to asynchronous reads.
187 TEST_F(WebSocketBasicStreamSocketTest, HeaderFragmentedAsync) {
188 MockRead reads[] = {MockRead(ASYNC, kSampleFrame, 1),
189 MockRead(ASYNC, kSampleFrame + 1, kSampleFrameSize - 1)};
190 CreateReadOnly(reads);
191 int result = stream_->ReadFrames(&frame_chunks_, cb_.callback());
192 ASSERT_EQ(ERR_IO_PENDING, result);
193 EXPECT_EQ(OK, cb_.WaitForResult());
194 ASSERT_EQ(1U, frame_chunks_.size());
195 ASSERT_TRUE(frame_chunks_[0]->header);
196 EXPECT_EQ(GG_UINT64_C(6), frame_chunks_[0]->header->payload_length);
197 }
198
199 // If it receives an incomplete header in a synchronous call, then has to wait
200 // for the rest of the frame, ReadFrames will return ERR_IO_PENDING.
201 TEST_F(WebSocketBasicStreamSocketTest, HeaderFragmentedSyncAsync) {
202 MockRead reads[] = {MockRead(SYNCHRONOUS, kSampleFrame, 1),
203 MockRead(ASYNC, kSampleFrame + 1, kSampleFrameSize - 1)};
204 CreateReadOnly(reads);
205 int result = stream_->ReadFrames(&frame_chunks_, cb_.callback());
206 ASSERT_EQ(ERR_IO_PENDING, result);
207 EXPECT_EQ(OK, cb_.WaitForResult());
208 ASSERT_EQ(1U, frame_chunks_.size());
209 ASSERT_TRUE(frame_chunks_[0]->header);
210 EXPECT_EQ(GG_UINT64_C(6), frame_chunks_[0]->header->payload_length);
211 }
212
213 // An extended header should also return ERR_IO_PENDING if it is not completely
214 // received.
215 TEST_F(WebSocketBasicStreamSocketTest, FragmentedLargeHeader) {
216 MockRead reads[] = {
217 MockRead(SYNCHRONOUS, kPartialLargeFrame, kLargeFrameHeaderSize - 1),
218 MockRead(SYNCHRONOUS, ERR_IO_PENDING)};
219 CreateReadOnly(reads);
220 EXPECT_EQ(ERR_IO_PENDING,
221 stream_->ReadFrames(&frame_chunks_, cb_.callback()));
222 }
223
224 // A frame that does not arrive in a single read should arrive in chunks.
225 TEST_F(WebSocketBasicStreamSocketTest, LargeFrameFirstChunk) {
226 MockRead reads[] = {
227 MockRead(SYNCHRONOUS, kPartialLargeFrame, kPartialLargeFrameSize)};
228 CreateReadOnly(reads);
229 EXPECT_EQ(OK, stream_->ReadFrames(&frame_chunks_, cb_.callback()));
230 ASSERT_EQ(1U, frame_chunks_.size());
231 ASSERT_TRUE(frame_chunks_[0]->header);
232 EXPECT_EQ(kLargeFrameDeclaredPayloadSize,
233 frame_chunks_[0]->header->payload_length);
234 EXPECT_TRUE(frame_chunks_[0]->header->final);
235 EXPECT_FALSE(frame_chunks_[0]->final_chunk);
236 EXPECT_EQ(kPartialLargeFrameSize - kLargeFrameHeaderSize,
237 static_cast<size_t>(frame_chunks_[0]->data->size()));
238 }
239
240 // If only the header arrives, we should get a zero-byte chunk.
241 TEST_F(WebSocketBasicStreamSocketTest, HeaderOnlyChunk) {
242 MockRead reads[] = {
243 MockRead(SYNCHRONOUS, kPartialLargeFrame, kLargeFrameHeaderSize)};
244 CreateReadOnly(reads);
245 EXPECT_EQ(OK, stream_->ReadFrames(&frame_chunks_, cb_.callback()));
246 ASSERT_EQ(1U, frame_chunks_.size());
247 EXPECT_FALSE(frame_chunks_[0]->final_chunk);
248 EXPECT_TRUE(frame_chunks_[0]->data.get() == NULL);
249 }
250
251 // The second and subsequent chunks of a frame have no header.
252 TEST_F(WebSocketBasicStreamSocketTest, LargeFrameTwoChunks) {
253 static const size_t kChunkSize = 16;
254 MockRead reads[] = {
255 MockRead(ASYNC, kPartialLargeFrame, kChunkSize),
256 MockRead(ASYNC, kPartialLargeFrame + kChunkSize, kChunkSize)};
257 CreateReadOnly(reads);
258 TestCompletionCallback cb[2];
259
260 ASSERT_EQ(ERR_IO_PENDING,
261 stream_->ReadFrames(&frame_chunks_, cb[0].callback()));
262 EXPECT_EQ(OK, cb[0].WaitForResult());
263 ASSERT_EQ(1U, frame_chunks_.size());
264 ASSERT_TRUE(frame_chunks_[0]->header);
265
266 frame_chunks_.clear();
267 ASSERT_EQ(ERR_IO_PENDING,
268 stream_->ReadFrames(&frame_chunks_, cb[1].callback()));
269 EXPECT_EQ(OK, cb[1].WaitForResult());
270 ASSERT_EQ(1U, frame_chunks_.size());
271 ASSERT_FALSE(frame_chunks_[0]->header);
272 }
273
274 // Only the final chunk of a frame has final_chunk set.
275 TEST_F(WebSocketBasicStreamSocketTest, OnlyFinalChunkIsFinal) {
276 static const size_t kFirstChunkSize = 4;
277 MockRead reads[] = {MockRead(ASYNC, kSampleFrame, kFirstChunkSize),
278 MockRead(ASYNC,
279 kSampleFrame + kFirstChunkSize,
280 kSampleFrameSize - kFirstChunkSize)};
281 CreateReadOnly(reads);
282 TestCompletionCallback cb[2];
283
284 ASSERT_EQ(ERR_IO_PENDING,
285 stream_->ReadFrames(&frame_chunks_, cb[0].callback()));
286 EXPECT_EQ(OK, cb[0].WaitForResult());
287 ASSERT_EQ(1U, frame_chunks_.size());
288 ASSERT_FALSE(frame_chunks_[0]->final_chunk);
289
290 frame_chunks_.clear();
291 ASSERT_EQ(ERR_IO_PENDING,
292 stream_->ReadFrames(&frame_chunks_, cb[1].callback()));
293 EXPECT_EQ(OK, cb[1].WaitForResult());
294 ASSERT_EQ(1U, frame_chunks_.size());
295 ASSERT_TRUE(frame_chunks_[0]->final_chunk);
296 }
297
298 // Multiple frames that arrive together should be parsed correctly.
299 TEST_F(WebSocketBasicStreamSocketTest, ThreeFramesTogether) {
300 MockRead reads[] = {
301 MockRead(SYNCHRONOUS, kMultipleFrames, kMultipleFramesSize)};
302 CreateReadOnly(reads);
303
304 ASSERT_EQ(OK, stream_->ReadFrames(&frame_chunks_, cb_.callback()));
305 ASSERT_EQ(3U, frame_chunks_.size());
306 EXPECT_TRUE(frame_chunks_[0]->final_chunk);
307 EXPECT_TRUE(frame_chunks_[1]->final_chunk);
308 EXPECT_TRUE(frame_chunks_[2]->final_chunk);
309 }
310
311 // ERR_CONNECTION_CLOSED must be returned on close.
312 TEST_F(WebSocketBasicStreamSocketTest, SyncClose) {
313 MockRead reads[] = {MockRead(SYNCHRONOUS, "", 0)};
314 CreateReadOnly(reads);
315
316 EXPECT_EQ(ERR_CONNECTION_CLOSED,
317 stream_->ReadFrames(&frame_chunks_, cb_.callback()));
318 }
319
320 TEST_F(WebSocketBasicStreamSocketTest, AsyncClose) {
321 MockRead reads[] = {MockRead(ASYNC, "", 0)};
322 CreateReadOnly(reads);
323
324 ASSERT_EQ(ERR_IO_PENDING,
325 stream_->ReadFrames(&frame_chunks_, cb_.callback()));
326 EXPECT_EQ(ERR_CONNECTION_CLOSED, cb_.WaitForResult());
327 }
328
329 // The result should be the same if the socket returns ERR_CONNECTION_CLOSED
330 TEST_F(WebSocketBasicStreamSocketTest, SyncCloseWithErr) {
331 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED)};
332 CreateReadOnly(reads);
333
334 EXPECT_EQ(ERR_CONNECTION_CLOSED,
335 stream_->ReadFrames(&frame_chunks_, cb_.callback()));
336 }
337
338 TEST_F(WebSocketBasicStreamSocketTest, AsyncCloseWithErr) {
339 MockRead reads[] = {MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
340 CreateReadOnly(reads);
341
342 ASSERT_EQ(ERR_IO_PENDING,
343 stream_->ReadFrames(&frame_chunks_, cb_.callback()));
344 EXPECT_EQ(ERR_CONNECTION_CLOSED, cb_.WaitForResult());
345 }
346
347 // If we get a frame followed by a close, we should receive them separately.
348 TEST_F(WebSocketBasicStreamSocketTest, CloseAfterFrame) {
349 MockRead reads[] = {MockRead(SYNCHRONOUS, kSampleFrame, kSampleFrameSize),
350 MockRead(SYNCHRONOUS, "", 0)};
351 CreateReadOnly(reads);
352
353 EXPECT_EQ(OK, stream_->ReadFrames(&frame_chunks_, cb_.callback()));
354 EXPECT_EQ(1U, frame_chunks_.size());
355 frame_chunks_.clear();
356 EXPECT_EQ(ERR_CONNECTION_CLOSED,
357 stream_->ReadFrames(&frame_chunks_, cb_.callback()));
358 }
359
360 // Synchronous close after an async frame header is handled by a different code
361 // path.
362 TEST_F(WebSocketBasicStreamSocketTest, AsyncCloseAfterIncompleteHeader) {
363 MockRead reads[] = {MockRead(ASYNC, kSampleFrame, 1U),
364 MockRead(SYNCHRONOUS, "", 0)};
365 CreateReadOnly(reads);
366
367 ASSERT_EQ(ERR_IO_PENDING,
368 stream_->ReadFrames(&frame_chunks_, cb_.callback()));
369 ASSERT_EQ(ERR_CONNECTION_CLOSED, cb_.WaitForResult());
370 }
371
372 // When Stream::Read returns ERR_CONNECTION_CLOSED we get the same result via a
373 // slightly different code path.
374 TEST_F(WebSocketBasicStreamSocketTest, AsyncErrCloseAfterIncompleteHeader) {
375 MockRead reads[] = {MockRead(ASYNC, kSampleFrame, 1U),
376 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED)};
377 CreateReadOnly(reads);
378
379 ASSERT_EQ(ERR_IO_PENDING,
380 stream_->ReadFrames(&frame_chunks_, cb_.callback()));
381 ASSERT_EQ(ERR_CONNECTION_CLOSED, cb_.WaitForResult());
382 }
383
384 // If there was a frame read at the same time as the response headers (and the
385 // handshake succeeded), then we should parse it.
386 TEST_F(WebSocketBasicStreamSocketTest, HttpReadBufferIsUsed) {
387 SetHttpReadBuffer(kSampleFrame, kSampleFrameSize);
388 CreateNullStream();
389
390 EXPECT_EQ(OK, stream_->ReadFrames(&frame_chunks_, cb_.callback()));
391 ASSERT_EQ(1U, frame_chunks_.size());
392 ASSERT_TRUE(frame_chunks_[0]->data);
393 EXPECT_EQ(6, frame_chunks_[0]->data->size());
394 }
395
396 // Check that a frame whose header partially arrived at the end of the response
397 // headers works correctly.
398 TEST_F(WebSocketBasicStreamSocketTest, PartialFrameHeaderInHttpResponse) {
399 SetHttpReadBuffer(kSampleFrame, 1);
400 MockRead reads[] = {MockRead(ASYNC, kSampleFrame + 1, kSampleFrameSize - 1)};
401 CreateReadOnly(reads);
402
403 ASSERT_EQ(ERR_IO_PENDING,
404 stream_->ReadFrames(&frame_chunks_, cb_.callback()));
405 EXPECT_EQ(OK, cb_.WaitForResult());
406 ASSERT_EQ(1U, frame_chunks_.size());
407 ASSERT_TRUE(frame_chunks_[0]->data);
408 EXPECT_EQ(6, frame_chunks_[0]->data->size());
409 ASSERT_TRUE(frame_chunks_[0]->header);
410 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText,
411 frame_chunks_[0]->header->opcode);
412 }
413
414 // Check that an invalid frame results in an error.
415 TEST_F(WebSocketBasicStreamSocketTest, SyncInvalidFrame) {
416 MockRead reads[] = {MockRead(SYNCHRONOUS, kInvalidFrame, kInvalidFrameSize)};
417 CreateReadOnly(reads);
418
419 EXPECT_EQ(ERR_WS_PROTOCOL_ERROR,
420 stream_->ReadFrames(&frame_chunks_, cb_.callback()));
421 }
422
423 TEST_F(WebSocketBasicStreamSocketTest, AsyncInvalidFrame) {
424 MockRead reads[] = {MockRead(ASYNC, kInvalidFrame, kInvalidFrameSize)};
425 CreateReadOnly(reads);
426
427 ASSERT_EQ(ERR_IO_PENDING,
428 stream_->ReadFrames(&frame_chunks_, cb_.callback()));
429 EXPECT_EQ(ERR_WS_PROTOCOL_ERROR, cb_.WaitForResult());
430 }
431
432 // Check that writing a frame all at once works.
433 TEST_F(WebSocketBasicStreamSocketTest, WriteAtOnce) {
434 MockWrite writes[] = {MockWrite(SYNCHRONOUS, kWriteFrame, kWriteFrameSize)};
435 CreateWriteOnly(writes);
436 frame_chunks_ = GenerateWriteFrame();
437
438 EXPECT_EQ(OK, stream_->WriteFrames(&frame_chunks_, cb_.callback()));
439 }
440
441 // Check that completely async writing works.
442 TEST_F(WebSocketBasicStreamSocketTest, AsyncWriteAtOnce) {
443 MockWrite writes[] = {MockWrite(ASYNC, kWriteFrame, kWriteFrameSize)};
444 CreateWriteOnly(writes);
445 frame_chunks_ = GenerateWriteFrame();
446
447 ASSERT_EQ(ERR_IO_PENDING,
448 stream_->WriteFrames(&frame_chunks_, cb_.callback()));
449 EXPECT_EQ(OK, cb_.WaitForResult());
450 }
451
452 // Check that writing a frame to an extremely full kernel buffer (so that it
453 // ends up being sent in bits) works. The WriteFrames() callback should not be
454 // called until all parts have been written.
455 TEST_F(WebSocketBasicStreamSocketTest, WriteInBits) {
456 MockWrite writes[] = {MockWrite(SYNCHRONOUS, kWriteFrame, 4),
457 MockWrite(ASYNC, kWriteFrame + 4, 4),
458 MockWrite(ASYNC, kWriteFrame + 8, kWriteFrameSize - 8)};
459 CreateWriteOnly(writes);
460 frame_chunks_ = GenerateWriteFrame();
461
462 ASSERT_EQ(ERR_IO_PENDING,
463 stream_->WriteFrames(&frame_chunks_, cb_.callback()));
464 EXPECT_EQ(OK, cb_.WaitForResult());
465 }
466
467 TEST_F(WebSocketBasicStreamSocketTest, GetExtensionsWorks) {
468 extensions_ = "inflate-uuencode";
469 CreateNullStream();
470
471 EXPECT_EQ("inflate-uuencode", stream_->GetExtensions());
472 }
473
474 TEST_F(WebSocketBasicStreamSocketTest, GetSubProtocolWorks) {
475 sub_protocol_ = "cyberchat";
476 CreateNullStream();
477
478 EXPECT_EQ("cyberchat", stream_->GetSubProtocol());
479 }
480
481 } // namespace
482 } // namespace net
OLDNEW
« net/websockets/websocket_basic_stream.cc ('K') | « net/websockets/websocket_basic_stream.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698