Loading .github/actions/setup/action.yml 0 → 100644 +11 −0 Original line number Diff line number Diff line name: "setup" description: "setup environment for s3s" runs: using: "composite" steps: - uses: taiki-e/install-action@just - uses: astral-sh/setup-uv@v3 with: enable-cache: true - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 .github/workflows/ci.yml +11 −17 Original line number Diff line number Diff line Loading @@ -86,42 +86,36 @@ jobs: - uses: taiki-e/install-action@cargo-audit - run: cargo audit -D warnings mint: mint-proxy-minio: name: e2e (mint, s3s-proxy, minio) needs: skip-check if: needs.skip-check.outputs.should_skip != 'true' name: e2e (s3s-proxy, mint) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: toolchain: stable - uses: Swatinem/rust-cache@v2 - uses: ./.github/actions/setup - run: docker pull minio/mint:edge - run: docker pull minio/minio:latest - run: cargo install --path crates/s3s-proxy - run: just install s3s-proxy - run: ./scripts/e2e-mint.sh - run: ./scripts/report-mint.py /tmp/mint/log.json - uses: actions/upload-artifact@v4 with: name: e2e-mint-logs name: mint-proxy-minio.logs path: ./target/s3s-proxy.log e2e-fs: name: e2e (s3s-e2e, s3s-fs) needs: skip-check if: needs.skip-check.outputs.should_skip != 'true' name: e2e (s3s-fs, s3s-e2e) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: toolchain: stable - uses: Swatinem/rust-cache@v2 - uses: ./.github/actions/setup - run: just install s3s-e2e - run: just install s3s-fs - run: ./scripts/e2e-fs.sh - uses: actions/upload-artifact@v4 with: name: e2e-fs-logs path: | ./target/s3s-fs.log ./target/s3s-e2e.log name: e2e-fs.logs path: ./target/s3s-fs.log crates/s3s-fs/src/s3.rs +5 −1 Original line number Diff line number Diff line Loading @@ -124,7 +124,11 @@ impl S3 for FileSystem { async fn delete_bucket(&self, req: S3Request<DeleteBucketInput>) -> S3Result<S3Response<DeleteBucketOutput>> { let input = req.input; let path = self.get_bucket_path(&input.bucket)?; if path.exists() { try_!(fs::remove_dir_all(path).await); } else { return Err(s3_error!(NoSuchBucket)); } Ok(S3Response::new(DeleteBucketOutput {})) } Loading crates/s3s-test/e2e/main.rs +3 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ use s3s_test::TestFixture; use s3s_test::TestSuite; use std::fmt; use std::process::Termination; use std::sync::Arc; use aws_sdk_s3::error::ProvideErrorMetadata; Loading Loading @@ -115,7 +116,7 @@ impl Basic { } } fn main() { fn main() -> impl Termination { s3s_test::cli::main(|tcx| { macro_rules! case { ($s:ident, $x:ident, $c:ident) => {{ Loading @@ -126,5 +127,5 @@ fn main() { } case!(E2E, Basic, test_list_buckets); }); }) } crates/s3s-test/src/cli.rs +35 −17 Original line number Diff line number Diff line use std::path::Path; use std::path::PathBuf; use std::process::ExitCode; use std::process::Termination; use crate::report::FnResult; use crate::report::Report; use crate::tcx::TestContext; use clap::Parser; Loading Loading @@ -37,18 +41,13 @@ fn status(passed: bool) -> ColoredString { } } #[tokio::main] async fn async_main(opt: &Opt, register: impl FnOnce(&mut TestContext)) -> Result<(), StdError> { let mut tcx = TestContext::new(); register(&mut tcx); let report = crate::runner::run(&mut tcx).await; if let Some(ref json_path) = opt.json { fn write_report(json_path: &Path, report: &Report) -> Result<(), StdError> { let report_json = serde_json::to_string_pretty(&report)?; std::fs::write(json_path, report_json)?; Ok(()) } fn print_summary(report: &Report) { let w = format!("{:.3}", report.duration_ms).len(); for suite in &report.suites { Loading Loading @@ -87,16 +86,35 @@ async fn async_main(opt: &Opt, register: impl FnOnce(&mut TestContext)) -> Resul let status = status(report.suite_count.all_passed()); let duration = report.duration_ms; println!("{status} {duration:>w$.3}ms"); } Ok(()) #[tokio::main] async fn async_main(opt: &Opt, register: impl FnOnce(&mut TestContext)) -> ExitCode { let mut tcx = TestContext::new(); register(&mut tcx); let report = crate::runner::run(&mut tcx).await; if let Some(ref json_path) = opt.json { if let Err(err) = write_report(json_path, &report) { eprintln!("Failed to write report: {err}"); return ExitCode::from(2); } } pub fn main(register: impl FnOnce(&mut TestContext)) { print_summary(&report); if report.suite_count.all_passed() { ExitCode::from(0) } else { ExitCode::from(1) } } #[must_use] pub fn main(register: impl FnOnce(&mut TestContext)) -> impl Termination { dotenvy::dotenv().ok(); setup_tracing(); let opt = Opt::parse(); if let Err(err) = async_main(&opt, register) { eprintln!("{err}"); std::process::exit(1); } async_main(&opt, register) } Loading
.github/actions/setup/action.yml 0 → 100644 +11 −0 Original line number Diff line number Diff line name: "setup" description: "setup environment for s3s" runs: using: "composite" steps: - uses: taiki-e/install-action@just - uses: astral-sh/setup-uv@v3 with: enable-cache: true - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2
.github/workflows/ci.yml +11 −17 Original line number Diff line number Diff line Loading @@ -86,42 +86,36 @@ jobs: - uses: taiki-e/install-action@cargo-audit - run: cargo audit -D warnings mint: mint-proxy-minio: name: e2e (mint, s3s-proxy, minio) needs: skip-check if: needs.skip-check.outputs.should_skip != 'true' name: e2e (s3s-proxy, mint) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: toolchain: stable - uses: Swatinem/rust-cache@v2 - uses: ./.github/actions/setup - run: docker pull minio/mint:edge - run: docker pull minio/minio:latest - run: cargo install --path crates/s3s-proxy - run: just install s3s-proxy - run: ./scripts/e2e-mint.sh - run: ./scripts/report-mint.py /tmp/mint/log.json - uses: actions/upload-artifact@v4 with: name: e2e-mint-logs name: mint-proxy-minio.logs path: ./target/s3s-proxy.log e2e-fs: name: e2e (s3s-e2e, s3s-fs) needs: skip-check if: needs.skip-check.outputs.should_skip != 'true' name: e2e (s3s-fs, s3s-e2e) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: toolchain: stable - uses: Swatinem/rust-cache@v2 - uses: ./.github/actions/setup - run: just install s3s-e2e - run: just install s3s-fs - run: ./scripts/e2e-fs.sh - uses: actions/upload-artifact@v4 with: name: e2e-fs-logs path: | ./target/s3s-fs.log ./target/s3s-e2e.log name: e2e-fs.logs path: ./target/s3s-fs.log
crates/s3s-fs/src/s3.rs +5 −1 Original line number Diff line number Diff line Loading @@ -124,7 +124,11 @@ impl S3 for FileSystem { async fn delete_bucket(&self, req: S3Request<DeleteBucketInput>) -> S3Result<S3Response<DeleteBucketOutput>> { let input = req.input; let path = self.get_bucket_path(&input.bucket)?; if path.exists() { try_!(fs::remove_dir_all(path).await); } else { return Err(s3_error!(NoSuchBucket)); } Ok(S3Response::new(DeleteBucketOutput {})) } Loading
crates/s3s-test/e2e/main.rs +3 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ use s3s_test::TestFixture; use s3s_test::TestSuite; use std::fmt; use std::process::Termination; use std::sync::Arc; use aws_sdk_s3::error::ProvideErrorMetadata; Loading Loading @@ -115,7 +116,7 @@ impl Basic { } } fn main() { fn main() -> impl Termination { s3s_test::cli::main(|tcx| { macro_rules! case { ($s:ident, $x:ident, $c:ident) => {{ Loading @@ -126,5 +127,5 @@ fn main() { } case!(E2E, Basic, test_list_buckets); }); }) }
crates/s3s-test/src/cli.rs +35 −17 Original line number Diff line number Diff line use std::path::Path; use std::path::PathBuf; use std::process::ExitCode; use std::process::Termination; use crate::report::FnResult; use crate::report::Report; use crate::tcx::TestContext; use clap::Parser; Loading Loading @@ -37,18 +41,13 @@ fn status(passed: bool) -> ColoredString { } } #[tokio::main] async fn async_main(opt: &Opt, register: impl FnOnce(&mut TestContext)) -> Result<(), StdError> { let mut tcx = TestContext::new(); register(&mut tcx); let report = crate::runner::run(&mut tcx).await; if let Some(ref json_path) = opt.json { fn write_report(json_path: &Path, report: &Report) -> Result<(), StdError> { let report_json = serde_json::to_string_pretty(&report)?; std::fs::write(json_path, report_json)?; Ok(()) } fn print_summary(report: &Report) { let w = format!("{:.3}", report.duration_ms).len(); for suite in &report.suites { Loading Loading @@ -87,16 +86,35 @@ async fn async_main(opt: &Opt, register: impl FnOnce(&mut TestContext)) -> Resul let status = status(report.suite_count.all_passed()); let duration = report.duration_ms; println!("{status} {duration:>w$.3}ms"); } Ok(()) #[tokio::main] async fn async_main(opt: &Opt, register: impl FnOnce(&mut TestContext)) -> ExitCode { let mut tcx = TestContext::new(); register(&mut tcx); let report = crate::runner::run(&mut tcx).await; if let Some(ref json_path) = opt.json { if let Err(err) = write_report(json_path, &report) { eprintln!("Failed to write report: {err}"); return ExitCode::from(2); } } pub fn main(register: impl FnOnce(&mut TestContext)) { print_summary(&report); if report.suite_count.all_passed() { ExitCode::from(0) } else { ExitCode::from(1) } } #[must_use] pub fn main(register: impl FnOnce(&mut TestContext)) -> impl Termination { dotenvy::dotenv().ok(); setup_tracing(); let opt = Opt::parse(); if let Err(err) = async_main(&opt, register) { eprintln!("{err}"); std::process::exit(1); } async_main(&opt, register) }