#337 Allow setting order of handlers.
Merged 3 months ago by jkaluza. Opened 3 months ago by jkaluza.
jkaluza/freshmaker errata-refactor  into  master

file modified
+3 -1

@@ -146,7 +146,9 @@ 

          log.debug('Received a message with an ID of "{0}" and of type "{1}"'

                    .format(getattr(msg, 'msg_id', None), type(msg).__name__))

  

-         for handler_class in load_classes(conf.handlers):

+         handlers = load_classes(conf.handlers)

+         handlers = sorted(handlers, key=lambda handler: getattr(handler, "order", 50))

+         for handler_class in handlers:

              handler = handler_class()

  

              if not handler.can_handle(msg):

@@ -119,6 +119,11 @@ 

      """

      __metaclass__ = abc.ABCMeta

  

+     # Defines the order of this handler when evaluating multiple handlers.

+     # The handlers with lower order are called as first. If two handlers

+     # have the same order value, they can be called in any random order.

+     order = 50

+ 

      def __init__(self):

          self._db_event_id = None

          self._db_artifact_build_id = None

@@ -40,6 +40,7 @@ 

      """

  

      name = 'UpdateDBOnAdvisoryChange'

+     order = 0

  

      def can_handle(self, event):

          if not isinstance(event, ErrataAdvisoryStateChangedEvent):

@@ -31,6 +31,7 @@ 

  

  class UpdateDBOnModuleBuild(BaseHandler):

      name = "UpdateDBOnModuleBuild"

+     order = 0

  

      def can_handle(self, event):

          if isinstance(event, MBSModuleStateChangeEvent):

file modified
+53

@@ -68,6 +68,59 @@ 

          event = consumer.incoming.get()

          self.assertEqual(event.msg_id, "ModuleBuilt handled")

  

+     @mock.patch("freshmaker.handlers.koji.RebuildImagesOnRPMBodhiUpdate.can_handle")

+     @mock.patch("freshmaker.handlers.internal.UpdateDBOnModuleBuild.order",

+                 new_callable=mock.PropertyMock)

+     @mock.patch("freshmaker.handlers.internal.UpdateDBOnModuleBuild.can_handle")

+     @mock.patch("freshmaker.consumer.get_global_consumer")

+     def test_consumer_handlers_order(self, global_consumer, handler1,

+                                      handler1_order, handler2):

+         """

+         Tests that consumer parses the message, forwards the event

+         to proper handler and is able to get the further work from

+         the handler.

+         """

+         consumer = self.create_consumer()

+         global_consumer.return_value = consumer

+ 

+         for reverse in [False, True]:

+             order_lst = []

+ 

+             def mocked_handler1(*args, **kwargs):

+                 order_lst.append(1)

+                 return False

+ 

+             def mocked_handler2(*args, **kwargs):

+                 order_lst.append(2)

+                 return False

+ 

+             handler1.side_effect = mocked_handler1

+             handler2.side_effect = mocked_handler2

+             handler1_order.return_value = 100 if reverse else 0

+ 

+             msg = self._module_state_change_msg()

+             consumer.consume(msg)

+             self.assertEqual(order_lst, [2, 1] if reverse else [1, 2])

+ 

+     @mock.patch("freshmaker.handlers.koji.RebuildImagesOnRPMBodhiUpdate.handle")

+     @mock.patch("freshmaker.handlers.koji.RebuildImagesOnRPMBodhiUpdate.can_handle")

+     @mock.patch("freshmaker.handlers.internal.UpdateDBOnModuleBuild.handle")

+     @mock.patch("freshmaker.handlers.internal.UpdateDBOnModuleBuild.can_handle")

+     @mock.patch("freshmaker.consumer.get_global_consumer")

+     def test_consumer_multiple_handlers_called(

+             self, global_consumer, handler1_can_handle, handler1, handler2_can_handle,

+             handler2):

+         consumer = self.create_consumer()

+         global_consumer.return_value = consumer

+ 

+         handler1_can_handle.return_value = True

+         handler2_can_handle.return_value = True

+         msg = self._module_state_change_msg()

+         consumer.consume(msg)

+ 

+         handler1.assert_called_once()

+         handler2.assert_called_once()

+ 

      @mock.patch("freshmaker.consumer.get_global_consumer")

      def test_consumer_subscribe_to_specified_topics(self, global_consumer):

          """

New "order" attribute defines the order of this handler when evaluating
multiple handlers. The handlers with lower order are called as first.
If two handlers have the same order value, they can be called in any
random order.

Also set the internal handlers updating the database to be run as first.

rebased onto 83fd8205876b1f1743deefdb3a7966730b64daee

3 months ago

rebased onto 445022d

3 months ago

Pull-Request has been merged by jkaluza

3 months ago