From 997720fba6b2b9b3b5cd73dc21a7bff89857f0be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Tue, 14 Mar 2023 10:36:09 +0100 Subject: [PATCH] Expose enhanced iteration syscall to the client and test them --- src/api.rs | 6 ++-- src/api/macros.rs | 6 ++-- src/client.rs | 28 +++++++++++++++++ src/service.rs | 4 +-- src/store/filestore.rs | 4 +-- tests/filesystem.rs | 70 ++++++++++++++++++++++++++---------------- 6 files changed, 83 insertions(+), 35 deletions(-) diff --git a/src/api.rs b/src/api.rs index cb23d1e39f0..26c67a75e12 100644 --- a/src/api.rs +++ b/src/api.rs @@ -41,7 +41,7 @@ generate_enums! { Hash: 12 // TODO: add ReadDir{First,Next}, not loading data, if needed for efficiency ReadDirFilesFirst: 13 - ReadDirFilesNth: 31 + ReadDirFilesNth: 63 ReadDirFilesNext: 14 ReadFile: 15 Metadata: 26 @@ -64,7 +64,7 @@ generate_enums! { // // CreateDir, <-- implied by WriteFile ReadDirFirst: 31 // <-- gets Option to restrict to just dir/file DirEntries, - ReadDirNth: 31 + ReadDirNth: 64 ReadDirNext: 32 // <-- gets Option to restrict to just dir/file DirEntries, // // returns simplified Metadata // // ReadDirFilesFirst: 23 // <-- returns contents @@ -442,7 +442,7 @@ pub mod reply { - entry: Option ReadDirNth: - - data: Option + - entry: Option ReadDirNext: - entry: Option diff --git a/src/api/macros.rs b/src/api/macros.rs index 0de36555b52..30f57c363f4 100644 --- a/src/api/macros.rs +++ b/src/api/macros.rs @@ -2,16 +2,18 @@ macro_rules! generate_enums { ($($(#[$attr:meta])? $which:ident: $index:literal)*) => { #[derive(Clone, Eq, PartialEq, Debug)] + #[repr(u8)] #[allow(clippy::large_enum_variant)] pub enum Request { - DummyRequest, // for testing + DummyRequest = 0, // for testing $( $(#[$attr])? - $which(request::$which), + $which(request::$which) = $index, )* } #[derive(Clone, Eq, PartialEq, Debug)] + #[repr(u8)] #[allow(clippy::large_enum_variant)] pub enum Reply { DummyReply, // for testing diff --git a/src/client.rs b/src/client.rs index c2f5d58b728..60deae33659 100644 --- a/src/client.rs +++ b/src/client.rs @@ -569,6 +569,19 @@ pub trait FilesystemClient: PollClient { }) } + fn read_dir_nth( + &mut self, + location: Location, + dir: PathBuf, + start_at: usize, + ) -> ClientResult<'_, reply::ReadDirNth, Self> { + self.request(request::ReadDirNth { + location, + dir, + start_at, + }) + } + fn read_dir_next(&mut self) -> ClientResult<'_, reply::ReadDirNext, Self> { self.request(request::ReadDirNext {}) } @@ -586,6 +599,21 @@ pub trait FilesystemClient: PollClient { }) } + fn read_dir_files_nth( + &mut self, + location: Location, + dir: PathBuf, + start_at: usize, + user_attribute: Option, + ) -> ClientResult<'_, reply::ReadDirFilesNth, Self> { + self.request(request::ReadDirFilesNth { + dir, + location, + start_at, + user_attribute, + }) + } + fn read_dir_files_next(&mut self) -> ClientResult<'_, reply::ReadDirFilesNext, Self> { self.request(request::ReadDirFilesNext {}) } diff --git a/src/service.rs b/src/service.rs index a17519c061b..f2860b0574e 100644 --- a/src/service.rs +++ b/src/service.rs @@ -365,7 +365,7 @@ impl ServiceResources

{ } }; - Ok(Reply::ReadDirFirst(reply::ReadDirFirst { entry: maybe_entry } )) + Ok(Reply::ReadDirNth(reply::ReadDirNth { entry: maybe_entry } )) } Request::ReadDirNext(_request) => { @@ -416,7 +416,7 @@ impl ServiceResources

{ None } }; - Ok(Reply::ReadDirFilesFirst(reply::ReadDirFilesFirst { data: maybe_data } )) + Ok(Reply::ReadDirFilesNth(reply::ReadDirFilesNth { data: maybe_data } )) } Request::ReadDirFilesNext(_request) => { diff --git a/src/store/filestore.rs b/src/store/filestore.rs index 4120beb2e17..a8168bf0b36 100644 --- a/src/store/filestore.rs +++ b/src/store/filestore.rs @@ -6,14 +6,14 @@ use crate::{ Bytes, }; -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct ReadDirState { real_dir: PathBuf, location: Location, position: DirIterationTell, } -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct ReadDirFilesState { real_dir: PathBuf, position: DirIterationTell, diff --git a/tests/filesystem.rs b/tests/filesystem.rs index 08ca8efe511..d3cadff84b6 100644 --- a/tests/filesystem.rs +++ b/tests/filesystem.rs @@ -55,34 +55,52 @@ fn escape_namespace_root() { } fn iterating(location: Location) { - client::get(|client| { - syscall!(client.write_file( - location, - PathBuf::from("foo"), - Bytes::from_slice(b"foo").unwrap(), - None - )); - syscall!(client.write_file( - location, - PathBuf::from("bar"), - Bytes::from_slice(b"bar").unwrap(), - None - )); - let first_entry = syscall!(client.read_dir_first(location, PathBuf::from(""), None)) - .entry - .unwrap(); - assert_eq!(first_entry.file_name(), "bar"); + for count in [0, 1, 10, 20] { + let files: Vec<_> = (0..count).map(|i| format!("file{i:04}")).collect(); + client::get(|client| { + // Setup filesystem + for file in &files { + syscall!(client.write_file( + location, + PathBuf::from(&**file), + Bytes::from_slice(file.as_bytes()).unwrap(), + None + )); + } + + // Iteration over entries (filenames) + for i in 0..count { + if let Some(f) = files.get(i) { + let entry = syscall!(client.read_dir_nth(location, PathBuf::new(), i)) + .entry + .unwrap(); + assert_eq!(entry.path().as_ref(), f); + } + + for j in i + 1..count { + let entry = syscall!(client.read_dir_next()).entry.unwrap(); + assert_eq!(entry.path().as_ref(), &files[j]); + } + assert!(syscall!(client.read_dir_next()).entry.is_none()); + } - let next_entry = syscall!(client.read_dir_next()).entry.unwrap(); - assert_eq!(next_entry.file_name(), "foo"); + for i in 0..count { + if let Some(f) = files.get(i) { + let data = + syscall!(client.read_dir_files_nth(location, PathBuf::new(), i, None)) + .data + .unwrap(); + assert_eq!(data, f.as_bytes()); + } - let first_data = syscall!(client.read_dir_files_first(location, PathBuf::from(""), None)) - .data - .unwrap(); - assert_eq!(first_data, b"bar"); - let next_data = syscall!(client.read_dir_files_next()).data.unwrap(); - assert_eq!(next_data, b"foo"); - }); + for j in i + 1..count { + let data = syscall!(client.read_dir_files_next()).data.unwrap(); + assert_eq!(data, files[j].as_bytes()); + } + assert!(syscall!(client.read_dir_files_next()).data.is_none()); + } + }); + } } #[test]