From f206c3d49334694ad7ceb44306089000b16ed7fb Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Wed, 16 Apr 2014 00:30:46 -0400 Subject: [PATCH 1/6] BF: give a custom prefix to a tempfile and close it upon tearDown in ExecuteActions tests --- testcases/actionstestcase.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/testcases/actionstestcase.py b/testcases/actionstestcase.py index 15877749..ae123417 100644 --- a/testcases/actionstestcase.py +++ b/testcases/actionstestcase.py @@ -35,9 +35,10 @@ class ExecuteActions(unittest.TestCase): """Call before every test case.""" self.__jail = DummyJail() self.__actions = Actions(self.__jail) - self.__tmpfile, self.__tmpfilename = tempfile.mkstemp() + self.__tmpfile, self.__tmpfilename = tempfile.mkstemp('fail2ban', 'executeactions') def tearDown(self): + os.close(self.__tmpfile) os.remove(self.__tmpfilename) def defaultActions(self): From cb9cbd754e6907ca15c8b01b0fb6a0aba709230d Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Wed, 16 Apr 2014 00:32:22 -0400 Subject: [PATCH 2/6] DOC: minor wording fix --- server/filtergamin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/filtergamin.py b/server/filtergamin.py index 196396c5..296ba700 100644 --- a/server/filtergamin.py +++ b/server/filtergamin.py @@ -125,7 +125,7 @@ class FilterGamin(FileFilter): self.__cleanup() ## - # Desallocates the resources used by Gamin. + # Free up the resources used by Gamin. def __cleanup(self): for path in self.getLogPath(): From e19f9e16971741cef48571d09d2eeeb061ce7e0b Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Wed, 16 Apr 2014 00:47:43 -0400 Subject: [PATCH 3/6] BF(?): stop/join notifier only if defined Somehow on that elderly squeeze Debian sparc box, I got error that self.__notifier was not defined. So first I did define it now in the constructor, but mystery remains how come it was not defined -- wasn"t run() then run (where it is defined)? Anyways -- conditioning on it being defined might be safer may be? Not sure (need to go to sleep) if with this change but on this box I also run from time to time either into stalling of fail2ban-testcases and refusing to exit normally or ====================================================================== ERROR: test_move_into_file_after_removed (testcases.filtertestcase.MonitorFailures(/tmp/monitorfailures_FilterPyinotifypcHmMJfail2ban)) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/yoh/deb/gits/fail2ban/testcases/filtertestcase.py", line 473, in tearDown self.filter.stop() File "/home/yoh/deb/gits/fail2ban/server/filterpyinotify.py", line 196, in stop self.__notifier.stop() File "/usr/lib/pymodules/python2.6/pyinotify.py", line 1315, in stop threading.Thread.join(self) File "/usr/lib/python2.6/threading.py", line 633, in join raise RuntimeError("cannot join thread before it is started") RuntimeError: cannot join thread before it is started that is with pyinotify 0.8.9-1 so could quite be "related" to its age. --- server/filterpyinotify.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/server/filterpyinotify.py b/server/filterpyinotify.py index 68675df4..8a9e4529 100644 --- a/server/filterpyinotify.py +++ b/server/filterpyinotify.py @@ -69,6 +69,7 @@ class FilterPyinotify(FileFilter): # Pyinotify watch manager self.__monitor = pyinotify.WatchManager() self.__watches = dict() + self.__notifier = None logSys.debug("Created FilterPyinotify") @@ -190,9 +191,10 @@ class FilterPyinotify(FileFilter): def stop(self): super(FilterPyinotify, self).stop() - # Stop the notifier thread - self.__notifier.stop() - self.__notifier.join() # to not exit before notifier does + # Stop the notifier thread if it was ran and notifier was created + if self.__notifier is not None: + self.__notifier.stop() + self.__notifier.join() # to not exit before notifier does self.__cleanup() # for pedantic ones ## From dfc7dd6dc9f2afb5a3e88a79097bd93a41eba240 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Wed, 16 Apr 2014 08:25:54 -0400 Subject: [PATCH 4/6] ENH: use unique filename in LogFileFilterPoll on every setUp call --- testcases/filtertestcase.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/testcases/filtertestcase.py b/testcases/filtertestcase.py index f244808a..e5e5f4f8 100644 --- a/testcases/filtertestcase.py +++ b/testcases/filtertestcase.py @@ -280,11 +280,15 @@ class LogFileFilterPoll(unittest.TestCase): class LogFileMonitor(LogCaptureTestCase): """Few more tests for FilterPoll API """ + + _setup_idx = 0 # to ease tracking of dangling opened files + def setUp(self): """Call before every test case.""" LogCaptureTestCase.setUp(self) self.filter = self.name = 'NA' - _, self.name = tempfile.mkstemp('fail2ban', 'monitorfailures') + _, self.name = tempfile.mkstemp('fail2ban', 'monitorfailures-%d-' % LogFileMonitor._setup_idx) + LogFileMonitor._setup_idx += 1 self.file = open(self.name, 'a') self.filter = FilterPoll(None) self.filter.addLogPath(self.name) From 6eb67899a52414b71305ef7d751dfbd9faee64fa Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Wed, 16 Apr 2014 08:43:54 -0400 Subject: [PATCH 5/6] BF: overcome problem with failed *_movefile test if file gets properly closed Discussion is in the comments on 7260403fdd41b74335a0a71579df3df5cae6c6ba and fix consists of skipping first 3 lines while creating a "new" log file. This should be sufficient to make fail2ban detect "log rotation" and thus function properly --- testcases/filtertestcase.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testcases/filtertestcase.py b/testcases/filtertestcase.py index e5e5f4f8..58162201 100644 --- a/testcases/filtertestcase.py +++ b/testcases/filtertestcase.py @@ -559,7 +559,7 @@ def get_monitor_failures_testcase(Filter_): # now create a new one to override old one _copy_lines_between_files(GetFailures.FILENAME_01, self.name + '.new', - n=100).close() + n=100, skip=3).close() os.rename(self.name + '.new', self.name) self.assert_correct_last_attempt(GetFailures.FAILURES_01) self.assertEqual(self.filter.failManager.getFailTotal(), 6) From 8faff41d40b5382f9871aa256a858d17f9588c7f Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Wed, 16 Apr 2014 08:48:52 -0400 Subject: [PATCH 6/6] DOC: changelog entry on leaky file descriptors --- ChangeLog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index d42ea111..85fbaa54 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14,6 +14,8 @@ ver. 0.8.14 (2014/??/??) - take-care-of-the-elderly - minor fixes for claimed Python 2.4 and 2.5 compatibility - Handle case when inotify watch is auto deleted on file deletion to stop error messages + - tests - fixed few "leaky" file descriptors when files were not closed while + being removed physically ver. 0.8.13 (2014/03/15) - maintenance-only-from-now-on