diff options
author | Yureka <tvl@yuka.dev> | 2024-07-24T18·50+0200 |
---|---|---|
committer | yuka <tvl@yuka.dev> | 2024-07-25T09·52+0000 |
commit | 5114504b675cf334dd8476a4a64eb77c5d405896 (patch) | |
tree | 8f3eb0e2fa9965b6d50ee443cb45d3e3a4638c69 /tvix/castore | |
parent | 6a988a1598ac81a06454f9b18d36e4e3ac33cac6 (diff) |
test(tvix/castore/dirsvc): check for a pitfall with deduplicated dirs r/8413
Change-Id: I3cff2c2e8b2c8a2fd8d8074647d0d99a1db8e693 Reviewed-on: https://cl.tvl.fyi/c/depot/+/12034 Reviewed-by: flokli <flokli@flokli.de> Tested-by: BuildkiteCI
Diffstat (limited to 'tvix/castore')
-rw-r--r-- | tvix/castore/src/directoryservice/tests/mod.rs | 39 | ||||
-rw-r--r-- | tvix/castore/src/fixtures.rs | 15 |
2 files changed, 49 insertions, 5 deletions
diff --git a/tvix/castore/src/directoryservice/tests/mod.rs b/tvix/castore/src/directoryservice/tests/mod.rs index 4d14fbea1a92..d51140baaae6 100644 --- a/tvix/castore/src/directoryservice/tests/mod.rs +++ b/tvix/castore/src/directoryservice/tests/mod.rs @@ -9,7 +9,7 @@ use rstest_reuse::{self, *}; use super::DirectoryService; use crate::directoryservice; use crate::{ - fixtures::{DIRECTORY_A, DIRECTORY_B, DIRECTORY_C}, + fixtures::{DIRECTORY_A, DIRECTORY_B, DIRECTORY_C, DIRECTORY_D}, proto::{self, Directory}, }; @@ -36,10 +36,7 @@ pub fn directory_services(#[case] directory_service: impl DirectoryService) {} #[tokio::test] async fn test_non_exist(directory_service: impl DirectoryService) { // single get - assert_eq!( - Ok(None), - directory_service.get(&DIRECTORY_A.digest()).await - ); + assert_eq!(Ok(None), directory_service.get(&DIRECTORY_A.digest()).await); // recursive get 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, /// as B itself would be left unconnected. #[apply(directory_services)] diff --git a/tvix/castore/src/fixtures.rs b/tvix/castore/src/fixtures.rs index a206d9b7ddc6..3ebda64a818a 100644 --- a/tvix/castore/src/fixtures.rs +++ b/tvix/castore/src/fixtures.rs @@ -85,4 +85,19 @@ lazy_static! { ], ..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() + }; } |