From fcc40f3a4ee8b7fe88cdc201d3dfb980391b72cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Narzis?= <78718413+lean-apple@users.noreply.github.com> Date: Sat, 5 Apr 2025 16:35:04 +0200 Subject: [PATCH] feat(era- e2store): add `read_next_entry` + improve tests (#15556) --- crates/era/src/e2s_file.rs | 68 ++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 7 deletions(-) diff --git a/crates/era/src/e2s_file.rs b/crates/era/src/e2s_file.rs index be0cf167ff..9e74aaaeed 100644 --- a/crates/era/src/e2s_file.rs +++ b/crates/era/src/e2s_file.rs @@ -29,6 +29,11 @@ impl E2StoreReader { } } + /// Read the next entry from the file + pub fn read_next_entry(&mut self) -> Result, E2sError> { + Entry::read(&mut self.reader) + } + /// Iterate through all entries, including the version entry pub fn entries(&mut self) -> Result, E2sError> { // Reset reader to beginning @@ -36,7 +41,7 @@ impl E2StoreReader { let mut entries = Vec::new(); - while let Some(entry) = Entry::read(&mut self.reader)? { + while let Some(entry) = self.read_next_entry()? { entries.push(entry); } @@ -50,27 +55,31 @@ mod tests { use crate::e2s_types::{BLOCK_INDEX, VERSION}; use std::io::Cursor; + fn create_block_index_data(block_number: u64, offset: u64) -> Vec { + let mut data = Vec::with_capacity(16); + data.extend_from_slice(&block_number.to_le_bytes()); + data.extend_from_slice(&offset.to_le_bytes()); + data + } + #[test] fn test_e2store_reader() -> Result<(), E2sError> { // Create a mock e2store file in memory let mut mock_file = Vec::new(); - // Write version entry let version_entry = Entry::new(VERSION, Vec::new()); version_entry.write(&mut mock_file)?; - // Write multiple entries of different types - let block_index_entry1 = Entry::new(BLOCK_INDEX, vec![1, 2, 3, 4]); + let block_index_entry1 = Entry::new(BLOCK_INDEX, create_block_index_data(1, 1024)); block_index_entry1.write(&mut mock_file)?; - let block_index_entry2 = Entry::new(BLOCK_INDEX, vec![5, 6, 7, 8, 9]); + let block_index_entry2 = Entry::new(BLOCK_INDEX, create_block_index_data(2, 2048)); block_index_entry2.write(&mut mock_file)?; - let custom_type = [0x99, 0x99]; // Application-specific type + let custom_type = [0x99, 0x99]; let custom_entry = Entry::new(custom_type, vec![10, 11, 12]); custom_entry.write(&mut mock_file)?; - // Create reader and process entries let cursor = Cursor::new(mock_file); let mut e2store_reader = E2StoreReader::new(cursor); @@ -92,4 +101,49 @@ mod tests { Ok(()) } + + #[test] + fn test_empty_file() -> Result<(), E2sError> { + // Create an empty file + let mock_file = Vec::new(); + + // Create reader + let cursor = Cursor::new(mock_file); + let mut e2store_reader = E2StoreReader::new(cursor); + + // Reading version should return None + let version = e2store_reader.read_version()?; + assert!(version.is_none()); + + // Entries should be empty + let entries = e2store_reader.entries()?; + assert!(entries.is_empty()); + + Ok(()) + } + + #[test] + fn test_read_next_entry() -> Result<(), E2sError> { + let mut mock_file = Vec::new(); + + let version_entry = Entry::new(VERSION, Vec::new()); + version_entry.write(&mut mock_file)?; + + let block_entry = Entry::new(BLOCK_INDEX, create_block_index_data(1, 1024)); + block_entry.write(&mut mock_file)?; + + let cursor = Cursor::new(mock_file); + let mut reader = E2StoreReader::new(cursor); + + let first = reader.read_next_entry()?.unwrap(); + assert!(first.is_version()); + + let second = reader.read_next_entry()?.unwrap(); + assert!(second.is_block_index()); + + let third = reader.read_next_entry()?; + assert!(third.is_none()); + + Ok(()) + } }