From f7713c47e8b4c7f5bca5bc7dd8d95606834db217 Mon Sep 17 00:00:00 2001 From: Marc Abramowitz Date: Tue, 1 Apr 2014 10:15:27 -0700 Subject: [PATCH] testing/conftest.py: Refactor lsof fd leak checking Isolate the logic into one class to make easier to understand, more maintainable. This may aid in later plugging in an alternative implementation, such as one that uses psutil (https://bitbucket.org/hpk42/pytest/pull-request/137/use-psutil-to-detect-open-files-in-tests/diff) --HG-- branch : refactor_LsofFdLeakChecker --- testing/conftest.py | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/testing/conftest.py b/testing/conftest.py index 204c4490e..fd9f83324 100644 --- a/testing/conftest.py +++ b/testing/conftest.py @@ -4,7 +4,23 @@ import sys pytest_plugins = "pytester", import os, py -pid = os.getpid() + +class LsofFdLeakChecker(object): + def get_open_files(self): + out = self._exec_lsof() + open_files = self._parse_lsof_output(out) + return open_files + + def _exec_lsof(self): + pid = os.getpid() + return py.process.cmdexec("lsof -p %d" % pid) + + def _parse_lsof_output(self, out): + def isopen(line): + return ("REG" in line or "CHR" in line) and ( + "deleted" not in line and 'mem' not in line and "txt" not in line) + return [x for x in out.split("\n") if isopen(x)] + def pytest_addoption(parser): parser.addoption('--lsof', @@ -15,11 +31,12 @@ def pytest_configure(config): config._basedir = py.path.local() if config.getvalue("lsof"): try: - out = py.process.cmdexec("lsof -p %d" % pid) + config._fd_leak_checker = LsofFdLeakChecker() + config._openfiles = config._fd_leak_checker.get_open_files() except py.process.cmdexec.Error: pass else: - config._numfiles = len(getopenfiles(out)) + config._numfiles = len(config._openfiles) #def pytest_report_header(): # return "pid: %s" % os.getpid() @@ -31,8 +48,7 @@ def getopenfiles(out): return [x for x in out.split("\n") if isopen(x)] def check_open_files(config): - out2 = py.process.cmdexec("lsof -p %d" % pid) - lines2 = getopenfiles(out2) + lines2 = config._fd_leak_checker.get_open_files() if len(lines2) > config._numfiles + 3: error = [] error.append("***** %s FD leackage detected" %