github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/test/e2e/images_test.go (about) 1 package integration 2 3 import ( 4 "fmt" 5 "os" 6 "sort" 7 "strings" 8 9 . "github.com/containers/libpod/test/utils" 10 "github.com/docker/go-units" 11 . "github.com/onsi/ginkgo" 12 . "github.com/onsi/gomega" 13 ) 14 15 var _ = Describe("Podman images", func() { 16 var ( 17 tempdir string 18 err error 19 podmanTest *PodmanTestIntegration 20 ) 21 22 BeforeEach(func() { 23 tempdir, err = CreateTempDirInTempDir() 24 if err != nil { 25 os.Exit(1) 26 } 27 podmanTest = PodmanTestCreate(tempdir) 28 podmanTest.Setup() 29 podmanTest.SeedImages() 30 }) 31 32 AfterEach(func() { 33 podmanTest.Cleanup() 34 f := CurrentGinkgoTestDescription() 35 processTestResult(f) 36 37 }) 38 It("podman images", func() { 39 session := podmanTest.Podman([]string{"images"}) 40 session.WaitWithDefaultTimeout() 41 Expect(session.ExitCode()).To(Equal(0)) 42 Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 2)) 43 Expect(session.LineInOuputStartsWith("docker.io/library/alpine")).To(BeTrue()) 44 Expect(session.LineInOuputStartsWith("docker.io/library/busybox")).To(BeTrue()) 45 }) 46 47 It("podman images with no images prints header", func() { 48 rmi := podmanTest.PodmanNoCache([]string{"rmi", "-a"}) 49 rmi.WaitWithDefaultTimeout() 50 Expect(rmi.ExitCode()).To(Equal(0)) 51 52 session := podmanTest.PodmanNoCache([]string{"images"}) 53 session.WaitWithDefaultTimeout() 54 Expect(session.ExitCode()).To(Equal(0)) 55 Expect(len(session.OutputToStringArray())).To(Equal(1)) 56 Expect(session.LineInOutputContains("REPOSITORY")).To(BeTrue()) 57 }) 58 59 It("podman image List", func() { 60 session := podmanTest.Podman([]string{"image", "list"}) 61 session.WaitWithDefaultTimeout() 62 Expect(session.ExitCode()).To(Equal(0)) 63 Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 2)) 64 Expect(session.LineInOuputStartsWith("docker.io/library/alpine")).To(BeTrue()) 65 Expect(session.LineInOuputStartsWith("docker.io/library/busybox")).To(BeTrue()) 66 }) 67 68 It("podman images with multiple tags", func() { 69 // tag "docker.io/library/alpine:latest" to "foo:{a,b,c}" 70 podmanTest.RestoreAllArtifacts() 71 session := podmanTest.PodmanNoCache([]string{"tag", ALPINE, "foo:a", "foo:b", "foo:c"}) 72 session.WaitWithDefaultTimeout() 73 Expect(session.ExitCode()).To(Equal(0)) 74 // tag "foo:c" to "bar:{a,b}" 75 session = podmanTest.PodmanNoCache([]string{"tag", "foo:c", "bar:a", "bar:b"}) 76 session.WaitWithDefaultTimeout() 77 Expect(session.ExitCode()).To(Equal(0)) 78 // check all previous and the newly tagged images 79 session = podmanTest.PodmanNoCache([]string{"images"}) 80 session.WaitWithDefaultTimeout() 81 Expect(session.ExitCode()).To(Equal(0)) 82 session.LineInOutputContainsTag("docker.io/library/alpine", "latest") 83 session.LineInOutputContainsTag("docker.io/library/busybox", "glibc") 84 session.LineInOutputContainsTag("foo", "a") 85 session.LineInOutputContainsTag("foo", "b") 86 session.LineInOutputContainsTag("foo", "c") 87 session.LineInOutputContainsTag("bar", "a") 88 session.LineInOutputContainsTag("bar", "b") 89 session = podmanTest.PodmanNoCache([]string{"images", "-qn"}) 90 session.WaitWithDefaultTimeout() 91 Expect(session.ExitCode()).To(Equal(0)) 92 Expect(len(session.OutputToStringArray())).To(BeNumerically("==", 2)) 93 }) 94 95 It("podman images with digests", func() { 96 session := podmanTest.Podman([]string{"images", "--digests"}) 97 session.WaitWithDefaultTimeout() 98 Expect(session.ExitCode()).To(Equal(0)) 99 Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 2)) 100 Expect(session.LineInOuputStartsWith("docker.io/library/alpine")).To(BeTrue()) 101 Expect(session.LineInOuputStartsWith("docker.io/library/busybox")).To(BeTrue()) 102 }) 103 104 It("podman empty images list in JSON format", func() { 105 session := podmanTest.Podman([]string{"images", "--format=json", "not-existing-image"}) 106 session.WaitWithDefaultTimeout() 107 Expect(session.ExitCode()).To(Equal(0)) 108 Expect(session.IsJSONOutputValid()).To(BeTrue()) 109 }) 110 111 It("podman images in JSON format", func() { 112 session := podmanTest.Podman([]string{"images", "--format=json"}) 113 session.WaitWithDefaultTimeout() 114 Expect(session.ExitCode()).To(Equal(0)) 115 Expect(session.IsJSONOutputValid()).To(BeTrue()) 116 }) 117 118 It("podman images in GO template format", func() { 119 formatStr := "{{.ID}}\t{{.Created}}\t{{.CreatedAt}}\t{{.CreatedSince}}\t{{.CreatedTime}}" 120 session := podmanTest.Podman([]string{"images", fmt.Sprintf("--format=%s", formatStr)}) 121 session.WaitWithDefaultTimeout() 122 Expect(session.ExitCode()).To(Equal(0)) 123 }) 124 125 It("podman images with short options", func() { 126 session := podmanTest.Podman([]string{"images", "-qn"}) 127 session.WaitWithDefaultTimeout() 128 Expect(session.ExitCode()).To(Equal(0)) 129 Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 1)) 130 }) 131 132 It("podman images filter by image name", func() { 133 podmanTest.RestoreAllArtifacts() 134 session := podmanTest.PodmanNoCache([]string{"images", "-q", ALPINE}) 135 session.WaitWithDefaultTimeout() 136 Expect(session.ExitCode()).To(Equal(0)) 137 Expect(len(session.OutputToStringArray())).To(Equal(1)) 138 139 session = podmanTest.PodmanNoCache([]string{"tag", ALPINE, "foo:a"}) 140 session.WaitWithDefaultTimeout() 141 Expect(session.ExitCode()).To(Equal(0)) 142 session = podmanTest.PodmanNoCache([]string{"tag", BB, "foo:b"}) 143 session.WaitWithDefaultTimeout() 144 Expect(session.ExitCode()).To(Equal(0)) 145 146 session = podmanTest.PodmanNoCache([]string{"images", "-q", "foo"}) 147 session.WaitWithDefaultTimeout() 148 Expect(session.ExitCode()).To(Equal(0)) 149 Expect(len(session.OutputToStringArray())).To(Equal(2)) 150 }) 151 152 It("podman images filter reference", func() { 153 if podmanTest.RemoteTest { 154 Skip("Does not work on remote client") 155 } 156 podmanTest.RestoreAllArtifacts() 157 result := podmanTest.PodmanNoCache([]string{"images", "-q", "-f", "reference=docker.io*"}) 158 result.WaitWithDefaultTimeout() 159 Expect(result.ExitCode()).To(Equal(0)) 160 Expect(len(result.OutputToStringArray())).To(Equal(2)) 161 162 retapline := podmanTest.PodmanNoCache([]string{"images", "-f", "reference=a*pine"}) 163 retapline.WaitWithDefaultTimeout() 164 Expect(retapline.ExitCode()).To(Equal(0)) 165 Expect(len(retapline.OutputToStringArray())).To(Equal(2)) 166 Expect(retapline.LineInOutputContains("alpine")).To(BeTrue()) 167 168 retapline = podmanTest.PodmanNoCache([]string{"images", "-f", "reference=alpine"}) 169 retapline.WaitWithDefaultTimeout() 170 Expect(retapline.ExitCode()).To(Equal(0)) 171 Expect(len(retapline.OutputToStringArray())).To(Equal(2)) 172 Expect(retapline.LineInOutputContains("alpine")).To(BeTrue()) 173 174 retnone := podmanTest.PodmanNoCache([]string{"images", "-q", "-f", "reference=bogus"}) 175 retnone.WaitWithDefaultTimeout() 176 Expect(retnone.ExitCode()).To(Equal(0)) 177 Expect(len(retnone.OutputToStringArray())).To(Equal(0)) 178 }) 179 180 It("podman images filter before image", func() { 181 if podmanTest.RemoteTest { 182 Skip("Does not work on remote client") 183 } 184 dockerfile := `FROM docker.io/library/alpine:latest 185 RUN apk update && apk add strace 186 ` 187 podmanTest.BuildImage(dockerfile, "foobar.com/before:latest", "false") 188 result := podmanTest.Podman([]string{"images", "-q", "-f", "before=foobar.com/before:latest"}) 189 result.WaitWithDefaultTimeout() 190 Expect(result.ExitCode()).To(Equal(0)) 191 Expect(len(result.OutputToStringArray()) >= 1).To(BeTrue()) 192 }) 193 194 It("podman images filter after image", func() { 195 if podmanTest.RemoteTest { 196 Skip("Does not work on remote client") 197 } 198 podmanTest.RestoreAllArtifacts() 199 rmi := podmanTest.PodmanNoCache([]string{"rmi", "busybox"}) 200 rmi.WaitWithDefaultTimeout() 201 Expect(rmi.ExitCode()).To(Equal(0)) 202 203 dockerfile := `FROM docker.io/library/alpine:latest 204 ` 205 podmanTest.BuildImage(dockerfile, "foobar.com/before:latest", "false") 206 result := podmanTest.PodmanNoCache([]string{"images", "-q", "-f", "after=docker.io/library/alpine:latest"}) 207 result.WaitWithDefaultTimeout() 208 Expect(result.ExitCode()).To(Equal(0)) 209 Expect(len(result.OutputToStringArray())).To(Equal(0)) 210 }) 211 212 It("podman image list filter after image", func() { 213 if podmanTest.RemoteTest { 214 Skip("Does not work on remote client") 215 } 216 podmanTest.RestoreAllArtifacts() 217 rmi := podmanTest.PodmanNoCache([]string{"image", "rm", "busybox"}) 218 rmi.WaitWithDefaultTimeout() 219 Expect(rmi.ExitCode()).To(Equal(0)) 220 221 dockerfile := `FROM docker.io/library/alpine:latest 222 ` 223 podmanTest.BuildImage(dockerfile, "foobar.com/before:latest", "false") 224 result := podmanTest.PodmanNoCache([]string{"image", "list", "-q", "-f", "after=docker.io/library/alpine:latest"}) 225 result.WaitWithDefaultTimeout() 226 Expect(result.ExitCode()).To(Equal(0)) 227 Expect(len(result.OutputToStringArray())).To(Equal(0)) 228 }) 229 230 It("podman images filter dangling", func() { 231 if podmanTest.RemoteTest { 232 Skip("Does not work on remote client") 233 } 234 dockerfile := `FROM docker.io/library/alpine:latest 235 ` 236 podmanTest.BuildImage(dockerfile, "foobar.com/before:latest", "false") 237 podmanTest.BuildImage(dockerfile, "foobar.com/before:latest", "false") 238 result := podmanTest.Podman([]string{"images", "-q", "-f", "dangling=true"}) 239 result.WaitWithDefaultTimeout() 240 Expect(result.ExitCode()).To(Equal(0)) 241 Expect(len(result.OutputToStringArray())).To(Equal(0)) 242 }) 243 244 It("podman check for image with sha256: prefix", func() { 245 if podmanTest.RemoteTest { 246 Skip("Does not work on remote client") 247 } 248 session := podmanTest.Podman([]string{"inspect", "--format=json", ALPINE}) 249 session.WaitWithDefaultTimeout() 250 Expect(session.ExitCode()).To(Equal(0)) 251 Expect(session.IsJSONOutputValid()).To(BeTrue()) 252 imageData := session.InspectImageJSON() 253 254 result := podmanTest.Podman([]string{"images", fmt.Sprintf("sha256:%s", imageData[0].ID)}) 255 result.WaitWithDefaultTimeout() 256 Expect(result.ExitCode()).To(Equal(0)) 257 }) 258 259 It("podman check for image with sha256: prefix", func() { 260 if podmanTest.RemoteTest { 261 Skip("Does not work on remote client") 262 } 263 session := podmanTest.Podman([]string{"image", "inspect", "--format=json", ALPINE}) 264 session.WaitWithDefaultTimeout() 265 Expect(session.ExitCode()).To(Equal(0)) 266 Expect(session.IsJSONOutputValid()).To(BeTrue()) 267 imageData := session.InspectImageJSON() 268 269 result := podmanTest.Podman([]string{"image", "ls", fmt.Sprintf("sha256:%s", imageData[0].ID)}) 270 result.WaitWithDefaultTimeout() 271 Expect(result.ExitCode()).To(Equal(0)) 272 }) 273 274 It("podman images sort by values", func() { 275 sortValueTest := func(value string, result int, format string) []string { 276 f := fmt.Sprintf("{{.%s}}", format) 277 session := podmanTest.Podman([]string{"images", "--sort", value, "--format", f}) 278 session.WaitWithDefaultTimeout() 279 Expect(session.ExitCode()).To(Equal(result)) 280 281 return session.OutputToStringArray() 282 } 283 284 sortedArr := sortValueTest("created", 0, "CreatedAt") 285 Expect(sort.SliceIsSorted(sortedArr, func(i, j int) bool { return sortedArr[i] > sortedArr[j] })).To(BeTrue()) 286 287 sortedArr = sortValueTest("id", 0, "ID") 288 Expect(sort.SliceIsSorted(sortedArr, func(i, j int) bool { return sortedArr[i] < sortedArr[j] })).To(BeTrue()) 289 290 sortedArr = sortValueTest("repository", 0, "Repository") 291 Expect(sort.SliceIsSorted(sortedArr, func(i, j int) bool { return sortedArr[i] < sortedArr[j] })).To(BeTrue()) 292 293 sortedArr = sortValueTest("size", 0, "Size") 294 Expect(sort.SliceIsSorted(sortedArr, func(i, j int) bool { 295 size1, _ := units.FromHumanSize(sortedArr[i]) 296 size2, _ := units.FromHumanSize(sortedArr[j]) 297 return size1 < size2 298 })).To(BeTrue()) 299 sortedArr = sortValueTest("tag", 0, "Tag") 300 Expect(sort.SliceIsSorted(sortedArr, func(i, j int) bool { return sortedArr[i] < sortedArr[j] })).To(BeTrue()) 301 302 sortValueTest("badvalue", 125, "Tag") 303 sortValueTest("id", 125, "badvalue") 304 }) 305 306 It("podman images --all flag", func() { 307 if podmanTest.RemoteTest { 308 Skip("Does not work on remote client") 309 } 310 podmanTest.RestoreAllArtifacts() 311 dockerfile := `FROM docker.io/library/alpine:latest 312 RUN mkdir hello 313 RUN touch test.txt 314 ENV foo=bar 315 ` 316 podmanTest.BuildImage(dockerfile, "test", "true") 317 session := podmanTest.PodmanNoCache([]string{"images"}) 318 session.WaitWithDefaultTimeout() 319 Expect(session.ExitCode()).To(Equal(0)) 320 Expect(len(session.OutputToStringArray())).To(Equal(4)) 321 322 session2 := podmanTest.PodmanNoCache([]string{"images", "--all"}) 323 session2.WaitWithDefaultTimeout() 324 Expect(session2.ExitCode()).To(Equal(0)) 325 Expect(len(session2.OutputToStringArray())).To(Equal(6)) 326 }) 327 328 It("podman images filter by label", func() { 329 SkipIfRemote() 330 dockerfile := `FROM docker.io/library/alpine:latest 331 LABEL version="1.0" 332 LABEL "com.example.vendor"="Example Vendor" 333 ` 334 podmanTest.BuildImage(dockerfile, "test", "true") 335 session := podmanTest.Podman([]string{"images", "-f", "label=version=1.0"}) 336 session.WaitWithDefaultTimeout() 337 Expect(session.ExitCode()).To(Equal(0)) 338 Expect(len(session.OutputToStringArray())).To(Equal(2)) 339 }) 340 341 It("podman with images with no layers", func() { 342 if podmanTest.RemoteTest { 343 Skip("Does not work on remote client") 344 } 345 346 dockerfile := strings.Join([]string{ 347 `FROM scratch`, 348 `LABEL org.opencontainers.image.authors="<somefolks@example.org>"`, 349 `LABEL org.opencontainers.image.created=2019-06-11T19:03:37Z`, 350 `LABEL org.opencontainers.image.description="This is a test image"`, 351 `LABEL org.opencontainers.image.title=test`, 352 `LABEL org.opencontainers.image.vendor="Example.org"`, 353 `LABEL org.opencontainers.image.version=1`, 354 }, "\n") 355 podmanTest.BuildImage(dockerfile, "foo", "true") 356 357 session := podmanTest.Podman([]string{"images", "foo"}) 358 session.WaitWithDefaultTimeout() 359 Expect(session.ExitCode()).To(Equal(0)) 360 output := session.OutputToString() 361 Expect(output).To(Not(MatchRegexp("<missing>"))) 362 Expect(output).To(Not(MatchRegexp("error"))) 363 364 session = podmanTest.Podman([]string{"image", "tree", "foo"}) 365 session.WaitWithDefaultTimeout() 366 Expect(session.ExitCode()).To(Equal(0)) 367 output = session.OutputToString() 368 Expect(output).To(MatchRegexp("No Image Layers")) 369 370 session = podmanTest.Podman([]string{"history", "foo"}) 371 session.WaitWithDefaultTimeout() 372 Expect(session.ExitCode()).To(Equal(0)) 373 output = session.OutputToString() 374 Expect(output).To(Not(MatchRegexp("error"))) 375 376 session = podmanTest.Podman([]string{"history", "--quiet", "foo"}) 377 session.WaitWithDefaultTimeout() 378 Expect(session.ExitCode()).To(Equal(0)) 379 Expect(len(session.OutputToStringArray())).To(Equal(6)) 380 381 session = podmanTest.Podman([]string{"image", "list", "foo"}) 382 session.WaitWithDefaultTimeout() 383 Expect(session.ExitCode()).To(Equal(0)) 384 output = session.OutputToString() 385 Expect(output).To(Not(MatchRegexp("<missing>"))) 386 Expect(output).To(Not(MatchRegexp("error"))) 387 388 session = podmanTest.Podman([]string{"image", "list"}) 389 session.WaitWithDefaultTimeout() 390 Expect(session.ExitCode()).To(Equal(0)) 391 output = session.OutputToString() 392 Expect(output).To(Not(MatchRegexp("<missing>"))) 393 Expect(output).To(Not(MatchRegexp("error"))) 394 395 session = podmanTest.Podman([]string{"inspect", "foo"}) 396 session.WaitWithDefaultTimeout() 397 Expect(session.ExitCode()).To(Equal(0)) 398 output = session.OutputToString() 399 Expect(output).To(Not(MatchRegexp("<missing>"))) 400 Expect(output).To(Not(MatchRegexp("error"))) 401 402 session = podmanTest.Podman([]string{"inspect", "--format", "{{.RootFS.Layers}}", "foo"}) 403 session.WaitWithDefaultTimeout() 404 Expect(session.ExitCode()).To(Equal(0)) 405 output = session.OutputToString() 406 Expect(output).To(Equal("[]")) 407 }) 408 409 It("podman images --filter readonly", func() { 410 SkipIfRemote() 411 dockerfile := `FROM docker.io/library/alpine:latest 412 ` 413 podmanTest.BuildImage(dockerfile, "foobar.com/before:latest", "false") 414 result := podmanTest.Podman([]string{"images", "-f", "readonly=true"}) 415 result.WaitWithDefaultTimeout() 416 Expect(result.ExitCode()).To(Equal(0)) 417 418 result1 := podmanTest.Podman([]string{"images", "--filter", "readonly=false"}) 419 result1.WaitWithDefaultTimeout() 420 Expect(result1.ExitCode()).To(Equal(0)) 421 Expect(result.OutputToStringArray()).To(Not(Equal(result1.OutputToStringArray()))) 422 }) 423 424 })