testcontainers_modules/dynamodb_local/
mod.rs1use testcontainers::{core::WaitFor, Image};
2
3const NAME: &str = "amazon/dynamodb-local";
4const TAG: &str = "2.0.0";
5const DEFAULT_WAIT: u64 = 3000;
6
7#[derive(Default, Debug, Clone)]
32pub struct DynamoDb {
33 _priv: (),
37}
38
39impl Image for DynamoDb {
40 fn name(&self) -> &str {
41 NAME
42 }
43
44 fn tag(&self) -> &str {
45 TAG
46 }
47
48 fn ready_conditions(&self) -> Vec<WaitFor> {
49 vec![
50 WaitFor::message_on_stdout(
51 "Initializing DynamoDB Local with the following configuration",
52 ),
53 WaitFor::millis(DEFAULT_WAIT),
54 ]
55 }
56}
57
58#[cfg(test)]
59mod tests {
60 use std::fmt::Display;
61
62 use aws_config::{meta::region::RegionProviderChain, BehaviorVersion};
63 use aws_sdk_dynamodb::{
64 config::Credentials,
65 types::{
66 AttributeDefinition, KeySchemaElement, KeyType, ProvisionedThroughput,
67 ScalarAttributeType,
68 },
69 Client,
70 };
71 use testcontainers::core::IntoContainerPort;
72
73 use crate::{dynamodb_local::DynamoDb, testcontainers::runners::AsyncRunner};
74
75 #[tokio::test]
76 async fn dynamodb_local_create_table() -> Result<(), Box<dyn std::error::Error + 'static>> {
77 let _ = pretty_env_logger::try_init();
78 let node = DynamoDb::default().start().await?;
79 let host = node.get_host().await?;
80 let host_port = node.get_host_port_ipv4(8000.tcp()).await?;
81
82 let table_name = "books".to_string();
83
84 let key_schema = KeySchemaElement::builder()
85 .attribute_name("title".to_string())
86 .key_type(KeyType::Hash)
87 .build()
88 .unwrap();
89
90 let attribute_def = AttributeDefinition::builder()
91 .attribute_name("title".to_string())
92 .attribute_type(ScalarAttributeType::S)
93 .build()
94 .unwrap();
95
96 let provisioned_throughput = ProvisionedThroughput::builder()
97 .read_capacity_units(10)
98 .write_capacity_units(5)
99 .build()
100 .unwrap();
101
102 let dynamodb = build_dynamodb_client(host, host_port).await;
103 let create_table_result = dynamodb
104 .create_table()
105 .table_name(table_name)
106 .key_schema(key_schema)
107 .attribute_definitions(attribute_def)
108 .provisioned_throughput(provisioned_throughput)
109 .send()
110 .await;
111 assert!(create_table_result.is_ok());
112
113 let req = dynamodb.list_tables().limit(10);
114 let list_tables_result = req.send().await.unwrap();
115
116 assert_eq!(list_tables_result.table_names().len(), 1);
117 Ok(())
118 }
119
120 async fn build_dynamodb_client(host: impl Display, host_port: u16) -> Client {
121 let endpoint_uri = format!("http://{host}:{host_port}");
122 let region_provider = RegionProviderChain::default_provider().or_else("us-east-1");
123 let creds = Credentials::new("fakeKey", "fakeSecret", None, None, "test");
124
125 let shared_config = aws_config::defaults(BehaviorVersion::latest())
126 .region(region_provider)
127 .endpoint_url(endpoint_uri)
128 .credentials_provider(creds)
129 .load()
130 .await;
131
132 Client::new(&shared_config)
133 }
134}