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