github.com/walkingsparrow/docker@v1.4.2-0.20151218153551-b708a2249bfa/integration-cli/docker_cli_pull_local_test.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "os/exec" 6 "strings" 7 8 "github.com/docker/docker/pkg/integration/checker" 9 "github.com/go-check/check" 10 ) 11 12 // TestPullImageWithAliases pulls a specific image tag and verifies that any aliases (i.e., other 13 // tags for the same image) are not also pulled down. 14 // 15 // Ref: docker/docker#8141 16 func (s *DockerRegistrySuite) TestPullImageWithAliases(c *check.C) { 17 repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL) 18 19 repos := []string{} 20 for _, tag := range []string{"recent", "fresh"} { 21 repos = append(repos, fmt.Sprintf("%v:%v", repoName, tag)) 22 } 23 24 // Tag and push the same image multiple times. 25 for _, repo := range repos { 26 dockerCmd(c, "tag", "busybox", repo) 27 dockerCmd(c, "push", repo) 28 } 29 30 // Clear local images store. 31 args := append([]string{"rmi"}, repos...) 32 dockerCmd(c, args...) 33 34 // Pull a single tag and verify it doesn't bring down all aliases. 35 dockerCmd(c, "pull", repos[0]) 36 dockerCmd(c, "inspect", repos[0]) 37 for _, repo := range repos[1:] { 38 _, _, err := dockerCmdWithError("inspect", repo) 39 c.Assert(err, checker.NotNil, check.Commentf("Image %v shouldn't have been pulled down", repo)) 40 } 41 } 42 43 // TestConcurrentPullWholeRepo pulls the same repo concurrently. 44 func (s *DockerRegistrySuite) TestConcurrentPullWholeRepo(c *check.C) { 45 repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL) 46 47 repos := []string{} 48 for _, tag := range []string{"recent", "fresh", "todays"} { 49 repo := fmt.Sprintf("%v:%v", repoName, tag) 50 _, err := buildImage(repo, fmt.Sprintf(` 51 FROM busybox 52 ENTRYPOINT ["/bin/echo"] 53 ENV FOO foo 54 ENV BAR bar 55 CMD echo %s 56 `, repo), true) 57 c.Assert(err, checker.IsNil) 58 dockerCmd(c, "push", repo) 59 repos = append(repos, repo) 60 } 61 62 // Clear local images store. 63 args := append([]string{"rmi"}, repos...) 64 dockerCmd(c, args...) 65 66 // Run multiple re-pulls concurrently 67 results := make(chan error) 68 numPulls := 3 69 70 for i := 0; i != numPulls; i++ { 71 go func() { 72 _, _, err := runCommandWithOutput(exec.Command(dockerBinary, "pull", "-a", repoName)) 73 results <- err 74 }() 75 } 76 77 // These checks are separate from the loop above because the check 78 // package is not goroutine-safe. 79 for i := 0; i != numPulls; i++ { 80 err := <-results 81 c.Assert(err, checker.IsNil, check.Commentf("concurrent pull failed with error: %v", err)) 82 } 83 84 // Ensure all tags were pulled successfully 85 for _, repo := range repos { 86 dockerCmd(c, "inspect", repo) 87 out, _ := dockerCmd(c, "run", "--rm", repo) 88 c.Assert(strings.TrimSpace(out), checker.Equals, "/bin/sh -c echo "+repo) 89 } 90 } 91 92 // TestConcurrentFailingPull tries a concurrent pull that doesn't succeed. 93 func (s *DockerRegistrySuite) TestConcurrentFailingPull(c *check.C) { 94 repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL) 95 96 // Run multiple pulls concurrently 97 results := make(chan error) 98 numPulls := 3 99 100 for i := 0; i != numPulls; i++ { 101 go func() { 102 _, _, err := runCommandWithOutput(exec.Command(dockerBinary, "pull", repoName+":asdfasdf")) 103 results <- err 104 }() 105 } 106 107 // These checks are separate from the loop above because the check 108 // package is not goroutine-safe. 109 for i := 0; i != numPulls; i++ { 110 err := <-results 111 c.Assert(err, checker.NotNil, check.Commentf("expected pull to fail")) 112 } 113 } 114 115 // TestConcurrentPullMultipleTags pulls multiple tags from the same repo 116 // concurrently. 117 func (s *DockerRegistrySuite) TestConcurrentPullMultipleTags(c *check.C) { 118 repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL) 119 120 repos := []string{} 121 for _, tag := range []string{"recent", "fresh", "todays"} { 122 repo := fmt.Sprintf("%v:%v", repoName, tag) 123 _, err := buildImage(repo, fmt.Sprintf(` 124 FROM busybox 125 ENTRYPOINT ["/bin/echo"] 126 ENV FOO foo 127 ENV BAR bar 128 CMD echo %s 129 `, repo), true) 130 c.Assert(err, checker.IsNil) 131 dockerCmd(c, "push", repo) 132 repos = append(repos, repo) 133 } 134 135 // Clear local images store. 136 args := append([]string{"rmi"}, repos...) 137 dockerCmd(c, args...) 138 139 // Re-pull individual tags, in parallel 140 results := make(chan error) 141 142 for _, repo := range repos { 143 go func(repo string) { 144 _, _, err := runCommandWithOutput(exec.Command(dockerBinary, "pull", repo)) 145 results <- err 146 }(repo) 147 } 148 149 // These checks are separate from the loop above because the check 150 // package is not goroutine-safe. 151 for range repos { 152 err := <-results 153 c.Assert(err, checker.IsNil, check.Commentf("concurrent pull failed with error: %v", err)) 154 } 155 156 // Ensure all tags were pulled successfully 157 for _, repo := range repos { 158 dockerCmd(c, "inspect", repo) 159 out, _ := dockerCmd(c, "run", "--rm", repo) 160 c.Assert(strings.TrimSpace(out), checker.Equals, "/bin/sh -c echo "+repo) 161 } 162 } 163 164 // TestPullIDStability verifies that pushing an image and pulling it back 165 // preserves the image ID. 166 func (s *DockerRegistrySuite) TestPullIDStability(c *check.C) { 167 derivedImage := privateRegistryURL + "/dockercli/id-stability" 168 baseImage := "busybox" 169 170 _, err := buildImage(derivedImage, fmt.Sprintf(` 171 FROM %s 172 ENV derived true 173 ENV asdf true 174 RUN dd if=/dev/zero of=/file bs=1024 count=1024 175 CMD echo %s 176 `, baseImage, derivedImage), true) 177 if err != nil { 178 c.Fatal(err) 179 } 180 181 originalID, err := getIDByName(derivedImage) 182 if err != nil { 183 c.Fatalf("error inspecting: %v", err) 184 } 185 dockerCmd(c, "push", derivedImage) 186 187 // Pull 188 out, _ := dockerCmd(c, "pull", derivedImage) 189 if strings.Contains(out, "Pull complete") { 190 c.Fatalf("repull redownloaded a layer: %s", out) 191 } 192 193 derivedIDAfterPull, err := getIDByName(derivedImage) 194 if err != nil { 195 c.Fatalf("error inspecting: %v", err) 196 } 197 198 if derivedIDAfterPull != originalID { 199 c.Fatal("image's ID unexpectedly changed after a repush/repull") 200 } 201 202 // Make sure the image runs correctly 203 out, _ = dockerCmd(c, "run", "--rm", derivedImage) 204 if strings.TrimSpace(out) != derivedImage { 205 c.Fatalf("expected %s; got %s", derivedImage, out) 206 } 207 208 // Confirm that repushing and repulling does not change the computed ID 209 dockerCmd(c, "push", derivedImage) 210 dockerCmd(c, "rmi", derivedImage) 211 dockerCmd(c, "pull", derivedImage) 212 213 derivedIDAfterPull, err = getIDByName(derivedImage) 214 if err != nil { 215 c.Fatalf("error inspecting: %v", err) 216 } 217 218 if derivedIDAfterPull != originalID { 219 c.Fatal("image's ID unexpectedly changed after a repush/repull") 220 } 221 if err != nil { 222 c.Fatalf("error inspecting: %v", err) 223 } 224 225 // Make sure the image still runs 226 out, _ = dockerCmd(c, "run", "--rm", derivedImage) 227 if strings.TrimSpace(out) != derivedImage { 228 c.Fatalf("expected %s; got %s", derivedImage, out) 229 } 230 }