Skip to content

Commit

Permalink
fix: allow resource.Exec to correctly wait for process completion (#383)
Browse files Browse the repository at this point in the history
This bug was due to a bug in the vendored client library where
StartExec would return early even if opts.Detatch was true, if stderr
and stdout were not provided. This fix always attaches them and falls
back to io.Discard if the user does not provide their own readers.

See: fsouza/go-dockerclient#838
Fixes #372
  • Loading branch information
flowchartsman authored Oct 18, 2022
1 parent fd10436 commit 49a59c3
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 7 deletions.
14 changes: 12 additions & 2 deletions dockertest.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,15 +117,25 @@ func (r *Resource) Exec(cmd []string, opts ExecOptions) (exitCode int, err error
Container: r.Container.ID,
Cmd: cmd,
Env: opts.Env,
AttachStderr: opts.StdErr != nil,
AttachStdout: opts.StdOut != nil,
AttachStderr: true,
AttachStdout: true,
AttachStdin: opts.StdIn != nil,
Tty: opts.TTY,
})
if err != nil {
return -1, errors.Wrap(err, "Create exec failed")
}

// Always attach stderr/stdout, even if not specified, to ensure that exec
// waits with opts.Detach as false (default)
// ref: https://github.com/fsouza/go-dockerclient/issues/838
if opts.StdErr == nil {
opts.StdErr = io.Discard
}
if opts.StdOut == nil {
opts.StdOut = io.Discard
}

err = r.pool.Client.StartExec(exec.ID, dc.StartExecOptions{
InputStream: opts.StdIn,
OutputStream: opts.StdOut,
Expand Down
27 changes: 22 additions & 5 deletions dockertest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ import (
"github.com/stretchr/testify/require"
)

var docker = os.Getenv("DOCKER_URL")
var pool *Pool
var (
docker = os.Getenv("DOCKER_URL")
pool *Pool
)

func TestMain(m *testing.M) {
var err error
Expand Down Expand Up @@ -65,7 +67,6 @@ func TestMongo(t *testing.T) {

err = pool.Retry(func() error {
response, err := http.Get(fmt.Sprintf("http://127.0.0.1:%s", port))

if err != nil {
return err
}
Expand Down Expand Up @@ -197,7 +198,7 @@ func TestBuildImage(t *testing.T) {
dockerfilePath := dir + "/Dockerfile"
ioutil.WriteFile(dockerfilePath,
[]byte("FROM postgres:9.5"),
0644,
0o644,
)

resource, err := pool.BuildAndRun("postgres-test", dockerfilePath, nil)
Expand All @@ -219,7 +220,7 @@ ARG foo
RUN echo -n $foo > /build-time-value
CMD sleep 10
`)),
0644,
0o644,
)

resource, err := pool.BuildAndRunWithBuildOptions(
Expand Down Expand Up @@ -467,3 +468,19 @@ func TestClientRaceCondition(t *testing.T) {
})
}
}

func TestExecStatus(t *testing.T) {
resource, err := pool.RunWithOptions(&RunOptions{
Repository: "alpine",
Tag: "3.16",
Cmd: []string{"tail", "-f", "/dev/null"},
})
defer resource.Close()
require.Nil(t, err)
exitCode, err := resource.Exec([]string{"/bin/false"}, ExecOptions{})
require.Nil(t, err)
require.Equal(t, 1, exitCode)
exitCode, err = resource.Exec([]string{"/bin/sh", "-c", "/bin/sleep 2 && exit 42"}, ExecOptions{})
require.Nil(t, err)
require.Equal(t, 42, exitCode)
}

0 comments on commit 49a59c3

Please sign in to comment.