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  })