mirror of
https://git.proxmox.com/git/proxmox-backup
synced 2025-10-04 20:16:38 +00:00
chunk stream: tests: add regression tests for payload chunker
Regression tests to cover suggested and forced boundaries as well as chunk injection. Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
This commit is contained in:
parent
e11ee319ce
commit
589f510e7d
@ -228,3 +228,120 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use futures::stream::StreamExt;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
struct DummyInput {
|
||||||
|
data: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DummyInput {
|
||||||
|
fn new(data: Vec<u8>) -> Self {
|
||||||
|
Self { data }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Stream for DummyInput {
|
||||||
|
type Item = Result<Vec<u8>, Error>;
|
||||||
|
|
||||||
|
fn poll_next(self: Pin<&mut Self>, _cx: &mut Context) -> Poll<Option<Self::Item>> {
|
||||||
|
let this = self.get_mut();
|
||||||
|
match this.data.len() {
|
||||||
|
0 => Poll::Ready(None),
|
||||||
|
size if size > 10 => Poll::Ready(Some(Ok(this.data.split_off(10)))),
|
||||||
|
_ => Poll::Ready(Some(Ok(std::mem::take(&mut this.data)))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_chunk_stream_forced_boundaries() {
|
||||||
|
let mut data = Vec::new();
|
||||||
|
for i in 0..(256 * 1024) {
|
||||||
|
for j in 0..4 {
|
||||||
|
let byte = ((i >> (j << 3)) & 0xff) as u8;
|
||||||
|
data.push(byte);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut input = DummyInput::new(data);
|
||||||
|
let input = Pin::new(&mut input);
|
||||||
|
|
||||||
|
let (injections_tx, injections_rx) = mpsc::channel();
|
||||||
|
let (boundaries_tx, boundaries_rx) = mpsc::channel();
|
||||||
|
let (suggested_tx, suggested_rx) = mpsc::channel();
|
||||||
|
let injection_data = InjectionData::new(boundaries_rx, injections_tx);
|
||||||
|
|
||||||
|
let mut chunk_stream = ChunkStream::new(
|
||||||
|
input,
|
||||||
|
Some(64 * 1024),
|
||||||
|
Some(injection_data),
|
||||||
|
Some(suggested_rx),
|
||||||
|
);
|
||||||
|
let chunks = std::sync::Arc::new(std::sync::Mutex::new(Vec::new()));
|
||||||
|
let chunks_clone = chunks.clone();
|
||||||
|
|
||||||
|
// Suggested boundary matching forced boundary
|
||||||
|
suggested_tx.send(32 * 1024).unwrap();
|
||||||
|
// Suggested boundary not matching forced boundary
|
||||||
|
suggested_tx.send(64 * 1024).unwrap();
|
||||||
|
// Force chunk boundary at suggested boundary
|
||||||
|
boundaries_tx
|
||||||
|
.send(InjectChunks {
|
||||||
|
boundary: 32 * 1024,
|
||||||
|
chunks: Vec::new(),
|
||||||
|
size: 1024,
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
// Force chunk boundary within regular chunk
|
||||||
|
boundaries_tx
|
||||||
|
.send(InjectChunks {
|
||||||
|
boundary: 128 * 1024,
|
||||||
|
chunks: Vec::new(),
|
||||||
|
size: 2048,
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
// Force chunk boundary aligned with regular boundary
|
||||||
|
boundaries_tx
|
||||||
|
.send(InjectChunks {
|
||||||
|
boundary: 657408,
|
||||||
|
chunks: Vec::new(),
|
||||||
|
size: 512,
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
// Force chunk boundary within regular chunk, without injecting data
|
||||||
|
boundaries_tx
|
||||||
|
.send(InjectChunks {
|
||||||
|
boundary: 657408 + 1024,
|
||||||
|
chunks: Vec::new(),
|
||||||
|
size: 0,
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
|
rt.block_on(async move {
|
||||||
|
while let Some(chunk) = chunk_stream.next().await {
|
||||||
|
let chunk = chunk.unwrap();
|
||||||
|
let mut chunks = chunks.lock().unwrap();
|
||||||
|
chunks.push(chunk);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut total = 0;
|
||||||
|
let chunks = chunks_clone.lock().unwrap();
|
||||||
|
let expected = [32768, 31744, 65536, 262144, 262144, 512, 262144, 131584];
|
||||||
|
for (chunk, expected) in chunks.as_slice().iter().zip(expected.iter()) {
|
||||||
|
assert_eq!(chunk.len(), *expected);
|
||||||
|
total += chunk.len();
|
||||||
|
}
|
||||||
|
while let Ok(injection) = injections_rx.recv() {
|
||||||
|
total += injection.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(total, 4 * 256 * 1024 + 1024 + 2048 + 512);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user