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