Пример #1
0
    def __init__(
        self,
        event_dispatcher,
        logger=None,
        start_on_init=False,
        event_queue=None,
        batch_size=None,
        flush_interval=None,
        timeout_interval=None,
        notification_center=None,
    ):
        """ BatchEventProcessor init method to configure event batching.

    Args:
      event_dispatcher: Provides a dispatch_event method which if given a URL and params sends a request to it.
      logger: Optional component which provides a log method to log messages. By default nothing would be logged.
      start_on_init: Optional boolean param which starts the consumer thread if set to True.
                     Default value is False.
      event_queue: Optional component which accumulates the events until dispacthed.
      batch_size: Optional param which defines the upper limit on the number of events in event_queue after which
                  the event_queue will be flushed.
      flush_interval: Optional floating point number representing time interval in seconds after which event_queue will
                      be flushed.
      timeout_interval: Optional floating point number representing time interval in seconds before joining the consumer
                        thread.
      notification_center: Optional instance of notification_center.NotificationCenter.
    """
        self.event_dispatcher = event_dispatcher or default_event_dispatcher
        self.logger = _logging.adapt_logger(logger or _logging.NoOpLogger())
        self.event_queue = event_queue or queue.Queue(
            maxsize=self._DEFAULT_QUEUE_CAPACITY)
        self.batch_size = (batch_size if self._validate_instantiation_props(
            batch_size, 'batch_size', self._DEFAULT_BATCH_SIZE) else
                           self._DEFAULT_BATCH_SIZE)
        self.flush_interval = (timedelta(
            seconds=flush_interval) if self._validate_instantiation_props(
                flush_interval, 'flush_interval', self._DEFAULT_FLUSH_INTERVAL)
                               else timedelta(
                                   seconds=self._DEFAULT_FLUSH_INTERVAL))
        self.timeout_interval = (timedelta(
            seconds=timeout_interval) if self._validate_instantiation_props(
                timeout_interval, 'timeout_interval',
                self._DEFAULT_TIMEOUT_INTERVAL) else timedelta(
                    seconds=self._DEFAULT_TIMEOUT_INTERVAL))

        self.notification_center = notification_center or _notification_center.NotificationCenter(
            self.logger)
        self._current_batch = list()

        if not validator.is_notification_center_valid(
                self.notification_center):
            self.logger.error(
                enums.Errors.INVALID_INPUT.format('notification_center'))
            self.logger.debug('Creating notification center for use.')
            self.notification_center = _notification_center.NotificationCenter(
                self.logger)

        self.executor = None
        if start_on_init is True:
            self.start()
Пример #2
0
    def __init__(self, event_dispatcher, logger=None, notification_center=None):
        """ ForwardingEventProcessor init method to configure event dispatching.

    Args:
      event_dispatcher: Provides a dispatch_event method which if given a URL and params sends a request to it.
      logger: Optional component which provides a log method to log messages. By default nothing would be logged.
      notification_center: Optional instance of notification_center.NotificationCenter.
    """
        self.event_dispatcher = event_dispatcher or default_event_dispatcher
        self.logger = _logging.adapt_logger(logger or _logging.NoOpLogger())
        self.notification_center = notification_center or _notification_center.NotificationCenter(self.logger)

        if not validator.is_notification_center_valid(self.notification_center):
            self.logger.error(enums.Errors.INVALID_INPUT.format('notification_center'))
            self.notification_center = _notification_center.NotificationCenter()
Пример #3
0
    def test_add_notification_listener__valid_type(self):
        """ Test successfully adding a notification listener. """

        test_notification_center = notification_center.NotificationCenter()

        # Test by adding different supported notification listeners.
        self.assertEqual(
            1,
            test_notification_center.add_notification_listener(
                enums.NotificationTypes.ACTIVATE, on_activate_listener),
        )
        self.assertEqual(
            2,
            test_notification_center.add_notification_listener(
                enums.NotificationTypes.OPTIMIZELY_CONFIG_UPDATE,
                on_config_update_listener,
            ),
        )
        self.assertEqual(
            3,
            test_notification_center.add_notification_listener(
                enums.NotificationTypes.DECISION, on_decision_listener),
        )
        self.assertEqual(
            4,
            test_notification_center.add_notification_listener(
                enums.NotificationTypes.TRACK, on_track_listener),
        )

        self.assertEqual(
            5,
            test_notification_center.add_notification_listener(
                enums.NotificationTypes.LOG_EVENT, on_log_event_listener),
        )
Пример #4
0
    def test_clear_all_notification_listeners(self):
        """ Test that all notification listeners are cleared on using the clear all API. """

        test_notification_center = notification_center.NotificationCenter()

        # Add listeners
        test_notification_center.add_notification_listener(
            enums.NotificationTypes.ACTIVATE, on_activate_listener)
        test_notification_center.add_notification_listener(
            enums.NotificationTypes.OPTIMIZELY_CONFIG_UPDATE,
            on_config_update_listener)
        test_notification_center.add_notification_listener(
            enums.NotificationTypes.DECISION, on_decision_listener)
        test_notification_center.add_notification_listener(
            enums.NotificationTypes.TRACK, on_track_listener)
        test_notification_center.add_notification_listener(
            enums.NotificationTypes.LOG_EVENT, on_log_event_listener)

        # Assert all listeners are there:
        for notification_type in notification_center.NOTIFICATION_TYPES:
            self.assertEqual(
                1,
                len(test_notification_center.
                    notification_listeners[notification_type]),
            )

        # Clear all and assert again.
        test_notification_center.clear_all_notification_listeners()

        for notification_type in notification_center.NOTIFICATION_TYPES:
            self.assertEqual(
                0,
                len(test_notification_center.
                    notification_listeners[notification_type]),
            )
Пример #5
0
    def test_remove_notification_listener__invalid_listener(self):
        """ Test that removing a invalid notification listener returns False. """
        def another_on_activate_listener(*args):
            pass

        test_notification_center = notification_center.NotificationCenter()

        # Add multiple notification listeners.
        self.assertEqual(
            1,
            test_notification_center.add_notification_listener(
                enums.NotificationTypes.ACTIVATE, on_activate_listener),
        )
        self.assertEqual(
            2,
            test_notification_center.add_notification_listener(
                enums.NotificationTypes.DECISION, on_decision_listener),
        )
        self.assertEqual(
            3,
            test_notification_center.add_notification_listener(
                enums.NotificationTypes.ACTIVATE,
                another_on_activate_listener),
        )
        self.assertEqual(
            4,
            test_notification_center.add_notification_listener(
                enums.NotificationTypes.LOG_EVENT, on_log_event_listener),
        )

        # Try removing a listener which does not exist.
        self.assertFalse(
            test_notification_center.remove_notification_listener(42))
Пример #6
0
    def test_add_notification_listener__same_listener(self):
        """ Test that adding same listener again does nothing and returns -1. """

        mock_logger = mock.Mock()
        test_notification_center = notification_center.NotificationCenter(
            logger=mock_logger)

        self.assertEqual(
            1,
            test_notification_center.add_notification_listener(
                enums.NotificationTypes.TRACK, on_track_listener),
        )
        self.assertEqual(
            1,
            len(test_notification_center.notification_listeners[
                enums.NotificationTypes.TRACK]),
        )

        # Test that adding same listener again makes no difference.
        self.assertEqual(
            -1,
            test_notification_center.add_notification_listener(
                enums.NotificationTypes.TRACK, on_track_listener),
        )
        self.assertEqual(
            1,
            len(test_notification_center.notification_listeners[
                enums.NotificationTypes.TRACK]),
        )
        mock_logger.error.assert_called_once_with(
            'Listener has already been added. Not adding it again.')
    def test_clear_notification_listeners(self):
        """ Test that notification listeners of a certain type are cleared
            up on using the clear_notification_listeners API. """

        test_notification_center = notification_center.NotificationCenter()

        # Add listeners
        test_notification_center.add_notification_listener(
            enums.NotificationTypes.ACTIVATE, on_activate_listener)
        test_notification_center.add_notification_listener(
            enums.NotificationTypes.OPTIMIZELY_CONFIG_UPDATE,
            on_config_update_listener)
        test_notification_center.add_notification_listener(
            enums.NotificationTypes.DECISION, on_decision_listener)
        test_notification_center.add_notification_listener(
            enums.NotificationTypes.TRACK, on_track_listener)

        # Assert all listeners are there:
        for notification_type in notification_center.NOTIFICATION_TYPES:
            self.assertEqual(
                1,
                len(test_notification_center.
                    notification_listeners[notification_type]))

        # Clear all of type DECISION.
        test_notification_center.clear_notification_listeners(
            enums.NotificationTypes.DECISION)
        self.assertEqual(
            0,
            len(test_notification_center.notification_listeners[
                enums.NotificationTypes.DECISION]))
Пример #8
0
    def test_send_notifications(self):
        """ Test that send_notifications dispatches notification to the callback(s). """

        test_notification_center = notification_center.NotificationCenter()
        self.listener_called = False
        test_notification_center.add_notification_listener(
            enums.NotificationTypes.DECISION, self.set_listener_called_to_true)
        test_notification_center.send_notifications(
            enums.NotificationTypes.DECISION)
        self.assertTrue(self.listener_called)
Пример #9
0
    def test_send_notifications__invalid_notification_type(self):
        """ Test that send_notifications logs exception when notification_type is invalid. """

        mock_logger = mock.Mock()
        test_notification_center = notification_center.NotificationCenter(
            logger=mock_logger)
        test_notification_center.send_notifications(
            'invalid_notification_type')
        mock_logger.error.assert_called_once_with(
            'Invalid notification_type: invalid_notification_type provided. '
            'Not triggering any notification.')
Пример #10
0
    def test_remove_notification_listener__valid_listener(self):
        """ Test that removing a valid notification listener returns True. """
        def another_on_activate_listener(*args):
            pass

        test_notification_center = notification_center.NotificationCenter()

        # Add multiple notification listeners.
        self.assertEqual(
            1,
            test_notification_center.add_notification_listener(
                enums.NotificationTypes.ACTIVATE, on_activate_listener),
        )
        self.assertEqual(
            2,
            test_notification_center.add_notification_listener(
                enums.NotificationTypes.DECISION, on_decision_listener),
        )
        self.assertEqual(
            3,
            test_notification_center.add_notification_listener(
                enums.NotificationTypes.ACTIVATE,
                another_on_activate_listener),
        )

        self.assertEqual(
            2,
            len(test_notification_center.notification_listeners[
                enums.NotificationTypes.ACTIVATE]),
        )
        self.assertEqual(
            1,
            len(test_notification_center.notification_listeners[
                enums.NotificationTypes.DECISION]),
        )
        self.assertEqual(
            0,
            len(test_notification_center.notification_listeners[
                enums.NotificationTypes.TRACK]),
        )
        self.assertEqual(
            0,
            len(test_notification_center.notification_listeners[
                enums.NotificationTypes.LOG_EVENT]),
        )

        # Remove one of the activate listeners and assert.
        self.assertTrue(
            test_notification_center.remove_notification_listener(3))
        self.assertEqual(
            1,
            len(test_notification_center.notification_listeners[
                enums.NotificationTypes.ACTIVATE]),
        )
Пример #11
0
    def test_clear_notification_listeners__invalid_type(self):
        """ Test that clear_notification_listener logs error if provided notification type is invalid. """

        mock_logger = mock.Mock()
        test_notification_center = notification_center.NotificationCenter(
            logger=mock_logger)

        test_notification_center.clear_notification_listeners(
            'invalid_notification_type')
        mock_logger.error.assert_called_once_with(
            'Invalid notification_type: invalid_notification_type provided. '
            'Not removing any listener.')
    def test_add_notification_listener__invalid_type(self):
        """ Test that adding an invalid notification listener fails and returns -1. """

        mock_logger = mock.Mock()
        test_notification_center = notification_center.NotificationCenter(
            logger=mock_logger)

        def notif_listener(*args):
            pass

        self.assertEqual(
            -1,
            test_notification_center.add_notification_listener(
                'invalid_notification_type', notif_listener))
        mock_logger.error.assert_called_once_with(
            'Invalid notification_type: invalid_notification_type provided. '
            'Not adding listener.')
    def test_add_notification_listener__multiple_listeners(self):
        """ Test that multiple listeners of the same type can be successfully added. """
        def another_on_activate_listener(*args):
            pass

        test_notification_center = notification_center.NotificationCenter()

        # Test by adding multiple listeners of same type.
        self.assertEqual(
            1,
            test_notification_center.add_notification_listener(
                enums.NotificationTypes.ACTIVATE, on_activate_listener))
        self.assertEqual(
            2,
            test_notification_center.add_notification_listener(
                enums.NotificationTypes.ACTIVATE,
                another_on_activate_listener))
Пример #14
0
    def test_send_notifications__fails(self):
        """ Test that send_notifications logs exception when call back fails. """

        # Defining a listener here which expects 2 arguments.
        def some_listener(arg_1, arg_2):
            pass

        mock_logger = mock.Mock()
        test_notification_center = notification_center.NotificationCenter(
            logger=mock_logger)
        test_notification_center.add_notification_listener(
            enums.NotificationTypes.ACTIVATE, some_listener)

        # Not providing any of the 2 expected arguments during send.
        test_notification_center.send_notifications(
            enums.NotificationTypes.ACTIVATE)
        mock_logger.exception.assert_called_once_with(
            'Unknown problem when sending "{}" type notification.'.format(
                enums.NotificationTypes.ACTIVATE))