github.com/tsuna/docker@v1.7.0-rc3/integration-cli/docker_cli_attach_test.go (about) 1 package main 2 3 import ( 4 "bufio" 5 "fmt" 6 "io" 7 "os/exec" 8 "strings" 9 "sync" 10 "time" 11 12 "github.com/go-check/check" 13 ) 14 15 const attachWait = 5 * time.Second 16 17 func (s *DockerSuite) TestAttachMultipleAndRestart(c *check.C) { 18 19 endGroup := &sync.WaitGroup{} 20 startGroup := &sync.WaitGroup{} 21 endGroup.Add(3) 22 startGroup.Add(3) 23 24 if err := waitForContainer("attacher", "-d", "busybox", "/bin/sh", "-c", "while true; do sleep 1; echo hello; done"); err != nil { 25 c.Fatal(err) 26 } 27 28 startDone := make(chan struct{}) 29 endDone := make(chan struct{}) 30 31 go func() { 32 endGroup.Wait() 33 close(endDone) 34 }() 35 36 go func() { 37 startGroup.Wait() 38 close(startDone) 39 }() 40 41 for i := 0; i < 3; i++ { 42 go func() { 43 cmd := exec.Command(dockerBinary, "attach", "attacher") 44 45 defer func() { 46 cmd.Wait() 47 endGroup.Done() 48 }() 49 50 out, err := cmd.StdoutPipe() 51 if err != nil { 52 c.Fatal(err) 53 } 54 55 if err := cmd.Start(); err != nil { 56 c.Fatal(err) 57 } 58 59 buf := make([]byte, 1024) 60 61 if _, err := out.Read(buf); err != nil && err != io.EOF { 62 c.Fatal(err) 63 } 64 65 startGroup.Done() 66 67 if !strings.Contains(string(buf), "hello") { 68 c.Fatalf("unexpected output %s expected hello\n", string(buf)) 69 } 70 }() 71 } 72 73 select { 74 case <-startDone: 75 case <-time.After(attachWait): 76 c.Fatalf("Attaches did not initialize properly") 77 } 78 79 cmd := exec.Command(dockerBinary, "kill", "attacher") 80 if _, err := runCommand(cmd); err != nil { 81 c.Fatal(err) 82 } 83 84 select { 85 case <-endDone: 86 case <-time.After(attachWait): 87 c.Fatalf("Attaches did not finish properly") 88 } 89 90 } 91 92 func (s *DockerSuite) TestAttachTtyWithoutStdin(c *check.C) { 93 cmd := exec.Command(dockerBinary, "run", "-d", "-ti", "busybox") 94 out, _, err := runCommandWithOutput(cmd) 95 if err != nil { 96 c.Fatalf("failed to start container: %v (%v)", out, err) 97 } 98 99 id := strings.TrimSpace(out) 100 if err := waitRun(id); err != nil { 101 c.Fatal(err) 102 } 103 104 defer func() { 105 cmd := exec.Command(dockerBinary, "kill", id) 106 if out, _, err := runCommandWithOutput(cmd); err != nil { 107 c.Fatalf("failed to kill container: %v (%v)", out, err) 108 } 109 }() 110 111 done := make(chan error) 112 go func() { 113 defer close(done) 114 115 cmd := exec.Command(dockerBinary, "attach", id) 116 if _, err := cmd.StdinPipe(); err != nil { 117 done <- err 118 return 119 } 120 121 expected := "cannot enable tty mode" 122 if out, _, err := runCommandWithOutput(cmd); err == nil { 123 done <- fmt.Errorf("attach should have failed") 124 return 125 } else if !strings.Contains(out, expected) { 126 done <- fmt.Errorf("attach failed with error %q: expected %q", out, expected) 127 return 128 } 129 }() 130 131 select { 132 case err := <-done: 133 c.Assert(err, check.IsNil) 134 case <-time.After(attachWait): 135 c.Fatal("attach is running but should have failed") 136 } 137 } 138 139 func (s *DockerSuite) TestAttachDisconnect(c *check.C) { 140 out, _ := dockerCmd(c, "run", "-di", "busybox", "/bin/cat") 141 id := strings.TrimSpace(out) 142 143 cmd := exec.Command(dockerBinary, "attach", id) 144 stdin, err := cmd.StdinPipe() 145 if err != nil { 146 c.Fatal(err) 147 } 148 defer stdin.Close() 149 stdout, err := cmd.StdoutPipe() 150 if err != nil { 151 c.Fatal(err) 152 } 153 defer stdout.Close() 154 if err := cmd.Start(); err != nil { 155 c.Fatal(err) 156 } 157 defer cmd.Process.Kill() 158 159 if _, err := stdin.Write([]byte("hello\n")); err != nil { 160 c.Fatal(err) 161 } 162 out, err = bufio.NewReader(stdout).ReadString('\n') 163 if err != nil { 164 c.Fatal(err) 165 } 166 if strings.TrimSpace(out) != "hello" { 167 c.Fatalf("expected 'hello', got %q", out) 168 } 169 170 if err := stdin.Close(); err != nil { 171 c.Fatal(err) 172 } 173 174 // Expect container to still be running after stdin is closed 175 running, err := inspectField(id, "State.Running") 176 if err != nil { 177 c.Fatal(err) 178 } 179 if running != "true" { 180 c.Fatal("expected container to still be running") 181 } 182 183 }