Merge pull request 'Increase Garage tests robustness' (#526) from tests/increase-robustness into main

Reviewed-on: Deuxfleurs/garage#526
Reviewed-by: Alex <alex@adnab.me>
Reviewed-by: trinity-1686a <trinity.pointard@gmail.com>
This commit is contained in:
Alex 2023-03-13 17:26:21 +00:00
commit d6ffa57f40
8 changed files with 58 additions and 63 deletions

View file

@ -21,14 +21,7 @@ async fn test_admin_bucket_perms() {
ctx.garage ctx.garage
.command() .command()
.args([ .args(["bucket", "allow", "--read", "--key", &ctx.key.id, BCKT_NAME])
"bucket",
"allow",
"--read",
"--key",
&ctx.garage.key.id,
BCKT_NAME,
])
.quiet() .quiet()
.expect_success_status("Could not create bucket"); .expect_success_status("Could not create bucket");
@ -36,14 +29,7 @@ async fn test_admin_bucket_perms() {
ctx.garage ctx.garage
.command() .command()
.args([ .args(["bucket", "deny", "--read", "--key", &ctx.key.id, BCKT_NAME])
"bucket",
"deny",
"--read",
"--key",
&ctx.garage.key.name,
BCKT_NAME,
])
.quiet() .quiet()
.expect_success_status("Could not create bucket"); .expect_success_status("Could not create bucket");
@ -51,14 +37,7 @@ async fn test_admin_bucket_perms() {
ctx.garage ctx.garage
.command() .command()
.args([ .args(["bucket", "allow", "--read", "--key", &ctx.key.id, BCKT_NAME])
"bucket",
"allow",
"--read",
"--key",
&ctx.garage.key.name,
BCKT_NAME,
])
.quiet() .quiet()
.expect_success_status("Could not create bucket"); .expect_success_status("Could not create bucket");

View file

@ -13,7 +13,7 @@ async fn test_bucket_all() {
ctx.garage ctx.garage
.command() .command()
.args(["key", "deny"]) .args(["key", "deny"])
.args(["--create-bucket", &ctx.garage.key.id]) .args(["--create-bucket", &ctx.key.id])
.quiet() .quiet()
.expect_success_output("Could not deny key to create buckets"); .expect_success_output("Could not deny key to create buckets");
@ -26,7 +26,7 @@ async fn test_bucket_all() {
ctx.garage ctx.garage
.command() .command()
.args(["key", "allow"]) .args(["key", "allow"])
.args(["--create-bucket", &ctx.garage.key.id]) .args(["--create-bucket", &ctx.key.id])
.quiet() .quiet()
.expect_success_output("Could not deny key to create buckets"); .expect_success_output("Could not deny key to create buckets");

View file

@ -1,15 +1,9 @@
use aws_sdk_s3::{Client, Config, Credentials, Endpoint}; use aws_sdk_s3::{Client, Config, Credentials, Endpoint};
use super::garage::Instance; use super::garage::{Instance, Key};
pub fn build_client(instance: &Instance) -> Client { pub fn build_client(instance: &Instance, key: &Key) -> Client {
let credentials = Credentials::new( let credentials = Credentials::new(&key.id, &key.secret, None, None, "garage-integ-test");
&instance.key.id,
&instance.key.secret,
None,
None,
"garage-integ-test",
);
let endpoint = Endpoint::immutable(instance.s3_uri()); let endpoint = Endpoint::immutable(instance.s3_uri());
let config = Config::builder() let config = Config::builder()

View file

@ -14,6 +14,7 @@ use garage_api::signature;
/// You should ever only use this to send requests AWS sdk won't send, /// You should ever only use this to send requests AWS sdk won't send,
/// like to reproduce behavior of unusual implementations found to be /// like to reproduce behavior of unusual implementations found to be
/// problematic. /// problematic.
#[derive(Clone)]
pub struct CustomRequester { pub struct CustomRequester {
key: Key, key: Key,
uri: Uri, uri: Uri,
@ -22,18 +23,18 @@ pub struct CustomRequester {
} }
impl CustomRequester { impl CustomRequester {
pub fn new_s3(instance: &Instance) -> Self { pub fn new_s3(instance: &Instance, key: &Key) -> Self {
CustomRequester { CustomRequester {
key: instance.key.clone(), key: key.clone(),
uri: instance.s3_uri(), uri: instance.s3_uri(),
service: "s3", service: "s3",
client: Client::new(), client: Client::new(),
} }
} }
pub fn new_k2v(instance: &Instance) -> Self { pub fn new_k2v(instance: &Instance, key: &Key) -> Self {
CustomRequester { CustomRequester {
key: instance.key.clone(), key: key.clone(),
uri: instance.k2v_uri(), uri: instance.k2v_uri(),
service: "k2v", service: "k2v",
client: Client::new(), client: Client::new(),

View file

@ -13,7 +13,7 @@ static GARAGE_TEST_SECRET: &str =
#[derive(Debug, Default, Clone)] #[derive(Debug, Default, Clone)]
pub struct Key { pub struct Key {
pub name: String, pub name: Option<String>,
pub id: String, pub id: String,
pub secret: String, pub secret: String,
} }
@ -21,7 +21,7 @@ pub struct Key {
pub struct Instance { pub struct Instance {
process: process::Child, process: process::Child,
pub path: PathBuf, pub path: PathBuf,
pub key: Key, pub default_key: Key,
pub s3_port: u16, pub s3_port: u16,
pub k2v_port: u16, pub k2v_port: u16,
pub web_port: u16, pub web_port: u16,
@ -102,7 +102,7 @@ api_bind_addr = "127.0.0.1:{admin_port}"
Instance { Instance {
process: child, process: child,
path, path,
key: Key::default(), default_key: Key::default(),
s3_port: port, s3_port: port,
k2v_port: port + 1, k2v_port: port + 1,
web_port: port + 3, web_port: port + 3,
@ -111,14 +111,27 @@ api_bind_addr = "127.0.0.1:{admin_port}"
} }
fn setup(&mut self) { fn setup(&mut self) {
self.wait_for_boot();
self.setup_layout();
self.default_key = self.key(Some("garage_test"));
}
fn wait_for_boot(&mut self) {
use std::{thread, time::Duration}; use std::{thread, time::Duration};
// Wait for node to be ready // 60 * 2 seconds = 120 seconds = 2min
for _ in 0..60 {
let termination = self
.command()
.args(["status"])
.quiet()
.status()
.expect("Unable to run command");
if termination.success() {
break;
}
thread::sleep(Duration::from_secs(2)); thread::sleep(Duration::from_secs(2));
}
self.setup_layout();
self.key = self.new_key("garage_test");
} }
fn setup_layout(&self) { fn setup_layout(&self) {
@ -169,14 +182,17 @@ api_bind_addr = "127.0.0.1:{admin_port}"
.expect("Could not build garage endpoint URI") .expect("Could not build garage endpoint URI")
} }
pub fn new_key(&self, name: &str) -> Key { pub fn key(&self, maybe_name: Option<&str>) -> Key {
let mut key = Key::default(); let mut key = Key::default();
let output = self let mut cmd = self.command();
.command() let base = cmd.args(["key", "new"]);
.args(["key", "new"]) let with_name = match maybe_name {
.args(["--name", name]) Some(name) => base.args(["--name", name]),
.expect_success_output("Could not create key"); None => base,
};
let output = with_name.expect_success_output("Could not create key");
let stdout = String::from_utf8(output.stdout).unwrap(); let stdout = String::from_utf8(output.stdout).unwrap();
for line in stdout.lines() { for line in stdout.lines() {
@ -193,7 +209,7 @@ api_bind_addr = "127.0.0.1:{admin_port}"
assert!(!key.secret.is_empty(), "Invalid key: Key secret is empty"); assert!(!key.secret.is_empty(), "Invalid key: Key secret is empty");
Key { Key {
name: name.to_owned(), name: maybe_name.map(String::from),
..key ..key
} }
} }

View file

@ -13,13 +13,16 @@ use custom_requester::CustomRequester;
const REGION: Region = Region::from_static("garage-integ-test"); const REGION: Region = Region::from_static("garage-integ-test");
#[derive(Clone)]
pub struct Context { pub struct Context {
pub garage: &'static garage::Instance, pub garage: &'static garage::Instance,
pub key: garage::Key,
pub client: Client, pub client: Client,
pub custom_request: CustomRequester, pub custom_request: CustomRequester,
pub k2v: K2VContext, pub k2v: K2VContext,
} }
#[derive(Clone)]
pub struct K2VContext { pub struct K2VContext {
pub request: CustomRequester, pub request: CustomRequester,
} }
@ -27,13 +30,15 @@ pub struct K2VContext {
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 key = garage.key(None);
let custom_request = CustomRequester::new_s3(garage); let client = client::build_client(garage, &key);
let k2v_request = CustomRequester::new_k2v(garage); let custom_request = CustomRequester::new_s3(garage, &key);
let k2v_request = CustomRequester::new_k2v(garage, &key);
Context { Context {
garage, garage,
client, client,
key,
custom_request, custom_request,
k2v: K2VContext { k2v: K2VContext {
request: k2v_request, request: k2v_request,
@ -57,7 +62,7 @@ impl Context {
.args(["bucket", "allow"]) .args(["bucket", "allow"])
.args(["--owner", "--read", "--write"]) .args(["--owner", "--read", "--write"])
.arg(&bucket_name) .arg(&bucket_name)
.args(["--key", &self.garage.key.name]) .args(["--key", &self.key.id])
.quiet() .quiet()
.expect_success_status("Could not allow key for bucket"); .expect_success_status("Could not allow key for bucket");

View file

@ -57,8 +57,8 @@ async fn test_poll_item() {
let poll = { let poll = {
let bucket = bucket.clone(); let bucket = bucket.clone();
let ct = ct.clone(); let ct = ct.clone();
let ctx = ctx.clone();
tokio::spawn(async move { tokio::spawn(async move {
let ctx = common::context();
ctx.k2v ctx.k2v
.request .request
.builder(bucket.clone()) .builder(bucket.clone())
@ -171,8 +171,8 @@ async fn test_poll_range() {
// Second poll range, which will complete later // Second poll range, which will complete later
let poll = { let poll = {
let bucket = bucket.clone(); let bucket = bucket.clone();
let ctx = ctx.clone();
tokio::spawn(async move { tokio::spawn(async move {
let ctx = common::context();
ctx.k2v ctx.k2v
.request .request
.builder(bucket.clone()) .builder(bucket.clone())
@ -220,8 +220,8 @@ async fn test_poll_range() {
// Start a new poll operation // Start a new poll operation
let poll = { let poll = {
let bucket = bucket.clone(); let bucket = bucket.clone();
let ctx = ctx.clone();
tokio::spawn(async move { tokio::spawn(async move {
let ctx = common::context();
ctx.k2v ctx.k2v
.request .request
.builder(bucket.clone()) .builder(bucket.clone())

View file

@ -109,7 +109,7 @@ async fn test_create_bucket_streaming() {
ctx.garage ctx.garage
.command() .command()
.args(["key", "allow"]) .args(["key", "allow"])
.args(["--create-bucket", &ctx.garage.key.id]) .args(["--create-bucket", &ctx.key.id])
.quiet() .quiet()
.expect_success_output("Could not allow key to create buckets"); .expect_success_output("Could not allow key to create buckets");