소스 검색

Fix multiple attach test.

Docker-DCO-1.1-Signed-off-by: Erik Hollensbe <github@hollensbe.org> (github: erikh)
Erik Hollensbe 11 년 전
부모
커밋
01094c1568
2개의 변경된 파일101개의 추가작업 그리고 24개의 파일을 삭제
  1. 60 24
      integration-cli/docker_cli_attach_test.go
  2. 41 0
      integration-cli/utils.go

+ 60 - 24
integration-cli/docker_cli_attach_test.go

@@ -1,6 +1,7 @@
 package main
 
 import (
+	"io"
 	"os/exec"
 	"strings"
 	"sync"
@@ -8,46 +9,81 @@ import (
 	"time"
 )
 
+const attachWait = 5 * time.Second
+
 func TestMultipleAttachRestart(t *testing.T) {
-	cmd := exec.Command(dockerBinary, "run", "--name", "attacher", "-d", "busybox",
-		"/bin/sh", "-c", "sleep 2 && echo hello")
-
-	group := sync.WaitGroup{}
-	group.Add(4)
-
-	defer func() {
-		cmd = exec.Command(dockerBinary, "kill", "attacher")
-		if _, err := runCommand(cmd); err != nil {
-			t.Fatal(err)
-		}
-		deleteAllContainers()
+	defer deleteAllContainers()
+
+	endGroup := &sync.WaitGroup{}
+	startGroup := &sync.WaitGroup{}
+	endGroup.Add(3)
+	startGroup.Add(3)
+
+	if err := waitForContainer("attacher", "-d", "busybox", "/bin/sh", "-c", "while true; do sleep 1; echo hello; done"); err != nil {
+		t.Fatal(err)
+	}
+
+	startDone := make(chan struct{})
+	endDone := make(chan struct{})
+
+	go func() {
+		endGroup.Wait()
+		close(endDone)
 	}()
 
 	go func() {
-		defer group.Done()
-		out, _, err := runCommandWithOutput(cmd)
-		if err != nil {
-			t.Fatal(err, out)
-		}
+		startGroup.Wait()
+		close(startDone)
 	}()
-	time.Sleep(500 * time.Millisecond)
 
 	for i := 0; i < 3; i++ {
 		go func() {
-			defer group.Done()
 			c := exec.Command(dockerBinary, "attach", "attacher")
 
-			out, _, err := runCommandWithOutput(c)
+			defer func() {
+				c.Wait()
+				endGroup.Done()
+			}()
+
+			out, err := c.StdoutPipe()
 			if err != nil {
-				t.Fatal(err, out)
+				t.Fatal(err)
+			}
+
+			if _, err := startCommand(c); err != nil {
+				t.Fatal(err)
 			}
-			if actual := strings.Trim(out, "\r\n"); actual != "hello" {
-				t.Fatalf("unexpected output %s expected hello", actual)
+
+			buf := make([]byte, 1024)
+
+			if _, err := out.Read(buf); err != nil && err != io.EOF {
+				t.Fatal(err)
+			}
+
+			startGroup.Done()
+
+			if !strings.Contains(string(buf), "hello") {
+				t.Fatalf("unexpected output %s expected hello\n", string(buf))
 			}
 		}()
 	}
 
-	group.Wait()
+	select {
+	case <-startDone:
+	case <-time.After(attachWait):
+		t.Fatalf("Attaches did not initialize properly")
+	}
+
+	cmd := exec.Command(dockerBinary, "kill", "attacher")
+	if _, err := runCommand(cmd); err != nil {
+		t.Fatal(err)
+	}
+
+	select {
+	case <-endDone:
+	case <-time.After(attachWait):
+		t.Fatalf("Attaches did not finish properly")
+	}
 
 	logDone("attach - multiple attach")
 }

+ 41 - 0
integration-cli/utils.go

@@ -10,6 +10,7 @@ import (
 	"strings"
 	"syscall"
 	"testing"
+	"time"
 )
 
 func getExitCode(err error) (int, error) {
@@ -134,3 +135,43 @@ func convertSliceOfStringsToMap(input []string) map[string]struct{} {
 	}
 	return output
 }
+
+func waitForContainer(contId string, args ...string) error {
+	args = append([]string{"run", "--name", contId}, args...)
+	cmd := exec.Command(dockerBinary, args...)
+	if _, err := runCommand(cmd); err != nil {
+		return err
+	}
+
+	if err := waitRun(contId); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func waitRun(contId string) error {
+	after := time.After(5 * time.Second)
+
+	for {
+		cmd := exec.Command(dockerBinary, "inspect", "-f", "{{.State.Running}}", contId)
+		out, _, err := runCommandWithOutput(cmd)
+		if err != nil {
+			return fmt.Errorf("error executing docker inspect: %v", err)
+		}
+
+		if strings.Contains(out, "true") {
+			break
+		}
+
+		select {
+		case <-after:
+			return fmt.Errorf("container did not come up in time")
+		default:
+		}
+
+		time.Sleep(100 * time.Millisecond)
+	}
+
+	return nil
+}