#1962: attempt to make the timestep actions look neater + adding logic that allows restoring a folder take multiple timesteps
This commit is contained in:
@@ -22,11 +22,23 @@ class Folder(FileSystemItemABC):
|
|||||||
deleted_files: Dict[str, File] = {}
|
deleted_files: Dict[str, File] = {}
|
||||||
"Files that have been deleted."
|
"Files that have been deleted."
|
||||||
|
|
||||||
scan_duration: int = -1
|
scan_duration: int = 3
|
||||||
"How many timesteps to complete a scan."
|
"How many timesteps to complete a scan. Default 3 timesteps"
|
||||||
|
|
||||||
red_scan_duration: int = -1
|
scan_countdown: int = 0
|
||||||
"How many timesteps to complete reveal to red scan."
|
"Time steps needed until scan completion."
|
||||||
|
|
||||||
|
red_scan_duration: int = 3
|
||||||
|
"How many timesteps to complete reveal to red scan. Default 3 timesteps"
|
||||||
|
|
||||||
|
red_scan_countdown: int = 0
|
||||||
|
"Time steps needed until red scan completion."
|
||||||
|
|
||||||
|
restore_duration: int = 3
|
||||||
|
"How many timesteps to complete a restore. Default 3 timesteps"
|
||||||
|
|
||||||
|
restore_countdown: int = 0
|
||||||
|
"Time steps needed until restore completion."
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
"""
|
"""
|
||||||
@@ -55,6 +67,7 @@ class Folder(FileSystemItemABC):
|
|||||||
"""
|
"""
|
||||||
state = super().describe_state()
|
state = super().describe_state()
|
||||||
state["files"] = {file.name: file.describe_state() for uuid, file in self.files.items()}
|
state["files"] = {file.name: file.describe_state() for uuid, file in self.files.items()}
|
||||||
|
state["deleted_files"] = {file.name: file.describe_state() for uuid, file in self.deleted_files.items()}
|
||||||
return state
|
return state
|
||||||
|
|
||||||
def show(self, markdown: bool = False):
|
def show(self, markdown: bool = False):
|
||||||
@@ -94,30 +107,57 @@ class Folder(FileSystemItemABC):
|
|||||||
"""
|
"""
|
||||||
super().apply_timestep(timestep=timestep)
|
super().apply_timestep(timestep=timestep)
|
||||||
|
|
||||||
# scan files each timestep
|
self._scan_timestep()
|
||||||
if self.scan_duration >= 0:
|
|
||||||
self.scan_duration -= 1
|
|
||||||
|
|
||||||
if self.scan_duration == 0:
|
self._reveal_to_red_timestep()
|
||||||
|
|
||||||
|
self._restoring_timestep()
|
||||||
|
|
||||||
|
# apply timestep to files in folder
|
||||||
|
for file_id in self.files:
|
||||||
|
self.files[file_id].apply_timestep(timestep=timestep)
|
||||||
|
|
||||||
|
def _scan_timestep(self) -> None:
|
||||||
|
"""Apply the scan action timestep."""
|
||||||
|
if self.scan_countdown >= 0:
|
||||||
|
self.scan_countdown -= 1
|
||||||
|
|
||||||
|
if self.scan_countdown == 0:
|
||||||
for file_id in self.files:
|
for file_id in self.files:
|
||||||
file = self.get_file_by_id(file_uuid=file_id)
|
file = self.get_file_by_id(file_uuid=file_id)
|
||||||
file.scan()
|
file.scan()
|
||||||
if file.visible_health_status == FileSystemItemHealthStatus.CORRUPT:
|
if file.visible_health_status == FileSystemItemHealthStatus.CORRUPT:
|
||||||
self.visible_health_status = FileSystemItemHealthStatus.CORRUPT
|
self.visible_health_status = FileSystemItemHealthStatus.CORRUPT
|
||||||
|
|
||||||
# red scan file at each step
|
def _reveal_to_red_timestep(self) -> None:
|
||||||
if self.red_scan_duration >= 0:
|
"""Apply reveal to red timestep."""
|
||||||
self.red_scan_duration -= 1
|
if self.red_scan_countdown >= 0:
|
||||||
|
self.red_scan_countdown -= 1
|
||||||
|
|
||||||
if self.red_scan_duration == 0:
|
if self.red_scan_countdown == 0:
|
||||||
self.revealed_to_red = True
|
self.revealed_to_red = True
|
||||||
for file_id in self.files:
|
for file_id in self.files:
|
||||||
file = self.get_file_by_id(file_uuid=file_id)
|
file = self.get_file_by_id(file_uuid=file_id)
|
||||||
file.reveal_to_red()
|
file.reveal_to_red()
|
||||||
|
|
||||||
# apply timestep to files in folder
|
def _restoring_timestep(self) -> None:
|
||||||
for file_id in self.files:
|
"""Apply restoring timestep."""
|
||||||
self.files[file_id].apply_timestep(timestep=timestep)
|
if self.restore_countdown >= 0:
|
||||||
|
self.restore_countdown -= 1
|
||||||
|
|
||||||
|
if self.restore_countdown == 0:
|
||||||
|
# repair all files
|
||||||
|
for file_id in self.files:
|
||||||
|
self.restore_file(file_uuid=file_id)
|
||||||
|
|
||||||
|
deleted_files = self.deleted_files.copy()
|
||||||
|
for file_id in deleted_files:
|
||||||
|
self.restore_file(file_uuid=file_id)
|
||||||
|
|
||||||
|
if self.deleted:
|
||||||
|
self.deleted = False
|
||||||
|
elif self.health_status in [FileSystemItemHealthStatus.CORRUPT, FileSystemItemHealthStatus.RESTORING]:
|
||||||
|
self.health_status = FileSystemItemHealthStatus.GOOD
|
||||||
|
|
||||||
def get_file(self, file_name: str) -> Optional[File]:
|
def get_file(self, file_name: str) -> Optional[File]:
|
||||||
"""
|
"""
|
||||||
@@ -259,9 +299,9 @@ class Folder(FileSystemItemABC):
|
|||||||
self.visible_health_status = FileSystemItemHealthStatus.CORRUPT
|
self.visible_health_status = FileSystemItemHealthStatus.CORRUPT
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.scan_duration <= 0:
|
if self.scan_countdown <= 0:
|
||||||
# scan one file per timestep
|
# scan one file per timestep
|
||||||
self.scan_duration = len(self.files)
|
self.scan_countdown = self.scan_duration
|
||||||
self.sys_log.info(f"Scanning folder {self.name} (id: {self.uuid})")
|
self.sys_log.info(f"Scanning folder {self.name} (id: {self.uuid})")
|
||||||
else:
|
else:
|
||||||
# scan already in progress
|
# scan already in progress
|
||||||
@@ -284,9 +324,9 @@ class Folder(FileSystemItemABC):
|
|||||||
file.reveal_to_red()
|
file.reveal_to_red()
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.red_scan_duration <= 0:
|
if self.red_scan_countdown <= 0:
|
||||||
# scan one file per timestep
|
# scan one file per timestep
|
||||||
self.red_scan_duration = len(self.files)
|
self.red_scan_countdown = self.red_scan_duration
|
||||||
self.sys_log.info(f"Folder revealed to red agent: {self.name} (id: {self.uuid})")
|
self.sys_log.info(f"Folder revealed to red agent: {self.name} (id: {self.uuid})")
|
||||||
else:
|
else:
|
||||||
# scan already in progress
|
# scan already in progress
|
||||||
@@ -347,18 +387,16 @@ class Folder(FileSystemItemABC):
|
|||||||
|
|
||||||
If the folder is deleted, restore the folder by setting deleted status to False.
|
If the folder is deleted, restore the folder by setting deleted status to False.
|
||||||
"""
|
"""
|
||||||
# repair all files
|
|
||||||
for file_id in self.files:
|
|
||||||
self.restore_file(file_uuid=file_id)
|
|
||||||
|
|
||||||
deleted_files = self.deleted_files.copy()
|
|
||||||
for file_id in deleted_files:
|
|
||||||
self.restore_file(file_uuid=file_id)
|
|
||||||
|
|
||||||
if self.deleted:
|
if self.deleted:
|
||||||
self.deleted = False
|
self.deleted = False
|
||||||
elif self.health_status == FileSystemItemHealthStatus.CORRUPT:
|
|
||||||
self.health_status = FileSystemItemHealthStatus.GOOD
|
if self.restore_countdown <= 0:
|
||||||
|
self.restore_countdown = self.restore_duration
|
||||||
|
self.health_status = FileSystemItemHealthStatus.RESTORING
|
||||||
|
self.sys_log.info(f"Restoring folder: {self.name} (id: {self.uuid})")
|
||||||
|
else:
|
||||||
|
# scan already in progress
|
||||||
|
self.sys_log.info(f"Folder restoration already in progress {self.name} (id: {self.uuid})")
|
||||||
|
|
||||||
def corrupt(self) -> None:
|
def corrupt(self) -> None:
|
||||||
"""Corrupt a File by setting the folder and containing files status to FileSystemItemStatus.CORRUPT."""
|
"""Corrupt a File by setting the folder and containing files status to FileSystemItemStatus.CORRUPT."""
|
||||||
|
|||||||
@@ -71,7 +71,25 @@ def test_folder_restore_request(populated_file_system):
|
|||||||
|
|
||||||
# restore folder
|
# restore folder
|
||||||
fs.apply_request(request=["restore", "folder", folder.uuid])
|
fs.apply_request(request=["restore", "folder", folder.uuid])
|
||||||
|
fs.apply_timestep(timestep=0)
|
||||||
|
assert fs.get_folder(folder_name=folder.name) is not None
|
||||||
|
assert (
|
||||||
|
fs.get_folder_by_id(folder_uuid=folder.uuid, include_deleted=True).health_status
|
||||||
|
== FileSystemItemHealthStatus.RESTORING
|
||||||
|
)
|
||||||
|
assert fs.get_folder_by_id(folder_uuid=folder.uuid, include_deleted=True).deleted is False
|
||||||
|
|
||||||
|
assert fs.get_file(folder_name=folder.name, file_name=file.name) is None
|
||||||
|
assert fs.get_file_by_id(folder_uuid=folder.uuid, file_uuid=file.uuid, include_deleted=True).deleted is True
|
||||||
|
|
||||||
|
fs.apply_timestep(timestep=1)
|
||||||
|
fs.apply_timestep(timestep=2)
|
||||||
|
|
||||||
assert fs.get_file(folder_name=folder.name, file_name=file.name) is not None
|
assert fs.get_file(folder_name=folder.name, file_name=file.name) is not None
|
||||||
|
assert (
|
||||||
|
fs.get_file(folder_name=folder.name, file_name=file.name).health_status
|
||||||
|
is not FileSystemItemHealthStatus.RESTORING
|
||||||
|
)
|
||||||
assert fs.get_file(folder_name=folder.name, file_name=file.name).deleted is False
|
assert fs.get_file(folder_name=folder.name, file_name=file.name).deleted is False
|
||||||
|
|
||||||
assert fs.get_file(folder_name=folder.name, file_name=file.name) is not None
|
assert fs.get_file(folder_name=folder.name, file_name=file.name) is not None
|
||||||
@@ -84,5 +102,19 @@ def test_folder_restore_request(populated_file_system):
|
|||||||
|
|
||||||
# restore folder
|
# restore folder
|
||||||
fs.apply_request(request=["restore", "folder", folder.uuid])
|
fs.apply_request(request=["restore", "folder", folder.uuid])
|
||||||
assert fs.get_folder(folder_name=folder.name).health_status == FileSystemItemHealthStatus.GOOD
|
fs.apply_timestep(timestep=0)
|
||||||
assert fs.get_file(folder_name=folder.name, file_name=file.name).health_status == FileSystemItemHealthStatus.GOOD
|
assert fs.get_folder(folder_name=folder.name).health_status == FileSystemItemHealthStatus.RESTORING
|
||||||
|
assert fs.get_file(folder_name=folder.name, file_name=file.name).health_status == FileSystemItemHealthStatus.CORRUPT
|
||||||
|
|
||||||
|
fs.apply_timestep(timestep=1)
|
||||||
|
fs.apply_timestep(timestep=2)
|
||||||
|
|
||||||
|
assert fs.get_file(folder_name=folder.name, file_name=file.name) is not None
|
||||||
|
assert (
|
||||||
|
fs.get_file(folder_name=folder.name, file_name=file.name).health_status
|
||||||
|
is not FileSystemItemHealthStatus.RESTORING
|
||||||
|
)
|
||||||
|
assert fs.get_file(folder_name=folder.name, file_name=file.name).deleted is False
|
||||||
|
|
||||||
|
assert fs.get_file(folder_name=folder.name, file_name=file.name) is not None
|
||||||
|
assert fs.get_file_by_id(folder_uuid=folder.uuid, file_uuid=file.uuid, include_deleted=True).deleted is False
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ def test_folder_scan(file_system):
|
|||||||
assert file2.visible_health_status == FileSystemItemHealthStatus.GOOD
|
assert file2.visible_health_status == FileSystemItemHealthStatus.GOOD
|
||||||
|
|
||||||
folder.apply_timestep(timestep=1)
|
folder.apply_timestep(timestep=1)
|
||||||
|
folder.apply_timestep(timestep=2)
|
||||||
|
|
||||||
assert folder.health_status == FileSystemItemHealthStatus.CORRUPT
|
assert folder.health_status == FileSystemItemHealthStatus.CORRUPT
|
||||||
assert folder.visible_health_status == FileSystemItemHealthStatus.CORRUPT
|
assert folder.visible_health_status == FileSystemItemHealthStatus.CORRUPT
|
||||||
@@ -93,6 +94,7 @@ def test_folder_reveal_to_red_scan(file_system):
|
|||||||
assert file2.revealed_to_red is False
|
assert file2.revealed_to_red is False
|
||||||
|
|
||||||
folder.apply_timestep(timestep=1)
|
folder.apply_timestep(timestep=1)
|
||||||
|
folder.apply_timestep(timestep=2)
|
||||||
|
|
||||||
assert folder.revealed_to_red is True
|
assert folder.revealed_to_red is True
|
||||||
assert file1.revealed_to_red is True
|
assert file1.revealed_to_red is True
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ def test_folder_scan_request(populated_file_system):
|
|||||||
assert file2.visible_health_status == FileSystemItemHealthStatus.GOOD
|
assert file2.visible_health_status == FileSystemItemHealthStatus.GOOD
|
||||||
|
|
||||||
folder.apply_timestep(timestep=1)
|
folder.apply_timestep(timestep=1)
|
||||||
|
folder.apply_timestep(timestep=2)
|
||||||
|
|
||||||
assert folder.health_status == FileSystemItemHealthStatus.CORRUPT
|
assert folder.health_status == FileSystemItemHealthStatus.CORRUPT
|
||||||
assert folder.visible_health_status == FileSystemItemHealthStatus.CORRUPT
|
assert folder.visible_health_status == FileSystemItemHealthStatus.CORRUPT
|
||||||
|
|||||||
Reference in New Issue
Block a user