some compatibility fixes (prevent forking of testcase-process, code review), wait 4 server ready, test cases fixed (py2/py3)

pull/1483/head
sebres 2016-02-12 21:51:32 +01:00
parent 2fcb6358ff
commit 0b4143730d
6 changed files with 219 additions and 135 deletions

View File

@ -34,14 +34,18 @@ from threading import Thread
from ..version import version
from .csocket import CSocket
from .beautifier import Beautifier
from .fail2bancmdline import Fail2banCmdLine, ExitException, PRODUCTION, logSys, exit, output
from .fail2bancmdline import Fail2banCmdLine, ServerExecutionException, ExitException, \
logSys, PRODUCTION, exit, output
MAX_WAITTIME = 30
PROMPT = "fail2ban> "
def _thread_name():
return threading.current_thread().__class__.__name__
def input_command():
return raw_input(PROMPT)
##
#
@ -49,8 +53,6 @@ def _thread_name():
class Fail2banClient(Fail2banCmdLine, Thread):
PROMPT = "fail2ban> "
def __init__(self):
Fail2banCmdLine.__init__(self)
Thread.__init__(self)
@ -91,11 +93,11 @@ class Fail2banClient(Fail2banCmdLine, Thread):
client = CSocket(self._conf["socket"])
ret = client.send(c)
if ret[0] == 0:
logSys.debug("OK : " + `ret[1]`)
logSys.debug("OK : %r", ret[1])
if showRet or c[0] == 'echo':
output(beautifier.beautify(ret[1]))
else:
logSys.error("NOK: " + `ret[1].args`)
logSys.error("NOK: %r", ret[1].args)
if showRet:
output(beautifier.beautifyError(ret[1]))
streamRet = False
@ -202,7 +204,10 @@ class Fail2banClient(Fail2banCmdLine, Thread):
except Exception as e:
output("")
logSys.error("Exception while starting server " + ("background" if background else "foreground"))
logSys.error(e)
if self._conf["verbose"] > 1:
logSys.exception(e)
else:
logSys.error(e)
return False
return True
@ -249,7 +254,9 @@ class Fail2banClient(Fail2banCmdLine, Thread):
if self._conf.get("interactive", False):
output(' ## stop ... ')
self.__processCommand(['stop'])
self.__waitOnServer(False)
if not self.__waitOnServer(False):
logSys.error("Could not stop server")
return False
# in interactive mode reset config, to make full-reload if there something changed:
if self._conf.get("interactive", False):
output(' ## load configuration ... ')
@ -286,10 +293,14 @@ class Fail2banClient(Fail2banCmdLine, Thread):
def __processStartStreamAfterWait(self, *args):
try:
# Wait for the server to start
self.__waitOnServer()
if not self.__waitOnServer():
logSys.error("Could not find server, waiting failed")
return False
# Configure the server
self.__processCmd(*args)
except ServerExecutionException:
except ServerExecutionException as e:
if self._conf["verbose"] > 1:
logSys.exception(e)
logSys.error("Could not start server. Maybe an old "
"socket file is still present. Try to "
"remove " + self._conf["socket"] + ". If "
@ -306,11 +317,13 @@ class Fail2banClient(Fail2banCmdLine, Thread):
# Wait for the server to start (the server has 30 seconds to answer ping)
starttime = time.time()
logSys.debug("__waitOnServer: %r", (alive, maxtime))
test = lambda: os.path.exists(self._conf["socket"]) and self.__ping()
with VisualWait(self._conf["verbose"]) as vis:
while self._alive and (
not self.__ping() == alive or (
not alive and os.path.exists(self._conf["socket"])
)):
sltime = 0.0125 / 2
while self._alive:
runf = test()
if runf == alive:
return True
now = time.time()
# Wonderful visual :)
if now > starttime + 1:
@ -318,7 +331,9 @@ class Fail2banClient(Fail2banCmdLine, Thread):
# f end time reached:
if now - starttime >= maxtime:
raise ServerExecutionException("Failed to start server")
time.sleep(0.1)
sltime = min(sltime * 2, 0.5)
time.sleep(sltime)
return False
def start(self, argv):
# Install signal handlers
@ -332,27 +347,31 @@ class Fail2banClient(Fail2banCmdLine, Thread):
if self._argv is None:
ret = self.initCmdLine(argv)
if ret is not None:
return ret
if ret:
return True
raise ServerExecutionException("Init of command line failed")
# Commands
args = self._args
# Interactive mode
if self._conf.get("interactive", False):
try:
import readline
except ImportError:
logSys.error("Readline not available")
return False
# no readline in test:
if PRODUCTION: # pragma: no cover
try:
import readline
except ImportError:
raise ServerExecutionException("Readline not available")
try:
ret = True
if len(args) > 0:
ret = self.__processCommand(args)
if ret:
readline.parse_and_bind("tab: complete")
if PRODUCTION: # pragma: no cover
readline.parse_and_bind("tab: complete")
self.dispInteractive()
while True:
cmd = raw_input(self.PROMPT)
cmd = input_command()
if cmd == "exit" or cmd == "quit":
# Exit
return True
@ -362,26 +381,31 @@ class Fail2banClient(Fail2banCmdLine, Thread):
try:
self.__processCommand(shlex.split(cmd))
except Exception, e:
logSys.error(e)
if self._conf["verbose"] > 1:
logSys.exception(e)
else:
logSys.error(e)
except (EOFError, KeyboardInterrupt):
output("")
return True
raise
# Single command mode
else:
if len(args) < 1:
self.dispUsage()
return False
return self.__processCommand(args)
except Exception as e:
if self._conf["verbose"] > 1:
logSys.exception(e)
else:
logSys.error(e)
return False
finally:
self._alive = False
for s, sh in _prev_signals.iteritems():
signal.signal(s, sh)
class ServerExecutionException(Exception):
pass
##
# Wonderful visual :)
#

View File

@ -261,5 +261,9 @@ class Fail2banCmdLine():
exit = Fail2banCmdLine.exit
class ExitException:
pass
class ExitException(Exception):
pass
class ServerExecutionException(Exception):
pass

View File

@ -24,10 +24,8 @@ __license__ = "GPL"
import os
import sys
from ..version import version
from ..server.server import Server
from ..server.utils import Utils
from .fail2bancmdline import Fail2banCmdLine, logSys, PRODUCTION, exit
from .fail2bancmdline import Fail2banCmdLine, ServerExecutionException, \
logSys, PRODUCTION, exit
MAX_WAITTIME = 30
@ -44,13 +42,14 @@ class Fail2banServer(Fail2banCmdLine):
# Fail2banCmdLine.__init__(self)
##
# Start Fail2Ban server in main thread without fork (foreground).
# Start Fail2Ban server in main thread without fork (direct, it can fork itself in Server if daemon=True).
#
# Start the Fail2ban server in foreground (daemon mode or not).
# Start the Fail2ban server in background/foreground (daemon mode or not).
@staticmethod
def startServerDirect(conf, daemon=True):
logSys.debug("-- direct starting of server in %s, deamon: %s", os.getpid(), daemon)
from ..server.server import Server
server = None
try:
# Start it in foreground (current thread, not new process),
@ -59,11 +58,14 @@ class Fail2banServer(Fail2banCmdLine):
server.start(conf["socket"],
conf["pidfile"], conf["force"],
conf=conf)
except Exception, e:
logSys.exception(e)
if server:
server.quit()
exit(-1)
except Exception as e:
try:
if server:
server.quit()
except Exception as e2:
if conf["verbose"] > 1:
logSys.exception(e2)
raise
return server
@ -74,10 +76,6 @@ class Fail2banServer(Fail2banCmdLine):
@staticmethod
def startServerAsync(conf):
# Directory of client (to try the first start from the same directory as client):
startdir = sys.path[0]
if startdir in ("", "."): # may be uresolved in test-cases, so get bin-directory:
startdir = os.path.dirname(sys.argv[0])
# Forks the current process, don't fork if async specified (ex: test cases)
pid = 0
frk = not conf["async"] and PRODUCTION
@ -103,25 +101,43 @@ class Fail2banServer(Fail2banCmdLine):
for o in ('loglevel', 'logtarget', 'syslogsocket'):
args.append("--"+o)
args.append(conf[o])
try:
# Use the current directory.
exe = os.path.abspath(os.path.join(startdir, SERVER))
# Directory of client (to try the first start from current or the same directory as client, and from relative bin):
exe = Fail2banServer.getServerPath()
if not frk:
# Wrapr args to use the same python version in client/server (important for multi-python systems):
args[0] = exe
exe = sys.executable
args[0:0] = [exe]
logSys.debug("Starting %r with args %r", exe, args)
if frk:
os.execv(exe, args)
return os.execv(exe, args)
else:
os.spawnv(os.P_NOWAITO, exe, args)
# use P_WAIT instead of P_NOWAIT (to prevent defunct-zomby process), it startet as daemon, so parent exit fast after fork):
return os.spawnv(os.P_WAIT, exe, args)
except OSError as e:
try:
# Use the PATH env.
logSys.warning("Initial start attempt failed (%s). Starting %r with the same args", e, SERVER)
if frk:
os.execvp(SERVER, args)
else:
os.spawnvp(os.P_NOWAITO, SERVER, args)
except OSError:
exit(-1)
# Use the PATH env.
logSys.warning("Initial start attempt failed (%s). Starting %r with the same args", e, SERVER)
if frk:
return os.execvp(SERVER, args)
else:
del args[0]
args[0] = SERVER
return os.spawnvp(os.P_WAIT, SERVER, args)
return pid
@staticmethod
def getServerPath():
startdir = sys.path[0]
exe = os.path.abspath(os.path.join(startdir, SERVER))
if not os.path.isfile(exe): # may be uresolved in test-cases, so get relative starter (client):
startdir = os.path.dirname(sys.argv[0])
exe = os.path.abspath(os.path.join(startdir, SERVER))
if not os.path.isfile(exe): # may be uresolved in test-cases, so try to get relative bin-directory:
startdir = os.path.dirname(os.path.abspath(__file__))
startdir = os.path.join(os.path.dirname(os.path.dirname(startdir)), "bin")
exe = os.path.abspath(os.path.join(startdir, SERVER))
return exe
def _Fail2banClient(self):
from .fail2banclient import Fail2banClient
@ -139,18 +155,24 @@ class Fail2banServer(Fail2banCmdLine):
args = self._args
cli = None
# If client mode - whole processing over client:
if len(args) or self._conf.get("interactive", False):
cli = self._Fail2banClient()
return cli.start(argv)
# Just start:
if len(args) == 1 and args[0] == 'start' and not self._conf.get("interactive", False):
pass
else:
# If client mode - whole processing over client:
if len(args) or self._conf.get("interactive", False):
cli = self._Fail2banClient()
return cli.start(argv)
# Start the server:
server = None
try:
# async = True, if started from client, should fork, daemonize, etc...
# background = True, if should start in new process, otherwise start in foreground
async = self._conf.get("async", False)
from ..server.utils import Utils
# background = True, if should be new process running in background, otherwise start in foreground
# process will be forked in daemonize, inside of Server module.
# async = True, if started from client, should...
background = self._conf["background"]
async = self._conf.get("async", False)
# If was started not from the client:
if not async:
# Start new thread with client to read configuration and
@ -162,13 +184,14 @@ class Fail2banServer(Fail2banCmdLine):
# wait up to MAX_WAITTIME, do not continue if configuration is not 100% valid:
Utils.wait_for(lambda: phase.get('ready', None) is not None, MAX_WAITTIME)
if not phase.get('start', False):
return False
raise ServerExecutionException('Async configuration of server failed')
# Start server, daemonize it, etc.
if async or not background:
server = Fail2banServer.startServerDirect(self._conf, background)
else:
Fail2banServer.startServerAsync(self._conf)
pid = os.getpid()
server = Fail2banServer.startServerDirect(self._conf, background)
# If forked - just exit other processes
if pid != os.getpid():
os._exit(0)
if cli:
cli._server = server
@ -182,7 +205,8 @@ class Fail2banServer(Fail2banCmdLine):
logSys.debug('Starting server done')
except Exception, e:
logSys.exception(e)
if self._conf["verbose"] > 1:
logSys.exception(e)
if server:
server.quit()
exit(-1)

View File

@ -93,9 +93,15 @@ class Server:
if self.__daemon: # pragma: no cover
logSys.info("Starting in daemon mode")
ret = self.__createDaemon()
if not ret:
logSys.error("Could not create daemon")
raise ServerInitializationError("Could not create daemon")
# If forked parent - return here (parent process will configure server later):
if ret is None:
return False
# If error:
if not ret[0]:
err = "Could not create daemon %s", ret[1:]
logSys.error(err)
raise ServerInitializationError(err)
# We are daemon.
# Set all logging parameters (or use default if not specified):
self.setSyslogSocket(conf.get("syslogsocket",
@ -159,8 +165,12 @@ class Server:
logging.shutdown()
# Restore default signal handlers:
for s, sh in self.__prev_signals.iteritems():
signal.signal(s, sh)
if _thread_name() == '_MainThread':
for s, sh in self.__prev_signals.iteritems():
signal.signal(s, sh)
# Prevent to call quit twice:
self.quit = lambda: False
def addJail(self, name, backend):
self.__jails.add(name, backend, self.__db)
@ -569,10 +579,9 @@ class Server:
# We need to set this in the parent process, so it gets inherited by the
# child process, and this makes sure that it is effect even if the parent
# terminates quickly.
if _thread_name() == '_MainThread':
for s in (signal.SIGHUP,):
self.__prev_signals[s] = signal.getsignal(s)
signal.signal(s, signal.SIG_IGN)
for s in (signal.SIGHUP,):
self.__prev_signals[s] = signal.getsignal(s)
signal.signal(s, signal.SIG_IGN)
try:
# Fork a child process so the parent can exit. This will return control
@ -583,7 +592,7 @@ class Server:
# PGID.
pid = os.fork()
except OSError, e:
return((e.errno, e.strerror)) # ERROR (return a tuple)
return (False, (e.errno, e.strerror)) # ERROR (return a tuple)
if pid == 0: # The first child.
@ -604,7 +613,7 @@ class Server:
# preventing the daemon from ever acquiring a controlling terminal.
pid = os.fork() # Fork a second child.
except OSError, e:
return((e.errno, e.strerror)) # ERROR (return a tuple)
return (False, (e.errno, e.strerror)) # ERROR (return a tuple)
if (pid == 0): # The second child.
# Ensure that the daemon doesn't keep any directory in use. Failure
@ -613,7 +622,8 @@ class Server:
else:
os._exit(0) # Exit parent (the first child) of the second child.
else:
os._exit(0) # Exit parent of the first child.
# Signal to exit, parent of the first child.
return None
# Close all open files. Try the system configuration variable, SC_OPEN_MAX,
# for the maximum number of open files to close. If it doesn't exist, use
@ -641,7 +651,7 @@ class Server:
os.open("/dev/null", os.O_RDONLY) # standard input (0)
os.open("/dev/null", os.O_RDWR) # standard output (1)
os.open("/dev/null", os.O_RDWR) # standard error (2)
return True
return (True,)
class ServerInitializationError(Exception):

View File

@ -26,6 +26,7 @@ __license__ = "GPL"
import fileinput
import os
import re
import sys
import time
import unittest
@ -50,10 +51,9 @@ else:
CLIENT = "fail2ban-client"
SERVER = "fail2ban-server"
BIN = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "bin")
BIN = os.path.dirname(Fail2banServer.getServerPath())
MAX_WAITTIME = 10
MAX_WAITTIME = unittest.F2B.maxWaitTime(MAX_WAITTIME)
MAX_WAITTIME = 30 if not unittest.F2B.fast else 5
##
# Several wrappers and settings for proper testing:
@ -67,8 +67,6 @@ fail2bancmdline.logSys = \
fail2banclient.logSys = \
fail2banserver.logSys = logSys
LOG_LEVEL = logSys.level
server.DEF_LOGTARGET = "/dev/null"
def _test_output(*args):
@ -89,13 +87,13 @@ fail2banclient.exit = \
fail2banserver.exit = _test_exit
INTERACT = []
def _test_raw_input(*args):
def _test_input_command(*args):
if len(INTERACT):
#print('--- interact command: ', INTERACT[0])
#logSys.debug('--- interact command: %r', INTERACT[0])
return INTERACT.pop(0)
else:
return "exit"
fail2banclient.raw_input = _test_raw_input
fail2banclient.input_command = _test_input_command
# prevents change logging params, log capturing, etc:
fail2bancmdline.PRODUCTION = \
@ -142,7 +140,7 @@ def _start_params(tmp, use_stock=False, logtarget="/dev/null"):
else:
# just empty config directory without anything (only fail2ban.conf/jail.conf):
os.mkdir(cfg)
f = open(cfg+"/fail2ban.conf", "wb")
f = open(cfg+"/fail2ban.conf", "w")
f.write('\n'.join((
"[Definition]",
"loglevel = INFO",
@ -156,20 +154,20 @@ def _start_params(tmp, use_stock=False, logtarget="/dev/null"):
"",
)))
f.close()
f = open(cfg+"/jail.conf", "wb")
f = open(cfg+"/jail.conf", "w")
f.write('\n'.join((
"[INCLUDES]", "",
"[DEFAULT]", "",
"",
)))
f.close()
if LOG_LEVEL < logging.DEBUG: # if HEAVYDEBUG
if logSys.level < logging.DEBUG: # if HEAVYDEBUG
_out_file(cfg+"/fail2ban.conf")
_out_file(cfg+"/jail.conf")
# parameters:
return ("-c", cfg,
"--logtarget", logtarget, "--loglevel", "DEBUG", "--syslogsocket", "auto",
"-s", tmp+"/f2b.sock", "-p", tmp+"/f2b.pid")
# parameters (sock/pid and config, increase verbosity, set log, etc.):
return ("-c", cfg, "-s", tmp+"/f2b.sock", "-p", tmp+"/f2b.pid",
"-vv", "--logtarget", logtarget, "--loglevel", "DEBUG", "--syslogsocket", "auto",
)
def _kill_srv(pidfile): # pragma: no cover
def _pid_exists(pid):
@ -206,14 +204,14 @@ def _kill_srv(pidfile): # pragma: no cover
os.kill(pid, signal.SIGKILL)
return not _pid_exists(pid)
except Exception as e:
sysLog.debug(e)
logSys.debug(e)
finally:
if f is not None:
f.close()
return True
class Fail2banClientTest(LogCaptureTestCase):
class Fail2banClientServerBase(LogCaptureTestCase):
def setUp(self):
"""Call before every test case."""
@ -223,6 +221,21 @@ class Fail2banClientTest(LogCaptureTestCase):
"""Call after every test case."""
LogCaptureTestCase.tearDown(self)
def _wait_for_srv(self, tmp, ready=True, startparams=None):
sock = tmp+"/f2b.sock"
# wait for server (socket):
ret = Utils.wait_for(lambda: os.path.exists(sock), MAX_WAITTIME)
if not ret:
raise Exception('Unexpected: Socket file does not exists.\nStart failed: %r' % (startparams,))
if ready:
# wait for communication with worker ready:
ret = Utils.wait_for(lambda: "Server ready" in self.getLog(), MAX_WAITTIME)
if not ret:
raise Exception('Unexpected: Server ready was not found.\nStart failed: %r' % (startparams,))
class Fail2banClientTest(Fail2banClientServerBase):
def testClientUsage(self):
self.assertRaises(ExitException, _exec_client,
(CLIENT, "-h",))
@ -232,12 +245,13 @@ class Fail2banClientTest(LogCaptureTestCase):
@withtmpdir
def testClientStartBackgroundInside(self, tmp):
try:
# always add "--async" by start inside, should don't fork by async (not replace client with server, just start in new process)
# (we can't fork the test cases process):
# use once the stock configuration (to test starting also)
startparams = _start_params(tmp, True)
# start:
self.assertRaises(ExitException, _exec_client,
(CLIENT, "--async", "-b") + startparams + ("start",))
(CLIENT, "-b") + startparams + ("start",))
# wait for server (socket and ready):
self._wait_for_srv(tmp, True, startparams=startparams)
self.assertLogged("Server ready")
self.assertLogged("Exit with code 0")
try:
@ -245,6 +259,11 @@ class Fail2banClientTest(LogCaptureTestCase):
(CLIENT,) + startparams + ("echo", "TEST-ECHO",))
self.assertRaises(FailExitException, _exec_client,
(CLIENT,) + startparams + ("~~unknown~cmd~failed~~",))
self.pruneLog()
# start again (should fail):
self.assertRaises(FailExitException, _exec_client,
(CLIENT, "-b") + startparams + ("start",))
self.assertLogged("Server already running")
finally:
self.pruneLog()
# stop:
@ -260,11 +279,14 @@ class Fail2banClientTest(LogCaptureTestCase):
try:
global INTERACT
startparams = _start_params(tmp)
# start (without async in new process):
cmd = os.path.join(os.path.join(BIN), CLIENT)
# start (in new process, using the same python version):
cmd = (sys.executable, os.path.join(os.path.join(BIN), CLIENT))
logSys.debug('Start %s ...', cmd)
Utils.executeCmd((cmd,) + startparams + ("start",),
timeout=MAX_WAITTIME, shell=False, output=False)
cmd = cmd + startparams + ("start",)
Utils.executeCmd(cmd, timeout=MAX_WAITTIME, shell=False, output=True)
# wait for server (socket and ready):
self._wait_for_srv(tmp, True, startparams=cmd)
self.assertLogged("Server ready")
self.pruneLog()
try:
# echo from client (inside):
@ -312,7 +334,7 @@ class Fail2banClientTest(LogCaptureTestCase):
# start and wait to end (foreground):
logSys.debug("-- start of test worker")
phase['start'] = True
self.assertRaises(ExitException, _exec_client,
self.assertRaises(fail2bancmdline.ExitException, _exec_client,
(CLIENT, "-f") + startparams + ("start",))
# end :
phase['end'] = True
@ -334,9 +356,10 @@ class Fail2banClientTest(LogCaptureTestCase):
# wait for start thread:
Utils.wait_for(lambda: phase.get('start', None) is not None, MAX_WAITTIME)
self.assertTrue(phase.get('start', None))
# wait for server (socket):
Utils.wait_for(lambda: os.path.exists(tmp+"/f2b.sock"), MAX_WAITTIME)
self.assertLogged("Starting communication")
# wait for server (socket and ready):
self._wait_for_srv(tmp, True, startparams=startparams)
self.pruneLog()
# several commands to server:
self.assertRaises(ExitException, _exec_client,
(CLIENT,) + startparams + ("ping",))
self.assertRaises(FailExitException, _exec_client,
@ -382,15 +405,7 @@ class Fail2banClientTest(LogCaptureTestCase):
cntr -= 1
class Fail2banServerTest(LogCaptureTestCase):
def setUp(self):
"""Call before every test case."""
LogCaptureTestCase.setUp(self)
def tearDown(self):
"""Call after every test case."""
LogCaptureTestCase.tearDown(self)
class Fail2banServerTest(Fail2banClientServerBase):
def testServerUsage(self):
self.assertRaises(ExitException, _exec_server,
@ -401,15 +416,17 @@ class Fail2banServerTest(LogCaptureTestCase):
@withtmpdir
def testServerStartBackground(self, tmp):
try:
# don't add "--async" by start, because if will fork current process by daemonize
# (we can't fork the test cases process),
# because server started internal communication in new thread use INHERITED as logtarget here:
startparams = _start_params(tmp, logtarget="INHERITED")
# start:
self.assertRaises(ExitException, _exec_server,
(SERVER, "-b") + startparams)
# to prevent fork of test-cases process, start server in background via command:
startparams = _start_params(tmp)
# start (in new process, using the same python version):
cmd = (sys.executable, os.path.join(os.path.join(BIN), SERVER))
logSys.debug('Start %s ...', cmd)
cmd = cmd + startparams + ("-b",)
Utils.executeCmd(cmd, timeout=MAX_WAITTIME, shell=False, output=True)
# wait for server (socket and ready):
self._wait_for_srv(tmp, True, startparams=cmd)
self.assertLogged("Server ready")
self.assertLogged("Exit with code 0")
self.pruneLog()
try:
self.assertRaises(ExitException, _exec_server,
(SERVER,) + startparams + ("echo", "TEST-ECHO",))
@ -429,7 +446,7 @@ class Fail2banServerTest(LogCaptureTestCase):
# start and wait to end (foreground):
logSys.debug("-- start of test worker")
phase['start'] = True
self.assertRaises(ExitException, _exec_server,
self.assertRaises(fail2bancmdline.ExitException, _exec_server,
(SERVER, "-f") + startparams + ("start",))
# end :
phase['end'] = True
@ -451,9 +468,10 @@ class Fail2banServerTest(LogCaptureTestCase):
# wait for start thread:
Utils.wait_for(lambda: phase.get('start', None) is not None, MAX_WAITTIME)
self.assertTrue(phase.get('start', None))
# wait for server (socket):
Utils.wait_for(lambda: os.path.exists(tmp+"/f2b.sock"), MAX_WAITTIME)
self.assertLogged("Starting communication")
# wait for server (socket and ready):
self._wait_for_srv(tmp, True, startparams=startparams)
self.pruneLog()
# several commands to server:
self.assertRaises(ExitException, _exec_server,
(SERVER,) + startparams + ("ping",))
self.assertRaises(FailExitException, _exec_server,

View File

@ -54,6 +54,10 @@ if not CONFIG_DIR:
else:
CONFIG_DIR = '/etc/fail2ban'
# In not installed env (setup, test-cases) use fail2ban modules from main directory:
if 1 or os.environ.get('PYTHONPATH', None) is None:
os.putenv('PYTHONPATH', os.path.dirname(os.path.dirname(os.path.dirname(
os.path.abspath(__file__)))))
class F2B(optparse.Values):
def __init__(self, opts={}):
@ -343,7 +347,7 @@ class LogCaptureTestCase(unittest.TestCase):
if self._old_level <= logging.DEBUG: # so if DEBUG etc -- show them (and log it in travis)!
print("")
logSys.handlers += self._old_handlers
logSys.debug('--'*40)
logSys.debug('='*10 + ' %s ' + '='*20, self.id())
logSys.setLevel(getattr(logging, 'DEBUG'))
def tearDown(self):