1package client // import "github.com/docker/docker/client" 2 3import ( 4 "bytes" 5 "context" 6 "fmt" 7 "io/ioutil" 8 "math/rand" 9 "net/http" 10 "strings" 11 "testing" 12 13 "github.com/docker/docker/api/types" 14 "github.com/docker/docker/errdefs" 15 "gotest.tools/v3/assert" 16 is "gotest.tools/v3/assert/cmp" 17) 18 19// TestSetHostHeader should set fake host for local communications, set real host 20// for normal communications. 21func TestSetHostHeader(t *testing.T) { 22 testURL := "/test" 23 testCases := []struct { 24 host string 25 expectedHost string 26 expectedURLHost string 27 }{ 28 { 29 "unix:///var/run/docker.sock", 30 "docker", 31 "/var/run/docker.sock", 32 }, 33 { 34 "npipe:////./pipe/docker_engine", 35 "docker", 36 "//./pipe/docker_engine", 37 }, 38 { 39 "tcp://0.0.0.0:4243", 40 "", 41 "0.0.0.0:4243", 42 }, 43 { 44 "tcp://localhost:4243", 45 "", 46 "localhost:4243", 47 }, 48 } 49 50 for c, test := range testCases { 51 hostURL, err := ParseHostURL(test.host) 52 assert.NilError(t, err) 53 54 client := &Client{ 55 client: newMockClient(func(req *http.Request) (*http.Response, error) { 56 if !strings.HasPrefix(req.URL.Path, testURL) { 57 return nil, fmt.Errorf("Test Case #%d: Expected URL %q, got %q", c, testURL, req.URL) 58 } 59 if req.Host != test.expectedHost { 60 return nil, fmt.Errorf("Test Case #%d: Expected host %q, got %q", c, test.expectedHost, req.Host) 61 } 62 if req.URL.Host != test.expectedURLHost { 63 return nil, fmt.Errorf("Test Case #%d: Expected URL host %q, got %q", c, test.expectedURLHost, req.URL.Host) 64 } 65 return &http.Response{ 66 StatusCode: http.StatusOK, 67 Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), 68 }, nil 69 }), 70 71 proto: hostURL.Scheme, 72 addr: hostURL.Host, 73 basePath: hostURL.Path, 74 } 75 76 _, err = client.sendRequest(context.Background(), http.MethodGet, testURL, nil, nil, nil) 77 assert.NilError(t, err) 78 } 79} 80 81// TestPlainTextError tests the server returning an error in plain text for 82// backwards compatibility with API versions <1.24. All other tests use 83// errors returned as JSON 84func TestPlainTextError(t *testing.T) { 85 client := &Client{ 86 client: newMockClient(plainTextErrorMock(http.StatusInternalServerError, "Server error")), 87 } 88 _, err := client.ContainerList(context.Background(), types.ContainerListOptions{}) 89 if !errdefs.IsSystem(err) { 90 t.Fatalf("expected a Server Error, got %[1]T: %[1]v", err) 91 } 92} 93 94func TestInfiniteError(t *testing.T) { 95 infinitR := rand.New(rand.NewSource(42)) 96 client := &Client{ 97 client: newMockClient(func(req *http.Request) (*http.Response, error) { 98 resp := &http.Response{StatusCode: http.StatusInternalServerError} 99 resp.Header = http.Header{} 100 resp.Body = ioutil.NopCloser(infinitR) 101 return resp, nil 102 }), 103 } 104 105 _, err := client.Ping(context.Background()) 106 assert.Check(t, is.ErrorContains(err, "request returned Internal Server Error")) 107} 108