From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id 1B0B61FF39E for ; Wed, 5 Jun 2024 12:55:08 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 21B5732099; Wed, 5 Jun 2024 12:55:31 +0200 (CEST) From: Christian Ebner To: pbs-devel@lists.proxmox.com Date: Wed, 5 Jun 2024 12:54:05 +0200 Message-Id: <20240605105416.278748-48-c.ebner@proxmox.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240605105416.278748-1-c.ebner@proxmox.com> References: <20240605105416.278748-1-c.ebner@proxmox.com> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.027 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record T_SCC_BODY_TEXT_LINE -0.01 - Subject: [pbs-devel] [PATCH v9 proxmox-backup 47/58] chunk stream: tests: add regression tests for payload chunker X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Proxmox Backup Server development discussion Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pbs-devel-bounces@lists.proxmox.com Sender: "pbs-devel" Regression tests to cover suggested and forced boundaries as well as chunk injection. Signed-off-by: Christian Ebner --- changes since version 8: - no changes pbs-client/src/chunk_stream.rs | 117 +++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/pbs-client/src/chunk_stream.rs b/pbs-client/src/chunk_stream.rs index 84158a2c9..070a10c17 100644 --- a/pbs-client/src/chunk_stream.rs +++ b/pbs-client/src/chunk_stream.rs @@ -228,3 +228,120 @@ where } } } + +#[cfg(test)] +mod test { + use futures::stream::StreamExt; + + use super::*; + + struct DummyInput { + data: Vec, + } + + impl DummyInput { + fn new(data: Vec) -> Self { + Self { data } + } + } + + impl Stream for DummyInput { + type Item = Result, Error>; + + fn poll_next(self: Pin<&mut Self>, _cx: &mut Context) -> Poll> { + 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); + } +} -- 2.39.2 _______________________________________________ pbs-devel mailing list pbs-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel