github.com/zhouyu0/docker-note@v0.0.0-20190722021225-b8d3825084db/client/image_build_test.go (about)

     1  package client // import "github.com/docker/docker/client"
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"net/http"
     9  	"reflect"
    10  	"strings"
    11  	"testing"
    12  
    13  	"github.com/docker/docker/api/types"
    14  	"github.com/docker/docker/api/types/container"
    15  	"github.com/docker/go-units"
    16  )
    17  
    18  func TestImageBuildError(t *testing.T) {
    19  	client := &Client{
    20  		client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
    21  	}
    22  	_, err := client.ImageBuild(context.Background(), nil, types.ImageBuildOptions{})
    23  	if err == nil || err.Error() != "Error response from daemon: Server error" {
    24  		t.Fatalf("expected a Server Error, got %v", err)
    25  	}
    26  }
    27  
    28  func TestImageBuild(t *testing.T) {
    29  	v1 := "value1"
    30  	v2 := "value2"
    31  	emptyRegistryConfig := "bnVsbA=="
    32  	buildCases := []struct {
    33  		buildOptions           types.ImageBuildOptions
    34  		expectedQueryParams    map[string]string
    35  		expectedTags           []string
    36  		expectedRegistryConfig string
    37  	}{
    38  		{
    39  			buildOptions: types.ImageBuildOptions{
    40  				SuppressOutput: true,
    41  				NoCache:        true,
    42  				Remove:         true,
    43  				ForceRemove:    true,
    44  				PullParent:     true,
    45  			},
    46  			expectedQueryParams: map[string]string{
    47  				"q":       "1",
    48  				"nocache": "1",
    49  				"rm":      "1",
    50  				"forcerm": "1",
    51  				"pull":    "1",
    52  			},
    53  			expectedTags:           []string{},
    54  			expectedRegistryConfig: emptyRegistryConfig,
    55  		},
    56  		{
    57  			buildOptions: types.ImageBuildOptions{
    58  				SuppressOutput: false,
    59  				NoCache:        false,
    60  				Remove:         false,
    61  				ForceRemove:    false,
    62  				PullParent:     false,
    63  			},
    64  			expectedQueryParams: map[string]string{
    65  				"q":       "",
    66  				"nocache": "",
    67  				"rm":      "0",
    68  				"forcerm": "",
    69  				"pull":    "",
    70  			},
    71  			expectedTags:           []string{},
    72  			expectedRegistryConfig: emptyRegistryConfig,
    73  		},
    74  		{
    75  			buildOptions: types.ImageBuildOptions{
    76  				RemoteContext: "remoteContext",
    77  				Isolation:     container.Isolation("isolation"),
    78  				CPUSetCPUs:    "2",
    79  				CPUSetMems:    "12",
    80  				CPUShares:     20,
    81  				CPUQuota:      10,
    82  				CPUPeriod:     30,
    83  				Memory:        256,
    84  				MemorySwap:    512,
    85  				ShmSize:       10,
    86  				CgroupParent:  "cgroup_parent",
    87  				Dockerfile:    "Dockerfile",
    88  			},
    89  			expectedQueryParams: map[string]string{
    90  				"remote":       "remoteContext",
    91  				"isolation":    "isolation",
    92  				"cpusetcpus":   "2",
    93  				"cpusetmems":   "12",
    94  				"cpushares":    "20",
    95  				"cpuquota":     "10",
    96  				"cpuperiod":    "30",
    97  				"memory":       "256",
    98  				"memswap":      "512",
    99  				"shmsize":      "10",
   100  				"cgroupparent": "cgroup_parent",
   101  				"dockerfile":   "Dockerfile",
   102  				"rm":           "0",
   103  			},
   104  			expectedTags:           []string{},
   105  			expectedRegistryConfig: emptyRegistryConfig,
   106  		},
   107  		{
   108  			buildOptions: types.ImageBuildOptions{
   109  				BuildArgs: map[string]*string{
   110  					"ARG1": &v1,
   111  					"ARG2": &v2,
   112  					"ARG3": nil,
   113  				},
   114  			},
   115  			expectedQueryParams: map[string]string{
   116  				"buildargs": `{"ARG1":"value1","ARG2":"value2","ARG3":null}`,
   117  				"rm":        "0",
   118  			},
   119  			expectedTags:           []string{},
   120  			expectedRegistryConfig: emptyRegistryConfig,
   121  		},
   122  		{
   123  			buildOptions: types.ImageBuildOptions{
   124  				Ulimits: []*units.Ulimit{
   125  					{
   126  						Name: "nproc",
   127  						Hard: 65557,
   128  						Soft: 65557,
   129  					},
   130  					{
   131  						Name: "nofile",
   132  						Hard: 20000,
   133  						Soft: 40000,
   134  					},
   135  				},
   136  			},
   137  			expectedQueryParams: map[string]string{
   138  				"ulimits": `[{"Name":"nproc","Hard":65557,"Soft":65557},{"Name":"nofile","Hard":20000,"Soft":40000}]`,
   139  				"rm":      "0",
   140  			},
   141  			expectedTags:           []string{},
   142  			expectedRegistryConfig: emptyRegistryConfig,
   143  		},
   144  		{
   145  			buildOptions: types.ImageBuildOptions{
   146  				AuthConfigs: map[string]types.AuthConfig{
   147  					"https://index.docker.io/v1/": {
   148  						Auth: "dG90bwo=",
   149  					},
   150  				},
   151  			},
   152  			expectedQueryParams: map[string]string{
   153  				"rm": "0",
   154  			},
   155  			expectedTags:           []string{},
   156  			expectedRegistryConfig: "eyJodHRwczovL2luZGV4LmRvY2tlci5pby92MS8iOnsiYXV0aCI6ImRHOTBid289In19",
   157  		},
   158  	}
   159  	for _, buildCase := range buildCases {
   160  		expectedURL := "/build"
   161  		client := &Client{
   162  			client: newMockClient(func(r *http.Request) (*http.Response, error) {
   163  				if !strings.HasPrefix(r.URL.Path, expectedURL) {
   164  					return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, r.URL)
   165  				}
   166  				// Check request headers
   167  				registryConfig := r.Header.Get("X-Registry-Config")
   168  				if registryConfig != buildCase.expectedRegistryConfig {
   169  					return nil, fmt.Errorf("X-Registry-Config header not properly set in the request. Expected '%s', got %s", buildCase.expectedRegistryConfig, registryConfig)
   170  				}
   171  				contentType := r.Header.Get("Content-Type")
   172  				if contentType != "application/x-tar" {
   173  					return nil, fmt.Errorf("Content-type header not properly set in the request. Expected 'application/x-tar', got %s", contentType)
   174  				}
   175  
   176  				// Check query parameters
   177  				query := r.URL.Query()
   178  				for key, expected := range buildCase.expectedQueryParams {
   179  					actual := query.Get(key)
   180  					if actual != expected {
   181  						return nil, fmt.Errorf("%s not set in URL query properly. Expected '%s', got %s", key, expected, actual)
   182  					}
   183  				}
   184  
   185  				// Check tags
   186  				if len(buildCase.expectedTags) > 0 {
   187  					tags := query["t"]
   188  					if !reflect.DeepEqual(tags, buildCase.expectedTags) {
   189  						return nil, fmt.Errorf("t (tags) not set in URL query properly. Expected '%s', got %s", buildCase.expectedTags, tags)
   190  					}
   191  				}
   192  
   193  				headers := http.Header{}
   194  				headers.Add("Server", "Docker/v1.23 (MyOS)")
   195  				return &http.Response{
   196  					StatusCode: http.StatusOK,
   197  					Body:       ioutil.NopCloser(bytes.NewReader([]byte("body"))),
   198  					Header:     headers,
   199  				}, nil
   200  			}),
   201  		}
   202  		buildResponse, err := client.ImageBuild(context.Background(), nil, buildCase.buildOptions)
   203  		if err != nil {
   204  			t.Fatal(err)
   205  		}
   206  		if buildResponse.OSType != "MyOS" {
   207  			t.Fatalf("expected OSType to be 'MyOS', got %s", buildResponse.OSType)
   208  		}
   209  		response, err := ioutil.ReadAll(buildResponse.Body)
   210  		if err != nil {
   211  			t.Fatal(err)
   212  		}
   213  		buildResponse.Body.Close()
   214  		if string(response) != "body" {
   215  			t.Fatalf("expected Body to contain 'body' string, got %s", response)
   216  		}
   217  	}
   218  }
   219  
   220  func TestGetDockerOS(t *testing.T) {
   221  	cases := map[string]string{
   222  		"Docker/v1.22 (linux)":   "linux",
   223  		"Docker/v1.22 (windows)": "windows",
   224  		"Foo/v1.22 (bar)":        "",
   225  	}
   226  	for header, os := range cases {
   227  		g := getDockerOS(header)
   228  		if g != os {
   229  			t.Fatalf("Expected %s, got %s", os, g)
   230  		}
   231  	}
   232  }