K2V #293

Merged
lx merged 68 commits from k2v into main 2022-05-10 11:16:58 +00:00
14 changed files with 111 additions and 31 deletions
Showing only changes of commit aedb1c1751 - Show all commits

View file

@ -10,7 +10,7 @@ pub fn build_client(instance: &Instance) -> Client {
None, None,
"garage-integ-test", "garage-integ-test",
); );
let endpoint = Endpoint::immutable(instance.uri()); let endpoint = Endpoint::immutable(instance.s3_uri());
let config = Config::builder() let config = Config::builder()
.region(super::REGION) .region(super::REGION)

View file

@ -17,14 +17,25 @@ use garage_api::signature;
pub struct CustomRequester { pub struct CustomRequester {
key: Key, key: Key,
uri: Uri, uri: Uri,
service: &'static str,
client: Client<HttpConnector>, client: Client<HttpConnector>,
} }
impl CustomRequester { impl CustomRequester {
pub fn new(instance: &Instance) -> Self { pub fn new_s3(instance: &Instance) -> Self {
CustomRequester { CustomRequester {
key: instance.key.clone(), key: instance.key.clone(),
uri: instance.uri(), uri: instance.s3_uri(),
service: "s3",
client: Client::new(),
}
}
pub fn new_k2v(instance: &Instance) -> Self {
CustomRequester {
key: instance.key.clone(),
uri: instance.k2v_uri(),
service: "k2v",
client: Client::new(), client: Client::new(),
} }
} }
@ -32,7 +43,7 @@ impl CustomRequester {
pub fn builder(&self, bucket: String) -> RequestBuilder<'_> { pub fn builder(&self, bucket: String) -> RequestBuilder<'_> {
RequestBuilder { RequestBuilder {
requester: self, requester: self,
service: "s3", service: self.service,
bucket, bucket,
method: Method::GET, method: Method::GET,
path: String::new(), path: String::new(),
@ -112,12 +123,12 @@ impl<'a> RequestBuilder<'a> {
let query = query_param_to_string(&self.query_params); let query = query_param_to_string(&self.query_params);
let (host, path) = if self.vhost_style { let (host, path) = if self.vhost_style {
( (
format!("{}.s3.garage", self.bucket), format!("{}.{}.garage", self.bucket, self.service),
format!("{}{}", self.path, query), format!("{}{}", self.path, query),
) )
} else { } else {
( (
"s3.garage".to_owned(), format!("{}.garage", self.service),
format!("{}/{}{}", self.bucket, self.path, query), format!("{}/{}{}", self.bucket, self.path, query),
) )
}; };
@ -129,7 +140,7 @@ impl<'a> RequestBuilder<'a> {
&now, &now,
&self.requester.key.secret, &self.requester.key.secret,
super::REGION.as_ref(), super::REGION.as_ref(),
"s3", self.service,
) )
.unwrap(); .unwrap();
let streaming_signer = signer.clone(); let streaming_signer = signer.clone();

View file

@ -22,7 +22,9 @@ pub struct Instance {
process: process::Child, process: process::Child,
pub path: PathBuf, pub path: PathBuf,
pub key: Key, pub key: Key,
pub api_port: u16, pub s3_port: u16,
pub k2v_port: u16,
pub web_port: u16,
} }
impl Instance { impl Instance {
@ -58,9 +60,12 @@ rpc_secret = "{secret}"
[s3_api] [s3_api]
s3_region = "{region}" s3_region = "{region}"
api_bind_addr = "127.0.0.1:{api_port}" api_bind_addr = "127.0.0.1:{s3_port}"
root_domain = ".s3.garage" root_domain = ".s3.garage"
[k2v_api]
api_bind_addr = "127.0.0.1:{k2v_port}"
[s3_web] [s3_web]
bind_addr = "127.0.0.1:{web_port}" bind_addr = "127.0.0.1:{web_port}"
root_domain = ".web.garage" root_domain = ".web.garage"
@ -72,10 +77,11 @@ api_bind_addr = "127.0.0.1:{admin_port}"
path = path.display(), path = path.display(),
secret = GARAGE_TEST_SECRET, secret = GARAGE_TEST_SECRET,
region = super::REGION, region = super::REGION,
api_port = port, s3_port = port,
rpc_port = port + 1, k2v_port = port + 1,
web_port = port + 2, rpc_port = port + 2,
admin_port = port + 3, web_port = port + 3,
admin_port = port + 4,
); );
fs::write(path.join("config.toml"), config).expect("Could not write garage config file"); fs::write(path.join("config.toml"), config).expect("Could not write garage config file");
@ -88,7 +94,7 @@ api_bind_addr = "127.0.0.1:{admin_port}"
.arg("server") .arg("server")
.stdout(stdout) .stdout(stdout)
.stderr(stderr) .stderr(stderr)
.env("RUST_LOG", "garage=info,garage_api=debug") .env("RUST_LOG", "garage=info,garage_api=trace")
.spawn() .spawn()
.expect("Could not start garage"); .expect("Could not start garage");
@ -96,7 +102,9 @@ api_bind_addr = "127.0.0.1:{admin_port}"
process: child, process: child,
path, path,
key: Key::default(), key: Key::default(),
api_port: port, s3_port: port,
k2v_port: port + 1,
web_port: port + 3,
} }
} }
@ -147,8 +155,14 @@ api_bind_addr = "127.0.0.1:{admin_port}"
String::from_utf8(output.stdout).unwrap() String::from_utf8(output.stdout).unwrap()
} }
pub fn uri(&self) -> http::Uri { pub fn s3_uri(&self) -> http::Uri {
format!("http://127.0.0.1:{api_port}", api_port = self.api_port) format!("http://127.0.0.1:{s3_port}", s3_port = self.s3_port)
.parse()
.expect("Could not build garage endpoint URI")
}
pub fn k2v_uri(&self) -> http::Uri {
format!("http://127.0.0.1:{k2v_port}", k2v_port = self.k2v_port)
.parse() .parse()
.expect("Could not build garage endpoint URI") .expect("Could not build garage endpoint URI")
} }

View file

@ -17,18 +17,27 @@ pub struct Context {
pub garage: &'static garage::Instance, pub garage: &'static garage::Instance,
pub client: Client, pub client: Client,
pub custom_request: CustomRequester, pub custom_request: CustomRequester,
pub k2v: K2VContext,
}
pub struct K2VContext {
pub request: CustomRequester,
} }
impl Context { impl Context {
fn new() -> Self { fn new() -> Self {
let garage = garage::instance(); let garage = garage::instance();
let client = client::build_client(garage); let client = client::build_client(garage);
let custom_request = CustomRequester::new(garage); let custom_request = CustomRequester::new_s3(garage);
let k2v_request = CustomRequester::new_k2v(garage);
Context { Context {
garage, garage,
client, client,
custom_request, custom_request,
k2v: K2VContext {
request: k2v_request,
}
} }
} }

View file

@ -0,0 +1 @@
pub mod simple;

View file

@ -0,0 +1,43 @@
use std::collections::HashMap;
use crate::common;
use common::custom_requester::BodySignature;
use hyper::Method;
#[tokio::test]
async fn test_simple() {
let ctx = common::context();
let bucket = ctx.create_bucket("test-k2v-simple");
let mut query_params = HashMap::new();
query_params.insert("sort_key".to_string(), Some("test1".to_string()));
let res = ctx.k2v.request
.builder(bucket.clone())
.method(Method::PUT)
.path("root".into())
.query_params(query_params.clone())
.body(b"Hello, world!".to_vec())
.body_signature(BodySignature::Classic)
.send()
.await
.unwrap();
assert_eq!(res.status(), 200);
let mut h = HashMap::new();
h.insert("accept".to_string(), "application/octet-stream".to_string());
let res2 = ctx.k2v.request
.builder(bucket.clone())
.path("root".into())
.query_params(query_params.clone())
.signed_headers(h)
.body_signature(BodySignature::Classic)
.send()
.await
.unwrap();
assert_eq!(res2.status(), 200);
let res2_body = hyper::body::to_bytes(res2.into_body()).await.unwrap().to_vec();
assert_eq!(res2_body, b"Hello, world!");
}

View file

@ -3,9 +3,5 @@ mod common;
mod admin; mod admin;
mod bucket; mod bucket;
mod list; mod s3;
mod multipart; mod k2v;
mod objects;
mod simple;
mod streaming_signature;
mod website;

View file

@ -0,0 +1,6 @@
mod list;
mod multipart;
mod objects;
mod simple;
mod streaming_signature;
mod website;

View file

@ -37,7 +37,7 @@ async fn test_website() {
.method("GET") .method("GET")
.uri(format!( .uri(format!(
"http://127.0.0.1:{}/", "http://127.0.0.1:{}/",
common::garage::DEFAULT_PORT + 2 ctx.garage.web_port
)) ))
.header("Host", format!("{}.web.garage", BCKT_NAME)) .header("Host", format!("{}.web.garage", BCKT_NAME))
.body(Body::empty()) .body(Body::empty())
@ -172,7 +172,7 @@ async fn test_website_s3_api() {
.method("GET") .method("GET")
.uri(format!( .uri(format!(
"http://127.0.0.1:{}/site/", "http://127.0.0.1:{}/site/",
common::garage::DEFAULT_PORT + 2 ctx.garage.web_port
)) ))
.header("Host", format!("{}.web.garage", BCKT_NAME)) .header("Host", format!("{}.web.garage", BCKT_NAME))
.header("Origin", "https://example.com") .header("Origin", "https://example.com")
@ -198,7 +198,7 @@ async fn test_website_s3_api() {
.method("GET") .method("GET")
.uri(format!( .uri(format!(
"http://127.0.0.1:{}/wrong.html", "http://127.0.0.1:{}/wrong.html",
common::garage::DEFAULT_PORT + 2 ctx.garage.web_port
)) ))
.header("Host", format!("{}.web.garage", BCKT_NAME)) .header("Host", format!("{}.web.garage", BCKT_NAME))
.body(Body::empty()) .body(Body::empty())
@ -219,7 +219,7 @@ async fn test_website_s3_api() {
.method("OPTIONS") .method("OPTIONS")
.uri(format!( .uri(format!(
"http://127.0.0.1:{}/site/", "http://127.0.0.1:{}/site/",
common::garage::DEFAULT_PORT + 2 ctx.garage.web_port
)) ))
.header("Host", format!("{}.web.garage", BCKT_NAME)) .header("Host", format!("{}.web.garage", BCKT_NAME))
.header("Origin", "https://example.com") .header("Origin", "https://example.com")
@ -246,7 +246,7 @@ async fn test_website_s3_api() {
.method("OPTIONS") .method("OPTIONS")
.uri(format!( .uri(format!(
"http://127.0.0.1:{}/site/", "http://127.0.0.1:{}/site/",
common::garage::DEFAULT_PORT + 2 ctx.garage.web_port
)) ))
.header("Host", format!("{}.web.garage", BCKT_NAME)) .header("Host", format!("{}.web.garage", BCKT_NAME))
.header("Origin", "https://example.com") .header("Origin", "https://example.com")
@ -290,7 +290,7 @@ async fn test_website_s3_api() {
.method("OPTIONS") .method("OPTIONS")
.uri(format!( .uri(format!(
"http://127.0.0.1:{}/site/", "http://127.0.0.1:{}/site/",
common::garage::DEFAULT_PORT + 2 ctx.garage.web_port
)) ))
.header("Host", format!("{}.web.garage", BCKT_NAME)) .header("Host", format!("{}.web.garage", BCKT_NAME))
.header("Origin", "https://example.com") .header("Origin", "https://example.com")
@ -321,7 +321,7 @@ async fn test_website_s3_api() {
.method("GET") .method("GET")
.uri(format!( .uri(format!(
"http://127.0.0.1:{}/site/", "http://127.0.0.1:{}/site/",
common::garage::DEFAULT_PORT + 2 ctx.garage.web_port
)) ))
.header("Host", format!("{}.web.garage", BCKT_NAME)) .header("Host", format!("{}.web.garage", BCKT_NAME))
.body(Body::empty()) .body(Body::empty())