diff options
author | OpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com> | 2021-08-25 14:42:12 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-25 14:42:12 -0400 |
commit | 49cfed756f5dfb6d9267eb29d31f651578c9037c (patch) | |
tree | 677b6acfee4b6fddc1b08d8181ce3552a5ccab68 /pkg/bindings/test/resource_test.go | |
parent | fefa0b32c74fc5d394a0e2bd5b4564bedb3ed15d (diff) | |
parent | 1dc6d14735eef1e51368103aefba3d7c704dcfe3 (diff) | |
download | podman-49cfed756f5dfb6d9267eb29d31f651578c9037c.tar.gz podman-49cfed756f5dfb6d9267eb29d31f651578c9037c.tar.bz2 podman-49cfed756f5dfb6d9267eb29d31f651578c9037c.zip |
Merge pull request #11103 from jwhonce/wip/bindings
Fix file descriptor leaks in bindings and add test
Diffstat (limited to 'pkg/bindings/test/resource_test.go')
-rw-r--r-- | pkg/bindings/test/resource_test.go | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/pkg/bindings/test/resource_test.go b/pkg/bindings/test/resource_test.go new file mode 100644 index 000000000..b12d1ccd6 --- /dev/null +++ b/pkg/bindings/test/resource_test.go @@ -0,0 +1,116 @@ +package test_bindings + +import ( + "context" + "fmt" + "io/fs" + "os" + "os/exec" + "path/filepath" + "reflect" + "strconv" + "syscall" + + "github.com/containers/podman/v3/pkg/bindings" + "github.com/containers/podman/v3/pkg/bindings/containers" + "github.com/containers/podman/v3/pkg/bindings/images" + "github.com/containers/podman/v3/pkg/bindings/pods" + "github.com/containers/podman/v3/pkg/bindings/system" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" +) + +var _ = Describe("Verify Podman resources", func() { + var ( + bt *bindingTest + s *Session + ) + + BeforeEach(func() { + bt = newBindingTest() + s = bt.startAPIService() + err := bt.NewConnection() + Expect(err).ShouldNot(HaveOccurred()) + }) + + AfterEach(func() { + s.Kill() + bt.cleanup() + }) + + It("no leaked connections", func() { + conn, err := bindings.NewConnection(context.Background(), bt.sock) + Expect(err).ShouldNot(HaveOccurred()) + + // Record details on open file descriptors before using API + buffer := lsof() + + // Record open fd from /proc + start, err := readProc() + Expect(err).ShouldNot(HaveOccurred()) + + // Run some operations + _, err = system.Info(conn, nil) + Expect(err).ShouldNot(HaveOccurred()) + _, err = images.List(conn, nil) + Expect(err).ShouldNot(HaveOccurred()) + _, err = containers.List(conn, nil) + Expect(err).ShouldNot(HaveOccurred()) + _, err = pods.List(conn, nil) + Expect(err).ShouldNot(HaveOccurred()) + + podman, _ := bindings.GetClient(conn) + podman.Client.CloseIdleConnections() + + // Record open fd from /proc + finished, err := readProc() + Expect(err).ShouldNot(HaveOccurred()) + if !reflect.DeepEqual(finished, start) { + fmt.Fprintf(GinkgoWriter, "Open FDs:\nlsof Before:\n%s\n", buffer) + + // Record details on open file descriptors after using API + buffer := lsof() + fmt.Fprintf(GinkgoWriter, "lsof After:\n%s\n", buffer) + + // We know test has failed. Easier to let ginkgo format output. + Expect(finished).Should(Equal(start)) + } + }) +}) + +func lsof() string { + lsof := exec.Command("lsof", "+E", "-p", strconv.Itoa(os.Getpid())) + buffer, err := lsof.Output() + Expect(err).ShouldNot(HaveOccurred()) + return string(buffer) +} + +func readProc() ([]string, error) { + syscall.Sync() + + names := make([]string, 0) + err := filepath.WalkDir(fmt.Sprintf("/proc/%d/fd", os.Getpid()), + func(path string, d fs.DirEntry, err error) error { + name := path + " -> " + + switch { + case d.IsDir(): + return nil + case err != nil: + name += err.Error() + case d.Type()&fs.ModeSymlink != 0: + n, err := os.Readlink(path) + if err != nil && !os.IsNotExist(err) { + return err + } + if n == "" { + n = d.Type().String() + } + name += n + } + names = append(names, name) + return nil + }) + return names, err +} |