Skip to content

Commit

Permalink
Basic HashMap for memory store and enable store_one_item_existence test
Browse files Browse the repository at this point in the history
  • Loading branch information
allada committed Dec 26, 2020
1 parent a6f1a70 commit 5206e74
Show file tree
Hide file tree
Showing 10 changed files with 125 additions and 26 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Expand Up @@ -10,6 +10,7 @@ path = "needed_only_to_make_cargo_tooling_happy.rs"
[dependencies]
prost = "0.6.1"
prost-types = "0.6.1"
hex = "0.4.2"
async-trait = "0.1.42"
tokio = { version = "0.2.2", features = ["macros"] }
tonic = "0.3.1"
Expand Down
2 changes: 1 addition & 1 deletion cas/grpc_service/cas_server.rs
Expand Up @@ -40,7 +40,7 @@ impl ContentAddressableStorage for CasServer {
missing_blob_digests: vec![],
};
for digest in request_data.blob_digests.into_iter() {
if !self.store.has(&digest.hash) {
if !self.store.has(&digest.hash).await? {
response.missing_blob_digests.push(digest);
}
}
Expand Down
16 changes: 5 additions & 11 deletions cas/grpc_service/tests/cas_server_test.rs
@@ -1,8 +1,5 @@
// 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;
Expand All @@ -23,18 +20,17 @@ mod find_missing_blobs {
};

const INSTANCE_NAME: &str = "foo";
const HASH1: &str = "0123456789abcdef000000000000000000000000000000000123456789abcdef";

#[tokio::test]
async fn empty_store() {
let cas_server = CasServer::new(create_store(&StoreType::Memory));

const HASH: &str = "123";

let raw_response = cas_server
.find_missing_blobs(Request::new(FindMissingBlobsRequest {
instance_name: INSTANCE_NAME.to_string(),
blob_digests: vec![Digest {
hash: HASH.to_string(),
hash: HASH1.to_string(),
size_bytes: 0,
}],
}))
Expand All @@ -44,23 +40,21 @@ mod find_missing_blobs {
assert_eq!(response.missing_blob_digests.len(), 1);
}

#[ignore = "Feature not ready yet"]
#[tokio::test]
async fn store_one_item_existence() -> Result<(), Error> {
let cas_server = CasServer::new(create_store(&StoreType::Memory));
let mut cas_server = CasServer::new(create_store(&StoreType::Memory));

const HASH: &str = "123";
const VALUE: &str = "1";

cas_server
.store
.update(&HASH, 1, Box::new(Cursor::new(VALUE)))
.update(&HASH1, 1, Box::new(Cursor::new(VALUE)))
.await?;
let raw_response = cas_server
.find_missing_blobs(Request::new(FindMissingBlobsRequest {
instance_name: INSTANCE_NAME.to_string(),
blob_digests: vec![Digest {
hash: HASH.to_string(),
hash: HASH1.to_string(),
size_bytes: VALUE.len() as i64,
}],
}))
Expand Down
1 change: 1 addition & 0 deletions cas/store/BUILD
Expand Up @@ -30,6 +30,7 @@ rust_library(
deps = [
":traits",
"//third_party:tokio",
"//third_party:hex",
],
proc_macro_deps = ["//third_party:async_trait"],
visibility = ["//cas:__pkg__"]
Expand Down
36 changes: 26 additions & 10 deletions cas/store/memory_store.rs
@@ -1,32 +1,48 @@
// Copyright 2020 Nathan (Blaise) Bruer. All rights reserved.

use async_trait::async_trait;
use std::collections::HashMap;

use tokio::io::{AsyncRead, Error};
use async_trait::async_trait;
use hex::FromHex;
use tokio::io::{AsyncRead, AsyncReadExt, Error};

use traits::StoreTrait;

#[derive(Debug)]
pub struct MemoryStore {}
pub struct MemoryStore {
map: HashMap<[u8; 32], Vec<u8>>,
}

impl MemoryStore {
pub fn new() -> Self {
MemoryStore {}
MemoryStore {
map: HashMap::new(),
}
}
}

#[async_trait]
impl StoreTrait for MemoryStore {
fn has(&self, _hash: &str) -> bool {
false
async fn has(&self, hash: &str) -> Result<bool, Error> {
let raw_key = <[u8; 32]>::from_hex(&hash).expect("Hex length is not 64 hex characters");
Ok(self.map.contains_key(&raw_key))
}

async fn update<'a>(
&'a self,
_hash: &'a str,
_size: i64,
_reader: Box<dyn AsyncRead + Send>,
&'a mut self,
hash: &'a str,
expected_size: usize,
mut reader: Box<dyn AsyncRead + Send + Unpin>,
) -> Result<(), Error> {
let raw_key = <[u8; 32]>::from_hex(&hash).expect("Hex length is not 64 hex characters");
let mut buffer = Vec::new();
let read_size = reader.read_to_end(&mut buffer).await?;
assert_eq!(
read_size, expected_size,
"Expected size {} but got size {} for hash {} CAS insert",
expected_size, read_size, hash
);
self.map.insert(raw_key, buffer);
Ok(())
}
}
8 changes: 4 additions & 4 deletions cas/store/store_trait.rs
Expand Up @@ -8,11 +8,11 @@ use tokio::io::{AsyncRead, Error};

#[async_trait]
pub trait StoreTrait: Sync + Send + Debug {
fn has(&self, hash: &str) -> bool;
async fn has(&self, hash: &str) -> Result<bool, Error>;
async fn update<'a>(
&'a self,
&'a mut self,
_hash: &'a str,
_size: i64,
_reader: Box<dyn AsyncRead + Send>,
_size: usize,
mut _reader: Box<dyn AsyncRead + Send + Unpin>,
) -> Result<(), Error>;
}
9 changes: 9 additions & 0 deletions third_party/BUILD.bazel
Expand Up @@ -39,6 +39,15 @@ alias(
],
)

alias(
name = "hex",
actual = "@raze__hex__0_4_2//:hex",
tags = [
"cargo-raze",
"manual",
],
)

alias(
name = "prost",
actual = "@raze__prost__0_6_1//:prost",
Expand Down
10 changes: 10 additions & 0 deletions third_party/crates.bzl
Expand Up @@ -631,6 +631,16 @@ def raze_fetch_remote_crates():
build_file = Label("//third_party/remote:BUILD.hermit-abi-0.1.17.bazel"),
)

maybe(
http_archive,
name = "raze__hex__0_4_2",
url = "https://crates.io/api/v1/crates/hex/0.4.2/download",
type = "tar.gz",
sha256 = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35",
strip_prefix = "hex-0.4.2",
build_file = Label("//third_party/remote:BUILD.hex-0.4.2.bazel"),
)

maybe(
http_archive,
name = "raze__http__0_2_2",
Expand Down
61 changes: 61 additions & 0 deletions third_party/remote/BUILD.hex-0.4.2.bazel
@@ -0,0 +1,61 @@
"""
@generated
cargo-raze crate build file.

DO NOT EDIT! Replaced on runs of cargo-raze
"""

# buildifier: disable=load
load(
"@io_bazel_rules_rust//rust:rust.bzl",
"rust_binary",
"rust_library",
"rust_test",
)

# buildifier: disable=load
load("@bazel_skylib//lib:selects.bzl", "selects")

package(default_visibility = [
# Public for visibility by "@raze__crate__version//" targets.
#
# Prefer access through "//third_party", which limits external
# visibility to explicit Cargo.toml dependencies.
"//visibility:public",
])

licenses([
"notice", # MIT from expression "MIT OR Apache-2.0"
])

# Generated Targets

# Unsupported target "hex" with type "bench" omitted

rust_library(
name = "hex",
srcs = glob(["**/*.rs"]),
crate_features = [
"default",
"std",
],
crate_root = "src/lib.rs",
crate_type = "lib",
data = [],
edition = "2018",
rustc_flags = [
"--cap-lints=allow",
],
tags = [
"cargo-raze",
"manual",
],
version = "0.4.2",
# buildifier: leave-alone
deps = [
],
)

# Unsupported target "serde" with type "test" omitted

# Unsupported target "version-number" with type "test" omitted

0 comments on commit 5206e74

Please sign in to comment.