Files
podman/test/e2e/events_test.go
Paul Holzinger 8f1cebf96f cmd/podman: remove duplicated event ToHumanReadable()
ToHumanReadable() exists twice now, there is no reason for this just
call the function on the backend event type is fine as this still has to
be used there.

It also fixes a bug where the wrong event type was passed to the
template which did not match the docs and json output.

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
2024-02-22 12:10:57 +01:00

293 lines
11 KiB
Go

package integration
import (
"encoding/json"
"fmt"
"strconv"
"sync"
"time"
"github.com/containers/podman/v5/cmd/podman/system"
. "github.com/containers/podman/v5/test/utils"
"github.com/containers/storage/pkg/stringid"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("Podman events", func() {
// For most, all, of these tests we do not "live" test following a log because it may make a fragile test
// system more complex. Instead we run the "events" and then verify that the events are processed correctly.
// Perhaps a future version of this test would put events in a go func and send output back over a channel
// while events occur.
It("podman events", func() {
_, ec, _ := podmanTest.RunLsContainer("")
Expect(ec).To(Equal(0))
result := podmanTest.Podman([]string{"events", "--stream=false"})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
})
It("podman events with an event filter", func() {
_, ec, _ := podmanTest.RunLsContainer("")
Expect(ec).To(Equal(0))
result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "event=start"})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
Expect(result.OutputToStringArray()).ToNot(BeEmpty(), "Number of events")
date := time.Now().Format("2006-01-02")
Expect(result.OutputToStringArray()).To(ContainElement(HavePrefix(date)), "event log has correct timestamp")
})
It("podman events with a volume filter", func() {
_, ec, vname := podmanTest.CreateVolume(nil)
Expect(ec).To(Equal(0))
// Run two event commands - one with the full volume name and the second with the prefix
result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", fmt.Sprintf("volume=%s", vname)})
resultPrefix := podmanTest.Podman([]string{"events", "--stream=false", "--filter", fmt.Sprintf("volume=%s", vname[:5])})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
events := result.OutputToStringArray()
Expect(events).To(HaveLen(1), "number of events")
Expect(events[0]).To(ContainSubstring(vname), "event log includes volume name")
resultPrefix.WaitWithDefaultTimeout()
Expect(resultPrefix).Should(ExitCleanly())
events = resultPrefix.OutputToStringArray()
Expect(events).To(HaveLen(1), "number of events")
Expect(events[0]).To(ContainSubstring(vname), "event log includes volume name")
})
It("podman events with an event filter and container=cid", func() {
_, ec, cid := podmanTest.RunLsContainer("")
Expect(ec).To(Equal(0))
_, ec2, cid2 := podmanTest.RunLsContainer("")
Expect(ec2).To(Equal(0))
time.Sleep(5 * time.Second)
result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "event=start", "--filter", fmt.Sprintf("container=%s", cid)})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
events := result.OutputToStringArray()
Expect(events).To(HaveLen(1), "number of events")
Expect(events[0]).To(ContainSubstring(cid), "event log includes CID")
Expect(events[0]).To(Not(ContainSubstring(cid2)), "event log does not include second CID")
})
It("podman events with a type and filter container=id", func() {
_, ec, cid := podmanTest.RunLsContainer("")
Expect(ec).To(Equal(0))
result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "type=pod", "--filter", fmt.Sprintf("container=%s", cid)})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
Expect(result.OutputToStringArray()).To(BeEmpty())
})
It("podman events with a type", func() {
setup := podmanTest.Podman([]string{"run", "-dt", "--pod", "new:foobarpod", ALPINE, "top"})
setup.WaitWithDefaultTimeout()
Expect(setup).Should(ExitCleanly())
podmanTest.StopPod("foobarpod")
result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "type=pod", "--filter", "pod=foobarpod"})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
events := result.OutputToStringArray()
GinkgoWriter.Println(events)
Expect(len(events)).To(BeNumerically(">=", 2), "Number of events")
Expect(events).To(ContainElement(ContainSubstring(" pod create ")))
Expect(events).To(ContainElement(ContainSubstring(" pod stop ")))
Expect(events).To(ContainElement(ContainSubstring("name=foobarpod")))
})
It("podman events --since", func() {
_, ec, _ := podmanTest.RunLsContainer("")
Expect(ec).To(Equal(0))
result := podmanTest.Podman([]string{"events", "--stream=false", "--since", "1m"})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
})
It("podman events --until", func() {
_, ec, _ := podmanTest.RunLsContainer("")
Expect(ec).To(Equal(0))
result := podmanTest.Podman([]string{"events", "--stream=false", "--until", "1h"})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
})
It("podman events format", func() {
start := time.Now()
ctrName := "testCtr"
_, ec, _ := podmanTest.RunLsContainer(ctrName)
end := time.Now()
Expect(ec).To(Equal(0))
test := podmanTest.Podman([]string{"events", "--stream=false", "--format", "json"})
test.WaitWithDefaultTimeout()
Expect(test).To(ExitCleanly())
jsonArr := test.OutputToStringArray()
Expect(test.OutputToStringArray()).ShouldNot(BeEmpty())
event := system.Event{}
err := json.Unmarshal([]byte(jsonArr[0]), &event)
Expect(err).ToNot(HaveOccurred())
test = podmanTest.Podman([]string{
"events",
"--stream=false",
"--since", strconv.FormatInt(start.Unix(), 10),
"--filter", fmt.Sprintf("container=%s", ctrName),
"--format", "{{json .}}",
})
test.WaitWithDefaultTimeout()
Expect(test).To(ExitCleanly())
jsonArr = test.OutputToStringArray()
Expect(test.OutputToStringArray()).ShouldNot(BeEmpty())
event = system.Event{}
err = json.Unmarshal([]byte(jsonArr[0]), &event)
Expect(err).ToNot(HaveOccurred())
Expect(event.Time).To(BeNumerically(">=", start.Unix()))
Expect(event.Time).To(BeNumerically("<=", end.Unix()))
Expect(event.TimeNano).To(BeNumerically(">=", start.UnixNano()))
Expect(event.TimeNano).To(BeNumerically("<=", end.UnixNano()))
Expect(time.Unix(0, event.TimeNano).Unix()).To(BeEquivalentTo(event.Time))
test = podmanTest.Podman([]string{"events", "--stream=false", "--filter=type=container", "--format", "ID: {{.ID}}"})
test.WaitWithDefaultTimeout()
Expect(test).To(ExitCleanly())
arr := test.OutputToStringArray()
Expect(len(arr)).To(BeNumerically(">", 1))
Expect(arr[0]).To(MatchRegexp("ID: [a-fA-F0-9]{64}"))
})
It("podman events --until future", func() {
name1 := stringid.GenerateRandomID()
name2 := stringid.GenerateRandomID()
name3 := stringid.GenerateRandomID()
session := podmanTest.Podman([]string{"create", "--name", name1, ALPINE})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer GinkgoRecover()
defer wg.Done()
// wait 2 seconds to be sure events is running
time.Sleep(time.Second * 2)
session = podmanTest.Podman([]string{"create", "--name", name2, ALPINE})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
session = podmanTest.Podman([]string{"create", "--name", name3, ALPINE})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
}()
// unix timestamp in 10 seconds
until := time.Now().Add(time.Second * 10).Unix()
result := podmanTest.Podman([]string{"events", "--since", "30s", "--until", strconv.FormatInt(until, 10)})
result.Wait(11)
Expect(result).Should(ExitCleanly())
Expect(result.OutputToString()).To(ContainSubstring(name1))
Expect(result.OutputToString()).To(ContainSubstring(name2))
Expect(result.OutputToString()).To(ContainSubstring(name3))
// string duration in 10 seconds
untilT := time.Now().Add(time.Second * 9)
result = podmanTest.Podman([]string{"events", "--since", "30s", "--until", "10s"})
result.Wait(11)
Expect(result).Should(ExitCleanly())
tEnd := time.Now()
outDur := tEnd.Sub(untilT)
Expect(outDur.Seconds()).To(BeNumerically(">", 0), "duration")
Expect(result.OutputToString()).To(ContainSubstring(name1))
Expect(result.OutputToString()).To(ContainSubstring(name2))
Expect(result.OutputToString()).To(ContainSubstring(name3))
wg.Wait()
})
It("podman events pod creation", func() {
create := podmanTest.Podman([]string{"pod", "create", "--infra=false", "--name", "foobarpod"})
create.WaitWithDefaultTimeout()
Expect(create).Should(ExitCleanly())
id := create.OutputToString()
result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "pod=" + id})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
Expect(result.OutputToStringArray()).To(HaveLen(1))
Expect(result.OutputToString()).To(ContainSubstring("create"))
ctrName := "testCtr"
run := podmanTest.Podman([]string{"create", "--pod", id, "--name", ctrName, ALPINE, "top"})
run.WaitWithDefaultTimeout()
Expect(run).Should(ExitCleanly())
result2 := podmanTest.Podman([]string{"events", "--stream=false", "--filter", fmt.Sprintf("container=%s", ctrName), "--since", "30s"})
result2.WaitWithDefaultTimeout()
Expect(result2).Should(ExitCleanly())
Expect(result2.OutputToString()).To(ContainSubstring(fmt.Sprintf("pod_id=%s", id)))
})
It("podman events network connection", func() {
network := stringid.GenerateRandomID()
result := podmanTest.Podman([]string{"create", "--network", "bridge", ALPINE, "top"})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
ctrID := result.OutputToString()
result = podmanTest.Podman([]string{"network", "create", network})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
result = podmanTest.Podman([]string{"network", "connect", network, ctrID})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
result = podmanTest.Podman([]string{"network", "disconnect", network, ctrID})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
result = podmanTest.Podman([]string{"events", "--stream=false", "--since", "30s"})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
lines := result.OutputToStringArray()
Expect(lines).To(HaveLen(5))
Expect(lines[3]).To(ContainSubstring("network connect"))
Expect(lines[3]).To(ContainSubstring(fmt.Sprintf("(container=%s, name=%s)", ctrID, network)))
Expect(lines[4]).To(ContainSubstring("network disconnect"))
Expect(lines[4]).To(ContainSubstring(fmt.Sprintf("(container=%s, name=%s)", ctrID, network)))
})
It("podman events health_status generated", func() {
session := podmanTest.Podman([]string{"run", "--name", "test-hc", "-dt", "--health-cmd", "echo working", "busybox"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
for i := 0; i < 5; i++ {
hc := podmanTest.Podman([]string{"healthcheck", "run", "test-hc"})
hc.WaitWithDefaultTimeout()
exitCode := hc.ExitCode()
if exitCode == 0 || i == 4 {
break
}
time.Sleep(1 * time.Second)
}
result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "event=health_status", "--since", "1m"})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
Expect(result.OutputToStringArray()).ToNot(BeEmpty(), "Number of health_status events")
})
})