From 7cf27c059c358fad52ed918a1e016aa3e6dc2315 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Thu, 16 Mar 2023 12:15:36 +0100 Subject: [PATCH 01/42] feat: support a container option to customise a container request --- container.go | 17 +++++++++++++++++ docs/features/creating_container.md | 2 +- go.mod | 1 + go.sum | 4 ++++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/container.go b/container.go index 92ea80999e..b76ddad15b 100644 --- a/container.go +++ b/container.go @@ -13,6 +13,7 @@ import ( "github.com/docker/docker/api/types/network" "github.com/docker/docker/pkg/archive" "github.com/docker/go-connections/nat" + "github.com/imdario/mergo" tcexec "github.com/testcontainers/testcontainers-go/exec" "github.com/testcontainers/testcontainers-go/internal/testcontainersdocker" @@ -132,6 +133,22 @@ type containerOptions struct { // functional option for setting the reaper image type ContainerOption func(*containerOptions) +// CustomizeContainerRequestOption is a type that can be used to configure the Testcontainers container request. +// The passed request will be merged with the default one. +type CustomizeContainerRequestOption func(req ContainerRequest) ContainerRequest + +// CustomizeContainerRequest returns a function that can be used to merge the passed container request with the one that is used by the container +func CustomizeContainerRequest(r ContainerRequest) CustomizeContainerRequestOption { + return func(req ContainerRequest) ContainerRequest { + if err := mergo.Merge(&req, r, mergo.WithOverride); err != nil { + fmt.Printf("error merging container request, keeping the original one. Error: %v", err) + return req + } + + return req + } +} + // WithImageName sets the reaper image name func WithImageName(imageName string) ContainerOption { return func(o *containerOptions) { diff --git a/docs/features/creating_container.md b/docs/features/creating_container.md index 58f10914e8..6a31b4e236 100644 --- a/docs/features/creating_container.md +++ b/docs/features/creating_container.md @@ -89,7 +89,7 @@ func TestIntegrationNginxLatestReturn(t *testing.T) { ### Advanced Settings -The aforementioned `GenericContainer` function and the `ContainerRequest` struct represent a straightforward manner to configure the containers, but you could need to create your containers with more advance settings regarding the config, host config and endpoint settings Docker types. For those more advance settings, _Testcontainers for Go_ offers a way to fully customise the container request and those internal Docker types. These customisations, called _modifiers_, will be applied just before the internal call to the Docker client to create the container. +The aforementioned `GenericContainer` function and the `ContainerRequest` struct represent a straightforward manner to configure the containers, but you could need to create your containers with more advance settings regarding the config, host config and endpoint settings Docker types. For those more advance settings, _Testcontainers for Go_ offers a way to fully customize the container request and those internal Docker types. These customisations, called _modifiers_, will be applied just before the internal call to the Docker client to create the container. [Using modifiers](../../lifecycle_test.go) inside_block:reqWithModifiers diff --git a/go.mod b/go.mod index b9a4af7b8a..44fa3e2d0f 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/docker/go-connections v0.4.0 github.com/docker/go-units v0.5.0 github.com/google/uuid v1.3.0 + github.com/imdario/mergo v0.3.12 github.com/magiconair/properties v1.8.7 github.com/moby/term v0.0.0-20221128092401-c43b287e0e0f github.com/opencontainers/image-spec v1.1.0-rc2 diff --git a/go.sum b/go.sum index de01a00331..dfb1a7e01d 100644 --- a/go.sum +++ b/go.sum @@ -95,6 +95,8 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.11.13 h1:eSvu8Tmq6j2psUJqJrLcWH6K3w5Dwc+qipbaA6eVEN4= @@ -304,6 +306,8 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 41c73f8b698a85eaa71b93cfd48b9cf3cb330ecc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Tue, 28 Mar 2023 18:00:19 +0200 Subject: [PATCH 02/42] feat: provide a way to override the wait strategy including deadline --- container.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/container.go b/container.go index b76ddad15b..e4298d3977 100644 --- a/container.go +++ b/container.go @@ -149,6 +149,18 @@ func CustomizeContainerRequest(r ContainerRequest) CustomizeContainerRequestOpti } } +// WithWaitStrategy sets the wait strategy for a container, using 1 minute as deadline +func WithWaitStrategy(strategies ...wait.Strategy) func(req *ContainerRequest) { + return WithWaitStrategyAndDuration(1*time.Minute, strategies...) +} + +// WithWaitStrategy sets the wait strategy for a container, including deadline +func WithWaitStrategyAndDuration(deadline time.Duration, strategies ...wait.Strategy) func(req *ContainerRequest) { + return func(req *ContainerRequest) { + req.WaitingFor = wait.ForAll(strategies...).WithDeadline(deadline) + } +} + // WithImageName sets the reaper image name func WithImageName(imageName string) ContainerOption { return func(o *containerOptions) { From 0dcc72ae9d3515f72305ff04ee713acf94c5fdf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Thu, 16 Mar 2023 12:33:57 +0100 Subject: [PATCH 03/42] chore: use new container request customisation in localstack --- docs/modules/localstack.md | 18 +++++---------- modules/localstack/localstack.go | 22 +++++++++++------- modules/localstack/localstack_test.go | 25 ++++++++------------ modules/localstack/types.go | 33 +++++++++++++++------------ modules/localstack/v1/s3_test.go | 4 ++-- modules/localstack/v2/s3_test.go | 4 ++-- 6 files changed, 52 insertions(+), 54 deletions(-) diff --git a/docs/modules/localstack.md b/docs/modules/localstack.md index 7aada1f93f..bfb4b0ee92 100644 --- a/docs/modules/localstack.md +++ b/docs/modules/localstack.md @@ -19,7 +19,7 @@ Running LocalStack as a stand-in for multiple AWS services during a test: 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. +Use the `testcontainers.CustomizeContainerRequest` option when creating the LocalStack `Container` to apply configuration settings. ## Creating a client using the AWS SDK for Go @@ -64,21 +64,21 @@ Testcontainers will inform Localstack of the best hostname automatically, using 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) +func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeContainerRequestOption) (*Container, error) { ``` - `context.Context` -- `OverrideContainerRequestOption` +- `testcontainers.CustomizeContainerRequestOption` -### OverrideContainerRequestOption +### CustomizeContainerRequestOption -The `OverrideContainerRequestOption` functional option represents a way to override the default LocalStack container request: +The variadic `testcontainers.CustomizeContainerRequestOption` functional option represents a way to override the default LocalStack container request: [Default container request](../../modules/localstack/localstack.go) inside_block:defaultContainerRequest -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. +With simply passing your own instance of an `testcontainers.CustomizeContainerRequest` type to the `RunContainer` 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: @@ -86,12 +86,6 @@ In the following example you check how it's possible to set certain environment [Overriding the default container request](../../modules/localstack/localstack_test.go) inside_block:withNetwork -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. - - -[Skip overriding the default container request](../../modules/localstack/localstack_test.go) inside_block:noopOverrideContainerRequest - - ## 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: diff --git a/modules/localstack/localstack.go b/modules/localstack/localstack.go index 4c36a3f71b..686b87437d 100644 --- a/modules/localstack/localstack.go +++ b/modules/localstack/localstack.go @@ -40,9 +40,9 @@ func isLegacyMode(image string) bool { return true } -// StartContainer creates an instance of the LocalStack container type, being possible to pass a custom request and options: +// RunContainer creates an instance of the LocalStack container type, being possible to pass a custom request and options: // - overrideReq: a function that can be used to override the default container request, usually used to set the image version, environment variables for localstack, etc. -func StartContainer(ctx context.Context, overrideReq OverrideContainerRequestOption) (*LocalStackContainer, error) { +func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeContainerRequestOption) (*Container, error) { // defaultContainerRequest { req := testcontainers.ContainerRequest{ Image: fmt.Sprintf("localstack/localstack:%s", defaultVersion), @@ -53,14 +53,13 @@ func StartContainer(ctx context.Context, overrideReq OverrideContainerRequestOpt } // } - localStackReq := LocalStackContainerRequest{ + localStackReq := ContainerRequest{ ContainerRequest: req, } // first, when needed, we merge the user request with the default one - if overrideReq != nil { - merged := overrideReq(localStackReq.ContainerRequest) - localStackReq.ContainerRequest = merged + for _, opt := range opts { + localStackReq.ContainerRequest = opt(localStackReq.ContainerRequest) } if isLegacyMode(localStackReq.Image) { @@ -81,13 +80,20 @@ func StartContainer(ctx context.Context, overrideReq OverrideContainerRequestOpt return nil, err } - c := &LocalStackContainer{ + c := &Container{ Container: container, } return c, nil } -func configureDockerHost(req *LocalStackContainerRequest) (reason string, err error) { +// StartContainer creates an instance of the LocalStack container type, being possible to pass a custom request and options: +// - overrideReq: a function that can be used to override the default container request, usually used to set the image version, environment variables for localstack, etc. +// Deprecated use RunContainer instead +func StartContainer(ctx context.Context, overrideReq OverrideContainerRequestOption) (*Container, error) { + return RunContainer(ctx, testcontainers.CustomizeContainerRequestOption(overrideReq)) +} + +func configureDockerHost(req *ContainerRequest) (reason string, err error) { err = nil reason = "" diff --git a/modules/localstack/localstack_test.go b/modules/localstack/localstack_test.go index fa1c7ca410..456f5b4974 100644 --- a/modules/localstack/localstack_test.go +++ b/modules/localstack/localstack_test.go @@ -10,8 +10,8 @@ import ( "github.com/testcontainers/testcontainers-go" ) -func generateContainerRequest() *LocalStackContainerRequest { - return &LocalStackContainerRequest{ +func generateContainerRequest() *ContainerRequest { + return &ContainerRequest{ ContainerRequest: testcontainers.ContainerRequest{ Env: map[string]string{}, ExposedPorts: []string{}, @@ -91,13 +91,13 @@ func TestIsLegacyMode(t *testing.T) { } } -func TestStart(t *testing.T) { +func TestRunContainer(t *testing.T) { ctx := context.Background() // withoutNetwork { - container, err := StartContainer( + container, err := RunContainer( ctx, - OverrideContainerRequest(testcontainers.ContainerRequest{ + testcontainers.CustomizeContainerRequest(testcontainers.ContainerRequest{ Image: fmt.Sprintf("localstack/localstack:%s", defaultVersion), }), ) @@ -122,20 +122,15 @@ func TestStart(t *testing.T) { }) } -func TestStartWithoutOverride(t *testing.T) { - // noopOverrideContainerRequest { +func TestRunContainerWithoutOverride(t *testing.T) { ctx := context.Background() - container, err := StartContainer( - ctx, - NoopOverrideContainerRequest, - ) + container, err := RunContainer(ctx) require.Nil(t, err) assert.NotNil(t, container) - // } } -func TestStartWithNetwork(t *testing.T) { +func TestRunContainerWithNetwork(t *testing.T) { // withNetwork { ctx := context.Background() @@ -147,9 +142,9 @@ func TestStartWithNetwork(t *testing.T) { require.Nil(t, err) assert.NotNil(t, nw) - container, err := StartContainer( + container, err := RunContainer( ctx, - OverrideContainerRequest(testcontainers.ContainerRequest{ + testcontainers.CustomizeContainerRequest(testcontainers.ContainerRequest{ Image: "localstack/localstack:0.13.0", Env: map[string]string{"SERVICES": "s3,sqs"}, Networks: []string{"localstack-network"}, diff --git a/modules/localstack/types.go b/modules/localstack/types.go index 9f08095d69..5eca3981c9 100644 --- a/modules/localstack/types.go +++ b/modules/localstack/types.go @@ -1,40 +1,43 @@ package localstack import ( - "fmt" - - "github.com/imdario/mergo" "github.com/testcontainers/testcontainers-go" ) -// LocalStackContainer represents the LocalStack container type used in the module -type LocalStackContainer struct { +// Container represents the LocalStack container type used in the module +type Container struct { testcontainers.Container } -// LocalStackContainerRequest represents the LocalStack container request type used in the module +// Deprecated: use Container instead +type LocalStackContainer struct { + Container +} + +// ContainerRequest represents the LocalStack container request type used in the module // to configure the container -type LocalStackContainerRequest struct { +type ContainerRequest struct { testcontainers.ContainerRequest } +// Deprecated: use ContainerRequest instead +type LocalStackContainerRequest struct { + ContainerRequest +} + // OverrideContainerRequestOption is a type that can be used to configure the Testcontainers container request. // The passed request will be merged with the default one. +// Deprecated: use testcontainers.CustomizeContainerRequestOption instead type OverrideContainerRequestOption func(req testcontainers.ContainerRequest) testcontainers.ContainerRequest // NoopOverrideContainerRequest returns a helper function that does not override the container request +// Deprecated var NoopOverrideContainerRequest = func(req testcontainers.ContainerRequest) testcontainers.ContainerRequest { return req } // OverrideContainerRequest returns a function that can be used to merge the passed container request with one that is created by the LocalStack container +// Deprecated: use testcontainers.CustomizeContainerRequestOption instead func OverrideContainerRequest(r testcontainers.ContainerRequest) func(req testcontainers.ContainerRequest) testcontainers.ContainerRequest { - return func(req testcontainers.ContainerRequest) testcontainers.ContainerRequest { - if err := mergo.Merge(&req, r, mergo.WithOverride); err != nil { - fmt.Printf("error merging container request %v. Keeping the default one: %v", err, req) - return req - } - - return req - } + return testcontainers.CustomizeContainerRequest(r) } diff --git a/modules/localstack/v1/s3_test.go b/modules/localstack/v1/s3_test.go index 3d795b5e1f..8895f64123 100644 --- a/modules/localstack/v1/s3_test.go +++ b/modules/localstack/v1/s3_test.go @@ -28,7 +28,7 @@ const ( // awsSDKClientV1 { // awsSession returns a new AWS session for the given service. To retrieve the specific AWS service client, use the // session's client method, e.g. s3manager.NewUploader(session). -func awsSession(ctx context.Context, l *localstack.LocalStackContainer) (*session.Session, error) { +func awsSession(ctx context.Context, l *localstack.Container) (*session.Session, error) { mappedPort, err := l.MappedPort(ctx, nat.Port("4566/tcp")) if err != nil { return &session.Session{}, err @@ -62,7 +62,7 @@ func TestS3(t *testing.T) { ctx := context.Background() // localStackCreateContainer { - container, err := localstack.StartContainer(ctx, localstack.NoopOverrideContainerRequest) + container, err := localstack.RunContainer(ctx) require.Nil(t, err) // } diff --git a/modules/localstack/v2/s3_test.go b/modules/localstack/v2/s3_test.go index c80d534b39..fcb0eada8e 100644 --- a/modules/localstack/v2/s3_test.go +++ b/modules/localstack/v2/s3_test.go @@ -25,7 +25,7 @@ const ( ) // awsSDKClientV2 { -func s3Client(ctx context.Context, l *localstack.LocalStackContainer) (*s3.Client, error) { +func s3Client(ctx context.Context, l *localstack.Container) (*s3.Client, error) { mappedPort, err := l.MappedPort(ctx, nat.Port("4566/tcp")) if err != nil { return nil, err @@ -72,7 +72,7 @@ func s3Client(ctx context.Context, l *localstack.LocalStackContainer) (*s3.Clien func TestS3(t *testing.T) { ctx := context.Background() - container, err := localstack.StartContainer(ctx, localstack.NoopOverrideContainerRequest) + container, err := localstack.RunContainer(ctx) require.Nil(t, err) s3Client, err := s3Client(ctx, container) From 6bed15348cc227486b528d549e7ee7562b59eb5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Wed, 29 Mar 2023 07:37:38 +0200 Subject: [PATCH 04/42] chore: add emojis to the start container logs --- docker.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docker.go b/docker.go index e4ec56926c..2897ef2518 100644 --- a/docker.go +++ b/docker.go @@ -188,7 +188,7 @@ func (c *DockerContainer) SessionID() string { // Start will start an already created container func (c *DockerContainer) Start(ctx context.Context) error { shortID := c.ID[:12] - c.logger.Printf("Starting container id: %s image: %s", shortID, c.Image) + c.logger.Printf("🐳 Starting container id: %s image: %s", shortID, c.Image) if err := c.provider.client.ContainerStart(ctx, c.ID, types.ContainerStartOptions{}); err != nil { return err @@ -197,12 +197,12 @@ func (c *DockerContainer) Start(ctx context.Context) error { // if a Wait Strategy has been specified, wait before returning if c.WaitingFor != nil { - c.logger.Printf("Waiting for container id %s image: %s", shortID, c.Image) + c.logger.Printf("🚧 Waiting for container id %s image: %s", shortID, c.Image) if err := c.WaitingFor.WaitUntilReady(ctx, c); err != nil { return err } } - c.logger.Printf("Container is ready id: %s image: %s", shortID, c.Image) + c.logger.Printf("✅ Container is ready id: %s image: %s", shortID, c.Image) c.isRunning = true return nil } From 17bd5672bdda7b0741eb1ddf97827f0882bfe9f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Wed, 29 Mar 2023 15:39:05 +0200 Subject: [PATCH 05/42] chore: mod tidy in modules --- examples/bigtable/go.mod | 1 + examples/bigtable/go.sum | 4 ++++ examples/cockroachdb/go.mod | 1 + examples/cockroachdb/go.sum | 4 ++++ examples/consul/go.mod | 1 + examples/consul/go.sum | 4 ++++ examples/datastore/go.mod | 1 + examples/datastore/go.sum | 4 ++++ examples/firestore/go.mod | 1 + examples/firestore/go.sum | 4 ++++ examples/mongodb/go.mod | 1 + examples/mongodb/go.sum | 4 ++++ examples/nginx/go.mod | 1 + examples/nginx/go.sum | 4 ++++ examples/pubsub/go.mod | 1 + examples/pubsub/go.sum | 4 ++++ examples/spanner/go.mod | 1 + examples/spanner/go.sum | 4 ++++ examples/toxiproxy/go.mod | 1 + examples/toxiproxy/go.sum | 3 +++ modules/couchbase/go.mod | 1 + modules/couchbase/go.sum | 4 ++++ modules/localstack/go.mod | 2 +- modules/mysql/go.mod | 1 + modules/mysql/go.sum | 4 ++++ modules/neo4j/go.mod | 1 + modules/neo4j/go.sum | 4 ++++ modules/postgres/go.mod | 1 + modules/postgres/go.sum | 4 ++++ modules/pulsar/go.mod | 1 + modules/pulsar/go.sum | 2 ++ modules/redis/go.mod | 1 + modules/redis/go.sum | 3 +++ modules/vault/go.mod | 1 + modules/vault/go.sum | 4 ++++ 35 files changed, 82 insertions(+), 1 deletion(-) diff --git a/examples/bigtable/go.mod b/examples/bigtable/go.mod index 5be59a3610..69c69b1f5a 100644 --- a/examples/bigtable/go.mod +++ b/examples/bigtable/go.mod @@ -42,6 +42,7 @@ require ( github.com/google/uuid v1.3.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect github.com/googleapis/gax-go/v2 v2.7.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect github.com/klauspost/compress v1.15.9 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.12 // indirect diff --git a/examples/bigtable/go.sum b/examples/bigtable/go.sum index c33713d353..573da3c754 100644 --- a/examples/bigtable/go.sum +++ b/examples/bigtable/go.sum @@ -205,6 +205,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -617,6 +619,8 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/examples/cockroachdb/go.mod b/examples/cockroachdb/go.mod index 5d94aa32e3..438f5737ce 100644 --- a/examples/cockroachdb/go.mod +++ b/examples/cockroachdb/go.mod @@ -29,6 +29,7 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect + github.com/imdario/mergo v0.3.12 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect github.com/jackc/pgconn v1.14.0 // indirect github.com/jackc/pgio v1.0.0 // indirect diff --git a/examples/cockroachdb/go.sum b/examples/cockroachdb/go.sum index ab801fc456..4cc51058c2 100644 --- a/examples/cockroachdb/go.sum +++ b/examples/cockroachdb/go.sum @@ -106,6 +106,8 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= @@ -435,6 +437,8 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/examples/consul/go.mod b/examples/consul/go.mod index 82f1020732..078af7ffd7 100644 --- a/examples/consul/go.mod +++ b/examples/consul/go.mod @@ -32,6 +32,7 @@ require ( github.com/hashicorp/go-rootcerts v1.0.2 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/serf v0.10.1 // indirect + github.com/imdario/mergo v0.3.12 // indirect github.com/klauspost/compress v1.15.9 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.12 // indirect diff --git a/examples/consul/go.sum b/examples/consul/go.sum index f9f9561b9a..5acae805da 100644 --- a/examples/consul/go.sum +++ b/examples/consul/go.sum @@ -136,6 +136,8 @@ github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= @@ -363,6 +365,8 @@ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gotest.tools/gotestsum v1.9.0 h1:Jbo/0k/sIOXIJu51IZxEAt27n77xspFEfL6SqKUR72A= diff --git a/examples/datastore/go.mod b/examples/datastore/go.mod index b92d7d3217..04288b51c7 100644 --- a/examples/datastore/go.mod +++ b/examples/datastore/go.mod @@ -34,6 +34,7 @@ require ( github.com/google/uuid v1.3.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect github.com/googleapis/gax-go/v2 v2.7.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect github.com/klauspost/compress v1.15.9 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.12 // indirect diff --git a/examples/datastore/go.sum b/examples/datastore/go.sum index 1da3ed1be9..bb1b86859d 100644 --- a/examples/datastore/go.sum +++ b/examples/datastore/go.sum @@ -96,6 +96,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9 github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ= github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= @@ -291,6 +293,8 @@ google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175 google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/examples/firestore/go.mod b/examples/firestore/go.mod index 612a30a87a..62dcbeb8f5 100644 --- a/examples/firestore/go.mod +++ b/examples/firestore/go.mod @@ -35,6 +35,7 @@ require ( github.com/google/uuid v1.3.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect github.com/googleapis/gax-go/v2 v2.7.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect github.com/klauspost/compress v1.11.13 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.12 // indirect diff --git a/examples/firestore/go.sum b/examples/firestore/go.sum index 70adc28142..5f2c2a3de8 100644 --- a/examples/firestore/go.sum +++ b/examples/firestore/go.sum @@ -97,6 +97,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9 github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ= github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.11.13 h1:eSvu8Tmq6j2psUJqJrLcWH6K3w5Dwc+qipbaA6eVEN4= @@ -293,6 +295,8 @@ google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175 google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/examples/mongodb/go.mod b/examples/mongodb/go.mod index 590aee5a4c..b1466e8620 100644 --- a/examples/mongodb/go.mod +++ b/examples/mongodb/go.mod @@ -26,6 +26,7 @@ require ( github.com/golang/snappy v0.0.1 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.3.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect github.com/klauspost/compress v1.15.9 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.12 // indirect diff --git a/examples/mongodb/go.sum b/examples/mongodb/go.sum index 5a65bc7a27..421e0b468c 100644 --- a/examples/mongodb/go.sum +++ b/examples/mongodb/go.sum @@ -95,6 +95,8 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= @@ -310,6 +312,8 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/examples/nginx/go.mod b/examples/nginx/go.mod index 490162e232..3f7ce51930 100644 --- a/examples/nginx/go.mod +++ b/examples/nginx/go.mod @@ -26,6 +26,7 @@ require ( github.com/golang/protobuf v1.5.2 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.3.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect github.com/klauspost/compress v1.11.13 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.12 // indirect diff --git a/examples/nginx/go.sum b/examples/nginx/go.sum index 693bde15c8..ae6c2f54eb 100644 --- a/examples/nginx/go.sum +++ b/examples/nginx/go.sum @@ -92,6 +92,8 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.11.13 h1:eSvu8Tmq6j2psUJqJrLcWH6K3w5Dwc+qipbaA6eVEN4= @@ -282,6 +284,8 @@ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gotest.tools/gotestsum v1.9.0 h1:Jbo/0k/sIOXIJu51IZxEAt27n77xspFEfL6SqKUR72A= diff --git a/examples/pubsub/go.mod b/examples/pubsub/go.mod index 47804ae107..6b5bcd164d 100644 --- a/examples/pubsub/go.mod +++ b/examples/pubsub/go.mod @@ -35,6 +35,7 @@ require ( github.com/google/uuid v1.3.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect github.com/googleapis/gax-go/v2 v2.7.1 // indirect + github.com/imdario/mergo v0.3.12 // indirect github.com/klauspost/compress v1.15.9 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.12 // indirect diff --git a/examples/pubsub/go.sum b/examples/pubsub/go.sum index b6e37aa00d..6ef94d536f 100644 --- a/examples/pubsub/go.sum +++ b/examples/pubsub/go.sum @@ -99,6 +99,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9 github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.7.1 h1:gF4c0zjUP2H/s/hEGyLA3I0fA2ZWjzYiONAD6cvPr8A= github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= @@ -292,6 +294,8 @@ google.golang.org/protobuf v1.29.1 h1:7QBf+IK2gx70Ap/hDsOmam3GE0v9HicjfEdAxE62Uo google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/examples/spanner/go.mod b/examples/spanner/go.mod index 94cd23d7e9..614060788a 100644 --- a/examples/spanner/go.mod +++ b/examples/spanner/go.mod @@ -43,6 +43,7 @@ require ( github.com/google/uuid v1.3.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect github.com/googleapis/gax-go/v2 v2.7.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect github.com/klauspost/compress v1.11.13 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.12 // indirect diff --git a/examples/spanner/go.sum b/examples/spanner/go.sum index 6468c06049..49d9c25f45 100644 --- a/examples/spanner/go.sum +++ b/examples/spanner/go.sum @@ -204,6 +204,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -616,6 +618,8 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/examples/toxiproxy/go.mod b/examples/toxiproxy/go.mod index 8114cd2a57..073dc08d99 100644 --- a/examples/toxiproxy/go.mod +++ b/examples/toxiproxy/go.mod @@ -28,6 +28,7 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect + github.com/imdario/mergo v0.3.12 // indirect github.com/klauspost/compress v1.11.13 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect diff --git a/examples/toxiproxy/go.sum b/examples/toxiproxy/go.sum index d2fbd9b980..de79e5f085 100644 --- a/examples/toxiproxy/go.sum +++ b/examples/toxiproxy/go.sum @@ -100,6 +100,8 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.11.13 h1:eSvu8Tmq6j2psUJqJrLcWH6K3w5Dwc+qipbaA6eVEN4= @@ -296,6 +298,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/modules/couchbase/go.mod b/modules/couchbase/go.mod index e79b5887a6..472b8999d0 100644 --- a/modules/couchbase/go.mod +++ b/modules/couchbase/go.mod @@ -28,6 +28,7 @@ require ( github.com/golang/snappy v0.0.4 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.3.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect github.com/klauspost/compress v1.15.9 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.12 // indirect diff --git a/modules/couchbase/go.sum b/modules/couchbase/go.sum index 3367afb213..bcd7885809 100644 --- a/modules/couchbase/go.sum +++ b/modules/couchbase/go.sum @@ -100,6 +100,8 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= @@ -302,6 +304,8 @@ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/modules/localstack/go.mod b/modules/localstack/go.mod index 7bc621e8f8..5e79e68476 100644 --- a/modules/localstack/go.mod +++ b/modules/localstack/go.mod @@ -9,7 +9,6 @@ require ( github.com/aws/aws-sdk-go-v2/credentials v1.13.18 github.com/aws/aws-sdk-go-v2/service/s3 v1.31.0 github.com/docker/go-connections v0.4.0 - github.com/imdario/mergo v0.3.14 github.com/stretchr/testify v1.8.2 github.com/testcontainers/testcontainers-go v0.19.0 golang.org/x/mod v0.9.0 @@ -47,6 +46,7 @@ require ( github.com/golang/protobuf v1.5.2 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.3.0 // indirect + github.com/imdario/mergo v0.3.14 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/klauspost/compress v1.15.9 // indirect github.com/magiconair/properties v1.8.7 // indirect diff --git a/modules/mysql/go.mod b/modules/mysql/go.mod index ee1866ed0a..ca0d7e73c7 100644 --- a/modules/mysql/go.mod +++ b/modules/mysql/go.mod @@ -25,6 +25,7 @@ require ( github.com/golang/protobuf v1.5.2 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.3.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect github.com/klauspost/compress v1.15.9 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.12 // indirect diff --git a/modules/mysql/go.sum b/modules/mysql/go.sum index c9452c8142..688c307127 100644 --- a/modules/mysql/go.sum +++ b/modules/mysql/go.sum @@ -94,6 +94,8 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= @@ -284,6 +286,8 @@ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gotest.tools/gotestsum v1.9.0 h1:Jbo/0k/sIOXIJu51IZxEAt27n77xspFEfL6SqKUR72A= diff --git a/modules/neo4j/go.mod b/modules/neo4j/go.mod index e17552c6e1..46bdfaa32a 100644 --- a/modules/neo4j/go.mod +++ b/modules/neo4j/go.mod @@ -25,6 +25,7 @@ require ( github.com/golang/protobuf v1.5.2 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.3.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect github.com/klauspost/compress v1.15.9 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.12 // indirect diff --git a/modules/neo4j/go.sum b/modules/neo4j/go.sum index bd7559a9fc..00da5b44d5 100644 --- a/modules/neo4j/go.sum +++ b/modules/neo4j/go.sum @@ -92,6 +92,8 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= @@ -284,6 +286,8 @@ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gotest.tools/gotestsum v1.9.0 h1:Jbo/0k/sIOXIJu51IZxEAt27n77xspFEfL6SqKUR72A= diff --git a/modules/postgres/go.mod b/modules/postgres/go.mod index 150bfd3597..6c102cad0a 100644 --- a/modules/postgres/go.mod +++ b/modules/postgres/go.mod @@ -27,6 +27,7 @@ require ( github.com/golang/protobuf v1.5.2 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.3.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect github.com/klauspost/compress v1.15.9 // indirect github.com/kr/text v0.2.0 // indirect github.com/magiconair/properties v1.8.7 // indirect diff --git a/modules/postgres/go.sum b/modules/postgres/go.sum index 6814eebf38..25756a5015 100644 --- a/modules/postgres/go.sum +++ b/modules/postgres/go.sum @@ -93,6 +93,8 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= @@ -295,6 +297,8 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/modules/pulsar/go.mod b/modules/pulsar/go.mod index baf14021cc..c4df3bd55c 100644 --- a/modules/pulsar/go.mod +++ b/modules/pulsar/go.mod @@ -42,6 +42,7 @@ require ( github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.3.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect + github.com/imdario/mergo v0.3.12 // indirect github.com/klauspost/compress v1.15.9 // indirect github.com/kr/text v0.2.0 // indirect github.com/linkedin/goavro/v2 v2.9.8 // indirect diff --git a/modules/pulsar/go.sum b/modules/pulsar/go.sum index 069d4ce552..01cc827319 100644 --- a/modules/pulsar/go.sum +++ b/modules/pulsar/go.sum @@ -264,6 +264,8 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jawher/mow.cli v1.0.4/go.mod h1:5hQj2V8g+qYmLUVWqu4Wuja1pI57M83EChYLVZ0sMKk= github.com/jawher/mow.cli v1.2.0/go.mod h1:y+pcA3jBAdo/GIZx/0rFjw/K2bVEODP9rfZOfaiq8Ko= diff --git a/modules/redis/go.mod b/modules/redis/go.mod index 2994449c44..378fd08b8a 100644 --- a/modules/redis/go.mod +++ b/modules/redis/go.mod @@ -31,6 +31,7 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect + github.com/imdario/mergo v0.3.12 // indirect github.com/klauspost/compress v1.11.13 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.12 // indirect diff --git a/modules/redis/go.sum b/modules/redis/go.sum index 721655532a..4a02b42cc8 100644 --- a/modules/redis/go.sum +++ b/modules/redis/go.sum @@ -98,6 +98,8 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.11.13 h1:eSvu8Tmq6j2psUJqJrLcWH6K3w5Dwc+qipbaA6eVEN4= @@ -301,6 +303,7 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/modules/vault/go.mod b/modules/vault/go.mod index abaad7d8f1..470a439966 100644 --- a/modules/vault/go.mod +++ b/modules/vault/go.mod @@ -34,6 +34,7 @@ require ( github.com/hashicorp/go-retryablehttp v0.7.2 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect + github.com/imdario/mergo v0.3.12 // indirect github.com/klauspost/compress v1.15.9 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.12 // indirect diff --git a/modules/vault/go.sum b/modules/vault/go.sum index 5dd809e14f..80200d4e64 100644 --- a/modules/vault/go.sum +++ b/modules/vault/go.sum @@ -109,6 +109,8 @@ github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9 github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= github.com/hashicorp/vault-client-go v0.2.0 h1:Zzf5D2kj7QmBZE2ZTdril1aJlujMptPatxslTkdDF+U= github.com/hashicorp/vault-client-go v0.2.0/go.mod h1:C9rbJeHeI1Dy/MXXd5YLrzRfAH27n6mARnhpvaW/8gk= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= @@ -322,6 +324,8 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From f192623471954916409c1ec55e16ee589c7d510a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Wed, 29 Mar 2023 15:54:45 +0200 Subject: [PATCH 06/42] chore: append slices and maps while merging a container request --- container.go | 5 ++-- container_test.go | 41 +++++++++++++++++++++++++++ modules/localstack/types_test.go | 48 -------------------------------- 3 files changed, 44 insertions(+), 50 deletions(-) delete mode 100644 modules/localstack/types_test.go diff --git a/container.go b/container.go index e4298d3977..b7e2ab8da8 100644 --- a/container.go +++ b/container.go @@ -137,10 +137,11 @@ type ContainerOption func(*containerOptions) // The passed request will be merged with the default one. type CustomizeContainerRequestOption func(req ContainerRequest) ContainerRequest -// CustomizeContainerRequest returns a function that can be used to merge the passed container request with the one that is used by the container +// CustomizeContainerRequest returns a function that can be used to merge the passed container request with the one that is used by the container. +// Slices and Maps will be appended. func CustomizeContainerRequest(r ContainerRequest) CustomizeContainerRequestOption { return func(req ContainerRequest) ContainerRequest { - if err := mergo.Merge(&req, r, mergo.WithOverride); err != nil { + if err := mergo.Merge(&req, r, mergo.WithOverride, mergo.WithAppendSlice); err != nil { fmt.Printf("error merging container request, keeping the original one. Error: %v", err) return req } diff --git a/container_test.go b/container_test.go index 9f32a854b4..1fef97e191 100644 --- a/container_test.go +++ b/container_test.go @@ -419,3 +419,44 @@ func TestVolumeMount(t *testing.T) { }) } } + +func TestOverrideContainerRequest(t *testing.T) { + req := ContainerRequest{ + Env: map[string]string{ + "BAR": "BAR", + }, + Image: "foo", + ExposedPorts: []string{"12345/tcp"}, + WaitingFor: wait.ForNop( + func(ctx context.Context, target wait.StrategyTarget) error { + return nil + }, + ), + Networks: []string{"foo", "bar", "baaz"}, + NetworkAliases: map[string][]string{ + "foo": {"foo0", "foo1", "foo2", "foo3"}, + }, + } + + merged := CustomizeContainerRequest(ContainerRequest{ + Env: map[string]string{ + "FOO": "FOO", + }, + Image: "bar", + ExposedPorts: []string{"67890/tcp"}, + Networks: []string{"foo1", "bar1"}, + NetworkAliases: map[string][]string{ + "foo1": {"bar"}, + }, + WaitingFor: wait.ForLog("foo"), + })(req) + + assert.Equal(t, "FOO", merged.Env["FOO"]) + assert.Equal(t, "BAR", merged.Env["BAR"]) + assert.Equal(t, "bar", merged.Image) + assert.Equal(t, []string{"12345/tcp", "67890/tcp"}, merged.ExposedPorts) + assert.Equal(t, []string{"foo", "bar", "baaz", "foo1", "bar1"}, merged.Networks) + assert.Equal(t, []string{"foo0", "foo1", "foo2", "foo3"}, merged.NetworkAliases["foo"]) + assert.Equal(t, []string{"bar"}, merged.NetworkAliases["foo1"]) + assert.Equal(t, wait.ForLog("foo"), merged.WaitingFor) +} diff --git a/modules/localstack/types_test.go b/modules/localstack/types_test.go deleted file mode 100644 index faae146e51..0000000000 --- a/modules/localstack/types_test.go +++ /dev/null @@ -1,48 +0,0 @@ -package localstack - -import ( - "context" - "testing" - - "github.com/stretchr/testify/assert" - testcontainers "github.com/testcontainers/testcontainers-go" - "github.com/testcontainers/testcontainers-go/wait" -) - -func TestOverrideContainerRequest(t *testing.T) { - req := testcontainers.ContainerRequest{ - Env: map[string]string{}, - Image: "foo", - ExposedPorts: []string{}, - WaitingFor: wait.ForNop( - func(ctx context.Context, target wait.StrategyTarget) error { - return nil - }, - ), - Networks: []string{"foo", "bar", "baaz"}, - NetworkAliases: map[string][]string{ - "foo": {"foo0", "foo1", "foo2", "foo3"}, - }, - } - - merged := OverrideContainerRequest(testcontainers.ContainerRequest{ - Env: map[string]string{ - "FOO": "BAR", - }, - Image: "bar", - ExposedPorts: []string{"12345/tcp"}, - Networks: []string{"foo1", "bar1"}, - NetworkAliases: map[string][]string{ - "foo1": {"bar"}, - }, - WaitingFor: wait.ForLog("foo"), - })(req) - - assert.Equal(t, "BAR", merged.Env["FOO"]) - assert.Equal(t, "bar", merged.Image) - assert.Equal(t, []string{"12345/tcp"}, merged.ExposedPorts) - assert.Equal(t, []string{"foo1", "bar1"}, merged.Networks) - assert.Equal(t, []string{"foo0", "foo1", "foo2", "foo3"}, merged.NetworkAliases["foo"]) - assert.Equal(t, []string{"bar"}, merged.NetworkAliases["foo1"]) - assert.Equal(t, wait.ForLog("foo"), merged.WaitingFor) -} From c4e7a30ecd29a079999943f4ebff2578e2a05178 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Wed, 29 Mar 2023 16:35:28 +0200 Subject: [PATCH 07/42] docs: document how to create/migrate modules --- docs/modules/index.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/docs/modules/index.md b/docs/modules/index.md index b692f61bf8..d202ee51dc 100644 --- a/docs/modules/index.md +++ b/docs/modules/index.md @@ -2,6 +2,17 @@ In this section you'll discover how to create Go modules for _Testcontainers for Go_. +## Interested in converting an example into a module? + +The steps to convert an existing example, aka `${THE_EXAMPLE}`, into a module are the following: + +1. Rename the module path at the `go.mod`file for your example. +1. Move the `examples/${THE_EXAMPLE}` directory to `modules/${THE_EXAMPLE}`. +1. Move the `${THE_EXAMPLE}` dependabot config from the examples section to the modules one, which is located at the bottom. +1. In the `mkdocs.yml` file, move the entry for `${THE_EXAMPLE}` from examples to modules. +1. Move `docs/examples${THE_EXAMPLE}.md` file to `docs/modules/${THE_EXAMPLE}`, updating the references to the source code paths. +1. Update the Github workflow for `${THE_EXAMPLE}`, modifying names and paths. + ## 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: @@ -46,6 +57,31 @@ or for creating a Go module: go run . --name ${NAME_OF_YOUR_MODULE} --image "${REGISTRY}/${MODULE}:${TAG}" --title ${TITLE_OF_YOUR_MODULE} --as-module ``` +## Adding types and methods to the module + +We are going to propose a set of steps to follow when adding types and methods to the module: + +!!!warning + The `StartContainer` function will be eventually deprecated and replaced with `RunContainer`. We are keeping it in certain modules for backwards compatibility, but they will be removed in the future. + +- Make sure a public `Container` type exists for the module. This type have to use composition to embed the `testcontainers.Container` type, inheriting all the methods from it. +- Make sure a `RunContainer` function exists and is public. This function is the entrypoint to the module and will define the initial values for a `testcontainers.ContainerRequest` struct, including the image, the default exposed ports, wait strategies, etc. Therefore, the function must initialise the container request with the default values. +- Define container options for the module. We consider that a best practice for the options is to return a function that returns a modified `testcontainers.ContainerRequest` type, and for that, the library already provides with a `testcontainers.CustomizeContainerRequestOption` type representing this function signature. +- The options will be passed to the `RunContainer` function as variadic arguments after the Go context, and they will be processed right after defining the initial `testcontainers.ContainerRequest` struct using a for loop. + +```golang +func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeContainerRequestOption) (*Container, error) {...} +``` + +- If needed, define public methods to extract information from the running container, using the `Container` type as receiver. E.g. a connection string to access a database: + +```golang +func (c *Container) ConnectionString(ctx context.Context) (string, error) {...} +``` + +- Document the public API with Go comments. +- Extend the docs to describe the new API of the module. We usually define a parent `Module reference` section, including a `Container options` subsection; within the `Container options` subsection, we define a subsection for each option. + ## Update Go dependencies in the modules To update the Go dependencies in the modules, please run: From ca2e43d22752730570d9808ff7d2d418fbcefece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Wed, 29 Mar 2023 16:44:14 +0200 Subject: [PATCH 08/42] chore: move WithImage to the core --- container.go | 7 +++++++ docs/modules/mysql.md | 2 +- docs/modules/postgres.md | 4 ++-- modules/mysql/mysql.go | 15 +++++++-------- modules/mysql/mysql_test.go | 3 ++- modules/postgres/postgres.go | 10 ++++------ modules/postgres/postgres_test.go | 5 +++-- 7 files changed, 26 insertions(+), 20 deletions(-) diff --git a/container.go b/container.go index b7e2ab8da8..7f6151466d 100644 --- a/container.go +++ b/container.go @@ -150,6 +150,13 @@ func CustomizeContainerRequest(r ContainerRequest) CustomizeContainerRequestOpti } } +// WithImage sets the image for a container +func WithImage(image string) func(req *ContainerRequest) { + return func(req *ContainerRequest) { + req.Image = image + } +} + // WithWaitStrategy sets the wait strategy for a container, using 1 minute as deadline func WithWaitStrategy(strategies ...wait.Strategy) func(req *ContainerRequest) { return WithWaitStrategyAndDuration(1*time.Minute, strategies...) diff --git a/docs/modules/mysql.md b/docs/modules/mysql.md index 08c5cc14f4..c23704293d 100644 --- a/docs/modules/mysql.md +++ b/docs/modules/mysql.md @@ -35,7 +35,7 @@ When starting the MySQL container, you can pass options in a variadic way to con ### Set Image -By default, the image used is `mysql:8`. If you need to use a different image, you can use `WithImage` option. +By default, the image used is `mysql:8`. If you need to use a different image, you can use `testcontainers.WithImage` option. [Custom Image](../../modules/mysql/mysql_test.go) inside_block:withConfigFile diff --git a/docs/modules/postgres.md b/docs/modules/postgres.md index 9a493f74b3..999b3eb750 100644 --- a/docs/modules/postgres.md +++ b/docs/modules/postgres.md @@ -34,8 +34,8 @@ When starting the Postgres container, you can pass options in a variadic way to #### Image -If you need to set a different Postgres Docker image, you can use `WithImage` with a valid Docker image -for Postgres. E.g. `WithImage("docker.io/postgres:9.6")`. +If you need to set a different Postgres Docker image, you can use `testcontainers.WithImage` with a valid Docker image +for Postgres. E.g. `testcontainers.WithImage("docker.io/postgres:9.6")`. #### Initial Database diff --git a/modules/mysql/mysql.go b/modules/mysql/mysql.go index 8408075e21..505925a5ea 100644 --- a/modules/mysql/mysql.go +++ b/modules/mysql/mysql.go @@ -3,10 +3,11 @@ package mysql import ( "context" "fmt" - "github.com/testcontainers/testcontainers-go" - "github.com/testcontainers/testcontainers-go/wait" "path/filepath" "strings" + + "github.com/testcontainers/testcontainers-go" + "github.com/testcontainers/testcontainers-go/wait" ) const rootUser = "root" @@ -103,14 +104,12 @@ func (c *MySQLContainer) ConnectionString(ctx context.Context, args ...string) ( } // WithImage sets the image to be used for the mysql container +// Deprecated: use testcontainers.WithImage instead func WithImage(image string) func(req *testcontainers.ContainerRequest) { - return func(req *testcontainers.ContainerRequest) { - if image == "" { - image = "mysql:8" - } - - req.Image = image + if image == "" { + image = "mysql:8" } + return testcontainers.WithImage(image) } func WithUsername(username string) func(req *testcontainers.ContainerRequest) { diff --git a/modules/mysql/mysql_test.go b/modules/mysql/mysql_test.go index 19987ee264..b7f327a2f1 100644 --- a/modules/mysql/mysql_test.go +++ b/modules/mysql/mysql_test.go @@ -8,6 +8,7 @@ import ( // Import mysql into the scope of this package (required) _ "github.com/go-sql-driver/mysql" + "github.com/testcontainers/testcontainers-go" ) func TestMySQL(t *testing.T) { @@ -107,7 +108,7 @@ func TestMySQLWithConfigFile(t *testing.T) { ctx := context.Background() // withConfigFile { - container, err := StartContainer(ctx, WithImage("mysql:5.6.51"), + container, err := StartContainer(ctx, testcontainers.WithImage("mysql:5.6.51"), WithConfigFile("./testdata/my.cnf")) if err != nil { t.Fatal(err) diff --git a/modules/postgres/postgres.go b/modules/postgres/postgres.go index c33388561b..02e26660d8 100644 --- a/modules/postgres/postgres.go +++ b/modules/postgres/postgres.go @@ -57,14 +57,12 @@ func WithWaitStrategy(strategies ...wait.Strategy) func(req *testcontainers.Cont } // WithImage sets the image to be used for the postgres container +// Deprecated: use testcontainers.WithImage instead func WithImage(image string) func(req *testcontainers.ContainerRequest) { - return func(req *testcontainers.ContainerRequest) { - if image == "" { - image = defaultPostgresImage - } - - req.Image = image + if image == "" { + image = defaultPostgresImage } + return testcontainers.WithImage(image) } // WithConfigFile sets the config file to be used for the postgres container diff --git a/modules/postgres/postgres_test.go b/modules/postgres/postgres_test.go index 0dc520af8a..cba69ead1c 100644 --- a/modules/postgres/postgres_test.go +++ b/modules/postgres/postgres_test.go @@ -13,6 +13,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/wait" ) @@ -53,7 +54,7 @@ func TestPostgres(t *testing.T) { t.Run(tt.name, func(t *testing.T) { // postgresCreateContainer { container, err := StartContainer(ctx, - WithImage(tt.image), + testcontainers.WithImage(tt.image), WithDatabase(dbname), WithUsername(user), WithPassword(password), @@ -178,7 +179,7 @@ func TestWithInitScript(t *testing.T) { // withInitScripts { container, err := StartContainer(ctx, - WithImage("docker.io/postgres:15.2-alpine"), + testcontainers.WithImage("docker.io/postgres:15.2-alpine"), WithInitScripts(filepath.Join("testdata", "init-user-db.sh")), WithDatabase(dbname), WithUsername(user), From 94c7de3e350b1fb199eddf300bf359a292aa38b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Wed, 29 Mar 2023 16:46:04 +0200 Subject: [PATCH 09/42] chore: deprecated WithWaitStrategy from Postgres module, using core's --- docs/modules/postgres.md | 2 +- modules/postgres/postgres.go | 6 ++---- modules/postgres/postgres_test.go | 12 ++++++------ 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/docs/modules/postgres.md b/docs/modules/postgres.md index 999b3eb750..1fdfeae526 100644 --- a/docs/modules/postgres.md +++ b/docs/modules/postgres.md @@ -74,7 +74,7 @@ In the case you have a custom config file for Postgres, it's possible to copy th #### Wait Strategies Given you could need to wait for different conditions, in particular using a wait.ForSQL strategy, -the Postgres container exposes a `WithWaitStrategy` option to set a custom wait strategy. +the Postgres container exposes a `testcontainers.WithWaitStrategy` option to set a custom wait strategy. [Set Wait Strategy](../../modules/postgres/postgres_test.go) inside_block:withWaitStrategy diff --git a/modules/postgres/postgres.go b/modules/postgres/postgres.go index 02e26660d8..420b902264 100644 --- a/modules/postgres/postgres.go +++ b/modules/postgres/postgres.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "path/filepath" - "time" "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/wait" @@ -50,10 +49,9 @@ func (c *PostgresContainer) ConnectionString(ctx context.Context, args ...string type PostgresContainerOption func(req *testcontainers.ContainerRequest) // WithWaitStrategy sets the wait strategy for the postgres container +// Deprecated: use testcontainers.WithWaitStrategy instead func WithWaitStrategy(strategies ...wait.Strategy) func(req *testcontainers.ContainerRequest) { - return func(req *testcontainers.ContainerRequest) { - req.WaitingFor = wait.ForAll(strategies...).WithDeadline(1 * time.Minute) - } + return testcontainers.WithWaitStrategy(strategies...) } // WithImage sets the image to be used for the postgres container diff --git a/modules/postgres/postgres_test.go b/modules/postgres/postgres_test.go index cba69ead1c..16a00ae1da 100644 --- a/modules/postgres/postgres_test.go +++ b/modules/postgres/postgres_test.go @@ -58,7 +58,7 @@ func TestPostgres(t *testing.T) { WithDatabase(dbname), WithUsername(user), WithPassword(password), - WithWaitStrategy(tt.wait), + testcontainers.WithWaitStrategy(tt.wait), ) if err != nil { t.Fatal(err) @@ -110,7 +110,7 @@ func TestContainerWithWaitForSQL(t *testing.T) { WithDatabase(dbname), WithUsername(user), WithPassword(password), - WithWaitStrategy(wait.ForSQL(nat.Port(port), "postgres", dbURL)), + testcontainers.WithWaitStrategy(wait.ForSQL(nat.Port(port), "postgres", dbURL)), ) require.NoError(t, err) require.NotNil(t, container) @@ -123,7 +123,7 @@ func TestContainerWithWaitForSQL(t *testing.T) { WithDatabase(dbname), WithUsername(user), WithPassword(password), - WithWaitStrategy(wait.ForSQL(nat.Port(port), "postgres", dbURL).WithStartupTimeout(time.Second*5).WithQuery("SELECT 10")), + testcontainers.WithWaitStrategy(wait.ForSQL(nat.Port(port), "postgres", dbURL).WithStartupTimeout(time.Second*5).WithQuery("SELECT 10")), ) require.NoError(t, err) require.NotNil(t, container) @@ -135,7 +135,7 @@ func TestContainerWithWaitForSQL(t *testing.T) { WithDatabase(dbname), WithUsername(user), WithPassword(password), - WithWaitStrategy(wait.ForSQL(nat.Port(port), "postgres", dbURL).WithStartupTimeout(time.Second*5).WithQuery("SELECT 'a' from b")), + testcontainers.WithWaitStrategy(wait.ForSQL(nat.Port(port), "postgres", dbURL).WithStartupTimeout(time.Second*5).WithQuery("SELECT 'a' from b")), ) require.Error(t, err) require.Nil(t, container) @@ -151,7 +151,7 @@ func TestWithConfigFile(t *testing.T) { WithDatabase(dbname), WithUsername(user), WithPassword(password), - WithWaitStrategy(wait.ForLog("database system is ready to accept connections").WithOccurrence(2).WithStartupTimeout(5*time.Second)), + testcontainers.WithWaitStrategy(wait.ForLog("database system is ready to accept connections").WithOccurrence(2).WithStartupTimeout(5*time.Second)), ) if err != nil { t.Fatal(err) @@ -184,7 +184,7 @@ func TestWithInitScript(t *testing.T) { WithDatabase(dbname), WithUsername(user), WithPassword(password), - WithWaitStrategy(wait.ForLog("database system is ready to accept connections").WithOccurrence(2).WithStartupTimeout(5*time.Second)), + testcontainers.WithWaitStrategy(wait.ForLog("database system is ready to accept connections").WithOccurrence(2).WithStartupTimeout(5*time.Second)), ) if err != nil { t.Fatal(err) From a10c62e7cdf2aeb96792a84c0b7224b807f2a2b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Wed, 29 Mar 2023 19:31:43 +0200 Subject: [PATCH 10/42] chore: refine CustomizeRequestOption --- container.go | 12 +++++------- container_test.go | 31 ++++++++++++++++++++----------- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/container.go b/container.go index 7f6151466d..35bbb02281 100644 --- a/container.go +++ b/container.go @@ -135,18 +135,16 @@ type ContainerOption func(*containerOptions) // CustomizeContainerRequestOption is a type that can be used to configure the Testcontainers container request. // The passed request will be merged with the default one. -type CustomizeContainerRequestOption func(req ContainerRequest) ContainerRequest +type CustomizeContainerRequestOption func(req *ContainerRequest) // CustomizeContainerRequest returns a function that can be used to merge the passed container request with the one that is used by the container. // Slices and Maps will be appended. -func CustomizeContainerRequest(r ContainerRequest) CustomizeContainerRequestOption { - return func(req ContainerRequest) ContainerRequest { - if err := mergo.Merge(&req, r, mergo.WithOverride, mergo.WithAppendSlice); err != nil { +func CustomizeContainerRequest(src ContainerRequest) CustomizeContainerRequestOption { + return func(req *ContainerRequest) { + if err := mergo.Merge(req, &src, mergo.WithOverride, mergo.WithAppendSlice); err != nil { fmt.Printf("error merging container request, keeping the original one. Error: %v", err) - return req + return } - - return req } } diff --git a/container_test.go b/container_test.go index 1fef97e191..246d588727 100644 --- a/container_test.go +++ b/container_test.go @@ -438,7 +438,7 @@ func TestOverrideContainerRequest(t *testing.T) { }, } - merged := CustomizeContainerRequest(ContainerRequest{ + toBeMergedRequest := ContainerRequest{ Env: map[string]string{ "FOO": "FOO", }, @@ -449,14 +449,23 @@ func TestOverrideContainerRequest(t *testing.T) { "foo1": {"bar"}, }, WaitingFor: wait.ForLog("foo"), - })(req) - - assert.Equal(t, "FOO", merged.Env["FOO"]) - assert.Equal(t, "BAR", merged.Env["BAR"]) - assert.Equal(t, "bar", merged.Image) - assert.Equal(t, []string{"12345/tcp", "67890/tcp"}, merged.ExposedPorts) - assert.Equal(t, []string{"foo", "bar", "baaz", "foo1", "bar1"}, merged.Networks) - assert.Equal(t, []string{"foo0", "foo1", "foo2", "foo3"}, merged.NetworkAliases["foo"]) - assert.Equal(t, []string{"bar"}, merged.NetworkAliases["foo1"]) - assert.Equal(t, wait.ForLog("foo"), merged.WaitingFor) + } + + // the toBeMergedRequest should be merged into the req + CustomizeContainerRequest(toBeMergedRequest)(&req) + + // toBeMergedRequest should not be changed + assert.Equal(t, "", toBeMergedRequest.Env["BAR"]) + assert.Equal(t, 1, len(toBeMergedRequest.ExposedPorts)) + assert.Equal(t, "67890/tcp", toBeMergedRequest.ExposedPorts[0]) + + // req should be merged with toBeMergedRequest + assert.Equal(t, "FOO", req.Env["FOO"]) + assert.Equal(t, "BAR", req.Env["BAR"]) + assert.Equal(t, "bar", req.Image) + assert.Equal(t, []string{"12345/tcp", "67890/tcp"}, req.ExposedPorts) + assert.Equal(t, []string{"foo", "bar", "baaz", "foo1", "bar1"}, req.Networks) + assert.Equal(t, []string{"foo0", "foo1", "foo2", "foo3"}, req.NetworkAliases["foo"]) + assert.Equal(t, []string{"bar"}, req.NetworkAliases["foo1"]) + assert.Equal(t, wait.ForLog("foo"), req.WaitingFor) } From 445368599122fd9b887e07e862875e3e08984d77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Wed, 29 Mar 2023 19:34:44 +0200 Subject: [PATCH 11/42] fix: mysql image --- modules/mysql/mysql_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/mysql/mysql_test.go b/modules/mysql/mysql_test.go index b7f327a2f1..1915654aeb 100644 --- a/modules/mysql/mysql_test.go +++ b/modules/mysql/mysql_test.go @@ -108,7 +108,7 @@ func TestMySQLWithConfigFile(t *testing.T) { ctx := context.Background() // withConfigFile { - container, err := StartContainer(ctx, testcontainers.WithImage("mysql:5.6.51"), + container, err := StartContainer(ctx, testcontainers.WithImage("mysql:5.6"), WithConfigFile("./testdata/my.cnf")) if err != nil { t.Fatal(err) From 245c5e18b78e2ba28517c466370f5dd7f472af69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Wed, 29 Mar 2023 19:35:57 +0200 Subject: [PATCH 12/42] Revert "chore: use new container request customisation in localstack" This reverts commit 376dc26dd40687d1b340bfbf62a2c30669847b23. --- docs/modules/localstack.md | 18 ++++++++++----- modules/localstack/localstack.go | 22 +++++++----------- modules/localstack/localstack_test.go | 25 ++++++++++++-------- modules/localstack/types.go | 33 ++++++++++++--------------- modules/localstack/v1/s3_test.go | 4 ++-- modules/localstack/v2/s3_test.go | 4 ++-- 6 files changed, 54 insertions(+), 52 deletions(-) diff --git a/docs/modules/localstack.md b/docs/modules/localstack.md index bfb4b0ee92..7aada1f93f 100644 --- a/docs/modules/localstack.md +++ b/docs/modules/localstack.md @@ -19,7 +19,7 @@ Running LocalStack as a stand-in for multiple AWS services during a test: Environment variables listed in [Localstack's README](https://github.com/localstack/localstack#configurations) may be used to customize Localstack's configuration. -Use the `testcontainers.CustomizeContainerRequest` option when creating the LocalStack `Container` to apply configuration settings. +Use the `OverrideContainerRequest` option when creating the `LocalStackContainer` to apply configuration settings. ## Creating a client using the AWS SDK for Go @@ -64,21 +64,21 @@ Testcontainers will inform Localstack of the best hostname automatically, using The LocalStack module exposes one single function to create the LocalStack container, and this function receives two parameters: ```golang -func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeContainerRequestOption) (*Container, error) { +func StartContainer(ctx context.Context, overrideReq OverrideContainerRequestOption) (*LocalStackContainer, error) ``` - `context.Context` -- `testcontainers.CustomizeContainerRequestOption` +- `OverrideContainerRequestOption` -### CustomizeContainerRequestOption +### OverrideContainerRequestOption -The variadic `testcontainers.CustomizeContainerRequestOption` functional option represents a way to override the default LocalStack container request: +The `OverrideContainerRequestOption` functional option represents a way to override the default LocalStack container request: [Default container request](../../modules/localstack/localstack.go) inside_block:defaultContainerRequest -With simply passing your own instance of an `testcontainers.CustomizeContainerRequest` type to the `RunContainer` 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. +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: @@ -86,6 +86,12 @@ In the following example you check how it's possible to set certain environment [Overriding the default container request](../../modules/localstack/localstack_test.go) inside_block:withNetwork +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. + + +[Skip overriding the default container request](../../modules/localstack/localstack_test.go) inside_block:noopOverrideContainerRequest + + ## 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: diff --git a/modules/localstack/localstack.go b/modules/localstack/localstack.go index 686b87437d..4c36a3f71b 100644 --- a/modules/localstack/localstack.go +++ b/modules/localstack/localstack.go @@ -40,9 +40,9 @@ func isLegacyMode(image string) bool { return true } -// RunContainer creates an instance of the LocalStack container type, being possible to pass a custom request and options: +// StartContainer creates an instance of the LocalStack container type, being possible to pass a custom request and options: // - overrideReq: a function that can be used to override the default container request, usually used to set the image version, environment variables for localstack, etc. -func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeContainerRequestOption) (*Container, error) { +func StartContainer(ctx context.Context, overrideReq OverrideContainerRequestOption) (*LocalStackContainer, error) { // defaultContainerRequest { req := testcontainers.ContainerRequest{ Image: fmt.Sprintf("localstack/localstack:%s", defaultVersion), @@ -53,13 +53,14 @@ func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeContainer } // } - localStackReq := ContainerRequest{ + localStackReq := LocalStackContainerRequest{ ContainerRequest: req, } // first, when needed, we merge the user request with the default one - for _, opt := range opts { - localStackReq.ContainerRequest = opt(localStackReq.ContainerRequest) + if overrideReq != nil { + merged := overrideReq(localStackReq.ContainerRequest) + localStackReq.ContainerRequest = merged } if isLegacyMode(localStackReq.Image) { @@ -80,20 +81,13 @@ func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeContainer return nil, err } - c := &Container{ + c := &LocalStackContainer{ Container: container, } return c, nil } -// StartContainer creates an instance of the LocalStack container type, being possible to pass a custom request and options: -// - overrideReq: a function that can be used to override the default container request, usually used to set the image version, environment variables for localstack, etc. -// Deprecated use RunContainer instead -func StartContainer(ctx context.Context, overrideReq OverrideContainerRequestOption) (*Container, error) { - return RunContainer(ctx, testcontainers.CustomizeContainerRequestOption(overrideReq)) -} - -func configureDockerHost(req *ContainerRequest) (reason string, err error) { +func configureDockerHost(req *LocalStackContainerRequest) (reason string, err error) { err = nil reason = "" diff --git a/modules/localstack/localstack_test.go b/modules/localstack/localstack_test.go index 456f5b4974..fa1c7ca410 100644 --- a/modules/localstack/localstack_test.go +++ b/modules/localstack/localstack_test.go @@ -10,8 +10,8 @@ import ( "github.com/testcontainers/testcontainers-go" ) -func generateContainerRequest() *ContainerRequest { - return &ContainerRequest{ +func generateContainerRequest() *LocalStackContainerRequest { + return &LocalStackContainerRequest{ ContainerRequest: testcontainers.ContainerRequest{ Env: map[string]string{}, ExposedPorts: []string{}, @@ -91,13 +91,13 @@ func TestIsLegacyMode(t *testing.T) { } } -func TestRunContainer(t *testing.T) { +func TestStart(t *testing.T) { ctx := context.Background() // withoutNetwork { - container, err := RunContainer( + container, err := StartContainer( ctx, - testcontainers.CustomizeContainerRequest(testcontainers.ContainerRequest{ + OverrideContainerRequest(testcontainers.ContainerRequest{ Image: fmt.Sprintf("localstack/localstack:%s", defaultVersion), }), ) @@ -122,15 +122,20 @@ func TestRunContainer(t *testing.T) { }) } -func TestRunContainerWithoutOverride(t *testing.T) { +func TestStartWithoutOverride(t *testing.T) { + // noopOverrideContainerRequest { ctx := context.Background() - container, err := RunContainer(ctx) + container, err := StartContainer( + ctx, + NoopOverrideContainerRequest, + ) require.Nil(t, err) assert.NotNil(t, container) + // } } -func TestRunContainerWithNetwork(t *testing.T) { +func TestStartWithNetwork(t *testing.T) { // withNetwork { ctx := context.Background() @@ -142,9 +147,9 @@ func TestRunContainerWithNetwork(t *testing.T) { require.Nil(t, err) assert.NotNil(t, nw) - container, err := RunContainer( + container, err := StartContainer( ctx, - testcontainers.CustomizeContainerRequest(testcontainers.ContainerRequest{ + OverrideContainerRequest(testcontainers.ContainerRequest{ Image: "localstack/localstack:0.13.0", Env: map[string]string{"SERVICES": "s3,sqs"}, Networks: []string{"localstack-network"}, diff --git a/modules/localstack/types.go b/modules/localstack/types.go index 5eca3981c9..9f08095d69 100644 --- a/modules/localstack/types.go +++ b/modules/localstack/types.go @@ -1,43 +1,40 @@ package localstack import ( + "fmt" + + "github.com/imdario/mergo" "github.com/testcontainers/testcontainers-go" ) -// Container represents the LocalStack container type used in the module -type Container struct { - testcontainers.Container -} - -// Deprecated: use Container instead +// LocalStackContainer represents the LocalStack container type used in the module type LocalStackContainer struct { - Container + testcontainers.Container } -// ContainerRequest represents the LocalStack container request type used in the module +// LocalStackContainerRequest represents the LocalStack container request type used in the module // to configure the container -type ContainerRequest struct { - testcontainers.ContainerRequest -} - -// Deprecated: use ContainerRequest instead type LocalStackContainerRequest struct { - ContainerRequest + testcontainers.ContainerRequest } // OverrideContainerRequestOption is a type that can be used to configure the Testcontainers container request. // The passed request will be merged with the default one. -// Deprecated: use testcontainers.CustomizeContainerRequestOption instead type OverrideContainerRequestOption func(req testcontainers.ContainerRequest) testcontainers.ContainerRequest // NoopOverrideContainerRequest returns a helper function that does not override the container request -// Deprecated var NoopOverrideContainerRequest = func(req testcontainers.ContainerRequest) testcontainers.ContainerRequest { return req } // OverrideContainerRequest returns a function that can be used to merge the passed container request with one that is created by the LocalStack container -// Deprecated: use testcontainers.CustomizeContainerRequestOption instead func OverrideContainerRequest(r testcontainers.ContainerRequest) func(req testcontainers.ContainerRequest) testcontainers.ContainerRequest { - return testcontainers.CustomizeContainerRequest(r) + return func(req testcontainers.ContainerRequest) testcontainers.ContainerRequest { + if err := mergo.Merge(&req, r, mergo.WithOverride); err != nil { + fmt.Printf("error merging container request %v. Keeping the default one: %v", err, req) + return req + } + + return req + } } diff --git a/modules/localstack/v1/s3_test.go b/modules/localstack/v1/s3_test.go index 8895f64123..3d795b5e1f 100644 --- a/modules/localstack/v1/s3_test.go +++ b/modules/localstack/v1/s3_test.go @@ -28,7 +28,7 @@ const ( // awsSDKClientV1 { // awsSession returns a new AWS session for the given service. To retrieve the specific AWS service client, use the // session's client method, e.g. s3manager.NewUploader(session). -func awsSession(ctx context.Context, l *localstack.Container) (*session.Session, error) { +func awsSession(ctx context.Context, l *localstack.LocalStackContainer) (*session.Session, error) { mappedPort, err := l.MappedPort(ctx, nat.Port("4566/tcp")) if err != nil { return &session.Session{}, err @@ -62,7 +62,7 @@ func TestS3(t *testing.T) { ctx := context.Background() // localStackCreateContainer { - container, err := localstack.RunContainer(ctx) + container, err := localstack.StartContainer(ctx, localstack.NoopOverrideContainerRequest) require.Nil(t, err) // } diff --git a/modules/localstack/v2/s3_test.go b/modules/localstack/v2/s3_test.go index fcb0eada8e..c80d534b39 100644 --- a/modules/localstack/v2/s3_test.go +++ b/modules/localstack/v2/s3_test.go @@ -25,7 +25,7 @@ const ( ) // awsSDKClientV2 { -func s3Client(ctx context.Context, l *localstack.Container) (*s3.Client, error) { +func s3Client(ctx context.Context, l *localstack.LocalStackContainer) (*s3.Client, error) { mappedPort, err := l.MappedPort(ctx, nat.Port("4566/tcp")) if err != nil { return nil, err @@ -72,7 +72,7 @@ func s3Client(ctx context.Context, l *localstack.Container) (*s3.Client, error) func TestS3(t *testing.T) { ctx := context.Background() - container, err := localstack.RunContainer(ctx) + container, err := localstack.StartContainer(ctx, localstack.NoopOverrideContainerRequest) require.Nil(t, err) s3Client, err := s3Client(ctx, container) From 805ea5a8435f2aea5272d604acdfee1de0794aaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Wed, 29 Mar 2023 20:03:25 +0200 Subject: [PATCH 13/42] chore: simplify postgres types --- docs/modules/postgres.md | 4 ++-- modules/postgres/postgres.go | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/docs/modules/postgres.md b/docs/modules/postgres.md index 1fdfeae526..95a594c63b 100644 --- a/docs/modules/postgres.md +++ b/docs/modules/postgres.md @@ -19,11 +19,11 @@ go get github.com/testcontainers/testcontainers-go/modules/postgres The Postgres module exposes one entrypoint function to create the Postgres container, and this function receives two parameters: ```golang -func StartContainer(ctx context.Context, opts ...PostgresContainerOption) (*PostgresContainer, error) +func StartContainer(ctx context.Context, opts ...testcontainers.CustomizeContainerRequestOption) (*PostgresContainer, error) ``` - `context.Context`, the Go context. -- `PostgresContainerOption`, a variad argument for passing options. +- `testcontainers.CustomizeContainerRequestOption`, a variadic argument for passing options. ### Container Options diff --git a/modules/postgres/postgres.go b/modules/postgres/postgres.go index 420b902264..7332686ea7 100644 --- a/modules/postgres/postgres.go +++ b/modules/postgres/postgres.go @@ -45,9 +45,6 @@ func (c *PostgresContainer) ConnectionString(ctx context.Context, args ...string return connStr, nil } -// PostgresContainerOption is a function that configures the postgres container, affecting the container request -type PostgresContainerOption func(req *testcontainers.ContainerRequest) - // WithWaitStrategy sets the wait strategy for the postgres container // Deprecated: use testcontainers.WithWaitStrategy instead func WithWaitStrategy(strategies ...wait.Strategy) func(req *testcontainers.ContainerRequest) { @@ -129,7 +126,7 @@ func WithUsername(user string) func(req *testcontainers.ContainerRequest) { } // StartContainer creates an instance of the postgres container type -func StartContainer(ctx context.Context, opts ...PostgresContainerOption) (*PostgresContainer, error) { +func StartContainer(ctx context.Context, opts ...testcontainers.CustomizeContainerRequestOption) (*PostgresContainer, error) { req := testcontainers.ContainerRequest{ Image: defaultPostgresImage, Env: map[string]string{ From 01c10d2bf14bc7f824bd3e6d148145f6fc0215c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Thu, 30 Mar 2023 10:07:34 +0200 Subject: [PATCH 14/42] chore: try neo4j in ubuntu-22.04 --- .github/workflows/module-neo4j.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/module-neo4j.yml b/.github/workflows/module-neo4j.yml index 07f4f55727..46bf3a5cde 100644 --- a/.github/workflows/module-neo4j.yml +++ b/.github/workflows/module-neo4j.yml @@ -21,7 +21,7 @@ jobs: strategy: matrix: go-version: [1.19.x, 1.x] - runs-on: "ubuntu-latest" + runs-on: "ubuntu-22.04" steps: - name: Set up Go From 618f504e605a1045ff8c6d63f09b07ce544386e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Thu, 30 Mar 2023 10:21:50 +0200 Subject: [PATCH 15/42] chore: try neo4j in ubuntu-20.04 --- .github/workflows/module-neo4j.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/module-neo4j.yml b/.github/workflows/module-neo4j.yml index 46bf3a5cde..aed8e4465d 100644 --- a/.github/workflows/module-neo4j.yml +++ b/.github/workflows/module-neo4j.yml @@ -21,7 +21,7 @@ jobs: strategy: matrix: go-version: [1.19.x, 1.x] - runs-on: "ubuntu-22.04" + runs-on: "ubuntu-20.04" steps: - name: Set up Go From 3c2b07e7d555b755f6e3d88b44d42965273c5b6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Thu, 30 Mar 2023 13:56:23 +0200 Subject: [PATCH 16/42] Revert "chore: try neo4j in ubuntu-20.04" This reverts commit 28880402ad1cac5c815069172e5df6e04a6e79ae. --- .github/workflows/module-neo4j.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/module-neo4j.yml b/.github/workflows/module-neo4j.yml index aed8e4465d..46bf3a5cde 100644 --- a/.github/workflows/module-neo4j.yml +++ b/.github/workflows/module-neo4j.yml @@ -21,7 +21,7 @@ jobs: strategy: matrix: go-version: [1.19.x, 1.x] - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-22.04" steps: - name: Set up Go From 80d5fb62eb20d45d733775e76e2647aabec3e29f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Thu, 30 Mar 2023 13:56:26 +0200 Subject: [PATCH 17/42] Revert "chore: try neo4j in ubuntu-22.04" This reverts commit 1ceb465a145be23dcee3efe42c8320e6386d4427. --- .github/workflows/module-neo4j.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/module-neo4j.yml b/.github/workflows/module-neo4j.yml index 46bf3a5cde..07f4f55727 100644 --- a/.github/workflows/module-neo4j.yml +++ b/.github/workflows/module-neo4j.yml @@ -21,7 +21,7 @@ jobs: strategy: matrix: go-version: [1.19.x, 1.x] - runs-on: "ubuntu-22.04" + runs-on: "ubuntu-latest" steps: - name: Set up Go From ed4329078b809cbcdb7a2f4fdde377d15970222b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Thu, 30 Mar 2023 16:34:10 +0200 Subject: [PATCH 18/42] fix: update go mod for localstack --- modules/localstack/go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/localstack/go.mod b/modules/localstack/go.mod index 5e79e68476..7bc621e8f8 100644 --- a/modules/localstack/go.mod +++ b/modules/localstack/go.mod @@ -9,6 +9,7 @@ require ( github.com/aws/aws-sdk-go-v2/credentials v1.13.18 github.com/aws/aws-sdk-go-v2/service/s3 v1.31.0 github.com/docker/go-connections v0.4.0 + github.com/imdario/mergo v0.3.14 github.com/stretchr/testify v1.8.2 github.com/testcontainers/testcontainers-go v0.19.0 golang.org/x/mod v0.9.0 @@ -46,7 +47,6 @@ require ( github.com/golang/protobuf v1.5.2 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.3.0 // indirect - github.com/imdario/mergo v0.3.14 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/klauspost/compress v1.15.9 // indirect github.com/magiconair/properties v1.8.7 // indirect From d3683df6022fa28a9be4c2bd4919653c676c629c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Thu, 30 Mar 2023 16:40:00 +0200 Subject: [PATCH 19/42] chore: simplify types in mysql module --- modules/mysql/mysql.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/mysql/mysql.go b/modules/mysql/mysql.go index 505925a5ea..b3914e4c7a 100644 --- a/modules/mysql/mysql.go +++ b/modules/mysql/mysql.go @@ -24,10 +24,8 @@ type MySQLContainer struct { database string } -type MySQLContainerOption func(req *testcontainers.ContainerRequest) - // StartContainer creates an instance of the MySQL container type -func StartContainer(ctx context.Context, opts ...MySQLContainerOption) (*MySQLContainer, error) { +func StartContainer(ctx context.Context, opts ...testcontainers.CustomizeContainerRequestOption) (*MySQLContainer, error) { req := testcontainers.ContainerRequest{ Image: defaultImage, ExposedPorts: []string{"3306/tcp", "33060/tcp"}, From 280a42207f18c486a118728382c4a50dca14316f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Fri, 31 Mar 2023 16:19:20 +0200 Subject: [PATCH 20/42] chore: use types --- container.go | 6 +++--- modules/mysql/mysql.go | 19 +++++-------------- modules/postgres/postgres.go | 22 +++------------------- modules/redis/redis.go | 18 ++++-------------- modules/redis/redis_test.go | 2 +- 5 files changed, 16 insertions(+), 51 deletions(-) diff --git a/container.go b/container.go index 35bbb02281..0b3e820c51 100644 --- a/container.go +++ b/container.go @@ -149,19 +149,19 @@ func CustomizeContainerRequest(src ContainerRequest) CustomizeContainerRequestOp } // WithImage sets the image for a container -func WithImage(image string) func(req *ContainerRequest) { +func WithImage(image string) CustomizeContainerRequestOption { return func(req *ContainerRequest) { req.Image = image } } // WithWaitStrategy sets the wait strategy for a container, using 1 minute as deadline -func WithWaitStrategy(strategies ...wait.Strategy) func(req *ContainerRequest) { +func WithWaitStrategy(strategies ...wait.Strategy) CustomizeContainerRequestOption { return WithWaitStrategyAndDuration(1*time.Minute, strategies...) } // WithWaitStrategy sets the wait strategy for a container, including deadline -func WithWaitStrategyAndDuration(deadline time.Duration, strategies ...wait.Strategy) func(req *ContainerRequest) { +func WithWaitStrategyAndDuration(deadline time.Duration, strategies ...wait.Strategy) CustomizeContainerRequestOption { return func(req *ContainerRequest) { req.WaitingFor = wait.ForAll(strategies...).WithDeadline(deadline) } diff --git a/modules/mysql/mysql.go b/modules/mysql/mysql.go index b3914e4c7a..8a0b011a93 100644 --- a/modules/mysql/mysql.go +++ b/modules/mysql/mysql.go @@ -101,34 +101,25 @@ func (c *MySQLContainer) ConnectionString(ctx context.Context, args ...string) ( return connectionString, nil } -// WithImage sets the image to be used for the mysql container -// Deprecated: use testcontainers.WithImage instead -func WithImage(image string) func(req *testcontainers.ContainerRequest) { - if image == "" { - image = "mysql:8" - } - return testcontainers.WithImage(image) -} - -func WithUsername(username string) func(req *testcontainers.ContainerRequest) { +func WithUsername(username string) testcontainers.CustomizeContainerRequestOption { return func(req *testcontainers.ContainerRequest) { req.Env["MYSQL_USER"] = username } } -func WithPassword(password string) func(req *testcontainers.ContainerRequest) { +func WithPassword(password string) testcontainers.CustomizeContainerRequestOption { return func(req *testcontainers.ContainerRequest) { req.Env["MYSQL_PASSWORD"] = password } } -func WithDatabase(database string) func(req *testcontainers.ContainerRequest) { +func WithDatabase(database string) testcontainers.CustomizeContainerRequestOption { return func(req *testcontainers.ContainerRequest) { req.Env["MYSQL_DATABASE"] = database } } -func WithConfigFile(configFile string) func(req *testcontainers.ContainerRequest) { +func WithConfigFile(configFile string) testcontainers.CustomizeContainerRequestOption { return func(req *testcontainers.ContainerRequest) { cf := testcontainers.ContainerFile{ HostFilePath: configFile, @@ -139,7 +130,7 @@ func WithConfigFile(configFile string) func(req *testcontainers.ContainerRequest } } -func WithScripts(scripts ...string) func(req *testcontainers.ContainerRequest) { +func WithScripts(scripts ...string) testcontainers.CustomizeContainerRequestOption { return func(req *testcontainers.ContainerRequest) { var initScripts []testcontainers.ContainerFile for _, script := range scripts { diff --git a/modules/postgres/postgres.go b/modules/postgres/postgres.go index 7332686ea7..971360b7a7 100644 --- a/modules/postgres/postgres.go +++ b/modules/postgres/postgres.go @@ -6,7 +6,6 @@ import ( "path/filepath" "github.com/testcontainers/testcontainers-go" - "github.com/testcontainers/testcontainers-go/wait" ) const defaultUser = "postgres" @@ -45,25 +44,10 @@ func (c *PostgresContainer) ConnectionString(ctx context.Context, args ...string return connStr, nil } -// WithWaitStrategy sets the wait strategy for the postgres container -// Deprecated: use testcontainers.WithWaitStrategy instead -func WithWaitStrategy(strategies ...wait.Strategy) func(req *testcontainers.ContainerRequest) { - return testcontainers.WithWaitStrategy(strategies...) -} - -// WithImage sets the image to be used for the postgres container -// Deprecated: use testcontainers.WithImage instead -func WithImage(image string) func(req *testcontainers.ContainerRequest) { - if image == "" { - image = defaultPostgresImage - } - return testcontainers.WithImage(image) -} - // WithConfigFile sets the config file to be used for the postgres container // It will also set the "config_file" parameter to the path of the config file // as a command line argument to the container -func WithConfigFile(cfg string) func(req *testcontainers.ContainerRequest) { +func WithConfigFile(cfg string) testcontainers.CustomizeContainerRequestOption { return func(req *testcontainers.ContainerRequest) { cfgFile := testcontainers.ContainerFile{ HostFilePath: cfg, @@ -80,14 +64,14 @@ func WithConfigFile(cfg string) func(req *testcontainers.ContainerRequest) { // WithDatabase sets the initial database to be created when the container starts // It can be used to define a different name for the default database that is created when the image is first started. // If it is not specified, then the value of WithUser will be used. -func WithDatabase(dbName string) func(req *testcontainers.ContainerRequest) { +func WithDatabase(dbName string) testcontainers.CustomizeContainerRequestOption { return func(req *testcontainers.ContainerRequest) { req.Env["POSTGRES_DB"] = dbName } } // WithInitScripts sets the init scripts to be run when the container starts -func WithInitScripts(scripts ...string) func(req *testcontainers.ContainerRequest) { +func WithInitScripts(scripts ...string) testcontainers.CustomizeContainerRequestOption { return func(req *testcontainers.ContainerRequest) { initScripts := []testcontainers.ContainerFile{} for _, script := range scripts { diff --git a/modules/redis/redis.go b/modules/redis/redis.go index e0728f5336..eb706d5178 100644 --- a/modules/redis/redis.go +++ b/modules/redis/redis.go @@ -47,7 +47,7 @@ func (c *RedisContainer) ConnectionString(ctx context.Context) (string, error) { } // StartContainer creates an instance of the Redis container type -func StartContainer(ctx context.Context, opts ...RedisContainerOption) (*RedisContainer, error) { +func StartContainer(ctx context.Context, opts ...testcontainers.CustomizeContainerRequestOption) (*RedisContainer, error) { req := testcontainers.ContainerRequest{ Image: defaultImage, ExposedPorts: []string{"6379/tcp"}, @@ -69,19 +69,9 @@ func StartContainer(ctx context.Context, opts ...RedisContainerOption) (*RedisCo return &RedisContainer{Container: container}, nil } -// RedisContainerOption is a function that configures the redis container, affecting the container request -type RedisContainerOption func(req *testcontainers.ContainerRequest) - -// WithImage sets the image to be used for the redis container -func WithImage(image string) func(req *testcontainers.ContainerRequest) { - return func(req *testcontainers.ContainerRequest) { - req.Image = image - } -} - // WithConfigFile sets the config file to be used for the redis container, and sets the command to run the redis server // using the passed config file -func WithConfigFile(configFile string) func(req *testcontainers.ContainerRequest) { +func WithConfigFile(configFile string) testcontainers.CustomizeContainerRequestOption { const defaultConfigFile = "/usr/local/redis.conf" return func(req *testcontainers.ContainerRequest) { @@ -110,7 +100,7 @@ func WithConfigFile(configFile string) func(req *testcontainers.ContainerRequest // WithLogLevel sets the log level for the redis server process // See https://redis.io/docs/reference/modules/modules-api-ref/#redismodule_log for more information. -func WithLogLevel(level LogLevel) func(req *testcontainers.ContainerRequest) { +func WithLogLevel(level LogLevel) testcontainers.CustomizeContainerRequestOption { return func(req *testcontainers.ContainerRequest) { processRedisServerArgs(req, []string{"--loglevel", string(level)}) } @@ -120,7 +110,7 @@ func WithLogLevel(level LogLevel) func(req *testcontainers.ContainerRequest) { // save the dataset every N seconds if there are at least M changes in the dataset. // This method allows Redis to benefit from copy-on-write semantics. // See https://redis.io/docs/management/persistence/#snapshotting for more information. -func WithSnapshotting(seconds int, changedKeys int) func(req *testcontainers.ContainerRequest) { +func WithSnapshotting(seconds int, changedKeys int) testcontainers.CustomizeContainerRequestOption { if changedKeys < 1 { changedKeys = 1 } diff --git a/modules/redis/redis_test.go b/modules/redis/redis_test.go index 79d615cf7c..eb94f85e25 100644 --- a/modules/redis/redis_test.go +++ b/modules/redis/redis_test.go @@ -77,7 +77,7 @@ func TestRedisWithImage(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // withImage { - redisContainer, err := StartContainer(ctx, WithImage(tt.image), WithConfigFile(filepath.Join("testdata", "redis6.conf"))) + redisContainer, err := StartContainer(ctx, testcontainers.WithImage(tt.image), WithConfigFile(filepath.Join("testdata", "redis6.conf"))) require.NoError(t, err) t.Cleanup(func() { if err := redisContainer.Terminate(ctx); err != nil { From 8f5b8bf57540ebc218cddecce48782dce30ab0f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Mon, 3 Apr 2023 08:10:17 +0200 Subject: [PATCH 21/42] chore: simplify type name even more --- container.go | 14 +++++++------- container_test.go | 2 +- docs/modules/index.md | 4 ++-- docs/modules/mysql.md | 4 ++-- docs/modules/postgres.md | 4 ++-- modules/mysql/mysql.go | 14 +++++++------- modules/mysql/mysql_test.go | 10 +++++----- modules/postgres/postgres.go | 10 +++++----- modules/postgres/postgres_test.go | 12 ++++++------ modules/redis/redis.go | 8 ++++---- 10 files changed, 41 insertions(+), 41 deletions(-) diff --git a/container.go b/container.go index 0b3e820c51..8c6678dee9 100644 --- a/container.go +++ b/container.go @@ -133,13 +133,13 @@ type containerOptions struct { // functional option for setting the reaper image type ContainerOption func(*containerOptions) -// CustomizeContainerRequestOption is a type that can be used to configure the Testcontainers container request. +// CustomizeRequestOption is a type that can be used to configure the Testcontainers container request. // The passed request will be merged with the default one. -type CustomizeContainerRequestOption func(req *ContainerRequest) +type CustomizeRequestOption func(req *ContainerRequest) -// CustomizeContainerRequest returns a function that can be used to merge the passed container request with the one that is used by the container. +// CustomizeRequest returns a function that can be used to merge the passed container request with the one that is used by the container. // Slices and Maps will be appended. -func CustomizeContainerRequest(src ContainerRequest) CustomizeContainerRequestOption { +func CustomizeRequest(src ContainerRequest) CustomizeRequestOption { return func(req *ContainerRequest) { if err := mergo.Merge(req, &src, mergo.WithOverride, mergo.WithAppendSlice); err != nil { fmt.Printf("error merging container request, keeping the original one. Error: %v", err) @@ -149,19 +149,19 @@ func CustomizeContainerRequest(src ContainerRequest) CustomizeContainerRequestOp } // WithImage sets the image for a container -func WithImage(image string) CustomizeContainerRequestOption { +func WithImage(image string) CustomizeRequestOption { return func(req *ContainerRequest) { req.Image = image } } // WithWaitStrategy sets the wait strategy for a container, using 1 minute as deadline -func WithWaitStrategy(strategies ...wait.Strategy) CustomizeContainerRequestOption { +func WithWaitStrategy(strategies ...wait.Strategy) CustomizeRequestOption { return WithWaitStrategyAndDuration(1*time.Minute, strategies...) } // WithWaitStrategy sets the wait strategy for a container, including deadline -func WithWaitStrategyAndDuration(deadline time.Duration, strategies ...wait.Strategy) CustomizeContainerRequestOption { +func WithWaitStrategyAndDuration(deadline time.Duration, strategies ...wait.Strategy) CustomizeRequestOption { return func(req *ContainerRequest) { req.WaitingFor = wait.ForAll(strategies...).WithDeadline(deadline) } diff --git a/container_test.go b/container_test.go index 246d588727..54b335f422 100644 --- a/container_test.go +++ b/container_test.go @@ -452,7 +452,7 @@ func TestOverrideContainerRequest(t *testing.T) { } // the toBeMergedRequest should be merged into the req - CustomizeContainerRequest(toBeMergedRequest)(&req) + CustomizeRequest(toBeMergedRequest)(&req) // toBeMergedRequest should not be changed assert.Equal(t, "", toBeMergedRequest.Env["BAR"]) diff --git a/docs/modules/index.md b/docs/modules/index.md index d202ee51dc..0b7a52bc10 100644 --- a/docs/modules/index.md +++ b/docs/modules/index.md @@ -66,11 +66,11 @@ We are going to propose a set of steps to follow when adding types and methods t - Make sure a public `Container` type exists for the module. This type have to use composition to embed the `testcontainers.Container` type, inheriting all the methods from it. - Make sure a `RunContainer` function exists and is public. This function is the entrypoint to the module and will define the initial values for a `testcontainers.ContainerRequest` struct, including the image, the default exposed ports, wait strategies, etc. Therefore, the function must initialise the container request with the default values. -- Define container options for the module. We consider that a best practice for the options is to return a function that returns a modified `testcontainers.ContainerRequest` type, and for that, the library already provides with a `testcontainers.CustomizeContainerRequestOption` type representing this function signature. +- Define container options for the module. We consider that a best practice for the options is to return a function that returns a modified `testcontainers.ContainerRequest` type, and for that, the library already provides with a `testcontainers.CustomizeRequestOption` type representing this function signature. - The options will be passed to the `RunContainer` function as variadic arguments after the Go context, and they will be processed right after defining the initial `testcontainers.ContainerRequest` struct using a for loop. ```golang -func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeContainerRequestOption) (*Container, error) {...} +func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeRequestOption) (*Container, error) {...} ``` - If needed, define public methods to extract information from the running container, using the `Container` type as receiver. E.g. a connection string to access a database: diff --git a/docs/modules/mysql.md b/docs/modules/mysql.md index c23704293d..8ce8a6cb1e 100644 --- a/docs/modules/mysql.md +++ b/docs/modules/mysql.md @@ -19,11 +19,11 @@ go get github.com/testcontainers/testcontainers-go/modules/mysql The MySQL module exposes one entrypoint function to create the container, and this function receives two parameters: ```golang -func StartContainer(ctx context.Context, opts ...Option) (*MySQLContainer, error) { +func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeRequestOption) (*MySQLContainer, error) { ``` - `context.Context`, the Go context. -- `Option`, a variad argument for passing options. +- `testcontainers.CustomizeRequestOption`, a variad argument for passing options. ## Container Options diff --git a/docs/modules/postgres.md b/docs/modules/postgres.md index 95a594c63b..bc7dd502a1 100644 --- a/docs/modules/postgres.md +++ b/docs/modules/postgres.md @@ -19,11 +19,11 @@ go get github.com/testcontainers/testcontainers-go/modules/postgres The Postgres module exposes one entrypoint function to create the Postgres container, and this function receives two parameters: ```golang -func StartContainer(ctx context.Context, opts ...testcontainers.CustomizeContainerRequestOption) (*PostgresContainer, error) +func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeRequestOption) (*PostgresContainer, error) ``` - `context.Context`, the Go context. -- `testcontainers.CustomizeContainerRequestOption`, a variadic argument for passing options. +- `testcontainers.CustomizeRequestOption`, a variadic argument for passing options. ### Container Options diff --git a/modules/mysql/mysql.go b/modules/mysql/mysql.go index 8a0b011a93..b4c66bfbb9 100644 --- a/modules/mysql/mysql.go +++ b/modules/mysql/mysql.go @@ -24,8 +24,8 @@ type MySQLContainer struct { database string } -// StartContainer creates an instance of the MySQL container type -func StartContainer(ctx context.Context, opts ...testcontainers.CustomizeContainerRequestOption) (*MySQLContainer, error) { +// RunContainer creates an instance of the MySQL container type +func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeRequestOption) (*MySQLContainer, error) { req := testcontainers.ContainerRequest{ Image: defaultImage, ExposedPorts: []string{"3306/tcp", "33060/tcp"}, @@ -101,25 +101,25 @@ func (c *MySQLContainer) ConnectionString(ctx context.Context, args ...string) ( return connectionString, nil } -func WithUsername(username string) testcontainers.CustomizeContainerRequestOption { +func WithUsername(username string) testcontainers.CustomizeRequestOption { return func(req *testcontainers.ContainerRequest) { req.Env["MYSQL_USER"] = username } } -func WithPassword(password string) testcontainers.CustomizeContainerRequestOption { +func WithPassword(password string) testcontainers.CustomizeRequestOption { return func(req *testcontainers.ContainerRequest) { req.Env["MYSQL_PASSWORD"] = password } } -func WithDatabase(database string) testcontainers.CustomizeContainerRequestOption { +func WithDatabase(database string) testcontainers.CustomizeRequestOption { return func(req *testcontainers.ContainerRequest) { req.Env["MYSQL_DATABASE"] = database } } -func WithConfigFile(configFile string) testcontainers.CustomizeContainerRequestOption { +func WithConfigFile(configFile string) testcontainers.CustomizeRequestOption { return func(req *testcontainers.ContainerRequest) { cf := testcontainers.ContainerFile{ HostFilePath: configFile, @@ -130,7 +130,7 @@ func WithConfigFile(configFile string) testcontainers.CustomizeContainerRequestO } } -func WithScripts(scripts ...string) testcontainers.CustomizeContainerRequestOption { +func WithScripts(scripts ...string) testcontainers.CustomizeRequestOption { return func(req *testcontainers.ContainerRequest) { var initScripts []testcontainers.ContainerFile for _, script := range scripts { diff --git a/modules/mysql/mysql_test.go b/modules/mysql/mysql_test.go index 1915654aeb..c38653007e 100644 --- a/modules/mysql/mysql_test.go +++ b/modules/mysql/mysql_test.go @@ -15,7 +15,7 @@ func TestMySQL(t *testing.T) { ctx := context.Background() // createMysqlContainer { - container, err := StartContainer(ctx) + container, err := RunContainer(ctx) if err != nil { t.Fatal(err) } @@ -53,7 +53,7 @@ func TestMySQL(t *testing.T) { func TestMySQLWithNonRootUserAndEmptyPassword(t *testing.T) { ctx := context.Background() - _, err := StartContainer(ctx, + _, err := RunContainer(ctx, WithDatabase("foo"), WithUsername("test"), WithPassword("")) @@ -66,7 +66,7 @@ func TestMySQLWithRootUserAndEmptyPassword(t *testing.T) { ctx := context.Background() // customInitialization { - container, err := StartContainer(ctx, + container, err := RunContainer(ctx, WithDatabase("foo"), WithUsername("root"), WithPassword("")) @@ -108,7 +108,7 @@ func TestMySQLWithConfigFile(t *testing.T) { ctx := context.Background() // withConfigFile { - container, err := StartContainer(ctx, testcontainers.WithImage("mysql:5.6"), + container, err := RunContainer(ctx, testcontainers.WithImage("mysql:5.6"), WithConfigFile("./testdata/my.cnf")) if err != nil { t.Fatal(err) @@ -154,7 +154,7 @@ func TestMySQLWithScripts(t *testing.T) { ctx := context.Background() // withScripts { - container, err := StartContainer(ctx, + container, err := RunContainer(ctx, WithScripts(filepath.Join("testdata", "schema.sql"))) if err != nil { t.Fatal(err) diff --git a/modules/postgres/postgres.go b/modules/postgres/postgres.go index 971360b7a7..3d3c52890a 100644 --- a/modules/postgres/postgres.go +++ b/modules/postgres/postgres.go @@ -47,7 +47,7 @@ func (c *PostgresContainer) ConnectionString(ctx context.Context, args ...string // WithConfigFile sets the config file to be used for the postgres container // It will also set the "config_file" parameter to the path of the config file // as a command line argument to the container -func WithConfigFile(cfg string) testcontainers.CustomizeContainerRequestOption { +func WithConfigFile(cfg string) testcontainers.CustomizeRequestOption { return func(req *testcontainers.ContainerRequest) { cfgFile := testcontainers.ContainerFile{ HostFilePath: cfg, @@ -64,14 +64,14 @@ func WithConfigFile(cfg string) testcontainers.CustomizeContainerRequestOption { // WithDatabase sets the initial database to be created when the container starts // It can be used to define a different name for the default database that is created when the image is first started. // If it is not specified, then the value of WithUser will be used. -func WithDatabase(dbName string) testcontainers.CustomizeContainerRequestOption { +func WithDatabase(dbName string) testcontainers.CustomizeRequestOption { return func(req *testcontainers.ContainerRequest) { req.Env["POSTGRES_DB"] = dbName } } // WithInitScripts sets the init scripts to be run when the container starts -func WithInitScripts(scripts ...string) testcontainers.CustomizeContainerRequestOption { +func WithInitScripts(scripts ...string) testcontainers.CustomizeRequestOption { return func(req *testcontainers.ContainerRequest) { initScripts := []testcontainers.ContainerFile{} for _, script := range scripts { @@ -109,8 +109,8 @@ func WithUsername(user string) func(req *testcontainers.ContainerRequest) { } } -// StartContainer creates an instance of the postgres container type -func StartContainer(ctx context.Context, opts ...testcontainers.CustomizeContainerRequestOption) (*PostgresContainer, error) { +// RunContainer creates an instance of the postgres container type +func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeRequestOption) (*PostgresContainer, error) { req := testcontainers.ContainerRequest{ Image: defaultPostgresImage, Env: map[string]string{ diff --git a/modules/postgres/postgres_test.go b/modules/postgres/postgres_test.go index 16a00ae1da..fe91985faa 100644 --- a/modules/postgres/postgres_test.go +++ b/modules/postgres/postgres_test.go @@ -53,7 +53,7 @@ func TestPostgres(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // postgresCreateContainer { - container, err := StartContainer(ctx, + container, err := RunContainer(ctx, testcontainers.WithImage(tt.image), WithDatabase(dbname), WithUsername(user), @@ -105,7 +105,7 @@ func TestContainerWithWaitForSQL(t *testing.T) { t.Run("default query", func(t *testing.T) { // withInitialDatabase { - container, err := StartContainer( + container, err := RunContainer( ctx, WithDatabase(dbname), WithUsername(user), @@ -118,7 +118,7 @@ func TestContainerWithWaitForSQL(t *testing.T) { }) t.Run("custom query", func(t *testing.T) { // withWaitStrategy { - container, err := StartContainer( + container, err := RunContainer( ctx, WithDatabase(dbname), WithUsername(user), @@ -130,7 +130,7 @@ func TestContainerWithWaitForSQL(t *testing.T) { // } }) t.Run("custom bad query", func(t *testing.T) { - container, err := StartContainer( + container, err := RunContainer( ctx, WithDatabase(dbname), WithUsername(user), @@ -146,7 +146,7 @@ func TestWithConfigFile(t *testing.T) { ctx := context.Background() // withConfigFile { - container, err := StartContainer(ctx, + container, err := RunContainer(ctx, WithConfigFile(filepath.Join("testdata", "my-postgres.conf")), WithDatabase(dbname), WithUsername(user), @@ -178,7 +178,7 @@ func TestWithInitScript(t *testing.T) { ctx := context.Background() // withInitScripts { - container, err := StartContainer(ctx, + container, err := RunContainer(ctx, testcontainers.WithImage("docker.io/postgres:15.2-alpine"), WithInitScripts(filepath.Join("testdata", "init-user-db.sh")), WithDatabase(dbname), diff --git a/modules/redis/redis.go b/modules/redis/redis.go index eb706d5178..5843e54e31 100644 --- a/modules/redis/redis.go +++ b/modules/redis/redis.go @@ -47,7 +47,7 @@ func (c *RedisContainer) ConnectionString(ctx context.Context) (string, error) { } // StartContainer creates an instance of the Redis container type -func StartContainer(ctx context.Context, opts ...testcontainers.CustomizeContainerRequestOption) (*RedisContainer, error) { +func StartContainer(ctx context.Context, opts ...testcontainers.CustomizeRequestOption) (*RedisContainer, error) { req := testcontainers.ContainerRequest{ Image: defaultImage, ExposedPorts: []string{"6379/tcp"}, @@ -71,7 +71,7 @@ func StartContainer(ctx context.Context, opts ...testcontainers.CustomizeContain // WithConfigFile sets the config file to be used for the redis container, and sets the command to run the redis server // using the passed config file -func WithConfigFile(configFile string) testcontainers.CustomizeContainerRequestOption { +func WithConfigFile(configFile string) testcontainers.CustomizeRequestOption { const defaultConfigFile = "/usr/local/redis.conf" return func(req *testcontainers.ContainerRequest) { @@ -100,7 +100,7 @@ func WithConfigFile(configFile string) testcontainers.CustomizeContainerRequestO // WithLogLevel sets the log level for the redis server process // See https://redis.io/docs/reference/modules/modules-api-ref/#redismodule_log for more information. -func WithLogLevel(level LogLevel) testcontainers.CustomizeContainerRequestOption { +func WithLogLevel(level LogLevel) testcontainers.CustomizeRequestOption { return func(req *testcontainers.ContainerRequest) { processRedisServerArgs(req, []string{"--loglevel", string(level)}) } @@ -110,7 +110,7 @@ func WithLogLevel(level LogLevel) testcontainers.CustomizeContainerRequestOption // save the dataset every N seconds if there are at least M changes in the dataset. // This method allows Redis to benefit from copy-on-write semantics. // See https://redis.io/docs/management/persistence/#snapshotting for more information. -func WithSnapshotting(seconds int, changedKeys int) testcontainers.CustomizeContainerRequestOption { +func WithSnapshotting(seconds int, changedKeys int) testcontainers.CustomizeRequestOption { if changedKeys < 1 { changedKeys = 1 } From c2cdbfb120c3fca2bd40acaef07da88b1c7ab127 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Mon, 3 Apr 2023 08:53:18 +0200 Subject: [PATCH 22/42] chore: migrate pulsar to new options types --- docs/modules/pulsar.md | 2 +- modules/pulsar/pulsar.go | 74 +++++++++++++---------------------- modules/pulsar/pulsar_test.go | 32 ++++++++------- 3 files changed, 46 insertions(+), 62 deletions(-) diff --git a/docs/modules/pulsar.md b/docs/modules/pulsar.md index a28d7693d7..cc08971474 100644 --- a/docs/modules/pulsar.md +++ b/docs/modules/pulsar.md @@ -33,7 +33,7 @@ Then you can retrieve the broker and the admin url: When starting the Pulsar container, you can pass options in a variadic way to configure it. ### Pulsar Image -If you need to set a different Pulsar image you can use the `WithPulsarImage`. +If you need to set a different Pulsar image you can use the `testcontainers.WithImage`. [Set Pulsar image](../../modules/pulsar/pulsar_test.go) inside_block:setPulsarImage diff --git a/modules/pulsar/pulsar.go b/modules/pulsar/pulsar.go index 818581b62d..730c75be11 100644 --- a/modules/pulsar/pulsar.go +++ b/modules/pulsar/pulsar.go @@ -69,30 +69,26 @@ func (c *Container) resolveURL(ctx context.Context, port nat.Port) (string, erro type ContainerRequest struct { testcontainers.ContainerRequest - logConsumers []testcontainers.LogConsumer } -// ContainerOptions is a function that can be used to configure the Pulsar container -type ContainerOptions func(req *ContainerRequest) - // WithConfigModifier allows to override the default container config -func WithConfigModifier(modifier func(config *container.Config)) ContainerOptions { - return func(req *ContainerRequest) { +func WithConfigModifier(modifier func(config *container.Config)) testcontainers.CustomizeRequestOption { + return func(req *testcontainers.ContainerRequest) { req.ConfigModifier = modifier } } // WithEndpointSettingsModifier allows to override the default endpoint settings -func WithEndpointSettingsModifier(modifier func(settings map[string]*network.EndpointSettings)) ContainerOptions { - return func(req *ContainerRequest) { +func WithEndpointSettingsModifier(modifier func(settings map[string]*network.EndpointSettings)) testcontainers.CustomizeRequestOption { + return func(req *testcontainers.ContainerRequest) { req.EnpointSettingsModifier = modifier } } // WithFunctionsWorker enables the functions worker, which will override the default pulsar command // and add a waiting strategy for the functions worker -func WithFunctionsWorker() ContainerOptions { - return func(req *ContainerRequest) { +func WithFunctionsWorker() testcontainers.CustomizeRequestOption { + return func(req *testcontainers.ContainerRequest) { req.Cmd = []string{"/bin/bash", "-c", defaultPulsarCmd} // add the waiting strategy for the functions worker @@ -106,40 +102,33 @@ func WithFunctionsWorker() ContainerOptions { } // WithHostConfigModifier allows to override the default host config -func WithHostConfigModifier(modifier func(hostConfig *container.HostConfig)) ContainerOptions { - return func(req *ContainerRequest) { +func WithHostConfigModifier(modifier func(hostConfig *container.HostConfig)) testcontainers.CustomizeRequestOption { + return func(req *testcontainers.ContainerRequest) { req.HostConfigModifier = modifier } } -// WithLogConsumer allows to add log consumers to the container. They will be automatically started and stopped by the StartContainer function +// WithLogConsumers allows to add log consumers to the container. +// They will be automatically started and they will follow the container logs, // but it's a responsibility of the caller to stop them calling StopLogProducer -func WithLogConsumers(consumer ...testcontainers.LogConsumer) ContainerOptions { - return func(req *ContainerRequest) { - req.logConsumers = append(req.logConsumers, consumer...) +func (c *Container) WithLogConsumers(ctx context.Context, consumer ...testcontainers.LogConsumer) { + if len(c.LogConsumers) > 0 { + c.StartLogProducer(ctx) } -} - -// WithPulsarEnv allows to use the native APIs and set each variable with PULSAR_PREFIX_ as prefix. -func WithPulsarEnv(configVar string, configValue string) ContainerOptions { - return func(req *ContainerRequest) { - req.ContainerRequest.Env["PULSAR_PREFIX_"+configVar] = configValue + for _, lc := range c.LogConsumers { + c.FollowOutput(lc) } } -// WithPulsarImage allows to override the default Pulsar image -func WithPulsarImage(image string) ContainerOptions { - return func(req *ContainerRequest) { - if image == "" { - image = defaultPulsarImage - } - - req.Image = image +// WithPulsarEnv allows to use the native APIs and set each variable with PULSAR_PREFIX_ as prefix. +func WithPulsarEnv(configVar string, configValue string) testcontainers.CustomizeRequestOption { + return func(req *testcontainers.ContainerRequest) { + req.Env["PULSAR_PREFIX_"+configVar] = configValue } } -func WithTransactions() ContainerOptions { - return func(req *ContainerRequest) { +func WithTransactions() testcontainers.CustomizeRequestOption { + return func(req *testcontainers.ContainerRequest) { WithPulsarEnv("transactionCoordinatorEnabled", "true")(req) // add the waiting strategy for the transaction topic @@ -154,7 +143,7 @@ func WithTransactions() ContainerOptions { } } -// StartContainer creates an instance of the Pulsar container type, being possible to pass a custom request and options +// RunContainer creates an instance of the Pulsar container type, being possible to pass a custom request and options // The created container will use the following defaults: // - image: docker.io/apachepulsar/pulsar:2.10.2 // - exposed ports: 6650/tcp, 8080/tcp @@ -162,8 +151,8 @@ func WithTransactions() ContainerOptions { // - the Pulsar admin API ("/admin/v2/clusters") to be ready on port 8080/tcp and return the response `["standalone"]` // - the log message "Successfully updated the policies on namespace public/default" // - command: "/bin/bash -c /pulsar/bin/apply-config-from-env.py /pulsar/conf/standalone.conf && bin/pulsar standalone --no-functions-worker -nss" -func StartContainer(ctx context.Context, opts ...ContainerOptions) (*Container, error) { - req := testcontainers.ContainerRequest{ +func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeRequestOption) (*Container, error) { + req := &testcontainers.ContainerRequest{ Image: defaultPulsarImage, Env: map[string]string{}, ExposedPorts: []string{defaultPulsarPort, defaultPulsarAdminPort}, @@ -172,12 +161,11 @@ func StartContainer(ctx context.Context, opts ...ContainerOptions) (*Container, } pulsarRequest := ContainerRequest{ - ContainerRequest: req, - logConsumers: []testcontainers.LogConsumer{}, + ContainerRequest: *req, } for _, opt := range opts { - opt(&pulsarRequest) + opt(req) } c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ @@ -189,15 +177,7 @@ func StartContainer(ctx context.Context, opts ...ContainerOptions) (*Container, } pc := &Container{ - Container: c, - LogConsumers: pulsarRequest.logConsumers, - } - - if len(pc.LogConsumers) > 0 { - c.StartLogProducer(ctx) - } - for _, lc := range pc.LogConsumers { - c.FollowOutput(lc) + Container: c, } return pc, nil diff --git a/modules/pulsar/pulsar_test.go b/modules/pulsar/pulsar_test.go index 833e457fb1..081a2b49d8 100644 --- a/modules/pulsar/pulsar_test.go +++ b/modules/pulsar/pulsar_test.go @@ -43,17 +43,18 @@ func TestPulsar(t *testing.T) { require.NoError(t, err) tests := []struct { - name string - opts []testcontainerspulsar.ContainerOptions + name string + opts []testcontainers.CustomizeRequestOption + logConsumers []testcontainers.LogConsumer }{ { name: "default", }, { name: "with modifiers", - opts: []testcontainerspulsar.ContainerOptions{ + opts: []testcontainers.CustomizeRequestOption{ // setPulsarImage { - testcontainerspulsar.WithPulsarImage("docker.io/apachepulsar/pulsar:2.10.2"), + testcontainers.WithImage("docker.io/apachepulsar/pulsar:2.10.2"), // } // addPulsarEnv { testcontainerspulsar.WithPulsarEnv("brokerDeduplicationEnabled", "true"), @@ -77,7 +78,7 @@ func TestPulsar(t *testing.T) { }, { name: "with functions worker", - opts: []testcontainerspulsar.ContainerOptions{ + opts: []testcontainers.CustomizeRequestOption{ // withFunctionsWorker { testcontainerspulsar.WithFunctionsWorker(), // } @@ -85,35 +86,38 @@ func TestPulsar(t *testing.T) { }, { name: "with transactions", - opts: []testcontainerspulsar.ContainerOptions{ + opts: []testcontainers.CustomizeRequestOption{ // withTransactions { testcontainerspulsar.WithTransactions(), // } }, }, { - name: "with log consumers", - opts: []testcontainerspulsar.ContainerOptions{ - // withLogConsumers { - testcontainerspulsar.WithLogConsumers(&testLogConsumer{}), - // } - }, + name: "with log consumers", + logConsumers: []testcontainers.LogConsumer{&testLogConsumer{}}, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // startPulsarContainer { - c, err := testcontainerspulsar.StartContainer( + c, err := testcontainerspulsar.RunContainer( ctx, tt.opts..., ) - // } require.Nil(t, err) + defer func() { + err := c.Terminate(ctx) + require.Nil(t, err) + }() + // } + // withLogConsumers { if len(c.LogConsumers) > 0 { + c.WithLogConsumers(ctx, tt.logConsumers...) defer c.StopLogProducer() } + // } // getPulsarURLs { brokerURL, err := c.BrokerURL(ctx) From 6f79871e177a232bed67f7c46c7a0bb1812c239b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Mon, 3 Apr 2023 08:57:25 +0200 Subject: [PATCH 23/42] chore: migrate vault to new options types --- docs/modules/vault.md | 6 +++--- modules/vault/vault.go | 21 ++++++--------------- modules/vault/vault_test.go | 9 +++++---- 3 files changed, 14 insertions(+), 22 deletions(-) diff --git a/docs/modules/vault.md b/docs/modules/vault.md index aef8362c88..11bb677d2f 100644 --- a/docs/modules/vault.md +++ b/docs/modules/vault.md @@ -13,10 +13,10 @@ go get github.com/testcontainers/testcontainers-go/modules/vault ``` ## Usage example -The **StartContainer** function is the main entry point to create a new VaultContainer instance. +The **RunContainer** function is the main entry point to create a new VaultContainer instance. It takes a context and zero or more Option values to configure the container. -[Creating a Vault container](../../modules/vault/vault_test.go) inside_block:StartContainer +[Creating a Vault container](../../modules/vault/vault_test.go) inside_block:RunContainer ### Use CLI to read data from Vault container: @@ -43,7 +43,7 @@ go get -u github.com/hashicorp/vault-client-go You can set below options to create Vault container. ### Image -If you need to set a different Vault image, you can use the `WithImageName`. +If you need to set a different Vault image, you can use the `testcontainers.WithImage`. !!!info Default image name is `hashicorp/vault:1.13.0`. diff --git a/modules/vault/vault.go b/modules/vault/vault.go index 76d64dd8a2..b352d72875 100644 --- a/modules/vault/vault.go +++ b/modules/vault/vault.go @@ -3,9 +3,10 @@ package vault import ( "context" "fmt" - "github.com/testcontainers/testcontainers-go/wait" "strings" + "github.com/testcontainers/testcontainers-go/wait" + "github.com/docker/docker/api/types/container" "github.com/testcontainers/testcontainers-go" ) @@ -15,16 +16,13 @@ const ( defaultImageName = "hashicorp/vault:1.13.0" ) -// ContainerOptions is a function that can be used to configure the Vault container -type ContainerOptions func(req *testcontainers.ContainerRequest) - // VaultContainer represents the vault container type used in the module type VaultContainer struct { testcontainers.Container } -// StartContainer creates an instance of the vault container type -func StartContainer(ctx context.Context, opts ...ContainerOptions) (*VaultContainer, error) { +// RunContainer creates an instance of the vault container type +func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeRequestOption) (*VaultContainer, error) { req := testcontainers.ContainerRequest{ Image: defaultImageName, ExposedPorts: []string{defaultPort + "/tcp"}, @@ -52,15 +50,8 @@ func StartContainer(ctx context.Context, opts ...ContainerOptions) (*VaultContai return &VaultContainer{container}, nil } -// WithImageName is an option function that sets the Docker image name for the Vault -func WithImageName(imageName string) ContainerOptions { - return func(req *testcontainers.ContainerRequest) { - req.Image = imageName - } -} - // WithToken is a container option function that sets the root token for the Vault -func WithToken(token string) ContainerOptions { +func WithToken(token string) testcontainers.CustomizeRequestOption { return func(req *testcontainers.ContainerRequest) { req.Env["VAULT_DEV_ROOT_TOKEN_ID"] = token req.Env["VAULT_TOKEN"] = token @@ -68,7 +59,7 @@ func WithToken(token string) ContainerOptions { } // WithInitCommand is an option function that adds a set of initialization commands to the Vault's configuration -func WithInitCommand(commands ...string) ContainerOptions { +func WithInitCommand(commands ...string) testcontainers.CustomizeRequestOption { return func(req *testcontainers.ContainerRequest) { commandsList := make([]string, 0, len(commands)) for _, command := range commands { diff --git a/modules/vault/vault_test.go b/modules/vault/vault_test.go index 18f6213b60..ca1fac69cd 100644 --- a/modules/vault/vault_test.go +++ b/modules/vault/vault_test.go @@ -12,6 +12,7 @@ import ( vaultClient "github.com/hashicorp/vault-client-go" "github.com/hashicorp/vault-client-go/schema" "github.com/stretchr/testify/assert" + "github.com/testcontainers/testcontainers-go" testcontainervault "github.com/testcontainers/testcontainers-go/modules/vault" "github.com/tidwall/gjson" ) @@ -27,9 +28,9 @@ var ( func TestMain(m *testing.M) { var err error - opts := []testcontainervault.ContainerOptions{ + opts := []testcontainers.CustomizeRequestOption{ // WithImageName { - testcontainervault.WithImageName("hashicorp/vault:1.13.0"), + testcontainers.WithImage("hashicorp/vault:1.13.0"), // } // WithToken { testcontainervault.WithToken(token), @@ -40,8 +41,8 @@ func TestMain(m *testing.M) { // } } - // StartContainer { - vault, err = testcontainervault.StartContainer(ctx, opts...) + // RunContainer { + vault, err = testcontainervault.RunContainer(ctx, opts...) // } if err != nil { log.Fatal(err) From 6854ba129ce96c008e3d68e7d2ccb469aeaac6f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Mon, 3 Apr 2023 09:08:30 +0200 Subject: [PATCH 24/42] chore migrate redis to new option types --- docs/modules/redis.md | 8 ++++---- modules/redis/redis.go | 4 ++-- modules/redis/redis_test.go | 10 +++++----- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/modules/redis.md b/docs/modules/redis.md index 66ddb53b9d..714b8a48d1 100644 --- a/docs/modules/redis.md +++ b/docs/modules/redis.md @@ -19,11 +19,11 @@ go get github.com/testcontainers/testcontainers-go/modules/redis The Redis module exposes one entrypoint function to create the containerr, and this function receives two parameters: ```golang -func StartContainer(ctx context.Context, opts ...RedisContainerOption) (*RedisContainer, error) +func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeRequestOption) (*RedisContainer, error) ``` - `context.Context`, the Go context. -- `RedisContainerOption`, a variad argument for passing options. +- `testcontainers.CustomizeRequestOption`, a variad argument for passing options. ### Container Options @@ -34,8 +34,8 @@ When starting the Redis container, you can pass options in a variadic way to con #### Image -If you need to set a different Redis Docker image, you can use `WithImage` with a valid Docker image -for Postgres. E.g. `WithImage("docker.io/redis:7")`. +If you need to set a different Redis Docker image, you can use `testcontainers.WithImage` with a valid Docker image +for Postgres. E.g. `testcontainers.WithImage("docker.io/redis:7")`. [Use a different image](../../modules/redis/redis_test.go) inside_block:withImage diff --git a/modules/redis/redis.go b/modules/redis/redis.go index 5843e54e31..935a521961 100644 --- a/modules/redis/redis.go +++ b/modules/redis/redis.go @@ -46,8 +46,8 @@ func (c *RedisContainer) ConnectionString(ctx context.Context) (string, error) { return uri, nil } -// StartContainer creates an instance of the Redis container type -func StartContainer(ctx context.Context, opts ...testcontainers.CustomizeRequestOption) (*RedisContainer, error) { +// RunContainer creates an instance of the Redis container type +func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeRequestOption) (*RedisContainer, error) { req := testcontainers.ContainerRequest{ Image: defaultImage, ExposedPorts: []string{"6379/tcp"}, diff --git a/modules/redis/redis_test.go b/modules/redis/redis_test.go index eb94f85e25..4a2f12718d 100644 --- a/modules/redis/redis_test.go +++ b/modules/redis/redis_test.go @@ -17,7 +17,7 @@ func TestIntegrationSetGet(t *testing.T) { ctx := context.Background() // createRedisContainer { - redisContainer, err := StartContainer(ctx) + redisContainer, err := RunContainer(ctx) require.NoError(t, err) t.Cleanup(func() { if err := redisContainer.Terminate(ctx); err != nil { @@ -33,7 +33,7 @@ func TestRedisWithConfigFile(t *testing.T) { ctx := context.Background() // withConfigFile { - redisContainer, err := StartContainer(ctx, WithConfigFile(filepath.Join("testdata", "redis7.conf"))) + redisContainer, err := RunContainer(ctx, WithConfigFile(filepath.Join("testdata", "redis7.conf"))) require.NoError(t, err) t.Cleanup(func() { if err := redisContainer.Terminate(ctx); err != nil { @@ -77,7 +77,7 @@ func TestRedisWithImage(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // withImage { - redisContainer, err := StartContainer(ctx, testcontainers.WithImage(tt.image), WithConfigFile(filepath.Join("testdata", "redis6.conf"))) + redisContainer, err := RunContainer(ctx, testcontainers.WithImage(tt.image), WithConfigFile(filepath.Join("testdata", "redis6.conf"))) require.NoError(t, err) t.Cleanup(func() { if err := redisContainer.Terminate(ctx); err != nil { @@ -95,7 +95,7 @@ func TestRedisWithLogLevel(t *testing.T) { ctx := context.Background() // withLogLevel { - redisContainer, err := StartContainer(ctx, WithLogLevel(LogLevelVerbose)) + redisContainer, err := RunContainer(ctx, WithLogLevel(LogLevelVerbose)) require.NoError(t, err) t.Cleanup(func() { if err := redisContainer.Terminate(ctx); err != nil { @@ -111,7 +111,7 @@ func TestRedisWithSnapshotting(t *testing.T) { ctx := context.Background() // withSnapshotting { - redisContainer, err := StartContainer(ctx, WithSnapshotting(10, 1)) + redisContainer, err := RunContainer(ctx, WithSnapshotting(10, 1)) require.NoError(t, err) t.Cleanup(func() { if err := redisContainer.Terminate(ctx); err != nil { From c6f914f95ca22cc3f99bd4a047c3db953bf55629 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Mon, 3 Apr 2023 09:16:41 +0200 Subject: [PATCH 25/42] chore: support for using modifiers in modules --- container.go | 21 +++++++++++++++++++++ docs/modules/pulsar.md | 2 +- modules/pulsar/pulsar.go | 23 ----------------------- modules/pulsar/pulsar_test.go | 6 +++--- 4 files changed, 25 insertions(+), 27 deletions(-) diff --git a/container.go b/container.go index 8c6678dee9..2187445323 100644 --- a/container.go +++ b/container.go @@ -155,6 +155,27 @@ func WithImage(image string) CustomizeRequestOption { } } +// WithConfigModifier allows to override the default container config +func WithConfigModifier(modifier func(config *container.Config)) CustomizeRequestOption { + return func(req *ContainerRequest) { + req.ConfigModifier = modifier + } +} + +// WithEndpointSettingsModifier allows to override the default endpoint settings +func WithEndpointSettingsModifier(modifier func(settings map[string]*network.EndpointSettings)) CustomizeRequestOption { + return func(req *ContainerRequest) { + req.EnpointSettingsModifier = modifier + } +} + +// WithHostConfigModifier allows to override the default host config +func WithHostConfigModifier(modifier func(hostConfig *container.HostConfig)) CustomizeRequestOption { + return func(req *ContainerRequest) { + req.HostConfigModifier = modifier + } +} + // WithWaitStrategy sets the wait strategy for a container, using 1 minute as deadline func WithWaitStrategy(strategies ...wait.Strategy) CustomizeRequestOption { return WithWaitStrategyAndDuration(1*time.Minute, strategies...) diff --git a/docs/modules/pulsar.md b/docs/modules/pulsar.md index cc08971474..35121d90ea 100644 --- a/docs/modules/pulsar.md +++ b/docs/modules/pulsar.md @@ -87,7 +87,7 @@ If you want to know more about LogConsumers, please check the [Following Contain ## Advanced configuration In the case you need a more advanced configuration regarding the config, host config and endpoint settings Docker types, you can leverage the modifier functions that are available in -the ContainerRequest. The Pulsar container exposes a way to interact with those modifiers in a simple manner, using the aforementioned options in the `StartContainer` function: +the ContainerRequest. The Pulsar container exposes a way to interact with those modifiers in a simple manner, using the aforementioned options in the `RunContainer` function: [Advanced Docker settings](../../modules/pulsar/pulsar_test.go) inside_block:advancedDockerSettings diff --git a/modules/pulsar/pulsar.go b/modules/pulsar/pulsar.go index 730c75be11..904d9042ac 100644 --- a/modules/pulsar/pulsar.go +++ b/modules/pulsar/pulsar.go @@ -6,8 +6,6 @@ import ( "io" "strings" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/network" "github.com/docker/go-connections/nat" "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/wait" @@ -71,20 +69,6 @@ type ContainerRequest struct { testcontainers.ContainerRequest } -// WithConfigModifier allows to override the default container config -func WithConfigModifier(modifier func(config *container.Config)) testcontainers.CustomizeRequestOption { - return func(req *testcontainers.ContainerRequest) { - req.ConfigModifier = modifier - } -} - -// WithEndpointSettingsModifier allows to override the default endpoint settings -func WithEndpointSettingsModifier(modifier func(settings map[string]*network.EndpointSettings)) testcontainers.CustomizeRequestOption { - return func(req *testcontainers.ContainerRequest) { - req.EnpointSettingsModifier = modifier - } -} - // WithFunctionsWorker enables the functions worker, which will override the default pulsar command // and add a waiting strategy for the functions worker func WithFunctionsWorker() testcontainers.CustomizeRequestOption { @@ -101,13 +85,6 @@ func WithFunctionsWorker() testcontainers.CustomizeRequestOption { } } -// WithHostConfigModifier allows to override the default host config -func WithHostConfigModifier(modifier func(hostConfig *container.HostConfig)) testcontainers.CustomizeRequestOption { - return func(req *testcontainers.ContainerRequest) { - req.HostConfigModifier = modifier - } -} - // WithLogConsumers allows to add log consumers to the container. // They will be automatically started and they will follow the container logs, // but it's a responsibility of the caller to stop them calling StopLogProducer diff --git a/modules/pulsar/pulsar_test.go b/modules/pulsar/pulsar_test.go index 081a2b49d8..e87fa5edfb 100644 --- a/modules/pulsar/pulsar_test.go +++ b/modules/pulsar/pulsar_test.go @@ -60,15 +60,15 @@ func TestPulsar(t *testing.T) { testcontainerspulsar.WithPulsarEnv("brokerDeduplicationEnabled", "true"), // } // advancedDockerSettings { - testcontainerspulsar.WithConfigModifier(func(config *container.Config) { + testcontainers.WithConfigModifier(func(config *container.Config) { config.Env = append(config.Env, "PULSAR_MEM= -Xms512m -Xmx512m -XX:MaxDirectMemorySize=512m") }), - testcontainerspulsar.WithHostConfigModifier(func(hostConfig *container.HostConfig) { + testcontainers.WithHostConfigModifier(func(hostConfig *container.HostConfig) { hostConfig.Resources = container.Resources{ Memory: 1024 * 1024 * 1024, } }), - testcontainerspulsar.WithEndpointSettingsModifier(func(settings map[string]*network.EndpointSettings) { + testcontainers.WithEndpointSettingsModifier(func(settings map[string]*network.EndpointSettings) { settings[nwName] = &network.EndpointSettings{ Aliases: []string{"pulsar"}, } From 4a243a80256bfe8d026e2271a291dd4d1d6d30f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Mon, 3 Apr 2023 09:30:05 +0200 Subject: [PATCH 26/42] chore: go mod tidy --- examples/bigtable/go.mod | 2 +- examples/bigtable/go.sum | 4 ++-- examples/cockroachdb/go.mod | 2 +- examples/cockroachdb/go.sum | 4 ++-- examples/consul/go.mod | 2 +- examples/consul/go.sum | 4 ++-- examples/datastore/go.mod | 2 +- examples/datastore/go.sum | 4 ++-- examples/firestore/go.mod | 2 +- examples/firestore/go.sum | 4 ++-- examples/mongodb/go.mod | 2 +- examples/mongodb/go.sum | 4 ++-- examples/nginx/go.mod | 2 +- examples/nginx/go.sum | 4 ++-- examples/pubsub/go.mod | 2 +- examples/pubsub/go.sum | 4 ++-- examples/spanner/go.mod | 2 +- examples/spanner/go.sum | 4 ++-- examples/toxiproxy/go.mod | 2 +- examples/toxiproxy/go.sum | 4 ++-- modules/couchbase/go.mod | 2 +- modules/couchbase/go.sum | 4 ++-- modules/localstack/go.mod | 2 +- modules/localstack/go.sum | 4 ++-- modules/mysql/go.mod | 2 +- modules/mysql/go.sum | 4 ++-- modules/postgres/go.mod | 2 +- modules/postgres/go.sum | 4 ++-- modules/redis/go.mod | 2 +- modules/redis/go.sum | 4 ++-- 30 files changed, 45 insertions(+), 45 deletions(-) diff --git a/examples/bigtable/go.mod b/examples/bigtable/go.mod index 69c69b1f5a..d964afeec8 100644 --- a/examples/bigtable/go.mod +++ b/examples/bigtable/go.mod @@ -27,7 +27,7 @@ require ( github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/dnephin/pflag v1.0.7 // indirect github.com/docker/distribution v2.8.1+incompatible // indirect - github.com/docker/docker v23.0.1+incompatible // indirect + github.com/docker/docker v23.0.2+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/envoyproxy/go-control-plane v0.10.3 // indirect diff --git a/examples/bigtable/go.sum b/examples/bigtable/go.sum index 573da3c754..cae3b15711 100644 --- a/examples/bigtable/go.sum +++ b/examples/bigtable/go.sum @@ -97,8 +97,8 @@ github.com/dnephin/pflag v1.0.7 h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk= github.com/dnephin/pflag v1.0.7/go.mod h1:uxE91IoWURlOiTUIA8Mq5ZZkAv3dPUfZNaT80Zm7OQE= github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v23.0.1+incompatible h1:vjgvJZxprTTE1A37nm+CLNAdwu6xZekyoiVlUZEINcY= -github.com/docker/docker v23.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v23.0.2+incompatible h1:q81C2qQ/EhPm8COZMUGOQYh4qLv4Xu6CXELJ3WK/mlU= +github.com/docker/docker v23.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/examples/cockroachdb/go.mod b/examples/cockroachdb/go.mod index 438f5737ce..bd1cf9f813 100644 --- a/examples/cockroachdb/go.mod +++ b/examples/cockroachdb/go.mod @@ -21,7 +21,7 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/dnephin/pflag v1.0.7 // indirect github.com/docker/distribution v2.8.1+incompatible // indirect - github.com/docker/docker v23.0.1+incompatible // indirect + github.com/docker/docker v23.0.2+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/fatih/color v1.13.0 // indirect diff --git a/examples/cockroachdb/go.sum b/examples/cockroachdb/go.sum index 4cc51058c2..4e7186bacd 100644 --- a/examples/cockroachdb/go.sum +++ b/examples/cockroachdb/go.sum @@ -45,8 +45,8 @@ github.com/dnephin/pflag v1.0.7 h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk= github.com/dnephin/pflag v1.0.7/go.mod h1:uxE91IoWURlOiTUIA8Mq5ZZkAv3dPUfZNaT80Zm7OQE= github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v23.0.1+incompatible h1:vjgvJZxprTTE1A37nm+CLNAdwu6xZekyoiVlUZEINcY= -github.com/docker/docker v23.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v23.0.2+incompatible h1:q81C2qQ/EhPm8COZMUGOQYh4qLv4Xu6CXELJ3WK/mlU= +github.com/docker/docker v23.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/examples/consul/go.mod b/examples/consul/go.mod index 078af7ffd7..8889cbfc36 100644 --- a/examples/consul/go.mod +++ b/examples/consul/go.mod @@ -17,7 +17,7 @@ require ( github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/dnephin/pflag v1.0.7 // indirect github.com/docker/distribution v2.8.1+incompatible // indirect - github.com/docker/docker v23.0.1+incompatible // indirect + github.com/docker/docker v23.0.2+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/fatih/color v1.13.0 // indirect diff --git a/examples/consul/go.sum b/examples/consul/go.sum index 5acae805da..e54c4bcd2d 100644 --- a/examples/consul/go.sum +++ b/examples/consul/go.sum @@ -43,8 +43,8 @@ github.com/dnephin/pflag v1.0.7 h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk= github.com/dnephin/pflag v1.0.7/go.mod h1:uxE91IoWURlOiTUIA8Mq5ZZkAv3dPUfZNaT80Zm7OQE= github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v23.0.1+incompatible h1:vjgvJZxprTTE1A37nm+CLNAdwu6xZekyoiVlUZEINcY= -github.com/docker/docker v23.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v23.0.2+incompatible h1:q81C2qQ/EhPm8COZMUGOQYh4qLv4Xu6CXELJ3WK/mlU= +github.com/docker/docker v23.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/examples/datastore/go.mod b/examples/datastore/go.mod index 04288b51c7..e8d0670a8b 100644 --- a/examples/datastore/go.mod +++ b/examples/datastore/go.mod @@ -21,7 +21,7 @@ require ( github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/dnephin/pflag v1.0.7 // indirect github.com/docker/distribution v2.8.1+incompatible // indirect - github.com/docker/docker v23.0.1+incompatible // indirect + github.com/docker/docker v23.0.2+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/fatih/color v1.13.0 // indirect diff --git a/examples/datastore/go.sum b/examples/datastore/go.sum index bb1b86859d..458b141268 100644 --- a/examples/datastore/go.sum +++ b/examples/datastore/go.sum @@ -38,8 +38,8 @@ github.com/dnephin/pflag v1.0.7 h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk= github.com/dnephin/pflag v1.0.7/go.mod h1:uxE91IoWURlOiTUIA8Mq5ZZkAv3dPUfZNaT80Zm7OQE= github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v23.0.1+incompatible h1:vjgvJZxprTTE1A37nm+CLNAdwu6xZekyoiVlUZEINcY= -github.com/docker/docker v23.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v23.0.2+incompatible h1:q81C2qQ/EhPm8COZMUGOQYh4qLv4Xu6CXELJ3WK/mlU= +github.com/docker/docker v23.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/examples/firestore/go.mod b/examples/firestore/go.mod index 62dcbeb8f5..6896e16e65 100644 --- a/examples/firestore/go.mod +++ b/examples/firestore/go.mod @@ -22,7 +22,7 @@ require ( github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/dnephin/pflag v1.0.7 // indirect github.com/docker/distribution v2.8.1+incompatible // indirect - github.com/docker/docker v23.0.1+incompatible // indirect + github.com/docker/docker v23.0.2+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/fatih/color v1.13.0 // indirect diff --git a/examples/firestore/go.sum b/examples/firestore/go.sum index 5f2c2a3de8..24f80ab226 100644 --- a/examples/firestore/go.sum +++ b/examples/firestore/go.sum @@ -39,8 +39,8 @@ github.com/dnephin/pflag v1.0.7 h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk= github.com/dnephin/pflag v1.0.7/go.mod h1:uxE91IoWURlOiTUIA8Mq5ZZkAv3dPUfZNaT80Zm7OQE= github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v23.0.1+incompatible h1:vjgvJZxprTTE1A37nm+CLNAdwu6xZekyoiVlUZEINcY= -github.com/docker/docker v23.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v23.0.2+incompatible h1:q81C2qQ/EhPm8COZMUGOQYh4qLv4Xu6CXELJ3WK/mlU= +github.com/docker/docker v23.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/examples/mongodb/go.mod b/examples/mongodb/go.mod index b1466e8620..82077c68b7 100644 --- a/examples/mongodb/go.mod +++ b/examples/mongodb/go.mod @@ -16,7 +16,7 @@ require ( github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/dnephin/pflag v1.0.7 // indirect github.com/docker/distribution v2.8.1+incompatible // indirect - github.com/docker/docker v23.0.1+incompatible // indirect + github.com/docker/docker v23.0.2+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/fatih/color v1.13.0 // indirect diff --git a/examples/mongodb/go.sum b/examples/mongodb/go.sum index 421e0b468c..a3f7734256 100644 --- a/examples/mongodb/go.sum +++ b/examples/mongodb/go.sum @@ -37,8 +37,8 @@ github.com/dnephin/pflag v1.0.7 h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk= github.com/dnephin/pflag v1.0.7/go.mod h1:uxE91IoWURlOiTUIA8Mq5ZZkAv3dPUfZNaT80Zm7OQE= github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v23.0.1+incompatible h1:vjgvJZxprTTE1A37nm+CLNAdwu6xZekyoiVlUZEINcY= -github.com/docker/docker v23.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v23.0.2+incompatible h1:q81C2qQ/EhPm8COZMUGOQYh4qLv4Xu6CXELJ3WK/mlU= +github.com/docker/docker v23.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/examples/nginx/go.mod b/examples/nginx/go.mod index 3f7ce51930..769852ad24 100644 --- a/examples/nginx/go.mod +++ b/examples/nginx/go.mod @@ -17,7 +17,7 @@ require ( github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/dnephin/pflag v1.0.7 // indirect github.com/docker/distribution v2.8.1+incompatible // indirect - github.com/docker/docker v23.0.1+incompatible // indirect + github.com/docker/docker v23.0.2+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/fatih/color v1.13.0 // indirect diff --git a/examples/nginx/go.sum b/examples/nginx/go.sum index ae6c2f54eb..03bca64dd2 100644 --- a/examples/nginx/go.sum +++ b/examples/nginx/go.sum @@ -37,8 +37,8 @@ github.com/dnephin/pflag v1.0.7 h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk= github.com/dnephin/pflag v1.0.7/go.mod h1:uxE91IoWURlOiTUIA8Mq5ZZkAv3dPUfZNaT80Zm7OQE= github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v23.0.1+incompatible h1:vjgvJZxprTTE1A37nm+CLNAdwu6xZekyoiVlUZEINcY= -github.com/docker/docker v23.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v23.0.2+incompatible h1:q81C2qQ/EhPm8COZMUGOQYh4qLv4Xu6CXELJ3WK/mlU= +github.com/docker/docker v23.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/examples/pubsub/go.mod b/examples/pubsub/go.mod index 6b5bcd164d..272d5c4d68 100644 --- a/examples/pubsub/go.mod +++ b/examples/pubsub/go.mod @@ -22,7 +22,7 @@ require ( github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/dnephin/pflag v1.0.7 // indirect github.com/docker/distribution v2.8.1+incompatible // indirect - github.com/docker/docker v23.0.1+incompatible // indirect + github.com/docker/docker v23.0.2+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/fatih/color v1.13.0 // indirect diff --git a/examples/pubsub/go.sum b/examples/pubsub/go.sum index 6ef94d536f..f026f077c0 100644 --- a/examples/pubsub/go.sum +++ b/examples/pubsub/go.sum @@ -41,8 +41,8 @@ github.com/dnephin/pflag v1.0.7 h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk= github.com/dnephin/pflag v1.0.7/go.mod h1:uxE91IoWURlOiTUIA8Mq5ZZkAv3dPUfZNaT80Zm7OQE= github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v23.0.1+incompatible h1:vjgvJZxprTTE1A37nm+CLNAdwu6xZekyoiVlUZEINcY= -github.com/docker/docker v23.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v23.0.2+incompatible h1:q81C2qQ/EhPm8COZMUGOQYh4qLv4Xu6CXELJ3WK/mlU= +github.com/docker/docker v23.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/examples/spanner/go.mod b/examples/spanner/go.mod index 614060788a..cbb04a7a94 100644 --- a/examples/spanner/go.mod +++ b/examples/spanner/go.mod @@ -28,7 +28,7 @@ require ( github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/dnephin/pflag v1.0.7 // indirect github.com/docker/distribution v2.8.1+incompatible // indirect - github.com/docker/docker v23.0.1+incompatible // indirect + github.com/docker/docker v23.0.2+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/envoyproxy/go-control-plane v0.10.3 // indirect diff --git a/examples/spanner/go.sum b/examples/spanner/go.sum index 49d9c25f45..869c2e39ae 100644 --- a/examples/spanner/go.sum +++ b/examples/spanner/go.sum @@ -97,8 +97,8 @@ github.com/dnephin/pflag v1.0.7 h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk= github.com/dnephin/pflag v1.0.7/go.mod h1:uxE91IoWURlOiTUIA8Mq5ZZkAv3dPUfZNaT80Zm7OQE= github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v23.0.1+incompatible h1:vjgvJZxprTTE1A37nm+CLNAdwu6xZekyoiVlUZEINcY= -github.com/docker/docker v23.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v23.0.2+incompatible h1:q81C2qQ/EhPm8COZMUGOQYh4qLv4Xu6CXELJ3WK/mlU= +github.com/docker/docker v23.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/examples/toxiproxy/go.mod b/examples/toxiproxy/go.mod index 073dc08d99..2abfc0df20 100644 --- a/examples/toxiproxy/go.mod +++ b/examples/toxiproxy/go.mod @@ -20,7 +20,7 @@ require ( github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dnephin/pflag v1.0.7 // indirect github.com/docker/distribution v2.8.1+incompatible // indirect - github.com/docker/docker v23.0.1+incompatible // indirect + github.com/docker/docker v23.0.2+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/fatih/color v1.13.0 // indirect diff --git a/examples/toxiproxy/go.sum b/examples/toxiproxy/go.sum index de79e5f085..ceb3c20e38 100644 --- a/examples/toxiproxy/go.sum +++ b/examples/toxiproxy/go.sum @@ -43,8 +43,8 @@ github.com/dnephin/pflag v1.0.7 h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk= github.com/dnephin/pflag v1.0.7/go.mod h1:uxE91IoWURlOiTUIA8Mq5ZZkAv3dPUfZNaT80Zm7OQE= github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v23.0.1+incompatible h1:vjgvJZxprTTE1A37nm+CLNAdwu6xZekyoiVlUZEINcY= -github.com/docker/docker v23.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v23.0.2+incompatible h1:q81C2qQ/EhPm8COZMUGOQYh4qLv4Xu6CXELJ3WK/mlU= +github.com/docker/docker v23.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/modules/couchbase/go.mod b/modules/couchbase/go.mod index 472b8999d0..60872fde04 100644 --- a/modules/couchbase/go.mod +++ b/modules/couchbase/go.mod @@ -19,7 +19,7 @@ require ( github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/dnephin/pflag v1.0.7 // indirect github.com/docker/distribution v2.8.1+incompatible // indirect - github.com/docker/docker v23.0.1+incompatible // indirect + github.com/docker/docker v23.0.2+incompatible // indirect github.com/docker/go-units v0.5.0 // indirect github.com/fatih/color v1.13.0 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect diff --git a/modules/couchbase/go.sum b/modules/couchbase/go.sum index bcd7885809..951b0d4382 100644 --- a/modules/couchbase/go.sum +++ b/modules/couchbase/go.sum @@ -43,8 +43,8 @@ github.com/dnephin/pflag v1.0.7 h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk= github.com/dnephin/pflag v1.0.7/go.mod h1:uxE91IoWURlOiTUIA8Mq5ZZkAv3dPUfZNaT80Zm7OQE= github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v23.0.1+incompatible h1:vjgvJZxprTTE1A37nm+CLNAdwu6xZekyoiVlUZEINcY= -github.com/docker/docker v23.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v23.0.2+incompatible h1:q81C2qQ/EhPm8COZMUGOQYh4qLv4Xu6CXELJ3WK/mlU= +github.com/docker/docker v23.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/modules/localstack/go.mod b/modules/localstack/go.mod index 7bc621e8f8..38dbc8c1b8 100644 --- a/modules/localstack/go.mod +++ b/modules/localstack/go.mod @@ -39,7 +39,7 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/dnephin/pflag v1.0.7 // indirect github.com/docker/distribution v2.8.1+incompatible // indirect - github.com/docker/docker v23.0.1+incompatible // indirect + github.com/docker/docker v23.0.2+incompatible // indirect github.com/docker/go-units v0.5.0 // indirect github.com/fatih/color v1.13.0 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect diff --git a/modules/localstack/go.sum b/modules/localstack/go.sum index 4e9702e803..8a7a28fe2c 100644 --- a/modules/localstack/go.sum +++ b/modules/localstack/go.sum @@ -75,8 +75,8 @@ github.com/dnephin/pflag v1.0.7 h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk= github.com/dnephin/pflag v1.0.7/go.mod h1:uxE91IoWURlOiTUIA8Mq5ZZkAv3dPUfZNaT80Zm7OQE= github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v23.0.1+incompatible h1:vjgvJZxprTTE1A37nm+CLNAdwu6xZekyoiVlUZEINcY= -github.com/docker/docker v23.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v23.0.2+incompatible h1:q81C2qQ/EhPm8COZMUGOQYh4qLv4Xu6CXELJ3WK/mlU= +github.com/docker/docker v23.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/modules/mysql/go.mod b/modules/mysql/go.mod index ca0d7e73c7..1ebcff6d25 100644 --- a/modules/mysql/go.mod +++ b/modules/mysql/go.mod @@ -16,7 +16,7 @@ require ( github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/dnephin/pflag v1.0.7 // indirect github.com/docker/distribution v2.8.1+incompatible // indirect - github.com/docker/docker v23.0.1+incompatible // indirect + github.com/docker/docker v23.0.2+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/fatih/color v1.13.0 // indirect diff --git a/modules/mysql/go.sum b/modules/mysql/go.sum index 688c307127..0c9f8fa560 100644 --- a/modules/mysql/go.sum +++ b/modules/mysql/go.sum @@ -37,8 +37,8 @@ github.com/dnephin/pflag v1.0.7 h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk= github.com/dnephin/pflag v1.0.7/go.mod h1:uxE91IoWURlOiTUIA8Mq5ZZkAv3dPUfZNaT80Zm7OQE= github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v23.0.1+incompatible h1:vjgvJZxprTTE1A37nm+CLNAdwu6xZekyoiVlUZEINcY= -github.com/docker/docker v23.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v23.0.2+incompatible h1:q81C2qQ/EhPm8COZMUGOQYh4qLv4Xu6CXELJ3WK/mlU= +github.com/docker/docker v23.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/modules/postgres/go.mod b/modules/postgres/go.mod index 6c102cad0a..96cf9f22fe 100644 --- a/modules/postgres/go.mod +++ b/modules/postgres/go.mod @@ -19,7 +19,7 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/dnephin/pflag v1.0.7 // indirect github.com/docker/distribution v2.8.1+incompatible // indirect - github.com/docker/docker v23.0.1+incompatible // indirect + github.com/docker/docker v23.0.2+incompatible // indirect github.com/docker/go-units v0.5.0 // indirect github.com/fatih/color v1.13.0 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect diff --git a/modules/postgres/go.sum b/modules/postgres/go.sum index 25756a5015..0f90c23956 100644 --- a/modules/postgres/go.sum +++ b/modules/postgres/go.sum @@ -38,8 +38,8 @@ github.com/dnephin/pflag v1.0.7 h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk= github.com/dnephin/pflag v1.0.7/go.mod h1:uxE91IoWURlOiTUIA8Mq5ZZkAv3dPUfZNaT80Zm7OQE= github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v23.0.1+incompatible h1:vjgvJZxprTTE1A37nm+CLNAdwu6xZekyoiVlUZEINcY= -github.com/docker/docker v23.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v23.0.2+incompatible h1:q81C2qQ/EhPm8COZMUGOQYh4qLv4Xu6CXELJ3WK/mlU= +github.com/docker/docker v23.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/modules/redis/go.mod b/modules/redis/go.mod index 378fd08b8a..d76bcb17a5 100644 --- a/modules/redis/go.mod +++ b/modules/redis/go.mod @@ -23,7 +23,7 @@ require ( github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dnephin/pflag v1.0.7 // indirect github.com/docker/distribution v2.8.1+incompatible // indirect - github.com/docker/docker v23.0.1+incompatible // indirect + github.com/docker/docker v23.0.2+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/fatih/color v1.13.0 // indirect diff --git a/modules/redis/go.sum b/modules/redis/go.sum index 4a02b42cc8..b961320a95 100644 --- a/modules/redis/go.sum +++ b/modules/redis/go.sum @@ -41,8 +41,8 @@ github.com/dnephin/pflag v1.0.7 h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk= github.com/dnephin/pflag v1.0.7/go.mod h1:uxE91IoWURlOiTUIA8Mq5ZZkAv3dPUfZNaT80Zm7OQE= github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v23.0.1+incompatible h1:vjgvJZxprTTE1A37nm+CLNAdwu6xZekyoiVlUZEINcY= -github.com/docker/docker v23.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v23.0.2+incompatible h1:q81C2qQ/EhPm8COZMUGOQYh4qLv4Xu6CXELJ3WK/mlU= +github.com/docker/docker v23.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= From 24fca0ab0d926ad9d5a3b38e45c1031011392366 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Mon, 3 Apr 2023 09:35:38 +0200 Subject: [PATCH 27/42] chore: use RunContainer in code generator --- modulegen/_template/example.go.tmpl | 7 ++++++- modulegen/main.go | 6 +++--- modulegen/main_test.go | 12 ++++++------ 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/modulegen/_template/example.go.tmpl b/modulegen/_template/example.go.tmpl index 4936388a94..34b96df089 100644 --- a/modulegen/_template/example.go.tmpl +++ b/modulegen/_template/example.go.tmpl @@ -12,10 +12,15 @@ type {{ $containerName }} struct { } // {{ $entrypoint }} creates an instance of the {{ $title }} container type -func {{ $entrypoint }}(ctx context.Context) (*{{ $containerName }}, error) { +func {{ $entrypoint }}(ctx context.Context, opts ...testcontainers.CustomizeRequestOption) (*{{ $containerName }}, error) { req := testcontainers.ContainerRequest{ Image: "{{ .Image }}", } + + for _, opt := range opts { + opt(&req) + } + container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ ContainerRequest: req, Started: true, diff --git a/modulegen/main.go b/modulegen/main.go index d5e6b8b4ed..a4ee7fb3bf 100644 --- a/modulegen/main.go +++ b/modulegen/main.go @@ -59,13 +59,13 @@ func (e *Example) ContainerName() string { } // Entrypoint returns the name of the entrypoint function, which is the lower-cased title of the example -// If the example is a module, the entrypoint will be "StartContainer" +// If the example is a module, the entrypoint will be "RunContainer" func (e *Example) Entrypoint() string { if e.IsModule { - return "StartContainer" + return "RunContainer" } - return "startContainer" + return "runContainer" } func (e *Example) Lower() string { diff --git a/modulegen/main_test.go b/modulegen/main_test.go index 0baffc9e22..354a71656d 100644 --- a/modulegen/main_test.go +++ b/modulegen/main_test.go @@ -27,7 +27,7 @@ func TestExample(t *testing.T) { TitleName: "MongoDB", }, expectedContainerName: "MongoDBContainer", - expectedEntrypoint: "StartContainer", + expectedEntrypoint: "RunContainer", expectedTitle: "MongoDB", }, { @@ -38,7 +38,7 @@ func TestExample(t *testing.T) { Image: "mongodb:latest", }, expectedContainerName: "MongodbContainer", - expectedEntrypoint: "StartContainer", + expectedEntrypoint: "RunContainer", expectedTitle: "Mongodb", }, { @@ -50,7 +50,7 @@ func TestExample(t *testing.T) { TitleName: "MongoDB", }, expectedContainerName: "mongoDBContainer", - expectedEntrypoint: "startContainer", + expectedEntrypoint: "runContainer", expectedTitle: "MongoDB", }, { @@ -61,7 +61,7 @@ func TestExample(t *testing.T) { Image: "mongodb:latest", }, expectedContainerName: "mongodbContainer", - expectedEntrypoint: "startContainer", + expectedEntrypoint: "runContainer", expectedTitle: "Mongodb", }, } @@ -450,9 +450,9 @@ func assertExampleContent(t *testing.T, example Example, exampleFile string) { assert.Equal(t, data[8], "// "+containerName+" represents the "+exampleName+" container type used in the module") assert.Equal(t, data[9], "type "+containerName+" struct {") assert.Equal(t, data[13], "// "+entrypoint+" creates an instance of the "+exampleName+" container type") - assert.Equal(t, data[14], "func "+entrypoint+"(ctx context.Context) (*"+containerName+", error) {") + assert.Equal(t, data[14], "func "+entrypoint+"(ctx context.Context, opts ...testcontainers.CustomizeRequestOption) (*"+containerName+", error) {") assert.Equal(t, data[16], "\t\tImage: \""+example.Image+"\",") - assert.Equal(t, data[26], "\treturn &"+containerName+"{Container: container}, nil") + assert.Equal(t, data[31], "\treturn &"+containerName+"{Container: container}, nil") } // assert content GitHub workflow for the example From 464dd220ff93bd346d21a3d71dc7b060a987e3cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Mon, 3 Apr 2023 09:41:35 +0200 Subject: [PATCH 28/42] docs: extend module reference in generated docs --- modulegen/_template/docs_example.md.tmpl | 11 +++++++++++ modulegen/main_test.go | 2 ++ 2 files changed, 13 insertions(+) diff --git a/modulegen/_template/docs_example.md.tmpl b/modulegen/_template/docs_example.md.tmpl index 8b63cb3a56..200291004b 100644 --- a/modulegen/_template/docs_example.md.tmpl +++ b/modulegen/_template/docs_example.md.tmpl @@ -17,3 +17,14 @@ go get github.com/testcontainers/testcontainers-go/{{ ParentDir }}/{{ $lower }} {{ codeinclude "" }} [Test for a {{ $title }} container](../../{{ ParentDir }}/{{ $lower }}/{{ $lower }}_test.go) {{ codeinclude "" }} + +## Module reference + +The {{ $title }} module exposes one entrypoint function to create the {{ $title }} container, and this function receives two parameters: + +```golang +func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeRequestOption) (*{{ $title }}Container, error) +``` + +- `context.Context`, the Go context. +- `testcontainers.CustomizeRequestOption`, a variadic argument for passing options. diff --git a/modulegen/main_test.go b/modulegen/main_test.go index 354a71656d..c8bde5851e 100644 --- a/modulegen/main_test.go +++ b/modulegen/main_test.go @@ -422,6 +422,8 @@ func assertExampleDocContent(t *testing.T, example Example, exampleDocFile strin assert.Equal(t, data[16], "") assert.Equal(t, data[17], "[Test for a "+title+" container](../../"+example.ParentDir()+"/"+lower+"/"+lower+"_test.go)") assert.Equal(t, data[18], "") + assert.Equal(t, data[22], "The "+title+" module exposes one entrypoint function to create the "+title+" container, and this function receives two parameters:") + assert.True(t, strings.HasSuffix(data[25], "(*"+title+"Container, error)")) } // assert content example test From 26afc1167d5796b2d11c3658cdcc39ebd16b5aeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Mon, 3 Apr 2023 09:47:00 +0200 Subject: [PATCH 29/42] chore: generate a section for container options --- modulegen/_template/docs_example.md.tmpl | 9 +++++++++ modulegen/main_test.go | 1 + 2 files changed, 10 insertions(+) diff --git a/modulegen/_template/docs_example.md.tmpl b/modulegen/_template/docs_example.md.tmpl index 200291004b..dab8be33ca 100644 --- a/modulegen/_template/docs_example.md.tmpl +++ b/modulegen/_template/docs_example.md.tmpl @@ -28,3 +28,12 @@ func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeRequestOp - `context.Context`, the Go context. - `testcontainers.CustomizeRequestOption`, a variadic argument for passing options. + +### Container Options + +When starting the {{ $title }} container, you can pass options in a variadic way to configure it. + +#### Image + +If you need to set a different {{ $title }} Docker image, you can use `testcontainers.WithImage` with a valid Docker image +for {{ $title }}. E.g. `testcontainers.WithImage("{{ .Image }}")`. diff --git a/modulegen/main_test.go b/modulegen/main_test.go index c8bde5851e..e886fb5a19 100644 --- a/modulegen/main_test.go +++ b/modulegen/main_test.go @@ -424,6 +424,7 @@ func assertExampleDocContent(t *testing.T, example Example, exampleDocFile strin assert.Equal(t, data[18], "") assert.Equal(t, data[22], "The "+title+" module exposes one entrypoint function to create the "+title+" container, and this function receives two parameters:") assert.True(t, strings.HasSuffix(data[25], "(*"+title+"Container, error)")) + assert.Equal(t, "for "+title+". E.g. `testcontainers.WithImage(\""+example.Image+"\")`.", data[38]) } // assert content example test From 4c9ac9440083728783634936cae0a2607b096640 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Mon, 3 Apr 2023 09:48:37 +0200 Subject: [PATCH 30/42] chore: generate a section for container methods --- modulegen/_template/docs_example.md.tmpl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modulegen/_template/docs_example.md.tmpl b/modulegen/_template/docs_example.md.tmpl index dab8be33ca..68a90df52b 100644 --- a/modulegen/_template/docs_example.md.tmpl +++ b/modulegen/_template/docs_example.md.tmpl @@ -37,3 +37,7 @@ When starting the {{ $title }} container, you can pass options in a variadic way If you need to set a different {{ $title }} Docker image, you can use `testcontainers.WithImage` with a valid Docker image for {{ $title }}. E.g. `testcontainers.WithImage("{{ .Image }}")`. + +### Container Methods + +The {{ $title }} container exposes the following methods: From 9059f5ac17d104e1c346a83aade85edb0a518f2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Mon, 3 Apr 2023 09:51:25 +0200 Subject: [PATCH 31/42] docs: enrich section for documenting a module --- docs/modules/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/modules/index.md b/docs/modules/index.md index 0b7a52bc10..7d7a2b6041 100644 --- a/docs/modules/index.md +++ b/docs/modules/index.md @@ -80,7 +80,7 @@ func (c *Container) ConnectionString(ctx context.Context) (string, error) {...} ``` - Document the public API with Go comments. -- Extend the docs to describe the new API of the module. We usually define a parent `Module reference` section, including a `Container options` subsection; within the `Container options` subsection, we define a subsection for each option. +- Extend the docs to describe the new API of the module. We usually define a parent `Module reference` section, including a `Container options` and a `Container methods` subsections; within each subsection, we define a nested subsection for each option and method, respectively. ## Update Go dependencies in the modules From 3aba4a0df73a4fb31404e0d3778487502ccc3e81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Mon, 3 Apr 2023 10:32:17 +0200 Subject: [PATCH 32/42] chore: one less level of indirection for pulsar's container request --- modules/pulsar/pulsar.go | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/modules/pulsar/pulsar.go b/modules/pulsar/pulsar.go index 904d9042ac..2aed3a32b2 100644 --- a/modules/pulsar/pulsar.go +++ b/modules/pulsar/pulsar.go @@ -129,7 +129,7 @@ func WithTransactions() testcontainers.CustomizeRequestOption { // - the log message "Successfully updated the policies on namespace public/default" // - command: "/bin/bash -c /pulsar/bin/apply-config-from-env.py /pulsar/conf/standalone.conf && bin/pulsar standalone --no-functions-worker -nss" func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeRequestOption) (*Container, error) { - req := &testcontainers.ContainerRequest{ + req := testcontainers.ContainerRequest{ Image: defaultPulsarImage, Env: map[string]string{}, ExposedPorts: []string{defaultPulsarPort, defaultPulsarAdminPort}, @@ -137,16 +137,12 @@ func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeRequestOp Cmd: []string{"/bin/bash", "-c", strings.Join([]string{defaultPulsarCmd, detaultPulsarCmdWithoutFunctionsWorker}, " ")}, } - pulsarRequest := ContainerRequest{ - ContainerRequest: *req, - } - for _, opt := range opts { - opt(req) + opt(&req) } c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ - ContainerRequest: pulsarRequest.ContainerRequest, + ContainerRequest: req, Started: true, }) if err != nil { From 08fd14e3d4f16ca5656f48fcc7dfc2f6a0831de9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Mon, 3 Apr 2023 11:36:00 +0200 Subject: [PATCH 33/42] chore: remove unused type in pulsar --- modules/pulsar/pulsar.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/modules/pulsar/pulsar.go b/modules/pulsar/pulsar.go index 2aed3a32b2..da83ca7798 100644 --- a/modules/pulsar/pulsar.go +++ b/modules/pulsar/pulsar.go @@ -65,10 +65,6 @@ func (c *Container) resolveURL(ctx context.Context, port nat.Port) (string, erro return fmt.Sprintf("%s://%s:%v", proto, host, pulsarPort.Int()), nil } -type ContainerRequest struct { - testcontainers.ContainerRequest -} - // WithFunctionsWorker enables the functions worker, which will override the default pulsar command // and add a waiting strategy for the functions worker func WithFunctionsWorker() testcontainers.CustomizeRequestOption { From fccd0042e3f70d525dd5839c2dbb0155bcbfbc19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Mon, 3 Apr 2023 12:32:13 +0200 Subject: [PATCH 34/42] chore: rename functional option for wait strategies --- container.go | 6 +++--- docs/modules/index.md | 12 ++++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/container.go b/container.go index 2187445323..a5736332ef 100644 --- a/container.go +++ b/container.go @@ -178,11 +178,11 @@ func WithHostConfigModifier(modifier func(hostConfig *container.HostConfig)) Cus // WithWaitStrategy sets the wait strategy for a container, using 1 minute as deadline func WithWaitStrategy(strategies ...wait.Strategy) CustomizeRequestOption { - return WithWaitStrategyAndDuration(1*time.Minute, strategies...) + return WithWaitStrategyAndDeadline(1*time.Minute, strategies...) } -// WithWaitStrategy sets the wait strategy for a container, including deadline -func WithWaitStrategyAndDuration(deadline time.Duration, strategies ...wait.Strategy) CustomizeRequestOption { +// WithWaitStrategyAndDeadline sets the wait strategy for a container, including deadline +func WithWaitStrategyAndDeadline(deadline time.Duration, strategies ...wait.Strategy) CustomizeRequestOption { return func(req *ContainerRequest) { req.WaitingFor = wait.ForAll(strategies...).WithDeadline(deadline) } diff --git a/docs/modules/index.md b/docs/modules/index.md index 7d7a2b6041..264729b517 100644 --- a/docs/modules/index.md +++ b/docs/modules/index.md @@ -82,6 +82,18 @@ func (c *Container) ConnectionString(ctx context.Context) (string, error) {...} - Document the public API with Go comments. - Extend the docs to describe the new API of the module. We usually define a parent `Module reference` section, including a `Container options` and a `Container methods` subsections; within each subsection, we define a nested subsection for each option and method, respectively. +### ContainerRequest options + +`Testcontainers for Go` provides with a set of default options to customise the container request for a given module, in order to simplify the creation of the container. These options are: + +- `testcontainers.CustomizeRequest`: a function that merges the default options with the ones provided by the user. Recommended for completely customising the container request. +- `testcontainers.WithImage`: a function that sets the image for the container request. +- `testcontainers.WithConfigModifier`: a function that sets the config Docker type for the container request. +- `testcontainers.WithEndpointSettingsModifier`: a function that sets the endpoint settings Docker type for the container request. +- `testcontainers.WithHostConfigModifier`: a function that sets the host config Docker type for the container request. +- `testcontainers.WithWaitStrategy`: a function that sets the wait strategy for the container request. +- `testcontainers.WithWaitStrategyAndDeadline` + ## Update Go dependencies in the modules To update the Go dependencies in the modules, please run: From 044b4b78bfe7fce36decc762d3007642164ba428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Mon, 3 Apr 2023 12:33:21 +0200 Subject: [PATCH 35/42] chore: use seconds as deadline --- container.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/container.go b/container.go index a5736332ef..dbe5e2d6c5 100644 --- a/container.go +++ b/container.go @@ -176,9 +176,9 @@ func WithHostConfigModifier(modifier func(hostConfig *container.HostConfig)) Cus } } -// WithWaitStrategy sets the wait strategy for a container, using 1 minute as deadline +// WithWaitStrategy sets the wait strategy for a container, using 60 seconds as deadline func WithWaitStrategy(strategies ...wait.Strategy) CustomizeRequestOption { - return WithWaitStrategyAndDeadline(1*time.Minute, strategies...) + return WithWaitStrategyAndDeadline(60*time.Second, strategies...) } // WithWaitStrategyAndDeadline sets the wait strategy for a container, including deadline From d70ce733d9f1a658119da8a47f76d8e0510beeeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Mon, 3 Apr 2023 12:43:20 +0200 Subject: [PATCH 36/42] docs: reorg module docs --- docs/modules/index.md | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/docs/modules/index.md b/docs/modules/index.md index 264729b517..0f70968fb7 100644 --- a/docs/modules/index.md +++ b/docs/modules/index.md @@ -2,17 +2,6 @@ In this section you'll discover how to create Go modules for _Testcontainers for Go_. -## Interested in converting an example into a module? - -The steps to convert an existing example, aka `${THE_EXAMPLE}`, into a module are the following: - -1. Rename the module path at the `go.mod`file for your example. -1. Move the `examples/${THE_EXAMPLE}` directory to `modules/${THE_EXAMPLE}`. -1. Move the `${THE_EXAMPLE}` dependabot config from the examples section to the modules one, which is located at the bottom. -1. In the `mkdocs.yml` file, move the entry for `${THE_EXAMPLE}` from examples to modules. -1. Move `docs/examples${THE_EXAMPLE}.md` file to `docs/modules/${THE_EXAMPLE}`, updating the references to the source code paths. -1. Update the Github workflow for `${THE_EXAMPLE}`, modifying names and paths. - ## 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: @@ -57,7 +46,7 @@ or for creating a Go module: go run . --name ${NAME_OF_YOUR_MODULE} --image "${REGISTRY}/${MODULE}:${TAG}" --title ${TITLE_OF_YOUR_MODULE} --as-module ``` -## Adding types and methods to the module +### Adding types and methods to the module We are going to propose a set of steps to follow when adding types and methods to the module: @@ -84,17 +73,17 @@ func (c *Container) ConnectionString(ctx context.Context) (string, error) {...} ### ContainerRequest options -`Testcontainers for Go` provides with a set of default options to customise the container request for a given module, in order to simplify the creation of the container. These options are: +In order to simplify the creation of the container for a given module, `Testcontainers for Go` provides with a set of `testcontainers.CustomizeRequestOption` functions to customise the container request for the module. These options are: - `testcontainers.CustomizeRequest`: a function that merges the default options with the ones provided by the user. Recommended for completely customising the container request. - `testcontainers.WithImage`: a function that sets the image for the container request. -- `testcontainers.WithConfigModifier`: a function that sets the config Docker type for the container request. -- `testcontainers.WithEndpointSettingsModifier`: a function that sets the endpoint settings Docker type for the container request. -- `testcontainers.WithHostConfigModifier`: a function that sets the host config Docker type for the container request. -- `testcontainers.WithWaitStrategy`: a function that sets the wait strategy for the container request. -- `testcontainers.WithWaitStrategyAndDeadline` +- `testcontainers.WithConfigModifier`: a function that sets the config Docker type for the container request. Please see [Advanced Settings](../features/creating_container.md#advanced-settings) for more information. +- `testcontainers.WithEndpointSettingsModifier`: a function that sets the endpoint settings Docker type for the container request. Please see [Advanced Settings](../features/creating_container.md#advanced-settings) for more information. +- `testcontainers.WithHostConfigModifier`: a function that sets the host config Docker type for the container request. Please see [Advanced Settings](../features/creating_container.md#advanced-settings) for more information. +- `testcontainers.WithWaitStrategy`: a function that sets the wait strategy for the container request, adding all the passed wait strategies to the container request, using a `testcontainers.MultiStrategy` with 60 seconds of deadline. Please see [Wait strategies](../features/wait/multi.md) for more information. +- `testcontainers.WithWaitStrategyAndDeadline`: a function that sets the wait strategy for the container request, adding all the passed wait strategies to the container request, using a `testcontainers.MultiStrategy` with the passed deadline. Please see [Wait strategies](../features/wait/multi.md) for more information. -## Update Go dependencies in the modules +### Update Go dependencies in the modules To update the Go dependencies in the modules, please run: @@ -102,3 +91,14 @@ To update the Go dependencies in the modules, please run: $ cd modules $ make tidy-examples ``` + +## Interested in converting an example into a module? + +The steps to convert an existing example, aka `${THE_EXAMPLE}`, into a module are the following: + +1. Rename the module path at the `go.mod`file for your example. +1. Move the `examples/${THE_EXAMPLE}` directory to `modules/${THE_EXAMPLE}`. +1. Move the `${THE_EXAMPLE}` dependabot config from the examples section to the modules one, which is located at the bottom. +1. In the `mkdocs.yml` file, move the entry for `${THE_EXAMPLE}` from examples to modules. +1. Move `docs/examples${THE_EXAMPLE}.md` file to `docs/modules/${THE_EXAMPLE}`, updating the references to the source code paths. +1. Update the Github workflow for `${THE_EXAMPLE}`, modifying names and paths. From b984f04df698c89611d1178d667c0812286e750f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Mon, 3 Apr 2023 14:37:19 +0200 Subject: [PATCH 37/42] chore: move the customize function to the GenericContainerRequest It will allow providing access to the underlying Logger, the container Provider, the Started and Reuse states --- container.go | 56 --------------------------------- docs/modules/index.md | 6 ++-- generic.go | 61 ++++++++++++++++++++++++++++++++++++ modules/mysql/mysql.go | 23 +++++++------- modules/postgres/postgres.go | 26 ++++++++------- modules/pulsar/pulsar.go | 18 ++++++----- modules/redis/redis.go | 20 ++++++------ modules/redis/redis_test.go | 18 +++++++---- modules/vault/vault.go | 16 +++++----- 9 files changed, 132 insertions(+), 112 deletions(-) diff --git a/container.go b/container.go index dbe5e2d6c5..92ea80999e 100644 --- a/container.go +++ b/container.go @@ -13,7 +13,6 @@ import ( "github.com/docker/docker/api/types/network" "github.com/docker/docker/pkg/archive" "github.com/docker/go-connections/nat" - "github.com/imdario/mergo" tcexec "github.com/testcontainers/testcontainers-go/exec" "github.com/testcontainers/testcontainers-go/internal/testcontainersdocker" @@ -133,61 +132,6 @@ type containerOptions struct { // functional option for setting the reaper image type ContainerOption func(*containerOptions) -// CustomizeRequestOption is a type that can be used to configure the Testcontainers container request. -// The passed request will be merged with the default one. -type CustomizeRequestOption func(req *ContainerRequest) - -// CustomizeRequest returns a function that can be used to merge the passed container request with the one that is used by the container. -// Slices and Maps will be appended. -func CustomizeRequest(src ContainerRequest) CustomizeRequestOption { - return func(req *ContainerRequest) { - if err := mergo.Merge(req, &src, mergo.WithOverride, mergo.WithAppendSlice); err != nil { - fmt.Printf("error merging container request, keeping the original one. Error: %v", err) - return - } - } -} - -// WithImage sets the image for a container -func WithImage(image string) CustomizeRequestOption { - return func(req *ContainerRequest) { - req.Image = image - } -} - -// WithConfigModifier allows to override the default container config -func WithConfigModifier(modifier func(config *container.Config)) CustomizeRequestOption { - return func(req *ContainerRequest) { - req.ConfigModifier = modifier - } -} - -// WithEndpointSettingsModifier allows to override the default endpoint settings -func WithEndpointSettingsModifier(modifier func(settings map[string]*network.EndpointSettings)) CustomizeRequestOption { - return func(req *ContainerRequest) { - req.EnpointSettingsModifier = modifier - } -} - -// WithHostConfigModifier allows to override the default host config -func WithHostConfigModifier(modifier func(hostConfig *container.HostConfig)) CustomizeRequestOption { - return func(req *ContainerRequest) { - req.HostConfigModifier = modifier - } -} - -// WithWaitStrategy sets the wait strategy for a container, using 60 seconds as deadline -func WithWaitStrategy(strategies ...wait.Strategy) CustomizeRequestOption { - return WithWaitStrategyAndDeadline(60*time.Second, strategies...) -} - -// WithWaitStrategyAndDeadline sets the wait strategy for a container, including deadline -func WithWaitStrategyAndDeadline(deadline time.Duration, strategies ...wait.Strategy) CustomizeRequestOption { - return func(req *ContainerRequest) { - req.WaitingFor = wait.ForAll(strategies...).WithDeadline(deadline) - } -} - // WithImageName sets the reaper image name func WithImageName(imageName string) ContainerOption { return func(o *containerOptions) { diff --git a/docs/modules/index.md b/docs/modules/index.md index 0f70968fb7..eb7299b2ce 100644 --- a/docs/modules/index.md +++ b/docs/modules/index.md @@ -54,9 +54,9 @@ We are going to propose a set of steps to follow when adding types and methods t The `StartContainer` function will be eventually deprecated and replaced with `RunContainer`. We are keeping it in certain modules for backwards compatibility, but they will be removed in the future. - Make sure a public `Container` type exists for the module. This type have to use composition to embed the `testcontainers.Container` type, inheriting all the methods from it. -- Make sure a `RunContainer` function exists and is public. This function is the entrypoint to the module and will define the initial values for a `testcontainers.ContainerRequest` struct, including the image, the default exposed ports, wait strategies, etc. Therefore, the function must initialise the container request with the default values. -- Define container options for the module. We consider that a best practice for the options is to return a function that returns a modified `testcontainers.ContainerRequest` type, and for that, the library already provides with a `testcontainers.CustomizeRequestOption` type representing this function signature. -- The options will be passed to the `RunContainer` function as variadic arguments after the Go context, and they will be processed right after defining the initial `testcontainers.ContainerRequest` struct using a for loop. +- Make sure a `RunContainer` function exists and is public. This function is the entrypoint to the module and will define the initial values for a `testcontainers.GenericContainerRequest` struct, including the image, the default exposed ports, wait strategies, etc. Therefore, the function must initialise the container request with the default values. +- Define container options for the module. We consider that a best practice for the options is to return a function that returns a modified `testcontainers.GenericContainerRequest` type, and for that, the library already provides with a `testcontainers.CustomizeRequestOption` type representing this function signature. +- The options will be passed to the `RunContainer` function as variadic arguments after the Go context, and they will be processed right after defining the initial `testcontainers.GenericContainerRequest` struct using a for loop. ```golang func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeRequestOption) (*Container, error) {...} diff --git a/generic.go b/generic.go index ce79aa1100..b7b10efe03 100644 --- a/generic.go +++ b/generic.go @@ -5,6 +5,12 @@ import ( "errors" "fmt" "sync" + "time" + + "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/network" + "github.com/imdario/mergo" + "github.com/testcontainers/testcontainers-go/wait" ) var ( @@ -21,6 +27,61 @@ type GenericContainerRequest struct { Reuse bool // reuse an existing container if it exists or create a new one. a container name mustn't be empty } +// CustomizeRequestOption is a type that can be used to configure the Testcontainers container request. +// The passed request will be merged with the default one. +type CustomizeRequestOption func(req *GenericContainerRequest) + +// CustomizeRequest returns a function that can be used to merge the passed container request with the one that is used by the container. +// Slices and Maps will be appended. +func CustomizeRequest(src GenericContainerRequest) CustomizeRequestOption { + return func(req *GenericContainerRequest) { + if err := mergo.Merge(req, &src, mergo.WithOverride, mergo.WithAppendSlice); err != nil { + fmt.Printf("error merging container request, keeping the original one. Error: %v", err) + return + } + } +} + +// WithImage sets the image for a container +func WithImage(image string) CustomizeRequestOption { + return func(req *GenericContainerRequest) { + req.Image = image + } +} + +// WithConfigModifier allows to override the default container config +func WithConfigModifier(modifier func(config *container.Config)) CustomizeRequestOption { + return func(req *GenericContainerRequest) { + req.ConfigModifier = modifier + } +} + +// WithEndpointSettingsModifier allows to override the default endpoint settings +func WithEndpointSettingsModifier(modifier func(settings map[string]*network.EndpointSettings)) CustomizeRequestOption { + return func(req *GenericContainerRequest) { + req.EnpointSettingsModifier = modifier + } +} + +// WithHostConfigModifier allows to override the default host config +func WithHostConfigModifier(modifier func(hostConfig *container.HostConfig)) CustomizeRequestOption { + return func(req *GenericContainerRequest) { + req.HostConfigModifier = modifier + } +} + +// WithWaitStrategy sets the wait strategy for a container, using 60 seconds as deadline +func WithWaitStrategy(strategies ...wait.Strategy) CustomizeRequestOption { + return WithWaitStrategyAndDeadline(60*time.Second, strategies...) +} + +// WithWaitStrategyAndDeadline sets the wait strategy for a container, including deadline +func WithWaitStrategyAndDeadline(deadline time.Duration, strategies ...wait.Strategy) CustomizeRequestOption { + return func(req *GenericContainerRequest) { + req.WaitingFor = wait.ForAll(strategies...).WithDeadline(deadline) + } +} + // GenericNetworkRequest represents parameters to a generic network type GenericNetworkRequest struct { NetworkRequest // embedded request for provider diff --git a/modules/mysql/mysql.go b/modules/mysql/mysql.go index b4c66bfbb9..4cbb8e605e 100644 --- a/modules/mysql/mysql.go +++ b/modules/mysql/mysql.go @@ -37,7 +37,7 @@ func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeRequestOp WaitingFor: wait.ForLog("port: 3306 MySQL Community Server"), } - opts = append(opts, func(req *testcontainers.ContainerRequest) { + opts = append(opts, func(req *testcontainers.GenericContainerRequest) { username := req.Env["MYSQL_USER"] password := req.Env["MYSQL_PASSWORD"] if strings.EqualFold(rootUser, username) { @@ -51,8 +51,12 @@ func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeRequestOp } }) + genericContainerReq := testcontainers.GenericContainerRequest{ + ContainerRequest: req, + Started: true, + } for _, opt := range opts { - opt(&req) + opt(&genericContainerReq) } username, ok := req.Env["MYSQL_USER"] @@ -65,10 +69,7 @@ func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeRequestOp return nil, fmt.Errorf("empty password can be used only with the root user") } - container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ - ContainerRequest: req, - Started: true, - }) + container, err := testcontainers.GenericContainer(ctx, genericContainerReq) if err != nil { return nil, err } @@ -102,25 +103,25 @@ func (c *MySQLContainer) ConnectionString(ctx context.Context, args ...string) ( } func WithUsername(username string) testcontainers.CustomizeRequestOption { - return func(req *testcontainers.ContainerRequest) { + return func(req *testcontainers.GenericContainerRequest) { req.Env["MYSQL_USER"] = username } } func WithPassword(password string) testcontainers.CustomizeRequestOption { - return func(req *testcontainers.ContainerRequest) { + return func(req *testcontainers.GenericContainerRequest) { req.Env["MYSQL_PASSWORD"] = password } } func WithDatabase(database string) testcontainers.CustomizeRequestOption { - return func(req *testcontainers.ContainerRequest) { + return func(req *testcontainers.GenericContainerRequest) { req.Env["MYSQL_DATABASE"] = database } } func WithConfigFile(configFile string) testcontainers.CustomizeRequestOption { - return func(req *testcontainers.ContainerRequest) { + return func(req *testcontainers.GenericContainerRequest) { cf := testcontainers.ContainerFile{ HostFilePath: configFile, ContainerFilePath: "/etc/mysql/conf.d/my.cnf", @@ -131,7 +132,7 @@ func WithConfigFile(configFile string) testcontainers.CustomizeRequestOption { } func WithScripts(scripts ...string) testcontainers.CustomizeRequestOption { - return func(req *testcontainers.ContainerRequest) { + return func(req *testcontainers.GenericContainerRequest) { var initScripts []testcontainers.ContainerFile for _, script := range scripts { cf := testcontainers.ContainerFile{ diff --git a/modules/postgres/postgres.go b/modules/postgres/postgres.go index 3d3c52890a..ae44c2cc9c 100644 --- a/modules/postgres/postgres.go +++ b/modules/postgres/postgres.go @@ -48,7 +48,7 @@ func (c *PostgresContainer) ConnectionString(ctx context.Context, args ...string // It will also set the "config_file" parameter to the path of the config file // as a command line argument to the container func WithConfigFile(cfg string) testcontainers.CustomizeRequestOption { - return func(req *testcontainers.ContainerRequest) { + return func(req *testcontainers.GenericContainerRequest) { cfgFile := testcontainers.ContainerFile{ HostFilePath: cfg, ContainerFilePath: "/etc/postgresql.conf", @@ -65,14 +65,14 @@ func WithConfigFile(cfg string) testcontainers.CustomizeRequestOption { // It can be used to define a different name for the default database that is created when the image is first started. // If it is not specified, then the value of WithUser will be used. func WithDatabase(dbName string) testcontainers.CustomizeRequestOption { - return func(req *testcontainers.ContainerRequest) { + return func(req *testcontainers.GenericContainerRequest) { req.Env["POSTGRES_DB"] = dbName } } // WithInitScripts sets the init scripts to be run when the container starts func WithInitScripts(scripts ...string) testcontainers.CustomizeRequestOption { - return func(req *testcontainers.ContainerRequest) { + return func(req *testcontainers.GenericContainerRequest) { initScripts := []testcontainers.ContainerFile{} for _, script := range scripts { cf := testcontainers.ContainerFile{ @@ -89,8 +89,8 @@ func WithInitScripts(scripts ...string) testcontainers.CustomizeRequestOption { // WithPassword sets the initial password of the user to be created when the container starts // It is required for you to use the PostgreSQL image. It must not be empty or undefined. // This environment variable sets the superuser password for PostgreSQL. -func WithPassword(password string) func(req *testcontainers.ContainerRequest) { - return func(req *testcontainers.ContainerRequest) { +func WithPassword(password string) testcontainers.CustomizeRequestOption { + return func(req *testcontainers.GenericContainerRequest) { req.Env["POSTGRES_PASSWORD"] = password } } @@ -99,8 +99,8 @@ func WithPassword(password string) func(req *testcontainers.ContainerRequest) { // It is used in conjunction with WithPassword to set a user and its password. // It will create the specified user with superuser power and a database with the same name. // If it is not specified, then the default user of postgres will be used. -func WithUsername(user string) func(req *testcontainers.ContainerRequest) { - return func(req *testcontainers.ContainerRequest) { +func WithUsername(user string) testcontainers.CustomizeRequestOption { + return func(req *testcontainers.GenericContainerRequest) { if user == "" { user = defaultUser } @@ -122,14 +122,16 @@ func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeRequestOp Cmd: []string{"postgres", "-c", "fsync=off"}, } + genericContainerReq := testcontainers.GenericContainerRequest{ + ContainerRequest: req, + Started: true, + } + for _, opt := range opts { - opt(&req) + opt(&genericContainerReq) } - container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ - ContainerRequest: req, - Started: true, - }) + container, err := testcontainers.GenericContainer(ctx, genericContainerReq) if err != nil { return nil, err } diff --git a/modules/pulsar/pulsar.go b/modules/pulsar/pulsar.go index da83ca7798..112efd8916 100644 --- a/modules/pulsar/pulsar.go +++ b/modules/pulsar/pulsar.go @@ -68,7 +68,7 @@ func (c *Container) resolveURL(ctx context.Context, port nat.Port) (string, erro // WithFunctionsWorker enables the functions worker, which will override the default pulsar command // and add a waiting strategy for the functions worker func WithFunctionsWorker() testcontainers.CustomizeRequestOption { - return func(req *testcontainers.ContainerRequest) { + return func(req *testcontainers.GenericContainerRequest) { req.Cmd = []string{"/bin/bash", "-c", defaultPulsarCmd} // add the waiting strategy for the functions worker @@ -95,13 +95,13 @@ func (c *Container) WithLogConsumers(ctx context.Context, consumer ...testcontai // WithPulsarEnv allows to use the native APIs and set each variable with PULSAR_PREFIX_ as prefix. func WithPulsarEnv(configVar string, configValue string) testcontainers.CustomizeRequestOption { - return func(req *testcontainers.ContainerRequest) { + return func(req *testcontainers.GenericContainerRequest) { req.Env["PULSAR_PREFIX_"+configVar] = configValue } } func WithTransactions() testcontainers.CustomizeRequestOption { - return func(req *testcontainers.ContainerRequest) { + return func(req *testcontainers.GenericContainerRequest) { WithPulsarEnv("transactionCoordinatorEnabled", "true")(req) // add the waiting strategy for the transaction topic @@ -133,14 +133,16 @@ func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeRequestOp Cmd: []string{"/bin/bash", "-c", strings.Join([]string{defaultPulsarCmd, detaultPulsarCmdWithoutFunctionsWorker}, " ")}, } + genericContainerReq := testcontainers.GenericContainerRequest{ + ContainerRequest: req, + Started: true, + } + for _, opt := range opts { - opt(&req) + opt(&genericContainerReq) } - c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ - ContainerRequest: req, - Started: true, - }) + c, err := testcontainers.GenericContainer(ctx, genericContainerReq) if err != nil { return nil, err } diff --git a/modules/redis/redis.go b/modules/redis/redis.go index 935a521961..6b608ecc4b 100644 --- a/modules/redis/redis.go +++ b/modules/redis/redis.go @@ -54,14 +54,16 @@ func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeRequestOp WaitingFor: wait.ForLog("* Ready to accept connections"), } + genericContainerReq := testcontainers.GenericContainerRequest{ + ContainerRequest: req, + Started: true, + } + for _, opt := range opts { - opt(&req) + opt(&genericContainerReq) } - container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ - ContainerRequest: req, - Started: true, - }) + container, err := testcontainers.GenericContainer(ctx, genericContainerReq) if err != nil { return nil, err } @@ -74,7 +76,7 @@ func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeRequestOp func WithConfigFile(configFile string) testcontainers.CustomizeRequestOption { const defaultConfigFile = "/usr/local/redis.conf" - return func(req *testcontainers.ContainerRequest) { + return func(req *testcontainers.GenericContainerRequest) { cf := testcontainers.ContainerFile{ HostFilePath: configFile, ContainerFilePath: defaultConfigFile, @@ -101,7 +103,7 @@ func WithConfigFile(configFile string) testcontainers.CustomizeRequestOption { // WithLogLevel sets the log level for the redis server process // See https://redis.io/docs/reference/modules/modules-api-ref/#redismodule_log for more information. func WithLogLevel(level LogLevel) testcontainers.CustomizeRequestOption { - return func(req *testcontainers.ContainerRequest) { + return func(req *testcontainers.GenericContainerRequest) { processRedisServerArgs(req, []string{"--loglevel", string(level)}) } } @@ -118,12 +120,12 @@ func WithSnapshotting(seconds int, changedKeys int) testcontainers.CustomizeRequ seconds = 1 } - return func(req *testcontainers.ContainerRequest) { + return func(req *testcontainers.GenericContainerRequest) { processRedisServerArgs(req, []string{"--save", fmt.Sprintf("%d", seconds), fmt.Sprintf("%d", changedKeys)}) } } -func processRedisServerArgs(req *testcontainers.ContainerRequest, args []string) { +func processRedisServerArgs(req *testcontainers.GenericContainerRequest, args []string) { if len(req.Cmd) == 0 { req.Cmd = append([]string{redisServerProcess}, args...) return diff --git a/modules/redis/redis_test.go b/modules/redis/redis_test.go index 4a2f12718d..b9cffc032e 100644 --- a/modules/redis/redis_test.go +++ b/modules/redis/redis_test.go @@ -196,8 +196,10 @@ func TestWithConfigFile(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - req := &testcontainers.ContainerRequest{ - Cmd: tt.cmds, + req := &testcontainers.GenericContainerRequest{ + ContainerRequest: testcontainers.ContainerRequest{ + Cmd: tt.cmds, + }, } WithConfigFile("redis.conf")(req) @@ -232,8 +234,10 @@ func TestWithLogLevel(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - req := &testcontainers.ContainerRequest{ - Cmd: tt.cmds, + req := &testcontainers.GenericContainerRequest{ + ContainerRequest: testcontainers.ContainerRequest{ + Cmd: tt.cmds, + }, } WithLogLevel(LogLevelDebug)(req) @@ -283,8 +287,10 @@ func TestWithSnapshotting(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - req := &testcontainers.ContainerRequest{ - Cmd: tt.cmds, + req := &testcontainers.GenericContainerRequest{ + ContainerRequest: testcontainers.ContainerRequest{ + Cmd: tt.cmds, + }, } WithSnapshotting(tt.seconds, tt.changedKeys)(req) diff --git a/modules/vault/vault.go b/modules/vault/vault.go index b352d72875..bd34762754 100644 --- a/modules/vault/vault.go +++ b/modules/vault/vault.go @@ -35,14 +35,16 @@ func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeRequestOp }, } + genericContainerReq := testcontainers.GenericContainerRequest{ + ContainerRequest: req, + Started: true, + } + for _, opt := range opts { - opt(&req) + opt(&genericContainerReq) } - container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ - ContainerRequest: req, - Started: true, - }) + container, err := testcontainers.GenericContainer(ctx, genericContainerReq) if err != nil { return nil, err } @@ -52,7 +54,7 @@ func RunContainer(ctx context.Context, opts ...testcontainers.CustomizeRequestOp // WithToken is a container option function that sets the root token for the Vault func WithToken(token string) testcontainers.CustomizeRequestOption { - return func(req *testcontainers.ContainerRequest) { + return func(req *testcontainers.GenericContainerRequest) { req.Env["VAULT_DEV_ROOT_TOKEN_ID"] = token req.Env["VAULT_TOKEN"] = token } @@ -60,7 +62,7 @@ func WithToken(token string) testcontainers.CustomizeRequestOption { // WithInitCommand is an option function that adds a set of initialization commands to the Vault's configuration func WithInitCommand(commands ...string) testcontainers.CustomizeRequestOption { - return func(req *testcontainers.ContainerRequest) { + return func(req *testcontainers.GenericContainerRequest) { commandsList := make([]string, 0, len(commands)) for _, command := range commands { commandsList = append(commandsList, "vault "+command) From 0a198fd93b3bd5b071229896de1eadcac8e06da5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Mon, 3 Apr 2023 18:36:57 +0200 Subject: [PATCH 38/42] chore: migrate neo4j to new options types --- modules/neo4j/config.go | 96 ++++++++++++++----------------------- modules/neo4j/neo4j.go | 44 +++++++++-------- modules/neo4j/neo4j_test.go | 13 ++--- 3 files changed, 68 insertions(+), 85 deletions(-) diff --git a/modules/neo4j/config.go b/modules/neo4j/config.go index cbf27e65a6..b0a0dd6da4 100644 --- a/modules/neo4j/config.go +++ b/modules/neo4j/config.go @@ -3,19 +3,10 @@ package neo4j import ( "errors" "fmt" - "github.com/testcontainers/testcontainers-go" "strings" -) - -type Option func(*config) -type config struct { - imageCoordinates string - adminPassword string - labsPlugins []string - neo4jSettings map[string]string - logger testcontainers.Logging -} + "github.com/testcontainers/testcontainers-go" +) type LabsPlugin string @@ -29,35 +20,36 @@ const ( ) // WithoutAuthentication disables authentication. -func WithoutAuthentication() Option { +func WithoutAuthentication() testcontainers.CustomizeRequestOption { return WithAdminPassword("") } // WithAdminPassword sets the admin password for the default account // An empty string disables authentication. // The default password is "password". -func WithAdminPassword(adminPassword string) Option { - return func(c *config) { - c.adminPassword = adminPassword - } -} +func WithAdminPassword(adminPassword string) testcontainers.CustomizeRequestOption { + return func(req *testcontainers.GenericContainerRequest) { + pwd := "none" + if adminPassword != "" { + pwd = fmt.Sprintf("neo4j/%s", adminPassword) + } -// WithImageCoordinates sets the image coordinates of the Neo4j container. -func WithImageCoordinates(imageCoordinates string) Option { - return func(c *config) { - c.imageCoordinates = imageCoordinates + req.Env["NEO4J_AUTH"] = pwd } } // WithLabsPlugin registers one or more Neo4jLabsPlugin for download and server startup. // There might be plugins not supported by your selected version of Neo4j. -func WithLabsPlugin(plugins ...LabsPlugin) Option { - return func(c *config) { +func WithLabsPlugin(plugins ...LabsPlugin) testcontainers.CustomizeRequestOption { + return func(req *testcontainers.GenericContainerRequest) { rawPluginValues := make([]string, len(plugins)) for i := 0; i < len(plugins); i++ { rawPluginValues[i] = string(plugins[i]) } - c.labsPlugins = rawPluginValues + + if len(plugins) > 0 { + req.Env["NEO4JLABS_PLUGINS"] = fmt.Sprintf(`["%s"]`, strings.Join(rawPluginValues, `","`)) + } } } @@ -67,9 +59,9 @@ func WithLabsPlugin(plugins ...LabsPlugin) Option { // This function can be called multiple times. A warning is emitted if a key is overwritten. // See WithNeo4jSettings to add multiple settings at once // Note: credentials must be configured with WithAdminPassword -func WithNeo4jSetting(key, value string) Option { - return func(c *config) { - c.addSetting(key, value) +func WithNeo4jSetting(key, value string) testcontainers.CustomizeRequestOption { + return func(req *testcontainers.GenericContainerRequest) { + addSetting(req, key, value) } } @@ -79,52 +71,38 @@ func WithNeo4jSetting(key, value string) Option { // This function can be called multiple times. A warning is emitted if a key is overwritten. // See WithNeo4jSetting to add a single setting // Note: credentials must be configured with WithAdminPassword -func WithNeo4jSettings(settings map[string]string) Option { - return func(c *config) { +func WithNeo4jSettings(settings map[string]string) testcontainers.CustomizeRequestOption { + return func(req *testcontainers.GenericContainerRequest) { for key, value := range settings { - c.addSetting(key, value) + addSetting(req, key, value) } } } // WithLogger sets a custom logger to be used by the container // Consider calling this before other "With functions" as these may generate logs -func WithLogger(logger testcontainers.Logging) Option { - return func(c *config) { - c.logger = logger +func WithLogger(logger testcontainers.Logging) testcontainers.CustomizeRequestOption { + return func(req *testcontainers.GenericContainerRequest) { + req.Logger = logger } } -func (c *config) exportEnv() map[string]string { - env := c.neo4jSettings // set this first to ensure it has the lowest precedence - env["NEO4J_AUTH"] = c.authEnvVar() - if len(c.labsPlugins) > 0 { - env["NEO4JLABS_PLUGINS"] = c.labsPluginsEnvVar() - } - return env -} - -func (c *config) authEnvVar() string { - if c.adminPassword == "" { - return "none" - } - return fmt.Sprintf("neo4j/%s", c.adminPassword) -} - -func (c *config) labsPluginsEnvVar() string { - return fmt.Sprintf(`["%s"]`, strings.Join(c.labsPlugins, `","`)) -} - -func (c *config) addSetting(key string, newVal string) { +func addSetting(req *testcontainers.GenericContainerRequest, key string, newVal string) { normalizedKey := formatNeo4jConfig(key) - if oldVal, found := c.neo4jSettings[normalizedKey]; found { - c.logger.Printf("setting %q with value %q is now overwritten with value %q\n", []any{key, oldVal, newVal}...) + if oldVal, found := req.Env[normalizedKey]; found { + // make sure AUTH is not overwritten by a setting + if key == "AUTH" { + req.Logger.Printf("setting %q is not permitted, WithAdminPassword as already been set\n", normalizedKey) + return + } + + req.Logger.Printf("setting %q with value %q is now overwritten with value %q\n", []any{key, oldVal, newVal}...) } - c.neo4jSettings[normalizedKey] = newVal + req.Env[normalizedKey] = newVal } -func (c *config) validate() error { - if c.logger == nil { +func validate(req *testcontainers.GenericContainerRequest) error { + if req.Logger == nil { return errors.New("nil logger is not permitted") } return nil diff --git a/modules/neo4j/neo4j.go b/modules/neo4j/neo4j.go index e4b36e0150..8b8356c408 100644 --- a/modules/neo4j/neo4j.go +++ b/modules/neo4j/neo4j.go @@ -3,10 +3,11 @@ package neo4j import ( "context" "fmt" + "net/http" + "github.com/docker/go-connections/nat" "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/wait" - "net/http" ) const defaultImageName = "neo4j" @@ -36,26 +37,14 @@ func (c Neo4jContainer) BoltUrl(ctx context.Context) (string, error) { return fmt.Sprintf("neo4j://%s:%d", host, mappedPort.Int()), nil } -// StartContainer creates an instance of the Neo4j container type -func StartContainer(ctx context.Context, options ...Option) (*Neo4jContainer, error) { - settings := &config{ - imageCoordinates: fmt.Sprintf("docker.io/%s:%s", defaultImageName, defaultTag), - adminPassword: "password", - neo4jSettings: map[string]string{}, - logger: testcontainers.Logger, - } - for _, option := range options { - option(settings) - } - - if err := settings.validate(); err != nil { - return nil, err - } - +// RunContainer creates an instance of the Neo4j container type +func RunContainer(ctx context.Context, options ...testcontainers.CustomizeRequestOption) (*Neo4jContainer, error) { httpPort, _ := nat.NewPort("tcp", defaultHttpPort) request := testcontainers.ContainerRequest{ - Image: settings.imageCoordinates, - Env: settings.exportEnv(), + Image: fmt.Sprintf("docker.io/%s:%s", defaultImageName, defaultTag), + Env: map[string]string{ + "NEO4J_AUTH": "none", + }, ExposedPorts: []string{ fmt.Sprintf("%s/tcp", defaultBoltPort), fmt.Sprintf("%s/tcp", defaultHttpPort), @@ -71,10 +60,25 @@ func StartContainer(ctx context.Context, options ...Option) (*Neo4jContainer, er }, }, } + + genericContainerReq := testcontainers.GenericContainerRequest{ + ContainerRequest: request, + Logger: testcontainers.Logger, + Started: true, + } + + for _, option := range options { + option(&genericContainerReq) + } + + err := validate(&genericContainerReq) + if err != nil { + return nil, err + } + container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ ContainerRequest: request, Started: true, - Logger: settings.logger, }) if err != nil { return nil, err diff --git a/modules/neo4j/neo4j_test.go b/modules/neo4j/neo4j_test.go index 1f8ce5355e..ca51242186 100644 --- a/modules/neo4j/neo4j_test.go +++ b/modules/neo4j/neo4j_test.go @@ -3,11 +3,12 @@ package neo4j_test import ( "context" "fmt" - neo "github.com/neo4j/neo4j-go-driver/v5/neo4j" - "github.com/testcontainers/testcontainers-go/modules/neo4j" "io" "strings" "testing" + + neo "github.com/neo4j/neo4j-go-driver/v5/neo4j" + "github.com/testcontainers/testcontainers-go/modules/neo4j" ) const testPassword = "letmein!" @@ -65,7 +66,7 @@ func TestNeo4jWithWrongSettings(outer *testing.T) { ctx := context.Background() outer.Run("ignores auth setting outside WithAdminPassword", func(t *testing.T) { - container, err := neo4j.StartContainer(ctx, + container, err := neo4j.RunContainer(ctx, neo4j.WithAdminPassword(testPassword), neo4j.WithNeo4jSetting("AUTH", "neo4j/thisisgonnabeignored"), ) @@ -87,7 +88,7 @@ func TestNeo4jWithWrongSettings(outer *testing.T) { outer.Run("warns about overwrites of setting keys", func(t *testing.T) { logger := &inMemoryLogger{} - container, err := neo4j.StartContainer(ctx, + container, err := neo4j.RunContainer(ctx, neo4j.WithLogger(logger), // needs to go before WithNeo4jSetting and WithNeo4jSettings neo4j.WithAdminPassword(testPassword), neo4j.WithNeo4jSetting("some.key", "value1"), @@ -114,7 +115,7 @@ func TestNeo4jWithWrongSettings(outer *testing.T) { }) outer.Run("rejects nil logger", func(t *testing.T) { - container, err := neo4j.StartContainer(ctx, neo4j.WithLogger(nil)) + container, err := neo4j.RunContainer(ctx, neo4j.WithLogger(nil)) if container != nil { t.Fatalf("container must not be created with nil logger") @@ -127,7 +128,7 @@ func TestNeo4jWithWrongSettings(outer *testing.T) { func setupNeo4j(ctx context.Context, t *testing.T) *neo4j.Neo4jContainer { // neo4jCreateContainer { - container, err := neo4j.StartContainer(ctx, + container, err := neo4j.RunContainer(ctx, neo4j.WithAdminPassword(testPassword), neo4j.WithLabsPlugin(neo4j.Apoc), neo4j.WithNeo4jSetting("dbms.tx_log.rotation.size", "42M"), From e48c7fbcc85855a825bb8de6f34befa1ed76d17a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Tue, 4 Apr 2023 07:45:07 +0200 Subject: [PATCH 39/42] docs: include the existing customize options in the generated docs --- modulegen/_template/docs_example.md.tmpl | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/modulegen/_template/docs_example.md.tmpl b/modulegen/_template/docs_example.md.tmpl index 68a90df52b..67f99a5f9a 100644 --- a/modulegen/_template/docs_example.md.tmpl +++ b/modulegen/_template/docs_example.md.tmpl @@ -38,6 +38,26 @@ When starting the {{ $title }} container, you can pass options in a variadic way If you need to set a different {{ $title }} Docker image, you can use `testcontainers.WithImage` with a valid Docker image for {{ $title }}. E.g. `testcontainers.WithImage("{{ .Image }}")`. +#### Wait Strategies + +If you need to set a different wait strategy for {{ $title }}, you can use `testcontainers.WithWaitStrategy` with a valid wait strategy +for {{ $title }}. + +!!!info + The default deadline for the wait strategy is 60 seconds. + +At the same time, it's possible to set a wait strategy and a custom deadline with `testcontainers.WithWaitStrategyAndDeadline`. + +#### Docker type modifiers + +If you need an advanced configuration for {{ $title }}, you can leverage the following Docker type modifiers: + +- `testcontainers.WithConfigModifier` +- `testcontainers.WithHostConfigModifier` +- `testcontainers.WithEndpointSettingsModifier` + +Please read the [Create containers: Advanced Settings](../features/creating_container.md#advanced-settings) documentation for more information. + ### Container Methods The {{ $title }} container exposes the following methods: From 47be787b43020d15005d65661fa1bd9601cf05aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Tue, 4 Apr 2023 07:46:30 +0200 Subject: [PATCH 40/42] chore: add a test for neo4j without auth --- modules/neo4j/neo4j.go | 4 ++++ modules/neo4j/neo4j_test.go | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/modules/neo4j/neo4j.go b/modules/neo4j/neo4j.go index 8b8356c408..d9206126c6 100644 --- a/modules/neo4j/neo4j.go +++ b/modules/neo4j/neo4j.go @@ -67,6 +67,10 @@ func RunContainer(ctx context.Context, options ...testcontainers.CustomizeReques Started: true, } + if len(options) == 0 { + options = append(options, WithoutAuthentication()) + } + for _, option := range options { option(&genericContainerReq) } diff --git a/modules/neo4j/neo4j_test.go b/modules/neo4j/neo4j_test.go index ca51242186..913cc21149 100644 --- a/modules/neo4j/neo4j_test.go +++ b/modules/neo4j/neo4j_test.go @@ -65,6 +65,16 @@ func TestNeo4jWithWrongSettings(outer *testing.T) { ctx := context.Background() + outer.Run("without authentication", func(t *testing.T) { + container, err := neo4j.RunContainer(ctx) + if err != nil { + t.Fatalf("expected env to successfully run but did not: %s", err) + } + if container != nil { + t.Fatalf("container must not be created with nil logger") + } + }) + outer.Run("ignores auth setting outside WithAdminPassword", func(t *testing.T) { container, err := neo4j.RunContainer(ctx, neo4j.WithAdminPassword(testPassword), From 4999c4aec23388a0258c708108e07bb91216494f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Tue, 4 Apr 2023 09:26:31 +0200 Subject: [PATCH 41/42] fix: update test --- container_test.go | 50 +++++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/container_test.go b/container_test.go index 54b335f422..04c57c615a 100644 --- a/container_test.go +++ b/container_test.go @@ -421,34 +421,38 @@ func TestVolumeMount(t *testing.T) { } func TestOverrideContainerRequest(t *testing.T) { - req := ContainerRequest{ - Env: map[string]string{ - "BAR": "BAR", - }, - Image: "foo", - ExposedPorts: []string{"12345/tcp"}, - WaitingFor: wait.ForNop( - func(ctx context.Context, target wait.StrategyTarget) error { - return nil + req := GenericContainerRequest{ + ContainerRequest: ContainerRequest{ + Env: map[string]string{ + "BAR": "BAR", + }, + Image: "foo", + ExposedPorts: []string{"12345/tcp"}, + WaitingFor: wait.ForNop( + func(ctx context.Context, target wait.StrategyTarget) error { + return nil + }, + ), + Networks: []string{"foo", "bar", "baaz"}, + NetworkAliases: map[string][]string{ + "foo": {"foo0", "foo1", "foo2", "foo3"}, }, - ), - Networks: []string{"foo", "bar", "baaz"}, - NetworkAliases: map[string][]string{ - "foo": {"foo0", "foo1", "foo2", "foo3"}, }, } - toBeMergedRequest := ContainerRequest{ - Env: map[string]string{ - "FOO": "FOO", - }, - Image: "bar", - ExposedPorts: []string{"67890/tcp"}, - Networks: []string{"foo1", "bar1"}, - NetworkAliases: map[string][]string{ - "foo1": {"bar"}, + toBeMergedRequest := GenericContainerRequest{ + ContainerRequest: ContainerRequest{ + Env: map[string]string{ + "FOO": "FOO", + }, + Image: "bar", + ExposedPorts: []string{"67890/tcp"}, + Networks: []string{"foo1", "bar1"}, + NetworkAliases: map[string][]string{ + "foo1": {"bar"}, + }, + WaitingFor: wait.ForLog("foo"), }, - WaitingFor: wait.ForLog("foo"), } // the toBeMergedRequest should be merged into the req From 9c9293ba31a8f98efa3aa96b73eab8fc70c7e7f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Tue, 4 Apr 2023 10:32:22 +0200 Subject: [PATCH 42/42] fix: wrong copy-paste --- modules/neo4j/neo4j_test.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/neo4j/neo4j_test.go b/modules/neo4j/neo4j_test.go index 913cc21149..82bb738bb3 100644 --- a/modules/neo4j/neo4j_test.go +++ b/modules/neo4j/neo4j_test.go @@ -70,9 +70,11 @@ func TestNeo4jWithWrongSettings(outer *testing.T) { if err != nil { t.Fatalf("expected env to successfully run but did not: %s", err) } - if container != nil { - t.Fatalf("container must not be created with nil logger") - } + t.Cleanup(func() { + if err := container.Terminate(ctx); err != nil { + outer.Fatalf("failed to terminate container: %s", err) + } + }) }) outer.Run("ignores auth setting outside WithAdminPassword", func(t *testing.T) {