github.com/rita33cool1/iot-system-gateway@v0.0.0-20200911033302-e65bde238cc5/docker-engine/integration-cli/docker_cli_attach_unix_test.go (about) 1 // +build !windows 2 3 package main 4 5 import ( 6 "bufio" 7 "io/ioutil" 8 "os/exec" 9 "strings" 10 "time" 11 12 "github.com/docker/docker/integration-cli/checker" 13 "github.com/docker/docker/pkg/stringid" 14 "github.com/go-check/check" 15 "github.com/kr/pty" 16 ) 17 18 // #9860 Make sure attach ends when container ends (with no errors) 19 func (s *DockerSuite) TestAttachClosedOnContainerStop(c *check.C) { 20 testRequires(c, SameHostDaemon) 21 22 out, _ := dockerCmd(c, "run", "-dti", "busybox", "/bin/sh", "-c", `trap 'exit 0' SIGTERM; while true; do sleep 1; done`) 23 24 id := strings.TrimSpace(out) 25 c.Assert(waitRun(id), check.IsNil) 26 27 pty, tty, err := pty.Open() 28 c.Assert(err, check.IsNil) 29 30 attachCmd := exec.Command(dockerBinary, "attach", id) 31 attachCmd.Stdin = tty 32 attachCmd.Stdout = tty 33 attachCmd.Stderr = tty 34 err = attachCmd.Start() 35 c.Assert(err, check.IsNil) 36 37 errChan := make(chan error) 38 go func() { 39 time.Sleep(300 * time.Millisecond) 40 defer close(errChan) 41 // Container is waiting for us to signal it to stop 42 dockerCmd(c, "stop", id) 43 // And wait for the attach command to end 44 errChan <- attachCmd.Wait() 45 }() 46 47 // Wait for the docker to end (should be done by the 48 // stop command in the go routine) 49 dockerCmd(c, "wait", id) 50 51 select { 52 case err := <-errChan: 53 tty.Close() 54 out, _ := ioutil.ReadAll(pty) 55 c.Assert(err, check.IsNil, check.Commentf("out: %v", string(out))) 56 case <-time.After(attachWait): 57 c.Fatal("timed out without attach returning") 58 } 59 60 } 61 62 func (s *DockerSuite) TestAttachAfterDetach(c *check.C) { 63 name := "detachtest" 64 65 cpty, tty, err := pty.Open() 66 c.Assert(err, checker.IsNil, check.Commentf("Could not open pty: %v", err)) 67 cmd := exec.Command(dockerBinary, "run", "-ti", "--name", name, "busybox") 68 cmd.Stdin = tty 69 cmd.Stdout = tty 70 cmd.Stderr = tty 71 72 cmdExit := make(chan error) 73 go func() { 74 cmdExit <- cmd.Run() 75 close(cmdExit) 76 }() 77 78 c.Assert(waitRun(name), check.IsNil) 79 80 cpty.Write([]byte{16}) 81 time.Sleep(100 * time.Millisecond) 82 cpty.Write([]byte{17}) 83 84 select { 85 case <-cmdExit: 86 case <-time.After(5 * time.Second): 87 c.Fatal("timeout while detaching") 88 } 89 90 cpty, tty, err = pty.Open() 91 c.Assert(err, checker.IsNil, check.Commentf("Could not open pty: %v", err)) 92 93 cmd = exec.Command(dockerBinary, "attach", name) 94 cmd.Stdin = tty 95 cmd.Stdout = tty 96 cmd.Stderr = tty 97 98 err = cmd.Start() 99 c.Assert(err, checker.IsNil) 100 defer cmd.Process.Kill() 101 102 bytes := make([]byte, 10) 103 var nBytes int 104 readErr := make(chan error, 1) 105 106 go func() { 107 time.Sleep(500 * time.Millisecond) 108 cpty.Write([]byte("\n")) 109 time.Sleep(500 * time.Millisecond) 110 111 nBytes, err = cpty.Read(bytes) 112 cpty.Close() 113 readErr <- err 114 }() 115 116 select { 117 case err := <-readErr: 118 c.Assert(err, check.IsNil) 119 case <-time.After(2 * time.Second): 120 c.Fatal("timeout waiting for attach read") 121 } 122 123 c.Assert(string(bytes[:nBytes]), checker.Contains, "/ #") 124 } 125 126 // TestAttachDetach checks that attach in tty mode can be detached using the long container ID 127 func (s *DockerSuite) TestAttachDetach(c *check.C) { 128 out, _ := dockerCmd(c, "run", "-itd", "busybox", "cat") 129 id := strings.TrimSpace(out) 130 c.Assert(waitRun(id), check.IsNil) 131 132 cpty, tty, err := pty.Open() 133 c.Assert(err, check.IsNil) 134 defer cpty.Close() 135 136 cmd := exec.Command(dockerBinary, "attach", id) 137 cmd.Stdin = tty 138 stdout, err := cmd.StdoutPipe() 139 c.Assert(err, check.IsNil) 140 defer stdout.Close() 141 err = cmd.Start() 142 c.Assert(err, check.IsNil) 143 c.Assert(waitRun(id), check.IsNil) 144 145 _, err = cpty.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), checker.Equals, "hello", check.Commentf("expected 'hello', got %q", out)) 150 151 // escape sequence 152 _, err = cpty.Write([]byte{16}) 153 c.Assert(err, checker.IsNil) 154 time.Sleep(100 * time.Millisecond) 155 _, err = cpty.Write([]byte{17}) 156 c.Assert(err, checker.IsNil) 157 158 ch := make(chan struct{}) 159 go func() { 160 cmd.Wait() 161 ch <- struct{}{} 162 }() 163 164 running := inspectField(c, id, "State.Running") 165 c.Assert(running, checker.Equals, "true", check.Commentf("expected container to still be running")) 166 167 go func() { 168 dockerCmdWithResult("kill", id) 169 }() 170 171 select { 172 case <-ch: 173 case <-time.After(10 * time.Millisecond): 174 c.Fatal("timed out waiting for container to exit") 175 } 176 177 } 178 179 // TestAttachDetachTruncatedID checks that attach in tty mode can be detached 180 func (s *DockerSuite) TestAttachDetachTruncatedID(c *check.C) { 181 out, _ := dockerCmd(c, "run", "-itd", "busybox", "cat") 182 id := stringid.TruncateID(strings.TrimSpace(out)) 183 c.Assert(waitRun(id), check.IsNil) 184 185 cpty, tty, err := pty.Open() 186 c.Assert(err, checker.IsNil) 187 defer cpty.Close() 188 189 cmd := exec.Command(dockerBinary, "attach", id) 190 cmd.Stdin = tty 191 stdout, err := cmd.StdoutPipe() 192 c.Assert(err, checker.IsNil) 193 defer stdout.Close() 194 err = cmd.Start() 195 c.Assert(err, checker.IsNil) 196 197 _, err = cpty.Write([]byte("hello\n")) 198 c.Assert(err, checker.IsNil) 199 out, err = bufio.NewReader(stdout).ReadString('\n') 200 c.Assert(err, checker.IsNil) 201 c.Assert(strings.TrimSpace(out), checker.Equals, "hello", check.Commentf("expected 'hello', got %q", out)) 202 203 // escape sequence 204 _, err = cpty.Write([]byte{16}) 205 c.Assert(err, checker.IsNil) 206 time.Sleep(100 * time.Millisecond) 207 _, err = cpty.Write([]byte{17}) 208 c.Assert(err, checker.IsNil) 209 210 ch := make(chan struct{}) 211 go func() { 212 cmd.Wait() 213 ch <- struct{}{} 214 }() 215 216 running := inspectField(c, id, "State.Running") 217 c.Assert(running, checker.Equals, "true", check.Commentf("expected container to still be running")) 218 219 go func() { 220 dockerCmdWithResult("kill", id) 221 }() 222 223 select { 224 case <-ch: 225 case <-time.After(10 * time.Millisecond): 226 c.Fatal("timed out waiting for container to exit") 227 } 228 229 }