summaryrefslogtreecommitdiff
path: root/test/e2e/system_service_test.go
diff options
context:
space:
mode:
authorJhon Honce <jhonce@redhat.com>2021-10-05 10:43:55 -0700
committerJhon Honce <jhonce@redhat.com>2021-10-08 13:57:20 -0700
commit8d3aec9d08bddf486dcb30e7113777b9d0cc27bd (patch)
treee47d47a39f50f7cadaaf0c8bd81f5ed689081b1a /test/e2e/system_service_test.go
parentbd4d9a09520b2329b1cf3dd8cdf8194b8bdeab67 (diff)
downloadpodman-8d3aec9d08bddf486dcb30e7113777b9d0cc27bd.tar.gz
podman-8d3aec9d08bddf486dcb30e7113777b9d0cc27bd.tar.bz2
podman-8d3aec9d08bddf486dcb30e7113777b9d0cc27bd.zip
Enable /debug/pprof API service endpoints
* Refactor sidecar HTTP service for /debug/pprof endpoints to use a TCP address given via new podman system service --pprof-address flag * Allow same URL parsing in "system service" as bindings/connection.go * Refactor NewServerWithSettings() to use entities.ServiceOptions in place of deleted server.Options * Updated godoc for impacted functions and types * Fixed API service Shutdown() to do an orderly shutdown when terminated and running with --time=0 Signed-off-by: Jhon Honce <jhonce@redhat.com>
Diffstat (limited to 'test/e2e/system_service_test.go')
-rw-r--r--test/e2e/system_service_test.go142
1 files changed, 142 insertions, 0 deletions
diff --git a/test/e2e/system_service_test.go b/test/e2e/system_service_test.go
new file mode 100644
index 000000000..684ac56b4
--- /dev/null
+++ b/test/e2e/system_service_test.go
@@ -0,0 +1,142 @@
+package integration
+
+import (
+ "io/ioutil"
+ "net"
+ "net/http"
+ "net/url"
+ "strconv"
+ "time"
+
+ . "github.com/containers/podman/v3/test/utils"
+ "github.com/containers/podman/v3/utils"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+ . "github.com/onsi/gomega/gexec"
+)
+
+var _ = Describe("podman system service", func() {
+ var podmanTest *PodmanTestIntegration
+
+ BeforeEach(func() {
+ tempdir, err := CreateTempDirInTempDir()
+ Expect(err).ShouldNot(HaveOccurred())
+
+ podmanTest = PodmanTestCreate(tempdir)
+ podmanTest.Setup()
+ })
+
+ AfterEach(func() {
+ podmanTest.Cleanup()
+ processTestResult(CurrentGinkgoTestDescription())
+ })
+
+ Describe("verify timeout", func() {
+ It("of 2 seconds", func() {
+ SkipIfRemote("service subcommand not supported remotely")
+
+ address := url.URL{
+ Scheme: "tcp",
+ Host: net.JoinHostPort("localhost", randomPort()),
+ }
+ session := podmanTest.Podman([]string{
+ "system", "service", "--time=2", address.String(),
+ })
+ defer session.Kill()
+
+ WaitForService(address)
+
+ session.Wait(5 * time.Second)
+ Eventually(session, 5).Should(Exit(0))
+ })
+ })
+
+ Describe("verify pprof endpoints", func() {
+ // Depends on pkg/api/server/server.go:255
+ const magicComment = "pprof service listening on"
+
+ It("are available", func() {
+ SkipIfRemote("service subcommand not supported remotely")
+
+ address := url.URL{
+ Scheme: "tcp",
+ Host: net.JoinHostPort("localhost", randomPort()),
+ }
+
+ pprofPort := randomPort()
+ session := podmanTest.Podman([]string{
+ "system", "service", "--log-level=info", "--time=0",
+ "--pprof-address=localhost:" + pprofPort, address.String(),
+ })
+ defer session.Kill()
+
+ WaitForService(address)
+
+ // Combined with test below we have positive/negative test for pprof
+ Expect(session.Err.Contents()).Should(ContainSubstring(magicComment))
+
+ heap := url.URL{
+ Scheme: "http",
+ Host: net.JoinHostPort("localhost", pprofPort),
+ Path: "/debug/pprof/heap",
+ RawQuery: "seconds=2",
+ }
+ resp, err := http.Get(heap.String())
+ Expect(err).ShouldNot(HaveOccurred())
+ defer resp.Body.Close()
+ Expect(resp).To(HaveHTTPStatus(http.StatusOK))
+
+ body, err := ioutil.ReadAll(resp.Body)
+ Expect(err).ShouldNot(HaveOccurred())
+ Expect(body).ShouldNot(BeEmpty())
+
+ session.Interrupt().Wait(2 * time.Second)
+ Eventually(session, 2).Should(Exit(1))
+ })
+
+ It("are not available", func() {
+ SkipIfRemote("service subcommand not supported remotely")
+
+ address := url.URL{
+ Scheme: "tcp",
+ Host: net.JoinHostPort("localhost", randomPort()),
+ }
+
+ session := podmanTest.Podman([]string{
+ "system", "service", "--log-level=info", "--time=0", address.String(),
+ })
+ defer session.Kill()
+
+ WaitForService(address)
+
+ // Combined with test above we have positive/negative test for pprof
+ Expect(session.Err.Contents()).ShouldNot(ContainSubstring(magicComment))
+
+ session.Interrupt().Wait(2 * time.Second)
+ Eventually(session, 2).Should(Exit(1))
+ })
+ })
+})
+
+// WaitForService blocks, waiting for some service listening on given host:port
+func WaitForService(address url.URL) {
+ // Wait for podman to be ready
+ var conn net.Conn
+ var err error
+ for i := 1; i <= 5; i++ {
+ conn, err = net.Dial("tcp", address.Host)
+ if err != nil {
+ // Podman not available yet...
+ time.Sleep(time.Duration(i) * time.Second)
+ }
+ }
+ Expect(err).ShouldNot(HaveOccurred())
+ conn.Close()
+}
+
+// randomPort leans on the go net library to find an available port...
+func randomPort() string {
+ port, err := utils.GetRandomPort()
+ Expect(err).ShouldNot(HaveOccurred())
+ return strconv.Itoa(port)
+}