|
@@ -9,7 +9,7 @@ from Queue import Empty
|
|
|
|
|
|
from billiard.exceptions import WorkerLostError
|
|
from billiard.exceptions import WorkerLostError
|
|
from kombu import Connection
|
|
from kombu import Connection
|
|
-from kombu.common import QoS, PREFETCH_COUNT_MAX
|
|
|
|
|
|
+from kombu.common import QoS, PREFETCH_COUNT_MAX, ignore_errors
|
|
from kombu.exceptions import StdChannelError
|
|
from kombu.exceptions import StdChannelError
|
|
from kombu.transport.base import Message
|
|
from kombu.transport.base import Message
|
|
from mock import Mock, patch
|
|
from mock import Mock, patch
|
|
@@ -17,6 +17,7 @@ from nose import SkipTest
|
|
|
|
|
|
from celery import current_app
|
|
from celery import current_app
|
|
from celery.app.defaults import DEFAULTS
|
|
from celery.app.defaults import DEFAULTS
|
|
|
|
+from celery.bootsteps import RUN, CLOSE, TERMINATE, StartStopStep
|
|
from celery.concurrency.base import BasePool
|
|
from celery.concurrency.base import BasePool
|
|
from celery.datastructures import AttributeDict
|
|
from celery.datastructures import AttributeDict
|
|
from celery.exceptions import SystemTerminate
|
|
from celery.exceptions import SystemTerminate
|
|
@@ -24,33 +25,51 @@ from celery.task import task as task_dec
|
|
from celery.task import periodic_task as periodic_task_dec
|
|
from celery.task import periodic_task as periodic_task_dec
|
|
from celery.utils import uuid
|
|
from celery.utils import uuid
|
|
from celery.worker import WorkController
|
|
from celery.worker import WorkController
|
|
-from celery.worker.components import Queues, Timers, EvLoop, Pool
|
|
|
|
-from celery.worker.bootsteps import RUN, CLOSE, TERMINATE, StartStopComponent
|
|
|
|
|
|
+from celery.worker.components import Queues, Timers, Hub, Pool
|
|
from celery.worker.buckets import FastQueue
|
|
from celery.worker.buckets import FastQueue
|
|
from celery.worker.job import Request
|
|
from celery.worker.job import Request
|
|
-from celery.worker.consumer import BlockingConsumer
|
|
|
|
|
|
+from celery.worker import consumer
|
|
|
|
+from celery.worker.consumer import Consumer
|
|
from celery.utils.serialization import pickle
|
|
from celery.utils.serialization import pickle
|
|
from celery.utils.timer2 import Timer
|
|
from celery.utils.timer2 import Timer
|
|
|
|
|
|
from celery.tests.utils import AppCase, Case
|
|
from celery.tests.utils import AppCase, Case
|
|
|
|
|
|
|
|
|
|
|
|
+def MockStep(step=None):
|
|
|
|
+ step = Mock() if step is None else step
|
|
|
|
+ step.namespace = Mock()
|
|
|
|
+ step.namespace.name = 'MockNS'
|
|
|
|
+ step.name = 'MockStep'
|
|
|
|
+ return step
|
|
|
|
+
|
|
|
|
+
|
|
class PlaceHolder(object):
|
|
class PlaceHolder(object):
|
|
pass
|
|
pass
|
|
|
|
|
|
|
|
|
|
-class MyKombuConsumer(BlockingConsumer):
|
|
|
|
|
|
+def find_step(obj, typ):
|
|
|
|
+ return obj.namespace.steps[typ.name]
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+class _MyKombuConsumer(Consumer):
|
|
broadcast_consumer = Mock()
|
|
broadcast_consumer = Mock()
|
|
task_consumer = Mock()
|
|
task_consumer = Mock()
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
def __init__(self, *args, **kwargs):
|
|
kwargs.setdefault('pool', BasePool(2))
|
|
kwargs.setdefault('pool', BasePool(2))
|
|
- super(MyKombuConsumer, self).__init__(*args, **kwargs)
|
|
|
|
|
|
+ super(_MyKombuConsumer, self).__init__(*args, **kwargs)
|
|
|
|
|
|
def restart_heartbeat(self):
|
|
def restart_heartbeat(self):
|
|
self.heart = None
|
|
self.heart = None
|
|
|
|
|
|
|
|
|
|
|
|
+class MyKombuConsumer(Consumer):
|
|
|
|
+
|
|
|
|
+ def loop(self, *args, **kwargs):
|
|
|
|
+ pass
|
|
|
|
+
|
|
|
|
+
|
|
class MockNode(object):
|
|
class MockNode(object):
|
|
commands = []
|
|
commands = []
|
|
|
|
|
|
@@ -227,90 +246,102 @@ class test_Consumer(Case):
|
|
|
|
|
|
def test_start_when_closed(self):
|
|
def test_start_when_closed(self):
|
|
l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
- l._state = CLOSE
|
|
|
|
|
|
+ l.namespace.state = CLOSE
|
|
l.start()
|
|
l.start()
|
|
|
|
|
|
def test_connection(self):
|
|
def test_connection(self):
|
|
l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
|
|
|
|
- l.reset_connection()
|
|
|
|
|
|
+ l.namespace.start(l)
|
|
self.assertIsInstance(l.connection, Connection)
|
|
self.assertIsInstance(l.connection, Connection)
|
|
|
|
|
|
- l._state = RUN
|
|
|
|
|
|
+ l.namespace.state = RUN
|
|
l.event_dispatcher = None
|
|
l.event_dispatcher = None
|
|
- l.stop_consumers(close_connection=False)
|
|
|
|
|
|
+ l.namespace.restart(l)
|
|
self.assertTrue(l.connection)
|
|
self.assertTrue(l.connection)
|
|
|
|
|
|
- l._state = RUN
|
|
|
|
- l.stop_consumers()
|
|
|
|
|
|
+ l.namespace.state = RUN
|
|
|
|
+ l.shutdown()
|
|
self.assertIsNone(l.connection)
|
|
self.assertIsNone(l.connection)
|
|
self.assertIsNone(l.task_consumer)
|
|
self.assertIsNone(l.task_consumer)
|
|
|
|
|
|
- l.reset_connection()
|
|
|
|
|
|
+ l.namespace.start(l)
|
|
self.assertIsInstance(l.connection, Connection)
|
|
self.assertIsInstance(l.connection, Connection)
|
|
- l.stop_consumers()
|
|
|
|
|
|
+ l.namespace.restart(l)
|
|
|
|
|
|
l.stop()
|
|
l.stop()
|
|
- l.close_connection()
|
|
|
|
|
|
+ l.shutdown()
|
|
self.assertIsNone(l.connection)
|
|
self.assertIsNone(l.connection)
|
|
self.assertIsNone(l.task_consumer)
|
|
self.assertIsNone(l.task_consumer)
|
|
|
|
|
|
def test_close_connection(self):
|
|
def test_close_connection(self):
|
|
l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
- l._state = RUN
|
|
|
|
- l.close_connection()
|
|
|
|
|
|
+ l.namespace.state = RUN
|
|
|
|
+ step = find_step(l, consumer.Connection)
|
|
|
|
+ conn = l.connection = Mock()
|
|
|
|
+ step.shutdown(l)
|
|
|
|
+ self.assertTrue(conn.close.called)
|
|
|
|
+ self.assertIsNone(l.connection)
|
|
|
|
|
|
l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
eventer = l.event_dispatcher = Mock()
|
|
eventer = l.event_dispatcher = Mock()
|
|
eventer.enabled = True
|
|
eventer.enabled = True
|
|
heart = l.heart = MockHeart()
|
|
heart = l.heart = MockHeart()
|
|
- l._state = RUN
|
|
|
|
- l.stop_consumers()
|
|
|
|
|
|
+ l.namespace.state = RUN
|
|
|
|
+ Events = find_step(l, consumer.Events)
|
|
|
|
+ Events.shutdown(l)
|
|
|
|
+ Heart = find_step(l, consumer.Heart)
|
|
|
|
+ Heart.shutdown(l)
|
|
self.assertTrue(eventer.close.call_count)
|
|
self.assertTrue(eventer.close.call_count)
|
|
self.assertTrue(heart.closed)
|
|
self.assertTrue(heart.closed)
|
|
|
|
|
|
@patch('celery.worker.consumer.warn')
|
|
@patch('celery.worker.consumer.warn')
|
|
def test_receive_message_unknown(self, warn):
|
|
def test_receive_message_unknown(self, warn):
|
|
- l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
|
|
|
|
+ l = _MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
|
|
+ l.steps.pop()
|
|
backend = Mock()
|
|
backend = Mock()
|
|
m = create_message(backend, unknown={'baz': '!!!'})
|
|
m = create_message(backend, unknown={'baz': '!!!'})
|
|
l.event_dispatcher = Mock()
|
|
l.event_dispatcher = Mock()
|
|
- l.pidbox_node = MockNode()
|
|
|
|
|
|
+ l.node = MockNode()
|
|
|
|
|
|
- l.receive_message(m.decode(), m)
|
|
|
|
|
|
+ callback = self._get_on_message(l)
|
|
|
|
+ callback(m.decode(), m)
|
|
self.assertTrue(warn.call_count)
|
|
self.assertTrue(warn.call_count)
|
|
|
|
|
|
- @patch('celery.utils.timer2.to_timestamp')
|
|
|
|
|
|
+ @patch('celery.worker.consumer.to_timestamp')
|
|
def test_receive_message_eta_OverflowError(self, to_timestamp):
|
|
def test_receive_message_eta_OverflowError(self, to_timestamp):
|
|
to_timestamp.side_effect = OverflowError()
|
|
to_timestamp.side_effect = OverflowError()
|
|
- l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
|
|
|
|
+ l = _MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
|
|
+ l.steps.pop()
|
|
m = create_message(Mock(), task=foo_task.name,
|
|
m = create_message(Mock(), task=foo_task.name,
|
|
args=('2, 2'),
|
|
args=('2, 2'),
|
|
kwargs={},
|
|
kwargs={},
|
|
eta=datetime.now().isoformat())
|
|
eta=datetime.now().isoformat())
|
|
l.event_dispatcher = Mock()
|
|
l.event_dispatcher = Mock()
|
|
- l.pidbox_node = MockNode()
|
|
|
|
|
|
+ l.node = MockNode()
|
|
l.update_strategies()
|
|
l.update_strategies()
|
|
|
|
|
|
- l.receive_message(m.decode(), m)
|
|
|
|
|
|
+ callback = self._get_on_message(l)
|
|
|
|
+ callback(m.decode(), m)
|
|
self.assertTrue(m.acknowledged)
|
|
self.assertTrue(m.acknowledged)
|
|
self.assertTrue(to_timestamp.call_count)
|
|
self.assertTrue(to_timestamp.call_count)
|
|
|
|
|
|
@patch('celery.worker.consumer.error')
|
|
@patch('celery.worker.consumer.error')
|
|
def test_receive_message_InvalidTaskError(self, error):
|
|
def test_receive_message_InvalidTaskError(self, error):
|
|
- l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
|
|
|
|
+ l = _MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
|
|
+ l.steps.pop()
|
|
m = create_message(Mock(), task=foo_task.name,
|
|
m = create_message(Mock(), task=foo_task.name,
|
|
args=(1, 2), kwargs='foobarbaz', id=1)
|
|
args=(1, 2), kwargs='foobarbaz', id=1)
|
|
l.update_strategies()
|
|
l.update_strategies()
|
|
l.event_dispatcher = Mock()
|
|
l.event_dispatcher = Mock()
|
|
- l.pidbox_node = MockNode()
|
|
|
|
|
|
|
|
- l.receive_message(m.decode(), m)
|
|
|
|
|
|
+ callback = self._get_on_message(l)
|
|
|
|
+ callback(m.decode(), m)
|
|
self.assertIn('Received invalid task message', error.call_args[0][0])
|
|
self.assertIn('Received invalid task message', error.call_args[0][0])
|
|
|
|
|
|
@patch('celery.worker.consumer.crit')
|
|
@patch('celery.worker.consumer.crit')
|
|
def test_on_decode_error(self, crit):
|
|
def test_on_decode_error(self, crit):
|
|
- l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
|
|
|
|
+ l = Consumer(self.ready_queue, timer=self.timer)
|
|
|
|
|
|
class MockMessage(Mock):
|
|
class MockMessage(Mock):
|
|
content_type = 'application/x-msgpack'
|
|
content_type = 'application/x-msgpack'
|
|
@@ -322,14 +353,25 @@ class test_Consumer(Case):
|
|
self.assertTrue(message.ack.call_count)
|
|
self.assertTrue(message.ack.call_count)
|
|
self.assertIn("Can't decode message body", crit.call_args[0][0])
|
|
self.assertIn("Can't decode message body", crit.call_args[0][0])
|
|
|
|
|
|
|
|
+ def _get_on_message(self, l):
|
|
|
|
+ l.qos = Mock()
|
|
|
|
+ l.event_dispatcher = Mock()
|
|
|
|
+ l.task_consumer = Mock()
|
|
|
|
+ l.connection = Mock()
|
|
|
|
+ l.connection.drain_events.side_effect = SystemExit()
|
|
|
|
+
|
|
|
|
+ with self.assertRaises(SystemExit):
|
|
|
|
+ l.loop(*l.loop_args())
|
|
|
|
+ self.assertTrue(l.task_consumer.register_callback.called)
|
|
|
|
+ return l.task_consumer.register_callback.call_args[0][0]
|
|
|
|
+
|
|
def test_receieve_message(self):
|
|
def test_receieve_message(self):
|
|
- l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
|
|
|
|
+ l = Consumer(self.ready_queue, timer=self.timer)
|
|
m = create_message(Mock(), task=foo_task.name,
|
|
m = create_message(Mock(), task=foo_task.name,
|
|
args=[2, 4, 8], kwargs={})
|
|
args=[2, 4, 8], kwargs={})
|
|
l.update_strategies()
|
|
l.update_strategies()
|
|
-
|
|
|
|
- l.event_dispatcher = Mock()
|
|
|
|
- l.receive_message(m.decode(), m)
|
|
|
|
|
|
+ callback = self._get_on_message(l)
|
|
|
|
+ callback(m.decode(), m)
|
|
|
|
|
|
in_bucket = self.ready_queue.get_nowait()
|
|
in_bucket = self.ready_queue.get_nowait()
|
|
self.assertIsInstance(in_bucket, Request)
|
|
self.assertIsInstance(in_bucket, Request)
|
|
@@ -339,10 +381,10 @@ class test_Consumer(Case):
|
|
|
|
|
|
def test_start_connection_error(self):
|
|
def test_start_connection_error(self):
|
|
|
|
|
|
- class MockConsumer(BlockingConsumer):
|
|
|
|
|
|
+ class MockConsumer(Consumer):
|
|
iterations = 0
|
|
iterations = 0
|
|
|
|
|
|
- def consume_messages(self):
|
|
|
|
|
|
+ def loop(self, *args, **kwargs):
|
|
if not self.iterations:
|
|
if not self.iterations:
|
|
self.iterations = 1
|
|
self.iterations = 1
|
|
raise KeyError('foo')
|
|
raise KeyError('foo')
|
|
@@ -360,10 +402,10 @@ class test_Consumer(Case):
|
|
# Regression test for AMQPChannelExceptions that can occur within the
|
|
# Regression test for AMQPChannelExceptions that can occur within the
|
|
# consumer. (i.e. 404 errors)
|
|
# consumer. (i.e. 404 errors)
|
|
|
|
|
|
- class MockConsumer(BlockingConsumer):
|
|
|
|
|
|
+ class MockConsumer(Consumer):
|
|
iterations = 0
|
|
iterations = 0
|
|
|
|
|
|
- def consume_messages(self):
|
|
|
|
|
|
+ def loop(self, *args, **kwargs):
|
|
if not self.iterations:
|
|
if not self.iterations:
|
|
self.iterations = 1
|
|
self.iterations = 1
|
|
raise KeyError('foo')
|
|
raise KeyError('foo')
|
|
@@ -377,7 +419,7 @@ class test_Consumer(Case):
|
|
l.heart.stop()
|
|
l.heart.stop()
|
|
l.timer.stop()
|
|
l.timer.stop()
|
|
|
|
|
|
- def test_consume_messages_ignores_socket_timeout(self):
|
|
|
|
|
|
+ def test_loop_ignores_socket_timeout(self):
|
|
|
|
|
|
class Connection(current_app.connection().__class__):
|
|
class Connection(current_app.connection().__class__):
|
|
obj = None
|
|
obj = None
|
|
@@ -391,9 +433,9 @@ class test_Consumer(Case):
|
|
l.task_consumer = Mock()
|
|
l.task_consumer = Mock()
|
|
l.connection.obj = l
|
|
l.connection.obj = l
|
|
l.qos = QoS(l.task_consumer, 10)
|
|
l.qos = QoS(l.task_consumer, 10)
|
|
- l.consume_messages()
|
|
|
|
|
|
+ l.loop(*l.loop_args())
|
|
|
|
|
|
- def test_consume_messages_when_socket_error(self):
|
|
|
|
|
|
+ def test_loop_when_socket_error(self):
|
|
|
|
|
|
class Connection(current_app.connection().__class__):
|
|
class Connection(current_app.connection().__class__):
|
|
obj = None
|
|
obj = None
|
|
@@ -402,20 +444,20 @@ class test_Consumer(Case):
|
|
self.obj.connection = None
|
|
self.obj.connection = None
|
|
raise socket.error('foo')
|
|
raise socket.error('foo')
|
|
|
|
|
|
- l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
|
|
- l._state = RUN
|
|
|
|
|
|
+ l = Consumer(self.ready_queue, timer=self.timer)
|
|
|
|
+ l.namespace.state = RUN
|
|
c = l.connection = Connection()
|
|
c = l.connection = Connection()
|
|
l.connection.obj = l
|
|
l.connection.obj = l
|
|
l.task_consumer = Mock()
|
|
l.task_consumer = Mock()
|
|
l.qos = QoS(l.task_consumer, 10)
|
|
l.qos = QoS(l.task_consumer, 10)
|
|
with self.assertRaises(socket.error):
|
|
with self.assertRaises(socket.error):
|
|
- l.consume_messages()
|
|
|
|
|
|
+ l.loop(*l.loop_args())
|
|
|
|
|
|
- l._state = CLOSE
|
|
|
|
|
|
+ l.namespace.state = CLOSE
|
|
l.connection = c
|
|
l.connection = c
|
|
- l.consume_messages()
|
|
|
|
|
|
+ l.loop(*l.loop_args())
|
|
|
|
|
|
- def test_consume_messages(self):
|
|
|
|
|
|
+ def test_loop(self):
|
|
|
|
|
|
class Connection(current_app.connection().__class__):
|
|
class Connection(current_app.connection().__class__):
|
|
obj = None
|
|
obj = None
|
|
@@ -423,14 +465,14 @@ class test_Consumer(Case):
|
|
def drain_events(self, **kwargs):
|
|
def drain_events(self, **kwargs):
|
|
self.obj.connection = None
|
|
self.obj.connection = None
|
|
|
|
|
|
- l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
|
|
|
|
+ l = Consumer(self.ready_queue, timer=self.timer)
|
|
l.connection = Connection()
|
|
l.connection = Connection()
|
|
l.connection.obj = l
|
|
l.connection.obj = l
|
|
l.task_consumer = Mock()
|
|
l.task_consumer = Mock()
|
|
l.qos = QoS(l.task_consumer, 10)
|
|
l.qos = QoS(l.task_consumer, 10)
|
|
|
|
|
|
- l.consume_messages()
|
|
|
|
- l.consume_messages()
|
|
|
|
|
|
+ l.loop(*l.loop_args())
|
|
|
|
+ l.loop(*l.loop_args())
|
|
self.assertTrue(l.task_consumer.consume.call_count)
|
|
self.assertTrue(l.task_consumer.consume.call_count)
|
|
l.task_consumer.qos.assert_called_with(prefetch_count=10)
|
|
l.task_consumer.qos.assert_called_with(prefetch_count=10)
|
|
l.task_consumer.qos = Mock()
|
|
l.task_consumer.qos = Mock()
|
|
@@ -441,15 +483,15 @@ class test_Consumer(Case):
|
|
self.assertEqual(l.qos.value, 9)
|
|
self.assertEqual(l.qos.value, 9)
|
|
l.task_consumer.qos.assert_called_with(prefetch_count=9)
|
|
l.task_consumer.qos.assert_called_with(prefetch_count=9)
|
|
|
|
|
|
- def test_maybe_conn_error(self):
|
|
|
|
|
|
+ def test_ignore_errors(self):
|
|
l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
l.connection_errors = (KeyError, )
|
|
l.connection_errors = (KeyError, )
|
|
l.channel_errors = (SyntaxError, )
|
|
l.channel_errors = (SyntaxError, )
|
|
- l.maybe_conn_error(Mock(side_effect=AttributeError('foo')))
|
|
|
|
- l.maybe_conn_error(Mock(side_effect=KeyError('foo')))
|
|
|
|
- l.maybe_conn_error(Mock(side_effect=SyntaxError('foo')))
|
|
|
|
|
|
+ ignore_errors(l, Mock(side_effect=AttributeError('foo')))
|
|
|
|
+ ignore_errors(l, Mock(side_effect=KeyError('foo')))
|
|
|
|
+ ignore_errors(l, Mock(side_effect=SyntaxError('foo')))
|
|
with self.assertRaises(IndexError):
|
|
with self.assertRaises(IndexError):
|
|
- l.maybe_conn_error(Mock(side_effect=IndexError('foo')))
|
|
|
|
|
|
+ ignore_errors(l, Mock(side_effect=IndexError('foo')))
|
|
|
|
|
|
def test_apply_eta_task(self):
|
|
def test_apply_eta_task(self):
|
|
from celery.worker import state
|
|
from celery.worker import state
|
|
@@ -464,18 +506,20 @@ class test_Consumer(Case):
|
|
self.assertIs(self.ready_queue.get_nowait(), task)
|
|
self.assertIs(self.ready_queue.get_nowait(), task)
|
|
|
|
|
|
def test_receieve_message_eta_isoformat(self):
|
|
def test_receieve_message_eta_isoformat(self):
|
|
- l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
|
|
|
|
+ l = _MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
|
|
+ l.steps.pop()
|
|
m = create_message(Mock(), task=foo_task.name,
|
|
m = create_message(Mock(), task=foo_task.name,
|
|
eta=datetime.now().isoformat(),
|
|
eta=datetime.now().isoformat(),
|
|
args=[2, 4, 8], kwargs={})
|
|
args=[2, 4, 8], kwargs={})
|
|
|
|
|
|
l.task_consumer = Mock()
|
|
l.task_consumer = Mock()
|
|
- l.qos = QoS(l.task_consumer, l.initial_prefetch_count)
|
|
|
|
|
|
+ l.qos = QoS(l.task_consumer, 1)
|
|
current_pcount = l.qos.value
|
|
current_pcount = l.qos.value
|
|
l.event_dispatcher = Mock()
|
|
l.event_dispatcher = Mock()
|
|
l.enabled = False
|
|
l.enabled = False
|
|
l.update_strategies()
|
|
l.update_strategies()
|
|
- l.receive_message(m.decode(), m)
|
|
|
|
|
|
+ callback = self._get_on_message(l)
|
|
|
|
+ callback(m.decode(), m)
|
|
l.timer.stop()
|
|
l.timer.stop()
|
|
l.timer.join(1)
|
|
l.timer.join(1)
|
|
|
|
|
|
@@ -488,28 +532,30 @@ class test_Consumer(Case):
|
|
self.assertGreater(l.qos.value, current_pcount)
|
|
self.assertGreater(l.qos.value, current_pcount)
|
|
l.timer.stop()
|
|
l.timer.stop()
|
|
|
|
|
|
- def test_on_control(self):
|
|
|
|
|
|
+ def test_pidbox_callback(self):
|
|
l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
- l.pidbox_node = Mock()
|
|
|
|
- l.reset_pidbox_node = Mock()
|
|
|
|
|
|
+ con = find_step(l, consumer.Control).box
|
|
|
|
+ con.node = Mock()
|
|
|
|
+ con.reset = Mock()
|
|
|
|
|
|
- l.on_control('foo', 'bar')
|
|
|
|
- l.pidbox_node.handle_message.assert_called_with('foo', 'bar')
|
|
|
|
|
|
+ con.on_message('foo', 'bar')
|
|
|
|
+ con.node.handle_message.assert_called_with('foo', 'bar')
|
|
|
|
|
|
- l.pidbox_node = Mock()
|
|
|
|
- l.pidbox_node.handle_message.side_effect = KeyError('foo')
|
|
|
|
- l.on_control('foo', 'bar')
|
|
|
|
- l.pidbox_node.handle_message.assert_called_with('foo', 'bar')
|
|
|
|
|
|
+ con.node = Mock()
|
|
|
|
+ con.node.handle_message.side_effect = KeyError('foo')
|
|
|
|
+ con.on_message('foo', 'bar')
|
|
|
|
+ con.node.handle_message.assert_called_with('foo', 'bar')
|
|
|
|
|
|
- l.pidbox_node = Mock()
|
|
|
|
- l.pidbox_node.handle_message.side_effect = ValueError('foo')
|
|
|
|
- l.on_control('foo', 'bar')
|
|
|
|
- l.pidbox_node.handle_message.assert_called_with('foo', 'bar')
|
|
|
|
- l.reset_pidbox_node.assert_called_with()
|
|
|
|
|
|
+ con.node = Mock()
|
|
|
|
+ con.node.handle_message.side_effect = ValueError('foo')
|
|
|
|
+ con.on_message('foo', 'bar')
|
|
|
|
+ con.node.handle_message.assert_called_with('foo', 'bar')
|
|
|
|
+ self.assertTrue(con.reset.called)
|
|
|
|
|
|
def test_revoke(self):
|
|
def test_revoke(self):
|
|
ready_queue = FastQueue()
|
|
ready_queue = FastQueue()
|
|
- l = MyKombuConsumer(ready_queue, timer=self.timer)
|
|
|
|
|
|
+ l = _MyKombuConsumer(ready_queue, timer=self.timer)
|
|
|
|
+ l.steps.pop()
|
|
backend = Mock()
|
|
backend = Mock()
|
|
id = uuid()
|
|
id = uuid()
|
|
t = create_message(backend, task=foo_task.name, args=[2, 4, 8],
|
|
t = create_message(backend, task=foo_task.name, args=[2, 4, 8],
|
|
@@ -517,16 +563,19 @@ class test_Consumer(Case):
|
|
from celery.worker.state import revoked
|
|
from celery.worker.state import revoked
|
|
revoked.add(id)
|
|
revoked.add(id)
|
|
|
|
|
|
- l.receive_message(t.decode(), t)
|
|
|
|
|
|
+ callback = self._get_on_message(l)
|
|
|
|
+ callback(t.decode(), t)
|
|
self.assertTrue(ready_queue.empty())
|
|
self.assertTrue(ready_queue.empty())
|
|
|
|
|
|
def test_receieve_message_not_registered(self):
|
|
def test_receieve_message_not_registered(self):
|
|
- l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
|
|
|
|
+ l = _MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
|
|
+ l.steps.pop()
|
|
backend = Mock()
|
|
backend = Mock()
|
|
m = create_message(backend, task='x.X.31x', args=[2, 4, 8], kwargs={})
|
|
m = create_message(backend, task='x.X.31x', args=[2, 4, 8], kwargs={})
|
|
|
|
|
|
l.event_dispatcher = Mock()
|
|
l.event_dispatcher = Mock()
|
|
- self.assertFalse(l.receive_message(m.decode(), m))
|
|
|
|
|
|
+ callback = self._get_on_message(l)
|
|
|
|
+ self.assertFalse(callback(m.decode(), m))
|
|
with self.assertRaises(Empty):
|
|
with self.assertRaises(Empty):
|
|
self.ready_queue.get_nowait()
|
|
self.ready_queue.get_nowait()
|
|
self.assertTrue(self.timer.empty())
|
|
self.assertTrue(self.timer.empty())
|
|
@@ -534,7 +583,7 @@ class test_Consumer(Case):
|
|
@patch('celery.worker.consumer.warn')
|
|
@patch('celery.worker.consumer.warn')
|
|
@patch('celery.worker.consumer.logger')
|
|
@patch('celery.worker.consumer.logger')
|
|
def test_receieve_message_ack_raises(self, logger, warn):
|
|
def test_receieve_message_ack_raises(self, logger, warn):
|
|
- l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
|
|
|
|
+ l = Consumer(self.ready_queue, timer=self.timer)
|
|
backend = Mock()
|
|
backend = Mock()
|
|
m = create_message(backend, args=[2, 4, 8], kwargs={})
|
|
m = create_message(backend, args=[2, 4, 8], kwargs={})
|
|
|
|
|
|
@@ -542,7 +591,8 @@ class test_Consumer(Case):
|
|
l.connection_errors = (socket.error, )
|
|
l.connection_errors = (socket.error, )
|
|
m.reject = Mock()
|
|
m.reject = Mock()
|
|
m.reject.side_effect = socket.error('foo')
|
|
m.reject.side_effect = socket.error('foo')
|
|
- self.assertFalse(l.receive_message(m.decode(), m))
|
|
|
|
|
|
+ callback = self._get_on_message(l)
|
|
|
|
+ self.assertFalse(callback(m.decode(), m))
|
|
self.assertTrue(warn.call_count)
|
|
self.assertTrue(warn.call_count)
|
|
with self.assertRaises(Empty):
|
|
with self.assertRaises(Empty):
|
|
self.ready_queue.get_nowait()
|
|
self.ready_queue.get_nowait()
|
|
@@ -551,7 +601,8 @@ class test_Consumer(Case):
|
|
self.assertTrue(logger.critical.call_count)
|
|
self.assertTrue(logger.critical.call_count)
|
|
|
|
|
|
def test_receieve_message_eta(self):
|
|
def test_receieve_message_eta(self):
|
|
- l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
|
|
|
|
+ l = _MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
|
|
+ l.steps.pop()
|
|
l.event_dispatcher = Mock()
|
|
l.event_dispatcher = Mock()
|
|
l.event_dispatcher._outbound_buffer = deque()
|
|
l.event_dispatcher._outbound_buffer = deque()
|
|
backend = Mock()
|
|
backend = Mock()
|
|
@@ -560,16 +611,17 @@ class test_Consumer(Case):
|
|
eta=(datetime.now() +
|
|
eta=(datetime.now() +
|
|
timedelta(days=1)).isoformat())
|
|
timedelta(days=1)).isoformat())
|
|
|
|
|
|
- l.reset_connection()
|
|
|
|
|
|
+ l.namespace.start(l)
|
|
p = l.app.conf.BROKER_CONNECTION_RETRY
|
|
p = l.app.conf.BROKER_CONNECTION_RETRY
|
|
l.app.conf.BROKER_CONNECTION_RETRY = False
|
|
l.app.conf.BROKER_CONNECTION_RETRY = False
|
|
try:
|
|
try:
|
|
- l.reset_connection()
|
|
|
|
|
|
+ l.namespace.start(l)
|
|
finally:
|
|
finally:
|
|
l.app.conf.BROKER_CONNECTION_RETRY = p
|
|
l.app.conf.BROKER_CONNECTION_RETRY = p
|
|
- l.stop_consumers()
|
|
|
|
|
|
+ l.namespace.restart(l)
|
|
l.event_dispatcher = Mock()
|
|
l.event_dispatcher = Mock()
|
|
- l.receive_message(m.decode(), m)
|
|
|
|
|
|
+ callback = self._get_on_message(l)
|
|
|
|
+ callback(m.decode(), m)
|
|
l.timer.stop()
|
|
l.timer.stop()
|
|
in_hold = l.timer.queue[0]
|
|
in_hold = l.timer.queue[0]
|
|
self.assertEqual(len(in_hold), 3)
|
|
self.assertEqual(len(in_hold), 3)
|
|
@@ -583,24 +635,34 @@ class test_Consumer(Case):
|
|
|
|
|
|
def test_reset_pidbox_node(self):
|
|
def test_reset_pidbox_node(self):
|
|
l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
- l.pidbox_node = Mock()
|
|
|
|
- chan = l.pidbox_node.channel = Mock()
|
|
|
|
|
|
+ con = find_step(l, consumer.Control).box
|
|
|
|
+ con.node = Mock()
|
|
|
|
+ chan = con.node.channel = Mock()
|
|
l.connection = Mock()
|
|
l.connection = Mock()
|
|
chan.close.side_effect = socket.error('foo')
|
|
chan.close.side_effect = socket.error('foo')
|
|
l.connection_errors = (socket.error, )
|
|
l.connection_errors = (socket.error, )
|
|
- l.reset_pidbox_node()
|
|
|
|
|
|
+ con.reset()
|
|
chan.close.assert_called_with()
|
|
chan.close.assert_called_with()
|
|
|
|
|
|
def test_reset_pidbox_node_green(self):
|
|
def test_reset_pidbox_node_green(self):
|
|
- l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
|
|
- l.pool = Mock()
|
|
|
|
- l.pool.is_green = True
|
|
|
|
- l.reset_pidbox_node()
|
|
|
|
- l.pool.spawn_n.assert_called_with(l._green_pidbox_node)
|
|
|
|
|
|
+ from celery.worker.pidbox import gPidbox
|
|
|
|
+ pool = Mock()
|
|
|
|
+ pool.is_green = True
|
|
|
|
+ l = MyKombuConsumer(self.ready_queue, timer=self.timer, pool=pool)
|
|
|
|
+ con = find_step(l, consumer.Control)
|
|
|
|
+ self.assertIsInstance(con.box, gPidbox)
|
|
|
|
+ con.start(l)
|
|
|
|
+ l.pool.spawn_n.assert_called_with(
|
|
|
|
+ con.box.loop, l,
|
|
|
|
+ )
|
|
|
|
|
|
def test__green_pidbox_node(self):
|
|
def test__green_pidbox_node(self):
|
|
- l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
|
|
- l.pidbox_node = Mock()
|
|
|
|
|
|
+ pool = Mock()
|
|
|
|
+ pool.is_green = True
|
|
|
|
+ l = MyKombuConsumer(self.ready_queue, timer=self.timer, pool=pool)
|
|
|
|
+ l.node = Mock()
|
|
|
|
+ controller = find_step(l, consumer.Control)
|
|
|
|
+ box = controller.box
|
|
|
|
|
|
class BConsumer(Mock):
|
|
class BConsumer(Mock):
|
|
|
|
|
|
@@ -611,7 +673,7 @@ class test_Consumer(Case):
|
|
def __exit__(self, *exc_info):
|
|
def __exit__(self, *exc_info):
|
|
self.cancel()
|
|
self.cancel()
|
|
|
|
|
|
- l.pidbox_node.listen = BConsumer()
|
|
|
|
|
|
+ controller.box.node.listen = BConsumer()
|
|
connections = []
|
|
connections = []
|
|
|
|
|
|
class Connection(object):
|
|
class Connection(object):
|
|
@@ -640,25 +702,26 @@ class test_Consumer(Case):
|
|
self.calls += 1
|
|
self.calls += 1
|
|
raise socket.timeout()
|
|
raise socket.timeout()
|
|
self.obj.connection = None
|
|
self.obj.connection = None
|
|
- self.obj._pidbox_node_shutdown.set()
|
|
|
|
|
|
+ controller.box._node_shutdown.set()
|
|
|
|
|
|
def close(self):
|
|
def close(self):
|
|
self.closed = True
|
|
self.closed = True
|
|
|
|
|
|
l.connection = Mock()
|
|
l.connection = Mock()
|
|
- l._open_connection = lambda: Connection(obj=l)
|
|
|
|
- l._green_pidbox_node()
|
|
|
|
|
|
+ l.connect = lambda: Connection(obj=l)
|
|
|
|
+ controller = find_step(l, consumer.Control)
|
|
|
|
+ controller.box.loop(l)
|
|
|
|
|
|
- l.pidbox_node.listen.assert_called_with(callback=l.on_control)
|
|
|
|
- self.assertTrue(l.broadcast_consumer)
|
|
|
|
- l.broadcast_consumer.consume.assert_called_with()
|
|
|
|
|
|
+ self.assertTrue(controller.box.node.listen.called)
|
|
|
|
+ self.assertTrue(controller.box.consumer)
|
|
|
|
+ controller.box.consumer.consume.assert_called_with()
|
|
|
|
|
|
self.assertIsNone(l.connection)
|
|
self.assertIsNone(l.connection)
|
|
self.assertTrue(connections[0].closed)
|
|
self.assertTrue(connections[0].closed)
|
|
|
|
|
|
@patch('kombu.connection.Connection._establish_connection')
|
|
@patch('kombu.connection.Connection._establish_connection')
|
|
@patch('kombu.utils.sleep')
|
|
@patch('kombu.utils.sleep')
|
|
- def test_open_connection_errback(self, sleep, connect):
|
|
|
|
|
|
+ def test_connect_errback(self, sleep, connect):
|
|
l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
from kombu.transport.memory import Transport
|
|
from kombu.transport.memory import Transport
|
|
Transport.connection_errors = (StdChannelError, )
|
|
Transport.connection_errors = (StdChannelError, )
|
|
@@ -668,17 +731,18 @@ class test_Consumer(Case):
|
|
return
|
|
return
|
|
raise StdChannelError()
|
|
raise StdChannelError()
|
|
connect.side_effect = effect
|
|
connect.side_effect = effect
|
|
- l._open_connection()
|
|
|
|
|
|
+ l.connect()
|
|
connect.assert_called_with()
|
|
connect.assert_called_with()
|
|
|
|
|
|
def test_stop_pidbox_node(self):
|
|
def test_stop_pidbox_node(self):
|
|
l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
l = MyKombuConsumer(self.ready_queue, timer=self.timer)
|
|
- l._pidbox_node_stopped = Event()
|
|
|
|
- l._pidbox_node_shutdown = Event()
|
|
|
|
- l._pidbox_node_stopped.set()
|
|
|
|
- l.stop_pidbox_node()
|
|
|
|
|
|
+ cont = find_step(l, consumer.Control)
|
|
|
|
+ cont._node_stopped = Event()
|
|
|
|
+ cont._node_shutdown = Event()
|
|
|
|
+ cont._node_stopped.set()
|
|
|
|
+ cont.stop(l)
|
|
|
|
|
|
- def test_start__consume_messages(self):
|
|
|
|
|
|
+ def test_start__loop(self):
|
|
|
|
|
|
class _QoS(object):
|
|
class _QoS(object):
|
|
prev = 3
|
|
prev = 3
|
|
@@ -703,18 +767,17 @@ class test_Consumer(Case):
|
|
l.connection = Connection()
|
|
l.connection = Connection()
|
|
l.iterations = 0
|
|
l.iterations = 0
|
|
|
|
|
|
- def raises_KeyError(limit=None):
|
|
|
|
|
|
+ def raises_KeyError(*args, **kwargs):
|
|
l.iterations += 1
|
|
l.iterations += 1
|
|
if l.qos.prev != l.qos.value:
|
|
if l.qos.prev != l.qos.value:
|
|
l.qos.update()
|
|
l.qos.update()
|
|
if l.iterations >= 2:
|
|
if l.iterations >= 2:
|
|
raise KeyError('foo')
|
|
raise KeyError('foo')
|
|
|
|
|
|
- l.consume_messages = raises_KeyError
|
|
|
|
|
|
+ l.loop = raises_KeyError
|
|
with self.assertRaises(KeyError):
|
|
with self.assertRaises(KeyError):
|
|
l.start()
|
|
l.start()
|
|
- self.assertTrue(init_callback.call_count)
|
|
|
|
- self.assertEqual(l.iterations, 1)
|
|
|
|
|
|
+ self.assertEqual(l.iterations, 2)
|
|
self.assertEqual(l.qos.prev, l.qos.value)
|
|
self.assertEqual(l.qos.prev, l.qos.value)
|
|
|
|
|
|
init_callback.reset_mock()
|
|
init_callback.reset_mock()
|
|
@@ -724,25 +787,25 @@ class test_Consumer(Case):
|
|
l.task_consumer = Mock()
|
|
l.task_consumer = Mock()
|
|
l.broadcast_consumer = Mock()
|
|
l.broadcast_consumer = Mock()
|
|
l.connection = Connection()
|
|
l.connection = Connection()
|
|
- l.consume_messages = Mock(side_effect=socket.error('foo'))
|
|
|
|
|
|
+ l.loop = Mock(side_effect=socket.error('foo'))
|
|
with self.assertRaises(socket.error):
|
|
with self.assertRaises(socket.error):
|
|
l.start()
|
|
l.start()
|
|
- self.assertTrue(init_callback.call_count)
|
|
|
|
- self.assertTrue(l.consume_messages.call_count)
|
|
|
|
|
|
+ self.assertTrue(l.loop.call_count)
|
|
|
|
|
|
def test_reset_connection_with_no_node(self):
|
|
def test_reset_connection_with_no_node(self):
|
|
- l = BlockingConsumer(self.ready_queue, timer=self.timer)
|
|
|
|
|
|
+ l = Consumer(self.ready_queue, timer=self.timer)
|
|
|
|
+ l.steps.pop()
|
|
self.assertEqual(None, l.pool)
|
|
self.assertEqual(None, l.pool)
|
|
- l.reset_connection()
|
|
|
|
|
|
+ l.namespace.start(l)
|
|
|
|
|
|
def test_on_task_revoked(self):
|
|
def test_on_task_revoked(self):
|
|
- l = BlockingConsumer(self.ready_queue, timer=self.timer)
|
|
|
|
|
|
+ l = Consumer(self.ready_queue, timer=self.timer)
|
|
task = Mock()
|
|
task = Mock()
|
|
task.revoked.return_value = True
|
|
task.revoked.return_value = True
|
|
l.on_task(task)
|
|
l.on_task(task)
|
|
|
|
|
|
def test_on_task_no_events(self):
|
|
def test_on_task_no_events(self):
|
|
- l = BlockingConsumer(self.ready_queue, timer=self.timer)
|
|
|
|
|
|
+ l = Consumer(self.ready_queue, timer=self.timer)
|
|
task = Mock()
|
|
task = Mock()
|
|
task.revoked.return_value = False
|
|
task.revoked.return_value = False
|
|
l.event_dispatcher = Mock()
|
|
l.event_dispatcher = Mock()
|
|
@@ -778,7 +841,7 @@ class test_WorkController(AppCase):
|
|
def test_use_pidfile(self, create_pidlock):
|
|
def test_use_pidfile(self, create_pidlock):
|
|
create_pidlock.return_value = Mock()
|
|
create_pidlock.return_value = Mock()
|
|
worker = self.create_worker(pidfile='pidfilelockfilepid')
|
|
worker = self.create_worker(pidfile='pidfilelockfilepid')
|
|
- worker.components = []
|
|
|
|
|
|
+ worker.steps = []
|
|
worker.start()
|
|
worker.start()
|
|
self.assertTrue(create_pidlock.called)
|
|
self.assertTrue(create_pidlock.called)
|
|
worker.stop()
|
|
worker.stop()
|
|
@@ -825,12 +888,12 @@ class test_WorkController(AppCase):
|
|
self.assertTrue(worker.pool)
|
|
self.assertTrue(worker.pool)
|
|
self.assertTrue(worker.consumer)
|
|
self.assertTrue(worker.consumer)
|
|
self.assertTrue(worker.mediator)
|
|
self.assertTrue(worker.mediator)
|
|
- self.assertTrue(worker.components)
|
|
|
|
|
|
+ self.assertTrue(worker.steps)
|
|
|
|
|
|
def test_with_embedded_celerybeat(self):
|
|
def test_with_embedded_celerybeat(self):
|
|
worker = WorkController(concurrency=1, loglevel=0, beat=True)
|
|
worker = WorkController(concurrency=1, loglevel=0, beat=True)
|
|
self.assertTrue(worker.beat)
|
|
self.assertTrue(worker.beat)
|
|
- self.assertIn(worker.beat, [w.obj for w in worker.components])
|
|
|
|
|
|
+ self.assertIn(worker.beat, [w.obj for w in worker.steps])
|
|
|
|
|
|
def test_with_autoscaler(self):
|
|
def test_with_autoscaler(self):
|
|
worker = self.create_worker(autoscale=[10, 3], send_events=False,
|
|
worker = self.create_worker(autoscale=[10, 3], send_events=False,
|
|
@@ -892,7 +955,7 @@ class test_WorkController(AppCase):
|
|
m = create_message(backend, task=foo_task.name, args=[4, 8, 10],
|
|
m = create_message(backend, task=foo_task.name, args=[4, 8, 10],
|
|
kwargs={})
|
|
kwargs={})
|
|
task = Request.from_message(m, m.decode())
|
|
task = Request.from_message(m, m.decode())
|
|
- worker.components = []
|
|
|
|
|
|
+ worker.steps = []
|
|
worker.namespace.state = RUN
|
|
worker.namespace.state = RUN
|
|
with self.assertRaises(KeyboardInterrupt):
|
|
with self.assertRaises(KeyboardInterrupt):
|
|
worker.process_task(task)
|
|
worker.process_task(task)
|
|
@@ -906,7 +969,7 @@ class test_WorkController(AppCase):
|
|
m = create_message(backend, task=foo_task.name, args=[4, 8, 10],
|
|
m = create_message(backend, task=foo_task.name, args=[4, 8, 10],
|
|
kwargs={})
|
|
kwargs={})
|
|
task = Request.from_message(m, m.decode())
|
|
task = Request.from_message(m, m.decode())
|
|
- worker.components = []
|
|
|
|
|
|
+ worker.steps = []
|
|
worker.namespace.state = RUN
|
|
worker.namespace.state = RUN
|
|
with self.assertRaises(SystemExit):
|
|
with self.assertRaises(SystemExit):
|
|
worker.process_task(task)
|
|
worker.process_task(task)
|
|
@@ -925,17 +988,18 @@ class test_WorkController(AppCase):
|
|
|
|
|
|
def test_start_catches_base_exceptions(self):
|
|
def test_start_catches_base_exceptions(self):
|
|
worker1 = self.create_worker()
|
|
worker1 = self.create_worker()
|
|
- stc = Mock()
|
|
|
|
|
|
+ stc = MockStep()
|
|
stc.start.side_effect = SystemTerminate()
|
|
stc.start.side_effect = SystemTerminate()
|
|
- worker1.components = [stc]
|
|
|
|
|
|
+ worker1.steps = [stc]
|
|
worker1.start()
|
|
worker1.start()
|
|
|
|
+ stc.start.assert_called_with(worker1)
|
|
self.assertTrue(stc.terminate.call_count)
|
|
self.assertTrue(stc.terminate.call_count)
|
|
|
|
|
|
worker2 = self.create_worker()
|
|
worker2 = self.create_worker()
|
|
- sec = Mock()
|
|
|
|
|
|
+ sec = MockStep()
|
|
sec.start.side_effect = SystemExit()
|
|
sec.start.side_effect = SystemExit()
|
|
sec.terminate = None
|
|
sec.terminate = None
|
|
- worker2.components = [sec]
|
|
|
|
|
|
+ worker2.steps = [sec]
|
|
worker2.start()
|
|
worker2.start()
|
|
self.assertTrue(sec.stop.call_count)
|
|
self.assertTrue(sec.stop.call_count)
|
|
|
|
|
|
@@ -988,18 +1052,18 @@ class test_WorkController(AppCase):
|
|
def test_start__stop(self):
|
|
def test_start__stop(self):
|
|
worker = self.worker
|
|
worker = self.worker
|
|
worker.namespace.shutdown_complete.set()
|
|
worker.namespace.shutdown_complete.set()
|
|
- worker.components = [StartStopComponent(self) for _ in range(4)]
|
|
|
|
|
|
+ worker.steps = [MockStep(StartStopStep(self)) for _ in range(4)]
|
|
worker.namespace.state = RUN
|
|
worker.namespace.state = RUN
|
|
worker.namespace.started = 4
|
|
worker.namespace.started = 4
|
|
- for w in worker.components:
|
|
|
|
|
|
+ for w in worker.steps:
|
|
w.start = Mock()
|
|
w.start = Mock()
|
|
w.stop = Mock()
|
|
w.stop = Mock()
|
|
|
|
|
|
worker.start()
|
|
worker.start()
|
|
- for w in worker.components:
|
|
|
|
|
|
+ for w in worker.steps:
|
|
self.assertTrue(w.start.call_count)
|
|
self.assertTrue(w.start.call_count)
|
|
worker.stop()
|
|
worker.stop()
|
|
- for w in worker.components:
|
|
|
|
|
|
+ for w in worker.steps:
|
|
self.assertTrue(w.stop.call_count)
|
|
self.assertTrue(w.stop.call_count)
|
|
|
|
|
|
# Doesn't close pool if no pool.
|
|
# Doesn't close pool if no pool.
|
|
@@ -1008,15 +1072,15 @@ class test_WorkController(AppCase):
|
|
worker.stop()
|
|
worker.stop()
|
|
|
|
|
|
# test that stop of None is not attempted
|
|
# test that stop of None is not attempted
|
|
- worker.components[-1] = None
|
|
|
|
|
|
+ worker.steps[-1] = None
|
|
worker.start()
|
|
worker.start()
|
|
worker.stop()
|
|
worker.stop()
|
|
|
|
|
|
- def test_component_raises(self):
|
|
|
|
|
|
+ def test_step_raises(self):
|
|
worker = self.worker
|
|
worker = self.worker
|
|
- comp = Mock()
|
|
|
|
- worker.components = [comp]
|
|
|
|
- comp.start.side_effect = TypeError()
|
|
|
|
|
|
+ step = Mock()
|
|
|
|
+ worker.steps = [step]
|
|
|
|
+ step.start.side_effect = TypeError()
|
|
worker.stop = Mock()
|
|
worker.stop = Mock()
|
|
worker.start()
|
|
worker.start()
|
|
worker.stop.assert_called_with()
|
|
worker.stop.assert_called_with()
|
|
@@ -1029,16 +1093,15 @@ class test_WorkController(AppCase):
|
|
worker.namespace.shutdown_complete.set()
|
|
worker.namespace.shutdown_complete.set()
|
|
worker.namespace.started = 5
|
|
worker.namespace.started = 5
|
|
worker.namespace.state = RUN
|
|
worker.namespace.state = RUN
|
|
- worker.components = [Mock(), Mock(), Mock(), Mock(), Mock()]
|
|
|
|
-
|
|
|
|
|
|
+ worker.steps = [MockStep() for _ in range(5)]
|
|
worker.start()
|
|
worker.start()
|
|
- for w in worker.components[:3]:
|
|
|
|
|
|
+ for w in worker.steps[:3]:
|
|
self.assertTrue(w.start.call_count)
|
|
self.assertTrue(w.start.call_count)
|
|
- self.assertTrue(worker.namespace.started, len(worker.components))
|
|
|
|
|
|
+ self.assertTrue(worker.namespace.started, len(worker.steps))
|
|
self.assertEqual(worker.namespace.state, RUN)
|
|
self.assertEqual(worker.namespace.state, RUN)
|
|
worker.terminate()
|
|
worker.terminate()
|
|
- for component in worker.components:
|
|
|
|
- self.assertTrue(component.terminate.call_count)
|
|
|
|
|
|
+ for step in worker.steps:
|
|
|
|
+ self.assertTrue(step.terminate.call_count)
|
|
|
|
|
|
def test_Queues_pool_not_rlimit_safe(self):
|
|
def test_Queues_pool_not_rlimit_safe(self):
|
|
w = Mock()
|
|
w = Mock()
|
|
@@ -1052,9 +1115,9 @@ class test_WorkController(AppCase):
|
|
Queues(w).create(w)
|
|
Queues(w).create(w)
|
|
self.assertIs(w.ready_queue.put, w.process_task)
|
|
self.assertIs(w.ready_queue.put, w.process_task)
|
|
|
|
|
|
- def test_EvLoop_crate(self):
|
|
|
|
|
|
+ def test_Hub_crate(self):
|
|
w = Mock()
|
|
w = Mock()
|
|
- x = EvLoop(w)
|
|
|
|
|
|
+ x = Hub(w)
|
|
hub = x.create(w)
|
|
hub = x.create(w)
|
|
self.assertTrue(w.timer.max_interval)
|
|
self.assertTrue(w.timer.max_interval)
|
|
self.assertIs(w.hub, hub)
|
|
self.assertIs(w.hub, hub)
|