Skip to content

Commit 47a6c77

Browse files
committed
feat(telco-kpis): Add cross-cutting test infrastructure refactorings
Implement shared roles and modules to eliminate code duplication and standardize Telco-KPIs test implementations. ## New Roles **playbooks/telco-kpis/roles/artifact-management/** - Eliminates duplicate artifact collection code across all tests - Standardized artifact workflow: collect → generate JUnit XML → push to shared location → cleanup - Tasks: - `collect-from-bastion.yml` - Fetch artifacts from remote bastion - `generate-junit-xml.yml` - Create JUnit XML from test results - `push-to-shared.yml` - Copy to shared artifact location - `cleanup-old-artifacts.yml` - Remove temporary artifacts - Template: `junit-report.xml.j2` - Standardized JUnit XML format **playbooks/telco-kpis/roles/telco-kpis-defaults/** - Centralized default values for all telco-kpis tests - Provides consistent defaults for: - Spirent configuration (chassis, stcweb, ports, test config) - Artifact directories - Test parameters - Eliminates hardcoded values scattered across playbooks ## Refactorings Applied **kubernetes.core Module Migration:** - Replaced shell commands with kubernetes.core.k8s module for: - Pod deployment (dpdk-testpmd) - Resource querying - Pod deletion verification - Benefits: - Idempotent operations - Better error handling - Structured return values - No shell parsing required **Centralized Configuration:** - Default Spirent settings in telco-kpis-defaults role - Eliminates magic numbers and hardcoded IPs - Single source of truth for test parameters ## Benefits - **Code Reuse:** artifact-management role used across all tests - **Consistency:** Standardized artifact naming and structure - **Maintainability:** Changes to artifact workflow in one place - **Reliability:** kubernetes.core modules more robust than shell commands - **Configuration Management:** Centralized defaults easier to update ## Impact All telco-kpis tests (oslat, cyclictest, ptp, cpu_util, reboot, rfc2544, bios-validation, rds-compare, ztp-timeline) benefit from these refactorings. Related: Telco-KPIs test infrastructure Signed-off-by: Carlos Cardenosa <ccardeno@redhat.com>
1 parent d717507 commit 47a6c77

8 files changed

Lines changed: 213 additions & 0 deletions

File tree

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
# Default values for artifact-management role
3+
# These can be overridden when calling the role
4+
5+
# Required parameters (no defaults - must be provided by caller):
6+
# - artifact_management_test_name
7+
# - artifact_management_spoke_cluster
8+
# - artifact_management_temp_dir
9+
# - artifact_management_test_rc
10+
11+
# Optional parameters with defaults (inherit from telco-kpis-defaults if loaded):
12+
artifact_management_namespace: "{{ telco_kpis_sriov_namespace | default('openshift-sriov-network-operator') }}"
13+
artifact_management_shared_base: "{{ telco_kpis_shared_artifact_base | default('/home/telcov10n/telco-kpis-artifacts') }}"
14+
artifact_management_local_base: "{{ telco_kpis_local_artifact_base | default(lookup('env', 'ARTIFACT_DIR') | default('/artifacts', true)) }}"
15+
artifact_management_test_duration: "{{ duration_seconds | default('600') }}"
16+
17+
# JUnit XML generation options:
18+
# - If artifact_management_junit_source_pattern is defined: Search for existing XML and rename it
19+
# - If not defined: Generate JUnit XML from template
20+
artifact_management_junit_source_pattern: ""
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
# Cleanup old test artifacts from shared location (keep only latest run)
3+
4+
- name: Find old artifact directories for this test type
5+
ansible.builtin.find:
6+
paths: "{{ artifact_management_shared_base }}/{{ artifact_management_spoke_cluster }}"
7+
patterns: "{{ artifact_management_test_name }}-{{ artifact_management_spoke_cluster }}-*"
8+
file_type: directory
9+
register: old_artifact_dirs
10+
11+
- name: Sort artifact directories by timestamp (newest first)
12+
ansible.builtin.set_fact:
13+
sorted_artifacts: "{{ old_artifact_dirs.files | sort(attribute='path', reverse=True) }}"
14+
15+
- name: Identify artifacts to delete (keep only latest)
16+
ansible.builtin.set_fact:
17+
artifacts_to_delete: "{{ sorted_artifacts[1:] }}"
18+
when: sorted_artifacts | length > 1
19+
20+
- name: Remove old artifact directories
21+
ansible.builtin.file:
22+
path: "{{ item.path }}"
23+
state: absent
24+
loop: "{{ artifacts_to_delete | default([]) }}"
25+
when: artifacts_to_delete is defined and artifacts_to_delete | length > 0
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
# Collect artifacts from bastion temporary directory to container /artifacts
3+
4+
- name: List artifacts generated in temp directory
5+
ansible.builtin.find:
6+
paths: "{{ artifact_management_temp_dir }}"
7+
patterns: "*"
8+
recurse: yes
9+
register: artifact_files
10+
11+
- name: Display artifacts found
12+
ansible.builtin.debug:
13+
msg: "Artifacts found: {{ artifact_files.files | map(attribute='path') | list }}"
14+
15+
- name: Create local artifact directory
16+
ansible.builtin.file:
17+
path: "{{ artifact_management_local_base }}/{{ artifact_management_test_name }}-{{ artifact_management_spoke_cluster }}"
18+
state: directory
19+
mode: '0755'
20+
delegate_to: localhost
21+
22+
- name: Fetch artifacts from bastion to local
23+
ansible.builtin.fetch:
24+
src: "{{ item.path }}"
25+
dest: "{{ artifact_management_local_base }}/{{ artifact_management_test_name }}-{{ artifact_management_spoke_cluster }}/"
26+
flat: yes
27+
loop: "{{ artifact_files.files }}"
28+
when: artifact_files.files | length > 0
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
# Generate JUnit XML report from test results
3+
4+
- name: Search for existing JUnit XML file (if pattern provided)
5+
ansible.builtin.find:
6+
paths: "{{ artifact_management_local_base }}/{{ artifact_management_test_name }}-{{ artifact_management_spoke_cluster }}"
7+
patterns: "{{ artifact_management_junit_source_pattern }}"
8+
delegate_to: localhost
9+
register: existing_junit_files
10+
when: artifact_management_junit_source_pattern is defined and artifact_management_junit_source_pattern | length > 0
11+
failed_when: false
12+
13+
- name: Create JUnit format copy for reporter compatibility (rename existing XML)
14+
ansible.builtin.copy:
15+
src: "{{ existing_junit_files.files[0].path }}"
16+
dest: "{{ artifact_management_local_base }}/{{ artifact_management_test_name }}-{{ artifact_management_spoke_cluster }}/junit_{{ artifact_management_test_name }}_{{ artifact_management_spoke_cluster }}.xml"
17+
mode: '0644'
18+
delegate_to: localhost
19+
when:
20+
- artifact_management_junit_source_pattern is defined
21+
- artifact_management_junit_source_pattern | length > 0
22+
- existing_junit_files is defined
23+
- existing_junit_files.files | length > 0
24+
failed_when: false
25+
26+
- name: Generate JUnit XML report from template (if no existing XML)
27+
ansible.builtin.template:
28+
src: junit-report.xml.j2
29+
dest: "{{ artifact_management_local_base }}/{{ artifact_management_test_name }}-{{ artifact_management_spoke_cluster }}/junit_{{ artifact_management_test_name }}_{{ artifact_management_spoke_cluster }}.xml"
30+
mode: '0644'
31+
delegate_to: localhost
32+
when: >
33+
artifact_management_junit_source_pattern is not defined or
34+
artifact_management_junit_source_pattern | length == 0 or
35+
(existing_junit_files is defined and existing_junit_files.files | length == 0)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
# Artifact Management Role - Main Entry Point
3+
# Purpose: Centralized artifact collection, storage, and JUnit XML generation
4+
5+
- name: Validate required parameters
6+
ansible.builtin.assert:
7+
that:
8+
- artifact_management_test_name is defined
9+
- artifact_management_spoke_cluster is defined
10+
- artifact_management_temp_dir is defined
11+
- artifact_management_test_rc is defined
12+
fail_msg: |
13+
Missing required parameters for artifact-management role.
14+
Required: test_name, spoke_cluster, temp_dir, test_rc
15+
16+
- name: Collect artifacts from bastion temp directory
17+
ansible.builtin.include_tasks: collect-from-bastion.yml
18+
19+
- name: Push artifacts to shared persistent location
20+
ansible.builtin.include_tasks: push-to-shared.yml
21+
22+
- name: Generate JUnit XML report
23+
ansible.builtin.include_tasks: generate-junit-xml.yml
24+
25+
- name: Cleanup old artifacts (keep only latest run)
26+
ansible.builtin.include_tasks: cleanup-old-artifacts.yml
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
# Push artifacts to shared persistent location on bastion
3+
4+
- name: Set timestamp for shared artifact directory
5+
ansible.builtin.set_fact:
6+
artifact_timestamp: "{{ lookup('pipe', 'date +%Y%m%d-%H%M%S') }}"
7+
8+
- name: Create shared artifact base directory
9+
ansible.builtin.file:
10+
path: "{{ artifact_management_shared_base }}/{{ artifact_management_spoke_cluster }}"
11+
state: directory
12+
mode: '0755'
13+
14+
- name: Copy artifacts to shared persistent location
15+
ansible.builtin.copy:
16+
src: "{{ artifact_management_temp_dir }}/"
17+
dest: "{{ artifact_management_shared_base }}/{{ artifact_management_spoke_cluster }}/{{ artifact_management_test_name }}-{{ artifact_management_spoke_cluster }}-{{ artifact_timestamp }}/"
18+
remote_src: true
19+
mode: '0755'
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<testsuites>
3+
<testsuite name="{{ artifact_management_test_name }}-{{ artifact_management_spoke_cluster }}" tests="1" failures="{{ '1' if artifact_management_test_rc != 0 else '0' }}" errors="0" time="{{ artifact_management_test_duration }}">
4+
<testcase name="{{ artifact_management_test_name | upper }}-{{ artifact_management_spoke_cluster }}" classname="telco.kpis.{{ artifact_management_test_name }}" time="{{ artifact_management_test_duration }}">
5+
{% if artifact_management_test_rc != 0 %}
6+
<failure message="{{ artifact_management_test_name }} test failed with exit code {{ artifact_management_test_rc }}">
7+
Test failed. Check test artifacts for details.
8+
</failure>
9+
{% endif %}
10+
</testcase>
11+
</testsuite>
12+
</testsuites>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
---
2+
# Telco-KPIs Default Configuration Values
3+
# These defaults can be overridden at playbook or task level
4+
5+
# Git Repository URLs
6+
telco_kpis_ran_integration_repo: "https://gitlab.cee.redhat.com/ran/ran-integration.git"
7+
telco_kpis_ran_integration_branch: "master"
8+
telco_kpis_cnf_gotests_repo: "https://gitlab.cee.redhat.com/cnf/cnf-gotests.git"
9+
telco_kpis_cnf_gotests_branch: "master"
10+
telco_kpis_oslat_repo: "https://gitlab.cee.redhat.com/ran/oslat.git"
11+
telco_kpis_cyclictest_repo: "https://gitlab.cee.redhat.com/ran/cyclictest.git"
12+
telco_kpis_telco_reference_repo: "https://github.com/openshift-kni/telco-reference.git"
13+
telco_kpis_test_scripts_repo: "https://gitlab.cee.redhat.com/ccardeno/telco-kpis-test-local-scripts.git"
14+
15+
# Container Images
16+
telco_kpis_test_runner_image: "telco-kpis-test-runner:latest"
17+
telco_kpis_dpdk_testpmd_image: "quay.io/container-perf-tools/dpdk-testpmd"
18+
19+
# OpenShift Namespaces
20+
telco_kpis_sriov_namespace: "openshift-sriov-network-operator"
21+
telco_kpis_mco_namespace: "openshift-machine-config-operator"
22+
23+
# Artifact Paths
24+
telco_kpis_shared_artifact_base: "/home/telcov10n/telco-kpis-artifacts"
25+
telco_kpis_local_artifact_base: "{{ lookup('env', 'ARTIFACT_DIR') | default('/artifacts', true) }}"
26+
27+
# Default Test Durations
28+
telco_kpis_default_duration_cyclictest: "12h"
29+
telco_kpis_default_duration_oslat: "10m"
30+
telco_kpis_default_duration_ptp: "10m"
31+
telco_kpis_default_duration_cpu_util: "10m"
32+
telco_kpis_default_duration_rfc2544: "1h"
33+
34+
# Default Test Parameters
35+
telco_kpis_default_reboot_count: 6
36+
telco_kpis_default_frame_size: "256"
37+
telco_kpis_default_lat_rate: "0.8"
38+
39+
# Spirent RFC2544 Default Configuration
40+
telco_kpis_default_spirent_chassis: "spt-n4u-mgmt"
41+
telco_kpis_default_spirent_stcweb: "10.16.231.236:8888"
42+
telco_kpis_default_spirent_port1: "//spt-n4u-mgmt/2/6"
43+
telco_kpis_default_spirent_port2: "//spt-n4u-mgmt/2/7"
44+
telco_kpis_default_spirent_config: "spirent_testcfg.xml"
45+
46+
# Environment Variables
47+
telco_kpis_git_ssl_no_verify: "true"
48+
telco_kpis_ran_metrics_url: "https://pushgateway.ran-metrics.telco5g.corp.redhat.com/metrics/job/pipeline1/"

0 commit comments

Comments
 (0)