github.com/dpiddy/docker@v1.12.2-rc1/integration-cli/docker_cli_images_test.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"path/filepath"
     8  	"reflect"
     9  	"sort"
    10  	"strings"
    11  	"time"
    12  
    13  	"github.com/docker/docker/pkg/integration/checker"
    14  	"github.com/docker/docker/pkg/stringid"
    15  	"github.com/go-check/check"
    16  )
    17  
    18  func (s *DockerSuite) TestImagesEnsureImageIsListed(c *check.C) {
    19  	testRequires(c, DaemonIsLinux)
    20  	imagesOut, _ := dockerCmd(c, "images")
    21  	c.Assert(imagesOut, checker.Contains, "busybox")
    22  }
    23  
    24  func (s *DockerSuite) TestImagesEnsureImageWithTagIsListed(c *check.C) {
    25  	testRequires(c, DaemonIsLinux)
    26  
    27  	name := "imagewithtag"
    28  	dockerCmd(c, "tag", "busybox", name+":v1")
    29  	dockerCmd(c, "tag", "busybox", name+":v1v1")
    30  	dockerCmd(c, "tag", "busybox", name+":v2")
    31  
    32  	imagesOut, _ := dockerCmd(c, "images", name+":v1")
    33  	c.Assert(imagesOut, checker.Contains, name)
    34  	c.Assert(imagesOut, checker.Contains, "v1")
    35  	c.Assert(imagesOut, checker.Not(checker.Contains), "v2")
    36  	c.Assert(imagesOut, checker.Not(checker.Contains), "v1v1")
    37  
    38  	imagesOut, _ = dockerCmd(c, "images", name)
    39  	c.Assert(imagesOut, checker.Contains, name)
    40  	c.Assert(imagesOut, checker.Contains, "v1")
    41  	c.Assert(imagesOut, checker.Contains, "v1v1")
    42  	c.Assert(imagesOut, checker.Contains, "v2")
    43  }
    44  
    45  func (s *DockerSuite) TestImagesEnsureImageWithBadTagIsNotListed(c *check.C) {
    46  	imagesOut, _ := dockerCmd(c, "images", "busybox:nonexistent")
    47  	c.Assert(imagesOut, checker.Not(checker.Contains), "busybox")
    48  }
    49  
    50  func (s *DockerSuite) TestImagesOrderedByCreationDate(c *check.C) {
    51  	testRequires(c, DaemonIsLinux)
    52  	id1, err := buildImage("order:test_a",
    53  		`FROM scratch
    54                  MAINTAINER dockerio1`, true)
    55  	c.Assert(err, checker.IsNil)
    56  	time.Sleep(1 * time.Second)
    57  	id2, err := buildImage("order:test_c",
    58  		`FROM scratch
    59                  MAINTAINER dockerio2`, true)
    60  	c.Assert(err, checker.IsNil)
    61  	time.Sleep(1 * time.Second)
    62  	id3, err := buildImage("order:test_b",
    63  		`FROM scratch
    64                  MAINTAINER dockerio3`, true)
    65  	c.Assert(err, checker.IsNil)
    66  
    67  	out, _ := dockerCmd(c, "images", "-q", "--no-trunc")
    68  	imgs := strings.Split(out, "\n")
    69  	c.Assert(imgs[0], checker.Equals, id3, check.Commentf("First image must be %s, got %s", id3, imgs[0]))
    70  	c.Assert(imgs[1], checker.Equals, id2, check.Commentf("First image must be %s, got %s", id2, imgs[1]))
    71  	c.Assert(imgs[2], checker.Equals, id1, check.Commentf("First image must be %s, got %s", id1, imgs[2]))
    72  }
    73  
    74  func (s *DockerSuite) TestImagesErrorWithInvalidFilterNameTest(c *check.C) {
    75  	out, _, err := dockerCmdWithError("images", "-f", "FOO=123")
    76  	c.Assert(err, checker.NotNil)
    77  	c.Assert(out, checker.Contains, "Invalid filter")
    78  }
    79  
    80  func (s *DockerSuite) TestImagesFilterLabelMatch(c *check.C) {
    81  	testRequires(c, DaemonIsLinux)
    82  	imageName1 := "images_filter_test1"
    83  	imageName2 := "images_filter_test2"
    84  	imageName3 := "images_filter_test3"
    85  	image1ID, err := buildImage(imageName1,
    86  		`FROM scratch
    87                   LABEL match me`, true)
    88  	c.Assert(err, check.IsNil)
    89  
    90  	image2ID, err := buildImage(imageName2,
    91  		`FROM scratch
    92                   LABEL match="me too"`, true)
    93  	c.Assert(err, check.IsNil)
    94  
    95  	image3ID, err := buildImage(imageName3,
    96  		`FROM scratch
    97                   LABEL nomatch me`, true)
    98  	c.Assert(err, check.IsNil)
    99  
   100  	out, _ := dockerCmd(c, "images", "--no-trunc", "-q", "-f", "label=match")
   101  	out = strings.TrimSpace(out)
   102  	c.Assert(out, check.Matches, fmt.Sprintf("[\\s\\w:]*%s[\\s\\w:]*", image1ID))
   103  	c.Assert(out, check.Matches, fmt.Sprintf("[\\s\\w:]*%s[\\s\\w:]*", image2ID))
   104  	c.Assert(out, check.Not(check.Matches), fmt.Sprintf("[\\s\\w:]*%s[\\s\\w:]*", image3ID))
   105  
   106  	out, _ = dockerCmd(c, "images", "--no-trunc", "-q", "-f", "label=match=me too")
   107  	out = strings.TrimSpace(out)
   108  	c.Assert(out, check.Equals, image2ID)
   109  }
   110  
   111  // Regression : #15659
   112  func (s *DockerSuite) TestImagesFilterLabelWithCommit(c *check.C) {
   113  	// Create a container
   114  	dockerCmd(c, "run", "--name", "bar", "busybox", "/bin/sh")
   115  	// Commit with labels "using changes"
   116  	out, _ := dockerCmd(c, "commit", "-c", "LABEL foo.version=1.0.0-1", "-c", "LABEL foo.name=bar", "-c", "LABEL foo.author=starlord", "bar", "bar:1.0.0-1")
   117  	imageID := strings.TrimSpace(out)
   118  
   119  	out, _ = dockerCmd(c, "images", "--no-trunc", "-q", "-f", "label=foo.version=1.0.0-1")
   120  	out = strings.TrimSpace(out)
   121  	c.Assert(out, check.Equals, imageID)
   122  }
   123  
   124  func (s *DockerSuite) TestImagesFilterSinceAndBefore(c *check.C) {
   125  	imageID1, err := buildImage("image:1", `FROM `+minimalBaseImage()+`
   126  LABEL number=1`, true)
   127  	c.Assert(err, checker.IsNil)
   128  	imageID2, err := buildImage("image:2", `FROM `+minimalBaseImage()+`
   129  LABEL number=2`, true)
   130  	c.Assert(err, checker.IsNil)
   131  	imageID3, err := buildImage("image:3", `FROM `+minimalBaseImage()+`
   132  LABEL number=3`, true)
   133  	c.Assert(err, checker.IsNil)
   134  
   135  	expected := []string{imageID3, imageID2}
   136  
   137  	out, _ := dockerCmd(c, "images", "-f", "since=image:1", "image")
   138  	c.Assert(assertImageList(out, expected), checker.Equals, true, check.Commentf("SINCE filter: Image list is not in the correct order: %v\n%s", expected, out))
   139  
   140  	out, _ = dockerCmd(c, "images", "-f", "since="+imageID1, "image")
   141  	c.Assert(assertImageList(out, expected), checker.Equals, true, check.Commentf("SINCE filter: Image list is not in the correct order: %v\n%s", expected, out))
   142  
   143  	expected = []string{imageID3}
   144  
   145  	out, _ = dockerCmd(c, "images", "-f", "since=image:2", "image")
   146  	c.Assert(assertImageList(out, expected), checker.Equals, true, check.Commentf("SINCE filter: Image list is not in the correct order: %v\n%s", expected, out))
   147  
   148  	out, _ = dockerCmd(c, "images", "-f", "since="+imageID2, "image")
   149  	c.Assert(assertImageList(out, expected), checker.Equals, true, check.Commentf("SINCE filter: Image list is not in the correct order: %v\n%s", expected, out))
   150  
   151  	expected = []string{imageID2, imageID1}
   152  
   153  	out, _ = dockerCmd(c, "images", "-f", "before=image:3", "image")
   154  	c.Assert(assertImageList(out, expected), checker.Equals, true, check.Commentf("BEFORE filter: Image list is not in the correct order: %v\n%s", expected, out))
   155  
   156  	out, _ = dockerCmd(c, "images", "-f", "before="+imageID3, "image")
   157  	c.Assert(assertImageList(out, expected), checker.Equals, true, check.Commentf("BEFORE filter: Image list is not in the correct order: %v\n%s", expected, out))
   158  
   159  	expected = []string{imageID1}
   160  
   161  	out, _ = dockerCmd(c, "images", "-f", "before=image:2", "image")
   162  	c.Assert(assertImageList(out, expected), checker.Equals, true, check.Commentf("BEFORE filter: Image list is not in the correct order: %v\n%s", expected, out))
   163  
   164  	out, _ = dockerCmd(c, "images", "-f", "before="+imageID2, "image")
   165  	c.Assert(assertImageList(out, expected), checker.Equals, true, check.Commentf("BEFORE filter: Image list is not in the correct order: %v\n%s", expected, out))
   166  }
   167  
   168  func assertImageList(out string, expected []string) bool {
   169  	lines := strings.Split(strings.Trim(out, "\n "), "\n")
   170  
   171  	if len(lines)-1 != len(expected) {
   172  		return false
   173  	}
   174  
   175  	imageIDIndex := strings.Index(lines[0], "IMAGE ID")
   176  	for i := 0; i < len(expected); i++ {
   177  		imageID := lines[i+1][imageIDIndex : imageIDIndex+12]
   178  		found := false
   179  		for _, e := range expected {
   180  			if imageID == e[7:19] {
   181  				found = true
   182  				break
   183  			}
   184  		}
   185  		if !found {
   186  			return false
   187  		}
   188  	}
   189  
   190  	return true
   191  }
   192  
   193  func (s *DockerSuite) TestImagesFilterSpaceTrimCase(c *check.C) {
   194  	testRequires(c, DaemonIsLinux)
   195  	imageName := "images_filter_test"
   196  	buildImage(imageName,
   197  		`FROM scratch
   198                   RUN touch /test/foo
   199                   RUN touch /test/bar
   200                   RUN touch /test/baz`, true)
   201  
   202  	filters := []string{
   203  		"dangling=true",
   204  		"Dangling=true",
   205  		" dangling=true",
   206  		"dangling=true ",
   207  		"dangling = true",
   208  	}
   209  
   210  	imageListings := make([][]string, 5, 5)
   211  	for idx, filter := range filters {
   212  		out, _ := dockerCmd(c, "images", "-q", "-f", filter)
   213  		listing := strings.Split(out, "\n")
   214  		sort.Strings(listing)
   215  		imageListings[idx] = listing
   216  	}
   217  
   218  	for idx, listing := range imageListings {
   219  		if idx < 4 && !reflect.DeepEqual(listing, imageListings[idx+1]) {
   220  			for idx, errListing := range imageListings {
   221  				fmt.Printf("out %d", idx)
   222  				for _, image := range errListing {
   223  					fmt.Print(image)
   224  				}
   225  				fmt.Print("")
   226  			}
   227  			c.Fatalf("All output must be the same")
   228  		}
   229  	}
   230  }
   231  
   232  func (s *DockerSuite) TestImagesEnsureDanglingImageOnlyListedOnce(c *check.C) {
   233  	testRequires(c, DaemonIsLinux)
   234  	// create container 1
   235  	out, _ := dockerCmd(c, "run", "-d", "busybox", "true")
   236  	containerID1 := strings.TrimSpace(out)
   237  
   238  	// tag as foobox
   239  	out, _ = dockerCmd(c, "commit", containerID1, "foobox")
   240  	imageID := stringid.TruncateID(strings.TrimSpace(out))
   241  
   242  	// overwrite the tag, making the previous image dangling
   243  	dockerCmd(c, "tag", "busybox", "foobox")
   244  
   245  	out, _ = dockerCmd(c, "images", "-q", "-f", "dangling=true")
   246  	// Expect one dangling image
   247  	c.Assert(strings.Count(out, imageID), checker.Equals, 1)
   248  
   249  	out, _ = dockerCmd(c, "images", "-q", "-f", "dangling=false")
   250  	//dangling=false would not include dangling images
   251  	c.Assert(out, checker.Not(checker.Contains), imageID)
   252  
   253  	out, _ = dockerCmd(c, "images")
   254  	//docker images still include dangling images
   255  	c.Assert(out, checker.Contains, imageID)
   256  
   257  }
   258  
   259  func (s *DockerSuite) TestImagesWithIncorrectFilter(c *check.C) {
   260  	out, _, err := dockerCmdWithError("images", "-f", "dangling=invalid")
   261  	c.Assert(err, check.NotNil)
   262  	c.Assert(out, checker.Contains, "Invalid filter")
   263  }
   264  
   265  func (s *DockerSuite) TestImagesEnsureOnlyHeadsImagesShown(c *check.C) {
   266  	testRequires(c, DaemonIsLinux)
   267  
   268  	dockerfile := `
   269          FROM scratch
   270          MAINTAINER docker
   271          ENV foo bar`
   272  
   273  	head, out, err := buildImageWithOut("scratch-image", dockerfile, false)
   274  	c.Assert(err, check.IsNil)
   275  
   276  	// this is just the output of docker build
   277  	// we're interested in getting the image id of the MAINTAINER instruction
   278  	// and that's located at output, line 5, from 7 to end
   279  	split := strings.Split(out, "\n")
   280  	intermediate := strings.TrimSpace(split[5][7:])
   281  
   282  	out, _ = dockerCmd(c, "images")
   283  	// images shouldn't show non-heads images
   284  	c.Assert(out, checker.Not(checker.Contains), intermediate)
   285  	// images should contain final built images
   286  	c.Assert(out, checker.Contains, stringid.TruncateID(head))
   287  }
   288  
   289  func (s *DockerSuite) TestImagesEnsureImagesFromScratchShown(c *check.C) {
   290  	testRequires(c, DaemonIsLinux)
   291  
   292  	dockerfile := `
   293          FROM scratch
   294          MAINTAINER docker`
   295  
   296  	id, _, err := buildImageWithOut("scratch-image", dockerfile, false)
   297  	c.Assert(err, check.IsNil)
   298  
   299  	out, _ := dockerCmd(c, "images")
   300  	// images should contain images built from scratch
   301  	c.Assert(out, checker.Contains, stringid.TruncateID(id))
   302  }
   303  
   304  // #18181
   305  func (s *DockerSuite) TestImagesFilterNameWithPort(c *check.C) {
   306  	tag := "a.b.c.d:5000/hello"
   307  	dockerCmd(c, "tag", "busybox", tag)
   308  	out, _ := dockerCmd(c, "images", tag)
   309  	c.Assert(out, checker.Contains, tag)
   310  
   311  	out, _ = dockerCmd(c, "images", tag+":latest")
   312  	c.Assert(out, checker.Contains, tag)
   313  
   314  	out, _ = dockerCmd(c, "images", tag+":no-such-tag")
   315  	c.Assert(out, checker.Not(checker.Contains), tag)
   316  }
   317  
   318  func (s *DockerSuite) TestImagesFormat(c *check.C) {
   319  	// testRequires(c, DaemonIsLinux)
   320  	tag := "myimage"
   321  	dockerCmd(c, "tag", "busybox", tag+":v1")
   322  	dockerCmd(c, "tag", "busybox", tag+":v2")
   323  
   324  	out, _ := dockerCmd(c, "images", "--format", "{{.Repository}}", tag)
   325  	lines := strings.Split(strings.TrimSpace(string(out)), "\n")
   326  
   327  	expected := []string{"myimage", "myimage"}
   328  	var names []string
   329  	for _, l := range lines {
   330  		names = append(names, l)
   331  	}
   332  	c.Assert(expected, checker.DeepEquals, names, check.Commentf("Expected array with truncated names: %v, got: %v", expected, names))
   333  }
   334  
   335  // ImagesDefaultFormatAndQuiet
   336  func (s *DockerSuite) TestImagesFormatDefaultFormat(c *check.C) {
   337  	testRequires(c, DaemonIsLinux)
   338  
   339  	// create container 1
   340  	out, _ := dockerCmd(c, "run", "-d", "busybox", "true")
   341  	containerID1 := strings.TrimSpace(out)
   342  
   343  	// tag as foobox
   344  	out, _ = dockerCmd(c, "commit", containerID1, "myimage")
   345  	imageID := stringid.TruncateID(strings.TrimSpace(out))
   346  
   347  	config := `{
   348  		"imagesFormat": "{{ .ID }} default"
   349  }`
   350  	d, err := ioutil.TempDir("", "integration-cli-")
   351  	c.Assert(err, checker.IsNil)
   352  	defer os.RemoveAll(d)
   353  
   354  	err = ioutil.WriteFile(filepath.Join(d, "config.json"), []byte(config), 0644)
   355  	c.Assert(err, checker.IsNil)
   356  
   357  	out, _ = dockerCmd(c, "--config", d, "images", "-q", "myimage")
   358  	c.Assert(out, checker.Equals, imageID+"\n", check.Commentf("Expected to print only the image id, got %v\n", out))
   359  }