Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 27 additions & 30 deletions modules/toxiproxy/toxiproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,29 +54,21 @@ func (c *Container) URI(ctx context.Context) (string, error) {

// Run creates an instance of the Toxiproxy container type
func Run(ctx context.Context, img string, opts ...testcontainers.ContainerCustomizer) (*Container, error) {
req := testcontainers.ContainerRequest{
Image: img,
ExposedPorts: []string{ControlPort},
WaitingFor: wait.ForHTTP("/version").WithPort(ControlPort).WithStatusCodeMatcher(func(status int) bool {
return status == http.StatusOK
}),
}

genericContainerReq := testcontainers.GenericContainerRequest{
ContainerRequest: req,
Started: true,
}

// Process custom options first
settings := defaultOptions()
for _, opt := range opts {
if apply, ok := opt.(Option); ok {
if err := apply(&settings); err != nil {
return nil, fmt.Errorf("apply: %w", err)
return nil, fmt.Errorf("apply option: %w", err)
}
}
if err := opt.Customize(&genericContainerReq); err != nil {
return nil, fmt.Errorf("customize: %w", err)
}
}

moduleOpts := []testcontainers.ContainerCustomizer{
testcontainers.WithExposedPorts(ControlPort),
testcontainers.WithWaitStrategy(wait.ForHTTP("/version").WithPort(ControlPort).WithStatusCodeMatcher(func(status int) bool {
return status == http.StatusOK
})),
}

// Expose the ports for the proxies, starting from the first proxied port
Expand All @@ -87,39 +79,44 @@ func Run(ctx context.Context, img string, opts ...testcontainers.ContainerCustom
proxy.Listen = fmt.Sprintf("0.0.0.0:%d", proxiedPort)
portsInRange = append(portsInRange, fmt.Sprintf("%d/tcp", proxiedPort))
}
genericContainerReq.ExposedPorts = append(genericContainerReq.ExposedPorts, portsInRange...)

if len(portsInRange) > 0 {
moduleOpts = append(moduleOpts, testcontainers.WithExposedPorts(portsInRange...))
}

// Render the config file
jsonData, err := json.MarshalIndent(settings.proxies, "", " ")
if err != nil {
return nil, fmt.Errorf("marshal: %w", err)
return nil, fmt.Errorf("marshal config: %w", err)
}

// Apply the config file to the container with the proxies.
if len(settings.proxies) > 0 {
genericContainerReq.Files = append(genericContainerReq.Files, testcontainers.ContainerFile{
Reader: bytes.NewReader(jsonData),
ContainerFilePath: "/tmp/tc-toxiproxy.json",
FileMode: 0o644,
})
genericContainerReq.Cmd = append(genericContainerReq.Cmd, "-host=0.0.0.0", "-config=/tmp/tc-toxiproxy.json")
moduleOpts = append(moduleOpts,
testcontainers.WithFiles(testcontainers.ContainerFile{
Reader: bytes.NewReader(jsonData),
ContainerFilePath: "/tmp/tc-toxiproxy.json",
FileMode: 0o644,
}),
testcontainers.WithCmd("-host=0.0.0.0", "-config=/tmp/tc-toxiproxy.json"),
)
}

container, err := testcontainers.GenericContainer(ctx, genericContainerReq)
ctr, err := testcontainers.Run(ctx, img, append(moduleOpts, opts...)...)
var c *Container
if container != nil {
c = &Container{Container: container, proxiedEndpoints: make(map[int]string)}
if ctr != nil {
c = &Container{Container: ctr, proxiedEndpoints: make(map[int]string)}
}

if err != nil {
return c, fmt.Errorf("generic container: %w", err)
return c, fmt.Errorf("run toxiproxy: %w", err)
}

// Map the ports of the proxies to the container, so that we can use them in the tests
for _, proxy := range settings.proxies {
err := proxy.sanitize()
if err != nil {
return c, fmt.Errorf("sanitize: %w", err)
return c, fmt.Errorf("sanitize proxy: %w", err)
}

endpoint, err := c.PortEndpoint(ctx, nat.Port(fmt.Sprintf("%d/tcp", proxy.listenPort)), "")
Expand Down
Loading