blob: 787d8f51ebec306791251b1daf9e24a385ced733 [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 {
[email protected]b1f287d2012-12-22 17:25:3926namespace test {
[email protected]9c0b1352012-11-04 00:03:2727
28class QuicStreamSequencerPeer : public QuicStreamSequencer {
29 public:
30 explicit QuicStreamSequencerPeer(ReliableQuicStream* stream)
31 : QuicStreamSequencer(stream) {
32 }
33
34 QuicStreamSequencerPeer(int32 max_mem, ReliableQuicStream* stream)
35 : QuicStreamSequencer(max_mem, stream) {}
36
37 virtual bool OnFrame(QuicStreamOffset byte_offset,
[email protected]044ac2b2012-11-13 21:41:0638 const char* data,
39 uint32 data_len) {
[email protected]9c0b1352012-11-04 00:03:2740 QuicStreamFrame frame;
41 frame.stream_id = 1;
42 frame.offset = byte_offset;
43 frame.data = StringPiece(data, data_len);
44 return OnStreamFrame(frame);
45 }
46
47 void SetMemoryLimit(size_t limit) {
48 max_frame_memory_ = limit;
49 }
50
[email protected]2ff600a2012-11-11 19:22:1951 const ReliableQuicStream* stream() const { return stream_; }
52 uint64 num_bytes_consumed() const { return num_bytes_consumed_; }
53 const FrameMap* frames() const { return &frames_; }
54 int32 max_frame_memory() const { return max_frame_memory_; }
55 QuicStreamOffset close_offset() const { return close_offset_; }
[email protected]9c0b1352012-11-04 00:03:2756};
57
58class MockStream : public ReliableQuicStream {
59 public:
60 MockStream(QuicSession* session, QuicStreamId id)
61 : ReliableQuicStream(id, session) {
62 }
63
64 MOCK_METHOD1(TerminateFromPeer, void(bool half_close));
65 MOCK_METHOD2(ProcessData, uint32(const char* data, uint32 data_len));
[email protected]74bda142013-03-31 02:49:1166 MOCK_METHOD1(Close, void(QuicRstStreamErrorCode error));
[email protected]a5d4eee22012-12-13 09:09:0167 MOCK_METHOD0(OnCanWrite, void());
[email protected]9c0b1352012-11-04 00:03:2768};
69
70namespace {
71
72static const char kPayload[] =
73 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
74
75class QuicStreamSequencerTest : public ::testing::Test {
76 protected:
77 QuicStreamSequencerTest()
78 : session_(NULL),
79 stream_(session_, 1),
80 sequencer_(new QuicStreamSequencerPeer(&stream_)) {
81 }
82
83 QuicSession* session_;
84 testing::StrictMock<MockStream> stream_;
85 scoped_ptr<QuicStreamSequencerPeer> sequencer_;
86};
87
88TEST_F(QuicStreamSequencerTest, RejectOldFrame) {
89 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3))
90 .WillOnce(Return(3));
91
92 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
93 EXPECT_EQ(0u, sequencer_->frames()->size());
94 EXPECT_EQ(3u, sequencer_->num_bytes_consumed());
[email protected]9db443912013-02-25 05:27:0395 // Ignore this - it matches a past sequence number and we should not see it
[email protected]9c0b1352012-11-04 00:03:2796 // again.
[email protected]9db443912013-02-25 05:27:0397 EXPECT_TRUE(sequencer_->OnFrame(0, "def", 3));
[email protected]9c0b1352012-11-04 00:03:2798 EXPECT_EQ(0u, sequencer_->frames()->size());
99}
100
101TEST_F(QuicStreamSequencerTest, RejectOverlyLargeFrame) {
102 /*
103 EXPECT_DFATAL(sequencer_.reset(new QuicStreamSequencerPeer(2, &stream_)),
104 "Setting max frame memory to 2. "
105 "Some frames will be impossible to handle.");
106
107 EXPECT_DEBUG_DEATH(sequencer_->OnFrame(0, "abc", 3), "");
108 */
109}
110
111TEST_F(QuicStreamSequencerTest, DropFramePastBuffering) {
112 sequencer_->SetMemoryLimit(3);
113
114 EXPECT_FALSE(sequencer_->OnFrame(3, "abc", 3));
115}
116
117TEST_F(QuicStreamSequencerTest, RejectBufferedFrame) {
118 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3));
119
120 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
121 EXPECT_EQ(1u, sequencer_->frames()->size());
122 EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
123 // Ignore this - it matches a buffered frame.
124 // Right now there's no checking that the payload is consistent.
[email protected]9db443912013-02-25 05:27:03125 EXPECT_TRUE(sequencer_->OnFrame(0, "def", 3));
[email protected]9c0b1352012-11-04 00:03:27126 EXPECT_EQ(1u, sequencer_->frames()->size());
127}
128
129TEST_F(QuicStreamSequencerTest, FullFrameConsumed) {
[email protected]044ac2b2012-11-13 21:41:06130 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3));
[email protected]9c0b1352012-11-04 00:03:27131
132 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
133 EXPECT_EQ(0u, sequencer_->frames()->size());
134 EXPECT_EQ(3u, sequencer_->num_bytes_consumed());
135}
136
137TEST_F(QuicStreamSequencerTest, PartialFrameConsumed) {
[email protected]044ac2b2012-11-13 21:41:06138 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(2));
[email protected]9c0b1352012-11-04 00:03:27139
140 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
141 EXPECT_EQ(1u, sequencer_->frames()->size());
142 EXPECT_EQ(2u, sequencer_->num_bytes_consumed());
143 EXPECT_EQ("c", sequencer_->frames()->find(2)->second);
144}
145
146TEST_F(QuicStreamSequencerTest, NextxFrameNotConsumed) {
[email protected]044ac2b2012-11-13 21:41:06147 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(0));
[email protected]9c0b1352012-11-04 00:03:27148
149 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
150 EXPECT_EQ(1u, sequencer_->frames()->size());
151 EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
152 EXPECT_EQ("abc", sequencer_->frames()->find(0)->second);
153}
154
155TEST_F(QuicStreamSequencerTest, FutureFrameNotProcessed) {
156 EXPECT_TRUE(sequencer_->OnFrame(3, "abc", 3));
157 EXPECT_EQ(1u, sequencer_->frames()->size());
158 EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
159 EXPECT_EQ("abc", sequencer_->frames()->find(3)->second);
160}
161
162TEST_F(QuicStreamSequencerTest, OutOfOrderFrameProcessed) {
163 // Buffer the first
164 EXPECT_TRUE(sequencer_->OnFrame(6, "ghi", 3));
165 EXPECT_EQ(1u, sequencer_->frames()->size());
166 EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
167 // Buffer the second
168 EXPECT_TRUE(sequencer_->OnFrame(3, "def", 3));
169 EXPECT_EQ(2u, sequencer_->frames()->size());
170 EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
171
172 InSequence s;
173 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3));
174 EXPECT_CALL(stream_, ProcessData(StrEq("def"), 3)).WillOnce(Return(3));
175 EXPECT_CALL(stream_, ProcessData(StrEq("ghi"), 3)).WillOnce(Return(3));
176
177 // Ack right away
178 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
179 EXPECT_EQ(9u, sequencer_->num_bytes_consumed());
180
181 EXPECT_EQ(0u, sequencer_->frames()->size());
182}
183
184TEST_F(QuicStreamSequencerTest, OutOfOrderFramesProcessedWithBuffering) {
185 sequencer_->SetMemoryLimit(9);
186
187 // Too far to buffer.
188 EXPECT_FALSE(sequencer_->OnFrame(9, "jkl", 3));
189
190 // We can afford to buffer this.
191 EXPECT_TRUE(sequencer_->OnFrame(6, "ghi", 3));
192 EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
193
194 InSequence s;
195 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3));
196
197 // Ack right away
198 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
199 EXPECT_EQ(3u, sequencer_->num_bytes_consumed());
200
201 // We should be willing to buffer this now.
202 EXPECT_TRUE(sequencer_->OnFrame(9, "jkl", 3));
203 EXPECT_EQ(3u, sequencer_->num_bytes_consumed());
204
205 EXPECT_CALL(stream_, ProcessData(StrEq("def"), 3)).WillOnce(Return(3));
206 EXPECT_CALL(stream_, ProcessData(StrEq("ghi"), 3)).WillOnce(Return(3));
207 EXPECT_CALL(stream_, ProcessData(StrEq("jkl"), 3)).WillOnce(Return(3));
208
209 EXPECT_TRUE(sequencer_->OnFrame(3, "def", 3));
210 EXPECT_EQ(12u, sequencer_->num_bytes_consumed());
211 EXPECT_EQ(0u, sequencer_->frames()->size());
212}
213
214TEST_F(QuicStreamSequencerTest, BasicCloseOrdered) {
215 InSequence s;
216 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3));
217 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
218
219 EXPECT_CALL(stream_, TerminateFromPeer(false));
220 sequencer_->CloseStreamAtOffset(3, false);
221 EXPECT_EQ(3u, sequencer_->close_offset());
222}
223
224TEST_F(QuicStreamSequencerTest, BasicHalfOrdered) {
225 InSequence s;
226
227 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3));
228 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
229
230 EXPECT_CALL(stream_, TerminateFromPeer(true));
231 sequencer_->CloseStreamAtOffset(3, true);
232 EXPECT_EQ(3u, sequencer_->close_offset());
233}
234
235TEST_F(QuicStreamSequencerTest, BasicCloseUnordered) {
236 sequencer_->CloseStreamAtOffset(3, false);
237 EXPECT_EQ(3u, sequencer_->close_offset());
238
239 InSequence s;
240 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3));
241 EXPECT_CALL(stream_, TerminateFromPeer(false));
242
243 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
244}
245
246TEST_F(QuicStreamSequencerTest, BasicHalfUnorderedWithFlush) {
247 sequencer_->CloseStreamAtOffset(6, true);
248 EXPECT_EQ(6u, sequencer_->close_offset());
249 InSequence s;
250 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3));
251 EXPECT_CALL(stream_, ProcessData(StrEq("def"), 3)).WillOnce(Return(3));
252 EXPECT_CALL(stream_, TerminateFromPeer(true));
253
254 EXPECT_TRUE(sequencer_->OnFrame(3, "def", 3));
255 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
256}
257
258TEST_F(QuicStreamSequencerTest, BasicCloseUnorderedWithFlush) {
259 sequencer_->CloseStreamAtOffset(6, false);
260 EXPECT_EQ(6u, sequencer_->close_offset());
261
262 InSequence s;
263 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3));
264 EXPECT_CALL(stream_, ProcessData(StrEq("def"), 3)).WillOnce(Return(3));
265 EXPECT_CALL(stream_, TerminateFromPeer(false));
266
267 EXPECT_TRUE(sequencer_->OnFrame(3, "def", 3));
268 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
269}
270
271TEST_F(QuicStreamSequencerTest, BasicHalfUnordered) {
272 sequencer_->CloseStreamAtOffset(3, true);
273 EXPECT_EQ(3u, sequencer_->close_offset());
274 InSequence s;
275 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3));
276 EXPECT_CALL(stream_, TerminateFromPeer(true));
277
278 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
279}
280
[email protected]044ac2b2012-11-13 21:41:06281TEST_F(QuicStreamSequencerTest, TerminateStreamBeforeCloseEqual) {
[email protected]9c0b1352012-11-04 00:03:27282 sequencer_->CloseStreamAtOffset(3, true);
283 EXPECT_EQ(3u, sequencer_->close_offset());
284
285 sequencer_->CloseStreamAtOffset(3, false);
286 EXPECT_EQ(3u, sequencer_->close_offset());
287
288 InSequence s;
289 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3));
290 EXPECT_CALL(stream_, TerminateFromPeer(false));
291 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
292}
293
294TEST_F(QuicStreamSequencerTest, CloseBeforeTermianteEqual) {
295 sequencer_->CloseStreamAtOffset(3, false);
296 EXPECT_EQ(3u, sequencer_->close_offset());
297
298 sequencer_->CloseStreamAtOffset(3, true);
299 EXPECT_EQ(3u, sequencer_->close_offset());
300
301 InSequence s;
302 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3));
303 EXPECT_CALL(stream_, TerminateFromPeer(false));
304 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3));
305}
306
307TEST_F(QuicStreamSequencerTest, MutipleOffsets) {
308 sequencer_->CloseStreamAtOffset(3, false);
309 EXPECT_EQ(3u, sequencer_->close_offset());
310
311 EXPECT_CALL(stream_, Close(QUIC_MULTIPLE_TERMINATION_OFFSETS));
312 sequencer_->CloseStreamAtOffset(5, false);
313 EXPECT_EQ(3u, sequencer_->close_offset());
314
315 EXPECT_CALL(stream_, Close(QUIC_MULTIPLE_TERMINATION_OFFSETS));
316 sequencer_->CloseStreamAtOffset(1, false);
317 EXPECT_EQ(3u, sequencer_->close_offset());
318
319 sequencer_->CloseStreamAtOffset(3, false);
320 EXPECT_EQ(3u, sequencer_->close_offset());
321}
322
323class QuicSequencerRandomTest : public QuicStreamSequencerTest {
324 public:
325 typedef pair<int, string> Frame;
326 typedef vector<Frame> FrameList;
327
328 void CreateFrames() {
329 int payload_size = arraysize(kPayload) - 1;
330 int remaining_payload = payload_size;
331 while (remaining_payload != 0) {
332 int size = min(OneToN(6), remaining_payload);
[email protected]044ac2b2012-11-13 21:41:06333 int index = payload_size - remaining_payload;
334 list_.push_back(make_pair(index, string(kPayload + index, size)));
[email protected]9c0b1352012-11-04 00:03:27335 remaining_payload -= size;
336 }
337 }
338
339 QuicSequencerRandomTest() {
[email protected]9c0b1352012-11-04 00:03:27340 CreateFrames();
341 }
342
343 int OneToN(int n) {
344 return base::RandInt(1, n);
345 }
346
347 int MaybeProcessMaybeBuffer(const char* data, uint32 len) {
348 int to_process = len;
349 if (base::RandUint64() % 2 != 0) {
350 to_process = base::RandInt(0, len);
351 }
352 output_.append(data, to_process);
[email protected]9c0b1352012-11-04 00:03:27353 return to_process;
354 }
355
356 string output_;
[email protected]9c0b1352012-11-04 00:03:27357 FrameList list_;
358};
359
360// All frames are processed as soon as we have sequential data.
361// Infinite buffering, so all frames are acked right away.
362TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingNoBackup) {
363 InSequence s;
364 for (size_t i = 0; i < list_.size(); ++i) {
365 string* data = &list_[i].second;
366 EXPECT_CALL(stream_, ProcessData(StrEq(*data), data->size()))
367 .WillOnce(Return(data->size()));
368 }
369
370 while (list_.size() != 0) {
[email protected]044ac2b2012-11-13 21:41:06371 int index = OneToN(list_.size()) - 1;
372 LOG(ERROR) << "Sending index " << index << " "
373 << list_[index].second.data();
[email protected]9c0b1352012-11-04 00:03:27374 EXPECT_TRUE(sequencer_->OnFrame(
[email protected]044ac2b2012-11-13 21:41:06375 list_[index].first, list_[index].second.data(),
376 list_[index].second.size()));
377 list_.erase(list_.begin() + index);
[email protected]9c0b1352012-11-04 00:03:27378 }
379}
380
381// All frames are processed as soon as we have sequential data.
382// Buffering, so some frames are rejected.
383TEST_F(QuicSequencerRandomTest, RandomFramesDroppingNoBackup) {
384 sequencer_->SetMemoryLimit(26);
385
386 InSequence s;
387 for (size_t i = 0; i < list_.size(); ++i) {
388 string* data = &list_[i].second;
389 EXPECT_CALL(stream_, ProcessData(StrEq(*data), data->size()))
390 .WillOnce(Return(data->size()));
391 }
392
393 while (list_.size() != 0) {
[email protected]044ac2b2012-11-13 21:41:06394 int index = OneToN(list_.size()) - 1;
395 LOG(ERROR) << "Sending index " << index << " "
396 << list_[index].second.data();
[email protected]9c0b1352012-11-04 00:03:27397 bool acked = sequencer_->OnFrame(
[email protected]044ac2b2012-11-13 21:41:06398 list_[index].first, list_[index].second.data(),
399 list_[index].second.size());
[email protected]9c0b1352012-11-04 00:03:27400 if (acked) {
[email protected]044ac2b2012-11-13 21:41:06401 list_.erase(list_.begin() + index);
[email protected]9c0b1352012-11-04 00:03:27402 }
403 }
404}
405
406} // namespace
[email protected]b1f287d2012-12-22 17:25:39407} // namespace test
[email protected]9c0b1352012-11-04 00:03:27408} // namespace net