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