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