Skip to content
Open
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
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ dynamodb = []
databend = ["http_wait"]
elastic_search = []
elasticmq = []
fakecloud = []
gitea = ["http_wait", "dep:rcgen"]
google_cloud_sdk_emulators = []
hashicorp_vault = ["http_wait"]
Expand Down Expand Up @@ -198,3 +199,7 @@ required-features = ["azurite"]
[[example]]
name = "selenium"
required-features = ["selenium"]

[[example]]
name = "fakecloud"
required-features = ["fakecloud"]
28 changes: 28 additions & 0 deletions examples/fakecloud.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use testcontainers_modules::{
fakecloud::{FakeCloud, FAKECLOUD_PORT},
testcontainers::runners::AsyncRunner,
};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + 'static>> {
let _ = pretty_env_logger::try_init();

let node = FakeCloud::default().start().await?;
let host_ip = node.get_host().await?;
let host_port = node.get_host_port_ipv4(FAKECLOUD_PORT).await?;

println!("fakecloud running at http://{}:{}", host_ip, host_port);

let client = reqwest::Client::new();
let response = client
.get(format!(
"http://{}:{}/_fakecloud/health",
host_ip, host_port
))
.send()
.await?;

println!("Health check: {}", response.text().await?);

Ok(())
}
83 changes: 83 additions & 0 deletions src/fakecloud/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
use testcontainers::{core::WaitFor, Image};

/// Container port for the fakecloud HTTP API.
pub const FAKECLOUD_PORT: u16 = 4566;

const NAME: &str = "ghcr.io/faiscadev/fakecloud";
const TAG: &str = "0.4.0";

/// [fakecloud](https://fakecloud.dev) is a free, open-source local AWS cloud emulator.
///
/// Supports S3, SQS, SNS, EventBridge, IAM/STS, SSM, DynamoDB, Lambda,
/// Secrets Manager, CloudWatch Logs, KMS, SES, and CloudFormation.
///
/// Currently pinned to [version `0.4.0`](https://github.com/faiscadev/fakecloud/releases/tag/v0.4.0).
///
/// # Configuration
///
/// fakecloud uses environment variables for configuration. See the
/// [documentation](https://fakecloud.dev) for the full list.
///
/// ```
/// use testcontainers_modules::{fakecloud::FakeCloud, testcontainers::ImageExt};
///
/// let container_request = FakeCloud::default().with_env_var("FAKECLOUD_LOG", "debug");
/// ```
///
/// No environment variables are required.
#[derive(Default, Debug, Clone)]
pub struct FakeCloud {
_priv: (),
}

impl Image for FakeCloud {
fn name(&self) -> &str {
NAME
}

fn tag(&self) -> &str {
TAG
}

fn ready_conditions(&self) -> Vec<WaitFor> {
vec![WaitFor::message_on_stdout("fakecloud is ready")]
}
}

#[cfg(test)]
mod tests {
use aws_config::{meta::region::RegionProviderChain, BehaviorVersion};
use aws_sdk_sqs as sqs;
use testcontainers::runners::AsyncRunner;

use super::FakeCloud;

#[tokio::test]
#[allow(clippy::result_large_err)]
async fn create_and_list_queue() -> Result<(), Box<dyn std::error::Error + 'static>> {
let node = FakeCloud::default().start().await?;
let host_ip = node.get_host().await?;
let host_port = node.get_host_port_ipv4(4566).await?;

let region_provider = RegionProviderChain::default_provider().or_else("us-east-1");
let creds = sqs::config::Credentials::new("test", "test", None, None, "test");
let config = aws_config::defaults(BehaviorVersion::v2025_08_07())
.region(region_provider)
.credentials_provider(creds)
.endpoint_url(format!("http://{host_ip}:{host_port}"))
.load()
.await;
let client = sqs::Client::new(&config);

client
.create_queue()
.queue_name("example-queue")
.send()
.await?;

let list_result = client.list_queues().send().await?;
assert_eq!(list_result.queue_urls().len(), 1);

Ok(())
}
}
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ pub mod elastic_search;
#[cfg_attr(docsrs, doc(cfg(feature = "elasticmq")))]
/// **ElasticMQ** (message queue) testcontainer
pub mod elasticmq;
#[cfg(feature = "fakecloud")]
#[cfg_attr(docsrs, doc(cfg(feature = "fakecloud")))]
/// **fakecloud** (local AWS cloud emulator) testcontainer
pub mod fakecloud;
#[cfg(feature = "gitea")]
#[cfg_attr(docsrs, doc(cfg(feature = "gitea")))]
/// **Gitea** (self-hosted Git service) testcontainer
Expand Down