github.com/goern/docker@v1.9.0-rc1/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/go-check/check" 9 ) 10 11 // TestPullImageWithAliases pulls a specific image tag and verifies that any aliases (i.e., other 12 // tags for the same image) are not also pulled down. 13 // 14 // Ref: docker/docker#8141 15 func (s *DockerRegistrySuite) TestPullImageWithAliases(c *check.C) { 16 repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL) 17 18 repos := []string{} 19 for _, tag := range []string{"recent", "fresh"} { 20 repos = append(repos, fmt.Sprintf("%v:%v", repoName, tag)) 21 } 22 23 // Tag and push the same image multiple times. 24 for _, repo := range repos { 25 dockerCmd(c, "tag", "busybox", repo) 26 dockerCmd(c, "push", repo) 27 } 28 29 // Clear local images store. 30 args := append([]string{"rmi"}, repos...) 31 dockerCmd(c, args...) 32 33 // Pull a single tag and verify it doesn't bring down all aliases. 34 dockerCmd(c, "pull", repos[0]) 35 dockerCmd(c, "inspect", repos[0]) 36 for _, repo := range repos[1:] { 37 _, _, err := dockerCmdWithError("inspect", repo) 38 c.Assert(err, check.NotNil, check.Commentf("Image %v shouldn't have been pulled down", repo)) 39 } 40 } 41 42 // TestConcurrentPullWholeRepo pulls the same repo concurrently. 43 func (s *DockerRegistrySuite) TestConcurrentPullWholeRepo(c *check.C) { 44 repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL) 45 46 repos := []string{} 47 for _, tag := range []string{"recent", "fresh", "todays"} { 48 repo := fmt.Sprintf("%v:%v", repoName, tag) 49 _, err := buildImage(repo, fmt.Sprintf(` 50 FROM busybox 51 ENTRYPOINT ["/bin/echo"] 52 ENV FOO foo 53 ENV BAR bar 54 CMD echo %s 55 `, repo), true) 56 c.Assert(err, check.IsNil) 57 dockerCmd(c, "push", repo) 58 repos = append(repos, repo) 59 } 60 61 // Clear local images store. 62 args := append([]string{"rmi"}, repos...) 63 dockerCmd(c, args...) 64 65 // Run multiple re-pulls concurrently 66 results := make(chan error) 67 numPulls := 3 68 69 for i := 0; i != numPulls; i++ { 70 go func() { 71 _, _, err := runCommandWithOutput(exec.Command(dockerBinary, "pull", "-a", repoName)) 72 results <- err 73 }() 74 } 75 76 // These checks are separate from the loop above because the check 77 // package is not goroutine-safe. 78 for i := 0; i != numPulls; i++ { 79 err := <-results 80 c.Assert(err, check.IsNil, check.Commentf("concurrent pull failed with error: %v", err)) 81 } 82 83 // Ensure all tags were pulled successfully 84 for _, repo := range repos { 85 dockerCmd(c, "inspect", repo) 86 out, _ := dockerCmd(c, "run", "--rm", repo) 87 c.Assert(strings.TrimSpace(out), check.Equals, "/bin/sh -c echo "+repo, check.Commentf("CMD did not contain /bin/sh -c echo %s: %s", repo, out)) 88 } 89 } 90 91 // TestConcurrentFailingPull tries a concurrent pull that doesn't succeed. 92 func (s *DockerRegistrySuite) TestConcurrentFailingPull(c *check.C) { 93 repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL) 94 95 // Run multiple pulls concurrently 96 results := make(chan error) 97 numPulls := 3 98 99 for i := 0; i != numPulls; i++ { 100 go func() { 101 _, _, err := runCommandWithOutput(exec.Command(dockerBinary, "pull", repoName+":asdfasdf")) 102 results <- err 103 }() 104 } 105 106 // These checks are separate from the loop above because the check 107 // package is not goroutine-safe. 108 for i := 0; i != numPulls; i++ { 109 err := <-results 110 c.Assert(err, check.NotNil, check.Commentf("expected pull to fail")) 111 } 112 } 113 114 // TestConcurrentPullMultipleTags pulls multiple tags from the same repo 115 // concurrently. 116 func (s *DockerRegistrySuite) TestConcurrentPullMultipleTags(c *check.C) { 117 repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL) 118 119 repos := []string{} 120 for _, tag := range []string{"recent", "fresh", "todays"} { 121 repo := fmt.Sprintf("%v:%v", repoName, tag) 122 _, err := buildImage(repo, fmt.Sprintf(` 123 FROM busybox 124 ENTRYPOINT ["/bin/echo"] 125 ENV FOO foo 126 ENV BAR bar 127 CMD echo %s 128 `, repo), true) 129 c.Assert(err, check.IsNil) 130 dockerCmd(c, "push", repo) 131 repos = append(repos, repo) 132 } 133 134 // Clear local images store. 135 args := append([]string{"rmi"}, repos...) 136 dockerCmd(c, args...) 137 138 // Re-pull individual tags, in parallel 139 results := make(chan error) 140 141 for _, repo := range repos { 142 go func(repo string) { 143 _, _, err := runCommandWithOutput(exec.Command(dockerBinary, "pull", repo)) 144 results <- err 145 }(repo) 146 } 147 148 // These checks are separate from the loop above because the check 149 // package is not goroutine-safe. 150 for range repos { 151 err := <-results 152 c.Assert(err, check.IsNil, check.Commentf("concurrent pull failed with error: %v", err)) 153 } 154 155 // Ensure all tags were pulled successfully 156 for _, repo := range repos { 157 dockerCmd(c, "inspect", repo) 158 out, _ := dockerCmd(c, "run", "--rm", repo) 159 c.Assert(strings.TrimSpace(out), check.Equals, "/bin/sh -c echo "+repo, check.Commentf("CMD did not contain /bin/sh -c echo %s; %s", repo, out)) 160 } 161 }