Browse code

Fix multiple attach test.

Docker-DCO-1.1-Signed-off-by: Erik Hollensbe <github@hollensbe.org> (github: erikh)

Erik Hollensbe authored on 2014/07/29 14:50:16
Showing 2 changed files
... ...
@@ -1,6 +1,7 @@
1 1
 package main
2 2
 
3 3
 import (
4
+	"io"
4 5
 	"os/exec"
5 6
 	"strings"
6 7
 	"sync"
... ...
@@ -8,46 +9,81 @@ import (
8 8
 	"time"
9 9
 )
10 10
 
11
+const attachWait = 5 * time.Second
12
+
11 13
 func TestMultipleAttachRestart(t *testing.T) {
12
-	cmd := exec.Command(dockerBinary, "run", "--name", "attacher", "-d", "busybox",
13
-		"/bin/sh", "-c", "sleep 2 && echo hello")
14
-
15
-	group := sync.WaitGroup{}
16
-	group.Add(4)
17
-
18
-	defer func() {
19
-		cmd = exec.Command(dockerBinary, "kill", "attacher")
20
-		if _, err := runCommand(cmd); err != nil {
21
-			t.Fatal(err)
22
-		}
23
-		deleteAllContainers()
14
+	defer deleteAllContainers()
15
+
16
+	endGroup := &sync.WaitGroup{}
17
+	startGroup := &sync.WaitGroup{}
18
+	endGroup.Add(3)
19
+	startGroup.Add(3)
20
+
21
+	if err := waitForContainer("attacher", "-d", "busybox", "/bin/sh", "-c", "while true; do sleep 1; echo hello; done"); err != nil {
22
+		t.Fatal(err)
23
+	}
24
+
25
+	startDone := make(chan struct{})
26
+	endDone := make(chan struct{})
27
+
28
+	go func() {
29
+		endGroup.Wait()
30
+		close(endDone)
24 31
 	}()
25 32
 
26 33
 	go func() {
27
-		defer group.Done()
28
-		out, _, err := runCommandWithOutput(cmd)
29
-		if err != nil {
30
-			t.Fatal(err, out)
31
-		}
34
+		startGroup.Wait()
35
+		close(startDone)
32 36
 	}()
33
-	time.Sleep(500 * time.Millisecond)
34 37
 
35 38
 	for i := 0; i < 3; i++ {
36 39
 		go func() {
37
-			defer group.Done()
38 40
 			c := exec.Command(dockerBinary, "attach", "attacher")
39 41
 
40
-			out, _, err := runCommandWithOutput(c)
42
+			defer func() {
43
+				c.Wait()
44
+				endGroup.Done()
45
+			}()
46
+
47
+			out, err := c.StdoutPipe()
41 48
 			if err != nil {
42
-				t.Fatal(err, out)
49
+				t.Fatal(err)
50
+			}
51
+
52
+			if _, err := startCommand(c); err != nil {
53
+				t.Fatal(err)
43 54
 			}
44
-			if actual := strings.Trim(out, "\r\n"); actual != "hello" {
45
-				t.Fatalf("unexpected output %s expected hello", actual)
55
+
56
+			buf := make([]byte, 1024)
57
+
58
+			if _, err := out.Read(buf); err != nil && err != io.EOF {
59
+				t.Fatal(err)
60
+			}
61
+
62
+			startGroup.Done()
63
+
64
+			if !strings.Contains(string(buf), "hello") {
65
+				t.Fatalf("unexpected output %s expected hello\n", string(buf))
46 66
 			}
47 67
 		}()
48 68
 	}
49 69
 
50
-	group.Wait()
70
+	select {
71
+	case <-startDone:
72
+	case <-time.After(attachWait):
73
+		t.Fatalf("Attaches did not initialize properly")
74
+	}
75
+
76
+	cmd := exec.Command(dockerBinary, "kill", "attacher")
77
+	if _, err := runCommand(cmd); err != nil {
78
+		t.Fatal(err)
79
+	}
80
+
81
+	select {
82
+	case <-endDone:
83
+	case <-time.After(attachWait):
84
+		t.Fatalf("Attaches did not finish properly")
85
+	}
51 86
 
52 87
 	logDone("attach - multiple attach")
53 88
 }
... ...
@@ -10,6 +10,7 @@ import (
10 10
 	"strings"
11 11
 	"syscall"
12 12
 	"testing"
13
+	"time"
13 14
 )
14 15
 
15 16
 func getExitCode(err error) (int, error) {
... ...
@@ -134,3 +135,43 @@ func convertSliceOfStringsToMap(input []string) map[string]struct{} {
134 134
 	}
135 135
 	return output
136 136
 }
137
+
138
+func waitForContainer(contId string, args ...string) error {
139
+	args = append([]string{"run", "--name", contId}, args...)
140
+	cmd := exec.Command(dockerBinary, args...)
141
+	if _, err := runCommand(cmd); err != nil {
142
+		return err
143
+	}
144
+
145
+	if err := waitRun(contId); err != nil {
146
+		return err
147
+	}
148
+
149
+	return nil
150
+}
151
+
152
+func waitRun(contId string) error {
153
+	after := time.After(5 * time.Second)
154
+
155
+	for {
156
+		cmd := exec.Command(dockerBinary, "inspect", "-f", "{{.State.Running}}", contId)
157
+		out, _, err := runCommandWithOutput(cmd)
158
+		if err != nil {
159
+			return fmt.Errorf("error executing docker inspect: %v", err)
160
+		}
161
+
162
+		if strings.Contains(out, "true") {
163
+			break
164
+		}
165
+
166
+		select {
167
+		case <-after:
168
+			return fmt.Errorf("container did not come up in time")
169
+		default:
170
+		}
171
+
172
+		time.Sleep(100 * time.Millisecond)
173
+	}
174
+
175
+	return nil
176
+}