diff --git a/bin/fail2ban-client b/bin/fail2ban-client index 0c6999c1..866a5287 100755 --- a/bin/fail2ban-client +++ b/bin/fail2ban-client @@ -419,12 +419,11 @@ class Fail2banClient: ret = False return ret - #@staticmethod + @staticmethod def dumpConfig(cmd): for c in cmd: print c return True - dumpConfig = staticmethod(dumpConfig) class ServerExecutionException(Exception): diff --git a/fail2ban/client/csocket.py b/fail2ban/client/csocket.py index 1d522f6c..921b0de5 100644 --- a/fail2ban/client/csocket.py +++ b/fail2ban/client/csocket.py @@ -57,7 +57,7 @@ class CSocket: self.__csock.close() return ret - #@staticmethod + @staticmethod def receive(sock): msg = EMPTY_BYTES while msg.rfind(CSocket.END_STRING) == -1: @@ -66,4 +66,3 @@ class CSocket: raise RuntimeError, "socket connection broken" msg = msg + chunk return loads(msg) - receive = staticmethod(receive) diff --git a/fail2ban/client/jailreader.py b/fail2ban/client/jailreader.py index ffdc5e26..84cc5e2a 100644 --- a/fail2ban/client/jailreader.py +++ b/fail2ban/client/jailreader.py @@ -220,7 +220,7 @@ class JailReader(ConfigReader): stream.insert(0, ["add", self.__name, backend]) return stream - #@staticmethod + @staticmethod def extractOptions(option): match = JailReader.optionCRE.match(option) if not match: @@ -235,4 +235,3 @@ class JailReader(ConfigReader): val for val in optmatch.group(2,3,4) if val is not None][0] option_opts[opt.strip()] = value.strip() return option_name, option_opts - extractOptions = staticmethod(extractOptions) diff --git a/fail2ban/server/asyncserver.py b/fail2ban/server/asyncserver.py index 14673a99..a54d41a1 100644 --- a/fail2ban/server/asyncserver.py +++ b/fail2ban/server/asyncserver.py @@ -149,12 +149,8 @@ class AsyncServer(asyncore.dispatcher): self.__init = True # TODO Add try..catch # There's a bug report for Python 2.6/3.0 that use_poll=True yields some 2.5 incompatibilities: - if sys.version_info >= (2, 6): # if python 2.6 or greater... - logSys.debug("Detected Python 2.6 or greater. asyncore.loop() not using poll") - asyncore.loop(use_poll = False) # fixes the "Unexpected communication problem" issue on Python 2.6 and 3.0 - else: # pragma: no cover - logSys.debug("NOT Python 2.6/3.* - asyncore.loop() using poll") - asyncore.loop(use_poll = True) + logSys.debug("Detected Python 2.6 or greater. asyncore.loop() not using poll") + asyncore.loop(use_poll=False) # fixes the "Unexpected communication problem" issue on Python 2.6 and 3.0 ## # Stops the communication server. @@ -175,12 +171,11 @@ class AsyncServer(asyncore.dispatcher): # @param sock: socket file. - #@staticmethod + @staticmethod def __markCloseOnExec(sock): fd = sock.fileno() flags = fcntl.fcntl(fd, fcntl.F_GETFD) fcntl.fcntl(fd, fcntl.F_SETFD, flags|fcntl.FD_CLOEXEC) - __markCloseOnExec = staticmethod(__markCloseOnExec) ## # AsyncServerException is used to wrap communication exceptions. diff --git a/fail2ban/server/banmanager.py b/fail2ban/server/banmanager.py index b24fa9e5..c21cad45 100644 --- a/fail2ban/server/banmanager.py +++ b/fail2ban/server/banmanager.py @@ -126,7 +126,7 @@ class BanManager: # @param ticket the FailTicket # @return a BanTicket - #@staticmethod + @staticmethod def createBanTicket(ticket): ip = ticket.getIP() #lastTime = ticket.getTime() @@ -134,7 +134,6 @@ class BanManager: banTicket = BanTicket(ip, lastTime, ticket.getMatches()) banTicket.setAttempt(ticket.getAttempt()) return banTicket - createBanTicket = staticmethod(createBanTicket) ## # Add a ban ticket. diff --git a/fail2ban/server/filter.py b/fail2ban/server/filter.py index d1c9d2ad..c886bf35 100644 --- a/fail2ban/server/filter.py +++ b/fail2ban/server/filter.py @@ -838,7 +838,7 @@ class DNSUtils: IP_CRE = re.compile("^(?:\d{1,3}\.){3}\d{1,3}$") - #@staticmethod + @staticmethod def dnsToIp(dns): """ Convert a DNS into an IP address using the Python socket module. Thanks to Kevin Drapel. @@ -853,9 +853,8 @@ class DNSUtils: logSys.warning("Socket error raised trying to resolve hostname %s: %s" % (dns, e)) return list() - dnsToIp = staticmethod(dnsToIp) - #@staticmethod + @staticmethod def searchIP(text): """ Search if an IP address if directly available and return it. @@ -865,9 +864,8 @@ class DNSUtils: return match else: return None - searchIP = staticmethod(searchIP) - #@staticmethod + @staticmethod def isValidIP(string): """ Return true if str is a valid IP """ @@ -877,9 +875,8 @@ class DNSUtils: return True except socket.error: return False - isValidIP = staticmethod(isValidIP) - #@staticmethod + @staticmethod def textToIp(text, useDns): """ Return the IP of DNS found in a given text. """ @@ -901,9 +898,8 @@ class DNSUtils: text, ipList) return ipList - textToIp = staticmethod(textToIp) - #@staticmethod + @staticmethod def cidr(i, n): """ Convert an IP address string with a CIDR mask into a 32-bit integer. @@ -911,18 +907,15 @@ class DNSUtils: # 32-bit IPv4 address mask MASK = 0xFFFFFFFFL return ~(MASK >> n) & MASK & DNSUtils.addr2bin(i) - cidr = staticmethod(cidr) - #@staticmethod + @staticmethod def addr2bin(string): """ Convert a string IPv4 address into an unsigned integer. """ return struct.unpack("!L", socket.inet_aton(string))[0] - addr2bin = staticmethod(addr2bin) - #@staticmethod + @staticmethod def bin2addr(addr): """ Convert a numeric IPv4 address into string n.n.n.n form. """ return socket.inet_ntoa(struct.pack("!L", addr)) - bin2addr = staticmethod(bin2addr) diff --git a/fail2ban/server/mytime.py b/fail2ban/server/mytime.py index 96c7f8ab..f284379e 100644 --- a/fail2ban/server/mytime.py +++ b/fail2ban/server/mytime.py @@ -26,65 +26,71 @@ import time, datetime ## # MyTime class. # -# This class is a wrapper around time.time() and time.gmtime(). When -# performing unit test, it is very useful to get a fixed value from these -# functions. -# Thus, time.time() and time.gmtime() should never be called directly. -# This wrapper should be called instead. The API are equivalent. class MyTime: - + """A wrapper around time module primarily for testing purposes + + This class is a wrapper around time.time() and time.gmtime(). When + performing unit test, it is very useful to get a fixed value from + these functions. Thus, time.time() and time.gmtime() should never + be called directly. This wrapper should be called instead. The API + are equivalent. + """ + myTime = None - - ## - # Sets the current time. - # - # Use None in order to always get the real current time. - # - # @param t the time to set or None - - #@staticmethod + + @staticmethod def setTime(t): + """Set current time. + + Use None in order to always get the real current time. + + @param t the time to set or None + """ + MyTime.myTime = t - setTime = staticmethod(setTime) - - ## - # Equivalent to time.time() - # - # @return time.time() if setTime was called with None - - #@staticmethod + + @staticmethod def time(): + """Decorate time.time() for the purpose of testing mocking + + @return time.time() if setTime was called with None + """ + if MyTime.myTime is None: return time.time() else: return MyTime.myTime - time = staticmethod(time) - - ## - # Equivalent to time.gmtime() - # - # @return time.gmtime() if setTime was called with None - - #@staticmethod + + @staticmethod def gmtime(): + """Decorate time.gmtime() for the purpose of testing mocking + + @return time.gmtime() if setTime was called with None + """ if MyTime.myTime is None: return time.gmtime() else: return time.gmtime(MyTime.myTime) - gmtime = staticmethod(gmtime) - #@staticmethod + @staticmethod def now(): + """Decorate datetime.now() for the purpose of testing mocking + + @return datetime.now() if setTime was called with None + """ if MyTime.myTime is None: return datetime.datetime.now() else: return datetime.datetime.fromtimestamp(MyTime.myTime) - now = staticmethod(now) + @staticmethod def localtime(x=None): + """Decorate time.localtime() for the purpose of testing mocking + + @return time.localtime() if setTime was called with None + """ if MyTime.myTime is None or x is not None: return time.localtime(x) else: return time.localtime(MyTime.myTime) - localtime = staticmethod(localtime) diff --git a/fail2ban/tests/samplestestcase.py b/fail2ban/tests/samplestestcase.py index e0831184..2c18a504 100644 --- a/fail2ban/tests/samplestestcase.py +++ b/fail2ban/tests/samplestestcase.py @@ -24,11 +24,7 @@ __license__ = "GPL" import unittest, sys, os, fileinput, re, time, datetime, inspect -if sys.version_info >= (2, 6): - import json -else: - import simplejson as json - next = lambda x: x.next() +import json from ..server.filter import Filter from ..client.filterreader import FilterReader