github.com/moby/docker@v26.1.3+incompatible/client/container_create_test.go (about)

     1  package client // import "github.com/docker/docker/client"
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"encoding/json"
     7  	"fmt"
     8  	"io"
     9  	"net/http"
    10  	"strings"
    11  	"testing"
    12  
    13  	"github.com/docker/docker/api/types/container"
    14  	"github.com/docker/docker/errdefs"
    15  	"gotest.tools/v3/assert"
    16  	is "gotest.tools/v3/assert/cmp"
    17  )
    18  
    19  func TestContainerCreateError(t *testing.T) {
    20  	client := &Client{
    21  		client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
    22  	}
    23  	_, err := client.ContainerCreate(context.Background(), nil, nil, nil, nil, "nothing")
    24  	assert.Check(t, is.ErrorType(err, errdefs.IsSystem))
    25  
    26  	// 404 doesn't automatically means an unknown image
    27  	client = &Client{
    28  		client: newMockClient(errorMock(http.StatusNotFound, "Server error")),
    29  	}
    30  	_, err = client.ContainerCreate(context.Background(), nil, nil, nil, nil, "nothing")
    31  	assert.Check(t, is.ErrorType(err, errdefs.IsNotFound))
    32  }
    33  
    34  func TestContainerCreateImageNotFound(t *testing.T) {
    35  	client := &Client{
    36  		client: newMockClient(errorMock(http.StatusNotFound, "No such image")),
    37  	}
    38  	_, err := client.ContainerCreate(context.Background(), &container.Config{Image: "unknown_image"}, nil, nil, nil, "unknown")
    39  	assert.Check(t, is.ErrorType(err, errdefs.IsNotFound))
    40  }
    41  
    42  func TestContainerCreateWithName(t *testing.T) {
    43  	expectedURL := "/containers/create"
    44  	client := &Client{
    45  		client: newMockClient(func(req *http.Request) (*http.Response, error) {
    46  			if !strings.HasPrefix(req.URL.Path, expectedURL) {
    47  				return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
    48  			}
    49  			name := req.URL.Query().Get("name")
    50  			if name != "container_name" {
    51  				return nil, fmt.Errorf("container name not set in URL query properly. Expected `container_name`, got %s", name)
    52  			}
    53  			b, err := json.Marshal(container.CreateResponse{
    54  				ID: "container_id",
    55  			})
    56  			if err != nil {
    57  				return nil, err
    58  			}
    59  			return &http.Response{
    60  				StatusCode: http.StatusOK,
    61  				Body:       io.NopCloser(bytes.NewReader(b)),
    62  			}, nil
    63  		}),
    64  	}
    65  
    66  	r, err := client.ContainerCreate(context.Background(), nil, nil, nil, nil, "container_name")
    67  	if err != nil {
    68  		t.Fatal(err)
    69  	}
    70  	if r.ID != "container_id" {
    71  		t.Fatalf("expected `container_id`, got %s", r.ID)
    72  	}
    73  }
    74  
    75  // TestContainerCreateAutoRemove validates that a client using API 1.24 always disables AutoRemove. When using API 1.25
    76  // or up, AutoRemove should not be disabled.
    77  func TestContainerCreateAutoRemove(t *testing.T) {
    78  	autoRemoveValidator := func(expectedValue bool) func(req *http.Request) (*http.Response, error) {
    79  		return func(req *http.Request) (*http.Response, error) {
    80  			var config configWrapper
    81  
    82  			if err := json.NewDecoder(req.Body).Decode(&config); err != nil {
    83  				return nil, err
    84  			}
    85  			if config.HostConfig.AutoRemove != expectedValue {
    86  				return nil, fmt.Errorf("expected AutoRemove to be %v, got %v", expectedValue, config.HostConfig.AutoRemove)
    87  			}
    88  			b, err := json.Marshal(container.CreateResponse{
    89  				ID: "container_id",
    90  			})
    91  			if err != nil {
    92  				return nil, err
    93  			}
    94  			return &http.Response{
    95  				StatusCode: http.StatusOK,
    96  				Body:       io.NopCloser(bytes.NewReader(b)),
    97  			}, nil
    98  		}
    99  	}
   100  
   101  	client := &Client{
   102  		client:  newMockClient(autoRemoveValidator(false)),
   103  		version: "1.24",
   104  	}
   105  	if _, err := client.ContainerCreate(context.Background(), nil, &container.HostConfig{AutoRemove: true}, nil, nil, ""); err != nil {
   106  		t.Fatal(err)
   107  	}
   108  	client = &Client{
   109  		client:  newMockClient(autoRemoveValidator(true)),
   110  		version: "1.25",
   111  	}
   112  	if _, err := client.ContainerCreate(context.Background(), nil, &container.HostConfig{AutoRemove: true}, nil, nil, ""); err != nil {
   113  		t.Fatal(err)
   114  	}
   115  }
   116  
   117  // TestContainerCreateConnection verifies that connection errors occurring
   118  // during API-version negotiation are not shadowed by API-version errors.
   119  //
   120  // Regression test for https://github.com/docker/cli/issues/4890
   121  func TestContainerCreateConnectionError(t *testing.T) {
   122  	client, err := NewClientWithOpts(WithAPIVersionNegotiation(), WithHost("tcp://no-such-host.invalid"))
   123  	assert.NilError(t, err)
   124  
   125  	_, err = client.ContainerCreate(context.Background(), nil, nil, nil, nil, "")
   126  	assert.Check(t, is.ErrorType(err, IsErrConnectionFailed))
   127  }