blob: c1ae86ae7f0c0bea43173d527d71db2d02ac38fa [file] [log] [blame]
[email protected]9c0b1352012-11-04 00:03:271// Copyright (c) 2012 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/quic/quic_stream_sequencer.h"
6
7#include <utility>
8#include <vector>
9
10#include "base/rand_util.h"
11#include "net/quic/reliable_quic_stream.h"
12#include "testing/gmock/include/gmock/gmock.h"
13#include "testing/gtest/include/gtest/gtest.h"
14
15using base::StringPiece;
16using std::min;
17using std::pair;
18using std::vector;
19using testing::_;
20using testing::AnyNumber;
21using testing::InSequence;
22using testing::Return;
23using testing::StrEq;
24
25namespace net {
26
27class QuicStreamSequencerPeer : public QuicStreamSequencer {
28 public:
29 explicit QuicStreamSequencerPeer(ReliableQuicStream* stream)
30 : QuicStreamSequencer(stream) {
31 }
32
33 QuicStreamSequencerPeer(int32 max_mem, ReliableQuicStream* stream)
34 : QuicStreamSequencer(max_mem, stream) {}
35
36 virtual bool OnFrame(QuicStreamOffset byte_offset,
[email protected]044ac2b2012-11-13 21:41:0637 const char* data,
38 uint32 data_len) {
[email protected]9c0b1352012-11-04 00:03:2739 QuicStreamFrame frame;
40 frame.stream_id = 1;
41 frame.offset = byte_offset;
42 frame.data = StringPiece(data, data_len);
43 return OnStreamFrame(frame);
44 }
45
46 void SetMemoryLimit(size_t limit) {
47 max_frame_memory_ = limit;
48 }
49
[email protected]2ff600a2012-11-11 19:22:1950 const ReliableQuicStream* stream() const { return stream_; }
51 uint64 num_bytes_consumed() const { return num_bytes_consumed_; }
52 const FrameMap* frames() const { return &frames_; }
53 int32 max_frame_memory() const { return max_frame_memory_; }
54 QuicStreamOffset close_offset() const { return close_offset_; }
[email protected]9c0b1352012-11-04 00:03:2755};
56
57class MockStream : public ReliableQuicStream {
58 public:
59 MockStream(QuicSession* session, QuicStreamId id)
60 : ReliableQuicStream(id, session) {
61 }
62
63 MOCK_METHOD1(TerminateFromPeer, void(bool half_close));
64 MOCK_METHOD2(ProcessData, uint32(const char* data, uint32 data_len));
65 MOCK_METHOD1(Close, void(QuicErrorCode error));
[email protected]a5d4eee22012-12-13 09:09:0166 MOCK_METHOD0(OnCanWrite, void());
[email protected]9c0b1352012-11-04 00:03:2767};
68
69namespace {
70
71static const char kPayload[] =
72 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
73
74class QuicStreamSequencerTest : public ::testing::Test {
75 protected:
76 QuicStreamSequencerTest()
77 : session_(NULL),
78 stream_(session_, 1),
79 sequencer_(new QuicStreamSequencerPeer(&stream_)) {
80 }
81
82 QuicSession* session_;
83 testing::StrictMock<MockStream> stream_;
84 scoped_ptr<QuicStreamSequencerPeer> sequencer_;
85};
86
87TEST_F(QuicStreamSequencerTest, RejectOldFrame) {
88 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3))
89 .WillOnce(Return(3));
90
91 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
92 EXPECT_EQ(0u, sequencer_->frames()->size());
93 EXPECT_EQ(3u, sequencer_->num_bytes_consumed());
94 // Nack this - it matches a past sequence number and we should not see it
95 // again.
96 EXPECT_FALSE(sequencer_->OnFrame(0, "def", 3));
97 EXPECT_EQ(0u, sequencer_->frames()->size());
98}
99
100TEST_F(QuicStreamSequencerTest, RejectOverlyLargeFrame) {
101 /*
102 EXPECT_DFATAL(sequencer_.reset(new QuicStreamSequencerPeer(2, &stream_)),
103 "Setting max frame memory to 2. "
104 "Some frames will be impossible to handle.");
105
106 EXPECT_DEBUG_DEATH(sequencer_->OnFrame(0, "abc", 3), "");
107 */
108}
109
110TEST_F(QuicStreamSequencerTest, DropFramePastBuffering) {
111 sequencer_->SetMemoryLimit(3);
112
113 EXPECT_FALSE(sequencer_->OnFrame(3, "abc", 3));
114}
115
116TEST_F(QuicStreamSequencerTest, RejectBufferedFrame) {
117 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3));
118
119 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
120 EXPECT_EQ(1u, sequencer_->frames()->size());
121 EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
122 // Ignore this - it matches a buffered frame.
123 // Right now there's no checking that the payload is consistent.
124 EXPECT_FALSE(sequencer_->OnFrame(0, "def", 3));
125 EXPECT_EQ(1u, sequencer_->frames()->size());
126}
127
128TEST_F(QuicStreamSequencerTest, FullFrameConsumed) {
[email protected]044ac2b2012-11-13 21:41:06129 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3));
[email protected]9c0b1352012-11-04 00:03:27130
131 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
132 EXPECT_EQ(0u, sequencer_->frames()->size());
133 EXPECT_EQ(3u, sequencer_->num_bytes_consumed());
134}
135
136TEST_F(QuicStreamSequencerTest, PartialFrameConsumed) {
[email protected]044ac2b2012-11-13 21:41:06137 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(2));
[email protected]9c0b1352012-11-04 00:03:27138
139 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
140 EXPECT_EQ(1u, sequencer_->frames()->size());
141 EXPECT_EQ(2u, sequencer_->num_bytes_consumed());
142 EXPECT_EQ("c", sequencer_->frames()->find(2)->second);
143}
144
145TEST_F(QuicStreamSequencerTest, NextxFrameNotConsumed) {
[email protected]044ac2b2012-11-13 21:41:06146 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(0));
[email protected]9c0b1352012-11-04 00:03:27147
148 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
149 EXPECT_EQ(1u, sequencer_->frames()->size());
150 EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
151 EXPECT_EQ("abc", sequencer_->frames()->find(0)->second);
152}
153
154TEST_F(QuicStreamSequencerTest, FutureFrameNotProcessed) {
155 EXPECT_TRUE(sequencer_->OnFrame(3, "abc", 3));
156 EXPECT_EQ(1u, sequencer_->frames()->size());
157 EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
158 EXPECT_EQ("abc", sequencer_->frames()->find(3)->second);
159}
160
161TEST_F(QuicStreamSequencerTest, OutOfOrderFrameProcessed) {
162 // Buffer the first
163 EXPECT_TRUE(sequencer_->OnFrame(6, "ghi", 3));
164 EXPECT_EQ(1u, sequencer_->frames()->size());
165 EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
166 // Buffer the second
167 EXPECT_TRUE(sequencer_->OnFrame(3, "def", 3));
168 EXPECT_EQ(2u, sequencer_->frames()->size());
169 EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
170
171 InSequence s;
172 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3));
173 EXPECT_CALL(stream_, ProcessData(StrEq("def"), 3)).WillOnce(Return(3));
174 EXPECT_CALL(stream_, ProcessData(StrEq("ghi"), 3)).WillOnce(Return(3));
175
176 // Ack right away
177 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
178 EXPECT_EQ(9u, sequencer_->num_bytes_consumed());
179
180 EXPECT_EQ(0u, sequencer_->frames()->size());
181}
182
183TEST_F(QuicStreamSequencerTest, OutOfOrderFramesProcessedWithBuffering) {
184 sequencer_->SetMemoryLimit(9);
185
186 // Too far to buffer.
187 EXPECT_FALSE(sequencer_->OnFrame(9, "jkl", 3));
188
189 // We can afford to buffer this.
190 EXPECT_TRUE(sequencer_->OnFrame(6, "ghi", 3));
191 EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
192
193 InSequence s;
194 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3));
195
196 // Ack right away
197 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
198 EXPECT_EQ(3u, sequencer_->num_bytes_consumed());
199
200 // We should be willing to buffer this now.
201 EXPECT_TRUE(sequencer_->OnFrame(9, "jkl", 3));
202 EXPECT_EQ(3u, sequencer_->num_bytes_consumed());
203
204 EXPECT_CALL(stream_, ProcessData(StrEq("def"), 3)).WillOnce(Return(3));
205 EXPECT_CALL(stream_, ProcessData(StrEq("ghi"), 3)).WillOnce(Return(3));
206 EXPECT_CALL(stream_, ProcessData(StrEq("jkl"), 3)).WillOnce(Return(3));
207
208 EXPECT_TRUE(sequencer_->OnFrame(3, "def", 3));
209 EXPECT_EQ(12u, sequencer_->num_bytes_consumed());
210 EXPECT_EQ(0u, sequencer_->frames()->size());
211}
212
213TEST_F(QuicStreamSequencerTest, BasicCloseOrdered) {
214 InSequence s;
215 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3));
216 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
217
218 EXPECT_CALL(stream_, TerminateFromPeer(false));
219 sequencer_->CloseStreamAtOffset(3, false);
220 EXPECT_EQ(3u, sequencer_->close_offset());
221}
222
223TEST_F(QuicStreamSequencerTest, BasicHalfOrdered) {
224 InSequence s;
225
226 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3));
227 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
228
229 EXPECT_CALL(stream_, TerminateFromPeer(true));
230 sequencer_->CloseStreamAtOffset(3, true);
231 EXPECT_EQ(3u, sequencer_->close_offset());
232}
233
234TEST_F(QuicStreamSequencerTest, BasicCloseUnordered) {
235 sequencer_->CloseStreamAtOffset(3, false);
236 EXPECT_EQ(3u, sequencer_->close_offset());
237
238 InSequence s;
239 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3));
240 EXPECT_CALL(stream_, TerminateFromPeer(false));
241
242 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
243}
244
245TEST_F(QuicStreamSequencerTest, BasicHalfUnorderedWithFlush) {
246 sequencer_->CloseStreamAtOffset(6, true);
247 EXPECT_EQ(6u, sequencer_->close_offset());
248 InSequence s;
249 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3));
250 EXPECT_CALL(stream_, ProcessData(StrEq("def"), 3)).WillOnce(Return(3));
251 EXPECT_CALL(stream_, TerminateFromPeer(true));
252
253 EXPECT_TRUE(sequencer_->OnFrame(3, "def", 3));
254 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
255}
256
257TEST_F(QuicStreamSequencerTest, BasicCloseUnorderedWithFlush) {
258 sequencer_->CloseStreamAtOffset(6, false);
259 EXPECT_EQ(6u, sequencer_->close_offset());
260
261 InSequence s;
262 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3));
263 EXPECT_CALL(stream_, ProcessData(StrEq("def"), 3)).WillOnce(Return(3));
264 EXPECT_CALL(stream_, TerminateFromPeer(false));
265
266 EXPECT_TRUE(sequencer_->OnFrame(3, "def", 3));
267 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
268}
269
270TEST_F(QuicStreamSequencerTest, BasicHalfUnordered) {
271 sequencer_->CloseStreamAtOffset(3, true);
272 EXPECT_EQ(3u, sequencer_->close_offset());
273 InSequence s;
274 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3));
275 EXPECT_CALL(stream_, TerminateFromPeer(true));
276
277 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
278}
279
[email protected]044ac2b2012-11-13 21:41:06280TEST_F(QuicStreamSequencerTest, TerminateStreamBeforeCloseEqual) {
[email protected]9c0b1352012-11-04 00:03:27281 sequencer_->CloseStreamAtOffset(3, true);
282 EXPECT_EQ(3u, sequencer_->close_offset());
283
284 sequencer_->CloseStreamAtOffset(3, false);
285 EXPECT_EQ(3u, sequencer_->close_offset());
286
287 InSequence s;
288 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3));
289 EXPECT_CALL(stream_, TerminateFromPeer(false));
290 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
291}
292
293TEST_F(QuicStreamSequencerTest, CloseBeforeTermianteEqual) {
294 sequencer_->CloseStreamAtOffset(3, false);
295 EXPECT_EQ(3u, sequencer_->close_offset());
296
297 sequencer_->CloseStreamAtOffset(3, true);
298 EXPECT_EQ(3u, sequencer_->close_offset());
299
300 InSequence s;
301 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3));
302 EXPECT_CALL(stream_, TerminateFromPeer(false));
303 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
304}
305
306TEST_F(QuicStreamSequencerTest, MutipleOffsets) {
307 sequencer_->CloseStreamAtOffset(3, false);
308 EXPECT_EQ(3u, sequencer_->close_offset());
309
310 EXPECT_CALL(stream_, Close(QUIC_MULTIPLE_TERMINATION_OFFSETS));
311 sequencer_->CloseStreamAtOffset(5, false);
312 EXPECT_EQ(3u, sequencer_->close_offset());
313
314 EXPECT_CALL(stream_, Close(QUIC_MULTIPLE_TERMINATION_OFFSETS));
315 sequencer_->CloseStreamAtOffset(1, false);
316 EXPECT_EQ(3u, sequencer_->close_offset());
317
318 sequencer_->CloseStreamAtOffset(3, false);
319 EXPECT_EQ(3u, sequencer_->close_offset());
320}
321
322class QuicSequencerRandomTest : public QuicStreamSequencerTest {
323 public:
324 typedef pair<int, string> Frame;
325 typedef vector<Frame> FrameList;
326
327 void CreateFrames() {
328 int payload_size = arraysize(kPayload) - 1;
329 int remaining_payload = payload_size;
330 while (remaining_payload != 0) {
331 int size = min(OneToN(6), remaining_payload);
[email protected]044ac2b2012-11-13 21:41:06332 int index = payload_size - remaining_payload;
333 list_.push_back(make_pair(index, string(kPayload + index, size)));
[email protected]9c0b1352012-11-04 00:03:27334 remaining_payload -= size;
335 }
336 }
337
338 QuicSequencerRandomTest() {
[email protected]9c0b1352012-11-04 00:03:27339 CreateFrames();
340 }
341
342 int OneToN(int n) {
343 return base::RandInt(1, n);
344 }
345
346 int MaybeProcessMaybeBuffer(const char* data, uint32 len) {
347 int to_process = len;
348 if (base::RandUint64() % 2 != 0) {
349 to_process = base::RandInt(0, len);
350 }
351 output_.append(data, to_process);
[email protected]9c0b1352012-11-04 00:03:27352 return to_process;
353 }
354
355 string output_;
[email protected]9c0b1352012-11-04 00:03:27356 FrameList list_;
357};
358
359// All frames are processed as soon as we have sequential data.
360// Infinite buffering, so all frames are acked right away.
361TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingNoBackup) {
362 InSequence s;
363 for (size_t i = 0; i < list_.size(); ++i) {
364 string* data = &list_[i].second;
365 EXPECT_CALL(stream_, ProcessData(StrEq(*data), data->size()))
366 .WillOnce(Return(data->size()));
367 }
368
369 while (list_.size() != 0) {
[email protected]044ac2b2012-11-13 21:41:06370 int index = OneToN(list_.size()) - 1;
371 LOG(ERROR) << "Sending index " << index << " "
372 << list_[index].second.data();
[email protected]9c0b1352012-11-04 00:03:27373 EXPECT_TRUE(sequencer_->OnFrame(
[email protected]044ac2b2012-11-13 21:41:06374 list_[index].first, list_[index].second.data(),
375 list_[index].second.size()));
376 list_.erase(list_.begin() + index);
[email protected]9c0b1352012-11-04 00:03:27377 }
378}
379
380// All frames are processed as soon as we have sequential data.
381// Buffering, so some frames are rejected.
382TEST_F(QuicSequencerRandomTest, RandomFramesDroppingNoBackup) {
383 sequencer_->SetMemoryLimit(26);
384
385 InSequence s;
386 for (size_t i = 0; i < list_.size(); ++i) {
387 string* data = &list_[i].second;
388 EXPECT_CALL(stream_, ProcessData(StrEq(*data), data->size()))
389 .WillOnce(Return(data->size()));
390 }
391
392 while (list_.size() != 0) {
[email protected]044ac2b2012-11-13 21:41:06393 int index = OneToN(list_.size()) - 1;
394 LOG(ERROR) << "Sending index " << index << " "
395 << list_[index].second.data();
[email protected]9c0b1352012-11-04 00:03:27396 bool acked = sequencer_->OnFrame(
[email protected]044ac2b2012-11-13 21:41:06397 list_[index].first, list_[index].second.data(),
398 list_[index].second.size());
[email protected]9c0b1352012-11-04 00:03:27399 if (acked) {
[email protected]044ac2b2012-11-13 21:41:06400 list_.erase(list_.begin() + index);
[email protected]9c0b1352012-11-04 00:03:27401 }
402 }
403}
404
405} // namespace
406
407} // namespace net