podman/test/e2e/top_test.go

176 lines
6.9 KiB
Go

//go:build linux || freebsd
package integration
import (
"os"
"os/user"
. "github.com/containers/podman/v5/test/utils"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("Podman top", func() {
It("podman top without container name or id", func() {
result := podmanTest.Podman([]string{"top"})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitWithError(125, "you must provide the name or id of a running container"))
})
It("podman top on bogus container", func() {
result := podmanTest.Podman([]string{"top", "1234"})
result.WaitWithDefaultTimeout()
expect := `no container with name or ID "1234" found: no such container`
if !IsRemote() {
expect = `unable to look up requested container: ` + expect
}
Expect(result).Should(ExitWithError(125, expect))
})
It("podman top on non-running container", func() {
_, ec, cid := podmanTest.RunLsContainer("")
Expect(ec).To(Equal(0))
result := podmanTest.Podman([]string{"top", cid})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitWithError(125, "top can only be used on running containers"))
})
It("podman top on container", func() {
session := podmanTest.Podman([]string{"run", "--name", "test", "-d", ALPINE, "top", "-d", "2"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
result := podmanTest.Podman([]string{"top", "test"})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
Expect(len(result.OutputToStringArray())).To(BeNumerically(">", 1))
})
It("podman container top on container", func() {
session := podmanTest.Podman([]string{"container", "run", "--name", "test", "-d", ALPINE, "top", "-d", "2"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
result := podmanTest.Podman([]string{"container", "top", "test"})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
Expect(len(result.OutputToStringArray())).To(BeNumerically(">", 1))
// Just a smoke test since groups may change over time.
result = podmanTest.Podman([]string{"container", "top", "test", "groups", "hgroups"})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
Expect(len(result.OutputToStringArray())).To(BeNumerically(">", 1))
})
It("podman top with options", func() {
session := podmanTest.Podman([]string{"run", "-d", ALPINE, "top", "-d", "2"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
result := podmanTest.Podman([]string{"top", session.OutputToString(), "pid", "%C", "args"})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
Expect(len(result.OutputToStringArray())).To(BeNumerically(">", 1))
result = podmanTest.Podman([]string{"container", "top", session.OutputToString(), "uid"})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
Expect(len(result.OutputToStringArray())).To(BeNumerically(">", 1))
Expect(result.OutputToStringArray()[1]).To(Equal("0"))
user, err := user.Current()
if err != nil {
os.Exit(1)
}
result = podmanTest.Podman([]string{"container", "top", session.OutputToString(), "huid"})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
Expect(len(result.OutputToStringArray())).To(BeNumerically(">", 1))
Expect(result.OutputToStringArray()[1]).To(Equal(user.Uid))
})
It("podman top with ps(1) options", func() {
session := podmanTest.Podman([]string{"run", "-d", fedoraMinimal, "sleep", "inf"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
result := podmanTest.Podman([]string{"top", session.OutputToString(), "aux"})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
Expect(len(result.OutputToStringArray())).To(BeNumerically(">", 1))
result = podmanTest.Podman([]string{"top", session.OutputToString(), "ax -o args"})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
result = podmanTest.Podman([]string{"top", session.OutputToString(), "ax", "-o", "args"})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
Expect(result.OutputToStringArray()).To(Equal([]string{"COMMAND", "sleep inf"}))
// Now make sure we use ps in the container with CAP_SYS_PTRACE
session = podmanTest.Podman([]string{"run", "-d", "--cap-add=SYS_PTRACE", fedoraMinimal, "sleep", "inf"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
// Because the image does not contain this must fail and we know we use the correct podman exec fallback.
exec := podmanTest.Podman([]string{"top", session.OutputToString(), "aux"})
exec.WaitWithDefaultTimeout()
Expect(exec).Should(ExitWithError(125, "OCI runtime attempted to invoke a command that was not found"))
session = podmanTest.Podman([]string{"run", "-d", "--uidmap=0:1000:1000", "--user", "9", fedoraMinimal, "sleep", "inf"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
result = podmanTest.Podman([]string{"top", session.OutputToString(), "-ef", "hn"})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
output := result.OutputToString()
Expect(output).To(ContainSubstring("sleep inf"))
// check for https://github.com/containers/podman/issues/22293
Expect(output).To(HavePrefix("9 "), "user id of process")
})
It("podman top with comma-separated options", func() {
session := podmanTest.Podman([]string{"run", "-d", ALPINE, "top", "-d", "2"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
result := podmanTest.Podman([]string{"top", session.OutputToString(), "user,pid,comm"})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
Expect(len(result.OutputToStringArray())).To(BeNumerically(">", 1))
})
It("podman top on container invalid options", func() {
top := podmanTest.RunTopContainer("")
top.WaitWithDefaultTimeout()
Expect(top).Should(ExitCleanly())
cid := top.OutputToString()
// We need to pass -eo to force executing ps in the Alpine container.
// Alpines stripped down ps(1) is accepting any kind of weird input in
// contrast to others, such that a `ps invalid` will silently ignore
// the wrong input and still print the -ef output instead.
result := podmanTest.Podman([]string{"top", cid, "-eo", "invalid"})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitWithError(125, `Error: ps(1) failed with exit code 1: error: unknown user-defined format specifier "invalid"`))
})
It("podman top on privileged container", func() {
session := podmanTest.Podman([]string{"run", "--privileged", "-d", ALPINE, "top"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
cid := session.OutputToString()
result := podmanTest.Podman([]string{"top", cid, "capeff"})
result.WaitWithDefaultTimeout()
Expect(result).Should(ExitCleanly())
Expect(result.OutputToStringArray()).To(Equal([]string{"EFFECTIVE CAPS", "full"}))
})
})