diff --git a/docker_exec_test.go b/docker_exec_test.go index 7e1cd4bc2f..4716c493ab 100644 --- a/docker_exec_test.go +++ b/docker_exec_test.go @@ -1,44 +1,16 @@ package testcontainers import ( + "bytes" "context" "io" - "strings" "testing" + "github.com/docker/docker/pkg/stdcopy" "github.com/stretchr/testify/require" - tcexec "github.com/testcontainers/testcontainers-go/exec" ) -func TestExecWithMultiplexedResponse(t *testing.T) { - ctx := context.Background() - req := ContainerRequest{ - Image: nginxAlpineImage, - } - - container, err := GenericContainer(ctx, GenericContainerRequest{ - ProviderType: providerType, - ContainerRequest: req, - Started: true, - }) - - require.NoError(t, err) - terminateContainerOnEnd(t, ctx, container) - - code, reader, err := container.Exec(ctx, []string{"ls", "/usr/share/nginx"}, tcexec.Multiplexed()) - require.NoError(t, err) - require.Zero(t, code) - require.NotNil(t, reader) - - b, err := io.ReadAll(reader) - require.NoError(t, err) - require.NotNil(t, b) - - str := string(b) - require.Equal(t, "html\n", str) -} - func TestExecWithOptions(t *testing.T) { tests := []struct { name string @@ -79,7 +51,6 @@ func TestExecWithOptions(t *testing.T) { } container, err := GenericContainer(ctx, GenericContainerRequest{ - ProviderType: providerType, ContainerRequest: req, Started: true, }) @@ -106,14 +77,13 @@ func TestExecWithOptions(t *testing.T) { } } -func TestExecWithMultiplexedStderrResponse(t *testing.T) { +func TestExecWithMultiplexedResponse(t *testing.T) { ctx := context.Background() req := ContainerRequest{ Image: nginxAlpineImage, } container, err := GenericContainer(ctx, GenericContainerRequest{ - ProviderType: providerType, ContainerRequest: req, Started: true, }) @@ -121,9 +91,9 @@ func TestExecWithMultiplexedStderrResponse(t *testing.T) { require.NoError(t, err) terminateContainerOnEnd(t, ctx, container) - code, reader, err := container.Exec(ctx, []string{"ls", "/non-existing-directory"}, tcexec.Multiplexed()) + code, reader, err := container.Exec(ctx, []string{"sh", "-c", "echo stdout; echo stderr >&2"}, tcexec.Multiplexed()) require.NoError(t, err) - require.NotZero(t, code) + require.Zero(t, code) require.NotNil(t, reader) b, err := io.ReadAll(reader) @@ -131,7 +101,8 @@ func TestExecWithMultiplexedStderrResponse(t *testing.T) { require.NotNil(t, b) str := string(b) - require.Contains(t, str, "No such file or directory") + require.Contains(t, str, "stdout") + require.Contains(t, str, "stderr") } func TestExecWithNonMultiplexedResponse(t *testing.T) { @@ -141,7 +112,6 @@ func TestExecWithNonMultiplexedResponse(t *testing.T) { } container, err := GenericContainer(ctx, GenericContainerRequest{ - ProviderType: providerType, ContainerRequest: req, Started: true, }) @@ -149,15 +119,20 @@ func TestExecWithNonMultiplexedResponse(t *testing.T) { require.NoError(t, err) terminateContainerOnEnd(t, ctx, container) - code, reader, err := container.Exec(ctx, []string{"ls", "/usr/share/nginx"}) + code, reader, err := container.Exec(ctx, []string{"sh", "-c", "echo stdout; echo stderr >&2"}) require.NoError(t, err) require.Zero(t, code) require.NotNil(t, reader) - b, err := io.ReadAll(reader) + var stdout bytes.Buffer + var stderr bytes.Buffer + + written, err := stdcopy.StdCopy(&stdout, &stderr, reader) require.NoError(t, err) - require.NotNil(t, b) + require.NotZero(t, written) + require.NotNil(t, stdout) + require.NotNil(t, stderr) - str := string(b) - require.True(t, strings.HasSuffix(str, "html\n")) + require.Equal(t, stdout.String(), "stdout\n") + require.Equal(t, stderr.String(), "stderr\n") } diff --git a/exec/processor.go b/exec/processor.go index c4d40f1e73..c4f9e1b100 100644 --- a/exec/processor.go +++ b/exec/processor.go @@ -82,10 +82,6 @@ func Multiplexed() ProcessOption { <-done - if errBuff.Bytes() != nil { - opts.Reader = &errBuff - } else { - opts.Reader = &outBuff - } + opts.Reader = io.MultiReader(&outBuff, &errBuff) }) }