Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 6, 2010 22:34:55

Cyxapeff
От:
Зарегистрирован: 2006-08-17
Сообщения: 148
Репутация: +  0  -
Профиль   Отправить e-mail  

Unittest tearDown and fork

Вынес часть функционала в отдельного демона, переделываю тесты, перед каждым тестом хочу демона стартовать, а после соответственно останавливать.

class BaseTest(TestCase):
def setUp(self):
print 'TEST start'
...
self.daemon = MyDaemon('/tmp/daemon-test.pid')
self.daemon.start()

def tearDown(self):
print 'TEST stop'
self.daemon.stop()
Проблема в том, что с появлением daemon.start() метод tearDown() перестаёт вызывается по окончанию теста.

MyDaemon() это http://gist.github.com/613926 (найденный на просторах интернета) с переопределённым методом run.

Погуглил - ничего не нашёл, видимо поисковый запрос составил как-то не так. Не знаю в какую сторону копать, подскажите, пожалуйста.



Офлайн

#2 Окт. 7, 2010 00:06:03

Александр Кошелев
От: Москва
Зарегистрирован: 2007-02-03
Сообщения: 1724
Репутация: +  2  -
Профиль   Отправить e-mail  

Unittest tearDown and fork

А тесты выполняются!?:-)



Офлайн

#3 Окт. 7, 2010 00:17:29

Cyxapeff
От:
Зарегистрирован: 2006-08-17
Сообщения: 148
Репутация: +  0  -
Профиль   Отправить e-mail  

Unittest tearDown and fork

Да, первый тест отрабатывает как следует, а дальше естественно ошибка т.к демон уже запущен и pid существует. Если оставить только один тест, то тестирование завершается успешно, консоль возвращается, но tearDown так и не выполняется.



Офлайн

#4 Окт. 7, 2010 09:53:41

ziro
От:
Зарегистрирован: 2009-08-13
Сообщения: 225
Репутация: +  8  -
Профиль   Отправить e-mail  

Unittest tearDown and fork

Я обычно выполняю тесты демонов так

from subprocess import Popen, PIPE

class LaunchResult(object):
'''
Small helper to hold result for daemon launch.


:param output: data from stdout stream;
:param errors: data from stderr stream;
'''
def __init__(self, output, errors):
self.output = output
self.errors = errors

@property
def has_errors(self):
'''
Is was error when daemon executed
'''
return self.errors != ''

class Launcher(object):
'''
Utility class for launching daemon via :mod:`subprocess.Popen`

:param settings: python path for module with settings to owerride defaults;
'''
def __init__(self, settings):
self.settings = settings

def launch(self, command, mode, *opts, **optpairs):
'''
Launch daemon script command

:param command: daemon command to launch;
:param mode: daemon mode for launching command;
:param opts: flag options for command;
:param optpairs: value options for command;
'''
args = ['daemon']

if command: args.append(command)

# Simple option
for option in opts:
if option.startswith('-'):
args.append(option)
else:
args.append('--%s' % option)

# Pair option
for option, value in optpairs.iteritems():
args.append('--%s=%s' % (option, value))

if self.settings:
args.append('--settings=%s' % self.settings)

if mode: args.append(mode)

data = Popen(args, stdout=PIPE, stderr=PIPE).communicate()
return LaunchResult(*data)
То есть тестирую демон как внешний черный ящик. При необходимости записываю команды старта/останова демона в setUp, tearDown



Офлайн

#5 Окт. 7, 2010 22:56:53

Cyxapeff
От:
Зарегистрирован: 2006-08-17
Сообщения: 148
Репутация: +  0  -
Профиль   Отправить e-mail  

Unittest tearDown and fork

Ну примерно так я и поступил сразу. Только через call_command, т.к. тестируется django приложение. Но всё-таки интересно, почему оно так странно не работает.



Офлайн

#6 Окт. 8, 2010 08:45:33

ziro
От:
Зарегистрирован: 2009-08-13
Сообщения: 225
Репутация: +  8  -
Профиль   Отправить e-mail  

Unittest tearDown and fork

Ну если Вы действительно запускаете так, как привели в коде, то ничего удивительного, так как в setUp у Вас вызывается метод start, в котором вызывается метод daemonize, который форкает процесс и завершает запускающий процесс, в данном случае - Ваш тест, так что там не только tearDown, там и функция тестирования не успевает выполнятся так, чтобы Вы видели реальный результат (впрочем в отфоркнутом процессе тест выполнятся продолжает, но к сожалению вес вывод идет в /dev/null, как и положено). И как следствие, второй тест тоже не запускается.

Так что единственный способ на мой взгляд тестировать демоны - это запускать их через subprocess.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version