Skip to content

Commit

Permalink
feat: add dynamodb-local module (#2799)
Browse files Browse the repository at this point in the history
* feat: add dynamodb-local module

* docs: fix

* fix: remove module from CI

* fix: wrongly generated

* chore: bump dockercfg

* chore: wrap errors

* Revert "chore: wrap errors"

This reverts commit 93a9d01.

* fix: remove unused constant

* chore: wrap errors

* chore: simplify helper methods

* chore: wrap methods

* fix: partially revert helpers as we need to check for errors in the caller

* chore: wrap error

* chore: simplify variable

Co-authored-by: Steven Hartland <stevenmhartland@gmail.com>

* fixlint

* chore: pass testing.T

---------

Co-authored-by: Steven Hartland <stevenmhartland@gmail.com>
  • Loading branch information
mdelapenya and stevenh authored Sep 30, 2024
1 parent 9562594 commit 7a1419d
Show file tree
Hide file tree
Showing 11 changed files with 781 additions and 2 deletions.
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
90 changes: 90 additions & 0 deletions modules/dynamodb/dynamodb.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package dynamodb

import (
"context"
"fmt"

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

const (
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) {
mappedPort, err := c.MappedPort(ctx, port)
if err != nil {
return "", err
}

hostIP, err := c.Host(ctx)
if err != nil {
return "", err
}

return hostIP + ":" + mappedPort.Port(), nil
}

// 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

0 comments on commit 7a1419d

Please sign in to comment.