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