Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add dynamodb-local module #2799

Merged
merged 18 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from 8 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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ jobs:
matrix:
go-version: [1.22.x, 1.x]
platform: [ubuntu-latest]
module: [artemis, azurite, cassandra, chroma, clickhouse, cockroachdb, compose, consul, couchbase, databend, dolt, elasticsearch, gcloud, grafana-lgtm, inbucket, influxdb, k3s, k6, kafka, localstack, mariadb, milvus, minio, mockserver, mongodb, mssql, mysql, nats, neo4j, ollama, openfga, openldap, opensearch, postgres, pulsar, qdrant, rabbitmq, redis, redpanda, registry, surrealdb, valkey, vault, vearch, weaviate]
module: [artemis, azurite, cassandra, chroma, clickhouse, cockroachdb, compose, consul, couchbase, databend, dolt, dynamodb, elasticsearch, gcloud, grafana-lgtm, inbucket, influxdb, k3s, k6, kafka, localstack, mariadb, milvus, minio, mockserver, mongodb, mssql, mysql, nats, neo4j, ollama, openfga, openldap, opensearch, postgres, pulsar, qdrant, rabbitmq, redis, redpanda, registry, surrealdb, valkey, vault, vearch, weaviate]
uses: ./.github/workflows/ci-test-go.yml
with:
go-version: ${{ matrix.go-version }}
Expand Down
4 changes: 4 additions & 0 deletions .vscode/.testcontainers-go.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@
"name": "module / dolt",
"path": "../modules/dolt"
},
{
"name": "module / dynamodb",
"path": "../modules/dynamodb"
},
{
"name": "module / elasticsearch",
"path": "../modules/elasticsearch"
Expand Down
77 changes: 77 additions & 0 deletions docs/modules/dynamodb.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# DynamoDB

Not available until the next release of testcontainers-go <a href="https://github.com/testcontainers/testcontainers-go"><span class="tc-version">:material-tag: main</span></a>

## Introduction

The Testcontainers module for DynamoDB.

## Adding this module to your project dependencies

Please run the following command to add the DynamoDB module to your Go dependencies:

```
go get github.com/testcontainers/testcontainers-go/modules/dynamodb
```

## Usage example

<!--codeinclude-->
[Creating a DynamoDB container](../../modules/dynamodb/examples_test.go) inside_block:runDynamoDBContainer
<!--/codeinclude-->

## Module Reference

### Run function

- Not available until the next release of testcontainers-go <a href="https://github.com/testcontainers/testcontainers-go"><span class="tc-version">:material-tag: main</span></a>

The DynamoDB module exposes one entrypoint function to create the DynamoDB container, and this function receives three parameters:

```golang
func Run(ctx context.Context, img string, opts ...testcontainers.ContainerCustomizer) (*DynamoDBContainer, error)
```

- `context.Context`, the Go context.
- `string`, the Docker image to use.
- `testcontainers.ContainerCustomizer`, a variadic argument for passing options.

### Container Options

When starting the DynamoDB container, you can pass options in a variadic way to configure it.

#### Image

If you need to set a different DynamoDB Docker image, you can set a valid Docker image as the second argument in the `Run` function.
E.g. `Run(context.Background(), "amazon/dynamodb-local:2.2.1")`.

{% include "../features/common_functional_options.md" %}

#### WithSharedDB

- Not available until the next release of testcontainers-go <a href="https://github.com/testcontainers/testcontainers-go"><span class="tc-version">:material-tag: main</span></a>

The `WithSharedDB` option tells the DynamoDB container to use a single database file. At the same time, it marks the container as reusable, which causes that successive calls to the `Run` function will return the same container instance, and therefore, the same database file.

#### WithDisableTelemetry

- Not available until the next release of testcontainers-go <a href="https://github.com/testcontainers/testcontainers-go"><span class="tc-version">:material-tag: main</span></a>

You can turn off telemetry when starting the DynamoDB container, using the option `WithDisableTelemetry`.

### Container Methods

The DynamoDB container exposes the following methods:

#### ConnectionString

- Not available until the next release of testcontainers-go <a href="https://github.com/testcontainers/testcontainers-go"><span class="tc-version">:material-tag: main</span></a>

The `ConnectionString` method returns the connection string to the DynamoDB container. This connection string can be used to connect to the DynamoDB container from your application,
using the AWS SDK or any other DynamoDB client of your choice.

<!--codeinclude-->
[Creating a client](../../modules/dynamodb/dynamodb_test.go) inside_block:createClient
<!--/codeinclude-->

The above example uses `github.com/aws/aws-sdk-go-v2/service/dynamodb` to create a client and connect to the DynamoDB container.
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ nav:
- modules/couchbase.md
- modules/databend.md
- modules/dolt.md
- modules/dynamodb.md
- modules/elasticsearch.md
- modules/gcloud.md
- modules/grafana-lgtm.md
Expand Down
5 changes: 5 additions & 0 deletions modules/dynamodb/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
include ../../commons-test.mk

.PHONY: test
test:
$(MAKE) test-dynamodb
95 changes: 95 additions & 0 deletions modules/dynamodb/dynamodb.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package dynamodb

import (
"context"
"errors"
"fmt"

"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/wait"
)

const (
image = "amazon/dynamodb-local:2.2.1"
mdelapenya marked this conversation as resolved.
Show resolved Hide resolved
port = "8000/tcp"
containerName = "tc_dynamodb_local"
)

// DynamoDBContainer represents the DynamoDB container type used in the module
type DynamoDBContainer struct {
testcontainers.Container
}

// Run creates an instance of the DynamoDB container type
func Run(ctx context.Context, img string, opts ...testcontainers.ContainerCustomizer) (*DynamoDBContainer, error) {
req := testcontainers.ContainerRequest{
Image: img,
ExposedPorts: []string{string(port)},
Entrypoint: []string{"java", "-Djava.library.path=./DynamoDBLocal_lib"},
Cmd: []string{"-jar", "DynamoDBLocal.jar"},
WaitingFor: wait.ForListeningPort(port),
}

genericContainerReq := testcontainers.GenericContainerRequest{
ContainerRequest: req,
Started: true,
}

for _, opt := range opts {
if err := opt.Customize(&genericContainerReq); err != nil {
return nil, fmt.Errorf("customize: %w", err)
}
}

container, err := testcontainers.GenericContainer(ctx, genericContainerReq)
var c *DynamoDBContainer
if container != nil {
c = &DynamoDBContainer{Container: container}
}

if err != nil {
return c, fmt.Errorf("generic container: %w", err)
}

return c, nil
}

// ConnectionString returns DynamoDB local endpoint host and port in <host>:<port> format
func (c *DynamoDBContainer) ConnectionString(ctx context.Context) (string, error) {
var errs []error
mdelapenya marked this conversation as resolved.
Show resolved Hide resolved

mappedPort, err := c.MappedPort(ctx, port)
if err != nil {
errs = append(errs, fmt.Errorf("mapped port: %w", err))
}

hostIP, err := c.Host(ctx)
if err != nil {
errs = append(errs, fmt.Errorf("host: %w", err))
}

uri := fmt.Sprintf("%s:%s", hostIP, mappedPort.Port())
return uri, errors.Join(errs...)
}

// WithSharedDB allows container reuse between successive runs. Data will be persisted
func WithSharedDB() testcontainers.CustomizeRequestOption {
return func(req *testcontainers.GenericContainerRequest) error {
req.Cmd = append(req.Cmd, "-sharedDb")

req.Reuse = true
req.Name = containerName

return nil
}
}

// WithDisableTelemetry - DynamoDB local will not send any telemetry
func WithDisableTelemetry() testcontainers.CustomizeRequestOption {
return func(req *testcontainers.GenericContainerRequest) error {
// if other flags (e.g. -sharedDb) exist, append to them
req.Cmd = append(req.Cmd, "-disableTelemetry")

return nil
}
}
Loading