diff options
author | Jhon Honce <jhonce@redhat.com> | 2021-10-05 10:43:55 -0700 |
---|---|---|
committer | Jhon Honce <jhonce@redhat.com> | 2021-10-08 13:57:20 -0700 |
commit | 8d3aec9d08bddf486dcb30e7113777b9d0cc27bd (patch) | |
tree | e47d47a39f50f7cadaaf0c8bd81f5ed689081b1a /test/e2e/system_service_test.go | |
parent | bd4d9a09520b2329b1cf3dd8cdf8194b8bdeab67 (diff) | |
download | podman-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.go | 142 |
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) +} |