fix(sync): S-07 — skip invalid windows filenames with files_skipped_invalid counter
This commit is contained in:
@@ -903,3 +903,85 @@ fn test_s06_advisory_lock_blocks_sync_and_force_overrides() {
|
||||
|
||||
let _ = fs::remove_dir_all(&temp_root);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_s07_skip_invalid_windows_filenames_push_and_pull() {
|
||||
let temp_root =
|
||||
std::env::temp_dir().join(format!("sanctum_s07_test_{}", rand::random::<u64>()));
|
||||
let container_path = temp_root.join("s07.sanctum");
|
||||
let source_dir = temp_root.join("source");
|
||||
let restore_dir = temp_root.join("restore");
|
||||
|
||||
fs::create_dir_all(&source_dir).unwrap();
|
||||
fs::create_dir_all(&restore_dir).unwrap();
|
||||
|
||||
let (db, dek) = create_test_container(&container_path);
|
||||
|
||||
// Erstelle valide Dateien
|
||||
fs::write(source_dir.join("valid1.txt"), b"Content 1").unwrap();
|
||||
fs::write(source_dir.join("valid2.txt"), b"Content 2").unwrap();
|
||||
|
||||
// Versuche eine Datei mit ungültigem Namen anzulegen
|
||||
// Unter Windows via extended path r"\\?\"
|
||||
let extended_aux = format!(r"\\?\{}\aux.txt", source_dir.display());
|
||||
let created_aux = fs::write(&extended_aux, b"reserved aux file").is_ok();
|
||||
|
||||
let mut opts = SyncOptions::default();
|
||||
opts.direction = SyncDirection::Push;
|
||||
opts.quiet = true;
|
||||
|
||||
// 1. Push: Darf bei Vorhandensein von aux.txt nicht abbrechen
|
||||
let push_stats = run_sync(
|
||||
&db,
|
||||
0,
|
||||
&dek,
|
||||
FORMAT_VERSION,
|
||||
source_dir.to_str().unwrap(),
|
||||
"/",
|
||||
&opts,
|
||||
)
|
||||
.expect("Push sync must not abort when encountering invalid filenames");
|
||||
|
||||
assert_eq!(push_stats.files_transferred, 2);
|
||||
if created_aux {
|
||||
assert!(push_stats.files_skipped_invalid >= 1);
|
||||
}
|
||||
|
||||
// 2. Jetzt fügen wir manuell einen ungültigen Knoten in die Datenbank ein
|
||||
// (z. B. von Linux oder externem Container importiert: "aux.txt")
|
||||
{
|
||||
let conn = rusqlite::Connection::open(&container_path).unwrap();
|
||||
let root_id = Database::get_root_node_id_for_vault(0);
|
||||
let now = 123456789;
|
||||
conn.execute(
|
||||
"INSERT INTO nodes (parent_id, name, is_dir, size, created_at, modified_at)
|
||||
VALUES (?1, ?2, 0, 0, ?3, ?4)",
|
||||
rusqlite::params![root_id, "aux.txt", now, now],
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
// 3. Pull: Darf bei unzulässigem Knotennamen im Tresor nicht abbrechen
|
||||
opts.direction = SyncDirection::Pull;
|
||||
let pull_stats = run_sync(
|
||||
&db,
|
||||
0,
|
||||
&dek,
|
||||
FORMAT_VERSION,
|
||||
"/",
|
||||
restore_dir.to_str().unwrap(),
|
||||
&opts,
|
||||
)
|
||||
.expect("Pull sync must not abort when encountering invalid filenames in vault");
|
||||
|
||||
// Valide Dateien müssen wiederhergestellt worden sein
|
||||
assert!(restore_dir.join("valid1.txt").exists());
|
||||
assert!(restore_dir.join("valid2.txt").exists());
|
||||
assert_eq!(pull_stats.files_transferred, 2);
|
||||
assert_eq!(pull_stats.files_skipped_invalid, 1);
|
||||
|
||||
if created_aux {
|
||||
let _ = fs::remove_file(&extended_aux);
|
||||
}
|
||||
let _ = fs::remove_dir_all(&temp_root);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user