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 #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 Loading... | |
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 Loading... | |
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 DCHECK(frames_to_be_input_.empty()); | |
116 DCHECK(frames_written_.empty()); | |
117 } | |
118 | |
119 // WebSocketDeflatePredictor functions. | |
120 virtual Result Predict(const ScopedVector<WebSocketFrame>& frames, | |
121 size_t frame_index) OVERRIDE { | |
122 return result_; | |
123 } | |
124 virtual void RecordInputDataFrame(const WebSocketFrame* frame) OVERRIDE { | |
125 DCHECK(WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode)); | |
126 DCHECK(!frame->header.reserved1); | |
127 DCHECK(!frames_to_be_input_.empty()); | |
128 DCHECK_EQ(frame, frames_to_be_input_.front()); | |
129 frames_to_be_input_.pop_front(); | |
130 } | |
tyoshino (SeeGerritForStatus)
2013/10/30 06:15:04
can you try not to use check but ADD_FAILURE() etc
yhirano
2013/10/30 09:32:17
Done.
| |
131 virtual void RecordWrittenDataFrame(const WebSocketFrame* frame) OVERRIDE { | |
132 DCHECK(WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode)); | |
133 frames_written_.push_back(frame); | |
134 } | |
135 | |
136 // Sets |result_| for the |Predict| return value. | |
137 void set_result(Result result) { result_ = result; } | |
138 | |
139 // Adds |frame| as an expectation of future |RecordInputDataFrame| call. | |
140 void AddFrameToBeInput(const WebSocketFrame* frame) { | |
141 if (!WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode)) | |
142 return; | |
143 frames_to_be_input_.push_back(frame); | |
144 } | |
145 // Verifies that |frame| is recorded in order. | |
146 void VerifySentFrame(const WebSocketFrame* frame) { | |
147 if (!WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode)) | |
148 return; | |
149 DCHECK(!frames_written_.empty()); | |
150 DCHECK_EQ(frame, frames_written_.front()); | |
151 frames_written_.pop_front(); | |
tyoshino (SeeGerritForStatus)
2013/10/30 06:15:04
ditto
yhirano
2013/10/30 09:32:17
Done.
| |
152 } | |
153 void AddFramesToBeInput(const ScopedVector<WebSocketFrame>& frames) { | |
154 for (size_t i = 0; i < frames.size(); ++i) | |
155 AddFrameToBeInput(frames[i]); | |
156 } | |
157 void VerifySentFrames(const ScopedVector<WebSocketFrame>& frames) { | |
158 for (size_t i = 0; i < frames.size(); ++i) | |
159 VerifySentFrame(frames[i]); | |
160 } | |
161 // Call this method in order to disable checks in the destructor when | |
162 // WriteFrames fails. | |
163 void Clear() { | |
164 frames_to_be_input_.clear(); | |
165 frames_written_.clear(); | |
166 } | |
167 | |
168 private: | |
169 Result result_; | |
170 // Data frames which will be recorded by |RecordInputFrames|. | |
171 // Pushed by |AddFrameToBeInput| and popped and verified by | |
172 // |RecordInputFrames|. | |
173 std::deque<const WebSocketFrame*> frames_to_be_input_; | |
174 // Data frames recorded by |RecordWrittenFrames|. | |
175 // Pushed by |RecordWrittenFrames| and popped and verified by | |
176 // |VerifySentFrame|. | |
177 std::deque<const WebSocketFrame*> frames_written_; | |
178 | |
179 DISALLOW_COPY_AND_ASSIGN(WebSocketDeflatePredictorMock); | |
180 }; | |
181 | |
104 class WebSocketDeflateStreamTest : public ::testing::Test { | 182 class WebSocketDeflateStreamTest : public ::testing::Test { |
105 public: | 183 public: |
106 WebSocketDeflateStreamTest() | 184 WebSocketDeflateStreamTest() |
107 : mock_stream_(NULL) { | 185 : mock_stream_(NULL) { |
108 mock_stream_ = new testing::StrictMock<MockWebSocketStream>; | 186 mock_stream_ = new testing::StrictMock<MockWebSocketStream>; |
187 predictor_ = new WebSocketDeflatePredictorMock; | |
109 deflate_stream_.reset(new WebSocketDeflateStream( | 188 deflate_stream_.reset(new WebSocketDeflateStream( |
110 scoped_ptr<WebSocketStream>(mock_stream_), | 189 scoped_ptr<WebSocketStream>(mock_stream_), |
111 WebSocketDeflater::TAKE_OVER_CONTEXT)); | 190 WebSocketDeflater::TAKE_OVER_CONTEXT, |
191 scoped_ptr<WebSocketDeflatePredictor>(predictor_))); | |
112 } | 192 } |
113 virtual ~WebSocketDeflateStreamTest() {} | 193 virtual ~WebSocketDeflateStreamTest() {} |
114 | 194 |
115 protected: | 195 protected: |
116 scoped_ptr<WebSocketDeflateStream> deflate_stream_; | 196 scoped_ptr<WebSocketDeflateStream> deflate_stream_; |
117 // |mock_stream_| will be deleted when |deflate_stream_| is destroyed. | 197 // Owned by |deflate_stream_|. |
118 MockWebSocketStream* mock_stream_; | 198 MockWebSocketStream* mock_stream_; |
199 // Owned by |deflate_stream_|. | |
200 WebSocketDeflatePredictorMock* predictor_; | |
119 }; | 201 }; |
120 | 202 |
121 // Since WebSocketDeflater with DoNotTakeOverContext is well tested at | 203 // Since WebSocketDeflater with DoNotTakeOverContext is well tested at |
122 // websocket_deflater_test.cc, we have only one test for this configuration | 204 // websocket_deflater_test.cc, we have only a few tests for this configuration |
123 // here. | 205 // here. |
124 class WebSocketDeflateStreamWithDoNotTakeOverContextTest | 206 class WebSocketDeflateStreamWithDoNotTakeOverContextTest |
125 : public ::testing::Test { | 207 : public ::testing::Test { |
126 public: | 208 public: |
127 WebSocketDeflateStreamWithDoNotTakeOverContextTest() | 209 WebSocketDeflateStreamWithDoNotTakeOverContextTest() |
128 : mock_stream_(NULL) { | 210 : mock_stream_(NULL) { |
129 mock_stream_ = new testing::StrictMock<MockWebSocketStream>; | 211 mock_stream_ = new testing::StrictMock<MockWebSocketStream>; |
212 predictor_ = new WebSocketDeflatePredictorMock; | |
130 deflate_stream_.reset(new WebSocketDeflateStream( | 213 deflate_stream_.reset(new WebSocketDeflateStream( |
131 scoped_ptr<WebSocketStream>(mock_stream_), | 214 scoped_ptr<WebSocketStream>(mock_stream_), |
132 WebSocketDeflater::DO_NOT_TAKE_OVER_CONTEXT)); | 215 WebSocketDeflater::DO_NOT_TAKE_OVER_CONTEXT, |
216 scoped_ptr<WebSocketDeflatePredictor>(predictor_))); | |
133 } | 217 } |
134 virtual ~WebSocketDeflateStreamWithDoNotTakeOverContextTest() {} | 218 virtual ~WebSocketDeflateStreamWithDoNotTakeOverContextTest() {} |
135 | 219 |
136 protected: | 220 protected: |
137 scoped_ptr<WebSocketDeflateStream> deflate_stream_; | 221 scoped_ptr<WebSocketDeflateStream> deflate_stream_; |
138 // |mock_stream_| will be deleted when |deflate_stream_| is destroyed. | 222 // |mock_stream_| will be deleted when |deflate_stream_| is destroyed. |
139 MockWebSocketStream* mock_stream_; | 223 MockWebSocketStream* mock_stream_; |
224 // |predictor_| will be deleted when |deflate_stream_| is destroyed. | |
225 WebSocketDeflatePredictorMock* predictor_; | |
140 }; | 226 }; |
141 | 227 |
142 // ReadFrameStub is a stub for WebSocketStream::ReadFrames. | 228 // ReadFrameStub is a stub for WebSocketStream::ReadFrames. |
143 // It returns |result_| and |frames_to_output_| to the caller and | 229 // It returns |result_| and |frames_to_output_| to the caller and |
144 // saves parameters to |frames_passed_| and |callback_|. | 230 // saves parameters to |frames_passed_| and |callback_|. |
145 class ReadFramesStub { | 231 class ReadFramesStub { |
146 public: | 232 public: |
147 explicit ReadFramesStub(int result) : result_(result) {} | 233 explicit ReadFramesStub(int result) : result_(result) {} |
148 | 234 |
149 ReadFramesStub(int result, ScopedVector<WebSocketFrame>* frames_to_output) | 235 ReadFramesStub(int result, ScopedVector<WebSocketFrame>* frames_to_output) |
(...skipping 16 matching lines...) Expand all Loading... | |
166 return frames_passed_; | 252 return frames_passed_; |
167 } | 253 } |
168 | 254 |
169 private: | 255 private: |
170 int result_; | 256 int result_; |
171 CompletionCallback callback_; | 257 CompletionCallback callback_; |
172 ScopedVector<WebSocketFrame> frames_to_output_; | 258 ScopedVector<WebSocketFrame> frames_to_output_; |
173 ScopedVector<WebSocketFrame>* frames_passed_; | 259 ScopedVector<WebSocketFrame>* frames_passed_; |
174 }; | 260 }; |
175 | 261 |
176 // WriteFrameStub is a stub for WebSocketStream::WriteFrames. | 262 // WriteFramesStub is a stub for WebSocketStream::WriteFrames. |
177 // It returns |result_| and |frames_| to the caller and | 263 // It returns |result_| and |frames_| to the caller and |
178 // saves |callback| parameter to |callback_|. | 264 // saves |callback| parameter to |callback_|. |
179 class WriteFramesStub { | 265 class WriteFramesStub { |
180 public: | 266 public: |
181 explicit WriteFramesStub(int result) : result_(result) {} | 267 explicit WriteFramesStub(WebSocketDeflatePredictorMock* predictor, |
268 int result) | |
269 : result_(result), predictor_(predictor) {} | |
182 | 270 |
183 int Call(ScopedVector<WebSocketFrame>* frames, | 271 int Call(ScopedVector<WebSocketFrame>* frames, |
184 const CompletionCallback& callback) { | 272 const CompletionCallback& callback) { |
185 for (size_t i = 0; i < frames->size(); ++i) { | 273 frames_.insert(frames_.end(), frames->begin(), frames->end()); |
186 frames_.push_back((*frames)[i]); | |
187 } | |
188 frames->weak_clear(); | 274 frames->weak_clear(); |
189 callback_ = callback; | 275 callback_ = callback; |
276 predictor_->VerifySentFrames(frames_); | |
190 return result_; | 277 return result_; |
191 } | 278 } |
192 | 279 |
193 int result() const { return result_; } | 280 int result() const { return result_; } |
194 const CompletionCallback callback() const { return callback_; } | 281 const CompletionCallback callback() const { return callback_; } |
195 ScopedVector<WebSocketFrame>* frames() { return &frames_; } | 282 ScopedVector<WebSocketFrame>* frames() { return &frames_; } |
196 | 283 |
197 private: | 284 private: |
198 int result_; | 285 int result_; |
199 CompletionCallback callback_; | 286 CompletionCallback callback_; |
200 ScopedVector<WebSocketFrame> frames_; | 287 ScopedVector<WebSocketFrame> frames_; |
288 WebSocketDeflatePredictorMock* predictor_; | |
201 }; | 289 }; |
202 | 290 |
203 TEST_F(WebSocketDeflateStreamTest, ReadFailedImmediately) { | 291 TEST_F(WebSocketDeflateStreamTest, ReadFailedImmediately) { |
204 ScopedVector<WebSocketFrame> frames; | 292 ScopedVector<WebSocketFrame> frames; |
205 CompletionCallback callback; | 293 CompletionCallback callback; |
206 { | 294 { |
207 InSequence s; | 295 InSequence s; |
208 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _)) | 296 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _)) |
209 .WillOnce(Return(ERR_FAILED)); | 297 .WillOnce(Return(ERR_FAILED)); |
210 } | 298 } |
(...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
784 TEST_F(WebSocketDeflateStreamTest, WriteFailedImmediately) { | 872 TEST_F(WebSocketDeflateStreamTest, WriteFailedImmediately) { |
785 ScopedVector<WebSocketFrame> frames; | 873 ScopedVector<WebSocketFrame> frames; |
786 CompletionCallback callback; | 874 CompletionCallback callback; |
787 { | 875 { |
788 InSequence s; | 876 InSequence s; |
789 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) | 877 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) |
790 .WillOnce(Return(ERR_FAILED)); | 878 .WillOnce(Return(ERR_FAILED)); |
791 } | 879 } |
792 | 880 |
793 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "hello"); | 881 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "hello"); |
882 predictor_->AddFramesToBeInput(frames); | |
794 EXPECT_EQ(ERR_FAILED, deflate_stream_->WriteFrames(&frames, callback)); | 883 EXPECT_EQ(ERR_FAILED, deflate_stream_->WriteFrames(&frames, callback)); |
884 predictor_->Clear(); | |
795 } | 885 } |
796 | 886 |
797 TEST_F(WebSocketDeflateStreamTest, WriteFrameImmediately) { | 887 TEST_F(WebSocketDeflateStreamTest, WriteFrameImmediately) { |
798 ScopedVector<WebSocketFrame> frames; | 888 ScopedVector<WebSocketFrame> frames; |
799 CompletionCallback callback; | 889 CompletionCallback callback; |
800 WriteFramesStub stub(OK); | 890 WriteFramesStub stub(predictor_, OK); |
801 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello"); | 891 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello"); |
892 predictor_->AddFramesToBeInput(frames); | |
802 { | 893 { |
803 InSequence s; | 894 InSequence s; |
804 EXPECT_CALL(*mock_stream_, WriteFrames(_, _)) | 895 EXPECT_CALL(*mock_stream_, WriteFrames(_, _)) |
805 .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); | 896 .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); |
806 } | 897 } |
807 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); | 898 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); |
808 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); | 899 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); |
809 ASSERT_EQ(1u, frames_passed.size()); | 900 ASSERT_EQ(1u, frames_passed.size()); |
810 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode); | 901 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode); |
811 EXPECT_TRUE(frames_passed[0]->header.final); | 902 EXPECT_TRUE(frames_passed[0]->header.final); |
812 EXPECT_TRUE(frames_passed[0]->header.reserved1); | 903 EXPECT_TRUE(frames_passed[0]->header.reserved1); |
813 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7), | 904 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7), |
814 ToString(frames_passed[0])); | 905 ToString(frames_passed[0])); |
815 } | 906 } |
816 | 907 |
817 TEST_F(WebSocketDeflateStreamTest, WriteFrameAsync) { | 908 TEST_F(WebSocketDeflateStreamTest, WriteFrameAsync) { |
818 WriteFramesStub stub(ERR_IO_PENDING); | 909 WriteFramesStub stub(predictor_, ERR_IO_PENDING); |
819 MockCallback mock_callback, checkpoint; | 910 MockCallback mock_callback, checkpoint; |
820 CompletionCallback callback = | 911 CompletionCallback callback = |
821 base::Bind(&MockCallback::Call, base::Unretained(&mock_callback)); | 912 base::Bind(&MockCallback::Call, base::Unretained(&mock_callback)); |
822 ScopedVector<WebSocketFrame> frames; | 913 ScopedVector<WebSocketFrame> frames; |
823 { | 914 { |
824 InSequence s; | 915 InSequence s; |
825 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) | 916 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) |
826 .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); | 917 .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); |
827 EXPECT_CALL(checkpoint, Call(0)); | 918 EXPECT_CALL(checkpoint, Call(0)); |
828 EXPECT_CALL(mock_callback, Call(OK)); | 919 EXPECT_CALL(mock_callback, Call(OK)); |
829 } | 920 } |
830 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello"); | 921 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello"); |
922 predictor_->AddFramesToBeInput(frames); | |
831 ASSERT_EQ(ERR_IO_PENDING, deflate_stream_->WriteFrames(&frames, callback)); | 923 ASSERT_EQ(ERR_IO_PENDING, deflate_stream_->WriteFrames(&frames, callback)); |
832 | 924 |
833 checkpoint.Call(0); | 925 checkpoint.Call(0); |
834 stub.callback().Run(OK); | 926 stub.callback().Run(OK); |
835 | 927 |
836 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); | 928 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); |
837 ASSERT_EQ(1u, frames_passed.size()); | 929 ASSERT_EQ(1u, frames_passed.size()); |
838 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode); | 930 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode); |
839 EXPECT_TRUE(frames_passed[0]->header.final); | 931 EXPECT_TRUE(frames_passed[0]->header.final); |
840 EXPECT_TRUE(frames_passed[0]->header.reserved1); | 932 EXPECT_TRUE(frames_passed[0]->header.reserved1); |
841 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7), | 933 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7), |
842 ToString(frames_passed[0])); | 934 ToString(frames_passed[0])); |
843 } | 935 } |
844 | 936 |
845 TEST_F(WebSocketDeflateStreamTest, WriteControlFrameBetweenDataFrames) { | 937 TEST_F(WebSocketDeflateStreamTest, WriteControlFrameBetweenDataFrames) { |
846 ScopedVector<WebSocketFrame> frames; | 938 ScopedVector<WebSocketFrame> frames; |
847 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "Hel"); | 939 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "Hel"); |
848 AppendTo(&frames, WebSocketFrameHeader::kOpCodePing, kFinal); | 940 AppendTo(&frames, WebSocketFrameHeader::kOpCodePing, kFinal); |
849 AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "lo"); | 941 AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "lo"); |
850 WriteFramesStub stub(OK); | 942 predictor_->AddFramesToBeInput(frames); |
943 WriteFramesStub stub(predictor_, OK); | |
851 CompletionCallback callback; | 944 CompletionCallback callback; |
852 | 945 |
853 { | 946 { |
854 InSequence s; | 947 InSequence s; |
855 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) | 948 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) |
856 .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); | 949 .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); |
857 } | 950 } |
858 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); | 951 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); |
859 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); | 952 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); |
860 ASSERT_EQ(2u, frames_passed.size()); | 953 ASSERT_EQ(2u, frames_passed.size()); |
861 EXPECT_EQ(WebSocketFrameHeader::kOpCodePing, frames_passed[0]->header.opcode); | 954 EXPECT_EQ(WebSocketFrameHeader::kOpCodePing, frames_passed[0]->header.opcode); |
862 EXPECT_TRUE(frames_passed[0]->header.final); | 955 EXPECT_TRUE(frames_passed[0]->header.final); |
863 EXPECT_FALSE(frames_passed[0]->header.reserved1); | 956 EXPECT_FALSE(frames_passed[0]->header.reserved1); |
864 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[1]->header.opcode); | 957 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[1]->header.opcode); |
865 EXPECT_TRUE(frames_passed[1]->header.final); | 958 EXPECT_TRUE(frames_passed[1]->header.final); |
866 EXPECT_TRUE(frames_passed[1]->header.reserved1); | 959 EXPECT_TRUE(frames_passed[1]->header.reserved1); |
867 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), |
868 ToString(frames_passed[1])); | 961 ToString(frames_passed[1])); |
869 } | 962 } |
870 | 963 |
871 TEST_F(WebSocketDeflateStreamTest, WriteEmptyMessage) { | 964 TEST_F(WebSocketDeflateStreamTest, WriteEmptyMessage) { |
872 ScopedVector<WebSocketFrame> frames; | 965 ScopedVector<WebSocketFrame> frames; |
873 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal); | 966 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal); |
874 WriteFramesStub stub(OK); | 967 predictor_->AddFramesToBeInput(frames); |
968 WriteFramesStub stub(predictor_, OK); | |
875 CompletionCallback callback; | 969 CompletionCallback callback; |
876 | 970 |
877 { | 971 { |
878 InSequence s; | 972 InSequence s; |
879 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) | 973 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) |
880 .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); | 974 .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); |
881 } | 975 } |
882 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); | 976 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); |
883 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); | 977 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); |
884 ASSERT_EQ(1u, frames_passed.size()); | 978 ASSERT_EQ(1u, frames_passed.size()); |
885 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode); | 979 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode); |
886 EXPECT_TRUE(frames_passed[0]->header.final); | 980 EXPECT_TRUE(frames_passed[0]->header.final); |
887 EXPECT_TRUE(frames_passed[0]->header.reserved1); | 981 EXPECT_TRUE(frames_passed[0]->header.reserved1); |
888 EXPECT_EQ(std::string("\x02\x00", 2), ToString(frames_passed[0])); | 982 EXPECT_EQ(std::string("\x02\x00", 2), ToString(frames_passed[0])); |
889 } | 983 } |
890 | 984 |
985 TEST_F(WebSocketDeflateStreamTest, WriteUncompressedMessage) { | |
986 ScopedVector<WebSocketFrame> frames; | |
987 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "AAAA"); | |
988 AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "AAA"); | |
989 predictor_->AddFramesToBeInput(frames); | |
990 WriteFramesStub stub(predictor_, OK); | |
991 CompletionCallback callback; | |
992 | |
993 predictor_->set_result(WebSocketDeflatePredictor::DO_NOT_DEFLATE); | |
994 | |
995 { | |
996 InSequence s; | |
997 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) | |
998 .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); | |
999 } | |
1000 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); | |
1001 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); | |
1002 ASSERT_EQ(2u, frames_passed.size()); | |
1003 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode); | |
1004 EXPECT_FALSE(frames_passed[0]->header.final); | |
1005 EXPECT_FALSE(frames_passed[0]->header.reserved1); | |
1006 EXPECT_EQ("AAAA", ToString(frames_passed[0])); | |
1007 EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation, | |
1008 frames_passed[1]->header.opcode); | |
1009 EXPECT_TRUE(frames_passed[1]->header.final); | |
1010 EXPECT_FALSE(frames_passed[1]->header.reserved1); | |
1011 EXPECT_EQ("AAA", ToString(frames_passed[1])); | |
1012 } | |
1013 | |
891 TEST_F(WebSocketDeflateStreamTest, LargeDeflatedFramesShouldBeSplit) { | 1014 TEST_F(WebSocketDeflateStreamTest, LargeDeflatedFramesShouldBeSplit) { |
892 WebSocketDeflater deflater(WebSocketDeflater::TAKE_OVER_CONTEXT); | 1015 WebSocketDeflater deflater(WebSocketDeflater::TAKE_OVER_CONTEXT); |
893 LinearCongruentialGenerator lcg(133); | 1016 LinearCongruentialGenerator lcg(133); |
894 WriteFramesStub stub(OK); | 1017 WriteFramesStub stub(predictor_, OK); |
895 CompletionCallback callback; | 1018 CompletionCallback callback; |
896 const size_t size = 1024; | 1019 const size_t size = 1024; |
897 | 1020 |
898 { | 1021 { |
899 InSequence s; | 1022 InSequence s; |
900 EXPECT_CALL(*mock_stream_, WriteFrames(_, _)) | 1023 EXPECT_CALL(*mock_stream_, WriteFrames(_, _)) |
901 .WillRepeatedly(Invoke(&stub, &WriteFramesStub::Call)); | 1024 .WillRepeatedly(Invoke(&stub, &WriteFramesStub::Call)); |
902 } | 1025 } |
903 ScopedVector<WebSocketFrame> total_compressed_frames; | 1026 ScopedVector<WebSocketFrame> total_compressed_frames; |
904 | 1027 |
905 deflater.Initialize(kWindowBits); | 1028 deflater.Initialize(kWindowBits); |
906 while (true) { | 1029 while (true) { |
907 bool is_final = (total_compressed_frames.size() >= 2); | 1030 bool is_final = (total_compressed_frames.size() >= 2); |
908 ScopedVector<WebSocketFrame> frames; | 1031 ScopedVector<WebSocketFrame> frames; |
909 std::string data; | 1032 std::string data; |
910 for (size_t i = 0; i < size; ++i) | 1033 for (size_t i = 0; i < size; ++i) |
911 data += static_cast<char>(lcg.Generate()); | 1034 data += static_cast<char>(lcg.Generate()); |
912 deflater.AddBytes(data.data(), data.size()); | 1035 deflater.AddBytes(data.data(), data.size()); |
913 FrameFlag flag = is_final ? kFinal : kNoFlag; | 1036 FrameFlag flag = is_final ? kFinal : kNoFlag; |
914 AppendTo(&frames, WebSocketFrameHeader::kOpCodeBinary, flag, data); | 1037 AppendTo(&frames, WebSocketFrameHeader::kOpCodeBinary, flag, data); |
1038 predictor_->AddFramesToBeInput(frames); | |
915 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); | 1039 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); |
916 for (size_t i = 0; i < stub.frames()->size(); ++i) | 1040 total_compressed_frames.insert(total_compressed_frames.end(), |
917 total_compressed_frames.push_back((*stub.frames())[i]); | 1041 stub.frames()->begin(), |
1042 stub.frames()->end()); | |
918 stub.frames()->weak_clear(); | 1043 stub.frames()->weak_clear(); |
919 if (is_final) | 1044 if (is_final) |
920 break; | 1045 break; |
921 } | 1046 } |
922 deflater.Finish(); | 1047 deflater.Finish(); |
923 std::string total_deflated; | 1048 std::string total_deflated; |
924 for (size_t i = 0; i < total_compressed_frames.size(); ++i) { | 1049 for (size_t i = 0; i < total_compressed_frames.size(); ++i) { |
925 WebSocketFrame* frame = total_compressed_frames[i]; | 1050 WebSocketFrame* frame = total_compressed_frames[i]; |
926 const WebSocketFrameHeader& header = frame->header; | 1051 const WebSocketFrameHeader& header = frame->header; |
927 if (i > 0) { | 1052 if (i > 0) { |
(...skipping 10 matching lines...) Expand all Loading... | |
938 total_deflated += ToString(frame); | 1063 total_deflated += ToString(frame); |
939 } | 1064 } |
940 EXPECT_EQ(total_deflated, | 1065 EXPECT_EQ(total_deflated, |
941 ToString(deflater.GetOutput(deflater.CurrentOutputSize()))); | 1066 ToString(deflater.GetOutput(deflater.CurrentOutputSize()))); |
942 } | 1067 } |
943 | 1068 |
944 TEST_F(WebSocketDeflateStreamTest, WriteMultipleMessages) { | 1069 TEST_F(WebSocketDeflateStreamTest, WriteMultipleMessages) { |
945 ScopedVector<WebSocketFrame> frames; | 1070 ScopedVector<WebSocketFrame> frames; |
946 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello"); | 1071 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello"); |
947 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello"); | 1072 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello"); |
948 WriteFramesStub stub(OK); | 1073 predictor_->AddFramesToBeInput(frames); |
1074 WriteFramesStub stub(predictor_, OK); | |
949 CompletionCallback callback; | 1075 CompletionCallback callback; |
950 | 1076 |
951 { | 1077 { |
952 InSequence s; | 1078 InSequence s; |
953 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) | 1079 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) |
954 .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); | 1080 .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); |
955 } | 1081 } |
956 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); | 1082 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); |
957 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); | 1083 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); |
958 ASSERT_EQ(2u, frames_passed.size()); | 1084 ASSERT_EQ(2u, frames_passed.size()); |
959 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode); | 1085 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode); |
960 EXPECT_TRUE(frames_passed[0]->header.final); | 1086 EXPECT_TRUE(frames_passed[0]->header.final); |
961 EXPECT_TRUE(frames_passed[0]->header.reserved1); | 1087 EXPECT_TRUE(frames_passed[0]->header.reserved1); |
962 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7), | 1088 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7), |
963 ToString(frames_passed[0])); | 1089 ToString(frames_passed[0])); |
964 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[1]->header.opcode); | 1090 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[1]->header.opcode); |
965 EXPECT_TRUE(frames_passed[1]->header.final); | 1091 EXPECT_TRUE(frames_passed[1]->header.final); |
966 EXPECT_TRUE(frames_passed[1]->header.reserved1); | 1092 EXPECT_TRUE(frames_passed[1]->header.reserved1); |
967 EXPECT_EQ(std::string("\xf2\x00\x11\x00\x00", 5), ToString(frames_passed[1])); | 1093 EXPECT_EQ(std::string("\xf2\x00\x11\x00\x00", 5), ToString(frames_passed[1])); |
968 } | 1094 } |
969 | 1095 |
970 TEST_F(WebSocketDeflateStreamWithDoNotTakeOverContextTest, | 1096 TEST_F(WebSocketDeflateStreamWithDoNotTakeOverContextTest, |
971 WriteMultipleMessages) { | 1097 WriteMultipleMessages) { |
972 ScopedVector<WebSocketFrame> frames; | 1098 ScopedVector<WebSocketFrame> frames; |
973 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello"); | 1099 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello"); |
974 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello"); | 1100 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello"); |
975 WriteFramesStub stub(OK); | 1101 predictor_->AddFramesToBeInput(frames); |
1102 WriteFramesStub stub(predictor_, OK); | |
976 CompletionCallback callback; | 1103 CompletionCallback callback; |
977 | 1104 |
978 { | 1105 { |
979 InSequence s; | 1106 InSequence s; |
980 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) | 1107 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) |
981 .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); | 1108 .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); |
982 } | 1109 } |
983 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); | 1110 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); |
984 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); | 1111 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); |
985 ASSERT_EQ(2u, frames_passed.size()); | 1112 ASSERT_EQ(2u, frames_passed.size()); |
986 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode); | 1113 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode); |
987 EXPECT_TRUE(frames_passed[0]->header.final); | 1114 EXPECT_TRUE(frames_passed[0]->header.final); |
988 EXPECT_TRUE(frames_passed[0]->header.reserved1); | 1115 EXPECT_TRUE(frames_passed[0]->header.reserved1); |
989 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7), | 1116 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7), |
990 ToString(frames_passed[0])); | 1117 ToString(frames_passed[0])); |
991 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[1]->header.opcode); | 1118 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[1]->header.opcode); |
992 EXPECT_TRUE(frames_passed[1]->header.final); | 1119 EXPECT_TRUE(frames_passed[1]->header.final); |
993 EXPECT_TRUE(frames_passed[1]->header.reserved1); | 1120 EXPECT_TRUE(frames_passed[1]->header.reserved1); |
994 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7), | 1121 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7), |
995 ToString(frames_passed[1])); | 1122 ToString(frames_passed[1])); |
996 } | 1123 } |
997 | 1124 |
1125 // In order to check the stream works correctly for multiple | |
1126 // "PossiblyCompressedMessage"s, we test various messages at one test case. | |
1127 TEST_F(WebSocketDeflateStreamWithDoNotTakeOverContextTest, | |
1128 WritePossiblyCompressMessages) { | |
1129 ScopedVector<WebSocketFrame> frames; | |
1130 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "He"); | |
1131 AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "llo"); | |
1132 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "AAAAAAAAAA"); | |
1133 AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "AA"); | |
1134 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "XX"); | |
1135 AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "YY"); | |
1136 predictor_->AddFramesToBeInput(frames); | |
1137 WriteFramesStub stub(predictor_, OK); | |
1138 CompletionCallback callback; | |
1139 predictor_->set_result(WebSocketDeflatePredictor::TRY_DEFLATE); | |
1140 | |
1141 { | |
1142 InSequence s; | |
1143 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)) | |
1144 .WillOnce(Invoke(&stub, &WriteFramesStub::Call)); | |
1145 } | |
1146 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback)); | |
1147 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames(); | |
1148 ASSERT_EQ(5u, frames_passed.size()); | |
1149 | |
1150 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode); | |
1151 EXPECT_FALSE(frames_passed[0]->header.final); | |
1152 EXPECT_FALSE(frames_passed[0]->header.reserved1); | |
1153 EXPECT_EQ("He", ToString(frames_passed[0])); | |
1154 EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation, | |
1155 frames_passed[1]->header.opcode); | |
1156 EXPECT_TRUE(frames_passed[1]->header.final); | |
1157 EXPECT_FALSE(frames_passed[1]->header.reserved1); | |
1158 EXPECT_EQ("llo", ToString(frames_passed[1])); | |
1159 | |
1160 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[2]->header.opcode); | |
1161 EXPECT_TRUE(frames_passed[2]->header.final); | |
1162 EXPECT_TRUE(frames_passed[2]->header.reserved1); | |
1163 EXPECT_EQ(std::string("\x72\x74\x44\x00\x00\x00", 6), | |
1164 ToString(frames_passed[2])); | |
1165 | |
1166 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[3]->header.opcode); | |
1167 EXPECT_FALSE(frames_passed[3]->header.final); | |
1168 EXPECT_FALSE(frames_passed[3]->header.reserved1); | |
1169 EXPECT_EQ("XX", ToString(frames_passed[3])); | |
1170 EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation, | |
1171 frames_passed[4]->header.opcode); | |
1172 EXPECT_TRUE(frames_passed[4]->header.final); | |
1173 EXPECT_FALSE(frames_passed[4]->header.reserved1); | |
1174 EXPECT_EQ("YY", ToString(frames_passed[4])); | |
1175 } | |
1176 | |
998 } // namespace | 1177 } // namespace |
999 | 1178 |
1000 } // namespace net | 1179 } // namespace net |
OLD | NEW |