client: remove transport package

This package doesn't really seem to do anything of real interest.
Removing it and replacing with a few helper functions. Most of this was
maintaining a fork of ctxhttp to support a mock that was unnecessary.

We could probably do with a further refactor of the client interface.
There is a lot of confusion of between transport, http layer and
application layer that makes for some awkward code. This change
improves the situation to the point where no breaking changes are
introduced.

Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
Stephen J Day 2016-09-08 20:44:25 -07:00
parent 9d7be9df8f
commit 9a072adff3
No known key found for this signature in database
GPG Key ID: FB5F6B2905D7ECF3
86 changed files with 276 additions and 533 deletions

View File

@ -15,7 +15,7 @@ import (
func TestCheckpointCreateError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.CheckpointCreate(context.Background(), "nothing", types.CheckpointCreateOptions{
CheckpointID: "noting",
@ -33,7 +33,7 @@ func TestCheckpointCreate(t *testing.T) {
expectedURL := "/containers/container_id/checkpoints"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -13,7 +13,7 @@ import (
func TestCheckpointDeleteError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.CheckpointDelete(context.Background(), "container_id", "checkpoint_id")
@ -26,7 +26,7 @@ func TestCheckpointDelete(t *testing.T) {
expectedURL := "/containers/container_id/checkpoints/checkpoint_id"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -15,7 +15,7 @@ import (
func TestCheckpointListError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.CheckpointList(context.Background(), "container_id")
@ -28,7 +28,7 @@ func TestCheckpointList(t *testing.T) {
expectedURL := "/containers/container_id/checkpoints"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -8,7 +8,7 @@ import (
"path/filepath"
"strings"
"github.com/docker/docker/client/transport"
"github.com/docker/go-connections/sockets"
"github.com/docker/go-connections/tlsconfig"
)
@ -26,8 +26,8 @@ type Client struct {
addr string
// basePath holds the path to prepend to the requests.
basePath string
// transport is the interface to send request with, it implements transport.Client.
transport transport.Client
// client used to send and receive http requests.
client *http.Client
// version of the server to talk to.
version string
// custom http headers configured by users.
@ -86,9 +86,15 @@ func NewClient(host string, version string, client *http.Client, httpHeaders map
return nil, err
}
transport, err := transport.NewTransportWithHTTP(proto, addr, client)
if err != nil {
return nil, err
if client == nil {
client = &http.Client{}
}
if client.Transport == nil {
// setup the transport, if not already present
transport := new(http.Transport)
sockets.ConfigureTransport(transport, proto, addr)
client.Transport = transport
}
return &Client{
@ -96,7 +102,7 @@ func NewClient(host string, version string, client *http.Client, httpHeaders map
proto: proto,
addr: addr,
basePath: basePath,
transport: transport,
client: client,
version: version,
customHTTPHeaders: httpHeaders,
}, nil

View File

@ -2,48 +2,17 @@ package client
import (
"bytes"
"crypto/tls"
"encoding/json"
"io/ioutil"
"net/http"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client/transport"
)
type mockClient struct {
do func(*http.Request) (*http.Response, error)
}
// TLSConfig returns the TLS configuration.
func (m *mockClient) TLSConfig() *tls.Config {
return &tls.Config{}
}
// Scheme returns protocol scheme to use.
func (m *mockClient) Scheme() string {
return "http"
}
// Secure returns true if there is a TLS configuration.
func (m *mockClient) Secure() bool {
return false
}
// NewMockClient returns a mocked client that runs the function supplied as `client.Do` call
func newMockClient(tlsConfig *tls.Config, doer func(*http.Request) (*http.Response, error)) transport.Client {
if tlsConfig != nil {
panic("this actually gets set!")
func newMockClient(doer func(*http.Request) (*http.Response, error)) *http.Client {
return &http.Client{
Transport: transportFunc(doer),
}
return &mockClient{
do: doer,
}
}
// Do executes the supplied function for the mock.
func (m mockClient) Do(req *http.Request) (*http.Response, error) {
return m.do(req)
}
func errorMock(statusCode int, message string) func(req *http.Request) (*http.Response, error) {

View File

@ -173,7 +173,7 @@ func TestParseHost(t *testing.T) {
func TestUpdateClientVersion(t *testing.T) {
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
splitQuery := strings.Split(req.URL.Path, "/")
queryVersion := splitQuery[1]
b, err := json.Marshal(types.Version{

View File

@ -15,7 +15,7 @@ import (
func TestContainerCommitError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ContainerCommit(context.Background(), "nothing", types.ContainerCommitOptions{})
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -34,7 +34,7 @@ func TestContainerCommit(t *testing.T) {
expectedChanges := []string{"change1", "change2"}
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -17,7 +17,7 @@ import (
func TestContainerStatPathError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ContainerStatPath(context.Background(), "container_id", "path")
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -27,7 +27,7 @@ func TestContainerStatPathError(t *testing.T) {
func TestContainerStatPathNoHeaderError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: http.StatusOK,
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
@ -44,7 +44,7 @@ func TestContainerStatPath(t *testing.T) {
expectedURL := "/containers/container_id/archive"
expectedPath := "path/to/file"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}
@ -87,7 +87,7 @@ func TestContainerStatPath(t *testing.T) {
func TestCopyToContainerError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.CopyToContainer(context.Background(), "container_id", "path/to/file", bytes.NewReader([]byte("")), types.CopyToContainerOptions{})
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -97,7 +97,7 @@ func TestCopyToContainerError(t *testing.T) {
func TestCopyToContainerNotStatusOKError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusNoContent, "No content")),
client: newMockClient(errorMock(http.StatusNoContent, "No content")),
}
err := client.CopyToContainer(context.Background(), "container_id", "path/to/file", bytes.NewReader([]byte("")), types.CopyToContainerOptions{})
if err == nil || err.Error() != "unexpected status code from daemon: 204" {
@ -109,7 +109,7 @@ func TestCopyToContainer(t *testing.T) {
expectedURL := "/containers/container_id/archive"
expectedPath := "path/to/file"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}
@ -153,7 +153,7 @@ func TestCopyToContainer(t *testing.T) {
func TestCopyFromContainerError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, _, err := client.CopyFromContainer(context.Background(), "container_id", "path/to/file")
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -163,7 +163,7 @@ func TestCopyFromContainerError(t *testing.T) {
func TestCopyFromContainerNotStatusOKError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusNoContent, "No content")),
client: newMockClient(errorMock(http.StatusNoContent, "No content")),
}
_, _, err := client.CopyFromContainer(context.Background(), "container_id", "path/to/file")
if err == nil || err.Error() != "unexpected status code from daemon: 204" {
@ -173,7 +173,7 @@ func TestCopyFromContainerNotStatusOKError(t *testing.T) {
func TestCopyFromContainerNoHeaderError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: http.StatusOK,
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
@ -190,7 +190,7 @@ func TestCopyFromContainer(t *testing.T) {
expectedURL := "/containers/container_id/archive"
expectedPath := "path/to/file"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -16,7 +16,7 @@ import (
func TestContainerCreateError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ContainerCreate(context.Background(), nil, nil, nil, "nothing")
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -25,7 +25,7 @@ func TestContainerCreateError(t *testing.T) {
// 404 doesn't automagitally means an unknown image
client = &Client{
transport: newMockClient(nil, errorMock(http.StatusNotFound, "Server error")),
client: newMockClient(errorMock(http.StatusNotFound, "Server error")),
}
_, err = client.ContainerCreate(context.Background(), nil, nil, nil, "nothing")
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -35,7 +35,7 @@ func TestContainerCreateError(t *testing.T) {
func TestContainerCreateImageNotFound(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusNotFound, "No such image")),
client: newMockClient(errorMock(http.StatusNotFound, "No such image")),
}
_, err := client.ContainerCreate(context.Background(), &container.Config{Image: "unknown_image"}, nil, nil, "unknown")
if err == nil || !IsErrImageNotFound(err) {
@ -46,7 +46,7 @@ func TestContainerCreateImageNotFound(t *testing.T) {
func TestContainerCreateWithName(t *testing.T) {
expectedURL := "/containers/create"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -15,7 +15,7 @@ import (
func TestContainerDiffError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ContainerDiff(context.Background(), "nothing")
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -27,7 +27,7 @@ func TestContainerDiffError(t *testing.T) {
func TestContainerDiff(t *testing.T) {
expectedURL := "/containers/container_id/changes"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -16,7 +16,7 @@ import (
func TestContainerExecCreateError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ContainerExecCreate(context.Background(), "container_id", types.ExecConfig{})
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -27,7 +27,7 @@ func TestContainerExecCreateError(t *testing.T) {
func TestContainerExecCreate(t *testing.T) {
expectedURL := "/containers/container_id/exec"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("expected URL '%s', got '%s'", expectedURL, req.URL)
}
@ -71,7 +71,7 @@ func TestContainerExecCreate(t *testing.T) {
func TestContainerExecStartError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.ContainerExecStart(context.Background(), "nothing", types.ExecStartCheck{})
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -82,7 +82,7 @@ func TestContainerExecStartError(t *testing.T) {
func TestContainerExecStart(t *testing.T) {
expectedURL := "/exec/exec_id/start"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}
@ -115,7 +115,7 @@ func TestContainerExecStart(t *testing.T) {
func TestContainerExecInspectError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ContainerExecInspect(context.Background(), "nothing")
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -126,7 +126,7 @@ func TestContainerExecInspectError(t *testing.T) {
func TestContainerExecInspect(t *testing.T) {
expectedURL := "/exec/exec_id/json"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -13,7 +13,7 @@ import (
func TestContainerExportError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ContainerExport(context.Background(), "nothing")
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -24,7 +24,7 @@ func TestContainerExportError(t *testing.T) {
func TestContainerExport(t *testing.T) {
expectedURL := "/containers/container_id/export"
client := &Client{
transport: newMockClient(nil, func(r *http.Request) (*http.Response, error) {
client: newMockClient(func(r *http.Request) (*http.Response, error) {
if !strings.HasPrefix(r.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, r.URL)
}

View File

@ -15,7 +15,7 @@ import (
func TestContainerInspectError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ContainerInspect(context.Background(), "nothing")
@ -26,7 +26,7 @@ func TestContainerInspectError(t *testing.T) {
func TestContainerInspectContainerNotFound(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusNotFound, "Server error")),
client: newMockClient(errorMock(http.StatusNotFound, "Server error")),
}
_, err := client.ContainerInspect(context.Background(), "unknown")
@ -38,7 +38,7 @@ func TestContainerInspectContainerNotFound(t *testing.T) {
func TestContainerInspect(t *testing.T) {
expectedURL := "/containers/container_id/json"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}
@ -76,7 +76,7 @@ func TestContainerInspect(t *testing.T) {
func TestContainerInspectNode(t *testing.T) {
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
content, err := json.Marshal(types.ContainerJSON{
ContainerJSONBase: &types.ContainerJSONBase{
ID: "container_id",

View File

@ -13,7 +13,7 @@ import (
func TestContainerKillError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.ContainerKill(context.Background(), "nothing", "SIGKILL")
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -24,7 +24,7 @@ func TestContainerKillError(t *testing.T) {
func TestContainerKill(t *testing.T) {
expectedURL := "/containers/container_id/kill"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -16,7 +16,7 @@ import (
func TestContainerListError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ContainerList(context.Background(), types.ContainerListOptions{})
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -28,7 +28,7 @@ func TestContainerList(t *testing.T) {
expectedURL := "/containers/json"
expectedFilters := `{"before":{"container":true},"label":{"label1":true,"label2":true}}`
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -19,7 +19,7 @@ import (
func TestContainerLogsError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ContainerLogs(context.Background(), "container_id", types.ContainerLogsOptions{})
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -83,7 +83,7 @@ func TestContainerLogs(t *testing.T) {
}
for _, logCase := range cases {
client := &Client{
transport: newMockClient(nil, func(r *http.Request) (*http.Response, error) {
client: newMockClient(func(r *http.Request) (*http.Response, error) {
if !strings.HasPrefix(r.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, r.URL)
}

View File

@ -13,7 +13,7 @@ import (
func TestContainerPauseError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.ContainerPause(context.Background(), "nothing")
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -24,7 +24,7 @@ func TestContainerPauseError(t *testing.T) {
func TestContainerPause(t *testing.T) {
expectedURL := "/containers/container_id/pause"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -14,7 +14,7 @@ import (
func TestContainerRemoveError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.ContainerRemove(context.Background(), "container_id", types.ContainerRemoveOptions{})
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -25,7 +25,7 @@ func TestContainerRemoveError(t *testing.T) {
func TestContainerRemove(t *testing.T) {
expectedURL := "/containers/container_id"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -13,7 +13,7 @@ import (
func TestContainerRenameError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.ContainerRename(context.Background(), "nothing", "newNothing")
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -24,7 +24,7 @@ func TestContainerRenameError(t *testing.T) {
func TestContainerRename(t *testing.T) {
expectedURL := "/containers/container_id/rename"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -14,7 +14,7 @@ import (
func TestContainerResizeError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.ContainerResize(context.Background(), "container_id", types.ResizeOptions{})
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -24,7 +24,7 @@ func TestContainerResizeError(t *testing.T) {
func TestContainerExecResizeError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.ContainerExecResize(context.Background(), "exec_id", types.ResizeOptions{})
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -34,7 +34,7 @@ func TestContainerExecResizeError(t *testing.T) {
func TestContainerResize(t *testing.T) {
client := &Client{
transport: newMockClient(nil, resizeTransport("/containers/container_id/resize")),
client: newMockClient(resizeTransport("/containers/container_id/resize")),
}
err := client.ContainerResize(context.Background(), "container_id", types.ResizeOptions{
@ -48,7 +48,7 @@ func TestContainerResize(t *testing.T) {
func TestContainerExecResize(t *testing.T) {
client := &Client{
transport: newMockClient(nil, resizeTransport("/exec/exec_id/resize")),
client: newMockClient(resizeTransport("/exec/exec_id/resize")),
}
err := client.ContainerExecResize(context.Background(), "exec_id", types.ResizeOptions{

View File

@ -14,7 +14,7 @@ import (
func TestContainerRestartError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
timeout := 0 * time.Second
err := client.ContainerRestart(context.Background(), "nothing", &timeout)
@ -26,7 +26,7 @@ func TestContainerRestartError(t *testing.T) {
func TestContainerRestart(t *testing.T) {
expectedURL := "/containers/container_id/restart"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -16,7 +16,7 @@ import (
func TestContainerStartError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.ContainerStart(context.Background(), "nothing", types.ContainerStartOptions{})
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -27,7 +27,7 @@ func TestContainerStartError(t *testing.T) {
func TestContainerStart(t *testing.T) {
expectedURL := "/containers/container_id/start"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -13,7 +13,7 @@ import (
func TestContainerStatsError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ContainerStats(context.Background(), "nothing", false)
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -37,7 +37,7 @@ func TestContainerStats(t *testing.T) {
}
for _, c := range cases {
client := &Client{
transport: newMockClient(nil, func(r *http.Request) (*http.Response, error) {
client: newMockClient(func(r *http.Request) (*http.Response, error) {
if !strings.HasPrefix(r.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, r.URL)
}

View File

@ -14,7 +14,7 @@ import (
func TestContainerStopError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
timeout := 0 * time.Second
err := client.ContainerStop(context.Background(), "nothing", &timeout)
@ -26,7 +26,7 @@ func TestContainerStopError(t *testing.T) {
func TestContainerStop(t *testing.T) {
expectedURL := "/containers/container_id/stop"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -16,7 +16,7 @@ import (
func TestContainerTopError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ContainerTop(context.Background(), "nothing", []string{})
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -33,7 +33,7 @@ func TestContainerTop(t *testing.T) {
expectedTitles := []string{"title1", "title2"}
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -13,7 +13,7 @@ import (
func TestContainerUnpauseError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.ContainerUnpause(context.Background(), "nothing")
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -24,7 +24,7 @@ func TestContainerUnpauseError(t *testing.T) {
func TestContainerUnpause(t *testing.T) {
expectedURL := "/containers/container_id/unpause"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -16,7 +16,7 @@ import (
func TestContainerUpdateError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ContainerUpdate(context.Background(), "nothing", container.UpdateConfig{})
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -28,7 +28,7 @@ func TestContainerUpdate(t *testing.T) {
expectedURL := "/containers/container_id/update"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -18,7 +18,7 @@ import (
func TestContainerWaitError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
code, err := client.ContainerWait(context.Background(), "nothing")
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -32,7 +32,7 @@ func TestContainerWaitError(t *testing.T) {
func TestContainerWait(t *testing.T) {
expectedURL := "/containers/container_id/wait"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -34,7 +34,7 @@ func TestEventsErrorInOptions(t *testing.T) {
}
for _, e := range errorCases {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.Events(context.Background(), e.options)
if err == nil || !strings.Contains(err.Error(), e.expectedError) {
@ -45,7 +45,7 @@ func TestEventsErrorInOptions(t *testing.T) {
func TestEventsErrorFromServer(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.Events(context.Background(), types.EventsOptions{})
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -93,7 +93,7 @@ func TestEvents(t *testing.T) {
for _, eventsCase := range eventsCases {
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -47,7 +47,12 @@ func (cli *Client) postHijacked(ctx context.Context, path string, query url.Valu
req.Header.Set("Connection", "Upgrade")
req.Header.Set("Upgrade", "tcp")
conn, err := dial(cli.proto, cli.addr, cli.transport.TLSConfig())
tlsConfig, err := resolveTLSConfig(cli.client.Transport)
if err != nil {
return types.HijackedResponse{}, err
}
conn, err := dial(cli.proto, cli.addr, tlsConfig)
if err != nil {
if strings.Contains(err.Error(), "connection refused") {
return types.HijackedResponse{}, fmt.Errorf("Cannot connect to the Docker daemon. Is 'docker daemon' running on this host?")

View File

@ -18,7 +18,7 @@ import (
func TestImageBuildError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ImageBuild(context.Background(), nil, types.ImageBuildOptions{})
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -157,7 +157,7 @@ func TestImageBuild(t *testing.T) {
for _, buildCase := range buildCases {
expectedURL := "/build"
client := &Client{
transport: newMockClient(nil, func(r *http.Request) (*http.Response, error) {
client: newMockClient(func(r *http.Request) (*http.Response, error) {
if !strings.HasPrefix(r.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, r.URL)
}

View File

@ -15,7 +15,7 @@ import (
func TestImageCreateError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ImageCreate(context.Background(), "reference", types.ImageCreateOptions{})
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -30,7 +30,7 @@ func TestImageCreate(t *testing.T) {
expectedReference := fmt.Sprintf("%s@%s", expectedImage, expectedTag)
expectedRegistryAuth := "eyJodHRwczovL2luZGV4LmRvY2tlci5pby92MS8iOnsiYXV0aCI6ImRHOTBid289IiwiZW1haWwiOiJqb2huQGRvZS5jb20ifX0="
client := &Client{
transport: newMockClient(nil, func(r *http.Request) (*http.Response, error) {
client: newMockClient(func(r *http.Request) (*http.Response, error) {
if !strings.HasPrefix(r.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, r.URL)
}

View File

@ -15,7 +15,7 @@ import (
func TestImageHistoryError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ImageHistory(context.Background(), "nothing")
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -26,7 +26,7 @@ func TestImageHistoryError(t *testing.T) {
func TestImageHistory(t *testing.T) {
expectedURL := "/images/image_id/history"
client := &Client{
transport: newMockClient(nil, func(r *http.Request) (*http.Response, error) {
client: newMockClient(func(r *http.Request) (*http.Response, error) {
if !strings.HasPrefix(r.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, r.URL)
}

View File

@ -15,7 +15,7 @@ import (
func TestImageImportError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ImageImport(context.Background(), types.ImageImportSource{}, "image:tag", types.ImageImportOptions{})
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -26,7 +26,7 @@ func TestImageImportError(t *testing.T) {
func TestImageImport(t *testing.T) {
expectedURL := "/images/create"
client := &Client{
transport: newMockClient(nil, func(r *http.Request) (*http.Response, error) {
client: newMockClient(func(r *http.Request) (*http.Response, error) {
if !strings.HasPrefix(r.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, r.URL)
}

View File

@ -16,7 +16,7 @@ import (
func TestImageInspectError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, _, err := client.ImageInspectWithRaw(context.Background(), "nothing")
@ -27,7 +27,7 @@ func TestImageInspectError(t *testing.T) {
func TestImageInspectImageNotFound(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusNotFound, "Server error")),
client: newMockClient(errorMock(http.StatusNotFound, "Server error")),
}
_, _, err := client.ImageInspectWithRaw(context.Background(), "unknown")
@ -40,7 +40,7 @@ func TestImageInspect(t *testing.T) {
expectedURL := "/images/image_id/json"
expectedTags := []string{"tag1", "tag2"}
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -16,7 +16,7 @@ import (
func TestImageListError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ImageList(context.Background(), types.ImageListOptions{})
@ -82,7 +82,7 @@ func TestImageList(t *testing.T) {
}
for _, listCase := range listCases {
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -13,7 +13,7 @@ import (
func TestImageLoadError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ImageLoad(context.Background(), nil, true)
@ -51,7 +51,7 @@ func TestImageLoad(t *testing.T) {
}
for _, loadCase := range loadCases {
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -15,7 +15,7 @@ import (
func TestImagePullReferenceParseError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
return nil, nil
}),
}
@ -28,7 +28,7 @@ func TestImagePullReferenceParseError(t *testing.T) {
func TestImagePullAnyError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ImagePull(context.Background(), "myimage", types.ImagePullOptions{})
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -38,7 +38,7 @@ func TestImagePullAnyError(t *testing.T) {
func TestImagePullStatusUnauthorizedError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusUnauthorized, "Unauthorized error")),
client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")),
}
_, err := client.ImagePull(context.Background(), "myimage", types.ImagePullOptions{})
if err == nil || err.Error() != "Error response from daemon: Unauthorized error" {
@ -48,7 +48,7 @@ func TestImagePullStatusUnauthorizedError(t *testing.T) {
func TestImagePullWithUnauthorizedErrorAndPrivilegeFuncError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusUnauthorized, "Unauthorized error")),
client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")),
}
privilegeFunc := func() (string, error) {
return "", fmt.Errorf("Error requesting privilege")
@ -63,7 +63,7 @@ func TestImagePullWithUnauthorizedErrorAndPrivilegeFuncError(t *testing.T) {
func TestImagePullWithUnauthorizedErrorAndAnotherUnauthorizedError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusUnauthorized, "Unauthorized error")),
client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")),
}
privilegeFunc := func() (string, error) {
return "a-auth-header", nil
@ -79,7 +79,7 @@ func TestImagePullWithUnauthorizedErrorAndAnotherUnauthorizedError(t *testing.T)
func TestImagePullWithPrivilegedFuncNoError(t *testing.T) {
expectedURL := "/images/create"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}
@ -163,7 +163,7 @@ func TestImagePullWithoutErrors(t *testing.T) {
}
for _, pullCase := range pullCases {
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -15,7 +15,7 @@ import (
func TestImagePushReferenceError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
return nil, nil
}),
}
@ -33,7 +33,7 @@ func TestImagePushReferenceError(t *testing.T) {
func TestImagePushAnyError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ImagePush(context.Background(), "myimage", types.ImagePushOptions{})
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -43,7 +43,7 @@ func TestImagePushAnyError(t *testing.T) {
func TestImagePushStatusUnauthorizedError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusUnauthorized, "Unauthorized error")),
client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")),
}
_, err := client.ImagePush(context.Background(), "myimage", types.ImagePushOptions{})
if err == nil || err.Error() != "Error response from daemon: Unauthorized error" {
@ -53,7 +53,7 @@ func TestImagePushStatusUnauthorizedError(t *testing.T) {
func TestImagePushWithUnauthorizedErrorAndPrivilegeFuncError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusUnauthorized, "Unauthorized error")),
client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")),
}
privilegeFunc := func() (string, error) {
return "", fmt.Errorf("Error requesting privilege")
@ -68,7 +68,7 @@ func TestImagePushWithUnauthorizedErrorAndPrivilegeFuncError(t *testing.T) {
func TestImagePushWithUnauthorizedErrorAndAnotherUnauthorizedError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusUnauthorized, "Unauthorized error")),
client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")),
}
privilegeFunc := func() (string, error) {
return "a-auth-header", nil
@ -84,7 +84,7 @@ func TestImagePushWithUnauthorizedErrorAndAnotherUnauthorizedError(t *testing.T)
func TestImagePushWithPrivilegedFuncNoError(t *testing.T) {
expectedURL := "/images/myimage/push"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}
@ -149,7 +149,7 @@ func TestImagePushWithoutErrors(t *testing.T) {
}
for _, pullCase := range pullCases {
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
expectedURL := fmt.Sprintf(expectedURLFormat, pullCase.expectedImage)
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)

View File

@ -15,7 +15,7 @@ import (
func TestImageRemoveError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ImageRemove(context.Background(), "image_id", types.ImageRemoveOptions{})
@ -49,7 +49,7 @@ func TestImageRemove(t *testing.T) {
}
for _, removeCase := range removeCases {
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -15,7 +15,7 @@ import (
func TestImageSaveError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ImageSave(context.Background(), []string{"nothing"})
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -26,7 +26,7 @@ func TestImageSaveError(t *testing.T) {
func TestImageSave(t *testing.T) {
expectedURL := "/images/get"
client := &Client{
transport: newMockClient(nil, func(r *http.Request) (*http.Response, error) {
client: newMockClient(func(r *http.Request) (*http.Response, error) {
if !strings.HasPrefix(r.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, r.URL)
}

View File

@ -18,7 +18,7 @@ import (
func TestImageSearchAnyError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ImageSearch(context.Background(), "some-image", types.ImageSearchOptions{})
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -28,7 +28,7 @@ func TestImageSearchAnyError(t *testing.T) {
func TestImageSearchStatusUnauthorizedError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusUnauthorized, "Unauthorized error")),
client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")),
}
_, err := client.ImageSearch(context.Background(), "some-image", types.ImageSearchOptions{})
if err == nil || err.Error() != "Error response from daemon: Unauthorized error" {
@ -38,7 +38,7 @@ func TestImageSearchStatusUnauthorizedError(t *testing.T) {
func TestImageSearchWithUnauthorizedErrorAndPrivilegeFuncError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusUnauthorized, "Unauthorized error")),
client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")),
}
privilegeFunc := func() (string, error) {
return "", fmt.Errorf("Error requesting privilege")
@ -53,7 +53,7 @@ func TestImageSearchWithUnauthorizedErrorAndPrivilegeFuncError(t *testing.T) {
func TestImageSearchWithUnauthorizedErrorAndAnotherUnauthorizedError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusUnauthorized, "Unauthorized error")),
client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")),
}
privilegeFunc := func() (string, error) {
return "a-auth-header", nil
@ -69,7 +69,7 @@ func TestImageSearchWithUnauthorizedErrorAndAnotherUnauthorizedError(t *testing.
func TestImageSearchWithPrivilegedFuncNoError(t *testing.T) {
expectedURL := "/images/search"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}
@ -126,7 +126,7 @@ func TestImageSearchWithoutErrors(t *testing.T) {
expectedFilters := `{"is-automated":{"true":true},"stars":{"3":true}}`
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -13,7 +13,7 @@ import (
func TestImageTagError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.ImageTag(context.Background(), "image_id", "repo:tag")
@ -26,7 +26,7 @@ func TestImageTagError(t *testing.T) {
// of distribution/reference package.
func TestImageTagInvalidReference(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.ImageTag(context.Background(), "image_id", "aa/asdf$$^/aa")
@ -93,7 +93,7 @@ func TestImageTag(t *testing.T) {
}
for _, tagCase := range tagCases {
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -15,7 +15,7 @@ import (
func TestInfoServerError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.Info(context.Background())
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -25,7 +25,7 @@ func TestInfoServerError(t *testing.T) {
func TestInfoInvalidResponseJSONError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: http.StatusOK,
Body: ioutil.NopCloser(bytes.NewReader([]byte("invalid json"))),
@ -41,7 +41,7 @@ func TestInfoInvalidResponseJSONError(t *testing.T) {
func TestInfo(t *testing.T) {
expectedURL := "/info"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -17,7 +17,7 @@ import (
func TestNetworkConnectError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.NetworkConnect(context.Background(), "network_id", "container_id", nil)
@ -30,7 +30,7 @@ func TestNetworkConnectEmptyNilEndpointSettings(t *testing.T) {
expectedURL := "/networks/network_id/connect"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}
@ -69,7 +69,7 @@ func TestNetworkConnect(t *testing.T) {
expectedURL := "/networks/network_id/connect"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -15,7 +15,7 @@ import (
func TestNetworkCreateError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.NetworkCreate(context.Background(), "mynetwork", types.NetworkCreate{})
@ -28,7 +28,7 @@ func TestNetworkCreate(t *testing.T) {
expectedURL := "/networks/create"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -15,7 +15,7 @@ import (
func TestNetworkDisconnectError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.NetworkDisconnect(context.Background(), "network_id", "container_id", false)
@ -28,7 +28,7 @@ func TestNetworkDisconnect(t *testing.T) {
expectedURL := "/networks/network_id/disconnect"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -15,7 +15,7 @@ import (
func TestNetworkInspectError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.NetworkInspect(context.Background(), "nothing")
@ -26,7 +26,7 @@ func TestNetworkInspectError(t *testing.T) {
func TestNetworkInspectContainerNotFound(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusNotFound, "Server error")),
client: newMockClient(errorMock(http.StatusNotFound, "Server error")),
}
_, err := client.NetworkInspect(context.Background(), "unknown")
@ -38,7 +38,7 @@ func TestNetworkInspectContainerNotFound(t *testing.T) {
func TestNetworkInspect(t *testing.T) {
expectedURL := "/networks/network_id"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -16,7 +16,7 @@ import (
func TestNetworkListError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.NetworkList(context.Background(), types.NetworkListOptions{
@ -69,7 +69,7 @@ func TestNetworkList(t *testing.T) {
for _, listCase := range listCases {
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -13,7 +13,7 @@ import (
func TestNetworkRemoveError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.NetworkRemove(context.Background(), "network_id")
@ -26,7 +26,7 @@ func TestNetworkRemove(t *testing.T) {
expectedURL := "/networks/network_id"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -15,7 +15,7 @@ import (
func TestNodeInspectError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, _, err := client.NodeInspectWithRaw(context.Background(), "nothing")
@ -26,7 +26,7 @@ func TestNodeInspectError(t *testing.T) {
func TestNodeInspectNodeNotFound(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusNotFound, "Server error")),
client: newMockClient(errorMock(http.StatusNotFound, "Server error")),
}
_, _, err := client.NodeInspectWithRaw(context.Background(), "unknown")
@ -38,7 +38,7 @@ func TestNodeInspectNodeNotFound(t *testing.T) {
func TestNodeInspect(t *testing.T) {
expectedURL := "/nodes/node_id"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -17,7 +17,7 @@ import (
func TestNodeListError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.NodeList(context.Background(), types.NodeListOptions{})
@ -54,7 +54,7 @@ func TestNodeList(t *testing.T) {
}
for _, listCase := range listCases {
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -15,7 +15,7 @@ import (
func TestNodeRemoveError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.NodeRemove(context.Background(), "node_id", types.NodeRemoveOptions{Force: false})
@ -42,7 +42,7 @@ func TestNodeRemove(t *testing.T) {
for _, removeCase := range removeCases {
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -15,7 +15,7 @@ import (
func TestNodeUpdateError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.NodeUpdate(context.Background(), "node_id", swarm.Version{}, swarm.NodeSpec{})
@ -28,7 +28,7 @@ func TestNodeUpdate(t *testing.T) {
expectedURL := "/nodes/node_id/update"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -15,7 +15,7 @@ import (
func TestPluginDisableError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.PluginDisable(context.Background(), "plugin_name")
@ -28,7 +28,7 @@ func TestPluginDisable(t *testing.T) {
expectedURL := "/plugins/plugin_name/disable"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -15,7 +15,7 @@ import (
func TestPluginEnableError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.PluginEnable(context.Background(), "plugin_name")
@ -28,7 +28,7 @@ func TestPluginEnable(t *testing.T) {
expectedURL := "/plugins/plugin_name/enable"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -17,7 +17,7 @@ import (
func TestPluginInspectError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, _, err := client.PluginInspectWithRaw(context.Background(), "nothing")
@ -29,7 +29,7 @@ func TestPluginInspectError(t *testing.T) {
func TestPluginInspect(t *testing.T) {
expectedURL := "/plugins/plugin_name"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -17,7 +17,7 @@ import (
func TestPluginListError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.PluginList(context.Background())
@ -29,7 +29,7 @@ func TestPluginListError(t *testing.T) {
func TestPluginList(t *testing.T) {
expectedURL := "/plugins"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -15,7 +15,7 @@ import (
func TestPluginPushError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.PluginPush(context.Background(), "plugin_name", "")
@ -28,7 +28,7 @@ func TestPluginPush(t *testing.T) {
expectedURL := "/plugins/plugin_name"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -17,7 +17,7 @@ import (
func TestPluginRemoveError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.PluginRemove(context.Background(), "plugin_name", types.PluginRemoveOptions{})
@ -30,7 +30,7 @@ func TestPluginRemove(t *testing.T) {
expectedURL := "/plugins/plugin_name"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -15,7 +15,7 @@ import (
func TestPluginSetError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.PluginSet(context.Background(), "plugin_name", []string{})
@ -28,7 +28,7 @@ func TestPluginSet(t *testing.T) {
expectedURL := "/plugins/plugin_name/set"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -13,9 +13,9 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/versions"
"github.com/docker/docker/client/transport/cancellable"
"github.com/pkg/errors"
"golang.org/x/net/context"
"golang.org/x/net/context/ctxhttp"
)
// serverResponse is a wrapper for http API responses.
@ -98,20 +98,27 @@ func (cli *Client) sendClientRequest(ctx context.Context, method, path string, q
// need a valid and meaningful host name. (See #189)
req.Host = "docker"
}
scheme, err := resolveScheme(cli.client.Transport)
if err != nil {
return serverResp, err
}
req.URL.Host = cli.addr
req.URL.Scheme = cli.transport.Scheme()
req.URL.Scheme = scheme
if expectedPayload && req.Header.Get("Content-Type") == "" {
req.Header.Set("Content-Type", "text/plain")
}
resp, err := cancellable.Do(ctx, cli.transport, req)
resp, err := ctxhttp.Do(ctx, cli.client, req)
if err != nil {
if !cli.transport.Secure() && strings.Contains(err.Error(), "malformed HTTP response") {
if scheme == "https" && strings.Contains(err.Error(), "malformed HTTP response") {
return serverResp, fmt.Errorf("%v.\n* Are you trying to connect to a TLS-enabled daemon without TLS?", err)
}
if cli.transport.Secure() && strings.Contains(err.Error(), "bad certificate") {
if scheme == "https" && strings.Contains(err.Error(), "bad certificate") {
return serverResp, fmt.Errorf("The server probably has client authentication (--tlsverify) enabled. Please check your TLS client certification settings: %v", err)
}

View File

@ -50,7 +50,7 @@ func TestSetHostHeader(t *testing.T) {
}
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, testURL) {
return nil, fmt.Errorf("Test Case #%d: Expected URL %q, got %q", c, testURL, req.URL)
}
@ -65,6 +65,7 @@ func TestSetHostHeader(t *testing.T) {
Body: ioutil.NopCloser(bytes.NewReader(([]byte("")))),
}, nil
}),
proto: proto,
addr: addr,
basePath: basePath,
@ -82,7 +83,7 @@ func TestSetHostHeader(t *testing.T) {
// errors returned as JSON
func TestPlainTextError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, plainTextErrorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(plainTextErrorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ContainerList(context.Background(), types.ContainerListOptions{})
if err == nil || err.Error() != "Error response from daemon: Server error" {

View File

@ -16,7 +16,7 @@ import (
func TestServiceCreateError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ServiceCreate(context.Background(), swarm.ServiceSpec{}, types.ServiceCreateOptions{})
if err == nil || err.Error() != "Error response from daemon: Server error" {
@ -27,7 +27,7 @@ func TestServiceCreateError(t *testing.T) {
func TestServiceCreate(t *testing.T) {
expectedURL := "/services/create"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -15,7 +15,7 @@ import (
func TestServiceInspectError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, _, err := client.ServiceInspectWithRaw(context.Background(), "nothing")
@ -26,7 +26,7 @@ func TestServiceInspectError(t *testing.T) {
func TestServiceInspectServiceNotFound(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusNotFound, "Server error")),
client: newMockClient(errorMock(http.StatusNotFound, "Server error")),
}
_, _, err := client.ServiceInspectWithRaw(context.Background(), "unknown")
@ -38,7 +38,7 @@ func TestServiceInspectServiceNotFound(t *testing.T) {
func TestServiceInspect(t *testing.T) {
expectedURL := "/services/service_id"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -17,7 +17,7 @@ import (
func TestServiceListError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.ServiceList(context.Background(), types.ServiceListOptions{})
@ -54,7 +54,7 @@ func TestServiceList(t *testing.T) {
}
for _, listCase := range listCases {
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -13,7 +13,7 @@ import (
func TestServiceRemoveError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.ServiceRemove(context.Background(), "service_id")
@ -26,7 +26,7 @@ func TestServiceRemove(t *testing.T) {
expectedURL := "/services/service_id"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -16,7 +16,7 @@ import (
func TestServiceUpdateError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.ServiceUpdate(context.Background(), "service_id", swarm.Version{}, swarm.ServiceSpec{}, types.ServiceUpdateOptions{})
@ -51,7 +51,7 @@ func TestServiceUpdate(t *testing.T) {
for _, updateCase := range updateCases {
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -15,7 +15,7 @@ import (
func TestSwarmInitError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.SwarmInit(context.Background(), swarm.InitRequest{})
@ -28,7 +28,7 @@ func TestSwarmInit(t *testing.T) {
expectedURL := "/swarm/init"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -15,7 +15,7 @@ import (
func TestSwarmInspectError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.SwarmInspect(context.Background())
@ -27,7 +27,7 @@ func TestSwarmInspectError(t *testing.T) {
func TestSwarmInspect(t *testing.T) {
expectedURL := "/swarm"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -15,7 +15,7 @@ import (
func TestSwarmJoinError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.SwarmJoin(context.Background(), swarm.JoinRequest{})
@ -28,7 +28,7 @@ func TestSwarmJoin(t *testing.T) {
expectedURL := "/swarm/join"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -13,7 +13,7 @@ import (
func TestSwarmLeaveError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.SwarmLeave(context.Background(), false)
@ -40,7 +40,7 @@ func TestSwarmLeave(t *testing.T) {
for _, leaveCase := range leaveCases {
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -15,7 +15,7 @@ import (
func TestSwarmUpdateError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.SwarmUpdate(context.Background(), swarm.Version{}, swarm.Spec{}, swarm.UpdateFlags{})
@ -28,7 +28,7 @@ func TestSwarmUpdate(t *testing.T) {
expectedURL := "/swarm/update"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -15,7 +15,7 @@ import (
func TestTaskInspectError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, _, err := client.TaskInspectWithRaw(context.Background(), "nothing")
@ -27,7 +27,7 @@ func TestTaskInspectError(t *testing.T) {
func TestTaskInspect(t *testing.T) {
expectedURL := "/tasks/task_id"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -17,7 +17,7 @@ import (
func TestTaskListError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.TaskList(context.Background(), types.TaskListOptions{})
@ -54,7 +54,7 @@ func TestTaskList(t *testing.T) {
}
for _, listCase := range listCases {
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

51
client/transport.go Normal file
View File

@ -0,0 +1,51 @@
package client
import (
"crypto/tls"
"errors"
"net/http"
)
var errTLSConfigUnavailable = errors.New("TLSConfig unavailable")
// transportFunc allows us to inject a mock transport for testing. We define it
// here so we can detect the tlsconfig and return nil for only this type.
type transportFunc func(*http.Request) (*http.Response, error)
func (tf transportFunc) RoundTrip(req *http.Request) (*http.Response, error) {
return tf(req)
}
// resolveTLSConfig attempts to resolve the tls configuration from the
// RoundTripper.
func resolveTLSConfig(transport http.RoundTripper) (*tls.Config, error) {
switch tr := transport.(type) {
case *http.Transport:
return tr.TLSClientConfig, nil
case transportFunc:
return nil, nil // detect this type for testing.
default:
return nil, errTLSConfigUnavailable
}
}
// resolveScheme detects a tls config on the transport and returns the
// appropriate http scheme.
//
// TODO(stevvooe): This isn't really the right way to write clients in Go.
// `NewClient` should probably only take an `*http.Client` and work from there.
// Unfortunately, the model of having a host-ish/url-thingy as the connection
// string has us confusing protocol and transport layers. We continue doing
// this to avoid breaking existing clients but this should be addressed.
func resolveScheme(transport http.RoundTripper) (string, error) {
c, err := resolveTLSConfig(transport)
if err != nil {
return "", err
}
if c != nil {
return "https", nil
}
return "http", nil
}

View File

@ -1,27 +0,0 @@
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,23 +0,0 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build go1.5
package cancellable
import (
"net/http"
"github.com/docker/docker/client/transport"
)
func canceler(client transport.Sender, req *http.Request) func() {
// TODO(djd): Respect any existing value of req.Cancel.
ch := make(chan struct{})
req.Cancel = ch
return func() {
close(ch)
}
}

View File

@ -1,27 +0,0 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !go1.5
package cancellable
import (
"net/http"
"github.com/docker/docker/client/transport"
)
type requestCanceler interface {
CancelRequest(*http.Request)
}
func canceler(client transport.Sender, req *http.Request) func() {
rc, ok := client.(requestCanceler)
if !ok {
return func() {}
}
return func() {
rc.CancelRequest(req)
}
}

View File

@ -1,115 +0,0 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package cancellable provides helper function to cancel http requests.
package cancellable
import (
"io"
"net/http"
"sync"
"github.com/docker/docker/client/transport"
"golang.org/x/net/context"
)
func nop() {}
var (
testHookContextDoneBeforeHeaders = nop
testHookDoReturned = nop
testHookDidBodyClose = nop
)
// Do sends an HTTP request with the provided transport.Sender and returns an HTTP response.
// If the client is nil, http.DefaultClient is used.
// If the context is canceled or times out, ctx.Err() will be returned.
//
// FORK INFORMATION:
//
// This function deviates from the upstream version in golang.org/x/net/context/ctxhttp by
// taking a Sender interface rather than a *http.Client directly. That allow us to use
// this function with mocked clients and hijacked connections.
func Do(ctx context.Context, client transport.Sender, req *http.Request) (*http.Response, error) {
if client == nil {
client = http.DefaultClient
}
// Request cancelation changed in Go 1.5, see canceler.go and canceler_go14.go.
cancel := canceler(client, req)
type responseAndError struct {
resp *http.Response
err error
}
result := make(chan responseAndError, 1)
go func() {
resp, err := client.Do(req)
testHookDoReturned()
result <- responseAndError{resp, err}
}()
var resp *http.Response
select {
case <-ctx.Done():
testHookContextDoneBeforeHeaders()
cancel()
// Clean up after the goroutine calling client.Do:
go func() {
if r := <-result; r.resp != nil && r.resp.Body != nil {
testHookDidBodyClose()
r.resp.Body.Close()
}
}()
return nil, ctx.Err()
case r := <-result:
var err error
resp, err = r.resp, r.err
if err != nil {
return resp, err
}
}
c := make(chan struct{})
go func() {
select {
case <-ctx.Done():
cancel()
case <-c:
// The response's Body is closed.
}
}()
resp.Body = &notifyingReader{ReadCloser: resp.Body, notify: c}
return resp, nil
}
// notifyingReader is an io.ReadCloser that closes the notify channel after
// Close is called or a Read fails on the underlying ReadCloser.
type notifyingReader struct {
io.ReadCloser
notify chan<- struct{}
notifyOnce sync.Once
}
func (r *notifyingReader) Read(p []byte) (int, error) {
n, err := r.ReadCloser.Read(p)
if err != nil {
r.notifyOnce.Do(func() {
close(r.notify)
})
}
return n, err
}
func (r *notifyingReader) Close() error {
err := r.ReadCloser.Close()
r.notifyOnce.Do(func() {
close(r.notify)
})
return err
}

View File

@ -1,47 +0,0 @@
package transport
import (
"crypto/tls"
"net/http"
)
// Sender is an interface that clients must implement
// to be able to send requests to a remote connection.
type Sender interface {
// Do sends request to a remote endpoint.
Do(*http.Request) (*http.Response, error)
}
// Client is an interface that abstracts all remote connections.
type Client interface {
Sender
// Secure tells whether the connection is secure or not.
Secure() bool
// Scheme returns the connection protocol the client uses.
Scheme() string
// TLSConfig returns any TLS configuration the client uses.
TLSConfig() *tls.Config
}
// tlsInfo returns information about the TLS configuration.
type tlsInfo struct {
tlsConfig *tls.Config
}
// TLSConfig returns the TLS configuration.
func (t *tlsInfo) TLSConfig() *tls.Config {
return t.tlsConfig
}
// Scheme returns protocol scheme to use.
func (t *tlsInfo) Scheme() string {
if t.tlsConfig != nil {
return "https"
}
return "http"
}
// Secure returns true if there is a TLS configuration.
func (t *tlsInfo) Secure() bool {
return t.tlsConfig != nil
}

View File

@ -1,57 +0,0 @@
// Package transport provides function to send request to remote endpoints.
package transport
import (
"fmt"
"net/http"
"github.com/docker/go-connections/sockets"
)
// apiTransport holds information about the http transport to connect with the API.
type apiTransport struct {
*http.Client
*tlsInfo
transport *http.Transport
}
// NewTransportWithHTTP creates a new transport based on the provided proto, address and http client.
// It uses Docker's default http transport configuration if the client is nil.
// It does not modify the client's transport if it's not nil.
func NewTransportWithHTTP(proto, addr string, client *http.Client) (Client, error) {
var transport *http.Transport
if client != nil {
tr, ok := client.Transport.(*http.Transport)
if !ok {
return nil, fmt.Errorf("unable to verify TLS configuration, invalid transport %v", client.Transport)
}
transport = tr
} else {
transport = defaultTransport(proto, addr)
client = &http.Client{
Transport: transport,
}
}
return &apiTransport{
Client: client,
tlsInfo: &tlsInfo{transport.TLSClientConfig},
transport: transport,
}, nil
}
// CancelRequest stops a request execution.
func (a *apiTransport) CancelRequest(req *http.Request) {
a.transport.CancelRequest(req)
}
// defaultTransport creates a new http.Transport with Docker's
// default transport configuration.
func defaultTransport(proto, addr string) *http.Transport {
tr := new(http.Transport)
sockets.ConfigureTransport(tr, proto, addr)
return tr
}
var _ Client = &apiTransport{}

View File

@ -15,7 +15,7 @@ import (
func TestVolumeCreateError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.VolumeCreate(context.Background(), types.VolumeCreateRequest{})
@ -28,7 +28,7 @@ func TestVolumeCreate(t *testing.T) {
expectedURL := "/volumes/create"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -15,7 +15,7 @@ import (
func TestVolumeInspectError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.VolumeInspect(context.Background(), "nothing")
@ -26,7 +26,7 @@ func TestVolumeInspectError(t *testing.T) {
func TestVolumeInspectNotFound(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusNotFound, "Server error")),
client: newMockClient(errorMock(http.StatusNotFound, "Server error")),
}
_, err := client.VolumeInspect(context.Background(), "unknown")
@ -38,7 +38,7 @@ func TestVolumeInspectNotFound(t *testing.T) {
func TestVolumeInspect(t *testing.T) {
expectedURL := "/volumes/volume_id"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -16,7 +16,7 @@ import (
func TestVolumeListError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
_, err := client.VolumeList(context.Background(), filters.NewArgs())
@ -59,7 +59,7 @@ func TestVolumeList(t *testing.T) {
for _, listCase := range listCases {
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}

View File

@ -13,7 +13,7 @@ import (
func TestVolumeRemoveError(t *testing.T) {
client := &Client{
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
}
err := client.VolumeRemove(context.Background(), "volume_id", false)
@ -26,7 +26,7 @@ func TestVolumeRemove(t *testing.T) {
expectedURL := "/volumes/volume_id"
client := &Client{
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
client: newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
}