| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 // | 4 // |
| 5 // Tests for WebSocketBasicStream. Note that we do not attempt to verify that | 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 | 6 // frame parsing itself functions correctly, as that is covered by the |
| 7 // WebSocketFrameParser tests. | 7 // WebSocketFrameParser tests. |
| 8 | 8 |
| 9 #include "net/websockets/websocket_basic_stream.h" | 9 #include "net/websockets/websocket_basic_stream.h" |
| 10 | 10 |
| 11 #include <stddef.h> | 11 #include <stddef.h> |
| 12 #include <stdint.h> | 12 #include <stdint.h> |
| 13 #include <string.h> // for memcpy() and memset(). | 13 #include <string.h> // for memcpy() and memset(). |
| 14 #include <string> | 14 #include <string> |
| 15 #include <utility> | 15 #include <utility> |
| 16 #include <vector> | 16 #include <vector> |
| 17 | 17 |
| 18 #include "base/big_endian.h" | 18 #include "base/big_endian.h" |
| 19 #include "base/macros.h" | 19 #include "base/macros.h" |
| 20 #include "net/base/test_completion_callback.h" | 20 #include "net/base/test_completion_callback.h" |
| 21 #include "net/log/test_net_log.h" | 21 #include "net/log/test_net_log.h" |
| 22 #include "net/socket/socket_test_util.h" | 22 #include "net/socket/socket_test_util.h" |
| 23 #include "net/test/gtest_util.h" |
| 24 #include "testing/gmock/include/gmock/gmock.h" |
| 23 #include "testing/gtest/include/gtest/gtest.h" | 25 #include "testing/gtest/include/gtest/gtest.h" |
| 24 | 26 |
| 27 using net::test::IsError; |
| 28 using net::test::IsOk; |
| 29 |
| 25 namespace net { | 30 namespace net { |
| 26 namespace { | 31 namespace { |
| 27 | 32 |
| 28 #define WEBSOCKET_BASIC_STREAM_TEST_DEFINE_CONSTANT(name, value) \ | 33 #define WEBSOCKET_BASIC_STREAM_TEST_DEFINE_CONSTANT(name, value) \ |
| 29 const char k##name[] = value; \ | 34 const char k##name[] = value; \ |
| 30 const size_t k##name##Size = arraysize(k##name) - 1; | 35 const size_t k##name##Size = arraysize(k##name) - 1; |
| 31 | 36 |
| 32 WEBSOCKET_BASIC_STREAM_TEST_DEFINE_CONSTANT(SampleFrame, "\x81\x06Sample"); | 37 WEBSOCKET_BASIC_STREAM_TEST_DEFINE_CONSTANT(SampleFrame, "\x81\x06Sample"); |
| 33 WEBSOCKET_BASIC_STREAM_TEST_DEFINE_CONSTANT( | 38 WEBSOCKET_BASIC_STREAM_TEST_DEFINE_CONSTANT( |
| 34 PartialLargeFrame, | 39 PartialLargeFrame, |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 } | 268 } |
| 264 }; | 269 }; |
| 265 | 270 |
| 266 TEST_F(WebSocketBasicStreamSocketTest, ConstructionWorks) { | 271 TEST_F(WebSocketBasicStreamSocketTest, ConstructionWorks) { |
| 267 CreateNullStream(); | 272 CreateNullStream(); |
| 268 } | 273 } |
| 269 | 274 |
| 270 TEST_F(WebSocketBasicStreamSocketSingleReadTest, SyncReadWorks) { | 275 TEST_F(WebSocketBasicStreamSocketSingleReadTest, SyncReadWorks) { |
| 271 CreateRead(MockRead(SYNCHRONOUS, kSampleFrame, kSampleFrameSize)); | 276 CreateRead(MockRead(SYNCHRONOUS, kSampleFrame, kSampleFrameSize)); |
| 272 int result = stream_->ReadFrames(&frames_, cb_.callback()); | 277 int result = stream_->ReadFrames(&frames_, cb_.callback()); |
| 273 EXPECT_EQ(OK, result); | 278 EXPECT_THAT(result, IsOk()); |
| 274 ASSERT_EQ(1U, frames_.size()); | 279 ASSERT_EQ(1U, frames_.size()); |
| 275 EXPECT_EQ(UINT64_C(6), frames_[0]->header.payload_length); | 280 EXPECT_EQ(UINT64_C(6), frames_[0]->header.payload_length); |
| 276 EXPECT_TRUE(frames_[0]->header.final); | 281 EXPECT_TRUE(frames_[0]->header.final); |
| 277 } | 282 } |
| 278 | 283 |
| 279 TEST_F(WebSocketBasicStreamSocketSingleReadTest, AsyncReadWorks) { | 284 TEST_F(WebSocketBasicStreamSocketSingleReadTest, AsyncReadWorks) { |
| 280 CreateRead(MockRead(ASYNC, kSampleFrame, kSampleFrameSize)); | 285 CreateRead(MockRead(ASYNC, kSampleFrame, kSampleFrameSize)); |
| 281 int result = stream_->ReadFrames(&frames_, cb_.callback()); | 286 int result = stream_->ReadFrames(&frames_, cb_.callback()); |
| 282 ASSERT_EQ(ERR_IO_PENDING, result); | 287 ASSERT_THAT(result, IsError(ERR_IO_PENDING)); |
| 283 EXPECT_EQ(OK, cb_.WaitForResult()); | 288 EXPECT_THAT(cb_.WaitForResult(), IsOk()); |
| 284 ASSERT_EQ(1U, frames_.size()); | 289 ASSERT_EQ(1U, frames_.size()); |
| 285 EXPECT_EQ(UINT64_C(6), frames_[0]->header.payload_length); | 290 EXPECT_EQ(UINT64_C(6), frames_[0]->header.payload_length); |
| 286 // Don't repeat all the tests from SyncReadWorks; just enough to be sure the | 291 // Don't repeat all the tests from SyncReadWorks; just enough to be sure the |
| 287 // frame was really read. | 292 // frame was really read. |
| 288 } | 293 } |
| 289 | 294 |
| 290 // ReadFrames will not return a frame whose header has not been wholly received. | 295 // ReadFrames will not return a frame whose header has not been wholly received. |
| 291 TEST_F(WebSocketBasicStreamSocketChunkedReadTest, HeaderFragmentedSync) { | 296 TEST_F(WebSocketBasicStreamSocketChunkedReadTest, HeaderFragmentedSync) { |
| 292 CreateChunkedRead( | 297 CreateChunkedRead( |
| 293 SYNCHRONOUS, kSampleFrame, kSampleFrameSize, 1, 2, LAST_FRAME_BIG); | 298 SYNCHRONOUS, kSampleFrame, kSampleFrameSize, 1, 2, LAST_FRAME_BIG); |
| 294 int result = stream_->ReadFrames(&frames_, cb_.callback()); | 299 int result = stream_->ReadFrames(&frames_, cb_.callback()); |
| 295 EXPECT_EQ(OK, result); | 300 EXPECT_THAT(result, IsOk()); |
| 296 ASSERT_EQ(1U, frames_.size()); | 301 ASSERT_EQ(1U, frames_.size()); |
| 297 EXPECT_EQ(UINT64_C(6), frames_[0]->header.payload_length); | 302 EXPECT_EQ(UINT64_C(6), frames_[0]->header.payload_length); |
| 298 } | 303 } |
| 299 | 304 |
| 300 // The same behaviour applies to asynchronous reads. | 305 // The same behaviour applies to asynchronous reads. |
| 301 TEST_F(WebSocketBasicStreamSocketChunkedReadTest, HeaderFragmentedAsync) { | 306 TEST_F(WebSocketBasicStreamSocketChunkedReadTest, HeaderFragmentedAsync) { |
| 302 CreateChunkedRead( | 307 CreateChunkedRead( |
| 303 ASYNC, kSampleFrame, kSampleFrameSize, 1, 2, LAST_FRAME_BIG); | 308 ASYNC, kSampleFrame, kSampleFrameSize, 1, 2, LAST_FRAME_BIG); |
| 304 int result = stream_->ReadFrames(&frames_, cb_.callback()); | 309 int result = stream_->ReadFrames(&frames_, cb_.callback()); |
| 305 ASSERT_EQ(ERR_IO_PENDING, result); | 310 ASSERT_THAT(result, IsError(ERR_IO_PENDING)); |
| 306 EXPECT_EQ(OK, cb_.WaitForResult()); | 311 EXPECT_THAT(cb_.WaitForResult(), IsOk()); |
| 307 ASSERT_EQ(1U, frames_.size()); | 312 ASSERT_EQ(1U, frames_.size()); |
| 308 EXPECT_EQ(UINT64_C(6), frames_[0]->header.payload_length); | 313 EXPECT_EQ(UINT64_C(6), frames_[0]->header.payload_length); |
| 309 } | 314 } |
| 310 | 315 |
| 311 // If it receives an incomplete header in a synchronous call, then has to wait | 316 // If it receives an incomplete header in a synchronous call, then has to wait |
| 312 // for the rest of the frame, ReadFrames will return ERR_IO_PENDING. | 317 // for the rest of the frame, ReadFrames will return ERR_IO_PENDING. |
| 313 TEST_F(WebSocketBasicStreamSocketTest, HeaderFragmentedSyncAsync) { | 318 TEST_F(WebSocketBasicStreamSocketTest, HeaderFragmentedSyncAsync) { |
| 314 MockRead reads[] = {MockRead(SYNCHRONOUS, kSampleFrame, 1), | 319 MockRead reads[] = {MockRead(SYNCHRONOUS, kSampleFrame, 1), |
| 315 MockRead(ASYNC, kSampleFrame + 1, kSampleFrameSize - 1)}; | 320 MockRead(ASYNC, kSampleFrame + 1, kSampleFrameSize - 1)}; |
| 316 CreateReadOnly(reads); | 321 CreateReadOnly(reads); |
| 317 int result = stream_->ReadFrames(&frames_, cb_.callback()); | 322 int result = stream_->ReadFrames(&frames_, cb_.callback()); |
| 318 ASSERT_EQ(ERR_IO_PENDING, result); | 323 ASSERT_THAT(result, IsError(ERR_IO_PENDING)); |
| 319 EXPECT_EQ(OK, cb_.WaitForResult()); | 324 EXPECT_THAT(cb_.WaitForResult(), IsOk()); |
| 320 ASSERT_EQ(1U, frames_.size()); | 325 ASSERT_EQ(1U, frames_.size()); |
| 321 EXPECT_EQ(UINT64_C(6), frames_[0]->header.payload_length); | 326 EXPECT_EQ(UINT64_C(6), frames_[0]->header.payload_length); |
| 322 } | 327 } |
| 323 | 328 |
| 324 // An extended header should also return ERR_IO_PENDING if it is not completely | 329 // An extended header should also return ERR_IO_PENDING if it is not completely |
| 325 // received. | 330 // received. |
| 326 TEST_F(WebSocketBasicStreamSocketTest, FragmentedLargeHeader) { | 331 TEST_F(WebSocketBasicStreamSocketTest, FragmentedLargeHeader) { |
| 327 MockRead reads[] = { | 332 MockRead reads[] = { |
| 328 MockRead(SYNCHRONOUS, kPartialLargeFrame, kLargeFrameHeaderSize - 1), | 333 MockRead(SYNCHRONOUS, kPartialLargeFrame, kLargeFrameHeaderSize - 1), |
| 329 MockRead(SYNCHRONOUS, ERR_IO_PENDING)}; | 334 MockRead(SYNCHRONOUS, ERR_IO_PENDING)}; |
| 330 CreateReadOnly(reads); | 335 CreateReadOnly(reads); |
| 331 EXPECT_EQ(ERR_IO_PENDING, stream_->ReadFrames(&frames_, cb_.callback())); | 336 EXPECT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), |
| 337 IsError(ERR_IO_PENDING)); |
| 332 } | 338 } |
| 333 | 339 |
| 334 // A frame that does not arrive in a single read should be broken into separate | 340 // A frame that does not arrive in a single read should be broken into separate |
| 335 // frames. | 341 // frames. |
| 336 TEST_F(WebSocketBasicStreamSocketSingleReadTest, LargeFrameFirstChunk) { | 342 TEST_F(WebSocketBasicStreamSocketSingleReadTest, LargeFrameFirstChunk) { |
| 337 CreateRead(MockRead(SYNCHRONOUS, kPartialLargeFrame, kPartialLargeFrameSize)); | 343 CreateRead(MockRead(SYNCHRONOUS, kPartialLargeFrame, kPartialLargeFrameSize)); |
| 338 EXPECT_EQ(OK, stream_->ReadFrames(&frames_, cb_.callback())); | 344 EXPECT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), IsOk()); |
| 339 ASSERT_EQ(1U, frames_.size()); | 345 ASSERT_EQ(1U, frames_.size()); |
| 340 EXPECT_FALSE(frames_[0]->header.final); | 346 EXPECT_FALSE(frames_[0]->header.final); |
| 341 EXPECT_EQ(kPartialLargeFrameSize - kLargeFrameHeaderSize, | 347 EXPECT_EQ(kPartialLargeFrameSize - kLargeFrameHeaderSize, |
| 342 static_cast<size_t>(frames_[0]->header.payload_length)); | 348 static_cast<size_t>(frames_[0]->header.payload_length)); |
| 343 } | 349 } |
| 344 | 350 |
| 345 // If only the header of a data frame arrives, we should receive a frame with a | 351 // If only the header of a data frame arrives, we should receive a frame with a |
| 346 // zero-size payload. | 352 // zero-size payload. |
| 347 TEST_F(WebSocketBasicStreamSocketSingleReadTest, HeaderOnlyChunk) { | 353 TEST_F(WebSocketBasicStreamSocketSingleReadTest, HeaderOnlyChunk) { |
| 348 CreateRead(MockRead(SYNCHRONOUS, kPartialLargeFrame, kLargeFrameHeaderSize)); | 354 CreateRead(MockRead(SYNCHRONOUS, kPartialLargeFrame, kLargeFrameHeaderSize)); |
| 349 | 355 |
| 350 EXPECT_EQ(OK, stream_->ReadFrames(&frames_, cb_.callback())); | 356 EXPECT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), IsOk()); |
| 351 ASSERT_EQ(1U, frames_.size()); | 357 ASSERT_EQ(1U, frames_.size()); |
| 352 EXPECT_EQ(NULL, frames_[0]->data.get()); | 358 EXPECT_EQ(NULL, frames_[0]->data.get()); |
| 353 EXPECT_EQ(0U, frames_[0]->header.payload_length); | 359 EXPECT_EQ(0U, frames_[0]->header.payload_length); |
| 354 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_[0]->header.opcode); | 360 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_[0]->header.opcode); |
| 355 } | 361 } |
| 356 | 362 |
| 357 // If the header and the body of a data frame arrive seperately, we should see | 363 // If the header and the body of a data frame arrive seperately, we should see |
| 358 // them as separate frames. | 364 // them as separate frames. |
| 359 TEST_F(WebSocketBasicStreamSocketTest, HeaderBodySeparated) { | 365 TEST_F(WebSocketBasicStreamSocketTest, HeaderBodySeparated) { |
| 360 MockRead reads[] = { | 366 MockRead reads[] = { |
| 361 MockRead(SYNCHRONOUS, kPartialLargeFrame, kLargeFrameHeaderSize), | 367 MockRead(SYNCHRONOUS, kPartialLargeFrame, kLargeFrameHeaderSize), |
| 362 MockRead(ASYNC, | 368 MockRead(ASYNC, |
| 363 kPartialLargeFrame + kLargeFrameHeaderSize, | 369 kPartialLargeFrame + kLargeFrameHeaderSize, |
| 364 kPartialLargeFrameSize - kLargeFrameHeaderSize)}; | 370 kPartialLargeFrameSize - kLargeFrameHeaderSize)}; |
| 365 CreateReadOnly(reads); | 371 CreateReadOnly(reads); |
| 366 EXPECT_EQ(OK, stream_->ReadFrames(&frames_, cb_.callback())); | 372 EXPECT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), IsOk()); |
| 367 ASSERT_EQ(1U, frames_.size()); | 373 ASSERT_EQ(1U, frames_.size()); |
| 368 EXPECT_EQ(NULL, frames_[0]->data.get()); | 374 EXPECT_EQ(NULL, frames_[0]->data.get()); |
| 369 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_[0]->header.opcode); | 375 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_[0]->header.opcode); |
| 370 frames_.clear(); | 376 frames_.clear(); |
| 371 EXPECT_EQ(ERR_IO_PENDING, stream_->ReadFrames(&frames_, cb_.callback())); | 377 EXPECT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), |
| 372 EXPECT_EQ(OK, cb_.WaitForResult()); | 378 IsError(ERR_IO_PENDING)); |
| 379 EXPECT_THAT(cb_.WaitForResult(), IsOk()); |
| 373 ASSERT_EQ(1U, frames_.size()); | 380 ASSERT_EQ(1U, frames_.size()); |
| 374 EXPECT_EQ(kPartialLargeFrameSize - kLargeFrameHeaderSize, | 381 EXPECT_EQ(kPartialLargeFrameSize - kLargeFrameHeaderSize, |
| 375 frames_[0]->header.payload_length); | 382 frames_[0]->header.payload_length); |
| 376 EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation, | 383 EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation, |
| 377 frames_[0]->header.opcode); | 384 frames_[0]->header.opcode); |
| 378 } | 385 } |
| 379 | 386 |
| 380 // Every frame has a header with a correct payload_length field. | 387 // Every frame has a header with a correct payload_length field. |
| 381 TEST_F(WebSocketBasicStreamSocketChunkedReadTest, LargeFrameTwoChunks) { | 388 TEST_F(WebSocketBasicStreamSocketChunkedReadTest, LargeFrameTwoChunks) { |
| 382 const size_t kChunkSize = 16; | 389 const size_t kChunkSize = 16; |
| 383 CreateChunkedRead(ASYNC, | 390 CreateChunkedRead(ASYNC, |
| 384 kPartialLargeFrame, | 391 kPartialLargeFrame, |
| 385 kPartialLargeFrameSize, | 392 kPartialLargeFrameSize, |
| 386 kChunkSize, | 393 kChunkSize, |
| 387 2, | 394 2, |
| 388 LAST_FRAME_NOT_BIG); | 395 LAST_FRAME_NOT_BIG); |
| 389 TestCompletionCallback cb[2]; | 396 TestCompletionCallback cb[2]; |
| 390 | 397 |
| 391 ASSERT_EQ(ERR_IO_PENDING, stream_->ReadFrames(&frames_, cb[0].callback())); | 398 ASSERT_THAT(stream_->ReadFrames(&frames_, cb[0].callback()), |
| 392 EXPECT_EQ(OK, cb[0].WaitForResult()); | 399 IsError(ERR_IO_PENDING)); |
| 400 EXPECT_THAT(cb[0].WaitForResult(), IsOk()); |
| 393 ASSERT_EQ(1U, frames_.size()); | 401 ASSERT_EQ(1U, frames_.size()); |
| 394 EXPECT_EQ(kChunkSize - kLargeFrameHeaderSize, | 402 EXPECT_EQ(kChunkSize - kLargeFrameHeaderSize, |
| 395 frames_[0]->header.payload_length); | 403 frames_[0]->header.payload_length); |
| 396 | 404 |
| 397 frames_.clear(); | 405 frames_.clear(); |
| 398 ASSERT_EQ(ERR_IO_PENDING, stream_->ReadFrames(&frames_, cb[1].callback())); | 406 ASSERT_THAT(stream_->ReadFrames(&frames_, cb[1].callback()), |
| 399 EXPECT_EQ(OK, cb[1].WaitForResult()); | 407 IsError(ERR_IO_PENDING)); |
| 408 EXPECT_THAT(cb[1].WaitForResult(), IsOk()); |
| 400 ASSERT_EQ(1U, frames_.size()); | 409 ASSERT_EQ(1U, frames_.size()); |
| 401 EXPECT_EQ(kChunkSize, frames_[0]->header.payload_length); | 410 EXPECT_EQ(kChunkSize, frames_[0]->header.payload_length); |
| 402 } | 411 } |
| 403 | 412 |
| 404 // Only the final frame of a fragmented message has |final| bit set. | 413 // Only the final frame of a fragmented message has |final| bit set. |
| 405 TEST_F(WebSocketBasicStreamSocketChunkedReadTest, OnlyFinalChunkIsFinal) { | 414 TEST_F(WebSocketBasicStreamSocketChunkedReadTest, OnlyFinalChunkIsFinal) { |
| 406 static const size_t kFirstChunkSize = 4; | 415 static const size_t kFirstChunkSize = 4; |
| 407 CreateChunkedRead(ASYNC, | 416 CreateChunkedRead(ASYNC, |
| 408 kSampleFrame, | 417 kSampleFrame, |
| 409 kSampleFrameSize, | 418 kSampleFrameSize, |
| 410 kFirstChunkSize, | 419 kFirstChunkSize, |
| 411 2, | 420 2, |
| 412 LAST_FRAME_BIG); | 421 LAST_FRAME_BIG); |
| 413 TestCompletionCallback cb[2]; | 422 TestCompletionCallback cb[2]; |
| 414 | 423 |
| 415 ASSERT_EQ(ERR_IO_PENDING, stream_->ReadFrames(&frames_, cb[0].callback())); | 424 ASSERT_THAT(stream_->ReadFrames(&frames_, cb[0].callback()), |
| 416 EXPECT_EQ(OK, cb[0].WaitForResult()); | 425 IsError(ERR_IO_PENDING)); |
| 426 EXPECT_THAT(cb[0].WaitForResult(), IsOk()); |
| 417 ASSERT_EQ(1U, frames_.size()); | 427 ASSERT_EQ(1U, frames_.size()); |
| 418 ASSERT_FALSE(frames_[0]->header.final); | 428 ASSERT_FALSE(frames_[0]->header.final); |
| 419 | 429 |
| 420 frames_.clear(); | 430 frames_.clear(); |
| 421 ASSERT_EQ(ERR_IO_PENDING, stream_->ReadFrames(&frames_, cb[1].callback())); | 431 ASSERT_THAT(stream_->ReadFrames(&frames_, cb[1].callback()), |
| 422 EXPECT_EQ(OK, cb[1].WaitForResult()); | 432 IsError(ERR_IO_PENDING)); |
| 433 EXPECT_THAT(cb[1].WaitForResult(), IsOk()); |
| 423 ASSERT_EQ(1U, frames_.size()); | 434 ASSERT_EQ(1U, frames_.size()); |
| 424 ASSERT_TRUE(frames_[0]->header.final); | 435 ASSERT_TRUE(frames_[0]->header.final); |
| 425 } | 436 } |
| 426 | 437 |
| 427 // All frames after the first have their opcode changed to Continuation. | 438 // All frames after the first have their opcode changed to Continuation. |
| 428 TEST_F(WebSocketBasicStreamSocketChunkedReadTest, ContinuationOpCodeUsed) { | 439 TEST_F(WebSocketBasicStreamSocketChunkedReadTest, ContinuationOpCodeUsed) { |
| 429 const size_t kFirstChunkSize = 3; | 440 const size_t kFirstChunkSize = 3; |
| 430 const int kChunkCount = 3; | 441 const int kChunkCount = 3; |
| 431 // The input data is one frame with opcode Text, which arrives in three | 442 // The input data is one frame with opcode Text, which arrives in three |
| 432 // separate chunks. | 443 // separate chunks. |
| 433 CreateChunkedRead(ASYNC, | 444 CreateChunkedRead(ASYNC, |
| 434 kSampleFrame, | 445 kSampleFrame, |
| 435 kSampleFrameSize, | 446 kSampleFrameSize, |
| 436 kFirstChunkSize, | 447 kFirstChunkSize, |
| 437 kChunkCount, | 448 kChunkCount, |
| 438 LAST_FRAME_BIG); | 449 LAST_FRAME_BIG); |
| 439 TestCompletionCallback cb[kChunkCount]; | 450 TestCompletionCallback cb[kChunkCount]; |
| 440 | 451 |
| 441 ASSERT_EQ(ERR_IO_PENDING, stream_->ReadFrames(&frames_, cb[0].callback())); | 452 ASSERT_THAT(stream_->ReadFrames(&frames_, cb[0].callback()), |
| 442 EXPECT_EQ(OK, cb[0].WaitForResult()); | 453 IsError(ERR_IO_PENDING)); |
| 454 EXPECT_THAT(cb[0].WaitForResult(), IsOk()); |
| 443 ASSERT_EQ(1U, frames_.size()); | 455 ASSERT_EQ(1U, frames_.size()); |
| 444 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_[0]->header.opcode); | 456 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_[0]->header.opcode); |
| 445 | 457 |
| 446 // This test uses a loop to verify that the opcode for every frames generated | 458 // This test uses a loop to verify that the opcode for every frames generated |
| 447 // after the first is converted to Continuation. | 459 // after the first is converted to Continuation. |
| 448 for (int i = 1; i < kChunkCount; ++i) { | 460 for (int i = 1; i < kChunkCount; ++i) { |
| 449 frames_.clear(); | 461 frames_.clear(); |
| 450 ASSERT_EQ(ERR_IO_PENDING, stream_->ReadFrames(&frames_, cb[i].callback())); | 462 ASSERT_THAT(stream_->ReadFrames(&frames_, cb[i].callback()), |
| 451 EXPECT_EQ(OK, cb[i].WaitForResult()); | 463 IsError(ERR_IO_PENDING)); |
| 464 EXPECT_THAT(cb[i].WaitForResult(), IsOk()); |
| 452 ASSERT_EQ(1U, frames_.size()); | 465 ASSERT_EQ(1U, frames_.size()); |
| 453 EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation, | 466 EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation, |
| 454 frames_[0]->header.opcode); | 467 frames_[0]->header.opcode); |
| 455 } | 468 } |
| 456 } | 469 } |
| 457 | 470 |
| 458 // Multiple frames that arrive together should be parsed correctly. | 471 // Multiple frames that arrive together should be parsed correctly. |
| 459 TEST_F(WebSocketBasicStreamSocketSingleReadTest, ThreeFramesTogether) { | 472 TEST_F(WebSocketBasicStreamSocketSingleReadTest, ThreeFramesTogether) { |
| 460 CreateRead(MockRead(SYNCHRONOUS, kMultipleFrames, kMultipleFramesSize)); | 473 CreateRead(MockRead(SYNCHRONOUS, kMultipleFrames, kMultipleFramesSize)); |
| 461 | 474 |
| 462 EXPECT_EQ(OK, stream_->ReadFrames(&frames_, cb_.callback())); | 475 EXPECT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), IsOk()); |
| 463 ASSERT_EQ(3U, frames_.size()); | 476 ASSERT_EQ(3U, frames_.size()); |
| 464 EXPECT_TRUE(frames_[0]->header.final); | 477 EXPECT_TRUE(frames_[0]->header.final); |
| 465 EXPECT_TRUE(frames_[1]->header.final); | 478 EXPECT_TRUE(frames_[1]->header.final); |
| 466 EXPECT_TRUE(frames_[2]->header.final); | 479 EXPECT_TRUE(frames_[2]->header.final); |
| 467 } | 480 } |
| 468 | 481 |
| 469 // ERR_CONNECTION_CLOSED must be returned on close. | 482 // ERR_CONNECTION_CLOSED must be returned on close. |
| 470 TEST_F(WebSocketBasicStreamSocketSingleReadTest, SyncClose) { | 483 TEST_F(WebSocketBasicStreamSocketSingleReadTest, SyncClose) { |
| 471 CreateRead(MockRead(SYNCHRONOUS, "", 0)); | 484 CreateRead(MockRead(SYNCHRONOUS, "", 0)); |
| 472 | 485 |
| 473 EXPECT_EQ(ERR_CONNECTION_CLOSED, | 486 EXPECT_EQ(ERR_CONNECTION_CLOSED, |
| 474 stream_->ReadFrames(&frames_, cb_.callback())); | 487 stream_->ReadFrames(&frames_, cb_.callback())); |
| 475 } | 488 } |
| 476 | 489 |
| 477 TEST_F(WebSocketBasicStreamSocketSingleReadTest, AsyncClose) { | 490 TEST_F(WebSocketBasicStreamSocketSingleReadTest, AsyncClose) { |
| 478 CreateRead(MockRead(ASYNC, "", 0)); | 491 CreateRead(MockRead(ASYNC, "", 0)); |
| 479 | 492 |
| 480 ASSERT_EQ(ERR_IO_PENDING, stream_->ReadFrames(&frames_, cb_.callback())); | 493 ASSERT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), |
| 481 EXPECT_EQ(ERR_CONNECTION_CLOSED, cb_.WaitForResult()); | 494 IsError(ERR_IO_PENDING)); |
| 495 EXPECT_THAT(cb_.WaitForResult(), IsError(ERR_CONNECTION_CLOSED)); |
| 482 } | 496 } |
| 483 | 497 |
| 484 // The result should be the same if the socket returns | 498 // The result should be the same if the socket returns |
| 485 // ERR_CONNECTION_CLOSED. This is not expected to happen on an established | 499 // ERR_CONNECTION_CLOSED. This is not expected to happen on an established |
| 486 // connection; a Read of size 0 is the expected behaviour. The key point of this | 500 // connection; a Read of size 0 is the expected behaviour. The key point of this |
| 487 // test is to confirm that ReadFrames() behaviour is identical in both cases. | 501 // test is to confirm that ReadFrames() behaviour is identical in both cases. |
| 488 TEST_F(WebSocketBasicStreamSocketSingleReadTest, SyncCloseWithErr) { | 502 TEST_F(WebSocketBasicStreamSocketSingleReadTest, SyncCloseWithErr) { |
| 489 CreateRead(MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED)); | 503 CreateRead(MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED)); |
| 490 | 504 |
| 491 EXPECT_EQ(ERR_CONNECTION_CLOSED, | 505 EXPECT_EQ(ERR_CONNECTION_CLOSED, |
| 492 stream_->ReadFrames(&frames_, cb_.callback())); | 506 stream_->ReadFrames(&frames_, cb_.callback())); |
| 493 } | 507 } |
| 494 | 508 |
| 495 TEST_F(WebSocketBasicStreamSocketSingleReadTest, AsyncCloseWithErr) { | 509 TEST_F(WebSocketBasicStreamSocketSingleReadTest, AsyncCloseWithErr) { |
| 496 CreateRead(MockRead(ASYNC, ERR_CONNECTION_CLOSED)); | 510 CreateRead(MockRead(ASYNC, ERR_CONNECTION_CLOSED)); |
| 497 | 511 |
| 498 ASSERT_EQ(ERR_IO_PENDING, stream_->ReadFrames(&frames_, cb_.callback())); | 512 ASSERT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), |
| 499 EXPECT_EQ(ERR_CONNECTION_CLOSED, cb_.WaitForResult()); | 513 IsError(ERR_IO_PENDING)); |
| 514 EXPECT_THAT(cb_.WaitForResult(), IsError(ERR_CONNECTION_CLOSED)); |
| 500 } | 515 } |
| 501 | 516 |
| 502 TEST_F(WebSocketBasicStreamSocketSingleReadTest, SyncErrorsPassedThrough) { | 517 TEST_F(WebSocketBasicStreamSocketSingleReadTest, SyncErrorsPassedThrough) { |
| 503 // ERR_INSUFFICIENT_RESOURCES here represents an arbitrary error that | 518 // ERR_INSUFFICIENT_RESOURCES here represents an arbitrary error that |
| 504 // WebSocketBasicStream gives no special handling to. | 519 // WebSocketBasicStream gives no special handling to. |
| 505 CreateRead(MockRead(SYNCHRONOUS, ERR_INSUFFICIENT_RESOURCES)); | 520 CreateRead(MockRead(SYNCHRONOUS, ERR_INSUFFICIENT_RESOURCES)); |
| 506 | 521 |
| 507 EXPECT_EQ(ERR_INSUFFICIENT_RESOURCES, | 522 EXPECT_EQ(ERR_INSUFFICIENT_RESOURCES, |
| 508 stream_->ReadFrames(&frames_, cb_.callback())); | 523 stream_->ReadFrames(&frames_, cb_.callback())); |
| 509 } | 524 } |
| 510 | 525 |
| 511 TEST_F(WebSocketBasicStreamSocketSingleReadTest, AsyncErrorsPassedThrough) { | 526 TEST_F(WebSocketBasicStreamSocketSingleReadTest, AsyncErrorsPassedThrough) { |
| 512 CreateRead(MockRead(ASYNC, ERR_INSUFFICIENT_RESOURCES)); | 527 CreateRead(MockRead(ASYNC, ERR_INSUFFICIENT_RESOURCES)); |
| 513 | 528 |
| 514 ASSERT_EQ(ERR_IO_PENDING, stream_->ReadFrames(&frames_, cb_.callback())); | 529 ASSERT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), |
| 515 EXPECT_EQ(ERR_INSUFFICIENT_RESOURCES, cb_.WaitForResult()); | 530 IsError(ERR_IO_PENDING)); |
| 531 EXPECT_THAT(cb_.WaitForResult(), IsError(ERR_INSUFFICIENT_RESOURCES)); |
| 516 } | 532 } |
| 517 | 533 |
| 518 // If we get a frame followed by a close, we should receive them separately. | 534 // If we get a frame followed by a close, we should receive them separately. |
| 519 TEST_F(WebSocketBasicStreamSocketChunkedReadTest, CloseAfterFrame) { | 535 TEST_F(WebSocketBasicStreamSocketChunkedReadTest, CloseAfterFrame) { |
| 520 // The chunk size equals the data size, so the second chunk is 0 size, closing | 536 // The chunk size equals the data size, so the second chunk is 0 size, closing |
| 521 // the connection. | 537 // the connection. |
| 522 CreateChunkedRead(SYNCHRONOUS, | 538 CreateChunkedRead(SYNCHRONOUS, |
| 523 kSampleFrame, | 539 kSampleFrame, |
| 524 kSampleFrameSize, | 540 kSampleFrameSize, |
| 525 kSampleFrameSize, | 541 kSampleFrameSize, |
| 526 2, | 542 2, |
| 527 LAST_FRAME_NOT_BIG); | 543 LAST_FRAME_NOT_BIG); |
| 528 | 544 |
| 529 EXPECT_EQ(OK, stream_->ReadFrames(&frames_, cb_.callback())); | 545 EXPECT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), IsOk()); |
| 530 EXPECT_EQ(1U, frames_.size()); | 546 EXPECT_EQ(1U, frames_.size()); |
| 531 frames_.clear(); | 547 frames_.clear(); |
| 532 EXPECT_EQ(ERR_CONNECTION_CLOSED, | 548 EXPECT_EQ(ERR_CONNECTION_CLOSED, |
| 533 stream_->ReadFrames(&frames_, cb_.callback())); | 549 stream_->ReadFrames(&frames_, cb_.callback())); |
| 534 } | 550 } |
| 535 | 551 |
| 536 // Synchronous close after an async frame header is handled by a different code | 552 // Synchronous close after an async frame header is handled by a different code |
| 537 // path. | 553 // path. |
| 538 TEST_F(WebSocketBasicStreamSocketTest, AsyncCloseAfterIncompleteHeader) { | 554 TEST_F(WebSocketBasicStreamSocketTest, AsyncCloseAfterIncompleteHeader) { |
| 539 MockRead reads[] = {MockRead(ASYNC, kSampleFrame, 1U), | 555 MockRead reads[] = {MockRead(ASYNC, kSampleFrame, 1U), |
| 540 MockRead(SYNCHRONOUS, "", 0)}; | 556 MockRead(SYNCHRONOUS, "", 0)}; |
| 541 CreateReadOnly(reads); | 557 CreateReadOnly(reads); |
| 542 | 558 |
| 543 ASSERT_EQ(ERR_IO_PENDING, stream_->ReadFrames(&frames_, cb_.callback())); | 559 ASSERT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), |
| 544 EXPECT_EQ(ERR_CONNECTION_CLOSED, cb_.WaitForResult()); | 560 IsError(ERR_IO_PENDING)); |
| 561 EXPECT_THAT(cb_.WaitForResult(), IsError(ERR_CONNECTION_CLOSED)); |
| 545 } | 562 } |
| 546 | 563 |
| 547 // When Stream::Read returns ERR_CONNECTION_CLOSED we get the same result via a | 564 // When Stream::Read returns ERR_CONNECTION_CLOSED we get the same result via a |
| 548 // slightly different code path. | 565 // slightly different code path. |
| 549 TEST_F(WebSocketBasicStreamSocketTest, AsyncErrCloseAfterIncompleteHeader) { | 566 TEST_F(WebSocketBasicStreamSocketTest, AsyncErrCloseAfterIncompleteHeader) { |
| 550 MockRead reads[] = {MockRead(ASYNC, kSampleFrame, 1U), | 567 MockRead reads[] = {MockRead(ASYNC, kSampleFrame, 1U), |
| 551 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED)}; | 568 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED)}; |
| 552 CreateReadOnly(reads); | 569 CreateReadOnly(reads); |
| 553 | 570 |
| 554 ASSERT_EQ(ERR_IO_PENDING, stream_->ReadFrames(&frames_, cb_.callback())); | 571 ASSERT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), |
| 555 EXPECT_EQ(ERR_CONNECTION_CLOSED, cb_.WaitForResult()); | 572 IsError(ERR_IO_PENDING)); |
| 573 EXPECT_THAT(cb_.WaitForResult(), IsError(ERR_CONNECTION_CLOSED)); |
| 556 } | 574 } |
| 557 | 575 |
| 558 // An empty first frame is not ignored. | 576 // An empty first frame is not ignored. |
| 559 TEST_F(WebSocketBasicStreamSocketSingleReadTest, EmptyFirstFrame) { | 577 TEST_F(WebSocketBasicStreamSocketSingleReadTest, EmptyFirstFrame) { |
| 560 CreateRead(MockRead(SYNCHRONOUS, kEmptyFirstFrame, kEmptyFirstFrameSize)); | 578 CreateRead(MockRead(SYNCHRONOUS, kEmptyFirstFrame, kEmptyFirstFrameSize)); |
| 561 | 579 |
| 562 EXPECT_EQ(OK, stream_->ReadFrames(&frames_, cb_.callback())); | 580 EXPECT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), IsOk()); |
| 563 ASSERT_EQ(1U, frames_.size()); | 581 ASSERT_EQ(1U, frames_.size()); |
| 564 EXPECT_EQ(NULL, frames_[0]->data.get()); | 582 EXPECT_EQ(NULL, frames_[0]->data.get()); |
| 565 EXPECT_EQ(0U, frames_[0]->header.payload_length); | 583 EXPECT_EQ(0U, frames_[0]->header.payload_length); |
| 566 } | 584 } |
| 567 | 585 |
| 568 // An empty frame in the middle of a message is ignored. | 586 // An empty frame in the middle of a message is ignored. |
| 569 TEST_F(WebSocketBasicStreamSocketTest, EmptyMiddleFrame) { | 587 TEST_F(WebSocketBasicStreamSocketTest, EmptyMiddleFrame) { |
| 570 MockRead reads[] = { | 588 MockRead reads[] = { |
| 571 MockRead(SYNCHRONOUS, kEmptyFirstFrame, kEmptyFirstFrameSize), | 589 MockRead(SYNCHRONOUS, kEmptyFirstFrame, kEmptyFirstFrameSize), |
| 572 MockRead(SYNCHRONOUS, kEmptyMiddleFrame, kEmptyMiddleFrameSize), | 590 MockRead(SYNCHRONOUS, kEmptyMiddleFrame, kEmptyMiddleFrameSize), |
| 573 MockRead(SYNCHRONOUS, ERR_IO_PENDING)}; | 591 MockRead(SYNCHRONOUS, ERR_IO_PENDING)}; |
| 574 CreateReadOnly(reads); | 592 CreateReadOnly(reads); |
| 575 | 593 |
| 576 EXPECT_EQ(OK, stream_->ReadFrames(&frames_, cb_.callback())); | 594 EXPECT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), IsOk()); |
| 577 EXPECT_EQ(1U, frames_.size()); | 595 EXPECT_EQ(1U, frames_.size()); |
| 578 frames_.clear(); | 596 frames_.clear(); |
| 579 EXPECT_EQ(ERR_IO_PENDING, stream_->ReadFrames(&frames_, cb_.callback())); | 597 EXPECT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), |
| 598 IsError(ERR_IO_PENDING)); |
| 580 } | 599 } |
| 581 | 600 |
| 582 // An empty frame in the middle of a message that arrives separately is still | 601 // An empty frame in the middle of a message that arrives separately is still |
| 583 // ignored. | 602 // ignored. |
| 584 TEST_F(WebSocketBasicStreamSocketTest, EmptyMiddleFrameAsync) { | 603 TEST_F(WebSocketBasicStreamSocketTest, EmptyMiddleFrameAsync) { |
| 585 MockRead reads[] = { | 604 MockRead reads[] = { |
| 586 MockRead(SYNCHRONOUS, kEmptyFirstFrame, kEmptyFirstFrameSize), | 605 MockRead(SYNCHRONOUS, kEmptyFirstFrame, kEmptyFirstFrameSize), |
| 587 MockRead(ASYNC, kEmptyMiddleFrame, kEmptyMiddleFrameSize), | 606 MockRead(ASYNC, kEmptyMiddleFrame, kEmptyMiddleFrameSize), |
| 588 // We include a pong message to verify the middle frame was actually | 607 // We include a pong message to verify the middle frame was actually |
| 589 // processed. | 608 // processed. |
| 590 MockRead(ASYNC, kValidPong, kValidPongSize)}; | 609 MockRead(ASYNC, kValidPong, kValidPongSize)}; |
| 591 CreateReadOnly(reads); | 610 CreateReadOnly(reads); |
| 592 | 611 |
| 593 EXPECT_EQ(OK, stream_->ReadFrames(&frames_, cb_.callback())); | 612 EXPECT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), IsOk()); |
| 594 EXPECT_EQ(1U, frames_.size()); | 613 EXPECT_EQ(1U, frames_.size()); |
| 595 frames_.clear(); | 614 frames_.clear(); |
| 596 ASSERT_EQ(ERR_IO_PENDING, stream_->ReadFrames(&frames_, cb_.callback())); | 615 ASSERT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), |
| 597 EXPECT_EQ(OK, cb_.WaitForResult()); | 616 IsError(ERR_IO_PENDING)); |
| 617 EXPECT_THAT(cb_.WaitForResult(), IsOk()); |
| 598 ASSERT_EQ(1U, frames_.size()); | 618 ASSERT_EQ(1U, frames_.size()); |
| 599 EXPECT_EQ(WebSocketFrameHeader::kOpCodePong, frames_[0]->header.opcode); | 619 EXPECT_EQ(WebSocketFrameHeader::kOpCodePong, frames_[0]->header.opcode); |
| 600 } | 620 } |
| 601 | 621 |
| 602 // An empty final frame is not ignored. | 622 // An empty final frame is not ignored. |
| 603 TEST_F(WebSocketBasicStreamSocketSingleReadTest, EmptyFinalFrame) { | 623 TEST_F(WebSocketBasicStreamSocketSingleReadTest, EmptyFinalFrame) { |
| 604 CreateRead( | 624 CreateRead( |
| 605 MockRead(SYNCHRONOUS, kEmptyFinalTextFrame, kEmptyFinalTextFrameSize)); | 625 MockRead(SYNCHRONOUS, kEmptyFinalTextFrame, kEmptyFinalTextFrameSize)); |
| 606 | 626 |
| 607 EXPECT_EQ(OK, stream_->ReadFrames(&frames_, cb_.callback())); | 627 EXPECT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), IsOk()); |
| 608 ASSERT_EQ(1U, frames_.size()); | 628 ASSERT_EQ(1U, frames_.size()); |
| 609 EXPECT_EQ(NULL, frames_[0]->data.get()); | 629 EXPECT_EQ(NULL, frames_[0]->data.get()); |
| 610 EXPECT_EQ(0U, frames_[0]->header.payload_length); | 630 EXPECT_EQ(0U, frames_[0]->header.payload_length); |
| 611 } | 631 } |
| 612 | 632 |
| 613 // An empty middle frame is ignored with a final frame present. | 633 // An empty middle frame is ignored with a final frame present. |
| 614 TEST_F(WebSocketBasicStreamSocketTest, ThreeFrameEmptyMessage) { | 634 TEST_F(WebSocketBasicStreamSocketTest, ThreeFrameEmptyMessage) { |
| 615 MockRead reads[] = { | 635 MockRead reads[] = { |
| 616 MockRead(SYNCHRONOUS, kEmptyFirstFrame, kEmptyFirstFrameSize), | 636 MockRead(SYNCHRONOUS, kEmptyFirstFrame, kEmptyFirstFrameSize), |
| 617 MockRead(SYNCHRONOUS, kEmptyMiddleFrame, kEmptyMiddleFrameSize), | 637 MockRead(SYNCHRONOUS, kEmptyMiddleFrame, kEmptyMiddleFrameSize), |
| 618 MockRead(SYNCHRONOUS, | 638 MockRead(SYNCHRONOUS, |
| 619 kEmptyFinalContinuationFrame, | 639 kEmptyFinalContinuationFrame, |
| 620 kEmptyFinalContinuationFrameSize)}; | 640 kEmptyFinalContinuationFrameSize)}; |
| 621 CreateReadOnly(reads); | 641 CreateReadOnly(reads); |
| 622 | 642 |
| 623 EXPECT_EQ(OK, stream_->ReadFrames(&frames_, cb_.callback())); | 643 EXPECT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), IsOk()); |
| 624 ASSERT_EQ(1U, frames_.size()); | 644 ASSERT_EQ(1U, frames_.size()); |
| 625 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_[0]->header.opcode); | 645 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_[0]->header.opcode); |
| 626 frames_.clear(); | 646 frames_.clear(); |
| 627 EXPECT_EQ(OK, stream_->ReadFrames(&frames_, cb_.callback())); | 647 EXPECT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), IsOk()); |
| 628 ASSERT_EQ(1U, frames_.size()); | 648 ASSERT_EQ(1U, frames_.size()); |
| 629 EXPECT_TRUE(frames_[0]->header.final); | 649 EXPECT_TRUE(frames_[0]->header.final); |
| 630 } | 650 } |
| 631 | 651 |
| 632 // If there was a frame read at the same time as the response headers (and the | 652 // If there was a frame read at the same time as the response headers (and the |
| 633 // handshake succeeded), then we should parse it. | 653 // handshake succeeded), then we should parse it. |
| 634 TEST_F(WebSocketBasicStreamSocketTest, HttpReadBufferIsUsed) { | 654 TEST_F(WebSocketBasicStreamSocketTest, HttpReadBufferIsUsed) { |
| 635 SetHttpReadBuffer(kSampleFrame, kSampleFrameSize); | 655 SetHttpReadBuffer(kSampleFrame, kSampleFrameSize); |
| 636 CreateNullStream(); | 656 CreateNullStream(); |
| 637 | 657 |
| 638 EXPECT_EQ(OK, stream_->ReadFrames(&frames_, cb_.callback())); | 658 EXPECT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), IsOk()); |
| 639 ASSERT_EQ(1U, frames_.size()); | 659 ASSERT_EQ(1U, frames_.size()); |
| 640 ASSERT_TRUE(frames_[0]->data.get()); | 660 ASSERT_TRUE(frames_[0]->data.get()); |
| 641 EXPECT_EQ(UINT64_C(6), frames_[0]->header.payload_length); | 661 EXPECT_EQ(UINT64_C(6), frames_[0]->header.payload_length); |
| 642 } | 662 } |
| 643 | 663 |
| 644 // Check that a frame whose header partially arrived at the end of the response | 664 // Check that a frame whose header partially arrived at the end of the response |
| 645 // headers works correctly. | 665 // headers works correctly. |
| 646 TEST_F(WebSocketBasicStreamSocketSingleReadTest, | 666 TEST_F(WebSocketBasicStreamSocketSingleReadTest, |
| 647 PartialFrameHeaderInHttpResponse) { | 667 PartialFrameHeaderInHttpResponse) { |
| 648 SetHttpReadBuffer(kSampleFrame, 1); | 668 SetHttpReadBuffer(kSampleFrame, 1); |
| 649 CreateRead(MockRead(ASYNC, kSampleFrame + 1, kSampleFrameSize - 1)); | 669 CreateRead(MockRead(ASYNC, kSampleFrame + 1, kSampleFrameSize - 1)); |
| 650 | 670 |
| 651 ASSERT_EQ(ERR_IO_PENDING, stream_->ReadFrames(&frames_, cb_.callback())); | 671 ASSERT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), |
| 652 EXPECT_EQ(OK, cb_.WaitForResult()); | 672 IsError(ERR_IO_PENDING)); |
| 673 EXPECT_THAT(cb_.WaitForResult(), IsOk()); |
| 653 ASSERT_EQ(1U, frames_.size()); | 674 ASSERT_EQ(1U, frames_.size()); |
| 654 ASSERT_TRUE(frames_[0]->data.get()); | 675 ASSERT_TRUE(frames_[0]->data.get()); |
| 655 EXPECT_EQ(UINT64_C(6), frames_[0]->header.payload_length); | 676 EXPECT_EQ(UINT64_C(6), frames_[0]->header.payload_length); |
| 656 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_[0]->header.opcode); | 677 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_[0]->header.opcode); |
| 657 } | 678 } |
| 658 | 679 |
| 659 // Check that a control frame which partially arrives at the end of the response | 680 // Check that a control frame which partially arrives at the end of the response |
| 660 // headers works correctly. | 681 // headers works correctly. |
| 661 TEST_F(WebSocketBasicStreamSocketSingleReadTest, | 682 TEST_F(WebSocketBasicStreamSocketSingleReadTest, |
| 662 PartialControlFrameInHttpResponse) { | 683 PartialControlFrameInHttpResponse) { |
| 663 const size_t kPartialFrameBytes = 3; | 684 const size_t kPartialFrameBytes = 3; |
| 664 SetHttpReadBuffer(kCloseFrame, kPartialFrameBytes); | 685 SetHttpReadBuffer(kCloseFrame, kPartialFrameBytes); |
| 665 CreateRead(MockRead(ASYNC, | 686 CreateRead(MockRead(ASYNC, |
| 666 kCloseFrame + kPartialFrameBytes, | 687 kCloseFrame + kPartialFrameBytes, |
| 667 kCloseFrameSize - kPartialFrameBytes)); | 688 kCloseFrameSize - kPartialFrameBytes)); |
| 668 | 689 |
| 669 ASSERT_EQ(ERR_IO_PENDING, stream_->ReadFrames(&frames_, cb_.callback())); | 690 ASSERT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), |
| 670 EXPECT_EQ(OK, cb_.WaitForResult()); | 691 IsError(ERR_IO_PENDING)); |
| 692 EXPECT_THAT(cb_.WaitForResult(), IsOk()); |
| 671 ASSERT_EQ(1U, frames_.size()); | 693 ASSERT_EQ(1U, frames_.size()); |
| 672 EXPECT_EQ(WebSocketFrameHeader::kOpCodeClose, frames_[0]->header.opcode); | 694 EXPECT_EQ(WebSocketFrameHeader::kOpCodeClose, frames_[0]->header.opcode); |
| 673 EXPECT_EQ(kCloseFrameSize - 2, frames_[0]->header.payload_length); | 695 EXPECT_EQ(kCloseFrameSize - 2, frames_[0]->header.payload_length); |
| 674 EXPECT_EQ( | 696 EXPECT_EQ( |
| 675 0, | 697 0, |
| 676 memcmp(frames_[0]->data->data(), kCloseFrame + 2, kCloseFrameSize - 2)); | 698 memcmp(frames_[0]->data->data(), kCloseFrame + 2, kCloseFrameSize - 2)); |
| 677 } | 699 } |
| 678 | 700 |
| 679 // Check that a control frame which partially arrives at the end of the response | 701 // Check that a control frame which partially arrives at the end of the response |
| 680 // headers works correctly. Synchronous version (unlikely in practice). | 702 // headers works correctly. Synchronous version (unlikely in practice). |
| 681 TEST_F(WebSocketBasicStreamSocketSingleReadTest, | 703 TEST_F(WebSocketBasicStreamSocketSingleReadTest, |
| 682 PartialControlFrameInHttpResponseSync) { | 704 PartialControlFrameInHttpResponseSync) { |
| 683 const size_t kPartialFrameBytes = 3; | 705 const size_t kPartialFrameBytes = 3; |
| 684 SetHttpReadBuffer(kCloseFrame, kPartialFrameBytes); | 706 SetHttpReadBuffer(kCloseFrame, kPartialFrameBytes); |
| 685 CreateRead(MockRead(SYNCHRONOUS, | 707 CreateRead(MockRead(SYNCHRONOUS, |
| 686 kCloseFrame + kPartialFrameBytes, | 708 kCloseFrame + kPartialFrameBytes, |
| 687 kCloseFrameSize - kPartialFrameBytes)); | 709 kCloseFrameSize - kPartialFrameBytes)); |
| 688 | 710 |
| 689 EXPECT_EQ(OK, stream_->ReadFrames(&frames_, cb_.callback())); | 711 EXPECT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), IsOk()); |
| 690 ASSERT_EQ(1U, frames_.size()); | 712 ASSERT_EQ(1U, frames_.size()); |
| 691 EXPECT_EQ(WebSocketFrameHeader::kOpCodeClose, frames_[0]->header.opcode); | 713 EXPECT_EQ(WebSocketFrameHeader::kOpCodeClose, frames_[0]->header.opcode); |
| 692 } | 714 } |
| 693 | 715 |
| 694 // Check that an invalid frame results in an error. | 716 // Check that an invalid frame results in an error. |
| 695 TEST_F(WebSocketBasicStreamSocketSingleReadTest, SyncInvalidFrame) { | 717 TEST_F(WebSocketBasicStreamSocketSingleReadTest, SyncInvalidFrame) { |
| 696 CreateRead(MockRead(SYNCHRONOUS, kInvalidFrame, kInvalidFrameSize)); | 718 CreateRead(MockRead(SYNCHRONOUS, kInvalidFrame, kInvalidFrameSize)); |
| 697 | 719 |
| 698 EXPECT_EQ(ERR_WS_PROTOCOL_ERROR, | 720 EXPECT_EQ(ERR_WS_PROTOCOL_ERROR, |
| 699 stream_->ReadFrames(&frames_, cb_.callback())); | 721 stream_->ReadFrames(&frames_, cb_.callback())); |
| 700 } | 722 } |
| 701 | 723 |
| 702 TEST_F(WebSocketBasicStreamSocketSingleReadTest, AsyncInvalidFrame) { | 724 TEST_F(WebSocketBasicStreamSocketSingleReadTest, AsyncInvalidFrame) { |
| 703 CreateRead(MockRead(ASYNC, kInvalidFrame, kInvalidFrameSize)); | 725 CreateRead(MockRead(ASYNC, kInvalidFrame, kInvalidFrameSize)); |
| 704 | 726 |
| 705 ASSERT_EQ(ERR_IO_PENDING, stream_->ReadFrames(&frames_, cb_.callback())); | 727 ASSERT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), |
| 706 EXPECT_EQ(ERR_WS_PROTOCOL_ERROR, cb_.WaitForResult()); | 728 IsError(ERR_IO_PENDING)); |
| 729 EXPECT_THAT(cb_.WaitForResult(), IsError(ERR_WS_PROTOCOL_ERROR)); |
| 707 } | 730 } |
| 708 | 731 |
| 709 // A control frame without a FIN flag is invalid and should not be passed | 732 // A control frame without a FIN flag is invalid and should not be passed |
| 710 // through to higher layers. RFC6455 5.5 "All control frames ... MUST NOT be | 733 // through to higher layers. RFC6455 5.5 "All control frames ... MUST NOT be |
| 711 // fragmented." | 734 // fragmented." |
| 712 TEST_F(WebSocketBasicStreamSocketSingleReadTest, ControlFrameWithoutFin) { | 735 TEST_F(WebSocketBasicStreamSocketSingleReadTest, ControlFrameWithoutFin) { |
| 713 CreateRead( | 736 CreateRead( |
| 714 MockRead(SYNCHRONOUS, kPingFrameWithoutFin, kPingFrameWithoutFinSize)); | 737 MockRead(SYNCHRONOUS, kPingFrameWithoutFin, kPingFrameWithoutFinSize)); |
| 715 | 738 |
| 716 EXPECT_EQ(ERR_WS_PROTOCOL_ERROR, | 739 EXPECT_EQ(ERR_WS_PROTOCOL_ERROR, |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 751 AsyncSplitOverlongControlFrame) { | 774 AsyncSplitOverlongControlFrame) { |
| 752 const size_t kFirstChunkSize = 16; | 775 const size_t kFirstChunkSize = 16; |
| 753 expect_all_io_to_complete_ = false; | 776 expect_all_io_to_complete_ = false; |
| 754 CreateChunkedRead(ASYNC, | 777 CreateChunkedRead(ASYNC, |
| 755 k126BytePong, | 778 k126BytePong, |
| 756 k126BytePongSize, | 779 k126BytePongSize, |
| 757 kFirstChunkSize, | 780 kFirstChunkSize, |
| 758 2, | 781 2, |
| 759 LAST_FRAME_BIG); | 782 LAST_FRAME_BIG); |
| 760 | 783 |
| 761 ASSERT_EQ(ERR_IO_PENDING, stream_->ReadFrames(&frames_, cb_.callback())); | 784 ASSERT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), |
| 762 EXPECT_EQ(ERR_WS_PROTOCOL_ERROR, cb_.WaitForResult()); | 785 IsError(ERR_IO_PENDING)); |
| 786 EXPECT_THAT(cb_.WaitForResult(), IsError(ERR_WS_PROTOCOL_ERROR)); |
| 763 // The caller should not call ReadFrames() again after receiving an error | 787 // The caller should not call ReadFrames() again after receiving an error |
| 764 // other than ERR_IO_PENDING. | 788 // other than ERR_IO_PENDING. |
| 765 EXPECT_TRUE(frames_.empty()); | 789 EXPECT_TRUE(frames_.empty()); |
| 766 } | 790 } |
| 767 | 791 |
| 768 // In the synchronous case, ReadFrames assembles the whole control frame before | 792 // In the synchronous case, ReadFrames assembles the whole control frame before |
| 769 // returning. | 793 // returning. |
| 770 TEST_F(WebSocketBasicStreamSocketChunkedReadTest, SyncControlFrameAssembly) { | 794 TEST_F(WebSocketBasicStreamSocketChunkedReadTest, SyncControlFrameAssembly) { |
| 771 const size_t kChunkSize = 3; | 795 const size_t kChunkSize = 3; |
| 772 CreateChunkedRead( | 796 CreateChunkedRead( |
| 773 SYNCHRONOUS, kCloseFrame, kCloseFrameSize, kChunkSize, 3, LAST_FRAME_BIG); | 797 SYNCHRONOUS, kCloseFrame, kCloseFrameSize, kChunkSize, 3, LAST_FRAME_BIG); |
| 774 | 798 |
| 775 EXPECT_EQ(OK, stream_->ReadFrames(&frames_, cb_.callback())); | 799 EXPECT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), IsOk()); |
| 776 ASSERT_EQ(1U, frames_.size()); | 800 ASSERT_EQ(1U, frames_.size()); |
| 777 EXPECT_EQ(WebSocketFrameHeader::kOpCodeClose, frames_[0]->header.opcode); | 801 EXPECT_EQ(WebSocketFrameHeader::kOpCodeClose, frames_[0]->header.opcode); |
| 778 } | 802 } |
| 779 | 803 |
| 780 // In the asynchronous case, the callback is not called until the control frame | 804 // In the asynchronous case, the callback is not called until the control frame |
| 781 // has been completely assembled. | 805 // has been completely assembled. |
| 782 TEST_F(WebSocketBasicStreamSocketChunkedReadTest, AsyncControlFrameAssembly) { | 806 TEST_F(WebSocketBasicStreamSocketChunkedReadTest, AsyncControlFrameAssembly) { |
| 783 const size_t kChunkSize = 3; | 807 const size_t kChunkSize = 3; |
| 784 CreateChunkedRead( | 808 CreateChunkedRead( |
| 785 ASYNC, kCloseFrame, kCloseFrameSize, kChunkSize, 3, LAST_FRAME_BIG); | 809 ASYNC, kCloseFrame, kCloseFrameSize, kChunkSize, 3, LAST_FRAME_BIG); |
| 786 | 810 |
| 787 ASSERT_EQ(ERR_IO_PENDING, stream_->ReadFrames(&frames_, cb_.callback())); | 811 ASSERT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), |
| 788 EXPECT_EQ(OK, cb_.WaitForResult()); | 812 IsError(ERR_IO_PENDING)); |
| 813 EXPECT_THAT(cb_.WaitForResult(), IsOk()); |
| 789 ASSERT_EQ(1U, frames_.size()); | 814 ASSERT_EQ(1U, frames_.size()); |
| 790 EXPECT_EQ(WebSocketFrameHeader::kOpCodeClose, frames_[0]->header.opcode); | 815 EXPECT_EQ(WebSocketFrameHeader::kOpCodeClose, frames_[0]->header.opcode); |
| 791 } | 816 } |
| 792 | 817 |
| 793 // A frame with a 1MB payload that has to be read in chunks. | 818 // A frame with a 1MB payload that has to be read in chunks. |
| 794 TEST_F(WebSocketBasicStreamSocketChunkedReadTest, OneMegFrame) { | 819 TEST_F(WebSocketBasicStreamSocketChunkedReadTest, OneMegFrame) { |
| 795 // This should be equal to the definition of kReadBufferSize in | 820 // This should be equal to the definition of kReadBufferSize in |
| 796 // websocket_basic_stream.cc. | 821 // websocket_basic_stream.cc. |
| 797 const int kReadBufferSize = 32 * 1024; | 822 const int kReadBufferSize = 32 * 1024; |
| 798 const uint64_t kPayloadSize = 1 << 20; | 823 const uint64_t kPayloadSize = 1 << 20; |
| 799 const size_t kWireSize = kPayloadSize + kLargeFrameHeaderSize; | 824 const size_t kWireSize = kPayloadSize + kLargeFrameHeaderSize; |
| 800 const size_t kExpectedFrameCount = | 825 const size_t kExpectedFrameCount = |
| 801 (kWireSize + kReadBufferSize - 1) / kReadBufferSize; | 826 (kWireSize + kReadBufferSize - 1) / kReadBufferSize; |
| 802 std::unique_ptr<char[]> big_frame(new char[kWireSize]); | 827 std::unique_ptr<char[]> big_frame(new char[kWireSize]); |
| 803 memcpy(big_frame.get(), "\x81\x7F", 2); | 828 memcpy(big_frame.get(), "\x81\x7F", 2); |
| 804 base::WriteBigEndian(big_frame.get() + 2, kPayloadSize); | 829 base::WriteBigEndian(big_frame.get() + 2, kPayloadSize); |
| 805 memset(big_frame.get() + kLargeFrameHeaderSize, 'A', kPayloadSize); | 830 memset(big_frame.get() + kLargeFrameHeaderSize, 'A', kPayloadSize); |
| 806 | 831 |
| 807 CreateChunkedRead(ASYNC, | 832 CreateChunkedRead(ASYNC, |
| 808 big_frame.get(), | 833 big_frame.get(), |
| 809 kWireSize, | 834 kWireSize, |
| 810 kReadBufferSize, | 835 kReadBufferSize, |
| 811 kExpectedFrameCount, | 836 kExpectedFrameCount, |
| 812 LAST_FRAME_BIG); | 837 LAST_FRAME_BIG); |
| 813 | 838 |
| 814 for (size_t frame = 0; frame < kExpectedFrameCount; ++frame) { | 839 for (size_t frame = 0; frame < kExpectedFrameCount; ++frame) { |
| 815 frames_.clear(); | 840 frames_.clear(); |
| 816 ASSERT_EQ(ERR_IO_PENDING, stream_->ReadFrames(&frames_, cb_.callback())); | 841 ASSERT_THAT(stream_->ReadFrames(&frames_, cb_.callback()), |
| 817 EXPECT_EQ(OK, cb_.WaitForResult()); | 842 IsError(ERR_IO_PENDING)); |
| 843 EXPECT_THAT(cb_.WaitForResult(), IsOk()); |
| 818 ASSERT_EQ(1U, frames_.size()); | 844 ASSERT_EQ(1U, frames_.size()); |
| 819 size_t expected_payload_size = kReadBufferSize; | 845 size_t expected_payload_size = kReadBufferSize; |
| 820 if (frame == 0) { | 846 if (frame == 0) { |
| 821 expected_payload_size = kReadBufferSize - kLargeFrameHeaderSize; | 847 expected_payload_size = kReadBufferSize - kLargeFrameHeaderSize; |
| 822 } else if (frame == kExpectedFrameCount - 1) { | 848 } else if (frame == kExpectedFrameCount - 1) { |
| 823 expected_payload_size = kLargeFrameHeaderSize; | 849 expected_payload_size = kLargeFrameHeaderSize; |
| 824 } | 850 } |
| 825 EXPECT_EQ(expected_payload_size, frames_[0]->header.payload_length); | 851 EXPECT_EQ(expected_payload_size, frames_[0]->header.payload_length); |
| 826 } | 852 } |
| 827 } | 853 } |
| 828 | 854 |
| 829 // A frame with reserved flag(s) set that arrives in chunks should only have the | 855 // A frame with reserved flag(s) set that arrives in chunks should only have the |
| 830 // reserved flag(s) set on the first chunk when split. | 856 // reserved flag(s) set on the first chunk when split. |
| 831 TEST_F(WebSocketBasicStreamSocketChunkedReadTest, ReservedFlagCleared) { | 857 TEST_F(WebSocketBasicStreamSocketChunkedReadTest, ReservedFlagCleared) { |
| 832 static const char kReservedFlagFrame[] = "\x41\x05Hello"; | 858 static const char kReservedFlagFrame[] = "\x41\x05Hello"; |
| 833 const size_t kReservedFlagFrameSize = arraysize(kReservedFlagFrame) - 1; | 859 const size_t kReservedFlagFrameSize = arraysize(kReservedFlagFrame) - 1; |
| 834 const size_t kChunkSize = 5; | 860 const size_t kChunkSize = 5; |
| 835 | 861 |
| 836 CreateChunkedRead(ASYNC, | 862 CreateChunkedRead(ASYNC, |
| 837 kReservedFlagFrame, | 863 kReservedFlagFrame, |
| 838 kReservedFlagFrameSize, | 864 kReservedFlagFrameSize, |
| 839 kChunkSize, | 865 kChunkSize, |
| 840 2, | 866 2, |
| 841 LAST_FRAME_BIG); | 867 LAST_FRAME_BIG); |
| 842 | 868 |
| 843 TestCompletionCallback cb[2]; | 869 TestCompletionCallback cb[2]; |
| 844 ASSERT_EQ(ERR_IO_PENDING, stream_->ReadFrames(&frames_, cb[0].callback())); | 870 ASSERT_THAT(stream_->ReadFrames(&frames_, cb[0].callback()), |
| 845 EXPECT_EQ(OK, cb[0].WaitForResult()); | 871 IsError(ERR_IO_PENDING)); |
| 872 EXPECT_THAT(cb[0].WaitForResult(), IsOk()); |
| 846 ASSERT_EQ(1U, frames_.size()); | 873 ASSERT_EQ(1U, frames_.size()); |
| 847 EXPECT_TRUE(frames_[0]->header.reserved1); | 874 EXPECT_TRUE(frames_[0]->header.reserved1); |
| 848 | 875 |
| 849 frames_.clear(); | 876 frames_.clear(); |
| 850 ASSERT_EQ(ERR_IO_PENDING, stream_->ReadFrames(&frames_, cb[1].callback())); | 877 ASSERT_THAT(stream_->ReadFrames(&frames_, cb[1].callback()), |
| 851 EXPECT_EQ(OK, cb[1].WaitForResult()); | 878 IsError(ERR_IO_PENDING)); |
| 879 EXPECT_THAT(cb[1].WaitForResult(), IsOk()); |
| 852 ASSERT_EQ(1U, frames_.size()); | 880 ASSERT_EQ(1U, frames_.size()); |
| 853 EXPECT_FALSE(frames_[0]->header.reserved1); | 881 EXPECT_FALSE(frames_[0]->header.reserved1); |
| 854 } | 882 } |
| 855 | 883 |
| 856 // Check that writing a frame all at once works. | 884 // Check that writing a frame all at once works. |
| 857 TEST_F(WebSocketBasicStreamSocketWriteTest, WriteAtOnce) { | 885 TEST_F(WebSocketBasicStreamSocketWriteTest, WriteAtOnce) { |
| 858 MockWrite writes[] = {MockWrite(SYNCHRONOUS, kWriteFrame, kWriteFrameSize)}; | 886 MockWrite writes[] = {MockWrite(SYNCHRONOUS, kWriteFrame, kWriteFrameSize)}; |
| 859 CreateWriteOnly(writes); | 887 CreateWriteOnly(writes); |
| 860 | 888 |
| 861 EXPECT_EQ(OK, stream_->WriteFrames(&frames_, cb_.callback())); | 889 EXPECT_THAT(stream_->WriteFrames(&frames_, cb_.callback()), IsOk()); |
| 862 } | 890 } |
| 863 | 891 |
| 864 // Check that completely async writing works. | 892 // Check that completely async writing works. |
| 865 TEST_F(WebSocketBasicStreamSocketWriteTest, AsyncWriteAtOnce) { | 893 TEST_F(WebSocketBasicStreamSocketWriteTest, AsyncWriteAtOnce) { |
| 866 MockWrite writes[] = {MockWrite(ASYNC, kWriteFrame, kWriteFrameSize)}; | 894 MockWrite writes[] = {MockWrite(ASYNC, kWriteFrame, kWriteFrameSize)}; |
| 867 CreateWriteOnly(writes); | 895 CreateWriteOnly(writes); |
| 868 | 896 |
| 869 ASSERT_EQ(ERR_IO_PENDING, stream_->WriteFrames(&frames_, cb_.callback())); | 897 ASSERT_THAT(stream_->WriteFrames(&frames_, cb_.callback()), |
| 870 EXPECT_EQ(OK, cb_.WaitForResult()); | 898 IsError(ERR_IO_PENDING)); |
| 899 EXPECT_THAT(cb_.WaitForResult(), IsOk()); |
| 871 } | 900 } |
| 872 | 901 |
| 873 // Check that writing a frame to an extremely full kernel buffer (so that it | 902 // Check that writing a frame to an extremely full kernel buffer (so that it |
| 874 // ends up being sent in bits) works. The WriteFrames() callback should not be | 903 // ends up being sent in bits) works. The WriteFrames() callback should not be |
| 875 // called until all parts have been written. | 904 // called until all parts have been written. |
| 876 TEST_F(WebSocketBasicStreamSocketWriteTest, WriteInBits) { | 905 TEST_F(WebSocketBasicStreamSocketWriteTest, WriteInBits) { |
| 877 MockWrite writes[] = {MockWrite(SYNCHRONOUS, kWriteFrame, 4), | 906 MockWrite writes[] = {MockWrite(SYNCHRONOUS, kWriteFrame, 4), |
| 878 MockWrite(ASYNC, kWriteFrame + 4, 4), | 907 MockWrite(ASYNC, kWriteFrame + 4, 4), |
| 879 MockWrite(ASYNC, kWriteFrame + 8, kWriteFrameSize - 8)}; | 908 MockWrite(ASYNC, kWriteFrame + 8, kWriteFrameSize - 8)}; |
| 880 CreateWriteOnly(writes); | 909 CreateWriteOnly(writes); |
| 881 | 910 |
| 882 ASSERT_EQ(ERR_IO_PENDING, stream_->WriteFrames(&frames_, cb_.callback())); | 911 ASSERT_THAT(stream_->WriteFrames(&frames_, cb_.callback()), |
| 883 EXPECT_EQ(OK, cb_.WaitForResult()); | 912 IsError(ERR_IO_PENDING)); |
| 913 EXPECT_THAT(cb_.WaitForResult(), IsOk()); |
| 884 } | 914 } |
| 885 | 915 |
| 886 // Check that writing a Pong frame with a NULL body works. | 916 // Check that writing a Pong frame with a NULL body works. |
| 887 TEST_F(WebSocketBasicStreamSocketWriteTest, WriteNullPong) { | 917 TEST_F(WebSocketBasicStreamSocketWriteTest, WriteNullPong) { |
| 888 MockWrite writes[] = { | 918 MockWrite writes[] = { |
| 889 MockWrite(SYNCHRONOUS, kMaskedEmptyPong, kMaskedEmptyPongSize)}; | 919 MockWrite(SYNCHRONOUS, kMaskedEmptyPong, kMaskedEmptyPongSize)}; |
| 890 CreateWriteOnly(writes); | 920 CreateWriteOnly(writes); |
| 891 | 921 |
| 892 std::unique_ptr<WebSocketFrame> frame( | 922 std::unique_ptr<WebSocketFrame> frame( |
| 893 new WebSocketFrame(WebSocketFrameHeader::kOpCodePong)); | 923 new WebSocketFrame(WebSocketFrameHeader::kOpCodePong)); |
| 894 WebSocketFrameHeader& header = frame->header; | 924 WebSocketFrameHeader& header = frame->header; |
| 895 header.final = true; | 925 header.final = true; |
| 896 header.masked = true; | 926 header.masked = true; |
| 897 header.payload_length = 0; | 927 header.payload_length = 0; |
| 898 std::vector<std::unique_ptr<WebSocketFrame>> frames; | 928 std::vector<std::unique_ptr<WebSocketFrame>> frames; |
| 899 frames.push_back(std::move(frame)); | 929 frames.push_back(std::move(frame)); |
| 900 EXPECT_EQ(OK, stream_->WriteFrames(&frames, cb_.callback())); | 930 EXPECT_THAT(stream_->WriteFrames(&frames, cb_.callback()), IsOk()); |
| 901 } | 931 } |
| 902 | 932 |
| 903 // Check that writing with a non-NULL mask works correctly. | 933 // Check that writing with a non-NULL mask works correctly. |
| 904 TEST_F(WebSocketBasicStreamSocketTest, WriteNonNulMask) { | 934 TEST_F(WebSocketBasicStreamSocketTest, WriteNonNulMask) { |
| 905 std::string masked_frame = std::string("\x81\x88"); | 935 std::string masked_frame = std::string("\x81\x88"); |
| 906 masked_frame += std::string(kNonNulMaskingKey.key, 4); | 936 masked_frame += std::string(kNonNulMaskingKey.key, 4); |
| 907 masked_frame += "jiggered"; | 937 masked_frame += "jiggered"; |
| 908 MockWrite writes[] = { | 938 MockWrite writes[] = { |
| 909 MockWrite(SYNCHRONOUS, masked_frame.data(), masked_frame.size())}; | 939 MockWrite(SYNCHRONOUS, masked_frame.data(), masked_frame.size())}; |
| 910 generator_ = &GenerateNonNulMaskingKey; | 940 generator_ = &GenerateNonNulMaskingKey; |
| 911 CreateStream(NULL, 0, writes, arraysize(writes)); | 941 CreateStream(NULL, 0, writes, arraysize(writes)); |
| 912 | 942 |
| 913 std::unique_ptr<WebSocketFrame> frame( | 943 std::unique_ptr<WebSocketFrame> frame( |
| 914 new WebSocketFrame(WebSocketFrameHeader::kOpCodeText)); | 944 new WebSocketFrame(WebSocketFrameHeader::kOpCodeText)); |
| 915 const std::string unmasked_payload = "graphics"; | 945 const std::string unmasked_payload = "graphics"; |
| 916 const size_t payload_size = unmasked_payload.size(); | 946 const size_t payload_size = unmasked_payload.size(); |
| 917 frame->data = new IOBuffer(payload_size); | 947 frame->data = new IOBuffer(payload_size); |
| 918 memcpy(frame->data->data(), unmasked_payload.data(), payload_size); | 948 memcpy(frame->data->data(), unmasked_payload.data(), payload_size); |
| 919 WebSocketFrameHeader& header = frame->header; | 949 WebSocketFrameHeader& header = frame->header; |
| 920 header.final = true; | 950 header.final = true; |
| 921 header.masked = true; | 951 header.masked = true; |
| 922 header.payload_length = payload_size; | 952 header.payload_length = payload_size; |
| 923 frames_.push_back(std::move(frame)); | 953 frames_.push_back(std::move(frame)); |
| 924 | 954 |
| 925 EXPECT_EQ(OK, stream_->WriteFrames(&frames_, cb_.callback())); | 955 EXPECT_THAT(stream_->WriteFrames(&frames_, cb_.callback()), IsOk()); |
| 926 } | 956 } |
| 927 | 957 |
| 928 TEST_F(WebSocketBasicStreamSocketTest, GetExtensionsWorks) { | 958 TEST_F(WebSocketBasicStreamSocketTest, GetExtensionsWorks) { |
| 929 extensions_ = "inflate-uuencode"; | 959 extensions_ = "inflate-uuencode"; |
| 930 CreateNullStream(); | 960 CreateNullStream(); |
| 931 | 961 |
| 932 EXPECT_EQ("inflate-uuencode", stream_->GetExtensions()); | 962 EXPECT_EQ("inflate-uuencode", stream_->GetExtensions()); |
| 933 } | 963 } |
| 934 | 964 |
| 935 TEST_F(WebSocketBasicStreamSocketTest, GetSubProtocolWorks) { | 965 TEST_F(WebSocketBasicStreamSocketTest, GetSubProtocolWorks) { |
| 936 sub_protocol_ = "cyberchat"; | 966 sub_protocol_ = "cyberchat"; |
| 937 CreateNullStream(); | 967 CreateNullStream(); |
| 938 | 968 |
| 939 EXPECT_EQ("cyberchat", stream_->GetSubProtocol()); | 969 EXPECT_EQ("cyberchat", stream_->GetSubProtocol()); |
| 940 } | 970 } |
| 941 | 971 |
| 942 } // namespace | 972 } // namespace |
| 943 } // namespace net | 973 } // namespace net |
| OLD | NEW |