Signed-off-by: Tibor Vass <teabee89@gmail.com>
| ... | ... |
@@ -3,6 +3,7 @@ package main |
| 3 | 3 |
import ( |
| 4 | 4 |
"os" |
| 5 | 5 |
"os/exec" |
| 6 |
+ "strings" |
|
| 6 | 7 |
"testing" |
| 7 | 8 |
) |
| 8 | 9 |
|
| ... | ... |
@@ -92,6 +93,69 @@ func TestRemoveContainerWithStopAndKill(t *testing.T) {
|
| 92 | 92 |
logDone("rm - with --stop=true and --kill=true")
|
| 93 | 93 |
} |
| 94 | 94 |
|
| 95 |
+func TestContainerOrphaning(t *testing.T) {
|
|
| 96 |
+ dockerfile1 := `FROM busybox:latest |
|
| 97 |
+ ENTRYPOINT ["/bin/true"]` |
|
| 98 |
+ img := "test-container-orphaning" |
|
| 99 |
+ dockerfile2 := `FROM busybox:latest |
|
| 100 |
+ ENTRYPOINT ["/bin/true"] |
|
| 101 |
+ MAINTAINER Integration Tests` |
|
| 102 |
+ |
|
| 103 |
+ // build first dockerfile |
|
| 104 |
+ img1, err := buildImage(img, dockerfile1, true) |
|
| 105 |
+ if err != nil {
|
|
| 106 |
+ t.Fatalf("Could not build image %s: %v", img, err)
|
|
| 107 |
+ } |
|
| 108 |
+ // run container on first image |
|
| 109 |
+ if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", img)); err != nil {
|
|
| 110 |
+ t.Fatalf("Could not run image %s: %v: %s", img, err, out)
|
|
| 111 |
+ } |
|
| 112 |
+ // rebuild dockerfile with a small addition at the end |
|
| 113 |
+ if _, err := buildImage(img, dockerfile2, true); err != nil {
|
|
| 114 |
+ t.Fatalf("Could not rebuild image %s: %v", img, err)
|
|
| 115 |
+ } |
|
| 116 |
+ // try to remove the image, should error out. |
|
| 117 |
+ if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "rmi", img)); err == nil {
|
|
| 118 |
+ t.Fatalf("Expected to error out removing the image, but succeeded: %s", out)
|
|
| 119 |
+ } |
|
| 120 |
+ // check if we deleted the first image |
|
| 121 |
+ out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "images", "-q", "--no-trunc")) |
|
| 122 |
+ if err != nil {
|
|
| 123 |
+ t.Fatalf("%v: %s", err, out)
|
|
| 124 |
+ } |
|
| 125 |
+ if !strings.Contains(out, img1) {
|
|
| 126 |
+ t.Fatal("Orphaned container (could not find '%s' in docker images): %s", img1, out)
|
|
| 127 |
+ } |
|
| 128 |
+ |
|
| 129 |
+ deleteAllContainers() |
|
| 130 |
+ |
|
| 131 |
+ logDone("rm - container orphaning")
|
|
| 132 |
+} |
|
| 133 |
+ |
|
| 134 |
+func TestDeleteTagWithExistingContainers(t *testing.T) {
|
|
| 135 |
+ container := "test-delete-tag" |
|
| 136 |
+ newtag := "busybox:newtag" |
|
| 137 |
+ bb := "busybox:latest" |
|
| 138 |
+ if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "tag", bb, newtag)); err != nil {
|
|
| 139 |
+ t.Fatalf("Could not tag busybox: %v: %s", err, out)
|
|
| 140 |
+ } |
|
| 141 |
+ if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--name", container, bb, "/bin/true")); err != nil {
|
|
| 142 |
+ t.Fatalf("Could not run busybox: %v: %s", err, out)
|
|
| 143 |
+ } |
|
| 144 |
+ out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "rmi", newtag)) |
|
| 145 |
+ if err != nil {
|
|
| 146 |
+ t.Fatalf("Could not remove tag %s: %v: %s", newtag, err, out)
|
|
| 147 |
+ } |
|
| 148 |
+ if d := strings.Count(out, "Untagged: "); d != 1 {
|
|
| 149 |
+ t.Fatalf("Expected 1 untagged entry got %d: %q", d, out)
|
|
| 150 |
+ } |
|
| 151 |
+ |
|
| 152 |
+ deleteAllContainers() |
|
| 153 |
+ |
|
| 154 |
+ logDone("rm - delete tag with existing containers")
|
|
| 155 |
+ |
|
| 156 |
+} |
|
| 157 |
+ |
|
| 95 | 158 |
func createRunningContainer(t *testing.T, name string) {
|
| 96 | 159 |
cmd := exec.Command(dockerBinary, "run", "-dt", "--name", name, "busybox", "top") |
| 97 | 160 |
if _, err := runCommand(cmd); err != nil {
|
| ... | ... |
@@ -13,7 +13,6 @@ import ( |
| 13 | 13 |
|
| 14 | 14 |
"github.com/docker/docker/api/client" |
| 15 | 15 |
"github.com/docker/docker/daemon" |
| 16 |
- "github.com/docker/docker/engine" |
|
| 17 | 16 |
"github.com/docker/docker/pkg/term" |
| 18 | 17 |
"github.com/docker/docker/utils" |
| 19 | 18 |
) |
| ... | ... |
@@ -682,70 +681,3 @@ func TestRunCidFileCleanupIfEmpty(t *testing.T) {
|
| 682 | 682 |
<-c |
| 683 | 683 |
}) |
| 684 | 684 |
} |
| 685 |
- |
|
| 686 |
-func TestContainerOrphaning(t *testing.T) {
|
|
| 687 |
- |
|
| 688 |
- // setup a temporary directory |
|
| 689 |
- tmpDir, err := ioutil.TempDir("", "project")
|
|
| 690 |
- if err != nil {
|
|
| 691 |
- t.Fatal(err) |
|
| 692 |
- } |
|
| 693 |
- defer os.RemoveAll(tmpDir) |
|
| 694 |
- |
|
| 695 |
- // setup a CLI and server |
|
| 696 |
- cli := client.NewDockerCli(nil, ioutil.Discard, ioutil.Discard, testDaemonProto, testDaemonAddr, nil) |
|
| 697 |
- defer cleanup(globalEngine, t) |
|
| 698 |
- srv := mkServerFromEngine(globalEngine, t) |
|
| 699 |
- |
|
| 700 |
- // closure to build something |
|
| 701 |
- buildSomething := func(template string, image string) string {
|
|
| 702 |
- dockerfile := path.Join(tmpDir, "Dockerfile") |
|
| 703 |
- replacer := strings.NewReplacer("{IMAGE}", unitTestImageID)
|
|
| 704 |
- contents := replacer.Replace(template) |
|
| 705 |
- ioutil.WriteFile(dockerfile, []byte(contents), 0x777) |
|
| 706 |
- if err := cli.CmdBuild("-t", image, tmpDir); err != nil {
|
|
| 707 |
- t.Fatal(err) |
|
| 708 |
- } |
|
| 709 |
- job := globalEngine.Job("image_get", image)
|
|
| 710 |
- info, _ := job.Stdout.AddEnv() |
|
| 711 |
- if err := job.Run(); err != nil {
|
|
| 712 |
- t.Fatal(err) |
|
| 713 |
- } |
|
| 714 |
- return info.Get("Id")
|
|
| 715 |
- } |
|
| 716 |
- |
|
| 717 |
- // build an image |
|
| 718 |
- imageName := "orphan-test" |
|
| 719 |
- template1 := ` |
|
| 720 |
- from {IMAGE}
|
|
| 721 |
- cmd ["/bin/echo", "holla"] |
|
| 722 |
- ` |
|
| 723 |
- img1 := buildSomething(template1, imageName) |
|
| 724 |
- |
|
| 725 |
- // create a container using the fist image |
|
| 726 |
- if err := cli.CmdRun(imageName); err != nil {
|
|
| 727 |
- t.Fatal(err) |
|
| 728 |
- } |
|
| 729 |
- |
|
| 730 |
- // build a new image that splits lineage |
|
| 731 |
- template2 := ` |
|
| 732 |
- from {IMAGE}
|
|
| 733 |
- cmd ["/bin/echo", "holla"] |
|
| 734 |
- expose 22 |
|
| 735 |
- ` |
|
| 736 |
- buildSomething(template2, imageName) |
|
| 737 |
- |
|
| 738 |
- // remove the second image by name |
|
| 739 |
- resp := engine.NewTable("", 0)
|
|
| 740 |
- if err := srv.DeleteImage(imageName, resp, true, false, false); err == nil {
|
|
| 741 |
- t.Fatal("Expected error, got none")
|
|
| 742 |
- } |
|
| 743 |
- |
|
| 744 |
- // see if we deleted the first image (and orphaned the container) |
|
| 745 |
- for _, i := range resp.Data {
|
|
| 746 |
- if img1 == i.Get("Deleted") {
|
|
| 747 |
- t.Fatal("Orphaned image with container")
|
|
| 748 |
- } |
|
| 749 |
- } |
|
| 750 |
- |
|
| 751 |
-} |
| ... | ... |
@@ -297,56 +297,3 @@ func TestImagesFilter(t *testing.T) {
|
| 297 | 297 |
t.Fatal("incorrect number of matches returned")
|
| 298 | 298 |
} |
| 299 | 299 |
} |
| 300 |
- |
|
| 301 |
-// Regression test for being able to untag an image with an existing |
|
| 302 |
-// container |
|
| 303 |
-func TestDeleteTagWithExistingContainers(t *testing.T) {
|
|
| 304 |
- eng := NewTestEngine(t) |
|
| 305 |
- defer nuke(mkDaemonFromEngine(eng, t)) |
|
| 306 |
- |
|
| 307 |
- srv := mkServerFromEngine(eng, t) |
|
| 308 |
- |
|
| 309 |
- // Tag the image |
|
| 310 |
- if err := eng.Job("tag", unitTestImageID, "utest", "tag1").Run(); err != nil {
|
|
| 311 |
- t.Fatal(err) |
|
| 312 |
- } |
|
| 313 |
- |
|
| 314 |
- // Create a container from the image |
|
| 315 |
- config, _, _, err := runconfig.Parse([]string{unitTestImageID, "echo test"}, nil)
|
|
| 316 |
- if err != nil {
|
|
| 317 |
- t.Fatal(err) |
|
| 318 |
- } |
|
| 319 |
- |
|
| 320 |
- id := createNamedTestContainer(eng, config, t, "testingtags") |
|
| 321 |
- if id == "" {
|
|
| 322 |
- t.Fatal("No id returned")
|
|
| 323 |
- } |
|
| 324 |
- |
|
| 325 |
- job := srv.Eng.Job("containers")
|
|
| 326 |
- job.SetenvBool("all", true)
|
|
| 327 |
- outs, err := job.Stdout.AddListTable() |
|
| 328 |
- if err != nil {
|
|
| 329 |
- t.Fatal(err) |
|
| 330 |
- } |
|
| 331 |
- if err := job.Run(); err != nil {
|
|
| 332 |
- t.Fatal(err) |
|
| 333 |
- } |
|
| 334 |
- |
|
| 335 |
- if len(outs.Data) != 1 {
|
|
| 336 |
- t.Fatalf("Expected 1 container got %d", len(outs.Data))
|
|
| 337 |
- } |
|
| 338 |
- |
|
| 339 |
- // Try to remove the tag |
|
| 340 |
- imgs := engine.NewTable("", 0)
|
|
| 341 |
- if err := srv.DeleteImage("utest:tag1", imgs, true, false, false); err != nil {
|
|
| 342 |
- t.Fatal(err) |
|
| 343 |
- } |
|
| 344 |
- |
|
| 345 |
- if len(imgs.Data) != 1 {
|
|
| 346 |
- t.Fatalf("Should only have deleted one untag %d", len(imgs.Data))
|
|
| 347 |
- } |
|
| 348 |
- |
|
| 349 |
- if untag := imgs.Data[0].Get("Untagged"); untag != "utest:tag1" {
|
|
| 350 |
- t.Fatalf("Expected %s got %s", unitTestImageID, untag)
|
|
| 351 |
- } |
|
| 352 |
-} |