about summary refs log tree commit diff
path: root/tvix/store/src/proto/tests/grpc_pathinfoservice.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tvix/store/src/proto/tests/grpc_pathinfoservice.rs')
-rw-r--r--tvix/store/src/proto/tests/grpc_pathinfoservice.rs107
1 files changed, 107 insertions, 0 deletions
diff --git a/tvix/store/src/proto/tests/grpc_pathinfoservice.rs b/tvix/store/src/proto/tests/grpc_pathinfoservice.rs
new file mode 100644
index 000000000000..3858909757b8
--- /dev/null
+++ b/tvix/store/src/proto/tests/grpc_pathinfoservice.rs
@@ -0,0 +1,107 @@
+use std::path::Path;
+
+use tempfile::TempDir;
+use tonic::Request;
+
+use crate::blobservice::{BlobService, SledBlobService};
+use crate::chunkservice::{ChunkService, SledChunkService};
+use crate::directoryservice::{DirectoryService, SledDirectoryService};
+use crate::nar::NonCachingNARCalculationService;
+use crate::pathinfoservice::{PathInfoService, SledPathInfoService};
+use crate::proto::get_path_info_request::ByWhat::ByOutputHash;
+use crate::proto::node::Node::Symlink;
+use crate::proto::path_info_service_server::PathInfoService as GRPCPathInfoService;
+use crate::proto::GRPCPathInfoServiceWrapper;
+use crate::proto::PathInfo;
+use crate::proto::{GetPathInfoRequest, Node, SymlinkNode};
+
+use lazy_static::lazy_static;
+
+lazy_static! {
+    static ref DUMMY_OUTPUT_HASH: Vec<u8> = vec![
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00
+    ];
+}
+
+// TODO: dedup these helpers
+fn gen_pathinfo_service(p: &Path) -> impl PathInfoService {
+    SledPathInfoService::new(p.join("pathinfo")).unwrap()
+}
+fn gen_blob_service(p: &Path) -> impl BlobService {
+    SledBlobService::new(p.join("blobs")).unwrap()
+}
+
+fn gen_chunk_service(p: &Path) -> impl ChunkService + Clone {
+    SledChunkService::new(p.join("chunks")).unwrap()
+}
+
+fn gen_directory_service(p: &Path) -> impl DirectoryService {
+    SledDirectoryService::new(p.join("directories")).unwrap()
+}
+
+/// generates a GRPCPathInfoService out of blob, chunk, directory and pathinfo services.
+///
+/// It doesn't create underlying services on its own, as we don't need to
+/// preseed them with existing data for the test - we only interact with it via
+// the PathInfo GRPC interface.
+/// It uses the NonCachingNARCalculationService NARCalculationService to
+/// calculate NARs.
+fn gen_grpc_service(p: &Path) -> impl GRPCPathInfoService {
+    let blob_service = gen_blob_service(p);
+    let chunk_service = gen_chunk_service(p);
+    let directory_service = gen_directory_service(p);
+    let pathinfo_service = gen_pathinfo_service(p);
+
+    GRPCPathInfoServiceWrapper::new(
+        pathinfo_service,
+        NonCachingNARCalculationService::new(blob_service, chunk_service, directory_service),
+    )
+}
+
+/// Trying to get a non-existent PathInfo should return a not found error.
+#[tokio::test]
+async fn not_found() {
+    let tmpdir = TempDir::new().unwrap();
+    let service = gen_grpc_service(tmpdir.path());
+
+    let resp = service
+        .get(Request::new(GetPathInfoRequest {
+            by_what: Some(ByOutputHash(DUMMY_OUTPUT_HASH.to_vec())),
+        }))
+        .await;
+
+    let resp = resp.expect_err("must fail");
+    assert_eq!(resp.code(), tonic::Code::NotFound);
+}
+
+/// Put a PathInfo into the store, get it back.
+#[tokio::test]
+async fn put_get() {
+    let tmpdir = TempDir::new().unwrap();
+    let service = gen_grpc_service(tmpdir.path());
+
+    let path_info = PathInfo {
+        node: Some(Node {
+            node: Some(Symlink(SymlinkNode {
+                name: "00000000000000000000000000000000-foo".to_string(),
+                target: "doesntmatter".to_string(),
+            })),
+        }),
+        ..Default::default()
+    };
+
+    let resp = service.put(Request::new(path_info.clone())).await;
+
+    assert!(resp.is_ok());
+    assert_eq!(resp.expect("must succeed").into_inner(), path_info);
+
+    let resp = service
+        .get(Request::new(GetPathInfoRequest {
+            by_what: Some(ByOutputHash(DUMMY_OUTPUT_HASH.to_vec())),
+        }))
+        .await;
+
+    assert!(resp.is_ok());
+    assert_eq!(resp.expect("must succeed").into_inner(), path_info);
+}