Skip to content

Commit

Permalink
feat: expose a WithNetwork functional option (#1887)
Browse files Browse the repository at this point in the history
* feat: move WithNetwork functional option to the core

* chore: reuse the network if it already existed
  • Loading branch information
mdelapenya committed Nov 2, 2023
1 parent 27481c5 commit 0ce34a8
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 26 deletions.
8 changes: 8 additions & 0 deletions docs/features/common_functional_options.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ It also exports an `Executable` interface, defining one single method: `AsComman

You could use this feature to run a custom script, or to run a command that is not supported by the module right after the container is started.

#### WithNetwork

- Not available until the next release of testcontainers-go <a href="https://github.com/testcontainers/testcontainers-go"><span class="tc-version">:material-tag: main</span></a>

By default, the container is started in the default Docker network. If you want to use a different Docker network, you can use the `WithNetwork(networkName string, alias string)` option, which receives the new network name and an alias as parameters, creating the new network, attaching the container to it, and setting the network alias for that network.

If the network already exists, _Testcontainers for Go_ won't create a new one, but it will attach the container to it and set the network alias.

#### Docker type modifiers

If you need an advanced configuration for the container, you can leverage the following Docker type modifiers:
Expand Down
4 changes: 0 additions & 4 deletions docs/modules/localstack.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,6 @@ With simply passing the `testcontainers.CustomizeRequest` functional option to t

In the above example you can check how it's possible to set certain environment variables that are needed by the tests, the most important ones are the AWS services you want to use. Besides, the container runs in a separate Docker network with an alias.
#### WithNetwork
By default, the LocalStack container is started in the default Docker network. If you want to use a different Docker network, you can use the `WithNetwork(networkName string, alias string)` option, which receives the new network name and an alias as parameters, creating the new network, attaching the container to it, and setting the network alias for that network.
## Accessing hostname-sensitive services
Some Localstack APIs, such as SQS, require the container to be aware of the hostname that it is accessible on - for example, for construction of queue URLs in responses.
Expand Down
31 changes: 31 additions & 0 deletions generic.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"strings"
"sync"
"time"

Expand Down Expand Up @@ -101,6 +102,36 @@ func WithHostConfigModifier(modifier func(hostConfig *container.HostConfig)) Cus
}
}

// WithNetwork creates a network with the given name and attaches the container to it, setting the network alias
// on that network to the given alias.
// If the network already exists, checking if the network name already exists, it will be reused.
func WithNetwork(networkName string, alias string) CustomizeRequestOption {
return func(req *GenericContainerRequest) {
_, err := GenericNetwork(context.Background(), GenericNetworkRequest{
NetworkRequest: NetworkRequest{
Name: networkName,
CheckDuplicate: true, // force the Docker provider to reuse an existing network
},
})
if err != nil && !strings.Contains(err.Error(), "already exists") {
logger := req.Logger
if logger == nil {
logger = Logger
}
logger.Printf("Failed to create network '%s'. Container won't be attached to this network: %v", networkName, err)
return
}

// attaching to the network because it was created with success or it already existed.
req.Networks = append(req.Networks, networkName)

if req.NetworkAliases == nil {
req.NetworkAliases = make(map[string][]string)
}
req.NetworkAliases[networkName] = []string{alias}
}
}

// Executable represents an executable command to be sent to a container
// as part of the PostStart lifecycle hook.
type Executable interface {
Expand Down
24 changes: 2 additions & 22 deletions modules/localstack/localstack.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,29 +61,9 @@ func isVersion2(image string) bool {

// WithNetwork creates a network with the given name and attaches the container to it, setting the network alias
// on that network to the given alias.
// Deprecated: use testcontainers.WithNetwork instead
func WithNetwork(networkName string, alias string) testcontainers.CustomizeRequestOption {
return func(req *testcontainers.GenericContainerRequest) {
_, err := testcontainers.GenericNetwork(context.Background(), testcontainers.GenericNetworkRequest{
NetworkRequest: testcontainers.NetworkRequest{
Name: networkName,
},
})
if err != nil {
logger := req.Logger
if logger == nil {
logger = testcontainers.Logger
}
logger.Printf("Failed to create network '%s'. Container won't be attached to this network: %v", networkName, err)
return
}

req.Networks = append(req.Networks, networkName)

if req.NetworkAliases == nil {
req.NetworkAliases = make(map[string][]string)
}
req.NetworkAliases[networkName] = []string{alias}
}
return testcontainers.WithNetwork(networkName, alias)
}

// RunContainer creates an instance of the LocalStack container type, being possible to pass a custom request and options:
Expand Down

0 comments on commit 0ce34a8

Please sign in to comment.