Skip to content

Commit

Permalink
Merge branch 'main' into upgrade-v0.29.1
Browse files Browse the repository at this point in the history
  • Loading branch information
mdelapenya authored Apr 3, 2024
2 parents 27aa00c + d24cf91 commit 41b99e4
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 23 deletions.
2 changes: 1 addition & 1 deletion docker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1854,7 +1854,7 @@ func TestContainerWithNoUserID(t *testing.T) {
}

func TestGetGatewayIP(t *testing.T) {
// When using docker-compose with DinD mode, and using host port or http wait strategy
// When using docker compose with DinD mode, and using host port or http wait strategy
// It's need to invoke GetGatewayIP for get the host
provider, err := providerType.GetProvider(WithLogger(TestLogger(t)))
if err != nil {
Expand Down
20 changes: 10 additions & 10 deletions docs/features/docker_compose.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ This is intended to be useful on projects where Docker Compose is already used
in dev or other environments to define services that an application may be
dependent upon.

## Using `docker-compose` directly
## Using `docker compose` directly

!!!warning
The minimal version of Go required to use this module is **1.21**.
Expand All @@ -16,9 +16,9 @@ dependent upon.
go get github.com/testcontainers/testcontainers-go/modules/compose
```

Because `docker-compose` v2 is implemented in Go it's possible for _Testcontainers for Go_ to
Because `compose` v2 is implemented in Go it's possible for _Testcontainers for Go_ to
use [`github.com/docker/compose`](https://github.com/docker/compose) directly and skip any process execution/_docker-compose-in-a-container_ scenario.
The `ComposeStack` API exposes this variant of using `docker-compose` in an easy way.
The `ComposeStack` API exposes this variant of using `docker compose` in an easy way.

### Basic examples

Expand Down Expand Up @@ -88,14 +88,14 @@ func TestSomethingElse(t *testing.T) {

To interact with service containers after a stack was started it is possible to get an `*tc.DockerContainer` instance via the `ServiceContainer(...)` function.
The function takes a **service name** (and a `context.Context`) and returns either a `*tc.DockerContainer` or an `error`.
This is different to the previous `LocalDockerCompose` API where service containers were accessed via their **container name** e.g. `mysql_1` or `mysql-1` (depending on the version of `docker-compose`).
This is different to the previous `LocalDockerCompose` API where service containers were accessed via their **container name** e.g. `mysql_1` or `mysql-1` (depending on the version of `docker compose`).

Furthermore, there's the convenience function `Serices()` to get a list of all services **defined** by the current project.
Note that not all of them need necessarily be correctly started as the information is based on the given compose files.

### Wait strategies

Just like with regular test containers you can also apply wait strategies to `docker-compose` services.
Just like with regular test containers you can also apply wait strategies to `docker compose` services.
The `ComposeStack.WaitForService(...)` function allows you to apply a wait strategy to **a service by name**.
All wait strategies are executed in parallel to both improve startup performance by not blocking too long and to fail
early if something's wrong.
Expand Down Expand Up @@ -139,7 +139,7 @@ func TestSomethingWithWaiting(t *testing.T) {

### Compose environment

`docker-compose` supports expansion based on environment variables.
`docker compose` supports expansion based on environment variables.
The `ComposeStack` supports this as well in two different variants:

- `ComposeStack.WithEnv(m map[string]string) ComposeStack` to parameterize stacks from your test code
Expand All @@ -150,14 +150,14 @@ The `ComposeStack` supports this as well in two different variants:
Also have a look at [ComposeStack](https://pkg.go.dev/github.com/testcontainers/testcontainers-go#ComposeStack) docs for
further information.

## Usage of `docker-compose` binary
## Usage of the `docker compose` binary

_Node:_ this API is deprecated and superseded by `ComposeStack` which takes advantage of `docker-compose` v2 being
_Node:_ this API is deprecated and superseded by `ComposeStack` which takes advantage of `compose` v2 being
implemented in Go as well by directly using the upstream project.

You can override Testcontainers' default behaviour and make it use a
docker-compose binary installed on the local machine. This will generally yield
an experience that is closer to running docker-compose locally, with the caveat
docker compose binary installed on the local machine. This will generally yield
an experience that is closer to running docker compose locally, with the caveat
that Docker Compose needs to be present on dev and CI machines.

### Examples
Expand Down
5 changes: 3 additions & 2 deletions modules/compose/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,12 @@ func NewLocalDockerCompose(filePaths []string, identifier string, opts ...LocalD
opts[idx].ApplyToLocalCompose(dc.LocalDockerComposeOptions)
}

dc.Executable = "docker-compose"
dc.Executable = "docker"
if runtime.GOOS == "windows" {
dc.Executable = "docker-compose.exe"
dc.Executable = "docker.exe"
}

dc.composeSubcommand = "compose"
dc.ComposeFilePaths = filePaths

dc.absComposeFilePaths = make([]string, len(filePaths))
Expand Down
3 changes: 1 addition & 2 deletions modules/compose/compose_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func (f stackDownOptionFunc) applyToStackDown(do *api.DownOptions) {
f(do)
}

// RunServices is comparable to 'docker-compose run' as it only creates a subset of containers
// RunServices is comparable to 'docker compose run' as it only creates a subset of containers
// instead of all services defined by the project
func RunServices(serviceNames ...string) StackUpOption {
return stackUpOptionFunc(func(o *stackUpOptions) {
Expand Down Expand Up @@ -231,7 +231,6 @@ func (d *dockerCompose) Up(ctx context.Context, opts ...StackUpOption) error {
Wait: upOptions.Wait,
},
})

if err != nil {
return err
}
Expand Down
34 changes: 27 additions & 7 deletions modules/compose/compose_local.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,14 @@ func (c composeVersion2) Format(parts ...string) string {
return strings.Join(parts, "-")
}

// Deprecated: use ComposeStack instead
// LocalDockerCompose represents a Docker Compose execution using local binary
// docker-compose or docker-compose.exe, depending on the underlying platform
// docker compose or docker.exe compose, depending on the underlying platform
type LocalDockerCompose struct {
ComposeVersion
*LocalDockerComposeOptions
Executable string
composeSubcommand string
ComposeFilePaths []string
absComposeFilePaths []string
Identifier string
Expand All @@ -58,17 +60,20 @@ type LocalDockerCompose struct {
}

type (
// Deprecated: it will be removed in the next major release
// LocalDockerComposeOptions defines options applicable to LocalDockerCompose
LocalDockerComposeOptions struct {
Logger testcontainers.Logging
}

// Deprecated: it will be removed in the next major release
// LocalDockerComposeOption defines a common interface to modify LocalDockerComposeOptions
// These options can be passed to NewLocalDockerCompose in a variadic way to customize the returned LocalDockerCompose instance
LocalDockerComposeOption interface {
ApplyToLocalCompose(opts *LocalDockerComposeOptions)
}

// Deprecated: it will be removed in the next major release
// LocalDockerComposeOptionsFunc is a shorthand to implement the LocalDockerComposeOption interface
LocalDockerComposeOptionsFunc func(opts *LocalDockerComposeOptions)
)
Expand All @@ -86,6 +91,7 @@ func WithLogger(logger testcontainers.Logging) ComposeLoggerOption {
}
}

// Deprecated: it will be removed in the next major release
func (o ComposeLoggerOption) ApplyToLocalCompose(opts *LocalDockerComposeOptions) {
opts.Logger = o.logger
}
Expand All @@ -94,15 +100,18 @@ func (o ComposeLoggerOption) applyToComposeStack(opts *composeStackOptions) {
opts.Logger = o.logger
}

// Deprecated: it will be removed in the next major release
func (f LocalDockerComposeOptionsFunc) ApplyToLocalCompose(opts *LocalDockerComposeOptions) {
f(opts)
}

// Down executes docker-compose down
// Deprecated: it will be removed in the next major release
// Down executes docker compose down
func (dc *LocalDockerCompose) Down() ExecError {
return executeCompose(dc, []string{"down", "--remove-orphans", "--volumes"})
}

// Deprecated: it will be removed in the next major release
func (dc *LocalDockerCompose) getDockerComposeEnvironment() map[string]string {
environment := map[string]string{}

Expand All @@ -117,10 +126,12 @@ func (dc *LocalDockerCompose) getDockerComposeEnvironment() map[string]string {
return environment
}

// Deprecated: it will be removed in the next major release
func (dc *LocalDockerCompose) containerNameFromServiceName(service, separator string) string {
return dc.Identifier + separator + service
}

// Deprecated: it will be removed in the next major release
func (dc *LocalDockerCompose) applyStrategyToRunningContainer() error {
cli, err := testcontainers.NewDockerClientWithOpts(context.Background())
if err != nil {
Expand Down Expand Up @@ -163,36 +174,41 @@ func (dc *LocalDockerCompose) applyStrategyToRunningContainer() error {

err = strategy.WaitUntilReady(context.Background(), dockercontainer)
if err != nil {
return fmt.Errorf("Unable to apply wait strategy %v to service %s due to %w", strategy, k.service, err)
return fmt.Errorf("unable to apply wait strategy %v to service %s due to %w", strategy, k.service, err)
}
}
return nil
}

// Deprecated: it will be removed in the next major release
// Invoke invokes the docker compose
func (dc *LocalDockerCompose) Invoke() ExecError {
return executeCompose(dc, dc.Cmd)
}

// Deprecated: it will be removed in the next major release
// WaitForService sets the strategy for the service that is to be waited on
func (dc *LocalDockerCompose) WaitForService(service string, strategy wait.Strategy) DockerCompose {
dc.waitStrategySupplied = true
dc.WaitStrategyMap[waitService{service: service}] = strategy
return dc
}

// Deprecated: it will be removed in the next major release
// WithCommand assigns the command
func (dc *LocalDockerCompose) WithCommand(cmd []string) DockerCompose {
dc.Cmd = cmd
return dc
}

// Deprecated: it will be removed in the next major release
// WithEnv assigns the environment
func (dc *LocalDockerCompose) WithEnv(env map[string]string) DockerCompose {
dc.Env = env
return dc
}

// Deprecated: it will be removed in the next major release
// WithExposedService sets the strategy for the service that is to be waited on. If multiple strategies
// are given for a single service running on different ports, both strategies will be applied on the same container
func (dc *LocalDockerCompose) WithExposedService(service string, port int, strategy wait.Strategy) DockerCompose {
Expand All @@ -201,7 +217,8 @@ func (dc *LocalDockerCompose) WithExposedService(service string, port int, strat
return dc
}

// determineVersion checks which version of docker-compose is installed
// Deprecated: it will be removed in the next major release
// determineVersion checks which version of docker compose is installed
// depending on the version services names are composed in a different way
func (dc *LocalDockerCompose) determineVersion() error {
execErr := executeCompose(dc, []string{"version", "--short"})
Expand Down Expand Up @@ -232,6 +249,7 @@ func (dc *LocalDockerCompose) determineVersion() error {
return nil
}

// Deprecated: it will be removed in the next major release
// validate checks if the files to be run in the compose are valid YAML files, setting up
// references to all services in them
func (dc *LocalDockerCompose) validate() error {
Expand Down Expand Up @@ -336,11 +354,12 @@ func execute(
}
}

// Deprecated: it will be removed in the next major release
func executeCompose(dc *LocalDockerCompose, args []string) ExecError {
if which(dc.Executable) != nil {
return ExecError{
Command: []string{dc.Executable},
Error: fmt.Errorf("Local Docker Compose not found. Is %s on the PATH?", dc.Executable),
Error: fmt.Errorf("Local Docker not found. Is %s on the PATH?", dc.Executable),
}
}

Expand All @@ -349,7 +368,8 @@ func executeCompose(dc *LocalDockerCompose, args []string) ExecError {
environment[k] = v
}

var cmds []string
// initialise the command with the compose subcommand
cmds := []string{dc.composeSubcommand}
pwd := "."
if len(dc.absComposeFilePaths) > 0 {
pwd, _ = filepath.Split(dc.absComposeFilePaths[0])
Expand All @@ -367,7 +387,7 @@ func executeCompose(dc *LocalDockerCompose, args []string) ExecError {
if err != nil {
args := strings.Join(dc.Cmd, " ")
return ExecError{
Command: []string{dc.Executable},
Command: []string{dc.Executable, args},
Error: fmt.Errorf("Local Docker compose exited abnormally whilst running %s: [%v]. %s", dc.Executable, args, err.Error()),
}
}
Expand Down
2 changes: 1 addition & 1 deletion modules/compose/compose_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func ExampleNewLocalDockerCompose() {

func ExampleLocalDockerCompose() {
_ = LocalDockerCompose{
Executable: "docker-compose",
Executable: "docker compose",
ComposeFilePaths: []string{
"/path/to/docker-compose.yml",
"/path/to/docker-compose-1.yml",
Expand Down

0 comments on commit 41b99e4

Please sign in to comment.