Browse code

testing: add case for exec closeStdin

add regression case for the issue#37870

Signed-off-by: Wei Fu <fuweid89@gmail.com>

Wei Fu authored on 2018/10/11 20:03:02
Showing 1 changed files
... ...
@@ -4,6 +4,7 @@ import (
4 4
 	"context"
5 5
 	"io/ioutil"
6 6
 	"testing"
7
+	"time"
7 8
 
8 9
 	"github.com/docker/docker/api/types"
9 10
 	"github.com/docker/docker/api/types/strslice"
... ...
@@ -15,6 +16,74 @@ import (
15 15
 	"gotest.tools/skip"
16 16
 )
17 17
 
18
+// TestExecWithCloseStdin adds case for moby#37870 issue.
19
+func TestExecWithCloseStdin(t *testing.T) {
20
+	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.39"), "broken in earlier versions")
21
+	defer setupTest(t)()
22
+
23
+	ctx := context.Background()
24
+	client := request.NewAPIClient(t)
25
+
26
+	// run top with detached mode
27
+	cID := container.Run(t, ctx, client)
28
+
29
+	expected := "closeIO"
30
+	execResp, err := client.ContainerExecCreate(ctx, cID,
31
+		types.ExecConfig{
32
+			AttachStdin:  true,
33
+			AttachStdout: true,
34
+			Cmd:          strslice.StrSlice([]string{"sh", "-c", "cat && echo " + expected}),
35
+		},
36
+	)
37
+	assert.NilError(t, err)
38
+
39
+	resp, err := client.ContainerExecAttach(ctx, execResp.ID,
40
+		types.ExecStartCheck{
41
+			Detach: false,
42
+			Tty:    false,
43
+		},
44
+	)
45
+	assert.NilError(t, err)
46
+	defer resp.Close()
47
+
48
+	// close stdin to send EOF to cat
49
+	assert.NilError(t, resp.CloseWrite())
50
+
51
+	var (
52
+		waitCh = make(chan struct{})
53
+		resCh  = make(chan struct {
54
+			content string
55
+			err     error
56
+		})
57
+	)
58
+
59
+	go func() {
60
+		close(waitCh)
61
+		defer close(resCh)
62
+		r, err := ioutil.ReadAll(resp.Reader)
63
+
64
+		resCh <- struct {
65
+			content string
66
+			err     error
67
+		}{
68
+			content: string(r),
69
+			err:     err,
70
+		}
71
+	}()
72
+
73
+	<-waitCh
74
+	select {
75
+	case <-time.After(3 * time.Second):
76
+		t.Fatal("failed to read the content in time")
77
+	case got := <-resCh:
78
+		assert.NilError(t, got.err)
79
+
80
+		// NOTE: using Contains because no-tty's stream contains UX information
81
+		// like size, stream type.
82
+		assert.Assert(t, is.Contains(got.content, expected))
83
+	}
84
+}
85
+
18 86
 func TestExec(t *testing.T) {
19 87
 	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.35"), "broken in earlier versions")
20 88
 	skip.If(t, testEnv.OSType == "windows", "FIXME. Probably needs to wait for container to be in running state.")