Skip to content

Commit

Permalink
break: update Executable interface to accept ProcessOptions
Browse files Browse the repository at this point in the history
  • Loading branch information
mdelapenya committed Nov 15, 2023
1 parent 2c43b29 commit 767d698
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 19 deletions.
5 changes: 4 additions & 1 deletion docs/features/common_functional_options.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ Testcontainers exposes the `WithStartupCommand(e ...Executable)` option to run a
!!!info
To better understand how this feature works, please read the [Create containers: Lifecycle Hooks](/features/creating_container/#lifecycle-hooks) documentation.

It also exports an `Executable` interface, defining one single method: `AsCommand()`, which returns a slice of strings to represent the command and positional arguments to be executed in the container.
It also exports an `Executable` interface, defining the following methods:

- `AsCommand()`, which returns a slice of strings to represent the command and positional arguments to be executed in the container;
- `Options()` to set the command options, such as the working directory, environment variables, user executing the command, etc. It returns a slice of functional options to configure the command.

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.

Expand Down
3 changes: 3 additions & 0 deletions modules/cassandra/executable.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ package cassandra

import (
"strings"

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

type initScript struct {
testcontainers.ExecOptions
File string
}

Expand Down
5 changes: 4 additions & 1 deletion modules/rabbitmq/examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,10 @@ func ExampleRunContainer_withPlugins() {
testcontainers.WithImage("rabbitmq:3.7.25-management-alpine"),
// Multiple test implementations of the Executable interface, specific to RabbitMQ, exist in the types_test.go file.
// Please refer to them for more examples.
testcontainers.WithStartupCommand(testcontainers.RawCommand{"rabbitmq_shovel"}, testcontainers.RawCommand{"rabbitmq_random_exchange"}),
testcontainers.WithStartupCommand(
testcontainers.NewRawCommand([]string{"rabbitmq_shovel"}),
testcontainers.NewRawCommand([]string{"rabbitmq_random_exchange"}),
),
)
if err != nil {
panic(err)
Expand Down
2 changes: 1 addition & 1 deletion modules/rabbitmq/rabbitmq_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ func TestRunContainer_withAllSettings(t *testing.T) {
}),
// }
// enablePlugins {
testcontainers.WithStartupCommand(Plugin("rabbitmq_shovel"), Plugin("rabbitmq_random_exchange")),
testcontainers.WithStartupCommand(Plugin{Name: "rabbitmq_shovel"}, Plugin{Name: "rabbitmq_random_exchange"}),
// }
)
if err != nil {
Expand Down
19 changes: 17 additions & 2 deletions modules/rabbitmq/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"encoding/json"
"fmt"
"strings"

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

// The following structs are added as a demonstration for the RabbitMQ management API therefore,
Expand All @@ -15,6 +17,7 @@ import (
// --------- Bindings ---------

type Binding struct {
testcontainers.ConfigurableExec
VHost string
Source string
Destination string
Expand Down Expand Up @@ -72,6 +75,7 @@ func (b Binding) AsCommand() []string {
// --------- Exchange ---------

type Exchange struct {
testcontainers.ConfigurableExec
Name string
VHost string
Type string
Expand Down Expand Up @@ -117,6 +121,7 @@ func (e Exchange) AsCommand() []string {
// --------- OperatorPolicy ---------

type OperatorPolicy struct {
testcontainers.ConfigurableExec
Name string
Pattern string
Definition map[string]interface{}
Expand Down Expand Up @@ -151,6 +156,7 @@ func (op OperatorPolicy) AsCommand() []string {
// --------- Parameter ---------

type Parameter struct {
testcontainers.ConfigurableExec
Component string
Name string
Value string
Expand All @@ -176,6 +182,7 @@ func (p Parameter) AsCommand() []string {
// --------- Permission ---------

type Permission struct {
testcontainers.ConfigurableExec
VHost string
User string
Configure string
Expand Down Expand Up @@ -205,17 +212,21 @@ func (p Permission) AsCommand() []string {

// --------- Plugin ---------

type Plugin string
type Plugin struct {
testcontainers.ConfigurableExec
Name string
}

func (p Plugin) AsCommand() []string {
return []string{"rabbitmq-plugins", "enable", string(p)}
return []string{"rabbitmq-plugins", "enable", p.Name}
}

// --------- Plugin ---------

// --------- Policy ---------

type Policy struct {
testcontainers.ConfigurableExec
VHost string
Name string
Pattern string
Expand Down Expand Up @@ -257,6 +268,7 @@ func (p Policy) AsCommand() []string {
// --------- Queue ---------

type Queue struct {
testcontainers.ConfigurableExec
Name string
VHost string
AutoDelete bool
Expand Down Expand Up @@ -297,6 +309,7 @@ func (q Queue) AsCommand() []string {
// --------- User ---------

type User struct {
testcontainers.ConfigurableExec
Name string
Password string
Tags []string
Expand Down Expand Up @@ -325,6 +338,7 @@ func (u User) AsCommand() []string {
// --------- Virtual Hosts --------

type VirtualHost struct {
testcontainers.ConfigurableExec
Name string
Tracing bool
}
Expand All @@ -340,6 +354,7 @@ func (v VirtualHost) AsCommand() []string {
}

type VirtualHostLimit struct {
testcontainers.ConfigurableExec
VHost string
Name string
Value int
Expand Down
30 changes: 27 additions & 3 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"

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

Expand Down Expand Up @@ -118,14 +119,37 @@ func WithNetwork(networkName string, alias string) CustomizeRequestOption {
// as part of the PostStart lifecycle hook.
type Executable interface {
AsCommand() []string
Options() []tcexec.ProcessOption
}

// ExecOptions is a struct that provides a default implementation for the Options method
// of the Executable interface.
type ExecOptions struct {
opts []tcexec.ProcessOption
}

func (ce ExecOptions) Options() []tcexec.ProcessOption {
return ce.opts
}

// RawCommand is a type that implements Executable and represents a command to be sent to a container
type RawCommand []string
type RawCommand struct {
ExecOptions
cmds []string
}

func NewRawCommand(cmds []string) RawCommand {
return RawCommand{
cmds: cmds,
ExecOptions: ExecOptions{
opts: []tcexec.ProcessOption{},
},
}
}

// AsCommand returns the command as a slice of strings
func (r RawCommand) AsCommand() []string {
return r
return r.cmds
}

// WithStartupCommand will execute the command representation of each Executable into the container.
Expand All @@ -139,7 +163,7 @@ func WithStartupCommand(execs ...Executable) CustomizeRequestOption {

for _, exec := range execs {
execFn := func(ctx context.Context, c Container) error {
_, _, err := c.Exec(ctx, exec.AsCommand())
_, _, err := c.Exec(ctx, exec.AsCommand(), exec.Options()...)
return err
}

Expand Down
12 changes: 1 addition & 11 deletions options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,14 +120,6 @@ func TestWithNetworkMultipleCallsWithSameNameReuseTheNetwork(t *testing.T) {
assert.Equal(t, "new-network", resources[0].Name)
}

type testExecutable struct {
cmds []string
}

func (t testExecutable) AsCommand() []string {
return t.cmds
}

func TestWithStartupCommand(t *testing.T) {
req := testcontainers.GenericContainerRequest{
ContainerRequest: testcontainers.ContainerRequest{
Expand All @@ -137,9 +129,7 @@ func TestWithStartupCommand(t *testing.T) {
Started: true,
}

testExec := testExecutable{
cmds: []string{"touch", "/tmp/.testcontainers"},
}
testExec := testcontainers.NewRawCommand([]string{"touch", "/tmp/.testcontainers"})

testcontainers.WithStartupCommand(testExec)(&req)

Expand Down

0 comments on commit 767d698

Please sign in to comment.