def setUp(self):
        """Set up."""
        super(TestEventNotifier, self).setUp()
        self.tx_manager = ThreadTransactionManager()
        self.notifier = EventNotifier(tx_manager=self.tx_manager)
        self.patch(notifier, 'get_notifier', lambda: self.notifier)

        self.notifications = []
        self.patch(self.notifier, 'on_event',
                   lambda event: self.notifications.append(event))
    def setUp(self):
        """Set up."""
        super(TestEventNotifier, self).setUp()
        self.tx_manager = ThreadTransactionManager()
        self.notifier = EventNotifier(tx_manager=self.tx_manager)
        self.patch(notifier, 'get_notifier', lambda: self.notifier)

        self.notifications = []
        self.patch(self.notifier, 'on_event',
                   lambda event: self.notifications.append(event))
class TestEventNotifier(unittest.TestCase):
    """Test the EventNotifier class."""

    def patch(self, obj, attr_name, new_val):
        """Patch!"""
        old_val = getattr(obj, attr_name)
        setattr(obj, attr_name, new_val)
        self.addCleanup(setattr, obj, attr_name, old_val)

    def setUp(self):
        """Set up."""
        super(TestEventNotifier, self).setUp()
        self.tx_manager = ThreadTransactionManager()
        self.notifier = EventNotifier(tx_manager=self.tx_manager)
        self.patch(notifier, 'get_notifier', lambda: self.notifier)

        self.notifications = []
        self.patch(self.notifier, 'on_event',
                   lambda event: self.notifications.append(event))

    def test_notify_properties(self):
        """Test getter and setter for notify handler."""
        handler = object()
        self.notifier.on_node_update = handler
        self.assert_(self.notifier.on_node_update is handler)

    def test_broadcast_share_created(self):
        """Test broadcast of an share creation."""
        share = FakeShare()
        self.notifier.queue_share_created(share)
        self.tx_manager.commit()
        self.assertEqual(self.notifications,
                         [ShareCreated(*share.event_args)])

    def test_broadcast_share_deleted(self):
        """Test broadcast of an share deletion."""
        share = FakeShare()
        self.notifier.queue_share_deleted(share)
        self.tx_manager.commit()
        self.assertEqual(self.notifications,
                         [ShareDeleted(*share.event_args)])

    def test_broadcast_share_accepted(self):
        """Test broadcast of an share accepted."""
        share = FakeShare()
        self.notifier.queue_share_accepted(share)
        self.tx_manager.commit()
        self.assertEqual(self.notifications,
                         [ShareAccepted(*share.event_args)])

    def test_broadcast_share_declined(self):
        """Test broadcast of an share declined."""
        share = FakeShare()
        self.notifier.queue_share_declined(share)
        self.tx_manager.commit()
        self.assertEqual(self.notifications,
                         [ShareDeclined(*share.event_args)])

    def test_broadcast_udf_create(self):
        """Test broadcast of an udf creation."""
        udf_id = uuid.uuid4()
        root_id = uuid.uuid4()
        suggested_path = u"foo"
        self.notifier.queue_udf_create(0, udf_id, root_id, suggested_path)
        self.tx_manager.commit()
        self.assertEqual(self.notifications,
                         [UDFCreate(0, udf_id, root_id, suggested_path, None)])

    def test_broadcast_udf_delete(self):
        """Test broadcast of an udf creation."""
        udf_id = uuid.uuid4()
        self.notifier.queue_udf_delete(0, udf_id)
        self.tx_manager.commit()
        self.assertEqual(self.notifications,
                         [UDFDelete(0, udf_id, None)])

    def test_broadcast_vol_new_gen(self):
        """Test the broadcast of a new generation for the volume."""
        user_id = 1
        volume_id = uuid.uuid4()
        new_gen = 77
        self.notifier.queue_volume_new_generation(user_id, volume_id, new_gen)
        self.tx_manager.commit()
        self.assertEqual(self.notifications,
                         [VolumeNewGeneration(user_id, volume_id,
                                              new_gen, None)])

    def test_deliver_after_commit(self):
        """Test that notifications are delivered after committing."""
        source_session = uuid.uuid4()
        udf_a = uuid.uuid4()
        udf_b = uuid.uuid4()
        udf_c = uuid.uuid4()
        self.tx_manager.begin()
        self.notifier.queue_udf_delete(1, udf_a, source_session)
        self.notifier.queue_udf_delete(1, udf_b)
        self.assertEqual([], self.notifications)
        self.tx_manager.commit()

        # should have sent notifications after commit
        event_a = self.notifications[0]
        event_b = self.notifications[1]
        self.assertEqual(event_a.udf_id, udf_a)
        self.assertEqual(event_a.source_session, source_session)
        self.assertEqual(event_b.udf_id, udf_b)
        self.assertEqual(event_b.source_session, None)
        self.notifications[:] = []

        self.tx_manager.begin()
        self.notifier.queue_udf_delete(1, udf_c)
        self.assertEqual([], self.notifications)
        self.tx_manager.commit()
        # make sure we don't re-send from previous transactions
        event_c = self.notifications[0]
        self.assertEqual(event_c.udf_id, udf_c)
        self.assertEqual(event_c.source_session, None)

    def test_no_delivery_after_abort(self):
        """Test that notifs queued for an aborted transaction are not sent."""
        source_session = uuid.uuid4()
        udf_a = uuid.uuid4()
        udf_b = uuid.uuid4()
        udf_c = uuid.uuid4()

        self.tx_manager.begin()
        self.notifier.queue_udf_delete(1, udf_a, source_session)
        self.notifier.queue_udf_delete(1, udf_b)
        self.assertEqual([], self.notifications)
        self.tx_manager.abort()
        # should not send any notifications
        self.assertEqual([], self.notifications)

        self.tx_manager.begin()
        self.notifier.queue_udf_delete(1, udf_c)
        self.assertEqual([], self.notifications)
        self.tx_manager.commit()
        # make sure we don't re-send from previous transactions
        event_c = self.notifications[0]
        self.assertEqual(event_c.udf_id, udf_c)
        self.assertEqual(event_c.source_session, None)
class TestEventNotifier(unittest.TestCase):
    """Test the EventNotifier class."""
    def patch(self, obj, attr_name, new_val):
        """Patch!"""
        old_val = getattr(obj, attr_name)
        setattr(obj, attr_name, new_val)
        self.addCleanup(setattr, obj, attr_name, old_val)

    def setUp(self):
        """Set up."""
        super(TestEventNotifier, self).setUp()
        self.tx_manager = ThreadTransactionManager()
        self.notifier = EventNotifier(tx_manager=self.tx_manager)
        self.patch(notifier, 'get_notifier', lambda: self.notifier)

        self.notifications = []
        self.patch(self.notifier, 'on_event',
                   lambda event: self.notifications.append(event))

    def test_notify_properties(self):
        """Test getter and setter for notify handler."""
        handler = object()
        self.notifier.on_node_update = handler
        self.assert_(self.notifier.on_node_update is handler)

    def test_broadcast_share_created(self):
        """Test broadcast of an share creation."""
        share = FakeShare()
        self.notifier.queue_share_created(share)
        self.tx_manager.commit()
        self.assertEqual(self.notifications, [ShareCreated(*share.event_args)])

    def test_broadcast_share_deleted(self):
        """Test broadcast of an share deletion."""
        share = FakeShare()
        self.notifier.queue_share_deleted(share)
        self.tx_manager.commit()
        self.assertEqual(self.notifications, [ShareDeleted(*share.event_args)])

    def test_broadcast_share_accepted(self):
        """Test broadcast of an share accepted."""
        share = FakeShare()
        self.notifier.queue_share_accepted(share)
        self.tx_manager.commit()
        self.assertEqual(self.notifications,
                         [ShareAccepted(*share.event_args)])

    def test_broadcast_share_declined(self):
        """Test broadcast of an share declined."""
        share = FakeShare()
        self.notifier.queue_share_declined(share)
        self.tx_manager.commit()
        self.assertEqual(self.notifications,
                         [ShareDeclined(*share.event_args)])

    def test_broadcast_udf_create(self):
        """Test broadcast of an udf creation."""
        udf_id = uuid.uuid4()
        root_id = uuid.uuid4()
        suggested_path = u"foo"
        self.notifier.queue_udf_create(0, udf_id, root_id, suggested_path)
        self.tx_manager.commit()
        self.assertEqual(self.notifications,
                         [UDFCreate(0, udf_id, root_id, suggested_path, None)])

    def test_broadcast_udf_delete(self):
        """Test broadcast of an udf creation."""
        udf_id = uuid.uuid4()
        self.notifier.queue_udf_delete(0, udf_id)
        self.tx_manager.commit()
        self.assertEqual(self.notifications, [UDFDelete(0, udf_id, None)])

    def test_broadcast_vol_new_gen(self):
        """Test the broadcast of a new generation for the volume."""
        user_id = 1
        volume_id = uuid.uuid4()
        new_gen = 77
        self.notifier.queue_volume_new_generation(user_id, volume_id, new_gen)
        self.tx_manager.commit()
        self.assertEqual(
            self.notifications,
            [VolumeNewGeneration(user_id, volume_id, new_gen, None)])

    def test_deliver_after_commit(self):
        """Test that notifications are delivered after committing."""
        source_session = uuid.uuid4()
        udf_a = uuid.uuid4()
        udf_b = uuid.uuid4()
        udf_c = uuid.uuid4()
        self.tx_manager.begin()
        self.notifier.queue_udf_delete(1, udf_a, source_session)
        self.notifier.queue_udf_delete(1, udf_b)
        self.assertEqual([], self.notifications)
        self.tx_manager.commit()

        # should have sent notifications after commit
        event_a = self.notifications[0]
        event_b = self.notifications[1]
        self.assertEqual(event_a.udf_id, udf_a)
        self.assertEqual(event_a.source_session, source_session)
        self.assertEqual(event_b.udf_id, udf_b)
        self.assertEqual(event_b.source_session, None)
        self.notifications[:] = []

        self.tx_manager.begin()
        self.notifier.queue_udf_delete(1, udf_c)
        self.assertEqual([], self.notifications)
        self.tx_manager.commit()
        # make sure we don't re-send from previous transactions
        event_c = self.notifications[0]
        self.assertEqual(event_c.udf_id, udf_c)
        self.assertEqual(event_c.source_session, None)

    def test_no_delivery_after_abort(self):
        """Test that notifs queued for an aborted transaction are not sent."""
        source_session = uuid.uuid4()
        udf_a = uuid.uuid4()
        udf_b = uuid.uuid4()
        udf_c = uuid.uuid4()

        self.tx_manager.begin()
        self.notifier.queue_udf_delete(1, udf_a, source_session)
        self.notifier.queue_udf_delete(1, udf_b)
        self.assertEqual([], self.notifications)
        self.tx_manager.abort()
        # should not send any notifications
        self.assertEqual([], self.notifications)

        self.tx_manager.begin()
        self.notifier.queue_udf_delete(1, udf_c)
        self.assertEqual([], self.notifications)
        self.tx_manager.commit()
        # make sure we don't re-send from previous transactions
        event_c = self.notifications[0]
        self.assertEqual(event_c.udf_id, udf_c)
        self.assertEqual(event_c.source_session, None)