Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / net / websockets / websocket_deflate_stream_test.cc
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/websockets/websocket_deflate_stream.h"
6
7 #include <stdint.h>
8 #include <deque>
9 #include <string>
10
11 #include "base/basictypes.h"
12 #include "base/bind.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/memory/scoped_vector.h"
16 #include "net/base/completion_callback.h"
17 #include "net/base/io_buffer.h"
18 #include "net/base/net_errors.h"
19 #include "net/websockets/websocket_deflate_predictor.h"
20 #include "net/websockets/websocket_deflater.h"
21 #include "net/websockets/websocket_frame.h"
22 #include "net/websockets/websocket_inflater.h"
23 #include "net/websockets/websocket_stream.h"
24 #include "net/websockets/websocket_test_util.h"
25 #include "testing/gmock/include/gmock/gmock.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27
28 namespace net {
29 namespace {
30
31 typedef ::testing::MockFunction<void(int)> MockCallback;  // NOLINT
32 using ::testing::_;
33 using ::testing::InSequence;
34 using ::testing::Invoke;
35 using ::testing::Return;
36
37 typedef uint32_t FrameFlag;
38 const FrameFlag kNoFlag = 0;
39 const FrameFlag kFinal = 1;
40 const FrameFlag kReserved1 = 2;
41 // We don't define values for other flags because we don't need them.
42
43 // The value must equal to the value of the corresponding
44 // constant in websocket_deflate_stream.cc
45 const size_t kChunkSize = 4 * 1024;
46 const int kWindowBits = 15;
47
48 scoped_refptr<IOBuffer> ToIOBuffer(const std::string& s) {
49   scoped_refptr<IOBuffer> buffer = new IOBuffer(s.size());
50   memcpy(buffer->data(), s.data(), s.size());
51   return buffer;
52 }
53
54 std::string ToString(IOBufferWithSize* buffer) {
55   return std::string(buffer->data(), buffer->size());
56 }
57
58 std::string ToString(const scoped_refptr<IOBufferWithSize>& buffer) {
59   return ToString(buffer.get());
60 }
61
62 std::string ToString(IOBuffer* buffer, size_t size) {
63   return std::string(buffer->data(), size);
64 }
65
66 std::string ToString(const scoped_refptr<IOBuffer>& buffer, size_t size) {
67   return ToString(buffer.get(), size);
68 }
69
70 std::string ToString(const WebSocketFrame* frame) {
71   return frame->data ? ToString(frame->data, frame->header.payload_length) : "";
72 }
73
74 void AppendTo(ScopedVector<WebSocketFrame>* frames,
75               WebSocketFrameHeader::OpCode opcode,
76               FrameFlag flag,
77               const std::string& data) {
78   scoped_ptr<WebSocketFrame> frame(new WebSocketFrame(opcode));
79   frame->header.final = (flag & kFinal);
80   frame->header.reserved1 = (flag & kReserved1);
81   frame->data = ToIOBuffer(data);
82   frame->header.payload_length = data.size();
83   frames->push_back(frame.release());
84 }
85
86 void AppendTo(ScopedVector<WebSocketFrame>* frames,
87               WebSocketFrameHeader::OpCode opcode,
88               FrameFlag flag) {
89   scoped_ptr<WebSocketFrame> frame(new WebSocketFrame(opcode));
90   frame->header.final = (flag & kFinal);
91   frame->header.reserved1 = (flag & kReserved1);
92   frames->push_back(frame.release());
93 }
94
95 class MockWebSocketStream : public WebSocketStream {
96  public:
97   MOCK_METHOD2(ReadFrames, int(ScopedVector<WebSocketFrame>*,
98                                const CompletionCallback&));
99   MOCK_METHOD2(WriteFrames, int(ScopedVector<WebSocketFrame>*,
100                                 const CompletionCallback&));
101   MOCK_METHOD0(Close, void());
102   MOCK_CONST_METHOD0(GetSubProtocol, std::string());
103   MOCK_CONST_METHOD0(GetExtensions, std::string());
104 };
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
209 class WebSocketDeflateStreamTest : public ::testing::Test {
210  public:
211   WebSocketDeflateStreamTest()
212       : mock_stream_(NULL),
213         predictor_(NULL) {}
214   virtual ~WebSocketDeflateStreamTest() {}
215
216   virtual void SetUp() {
217     Initialize(WebSocketDeflater::TAKE_OVER_CONTEXT, kWindowBits);
218   }
219
220  protected:
221   // Initialize deflate_stream_ with the given parameters.
222   void Initialize(WebSocketDeflater::ContextTakeOverMode mode,
223                   int window_bits) {
224     mock_stream_ = new testing::StrictMock<MockWebSocketStream>;
225     predictor_ = new WebSocketDeflatePredictorMock;
226     deflate_stream_.reset(new WebSocketDeflateStream(
227         scoped_ptr<WebSocketStream>(mock_stream_),
228         mode,
229         window_bits,
230         scoped_ptr<WebSocketDeflatePredictor>(predictor_)));
231   }
232
233   scoped_ptr<WebSocketDeflateStream> deflate_stream_;
234   // Owned by |deflate_stream_|.
235   MockWebSocketStream* mock_stream_;
236   // Owned by |deflate_stream_|.
237   WebSocketDeflatePredictorMock* predictor_;
238 };
239
240 // Since WebSocketDeflater with DoNotTakeOverContext is well tested at
241 // websocket_deflater_test.cc, we have only a few tests for this configuration
242 // here.
243 class WebSocketDeflateStreamWithDoNotTakeOverContextTest
244     : public WebSocketDeflateStreamTest {
245  public:
246   WebSocketDeflateStreamWithDoNotTakeOverContextTest() {}
247   virtual ~WebSocketDeflateStreamWithDoNotTakeOverContextTest() {}
248
249   virtual void SetUp() {
250     Initialize(WebSocketDeflater::DO_NOT_TAKE_OVER_CONTEXT, kWindowBits);
251   }
252 };
253
254 class WebSocketDeflateStreamWithClientWindowBitsTest
255     : public WebSocketDeflateStreamTest {
256  public:
257   WebSocketDeflateStreamWithClientWindowBitsTest() {}
258   virtual ~WebSocketDeflateStreamWithClientWindowBitsTest() {}
259
260   // Overridden to postpone the call to Initialize().
261   virtual void SetUp() {}
262
263   // This needs to be called explicitly from the tests.
264   void SetUpWithWindowBits(int window_bits) {
265     Initialize(WebSocketDeflater::TAKE_OVER_CONTEXT, window_bits);
266   }
267
268   // Add a frame which will be compressed to a smaller size if the window
269   // size is large enough.
270   void AddCompressibleFrameString() {
271     const std::string word = "Chromium";
272     const std::string payload = word + std::string(256, 'a') + word;
273     AppendTo(&frames_, WebSocketFrameHeader::kOpCodeText, kFinal, payload);
274     predictor_->AddFramesToBeInput(frames_);
275   }
276
277  protected:
278   ScopedVector<WebSocketFrame> frames_;
279 };
280
281 // ReadFrameStub is a stub for WebSocketStream::ReadFrames.
282 // It returns |result_| and |frames_to_output_| to the caller and
283 // saves parameters to |frames_passed_| and |callback_|.
284 class ReadFramesStub {
285  public:
286   explicit ReadFramesStub(int result) : result_(result) {}
287
288   ReadFramesStub(int result, ScopedVector<WebSocketFrame>* frames_to_output)
289       : result_(result) {
290     frames_to_output_.swap(*frames_to_output);
291   }
292
293   int Call(ScopedVector<WebSocketFrame>* frames,
294            const CompletionCallback& callback) {
295     DCHECK(frames->empty());
296     frames_passed_ = frames;
297     callback_ = callback;
298     frames->swap(frames_to_output_);
299     return result_;
300   }
301
302   int result() const { return result_; }
303   const CompletionCallback callback() const { return callback_; }
304   ScopedVector<WebSocketFrame>* frames_passed() {
305     return frames_passed_;
306   }
307
308  private:
309   int result_;
310   CompletionCallback callback_;
311   ScopedVector<WebSocketFrame> frames_to_output_;
312   ScopedVector<WebSocketFrame>* frames_passed_;
313 };
314
315 // WriteFramesStub is a stub for WebSocketStream::WriteFrames.
316 // It returns |result_| and |frames_| to the caller and
317 // saves |callback| parameter to |callback_|.
318 class WriteFramesStub {
319  public:
320   explicit WriteFramesStub(WebSocketDeflatePredictorMock* predictor,
321                            int result)
322       : result_(result), predictor_(predictor) {}
323
324   int Call(ScopedVector<WebSocketFrame>* frames,
325            const CompletionCallback& callback) {
326     frames_.insert(frames_.end(), frames->begin(), frames->end());
327     frames->weak_clear();
328     callback_ = callback;
329     predictor_->VerifySentFrames(frames_);
330     return result_;
331   }
332
333   int result() const { return result_; }
334   const CompletionCallback callback() const { return callback_; }
335   ScopedVector<WebSocketFrame>* frames() { return &frames_; }
336
337  private:
338   int result_;
339   CompletionCallback callback_;
340   ScopedVector<WebSocketFrame> frames_;
341   WebSocketDeflatePredictorMock* predictor_;
342 };
343
344 TEST_F(WebSocketDeflateStreamTest, ReadFailedImmediately) {
345   ScopedVector<WebSocketFrame> frames;
346   CompletionCallback callback;
347   {
348     InSequence s;
349     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
350         .WillOnce(Return(ERR_FAILED));
351   }
352   EXPECT_EQ(ERR_FAILED, deflate_stream_->ReadFrames(&frames, callback));
353 }
354
355 TEST_F(WebSocketDeflateStreamTest, ReadUncompressedFrameImmediately) {
356   ScopedVector<WebSocketFrame> frames_to_output;
357   AppendTo(&frames_to_output,
358            WebSocketFrameHeader::kOpCodeText,
359            kFinal,
360            "hello");
361   ReadFramesStub stub(OK, &frames_to_output);
362   ScopedVector<WebSocketFrame> frames;
363
364   {
365     InSequence s;
366     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
367         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
368   }
369   CompletionCallback callback;
370   ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback));
371   ASSERT_EQ(1u, frames.size());
372   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
373   EXPECT_TRUE(frames[0]->header.final);
374   EXPECT_FALSE(frames[0]->header.reserved1);
375   EXPECT_EQ("hello", ToString(frames[0]));
376 }
377
378 TEST_F(WebSocketDeflateStreamTest, ReadUncompressedFrameAsync) {
379   ReadFramesStub stub(ERR_IO_PENDING);
380   ScopedVector<WebSocketFrame> frames;
381   MockCallback mock_callback, checkpoint;
382   CompletionCallback callback =
383       base::Bind(&MockCallback::Call, base::Unretained(&mock_callback));
384
385   {
386     InSequence s;
387     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
388         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
389     EXPECT_CALL(checkpoint, Call(0));
390     EXPECT_CALL(mock_callback, Call(OK));
391   }
392   ASSERT_EQ(ERR_IO_PENDING, deflate_stream_->ReadFrames(&frames, callback));
393   ASSERT_EQ(0u, frames.size());
394
395   checkpoint.Call(0);
396
397   AppendTo(stub.frames_passed(),
398            WebSocketFrameHeader::kOpCodeText,
399            kFinal,
400            "hello");
401   stub.callback().Run(OK);
402   ASSERT_EQ(1u, frames.size());
403   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
404   EXPECT_TRUE(frames[0]->header.final);
405   EXPECT_FALSE(frames[0]->header.reserved1);
406   EXPECT_EQ("hello", ToString(frames[0]));
407 }
408
409 TEST_F(WebSocketDeflateStreamTest, ReadFailedAsync) {
410   ReadFramesStub stub(ERR_IO_PENDING);
411   ScopedVector<WebSocketFrame> frames;
412   MockCallback mock_callback, checkpoint;
413   CompletionCallback callback =
414       base::Bind(&MockCallback::Call, base::Unretained(&mock_callback));
415
416   {
417     InSequence s;
418     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
419         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
420     EXPECT_CALL(checkpoint, Call(0));
421     EXPECT_CALL(mock_callback, Call(ERR_FAILED));
422   }
423   ASSERT_EQ(ERR_IO_PENDING, deflate_stream_->ReadFrames(&frames, callback));
424   ASSERT_EQ(0u, frames.size());
425
426   checkpoint.Call(0);
427
428   AppendTo(stub.frames_passed(),
429            WebSocketFrameHeader::kOpCodeText,
430            kFinal,
431            "hello");
432   stub.callback().Run(ERR_FAILED);
433   ASSERT_EQ(0u, frames.size());
434 }
435
436 TEST_F(WebSocketDeflateStreamTest, ReadCompressedFrameImmediately) {
437   ScopedVector<WebSocketFrame> frames_to_output;
438   AppendTo(&frames_to_output,
439            WebSocketFrameHeader::kOpCodeText,
440            kFinal | kReserved1,
441            std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
442   ReadFramesStub stub(OK, &frames_to_output);
443   CompletionCallback callback;
444   ScopedVector<WebSocketFrame> frames;
445   {
446     InSequence s;
447     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
448         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
449   }
450   ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback));
451   ASSERT_EQ(1u, frames.size());
452   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
453   EXPECT_TRUE(frames[0]->header.final);
454   EXPECT_FALSE(frames[0]->header.reserved1);
455   EXPECT_EQ("Hello", ToString(frames[0]));
456 }
457
458 TEST_F(WebSocketDeflateStreamTest, ReadCompressedFrameAsync) {
459   ReadFramesStub stub(ERR_IO_PENDING);
460   MockCallback mock_callback, checkpoint;
461   CompletionCallback callback =
462       base::Bind(&MockCallback::Call, base::Unretained(&mock_callback));
463   ScopedVector<WebSocketFrame> frames;
464   {
465     InSequence s;
466     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
467         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
468     EXPECT_CALL(checkpoint, Call(0));
469     EXPECT_CALL(mock_callback, Call(OK));
470   }
471   ASSERT_EQ(ERR_IO_PENDING, deflate_stream_->ReadFrames(&frames, callback));
472
473   checkpoint.Call(0);
474
475   AppendTo(stub.frames_passed(),
476            WebSocketFrameHeader::kOpCodeText,
477            kFinal | kReserved1,
478            std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
479   stub.callback().Run(OK);
480
481   ASSERT_EQ(1u, frames.size());
482   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
483   EXPECT_TRUE(frames[0]->header.final);
484   EXPECT_FALSE(frames[0]->header.reserved1);
485   EXPECT_EQ("Hello", ToString(frames[0]));
486 }
487
488 TEST_F(WebSocketDeflateStreamTest,
489        ReadCompressedFrameFragmentImmediatelyButInflaterReturnsPending) {
490   ScopedVector<WebSocketFrame> frames_to_output;
491   const std::string data1("\xf2", 1);
492   const std::string data2("\x48\xcd\xc9\xc9\x07\x00", 6);
493   AppendTo(&frames_to_output,
494            WebSocketFrameHeader::kOpCodeText,
495            kReserved1,
496            data1);
497   ReadFramesStub stub1(OK, &frames_to_output), stub2(ERR_IO_PENDING);
498   MockCallback mock_callback, checkpoint;
499   CompletionCallback callback =
500       base::Bind(&MockCallback::Call, base::Unretained(&mock_callback));
501   ScopedVector<WebSocketFrame> frames;
502
503   {
504     InSequence s;
505     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
506         .WillOnce(Invoke(&stub1, &ReadFramesStub::Call))
507         .WillOnce(Invoke(&stub2, &ReadFramesStub::Call));
508     EXPECT_CALL(checkpoint, Call(0));
509     EXPECT_CALL(mock_callback, Call(OK));
510   }
511   ASSERT_EQ(ERR_IO_PENDING, deflate_stream_->ReadFrames(&frames, callback));
512   ASSERT_EQ(0u, frames.size());
513
514   AppendTo(stub2.frames_passed(),
515            WebSocketFrameHeader::kOpCodeText,
516            kFinal,
517            data2);
518
519   checkpoint.Call(0);
520   stub2.callback().Run(OK);
521
522   ASSERT_EQ(1u, frames.size());
523   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
524   EXPECT_TRUE(frames[0]->header.final);
525   EXPECT_FALSE(frames[0]->header.reserved1);
526   EXPECT_EQ("Hello", ToString(frames[0]));
527 }
528
529 TEST_F(WebSocketDeflateStreamTest, ReadInvalidCompressedPayload) {
530   const std::string data("\xf2\x48\xcdINVALID", 10);
531   ScopedVector<WebSocketFrame> frames_to_output;
532   AppendTo(&frames_to_output,
533            WebSocketFrameHeader::kOpCodeText,
534            kFinal | kReserved1,
535            data);
536   ReadFramesStub stub(OK, &frames_to_output);
537   CompletionCallback callback;
538   ScopedVector<WebSocketFrame> frames;
539
540   {
541     InSequence s;
542     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
543         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
544   }
545   ASSERT_EQ(ERR_WS_PROTOCOL_ERROR,
546             deflate_stream_->ReadFrames(&frames, callback));
547   ASSERT_EQ(0u, frames.size());
548 }
549
550 TEST_F(WebSocketDeflateStreamTest, MergeMultipleFramesInReadFrames) {
551   const std::string data1("\xf2\x48\xcd", 3);
552   const std::string data2("\xc9\xc9\x07\x00", 4);
553   ScopedVector<WebSocketFrame> frames_to_output;
554   AppendTo(&frames_to_output,
555            WebSocketFrameHeader::kOpCodeText,
556            kReserved1,
557            data1);
558   AppendTo(&frames_to_output,
559            WebSocketFrameHeader::kOpCodeContinuation,
560            kFinal,
561            data2);
562   ReadFramesStub stub(OK, &frames_to_output);
563   CompletionCallback callback;
564   ScopedVector<WebSocketFrame> frames;
565
566   {
567     InSequence s;
568     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
569         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
570   }
571   ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback));
572   ASSERT_EQ(1u, frames.size());
573   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
574   EXPECT_TRUE(frames[0]->header.final);
575   EXPECT_FALSE(frames[0]->header.reserved1);
576   EXPECT_EQ("Hello", ToString(frames[0]));
577 }
578
579 TEST_F(WebSocketDeflateStreamTest, ReadUncompressedEmptyFrames) {
580   ScopedVector<WebSocketFrame> frames_to_output;
581   AppendTo(&frames_to_output,
582            WebSocketFrameHeader::kOpCodeText,
583            kNoFlag);
584   AppendTo(&frames_to_output,
585            WebSocketFrameHeader::kOpCodeContinuation,
586            kFinal);
587   ReadFramesStub stub(OK, &frames_to_output);
588   CompletionCallback callback;
589   ScopedVector<WebSocketFrame> frames;
590
591   {
592     InSequence s;
593     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
594         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
595   }
596   ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback));
597   ASSERT_EQ(2u, frames.size());
598   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
599   EXPECT_FALSE(frames[0]->header.final);
600   EXPECT_FALSE(frames[0]->header.reserved1);
601   EXPECT_EQ("", ToString(frames[0]));
602   EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
603             frames[1]->header.opcode);
604   EXPECT_TRUE(frames[1]->header.final);
605   EXPECT_FALSE(frames[1]->header.reserved1);
606   EXPECT_EQ("", ToString(frames[1]));
607 }
608
609 TEST_F(WebSocketDeflateStreamTest, ReadCompressedEmptyFrames) {
610   ScopedVector<WebSocketFrame> frames_to_output;
611   AppendTo(&frames_to_output,
612            WebSocketFrameHeader::kOpCodeText,
613            kReserved1,
614            std::string("\x02\x00", 1));
615   AppendTo(&frames_to_output,
616            WebSocketFrameHeader::kOpCodeContinuation,
617            kFinal);
618   ReadFramesStub stub(OK, &frames_to_output);
619   CompletionCallback callback;
620   ScopedVector<WebSocketFrame> frames;
621
622   {
623     InSequence s;
624     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
625         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
626   }
627   ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback));
628   ASSERT_EQ(1u, frames.size());
629   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
630   EXPECT_TRUE(frames[0]->header.final);
631   EXPECT_FALSE(frames[0]->header.reserved1);
632   EXPECT_EQ("", ToString(frames[0]));
633 }
634
635 TEST_F(WebSocketDeflateStreamTest,
636        ReadCompressedFrameFollowedByEmptyFrame) {
637   const std::string data("\xf2\x48\xcd\xc9\xc9\x07\x00", 7);
638   ScopedVector<WebSocketFrame> frames_to_output;
639   AppendTo(&frames_to_output,
640            WebSocketFrameHeader::kOpCodeText,
641            kReserved1,
642            data);
643   AppendTo(&frames_to_output,
644            WebSocketFrameHeader::kOpCodeContinuation,
645            kFinal);
646   ReadFramesStub stub(OK, &frames_to_output);
647   CompletionCallback callback;
648   ScopedVector<WebSocketFrame> frames;
649
650   {
651     InSequence s;
652     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
653         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
654   }
655   ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback));
656   ASSERT_EQ(1u, frames.size());
657   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
658   EXPECT_TRUE(frames[0]->header.final);
659   EXPECT_FALSE(frames[0]->header.reserved1);
660   EXPECT_EQ("Hello", ToString(frames[0]));
661 }
662
663 TEST_F(WebSocketDeflateStreamTest, ReadControlFrameBetweenDataFrames) {
664   const std::string data1("\xf2\x48\xcd", 3);
665   const std::string data2("\xc9\xc9\x07\x00", 4);
666   ScopedVector<WebSocketFrame> frames_to_output;
667   AppendTo(&frames_to_output,
668            WebSocketFrameHeader::kOpCodeText,
669            kReserved1,
670            data1);
671   AppendTo(&frames_to_output, WebSocketFrameHeader::kOpCodePing, kFinal);
672   AppendTo(&frames_to_output, WebSocketFrameHeader::kOpCodeText, kFinal, data2);
673   ReadFramesStub stub(OK, &frames_to_output);
674   CompletionCallback callback;
675   ScopedVector<WebSocketFrame> frames;
676
677   {
678     InSequence s;
679     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
680         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
681   }
682   ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback));
683   ASSERT_EQ(2u, frames.size());
684   EXPECT_EQ(WebSocketFrameHeader::kOpCodePing, frames[0]->header.opcode);
685   EXPECT_TRUE(frames[0]->header.final);
686   EXPECT_FALSE(frames[0]->header.reserved1);
687   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[1]->header.opcode);
688   EXPECT_TRUE(frames[1]->header.final);
689   EXPECT_FALSE(frames[1]->header.reserved1);
690   EXPECT_EQ("Hello", ToString(frames[1]));
691 }
692
693 TEST_F(WebSocketDeflateStreamTest, SplitToMultipleFramesInReadFrames) {
694   WebSocketDeflater deflater(WebSocketDeflater::TAKE_OVER_CONTEXT);
695   deflater.Initialize(kWindowBits);
696   const size_t kSize = kChunkSize * 3;
697   const std::string original_data(kSize, 'a');
698   deflater.AddBytes(original_data.data(), original_data.size());
699   deflater.Finish();
700
701   ScopedVector<WebSocketFrame> frames_to_output;
702   AppendTo(&frames_to_output,
703            WebSocketFrameHeader::kOpCodeBinary,
704            kFinal | kReserved1,
705            ToString(deflater.GetOutput(deflater.CurrentOutputSize())));
706
707   ReadFramesStub stub(OK, &frames_to_output);
708   CompletionCallback callback;
709   ScopedVector<WebSocketFrame> frames;
710   {
711     InSequence s;
712     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
713         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
714   }
715
716   ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback));
717   ASSERT_EQ(3u, frames.size());
718   EXPECT_EQ(WebSocketFrameHeader::kOpCodeBinary, frames[0]->header.opcode);
719   EXPECT_FALSE(frames[0]->header.final);
720   EXPECT_FALSE(frames[0]->header.reserved1);
721   EXPECT_EQ(kChunkSize, static_cast<size_t>(frames[0]->header.payload_length));
722   EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
723             frames[1]->header.opcode);
724   EXPECT_FALSE(frames[1]->header.final);
725   EXPECT_FALSE(frames[1]->header.reserved1);
726   EXPECT_EQ(kChunkSize, static_cast<size_t>(frames[1]->header.payload_length));
727   EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
728             frames[2]->header.opcode);
729   EXPECT_TRUE(frames[2]->header.final);
730   EXPECT_FALSE(frames[2]->header.reserved1);
731   EXPECT_EQ(kChunkSize, static_cast<size_t>(frames[2]->header.payload_length));
732   EXPECT_EQ(original_data,
733             ToString(frames[0]) + ToString(frames[1]) + ToString(frames[2]));
734 }
735
736 TEST_F(WebSocketDeflateStreamTest, InflaterInternalDataCanBeEmpty) {
737   WebSocketDeflater deflater(WebSocketDeflater::TAKE_OVER_CONTEXT);
738   deflater.Initialize(kWindowBits);
739   const std::string original_data(kChunkSize, 'a');
740   deflater.AddBytes(original_data.data(), original_data.size());
741   deflater.Finish();
742
743   ScopedVector<WebSocketFrame> frames_to_output;
744   AppendTo(&frames_to_output,
745            WebSocketFrameHeader::kOpCodeBinary,
746            kReserved1,
747            ToString(deflater.GetOutput(deflater.CurrentOutputSize())));
748   AppendTo(&frames_to_output,
749            WebSocketFrameHeader::kOpCodeBinary,
750            kFinal,
751            "");
752
753   ReadFramesStub stub(OK, &frames_to_output);
754   CompletionCallback callback;
755   ScopedVector<WebSocketFrame> frames;
756   {
757     InSequence s;
758     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
759         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
760   }
761
762   ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback));
763   ASSERT_EQ(2u, frames.size());
764   EXPECT_EQ(WebSocketFrameHeader::kOpCodeBinary, frames[0]->header.opcode);
765   EXPECT_FALSE(frames[0]->header.final);
766   EXPECT_FALSE(frames[0]->header.reserved1);
767   EXPECT_EQ(kChunkSize, static_cast<size_t>(frames[0]->header.payload_length));
768
769   EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
770             frames[1]->header.opcode);
771   EXPECT_TRUE(frames[1]->header.final);
772   EXPECT_FALSE(frames[1]->header.reserved1);
773   EXPECT_EQ(0u, static_cast<size_t>(frames[1]->header.payload_length));
774   EXPECT_EQ(original_data, ToString(frames[0]) + ToString(frames[1]));
775 }
776
777 TEST_F(WebSocketDeflateStreamTest,
778        Reserved1TurnsOnDuringReadingCompressedContinuationFrame) {
779   const std::string data1("\xf2\x48\xcd", 3);
780   const std::string data2("\xc9\xc9\x07\x00", 4);
781   ScopedVector<WebSocketFrame> frames_to_output;
782   AppendTo(&frames_to_output,
783            WebSocketFrameHeader::kOpCodeText,
784            kReserved1,
785            data1);
786   AppendTo(&frames_to_output,
787            WebSocketFrameHeader::kOpCodeContinuation,
788            kFinal | kReserved1,
789            data2);
790   ReadFramesStub stub(OK, &frames_to_output);
791   CompletionCallback callback;
792   ScopedVector<WebSocketFrame> frames;
793
794   {
795     InSequence s;
796     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
797         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
798   }
799   ASSERT_EQ(ERR_WS_PROTOCOL_ERROR,
800             deflate_stream_->ReadFrames(&frames, callback));
801 }
802
803 TEST_F(WebSocketDeflateStreamTest,
804        Reserved1TurnsOnDuringReadingUncompressedContinuationFrame) {
805   ScopedVector<WebSocketFrame> frames_to_output;
806   AppendTo(&frames_to_output,
807            WebSocketFrameHeader::kOpCodeText,
808            kNoFlag,
809            "hello");
810   AppendTo(&frames_to_output,
811            WebSocketFrameHeader::kOpCodeContinuation,
812            kFinal | kReserved1,
813            "world");
814   ReadFramesStub stub(OK, &frames_to_output);
815   CompletionCallback callback;
816   ScopedVector<WebSocketFrame> frames;
817
818   {
819     InSequence s;
820     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
821         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
822   }
823   ASSERT_EQ(ERR_WS_PROTOCOL_ERROR,
824             deflate_stream_->ReadFrames(&frames, callback));
825 }
826
827 TEST_F(WebSocketDeflateStreamTest, ReadCompressedMessages) {
828   ScopedVector<WebSocketFrame> frames_to_output;
829   AppendTo(&frames_to_output,
830            WebSocketFrameHeader::kOpCodeText,
831            kFinal | kReserved1,
832            std::string(
833                "\x4a\xce\xcf\x2d\x28\x4a\x2d\x2e\x4e\x4d\x31\x04\x00", 13));
834   AppendTo(&frames_to_output,
835            WebSocketFrameHeader::kOpCodeText,
836            kFinal | kReserved1,
837            std::string("\x4a\x86\x33\x8d\x00\x00", 6));
838   ReadFramesStub stub(OK, &frames_to_output);
839   CompletionCallback callback;
840   ScopedVector<WebSocketFrame> frames;
841
842   {
843     InSequence s;
844     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
845         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
846   }
847   ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback));
848   ASSERT_EQ(2u, frames.size());
849   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
850   EXPECT_TRUE(frames[0]->header.final);
851   EXPECT_FALSE(frames[0]->header.reserved1);
852   EXPECT_EQ("compressed1", ToString(frames[0]));
853   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[1]->header.opcode);
854   EXPECT_TRUE(frames[1]->header.final);
855   EXPECT_FALSE(frames[1]->header.reserved1);
856   EXPECT_EQ("compressed2", ToString(frames[1]));
857 }
858
859 TEST_F(WebSocketDeflateStreamTest, ReadUncompressedMessages) {
860   ScopedVector<WebSocketFrame> frames_to_output;
861   AppendTo(&frames_to_output,
862            WebSocketFrameHeader::kOpCodeText,
863            kFinal,
864            "uncompressed1");
865   AppendTo(&frames_to_output,
866            WebSocketFrameHeader::kOpCodeText,
867            kFinal,
868            "uncompressed2");
869   ReadFramesStub stub(OK, &frames_to_output);
870   CompletionCallback callback;
871   ScopedVector<WebSocketFrame> frames;
872
873   {
874     InSequence s;
875     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
876         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
877   }
878   ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback));
879   ASSERT_EQ(2u, frames.size());
880   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
881   EXPECT_TRUE(frames[0]->header.final);
882   EXPECT_FALSE(frames[0]->header.reserved1);
883   EXPECT_EQ("uncompressed1", ToString(frames[0]));
884   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[1]->header.opcode);
885   EXPECT_TRUE(frames[1]->header.final);
886   EXPECT_FALSE(frames[1]->header.reserved1);
887   EXPECT_EQ("uncompressed2", ToString(frames[1]));
888 }
889
890 TEST_F(WebSocketDeflateStreamTest,
891        ReadCompressedMessageThenUncompressedMessage) {
892   ScopedVector<WebSocketFrame> frames_to_output;
893   AppendTo(&frames_to_output,
894            WebSocketFrameHeader::kOpCodeText,
895            kFinal | kReserved1,
896            std::string(
897                "\x4a\xce\xcf\x2d\x28\x4a\x2d\x2e\x4e\x4d\x01\x00", 12));
898   AppendTo(&frames_to_output,
899            WebSocketFrameHeader::kOpCodeText,
900            kFinal,
901            "uncompressed");
902   ReadFramesStub stub(OK, &frames_to_output);
903   CompletionCallback callback;
904   ScopedVector<WebSocketFrame> frames;
905
906   {
907     InSequence s;
908     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
909         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
910   }
911   ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback));
912   ASSERT_EQ(2u, frames.size());
913   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
914   EXPECT_TRUE(frames[0]->header.final);
915   EXPECT_FALSE(frames[0]->header.reserved1);
916   EXPECT_EQ("compressed", ToString(frames[0]));
917   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[1]->header.opcode);
918   EXPECT_TRUE(frames[1]->header.final);
919   EXPECT_FALSE(frames[1]->header.reserved1);
920   EXPECT_EQ("uncompressed", ToString(frames[1]));
921 }
922
923 TEST_F(WebSocketDeflateStreamTest,
924        ReadUncompressedMessageThenCompressedMessage) {
925   ScopedVector<WebSocketFrame> frames_to_output;
926   AppendTo(&frames_to_output,
927            WebSocketFrameHeader::kOpCodeText,
928            kFinal,
929            "uncompressed");
930   AppendTo(&frames_to_output,
931            WebSocketFrameHeader::kOpCodeText,
932            kFinal | kReserved1,
933            std::string(
934                "\x4a\xce\xcf\x2d\x28\x4a\x2d\x2e\x4e\x4d\x01\x00", 12));
935   ReadFramesStub stub(OK, &frames_to_output);
936   CompletionCallback callback;
937   ScopedVector<WebSocketFrame> frames;
938
939   {
940     InSequence s;
941     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
942         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
943   }
944   ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback));
945   ASSERT_EQ(2u, frames.size());
946   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
947   EXPECT_TRUE(frames[0]->header.final);
948   EXPECT_FALSE(frames[0]->header.reserved1);
949   EXPECT_EQ("uncompressed", ToString(frames[0]));
950   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[1]->header.opcode);
951   EXPECT_TRUE(frames[1]->header.final);
952   EXPECT_FALSE(frames[1]->header.reserved1);
953   EXPECT_EQ("compressed", ToString(frames[1]));
954 }
955
956 // This is a regression test for crbug.com/343506.
957 TEST_F(WebSocketDeflateStreamTest, ReadEmptyAsyncFrame) {
958   ScopedVector<ReadFramesStub> stub_vector;
959   stub_vector.push_back(new ReadFramesStub(ERR_IO_PENDING));
960   stub_vector.push_back(new ReadFramesStub(ERR_IO_PENDING));
961   MockCallback mock_callback;
962   CompletionCallback callback =
963       base::Bind(&MockCallback::Call, base::Unretained(&mock_callback));
964   ScopedVector<WebSocketFrame> frames;
965
966   {
967     InSequence s;
968     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
969         .WillOnce(Invoke(stub_vector[0], &ReadFramesStub::Call));
970
971     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
972         .WillOnce(Invoke(stub_vector[1], &ReadFramesStub::Call));
973
974     EXPECT_CALL(mock_callback, Call(OK));
975   }
976
977   ASSERT_EQ(ERR_IO_PENDING, deflate_stream_->ReadFrames(&frames, callback));
978   AppendTo(stub_vector[0]->frames_passed(),
979            WebSocketFrameHeader::kOpCodeText,
980            kReserved1,
981            std::string());
982   stub_vector[0]->callback().Run(OK);
983   AppendTo(stub_vector[1]->frames_passed(),
984            WebSocketFrameHeader::kOpCodeContinuation,
985            kFinal,
986            std::string("\x02\x00"));
987   stub_vector[1]->callback().Run(OK);
988   ASSERT_EQ(1u, frames.size());
989   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
990   EXPECT_EQ("", ToString(frames[0]));
991 }
992
993 TEST_F(WebSocketDeflateStreamTest, WriteEmpty) {
994   ScopedVector<WebSocketFrame> frames;
995   CompletionCallback callback;
996   {
997     InSequence s;
998     EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)).Times(0);
999   }
1000   EXPECT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
1001 }
1002
1003 TEST_F(WebSocketDeflateStreamTest, WriteFailedImmediately) {
1004   ScopedVector<WebSocketFrame> frames;
1005   CompletionCallback callback;
1006   {
1007     InSequence s;
1008     EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
1009         .WillOnce(Return(ERR_FAILED));
1010   }
1011
1012   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "hello");
1013   predictor_->AddFramesToBeInput(frames);
1014   EXPECT_EQ(ERR_FAILED, deflate_stream_->WriteFrames(&frames, callback));
1015   predictor_->Clear();
1016 }
1017
1018 TEST_F(WebSocketDeflateStreamTest, WriteFrameImmediately) {
1019   ScopedVector<WebSocketFrame> frames;
1020   CompletionCallback callback;
1021   WriteFramesStub stub(predictor_, OK);
1022   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
1023   predictor_->AddFramesToBeInput(frames);
1024   {
1025     InSequence s;
1026     EXPECT_CALL(*mock_stream_, WriteFrames(_, _))
1027         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1028   }
1029   ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
1030   const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
1031   ASSERT_EQ(1u, frames_passed.size());
1032   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1033   EXPECT_TRUE(frames_passed[0]->header.final);
1034   EXPECT_TRUE(frames_passed[0]->header.reserved1);
1035   EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
1036             ToString(frames_passed[0]));
1037 }
1038
1039 TEST_F(WebSocketDeflateStreamTest, WriteFrameAsync) {
1040   WriteFramesStub stub(predictor_, ERR_IO_PENDING);
1041   MockCallback mock_callback, checkpoint;
1042   CompletionCallback callback =
1043       base::Bind(&MockCallback::Call, base::Unretained(&mock_callback));
1044   ScopedVector<WebSocketFrame> frames;
1045   {
1046     InSequence s;
1047     EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
1048         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1049     EXPECT_CALL(checkpoint, Call(0));
1050     EXPECT_CALL(mock_callback, Call(OK));
1051   }
1052   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
1053   predictor_->AddFramesToBeInput(frames);
1054   ASSERT_EQ(ERR_IO_PENDING, deflate_stream_->WriteFrames(&frames, callback));
1055
1056   checkpoint.Call(0);
1057   stub.callback().Run(OK);
1058
1059   const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
1060   ASSERT_EQ(1u, frames_passed.size());
1061   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1062   EXPECT_TRUE(frames_passed[0]->header.final);
1063   EXPECT_TRUE(frames_passed[0]->header.reserved1);
1064   EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
1065             ToString(frames_passed[0]));
1066 }
1067
1068 TEST_F(WebSocketDeflateStreamTest, WriteControlFrameBetweenDataFrames) {
1069   ScopedVector<WebSocketFrame> frames;
1070   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "Hel");
1071   AppendTo(&frames, WebSocketFrameHeader::kOpCodePing, kFinal);
1072   AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "lo");
1073   predictor_->AddFramesToBeInput(frames);
1074   WriteFramesStub stub(predictor_, OK);
1075   CompletionCallback callback;
1076
1077   {
1078     InSequence s;
1079     EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
1080         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1081   }
1082   ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
1083   const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
1084   ASSERT_EQ(2u, frames_passed.size());
1085   EXPECT_EQ(WebSocketFrameHeader::kOpCodePing, frames_passed[0]->header.opcode);
1086   EXPECT_TRUE(frames_passed[0]->header.final);
1087   EXPECT_FALSE(frames_passed[0]->header.reserved1);
1088   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[1]->header.opcode);
1089   EXPECT_TRUE(frames_passed[1]->header.final);
1090   EXPECT_TRUE(frames_passed[1]->header.reserved1);
1091   EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
1092             ToString(frames_passed[1]));
1093 }
1094
1095 TEST_F(WebSocketDeflateStreamTest, WriteEmptyMessage) {
1096   ScopedVector<WebSocketFrame> frames;
1097   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal);
1098   predictor_->AddFramesToBeInput(frames);
1099   WriteFramesStub stub(predictor_, OK);
1100   CompletionCallback callback;
1101
1102   {
1103     InSequence s;
1104     EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
1105         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1106   }
1107   ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
1108   const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
1109   ASSERT_EQ(1u, frames_passed.size());
1110   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1111   EXPECT_TRUE(frames_passed[0]->header.final);
1112   EXPECT_TRUE(frames_passed[0]->header.reserved1);
1113   EXPECT_EQ(std::string("\x00", 1), ToString(frames_passed[0]));
1114 }
1115
1116 TEST_F(WebSocketDeflateStreamTest, WriteUncompressedMessage) {
1117   ScopedVector<WebSocketFrame> frames;
1118   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "AAAA");
1119   AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "AAA");
1120   predictor_->AddFramesToBeInput(frames);
1121   WriteFramesStub stub(predictor_, OK);
1122   CompletionCallback callback;
1123
1124   predictor_->set_result(WebSocketDeflatePredictor::DO_NOT_DEFLATE);
1125
1126   {
1127     InSequence s;
1128     EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
1129         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1130   }
1131   ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
1132   const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
1133   ASSERT_EQ(2u, frames_passed.size());
1134   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1135   EXPECT_FALSE(frames_passed[0]->header.final);
1136   EXPECT_FALSE(frames_passed[0]->header.reserved1);
1137   EXPECT_EQ("AAAA", ToString(frames_passed[0]));
1138   EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
1139             frames_passed[1]->header.opcode);
1140   EXPECT_TRUE(frames_passed[1]->header.final);
1141   EXPECT_FALSE(frames_passed[1]->header.reserved1);
1142   EXPECT_EQ("AAA", ToString(frames_passed[1]));
1143 }
1144
1145 TEST_F(WebSocketDeflateStreamTest, LargeDeflatedFramesShouldBeSplit) {
1146   WebSocketDeflater deflater(WebSocketDeflater::TAKE_OVER_CONTEXT);
1147   LinearCongruentialGenerator lcg(133);
1148   WriteFramesStub stub(predictor_, OK);
1149   CompletionCallback callback;
1150   const size_t size = 1024;
1151
1152   {
1153     InSequence s;
1154     EXPECT_CALL(*mock_stream_, WriteFrames(_, _))
1155         .WillRepeatedly(Invoke(&stub, &WriteFramesStub::Call));
1156   }
1157   ScopedVector<WebSocketFrame> total_compressed_frames;
1158
1159   deflater.Initialize(kWindowBits);
1160   while (true) {
1161     bool is_final = (total_compressed_frames.size() >= 2);
1162     ScopedVector<WebSocketFrame> frames;
1163     std::string data;
1164     for (size_t i = 0; i < size; ++i)
1165       data += static_cast<char>(lcg.Generate());
1166     deflater.AddBytes(data.data(), data.size());
1167     FrameFlag flag = is_final ? kFinal : kNoFlag;
1168     AppendTo(&frames, WebSocketFrameHeader::kOpCodeBinary, flag, data);
1169     predictor_->AddFramesToBeInput(frames);
1170     ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
1171     total_compressed_frames.insert(total_compressed_frames.end(),
1172                                    stub.frames()->begin(),
1173                                    stub.frames()->end());
1174     stub.frames()->weak_clear();
1175     if (is_final)
1176       break;
1177   }
1178   deflater.Finish();
1179   std::string total_deflated;
1180   for (size_t i = 0; i < total_compressed_frames.size(); ++i) {
1181     WebSocketFrame* frame = total_compressed_frames[i];
1182     const WebSocketFrameHeader& header = frame->header;
1183     if (i > 0) {
1184       EXPECT_EQ(header.kOpCodeContinuation, header.opcode);
1185       EXPECT_FALSE(header.reserved1);
1186     } else {
1187       EXPECT_EQ(header.kOpCodeBinary, header.opcode);
1188       EXPECT_TRUE(header.reserved1);
1189     }
1190     const bool is_final_frame = (i + 1 == total_compressed_frames.size());
1191     EXPECT_EQ(is_final_frame, header.final);
1192     if (!is_final_frame)
1193       EXPECT_GT(header.payload_length, 0ul);
1194     total_deflated += ToString(frame);
1195   }
1196   EXPECT_EQ(total_deflated,
1197             ToString(deflater.GetOutput(deflater.CurrentOutputSize())));
1198 }
1199
1200 TEST_F(WebSocketDeflateStreamTest, WriteMultipleMessages) {
1201   ScopedVector<WebSocketFrame> frames;
1202   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
1203   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
1204   predictor_->AddFramesToBeInput(frames);
1205   WriteFramesStub stub(predictor_, OK);
1206   CompletionCallback callback;
1207
1208   {
1209     InSequence s;
1210     EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
1211         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1212   }
1213   ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
1214   const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
1215   ASSERT_EQ(2u, frames_passed.size());
1216   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1217   EXPECT_TRUE(frames_passed[0]->header.final);
1218   EXPECT_TRUE(frames_passed[0]->header.reserved1);
1219   EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
1220             ToString(frames_passed[0]));
1221   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[1]->header.opcode);
1222   EXPECT_TRUE(frames_passed[1]->header.final);
1223   EXPECT_TRUE(frames_passed[1]->header.reserved1);
1224   EXPECT_EQ(std::string("\xf2\x00\x11\x00\x00", 5), ToString(frames_passed[1]));
1225 }
1226
1227 TEST_F(WebSocketDeflateStreamWithDoNotTakeOverContextTest,
1228        WriteMultipleMessages) {
1229   ScopedVector<WebSocketFrame> frames;
1230   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
1231   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
1232   predictor_->AddFramesToBeInput(frames);
1233   WriteFramesStub stub(predictor_, OK);
1234   CompletionCallback callback;
1235
1236   {
1237     InSequence s;
1238     EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
1239         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1240   }
1241   ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
1242   const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
1243   ASSERT_EQ(2u, frames_passed.size());
1244   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1245   EXPECT_TRUE(frames_passed[0]->header.final);
1246   EXPECT_TRUE(frames_passed[0]->header.reserved1);
1247   EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
1248             ToString(frames_passed[0]));
1249   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[1]->header.opcode);
1250   EXPECT_TRUE(frames_passed[1]->header.final);
1251   EXPECT_TRUE(frames_passed[1]->header.reserved1);
1252   EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
1253             ToString(frames_passed[1]));
1254 }
1255
1256 // In order to check the stream works correctly for multiple
1257 // "PossiblyCompressedMessage"s, we test various messages at one test case.
1258 TEST_F(WebSocketDeflateStreamWithDoNotTakeOverContextTest,
1259        WritePossiblyCompressMessages) {
1260   ScopedVector<WebSocketFrame> frames;
1261   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "He");
1262   AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "llo");
1263   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "AAAAAAAAAA");
1264   AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "AA");
1265   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "XX");
1266   AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "YY");
1267   predictor_->AddFramesToBeInput(frames);
1268   WriteFramesStub stub(predictor_, OK);
1269   CompletionCallback callback;
1270   predictor_->set_result(WebSocketDeflatePredictor::TRY_DEFLATE);
1271
1272   {
1273     InSequence s;
1274     EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
1275         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1276   }
1277   ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
1278   const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
1279   ASSERT_EQ(5u, frames_passed.size());
1280
1281   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1282   EXPECT_FALSE(frames_passed[0]->header.final);
1283   EXPECT_FALSE(frames_passed[0]->header.reserved1);
1284   EXPECT_EQ("He", ToString(frames_passed[0]));
1285   EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
1286             frames_passed[1]->header.opcode);
1287   EXPECT_TRUE(frames_passed[1]->header.final);
1288   EXPECT_FALSE(frames_passed[1]->header.reserved1);
1289   EXPECT_EQ("llo", ToString(frames_passed[1]));
1290
1291   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[2]->header.opcode);
1292   EXPECT_TRUE(frames_passed[2]->header.final);
1293   EXPECT_TRUE(frames_passed[2]->header.reserved1);
1294   EXPECT_EQ(std::string("\x72\x74\x44\x00\x00\x00", 6),
1295             ToString(frames_passed[2]));
1296
1297   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[3]->header.opcode);
1298   EXPECT_FALSE(frames_passed[3]->header.final);
1299   EXPECT_FALSE(frames_passed[3]->header.reserved1);
1300   EXPECT_EQ("XX", ToString(frames_passed[3]));
1301   EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
1302             frames_passed[4]->header.opcode);
1303   EXPECT_TRUE(frames_passed[4]->header.final);
1304   EXPECT_FALSE(frames_passed[4]->header.reserved1);
1305   EXPECT_EQ("YY", ToString(frames_passed[4]));
1306 }
1307
1308 // This is based on the similar test from websocket_deflater_test.cc
1309 TEST_F(WebSocketDeflateStreamWithClientWindowBitsTest, WindowBits8) {
1310   SetUpWithWindowBits(8);
1311   CompletionCallback callback;
1312   AddCompressibleFrameString();
1313   WriteFramesStub stub(predictor_, OK);
1314   {
1315     InSequence s;
1316     EXPECT_CALL(*mock_stream_, WriteFrames(_, _))
1317         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1318   }
1319   ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames_, callback));
1320   const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
1321   ASSERT_EQ(1u, frames_passed.size());
1322   EXPECT_EQ(std::string("r\xce(\xca\xcf\xcd,\xcdM\x1c\xe1\xc0\x39\xa3"
1323                         "(?7\xb3\x34\x17\x00", 21),
1324             ToString(frames_passed[0]));
1325 }
1326
1327 // The same input with window_bits=10 returns smaller output.
1328 TEST_F(WebSocketDeflateStreamWithClientWindowBitsTest, WindowBits10) {
1329   SetUpWithWindowBits(10);
1330   CompletionCallback callback;
1331   AddCompressibleFrameString();
1332   WriteFramesStub stub(predictor_, OK);
1333   {
1334     InSequence s;
1335     EXPECT_CALL(*mock_stream_, WriteFrames(_, _))
1336         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1337   }
1338   ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames_, callback));
1339   const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
1340   ASSERT_EQ(1u, frames_passed.size());
1341   EXPECT_EQ(
1342       std::string("r\xce(\xca\xcf\xcd,\xcdM\x1c\xe1\xc0\x19\x1a\x0e\0\0", 17),
1343       ToString(frames_passed[0]));
1344 }
1345
1346 }  // namespace
1347
1348 }  // namespace net