From ed4bde4310ddedff0e5473295410f1f3d68fce71 Mon Sep 17 00:00:00 2001 From: Nathan Bruer Date: Fri, 25 Dec 2020 14:33:25 -0800 Subject: [PATCH] Add store and first test --- cas/BUILD | 1 + cas/cas_main.rs | 5 ++- cas/grpc_service/BUILD | 15 ++++++++- cas/grpc_service/cas_server.rs | 27 ++++++++++++----- cas/grpc_service/tests/cas_server_test.rs | 37 +++++++++++++++++++++++ cas/store/BUILD | 26 ++++++++++++++++ cas/store/lib.rs | 15 +++++++++ cas/store/memory_store.rs | 18 +++++++++++ cas/store/store_trait.rs | 7 +++++ 9 files changed, 142 insertions(+), 9 deletions(-) create mode 100644 cas/grpc_service/tests/cas_server_test.rs create mode 100644 cas/store/BUILD create mode 100644 cas/store/lib.rs create mode 100644 cas/store/memory_store.rs create mode 100644 cas/store/store_trait.rs diff --git a/cas/BUILD b/cas/BUILD index cb2c9e44b..3e58f91b7 100644 --- a/cas/BUILD +++ b/cas/BUILD @@ -8,6 +8,7 @@ rust_binary( "//cas/grpc_service:ac_server", "//cas/grpc_service:capabilities_server", "//cas/grpc_service:execution_server", + "//cas/store", "//third_party:tokio", "//third_party:tonic", ], diff --git a/cas/cas_main.rs b/cas/cas_main.rs index 1f6647381..5884af59f 100644 --- a/cas/cas_main.rs +++ b/cas/cas_main.rs @@ -6,13 +6,16 @@ use ac_server::AcServer; use capabilities_server::CapabilitiesServer; use cas_server::CasServer; use execution_server::ExecutionServer; +use store; #[tokio::main] async fn main() -> Result<(), Box> { let addr = "0.0.0.0:50051".parse()?; + let store = store::create_store(&store::StoreType::Memory); + Server::builder() - .add_service(CasServer::default().into_service()) + .add_service(CasServer::new(store).into_service()) .add_service(AcServer::default().into_service()) .add_service(CapabilitiesServer::default().into_service()) .add_service(ExecutionServer::default().into_service()) diff --git a/cas/grpc_service/BUILD b/cas/grpc_service/BUILD index b277c8635..de06d295a 100644 --- a/cas/grpc_service/BUILD +++ b/cas/grpc_service/BUILD @@ -1,4 +1,4 @@ -load("@io_bazel_rules_rust//rust:rust.bzl", "rust_library") +load("@io_bazel_rules_rust//rust:rust.bzl", "rust_library", "rust_test") rust_library( name = "cas_server", @@ -8,6 +8,7 @@ rust_library( "//third_party:tonic", "//third_party:futures_core", "//third_party:stdext", + "//cas/store", ], visibility = ["//cas:__pkg__"] ) @@ -44,3 +45,15 @@ rust_library( ], visibility = ["//cas:__pkg__"] ) + +rust_test( + name = "cas_server_test", + srcs = ["tests/cas_server_test.rs"], + deps = [ + ":cas_server", + "//cas/store", + "//proto", + "//third_party:tonic", + "//third_party:tokio", + ], +) \ No newline at end of file diff --git a/cas/grpc_service/cas_server.rs b/cas/grpc_service/cas_server.rs index 07824eecb..e6c141aa0 100644 --- a/cas/grpc_service/cas_server.rs +++ b/cas/grpc_service/cas_server.rs @@ -12,11 +12,18 @@ use proto::build::bazel::remote::execution::v2::{ BatchUpdateBlobsResponse, FindMissingBlobsRequest, FindMissingBlobsResponse, GetTreeRequest, GetTreeResponse, }; +use store; -#[derive(Debug, Default)] -pub struct CasServer {} +#[derive(Debug)] +pub struct CasServer { + pub store: Box, +} impl CasServer { + pub fn new(in_store: Box) -> Self { + CasServer { store: in_store } + } + pub fn into_service(self) -> Server { Server::new(self) } @@ -26,12 +33,18 @@ impl CasServer { impl ContentAddressableStorage for CasServer { async fn find_missing_blobs( &self, - _request: Request, + request: Request, ) -> Result, Status> { - use stdext::function_name; - let output = format!("{} not yet implemented", function_name!()); - println!("{}", output); - Err(Status::unimplemented(output)) + let request_data = request.into_inner(); + let mut response = FindMissingBlobsResponse { + missing_blob_digests: vec![], + }; + for digest in request_data.blob_digests.into_iter() { + if !self.store.has(&digest.hash) { + response.missing_blob_digests.push(digest); + } + } + Ok(Response::new(response)) } async fn batch_update_blobs( diff --git a/cas/grpc_service/tests/cas_server_test.rs b/cas/grpc_service/tests/cas_server_test.rs new file mode 100644 index 000000000..923090f44 --- /dev/null +++ b/cas/grpc_service/tests/cas_server_test.rs @@ -0,0 +1,37 @@ +// Copyright 2020 Nathan (Blaise) Bruer. All rights reserved. + +extern crate cas_server; +extern crate store; + +use tonic::Request; + +use proto::build::bazel::remote::execution::v2::Digest; + +use cas_server::CasServer; +use store::{create_store, StoreType}; + +#[cfg(test)] +mod find_missing_blobs { + use super::*; + + use proto::build::bazel::remote::execution::v2::{ + content_addressable_storage_server::ContentAddressableStorage, FindMissingBlobsRequest, + }; + + #[tokio::test] + async fn empty_store() { + let cas_server = CasServer::new(create_store(&StoreType::Memory)); + let raw_response = cas_server + .find_missing_blobs(Request::new(FindMissingBlobsRequest { + instance_name: "foo".to_string(), + blob_digests: vec![Digest { + hash: "".to_string(), + size_bytes: 0, + }], + })) + .await; + assert!(raw_response.is_ok()); + let response = raw_response.unwrap().into_inner(); + assert_eq!(response.missing_blob_digests.len(), 1); + } +} diff --git a/cas/store/BUILD b/cas/store/BUILD new file mode 100644 index 000000000..b6b8da658 --- /dev/null +++ b/cas/store/BUILD @@ -0,0 +1,26 @@ +# Copyright 2020 Nathan (Blaise) Bruer. All rights reserved. + +load("@io_bazel_rules_rust//rust:rust.bzl", "rust_library") + +rust_library( + name = "store", + srcs = ["lib.rs"], + deps = [ + ":memory_store", + ":traits", + ], + visibility = ["//cas:__pkg__", "//cas:__subpackages__"] +) + +rust_library( + name = "traits", + srcs = ["store_trait.rs"], + visibility = ["//cas:__pkg__"] +) + +rust_library( + name = "memory_store", + srcs = ["memory_store.rs"], + deps = [":traits"], + visibility = ["//cas:__pkg__"] +) diff --git a/cas/store/lib.rs b/cas/store/lib.rs new file mode 100644 index 000000000..04f245f88 --- /dev/null +++ b/cas/store/lib.rs @@ -0,0 +1,15 @@ +// Copyright 2020 Nathan (Blaise) Bruer. All rights reserved. + +pub use traits::StoreTrait as Store; + +use memory_store::MemoryStore; + +pub enum StoreType { + Memory, +} + +pub fn create_store(store_type: &StoreType) -> Box { + match store_type { + StoreType::Memory => Box::new(MemoryStore::new()), + } +} diff --git a/cas/store/memory_store.rs b/cas/store/memory_store.rs new file mode 100644 index 000000000..2d0147956 --- /dev/null +++ b/cas/store/memory_store.rs @@ -0,0 +1,18 @@ +// Copyright 2020 Nathan (Blaise) Bruer. All rights reserved. + +use traits::StoreTrait; + +#[derive(Debug)] +pub struct MemoryStore {} + +impl MemoryStore { + pub fn new() -> Self { + MemoryStore {} + } +} + +impl StoreTrait for MemoryStore { + fn has(&self, _hash: &str) -> bool { + false + } +} diff --git a/cas/store/store_trait.rs b/cas/store/store_trait.rs new file mode 100644 index 000000000..8d5c253ca --- /dev/null +++ b/cas/store/store_trait.rs @@ -0,0 +1,7 @@ +// Copyright 2020 Nathan (Blaise) Bruer. All rights reserved. + +use std::fmt::Debug; + +pub trait StoreTrait: Sync + Send + Debug { + fn has(&self, hash: &str) -> bool; +}