-
Notifications
You must be signed in to change notification settings - Fork 181
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: CLI tests for iroh add, and API changes #343
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -320,7 +320,6 @@ pub struct DirectoryBuilder { | |
name: Option<String>, | ||
entries: Vec<Entry>, | ||
typ: DirectoryType, | ||
recursive: bool, | ||
} | ||
|
||
impl Default for DirectoryBuilder { | ||
|
@@ -329,7 +328,6 @@ impl Default for DirectoryBuilder { | |
name: None, | ||
entries: Default::default(), | ||
typ: DirectoryType::Basic, | ||
recursive: false, | ||
} | ||
} | ||
} | ||
|
@@ -344,18 +342,12 @@ impl DirectoryBuilder { | |
self | ||
} | ||
|
||
pub fn recursive(&mut self) -> &mut Self { | ||
self.recursive = true; | ||
self | ||
} | ||
|
||
pub fn name<N: Into<String>>(&mut self, name: N) -> &mut Self { | ||
self.name = Some(name.into()); | ||
self | ||
} | ||
|
||
pub fn add_dir(&mut self, dir: Directory) -> Result<&mut Self> { | ||
ensure!(self.recursive, "recursive directories not allowed"); | ||
Ok(self.entry(Entry::Directory(dir))) | ||
} | ||
|
||
|
@@ -471,15 +463,10 @@ pub async fn add_file<S: Store>(store: Option<S>, path: &Path, wrap: bool) -> Re | |
/// - storing the content using `rpc.store` | ||
/// - returns the root Cid | ||
/// - optionally wraps into a UnixFs directory to preserve the directory name | ||
pub async fn add_dir<S: Store>( | ||
store: Option<S>, | ||
path: &Path, | ||
wrap: bool, | ||
recursive: bool, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is the recursive flag not needed anymore? Do we always use recursive? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The use case for the |
||
) -> Result<Cid> { | ||
pub async fn add_dir<S: Store>(store: Option<S>, path: &Path, wrap: bool) -> Result<Cid> { | ||
ensure!(path.is_dir(), "provided path was not a directory"); | ||
|
||
let dir = make_dir_from_path(path, recursive).await?; | ||
let dir = make_dir_from_path(path).await?; | ||
// encode and store | ||
let mut root = None; | ||
let parts = { | ||
|
@@ -504,25 +491,22 @@ pub async fn add_dir<S: Store>( | |
} | ||
|
||
#[async_recursion(?Send)] | ||
async fn make_dir_from_path<P: Into<PathBuf>>(path: P, recursive: bool) -> Result<Directory> { | ||
async fn make_dir_from_path<P: Into<PathBuf>>(path: P) -> Result<Directory> { | ||
let path = path.into(); | ||
let mut dir = DirectoryBuilder::new(); | ||
dir.name( | ||
path.file_name() | ||
.and_then(|s| s.to_str()) | ||
.unwrap_or_default(), | ||
); | ||
if recursive { | ||
dir.recursive(); | ||
} | ||
let mut directory_reader = tokio::fs::read_dir(path.clone()).await?; | ||
while let Some(entry) = directory_reader.next_entry().await? { | ||
let path = entry.path(); | ||
if path.is_file() { | ||
let f = FileBuilder::new().path(path).build().await?; | ||
dir.add_file(f); | ||
} else if path.is_dir() { | ||
let d = make_dir_from_path(path, recursive).await?; | ||
let d = make_dir_from_path(path).await?; | ||
dir.add_dir(d)?; | ||
} else { | ||
anyhow::bail!("directory entry is neither file nor directory") | ||
|
@@ -597,16 +581,7 @@ mod tests { | |
let dir = DirectoryBuilder::new(); | ||
let dir = dir.build()?; | ||
|
||
let mut no_recursive = DirectoryBuilder::new(); | ||
if no_recursive.add_dir(dir).is_ok() { | ||
panic!("shouldn't be able to add a directory to a non-recursive directory builder"); | ||
} | ||
|
||
let dir = DirectoryBuilder::new(); | ||
let dir = dir.build()?; | ||
|
||
let mut recursive_dir_builder = DirectoryBuilder::new(); | ||
recursive_dir_builder.recursive(); | ||
recursive_dir_builder | ||
.add_dir(dir) | ||
.expect("recursive directories allowed"); | ||
|
@@ -703,7 +678,6 @@ mod tests { | |
#[async_recursion(?Send)] | ||
async fn build_directory(name: &str, dir: &TestDir) -> Result<Directory> { | ||
let mut builder = DirectoryBuilder::new(); | ||
builder.recursive(); | ||
builder.name(name); | ||
for (name, entry) in dir { | ||
match entry { | ||
|
@@ -1027,7 +1001,7 @@ mod tests { | |
entries: vec![Entry::File(file), Entry::Directory(nested_dir)], | ||
}; | ||
|
||
let mut got = make_dir_from_path(dir, true).await?; | ||
let mut got = make_dir_from_path(dir).await?; | ||
|
||
// Before comparison sort entries to make test deterministic. | ||
// The readdir_r function is used in the underlying platform which | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,10 @@ | ||
use std::collections::HashMap; | ||
use std::env; | ||
use std::future; | ||
use std::str::FromStr; | ||
|
||
use futures::StreamExt; | ||
use iroh_api::{Lookup, MockApi, MockP2p, OutType, PeerId}; | ||
use iroh_api::{Cid, Lookup, MockApi, MockP2p, OutType, PeerId}; | ||
use relative_path::RelativePathBuf; | ||
|
||
type GetFixture = fn() -> MockApi; | ||
|
@@ -51,6 +53,26 @@ fn fixture_get() -> MockApi { | |
api | ||
} | ||
|
||
fn fixture_add_file() -> MockApi { | ||
let mut api = MockApi::default(); | ||
api.expect_add_file().returning(|_ipfs_path, _| { | ||
Box::pin(future::ready( | ||
Cid::from_str("QmYbcW4tXLXHWw753boCK8Y7uxLu5abXjyYizhLznq9PUR").map_err(|e| e.into()), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So this returns the same cid whatever you add. Is the intention to make it more realistic, or just write another mock for that? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just write another mock if that becomes a use case. In general I don't think we should strive for realism in these mocks, just fulfilling the contract in the easiest way possible for a particular test case. Unfortunately this means for |
||
)) | ||
}); | ||
api | ||
} | ||
|
||
fn fixture_add_directory() -> MockApi { | ||
let mut api = MockApi::default(); | ||
api.expect_add_dir().returning(|_ipfs_path, _| { | ||
Box::pin(future::ready( | ||
Cid::from_str("QmYbcW4tXLXHWw753boCK8Y7uxLu5abXjyYizhLznq9PUR").map_err(|e| e.into()), | ||
)) | ||
}); | ||
api | ||
} | ||
|
||
fn fixture_get_wrapped_file() -> MockApi { | ||
let mut api = MockApi::default(); | ||
api.expect_get_stream().returning(|_ipfs_path| { | ||
|
@@ -90,6 +112,11 @@ fn register_fixtures() -> FixtureRegistry { | |
"get_unwrapped_file".to_string(), | ||
fixture_get_unwrapped_file as GetFixture, | ||
), | ||
("add_file".to_string(), fixture_add_file as GetFixture), | ||
( | ||
"add_directory".to_string(), | ||
fixture_add_directory as GetFixture, | ||
), | ||
] | ||
.into_iter() | ||
.collect() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the code to figure out if it is a file or a dir is moved to ApiExt, and the main fns in api require you to be explicit? I like it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, and the check for the
recursive
flag before copying a directory was removed from the API entirely, because the use case for writing code like this is very different from the reason it's in the CLI (which is to prevent accidents in interactive mode).