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