github.com/pritambaral/docker@v1.4.2-0.20150120174542-b2fe1b3dd952/integration-cli/docker_cli_attach_unix_test.go (about) 1 // +build !windows 2 3 package main 4 5 import ( 6 "os/exec" 7 "strings" 8 "testing" 9 "time" 10 11 "github.com/kr/pty" 12 ) 13 14 // #9860 15 func TestAttachClosedOnContainerStop(t *testing.T) { 16 defer deleteAllContainers() 17 18 cmd := exec.Command(dockerBinary, "run", "-dti", "busybox", "sleep", "2") 19 out, _, err := runCommandWithOutput(cmd) 20 if err != nil { 21 t.Fatalf("failed to start container: %v (%v)", out, err) 22 } 23 24 id := stripTrailingCharacters(out) 25 if err := waitRun(id); err != nil { 26 t.Fatal(err) 27 } 28 29 done := make(chan struct{}) 30 31 go func() { 32 defer close(done) 33 34 _, tty, err := pty.Open() 35 if err != nil { 36 t.Fatalf("could not open pty: %v", err) 37 } 38 attachCmd := exec.Command(dockerBinary, "attach", id) 39 attachCmd.Stdin = tty 40 attachCmd.Stdout = tty 41 attachCmd.Stderr = tty 42 43 if err := attachCmd.Run(); err != nil { 44 t.Fatalf("attach returned error %s", err) 45 } 46 }() 47 48 waitCmd := exec.Command(dockerBinary, "wait", id) 49 if out, _, err = runCommandWithOutput(waitCmd); err != nil { 50 t.Fatalf("error thrown while waiting for container: %s, %v", out, err) 51 } 52 select { 53 case <-done: 54 case <-time.After(attachWait): 55 t.Fatal("timed out without attach returning") 56 } 57 58 logDone("attach - return after container finished") 59 } 60 61 func TestAttachAfterDetach(t *testing.T) { 62 defer deleteAllContainers() 63 64 name := "detachtest" 65 66 cpty, tty, err := pty.Open() 67 if err != nil { 68 t.Fatalf("Could not open pty: %v", err) 69 } 70 cmd := exec.Command(dockerBinary, "run", "-ti", "--name", name, "busybox") 71 cmd.Stdin = tty 72 cmd.Stdout = tty 73 cmd.Stderr = tty 74 75 detached := make(chan struct{}) 76 go func() { 77 if err := cmd.Run(); err != nil { 78 t.Fatalf("attach returned error %s", err) 79 } 80 close(detached) 81 }() 82 83 time.Sleep(500 * time.Millisecond) 84 cpty.Write([]byte{16}) 85 time.Sleep(100 * time.Millisecond) 86 cpty.Write([]byte{17}) 87 88 <-detached 89 90 cpty, tty, err = pty.Open() 91 if err != nil { 92 t.Fatalf("Could not open pty: %v", err) 93 } 94 95 cmd = exec.Command(dockerBinary, "attach", name) 96 cmd.Stdin = tty 97 cmd.Stdout = tty 98 cmd.Stderr = tty 99 100 go func() { 101 if err := cmd.Run(); err != nil { 102 t.Fatalf("attach returned error %s", err) 103 } 104 cpty.Close() // unblocks the reader in case of a failure 105 }() 106 107 time.Sleep(500 * time.Millisecond) 108 cpty.Write([]byte("\n")) 109 time.Sleep(500 * time.Millisecond) 110 bytes := make([]byte, 10) 111 112 n, err := cpty.Read(bytes) 113 114 if err != nil { 115 t.Fatalf("prompt read failed: %v", err) 116 } 117 118 if !strings.Contains(string(bytes[:n]), "/ #") { 119 t.Fatalf("failed to get a new prompt. got %s", string(bytes[:n])) 120 } 121 122 cpty.Write([]byte("exit\n")) 123 124 logDone("attach - reconnect after detaching") 125 }