From c7552a7a6ac18cf5b07615a53db073d778ceece2 Mon Sep 17 00:00:00 2001 From: Alexander Weiss Date: Tue, 5 Mar 2024 10:30:58 +0100 Subject: [PATCH 01/46] tests: Add integration tests --- crates/core/Cargo.toml | 3 + crates/core/src/backend.rs | 83 ++++++++- crates/core/src/lib.rs | 1 + crates/core/tests/integration.rs | 162 ++++++++++++++++++ .../snapshots/integration__backup-2.snap | 19 ++ .../tests/snapshots/integration__backup.snap | 19 ++ .../integration__backup_dry_run-2.snap | 19 ++ .../integration__backup_dry_run.snap | 19 ++ crates/core/tests/testdata/backup-data.tar.gz | Bin 0 -> 11704 bytes 9 files changed, 323 insertions(+), 2 deletions(-) create mode 100644 crates/core/tests/integration.rs create mode 100644 crates/core/tests/snapshots/integration__backup-2.snap create mode 100644 crates/core/tests/snapshots/integration__backup.snap create mode 100644 crates/core/tests/snapshots/integration__backup_dry_run-2.snap create mode 100644 crates/core/tests/snapshots/integration__backup_dry_run.snap create mode 100644 crates/core/tests/testdata/backup-data.tar.gz diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 82c21e5a..ecdffa76 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -132,6 +132,8 @@ xattr = "1" [dev-dependencies] expect-test = "1.4.1" +flate2 = "1.0.28" +insta = "1.36.1" mockall = "0.12.1" pretty_assertions = "1.4.0" quickcheck = "1.0.3" @@ -142,6 +144,7 @@ rustdoc-json = "0.8.9" rustic_backend = { workspace = true } rustup-toolchain = "0.1.6" simplelog = "0.12.2" +tar = "0.4.40" tempfile = { workspace = true } [lints] diff --git a/crates/core/src/backend.rs b/crates/core/src/backend.rs index c14cc6fe..ffb327c0 100644 --- a/crates/core/src/backend.rs +++ b/crates/core/src/backend.rs @@ -13,6 +13,7 @@ use std::{io::Read, ops::Deref, path::PathBuf, sync::Arc}; use anyhow::Result; use bytes::Bytes; +use enum_map::Enum; use log::trace; #[cfg(test)] use mockall::*; @@ -34,7 +35,7 @@ pub const ALL_FILE_TYPES: [FileType; 4] = [ ]; /// Type for describing the kind of a file that can occur. -#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, Enum)] pub enum FileType { /// Config file #[serde(rename = "config")] @@ -295,7 +296,9 @@ pub trait WriteBackend: ReadBackend { /// # Returns /// /// The result of the creation. - fn create(&self) -> Result<()>; + fn create(&self) -> Result<()> { + Ok(()) + } /// Writes bytes to the given file. /// @@ -545,3 +548,79 @@ impl RepositoryBackends { self.repo_hot.clone() } } + +pub mod in_memory_backend { + use std::{collections::BTreeMap, sync::RwLock}; + + use anyhow::{bail, Result}; + use bytes::Bytes; + use enum_map::EnumMap; + + use super::{ReadBackend, WriteBackend}; + use crate::{FileType, Id}; + + #[derive(Debug)] + /// In-Memory backend to be used for testing + pub struct InMemoryBackend(RwLock>>); + + impl InMemoryBackend { + /// Create a new (empty) `InMemoryBackend` + pub fn new() -> Self { + Self(RwLock::new(EnumMap::from_fn(|_| BTreeMap::new()))) + } + } + + impl Default for InMemoryBackend { + fn default() -> Self { + Self::new() + } + } + + impl ReadBackend for InMemoryBackend { + fn location(&self) -> String { + "test".to_string() + } + + fn list_with_size(&self, tpe: FileType) -> Result> { + Ok(self.0.read().unwrap()[tpe] + .iter() + .map(|(id, byte)| (*id, byte.len() as u32)) + .collect()) + } + + fn read_full(&self, tpe: FileType, id: &Id) -> Result { + Ok(self.0.read().unwrap()[tpe][id].clone()) + } + + fn read_partial( + &self, + tpe: FileType, + id: &Id, + _cacheable: bool, + offset: u32, + length: u32, + ) -> Result { + Ok(self.0.read().unwrap()[tpe][id].slice(offset as usize..(offset + length) as usize)) + } + } + + impl WriteBackend for InMemoryBackend { + fn create(&self) -> Result<()> { + Ok(()) + } + + fn write_bytes(&self, tpe: FileType, id: &Id, _cacheable: bool, buf: Bytes) -> Result<()> { + if self.0.write().unwrap()[tpe].insert(*id, buf).is_some() { + bail!("id {id} already exists"); + } + Ok(()) + } + + fn remove(&self, tpe: FileType, id: &Id, _cacheable: bool) -> Result<()> { + if self.0.write().unwrap()[tpe].remove(id).is_none() { + bail!("id {id} doesn't exists"); + } + Ok(()) + } + } +} diff --git a/crates/core/src/lib.rs b/crates/core/src/lib.rs index 698763c2..63bd3047 100644 --- a/crates/core/src/lib.rs +++ b/crates/core/src/lib.rs @@ -124,6 +124,7 @@ pub use crate::{ backend::{ decrypt::{compression_level_range, max_compression_level}, ignore::{LocalSource, LocalSourceFilterOptions, LocalSourceSaveOptions}, + in_memory_backend::InMemoryBackend, local_destination::LocalDestination, node::last_modified_node, FileType, ReadBackend, ReadSource, ReadSourceEntry, ReadSourceOpen, RepositoryBackends, diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs new file mode 100644 index 00000000..6d16470d --- /dev/null +++ b/crates/core/tests/integration.rs @@ -0,0 +1,162 @@ +use std::{env, fs::File, path::Path, str::FromStr, sync::Arc}; + +use anyhow::Result; +use flate2::read::GzDecoder; +use insta::assert_debug_snapshot; +use pretty_assertions::assert_eq; +use rustic_core::{ + repofile::SnapshotFile, BackupOptions, ConfigOptions, InMemoryBackend, KeyOptions, + NoProgressBars, OpenStatus, PathList, Repository, RepositoryBackends, RepositoryOptions, + StringList, +}; +use tar::Archive; +use tempfile::{tempdir, TempDir}; + +fn set_up_repo() -> Result> { + let be = InMemoryBackend::new(); + let be = RepositoryBackends::new(Arc::new(be), None); + let options = RepositoryOptions::default().password("test"); + let repo = Repository::new(&options, be)?; + let key_opts = KeyOptions::default(); + let config_opts = &ConfigOptions::default(); + let repo = repo.init(&key_opts, config_opts)?; + Ok(repo) +} + +struct TestSource(TempDir); + +impl TestSource { + fn new(tmp: TempDir) -> Self { + Self(tmp) + } + + fn paths(&self) -> Result { + Ok(PathList::from_string(self.0.path().to_str().unwrap())?) + } + + fn strings(&self) -> Result { + Ok(StringList::from_str(self.0.path().to_str().unwrap())?) + } +} + +fn set_up_testdata(path: impl AsRef) -> Result { + let dir = tempdir()?; + let path = Path::new("tests/testdata").join(path); + let tar_gz = File::open(path)?; + let tar = GzDecoder::new(tar_gz); + let mut archive = Archive::new(tar); + archive.set_preserve_permissions(true); + archive.set_preserve_mtime(true); + archive.unpack(&dir)?; + Ok(TestSource::new(dir)) +} + +// Parts of the snapshot summary we want to test against references +struct TestSummary<'a>(&'a SnapshotFile); + +impl<'a> std::fmt::Debug for TestSummary<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let s = self.0.summary.as_ref().unwrap(); + // leave out info we expect to change: + // Ids, times, tree sizes (as used uid/username is saved in trees) + let mut b = f.debug_struct("TestSnap"); + b.field("files_new", &s.files_new); + b.field("files_changed", &s.files_changed); + b.field("files_unmodified", &s.files_unmodified); + b.field("total_files_processed", &s.total_files_processed); + b.field("total_bytes_processed", &s.total_bytes_processed); + b.field("dirs_new", &s.dirs_new); + b.field("dirs_changed", &s.dirs_changed); + b.field("dirs_unmodified", &s.dirs_unmodified); + b.field("total_dirs_processed", &s.total_dirs_processed); + b.field("data_blobs", &s.data_blobs); + b.field("tree_blobs", &s.tree_blobs); + b.field("data_added_files", &s.data_added_files); + b.field("data_added_files_packed", &s.data_added_files_packed); + b.finish() + } +} + +#[test] +fn backup() -> Result<()> { + // SimpleLogger::init(log::LevelFilter::Debug, Config::default())?; + let source = set_up_testdata("backup-data.tar.gz")?; + let paths = &source.paths()?; + let repo = set_up_repo()?.to_indexed_ids()?; + let opts = BackupOptions::default(); + + // first backup + let snap1 = repo.backup(&opts, paths, SnapshotFile::default())?; + assert_debug_snapshot!(TestSummary(&snap1)); + assert_eq!(snap1.parent, None); + assert_eq!(snap1.paths, source.strings()?); + + // get all snapshots and check them + let snaps = repo.get_all_snapshots()?; + assert_eq!(vec![snap1.clone()], snaps); + // save list of pack files + let packs1: Vec<_> = repo.list(rustic_core::FileType::Pack)?.collect(); + + // re-read index + let repo = repo.to_indexed_ids()?; + // second backup + let snap2 = repo.backup(&opts, paths, SnapshotFile::default())?; + assert_debug_snapshot!(TestSummary(&snap2)); + assert_eq!(snap2.parent, Some(snap1.id)); + assert_eq!(snap1.tree, snap2.tree); + + // get all snapshots and check them + let mut snaps = repo.get_all_snapshots()?; + snaps.sort_unstable(); + assert_eq!(vec![snap1, snap2], snaps); + + // pack files should be unchanged + let packs2: Vec<_> = repo.list(rustic_core::FileType::Pack)?.collect(); + assert_eq!(packs1, packs2); + Ok(()) +} + +#[test] +fn backup_dry_run() -> Result<()> { + let source = &set_up_testdata("backup-data.tar.gz")?; + let paths = &source.paths()?; + let repo = set_up_repo()?.to_indexed_ids()?; + let opts = BackupOptions::default().dry_run(true); + + // dry-run backup + let snap_dry_run = repo.backup(&opts, paths, SnapshotFile::default())?; + assert_debug_snapshot!(TestSummary(&snap_dry_run)); + // check that repo is still empty + let snaps = repo.get_all_snapshots()?; + assert_eq!(snaps.len(), 0); + let packs: Vec<_> = repo.list(rustic_core::FileType::Pack)?.collect(); + assert_eq!(packs.len(), 0); + let indexes: Vec<_> = repo.list(rustic_core::FileType::Index)?.collect(); + assert_eq!(indexes.len(), 0); + + // first real backup + let opts = opts.dry_run(false); + let snap1 = repo.backup(&opts, paths, SnapshotFile::default())?; + assert_eq!(snap_dry_run.tree, snap1.tree); + let packs: Vec<_> = repo.list(rustic_core::FileType::Pack)?.collect(); + + // re-read index + let repo = repo.to_indexed_ids()?; + // second dry-run backup + let opts = opts.dry_run(true); + let snap_dry_run = repo.backup(&opts, paths, SnapshotFile::default())?; + assert_debug_snapshot!(TestSummary(&snap_dry_run)); + // check that no data has been added + let snaps = repo.get_all_snapshots()?; + assert_eq!(snaps, vec![snap1.clone()]); + let packs_dry_run: Vec<_> = repo.list(rustic_core::FileType::Pack)?.collect(); + assert_eq!(packs_dry_run, packs); + + // re-read index + let repo = repo.to_indexed_ids()?; + // second real backup + let opts = opts.dry_run(false); + let snap2 = repo.backup(&opts, paths, SnapshotFile::default())?; + assert_eq!(snap_dry_run.tree, snap2.tree); + Ok(()) +} diff --git a/crates/core/tests/snapshots/integration__backup-2.snap b/crates/core/tests/snapshots/integration__backup-2.snap new file mode 100644 index 00000000..f74a1250 --- /dev/null +++ b/crates/core/tests/snapshots/integration__backup-2.snap @@ -0,0 +1,19 @@ +--- +source: crates/core/tests/integration.rs +expression: TestSnap(&snap2) +--- +TestSnap { + files_new: 0, + files_changed: 0, + files_unmodified: 73, + total_files_processed: 73, + total_bytes_processed: 1125682, + dirs_new: 0, + dirs_changed: 0, + dirs_unmodified: 7, + total_dirs_processed: 7, + data_blobs: 0, + tree_blobs: 0, + data_added_files: 0, + data_added_files_packed: 0, +} diff --git a/crates/core/tests/snapshots/integration__backup.snap b/crates/core/tests/snapshots/integration__backup.snap new file mode 100644 index 00000000..dedc22bf --- /dev/null +++ b/crates/core/tests/snapshots/integration__backup.snap @@ -0,0 +1,19 @@ +--- +source: crates/core/tests/integration.rs +expression: TestSnap(&snap1) +--- +TestSnap { + files_new: 73, + files_changed: 0, + files_unmodified: 0, + total_files_processed: 73, + total_bytes_processed: 1125674, + dirs_new: 7, + dirs_changed: 0, + dirs_unmodified: 0, + total_dirs_processed: 7, + data_blobs: 70, + tree_blobs: 7, + data_added_files: 1125653, + data_added_files_packed: 78740, +} diff --git a/crates/core/tests/snapshots/integration__backup_dry_run-2.snap b/crates/core/tests/snapshots/integration__backup_dry_run-2.snap new file mode 100644 index 00000000..0c2d561c --- /dev/null +++ b/crates/core/tests/snapshots/integration__backup_dry_run-2.snap @@ -0,0 +1,19 @@ +--- +source: crates/core/tests/integration.rs +expression: TestSnap(&snap_dry_run) +--- +TestSnap { + files_new: 0, + files_changed: 0, + files_unmodified: 73, + total_files_processed: 73, + total_bytes_processed: 1125682, + dirs_new: 0, + dirs_changed: 0, + dirs_unmodified: 7, + total_dirs_processed: 7, + data_blobs: 0, + tree_blobs: 0, + data_added_files: 0, + data_added_files_packed: 0, +} diff --git a/crates/core/tests/snapshots/integration__backup_dry_run.snap b/crates/core/tests/snapshots/integration__backup_dry_run.snap new file mode 100644 index 00000000..2d2d2ac2 --- /dev/null +++ b/crates/core/tests/snapshots/integration__backup_dry_run.snap @@ -0,0 +1,19 @@ +--- +source: crates/core/tests/integration.rs +expression: TestSnap(&snap_dry_run) +--- +TestSnap { + files_new: 73, + files_changed: 0, + files_unmodified: 0, + total_files_processed: 73, + total_bytes_processed: 1125674, + dirs_new: 7, + dirs_changed: 0, + dirs_unmodified: 0, + total_dirs_processed: 7, + data_blobs: 70, + tree_blobs: 7, + data_added_files: 1125653, + data_added_files_packed: 78740, +} diff --git a/crates/core/tests/testdata/backup-data.tar.gz b/crates/core/tests/testdata/backup-data.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..6ba5881ae4f2a1824bd9a7978ba772a6f86d5384 GIT binary patch literal 11704 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 literal 0 HcmV?d00001 From f2ce7dce420120aea82b5bdbfd372ba24c267665 Mon Sep 17 00:00:00 2001 From: Alexander Weiss Date: Sat, 9 Mar 2024 16:41:06 +0100 Subject: [PATCH 02/46] temporary: Add logging output --- crates/core/tests/integration.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index 6d16470d..62d10e05 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -9,6 +9,7 @@ use rustic_core::{ NoProgressBars, OpenStatus, PathList, Repository, RepositoryBackends, RepositoryOptions, StringList, }; +use simplelog::{Config, SimpleLogger}; use tar::Archive; use tempfile::{tempdir, TempDir}; @@ -79,7 +80,7 @@ impl<'a> std::fmt::Debug for TestSummary<'a> { #[test] fn backup() -> Result<()> { - // SimpleLogger::init(log::LevelFilter::Debug, Config::default())?; + SimpleLogger::init(log::LevelFilter::Debug, Config::default())?; let source = set_up_testdata("backup-data.tar.gz")?; let paths = &source.paths()?; let repo = set_up_repo()?.to_indexed_ids()?; From e5f883f15bc4dcdde08fd202bfd1089d56b4d37e Mon Sep 17 00:00:00 2001 From: Alexander Weiss Date: Sat, 9 Mar 2024 19:48:17 +0100 Subject: [PATCH 03/46] use as_path --- crates/core/tests/integration.rs | 35 ++++++++++++------- .../snapshots/integration__backup-2.snap | 16 +++++++-- .../tests/snapshots/integration__backup.snap | 18 +++++++--- .../integration__backup_dry_run-2.snap | 16 +++++++-- .../integration__backup_dry_run.snap | 18 +++++++--- 5 files changed, 77 insertions(+), 26 deletions(-) diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index 62d10e05..5f4f0ce3 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -1,4 +1,10 @@ -use std::{env, fs::File, path::Path, str::FromStr, sync::Arc}; +use std::{ + env, + fs::File, + path::{Path, PathBuf}, + str::FromStr, + sync::Arc, +}; use anyhow::Result; use flate2::read::GzDecoder; @@ -7,9 +13,9 @@ use pretty_assertions::assert_eq; use rustic_core::{ repofile::SnapshotFile, BackupOptions, ConfigOptions, InMemoryBackend, KeyOptions, NoProgressBars, OpenStatus, PathList, Repository, RepositoryBackends, RepositoryOptions, - StringList, }; -use simplelog::{Config, SimpleLogger}; +// uncomment for logging output +// use simplelog::{Config, SimpleLogger}; use tar::Archive; use tempfile::{tempdir, TempDir}; @@ -34,10 +40,6 @@ impl TestSource { fn paths(&self) -> Result { Ok(PathList::from_string(self.0.path().to_str().unwrap())?) } - - fn strings(&self) -> Result { - Ok(StringList::from_str(self.0.path().to_str().unwrap())?) - } } fn set_up_testdata(path: impl AsRef) -> Result { @@ -57,10 +59,15 @@ struct TestSummary<'a>(&'a SnapshotFile); impl<'a> std::fmt::Debug for TestSummary<'a> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let s = self.0.summary.as_ref().unwrap(); // leave out info we expect to change: // Ids, times, tree sizes (as used uid/username is saved in trees) let mut b = f.debug_struct("TestSnap"); + b.field("hostname", &self.0.hostname); + b.field("paths", &self.0.paths); + b.field("label", &self.0.label); + b.field("tags", &self.0.tags); + + let s = self.0.summary.as_ref().unwrap(); b.field("files_new", &s.files_new); b.field("files_changed", &s.files_changed); b.field("files_unmodified", &s.files_unmodified); @@ -80,17 +87,18 @@ impl<'a> std::fmt::Debug for TestSummary<'a> { #[test] fn backup() -> Result<()> { - SimpleLogger::init(log::LevelFilter::Debug, Config::default())?; + // uncomment for logging output + // SimpleLogger::init(log::LevelFilter::Debug, Config::default())?; let source = set_up_testdata("backup-data.tar.gz")?; let paths = &source.paths()?; let repo = set_up_repo()?.to_indexed_ids()?; - let opts = BackupOptions::default(); + // we use as_path to not depend on the actual tempdir + let opts = BackupOptions::default().as_path(PathBuf::from_str("test")?); // first backup let snap1 = repo.backup(&opts, paths, SnapshotFile::default())?; assert_debug_snapshot!(TestSummary(&snap1)); assert_eq!(snap1.parent, None); - assert_eq!(snap1.paths, source.strings()?); // get all snapshots and check them let snaps = repo.get_all_snapshots()?; @@ -122,7 +130,10 @@ fn backup_dry_run() -> Result<()> { let source = &set_up_testdata("backup-data.tar.gz")?; let paths = &source.paths()?; let repo = set_up_repo()?.to_indexed_ids()?; - let opts = BackupOptions::default().dry_run(true); + // we use as_path to not depend on the actual tempdir + let opts = BackupOptions::default() + .as_path(PathBuf::from_str("test")?) + .dry_run(true); // dry-run backup let snap_dry_run = repo.backup(&opts, paths, SnapshotFile::default())?; diff --git a/crates/core/tests/snapshots/integration__backup-2.snap b/crates/core/tests/snapshots/integration__backup-2.snap index f74a1250..52a022e2 100644 --- a/crates/core/tests/snapshots/integration__backup-2.snap +++ b/crates/core/tests/snapshots/integration__backup-2.snap @@ -1,8 +1,18 @@ --- source: crates/core/tests/integration.rs -expression: TestSnap(&snap2) +expression: TestSummary(&snap2) --- TestSnap { + hostname: "", + paths: StringList( + [ + "test", + ], + ), + label: "", + tags: StringList( + [], + ), files_new: 0, files_changed: 0, files_unmodified: 73, @@ -10,8 +20,8 @@ TestSnap { total_bytes_processed: 1125682, dirs_new: 0, dirs_changed: 0, - dirs_unmodified: 7, - total_dirs_processed: 7, + dirs_unmodified: 6, + total_dirs_processed: 6, data_blobs: 0, tree_blobs: 0, data_added_files: 0, diff --git a/crates/core/tests/snapshots/integration__backup.snap b/crates/core/tests/snapshots/integration__backup.snap index dedc22bf..209647bb 100644 --- a/crates/core/tests/snapshots/integration__backup.snap +++ b/crates/core/tests/snapshots/integration__backup.snap @@ -1,19 +1,29 @@ --- source: crates/core/tests/integration.rs -expression: TestSnap(&snap1) +expression: TestSummary(&snap1) --- TestSnap { + hostname: "", + paths: StringList( + [ + "test", + ], + ), + label: "", + tags: StringList( + [], + ), files_new: 73, files_changed: 0, files_unmodified: 0, total_files_processed: 73, total_bytes_processed: 1125674, - dirs_new: 7, + dirs_new: 6, dirs_changed: 0, dirs_unmodified: 0, - total_dirs_processed: 7, + total_dirs_processed: 6, data_blobs: 70, - tree_blobs: 7, + tree_blobs: 6, data_added_files: 1125653, data_added_files_packed: 78740, } diff --git a/crates/core/tests/snapshots/integration__backup_dry_run-2.snap b/crates/core/tests/snapshots/integration__backup_dry_run-2.snap index 0c2d561c..632d04ee 100644 --- a/crates/core/tests/snapshots/integration__backup_dry_run-2.snap +++ b/crates/core/tests/snapshots/integration__backup_dry_run-2.snap @@ -1,8 +1,18 @@ --- source: crates/core/tests/integration.rs -expression: TestSnap(&snap_dry_run) +expression: TestSummary(&snap_dry_run) --- TestSnap { + hostname: "", + paths: StringList( + [ + "test", + ], + ), + label: "", + tags: StringList( + [], + ), files_new: 0, files_changed: 0, files_unmodified: 73, @@ -10,8 +20,8 @@ TestSnap { total_bytes_processed: 1125682, dirs_new: 0, dirs_changed: 0, - dirs_unmodified: 7, - total_dirs_processed: 7, + dirs_unmodified: 6, + total_dirs_processed: 6, data_blobs: 0, tree_blobs: 0, data_added_files: 0, diff --git a/crates/core/tests/snapshots/integration__backup_dry_run.snap b/crates/core/tests/snapshots/integration__backup_dry_run.snap index 2d2d2ac2..5663f447 100644 --- a/crates/core/tests/snapshots/integration__backup_dry_run.snap +++ b/crates/core/tests/snapshots/integration__backup_dry_run.snap @@ -1,19 +1,29 @@ --- source: crates/core/tests/integration.rs -expression: TestSnap(&snap_dry_run) +expression: TestSummary(&snap_dry_run) --- TestSnap { + hostname: "", + paths: StringList( + [ + "test", + ], + ), + label: "", + tags: StringList( + [], + ), files_new: 73, files_changed: 0, files_unmodified: 0, total_files_processed: 73, total_bytes_processed: 1125674, - dirs_new: 7, + dirs_new: 6, dirs_changed: 0, dirs_unmodified: 0, - total_dirs_processed: 7, + total_dirs_processed: 6, data_blobs: 70, - tree_blobs: 7, + tree_blobs: 6, data_added_files: 1125653, data_added_files_packed: 78740, } From 6cc4309ff1fff89506a9a8fe582b49052bafb81a Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Tue, 12 Mar 2024 15:46:46 +0100 Subject: [PATCH 04/46] impl from_iter Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- .gitignore | 3 + crates/core/src/backend.rs | 8 ++- crates/core/src/lib.rs | 4 +- crates/core/src/repofile/snapshotfile.rs | 17 +++++ crates/core/tests/integration.rs | 79 ++++++++++++------------ 5 files changed, 70 insertions(+), 41 deletions(-) diff --git a/.gitignore b/.gitignore index 0e341ea3..0a0a1985 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,6 @@ coverage/*.info # local repo config .cargo/config.toml + +# Generated by Tests +crates/core/tests/generated/ diff --git a/crates/core/src/backend.rs b/crates/core/src/backend.rs index ffb327c0..49def321 100644 --- a/crates/core/src/backend.rs +++ b/crates/core/src/backend.rs @@ -565,6 +565,7 @@ pub mod in_memory_backend { impl InMemoryBackend { /// Create a new (empty) `InMemoryBackend` + #[must_use] pub fn new() -> Self { Self(RwLock::new(EnumMap::from_fn(|_| BTreeMap::new()))) } @@ -584,7 +585,12 @@ pub mod in_memory_backend { fn list_with_size(&self, tpe: FileType) -> Result> { Ok(self.0.read().unwrap()[tpe] .iter() - .map(|(id, byte)| (*id, byte.len() as u32)) + .map(|(id, byte)| { + ( + *id, + u32::try_from(byte.len()).expect("byte length is too large"), + ) + }) .collect()) } diff --git a/crates/core/src/lib.rs b/crates/core/src/lib.rs index 63bd3047..1c8edc56 100644 --- a/crates/core/src/lib.rs +++ b/crates/core/src/lib.rs @@ -45,10 +45,10 @@ implement [`serde::Serialize`] and [`serde::Deserialize`]. let config_opts = ConfigOptions::default(); - let _repo = Repository::new(&repo_opts, backends.clone()).unwrap().init(&key_opts, &config_opts).unwrap(); + let _repo = Repository::new(&repo_opts, &backends.clone()).unwrap().init(&key_opts, &config_opts).unwrap(); // We could have used _repo directly, but open the repository again to show how to open it... - let repo = Repository::new(&repo_opts, backends).unwrap().open().unwrap(); + let repo = Repository::new(&repo_opts, &backends).unwrap().open().unwrap(); // Get all snapshots from the repository let snaps = repo.get_all_snapshots().unwrap(); diff --git a/crates/core/src/repofile/snapshotfile.rs b/crates/core/src/repofile/snapshotfile.rs index 95af1e61..e38db6c3 100644 --- a/crates/core/src/repofile/snapshotfile.rs +++ b/crates/core/src/repofile/snapshotfile.rs @@ -1119,6 +1119,23 @@ impl PathList { ) } + /// Create a `PathList` from a list of `PathBuf`s. + /// + /// # Arguments + /// + /// * `source` - The `PathBuf`s to use + /// + /// # Returns + /// + /// A `PathList` containing the `PathBuf`s + pub fn from_iter(source: I) -> Self + where + I: IntoIterator, + I::Item: Into, + { + Self(source.into_iter().map(Into::into).collect()) + } + /// Create a `PathList` by parsing a Strings containing paths separated by whitspaces. /// /// # Arguments diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index 5f4f0ce3..b82f2234 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -23,7 +23,7 @@ fn set_up_repo() -> Result> { let be = InMemoryBackend::new(); let be = RepositoryBackends::new(Arc::new(be), None); let options = RepositoryOptions::default().password("test"); - let repo = Repository::new(&options, be)?; + let repo = Repository::new(&options, &be)?; let key_opts = KeyOptions::default(); let config_opts = &ConfigOptions::default(); let repo = repo.init(&key_opts, config_opts)?; @@ -38,7 +38,11 @@ impl TestSource { } fn paths(&self) -> Result { - Ok(PathList::from_string(self.0.path().to_str().unwrap())?) + let sources = self.0.path().to_str().unwrap(); + + let path_list = PathList::from_string(sources)?; + + Ok(path_list) } } @@ -62,25 +66,25 @@ impl<'a> std::fmt::Debug for TestSummary<'a> { // leave out info we expect to change: // Ids, times, tree sizes (as used uid/username is saved in trees) let mut b = f.debug_struct("TestSnap"); - b.field("hostname", &self.0.hostname); - b.field("paths", &self.0.paths); - b.field("label", &self.0.label); - b.field("tags", &self.0.tags); + _ = b.field("hostname", &self.0.hostname); + _ = b.field("paths", &self.0.paths); + _ = b.field("label", &self.0.label); + _ = b.field("tags", &self.0.tags); let s = self.0.summary.as_ref().unwrap(); - b.field("files_new", &s.files_new); - b.field("files_changed", &s.files_changed); - b.field("files_unmodified", &s.files_unmodified); - b.field("total_files_processed", &s.total_files_processed); - b.field("total_bytes_processed", &s.total_bytes_processed); - b.field("dirs_new", &s.dirs_new); - b.field("dirs_changed", &s.dirs_changed); - b.field("dirs_unmodified", &s.dirs_unmodified); - b.field("total_dirs_processed", &s.total_dirs_processed); - b.field("data_blobs", &s.data_blobs); - b.field("tree_blobs", &s.tree_blobs); - b.field("data_added_files", &s.data_added_files); - b.field("data_added_files_packed", &s.data_added_files_packed); + _ = b.field("files_new", &s.files_new); + _ = b.field("files_changed", &s.files_changed); + _ = b.field("files_unmodified", &s.files_unmodified); + _ = b.field("total_files_processed", &s.total_files_processed); + _ = b.field("total_bytes_processed", &s.total_bytes_processed); + _ = b.field("dirs_new", &s.dirs_new); + _ = b.field("dirs_changed", &s.dirs_changed); + _ = b.field("dirs_unmodified", &s.dirs_unmodified); + _ = b.field("total_dirs_processed", &s.total_dirs_processed); + _ = b.field("data_blobs", &s.data_blobs); + _ = b.field("tree_blobs", &s.tree_blobs); + _ = b.field("data_added_files", &s.data_added_files); + _ = b.field("data_added_files_packed", &s.data_added_files_packed); b.finish() } } @@ -91,18 +95,19 @@ fn backup() -> Result<()> { // SimpleLogger::init(log::LevelFilter::Debug, Config::default())?; let source = set_up_testdata("backup-data.tar.gz")?; let paths = &source.paths()?; + let repo = set_up_repo()?.to_indexed_ids()?; // we use as_path to not depend on the actual tempdir let opts = BackupOptions::default().as_path(PathBuf::from_str("test")?); // first backup - let snap1 = repo.backup(&opts, paths, SnapshotFile::default())?; - assert_debug_snapshot!(TestSummary(&snap1)); - assert_eq!(snap1.parent, None); + let first_backup = repo.backup(&opts, paths, SnapshotFile::default())?; + assert_debug_snapshot!(TestSummary(&first_backup)); + assert_eq!(first_backup.parent, None); // get all snapshots and check them - let snaps = repo.get_all_snapshots()?; - assert_eq!(vec![snap1.clone()], snaps); + let all_snapshots = repo.get_all_snapshots()?; + assert_eq!(vec![first_backup.clone()], all_snapshots); // save list of pack files let packs1: Vec<_> = repo.list(rustic_core::FileType::Pack)?.collect(); @@ -111,13 +116,13 @@ fn backup() -> Result<()> { // second backup let snap2 = repo.backup(&opts, paths, SnapshotFile::default())?; assert_debug_snapshot!(TestSummary(&snap2)); - assert_eq!(snap2.parent, Some(snap1.id)); - assert_eq!(snap1.tree, snap2.tree); + assert_eq!(snap2.parent, Some(first_backup.id)); + assert_eq!(first_backup.tree, snap2.tree); // get all snapshots and check them - let mut snaps = repo.get_all_snapshots()?; - snaps.sort_unstable(); - assert_eq!(vec![snap1, snap2], snaps); + let mut all_snapshots = repo.get_all_snapshots()?; + all_snapshots.sort_unstable(); + assert_eq!(vec![first_backup, snap2], all_snapshots); // pack files should be unchanged let packs2: Vec<_> = repo.list(rustic_core::FileType::Pack)?.collect(); @@ -141,15 +146,13 @@ fn backup_dry_run() -> Result<()> { // check that repo is still empty let snaps = repo.get_all_snapshots()?; assert_eq!(snaps.len(), 0); - let packs: Vec<_> = repo.list(rustic_core::FileType::Pack)?.collect(); - assert_eq!(packs.len(), 0); - let indexes: Vec<_> = repo.list(rustic_core::FileType::Index)?.collect(); - assert_eq!(indexes.len(), 0); + assert_eq!(repo.list(rustic_core::FileType::Pack)?.count(), 0); + assert_eq!(repo.list(rustic_core::FileType::Index)?.count(), 0); // first real backup let opts = opts.dry_run(false); - let snap1 = repo.backup(&opts, paths, SnapshotFile::default())?; - assert_eq!(snap_dry_run.tree, snap1.tree); + let first_snapshot = repo.backup(&opts, paths, SnapshotFile::default())?; + assert_eq!(snap_dry_run.tree, first_snapshot.tree); let packs: Vec<_> = repo.list(rustic_core::FileType::Pack)?.collect(); // re-read index @@ -160,7 +163,7 @@ fn backup_dry_run() -> Result<()> { assert_debug_snapshot!(TestSummary(&snap_dry_run)); // check that no data has been added let snaps = repo.get_all_snapshots()?; - assert_eq!(snaps, vec![snap1.clone()]); + assert_eq!(snaps, vec![first_snapshot]); let packs_dry_run: Vec<_> = repo.list(rustic_core::FileType::Pack)?.collect(); assert_eq!(packs_dry_run, packs); @@ -168,7 +171,7 @@ fn backup_dry_run() -> Result<()> { let repo = repo.to_indexed_ids()?; // second real backup let opts = opts.dry_run(false); - let snap2 = repo.backup(&opts, paths, SnapshotFile::default())?; - assert_eq!(snap_dry_run.tree, snap2.tree); + let second_snapshot = repo.backup(&opts, paths, SnapshotFile::default())?; + assert_eq!(snap_dry_run.tree, second_snapshot.tree); Ok(()) } From e38d7e3cf12dee3e330de69d1df8b11c3eeff697 Mon Sep 17 00:00:00 2001 From: Alexander Weiss Date: Tue, 12 Mar 2024 16:00:45 +0100 Subject: [PATCH 05/46] use PathList::from_iter --- crates/core/tests/integration.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index b82f2234..344dadb2 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -37,12 +37,8 @@ impl TestSource { Self(tmp) } - fn paths(&self) -> Result { - let sources = self.0.path().to_str().unwrap(); - - let path_list = PathList::from_string(sources)?; - - Ok(path_list) + fn paths(&self) -> PathList { + PathList::from_iter(Some(self.0.path().to_path_buf())) } } @@ -94,7 +90,7 @@ fn backup() -> Result<()> { // uncomment for logging output // SimpleLogger::init(log::LevelFilter::Debug, Config::default())?; let source = set_up_testdata("backup-data.tar.gz")?; - let paths = &source.paths()?; + let paths = &source.paths(); let repo = set_up_repo()?.to_indexed_ids()?; // we use as_path to not depend on the actual tempdir @@ -133,7 +129,7 @@ fn backup() -> Result<()> { #[test] fn backup_dry_run() -> Result<()> { let source = &set_up_testdata("backup-data.tar.gz")?; - let paths = &source.paths()?; + let paths = &source.paths(); let repo = set_up_repo()?.to_indexed_ids()?; // we use as_path to not depend on the actual tempdir let opts = BackupOptions::default() From 72add8944531461b044096eece5c3c6e798d09a4 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Tue, 12 Mar 2024 16:11:41 +0100 Subject: [PATCH 06/46] impl FromIterator for PathList Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/core/src/commands/merge.rs | 7 ++- crates/core/src/repofile/snapshotfile.rs | 55 ++++++++++-------------- 2 files changed, 28 insertions(+), 34 deletions(-) diff --git a/crates/core/src/commands/merge.rs b/crates/core/src/commands/merge.rs index fb86412c..63cf7c32 100644 --- a/crates/core/src/commands/merge.rs +++ b/crates/core/src/commands/merge.rs @@ -39,7 +39,12 @@ pub(crate) fn merge_snapshots( ) -> RusticResult { let now = Local::now(); - let paths = PathList::from_strings(snapshots.iter().flat_map(|snap| snap.paths.iter())).merge(); + let paths = snapshots + .iter() + .flat_map(|snap| snap.paths.iter()) + .collect::() + .merge(); + snap.paths.set_paths(&paths.paths())?; // set snapshot time to time of latest snapshot to be merged diff --git a/crates/core/src/repofile/snapshotfile.rs b/crates/core/src/repofile/snapshotfile.rs index e38db6c3..808a32d7 100644 --- a/crates/core/src/repofile/snapshotfile.rs +++ b/crates/core/src/repofile/snapshotfile.rs @@ -1100,42 +1100,31 @@ impl Display for PathList { } } -impl PathList { - /// Create a `PathList` from `String`s. - /// - /// # Arguments - /// - /// * `source` - The `String`s to use - pub fn from_strings(source: I) -> Self - where - I: IntoIterator, - I::Item: AsRef, - { - Self( - source - .into_iter() - .map(|source| PathBuf::from(source.as_ref())) - .collect(), - ) +impl FromIterator for PathList { + fn from_iter>(iter: I) -> Self { + Self(iter.into_iter().collect()) } +} - /// Create a `PathList` from a list of `PathBuf`s. - /// - /// # Arguments - /// - /// * `source` - The `PathBuf`s to use - /// - /// # Returns - /// - /// A `PathList` containing the `PathBuf`s - pub fn from_iter(source: I) -> Self - where - I: IntoIterator, - I::Item: Into, - { - Self(source.into_iter().map(Into::into).collect()) +impl<'a> FromIterator<&'a String> for PathList { + fn from_iter>(iter: I) -> Self { + Self(iter.into_iter().map(PathBuf::from).collect()) } +} +impl FromIterator for PathList { + fn from_iter>(iter: I) -> Self { + Self(iter.into_iter().map(PathBuf::from).collect()) + } +} + +impl<'a> FromIterator<&'a str> for PathList { + fn from_iter>(iter: I) -> Self { + Self(iter.into_iter().map(PathBuf::from).collect()) + } +} + +impl PathList { /// Create a `PathList` by parsing a Strings containing paths separated by whitspaces. /// /// # Arguments @@ -1149,7 +1138,7 @@ impl PathList { /// [`SnapshotFileErrorKind::FromSplitError`]: crate::error::SnapshotFileErrorKind::FromSplitError pub fn from_string(sources: &str) -> RusticResult { let sources = split(sources).map_err(SnapshotFileErrorKind::FromSplitError)?; - Ok(Self::from_strings(sources)) + Ok(Self::from_iter(sources)) } /// Number of paths in the `PathList`. From e5033cb5d3be3bc1e18bb7efdc20d8d9f1109fb8 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Tue, 12 Mar 2024 17:14:09 +0100 Subject: [PATCH 07/46] refactor test Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- .github/workflows/ci.yml | 12 +++ .../{testdata => fixtures}/backup-data.tar.gz | Bin crates/core/tests/fixtures/backup-data/0/9/0 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/1 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/10 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/11 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/12 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/13 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/14 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/15 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/16 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/17 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/18 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/19 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/2 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/20 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/21 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/22 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/23 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/24 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/25 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/26 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/27 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/28 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/29 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/3 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/30 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/31 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/32 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/33 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/34 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/35 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/36 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/37 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/38 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/39 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/4 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/40 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/41 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/42 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/43 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/44 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/45 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/46 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/47 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/48 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/49 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/5 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/50 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/51 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/52 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/53 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/54 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/55 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/56 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/57 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/58 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/59 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/6 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/60 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/61 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/62 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/63 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/64 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/65 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/66 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/67 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/68 | Bin 0 -> 11520 bytes crates/core/tests/fixtures/backup-data/0/9/7 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/8 | Bin 0 -> 16384 bytes crates/core/tests/fixtures/backup-data/0/9/9 | Bin 0 -> 16384 bytes .../fixtures/backup-data/tests/empty-file | 0 .../tests/fixtures/backup-data/tests/testfile | 1 + .../backup-data/tests/testfile-hardlink | 1 + .../backup-data/tests/testfile-symlink | 1 + crates/core/tests/integration.rs | 99 +++++++++++++----- .../snapshots/integration__backup-2.snap | 29 ----- .../tests/snapshots/integration__backup.snap | 29 ----- .../integration__backup_dry_run-2.snap | 29 ----- .../integration__backup_dry_run.snap | 29 ----- 80 files changed, 89 insertions(+), 141 deletions(-) rename crates/core/tests/{testdata => fixtures}/backup-data.tar.gz (100%) create mode 100644 crates/core/tests/fixtures/backup-data/0/9/0 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/1 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/10 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/11 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/12 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/13 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/14 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/15 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/16 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/17 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/18 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/19 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/2 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/20 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/21 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/22 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/23 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/24 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/25 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/26 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/27 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/28 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/29 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/3 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/30 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/31 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/32 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/33 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/34 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/35 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/36 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/37 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/38 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/39 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/4 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/40 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/41 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/42 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/43 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/44 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/45 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/46 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/47 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/48 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/49 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/5 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/50 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/51 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/52 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/53 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/54 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/55 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/56 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/57 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/58 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/59 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/6 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/60 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/61 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/62 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/63 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/64 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/65 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/66 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/67 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/68 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/7 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/8 create mode 100644 crates/core/tests/fixtures/backup-data/0/9/9 create mode 100644 crates/core/tests/fixtures/backup-data/tests/empty-file create mode 100644 crates/core/tests/fixtures/backup-data/tests/testfile create mode 100644 crates/core/tests/fixtures/backup-data/tests/testfile-hardlink create mode 120000 crates/core/tests/fixtures/backup-data/tests/testfile-symlink delete mode 100644 crates/core/tests/snapshots/integration__backup-2.snap delete mode 100644 crates/core/tests/snapshots/integration__backup.snap delete mode 100644 crates/core/tests/snapshots/integration__backup_dry_run-2.snap delete mode 100644 crates/core/tests/snapshots/integration__backup_dry_run.snap diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 24f9b262..854bd8ec 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,6 +4,9 @@ concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true +env: + CI: true + on: pull_request: paths: @@ -86,6 +89,15 @@ jobs: - uses: Swatinem/rust-cache@23bce251a8cd2ffc3c1075eaa2367cf899916d84 # v2 - name: Run Cargo Test run: cargo +${{ matrix.rust }} test -r --all-targets --all-features --workspace --examples + id: run_tests + env: + INSTA_UPDATE: new + - name: Upload snapshots of failed tests + if: ${{ failure() && steps.run_tests.outcome == 'failure' }} + uses: actions/upload-artifact@v3 + with: + name: failed-snapshots-${{ matrix.job.os }} + path: "**/snapshots/*.snap.new" docs: name: Build docs diff --git a/crates/core/tests/testdata/backup-data.tar.gz b/crates/core/tests/fixtures/backup-data.tar.gz similarity index 100% rename from crates/core/tests/testdata/backup-data.tar.gz rename to crates/core/tests/fixtures/backup-data.tar.gz diff --git a/crates/core/tests/fixtures/backup-data/0/9/0 b/crates/core/tests/fixtures/backup-data/0/9/0 new file mode 100644 index 0000000000000000000000000000000000000000..187e73b7363ee200f2591a333fe551aab518d084 GIT binary patch literal 16384 zcmeI!`8(Tp0KoBJsKii5_e5LAknvEgq;%#=J4e(VN2QOdTTpei?$&)YRTRbYq>j~5 zIa*Rzn1#+=L9JL_Q{sq}%HU!(956xTW5s*Dh(FnRIcc(>G8ZUZXaDP;K5v@?u}S1?@Oi5-|~g(OZ>MECM;|)LRnZwI+)m@8d4<}?#Y)3B(yo{+r(@Q zTI9YQjPQSR+cb)&dbcWGAJ#w?xb~*v;dhJ}YL`*B<)Oj?+&rVuPu|RmwNfHBVCR-; z%GDrX(+kS8f+_=g`>{96)f;X-RjK!gCB(gQtd_j?>(|djVm=CHoSva~)C<7LCv%N$ zKm2AbAC1!tUJ8qNouRxMKHxL#V|a11Slq`*PDi3ji$r3iTFrYzSEOxkZ}18e83tDo z8n7Cbe%hWNH_BChVbCecSrp-k&d}APwA)XcyEh?t($THr?1N|pS!8z*_l`^`YaFhf zs5HxS49m67(X$CJ%f=Wf^dXt1R_(PNsUH-dE41S&j5@<{<1~sv#zqh1V>yF!<)>=%x9X^MN5-t}( zT&_7Sxfil%5Qe{iJLoZG^02%EsA84B|-6PFZny ziT4w%t`4a-_6%!&ePU@n$CqKjo?0s2DvYc(WtDpb!|9w7hpleLH(nEp1s+I`OQD>yBezqtbMY^-TouDY3xE*3<&3^cov;Tnfn zKcY>XvG|2_=>Qx7xe`0E?-th>YTLfZE%(~5l9KC`6!cAtNGzg;cphVVZsVn98kZxf z3Vvuf-$3o6*F)6tp;`cKK55PA{{4DAlA+rUXH-nhylOwd)$As7 z9u!cAyN)}T^|MRg#Si!tPYu<=w3E%Hra#*TvL$~}vL2TZBP7l=Q&2}iByaH;)G2a> zJki~|C-E;5KmZ`{pCC{N5C8~(6M*&!yZ{IQ1ONiiMxY)b01yBOKpO!HKmZ^B5P&uU zRDb|L03ZNu1ZV&OfB--M+6d4A0ssMk0JIT!2@n7X00f|oz$<_NKmZ^BZ3G$s0ssMk z0JITk1PA~G00PiPfB_Hy2ml12jlgSw06+jB0Br=C00IC3fB>`+Xa)%UUkLmISzm-2 literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/1 b/crates/core/tests/fixtures/backup-data/0/9/1 new file mode 100644 index 0000000000000000000000000000000000000000..fd161476f6206f5ff917a12077fe498963488802 GIT binary patch literal 16384 zcmeI!`8(Tp0KoBJsKii5_e5LAknvEgq;%#=J4e(VN2QOdTTpei?$&)YRTRbYq>j}w zBpX>BiKao_71WB=H6@OyXsFxldG`B$@AG^=??2-8yv_S2idu%HclGm0N4FA2}C^DEsZF$aMAfB#fGXozbWLQ&| zv>op-g(;(r^?OT-we7gwX{*K5+u?KQDB*Gu#O0dPl6xVG24VOMxFhDRz$;k{>RmWD z&QHDy1RlA}>&X2W!m4Y4y=)Q@;Zz)wlO_8j8D>w+uPsMdfa z;f_<3!X7LYo#}S4ht9+8t{1mbJk~fkrr=24){SzfzS1L@DnjWaKaM}z%hV-?Y-wrM zs-H_9EMr}@3O$DXmu2f@XD}uupwBk0XeHT-MK)VGWOMA>In)?r7-@AkZU!?<6l(Q< zTMtW`HF2KR%{ShC6CvxEvT^nijX09CQ&t>a;{61xt3#@dJ;Rz`pIBPY@ugX?rcphVVZsVn9nwKLR75va}zJc0BuZO7PL$v_PeA1fJ{rmNL zBty3y&ZwB0IY0m)@I@lf1`q%UfD?fB3A6(Q00IC3Xd^%e2mk~C0?H00;mCppC$5fB--MAOLLydH@0d0e}Fs5$FX7{2v1U0t9V_ A7ytkO literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/10 b/crates/core/tests/fixtures/backup-data/0/9/10 new file mode 100644 index 0000000000000000000000000000000000000000..07ba19b69553d69e17d13cac2d50583dbbda59ff GIT binary patch literal 16384 zcmeI!`8(Tp0KoBJsKijDd!nsl$apALQaW>`9T7KiRQjm81yxt;Zrw*yMNzUmsbh5v z$wpR3n1;?>L9JL_Q{sqg zo_<4z!;FQ;a|B;DrcIJ_7^5hU>IvrEmJ4G~z;%+8=lD+HdDgl5HW8E@tg&K0ie-lD zsO?O9tMp8F+IQy2Kjo_Iy&oJ^N=SF@NK3Tsy5DZA#n#&sb6IH7axui^n$yzzp-YD0#0!MuuA4zuvO5@e z;JhGTnCe^_OPw$|ZYDaSHNeo4e_uw6K~u~}SYn$JXYlCni5-DIB>OpV$%lUwUSUMH z1}2Mko}w4^;u)AM_rrZmK4EX8q?PWu&LwmSkLGV*FL&-QJBFztl-~>D1!H|(dgRb; zZLM03b16d<_ElWi3GBacR#V*}*wny&yZGYO6dapozIw#rI<#{cv8ZtB+FtxDc7!a_ z8t}RvmON+bGN)HyviB-d-YIqS>_aAbGe{&7_X;Gt&KawUf7si-pKW1T5_hB zOSX%m>OQRxA*qQKQ>Lu*MnkTnDD@^p;c7Nrtn$aleqKisqPx0Em|?zXC<<%z?3&Jf zIOt@GTHI8CJHKPExx2`*tf1GRo)8) zq=4p-Iz%K^BP;O{dokJJE@y$G_o))ub{x>?c&P<8o`q7Zp0_$g{pBxj88tZbbw;(v zyww+QdY)iw72efc^L(Z1Mh>P#80|XP;zomO9^w7THt{Bs7cyi62_)2N+~k3Kd~=vx z#}cpH`=Ck&*(ELPmmZl^+!*S0g6+LUl$mW_iE32z$G`=K>KDBqpihp}1L+IN>(2M? z)$3D@+;_QS66zNHlf^9~GRQgjWw^)`K@(lGm%_bY*f`RC(zRlcQ}#Mx(6?lIxE7|9 zVj(m0!7hj+{gblwgp>p+X||;SeH={nk&H#3qE#r6J$!nT{-)loa8sf`9Z+5yUZ1CP z(g*bVBiPY{atMAR_ruSHhF^`n>uUlllao%pLyev`tn()Dx>=MSH zVM|HKON{bX_ngN^mA&h6c>c#q-G3B{G?oRg98KBy5QK`ToNNfWQ!TU#8Q~?63L>>T z8`#8d4_W5@G87r`@|IaNU+qp+f&r|FCS?1v;=wn}*v4+-9;+k8MYu&~k-vgDj=fqc zF=+3eWyaGa;WG-$vx6%G`v&kg$~Bs9K2fdrj3dSW>QpUl`}>zq#bVzHXP%yAbk+;O zX`kks+rN7O5cvEE-~a*u0e}FsPrw==01yBOKpO!(KmZ^B5P&uUHUI&D06+lR2-pGy z00IC3Xd_?;5C8}O1fY$8JwN~;01$vS0uBHHfB--M+6XuT1ONg60ca!O1P}lS00f|o yfHOb`+a0Lhe1ONiiM!*dq01)^e5%?GDDSzt# literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/11 b/crates/core/tests/fixtures/backup-data/0/9/11 new file mode 100644 index 0000000000000000000000000000000000000000..c677791629e2ca060ef6fba403e823713782fc0f GIT binary patch literal 16384 zcmeI!2|L?&0KoB-p%OzK-4kttm6V5;m6Xn0X;%?#9gPO*ToECm>T2DsyVdldD3&L6 ztd1es$ciRrp>stAwbHeYDRD$aL)~W2vv<+w|NFj(&+|RTjjM0B>2TUcO~DcAw!OrdhR@6^y&YOk?drk%l^Qh!JU&|M6HiO{)xA>f{O?~rQH*;pmvvx_ z(^|U^&f1%3eE#hp&N{IK6Z%X<)Nfh(^O3#eezNt+bN!5!?qc9Hl@xc zqI;JL6!j^aX__6~ow*ICcmwS|kITe|{>mc7$Xi#{q^u^oy}_1nhk63llv~z_*IKHv zwHHY_JhVcoBI0z_0kw^=X{!j*al%epK**Wfe9m>aB!mn*I-brmB#aE%EA*T6a7?s5 z6tiN{B@X>O#U(9J1oS0^6ibCstc77+GgUKdtZD1Y}))xz# z***(mLYv&c!<8$g9^J(|Faw0%2U&t_u&d3S5w>D#Qf+iNRahc8iwoa{{U44v+D^x& zQM)fB6wIaK1T2TSZIRgZxtJ4&j9|{MCyZhH8S>4+uWDf_<93(E&2w$nUq)%Ur!5`2 z$7KxUtd$f-76m@So0~DK;|~fZ7e{6mbAq_%L~mvaSMsB4_7;TN%%rkWJKhm%q2~b7 zumO=bcblzP{^O${-)&`uH8WjIpHv|XiM4*}ec~1zxnn`%y_T5Nt*h3L5*>;nP2)mx z(_Bff9UjQHdLo=`SACpGvT{}vnN|t=#?!XKe=?UA+(@rML}87xlO71BQe1C{CPn6Z z<=QPf!S!yZnqWiONL1y7(-!h?iq^U4-gjSTR(ef1eF10Rmo3l1+ZwB$%~tr`!4%4& zJ$sujv*5-gHgoxCB(sLeGRi-76HPxYa zLYaXoap?W5G989jU}y3_%o}Bwb=gmP^yd2(CfK5k9`o)hXWjj^m-*4^i;Sn}5Fu-7O3^(*ms>8EnD ze|7SWW@Inj>;!l^LSI2sgU)C*2&>SJ^p&ZG(4Ko(y2Pyr&)xq;7!~~Ds(p;q;Ce-( zC9Hw9@BE9hyT(=cZ0fZB!Rsc{s6TY8sKJ>t3(>FYfjGe*TE}>tnJbLbK|n-QKW|W^1QX ziOP?)cK;ZaSMyQoO5L< zEiTlhJHXm_J5D^Px&DnXrM2JrzUQX#48lFPEXK%kgc1k~%E`0dL(nklckS z->#AG`7@WyQg>=-%3MkJe}S(OJ{gMCg?Funp6_bJH~W$cMHr20P2}N*UAmv>vyO@6 z{iLnFvvEiBdjuB{inu74`Q%lRC28!5tA^BONMK|5u9BCGsdAHwG~dH_6EWYDdnm^< zqy6OUjXz3{3Rs<#OpV^1{IUU}0GAiK@d;NFbkyV zJ5`!$^kE;CO<%UPX|&p#HC!b=Mo8F({TG2U-cQ44QwDv~%IC8PVxHUlrcCbFEf=Jq z6S;5K(kAdywt8pm(`H!aCU-W2Rw1_WM0IgzS;R)hZ67BJvgyYsYO&-7TJ8 z9GhD#j23#xUd(Zp%aWQtFASr&mukk3i1s-R2aljF+mNO6`FzdVA8tiQY{E5G?M!fw zlp1t2-s$ei16L5}Eqk))xx%JpO{aA{)UASHn-W)&?MHs@c2m7K80qP<67EG-)$%%` zsP(XKgI(&*OqWn&+i6WmCf+LV(oOM9rr$-`v<&;X7S**C+v`+paBE`0ssMM zBR~fT00aO6&_*BuAOH{m2tXTwa{vK=06+lR2qXdo00IC3Xd`eQAOH{m2tXSF20#EH z01$vS0!)AaKmZ^BZ3L140ssMk0JITc0R#X700C$tkPHw22ml12jlczf!2b$?e*u(1 BebE2_ literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/13 b/crates/core/tests/fixtures/backup-data/0/9/13 new file mode 100644 index 0000000000000000000000000000000000000000..4a89720915ef60ff097a217ce54b36d609b73fc0 GIT binary patch literal 16384 zcmeI!|3A}t0KoCZnQRXE(mkf~sb-LVUeb5nJ}&y!+%QzTTG2~w4*c>iOG%NIkhdYTdfb|u|jR8dgfV%=1su5zW- z)R?S$N^5n<_%+U%|ITtt7`*DG?PkJ+9b~J23us=;UKm6u5U-L8~CSfKy^_K$c`4m~?K&0!wcjfw#Zf1@Kyge+I zDA#8yG>x0Ly!=*Gnk8~MjI@WH6IAmE(sE#M!^euAoOR2hsceCh4i9LMU>pF5@THd#4C-X)1 zuFu@__--6ujQqxlGPrg0YL3aH-tOY2{o=u{(7Rm4jz0>>RBhMVdd70bu^0F%(Xcea zP_J!;biS<)-w;495~FoEaO8p7ZH6BcU%Moe_YyZc&&D0P+Ah3^P{u{Vc2DGrZHXhp z9y$XUsSsoOrjnh8uJRlZ!{6#{C!oJ2x5s|Rhze9N*M2WKB&4>+GITn&3QD^PLR=wf z?IZ3sQL|XyDhORr5IeO7Z!ewZ1oc*Kz-*9KZ`5@4P){e8nYgqEQ)jm`yRS-e*e7Wd z_HRCyM!OR5IkCO|^s>2Z9|_xYZe6Yje5er8P|2)$4SgIxz|?MydD;MDOdLEhfh~5| zJV`Y@p7VCc4H0v&Xr-z=r6S@E0qe-BOW!V;S{#{KEQ%5xk-wNJUn;#&|7oGmjFrh9 zJt*Gg+7~>CvTZ_^%v}}0tG~Y!6}GOYv*Kup>sRR{qVTTwPdQvcpf;Sy;^#^XUt`cX zO7g5o*+Yvf&Iu$x_q?Uu5sdV9Uk>#ptE<^9k(3(P*TL?*@Tp=-Omjj#G8J!En0ZSw z%?P|CpORxgRhzYK#55k;-vS#hL|N2Kdat4Wj5a-TK{obfeoe@v_h$&fP4&AuL}zpD zgIV60Yq)YPbg-=DBpYGBPKaju(cSg;<{QTnDX6*hkyR4CImy5MwUQIQ$}=+SG}Ma9 zOU){4Obpw^cb_90jW^F;XtapNA=ECm`@*lIH`i@r1yhWLpv#vVoLH`;6~&OAtyk|z zS<8Tt*#zPMLVJ{GkFM2ZE3T9@4s>mH&N^SKe3~JPEPv5o2Xn~wG8%jDA162b!OHiU zfgUAmyoHb6h-XFU)6f6`fWUu^01Y4j5CA6t?Gs1`2mk~C0?`+ z$OZ@i1ONiiMj!_u01yBOKpTNvfB--MAOLLy@&Ez=0e}Fs5y%G!00aO6&_>BRA%4EC z33VDk_7sgmU7%FS5?wv}7Z*BwL4;#_tQw2@2iK#5nScR zHL<#|77E{;S5-M*(W9Ds4f@PaPJ%9Sed0KZPADnW&*xLEcZfYWqwyq z`|=;@_y__0x`u?kSi4zF1$}bJQ(UBD-{nz9J*LqHpUprCRth0*)?E}o3|i3(!C%9j z_B`;vmDxpm4CnZJ!ITzK7%I5wNn^n=^&y(N^oMdvB&xz>j3KlwatVw27T@LfU4pkQ zn|S1cg{r?V_I5uJ5!~03M~`v^ zgOC{g7k4$E!jY#sc*a|fdeebe^Nfp0S*S*oe_^sM{;f&AK(`aZ+;Gp$63?rqw0RL~ zVP88L)_5!x5`0?&8xUa_)r`1&=5m7V6V?(-`@CAF4RxyU6*U}{Ya0KLf z^z@NSOlz=p*9xc7APXP>5C8~38-Z+q06+jB0Br`+ zAOZvc0ssMMBajOa00;mCpp8HtKmZ^B5P&uU`2Ycc06+lR2owMW00IC3Xd_Sv5C8}O z1fY#T5kLSS01$vS0>uCUfB--M+6a^Y1ONg60cayo3J?GY00f|o00|)Q9|ZmZYfFS2 literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/15 b/crates/core/tests/fixtures/backup-data/0/9/15 new file mode 100644 index 0000000000000000000000000000000000000000..7aa90d69b7ce2a2e29d162f3f4b70211a00d5f2b GIT binary patch literal 16384 zcmeI!jX%?Q0KoC#Og4wG?lqN%lN~P=7t1;)tS(F_<{|4Pc{U_Z#XOYfhgKoP+RbKp zI&63B@~}BKIt&@=qRZ2XB~z;rdAjcPy8q%{zwhUdc)vd0420=6A%yBeu~j>gqZLLZ zqnDB=Hhn0q(XN68DKlV`t%>T^Pz=tFODk)R^54bxT_I^sx4w>V)(gQRL#4B`YrX_9D)soThq+$?Dx>DldmZB}ZCA=F|t*aIwZi1LtSzs^qlkwkFI@1U*nK3A2a6(xv(a_NDzzzs~a3 z=TwOd-V86#a>Uspi-A~S!k{)%mMZ!1Q;GFgW3T#KBHa!~7p=(1=svzm99KoU-marX zQn{eGIi|IMwQ72=uiy`-y)-}I`_XXYVlqMYvD*9}-BOc9`IB=eg@j0?p|ZACB(>{M z6dM)mFINvIcY0X4B&`mex%2Z-Th@}UidwLaAsr#^bYBiXl`r64LrBAeU`8`pd}HFoxSjHd znTTtq^R|+ah@sh!@Zs-N_YpAPlLTQuqzAi8s9S%OoZ=?5hovib?ctR65xCeqpRG^W zBI3qMc{|5%Swieq94%VC$n+Sf+<_fJ8oZTLDnn}m*`zuBNn<434U?V(Q_Vd*m`J!dS6Z8x68 z>737exBoVeI$F3+E03)RyhpGwr`IR%6V9znEUpv=^UjE0ES9g9#y5Ok9zxMmS(7LE z2XRAQqiEw6WXV!K2VVW)Uak*~*?^40o8+b570#!- zUl-4bEk0MHI(9;v&mC`rjpw2DYG)m{(0_&KoQWTt`Z}l9ch>O>1m}+Y{SuR literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/16 b/crates/core/tests/fixtures/backup-data/0/9/16 new file mode 100644 index 0000000000000000000000000000000000000000..3100f73717da47148cbb0f5240bb604ade747bfd GIT binary patch literal 16384 zcmeI!`8(Tp0KoBJsKii5_e5LAknvEgq;%#=J4e(VN2QOdTTpei?$&)YRTRbYq>j~5 zIa*Rzn1#+=L9JL_Q{sqV_M)3jW5 zGaFqjh;kWdb|u3#4zYejn>b_f3+d7UI0AAdc4FTxt})cMeUV%4wO=JA*C{FJn--B+ zL=Evg#`N6AOU*PcM^Y91&~Uzi+C{I2sN+Mm0NQ-gn$!LJ^?D>jw;j%?n3{RtL{amw zl-w-*GF)g9r-7>3P3Al(pbmE(cP{H^m%fW1@F|`es)cDMn@df9whd%U{-R_(E+Ixp zoN1<@j)F+u;xVXGB>%$tz0@vPDJp7IkL+vu^wmei=fSYF&`pKJFu~tgN2JGB2O}QEbY~T`X^}{bRI7Q9=!&%M?G0XGBE#S+LIYN#(ofs-<3_p4 zFAO?GIg27Z(HXjWly>`RbN40$Pdd6)oP7|jAdBn{;@*)7WsSqN6P0Fpj$yghIeIqX zW!V@bg+3(H)T+I-UxvYu$0X(^`wEx5MW!QNraSh|4vnCHF!W4Z`pj za7UfD01t~qJG4;2mF-e zYtJDb{9bT{9@P?%B;0X|R@j53qchzO_Rx8_-Sy%Yn#URk*C{xXw{@f3sju`1rixJd z#E;{T_IBzLL$`dpvMU&q63}NGSG1CB#Uh)n9I`p~Z5(gF5ozKxJ|OxZa5h(R35*(oayFY$hY)zu-@#-3r# zuTLzk=lC)#*i%czTZNHzCu@Upq=bq|6XtotL6;GvS_7hBC5t9f`STNB&qFcc9UVpV z5KlM+i7|YBUHbtXd8CJDzUOLEb|t8jZe}InS}}q7DfamHW{-tBTo9JV+aA_Gyh00IC3fB>`+cmWUq2ml12jX*s>03ZMm zfHndYfB--MAOLLyr~mj}w zBpX>BiKao_71WB=H6@OyXsFxldG-(N*FMkp^Zp}V&$|gxu#!a)sr>ngujiqd@Q#im zdWa_+g2Wg;zpniNjy%%C)8BD58+IicC*90S!nI-o^Hc2c@5~+xb+{lbjki6l@%&11 ziw~h1_PvX7mDhYe!M{1U4iSM-&rEpCT1c|L$DU{Fo>a=U9r-spTxx-hWg-=-=PVD9 zfBDH;L=H@Un_lfcXZaPJlFQ#*fis(HUMyGL%tjXrqFe@AT*+{aL#!XsCeB#=Lb`MS zj(}W=o!EDaYYw$#EON`e_N%1in396NX%UGiAGCfHI%7=5+sly&lQXZHF@|re@wZQPeUlB{vJd3>TWjX`pI$lQ|Cx8izZNnaldw zrElX0e2S-rYGK;R=2Fw2Yy;VnzbILcONbE?XIdIiM?oZS@fg%8a)mt6-Mc68Z_>RA zS4GORex=o+wK)nqtzWkj4cNJ5nsPM=*z|((tf0z(-hS-Oa`mQLPgUwYVhM4-J620xd-?S< zk(dvH8K-Bc9rXfm^2uCt`wy?I<)d+$!AoHge`F}Hh7b4*`xsu_EEe}MlGBl>(jt*) zsaEqI(G_Xi+Z(*XM4G`>ga)ierJu6r$BlB8Ul??Xau!8+qBC^$8W{G|=I$>LJn85* zarQy9f-JHthgYMW(B-C%@?ueWcUlX$9x(pBeZlA;X%wr0sZzDNGq{tlwKw ztZm2bPFpRe-VUEbM+ujUATHOOmfQ1t~qJG3P0)9&JwdW8IUKd=UMzsbc33r^L6!u`L=uEeR zJ#-#!cfGik;<3iTF$G8Rwr-R=^_3pMR1r!a`EmTwUZyTFWJ^o4R{dP^U>WPGRp>G7 zzpPp&JA*MP0e!Y{MJvfxEV9|kA)900&Y{L2!$_;UaWj}~itcmliZocvE zn+RFQl#R2GXvC46owDNa67MHiT^&+w>>1Yl`oz+DjxWuEJ+)N4RTx=!vNkA3N~oAL zp`SM#bQwXaH30+w0sw(83xQUE05}0~0?`+cm)su2ml12jQ|TE z01yBOKpTNhfB--MAOLLyx&Q(I0e}Fs5$Fa800aO6&_>`jKmZ^B5P&uUJ^zEiznJTQ Ag8%>k literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/18 b/crates/core/tests/fixtures/backup-data/0/9/18 new file mode 100644 index 0000000000000000000000000000000000000000..9409bc40c8f53d4ef73de31db3a853a602d24f23 GIT binary patch literal 16384 zcmeI!jX%?Q0KoC#M%x_n(7mSeaAn7f;$qP`VHLB=<2+=&B+m_LqF7mZh-f_!t9E;> z%`Ojz?T%e&oSQoKpbaUy@^F>4Osz)b>AKhJ{)~R#&mZxAea3MLx{am#TF7bTl+x{UtySl0N=xX@cGz$k+NN$Ya2fq~vSq+Y+4FBN)Wu8&eud;;(Y;qA zd)n&nzUCb%$1?OWk+SwEHqvQ@kWAlC^)cRd!90~nMyvBjm!hd{nFqUGX*lsqJTt2v zQ~jip?1Gw>jJP#i-*J-Jc-!lfEjGzmq|Vb}NBkws+KNLee~LB}e(qe8JIgD2K{bSM z@Ry9%v@6W4CXl<324h4gO#Nb^>U>p;qIa$5wMY4_M`vV-jHd$)uM)}kFgSr^Dyh!Tx)tvLSMl@tkc{mTmEgS-J5}#Nxrf~>L#Ixb7U4M z?OD}_U#dL68G6~@njXA4^V+PIjP4T|Webcn3mul`B%?$6OGD|na^A| z#eB41Je*I^eynx<*SgwqTK6z?x0sNQvWHukr_;N)X7H>iaXOPU^1X16{dsfpfGfYs zvr`@%_s!96J;giY0c&OJ9eBXK^qnxTrPup@;EK%)q-hEciQR#q32$d6RduV zl>aGNlM`kALLQzIVT6jqmb$q&cZEFnkGYG|n&);JE0=R^EYbImX--&Vibs&!3+yJe zVOdv#D%|%|nB_Qc8wpzEi|=aaE`DZv$EJ(aENt`|@hNHc<^(w_FGtiE+9xj+S=^WO zRkrRF4fe*~;Hox0E+yp{c-1%3=Ffya#W97$(gagP=R)*}&IVjlFsVX>fpZK|yXx1Q ze#&^|nMK-0T|6}fPa!gVhuA>C z{7C9b-A79bQPG$Gs@fyS=}4u)yVvon`v?MTS@iNJ>^0)zETe-TJEJ1@=nr0-JIo1} z+**ZgMcKX8QFTN8J#O@jITz;!$4!NDrg$$ta}D-?`2MlpbX-xY`+ z7y<|Y1ONiiMqn5q01yBOKpTNa00DpiKmghZi~s}x0ssMMBk&j?01yBOd|3$m2XQQf AHvj+t literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/19 b/crates/core/tests/fixtures/backup-data/0/9/19 new file mode 100644 index 0000000000000000000000000000000000000000..f179b64e8965b039bc773110931d5592ab77dd9c GIT binary patch literal 16384 zcmeIy`8(Tp007`%sKii5_e5LAknvEgq;%#=J0j|iqtZv!EvUL$XIl5sR8bVmlR8$% zkZfdigjwj^71SJc))7ZkG}LX~^Xxy^Py6BfdH;x)gYOU=&e^$D>eyR+0#ijOec;FP zM|wJR$-z5Xn$_wT5(i3H*Rdg|uzz94Cp&{MN&dYyu?1_1SQgc6?U>E6Yvs_Rk)f3J z{n%N|5Lu|%?`1tLKrWGBKn`B2AH+w47?u@WB-gUPk@XM)9-o#4S zx6Z~Do(s7|zs8^%L^wu0J^m?ck!1IPy};J}TrSsg;#Y5fr3p5gj#Q|ew>(0=^Od!T z=%4vIwbE_g@(VaEo4>sV?`W)gwOVmI6J02Xa_(<(p~5wealT~hSYz=^snY&Ap*lnr&Q-s8{es!}$hkmpvb&PLI|6 zX$zzc$A=GV^(cm}dz=w5HS^wyf~FxUxjFb%xX>hC168%3$a$1kKh$~Jv8tb0{5G!N zyKri-8m66SE;aMfCV(yZlake#gcvblwy6$v5=ik9k4BxLmdTUdyt)(KQy!GLDAHc^ zDXkA~%+uH@eY(A2tjK;D1TUWR@#j2)uSS-78iH&uhU9GWh{$fHXgFPzyVoo$O%S~) zcsL@xjMlH)Ruu3MDVf%};Py#*|5gl+_o-axZ~1)n75*E06BaHAp)4#T9Yk(d4X%(2 z^WaMa5L+Gft)q7aEV6$Y2={w^*EEu+dcPu0AJ#w>xbeE|@i&a<`c9)R%VUK_xOrN> zue=$SwN@n7Z|jq(*9yR?pXVD}zx%^VJ_@fHv=SQrTblBESikp>x8ddOLUC^+IUR`#EeeH^j9qY# zDofej-QwjZFbu9EG+NBRA?jAF=`CQj8p22 zO06{6Pn-%wlzk7AWV(90a~rNOhdbS$mvPSjl}3mZGOVg0?Z(+pVM-XIeO{7cEqku_ zTB11 zZx%Mw+&4J?F@Xt?07w8N0PO@OK>{EFkN~t3m;woa1V94NPT(C#03-ksfOZ1YAOVm7 zNC4Ui%zy+y0w4isCol^V011Eupq;=RNB|@N5`cCB^B@6`07wAZ2`qpFKms5EXeaO< yBmfcs2|zo6MUVhU03-nI1eQPoAOVm7v=dkc34jDZ0?WFNYZb literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/2 b/crates/core/tests/fixtures/backup-data/0/9/2 new file mode 100644 index 0000000000000000000000000000000000000000..20ae9eec678e51288232ff7ccf53b83aeb00712d GIT binary patch literal 16384 zcmeI!jX%?Q0KoC#HrX8V(7mSeaMSS99KA~DJw>({Z+mm5#V#I?)OopVkGY0fU3Q`JrWi9} z7cVw@u)HG{R0Ae1fs*0Mc7=t_1ac?RXoTd3Y0&4YE|s?^dR9emJg?q)dR|7U8trR@ zZOaX`82h+CQEC2@L&%Vs2`y*5or_sH$%-}2#H?f2+Ap~KpeY<$#kalrC5 z-jn;m-XI!L{la}y&N-s z%?3#J+GN{<@BRp}%^+curc>#^6*|66lTj2D@9iI|OesD#?q-}VES4ZYcq%HRwqSn# zy|yAp;I$j&25WGV@;=9F(vR4_l!v7sHbzC`3vnLYuF$c-$onX*Wk#o|aw)^k8vXF3 z=CoCccnG;I$6-QyD77S{*kf;6^;Lq8odhlP5AJI0&VONl&#sHi6*PGd`4(_}YC^Ee z>xU~5j`53mRu3h;Wvx4e{XJ2)YE>Jb6_V49yc?Pr^XCta5~>A*(pYno&V`86osER% z1LR^M23~_e?QB?Y{yF)zS1NfcX+?A*ao3eD{#m3Zkpgp?$QQbhh6nxO3apfmwSISp zoq?$iPzVw4O*RlQ-;=wjKQQ7#Rm`P7%Xjh9JE#nJ_c~rhFOiQgidg!LFD2<`t2%g5 zGb)nEu)lQfSWTGZ&I-&K1YBpK;RBIHpe z`?D+6xxr#~fO=V}3VopBXQESCZ}r*Z1O?NmBjIT?j4|PNcmh}EtA9ebK9u)<<8=YE zzj&d#D(!acO(M>n)tI$GJT*H!JzE?n*rObsu9~Yj)3i1tw_#nV9q|)x_LhhDqg`52 zM;0x~d_&zN>8BOrMcXZn&BznbzEPSrPa`k2{BM||&)3#(LmgR+# zp9kD9>JCQ*`OZg$kaczJb_%T?_HDQ?CuXXQme7{egrXB%i!R&{zhs1-Q%)&yYjrlA zD+w(JceKL>i_muUlR-=9zv8X;oRN)veYrkzGUy8=uSEAjjTE&t+<(J4eidJ3hzXaq zA7LZimWlDqz1hB|00DpiBoL4S1ONiy1fYEaGJpU;03ZNu1mpk#fB--M+6eRk1ONg6 z0ca!e1Rwwq00=-E0R=z+AOH}6HUdh306+jB0Br>N0RjL4fB>`+7yt+W1ONiiMqm&i z01yBOKpTOl00DpiKmghZ3;_fH0ssMMBk&9$01yBOKpTPQ00DpiKmghZ4F7)+_!j^R Bg^d6J literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/20 b/crates/core/tests/fixtures/backup-data/0/9/20 new file mode 100644 index 0000000000000000000000000000000000000000..e7a97c9e155bedd326ceb0d8d9c813d9f910e9ac GIT binary patch literal 16384 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 F{0q4jdawWh literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/23 b/crates/core/tests/fixtures/backup-data/0/9/23 new file mode 100644 index 0000000000000000000000000000000000000000..ae522109bca0650cbc8c06401fd9dd7d1bb57068 GIT binary patch literal 16384 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 Ap#T5? literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/25 b/crates/core/tests/fixtures/backup-data/0/9/25 new file mode 100644 index 0000000000000000000000000000000000000000..dd9f68a067f274faa06f3b262218e4be8d700ba7 GIT binary patch literal 16384 zcmeI!`8(Tp0KoBJsKii5_e5LAknvEggs8eg9Z`22l|HI&LDki|TldjaQ54IQI#$P! zY-DwWS?Jsq)QZ(LC61_QsN1^d*-!fu`aIvy`;T}%Z{ZvKhvSmVXx+wbc|I?p@^@Mn zJU%Jz-;Bd?KUHb{BU_}p!h7v#%*2Ht6a}RuLr7i9q17@GUOcfNVu!P?ZS2mlW!}%j zkpZvnm_&1x?^P%0!kQ_3*I!jW`i>sk)MMCdbu708H_I&Ymo>F!u9b=m*}G?%aMXyn zjKYfS;Htp>LENnh)#lsJlo~wai1EKT)repJ?d#`4vG4ga&(6`h8u;Lp&kHRbSAMsV zjlrvjtb|AYnyI)RG2}byi@CgABI;`>qa{|YK_=7FtQS3FD${p&x41<~bbSki8mv}n zkb2U~tfLq?X=HCO=dM&3a}utZq%hBQ z3eU62)v=8z&%qkX4ImjN)}3`-Y47A;$aNAL>GhaNqx43@3LACSW0ztfMgPN8sosIU zf@VF&SdZtkO7{6bGYQcGnA-Z}-2}%OY&m^m&_`UPeb4=FdmXmHo{-Bx304Rp3~JAc zAA~OJhZ8R0Pr7dhnP+#>?!h@hzA&ZvG=>U(YQjWtRDF=9F8!g55`!u?9c2h@iJZfs zt`a%}uO<6Aut`UM6q?hb+X9mXyUtLH`fxOKmiy5GIv>BkS<*)J++gFo`N#5iZdN!C zl%2qo5egr8@x1Z=Zf#QNj)r=j>V=fya;AlK*eUG4Z1kpkLa?cU19tJnYbn-Dis{-h zi|x?Cro|$|$?N;^bJ$UmKwH3@23YdEvCF)6fzkf!NNK0kt@DrRq_Nz+@{)*BpQku& zEplDlIp*T#)XHYAAKj8Qvr@8C6jlFuV_1fqSUGLXxQH2c9Yd-#BMR5DsX|phJoWQB z77^Ujl1Gnl1w)Zo%!?bE58=oY9RlMmN4;@htZCZav@}8^HmD%gf$-M!i9nYt!pdmZ z(}uvSqO|%FYhd5I8dZBQ77znkLh2EbSkF-4v}M%L?6(;;9t&1q!Krz??KOCJOYO_m>RUPJ5`L8HP^%jSu6B&`C)vgu ziC)T(48#+WYjIPD?(r>QcAd+d3h%>e37Kwje!uj{q~fMfuTyN_9fHJM%W71UoIe`Q z(^t9d{Rnk>tP)6FOx|#Q@Ss75jB(#%kBg|74NMicj!MYP!wuj9(|9#h?S2aTVPVr~ z&uRCnZcf>ogdyLOnUOk}W{R1_>_@vGmiUhfHj`o^#H6{_M$}0#*+(=Mb%s(YOY-pP zOZuC9ztT;f`g~AfePm;S%1R&99*AH@4@n`oiR_O*73zO8{=UCC#QtJf{w9}*>|+Q= z(u6sCZPJniVSoTY;C~3{0|Wp9-~^z30vLb*KmZ^BZ3GMe0ssMk0JIUf0uTTQ00f|o zfFVEtAOH}6HUd`x0ssMk0JIS>0tf&E00PiPz!)F^5C8~38vzr506+jB0Br`+Farnx1ONiiMgR*C00;mCppAezKmZ^B5P&uU761W&06+lR2wVdQeEA6c3zSHD AE&u=k literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/26 b/crates/core/tests/fixtures/backup-data/0/9/26 new file mode 100644 index 0000000000000000000000000000000000000000..2d9d6f98585c99010147d27dfede4e67a8fe2bf9 GIT binary patch literal 16384 zcmeI!`8(Tp0KoBJsKii5_e5LAknvEgq;%#=J0x!6sPs{FOQ^b9ck4cyDvDxxQpf5T zl8vm6Fbka{R8T8c*OWM-qM>fH=h@$|{q+63|A^P~PMU3PL>-4vd?jO1XQ-8mWKZ9| zq`xTlE8Uf8&j(f3hS%q5ob*Bcfe2PKTMofb0R*rq`G%A4#)pgrT4dDk>;}CwUZeOM?$EI z%E^+*UFxCL3K8A{sbFG9symT7+9>76m9;*sxYhCD;xgS>`+~A}*t_B0HoisDBW5t3tE+_A|8xuQ+1-&(1Z{ zcE5i9TrBpzaOT-rdRK!GoO(Ln((%o2Sj8B;HfcFL@|R52wFtJ~h@bK0trAH;69qk~ zY8?uNk!G{t6;qkMv$M%BN@5sYM`*!n)dp$%0la8;#l<0)XjgHBH#$?_ps~|&#?td8 zf-f7>F3CBJQIbdYhVbsng|Q~!x=AW?eCO~yY_5TAM0pOzL}>uYG`H!j>q>j4{6eXd z(8#Dao-j>sG^xO9a~``Ei>U@2q{{UU^c6H;VUG5AJ*(uN|09zSEn-|-pS+XcG>s`| zj1T%sOSJEL+-@OZemN+riheJL&h}ykI|=+FTk_ z13x)#E;^z;NY|GCP)3bGm0OH3#Wp3*;ZWZaI)lDT_IKox4}UMbMvra_N*3)pLo4dT z(a~8Rhx_P!{N6@M8_jE-i|-a5&ELLR;WAKm3{yv_d=SJ7#`?SU$)Vdi+I5;2QijS| z*KNX1VE=}-n(858QiBHU_TpzTBV>`bz&8!BcMsTZ<(Ah{Ji*o~ zyt}3LAWFrXNF>~hB> zG%N=ui(5xz6z1Sp;UZIbEmZAZ3in}Q(@4)r_ljXo*_#BmU&-`v9ZWaHQfB6(eK1G* z2NmpulmsyeAOH~f9}%zy2ml1Y2|)V`+Z~+Ja1ONiiM!*#y01yBOKpO!(KmZ^B5P&uUZUBM*9)W)V1h#zv literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/27 b/crates/core/tests/fixtures/backup-data/0/9/27 new file mode 100644 index 0000000000000000000000000000000000000000..338a4ed468fb42371c6eea8d910573951850971b GIT binary patch literal 16384 zcmeI!jX%?Q0KoCZA)7;3_nOMX$&S}5E|zu9)9PaDL1|1|C(Jwy$y0gA%5!NIV%2W1 zwQ(7T?T%e&oSQm~GRlR^(^ckSGL6X7x!3Fdi+laPpFiUL`k*(~Y$HVD%o)EcSE`-3 zIP#LRPv6$7bD*@L#~3*ZKM2jv3WqKJ8 ze>fhgF#6Go&~K>E$QWs;L9a(~Lk&{UTX_O=R$yp*#^2maf&fd=1G&}ovzalGB1i7n z881ufGDWB_D?j{H?D9q5+m5>E6T4yyXVnZ;yHqbhtfyLPG&7;&o z5~Ry{?XWZOqxJIHRHFK0nZrNkC3X{<=O^7|#At-Ij;TpBt7UggIWj&-V;ISJ?B{$m zWug1Xt)IIS!k?b^NK)^Yjer z339%N%AP^YE#_Z~DvRil6VLJO>O$_?R8vwJX}_GRFgo_z=MQvK-fHD-8xgluZ-MhR z$Lb${^E<&jnS_a+h)ei2&w4t(i`GNK?Vo2G&|HxYhUI&>TuHXiI3-z-v$!~?F3FI% z97fo~gf?=~C%P&r!2C_OU(#tkL=ZO5(W$1{ci1cN5khT}++?6wO|~#YJ&96XFpZV< z!}n!ajjB(@-69k?9gXK)$Gci|qNE-^&6O?LuPq;1G*fFNRk(h)oEld?0i(Eix>VPi zzLI77q_e%K?trwnjdE9@-0^1~HAx#MtYR*vpB%z-BroKlM*2-l_? zsynB@orwOH+8ps6Gt5`XTK%K=kT|I^f~nK8RaDYW6l3$rtDmriq~%$5qlhx2B(-Yw z7A~CS`*q%5hwVmKz1O5^`Z`)2SuqQHFqL*YGrKvm!#=Sau>T?i47Nq%vm!c=r#P?_;Gn1r^7gUQQdq_pr1Z!(Udzn4|8eM;(jYmY*k>oywZqaZ|$TEm-2P z%34<0XKgx5z`ArkO*`Im3Y-Y|VHDaI9!n`OwR_3+x0 z2O3~6@=+EQW8SN%zvyO161#@K%&iC<^ZpDjx}}+)g16QSA5E5@yN+dRq5ZoW0(fxy zH6opLG|kOmZ>~uMiGi9*9atf!)yE!hey8FGuap}jTaC2BauPC1Yh!{o@a^ZR#v}EU ziM1AVEL`JayFd5_8Xy1=_#Yua1_%HIzzIP61Ofp900Dpiv=KN15C8}O1fY!o1t0(r z00=-E0V+TMAOH}6HUeh>0ssMk0JIVK9v}b^00=-EfgpeYKmZ^BZ3NB%1ONg60cax- z3=jYa00f|oKnOqpAOH}6HUgml0e}EN0NM!900IC3fB>`+2m=TJ1ONiiMt}|w5I*`B DiHCwx literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/28 b/crates/core/tests/fixtures/backup-data/0/9/28 new file mode 100644 index 0000000000000000000000000000000000000000..caf4ef55c27a9bf337f494f8cc76b0f19a2cdade GIT binary patch literal 16384 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 literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/31 b/crates/core/tests/fixtures/backup-data/0/9/31 new file mode 100644 index 0000000000000000000000000000000000000000..5439e2b4f9dc1bd0c933bd09456f116028b69d8b GIT binary patch literal 16384 zcmeI!jX%?Q0KoCZA)7-Uy4O@5E_S>WE*72hv^oz{d78+2sm$Y$XbQ3N{Lm`Iuy(Uq zc{sD(vCG3aH#$#~QC+w^U1edi8hLi^^}0Xfe&5d@@qT^0+9bRrWE_2dEoBljL{V%B ze^C!3PdWNcSrs{~JxkE>$yhpYmrofkSfx?p%R?Sutt{!a$@_&fi=(rP1)+Rb@%Sut zx#U{i?t(~{p2`|?6dbY>`41ya8WF{Fd0geHhYv!7w^Wr@Ee+6vGNl+K#_sWXi`#JI zwl!YxN@~toQ*Rgxa4wHOk`!5#;e~(Yd|$D{AK~V(66ArGS23Ci#A?{L{toO*GeyMk zrsz6E0>(5q^}g^8+3SXQMr^fPrQ5n4-r#+_8TLFEsb4+qwu$^JOvm-wz{J}qp1og|AFRn47k}AHjLt#;-GdkTPp%bM9w9TZUm$>#hz(@ zCuLsRU~B4jYAA$eC8U)$#02kPdamF#C!5}1YtRov!{xRn$1dGL?QEGuaA(L1zPE1G zThr|VRwW~N8IaK$m48LDP2U2?m)VW?}T^Sw=e#fzH*1nT%;EzBa_ zMRVfQnMkq5BSVju>Z-)F$z~2}JBl8nmW0~NVChi;LweHwrr%(lGvHSC8_o|dOmoFq z{Z@VPLehXXLY6A|^i#3zS0itG8>7!2iY;7}5s^Itl?0xObhSlC3$JosVPiz=9omNT z(O^%oGVQhH!NAW(YZsESvd>kP|LB#N&dQ&8I|{MU2qPtJt!PSzaSU5GK3J|ENo@1A z@l0A4x!(I(lo0;(iW5m@e4TyM2G+>fbNVUk&Nuv|hA#VVw=MlQaF?8tFg<5?;as`u zz}bLYC#e|`n_bMzi>iv~?Z;kZnl@f8J6s=>OicO3r&{CmZ(mj_C%sk3**D4SsNVx; z>`pheefPVEULwvsdNwZM*Bqny_yNKY!S2{csv5yw*HWE*gihyYy3Yh9va(iImSiPq zeA`n9Gg!^xe(rjhlypw-jmVeer-BGZ=U7>D+Px-R0-qpcT8XV{;>|>T9b|Wu^s08O z@FmJMUB6Og zqp*z(?e4ywqQ>Kb;jW-EmgK;nIe3zyT}>T%<)-&IhQ@#1AEKe!x*Bk`wH8x<7GEGh zDKV81Cu;U-tjD~wjl&e$OI>A~{QxdEH&=tA7uBDIAZv>?HC zDhwAcUts$7RcynI5r!Y+De{rtPAf{x@)7e|(}U?En(&l+><;X|Jg8$`(U^>gzB4JM zbLs9vhV$H(SmFf`00;mCAcH^|KmeQoI00y%Ksi7FAOH}6HUbp@0e}EN0NM!900IC3 zfB>`+cnA;x2ml12jQ|}W01yBOKpTM{0RjL4fB>`+U;qRF0ssMMBTxwt00;mCpp5_% yAOH{m2tXSF7C-c5T{eZ^+ literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/32 b/crates/core/tests/fixtures/backup-data/0/9/32 new file mode 100644 index 0000000000000000000000000000000000000000..d864a4598affc4254e047bbdf2db13bb26b4e6c1 GIT binary patch literal 16384 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 literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/35 b/crates/core/tests/fixtures/backup-data/0/9/35 new file mode 100644 index 0000000000000000000000000000000000000000..0e59da1062ae73811e92bd9355f147b980ed067a GIT binary patch literal 16384 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 literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/38 b/crates/core/tests/fixtures/backup-data/0/9/38 new file mode 100644 index 0000000000000000000000000000000000000000..80d2d49837605d29e6dd1ef80ac01440917a55e1 GIT binary patch literal 16384 zcmeI!`CHO=0Kjq5fdS@id$2-X%Jk8crKHW7O3edP%kW5gth`0dyvidj?;|QTC1pJ1 zu{@^2rYsM14s9M_pytw69;-wX3qzB<)}CiS?+@sCzMuCW@p|4om3WSdbiG4Ii=uK? zX=6<5HNm=hMSoWyg7MsPzyAkA#kmxc>_d&^KYC>*^YX{1j`2xRXhXQRRurwrD7scR zE>Nx(LGALkc28avI^X_T7$5fNl0%}*=t^yxHLR7j>*S;An_qL2Tl(z!UAC|y(F?()O>9GuX%=V;sn8>VB5nhbk$%xT}!oEb0(9U?K&5b zRGqW7_D)uo&b2v#Higw69A4&u67uj?&D~xvoctf6Wm-v{s^ZNg ztPZ9>QhHfChChL_NH>^~osPZjR%GQK$0#J)VTUk02iNX~p6uuP53t>oW^SYHgndr4 zU6q@e_|}*xbG<4;ooP3cu8oRf0Q2QBzA;nzKcQU@x8)y=rdOV6s0`$l#xFjoE?y7YRPq z7e&kpAM!{oU(9snvm6(<#1gMA2`3p7%Y36qohFKC${k@(nqV0-$Ii^)OY9Yo<8@AF zz1w$-OB*d(XVBv+g6@*=mdu8fz5Kc5$@%4?5U#WM**txJvs}@MsLt_Q6?;8z{`S6@~XyYSye!Ynk$MtcWvD zjws3UqC9oHquk?zcClXzaHGg;Sna{oI@mWp_O%!0N~mFNQH|($qDlU>JN%a!URT9) zV*IBX-OlZ>mQzRCVdME2Y~8HOCg!hD9p?nWi?4F){AXRhK(TMjR~AvdZS@ZqYR?xE z=t?*rLAx&tWx7QQrMaits~*bL3MW%Biz$;EeyMFS9^J2{RTnmDHFSH`l|pjj)5}|; z19yl6mna(3Z3_u4*iZsWZex7-!cE-HmT@?HE@R32`t>F&rmf$)WDIHSG&EV>F4EAQ zK^;XYPmxV=^@>c%jnWoT-%js>bz$X`G(j-^*+>J-BGXCZ#e0tkvHFh&ZWC%qYWj40 zGj2PQ8Kjzw+s&%hqxlC7r2oylTJ5XPzCUd6W@KrWEzTLn55@5l1=?uYHOc#*N^QOz zdo|b^<#`~ccv(ip4DbK~0D=EU009sH2!IoS_6eu}1ONg60cazz8z2A>00=-E0VF^G zAOH}6HUcPs06+jB0Br=&00DpiKmghZr~(840ssMMBd`Y`01yBOKpO!yfB--MAOLLy z)Byqj0e}Fs5zqh#00aO6&_+NLAOH{m2tXSFEr0+(03ZNu1hfGH00Dpiv=Pt&2z;gp F{0kjlcs&3B literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/39 b/crates/core/tests/fixtures/backup-data/0/9/39 new file mode 100644 index 0000000000000000000000000000000000000000..8142d4e9d54bc0abe4aa87c71f11ec90eba526ce GIT binary patch literal 16384 zcmeI!|3A}t0KoC#MmC2q-KK`HrhwErw7_vD9p2K+!s(zB**^n&8NPZ>kom$$4qNJ@}*f^2rpE z@?(YlKbT_c8P$^`ZW2-~(j0DR5X)}2jH^T?hN^U<>8$~d2bl}~UIjn*Gol`zaZgfO zp07-Ggf;Ng4m~Wt_O*yv-|5ojy^ftmc;*&IVmy2#@;lmnhlBFm6*hFz<)X4HF%`5& zy`)oR)(xj`ThxW5&{@A6t(mguPm_(U-~R54NhaII&Ll8? z%{8A*?4u4)o%g&i)uFne>~$-5ak-*wpQ(`K@|?xRcgo^)k<$UB4XoOtSFjSPNIH(0 z?hi;hriBb8*q0!iK%#!OoD| zXIm5ILgZ-f%tbmZhMxEj7ft!<2k64qm2-+*iF-Zzb-vQvzi- zd86ZW^!_Vt!t)44G!$5UnJCMXDl&`*5k)2k!Siycpma~sm#AsCS;-$ zxUc z@HjNl`ThyJO9=Fa14aB?Vas3Etsf2YxRbbx8C{s=PkHWfL!&(q>Fv50;!9Cg@S3Rf zD%dxHu9aa^h4iS#*jglmXq}gKLo%J=e?dAW#eb?mwQNMyAKBXk8_q*xt0ukI(0@f5 zd7bMU+j+Svc+&d|grGq6UXJK!tbXvO^3+vAsX8vOujx1sVY5z(WFKU?>g>L3KqJ%9 z@|2O)AXa0%U)yU%S=ef&KB_}cJtBvZUQ!cI8%aQ@oUHbQUBhjz zThRnl8FK*_FV;D5or9KSL)uoJJtHMe1Nx{5#6E<^DA@*Ay__k#R8&9Ex!Li?@#@{D zseRPa7msUTcA1{~V;}qg0sw*k2LWS%06+ko0JKkF8$bXc01$vS0$%|H00IC3Xd{3I z2mk~C0?*06+jB0Br=!00IC3fB>`+Fb4<#1ONiiMqnpE03ZMmfHnda00DpiKmghZSONq- H69WGNp@(`L literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/4 b/crates/core/tests/fixtures/backup-data/0/9/4 new file mode 100644 index 0000000000000000000000000000000000000000..bef45cce02ce7acab49ddea61985f99907e7db69 GIT binary patch literal 16384 zcmeI!`8(Tp0KoBJsKii5_e5LAknvEgq;%#=J4e(VN2QOdTTpei?$&)YRTRbYq>j}w zBpX>BVHP@f1+`*zO^FbMIO3c=&;Ek_xaawP-hagFd3zp<3GeGDqKCP{AxMnj>)YB- z;K&m_JpBVlvw<(sIOS$m60Q{!n4e;g|6ul9sM7^uX}s%UjptR8TYL!Bu&-T=tGpKS z3I5H&b%+RzdS=3N#$uBFBjy5A_pDN`?Zm&);aUr9JQJxlw95x8{XAi^Jb;$ZZ^7D5alx1;!1{V9Ao{6HgU${SJI^ea0DbfcJk0It~u1U zV~JDlbyy`O*Ci?Fn--B+)EMGu{kdoCd0fpUiqv&^Xe4+O?veUHU$L(5HBMxE7|J zY%VpkZ5zmx{6WcjLPCs?INQ>IIte0qi^rhOkt^hh?%utLe~}(lxGGX!4JfS+ugz1K zX#=|b;f$z383Z?hwf$p(!53qn`kI36E{Eo=a|y^^x@ZJdl(XL|D~%VuEqFL4y@b|p z*isbm6e;_tbIE;AnSUo1%iXKg`CGnFeVO;p!GwVgMkou*NCy);RYR)e!aaEsfrNG^ zeVdq_A&cCfh9dmm-Zzcnsy?iW*M~Kc1#Z2qc={DBrm@?o$MRTV5pJGQ=qGPx#bB3+ z4cfV7nsPJ<*z|((tf0z(z5(pra`mQrFIDP2VhM3SJ622H`t|cyA~Bx?GtSRaJL?7D zl>y3uA1BIHesRbt%2^cQiO$f~Yv{0_F?WB1;7Uigi8GI)6=ab;L7WFN zp^OQ*cB0Z8*D);DI!DhYyeu1Iq|lF~n_6|$cBXz*e67%dZ=lr~P8g>(7?oRVGM_mY zi75LWrpWa4_vSZUqmOobysThd{38P&C1hArm$V!2FpVjrjSqNBinZ;#J!q@N)Z5{6 z=qTZG5ybVH^O6T4O9o;1E4Y)cdx1ByI;aofoIoF#%3La44L3P%DmE;{r-$lqerfgn(Mk9{q z?3WdXmw3Ox>gtecV=pik)+d+Ob9`wQ%<1Lgox;evv$Y{PQbNU)3H`F+kjp4itqD=U z&Z3A^e*ePP6CeN(00{gK5Lg8WfD-^G0PPc40|)>F00PiPfCCT!2ml12jleoU03ZMm zfHndf00DpiKmghZYyt!T0ssMMBftd+00aO6&_-YjAOH{m2tXTwZGZqk03ZNu1b6@e zfB--M+6e3b1ONg60cazz3lIPZ00f|oz#c#VAOH}6HUj$q0e}EN0NM!f|2qQz073?X AasU7T literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/40 b/crates/core/tests/fixtures/backup-data/0/9/40 new file mode 100644 index 0000000000000000000000000000000000000000..06438593962d157a7f27767cb3906c5eed716f5c GIT binary patch literal 16384 zcmeI!jX%?Q0KoCZjkY=Dp?gi`;mYFXVa1|zo>mv862@e`B*Qc$qDEPHh|+o>B)8Yv zxICOa+_4L7&W%o38P$c$(^b}(tVZPN-0OA!#l3#t&mZxAeFTcV=9G(R$BBm?*Z}vG}xRvl; zkM-1(>2aYVzX#WyDogJ*MQJW5KmJtW_SL|f$Bl`Hw%!HzU zRA*_xn%JCZcTMrY4E3wjD{; z=BZIy!vy-n5Z6G)oczFzpXF)sk4|}~Yj&KiKJN-^$U5#NXhD2+)*tAS!U z!_o}hc~X7aG+Fin>6C3frU_2D5m4k3m|A(2;9=Q~mU#P1>)P^OS>3mkQuyL}_ZOb| zd=G8_R&hPFOwT56Dc7{KyQ{cykEFjN@(xeA<&~WIFeS|PbBQSA{CuQsuQTN?PGZoThib&Z+IWJ zM}#$df0vVisr2cS=*=QF6EWXWq_ppuu|Z1K@*gGpMCmOwCcJH$UHlj*YSA=?1KirOuT0y`UoUQOrH1H%e!TtVGr%OomstZN(QjO&=8VZKUJ{74B zjD+IcAj(Uho4RdbC_m5n$N-AAiqlM`*T8m#c~(bH6w~9I66;ZE1iQiuH)XGxLFW_` z3fy{?dFyJt;K-h4*t0^kWzD$XGWxGLvjb;(N4~yX6EW`h1yXoJ`$2_lZ>oLpuKM^@ ze7O!LthYIwgS1~E#<2pkJPjN#o6tyfv?_COiJaAxd`S9M&5d5FHa2fJ(uvJa%Ptcn zMXeFKPEm|Uo8Fxf00aO6|4#%k00DpiI00y%z)pYwKmZ^BZ3OH90ssMk0JIUX2M7QJ z00PiP;2VGdKmZ^BZ3M6Y0e}EN0NMyR00aO600C$t;0O=^2ml12jerwC03ZMmfHnfo z00DpiKmghZ-~a*u0e}Fs5!eL~00;mCppC$8fB--MAOLLyTmS+90e}Fs5pabp0{;Rm CBz!{v literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/41 b/crates/core/tests/fixtures/backup-data/0/9/41 new file mode 100644 index 0000000000000000000000000000000000000000..3680b4155801ba005e14cb68a48a5f5594bec7d2 GIT binary patch literal 16384 zcmeI!2|L?&0KoBJsKii5_e5LAknvEggs8g098q^1l|HI&LDki|TldjaQ54IQI#$P! zY-DwWS?Jsq)QZ(LC61_QsM~DM-o>8(@B1P?&lgV3<880OyIX2stybU8L6`8OT!&iS zC~&o7oIlAn-bnOHhGZa~h+K=CI&_b33A5{5=2UneR!hiqi}U-XMSFSS^TUS?I%JId9(!Cw#cW`zxOG%QW*%+;7nsJY zp=$S2*pCXEMte@XS9NpB-X;wBmduRQ!8B9MBxXO^1+m0`P_UU46CozewKk$og2_Ij zv8Z#DN?DSJPhZks|tML#0%^~)e z!}2$|L}VXBIFcsJ*=v)QBnaQ+KOC1_M(Z|i%ky~&mA}`zbFEZl$lg86gri2pWfWFq2Ui9558`fDs5aku zuGHWeM~wg3sYd+9uV20piv7T!d47)8)xZa*oGr9;T>H&NHU_UAvJxKoOQzy_#E|c( zFXrlYiKwrkjFwon2ANDxvtIO!sZ8J9-QpG{(e*75YOq?RLF$1&C)!PRY1ld1MHu0Q z&eYav>~xql^LT~eO2)K{vW{Zpq>;VBoO@DX%t^RrlEOUKDLl_6SI0J@JO^tiH-KcA zSa;TSrM;JbDc4D8q}O96jnW$pD{RzRPh5(H6#WlVrFsYY3Yzs8V?CbFE7=$S$RtDy zU~21=cM}|Eu;uiLK_79E_C5D|?RD4&dqOS)C0HSZFsMB*eh|8>A5OS}Kk2>`WS-qg zyAS6C`NEXu(-WE*maIt)Q6*?v)qpk(E0fN&5|~%=LQ?!%|DjEbF0F6pzH*uj8OQPsg#6QA+A?Zr_Unuq zj|HnQ-~a)D06^eh25@=+0dNA~1fYEa`Tzld06+lR2w(sL00Dpiv=J}>2mk~C0?1qc8H00PiPzziS&5C8~38v!gp03ZMmfHnf=00DpiKmghZSp07g_y=ipevtqG literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/42 b/crates/core/tests/fixtures/backup-data/0/9/42 new file mode 100644 index 0000000000000000000000000000000000000000..36633f226166551ae23605c8b2f2991f8bb4bc03 GIT binary patch literal 16384 zcmeI!`8(Tp0KoBJsKii5_e5Jqk?~Nhq;%#=TSwf)QR$w@8;e!rFAl+ZHdVqPF@IYhd5G zn^yZS6c7VjLhBJx7|pE2C#=O}r~8}*j{fH=h4$mXCg;nou<eA@Xm6yjAqz z%!P~^uX*dQ;Iur!)+)TarS|1Y^{pIqi7?82u+@VK*E+%y$ae9jk{2^%gK$LTYTV?3 zXM9VzL+28&!uOzBMxk3;I3PVLskkZ3=LFMt2QM?*vJ%~-L_os@MjDrVAE8c;G=gXg z$?L8U9yAzGj6HX`V-gyc?8)NR5gCO!_!YRw6iy3OyO+X!SlBeubJD$Hm{ay9VbH&1 zdbkdzn_?+5^U)!gBmI+#?SzyBF=@875p^6w@so^2ouXDMlD+);lK!FGuk=u+Js(h6 z8(yEManc9$*^w;Lpd5mq$o=?pq0u*E@B5oW9nXj7Z}5r8KBjmSU7WYuCNGN@zae}u zCcA_-Y}`^7@)0Y4r+3cllj`2hI4u8DmEOOKMViZk*Un}vY$!riR8BUO+@&5?tq|!W zkP0StxEk8UZVy@I{W264`09>1iLZXII>8XuOck1$Nw4*h(jwe4vxuN* zVZ&N2l^AsN%rfU`5wRJC71<$GLHz^RTNRqkx1Xssc*hare|4#mw*UR>=VGz%g)>jj z(z_aj;MC9aEgj$gVXGK}(+*vZi25y4buDtxf5hMT(pHJ2zlnmLRJ9I;!br1O@Q$fW z-`UyZ7bP)_t|7EwwQ2*jeFBf|dF9l8A9_eezC%^E9TMF+SiYEz!Q~dAGd| z)8L5DWuinY#1L0%PfPEIEg41NFXE27ZwFt^?xf#?^Md_hYIA8!4cz3ox#)=Y09{-D zLm4#&Rc64N*3)pMJwvV($QI-hx_P!+}=h> z8_j#2i|ZC1&ELLR;mR&MhN&Y|J_zCkWBuLwZqepXv$4 zqz17a;)_>PY*`bz&8!B%8Ys5c*uPe zsnLumT+OD5RsHxhz~@LpbXQLqJ0y+|YdpM;;sCnQwX8jeAl}Q=S&3kvg%# z1*uN>w-!%C00IC3fWVhPzzQG$P5_($v`@eqAOH{m2tXSF8-M^n03ZNu1Z)8U00Dpi zv=P7p1ONg60cay&2M_=V00f|ofIUC}AOH}6HUbU+0e}EN0NMyR0t5g800C$t-~(K0ssMMBj5%Q00;mCpp5|Tiy`nI%W8jd literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/43 b/crates/core/tests/fixtures/backup-data/0/9/43 new file mode 100644 index 0000000000000000000000000000000000000000..15dff47cae5a51c8a833a708f5243e28ecc59378 GIT binary patch literal 16384 zcmeI!|3A}t0KoC#kj)`qy2n($T-os;Tr4^#tS+oCN@JK?GBXWnYYMUQB}z+(Rc?=k zUA~-sxnq|vn{!jAjoPR#y7J{J3zOBzch@~0_e1}~JwET(AMt#=*s~R<8b40;*>JLJ zhIUCd`}RfjBb}NNCp6Y$^<%PPa(csVE!V=xP33yja z{hc?wqnFTZeN;qmYa|!$vVtYE_GS5-Zo6Pf!BLSDnS)FCtd`UR($|{mxFw#2O_#ZT zLIFLeQjkJi!}OdWSPZwkIVG?oqv1Lqr|ofy7uNn~%@-lGx84G{D?*gDhUWKaiv{|Is1z ziJ1vCXSkJ*T0PE*H_bq;LzT3KX7lnvBtFh0tcJ z-~UwZ^Toic`_0J*H>Z|PYpKW{i7{PdteJ1Kwj>xw>n{yhzD9fV-`VRCjjEn|Y>N8e zxDcC()qbe;_{X-wd0hAK&@LG^8R2MXWtq(C+?v9(p%HavNz{&T?|m7weS1rO?xQE( zI}yOpZavLA>kVt>>g~T*bNMTAhM?Q;Zt#lTOL$OW1=%(*L^g55r1v1cC_v*v#a<|{ zzIeQra$kWxTJ79??E03bm`rNcFNf>Q_y6|!Eu)NA`i1Lbal{xwL>GE`@uguef}-vqw3g}ZrmE$1J8R_KFJsj??<_Z){2?cubN z&|65)dM7=*)j^f7?z<;ENl5pZFK>{i;J(cKposF#ym)~54 zZACb|)n(}h?ss{zQfA#;8=N=g_EpLDgru&){tFv1)SZmUqsR|rRZirF$hd(MD=KwZ zhgy_@Oyf*0WDR4KEQ7Yh$4xNi$gU$Jo@M?E59!v2^JX?)5wrS>=d0MX8}Zk$o*tZr z%nh=!>A~^o;so(t)w6LnKmZ^B5coeJ5D5?fCjd?W+9!Yq2mk~C0?`+I0_H|2ml12jX)eg03ZMmfHnfh00IC3fB>`+hzAG&1ONiiMt}qm00;mCpp8Jn HCj|ZldG~mM literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/44 b/crates/core/tests/fixtures/backup-data/0/9/44 new file mode 100644 index 0000000000000000000000000000000000000000..f1994014a2be8aabef0fcee06de52b5e76d37e7f GIT binary patch literal 16384 zcmeI!jX%?Q0KoCZp=}O%=w4HKIN9-AW7A~4B+S@|&6MXNd1?uva(gWg zmxnXk9lJbiZZ~ye%BU{7Je`<_snv))UH5w3e{rwh_wz@*U!RKkY;Ot2eST9W_wSPP zQ&0))g|)PC+#pN6Bl>wWENkM(sR{d1*R`h%!@!((du|9=Lq)4qmGnCixA69M?8emH zlBuPU*`=Z=fv4=%Y~^x!Qq$+f0V8%s&FB%~KIehpA(Uk+vTVM9r&;^Mt*Ed~xW=lT zDfWp{BMyagzJJE{3Ies|KoY)GV7O~KEu%#DJ9L|rn9>}7(o6T7>fOOeFV~e&ACjt; z(;i8!hkYCDS{FW5N{w!#H6a-|tNe_clIbk}OR_1M{pVVv&aLQ{fJ5!DXZa|T`bn=1 z)L&#n&m`&C*VpPpCcVBu@QPLM=Mmzzh6i(X=L)fvYUp5T`)LlsdJ|7(ok(-lK5$K+ zLZG7NQ%BZ`X>IYoq8UYX_xfK+D4Km1hY^wsd2$E`HKeeoqrN-C;XsKwxGDONiS z^+{T1)YgafXRwak_oh3-G^<|Q?G5>8zIHYhul!hR_m6S8)vW4iz!3?ahBVhO(5JDw z_s7*4(Zf_aG1RUg#}g^b1D?e{4=|!1U2tP6_g}0_cZ9WacAR`vbNw4ZN=uK+L$6Jf zX@o~!Ioa6VTQYwKF7+ekyD6-x_-kd=1+lf1$Nl(o)mE+NZ(B5nrc%>>39Q#W`P-NG zG*jNF}CfDSyth`f}X9}E-A+2Ez7X7?WWCioI@$^6t^OP1c44Y@~z!mwAd4xPbD)o~) zwPhR0CWfeov5G{4c*zTdZKm0TGBBaor^w+1y{ZuBV$z2ax_OHlyRW`By>B8SaRp7z zFI;oEF4aC5*^N^bn&#y79D|2_y``;(ghM@{w`=5k{>&pW)twufvR2XqUg4?)&-x>D z;hn3*#Lh-svmdEQh}NjqL>_L~rTZyv#wmexfUqS#A9J)o#J`A8#6-d@CawxC2_w(k zGzKyKe2n4SyPRZnmHVJj^BsIQ9{oK@L^+-n{-8mG|QL*nHx~ zCu|8}ZK<+@7rH1Xh}DKlmd{oP_1)cq?MIruRi&whAB*i-amzNCMytKq167h^-tpV8 z|H6|;duX^EN}q391wa5G01$v80?_~ga01{2pnU=qfB--MAOLLyVgLdF0e}Fs5r_o{ z00aO6&_;j?5C8}O1fY!o4Ilsz00=-EfjEEwKmZ^BZ3N;00ssMk0JIUf01yBO00f|o zKmtGjAOH}6HUfzN0e}EN0NM!90RjL4fB>`+U;qRF0ssMMBaj3T00;mC{;vr93nkru Ap#T5? literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/45 b/crates/core/tests/fixtures/backup-data/0/9/45 new file mode 100644 index 0000000000000000000000000000000000000000..64296f1caef22dd0919c7074ecc4d9d2c6095b89 GIT binary patch literal 16384 zcmeIy{Xf%r008je&^CuWbg!vA9Co}^Tr4{0X>}f^QkuwmsXR9%3^PogA6i1F++J(r z@^IMh*oDUJMklN`%7x3*iFuezBhSvgUiUZL>wfuu-hafqV;{S;8^^)q`fhDtity`; z<*jW01qq(7*k81Ah3Vb%Xa{D3H2ff^$Om5Vt!R-eM=Wa14y6k#1gG7jc47a*k%l`X zuo+=JXDMZK>FxrC^W3&r;`L0zA)}({^Xrr`tca%68v3RlMjdy&IBr$!u>LAm=R(HP z!Mj{qf5BQsdCbGW`#390dTr7H!Q|r5%wj<>*Ht_+Q@&CfSGTty)TO7eh8=l_?Swx4 zDAOin$y^>=rSkjx!2#QFf%jHw(Xg)GIPB~EFy;t3 zyg0*)@YeaBQil)H&0*EwgCMVDv;+~WVPE?=R9%}aCWbag)FETBX1OW%1XEP6MDe89 zYOhkaZ6~zx{D~IW>s*w6^@Q6N>dz1z*SNmXFSD!tCfq(lunXnOa|nKO&C}VctNEC6 zMYK;}%OwWFd>a=+^Q1Va9nIDX!xK?+Nkf~yl;)_j?bA}`waqF`UA~55a8_(;Sz~0t zF1Gt7L36BmHm*@W1cQ*o*es76NbW3cpSeu3Sof6)_JmkijCdkyDbE=;h+S-n<0F#=MbHd2-%`S@dr?H2>@ zUo=IWI~-NCC?le}d8)A-Rq0x*jut`nvf}1|)-=YZVc9?-K&9fHI z*#_3cP&o6Pb>}NCxv|r}%WYeK3gMDd8lvayE|_}=?>pz4>m)TN;<8Jac{eJNt8PH>9_;qXdJ9W2uJYvJ26L9tGB(F%|h( zd;K01&&j>Lwj=YM!4v&=ecc*1&J+BpdbX?PIKcs!G5iXVFIq%5-NV literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/46 b/crates/core/tests/fixtures/backup-data/0/9/46 new file mode 100644 index 0000000000000000000000000000000000000000..a860b151ef5d652039437c613241b3a110ad6353 GIT binary patch literal 16384 zcmeIy={wtZ008h{sKii5_e5LAknvEgq;%#=J4e(VN2QOdTTpei&b00;?xR?qG*}%& zvXRvhW}$OeP%Bo~lsKZIp>FG*XYcoZ&-43!{)i7%1aZCYyyRiXia{9u3huP$Uf_+) zF8V__H_!*BvXH`5!%a_`3Xf?H(KTh?S5Tr+m1bj1k!`UHSk$-pu7K}|zV;l_@$W@9 z=uzzfMB(mpw32=-9i8EJe26Z<9c-1g(>yjgxE{grg55h*r@@L-m?}c)JwJ{=G0>w+ z3fa}ttXIF3G*ZdBX%%_~`xiEKrZ*Uq9584bSGt~L#iE$4pRhUhog8`$GK{=&5I2t* zBMG(pzixyP7fhTNbPJ6SUPZ_{CU0NNWst_R_bbc7%e{-Sx;o_g*bA(st?AXRY+r^2 zdv>*KwdAIiYICgn8L;#AO_*)`BQn&!mY|e_!nDc_JpfucL?_~(F+$>eTNCOui0myMgE~j4k|())_b2{EepKbENP9Ms{dQStyy$JgqY3F1 zw0_f$qJXDJ9X<-c+;VPS(2%EB_z!K7~0kQ%vgPrgJT zq0>p2>+M&O`~|K4{PG}VJ#GaTQ93}zGB2Q_ZszCo+vEC&C^T#*Zp@c5WG_Tnz#?t%#Z#R2?udguP2uZ@KqWrO_jn5cjiVt>mp=KYu0?^G-1R{5-w8 zQ2&DhkeF;46p8#iTfDI=}6RQk;#k{t0j-AHGNUG{V4?k^BL>F5q|_Hnd=EV3_% z`#>g?H3ipBR9fIUhUHmj>)C`?W?_sJ29ZottFHR)l(&k{6}s?Ej0VFgrf;ynu;m(ayw~Gt73bm~>G&ui!@36IUcAFBrjju^} zhtFoBgsK0_1kykPAOVm7v=c}N34jDZ0?5&#K6I{^|%03-ksfOZ18AOVm7NC4Ui^l~~KI#=f!1uC->k zphfpRixmxmH#0Rm1ziR8CwT)MeovUZY$>oToM)tJ35}lGb9YXvQrSEdpKyV z52f@36xCkHQ(RI$h(~=-Yz_S(J;+r|-ukofG$+0(G+m)>Kf9<4&%xySY;9m35!M$e zO>DmfF`-><;L*w@hKHbZ2X+jh|3Q{48|-d3Cr7TBpsS1yXY^6|XPl#UVgJJy4R=J~ zGD8LDlZ)pvocVP7xowfywMEQHL`Ku**OSL^Lb7~Q$m<$d`nav|F*KinwcJ^U#bv^#9^OZG`$T+?pP3cZzbs3b=A6IAN!IRlft(~bGFd2Tw1d@%WJvW?2|I~t(`5^^qSXwxUTA?keVw1jbGlclcRt|k|h9h+8M7wNx? z>$*l%A8VM6tJ4j}z-3m3C$8K>?QR=}vM19QJZ{~pv7ljn*2II#h7N+E;zpsm_Bi|$ zTz;5fjH+DE5Z^AW6L##j&sye{zE0^4q>S`e!Avt8)JH#_4-={Vr0?=ZRhg7F)>w<$ z38w|9B%=1ynL1?OfUdNEXg8VOdhD_u{rUcd3AQM^$6OG@kMGq)NK?fhe=fB8YVdt` zeZ++$QI8g-BxDy)DVC!oS!>eLASzvy+Z@!G##q)a>+SPbq`osd?EA@J{ZbNM`l;OP zU!5YO8QDuWTRuJlVW6O?5kYP{7Rl0%@t3KFky<<~&nB+)IX?KMFE-@GHM@A}u^X%u zOISU9-?pHAEowjwS;0`%O!8-QN{J9e4-U~jtb`oO}{!Ss|Zg_cUcMtwD z!>Io1lcP0$Nu=ao-7D12{r+W{V&Z$boC9N=wwir#`rbrC%Xfdc=p+!(5i`-TzvURr z$MgmY1F=103-ksfOY~jkN`*kBmnIMegp}C1V94NPJj*)011Eupq)S& wNB|@N5`cCB43Gdw03-nI1ehQJkN`*k+6k0{1V92H0ca<{0ttWwKA!~s19jSnIsgCw literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/48 b/crates/core/tests/fixtures/backup-data/0/9/48 new file mode 100644 index 0000000000000000000000000000000000000000..d38114cad1ff84788880fdb7dd9f4ca716d99e6b GIT binary patch literal 16384 zcmeI!`8(Tp0KoBJsKii5_e5LAknvEgq;%#=J4e(VN2QOdTTpei?$&)YRTRbYq>j2O zM@v>mn1#+=L9JL_Q{sq~(`;T}%Z-&8Dga)iurJuIv$BlB8Ul??X zau!8+qBC^$DDC#s=I*Z%Jn86GarQy9f-JH-h*s6j?@o|)e7x+3Zvd|+&GP5RBo-we&k#vqU^VyBGcX1lizrWInw3vw1RW? zj|_a2kYR0o(ssPV6sC+Z*6%GT*1F?%r?n2#V296PqJ+yu5SMFDOYVg%8ie65;Ep

z_`To?J*p)jNx0(_t*{46M`yYn?4k2;yX(a*G>J35N!A)asu z5@T3>UHbtXd8CJDzUOLEb|t8jZe}InS}}q7DfamHW{-tBTo9JV+aA_>B-!6%&$D$;D&<;_{HYF?nqgy^NQIg?%LC+}ezF#k z1JmE8*SODFeg&uH@;6uDolUi`m#c1Oql*PmE(6W3WVps5){kftXDogpT{-|qK(542 z?7PJ^h1#|+a?8E;tEA*QB?W!cA`*+JA)d#Wp4)h-nWp7Ps)8RH&NooI==BhFe5e*c zn@?JEx_`exk7Ve!!xsp-$Qfo#d=O4j2NVuZw*W(w*kh~zCEgE~d7kSDr(_ay#Bx>w<-L4Sq6TCTyadkY7X=32jDGBG47NKTnzzm)AbXgi5p+@RPK&HGUi7-) z{;2dKTA#A1DBvkl_Ce>I`xoWi8?jj4mr9+#L}5{Z#&HSZB! zk+!|P!7EH;00jO60@VNkfB--M+9yy05C8}O1fY#TEkFPu01$vS0(AfZfB--M+6dGG z1ONg60ca!e0w4eo00=-Efd+s8KmZ^BZ3HL)0e}EN0NMyp0RjL4fB>`+paBE`0ssMM zBR~fT00aO6&_>`TKmZ^B5P&uUuK)r70e}Fs5oiPm00aO6&_Zo+ zrn-YMDFOYqaYd`iRxGmF>Jgh`-^roIAj3#&dvUXv5u#AL|CVs|9O2#j+9V2WkNr1 zIOH;lRBJ{QtY%R}s(yar>v<$5ysM*#9_9&$ATfr|u4_MlBaij)^tW8i#yyFqDL1py zaIKiY{1kiqTeHVPT`mYq;~fucJim(E=0m7~eeYsi?X{3k@NWsOM?_%MGZP-O7L)An zu@~67pR43Lj{Tb)F15kNGm#24^OlFmzx-q^A_r%_O|NmExBLoD$>ndY!kI0#tt-_x zv(d$ZD3`%DS2A4V2T0(6ZOWX>tgK8-`rlg>6T0~+| zQ;6pYruQ~pYPMx1vPr=Y4d)xEUG#d0Iyq7cpe!V;bkVWoqLlOS3ZktB& zRPR>D>%*GK0@q$uKKzar)6{L$V|k>o2sh6t^piKUVy%{n4cfV7nsPM=*z|&mte~oZ zz5(pb3iak&B>;gh0Dt@q06+lR2)qCY00aO6 z&_;j>5C8}O1fY$;OMn1C03ZNu1Xut8fB--M+6Z(51ONg60ca!80}ucR{C@=g1ux}> Ac>n+a literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/5 b/crates/core/tests/fixtures/backup-data/0/9/5 new file mode 100644 index 0000000000000000000000000000000000000000..f5a6028cb0b2d8dabe6ea641e095b3928eb4d1ba GIT binary patch literal 16384 zcmeI!2|L?&0KoB}iAoH0bWgN(3>go_N=j$0v~xt=aa8)Kx@Ej_yf?Tkn|kE<_fa2sruz|<*h7ikub((pxKp% z)HuZZQEXz3#V@8wlL%z=O3cK*TWnK^ZTljx%xk|=O0H8<*f%vip|By?^BC82hbT4E zv>ef(;D<#D4Ad@pJ;EFxs*&jPiEB;|9@Obk4c&IQqhf02eG`Sv!%}jy$SX*ZNrDEZ zdN+ytFu!5A>$r1SKdav0J&a>7h=J?1Eo>Mb6P zIZZ2YRgU+$_%f8MXOI6*`~g3)Ghc zuN_R-_#l)rTt+&G(xDn$DHrA`kO&~RIqBO(Zw*@H{5lx!|LTruBwzJjWt={&ktTHg zRr#ZDnb8ehM%|W&3JXZ{^a4M5Gb{E=vDko}TZSo5gN#qhFUt(9Aocd+Z8S?-5m=y1l)@FGye-TtjKVs#W^wdw#q~SNVlOr$}c}lqWV_ zSFgU^e%jpqC5kT{)hf<8h*FS6cL(zB%7n1Tk=hALvwX+U9P4a7o3PR>oRLBwnq_L$ zUel5CPVt38JF%WwYdCJ4T5nWlt;u=pT!>Ki+fSD1?(4~Gyv!Qu@_1IxJ@M^%=>%;6;N_;zhzy=k0*2neB{w zNM3*sOl3BOrAC+-GldUp_A@kPKa|j-Fr{Y0EX0P`Sv=+kVms-_L|=O@<>0UUtBlAN zQX;(LG`*k)&%kE59qeIq3A^h>Ep(4HE}>I+BzNm(nNwfM5lj`O^g$3S813!Ur37zj zY1XKpPZ}&`U$Y81hW(%A-egx0E}7J48(X-NWW}bLtsHW=_HA57G&+>Jx*I!#8>Wb~ z_`j)xCC&l_00IDkFA#x!fB-lFa01Xifdha5KmZ^BZ3GSh0ssMk0JIS}0tf&E00PiP z;20nP5C8~38-dRN0e}EN0NMzg00aO600BrNUwyrvy_Sc| z!`Z_fyU@7ZsM&)y4_$P5Ix!DZtC8jDy4UOejDFwGAMt*D;>b^eUHmhbBuDQ2DoKrf zdd@RlX?>yYk_)Vbu5t8f&8_b^napnY9-npdDTH@nS&W&NFMqC5R~#5xuxSYaXo!I8@sN(ws>UTNnmiA++KJTFx;#C>}9u4l*6rJR`ZQ}go2Wm zecb-;@CP;W?SB;#(zV#7TXsVZ#3xB7(4Tt`b z&`CO+8yzI4tUW6|$WCu3LsmrwVaTbId$ zp2*pmsASr_I(rN&rD(Os4mHDa#}AwscPjBvKTkC|p8sz9Z4RZsc!gS#QW*_|0zk{?8P>2+7DD+KA|u^jG4 zP}S1gh~#?M_aPp2k&`9l*w%z5WGdFS=<;3uRBq5k*`&=OC+P^gbzBU^KiflZ z&vhdbo{XBy8eR>}ZcPg4oK{pvuGSfv@(eVi3sQ5+nTZjbSiw1h;aKZz8q+)mgHXBJ z?2WvI-dwjKu_kjDg0Ea@cBZ+7uE+;;ZM=oU;$#LtTl&4w*CpqSwK32e@w6ztO!O9djTt2@N|5sp z?PASI3)VxC<$T}51WQ&RauTNS)5XR}E5D}j1q8lQrS9+ zm39*&g3c+;)d8bvj0@wvg+>IN`r2_v*hee%=`5V`W3A)AW@WZBs^`ZJ@No%9D{W(= z1WK26Vx4J9gi1dSAn*ku@C+aT5C8~3`ve340e}EN0NM!j0t5g800C$tAOr{i1ONii zMnD7*00;mCppAeSAOH{m2tXSF2|xfK01$vS0(}4hfB--M+6X)c2mk~C0?`+7z79a1ONiiMqmga@FgSgA8$H} A3;+NC literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/51 b/crates/core/tests/fixtures/backup-data/0/9/51 new file mode 100644 index 0000000000000000000000000000000000000000..6683062413b32e33c40cc7c30254fedaf8bfffbd GIT binary patch literal 16384 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 I|8E5T0XyP*-~a#s literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/55 b/crates/core/tests/fixtures/backup-data/0/9/55 new file mode 100644 index 0000000000000000000000000000000000000000..e1860e7f9a41ed59ecda6249013dc8370fdf856a GIT binary patch literal 16384 zcmeI!|3A}t0KoC#kj){iZq$(McucrhbWT`Zm?X@XtcS|?hBRNwm#j#XmJlnuJ(k(! z%dzc_UA~NSqw_tZT)2EYu`sn7nXlJ99``qNKYiY>KjQg#Q7luU3$wgQFJ11bwE835 zoK}K8Nb+)4Lm0UN_Km+2=iGE5IkG;c8j*lE&%Jt2G(+{iBAyo8d@4saZAEfV9cq9* z&qbjtrrb7Ae?{mYPwXAvce5gB%Iym{FJJzC9^O`8`Q#1f>}?!f8ROsE5Ws?4Y!V`9 zo@q{+2X5*{5y`0e)RFbTwE8%&mRV`pxpj^XvQ1k#JUbzygc}>Ojqkij(wV4#lgLF! z;NWt5vxDdEV752SqIlEPMc-@JYHXPffvb`s4Kvs7k&=c19pohZFkEGnXo0CzWJ<0V zaR=JB+uqpSE`5>S8%7`NuYy@+y6TL7@QM~||7h$ntffKDm}scQY+Yc6YNlXzu-FE) zpwP~YznNFq0YJ;n?Di&H#tc8^UrMU>R5hmc*BeE6xze)rJpuDY0$d*ce0WMovQ zP(6XKE?sTZ*CnZ+R$d>{oyFPJzBf_|QDeNa-V^lEL~$mSAp2Nu{f|Mh`JDXOsUspn z48lZJPdA3vx<8hKq=d+|qRGv^cAhEAeaG{E?n{V#deJ#aw*N9G-40gAQabUJedlXI z3b);{!)+5i19#0Sjxca>7tKG^=sg*j>nyb(6K)oj-MUa7)zw2dTV`H&{()&ta4I?N z7oQ646Tf}=NG;{Ha?Z{Pert^qob_p{zWLkVJq(hG*qFKagkN(^7AU=817Qva-_te2 z9Ff*q97`rsaKn8%IGLTjvhq$=oFTA3hOmHDn)dM4BBV(H1~YxWNq*{x5L}LpZEcJ9 zxNFc8giJTNNmIO$jMhhWT##PUixUmQtul-!Wj^uw9(lH&6vl15Bf1+Ubarp4YQ6Ew z=rOv5R4b@<70peEM`RJp!TKJdY(&#Xl z>EsQe8FA#fv+4l0hmX~NTgpntFkA+NYVS055isA8TB5$EhI>nB8-ElXA<*xAHXkP*EG4@2)0Y^<48sk=neOCxhjdEtWN;;}jUa&cny zr^P-b^D2Avh;Xk%pZ_4rtPW8$e~YJ9{=@z7kWCHMRcj+$zf3h2g?D&-+UhzSwPi~Z zzLa8X61_%HI00PiPzyu%w5C8~38-aZQ0e}EN0NMzceqIFr E1j}w zBpX>BVHP@f1+`*zO^G8a8tOKCp1q4b|KImTe4g*dO`YY{m(^L2W)`@H2Ba9S>ZYZczr zT=QzB>UK7^SP z=$jUiSkxHed4lV`OO%>zUWsf}@WaCS25P!qk5MN_Y5}x`q;;o<59{?PhHkr@F)=ms z{>h@25h=Mj_*J;j6hQ-3vzN?yRM0rmebTj}pI!Pke$c0Qdbk#*oop^O^T{@lE%~F8 z^@M~NDRH)?0d*Wi@fMFkouO99lij_06aS_>sBl%Jy%{`9;3-n}Ugv`Q zXXU+Hv3TC+N}Ye?3)PqTZyZcm_+W&xu#9vtxl=WyN-o@!FA+#;cha|s*&edU{dp+D z|MgwdD4y#5s(5`^6II~G>x##h7%`3AMm?5C3X5>_j6y$oGb`3=iP)f>Tc#;jgM?2n zD9;M24Couc-!4~gy7OG6-XoS2_lsk-i@PLmNaMLJcr3Q-g^@v>zJ~6{t1ITnzLJ09A4u643E*F z)W)7;Eo=Y;00IDk{}}>m00D3U-~^z30w{n0KmZ^BZ3Hd>1ONg60cazj4iEqc00f|o zfCfMSAOH}6HUi%O1ONg60cazD1_%HI00PiPKocMU5C8~38v!kV06+jB0Br=c0RjL4 ufB>`+&;bYl1ONiiMgRj400;mCppC#~fB--MAOLLybO8bY0e}Fc5%?D?n|MtC literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/57 b/crates/core/tests/fixtures/backup-data/0/9/57 new file mode 100644 index 0000000000000000000000000000000000000000..5885e2ba1e0cbb3a26182d9efd3fd9bf353d8e42 GIT binary patch literal 16384 zcmeIyi8tGK008h{sKii5_oA(1$aoYhA*!ylbwu59RQgn1A*i}qck4cyDvDxxsbh5v z$wpR3n1#+=L9JL_Q{sqDH;Wx13$+HktA{1cnYzsB=9}!jjgWOp**yQ0K_1Q7Eh`Q$@p+EZ)uGhJ zo?|U+OfGNa_%STm)62!%g^_iq>qBysgo-Is=0(hq>nKvK2~n_`MH8v~;klpJk(ltV zjv{)PCme#rVqV?Sehfz*>k*jmxta}o5{*;t<|W};F@gCh4utpS&xAT%5mqKUo;C!2 zCAGzuR1N#y)uhUMA)ge`99)Npz^Z2^JYy{;IXq-9uys!><=Tz|8XXN}xgDq}UxW*CApKKdvB7P}d znusSMS7Rp++~b-VET+KcCv-k%xAkmw&agWHWLzJq{P{l2Gns7#Ya2_b%t6YPxkQXP5hhk zu)}85Z&_%hs zt+LVt(OZHCW711#{e~??0WXoV4>}h-z9{eAj>Yl5RORR--aN+xO>2xydgMIY+sOBD~NUx_S*A4l@=WuMs@y z=r(coVYGrQvL}dpUnZ0_0oP7cn&UZz<=W)v*@l;8V~rL1kxVn|j@r)D4~nl8ItUGn zI?RMgT7z-9jVAl4OOc4O|3QjOPk(QIlL2$I+w(;Q=lq`;geW0QOwdqj7F%ym$YG*{%S8}IHD@LFLzWD~2$%53U3UYoWp&UWz`23GFqOGfrW$^7 z+)Q{xbAYZX`>B)~jVd!AVTx>uox`E75;}-ClKdPv$-L5 z3G6?%`XB+207wAZ37|m&AOVm7v=cA@34jDZ0?mI^rgdN*`6Xpz3Pft@~)ID2nAt9jjwV zHnKXxEOf4@pjND|DRD$aL*3Rr&tAj&*YEpz5g*dgA4TT0nD(F);qEik;(iKAKog0-dgXJeM6@=n@egc1dpht%kwxg+0uXZ7oRl&5d4nKwc z$JTthHx!!|G-#htvX*Miq?oQ9vpJ5P99kSQg1o+;Fozu_3AG2lZiJ=G8@tZy6dLWn zijs9s+dBVKT(I(f&pJOg=POWU_`O_`gGb^P##nBC)Hdu1xq^fCS z#zg~`+Za-{1yQt?Llvq1;fcTZv6%3lwgP5^Cme>v8a%(Q^#G1M(Iqh6a5b9tC7P!_ zOv@rQ$za{1)Q4C-(G|FwAQ^? zt+|d;OfV?0FrHjk@%%d=^#82xfVZl=#kJGZr`=ct@Jspk&^3?6!g!C zN-k**^FGD)-zG@SwXQ}tqXIB+zP{>ZpNHtvW7Qz)V#q&bXMW+2B-3 z+o+V>Jp3wLXd17MuG>%LJSb`&?LF;T)ypk^ojB}QIx|ua(@Hgyn*CrO%$EF7(PmOY zjF>#v)`UI@A^VEQq0dmNpAmA-h@mBkS=SQXe z8}T^a$7=0=~ztyjoV>a=Ksu!3VeCn zB!;JQwlrV3$2~s{ca;4i`NKU ziHQ0&OKClF*l*O&;PQ5OlZE z#$A4iF73fInJ7SzCiG#V>`szN3kebWM2sPj!Zan60Vi3IL~vA$hXPU zwT-OE#Tudpkqi^-uKMouw+hcuU4$ljgTbUxMw4NsjRyOXYl(A4kbp3_CU3+D#=!IbCI8LIfH2@~N_jUk$b?E7*`EV{yUlp(Sub`FRBp3oI^ zEydrFL;AlHumA~w1V94NPT(3y03-ksfOZ0wAOVm7NC4UiSb+pU0w4isCtwW{011Eu zpq+pXNB|@N5`cCBIFJBH03-nI1Z+V9AOVm7v=guc34jDZ0?Tcbw`)H~tiseZit7Awu zvO2;nbnXgj#p;?8M^rS_ZQb+izrKS#&+q$r5ub>TdQ77YA&-F)tQ10AuRAY(7`mbt zPPl?Q?ePw}k<&%H1Lp+!!ju-$87jExNn^n=^&y(N^t*COEULm}j3Klwasi9_me3XW zU5cMAn{@m~(G6Nmdti!S_c>~DKbD5h#vdP|3vdTprR`L=O*XEFf4pGVz0zT@{1m2) zPFQtxDFmGCfox%QNjpyxGltz~MJjQBkk?Z3x zFqgKbSGV%~=w__h)zaPK=!TD*BQoTqsu?53W&IJSaimHMqG&ybDpdW$V?U1*5y5>e zdGsh(FcgW=f99%rAC5fLAuwKZ)SC{(nrHAPWsw?jL4|3ygx4mI1iGCN=7xK2mIPik zrOlUE3;Wv1u*PetkQmS!(twD+g)peO=ctIY8TCq zk$?G1n?(=LeVJM7vS|JpoSM(uS%>$u);(XV@ytb+@}r!F+ngzIwG*sA$tuB6^h%~= zAdZM!kDormC$xrHcdc+Ly^d-mWO~H;{W7AGOPWJH&M^JA2@>qL_U?ekUSPH>SV!!{XNbie@w*xI9HkZQ+wzx!OKSMZ*Cd}Dy zmzE?5yYe4RNUorDn|9>+JcKIVXkBvopm^XOkL7--*7`@bSap^6($0v94M8XhN=b&0 zx|Ks~WFkFyVnM`C2VJYU-4V0=pGTqsUfed0;VR#$Nz{e4Q21`WsCw`fJ+8UepwIk7 zZW(TxRqQWoV!>Q56B)L_XB%_Wh}g`c%ADZpz=0vGXQgV3_YG9ZYapW~R--{C z)6*@M++wRT_V%{9#mRKNn+P>nozf8X(4Q0IEW1475aTF}@IYs2>oj%Q&Y8MAM{p%$ zJ49K>v2xPLzFW`z_kz0x6ISAimb@R7|0DG8O9b}_1)=jg>a2&3B|?h+M`==hgZ+gq*BIlyZcnP%7yry6#0couHKgn%+Rb7r=#xV} z;vyaU_=x{|0yvNWNB|@N?F5`a0w4j90JIZu1_^)!KmyQC01pxX34jEkoq!8S03-ks zfOZ0|AOVm7NC4UixPb&f0w4isCqMuRfCNAS&`!V|Bmfcs2|zo6??D0}0gwQ+6Yu~D wfCNAS&`!V;Bmfcs2|zmmFOUF803-nI1iV24AOVm7v=i_F34jDZ0-q%CFC(0OQUCw| literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/6 b/crates/core/tests/fixtures/backup-data/0/9/6 new file mode 100644 index 0000000000000000000000000000000000000000..203b4855ba5e2017601888d0c4c4ee5f9e2e0240 GIT binary patch literal 16384 zcmeIyc{|&8008h{jwI@iJ<--NWIPlrDV@2}&JlITQR$=V7F1oWyLBH;6-BW;sbh5v z$wpR3n1#+=L9JL_Q{sq^3Z#3*WhE{Jz7OrK}M5=yx;^%b?7v9rV!jABSL(w>+=ht-}AkZiJ zMCKc=R^z@z)3m#JX@qucP(i8#@s0Uop)OaXmC3HB4Uu0(ZS^J9z`k)csrFthAO*C9 z)FUHt8d-^tSxdHhf*9AKRyQg_^BC_>wv9ItzmOplNFbrt;-(JW<6FY)I+wW> z-iOsvsBTF?zx2qY;-*lqQ(WI|qSRc=YE+Y=KNi6^RKMu`5OaF09!OhE-f+Huzd@g3 zWdjkvf=8iiOnd z2fHA)u(ORKOdIA$s?irn4*z%QSM%woD5O)y5Qls%re%Xaa&2i zOQig*?m3T-D*HF$@Vt*zy8kE?X{_*HIhwNYAxITrS(y-Wms)5wD#D8|5k%^6Hn5G| z8Me&(c{noQjGO zmKj%*gwH6f$PTUw>>tG6tk7t_^;EUNGmaGhi&Kr{wcpM>6N!B%m?=F+?`jZ0P(LlS zbbR}}jY14TD`X`+^4Cn2^@t(gQD38r+a=<@#wcBhYHbRIk!HQ<8B>|QySv3JN@5sZ zMQXxoRR?JY{@iFcg{5KVXctkW7dBH*zp>L{*23cjk|z_>F3vuRQItdX26OMohOs6Q zI!Vg&Jg4wHn_PX{i1HkqvEl%lX=dG7*Om5G>A7Mjv5`@4G-;CFXk1~V#eU>cETZCn zm@3;l&{xoWi8P32)zXztdiaYp^HgGBLsx zBFM|N(vkU{EFkN~t3K!5~50w4isCx8SAfCNAS&`v-cBmfcs z2|zo6Gavzw07wAZ2}pnhKms5EXeS^E5&#K+1fZRO6i5Ih01|+90@5G>kN`*k+6l;j x1V92H0ca;63labcfCQkOfE-8wBmfeCb^<7n07w8N0PO_iK>{EFkich?z`u__cuY)M!9h16zng z2N|(h(&#r7klXBE9gb07Jyc=pOkT{fy{G6cZQU*%=!v@_)NJ@OkH|Lmt8dJjKX+gh z$CEr(CRmwwF2tPbY``_`Cl*Q3Ce@~h9rf$1J~3YTrV_UhR=Q76cNNIQXW&{Y3Fb0> zN$N%zejI4hk5P&-c5iPA($Ku1eyQm@^YwW2_e2?GPgY{2hP(7f*)B1=gOX*^wN_N# zix*?_W0pQ)O9+P9$_`Q7jE2x{G*B{kv^q+0a|Py#aC)of=m#HkdvO_an=uXU8?#kB z`R=fkRoH(bNFzOTTn*pGGBt2<@WsUDV zH11UzV0gr`JDBrs!&M1)plE?t$*fAaj`#B9H)O1rPtFcc%@!p}Le!&Em2>5%8$Zve zko@z)k)6^_eyZpJlv^vJY`Q>XTJyv8#Q0@%lLb#l>_eRi1BLUuePruJIBLb4D1EBM zG#e~iMq+}hn48n7r8$wrr$N_@yP^@H0rPR;M175*okXjHeH$H6dwjB#mefXXM6ht~ z`RA|6Ut~p|RZptDKGz^SSCU!|Y;T7>&PO@aO@uC?{vz9jobG%6_2s(QiO?_LqGJ8~ zX?S;A{himf#|p8PM(F6i_QL|W$1M&KkTEb zt$uV0AF?#3WsbEsqgRso2^Q(-wF03%H#VU+^KbrH;bBM7Ev3_&hcgo*b*|D&!IZQ6 zY!SNinh!sf`F=I{@Y+@&9n<0b~Z$_BSwpZHm|Tg&F>x8#GCS- zd2WpT=xjKef!BSk@%+cW+SaaYqCxZv|d+uiSe z54TSvVCYk+tY7n--!S_~{UpC_?<*}x{zy;D+Rc2v_cXVcx;}Rce5<=d2s9IO07w8N0PO^lKms5EkN~t3pnwEG0w4isCqM-W zfCNAS&`uy3Bmfcs2|zmm8b|;n01|+90(6i7NB|@N?F1Mg0gwPl0NM$pfCNASAOUD6 ya1tZ{5&#K6JAqV?07w8N0PO@$fdoJTAOUD6zyt|^1V94NPJjgx015oh6ZjW8LV_&- literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/61 b/crates/core/tests/fixtures/backup-data/0/9/61 new file mode 100644 index 0000000000000000000000000000000000000000..366ae659e73e9fb820af59b45eadc97ab8a717a8 GIT binary patch literal 16384 zcmeI!|3A}t0KoC#M%x_nrF%@}%VEcZvWrFMd|RC_Qz^}ttcPTVhJ>jZTahR&AtblQ z^5yd7u-&l>jdN2cLmTSC<;$)zV`??>-F1)0{R{Va+%KQ^>yLOoUb67Cs+^^zcd8Pm zz~vCi4pwI+=B-kcv=Gx*13|PCI;aR-F4n23GjPH?>;Xz;nAV{yT~9MJMn5{MJa3dJ zdXC)7w3t#IPb%=wcM3?ZxQ=%->q84Y{W|NruDmqAZ`Mg_5;V9zch6~ZtMs>*-aJvN zZAn?nHhR?8Thy{&IMfq%eAh7wUlve9A6kCO6* z7N>OkFg{ndmwE=i<4#LezAaR;w;@-HBjab%d))D@u(adgBJF0mK$?Tz2w<)&dO zyd*;HcZeMX%(tY@*zZ`;fpYfx@5KlCwDwpQylWe;q?f?Q<%O=V;tGi?3uW!R@Oe40 zTXU#z@l<6{-`!1^HOk_xnxP(k(v4*&EIQcN+wRI5s1P0UOWcC}TR`eqPdq+5w(kg| zRFUN;;(94Ir1HRray}iM#F<-ROyVVMt@fB_jWE`f$B8Lyk^9Qi6yxLB?{?l4u!r)O zE6S3~qiz$hj-2}R9U|Gn=*&WXw7^F?K2x?>lG^ZTe!zs2SvBS%-0eCLJcPDsK@}^m z@wBVIza1U1fq*YNn&Spl@B}p8_5R7dmyzgACz9}m(!Oa$uX!xgt326(9#@ndNP6LQ zORFmw;Q(l?w+fLu|z6bkv_T>%4khI()mVN8M#(tVA8Fx8J&~DENxDR*uwXoBNNVH6L{8Qlk^cHFQ}%jIi6T{ACAOH^?$JNf3An1GAG-bFq>yNQMz=@ zHg1(EJ1nY~`4{J6Rfsw7p4eh;aDJL6%@Je!l0~$BBa|vr{^7@BmoJ82KWT|Sx;wFO zK}ALP3UyNWI?CmCV?&b8NzJuk!#6nRruXI=5!w|m9e0I&v|KrrPEdWUcKqA4#CAsg z^q7Z;5RbBi8yUv4yQ~vxOp+tidU4c;LCyj6#Q~p!p9WH59-s51sjM&5WH`fGxEhBa zSKatZKyU7Gd*r)e_6q5pTS77Q@)Ie_5&cI)^E{PyRKnHb%4=tq+&fKwT z3{R&rem-8SfB4tW?`hLtYvyjB`+ zU;+dH0ssMMBftU(00aO6&_>`AKmZ^B5P&uUmjMC*0e}Fs5y%1v00aO6&_*B|AOH~f HpAq;62Ec>? literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/62 b/crates/core/tests/fixtures/backup-data/0/9/62 new file mode 100644 index 0000000000000000000000000000000000000000..0ced4d2ec409d9fee540d732776096b95f88546b GIT binary patch literal 16384 zcmeI!`8(Tp0KoBJsKii5_e5LAknvEgq;%#=J4e(VN2QOdTTqRob+_&-t`x=cq>j}w zBpX>BVHP@f1+`*zO^G8a8tOKCp8W&+bG%<|SQ6Iyr+a=;Y zMshk5)mjt^BgJabBdRiWcXx|dl)x~!iO_)6stnQ&{J4>>@=L=`kG3*Ol^4 z@r6PszL8OHIBA^PXjEaX$Bey6l>ped(d8oX|Tg*Gf~17B8cm?=Oqt9mJP!2S8ylY_X2NZcG4fhxq&_~ zmH8B=8g6RBRCrW#kgh5Fp^O@ZDmNQtifoBpz@omzcLscy=xfg*9sN$eL62+;NEGfm zM=R>X($N`iM+fKv-2P@s8_i>bgX_g{z0Iwo&j%w>?qviHhMh^5|7vAQ~xx|j>B#m%Xe&1_$W1$$?bz({~>)HP^Bl(WKyqhVu>7u6pI5PLI_BXp4y(PLCfq=ur&a z_Bi8WYUTq|#jT@Ka`W)(aG`0O2C8;HiSvZqG}?38y{ey8_9kw~r(|ZN4yK)CE;akn zHjpj(gOc^6gcu=VuC)<$5=8M9k4BxNR?3syz55dWqCBc}Rir&1R9YX|SfH^}2XzOC ztjHl51TUWR@kg@37vt~yn}h8xhZbz|2*^IBXgFPzyVoWwjTgNwcsMS-jMi`5Ruu3Q zDSxMP$^Db^{+$>s?^Bh|-||K3EBx0ECM;|)LRnZwI+)a@8d5Ds^yEtf5;~mpZK8LE zE%JUE4)=d`-!zh^`mj1qAJ$A2xb>K>&gO7XqmO0e}EN0NN*z1`q%U00f|oKsrDGAOH}6HUb#{0e}EN0NMy- z0t5g800C$tkOdF`2ml12jX*X)03ZMmfHnd-00DpiKmghZkN^Sz0e}Fs5y%Ay00aO6 z&_*B+AOH{m2tXTwe1HHz03ZNu1PTBG00Dpiv=Jx-2mk~C0?o&W#R3Ms?AZhbxv$rV)9%?)ADqqu=-QN4#Gj8nfLpR)9_jRqMr2Tm2lo zQy2S>-1?^dbMoH{#U#PUkLj!*n8*WztLU&LU9)4m0kZiF-1R!^{-!x3NcoD50f=PWJFtBNzl zj)ze;u&P}$;m0Uta-hkpe!paY9aJbj*UrAK&G)5y@B@^}Fr`ITzLsKYjOjY7JZ}^y zeTv+hX+Ewx5r4}o-`+cceVyQJ+KZ96dbU-!UwL76-?WWfC$4dN>XK9E%=5y@Z~B+O zEuvPljk<~H ztIdO>4peQ`{}?;v7*F0q+UPhFbLd)|=mJt169L;bennzM8hPxhJ&2QuaK`V-xhYt- z+n@wKkJv`UeotFVL04m)P-;%;2E^^UB5w)C)P+$QY*yo*LVX@qP_uMfRs zCd*UGb(>k2D|}lOqEt*g=j{r8j4;U5YL0$V3uBBQ^dGk?a9MejXnZ1je)~-^b0~kA z%}OW>FCyC6a;np|Nhjw%p}lNth96LA$6^Rh_fPJ+7x_hn~Qb<(HOxnn55WO+Zr)^5f3tJT!pgZ(6BXbfnOX_1oHwoS6$OdDL zZ<6Xwqwq+zqt(8!8`#ZtD~fQEG3$5fQmsA5DQH!}`snmN`~hut{K3D-@< zZsGDxn8D%Qng4Ju@&nC;_hja82WBUP@*J66Z-O+r&j_W;P`v-S(DAF`*F6oiV>{#S z%&DlDZi!B!NJqKcY-~u@IjOliY&eB?s9P}82!*p>*zO4aV6k#4ji~xiVf(L1vGuh2 z(eZ;)A`NAsZDdFT2z=fM6axeR0ssMMpFjyf03ZMmfHndwfB--MAOLLyN&x}@0e}Fs z5hw!)00aO6&_F00PiPfDaG=2ml12jX(uJ;Il*EKWssS AkN^Mx literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/64 b/crates/core/tests/fixtures/backup-data/0/9/64 new file mode 100644 index 0000000000000000000000000000000000000000..8cac68927155229967752e9140ecbb9197a5ca7a GIT binary patch literal 16384 zcmeI!`8(Tp0KoB-p%OzK-4kscD;W>PN=j$0v~xt=aa8(f>k2{D)w)~v(X>TTEKiEm zRXJL+I>Ib;?h0zf>Y5TqR5a9W_B{I!_S1g&e%^n?>v;VoO9YCHPxS3UYXft0KF@a`R|I+PcayZ}HL(dZ#_VsBK@1#R|Su=>4r!pt&G? z>tx2k1|!tOgA~rq0EGwvj(A|r@UZz=p^Xb_- zuUKN-E9WYiE5CmIOg!eJNXCgNW?S7cIOS-jq2-6)Y?Y#M+QAE95x-=pEr<8{4*D9O zUoVpKHBr=)rs|N%tW=v>ujul$&CNAIK_biOGC~VheYTge7la`*Z5dyjBW-0Dow6X%SGl+j%K9n;G*G*KN7C47JvduBD3op&am?-xk+2%H_ zHEpRMR4SEQ@ibPg@u+DU&7{m$oBPnUP+ZM_H$}d)rz@}i0(+>#>uEXf)E^o6C{g3; z+N8~RrwL3cYoymlMzVR!<92fmrp^JM!$ygfi6bsnpOD!JnKuf?1+R&)GVR@{k& zqK$&c+M|_zMRG#86)0URXhC^d(lozIQXF-k8lJ z1~dfMA|f!FnF)_Mb4iYOxwBmTqYB05g8;hIg+|y&CQ`X-#(EF=r@w+#WZ&es=~bRH z)?dLHkA&+>@b-r4*NfEa+2|q>lv`h;I|Z(_kM$?n#hFT-OP3?yh{&bbv0ab2hEV&~ zd4AcAU8<~NyNrlmT0~+YJ;eJE({&3kJJqllNmuqq!-Yl~=Wjef9qwxo7_&($F8A)$ z8IX-Vws^ym8kRj{g^h!*KG<>CzG#?T@-Dv5w`gLZ2Bw>A zDLeVuK9DQ(T-A0|T9TMJ)ks4f1d)BDVo=8^cfWo&y8`0^kIoeFBvL0e}EN0NMyt0R#X700C$tPz?|O2ml12 zjX(`R03ZMmfHnfP00DpiKmghZyZ{IQ1ONiiMxYKL01yBOKpO!XKmZ^B5P&uUbbtUr z03ZNu1Q-ATfB--M+6XWK0ssMk0JIT!2@n7X00f|oz$<_NKmZ^BZ3OB80{=S#{{X8w Bf;RvF literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/65 b/crates/core/tests/fixtures/backup-data/0/9/65 new file mode 100644 index 0000000000000000000000000000000000000000..ec8512326c5c29438cf311b83dd29631a9424707 GIT binary patch literal 16384 zcmeI!`8(Tp0KoBJsKii5_e5LAknvEgq;%#=J4e(VN2QOdTTpei?$&)YRTRbYq>j}w zBpazK(KK}K3Tnmbni5A;G}LYOJo^v!Q-An=-hagFd3PN%m-Vwt-^LI46i*G+!nBjk zrKUgG2C^l8QL-MF5F;ecv^JoQf=J%tF{o4I3VEWtcTeKqqo1Y{3gG=eJ1-D#7R#*1DT+#i)*MC&(f zDhhatl)cwE=l)rF_eLz1_qkH%ANfM{CH@-+6BafYp)4#T9Zc+04XKg~_vA|i5;~mp zZDO_tEpmSwjPQSb+cb)&dbcWGAJ#+`xc0i@;diu{#xA37%R_|)xOqmQpS+nBYo$bN zz|Jkxl&e9&rWcfF1yu(0_G53Bt2fxwR(yk#muV zvfqA+Om|;Te$yrTNSDXc3eMR-Gw@MDhBb9b+wl%lm@?W}zqh1V`;Ob4_F7E69X^MS z5-t}(T&_7Sxfil%5Qe{iJ7V4nypqMB-i31mePAlHsdP2m#F(k@ux3A1Q}$yiIT}@F zHcS`U5IciK{fK7-{FLNt&mkWCQE-JC)fSK>+)#~KI6 z6dcLhx>4@bS9%0fMJRpb$MHvdnYzS~EiKJj^>fLCWvr`Kp~tZQvT2^|3dW=a^x4K0 ztt4Bq$Yv{tY>s^ghZ=(nBdzYn&0vO!LT&zU>tRW=CeE|E`Nq3%B4iy?HqJhx5l3=% z%8J8Fyq{oobx5_bXIS&=6HDtkzBCK=)Kc+QVPxIO+MpaMp<>d6e%^4EY?`xS9>S5{;8?W+mZTF@gCh_V{;Z zkA*s25SGT<9@cn%CArmyP!0Ru#kk6AKA+&<99)Npz^G>?JZ3E<+23Q&vvp4@<=T(@ z8yzmS!p1U@3e|I#2gtwtWGx~GroTn6MdWbqcR12WYC#^Z%zhAFMGIZPFjEbq5_e~VF4ok_+!Y{*xCUF|5 zn%!j1gM!B4E`R_);7cMv0|)>FzzIP61YQ6H00IC3Xd}=95C8}O1fY#TD?k7s01$vS z0&M^RfB--M+6c4*1ONg60ca!80T2KP00f|o039Fz5C8~38vzDD03ZMmfHnf100Dpi zKmghZyaWgU1ONiiMt}(r00;mCppC#QfB--MAOLLySO5Wl06+lR2y_7i{x<^u0&z2j AVgLXD literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/66 b/crates/core/tests/fixtures/backup-data/0/9/66 new file mode 100644 index 0000000000000000000000000000000000000000..32cecc6c1febb99b694661d638822a47e70b37f9 GIT binary patch literal 16384 zcmeI!2|L?&0KoBJq7p-q?uoXJA>+}Om6Xn0X;(zuaa8(f>lRd9t-E!rri!AiY6b*i-ya}Y-HS4hAd zp;oGsef;}U|EAoj^wOj~=V&bttjy2^SsY__G%Jp)iWH{^KmJ^7_SNwF{^oG!laYn1 zViLNKDHlVR6K%DrsSxF^Nbe4-%wtU(*EOa5;N|a(PWXJ%-oBcM7k{cU`bWJ)e?c=gx)If=Xg`T!DCw2Esbj(h?^3}pyqMtLo7Qn+-P_g4rm$wJ)aBmF z2j4Ifnz}7|?DjS05VkobLFzX4tfi;&TxaiGYmos7pIuy$7giP0&%s}-&~Lu+M5nhT1_@P(+D-*U8+=#RR*7#{5bVWksG)npM7LBUS)+(Esan%wx2OV#d=tm$^7}Xo4K|u-ZQoJX znfXrhg+>Rlkx_3xYMIq&QQ=@Hc<50I*ACjvQ0-y&6*Zq@4t4uJsT3anGlv)_V_sXI zwwdfYfh%W>aQv0z+qb-Lwb$VqoQe5NjBEuQdA|0j(oV#@SrqX!;h^hA=!Luv`fY?L zGytYEoypWAjEz{!@(nq3L$wdjsPUL`8$J`hCVvc%`JUJj@6iL|ra^mQOgs;I32q#D?_o|e_uXNyR| zE#dXZ7@U4?$|KfXn#&!*tibql6{`IpxXJZgD{Leetx+>$w}<{KNbOQAck=7(8lM@v zFA%f>$@&tatEKkkV)eEA*fMF1C%4s$iZIy62az3`+-~a>w0ssMMBftd+00aO6&_;j<5C8}O1fY$;06+jB01$vS0)qenfB--M v+6eFg0ssMk0JISh00aO600C$tFa!_)2ml12jleKK03ZMmfHndn5J2Ex5z>aG literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/67 b/crates/core/tests/fixtures/backup-data/0/9/67 new file mode 100644 index 0000000000000000000000000000000000000000..d3795b9bf4970acd7e90d2ad218d3ca13ddbb3d4 GIT binary patch literal 16384 zcmeI!`8(Tp0KoBJsKii5_e5LAknvEgq;%#=J4e(VN2QOdTTpei&b02MsiG*BCv~ij zA=$|42(!?+E3P`~tP)35G}LYOJo|mW_j$gb_aE_k-f2j=ih1)xWM{3xfsMrR6K?Fj2bvWhVjy_6#9ha(_YqbCkrVj6<2 zTbDQ`9tY(TGVS90-pOI{`E^0=Cz!6gc!}ADmGC+_A2gh&r*hfjG3w+<#gDo`Tz7c* zuttZh@3PAt7Ev+nnaFP(l#rQ&Uxf=y;?z);dkO4ExpjjbC+#b`8AYS9eO?7q16451 z1XGEbPuBh{@m~}y$HYVk@w1J!sN(>#r)U)F45d_-`%Yu>U}f(p}RiN=3;R62A6>BVhD%PggLuS(vo=LoBRjEl1pga z+AVoLccJ2GtqZQ7758pMW4WKpwEmIJQ(fl0u`^;~0}+aXQj&qBHszplnNWA0m_MP# zLDwp3yWcG9xBf8S*LRI0xXSm-V|8Km6uuj;OCNtnkE-i1=rli)TZEgY=K08)STI)$ zMfz-9(u_H31Z+xfNqRt;Uw1F|c8O~Jo##q5ZqbC8-|Z{JZ~Xc73!$hF{HbSWX>B!p zaLVa?L(30;S;|J@)B~48!v08ATnp{<8uZe?yj39TWgw#^R<1!N(~~R~+#*YpcXl?p zdGU0;>j*VirBW|---i?7EW6n65aB3{a7U+V>(sW|&X~HsLU1J`n?+fNk#f?=&H&Cm zsbJ<9Tr*x_j%y#1WtpjC6Z~V@ z`9g|52Z>UhJzY8VR~SPbZqG~E=ijE{BLws-tBE_Yc2k&Q`be**xJdJ^%f03*OpOgb zlYtT}5kg$8JS)B*w4@h;zl1w(zvF)`y_I$!&hhtxDa|D@RB#g`#)5{k42P7 zRI$k*Lugav92WH>zSZw1qPH!Zboh7fHCjZIA5pOF3^lI{OGBr*9PXpDaeEsDO;opa zHm;q2D0}->i9=7(F-#eu@R1k88}4q`CIxM4s8^|8Na!zSUbhH7f&G`&=wwGACeg3Q zIwpTL!GcLKSv_L0ZClv1C}aqEZ7*gPGe{C>@*S;#5$B8?=d^PS_uhm_+b3?Ge?lh> zW$qRigcf=}!)j}htD?^_7d9rAH!{8HW~`~@g6+KU>eKap8FF0dq!Htye!tTYQl%b| zyP8fFD*O4FxBHQZ;I5WDdVnh!gv98-ys7yJjy%@EGsZdUwR>W9lP)HOp&C*CIf=IT zag(P4ZB7Vt!yPwEJg=tZc2eeYyg?y-qO-5C8~38-WRc06+jB z0Br;&0RjL4fB>`+m;wj@1ONiiM&KPl03ZMmfHnft00DpiKmghZ%m4%c0ssMMBQOgP z00;mCppC#BKmZ^B5P&uU^8f*W06+lR2rK{u00IC3Xe00*AOH{m2tXTw#V-(ne*u;t Bhi?D? literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/68 b/crates/core/tests/fixtures/backup-data/0/9/68 new file mode 100644 index 0000000000000000000000000000000000000000..ed1afe518da785a46ef024ade0abb409c3d3a6f0 GIT binary patch literal 11520 zcmeI!c{>|+0KoBJsKii5_e9%Z$apALQaW>`og?awqtZv!6@sd(b+_)LsiLGfH=h=JM{>ktAB0kS|f~!@(FV!&RZeAR&9TS+J;((hl ze=gGD3bQiV^|Zn9D=5vrgeu6_t|pb<3;BeArr=sw1X?3A;W=|L$>9-efu(m=q0o8~ z(BOEj88Vg$M^w#Q9l`(fm$!@@nE5ij%46Q@GblBezs-SmHdVh_t-PC!A_*g12b$d| zP|ahEKhZYMMDj|yEFMdMb7ChC-Q$`gg*+(H&nms{SiuN)lY)lfuG7v{gY1&`@dLi3>7g2kPO^o}%tyOGmh=zGHsewfgv8nAdgMtE*+()4 zd5%)9Nc8aON&JiasN7A7`l?@fZD@U-%1Z0k>kDT_4amWG3G9zQ78rgpy42ekY=1d4 zZ-YmG_b|jGXyV+x7I|5m_-*0CQQ2jbLH)Lpke68L2i;2^pH%km#A0}#Ds=x=EYw)x zzjHKYVuE2RqH?mq#16HPN`-JQzEmKg&Dp>PB%E=6mex@x1f`tKH?@89n~h>LRx5ZVEaI08m9_8z-(g>) ztJ@?=Utw!6E#t-h^pFs#W``2mahBH^s$4=O`C(m=`KT zPrtt1VaCGa4U8un-73jCiblx8yMwq7W#~6v{=tvio{g>4^!m2`+D*luQ5itJYSZxFaD8%ixM%a zu1(sFcbrC-(#QIJq$OJS+#j^opzG{$ISiy|nHcPP^?B)okY&R#+!gFe=e@uiS?#ok zP;Q_vM0GBep^lv#GZP)w>ZfVRZ?gKBE&ya`s9|;l(~LFnYS=n%E1>g^kITjT}F^C2M+x zv{M*ad$vBPKu##1GG$yg8gw0jt2e?5I9XJ&itk_ec^ylL?&&I_hIpbOaJ13u+d5C6 z@DqI;V*(%m5C91Le+VoC1i%S^6Aw0ssNQMqmvf01yBO2sQ%i00DpiKtQk&-~t2y0ssNQMqmRV01yBO2sQ$n0D=Dw GfqwwNM=I+8 literal 0 HcmV?d00001 diff --git a/crates/core/tests/fixtures/backup-data/0/9/7 b/crates/core/tests/fixtures/backup-data/0/9/7 new file mode 100644 index 0000000000000000000000000000000000000000..62f04f631024130be4991f724dc3272f913cb57b GIT binary patch literal 16384 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 Result> { let be = InMemoryBackend::new(); @@ -30,28 +31,35 @@ fn set_up_repo() -> Result> { Ok(repo) } -struct TestSource(TempDir); +struct TestSource(PathBuf); impl TestSource { - fn new(tmp: TempDir) -> Self { - Self(tmp) + fn new(tmp: impl Into) -> Self { + Self(tmp.into()) } - fn paths(&self) -> PathList { - PathList::from_iter(Some(self.0.path().to_path_buf())) + fn path_list(&self) -> PathList { + PathList::from_iter(Some(self.0.clone())) } } -fn set_up_testdata(path: impl AsRef) -> Result { +#[fixture] +fn tar_gz_testdata() -> Result { let dir = tempdir()?; - let path = Path::new("tests/testdata").join(path); + let path = Path::new("tests/fixtures/backup-data.tar.gz"); let tar_gz = File::open(path)?; let tar = GzDecoder::new(tar_gz); let mut archive = Archive::new(tar); archive.set_preserve_permissions(true); archive.set_preserve_mtime(true); archive.unpack(&dir)?; - Ok(TestSource::new(dir)) + Ok(TestSource::new(dir.as_ref())) +} + +#[fixture] +fn dir_testdata() -> Result { + let path = Path::new("tests/fixtures/backup-data/"); + Ok(TestSource::new(path)) } // Parts of the snapshot summary we want to test against references @@ -85,12 +93,53 @@ impl<'a> std::fmt::Debug for TestSummary<'a> { } } -#[test] -fn backup() -> Result<()> { +#[rstest] +fn test_backup_with_dir_passes(dir_testdata: Result) -> Result<()> { + // uncomment for logging output + // SimpleLogger::init(log::LevelFilter::Debug, Config::default())?; + let source = dir_testdata?; + let paths = &source.path_list(); + + let repo = set_up_repo()?.to_indexed_ids()?; + // we use as_path to not depend on the actual tempdir + let opts = BackupOptions::default().as_path(PathBuf::from_str("test")?); + + // first backup + let first_backup = repo.backup(&opts, paths, SnapshotFile::default())?; + assert_debug_snapshot!(TestSummary(&first_backup)); + assert_eq!(first_backup.parent, None); + + // get all snapshots and check them + let all_snapshots = repo.get_all_snapshots()?; + assert_eq!(vec![first_backup.clone()], all_snapshots); + // save list of pack files + let packs1: Vec<_> = repo.list(rustic_core::FileType::Pack)?.collect(); + + // re-read index + let repo = repo.to_indexed_ids()?; + // second backup + let snap2 = repo.backup(&opts, paths, SnapshotFile::default())?; + assert_debug_snapshot!(TestSummary(&snap2)); + assert_eq!(snap2.parent, Some(first_backup.id)); + assert_eq!(first_backup.tree, snap2.tree); + + // get all snapshots and check them + let mut all_snapshots = repo.get_all_snapshots()?; + all_snapshots.sort_unstable(); + assert_eq!(vec![first_backup, snap2], all_snapshots); + + // pack files should be unchanged + let packs2: Vec<_> = repo.list(rustic_core::FileType::Pack)?.collect(); + assert_eq!(packs1, packs2); + Ok(()) +} + +#[rstest] +fn test_backup_with_tar_gz_passes(tar_gz_testdata: Result) -> Result<()> { // uncomment for logging output // SimpleLogger::init(log::LevelFilter::Debug, Config::default())?; - let source = set_up_testdata("backup-data.tar.gz")?; - let paths = &source.paths(); + let source = tar_gz_testdata?; + let paths = &source.path_list(); let repo = set_up_repo()?.to_indexed_ids()?; // we use as_path to not depend on the actual tempdir @@ -126,10 +175,10 @@ fn backup() -> Result<()> { Ok(()) } -#[test] -fn backup_dry_run() -> Result<()> { - let source = &set_up_testdata("backup-data.tar.gz")?; - let paths = &source.paths(); +#[rstest] +fn test_backup_dry_run_with_tar_gz_passes(tar_gz_testdata: Result) -> Result<()> { + let source = tar_gz_testdata?; + let paths = &source.path_list(); let repo = set_up_repo()?.to_indexed_ids()?; // we use as_path to not depend on the actual tempdir let opts = BackupOptions::default() diff --git a/crates/core/tests/snapshots/integration__backup-2.snap b/crates/core/tests/snapshots/integration__backup-2.snap deleted file mode 100644 index 52a022e2..00000000 --- a/crates/core/tests/snapshots/integration__backup-2.snap +++ /dev/null @@ -1,29 +0,0 @@ ---- -source: crates/core/tests/integration.rs -expression: TestSummary(&snap2) ---- -TestSnap { - hostname: "", - paths: StringList( - [ - "test", - ], - ), - label: "", - tags: StringList( - [], - ), - files_new: 0, - files_changed: 0, - files_unmodified: 73, - total_files_processed: 73, - total_bytes_processed: 1125682, - dirs_new: 0, - dirs_changed: 0, - dirs_unmodified: 6, - total_dirs_processed: 6, - data_blobs: 0, - tree_blobs: 0, - data_added_files: 0, - data_added_files_packed: 0, -} diff --git a/crates/core/tests/snapshots/integration__backup.snap b/crates/core/tests/snapshots/integration__backup.snap deleted file mode 100644 index 209647bb..00000000 --- a/crates/core/tests/snapshots/integration__backup.snap +++ /dev/null @@ -1,29 +0,0 @@ ---- -source: crates/core/tests/integration.rs -expression: TestSummary(&snap1) ---- -TestSnap { - hostname: "", - paths: StringList( - [ - "test", - ], - ), - label: "", - tags: StringList( - [], - ), - files_new: 73, - files_changed: 0, - files_unmodified: 0, - total_files_processed: 73, - total_bytes_processed: 1125674, - dirs_new: 6, - dirs_changed: 0, - dirs_unmodified: 0, - total_dirs_processed: 6, - data_blobs: 70, - tree_blobs: 6, - data_added_files: 1125653, - data_added_files_packed: 78740, -} diff --git a/crates/core/tests/snapshots/integration__backup_dry_run-2.snap b/crates/core/tests/snapshots/integration__backup_dry_run-2.snap deleted file mode 100644 index 632d04ee..00000000 --- a/crates/core/tests/snapshots/integration__backup_dry_run-2.snap +++ /dev/null @@ -1,29 +0,0 @@ ---- -source: crates/core/tests/integration.rs -expression: TestSummary(&snap_dry_run) ---- -TestSnap { - hostname: "", - paths: StringList( - [ - "test", - ], - ), - label: "", - tags: StringList( - [], - ), - files_new: 0, - files_changed: 0, - files_unmodified: 73, - total_files_processed: 73, - total_bytes_processed: 1125682, - dirs_new: 0, - dirs_changed: 0, - dirs_unmodified: 6, - total_dirs_processed: 6, - data_blobs: 0, - tree_blobs: 0, - data_added_files: 0, - data_added_files_packed: 0, -} diff --git a/crates/core/tests/snapshots/integration__backup_dry_run.snap b/crates/core/tests/snapshots/integration__backup_dry_run.snap deleted file mode 100644 index 5663f447..00000000 --- a/crates/core/tests/snapshots/integration__backup_dry_run.snap +++ /dev/null @@ -1,29 +0,0 @@ ---- -source: crates/core/tests/integration.rs -expression: TestSummary(&snap_dry_run) ---- -TestSnap { - hostname: "", - paths: StringList( - [ - "test", - ], - ), - label: "", - tags: StringList( - [], - ), - files_new: 73, - files_changed: 0, - files_unmodified: 0, - total_files_processed: 73, - total_bytes_processed: 1125674, - dirs_new: 6, - dirs_changed: 0, - dirs_unmodified: 0, - total_dirs_processed: 6, - data_blobs: 70, - tree_blobs: 6, - data_added_files: 1125653, - data_added_files_packed: 78740, -} From db56e15efa7af524aadf8bd7fdb3b63b5cfa1b73 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Tue, 12 Mar 2024 17:40:13 +0100 Subject: [PATCH 08/46] push base snapshots ci updates Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/core/tests/integration.rs | 12 ++++---- ...ckup_dry_run_with_tar_gz_passes-2.snap.new | 30 +++++++++++++++++++ ...backup_dry_run_with_tar_gz_passes.snap.new | 30 +++++++++++++++++++ ...gration__backup_with_dir_passes-2.snap.new | 30 +++++++++++++++++++ .../integration__backup_with_dir_passes.snap | 29 ++++++++++++++++++ ...tion__backup_with_tar_gz_passes-2.snap.new | 30 +++++++++++++++++++ ...ration__backup_with_tar_gz_passes.snap.new | 30 +++++++++++++++++++ 7 files changed, 185 insertions(+), 6 deletions(-) create mode 100644 crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes-2.snap.new create mode 100644 crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes.snap.new create mode 100644 crates/core/tests/snapshots/integration__backup_with_dir_passes-2.snap.new create mode 100644 crates/core/tests/snapshots/integration__backup_with_dir_passes.snap create mode 100644 crates/core/tests/snapshots/integration__backup_with_tar_gz_passes-2.snap.new create mode 100644 crates/core/tests/snapshots/integration__backup_with_tar_gz_passes.snap.new diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index 5c12536a..6c768d7a 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -16,7 +16,7 @@ use std::{ sync::Arc, }; // uncomment for logging output -// use simplelog::{Config, SimpleLogger}; +use simplelog::{Config, SimpleLogger}; use tar::Archive; use tempfile::tempdir; @@ -57,9 +57,9 @@ fn tar_gz_testdata() -> Result { } #[fixture] -fn dir_testdata() -> Result { +fn dir_testdata() -> TestSource { let path = Path::new("tests/fixtures/backup-data/"); - Ok(TestSource::new(path)) + TestSource::new(path) } // Parts of the snapshot summary we want to test against references @@ -94,10 +94,10 @@ impl<'a> std::fmt::Debug for TestSummary<'a> { } #[rstest] -fn test_backup_with_dir_passes(dir_testdata: Result) -> Result<()> { +fn test_backup_with_dir_passes(dir_testdata: TestSource) -> Result<()> { // uncomment for logging output - // SimpleLogger::init(log::LevelFilter::Debug, Config::default())?; - let source = dir_testdata?; + SimpleLogger::init(log::LevelFilter::Debug, Config::default())?; + let source = dir_testdata; let paths = &source.path_list(); let repo = set_up_repo()?.to_indexed_ids()?; diff --git a/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes-2.snap.new b/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes-2.snap.new new file mode 100644 index 00000000..9930b527 --- /dev/null +++ b/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes-2.snap.new @@ -0,0 +1,30 @@ +--- +source: crates/core/tests/integration.rs +assertion_line: 208 +expression: TestSummary(&snap_dry_run) +--- +TestSnap { + hostname: "", + paths: StringList( + [ + "test", + ], + ), + label: "", + tags: StringList( + [], + ), + files_new: 0, + files_changed: 0, + files_unmodified: 0, + total_files_processed: 0, + total_bytes_processed: 0, + dirs_new: 0, + dirs_changed: 0, + dirs_unmodified: 1, + total_dirs_processed: 1, + data_blobs: 0, + tree_blobs: 0, + data_added_files: 0, + data_added_files_packed: 0, +} diff --git a/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes.snap.new b/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes.snap.new new file mode 100644 index 00000000..d4332951 --- /dev/null +++ b/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes.snap.new @@ -0,0 +1,30 @@ +--- +source: crates/core/tests/integration.rs +assertion_line: 190 +expression: TestSummary(&snap_dry_run) +--- +TestSnap { + hostname: "", + paths: StringList( + [ + "test", + ], + ), + label: "", + tags: StringList( + [], + ), + files_new: 0, + files_changed: 0, + files_unmodified: 0, + total_files_processed: 0, + total_bytes_processed: 0, + dirs_new: 1, + dirs_changed: 0, + dirs_unmodified: 0, + total_dirs_processed: 1, + data_blobs: 0, + tree_blobs: 1, + data_added_files: 0, + data_added_files_packed: 0, +} diff --git a/crates/core/tests/snapshots/integration__backup_with_dir_passes-2.snap.new b/crates/core/tests/snapshots/integration__backup_with_dir_passes-2.snap.new new file mode 100644 index 00000000..f55d9277 --- /dev/null +++ b/crates/core/tests/snapshots/integration__backup_with_dir_passes-2.snap.new @@ -0,0 +1,30 @@ +--- +source: crates/core/tests/integration.rs +assertion_line: 122 +expression: TestSummary(&snap2) +--- +TestSnap { + hostname: "", + paths: StringList( + [ + "test", + ], + ), + label: "", + tags: StringList( + [], + ), + files_new: 0, + files_changed: 0, + files_unmodified: 73, + total_files_processed: 73, + total_bytes_processed: 1125674, + dirs_new: 0, + dirs_changed: 0, + dirs_unmodified: 5, + total_dirs_processed: 5, + data_blobs: 0, + tree_blobs: 0, + data_added_files: 0, + data_added_files_packed: 0, +} diff --git a/crates/core/tests/snapshots/integration__backup_with_dir_passes.snap b/crates/core/tests/snapshots/integration__backup_with_dir_passes.snap new file mode 100644 index 00000000..baf201e1 --- /dev/null +++ b/crates/core/tests/snapshots/integration__backup_with_dir_passes.snap @@ -0,0 +1,29 @@ +--- +source: crates/core/tests/integration.rs +expression: TestSummary(&first_backup) +--- +TestSnap { + hostname: "", + paths: StringList( + [ + "test", + ], + ), + label: "", + tags: StringList( + [], + ), + files_new: 73, + files_changed: 0, + files_unmodified: 0, + total_files_processed: 73, + total_bytes_processed: 1125674, + dirs_new: 5, + dirs_changed: 0, + dirs_unmodified: 0, + total_dirs_processed: 5, + data_blobs: 70, + tree_blobs: 5, + data_added_files: 1125653, + data_added_files_packed: 78740, +} diff --git a/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes-2.snap.new b/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes-2.snap.new new file mode 100644 index 00000000..ca8ebded --- /dev/null +++ b/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes-2.snap.new @@ -0,0 +1,30 @@ +--- +source: crates/core/tests/integration.rs +assertion_line: 163 +expression: TestSummary(&snap2) +--- +TestSnap { + hostname: "", + paths: StringList( + [ + "test", + ], + ), + label: "", + tags: StringList( + [], + ), + files_new: 0, + files_changed: 0, + files_unmodified: 0, + total_files_processed: 0, + total_bytes_processed: 0, + dirs_new: 0, + dirs_changed: 0, + dirs_unmodified: 1, + total_dirs_processed: 1, + data_blobs: 0, + tree_blobs: 0, + data_added_files: 0, + data_added_files_packed: 0, +} diff --git a/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes.snap.new b/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes.snap.new new file mode 100644 index 00000000..ab836c27 --- /dev/null +++ b/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes.snap.new @@ -0,0 +1,30 @@ +--- +source: crates/core/tests/integration.rs +assertion_line: 150 +expression: TestSummary(&first_backup) +--- +TestSnap { + hostname: "", + paths: StringList( + [ + "test", + ], + ), + label: "", + tags: StringList( + [], + ), + files_new: 0, + files_changed: 0, + files_unmodified: 0, + total_files_processed: 0, + total_bytes_processed: 0, + dirs_new: 1, + dirs_changed: 0, + dirs_unmodified: 0, + total_dirs_processed: 1, + data_blobs: 0, + tree_blobs: 1, + data_added_files: 0, + data_added_files_packed: 0, +} From 5cde10509cd3d82083afcf21813e03184d8f1665 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Tue, 12 Mar 2024 19:39:49 +0100 Subject: [PATCH 09/46] update snapshots Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/core/tests/integration.rs | 10 ++++--- ..._backup_dry_run_with_tar_gz_passes-2.snap} | 1 - ...n__backup_dry_run_with_tar_gz_passes.snap} | 1 - ...integration__backup_with_dir_passes-2.snap | 29 +++++++++++++++++++ ...gration__backup_with_dir_passes-2.snap.new | 2 +- ...gration__backup_with_tar_gz_passes-2.snap} | 1 - ...tegration__backup_with_tar_gz_passes.snap} | 1 - 7 files changed, 36 insertions(+), 9 deletions(-) rename crates/core/tests/snapshots/{integration__backup_dry_run_with_tar_gz_passes-2.snap.new => integration__backup_dry_run_with_tar_gz_passes-2.snap} (96%) rename crates/core/tests/snapshots/{integration__backup_dry_run_with_tar_gz_passes.snap.new => integration__backup_dry_run_with_tar_gz_passes.snap} (96%) create mode 100644 crates/core/tests/snapshots/integration__backup_with_dir_passes-2.snap rename crates/core/tests/snapshots/{integration__backup_with_tar_gz_passes-2.snap.new => integration__backup_with_tar_gz_passes-2.snap} (96%) rename crates/core/tests/snapshots/{integration__backup_with_tar_gz_passes.snap.new => integration__backup_with_tar_gz_passes.snap} (96%) diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index 6c768d7a..4596a944 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -46,7 +46,7 @@ impl TestSource { #[fixture] fn tar_gz_testdata() -> Result { let dir = tempdir()?; - let path = Path::new("tests/fixtures/backup-data.tar.gz"); + let path = Path::new("tests/fixtures/backup-data.tar.gz").canonicalize()?; let tar_gz = File::open(path)?; let tar = GzDecoder::new(tar_gz); let mut archive = Archive::new(tar); @@ -58,7 +58,9 @@ fn tar_gz_testdata() -> Result { #[fixture] fn dir_testdata() -> TestSource { - let path = Path::new("tests/fixtures/backup-data/"); + let path = Path::new("tests/fixtures/backup-data/") + .canonicalize() + .expect("fixture path"); TestSource::new(path) } @@ -96,7 +98,7 @@ impl<'a> std::fmt::Debug for TestSummary<'a> { #[rstest] fn test_backup_with_dir_passes(dir_testdata: TestSource) -> Result<()> { // uncomment for logging output - SimpleLogger::init(log::LevelFilter::Debug, Config::default())?; + // SimpleLogger::init(log::LevelFilter::Debug, Config::default())?; let source = dir_testdata; let paths = &source.path_list(); @@ -137,7 +139,7 @@ fn test_backup_with_dir_passes(dir_testdata: TestSource) -> Result<()> { #[rstest] fn test_backup_with_tar_gz_passes(tar_gz_testdata: Result) -> Result<()> { // uncomment for logging output - // SimpleLogger::init(log::LevelFilter::Debug, Config::default())?; + SimpleLogger::init(log::LevelFilter::Debug, Config::default())?; let source = tar_gz_testdata?; let paths = &source.path_list(); diff --git a/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes-2.snap.new b/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes-2.snap similarity index 96% rename from crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes-2.snap.new rename to crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes-2.snap index 9930b527..ca4054ce 100644 --- a/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes-2.snap.new +++ b/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes-2.snap @@ -1,6 +1,5 @@ --- source: crates/core/tests/integration.rs -assertion_line: 208 expression: TestSummary(&snap_dry_run) --- TestSnap { diff --git a/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes.snap.new b/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes.snap similarity index 96% rename from crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes.snap.new rename to crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes.snap index d4332951..7e69e0e7 100644 --- a/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes.snap.new +++ b/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes.snap @@ -1,6 +1,5 @@ --- source: crates/core/tests/integration.rs -assertion_line: 190 expression: TestSummary(&snap_dry_run) --- TestSnap { diff --git a/crates/core/tests/snapshots/integration__backup_with_dir_passes-2.snap b/crates/core/tests/snapshots/integration__backup_with_dir_passes-2.snap new file mode 100644 index 00000000..7eb5a086 --- /dev/null +++ b/crates/core/tests/snapshots/integration__backup_with_dir_passes-2.snap @@ -0,0 +1,29 @@ +--- +source: crates/core/tests/integration.rs +expression: TestSummary(&snap2) +--- +TestSnap { + hostname: "", + paths: StringList( + [ + "test", + ], + ), + label: "", + tags: StringList( + [], + ), + files_new: 0, + files_changed: 0, + files_unmodified: 73, + total_files_processed: 73, + total_bytes_processed: 1125682, + dirs_new: 0, + dirs_changed: 0, + dirs_unmodified: 5, + total_dirs_processed: 5, + data_blobs: 0, + tree_blobs: 0, + data_added_files: 0, + data_added_files_packed: 0, +} diff --git a/crates/core/tests/snapshots/integration__backup_with_dir_passes-2.snap.new b/crates/core/tests/snapshots/integration__backup_with_dir_passes-2.snap.new index f55d9277..f51f4dd1 100644 --- a/crates/core/tests/snapshots/integration__backup_with_dir_passes-2.snap.new +++ b/crates/core/tests/snapshots/integration__backup_with_dir_passes-2.snap.new @@ -1,6 +1,6 @@ --- source: crates/core/tests/integration.rs -assertion_line: 122 +assertion_line: 124 expression: TestSummary(&snap2) --- TestSnap { diff --git a/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes-2.snap.new b/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes-2.snap similarity index 96% rename from crates/core/tests/snapshots/integration__backup_with_tar_gz_passes-2.snap.new rename to crates/core/tests/snapshots/integration__backup_with_tar_gz_passes-2.snap index ca8ebded..ae654b59 100644 --- a/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes-2.snap.new +++ b/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes-2.snap @@ -1,6 +1,5 @@ --- source: crates/core/tests/integration.rs -assertion_line: 163 expression: TestSummary(&snap2) --- TestSnap { diff --git a/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes.snap.new b/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes.snap similarity index 96% rename from crates/core/tests/snapshots/integration__backup_with_tar_gz_passes.snap.new rename to crates/core/tests/snapshots/integration__backup_with_tar_gz_passes.snap index ab836c27..2ba2b256 100644 --- a/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes.snap.new +++ b/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes.snap @@ -1,6 +1,5 @@ --- source: crates/core/tests/integration.rs -assertion_line: 150 expression: TestSummary(&first_backup) --- TestSnap { From 7fbd7d43ed97cfdcfe73e22726efa1d2b842fce8 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Tue, 12 Mar 2024 19:51:16 +0100 Subject: [PATCH 10/46] update snapshots Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/core/tests/integration.rs | 20 ++++++------- ...gration__backup_with_dir_passes-2.snap.new | 30 ------------------- 2 files changed, 10 insertions(+), 40 deletions(-) delete mode 100644 crates/core/tests/snapshots/integration__backup_with_dir_passes-2.snap.new diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index 4596a944..d1bbdbbf 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -120,15 +120,15 @@ fn test_backup_with_dir_passes(dir_testdata: TestSource) -> Result<()> { // re-read index let repo = repo.to_indexed_ids()?; // second backup - let snap2 = repo.backup(&opts, paths, SnapshotFile::default())?; - assert_debug_snapshot!(TestSummary(&snap2)); - assert_eq!(snap2.parent, Some(first_backup.id)); - assert_eq!(first_backup.tree, snap2.tree); + let second_snapshot = repo.backup(&opts, paths, SnapshotFile::default())?; + assert_debug_snapshot!(TestSummary(&second_snapshot)); + assert_eq!(second_snapshot.parent, Some(first_backup.id)); + assert_eq!(first_backup.tree, second_snapshot.tree); // get all snapshots and check them let mut all_snapshots = repo.get_all_snapshots()?; all_snapshots.sort_unstable(); - assert_eq!(vec![first_backup, snap2], all_snapshots); + assert_eq!(vec![first_backup, second_snapshot], all_snapshots); // pack files should be unchanged let packs2: Vec<_> = repo.list(rustic_core::FileType::Pack)?.collect(); @@ -161,15 +161,15 @@ fn test_backup_with_tar_gz_passes(tar_gz_testdata: Result) -> Result // re-read index let repo = repo.to_indexed_ids()?; // second backup - let snap2 = repo.backup(&opts, paths, SnapshotFile::default())?; - assert_debug_snapshot!(TestSummary(&snap2)); - assert_eq!(snap2.parent, Some(first_backup.id)); - assert_eq!(first_backup.tree, snap2.tree); + let second_snapshot = repo.backup(&opts, paths, SnapshotFile::default())?; + assert_debug_snapshot!(TestSummary(&second_snapshot)); + assert_eq!(second_snapshot.parent, Some(first_backup.id)); + assert_eq!(first_backup.tree, second_snapshot.tree); // get all snapshots and check them let mut all_snapshots = repo.get_all_snapshots()?; all_snapshots.sort_unstable(); - assert_eq!(vec![first_backup, snap2], all_snapshots); + assert_eq!(vec![first_backup, second_snapshot], all_snapshots); // pack files should be unchanged let packs2: Vec<_> = repo.list(rustic_core::FileType::Pack)?.collect(); diff --git a/crates/core/tests/snapshots/integration__backup_with_dir_passes-2.snap.new b/crates/core/tests/snapshots/integration__backup_with_dir_passes-2.snap.new deleted file mode 100644 index f51f4dd1..00000000 --- a/crates/core/tests/snapshots/integration__backup_with_dir_passes-2.snap.new +++ /dev/null @@ -1,30 +0,0 @@ ---- -source: crates/core/tests/integration.rs -assertion_line: 124 -expression: TestSummary(&snap2) ---- -TestSnap { - hostname: "", - paths: StringList( - [ - "test", - ], - ), - label: "", - tags: StringList( - [], - ), - files_new: 0, - files_changed: 0, - files_unmodified: 73, - total_files_processed: 73, - total_bytes_processed: 1125674, - dirs_new: 0, - dirs_changed: 0, - dirs_unmodified: 5, - total_dirs_processed: 5, - data_blobs: 0, - tree_blobs: 0, - data_added_files: 0, - data_added_files_packed: 0, -} From 416cfd1b37f93d82ab86daba629a8258bafbcb2c Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Tue, 12 Mar 2024 20:16:32 +0100 Subject: [PATCH 11/46] fix tempdir Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/core/tests/integration.rs | 32 +++++++++++-------- ...backup_dry_run_with_tar_gz_passes.snap.new | 30 +++++++++++++++++ ...gration__backup_with_dir_passes-2.snap.new | 30 +++++++++++++++++ ...ration__backup_with_tar_gz_passes.snap.new | 30 +++++++++++++++++ 4 files changed, 108 insertions(+), 14 deletions(-) create mode 100644 crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes.snap.new create mode 100644 crates/core/tests/snapshots/integration__backup_with_dir_passes-2.snap.new create mode 100644 crates/core/tests/snapshots/integration__backup_with_tar_gz_passes.snap.new diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index d1bbdbbf..6c59e387 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -8,6 +8,7 @@ use rustic_core::{ repofile::SnapshotFile, BackupOptions, ConfigOptions, InMemoryBackend, KeyOptions, NoProgressBars, OpenStatus, PathList, Repository, RepositoryBackends, RepositoryOptions, }; + use std::{ env, fs::File, @@ -18,7 +19,7 @@ use std::{ // uncomment for logging output use simplelog::{Config, SimpleLogger}; use tar::Archive; -use tempfile::tempdir; +use tempfile::{tempdir, TempDir}; fn set_up_repo() -> Result> { let be = InMemoryBackend::new(); @@ -31,15 +32,16 @@ fn set_up_repo() -> Result> { Ok(repo) } -struct TestSource(PathBuf); +#[derive(Debug)] +struct TestSource(TempDir); impl TestSource { - fn new(tmp: impl Into) -> Self { - Self(tmp.into()) + fn new(tmp: TempDir) -> Self { + Self(tmp) } fn path_list(&self) -> PathList { - PathList::from_iter(Some(self.0.clone())) + PathList::from_iter(Some(self.0.path().to_path_buf())) } } @@ -53,15 +55,14 @@ fn tar_gz_testdata() -> Result { archive.set_preserve_permissions(true); archive.set_preserve_mtime(true); archive.unpack(&dir)?; - Ok(TestSource::new(dir.as_ref())) + Ok(TestSource::new(dir)) } #[fixture] -fn dir_testdata() -> TestSource { - let path = Path::new("tests/fixtures/backup-data/") +fn dir_testdata() -> PathBuf { + Path::new("tests/fixtures/backup-data/") .canonicalize() - .expect("fixture path"); - TestSource::new(path) + .expect("fixture path") } // Parts of the snapshot summary we want to test against references @@ -96,18 +97,18 @@ impl<'a> std::fmt::Debug for TestSummary<'a> { } #[rstest] -fn test_backup_with_dir_passes(dir_testdata: TestSource) -> Result<()> { +fn test_backup_with_dir_passes(dir_testdata: PathBuf) -> Result<()> { // uncomment for logging output // SimpleLogger::init(log::LevelFilter::Debug, Config::default())?; let source = dir_testdata; - let paths = &source.path_list(); + let paths = PathList::from_iter(Some(source.clone())); let repo = set_up_repo()?.to_indexed_ids()?; // we use as_path to not depend on the actual tempdir let opts = BackupOptions::default().as_path(PathBuf::from_str("test")?); // first backup - let first_backup = repo.backup(&opts, paths, SnapshotFile::default())?; + let first_backup = repo.backup(&opts, &paths, SnapshotFile::default())?; assert_debug_snapshot!(TestSummary(&first_backup)); assert_eq!(first_backup.parent, None); @@ -120,7 +121,7 @@ fn test_backup_with_dir_passes(dir_testdata: TestSource) -> Result<()> { // re-read index let repo = repo.to_indexed_ids()?; // second backup - let second_snapshot = repo.backup(&opts, paths, SnapshotFile::default())?; + let second_snapshot = repo.backup(&opts, &paths, SnapshotFile::default())?; assert_debug_snapshot!(TestSummary(&second_snapshot)); assert_eq!(second_snapshot.parent, Some(first_backup.id)); assert_eq!(first_backup.tree, second_snapshot.tree); @@ -141,6 +142,9 @@ fn test_backup_with_tar_gz_passes(tar_gz_testdata: Result) -> Result // uncomment for logging output SimpleLogger::init(log::LevelFilter::Debug, Config::default())?; let source = tar_gz_testdata?; + + dbg!(&source); + let paths = &source.path_list(); let repo = set_up_repo()?.to_indexed_ids()?; diff --git a/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes.snap.new b/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes.snap.new new file mode 100644 index 00000000..46029bbd --- /dev/null +++ b/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes.snap.new @@ -0,0 +1,30 @@ +--- +source: crates/core/tests/integration.rs +assertion_line: 196 +expression: TestSummary(&snap_dry_run) +--- +TestSnap { + hostname: "", + paths: StringList( + [ + "test", + ], + ), + label: "", + tags: StringList( + [], + ), + files_new: 73, + files_changed: 0, + files_unmodified: 0, + total_files_processed: 73, + total_bytes_processed: 1125674, + dirs_new: 6, + dirs_changed: 0, + dirs_unmodified: 0, + total_dirs_processed: 6, + data_blobs: 70, + tree_blobs: 6, + data_added_files: 1125653, + data_added_files_packed: 78740, +} diff --git a/crates/core/tests/snapshots/integration__backup_with_dir_passes-2.snap.new b/crates/core/tests/snapshots/integration__backup_with_dir_passes-2.snap.new new file mode 100644 index 00000000..b8b874a7 --- /dev/null +++ b/crates/core/tests/snapshots/integration__backup_with_dir_passes-2.snap.new @@ -0,0 +1,30 @@ +--- +source: crates/core/tests/integration.rs +assertion_line: 125 +expression: TestSummary(&second_snapshot) +--- +TestSnap { + hostname: "", + paths: StringList( + [ + "test", + ], + ), + label: "", + tags: StringList( + [], + ), + files_new: 0, + files_changed: 0, + files_unmodified: 73, + total_files_processed: 73, + total_bytes_processed: 1125674, + dirs_new: 0, + dirs_changed: 0, + dirs_unmodified: 5, + total_dirs_processed: 5, + data_blobs: 0, + tree_blobs: 0, + data_added_files: 0, + data_added_files_packed: 0, +} diff --git a/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes.snap.new b/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes.snap.new new file mode 100644 index 00000000..a8d69189 --- /dev/null +++ b/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes.snap.new @@ -0,0 +1,30 @@ +--- +source: crates/core/tests/integration.rs +assertion_line: 156 +expression: TestSummary(&first_backup) +--- +TestSnap { + hostname: "", + paths: StringList( + [ + "test", + ], + ), + label: "", + tags: StringList( + [], + ), + files_new: 73, + files_changed: 0, + files_unmodified: 0, + total_files_processed: 73, + total_bytes_processed: 1125674, + dirs_new: 6, + dirs_changed: 0, + dirs_unmodified: 0, + total_dirs_processed: 6, + data_blobs: 70, + tree_blobs: 6, + data_added_files: 1125653, + data_added_files_packed: 78740, +} From b93ef46e8d40769833c51ece20ea55f4fded2ff8 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Tue, 12 Mar 2024 20:28:02 +0100 Subject: [PATCH 12/46] update snapshots Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/core/tests/integration.rs | 36 ++++++++++++------- ...__backup_dry_run_with_tar_gz_passes-2.snap | 10 +++--- ...on__backup_dry_run_with_tar_gz_passes.snap | 18 +++++----- ...backup_dry_run_with_tar_gz_passes.snap.new | 30 ---------------- ...gration__backup_with_dir_passes-2.snap.new | 30 ---------------- ...egration__backup_with_tar_gz_passes-2.snap | 12 +++---- ...ntegration__backup_with_tar_gz_passes.snap | 18 +++++----- ...ration__backup_with_tar_gz_passes.snap.new | 30 ---------------- 8 files changed, 53 insertions(+), 131 deletions(-) delete mode 100644 crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes.snap.new delete mode 100644 crates/core/tests/snapshots/integration__backup_with_dir_passes-2.snap.new delete mode 100644 crates/core/tests/snapshots/integration__backup_with_tar_gz_passes.snap.new diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index 6c59e387..d3d6ebd4 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -21,7 +21,10 @@ use simplelog::{Config, SimpleLogger}; use tar::Archive; use tempfile::{tempdir, TempDir}; -fn set_up_repo() -> Result> { +type RepoOpen = Repository; + +#[fixture] +fn set_up_repo() -> Result { let be = InMemoryBackend::new(); let be = RepositoryBackends::new(Arc::new(be), None); let options = RepositoryOptions::default().password("test"); @@ -97,13 +100,15 @@ impl<'a> std::fmt::Debug for TestSummary<'a> { } #[rstest] -fn test_backup_with_dir_passes(dir_testdata: PathBuf) -> Result<()> { +fn test_backup_with_dir_passes(dir_testdata: PathBuf, set_up_repo: Result) -> Result<()> { // uncomment for logging output // SimpleLogger::init(log::LevelFilter::Debug, Config::default())?; - let source = dir_testdata; + + // Fixtures + let (source, repo) = (dir_testdata, set_up_repo?.to_indexed_ids()?); + let paths = PathList::from_iter(Some(source.clone())); - let repo = set_up_repo()?.to_indexed_ids()?; // we use as_path to not depend on the actual tempdir let opts = BackupOptions::default().as_path(PathBuf::from_str("test")?); @@ -138,16 +143,18 @@ fn test_backup_with_dir_passes(dir_testdata: PathBuf) -> Result<()> { } #[rstest] -fn test_backup_with_tar_gz_passes(tar_gz_testdata: Result) -> Result<()> { +fn test_backup_with_tar_gz_passes( + tar_gz_testdata: Result, + set_up_repo: Result, +) -> Result<()> { // uncomment for logging output - SimpleLogger::init(log::LevelFilter::Debug, Config::default())?; - let source = tar_gz_testdata?; + // SimpleLogger::init(log::LevelFilter::Debug, Config::default())?; - dbg!(&source); + // Fixtures + let (source, repo) = (tar_gz_testdata?, set_up_repo?.to_indexed_ids()?); let paths = &source.path_list(); - let repo = set_up_repo()?.to_indexed_ids()?; // we use as_path to not depend on the actual tempdir let opts = BackupOptions::default().as_path(PathBuf::from_str("test")?); @@ -182,10 +189,15 @@ fn test_backup_with_tar_gz_passes(tar_gz_testdata: Result) -> Result } #[rstest] -fn test_backup_dry_run_with_tar_gz_passes(tar_gz_testdata: Result) -> Result<()> { - let source = tar_gz_testdata?; +fn test_backup_dry_run_with_tar_gz_passes( + tar_gz_testdata: Result, + set_up_repo: Result, +) -> Result<()> { + // Fixtures + let (source, repo) = (tar_gz_testdata?, set_up_repo?.to_indexed_ids()?); + let paths = &source.path_list(); - let repo = set_up_repo()?.to_indexed_ids()?; + // we use as_path to not depend on the actual tempdir let opts = BackupOptions::default() .as_path(PathBuf::from_str("test")?) diff --git a/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes-2.snap b/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes-2.snap index ca4054ce..ba72d6a9 100644 --- a/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes-2.snap +++ b/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes-2.snap @@ -15,13 +15,13 @@ TestSnap { ), files_new: 0, files_changed: 0, - files_unmodified: 0, - total_files_processed: 0, - total_bytes_processed: 0, + files_unmodified: 73, + total_files_processed: 73, + total_bytes_processed: 1125674, dirs_new: 0, dirs_changed: 0, - dirs_unmodified: 1, - total_dirs_processed: 1, + dirs_unmodified: 6, + total_dirs_processed: 6, data_blobs: 0, tree_blobs: 0, data_added_files: 0, diff --git a/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes.snap b/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes.snap index 7e69e0e7..5663f447 100644 --- a/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes.snap +++ b/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes.snap @@ -13,17 +13,17 @@ TestSnap { tags: StringList( [], ), - files_new: 0, + files_new: 73, files_changed: 0, files_unmodified: 0, - total_files_processed: 0, - total_bytes_processed: 0, - dirs_new: 1, + total_files_processed: 73, + total_bytes_processed: 1125674, + dirs_new: 6, dirs_changed: 0, dirs_unmodified: 0, - total_dirs_processed: 1, - data_blobs: 0, - tree_blobs: 1, - data_added_files: 0, - data_added_files_packed: 0, + total_dirs_processed: 6, + data_blobs: 70, + tree_blobs: 6, + data_added_files: 1125653, + data_added_files_packed: 78740, } diff --git a/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes.snap.new b/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes.snap.new deleted file mode 100644 index 46029bbd..00000000 --- a/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes.snap.new +++ /dev/null @@ -1,30 +0,0 @@ ---- -source: crates/core/tests/integration.rs -assertion_line: 196 -expression: TestSummary(&snap_dry_run) ---- -TestSnap { - hostname: "", - paths: StringList( - [ - "test", - ], - ), - label: "", - tags: StringList( - [], - ), - files_new: 73, - files_changed: 0, - files_unmodified: 0, - total_files_processed: 73, - total_bytes_processed: 1125674, - dirs_new: 6, - dirs_changed: 0, - dirs_unmodified: 0, - total_dirs_processed: 6, - data_blobs: 70, - tree_blobs: 6, - data_added_files: 1125653, - data_added_files_packed: 78740, -} diff --git a/crates/core/tests/snapshots/integration__backup_with_dir_passes-2.snap.new b/crates/core/tests/snapshots/integration__backup_with_dir_passes-2.snap.new deleted file mode 100644 index b8b874a7..00000000 --- a/crates/core/tests/snapshots/integration__backup_with_dir_passes-2.snap.new +++ /dev/null @@ -1,30 +0,0 @@ ---- -source: crates/core/tests/integration.rs -assertion_line: 125 -expression: TestSummary(&second_snapshot) ---- -TestSnap { - hostname: "", - paths: StringList( - [ - "test", - ], - ), - label: "", - tags: StringList( - [], - ), - files_new: 0, - files_changed: 0, - files_unmodified: 73, - total_files_processed: 73, - total_bytes_processed: 1125674, - dirs_new: 0, - dirs_changed: 0, - dirs_unmodified: 5, - total_dirs_processed: 5, - data_blobs: 0, - tree_blobs: 0, - data_added_files: 0, - data_added_files_packed: 0, -} diff --git a/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes-2.snap b/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes-2.snap index ae654b59..4d76ed94 100644 --- a/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes-2.snap +++ b/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes-2.snap @@ -1,6 +1,6 @@ --- source: crates/core/tests/integration.rs -expression: TestSummary(&snap2) +expression: TestSummary(&second_snapshot) --- TestSnap { hostname: "", @@ -15,13 +15,13 @@ TestSnap { ), files_new: 0, files_changed: 0, - files_unmodified: 0, - total_files_processed: 0, - total_bytes_processed: 0, + files_unmodified: 73, + total_files_processed: 73, + total_bytes_processed: 1125674, dirs_new: 0, dirs_changed: 0, - dirs_unmodified: 1, - total_dirs_processed: 1, + dirs_unmodified: 6, + total_dirs_processed: 6, data_blobs: 0, tree_blobs: 0, data_added_files: 0, diff --git a/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes.snap b/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes.snap index 2ba2b256..4f80bc50 100644 --- a/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes.snap +++ b/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes.snap @@ -13,17 +13,17 @@ TestSnap { tags: StringList( [], ), - files_new: 0, + files_new: 73, files_changed: 0, files_unmodified: 0, - total_files_processed: 0, - total_bytes_processed: 0, - dirs_new: 1, + total_files_processed: 73, + total_bytes_processed: 1125674, + dirs_new: 6, dirs_changed: 0, dirs_unmodified: 0, - total_dirs_processed: 1, - data_blobs: 0, - tree_blobs: 1, - data_added_files: 0, - data_added_files_packed: 0, + total_dirs_processed: 6, + data_blobs: 70, + tree_blobs: 6, + data_added_files: 1125653, + data_added_files_packed: 78740, } diff --git a/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes.snap.new b/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes.snap.new deleted file mode 100644 index a8d69189..00000000 --- a/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes.snap.new +++ /dev/null @@ -1,30 +0,0 @@ ---- -source: crates/core/tests/integration.rs -assertion_line: 156 -expression: TestSummary(&first_backup) ---- -TestSnap { - hostname: "", - paths: StringList( - [ - "test", - ], - ), - label: "", - tags: StringList( - [], - ), - files_new: 73, - files_changed: 0, - files_unmodified: 0, - total_files_processed: 73, - total_bytes_processed: 1125674, - dirs_new: 6, - dirs_changed: 0, - dirs_unmodified: 0, - total_dirs_processed: 6, - data_blobs: 70, - tree_blobs: 6, - data_added_files: 1125653, - data_added_files_packed: 78740, -} From 0bdc082629206b21c882a929061807a0b657983e Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Tue, 12 Mar 2024 20:53:55 +0100 Subject: [PATCH 13/46] fix clippy Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/core/tests/integration.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index d3d6ebd4..59b589dc 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -17,7 +17,7 @@ use std::{ sync::Arc, }; // uncomment for logging output -use simplelog::{Config, SimpleLogger}; +// use simplelog::{Config, SimpleLogger}; use tar::Archive; use tempfile::{tempdir, TempDir}; @@ -107,7 +107,7 @@ fn test_backup_with_dir_passes(dir_testdata: PathBuf, set_up_repo: Result Date: Tue, 12 Mar 2024 21:25:56 +0100 Subject: [PATCH 14/46] new snapshots Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- .../integration__backup_dry_run_with_tar_gz_passes-2.snap | 2 +- .../snapshots/integration__backup_with_tar_gz_passes-2.snap | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes-2.snap b/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes-2.snap index ba72d6a9..632d04ee 100644 --- a/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes-2.snap +++ b/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes-2.snap @@ -17,7 +17,7 @@ TestSnap { files_changed: 0, files_unmodified: 73, total_files_processed: 73, - total_bytes_processed: 1125674, + total_bytes_processed: 1125682, dirs_new: 0, dirs_changed: 0, dirs_unmodified: 6, diff --git a/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes-2.snap b/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes-2.snap index 4d76ed94..7413b5d5 100644 --- a/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes-2.snap +++ b/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes-2.snap @@ -17,7 +17,7 @@ TestSnap { files_changed: 0, files_unmodified: 73, total_files_processed: 73, - total_bytes_processed: 1125674, + total_bytes_processed: 1125682, dirs_new: 0, dirs_changed: 0, dirs_unmodified: 6, From 4e2bddda709f9956d1fd31d31ff0adac3eecd231 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Tue, 12 Mar 2024 22:20:39 +0100 Subject: [PATCH 15/46] update snapshots Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/core/tests/integration.rs | 12 +++++++++--- .../integration__backup_with_dir_passes.snap | 6 +++--- .../integration__backup_with_tar_gz_passes-2.snap | 2 +- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index 59b589dc..4aec3400 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -17,7 +17,7 @@ use std::{ sync::Arc, }; // uncomment for logging output -// use simplelog::{Config, SimpleLogger}; +use simplelog::{Config, SimpleLogger}; use tar::Archive; use tempfile::{tempdir, TempDir}; @@ -102,12 +102,12 @@ impl<'a> std::fmt::Debug for TestSummary<'a> { #[rstest] fn test_backup_with_dir_passes(dir_testdata: PathBuf, set_up_repo: Result) -> Result<()> { // uncomment for logging output - // SimpleLogger::init(log::LevelFilter::Debug, Config::default())?; + SimpleLogger::init(log::LevelFilter::Debug, Config::default())?; // Fixtures let (source, repo) = (dir_testdata, set_up_repo?.to_indexed_ids()?); - let paths = PathList::from_iter(Some(source)); + let paths = PathList::from_iter(Some(source.clone())); // we use as_path to not depend on the actual tempdir let opts = BackupOptions::default().as_path(PathBuf::from_str("test")?); @@ -117,6 +117,12 @@ fn test_backup_with_dir_passes(dir_testdata: PathBuf, set_up_repo: Result Date: Tue, 12 Mar 2024 22:38:36 +0100 Subject: [PATCH 16/46] update Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/core/tests/integration.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index 4aec3400..9e24fa72 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -17,7 +17,7 @@ use std::{ sync::Arc, }; // uncomment for logging output -use simplelog::{Config, SimpleLogger}; +// use simplelog::{Config, SimpleLogger}; use tar::Archive; use tempfile::{tempdir, TempDir}; @@ -102,7 +102,7 @@ impl<'a> std::fmt::Debug for TestSummary<'a> { #[rstest] fn test_backup_with_dir_passes(dir_testdata: PathBuf, set_up_repo: Result) -> Result<()> { // uncomment for logging output - SimpleLogger::init(log::LevelFilter::Debug, Config::default())?; + // SimpleLogger::init(log::LevelFilter::Debug, Config::default())?; // Fixtures let (source, repo) = (dir_testdata, set_up_repo?.to_indexed_ids()?); @@ -120,7 +120,8 @@ fn test_backup_with_dir_passes(dir_testdata: PathBuf, set_up_repo: Result Date: Tue, 12 Mar 2024 22:43:51 +0100 Subject: [PATCH 17/46] fix clippy Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/core/tests/integration.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index 9e24fa72..5160acc8 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -107,7 +107,7 @@ fn test_backup_with_dir_passes(dir_testdata: PathBuf, set_up_repo: Result Date: Tue, 12 Mar 2024 23:10:16 +0100 Subject: [PATCH 18/46] init snapshots Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/core/tests/integration.rs | 127 ++++++++++++++--- ...on__backup-dir-summary-first-windows.snap} | 8 +- ...n__backup-dir-summary-second-windows.snap} | 4 +- .../integration__backup-dir-tree-windows.snap | 129 ++++++++++++++++++ ...on__backup-tar-summary-first-windows.snap} | 2 +- ...n__backup-tar-summary-second-windows.snap} | 0 ...on__dryrun-tar-summary-first-windows.snap} | 0 ...n__dryrun-tar-summary-second-windows.snap} | 2 +- 8 files changed, 244 insertions(+), 28 deletions(-) rename crates/core/tests/snapshots/{integration__backup_with_dir_passes.snap => integration__backup-dir-summary-first-windows.snap} (75%) rename crates/core/tests/snapshots/{integration__backup_with_dir_passes-2.snap => integration__backup-dir-summary-second-windows.snap} (86%) create mode 100644 crates/core/tests/snapshots/integration__backup-dir-tree-windows.snap rename crates/core/tests/snapshots/{integration__backup_with_tar_gz_passes.snap => integration__backup-tar-summary-first-windows.snap} (92%) rename crates/core/tests/snapshots/{integration__backup_with_tar_gz_passes-2.snap => integration__backup-tar-summary-second-windows.snap} (100%) rename crates/core/tests/snapshots/{integration__backup_dry_run_with_tar_gz_passes.snap => integration__dryrun-tar-summary-first-windows.snap} (100%) rename crates/core/tests/snapshots/{integration__backup_dry_run_with_tar_gz_passes-2.snap => integration__dryrun-tar-summary-second-windows.snap} (93%) diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index 5160acc8..60e34d07 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -113,20 +113,33 @@ fn test_backup_with_dir_passes(dir_testdata: PathBuf, set_up_repo: Result = repo.list(rustic_core::FileType::Pack)?.collect(); @@ -134,14 +147,26 @@ fn test_backup_with_dir_passes(dir_testdata: PathBuf, set_up_repo: Result = repo.list(rustic_core::FileType::Pack)?.collect(); @@ -166,13 +191,34 @@ fn test_backup_with_tar_gz_passes( let opts = BackupOptions::default().as_path(PathBuf::from_str("test")?); // first backup - let first_backup = repo.backup(&opts, paths, SnapshotFile::default())?; - assert_debug_snapshot!(TestSummary(&first_backup)); - assert_eq!(first_backup.parent, None); + let first_snapshot = repo.backup(&opts, paths, SnapshotFile::default())?; + + #[cfg(windows)] + assert_debug_snapshot!( + "backup-tar-summary-first-windows", + TestSummary(&first_snapshot) + ); + + #[cfg(not(windows))] + assert_debug_snapshot!("backup-tar-summary-first-nix", TestSummary(&first_backup)); + + assert_eq!(first_snapshot.parent, None); + + // // tree of first backup + // // re-read index + // let repo = repo.to_indexed_ids()?; + // let tree = repo.node_from_path(first_snapshot.tree, Path::new("test/tests"))?; + // let tree = repo.get_tree(&tree.subtree.expect("Sub tree"))?; + + // #[cfg(windows)] + // assert_debug_snapshot!("backup-tar-tree-windows", tree); + + // #[cfg(not(windows))] + // assert_debug_snapshot!("backup-tar-tree-nix", tree); // get all snapshots and check them let all_snapshots = repo.get_all_snapshots()?; - assert_eq!(vec![first_backup.clone()], all_snapshots); + assert_eq!(vec![first_snapshot.clone()], all_snapshots); // save list of pack files let packs1: Vec<_> = repo.list(rustic_core::FileType::Pack)?.collect(); @@ -180,14 +226,25 @@ fn test_backup_with_tar_gz_passes( let repo = repo.to_indexed_ids()?; // second backup let second_snapshot = repo.backup(&opts, paths, SnapshotFile::default())?; - assert_debug_snapshot!(TestSummary(&second_snapshot)); - assert_eq!(second_snapshot.parent, Some(first_backup.id)); - assert_eq!(first_backup.tree, second_snapshot.tree); + + #[cfg(windows)] + assert_debug_snapshot!( + "backup-tar-summary-second-windows", + TestSummary(&second_snapshot) + ); + #[cfg(not(windows))] + assert_debug_snapshot!( + "backup-tar-summary-second-nix", + TestSummary(&second_snapshot) + ); + + assert_eq!(second_snapshot.parent, Some(first_snapshot.id)); + assert_eq!(first_snapshot.tree, second_snapshot.tree); // get all snapshots and check them let mut all_snapshots = repo.get_all_snapshots()?; all_snapshots.sort_unstable(); - assert_eq!(vec![first_backup, second_snapshot], all_snapshots); + assert_eq!(vec![first_snapshot, second_snapshot], all_snapshots); // pack files should be unchanged let packs2: Vec<_> = repo.list(rustic_core::FileType::Pack)?.collect(); @@ -212,7 +269,16 @@ fn test_backup_dry_run_with_tar_gz_passes( // dry-run backup let snap_dry_run = repo.backup(&opts, paths, SnapshotFile::default())?; - assert_debug_snapshot!(TestSummary(&snap_dry_run)); + + #[cfg(windows)] + assert_debug_snapshot!( + "dryrun-tar-summary-first-windows", + TestSummary(&snap_dry_run) + ); + + #[cfg(not(windows))] + assert_debug_snapshot!("dryrun-tar-summary-first-nix", TestSummary(&snap_dry_run)); + // check that repo is still empty let snaps = repo.get_all_snapshots()?; assert_eq!(snaps.len(), 0); @@ -225,12 +291,33 @@ fn test_backup_dry_run_with_tar_gz_passes( assert_eq!(snap_dry_run.tree, first_snapshot.tree); let packs: Vec<_> = repo.list(rustic_core::FileType::Pack)?.collect(); + // // tree of first backup + // // re-read index + // let repo = repo.to_indexed_ids()?; + // let tree = repo.node_from_path(first_snapshot.tree, Path::new("test/tests"))?; + // let tree = repo.get_tree(&tree.subtree.expect("Sub tree"))?; + + // #[cfg(windows)] + // assert_debug_snapshot!("dryrun-tar-tree-windows", tree); + + // #[cfg(not(windows))] + // assert_debug_snapshot!("dryrun-tar-tree-nix", tree); + // re-read index let repo = repo.to_indexed_ids()?; // second dry-run backup let opts = opts.dry_run(true); let snap_dry_run = repo.backup(&opts, paths, SnapshotFile::default())?; - assert_debug_snapshot!(TestSummary(&snap_dry_run)); + + #[cfg(windows)] + assert_debug_snapshot!( + "dryrun-tar-summary-second-windows", + TestSummary(&snap_dry_run) + ); + + #[cfg(not(windows))] + assert_debug_snapshot!("dryrun-tar-summary-second-nix", TestSummary(&snap_dry_run)); + // check that no data has been added let snaps = repo.get_all_snapshots()?; assert_eq!(snaps, vec![first_snapshot]); diff --git a/crates/core/tests/snapshots/integration__backup_with_dir_passes.snap b/crates/core/tests/snapshots/integration__backup-dir-summary-first-windows.snap similarity index 75% rename from crates/core/tests/snapshots/integration__backup_with_dir_passes.snap rename to crates/core/tests/snapshots/integration__backup-dir-summary-first-windows.snap index 6c7dfee3..6d981dbd 100644 --- a/crates/core/tests/snapshots/integration__backup_with_dir_passes.snap +++ b/crates/core/tests/snapshots/integration__backup-dir-summary-first-windows.snap @@ -1,6 +1,6 @@ --- source: crates/core/tests/integration.rs -expression: TestSummary(&first_backup) +expression: TestSummary(&first_snapshot) --- TestSnap { hostname: "", @@ -17,13 +17,13 @@ TestSnap { files_changed: 0, files_unmodified: 0, total_files_processed: 73, - total_bytes_processed: 1125676, + total_bytes_processed: 1125674, dirs_new: 5, dirs_changed: 0, dirs_unmodified: 0, total_dirs_processed: 5, data_blobs: 70, tree_blobs: 5, - data_added_files: 1125654, - data_added_files_packed: 78741, + data_added_files: 1125653, + data_added_files_packed: 78740, } diff --git a/crates/core/tests/snapshots/integration__backup_with_dir_passes-2.snap b/crates/core/tests/snapshots/integration__backup-dir-summary-second-windows.snap similarity index 86% rename from crates/core/tests/snapshots/integration__backup_with_dir_passes-2.snap rename to crates/core/tests/snapshots/integration__backup-dir-summary-second-windows.snap index 7eb5a086..88efa041 100644 --- a/crates/core/tests/snapshots/integration__backup_with_dir_passes-2.snap +++ b/crates/core/tests/snapshots/integration__backup-dir-summary-second-windows.snap @@ -1,6 +1,6 @@ --- source: crates/core/tests/integration.rs -expression: TestSummary(&snap2) +expression: TestSummary(&second_snapshot) --- TestSnap { hostname: "", @@ -17,7 +17,7 @@ TestSnap { files_changed: 0, files_unmodified: 73, total_files_processed: 73, - total_bytes_processed: 1125682, + total_bytes_processed: 1125674, dirs_new: 0, dirs_changed: 0, dirs_unmodified: 5, diff --git a/crates/core/tests/snapshots/integration__backup-dir-tree-windows.snap b/crates/core/tests/snapshots/integration__backup-dir-tree-windows.snap new file mode 100644 index 00000000..ee1c4702 --- /dev/null +++ b/crates/core/tests/snapshots/integration__backup-dir-tree-windows.snap @@ -0,0 +1,129 @@ +--- +source: crates/core/tests/integration.rs +expression: tree +--- +Tree { + nodes: [ + Node { + name: "empty-file", + node_type: File, + meta: Metadata { + mode: None, + mtime: Some( + 2014-11-30T16:03:11+01:00, + ), + atime: Some( + 2014-11-30T16:03:11+01:00, + ), + ctime: Some( + 2024-03-12T22:32:55+01:00, + ), + uid: None, + gid: None, + user: None, + group: None, + inode: 0, + device_id: 0, + size: 0, + links: 0, + extended_attributes: [], + }, + content: Some( + [], + ), + subtree: None, + }, + Node { + name: "testfile", + node_type: File, + meta: Metadata { + mode: None, + mtime: Some( + 2014-08-09T14:14:20+02:00, + ), + atime: Some( + 2014-08-09T14:14:20+02:00, + ), + ctime: Some( + 2024-03-12T22:32:55+01:00, + ), + uid: None, + gid: None, + user: None, + group: None, + inode: 0, + device_id: 0, + size: 21, + links: 0, + extended_attributes: [], + }, + content: Some( + [ + 649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a, + ], + ), + subtree: None, + }, + Node { + name: "testfile-hardlink", + node_type: File, + meta: Metadata { + mode: None, + mtime: Some( + 2014-08-09T14:14:20+02:00, + ), + atime: Some( + 2014-08-09T14:14:20+02:00, + ), + ctime: Some( + 2024-03-12T22:32:55+01:00, + ), + uid: None, + gid: None, + user: None, + group: None, + inode: 0, + device_id: 0, + size: 21, + links: 0, + extended_attributes: [], + }, + content: Some( + [ + 649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a, + ], + ), + subtree: None, + }, + Node { + name: "testfile-symlink", + node_type: Symlink { + linktarget: "testfile", + linktarget_raw: None, + }, + meta: Metadata { + mode: None, + mtime: Some( + 2024-03-12T22:32:55.218816+01:00, + ), + atime: Some( + 2024-03-12T22:32:55.218816+01:00, + ), + ctime: Some( + 2024-03-12T22:32:55.218816+01:00, + ), + uid: None, + gid: None, + user: None, + group: None, + inode: 0, + device_id: 0, + size: 0, + links: 0, + extended_attributes: [], + }, + content: None, + subtree: None, + }, + ], +} diff --git a/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes.snap b/crates/core/tests/snapshots/integration__backup-tar-summary-first-windows.snap similarity index 92% rename from crates/core/tests/snapshots/integration__backup_with_tar_gz_passes.snap rename to crates/core/tests/snapshots/integration__backup-tar-summary-first-windows.snap index 4f80bc50..fbf264a3 100644 --- a/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes.snap +++ b/crates/core/tests/snapshots/integration__backup-tar-summary-first-windows.snap @@ -1,6 +1,6 @@ --- source: crates/core/tests/integration.rs -expression: TestSummary(&first_backup) +expression: TestSummary(&first_snapshot) --- TestSnap { hostname: "", diff --git a/crates/core/tests/snapshots/integration__backup_with_tar_gz_passes-2.snap b/crates/core/tests/snapshots/integration__backup-tar-summary-second-windows.snap similarity index 100% rename from crates/core/tests/snapshots/integration__backup_with_tar_gz_passes-2.snap rename to crates/core/tests/snapshots/integration__backup-tar-summary-second-windows.snap diff --git a/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes.snap b/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-windows.snap similarity index 100% rename from crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes.snap rename to crates/core/tests/snapshots/integration__dryrun-tar-summary-first-windows.snap diff --git a/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes-2.snap b/crates/core/tests/snapshots/integration__dryrun-tar-summary-second-windows.snap similarity index 93% rename from crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes-2.snap rename to crates/core/tests/snapshots/integration__dryrun-tar-summary-second-windows.snap index 632d04ee..ba72d6a9 100644 --- a/crates/core/tests/snapshots/integration__backup_dry_run_with_tar_gz_passes-2.snap +++ b/crates/core/tests/snapshots/integration__dryrun-tar-summary-second-windows.snap @@ -17,7 +17,7 @@ TestSnap { files_changed: 0, files_unmodified: 73, total_files_processed: 73, - total_bytes_processed: 1125682, + total_bytes_processed: 1125674, dirs_new: 0, dirs_changed: 0, dirs_unmodified: 6, From 34d9e89a8f5e5ade31d472d3f0d00524b378a95a Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Tue, 12 Mar 2024 23:12:38 +0100 Subject: [PATCH 19/46] update vars Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/core/tests/integration.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index 60e34d07..3e36701e 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -121,7 +121,7 @@ fn test_backup_with_dir_passes(dir_testdata: PathBuf, set_up_repo: Result Date: Tue, 12 Mar 2024 23:29:34 +0100 Subject: [PATCH 20/46] update snapshots Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- ...gration__backup-dir-summary-first-nix.snap | 29 +++++++++++++++++++ ...gration__backup-tar-summary-first-nix.snap | 29 +++++++++++++++++++ ...gration__dryrun-tar-summary-first-nix.snap | 29 +++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 crates/core/tests/snapshots/integration__backup-dir-summary-first-nix.snap create mode 100644 crates/core/tests/snapshots/integration__backup-tar-summary-first-nix.snap create mode 100644 crates/core/tests/snapshots/integration__dryrun-tar-summary-first-nix.snap diff --git a/crates/core/tests/snapshots/integration__backup-dir-summary-first-nix.snap b/crates/core/tests/snapshots/integration__backup-dir-summary-first-nix.snap new file mode 100644 index 00000000..6d981dbd --- /dev/null +++ b/crates/core/tests/snapshots/integration__backup-dir-summary-first-nix.snap @@ -0,0 +1,29 @@ +--- +source: crates/core/tests/integration.rs +expression: TestSummary(&first_snapshot) +--- +TestSnap { + hostname: "", + paths: StringList( + [ + "test", + ], + ), + label: "", + tags: StringList( + [], + ), + files_new: 73, + files_changed: 0, + files_unmodified: 0, + total_files_processed: 73, + total_bytes_processed: 1125674, + dirs_new: 5, + dirs_changed: 0, + dirs_unmodified: 0, + total_dirs_processed: 5, + data_blobs: 70, + tree_blobs: 5, + data_added_files: 1125653, + data_added_files_packed: 78740, +} diff --git a/crates/core/tests/snapshots/integration__backup-tar-summary-first-nix.snap b/crates/core/tests/snapshots/integration__backup-tar-summary-first-nix.snap new file mode 100644 index 00000000..fbf264a3 --- /dev/null +++ b/crates/core/tests/snapshots/integration__backup-tar-summary-first-nix.snap @@ -0,0 +1,29 @@ +--- +source: crates/core/tests/integration.rs +expression: TestSummary(&first_snapshot) +--- +TestSnap { + hostname: "", + paths: StringList( + [ + "test", + ], + ), + label: "", + tags: StringList( + [], + ), + files_new: 73, + files_changed: 0, + files_unmodified: 0, + total_files_processed: 73, + total_bytes_processed: 1125674, + dirs_new: 6, + dirs_changed: 0, + dirs_unmodified: 0, + total_dirs_processed: 6, + data_blobs: 70, + tree_blobs: 6, + data_added_files: 1125653, + data_added_files_packed: 78740, +} diff --git a/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-nix.snap b/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-nix.snap new file mode 100644 index 00000000..5663f447 --- /dev/null +++ b/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-nix.snap @@ -0,0 +1,29 @@ +--- +source: crates/core/tests/integration.rs +expression: TestSummary(&snap_dry_run) +--- +TestSnap { + hostname: "", + paths: StringList( + [ + "test", + ], + ), + label: "", + tags: StringList( + [], + ), + files_new: 73, + files_changed: 0, + files_unmodified: 0, + total_files_processed: 73, + total_bytes_processed: 1125674, + dirs_new: 6, + dirs_changed: 0, + dirs_unmodified: 0, + total_dirs_processed: 6, + data_blobs: 70, + tree_blobs: 6, + data_added_files: 1125653, + data_added_files_packed: 78740, +} From e31c9aff61845bc2e0ba27c2d81d3210bc8a557d Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Tue, 12 Mar 2024 23:54:08 +0100 Subject: [PATCH 21/46] update snapshots II Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/core/tests/integration.rs | 1 + .../integration__backup-dir-tree-nix.snap | 169 ++++++++++++++++++ ...ration__backup-tar-summary-second-nix.snap | 29 +++ ...ration__dryrun-tar-summary-second-nix.snap | 29 +++ 4 files changed, 228 insertions(+) create mode 100644 crates/core/tests/snapshots/integration__backup-dir-tree-nix.snap create mode 100644 crates/core/tests/snapshots/integration__backup-tar-summary-second-nix.snap create mode 100644 crates/core/tests/snapshots/integration__dryrun-tar-summary-second-nix.snap diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index 3e36701e..a54411d5 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -61,6 +61,7 @@ fn tar_gz_testdata() -> Result { Ok(TestSource::new(dir)) } +// TODO!: Remove? #[fixture] fn dir_testdata() -> PathBuf { Path::new("tests/fixtures/backup-data/") diff --git a/crates/core/tests/snapshots/integration__backup-dir-tree-nix.snap b/crates/core/tests/snapshots/integration__backup-dir-tree-nix.snap new file mode 100644 index 00000000..4cc57375 --- /dev/null +++ b/crates/core/tests/snapshots/integration__backup-dir-tree-nix.snap @@ -0,0 +1,169 @@ +--- +source: crates/core/tests/integration.rs +expression: tree +--- +Tree { + nodes: [ + Node { + name: "empty-file", + node_type: File, + meta: Metadata { + mode: Some( + 420, + ), + mtime: Some( + 2024-03-12T22:31:11.115831358+00:00, + ), + atime: Some( + 2024-03-12T22:31:11.115831358+00:00, + ), + ctime: Some( + 2024-03-12T22:31:11.115831358+00:00, + ), + uid: Some( + 501, + ), + gid: Some( + 20, + ), + user: Some( + "runner", + ), + group: Some( + "staff", + ), + inode: 12891863206, + device_id: 16777220, + size: 0, + links: 1, + extended_attributes: [], + }, + content: Some( + [], + ), + subtree: None, + }, + Node { + name: "testfile", + node_type: File, + meta: Metadata { + mode: Some( + 420, + ), + mtime: Some( + 2024-03-12T22:31:11.115939543+00:00, + ), + atime: Some( + 2024-03-12T22:31:11.115939543+00:00, + ), + ctime: Some( + 2024-03-12T22:31:11.115939543+00:00, + ), + uid: Some( + 501, + ), + gid: Some( + 20, + ), + user: Some( + "runner", + ), + group: Some( + "staff", + ), + inode: 12891863207, + device_id: 16777220, + size: 21, + links: 1, + extended_attributes: [], + }, + content: Some( + [ + 649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a, + ], + ), + subtree: None, + }, + Node { + name: "testfile-hardlink", + node_type: File, + meta: Metadata { + mode: Some( + 420, + ), + mtime: Some( + 2024-03-12T22:31:11.116070531+00:00, + ), + atime: Some( + 2024-03-12T22:31:11.116070531+00:00, + ), + ctime: Some( + 2024-03-12T22:31:11.116070531+00:00, + ), + uid: Some( + 501, + ), + gid: Some( + 20, + ), + user: Some( + "runner", + ), + group: Some( + "staff", + ), + inode: 12891863208, + device_id: 16777220, + size: 21, + links: 1, + extended_attributes: [], + }, + content: Some( + [ + 649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a, + ], + ), + subtree: None, + }, + Node { + name: "testfile-symlink", + node_type: Symlink { + linktarget: "testfile", + linktarget_raw: None, + }, + meta: Metadata { + mode: Some( + 134218221, + ), + mtime: Some( + 2024-03-12T22:31:11.116267198+00:00, + ), + atime: Some( + 2024-03-12T22:31:11.116267198+00:00, + ), + ctime: Some( + 2024-03-12T22:31:11.116267198+00:00, + ), + uid: Some( + 501, + ), + gid: Some( + 20, + ), + user: Some( + "runner", + ), + group: Some( + "staff", + ), + inode: 12891863209, + device_id: 16777220, + size: 8, + links: 1, + extended_attributes: [], + }, + content: None, + subtree: None, + }, + ], +} diff --git a/crates/core/tests/snapshots/integration__backup-tar-summary-second-nix.snap b/crates/core/tests/snapshots/integration__backup-tar-summary-second-nix.snap new file mode 100644 index 00000000..7413b5d5 --- /dev/null +++ b/crates/core/tests/snapshots/integration__backup-tar-summary-second-nix.snap @@ -0,0 +1,29 @@ +--- +source: crates/core/tests/integration.rs +expression: TestSummary(&second_snapshot) +--- +TestSnap { + hostname: "", + paths: StringList( + [ + "test", + ], + ), + label: "", + tags: StringList( + [], + ), + files_new: 0, + files_changed: 0, + files_unmodified: 73, + total_files_processed: 73, + total_bytes_processed: 1125682, + dirs_new: 0, + dirs_changed: 0, + dirs_unmodified: 6, + total_dirs_processed: 6, + data_blobs: 0, + tree_blobs: 0, + data_added_files: 0, + data_added_files_packed: 0, +} diff --git a/crates/core/tests/snapshots/integration__dryrun-tar-summary-second-nix.snap b/crates/core/tests/snapshots/integration__dryrun-tar-summary-second-nix.snap new file mode 100644 index 00000000..632d04ee --- /dev/null +++ b/crates/core/tests/snapshots/integration__dryrun-tar-summary-second-nix.snap @@ -0,0 +1,29 @@ +--- +source: crates/core/tests/integration.rs +expression: TestSummary(&snap_dry_run) +--- +TestSnap { + hostname: "", + paths: StringList( + [ + "test", + ], + ), + label: "", + tags: StringList( + [], + ), + files_new: 0, + files_changed: 0, + files_unmodified: 73, + total_files_processed: 73, + total_bytes_processed: 1125682, + dirs_new: 0, + dirs_changed: 0, + dirs_unmodified: 6, + total_dirs_processed: 6, + data_blobs: 0, + tree_blobs: 0, + data_added_files: 0, + data_added_files_packed: 0, +} From 1d359cf1a57fa35fe890b7e1e6f0ec11a7ea20e3 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Wed, 13 Mar 2024 00:40:36 +0100 Subject: [PATCH 22/46] cleanup, add new snapshots Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/core/tests/fixtures/backup-data/0/9/0 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/1 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/10 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/11 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/12 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/13 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/14 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/15 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/16 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/17 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/18 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/19 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/2 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/20 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/21 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/22 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/23 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/24 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/25 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/26 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/27 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/28 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/29 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/3 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/30 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/31 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/32 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/33 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/34 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/35 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/36 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/37 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/38 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/39 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/4 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/40 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/41 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/42 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/43 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/44 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/45 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/46 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/47 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/48 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/49 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/5 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/50 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/51 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/52 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/53 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/54 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/55 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/56 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/57 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/58 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/59 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/6 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/60 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/61 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/62 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/63 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/64 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/65 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/66 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/67 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/68 | Bin 11520 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/7 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/8 | Bin 16384 -> 0 bytes crates/core/tests/fixtures/backup-data/0/9/9 | Bin 16384 -> 0 bytes .../fixtures/backup-data/tests/empty-file | 0 .../tests/fixtures/backup-data/tests/testfile | 1 - .../backup-data/tests/testfile-hardlink | 1 - .../backup-data/tests/testfile-symlink | 1 - crates/core/tests/integration.rs | 119 ++---------- ...gration__backup-dir-summary-first-nix.snap | 29 --- ...ion__backup-dir-summary-first-windows.snap | 29 --- ...on__backup-dir-summary-second-windows.snap | 29 --- .../integration__backup-dir-tree-nix.snap | 169 ------------------ ...integration__backup-tar-tree-windows.snap} | 12 +- .../integration__dryrun-tar-tree-windows.snap | 129 +++++++++++++ 80 files changed, 153 insertions(+), 366 deletions(-) delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/0 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/1 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/10 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/11 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/12 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/13 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/14 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/15 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/16 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/17 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/18 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/19 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/2 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/20 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/21 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/22 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/23 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/24 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/25 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/26 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/27 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/28 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/29 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/3 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/30 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/31 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/32 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/33 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/34 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/35 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/36 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/37 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/38 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/39 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/4 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/40 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/41 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/42 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/43 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/44 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/45 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/46 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/47 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/48 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/49 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/5 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/50 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/51 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/52 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/53 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/54 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/55 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/56 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/57 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/58 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/59 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/6 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/60 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/61 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/62 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/63 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/64 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/65 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/66 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/67 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/68 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/7 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/8 delete mode 100644 crates/core/tests/fixtures/backup-data/0/9/9 delete mode 100644 crates/core/tests/fixtures/backup-data/tests/empty-file delete mode 100644 crates/core/tests/fixtures/backup-data/tests/testfile delete mode 100644 crates/core/tests/fixtures/backup-data/tests/testfile-hardlink delete mode 120000 crates/core/tests/fixtures/backup-data/tests/testfile-symlink delete mode 100644 crates/core/tests/snapshots/integration__backup-dir-summary-first-nix.snap delete mode 100644 crates/core/tests/snapshots/integration__backup-dir-summary-first-windows.snap delete mode 100644 crates/core/tests/snapshots/integration__backup-dir-summary-second-windows.snap delete mode 100644 crates/core/tests/snapshots/integration__backup-dir-tree-nix.snap rename crates/core/tests/snapshots/{integration__backup-dir-tree-windows.snap => integration__backup-tar-tree-windows.snap} (91%) create mode 100644 crates/core/tests/snapshots/integration__dryrun-tar-tree-windows.snap diff --git a/crates/core/tests/fixtures/backup-data/0/9/0 b/crates/core/tests/fixtures/backup-data/0/9/0 deleted file mode 100644 index 187e73b7363ee200f2591a333fe551aab518d084..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!`8(Tp0KoBJsKii5_e5LAknvEgq;%#=J4e(VN2QOdTTpei?$&)YRTRbYq>j~5 zIa*Rzn1#+=L9JL_Q{sq}%HU!(956xTW5s*Dh(FnRIcc(>G8ZUZXaDP;K5v@?u}S1?@Oi5-|~g(OZ>MECM;|)LRnZwI+)m@8d4<}?#Y)3B(yo{+r(@Q zTI9YQjPQSR+cb)&dbcWGAJ#w?xb~*v;dhJ}YL`*B<)Oj?+&rVuPu|RmwNfHBVCR-; z%GDrX(+kS8f+_=g`>{96)f;X-RjK!gCB(gQtd_j?>(|djVm=CHoSva~)C<7LCv%N$ zKm2AbAC1!tUJ8qNouRxMKHxL#V|a11Slq`*PDi3ji$r3iTFrYzSEOxkZ}18e83tDo z8n7Cbe%hWNH_BChVbCecSrp-k&d}APwA)XcyEh?t($THr?1N|pS!8z*_l`^`YaFhf zs5HxS49m67(X$CJ%f=Wf^dXt1R_(PNsUH-dE41S&j5@<{<1~sv#zqh1V>yF!<)>=%x9X^MN5-t}( zT&_7Sxfil%5Qe{iJLoZG^02%EsA84B|-6PFZny ziT4w%t`4a-_6%!&ePU@n$CqKjo?0s2DvYc(WtDpb!|9w7hpleLH(nEp1s+I`OQD>yBezqtbMY^-TouDY3xE*3<&3^cov;Tnfn zKcY>XvG|2_=>Qx7xe`0E?-th>YTLfZE%(~5l9KC`6!cAtNGzg;cphVVZsVn98kZxf z3Vvuf-$3o6*F)6tp;`cKK55PA{{4DAlA+rUXH-nhylOwd)$As7 z9u!cAyN)}T^|MRg#Si!tPYu<=w3E%Hra#*TvL$~}vL2TZBP7l=Q&2}iByaH;)G2a> zJki~|C-E;5KmZ`{pCC{N5C8~(6M*&!yZ{IQ1ONiiMxY)b01yBOKpO!HKmZ^B5P&uU zRDb|L03ZNu1ZV&OfB--M+6d4A0ssMk0JIT!2@n7X00f|oz$<_NKmZ^BZ3G$s0ssMk z0JITk1PA~G00PiPfB_Hy2ml12jlgSw06+jB0Br=C00IC3fB>`+Xa)%UUkLmISzm-2 diff --git a/crates/core/tests/fixtures/backup-data/0/9/1 b/crates/core/tests/fixtures/backup-data/0/9/1 deleted file mode 100644 index fd161476f6206f5ff917a12077fe498963488802..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!`8(Tp0KoBJsKii5_e5LAknvEgq;%#=J4e(VN2QOdTTpei?$&)YRTRbYq>j}w zBpX>BiKao_71WB=H6@OyXsFxldG`B$@AG^=??2-8yv_S2idu%HclGm0N4FA2}C^DEsZF$aMAfB#fGXozbWLQ&| zv>op-g(;(r^?OT-we7gwX{*K5+u?KQDB*Gu#O0dPl6xVG24VOMxFhDRz$;k{>RmWD z&QHDy1RlA}>&X2W!m4Y4y=)Q@;Zz)wlO_8j8D>w+uPsMdfa z;f_<3!X7LYo#}S4ht9+8t{1mbJk~fkrr=24){SzfzS1L@DnjWaKaM}z%hV-?Y-wrM zs-H_9EMr}@3O$DXmu2f@XD}uupwBk0XeHT-MK)VGWOMA>In)?r7-@AkZU!?<6l(Q< zTMtW`HF2KR%{ShC6CvxEvT^nijX09CQ&t>a;{61xt3#@dJ;Rz`pIBPY@ugX?rcphVVZsVn9nwKLR75va}zJc0BuZO7PL$v_PeA1fJ{rmNL zBty3y&ZwB0IY0m)@I@lf1`q%UfD?fB3A6(Q00IC3Xd^%e2mk~C0?H00;mCppC$5fB--MAOLLydH@0d0e}Fs5$FX7{2v1U0t9V_ A7ytkO diff --git a/crates/core/tests/fixtures/backup-data/0/9/10 b/crates/core/tests/fixtures/backup-data/0/9/10 deleted file mode 100644 index 07ba19b69553d69e17d13cac2d50583dbbda59ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!`8(Tp0KoBJsKijDd!nsl$apALQaW>`9T7KiRQjm81yxt;Zrw*yMNzUmsbh5v z$wpR3n1;?>L9JL_Q{sqg zo_<4z!;FQ;a|B;DrcIJ_7^5hU>IvrEmJ4G~z;%+8=lD+HdDgl5HW8E@tg&K0ie-lD zsO?O9tMp8F+IQy2Kjo_Iy&oJ^N=SF@NK3Tsy5DZA#n#&sb6IH7axui^n$yzzp-YD0#0!MuuA4zuvO5@e z;JhGTnCe^_OPw$|ZYDaSHNeo4e_uw6K~u~}SYn$JXYlCni5-DIB>OpV$%lUwUSUMH z1}2Mko}w4^;u)AM_rrZmK4EX8q?PWu&LwmSkLGV*FL&-QJBFztl-~>D1!H|(dgRb; zZLM03b16d<_ElWi3GBacR#V*}*wny&yZGYO6dapozIw#rI<#{cv8ZtB+FtxDc7!a_ z8t}RvmON+bGN)HyviB-d-YIqS>_aAbGe{&7_X;Gt&KawUf7si-pKW1T5_hB zOSX%m>OQRxA*qQKQ>Lu*MnkTnDD@^p;c7Nrtn$aleqKisqPx0Em|?zXC<<%z?3&Jf zIOt@GTHI8CJHKPExx2`*tf1GRo)8) zq=4p-Iz%K^BP;O{dokJJE@y$G_o))ub{x>?c&P<8o`q7Zp0_$g{pBxj88tZbbw;(v zyww+QdY)iw72efc^L(Z1Mh>P#80|XP;zomO9^w7THt{Bs7cyi62_)2N+~k3Kd~=vx z#}cpH`=Ck&*(ELPmmZl^+!*S0g6+LUl$mW_iE32z$G`=K>KDBqpihp}1L+IN>(2M? z)$3D@+;_QS66zNHlf^9~GRQgjWw^)`K@(lGm%_bY*f`RC(zRlcQ}#Mx(6?lIxE7|9 zVj(m0!7hj+{gblwgp>p+X||;SeH={nk&H#3qE#r6J$!nT{-)loa8sf`9Z+5yUZ1CP z(g*bVBiPY{atMAR_ruSHhF^`n>uUlllao%pLyev`tn()Dx>=MSH zVM|HKON{bX_ngN^mA&h6c>c#q-G3B{G?oRg98KBy5QK`ToNNfWQ!TU#8Q~?63L>>T z8`#8d4_W5@G87r`@|IaNU+qp+f&r|FCS?1v;=wn}*v4+-9;+k8MYu&~k-vgDj=fqc zF=+3eWyaGa;WG-$vx6%G`v&kg$~Bs9K2fdrj3dSW>QpUl`}>zq#bVzHXP%yAbk+;O zX`kks+rN7O5cvEE-~a*u0e}FsPrw==01yBOKpO!(KmZ^B5P&uUHUI&D06+lR2-pGy z00IC3Xd_?;5C8}O1fY$8JwN~;01$vS0uBHHfB--M+6XuT1ONg60ca!O1P}lS00f|o yfHOb`+a0Lhe1ONiiM!*dq01)^e5%?GDDSzt# diff --git a/crates/core/tests/fixtures/backup-data/0/9/11 b/crates/core/tests/fixtures/backup-data/0/9/11 deleted file mode 100644 index c677791629e2ca060ef6fba403e823713782fc0f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!2|L?&0KoB-p%OzK-4kttm6V5;m6Xn0X;%?#9gPO*ToECm>T2DsyVdldD3&L6 ztd1es$ciRrp>stAwbHeYDRD$aL)~W2vv<+w|NFj(&+|RTjjM0B>2TUcO~DcAw!OrdhR@6^y&YOk?drk%l^Qh!JU&|M6HiO{)xA>f{O?~rQH*;pmvvx_ z(^|U^&f1%3eE#hp&N{IK6Z%X<)Nfh(^O3#eezNt+bN!5!?qc9Hl@xc zqI;JL6!j^aX__6~ow*ICcmwS|kITe|{>mc7$Xi#{q^u^oy}_1nhk63llv~z_*IKHv zwHHY_JhVcoBI0z_0kw^=X{!j*al%epK**Wfe9m>aB!mn*I-brmB#aE%EA*T6a7?s5 z6tiN{B@X>O#U(9J1oS0^6ibCstc77+GgUKdtZD1Y}))xz# z***(mLYv&c!<8$g9^J(|Faw0%2U&t_u&d3S5w>D#Qf+iNRahc8iwoa{{U44v+D^x& zQM)fB6wIaK1T2TSZIRgZxtJ4&j9|{MCyZhH8S>4+uWDf_<93(E&2w$nUq)%Ur!5`2 z$7KxUtd$f-76m@So0~DK;|~fZ7e{6mbAq_%L~mvaSMsB4_7;TN%%rkWJKhm%q2~b7 zumO=bcblzP{^O${-)&`uH8WjIpHv|XiM4*}ec~1zxnn`%y_T5Nt*h3L5*>;nP2)mx z(_Bff9UjQHdLo=`SACpGvT{}vnN|t=#?!XKe=?UA+(@rML}87xlO71BQe1C{CPn6Z z<=QPf!S!yZnqWiONL1y7(-!h?iq^U4-gjSTR(ef1eF10Rmo3l1+ZwB$%~tr`!4%4& zJ$sujv*5-gHgoxCB(sLeGRi-76HPxYa zLYaXoap?W5G989jU}y3_%o}Bwb=gmP^yd2(CfK5k9`o)hXWjj^m-*4^i;Sn}5Fu-7O3^(*ms>8EnD ze|7SWW@Inj>;!l^LSI2sgU)C*2&>SJ^p&ZG(4Ko(y2Pyr&)xq;7!~~Ds(p;q;Ce-( zC9Hw9@BE9hyT(=cZ0fZB!Rsc{s6TY8sKJ>t3(>FYfjGe*TE}>tnJbLbK|n-QKW|W^1QX ziOP?)cK;ZaSMyQoO5L< zEiTlhJHXm_J5D^Px&DnXrM2JrzUQX#48lFPEXK%kgc1k~%E`0dL(nklckS z->#AG`7@WyQg>=-%3MkJe}S(OJ{gMCg?Funp6_bJH~W$cMHr20P2}N*UAmv>vyO@6 z{iLnFvvEiBdjuB{inu74`Q%lRC28!5tA^BONMK|5u9BCGsdAHwG~dH_6EWYDdnm^< zqy6OUjXz3{3Rs<#OpV^1{IUU}0GAiK@d;NFbkyV zJ5`!$^kE;CO<%UPX|&p#HC!b=Mo8F({TG2U-cQ44QwDv~%IC8PVxHUlrcCbFEf=Jq z6S;5K(kAdywt8pm(`H!aCU-W2Rw1_WM0IgzS;R)hZ67BJvgyYsYO&-7TJ8 z9GhD#j23#xUd(Zp%aWQtFASr&mukk3i1s-R2aljF+mNO6`FzdVA8tiQY{E5G?M!fw zlp1t2-s$ei16L5}Eqk))xx%JpO{aA{)UASHn-W)&?MHs@c2m7K80qP<67EG-)$%%` zsP(XKgI(&*OqWn&+i6WmCf+LV(oOM9rr$-`v<&;X7S**C+v`+paBE`0ssMM zBR~fT00aO6&_*BuAOH{m2tXTwa{vK=06+lR2qXdo00IC3Xd`eQAOH{m2tXSF20#EH z01$vS0!)AaKmZ^BZ3L140ssMk0JITc0R#X700C$tkPHw22ml12jlczf!2b$?e*u(1 BebE2_ diff --git a/crates/core/tests/fixtures/backup-data/0/9/13 b/crates/core/tests/fixtures/backup-data/0/9/13 deleted file mode 100644 index 4a89720915ef60ff097a217ce54b36d609b73fc0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!|3A}t0KoCZnQRXE(mkf~sb-LVUeb5nJ}&y!+%QzTTG2~w4*c>iOG%NIkhdYTdfb|u|jR8dgfV%=1su5zW- z)R?S$N^5n<_%+U%|ITtt7`*DG?PkJ+9b~J23us=;UKm6u5U-L8~CSfKy^_K$c`4m~?K&0!wcjfw#Zf1@Kyge+I zDA#8yG>x0Ly!=*Gnk8~MjI@WH6IAmE(sE#M!^euAoOR2hsceCh4i9LMU>pF5@THd#4C-X)1 zuFu@__--6ujQqxlGPrg0YL3aH-tOY2{o=u{(7Rm4jz0>>RBhMVdd70bu^0F%(Xcea zP_J!;biS<)-w;495~FoEaO8p7ZH6BcU%Moe_YyZc&&D0P+Ah3^P{u{Vc2DGrZHXhp z9y$XUsSsoOrjnh8uJRlZ!{6#{C!oJ2x5s|Rhze9N*M2WKB&4>+GITn&3QD^PLR=wf z?IZ3sQL|XyDhORr5IeO7Z!ewZ1oc*Kz-*9KZ`5@4P){e8nYgqEQ)jm`yRS-e*e7Wd z_HRCyM!OR5IkCO|^s>2Z9|_xYZe6Yje5er8P|2)$4SgIxz|?MydD;MDOdLEhfh~5| zJV`Y@p7VCc4H0v&Xr-z=r6S@E0qe-BOW!V;S{#{KEQ%5xk-wNJUn;#&|7oGmjFrh9 zJt*Gg+7~>CvTZ_^%v}}0tG~Y!6}GOYv*Kup>sRR{qVTTwPdQvcpf;Sy;^#^XUt`cX zO7g5o*+Yvf&Iu$x_q?Uu5sdV9Uk>#ptE<^9k(3(P*TL?*@Tp=-Omjj#G8J!En0ZSw z%?P|CpORxgRhzYK#55k;-vS#hL|N2Kdat4Wj5a-TK{obfeoe@v_h$&fP4&AuL}zpD zgIV60Yq)YPbg-=DBpYGBPKaju(cSg;<{QTnDX6*hkyR4CImy5MwUQIQ$}=+SG}Ma9 zOU){4Obpw^cb_90jW^F;XtapNA=ECm`@*lIH`i@r1yhWLpv#vVoLH`;6~&OAtyk|z zS<8Tt*#zPMLVJ{GkFM2ZE3T9@4s>mH&N^SKe3~JPEPv5o2Xn~wG8%jDA162b!OHiU zfgUAmyoHb6h-XFU)6f6`fWUu^01Y4j5CA6t?Gs1`2mk~C0?`+ z$OZ@i1ONiiMj!_u01yBOKpTNvfB--MAOLLy@&Ez=0e}Fs5y%G!00aO6&_>BRA%4EC z33VDk_7sgmU7%FS5?wv}7Z*BwL4;#_tQw2@2iK#5nScR zHL<#|77E{;S5-M*(W9Ds4f@PaPJ%9Sed0KZPADnW&*xLEcZfYWqwyq z`|=;@_y__0x`u?kSi4zF1$}bJQ(UBD-{nz9J*LqHpUprCRth0*)?E}o3|i3(!C%9j z_B`;vmDxpm4CnZJ!ITzK7%I5wNn^n=^&y(N^oMdvB&xz>j3KlwatVw27T@LfU4pkQ zn|S1cg{r?V_I5uJ5!~03M~`v^ zgOC{g7k4$E!jY#sc*a|fdeebe^Nfp0S*S*oe_^sM{;f&AK(`aZ+;Gp$63?rqw0RL~ zVP88L)_5!x5`0?&8xUa_)r`1&=5m7V6V?(-`@CAF4RxyU6*U}{Ya0KLf z^z@NSOlz=p*9xc7APXP>5C8~38-Z+q06+jB0Br`+ zAOZvc0ssMMBajOa00;mCpp8HtKmZ^B5P&uU`2Ycc06+lR2owMW00IC3Xd_Sv5C8}O z1fY#T5kLSS01$vS0>uCUfB--M+6a^Y1ONg60cayo3J?GY00f|o00|)Q9|ZmZYfFS2 diff --git a/crates/core/tests/fixtures/backup-data/0/9/15 b/crates/core/tests/fixtures/backup-data/0/9/15 deleted file mode 100644 index 7aa90d69b7ce2a2e29d162f3f4b70211a00d5f2b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!jX%?Q0KoC#Og4wG?lqN%lN~P=7t1;)tS(F_<{|4Pc{U_Z#XOYfhgKoP+RbKp zI&63B@~}BKIt&@=qRZ2XB~z;rdAjcPy8q%{zwhUdc)vd0420=6A%yBeu~j>gqZLLZ zqnDB=Hhn0q(XN68DKlV`t%>T^Pz=tFODk)R^54bxT_I^sx4w>V)(gQRL#4B`YrX_9D)soThq+$?Dx>DldmZB}ZCA=F|t*aIwZi1LtSzs^qlkwkFI@1U*nK3A2a6(xv(a_NDzzzs~a3 z=TwOd-V86#a>Uspi-A~S!k{)%mMZ!1Q;GFgW3T#KBHa!~7p=(1=svzm99KoU-marX zQn{eGIi|IMwQ72=uiy`-y)-}I`_XXYVlqMYvD*9}-BOc9`IB=eg@j0?p|ZACB(>{M z6dM)mFINvIcY0X4B&`mex%2Z-Th@}UidwLaAsr#^bYBiXl`r64LrBAeU`8`pd}HFoxSjHd znTTtq^R|+ah@sh!@Zs-N_YpAPlLTQuqzAi8s9S%OoZ=?5hovib?ctR65xCeqpRG^W zBI3qMc{|5%Swieq94%VC$n+Sf+<_fJ8oZTLDnn}m*`zuBNn<434U?V(Q_Vd*m`J!dS6Z8x68 z>737exBoVeI$F3+E03)RyhpGwr`IR%6V9znEUpv=^UjE0ES9g9#y5Ok9zxMmS(7LE z2XRAQqiEw6WXV!K2VVW)Uak*~*?^40o8+b570#!- zUl-4bEk0MHI(9;v&mC`rjpw2DYG)m{(0_&KoQWTt`Z}l9ch>O>1m}+Y{SuR diff --git a/crates/core/tests/fixtures/backup-data/0/9/16 b/crates/core/tests/fixtures/backup-data/0/9/16 deleted file mode 100644 index 3100f73717da47148cbb0f5240bb604ade747bfd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!`8(Tp0KoBJsKii5_e5LAknvEgq;%#=J4e(VN2QOdTTpei?$&)YRTRbYq>j~5 zIa*Rzn1#+=L9JL_Q{sqV_M)3jW5 zGaFqjh;kWdb|u3#4zYejn>b_f3+d7UI0AAdc4FTxt})cMeUV%4wO=JA*C{FJn--B+ zL=Evg#`N6AOU*PcM^Y91&~Uzi+C{I2sN+Mm0NQ-gn$!LJ^?D>jw;j%?n3{RtL{amw zl-w-*GF)g9r-7>3P3Al(pbmE(cP{H^m%fW1@F|`es)cDMn@df9whd%U{-R_(E+Ixp zoN1<@j)F+u;xVXGB>%$tz0@vPDJp7IkL+vu^wmei=fSYF&`pKJFu~tgN2JGB2O}QEbY~T`X^}{bRI7Q9=!&%M?G0XGBE#S+LIYN#(ofs-<3_p4 zFAO?GIg27Z(HXjWly>`RbN40$Pdd6)oP7|jAdBn{;@*)7WsSqN6P0Fpj$yghIeIqX zW!V@bg+3(H)T+I-UxvYu$0X(^`wEx5MW!QNraSh|4vnCHF!W4Z`pj za7UfD01t~qJG4;2mF-e zYtJDb{9bT{9@P?%B;0X|R@j53qchzO_Rx8_-Sy%Yn#URk*C{xXw{@f3sju`1rixJd z#E;{T_IBzLL$`dpvMU&q63}NGSG1CB#Uh)n9I`p~Z5(gF5ozKxJ|OxZa5h(R35*(oayFY$hY)zu-@#-3r# zuTLzk=lC)#*i%czTZNHzCu@Upq=bq|6XtotL6;GvS_7hBC5t9f`STNB&qFcc9UVpV z5KlM+i7|YBUHbtXd8CJDzUOLEb|t8jZe}InS}}q7DfamHW{-tBTo9JV+aA_Gyh00IC3fB>`+cmWUq2ml12jX*s>03ZMm zfHndYfB--MAOLLyr~mj}w zBpX>BiKao_71WB=H6@OyXsFxldG-(N*FMkp^Zp}V&$|gxu#!a)sr>ngujiqd@Q#im zdWa_+g2Wg;zpniNjy%%C)8BD58+IicC*90S!nI-o^Hc2c@5~+xb+{lbjki6l@%&11 ziw~h1_PvX7mDhYe!M{1U4iSM-&rEpCT1c|L$DU{Fo>a=U9r-spTxx-hWg-=-=PVD9 zfBDH;L=H@Un_lfcXZaPJlFQ#*fis(HUMyGL%tjXrqFe@AT*+{aL#!XsCeB#=Lb`MS zj(}W=o!EDaYYw$#EON`e_N%1in396NX%UGiAGCfHI%7=5+sly&lQXZHF@|re@wZQPeUlB{vJd3>TWjX`pI$lQ|Cx8izZNnaldw zrElX0e2S-rYGK;R=2Fw2Yy;VnzbILcONbE?XIdIiM?oZS@fg%8a)mt6-Mc68Z_>RA zS4GORex=o+wK)nqtzWkj4cNJ5nsPM=*z|((tf0z(-hS-Oa`mQLPgUwYVhM4-J620xd-?S< zk(dvH8K-Bc9rXfm^2uCt`wy?I<)d+$!AoHge`F}Hh7b4*`xsu_EEe}MlGBl>(jt*) zsaEqI(G_Xi+Z(*XM4G`>ga)ierJu6r$BlB8Ul??Xau!8+qBC^$8W{G|=I$>LJn85* zarQy9f-JHthgYMW(B-C%@?ueWcUlX$9x(pBeZlA;X%wr0sZzDNGq{tlwKw ztZm2bPFpRe-VUEbM+ujUATHOOmfQ1t~qJG3P0)9&JwdW8IUKd=UMzsbc33r^L6!u`L=uEeR zJ#-#!cfGik;<3iTF$G8Rwr-R=^_3pMR1r!a`EmTwUZyTFWJ^o4R{dP^U>WPGRp>G7 zzpPp&JA*MP0e!Y{MJvfxEV9|kA)900&Y{L2!$_;UaWj}~itcmliZocvE zn+RFQl#R2GXvC46owDNa67MHiT^&+w>>1Yl`oz+DjxWuEJ+)N4RTx=!vNkA3N~oAL zp`SM#bQwXaH30+w0sw(83xQUE05}0~0?`+cm)su2ml12jQ|TE z01yBOKpTNhfB--MAOLLyx&Q(I0e}Fs5$Fa800aO6&_>`jKmZ^B5P&uUJ^zEiznJTQ Ag8%>k diff --git a/crates/core/tests/fixtures/backup-data/0/9/18 b/crates/core/tests/fixtures/backup-data/0/9/18 deleted file mode 100644 index 9409bc40c8f53d4ef73de31db3a853a602d24f23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!jX%?Q0KoC#M%x_n(7mSeaAn7f;$qP`VHLB=<2+=&B+m_LqF7mZh-f_!t9E;> z%`Ojz?T%e&oSQoKpbaUy@^F>4Osz)b>AKhJ{)~R#&mZxAea3MLx{am#TF7bTl+x{UtySl0N=xX@cGz$k+NN$Ya2fq~vSq+Y+4FBN)Wu8&eud;;(Y;qA zd)n&nzUCb%$1?OWk+SwEHqvQ@kWAlC^)cRd!90~nMyvBjm!hd{nFqUGX*lsqJTt2v zQ~jip?1Gw>jJP#i-*J-Jc-!lfEjGzmq|Vb}NBkws+KNLee~LB}e(qe8JIgD2K{bSM z@Ry9%v@6W4CXl<324h4gO#Nb^>U>p;qIa$5wMY4_M`vV-jHd$)uM)}kFgSr^Dyh!Tx)tvLSMl@tkc{mTmEgS-J5}#Nxrf~>L#Ixb7U4M z?OD}_U#dL68G6~@njXA4^V+PIjP4T|Webcn3mul`B%?$6OGD|na^A| z#eB41Je*I^eynx<*SgwqTK6z?x0sNQvWHukr_;N)X7H>iaXOPU^1X16{dsfpfGfYs zvr`@%_s!96J;giY0c&OJ9eBXK^qnxTrPup@;EK%)q-hEciQR#q32$d6RduV zl>aGNlM`kALLQzIVT6jqmb$q&cZEFnkGYG|n&);JE0=R^EYbImX--&Vibs&!3+yJe zVOdv#D%|%|nB_Qc8wpzEi|=aaE`DZv$EJ(aENt`|@hNHc<^(w_FGtiE+9xj+S=^WO zRkrRF4fe*~;Hox0E+yp{c-1%3=Ffya#W97$(gagP=R)*}&IVjlFsVX>fpZK|yXx1Q ze#&^|nMK-0T|6}fPa!gVhuA>C z{7C9b-A79bQPG$Gs@fyS=}4u)yVvon`v?MTS@iNJ>^0)zETe-TJEJ1@=nr0-JIo1} z+**ZgMcKX8QFTN8J#O@jITz;!$4!NDrg$$ta}D-?`2MlpbX-xY`+ z7y<|Y1ONiiMqn5q01yBOKpTNa00DpiKmghZi~s}x0ssMMBk&j?01yBOd|3$m2XQQf AHvj+t diff --git a/crates/core/tests/fixtures/backup-data/0/9/19 b/crates/core/tests/fixtures/backup-data/0/9/19 deleted file mode 100644 index f179b64e8965b039bc773110931d5592ab77dd9c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeIy`8(Tp007`%sKii5_e5LAknvEgq;%#=J0j|iqtZv!EvUL$XIl5sR8bVmlR8$% zkZfdigjwj^71SJc))7ZkG}LX~^Xxy^Py6BfdH;x)gYOU=&e^$D>eyR+0#ijOec;FP zM|wJR$-z5Xn$_wT5(i3H*Rdg|uzz94Cp&{MN&dYyu?1_1SQgc6?U>E6Yvs_Rk)f3J z{n%N|5Lu|%?`1tLKrWGBKn`B2AH+w47?u@WB-gUPk@XM)9-o#4S zx6Z~Do(s7|zs8^%L^wu0J^m?ck!1IPy};J}TrSsg;#Y5fr3p5gj#Q|ew>(0=^Od!T z=%4vIwbE_g@(VaEo4>sV?`W)gwOVmI6J02Xa_(<(p~5wealT~hSYz=^snY&Ap*lnr&Q-s8{es!}$hkmpvb&PLI|6 zX$zzc$A=GV^(cm}dz=w5HS^wyf~FxUxjFb%xX>hC168%3$a$1kKh$~Jv8tb0{5G!N zyKri-8m66SE;aMfCV(yZlake#gcvblwy6$v5=ik9k4BxLmdTUdyt)(KQy!GLDAHc^ zDXkA~%+uH@eY(A2tjK;D1TUWR@#j2)uSS-78iH&uhU9GWh{$fHXgFPzyVoo$O%S~) zcsL@xjMlH)Ruu3MDVf%};Py#*|5gl+_o-axZ~1)n75*E06BaHAp)4#T9Yk(d4X%(2 z^WaMa5L+Gft)q7aEV6$Y2={w^*EEu+dcPu0AJ#w>xbeE|@i&a<`c9)R%VUK_xOrN> zue=$SwN@n7Z|jq(*9yR?pXVD}zx%^VJ_@fHv=SQrTblBESikp>x8ddOLUC^+IUR`#EeeH^j9qY# zDofej-QwjZFbu9EG+NBRA?jAF=`CQj8p22 zO06{6Pn-%wlzk7AWV(90a~rNOhdbS$mvPSjl}3mZGOVg0?Z(+pVM-XIeO{7cEqku_ zTB11 zZx%Mw+&4J?F@Xt?07w8N0PO@OK>{EFkN~t3m;woa1V94NPT(C#03-ksfOZ1YAOVm7 zNC4Ui%zy+y0w4isCol^V011Eupq;=RNB|@N5`cCB^B@6`07wAZ2`qpFKms5EXeaO< yBmfcs2|zo6MUVhU03-nI1eQPoAOVm7v=dkc34jDZ0?WFNYZb diff --git a/crates/core/tests/fixtures/backup-data/0/9/2 b/crates/core/tests/fixtures/backup-data/0/9/2 deleted file mode 100644 index 20ae9eec678e51288232ff7ccf53b83aeb00712d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!jX%?Q0KoC#HrX8V(7mSeaMSS99KA~DJw>({Z+mm5#V#I?)OopVkGY0fU3Q`JrWi9} z7cVw@u)HG{R0Ae1fs*0Mc7=t_1ac?RXoTd3Y0&4YE|s?^dR9emJg?q)dR|7U8trR@ zZOaX`82h+CQEC2@L&%Vs2`y*5or_sH$%-}2#H?f2+Ap~KpeY<$#kalrC5 z-jn;m-XI!L{la}y&N-s z%?3#J+GN{<@BRp}%^+curc>#^6*|66lTj2D@9iI|OesD#?q-}VES4ZYcq%HRwqSn# zy|yAp;I$j&25WGV@;=9F(vR4_l!v7sHbzC`3vnLYuF$c-$onX*Wk#o|aw)^k8vXF3 z=CoCccnG;I$6-QyD77S{*kf;6^;Lq8odhlP5AJI0&VONl&#sHi6*PGd`4(_}YC^Ee z>xU~5j`53mRu3h;Wvx4e{XJ2)YE>Jb6_V49yc?Pr^XCta5~>A*(pYno&V`86osER% z1LR^M23~_e?QB?Y{yF)zS1NfcX+?A*ao3eD{#m3Zkpgp?$QQbhh6nxO3apfmwSISp zoq?$iPzVw4O*RlQ-;=wjKQQ7#Rm`P7%Xjh9JE#nJ_c~rhFOiQgidg!LFD2<`t2%g5 zGb)nEu)lQfSWTGZ&I-&K1YBpK;RBIHpe z`?D+6xxr#~fO=V}3VopBXQESCZ}r*Z1O?NmBjIT?j4|PNcmh}EtA9ebK9u)<<8=YE zzj&d#D(!acO(M>n)tI$GJT*H!JzE?n*rObsu9~Yj)3i1tw_#nV9q|)x_LhhDqg`52 zM;0x~d_&zN>8BOrMcXZn&BznbzEPSrPa`k2{BM||&)3#(LmgR+# zp9kD9>JCQ*`OZg$kaczJb_%T?_HDQ?CuXXQme7{egrXB%i!R&{zhs1-Q%)&yYjrlA zD+w(JceKL>i_muUlR-=9zv8X;oRN)veYrkzGUy8=uSEAjjTE&t+<(J4eidJ3hzXaq zA7LZimWlDqz1hB|00DpiBoL4S1ONiy1fYEaGJpU;03ZNu1mpk#fB--M+6eRk1ONg6 z0ca!e1Rwwq00=-E0R=z+AOH}6HUdh306+jB0Br>N0RjL4fB>`+7yt+W1ONiiMqm&i z01yBOKpTOl00DpiKmghZ3;_fH0ssMMBk&9$01yBOKpTPQ00DpiKmghZ4F7)+_!j^R Bg^d6J diff --git a/crates/core/tests/fixtures/backup-data/0/9/20 b/crates/core/tests/fixtures/backup-data/0/9/20 deleted file mode 100644 index e7a97c9e155bedd326ceb0d8d9c813d9f910e9ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 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 F{0q4jdawWh diff --git a/crates/core/tests/fixtures/backup-data/0/9/23 b/crates/core/tests/fixtures/backup-data/0/9/23 deleted file mode 100644 index ae522109bca0650cbc8c06401fd9dd7d1bb57068..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 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 Ap#T5? diff --git a/crates/core/tests/fixtures/backup-data/0/9/25 b/crates/core/tests/fixtures/backup-data/0/9/25 deleted file mode 100644 index dd9f68a067f274faa06f3b262218e4be8d700ba7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!`8(Tp0KoBJsKii5_e5LAknvEggs8eg9Z`22l|HI&LDki|TldjaQ54IQI#$P! zY-DwWS?Jsq)QZ(LC61_QsN1^d*-!fu`aIvy`;T}%Z{ZvKhvSmVXx+wbc|I?p@^@Mn zJU%Jz-;Bd?KUHb{BU_}p!h7v#%*2Ht6a}RuLr7i9q17@GUOcfNVu!P?ZS2mlW!}%j zkpZvnm_&1x?^P%0!kQ_3*I!jW`i>sk)MMCdbu708H_I&Ymo>F!u9b=m*}G?%aMXyn zjKYfS;Htp>LENnh)#lsJlo~wai1EKT)repJ?d#`4vG4ga&(6`h8u;Lp&kHRbSAMsV zjlrvjtb|AYnyI)RG2}byi@CgABI;`>qa{|YK_=7FtQS3FD${p&x41<~bbSki8mv}n zkb2U~tfLq?X=HCO=dM&3a}utZq%hBQ z3eU62)v=8z&%qkX4ImjN)}3`-Y47A;$aNAL>GhaNqx43@3LACSW0ztfMgPN8sosIU zf@VF&SdZtkO7{6bGYQcGnA-Z}-2}%OY&m^m&_`UPeb4=FdmXmHo{-Bx304Rp3~JAc zAA~OJhZ8R0Pr7dhnP+#>?!h@hzA&ZvG=>U(YQjWtRDF=9F8!g55`!u?9c2h@iJZfs zt`a%}uO<6Aut`UM6q?hb+X9mXyUtLH`fxOKmiy5GIv>BkS<*)J++gFo`N#5iZdN!C zl%2qo5egr8@x1Z=Zf#QNj)r=j>V=fya;AlK*eUG4Z1kpkLa?cU19tJnYbn-Dis{-h zi|x?Cro|$|$?N;^bJ$UmKwH3@23YdEvCF)6fzkf!NNK0kt@DrRq_Nz+@{)*BpQku& zEplDlIp*T#)XHYAAKj8Qvr@8C6jlFuV_1fqSUGLXxQH2c9Yd-#BMR5DsX|phJoWQB z77^Ujl1Gnl1w)Zo%!?bE58=oY9RlMmN4;@htZCZav@}8^HmD%gf$-M!i9nYt!pdmZ z(}uvSqO|%FYhd5I8dZBQ77znkLh2EbSkF-4v}M%L?6(;;9t&1q!Krz??KOCJOYO_m>RUPJ5`L8HP^%jSu6B&`C)vgu ziC)T(48#+WYjIPD?(r>QcAd+d3h%>e37Kwje!uj{q~fMfuTyN_9fHJM%W71UoIe`Q z(^t9d{Rnk>tP)6FOx|#Q@Ss75jB(#%kBg|74NMicj!MYP!wuj9(|9#h?S2aTVPVr~ z&uRCnZcf>ogdyLOnUOk}W{R1_>_@vGmiUhfHj`o^#H6{_M$}0#*+(=Mb%s(YOY-pP zOZuC9ztT;f`g~AfePm;S%1R&99*AH@4@n`oiR_O*73zO8{=UCC#QtJf{w9}*>|+Q= z(u6sCZPJniVSoTY;C~3{0|Wp9-~^z30vLb*KmZ^BZ3GMe0ssMk0JIUf0uTTQ00f|o zfFVEtAOH}6HUd`x0ssMk0JIS>0tf&E00PiPz!)F^5C8~38vzr506+jB0Br`+Farnx1ONiiMgR*C00;mCppAezKmZ^B5P&uU761W&06+lR2wVdQeEA6c3zSHD AE&u=k diff --git a/crates/core/tests/fixtures/backup-data/0/9/26 b/crates/core/tests/fixtures/backup-data/0/9/26 deleted file mode 100644 index 2d9d6f98585c99010147d27dfede4e67a8fe2bf9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!`8(Tp0KoBJsKii5_e5LAknvEgq;%#=J0x!6sPs{FOQ^b9ck4cyDvDxxQpf5T zl8vm6Fbka{R8T8c*OWM-qM>fH=h@$|{q+63|A^P~PMU3PL>-4vd?jO1XQ-8mWKZ9| zq`xTlE8Uf8&j(f3hS%q5ob*Bcfe2PKTMofb0R*rq`G%A4#)pgrT4dDk>;}CwUZeOM?$EI z%E^+*UFxCL3K8A{sbFG9symT7+9>76m9;*sxYhCD;xgS>`+~A}*t_B0HoisDBW5t3tE+_A|8xuQ+1-&(1Z{ zcE5i9TrBpzaOT-rdRK!GoO(Ln((%o2Sj8B;HfcFL@|R52wFtJ~h@bK0trAH;69qk~ zY8?uNk!G{t6;qkMv$M%BN@5sYM`*!n)dp$%0la8;#l<0)XjgHBH#$?_ps~|&#?td8 zf-f7>F3CBJQIbdYhVbsng|Q~!x=AW?eCO~yY_5TAM0pOzL}>uYG`H!j>q>j4{6eXd z(8#Dao-j>sG^xO9a~``Ei>U@2q{{UU^c6H;VUG5AJ*(uN|09zSEn-|-pS+XcG>s`| zj1T%sOSJEL+-@OZemN+riheJL&h}ykI|=+FTk_ z13x)#E;^z;NY|GCP)3bGm0OH3#Wp3*;ZWZaI)lDT_IKox4}UMbMvra_N*3)pLo4dT z(a~8Rhx_P!{N6@M8_jE-i|-a5&ELLR;WAKm3{yv_d=SJ7#`?SU$)Vdi+I5;2QijS| z*KNX1VE=}-n(858QiBHU_TpzTBV>`bz&8!BcMsTZ<(Ah{Ji*o~ zyt}3LAWFrXNF>~hB> zG%N=ui(5xz6z1Sp;UZIbEmZAZ3in}Q(@4)r_ljXo*_#BmU&-`v9ZWaHQfB6(eK1G* z2NmpulmsyeAOH~f9}%zy2ml1Y2|)V`+Z~+Ja1ONiiM!*#y01yBOKpO!(KmZ^B5P&uUZUBM*9)W)V1h#zv diff --git a/crates/core/tests/fixtures/backup-data/0/9/27 b/crates/core/tests/fixtures/backup-data/0/9/27 deleted file mode 100644 index 338a4ed468fb42371c6eea8d910573951850971b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!jX%?Q0KoCZA)7;3_nOMX$&S}5E|zu9)9PaDL1|1|C(Jwy$y0gA%5!NIV%2W1 zwQ(7T?T%e&oSQm~GRlR^(^ckSGL6X7x!3Fdi+laPpFiUL`k*(~Y$HVD%o)EcSE`-3 zIP#LRPv6$7bD*@L#~3*ZKM2jv3WqKJ8 ze>fhgF#6Go&~K>E$QWs;L9a(~Lk&{UTX_O=R$yp*#^2maf&fd=1G&}ovzalGB1i7n z881ufGDWB_D?j{H?D9q5+m5>E6T4yyXVnZ;yHqbhtfyLPG&7;&o z5~Ry{?XWZOqxJIHRHFK0nZrNkC3X{<=O^7|#At-Ij;TpBt7UggIWj&-V;ISJ?B{$m zWug1Xt)IIS!k?b^NK)^Yjer z339%N%AP^YE#_Z~DvRil6VLJO>O$_?R8vwJX}_GRFgo_z=MQvK-fHD-8xgluZ-MhR z$Lb${^E<&jnS_a+h)ei2&w4t(i`GNK?Vo2G&|HxYhUI&>TuHXiI3-z-v$!~?F3FI% z97fo~gf?=~C%P&r!2C_OU(#tkL=ZO5(W$1{ci1cN5khT}++?6wO|~#YJ&96XFpZV< z!}n!ajjB(@-69k?9gXK)$Gci|qNE-^&6O?LuPq;1G*fFNRk(h)oEld?0i(Eix>VPi zzLI77q_e%K?trwnjdE9@-0^1~HAx#MtYR*vpB%z-BroKlM*2-l_? zsynB@orwOH+8ps6Gt5`XTK%K=kT|I^f~nK8RaDYW6l3$rtDmriq~%$5qlhx2B(-Yw z7A~CS`*q%5hwVmKz1O5^`Z`)2SuqQHFqL*YGrKvm!#=Sau>T?i47Nq%vm!c=r#P?_;Gn1r^7gUQQdq_pr1Z!(Udzn4|8eM;(jYmY*k>oywZqaZ|$TEm-2P z%34<0XKgx5z`ArkO*`Im3Y-Y|VHDaI9!n`OwR_3+x0 z2O3~6@=+EQW8SN%zvyO161#@K%&iC<^ZpDjx}}+)g16QSA5E5@yN+dRq5ZoW0(fxy zH6opLG|kOmZ>~uMiGi9*9atf!)yE!hey8FGuap}jTaC2BauPC1Yh!{o@a^ZR#v}EU ziM1AVEL`JayFd5_8Xy1=_#Yua1_%HIzzIP61Ofp900Dpiv=KN15C8}O1fY!o1t0(r z00=-E0V+TMAOH}6HUeh>0ssMk0JIVK9v}b^00=-EfgpeYKmZ^BZ3NB%1ONg60cax- z3=jYa00f|oKnOqpAOH}6HUgml0e}EN0NM!900IC3fB>`+2m=TJ1ONiiMt}|w5I*`B DiHCwx diff --git a/crates/core/tests/fixtures/backup-data/0/9/28 b/crates/core/tests/fixtures/backup-data/0/9/28 deleted file mode 100644 index caf4ef55c27a9bf337f494f8cc76b0f19a2cdade..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 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 diff --git a/crates/core/tests/fixtures/backup-data/0/9/31 b/crates/core/tests/fixtures/backup-data/0/9/31 deleted file mode 100644 index 5439e2b4f9dc1bd0c933bd09456f116028b69d8b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!jX%?Q0KoCZA)7-Uy4O@5E_S>WE*72hv^oz{d78+2sm$Y$XbQ3N{Lm`Iuy(Uq zc{sD(vCG3aH#$#~QC+w^U1edi8hLi^^}0Xfe&5d@@qT^0+9bRrWE_2dEoBljL{V%B ze^C!3PdWNcSrs{~JxkE>$yhpYmrofkSfx?p%R?Sutt{!a$@_&fi=(rP1)+Rb@%Sut zx#U{i?t(~{p2`|?6dbY>`41ya8WF{Fd0geHhYv!7w^Wr@Ee+6vGNl+K#_sWXi`#JI zwl!YxN@~toQ*Rgxa4wHOk`!5#;e~(Yd|$D{AK~V(66ArGS23Ci#A?{L{toO*GeyMk zrsz6E0>(5q^}g^8+3SXQMr^fPrQ5n4-r#+_8TLFEsb4+qwu$^JOvm-wz{J}qp1og|AFRn47k}AHjLt#;-GdkTPp%bM9w9TZUm$>#hz(@ zCuLsRU~B4jYAA$eC8U)$#02kPdamF#C!5}1YtRov!{xRn$1dGL?QEGuaA(L1zPE1G zThr|VRwW~N8IaK$m48LDP2U2?m)VW?}T^Sw=e#fzH*1nT%;EzBa_ zMRVfQnMkq5BSVju>Z-)F$z~2}JBl8nmW0~NVChi;LweHwrr%(lGvHSC8_o|dOmoFq z{Z@VPLehXXLY6A|^i#3zS0itG8>7!2iY;7}5s^Itl?0xObhSlC3$JosVPiz=9omNT z(O^%oGVQhH!NAW(YZsESvd>kP|LB#N&dQ&8I|{MU2qPtJt!PSzaSU5GK3J|ENo@1A z@l0A4x!(I(lo0;(iW5m@e4TyM2G+>fbNVUk&Nuv|hA#VVw=MlQaF?8tFg<5?;as`u zz}bLYC#e|`n_bMzi>iv~?Z;kZnl@f8J6s=>OicO3r&{CmZ(mj_C%sk3**D4SsNVx; z>`pheefPVEULwvsdNwZM*Bqny_yNKY!S2{csv5yw*HWE*gihyYy3Yh9va(iImSiPq zeA`n9Gg!^xe(rjhlypw-jmVeer-BGZ=U7>D+Px-R0-qpcT8XV{;>|>T9b|Wu^s08O z@FmJMUB6Og zqp*z(?e4ywqQ>Kb;jW-EmgK;nIe3zyT}>T%<)-&IhQ@#1AEKe!x*Bk`wH8x<7GEGh zDKV81Cu;U-tjD~wjl&e$OI>A~{QxdEH&=tA7uBDIAZv>?HC zDhwAcUts$7RcynI5r!Y+De{rtPAf{x@)7e|(}U?En(&l+><;X|Jg8$`(U^>gzB4JM zbLs9vhV$H(SmFf`00;mCAcH^|KmeQoI00y%Ksi7FAOH}6HUbp@0e}EN0NM!900IC3 zfB>`+cnA;x2ml12jQ|}W01yBOKpTM{0RjL4fB>`+U;qRF0ssMMBTxwt00;mCpp5_% yAOH{m2tXSF7C-c5T{eZ^+ diff --git a/crates/core/tests/fixtures/backup-data/0/9/32 b/crates/core/tests/fixtures/backup-data/0/9/32 deleted file mode 100644 index d864a4598affc4254e047bbdf2db13bb26b4e6c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 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 diff --git a/crates/core/tests/fixtures/backup-data/0/9/35 b/crates/core/tests/fixtures/backup-data/0/9/35 deleted file mode 100644 index 0e59da1062ae73811e92bd9355f147b980ed067a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 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 diff --git a/crates/core/tests/fixtures/backup-data/0/9/38 b/crates/core/tests/fixtures/backup-data/0/9/38 deleted file mode 100644 index 80d2d49837605d29e6dd1ef80ac01440917a55e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!`CHO=0Kjq5fdS@id$2-X%Jk8crKHW7O3edP%kW5gth`0dyvidj?;|QTC1pJ1 zu{@^2rYsM14s9M_pytw69;-wX3qzB<)}CiS?+@sCzMuCW@p|4om3WSdbiG4Ii=uK? zX=6<5HNm=hMSoWyg7MsPzyAkA#kmxc>_d&^KYC>*^YX{1j`2xRXhXQRRurwrD7scR zE>Nx(LGALkc28avI^X_T7$5fNl0%}*=t^yxHLR7j>*S;An_qL2Tl(z!UAC|y(F?()O>9GuX%=V;sn8>VB5nhbk$%xT}!oEb0(9U?K&5b zRGqW7_D)uo&b2v#Higw69A4&u67uj?&D~xvoctf6Wm-v{s^ZNg ztPZ9>QhHfChChL_NH>^~osPZjR%GQK$0#J)VTUk02iNX~p6uuP53t>oW^SYHgndr4 zU6q@e_|}*xbG<4;ooP3cu8oRf0Q2QBzA;nzKcQU@x8)y=rdOV6s0`$l#xFjoE?y7YRPq z7e&kpAM!{oU(9snvm6(<#1gMA2`3p7%Y36qohFKC${k@(nqV0-$Ii^)OY9Yo<8@AF zz1w$-OB*d(XVBv+g6@*=mdu8fz5Kc5$@%4?5U#WM**txJvs}@MsLt_Q6?;8z{`S6@~XyYSye!Ynk$MtcWvD zjws3UqC9oHquk?zcClXzaHGg;Sna{oI@mWp_O%!0N~mFNQH|($qDlU>JN%a!URT9) zV*IBX-OlZ>mQzRCVdME2Y~8HOCg!hD9p?nWi?4F){AXRhK(TMjR~AvdZS@ZqYR?xE z=t?*rLAx&tWx7QQrMaits~*bL3MW%Biz$;EeyMFS9^J2{RTnmDHFSH`l|pjj)5}|; z19yl6mna(3Z3_u4*iZsWZex7-!cE-HmT@?HE@R32`t>F&rmf$)WDIHSG&EV>F4EAQ zK^;XYPmxV=^@>c%jnWoT-%js>bz$X`G(j-^*+>J-BGXCZ#e0tkvHFh&ZWC%qYWj40 zGj2PQ8Kjzw+s&%hqxlC7r2oylTJ5XPzCUd6W@KrWEzTLn55@5l1=?uYHOc#*N^QOz zdo|b^<#`~ccv(ip4DbK~0D=EU009sH2!IoS_6eu}1ONg60cazz8z2A>00=-E0VF^G zAOH}6HUcPs06+jB0Br=&00DpiKmghZr~(840ssMMBd`Y`01yBOKpO!yfB--MAOLLy z)Byqj0e}Fs5zqh#00aO6&_+NLAOH{m2tXSFEr0+(03ZNu1hfGH00Dpiv=Pt&2z;gp F{0kjlcs&3B diff --git a/crates/core/tests/fixtures/backup-data/0/9/39 b/crates/core/tests/fixtures/backup-data/0/9/39 deleted file mode 100644 index 8142d4e9d54bc0abe4aa87c71f11ec90eba526ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!|3A}t0KoC#MmC2q-KK`HrhwErw7_vD9p2K+!s(zB**^n&8NPZ>kom$$4qNJ@}*f^2rpE z@?(YlKbT_c8P$^`ZW2-~(j0DR5X)}2jH^T?hN^U<>8$~d2bl}~UIjn*Gol`zaZgfO zp07-Ggf;Ng4m~Wt_O*yv-|5ojy^ftmc;*&IVmy2#@;lmnhlBFm6*hFz<)X4HF%`5& zy`)oR)(xj`ThxW5&{@A6t(mguPm_(U-~R54NhaII&Ll8? z%{8A*?4u4)o%g&i)uFne>~$-5ak-*wpQ(`K@|?xRcgo^)k<$UB4XoOtSFjSPNIH(0 z?hi;hriBb8*q0!iK%#!OoD| zXIm5ILgZ-f%tbmZhMxEj7ft!<2k64qm2-+*iF-Zzb-vQvzi- zd86ZW^!_Vt!t)44G!$5UnJCMXDl&`*5k)2k!Siycpma~sm#AsCS;-$ zxUc z@HjNl`ThyJO9=Fa14aB?Vas3Etsf2YxRbbx8C{s=PkHWfL!&(q>Fv50;!9Cg@S3Rf zD%dxHu9aa^h4iS#*jglmXq}gKLo%J=e?dAW#eb?mwQNMyAKBXk8_q*xt0ukI(0@f5 zd7bMU+j+Svc+&d|grGq6UXJK!tbXvO^3+vAsX8vOujx1sVY5z(WFKU?>g>L3KqJ%9 z@|2O)AXa0%U)yU%S=ef&KB_}cJtBvZUQ!cI8%aQ@oUHbQUBhjz zThRnl8FK*_FV;D5or9KSL)uoJJtHMe1Nx{5#6E<^DA@*Ay__k#R8&9Ex!Li?@#@{D zseRPa7msUTcA1{~V;}qg0sw*k2LWS%06+ko0JKkF8$bXc01$vS0$%|H00IC3Xd{3I z2mk~C0?*06+jB0Br=!00IC3fB>`+Fb4<#1ONiiMqnpE03ZMmfHnda00DpiKmghZSONq- H69WGNp@(`L diff --git a/crates/core/tests/fixtures/backup-data/0/9/4 b/crates/core/tests/fixtures/backup-data/0/9/4 deleted file mode 100644 index bef45cce02ce7acab49ddea61985f99907e7db69..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!`8(Tp0KoBJsKii5_e5LAknvEgq;%#=J4e(VN2QOdTTpei?$&)YRTRbYq>j}w zBpX>BVHP@f1+`*zO^FbMIO3c=&;Ek_xaawP-hagFd3zp<3GeGDqKCP{AxMnj>)YB- z;K&m_JpBVlvw<(sIOS$m60Q{!n4e;g|6ul9sM7^uX}s%UjptR8TYL!Bu&-T=tGpKS z3I5H&b%+RzdS=3N#$uBFBjy5A_pDN`?Zm&);aUr9JQJxlw95x8{XAi^Jb;$ZZ^7D5alx1;!1{V9Ao{6HgU${SJI^ea0DbfcJk0It~u1U zV~JDlbyy`O*Ci?Fn--B+)EMGu{kdoCd0fpUiqv&^Xe4+O?veUHU$L(5HBMxE7|J zY%VpkZ5zmx{6WcjLPCs?INQ>IIte0qi^rhOkt^hh?%utLe~}(lxGGX!4JfS+ugz1K zX#=|b;f$z383Z?hwf$p(!53qn`kI36E{Eo=a|y^^x@ZJdl(XL|D~%VuEqFL4y@b|p z*isbm6e;_tbIE;AnSUo1%iXKg`CGnFeVO;p!GwVgMkou*NCy);RYR)e!aaEsfrNG^ zeVdq_A&cCfh9dmm-Zzcnsy?iW*M~Kc1#Z2qc={DBrm@?o$MRTV5pJGQ=qGPx#bB3+ z4cfV7nsPJ<*z|((tf0z(z5(pra`mQrFIDP2VhM3SJ622H`t|cyA~Bx?GtSRaJL?7D zl>y3uA1BIHesRbt%2^cQiO$f~Yv{0_F?WB1;7Uigi8GI)6=ab;L7WFN zp^OQ*cB0Z8*D);DI!DhYyeu1Iq|lF~n_6|$cBXz*e67%dZ=lr~P8g>(7?oRVGM_mY zi75LWrpWa4_vSZUqmOobysThd{38P&C1hArm$V!2FpVjrjSqNBinZ;#J!q@N)Z5{6 z=qTZG5ybVH^O6T4O9o;1E4Y)cdx1ByI;aofoIoF#%3La44L3P%DmE;{r-$lqerfgn(Mk9{q z?3WdXmw3Ox>gtecV=pik)+d+Ob9`wQ%<1Lgox;evv$Y{PQbNU)3H`F+kjp4itqD=U z&Z3A^e*ePP6CeN(00{gK5Lg8WfD-^G0PPc40|)>F00PiPfCCT!2ml12jleoU03ZMm zfHndf00DpiKmghZYyt!T0ssMMBftd+00aO6&_-YjAOH{m2tXTwZGZqk03ZNu1b6@e zfB--M+6e3b1ONg60cazz3lIPZ00f|oz#c#VAOH}6HUj$q0e}EN0NM!f|2qQz073?X AasU7T diff --git a/crates/core/tests/fixtures/backup-data/0/9/40 b/crates/core/tests/fixtures/backup-data/0/9/40 deleted file mode 100644 index 06438593962d157a7f27767cb3906c5eed716f5c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!jX%?Q0KoCZjkY=Dp?gi`;mYFXVa1|zo>mv862@e`B*Qc$qDEPHh|+o>B)8Yv zxICOa+_4L7&W%o38P$c$(^b}(tVZPN-0OA!#l3#t&mZxAeFTcV=9G(R$BBm?*Z}vG}xRvl; zkM-1(>2aYVzX#WyDogJ*MQJW5KmJtW_SL|f$Bl`Hw%!HzU zRA*_xn%JCZcTMrY4E3wjD{; z=BZIy!vy-n5Z6G)oczFzpXF)sk4|}~Yj&KiKJN-^$U5#NXhD2+)*tAS!U z!_o}hc~X7aG+Fin>6C3frU_2D5m4k3m|A(2;9=Q~mU#P1>)P^OS>3mkQuyL}_ZOb| zd=G8_R&hPFOwT56Dc7{KyQ{cykEFjN@(xeA<&~WIFeS|PbBQSA{CuQsuQTN?PGZoThib&Z+IWJ zM}#$df0vVisr2cS=*=QF6EWXWq_ppuu|Z1K@*gGpMCmOwCcJH$UHlj*YSA=?1KirOuT0y`UoUQOrH1H%e!TtVGr%OomstZN(QjO&=8VZKUJ{74B zjD+IcAj(Uho4RdbC_m5n$N-AAiqlM`*T8m#c~(bH6w~9I66;ZE1iQiuH)XGxLFW_` z3fy{?dFyJt;K-h4*t0^kWzD$XGWxGLvjb;(N4~yX6EW`h1yXoJ`$2_lZ>oLpuKM^@ ze7O!LthYIwgS1~E#<2pkJPjN#o6tyfv?_COiJaAxd`S9M&5d5FHa2fJ(uvJa%Ptcn zMXeFKPEm|Uo8Fxf00aO6|4#%k00DpiI00y%z)pYwKmZ^BZ3OH90ssMk0JIUX2M7QJ z00PiP;2VGdKmZ^BZ3M6Y0e}EN0NMyR00aO600C$t;0O=^2ml12jerwC03ZMmfHnfo z00DpiKmghZ-~a*u0e}Fs5!eL~00;mCppC$8fB--MAOLLyTmS+90e}Fs5pabp0{;Rm CBz!{v diff --git a/crates/core/tests/fixtures/backup-data/0/9/41 b/crates/core/tests/fixtures/backup-data/0/9/41 deleted file mode 100644 index 3680b4155801ba005e14cb68a48a5f5594bec7d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!2|L?&0KoBJsKii5_e5LAknvEggs8g098q^1l|HI&LDki|TldjaQ54IQI#$P! zY-DwWS?Jsq)QZ(LC61_QsM~DM-o>8(@B1P?&lgV3<880OyIX2stybU8L6`8OT!&iS zC~&o7oIlAn-bnOHhGZa~h+K=CI&_b33A5{5=2UneR!hiqi}U-XMSFSS^TUS?I%JId9(!Cw#cW`zxOG%QW*%+;7nsJY zp=$S2*pCXEMte@XS9NpB-X;wBmduRQ!8B9MBxXO^1+m0`P_UU46CozewKk$og2_Ij zv8Z#DN?DSJPhZks|tML#0%^~)e z!}2$|L}VXBIFcsJ*=v)QBnaQ+KOC1_M(Z|i%ky~&mA}`zbFEZl$lg86gri2pWfWFq2Ui9558`fDs5aku zuGHWeM~wg3sYd+9uV20piv7T!d47)8)xZa*oGr9;T>H&NHU_UAvJxKoOQzy_#E|c( zFXrlYiKwrkjFwon2ANDxvtIO!sZ8J9-QpG{(e*75YOq?RLF$1&C)!PRY1ld1MHu0Q z&eYav>~xql^LT~eO2)K{vW{Zpq>;VBoO@DX%t^RrlEOUKDLl_6SI0J@JO^tiH-KcA zSa;TSrM;JbDc4D8q}O96jnW$pD{RzRPh5(H6#WlVrFsYY3Yzs8V?CbFE7=$S$RtDy zU~21=cM}|Eu;uiLK_79E_C5D|?RD4&dqOS)C0HSZFsMB*eh|8>A5OS}Kk2>`WS-qg zyAS6C`NEXu(-WE*maIt)Q6*?v)qpk(E0fN&5|~%=LQ?!%|DjEbF0F6pzH*uj8OQPsg#6QA+A?Zr_Unuq zj|HnQ-~a)D06^eh25@=+0dNA~1fYEa`Tzld06+lR2w(sL00Dpiv=J}>2mk~C0?1qc8H00PiPzziS&5C8~38v!gp03ZMmfHnf=00DpiKmghZSp07g_y=ipevtqG diff --git a/crates/core/tests/fixtures/backup-data/0/9/42 b/crates/core/tests/fixtures/backup-data/0/9/42 deleted file mode 100644 index 36633f226166551ae23605c8b2f2991f8bb4bc03..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!`8(Tp0KoBJsKii5_e5Jqk?~Nhq;%#=TSwf)QR$w@8;e!rFAl+ZHdVqPF@IYhd5G zn^yZS6c7VjLhBJx7|pE2C#=O}r~8}*j{fH=h4$mXCg;nou<eA@Xm6yjAqz z%!P~^uX*dQ;Iur!)+)TarS|1Y^{pIqi7?82u+@VK*E+%y$ae9jk{2^%gK$LTYTV?3 zXM9VzL+28&!uOzBMxk3;I3PVLskkZ3=LFMt2QM?*vJ%~-L_os@MjDrVAE8c;G=gXg z$?L8U9yAzGj6HX`V-gyc?8)NR5gCO!_!YRw6iy3OyO+X!SlBeubJD$Hm{ay9VbH&1 zdbkdzn_?+5^U)!gBmI+#?SzyBF=@875p^6w@so^2ouXDMlD+);lK!FGuk=u+Js(h6 z8(yEManc9$*^w;Lpd5mq$o=?pq0u*E@B5oW9nXj7Z}5r8KBjmSU7WYuCNGN@zae}u zCcA_-Y}`^7@)0Y4r+3cllj`2hI4u8DmEOOKMViZk*Un}vY$!riR8BUO+@&5?tq|!W zkP0StxEk8UZVy@I{W264`09>1iLZXII>8XuOck1$Nw4*h(jwe4vxuN* zVZ&N2l^AsN%rfU`5wRJC71<$GLHz^RTNRqkx1Xssc*hare|4#mw*UR>=VGz%g)>jj z(z_aj;MC9aEgj$gVXGK}(+*vZi25y4buDtxf5hMT(pHJ2zlnmLRJ9I;!br1O@Q$fW z-`UyZ7bP)_t|7EwwQ2*jeFBf|dF9l8A9_eezC%^E9TMF+SiYEz!Q~dAGd| z)8L5DWuinY#1L0%PfPEIEg41NFXE27ZwFt^?xf#?^Md_hYIA8!4cz3ox#)=Y09{-D zLm4#&Rc64N*3)pMJwvV($QI-hx_P!+}=h> z8_j#2i|ZC1&ELLR;mR&MhN&Y|J_zCkWBuLwZqepXv$4 zqz17a;)_>PY*`bz&8!B%8Ys5c*uPe zsnLumT+OD5RsHxhz~@LpbXQLqJ0y+|YdpM;;sCnQwX8jeAl}Q=S&3kvg%# z1*uN>w-!%C00IC3fWVhPzzQG$P5_($v`@eqAOH{m2tXSF8-M^n03ZNu1Z)8U00Dpi zv=P7p1ONg60cay&2M_=V00f|ofIUC}AOH}6HUbU+0e}EN0NMyR0t5g800C$t-~(K0ssMMBj5%Q00;mCpp5|Tiy`nI%W8jd diff --git a/crates/core/tests/fixtures/backup-data/0/9/43 b/crates/core/tests/fixtures/backup-data/0/9/43 deleted file mode 100644 index 15dff47cae5a51c8a833a708f5243e28ecc59378..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!|3A}t0KoC#kj)`qy2n($T-os;Tr4^#tS+oCN@JK?GBXWnYYMUQB}z+(Rc?=k zUA~-sxnq|vn{!jAjoPR#y7J{J3zOBzch@~0_e1}~JwET(AMt#=*s~R<8b40;*>JLJ zhIUCd`}RfjBb}NNCp6Y$^<%PPa(csVE!V=xP33yja z{hc?wqnFTZeN;qmYa|!$vVtYE_GS5-Zo6Pf!BLSDnS)FCtd`UR($|{mxFw#2O_#ZT zLIFLeQjkJi!}OdWSPZwkIVG?oqv1Lqr|ofy7uNn~%@-lGx84G{D?*gDhUWKaiv{|Is1z ziJ1vCXSkJ*T0PE*H_bq;LzT3KX7lnvBtFh0tcJ z-~UwZ^Toic`_0J*H>Z|PYpKW{i7{PdteJ1Kwj>xw>n{yhzD9fV-`VRCjjEn|Y>N8e zxDcC()qbe;_{X-wd0hAK&@LG^8R2MXWtq(C+?v9(p%HavNz{&T?|m7weS1rO?xQE( zI}yOpZavLA>kVt>>g~T*bNMTAhM?Q;Zt#lTOL$OW1=%(*L^g55r1v1cC_v*v#a<|{ zzIeQra$kWxTJ79??E03bm`rNcFNf>Q_y6|!Eu)NA`i1Lbal{xwL>GE`@uguef}-vqw3g}ZrmE$1J8R_KFJsj??<_Z){2?cubN z&|65)dM7=*)j^f7?z<;ENl5pZFK>{i;J(cKposF#ym)~54 zZACb|)n(}h?ss{zQfA#;8=N=g_EpLDgru&){tFv1)SZmUqsR|rRZirF$hd(MD=KwZ zhgy_@Oyf*0WDR4KEQ7Yh$4xNi$gU$Jo@M?E59!v2^JX?)5wrS>=d0MX8}Zk$o*tZr z%nh=!>A~^o;so(t)w6LnKmZ^B5coeJ5D5?fCjd?W+9!Yq2mk~C0?`+I0_H|2ml12jX)eg03ZMmfHnfh00IC3fB>`+hzAG&1ONiiMt}qm00;mCpp8Jn HCj|ZldG~mM diff --git a/crates/core/tests/fixtures/backup-data/0/9/44 b/crates/core/tests/fixtures/backup-data/0/9/44 deleted file mode 100644 index f1994014a2be8aabef0fcee06de52b5e76d37e7f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!jX%?Q0KoCZp=}O%=w4HKIN9-AW7A~4B+S@|&6MXNd1?uva(gWg zmxnXk9lJbiZZ~ye%BU{7Je`<_snv))UH5w3e{rwh_wz@*U!RKkY;Ot2eST9W_wSPP zQ&0))g|)PC+#pN6Bl>wWENkM(sR{d1*R`h%!@!((du|9=Lq)4qmGnCixA69M?8emH zlBuPU*`=Z=fv4=%Y~^x!Qq$+f0V8%s&FB%~KIehpA(Uk+vTVM9r&;^Mt*Ed~xW=lT zDfWp{BMyagzJJE{3Ies|KoY)GV7O~KEu%#DJ9L|rn9>}7(o6T7>fOOeFV~e&ACjt; z(;i8!hkYCDS{FW5N{w!#H6a-|tNe_clIbk}OR_1M{pVVv&aLQ{fJ5!DXZa|T`bn=1 z)L&#n&m`&C*VpPpCcVBu@QPLM=Mmzzh6i(X=L)fvYUp5T`)LlsdJ|7(ok(-lK5$K+ zLZG7NQ%BZ`X>IYoq8UYX_xfK+D4Km1hY^wsd2$E`HKeeoqrN-C;XsKwxGDONiS z^+{T1)YgafXRwak_oh3-G^<|Q?G5>8zIHYhul!hR_m6S8)vW4iz!3?ahBVhO(5JDw z_s7*4(Zf_aG1RUg#}g^b1D?e{4=|!1U2tP6_g}0_cZ9WacAR`vbNw4ZN=uK+L$6Jf zX@o~!Ioa6VTQYwKF7+ekyD6-x_-kd=1+lf1$Nl(o)mE+NZ(B5nrc%>>39Q#W`P-NG zG*jNF}CfDSyth`f}X9}E-A+2Ez7X7?WWCioI@$^6t^OP1c44Y@~z!mwAd4xPbD)o~) zwPhR0CWfeov5G{4c*zTdZKm0TGBBaor^w+1y{ZuBV$z2ax_OHlyRW`By>B8SaRp7z zFI;oEF4aC5*^N^bn&#y79D|2_y``;(ghM@{w`=5k{>&pW)twufvR2XqUg4?)&-x>D z;hn3*#Lh-svmdEQh}NjqL>_L~rTZyv#wmexfUqS#A9J)o#J`A8#6-d@CawxC2_w(k zGzKyKe2n4SyPRZnmHVJj^BsIQ9{oK@L^+-n{-8mG|QL*nHx~ zCu|8}ZK<+@7rH1Xh}DKlmd{oP_1)cq?MIruRi&whAB*i-amzNCMytKq167h^-tpV8 z|H6|;duX^EN}q391wa5G01$v80?_~ga01{2pnU=qfB--MAOLLyVgLdF0e}Fs5r_o{ z00aO6&_;j?5C8}O1fY!o4Ilsz00=-EfjEEwKmZ^BZ3N;00ssMk0JIUf01yBO00f|o zKmtGjAOH}6HUfzN0e}EN0NM!90RjL4fB>`+U;qRF0ssMMBaj3T00;mC{;vr93nkru Ap#T5? diff --git a/crates/core/tests/fixtures/backup-data/0/9/45 b/crates/core/tests/fixtures/backup-data/0/9/45 deleted file mode 100644 index 64296f1caef22dd0919c7074ecc4d9d2c6095b89..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeIy{Xf%r008je&^CuWbg!vA9Co}^Tr4{0X>}f^QkuwmsXR9%3^PogA6i1F++J(r z@^IMh*oDUJMklN`%7x3*iFuezBhSvgUiUZL>wfuu-hafqV;{S;8^^)q`fhDtity`; z<*jW01qq(7*k81Ah3Vb%Xa{D3H2ff^$Om5Vt!R-eM=Wa14y6k#1gG7jc47a*k%l`X zuo+=JXDMZK>FxrC^W3&r;`L0zA)}({^Xrr`tca%68v3RlMjdy&IBr$!u>LAm=R(HP z!Mj{qf5BQsdCbGW`#390dTr7H!Q|r5%wj<>*Ht_+Q@&CfSGTty)TO7eh8=l_?Swx4 zDAOin$y^>=rSkjx!2#QFf%jHw(Xg)GIPB~EFy;t3 zyg0*)@YeaBQil)H&0*EwgCMVDv;+~WVPE?=R9%}aCWbag)FETBX1OW%1XEP6MDe89 zYOhkaZ6~zx{D~IW>s*w6^@Q6N>dz1z*SNmXFSD!tCfq(lunXnOa|nKO&C}VctNEC6 zMYK;}%OwWFd>a=+^Q1Va9nIDX!xK?+Nkf~yl;)_j?bA}`waqF`UA~55a8_(;Sz~0t zF1Gt7L36BmHm*@W1cQ*o*es76NbW3cpSeu3Sof6)_JmkijCdkyDbE=;h+S-n<0F#=MbHd2-%`S@dr?H2>@ zUo=IWI~-NCC?le}d8)A-Rq0x*jut`nvf}1|)-=YZVc9?-K&9fHI z*#_3cP&o6Pb>}NCxv|r}%WYeK3gMDd8lvayE|_}=?>pz4>m)TN;<8Jac{eJNt8PH>9_;qXdJ9W2uJYvJ26L9tGB(F%|h( zd;K01&&j>Lwj=YM!4v&=ecc*1&J+BpdbX?PIKcs!G5iXVFIq%5-NV diff --git a/crates/core/tests/fixtures/backup-data/0/9/46 b/crates/core/tests/fixtures/backup-data/0/9/46 deleted file mode 100644 index a860b151ef5d652039437c613241b3a110ad6353..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeIy={wtZ008h{sKii5_e5LAknvEgq;%#=J4e(VN2QOdTTpei&b00;?xR?qG*}%& zvXRvhW}$OeP%Bo~lsKZIp>FG*XYcoZ&-43!{)i7%1aZCYyyRiXia{9u3huP$Uf_+) zF8V__H_!*BvXH`5!%a_`3Xf?H(KTh?S5Tr+m1bj1k!`UHSk$-pu7K}|zV;l_@$W@9 z=uzzfMB(mpw32=-9i8EJe26Z<9c-1g(>yjgxE{grg55h*r@@L-m?}c)JwJ{=G0>w+ z3fa}ttXIF3G*ZdBX%%_~`xiEKrZ*Uq9584bSGt~L#iE$4pRhUhog8`$GK{=&5I2t* zBMG(pzixyP7fhTNbPJ6SUPZ_{CU0NNWst_R_bbc7%e{-Sx;o_g*bA(st?AXRY+r^2 zdv>*KwdAIiYICgn8L;#AO_*)`BQn&!mY|e_!nDc_JpfucL?_~(F+$>eTNCOui0myMgE~j4k|())_b2{EepKbENP9Ms{dQStyy$JgqY3F1 zw0_f$qJXDJ9X<-c+;VPS(2%EB_z!K7~0kQ%vgPrgJT zq0>p2>+M&O`~|K4{PG}VJ#GaTQ93}zGB2Q_ZszCo+vEC&C^T#*Zp@c5WG_Tnz#?t%#Z#R2?udguP2uZ@KqWrO_jn5cjiVt>mp=KYu0?^G-1R{5-w8 zQ2&DhkeF;46p8#iTfDI=}6RQk;#k{t0j-AHGNUG{V4?k^BL>F5q|_Hnd=EV3_% z`#>g?H3ipBR9fIUhUHmj>)C`?W?_sJ29ZottFHR)l(&k{6}s?Ej0VFgrf;ynu;m(ayw~Gt73bm~>G&ui!@36IUcAFBrjju^} zhtFoBgsK0_1kykPAOVm7v=c}N34jDZ0?5&#K6I{^|%03-ksfOZ18AOVm7NC4Ui^l~~KI#=f!1uC->k zphfpRixmxmH#0Rm1ziR8CwT)MeovUZY$>oToM)tJ35}lGb9YXvQrSEdpKyV z52f@36xCkHQ(RI$h(~=-Yz_S(J;+r|-ukofG$+0(G+m)>Kf9<4&%xySY;9m35!M$e zO>DmfF`-><;L*w@hKHbZ2X+jh|3Q{48|-d3Cr7TBpsS1yXY^6|XPl#UVgJJy4R=J~ zGD8LDlZ)pvocVP7xowfywMEQHL`Ku**OSL^Lb7~Q$m<$d`nav|F*KinwcJ^U#bv^#9^OZG`$T+?pP3cZzbs3b=A6IAN!IRlft(~bGFd2Tw1d@%WJvW?2|I~t(`5^^qSXwxUTA?keVw1jbGlclcRt|k|h9h+8M7wNx? z>$*l%A8VM6tJ4j}z-3m3C$8K>?QR=}vM19QJZ{~pv7ljn*2II#h7N+E;zpsm_Bi|$ zTz;5fjH+DE5Z^AW6L##j&sye{zE0^4q>S`e!Avt8)JH#_4-={Vr0?=ZRhg7F)>w<$ z38w|9B%=1ynL1?OfUdNEXg8VOdhD_u{rUcd3AQM^$6OG@kMGq)NK?fhe=fB8YVdt` zeZ++$QI8g-BxDy)DVC!oS!>eLASzvy+Z@!G##q)a>+SPbq`osd?EA@J{ZbNM`l;OP zU!5YO8QDuWTRuJlVW6O?5kYP{7Rl0%@t3KFky<<~&nB+)IX?KMFE-@GHM@A}u^X%u zOISU9-?pHAEowjwS;0`%O!8-QN{J9e4-U~jtb`oO}{!Ss|Zg_cUcMtwD z!>Io1lcP0$Nu=ao-7D12{r+W{V&Z$boC9N=wwir#`rbrC%Xfdc=p+!(5i`-TzvURr z$MgmY1F=103-ksfOY~jkN`*kBmnIMegp}C1V94NPJj*)011Eupq)S& wNB|@N5`cCB43Gdw03-nI1ehQJkN`*k+6k0{1V92H0ca<{0ttWwKA!~s19jSnIsgCw diff --git a/crates/core/tests/fixtures/backup-data/0/9/48 b/crates/core/tests/fixtures/backup-data/0/9/48 deleted file mode 100644 index d38114cad1ff84788880fdb7dd9f4ca716d99e6b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!`8(Tp0KoBJsKii5_e5LAknvEgq;%#=J4e(VN2QOdTTpei?$&)YRTRbYq>j2O zM@v>mn1#+=L9JL_Q{sq~(`;T}%Z-&8Dga)iurJuIv$BlB8Ul??X zau!8+qBC^$DDC#s=I*Z%Jn86GarQy9f-JH-h*s6j?@o|)e7x+3Zvd|+&GP5RBo-we&k#vqU^VyBGcX1lizrWInw3vw1RW? zj|_a2kYR0o(ssPV6sC+Z*6%GT*1F?%r?n2#V296PqJ+yu5SMFDOYVg%8ie65;Ep

z_`To?J*p)jNx0(_t*{46M`yYn?4k2;yX(a*G>J35N!A)asu z5@T3>UHbtXd8CJDzUOLEb|t8jZe}InS}}q7DfamHW{-tBTo9JV+aA_>B-!6%&$D$;D&<;_{HYF?nqgy^NQIg?%LC+}ezF#k z1JmE8*SODFeg&uH@;6uDolUi`m#c1Oql*PmE(6W3WVps5){kftXDogpT{-|qK(542 z?7PJ^h1#|+a?8E;tEA*QB?W!cA`*+JA)d#Wp4)h-nWp7Ps)8RH&NooI==BhFe5e*c zn@?JEx_`exk7Ve!!xsp-$Qfo#d=O4j2NVuZw*W(w*kh~zCEgE~d7kSDr(_ay#Bx>w<-L4Sq6TCTyadkY7X=32jDGBG47NKTnzzm)AbXgi5p+@RPK&HGUi7-) z{;2dKTA#A1DBvkl_Ce>I`xoWi8?jj4mr9+#L}5{Z#&HSZB! zk+!|P!7EH;00jO60@VNkfB--M+9yy05C8}O1fY#TEkFPu01$vS0(AfZfB--M+6dGG z1ONg60ca!e0w4eo00=-Efd+s8KmZ^BZ3HL)0e}EN0NMyp0RjL4fB>`+paBE`0ssMM zBR~fT00aO6&_>`TKmZ^B5P&uUuK)r70e}Fs5oiPm00aO6&_Zo+ zrn-YMDFOYqaYd`iRxGmF>Jgh`-^roIAj3#&dvUXv5u#AL|CVs|9O2#j+9V2WkNr1 zIOH;lRBJ{QtY%R}s(yar>v<$5ysM*#9_9&$ATfr|u4_MlBaij)^tW8i#yyFqDL1py zaIKiY{1kiqTeHVPT`mYq;~fucJim(E=0m7~eeYsi?X{3k@NWsOM?_%MGZP-O7L)An zu@~67pR43Lj{Tb)F15kNGm#24^OlFmzx-q^A_r%_O|NmExBLoD$>ndY!kI0#tt-_x zv(d$ZD3`%DS2A4V2T0(6ZOWX>tgK8-`rlg>6T0~+| zQ;6pYruQ~pYPMx1vPr=Y4d)xEUG#d0Iyq7cpe!V;bkVWoqLlOS3ZktB& zRPR>D>%*GK0@q$uKKzar)6{L$V|k>o2sh6t^piKUVy%{n4cfV7nsPM=*z|&mte~oZ zz5(pb3iak&B>;gh0Dt@q06+lR2)qCY00aO6 z&_;j>5C8}O1fY$;OMn1C03ZNu1Xut8fB--M+6Z(51ONg60ca!80}ucR{C@=g1ux}> Ac>n+a diff --git a/crates/core/tests/fixtures/backup-data/0/9/5 b/crates/core/tests/fixtures/backup-data/0/9/5 deleted file mode 100644 index f5a6028cb0b2d8dabe6ea641e095b3928eb4d1ba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!2|L?&0KoB}iAoH0bWgN(3>go_N=j$0v~xt=aa8)Kx@Ej_yf?Tkn|kE<_fa2sruz|<*h7ikub((pxKp% z)HuZZQEXz3#V@8wlL%z=O3cK*TWnK^ZTljx%xk|=O0H8<*f%vip|By?^BC82hbT4E zv>ef(;D<#D4Ad@pJ;EFxs*&jPiEB;|9@Obk4c&IQqhf02eG`Sv!%}jy$SX*ZNrDEZ zdN+ytFu!5A>$r1SKdav0J&a>7h=J?1Eo>Mb6P zIZZ2YRgU+$_%f8MXOI6*`~g3)Ghc zuN_R-_#l)rTt+&G(xDn$DHrA`kO&~RIqBO(Zw*@H{5lx!|LTruBwzJjWt={&ktTHg zRr#ZDnb8ehM%|W&3JXZ{^a4M5Gb{E=vDko}TZSo5gN#qhFUt(9Aocd+Z8S?-5m=y1l)@FGye-TtjKVs#W^wdw#q~SNVlOr$}c}lqWV_ zSFgU^e%jpqC5kT{)hf<8h*FS6cL(zB%7n1Tk=hALvwX+U9P4a7o3PR>oRLBwnq_L$ zUel5CPVt38JF%WwYdCJ4T5nWlt;u=pT!>Ki+fSD1?(4~Gyv!Qu@_1IxJ@M^%=>%;6;N_;zhzy=k0*2neB{w zNM3*sOl3BOrAC+-GldUp_A@kPKa|j-Fr{Y0EX0P`Sv=+kVms-_L|=O@<>0UUtBlAN zQX;(LG`*k)&%kE59qeIq3A^h>Ep(4HE}>I+BzNm(nNwfM5lj`O^g$3S813!Ur37zj zY1XKpPZ}&`U$Y81hW(%A-egx0E}7J48(X-NWW}bLtsHW=_HA57G&+>Jx*I!#8>Wb~ z_`j)xCC&l_00IDkFA#x!fB-lFa01Xifdha5KmZ^BZ3GSh0ssMk0JIS}0tf&E00PiP z;20nP5C8~38-dRN0e}EN0NMzg00aO600BrNUwyrvy_Sc| z!`Z_fyU@7ZsM&)y4_$P5Ix!DZtC8jDy4UOejDFwGAMt*D;>b^eUHmhbBuDQ2DoKrf zdd@RlX?>yYk_)Vbu5t8f&8_b^napnY9-npdDTH@nS&W&NFMqC5R~#5xuxSYaXo!I8@sN(ws>UTNnmiA++KJTFx;#C>}9u4l*6rJR`ZQ}go2Wm zecb-;@CP;W?SB;#(zV#7TXsVZ#3xB7(4Tt`b z&`CO+8yzI4tUW6|$WCu3LsmrwVaTbId$ zp2*pmsASr_I(rN&rD(Os4mHDa#}AwscPjBvKTkC|p8sz9Z4RZsc!gS#QW*_|0zk{?8P>2+7DD+KA|u^jG4 zP}S1gh~#?M_aPp2k&`9l*w%z5WGdFS=<;3uRBq5k*`&=OC+P^gbzBU^KiflZ z&vhdbo{XBy8eR>}ZcPg4oK{pvuGSfv@(eVi3sQ5+nTZjbSiw1h;aKZz8q+)mgHXBJ z?2WvI-dwjKu_kjDg0Ea@cBZ+7uE+;;ZM=oU;$#LtTl&4w*CpqSwK32e@w6ztO!O9djTt2@N|5sp z?PASI3)VxC<$T}51WQ&RauTNS)5XR}E5D}j1q8lQrS9+ zm39*&g3c+;)d8bvj0@wvg+>IN`r2_v*hee%=`5V`W3A)AW@WZBs^`ZJ@No%9D{W(= z1WK26Vx4J9gi1dSAn*ku@C+aT5C8~3`ve340e}EN0NM!j0t5g800C$tAOr{i1ONii zMnD7*00;mCppAeSAOH{m2tXSF2|xfK01$vS0(}4hfB--M+6X)c2mk~C0?`+7z79a1ONiiMqmga@FgSgA8$H} A3;+NC diff --git a/crates/core/tests/fixtures/backup-data/0/9/51 b/crates/core/tests/fixtures/backup-data/0/9/51 deleted file mode 100644 index 6683062413b32e33c40cc7c30254fedaf8bfffbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 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 I|8E5T0XyP*-~a#s diff --git a/crates/core/tests/fixtures/backup-data/0/9/55 b/crates/core/tests/fixtures/backup-data/0/9/55 deleted file mode 100644 index e1860e7f9a41ed59ecda6249013dc8370fdf856a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!|3A}t0KoC#kj){iZq$(McucrhbWT`Zm?X@XtcS|?hBRNwm#j#XmJlnuJ(k(! z%dzc_UA~NSqw_tZT)2EYu`sn7nXlJ99``qNKYiY>KjQg#Q7luU3$wgQFJ11bwE835 zoK}K8Nb+)4Lm0UN_Km+2=iGE5IkG;c8j*lE&%Jt2G(+{iBAyo8d@4saZAEfV9cq9* z&qbjtrrb7Ae?{mYPwXAvce5gB%Iym{FJJzC9^O`8`Q#1f>}?!f8ROsE5Ws?4Y!V`9 zo@q{+2X5*{5y`0e)RFbTwE8%&mRV`pxpj^XvQ1k#JUbzygc}>Ojqkij(wV4#lgLF! z;NWt5vxDdEV752SqIlEPMc-@JYHXPffvb`s4Kvs7k&=c19pohZFkEGnXo0CzWJ<0V zaR=JB+uqpSE`5>S8%7`NuYy@+y6TL7@QM~||7h$ntffKDm}scQY+Yc6YNlXzu-FE) zpwP~YznNFq0YJ;n?Di&H#tc8^UrMU>R5hmc*BeE6xze)rJpuDY0$d*ce0WMovQ zP(6XKE?sTZ*CnZ+R$d>{oyFPJzBf_|QDeNa-V^lEL~$mSAp2Nu{f|Mh`JDXOsUspn z48lZJPdA3vx<8hKq=d+|qRGv^cAhEAeaG{E?n{V#deJ#aw*N9G-40gAQabUJedlXI z3b);{!)+5i19#0Sjxca>7tKG^=sg*j>nyb(6K)oj-MUa7)zw2dTV`H&{()&ta4I?N z7oQ646Tf}=NG;{Ha?Z{Pert^qob_p{zWLkVJq(hG*qFKagkN(^7AU=817Qva-_te2 z9Ff*q97`rsaKn8%IGLTjvhq$=oFTA3hOmHDn)dM4BBV(H1~YxWNq*{x5L}LpZEcJ9 zxNFc8giJTNNmIO$jMhhWT##PUixUmQtul-!Wj^uw9(lH&6vl15Bf1+Ubarp4YQ6Ew z=rOv5R4b@<70peEM`RJp!TKJdY(&#Xl z>EsQe8FA#fv+4l0hmX~NTgpntFkA+NYVS055isA8TB5$EhI>nB8-ElXA<*xAHXkP*EG4@2)0Y^<48sk=neOCxhjdEtWN;;}jUa&cny zr^P-b^D2Avh;Xk%pZ_4rtPW8$e~YJ9{=@z7kWCHMRcj+$zf3h2g?D&-+UhzSwPi~Z zzLa8X61_%HI00PiPzyu%w5C8~38-aZQ0e}EN0NMzceqIFr E1j}w zBpX>BVHP@f1+`*zO^G8a8tOKCp1q4b|KImTe4g*dO`YY{m(^L2W)`@H2Ba9S>ZYZczr zT=QzB>UK7^SP z=$jUiSkxHed4lV`OO%>zUWsf}@WaCS25P!qk5MN_Y5}x`q;;o<59{?PhHkr@F)=ms z{>h@25h=Mj_*J;j6hQ-3vzN?yRM0rmebTj}pI!Pke$c0Qdbk#*oop^O^T{@lE%~F8 z^@M~NDRH)?0d*Wi@fMFkouO99lij_06aS_>sBl%Jy%{`9;3-n}Ugv`Q zXXU+Hv3TC+N}Ye?3)PqTZyZcm_+W&xu#9vtxl=WyN-o@!FA+#;cha|s*&edU{dp+D z|MgwdD4y#5s(5`^6II~G>x##h7%`3AMm?5C3X5>_j6y$oGb`3=iP)f>Tc#;jgM?2n zD9;M24Couc-!4~gy7OG6-XoS2_lsk-i@PLmNaMLJcr3Q-g^@v>zJ~6{t1ITnzLJ09A4u643E*F z)W)7;Eo=Y;00IDk{}}>m00D3U-~^z30w{n0KmZ^BZ3Hd>1ONg60cazj4iEqc00f|o zfCfMSAOH}6HUi%O1ONg60cazD1_%HI00PiPKocMU5C8~38v!kV06+jB0Br=c0RjL4 ufB>`+&;bYl1ONiiMgRj400;mCppC#~fB--MAOLLybO8bY0e}Fc5%?D?n|MtC diff --git a/crates/core/tests/fixtures/backup-data/0/9/57 b/crates/core/tests/fixtures/backup-data/0/9/57 deleted file mode 100644 index 5885e2ba1e0cbb3a26182d9efd3fd9bf353d8e42..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 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 diff --git a/crates/core/tests/fixtures/backup-data/0/9/6 b/crates/core/tests/fixtures/backup-data/0/9/6 deleted file mode 100644 index 203b4855ba5e2017601888d0c4c4ee5f9e2e0240..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeIyc{|&8008h{jwI@iJ<--NWIPlrDV@2}&JlITQR$=V7F1oWyLBH;6-BW;sbh5v z$wpR3n1#+=L9JL_Q{sq^3Z#3*WhE{Jz7OrK}M5=yx;^%b?7v9rV!jABSL(w>+=ht-}AkZiJ zMCKc=R^z@z)3m#JX@qucP(i8#@s0Uop)OaXmC3HB4Uu0(ZS^J9z`k)csrFthAO*C9 z)FUHt8d-^tSxdHhf*9AKRyQg_^BC_>wv9ItzmOplNFbrt;-(JW<6FY)I+wW> z-iOsvsBTF?zx2qY;-*lqQ(WI|qSRc=YE+Y=KNi6^RKMu`5OaF09!OhE-f+Huzd@g3 zWdjkvf=8iiOnd z2fHA)u(ORKOdIA$s?irn4*z%QSM%woD5O)y5Qls%re%Xaa&2i zOQig*?m3T-D*HF$@Vt*zy8kE?X{_*HIhwNYAxITrS(y-Wms)5wD#D8|5k%^6Hn5G| z8Me&(c{noQjGO zmKj%*gwH6f$PTUw>>tG6tk7t_^;EUNGmaGhi&Kr{wcpM>6N!B%m?=F+?`jZ0P(LlS zbbR}}jY14TD`X`+^4Cn2^@t(gQD38r+a=<@#wcBhYHbRIk!HQ<8B>|QySv3JN@5sZ zMQXxoRR?JY{@iFcg{5KVXctkW7dBH*zp>L{*23cjk|z_>F3vuRQItdX26OMohOs6Q zI!Vg&Jg4wHn_PX{i1HkqvEl%lX=dG7*Om5G>A7Mjv5`@4G-;CFXk1~V#eU>cETZCn zm@3;l&{xoWi8P32)zXztdiaYp^HgGBLsx zBFM|N(vkU{EFkN~t3K!5~50w4isCx8SAfCNAS&`v-cBmfcs z2|zo6Gavzw07wAZ2}pnhKms5EXeS^E5&#K+1fZRO6i5Ih01|+90@5G>kN`*k+6l;j x1V92H0ca;63labcfCQkOfE-8wBmfeCb^<7n07w8N0PO_iK>{EFkich?z`u__cuY)M!9h16zng z2N|(h(&#r7klXBE9gb07Jyc=pOkT{fy{G6cZQU*%=!v@_)NJ@OkH|Lmt8dJjKX+gh z$CEr(CRmwwF2tPbY``_`Cl*Q3Ce@~h9rf$1J~3YTrV_UhR=Q76cNNIQXW&{Y3Fb0> zN$N%zejI4hk5P&-c5iPA($Ku1eyQm@^YwW2_e2?GPgY{2hP(7f*)B1=gOX*^wN_N# zix*?_W0pQ)O9+P9$_`Q7jE2x{G*B{kv^q+0a|Py#aC)of=m#HkdvO_an=uXU8?#kB z`R=fkRoH(bNFzOTTn*pGGBt2<@WsUDV zH11UzV0gr`JDBrs!&M1)plE?t$*fAaj`#B9H)O1rPtFcc%@!p}Le!&Em2>5%8$Zve zko@z)k)6^_eyZpJlv^vJY`Q>XTJyv8#Q0@%lLb#l>_eRi1BLUuePruJIBLb4D1EBM zG#e~iMq+}hn48n7r8$wrr$N_@yP^@H0rPR;M175*okXjHeH$H6dwjB#mefXXM6ht~ z`RA|6Ut~p|RZptDKGz^SSCU!|Y;T7>&PO@aO@uC?{vz9jobG%6_2s(QiO?_LqGJ8~ zX?S;A{himf#|p8PM(F6i_QL|W$1M&KkTEb zt$uV0AF?#3WsbEsqgRso2^Q(-wF03%H#VU+^KbrH;bBM7Ev3_&hcgo*b*|D&!IZQ6 zY!SNinh!sf`F=I{@Y+@&9n<0b~Z$_BSwpZHm|Tg&F>x8#GCS- zd2WpT=xjKef!BSk@%+cW+SaaYqCxZv|d+uiSe z54TSvVCYk+tY7n--!S_~{UpC_?<*}x{zy;D+Rc2v_cXVcx;}Rce5<=d2s9IO07w8N0PO^lKms5EkN~t3pnwEG0w4isCqM-W zfCNAS&`uy3Bmfcs2|zmm8b|;n01|+90(6i7NB|@N?F1Mg0gwPl0NM$pfCNASAOUD6 ya1tZ{5&#K6JAqV?07w8N0PO@$fdoJTAOUD6zyt|^1V94NPJjgx015oh6ZjW8LV_&- diff --git a/crates/core/tests/fixtures/backup-data/0/9/61 b/crates/core/tests/fixtures/backup-data/0/9/61 deleted file mode 100644 index 366ae659e73e9fb820af59b45eadc97ab8a717a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!|3A}t0KoC#M%x_nrF%@}%VEcZvWrFMd|RC_Qz^}ttcPTVhJ>jZTahR&AtblQ z^5yd7u-&l>jdN2cLmTSC<;$)zV`??>-F1)0{R{Va+%KQ^>yLOoUb67Cs+^^zcd8Pm zz~vCi4pwI+=B-kcv=Gx*13|PCI;aR-F4n23GjPH?>;Xz;nAV{yT~9MJMn5{MJa3dJ zdXC)7w3t#IPb%=wcM3?ZxQ=%->q84Y{W|NruDmqAZ`Mg_5;V9zch6~ZtMs>*-aJvN zZAn?nHhR?8Thy{&IMfq%eAh7wUlve9A6kCO6* z7N>OkFg{ndmwE=i<4#LezAaR;w;@-HBjab%d))D@u(adgBJF0mK$?Tz2w<)&dO zyd*;HcZeMX%(tY@*zZ`;fpYfx@5KlCwDwpQylWe;q?f?Q<%O=V;tGi?3uW!R@Oe40 zTXU#z@l<6{-`!1^HOk_xnxP(k(v4*&EIQcN+wRI5s1P0UOWcC}TR`eqPdq+5w(kg| zRFUN;;(94Ir1HRray}iM#F<-ROyVVMt@fB_jWE`f$B8Lyk^9Qi6yxLB?{?l4u!r)O zE6S3~qiz$hj-2}R9U|Gn=*&WXw7^F?K2x?>lG^ZTe!zs2SvBS%-0eCLJcPDsK@}^m z@wBVIza1U1fq*YNn&Spl@B}p8_5R7dmyzgACz9}m(!Oa$uX!xgt326(9#@ndNP6LQ zORFmw;Q(l?w+fLu|z6bkv_T>%4khI()mVN8M#(tVA8Fx8J&~DENxDR*uwXoBNNVH6L{8Qlk^cHFQ}%jIi6T{ACAOH^?$JNf3An1GAG-bFq>yNQMz=@ zHg1(EJ1nY~`4{J6Rfsw7p4eh;aDJL6%@Je!l0~$BBa|vr{^7@BmoJ82KWT|Sx;wFO zK}ALP3UyNWI?CmCV?&b8NzJuk!#6nRruXI=5!w|m9e0I&v|KrrPEdWUcKqA4#CAsg z^q7Z;5RbBi8yUv4yQ~vxOp+tidU4c;LCyj6#Q~p!p9WH59-s51sjM&5WH`fGxEhBa zSKatZKyU7Gd*r)e_6q5pTS77Q@)Ie_5&cI)^E{PyRKnHb%4=tq+&fKwT z3{R&rem-8SfB4tW?`hLtYvyjB`+ zU;+dH0ssMMBftU(00aO6&_>`AKmZ^B5P&uUmjMC*0e}Fs5y%1v00aO6&_*B|AOH~f HpAq;62Ec>? diff --git a/crates/core/tests/fixtures/backup-data/0/9/62 b/crates/core/tests/fixtures/backup-data/0/9/62 deleted file mode 100644 index 0ced4d2ec409d9fee540d732776096b95f88546b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!`8(Tp0KoBJsKii5_e5LAknvEgq;%#=J4e(VN2QOdTTqRob+_&-t`x=cq>j}w zBpX>BVHP@f1+`*zO^G8a8tOKCp8W&+bG%<|SQ6Iyr+a=;Y zMshk5)mjt^BgJabBdRiWcXx|dl)x~!iO_)6stnQ&{J4>>@=L=`kG3*Ol^4 z@r6PszL8OHIBA^PXjEaX$Bey6l>ped(d8oX|Tg*Gf~17B8cm?=Oqt9mJP!2S8ylY_X2NZcG4fhxq&_~ zmH8B=8g6RBRCrW#kgh5Fp^O@ZDmNQtifoBpz@omzcLscy=xfg*9sN$eL62+;NEGfm zM=R>X($N`iM+fKv-2P@s8_i>bgX_g{z0Iwo&j%w>?qviHhMh^5|7vAQ~xx|j>B#m%Xe&1_$W1$$?bz({~>)HP^Bl(WKyqhVu>7u6pI5PLI_BXp4y(PLCfq=ur&a z_Bi8WYUTq|#jT@Ka`W)(aG`0O2C8;HiSvZqG}?38y{ey8_9kw~r(|ZN4yK)CE;akn zHjpj(gOc^6gcu=VuC)<$5=8M9k4BxNR?3syz55dWqCBc}Rir&1R9YX|SfH^}2XzOC ztjHl51TUWR@kg@37vt~yn}h8xhZbz|2*^IBXgFPzyVoWwjTgNwcsMS-jMi`5Ruu3Q zDSxMP$^Db^{+$>s?^Bh|-||K3EBx0ECM;|)LRnZwI+)a@8d5Ds^yEtf5;~mpZK8LE zE%JUE4)=d`-!zh^`mj1qAJ$A2xb>K>&gO7XqmO0e}EN0NN*z1`q%U00f|oKsrDGAOH}6HUb#{0e}EN0NMy- z0t5g800C$tkOdF`2ml12jX*X)03ZMmfHnd-00DpiKmghZkN^Sz0e}Fs5y%Ay00aO6 z&_*B+AOH{m2tXTwe1HHz03ZNu1PTBG00Dpiv=Jx-2mk~C0?o&W#R3Ms?AZhbxv$rV)9%?)ADqqu=-QN4#Gj8nfLpR)9_jRqMr2Tm2lo zQy2S>-1?^dbMoH{#U#PUkLj!*n8*WztLU&LU9)4m0kZiF-1R!^{-!x3NcoD50f=PWJFtBNzl zj)ze;u&P}$;m0Uta-hkpe!paY9aJbj*UrAK&G)5y@B@^}Fr`ITzLsKYjOjY7JZ}^y zeTv+hX+Ewx5r4}o-`+cceVyQJ+KZ96dbU-!UwL76-?WWfC$4dN>XK9E%=5y@Z~B+O zEuvPljk<~H ztIdO>4peQ`{}?;v7*F0q+UPhFbLd)|=mJt169L;bennzM8hPxhJ&2QuaK`V-xhYt- z+n@wKkJv`UeotFVL04m)P-;%;2E^^UB5w)C)P+$QY*yo*LVX@qP_uMfRs zCd*UGb(>k2D|}lOqEt*g=j{r8j4;U5YL0$V3uBBQ^dGk?a9MejXnZ1je)~-^b0~kA z%}OW>FCyC6a;np|Nhjw%p}lNth96LA$6^Rh_fPJ+7x_hn~Qb<(HOxnn55WO+Zr)^5f3tJT!pgZ(6BXbfnOX_1oHwoS6$OdDL zZ<6Xwqwq+zqt(8!8`#ZtD~fQEG3$5fQmsA5DQH!}`snmN`~hut{K3D-@< zZsGDxn8D%Qng4Ju@&nC;_hja82WBUP@*J66Z-O+r&j_W;P`v-S(DAF`*F6oiV>{#S z%&DlDZi!B!NJqKcY-~u@IjOliY&eB?s9P}82!*p>*zO4aV6k#4ji~xiVf(L1vGuh2 z(eZ;)A`NAsZDdFT2z=fM6axeR0ssMMpFjyf03ZMmfHndwfB--MAOLLyN&x}@0e}Fs z5hw!)00aO6&_F00PiPfDaG=2ml12jX(uJ;Il*EKWssS AkN^Mx diff --git a/crates/core/tests/fixtures/backup-data/0/9/64 b/crates/core/tests/fixtures/backup-data/0/9/64 deleted file mode 100644 index 8cac68927155229967752e9140ecbb9197a5ca7a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!`8(Tp0KoB-p%OzK-4kscD;W>PN=j$0v~xt=aa8(f>k2{D)w)~v(X>TTEKiEm zRXJL+I>Ib;?h0zf>Y5TqR5a9W_B{I!_S1g&e%^n?>v;VoO9YCHPxS3UYXft0KF@a`R|I+PcayZ}HL(dZ#_VsBK@1#R|Su=>4r!pt&G? z>tx2k1|!tOgA~rq0EGwvj(A|r@UZz=p^Xb_- zuUKN-E9WYiE5CmIOg!eJNXCgNW?S7cIOS-jq2-6)Y?Y#M+QAE95x-=pEr<8{4*D9O zUoVpKHBr=)rs|N%tW=v>ujul$&CNAIK_biOGC~VheYTge7la`*Z5dyjBW-0Dow6X%SGl+j%K9n;G*G*KN7C47JvduBD3op&am?-xk+2%H_ zHEpRMR4SEQ@ibPg@u+DU&7{m$oBPnUP+ZM_H$}d)rz@}i0(+>#>uEXf)E^o6C{g3; z+N8~RrwL3cYoymlMzVR!<92fmrp^JM!$ygfi6bsnpOD!JnKuf?1+R&)GVR@{k& zqK$&c+M|_zMRG#86)0URXhC^d(lozIQXF-k8lJ z1~dfMA|f!FnF)_Mb4iYOxwBmTqYB05g8;hIg+|y&CQ`X-#(EF=r@w+#WZ&es=~bRH z)?dLHkA&+>@b-r4*NfEa+2|q>lv`h;I|Z(_kM$?n#hFT-OP3?yh{&bbv0ab2hEV&~ zd4AcAU8<~NyNrlmT0~+YJ;eJE({&3kJJqllNmuqq!-Yl~=Wjef9qwxo7_&($F8A)$ z8IX-Vws^ym8kRj{g^h!*KG<>CzG#?T@-Dv5w`gLZ2Bw>A zDLeVuK9DQ(T-A0|T9TMJ)ks4f1d)BDVo=8^cfWo&y8`0^kIoeFBvL0e}EN0NMyt0R#X700C$tPz?|O2ml12 zjX(`R03ZMmfHnfP00DpiKmghZyZ{IQ1ONiiMxYKL01yBOKpO!XKmZ^B5P&uUbbtUr z03ZNu1Q-ATfB--M+6XWK0ssMk0JIT!2@n7X00f|oz$<_NKmZ^BZ3OB80{=S#{{X8w Bf;RvF diff --git a/crates/core/tests/fixtures/backup-data/0/9/65 b/crates/core/tests/fixtures/backup-data/0/9/65 deleted file mode 100644 index ec8512326c5c29438cf311b83dd29631a9424707..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!`8(Tp0KoBJsKii5_e5LAknvEgq;%#=J4e(VN2QOdTTpei?$&)YRTRbYq>j}w zBpazK(KK}K3Tnmbni5A;G}LYOJo^v!Q-An=-hagFd3PN%m-Vwt-^LI46i*G+!nBjk zrKUgG2C^l8QL-MF5F;ecv^JoQf=J%tF{o4I3VEWtcTeKqqo1Y{3gG=eJ1-D#7R#*1DT+#i)*MC&(f zDhhatl)cwE=l)rF_eLz1_qkH%ANfM{CH@-+6BafYp)4#T9Zc+04XKg~_vA|i5;~mp zZDO_tEpmSwjPQSb+cb)&dbcWGAJ#+`xc0i@;diu{#xA37%R_|)xOqmQpS+nBYo$bN zz|Jkxl&e9&rWcfF1yu(0_G53Bt2fxwR(yk#muV zvfqA+Om|;Te$yrTNSDXc3eMR-Gw@MDhBb9b+wl%lm@?W}zqh1V`;Ob4_F7E69X^MS z5-t}(T&_7Sxfil%5Qe{iJ7V4nypqMB-i31mePAlHsdP2m#F(k@ux3A1Q}$yiIT}@F zHcS`U5IciK{fK7-{FLNt&mkWCQE-JC)fSK>+)#~KI6 z6dcLhx>4@bS9%0fMJRpb$MHvdnYzS~EiKJj^>fLCWvr`Kp~tZQvT2^|3dW=a^x4K0 ztt4Bq$Yv{tY>s^ghZ=(nBdzYn&0vO!LT&zU>tRW=CeE|E`Nq3%B4iy?HqJhx5l3=% z%8J8Fyq{oobx5_bXIS&=6HDtkzBCK=)Kc+QVPxIO+MpaMp<>d6e%^4EY?`xS9>S5{;8?W+mZTF@gCh_V{;Z zkA*s25SGT<9@cn%CArmyP!0Ru#kk6AKA+&<99)Npz^G>?JZ3E<+23Q&vvp4@<=T(@ z8yzmS!p1U@3e|I#2gtwtWGx~GroTn6MdWbqcR12WYC#^Z%zhAFMGIZPFjEbq5_e~VF4ok_+!Y{*xCUF|5 zn%!j1gM!B4E`R_);7cMv0|)>FzzIP61YQ6H00IC3Xd}=95C8}O1fY#TD?k7s01$vS z0&M^RfB--M+6c4*1ONg60ca!80T2KP00f|o039Fz5C8~38vzDD03ZMmfHnf100Dpi zKmghZyaWgU1ONiiMt}(r00;mCppC#QfB--MAOLLySO5Wl06+lR2y_7i{x<^u0&z2j AVgLXD diff --git a/crates/core/tests/fixtures/backup-data/0/9/66 b/crates/core/tests/fixtures/backup-data/0/9/66 deleted file mode 100644 index 32cecc6c1febb99b694661d638822a47e70b37f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!2|L?&0KoBJq7p-q?uoXJA>+}Om6Xn0X;(zuaa8(f>lRd9t-E!rri!AiY6b*i-ya}Y-HS4hAd zp;oGsef;}U|EAoj^wOj~=V&bttjy2^SsY__G%Jp)iWH{^KmJ^7_SNwF{^oG!laYn1 zViLNKDHlVR6K%DrsSxF^Nbe4-%wtU(*EOa5;N|a(PWXJ%-oBcM7k{cU`bWJ)e?c=gx)If=Xg`T!DCw2Esbj(h?^3}pyqMtLo7Qn+-P_g4rm$wJ)aBmF z2j4Ifnz}7|?DjS05VkobLFzX4tfi;&TxaiGYmos7pIuy$7giP0&%s}-&~Lu+M5nhT1_@P(+D-*U8+=#RR*7#{5bVWksG)npM7LBUS)+(Esan%wx2OV#d=tm$^7}Xo4K|u-ZQoJX znfXrhg+>Rlkx_3xYMIq&QQ=@Hc<50I*ACjvQ0-y&6*Zq@4t4uJsT3anGlv)_V_sXI zwwdfYfh%W>aQv0z+qb-Lwb$VqoQe5NjBEuQdA|0j(oV#@SrqX!;h^hA=!Luv`fY?L zGytYEoypWAjEz{!@(nq3L$wdjsPUL`8$J`hCVvc%`JUJj@6iL|ra^mQOgs;I32q#D?_o|e_uXNyR| zE#dXZ7@U4?$|KfXn#&!*tibql6{`IpxXJZgD{Leetx+>$w}<{KNbOQAck=7(8lM@v zFA%f>$@&tatEKkkV)eEA*fMF1C%4s$iZIy62az3`+-~a>w0ssMMBftd+00aO6&_;j<5C8}O1fY$;06+jB01$vS0)qenfB--M v+6eFg0ssMk0JISh00aO600C$tFa!_)2ml12jleKK03ZMmfHndn5J2Ex5z>aG diff --git a/crates/core/tests/fixtures/backup-data/0/9/67 b/crates/core/tests/fixtures/backup-data/0/9/67 deleted file mode 100644 index d3795b9bf4970acd7e90d2ad218d3ca13ddbb3d4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!`8(Tp0KoBJsKii5_e5LAknvEgq;%#=J4e(VN2QOdTTpei&b02MsiG*BCv~ij zA=$|42(!?+E3P`~tP)35G}LYOJo|mW_j$gb_aE_k-f2j=ih1)xWM{3xfsMrR6K?Fj2bvWhVjy_6#9ha(_YqbCkrVj6<2 zTbDQ`9tY(TGVS90-pOI{`E^0=Cz!6gc!}ADmGC+_A2gh&r*hfjG3w+<#gDo`Tz7c* zuttZh@3PAt7Ev+nnaFP(l#rQ&Uxf=y;?z);dkO4ExpjjbC+#b`8AYS9eO?7q16451 z1XGEbPuBh{@m~}y$HYVk@w1J!sN(>#r)U)F45d_-`%Yu>U}f(p}RiN=3;R62A6>BVhD%PggLuS(vo=LoBRjEl1pga z+AVoLccJ2GtqZQ7758pMW4WKpwEmIJQ(fl0u`^;~0}+aXQj&qBHszplnNWA0m_MP# zLDwp3yWcG9xBf8S*LRI0xXSm-V|8Km6uuj;OCNtnkE-i1=rli)TZEgY=K08)STI)$ zMfz-9(u_H31Z+xfNqRt;Uw1F|c8O~Jo##q5ZqbC8-|Z{JZ~Xc73!$hF{HbSWX>B!p zaLVa?L(30;S;|J@)B~48!v08ATnp{<8uZe?yj39TWgw#^R<1!N(~~R~+#*YpcXl?p zdGU0;>j*VirBW|---i?7EW6n65aB3{a7U+V>(sW|&X~HsLU1J`n?+fNk#f?=&H&Cm zsbJ<9Tr*x_j%y#1WtpjC6Z~V@ z`9g|52Z>UhJzY8VR~SPbZqG~E=ijE{BLws-tBE_Yc2k&Q`be**xJdJ^%f03*OpOgb zlYtT}5kg$8JS)B*w4@h;zl1w(zvF)`y_I$!&hhtxDa|D@RB#g`#)5{k42P7 zRI$k*Lugav92WH>zSZw1qPH!Zboh7fHCjZIA5pOF3^lI{OGBr*9PXpDaeEsDO;opa zHm;q2D0}->i9=7(F-#eu@R1k88}4q`CIxM4s8^|8Na!zSUbhH7f&G`&=wwGACeg3Q zIwpTL!GcLKSv_L0ZClv1C}aqEZ7*gPGe{C>@*S;#5$B8?=d^PS_uhm_+b3?Ge?lh> zW$qRigcf=}!)j}htD?^_7d9rAH!{8HW~`~@g6+KU>eKap8FF0dq!Htye!tTYQl%b| zyP8fFD*O4FxBHQZ;I5WDdVnh!gv98-ys7yJjy%@EGsZdUwR>W9lP)HOp&C*CIf=IT zag(P4ZB7Vt!yPwEJg=tZc2eeYyg?y-qO-5C8~38-WRc06+jB z0Br;&0RjL4fB>`+m;wj@1ONiiM&KPl03ZMmfHnft00DpiKmghZ%m4%c0ssMMBQOgP z00;mCppC#BKmZ^B5P&uU^8f*W06+lR2rK{u00IC3Xe00*AOH{m2tXTw#V-(ne*u;t Bhi?D? diff --git a/crates/core/tests/fixtures/backup-data/0/9/68 b/crates/core/tests/fixtures/backup-data/0/9/68 deleted file mode 100644 index ed1afe518da785a46ef024ade0abb409c3d3a6f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11520 zcmeI!c{>|+0KoBJsKii5_e9%Z$apALQaW>`og?awqtZv!6@sd(b+_)LsiLGfH=h=JM{>ktAB0kS|f~!@(FV!&RZeAR&9TS+J;((hl ze=gGD3bQiV^|Zn9D=5vrgeu6_t|pb<3;BeArr=sw1X?3A;W=|L$>9-efu(m=q0o8~ z(BOEj88Vg$M^w#Q9l`(fm$!@@nE5ij%46Q@GblBezs-SmHdVh_t-PC!A_*g12b$d| zP|ahEKhZYMMDj|yEFMdMb7ChC-Q$`gg*+(H&nms{SiuN)lY)lfuG7v{gY1&`@dLi3>7g2kPO^o}%tyOGmh=zGHsewfgv8nAdgMtE*+()4 zd5%)9Nc8aON&JiasN7A7`l?@fZD@U-%1Z0k>kDT_4amWG3G9zQ78rgpy42ekY=1d4 zZ-YmG_b|jGXyV+x7I|5m_-*0CQQ2jbLH)Lpke68L2i;2^pH%km#A0}#Ds=x=EYw)x zzjHKYVuE2RqH?mq#16HPN`-JQzEmKg&Dp>PB%E=6mex@x1f`tKH?@89n~h>LRx5ZVEaI08m9_8z-(g>) ztJ@?=Utw!6E#t-h^pFs#W``2mahBH^s$4=O`C(m=`KT zPrtt1VaCGa4U8un-73jCiblx8yMwq7W#~6v{=tvio{g>4^!m2`+D*luQ5itJYSZxFaD8%ixM%a zu1(sFcbrC-(#QIJq$OJS+#j^opzG{$ISiy|nHcPP^?B)okY&R#+!gFe=e@uiS?#ok zP;Q_vM0GBep^lv#GZP)w>ZfVRZ?gKBE&ya`s9|;l(~LFnYS=n%E1>g^kITjT}F^C2M+x zv{M*ad$vBPKu##1GG$yg8gw0jt2e?5I9XJ&itk_ec^ylL?&&I_hIpbOaJ13u+d5C6 z@DqI;V*(%m5C91Le+VoC1i%S^6Aw0ssNQMqmvf01yBO2sQ%i00DpiKtQk&-~t2y0ssNQMqmRV01yBO2sQ$n0D=Dw GfqwwNM=I+8 diff --git a/crates/core/tests/fixtures/backup-data/0/9/7 b/crates/core/tests/fixtures/backup-data/0/9/7 deleted file mode 100644 index 62f04f631024130be4991f724dc3272f913cb57b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 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 Result { Ok(TestSource::new(dir)) } -// TODO!: Remove? -#[fixture] -fn dir_testdata() -> PathBuf { - Path::new("tests/fixtures/backup-data/") - .canonicalize() - .expect("fixture path") -} - // Parts of the snapshot summary we want to test against references struct TestSummary<'a>(&'a SnapshotFile); @@ -100,81 +92,6 @@ impl<'a> std::fmt::Debug for TestSummary<'a> { } } -#[rstest] -fn test_backup_with_dir_passes(dir_testdata: PathBuf, set_up_repo: Result) -> Result<()> { - // uncomment for logging output - // SimpleLogger::init(log::LevelFilter::Debug, Config::default())?; - - // Fixtures - let (source, repo) = (dir_testdata, set_up_repo?.to_indexed_ids()?); - - let paths = PathList::from_iter(Some(source)); - - // we use as_path to not depend on the actual tempdir - let opts = BackupOptions::default().as_path(PathBuf::from_str("test")?); - - // first backup - let first_snapshot = repo.backup(&opts, &paths, SnapshotFile::default())?; - #[cfg(windows)] - assert_debug_snapshot!( - "backup-dir-summary-first-windows", - TestSummary(&first_snapshot) - ); - - #[cfg(not(windows))] - assert_debug_snapshot!("backup-dir-summary-first-nix", TestSummary(&first_snapshot)); - - assert_eq!(first_snapshot.parent, None); - - // tree of first backup - // re-read index - let repo = repo.to_indexed_ids()?; - let tree = repo.node_from_path(first_snapshot.tree, Path::new("test/tests"))?; - let tree = repo.get_tree(&tree.subtree.expect("Sub tree"))?; - - #[cfg(windows)] - assert_debug_snapshot!("backup-dir-tree-windows", tree); - - #[cfg(not(windows))] - assert_debug_snapshot!("backup-dir-tree-nix", tree); - - // get all snapshots and check them - let all_snapshots = repo.get_all_snapshots()?; - assert_eq!(vec![first_snapshot.clone()], all_snapshots); - // save list of pack files - let packs1: Vec<_> = repo.list(rustic_core::FileType::Pack)?.collect(); - - // re-read index - let repo = repo.to_indexed_ids()?; - // second backup - let second_snapshot = repo.backup(&opts, &paths, SnapshotFile::default())?; - - #[cfg(windows)] - assert_debug_snapshot!( - "backup-dir-summary-second-windows", - TestSummary(&second_snapshot) - ); - - #[cfg(not(windows))] - assert_debug_snapshot!( - "backup-dir-summary-second-nix", - TestSummary(&second_snapshot) - ); - - assert_eq!(second_snapshot.parent, Some(first_snapshot.id)); - assert_eq!(first_snapshot.tree, second_snapshot.tree); - - // get all snapshots and check them - let mut all_snapshots = repo.get_all_snapshots()?; - all_snapshots.sort_unstable(); - assert_eq!(vec![first_snapshot, second_snapshot], all_snapshots); - - // pack files should be unchanged - let packs2: Vec<_> = repo.list(rustic_core::FileType::Pack)?.collect(); - assert_eq!(packs1, packs2); - Ok(()) -} - #[rstest] fn test_backup_with_tar_gz_passes( tar_gz_testdata: Result, @@ -205,17 +122,17 @@ fn test_backup_with_tar_gz_passes( assert_eq!(first_snapshot.parent, None); - // // tree of first backup - // // re-read index - // let repo = repo.to_indexed_ids()?; - // let tree = repo.node_from_path(first_snapshot.tree, Path::new("test/tests"))?; - // let tree = repo.get_tree(&tree.subtree.expect("Sub tree"))?; + // tree of first backup + // re-read index + let repo = repo.to_indexed_ids()?; + let tree = repo.node_from_path(first_snapshot.tree, Path::new("test/0/tests"))?; + let tree = repo.get_tree(&tree.subtree.expect("Sub tree"))?; - // #[cfg(windows)] - // assert_debug_snapshot!("backup-tar-tree-windows", tree); + #[cfg(windows)] + assert_debug_snapshot!("backup-tar-tree-windows", tree); - // #[cfg(not(windows))] - // assert_debug_snapshot!("backup-tar-tree-nix", tree); + #[cfg(not(windows))] + assert_debug_snapshot!("backup-tar-tree-nix", tree); // get all snapshots and check them let all_snapshots = repo.get_all_snapshots()?; @@ -292,17 +209,17 @@ fn test_backup_dry_run_with_tar_gz_passes( assert_eq!(snap_dry_run.tree, first_snapshot.tree); let packs: Vec<_> = repo.list(rustic_core::FileType::Pack)?.collect(); - // // tree of first backup - // // re-read index - // let repo = repo.to_indexed_ids()?; - // let tree = repo.node_from_path(first_snapshot.tree, Path::new("test/tests"))?; - // let tree = repo.get_tree(&tree.subtree.expect("Sub tree"))?; + // tree of first backup + // re-read index + let repo = repo.to_indexed_ids()?; + let tree = repo.node_from_path(first_snapshot.tree, Path::new("test/0/tests"))?; + let tree = repo.get_tree(&tree.subtree.expect("Sub tree"))?; - // #[cfg(windows)] - // assert_debug_snapshot!("dryrun-tar-tree-windows", tree); + #[cfg(windows)] + assert_debug_snapshot!("dryrun-tar-tree-windows", tree); - // #[cfg(not(windows))] - // assert_debug_snapshot!("dryrun-tar-tree-nix", tree); + #[cfg(not(windows))] + assert_debug_snapshot!("dryrun-tar-tree-nix", tree); // re-read index let repo = repo.to_indexed_ids()?; diff --git a/crates/core/tests/snapshots/integration__backup-dir-summary-first-nix.snap b/crates/core/tests/snapshots/integration__backup-dir-summary-first-nix.snap deleted file mode 100644 index 6d981dbd..00000000 --- a/crates/core/tests/snapshots/integration__backup-dir-summary-first-nix.snap +++ /dev/null @@ -1,29 +0,0 @@ ---- -source: crates/core/tests/integration.rs -expression: TestSummary(&first_snapshot) ---- -TestSnap { - hostname: "", - paths: StringList( - [ - "test", - ], - ), - label: "", - tags: StringList( - [], - ), - files_new: 73, - files_changed: 0, - files_unmodified: 0, - total_files_processed: 73, - total_bytes_processed: 1125674, - dirs_new: 5, - dirs_changed: 0, - dirs_unmodified: 0, - total_dirs_processed: 5, - data_blobs: 70, - tree_blobs: 5, - data_added_files: 1125653, - data_added_files_packed: 78740, -} diff --git a/crates/core/tests/snapshots/integration__backup-dir-summary-first-windows.snap b/crates/core/tests/snapshots/integration__backup-dir-summary-first-windows.snap deleted file mode 100644 index 6d981dbd..00000000 --- a/crates/core/tests/snapshots/integration__backup-dir-summary-first-windows.snap +++ /dev/null @@ -1,29 +0,0 @@ ---- -source: crates/core/tests/integration.rs -expression: TestSummary(&first_snapshot) ---- -TestSnap { - hostname: "", - paths: StringList( - [ - "test", - ], - ), - label: "", - tags: StringList( - [], - ), - files_new: 73, - files_changed: 0, - files_unmodified: 0, - total_files_processed: 73, - total_bytes_processed: 1125674, - dirs_new: 5, - dirs_changed: 0, - dirs_unmodified: 0, - total_dirs_processed: 5, - data_blobs: 70, - tree_blobs: 5, - data_added_files: 1125653, - data_added_files_packed: 78740, -} diff --git a/crates/core/tests/snapshots/integration__backup-dir-summary-second-windows.snap b/crates/core/tests/snapshots/integration__backup-dir-summary-second-windows.snap deleted file mode 100644 index 88efa041..00000000 --- a/crates/core/tests/snapshots/integration__backup-dir-summary-second-windows.snap +++ /dev/null @@ -1,29 +0,0 @@ ---- -source: crates/core/tests/integration.rs -expression: TestSummary(&second_snapshot) ---- -TestSnap { - hostname: "", - paths: StringList( - [ - "test", - ], - ), - label: "", - tags: StringList( - [], - ), - files_new: 0, - files_changed: 0, - files_unmodified: 73, - total_files_processed: 73, - total_bytes_processed: 1125674, - dirs_new: 0, - dirs_changed: 0, - dirs_unmodified: 5, - total_dirs_processed: 5, - data_blobs: 0, - tree_blobs: 0, - data_added_files: 0, - data_added_files_packed: 0, -} diff --git a/crates/core/tests/snapshots/integration__backup-dir-tree-nix.snap b/crates/core/tests/snapshots/integration__backup-dir-tree-nix.snap deleted file mode 100644 index 4cc57375..00000000 --- a/crates/core/tests/snapshots/integration__backup-dir-tree-nix.snap +++ /dev/null @@ -1,169 +0,0 @@ ---- -source: crates/core/tests/integration.rs -expression: tree ---- -Tree { - nodes: [ - Node { - name: "empty-file", - node_type: File, - meta: Metadata { - mode: Some( - 420, - ), - mtime: Some( - 2024-03-12T22:31:11.115831358+00:00, - ), - atime: Some( - 2024-03-12T22:31:11.115831358+00:00, - ), - ctime: Some( - 2024-03-12T22:31:11.115831358+00:00, - ), - uid: Some( - 501, - ), - gid: Some( - 20, - ), - user: Some( - "runner", - ), - group: Some( - "staff", - ), - inode: 12891863206, - device_id: 16777220, - size: 0, - links: 1, - extended_attributes: [], - }, - content: Some( - [], - ), - subtree: None, - }, - Node { - name: "testfile", - node_type: File, - meta: Metadata { - mode: Some( - 420, - ), - mtime: Some( - 2024-03-12T22:31:11.115939543+00:00, - ), - atime: Some( - 2024-03-12T22:31:11.115939543+00:00, - ), - ctime: Some( - 2024-03-12T22:31:11.115939543+00:00, - ), - uid: Some( - 501, - ), - gid: Some( - 20, - ), - user: Some( - "runner", - ), - group: Some( - "staff", - ), - inode: 12891863207, - device_id: 16777220, - size: 21, - links: 1, - extended_attributes: [], - }, - content: Some( - [ - 649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a, - ], - ), - subtree: None, - }, - Node { - name: "testfile-hardlink", - node_type: File, - meta: Metadata { - mode: Some( - 420, - ), - mtime: Some( - 2024-03-12T22:31:11.116070531+00:00, - ), - atime: Some( - 2024-03-12T22:31:11.116070531+00:00, - ), - ctime: Some( - 2024-03-12T22:31:11.116070531+00:00, - ), - uid: Some( - 501, - ), - gid: Some( - 20, - ), - user: Some( - "runner", - ), - group: Some( - "staff", - ), - inode: 12891863208, - device_id: 16777220, - size: 21, - links: 1, - extended_attributes: [], - }, - content: Some( - [ - 649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a, - ], - ), - subtree: None, - }, - Node { - name: "testfile-symlink", - node_type: Symlink { - linktarget: "testfile", - linktarget_raw: None, - }, - meta: Metadata { - mode: Some( - 134218221, - ), - mtime: Some( - 2024-03-12T22:31:11.116267198+00:00, - ), - atime: Some( - 2024-03-12T22:31:11.116267198+00:00, - ), - ctime: Some( - 2024-03-12T22:31:11.116267198+00:00, - ), - uid: Some( - 501, - ), - gid: Some( - 20, - ), - user: Some( - "runner", - ), - group: Some( - "staff", - ), - inode: 12891863209, - device_id: 16777220, - size: 8, - links: 1, - extended_attributes: [], - }, - content: None, - subtree: None, - }, - ], -} diff --git a/crates/core/tests/snapshots/integration__backup-dir-tree-windows.snap b/crates/core/tests/snapshots/integration__backup-tar-tree-windows.snap similarity index 91% rename from crates/core/tests/snapshots/integration__backup-dir-tree-windows.snap rename to crates/core/tests/snapshots/integration__backup-tar-tree-windows.snap index ee1c4702..6e8fd2bc 100644 --- a/crates/core/tests/snapshots/integration__backup-dir-tree-windows.snap +++ b/crates/core/tests/snapshots/integration__backup-tar-tree-windows.snap @@ -16,7 +16,7 @@ Tree { 2014-11-30T16:03:11+01:00, ), ctime: Some( - 2024-03-12T22:32:55+01:00, + 2024-03-13T00:39:48.791253+01:00, ), uid: None, gid: None, @@ -45,7 +45,7 @@ Tree { 2014-08-09T14:14:20+02:00, ), ctime: Some( - 2024-03-12T22:32:55+01:00, + 2024-03-13T00:39:48.789254100+01:00, ), uid: None, gid: None, @@ -76,7 +76,7 @@ Tree { 2014-08-09T14:14:20+02:00, ), ctime: Some( - 2024-03-12T22:32:55+01:00, + 2024-03-13T00:39:48.789254100+01:00, ), uid: None, gid: None, @@ -104,13 +104,13 @@ Tree { meta: Metadata { mode: None, mtime: Some( - 2024-03-12T22:32:55.218816+01:00, + 2014-08-09T14:14:28+02:00, ), atime: Some( - 2024-03-12T22:32:55.218816+01:00, + 2014-08-09T14:14:28+02:00, ), ctime: Some( - 2024-03-12T22:32:55.218816+01:00, + 2024-03-13T00:39:48.791253+01:00, ), uid: None, gid: None, diff --git a/crates/core/tests/snapshots/integration__dryrun-tar-tree-windows.snap b/crates/core/tests/snapshots/integration__dryrun-tar-tree-windows.snap new file mode 100644 index 00000000..a11e66b4 --- /dev/null +++ b/crates/core/tests/snapshots/integration__dryrun-tar-tree-windows.snap @@ -0,0 +1,129 @@ +--- +source: crates/core/tests/integration.rs +expression: tree +--- +Tree { + nodes: [ + Node { + name: "empty-file", + node_type: File, + meta: Metadata { + mode: None, + mtime: Some( + 2014-11-30T16:03:11+01:00, + ), + atime: Some( + 2014-11-30T16:03:11+01:00, + ), + ctime: Some( + 2024-03-13T00:39:48.793256700+01:00, + ), + uid: None, + gid: None, + user: None, + group: None, + inode: 0, + device_id: 0, + size: 0, + links: 0, + extended_attributes: [], + }, + content: Some( + [], + ), + subtree: None, + }, + Node { + name: "testfile", + node_type: File, + meta: Metadata { + mode: None, + mtime: Some( + 2014-08-09T14:14:20+02:00, + ), + atime: Some( + 2014-08-09T14:14:20+02:00, + ), + ctime: Some( + 2024-03-13T00:39:48.792257400+01:00, + ), + uid: None, + gid: None, + user: None, + group: None, + inode: 0, + device_id: 0, + size: 21, + links: 0, + extended_attributes: [], + }, + content: Some( + [ + 649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a, + ], + ), + subtree: None, + }, + Node { + name: "testfile-hardlink", + node_type: File, + meta: Metadata { + mode: None, + mtime: Some( + 2014-08-09T14:14:20+02:00, + ), + atime: Some( + 2014-08-09T14:14:20+02:00, + ), + ctime: Some( + 2024-03-13T00:39:48.792257400+01:00, + ), + uid: None, + gid: None, + user: None, + group: None, + inode: 0, + device_id: 0, + size: 21, + links: 0, + extended_attributes: [], + }, + content: Some( + [ + 649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a, + ], + ), + subtree: None, + }, + Node { + name: "testfile-symlink", + node_type: Symlink { + linktarget: "testfile", + linktarget_raw: None, + }, + meta: Metadata { + mode: None, + mtime: Some( + 2014-08-09T14:14:28+02:00, + ), + atime: Some( + 2014-08-09T14:14:28+02:00, + ), + ctime: Some( + 2024-03-13T00:39:48.793256700+01:00, + ), + uid: None, + gid: None, + user: None, + group: None, + inode: 0, + device_id: 0, + size: 0, + links: 0, + extended_attributes: [], + }, + content: None, + subtree: None, + }, + ], +} From 8b6040227998e4f0dbca0ce84d25561c707f3b45 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Wed, 13 Mar 2024 00:55:17 +0100 Subject: [PATCH 23/46] Add todo about TreeID newtype Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/core/src/repository.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/core/src/repository.rs b/crates/core/src/repository.rs index 5079aef4..d9261b44 100644 --- a/crates/core/src/repository.rs +++ b/crates/core/src/repository.rs @@ -1452,6 +1452,7 @@ impl Repository { /// # Arguments /// /// * `id` - The `Id` of the tree + // TODO!: This ID should be a tree ID, we should refactor it to wrap it in a TreeId type /// /// # Errors /// @@ -1475,6 +1476,7 @@ impl Repository { /// # Arguments /// /// * `root_tree` - The `Id` of the root tree + // TODO!: This ID should be a tree ID, we should refactor it to wrap it in a TreeId type /// * `path` - The path /// /// # Errors From ece73224a2240d7268bca410078f4a248ef1f15e Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Wed, 13 Mar 2024 02:03:50 +0100 Subject: [PATCH 24/46] add new snapshots Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- .../integration__backup-tar-tree-nix.snap | 169 ++++++++++++++++++ .../integration__dryrun-tar-tree-nix.snap | 169 ++++++++++++++++++ 2 files changed, 338 insertions(+) create mode 100644 crates/core/tests/snapshots/integration__backup-tar-tree-nix.snap create mode 100644 crates/core/tests/snapshots/integration__dryrun-tar-tree-nix.snap diff --git a/crates/core/tests/snapshots/integration__backup-tar-tree-nix.snap b/crates/core/tests/snapshots/integration__backup-tar-tree-nix.snap new file mode 100644 index 00000000..658a82e0 --- /dev/null +++ b/crates/core/tests/snapshots/integration__backup-tar-tree-nix.snap @@ -0,0 +1,169 @@ +--- +source: crates/core/tests/integration.rs +expression: tree +--- +Tree { + nodes: [ + Node { + name: "empty-file", + node_type: File, + meta: Metadata { + mode: Some( + 420, + ), + mtime: Some( + 2014-11-30T15:03:11+00:00, + ), + atime: Some( + 2014-11-30T15:03:11+00:00, + ), + ctime: Some( + 2024-03-13T00:51:39.490651139+00:00, + ), + uid: Some( + 1001, + ), + gid: Some( + 127, + ), + user: Some( + "runner", + ), + group: Some( + "docker", + ), + inode: 67866, + device_id: 2065, + size: 0, + links: 1, + extended_attributes: [], + }, + content: Some( + [], + ), + subtree: None, + }, + Node { + name: "testfile", + node_type: File, + meta: Metadata { + mode: Some( + 420, + ), + mtime: Some( + 2014-08-09T12:14:20+00:00, + ), + atime: Some( + 2014-08-09T12:14:20+00:00, + ), + ctime: Some( + 2024-03-13T00:51:39.490651139+00:00, + ), + uid: Some( + 1001, + ), + gid: Some( + 127, + ), + user: Some( + "runner", + ), + group: Some( + "docker", + ), + inode: 67861, + device_id: 2065, + size: 21, + links: 2, + extended_attributes: [], + }, + content: Some( + [ + 649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a, + ], + ), + subtree: None, + }, + Node { + name: "testfile-hardlink", + node_type: File, + meta: Metadata { + mode: Some( + 420, + ), + mtime: Some( + 2014-08-09T12:14:20+00:00, + ), + atime: Some( + 2014-08-09T12:14:20+00:00, + ), + ctime: Some( + 2024-03-13T00:51:39.490651139+00:00, + ), + uid: Some( + 1001, + ), + gid: Some( + 127, + ), + user: Some( + "runner", + ), + group: Some( + "docker", + ), + inode: 67861, + device_id: 2065, + size: 21, + links: 2, + extended_attributes: [], + }, + content: Some( + [ + 649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a, + ], + ), + subtree: None, + }, + Node { + name: "testfile-symlink", + node_type: Symlink { + linktarget: "testfile", + linktarget_raw: None, + }, + meta: Metadata { + mode: Some( + 134218239, + ), + mtime: Some( + 2014-08-09T12:14:28+00:00, + ), + atime: Some( + 2014-08-09T12:14:28+00:00, + ), + ctime: Some( + 2024-03-13T00:51:39.490651139+00:00, + ), + uid: Some( + 1001, + ), + gid: Some( + 127, + ), + user: Some( + "runner", + ), + group: Some( + "docker", + ), + inode: 67873, + device_id: 2065, + size: 8, + links: 1, + extended_attributes: [], + }, + content: None, + subtree: None, + }, + ], +} diff --git a/crates/core/tests/snapshots/integration__dryrun-tar-tree-nix.snap b/crates/core/tests/snapshots/integration__dryrun-tar-tree-nix.snap new file mode 100644 index 00000000..34b558f6 --- /dev/null +++ b/crates/core/tests/snapshots/integration__dryrun-tar-tree-nix.snap @@ -0,0 +1,169 @@ +--- +source: crates/core/tests/integration.rs +expression: tree +--- +Tree { + nodes: [ + Node { + name: "empty-file", + node_type: File, + meta: Metadata { + mode: Some( + 420, + ), + mtime: Some( + 2014-11-30T15:03:11+00:00, + ), + atime: Some( + 2014-11-30T15:03:11+00:00, + ), + ctime: Some( + 2024-03-13T00:51:39.490651139+00:00, + ), + uid: Some( + 1001, + ), + gid: Some( + 127, + ), + user: Some( + "runner", + ), + group: Some( + "docker", + ), + inode: 67865, + device_id: 2065, + size: 0, + links: 1, + extended_attributes: [], + }, + content: Some( + [], + ), + subtree: None, + }, + Node { + name: "testfile", + node_type: File, + meta: Metadata { + mode: Some( + 420, + ), + mtime: Some( + 2014-08-09T12:14:20+00:00, + ), + atime: Some( + 2014-08-09T12:14:20+00:00, + ), + ctime: Some( + 2024-03-13T00:51:39.490651139+00:00, + ), + uid: Some( + 1001, + ), + gid: Some( + 127, + ), + user: Some( + "runner", + ), + group: Some( + "docker", + ), + inode: 67860, + device_id: 2065, + size: 21, + links: 2, + extended_attributes: [], + }, + content: Some( + [ + 649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a, + ], + ), + subtree: None, + }, + Node { + name: "testfile-hardlink", + node_type: File, + meta: Metadata { + mode: Some( + 420, + ), + mtime: Some( + 2014-08-09T12:14:20+00:00, + ), + atime: Some( + 2014-08-09T12:14:20+00:00, + ), + ctime: Some( + 2024-03-13T00:51:39.490651139+00:00, + ), + uid: Some( + 1001, + ), + gid: Some( + 127, + ), + user: Some( + "runner", + ), + group: Some( + "docker", + ), + inode: 67860, + device_id: 2065, + size: 21, + links: 2, + extended_attributes: [], + }, + content: Some( + [ + 649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a, + ], + ), + subtree: None, + }, + Node { + name: "testfile-symlink", + node_type: Symlink { + linktarget: "testfile", + linktarget_raw: None, + }, + meta: Metadata { + mode: Some( + 134218239, + ), + mtime: Some( + 2014-08-09T12:14:28+00:00, + ), + atime: Some( + 2014-08-09T12:14:28+00:00, + ), + ctime: Some( + 2024-03-13T00:51:39.490651139+00:00, + ), + uid: Some( + 1001, + ), + gid: Some( + 127, + ), + user: Some( + "runner", + ), + group: Some( + "docker", + ), + inode: 67867, + device_id: 2065, + size: 8, + links: 1, + extended_attributes: [], + }, + content: None, + subtree: None, + }, + ], +} From 6bc24c3c6b9bb445c2672723cdf832b3e21a742d Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Wed, 13 Mar 2024 02:50:47 +0100 Subject: [PATCH 25/46] use insta redactions to hide changing data Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/core/Cargo.toml | 2 +- crates/core/tests/integration.rs | 32 ++++++++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index ecdffa76..8cb3bee2 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -133,7 +133,7 @@ xattr = "1" [dev-dependencies] expect-test = "1.4.1" flate2 = "1.0.28" -insta = "1.36.1" +insta = { version = "1.36.1", features = ["redactions"] } mockall = "0.12.1" pretty_assertions = "1.4.0" quickcheck = "1.0.3" diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index ffcf8b01..c0ef89ed 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -129,10 +129,22 @@ fn test_backup_with_tar_gz_passes( let tree = repo.get_tree(&tree.subtree.expect("Sub tree"))?; #[cfg(windows)] - assert_debug_snapshot!("backup-tar-tree-windows", tree); + assert_debug_snapshot!("backup-tar-tree-windows", tree, + { + "inode" => "inode", + "ctime" => "ctime", + "mtime" => "mtime", + "atime" => "atime", + }); #[cfg(not(windows))] - assert_debug_snapshot!("backup-tar-tree-nix", tree); + assert_debug_snapshot!("backup-tar-tree-nix", tree, + { + "inode" => "inode", + "ctime" => "ctime", + "mtime" => "mtime", + "atime" => "atime", + }); // get all snapshots and check them let all_snapshots = repo.get_all_snapshots()?; @@ -216,10 +228,22 @@ fn test_backup_dry_run_with_tar_gz_passes( let tree = repo.get_tree(&tree.subtree.expect("Sub tree"))?; #[cfg(windows)] - assert_debug_snapshot!("dryrun-tar-tree-windows", tree); + assert_debug_snapshot!("dryrun-tar-tree-windows", tree, + { + "inode" => "inode", + "ctime" => "ctime", + "mtime" => "mtime", + "atime" => "atime", + }); #[cfg(not(windows))] - assert_debug_snapshot!("dryrun-tar-tree-nix", tree); + assert_debug_snapshot!("dryrun-tar-tree-nix", tree, + { + "inode" => "inode", + "ctime" => "ctime", + "mtime" => "mtime", + "atime" => "atime", + }); // re-read index let repo = repo.to_indexed_ids()?; From 9c799c6cdd9d80794158c4fc2fd71fb202e0eec4 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Wed, 13 Mar 2024 04:05:49 +0100 Subject: [PATCH 26/46] update snapshots Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/core/Cargo.toml | 2 +- crates/core/tests/integration.rs | 240 +++++++++++++----- ...gration__backup-tar-summary-first-nix.snap | 29 --- ...ion__backup-tar-summary-first-windows.snap | 38 ++- ...ration__backup-tar-summary-second-nix.snap | 29 --- ...on__backup-tar-summary-second-windows.snap | 39 ++- .../integration__backup-tar-tree-nix.snap | 169 ------------ .../integration__backup-tar-tree-windows.snap | 164 +++--------- ...gration__dryrun-tar-summary-first-nix.snap | 29 --- ...ion__dryrun-tar-summary-first-windows.snap | 37 ++- ...ration__dryrun-tar-summary-second-nix.snap | 29 --- ...on__dryrun-tar-summary-second-windows.snap | 38 ++- .../integration__dryrun-tar-tree-nix.snap | 169 ------------ .../integration__dryrun-tar-tree-windows.snap | 164 +++--------- 14 files changed, 353 insertions(+), 823 deletions(-) delete mode 100644 crates/core/tests/snapshots/integration__backup-tar-summary-first-nix.snap delete mode 100644 crates/core/tests/snapshots/integration__backup-tar-summary-second-nix.snap delete mode 100644 crates/core/tests/snapshots/integration__backup-tar-tree-nix.snap delete mode 100644 crates/core/tests/snapshots/integration__dryrun-tar-summary-first-nix.snap delete mode 100644 crates/core/tests/snapshots/integration__dryrun-tar-summary-second-nix.snap delete mode 100644 crates/core/tests/snapshots/integration__dryrun-tar-tree-nix.snap diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 8cb3bee2..9514d80d 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -133,7 +133,7 @@ xattr = "1" [dev-dependencies] expect-test = "1.4.1" flate2 = "1.0.28" -insta = { version = "1.36.1", features = ["redactions"] } +insta = { version = "1.36.1", features = ["redactions", "ron"] } mockall = "0.12.1" pretty_assertions = "1.4.0" quickcheck = "1.0.3" diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index c0ef89ed..b0115874 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -1,6 +1,6 @@ use anyhow::Result; use flate2::read::GzDecoder; -use insta::assert_debug_snapshot; +use insta::assert_ron_snapshot; use pretty_assertions::assert_eq; use rstest::fixture; use rstest::rstest; @@ -8,6 +8,7 @@ use rustic_core::{ repofile::SnapshotFile, BackupOptions, ConfigOptions, InMemoryBackend, KeyOptions, NoProgressBars, OpenStatus, PathList, Repository, RepositoryBackends, RepositoryOptions, }; +use serde_derive::Serialize; use std::{ env, @@ -62,35 +63,38 @@ fn tar_gz_testdata() -> Result { } // Parts of the snapshot summary we want to test against references +#[derive(Serialize)] struct TestSummary<'a>(&'a SnapshotFile); -impl<'a> std::fmt::Debug for TestSummary<'a> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - // leave out info we expect to change: - // Ids, times, tree sizes (as used uid/username is saved in trees) - let mut b = f.debug_struct("TestSnap"); - _ = b.field("hostname", &self.0.hostname); - _ = b.field("paths", &self.0.paths); - _ = b.field("label", &self.0.label); - _ = b.field("tags", &self.0.tags); - - let s = self.0.summary.as_ref().unwrap(); - _ = b.field("files_new", &s.files_new); - _ = b.field("files_changed", &s.files_changed); - _ = b.field("files_unmodified", &s.files_unmodified); - _ = b.field("total_files_processed", &s.total_files_processed); - _ = b.field("total_bytes_processed", &s.total_bytes_processed); - _ = b.field("dirs_new", &s.dirs_new); - _ = b.field("dirs_changed", &s.dirs_changed); - _ = b.field("dirs_unmodified", &s.dirs_unmodified); - _ = b.field("total_dirs_processed", &s.total_dirs_processed); - _ = b.field("data_blobs", &s.data_blobs); - _ = b.field("tree_blobs", &s.tree_blobs); - _ = b.field("data_added_files", &s.data_added_files); - _ = b.field("data_added_files_packed", &s.data_added_files_packed); - b.finish() - } -} +// TODO: we serialize to RON to make the snapshots more readable, +// but maybe we can keep this for the future? +// impl<'a> std::fmt::Debug for TestSummary<'a> { +// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +// // leave out info we expect to change: +// // Ids, times, tree sizes (as used uid/username is saved in trees) +// let mut b = f.debug_struct("TestSnap"); +// _ = b.field("hostname", &self.0.hostname); +// _ = b.field("paths", &self.0.paths); +// _ = b.field("label", &self.0.label); +// _ = b.field("tags", &self.0.tags); + +// let s = self.0.summary.as_ref().unwrap(); +// _ = b.field("files_new", &s.files_new); +// _ = b.field("files_changed", &s.files_changed); +// _ = b.field("files_unmodified", &s.files_unmodified); +// _ = b.field("total_files_processed", &s.total_files_processed); +// _ = b.field("total_bytes_processed", &s.total_bytes_processed); +// _ = b.field("dirs_new", &s.dirs_new); +// _ = b.field("dirs_changed", &s.dirs_changed); +// _ = b.field("dirs_unmodified", &s.dirs_unmodified); +// _ = b.field("total_dirs_processed", &s.total_dirs_processed); +// _ = b.field("data_blobs", &s.data_blobs); +// _ = b.field("tree_blobs", &s.tree_blobs); +// _ = b.field("data_added_files", &s.data_added_files); +// _ = b.field("data_added_files_packed", &s.data_added_files_packed); +// b.finish() +// } +// } #[rstest] fn test_backup_with_tar_gz_passes( @@ -112,13 +116,36 @@ fn test_backup_with_tar_gz_passes( let first_snapshot = repo.backup(&opts, paths, SnapshotFile::default())?; #[cfg(windows)] - assert_debug_snapshot!( + assert_ron_snapshot!( "backup-tar-summary-first-windows", - TestSummary(&first_snapshot) + TestSummary(&first_snapshot), + { + ".tree" => "[tree_id]", + ".program_version" => "[version]", + ".time" => "[time]", + ".tags" => "[tags]", + ".id" => "[id]", + ".summary.backup_start" => "[backup_start]", + ".summary.backup_end" => "[backup_end]", + ".summary.backup_duration" => "[backup_duration]", + ".summary.total_duration" => "[total_duration]", + } ); #[cfg(not(windows))] - assert_debug_snapshot!("backup-tar-summary-first-nix", TestSummary(&first_snapshot)); + assert_ron_snapshot!("backup-tar-summary-first-nix", + TestSummary(&first_snapshot), + { + ".tree" => "[tree_id]", + ".program_version" => "[version]", + ".time" => "[time]", + ".tags" => "[tags]", + ".id" => "[id]", + ".summary.backup_start" => "[backup_start]", + ".summary.backup_end" => "[backup_end]", + ".summary.backup_duration" => "[backup_duration]", + ".summary.total_duration" => "[total_duration]", + }); assert_eq!(first_snapshot.parent, None); @@ -126,25 +153,27 @@ fn test_backup_with_tar_gz_passes( // re-read index let repo = repo.to_indexed_ids()?; let tree = repo.node_from_path(first_snapshot.tree, Path::new("test/0/tests"))?; - let tree = repo.get_tree(&tree.subtree.expect("Sub tree"))?; + let tree: rustic_core::repofile::Tree = repo.get_tree(&tree.subtree.expect("Sub tree"))?; #[cfg(windows)] - assert_debug_snapshot!("backup-tar-tree-windows", tree, - { - "inode" => "inode", - "ctime" => "ctime", - "mtime" => "mtime", - "atime" => "atime", - }); + assert_ron_snapshot!( + "backup-tar-tree-windows", + tree, + { + ".nodes[].ctime" => "[ctime]", + ".nodes[].content" => "[content_id]", + } + ); #[cfg(not(windows))] - assert_debug_snapshot!("backup-tar-tree-nix", tree, - { - "inode" => "inode", - "ctime" => "ctime", - "mtime" => "mtime", - "atime" => "atime", - }); + assert_ron_snapshot!( + "backup-tar-tree-nix", + tree, + { + ".nodes[].ctime" => "[ctime]", + ".nodes[].content" => "[content_id]", + } + ); // get all snapshots and check them let all_snapshots = repo.get_all_snapshots()?; @@ -158,14 +187,36 @@ fn test_backup_with_tar_gz_passes( let second_snapshot = repo.backup(&opts, paths, SnapshotFile::default())?; #[cfg(windows)] - assert_debug_snapshot!( + assert_ron_snapshot!( "backup-tar-summary-second-windows", - TestSummary(&second_snapshot) + TestSummary(&second_snapshot), + { + ".tree" => "[tree_id]", + ".program_version" => "[version]", + ".time" => "[time]", + ".tags" => "[tags]", + ".id" => "[id]", + ".summary.backup_start" => "[backup_start]", + ".summary.backup_end" => "[backup_end]", + ".summary.backup_duration" => "[backup_duration]", + ".summary.total_duration" => "[total_duration]", + } ); #[cfg(not(windows))] - assert_debug_snapshot!( + assert_ron_snapshot!( "backup-tar-summary-second-nix", - TestSummary(&second_snapshot) + TestSummary(&second_snapshot), + { + ".tree" => "[tree_id]", + ".program_version" => "[version]", + ".time" => "[time]", + ".tags" => "[tags]", + ".id" => "[id]", + ".summary.backup_start" => "[backup_start]", + ".summary.backup_end" => "[backup_end]", + ".summary.backup_duration" => "[backup_duration]", + ".summary.total_duration" => "[total_duration]", + } ); assert_eq!(second_snapshot.parent, Some(first_snapshot.id)); @@ -201,13 +252,36 @@ fn test_backup_dry_run_with_tar_gz_passes( let snap_dry_run = repo.backup(&opts, paths, SnapshotFile::default())?; #[cfg(windows)] - assert_debug_snapshot!( + assert_ron_snapshot!( "dryrun-tar-summary-first-windows", - TestSummary(&snap_dry_run) + TestSummary(&snap_dry_run), + { + ".tree" => "[tree_id]", + ".program_version" => "[version]", + ".time" => "[time]", + ".tags" => "[tags]", + ".id" => "[id]", + ".summary.backup_start" => "[backup_start]", + ".summary.backup_end" => "[backup_end]", + ".summary.backup_duration" => "[backup_duration]", + ".summary.total_duration" => "[total_duration]", + } ); #[cfg(not(windows))] - assert_debug_snapshot!("dryrun-tar-summary-first-nix", TestSummary(&snap_dry_run)); + assert_ron_snapshot!("dryrun-tar-summary-first-nix", + TestSummary(&snap_dry_run), + { + ".tree" => "[tree_id]", + ".program_version" => "[version]", + ".time" => "[time]", + ".tags" => "[tags]", + ".id" => "[id]", + ".summary.backup_start" => "[backup_start]", + ".summary.backup_end" => "[backup_end]", + ".summary.backup_duration" => "[backup_duration]", + ".summary.total_duration" => "[total_duration]", + }); // check that repo is still empty let snaps = repo.get_all_snapshots()?; @@ -228,22 +302,24 @@ fn test_backup_dry_run_with_tar_gz_passes( let tree = repo.get_tree(&tree.subtree.expect("Sub tree"))?; #[cfg(windows)] - assert_debug_snapshot!("dryrun-tar-tree-windows", tree, - { - "inode" => "inode", - "ctime" => "ctime", - "mtime" => "mtime", - "atime" => "atime", - }); + assert_ron_snapshot!( + "dryrun-tar-tree-windows", + tree, + { + ".nodes[].ctime" => "[ctime]", + ".nodes[].content" => "[content_id]", + } + ); #[cfg(not(windows))] - assert_debug_snapshot!("dryrun-tar-tree-nix", tree, - { - "inode" => "inode", - "ctime" => "ctime", - "mtime" => "mtime", - "atime" => "atime", - }); + assert_ron_snapshot!( + "dryrun-tar-tree-nix", + tree, + { + ".nodes[].ctime" => "[ctime]", + ".nodes[].content" => "[content_id]", + } + ); // re-read index let repo = repo.to_indexed_ids()?; @@ -252,13 +328,37 @@ fn test_backup_dry_run_with_tar_gz_passes( let snap_dry_run = repo.backup(&opts, paths, SnapshotFile::default())?; #[cfg(windows)] - assert_debug_snapshot!( + assert_ron_snapshot!( "dryrun-tar-summary-second-windows", - TestSummary(&snap_dry_run) + TestSummary(&snap_dry_run), + { + ".tree" => "[tree_id]", + ".program_version" => "[version]", + ".time" => "[time]", + ".tags" => "[tags]", + ".id" => "[id]", + ".summary.backup_start" => "[backup_start]", + ".summary.backup_end" => "[backup_end]", + ".summary.backup_duration" => "[backup_duration]", + ".summary.total_duration" => "[total_duration]", + } ); #[cfg(not(windows))] - assert_debug_snapshot!("dryrun-tar-summary-second-nix", TestSummary(&snap_dry_run)); + assert_ron_snapshot!("dryrun-tar-summary-second-nix", + TestSummary(&snap_dry_run), + { + ".tree" => "[tree_id]", + ".program_version" => "[version]", + ".time" => "[time]", + ".tags" => "[tags]", + ".id" => "[id]", + ".summary.backup_start" => "[backup_start]", + ".summary.backup_end" => "[backup_end]", + ".summary.backup_duration" => "[backup_duration]", + ".summary.total_duration" => "[total_duration]", + } + ); // check that no data has been added let snaps = repo.get_all_snapshots()?; diff --git a/crates/core/tests/snapshots/integration__backup-tar-summary-first-nix.snap b/crates/core/tests/snapshots/integration__backup-tar-summary-first-nix.snap deleted file mode 100644 index fbf264a3..00000000 --- a/crates/core/tests/snapshots/integration__backup-tar-summary-first-nix.snap +++ /dev/null @@ -1,29 +0,0 @@ ---- -source: crates/core/tests/integration.rs -expression: TestSummary(&first_snapshot) ---- -TestSnap { - hostname: "", - paths: StringList( - [ - "test", - ], - ), - label: "", - tags: StringList( - [], - ), - files_new: 73, - files_changed: 0, - files_unmodified: 0, - total_files_processed: 73, - total_bytes_processed: 1125674, - dirs_new: 6, - dirs_changed: 0, - dirs_unmodified: 0, - total_dirs_processed: 6, - data_blobs: 70, - tree_blobs: 6, - data_added_files: 1125653, - data_added_files_packed: 78740, -} diff --git a/crates/core/tests/snapshots/integration__backup-tar-summary-first-windows.snap b/crates/core/tests/snapshots/integration__backup-tar-summary-first-windows.snap index fbf264a3..d6c4a690 100644 --- a/crates/core/tests/snapshots/integration__backup-tar-summary-first-windows.snap +++ b/crates/core/tests/snapshots/integration__backup-tar-summary-first-windows.snap @@ -2,17 +2,19 @@ source: crates/core/tests/integration.rs expression: TestSummary(&first_snapshot) --- -TestSnap { - hostname: "", - paths: StringList( - [ - "test", - ], - ), - label: "", - tags: StringList( - [], - ), +TestSummary(SnapshotFile( + time: "[time]", + program_version: "[version]", + tree: "[tree_id]", + paths: StringList([ + "test", + ]), + hostname: "", + username: "", + uid: 0, + gid: 0, + tags: "[tags]", + summary: Some(SnapshotSummary( files_new: 73, files_changed: 0, files_unmodified: 0, @@ -22,8 +24,20 @@ TestSnap { dirs_changed: 0, dirs_unmodified: 0, total_dirs_processed: 6, + total_dirsize_processed: 18471, data_blobs: 70, tree_blobs: 6, + data_added: 1144124, + data_added_packed: 82916, data_added_files: 1125653, data_added_files_packed: 78740, -} + data_added_trees: 18471, + data_added_trees_packed: 4176, + command: "", + backup_start: "[backup_start]", + backup_end: "[backup_end]", + backup_duration: "[backup_duration]", + total_duration: "[total_duration]", + )), + id: "[id]", +)) diff --git a/crates/core/tests/snapshots/integration__backup-tar-summary-second-nix.snap b/crates/core/tests/snapshots/integration__backup-tar-summary-second-nix.snap deleted file mode 100644 index 7413b5d5..00000000 --- a/crates/core/tests/snapshots/integration__backup-tar-summary-second-nix.snap +++ /dev/null @@ -1,29 +0,0 @@ ---- -source: crates/core/tests/integration.rs -expression: TestSummary(&second_snapshot) ---- -TestSnap { - hostname: "", - paths: StringList( - [ - "test", - ], - ), - label: "", - tags: StringList( - [], - ), - files_new: 0, - files_changed: 0, - files_unmodified: 73, - total_files_processed: 73, - total_bytes_processed: 1125682, - dirs_new: 0, - dirs_changed: 0, - dirs_unmodified: 6, - total_dirs_processed: 6, - data_blobs: 0, - tree_blobs: 0, - data_added_files: 0, - data_added_files_packed: 0, -} diff --git a/crates/core/tests/snapshots/integration__backup-tar-summary-second-windows.snap b/crates/core/tests/snapshots/integration__backup-tar-summary-second-windows.snap index 4d76ed94..f7f264cf 100644 --- a/crates/core/tests/snapshots/integration__backup-tar-summary-second-windows.snap +++ b/crates/core/tests/snapshots/integration__backup-tar-summary-second-windows.snap @@ -2,17 +2,20 @@ source: crates/core/tests/integration.rs expression: TestSummary(&second_snapshot) --- -TestSnap { - hostname: "", - paths: StringList( - [ - "test", - ], - ), - label: "", - tags: StringList( - [], - ), +TestSummary(SnapshotFile( + time: "[time]", + program_version: "[version]", + parent: Some(Id("7b7085ce125bcbbda8bcfcc1c8f7aa7b82a4e7f240efd5feaade6416dcb31c7e")), + tree: "[tree_id]", + paths: StringList([ + "test", + ]), + hostname: "", + username: "", + uid: 0, + gid: 0, + tags: "[tags]", + summary: Some(SnapshotSummary( files_new: 0, files_changed: 0, files_unmodified: 73, @@ -22,8 +25,20 @@ TestSnap { dirs_changed: 0, dirs_unmodified: 6, total_dirs_processed: 6, + total_dirsize_processed: 18471, data_blobs: 0, tree_blobs: 0, + data_added: 0, + data_added_packed: 0, data_added_files: 0, data_added_files_packed: 0, -} + data_added_trees: 0, + data_added_trees_packed: 0, + command: "", + backup_start: "[backup_start]", + backup_end: "[backup_end]", + backup_duration: "[backup_duration]", + total_duration: "[total_duration]", + )), + id: "[id]", +)) diff --git a/crates/core/tests/snapshots/integration__backup-tar-tree-nix.snap b/crates/core/tests/snapshots/integration__backup-tar-tree-nix.snap deleted file mode 100644 index 658a82e0..00000000 --- a/crates/core/tests/snapshots/integration__backup-tar-tree-nix.snap +++ /dev/null @@ -1,169 +0,0 @@ ---- -source: crates/core/tests/integration.rs -expression: tree ---- -Tree { - nodes: [ - Node { - name: "empty-file", - node_type: File, - meta: Metadata { - mode: Some( - 420, - ), - mtime: Some( - 2014-11-30T15:03:11+00:00, - ), - atime: Some( - 2014-11-30T15:03:11+00:00, - ), - ctime: Some( - 2024-03-13T00:51:39.490651139+00:00, - ), - uid: Some( - 1001, - ), - gid: Some( - 127, - ), - user: Some( - "runner", - ), - group: Some( - "docker", - ), - inode: 67866, - device_id: 2065, - size: 0, - links: 1, - extended_attributes: [], - }, - content: Some( - [], - ), - subtree: None, - }, - Node { - name: "testfile", - node_type: File, - meta: Metadata { - mode: Some( - 420, - ), - mtime: Some( - 2014-08-09T12:14:20+00:00, - ), - atime: Some( - 2014-08-09T12:14:20+00:00, - ), - ctime: Some( - 2024-03-13T00:51:39.490651139+00:00, - ), - uid: Some( - 1001, - ), - gid: Some( - 127, - ), - user: Some( - "runner", - ), - group: Some( - "docker", - ), - inode: 67861, - device_id: 2065, - size: 21, - links: 2, - extended_attributes: [], - }, - content: Some( - [ - 649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a, - ], - ), - subtree: None, - }, - Node { - name: "testfile-hardlink", - node_type: File, - meta: Metadata { - mode: Some( - 420, - ), - mtime: Some( - 2014-08-09T12:14:20+00:00, - ), - atime: Some( - 2014-08-09T12:14:20+00:00, - ), - ctime: Some( - 2024-03-13T00:51:39.490651139+00:00, - ), - uid: Some( - 1001, - ), - gid: Some( - 127, - ), - user: Some( - "runner", - ), - group: Some( - "docker", - ), - inode: 67861, - device_id: 2065, - size: 21, - links: 2, - extended_attributes: [], - }, - content: Some( - [ - 649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a, - ], - ), - subtree: None, - }, - Node { - name: "testfile-symlink", - node_type: Symlink { - linktarget: "testfile", - linktarget_raw: None, - }, - meta: Metadata { - mode: Some( - 134218239, - ), - mtime: Some( - 2014-08-09T12:14:28+00:00, - ), - atime: Some( - 2014-08-09T12:14:28+00:00, - ), - ctime: Some( - 2024-03-13T00:51:39.490651139+00:00, - ), - uid: Some( - 1001, - ), - gid: Some( - 127, - ), - user: Some( - "runner", - ), - group: Some( - "docker", - ), - inode: 67873, - device_id: 2065, - size: 8, - links: 1, - extended_attributes: [], - }, - content: None, - subtree: None, - }, - ], -} diff --git a/crates/core/tests/snapshots/integration__backup-tar-tree-windows.snap b/crates/core/tests/snapshots/integration__backup-tar-tree-windows.snap index 6e8fd2bc..89807d2b 100644 --- a/crates/core/tests/snapshots/integration__backup-tar-tree-windows.snap +++ b/crates/core/tests/snapshots/integration__backup-tar-tree-windows.snap @@ -2,128 +2,42 @@ source: crates/core/tests/integration.rs expression: tree --- -Tree { - nodes: [ - Node { - name: "empty-file", - node_type: File, - meta: Metadata { - mode: None, - mtime: Some( - 2014-11-30T16:03:11+01:00, - ), - atime: Some( - 2014-11-30T16:03:11+01:00, - ), - ctime: Some( - 2024-03-13T00:39:48.791253+01:00, - ), - uid: None, - gid: None, - user: None, - group: None, - inode: 0, - device_id: 0, - size: 0, - links: 0, - extended_attributes: [], - }, - content: Some( - [], - ), - subtree: None, - }, - Node { - name: "testfile", - node_type: File, - meta: Metadata { - mode: None, - mtime: Some( - 2014-08-09T14:14:20+02:00, - ), - atime: Some( - 2014-08-09T14:14:20+02:00, - ), - ctime: Some( - 2024-03-13T00:39:48.789254100+01:00, - ), - uid: None, - gid: None, - user: None, - group: None, - inode: 0, - device_id: 0, - size: 21, - links: 0, - extended_attributes: [], - }, - content: Some( - [ - 649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a, - ], - ), - subtree: None, - }, - Node { - name: "testfile-hardlink", - node_type: File, - meta: Metadata { - mode: None, - mtime: Some( - 2014-08-09T14:14:20+02:00, - ), - atime: Some( - 2014-08-09T14:14:20+02:00, - ), - ctime: Some( - 2024-03-13T00:39:48.789254100+01:00, - ), - uid: None, - gid: None, - user: None, - group: None, - inode: 0, - device_id: 0, - size: 21, - links: 0, - extended_attributes: [], - }, - content: Some( - [ - 649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a, - ], - ), - subtree: None, - }, - Node { - name: "testfile-symlink", - node_type: Symlink { - linktarget: "testfile", - linktarget_raw: None, - }, - meta: Metadata { - mode: None, - mtime: Some( - 2014-08-09T14:14:28+02:00, - ), - atime: Some( - 2014-08-09T14:14:28+02:00, - ), - ctime: Some( - 2024-03-13T00:39:48.791253+01:00, - ), - uid: None, - gid: None, - user: None, - group: None, - inode: 0, - device_id: 0, - size: 0, - links: 0, - extended_attributes: [], - }, - content: None, - subtree: None, - }, - ], -} +Tree( + nodes: [ + { + "name": "empty-file", + "type": "file", + "mtime": Some("2014-11-30T16:03:11+01:00"), + "atime": Some("2014-11-30T16:03:11+01:00"), + "ctime": "[ctime]", + "content": "[content_id]", + }, + { + "name": "testfile", + "type": "file", + "mtime": Some("2014-08-09T14:14:20+02:00"), + "atime": Some("2014-08-09T14:14:20+02:00"), + "ctime": "[ctime]", + "size": 21, + "content": "[content_id]", + }, + { + "name": "testfile-hardlink", + "type": "file", + "mtime": Some("2014-08-09T14:14:20+02:00"), + "atime": Some("2014-08-09T14:14:20+02:00"), + "ctime": "[ctime]", + "size": 21, + "content": "[content_id]", + }, + { + "name": "testfile-symlink", + "type": "symlink", + "linktarget": "testfile", + "mtime": Some("2014-08-09T14:14:28+02:00"), + "atime": Some("2014-08-09T14:14:28+02:00"), + "ctime": "[ctime]", + "content": "[content_id]", + }, + ], +) diff --git a/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-nix.snap b/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-nix.snap deleted file mode 100644 index 5663f447..00000000 --- a/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-nix.snap +++ /dev/null @@ -1,29 +0,0 @@ ---- -source: crates/core/tests/integration.rs -expression: TestSummary(&snap_dry_run) ---- -TestSnap { - hostname: "", - paths: StringList( - [ - "test", - ], - ), - label: "", - tags: StringList( - [], - ), - files_new: 73, - files_changed: 0, - files_unmodified: 0, - total_files_processed: 73, - total_bytes_processed: 1125674, - dirs_new: 6, - dirs_changed: 0, - dirs_unmodified: 0, - total_dirs_processed: 6, - data_blobs: 70, - tree_blobs: 6, - data_added_files: 1125653, - data_added_files_packed: 78740, -} diff --git a/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-windows.snap b/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-windows.snap index 5663f447..55495eee 100644 --- a/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-windows.snap +++ b/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-windows.snap @@ -2,17 +2,19 @@ source: crates/core/tests/integration.rs expression: TestSummary(&snap_dry_run) --- -TestSnap { - hostname: "", - paths: StringList( - [ - "test", - ], - ), - label: "", - tags: StringList( - [], - ), +TestSummary(SnapshotFile( + time: "[time]", + program_version: "[version]", + tree: "[tree_id]", + paths: StringList([ + "test", + ]), + hostname: "", + username: "", + uid: 0, + gid: 0, + tags: "[tags]", + summary: Some(SnapshotSummary( files_new: 73, files_changed: 0, files_unmodified: 0, @@ -22,8 +24,19 @@ TestSnap { dirs_changed: 0, dirs_unmodified: 0, total_dirs_processed: 6, + total_dirsize_processed: 18465, data_blobs: 70, tree_blobs: 6, + data_added: 1144118, + data_added_packed: 82905, data_added_files: 1125653, data_added_files_packed: 78740, -} + data_added_trees: 18465, + data_added_trees_packed: 4165, + command: "", + backup_start: "[backup_start]", + backup_end: "[backup_end]", + backup_duration: "[backup_duration]", + total_duration: "[total_duration]", + )), +)) diff --git a/crates/core/tests/snapshots/integration__dryrun-tar-summary-second-nix.snap b/crates/core/tests/snapshots/integration__dryrun-tar-summary-second-nix.snap deleted file mode 100644 index 632d04ee..00000000 --- a/crates/core/tests/snapshots/integration__dryrun-tar-summary-second-nix.snap +++ /dev/null @@ -1,29 +0,0 @@ ---- -source: crates/core/tests/integration.rs -expression: TestSummary(&snap_dry_run) ---- -TestSnap { - hostname: "", - paths: StringList( - [ - "test", - ], - ), - label: "", - tags: StringList( - [], - ), - files_new: 0, - files_changed: 0, - files_unmodified: 73, - total_files_processed: 73, - total_bytes_processed: 1125682, - dirs_new: 0, - dirs_changed: 0, - dirs_unmodified: 6, - total_dirs_processed: 6, - data_blobs: 0, - tree_blobs: 0, - data_added_files: 0, - data_added_files_packed: 0, -} diff --git a/crates/core/tests/snapshots/integration__dryrun-tar-summary-second-windows.snap b/crates/core/tests/snapshots/integration__dryrun-tar-summary-second-windows.snap index ba72d6a9..66965dc6 100644 --- a/crates/core/tests/snapshots/integration__dryrun-tar-summary-second-windows.snap +++ b/crates/core/tests/snapshots/integration__dryrun-tar-summary-second-windows.snap @@ -2,17 +2,20 @@ source: crates/core/tests/integration.rs expression: TestSummary(&snap_dry_run) --- -TestSnap { - hostname: "", - paths: StringList( - [ - "test", - ], - ), - label: "", - tags: StringList( - [], - ), +TestSummary(SnapshotFile( + time: "[time]", + program_version: "[version]", + parent: Some(Id("0c7ab572c3c7498fa3b941a9803ab950a52a846c2ad78579b3249af4508bf6c5")), + tree: "[tree_id]", + paths: StringList([ + "test", + ]), + hostname: "", + username: "", + uid: 0, + gid: 0, + tags: "[tags]", + summary: Some(SnapshotSummary( files_new: 0, files_changed: 0, files_unmodified: 73, @@ -22,8 +25,19 @@ TestSnap { dirs_changed: 0, dirs_unmodified: 6, total_dirs_processed: 6, + total_dirsize_processed: 18465, data_blobs: 0, tree_blobs: 0, + data_added: 0, + data_added_packed: 0, data_added_files: 0, data_added_files_packed: 0, -} + data_added_trees: 0, + data_added_trees_packed: 0, + command: "", + backup_start: "[backup_start]", + backup_end: "[backup_end]", + backup_duration: "[backup_duration]", + total_duration: "[total_duration]", + )), +)) diff --git a/crates/core/tests/snapshots/integration__dryrun-tar-tree-nix.snap b/crates/core/tests/snapshots/integration__dryrun-tar-tree-nix.snap deleted file mode 100644 index 34b558f6..00000000 --- a/crates/core/tests/snapshots/integration__dryrun-tar-tree-nix.snap +++ /dev/null @@ -1,169 +0,0 @@ ---- -source: crates/core/tests/integration.rs -expression: tree ---- -Tree { - nodes: [ - Node { - name: "empty-file", - node_type: File, - meta: Metadata { - mode: Some( - 420, - ), - mtime: Some( - 2014-11-30T15:03:11+00:00, - ), - atime: Some( - 2014-11-30T15:03:11+00:00, - ), - ctime: Some( - 2024-03-13T00:51:39.490651139+00:00, - ), - uid: Some( - 1001, - ), - gid: Some( - 127, - ), - user: Some( - "runner", - ), - group: Some( - "docker", - ), - inode: 67865, - device_id: 2065, - size: 0, - links: 1, - extended_attributes: [], - }, - content: Some( - [], - ), - subtree: None, - }, - Node { - name: "testfile", - node_type: File, - meta: Metadata { - mode: Some( - 420, - ), - mtime: Some( - 2014-08-09T12:14:20+00:00, - ), - atime: Some( - 2014-08-09T12:14:20+00:00, - ), - ctime: Some( - 2024-03-13T00:51:39.490651139+00:00, - ), - uid: Some( - 1001, - ), - gid: Some( - 127, - ), - user: Some( - "runner", - ), - group: Some( - "docker", - ), - inode: 67860, - device_id: 2065, - size: 21, - links: 2, - extended_attributes: [], - }, - content: Some( - [ - 649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a, - ], - ), - subtree: None, - }, - Node { - name: "testfile-hardlink", - node_type: File, - meta: Metadata { - mode: Some( - 420, - ), - mtime: Some( - 2014-08-09T12:14:20+00:00, - ), - atime: Some( - 2014-08-09T12:14:20+00:00, - ), - ctime: Some( - 2024-03-13T00:51:39.490651139+00:00, - ), - uid: Some( - 1001, - ), - gid: Some( - 127, - ), - user: Some( - "runner", - ), - group: Some( - "docker", - ), - inode: 67860, - device_id: 2065, - size: 21, - links: 2, - extended_attributes: [], - }, - content: Some( - [ - 649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a, - ], - ), - subtree: None, - }, - Node { - name: "testfile-symlink", - node_type: Symlink { - linktarget: "testfile", - linktarget_raw: None, - }, - meta: Metadata { - mode: Some( - 134218239, - ), - mtime: Some( - 2014-08-09T12:14:28+00:00, - ), - atime: Some( - 2014-08-09T12:14:28+00:00, - ), - ctime: Some( - 2024-03-13T00:51:39.490651139+00:00, - ), - uid: Some( - 1001, - ), - gid: Some( - 127, - ), - user: Some( - "runner", - ), - group: Some( - "docker", - ), - inode: 67867, - device_id: 2065, - size: 8, - links: 1, - extended_attributes: [], - }, - content: None, - subtree: None, - }, - ], -} diff --git a/crates/core/tests/snapshots/integration__dryrun-tar-tree-windows.snap b/crates/core/tests/snapshots/integration__dryrun-tar-tree-windows.snap index a11e66b4..89807d2b 100644 --- a/crates/core/tests/snapshots/integration__dryrun-tar-tree-windows.snap +++ b/crates/core/tests/snapshots/integration__dryrun-tar-tree-windows.snap @@ -2,128 +2,42 @@ source: crates/core/tests/integration.rs expression: tree --- -Tree { - nodes: [ - Node { - name: "empty-file", - node_type: File, - meta: Metadata { - mode: None, - mtime: Some( - 2014-11-30T16:03:11+01:00, - ), - atime: Some( - 2014-11-30T16:03:11+01:00, - ), - ctime: Some( - 2024-03-13T00:39:48.793256700+01:00, - ), - uid: None, - gid: None, - user: None, - group: None, - inode: 0, - device_id: 0, - size: 0, - links: 0, - extended_attributes: [], - }, - content: Some( - [], - ), - subtree: None, - }, - Node { - name: "testfile", - node_type: File, - meta: Metadata { - mode: None, - mtime: Some( - 2014-08-09T14:14:20+02:00, - ), - atime: Some( - 2014-08-09T14:14:20+02:00, - ), - ctime: Some( - 2024-03-13T00:39:48.792257400+01:00, - ), - uid: None, - gid: None, - user: None, - group: None, - inode: 0, - device_id: 0, - size: 21, - links: 0, - extended_attributes: [], - }, - content: Some( - [ - 649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a, - ], - ), - subtree: None, - }, - Node { - name: "testfile-hardlink", - node_type: File, - meta: Metadata { - mode: None, - mtime: Some( - 2014-08-09T14:14:20+02:00, - ), - atime: Some( - 2014-08-09T14:14:20+02:00, - ), - ctime: Some( - 2024-03-13T00:39:48.792257400+01:00, - ), - uid: None, - gid: None, - user: None, - group: None, - inode: 0, - device_id: 0, - size: 21, - links: 0, - extended_attributes: [], - }, - content: Some( - [ - 649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a, - ], - ), - subtree: None, - }, - Node { - name: "testfile-symlink", - node_type: Symlink { - linktarget: "testfile", - linktarget_raw: None, - }, - meta: Metadata { - mode: None, - mtime: Some( - 2014-08-09T14:14:28+02:00, - ), - atime: Some( - 2014-08-09T14:14:28+02:00, - ), - ctime: Some( - 2024-03-13T00:39:48.793256700+01:00, - ), - uid: None, - gid: None, - user: None, - group: None, - inode: 0, - device_id: 0, - size: 0, - links: 0, - extended_attributes: [], - }, - content: None, - subtree: None, - }, - ], -} +Tree( + nodes: [ + { + "name": "empty-file", + "type": "file", + "mtime": Some("2014-11-30T16:03:11+01:00"), + "atime": Some("2014-11-30T16:03:11+01:00"), + "ctime": "[ctime]", + "content": "[content_id]", + }, + { + "name": "testfile", + "type": "file", + "mtime": Some("2014-08-09T14:14:20+02:00"), + "atime": Some("2014-08-09T14:14:20+02:00"), + "ctime": "[ctime]", + "size": 21, + "content": "[content_id]", + }, + { + "name": "testfile-hardlink", + "type": "file", + "mtime": Some("2014-08-09T14:14:20+02:00"), + "atime": Some("2014-08-09T14:14:20+02:00"), + "ctime": "[ctime]", + "size": 21, + "content": "[content_id]", + }, + { + "name": "testfile-symlink", + "type": "symlink", + "linktarget": "testfile", + "mtime": Some("2014-08-09T14:14:28+02:00"), + "atime": Some("2014-08-09T14:14:28+02:00"), + "ctime": "[ctime]", + "content": "[content_id]", + }, + ], +) From e00c13a278a0696cbca0133a2966393928f92b40 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Wed, 13 Mar 2024 04:22:06 +0100 Subject: [PATCH 27/46] update snapshots Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/core/tests/integration.rs | 37 +++------------- ...gration__backup-tar-summary-first-nix.snap | 43 +++++++++++++++++++ ...gration__dryrun-tar-summary-first-nix.snap | 42 ++++++++++++++++++ 3 files changed, 92 insertions(+), 30 deletions(-) create mode 100644 crates/core/tests/snapshots/integration__backup-tar-summary-first-nix.snap create mode 100644 crates/core/tests/snapshots/integration__dryrun-tar-summary-first-nix.snap diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index b0115874..380fd3ef 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -63,39 +63,16 @@ fn tar_gz_testdata() -> Result { } // Parts of the snapshot summary we want to test against references +// +// # Note +// +// We use a struct to avoid having to escape the field names in the snapshot +// we use insta redactions to replace the actual values with placeholders in case +// there are changes in the actual values +// Readme: https://insta.rs/docs/redactions/ #[derive(Serialize)] struct TestSummary<'a>(&'a SnapshotFile); -// TODO: we serialize to RON to make the snapshots more readable, -// but maybe we can keep this for the future? -// impl<'a> std::fmt::Debug for TestSummary<'a> { -// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { -// // leave out info we expect to change: -// // Ids, times, tree sizes (as used uid/username is saved in trees) -// let mut b = f.debug_struct("TestSnap"); -// _ = b.field("hostname", &self.0.hostname); -// _ = b.field("paths", &self.0.paths); -// _ = b.field("label", &self.0.label); -// _ = b.field("tags", &self.0.tags); - -// let s = self.0.summary.as_ref().unwrap(); -// _ = b.field("files_new", &s.files_new); -// _ = b.field("files_changed", &s.files_changed); -// _ = b.field("files_unmodified", &s.files_unmodified); -// _ = b.field("total_files_processed", &s.total_files_processed); -// _ = b.field("total_bytes_processed", &s.total_bytes_processed); -// _ = b.field("dirs_new", &s.dirs_new); -// _ = b.field("dirs_changed", &s.dirs_changed); -// _ = b.field("dirs_unmodified", &s.dirs_unmodified); -// _ = b.field("total_dirs_processed", &s.total_dirs_processed); -// _ = b.field("data_blobs", &s.data_blobs); -// _ = b.field("tree_blobs", &s.tree_blobs); -// _ = b.field("data_added_files", &s.data_added_files); -// _ = b.field("data_added_files_packed", &s.data_added_files_packed); -// b.finish() -// } -// } - #[rstest] fn test_backup_with_tar_gz_passes( tar_gz_testdata: Result, diff --git a/crates/core/tests/snapshots/integration__backup-tar-summary-first-nix.snap b/crates/core/tests/snapshots/integration__backup-tar-summary-first-nix.snap new file mode 100644 index 00000000..8532beb0 --- /dev/null +++ b/crates/core/tests/snapshots/integration__backup-tar-summary-first-nix.snap @@ -0,0 +1,43 @@ +--- +source: crates/core/tests/integration.rs +expression: TestSummary(&first_snapshot) +--- +TestSummary(SnapshotFile( + time: "[time]", + program_version: "[version]", + tree: "[tree_id]", + paths: StringList([ + "test", + ]), + hostname: "", + username: "", + uid: 0, + gid: 0, + tags: "[tags]", + summary: Some(SnapshotSummary( + files_new: 73, + files_changed: 0, + files_unmodified: 0, + total_files_processed: 73, + total_bytes_processed: 1125674, + dirs_new: 6, + dirs_changed: 0, + dirs_unmodified: 0, + total_dirs_processed: 6, + total_dirsize_processed: 25591, + data_blobs: 70, + tree_blobs: 6, + data_added: 1151244, + data_added_packed: 83222, + data_added_files: 1125653, + data_added_files_packed: 78740, + data_added_trees: 25591, + data_added_trees_packed: 4482, + command: "", + backup_start: "[backup_start]", + backup_end: "[backup_end]", + backup_duration: "[backup_duration]", + total_duration: "[total_duration]", + )), + id: "[id]", +)) diff --git a/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-nix.snap b/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-nix.snap new file mode 100644 index 00000000..9ced6b92 --- /dev/null +++ b/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-nix.snap @@ -0,0 +1,42 @@ +--- +source: crates/core/tests/integration.rs +expression: TestSummary(&snap_dry_run) +--- +TestSummary(SnapshotFile( + time: "[time]", + program_version: "[version]", + tree: "[tree_id]", + paths: StringList([ + "test", + ]), + hostname: "", + username: "", + uid: 0, + gid: 0, + tags: "[tags]", + summary: Some(SnapshotSummary( + files_new: 73, + files_changed: 0, + files_unmodified: 0, + total_files_processed: 73, + total_bytes_processed: 1125674, + dirs_new: 6, + dirs_changed: 0, + dirs_unmodified: 0, + total_dirs_processed: 6, + total_dirsize_processed: 25591, + data_blobs: 70, + tree_blobs: 6, + data_added: 1151244, + data_added_packed: 83235, + data_added_files: 1125653, + data_added_files_packed: 78740, + data_added_trees: 25591, + data_added_trees_packed: 4495, + command: "", + backup_start: "[backup_start]", + backup_end: "[backup_end]", + backup_duration: "[backup_duration]", + total_duration: "[total_duration]", + )), +)) From 80e059bcdc74b62d84118e40dd2c6cd78fb147ba Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Wed, 13 Mar 2024 04:45:45 +0100 Subject: [PATCH 28/46] update redactions and snapshots Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/core/tests/integration.rs | 240 +++++++----------- ...ion__backup-tar-summary-first-windows.snap | 10 +- ...on__backup-tar-summary-second-windows.snap | 12 +- ...ion__dryrun-tar-summary-first-windows.snap | 10 +- ...on__dryrun-tar-summary-second-windows.snap | 12 +- 5 files changed, 116 insertions(+), 168 deletions(-) diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index 380fd3ef..51c8aae5 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -1,6 +1,6 @@ use anyhow::Result; use flate2::read::GzDecoder; -use insta::assert_ron_snapshot; +use insta::{assert_ron_snapshot, Settings}; use pretty_assertions::assert_eq; use rstest::fixture; use rstest::rstest; @@ -49,6 +49,45 @@ impl TestSource { } } +// Readme: https://docs.rs/insta/latest/insta/struct.Settings.html +#[fixture] +fn insta_summary_redaction() -> Settings { + let mut settings = insta::Settings::clone_current(); + + settings.add_redaction(".tree", "[tree_id]"); + settings.add_redaction(".program_version", "[version]"); + settings.add_redaction(".time", "[time]"); + settings.add_redaction(".tags", "[tags]"); + settings.add_redaction(".id", "[id]"); + settings.add_redaction(".summary.backup_start", "[backup_start]"); + settings.add_redaction(".summary.backup_end", "[backup_end]"); + settings.add_redaction(".summary.backup_duration", "[backup_duration]"); + settings.add_redaction(".summary.total_duration", "[total_duration]"); + settings.add_redaction(".summary.data_added", "[data_added]"); + settings.add_redaction(".summary.data_added_packed", "[data_added_packed]"); + settings.add_redaction( + ".summary.total_dirsize_processed", + "[total_dirsize_processed]", + ); + settings.add_redaction( + ".summary.data_added_trees_packed", + "[data_added_trees_packed]", + ); + settings.add_redaction(".summary.data_added_trees", "[data_added_trees]"); + + settings +} + +#[fixture] +fn insta_tree_redaction() -> Settings { + let mut settings = insta::Settings::clone_current(); + + settings.add_redaction(".nodes[].ctime", "[ctime]"); + settings.add_redaction(".nodes[].content", "[content_id]"); + + settings +} + #[fixture] fn tar_gz_testdata() -> Result { let dir = tempdir()?; @@ -77,6 +116,8 @@ struct TestSummary<'a>(&'a SnapshotFile); fn test_backup_with_tar_gz_passes( tar_gz_testdata: Result, set_up_repo: Result, + insta_summary_redaction: Settings, + insta_tree_redaction: Settings, ) -> Result<()> { // uncomment for logging output // SimpleLogger::init(log::LevelFilter::Debug, Config::default())?; @@ -93,35 +134,16 @@ fn test_backup_with_tar_gz_passes( let first_snapshot = repo.backup(&opts, paths, SnapshotFile::default())?; #[cfg(windows)] - assert_ron_snapshot!( - "backup-tar-summary-first-windows", - TestSummary(&first_snapshot), - { - ".tree" => "[tree_id]", - ".program_version" => "[version]", - ".time" => "[time]", - ".tags" => "[tags]", - ".id" => "[id]", - ".summary.backup_start" => "[backup_start]", - ".summary.backup_end" => "[backup_end]", - ".summary.backup_duration" => "[backup_duration]", - ".summary.total_duration" => "[total_duration]", - } - ); + insta_summary_redaction.bind(|| { + assert_ron_snapshot!( + "backup-tar-summary-first-windows", + TestSummary(&first_snapshot) + ); + }); #[cfg(not(windows))] - assert_ron_snapshot!("backup-tar-summary-first-nix", - TestSummary(&first_snapshot), - { - ".tree" => "[tree_id]", - ".program_version" => "[version]", - ".time" => "[time]", - ".tags" => "[tags]", - ".id" => "[id]", - ".summary.backup_start" => "[backup_start]", - ".summary.backup_end" => "[backup_end]", - ".summary.backup_duration" => "[backup_duration]", - ".summary.total_duration" => "[total_duration]", + insta_summary_redaction.bind(|| { + assert_ron_snapshot!("backup-tar-summary-first-nix", TestSummary(&first_snapshot)); }); assert_eq!(first_snapshot.parent, None); @@ -133,24 +155,14 @@ fn test_backup_with_tar_gz_passes( let tree: rustic_core::repofile::Tree = repo.get_tree(&tree.subtree.expect("Sub tree"))?; #[cfg(windows)] - assert_ron_snapshot!( - "backup-tar-tree-windows", - tree, - { - ".nodes[].ctime" => "[ctime]", - ".nodes[].content" => "[content_id]", - } - ); + insta_tree_redaction.bind(|| { + assert_ron_snapshot!("backup-tar-tree-windows", tree); + }); #[cfg(not(windows))] - assert_ron_snapshot!( - "backup-tar-tree-nix", - tree, - { - ".nodes[].ctime" => "[ctime]", - ".nodes[].content" => "[content_id]", - } - ); + insta_tree_redaction.bind(|| { + assert_ron_snapshot!("backup-tar-tree-nix", tree); + }); // get all snapshots and check them let all_snapshots = repo.get_all_snapshots()?; @@ -164,37 +176,20 @@ fn test_backup_with_tar_gz_passes( let second_snapshot = repo.backup(&opts, paths, SnapshotFile::default())?; #[cfg(windows)] - assert_ron_snapshot!( - "backup-tar-summary-second-windows", - TestSummary(&second_snapshot), - { - ".tree" => "[tree_id]", - ".program_version" => "[version]", - ".time" => "[time]", - ".tags" => "[tags]", - ".id" => "[id]", - ".summary.backup_start" => "[backup_start]", - ".summary.backup_end" => "[backup_end]", - ".summary.backup_duration" => "[backup_duration]", - ".summary.total_duration" => "[total_duration]", - } - ); + insta_summary_redaction.bind(|| { + assert_ron_snapshot!( + "backup-tar-summary-second-windows", + TestSummary(&second_snapshot) + ); + }); + #[cfg(not(windows))] - assert_ron_snapshot!( - "backup-tar-summary-second-nix", - TestSummary(&second_snapshot), - { - ".tree" => "[tree_id]", - ".program_version" => "[version]", - ".time" => "[time]", - ".tags" => "[tags]", - ".id" => "[id]", - ".summary.backup_start" => "[backup_start]", - ".summary.backup_end" => "[backup_end]", - ".summary.backup_duration" => "[backup_duration]", - ".summary.total_duration" => "[total_duration]", - } - ); + insta_summary_redaction.bind(|| { + assert_ron_snapshot!( + "backup-tar-summary-second-nix", + TestSummary(&second_snapshot) + ); + }); assert_eq!(second_snapshot.parent, Some(first_snapshot.id)); assert_eq!(first_snapshot.tree, second_snapshot.tree); @@ -214,6 +209,8 @@ fn test_backup_with_tar_gz_passes( fn test_backup_dry_run_with_tar_gz_passes( tar_gz_testdata: Result, set_up_repo: Result, + insta_summary_redaction: Settings, + insta_tree_redaction: Settings, ) -> Result<()> { // Fixtures let (source, repo) = (tar_gz_testdata?, set_up_repo?.to_indexed_ids()?); @@ -229,35 +226,16 @@ fn test_backup_dry_run_with_tar_gz_passes( let snap_dry_run = repo.backup(&opts, paths, SnapshotFile::default())?; #[cfg(windows)] - assert_ron_snapshot!( - "dryrun-tar-summary-first-windows", - TestSummary(&snap_dry_run), - { - ".tree" => "[tree_id]", - ".program_version" => "[version]", - ".time" => "[time]", - ".tags" => "[tags]", - ".id" => "[id]", - ".summary.backup_start" => "[backup_start]", - ".summary.backup_end" => "[backup_end]", - ".summary.backup_duration" => "[backup_duration]", - ".summary.total_duration" => "[total_duration]", - } - ); + insta_summary_redaction.bind(|| { + assert_ron_snapshot!( + "dryrun-tar-summary-first-windows", + TestSummary(&snap_dry_run) + ); + }); #[cfg(not(windows))] - assert_ron_snapshot!("dryrun-tar-summary-first-nix", - TestSummary(&snap_dry_run), - { - ".tree" => "[tree_id]", - ".program_version" => "[version]", - ".time" => "[time]", - ".tags" => "[tags]", - ".id" => "[id]", - ".summary.backup_start" => "[backup_start]", - ".summary.backup_end" => "[backup_end]", - ".summary.backup_duration" => "[backup_duration]", - ".summary.total_duration" => "[total_duration]", + insta_summary_redaction.bind(|| { + assert_ron_snapshot!("dryrun-tar-summary-first-nix", TestSummary(&snap_dry_run)); }); // check that repo is still empty @@ -279,24 +257,14 @@ fn test_backup_dry_run_with_tar_gz_passes( let tree = repo.get_tree(&tree.subtree.expect("Sub tree"))?; #[cfg(windows)] - assert_ron_snapshot!( - "dryrun-tar-tree-windows", - tree, - { - ".nodes[].ctime" => "[ctime]", - ".nodes[].content" => "[content_id]", - } - ); + insta_tree_redaction.bind(|| { + assert_ron_snapshot!("dryrun-tar-tree-windows", tree); + }); #[cfg(not(windows))] - assert_ron_snapshot!( - "dryrun-tar-tree-nix", - tree, - { - ".nodes[].ctime" => "[ctime]", - ".nodes[].content" => "[content_id]", - } - ); + insta_tree_redaction.bind(|| { + assert_ron_snapshot!("dryrun-tar-tree-nix", tree); + }); // re-read index let repo = repo.to_indexed_ids()?; @@ -305,37 +273,17 @@ fn test_backup_dry_run_with_tar_gz_passes( let snap_dry_run = repo.backup(&opts, paths, SnapshotFile::default())?; #[cfg(windows)] - assert_ron_snapshot!( - "dryrun-tar-summary-second-windows", - TestSummary(&snap_dry_run), - { - ".tree" => "[tree_id]", - ".program_version" => "[version]", - ".time" => "[time]", - ".tags" => "[tags]", - ".id" => "[id]", - ".summary.backup_start" => "[backup_start]", - ".summary.backup_end" => "[backup_end]", - ".summary.backup_duration" => "[backup_duration]", - ".summary.total_duration" => "[total_duration]", - } - ); + insta_summary_redaction.bind(|| { + assert_ron_snapshot!( + "dryrun-tar-summary-second-windows", + TestSummary(&snap_dry_run) + ); + }); #[cfg(not(windows))] - assert_ron_snapshot!("dryrun-tar-summary-second-nix", - TestSummary(&snap_dry_run), - { - ".tree" => "[tree_id]", - ".program_version" => "[version]", - ".time" => "[time]", - ".tags" => "[tags]", - ".id" => "[id]", - ".summary.backup_start" => "[backup_start]", - ".summary.backup_end" => "[backup_end]", - ".summary.backup_duration" => "[backup_duration]", - ".summary.total_duration" => "[total_duration]", - } - ); + insta_summary_redaction.bind(|| { + assert_ron_snapshot!("dryrun-tar-summary-second-nix", TestSummary(&snap_dry_run)); + }); // check that no data has been added let snaps = repo.get_all_snapshots()?; diff --git a/crates/core/tests/snapshots/integration__backup-tar-summary-first-windows.snap b/crates/core/tests/snapshots/integration__backup-tar-summary-first-windows.snap index d6c4a690..a6ebbc17 100644 --- a/crates/core/tests/snapshots/integration__backup-tar-summary-first-windows.snap +++ b/crates/core/tests/snapshots/integration__backup-tar-summary-first-windows.snap @@ -24,15 +24,15 @@ TestSummary(SnapshotFile( dirs_changed: 0, dirs_unmodified: 0, total_dirs_processed: 6, - total_dirsize_processed: 18471, + total_dirsize_processed: "[total_dirsize_processed]", data_blobs: 70, tree_blobs: 6, - data_added: 1144124, - data_added_packed: 82916, + data_added: "[data_added]", + data_added_packed: "[data_added_packed]", data_added_files: 1125653, data_added_files_packed: 78740, - data_added_trees: 18471, - data_added_trees_packed: 4176, + data_added_trees: "[data_added_trees]", + data_added_trees_packed: "[data_added_trees_packed]", command: "", backup_start: "[backup_start]", backup_end: "[backup_end]", diff --git a/crates/core/tests/snapshots/integration__backup-tar-summary-second-windows.snap b/crates/core/tests/snapshots/integration__backup-tar-summary-second-windows.snap index f7f264cf..15ee6998 100644 --- a/crates/core/tests/snapshots/integration__backup-tar-summary-second-windows.snap +++ b/crates/core/tests/snapshots/integration__backup-tar-summary-second-windows.snap @@ -5,7 +5,7 @@ expression: TestSummary(&second_snapshot) TestSummary(SnapshotFile( time: "[time]", program_version: "[version]", - parent: Some(Id("7b7085ce125bcbbda8bcfcc1c8f7aa7b82a4e7f240efd5feaade6416dcb31c7e")), + parent: Some(Id("1e1c441c94bb94db891589deac182ac69d2cf2c8a434081e5608515553833cd1")), tree: "[tree_id]", paths: StringList([ "test", @@ -25,15 +25,15 @@ TestSummary(SnapshotFile( dirs_changed: 0, dirs_unmodified: 6, total_dirs_processed: 6, - total_dirsize_processed: 18471, + total_dirsize_processed: "[total_dirsize_processed]", data_blobs: 0, tree_blobs: 0, - data_added: 0, - data_added_packed: 0, + data_added: "[data_added]", + data_added_packed: "[data_added_packed]", data_added_files: 0, data_added_files_packed: 0, - data_added_trees: 0, - data_added_trees_packed: 0, + data_added_trees: "[data_added_trees]", + data_added_trees_packed: "[data_added_trees_packed]", command: "", backup_start: "[backup_start]", backup_end: "[backup_end]", diff --git a/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-windows.snap b/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-windows.snap index 55495eee..10df22b4 100644 --- a/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-windows.snap +++ b/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-windows.snap @@ -24,15 +24,15 @@ TestSummary(SnapshotFile( dirs_changed: 0, dirs_unmodified: 0, total_dirs_processed: 6, - total_dirsize_processed: 18465, + total_dirsize_processed: "[total_dirsize_processed]", data_blobs: 70, tree_blobs: 6, - data_added: 1144118, - data_added_packed: 82905, + data_added: "[data_added]", + data_added_packed: "[data_added_packed]", data_added_files: 1125653, data_added_files_packed: 78740, - data_added_trees: 18465, - data_added_trees_packed: 4165, + data_added_trees: "[data_added_trees]", + data_added_trees_packed: "[data_added_trees_packed]", command: "", backup_start: "[backup_start]", backup_end: "[backup_end]", diff --git a/crates/core/tests/snapshots/integration__dryrun-tar-summary-second-windows.snap b/crates/core/tests/snapshots/integration__dryrun-tar-summary-second-windows.snap index 66965dc6..11cac455 100644 --- a/crates/core/tests/snapshots/integration__dryrun-tar-summary-second-windows.snap +++ b/crates/core/tests/snapshots/integration__dryrun-tar-summary-second-windows.snap @@ -5,7 +5,7 @@ expression: TestSummary(&snap_dry_run) TestSummary(SnapshotFile( time: "[time]", program_version: "[version]", - parent: Some(Id("0c7ab572c3c7498fa3b941a9803ab950a52a846c2ad78579b3249af4508bf6c5")), + parent: Some(Id("f25b23c13b9c895d57d6017d466abe317b57b5db280c996d86ea1fe4db423743")), tree: "[tree_id]", paths: StringList([ "test", @@ -25,15 +25,15 @@ TestSummary(SnapshotFile( dirs_changed: 0, dirs_unmodified: 6, total_dirs_processed: 6, - total_dirsize_processed: 18465, + total_dirsize_processed: "[total_dirsize_processed]", data_blobs: 0, tree_blobs: 0, - data_added: 0, - data_added_packed: 0, + data_added: "[data_added]", + data_added_packed: "[data_added_packed]", data_added_files: 0, data_added_files_packed: 0, - data_added_trees: 0, - data_added_trees_packed: 0, + data_added_trees: "[data_added_trees]", + data_added_trees_packed: "[data_added_trees_packed]", command: "", backup_start: "[backup_start]", backup_end: "[backup_end]", From cbe7379ecb80f8a052ed7e41993462bbb9efbcea Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Wed, 13 Mar 2024 04:51:09 +0100 Subject: [PATCH 29/46] update ubuntu snapshots Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- .../integration__backup-tar-summary-first-nix.snap | 10 +++++----- .../integration__dryrun-tar-summary-first-nix.snap | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/crates/core/tests/snapshots/integration__backup-tar-summary-first-nix.snap b/crates/core/tests/snapshots/integration__backup-tar-summary-first-nix.snap index 8532beb0..a6ebbc17 100644 --- a/crates/core/tests/snapshots/integration__backup-tar-summary-first-nix.snap +++ b/crates/core/tests/snapshots/integration__backup-tar-summary-first-nix.snap @@ -24,15 +24,15 @@ TestSummary(SnapshotFile( dirs_changed: 0, dirs_unmodified: 0, total_dirs_processed: 6, - total_dirsize_processed: 25591, + total_dirsize_processed: "[total_dirsize_processed]", data_blobs: 70, tree_blobs: 6, - data_added: 1151244, - data_added_packed: 83222, + data_added: "[data_added]", + data_added_packed: "[data_added_packed]", data_added_files: 1125653, data_added_files_packed: 78740, - data_added_trees: 25591, - data_added_trees_packed: 4482, + data_added_trees: "[data_added_trees]", + data_added_trees_packed: "[data_added_trees_packed]", command: "", backup_start: "[backup_start]", backup_end: "[backup_end]", diff --git a/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-nix.snap b/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-nix.snap index 9ced6b92..10df22b4 100644 --- a/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-nix.snap +++ b/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-nix.snap @@ -24,15 +24,15 @@ TestSummary(SnapshotFile( dirs_changed: 0, dirs_unmodified: 0, total_dirs_processed: 6, - total_dirsize_processed: 25591, + total_dirsize_processed: "[total_dirsize_processed]", data_blobs: 70, tree_blobs: 6, - data_added: 1151244, - data_added_packed: 83235, + data_added: "[data_added]", + data_added_packed: "[data_added_packed]", data_added_files: 1125653, data_added_files_packed: 78740, - data_added_trees: 25591, - data_added_trees_packed: 4495, + data_added_trees: "[data_added_trees]", + data_added_trees_packed: "[data_added_trees_packed]", command: "", backup_start: "[backup_start]", backup_end: "[backup_end]", From 2141cda9fd707c4b71721d62a770b869565835cd Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Wed, 13 Mar 2024 04:57:42 +0100 Subject: [PATCH 30/46] add comment about testing Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/core/tests/integration.rs | 50 +++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index 51c8aae5..4269e07c 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -1,3 +1,28 @@ +//! Integration tests for the core library +//! +//! # How to update snapshots +//! +//! The CI pipeline is configured to run the tests with the `INSTA_UPDATE` environment variable set to `new`. +//! This means, it uploads the failed tests snapshots to the artifacts and you can download them and use them to update the snapshots. +//! +//! To update the snapshots, you download the artifacts and copy the files to the `tests/snapshots` directory. +//! Then you run `cargo insta review` to review the changes and accept them. +//! +//! # Redactions +//! +//! We use the `insta` crate to compare the actual output of the tests with the expected output. +//! Some data in the output changes every test run, we use insta's redactions to replace the actual values with placeholders. +//! We define the redactions inside `Settings`` in the fixtures and bind them to the test functions. You can read more about +//! it here: https://docs.rs/insta/latest/insta/struct.Settings.html +//! +//! # Fixtures and Dependency Injection +//! +//! We use the `rstest` crate to define fixtures and dependency injection. +//! This allows us to define a set of fixtures that are used in multiple tests. +//! The fixtures are defined as functions with the `#[fixture]` attribute. +//! The tests that use the fixtures are defined as functions with the `#[rstest]` attribute. +//! The fixtures are passed as arguments to the test functions. + use anyhow::Result; use flate2::read::GzDecoder; use insta::{assert_ron_snapshot, Settings}; @@ -24,18 +49,6 @@ use tempfile::{tempdir, TempDir}; type RepoOpen = Repository; -#[fixture] -fn set_up_repo() -> Result { - let be = InMemoryBackend::new(); - let be = RepositoryBackends::new(Arc::new(be), None); - let options = RepositoryOptions::default().password("test"); - let repo = Repository::new(&options, &be)?; - let key_opts = KeyOptions::default(); - let config_opts = &ConfigOptions::default(); - let repo = repo.init(&key_opts, config_opts)?; - Ok(repo) -} - #[derive(Debug)] struct TestSource(TempDir); @@ -49,7 +62,18 @@ impl TestSource { } } -// Readme: https://docs.rs/insta/latest/insta/struct.Settings.html +#[fixture] +fn set_up_repo() -> Result { + let be = InMemoryBackend::new(); + let be = RepositoryBackends::new(Arc::new(be), None); + let options = RepositoryOptions::default().password("test"); + let repo = Repository::new(&options, &be)?; + let key_opts = KeyOptions::default(); + let config_opts = &ConfigOptions::default(); + let repo = repo.init(&key_opts, config_opts)?; + Ok(repo) +} + #[fixture] fn insta_summary_redaction() -> Settings { let mut settings = insta::Settings::clone_current(); From 80c03a1afe1a16581ee960c285c3bd38b78a00f5 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Wed, 13 Mar 2024 05:00:50 +0100 Subject: [PATCH 31/46] update redactions for trees Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/core/tests/integration.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index 4269e07c..84800832 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -107,6 +107,12 @@ fn insta_tree_redaction() -> Settings { let mut settings = insta::Settings::clone_current(); settings.add_redaction(".nodes[].ctime", "[ctime]"); + settings.add_redaction(".nodes[].inode", "[inode]"); + settings.add_redaction(".nodes[].device_id", "[device_id]"); + settings.add_redaction(".nodes[].uid", "[uid]"); + settings.add_redaction(".nodes[].user", "[user]"); + settings.add_redaction(".nodes[].gid", "[gid]"); + settings.add_redaction(".nodes[].group", "[group]"); settings.add_redaction(".nodes[].content", "[content_id]"); settings From 3f51f3b0729a0c5209e82e0268f7e20f06578bf1 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Wed, 13 Mar 2024 05:20:55 +0100 Subject: [PATCH 32/46] get fancy with redactions Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/core/tests/integration.rs | 15 ++++++++++++++- ...gration__backup-tar-summary-first-windows.snap | 2 +- ...ration__backup-tar-summary-second-windows.snap | 4 ++-- ...gration__dryrun-tar-summary-first-windows.snap | 2 +- ...ration__dryrun-tar-summary-second-windows.snap | 4 ++-- 5 files changed, 20 insertions(+), 7 deletions(-) diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index 84800832..9b56e148 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -79,8 +79,21 @@ fn insta_summary_redaction() -> Settings { let mut settings = insta::Settings::clone_current(); settings.add_redaction(".tree", "[tree_id]"); - settings.add_redaction(".program_version", "[version]"); + settings.add_dynamic_redaction(".program_version", |val, _| { + val.resolve_inner() + .as_str() + .map_or("[program_version]".to_string(), |v| { + v.replace(env!("CARGO_PKG_VERSION"), "[rustic_core_version]") + }) + }); settings.add_redaction(".time", "[time]"); + settings.add_dynamic_redaction(".parent", |val, _| { + if val.is_nil() { + "[none]".to_string() + } else { + "[some]".to_string() + } + }); settings.add_redaction(".tags", "[tags]"); settings.add_redaction(".id", "[id]"); settings.add_redaction(".summary.backup_start", "[backup_start]"); diff --git a/crates/core/tests/snapshots/integration__backup-tar-summary-first-windows.snap b/crates/core/tests/snapshots/integration__backup-tar-summary-first-windows.snap index a6ebbc17..6a4a9251 100644 --- a/crates/core/tests/snapshots/integration__backup-tar-summary-first-windows.snap +++ b/crates/core/tests/snapshots/integration__backup-tar-summary-first-windows.snap @@ -4,7 +4,7 @@ expression: TestSummary(&first_snapshot) --- TestSummary(SnapshotFile( time: "[time]", - program_version: "[version]", + program_version: "rustic [rustic_core_version]", tree: "[tree_id]", paths: StringList([ "test", diff --git a/crates/core/tests/snapshots/integration__backup-tar-summary-second-windows.snap b/crates/core/tests/snapshots/integration__backup-tar-summary-second-windows.snap index 15ee6998..b2f88d43 100644 --- a/crates/core/tests/snapshots/integration__backup-tar-summary-second-windows.snap +++ b/crates/core/tests/snapshots/integration__backup-tar-summary-second-windows.snap @@ -4,8 +4,8 @@ expression: TestSummary(&second_snapshot) --- TestSummary(SnapshotFile( time: "[time]", - program_version: "[version]", - parent: Some(Id("1e1c441c94bb94db891589deac182ac69d2cf2c8a434081e5608515553833cd1")), + program_version: "rustic [rustic_core_version]", + parent: "[some]", tree: "[tree_id]", paths: StringList([ "test", diff --git a/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-windows.snap b/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-windows.snap index 10df22b4..01f95b03 100644 --- a/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-windows.snap +++ b/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-windows.snap @@ -4,7 +4,7 @@ expression: TestSummary(&snap_dry_run) --- TestSummary(SnapshotFile( time: "[time]", - program_version: "[version]", + program_version: "rustic [rustic_core_version]", tree: "[tree_id]", paths: StringList([ "test", diff --git a/crates/core/tests/snapshots/integration__dryrun-tar-summary-second-windows.snap b/crates/core/tests/snapshots/integration__dryrun-tar-summary-second-windows.snap index 11cac455..b6169e59 100644 --- a/crates/core/tests/snapshots/integration__dryrun-tar-summary-second-windows.snap +++ b/crates/core/tests/snapshots/integration__dryrun-tar-summary-second-windows.snap @@ -4,8 +4,8 @@ expression: TestSummary(&snap_dry_run) --- TestSummary(SnapshotFile( time: "[time]", - program_version: "[version]", - parent: Some(Id("f25b23c13b9c895d57d6017d466abe317b57b5db280c996d86ea1fe4db423743")), + program_version: "rustic [rustic_core_version]", + parent: "[some]", tree: "[tree_id]", paths: StringList([ "test", From 99f5e4948b08ca29c6504b3c14b4ff08f8acb664 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Wed, 13 Mar 2024 05:23:17 +0100 Subject: [PATCH 33/46] add command about binding to scope Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/core/tests/integration.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index 9b56e148..3ddd7466 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -176,6 +176,9 @@ fn test_backup_with_tar_gz_passes( // first backup let first_snapshot = repo.backup(&opts, paths, SnapshotFile::default())?; + // We can also bind to scope ( https://docs.rs/insta/latest/insta/struct.Settings.html#method.bind_to_scope ) + // But I think that can get messy with a lot of tests, also checking which settings are currently applied + // will be probably harder #[cfg(windows)] insta_summary_redaction.bind(|| { assert_ron_snapshot!( From 4789b7e56b138fb713be366917b7ea4fbc560f6c Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Wed, 13 Mar 2024 05:24:37 +0100 Subject: [PATCH 34/46] fix clippy Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/core/tests/integration.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index 3ddd7466..924a9aaf 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -12,8 +12,8 @@ //! //! We use the `insta` crate to compare the actual output of the tests with the expected output. //! Some data in the output changes every test run, we use insta's redactions to replace the actual values with placeholders. -//! We define the redactions inside `Settings`` in the fixtures and bind them to the test functions. You can read more about -//! it here: https://docs.rs/insta/latest/insta/struct.Settings.html +//! We define the redactions inside `Settings` in the fixtures and bind them to the test functions. You can read more about +//! it [here](https://docs.rs/insta/latest/insta/struct.Settings.html). //! //! # Fixtures and Dependency Injection //! From e5ae77c83422ec1f9b813d7f902378fa5df651d4 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Wed, 13 Mar 2024 05:32:01 +0100 Subject: [PATCH 35/46] update snapshots Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- .../snapshots/integration__backup-tar-summary-first-nix.snap | 2 +- .../snapshots/integration__dryrun-tar-summary-first-nix.snap | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/core/tests/snapshots/integration__backup-tar-summary-first-nix.snap b/crates/core/tests/snapshots/integration__backup-tar-summary-first-nix.snap index a6ebbc17..6a4a9251 100644 --- a/crates/core/tests/snapshots/integration__backup-tar-summary-first-nix.snap +++ b/crates/core/tests/snapshots/integration__backup-tar-summary-first-nix.snap @@ -4,7 +4,7 @@ expression: TestSummary(&first_snapshot) --- TestSummary(SnapshotFile( time: "[time]", - program_version: "[version]", + program_version: "rustic [rustic_core_version]", tree: "[tree_id]", paths: StringList([ "test", diff --git a/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-nix.snap b/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-nix.snap index 10df22b4..01f95b03 100644 --- a/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-nix.snap +++ b/crates/core/tests/snapshots/integration__dryrun-tar-summary-first-nix.snap @@ -4,7 +4,7 @@ expression: TestSummary(&snap_dry_run) --- TestSummary(SnapshotFile( time: "[time]", - program_version: "[version]", + program_version: "rustic [rustic_core_version]", tree: "[tree_id]", paths: StringList([ "test", From 6d6c00af51367ade9b57d1d4490f5c6178386cac Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Wed, 13 Mar 2024 05:39:37 +0100 Subject: [PATCH 36/46] update snapshots Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- .../integration__backup-tar-tree-nix.snap | 76 +++++++++++++++++++ .../integration__dryrun-tar-tree-nix.snap | 76 +++++++++++++++++++ 2 files changed, 152 insertions(+) create mode 100644 crates/core/tests/snapshots/integration__backup-tar-tree-nix.snap create mode 100644 crates/core/tests/snapshots/integration__dryrun-tar-tree-nix.snap diff --git a/crates/core/tests/snapshots/integration__backup-tar-tree-nix.snap b/crates/core/tests/snapshots/integration__backup-tar-tree-nix.snap new file mode 100644 index 00000000..b61be3e6 --- /dev/null +++ b/crates/core/tests/snapshots/integration__backup-tar-tree-nix.snap @@ -0,0 +1,76 @@ +--- +source: crates/core/tests/integration.rs +expression: tree +--- +Tree( + nodes: [ + { + "name": "empty-file", + "type": "file", + "mode": Some(420), + "mtime": Some("2014-11-30T15:03:11Z"), + "atime": Some("2014-11-30T15:03:11Z"), + "ctime": "[ctime]", + "uid": "[uid]", + "gid": "[gid]", + "user": "[user]", + "group": "[group]", + "inode": "[inode]", + "device_id": "[device_id]", + "links": 1, + "content": "[content_id]", + }, + { + "name": "testfile", + "type": "file", + "mode": Some(420), + "mtime": Some("2014-08-09T12:14:20Z"), + "atime": Some("2014-08-09T12:14:20Z"), + "ctime": "[ctime]", + "uid": "[uid]", + "gid": "[gid]", + "user": "[user]", + "group": "[group]", + "inode": "[inode]", + "device_id": "[device_id]", + "size": 21, + "links": 2, + "content": "[content_id]", + }, + { + "name": "testfile-hardlink", + "type": "file", + "mode": Some(420), + "mtime": Some("2014-08-09T12:14:20Z"), + "atime": Some("2014-08-09T12:14:20Z"), + "ctime": "[ctime]", + "uid": "[uid]", + "gid": "[gid]", + "user": "[user]", + "group": "[group]", + "inode": "[inode]", + "device_id": "[device_id]", + "size": 21, + "links": 2, + "content": "[content_id]", + }, + { + "name": "testfile-symlink", + "type": "symlink", + "linktarget": "testfile", + "mode": Some(134218239), + "mtime": Some("2014-08-09T12:14:28Z"), + "atime": Some("2014-08-09T12:14:28Z"), + "ctime": "[ctime]", + "uid": "[uid]", + "gid": "[gid]", + "user": "[user]", + "group": "[group]", + "inode": "[inode]", + "device_id": "[device_id]", + "size": 8, + "links": 1, + "content": "[content_id]", + }, + ], +) diff --git a/crates/core/tests/snapshots/integration__dryrun-tar-tree-nix.snap b/crates/core/tests/snapshots/integration__dryrun-tar-tree-nix.snap new file mode 100644 index 00000000..b61be3e6 --- /dev/null +++ b/crates/core/tests/snapshots/integration__dryrun-tar-tree-nix.snap @@ -0,0 +1,76 @@ +--- +source: crates/core/tests/integration.rs +expression: tree +--- +Tree( + nodes: [ + { + "name": "empty-file", + "type": "file", + "mode": Some(420), + "mtime": Some("2014-11-30T15:03:11Z"), + "atime": Some("2014-11-30T15:03:11Z"), + "ctime": "[ctime]", + "uid": "[uid]", + "gid": "[gid]", + "user": "[user]", + "group": "[group]", + "inode": "[inode]", + "device_id": "[device_id]", + "links": 1, + "content": "[content_id]", + }, + { + "name": "testfile", + "type": "file", + "mode": Some(420), + "mtime": Some("2014-08-09T12:14:20Z"), + "atime": Some("2014-08-09T12:14:20Z"), + "ctime": "[ctime]", + "uid": "[uid]", + "gid": "[gid]", + "user": "[user]", + "group": "[group]", + "inode": "[inode]", + "device_id": "[device_id]", + "size": 21, + "links": 2, + "content": "[content_id]", + }, + { + "name": "testfile-hardlink", + "type": "file", + "mode": Some(420), + "mtime": Some("2014-08-09T12:14:20Z"), + "atime": Some("2014-08-09T12:14:20Z"), + "ctime": "[ctime]", + "uid": "[uid]", + "gid": "[gid]", + "user": "[user]", + "group": "[group]", + "inode": "[inode]", + "device_id": "[device_id]", + "size": 21, + "links": 2, + "content": "[content_id]", + }, + { + "name": "testfile-symlink", + "type": "symlink", + "linktarget": "testfile", + "mode": Some(134218239), + "mtime": Some("2014-08-09T12:14:28Z"), + "atime": Some("2014-08-09T12:14:28Z"), + "ctime": "[ctime]", + "uid": "[uid]", + "gid": "[gid]", + "user": "[user]", + "group": "[group]", + "inode": "[inode]", + "device_id": "[device_id]", + "size": 8, + "links": 1, + "content": "[content_id]", + }, + ], +) From 996228d69335de5ab66a7f067425ae5f77c57bc9 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Wed, 13 Mar 2024 05:42:38 +0100 Subject: [PATCH 37/46] ci: don't fail fast for tests Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 31f2767c..18a2aca1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,6 +43,8 @@ jobs: name: Test runs-on: ${{ matrix.job.os }} strategy: + # Don't fail fast, so we can actually see all the results + fail-fast: false matrix: rust: [stable] job: From 405c93188c77a86cd8b17f2b30a87531f21d905c Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Wed, 13 Mar 2024 05:45:58 +0100 Subject: [PATCH 38/46] ci: don't run in release mode Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- .github/workflows/ci-heavy.yml | 2 +- .github/workflows/ci.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-heavy.yml b/.github/workflows/ci-heavy.yml index e31b765d..7527f6a7 100644 --- a/.github/workflows/ci-heavy.yml +++ b/.github/workflows/ci-heavy.yml @@ -83,7 +83,7 @@ jobs: toolchain: ${{ matrix.rust }} - uses: Swatinem/rust-cache@23bce251a8cd2ffc3c1075eaa2367cf899916d84 # v2 - name: Run Cargo Test - run: cargo +${{ matrix.rust }} test -r --all-targets --all-features --workspace --examples + run: cargo +${{ matrix.rust }} test --all-targets --all-features --workspace --examples id: run_tests env: INSTA_UPDATE: new diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 18a2aca1..f9f58e05 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -69,7 +69,7 @@ jobs: toolchain: ${{ matrix.rust }} - uses: Swatinem/rust-cache@23bce251a8cd2ffc3c1075eaa2367cf899916d84 # v2 - name: Run Cargo Test - run: cargo +${{ matrix.rust }} test -r --all-targets --all-features --workspace --examples + run: cargo +${{ matrix.rust }} test --all-targets --all-features --workspace --examples id: run_tests env: INSTA_UPDATE: new From ac8286675fc9444cba80d228a02c11155a2046b7 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Wed, 13 Mar 2024 06:18:54 +0100 Subject: [PATCH 39/46] update snapshots and redactions Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/core/tests/integration.rs | 29 +++++++++++- ...ration__backup-tar-summary-second-nix.snap | 44 +++++++++++++++++++ .../integration__backup-tar-tree-nix.snap | 2 +- .../integration__backup-tar-tree-windows.snap | 24 +++++----- ...ration__dryrun-tar-summary-second-nix.snap | 43 ++++++++++++++++++ .../integration__dryrun-tar-tree-nix.snap | 2 +- .../integration__dryrun-tar-tree-windows.snap | 24 +++++----- 7 files changed, 141 insertions(+), 27 deletions(-) create mode 100644 crates/core/tests/snapshots/integration__backup-tar-summary-second-nix.snap create mode 100644 crates/core/tests/snapshots/integration__dryrun-tar-summary-second-nix.snap diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index 924a9aaf..b348326c 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -119,7 +119,6 @@ fn insta_summary_redaction() -> Settings { fn insta_tree_redaction() -> Settings { let mut settings = insta::Settings::clone_current(); - settings.add_redaction(".nodes[].ctime", "[ctime]"); settings.add_redaction(".nodes[].inode", "[inode]"); settings.add_redaction(".nodes[].device_id", "[device_id]"); settings.add_redaction(".nodes[].uid", "[uid]"); @@ -127,6 +126,34 @@ fn insta_tree_redaction() -> Settings { settings.add_redaction(".nodes[].gid", "[gid]"); settings.add_redaction(".nodes[].group", "[group]"); settings.add_redaction(".nodes[].content", "[content_id]"); + settings.add_dynamic_redaction(".nodes[].mode", |val, _| { + if val.is_nil() { + "[none]".to_string() + } else { + "[some]".to_string() + } + }); + settings.add_dynamic_redaction(".nodes[].mtime", |val, _| { + if val.is_nil() { + "[none]".to_string() + } else { + "[some]".to_string() + } + }); + settings.add_dynamic_redaction(".nodes[].atime", |val, _| { + if val.is_nil() { + "[none]".to_string() + } else { + "[some]".to_string() + } + }); + settings.add_dynamic_redaction(".nodes[].ctime", |val, _| { + if val.is_nil() { + "[none]".to_string() + } else { + "[some]".to_string() + } + }); settings } diff --git a/crates/core/tests/snapshots/integration__backup-tar-summary-second-nix.snap b/crates/core/tests/snapshots/integration__backup-tar-summary-second-nix.snap new file mode 100644 index 00000000..bba6b48d --- /dev/null +++ b/crates/core/tests/snapshots/integration__backup-tar-summary-second-nix.snap @@ -0,0 +1,44 @@ +--- +source: crates/core/tests/integration.rs +expression: TestSummary(&second_snapshot) +--- +TestSummary(SnapshotFile( + time: "[time]", + program_version: "rustic [rustic_core_version]", + parent: "[some]", + tree: "[tree_id]", + paths: StringList([ + "test", + ]), + hostname: "", + username: "", + uid: 0, + gid: 0, + tags: "[tags]", + summary: Some(SnapshotSummary( + files_new: 0, + files_changed: 0, + files_unmodified: 73, + total_files_processed: 73, + total_bytes_processed: 1125682, + dirs_new: 0, + dirs_changed: 0, + dirs_unmodified: 6, + total_dirs_processed: 6, + total_dirsize_processed: "[total_dirsize_processed]", + data_blobs: 0, + tree_blobs: 0, + data_added: "[data_added]", + data_added_packed: "[data_added_packed]", + data_added_files: 0, + data_added_files_packed: 0, + data_added_trees: "[data_added_trees]", + data_added_trees_packed: "[data_added_trees_packed]", + command: "", + backup_start: "[backup_start]", + backup_end: "[backup_end]", + backup_duration: "[backup_duration]", + total_duration: "[total_duration]", + )), + id: "[id]", +)) diff --git a/crates/core/tests/snapshots/integration__backup-tar-tree-nix.snap b/crates/core/tests/snapshots/integration__backup-tar-tree-nix.snap index b61be3e6..5a9a9fe5 100644 --- a/crates/core/tests/snapshots/integration__backup-tar-tree-nix.snap +++ b/crates/core/tests/snapshots/integration__backup-tar-tree-nix.snap @@ -58,7 +58,7 @@ Tree( "name": "testfile-symlink", "type": "symlink", "linktarget": "testfile", - "mode": Some(134218239), + "mode": Some(134218221), "mtime": Some("2014-08-09T12:14:28Z"), "atime": Some("2014-08-09T12:14:28Z"), "ctime": "[ctime]", diff --git a/crates/core/tests/snapshots/integration__backup-tar-tree-windows.snap b/crates/core/tests/snapshots/integration__backup-tar-tree-windows.snap index 89807d2b..9dda5c79 100644 --- a/crates/core/tests/snapshots/integration__backup-tar-tree-windows.snap +++ b/crates/core/tests/snapshots/integration__backup-tar-tree-windows.snap @@ -7,26 +7,26 @@ Tree( { "name": "empty-file", "type": "file", - "mtime": Some("2014-11-30T16:03:11+01:00"), - "atime": Some("2014-11-30T16:03:11+01:00"), - "ctime": "[ctime]", + "mtime": "[some]", + "atime": "[some]", + "ctime": "[some]", "content": "[content_id]", }, { "name": "testfile", "type": "file", - "mtime": Some("2014-08-09T14:14:20+02:00"), - "atime": Some("2014-08-09T14:14:20+02:00"), - "ctime": "[ctime]", + "mtime": "[some]", + "atime": "[some]", + "ctime": "[some]", "size": 21, "content": "[content_id]", }, { "name": "testfile-hardlink", "type": "file", - "mtime": Some("2014-08-09T14:14:20+02:00"), - "atime": Some("2014-08-09T14:14:20+02:00"), - "ctime": "[ctime]", + "mtime": "[some]", + "atime": "[some]", + "ctime": "[some]", "size": 21, "content": "[content_id]", }, @@ -34,9 +34,9 @@ Tree( "name": "testfile-symlink", "type": "symlink", "linktarget": "testfile", - "mtime": Some("2014-08-09T14:14:28+02:00"), - "atime": Some("2014-08-09T14:14:28+02:00"), - "ctime": "[ctime]", + "mtime": "[some]", + "atime": "[some]", + "ctime": "[some]", "content": "[content_id]", }, ], diff --git a/crates/core/tests/snapshots/integration__dryrun-tar-summary-second-nix.snap b/crates/core/tests/snapshots/integration__dryrun-tar-summary-second-nix.snap new file mode 100644 index 00000000..d75737df --- /dev/null +++ b/crates/core/tests/snapshots/integration__dryrun-tar-summary-second-nix.snap @@ -0,0 +1,43 @@ +--- +source: crates/core/tests/integration.rs +expression: TestSummary(&snap_dry_run) +--- +TestSummary(SnapshotFile( + time: "[time]", + program_version: "rustic [rustic_core_version]", + parent: "[some]", + tree: "[tree_id]", + paths: StringList([ + "test", + ]), + hostname: "", + username: "", + uid: 0, + gid: 0, + tags: "[tags]", + summary: Some(SnapshotSummary( + files_new: 0, + files_changed: 0, + files_unmodified: 73, + total_files_processed: 73, + total_bytes_processed: 1125682, + dirs_new: 0, + dirs_changed: 0, + dirs_unmodified: 6, + total_dirs_processed: 6, + total_dirsize_processed: "[total_dirsize_processed]", + data_blobs: 0, + tree_blobs: 0, + data_added: "[data_added]", + data_added_packed: "[data_added_packed]", + data_added_files: 0, + data_added_files_packed: 0, + data_added_trees: "[data_added_trees]", + data_added_trees_packed: "[data_added_trees_packed]", + command: "", + backup_start: "[backup_start]", + backup_end: "[backup_end]", + backup_duration: "[backup_duration]", + total_duration: "[total_duration]", + )), +)) diff --git a/crates/core/tests/snapshots/integration__dryrun-tar-tree-nix.snap b/crates/core/tests/snapshots/integration__dryrun-tar-tree-nix.snap index b61be3e6..5a9a9fe5 100644 --- a/crates/core/tests/snapshots/integration__dryrun-tar-tree-nix.snap +++ b/crates/core/tests/snapshots/integration__dryrun-tar-tree-nix.snap @@ -58,7 +58,7 @@ Tree( "name": "testfile-symlink", "type": "symlink", "linktarget": "testfile", - "mode": Some(134218239), + "mode": Some(134218221), "mtime": Some("2014-08-09T12:14:28Z"), "atime": Some("2014-08-09T12:14:28Z"), "ctime": "[ctime]", diff --git a/crates/core/tests/snapshots/integration__dryrun-tar-tree-windows.snap b/crates/core/tests/snapshots/integration__dryrun-tar-tree-windows.snap index 89807d2b..9dda5c79 100644 --- a/crates/core/tests/snapshots/integration__dryrun-tar-tree-windows.snap +++ b/crates/core/tests/snapshots/integration__dryrun-tar-tree-windows.snap @@ -7,26 +7,26 @@ Tree( { "name": "empty-file", "type": "file", - "mtime": Some("2014-11-30T16:03:11+01:00"), - "atime": Some("2014-11-30T16:03:11+01:00"), - "ctime": "[ctime]", + "mtime": "[some]", + "atime": "[some]", + "ctime": "[some]", "content": "[content_id]", }, { "name": "testfile", "type": "file", - "mtime": Some("2014-08-09T14:14:20+02:00"), - "atime": Some("2014-08-09T14:14:20+02:00"), - "ctime": "[ctime]", + "mtime": "[some]", + "atime": "[some]", + "ctime": "[some]", "size": 21, "content": "[content_id]", }, { "name": "testfile-hardlink", "type": "file", - "mtime": Some("2014-08-09T14:14:20+02:00"), - "atime": Some("2014-08-09T14:14:20+02:00"), - "ctime": "[ctime]", + "mtime": "[some]", + "atime": "[some]", + "ctime": "[some]", "size": 21, "content": "[content_id]", }, @@ -34,9 +34,9 @@ Tree( "name": "testfile-symlink", "type": "symlink", "linktarget": "testfile", - "mtime": Some("2014-08-09T14:14:28+02:00"), - "atime": Some("2014-08-09T14:14:28+02:00"), - "ctime": "[ctime]", + "mtime": "[some]", + "atime": "[some]", + "ctime": "[some]", "content": "[content_id]", }, ], From 7c2062134ddf5d0adfa7a2325bb4112cee14d578 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Wed, 13 Mar 2024 06:47:46 +0100 Subject: [PATCH 40/46] update snapshots Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- .../integration__backup-tar-tree-nix.snap | 32 +++++++++---------- .../integration__dryrun-tar-tree-nix.snap | 32 +++++++++---------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/crates/core/tests/snapshots/integration__backup-tar-tree-nix.snap b/crates/core/tests/snapshots/integration__backup-tar-tree-nix.snap index 5a9a9fe5..e8cbbf82 100644 --- a/crates/core/tests/snapshots/integration__backup-tar-tree-nix.snap +++ b/crates/core/tests/snapshots/integration__backup-tar-tree-nix.snap @@ -7,10 +7,10 @@ Tree( { "name": "empty-file", "type": "file", - "mode": Some(420), - "mtime": Some("2014-11-30T15:03:11Z"), - "atime": Some("2014-11-30T15:03:11Z"), - "ctime": "[ctime]", + "mode": "[some]", + "mtime": "[some]", + "atime": "[some]", + "ctime": "[some]", "uid": "[uid]", "gid": "[gid]", "user": "[user]", @@ -23,10 +23,10 @@ Tree( { "name": "testfile", "type": "file", - "mode": Some(420), - "mtime": Some("2014-08-09T12:14:20Z"), - "atime": Some("2014-08-09T12:14:20Z"), - "ctime": "[ctime]", + "mode": "[some]", + "mtime": "[some]", + "atime": "[some]", + "ctime": "[some]", "uid": "[uid]", "gid": "[gid]", "user": "[user]", @@ -40,10 +40,10 @@ Tree( { "name": "testfile-hardlink", "type": "file", - "mode": Some(420), - "mtime": Some("2014-08-09T12:14:20Z"), - "atime": Some("2014-08-09T12:14:20Z"), - "ctime": "[ctime]", + "mode": "[some]", + "mtime": "[some]", + "atime": "[some]", + "ctime": "[some]", "uid": "[uid]", "gid": "[gid]", "user": "[user]", @@ -58,10 +58,10 @@ Tree( "name": "testfile-symlink", "type": "symlink", "linktarget": "testfile", - "mode": Some(134218221), - "mtime": Some("2014-08-09T12:14:28Z"), - "atime": Some("2014-08-09T12:14:28Z"), - "ctime": "[ctime]", + "mode": "[some]", + "mtime": "[some]", + "atime": "[some]", + "ctime": "[some]", "uid": "[uid]", "gid": "[gid]", "user": "[user]", diff --git a/crates/core/tests/snapshots/integration__dryrun-tar-tree-nix.snap b/crates/core/tests/snapshots/integration__dryrun-tar-tree-nix.snap index 5a9a9fe5..e8cbbf82 100644 --- a/crates/core/tests/snapshots/integration__dryrun-tar-tree-nix.snap +++ b/crates/core/tests/snapshots/integration__dryrun-tar-tree-nix.snap @@ -7,10 +7,10 @@ Tree( { "name": "empty-file", "type": "file", - "mode": Some(420), - "mtime": Some("2014-11-30T15:03:11Z"), - "atime": Some("2014-11-30T15:03:11Z"), - "ctime": "[ctime]", + "mode": "[some]", + "mtime": "[some]", + "atime": "[some]", + "ctime": "[some]", "uid": "[uid]", "gid": "[gid]", "user": "[user]", @@ -23,10 +23,10 @@ Tree( { "name": "testfile", "type": "file", - "mode": Some(420), - "mtime": Some("2014-08-09T12:14:20Z"), - "atime": Some("2014-08-09T12:14:20Z"), - "ctime": "[ctime]", + "mode": "[some]", + "mtime": "[some]", + "atime": "[some]", + "ctime": "[some]", "uid": "[uid]", "gid": "[gid]", "user": "[user]", @@ -40,10 +40,10 @@ Tree( { "name": "testfile-hardlink", "type": "file", - "mode": Some(420), - "mtime": Some("2014-08-09T12:14:20Z"), - "atime": Some("2014-08-09T12:14:20Z"), - "ctime": "[ctime]", + "mode": "[some]", + "mtime": "[some]", + "atime": "[some]", + "ctime": "[some]", "uid": "[uid]", "gid": "[gid]", "user": "[user]", @@ -58,10 +58,10 @@ Tree( "name": "testfile-symlink", "type": "symlink", "linktarget": "testfile", - "mode": Some(134218221), - "mtime": Some("2014-08-09T12:14:28Z"), - "atime": Some("2014-08-09T12:14:28Z"), - "ctime": "[ctime]", + "mode": "[some]", + "mtime": "[some]", + "atime": "[some]", + "ctime": "[some]", "uid": "[uid]", "gid": "[gid]", "user": "[user]", From 971e24e0298c9d2276c2ac1fccf89d16df005588 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Wed, 13 Mar 2024 08:17:30 +0100 Subject: [PATCH 41/46] move out in-memory backend to rustic_testing Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- Cargo.toml | 1 + crates/core/Cargo.toml | 1 + crates/core/src/backend.rs | 86 ++------------------------------ crates/core/src/lib.rs | 1 - crates/core/tests/integration.rs | 6 ++- crates/testing/Cargo.toml | 4 ++ crates/testing/src/backend.rs | 81 ++++++++++++++++++++++++++++++ crates/testing/src/lib.rs | 3 ++ 8 files changed, 97 insertions(+), 86 deletions(-) create mode 100644 crates/testing/src/backend.rs diff --git a/Cargo.toml b/Cargo.toml index 91accdf1..7c466801 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ rust-version = "1.72.1" aho-corasick = "1.1.2" rustic_backend = { path = "crates/backend" } rustic_core = { path = "crates/core" } +rustic_testing = { path = "crates/testing" } simplelog = "0.12.2" # dev-dependencies diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 9514d80d..0261309c 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -142,6 +142,7 @@ rstest = { workspace = true } rustdoc-json = "0.8.9" # We need to have rustic_backend here, because the doc-tests in lib.rs of rustic_core rustic_backend = { workspace = true } +rustic_testing = { workspace = true } rustup-toolchain = "0.1.6" simplelog = "0.12.2" tar = "0.4.40" diff --git a/crates/core/src/backend.rs b/crates/core/src/backend.rs index 49def321..50a4c911 100644 --- a/crates/core/src/backend.rs +++ b/crates/core/src/backend.rs @@ -15,8 +15,10 @@ use anyhow::Result; use bytes::Bytes; use enum_map::Enum; use log::trace; + #[cfg(test)] -use mockall::*; +use mockall::mock; + use serde_derive::{Deserialize, Serialize}; use crate::{ @@ -548,85 +550,3 @@ impl RepositoryBackends { self.repo_hot.clone() } } - -pub mod in_memory_backend { - use std::{collections::BTreeMap, sync::RwLock}; - - use anyhow::{bail, Result}; - use bytes::Bytes; - use enum_map::EnumMap; - - use super::{ReadBackend, WriteBackend}; - use crate::{FileType, Id}; - - #[derive(Debug)] - /// In-Memory backend to be used for testing - pub struct InMemoryBackend(RwLock>>); - - impl InMemoryBackend { - /// Create a new (empty) `InMemoryBackend` - #[must_use] - pub fn new() -> Self { - Self(RwLock::new(EnumMap::from_fn(|_| BTreeMap::new()))) - } - } - - impl Default for InMemoryBackend { - fn default() -> Self { - Self::new() - } - } - - impl ReadBackend for InMemoryBackend { - fn location(&self) -> String { - "test".to_string() - } - - fn list_with_size(&self, tpe: FileType) -> Result> { - Ok(self.0.read().unwrap()[tpe] - .iter() - .map(|(id, byte)| { - ( - *id, - u32::try_from(byte.len()).expect("byte length is too large"), - ) - }) - .collect()) - } - - fn read_full(&self, tpe: FileType, id: &Id) -> Result { - Ok(self.0.read().unwrap()[tpe][id].clone()) - } - - fn read_partial( - &self, - tpe: FileType, - id: &Id, - _cacheable: bool, - offset: u32, - length: u32, - ) -> Result { - Ok(self.0.read().unwrap()[tpe][id].slice(offset as usize..(offset + length) as usize)) - } - } - - impl WriteBackend for InMemoryBackend { - fn create(&self) -> Result<()> { - Ok(()) - } - - fn write_bytes(&self, tpe: FileType, id: &Id, _cacheable: bool, buf: Bytes) -> Result<()> { - if self.0.write().unwrap()[tpe].insert(*id, buf).is_some() { - bail!("id {id} already exists"); - } - Ok(()) - } - - fn remove(&self, tpe: FileType, id: &Id, _cacheable: bool) -> Result<()> { - if self.0.write().unwrap()[tpe].remove(id).is_none() { - bail!("id {id} doesn't exists"); - } - Ok(()) - } - } -} diff --git a/crates/core/src/lib.rs b/crates/core/src/lib.rs index 1c8edc56..f277d948 100644 --- a/crates/core/src/lib.rs +++ b/crates/core/src/lib.rs @@ -124,7 +124,6 @@ pub use crate::{ backend::{ decrypt::{compression_level_range, max_compression_level}, ignore::{LocalSource, LocalSourceFilterOptions, LocalSourceSaveOptions}, - in_memory_backend::InMemoryBackend, local_destination::LocalDestination, node::last_modified_node, FileType, ReadBackend, ReadSource, ReadSourceEntry, ReadSourceOpen, RepositoryBackends, diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index b348326c..9a9b5fce 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -30,11 +30,13 @@ use pretty_assertions::assert_eq; use rstest::fixture; use rstest::rstest; use rustic_core::{ - repofile::SnapshotFile, BackupOptions, ConfigOptions, InMemoryBackend, KeyOptions, - NoProgressBars, OpenStatus, PathList, Repository, RepositoryBackends, RepositoryOptions, + repofile::SnapshotFile, BackupOptions, ConfigOptions, KeyOptions, NoProgressBars, OpenStatus, + PathList, Repository, RepositoryBackends, RepositoryOptions, }; use serde_derive::Serialize; +use rustic_testing::backend::in_memory_backend::InMemoryBackend; + use std::{ env, fs::File, diff --git a/crates/testing/Cargo.toml b/crates/testing/Cargo.toml index 35d865ad..83c0fbdc 100644 --- a/crates/testing/Cargo.toml +++ b/crates/testing/Cargo.toml @@ -6,7 +6,11 @@ publish = false [dependencies] aho-corasick = { workspace = true } +anyhow = "1.0.81" +bytes = "1.5.0" +enum-map = "2.7.3" once_cell = "1.19.0" +rustic_core = { workspace = true } tempfile = { workspace = true } [lints] diff --git a/crates/testing/src/backend.rs b/crates/testing/src/backend.rs new file mode 100644 index 00000000..1c7ca4d1 --- /dev/null +++ b/crates/testing/src/backend.rs @@ -0,0 +1,81 @@ +/// In-memory backend to be used for testing +pub mod in_memory_backend { + use std::{collections::BTreeMap, sync::RwLock}; + + use anyhow::{bail, Result}; + use bytes::Bytes; + use enum_map::EnumMap; + + use rustic_core::{FileType, Id, ReadBackend, WriteBackend}; + + #[derive(Debug)] + /// In-Memory backend to be used for testing + pub struct InMemoryBackend(RwLock>>); + + impl InMemoryBackend { + /// Create a new (empty) `InMemoryBackend` + #[must_use] + pub fn new() -> Self { + Self(RwLock::new(EnumMap::from_fn(|_| BTreeMap::new()))) + } + } + + impl Default for InMemoryBackend { + fn default() -> Self { + Self::new() + } + } + + impl ReadBackend for InMemoryBackend { + fn location(&self) -> String { + "test".to_string() + } + + fn list_with_size(&self, tpe: FileType) -> Result> { + Ok(self.0.read().unwrap()[tpe] + .iter() + .map(|(id, byte)| { + ( + *id, + u32::try_from(byte.len()).expect("byte length is too large"), + ) + }) + .collect()) + } + + fn read_full(&self, tpe: FileType, id: &Id) -> Result { + Ok(self.0.read().unwrap()[tpe][id].clone()) + } + + fn read_partial( + &self, + tpe: FileType, + id: &Id, + _cacheable: bool, + offset: u32, + length: u32, + ) -> Result { + Ok(self.0.read().unwrap()[tpe][id].slice(offset as usize..(offset + length) as usize)) + } + } + + impl WriteBackend for InMemoryBackend { + fn create(&self) -> Result<()> { + Ok(()) + } + + fn write_bytes(&self, tpe: FileType, id: &Id, _cacheable: bool, buf: Bytes) -> Result<()> { + if self.0.write().unwrap()[tpe].insert(*id, buf).is_some() { + bail!("id {id} already exists"); + } + Ok(()) + } + + fn remove(&self, tpe: FileType, id: &Id, _cacheable: bool) -> Result<()> { + if self.0.write().unwrap()[tpe].remove(id).is_none() { + bail!("id {id} doesn't exists"); + } + Ok(()) + } + } +} diff --git a/crates/testing/src/lib.rs b/crates/testing/src/lib.rs index 7a04e793..741f75dc 100644 --- a/crates/testing/src/lib.rs +++ b/crates/testing/src/lib.rs @@ -1,5 +1,8 @@ //! Testing utilities for the `rustic` ecosystem. +/// Backends to be used solely for testing. +pub mod backend; + use aho_corasick::{AhoCorasick, PatternID}; use std::{error::Error, ffi::OsStr}; use tempfile::NamedTempFile; From 5bc8ad2d409f0ec5ce2d3d35dc41e3042430fcf1 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Wed, 13 Mar 2024 10:01:52 +0100 Subject: [PATCH 42/46] chore: manifest Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- Cargo.toml | 3 +++ crates/core/Cargo.toml | 6 +++--- crates/testing/Cargo.toml | 6 +++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7c466801..6aa1fa6b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,9 @@ rust-version = "1.72.1" [workspace.dependencies] aho-corasick = "1.1.2" +anyhow = "1.0.81" +bytes = "1.5.0" +enum-map = "2.7.3" rustic_backend = { path = "crates/backend" } rustic_core = { path = "crates/core" } rustic_testing = { path = "crates/testing" } diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 0261309c..4caf6cb8 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -102,11 +102,11 @@ futures = { version = "0.3", optional = true } runtime-format = "0.1.3" # other dependencies -anyhow = "1.0.81" -bytes = "1.5.0" +anyhow = { workspace = true } +bytes = { workspace = true } bytesize = "1.3.0" chrono = { version = "0.4.35", default-features = false, features = ["clock", "serde"] } -enum-map = "2.7.3" +enum-map = { workspace = true } enum-map-derive = "0.17.0" enumset = { version = "1.1.3", features = ["serde"] } gethostname = "0.4.3" diff --git a/crates/testing/Cargo.toml b/crates/testing/Cargo.toml index 83c0fbdc..e39f9724 100644 --- a/crates/testing/Cargo.toml +++ b/crates/testing/Cargo.toml @@ -6,9 +6,9 @@ publish = false [dependencies] aho-corasick = { workspace = true } -anyhow = "1.0.81" -bytes = "1.5.0" -enum-map = "2.7.3" +anyhow = { workspace = true } +bytes = { workspace = true } +enum-map = { workspace = true } once_cell = "1.19.0" rustic_core = { workspace = true } tempfile = { workspace = true } From 199765bf4e3f8e8dc3272b952357447b6968ab46 Mon Sep 17 00:00:00 2001 From: Alexander Weiss Date: Wed, 13 Mar 2024 08:22:32 +0100 Subject: [PATCH 43/46] code cleanups --- crates/core/tests/integration.rs | 92 ++++++++++---------------------- 1 file changed, 27 insertions(+), 65 deletions(-) diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index 9a9b5fce..2614708f 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -25,6 +25,7 @@ use anyhow::Result; use flate2::read::GzDecoder; +use insta::internals::{Content, ContentPath}; use insta::{assert_ron_snapshot, Settings}; use pretty_assertions::assert_eq; use rstest::fixture; @@ -76,6 +77,15 @@ fn set_up_repo() -> Result { Ok(repo) } +// helper func to redact options, but still keep information about some/none +fn handle_option(val: Content, _: ContentPath<'_>) -> String { + if val.is_nil() { + "[none]".to_string() + } else { + "[some]".to_string() + } +} + #[fixture] fn insta_summary_redaction() -> Settings { let mut settings = insta::Settings::clone_current(); @@ -89,13 +99,7 @@ fn insta_summary_redaction() -> Settings { }) }); settings.add_redaction(".time", "[time]"); - settings.add_dynamic_redaction(".parent", |val, _| { - if val.is_nil() { - "[none]".to_string() - } else { - "[some]".to_string() - } - }); + settings.add_dynamic_redaction(".parent", handle_option); settings.add_redaction(".tags", "[tags]"); settings.add_redaction(".id", "[id]"); settings.add_redaction(".summary.backup_start", "[backup_start]"); @@ -128,34 +132,10 @@ fn insta_tree_redaction() -> Settings { settings.add_redaction(".nodes[].gid", "[gid]"); settings.add_redaction(".nodes[].group", "[group]"); settings.add_redaction(".nodes[].content", "[content_id]"); - settings.add_dynamic_redaction(".nodes[].mode", |val, _| { - if val.is_nil() { - "[none]".to_string() - } else { - "[some]".to_string() - } - }); - settings.add_dynamic_redaction(".nodes[].mtime", |val, _| { - if val.is_nil() { - "[none]".to_string() - } else { - "[some]".to_string() - } - }); - settings.add_dynamic_redaction(".nodes[].atime", |val, _| { - if val.is_nil() { - "[none]".to_string() - } else { - "[some]".to_string() - } - }); - settings.add_dynamic_redaction(".nodes[].ctime", |val, _| { - if val.is_nil() { - "[none]".to_string() - } else { - "[some]".to_string() - } - }); + settings.add_dynamic_redaction(".nodes[].mode", handle_option); + settings.add_dynamic_redaction(".nodes[].mtime", handle_option); + settings.add_dynamic_redaction(".nodes[].atime", handle_option); + settings.add_dynamic_redaction(".nodes[].ctime", handle_option); settings } @@ -208,16 +188,13 @@ fn test_backup_with_tar_gz_passes( // We can also bind to scope ( https://docs.rs/insta/latest/insta/struct.Settings.html#method.bind_to_scope ) // But I think that can get messy with a lot of tests, also checking which settings are currently applied // will be probably harder - #[cfg(windows)] insta_summary_redaction.bind(|| { + #[cfg(windows)] assert_ron_snapshot!( "backup-tar-summary-first-windows", TestSummary(&first_snapshot) ); - }); - - #[cfg(not(windows))] - insta_summary_redaction.bind(|| { + #[cfg(not(windows))] assert_ron_snapshot!("backup-tar-summary-first-nix", TestSummary(&first_snapshot)); }); @@ -229,13 +206,10 @@ fn test_backup_with_tar_gz_passes( let tree = repo.node_from_path(first_snapshot.tree, Path::new("test/0/tests"))?; let tree: rustic_core::repofile::Tree = repo.get_tree(&tree.subtree.expect("Sub tree"))?; - #[cfg(windows)] insta_tree_redaction.bind(|| { + #[cfg(windows)] assert_ron_snapshot!("backup-tar-tree-windows", tree); - }); - - #[cfg(not(windows))] - insta_tree_redaction.bind(|| { + #[cfg(not(windows))] assert_ron_snapshot!("backup-tar-tree-nix", tree); }); @@ -250,16 +224,13 @@ fn test_backup_with_tar_gz_passes( // second backup let second_snapshot = repo.backup(&opts, paths, SnapshotFile::default())?; - #[cfg(windows)] insta_summary_redaction.bind(|| { + #[cfg(windows)] assert_ron_snapshot!( "backup-tar-summary-second-windows", TestSummary(&second_snapshot) ); - }); - - #[cfg(not(windows))] - insta_summary_redaction.bind(|| { + #[cfg(not(windows))] assert_ron_snapshot!( "backup-tar-summary-second-nix", TestSummary(&second_snapshot) @@ -300,16 +271,13 @@ fn test_backup_dry_run_with_tar_gz_passes( // dry-run backup let snap_dry_run = repo.backup(&opts, paths, SnapshotFile::default())?; - #[cfg(windows)] insta_summary_redaction.bind(|| { + #[cfg(windows)] assert_ron_snapshot!( "dryrun-tar-summary-first-windows", TestSummary(&snap_dry_run) ); - }); - - #[cfg(not(windows))] - insta_summary_redaction.bind(|| { + #[cfg(not(windows))] assert_ron_snapshot!("dryrun-tar-summary-first-nix", TestSummary(&snap_dry_run)); }); @@ -331,13 +299,10 @@ fn test_backup_dry_run_with_tar_gz_passes( let tree = repo.node_from_path(first_snapshot.tree, Path::new("test/0/tests"))?; let tree = repo.get_tree(&tree.subtree.expect("Sub tree"))?; - #[cfg(windows)] insta_tree_redaction.bind(|| { + #[cfg(windows)] assert_ron_snapshot!("dryrun-tar-tree-windows", tree); - }); - - #[cfg(not(windows))] - insta_tree_redaction.bind(|| { + #[cfg(not(windows))] assert_ron_snapshot!("dryrun-tar-tree-nix", tree); }); @@ -347,16 +312,13 @@ fn test_backup_dry_run_with_tar_gz_passes( let opts = opts.dry_run(true); let snap_dry_run = repo.backup(&opts, paths, SnapshotFile::default())?; - #[cfg(windows)] insta_summary_redaction.bind(|| { + #[cfg(windows)] assert_ron_snapshot!( "dryrun-tar-summary-second-windows", TestSummary(&snap_dry_run) ); - }); - - #[cfg(not(windows))] - insta_summary_redaction.bind(|| { + #[cfg(not(windows))] assert_ron_snapshot!("dryrun-tar-summary-second-nix", TestSummary(&snap_dry_run)); }); From b56d673dd51344690f720258b21e023c200a9e4f Mon Sep 17 00:00:00 2001 From: Alexander Weiss Date: Wed, 13 Mar 2024 08:42:01 +0100 Subject: [PATCH 44/46] don`t redact content id --- crates/core/tests/integration.rs | 1 - .../snapshots/integration__backup-tar-tree-nix.snap | 12 ++++++++---- .../snapshots/integration__dryrun-tar-tree-nix.snap | 12 ++++++++---- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index 2614708f..39bb3e35 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -131,7 +131,6 @@ fn insta_tree_redaction() -> Settings { settings.add_redaction(".nodes[].user", "[user]"); settings.add_redaction(".nodes[].gid", "[gid]"); settings.add_redaction(".nodes[].group", "[group]"); - settings.add_redaction(".nodes[].content", "[content_id]"); settings.add_dynamic_redaction(".nodes[].mode", handle_option); settings.add_dynamic_redaction(".nodes[].mtime", handle_option); settings.add_dynamic_redaction(".nodes[].atime", handle_option); diff --git a/crates/core/tests/snapshots/integration__backup-tar-tree-nix.snap b/crates/core/tests/snapshots/integration__backup-tar-tree-nix.snap index e8cbbf82..1d815497 100644 --- a/crates/core/tests/snapshots/integration__backup-tar-tree-nix.snap +++ b/crates/core/tests/snapshots/integration__backup-tar-tree-nix.snap @@ -18,7 +18,7 @@ Tree( "inode": "[inode]", "device_id": "[device_id]", "links": 1, - "content": "[content_id]", + "content": Some([]), }, { "name": "testfile", @@ -35,7 +35,9 @@ Tree( "device_id": "[device_id]", "size": 21, "links": 2, - "content": "[content_id]", + "content": Some([ + Id("649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a"), + ]), }, { "name": "testfile-hardlink", @@ -52,7 +54,9 @@ Tree( "device_id": "[device_id]", "size": 21, "links": 2, - "content": "[content_id]", + "content": Some([ + Id("649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a"), + ]), }, { "name": "testfile-symlink", @@ -70,7 +74,7 @@ Tree( "device_id": "[device_id]", "size": 8, "links": 1, - "content": "[content_id]", + "content": None, }, ], ) diff --git a/crates/core/tests/snapshots/integration__dryrun-tar-tree-nix.snap b/crates/core/tests/snapshots/integration__dryrun-tar-tree-nix.snap index e8cbbf82..1d815497 100644 --- a/crates/core/tests/snapshots/integration__dryrun-tar-tree-nix.snap +++ b/crates/core/tests/snapshots/integration__dryrun-tar-tree-nix.snap @@ -18,7 +18,7 @@ Tree( "inode": "[inode]", "device_id": "[device_id]", "links": 1, - "content": "[content_id]", + "content": Some([]), }, { "name": "testfile", @@ -35,7 +35,9 @@ Tree( "device_id": "[device_id]", "size": 21, "links": 2, - "content": "[content_id]", + "content": Some([ + Id("649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a"), + ]), }, { "name": "testfile-hardlink", @@ -52,7 +54,9 @@ Tree( "device_id": "[device_id]", "size": 21, "links": 2, - "content": "[content_id]", + "content": Some([ + Id("649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a"), + ]), }, { "name": "testfile-symlink", @@ -70,7 +74,7 @@ Tree( "device_id": "[device_id]", "size": 8, "links": 1, - "content": "[content_id]", + "content": None, }, ], ) From b0401b848c6d54641957f4307c394c9ef47d4a87 Mon Sep 17 00:00:00 2001 From: Alexander Weiss Date: Wed, 13 Mar 2024 10:13:38 +0100 Subject: [PATCH 45/46] update windows snapshots --- .../integration__backup-tar-tree-windows.snap | 12 ++++++++---- .../integration__dryrun-tar-tree-windows.snap | 12 ++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/crates/core/tests/snapshots/integration__backup-tar-tree-windows.snap b/crates/core/tests/snapshots/integration__backup-tar-tree-windows.snap index 9dda5c79..21c9e746 100644 --- a/crates/core/tests/snapshots/integration__backup-tar-tree-windows.snap +++ b/crates/core/tests/snapshots/integration__backup-tar-tree-windows.snap @@ -10,7 +10,7 @@ Tree( "mtime": "[some]", "atime": "[some]", "ctime": "[some]", - "content": "[content_id]", + "content": Some([]), }, { "name": "testfile", @@ -19,7 +19,9 @@ Tree( "atime": "[some]", "ctime": "[some]", "size": 21, - "content": "[content_id]", + "content": Some([ + Id("649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a"), + ]), }, { "name": "testfile-hardlink", @@ -28,7 +30,9 @@ Tree( "atime": "[some]", "ctime": "[some]", "size": 21, - "content": "[content_id]", + "content": Some([ + Id("649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a"), + ]), }, { "name": "testfile-symlink", @@ -37,7 +41,7 @@ Tree( "mtime": "[some]", "atime": "[some]", "ctime": "[some]", - "content": "[content_id]", + "content": None, }, ], ) diff --git a/crates/core/tests/snapshots/integration__dryrun-tar-tree-windows.snap b/crates/core/tests/snapshots/integration__dryrun-tar-tree-windows.snap index 9dda5c79..21c9e746 100644 --- a/crates/core/tests/snapshots/integration__dryrun-tar-tree-windows.snap +++ b/crates/core/tests/snapshots/integration__dryrun-tar-tree-windows.snap @@ -10,7 +10,7 @@ Tree( "mtime": "[some]", "atime": "[some]", "ctime": "[some]", - "content": "[content_id]", + "content": Some([]), }, { "name": "testfile", @@ -19,7 +19,9 @@ Tree( "atime": "[some]", "ctime": "[some]", "size": 21, - "content": "[content_id]", + "content": Some([ + Id("649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a"), + ]), }, { "name": "testfile-hardlink", @@ -28,7 +30,9 @@ Tree( "atime": "[some]", "ctime": "[some]", "size": 21, - "content": "[content_id]", + "content": Some([ + Id("649b8b471e7d7bc175eec758a7006ac693c434c8297c07db15286788c837154a"), + ]), }, { "name": "testfile-symlink", @@ -37,7 +41,7 @@ Tree( "mtime": "[some]", "atime": "[some]", "ctime": "[some]", - "content": "[content_id]", + "content": None, }, ], ) From 37caad39e981d3f8401c6d870c8380cd63961c58 Mon Sep 17 00:00:00 2001 From: Alexander Weiss Date: Wed, 13 Mar 2024 10:15:02 +0100 Subject: [PATCH 46/46] fix clippy --- crates/core/tests/integration.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index 39bb3e35..f7707d64 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -78,6 +78,7 @@ fn set_up_repo() -> Result { } // helper func to redact options, but still keep information about some/none +#[allow(clippy::needless_pass_by_value)] // we need exactly that function signature fn handle_option(val: Content, _: ContentPath<'_>) -> String { if val.is_nil() { "[none]".to_string()