Browse Source

Merge pull request #33534 from sbko/31410-replace-deprecated-sockrequest

Stop using deprecated SockRequest
Daniel Nephin 7 years ago
parent
commit
eb52bb22a4
32 changed files with 1027 additions and 834 deletions
  1. 12 0
      integration-cli/daemon/daemon.go
  2. 214 175
      integration-cli/daemon/daemon_swarm.go
  3. 6 3
      integration-cli/docker_api_attach_test.go
  4. 7 8
      integration-cli/docker_api_auth_test.go
  5. 318 252
      integration-cli/docker_api_containers_test.go
  6. 35 15
      integration-cli/docker_api_create_test.go
  7. 9 6
      integration-cli/docker_api_exec_resize_test.go
  8. 29 16
      integration-cli/docker_api_exec_test.go
  9. 40 37
      integration-cli/docker_api_images_test.go
  10. 16 8
      integration-cli/docker_api_info_test.go
  11. 7 10
      integration-cli/docker_api_inspect_test.go
  12. 7 5
      integration-cli/docker_api_inspect_unix_test.go
  13. 7 4
      integration-cli/docker_api_logs_test.go
  14. 24 11
      integration-cli/docker_api_resize_test.go
  15. 10 6
      integration-cli/docker_api_stats_test.go
  16. 16 9
      integration-cli/docker_api_swarm_config_test.go
  17. 18 12
      integration-cli/docker_api_swarm_secret_test.go
  18. 17 6
      integration-cli/docker_api_swarm_service_test.go
  19. 36 48
      integration-cli/docker_api_swarm_test.go
  20. 14 5
      integration-cli/docker_api_update_unix_test.go
  21. 5 11
      integration-cli/docker_api_version_test.go
  22. 28 35
      integration-cli/docker_api_volumes_test.go
  23. 13 5
      integration-cli/docker_cli_events_test.go
  24. 11 6
      integration-cli/docker_cli_exec_test.go
  25. 7 5
      integration-cli/docker_cli_kill_test.go
  26. 7 8
      integration-cli/docker_cli_plugins_logdriver_test.go
  27. 16 23
      integration-cli/docker_cli_swarm_test.go
  28. 26 20
      integration-cli/docker_cli_volume_test.go
  29. 26 17
      integration-cli/docker_deprecated_api_v124_test.go
  30. 1 1
      integration-cli/docker_deprecated_api_v124_unix_test.go
  31. 17 21
      integration-cli/docker_utils_test.go
  32. 28 46
      integration-cli/environment/clean.go

+ 12 - 0
integration-cli/daemon/daemon.go

@@ -14,8 +14,10 @@ import (
 	"strings"
 	"time"
 
+	"github.com/docker/docker/api"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/events"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/request"
 	"github.com/docker/docker/opts"
@@ -752,6 +754,16 @@ func (d *Daemon) ReloadConfig() error {
 	return nil
 }
 
+// NewClient creates new client based on daemon's socket path
+func (d *Daemon) NewClient() (*client.Client, error) {
+	httpClient, err := request.NewHTTPClient(d.Sock())
+	if err != nil {
+		return nil, err
+	}
+
+	return client.NewClient(d.Sock(), api.DefaultVersion, httpClient, nil)
+}
+
 // WaitInspectWithArgs waits for the specified expression to be equals to the specified expected string in the given time.
 // Deprecated: use cli.WaitCmd instead
 func WaitInspectWithArgs(dockerBinary, name, expr, expected string, timeout time.Duration, arg ...string) error {

+ 214 - 175
integration-cli/daemon/daemon_swarm.go

@@ -1,7 +1,6 @@
 package daemon
 
 import (
-	"context"
 	"encoding/json"
 	"fmt"
 	"net/http"
@@ -11,10 +10,10 @@ import (
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/filters"
 	"github.com/docker/docker/api/types/swarm"
-	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/go-check/check"
 	"github.com/pkg/errors"
+	"golang.org/x/net/context"
 )
 
 // Swarm is a test daemon with helpers for participating in a swarm.
@@ -30,10 +29,12 @@ func (d *Swarm) Init(req swarm.InitRequest) error {
 	if req.ListenAddr == "" {
 		req.ListenAddr = d.ListenAddr
 	}
-	status, out, err := d.SockRequest("POST", "/swarm/init", req)
-	if status != http.StatusOK {
-		return fmt.Errorf("initializing swarm: invalid statuscode %v, %q", status, out)
+	cli, err := d.NewClient()
+	if err != nil {
+		return fmt.Errorf("initializing swarm: failed to create client %v", err)
 	}
+	defer cli.Close()
+	_, err = cli.SwarmInit(context.Background(), req)
 	if err != nil {
 		return fmt.Errorf("initializing swarm: %v", err)
 	}
@@ -50,10 +51,12 @@ func (d *Swarm) Join(req swarm.JoinRequest) error {
 	if req.ListenAddr == "" {
 		req.ListenAddr = d.ListenAddr
 	}
-	status, out, err := d.SockRequest("POST", "/swarm/join", req)
-	if status != http.StatusOK {
-		return fmt.Errorf("joining swarm: invalid statuscode %v, %q", status, out)
+	cli, err := d.NewClient()
+	if err != nil {
+		return fmt.Errorf("joining swarm: failed to create client %v", err)
 	}
+	defer cli.Close()
+	err = cli.SwarmJoin(context.Background(), req)
 	if err != nil {
 		return fmt.Errorf("joining swarm: %v", err)
 	}
@@ -67,14 +70,12 @@ func (d *Swarm) Join(req swarm.JoinRequest) error {
 
 // Leave forces daemon to leave current cluster.
 func (d *Swarm) Leave(force bool) error {
-	url := "/swarm/leave"
-	if force {
-		url += "?force=1"
-	}
-	status, out, err := d.SockRequest("POST", url, nil)
-	if status != http.StatusOK {
-		return fmt.Errorf("leaving swarm: invalid statuscode %v, %q", status, out)
+	cli, err := d.NewClient()
+	if err != nil {
+		return fmt.Errorf("leaving swarm: failed to create client %v", err)
 	}
+	defer cli.Close()
+	err = cli.SwarmLeave(context.Background(), force)
 	if err != nil {
 		err = fmt.Errorf("leaving swarm: %v", err)
 	}
@@ -83,28 +84,27 @@ func (d *Swarm) Leave(force bool) error {
 
 // SwarmInfo returns the swarm information of the daemon
 func (d *Swarm) SwarmInfo() (swarm.Info, error) {
-	var info struct {
-		Swarm swarm.Info
-	}
-	status, dt, err := d.SockRequest("GET", "/info", nil)
-	if status != http.StatusOK {
-		return info.Swarm, fmt.Errorf("get swarm info: invalid statuscode %v", status)
-	}
+	cli, err := d.NewClient()
 	if err != nil {
-		return info.Swarm, fmt.Errorf("get swarm info: %v", err)
+		return swarm.Info{}, fmt.Errorf("get swarm info: %v", err)
 	}
-	if err := json.Unmarshal(dt, &info); err != nil {
-		return info.Swarm, err
+
+	info, err := cli.Info(context.Background())
+	if err != nil {
+		return swarm.Info{}, fmt.Errorf("get swarm info: %v", err)
 	}
+
 	return info.Swarm, nil
 }
 
 // Unlock tries to unlock a locked swarm
 func (d *Swarm) Unlock(req swarm.UnlockRequest) error {
-	status, out, err := d.SockRequest("POST", "/swarm/unlock", req)
-	if status != http.StatusOK {
-		return fmt.Errorf("unlocking swarm: invalid statuscode %v, %q", status, out)
+	cli, err := d.NewClient()
+	if err != nil {
+		return fmt.Errorf("unlocking swarm: failed to create client %v", err)
 	}
+	defer cli.Close()
+	err = cli.SwarmUnlock(context.Background(), req)
 	if err != nil {
 		err = errors.Wrap(err, "unlocking swarm")
 	}
@@ -129,19 +129,19 @@ type SpecConstructor func(*swarm.Spec)
 // CreateServiceWithOptions creates a swarm service given the specified service constructors
 // and auth config
 func (d *Swarm) CreateServiceWithOptions(c *check.C, opts types.ServiceCreateOptions, f ...ServiceConstructor) string {
-	cl, err := client.NewClient(d.Sock(), "", nil, nil)
-	c.Assert(err, checker.IsNil, check.Commentf("failed to create client"))
-	defer cl.Close()
-
 	var service swarm.Service
 	for _, fn := range f {
 		fn(&service)
 	}
 
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
 	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
 	defer cancel()
 
-	res, err := cl.ServiceCreate(ctx, service.Spec, opts)
+	res, err := cli.ServiceCreate(ctx, service.Spec, opts)
 	c.Assert(err, checker.IsNil)
 	return res.ID
 }
@@ -153,28 +153,31 @@ func (d *Swarm) CreateService(c *check.C, f ...ServiceConstructor) string {
 
 // GetService returns the swarm service corresponding to the specified id
 func (d *Swarm) GetService(c *check.C, id string) *swarm.Service {
-	var service swarm.Service
-	status, out, err := d.SockRequest("GET", "/services/"+id, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
-	c.Assert(json.Unmarshal(out, &service), checker.IsNil)
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	service, _, err := cli.ServiceInspectWithRaw(context.Background(), id, types.ServiceInspectOptions{})
+	c.Assert(err, checker.IsNil)
 	return &service
 }
 
 // GetServiceTasks returns the swarm tasks for the specified service
 func (d *Swarm) GetServiceTasks(c *check.C, service string) []swarm.Task {
-	var tasks []swarm.Task
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
 	filterArgs := filters.NewArgs()
 	filterArgs.Add("desired-state", "running")
 	filterArgs.Add("service", service)
-	filters, err := filters.ToParam(filterArgs)
-	c.Assert(err, checker.IsNil)
 
-	status, out, err := d.SockRequest("GET", "/tasks?filters="+filters, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
-	c.Assert(json.Unmarshal(out, &tasks), checker.IsNil)
+	options := types.TaskListOptions{
+		Filters: filterArgs,
+	}
+
+	tasks, err := cli.TaskList(context.Background(), options)
+	c.Assert(err, checker.IsNil)
 	return tasks
 }
 
@@ -252,17 +255,19 @@ func (d *Swarm) CheckServiceTasks(service string) func(*check.C) (interface{}, c
 
 // CheckRunningTaskNetworks returns the number of times each network is referenced from a task.
 func (d *Swarm) CheckRunningTaskNetworks(c *check.C) (interface{}, check.CommentInterface) {
-	var tasks []swarm.Task
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
 	filterArgs := filters.NewArgs()
 	filterArgs.Add("desired-state", "running")
-	filters, err := filters.ToParam(filterArgs)
-	c.Assert(err, checker.IsNil)
 
-	status, out, err := d.SockRequest("GET", "/tasks?filters="+filters, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
-	c.Assert(json.Unmarshal(out, &tasks), checker.IsNil)
+	options := types.TaskListOptions{
+		Filters: filterArgs,
+	}
+
+	tasks, err := cli.TaskList(context.Background(), options)
+	c.Assert(err, checker.IsNil)
 
 	result := make(map[string]int)
 	for _, task := range tasks {
@@ -275,17 +280,19 @@ func (d *Swarm) CheckRunningTaskNetworks(c *check.C) (interface{}, check.Comment
 
 // CheckRunningTaskImages returns the times each image is running as a task.
 func (d *Swarm) CheckRunningTaskImages(c *check.C) (interface{}, check.CommentInterface) {
-	var tasks []swarm.Task
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
 	filterArgs := filters.NewArgs()
 	filterArgs.Add("desired-state", "running")
-	filters, err := filters.ToParam(filterArgs)
-	c.Assert(err, checker.IsNil)
 
-	status, out, err := d.SockRequest("GET", "/tasks?filters="+filters, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
-	c.Assert(json.Unmarshal(out, &tasks), checker.IsNil)
+	options := types.TaskListOptions{
+		Filters: filterArgs,
+	}
+
+	tasks, err := cli.TaskList(context.Background(), options)
+	c.Assert(err, checker.IsNil)
 
 	result := make(map[string]int)
 	for _, task := range tasks {
@@ -310,246 +317,281 @@ func (d *Swarm) CheckNodeReadyCount(c *check.C) (interface{}, check.CommentInter
 
 // GetTask returns the swarm task identified by the specified id
 func (d *Swarm) GetTask(c *check.C, id string) swarm.Task {
-	var task swarm.Task
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	status, out, err := d.SockRequest("GET", "/tasks/"+id, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
-	c.Assert(json.Unmarshal(out, &task), checker.IsNil)
+	task, _, err := cli.TaskInspectWithRaw(context.Background(), id)
+	c.Assert(err, checker.IsNil)
 	return task
 }
 
 // UpdateService updates a swarm service with the specified service constructor
 func (d *Swarm) UpdateService(c *check.C, service *swarm.Service, f ...ServiceConstructor) {
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
 	for _, fn := range f {
 		fn(service)
 	}
-	url := fmt.Sprintf("/services/%s/update?version=%d", service.ID, service.Version.Index)
-	status, out, err := d.SockRequest("POST", url, service.Spec)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
+
+	_, err = cli.ServiceUpdate(context.Background(), service.ID, service.Version, service.Spec, types.ServiceUpdateOptions{})
+	c.Assert(err, checker.IsNil)
 }
 
 // RemoveService removes the specified service
 func (d *Swarm) RemoveService(c *check.C, id string) {
-	status, out, err := d.SockRequest("DELETE", "/services/"+id, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	err = cli.ServiceRemove(context.Background(), id)
+	c.Assert(err, checker.IsNil)
 }
 
 // GetNode returns a swarm node identified by the specified id
 func (d *Swarm) GetNode(c *check.C, id string) *swarm.Node {
-	var node swarm.Node
-	status, out, err := d.SockRequest("GET", "/nodes/"+id, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
-	c.Assert(json.Unmarshal(out, &node), checker.IsNil)
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	node, _, err := cli.NodeInspectWithRaw(context.Background(), id)
+	c.Assert(err, checker.IsNil)
 	c.Assert(node.ID, checker.Equals, id)
 	return &node
 }
 
 // RemoveNode removes the specified node
 func (d *Swarm) RemoveNode(c *check.C, id string, force bool) {
-	url := "/nodes/" + id
-	if force {
-		url += "?force=1"
-	}
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	status, out, err := d.SockRequest("DELETE", url, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
+	options := types.NodeRemoveOptions{
+		Force: force,
+	}
+	err = cli.NodeRemove(context.Background(), id, options)
+	c.Assert(err, checker.IsNil)
 }
 
 // UpdateNode updates a swarm node with the specified node constructor
 func (d *Swarm) UpdateNode(c *check.C, id string, f ...NodeConstructor) {
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
 	for i := 0; ; i++ {
 		node := d.GetNode(c, id)
 		for _, fn := range f {
 			fn(node)
 		}
-		url := fmt.Sprintf("/nodes/%s/update?version=%d", node.ID, node.Version.Index)
-		status, out, err := d.SockRequest("POST", url, node.Spec)
-		if i < 10 && strings.Contains(string(out), "update out of sequence") {
+
+		err = cli.NodeUpdate(context.Background(), node.ID, node.Version, node.Spec)
+		if i < 10 && err != nil && strings.Contains(err.Error(), "update out of sequence") {
 			time.Sleep(100 * time.Millisecond)
 			continue
 		}
-		c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-		c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
+		c.Assert(err, checker.IsNil)
 		return
 	}
 }
 
 // ListNodes returns the list of the current swarm nodes
 func (d *Swarm) ListNodes(c *check.C) []swarm.Node {
-	status, out, err := d.SockRequest("GET", "/nodes", nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	nodes, err := cli.NodeList(context.Background(), types.NodeListOptions{})
+	c.Assert(err, checker.IsNil)
 
-	nodes := []swarm.Node{}
-	c.Assert(json.Unmarshal(out, &nodes), checker.IsNil)
 	return nodes
 }
 
 // ListServices returns the list of the current swarm services
 func (d *Swarm) ListServices(c *check.C) []swarm.Service {
-	status, out, err := d.SockRequest("GET", "/services", nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	services := []swarm.Service{}
-	c.Assert(json.Unmarshal(out, &services), checker.IsNil)
+	services, err := cli.ServiceList(context.Background(), types.ServiceListOptions{})
+	c.Assert(err, checker.IsNil)
 	return services
 }
 
 // CreateSecret creates a secret given the specified spec
 func (d *Swarm) CreateSecret(c *check.C, secretSpec swarm.SecretSpec) string {
-	status, out, err := d.SockRequest("POST", "/secrets/create", secretSpec)
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf("output: %q", string(out)))
+	scr, err := cli.SecretCreate(context.Background(), secretSpec)
+	c.Assert(err, checker.IsNil)
 
-	var scr types.SecretCreateResponse
-	c.Assert(json.Unmarshal(out, &scr), checker.IsNil)
 	return scr.ID
 }
 
 // ListSecrets returns the list of the current swarm secrets
 func (d *Swarm) ListSecrets(c *check.C) []swarm.Secret {
-	status, out, err := d.SockRequest("GET", "/secrets", nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	secrets := []swarm.Secret{}
-	c.Assert(json.Unmarshal(out, &secrets), checker.IsNil)
+	secrets, err := cli.SecretList(context.Background(), types.SecretListOptions{})
+	c.Assert(err, checker.IsNil)
 	return secrets
 }
 
 // GetSecret returns a swarm secret identified by the specified id
 func (d *Swarm) GetSecret(c *check.C, id string) *swarm.Secret {
-	var secret swarm.Secret
-	status, out, err := d.SockRequest("GET", "/secrets/"+id, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
-	c.Assert(json.Unmarshal(out, &secret), checker.IsNil)
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	secret, _, err := cli.SecretInspectWithRaw(context.Background(), id)
+	c.Assert(err, checker.IsNil)
 	return &secret
 }
 
 // DeleteSecret removes the swarm secret identified by the specified id
 func (d *Swarm) DeleteSecret(c *check.C, id string) {
-	status, out, err := d.SockRequest("DELETE", "/secrets/"+id, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusNoContent, check.Commentf("output: %q", string(out)))
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	err = cli.SecretRemove(context.Background(), id)
+	c.Assert(err, checker.IsNil)
 }
 
 // UpdateSecret updates the swarm secret identified by the specified id
 // Currently, only label update is supported.
 func (d *Swarm) UpdateSecret(c *check.C, id string, f ...SecretConstructor) {
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
 	secret := d.GetSecret(c, id)
 	for _, fn := range f {
 		fn(secret)
 	}
-	url := fmt.Sprintf("/secrets/%s/update?version=%d", secret.ID, secret.Version.Index)
-	status, out, err := d.SockRequest("POST", url, secret.Spec)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
+
+	err = cli.SecretUpdate(context.Background(), secret.ID, secret.Version, secret.Spec)
+
+	c.Assert(err, checker.IsNil)
 }
 
 // CreateConfig creates a config given the specified spec
 func (d *Swarm) CreateConfig(c *check.C, configSpec swarm.ConfigSpec) string {
-	status, out, err := d.SockRequest("POST", "/configs/create", configSpec)
-
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf("output: %q", string(out)))
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	var scr types.ConfigCreateResponse
-	c.Assert(json.Unmarshal(out, &scr), checker.IsNil)
+	scr, err := cli.ConfigCreate(context.Background(), configSpec)
+	c.Assert(err, checker.IsNil)
 	return scr.ID
 }
 
 // ListConfigs returns the list of the current swarm configs
 func (d *Swarm) ListConfigs(c *check.C) []swarm.Config {
-	status, out, err := d.SockRequest("GET", "/configs", nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	configs := []swarm.Config{}
-	c.Assert(json.Unmarshal(out, &configs), checker.IsNil)
+	configs, err := cli.ConfigList(context.Background(), types.ConfigListOptions{})
+	c.Assert(err, checker.IsNil)
 	return configs
 }
 
 // GetConfig returns a swarm config identified by the specified id
 func (d *Swarm) GetConfig(c *check.C, id string) *swarm.Config {
-	var config swarm.Config
-	status, out, err := d.SockRequest("GET", "/configs/"+id, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
-	c.Assert(json.Unmarshal(out, &config), checker.IsNil)
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	config, _, err := cli.ConfigInspectWithRaw(context.Background(), id)
+	c.Assert(err, checker.IsNil)
 	return &config
 }
 
 // DeleteConfig removes the swarm config identified by the specified id
 func (d *Swarm) DeleteConfig(c *check.C, id string) {
-	status, out, err := d.SockRequest("DELETE", "/configs/"+id, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusNoContent, check.Commentf("output: %q", string(out)))
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	err = cli.ConfigRemove(context.Background(), id)
+	c.Assert(err, checker.IsNil)
 }
 
 // UpdateConfig updates the swarm config identified by the specified id
 // Currently, only label update is supported.
 func (d *Swarm) UpdateConfig(c *check.C, id string, f ...ConfigConstructor) {
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
 	config := d.GetConfig(c, id)
 	for _, fn := range f {
 		fn(config)
 	}
-	url := fmt.Sprintf("/configs/%s/update?version=%d", config.ID, config.Version.Index)
-	status, out, err := d.SockRequest("POST", url, config.Spec)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
+
+	err = cli.ConfigUpdate(context.Background(), config.ID, config.Version, config.Spec)
+	c.Assert(err, checker.IsNil)
 }
 
 // GetSwarm returns the current swarm object
 func (d *Swarm) GetSwarm(c *check.C) swarm.Swarm {
-	var sw swarm.Swarm
-	status, out, err := d.SockRequest("GET", "/swarm", nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
-	c.Assert(json.Unmarshal(out, &sw), checker.IsNil)
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	sw, err := cli.SwarmInspect(context.Background())
+	c.Assert(err, checker.IsNil)
 	return sw
 }
 
 // UpdateSwarm updates the current swarm object with the specified spec constructors
 func (d *Swarm) UpdateSwarm(c *check.C, f ...SpecConstructor) {
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
 	sw := d.GetSwarm(c)
 	for _, fn := range f {
 		fn(&sw.Spec)
 	}
-	url := fmt.Sprintf("/swarm/update?version=%d", sw.Version.Index)
-	status, out, err := d.SockRequest("POST", url, sw.Spec)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
+
+	err = cli.SwarmUpdate(context.Background(), sw.Version, sw.Spec, swarm.UpdateFlags{})
+	c.Assert(err, checker.IsNil)
 }
 
 // RotateTokens update the swarm to rotate tokens
 func (d *Swarm) RotateTokens(c *check.C) {
-	var sw swarm.Swarm
-	status, out, err := d.SockRequest("GET", "/swarm", nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
-	c.Assert(json.Unmarshal(out, &sw), checker.IsNil)
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	sw, err := cli.SwarmInspect(context.Background())
+	c.Assert(err, checker.IsNil)
 
-	url := fmt.Sprintf("/swarm/update?version=%d&rotateWorkerToken=true&rotateManagerToken=true", sw.Version.Index)
-	status, out, err = d.SockRequest("POST", url, sw.Spec)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
+	flags := swarm.UpdateFlags{
+		RotateManagerToken: true,
+		RotateWorkerToken:  true,
+	}
+
+	err = cli.SwarmUpdate(context.Background(), sw.Version, sw.Spec, flags)
+	c.Assert(err, checker.IsNil)
 }
 
 // JoinTokens returns the current swarm join tokens
 func (d *Swarm) JoinTokens(c *check.C) swarm.JoinTokens {
-	var sw swarm.Swarm
-	status, out, err := d.SockRequest("GET", "/swarm", nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
-	c.Assert(json.Unmarshal(out, &sw), checker.IsNil)
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	sw, err := cli.SwarmInspect(context.Background())
+	c.Assert(err, checker.IsNil)
 	return sw.JoinTokens
 }
 
@@ -570,17 +612,14 @@ func (d *Swarm) CheckControlAvailable(c *check.C) (interface{}, check.CommentInt
 
 // CheckLeader returns whether there is a leader on the swarm or not
 func (d *Swarm) CheckLeader(c *check.C) (interface{}, check.CommentInterface) {
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
 	errList := check.Commentf("could not get node list")
-	status, out, err := d.SockRequest("GET", "/nodes", nil)
-	if err != nil {
-		return err, errList
-	}
-	if status != http.StatusOK {
-		return fmt.Errorf("expected http status OK, got: %d", status), errList
-	}
 
-	var ls []swarm.Node
-	if err := json.Unmarshal(out, &ls); err != nil {
+	ls, err := cli.NodeList(context.Background(), types.NodeListOptions{})
+	if err != nil {
 		return err, errList
 	}
 

+ 6 - 3
integration-cli/docker_api_attach_test.go

@@ -86,11 +86,13 @@ func (s *DockerSuite) TestPostContainersAttachContainerNotFound(c *check.C) {
 }
 
 func (s *DockerSuite) TestGetContainersWsAttachContainerNotFound(c *check.C) {
-	status, body, err := request.SockRequest("GET", "/containers/doesnotexist/attach/ws", nil, daemonHost())
-	c.Assert(status, checker.Equals, http.StatusNotFound)
+	res, body, err := request.Get("/containers/doesnotexist/attach/ws")
+	c.Assert(res.StatusCode, checker.Equals, http.StatusNotFound)
+	c.Assert(err, checker.IsNil)
+	b, err := request.ReadBody(body)
 	c.Assert(err, checker.IsNil)
 	expected := "No such container: doesnotexist"
-	c.Assert(getErrorMessage(c, body), checker.Contains, expected)
+	c.Assert(getErrorMessage(c, b), checker.Contains, expected)
 }
 
 func (s *DockerSuite) TestPostContainersAttach(c *check.C) {
@@ -177,6 +179,7 @@ func (s *DockerSuite) TestPostContainersAttach(c *check.C) {
 	// Make sure we don't see "hello" if Logs is false
 	client, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
+	defer client.Close()
 
 	cid, _ = dockerCmd(c, "run", "-di", "busybox", "/bin/sh", "-c", "echo hello; cat")
 	cid = strings.TrimSpace(cid)

+ 7 - 8
integration-cli/docker_api_auth_test.go

@@ -1,12 +1,11 @@
 package main
 
 import (
-	"net/http"
-
 	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
-	"github.com/docker/docker/integration-cli/request"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 // Test case for #22244
@@ -16,11 +15,11 @@ func (s *DockerSuite) TestAuthAPI(c *check.C) {
 		Username: "no-user",
 		Password: "no-password",
 	}
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
+	_, err = cli.RegistryLogin(context.Background(), config)
 	expected := "Get https://registry-1.docker.io/v2/: unauthorized: incorrect username or password"
-	status, body, err := request.SockRequest("POST", "/auth", config, daemonHost())
-	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusUnauthorized)
-	msg := getErrorMessage(c, body)
-	c.Assert(msg, checker.Contains, expected, check.Commentf("Expected: %v, got: %v", expected, msg))
+	c.Assert(err.Error(), checker.Contains, expected)
 }

File diff suppressed because it is too large
+ 318 - 252
integration-cli/docker_api_containers_test.go


+ 35 - 15
integration-cli/docker_api_create_test.go

@@ -23,11 +23,15 @@ func (s *DockerSuite) TestAPICreateWithInvalidHealthcheckParams(c *check.C) {
 		},
 	}
 
-	status, body, err := request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
+	res, body, err := request.Post("/containers/create?name="+name, request.JSONBody(config))
 	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusBadRequest)
+	c.Assert(res.StatusCode, check.Equals, http.StatusBadRequest)
+
+	buf, err := request.ReadBody(body)
+	c.Assert(err, checker.IsNil)
+
 	expected := fmt.Sprintf("Interval in Healthcheck cannot be less than %s", container.MinimumDuration)
-	c.Assert(getErrorMessage(c, body), checker.Contains, expected)
+	c.Assert(getErrorMessage(c, buf), checker.Contains, expected)
 
 	// test invalid Interval in Healthcheck: larger than 0s but less than 1ms
 	name = "test2"
@@ -39,10 +43,14 @@ func (s *DockerSuite) TestAPICreateWithInvalidHealthcheckParams(c *check.C) {
 			"Retries":  int(1000),
 		},
 	}
-	status, body, err = request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
+	res, body, err = request.Post("/containers/create?name="+name, request.JSONBody(config))
 	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusBadRequest)
-	c.Assert(getErrorMessage(c, body), checker.Contains, expected)
+
+	buf, err = request.ReadBody(body)
+	c.Assert(err, checker.IsNil)
+
+	c.Assert(res.StatusCode, check.Equals, http.StatusBadRequest)
+	c.Assert(getErrorMessage(c, buf), checker.Contains, expected)
 
 	// test invalid Timeout in Healthcheck: less than 1ms
 	name = "test3"
@@ -54,11 +62,15 @@ func (s *DockerSuite) TestAPICreateWithInvalidHealthcheckParams(c *check.C) {
 			"Retries":  int(1000),
 		},
 	}
-	status, body, err = request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
+	res, body, err = request.Post("/containers/create?name="+name, request.JSONBody(config))
 	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusBadRequest)
+	c.Assert(res.StatusCode, check.Equals, http.StatusBadRequest)
+
+	buf, err = request.ReadBody(body)
+	c.Assert(err, checker.IsNil)
+
 	expected = fmt.Sprintf("Timeout in Healthcheck cannot be less than %s", container.MinimumDuration)
-	c.Assert(getErrorMessage(c, body), checker.Contains, expected)
+	c.Assert(getErrorMessage(c, buf), checker.Contains, expected)
 
 	// test invalid Retries in Healthcheck: less than 0
 	name = "test4"
@@ -70,11 +82,15 @@ func (s *DockerSuite) TestAPICreateWithInvalidHealthcheckParams(c *check.C) {
 			"Retries":  int(-10),
 		},
 	}
-	status, body, err = request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
+	res, body, err = request.Post("/containers/create?name="+name, request.JSONBody(config))
 	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusBadRequest)
+	c.Assert(res.StatusCode, check.Equals, http.StatusBadRequest)
+
+	buf, err = request.ReadBody(body)
+	c.Assert(err, checker.IsNil)
+
 	expected = "Retries in Healthcheck cannot be negative"
-	c.Assert(getErrorMessage(c, body), checker.Contains, expected)
+	c.Assert(getErrorMessage(c, buf), checker.Contains, expected)
 
 	// test invalid StartPeriod in Healthcheck: not 0 and less than 1ms
 	name = "test3"
@@ -87,9 +103,13 @@ func (s *DockerSuite) TestAPICreateWithInvalidHealthcheckParams(c *check.C) {
 			"StartPeriod": 100 * time.Microsecond,
 		},
 	}
-	status, body, err = request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
+	res, body, err = request.Post("/containers/create?name="+name, request.JSONBody(config))
 	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusBadRequest)
+	c.Assert(res.StatusCode, check.Equals, http.StatusBadRequest)
+
+	buf, err = request.ReadBody(body)
+	c.Assert(err, checker.IsNil)
+
 	expected = fmt.Sprintf("StartPeriod in Healthcheck cannot be less than %s", container.MinimumDuration)
-	c.Assert(getErrorMessage(c, body), checker.Contains, expected)
+	c.Assert(getErrorMessage(c, buf), checker.Contains, expected)
 }

+ 9 - 6
integration-cli/docker_api_exec_resize_test.go

@@ -20,9 +20,9 @@ func (s *DockerSuite) TestExecResizeAPIHeightWidthNoInt(c *check.C) {
 	cleanedContainerID := strings.TrimSpace(out)
 
 	endpoint := "/exec/" + cleanedContainerID + "/resize?h=foo&w=bar"
-	status, _, err := request.SockRequest("POST", endpoint, nil, daemonHost())
+	res, _, err := request.Post(endpoint)
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusBadRequest)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
 }
 
 // Part of #14845
@@ -36,16 +36,19 @@ func (s *DockerSuite) TestExecResizeImmediatelyAfterExecStart(c *check.C) {
 			"Cmd":         []string{"/bin/sh"},
 		}
 		uri := fmt.Sprintf("/containers/%s/exec", name)
-		status, body, err := request.SockRequest("POST", uri, data, daemonHost())
+		res, body, err := request.Post(uri, request.JSONBody(data))
 		if err != nil {
 			return err
 		}
-		if status != http.StatusCreated {
-			return fmt.Errorf("POST %s is expected to return %d, got %d", uri, http.StatusCreated, status)
+		if res.StatusCode != http.StatusCreated {
+			return fmt.Errorf("POST %s is expected to return %d, got %d", uri, http.StatusCreated, res.StatusCode)
 		}
 
+		buf, err := request.ReadBody(body)
+		c.Assert(err, checker.IsNil)
+
 		out := map[string]string{}
-		err = json.Unmarshal(body, &out)
+		err = json.Unmarshal(buf, &out)
 		if err != nil {
 			return fmt.Errorf("ExecCreate returned invalid json. Error: %q", err.Error())
 		}

+ 29 - 16
integration-cli/docker_api_exec_test.go

@@ -10,9 +10,12 @@ import (
 	"net/http"
 	"time"
 
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/request"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 // Regression test for #9414
@@ -20,12 +23,15 @@ func (s *DockerSuite) TestExecAPICreateNoCmd(c *check.C) {
 	name := "exec_test"
 	dockerCmd(c, "run", "-d", "-t", "--name", name, "busybox", "/bin/sh")
 
-	status, body, err := request.SockRequest("POST", fmt.Sprintf("/containers/%s/exec", name), map[string]interface{}{"Cmd": nil}, daemonHost())
+	res, body, err := request.Post(fmt.Sprintf("/containers/%s/exec", name), request.JSONBody(map[string]interface{}{"Cmd": nil}))
+	c.Assert(err, checker.IsNil)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
+
+	b, err := request.ReadBody(body)
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusBadRequest)
 
 	comment := check.Commentf("Expected message when creating exec command with no Cmd specified")
-	c.Assert(getErrorMessage(c, body), checker.Contains, "No exec command specified", comment)
+	c.Assert(getErrorMessage(c, b), checker.Contains, "No exec command specified", comment)
 }
 
 func (s *DockerSuite) TestExecAPICreateNoValidContentType(c *check.C) {
@@ -55,12 +61,18 @@ func (s *DockerSuite) TestExecAPICreateContainerPaused(c *check.C) {
 	dockerCmd(c, "run", "-d", "-t", "--name", name, "busybox", "/bin/sh")
 
 	dockerCmd(c, "pause", name)
-	status, body, err := request.SockRequest("POST", fmt.Sprintf("/containers/%s/exec", name), map[string]interface{}{"Cmd": []string{"true"}}, daemonHost())
+
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusConflict)
+	defer cli.Close()
+
+	config := types.ExecConfig{
+		Cmd: []string{"true"},
+	}
+	_, err = cli.ContainerExecCreate(context.Background(), name, config)
 
 	comment := check.Commentf("Expected message when creating exec command with Container %s is paused", name)
-	c.Assert(getErrorMessage(c, body), checker.Contains, "Container "+name+" is paused, unpause the container before exec", comment)
+	c.Assert(err.Error(), checker.Contains, "Container "+name+" is paused, unpause the container before exec", comment)
 }
 
 func (s *DockerSuite) TestExecAPIStart(c *check.C) {
@@ -128,22 +140,23 @@ func (s *DockerSuite) TestExecAPIStartMultipleTimesError(c *check.C) {
 func (s *DockerSuite) TestExecAPIStartWithDetach(c *check.C) {
 	name := "foo"
 	runSleepingContainer(c, "-d", "-t", "--name", name)
-	data := map[string]interface{}{
-		"cmd":         []string{"true"},
-		"AttachStdin": true,
+
+	config := types.ExecConfig{
+		Cmd:          []string{"true"},
+		AttachStderr: true,
 	}
-	_, b, err := request.SockRequest("POST", fmt.Sprintf("/containers/%s/exec", name), data, daemonHost())
-	c.Assert(err, checker.IsNil, check.Commentf(string(b)))
 
-	createResp := struct {
-		ID string `json:"Id"`
-	}{}
-	c.Assert(json.Unmarshal(b, &createResp), checker.IsNil, check.Commentf(string(b)))
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	createResp, err := cli.ContainerExecCreate(context.Background(), name, config)
+	c.Assert(err, checker.IsNil)
 
 	_, body, err := request.Post(fmt.Sprintf("/exec/%s/start", createResp.ID), request.RawString(`{"Detach": true}`), request.JSON)
 	c.Assert(err, checker.IsNil)
 
-	b, err = request.ReadBody(body)
+	b, err := request.ReadBody(body)
 	comment := check.Commentf("response body: %s", b)
 	c.Assert(err, checker.IsNil, comment)
 

+ 40 - 37
integration-cli/docker_api_images_test.go

@@ -1,38 +1,40 @@
 package main
 
 import (
-	"encoding/json"
 	"net/http"
 	"net/http/httptest"
-	"net/url"
 	"strings"
 
 	"github.com/docker/docker/api/types"
-	"github.com/docker/docker/api/types/image"
+	"github.com/docker/docker/api/types/filters"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/cli/build"
 	"github.com/docker/docker/integration-cli/request"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSuite) TestAPIImagesFilter(c *check.C) {
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
 	name := "utest:tag1"
 	name2 := "utest/docker:tag2"
 	name3 := "utest:5000/docker:tag3"
 	for _, n := range []string{name, name2, name3} {
 		dockerCmd(c, "tag", "busybox", n)
 	}
-	type image types.ImageSummary
-	getImages := func(filter string) []image {
-		v := url.Values{}
-		v.Set("filter", filter)
-		status, b, err := request.SockRequest("GET", "/images/json?"+v.Encode(), nil, daemonHost())
-		c.Assert(err, checker.IsNil)
-		c.Assert(status, checker.Equals, http.StatusOK)
-
-		var images []image
-		err = json.Unmarshal(b, &images)
+	getImages := func(filter string) []types.ImageSummary {
+		filters := filters.NewArgs()
+		filters.Add("reference", filter)
+		options := types.ImageListOptions{
+			All:     false,
+			Filters: filters,
+		}
+		images, err := cli.ImageList(context.Background(), options)
 		c.Assert(err, checker.IsNil)
 
 		return images
@@ -74,6 +76,10 @@ func (s *DockerSuite) TestAPIImagesSaveAndLoad(c *check.C) {
 }
 
 func (s *DockerSuite) TestAPIImagesDelete(c *check.C) {
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
 	if testEnv.DaemonPlatform() != "windows" {
 		testRequires(c, Network)
 	}
@@ -83,20 +89,21 @@ func (s *DockerSuite) TestAPIImagesDelete(c *check.C) {
 
 	dockerCmd(c, "tag", name, "test:tag1")
 
-	status, _, err := request.SockRequest("DELETE", "/images/"+id, nil, daemonHost())
-	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusConflict)
+	_, err = cli.ImageRemove(context.Background(), id, types.ImageRemoveOptions{})
+	c.Assert(err.Error(), checker.Contains, "unable to delete")
 
-	status, _, err = request.SockRequest("DELETE", "/images/test:noexist", nil, daemonHost())
-	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNotFound) //Status Codes:404 – no such image
+	_, err = cli.ImageRemove(context.Background(), "test:noexist", types.ImageRemoveOptions{})
+	c.Assert(err.Error(), checker.Contains, "No such image")
 
-	status, _, err = request.SockRequest("DELETE", "/images/test:tag1", nil, daemonHost())
+	_, err = cli.ImageRemove(context.Background(), "test:tag1", types.ImageRemoveOptions{})
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK)
 }
 
 func (s *DockerSuite) TestAPIImagesHistory(c *check.C) {
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
 	if testEnv.DaemonPlatform() != "windows" {
 		testRequires(c, Network)
 	}
@@ -104,13 +111,8 @@ func (s *DockerSuite) TestAPIImagesHistory(c *check.C) {
 	buildImageSuccessfully(c, name, build.WithDockerfile("FROM busybox\nENV FOO bar"))
 	id := getIDByName(c, name)
 
-	status, body, err := request.SockRequest("GET", "/images/"+id+"/history", nil, daemonHost())
+	historydata, err := cli.ImageHistory(context.Background(), id)
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK)
-
-	var historydata []image.HistoryResponseItem
-	err = json.Unmarshal(body, &historydata)
-	c.Assert(err, checker.IsNil, check.Commentf("Error on unmarshal"))
 
 	c.Assert(historydata, checker.Not(checker.HasLen), 0)
 	c.Assert(historydata[0].Tags[0], checker.Equals, "test-api-images-history:latest")
@@ -133,9 +135,8 @@ func (s *DockerSuite) TestAPIImagesImportBadSrc(c *check.C) {
 	}
 
 	for _, te := range tt {
-		res, b, err := request.SockRequestRaw("POST", strings.Join([]string{"/images/create?fromSrc=", te.fromSrc}, ""), nil, "application/json", daemonHost())
+		res, _, err := request.Post(strings.Join([]string{"/images/create?fromSrc=", te.fromSrc}, ""), request.JSON)
 		c.Assert(err, check.IsNil)
-		b.Close()
 		c.Assert(res.StatusCode, checker.Equals, te.statusExp)
 		c.Assert(res.Header.Get("Content-Type"), checker.Equals, "application/json")
 	}
@@ -156,11 +157,11 @@ func (s *DockerSuite) TestAPIImagesSearchJSONContentType(c *check.C) {
 // Test case for 30027: image size reported as -1 in v1.12 client against v1.13 daemon.
 // This test checks to make sure both v1.12 and v1.13 client against v1.13 daemon get correct `Size` after the fix.
 func (s *DockerSuite) TestAPIImagesSizeCompatibility(c *check.C) {
-	status, b, err := request.SockRequest("GET", "/images/json", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK)
-	var images []types.ImageSummary
-	err = json.Unmarshal(b, &images)
+	defer cli.Close()
+
+	images, err := cli.ImageList(context.Background(), types.ImageListOptions{})
 	c.Assert(err, checker.IsNil)
 	c.Assert(len(images), checker.Not(checker.Equals), 0)
 	for _, image := range images {
@@ -177,11 +178,13 @@ func (s *DockerSuite) TestAPIImagesSizeCompatibility(c *check.C) {
 		VirtualSize int64
 		Labels      map[string]string
 	}
-	status, b, err = request.SockRequest("GET", "/v1.24/images/json", nil, daemonHost())
+
+	var httpClient *http.Client
+	cli, err = client.NewClient(daemonHost(), "v1.24", httpClient, nil)
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK)
-	var v124Images []v124Image
-	err = json.Unmarshal(b, &v124Images)
+	defer cli.Close()
+
+	v124Images, err := cli.ImageList(context.Background(), types.ImageListOptions{})
 	c.Assert(err, checker.IsNil)
 	c.Assert(len(v124Images), checker.Not(checker.Equals), 0)
 	for _, image := range v124Images {

+ 16 - 8
integration-cli/docker_api_info_test.go

@@ -4,17 +4,23 @@ import (
 	"encoding/json"
 	"net/http"
 
+	"fmt"
+
 	"github.com/docker/docker/api/types"
+
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/request"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSuite) TestInfoAPI(c *check.C) {
-	endpoint := "/info"
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	status, body, err := request.SockRequest("GET", endpoint, nil, daemonHost())
-	c.Assert(status, checker.Equals, http.StatusOK)
+	info, err := cli.Info(context.Background())
 	c.Assert(err, checker.IsNil)
 
 	// always shown fields
@@ -36,7 +42,7 @@ func (s *DockerSuite) TestInfoAPI(c *check.C) {
 		"ServerVersion",
 		"SecurityOptions"}
 
-	out := string(body)
+	out := fmt.Sprintf("%+v", info)
 	for _, linePrefix := range stringsToCheck {
 		c.Assert(out, checker.Contains, linePrefix)
 	}
@@ -63,13 +69,15 @@ func (s *DockerSuite) TestInfoAPIRuncCommit(c *check.C) {
 
 func (s *DockerSuite) TestInfoAPIVersioned(c *check.C) {
 	testRequires(c, DaemonIsLinux) // Windows only supports 1.25 or later
-	endpoint := "/v1.20/info"
 
-	status, body, err := request.SockRequest("GET", endpoint, nil, daemonHost())
-	c.Assert(status, checker.Equals, http.StatusOK)
+	res, body, err := request.Get("/v1.20/info")
+	c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
+	c.Assert(err, checker.IsNil)
+
+	b, err := request.ReadBody(body)
 	c.Assert(err, checker.IsNil)
 
-	out := string(body)
+	out := string(b)
 	c.Assert(out, checker.Contains, "ExecutionDriver")
 	c.Assert(out, checker.Contains, "not supported")
 }

+ 7 - 10
integration-cli/docker_api_inspect_test.go

@@ -2,13 +2,14 @@ package main
 
 import (
 	"encoding/json"
-	"net/http"
 	"strings"
 
+	"golang.org/x/net/context"
+
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/versions/v1p20"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
-	"github.com/docker/docker/integration-cli/request"
 	"github.com/docker/docker/pkg/stringutils"
 	"github.com/go-check/check"
 )
@@ -106,18 +107,14 @@ func (s *DockerSuite) TestInspectAPIContainerVolumeDriver(c *check.C) {
 
 func (s *DockerSuite) TestInspectAPIImageResponse(c *check.C) {
 	dockerCmd(c, "tag", "busybox:latest", "busybox:mytag")
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	endpoint := "/images/busybox/json"
-	status, body, err := request.SockRequest("GET", endpoint, nil, daemonHost())
-
+	imageJSON, _, err := cli.ImageInspectWithRaw(context.Background(), "busybox")
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK)
 
-	var imageJSON types.ImageInspect
-	err = json.Unmarshal(body, &imageJSON)
-	c.Assert(err, checker.IsNil, check.Commentf("Unable to unmarshal body for latest version"))
 	c.Assert(imageJSON.RepoTags, checker.HasLen, 2)
-
 	c.Assert(stringutils.InSlice(imageJSON.RepoTags, "busybox:latest"), checker.Equals, true)
 	c.Assert(stringutils.InSlice(imageJSON.RepoTags, "busybox:mytag"), checker.Equals, true)
 }

+ 7 - 5
integration-cli/docker_api_inspect_unix_test.go

@@ -4,12 +4,12 @@ package main
 
 import (
 	"encoding/json"
-	"fmt"
 	"net/http"
 
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
-	"github.com/docker/docker/integration-cli/request"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 // #16665
@@ -19,9 +19,11 @@ func (s *DockerSuite) TestInspectAPICpusetInConfigPre120(c *check.C) {
 
 	name := "cpusetinconfig-pre120"
 	dockerCmd(c, "run", "--name", name, "--cpuset-cpus", "0", "busybox", "true")
-
-	status, body, err := request.SockRequest("GET", fmt.Sprintf("/v1.19/containers/%s/json", name), nil, daemonHost())
-	c.Assert(status, check.Equals, http.StatusOK)
+	var httpClient *http.Client
+	cli, err := client.NewClient(daemonHost(), "v1.19", httpClient, nil)
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+	_, body, err := cli.ContainerInspectWithRaw(context.Background(), name, false)
 	c.Assert(err, check.IsNil)
 
 	var inspectJSON map[string]interface{}

+ 7 - 4
integration-cli/docker_api_logs_test.go

@@ -7,9 +7,12 @@ import (
 	"strings"
 	"time"
 
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/request"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSuite) TestLogsAPIWithStdout(c *check.C) {
@@ -51,13 +54,13 @@ func (s *DockerSuite) TestLogsAPIWithStdout(c *check.C) {
 func (s *DockerSuite) TestLogsAPINoStdoutNorStderr(c *check.C) {
 	name := "logs_test"
 	dockerCmd(c, "run", "-d", "-t", "--name", name, "busybox", "/bin/sh")
-
-	status, body, err := request.SockRequest("GET", fmt.Sprintf("/containers/%s/logs", name), nil, daemonHost())
-	c.Assert(status, checker.Equals, http.StatusBadRequest)
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
+	_, err = cli.ContainerLogs(context.Background(), name, types.ContainerLogsOptions{})
 	expected := "Bad parameters: you must choose at least one stream"
-	c.Assert(getErrorMessage(c, body), checker.Contains, expected)
+	c.Assert(err.Error(), checker.Contains, expected)
 }
 
 // Regression test for #12704

+ 24 - 11
integration-cli/docker_api_resize_test.go

@@ -1,9 +1,12 @@
 package main
 
 import (
+	"context"
 	"net/http"
 	"strings"
 
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/request"
 	"github.com/go-check/check"
@@ -12,10 +15,15 @@ import (
 func (s *DockerSuite) TestResizeAPIResponse(c *check.C) {
 	out := runSleepingContainer(c, "-d")
 	cleanedContainerID := strings.TrimSpace(out)
-
-	endpoint := "/containers/" + cleanedContainerID + "/resize?h=40&w=40"
-	status, _, err := request.SockRequest("POST", endpoint, nil, daemonHost())
-	c.Assert(status, check.Equals, http.StatusOK)
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	options := types.ResizeOptions{
+		Height: 40,
+		Width:  40,
+	}
+	err = cli.ContainerResize(context.Background(), cleanedContainerID, options)
 	c.Assert(err, check.IsNil)
 }
 
@@ -24,8 +32,8 @@ func (s *DockerSuite) TestResizeAPIHeightWidthNoInt(c *check.C) {
 	cleanedContainerID := strings.TrimSpace(out)
 
 	endpoint := "/containers/" + cleanedContainerID + "/resize?h=foo&w=bar"
-	status, _, err := request.SockRequest("POST", endpoint, nil, daemonHost())
-	c.Assert(status, check.Equals, http.StatusBadRequest)
+	res, _, err := request.Post(endpoint)
+	c.Assert(res.StatusCode, check.Equals, http.StatusBadRequest)
 	c.Assert(err, check.IsNil)
 }
 
@@ -36,10 +44,15 @@ func (s *DockerSuite) TestResizeAPIResponseWhenContainerNotStarted(c *check.C) {
 	// make sure the exited container is not running
 	dockerCmd(c, "wait", cleanedContainerID)
 
-	endpoint := "/containers/" + cleanedContainerID + "/resize?h=40&w=40"
-	status, body, err := request.SockRequest("POST", endpoint, nil, daemonHost())
-	c.Assert(status, check.Equals, http.StatusConflict)
-	c.Assert(err, check.IsNil)
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	options := types.ResizeOptions{
+		Height: 40,
+		Width:  40,
+	}
 
-	c.Assert(getErrorMessage(c, body), checker.Contains, "is not running", check.Commentf("resize should fail with message 'Container is not running'"))
+	err = cli.ContainerResize(context.Background(), cleanedContainerID, options)
+	c.Assert(err.Error(), checker.Contains, "is not running")
 }

+ 10 - 6
integration-cli/docker_api_stats_test.go

@@ -13,9 +13,11 @@ import (
 
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/versions"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/request"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 var expectedNetworkInterfaceStats = strings.Split("rx_bytes rx_dropped rx_errors rx_packets tx_bytes tx_dropped tx_errors tx_packets", " ")
@@ -260,14 +262,16 @@ func jsonBlobHasGTE121NetworkStats(blob map[string]interface{}) bool {
 
 func (s *DockerSuite) TestAPIStatsContainerNotFound(c *check.C) {
 	testRequires(c, DaemonIsLinux)
-
-	status, _, err := request.SockRequest("GET", "/containers/nonexistent/stats", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNotFound)
+	defer cli.Close()
 
-	status, _, err = request.SockRequest("GET", "/containers/nonexistent/stats?stream=0", nil, daemonHost())
-	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNotFound)
+	expected := "No such container: nonexistent"
+
+	_, err = cli.ContainerStats(context.Background(), "nonexistent", true)
+	c.Assert(err.Error(), checker.Contains, expected)
+	_, err = cli.ContainerStats(context.Background(), "nonexistent", false)
+	c.Assert(err.Error(), checker.Contains, expected)
 }
 
 func (s *DockerSuite) TestAPIStatsNoStreamConnectedContainers(c *check.C) {

+ 16 - 9
integration-cli/docker_api_swarm_config_test.go

@@ -3,12 +3,10 @@
 package main
 
 import (
-	"fmt"
-	"net/http"
-
 	"github.com/docker/docker/api/types/swarm"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSwarmSuite) TestAPISwarmConfigsEmptyList(c *check.C) {
@@ -52,9 +50,15 @@ func (s *DockerSwarmSuite) TestAPISwarmConfigsDelete(c *check.C) {
 	c.Assert(config.ID, checker.Equals, id, check.Commentf("config: %v", config))
 
 	d.DeleteConfig(c, config.ID)
-	status, out, err := d.SockRequest("GET", "/configs/"+id, nil)
+
+	cli, err := d.NewClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNotFound, check.Commentf("config delete: %s", string(out)))
+	defer cli.Close()
+
+	expected := "no such config"
+
+	_, _, err = cli.ConfigInspectWithRaw(context.Background(), id)
+	c.Assert(err.Error(), checker.Contains, expected)
 }
 
 func (s *DockerSwarmSuite) TestAPISwarmConfigsUpdate(c *check.C) {
@@ -110,9 +114,12 @@ func (s *DockerSwarmSuite) TestAPISwarmConfigsUpdate(c *check.C) {
 	config = d.GetConfig(c, id)
 	config.Spec.Data = []byte("TESTINGDATA2")
 
-	url := fmt.Sprintf("/configs/%s/update?version=%d", config.ID, config.Version.Index)
-	status, out, err := d.SockRequest("POST", url, config.Spec)
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	expected := "only updates to Labels are allowed"
 
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusBadRequest, check.Commentf("output: %q", string(out)))
+	err = cli.ConfigUpdate(context.Background(), config.ID, config.Version, config.Spec)
+	c.Assert(err.Error(), checker.Contains, expected)
 }

+ 18 - 12
integration-cli/docker_api_swarm_secret_test.go

@@ -3,12 +3,12 @@
 package main
 
 import (
-	"fmt"
 	"net/http"
 
 	"github.com/docker/docker/api/types/swarm"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSwarmSuite) TestAPISwarmSecretsEmptyList(c *check.C) {
@@ -59,16 +59,19 @@ func (s *DockerSwarmSuite) TestAPISwarmSecretsDelete(c *check.C) {
 	c.Assert(secret.ID, checker.Equals, id, check.Commentf("secret: %v", secret))
 
 	d.DeleteSecret(c, secret.ID)
-	status, out, err := d.SockRequest("GET", "/secrets/"+id, nil)
-	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNotFound, check.Commentf("secret delete: %s", string(out)))
 
-	// delete non-existing secret, daemon should return a status code of 404
-	id = "non-existing"
-	status, out, err = d.SockRequest("DELETE", "/secrets/"+id, nil)
+	cli, err := d.NewClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNotFound, check.Commentf("secret delete: %s", string(out)))
+	defer cli.Close()
+
+	expected := "no such secret"
+	_, _, err = cli.SecretInspectWithRaw(context.Background(), id)
+	c.Assert(err.Error(), checker.Contains, expected)
 
+	id = "non-existing"
+	expected = "secret non-existing not found"
+	err = cli.SecretRemove(context.Background(), id)
+	c.Assert(err.Error(), checker.Contains, expected)
 }
 
 func (s *DockerSwarmSuite) TestAPISwarmSecretsUpdate(c *check.C) {
@@ -124,9 +127,12 @@ func (s *DockerSwarmSuite) TestAPISwarmSecretsUpdate(c *check.C) {
 	secret = d.GetSecret(c, id)
 	secret.Spec.Data = []byte("TESTINGDATA2")
 
-	url := fmt.Sprintf("/secrets/%s/update?version=%d", secret.ID, secret.Version.Index)
-	status, out, err := d.SockRequest("POST", url, secret.Spec)
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	expected := "only updates to Labels are allowed"
 
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusBadRequest, check.Commentf("output: %q", string(out)))
+	err = cli.SecretUpdate(context.Background(), secret.ID, secret.Version, secret.Spec)
+	c.Assert(err.Error(), checker.Contains, expected)
 }

+ 17 - 6
integration-cli/docker_api_swarm_service_test.go

@@ -9,6 +9,7 @@ import (
 	"strings"
 	"time"
 
+	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/swarm"
 	"github.com/docker/docker/api/types/swarm/runtime"
 	"github.com/docker/docker/integration-cli/checker"
@@ -64,14 +65,24 @@ func (s *DockerSwarmSuite) TestAPISwarmServicesCreate(c *check.C) {
 	id := d.CreateService(c, simpleTestService, setInstances(instances))
 	waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, instances)
 
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	options := types.ServiceInspectOptions{
+		InsertDefaults: true,
+	}
+
 	// insertDefaults inserts UpdateConfig when service is fetched by ID
-	_, out, err := d.SockRequest("GET", "/services/"+id+"?insertDefaults=true", nil)
-	c.Assert(err, checker.IsNil, check.Commentf("%s", out))
-	c.Assert(string(out), checker.Contains, "UpdateConfig")
+	resp, _, err := cli.ServiceInspectWithRaw(context.Background(), id, options)
+	out := fmt.Sprintf("%+v", resp)
+	c.Assert(err, checker.IsNil)
+	c.Assert(out, checker.Contains, "UpdateConfig")
 
 	// insertDefaults inserts UpdateConfig when service is fetched by ID
-	_, out, err = d.SockRequest("GET", "/services/top?insertDefaults=true", nil)
-	c.Assert(err, checker.IsNil, check.Commentf("%s", out))
+	resp, _, err = cli.ServiceInspectWithRaw(context.Background(), "top", options)
+	out = fmt.Sprintf("%+v", resp)
+	c.Assert(err, checker.IsNil)
 	c.Assert(string(out), checker.Contains, "UpdateConfig")
 
 	service := d.GetService(c, id)
@@ -195,7 +206,7 @@ func (s *DockerSwarmSuite) TestAPISwarmServicesUpdateStartFirst(c *check.C) {
 	// service image at start
 	image1 := "busybox:latest"
 	// target image in update
-	image2 := "testhealth"
+	image2 := "testhealth:latest"
 
 	// service started from this image won't pass health check
 	_, _, err := d.BuildImageWithOut(image2,

+ 36 - 48
integration-cli/docker_api_swarm_test.go

@@ -23,8 +23,10 @@ import (
 	"github.com/docker/docker/api/types/swarm"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/daemon"
+	"github.com/docker/docker/integration-cli/request"
 	"github.com/docker/swarmkit/ca"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 var defaultReconciliationTimeout = 30 * time.Second
@@ -228,17 +230,20 @@ func (s *DockerSwarmSuite) TestAPISwarmPromoteDemote(c *check.C) {
 	node := d1.GetNode(c, d1.NodeID)
 	node.Spec.Role = swarm.NodeRoleWorker
 	url := fmt.Sprintf("/nodes/%s/update?version=%d", node.ID, node.Version.Index)
-	status, out, err := d1.SockRequest("POST", url, node.Spec)
+	res, body, err := request.DoOnHost(d1.Sock(), url, request.Method("POST"), request.JSONBody(node.Spec))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusBadRequest, check.Commentf("output: %q", string(out)))
+	b, err := request.ReadBody(body)
+	c.Assert(err, checker.IsNil)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest, check.Commentf("output: %q", string(b)))
+
 	// The warning specific to demoting the last manager is best-effort and
 	// won't appear until the Role field of the demoted manager has been
 	// updated.
 	// Yes, I know this looks silly, but checker.Matches is broken, since
 	// it anchors the regexp contrary to the documentation, and this makes
 	// it impossible to match something that includes a line break.
-	if !strings.Contains(string(out), "last manager of the swarm") {
-		c.Assert(string(out), checker.Contains, "this would result in a loss of quorum")
+	if !strings.Contains(string(b), "last manager of the swarm") {
+		c.Assert(string(b), checker.Contains, "this would result in a loss of quorum")
 	}
 	info, err = d1.SwarmInfo()
 	c.Assert(err, checker.IsNil)
@@ -362,9 +367,11 @@ func (s *DockerSwarmSuite) TestAPISwarmRaftQuorum(c *check.C) {
 	var service swarm.Service
 	simpleTestService(&service)
 	service.Spec.Name = "top2"
-	status, out, err := d1.SockRequest("POST", "/services/create", service.Spec)
+	cli, err := d1.NewClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusInternalServerError, check.Commentf("deadline exceeded", string(out)))
+	defer cli.Close()
+	_, err = cli.ServiceCreate(context.Background(), service.Spec, types.ServiceCreateOptions{})
+	c.Assert(err.Error(), checker.Contains, "deadline exceeded")
 
 	d2.Start(c)
 
@@ -505,17 +512,17 @@ func (s *DockerSwarmSuite) TestAPISwarmInvalidAddress(c *check.C) {
 	req := swarm.InitRequest{
 		ListenAddr: "",
 	}
-	status, _, err := d.SockRequest("POST", "/swarm/init", req)
+	res, _, err := request.DoOnHost(d.Sock(), "/swarm/init", request.Method("POST"), request.JSONBody(req))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusBadRequest)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
 
 	req2 := swarm.JoinRequest{
 		ListenAddr:  "0.0.0.0:2377",
 		RemoteAddrs: []string{""},
 	}
-	status, _, err = d.SockRequest("POST", "/swarm/join", req2)
+	res, _, err = request.DoOnHost(d.Sock(), "/swarm/join", request.Method("POST"), request.JSONBody(req2))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusBadRequest)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
 }
 
 func (s *DockerSwarmSuite) TestAPISwarmForceNewCluster(c *check.C) {
@@ -836,10 +843,11 @@ func (s *DockerSwarmSuite) TestAPISwarmServicesUpdateWithName(c *check.C) {
 	instances = 5
 
 	setInstances(instances)(service)
-	url := fmt.Sprintf("/services/%s/update?version=%d", service.Spec.Name, service.Version.Index)
-	status, out, err := d.SockRequest("POST", url, service.Spec)
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+	_, err = cli.ServiceUpdate(context.Background(), service.Spec.Name, service.Version, service.Spec, types.ServiceUpdateOptions{})
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
 	waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, instances)
 }
 
@@ -867,51 +875,31 @@ func (s *DockerSwarmSuite) TestAPISwarmErrorHandling(c *check.C) {
 // This test makes sure the fixes correctly output scopes instead.
 func (s *DockerSwarmSuite) TestAPIDuplicateNetworks(c *check.C) {
 	d := s.AddDaemon(c, true, true)
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
 	name := "foo"
-	networkCreateRequest := types.NetworkCreateRequest{
-		Name: name,
-		NetworkCreate: types.NetworkCreate{
-			CheckDuplicate: false,
-		},
+	networkCreate := types.NetworkCreate{
+		CheckDuplicate: false,
 	}
 
-	var n1 types.NetworkCreateResponse
-	networkCreateRequest.NetworkCreate.Driver = "bridge"
+	networkCreate.Driver = "bridge"
 
-	status, out, err := d.SockRequest("POST", "/networks/create", networkCreateRequest)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf(string(out)))
-
-	c.Assert(json.Unmarshal(out, &n1), checker.IsNil)
-
-	var n2 types.NetworkCreateResponse
-	networkCreateRequest.NetworkCreate.Driver = "overlay"
-
-	status, out, err = d.SockRequest("POST", "/networks/create", networkCreateRequest)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf(string(out)))
-
-	c.Assert(json.Unmarshal(out, &n2), checker.IsNil)
+	n1, err := cli.NetworkCreate(context.Background(), name, networkCreate)
+	c.Assert(err, checker.IsNil)
 
-	var r1 types.NetworkResource
+	networkCreate.Driver = "overlay"
 
-	status, out, err = d.SockRequest("GET", "/networks/"+n1.ID, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf(string(out)))
-
-	c.Assert(json.Unmarshal(out, &r1), checker.IsNil)
+	n2, err := cli.NetworkCreate(context.Background(), name, networkCreate)
+	c.Assert(err, checker.IsNil)
 
+	r1, err := cli.NetworkInspect(context.Background(), n1.ID, types.NetworkInspectOptions{})
+	c.Assert(err, checker.IsNil)
 	c.Assert(r1.Scope, checker.Equals, "local")
 
-	var r2 types.NetworkResource
-
-	status, out, err = d.SockRequest("GET", "/networks/"+n2.ID, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf(string(out)))
-
-	c.Assert(json.Unmarshal(out, &r2), checker.IsNil)
-
+	r2, err := cli.NetworkInspect(context.Background(), n2.ID, types.NetworkInspectOptions{})
+	c.Assert(err, checker.IsNil)
 	c.Assert(r2.Scope, checker.Equals, "swarm")
 }
 

+ 14 - 5
integration-cli/docker_api_update_unix_test.go

@@ -5,9 +5,11 @@ package main
 import (
 	"strings"
 
+	"github.com/docker/docker/api/types/container"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
-	"github.com/docker/docker/integration-cli/request"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSuite) TestAPIUpdateContainer(c *check.C) {
@@ -16,12 +18,19 @@ func (s *DockerSuite) TestAPIUpdateContainer(c *check.C) {
 	testRequires(c, swapMemorySupport)
 
 	name := "apiUpdateContainer"
-	hostConfig := map[string]interface{}{
-		"Memory":     314572800,
-		"MemorySwap": 524288000,
+	updateConfig := container.UpdateConfig{
+		Resources: container.Resources{
+			Memory:     314572800,
+			MemorySwap: 524288000,
+		},
 	}
 	dockerCmd(c, "run", "-d", "--name", name, "-m", "200M", "busybox", "top")
-	_, _, err := request.SockRequest("POST", "/containers/"+name+"/update", hostConfig, daemonHost())
+	cli, err := client.NewEnvClient()
+	c.Assert(err, check.IsNil)
+	defer cli.Close()
+
+	_, err = cli.ContainerUpdate(context.Background(), name, updateConfig)
+
 	c.Assert(err, check.IsNil)
 
 	c.Assert(inspectField(c, name, "HostConfig.Memory"), checker.Equals, "314572800")

+ 5 - 11
integration-cli/docker_api_version_test.go

@@ -1,24 +1,18 @@
 package main
 
 import (
-	"encoding/json"
-	"net/http"
-
-	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/dockerversion"
 	"github.com/docker/docker/integration-cli/checker"
-	"github.com/docker/docker/integration-cli/request"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSuite) TestGetVersion(c *check.C) {
-	status, body, err := request.SockRequest("GET", "/version", nil, daemonHost())
-	c.Assert(status, checker.Equals, http.StatusOK)
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	var v types.Version
-
-	c.Assert(json.Unmarshal(body, &v), checker.IsNil)
-
+	v, err := cli.ServerVersion(context.Background())
 	c.Assert(v.Version, checker.Equals, dockerversion.Version, check.Commentf("Version mismatch"))
 }

+ 28 - 35
integration-cli/docker_api_volumes_test.go

@@ -1,30 +1,29 @@
 package main
 
 import (
-	"encoding/json"
 	"fmt"
-	"net/http"
 	"path/filepath"
 	"strings"
 	"time"
 
-	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/api/types/filters"
 	volumetypes "github.com/docker/docker/api/types/volume"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
-	"github.com/docker/docker/integration-cli/request"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSuite) TestVolumesAPIList(c *check.C) {
 	prefix, _ := getPrefixAndSlashFromDaemonPlatform()
 	dockerCmd(c, "run", "-v", prefix+"/foo", "busybox")
 
-	status, b, err := request.SockRequest("GET", "/volumes", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK)
+	defer cli.Close()
 
-	var volumes volumetypes.VolumesListOKBody
-	c.Assert(json.Unmarshal(b, &volumes), checker.IsNil)
+	volumes, err := cli.VolumeList(context.Background(), filters.Args{})
+	c.Assert(err, checker.IsNil)
 
 	c.Assert(len(volumes.Volumes), checker.Equals, 1, check.Commentf("\n%v", volumes.Volumes))
 }
@@ -33,13 +32,13 @@ func (s *DockerSuite) TestVolumesAPICreate(c *check.C) {
 	config := volumetypes.VolumesCreateBody{
 		Name: "test",
 	}
-	status, b, err := request.SockRequest("POST", "/volumes/create", config, daemonHost())
-	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusCreated, check.Commentf(string(b)))
 
-	var vol types.Volume
-	err = json.Unmarshal(b, &vol)
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	vol, err := cli.VolumeCreate(context.Background(), config)
+	c.Assert(err, check.IsNil)
 
 	c.Assert(filepath.Base(filepath.Dir(vol.Mountpoint)), checker.Equals, config.Name)
 }
@@ -48,49 +47,43 @@ func (s *DockerSuite) TestVolumesAPIRemove(c *check.C) {
 	prefix, _ := getPrefixAndSlashFromDaemonPlatform()
 	dockerCmd(c, "run", "-v", prefix+"/foo", "--name=test", "busybox")
 
-	status, b, err := request.SockRequest("GET", "/volumes", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK)
+	defer cli.Close()
 
-	var volumes volumetypes.VolumesListOKBody
-	c.Assert(json.Unmarshal(b, &volumes), checker.IsNil)
-	c.Assert(len(volumes.Volumes), checker.Equals, 1, check.Commentf("\n%v", volumes.Volumes))
+	volumes, err := cli.VolumeList(context.Background(), filters.Args{})
+	c.Assert(err, checker.IsNil)
 
 	v := volumes.Volumes[0]
-	status, _, err = request.SockRequest("DELETE", "/volumes/"+v.Name, nil, daemonHost())
-	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusConflict, check.Commentf("Should not be able to remove a volume that is in use"))
+	err = cli.VolumeRemove(context.Background(), v.Name, false)
+	c.Assert(err.Error(), checker.Contains, "volume is in use")
 
 	dockerCmd(c, "rm", "-f", "test")
-	status, data, err := request.SockRequest("DELETE", "/volumes/"+v.Name, nil, daemonHost())
+	err = cli.VolumeRemove(context.Background(), v.Name, false)
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNoContent, check.Commentf(string(data)))
-
 }
 
 func (s *DockerSuite) TestVolumesAPIInspect(c *check.C) {
 	config := volumetypes.VolumesCreateBody{
 		Name: "test",
 	}
+
 	// sampling current time minus a minute so to now have false positive in case of delays
 	now := time.Now().Truncate(time.Minute)
-	status, b, err := request.SockRequest("POST", "/volumes/create", config, daemonHost())
-	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusCreated, check.Commentf(string(b)))
 
-	status, b, err = request.SockRequest("GET", "/volumes", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf(string(b)))
+	defer cli.Close()
 
-	var volumes volumetypes.VolumesListOKBody
-	c.Assert(json.Unmarshal(b, &volumes), checker.IsNil)
+	_, err = cli.VolumeCreate(context.Background(), config)
+	c.Assert(err, check.IsNil)
+
+	volumes, err := cli.VolumeList(context.Background(), filters.Args{})
+	c.Assert(err, checker.IsNil)
 	c.Assert(len(volumes.Volumes), checker.Equals, 1, check.Commentf("\n%v", volumes.Volumes))
 
-	var vol types.Volume
-	status, b, err = request.SockRequest("GET", "/volumes/"+config.Name, nil, daemonHost())
+	vol, err := cli.VolumeInspect(context.Background(), config.Name)
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf(string(b)))
-	c.Assert(json.Unmarshal(b, &vol), checker.IsNil)
 	c.Assert(vol.Name, checker.Equals, config.Name)
 
 	// comparing CreatedAt field time for the new volume to now. Removing a minute from both to avoid false positive

+ 13 - 5
integration-cli/docker_cli_events_test.go

@@ -6,20 +6,22 @@ import (
 	"fmt"
 	"io"
 	"io/ioutil"
-	"net/http"
 	"os"
 	"os/exec"
 	"strings"
 	"time"
 
+	"github.com/docker/docker/api/types"
 	eventtypes "github.com/docker/docker/api/types/events"
+	"github.com/docker/docker/client"
 	eventstestutils "github.com/docker/docker/daemon/events/testutils"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/cli/build"
-	"github.com/docker/docker/integration-cli/request"
+
 	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSuite) TestEventsTimestampFormats(c *check.C) {
@@ -498,9 +500,15 @@ func (s *DockerSuite) TestEventsResize(c *check.C) {
 	cID := strings.TrimSpace(out)
 	c.Assert(waitRun(cID), checker.IsNil)
 
-	endpoint := "/containers/" + cID + "/resize?h=80&w=24"
-	status, _, err := request.SockRequest("POST", endpoint, nil, daemonHost())
-	c.Assert(status, checker.Equals, http.StatusOK)
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	options := types.ResizeOptions{
+		Height: 80,
+		Width:  24,
+	}
+	err = cli.ContainerResize(context.Background(), cID, options)
 	c.Assert(err, checker.IsNil)
 
 	dockerCmd(c, "stop", cID)

+ 11 - 6
integration-cli/docker_cli_exec_test.go

@@ -5,7 +5,6 @@ package main
 import (
 	"bufio"
 	"fmt"
-	"net/http"
 	"os"
 	"os/exec"
 	"reflect"
@@ -15,12 +14,13 @@ import (
 	"sync"
 	"time"
 
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/cli/build"
-	"github.com/docker/docker/integration-cli/request"
 	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSuite) TestExec(c *check.C) {
@@ -357,16 +357,21 @@ func (s *DockerSuite) TestExecInspectID(c *check.C) {
 	}
 
 	// But we should still be able to query the execID
-	sc, body, _ := request.SockRequest("GET", "/exec/"+execID+"/json", nil, daemonHost())
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	c.Assert(sc, checker.Equals, http.StatusOK, check.Commentf("received status != 200 OK: %d\n%s", sc, body))
+	_, err = cli.ContainerExecInspect(context.Background(), execID)
+	c.Assert(err, checker.IsNil)
 
 	// Now delete the container and then an 'inspect' on the exec should
 	// result in a 404 (not 'container not running')
 	out, ec := dockerCmd(c, "rm", "-f", id)
 	c.Assert(ec, checker.Equals, 0, check.Commentf("error removing container: %s", out))
-	sc, body, _ = request.SockRequest("GET", "/exec/"+execID+"/json", nil, daemonHost())
-	c.Assert(sc, checker.Equals, http.StatusNotFound, check.Commentf("received status != 404: %d\n%s", sc, body))
+
+	_, err = cli.ContainerExecInspect(context.Background(), execID)
+	expected := "No such exec instance"
+	c.Assert(err.Error(), checker.Contains, expected)
 }
 
 func (s *DockerSuite) TestLinksPingLinkedContainersOnRename(c *check.C) {

+ 7 - 5
integration-cli/docker_cli_kill_test.go

@@ -1,16 +1,16 @@
 package main
 
 import (
-	"fmt"
 	"net/http"
 	"strings"
 	"time"
 
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli"
-	"github.com/docker/docker/integration-cli/request"
 	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSuite) TestKillContainer(c *check.C) {
@@ -131,8 +131,10 @@ func (s *DockerSuite) TestKillStoppedContainerAPIPre120(c *check.C) {
 	testRequires(c, DaemonIsLinux) // Windows only supports 1.25 or later
 	runSleepingContainer(c, "--name", "docker-kill-test-api", "-d")
 	dockerCmd(c, "stop", "docker-kill-test-api")
-
-	status, _, err := request.SockRequest("POST", fmt.Sprintf("/v1.19/containers/%s/kill", "docker-kill-test-api"), nil, daemonHost())
+	var httpClient *http.Client
+	cli, err := client.NewClient(daemonHost(), "v1.19", httpClient, nil)
+	c.Assert(err, check.IsNil)
+	defer cli.Close()
+	err = cli.ContainerKill(context.Background(), "docker-kill-test-api", "SIGKILL")
 	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusNoContent)
 }

+ 7 - 8
integration-cli/docker_cli_plugins_logdriver_test.go

@@ -1,14 +1,12 @@
 package main
 
 import (
-	"encoding/json"
-	"net/http"
 	"strings"
 
-	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
-	"github.com/docker/docker/integration-cli/request"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSuite) TestPluginLogDriver(c *check.C) {
@@ -36,13 +34,14 @@ func (s *DockerSuite) TestPluginLogDriverInfoList(c *check.C) {
 	pluginName := "cpuguy83/docker-logdriver-test"
 
 	dockerCmd(c, "plugin", "install", pluginName)
-	status, body, err := request.SockRequest("GET", "/info", nil, daemonHost())
-	c.Assert(status, checker.Equals, http.StatusOK)
+
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	var info types.Info
-	err = json.Unmarshal(body, &info)
+	info, err := cli.Info(context.Background())
 	c.Assert(err, checker.IsNil)
+
 	drivers := strings.Join(info.Plugins.Log, " ")
 	c.Assert(drivers, checker.Contains, "json-file")
 	c.Assert(drivers, checker.Not(checker.Contains), pluginName)

+ 16 - 23
integration-cli/docker_cli_swarm_test.go

@@ -29,6 +29,7 @@ import (
 	remoteipam "github.com/docker/libnetwork/ipams/remote/api"
 	"github.com/go-check/check"
 	"github.com/vishvananda/netlink"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSwarmSuite) TestSwarmUpdate(c *check.C) {
@@ -1843,19 +1844,17 @@ func (s *DockerSwarmSuite) TestNetworkInspectWithDuplicateNames(c *check.C) {
 	d := s.AddDaemon(c, true, true)
 
 	name := "foo"
-	networkCreateRequest := types.NetworkCreateRequest{
-		Name: name,
-		NetworkCreate: types.NetworkCreate{
-			CheckDuplicate: false,
-			Driver:         "bridge",
-		},
+	options := types.NetworkCreate{
+		CheckDuplicate: false,
+		Driver:         "bridge",
 	}
 
-	var n1 types.NetworkCreateResponse
-	status, body, err := d.SockRequest("POST", "/networks/create", networkCreateRequest)
-	c.Assert(err, checker.IsNil, check.Commentf(string(body)))
-	c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf(string(body)))
-	c.Assert(json.Unmarshal(body, &n1), checker.IsNil)
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	n1, err := cli.NetworkCreate(context.Background(), name, options)
+	c.Assert(err, checker.IsNil)
 
 	// Full ID always works
 	out, err := d.Cmd("network", "inspect", "--format", "{{.ID}}", n1.ID)
@@ -1867,12 +1866,8 @@ func (s *DockerSwarmSuite) TestNetworkInspectWithDuplicateNames(c *check.C) {
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 	c.Assert(strings.TrimSpace(out), checker.Equals, n1.ID)
 
-	var n2 types.NetworkCreateResponse
-	status, body, err = d.SockRequest("POST", "/networks/create", networkCreateRequest)
-	c.Assert(err, checker.IsNil, check.Commentf(string(body)))
-	c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf(string(body)))
-	c.Assert(json.Unmarshal(body, &n2), checker.IsNil)
-
+	n2, err := cli.NetworkCreate(context.Background(), name, options)
+	c.Assert(err, checker.IsNil)
 	// Full ID always works
 	out, err = d.Cmd("network", "inspect", "--format", "{{.ID}}", n1.ID)
 	c.Assert(err, checker.IsNil, check.Commentf(out))
@@ -1890,13 +1885,11 @@ func (s *DockerSwarmSuite) TestNetworkInspectWithDuplicateNames(c *check.C) {
 	out, err = d.Cmd("network", "rm", n2.ID)
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 
-	// Duplicates with name but with different driver
-	networkCreateRequest.NetworkCreate.Driver = "overlay"
+	// Dupliates with name but with different driver
+	options.Driver = "overlay"
 
-	status, body, err = d.SockRequest("POST", "/networks/create", networkCreateRequest)
-	c.Assert(err, checker.IsNil, check.Commentf(string(body)))
-	c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf(string(body)))
-	c.Assert(json.Unmarshal(body, &n2), checker.IsNil)
+	n2, err = cli.NetworkCreate(context.Background(), name, options)
+	c.Assert(err, checker.IsNil)
 
 	// Full ID always works
 	out, err = d.Cmd("network", "inspect", "--format", "{{.ID}}", n1.ID)

+ 26 - 20
integration-cli/docker_cli_volume_test.go

@@ -3,17 +3,20 @@ package main
 import (
 	"fmt"
 	"io/ioutil"
-	"net/http"
 	"os"
 	"os/exec"
 	"path/filepath"
 	"strings"
 
+	"github.com/docker/docker/api/types/container"
+	"github.com/docker/docker/api/types/mount"
+	"github.com/docker/docker/api/types/network"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli/build"
-	"github.com/docker/docker/integration-cli/request"
 	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSuite) TestVolumeCLICreate(c *check.C) {
@@ -607,25 +610,28 @@ func (s *DockerSuite) TestDuplicateMountpointsForVolumesFromAndMounts(c *check.C
 	err := os.MkdirAll("/tmp/data", 0755)
 	c.Assert(err, checker.IsNil)
 	// Mounts is available in API
-	status, body, err := request.SockRequest("POST", "/containers/create?name=app", map[string]interface{}{
-		"Image": "busybox",
-		"Cmd":   []string{"top"},
-		"HostConfig": map[string]interface{}{
-			"VolumesFrom": []string{
-				"data1",
-				"data2",
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	config := container.Config{
+		Cmd:   []string{"top"},
+		Image: "busybox",
+	}
+
+	hostConfig := container.HostConfig{
+		VolumesFrom: []string{"data1", "data2"},
+		Mounts: []mount.Mount{
+			{
+				Type:   "bind",
+				Source: "/tmp/data",
+				Target: "/tmp/data",
 			},
-			"Mounts": []map[string]interface{}{
-				{
-					"Type":   "bind",
-					"Source": "/tmp/data",
-					"Target": "/tmp/data",
-				},
-			}},
-	}, daemonHost())
-
-	c.Assert(err, checker.IsNil, check.Commentf(string(body)))
-	c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf(string(body)))
+		},
+	}
+	_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig, &network.NetworkingConfig{}, "app")
+
+	c.Assert(err, checker.IsNil)
 
 	// No volume will be referenced (mount is /tmp/data), this is backward compatible
 	out, _ = dockerCmd(c, "inspect", "--format", "{{(index .Mounts 0).Name}}", "app")

+ 26 - 17
integration-cli/docker_deprecated_api_v124_test.go

@@ -22,9 +22,14 @@ func (s *DockerSuite) TestDeprecatedContainerAPIStartHostConfig(c *check.C) {
 	config := map[string]interface{}{
 		"Binds": []string{"/aa:/bb"},
 	}
-	status, _, err := request.SockRequest("POST", "/containers/"+name+"/start", config, daemonHost())
+	res, body, err := request.Post("/containers/"+name+"/start", request.JSONBody(config))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusBadRequest)
+
+	buf, err := request.ReadBody(body)
+	c.Assert(err, checker.IsNil)
+
+	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
+	c.Assert(string(buf), checker.Contains, "was deprecated since API v1.22")
 }
 
 func (s *DockerSuite) TestDeprecatedContainerAPIStartVolumeBinds(c *check.C) {
@@ -40,17 +45,17 @@ func (s *DockerSuite) TestDeprecatedContainerAPIStartVolumeBinds(c *check.C) {
 		"Volumes": map[string]struct{}{path: {}},
 	}
 
-	status, _, err := request.SockRequest("POST", formatV123StartAPIURL("/containers/create?name="+name), config, daemonHost())
+	res, _, err := request.Post(formatV123StartAPIURL("/containers/create?name="+name), request.JSONBody(config))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusCreated)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusCreated)
 
 	bindPath := RandomTmpDirPath("test", testEnv.DaemonPlatform())
 	config = map[string]interface{}{
 		"Binds": []string{bindPath + ":" + path},
 	}
-	status, _, err = request.SockRequest("POST", formatV123StartAPIURL("/containers/"+name+"/start"), config, daemonHost())
+	res, _, err = request.Post(formatV123StartAPIURL("/containers/"+name+"/start"), request.JSONBody(config))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNoContent)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusNoContent)
 
 	pth, err := inspectMountSourceField(name, path)
 	c.Assert(err, checker.IsNil)
@@ -67,9 +72,9 @@ func (s *DockerSuite) TestDeprecatedContainerAPIStartDupVolumeBinds(c *check.C)
 		"Volumes": map[string]struct{}{"/tmp": {}},
 	}
 
-	status, _, err := request.SockRequest("POST", formatV123StartAPIURL("/containers/create?name="+name), config, daemonHost())
+	res, _, err := request.Post(formatV123StartAPIURL("/containers/create?name="+name), request.JSONBody(config))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusCreated)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusCreated)
 
 	bindPath1 := RandomTmpDirPath("test1", testEnv.DaemonPlatform())
 	bindPath2 := RandomTmpDirPath("test2", testEnv.DaemonPlatform())
@@ -77,10 +82,14 @@ func (s *DockerSuite) TestDeprecatedContainerAPIStartDupVolumeBinds(c *check.C)
 	config = map[string]interface{}{
 		"Binds": []string{bindPath1 + ":/tmp", bindPath2 + ":/tmp"},
 	}
-	status, body, err := request.SockRequest("POST", formatV123StartAPIURL("/containers/"+name+"/start"), config, daemonHost())
+	res, body, err := request.Post(formatV123StartAPIURL("/containers/"+name+"/start"), request.JSONBody(config))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusBadRequest)
-	c.Assert(string(body), checker.Contains, "Duplicate mount point", check.Commentf("Expected failure due to duplicate bind mounts to same path, instead got: %q with error: %v", string(body), err))
+
+	buf, err := request.ReadBody(body)
+	c.Assert(err, checker.IsNil)
+
+	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
+	c.Assert(string(buf), checker.Contains, "Duplicate mount point", check.Commentf("Expected failure due to duplicate bind mounts to same path, instead got: %q with error: %v", string(buf), err))
 }
 
 func (s *DockerSuite) TestDeprecatedContainerAPIStartVolumesFrom(c *check.C) {
@@ -97,16 +106,16 @@ func (s *DockerSuite) TestDeprecatedContainerAPIStartVolumesFrom(c *check.C) {
 		"Volumes": map[string]struct{}{volPath: {}},
 	}
 
-	status, _, err := request.SockRequest("POST", formatV123StartAPIURL("/containers/create?name="+name), config, daemonHost())
+	res, _, err := request.Post(formatV123StartAPIURL("/containers/create?name="+name), request.JSONBody(config))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusCreated)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusCreated)
 
 	config = map[string]interface{}{
 		"VolumesFrom": []string{volName},
 	}
-	status, _, err = request.SockRequest("POST", formatV123StartAPIURL("/containers/"+name+"/start"), config, daemonHost())
+	res, _, err = request.Post(formatV123StartAPIURL("/containers/"+name+"/start"), request.JSONBody(config))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNoContent)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusNoContent)
 
 	pth, err := inspectMountSourceField(name, volPath)
 	c.Assert(err, checker.IsNil)
@@ -127,9 +136,9 @@ func (s *DockerSuite) TestDeprecatedPostContainerBindNormalVolume(c *check.C) {
 	dockerCmd(c, "create", "-v", "/foo", "--name=two", "busybox")
 
 	bindSpec := map[string][]string{"Binds": {fooDir + ":/foo"}}
-	status, _, err := request.SockRequest("POST", formatV123StartAPIURL("/containers/two/start"), bindSpec, daemonHost())
+	res, _, err := request.Post(formatV123StartAPIURL("/containers/two/start"), request.JSONBody(bindSpec))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNoContent)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusNoContent)
 
 	fooDir2, err := inspectMountSourceField("two", "/foo")
 	c.Assert(err, checker.IsNil)

+ 1 - 1
integration-cli/docker_deprecated_api_v124_unix_test.go

@@ -22,7 +22,7 @@ func (s *DockerNetworkSuite) TestDeprecatedDockerNetworkStartAPIWithHostconfig(c
 			"NetworkMode": netName,
 		},
 	}
-	_, _, err := request.SockRequest("POST", formatV123StartAPIURL("/containers/"+conName+"/start"), config, daemonHost())
+	_, _, err := request.Post(formatV123StartAPIURL("/containers/"+conName+"/start"), request.JSONBody(config))
 	c.Assert(err, checker.IsNil)
 	c.Assert(waitRun(conName), checker.IsNil)
 	networks := inspectField(c, conName, "NetworkSettings.Networks")

+ 17 - 21
integration-cli/docker_utils_test.go

@@ -15,6 +15,7 @@ import (
 	"time"
 
 	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/daemon"
@@ -22,6 +23,7 @@ import (
 	"github.com/docker/docker/integration-cli/request"
 	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 // Deprecated
@@ -267,17 +269,12 @@ func daemonTime(c *check.C) time.Time {
 	if testEnv.LocalDaemon() {
 		return time.Now()
 	}
-
-	status, body, err := request.SockRequest("GET", "/info", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusOK)
+	defer cli.Close()
 
-	type infoJSON struct {
-		SystemTime string
-	}
-	var info infoJSON
-	err = json.Unmarshal(body, &info)
-	c.Assert(err, check.IsNil, check.Commentf("unable to unmarshal GET /info response"))
+	info, err := cli.Info(context.Background())
+	c.Assert(err, check.IsNil)
 
 	dt, err := time.Parse(time.RFC3339Nano, info.SystemTime)
 	c.Assert(err, check.IsNil, check.Commentf("invalid time format in GET /info response"))
@@ -376,10 +373,12 @@ func waitInspectWithArgs(name, expr, expected string, timeout time.Duration, arg
 }
 
 func getInspectBody(c *check.C, version, id string) []byte {
-	endpoint := fmt.Sprintf("/%s/containers/%s/json", version, id)
-	status, body, err := request.SockRequest("GET", endpoint, nil, daemonHost())
+	var httpClient *http.Client
+	cli, err := client.NewClient(daemonHost(), version, httpClient, nil)
+	c.Assert(err, check.IsNil)
+	defer cli.Close()
+	_, body, err := cli.ContainerInspectWithRaw(context.Background(), id, false)
 	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusOK)
 	return body
 }
 
@@ -406,20 +405,17 @@ func minimalBaseImage() string {
 }
 
 func getGoroutineNumber() (int, error) {
-	i := struct {
-		NGoroutines int
-	}{}
-	status, b, err := request.SockRequest("GET", "/info", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	if err != nil {
 		return 0, err
 	}
-	if status != http.StatusOK {
-		return 0, fmt.Errorf("http status code: %d", status)
-	}
-	if err := json.Unmarshal(b, &i); err != nil {
+	defer cli.Close()
+
+	info, err := cli.Info(context.Background())
+	if err != nil {
 		return 0, err
 	}
-	return i.NGoroutines, nil
+	return info.NGoroutines, nil
 }
 
 func waitForGoroutines(expected int) error {

+ 28 - 46
integration-cli/environment/clean.go

@@ -1,16 +1,14 @@
 package environment
 
 import (
-	"encoding/json"
-	"fmt"
-	"net/http"
 	"regexp"
 	"strings"
 
 	"github.com/docker/docker/api/types"
-	volumetypes "github.com/docker/docker/api/types/volume"
-	"github.com/docker/docker/integration-cli/request"
+	"github.com/docker/docker/api/types/filters"
+	"github.com/docker/docker/client"
 	icmd "github.com/docker/docker/pkg/testutil/cmd"
+	"golang.org/x/net/context"
 )
 
 type testingT interface {
@@ -26,15 +24,21 @@ type logT interface {
 // and removing everything else. It's meant to run after any tests so that they don't
 // depend on each others.
 func (e *Execution) Clean(t testingT, dockerBinary string) {
+	cli, err := client.NewEnvClient()
+	if err != nil {
+		t.Fatalf("%v", err)
+	}
+	defer cli.Close()
+
 	if (e.DaemonPlatform() != "windows") || (e.DaemonPlatform() == "windows" && e.Isolation() == "hyperv") {
 		unpauseAllContainers(t, dockerBinary)
 	}
 	deleteAllContainers(t, dockerBinary)
 	deleteAllImages(t, dockerBinary, e.protectedElements.images)
-	deleteAllVolumes(t, dockerBinary)
-	deleteAllNetworks(t, dockerBinary, e.DaemonPlatform())
+	deleteAllVolumes(t, cli)
+	deleteAllNetworks(t, cli, e.DaemonPlatform())
 	if e.DaemonPlatform() == "linux" {
-		deleteAllPlugins(t, dockerBinary)
+		deleteAllPlugins(t, cli, dockerBinary)
 	}
 }
 
@@ -108,41 +112,34 @@ func deleteAllImages(t testingT, dockerBinary string, protectedImages map[string
 	}
 }
 
-func deleteAllVolumes(t testingT, dockerBinary string) {
-	volumes, err := getAllVolumes()
+func deleteAllVolumes(t testingT, c client.APIClient) {
+	var errs []string
+	volumes, err := getAllVolumes(c)
 	if err != nil {
 		t.Fatalf("%v", err)
 	}
-	var errs []string
 	for _, v := range volumes {
-		status, b, err := request.SockRequest("DELETE", "/volumes/"+v.Name, nil, request.DaemonHost())
+		err := c.VolumeRemove(context.Background(), v.Name, true)
 		if err != nil {
 			errs = append(errs, err.Error())
 			continue
 		}
-		if status != http.StatusNoContent {
-			errs = append(errs, fmt.Sprintf("error deleting volume %s: %s", v.Name, string(b)))
-		}
 	}
 	if len(errs) > 0 {
 		t.Fatalf("%v", strings.Join(errs, "\n"))
 	}
 }
 
-func getAllVolumes() ([]*types.Volume, error) {
-	var volumes volumetypes.VolumesListOKBody
-	_, b, err := request.SockRequest("GET", "/volumes", nil, request.DaemonHost())
+func getAllVolumes(c client.APIClient) ([]*types.Volume, error) {
+	volumes, err := c.VolumeList(context.Background(), filters.Args{})
 	if err != nil {
 		return nil, err
 	}
-	if err := json.Unmarshal(b, &volumes); err != nil {
-		return nil, err
-	}
 	return volumes.Volumes, nil
 }
 
-func deleteAllNetworks(t testingT, dockerBinary string, daemonPlatform string) {
-	networks, err := getAllNetworks()
+func deleteAllNetworks(t testingT, c client.APIClient, daemonPlatform string) {
+	networks, err := getAllNetworks(c)
 	if err != nil {
 		t.Fatalf("%v", err)
 	}
@@ -155,62 +152,47 @@ func deleteAllNetworks(t testingT, dockerBinary string, daemonPlatform string) {
 			// nat is a pre-defined network on Windows and cannot be removed
 			continue
 		}
-		status, b, err := request.SockRequest("DELETE", "/networks/"+n.Name, nil, request.DaemonHost())
+		err := c.NetworkRemove(context.Background(), n.ID)
 		if err != nil {
 			errs = append(errs, err.Error())
 			continue
 		}
-		if status != http.StatusNoContent {
-			errs = append(errs, fmt.Sprintf("error deleting network %s: %s", n.Name, string(b)))
-		}
 	}
 	if len(errs) > 0 {
 		t.Fatalf("%v", strings.Join(errs, "\n"))
 	}
 }
 
-func getAllNetworks() ([]types.NetworkResource, error) {
-	var networks []types.NetworkResource
-	_, b, err := request.SockRequest("GET", "/networks", nil, request.DaemonHost())
+func getAllNetworks(c client.APIClient) ([]types.NetworkResource, error) {
+	networks, err := c.NetworkList(context.Background(), types.NetworkListOptions{})
 	if err != nil {
 		return nil, err
 	}
-	if err := json.Unmarshal(b, &networks); err != nil {
-		return nil, err
-	}
 	return networks, nil
 }
 
-func deleteAllPlugins(t testingT, dockerBinary string) {
-	plugins, err := getAllPlugins()
+func deleteAllPlugins(t testingT, c client.APIClient, dockerBinary string) {
+	plugins, err := getAllPlugins(c)
 	if err != nil {
 		t.Fatalf("%v", err)
 	}
 	var errs []string
 	for _, p := range plugins {
-		pluginName := p.Name
-		status, b, err := request.SockRequest("DELETE", "/plugins/"+pluginName+"?force=1", nil, request.DaemonHost())
+		err := c.PluginRemove(context.Background(), p.Name, types.PluginRemoveOptions{Force: true})
 		if err != nil {
 			errs = append(errs, err.Error())
 			continue
 		}
-		if status != http.StatusOK {
-			errs = append(errs, fmt.Sprintf("error deleting plugin %s: %s", p.Name, string(b)))
-		}
 	}
 	if len(errs) > 0 {
 		t.Fatalf("%v", strings.Join(errs, "\n"))
 	}
 }
 
-func getAllPlugins() (types.PluginsListResponse, error) {
-	var plugins types.PluginsListResponse
-	_, b, err := request.SockRequest("GET", "/plugins", nil, request.DaemonHost())
+func getAllPlugins(c client.APIClient) (types.PluginsListResponse, error) {
+	plugins, err := c.PluginList(context.Background(), filters.Args{})
 	if err != nil {
 		return nil, err
 	}
-	if err := json.Unmarshal(b, &plugins); err != nil {
-		return nil, err
-	}
 	return plugins, nil
 }

Some files were not shown because too many files changed in this diff