mirror of
https://github.com/neondatabase/neon.git
synced 2026-05-18 21:50:37 +00:00
move MockFile section after blackbox test
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user