diff --git a/src/primaite/simulator/system/services/database/database_service.py b/src/primaite/simulator/system/services/database/database_service.py index 541a15c2..ede2a54f 100644 --- a/src/primaite/simulator/system/services/database/database_service.py +++ b/src/primaite/simulator/system/services/database/database_service.py @@ -104,14 +104,30 @@ class DatabaseService(Service): self.sys_log.error("Unable to restore database backup.") return False + old_visible_state = SoftwareHealthState.GOOD + + # get db file regardless of whether or not it was deleted + db_file = self.file_system.get_file(folder_name="database", file_name="database.db", include_deleted=True) + + if db_file is None: + self.sys_log.error("Database file not initialised.") + return False + + # if the file was deleted, get the old visible health state + if db_file.deleted: + old_visible_state = db_file.visible_health_status + else: + old_visible_state = self.db_file.visible_health_status + self.file_system.delete_file(folder_name="database", file_name="database.db") + # replace db file - self.file_system.delete_file(folder_name="database", file_name="database.db") self.file_system.copy_file(src_folder_name="downloads", src_file_name="database.db", dst_folder_name="database") if self.db_file is None: self.sys_log.error("Copying database backup failed.") return False + self.db_file.visible_health_status = old_visible_state self.set_health_state(SoftwareHealthState.GOOD) return True diff --git a/tests/integration_tests/system/test_database_on_node.py b/tests/integration_tests/system/test_database_on_node.py index ac0e65b4..c555acff 100644 --- a/tests/integration_tests/system/test_database_on_node.py +++ b/tests/integration_tests/system/test_database_on_node.py @@ -3,6 +3,7 @@ from typing import Tuple import pytest +from primaite.simulator.file_system.file_system_item_abc import FileSystemItemHealthStatus from primaite.simulator.network.container import Network from primaite.simulator.network.hardware.node_operating_state import NodeOperatingState from primaite.simulator.network.hardware.nodes.host.computer import Computer @@ -138,6 +139,68 @@ def test_restore_backup(uc2_network): assert db_service.file_system.get_file(folder_name="database", file_name="database.db") is not None +def test_restore_backup_without_updating_scan(uc2_network): + """Same test as restore backup but the file is previously seen as corrupted.""" + db_server: Server = uc2_network.get_node_by_hostname("database_server") + db_service: DatabaseService = db_server.software_manager.software["DatabaseService"] + + # create a back up + assert db_service.backup_database() is True + + db_service.db_file.corrupt() # corrupt the db + assert db_service.db_file.health_status == FileSystemItemHealthStatus.CORRUPT # db file is actually corrupt + assert db_service.db_file.visible_health_status == FileSystemItemHealthStatus.GOOD # not scanned yet + + db_service.db_file.scan() # scan the db file + + # db file is corrupt since last scan + assert db_service.db_file.visible_health_status == FileSystemItemHealthStatus.CORRUPT + + # back up should be restored + assert db_service.restore_backup() is True + + assert db_service.db_file.health_status == FileSystemItemHealthStatus.GOOD # db file is actually good + # db file is corrupt since last scan + assert db_service.db_file.visible_health_status == FileSystemItemHealthStatus.CORRUPT + + db_service.db_file.scan() # scan the db file + assert db_service.db_file.visible_health_status == FileSystemItemHealthStatus.GOOD # now looks good + + +def test_restore_backup_after_deleting_file_without_updating_scan(uc2_network): + """Same test as restore backup but the file is previously seen as corrupted.""" + db_server: Server = uc2_network.get_node_by_hostname("database_server") + db_service: DatabaseService = db_server.software_manager.software["DatabaseService"] + + # create a back up + assert db_service.backup_database() is True + + db_service.db_file.corrupt() # corrupt the db + assert db_service.db_file.health_status == FileSystemItemHealthStatus.CORRUPT # db file is actually corrupt + assert db_service.db_file.visible_health_status == FileSystemItemHealthStatus.GOOD # not scanned yet + + db_service.db_file.scan() # scan the db file + + # db file is corrupt since last scan + assert db_service.db_file.visible_health_status == FileSystemItemHealthStatus.CORRUPT + + # delete database locally + db_service.file_system.delete_file(folder_name="database", file_name="database.db") + + # db file is gone, reduced to atoms + assert db_service.db_file is None + + # back up should be restored + assert db_service.restore_backup() is True + + assert db_service.db_file.health_status == FileSystemItemHealthStatus.GOOD # db file is actually good + # db file is corrupt since last scan + assert db_service.db_file.visible_health_status == FileSystemItemHealthStatus.CORRUPT + + db_service.db_file.scan() # scan the db file + assert db_service.db_file.visible_health_status == FileSystemItemHealthStatus.GOOD # now looks good + + def test_database_client_cannot_query_offline_database_server(uc2_network): """Tests DB query across the network returns HTTP status 404 when db server is offline.""" db_server: Server = uc2_network.get_node_by_hostname("database_server")