github.com/containers/podman/v5@v5.1.0-rc1/test/e2e/events_test.go (about) 1 package integration 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "strconv" 7 "sync" 8 "time" 9 10 "github.com/containers/podman/v5/cmd/podman/system" 11 . "github.com/containers/podman/v5/test/utils" 12 "github.com/containers/storage/pkg/stringid" 13 . "github.com/onsi/ginkgo/v2" 14 . "github.com/onsi/gomega" 15 ) 16 17 var _ = Describe("Podman events", func() { 18 19 // For most, all, of these tests we do not "live" test following a log because it may make a fragile test 20 // system more complex. Instead we run the "events" and then verify that the events are processed correctly. 21 // Perhaps a future version of this test would put events in a go func and send output back over a channel 22 // while events occur. 23 24 It("podman events", func() { 25 _, ec, _ := podmanTest.RunLsContainer("") 26 Expect(ec).To(Equal(0)) 27 result := podmanTest.Podman([]string{"events", "--stream=false"}) 28 result.WaitWithDefaultTimeout() 29 Expect(result).Should(ExitCleanly()) 30 }) 31 32 It("podman events with an event filter", func() { 33 _, ec, _ := podmanTest.RunLsContainer("") 34 Expect(ec).To(Equal(0)) 35 result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "event=start"}) 36 result.WaitWithDefaultTimeout() 37 Expect(result).Should(ExitCleanly()) 38 Expect(result.OutputToStringArray()).ToNot(BeEmpty(), "Number of events") 39 date := time.Now().Format("2006-01-02") 40 Expect(result.OutputToStringArray()).To(ContainElement(HavePrefix(date)), "event log has correct timestamp") 41 }) 42 It("podman events with a volume filter", func() { 43 _, ec, vname := podmanTest.CreateVolume(nil) 44 Expect(ec).To(Equal(0)) 45 46 // Run two event commands - one with the full volume name and the second with the prefix 47 result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", fmt.Sprintf("volume=%s", vname)}) 48 resultPrefix := podmanTest.Podman([]string{"events", "--stream=false", "--filter", fmt.Sprintf("volume=%s", vname[:5])}) 49 50 result.WaitWithDefaultTimeout() 51 Expect(result).Should(ExitCleanly()) 52 events := result.OutputToStringArray() 53 Expect(events).To(HaveLen(1), "number of events") 54 Expect(events[0]).To(ContainSubstring(vname), "event log includes volume name") 55 56 resultPrefix.WaitWithDefaultTimeout() 57 Expect(resultPrefix).Should(ExitCleanly()) 58 events = resultPrefix.OutputToStringArray() 59 Expect(events).To(HaveLen(1), "number of events") 60 Expect(events[0]).To(ContainSubstring(vname), "event log includes volume name") 61 }) 62 63 It("podman events with an event filter and container=cid", func() { 64 _, ec, cid := podmanTest.RunLsContainer("") 65 Expect(ec).To(Equal(0)) 66 _, ec2, cid2 := podmanTest.RunLsContainer("") 67 Expect(ec2).To(Equal(0)) 68 time.Sleep(5 * time.Second) 69 result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "event=start", "--filter", fmt.Sprintf("container=%s", cid)}) 70 result.WaitWithDefaultTimeout() 71 Expect(result).Should(ExitCleanly()) 72 events := result.OutputToStringArray() 73 Expect(events).To(HaveLen(1), "number of events") 74 Expect(events[0]).To(ContainSubstring(cid), "event log includes CID") 75 Expect(events[0]).To(Not(ContainSubstring(cid2)), "event log does not include second CID") 76 }) 77 78 It("podman events with a type and filter container=id", func() { 79 _, ec, cid := podmanTest.RunLsContainer("") 80 Expect(ec).To(Equal(0)) 81 result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "type=pod", "--filter", fmt.Sprintf("container=%s", cid)}) 82 result.WaitWithDefaultTimeout() 83 Expect(result).Should(ExitCleanly()) 84 Expect(result.OutputToStringArray()).To(BeEmpty()) 85 }) 86 87 It("podman events with a type", func() { 88 setup := podmanTest.Podman([]string{"run", "-dt", "--pod", "new:foobarpod", ALPINE, "top"}) 89 setup.WaitWithDefaultTimeout() 90 Expect(setup).Should(ExitCleanly()) 91 92 podmanTest.StopPod("foobarpod") 93 94 result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "type=pod", "--filter", "pod=foobarpod"}) 95 result.WaitWithDefaultTimeout() 96 Expect(result).Should(ExitCleanly()) 97 events := result.OutputToStringArray() 98 GinkgoWriter.Println(events) 99 Expect(len(events)).To(BeNumerically(">=", 2), "Number of events") 100 Expect(events).To(ContainElement(ContainSubstring(" pod create "))) 101 Expect(events).To(ContainElement(ContainSubstring(" pod stop "))) 102 Expect(events).To(ContainElement(ContainSubstring("name=foobarpod"))) 103 }) 104 105 It("podman events --since", func() { 106 _, ec, _ := podmanTest.RunLsContainer("") 107 Expect(ec).To(Equal(0)) 108 result := podmanTest.Podman([]string{"events", "--stream=false", "--since", "1m"}) 109 result.WaitWithDefaultTimeout() 110 Expect(result).Should(ExitCleanly()) 111 }) 112 113 It("podman events --until", func() { 114 _, ec, _ := podmanTest.RunLsContainer("") 115 Expect(ec).To(Equal(0)) 116 result := podmanTest.Podman([]string{"events", "--stream=false", "--until", "1h"}) 117 result.WaitWithDefaultTimeout() 118 Expect(result).Should(ExitCleanly()) 119 }) 120 121 It("podman events format", func() { 122 start := time.Now() 123 ctrName := "testCtr" 124 _, ec, _ := podmanTest.RunLsContainer(ctrName) 125 end := time.Now() 126 Expect(ec).To(Equal(0)) 127 128 test := podmanTest.Podman([]string{"events", "--stream=false", "--format", "json"}) 129 test.WaitWithDefaultTimeout() 130 Expect(test).To(ExitCleanly()) 131 132 jsonArr := test.OutputToStringArray() 133 Expect(test.OutputToStringArray()).ShouldNot(BeEmpty()) 134 135 event := system.Event{} 136 err := json.Unmarshal([]byte(jsonArr[0]), &event) 137 Expect(err).ToNot(HaveOccurred()) 138 139 test = podmanTest.Podman([]string{ 140 "events", 141 "--stream=false", 142 "--since", strconv.FormatInt(start.Unix(), 10), 143 "--filter", fmt.Sprintf("container=%s", ctrName), 144 "--format", "{{json .}}", 145 }) 146 147 test.WaitWithDefaultTimeout() 148 Expect(test).To(ExitCleanly()) 149 150 jsonArr = test.OutputToStringArray() 151 Expect(test.OutputToStringArray()).ShouldNot(BeEmpty()) 152 153 event = system.Event{} 154 err = json.Unmarshal([]byte(jsonArr[0]), &event) 155 Expect(err).ToNot(HaveOccurred()) 156 157 Expect(event.Time).To(BeNumerically(">=", start.Unix())) 158 Expect(event.Time).To(BeNumerically("<=", end.Unix())) 159 Expect(event.TimeNano).To(BeNumerically(">=", start.UnixNano())) 160 Expect(event.TimeNano).To(BeNumerically("<=", end.UnixNano())) 161 Expect(time.Unix(0, event.TimeNano).Unix()).To(BeEquivalentTo(event.Time)) 162 163 test = podmanTest.Podman([]string{"events", "--stream=false", "--filter=type=container", "--format", "ID: {{.ID}}"}) 164 test.WaitWithDefaultTimeout() 165 Expect(test).To(ExitCleanly()) 166 arr := test.OutputToStringArray() 167 Expect(len(arr)).To(BeNumerically(">", 1)) 168 Expect(arr[0]).To(MatchRegexp("ID: [a-fA-F0-9]{64}")) 169 }) 170 171 It("podman events --until future", func() { 172 name1 := stringid.GenerateRandomID() 173 name2 := stringid.GenerateRandomID() 174 name3 := stringid.GenerateRandomID() 175 session := podmanTest.Podman([]string{"create", "--name", name1, ALPINE}) 176 session.WaitWithDefaultTimeout() 177 Expect(session).Should(ExitCleanly()) 178 179 var wg sync.WaitGroup 180 wg.Add(1) 181 go func() { 182 defer GinkgoRecover() 183 defer wg.Done() 184 185 // wait 2 seconds to be sure events is running 186 time.Sleep(time.Second * 2) 187 session = podmanTest.Podman([]string{"create", "--name", name2, ALPINE}) 188 session.WaitWithDefaultTimeout() 189 Expect(session).Should(ExitCleanly()) 190 session = podmanTest.Podman([]string{"create", "--name", name3, ALPINE}) 191 session.WaitWithDefaultTimeout() 192 Expect(session).Should(ExitCleanly()) 193 }() 194 195 // unix timestamp in 10 seconds 196 until := time.Now().Add(time.Second * 10).Unix() 197 result := podmanTest.Podman([]string{"events", "--since", "30s", "--until", strconv.FormatInt(until, 10)}) 198 result.Wait(11) 199 Expect(result).Should(ExitCleanly()) 200 Expect(result.OutputToString()).To(ContainSubstring(name1)) 201 Expect(result.OutputToString()).To(ContainSubstring(name2)) 202 Expect(result.OutputToString()).To(ContainSubstring(name3)) 203 204 // string duration in 10 seconds 205 untilT := time.Now().Add(time.Second * 9) 206 result = podmanTest.Podman([]string{"events", "--since", "30s", "--until", "10s"}) 207 result.Wait(11) 208 Expect(result).Should(ExitCleanly()) 209 tEnd := time.Now() 210 outDur := tEnd.Sub(untilT) 211 Expect(outDur.Seconds()).To(BeNumerically(">", 0), "duration") 212 Expect(result.OutputToString()).To(ContainSubstring(name1)) 213 Expect(result.OutputToString()).To(ContainSubstring(name2)) 214 Expect(result.OutputToString()).To(ContainSubstring(name3)) 215 216 wg.Wait() 217 }) 218 219 It("podman events pod creation", func() { 220 create := podmanTest.Podman([]string{"pod", "create", "--infra=false", "--name", "foobarpod"}) 221 create.WaitWithDefaultTimeout() 222 Expect(create).Should(ExitCleanly()) 223 id := create.OutputToString() 224 result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "pod=" + id}) 225 result.WaitWithDefaultTimeout() 226 Expect(result).Should(ExitCleanly()) 227 Expect(result.OutputToStringArray()).To(HaveLen(1)) 228 Expect(result.OutputToString()).To(ContainSubstring("create")) 229 230 ctrName := "testCtr" 231 run := podmanTest.Podman([]string{"create", "--pod", id, "--name", ctrName, ALPINE, "top"}) 232 run.WaitWithDefaultTimeout() 233 Expect(run).Should(ExitCleanly()) 234 235 result2 := podmanTest.Podman([]string{"events", "--stream=false", "--filter", fmt.Sprintf("container=%s", ctrName), "--since", "30s"}) 236 result2.WaitWithDefaultTimeout() 237 Expect(result2).Should(ExitCleanly()) 238 Expect(result2.OutputToString()).To(ContainSubstring(fmt.Sprintf("pod_id=%s", id))) 239 }) 240 241 It("podman events network connection", func() { 242 network := stringid.GenerateRandomID() 243 result := podmanTest.Podman([]string{"create", "--network", "bridge", ALPINE, "top"}) 244 result.WaitWithDefaultTimeout() 245 Expect(result).Should(ExitCleanly()) 246 ctrID := result.OutputToString() 247 248 result = podmanTest.Podman([]string{"network", "create", network}) 249 result.WaitWithDefaultTimeout() 250 Expect(result).Should(ExitCleanly()) 251 252 result = podmanTest.Podman([]string{"network", "connect", network, ctrID}) 253 result.WaitWithDefaultTimeout() 254 Expect(result).Should(ExitCleanly()) 255 256 result = podmanTest.Podman([]string{"network", "disconnect", network, ctrID}) 257 result.WaitWithDefaultTimeout() 258 Expect(result).Should(ExitCleanly()) 259 260 result = podmanTest.Podman([]string{"events", "--stream=false", "--since", "30s"}) 261 result.WaitWithDefaultTimeout() 262 Expect(result).Should(ExitCleanly()) 263 lines := result.OutputToStringArray() 264 Expect(lines).To(HaveLen(5)) 265 Expect(lines[3]).To(ContainSubstring("network connect")) 266 Expect(lines[3]).To(ContainSubstring(fmt.Sprintf("(container=%s, name=%s)", ctrID, network))) 267 Expect(lines[4]).To(ContainSubstring("network disconnect")) 268 Expect(lines[4]).To(ContainSubstring(fmt.Sprintf("(container=%s, name=%s)", ctrID, network))) 269 }) 270 271 It("podman events health_status generated", func() { 272 session := podmanTest.Podman([]string{"run", "--name", "test-hc", "-dt", "--health-cmd", "echo working", "busybox"}) 273 session.WaitWithDefaultTimeout() 274 Expect(session).Should(ExitCleanly()) 275 276 for i := 0; i < 5; i++ { 277 hc := podmanTest.Podman([]string{"healthcheck", "run", "test-hc"}) 278 hc.WaitWithDefaultTimeout() 279 exitCode := hc.ExitCode() 280 if exitCode == 0 || i == 4 { 281 break 282 } 283 time.Sleep(1 * time.Second) 284 } 285 286 result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "event=health_status", "--since", "1m"}) 287 result.WaitWithDefaultTimeout() 288 Expect(result).Should(ExitCleanly()) 289 Expect(result.OutputToStringArray()).ToNot(BeEmpty(), "Number of health_status events") 290 }) 291 292 })