diff --git a/keywords/cloud_platform/dcmanager/dcmanager_subcloud_deploy_keywords.py b/keywords/cloud_platform/dcmanager/dcmanager_subcloud_deploy_keywords.py index ce9b356a..21dff8f8 100644 --- a/keywords/cloud_platform/dcmanager/dcmanager_subcloud_deploy_keywords.py +++ b/keywords/cloud_platform/dcmanager/dcmanager_subcloud_deploy_keywords.py @@ -3,6 +3,7 @@ from framework.ssh.ssh_connection import SSHConnection from keywords.base_keyword import BaseKeyword from keywords.cloud_platform.command_wrappers import source_openrc from keywords.cloud_platform.dcmanager.dcmanager_subcloud_list_keywords import DcManagerSubcloudListKeywords +from keywords.cloud_platform.dcmanager.objects.dcmanager_subcloud_deploy_show_output import DcManagerSubcloudDeployShowOutput class DCManagerSubcloudDeployKeywords(BaseKeyword): @@ -178,3 +179,67 @@ class DCManagerSubcloudDeployKeywords(BaseKeyword): success_status = "complete" dc_manager_sc_list_kw = DcManagerSubcloudListKeywords(self.ssh_connection) dc_manager_sc_list_kw.validate_subcloud_status(subcloud_name, success_status) + + def dcmanager_subcloud_deploy_upload(self, update_deploy_params: bool = False, prestaging_images: bool = False, release_version: str = None) -> DcManagerSubcloudDeployShowOutput: + """Uploads deployment files using dcmanager subcloud deploy upload command. + + Args: + update_deploy_params (bool): Whether to update deploy parameters. + prestaging_images (bool): Whether to include prestaging images file. + release_version (str): The release version to use. + + Returns: + DcManagerSubcloudDeployShowOutput: The output object containing the deployment upload details. + + Raises: + Exception: If none of the parameters are provided. + """ + if not update_deploy_params and not prestaging_images: + raise Exception("At least one parameter must be provided: update_deploy_params, prestaging_images") + + cmd_parts = ["dcmanager subcloud deploy upload"] + controller_deployment_assets = ConfigurationManager.get_deployment_assets_config().get_controller_deployment_assets() + + if update_deploy_params: + cmd_parts.extend(["--deploy-playbook", controller_deployment_assets.get_deploy_playbook_file(), "--deploy-overrides", controller_deployment_assets.get_deploy_overrides_file(), "--deploy-chart", controller_deployment_assets.get_deploy_chart_file()]) + + if prestaging_images: + cmd_parts.extend(["--prestage-images", controller_deployment_assets.get_prestage_images_file()]) + + if release_version: + cmd_parts.extend(["--release", release_version]) + + cmd = " ".join(cmd_parts) + output = self.ssh_connection.send(source_openrc(cmd)) + self.validate_success_return_code(self.ssh_connection) + return DcManagerSubcloudDeployShowOutput(output) + + def dcmanager_subcloud_deploy_upload_with_error(self, update_deploy_params: bool = False, prestaging_images: bool = False, release_version: str = None) -> str: + """ + Upload deployment files using dcmanager subcloud deploy upload command (error handling version). + + Args: + update_deploy_params (bool): Whether to update deploy parameters. + prestaging_images (bool): Whether to include prestaging images file. + release_version (str): The release version to use. + + Returns: + str: Raw command output (for error validation). + """ + cmd_parts = ["dcmanager subcloud deploy upload"] + controller_deployment_assets = ConfigurationManager.get_deployment_assets_config().get_controller_deployment_assets() + + if update_deploy_params: + cmd_parts.extend(["--deploy-playbook", controller_deployment_assets.get_deploy_playbook_file(), "--deploy-overrides", controller_deployment_assets.get_deploy_overrides_file(), "--deploy-chart", controller_deployment_assets.get_deploy_chart_file()]) + + if prestaging_images: + cmd_parts.extend(["--prestage-images", controller_deployment_assets.get_prestage_images_file()]) + + if release_version: + cmd_parts.extend(["--release", release_version]) + + cmd = " ".join(cmd_parts) + output = self.ssh_connection.send(source_openrc(cmd)) + if isinstance(output, list) and len(output) > 0: + return "\n".join(line.strip() for line in output) + return output.strip() if isinstance(output, str) else str(output) diff --git a/keywords/cloud_platform/upgrade/objects/software_list_output.py b/keywords/cloud_platform/upgrade/objects/software_list_output.py index fa47a16f..f857b5c5 100644 --- a/keywords/cloud_platform/upgrade/objects/software_list_output.py +++ b/keywords/cloud_platform/upgrade/objects/software_list_output.py @@ -1,5 +1,6 @@ """Software List Output.""" +import re from typing import List from keywords.cloud_platform.system.system_table_parser import SystemTableParser @@ -63,6 +64,23 @@ class SoftwareListOutput: """ return [entry["Release"] for entry in self.output_values if entry["State"] == state] + def get_product_version_by_state(self, state: str) -> List[str]: + """ + Get software version of all releases with a given state. + + Args: + state (str): Desired software release state (e.g., "deployed"). + + Returns: + List[str]: Matching release names. + """ + product_version = [] + for entry in self.output_values: + if entry["State"] == state: + match = re.search(r"(\d+\.\d+)", entry["Release"]) + product_version.append(match.group(1) if match else "") + return product_version + def get_release_state_by_release_name(self, release_name: str) -> str: """ Get the state of a release by its name. diff --git a/testcases/cloud_platform/upgrade/dc/subcloud_deploy/test_subcloud_deploy_upload.py b/testcases/cloud_platform/upgrade/dc/subcloud_deploy/test_subcloud_deploy_upload.py new file mode 100644 index 00000000..52e0adb7 --- /dev/null +++ b/testcases/cloud_platform/upgrade/dc/subcloud_deploy/test_subcloud_deploy_upload.py @@ -0,0 +1,131 @@ +""" +Test cases for dcmanager subcloud deploy upload functionality. + +Notes: + - A "deployed" version corresponds to the active load release. + - An "unavailable" version corresponds to the inactive load release. + - Both deployed and unavailable versions are considered valid release versions. +""" + +from pytest import mark + +from framework.validation.validation import validate_equals, validate_not_equals +from keywords.cloud_platform.dcmanager.dcmanager_subcloud_deploy_keywords import DCManagerSubcloudDeployKeywords +from keywords.cloud_platform.ssh.lab_connection_keywords import LabConnectionKeywords +from keywords.cloud_platform.upgrade.software_list_keywords import SoftwareListKeywords + + +@mark.p2 +def test_subcloud_deploy_upload_with_deployed_release(): + """ + Test dcmanager subcloud deploy upload with deployed release version. + + Test Steps: + - Get SSH connection to the active controller of the system controller + - Retrieve the list of software releases + - Identify a release that is in "deployed" state (active load release version) + - Run "dcmanager subcloud deploy upload" with the deployed release version + - Validate that the software version in the deploy show object matches the selected release version + """ + # Gets the SSH connection to the active controller of the central cloud. + ssh_connection = LabConnectionKeywords().get_active_controller_ssh() + + # Get deployed release version + software_list_keywords = SoftwareListKeywords(ssh_connection) + software_list_output = software_list_keywords.get_software_list() + deployed_version = software_list_output.get_product_version_by_state("deployed") + validate_not_equals(len(deployed_version), 0, "deployed releases found") + + # Execute deploy upload with deployed release version + dcm_sc_deploy_kw = DCManagerSubcloudDeployKeywords(ssh_connection) + deploy_show_obj = dcm_sc_deploy_kw.dcmanager_subcloud_deploy_upload(update_deploy_params=True, release_version=deployed_version[0]).get_dcmanager_subcloud_deploy_show_object() + validate_equals(deployed_version[0], deploy_show_obj.get_software_version(), "version matched") + + +@mark.p2 +def test_subcloud_deploy_upload_with_unavailable_release(): + """ + Test dcmanager subcloud deploy upload with unavailable release version. + + Test Steps: + - Get SSH connection to the active controller of the system controller + - Retrieve the list of software releases + - Identify a release that is in "unavailable" state (inactive load release version) + - Run "dcmanager subcloud deploy upload" with the unavailable release version + - Validate that the software version in the deploy show object matches the selected release version + """ + # Gets the SSH connection to the active controller of the central cloud. + ssh_connection = LabConnectionKeywords().get_active_controller_ssh() + + # Get unavailable release version + software_list_keywords = SoftwareListKeywords(ssh_connection) + software_list_output = software_list_keywords.get_software_list() + + # Find a release that is not in "available" state + unavailable_version = software_list_output.get_product_version_by_state("unavailable") + validate_not_equals(len(unavailable_version), 0, "unavailable releases found") + + # Execute deploy upload with unavailable release version + dcm_sc_deploy_kw = DCManagerSubcloudDeployKeywords(ssh_connection) + deploy_show_obj = dcm_sc_deploy_kw.dcmanager_subcloud_deploy_upload(update_deploy_params=True, release_version=unavailable_version[0]).get_dcmanager_subcloud_deploy_show_object() + validate_equals(unavailable_version[0], deploy_show_obj.get_software_version(), "version matched") + + +@mark.p2 +def test_dcmanager_subcloud_deploy_upload_with_prestaging_images_active_load(): + """ + Test dcmanager subcloud deploy upload with prestaging images using active load release version. + + Test Steps: + - Get SSH connection to the active controller of the system controller + - Retrieve the list of software releases + - Identify a release that is in "deployed" state (active load release version) + - Run "dcmanager subcloud deploy upload" with prestaging images enabled using the deployed release version + - Validate that prestaging images are present in the deploy show object. + - Validate that the software version in the deploy show object matches the selected release version + """ + # Gets the SSH connection to the active controller of the central cloud. + ssh_connection = LabConnectionKeywords().get_active_controller_ssh() + + # Get deployed release version + software_list_keywords = SoftwareListKeywords(ssh_connection) + software_list_output = software_list_keywords.get_software_list() + deployed_version = software_list_output.get_product_version_by_state("deployed") + validate_not_equals(len(deployed_version), 0, "deployed releases found") + + # Execute deploy upload with prestaging images enabled and deployed release version + dcm_sc_deploy_kw = DCManagerSubcloudDeployKeywords(ssh_connection) + deploy_show_obj = dcm_sc_deploy_kw.dcmanager_subcloud_deploy_upload(prestaging_images=True, release_version=deployed_version[0]).get_dcmanager_subcloud_deploy_show_object() + validate_not_equals(deploy_show_obj.get_prestage_images(), None, "Prestage images exist") + validate_equals(deployed_version[0], deploy_show_obj.get_software_version(), "version matched") + + +@mark.p2 +def test_dcmanager_subcloud_deploy_upload_with_prestaging_images_inactive_load(): + """ + Test dcmanager subcloud deploy upload with prestaging images using inactive load release version. + + Test Steps: + - Get SSH connection to the active controller of the system controller + - Retrieve the list of software releases + - Identify a release that is in "unavailable" state (inactive load release version) + - Run "dcmanager subcloud deploy upload" with prestaging images enabled using the unavailable release version + - Validate that prestaging images are present in the deploy show object. + - Validate that the software version in the deploy show object matches the selected release version + """ + # Gets the SSH connection to the active controller of the central cloud. + ssh_connection = LabConnectionKeywords().get_active_controller_ssh() + + # Get unavailable release version + software_list_keywords = SoftwareListKeywords(ssh_connection) + software_list_output = software_list_keywords.get_software_list() + + # Find a release that is not in "available" state + unavailable_version = software_list_output.get_product_version_by_state("unavailable") + validate_not_equals(len(unavailable_version), 0, "unavailable releases found") + + # Execute deploy upload with prestaging images enabled and unavailable release version + dcm_sc_deploy_kw = DCManagerSubcloudDeployKeywords(ssh_connection) + deploy_show_obj = dcm_sc_deploy_kw.dcmanager_subcloud_deploy_upload(prestaging_images=True, release_version=unavailable_version[0]).get_dcmanager_subcloud_deploy_show_object() + validate_not_equals(deploy_show_obj.get_prestage_images(), None, "Prestage images exist") + validate_equals(unavailable_version[0], deploy_show_obj.get_software_version(), "version matched") diff --git a/testcases/cloud_platform/upgrade/dc/subcloud_deploy/test_subcloud_deploy_upload_errors.py b/testcases/cloud_platform/upgrade/dc/subcloud_deploy/test_subcloud_deploy_upload_errors.py new file mode 100644 index 00000000..54c8e945 --- /dev/null +++ b/testcases/cloud_platform/upgrade/dc/subcloud_deploy/test_subcloud_deploy_upload_errors.py @@ -0,0 +1,95 @@ +""" +Negative Test cases for dcmanager subcloud deploy upload functionality. + +Notes: + - A "deployed" version corresponds to the active load release. + - An "unavailable" version corresponds to the inactive load release. + - Both deployed and unavailable versions are considered valid release versions. + - An "invalid" version, such as the second last major release, is considered an invalid release version and is used for negative testing. +""" + +from pytest import mark + +from framework.validation.validation import validate_not_equals, validate_str_contains +from keywords.cloud_platform.dcmanager.dcmanager_subcloud_deploy_keywords import DCManagerSubcloudDeployKeywords +from keywords.cloud_platform.ssh.lab_connection_keywords import LabConnectionKeywords +from keywords.cloud_platform.upgrade.software_list_keywords import SoftwareListKeywords +from keywords.cloud_platform.version_info.cloud_platform_version_manager import CloudPlatformVersionManagerClass + + +@mark.p2 +def test_subcloud_deploy_upload_with_invalid_release(): + """ + Negative testing: Test dcmanager subcloud deploy upload with unavailable release version. + + Test Steps: + - Get SSH connection to the active controller of the system controller + - Retrieve the second last major release version which is an invalid release version + - Run "dcmanager subcloud deploy upload" using invalid release version + - Validate that the upload fails with the expected error message + + Expected Results: + - Error message should indicate the release version is invalid + """ + # Gets the SSH connection to the active controller of the central cloud. + ssh_connection = LabConnectionKeywords().get_active_controller_ssh() + dcm_sc_deploy_kw = DCManagerSubcloudDeployKeywords(ssh_connection) + + # Execute deploy upload with second last major release version which is an invalid version + invalid_version = CloudPlatformVersionManagerClass().get_second_last_major_release().get_name() + error_message = dcm_sc_deploy_kw.dcmanager_subcloud_deploy_upload_with_error(update_deploy_params=True, release_version=invalid_version) + validate_str_contains(error_message, "invalid release version parameter", f"Error message for invalid release version: {invalid_version}") + + +@mark.p2 +def test_subcloud_deploy_upload_without_mandatory_parameters_active_load(): + """ + Negative testing: Test dcmanager subcloud deploy upload without mandatory parameters using active load release. + + Test Steps: + - Get SSH connection to the active controller of the system controller + - Run "dcmanager subcloud deploy upload" without passing any mandatory parameter + - Validate that the error message indicates mandatory arguments are required + + Expected Results: + - Error message should indicate that mandatory parameters are required + """ + # Gets the SSH connection to the active controller of the central cloud. + ssh_connection = LabConnectionKeywords().get_active_controller_ssh() + + # Execute deploy upload without mandatory parameters + dcm_sc_deploy_kw = DCManagerSubcloudDeployKeywords(ssh_connection) + error_message = dcm_sc_deploy_kw.dcmanager_subcloud_deploy_upload_with_error() + validate_str_contains(error_message, "argument --deploy_playbook--deploy_chart is required", "Error message for missing mandatory parameters") + + +@mark.p2 +def test_subcloud_deploy_upload_without_mandatory_parameters_inactive_load(): + """ + Negative testing: Test dcmanager subcloud deploy upload without mandatory parameters using inactive load release. + + Test Steps: + - Get SSH connection to the active controller of the system controller + - Retrieve the list of software releases + - Identify a release that is in "unavailable" state + - Run "dcmanager subcloud deploy upload" for the inactive release without passing mandatory parameters + - Validate that the error message indicates mandatory arguments are required + + Expected Results: + - Error message should indicate that mandatory parameters are required + """ + # Gets the SSH connection to the active controller of the central cloud. + ssh_connection = LabConnectionKeywords().get_active_controller_ssh() + + # Get unavailable release version + software_list_keywords = SoftwareListKeywords(ssh_connection) + software_list_output = software_list_keywords.get_software_list() + + # Find a release that is not in "available" state + unavailable_version = software_list_output.get_product_version_by_state("unavailable") + validate_not_equals(len(unavailable_version), 0, "unavailable releases found") + + # Execute deploy upload without mandatory parameters using unavailable release version + dcm_sc_deploy_kw = DCManagerSubcloudDeployKeywords(ssh_connection) + error_message = dcm_sc_deploy_kw.dcmanager_subcloud_deploy_upload_with_error(release_version=unavailable_version[0]) + validate_str_contains(error_message, "argument --deploy_playbook--deploy_chart is required", "Error message for missing mandatory parameters")