From 90d6a4a6cd8c2de9004239039c82dba80e562384 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Thu, 9 May 2013 22:46:59 -0400 Subject: [PATCH] ENH: consistent operation of formatExceptionInfo + unittest for it --- common/helpers.py | 12 ++++++----- fail2ban-testcases | 3 +++ server/asyncserver.py | 4 ++-- testcases/misctestcase.py | 44 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 testcases/misctestcase.py diff --git a/common/helpers.py b/common/helpers.py index dba4c9d6..c0cf052e 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -17,11 +17,7 @@ # along with Fail2Ban; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# Author: Cyril Jaquier -# Author: Arturo 'Buanzo' Busleiman -# - -__author__ = "Cyril Jaquier" +__author__ = "Cyril Jaquier, Arturo 'Buanzo' Busleiman" __copyright__ = "Copyright (c) 2009 Cyril Jaquier" __license__ = "GPL" @@ -33,6 +29,12 @@ def formatExceptionInfo(): excName = cla.__name__ try: excArgs = exc.__dict__["args"] + # Assure that we always return a string, without unneeded + # 'decorations' with python <= 2.5 where args would be a tuple + if isinstance(excArgs, tuple) and len(excArgs) == 1: + excArgs = excArgs[0] + excArgs = str(excArgs) except KeyError: + # And always provide a string output excArgs = str(exc) return (excName, excArgs) diff --git a/fail2ban-testcases b/fail2ban-testcases index e00cc908..4e6689ea 100755 --- a/fail2ban-testcases +++ b/fail2ban-testcases @@ -36,6 +36,7 @@ from testcases import servertestcase from testcases import datedetectortestcase from testcases import actiontestcase from testcases import sockettestcase +from testcases import misctestcase from testcases.utils import FormatterWithTraceBack from server.mytime import MyTime @@ -150,6 +151,8 @@ tests.addTest(unittest.makeSuite(clientreadertestcase.JailReaderTest)) tests.addTest(unittest.makeSuite(clientreadertestcase.JailsReaderTest)) # CSocket and AsyncServer tests.addTest(unittest.makeSuite(sockettestcase.Socket)) +# Misc helpers +tests.addTest(unittest.makeSuite(misctestcase.HelpersTest)) # Filter if not opts.no_network: diff --git a/server/asyncserver.py b/server/asyncserver.py index 87f91633..62a5dd8b 100644 --- a/server/asyncserver.py +++ b/server/asyncserver.py @@ -70,8 +70,8 @@ class RequestHandler(asynchat.async_chat): self.close_when_done() def handle_error(self): - e1,e2 = helpers.formatExceptionInfo() - logSys.error("Unexpected communication error: "+e2) + e1, e2 = helpers.formatExceptionInfo() + logSys.error("Unexpected communication error: %s" % str(e2)) logSys.error(traceback.format_exc().splitlines()) self.close() diff --git a/testcases/misctestcase.py b/testcases/misctestcase.py new file mode 100644 index 00000000..9b053c13 --- /dev/null +++ b/testcases/misctestcase.py @@ -0,0 +1,44 @@ +# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*- +# vi: set ft=python sts=4 ts=4 sw=4 noet : + +# This file is part of Fail2Ban. +# +# Fail2Ban is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# Fail2Ban is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Fail2Ban; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +__author__ = "Yaroslav Halchenko" +__copyright__ = "Copyright (c) 2013 Yaroslav Halchenko" +__license__ = "GPL" + +import unittest +from common.helpers import formatExceptionInfo + +class HelpersTest(unittest.TestCase): + + def testFormatExceptionInfoBasic(self): + try: + raise ValueError("Very bad exception") + except: + name, args = formatExceptionInfo() + self.assertEqual(name, "ValueError") + self.assertEqual(args, "Very bad exception") + + def testFormatExceptionConvertArgs(self): + try: + raise ValueError("Very bad", None) + except: + name, args = formatExceptionInfo() + self.assertEqual(name, "ValueError") + # might be fragile due to ' vs " + self.assertEqual(args, "('Very bad', None)")