move MockFile section after blackbox test

This commit is contained in:
Christian Schwarz
2024-08-20 13:28:26 +00:00
parent c047d01850
commit c6f4fce1b4

View File

@@ -279,6 +279,99 @@ mod tests {
use super::*;
use std::{cell::RefCell, collections::VecDeque};
struct InMemoryFile {
content: Vec<u8>,
}
impl InMemoryFile {
fn new_random(len: usize) -> Self {
Self {
content: rand::thread_rng()
.sample_iter(rand::distributions::Standard)
.take(len)
.collect(),
}
}
fn test_value_read(&self, pos: u32, len: usize) -> TestValueRead {
let expected_result = self.content[pos as usize..pos as usize + len].to_vec();
TestValueRead {
pos,
expected_result,
}
}
}
impl File for InMemoryFile {
async fn read_at_to_end<'a, 'b, B: IoBufMut + Send>(
&'b self,
start: u32,
mut dst: Slice<B>,
_ctx: &'a RequestContext,
) -> std::io::Result<(Slice<B>, usize)> {
let len = std::cmp::min(
dst.bytes_total(),
self.content.len().saturating_sub(start as usize),
);
let dst_slice: &mut [u8] = dst.as_mut_rust_slice_full_zeroed();
dst_slice[..len].copy_from_slice(&self.content[start as usize..start as usize + len]);
rand::Rng::fill(&mut rand::thread_rng(), &mut dst_slice[len..]); // to discover bugs
Ok((dst, len))
}
}
#[derive(Debug)]
struct TestValueRead {
pos: u32,
expected_result: Vec<u8>,
}
impl TestValueRead {
fn make_value_read(&self) -> ValueRead<Vec<u8>> {
ValueRead::new(self.pos, Vec::with_capacity(self.expected_result.len()))
}
}
#[tokio::test]
async fn test_blackbox() {
let ctx = RequestContext::new(TaskKind::UnitTest, DownloadBehavior::Error);
let cs = DIO_CHUNK_SIZE;
let cs_u32 = u32::try_from(cs).unwrap();
let file = InMemoryFile::new_random(10 * cs);
let test_value_reads = vec![
file.test_value_read(0, 1),
// adjacent to value_read0
file.test_value_read(1, 2),
// gap
// spans adjacent chunks
file.test_value_read(cs_u32 - 1, 2),
// gap
// tail of chunk 3, all of chunk 4, and 2 bytes of chunk 5
file.test_value_read(3 * cs_u32 - 1, cs + 2),
// gap
file.test_value_read(5 * cs_u32, 1),
];
let test_value_reads_perms = test_value_reads.iter().permutations(test_value_reads.len());
// test all orderings of ValueReads, the order shouldn't matter for the results
for test_value_reads in test_value_reads_perms {
let value_reads: Vec<ValueRead<_>> = test_value_reads
.iter()
.map(|tr| tr.make_value_read())
.collect();
execute(&file, value_reads.iter(), &ctx).await;
for (value_read, test_value_read) in
value_reads.into_iter().zip(test_value_reads.iter())
{
let res = value_read
.into_result()
.expect("InMemoryFile is infallible");
assert_eq!(res, test_value_read.expected_result);
}
}
}
struct ExpectedRead {
expect_pos: u32,
expect_len: usize,
@@ -377,97 +470,4 @@ mod tests {
.unwrap();
assert_eq!(err.to_string(), "foo");
}
struct InMemoryFile {
content: Vec<u8>,
}
impl InMemoryFile {
fn new_random(len: usize) -> Self {
Self {
content: rand::thread_rng()
.sample_iter(rand::distributions::Standard)
.take(len)
.collect(),
}
}
fn test_value_read(&self, pos: u32, len: usize) -> TestValueRead {
let expected_result = self.content[pos as usize..pos as usize + len].to_vec();
TestValueRead {
pos,
expected_result,
}
}
}
impl File for InMemoryFile {
async fn read_at_to_end<'a, 'b, B: IoBufMut + Send>(
&'b self,
start: u32,
mut dst: Slice<B>,
_ctx: &'a RequestContext,
) -> std::io::Result<(Slice<B>, usize)> {
let len = std::cmp::min(
dst.bytes_total(),
self.content.len().saturating_sub(start as usize),
);
let dst_slice: &mut [u8] = dst.as_mut_rust_slice_full_zeroed();
dst_slice[..len].copy_from_slice(&self.content[start as usize..start as usize + len]);
rand::Rng::fill(&mut rand::thread_rng(), &mut dst_slice[len..]); // to discover bugs
Ok((dst, len))
}
}
#[derive(Debug)]
struct TestValueRead {
pos: u32,
expected_result: Vec<u8>,
}
impl TestValueRead {
fn make_value_read(&self) -> ValueRead<Vec<u8>> {
ValueRead::new(self.pos, Vec::with_capacity(self.expected_result.len()))
}
}
#[tokio::test]
async fn test_blackbox() {
let ctx = RequestContext::new(TaskKind::UnitTest, DownloadBehavior::Error);
let cs = DIO_CHUNK_SIZE;
let cs_u32 = u32::try_from(cs).unwrap();
let file = InMemoryFile::new_random(10 * cs);
let test_value_reads = vec![
file.test_value_read(0, 1),
// adjacent to value_read0
file.test_value_read(1, 2),
// gap
// spans adjacent chunks
file.test_value_read(cs_u32 - 1, 2),
// gap
// tail of chunk 3, all of chunk 4, and 2 bytes of chunk 5
file.test_value_read(3 * cs_u32 - 1, cs + 2),
// gap
file.test_value_read(5 * cs_u32, 1),
];
let test_value_reads_perms = test_value_reads.iter().permutations(test_value_reads.len());
// test all orderings of ValueReads, the order shouldn't matter for the results
for test_value_reads in test_value_reads_perms {
let value_reads: Vec<ValueRead<_>> = test_value_reads
.iter()
.map(|tr| tr.make_value_read())
.collect();
execute(&file, value_reads.iter(), &ctx).await;
for (value_read, test_value_read) in
value_reads.into_iter().zip(test_value_reads.iter())
{
let res = value_read
.into_result()
.expect("InMemoryFile is infallible");
assert_eq!(res, test_value_read.expected_result);
}
}
}
}