refactor(tvix/castore): move tests to grpc client, rm tonic-mock
Similar to gen_directorysvc_grpc_client, introduce a gen_blobsvc_grpc_client function that provides a gRPC client connected to a blobservice. The test is update to use that client to test against, rather than the server trait, removing the last usage of tonic_mock, so it's removed as well. Fixes b/243. Change-Id: If746e8600588da247eb53a63b70fe72f139e9e77 Reviewed-on: https://cl.tvl.fyi/c/depot/+/9564 Tested-by: BuildkiteCI Reviewed-by: tazjin <tazjin@tvl.su> Reviewed-by: Connor Brewster <cbrewster@hey.com> Autosubmit: flokli <flokli@flokli.de>
This commit is contained in:
parent
e778a33710
commit
c847cc32d9
8 changed files with 63 additions and 97 deletions
14
tvix/Cargo.lock
generated
14
tvix/Cargo.lock
generated
|
@ -2626,19 +2626,6 @@ dependencies = [
|
||||||
"syn 1.0.109",
|
"syn 1.0.109",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tonic-mock"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "git+https://github.com/brainrake/tonic-mock?branch=bump-dependencies#ec1a15510875de99d709d684190db5d9beab175e"
|
|
||||||
dependencies = [
|
|
||||||
"bytes",
|
|
||||||
"futures",
|
|
||||||
"http",
|
|
||||||
"http-body",
|
|
||||||
"prost",
|
|
||||||
"tonic",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tonic-reflection"
|
name = "tonic-reflection"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
|
@ -2796,7 +2783,6 @@ dependencies = [
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
"tonic",
|
"tonic",
|
||||||
"tonic-build",
|
"tonic-build",
|
||||||
"tonic-mock",
|
|
||||||
"tonic-reflection",
|
"tonic-reflection",
|
||||||
"tower",
|
"tower",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
|
|
@ -7751,47 +7751,6 @@ rec {
|
||||||
};
|
};
|
||||||
resolvedDefaultFeatures = [ "default" "prost" "prost-build" "transport" ];
|
resolvedDefaultFeatures = [ "default" "prost" "prost-build" "transport" ];
|
||||||
};
|
};
|
||||||
"tonic-mock" = rec {
|
|
||||||
crateName = "tonic-mock";
|
|
||||||
version = "0.1.0";
|
|
||||||
edition = "2018";
|
|
||||||
workspace_member = null;
|
|
||||||
src = pkgs.fetchgit {
|
|
||||||
url = "https://github.com/brainrake/tonic-mock";
|
|
||||||
rev = "ec1a15510875de99d709d684190db5d9beab175e";
|
|
||||||
sha256 = "0lwa03hpp0mxa6aa1zv5w68k61y4hccfm0q2ykyq392fwal8vb50";
|
|
||||||
};
|
|
||||||
authors = [
|
|
||||||
"Tyr Chen <tyr.chen@gmail.com>"
|
|
||||||
];
|
|
||||||
dependencies = [
|
|
||||||
{
|
|
||||||
name = "bytes";
|
|
||||||
packageId = "bytes";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "futures";
|
|
||||||
packageId = "futures";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "http";
|
|
||||||
packageId = "http";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "http-body";
|
|
||||||
packageId = "http-body";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "prost";
|
|
||||||
packageId = "prost";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "tonic";
|
|
||||||
packageId = "tonic";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
};
|
|
||||||
"tonic-reflection" = rec {
|
"tonic-reflection" = rec {
|
||||||
crateName = "tonic-reflection";
|
crateName = "tonic-reflection";
|
||||||
version = "0.5.0";
|
version = "0.5.0";
|
||||||
|
@ -8399,10 +8358,6 @@ rec {
|
||||||
name = "test-case";
|
name = "test-case";
|
||||||
packageId = "test-case";
|
packageId = "test-case";
|
||||||
}
|
}
|
||||||
{
|
|
||||||
name = "tonic-mock";
|
|
||||||
packageId = "tonic-mock";
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
features = {
|
features = {
|
||||||
"tonic-reflection" = [ "dep:tonic-reflection" ];
|
"tonic-reflection" = [ "dep:tonic-reflection" ];
|
||||||
|
|
|
@ -34,7 +34,6 @@ tonic-build = "0.8.2"
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
test-case = "2.2.2"
|
test-case = "2.2.2"
|
||||||
tempfile = "3.3.0"
|
tempfile = "3.3.0"
|
||||||
tonic-mock = { git = "https://github.com/brainrake/tonic-mock", branch = "bump-dependencies" }
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
|
|
@ -1,23 +1,17 @@
|
||||||
use crate::fixtures::{BLOB_A, BLOB_A_DIGEST};
|
use crate::fixtures::{BLOB_A, BLOB_A_DIGEST};
|
||||||
use crate::proto::blob_service_server::BlobService as GRPCBlobService;
|
use crate::proto::{BlobChunk, ReadBlobRequest, StatBlobRequest};
|
||||||
use crate::proto::{BlobChunk, GRPCBlobServiceWrapper, ReadBlobRequest, StatBlobRequest};
|
use crate::utils::gen_blobsvc_grpc_client;
|
||||||
use crate::utils::gen_blob_service;
|
|
||||||
use tokio_stream::StreamExt;
|
use tokio_stream::StreamExt;
|
||||||
|
|
||||||
fn gen_grpc_blob_service() -> GRPCBlobServiceWrapper {
|
|
||||||
let blob_service = gen_blob_service();
|
|
||||||
GRPCBlobServiceWrapper::from(blob_service)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Trying to read a non-existent blob should return a not found error.
|
/// Trying to read a non-existent blob should return a not found error.
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn not_found_read() {
|
async fn not_found_read() {
|
||||||
let service = gen_grpc_blob_service();
|
let mut grpc_client = gen_blobsvc_grpc_client().await;
|
||||||
|
|
||||||
let resp = service
|
let resp = grpc_client
|
||||||
.read(tonic::Request::new(ReadBlobRequest {
|
.read(ReadBlobRequest {
|
||||||
digest: BLOB_A_DIGEST.clone().into(),
|
digest: BLOB_A_DIGEST.clone().into(),
|
||||||
}))
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
// We can't use unwrap_err here, because the Ok value doesn't implement
|
// We can't use unwrap_err here, because the Ok value doesn't implement
|
||||||
|
@ -32,13 +26,13 @@ async fn not_found_read() {
|
||||||
/// Trying to stat a non-existent blob should return a not found error.
|
/// Trying to stat a non-existent blob should return a not found error.
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn not_found_stat() {
|
async fn not_found_stat() {
|
||||||
let service = gen_grpc_blob_service();
|
let mut grpc_client = gen_blobsvc_grpc_client().await;
|
||||||
|
|
||||||
let resp = service
|
let resp = grpc_client
|
||||||
.stat(tonic::Request::new(StatBlobRequest {
|
.stat(StatBlobRequest {
|
||||||
digest: BLOB_A_DIGEST.clone().into(),
|
digest: BLOB_A_DIGEST.clone().into(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}))
|
})
|
||||||
.await
|
.await
|
||||||
.expect_err("must fail");
|
.expect_err("must fail");
|
||||||
|
|
||||||
|
@ -49,13 +43,13 @@ async fn not_found_stat() {
|
||||||
/// Put a blob in the store, get it back.
|
/// Put a blob in the store, get it back.
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn put_read_stat() {
|
async fn put_read_stat() {
|
||||||
let service = gen_grpc_blob_service();
|
let mut grpc_client = gen_blobsvc_grpc_client().await;
|
||||||
|
|
||||||
// Send blob A.
|
// Send blob A.
|
||||||
let put_resp = service
|
let put_resp = grpc_client
|
||||||
.put(tonic_mock::streaming_request(vec![BlobChunk {
|
.put(tokio_stream::once(BlobChunk {
|
||||||
data: BLOB_A.clone(),
|
data: BLOB_A.clone(),
|
||||||
}]))
|
}))
|
||||||
.await
|
.await
|
||||||
.expect("must succeed")
|
.expect("must succeed")
|
||||||
.into_inner();
|
.into_inner();
|
||||||
|
@ -65,20 +59,20 @@ async fn put_read_stat() {
|
||||||
// Stat for the digest of A.
|
// Stat for the digest of A.
|
||||||
// We currently don't ask for more granular chunking data, as we don't
|
// We currently don't ask for more granular chunking data, as we don't
|
||||||
// expose it yet.
|
// expose it yet.
|
||||||
let _resp = service
|
let _resp = grpc_client
|
||||||
.stat(tonic::Request::new(StatBlobRequest {
|
.stat(StatBlobRequest {
|
||||||
digest: BLOB_A_DIGEST.clone().into(),
|
digest: BLOB_A_DIGEST.clone().into(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}))
|
})
|
||||||
.await
|
.await
|
||||||
.expect("must succeed")
|
.expect("must succeed")
|
||||||
.into_inner();
|
.into_inner();
|
||||||
|
|
||||||
// Read the blob. It should return the same data.
|
// Read the blob. It should return the same data.
|
||||||
let resp = service
|
let resp = grpc_client
|
||||||
.read(tonic::Request::new(ReadBlobRequest {
|
.read(ReadBlobRequest {
|
||||||
digest: BLOB_A_DIGEST.clone().into(),
|
digest: BLOB_A_DIGEST.clone().into(),
|
||||||
}))
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let mut rx = resp.ok().unwrap().into_inner();
|
let mut rx = resp.ok().unwrap().into_inner();
|
||||||
|
|
|
@ -16,9 +16,7 @@ async fn get_directories(
|
||||||
grpc_client: &mut DirectoryServiceClient<Channel>,
|
grpc_client: &mut DirectoryServiceClient<Channel>,
|
||||||
get_directory_request: GetDirectoryRequest,
|
get_directory_request: GetDirectoryRequest,
|
||||||
) -> Result<Vec<Directory>, Status> {
|
) -> Result<Vec<Directory>, Status> {
|
||||||
let resp = grpc_client
|
let resp = grpc_client.get(get_directory_request).await;
|
||||||
.get(tonic::Request::new(get_directory_request))
|
|
||||||
.await;
|
|
||||||
|
|
||||||
// if the response is an error itself, return the error, otherwise unpack
|
// if the response is an error itself, return the error, otherwise unpack
|
||||||
let stream = match resp {
|
let stream = match resp {
|
||||||
|
@ -39,10 +37,10 @@ async fn not_found() {
|
||||||
let mut grpc_client = gen_directorysvc_grpc_client().await;
|
let mut grpc_client = gen_directorysvc_grpc_client().await;
|
||||||
|
|
||||||
let resp = grpc_client
|
let resp = grpc_client
|
||||||
.get(tonic::Request::new(GetDirectoryRequest {
|
.get(GetDirectoryRequest {
|
||||||
by_what: Some(ByWhat::Digest(DIRECTORY_A.digest().into())),
|
by_what: Some(ByWhat::Digest(DIRECTORY_A.digest().into())),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}))
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let stream = resp.expect("must succeed").into_inner();
|
let stream = resp.expect("must succeed").into_inner();
|
||||||
|
|
|
@ -12,8 +12,10 @@ use crate::{
|
||||||
blobservice::{BlobService, MemoryBlobService},
|
blobservice::{BlobService, MemoryBlobService},
|
||||||
directoryservice::{DirectoryService, MemoryDirectoryService},
|
directoryservice::{DirectoryService, MemoryDirectoryService},
|
||||||
proto::{
|
proto::{
|
||||||
|
blob_service_client::BlobServiceClient, blob_service_server::BlobServiceServer,
|
||||||
directory_service_client::DirectoryServiceClient,
|
directory_service_client::DirectoryServiceClient,
|
||||||
directory_service_server::DirectoryServiceServer, GRPCDirectoryServiceWrapper,
|
directory_service_server::DirectoryServiceServer, GRPCBlobServiceWrapper,
|
||||||
|
GRPCDirectoryServiceWrapper,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -34,9 +36,8 @@ pin_project! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This will spawn the a gRPC server with a DirectoryService client, and
|
/// This will spawn the a gRPC server with a DirectoryService client, connect a
|
||||||
/// connect a gRPC DirectoryService client.
|
/// gRPC DirectoryService client and return it.
|
||||||
/// The client is returned.
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub(crate) async fn gen_directorysvc_grpc_client() -> DirectoryServiceClient<Channel> {
|
pub(crate) async fn gen_directorysvc_grpc_client() -> DirectoryServiceClient<Channel> {
|
||||||
let (left, right) = tokio::io::duplex(64);
|
let (left, right) = tokio::io::duplex(64);
|
||||||
|
@ -69,3 +70,38 @@ pub(crate) async fn gen_directorysvc_grpc_client() -> DirectoryServiceClient<Cha
|
||||||
|
|
||||||
grpc_client
|
grpc_client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This will spawn the a gRPC server with a BlobService client, connect a
|
||||||
|
/// gRPC BlobService client and return it.
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub(crate) async fn gen_blobsvc_grpc_client() -> BlobServiceClient<Channel> {
|
||||||
|
let (left, right) = tokio::io::duplex(64);
|
||||||
|
|
||||||
|
// spin up a server, which will only connect once, to the left side.
|
||||||
|
tokio::spawn(async {
|
||||||
|
// spin up a new DirectoryService
|
||||||
|
let mut server = Server::builder();
|
||||||
|
let router = server.add_service(BlobServiceServer::new(GRPCBlobServiceWrapper::from(
|
||||||
|
gen_blob_service(),
|
||||||
|
)));
|
||||||
|
|
||||||
|
router
|
||||||
|
.serve_with_incoming(tokio_stream::once(Ok::<_, std::io::Error>(left)))
|
||||||
|
.await
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create a client, connecting to the right side. The URI is unused.
|
||||||
|
let mut maybe_right = Some(right);
|
||||||
|
let grpc_client = BlobServiceClient::new(
|
||||||
|
Endpoint::try_from("http://[::]:50051")
|
||||||
|
.unwrap()
|
||||||
|
.connect_with_connector(tower::service_fn(move |_: Uri| {
|
||||||
|
let right = maybe_right.take().unwrap();
|
||||||
|
async move { Ok::<_, std::io::Error>(right) }
|
||||||
|
}))
|
||||||
|
.await
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
|
||||||
|
grpc_client
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
{
|
{
|
||||||
"fuse-backend-rs 0.10.5 (git+https://github.com/griff/fuse-backend-rs?branch=macfuse-fix#70b835cada7e1f18e5cbb13f6c4b698ba203c820)": "107iaw8zqsz888xh9nkq3vvki1c1rqqqg0mncdplradhhn7wp3kp",
|
"fuse-backend-rs 0.10.5 (git+https://github.com/griff/fuse-backend-rs?branch=macfuse-fix#70b835cada7e1f18e5cbb13f6c4b698ba203c820)": "107iaw8zqsz888xh9nkq3vvki1c1rqqqg0mncdplradhhn7wp3kp",
|
||||||
"test-generator 0.3.0 (git+https://github.com/JamesGuthrie/test-generator.git?rev=82e799979980962aec1aa324ec6e0e4cad781f41#82e799979980962aec1aa324ec6e0e4cad781f41)": "08brp3qqa55hijc7xby3lam2cc84hvx1zzfqv6lj7smlczh8k32y",
|
"test-generator 0.3.0 (git+https://github.com/JamesGuthrie/test-generator.git?rev=82e799979980962aec1aa324ec6e0e4cad781f41#82e799979980962aec1aa324ec6e0e4cad781f41)": "08brp3qqa55hijc7xby3lam2cc84hvx1zzfqv6lj7smlczh8k32y",
|
||||||
"tonic-mock 0.1.0 (git+https://github.com/brainrake/tonic-mock?branch=bump-dependencies#ec1a15510875de99d709d684190db5d9beab175e)": "0lwa03hpp0mxa6aa1zv5w68k61y4hccfm0q2ykyq392fwal8vb50",
|
|
||||||
"wu-manber 0.1.0 (git+https://github.com/tvlfyi/wu-manber.git#0d5b22bea136659f7de60b102a7030e0daaa503d)": "1zhk83lbq99xzyjwphv2qrb8f8qgfqwa5bbbvyzm0z0bljsjv0pd"
|
"wu-manber 0.1.0 (git+https://github.com/tvlfyi/wu-manber.git#0d5b22bea136659f7de60b102a7030e0daaa503d)": "1zhk83lbq99xzyjwphv2qrb8f8qgfqwa5bbbvyzm0z0bljsjv0pd"
|
||||||
}
|
}
|
|
@ -64,7 +64,6 @@ let
|
||||||
) [
|
) [
|
||||||
"fuse-backend-rs"
|
"fuse-backend-rs"
|
||||||
"test-generator"
|
"test-generator"
|
||||||
"tonic-mock"
|
|
||||||
"wu-manber"
|
"wu-manber"
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue