use std::fs; use rpki::fetch::rsync::RsyncFetcher; use rpki::fetch::rsync_system::{SystemRsyncConfig, SystemRsyncFetcher}; #[test] fn system_rsync_fetcher_can_sync_from_local_directory_for_tests() { let tmp = tempfile::tempdir().expect("tempdir"); let src = tmp.path().join("src"); let nested = src.join("sub"); fs::create_dir_all(&nested).expect("mkdir"); fs::write(src.join("a.txt"), b"aaa").expect("write a"); fs::write(nested.join("b.txt"), b"bbb").expect("write b"); let config = SystemRsyncConfig { rsync_bin: "rsync".into(), ..Default::default() }; let fetcher = SystemRsyncFetcher::new(config); let base = src.to_string_lossy().to_string(); let out = fetcher.fetch_objects(&base).expect("fetch objects"); let mut saw_a = false; let mut saw_b = false; for (uri, bytes) in out { if uri.ends_with("a.txt") { assert_eq!(bytes, b"aaa"); saw_a = true; } if uri.ends_with("sub/b.txt") { assert_eq!(bytes, b"bbb"); saw_b = true; } } assert!(saw_a, "expected a.txt"); assert!(saw_b, "expected sub/b.txt"); } #[test] fn system_rsync_fetcher_can_reuse_persistent_mirror_directory() { let tmp = tempfile::tempdir().expect("tempdir"); let src = tmp.path().join("src"); let nested = src.join("sub"); fs::create_dir_all(&nested).expect("mkdir"); fs::write(src.join("a.txt"), b"aaa").expect("write a"); fs::write(nested.join("b.txt"), b"bbb").expect("write b"); let mirror_root = tmp.path().join("mirror"); let config = SystemRsyncConfig { rsync_bin: "rsync".into(), mirror_root: Some(mirror_root.clone()), ..Default::default() }; let fetcher = SystemRsyncFetcher::new(config); let base = src.to_string_lossy().to_string(); // First sync creates the mirror directory. let out1 = fetcher.fetch_objects(&base).expect("fetch objects #1"); assert!(out1.iter().any(|(u, _)| u.ends_with("a.txt"))); assert!(out1.iter().any(|(u, _)| u.ends_with("sub/b.txt"))); let dirs1: Vec<_> = std::fs::read_dir(&mirror_root) .expect("read mirror root") .filter_map(|e| e.ok()) .filter(|e| e.path().is_dir()) .collect(); assert_eq!(dirs1.len(), 1, "expected exactly one mirror directory"); // Second sync should reuse the same mirror directory (stable hash mapping). let out2 = fetcher.fetch_objects(&base).expect("fetch objects #2"); assert!(out2.iter().any(|(u, _)| u.ends_with("a.txt"))); assert!(out2.iter().any(|(u, _)| u.ends_with("sub/b.txt"))); let dirs2: Vec<_> = std::fs::read_dir(&mirror_root) .expect("read mirror root") .filter_map(|e| e.ok()) .filter(|e| e.path().is_dir()) .collect(); assert_eq!(dirs2.len(), 1, "expected mirror directory to be reused"); }