RF+ENH: @with_kill_srv fixture to kill_srv in the tests

pull/1483/head
Yaroslav Halchenko 2016-05-12 09:47:01 -04:00 committed by sebres
parent e57321ab1e
commit d7ff7d18cd
1 changed files with 183 additions and 179 deletions

View File

@ -31,8 +31,10 @@ import time
import signal import signal
import unittest import unittest
from functools import wraps
from threading import Thread from threading import Thread
from ..client import fail2banclient, fail2banserver, fail2bancmdline from ..client import fail2banclient, fail2banserver, fail2bancmdline
from ..client.fail2banclient import Fail2banClient, exec_command_line as _exec_client, VisualWait from ..client.fail2banclient import Fail2banClient, exec_command_line as _exec_client, VisualWait
from ..client.fail2banserver import Fail2banServer, exec_command_line as _exec_server from ..client.fail2banserver import Fail2banServer, exec_command_line as _exec_server
@ -205,6 +207,20 @@ def _kill_srv(pidfile): # pragma: no cover
f.close() f.close()
return True return True
def with_kill_srv(f):
"""Helper to decorate tests which receive in the last argument tmpdir to pass to kill_srv
To be used in tandem with @with_tmpdir
"""
@wraps(f)
def wrapper(self, *args):
pidfile = args[-1]
try:
return f(self, *args)
finally:
_kill_srv(pidfile)
return wrapper
class Fail2banClientServerBase(LogCaptureTestCase): class Fail2banClientServerBase(LogCaptureTestCase):
@ -263,115 +279,111 @@ class Fail2banClientTest(Fail2banClientServerBase):
self.assertLogged("logtarget") self.assertLogged("logtarget")
@with_tmpdir @with_tmpdir
@with_kill_srv
def testClientStartBackgroundInside(self, tmp): def testClientStartBackgroundInside(self, tmp):
# use once the stock configuration (to test starting also)
startparams = _start_params(tmp, True)
# start:
self.assertRaises(ExitException, _exec_client,
(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: try:
# use once the stock configuration (to test starting also)
startparams = _start_params(tmp, True)
# start:
self.assertRaises(ExitException, _exec_client, self.assertRaises(ExitException, _exec_client,
(CLIENT, "-b") + startparams + ("start",)) (CLIENT,) + startparams + ("echo", "TEST-ECHO",))
# 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:
self.assertRaises(ExitException, _exec_client,
(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:
self.assertRaises(ExitException, _exec_client,
(CLIENT,) + startparams + ("stop",))
self.assertLogged("Shutdown successful")
self.assertLogged("Exit with code 0")
self.pruneLog()
# stop again (should fail):
self.assertRaises(FailExitException, _exec_client, self.assertRaises(FailExitException, _exec_client,
(CLIENT,) + startparams + ("stop",)) (CLIENT,) + startparams + ("~~unknown~cmd~failed~~",))
self.assertLogged("Failed to access socket path") self.pruneLog()
self.assertLogged("Is fail2ban running?") # start again (should fail):
self.assertRaises(FailExitException, _exec_client,
(CLIENT, "-b") + startparams + ("start",))
self.assertLogged("Server already running")
finally: finally:
_kill_srv(tmp) self.pruneLog()
# stop:
self.assertRaises(ExitException, _exec_client,
(CLIENT,) + startparams + ("stop",))
self.assertLogged("Shutdown successful")
self.assertLogged("Exit with code 0")
self.pruneLog()
# stop again (should fail):
self.assertRaises(FailExitException, _exec_client,
(CLIENT,) + startparams + ("stop",))
self.assertLogged("Failed to access socket path")
self.assertLogged("Is fail2ban running?")
@with_tmpdir @with_tmpdir
@with_kill_srv
def testClientStartBackgroundCall(self, tmp): def testClientStartBackgroundCall(self, tmp):
global INTERACT
startparams = _start_params(tmp, logtarget=tmp+"/f2b.log")
# 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)
cmd = cmd + startparams + ("--async", "start",)
ret = Utils.executeCmd(cmd, timeout=MAX_WAITTIME, shell=False, output=True)
self.assertTrue(len(ret) and ret[0])
# wait for server (socket and ready):
self._wait_for_srv(tmp, True, startparams=cmd)
self.assertLogged("Server ready")
self.pruneLog()
try: try:
global INTERACT # echo from client (inside):
startparams = _start_params(tmp, logtarget=tmp+"/f2b.log") self.assertRaises(ExitException, _exec_client,
# start (in new process, using the same python version): (CLIENT,) + startparams + ("echo", "TEST-ECHO",))
cmd = (sys.executable, os.path.join(os.path.join(BIN), CLIENT)) self.assertLogged("TEST-ECHO")
logSys.debug('Start %s ...', cmd) self.assertLogged("Exit with code 0")
cmd = cmd + startparams + ("--async", "start",) self.pruneLog()
ret = Utils.executeCmd(cmd, timeout=MAX_WAITTIME, shell=False, output=True) # interactive client chat with started server:
self.assertTrue(len(ret) and ret[0]) INTERACT += [
# wait for server (socket and ready): "echo INTERACT-ECHO",
self._wait_for_srv(tmp, True, startparams=cmd) "status",
self.assertLogged("Server ready") "exit"
]
self.assertRaises(ExitException, _exec_client,
(CLIENT,) + startparams + ("-i",))
self.assertLogged("INTERACT-ECHO")
self.assertLogged("Status", "Number of jail:")
self.assertLogged("Exit with code 0")
self.pruneLog()
# test reload and restart over interactive client:
INTERACT += [
"reload",
"restart",
"exit"
]
self.assertRaises(ExitException, _exec_client,
(CLIENT,) + startparams + ("-i",))
self.assertLogged("Reading config files:")
self.assertLogged("Shutdown successful")
self.assertLogged("Server ready")
self.assertLogged("Exit with code 0")
self.pruneLog()
# test reload missing jail (interactive):
INTERACT += [
"reload ~~unknown~jail~fail~~",
"exit"
]
self.assertRaises(ExitException, _exec_client,
(CLIENT,) + startparams + ("-i",))
self.assertLogged("Failed during configuration: No section: '~~unknown~jail~fail~~'")
self.pruneLog()
# test reload missing jail (direct):
self.assertRaises(FailExitException, _exec_client,
(CLIENT,) + startparams + ("reload", "~~unknown~jail~fail~~"))
self.assertLogged("Failed during configuration: No section: '~~unknown~jail~fail~~'")
self.assertLogged("Exit with code -1")
self.pruneLog() self.pruneLog()
try:
# echo from client (inside):
self.assertRaises(ExitException, _exec_client,
(CLIENT,) + startparams + ("echo", "TEST-ECHO",))
self.assertLogged("TEST-ECHO")
self.assertLogged("Exit with code 0")
self.pruneLog()
# interactive client chat with started server:
INTERACT += [
"echo INTERACT-ECHO",
"status",
"exit"
]
self.assertRaises(ExitException, _exec_client,
(CLIENT,) + startparams + ("-i",))
self.assertLogged("INTERACT-ECHO")
self.assertLogged("Status", "Number of jail:")
self.assertLogged("Exit with code 0")
self.pruneLog()
# test reload and restart over interactive client:
INTERACT += [
"reload",
"restart",
"exit"
]
self.assertRaises(ExitException, _exec_client,
(CLIENT,) + startparams + ("-i",))
self.assertLogged("Reading config files:")
self.assertLogged("Shutdown successful")
self.assertLogged("Server ready")
self.assertLogged("Exit with code 0")
self.pruneLog()
# test reload missing jail (interactive):
INTERACT += [
"reload ~~unknown~jail~fail~~",
"exit"
]
self.assertRaises(ExitException, _exec_client,
(CLIENT,) + startparams + ("-i",))
self.assertLogged("Failed during configuration: No section: '~~unknown~jail~fail~~'")
self.pruneLog()
# test reload missing jail (direct):
self.assertRaises(FailExitException, _exec_client,
(CLIENT,) + startparams + ("reload", "~~unknown~jail~fail~~"))
self.assertLogged("Failed during configuration: No section: '~~unknown~jail~fail~~'")
self.assertLogged("Exit with code -1")
self.pruneLog()
finally:
self.pruneLog()
# stop:
self.assertRaises(ExitException, _exec_client,
(CLIENT,) + startparams + ("stop",))
self.assertLogged("Shutdown successful")
self.assertLogged("Exit with code 0")
finally: finally:
_kill_srv(tmp) self.pruneLog()
# stop:
self.assertRaises(ExitException, _exec_client,
(CLIENT,) + startparams + ("stop",))
self.assertLogged("Shutdown successful")
self.assertLogged("Exit with code 0")
def _testClientStartForeground(self, tmp, startparams, phase): def _testClientStartForeground(self, tmp, startparams, phase):
# start and wait to end (foreground): # start and wait to end (foreground):
@ -424,45 +436,42 @@ class Fail2banClientTest(Fail2banClientServerBase):
th.join() th.join()
@with_tmpdir @with_tmpdir
@with_kill_srv
def testClientFailStart(self, tmp): def testClientFailStart(self, tmp):
try: # started directly here, so prevent overwrite test cases logger with "INHERITED"
# started directly here, so prevent overwrite test cases logger with "INHERITED" startparams = _start_params(tmp, logtarget="INHERITED")
startparams = _start_params(tmp, logtarget="INHERITED")
## wrong config directory ## wrong config directory
self.assertRaises(FailExitException, _exec_client, self.assertRaises(FailExitException, _exec_client,
(CLIENT, "--async", "-c", tmp+"/miss", "start",)) (CLIENT, "--async", "-c", tmp+"/miss", "start",))
self.assertLogged("Base configuration directory " + tmp+"/miss" + " does not exist") self.assertLogged("Base configuration directory " + tmp+"/miss" + " does not exist")
self.pruneLog() self.pruneLog()
## wrong socket ## wrong socket
self.assertRaises(FailExitException, _exec_client, self.assertRaises(FailExitException, _exec_client,
(CLIENT, "--async", "-c", tmp+"/config", "-s", tmp+"/miss/f2b.sock", "start",)) (CLIENT, "--async", "-c", tmp+"/config", "-s", tmp+"/miss/f2b.sock", "start",))
self.assertLogged("There is no directory " + tmp+"/miss" + " to contain the socket file") self.assertLogged("There is no directory " + tmp+"/miss" + " to contain the socket file")
self.pruneLog() self.pruneLog()
## not running ## not running
self.assertRaises(FailExitException, _exec_client, self.assertRaises(FailExitException, _exec_client,
(CLIENT, "-c", tmp+"/config", "-s", tmp+"/f2b.sock", "reload",)) (CLIENT, "-c", tmp+"/config", "-s", tmp+"/f2b.sock", "reload",))
self.assertLogged("Could not find server") self.assertLogged("Could not find server")
self.pruneLog() self.pruneLog()
## already exists: ## already exists:
open(tmp+"/f2b.sock", 'a').close() open(tmp+"/f2b.sock", 'a').close()
self.assertRaises(FailExitException, _exec_client, self.assertRaises(FailExitException, _exec_client,
(CLIENT, "--async", "-c", tmp+"/config", "-s", tmp+"/f2b.sock", "start",)) (CLIENT, "--async", "-c", tmp+"/config", "-s", tmp+"/f2b.sock", "start",))
self.assertLogged("Fail2ban seems to be in unexpected state (not running but the socket exists)") self.assertLogged("Fail2ban seems to be in unexpected state (not running but the socket exists)")
self.pruneLog() self.pruneLog()
os.remove(tmp+"/f2b.sock") os.remove(tmp+"/f2b.sock")
## wrong option: ## wrong option:
self.assertRaises(FailExitException, _exec_client, self.assertRaises(FailExitException, _exec_client,
(CLIENT, "-s",)) (CLIENT, "-s",))
self.assertLogged("Usage: ") self.assertLogged("Usage: ")
self.pruneLog() self.pruneLog()
finally:
_kill_srv(tmp)
def testVisualWait(self): def testVisualWait(self):
sleeptime = 0.035 sleeptime = 0.035
@ -485,34 +494,32 @@ class Fail2banServerTest(Fail2banClientServerBase):
self.assertLogged("Report bugs to ") self.assertLogged("Report bugs to ")
@with_tmpdir @with_tmpdir
@with_kill_srv
def testServerStartBackground(self, tmp): def testServerStartBackground(self, tmp):
# to prevent fork of test-cases process, start server in background via command:
startparams = _start_params(tmp, logtarget=tmp+"/f2b.log")
# 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",)
ret = Utils.executeCmd(cmd, timeout=MAX_WAITTIME, shell=False, output=True)
self.assertTrue(len(ret) and ret[0])
# wait for server (socket and ready):
self._wait_for_srv(tmp, True, startparams=cmd)
self.assertLogged("Server ready")
self.pruneLog()
try: try:
# to prevent fork of test-cases process, start server in background via command: self.assertRaises(ExitException, _exec_server,
startparams = _start_params(tmp, logtarget=tmp+"/f2b.log") (SERVER,) + startparams + ("echo", "TEST-ECHO",))
# start (in new process, using the same python version): self.assertRaises(FailExitException, _exec_server,
cmd = (sys.executable, os.path.join(os.path.join(BIN), SERVER)) (SERVER,) + startparams + ("~~unknown~cmd~failed~~",))
logSys.debug('Start %s ...', cmd)
cmd = cmd + startparams + ("-b",)
ret = Utils.executeCmd(cmd, timeout=MAX_WAITTIME, shell=False, output=True)
self.assertTrue(len(ret) and ret[0])
# wait for server (socket and ready):
self._wait_for_srv(tmp, True, startparams=cmd)
self.assertLogged("Server ready")
self.pruneLog()
try:
self.assertRaises(ExitException, _exec_server,
(SERVER,) + startparams + ("echo", "TEST-ECHO",))
self.assertRaises(FailExitException, _exec_server,
(SERVER,) + startparams + ("~~unknown~cmd~failed~~",))
finally:
self.pruneLog()
# stop:
self.assertRaises(ExitException, _exec_server,
(SERVER,) + startparams + ("stop",))
self.assertLogged("Shutdown successful")
self.assertLogged("Exit with code 0")
finally: finally:
_kill_srv(tmp) self.pruneLog()
# stop:
self.assertRaises(ExitException, _exec_server,
(SERVER,) + startparams + ("stop",))
self.assertLogged("Shutdown successful")
self.assertLogged("Exit with code 0")
def _testServerStartForeground(self, tmp, startparams, phase): def _testServerStartForeground(self, tmp, startparams, phase):
# start and wait to end (foreground): # start and wait to end (foreground):
@ -565,30 +572,27 @@ class Fail2banServerTest(Fail2banClientServerBase):
th.join() th.join()
@with_tmpdir @with_tmpdir
@with_kill_srv
def testServerFailStart(self, tmp): def testServerFailStart(self, tmp):
try: # started directly here, so prevent overwrite test cases logger with "INHERITED"
# started directly here, so prevent overwrite test cases logger with "INHERITED" startparams = _start_params(tmp, logtarget="INHERITED")
startparams = _start_params(tmp, logtarget="INHERITED")
## wrong config directory ## wrong config directory
self.assertRaises(FailExitException, _exec_server, self.assertRaises(FailExitException, _exec_server,
(SERVER, "-c", tmp+"/miss",)) (SERVER, "-c", tmp+"/miss",))
self.assertLogged("Base configuration directory " + tmp+"/miss" + " does not exist") self.assertLogged("Base configuration directory " + tmp+"/miss" + " does not exist")
self.pruneLog() self.pruneLog()
## wrong socket ## wrong socket
self.assertRaises(FailExitException, _exec_server, self.assertRaises(FailExitException, _exec_server,
(SERVER, "-c", tmp+"/config", "-x", "-s", tmp+"/miss/f2b.sock",)) (SERVER, "-c", tmp+"/config", "-x", "-s", tmp+"/miss/f2b.sock",))
self.assertLogged("There is no directory " + tmp+"/miss" + " to contain the socket file") self.assertLogged("There is no directory " + tmp+"/miss" + " to contain the socket file")
self.pruneLog() self.pruneLog()
## already exists: ## already exists:
open(tmp+"/f2b.sock", 'a').close() open(tmp+"/f2b.sock", 'a').close()
self.assertRaises(FailExitException, _exec_server, self.assertRaises(FailExitException, _exec_server,
(SERVER, "-c", tmp+"/config", "-s", tmp+"/f2b.sock",)) (SERVER, "-c", tmp+"/config", "-s", tmp+"/f2b.sock",))
self.assertLogged("Fail2ban seems to be in unexpected state (not running but the socket exists)") self.assertLogged("Fail2ban seems to be in unexpected state (not running but the socket exists)")
self.pruneLog() self.pruneLog()
os.remove(tmp+"/f2b.sock") os.remove(tmp+"/f2b.sock")
finally:
_kill_srv(tmp)