github.com/endophage/docker@v1.4.2-0.20161027011718-242853499895/integration-cli/docker_api_exec_resize_test.go (about) 1 package main 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "io" 8 "net/http" 9 "strings" 10 "sync" 11 12 "github.com/docker/docker/pkg/integration/checker" 13 "github.com/go-check/check" 14 ) 15 16 func (s *DockerSuite) TestExecResizeAPIHeightWidthNoInt(c *check.C) { 17 testRequires(c, DaemonIsLinux) 18 out, _ := dockerCmd(c, "run", "-d", "busybox", "top") 19 cleanedContainerID := strings.TrimSpace(out) 20 21 endpoint := "/exec/" + cleanedContainerID + "/resize?h=foo&w=bar" 22 status, _, err := sockRequest("POST", endpoint, nil) 23 c.Assert(err, checker.IsNil) 24 c.Assert(status, checker.Equals, http.StatusInternalServerError) 25 } 26 27 // Part of #14845 28 func (s *DockerSuite) TestExecResizeImmediatelyAfterExecStart(c *check.C) { 29 name := "exec_resize_test" 30 dockerCmd(c, "run", "-d", "-i", "-t", "--name", name, "--restart", "always", "busybox", "/bin/sh") 31 32 testExecResize := func() error { 33 data := map[string]interface{}{ 34 "AttachStdin": true, 35 "Cmd": []string{"/bin/sh"}, 36 } 37 uri := fmt.Sprintf("/containers/%s/exec", name) 38 status, body, err := sockRequest("POST", uri, data) 39 if err != nil { 40 return err 41 } 42 if status != http.StatusCreated { 43 return fmt.Errorf("POST %s is expected to return %d, got %d", uri, http.StatusCreated, status) 44 } 45 46 out := map[string]string{} 47 err = json.Unmarshal(body, &out) 48 if err != nil { 49 return fmt.Errorf("ExecCreate returned invalid json. Error: %q", err.Error()) 50 } 51 52 execID := out["Id"] 53 if len(execID) < 1 { 54 return fmt.Errorf("ExecCreate got invalid execID") 55 } 56 57 payload := bytes.NewBufferString(`{"Tty":true}`) 58 conn, _, err := sockRequestHijack("POST", fmt.Sprintf("/exec/%s/start", execID), payload, "application/json") 59 if err != nil { 60 return fmt.Errorf("Failed to start the exec: %q", err.Error()) 61 } 62 defer conn.Close() 63 64 _, rc, err := sockRequestRaw("POST", fmt.Sprintf("/exec/%s/resize?h=24&w=80", execID), nil, "text/plain") 65 // It's probably a panic of the daemon if io.ErrUnexpectedEOF is returned. 66 if err == io.ErrUnexpectedEOF { 67 return fmt.Errorf("The daemon might have crashed.") 68 } 69 70 if err == nil { 71 rc.Close() 72 } 73 74 // We only interested in the io.ErrUnexpectedEOF error, so we return nil otherwise. 75 return nil 76 } 77 78 // The panic happens when daemon.ContainerExecStart is called but the 79 // container.Exec is not called. 80 // Because the panic is not 100% reproducible, we send the requests concurrently 81 // to increase the probability that the problem is triggered. 82 var ( 83 n = 10 84 ch = make(chan error, n) 85 wg sync.WaitGroup 86 ) 87 for i := 0; i < n; i++ { 88 wg.Add(1) 89 go func() { 90 defer wg.Done() 91 if err := testExecResize(); err != nil { 92 ch <- err 93 } 94 }() 95 } 96 97 wg.Wait() 98 select { 99 case err := <-ch: 100 c.Fatal(err.Error()) 101 default: 102 } 103 }