From 8e25f4ff6d89888a1bcd578f3f8f7aab89dce24d Mon Sep 17 00:00:00 2001 From: Wei Fu Date: Thu, 11 Oct 2018 19:03:02 +0800 Subject: [PATCH] testing: add case for exec closeStdin add regression case for the issue#37870 Signed-off-by: Wei Fu --- integration/container/exec_test.go | 69 ++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/integration/container/exec_test.go b/integration/container/exec_test.go index 8d23f6b1cc..20b1f3e8b5 100644 --- a/integration/container/exec_test.go +++ b/integration/container/exec_test.go @@ -4,6 +4,7 @@ import ( "context" "io/ioutil" "testing" + "time" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/strslice" @@ -15,6 +16,74 @@ import ( "gotest.tools/skip" ) +// TestExecWithCloseStdin adds case for moby#37870 issue. +func TestExecWithCloseStdin(t *testing.T) { + skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.39"), "broken in earlier versions") + defer setupTest(t)() + + ctx := context.Background() + client := request.NewAPIClient(t) + + // run top with detached mode + cID := container.Run(t, ctx, client) + + expected := "closeIO" + execResp, err := client.ContainerExecCreate(ctx, cID, + types.ExecConfig{ + AttachStdin: true, + AttachStdout: true, + Cmd: strslice.StrSlice([]string{"sh", "-c", "cat && echo " + expected}), + }, + ) + assert.NilError(t, err) + + resp, err := client.ContainerExecAttach(ctx, execResp.ID, + types.ExecStartCheck{ + Detach: false, + Tty: false, + }, + ) + assert.NilError(t, err) + defer resp.Close() + + // close stdin to send EOF to cat + assert.NilError(t, resp.CloseWrite()) + + var ( + waitCh = make(chan struct{}) + resCh = make(chan struct { + content string + err error + }) + ) + + go func() { + close(waitCh) + defer close(resCh) + r, err := ioutil.ReadAll(resp.Reader) + + resCh <- struct { + content string + err error + }{ + content: string(r), + err: err, + } + }() + + <-waitCh + select { + case <-time.After(3 * time.Second): + t.Fatal("failed to read the content in time") + case got := <-resCh: + assert.NilError(t, got.err) + + // NOTE: using Contains because no-tty's stream contains UX information + // like size, stream type. + assert.Assert(t, is.Contains(got.content, expected)) + } +} + func TestExec(t *testing.T) { skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.35"), "broken in earlier versions") skip.If(t, testEnv.OSType == "windows", "FIXME. Probably needs to wait for container to be in running state.")