#1796 - Made the FTP copy real files. Hardcoded the DatabaseService backup folder and filename. Added db restore and final query check to the data manipulation e2e test.

This commit is contained in:
Chris McCarthy
2023-09-29 20:14:42 +01:00
parent bca3e6344e
commit 3dc8a0f222
4 changed files with 36 additions and 22 deletions

View File

@@ -41,6 +41,9 @@ class DatabaseService(Service):
super().__init__(**kwargs) super().__init__(**kwargs)
self._db_file: File self._db_file: File
self._create_db_file() self._create_db_file()
self._connect()
def _connect(self):
self._conn = sqlite3.connect(self._db_file.sim_path) self._conn = sqlite3.connect(self._db_file.sim_path)
self._cursor = self._conn.cursor() self._cursor = self._conn.cursor()
@@ -51,8 +54,10 @@ class DatabaseService(Service):
:return: List of table names. :return: List of table names.
""" """
sql = "SELECT name FROM sqlite_master WHERE type='table' AND name != 'sqlite_sequence';" sql = "SELECT name FROM sqlite_master WHERE type='table' AND name != 'sqlite_sequence';"
results = self._process_sql(sql) results = self._process_sql(sql, None)
return [row[0] for row in results["data"]] if isinstance(results["data"], dict):
return list(results["data"].keys())
return []
def show(self, markdown: bool = False): def show(self, markdown: bool = False):
""" """
@@ -77,9 +82,7 @@ class DatabaseService(Service):
""" """
self.backup_server = backup_server self.backup_server = backup_server
def backup_database( def backup_database(self) -> bool:
self, backup_directory: Optional[str] = "db_backup", backup_file_name: Optional[str] = None
) -> bool:
""" """
Create a backup of the database to the configured backup server. Create a backup of the database to the configured backup server.
@@ -94,8 +97,7 @@ class DatabaseService(Service):
self.sys_log.error(f"{self.name} - {self.sys_log.hostname}: not configured.") self.sys_log.error(f"{self.name} - {self.sys_log.hostname}: not configured.")
return False return False
if backup_file_name is None: self._conn.close()
backup_file_name = f"{datetime.now().strftime('%d-%m-%Y_%H-%M')}.db"
software_manager: SoftwareManager = self.software_manager software_manager: SoftwareManager = self.software_manager
ftp_client_service: FTPClient = software_manager.software["FTPClient"] ftp_client_service: FTPClient = software_manager.software["FTPClient"]
@@ -105,19 +107,19 @@ class DatabaseService(Service):
dest_ip_address=self.backup_server, dest_ip_address=self.backup_server,
src_file_name=self._db_file.name, src_file_name=self._db_file.name,
src_folder_name=self._db_file.folder.name, src_folder_name=self._db_file.folder.name,
dest_folder_name=backup_directory, dest_folder_name=str(self.uuid),
dest_file_name=backup_file_name, dest_file_name="database.db",
real_file_path=self._db_file.sim_path,
) )
self._connect()
if response: if response:
self.latest_backup_directory = backup_directory
self.latest_backup_file_name = backup_file_name
return True return True
self.sys_log.error("Unable to create database backup.") self.sys_log.error("Unable to create database backup.")
return False return False
def restore_backup(self, backup_directory: Optional[str] = None, backup_file_name: Optional[str] = None) -> bool: def restore_backup(self) -> bool:
""" """
Restore a backup from backup server. Restore a backup from backup server.
@@ -127,32 +129,27 @@ class DatabaseService(Service):
:param: backup_file_name: Name of file where backup will be stored. Optional. :param: backup_file_name: Name of file where backup will be stored. Optional.
:type: backup_file_name: Optional[str] :type: backup_file_name: Optional[str]
""" """
if backup_directory is None:
backup_directory = self.latest_backup_directory
if backup_file_name is None:
backup_file_name = self.latest_backup_file_name
software_manager: SoftwareManager = self.software_manager software_manager: SoftwareManager = self.software_manager
ftp_client_service: FTPClient = software_manager.software["FTPClient"] ftp_client_service: FTPClient = software_manager.software["FTPClient"]
# retrieve backup file from backup server # retrieve backup file from backup server
response = ftp_client_service.request_file( response = ftp_client_service.request_file(
src_folder_name=backup_directory, src_folder_name=str(self.uuid),
src_file_name=backup_file_name, src_file_name="database.db",
dest_folder_name="downloads", dest_folder_name="downloads",
dest_file_name="database.db", dest_file_name="database.db",
dest_ip_address=self.backup_server, dest_ip_address=self.backup_server,
) )
if response: if response:
self._conn.close()
# replace db file # replace db file
self.file_system.delete_file(folder_name=self.folder.name, file_name="downloads.db") self.file_system.delete_file(folder_name=self.folder.name, file_name="downloads.db")
self.file_system.move_file( self.file_system.move_file(
src_folder_name="downloads", src_file_name="database.db", dst_folder_name=self.folder.name src_folder_name="downloads", src_file_name="database.db", dst_folder_name=self.folder.name
) )
self._db_file = self.file_system.get_file(folder_name=self.folder.name, file_name="database.db") self._db_file = self.file_system.get_file(folder_name=self.folder.name, file_name="database.db")
self._connect()
return self._db_file is not None return self._db_file is not None

View File

@@ -119,6 +119,7 @@ class FTPClient(FTPServiceABC):
dest_folder_name: str, dest_folder_name: str,
dest_file_name: str, dest_file_name: str,
dest_port: Optional[Port] = Port.FTP, dest_port: Optional[Port] = Port.FTP,
real_file_path: Optional[str] = None,
) -> bool: ) -> bool:
""" """
Send a file to a target IP address. Send a file to a target IP address.

View File

@@ -1,3 +1,4 @@
import shutil
from abc import ABC from abc import ABC
from ipaddress import IPv4Address from ipaddress import IPv4Address
from typing import Optional from typing import Optional
@@ -51,11 +52,17 @@ class FTPServiceABC(Service, ABC):
file_name = payload.ftp_command_args["dest_file_name"] file_name = payload.ftp_command_args["dest_file_name"]
folder_name = payload.ftp_command_args["dest_folder_name"] folder_name = payload.ftp_command_args["dest_folder_name"]
file_size = payload.ftp_command_args["file_size"] file_size = payload.ftp_command_args["file_size"]
self.file_system.create_file(file_name=file_name, folder_name=folder_name, size=file_size, real=True) real_file_path = payload.ftp_command_args.get("real_file_path")
is_real = real_file_path is not None
file = self.file_system.create_file(
file_name=file_name, folder_name=folder_name, size=file_size, real=is_real
)
self.sys_log.info( self.sys_log.info(
f"Created item in {self.sys_log.hostname}: {payload.ftp_command_args['dest_folder_name']}/" f"Created item in {self.sys_log.hostname}: {payload.ftp_command_args['dest_folder_name']}/"
f"{payload.ftp_command_args['dest_file_name']}" f"{payload.ftp_command_args['dest_file_name']}"
) )
if is_real:
shutil.copy(real_file_path, file.sim_path)
# file should exist # file should exist
return self.file_system.get_file(file_name=file_name, folder_name=folder_name) is not None return self.file_system.get_file(file_name=file_name, folder_name=folder_name) is not None
except Exception as e: except Exception as e:
@@ -99,6 +106,7 @@ class FTPServiceABC(Service, ABC):
"dest_folder_name": dest_folder_name, "dest_folder_name": dest_folder_name,
"dest_file_name": dest_file_name, "dest_file_name": dest_file_name,
"file_size": file.sim_size, "file_size": file.sim_size,
"real_file_path": file.sim_path if file.real else None,
}, },
packet_payload_size=file.sim_size, packet_payload_size=file.sim_size,
) )

View File

@@ -15,6 +15,8 @@ def test_data_manipulation(uc2_network):
web_server: Server = uc2_network.get_node_by_hostname("web_server") web_server: Server = uc2_network.get_node_by_hostname("web_server")
db_client: DatabaseClient = web_server.software_manager.software["DatabaseClient"] db_client: DatabaseClient = web_server.software_manager.software["DatabaseClient"]
db_service.backup_database()
# First check that the DB client on the web_server can successfully query the users table on the database # First check that the DB client on the web_server can successfully query the users table on the database
assert db_client.query("SELECT * FROM user;") assert db_client.query("SELECT * FROM user;")
@@ -23,3 +25,9 @@ def test_data_manipulation(uc2_network):
# Now check that the DB client on the web_server cannot query the users table on the database # Now check that the DB client on the web_server cannot query the users table on the database
assert not db_client.query("SELECT * FROM user;") assert not db_client.query("SELECT * FROM user;")
# Now restore the database
db_service.restore_backup()
# Now check that the DB client on the web_server can successfully query the users table on the database
assert db_client.query("SELECT * FROM user;")