about summary refs log tree commit diff
path: root/tvix
diff options
context:
space:
mode:
Diffstat (limited to 'tvix')
-rw-r--r--tvix/castore/src/directoryservice/tests/mod.rs39
-rw-r--r--tvix/castore/src/fixtures.rs15
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()
+    };
 }