From a8715ea2207966e649e66a4fafcf34517234061f Mon Sep 17 00:00:00 2001 From: Megan Kostick Date: Thu, 9 Jul 2015 11:49:41 -0700 Subject: [PATCH] Port POST container attach tests Signed-off-by: Megan Kostick --- integration-cli/docker_api_attach_test.go | 132 ++++++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/integration-cli/docker_api_attach_test.go b/integration-cli/docker_api_attach_test.go index 148164e9b7..d6ec24e0c3 100644 --- a/integration-cli/docker_api_attach_test.go +++ b/integration-cli/docker_api_attach_test.go @@ -2,7 +2,9 @@ package main import ( "bytes" + "io" "net/http" + "net/http/httputil" "os/exec" "strings" "time" @@ -98,3 +100,133 @@ func (s *DockerSuite) TestGetContainersWsAttachContainerNotFound(c *check.C) { c.Fatalf("Expected response body to contain %q", expected) } } + +func (s *DockerSuite) TestPostContainersAttach(c *check.C) { + runCmd := exec.Command(dockerBinary, "run", "-dit", "busybox", "cat") + out, _, err := runCommandWithOutput(runCmd) + c.Assert(err, check.IsNil) + + r, w := io.Pipe() + defer r.Close() + defer w.Close() + + conn, err := sockConn(time.Duration(10 * time.Second)) + c.Assert(err, check.IsNil) + + containerID := strings.TrimSpace(out) + + req, err := http.NewRequest("POST", "/containers/"+containerID+"/attach?stream=1&stdin=1&stdout=1&stderr=1", bytes.NewReader([]byte{})) + c.Assert(err, check.IsNil) + + client := httputil.NewClientConn(conn, nil) + defer client.Close() + + // Do POST attach request + resp, err := client.Do(req) + c.Assert(resp.StatusCode, check.Equals, http.StatusOK) + // If we check the err, we get a ErrPersistEOF = &http.ProtocolError{ErrorString: "persistent connection closed"} + // This means that the remote requested this be the last request serviced, is this okay? + + // Test read and write to the attached container + expected := []byte("hello") + actual := make([]byte, len(expected)) + + outChan := make(chan error) + go func() { + _, err := r.Read(actual) + outChan <- err + close(outChan) + }() + + inChan := make(chan error) + go func() { + _, err := w.Write(expected) + inChan <- err + close(inChan) + }() + + select { + case err := <-inChan: + c.Assert(err, check.IsNil) + case <-time.After(5 * time.Second): + c.Fatal("Timeout writing to stdout") + } + + select { + case err := <-outChan: + c.Assert(err, check.IsNil) + case <-time.After(5 * time.Second): + c.Fatal("Timeout reading from stdin") + } + + if !bytes.Equal(expected, actual) { + c.Fatal("Expected output to match input") + } + + resp.Body.Close() +} + +func (s *DockerSuite) TestPostContainersAttachStderr(c *check.C) { + runCmd := exec.Command(dockerBinary, "run", "-dit", "busybox", "/bin/sh", "-c", "cat >&2") + out, _, err := runCommandWithOutput(runCmd) + c.Assert(err, check.IsNil) + + r, w := io.Pipe() + defer r.Close() + defer w.Close() + + conn, err := sockConn(time.Duration(10 * time.Second)) + c.Assert(err, check.IsNil) + + containerID := strings.TrimSpace(out) + + req, err := http.NewRequest("POST", "/containers/"+containerID+"/attach?stream=1&stdin=1&stdout=1&stderr=1", bytes.NewReader([]byte{})) + c.Assert(err, check.IsNil) + + client := httputil.NewClientConn(conn, nil) + defer client.Close() + + // Do POST attach request + resp, err := client.Do(req) + c.Assert(resp.StatusCode, check.Equals, http.StatusOK) + // If we check the err, we get a ErrPersistEOF = &http.ProtocolError{ErrorString: "persistent connection closed"} + // This means that the remote requested this be the last request serviced, is this okay? + + // Test read and write to the attached container + expected := []byte("hello") + actual := make([]byte, len(expected)) + + outChan := make(chan error) + go func() { + _, err := r.Read(actual) + outChan <- err + close(outChan) + }() + + inChan := make(chan error) + go func() { + _, err := w.Write(expected) + inChan <- err + close(inChan) + }() + + select { + case err := <-inChan: + c.Assert(err, check.IsNil) + case <-time.After(5 * time.Second): + c.Fatal("Timeout writing to stdout") + } + + select { + case err := <-outChan: + c.Assert(err, check.IsNil) + case <-time.After(5 * time.Second): + c.Fatal("Timeout reading from stdin") + } + + if !bytes.Equal(expected, actual) { + c.Fatal("Expected output to match input") + } + + resp.Body.Close() +}