github.com/clintkitson/docker@v1.9.1/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  }