Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/go_modules/modules/compose/github…
Browse files Browse the repository at this point in the history
….com/docker/compose/v2-2.16.0
  • Loading branch information
mdelapenya authored Feb 15, 2023
2 parents b28a0c7 + 73750c5 commit fef3cd5
Show file tree
Hide file tree
Showing 100 changed files with 2,187 additions and 438 deletions.
12 changes: 12 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,24 @@ updates:
interval: weekly
open-pull-requests-limit: 3
rebase-strategy: disabled
- package-ecosystem: gomod
directory: /modulegen
schedule:
interval: weekly
open-pull-requests-limit: 3
rebase-strategy: disabled
- package-ecosystem: gomod
directory: /modules/compose
schedule:
interval: weekly
open-pull-requests-limit: 3
rebase-strategy: disabled
- package-ecosystem: gomod
directory: /modules/localstack
schedule:
interval: weekly
open-pull-requests-limit: 3
rebase-strategy: disabled
- package-ecosystem: gomod
directory: /examples/bigtable
schedule:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ jobs:
if: ${{ matrix.platform == 'ubuntu-latest' }}
run: make test-unit

- name: Run example generator tests
- name: Run module generator tests
if: ${{ matrix.platform == 'ubuntu-latest' }}
run: make -C examples test-unit
run: make -C modulegen test-unit

- name: Run checker
run: |
Expand Down
46 changes: 46 additions & 0 deletions .github/workflows/module-localstack.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: LocalStack module pipeline

on: [push, pull_request]

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.sha }}
cancel-in-progress: true

jobs:
test-localstack:
strategy:
matrix:
go-version: [1.18.x, 1.x]
runs-on: "ubuntu-latest"
steps:

- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
id: go

- name: Check out code into the Go module directory
uses: actions/checkout@v3

- name: modVerify
working-directory: ./modules/localstack
run: go mod verify

- name: modTidy
working-directory: ./modules/localstack
run: make tools-tidy

- name: gotestsum
working-directory: ./modules/localstack
run: make test-unit

- name: Run checker
run: |
./scripts/check_environment.sh
- name: Test Summary
uses: test-summary/action@4ee9ece4bca777a38f05c8fc578ac2007fe266f7
with:
paths: "**/TEST-localstack*.xml"
if: always()
8 changes: 8 additions & 0 deletions container.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"io"
"path/filepath"
"time"

"github.com/docker/docker/api/types"
Expand Down Expand Up @@ -234,6 +235,13 @@ func (c *ContainerRequest) GetContext() (io.Reader, error) {
return c.ContextArchive, nil
}

// always pass context as absolute path
abs, err := filepath.Abs(c.Context)
if err != nil {
return nil, fmt.Errorf("error getting absolute path: %w", err)
}
c.Context = abs

buildContext, err := archive.TarWithOptions(c.Context, &archive.TarOptions{})
if err != nil {
return nil, err
Expand Down
27 changes: 21 additions & 6 deletions docker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2022,18 +2022,20 @@ func TestDockerContainerCopyDirToContainer(t *testing.T) {
Started: true,
})

p := filepath.Join(".", "testresources", "Dokerfile")
require.NoError(t, err)
terminateContainerOnEnd(t, ctx, nginxC)

err = nginxC.CopyDirToContainer(ctx, "./testresources/Dockerfile", "/tmp/testresources/Dockerfile", 700)
err = nginxC.CopyDirToContainer(ctx, p, "/tmp/testresources/Dockerfile", 700)
require.Error(t, err) // copying a file using the directory method will raise an error

err = nginxC.CopyDirToContainer(ctx, "./testresources", "/tmp/testresources", 700)
p = filepath.Join(".", "testresources")
err = nginxC.CopyDirToContainer(ctx, p, "/tmp/testresources", 700)
if err != nil {
t.Fatal(err)
}

assertExtractedFiles(t, ctx, nginxC, "./testresources", "/tmp/testresources/")
assertExtractedFiles(t, ctx, nginxC, p, "/tmp/testresources/")
}

func TestDockerCreateContainerWithFiles(t *testing.T) {
Expand Down Expand Up @@ -2109,15 +2111,27 @@ func TestDockerCreateContainerWithDirs(t *testing.T) {
ctx := context.Background()
hostDirName := "testresources"

abs, err := filepath.Abs(filepath.Join(".", hostDirName))
assert.Nil(t, err)

tests := []struct {
name string
dir ContainerFile
hasError bool
}{
{
name: "success copy directory with full path",
dir: ContainerFile{
HostFilePath: abs,
ContainerFilePath: "/tmp/" + hostDirName, // the parent dir must exist
FileMode: 700,
},
hasError: false,
},
{
name: "success copy directory",
dir: ContainerFile{
HostFilePath: "./" + hostDirName,
HostFilePath: filepath.Join("./", hostDirName),
ContainerFilePath: "/tmp/" + hostDirName, // the parent dir must exist
FileMode: 700,
},
Expand Down Expand Up @@ -2561,10 +2575,11 @@ func assertExtractedFiles(t *testing.T, ctx context.Context, container Container
require.NoError(t, err)
}

fp := filepath.Join(containerFilePath, srcFile.Name())
// copy file by file, as there is a limitation in the Docker client to copy an entiry directory from the container
// paths for the container files are using Linux path separators
fd, err := container.CopyFileFromContainer(ctx, containerFilePath+"/"+srcFile.Name())
require.NoError(t, err, "Path not found in container: %s", containerFilePath+"/"+srcFile.Name())
fd, err := container.CopyFileFromContainer(ctx, fp)
require.NoError(t, err, "Path not found in container: %s", fp)
defer fd.Close()

targetPath := filepath.Join(tmpDir, srcFile.Name())
Expand Down
38 changes: 4 additions & 34 deletions docs/examples/index.md
Original file line number Diff line number Diff line change
@@ -1,42 +1,12 @@
# Code examples

In this section you'll discover how to create code examples for _Testcontainers for Go_.
In this section you'll discover how to create code examples for _Testcontainers for Go_, which are almost the same as Go modules, but without exporting any public API.

## Interested in adding a new example?

We have provided a command line tool to generate the scaffolding for the code of the example you are interested in. This tool will generate:

- a Go module for the example, including:
- go.mod and go.sum files, including the current version of _Testcontainer for Go_.
- a Go package named after the example, in lowercase
- a Go file for the creation of the container, using a dedicated struct in which the image flag is set as Docker image.
- a Go test file for running a simple test for your container, consuming the above struct.
- a Makefile to run the tests in a consistent manner
- a tools.go file including the build tools (i.e. `gotestsum`) used to build/run the example.
- a markdown file in the docs/examples directory including the snippets for both the creation of the container and a simple test.
- a new Nav entry for the example in the docs site, adding it to the `mkdocs.yml` file located at the root directory of the project.
- a GitHub workflow file in the .github/workflows directory to run the tests for the example.

### Command line flags

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| -name | string | Yes | Name of the example, use camel-case when needed. Only alphabetical characters are allowed. |
| -image | string | Yes | Fully-qualified name of the Docker image to be used by the example (i.e. 'docker.io/org/project:tag') |
| -title | string | No | A variant of the name supporting mixed casing (i.e. 'MongoDB'). Only alphabetical characters are allowed. |

### What is this tool not doing?
Their main goal is to create shareable code snippets on how to use certain technology (e.g. a database, a web server), in order to explore its usage before converting the example module into a real Go module exposing a public API.

- If the example name does not contain alphabetical characters, it will exit the generation.
- If the example already exists, it will exit without updating the existing files.

### How to run the tool

From the [`examples` directory]({{repo_url}}/tree/main/examples), please run:
## Interested in adding a new example?

```shell
go run . --name ${NAME_OF_YOUR_EXAMPLE} --image "${REGISTRY}/${EXAMPLE}:${TAG}" --title ${TITLE_OF_YOUR_EXAMPLE}
```
Please refer to the documentation of the code generation tool [here](../modules/index.md).

## Update Go dependencies in the examples

Expand Down
56 changes: 56 additions & 0 deletions docs/modules/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Testcontainers for Go modules

In this section you'll discover how to create Go modules for _Testcontainers for Go_.

## Interested in adding a new module?

We have provided a command line tool to generate the scaffolding for the code of the example you are interested in. This tool will generate:

- a Go module for the example, including:
- go.mod and go.sum files, including the current version of _Testcontainer for Go_.
- a Go package named after the module, in lowercase
- a Go file for the creation of the container, using a dedicated struct in which the image flag is set as Docker image.
- a Go test file for running a simple test for your container, consuming the above struct.
- a Makefile to run the tests in a consistent manner
- a tools.go file including the build tools (i.e. `gotestsum`) used to build/run the example.
- a markdown file in the docs/modules directory including the snippets for both the creation of the container and a simple test.
- a new Nav entry for the module in the docs site, adding it to the `mkdocs.yml` file located at the root directory of the project.
- a GitHub workflow file in the .github/workflows directory to run the tests for the example.
- an entry in Dependabot's configuration file, in order to receive dependency updates.

### Command line flags

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| -name | string | Yes | Name of the module, use camel-case when needed. Only alphabetical characters are allowed. |
| -image | string | Yes | Fully-qualified name of the Docker image to be used by the module (i.e. 'docker.io/org/project:tag') |
| -title | string | No | A variant of the name supporting mixed casing (i.e. 'MongoDB'). Only alphabetical characters are allowed. |
| -as-module | bool | No | If set, the module will be generated as a Go module, under the modules directory. Otherwise, it will be generated as a subdirectory of the examples directory. |

### What is this tool not doing?

- If the module name does not contain alphabetical characters, it will exit the generation.
- If the module already exists, it will exit without updating the existing files.

### How to run the tool

From the [`modulegen` directory]({{repo_url}}/tree/main/modulegen), please run:

```shell
go run . --name ${NAME_OF_YOUR_MODULE} --image "${REGISTRY}/${MODULE}:${TAG}" --title ${TITLE_OF_YOUR_MODULE}
```

or for creating a Go module:

```shell
go run . --name ${NAME_OF_YOUR_MODULE} --image "${REGISTRY}/${MODULE}:${TAG}" --title ${TITLE_OF_YOUR_MODULE} --as-module
```

## Update Go dependencies in the modules

To update the Go dependencies in the modules, please run:

```shell
$ cd modules
$ make tidy-examples
```
107 changes: 107 additions & 0 deletions docs/modules/localstack.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# LocalStack

The Testcontainers module for [LocalStack](http://localstack.cloud/) is _"a fully functional local AWS cloud stack"_, to develop and test your cloud and serverless apps without actually using the cloud.

## Adding this module to your project dependencies

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

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

## Usage example

Running LocalStack as a stand-in for multiple AWS services during a test:

<!--codeinclude-->
[Creating a LocalStack container](../../modules/localstack/v1/s3_test.go) inside_block:localStackCreateContainer
<!--/codeinclude-->

Environment variables listed in [Localstack's README](https://github.com/localstack/localstack#configurations) may be used to customize Localstack's configuration.
Use the `OverrideContainerRequest` option when creating the `LocalStackContainer` to apply configuration settings.

## Creating a client using the AWS SDK for Go

### Version 1

<!--codeinclude-->
[Test for a LocalStack container, usinv AWS SDK v1](../../modules/localstack/v1/s3_test.go) inside_block:awsSDKClientV1
<!--/codeinclude-->

For further reference on the SDK v1, please check out the AWS docs [here](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/setting-up.html).

### Version 2

<!--codeinclude-->
[Test for a LocalStack container, usinv AWS SDK v2](../../modules/localstack/v2/s3_test.go) inside_block:awsSDKClientV2
<!--/codeinclude-->

For further reference on the SDK v2, please check out the AWS docs [here](https://aws.github.io/aws-sdk-go-v2/docs/getting-started)

## `HOSTNAME_EXTERNAL` and hostname-sensitive services

Some Localstack APIs, such as SQS, require the container to be aware of the hostname that it is accessible on - for example, for construction of queue URLs in responses.

Testcontainers will inform Localstack of the best hostname automatically, using the `HOSTNAME_EXTERNAL` environment variable:

* when running the Localstack container directly without a custom network defined, it is expected that all calls to the container will be from the test host. As such, the container address will be used (typically localhost or the address where the Docker daemon is running).

<!--codeinclude-->
[Localstack container running without a custom network](../../modules/localstack/localstack_test.go) inside_block:withoutNetwork
<!--/codeinclude-->

* when running the Localstack container [with a custom network defined](/features/networking/#advanced-networking), it is expected that all calls to the container will be **from other containers on that network**. `HOSTNAME_EXTERNAL` will be set to the *last* network alias that has been configured for the Localstack container.

<!--codeinclude-->
[Localstack container running with a custom network](../../modules/localstack/localstack_test.go) inside_block:withNetwork
<!--/codeinclude-->

* Other usage scenarios, such as where the Localstack container is used from both the test host and containers on a custom network are not automatically supported. If you have this use case, you should set `HOSTNAME_EXTERNAL` manually.

## Module reference

The LocalStack module exposes one single function to create the LocalStack container, and this function receives two parameters:

```golang
func StartContainer(ctx context.Context, overrideReq OverrideContainerRequestOption) (*LocalStackContainer, error)
```

- `context.Context`
- `OverrideContainerRequestOption`

### OverrideContainerRequestOption

The `OverrideContainerRequestOption` functional option represents a way to override the default LocalStack container request:

<!--codeinclude-->
[Default container request](../../modules/localstack/localstack.go) inside_block:defaultContainerRequest
<!--/codeinclude-->

With simply passing your own instance of an `OverrideContainerRequestOption` type to the `StartContainer` function, you'll be able to configure the LocalStack container with your own needs, as this new container request will be merged with the original one.

In the following example you check how it's possible to set certain environment variables that are needed by the tests, the most important of them the AWS services you want to use. Besides, the container runs in a separate Docker network with an alias:

<!--codeinclude-->
[Overriding the default container request](../../modules/localstack/localstack_test.go) inside_block:withNetwork
<!--/codeinclude-->

If you do not need to override the container request, you can pass `nil` or the `NoopOverrideContainerRequest` instance, which is exposed as a helper for this reason.

<!--codeinclude-->
[Skip overriding the default container request](../../modules/localstack/localstack_test.go) inside_block:noopOverrideContainerRequest
<!--/codeinclude-->

## Testing the module

The module includes unit and integration tests that can be run from its source code. To run the tests please execute the following command:

```
cd modules/localstack
make test
```

!!!info

At this moment, the tests for the module include tests for the S3 service, only. They live in two different Go packages of the LocalStack module,
`v1` and `v2`, where it'll be easier to add more examples for the rest of services.
7 changes: 0 additions & 7 deletions examples/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,6 @@ include ../commons-test.mk
dependencies-scan-examples:
@find . -type f -name Makefile -execdir make dependencies-scan \;

.PHONY: test
test: test-unit
$(MAKE) -C cockroachdb test
$(MAKE) -C nginx test
$(MAKE) -C pulsar test
$(MAKE) -C redis test

.PHONY: tidy-examples
tidy-examples:
@find . -type f -name Makefile -execdir make tools-tidy \;
Loading

0 comments on commit fef3cd5

Please sign in to comment.