|  | @@ -1,17 +1,22 @@
 | 
											
												
													
														|  |  import socket
 |  |  import socket
 | 
											
												
													
														|  |  import unittest2 as unittest
 |  |  import unittest2 as unittest
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +from datetime import datetime, timedelta
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +from kombu import pidbox
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  from celery.utils.timer2 import Timer
 |  |  from celery.utils.timer2 import Timer
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  from celery.app import app_or_default
 |  |  from celery.app import app_or_default
 | 
											
												
													
														|  | 
 |  | +from celery.datastructures import AttributeDict
 | 
											
												
													
														|  |  from celery.decorators import task
 |  |  from celery.decorators import task
 | 
											
												
													
														|  |  from celery.registry import tasks
 |  |  from celery.registry import tasks
 | 
											
												
													
														|  |  from celery.task.builtins import PingTask
 |  |  from celery.task.builtins import PingTask
 | 
											
												
													
														|  |  from celery.utils import gen_unique_id
 |  |  from celery.utils import gen_unique_id
 | 
											
												
													
														|  | -from celery.worker import control
 |  | 
 | 
											
												
													
														|  |  from celery.worker.buckets import FastQueue
 |  |  from celery.worker.buckets import FastQueue
 | 
											
												
													
														|  |  from celery.worker.job import TaskRequest
 |  |  from celery.worker.job import TaskRequest
 | 
											
												
													
														|  |  from celery.worker.state import revoked
 |  |  from celery.worker.state import revoked
 | 
											
												
													
														|  | 
 |  | +from celery.worker.control.registry import Panel
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  hostname = socket.gethostname()
 |  |  hostname = socket.gethostname()
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -53,16 +58,23 @@ class Consumer(object):
 | 
											
												
													
														|  |  class test_ControlPanel(unittest.TestCase):
 |  |  class test_ControlPanel(unittest.TestCase):
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      def setUp(self):
 |  |      def setUp(self):
 | 
											
												
													
														|  | 
 |  | +        self.app = app_or_default()
 | 
											
												
													
														|  |          self.panel = self.create_panel(consumer=Consumer())
 |  |          self.panel = self.create_panel(consumer=Consumer())
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +    def create_state(self, **kwargs):
 | 
											
												
													
														|  | 
 |  | +        kwargs.setdefault("logger", self.app.log.get_default_logger())
 | 
											
												
													
														|  | 
 |  | +        return AttributeDict(kwargs)
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |      def create_panel(self, **kwargs):
 |  |      def create_panel(self, **kwargs):
 | 
											
												
													
														|  | -        return control.ControlDispatch(hostname=hostname, **kwargs)
 |  | 
 | 
											
												
													
														|  | 
 |  | +        return self.app.control.mailbox.Node(hostname=hostname,
 | 
											
												
													
														|  | 
 |  | +                                             state=self.create_state(**kwargs),
 | 
											
												
													
														|  | 
 |  | +                                             handlers=Panel.data)
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      def test_disable_events(self):
 |  |      def test_disable_events(self):
 | 
											
												
													
														|  |          consumer = Consumer()
 |  |          consumer = Consumer()
 | 
											
												
													
														|  |          panel = self.create_panel(consumer=consumer)
 |  |          panel = self.create_panel(consumer=consumer)
 | 
											
												
													
														|  |          consumer.event_dispatcher.enabled = True
 |  |          consumer.event_dispatcher.enabled = True
 | 
											
												
													
														|  | -        panel.execute("disable_events")
 |  | 
 | 
											
												
													
														|  | 
 |  | +        panel.handle("disable_events")
 | 
											
												
													
														|  |          self.assertEqual(consumer.event_dispatcher.enabled, False)
 |  |          self.assertEqual(consumer.event_dispatcher.enabled, False)
 | 
											
												
													
														|  |          self.assertIn("worker-offline", consumer.event_dispatcher.sent)
 |  |          self.assertIn("worker-offline", consumer.event_dispatcher.sent)
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -70,47 +82,49 @@ class test_ControlPanel(unittest.TestCase):
 | 
											
												
													
														|  |          consumer = Consumer()
 |  |          consumer = Consumer()
 | 
											
												
													
														|  |          panel = self.create_panel(consumer=consumer)
 |  |          panel = self.create_panel(consumer=consumer)
 | 
											
												
													
														|  |          consumer.event_dispatcher.enabled = False
 |  |          consumer.event_dispatcher.enabled = False
 | 
											
												
													
														|  | -        panel.execute("enable_events")
 |  | 
 | 
											
												
													
														|  | 
 |  | +        panel.handle("enable_events")
 | 
											
												
													
														|  |          self.assertEqual(consumer.event_dispatcher.enabled, True)
 |  |          self.assertEqual(consumer.event_dispatcher.enabled, True)
 | 
											
												
													
														|  |          self.assertIn("worker-online", consumer.event_dispatcher.sent)
 |  |          self.assertIn("worker-online", consumer.event_dispatcher.sent)
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      def test_dump_tasks(self):
 |  |      def test_dump_tasks(self):
 | 
											
												
													
														|  | -        info = "\n".join(self.panel.execute("dump_tasks"))
 |  | 
 | 
											
												
													
														|  | 
 |  | +        info = "\n".join(self.panel.handle("dump_tasks"))
 | 
											
												
													
														|  |          self.assertIn("mytask", info)
 |  |          self.assertIn("mytask", info)
 | 
											
												
													
														|  |          self.assertIn("rate_limit=200", info)
 |  |          self.assertIn("rate_limit=200", info)
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      def test_dump_schedule(self):
 |  |      def test_dump_schedule(self):
 | 
											
												
													
														|  |          consumer = Consumer()
 |  |          consumer = Consumer()
 | 
											
												
													
														|  |          panel = self.create_panel(consumer=consumer)
 |  |          panel = self.create_panel(consumer=consumer)
 | 
											
												
													
														|  | -        self.assertFalse(panel.execute("dump_schedule"))
 |  | 
 | 
											
												
													
														|  | -        import operator
 |  | 
 | 
											
												
													
														|  | -        consumer.eta_schedule.schedule.enter(100, operator.add, (2, 2))
 |  | 
 | 
											
												
													
														|  | -        self.assertTrue(panel.execute("dump_schedule"))
 |  | 
 | 
											
												
													
														|  | 
 |  | +        self.assertFalse(panel.handle("dump_schedule"))
 | 
											
												
													
														|  | 
 |  | +        r = TaskRequest("celery.ping", "CAFEBABE", (), {})
 | 
											
												
													
														|  | 
 |  | +        consumer.eta_schedule.schedule.enter(
 | 
											
												
													
														|  | 
 |  | +                consumer.eta_schedule.Entry(lambda x: x, (r, )),
 | 
											
												
													
														|  | 
 |  | +                    datetime.now() + timedelta(seconds=10))
 | 
											
												
													
														|  | 
 |  | +        self.assertTrue(panel.handle("dump_schedule"))
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      def test_dump_reserved(self):
 |  |      def test_dump_reserved(self):
 | 
											
												
													
														|  |          consumer = Consumer()
 |  |          consumer = Consumer()
 | 
											
												
													
														|  |          panel = self.create_panel(consumer=consumer)
 |  |          panel = self.create_panel(consumer=consumer)
 | 
											
												
													
														|  | -        response = panel.execute("dump_reserved", {"safe": True})
 |  | 
 | 
											
												
													
														|  | 
 |  | +        response = panel.handle("dump_reserved", {"safe": True})
 | 
											
												
													
														|  |          self.assertDictContainsSubset({"name": mytask.name,
 |  |          self.assertDictContainsSubset({"name": mytask.name,
 | 
											
												
													
														|  |                                         "args": (2, 2),
 |  |                                         "args": (2, 2),
 | 
											
												
													
														|  |                                         "kwargs": {},
 |  |                                         "kwargs": {},
 | 
											
												
													
														|  |                                         "hostname": socket.gethostname()},
 |  |                                         "hostname": socket.gethostname()},
 | 
											
												
													
														|  |                                         response[0])
 |  |                                         response[0])
 | 
											
												
													
														|  |          consumer.ready_queue = FastQueue()
 |  |          consumer.ready_queue = FastQueue()
 | 
											
												
													
														|  | -        self.assertFalse(panel.execute("dump_reserved"))
 |  | 
 | 
											
												
													
														|  | 
 |  | +        self.assertFalse(panel.handle("dump_reserved"))
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      def test_rate_limit_when_disabled(self):
 |  |      def test_rate_limit_when_disabled(self):
 | 
											
												
													
														|  |          app = app_or_default()
 |  |          app = app_or_default()
 | 
											
												
													
														|  |          app.conf.CELERY_DISABLE_RATE_LIMITS = True
 |  |          app.conf.CELERY_DISABLE_RATE_LIMITS = True
 | 
											
												
													
														|  |          try:
 |  |          try:
 | 
											
												
													
														|  | -            e = self.panel.execute("rate_limit", kwargs=dict(
 |  | 
 | 
											
												
													
														|  | 
 |  | +            e = self.panel.handle("rate_limit", arguments=dict(
 | 
											
												
													
														|  |                   task_name=mytask.name, rate_limit="100/m"))
 |  |                   task_name=mytask.name, rate_limit="100/m"))
 | 
											
												
													
														|  |              self.assertIn("rate limits disabled", e.get("error"))
 |  |              self.assertIn("rate limits disabled", e.get("error"))
 | 
											
												
													
														|  |          finally:
 |  |          finally:
 | 
											
												
													
														|  |              app.conf.CELERY_DISABLE_RATE_LIMITS = False
 |  |              app.conf.CELERY_DISABLE_RATE_LIMITS = False
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      def test_rate_limit_invalid_rate_limit_string(self):
 |  |      def test_rate_limit_invalid_rate_limit_string(self):
 | 
											
												
													
														|  | -        e = self.panel.execute("rate_limit", kwargs=dict(
 |  | 
 | 
											
												
													
														|  | 
 |  | +        e = self.panel.handle("rate_limit", arguments=dict(
 | 
											
												
													
														|  |              task_name="tasks.add", rate_limit="x1240301#%!"))
 |  |              task_name="tasks.add", rate_limit="x1240301#%!"))
 | 
											
												
													
														|  |          self.assertIn("Invalid rate limit string", e.get("error"))
 |  |          self.assertIn("Invalid rate limit string", e.get("error"))
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -133,66 +147,66 @@ class test_ControlPanel(unittest.TestCase):
 | 
											
												
													
														|  |          task = tasks[PingTask.name]
 |  |          task = tasks[PingTask.name]
 | 
											
												
													
														|  |          old_rate_limit = task.rate_limit
 |  |          old_rate_limit = task.rate_limit
 | 
											
												
													
														|  |          try:
 |  |          try:
 | 
											
												
													
														|  | -            panel.execute("rate_limit", kwargs=dict(task_name=task.name,
 |  | 
 | 
											
												
													
														|  | -                                                    rate_limit="100/m"))
 |  | 
 | 
											
												
													
														|  | 
 |  | +            panel.handle("rate_limit", arguments=dict(task_name=task.name,
 | 
											
												
													
														|  | 
 |  | +                                                      rate_limit="100/m"))
 | 
											
												
													
														|  |              self.assertEqual(task.rate_limit, "100/m")
 |  |              self.assertEqual(task.rate_limit, "100/m")
 | 
											
												
													
														|  |              self.assertTrue(consumer.ready_queue.fresh)
 |  |              self.assertTrue(consumer.ready_queue.fresh)
 | 
											
												
													
														|  |              consumer.ready_queue.fresh = False
 |  |              consumer.ready_queue.fresh = False
 | 
											
												
													
														|  | -            panel.execute("rate_limit", kwargs=dict(task_name=task.name,
 |  | 
 | 
											
												
													
														|  | -                                                    rate_limit=0))
 |  | 
 | 
											
												
													
														|  | 
 |  | +            panel.handle("rate_limit", arguments=dict(task_name=task.name,
 | 
											
												
													
														|  | 
 |  | +                                                      rate_limit=0))
 | 
											
												
													
														|  |              self.assertEqual(task.rate_limit, 0)
 |  |              self.assertEqual(task.rate_limit, 0)
 | 
											
												
													
														|  |              self.assertTrue(consumer.ready_queue.fresh)
 |  |              self.assertTrue(consumer.ready_queue.fresh)
 | 
											
												
													
														|  |          finally:
 |  |          finally:
 | 
											
												
													
														|  |              task.rate_limit = old_rate_limit
 |  |              task.rate_limit = old_rate_limit
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      def test_rate_limit_nonexistant_task(self):
 |  |      def test_rate_limit_nonexistant_task(self):
 | 
											
												
													
														|  | -        self.panel.execute("rate_limit", kwargs={
 |  | 
 | 
											
												
													
														|  | 
 |  | +        self.panel.handle("rate_limit", arguments={
 | 
											
												
													
														|  |                                  "task_name": "xxxx.does.not.exist",
 |  |                                  "task_name": "xxxx.does.not.exist",
 | 
											
												
													
														|  |                                  "rate_limit": "1000/s"})
 |  |                                  "rate_limit": "1000/s"})
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      def test_unexposed_command(self):
 |  |      def test_unexposed_command(self):
 | 
											
												
													
														|  | -        self.panel.execute("foo", kwargs={})
 |  | 
 | 
											
												
													
														|  | 
 |  | +        self.assertRaises(KeyError, self.panel.handle, "foo", arguments={})
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      def test_revoke_with_name(self):
 |  |      def test_revoke_with_name(self):
 | 
											
												
													
														|  |          uuid = gen_unique_id()
 |  |          uuid = gen_unique_id()
 | 
											
												
													
														|  | -        m = {"command": "revoke",
 |  | 
 | 
											
												
													
														|  | 
 |  | +        m = {"method": "revoke",
 | 
											
												
													
														|  |               "destination": hostname,
 |  |               "destination": hostname,
 | 
											
												
													
														|  | -             "task_id": uuid,
 |  | 
 | 
											
												
													
														|  | -             "task_name": mytask.name}
 |  | 
 | 
											
												
													
														|  | 
 |  | +             "arguments": {"task_id": uuid,
 | 
											
												
													
														|  | 
 |  | +                           "task_name": mytask.name}}
 | 
											
												
													
														|  |          self.panel.dispatch_from_message(m)
 |  |          self.panel.dispatch_from_message(m)
 | 
											
												
													
														|  |          self.assertIn(uuid, revoked)
 |  |          self.assertIn(uuid, revoked)
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      def test_revoke_with_name_not_in_registry(self):
 |  |      def test_revoke_with_name_not_in_registry(self):
 | 
											
												
													
														|  |          uuid = gen_unique_id()
 |  |          uuid = gen_unique_id()
 | 
											
												
													
														|  | -        m = {"command": "revoke",
 |  | 
 | 
											
												
													
														|  | 
 |  | +        m = {"method": "revoke",
 | 
											
												
													
														|  |               "destination": hostname,
 |  |               "destination": hostname,
 | 
											
												
													
														|  | -             "task_id": uuid,
 |  | 
 | 
											
												
													
														|  | -             "task_name": "xxxxxxxxx33333333388888"}
 |  | 
 | 
											
												
													
														|  | 
 |  | +             "arguments": {"task_id": uuid,
 | 
											
												
													
														|  | 
 |  | +                           "task_name": "xxxxxxxxx33333333388888"}}
 | 
											
												
													
														|  |          self.panel.dispatch_from_message(m)
 |  |          self.panel.dispatch_from_message(m)
 | 
											
												
													
														|  |          self.assertIn(uuid, revoked)
 |  |          self.assertIn(uuid, revoked)
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      def test_revoke(self):
 |  |      def test_revoke(self):
 | 
											
												
													
														|  |          uuid = gen_unique_id()
 |  |          uuid = gen_unique_id()
 | 
											
												
													
														|  | -        m = {"command": "revoke",
 |  | 
 | 
											
												
													
														|  | 
 |  | +        m = {"method": "revoke",
 | 
											
												
													
														|  |               "destination": hostname,
 |  |               "destination": hostname,
 | 
											
												
													
														|  | -             "task_id": uuid}
 |  | 
 | 
											
												
													
														|  | 
 |  | +             "arguments": {"task_id": uuid}}
 | 
											
												
													
														|  |          self.panel.dispatch_from_message(m)
 |  |          self.panel.dispatch_from_message(m)
 | 
											
												
													
														|  |          self.assertIn(uuid, revoked)
 |  |          self.assertIn(uuid, revoked)
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -        m = {"command": "revoke",
 |  | 
 | 
											
												
													
														|  | 
 |  | +        m = {"method": "revoke",
 | 
											
												
													
														|  |               "destination": "does.not.exist",
 |  |               "destination": "does.not.exist",
 | 
											
												
													
														|  | -             "task_id": uuid + "xxx"}
 |  | 
 | 
											
												
													
														|  | 
 |  | +             "arguments": {"task_id": uuid + "xxx"}}
 | 
											
												
													
														|  |          self.panel.dispatch_from_message(m)
 |  |          self.panel.dispatch_from_message(m)
 | 
											
												
													
														|  |          self.assertNotIn(uuid + "xxx", revoked)
 |  |          self.assertNotIn(uuid + "xxx", revoked)
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      def test_ping(self):
 |  |      def test_ping(self):
 | 
											
												
													
														|  | -        m = {"command": "ping",
 |  | 
 | 
											
												
													
														|  | 
 |  | +        m = {"method": "ping",
 | 
											
												
													
														|  |               "destination": hostname}
 |  |               "destination": hostname}
 | 
											
												
													
														|  |          r = self.panel.dispatch_from_message(m)
 |  |          r = self.panel.dispatch_from_message(m)
 | 
											
												
													
														|  |          self.assertEqual(r, "pong")
 |  |          self.assertEqual(r, "pong")
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      def test_shutdown(self):
 |  |      def test_shutdown(self):
 | 
											
												
													
														|  | -        m = {"command": "shutdown",
 |  | 
 | 
											
												
													
														|  | 
 |  | +        m = {"method": "shutdown",
 | 
											
												
													
														|  |               "destination": hostname}
 |  |               "destination": hostname}
 | 
											
												
													
														|  |          self.assertRaises(SystemExit, self.panel.dispatch_from_message, m)
 |  |          self.assertRaises(SystemExit, self.panel.dispatch_from_message, m)
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -200,14 +214,16 @@ class test_ControlPanel(unittest.TestCase):
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |          replies = []
 |  |          replies = []
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -        class _Dispatch(control.ControlDispatch):
 |  | 
 | 
											
												
													
														|  | 
 |  | +        class _Node(pidbox.Node):
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |              def reply(self, data, exchange, routing_key, **kwargs):
 |  |              def reply(self, data, exchange, routing_key, **kwargs):
 | 
											
												
													
														|  |                  replies.append(data)
 |  |                  replies.append(data)
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -        panel = _Dispatch(hostname, consumer=Consumer())
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -        r = panel.execute("ping", reply_to={"exchange": "x",
 |  | 
 | 
											
												
													
														|  | -                                            "routing_key": "x"})
 |  | 
 | 
											
												
													
														|  | 
 |  | +        panel = _Node(hostname=hostname,
 | 
											
												
													
														|  | 
 |  | +                      state=self.create_state(consumer=Consumer()),
 | 
											
												
													
														|  | 
 |  | +                      handlers=Panel.data,
 | 
											
												
													
														|  | 
 |  | +                      mailbox=self.app.control.mailbox)
 | 
											
												
													
														|  | 
 |  | +        r = panel.dispatch("ping", reply_to={"exchange": "x",
 | 
											
												
													
														|  | 
 |  | +                                             "routing_key": "x"})
 | 
											
												
													
														|  |          self.assertEqual(r, "pong")
 |  |          self.assertEqual(r, "pong")
 | 
											
												
													
														|  |          self.assertDictEqual(replies[0], {panel.hostname: "pong"})
 |  |          self.assertDictEqual(replies[0], {panel.hostname: "pong"})
 |