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