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#[allow(missing_docs)]
8#[derive(Default, Debug, Clone)]
10pub struct DynamoDb {
11 _priv: (),
15}
16
17impl Image for DynamoDb {
18 fn name(&self) -> &str {
19 NAME
20 }
21
22 fn tag(&self) -> &str {
23 TAG
24 }
25
26 fn ready_conditions(&self) -> Vec<WaitFor> {
27 vec![
28 WaitFor::message_on_stdout(
29 "Initializing DynamoDB Local with the following configuration",
30 ),
31 WaitFor::millis(DEFAULT_WAIT),
32 ]
33 }
34}
35
36#[cfg(test)]
37mod tests {
38 use std::fmt::Display;
39
40 use aws_config::{meta::region::RegionProviderChain, BehaviorVersion};
41 use aws_sdk_dynamodb::{
42 config::Credentials,
43 types::{
44 AttributeDefinition, KeySchemaElement, KeyType, ProvisionedThroughput,
45 ScalarAttributeType,
46 },
47 Client,
48 };
49 use testcontainers::core::IntoContainerPort;
50
51 use crate::{dynamodb_local::DynamoDb, testcontainers::runners::AsyncRunner};
52
53 #[tokio::test]
54 async fn dynamodb_local_create_table() -> Result<(), Box<dyn std::error::Error + 'static>> {
55 let _ = pretty_env_logger::try_init();
56 let node = DynamoDb::default().start().await?;
57 let host = node.get_host().await?;
58 let host_port = node.get_host_port_ipv4(8000.tcp()).await?;
59
60 let table_name = "books".to_string();
61
62 let key_schema = KeySchemaElement::builder()
63 .attribute_name("title".to_string())
64 .key_type(KeyType::Hash)
65 .build()
66 .unwrap();
67
68 let attribute_def = AttributeDefinition::builder()
69 .attribute_name("title".to_string())
70 .attribute_type(ScalarAttributeType::S)
71 .build()
72 .unwrap();
73
74 let provisioned_throughput = ProvisionedThroughput::builder()
75 .read_capacity_units(10)
76 .write_capacity_units(5)
77 .build()
78 .unwrap();
79
80 let dynamodb = build_dynamodb_client(host, host_port).await;
81 let create_table_result = dynamodb
82 .create_table()
83 .table_name(table_name)
84 .key_schema(key_schema)
85 .attribute_definitions(attribute_def)
86 .provisioned_throughput(provisioned_throughput)
87 .send()
88 .await;
89 assert!(create_table_result.is_ok());
90
91 let req = dynamodb.list_tables().limit(10);
92 let list_tables_result = req.send().await.unwrap();
93
94 assert_eq!(list_tables_result.table_names().len(), 1);
95 Ok(())
96 }
97
98 async fn build_dynamodb_client(host: impl Display, host_port: u16) -> Client {
99 let endpoint_uri = format!("http://{host}:{host_port}");
100 let region_provider = RegionProviderChain::default_provider().or_else("us-east-1");
101 let creds = Credentials::new("fakeKey", "fakeSecret", None, None, "test");
102
103 let shared_config = aws_config::defaults(BehaviorVersion::latest())
104 .region(region_provider)
105 .endpoint_url(endpoint_uri)
106 .credentials_provider(creds)
107 .load()
108 .await;
109
110 Client::new(&shared_config)
111 }
112}