Skip to content

Commit 0f61e93

Browse files
committed
increase unit test coverage
1 parent 2a0b700 commit 0f61e93

File tree

6 files changed

+368
-212
lines changed

6 files changed

+368
-212
lines changed

quic/s2n-quic-core/src/buffer/duplex/split.rs

+100-40
Original file line numberDiff line numberDiff line change
@@ -182,85 +182,145 @@ mod tests {
182182
};
183183

184184
#[test]
185-
fn split_test() {
185+
fn undersized_storage_test() {
186186
let mut duplex = Reassembler::default();
187-
let mut reader = Data::new(10_000);
187+
let mut reader = Data::new(10);
188188
let mut checker = reader;
189189

190+
let mut storage: Vec<u8> = vec![];
190191
{
191-
let mut storage: Vec<u8> = vec![];
192+
// limit the storage capacity so we force writing into the duplex
193+
let mut storage = storage.with_write_limit(1);
192194

193195
let mut split = Split::new(&mut storage, &mut duplex);
194196

195-
let mut reader = reader.with_read_limit(5);
196197
split.read_from(&mut reader).unwrap();
198+
}
197199

198-
assert_eq!(storage.len(), 5);
199-
assert_eq!(duplex.current_offset().as_u64(), 5);
200+
// the storage was too small so we delegated to duplex
201+
assert!(storage.is_empty());
202+
assert_eq!(duplex.buffered_len(), 10);
200203

201-
checker.receive(&[&storage[..]]);
202-
}
204+
// move the reassembled bytes into the checker
205+
checker.read_from(&mut duplex).unwrap();
206+
assert_eq!(duplex.current_offset().as_u64(), 10);
207+
assert!(duplex.is_consumed());
208+
}
209+
210+
#[test]
211+
fn out_of_order_test() {
212+
let mut duplex = Reassembler::default();
203213

214+
// first write 5 bytes at offset 5
204215
{
205-
let mut storage = writer::storage::Empty;
216+
let mut reader = Data::new(10);
217+
218+
// advance the reader by 5 bytes
219+
let _ = reader.send_one(5);
220+
221+
let mut storage: Vec<u8> = vec![];
206222

207223
let mut split = Split::new(&mut storage, &mut duplex);
208224

209-
let mut reader = reader.with_read_limit(5);
210225
split.read_from(&mut reader).unwrap();
211226

212-
assert_eq!(duplex.current_offset().as_u64(), 5);
213-
assert_eq!(duplex.len(), 5);
227+
// make sure we consumed the reader
228+
assert_eq!(reader.current_offset().as_u64(), 10);
229+
230+
assert_eq!(split.current_offset().as_u64(), 0);
231+
assert_eq!(split.buffered_len(), 0);
232+
233+
// make sure we didn't write to the storage, even if we had capacity, since the
234+
// current_offset doesn't match
235+
assert!(storage.is_empty());
214236
}
215237

238+
// then write 10 bytes at offset 0
216239
{
240+
let mut reader = Data::new(10);
241+
217242
let mut storage: Vec<u8> = vec![];
218243

219244
let mut split = Split::new(&mut storage, &mut duplex);
220245

221-
let mut reader = reader.with_read_limit(5);
222246
split.read_from(&mut reader).unwrap();
223247

224-
// make sure we didn't write to the storage, even if we had capacity, since the
225-
// current_offset doesn't match
226-
assert!(storage.is_empty());
227-
assert_eq!(duplex.current_offset().as_u64(), 5);
248+
// make sure we consumed the reader
249+
assert_eq!(reader.current_offset().as_u64(), 10);
228250

229-
// move the reassembled bytes into the checker
230-
checker.read_from(&mut duplex).unwrap();
231-
assert_eq!(duplex.current_offset().as_u64(), 15);
251+
assert_eq!(split.current_offset().as_u64(), 10);
252+
assert_eq!(split.buffered_len(), 0);
253+
254+
// make sure we copied the entire reader
255+
assert_eq!(storage.len(), 10);
256+
assert!(duplex.is_consumed());
232257
}
258+
}
233259

234-
{
235-
let mut storage: Vec<u8> = vec![];
236-
{
237-
let mut storage = storage.with_write_limit(1);
260+
#[test]
261+
fn skip_test() {
262+
let mut duplex = Reassembler::default();
263+
let mut reader = Data::new(10);
264+
let mut checker = reader;
238265

239-
let mut split = Split::new(&mut storage, &mut duplex);
266+
let mut storage: Vec<u8> = vec![];
240267

241-
let mut reader = reader.with_read_limit(10);
242-
split.read_from(&mut reader).unwrap();
243-
}
268+
let mut split = Split::new(&mut storage, &mut duplex);
244269

245-
// the storage was too small so we delegated to duplex
246-
assert!(storage.is_empty());
247-
assert_eq!(duplex.len(), 10);
270+
split.read_from(&mut reader).unwrap();
248271

249-
// move the reassembled bytes into the checker
250-
checker.read_from(&mut duplex).unwrap();
251-
assert_eq!(duplex.current_offset().as_u64(), 25);
252-
}
272+
assert_eq!(storage.len(), 10);
273+
assert_eq!(duplex.current_offset().as_u64(), 10);
274+
275+
checker.receive(&[&storage[..]]);
276+
}
277+
278+
#[test]
279+
fn empty_storage_test() {
280+
let mut duplex = Reassembler::default();
281+
let mut reader = Data::new(10);
282+
let mut checker = reader;
283+
284+
let mut storage = writer::storage::Empty;
285+
286+
let mut split = Split::new(&mut storage, &mut duplex);
253287

288+
split.read_from(&mut reader).unwrap();
289+
290+
assert_eq!(split.current_offset().as_u64(), 0);
291+
assert_eq!(split.buffered_len(), 10);
292+
293+
checker.read_from(&mut split).unwrap();
294+
295+
assert_eq!(split.current_offset().as_u64(), 10);
296+
assert!(split.buffer_is_empty());
297+
assert_eq!(split.buffered_len(), 0);
298+
assert!(split.is_consumed());
299+
}
300+
301+
#[test]
302+
fn partial_test() {
303+
let mut duplex = Reassembler::default();
304+
let mut reader = Data::new(10);
305+
let mut checker = reader;
306+
307+
let mut storage: Vec<u8> = vec![];
254308
{
255-
let mut storage = writer::storage::Empty;
309+
let mut storage = storage.with_write_limit(9);
256310

257311
let mut split = Split::new(&mut storage, &mut duplex);
258312

259-
let mut reader = reader.with_read_limit(1);
260313
split.read_from(&mut reader).unwrap();
261-
262-
assert_eq!(duplex.current_offset().as_u64(), 25);
263-
assert_eq!(duplex.len(), 1);
264314
}
315+
316+
// the storage was at least half the reader
317+
assert_eq!(storage.len(), 9);
318+
assert_eq!(duplex.buffered_len(), 1);
319+
320+
// move the reassembled bytes into the checker
321+
checker.receive(&[&storage]);
322+
checker.read_from(&mut duplex).unwrap();
323+
assert_eq!(duplex.current_offset().as_u64(), 10);
324+
assert!(duplex.is_consumed());
265325
}
266326
}

quic/s2n-quic-core/src/buffer/reader/checked.rs

+10
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ where
4949
self.inner.buffered_len()
5050
}
5151

52+
#[inline(always)]
53+
fn buffer_is_empty(&self) -> bool {
54+
self.inner.buffer_is_empty()
55+
}
56+
5257
#[inline(always)]
5358
fn read_chunk(&mut self, watermark: usize) -> Result<super::storage::Chunk<'_>, Self::Error> {
5459
self.inner.read_chunk(watermark)
@@ -86,6 +91,11 @@ where
8691
self.inner.buffered_len()
8792
}
8893

94+
#[inline]
95+
fn buffer_is_empty(&self) -> bool {
96+
self.inner.buffer_is_empty()
97+
}
98+
8999
#[inline]
90100
fn read_chunk(&mut self, watermark: usize) -> Result<super::storage::Chunk<'_>, Self::Error> {
91101
let snapshot = Snapshot::new(self.inner, watermark);

quic/s2n-quic-core/src/buffer/reader/complete.rs

+42-6
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,6 @@ where
3434
final_offset,
3535
})
3636
}
37-
38-
#[inline]
39-
pub fn is_empty(&self) -> bool {
40-
self.storage.buffer_is_empty()
41-
}
4237
}
4338

4439
impl<'a, S> Storage for Complete<'a, S>
@@ -52,6 +47,11 @@ where
5247
self.storage.buffered_len()
5348
}
5449

50+
#[inline]
51+
fn buffer_is_empty(&self) -> bool {
52+
self.storage.buffer_is_empty()
53+
}
54+
5555
#[inline]
5656
fn read_chunk(&mut self, watermark: usize) -> Result<Chunk, Self::Error> {
5757
let chunk = self.storage.read_chunk(watermark)?;
@@ -103,7 +103,23 @@ mod tests {
103103
use super::*;
104104

105105
#[test]
106-
fn complete_test() {
106+
fn read_chunk_test() {
107+
let mut storage: &[u8] = &[1, 2, 3, 4];
108+
let mut reader = Complete::new(&mut storage).unwrap();
109+
let mut reader = reader.with_checks();
110+
111+
assert_eq!(reader.current_offset(), VarInt::ZERO);
112+
assert_eq!(reader.final_offset(), Some(VarInt::from_u8(4)));
113+
114+
let chunk = reader.read_chunk(usize::MAX).unwrap();
115+
assert_eq!(&*chunk, &[1, 2, 3, 4]);
116+
117+
assert_eq!(reader.current_offset(), VarInt::from_u8(4));
118+
assert!(reader.buffer_is_empty());
119+
}
120+
121+
#[test]
122+
fn partial_copy_test() {
107123
let mut storage: &[u8] = &[1, 2, 3, 4];
108124
let mut reader = Complete::new(&mut storage).unwrap();
109125
let mut reader = reader.with_checks();
@@ -118,4 +134,24 @@ mod tests {
118134
assert_eq!(reader.current_offset(), VarInt::from_u8(4));
119135
assert!(reader.buffer_is_empty());
120136
}
137+
138+
#[test]
139+
fn copy_test() {
140+
let mut storage: &[u8] = &[1, 2, 3, 4];
141+
let mut reader = Complete::new(&mut storage).unwrap();
142+
let mut reader = reader.with_checks();
143+
144+
assert_eq!(reader.current_offset(), VarInt::ZERO);
145+
assert_eq!(reader.final_offset(), Some(VarInt::from_u8(4)));
146+
147+
let mut dest = [0; 4];
148+
{
149+
let mut dest = &mut dest[..];
150+
reader.copy_into(&mut dest).unwrap();
151+
}
152+
assert_eq!(&dest[..], &[1, 2, 3, 4]);
153+
154+
assert_eq!(reader.current_offset(), VarInt::from_u8(4));
155+
assert!(reader.buffer_is_empty());
156+
}
121157
}

quic/s2n-quic-core/src/buffer/reader/incremental.rs

+15
Original file line numberDiff line numberDiff line change
@@ -157,5 +157,20 @@ mod tests {
157157
}
158158

159159
assert_eq!(incremental.current_offset(), VarInt::from_u8(4));
160+
161+
{
162+
let mut chunk: &[u8] = &[5, 6, 7, 8];
163+
let mut reader = incremental.with_storage(&mut chunk, true).unwrap();
164+
let mut reader = reader.with_checks();
165+
166+
assert_eq!(reader.buffered_len(), 4);
167+
168+
let trailing_chunk = reader.read_chunk(usize::MAX).unwrap();
169+
assert_eq!(&*trailing_chunk, &[5, 6, 7, 8]);
170+
171+
assert_eq!(reader.buffered_len(), 0);
172+
assert!(reader.buffer_is_empty());
173+
assert!(reader.is_consumed());
174+
}
160175
}
161176
}

0 commit comments

Comments
 (0)