Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
1 change: 1 addition & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ updates:
- /examples/nginx
- /examples/toxiproxy
- /modulegen
- /modules/arangodb
- /modules/artemis
- /modules/azure
- /modules/azurite
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 @@ -13,6 +13,10 @@
"name": "example / toxiproxy",
"path": "../examples/toxiproxy"
},
{
"name": "module / arangodb",
"path": "../modules/arangodb"
},
{
"name": "module / artemis",
"path": "../modules/artemis"
Expand Down
74 changes: 74 additions & 0 deletions docs/modules/arangodb.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# ArangoDB

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 ArangoDB.

## Adding this module to your project dependencies

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

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

## Usage example

<!--codeinclude-->
[Creating a ArangoDB container](../../modules/arangodb/examples_test.go) inside_block:ExampleRun
<!--/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 ArangoDB module exposes one entrypoint function to create the ArangoDB container, and this function receives three parameters:

```golang
func Run(ctx context.Context, img string, opts ...testcontainers.ContainerCustomizer) (*ArangoDBContainer, 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 ArangoDB container, you can pass options in a variadic way to configure it.

#### Image

Use the second argument in the `Run` function to set a valid Docker image.
In example: `Run(context.Background(), "arangodb:3.11.5")`.

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

#### WithRootPassword

- 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 `WithRootPassword` function sets the root password for the ArangoDB container.

### Container Methods

The ArangoDB container exposes the following methods:

#### Credentials

- 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 `Credentials` method returns the credentials for the ArangoDB container, in the form of a tuple of two strings: the username and the password.

```golang
func (c *Container) Credentials() (string, string)
```

#### TransportAddress

- 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 `TransportAddress` method returns the transport address of the ArangoDB container, using the following format: `http://$host:$port`.
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ nav:
- Walk: features/wait/walk.md
- Modules:
- modules/index.md
- modules/arangodb.md
- modules/artemis.md
- modules/azure.md
- modules/azurite.md
Expand Down
5 changes: 5 additions & 0 deletions modules/arangodb/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
include ../../commons-test.mk

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

import (
"context"
"fmt"
"net/http"

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

const (
defaultPort = "8529/tcp"

// DefaultUser is the default username for the ArangoDB container.
// This is the username to be used when connecting to the ArangoDB instance.
DefaultUser = "root"

defaultPassword = "root"
)

// Container represents the ArangoDB container type used in the module
type Container struct {
testcontainers.Container
password string
}

// Credentials returns the credentials for the ArangoDB container:
// first return value is the username, second is the password.
func (c *Container) Credentials() (string, string) {
return DefaultUser, c.password
}

// HTTPEndpoint returns the transport address of the ArangoDB container
func (c *Container) HTTPEndpoint(ctx context.Context) (string, error) {
hostPort, err := c.PortEndpoint(ctx, defaultPort, "http")
if err != nil {
return "", fmt.Errorf("port endpoint: %w", err)
}

return hostPort, nil
}

// Run creates an instance of the ArangoDB container type
func Run(ctx context.Context, img string, opts ...testcontainers.ContainerCustomizer) (*Container, error) {
req := testcontainers.ContainerRequest{
Image: img,
ExposedPorts: []string{defaultPort},
Env: map[string]string{
"ARANGO_ROOT_PASSWORD": defaultPassword,
},
}

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)
}
}

// Wait for the container to be ready once we know the credentials
genericContainerReq.WaitingFor = wait.ForAll(
wait.ForListeningPort(defaultPort),
wait.ForHTTP("/_admin/status").
WithPort(defaultPort).
WithBasicAuth(DefaultUser, req.Env["ARANGO_ROOT_PASSWORD"]).
WithHeaders(map[string]string{
"Accept": "application/json",
}).
WithStatusCodeMatcher(func(status int) bool {
return status == http.StatusOK
}),
)

container, err := testcontainers.GenericContainer(ctx, genericContainerReq)
var c *Container
if container != nil {
c = &Container{Container: container, password: req.Env["ARANGO_ROOT_PASSWORD"]}
}

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

return c, nil
}
39 changes: 39 additions & 0 deletions modules/arangodb/arangodb_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package arangodb_test

import (
"context"
"testing"

"github.com/arangodb/go-driver/v2/arangodb"
"github.com/arangodb/go-driver/v2/connection"
"github.com/stretchr/testify/require"

"github.com/testcontainers/testcontainers-go"
tcarangodb "github.com/testcontainers/testcontainers-go/modules/arangodb"
)

func TestArangoDB(t *testing.T) {
ctx := context.Background()

const password = "t3stc0ntain3rs!"

ctr, err := tcarangodb.Run(ctx, "arangodb:3.11.5", tcarangodb.WithRootPassword(password))
testcontainers.CleanupContainer(t, ctr)
require.NoError(t, err)

httpAddress, err := ctr.HTTPEndpoint(ctx)
require.NoError(t, err)

endpoint := connection.NewRoundRobinEndpoints([]string{httpAddress})
conn := connection.NewHttp2Connection(connection.DefaultHTTP2ConfigurationWrapper(endpoint, true))

auth := connection.NewBasicAuth(ctr.Credentials())
err = conn.SetAuthentication(auth)
require.NoError(t, err)

client := arangodb.NewClient(conn)

versionInfo, err := client.Version(context.Background())
require.NoError(t, err)
require.Equal(t, "arango", versionInfo.Server)
}
96 changes: 96 additions & 0 deletions modules/arangodb/examples_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package arangodb_test

import (
"context"
"fmt"
"log"

"github.com/arangodb/go-driver/v2/arangodb"
"github.com/arangodb/go-driver/v2/connection"

"github.com/testcontainers/testcontainers-go"
tcarangodb "github.com/testcontainers/testcontainers-go/modules/arangodb"
)

func ExampleRun() {
ctx := context.Background()

const password = "t3stc0ntain3rs!"

arangodbContainer, err := tcarangodb.Run(ctx, "arangodb:3.11.5", tcarangodb.WithRootPassword(password))
defer func() {
if err := testcontainers.TerminateContainer(arangodbContainer); err != nil {
log.Printf("failed to terminate container: %s", err)
}
}()
if err != nil {
log.Printf("failed to start container: %s", err)
return
}
// }

state, err := arangodbContainer.State(ctx)
if err != nil {
log.Printf("failed to get container state: %s", err)
return
}

fmt.Println(state.Running)

// Output:
// true
}

func ExampleRun_usingClient() {
ctx := context.Background()

const password = "t3stc0ntain3rs!"

arangodbContainer, err := tcarangodb.Run(
ctx, "arangodb:3.11.5",
tcarangodb.WithRootPassword(password),
)
defer func() {
if err := testcontainers.TerminateContainer(arangodbContainer); err != nil {
log.Printf("failed to terminate container: %s", err)
}
}()
if err != nil {
log.Printf("failed to start container: %s", err)
return
}
// }

httpAddress, err := arangodbContainer.HTTPEndpoint(ctx)
if err != nil {
log.Printf("failed to get transport address: %s", err)
return
}

// Create an HTTP connection to the database
endpoint := connection.NewRoundRobinEndpoints([]string{httpAddress})
conn := connection.NewHttp2Connection(connection.DefaultHTTP2ConfigurationWrapper(endpoint, true))

// Add authentication
auth := connection.NewBasicAuth(arangodbContainer.Credentials())
err = conn.SetAuthentication(auth)
if err != nil {
log.Printf("Failed to set authentication: %v", err)
return
}

// Create a client
client := arangodb.NewClient(conn)

// Ask the version of the server
versionInfo, err := client.Version(context.Background())
if err != nil {
log.Printf("Failed to get version info: %v", err)
return
}

fmt.Println(versionInfo.Server)

// Output:
// arango
}
Loading
Loading