This is an automated email from the ASF dual-hosted git repository. xuanwo pushed a commit to branch exact-buf-write in repository https://gitbox.apache.org/repos/asf/incubator-opendal.git
commit a7150a3db9b5dd187be394a4b00e64aa15a2cc9d Author: Xuanwo <[email protected]> AuthorDate: Wed Aug 23 20:00:28 2023 +0800 Add fuzzing test for cursor Signed-off-by: Xuanwo <[email protected]> --- core/src/raw/oio/cursor.rs | 93 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/core/src/raw/oio/cursor.rs b/core/src/raw/oio/cursor.rs index 592517855..a10afbf33 100644 --- a/core/src/raw/oio/cursor.rs +++ b/core/src/raw/oio/cursor.rs @@ -309,6 +309,15 @@ impl ChunkedCursor { idx: 0, } } + + #[cfg(test)] + fn concat(&self) -> Bytes { + let mut bs = BytesMut::new(); + for v in &self.inner { + bs.extend_from_slice(&v); + } + bs.freeze() + } } impl oio::Stream for ChunkedCursor { @@ -493,6 +502,8 @@ mod tests { use super::*; use crate::raw::oio::StreamExt; use pretty_assertions::assert_eq; + use rand::{thread_rng, Rng, RngCore}; + use sha2::{Digest, Sha256}; #[test] fn test_vector_cursor() { @@ -628,4 +639,86 @@ mod tests { assert_eq!(c2.len(), 2); assert_eq!(&c2.inner, &[Bytes::from("ld")]); } + + #[test] + fn test_fuzz_chunked_cursor_split_to() { + let mut rng = thread_rng(); + let mut expected = vec![]; + let mut total_size = 0; + + let mut cursor = ChunkedCursor::new(); + + // Build Cursor + let count = rng.gen_range(1..1000); + for _ in 0..count { + let size = rng.gen_range(1..100); + let mut content = vec![0; size]; + rng.fill_bytes(&mut content); + total_size += size; + + expected.extend_from_slice(&content); + cursor.push(Bytes::from(content)); + } + + // Test Cursor + for _ in 0..count { + let mut cursor = cursor.clone(); + + let at = rng.gen_range(0..total_size); + let to = cursor.split_to(at); + + assert_eq!(cursor.len(), total_size - at); + assert_eq!( + format!("{:x}", Sha256::digest(&cursor.concat())), + format!("{:x}", Sha256::digest(&expected[at..])), + ); + + assert_eq!(to.len(), at); + assert_eq!( + format!("{:x}", Sha256::digest(&to.concat())), + format!("{:x}", Sha256::digest(&expected[0..at])), + ); + } + } + + #[test] + fn test_fuzz_chunked_cursor_split_off() { + let mut rng = thread_rng(); + let mut expected = vec![]; + let mut total_size = 0; + + let mut cursor = ChunkedCursor::new(); + + // Build Cursor + let count = rng.gen_range(1..1000); + for _ in 0..count { + let size = rng.gen_range(1..100); + let mut content = vec![0; size]; + rng.fill_bytes(&mut content); + total_size += size; + + expected.extend_from_slice(&content); + cursor.push(Bytes::from(content)); + } + + // Test Cursor + for _ in 0..count { + let mut cursor = cursor.clone(); + + let at = rng.gen_range(0..total_size); + let off = cursor.split_off(at); + + assert_eq!(cursor.len(), at); + assert_eq!( + format!("{:x}", Sha256::digest(&cursor.concat())), + format!("{:x}", Sha256::digest(&expected[..at])), + ); + + assert_eq!(off.len(), total_size - at); + assert_eq!( + format!("{:x}", Sha256::digest(&off.concat())), + format!("{:x}", Sha256::digest(&expected[at..])), + ); + } + } }
