1
0
mirror of https://github.com/dkmstr/openuds.git synced 2025-01-03 01:17:56 +03:00

Fixed dynamic service and done tests for deletion and deletion tests

This commit is contained in:
Adolfo Gómez García 2024-08-31 20:21:23 +02:00
parent f4ee6e50c0
commit 457c1e25e8
No known key found for this signature in database
GPG Key ID: DD1ABF20724CDA23
6 changed files with 57 additions and 7 deletions

View File

@ -526,6 +526,7 @@ class DynamicTestingService(dynamic_service.DynamicService):
caller_instance: typing.Optional[dynamic_userservice.DynamicUserService | dynamic_publication.DynamicPublication], caller_instance: typing.Optional[dynamic_userservice.DynamicUserService | dynamic_publication.DynamicPublication],
vmid: str, vmid: str,
) -> None: ) -> None:
super().set_deleting_state(vmid) # Call parent set_delete_runnign
self.mock.remove(caller_instance, vmid) self.mock.remove(caller_instance, vmid)
self.machine_running_flag = False self.machine_running_flag = False

View File

@ -196,6 +196,26 @@ class DynamicPublicationTest(UDSTestCase):
self.assertEqual(publication.check_state(), types.states.TaskState.ERROR) self.assertEqual(publication.check_state(), types.states.TaskState.ERROR)
self.assertEqual(publication.error_reason(), 'Max retries reached') self.assertEqual(publication.error_reason(), 'Max retries reached')
self.assertEqual(counter, 10) # 4 retries + 5 retries after reset + 1 of the reset itself self.assertEqual(counter, 10) # 4 retries + 5 retries after reset + 1 of the reset itself
def test_publication_delete(self) -> None:
service = fixtures.create_dynamic_service()
publication = fixtures.create_dynamic_publication(service)
publication._queue = [
types.services.Operation.NOP, # First check
types.services.Operation.DELETE, # Execute-check
types.services.Operation.FINISH, # Finish
]
state = types.states.TaskState.RUNNING
counter = 0 # to be able to use it outside the loop
# Shuold keep running until service notify_delete is called
for counter in limited_iterator(lambda: state == types.states.TaskState.RUNNING, limit=128):
state = publication.check_state()
if counter == 16: # After 16 iterations, we will call notify_deleted
publication.service().notify_deleted(publication._vmid)
# Counter should be greater than 16
self.assertGreater(counter, 16)
EXPECTED_DEPLOY_ITERATIONS_INFO: typing.Final[list[DynamicPublicationIterationInfo]] = [ EXPECTED_DEPLOY_ITERATIONS_INFO: typing.Final[list[DynamicPublicationIterationInfo]] = [

View File

@ -319,6 +319,27 @@ class DynamicServiceTest(UDSTestCase):
self.assertEqual(userservice.check_state(), types.states.TaskState.ERROR) self.assertEqual(userservice.check_state(), types.states.TaskState.ERROR)
self.assertEqual(userservice.error_reason(), 'Max retries reached') self.assertEqual(userservice.error_reason(), 'Max retries reached')
self.assertEqual(counter, 10) # 4 retries + 5 retries after reset + 1 of the reset itself self.assertEqual(counter, 10) # 4 retries + 5 retries after reset + 1 of the reset itself
def test_userservice_delete(self) -> None:
service = fixtures.create_dynamic_service()
userservice = fixtures.create_dynamic_userservice(service)
userservice._vmid = 'vmid'
userservice._queue = [
types.services.Operation.NOP, # First check
types.services.Operation.DELETE, # Execute-check
types.services.Operation.FINISH, # Finish
]
state = types.states.TaskState.RUNNING
counter = 0 # to be able to use it outside the loop
# Shuold keep running until service notify_delete is called
for counter in limited_iterator(lambda: state == types.states.TaskState.RUNNING, limit=128):
state = userservice.check_state()
if counter == 16: # After 16 iterations, we will call notify_deleted
userservice.service().notify_deleted(userservice._vmid)
# Counter should be greater than 16
self.assertGreater(counter, 16)
EXPECTED_DEPLOY_ITERATIONS_INFO: typing.Final[list[DynamicServiceIterationInfo]] = [ EXPECTED_DEPLOY_ITERATIONS_INFO: typing.Final[list[DynamicServiceIterationInfo]] = [

View File

@ -64,6 +64,8 @@ class DynamicPublication(services.Publication, autoserializable.AutoSerializable
# Extra info, not serializable, to keep information in case of exception and debug it # Extra info, not serializable, to keep information in case of exception and debug it
_error_debug_info: typing.Optional[str] = None _error_debug_info: typing.Optional[str] = None
# Default queues for publication. Should be enough for most of the cases
# but can be overrided if needed
_publish_queue: typing.ClassVar[list[Operation]] = [ _publish_queue: typing.ClassVar[list[Operation]] = [
Operation.INITIALIZE, Operation.INITIALIZE,
Operation.CREATE, Operation.CREATE,
@ -488,7 +490,7 @@ class DynamicPublication(services.Publication, autoserializable.AutoSerializable
""" """
This method is called to check if the service is removed This method is called to check if the service is removed
""" """
if self.service().is_delete_running(self, self._vmid) is False: if self.service().check_deleting_status(self, self._vmid) is False:
return types.states.TaskState.FINISHED return types.states.TaskState.FINISHED
return types.states.TaskState.RUNNING return types.states.TaskState.RUNNING

View File

@ -207,16 +207,14 @@ class DynamicService(services.Service, abc.ABC): # pylint: disable=too-many-pub
""" """
# Default is to stop "hard" # Default is to stop "hard"
return self.stop(caller_instance, vmid) return self.stop(caller_instance, vmid)
def delete(self, caller_instance: typing.Optional['DynamicUserService | DynamicPublication'], vmid: str) -> None: def delete(self, caller_instance: typing.Optional['DynamicUserService | DynamicPublication'], vmid: str) -> None:
""" """
Removes the machine, or queues it for removal, or whatever :) Removes the machine, or queues it for removal, or whatever :)
Use the caller_instance to notify anything if needed, or to identify caller Use the caller_instance to notify anything if needed, or to identify caller
""" """
# Store the deletion has started for future reference # Store the deletion has started for future reference
with self.storage.as_dict() as storage: self.set_deleting_state(vmid)
# Store deleting vmid
storage[f'deleting_{vmid}'] = True
DeferredDeletionWorker.add(self, vmid) DeferredDeletionWorker.add(self, vmid)
@ -247,7 +245,15 @@ class DynamicService(services.Service, abc.ABC): # pylint: disable=too-many-pub
with self.storage.as_dict() as storage: with self.storage.as_dict() as storage:
del storage[f'deleting_{vmid}'] del storage[f'deleting_{vmid}']
def is_delete_running(self, caller_instance: typing.Optional['DynamicUserService | DynamicPublication'], vmid: str) -> bool: def set_deleting_state(self, vmid: str) -> None:
"""
Marks a machine as deleting
"""
with self.storage.as_dict() as storage:
# Store deleting vmid
storage[f'deleting_{vmid}'] = True
def check_deleting_status(self, caller_instance: typing.Optional['DynamicUserService | DynamicPublication'], vmid: str) -> bool:
""" """
Checks if the deferred deletion of a machine is running Checks if the deferred deletion of a machine is running
Default implementation is return False always Default implementation is return False always

View File

@ -811,7 +811,7 @@ class DynamicUserService(services.UserService, autoserializable.AutoSerializable
""" """
This method is called to check if the service is removed This method is called to check if the service is removed
""" """
if self.service().is_delete_running(self, self._vmid) is False: if self.service().check_deleting_status(self, self._vmid) is False:
return types.states.TaskState.FINISHED return types.states.TaskState.FINISHED
return types.states.TaskState.RUNNING return types.states.TaskState.RUNNING