github.com/duglin/docker@v1.13.1/integration-cli/docker_cli_attach_test.go (about) 1 package main 2 3 import ( 4 "bufio" 5 "fmt" 6 "io" 7 "os/exec" 8 "runtime" 9 "strings" 10 "sync" 11 "time" 12 13 icmd "github.com/docker/docker/pkg/integration/cmd" 14 "github.com/go-check/check" 15 ) 16 17 const attachWait = 5 * time.Second 18 19 func (s *DockerSuite) TestAttachMultipleAndRestart(c *check.C) { 20 endGroup := &sync.WaitGroup{} 21 startGroup := &sync.WaitGroup{} 22 endGroup.Add(3) 23 startGroup.Add(3) 24 25 err := waitForContainer("attacher", "-d", "busybox", "/bin/sh", "-c", "while true; do sleep 1; echo hello; done") 26 c.Assert(err, check.IsNil) 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 defer out.Close() 55 56 if err := cmd.Start(); err != nil { 57 c.Fatal(err) 58 } 59 60 buf := make([]byte, 1024) 61 62 if _, err := out.Read(buf); err != nil && err != io.EOF { 63 c.Fatal(err) 64 } 65 66 startGroup.Done() 67 68 if !strings.Contains(string(buf), "hello") { 69 c.Fatalf("unexpected output %s expected hello\n", string(buf)) 70 } 71 }() 72 } 73 74 select { 75 case <-startDone: 76 case <-time.After(attachWait): 77 c.Fatalf("Attaches did not initialize properly") 78 } 79 80 dockerCmd(c, "kill", "attacher") 81 82 select { 83 case <-endDone: 84 case <-time.After(attachWait): 85 c.Fatalf("Attaches did not finish properly") 86 } 87 } 88 89 func (s *DockerSuite) TestAttachTTYWithoutStdin(c *check.C) { 90 out, _ := dockerCmd(c, "run", "-d", "-ti", "busybox") 91 92 id := strings.TrimSpace(out) 93 c.Assert(waitRun(id), check.IsNil) 94 95 done := make(chan error) 96 go func() { 97 defer close(done) 98 99 cmd := exec.Command(dockerBinary, "attach", id) 100 if _, err := cmd.StdinPipe(); err != nil { 101 done <- err 102 return 103 } 104 105 expected := "the input device is not a TTY" 106 if runtime.GOOS == "windows" { 107 expected += ". If you are using mintty, try prefixing the command with 'winpty'" 108 } 109 if out, _, err := runCommandWithOutput(cmd); err == nil { 110 done <- fmt.Errorf("attach should have failed") 111 return 112 } else if !strings.Contains(out, expected) { 113 done <- fmt.Errorf("attach failed with error %q: expected %q", out, expected) 114 return 115 } 116 }() 117 118 select { 119 case err := <-done: 120 c.Assert(err, check.IsNil) 121 case <-time.After(attachWait): 122 c.Fatal("attach is running but should have failed") 123 } 124 } 125 126 func (s *DockerSuite) TestAttachDisconnect(c *check.C) { 127 testRequires(c, DaemonIsLinux) 128 out, _ := dockerCmd(c, "run", "-di", "busybox", "/bin/cat") 129 id := strings.TrimSpace(out) 130 131 cmd := exec.Command(dockerBinary, "attach", id) 132 stdin, err := cmd.StdinPipe() 133 if err != nil { 134 c.Fatal(err) 135 } 136 defer stdin.Close() 137 stdout, err := cmd.StdoutPipe() 138 c.Assert(err, check.IsNil) 139 defer stdout.Close() 140 c.Assert(cmd.Start(), check.IsNil) 141 defer cmd.Process.Kill() 142 143 _, err = stdin.Write([]byte("hello\n")) 144 c.Assert(err, check.IsNil) 145 out, err = bufio.NewReader(stdout).ReadString('\n') 146 c.Assert(err, check.IsNil) 147 c.Assert(strings.TrimSpace(out), check.Equals, "hello") 148 149 c.Assert(stdin.Close(), check.IsNil) 150 151 // Expect container to still be running after stdin is closed 152 running := inspectField(c, id, "State.Running") 153 c.Assert(running, check.Equals, "true") 154 } 155 156 func (s *DockerSuite) TestAttachPausedContainer(c *check.C) { 157 testRequires(c, IsPausable) 158 defer unpauseAllContainers() 159 runSleepingContainer(c, "-d", "--name=test") 160 dockerCmd(c, "pause", "test") 161 162 result := dockerCmdWithResult("attach", "test") 163 c.Assert(result, icmd.Matches, icmd.Expected{ 164 Error: "exit status 1", 165 ExitCode: 1, 166 Err: "You cannot attach to a paused container, unpause it first", 167 }) 168 }