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