From e35b27ad3b3f5e5e02415ea9dc9c9eeac112c2d2 Mon Sep 17 00:00:00 2001 From: devanshjain Date: Thu, 30 Oct 2025 21:18:41 +0000 Subject: [PATCH 1/4] Add framework version tracking and update reports --- VERSION | 1 + docs/CHANGELOG.md | 13 ++++++++++++ scripts/sap_automation_qa.sh | 19 +++++++++++------ scripts/utils.sh | 23 +++++++++++++++++++++ src/modules/render_html_report.py | 11 ++++++++++ src/roles/misc/tasks/render-html-report.yml | 1 + src/templates/config_checks_report.html | 2 +- src/templates/report.html | 2 +- 8 files changed, 64 insertions(+), 8 deletions(-) create mode 100644 VERSION diff --git a/VERSION b/VERSION new file mode 100644 index 00000000..afaf360d --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +1.0.0 \ No newline at end of file diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 6361e43e..eca1e34e 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,3 +1,16 @@ # Changelog All notable changes to this project will be documented in this file. + + +## 1.0.0 +Release Date: 11-04-2025 + +1. High Availability Functional Tests: + - Added comprehensive functional tests for High Availability (HA) configurations for SAP HANA Database with scale-up architecture. + - Added functional tests for HA configurations for SAP Central Services (ASCS) with Primary and Secondary nodes for ENSA1 and ENSA2 system types. + - Support for running HA functional tests for systems with new HANA topology - SAP HANA SR-angi. + - Offline Validation for HA configurations for SAP HANA Database and Central Services. +2. Configuration Checks (preview release): + - Initial implementation of configuration checks for SAP systems. + - Support for validating SAP systems with HANA/DB2 database types. diff --git a/scripts/sap_automation_qa.sh b/scripts/sap_automation_qa.sh index 89c4d555..58ca35ea 100755 --- a/scripts/sap_automation_qa.sh +++ b/scripts/sap_automation_qa.sh @@ -348,6 +348,7 @@ retrieve_secret_from_key_vault() { # :param system_params: The path to the SAP parameters file. # :param auth_type: The authentication type (e.g., "SSHKEY", "VMPASSWORD"). # :param system_config_folder: The path to the system configuration folder. +# :param framework_version: The framework version from VERSION file. # :return: None. Exits with the return code of the ansible-playbook command. run_ansible_playbook() { local playbook_name=$1 @@ -355,6 +356,7 @@ run_ansible_playbook() { local system_params=$3 local auth_type=$4 local system_config_folder=$5 + local framework_version=$6 local extra_vars="" if [[ -n "$TEST_GROUPS" || -n "$TEST_CASES" ]]; then @@ -377,7 +379,8 @@ run_ansible_playbook() { if [[ "$OFFLINE_MODE" == "true" ]]; then log "INFO" "Offline mode: Skipping SSH authentication setup" command="ansible-playbook ${cmd_dir}/../src/$playbook_name.yml -i $system_hosts \ - -e @$VARS_FILE -e @$system_params -e '_workspace_directory=$system_config_folder' $extra_vars --connection=local" + -e @$VARS_FILE -e @$system_params -e '_workspace_directory=$system_config_folder' \ + -e \"framework_version=$framework_version\" $extra_vars --connection=local" else # Set local secret_id and key_vault_id if defined local secret_id=$(grep "^secret_id:" "$system_params" | awk '{split($0,a,": "); print a[2]}' | xargs || true) @@ -401,7 +404,8 @@ run_ansible_playbook() { check_file_exists "$temp_file" \ "Temporary SSH key file not found. Please check the Key Vault secret ID." command="ansible-playbook ${cmd_dir}/../src/$playbook_name.yml -i $system_hosts --private-key $temp_file \ - -e @$VARS_FILE -e @$system_params -e '_workspace_directory=$system_config_folder' $extra_vars" + -e @$VARS_FILE -e @$system_params -e '_workspace_directory=$system_config_folder' \ + -e \"framework_version=$framework_version\" $extra_vars" else local ssh_key_dir="${cmd_dir}/../WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME" local ssh_key="" @@ -433,7 +437,8 @@ run_ansible_playbook() { chmod 600 "$ssh_key" command="ansible-playbook ${cmd_dir}/../src/$playbook_name.yml -i $system_hosts --private-key $ssh_key \ - -e @$VARS_FILE -e @$system_params -e '_workspace_directory=$system_config_folder' $extra_vars" + -e @$VARS_FILE -e @$system_params -e '_workspace_directory=$system_config_folder' \ + -e \"framework_version=$framework_version\" $extra_vars" fi elif [[ "$auth_type" == "VMPASSWORD" ]]; then @@ -447,14 +452,14 @@ run_ansible_playbook() { "Temporary password file not found. Please check the Key Vault secret ID." command="ansible-playbook ${cmd_dir}/../src/$playbook_name.yml -i $system_hosts \ --extra-vars 'ansible_ssh_pass=$(cat $temp_file)' --extra-vars @$VARS_FILE -e @$system_params \ - -e '_workspace_directory=$system_config_folder' $extra_vars" + -e '_workspace_directory=$system_config_folder' -e \"framework_version=$framework_version\" $extra_vars" else local password_file="${cmd_dir}/../WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME/password" check_file_exists "$password_file" \ "password file not found in WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME directory." command="ansible-playbook ${cmd_dir}/../src/$playbook_name.yml -i $system_hosts \ --extra-vars 'ansible_ssh_pass=$(cat $password_file)' --extra-vars @$VARS_FILE -e @$system_params \ - -e '_workspace_directory=$system_config_folder' $extra_vars" + -e '_workspace_directory=$system_config_folder' -e \"framework_version=$framework_version\" $extra_vars" fi else @@ -542,7 +547,9 @@ main() { playbook_name=$(get_playbook_name "$TEST_TYPE" "$SAP_FUNCTIONAL_TEST_TYPE" "$OFFLINE_MODE") log "INFO" "Using playbook: $playbook_name." - run_ansible_playbook "$playbook_name" "$SYSTEM_HOSTS" "$SYSTEM_PARAMS" "$AUTHENTICATION_TYPE" "$SYSTEM_CONFIG_FOLDER" + FRAMEWORK_VERSION=$(read_version_file) + log "INFO" "Framework version: $FRAMEWORK_VERSION" + run_ansible_playbook "$playbook_name" "$SYSTEM_HOSTS" "$SYSTEM_PARAMS" "$AUTHENTICATION_TYPE" "$SYSTEM_CONFIG_FOLDER" "$FRAMEWORK_VERSION" } diff --git a/scripts/utils.sh b/scripts/utils.sh index 2600e47b..11b68bdc 100644 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -233,3 +233,26 @@ install_packages() { log "INFO" "All required packages are already installed." fi } + + +# Function to read VERSION file +# Looks for VERSION file in the project root directory +# :return: The version string from the VERSION file +read_version_file() { + local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + local project_root="$(cd "$script_dir/.." && pwd)" + local version_file="$project_root/VERSION" + + if [[ -f "$version_file" ]]; then + local version + version=$(<"$version_file") + version=$(echo "$version" | tr -d '[:space:]') + if [[ -z "$version" ]]; then + log "ERROR" "VERSION file is empty at: $version_file" + fi + echo "$version" + else + log "ERROR" "VERSION file not found at: $version_file" + exit 1 + fi +} \ No newline at end of file diff --git a/src/modules/render_html_report.py b/src/modules/render_html_report.py index 7a6ffdb7..6b837f39 100644 --- a/src/modules/render_html_report.py +++ b/src/modules/render_html_report.py @@ -53,6 +53,11 @@ - Reports will be created in {workspace_directory}/quality_assurance/ type: str required: true + framework_version: + description: + - Version of the SAP Automation QA framework + type: str + required: false author: - Microsoft Corporation notes: @@ -71,6 +76,7 @@ test_group_name: "hana_cluster_validation" report_template: "{{ lookup('file', 'templates/report_template.html') }}" workspace_directory: "/var/log/sap-automation-qa" + framework_version: "1.0.0" register: report_result - name: Show path to generated report @@ -115,6 +121,7 @@ def __init__( workspace_directory: str, test_case_results: List[Dict[str, Any]] = [], system_info: Dict[str, Any] = {}, + framework_version: str = "unknown", ): super().__init__() self.test_group_invocation_id = test_group_invocation_id @@ -128,6 +135,7 @@ def __init__( ) self.test_case_results = test_case_results or [] self.system_info = system_info or {} + self.framework_version = framework_version def read_log_file(self) -> List[Dict[str, Any]]: """ @@ -184,6 +192,7 @@ def render_report(self, test_case_results: List[Dict[str, Any]]) -> None: "%m/%d/%Y, %I:%M:%S %p" ), "system_info": self.system_info, + "framework_version": self.framework_version, } ) ) @@ -205,6 +214,7 @@ def run_module() -> None: workspace_directory=dict(type="str", required=True), test_case_results=dict(type="list", required=False), system_info=dict(type="dict", required=False), + framework_version=dict(type="str", required=False), ) module = AnsibleModule(argument_spec=module_args, supports_check_mode=True) @@ -216,6 +226,7 @@ def run_module() -> None: workspace_directory=module.params["workspace_directory"], test_case_results=module.params.get("test_case_results", []), system_info=module.params.get("system_info", {}), + framework_version=module.params.get("framework_version", "unknown"), ) test_case_results = ( diff --git a/src/roles/misc/tasks/render-html-report.yml b/src/roles/misc/tasks/render-html-report.yml index 1e30fb64..6cf68630 100644 --- a/src/roles/misc/tasks/render-html-report.yml +++ b/src/roles/misc/tasks/render-html-report.yml @@ -22,4 +22,5 @@ workspace_directory: "{{ _workspace_directory }}" test_case_results: "{{ all_results | default([]) }}" system_info: "{{ system_info | default({}) }}" + framework_version: "{{ framework_version | default('unknown') }}" register: report_file_path diff --git a/src/templates/config_checks_report.html b/src/templates/config_checks_report.html index f8d0c1f1..74b4ac9c 100644 --- a/src/templates/config_checks_report.html +++ b/src/templates/config_checks_report.html @@ -1391,7 +1391,7 @@

Report generated on: {{ report_generation_time }} +