From 18e40a80c831559e0eba863c14b9f5b51c7ea0f6 Mon Sep 17 00:00:00 2001 From: Danni Shi Date: Wed, 21 Jun 2023 17:02:09 -0400 Subject: [PATCH] Add lease expire notification --- esi_leap/objects/lease.py | 62 ++++++++++++------------ esi_leap/tests/objects/test_lease.py | 70 ++++++++++++++++++++++++---- 2 files changed, 95 insertions(+), 37 deletions(-) diff --git a/esi_leap/objects/lease.py b/esi_leap/objects/lease.py index 80e74fd6..c33d5bb5 100644 --- a/esi_leap/objects/lease.py +++ b/esi_leap/objects/lease.py @@ -208,25 +208,10 @@ def cancel(self, context=None): LOG.info('Deleting lease %s', self.uuid) try: resource = self.resource_object() - if resource.get_lease_uuid() == self.uuid: - resource.remove_lease(self) - if self.parent_lease_uuid is not None: - parent_lease = Lease.get(self.parent_lease_uuid) - resource.set_lease(parent_lease) + self.deactivate(context, resource) + self.status = statuses.DELETED + self.expire_time = datetime.datetime.now() - notify.emit_start_notification(context, self, - 'delete', CRUD_NOTIFY_OBJ, - node=resource) - with notify.handle_error_notification(context, - self, - 'delete', - CRUD_NOTIFY_OBJ, - node=resource): - self.status = statuses.DELETED - self.expire_time = datetime.datetime.now() - notify.emit_end_notification(context, self, - 'delete', CRUD_NOTIFY_OBJ, - node=resource) except Exception as e: LOG.info('Error canceling lease: %s: %s' % (type(e).__name__, e)) @@ -251,9 +236,6 @@ def fulfill(self, context=None): LOG.info('Fulfilling lease %s', self.uuid) try: resource = self.resource_object() - resource.set_lease(self) - - # activate lease notify.emit_start_notification(context, self, 'fulfill', CRUD_NOTIFY_OBJ, @@ -263,12 +245,16 @@ def fulfill(self, context=None): 'fulfill', CRUD_NOTIFY_OBJ, node=resource): - self.status = statuses.ACTIVE - self.fulfill_time = datetime.datetime.now() + resource.set_lease(self) + notify.emit_end_notification(context, self, 'fulfill', CRUD_NOTIFY_OBJ, node=resource) + + self.status = statuses.ACTIVE + self.fulfill_time = datetime.datetime.now() + except Exception as e: LOG.info('Error fulfilling lease: %s: %s' % (type(e).__name__, e)) @@ -295,15 +281,12 @@ def expire(self, context=None): external=True): LOG.info('Expiring lease %s', self.uuid) try: - resource = self.resource_object() - if resource.get_lease_uuid() == self.uuid: - resource.remove_lease(self) - if self.parent_lease_uuid is not None: - parent_lease = Lease.get(self.parent_lease_uuid) - resource.set_lease(parent_lease) # expire lease + resource = self.resource_object() + self.deactivate(context, resource) self.status = statuses.EXPIRED self.expire_time = datetime.datetime.now() + except Exception as e: LOG.info('Error expiring lease: %s: %s' % (type(e).__name__, e)) @@ -317,3 +300,24 @@ def resource_object(self): def verify_child_availability(self, start_time, end_time): return self.dbapi.lease_verify_child_availability( self, start_time, end_time) + + def deactivate(self, context, resource): + notify.emit_start_notification(context, self, + 'delete', CRUD_NOTIFY_OBJ, + node=resource) + + with notify.handle_error_notification(context, + self, + 'delete', + CRUD_NOTIFY_OBJ, + node=resource): + if resource.get_lease_uuid() == self.uuid: + resource.remove_lease(self) + + if self.parent_lease_uuid is not None: + parent_lease = Lease.get(self.parent_lease_uuid) + resource.set_lease(parent_lease) + + notify.emit_end_notification(context, self, + 'delete', CRUD_NOTIFY_OBJ, + node=resource) diff --git a/esi_leap/tests/objects/test_lease.py b/esi_leap/tests/objects/test_lease.py index 33767a22..8d987563 100644 --- a/esi_leap/tests/objects/test_lease.py +++ b/esi_leap/tests/objects/test_lease.py @@ -287,7 +287,14 @@ def test_fulfill_error(self, mock_notify, mock_save, lease.fulfill() - mock_notify.assert_not_called() + mock_notify.assert_has_calls([mock.call(mock.ANY, mock.ANY, 'fulfill', + obj_fields.NotificationLevel.INFO, + obj_fields.NotificationStatus.START, + mock.ANY, node=mock.ANY), + mock.call(mock.ANY, mock.ANY, 'fulfill', + obj_fields.NotificationLevel.ERROR, + obj_fields.NotificationStatus.ERROR, + mock.ANY, node=mock.ANY)]) mock_ro.assert_called_once() mock_set_lease.assert_called_once() mock_save.assert_called_once() @@ -311,7 +318,6 @@ def test_cancel(self, mock_notify, mock_save, mock_glu.return_value = lease.uuid lease.cancel() - mock_notify.assert_has_calls([mock.call(mock.ANY, mock.ANY, 'delete', obj_fields.NotificationLevel.INFO, obj_fields.NotificationStatus.START, @@ -348,7 +354,14 @@ def test_cancel_error(self, mock_notify, mock_save, lease.cancel() - mock_notify.assert_not_called() + mock_notify.assert_has_calls([mock.call(mock.ANY, mock.ANY, 'delete', + obj_fields.NotificationLevel.INFO, + obj_fields.NotificationStatus.START, + mock.ANY, node=mock.ANY), + mock.call(mock.ANY, mock.ANY, 'delete', + obj_fields.NotificationLevel.ERROR, + obj_fields.NotificationStatus.ERROR, + mock.ANY, node=mock.ANY)]) mock_sl.assert_not_called() mock_lg.assert_not_called() mock_ro.assert_called_once() @@ -430,7 +443,9 @@ def test_cancel_no_expire(self, mock_notify, mock_save, @mock.patch('esi_leap.resource_objects.test_node.TestNode.get_lease_uuid') @mock.patch('esi_leap.resource_objects.test_node.TestNode.remove_lease') @mock.patch('esi_leap.objects.lease.Lease.save') - def test_expire(self, mock_save, mock_rl, mock_glu, mock_ro, + @mock.patch('esi_leap.common.notification_utils' + '._emit_notification') + def test_expire(self, mock_notify, mock_save, mock_rl, mock_glu, mock_ro, mock_lg, mock_sl): lease = lease_obj.Lease(self.context, **self.test_lease_dict) test_node = TestNode('test-node', '12345') @@ -440,6 +455,14 @@ def test_expire(self, mock_save, mock_rl, mock_glu, mock_ro, lease.expire() + mock_notify.assert_has_calls([mock.call(mock.ANY, mock.ANY, 'delete', + obj_fields.NotificationLevel.INFO, + obj_fields.NotificationStatus.START, + mock.ANY, node=mock.ANY), + mock.call(mock.ANY, mock.ANY, 'delete', + obj_fields.NotificationLevel.INFO, + obj_fields.NotificationStatus.END, + mock.ANY, node=mock.ANY)]) mock_sl.assert_not_called() mock_lg.assert_not_called() mock_ro.assert_called_once() @@ -454,7 +477,9 @@ def test_expire(self, mock_save, mock_rl, mock_glu, mock_ro, @mock.patch('esi_leap.resource_objects.test_node.TestNode.get_lease_uuid') @mock.patch('esi_leap.resource_objects.test_node.TestNode.remove_lease') @mock.patch('esi_leap.objects.lease.Lease.save') - def test_expire_error(self, mock_save, mock_rl, mock_glu, + @mock.patch('esi_leap.common.notification_utils' + '._emit_notification') + def test_expire_error(self, mock_notify, mock_save, mock_rl, mock_glu, mock_ro, mock_lg, mock_sl): lease = lease_obj.Lease(self.context, **self.test_lease_dict) test_node = TestNode('test-node', '12345') @@ -465,6 +490,14 @@ def test_expire_error(self, mock_save, mock_rl, mock_glu, lease.expire() + mock_notify.assert_has_calls([mock.call(mock.ANY, mock.ANY, 'delete', + obj_fields.NotificationLevel.INFO, + obj_fields.NotificationStatus.START, + mock.ANY, node=mock.ANY), + mock.call(mock.ANY, mock.ANY, 'delete', + obj_fields.NotificationLevel.ERROR, + obj_fields.NotificationStatus.ERROR, + mock.ANY, node=mock.ANY)]) mock_sl.assert_not_called() mock_lg.assert_not_called() mock_ro.assert_called_once() @@ -479,8 +512,10 @@ def test_expire_error(self, mock_save, mock_rl, mock_glu, @mock.patch('esi_leap.resource_objects.test_node.TestNode.get_lease_uuid') @mock.patch('esi_leap.resource_objects.test_node.TestNode.remove_lease') @mock.patch('esi_leap.objects.lease.Lease.save') - def test_expire_with_parent(self, mock_save, mock_rl, mock_glu, - mock_ro, mock_lg, mock_sl): + @mock.patch('esi_leap.common.notification_utils' + '._emit_notification') + def test_expire_with_parent(self, mock_notify, mock_save, mock_rl, + mock_glu, mock_ro, mock_lg, mock_sl): lease = lease_obj.Lease(self.context, **self.test_lease_parent_lease_dict) test_node = TestNode('test-node', '12345') @@ -490,6 +525,14 @@ def test_expire_with_parent(self, mock_save, mock_rl, mock_glu, lease.expire() + mock_notify.assert_has_calls([mock.call(mock.ANY, mock.ANY, 'delete', + obj_fields.NotificationLevel.INFO, + obj_fields.NotificationStatus.START, + mock.ANY, node=mock.ANY), + mock.call(mock.ANY, mock.ANY, 'delete', + obj_fields.NotificationLevel.INFO, + obj_fields.NotificationStatus.END, + mock.ANY, node=mock.ANY)]) mock_sl.assert_called_once() mock_lg.assert_called_once() mock_ro.assert_called_once() @@ -502,7 +545,10 @@ def test_expire_with_parent(self, mock_save, mock_rl, mock_glu, @mock.patch('esi_leap.resource_objects.test_node.TestNode.get_lease_uuid') @mock.patch('esi_leap.resource_objects.test_node.TestNode.remove_lease') @mock.patch('esi_leap.objects.lease.Lease.save') - def test_expire_no_expire(self, mock_save, mock_rl, mock_glu, mock_ro): + @mock.patch('esi_leap.common.notification_utils' + '._emit_notification') + def test_expire_no_expire(self, mock_notify, mock_save, mock_rl, + mock_glu, mock_ro): lease = lease_obj.Lease(self.context, **self.test_lease_dict) test_node = TestNode('test-node', '12345') @@ -511,6 +557,14 @@ def test_expire_no_expire(self, mock_save, mock_rl, mock_glu, mock_ro): lease.expire() + mock_notify.assert_has_calls([mock.call(mock.ANY, mock.ANY, 'delete', + obj_fields.NotificationLevel.INFO, + obj_fields.NotificationStatus.START, + mock.ANY, node=mock.ANY), + mock.call(mock.ANY, mock.ANY, 'delete', + obj_fields.NotificationLevel.INFO, + obj_fields.NotificationStatus.END, + mock.ANY, node=mock.ANY)]) mock_ro.assert_called_once() mock_glu.assert_called_once() mock_rl.assert_not_called()