test(tvix/castore/dirsvc): check for a pitfall with deduplicated dirs

Change-Id: I3cff2c2e8b2c8a2fd8d8074647d0d99a1db8e693
Reviewed-on: https://cl.tvl.fyi/c/depot/+/12034
Reviewed-by: flokli <flokli@flokli.de>
Tested-by: BuildkiteCI
This commit is contained in:
Yureka 2024-07-24 20:50:44 +02:00 committed by yuka
parent 6a988a1598
commit 5114504b67
2 changed files with 49 additions and 5 deletions

View file

@ -9,7 +9,7 @@ use rstest_reuse::{self, *};
use super::DirectoryService; use super::DirectoryService;
use crate::directoryservice; use crate::directoryservice;
use crate::{ use crate::{
fixtures::{DIRECTORY_A, DIRECTORY_B, DIRECTORY_C}, fixtures::{DIRECTORY_A, DIRECTORY_B, DIRECTORY_C, DIRECTORY_D},
proto::{self, Directory}, proto::{self, Directory},
}; };
@ -36,10 +36,7 @@ pub fn directory_services(#[case] directory_service: impl DirectoryService) {}
#[tokio::test] #[tokio::test]
async fn test_non_exist(directory_service: impl DirectoryService) { async fn test_non_exist(directory_service: impl DirectoryService) {
// single get // single get
assert_eq!( assert_eq!(Ok(None), directory_service.get(&DIRECTORY_A.digest()).await);
Ok(None),
directory_service.get(&DIRECTORY_A.digest()).await
);
// recursive get // recursive get
assert_eq!( assert_eq!(
@ -136,6 +133,38 @@ async fn put_get_multiple_dedup(directory_service: impl DirectoryService) {
) )
} }
/// This tests the insertion and retrieval of a closure which contains a duplicated directory
/// (DIRECTORY_A, which is an empty directory), once in the root, and once in a subdir.
#[apply(directory_services)]
#[tokio::test]
async fn put_get_foo(directory_service: impl DirectoryService) {
let mut handle = directory_service.put_multiple_start();
handle.put(DIRECTORY_A.clone()).await.unwrap();
handle.put(DIRECTORY_B.clone()).await.unwrap();
handle.put(DIRECTORY_D.clone()).await.unwrap();
let root_digest = handle.close().await.unwrap();
assert_eq!(
DIRECTORY_D.digest(),
root_digest,
"root digest should match"
);
// Ensure we can get the closure back out of the service, and it is returned in a valid order
// (there are multiple valid possibilities)
let retrieved_closure = directory_service
.get_recursive(&DIRECTORY_D.digest())
.collect::<Vec<_>>()
.await;
let valid_closures = [
vec![Ok(DIRECTORY_D.clone()), Ok(DIRECTORY_B.clone()), Ok(DIRECTORY_A.clone())],
vec![Ok(DIRECTORY_D.clone()), Ok(DIRECTORY_A.clone()), Ok(DIRECTORY_B.clone())]
];
if !valid_closures.contains(&retrieved_closure) {
panic!("invalid closure returned: {:?}", retrieved_closure);
}
}
/// Uploading A, then C (referring to A twice), then B (itself referring to A) should fail during close, /// Uploading A, then C (referring to A twice), then B (itself referring to A) should fail during close,
/// as B itself would be left unconnected. /// as B itself would be left unconnected.
#[apply(directory_services)] #[apply(directory_services)]

View file

@ -85,4 +85,19 @@ lazy_static! {
], ],
..Default::default() ..Default::default()
}; };
pub static ref DIRECTORY_D: proto::Directory = proto::Directory {
directories: vec![
DirectoryNode {
name: b"a".to_vec().into(),
digest: DIRECTORY_A.digest().into(),
size: DIRECTORY_A.size(),
},
DirectoryNode {
name: b"b'".to_vec().into(),
digest: DIRECTORY_B.digest().into(),
size: DIRECTORY_B.size(),
}
],
..Default::default()
};
} }