Docker-DCO-1.1-Signed-off-by: Erik Hollensbe <github@hollensbe.org> (github: erikh)
Erik Hollensbe authored on 2014/07/29 14:50:16... | ... |
@@ -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 |
+} |