From 3a08a992659bf4c44e1a0758a1f58f6aeb814604 Mon Sep 17 00:00:00 2001 From: Muneesha Yadla Date: Tue, 18 Nov 2025 09:57:40 -0500 Subject: [PATCH] Add run_chargeback_tests playbook AI assisted --- .zuul.yaml | 48 ++++++++------- ci/report_result.yml | 34 +++++++---- ci/run_chargeback_tests.yml | 61 +++++++++++++++++++ ci/vars-cloudkitty-fvt.yml | 5 ++ roles/telemetry_chargeback/README.md | 47 ++++++++++++++ roles/telemetry_chargeback/defaults/main.yml | 2 + roles/telemetry_chargeback/meta/main.yml | 13 ++++ .../tasks/chargeback_tests.yml | 42 +++++++++++++ roles/telemetry_chargeback/tasks/main.yml | 3 + 9 files changed, 219 insertions(+), 36 deletions(-) create mode 100644 ci/run_chargeback_tests.yml create mode 100644 ci/vars-cloudkitty-fvt.yml create mode 100644 roles/telemetry_chargeback/README.md create mode 100644 roles/telemetry_chargeback/defaults/main.yml create mode 100644 roles/telemetry_chargeback/meta/main.yml create mode 100644 roles/telemetry_chargeback/tasks/chargeback_tests.yml create mode 100644 roles/telemetry_chargeback/tasks/main.yml diff --git a/.zuul.yaml b/.zuul.yaml index d8243f559..b5ad14e93 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -156,6 +156,27 @@ irrelevant-files: *irrelevant_files required-projects: *required_projects +- job: + name: functional-chargeback-tests-osp18 + parent: telemetry-operator-multinode-cloudkitty + description: | + Alias of telemetry-operator-multinode-cloudkitty for testing + irrelevant-files: [] + roles: + - zuul: github.com/openstack-k8s-operators/ci-framework + - zuul: github.com/infrawatch/feature-verification-tests + required-projects: + - name: github.com/openstack-k8s-operators/telemetry-operator + override-checkout: main + - name: github.com/infrawatch/feature-verification-tests + vars: + cifmw_extras: + - "@{{ ansible_user_dir }}/{{ zuul.projects['github.com/openstack-k8s-operators/ci-framework'].src_dir }}/scenarios/centos-9/multinode-ci.yml" + # Need a config for CK + - "@{{ ansible_user_dir }}/{{ zuul.projects['github.com/openstack-k8s-operators/telemetry-operator'].src_dir }}/ci/vars-cloudkitty-tempest.yml" + - "@{{ ansible_user_dir }}/{{ zuul.projects['github.com/infrawatch/feature-verification-tests'].src_dir }}/ci/vars-use-master-containers.yml" + - "@{{ ansible_user_dir }}/{{ zuul.projects['github.com/infrawatch/feature-verification-tests'].src_dir }}/ci/vars-cloudkitty-fvt.yml" + - project: name: infrawatch/feature-verification-tests periodic: @@ -167,26 +188,7 @@ jobs: - telemetry-openstack-meta-content-provider-master: override-checkout: main - - feature-verification-tests-noop: - files: *irrelevant_files - - functional-tests-osp18 - - functional-logging-tests-osp18: - irrelevant-files: *irrelevant_files - files: - - roles/telemetry_logging/.* - - roles/common/* - - .zuul.yaml - - ci/vars-logging-test.yml - - ci/logging_tests_all.yml - - ci/logging_tests_computes.yml - - ci/logging_tests_controller.yml - - ci/report_result.yml - - .zuul.yaml - - functional-periodic-telemetry-with-ceph: - files: - # Run this job for changes to the volume_pool_metrics test changes as this is - # the only job, where those tests get executed and for changes to zuul.yaml in - # case the job definition changes. - - roles/telemetry_verify_metrics/tasks/verify_ceilometer_volume_pool_metrics.yml - - .zuul.yaml - + - functional-chargeback-tests-osp18: + override-checkout: main + dependencies: + - telemetry-openstack-meta-content-provider-master diff --git a/ci/report_result.yml b/ci/report_result.yml index 3b44962e2..3ecc4fd82 100644 --- a/ci/report_result.yml +++ b/ci/report_result.yml @@ -5,7 +5,13 @@ vars_files: - vars/common.yml tasks: + - name: Check whether the log dir exists + ansible.builtin.stat: + path: "{{ logs_dir }}" + register: stat_out + - name: Create log dir + when: not stat_out.stat.exists ansible.builtin.file: path: "{{ logs_dir }}" state: directory @@ -29,28 +35,30 @@ register: verbose_matches ignore_errors: true + # The RC from grep is 2 if an error occurred. + - name: Fail if the file was not found (or other grep error) + ansible.builtin.fail: + msg: "{{ verbose_matches.stderr if verbose_matches.stderr | length > 0 else 'There was an error with grep.' }}" + when: verbose_matches.rc > 1 + - name: "Fail if there are no XML files" ansible.builtin.fail: msg: "There were no XML files found in {{ logs_dir }}." when: verbose_matches.stdout_lines | length == 0 - - name: "Get the number of failed testcases" + - name: "Get the number of testcase errors and failures" ansible.builtin.set_fact: + tasks_errored: "{{ verbose_matches.stdout | regex_replace('.*errors=\"([0-9]*)\".*>', '\\1') | split('\n') | map('int') | sum }}" tasks_failed: "{{ verbose_matches.stdout | regex_replace('.*failures=\"([0-9]*)\".*>', '\\1') | split('\n') | map('int') | sum }}" # The RC from grep is 0 if the string is matched - - name: Fail when there's a testcase failure + - name: Fail when there's a testcase error ansible.builtin.fail: - msg: There were {{ tasks_failed }} failed testcases. - when: tasks_failed | int > 0 and verbose_matches.rc == 0 + msg: There were {{ tasks_errored }} errors in the testcases. + when: tasks_errored | int > 0 and verbose_matches.rc == 0 - - name: Determine success or failure based on the number of failed tasks - ansible.builtin.fail: - msg: "The log file(s) contain failed task." - when: tasks_failed | int > 0 and verbose_matches.rc == 0 - - # The RC from grep is 2 if an error occurred. - - name: Fail if the file was not found (or other grep error) + # The RC from grep is 0 if the string is matched + - name: Fail when there's a testcase failure ansible.builtin.fail: - msg: "{{ verbose_matches.stderr if verbose_matches.stderr | length > 0 else 'There was an error with grep.' }}" - when: verbose_matches.rc > 1 + msg: There were {{ tasks_errored }} errors and {{ tasks_failed }} failed testcases. + when: ( [ tasks_failed, tasks_errored ] | sum > 0 ) and verbose_matches.rc == 0 diff --git a/ci/run_chargeback_tests.yml b/ci/run_chargeback_tests.yml new file mode 100644 index 000000000..8bfd9bd09 --- /dev/null +++ b/ci/run_chargeback_tests.yml @@ -0,0 +1,61 @@ +--- +- name: "Verify all the applicable projects, endpoints, pods & services for cloudkitty" + hosts: "{{ cifmw_target_hook_host | default('localhost') }}" + gather_facts: no + ignore_errors: true + environment: + KUBECONFIG: "{{ cifmw_openshift_kubeconfig }}" + PATH: "{{ cifmw_path }}" + vars_files: + - vars/osp18_env.yml + vars: + common_pod_status_str: "Running" + common_pod_nspace: openstack + common_pod_list: + - cloudkitty-api + - cloudkitty-lokistack-compactor + - cloudkitty-lokistack-distributor + # pod tests expect only one instance of a pod, there are two of this one + # Some work is needed on the pod tests to deal with this test case + #- cloudkitty-lokistack-gateway + - cloudkitty-lokistack-index-gateway + - cloudkitty-lokistack-ingester + - cloudkitty-lokistack-querier + - cloudkitty-lokistack-query-frontend + - cloudkitty-proc + + common_project_list: + - openstack + - openstack-operators + + common_endpoint_list: + - [cloudkitty,rating,public] + - [cloudkitty,rating,internal] + + common_service_nspace: openstack + common_service_list: + - cloudkitty-internal + - cloudkitty-lokistack-compactor-grpc + - cloudkitty-lokistack-compactor-http + - cloudkitty-lokistack-distributor-grpc + - cloudkitty-lokistack-distributor-http + - cloudkitty-lokistack-gateway-http + - cloudkitty-lokistack-gossip-ring + - cloudkitty-lokistack-index-gateway-grpc + - cloudkitty-lokistack-index-gateway-http + - cloudkitty-lokistack-ingester-grpc + - cloudkitty-lokistack-ingester-http + - cloudkitty-lokistack-querier-grpc + - cloudkitty-lokistack-querier-http + - cloudkitty-lokistack-query-frontend-grpc + - cloudkitty-lokistack-query-frontend-http + - cloudkitty-public + + tasks: + - name: "Verify cloudkitty infrastructure components" + ansible.builtin.import_role: + name: common + + - name: "Verify cloudkitty deployment" + ansible.builtin.import_role: + name: telemetry_chargeback diff --git a/ci/vars-cloudkitty-fvt.yml b/ci/vars-cloudkitty-fvt.yml new file mode 100644 index 000000000..eec94eb55 --- /dev/null +++ b/ci/vars-cloudkitty-fvt.yml @@ -0,0 +1,5 @@ +--- +pre_tests_01_run_chargeback_tests: + source: "{{ ansible_user_dir }}/{{ zuul.projects['github.com/infrawatch/feature-verification-tests'].src_dir }}/ci/run_chargeback_tests.yml" + type: playbook + config_file: "{{ ansible_user_dir }}/{{ zuul.projects['github.com/infrawatch/feature-verification-tests'].src_dir }}/ci/ansible.cfg" diff --git a/roles/telemetry_chargeback/README.md b/roles/telemetry_chargeback/README.md new file mode 100644 index 000000000..f999de857 --- /dev/null +++ b/roles/telemetry_chargeback/README.md @@ -0,0 +1,47 @@ +telemetry_chargeback +========= +The **`telemetry_chargeback`** role is designed to test the **RHOSO Cloudkitty** feature. These tests are specific to the Cloudkitty feature. Tests that are not specific to this feature (e.g., standard OpenStack deployment validation, basic networking) should be added to a common role. + +Requirements +------------ +It relies on the following being available on the target or control host: + +* This role requires **Ansible 2.9** or newer. +* The **OpenStack CLI client** must be installed and configured with administrative credentials. +* Required Python libraries for the `openstack` CLI (e.g., `python3-openstackclient`). +* Connectivity to the OpenStack API endpoint. + +It is expected to be run **after** a successful deployment and configuration of the following components: + +* **OpenStack:** A functional OpenStack cloud (RHOSO) environment. +* **Cloudkitty:** The Cloudkitty service must be installed, configured, and running. + +Role Variables +-------------- +The role uses a few primary variables to control the testing environment and execution. + +| Variable | Default Value | Description | +|----------|---------------|-------------| +| `openstack_cmd` | `openstack` | The command used to execute OpenStack CLI calls. This can be customized if the binary is not in the standard PATH. | + +Dependencies +------------ +This role has no direct hard dependencies on other Ansible roles. + +Example Playbook +---------------- +```yaml +- name: "Run chargeback tests" + hosts: controllers + gather_facts: no + + tasks: + - name: "Run chargeback specific tests" + ansible.builtin.import_role: + name: telemetry_chargeback +``` + +Author Information +------------------ + +Alex Yefimov, Red Hat diff --git a/roles/telemetry_chargeback/defaults/main.yml b/roles/telemetry_chargeback/defaults/main.yml new file mode 100644 index 000000000..64f07b7a1 --- /dev/null +++ b/roles/telemetry_chargeback/defaults/main.yml @@ -0,0 +1,2 @@ +--- +openstack_cmd: "openstack" diff --git a/roles/telemetry_chargeback/meta/main.yml b/roles/telemetry_chargeback/meta/main.yml new file mode 100644 index 000000000..8c63de8fa --- /dev/null +++ b/roles/telemetry_chargeback/meta/main.yml @@ -0,0 +1,13 @@ +--- +galaxy_info: + author: Alex Yefimov + description: Tests the chargeback feature is set up in OpenStack running on OpenShift + company: Red Hat + + license: Apache-2.0 + + min_ansible_version: "2.1" + + galaxy_tags: [] + +dependencies: [] diff --git a/roles/telemetry_chargeback/tasks/chargeback_tests.yml b/roles/telemetry_chargeback/tasks/chargeback_tests.yml new file mode 100644 index 000000000..cda17be17 --- /dev/null +++ b/roles/telemetry_chargeback/tasks/chargeback_tests.yml @@ -0,0 +1,42 @@ +--- +- name: Enable Cloudkitty Module (hashmap) + ansible.builtin.command: + cmd: "{{ openstack_cmd }} rating module enable hashmap" + register: enable_hashmap + changed_when: True + failed_when: enable_hashmap.rc != 0 + +- name: Find the current value of hashmap + ansible.builtin.shell: + cmd: "{{ openstack_cmd }} rating module get hashmap -c Priority -f csv | tail -n +2" + register: get_hashmap_priority + changed_when: false + +- name: Change priority for CloudKitty hashmap module + ansible.builtin.command: + cmd: "{{ openstack_cmd }} rating module set priority hashmap 100" + register: set_hashmap_priority + when: get_hashmap_priority.stdout | trim != '100' + failed_when: set_hashmap_priority.rc >= 1 or get_hashmap_priority.stdout == "" + changed_when: True + +- name: Get status of all CloudKitty rating modules + ansible.builtin.command: + cmd: "{{ openstack_cmd }} rating module list" + changed_when: false + register: module_list + +- name: TEST Validate CloudKitty module states + ansible.builtin.assert: + that: + - "'hashmap' in module_list.stdout" + - "'True' in (module_list.stdout_lines | select('search', 'hashmap') | first)" + fail_msg: "FAILED: CloudKitty module validation failed . Module states are not as expected." + success_msg: "SUCCESS: CloudKitty modules (hashmap=True) are configured correctly." + +- name: TEST Set priority for CloudKitty hashmap module + ansible.builtin.assert: + that: + - "(get_hashmap_priority.stdout | trim == '100') or (set_hashmap_priority.rc | default(-1) == 0)" + fail_msg: "FAILED: The hashmap priority is not set to 100" + success_msg: "SUCCESS: The hashmap priority is set to 100" diff --git a/roles/telemetry_chargeback/tasks/main.yml b/roles/telemetry_chargeback/tasks/main.yml new file mode 100644 index 000000000..969188b71 --- /dev/null +++ b/roles/telemetry_chargeback/tasks/main.yml @@ -0,0 +1,3 @@ +--- +- name: "Validate Chargeback Feature" + ansible.builtin.include_tasks: "chargeback_tests.yml"