This drops pretty much all of castore/utils.rs.
There were only two things left in there, both a bit messy and only used
for tests:
Some `gen_*_service()` helper functions. These can be expressed by
`from_addr("memory://")`.
The other thing was some plumbing code to test the gRPC layer, by
exposing a in-memory implementation via gRPC, and then connecting to
that channel via a gRPC client again.
Previous CLs moved the connection setup code to
{directory,blob}service::tests::utils, close to where we exercise them,
the new rstest-based tests.
The tests interacting directly on the gRPC types are removed, all
scenarios that were in there show now be covered through the rstest ones
on the trait level.
Change-Id: I450ccccf983b4c62145a25d81c36a40846664814
Reviewed-on: https://cl.tvl.fyi/c/depot/+/11223
Reviewed-by: Connor Brewster <cbrewster@hey.com>
Tested-by: BuildkiteCI
87 lines
3.6 KiB
Rust
87 lines
3.6 KiB
Rust
use super::{grpc::GRPCBuildService, BuildService, DummyBuildService};
|
|
use tvix_castore::{blobservice::BlobService, directoryservice::DirectoryService};
|
|
use url::Url;
|
|
|
|
/// Constructs a new instance of a [BuildService] from an URI.
|
|
///
|
|
/// The following schemes are supported by the following services:
|
|
/// - `dummy://` ([DummyBuildService])
|
|
/// - `grpc+*://` ([GRPCBuildService])
|
|
///
|
|
/// As some of these [BuildService] need to talk to a [BlobService] and
|
|
/// [DirectoryService], these also need to be passed in.
|
|
pub async fn from_addr<BS, DS>(
|
|
uri: &str,
|
|
_blob_service: BS,
|
|
_directory_service: DS,
|
|
) -> std::io::Result<Box<dyn BuildService>>
|
|
where
|
|
BS: AsRef<dyn BlobService> + Send + Sync + Clone + 'static,
|
|
DS: AsRef<dyn DirectoryService> + Send + Sync + Clone + 'static,
|
|
{
|
|
let url = Url::parse(uri)
|
|
.map_err(|e| std::io::Error::other(format!("unable to parse url: {}", e)))?;
|
|
|
|
Ok(match url.scheme() {
|
|
// dummy doesn't care about parameters.
|
|
"dummy" => Box::<DummyBuildService>::default(),
|
|
scheme => {
|
|
if scheme.starts_with("grpc+") {
|
|
let client = crate::proto::build_service_client::BuildServiceClient::new(
|
|
tvix_castore::tonic::channel_from_url(&url)
|
|
.await
|
|
.map_err(std::io::Error::other)?,
|
|
);
|
|
// FUTUREWORK: also allow responding to {blob,directory}_service
|
|
// requests from the remote BuildService?
|
|
Box::new(GRPCBuildService::from_client(client))
|
|
} else {
|
|
Err(std::io::Error::other(format!(
|
|
"unknown scheme: {}",
|
|
url.scheme()
|
|
)))?
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use std::sync::Arc;
|
|
|
|
use super::from_addr;
|
|
use test_case::test_case;
|
|
use tvix_castore::{
|
|
blobservice::{BlobService, MemoryBlobService},
|
|
directoryservice::{DirectoryService, MemoryDirectoryService},
|
|
};
|
|
|
|
/// This uses an unsupported scheme.
|
|
#[test_case("http://foo.example/test", false; "unsupported scheme")]
|
|
/// This configures dummy
|
|
#[test_case("dummy://", true; "valid dummy")]
|
|
/// Correct scheme to connect to a unix socket.
|
|
#[test_case("grpc+unix:///path/to/somewhere", true; "grpc valid unix socket")]
|
|
/// Correct scheme for unix socket, but setting a host too, which is invalid.
|
|
#[test_case("grpc+unix://host.example/path/to/somewhere", false; "grpc invalid unix socket and host")]
|
|
/// Correct scheme to connect to localhost, with port 12345
|
|
#[test_case("grpc+http://[::1]:12345", true; "grpc valid IPv6 localhost port 12345")]
|
|
/// Correct scheme to connect to localhost over http, without specifying a port.
|
|
#[test_case("grpc+http://localhost", true; "grpc valid http host without port")]
|
|
/// Correct scheme to connect to localhost over http, without specifying a port.
|
|
#[test_case("grpc+https://localhost", true; "grpc valid https host without port")]
|
|
/// Correct scheme to connect to localhost over http, but with additional path, which is invalid.
|
|
#[test_case("grpc+http://localhost/some-path", false; "grpc valid invalid host and path")]
|
|
#[tokio::test]
|
|
async fn test_from_addr(uri_str: &str, is_ok: bool) {
|
|
let blob_service: Arc<dyn BlobService> = Arc::from(MemoryBlobService::default());
|
|
let directory_service: Arc<dyn DirectoryService> =
|
|
Arc::from(MemoryDirectoryService::default());
|
|
assert_eq!(
|
|
from_addr(uri_str, blob_service, directory_service)
|
|
.await
|
|
.is_ok(),
|
|
is_ok
|
|
)
|
|
}
|
|
}
|