fix(vfs): V-01 — copy dispatches to CarrierFs in carrier mode

This commit is contained in:
2026-09-19 00:16:04 +02:00
parent 533764487a
commit 151fdba09d
3 changed files with 335 additions and 0 deletions
+199
View File
@@ -575,3 +575,202 @@ async fn test_carrier_file_drop_and_append_mode() {
let _ = std::fs::remove_file(&path);
}
#[tokio::test]
async fn test_v01_carrier_fs_copy_delegation_and_functionality() {
let path = temp_db_path("v01_copy");
let carrier_size_bytes = 10 * 1024 * 1024; // 10 MB
let carrier_name = "carrier_for_copy.bin";
let pass_decoy = "DecoyPass2026!";
let pass_hidden = "HiddenPass2026!";
let kdf_params = KdfParams {
memory_cost: MIN_MEMORY_COST_KIB,
time_cost: MIN_TIME_COST,
parallelism: 1,
};
let salt_0 = generate_salt();
let kek_0 = derive_kek(pass_decoy, &salt_0, &kdf_params).unwrap();
let dek_0 = generate_dek();
let salt_1 = generate_salt();
let kek_1 = derive_kek(pass_hidden, &salt_1, &kdf_params).unwrap();
let dek_1 = generate_dek();
let carrier_node_id = 3i64;
let (wrapped_0, nonce_0, tag_0) = wrap_slot0_payload(&kek_0, &dek_0, carrier_node_id).unwrap();
let (wrapped_1, nonce_1, tag_1) =
wrap_slot1_payload(&kek_1, &dek_1, &dek_0, carrier_node_id).unwrap();
let db = Database::open(&path).expect("Open database");
db.init_schema_with_carrier(
&salt_0,
&kdf_params,
&wrapped_0,
&nonce_0,
&tag_0,
Some((
carrier_name,
carrier_size_bytes,
&salt_1,
&kdf_params,
&wrapped_1,
&nonce_1,
&tag_1,
&dek_0,
&dek_1,
)),
)
.expect("Init carrier schema");
db.checkpoint().unwrap();
let meta = db.read_meta().unwrap();
let auth_hidden = meta.authenticate(pass_hidden).expect("Auth hidden");
let hidden_fs = SanctumFs::with_carrier(
db.clone(),
auth_hidden.dek().clone(),
auth_hidden.carrier_dek(),
auth_hidden.carrier_node_id(),
auth_hidden.version(),
true,
1,
);
// Ordner anlegen
let folder = DavPath::new("/work").unwrap();
hidden_fs.create_dir(&folder).await.expect("Create folder");
// Datei anlegen und Inhalt schreiben
let src_path = DavPath::new("/work/original.txt").unwrap();
let test_data = b"V01 CarrierFs Copy Functionality Test Payload 2026";
let mut file = hidden_fs
.open(
&src_path,
OpenOptions {
create: true,
write: true,
..Default::default()
},
)
.await
.expect("Create source file");
file.write_bytes(Bytes::from_static(test_data))
.await
.expect("Write source data");
file.flush().await.expect("Flush source file");
drop(file);
// V-01: copy von /work/original.txt nach /work/copy.txt aufrufen
let dest_path = DavPath::new("/work/copy.txt").unwrap();
hidden_fs
.copy(&src_path, &dest_path)
.await
.expect("V-01: Copy must succeed on CarrierFs");
// Metadaten der Kopie prüfen
let copy_meta = hidden_fs
.metadata(&dest_path)
.await
.expect("Metadata of copied file");
assert_eq!(copy_meta.len(), test_data.len() as u64);
assert!(!copy_meta.is_dir());
// Inhalt der Kopie lesen und verifizieren
let mut read_copy = hidden_fs
.open(
&dest_path,
OpenOptions {
read: true,
..Default::default()
},
)
.await
.expect("Open copied file");
let copy_bytes = read_copy.read_bytes(1024).await.expect("Read copy bytes");
assert_eq!(&copy_bytes[..], test_data);
drop(read_copy);
// Quelldatei löschen: Die Kopie muss unabhängig erhalten bleiben!
hidden_fs
.remove_file(&src_path)
.await
.expect("Delete source file");
assert!(hidden_fs.metadata(&src_path).await.is_err());
let mut read_copy_again = hidden_fs
.open(
&dest_path,
OpenOptions {
read: true,
..Default::default()
},
)
.await
.expect("Open copied file after source delete");
let copy_bytes_2 = read_copy_again
.read_bytes(1024)
.await
.expect("Read copy bytes after source delete");
assert_eq!(&copy_bytes_2[..], test_data);
drop(read_copy_again);
// Overwrite-Copy testen
let src2_path = DavPath::new("/work/source2.txt").unwrap();
let test_data_2 = b"New Overwrite Payload Content";
let mut file2 = hidden_fs
.open(
&src2_path,
OpenOptions {
create: true,
write: true,
..Default::default()
},
)
.await
.expect("Create source2");
file2
.write_bytes(Bytes::from_static(test_data_2))
.await
.expect("Write source2");
file2.flush().await.expect("Flush source2");
drop(file2);
hidden_fs
.copy(&src2_path, &dest_path)
.await
.expect("Overwrite copy must succeed");
let mut read_overwritten = hidden_fs
.open(
&dest_path,
OpenOptions {
read: true,
..Default::default()
},
)
.await
.expect("Open overwritten copy");
let overwritten_bytes = read_overwritten
.read_bytes(1024)
.await
.expect("Read overwritten bytes");
assert_eq!(&overwritten_bytes[..], test_data_2);
drop(read_overwritten);
// Checkpoint & Verify
db.checkpoint().unwrap();
let report = verify_container(&path, Some(&dek_0), true).expect("Verify with DEK_0");
assert!(
report.is_healthy(),
"Container muss integer und gesund bleiben: {:?}",
report.errors
);
let _ = std::fs::remove_file(&path);
}