2015-09-30 4 views
1

Я хочу запустить тесты интеграции py.test для моего приложения Django 1.8 с полной установкой Celery 3.1, то есть с реальной очередью (не CELERY_ALWAYS_EAGER).Интроспекция работника сельдерея для получения имени хоста/nodename

Для этого мне нужно убедить рабочего использовать мою тестовую базу данных на сервере (PostgreSQL), а не стандартную конфигурацию DB (SQlite3, которая не может разговаривать со вторым процессом).

Для этого я хочу просто изменить DATABASES setting в рабочем процессе до того, как база данных будет впервые использована. (Я хочу сохранить SQlite для других тестов py.test, а также для обычной нетестовой БД для интерактивного тестирования.)

Для этого работник должен признать, что он работает в тестовом режиме, в отличие от 'нормальный режим. Для индикации режима тестирования, я начинаю рабочий с различными именами узлов:

celery worker -A myapp --concurrency=1 -n myworker --loglevel=info 

для нормального режима по сравнению с

celery worker -A myapp --concurrency=1 -n mytestworker --loglevel=info 

для режима испытаний.

Вопрос: Как модуль celery.py в моем приложении Django может читать вне имя_узла (имя хоста, заданное параметром -n) работника?

Там, как представляется, три процесса, участвующих (я не имею никакой дальнейшей конфигурации параллелизма за выше =1):

  1. celery.exe (я на Windows),
  2. работник сам, и
  3. рабочий процесс (что для меня актуально).

Это правильно?

Там, как представляется, отличается signals, что сельдерей посылает каждому процессу:

  1. celeryd_init отправляется celery.exe,
  2. worker_init отправляется на работника,
  3. worker_process_init отправляется на рабочий процесс

Правильно ли это?

Я добавил следующее celery.py в моем приложении Django:

import celery.signals 

def init_here(signal, sender): 
    print("call %s(sender=%s)" % (signal, sender)) 

@celery.signals.celeryd_init.connect 
def celeryd_init(sender, instance, **kwargs): 
    init_here("celeryd_init", sender) 

@celery.signals.worker_init.connect 
def worker_init(sender, **kwargs): 
    init_here("worker_init", sender) 

@celery.signals.worker_process_init.connect 
def worker_process_init(sender, **kwargs): 
    init_here("worker_process_init", sender) 

Когда я начинаю рабочий в тестовом режиме, как указано выше, я получаю следующий результат (среди прочего):

call celeryd_init([email protected]) 
call worker_init([email protected]) 
[2015-09-30 15:53:23,767: WARNING/MainProcess] [email protected] ready. 
[2015-09-30 15:53:24,282: WARNING/Worker-1] call worker_process_init(sender=None) 

Слишком плохо! Соответствующий процесс Worker-1 не получает соответствующей информации [email protected]. Как получить имя хоста?

+0

Моя выше проблема действительно (как предложено @Louis), которую лучше всего разрешить переменной окружения. Тем не менее, я все равно хотел бы узнать ответ на вопрос, как его задали. –

ответ

0

Даже если вы можете заставить его работать, я не рекомендую использовать имена рабочих, чтобы определить, находитесь ли вы в тестовом режиме или нет. Это будет взлом.

Как я уже решил вопрос узнать, является ли мой код работает в тестовом режиме, или не иметь другой файл настроек под названием proj/test_settings.py (в то время как «регулярный» один находится в proj/settings.py), где proj мой проект-х имя (то же самое с PROJ ниже). Я его создать установку, которая определяет, является ли мы в режиме тестирования или нет:

from .settings import * 

PROJ_TESTING = True 

Эта переменная устанавливается истина только в файле test_settings. Обратите внимание, что в этом файле test_settings.py также можно указать некоторые строки, которые переопределяют значения по умолчанию, установленные в settings.py. Например, у меня есть код, который изменяет конфигурацию базы данных и регистрирует.

Я размещаю код, запускающий тесты для установки переменной окружения DJANGO_SETTINGS_MODULE=proj.test_settings. Поскольку мои работники сельдерея, используемые в тестировании, запускаются по коду, который запускает мой тест, тогда они загружают настройки теста и работают с PROJ_TESTING true. Таким образом, чтобы проверить в режиме тестирования, если мне нужно, я могу это сделать:

from django.conf import settings 

if settings.PROJ_TESTING: 
    # Do what we need when we are testing. 
else: 
    # Do something else. 

Этот метод ведения дел отражает, как мы установили режим отладки, установив параметр DEBUG в True.

Смежные вопросы