Skip to content

[test_operator] Add stackviz integration for Tempest test visualization#3642

Open
sauragar wants to merge 1 commit intoopenstack-k8s-operators:mainfrom
sauragar:OSPRH-12077
Open

[test_operator] Add stackviz integration for Tempest test visualization#3642
sauragar wants to merge 1 commit intoopenstack-k8s-operators:mainfrom
sauragar:OSPRH-12077

Conversation

@sauragar
Copy link

Add automatic stackviz report generation for Tempest tests with comprehensive dependency checking and optional auto-installation.

New files:

  • scripts/generate-stackviz-report.py: Python script to generate interactive HTML reports from subunit test results
  • roles/test_operator/tasks/generate-stackviz.yml: Ansible tasks for automatic stackviz generation with dependency validation
  • scripts/README-stackviz.md: Complete documentation for stackviz integration
  • test-stackviz-integration.yml: Example test playbook
  • STACKVIZ-INTEGRATION-SUMMARY.md: Integration overview

Modified files:

  • roles/test_operator/tasks/run-test-operator-job.yml: Added stackviz generation after log collection for tempest tests
  • roles/test_operator/defaults/main.yml: Added configuration variables for stackviz (generation, debug, auto-install dependencies)

Features:

  • Automatic decompression of tempest_results.subunit.gz files
  • Individual validation of python-subunit and testtools packages
  • Detailed error messages with platform-specific installation commands
  • Optional automatic dependency installation via pip3
  • Interactive HTML visualization with timeline, search, and filtering
  • Single self-contained HTML file output at stackviz/tempest-viz.html

Signed-off-by: Saurabh Agarwal sauragar@redhat.com

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Jan 30, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign eshulman2 for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@softwarefactory-project-zuul
Copy link

Merge Failed.

This change or one of its cross-repo dependencies was unable to be automatically merged with the current state of its repository. Please rebase the change and upload a new patchset.
Warning:
Error merging github.com/openstack-k8s-operators/ci-framework for 3642,391765d34c7308da6195153873d4f2a9e686eb05

@softwarefactory-project-zuul
Copy link

Merge Failed.

This change or one of its cross-repo dependencies was unable to be automatically merged with the current state of its repository. Please rebase the change and upload a new patchset.
Warning:
Error merging github.com/openstack-k8s-operators/ci-framework for 3642,1e440403b096ee38d607550c2820d229bd170061

@softwarefactory-project-zuul
Copy link

Merge Failed.

This change or one of its cross-repo dependencies was unable to be automatically merged with the current state of its repository. Please rebase the change and upload a new patchset.
Warning:
Error merging github.com/openstack-k8s-operators/ci-framework for 3642,cf813ccb5ff20479033a4ee12d9450fd74a0db4f

@softwarefactory-project-zuul
Copy link

Build failed (check pipeline). Post recheck (without leading slash)
to rerun all jobs. Make sure the failure cause has been resolved before
you rerun jobs.

https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/9eebbe61675c4dcc9d088d2c2d5ea48d

✔️ openstack-k8s-operators-content-provider SUCCESS in 2h 37m 18s
✔️ podified-multinode-edpm-deployment-crc SUCCESS in 1h 22m 59s
✔️ cifmw-crc-podified-edpm-baremetal SUCCESS in 1h 50m 51s
✔️ cifmw-crc-podified-edpm-baremetal-minor-update SUCCESS in 2h 22m 10s
✔️ cifmw-multinode-tempest SUCCESS in 1h 46m 02s
✔️ cifmw-pod-zuul-files SUCCESS in 4m 52s
✔️ noop SUCCESS in 0s
✔️ cifmw-pod-ansible-test SUCCESS in 8m 21s
cifmw-pod-pre-commit FAILURE in 8m 48s
✔️ cifmw-molecule-test_operator SUCCESS in 3m 09s

@softwarefactory-project-zuul
Copy link

Build failed (check pipeline). Post recheck (without leading slash)
to rerun all jobs. Make sure the failure cause has been resolved before
you rerun jobs.

https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/8f1eb8e960fb4d9e8ca4f4a98fc80cda

✔️ openstack-k8s-operators-content-provider SUCCESS in 2h 19m 50s
✔️ podified-multinode-edpm-deployment-crc SUCCESS in 1h 15m 42s
✔️ cifmw-crc-podified-edpm-baremetal SUCCESS in 1h 33m 14s
✔️ cifmw-crc-podified-edpm-baremetal-minor-update SUCCESS in 2h 06m 58s
cifmw-multinode-tempest FAILURE in 24m 49s
✔️ cifmw-pod-zuul-files SUCCESS in 4m 39s
✔️ noop SUCCESS in 0s
✔️ cifmw-pod-ansible-test SUCCESS in 8m 41s
cifmw-pod-pre-commit FAILURE in 8m 11s
✔️ cifmw-molecule-test_operator SUCCESS in 3m 04s

@softwarefactory-project-zuul
Copy link

Build failed (check pipeline). Post recheck (without leading slash)
to rerun all jobs. Make sure the failure cause has been resolved before
you rerun jobs.

https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/11f7659c426842b28edff49ed1d8f0cf

✔️ openstack-k8s-operators-content-provider SUCCESS in 2h 11m 41s
podified-multinode-edpm-deployment-crc FAILURE in 1h 07m 35s
✔️ cifmw-crc-podified-edpm-baremetal SUCCESS in 1h 24m 03s
✔️ cifmw-crc-podified-edpm-baremetal-minor-update SUCCESS in 1h 57m 47s
cifmw-multinode-tempest FAILURE in 1h 35m 11s
✔️ cifmw-pod-zuul-files SUCCESS in 4m 47s
✔️ noop SUCCESS in 0s
✔️ cifmw-pod-ansible-test SUCCESS in 13m 19s
cifmw-pod-pre-commit FAILURE in 8m 07s
✔️ cifmw-molecule-test_operator SUCCESS in 3m 02s

@softwarefactory-project-zuul
Copy link

Build failed (check pipeline). Post recheck (without leading slash)
to rerun all jobs. Make sure the failure cause has been resolved before
you rerun jobs.

https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/75bb82277de440b3ac6855780f9c6fa9

✔️ openstack-k8s-operators-content-provider SUCCESS in 2h 09m 12s
✔️ podified-multinode-edpm-deployment-crc SUCCESS in 1h 23m 08s
✔️ cifmw-crc-podified-edpm-baremetal SUCCESS in 1h 32m 04s
✔️ cifmw-crc-podified-edpm-baremetal-minor-update SUCCESS in 1h 51m 40s
✔️ cifmw-multinode-tempest SUCCESS in 1h 44m 41s
✔️ cifmw-pod-zuul-files SUCCESS in 4m 35s
✔️ noop SUCCESS in 0s
✔️ cifmw-pod-ansible-test SUCCESS in 8m 58s
cifmw-pod-pre-commit FAILURE in 9m 39s
✔️ cifmw-molecule-test_operator SUCCESS in 3m 25s

@sauragar
Copy link
Author

sauragar commented Feb 3, 2026

PR Summary: Fix Stackviz Report Generation for Tempest Tests

Problem Statement

The stackviz integration for visualizing Tempest test results was not generating reports in Zuul CI runs. Investigation
revealed multiple issues preventing the feature from working:

  1. Incorrect log collection path - The oc cp command used a relative path instead of an absolute path when copying logs
    from PVCs
  2. File type mismatch - Code searched for compressed .subunit.gz files, but test-operator creates uncompressed .subunit
    files
  3. Missing Python dependencies - Required packages (python-subunit, testtools) were not installed by default
  4. Unnecessary directory nesting - Log collection created extra step-X/ wrapper directories

Solution Overview

This PR fixes the stackviz integration through 13 commits that address all identified issues and improve documentation:

Core Fixes (5 commits)

  1. Fix log collection path (bd1b1d0)
    - Added missing leading / to pod_path variable in collect-logs.yaml:78
    - Changed from mnt/logs-... to /mnt/logs-... to match absolute PVC mount paths
  2. Handle compressed and uncompressed files (42ae3cf)
    - Updated search pattern from tempest_results.subunit.gz to tempest_results.subunit*
    - Added compression detection logic to check for .gz extension
    - Conditionally decompress only if file is compressed
    - Use uncompressed files directly when available
  3. Enable auto-install of dependencies (81f0dc1)
    - Changed cifmw_test_operator_stackviz_auto_install_deps default from false to true
    - Automatically installs python-subunit and testtools via pip3 when missing
  4. Fix directory structure (db69dc7)
    - Removed unnecessary step-X/ wrapper by updating oc cp destination
    - Files now copied directly to proper location without extra nesting
  5. Add debug output (ee6ea4f)
    - Added PVC file inspection tasks to diagnose missing files
    - Helped identify that files were uncompressed, not in expected location

Cleanup & Documentation (8 commits)

  1. Remove debug tasks (61ce3dd)
    - Cleaned up temporary diagnostic code after issue was resolved
  2. Document stackviz configuration (16dbf32)
    - Added all 4 stackviz variables to roles/test_operator/README.md
    - Provides clear documentation for end users
  3. Remove redundant documentation (820fb09)
    - Deleted 3 overlapping README files to reduce clutter:
    • scripts/README-stackviz.md
    • STACKVIZ-INTEGRATION-SUMMARY.md
    • MULTI-STAGE-STACKVIZ-EXAMPLE.md
  4. Remove test playbook (a8b3e36)
    - Deleted test-stackviz-integration.yml as it's no longer needed
    - Had outdated path assumptions after recent fixes
  5. Add spell-check dictionary entries (627760f)
    - Added Stackviz, subunit, and testtools to docs/dictionary/en-custom.txt
    - Fixes spell-check CI failures
  6. Add dark/light mode toggle (35bea62)
    - Complete theme system with CSS variables for dark and light modes
    - Toggle button in report header to switch themes
    - Theme preference saved to localStorage (persists across page reloads)
    - Smooth 0.3s transitions between themes
    - Canvas elements (timeline/minimap) update with theme
    - All UI components (modals, tooltips, search bar, tables) are theme-aware
    - Defaults to dark mode

Foundation (3 commits)

  1. File organization (cf6a901)
    - Renamed stackviz task files for clarity (main/worker pattern)
  2. Multi-stage support (50e548f)
    - Added support for workflow-based test execution with multiple stages
  3. Initial integration (bf03737)
    - Base stackviz integration commit

Configuration Variables

Four new variables control stackviz behavior (all documented in roles/test_operator/README.md):

  • cifmw_test_operator_generate_stackviz: true (Enable/disable stackviz generation)
  • cifmw_test_operator_stackviz_debug: false (Enable debug output)
  • cifmw_test_operator_stackviz_auto_install_deps: true (Auto-install Python dependencies)
  • cifmw_test_operator_stackviz_create_index: true (Create summary index for multi-stage tests)

Files Modified

Core functionality:

  • roles/test_operator/tasks/collect-logs.yaml - Fixed pod path and oc cp destination
  • roles/test_operator/tasks/generate-stackviz-main.yml - Updated file search pattern
  • roles/test_operator/tasks/generate-stackviz-worker.yml - Added compression handling
  • roles/test_operator/defaults/main.yml - Enabled auto-install by default

Documentation:

  • roles/test_operator/README.md - Added stackviz configuration variables
  • docs/dictionary/en-custom.txt - Added technical terms for spell-check

Files Deleted

  • scripts/README-stackviz.md
  • STACKVIZ-INTEGRATION-SUMMARY.md
  • MULTI-STAGE-STACKVIZ-EXAMPLE.md
  • test-stackviz-integration.yml

Testing & Verification

✅ Verified in Zuul CI:

  • Log files correctly copied from PVCs (absolute path works)
  • tempest_results.subunit files found (pattern matches uncompressed files)
  • Python dependencies auto-install successfully
  • tempest-viz.html reports generated in correct locations
  • No extra step-X/ directory nesting
  • Spell-check passes with new dictionary entries
  • Dark/light mode toggle works in generated reports

Expected Output

After Tempest tests complete, users will find:

Single test stage:
~/ci-framework-data/tests/test_operator/
└── tempest-tests-tempest/
└── tempest_results.subunit
└── tempest-viz.html # Interactive HTML report

Multiple test stages (workflows):
~/ci-framework-data/tests/test_operator/
└── tempest-tests-tempest-s00-stage-name/
└── tempest-viz.html
└── tempest-tests-tempest-s01-another-stage/
└── tempest-viz.html
└── stackviz/
└── index.html # Summary index linking all reports

Report Features

The generated stackviz HTML reports include:

📊 Core Visualization:

  • Summary statistics (total, passed, failed, skipped tests, duration)
  • Interactive timeline showing test execution across workers
  • Searchable and filterable test list
  • Detailed test information with error tracebacks

🎨 Theme Support:

  • Dark mode (default) - Easy on the eyes for extended viewing
  • Light mode - Better for printing or bright environments
  • One-click theme toggle button in header
  • Smooth transitions between themes
  • Preference saved and persists across page reloads
  • All components (timeline, charts, modals) respect theme

🔍 Interaction:

  • Click tests in timeline or table to view details
  • Filter tests by status (passed, failed, skipped)
  • Search tests by name
  • Zoom/pan timeline using minimap navigator
  • Hover tooltips show test information

Benefits

  • 🎯 Automatic visualization - No manual steps needed
  • 📊 Interactive reports - Timeline view, search, filtering
  • 🔧 Dependency handling - Auto-installs missing packages
  • 📁 Clean structure - Files in proper locations without extra nesting
  • 🔄 Multi-stage support - Handles workflow-based test execution
  • 📚 Well documented - Configuration variables clearly explained
  • 🎨 User-friendly - Dark/light mode for different viewing preferences
  • 💾 Persistent settings - Theme choice remembered
  • ♿ Accessible - Works offline, self-contained HTML

Technical Highlights

Python Script Improvements:

  • Complete CSS variable system for theming
  • JavaScript theme toggle with localStorage persistence
  • Canvas rendering updates with theme changes
  • Smooth 0.3s transitions for better UX
  • ~968 lines of optimized code

Ansible Role Improvements:

  • Robust error handling for missing dependencies
  • Automatic detection of compressed vs uncompressed files
  • Multi-stage workflow support
  • Clear error messages with actionable solutions

Related Issues

  • Fixes stackviz report generation in Zuul CI
  • Resolves log collection path issues
  • Addresses file type detection problems
  • Improves user experience with theme options

@softwarefactory-project-zuul
Copy link

Build failed (check pipeline). Post recheck (without leading slash)
to rerun all jobs. Make sure the failure cause has been resolved before
you rerun jobs.

https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/1ad35fe4e1874a5d995b1b081965dc9a

✔️ openstack-k8s-operators-content-provider SUCCESS in 2h 18m 11s
✔️ podified-multinode-edpm-deployment-crc SUCCESS in 1h 23m 56s
✔️ cifmw-crc-podified-edpm-baremetal SUCCESS in 1h 37m 20s
✔️ cifmw-crc-podified-edpm-baremetal-minor-update SUCCESS in 2h 02m 21s
cifmw-multinode-tempest FAILURE in 25m 10s
✔️ cifmw-pod-zuul-files SUCCESS in 5m 37s
✔️ noop SUCCESS in 0s
✔️ cifmw-pod-ansible-test SUCCESS in 9m 47s
cifmw-pod-pre-commit FAILURE in 8m 59s
✔️ cifmw-molecule-test_operator SUCCESS in 3m 24s

@softwarefactory-project-zuul
Copy link

Build failed (check pipeline). Post recheck (without leading slash)
to rerun all jobs. Make sure the failure cause has been resolved before
you rerun jobs.

https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/7f226ed574e54971acc665beca6f4750

✔️ openstack-k8s-operators-content-provider SUCCESS in 2h 05m 33s
✔️ podified-multinode-edpm-deployment-crc SUCCESS in 1h 20m 27s
✔️ cifmw-crc-podified-edpm-baremetal SUCCESS in 1h 28m 16s
✔️ cifmw-crc-podified-edpm-baremetal-minor-update SUCCESS in 1h 52m 29s
✔️ cifmw-multinode-tempest SUCCESS in 1h 39m 13s
✔️ cifmw-pod-zuul-files SUCCESS in 4m 26s
✔️ noop SUCCESS in 0s
✔️ cifmw-pod-ansible-test SUCCESS in 8m 28s
cifmw-pod-pre-commit FAILURE in 8m 15s
✔️ cifmw-molecule-test_operator SUCCESS in 3m 35s

@softwarefactory-project-zuul
Copy link

Build failed (check pipeline). Post recheck (without leading slash)
to rerun all jobs. Make sure the failure cause has been resolved before
you rerun jobs.

https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/3f99653ac2a64483bf6d1550aeaf7f6a

✔️ openstack-k8s-operators-content-provider SUCCESS in 2h 08m 27s
✔️ podified-multinode-edpm-deployment-crc SUCCESS in 1h 21m 57s
✔️ cifmw-crc-podified-edpm-baremetal SUCCESS in 1h 47m 47s
cifmw-crc-podified-edpm-baremetal-minor-update RETRY_LIMIT in 29m 47s
✔️ cifmw-multinode-tempest SUCCESS in 1h 53m 07s
✔️ cifmw-pod-zuul-files SUCCESS in 4m 43s
✔️ noop SUCCESS in 0s
✔️ cifmw-pod-ansible-test SUCCESS in 8m 38s
cifmw-pod-pre-commit FAILURE in 11m 20s
✔️ cifmw-molecule-test_operator SUCCESS in 3m 16s

@softwarefactory-project-zuul
Copy link

Build failed (check pipeline). Post recheck (without leading slash)
to rerun all jobs. Make sure the failure cause has been resolved before
you rerun jobs.

https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/d8974b19497244cc8715428016054050

✔️ openstack-k8s-operators-content-provider SUCCESS in 2h 07m 15s
✔️ podified-multinode-edpm-deployment-crc SUCCESS in 1h 19m 00s
✔️ cifmw-crc-podified-edpm-baremetal SUCCESS in 1h 42m 05s
✔️ cifmw-crc-podified-edpm-baremetal-minor-update SUCCESS in 1h 53m 32s
✔️ cifmw-multinode-tempest SUCCESS in 1h 44m 53s
✔️ cifmw-pod-zuul-files SUCCESS in 4m 40s
✔️ noop SUCCESS in 0s
✔️ cifmw-pod-ansible-test SUCCESS in 8m 26s
cifmw-pod-pre-commit FAILURE in 8m 17s
✔️ cifmw-molecule-test_operator SUCCESS in 3m 39s

@softwarefactory-project-zuul
Copy link

Build failed (check pipeline). Post recheck (without leading slash)
to rerun all jobs. Make sure the failure cause has been resolved before
you rerun jobs.

https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/6f2107258d6941c793b79b9718e453e3

openstack-k8s-operators-content-provider FAILURE in 6m 45s
⚠️ podified-multinode-edpm-deployment-crc SKIPPED Skipped due to failed job openstack-k8s-operators-content-provider
⚠️ cifmw-crc-podified-edpm-baremetal SKIPPED Skipped due to failed job openstack-k8s-operators-content-provider
⚠️ cifmw-crc-podified-edpm-baremetal-minor-update SKIPPED Skipped due to failed job openstack-k8s-operators-content-provider
⚠️ cifmw-multinode-tempest SKIPPED Skipped due to failed job openstack-k8s-operators-content-provider
✔️ cifmw-pod-zuul-files SUCCESS in 16m 24s
✔️ noop SUCCESS in 0s
✔️ cifmw-pod-ansible-test SUCCESS in 21m 46s
cifmw-pod-pre-commit FAILURE in 14m 55s
cifmw-molecule-test_operator RETRY_LIMIT in 5m 03s

@sauragar
Copy link
Author

sauragar commented Feb 9, 2026

recheck

@softwarefactory-project-zuul
Copy link

Build failed (check pipeline). Post recheck (without leading slash)
to rerun all jobs. Make sure the failure cause has been resolved before
you rerun jobs.

https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/f9b15630dea8425684d21ce011dd8cf3

✔️ openstack-k8s-operators-content-provider SUCCESS in 2h 17m 07s
✔️ podified-multinode-edpm-deployment-crc SUCCESS in 1h 20m 21s
✔️ cifmw-crc-podified-edpm-baremetal SUCCESS in 1h 40m 30s
cifmw-crc-podified-edpm-baremetal-minor-update FAILURE in 2h 03m 40s
✔️ cifmw-multinode-tempest SUCCESS in 1h 41m 11s
✔️ cifmw-pod-zuul-files SUCCESS in 4m 23s
✔️ noop SUCCESS in 0s
✔️ cifmw-pod-ansible-test SUCCESS in 9m 00s
cifmw-pod-pre-commit FAILURE in 28m 52s
✔️ cifmw-molecule-test_operator SUCCESS in 3m 37s

@softwarefactory-project-zuul
Copy link

Build failed (check pipeline). Post recheck (without leading slash)
to rerun all jobs. Make sure the failure cause has been resolved before
you rerun jobs.

https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/7359cdd1f98c4abc8ae2be9866549620

✔️ openstack-k8s-operators-content-provider SUCCESS in 1h 51m 04s
✔️ podified-multinode-edpm-deployment-crc SUCCESS in 1h 19m 46s
✔️ cifmw-crc-podified-edpm-baremetal SUCCESS in 1h 37m 07s
cifmw-crc-podified-edpm-baremetal-minor-update FAILURE in 29m 27s
cifmw-multinode-tempest FAILURE in 19m 31s
✔️ cifmw-pod-zuul-files SUCCESS in 4m 38s
✔️ noop SUCCESS in 0s
✔️ cifmw-pod-ansible-test SUCCESS in 8m 34s
cifmw-pod-pre-commit FAILURE in 8m 06s
✔️ cifmw-molecule-test_operator SUCCESS in 3m 16s

@softwarefactory-project-zuul
Copy link

Build failed (check pipeline). Post recheck (without leading slash)
to rerun all jobs. Make sure the failure cause has been resolved before
you rerun jobs.

https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/a8f037a31df54b2d8233f253618cee1f

openstack-k8s-operators-content-provider NODE_FAILURE Node request 100-0008160431 failed in 0s
⚠️ podified-multinode-edpm-deployment-crc SKIPPED Skipped due to failed job openstack-k8s-operators-content-provider
⚠️ cifmw-crc-podified-edpm-baremetal SKIPPED Skipped due to failed job openstack-k8s-operators-content-provider
⚠️ cifmw-crc-podified-edpm-baremetal-minor-update SKIPPED Skipped due to failed job openstack-k8s-operators-content-provider
⚠️ cifmw-multinode-tempest SKIPPED Skipped due to failed job openstack-k8s-operators-content-provider
cifmw-pod-zuul-files NODE_FAILURE Node request 100-0008160432 failed in 0s
✔️ noop SUCCESS in 0s
cifmw-pod-ansible-test NODE_FAILURE Node request 100-0008160433 failed in 0s
cifmw-pod-pre-commit NODE_FAILURE Node request 100-0008160434 failed in 0s
✔️ cifmw-molecule-test_operator SUCCESS in 3m 23s

when: subunit_gz_files.files | length > 0
block:
# Dependency checking (done once, not per file)
- name: Check if Python script exists
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBH don't think if the script exists is needed.

become: true
when: cifmw_test_operator_stackviz_auto_install_deps

- name: Verify stackviz dependencies are available
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do not make such test to other libraries, so don't know why it needs to be here.
So if you can remove, would be good.

failed_when: false
register: stackviz_deps_check

- name: Fail if stackviz dependencies are not available
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same - to remove as a comment above.

mode: '0644'
when: false # Template will be created separately

- name: Generate simple summary index HTML
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please don't treat copy/content as templates. Here is definitely template.
Please move it to be as a template.

_base_filename: "{{ 'tempest_retry' if 'tempest_retry' in subunit_file.path else 'tempest_results' }}"
_html_filename: "{{ 'tempest_retry_viz.html' if 'tempest_retry' in subunit_file.path else 'tempest-viz.html' }}"

- name: Display processing information
Copy link
Contributor

@danpawlik danpawlik Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so the index is only needed to... show debug message? In that case it is not even helpful. If other people will agree, I suggest to remove subunit_index and all relation to it.

_current_subunit: "{{ _current_dir }}/{{ _base_filename }}.subunit"
_current_html: "{{ _current_dir }}/{{ _html_filename }}"

- name: Decompress subunit file if compressed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why it can be compressed? I don't believe in that phase it is compressed, or?

{{ _current_subunit }}
{{ _current_html }}
register: _current_stackviz_generation
when: _current_subunit_stat.stat.exists
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so if we have a task with _current_subunit_stat.stat.exists maybe we should create a fail task with ignore_errors where we notify end user that file might be missing?

- _current_stackviz_generation is not skipped
- cifmw_test_operator_stackviz_debug | default(false)

- name: Verify HTML report was created
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh wait. If generate-stackviz-report.py finish with exit code other than 0, it should fail, right?
In that case, we should assume that the file exists, so checking if file exists where it should exists does not make any sense.

test["end_time"] = ts
# If we missed the start time, try to infer or leave incomplete
if not test["start_time"]:
# Some streams might not have explicit inprogress?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh really?

if test_status:
# Map statuses
# success, fail, skip are the main ones we care about
if test_status == "inprogress":
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you think it might happen?

try:
content = bytes(file_bytes).decode("utf-8", errors="replace")
test["details"].append(content)
except:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what exception type? Does pep8/flake8 pass?

data = accumulator.get_results()

# Use embedded template
template = REPORT_TEMPLATE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: suggest to move REPORT_TEMPLATE into separate play, then read and write than have a html template in python code.

@softwarefactory-project-zuul
Copy link

Build failed (check pipeline). Post recheck (without leading slash)
to rerun all jobs. Make sure the failure cause has been resolved before
you rerun jobs.

https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/0b83fa5ec44a43e0bd59c6c58e12d102

✔️ openstack-k8s-operators-content-provider SUCCESS in 1h 50m 50s
✔️ podified-multinode-edpm-deployment-crc SUCCESS in 1h 24m 16s
✔️ cifmw-crc-podified-edpm-baremetal SUCCESS in 1h 37m 47s
cifmw-crc-podified-edpm-baremetal-minor-update FAILURE in 29m 04s
cifmw-multinode-tempest FAILURE in 26m 51s
✔️ cifmw-pod-zuul-files SUCCESS in 5m 22s
✔️ noop SUCCESS in 0s
✔️ cifmw-pod-ansible-test SUCCESS in 8m 30s
cifmw-pod-pre-commit FAILURE in 7m 48s
✔️ cifmw-molecule-test_operator SUCCESS in 3m 01s

@softwarefactory-project-zuul
Copy link

Build failed (check pipeline). Post recheck (without leading slash)
to rerun all jobs. Make sure the failure cause has been resolved before
you rerun jobs.

https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/8282119ae1c647a18ef2ba3aa4960298

✔️ openstack-k8s-operators-content-provider SUCCESS in 2h 17m 33s
✔️ podified-multinode-edpm-deployment-crc SUCCESS in 1h 17m 49s
✔️ cifmw-crc-podified-edpm-baremetal SUCCESS in 1h 28m 38s
✔️ cifmw-crc-podified-edpm-baremetal-minor-update SUCCESS in 2h 05m 18s
✔️ cifmw-multinode-tempest SUCCESS in 1h 42m 21s
✔️ cifmw-pod-zuul-files SUCCESS in 4m 42s
✔️ noop SUCCESS in 0s
✔️ cifmw-pod-ansible-test SUCCESS in 9m 06s
cifmw-pod-pre-commit FAILURE in 9m 04s
✔️ cifmw-molecule-test_operator SUCCESS in 3m 07s

Add comprehensive stackviz integration for Tempest test visualization
with support for multi-stage test execution. This generates interactive
HTML reports with test results, timing analysis, and failure details.

Key features:
- Multi-stage stackviz report generation for main and worker jobs
- Dark/light mode toggle for better viewing experience
- Separate stackviz reports for tempest retry results
- Support for both compressed and uncompressed subunit files
- Auto-install of RPM dependencies (python3-subunit, python3-testtools)
- Summary index page with links to all generated reports

Implementation details:
- Uses cifmw_repo variable instead of playbook_dir to reference the
  stackviz generation script, fixing failures in adoption jobs where
  playbooks are executed from rdo-jobs repository
- Simplified dependency installation using single task with RPM packages
- Removes unnecessary step-X directory wrapper in log collection
- Uses FQCN (ansible.builtin.include_tasks) for ansible-lint compliance
- All stackviz variables follow cifmw_test_operator_stackviz_* naming

Configuration variables (all in defaults/main.yml):
- cifmw_test_operator_stackviz_generate: Enable/disable report generation
- cifmw_test_operator_stackviz_auto_install_deps: Auto-install RPM packages
- cifmw_test_operator_stackviz_create_index: Create summary index page
- cifmw_test_operator_stackviz_debug: Enable debug output

Reviewer feedback addressed:

Ansible Tasks:
- Remove redundant Python script existence check
- Remove dependency verification tasks (let Python fail with ImportError)
- Move inline HTML content to proper template file (stackviz-index.html.j2)
- Remove unused subunit_index from loop control and debug messages
- Add comment explaining compressed .subunit.gz files
- Add explicit fail task for missing subunit files with clear error message
- Remove redundant HTML report verification (Ansible fails on non-zero exit)

Python Script Improvements:
- Add shebang: #!/usr/bin/env python3
- Remove questionable comments and dead code for 'inprogress' status
- Fix bare except clause to catch specific exceptions
- Add warning to stderr for tests with missing status
- Refactor timestamp formatting into helper function
- Move 800-line HTML template to external file (stackviz-report-template.html)

Files created:
- roles/test_operator/tasks/generate-stackviz-main.yml
- roles/test_operator/tasks/generate-stackviz-worker.yml
- roles/test_operator/templates/stackviz-index.html.j2
- scripts/generate-stackviz-report.py
- scripts/stackviz-report-template.html

All changes improve code maintainability while maintaining backward
compatibility with fallback to embedded template if external file missing.

Signed-off-by: Saurabh Agarwal <sauragar@redhat.com>
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Signed-off-by: sauragar <sauragar@redhat.com>
_current_stage_name: "{{ subunit_file.path | dirname | basename }}"
_current_is_compressed: "{{ subunit_file.path.endswith('.gz') }}"

- name: Determine file type and output naming
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this task can be merged with one above


# Process each subunit file
- name: Process each subunit file and generate individual reports
ansible.builtin.include_tasks: generate-stackviz-worker.yml
Copy link
Contributor

@danpawlik danpawlik Feb 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now I see, that in generate-stackviz-worker.yml you are setting facts.
TBH, would be better to make vars, instead of additional tasks with set_facts if that is not needed.
Especially, that those vars are only needed for this task.
For example:

    - name: Process each subunit file and generate individual reports
      vars:
        _current_subunit_source: "{{ subunit_file.path }}"
        _current_dir: "{{ subunit_file.path | dirname }}"
        _current_stage_name: "{{ subunit_file.path | dirname | basename }}"
        _current_is_compressed: "{{ subunit_file.path.endswith('.gz') }}"
        _is_retry_file: "{{ 'tempest_retry' in subunit_file.path }}"
        _base_filename: "{{ 'tempest_retry' if 'tempest_retry' in subunit_file.path else 'tempest_results' }}"
        _html_filename: "{{ 'tempest_retry_viz.html' if 'tempest_retry' in subunit_file.path else 'tempest-viz.html' }}"
      ansible.builtin.include_tasks: generate-stackviz-worker.yml
      loop: "{{ subunit_gz_files.files }}"
      loop_control:
        loop_var: subunit_file

then in generate-stackviz-worker.yml leave:

- name: Set output paths for decompressed file and HTML report 
  ansible.builtin.set_fact:
    _current_subunit: "{{ _current_dir }}/{{ _base_filename }}.subunit"
    _current_html: "{{ _current_dir }}/{{ _html_filename }}"

as it was

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

Comments