github.com/containers/podman/v4@v4.9.4/pkg/bindings/test/system_test.go (about)

     1  package bindings_test
     2  
     3  import (
     4  	"sync"
     5  	"time"
     6  
     7  	"github.com/containers/podman/v4/pkg/bindings/containers"
     8  	"github.com/containers/podman/v4/pkg/bindings/pods"
     9  	"github.com/containers/podman/v4/pkg/bindings/system"
    10  	"github.com/containers/podman/v4/pkg/bindings/volumes"
    11  	"github.com/containers/podman/v4/pkg/domain/entities"
    12  	"github.com/containers/podman/v4/pkg/domain/entities/reports"
    13  	. "github.com/onsi/ginkgo/v2"
    14  	. "github.com/onsi/gomega"
    15  	"github.com/onsi/gomega/gexec"
    16  )
    17  
    18  var _ = Describe("Podman system", func() {
    19  	var (
    20  		bt     *bindingTest
    21  		s      *gexec.Session
    22  		newpod string
    23  	)
    24  
    25  	BeforeEach(func() {
    26  		bt = newBindingTest()
    27  		bt.RestoreImagesFromCache()
    28  		newpod = "newpod"
    29  		bt.Podcreate(&newpod)
    30  		s = bt.startAPIService()
    31  		time.Sleep(1 * time.Second)
    32  		err := bt.NewConnection()
    33  		Expect(err).ToNot(HaveOccurred())
    34  	})
    35  
    36  	AfterEach(func() {
    37  		s.Kill()
    38  		bt.cleanup()
    39  	})
    40  
    41  	It("podman events", func() {
    42  		var name = "top"
    43  		_, err := bt.RunTopContainer(&name, nil)
    44  		Expect(err).ToNot(HaveOccurred())
    45  
    46  		filters := make(map[string][]string)
    47  		filters["container"] = []string{name}
    48  
    49  		binChan := make(chan entities.Event)
    50  		done := sync.Mutex{}
    51  		done.Lock()
    52  		eventCounter := 0
    53  		go func() {
    54  			defer done.Unlock()
    55  			for range binChan {
    56  				eventCounter++
    57  			}
    58  		}()
    59  		options := new(system.EventsOptions).WithFilters(filters).WithStream(false)
    60  		err = system.Events(bt.conn, binChan, nil, options)
    61  		Expect(err).ToNot(HaveOccurred())
    62  		done.Lock()
    63  		Expect(eventCounter).To(BeNumerically(">", 0))
    64  	})
    65  
    66  	It("podman system prune - pod,container stopped", func() {
    67  		// Start and stop a pod to enter in exited state.
    68  		_, err := pods.Start(bt.conn, newpod, nil)
    69  		Expect(err).ToNot(HaveOccurred())
    70  		_, err = pods.Stop(bt.conn, newpod, nil)
    71  		Expect(err).ToNot(HaveOccurred())
    72  		// Start and stop a container to enter in exited state.
    73  		var name = "top"
    74  		_, err = bt.RunTopContainer(&name, nil)
    75  		Expect(err).ToNot(HaveOccurred())
    76  		err = containers.Stop(bt.conn, name, nil)
    77  		Expect(err).ToNot(HaveOccurred())
    78  
    79  		options := new(system.PruneOptions).WithAll(true)
    80  		systemPruneResponse, err := system.Prune(bt.conn, options)
    81  		Expect(err).ToNot(HaveOccurred())
    82  		Expect(systemPruneResponse.PodPruneReport).To(HaveLen(1))
    83  		Expect(systemPruneResponse.ContainerPruneReports).To(HaveLen(1))
    84  		Expect(systemPruneResponse.ImagePruneReports).
    85  			ToNot(BeEmpty())
    86  		Expect(systemPruneResponse.VolumePruneReports).To(BeEmpty())
    87  	})
    88  
    89  	It("podman system prune running alpine container", func() {
    90  		// Start and stop a pod to enter in exited state.
    91  		_, err := pods.Start(bt.conn, newpod, nil)
    92  		Expect(err).ToNot(HaveOccurred())
    93  		_, err = pods.Stop(bt.conn, newpod, nil)
    94  		Expect(err).ToNot(HaveOccurred())
    95  
    96  		// Start and stop a container to enter in exited state.
    97  		var name = "top"
    98  		_, err = bt.RunTopContainer(&name, nil)
    99  		Expect(err).ToNot(HaveOccurred())
   100  		err = containers.Stop(bt.conn, name, nil)
   101  		Expect(err).ToNot(HaveOccurred())
   102  
   103  		// Start container and leave in running
   104  		var name2 = "top2"
   105  		_, err = bt.RunTopContainer(&name2, nil)
   106  		Expect(err).ToNot(HaveOccurred())
   107  
   108  		// Adding an unused volume
   109  		_, err = volumes.Create(bt.conn, entities.VolumeCreateOptions{}, nil)
   110  		Expect(err).ToNot(HaveOccurred())
   111  		options := new(system.PruneOptions).WithAll(true)
   112  		systemPruneResponse, err := system.Prune(bt.conn, options)
   113  		Expect(err).ToNot(HaveOccurred())
   114  		Expect(systemPruneResponse.PodPruneReport).To(HaveLen(1))
   115  		Expect(systemPruneResponse.ContainerPruneReports).To(HaveLen(1))
   116  		Expect(systemPruneResponse.ImagePruneReports).
   117  			ToNot(BeEmpty())
   118  		// Alpine image should not be pruned as used by running container
   119  		Expect(reports.PruneReportsIds(systemPruneResponse.ImagePruneReports)).
   120  			ToNot(ContainElement("docker.io/library/alpine:latest"))
   121  		// Though unused volume is available it should not be pruned as flag set to false.
   122  		Expect(systemPruneResponse.VolumePruneReports).To(BeEmpty())
   123  	})
   124  
   125  	It("podman system prune running alpine container volume prune", func() {
   126  		// Start a pod and leave it running
   127  		_, err := pods.Start(bt.conn, newpod, nil)
   128  		Expect(err).ToNot(HaveOccurred())
   129  
   130  		// Start and stop a container to enter in exited state.
   131  		var name = "top"
   132  		_, err = bt.RunTopContainer(&name, nil)
   133  		Expect(err).ToNot(HaveOccurred())
   134  		err = containers.Stop(bt.conn, name, nil)
   135  		Expect(err).ToNot(HaveOccurred())
   136  
   137  		// Start second container and leave in running
   138  		var name2 = "top2"
   139  		_, err = bt.RunTopContainer(&name2, nil)
   140  		Expect(err).ToNot(HaveOccurred())
   141  
   142  		// Adding an unused volume should work
   143  		_, err = volumes.Create(bt.conn, entities.VolumeCreateOptions{}, nil)
   144  		Expect(err).ToNot(HaveOccurred())
   145  
   146  		options := new(system.PruneOptions).WithAll(true).WithVolumes(true)
   147  		systemPruneResponse, err := system.Prune(bt.conn, options)
   148  		Expect(err).ToNot(HaveOccurred())
   149  		Expect(systemPruneResponse.PodPruneReport).To(BeEmpty())
   150  		Expect(systemPruneResponse.ContainerPruneReports).To(HaveLen(1))
   151  		Expect(systemPruneResponse.ImagePruneReports).
   152  			ToNot(BeEmpty())
   153  		// Alpine image should not be pruned as used by running container
   154  		Expect(reports.PruneReportsIds(systemPruneResponse.ImagePruneReports)).
   155  			ToNot(ContainElement("docker.io/library/alpine:latest"))
   156  		// Volume should be pruned now as flag set true
   157  		Expect(systemPruneResponse.VolumePruneReports).To(HaveLen(1))
   158  	})
   159  
   160  	It("podman system prune running alpine container volume prune --filter", func() {
   161  		// Start a pod and leave it running
   162  		_, err := pods.Start(bt.conn, newpod, nil)
   163  		Expect(err).ToNot(HaveOccurred())
   164  
   165  		// Start and stop a container to enter in exited state.
   166  		var name = "top"
   167  		_, err = bt.RunTopContainer(&name, nil)
   168  		Expect(err).ToNot(HaveOccurred())
   169  		err = containers.Stop(bt.conn, name, nil)
   170  		Expect(err).ToNot(HaveOccurred())
   171  
   172  		// Start second container and leave in running
   173  		var name2 = "top2"
   174  		_, err = bt.RunTopContainer(&name2, nil)
   175  		Expect(err).ToNot(HaveOccurred())
   176  
   177  		// Adding an unused volume should work
   178  		_, err = volumes.Create(bt.conn, entities.VolumeCreateOptions{}, nil)
   179  		Expect(err).ToNot(HaveOccurred())
   180  
   181  		// Adding an unused volume with label should work
   182  		_, err = volumes.Create(bt.conn, entities.VolumeCreateOptions{Label: map[string]string{
   183  			"label1": "value1",
   184  		}}, nil)
   185  		Expect(err).ToNot(HaveOccurred())
   186  
   187  		f := make(map[string][]string)
   188  		f["label"] = []string{"label1=idontmatch"}
   189  
   190  		options := new(system.PruneOptions).WithAll(true).WithVolumes(true).WithFilters(f)
   191  		systemPruneResponse, err := system.Prune(bt.conn, options)
   192  		Expect(err).ToNot(HaveOccurred())
   193  		Expect(systemPruneResponse.PodPruneReport).To(BeEmpty())
   194  		Expect(systemPruneResponse.ContainerPruneReports).To(BeEmpty())
   195  		Expect(systemPruneResponse.ImagePruneReports).To(BeEmpty())
   196  		// Alpine image should not be pruned as used by running container
   197  		Expect(reports.PruneReportsIds(systemPruneResponse.ImagePruneReports)).
   198  			ToNot(ContainElement("docker.io/library/alpine:latest"))
   199  		// Volume shouldn't be pruned because the PruneOptions filters doesn't match
   200  		Expect(systemPruneResponse.VolumePruneReports).To(BeEmpty())
   201  
   202  		// Fix filter and re prune
   203  		f["label"] = []string{"label1=value1"}
   204  		options = new(system.PruneOptions).WithAll(true).WithVolumes(true).WithFilters(f)
   205  		systemPruneResponse, err = system.Prune(bt.conn, options)
   206  		Expect(err).ToNot(HaveOccurred())
   207  
   208  		// Volume should be pruned because the PruneOptions filters now match
   209  		Expect(systemPruneResponse.VolumePruneReports).To(HaveLen(1))
   210  	})
   211  })