Index: net/websockets/websocket_deflate_stream_test.cc |
diff --git a/net/websockets/websocket_deflate_stream_test.cc b/net/websockets/websocket_deflate_stream_test.cc |
deleted file mode 100644 |
index c30ab3287092d2cd0eae828ff241d5b9bef7e885..0000000000000000000000000000000000000000 |
--- a/net/websockets/websocket_deflate_stream_test.cc |
+++ /dev/null |
@@ -1,1349 +0,0 @@ |
-// Copyright 2013 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "net/websockets/websocket_deflate_stream.h" |
- |
-#include <stdint.h> |
-#include <deque> |
-#include <string> |
- |
-#include "base/basictypes.h" |
-#include "base/bind.h" |
-#include "base/memory/ref_counted.h" |
-#include "base/memory/scoped_ptr.h" |
-#include "base/memory/scoped_vector.h" |
-#include "net/base/completion_callback.h" |
-#include "net/base/io_buffer.h" |
-#include "net/base/net_errors.h" |
-#include "net/websockets/websocket_deflate_predictor.h" |
-#include "net/websockets/websocket_deflater.h" |
-#include "net/websockets/websocket_frame.h" |
-#include "net/websockets/websocket_inflater.h" |
-#include "net/websockets/websocket_stream.h" |
-#include "net/websockets/websocket_test_util.h" |
-#include "testing/gmock/include/gmock/gmock.h" |
-#include "testing/gtest/include/gtest/gtest.h" |
- |
-namespace net { |
-namespace { |
- |
-typedef ::testing::MockFunction<void(int)> MockCallback; // NOLINT |
-using ::testing::_; |
-using ::testing::InSequence; |
-using ::testing::Invoke; |
-using ::testing::Return; |
- |
-typedef uint32_t FrameFlag; |
-const FrameFlag kNoFlag = 0; |
-const FrameFlag kFinal = 1; |
-const FrameFlag kReserved1 = 2; |
-// We don't define values for other flags because we don't need them. |
- |
-// The value must equal to the value of the corresponding |
-// constant in websocket_deflate_stream.cc |
-const size_t kChunkSize = 4 * 1024; |
-const int kWindowBits = 15; |
- |
-scoped_refptr<IOBuffer> ToIOBuffer(const std::string& s) { |
- scoped_refptr<IOBuffer> buffer = new IOBuffer(s.size()); |
- memcpy(buffer->data(), s.data(), s.size()); |
- return buffer; |
-} |
- |
-std::string ToString(IOBufferWithSize* buffer) { |
- return std::string(buffer->data(), buffer->size()); |
-} |
- |
-std::string ToString(const scoped_refptr<IOBufferWithSize>& buffer) { |
- return ToString(buffer.get()); |
-} |
- |
-std::string ToString(IOBuffer* buffer, size_t size) { |
- return std::string(buffer->data(), size); |
-} |
- |
-std::string ToString(const scoped_refptr<IOBuffer>& buffer, size_t size) { |
- return ToString(buffer.get(), size); |
-} |
- |
-std::string ToString(const WebSocketFrame* frame) { |
- return frame->data.get() ? ToString(frame->data, frame->header.payload_length) |
- : ""; |
-} |
- |
-void AppendTo(ScopedVector<WebSocketFrame>* frames, |
- WebSocketFrameHeader::OpCode opcode, |
- FrameFlag flag, |
- const std::string& data) { |
- scoped_ptr<WebSocketFrame> frame(new WebSocketFrame(opcode)); |
- frame->header.final = (flag & kFinal); |
- frame->header.reserved1 = (flag & kReserved1); |
- frame->data = ToIOBuffer(data); |
- frame->header.payload_length = data.size(); |
- frames->push_back(frame.release()); |
-} |
- |
-void AppendTo(ScopedVector<WebSocketFrame>* frames, |
- WebSocketFrameHeader::OpCode opcode, |
- FrameFlag flag) { |
- scoped_ptr<WebSocketFrame> frame(new WebSocketFrame(opcode)); |
- frame->header.final = (flag & kFinal); |
- frame->header.reserved1 = (flag & kReserved1); |
- frames->push_back(frame.release()); |
-} |
- |
-class MockWebSocketStream : public WebSocketStream { |
- public: |
- MOCK_METHOD2(ReadFrames, int(ScopedVector<WebSocketFrame>*, |
- const CompletionCallback&)); |
- MOCK_METHOD2(WriteFrames, int(ScopedVector<WebSocketFrame>*, |
- const CompletionCallback&)); |
- MOCK_METHOD0(Close, void()); |
- MOCK_CONST_METHOD0(GetSubProtocol, std::string()); |
- MOCK_CONST_METHOD0(GetExtensions, std::string()); |
-}; |
- |
-// This mock class relies on some assumptions. |
-// - RecordInputDataFrame is called after the corresponding WriteFrames |
-// call. |
-// - RecordWrittenDataFrame is called before writing the frame. |
-class WebSocketDeflatePredictorMock : public WebSocketDeflatePredictor { |
- public: |
- WebSocketDeflatePredictorMock() : result_(DEFLATE) {} |
- ~WebSocketDeflatePredictorMock() override { |
- // Verify whether all expectaions are consumed. |
- if (!frames_to_be_input_.empty()) { |
- ADD_FAILURE() << "There are missing frames to be input."; |
- return; |
- } |
- if (!frames_written_.empty()) { |
- ADD_FAILURE() << "There are extra written frames."; |
- return; |
- } |
- } |
- |
- // WebSocketDeflatePredictor functions. |
- Result Predict(const ScopedVector<WebSocketFrame>& frames, |
- size_t frame_index) override { |
- return result_; |
- } |
- void RecordInputDataFrame(const WebSocketFrame* frame) override { |
- if (!WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode)) { |
- ADD_FAILURE() << "Control frames should not be recorded."; |
- return; |
- } |
- if (frame->header.reserved1) { |
- ADD_FAILURE() << "Input frame may not be compressed."; |
- return; |
- } |
- if (frames_to_be_input_.empty()) { |
- ADD_FAILURE() << "Unexpected input data frame"; |
- return; |
- } |
- if (frame != frames_to_be_input_.front()) { |
- ADD_FAILURE() << "Input data frame does not match the expectation."; |
- return; |
- } |
- frames_to_be_input_.pop_front(); |
- } |
- void RecordWrittenDataFrame(const WebSocketFrame* frame) override { |
- if (!WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode)) { |
- ADD_FAILURE() << "Control frames should not be recorded."; |
- return; |
- } |
- frames_written_.push_back(frame); |
- } |
- |
- // Sets |result_| for the |Predict| return value. |
- void set_result(Result result) { result_ = result; } |
- |
- // Adds |frame| as an expectation of future |RecordInputDataFrame| call. |
- void AddFrameToBeInput(const WebSocketFrame* frame) { |
- if (!WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode)) |
- return; |
- frames_to_be_input_.push_back(frame); |
- } |
- // Verifies that |frame| is recorded in order. |
- void VerifySentFrame(const WebSocketFrame* frame) { |
- if (!WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode)) |
- return; |
- if (frames_written_.empty()) { |
- ADD_FAILURE() << "There are missing frames to be written."; |
- return; |
- } |
- if (frame != frames_written_.front()) { |
- ADD_FAILURE() << "Written data frame does not match the expectation."; |
- return; |
- } |
- frames_written_.pop_front(); |
- } |
- void AddFramesToBeInput(const ScopedVector<WebSocketFrame>& frames) { |
- for (size_t i = 0; i < frames.size(); ++i) |
- AddFrameToBeInput(frames[i]); |
- } |
- void VerifySentFrames(const ScopedVector<WebSocketFrame>& frames) { |
- for (size_t i = 0; i < frames.size(); ++i) |
- VerifySentFrame(frames[i]); |
- } |
- // Call this method in order to disable checks in the destructor when |
- // WriteFrames fails. |
- void Clear() { |
- frames_to_be_input_.clear(); |
- frames_written_.clear(); |
- } |
- |
- private: |
- Result result_; |
- // Data frames which will be recorded by |RecordInputFrames|. |
- // Pushed by |AddFrameToBeInput| and popped and verified by |
- // |RecordInputFrames|. |
- std::deque<const WebSocketFrame*> frames_to_be_input_; |
- // Data frames recorded by |RecordWrittenFrames|. |
- // Pushed by |RecordWrittenFrames| and popped and verified by |
- // |VerifySentFrame|. |
- std::deque<const WebSocketFrame*> frames_written_; |
- |
- DISALLOW_COPY_AND_ASSIGN(WebSocketDeflatePredictorMock); |
-}; |
- |
-class WebSocketDeflateStreamTest : public ::testing::Test { |
- public: |
- WebSocketDeflateStreamTest() |
- : mock_stream_(NULL), |
- predictor_(NULL) {} |
- ~WebSocketDeflateStreamTest() override {} |
- |
- void SetUp() override { |
- Initialize(WebSocketDeflater::TAKE_OVER_CONTEXT, kWindowBits); |
- } |
- |
- protected: |
- // Initialize deflate_stream_ with the given parameters. |
- void Initialize(WebSocketDeflater::ContextTakeOverMode mode, |
- int window_bits) { |
- mock_stream_ = new testing::StrictMock<MockWebSocketStream>; |
- predictor_ = new WebSocketDeflatePredictorMock; |
- deflate_stream_.reset(new WebSocketDeflateStream( |
- scoped_ptr<WebSocketStream>(mock_stream_), |
- mode, |
- window_bits, |
- scoped_ptr<WebSocketDeflatePredictor>(predictor_))); |
- } |
- |
- scoped_ptr<WebSocketDeflateStream> deflate_stream_; |
- // Owned by |deflate_stream_|. |
- MockWebSocketStream* mock_stream_; |
- // Owned by |deflate_stream_|. |
- WebSocketDeflatePredictorMock* predictor_; |
-}; |
- |
-// Since WebSocketDeflater with DoNotTakeOverContext is well tested at |
-// websocket_deflater_test.cc, we have only a few tests for this configuration |
-// here. |
-class WebSocketDeflateStreamWithDoNotTakeOverContextTest |
- : public WebSocketDeflateStreamTest { |
- public: |
- WebSocketDeflateStreamWithDoNotTakeOverContextTest() {} |
- ~WebSocketDeflateStreamWithDoNotTakeOverContextTest() override {} |
- |
- void SetUp() override { |
- Initialize(WebSocketDeflater::DO_NOT_TAKE_OVER_CONTEXT, kWindowBits); |
- } |
-}; |
- |
-class WebSocketDeflateStreamWithClientWindowBitsTest |
- : public WebSocketDeflateStreamTest { |
- public: |
- WebSocketDeflateStreamWithClientWindowBitsTest() {} |
- ~WebSocketDeflateStreamWithClientWindowBitsTest() override {} |
- |
- // Overridden to postpone the call to Initialize(). |
- void SetUp() override {} |
- |
- // This needs to be called explicitly from the tests. |
- void SetUpWithWindowBits(int window_bits) { |
- Initialize(WebSocketDeflater::TAKE_OVER_CONTEXT, window_bits); |
- } |
- |
- // Add a frame which will be compressed to a smaller size if the window |
- // size is large enough. |
- void AddCompressibleFrameString() { |
- const std::string word = "Chromium"; |
- const std::string payload = word + std::string(256, 'a') + word; |
- AppendTo(&frames_, WebSocketFrameHeader::kOpCodeText, kFinal, payload); |
- predictor_->AddFramesToBeInput(frames_); |
- } |
- |
- protected: |
- ScopedVector<WebSocketFrame> frames_; |
-}; |
- |
-// ReadFrameStub is a stub for WebSocketStream::ReadFrames. |
-// It returns |result_| and |frames_to_output_| to the caller and |
-// saves parameters to |frames_passed_| and |callback_|. |
-class ReadFramesStub { |
- public: |
- explicit ReadFramesStub(int result) : result_(result) {} |
- |
- ReadFramesStub(int result, ScopedVector<WebSocketFrame>* frames_to_output) |
- : result_(result) { |
- frames_to_output_.swap(*frames_to_output); |
- } |
- |
- int Call(ScopedVector<WebSocketFrame>* frames, |
- const CompletionCallback& callback) { |
- DCHECK(frames->empty()); |
- frames_passed_ = frames; |
- callback_ = callback; |
- frames->swap(frames_to_output_); |
- return result_; |
- } |
- |
- int result() const { return result_; } |
- const CompletionCallback callback() const { return callback_; } |
- ScopedVector<WebSocketFrame>* frames_passed() { |
- return frames_passed_; |
- } |
- |
- private: |
- int result_; |
- CompletionCallback callback_; |
- ScopedVector<WebSocketFrame> frames_to_output_; |
- ScopedVector<WebSocketFrame>* frames_passed_; |
-}; |
- |
-// WriteFramesStub is a stub for WebSocketStream::WriteFrames. |
-// It returns |result_| and |frames_| to the caller and |
-// saves |callback| parameter to |callback_|. |
-class WriteFramesStub { |
- public: |
- explicit WriteFramesStub(WebSocketDeflatePredictorMock* predictor, |
- int result) |
- : result_(result), predictor_(predictor) {} |
- |
- int Call(ScopedVector<WebSocketFrame>* frames, |
- const CompletionCallback& callback) { |
- frames_.insert(frames_.end(), frames->begin(), frames->end()); |
- frames->weak_clear(); |
- callback_ = callback; |
- predictor_->VerifySentFrames(frames_); |
- return result_; |
- } |
- |
- int result() const { return result_; } |
- const CompletionCallback callback() const { return callback_; } |
- ScopedVector<WebSocketFrame>* frames() { return &frames_; } |
- |
- private: |
- int result_; |
- CompletionCallback callback_; |
- ScopedVector<WebSocketFrame> frames_; |
- WebSocketDeflatePredictorMock* predictor_; |
-}; |
- |
-TEST_F(WebSocketDeflateStreamTest, ReadFailedImmediately) { |
- ScopedVector<WebSocketFrame> frames; |
- CompletionCallback callback; |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _)) |
- .WillOnce(Return(ERR_FAILED)); |
- } |
- EXPECT_EQ(ERR_FAILED, deflate_stream_->ReadFrames(&frames, callback)); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, ReadUncompressedFrameImmediately) { |
- ScopedVector<WebSocketFrame> frames_to_output; |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeText, |
- kFinal, |
- "hello"); |
- ReadFramesStub stub(OK, &frames_to_output); |
- ScopedVector<WebSocketFrame> frames; |
- |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _)) |
- .WillOnce(Invoke(&stub, &ReadFramesStub::Call)); |
- } |
- CompletionCallback callback; |
- ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback)); |
- ASSERT_EQ(1u, frames.size()); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode); |
- EXPECT_TRUE(frames[0]->header.final); |
- EXPECT_FALSE(frames[0]->header.reserved1); |
- EXPECT_EQ("hello", ToString(frames[0])); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, ReadUncompressedFrameAsync) { |
- ReadFramesStub stub(ERR_IO_PENDING); |
- ScopedVector<WebSocketFrame> frames; |
- MockCallback mock_callback, checkpoint; |
- CompletionCallback callback = |
- base::Bind(&MockCallback::Call, base::Unretained(&mock_callback)); |
- |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _)) |
- .WillOnce(Invoke(&stub, &ReadFramesStub::Call)); |
- EXPECT_CALL(checkpoint, Call(0)); |
- EXPECT_CALL(mock_callback, Call(OK)); |
- } |
- ASSERT_EQ(ERR_IO_PENDING, deflate_stream_->ReadFrames(&frames, callback)); |
- ASSERT_EQ(0u, frames.size()); |
- |
- checkpoint.Call(0); |
- |
- AppendTo(stub.frames_passed(), |
- WebSocketFrameHeader::kOpCodeText, |
- kFinal, |
- "hello"); |
- stub.callback().Run(OK); |
- ASSERT_EQ(1u, frames.size()); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode); |
- EXPECT_TRUE(frames[0]->header.final); |
- EXPECT_FALSE(frames[0]->header.reserved1); |
- EXPECT_EQ("hello", ToString(frames[0])); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, ReadFailedAsync) { |
- ReadFramesStub stub(ERR_IO_PENDING); |
- ScopedVector<WebSocketFrame> frames; |
- MockCallback mock_callback, checkpoint; |
- CompletionCallback callback = |
- base::Bind(&MockCallback::Call, base::Unretained(&mock_callback)); |
- |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _)) |
- .WillOnce(Invoke(&stub, &ReadFramesStub::Call)); |
- EXPECT_CALL(checkpoint, Call(0)); |
- EXPECT_CALL(mock_callback, Call(ERR_FAILED)); |
- } |
- ASSERT_EQ(ERR_IO_PENDING, deflate_stream_->ReadFrames(&frames, callback)); |
- ASSERT_EQ(0u, frames.size()); |
- |
- checkpoint.Call(0); |
- |
- AppendTo(stub.frames_passed(), |
- WebSocketFrameHeader::kOpCodeText, |
- kFinal, |
- "hello"); |
- stub.callback().Run(ERR_FAILED); |
- ASSERT_EQ(0u, frames.size()); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, ReadCompressedFrameImmediately) { |
- ScopedVector<WebSocketFrame> frames_to_output; |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeText, |
- kFinal | kReserved1, |
- std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7)); |
- ReadFramesStub stub(OK, &frames_to_output); |
- CompletionCallback callback; |
- ScopedVector<WebSocketFrame> frames; |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _)) |
- .WillOnce(Invoke(&stub, &ReadFramesStub::Call)); |
- } |
- ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback)); |
- ASSERT_EQ(1u, frames.size()); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode); |
- EXPECT_TRUE(frames[0]->header.final); |
- EXPECT_FALSE(frames[0]->header.reserved1); |
- EXPECT_EQ("Hello", ToString(frames[0])); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, ReadCompressedFrameAsync) { |
- ReadFramesStub stub(ERR_IO_PENDING); |
- MockCallback mock_callback, checkpoint; |
- CompletionCallback callback = |
- base::Bind(&MockCallback::Call, base::Unretained(&mock_callback)); |
- ScopedVector<WebSocketFrame> frames; |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _)) |
- .WillOnce(Invoke(&stub, &ReadFramesStub::Call)); |
- EXPECT_CALL(checkpoint, Call(0)); |
- EXPECT_CALL(mock_callback, Call(OK)); |
- } |
- ASSERT_EQ(ERR_IO_PENDING, deflate_stream_->ReadFrames(&frames, callback)); |
- |
- checkpoint.Call(0); |
- |
- AppendTo(stub.frames_passed(), |
- WebSocketFrameHeader::kOpCodeText, |
- kFinal | kReserved1, |
- std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7)); |
- stub.callback().Run(OK); |
- |
- ASSERT_EQ(1u, frames.size()); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode); |
- EXPECT_TRUE(frames[0]->header.final); |
- EXPECT_FALSE(frames[0]->header.reserved1); |
- EXPECT_EQ("Hello", ToString(frames[0])); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, |
- ReadCompressedFrameFragmentImmediatelyButInflaterReturnsPending) { |
- ScopedVector<WebSocketFrame> frames_to_output; |
- const std::string data1("\xf2", 1); |
- const std::string data2("\x48\xcd\xc9\xc9\x07\x00", 6); |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeText, |
- kReserved1, |
- data1); |
- ReadFramesStub stub1(OK, &frames_to_output), stub2(ERR_IO_PENDING); |
- MockCallback mock_callback, checkpoint; |
- CompletionCallback callback = |
- base::Bind(&MockCallback::Call, base::Unretained(&mock_callback)); |
- ScopedVector<WebSocketFrame> frames; |
- |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _)) |
- .WillOnce(Invoke(&stub1, &ReadFramesStub::Call)) |
- .WillOnce(Invoke(&stub2, &ReadFramesStub::Call)); |
- EXPECT_CALL(checkpoint, Call(0)); |
- EXPECT_CALL(mock_callback, Call(OK)); |
- } |
- ASSERT_EQ(ERR_IO_PENDING, deflate_stream_->ReadFrames(&frames, callback)); |
- ASSERT_EQ(0u, frames.size()); |
- |
- AppendTo(stub2.frames_passed(), |
- WebSocketFrameHeader::kOpCodeText, |
- kFinal, |
- data2); |
- |
- checkpoint.Call(0); |
- stub2.callback().Run(OK); |
- |
- ASSERT_EQ(1u, frames.size()); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode); |
- EXPECT_TRUE(frames[0]->header.final); |
- EXPECT_FALSE(frames[0]->header.reserved1); |
- EXPECT_EQ("Hello", ToString(frames[0])); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, ReadInvalidCompressedPayload) { |
- const std::string data("\xf2\x48\xcdINVALID", 10); |
- ScopedVector<WebSocketFrame> frames_to_output; |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeText, |
- kFinal | kReserved1, |
- data); |
- ReadFramesStub stub(OK, &frames_to_output); |
- CompletionCallback callback; |
- ScopedVector<WebSocketFrame> frames; |
- |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _)) |
- .WillOnce(Invoke(&stub, &ReadFramesStub::Call)); |
- } |
- ASSERT_EQ(ERR_WS_PROTOCOL_ERROR, |
- deflate_stream_->ReadFrames(&frames, callback)); |
- ASSERT_EQ(0u, frames.size()); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, MergeMultipleFramesInReadFrames) { |
- const std::string data1("\xf2\x48\xcd", 3); |
- const std::string data2("\xc9\xc9\x07\x00", 4); |
- ScopedVector<WebSocketFrame> frames_to_output; |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeText, |
- kReserved1, |
- data1); |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeContinuation, |
- kFinal, |
- data2); |
- ReadFramesStub stub(OK, &frames_to_output); |
- CompletionCallback callback; |
- ScopedVector<WebSocketFrame> frames; |
- |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _)) |
- .WillOnce(Invoke(&stub, &ReadFramesStub::Call)); |
- } |
- ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback)); |
- ASSERT_EQ(1u, frames.size()); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode); |
- EXPECT_TRUE(frames[0]->header.final); |
- EXPECT_FALSE(frames[0]->header.reserved1); |
- EXPECT_EQ("Hello", ToString(frames[0])); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, ReadUncompressedEmptyFrames) { |
- ScopedVector<WebSocketFrame> frames_to_output; |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeText, |
- kNoFlag); |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeContinuation, |
- kFinal); |
- ReadFramesStub stub(OK, &frames_to_output); |
- CompletionCallback callback; |
- ScopedVector<WebSocketFrame> frames; |
- |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _)) |
- .WillOnce(Invoke(&stub, &ReadFramesStub::Call)); |
- } |
- ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback)); |
- ASSERT_EQ(2u, frames.size()); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode); |
- EXPECT_FALSE(frames[0]->header.final); |
- EXPECT_FALSE(frames[0]->header.reserved1); |
- EXPECT_EQ("", ToString(frames[0])); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation, |
- frames[1]->header.opcode); |
- EXPECT_TRUE(frames[1]->header.final); |
- EXPECT_FALSE(frames[1]->header.reserved1); |
- EXPECT_EQ("", ToString(frames[1])); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, ReadCompressedEmptyFrames) { |
- ScopedVector<WebSocketFrame> frames_to_output; |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeText, |
- kReserved1, |
- std::string("\x02\x00", 1)); |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeContinuation, |
- kFinal); |
- ReadFramesStub stub(OK, &frames_to_output); |
- CompletionCallback callback; |
- ScopedVector<WebSocketFrame> frames; |
- |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _)) |
- .WillOnce(Invoke(&stub, &ReadFramesStub::Call)); |
- } |
- ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback)); |
- ASSERT_EQ(1u, frames.size()); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode); |
- EXPECT_TRUE(frames[0]->header.final); |
- EXPECT_FALSE(frames[0]->header.reserved1); |
- EXPECT_EQ("", ToString(frames[0])); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, |
- ReadCompressedFrameFollowedByEmptyFrame) { |
- const std::string data("\xf2\x48\xcd\xc9\xc9\x07\x00", 7); |
- ScopedVector<WebSocketFrame> frames_to_output; |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeText, |
- kReserved1, |
- data); |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeContinuation, |
- kFinal); |
- ReadFramesStub stub(OK, &frames_to_output); |
- CompletionCallback callback; |
- ScopedVector<WebSocketFrame> frames; |
- |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _)) |
- .WillOnce(Invoke(&stub, &ReadFramesStub::Call)); |
- } |
- ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback)); |
- ASSERT_EQ(1u, frames.size()); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode); |
- EXPECT_TRUE(frames[0]->header.final); |
- EXPECT_FALSE(frames[0]->header.reserved1); |
- EXPECT_EQ("Hello", ToString(frames[0])); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, ReadControlFrameBetweenDataFrames) { |
- const std::string data1("\xf2\x48\xcd", 3); |
- const std::string data2("\xc9\xc9\x07\x00", 4); |
- ScopedVector<WebSocketFrame> frames_to_output; |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeText, |
- kReserved1, |
- data1); |
- AppendTo(&frames_to_output, WebSocketFrameHeader::kOpCodePing, kFinal); |
- AppendTo(&frames_to_output, WebSocketFrameHeader::kOpCodeText, kFinal, data2); |
- ReadFramesStub stub(OK, &frames_to_output); |
- CompletionCallback callback; |
- ScopedVector<WebSocketFrame> frames; |
- |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _)) |
- .WillOnce(Invoke(&stub, &ReadFramesStub::Call)); |
- } |
- ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback)); |
- ASSERT_EQ(2u, frames.size()); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodePing, frames[0]->header.opcode); |
- EXPECT_TRUE(frames[0]->header.final); |
- EXPECT_FALSE(frames[0]->header.reserved1); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[1]->header.opcode); |
- EXPECT_TRUE(frames[1]->header.final); |
- EXPECT_FALSE(frames[1]->header.reserved1); |
- EXPECT_EQ("Hello", ToString(frames[1])); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, SplitToMultipleFramesInReadFrames) { |
- WebSocketDeflater deflater(WebSocketDeflater::TAKE_OVER_CONTEXT); |
- deflater.Initialize(kWindowBits); |
- const size_t kSize = kChunkSize * 3; |
- const std::string original_data(kSize, 'a'); |
- deflater.AddBytes(original_data.data(), original_data.size()); |
- deflater.Finish(); |
- |
- ScopedVector<WebSocketFrame> frames_to_output; |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeBinary, |
- kFinal | kReserved1, |
- ToString(deflater.GetOutput(deflater.CurrentOutputSize()))); |
- |
- ReadFramesStub stub(OK, &frames_to_output); |
- CompletionCallback callback; |
- ScopedVector<WebSocketFrame> frames; |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _)) |
- .WillOnce(Invoke(&stub, &ReadFramesStub::Call)); |
- } |
- |
- ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback)); |
- ASSERT_EQ(3u, frames.size()); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeBinary, frames[0]->header.opcode); |
- EXPECT_FALSE(frames[0]->header.final); |
- EXPECT_FALSE(frames[0]->header.reserved1); |
- EXPECT_EQ(kChunkSize, static_cast<size_t>(frames[0]->header.payload_length)); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation, |
- frames[1]->header.opcode); |
- EXPECT_FALSE(frames[1]->header.final); |
- EXPECT_FALSE(frames[1]->header.reserved1); |
- EXPECT_EQ(kChunkSize, static_cast<size_t>(frames[1]->header.payload_length)); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation, |
- frames[2]->header.opcode); |
- EXPECT_TRUE(frames[2]->header.final); |
- EXPECT_FALSE(frames[2]->header.reserved1); |
- EXPECT_EQ(kChunkSize, static_cast<size_t>(frames[2]->header.payload_length)); |
- EXPECT_EQ(original_data, |
- ToString(frames[0]) + ToString(frames[1]) + ToString(frames[2])); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, InflaterInternalDataCanBeEmpty) { |
- WebSocketDeflater deflater(WebSocketDeflater::TAKE_OVER_CONTEXT); |
- deflater.Initialize(kWindowBits); |
- const std::string original_data(kChunkSize, 'a'); |
- deflater.AddBytes(original_data.data(), original_data.size()); |
- deflater.Finish(); |
- |
- ScopedVector<WebSocketFrame> frames_to_output; |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeBinary, |
- kReserved1, |
- ToString(deflater.GetOutput(deflater.CurrentOutputSize()))); |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeBinary, |
- kFinal, |
- ""); |
- |
- ReadFramesStub stub(OK, &frames_to_output); |
- CompletionCallback callback; |
- ScopedVector<WebSocketFrame> frames; |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _)) |
- .WillOnce(Invoke(&stub, &ReadFramesStub::Call)); |
- } |
- |
- ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback)); |
- ASSERT_EQ(2u, frames.size()); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeBinary, frames[0]->header.opcode); |
- EXPECT_FALSE(frames[0]->header.final); |
- EXPECT_FALSE(frames[0]->header.reserved1); |
- EXPECT_EQ(kChunkSize, static_cast<size_t>(frames[0]->header.payload_length)); |
- |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation, |
- frames[1]->header.opcode); |
- EXPECT_TRUE(frames[1]->header.final); |
- EXPECT_FALSE(frames[1]->header.reserved1); |
- EXPECT_EQ(0u, static_cast<size_t>(frames[1]->header.payload_length)); |
- EXPECT_EQ(original_data, ToString(frames[0]) + ToString(frames[1])); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, |
- Reserved1TurnsOnDuringReadingCompressedContinuationFrame) { |
- const std::string data1("\xf2\x48\xcd", 3); |
- const std::string data2("\xc9\xc9\x07\x00", 4); |
- ScopedVector<WebSocketFrame> frames_to_output; |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeText, |
- kReserved1, |
- data1); |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeContinuation, |
- kFinal | kReserved1, |
- data2); |
- ReadFramesStub stub(OK, &frames_to_output); |
- CompletionCallback callback; |
- ScopedVector<WebSocketFrame> frames; |
- |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _)) |
- .WillOnce(Invoke(&stub, &ReadFramesStub::Call)); |
- } |
- ASSERT_EQ(ERR_WS_PROTOCOL_ERROR, |
- deflate_stream_->ReadFrames(&frames, callback)); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, |
- Reserved1TurnsOnDuringReadingUncompressedContinuationFrame) { |
- ScopedVector<WebSocketFrame> frames_to_output; |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeText, |
- kNoFlag, |
- "hello"); |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeContinuation, |
- kFinal | kReserved1, |
- "world"); |
- ReadFramesStub stub(OK, &frames_to_output); |
- CompletionCallback callback; |
- ScopedVector<WebSocketFrame> frames; |
- |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _)) |
- .WillOnce(Invoke(&stub, &ReadFramesStub::Call)); |
- } |
- ASSERT_EQ(ERR_WS_PROTOCOL_ERROR, |
- deflate_stream_->ReadFrames(&frames, callback)); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, ReadCompressedMessages) { |
- ScopedVector<WebSocketFrame> frames_to_output; |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeText, |
- kFinal | kReserved1, |
- std::string( |
- "\x4a\xce\xcf\x2d\x28\x4a\x2d\x2e\x4e\x4d\x31\x04\x00", 13)); |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeText, |
- kFinal | kReserved1, |
- std::string("\x4a\x86\x33\x8d\x00\x00", 6)); |
- ReadFramesStub stub(OK, &frames_to_output); |
- CompletionCallback callback; |
- ScopedVector<WebSocketFrame> frames; |
- |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _)) |
- .WillOnce(Invoke(&stub, &ReadFramesStub::Call)); |
- } |
- ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback)); |
- ASSERT_EQ(2u, frames.size()); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode); |
- EXPECT_TRUE(frames[0]->header.final); |
- EXPECT_FALSE(frames[0]->header.reserved1); |
- EXPECT_EQ("compressed1", ToString(frames[0])); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[1]->header.opcode); |
- EXPECT_TRUE(frames[1]->header.final); |
- EXPECT_FALSE(frames[1]->header.reserved1); |
- EXPECT_EQ("compressed2", ToString(frames[1])); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, ReadUncompressedMessages) { |
- ScopedVector<WebSocketFrame> frames_to_output; |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeText, |
- kFinal, |
- "uncompressed1"); |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeText, |
- kFinal, |
- "uncompressed2"); |
- ReadFramesStub stub(OK, &frames_to_output); |
- CompletionCallback callback; |
- ScopedVector<WebSocketFrame> frames; |
- |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _)) |
- .WillOnce(Invoke(&stub, &ReadFramesStub::Call)); |
- } |
- ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback)); |
- ASSERT_EQ(2u, frames.size()); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode); |
- EXPECT_TRUE(frames[0]->header.final); |
- EXPECT_FALSE(frames[0]->header.reserved1); |
- EXPECT_EQ("uncompressed1", ToString(frames[0])); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[1]->header.opcode); |
- EXPECT_TRUE(frames[1]->header.final); |
- EXPECT_FALSE(frames[1]->header.reserved1); |
- EXPECT_EQ("uncompressed2", ToString(frames[1])); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, |
- ReadCompressedMessageThenUncompressedMessage) { |
- ScopedVector<WebSocketFrame> frames_to_output; |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeText, |
- kFinal | kReserved1, |
- std::string( |
- "\x4a\xce\xcf\x2d\x28\x4a\x2d\x2e\x4e\x4d\x01\x00", 12)); |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeText, |
- kFinal, |
- "uncompressed"); |
- ReadFramesStub stub(OK, &frames_to_output); |
- CompletionCallback callback; |
- ScopedVector<WebSocketFrame> frames; |
- |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _)) |
- .WillOnce(Invoke(&stub, &ReadFramesStub::Call)); |
- } |
- ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback)); |
- ASSERT_EQ(2u, frames.size()); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode); |
- EXPECT_TRUE(frames[0]->header.final); |
- EXPECT_FALSE(frames[0]->header.reserved1); |
- EXPECT_EQ("compressed", ToString(frames[0])); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[1]->header.opcode); |
- EXPECT_TRUE(frames[1]->header.final); |
- EXPECT_FALSE(frames[1]->header.reserved1); |
- EXPECT_EQ("uncompressed", ToString(frames[1])); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, |
- ReadUncompressedMessageThenCompressedMessage) { |
- ScopedVector<WebSocketFrame> frames_to_output; |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeText, |
- kFinal, |
- "uncompressed"); |
- AppendTo(&frames_to_output, |
- WebSocketFrameHeader::kOpCodeText, |
- kFinal | kReserved1, |
- std::string( |
- "\x4a\xce\xcf\x2d\x28\x4a\x2d\x2e\x4e\x4d\x01\x00", 12)); |
- ReadFramesStub stub(OK, &frames_to_output); |
- CompletionCallback callback; |
- ScopedVector<WebSocketFrame> frames; |
- |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _)) |
- .WillOnce(Invoke(&stub, &ReadFramesStub::Call)); |
- } |
- ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback)); |
- ASSERT_EQ(2u, frames.size()); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode); |
- EXPECT_TRUE(frames[0]->header.final); |
- EXPECT_FALSE(frames[0]->header.reserved1); |
- EXPECT_EQ("uncompressed", ToString(frames[0])); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[1]->header.opcode); |
- EXPECT_TRUE(frames[1]->header.final); |
- EXPECT_FALSE(frames[1]->header.reserved1); |
- EXPECT_EQ("compressed", ToString(frames[1])); |
-} |
- |
-// This is a regression test for crbug.com/343506. |
-TEST_F(WebSocketDeflateStreamTest, ReadEmptyAsyncFrame) { |
- ScopedVector<ReadFramesStub> stub_vector; |
- stub_vector.push_back(new ReadFramesStub(ERR_IO_PENDING)); |
- stub_vector.push_back(new ReadFramesStub(ERR_IO_PENDING)); |
- MockCallback mock_callback; |
- CompletionCallback callback = |
- base::Bind(&MockCallback::Call, base::Unretained(&mock_callback)); |
- ScopedVector<WebSocketFrame> frames; |
- |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _)) |
- .WillOnce(Invoke(stub_vector[0], &ReadFramesStub::Call)); |
- |
- EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _)) |
- .WillOnce(Invoke(stub_vector[1], &ReadFramesStub::Call)); |
- |
- EXPECT_CALL(mock_callback, Call(OK)); |
- } |
- |
- ASSERT_EQ(ERR_IO_PENDING, deflate_stream_->ReadFrames(&frames, callback)); |
- AppendTo(stub_vector[0]->frames_passed(), |
- WebSocketFrameHeader::kOpCodeText, |
- kReserved1, |
- std::string()); |
- stub_vector[0]->callback().Run(OK); |
- AppendTo(stub_vector[1]->frames_passed(), |
- WebSocketFrameHeader::kOpCodeContinuation, |
- kFinal, |
- std::string("\x02\x00")); |
- stub_vector[1]->callback().Run(OK); |
- ASSERT_EQ(1u, frames.size()); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode); |
- EXPECT_EQ("", ToString(frames[0])); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, WriteEmpty) { |
- ScopedVector<WebSocketFrame> frames; |
- CompletionCallback callback; |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)).Times(0); |
- } |
- EXPECT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, WriteFailedImmediately) { |
- ScopedVector<WebSocketFrame> frames; |
- CompletionCallback callback; |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) |
- .WillOnce(Return(ERR_FAILED)); |
- } |
- |
- AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "hello"); |
- predictor_->AddFramesToBeInput(frames); |
- EXPECT_EQ(ERR_FAILED, deflate_stream_->WriteFrames(&frames, callback)); |
- predictor_->Clear(); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, WriteFrameImmediately) { |
- ScopedVector<WebSocketFrame> frames; |
- CompletionCallback callback; |
- WriteFramesStub stub(predictor_, OK); |
- AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello"); |
- predictor_->AddFramesToBeInput(frames); |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, WriteFrames(_, _)) |
- .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); |
- } |
- ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); |
- const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); |
- ASSERT_EQ(1u, frames_passed.size()); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode); |
- EXPECT_TRUE(frames_passed[0]->header.final); |
- EXPECT_TRUE(frames_passed[0]->header.reserved1); |
- EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7), |
- ToString(frames_passed[0])); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, WriteFrameAsync) { |
- WriteFramesStub stub(predictor_, ERR_IO_PENDING); |
- MockCallback mock_callback, checkpoint; |
- CompletionCallback callback = |
- base::Bind(&MockCallback::Call, base::Unretained(&mock_callback)); |
- ScopedVector<WebSocketFrame> frames; |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) |
- .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); |
- EXPECT_CALL(checkpoint, Call(0)); |
- EXPECT_CALL(mock_callback, Call(OK)); |
- } |
- AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello"); |
- predictor_->AddFramesToBeInput(frames); |
- ASSERT_EQ(ERR_IO_PENDING, deflate_stream_->WriteFrames(&frames, callback)); |
- |
- checkpoint.Call(0); |
- stub.callback().Run(OK); |
- |
- const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); |
- ASSERT_EQ(1u, frames_passed.size()); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode); |
- EXPECT_TRUE(frames_passed[0]->header.final); |
- EXPECT_TRUE(frames_passed[0]->header.reserved1); |
- EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7), |
- ToString(frames_passed[0])); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, WriteControlFrameBetweenDataFrames) { |
- ScopedVector<WebSocketFrame> frames; |
- AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "Hel"); |
- AppendTo(&frames, WebSocketFrameHeader::kOpCodePing, kFinal); |
- AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "lo"); |
- predictor_->AddFramesToBeInput(frames); |
- WriteFramesStub stub(predictor_, OK); |
- CompletionCallback callback; |
- |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) |
- .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); |
- } |
- ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); |
- const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); |
- ASSERT_EQ(2u, frames_passed.size()); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodePing, frames_passed[0]->header.opcode); |
- EXPECT_TRUE(frames_passed[0]->header.final); |
- EXPECT_FALSE(frames_passed[0]->header.reserved1); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[1]->header.opcode); |
- EXPECT_TRUE(frames_passed[1]->header.final); |
- EXPECT_TRUE(frames_passed[1]->header.reserved1); |
- EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7), |
- ToString(frames_passed[1])); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, WriteEmptyMessage) { |
- ScopedVector<WebSocketFrame> frames; |
- AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal); |
- predictor_->AddFramesToBeInput(frames); |
- WriteFramesStub stub(predictor_, OK); |
- CompletionCallback callback; |
- |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) |
- .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); |
- } |
- ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); |
- const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); |
- ASSERT_EQ(1u, frames_passed.size()); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode); |
- EXPECT_TRUE(frames_passed[0]->header.final); |
- EXPECT_TRUE(frames_passed[0]->header.reserved1); |
- EXPECT_EQ(std::string("\x00", 1), ToString(frames_passed[0])); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, WriteUncompressedMessage) { |
- ScopedVector<WebSocketFrame> frames; |
- AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "AAAA"); |
- AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "AAA"); |
- predictor_->AddFramesToBeInput(frames); |
- WriteFramesStub stub(predictor_, OK); |
- CompletionCallback callback; |
- |
- predictor_->set_result(WebSocketDeflatePredictor::DO_NOT_DEFLATE); |
- |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) |
- .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); |
- } |
- ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); |
- const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); |
- ASSERT_EQ(2u, frames_passed.size()); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode); |
- EXPECT_FALSE(frames_passed[0]->header.final); |
- EXPECT_FALSE(frames_passed[0]->header.reserved1); |
- EXPECT_EQ("AAAA", ToString(frames_passed[0])); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation, |
- frames_passed[1]->header.opcode); |
- EXPECT_TRUE(frames_passed[1]->header.final); |
- EXPECT_FALSE(frames_passed[1]->header.reserved1); |
- EXPECT_EQ("AAA", ToString(frames_passed[1])); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, LargeDeflatedFramesShouldBeSplit) { |
- WebSocketDeflater deflater(WebSocketDeflater::TAKE_OVER_CONTEXT); |
- LinearCongruentialGenerator lcg(133); |
- WriteFramesStub stub(predictor_, OK); |
- CompletionCallback callback; |
- const size_t size = 1024; |
- |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, WriteFrames(_, _)) |
- .WillRepeatedly(Invoke(&stub, &WriteFramesStub::Call)); |
- } |
- ScopedVector<WebSocketFrame> total_compressed_frames; |
- |
- deflater.Initialize(kWindowBits); |
- while (true) { |
- bool is_final = (total_compressed_frames.size() >= 2); |
- ScopedVector<WebSocketFrame> frames; |
- std::string data; |
- for (size_t i = 0; i < size; ++i) |
- data += static_cast<char>(lcg.Generate()); |
- deflater.AddBytes(data.data(), data.size()); |
- FrameFlag flag = is_final ? kFinal : kNoFlag; |
- AppendTo(&frames, WebSocketFrameHeader::kOpCodeBinary, flag, data); |
- predictor_->AddFramesToBeInput(frames); |
- ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); |
- total_compressed_frames.insert(total_compressed_frames.end(), |
- stub.frames()->begin(), |
- stub.frames()->end()); |
- stub.frames()->weak_clear(); |
- if (is_final) |
- break; |
- } |
- deflater.Finish(); |
- std::string total_deflated; |
- for (size_t i = 0; i < total_compressed_frames.size(); ++i) { |
- WebSocketFrame* frame = total_compressed_frames[i]; |
- const WebSocketFrameHeader& header = frame->header; |
- if (i > 0) { |
- EXPECT_EQ(header.kOpCodeContinuation, header.opcode); |
- EXPECT_FALSE(header.reserved1); |
- } else { |
- EXPECT_EQ(header.kOpCodeBinary, header.opcode); |
- EXPECT_TRUE(header.reserved1); |
- } |
- const bool is_final_frame = (i + 1 == total_compressed_frames.size()); |
- EXPECT_EQ(is_final_frame, header.final); |
- if (!is_final_frame) |
- EXPECT_GT(header.payload_length, 0ul); |
- total_deflated += ToString(frame); |
- } |
- EXPECT_EQ(total_deflated, |
- ToString(deflater.GetOutput(deflater.CurrentOutputSize()))); |
-} |
- |
-TEST_F(WebSocketDeflateStreamTest, WriteMultipleMessages) { |
- ScopedVector<WebSocketFrame> frames; |
- AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello"); |
- AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello"); |
- predictor_->AddFramesToBeInput(frames); |
- WriteFramesStub stub(predictor_, OK); |
- CompletionCallback callback; |
- |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) |
- .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); |
- } |
- ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); |
- const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); |
- ASSERT_EQ(2u, frames_passed.size()); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode); |
- EXPECT_TRUE(frames_passed[0]->header.final); |
- EXPECT_TRUE(frames_passed[0]->header.reserved1); |
- EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7), |
- ToString(frames_passed[0])); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[1]->header.opcode); |
- EXPECT_TRUE(frames_passed[1]->header.final); |
- EXPECT_TRUE(frames_passed[1]->header.reserved1); |
- EXPECT_EQ(std::string("\xf2\x00\x11\x00\x00", 5), ToString(frames_passed[1])); |
-} |
- |
-TEST_F(WebSocketDeflateStreamWithDoNotTakeOverContextTest, |
- WriteMultipleMessages) { |
- ScopedVector<WebSocketFrame> frames; |
- AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello"); |
- AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello"); |
- predictor_->AddFramesToBeInput(frames); |
- WriteFramesStub stub(predictor_, OK); |
- CompletionCallback callback; |
- |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) |
- .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); |
- } |
- ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); |
- const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); |
- ASSERT_EQ(2u, frames_passed.size()); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode); |
- EXPECT_TRUE(frames_passed[0]->header.final); |
- EXPECT_TRUE(frames_passed[0]->header.reserved1); |
- EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7), |
- ToString(frames_passed[0])); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[1]->header.opcode); |
- EXPECT_TRUE(frames_passed[1]->header.final); |
- EXPECT_TRUE(frames_passed[1]->header.reserved1); |
- EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7), |
- ToString(frames_passed[1])); |
-} |
- |
-// In order to check the stream works correctly for multiple |
-// "PossiblyCompressedMessage"s, we test various messages at one test case. |
-TEST_F(WebSocketDeflateStreamWithDoNotTakeOverContextTest, |
- WritePossiblyCompressMessages) { |
- ScopedVector<WebSocketFrame> frames; |
- AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "He"); |
- AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "llo"); |
- AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "AAAAAAAAAA"); |
- AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "AA"); |
- AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "XX"); |
- AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "YY"); |
- predictor_->AddFramesToBeInput(frames); |
- WriteFramesStub stub(predictor_, OK); |
- CompletionCallback callback; |
- predictor_->set_result(WebSocketDeflatePredictor::TRY_DEFLATE); |
- |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) |
- .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); |
- } |
- ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); |
- const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); |
- ASSERT_EQ(5u, frames_passed.size()); |
- |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode); |
- EXPECT_FALSE(frames_passed[0]->header.final); |
- EXPECT_FALSE(frames_passed[0]->header.reserved1); |
- EXPECT_EQ("He", ToString(frames_passed[0])); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation, |
- frames_passed[1]->header.opcode); |
- EXPECT_TRUE(frames_passed[1]->header.final); |
- EXPECT_FALSE(frames_passed[1]->header.reserved1); |
- EXPECT_EQ("llo", ToString(frames_passed[1])); |
- |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[2]->header.opcode); |
- EXPECT_TRUE(frames_passed[2]->header.final); |
- EXPECT_TRUE(frames_passed[2]->header.reserved1); |
- EXPECT_EQ(std::string("\x72\x74\x44\x00\x00\x00", 6), |
- ToString(frames_passed[2])); |
- |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[3]->header.opcode); |
- EXPECT_FALSE(frames_passed[3]->header.final); |
- EXPECT_FALSE(frames_passed[3]->header.reserved1); |
- EXPECT_EQ("XX", ToString(frames_passed[3])); |
- EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation, |
- frames_passed[4]->header.opcode); |
- EXPECT_TRUE(frames_passed[4]->header.final); |
- EXPECT_FALSE(frames_passed[4]->header.reserved1); |
- EXPECT_EQ("YY", ToString(frames_passed[4])); |
-} |
- |
-// This is based on the similar test from websocket_deflater_test.cc |
-TEST_F(WebSocketDeflateStreamWithClientWindowBitsTest, WindowBits8) { |
- SetUpWithWindowBits(8); |
- CompletionCallback callback; |
- AddCompressibleFrameString(); |
- WriteFramesStub stub(predictor_, OK); |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, WriteFrames(_, _)) |
- .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); |
- } |
- ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames_, callback)); |
- const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); |
- ASSERT_EQ(1u, frames_passed.size()); |
- EXPECT_EQ(std::string("r\xce(\xca\xcf\xcd,\xcdM\x1c\xe1\xc0\x39\xa3" |
- "(?7\xb3\x34\x17\x00", 21), |
- ToString(frames_passed[0])); |
-} |
- |
-// The same input with window_bits=10 returns smaller output. |
-TEST_F(WebSocketDeflateStreamWithClientWindowBitsTest, WindowBits10) { |
- SetUpWithWindowBits(10); |
- CompletionCallback callback; |
- AddCompressibleFrameString(); |
- WriteFramesStub stub(predictor_, OK); |
- { |
- InSequence s; |
- EXPECT_CALL(*mock_stream_, WriteFrames(_, _)) |
- .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); |
- } |
- ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames_, callback)); |
- const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); |
- ASSERT_EQ(1u, frames_passed.size()); |
- EXPECT_EQ( |
- std::string("r\xce(\xca\xcf\xcd,\xcdM\x1c\xe1\xc0\x19\x1a\x0e\0\0", 17), |
- ToString(frames_passed[0])); |
-} |
- |
-} // namespace |
- |
-} // namespace net |