github.com/containers/podman/v4@v4.9.4/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/v4/libpod/events"
    11  	. "github.com/containers/podman/v4/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  		stop := podmanTest.Podman([]string{"pod", "stop", "foobarpod"})
    91  		stop.WaitWithDefaultTimeout()
    92  		Expect(stop).Should(ExitCleanly())
    93  		Expect(setup).Should(ExitCleanly())
    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  		_, ec, _ := podmanTest.RunLsContainer("")
   123  		Expect(ec).To(Equal(0))
   124  
   125  		test := podmanTest.Podman([]string{"events", "--stream=false", "--format", "json"})
   126  		test.WaitWithDefaultTimeout()
   127  		Expect(test).To(ExitCleanly())
   128  
   129  		jsonArr := test.OutputToStringArray()
   130  		Expect(test.OutputToStringArray()).ShouldNot(BeEmpty())
   131  
   132  		event := events.Event{}
   133  		err := json.Unmarshal([]byte(jsonArr[0]), &event)
   134  		Expect(err).ToNot(HaveOccurred())
   135  
   136  		test = podmanTest.Podman([]string{"events", "--stream=false", "--format", "{{json.}}"})
   137  		test.WaitWithDefaultTimeout()
   138  		Expect(test).To(ExitCleanly())
   139  
   140  		jsonArr = test.OutputToStringArray()
   141  		Expect(test.OutputToStringArray()).ShouldNot(BeEmpty())
   142  
   143  		event = events.Event{}
   144  		err = json.Unmarshal([]byte(jsonArr[0]), &event)
   145  		Expect(err).ToNot(HaveOccurred())
   146  
   147  		test = podmanTest.Podman([]string{"events", "--stream=false", "--filter=type=container", "--format", "ID: {{.ID}}"})
   148  		test.WaitWithDefaultTimeout()
   149  		Expect(test).To(ExitCleanly())
   150  		arr := test.OutputToStringArray()
   151  		Expect(len(arr)).To(BeNumerically(">", 1))
   152  		Expect(arr[0]).To(MatchRegexp("ID: [a-fA-F0-9]{64}"))
   153  	})
   154  
   155  	It("podman events --until future", func() {
   156  		name1 := stringid.GenerateRandomID()
   157  		name2 := stringid.GenerateRandomID()
   158  		name3 := stringid.GenerateRandomID()
   159  		session := podmanTest.Podman([]string{"create", "--name", name1, ALPINE})
   160  		session.WaitWithDefaultTimeout()
   161  		Expect(session).Should(ExitCleanly())
   162  
   163  		var wg sync.WaitGroup
   164  		wg.Add(1)
   165  		go func() {
   166  			defer GinkgoRecover()
   167  			defer wg.Done()
   168  
   169  			// wait 2 seconds to be sure events is running
   170  			time.Sleep(time.Second * 2)
   171  			session = podmanTest.Podman([]string{"create", "--name", name2, ALPINE})
   172  			session.WaitWithDefaultTimeout()
   173  			Expect(session).Should(ExitCleanly())
   174  			session = podmanTest.Podman([]string{"create", "--name", name3, ALPINE})
   175  			session.WaitWithDefaultTimeout()
   176  			Expect(session).Should(ExitCleanly())
   177  		}()
   178  
   179  		// unix timestamp in 10 seconds
   180  		until := time.Now().Add(time.Second * 10).Unix()
   181  		result := podmanTest.Podman([]string{"events", "--since", "30s", "--until", strconv.FormatInt(until, 10)})
   182  		result.Wait(11)
   183  		Expect(result).Should(ExitCleanly())
   184  		Expect(result.OutputToString()).To(ContainSubstring(name1))
   185  		Expect(result.OutputToString()).To(ContainSubstring(name2))
   186  		Expect(result.OutputToString()).To(ContainSubstring(name3))
   187  
   188  		// string duration in 10 seconds
   189  		untilT := time.Now().Add(time.Second * 9)
   190  		result = podmanTest.Podman([]string{"events", "--since", "30s", "--until", "10s"})
   191  		result.Wait(11)
   192  		Expect(result).Should(ExitCleanly())
   193  		tEnd := time.Now()
   194  		outDur := tEnd.Sub(untilT)
   195  		Expect(outDur.Seconds()).To(BeNumerically(">", 0), "duration")
   196  		Expect(result.OutputToString()).To(ContainSubstring(name1))
   197  		Expect(result.OutputToString()).To(ContainSubstring(name2))
   198  		Expect(result.OutputToString()).To(ContainSubstring(name3))
   199  
   200  		wg.Wait()
   201  	})
   202  
   203  	It("podman events pod creation", func() {
   204  		create := podmanTest.Podman([]string{"pod", "create", "--infra=false", "--name", "foobarpod"})
   205  		create.WaitWithDefaultTimeout()
   206  		Expect(create).Should(ExitCleanly())
   207  		id := create.OutputToString()
   208  		result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "pod=" + id})
   209  		result.WaitWithDefaultTimeout()
   210  		Expect(result).Should(ExitCleanly())
   211  		Expect(result.OutputToStringArray()).To(HaveLen(1))
   212  		Expect(result.OutputToString()).To(ContainSubstring("create"))
   213  
   214  		ctrName := "testCtr"
   215  		run := podmanTest.Podman([]string{"create", "--pod", id, "--name", ctrName, ALPINE, "top"})
   216  		run.WaitWithDefaultTimeout()
   217  		Expect(run).Should(ExitCleanly())
   218  
   219  		result2 := podmanTest.Podman([]string{"events", "--stream=false", "--filter", fmt.Sprintf("container=%s", ctrName), "--since", "30s"})
   220  		result2.WaitWithDefaultTimeout()
   221  		Expect(result2).Should(ExitCleanly())
   222  		Expect(result2.OutputToString()).To(ContainSubstring(fmt.Sprintf("pod_id=%s", id)))
   223  	})
   224  
   225  	It("podman events health_status generated", func() {
   226  		session := podmanTest.Podman([]string{"run", "--name", "test-hc", "-dt", "--health-cmd", "echo working", "busybox"})
   227  		session.WaitWithDefaultTimeout()
   228  		Expect(session).Should(ExitCleanly())
   229  
   230  		for i := 0; i < 5; i++ {
   231  			hc := podmanTest.Podman([]string{"healthcheck", "run", "test-hc"})
   232  			hc.WaitWithDefaultTimeout()
   233  			exitCode := hc.ExitCode()
   234  			if exitCode == 0 || i == 4 {
   235  				break
   236  			}
   237  			time.Sleep(1 * time.Second)
   238  		}
   239  
   240  		result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "event=health_status", "--since", "1m"})
   241  		result.WaitWithDefaultTimeout()
   242  		Expect(result).Should(ExitCleanly())
   243  		Expect(result.OutputToStringArray()).ToNot(BeEmpty(), "Number of health_status events")
   244  	})
   245  
   246  })