Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 0 additions & 14 deletions .changelog/1773800575.md

This file was deleted.

2 changes: 1 addition & 1 deletion aws/rust-runtime/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion aws/rust-runtime/aws-config/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "aws-config"
version = "1.9.0"
version = "1.8.16"
authors = [
"AWS Rust SDK Team <aws-sdk-rust@amazon.com>",
"Russell Cohen <rcoh@amazon.com>",
Expand Down
31 changes: 13 additions & 18 deletions aws/rust-runtime/aws-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -549,24 +549,6 @@ mod loader {
self
}

/// Override the environment variable abstraction used during config resolution.
///
/// This can be used with [`Env::from_custom`] to provide a custom environment
/// variable backend (e.g., remote config stores, vaults).
pub fn env(mut self, env: Env) -> Self {
self.env = Some(env);
self
}

/// Override the filesystem abstraction used during config resolution.
///
/// This can be used with [`Fs::from_custom`] to provide a custom filesystem
/// backend (e.g., in-memory stores, encrypted filesystems).
pub fn fs(mut self, fs: Fs) -> Self {
self.fs = Some(fs);
self
}

/// Override the access token provider used to build [`SdkConfig`].
///
/// # Examples
Expand Down Expand Up @@ -1059,6 +1041,19 @@ mod loader {
}
}

#[cfg(test)]
impl ConfigLoader {
pub(crate) fn env(mut self, env: Env) -> Self {
self.env = Some(env);
self
}

pub(crate) fn fs(mut self, fs: Fs) -> Self {
self.fs = Some(fs);
self
}
}

#[cfg(test)]
mod test {
#[allow(deprecated)]
Expand Down
2 changes: 1 addition & 1 deletion aws/rust-runtime/aws-types/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "aws-types"
version = "1.4.0"
version = "1.3.15"
authors = ["AWS Rust SDK Team <aws-sdk-rust@amazon.com>", "Russell Cohen <rcoh@amazon.com>"]
description = "Cross-service types for the AWS SDK."
edition = "2021"
Expand Down
130 changes: 1 addition & 129 deletions aws/rust-runtime/aws-types/src/os_shim_internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,36 +11,11 @@ use std::collections::HashMap;
use std::env::VarError;
use std::ffi::OsString;
use std::fmt::Debug;
use std::future::Future;
use std::panic::{RefUnwindSafe, UnwindSafe};
use std::path::{Path, PathBuf};
use std::pin::Pin;
use std::sync::{Arc, Mutex};

use crate::os_shim_internal::fs::Fake;

/// Trait for custom environment variable providers.
pub trait ProvideEnv: Debug + Send + Sync + UnwindSafe + RefUnwindSafe {
/// Get the value of environment variable `k`.
fn get(&self, k: &str) -> Result<String, VarError>;
}

/// Trait for custom filesystem providers.
pub trait ProvideFs: Debug + Send + Sync + UnwindSafe + RefUnwindSafe {
/// Read the entire contents of the file at `path`.
fn read_to_end(
&self,
path: &Path,
) -> Pin<Box<dyn Future<Output = std::io::Result<Vec<u8>>> + Send + '_>>;

/// Write `contents` to the file at `path`.
fn write(
&self,
path: &Path,
contents: &[u8],
) -> Pin<Box<dyn Future<Output = std::io::Result<()>> + Send + '_>>;
}

/// File system abstraction
///
/// Simple abstraction enabling in-memory mocking of the file system
Expand Down Expand Up @@ -75,11 +50,6 @@ impl Fs {
Fs(fs::Inner::Real)
}

/// Create an `Fs` backed by a custom `ProvideFs` implementation.
pub fn from_custom(provider: impl ProvideFs + 'static) -> Self {
Self(fs::Inner::Custom(Arc::new(provider)))
}

/// Create `Fs` from a map of `OsString` to `Vec<u8>`.
pub fn from_raw_map(fs: HashMap<OsString, Vec<u8>>) -> Self {
Fs(fs::Inner::Fake(Arc::new(Fake::MapFs(Mutex::new(fs)))))
Expand Down Expand Up @@ -177,7 +147,6 @@ impl Fs {
std::fs::read(real_path.join(actual_path))
}
},
Inner::Custom(provider) => provider.read_to_end(path).await,
}
}

Expand Down Expand Up @@ -218,9 +187,6 @@ impl Fs {
std::fs::write(real_path.join(actual_path), contents)?;
}
},
Inner::Custom(provider) => {
return provider.write(path.as_ref(), contents.as_ref()).await
}
}
Ok(())
}
Expand All @@ -232,13 +198,10 @@ mod fs {
use std::path::PathBuf;
use std::sync::{Arc, Mutex};

use super::ProvideFs;

#[derive(Clone, Debug)]
pub(super) enum Inner {
Real,
Fake(Arc<Fake>),
Custom(Arc<dyn ProvideFs>),
}

#[derive(Debug)]
Expand Down Expand Up @@ -276,7 +239,6 @@ impl Env {
match &self.0 {
Inner::Real => std::env::var(k),
Inner::Fake(map) => map.get(k).cloned().ok_or(VarError::NotPresent),
Inner::Custom(provider) => provider.get(k),
}
}

Expand Down Expand Up @@ -305,11 +267,6 @@ impl Env {
pub fn real() -> Self {
Self(env::Inner::Real)
}

/// Create an `Env` backed by a custom `ProvideEnv` implementation.
pub fn from_custom(provider: impl ProvideEnv + 'static) -> Self {
Self(env::Inner::Custom(Arc::new(provider)))
}
}

impl From<HashMap<String, String>> for Env {
Expand All @@ -322,26 +279,18 @@ mod env {
use std::collections::HashMap;
use std::sync::Arc;

use super::ProvideEnv;

#[derive(Clone, Debug)]
pub(super) enum Inner {
Real,
Fake(Arc<HashMap<String, String>>),
Custom(Arc<dyn ProvideEnv>),
}
}

#[cfg(test)]
mod test {
use std::collections::HashMap;
use std::env::VarError;
use std::future::Future;
use std::path::{Path, PathBuf};
use std::pin::Pin;
use std::sync::Mutex;

use crate::os_shim_internal::{Env, Fs, ProvideEnv, ProvideFs};
use crate::os_shim_internal::{Env, Fs};

#[test]
fn env_works() {
Expand Down Expand Up @@ -383,83 +332,6 @@ mod test {
assert_eq!(b"test", &result[..]);
}

#[test]
fn custom_env_works() {
#[derive(Debug)]
struct CustomEnvProvider {
vars: HashMap<String, String>,
}

impl ProvideEnv for CustomEnvProvider {
fn get(&self, k: &str) -> Result<String, VarError> {
self.vars.get(k).cloned().ok_or(VarError::NotPresent)
}
}

let mut vars = HashMap::new();
vars.insert("FOO".to_string(), "BAR".to_string());
let env = Env::from_custom(CustomEnvProvider { vars });
assert_eq!(env.get("FOO").unwrap(), "BAR");
assert_eq!(
env.get("OTHER").expect_err("not present"),
VarError::NotPresent
);
}

#[tokio::test]
async fn custom_fs_round_trip() {
#[derive(Debug)]
struct InMemoryFs {
files: Mutex<HashMap<PathBuf, Vec<u8>>>,
}

impl ProvideFs for InMemoryFs {
fn read_to_end(
&self,
path: &Path,
) -> Pin<Box<dyn Future<Output = std::io::Result<Vec<u8>>> + Send + '_>> {
let path = path.to_path_buf();
Box::pin(async move {
self.files
.lock()
.unwrap()
.get(&path)
.cloned()
.ok_or_else(|| std::io::ErrorKind::NotFound.into())
})
}

fn write(
&self,
path: &Path,
contents: &[u8],
) -> Pin<Box<dyn Future<Output = std::io::Result<()>> + Send + '_>> {
let path = path.to_path_buf();
let contents = contents.to_vec();
Box::pin(async move {
self.files.lock().unwrap().insert(path, contents);
Ok(())
})
}
}

let provider = InMemoryFs {
files: Mutex::new(HashMap::new()),
};
let fs = Fs::from_custom(provider);

fs.read_to_end("/missing")
.await
.expect_err("file doesn't exist yet");

fs.write("/test-file", b"hello")
.await
.expect("write succeeds");

let result = fs.read_to_end("/test-file").await.expect("read succeeds");
assert_eq!(result, b"hello");
}

#[cfg(unix)]
#[tokio::test]
async fn real_fs_write_sets_owner_only_permissions_on_unix() {
Expand Down
Loading