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

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

Issue 39193005: Introduce WebSocketDeflatePredictor. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/websockets/websocket_deflate_stream.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "net/websockets/websocket_deflate_stream.h" 5 #include "net/websockets/websocket_deflate_stream.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 #include <deque>
8 #include <string> 9 #include <string>
9 10
10 #include "base/basictypes.h" 11 #include "base/basictypes.h"
11 #include "base/bind.h" 12 #include "base/bind.h"
12 #include "base/memory/ref_counted.h" 13 #include "base/memory/ref_counted.h"
13 #include "base/memory/scoped_ptr.h" 14 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/scoped_vector.h" 15 #include "base/memory/scoped_vector.h"
15 #include "net/base/completion_callback.h" 16 #include "net/base/completion_callback.h"
16 #include "net/base/io_buffer.h" 17 #include "net/base/io_buffer.h"
17 #include "net/base/net_errors.h" 18 #include "net/base/net_errors.h"
19 #include "net/websockets/websocket_deflate_predictor.h"
18 #include "net/websockets/websocket_deflater.h" 20 #include "net/websockets/websocket_deflater.h"
19 #include "net/websockets/websocket_frame.h" 21 #include "net/websockets/websocket_frame.h"
20 #include "net/websockets/websocket_inflater.h" 22 #include "net/websockets/websocket_inflater.h"
21 #include "net/websockets/websocket_stream.h" 23 #include "net/websockets/websocket_stream.h"
22 #include "net/websockets/websocket_test_util.h" 24 #include "net/websockets/websocket_test_util.h"
23 #include "testing/gmock/include/gmock/gmock.h" 25 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h" 26 #include "testing/gtest/include/gtest/gtest.h"
25 27
26 namespace net { 28 namespace net {
27 namespace { 29 namespace {
(...skipping 30 matching lines...) Expand all
58 } 60 }
59 61
60 std::string ToString(IOBuffer* buffer, size_t size) { 62 std::string ToString(IOBuffer* buffer, size_t size) {
61 return std::string(buffer->data(), size); 63 return std::string(buffer->data(), size);
62 } 64 }
63 65
64 std::string ToString(const scoped_refptr<IOBuffer>& buffer, size_t size) { 66 std::string ToString(const scoped_refptr<IOBuffer>& buffer, size_t size) {
65 return ToString(buffer.get(), size); 67 return ToString(buffer.get(), size);
66 } 68 }
67 69
68 std::string ToString(WebSocketFrame* frame) { 70 std::string ToString(const WebSocketFrame* frame) {
69 return frame->data ? ToString(frame->data, frame->header.payload_length) : ""; 71 return frame->data ? ToString(frame->data, frame->header.payload_length) : "";
70 } 72 }
71 73
72 void AppendTo(ScopedVector<WebSocketFrame>* frames, 74 void AppendTo(ScopedVector<WebSocketFrame>* frames,
73 WebSocketFrameHeader::OpCode opcode, 75 WebSocketFrameHeader::OpCode opcode,
74 FrameFlag flag, 76 FrameFlag flag,
75 const std::string& data) { 77 const std::string& data) {
76 scoped_ptr<WebSocketFrame> frame(new WebSocketFrame(opcode)); 78 scoped_ptr<WebSocketFrame> frame(new WebSocketFrame(opcode));
77 frame->header.final = (flag & kFinal); 79 frame->header.final = (flag & kFinal);
78 frame->header.reserved1 = (flag & kReserved1); 80 frame->header.reserved1 = (flag & kReserved1);
(...skipping 15 matching lines...) Expand all
94 public: 96 public:
95 MOCK_METHOD2(ReadFrames, int(ScopedVector<WebSocketFrame>*, 97 MOCK_METHOD2(ReadFrames, int(ScopedVector<WebSocketFrame>*,
96 const CompletionCallback&)); 98 const CompletionCallback&));
97 MOCK_METHOD2(WriteFrames, int(ScopedVector<WebSocketFrame>*, 99 MOCK_METHOD2(WriteFrames, int(ScopedVector<WebSocketFrame>*,
98 const CompletionCallback&)); 100 const CompletionCallback&));
99 MOCK_METHOD0(Close, void()); 101 MOCK_METHOD0(Close, void());
100 MOCK_CONST_METHOD0(GetSubProtocol, std::string()); 102 MOCK_CONST_METHOD0(GetSubProtocol, std::string());
101 MOCK_CONST_METHOD0(GetExtensions, std::string()); 103 MOCK_CONST_METHOD0(GetExtensions, std::string());
102 }; 104 };
103 105
106 // This mock class relies on some assumptions.
107 // - RecordInputDataFrame is called after the corresponding WriteFrames
108 // call.
109 // - RecordWrittenDataFrame is called before writing the frame.
110 class WebSocketDeflatePredictorMock : public WebSocketDeflatePredictor {
111 public:
112 WebSocketDeflatePredictorMock() : result_(DEFLATE) {}
113 virtual ~WebSocketDeflatePredictorMock() {
114 // Verify whether all expectaions are consumed.
115 if (!frames_to_be_input_.empty()) {
116 ADD_FAILURE() << "There are missing frames to be input.";
117 return;
118 }
119 if (!frames_written_.empty()) {
120 ADD_FAILURE() << "There are extra written frames.";
121 return;
122 }
123 }
124
125 // WebSocketDeflatePredictor functions.
126 virtual Result Predict(const ScopedVector<WebSocketFrame>& frames,
127 size_t frame_index) OVERRIDE {
128 return result_;
129 }
130 virtual void RecordInputDataFrame(const WebSocketFrame* frame) OVERRIDE {
131 if (!WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode)) {
132 ADD_FAILURE() << "Control frames should not be recorded.";
133 return;
134 }
135 if (frame->header.reserved1) {
136 ADD_FAILURE() << "Input frame may not be compressed.";
137 return;
138 }
139 if (frames_to_be_input_.empty()) {
140 ADD_FAILURE() << "Unexpected input data frame";
141 return;
142 }
143 if (frame != frames_to_be_input_.front()) {
144 ADD_FAILURE() << "Input data frame does not match the expectation.";
145 return;
146 }
147 frames_to_be_input_.pop_front();
148 }
149 virtual void RecordWrittenDataFrame(const WebSocketFrame* frame) OVERRIDE {
150 if (!WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode)) {
151 ADD_FAILURE() << "Control frames should not be recorded.";
152 return;
153 }
154 frames_written_.push_back(frame);
155 }
156
157 // Sets |result_| for the |Predict| return value.
158 void set_result(Result result) { result_ = result; }
159
160 // Adds |frame| as an expectation of future |RecordInputDataFrame| call.
161 void AddFrameToBeInput(const WebSocketFrame* frame) {
162 if (!WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode))
163 return;
164 frames_to_be_input_.push_back(frame);
165 }
166 // Verifies that |frame| is recorded in order.
167 void VerifySentFrame(const WebSocketFrame* frame) {
168 if (!WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode))
169 return;
170 if (frames_written_.empty()) {
171 ADD_FAILURE() << "There are missing frames to be written.";
172 return;
173 }
174 if (frame != frames_written_.front()) {
175 ADD_FAILURE() << "Written data frame does not match the expectation.";
176 return;
177 }
178 frames_written_.pop_front();
179 }
180 void AddFramesToBeInput(const ScopedVector<WebSocketFrame>& frames) {
181 for (size_t i = 0; i < frames.size(); ++i)
182 AddFrameToBeInput(frames[i]);
183 }
184 void VerifySentFrames(const ScopedVector<WebSocketFrame>& frames) {
185 for (size_t i = 0; i < frames.size(); ++i)
186 VerifySentFrame(frames[i]);
187 }
188 // Call this method in order to disable checks in the destructor when
189 // WriteFrames fails.
190 void Clear() {
191 frames_to_be_input_.clear();
192 frames_written_.clear();
193 }
194
195 private:
196 Result result_;
197 // Data frames which will be recorded by |RecordInputFrames|.
198 // Pushed by |AddFrameToBeInput| and popped and verified by
199 // |RecordInputFrames|.
200 std::deque<const WebSocketFrame*> frames_to_be_input_;
201 // Data frames recorded by |RecordWrittenFrames|.
202 // Pushed by |RecordWrittenFrames| and popped and verified by
203 // |VerifySentFrame|.
204 std::deque<const WebSocketFrame*> frames_written_;
205
206 DISALLOW_COPY_AND_ASSIGN(WebSocketDeflatePredictorMock);
207 };
208
104 class WebSocketDeflateStreamTest : public ::testing::Test { 209 class WebSocketDeflateStreamTest : public ::testing::Test {
105 public: 210 public:
106 WebSocketDeflateStreamTest() 211 WebSocketDeflateStreamTest()
107 : mock_stream_(NULL) { 212 : mock_stream_(NULL) {
108 mock_stream_ = new testing::StrictMock<MockWebSocketStream>; 213 mock_stream_ = new testing::StrictMock<MockWebSocketStream>;
214 predictor_ = new WebSocketDeflatePredictorMock;
109 deflate_stream_.reset(new WebSocketDeflateStream( 215 deflate_stream_.reset(new WebSocketDeflateStream(
110 scoped_ptr<WebSocketStream>(mock_stream_), 216 scoped_ptr<WebSocketStream>(mock_stream_),
111 WebSocketDeflater::TAKE_OVER_CONTEXT)); 217 WebSocketDeflater::TAKE_OVER_CONTEXT,
218 scoped_ptr<WebSocketDeflatePredictor>(predictor_)));
112 } 219 }
113 virtual ~WebSocketDeflateStreamTest() {} 220 virtual ~WebSocketDeflateStreamTest() {}
114 221
115 protected: 222 protected:
116 scoped_ptr<WebSocketDeflateStream> deflate_stream_; 223 scoped_ptr<WebSocketDeflateStream> deflate_stream_;
117 // |mock_stream_| will be deleted when |deflate_stream_| is destroyed. 224 // Owned by |deflate_stream_|.
118 MockWebSocketStream* mock_stream_; 225 MockWebSocketStream* mock_stream_;
226 // Owned by |deflate_stream_|.
227 WebSocketDeflatePredictorMock* predictor_;
119 }; 228 };
120 229
121 // Since WebSocketDeflater with DoNotTakeOverContext is well tested at 230 // Since WebSocketDeflater with DoNotTakeOverContext is well tested at
122 // websocket_deflater_test.cc, we have only one test for this configuration 231 // websocket_deflater_test.cc, we have only a few tests for this configuration
123 // here. 232 // here.
124 class WebSocketDeflateStreamWithDoNotTakeOverContextTest 233 class WebSocketDeflateStreamWithDoNotTakeOverContextTest
125 : public ::testing::Test { 234 : public ::testing::Test {
126 public: 235 public:
127 WebSocketDeflateStreamWithDoNotTakeOverContextTest() 236 WebSocketDeflateStreamWithDoNotTakeOverContextTest()
128 : mock_stream_(NULL) { 237 : mock_stream_(NULL) {
129 mock_stream_ = new testing::StrictMock<MockWebSocketStream>; 238 mock_stream_ = new testing::StrictMock<MockWebSocketStream>;
239 predictor_ = new WebSocketDeflatePredictorMock;
130 deflate_stream_.reset(new WebSocketDeflateStream( 240 deflate_stream_.reset(new WebSocketDeflateStream(
131 scoped_ptr<WebSocketStream>(mock_stream_), 241 scoped_ptr<WebSocketStream>(mock_stream_),
132 WebSocketDeflater::DO_NOT_TAKE_OVER_CONTEXT)); 242 WebSocketDeflater::DO_NOT_TAKE_OVER_CONTEXT,
243 scoped_ptr<WebSocketDeflatePredictor>(predictor_)));
133 } 244 }
134 virtual ~WebSocketDeflateStreamWithDoNotTakeOverContextTest() {} 245 virtual ~WebSocketDeflateStreamWithDoNotTakeOverContextTest() {}
135 246
136 protected: 247 protected:
137 scoped_ptr<WebSocketDeflateStream> deflate_stream_; 248 scoped_ptr<WebSocketDeflateStream> deflate_stream_;
138 // |mock_stream_| will be deleted when |deflate_stream_| is destroyed. 249 // |mock_stream_| will be deleted when |deflate_stream_| is destroyed.
139 MockWebSocketStream* mock_stream_; 250 MockWebSocketStream* mock_stream_;
251 // |predictor_| will be deleted when |deflate_stream_| is destroyed.
252 WebSocketDeflatePredictorMock* predictor_;
140 }; 253 };
141 254
142 // ReadFrameStub is a stub for WebSocketStream::ReadFrames. 255 // ReadFrameStub is a stub for WebSocketStream::ReadFrames.
143 // It returns |result_| and |frames_to_output_| to the caller and 256 // It returns |result_| and |frames_to_output_| to the caller and
144 // saves parameters to |frames_passed_| and |callback_|. 257 // saves parameters to |frames_passed_| and |callback_|.
145 class ReadFramesStub { 258 class ReadFramesStub {
146 public: 259 public:
147 explicit ReadFramesStub(int result) : result_(result) {} 260 explicit ReadFramesStub(int result) : result_(result) {}
148 261
149 ReadFramesStub(int result, ScopedVector<WebSocketFrame>* frames_to_output) 262 ReadFramesStub(int result, ScopedVector<WebSocketFrame>* frames_to_output)
(...skipping 16 matching lines...) Expand all
166 return frames_passed_; 279 return frames_passed_;
167 } 280 }
168 281
169 private: 282 private:
170 int result_; 283 int result_;
171 CompletionCallback callback_; 284 CompletionCallback callback_;
172 ScopedVector<WebSocketFrame> frames_to_output_; 285 ScopedVector<WebSocketFrame> frames_to_output_;
173 ScopedVector<WebSocketFrame>* frames_passed_; 286 ScopedVector<WebSocketFrame>* frames_passed_;
174 }; 287 };
175 288
176 // WriteFrameStub is a stub for WebSocketStream::WriteFrames. 289 // WriteFramesStub is a stub for WebSocketStream::WriteFrames.
177 // It returns |result_| and |frames_| to the caller and 290 // It returns |result_| and |frames_| to the caller and
178 // saves |callback| parameter to |callback_|. 291 // saves |callback| parameter to |callback_|.
179 class WriteFramesStub { 292 class WriteFramesStub {
180 public: 293 public:
181 explicit WriteFramesStub(int result) : result_(result) {} 294 explicit WriteFramesStub(WebSocketDeflatePredictorMock* predictor,
295 int result)
296 : result_(result), predictor_(predictor) {}
182 297
183 int Call(ScopedVector<WebSocketFrame>* frames, 298 int Call(ScopedVector<WebSocketFrame>* frames,
184 const CompletionCallback& callback) { 299 const CompletionCallback& callback) {
185 for (size_t i = 0; i < frames->size(); ++i) { 300 frames_.insert(frames_.end(), frames->begin(), frames->end());
186 frames_.push_back((*frames)[i]);
187 }
188 frames->weak_clear(); 301 frames->weak_clear();
189 callback_ = callback; 302 callback_ = callback;
303 predictor_->VerifySentFrames(frames_);
190 return result_; 304 return result_;
191 } 305 }
192 306
193 int result() const { return result_; } 307 int result() const { return result_; }
194 const CompletionCallback callback() const { return callback_; } 308 const CompletionCallback callback() const { return callback_; }
195 ScopedVector<WebSocketFrame>* frames() { return &frames_; } 309 ScopedVector<WebSocketFrame>* frames() { return &frames_; }
196 310
197 private: 311 private:
198 int result_; 312 int result_;
199 CompletionCallback callback_; 313 CompletionCallback callback_;
200 ScopedVector<WebSocketFrame> frames_; 314 ScopedVector<WebSocketFrame> frames_;
315 WebSocketDeflatePredictorMock* predictor_;
201 }; 316 };
202 317
203 TEST_F(WebSocketDeflateStreamTest, ReadFailedImmediately) { 318 TEST_F(WebSocketDeflateStreamTest, ReadFailedImmediately) {
204 ScopedVector<WebSocketFrame> frames; 319 ScopedVector<WebSocketFrame> frames;
205 CompletionCallback callback; 320 CompletionCallback callback;
206 { 321 {
207 InSequence s; 322 InSequence s;
208 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _)) 323 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
209 .WillOnce(Return(ERR_FAILED)); 324 .WillOnce(Return(ERR_FAILED));
210 } 325 }
(...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after
784 TEST_F(WebSocketDeflateStreamTest, WriteFailedImmediately) { 899 TEST_F(WebSocketDeflateStreamTest, WriteFailedImmediately) {
785 ScopedVector<WebSocketFrame> frames; 900 ScopedVector<WebSocketFrame> frames;
786 CompletionCallback callback; 901 CompletionCallback callback;
787 { 902 {
788 InSequence s; 903 InSequence s;
789 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) 904 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
790 .WillOnce(Return(ERR_FAILED)); 905 .WillOnce(Return(ERR_FAILED));
791 } 906 }
792 907
793 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "hello"); 908 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "hello");
909 predictor_->AddFramesToBeInput(frames);
794 EXPECT_EQ(ERR_FAILED, deflate_stream_->WriteFrames(&frames, callback)); 910 EXPECT_EQ(ERR_FAILED, deflate_stream_->WriteFrames(&frames, callback));
911 predictor_->Clear();
795 } 912 }
796 913
797 TEST_F(WebSocketDeflateStreamTest, WriteFrameImmediately) { 914 TEST_F(WebSocketDeflateStreamTest, WriteFrameImmediately) {
798 ScopedVector<WebSocketFrame> frames; 915 ScopedVector<WebSocketFrame> frames;
799 CompletionCallback callback; 916 CompletionCallback callback;
800 WriteFramesStub stub(OK); 917 WriteFramesStub stub(predictor_, OK);
801 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello"); 918 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
919 predictor_->AddFramesToBeInput(frames);
802 { 920 {
803 InSequence s; 921 InSequence s;
804 EXPECT_CALL(*mock_stream_, WriteFrames(_, _)) 922 EXPECT_CALL(*mock_stream_, WriteFrames(_, _))
805 .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); 923 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
806 } 924 }
807 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); 925 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
808 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); 926 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
809 ASSERT_EQ(1u, frames_passed.size()); 927 ASSERT_EQ(1u, frames_passed.size());
810 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode); 928 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
811 EXPECT_TRUE(frames_passed[0]->header.final); 929 EXPECT_TRUE(frames_passed[0]->header.final);
812 EXPECT_TRUE(frames_passed[0]->header.reserved1); 930 EXPECT_TRUE(frames_passed[0]->header.reserved1);
813 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7), 931 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
814 ToString(frames_passed[0])); 932 ToString(frames_passed[0]));
815 } 933 }
816 934
817 TEST_F(WebSocketDeflateStreamTest, WriteFrameAsync) { 935 TEST_F(WebSocketDeflateStreamTest, WriteFrameAsync) {
818 WriteFramesStub stub(ERR_IO_PENDING); 936 WriteFramesStub stub(predictor_, ERR_IO_PENDING);
819 MockCallback mock_callback, checkpoint; 937 MockCallback mock_callback, checkpoint;
820 CompletionCallback callback = 938 CompletionCallback callback =
821 base::Bind(&MockCallback::Call, base::Unretained(&mock_callback)); 939 base::Bind(&MockCallback::Call, base::Unretained(&mock_callback));
822 ScopedVector<WebSocketFrame> frames; 940 ScopedVector<WebSocketFrame> frames;
823 { 941 {
824 InSequence s; 942 InSequence s;
825 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) 943 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
826 .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); 944 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
827 EXPECT_CALL(checkpoint, Call(0)); 945 EXPECT_CALL(checkpoint, Call(0));
828 EXPECT_CALL(mock_callback, Call(OK)); 946 EXPECT_CALL(mock_callback, Call(OK));
829 } 947 }
830 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello"); 948 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
949 predictor_->AddFramesToBeInput(frames);
831 ASSERT_EQ(ERR_IO_PENDING, deflate_stream_->WriteFrames(&frames, callback)); 950 ASSERT_EQ(ERR_IO_PENDING, deflate_stream_->WriteFrames(&frames, callback));
832 951
833 checkpoint.Call(0); 952 checkpoint.Call(0);
834 stub.callback().Run(OK); 953 stub.callback().Run(OK);
835 954
836 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); 955 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
837 ASSERT_EQ(1u, frames_passed.size()); 956 ASSERT_EQ(1u, frames_passed.size());
838 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode); 957 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
839 EXPECT_TRUE(frames_passed[0]->header.final); 958 EXPECT_TRUE(frames_passed[0]->header.final);
840 EXPECT_TRUE(frames_passed[0]->header.reserved1); 959 EXPECT_TRUE(frames_passed[0]->header.reserved1);
841 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7), 960 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
842 ToString(frames_passed[0])); 961 ToString(frames_passed[0]));
843 } 962 }
844 963
845 TEST_F(WebSocketDeflateStreamTest, WriteControlFrameBetweenDataFrames) { 964 TEST_F(WebSocketDeflateStreamTest, WriteControlFrameBetweenDataFrames) {
846 ScopedVector<WebSocketFrame> frames; 965 ScopedVector<WebSocketFrame> frames;
847 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "Hel"); 966 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "Hel");
848 AppendTo(&frames, WebSocketFrameHeader::kOpCodePing, kFinal); 967 AppendTo(&frames, WebSocketFrameHeader::kOpCodePing, kFinal);
849 AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "lo"); 968 AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "lo");
850 WriteFramesStub stub(OK); 969 predictor_->AddFramesToBeInput(frames);
970 WriteFramesStub stub(predictor_, OK);
851 CompletionCallback callback; 971 CompletionCallback callback;
852 972
853 { 973 {
854 InSequence s; 974 InSequence s;
855 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) 975 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
856 .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); 976 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
857 } 977 }
858 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); 978 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
859 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); 979 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
860 ASSERT_EQ(2u, frames_passed.size()); 980 ASSERT_EQ(2u, frames_passed.size());
861 EXPECT_EQ(WebSocketFrameHeader::kOpCodePing, frames_passed[0]->header.opcode); 981 EXPECT_EQ(WebSocketFrameHeader::kOpCodePing, frames_passed[0]->header.opcode);
862 EXPECT_TRUE(frames_passed[0]->header.final); 982 EXPECT_TRUE(frames_passed[0]->header.final);
863 EXPECT_FALSE(frames_passed[0]->header.reserved1); 983 EXPECT_FALSE(frames_passed[0]->header.reserved1);
864 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[1]->header.opcode); 984 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[1]->header.opcode);
865 EXPECT_TRUE(frames_passed[1]->header.final); 985 EXPECT_TRUE(frames_passed[1]->header.final);
866 EXPECT_TRUE(frames_passed[1]->header.reserved1); 986 EXPECT_TRUE(frames_passed[1]->header.reserved1);
867 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7), 987 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
868 ToString(frames_passed[1])); 988 ToString(frames_passed[1]));
869 } 989 }
870 990
871 TEST_F(WebSocketDeflateStreamTest, WriteEmptyMessage) { 991 TEST_F(WebSocketDeflateStreamTest, WriteEmptyMessage) {
872 ScopedVector<WebSocketFrame> frames; 992 ScopedVector<WebSocketFrame> frames;
873 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal); 993 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal);
874 WriteFramesStub stub(OK); 994 predictor_->AddFramesToBeInput(frames);
995 WriteFramesStub stub(predictor_, OK);
875 CompletionCallback callback; 996 CompletionCallback callback;
876 997
877 { 998 {
878 InSequence s; 999 InSequence s;
879 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) 1000 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
880 .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); 1001 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
881 } 1002 }
882 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); 1003 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
883 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); 1004 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
884 ASSERT_EQ(1u, frames_passed.size()); 1005 ASSERT_EQ(1u, frames_passed.size());
885 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode); 1006 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
886 EXPECT_TRUE(frames_passed[0]->header.final); 1007 EXPECT_TRUE(frames_passed[0]->header.final);
887 EXPECT_TRUE(frames_passed[0]->header.reserved1); 1008 EXPECT_TRUE(frames_passed[0]->header.reserved1);
888 EXPECT_EQ(std::string("\x02\x00", 2), ToString(frames_passed[0])); 1009 EXPECT_EQ(std::string("\x02\x00", 2), ToString(frames_passed[0]));
889 } 1010 }
890 1011
1012 TEST_F(WebSocketDeflateStreamTest, WriteUncompressedMessage) {
1013 ScopedVector<WebSocketFrame> frames;
1014 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "AAAA");
1015 AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "AAA");
1016 predictor_->AddFramesToBeInput(frames);
1017 WriteFramesStub stub(predictor_, OK);
1018 CompletionCallback callback;
1019
1020 predictor_->set_result(WebSocketDeflatePredictor::DO_NOT_DEFLATE);
1021
1022 {
1023 InSequence s;
1024 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
1025 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1026 }
1027 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
1028 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
1029 ASSERT_EQ(2u, frames_passed.size());
1030 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1031 EXPECT_FALSE(frames_passed[0]->header.final);
1032 EXPECT_FALSE(frames_passed[0]->header.reserved1);
1033 EXPECT_EQ("AAAA", ToString(frames_passed[0]));
1034 EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
1035 frames_passed[1]->header.opcode);
1036 EXPECT_TRUE(frames_passed[1]->header.final);
1037 EXPECT_FALSE(frames_passed[1]->header.reserved1);
1038 EXPECT_EQ("AAA", ToString(frames_passed[1]));
1039 }
1040
891 TEST_F(WebSocketDeflateStreamTest, LargeDeflatedFramesShouldBeSplit) { 1041 TEST_F(WebSocketDeflateStreamTest, LargeDeflatedFramesShouldBeSplit) {
892 WebSocketDeflater deflater(WebSocketDeflater::TAKE_OVER_CONTEXT); 1042 WebSocketDeflater deflater(WebSocketDeflater::TAKE_OVER_CONTEXT);
893 LinearCongruentialGenerator lcg(133); 1043 LinearCongruentialGenerator lcg(133);
894 WriteFramesStub stub(OK); 1044 WriteFramesStub stub(predictor_, OK);
895 CompletionCallback callback; 1045 CompletionCallback callback;
896 const size_t size = 1024; 1046 const size_t size = 1024;
897 1047
898 { 1048 {
899 InSequence s; 1049 InSequence s;
900 EXPECT_CALL(*mock_stream_, WriteFrames(_, _)) 1050 EXPECT_CALL(*mock_stream_, WriteFrames(_, _))
901 .WillRepeatedly(Invoke(&stub, &WriteFramesStub::Call)); 1051 .WillRepeatedly(Invoke(&stub, &WriteFramesStub::Call));
902 } 1052 }
903 ScopedVector<WebSocketFrame> total_compressed_frames; 1053 ScopedVector<WebSocketFrame> total_compressed_frames;
904 1054
905 deflater.Initialize(kWindowBits); 1055 deflater.Initialize(kWindowBits);
906 while (true) { 1056 while (true) {
907 bool is_final = (total_compressed_frames.size() >= 2); 1057 bool is_final = (total_compressed_frames.size() >= 2);
908 ScopedVector<WebSocketFrame> frames; 1058 ScopedVector<WebSocketFrame> frames;
909 std::string data; 1059 std::string data;
910 for (size_t i = 0; i < size; ++i) 1060 for (size_t i = 0; i < size; ++i)
911 data += static_cast<char>(lcg.Generate()); 1061 data += static_cast<char>(lcg.Generate());
912 deflater.AddBytes(data.data(), data.size()); 1062 deflater.AddBytes(data.data(), data.size());
913 FrameFlag flag = is_final ? kFinal : kNoFlag; 1063 FrameFlag flag = is_final ? kFinal : kNoFlag;
914 AppendTo(&frames, WebSocketFrameHeader::kOpCodeBinary, flag, data); 1064 AppendTo(&frames, WebSocketFrameHeader::kOpCodeBinary, flag, data);
1065 predictor_->AddFramesToBeInput(frames);
915 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); 1066 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
916 for (size_t i = 0; i < stub.frames()->size(); ++i) 1067 total_compressed_frames.insert(total_compressed_frames.end(),
917 total_compressed_frames.push_back((*stub.frames())[i]); 1068 stub.frames()->begin(),
1069 stub.frames()->end());
918 stub.frames()->weak_clear(); 1070 stub.frames()->weak_clear();
919 if (is_final) 1071 if (is_final)
920 break; 1072 break;
921 } 1073 }
922 deflater.Finish(); 1074 deflater.Finish();
923 std::string total_deflated; 1075 std::string total_deflated;
924 for (size_t i = 0; i < total_compressed_frames.size(); ++i) { 1076 for (size_t i = 0; i < total_compressed_frames.size(); ++i) {
925 WebSocketFrame* frame = total_compressed_frames[i]; 1077 WebSocketFrame* frame = total_compressed_frames[i];
926 const WebSocketFrameHeader& header = frame->header; 1078 const WebSocketFrameHeader& header = frame->header;
927 if (i > 0) { 1079 if (i > 0) {
(...skipping 10 matching lines...) Expand all
938 total_deflated += ToString(frame); 1090 total_deflated += ToString(frame);
939 } 1091 }
940 EXPECT_EQ(total_deflated, 1092 EXPECT_EQ(total_deflated,
941 ToString(deflater.GetOutput(deflater.CurrentOutputSize()))); 1093 ToString(deflater.GetOutput(deflater.CurrentOutputSize())));
942 } 1094 }
943 1095
944 TEST_F(WebSocketDeflateStreamTest, WriteMultipleMessages) { 1096 TEST_F(WebSocketDeflateStreamTest, WriteMultipleMessages) {
945 ScopedVector<WebSocketFrame> frames; 1097 ScopedVector<WebSocketFrame> frames;
946 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello"); 1098 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
947 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello"); 1099 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
948 WriteFramesStub stub(OK); 1100 predictor_->AddFramesToBeInput(frames);
1101 WriteFramesStub stub(predictor_, OK);
949 CompletionCallback callback; 1102 CompletionCallback callback;
950 1103
951 { 1104 {
952 InSequence s; 1105 InSequence s;
953 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) 1106 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
954 .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); 1107 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
955 } 1108 }
956 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); 1109 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
957 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); 1110 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
958 ASSERT_EQ(2u, frames_passed.size()); 1111 ASSERT_EQ(2u, frames_passed.size());
959 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode); 1112 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
960 EXPECT_TRUE(frames_passed[0]->header.final); 1113 EXPECT_TRUE(frames_passed[0]->header.final);
961 EXPECT_TRUE(frames_passed[0]->header.reserved1); 1114 EXPECT_TRUE(frames_passed[0]->header.reserved1);
962 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7), 1115 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
963 ToString(frames_passed[0])); 1116 ToString(frames_passed[0]));
964 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[1]->header.opcode); 1117 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[1]->header.opcode);
965 EXPECT_TRUE(frames_passed[1]->header.final); 1118 EXPECT_TRUE(frames_passed[1]->header.final);
966 EXPECT_TRUE(frames_passed[1]->header.reserved1); 1119 EXPECT_TRUE(frames_passed[1]->header.reserved1);
967 EXPECT_EQ(std::string("\xf2\x00\x11\x00\x00", 5), ToString(frames_passed[1])); 1120 EXPECT_EQ(std::string("\xf2\x00\x11\x00\x00", 5), ToString(frames_passed[1]));
968 } 1121 }
969 1122
970 TEST_F(WebSocketDeflateStreamWithDoNotTakeOverContextTest, 1123 TEST_F(WebSocketDeflateStreamWithDoNotTakeOverContextTest,
971 WriteMultipleMessages) { 1124 WriteMultipleMessages) {
972 ScopedVector<WebSocketFrame> frames; 1125 ScopedVector<WebSocketFrame> frames;
973 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello"); 1126 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
974 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello"); 1127 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
975 WriteFramesStub stub(OK); 1128 predictor_->AddFramesToBeInput(frames);
1129 WriteFramesStub stub(predictor_, OK);
976 CompletionCallback callback; 1130 CompletionCallback callback;
977 1131
978 { 1132 {
979 InSequence s; 1133 InSequence s;
980 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) 1134 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
981 .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); 1135 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
982 } 1136 }
983 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); 1137 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
984 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); 1138 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
985 ASSERT_EQ(2u, frames_passed.size()); 1139 ASSERT_EQ(2u, frames_passed.size());
986 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode); 1140 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
987 EXPECT_TRUE(frames_passed[0]->header.final); 1141 EXPECT_TRUE(frames_passed[0]->header.final);
988 EXPECT_TRUE(frames_passed[0]->header.reserved1); 1142 EXPECT_TRUE(frames_passed[0]->header.reserved1);
989 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7), 1143 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
990 ToString(frames_passed[0])); 1144 ToString(frames_passed[0]));
991 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[1]->header.opcode); 1145 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[1]->header.opcode);
992 EXPECT_TRUE(frames_passed[1]->header.final); 1146 EXPECT_TRUE(frames_passed[1]->header.final);
993 EXPECT_TRUE(frames_passed[1]->header.reserved1); 1147 EXPECT_TRUE(frames_passed[1]->header.reserved1);
994 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7), 1148 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
995 ToString(frames_passed[1])); 1149 ToString(frames_passed[1]));
996 } 1150 }
997 1151
1152 // In order to check the stream works correctly for multiple
1153 // "PossiblyCompressedMessage"s, we test various messages at one test case.
1154 TEST_F(WebSocketDeflateStreamWithDoNotTakeOverContextTest,
1155 WritePossiblyCompressMessages) {
1156 ScopedVector<WebSocketFrame> frames;
1157 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "He");
1158 AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "llo");
1159 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "AAAAAAAAAA");
1160 AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "AA");
1161 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "XX");
1162 AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "YY");
1163 predictor_->AddFramesToBeInput(frames);
1164 WriteFramesStub stub(predictor_, OK);
1165 CompletionCallback callback;
1166 predictor_->set_result(WebSocketDeflatePredictor::TRY_DEFLATE);
1167
1168 {
1169 InSequence s;
1170 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
1171 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1172 }
1173 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
1174 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
1175 ASSERT_EQ(5u, frames_passed.size());
1176
1177 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1178 EXPECT_FALSE(frames_passed[0]->header.final);
1179 EXPECT_FALSE(frames_passed[0]->header.reserved1);
1180 EXPECT_EQ("He", ToString(frames_passed[0]));
1181 EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
1182 frames_passed[1]->header.opcode);
1183 EXPECT_TRUE(frames_passed[1]->header.final);
1184 EXPECT_FALSE(frames_passed[1]->header.reserved1);
1185 EXPECT_EQ("llo", ToString(frames_passed[1]));
1186
1187 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[2]->header.opcode);
1188 EXPECT_TRUE(frames_passed[2]->header.final);
1189 EXPECT_TRUE(frames_passed[2]->header.reserved1);
1190 EXPECT_EQ(std::string("\x72\x74\x44\x00\x00\x00", 6),
1191 ToString(frames_passed[2]));
1192
1193 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[3]->header.opcode);
1194 EXPECT_FALSE(frames_passed[3]->header.final);
1195 EXPECT_FALSE(frames_passed[3]->header.reserved1);
1196 EXPECT_EQ("XX", ToString(frames_passed[3]));
1197 EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
1198 frames_passed[4]->header.opcode);
1199 EXPECT_TRUE(frames_passed[4]->header.final);
1200 EXPECT_FALSE(frames_passed[4]->header.reserved1);
1201 EXPECT_EQ("YY", ToString(frames_passed[4]));
1202 }
1203
998 } // namespace 1204 } // namespace
999 1205
1000 } // namespace net 1206 } // namespace net
OLDNEW
« no previous file with comments | « net/websockets/websocket_deflate_stream.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698