github.com/endophage/docker@v1.4.2-0.20161027011718-242853499895/client/image_build_test.go (about)

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