github.com/beornf/libcompose@v0.4.1-0.20210215180846-a59802c0f07c/docker/builder/builder_test.go (about) 1 package builder 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "io" 8 "io/ioutil" 9 "os" 10 "path/filepath" 11 "testing" 12 13 "golang.org/x/net/context" 14 15 "github.com/docker/docker/api/types" 16 "github.com/docker/docker/client" 17 "github.com/docker/docker/pkg/archive" 18 "github.com/docker/docker/pkg/jsonmessage" 19 "github.com/pkg/errors" 20 "strings" 21 ) 22 23 type daemonClient struct { 24 client.Client 25 contextDir string 26 imageName string 27 changes int 28 message jsonmessage.JSONMessage 29 } 30 31 func (c *daemonClient) ImageBuild(ctx context.Context, context io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error) { 32 if c.imageName != "" { 33 if len(options.Tags) != 1 || options.Tags[0] != c.imageName { 34 return types.ImageBuildResponse{}, fmt.Errorf("expected image %q, got %v", c.imageName, options.Tags) 35 } 36 } 37 if c.contextDir != "" { 38 tmp, err := ioutil.TempDir("", "image-build-test") 39 if err != nil { 40 return types.ImageBuildResponse{}, err 41 } 42 if err := archive.Untar(context, tmp, nil); err != nil { 43 return types.ImageBuildResponse{}, err 44 } 45 changes, err := archive.ChangesDirs(tmp, c.contextDir) 46 if err != nil { 47 return types.ImageBuildResponse{}, err 48 } 49 if len(changes) != c.changes { 50 return types.ImageBuildResponse{}, fmt.Errorf("expected %d changes, got %v", c.changes, changes) 51 } 52 b, err := json.Marshal(c.message) 53 if err != nil { 54 return types.ImageBuildResponse{}, err 55 } 56 return types.ImageBuildResponse{ 57 Body: ioutil.NopCloser(bytes.NewReader(b)), 58 }, nil 59 } 60 return types.ImageBuildResponse{ 61 Body: ioutil.NopCloser(strings.NewReader("{}")), 62 }, errors.New("Engine no longer exists") 63 } 64 65 func TestBuildInvalidContextDirectoryOrDockerfile(t *testing.T) { 66 tmpDir, err := ioutil.TempDir("", "daemonbuilder-test") 67 if err != nil { 68 t.Fatal(err) 69 } 70 testCases := []struct { 71 contextDirectory string 72 dockerfile string 73 expected string 74 }{ 75 { 76 contextDirectory: "", 77 dockerfile: "", 78 expected: "Cannot locate Dockerfile: Dockerfile", 79 }, 80 { 81 contextDirectory: "", 82 dockerfile: "test.Dockerfile", 83 expected: "Cannot locate Dockerfile: test.Dockerfile", 84 }, 85 { 86 contextDirectory: "/I/DONT/EXISTS", 87 dockerfile: "", 88 expected: "Cannot locate Dockerfile: Dockerfile", 89 }, 90 { 91 contextDirectory: "/I/DONT/EXISTS", 92 dockerfile: "test.Dockerfile", 93 expected: "Cannot locate Dockerfile: /I/DONT/EXISTS/test.Dockerfile", 94 }, 95 { 96 contextDirectory: tmpDir, 97 dockerfile: "test.Dockerfile", 98 expected: "Cannot locate Dockerfile: " + filepath.Join(tmpDir, "test.Dockerfile"), 99 }, 100 } 101 for _, c := range testCases { 102 builder := &DaemonBuilder{ 103 ContextDirectory: c.contextDirectory, 104 Dockerfile: c.dockerfile, 105 } 106 err := builder.Build(context.Background(), "image") 107 if err == nil || err.Error() != c.expected { 108 t.Fatalf("expected an error %q, got %s", c.expected, err) 109 } 110 111 } 112 } 113 114 func TestBuildWithClientBuildError(t *testing.T) { 115 tmpDir, err := ioutil.TempDir("", "daemonbuilder-test") 116 if err != nil { 117 t.Fatal(err) 118 } 119 defer os.RemoveAll(tmpDir) 120 if err := ioutil.WriteFile(filepath.Join(tmpDir, DefaultDockerfileName), []byte("FROM busybox"), 0700); err != nil { 121 t.Fatal(err) 122 } 123 124 imageName := "image" 125 client := &daemonClient{} 126 builder := &DaemonBuilder{ 127 ContextDirectory: tmpDir, 128 Client: client, 129 } 130 131 err = builder.Build(context.Background(), imageName) 132 if err == nil || err.Error() != "Engine no longer exists" { 133 t.Fatalf("expected an 'Engine no longer exists', got %s", err) 134 } 135 } 136 137 func TestBuildWithDefaultDockerfile(t *testing.T) { 138 tmpDir, err := ioutil.TempDir("", "daemonbuilder-test") 139 if err != nil { 140 t.Fatal(err) 141 } 142 defer os.RemoveAll(tmpDir) 143 if err := ioutil.WriteFile(filepath.Join(tmpDir, DefaultDockerfileName), []byte("FROM busybox"), 0700); err != nil { 144 t.Fatal(err) 145 } 146 if err := ioutil.WriteFile(filepath.Join(tmpDir, "afile"), []byte("another file"), 0700); err != nil { 147 t.Fatal(err) 148 } 149 150 imageName := "image" 151 client := &daemonClient{ 152 contextDir: tmpDir, 153 imageName: imageName, 154 } 155 builder := &DaemonBuilder{ 156 ContextDirectory: tmpDir, 157 Client: client, 158 } 159 160 err = builder.Build(context.Background(), imageName) 161 if err != nil { 162 t.Fatal(err) 163 } 164 } 165 166 func TestBuildWithDefaultLowercaseDockerfile(t *testing.T) { 167 tmpDir, err := ioutil.TempDir("", "daemonbuilder-test") 168 if err != nil { 169 t.Fatal(err) 170 } 171 defer os.RemoveAll(tmpDir) 172 if err := ioutil.WriteFile(filepath.Join(tmpDir, "dockerfile"), []byte("FROM busybox"), 0700); err != nil { 173 t.Fatal(err) 174 } 175 if err := ioutil.WriteFile(filepath.Join(tmpDir, "afile"), []byte("another file"), 0700); err != nil { 176 t.Fatal(err) 177 } 178 179 imageName := "image" 180 client := &daemonClient{ 181 contextDir: tmpDir, 182 imageName: imageName, 183 } 184 builder := &DaemonBuilder{ 185 ContextDirectory: tmpDir, 186 Client: client, 187 } 188 189 err = builder.Build(context.Background(), imageName) 190 if err != nil { 191 t.Fatal(err) 192 } 193 } 194 195 func TestBuildWithSpecificDockerfile(t *testing.T) { 196 tmpDir, err := ioutil.TempDir("", "daemonbuilder-test") 197 if err != nil { 198 t.Fatal(err) 199 } 200 defer os.RemoveAll(tmpDir) 201 if err := ioutil.WriteFile(filepath.Join(tmpDir, "test.Dockerfile"), []byte("FROM busybox"), 0700); err != nil { 202 t.Fatal(err) 203 } 204 if err := ioutil.WriteFile(filepath.Join(tmpDir, "afile"), []byte("another file"), 0700); err != nil { 205 t.Fatal(err) 206 } 207 208 imageName := "image" 209 client := &daemonClient{ 210 contextDir: tmpDir, 211 imageName: imageName, 212 } 213 builder := &DaemonBuilder{ 214 ContextDirectory: tmpDir, 215 Dockerfile: "test.Dockerfile", 216 Client: client, 217 } 218 219 err = builder.Build(context.Background(), imageName) 220 if err != nil { 221 t.Fatal(err) 222 } 223 } 224 225 func TestBuildWithDockerignoreNothing(t *testing.T) { 226 tmpDir, err := ioutil.TempDir("", "daemonbuilder-test") 227 if err != nil { 228 t.Fatal(err) 229 } 230 defer os.RemoveAll(tmpDir) 231 if err := ioutil.WriteFile(filepath.Join(tmpDir, "test.Dockerfile"), []byte("FROM busybox"), 0700); err != nil { 232 t.Fatal(err) 233 } 234 if err := ioutil.WriteFile(filepath.Join(tmpDir, "afile"), []byte("another file"), 0700); err != nil { 235 t.Fatal(err) 236 } 237 if err := ioutil.WriteFile(filepath.Join(tmpDir, ".dockerignore"), []byte(""), 0700); err != nil { 238 t.Fatal(err) 239 } 240 241 imageName := "image" 242 client := &daemonClient{ 243 contextDir: tmpDir, 244 imageName: imageName, 245 } 246 builder := &DaemonBuilder{ 247 ContextDirectory: tmpDir, 248 Dockerfile: "test.Dockerfile", 249 Client: client, 250 } 251 252 err = builder.Build(context.Background(), imageName) 253 if err != nil { 254 t.Fatal(err) 255 } 256 } 257 258 func TestBuildWithDockerignoreDockerfileAndItself(t *testing.T) { 259 tmpDir, err := ioutil.TempDir("", "daemonbuilder-test") 260 if err != nil { 261 t.Fatal(err) 262 } 263 defer os.RemoveAll(tmpDir) 264 if err := ioutil.WriteFile(filepath.Join(tmpDir, "test.Dockerfile"), []byte("FROM busybox"), 0700); err != nil { 265 t.Fatal(err) 266 } 267 if err := ioutil.WriteFile(filepath.Join(tmpDir, "afile"), []byte("another file"), 0700); err != nil { 268 t.Fatal(err) 269 } 270 if err := ioutil.WriteFile(filepath.Join(tmpDir, ".dockerignore"), []byte("Dockerfile\n.dockerignore"), 0700); err != nil { 271 t.Fatal(err) 272 } 273 274 imageName := "image" 275 client := &daemonClient{ 276 contextDir: tmpDir, 277 imageName: imageName, 278 } 279 builder := &DaemonBuilder{ 280 ContextDirectory: tmpDir, 281 Dockerfile: "test.Dockerfile", 282 Client: client, 283 } 284 285 err = builder.Build(context.Background(), imageName) 286 if err != nil { 287 t.Fatal(err) 288 } 289 } 290 291 func TestBuildWithDockerignoreAfile(t *testing.T) { 292 tmpDir, err := ioutil.TempDir("", "daemonbuilder-test") 293 if err != nil { 294 t.Fatal(err) 295 } 296 defer os.RemoveAll(tmpDir) 297 if err := ioutil.WriteFile(filepath.Join(tmpDir, "test.Dockerfile"), []byte("FROM busybox"), 0700); err != nil { 298 t.Fatal(err) 299 } 300 if err := ioutil.WriteFile(filepath.Join(tmpDir, "afile"), []byte("another file"), 0700); err != nil { 301 t.Fatal(err) 302 } 303 if err := ioutil.WriteFile(filepath.Join(tmpDir, ".dockerignore"), []byte("afile"), 0700); err != nil { 304 t.Fatal(err) 305 } 306 307 imageName := "image" 308 client := &daemonClient{ 309 contextDir: tmpDir, 310 imageName: imageName, 311 changes: 1, 312 } 313 builder := &DaemonBuilder{ 314 ContextDirectory: tmpDir, 315 Dockerfile: "test.Dockerfile", 316 Client: client, 317 } 318 319 err = builder.Build(context.Background(), imageName) 320 if err != nil { 321 t.Fatal(err) 322 } 323 } 324 325 func TestBuildWithErrorJSONMessage(t *testing.T) { 326 tmpDir, err := ioutil.TempDir("", "daemonbuilder-test") 327 if err != nil { 328 t.Fatal(err) 329 } 330 defer os.RemoveAll(tmpDir) 331 if err := ioutil.WriteFile(filepath.Join(tmpDir, DefaultDockerfileName), []byte("FROM busybox"), 0700); err != nil { 332 t.Fatal(err) 333 } 334 if err := ioutil.WriteFile(filepath.Join(tmpDir, "afile"), []byte("another file"), 0700); err != nil { 335 t.Fatal(err) 336 } 337 338 imageName := "image" 339 client := &daemonClient{ 340 contextDir: tmpDir, 341 imageName: imageName, 342 message: jsonmessage.JSONMessage{ 343 Error: &jsonmessage.JSONError{ 344 Code: 0, 345 Message: "error", 346 }, 347 }, 348 } 349 builder := &DaemonBuilder{ 350 ContextDirectory: tmpDir, 351 Client: client, 352 } 353 354 err = builder.Build(context.Background(), imageName) 355 expectedError := "Status: error, Code: 1" 356 if err == nil || err.Error() != expectedError { 357 t.Fatalf("expected an error about %q, got %s", expectedError, err) 358 } 359 }