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