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 }