From ca1e76ff632dec0b0e00e25f26677887ca8cc625 Mon Sep 17 00:00:00 2001
From: baude <bbaude@redhat.com>
Date: Thu, 28 Feb 2019 14:15:56 -0600
Subject: Add event logging to libpod, even display to podman

In lipod, we now log major events that occurr.  These events
can be displayed using the `podman events` command. Each
event contains:

* Type (container, image, volume, pod...)
* Status (create, rm, stop, kill, ....)
* Timestamp in RFC3339Nano format
* Name (if applicable)
* Image (if applicable)

The format of the event and the varlink endpoint are to not
be considered stable until cockpit has done its enablement.

Signed-off-by: baude <bbaude@redhat.com>
---
 test/e2e/common_test.go       |   2 +
 test/e2e/events_test.go       | 116 ++++++++++++++++++++++++++++++++++++++++++
 test/e2e/libpod_suite_test.go |   4 +-
 3 files changed, 120 insertions(+), 2 deletions(-)
 create mode 100644 test/e2e/events_test.go

(limited to 'test/e2e')

diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go
index ecd6d812f..afd6d3cf3 100644
--- a/test/e2e/common_test.go
+++ b/test/e2e/common_test.go
@@ -45,6 +45,7 @@ type PodmanTestIntegration struct {
 	CgroupManager       string
 	Host                HostOS
 	Timings             []string
+	TmpDir              string
 }
 
 var LockTmpDir string
@@ -245,6 +246,7 @@ func PodmanTestCreateUtil(tempDir string, remote bool) *PodmanTestIntegration {
 		},
 		ConmonBinary:        conmonBinary,
 		CrioRoot:            filepath.Join(tempDir, "crio"),
+		TmpDir:              tempDir,
 		CNIConfigDir:        CNIConfigDir,
 		OCIRuntime:          ociRuntime,
 		RunRoot:             filepath.Join(tempDir, "crio-run"),
diff --git a/test/e2e/events_test.go b/test/e2e/events_test.go
new file mode 100644
index 000000000..321d93757
--- /dev/null
+++ b/test/e2e/events_test.go
@@ -0,0 +1,116 @@
+package integration
+
+import (
+	"fmt"
+	"os"
+	"strings"
+
+	. "github.com/containers/libpod/test/utils"
+	. "github.com/onsi/ginkgo"
+	. "github.com/onsi/gomega"
+)
+
+var _ = Describe("Podman events", func() {
+	var (
+		tempdir    string
+		err        error
+		podmanTest *PodmanTestIntegration
+	)
+
+	BeforeEach(func() {
+		tempdir, err = CreateTempDirInTempDir()
+		if err != nil {
+			os.Exit(1)
+		}
+		podmanTest = PodmanTestCreate(tempdir)
+		podmanTest.RestoreAllArtifacts()
+	})
+
+	AfterEach(func() {
+		podmanTest.Cleanup()
+		f := CurrentGinkgoTestDescription()
+		timedResult := fmt.Sprintf("Test: %s completed in %f seconds", f.TestText, f.Duration.Seconds())
+		GinkgoWriter.Write([]byte(timedResult))
+
+	})
+
+	// 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.ExitCode()).To(BeZero())
+	})
+
+	It("podman events with an event filter", func() {
+		SkipIfRemote()
+		_, ec, _ := podmanTest.RunLsContainer("")
+		Expect(ec).To(Equal(0))
+		result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "event=start"})
+		result.WaitWithDefaultTimeout()
+		Expect(result.ExitCode()).To(Equal(0))
+		Expect(len(result.OutputToStringArray())).To(Equal(1))
+	})
+
+	It("podman events with an event filter and container=cid", func() {
+		SkipIfRemote()
+		_, ec, cid := podmanTest.RunLsContainer("")
+		Expect(ec).To(Equal(0))
+		_, ec2, cid2 := podmanTest.RunLsContainer("")
+		Expect(ec2).To(Equal(0))
+		result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "event=start", "--filter", fmt.Sprintf("container=%s", cid)})
+		result.WaitWithDefaultTimeout()
+		Expect(result.ExitCode()).To(Equal(0))
+		Expect(len(result.OutputToStringArray())).To(Equal(1))
+		Expect(!strings.Contains(result.OutputToString(), cid2))
+	})
+
+	It("podman events with a type", func() {
+		SkipIfRemote()
+		_, ec, _ := podmanTest.RunLsContainer("")
+		Expect(ec).To(Equal(0))
+		result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "type=pod"})
+		result.WaitWithDefaultTimeout()
+		Expect(result.ExitCode()).To(Equal(0))
+		Expect(len(result.OutputToStringArray())).To(Equal(0))
+	})
+
+	It("podman events with a type", func() {
+		SkipIfRemote()
+		setup := podmanTest.Podman([]string{"run", "-dt", "--pod", "new:foobar", ALPINE, "top"})
+		setup.WaitWithDefaultTimeout()
+		stop := podmanTest.Podman([]string{"pod", "stop", "foobar"})
+		stop.WaitWithDefaultTimeout()
+		Expect(stop.ExitCode()).To(Equal(0))
+		Expect(setup.ExitCode()).To(Equal(0))
+		result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "type=pod"})
+		result.WaitWithDefaultTimeout()
+		Expect(result.ExitCode()).To(Equal(0))
+		fmt.Println(result.OutputToStringArray())
+		Expect(len(result.OutputToStringArray())).To(Equal(2))
+	})
+
+	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.ExitCode()).To(BeZero())
+	})
+
+	It("podman events --until", func() {
+		_, ec, _ := podmanTest.RunLsContainer("")
+		Expect(ec).To(Equal(0))
+		test := podmanTest.Podman([]string{"events", "--help"})
+		test.WaitWithDefaultTimeout()
+		fmt.Println(test.OutputToStringArray())
+		result := podmanTest.Podman([]string{"events", "--stream=false", "--since", "1h"})
+		result.WaitWithDefaultTimeout()
+		Expect(result.ExitCode()).To(BeZero())
+	})
+
+})
diff --git a/test/e2e/libpod_suite_test.go b/test/e2e/libpod_suite_test.go
index 33e05b872..1a3f37e23 100644
--- a/test/e2e/libpod_suite_test.go
+++ b/test/e2e/libpod_suite_test.go
@@ -206,8 +206,8 @@ func PodmanTestCreate(tempDir string) *PodmanTestIntegration {
 
 //MakeOptions assembles all the podman main options
 func (p *PodmanTestIntegration) makeOptions(args []string) []string {
-	podmanOptions := strings.Split(fmt.Sprintf("--root %s --runroot %s --runtime %s --conmon %s --cni-config-dir %s --cgroup-manager %s",
-		p.CrioRoot, p.RunRoot, p.OCIRuntime, p.ConmonBinary, p.CNIConfigDir, p.CgroupManager), " ")
+	podmanOptions := strings.Split(fmt.Sprintf("--root %s --runroot %s --runtime %s --conmon %s --cni-config-dir %s --cgroup-manager %s --tmpdir %s",
+		p.CrioRoot, p.RunRoot, p.OCIRuntime, p.ConmonBinary, p.CNIConfigDir, p.CgroupManager, p.TmpDir), " ")
 	if os.Getenv("HOOK_OPTION") != "" {
 		podmanOptions = append(podmanOptions, os.Getenv("HOOK_OPTION"))
 	}
-- 
cgit v1.2.3-54-g00ecf