Skip to content

Commit 6edf060

Browse files
committed
add example and integration tests
1 parent a0cd1e0 commit 6edf060

10 files changed

+197
-4
lines changed

crates/core/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ xattr = "1"
132132
[dev-dependencies]
133133
expect-test = "1.4.1"
134134
flate2 = "1.0.28"
135+
globset = "0.4.14"
135136
insta = { version = "1.36.1", features = ["redactions", "ron"] }
136137
mockall = "0.12.1"
137138
pretty_assertions = "1.4.0"

crates/core/src/blob/tree.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ impl Tree {
331331
}
332332

333333
/// Results from `find_node_from_path`
334-
#[derive(Debug)]
334+
#[derive(Debug, Serialize)]
335335
pub struct FindNode {
336336
/// found nodes for the given path
337337
pub nodes: Vec<Node>,
@@ -340,7 +340,7 @@ pub struct FindNode {
340340
}
341341

342342
/// Results from `find_matching_nodes`
343-
#[derive(Debug)]
343+
#[derive(Debug, Serialize)]
344344
pub struct FindMatches {
345345
/// found matching paths
346346
pub paths: Vec<PathBuf>,

crates/core/tests/integration.rs

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,23 @@
2525
2626
use anyhow::Result;
2727
use flate2::read::GzDecoder;
28+
use globset::Glob;
2829
use insta::internals::{Content, ContentPath};
2930
use insta::{assert_ron_snapshot, Settings};
3031
use pretty_assertions::assert_eq;
3132
use rstest::fixture;
3233
use rstest::rstest;
34+
use rustic_core::repofile::{Metadata, Node};
3335
use rustic_core::{
34-
repofile::SnapshotFile, BackupOptions, ConfigOptions, KeyOptions, NoProgressBars, OpenStatus,
35-
PathList, Repository, RepositoryBackends, RepositoryOptions,
36+
repofile::SnapshotFile, BackupOptions, ConfigOptions, KeyOptions, LsOptions, NoProgressBars,
37+
OpenStatus, PathList, Repository, RepositoryBackends, RepositoryOptions,
3638
};
39+
use rustic_core::{FindMatches, FindNode, RusticResult};
3740
use serde_derive::Serialize;
3841

3942
use rustic_testing::backend::in_memory_backend::InMemoryBackend;
4043

44+
use std::ffi::OsStr;
4145
use std::{
4246
env,
4347
fs::File,
@@ -348,3 +352,79 @@ fn test_backup_dry_run_with_tar_gz_passes(
348352
assert_eq!(snap_dry_run.tree, second_snapshot.tree);
349353
Ok(())
350354
}
355+
356+
#[rstest]
357+
fn test_ls(tar_gz_testdata: Result<TestSource>, set_up_repo: Result<RepoOpen>) -> Result<()> {
358+
// Fixtures
359+
let (source, repo) = (tar_gz_testdata?, set_up_repo?.to_indexed_ids()?);
360+
let paths = &source.path_list();
361+
362+
// we use as_path to not depend on the actual tempdir
363+
let opts = BackupOptions::default().as_path(PathBuf::from_str("test")?);
364+
// backup test-data
365+
let snapshot = repo.backup(&opts, paths, SnapshotFile::default())?;
366+
367+
// test non-existing entries
368+
let mut node = Node::new_node(
369+
OsStr::new(""),
370+
rustic_core::repofile::NodeType::Dir,
371+
Metadata::default(),
372+
);
373+
node.subtree = Some(snapshot.tree);
374+
375+
// re-read index
376+
let repo = repo.to_indexed_ids()?;
377+
378+
let _entries: Vec<_> = repo
379+
.ls(&node, &LsOptions::default())?
380+
.collect::<RusticResult<_>>()?;
381+
// TODO: Snapshot-test entries
382+
// assert_ron_snapshot!("ls", entries);
383+
Ok(())
384+
}
385+
386+
#[rstest]
387+
fn test_find(tar_gz_testdata: Result<TestSource>, set_up_repo: Result<RepoOpen>) -> Result<()> {
388+
// Fixtures
389+
let (source, repo) = (tar_gz_testdata?, set_up_repo?.to_indexed_ids()?);
390+
let paths = &source.path_list();
391+
392+
// we use as_path to not depend on the actual tempdir
393+
let opts = BackupOptions::default().as_path(PathBuf::from_str("test")?);
394+
// backup test-data
395+
let snapshot = repo.backup(&opts, paths, SnapshotFile::default())?;
396+
397+
// re-read index
398+
let repo = repo.to_indexed_ids()?;
399+
400+
// test non-existing path
401+
let not_found = repo.find_nodes_from_path(vec![snapshot.tree], Path::new("not_existing"))?;
402+
assert_ron_snapshot!("find-nodes-not-found", not_found);
403+
// test non-existing match
404+
let glob = Glob::new("not_existing")?.compile_matcher();
405+
let not_found =
406+
repo.find_matching_nodes(vec![snapshot.tree], &|path, _| glob.is_match(path))?;
407+
assert_ron_snapshot!("find-matching-nodes-not-found", not_found);
408+
409+
// test existing path
410+
let FindNode { matches, .. } =
411+
repo.find_nodes_from_path(vec![snapshot.tree], Path::new("test/0/tests/testfile"))?;
412+
assert_ron_snapshot!("find-nodes-existing", matches);
413+
// test existing match
414+
let glob = Glob::new("testfile")?.compile_matcher();
415+
let match_func = |path: &Path, _: &Node| {
416+
glob.is_match(path) || path.file_name().is_some_and(|f| glob.is_match(f))
417+
};
418+
let FindMatches { paths, matches, .. } =
419+
repo.find_matching_nodes(vec![snapshot.tree], &match_func)?;
420+
assert_ron_snapshot!("find-matching-existing", (paths, matches));
421+
// test existing match
422+
let glob = Glob::new("testfile*")?.compile_matcher();
423+
let match_func = |path: &Path, _: &Node| {
424+
glob.is_match(path) || path.file_name().is_some_and(|f| glob.is_match(f))
425+
};
426+
let FindMatches { paths, matches, .. } =
427+
repo.find_matching_nodes(vec![snapshot.tree], &match_func)?;
428+
assert_ron_snapshot!("find-matching-wildcard-existing", (paths, matches));
429+
Ok(())
430+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
source: crates/core/tests/integration.rs
3+
expression: "(paths, matches)"
4+
---
5+
([
6+
"test/0/tests/testfile",
7+
], [
8+
[
9+
(0, 0),
10+
],
11+
])
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
source: crates/core/tests/integration.rs
3+
expression: not_found
4+
---
5+
FindMatches(
6+
paths: [],
7+
nodes: [],
8+
matches: [
9+
[],
10+
],
11+
)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
source: crates/core/tests/integration.rs
3+
expression: "(paths, matches)"
4+
---
5+
([
6+
"test/0/tests/testfile",
7+
"test/0/tests/testfile-hardlink",
8+
"test/0/tests/testfile-symlink",
9+
], [
10+
[
11+
(0, 0),
12+
(1, 1),
13+
(2, 2),
14+
],
15+
])
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
source: crates/core/tests/integration.rs
3+
expression: matches
4+
---
5+
[
6+
Some(0),
7+
]
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
source: crates/core/tests/integration.rs
3+
expression: not_found
4+
---
5+
FindNode(
6+
nodes: [],
7+
matches: [
8+
None,
9+
],
10+
)

examples/find/Cargo.toml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[package]
2+
name = "find"
3+
version = "0.1.0"
4+
edition = "2021"
5+
publish = false
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[dependencies]
10+
globset = "0.4.14"
11+
rustic_backend = { workspace = true }
12+
rustic_core = { workspace = true }
13+
simplelog = { workspace = true }
14+
15+
[[example]]
16+
name = "find"

examples/find/examples/find.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//! `ls` example
2+
use globset::Glob;
3+
use rustic_backend::BackendOptions;
4+
use rustic_core::{FindMatches, Repository, RepositoryOptions};
5+
use simplelog::{Config, LevelFilter, SimpleLogger};
6+
use std::error::Error;
7+
8+
fn main() -> Result<(), Box<dyn Error>> {
9+
// Display info logs
10+
let _ = SimpleLogger::init(LevelFilter::Info, Config::default());
11+
12+
// Initialize Backends
13+
let backends = BackendOptions::default()
14+
.repository("/tmp/repo")
15+
.to_backends()?;
16+
17+
// Open repository
18+
let repo_opts = RepositoryOptions::default().password("test ");
19+
20+
let repo = Repository::new(&repo_opts, &backends)?
21+
.open()?
22+
.to_indexed()?;
23+
24+
let mut snapshots = repo.get_all_snapshots()?;
25+
snapshots.sort_unstable();
26+
let tree_ids = snapshots.iter().map(|sn| sn.tree);
27+
28+
let glob = Glob::new("*.rs")?.compile_matcher();
29+
let FindMatches {
30+
paths,
31+
nodes,
32+
matches,
33+
} = repo.find_matching_nodes(tree_ids, &|path, _| glob.is_match(path))?;
34+
for (snap, matches) in snapshots.iter().zip(matches) {
35+
println!("results in {snap:?}");
36+
for (path_idx, node_idx) in matches {
37+
println!("path: {:?}, node: {:?}", paths[path_idx], nodes[node_idx]);
38+
}
39+
}
40+
41+
Ok(())
42+
}

0 commit comments

Comments
 (0)