Skip to content

Add virt-who Deploy Config Ansible REX job tests for all hypervisors - #22218

Draft
jnagare-redhat wants to merge 3 commits into
SatelliteQE:masterfrom
jnagare-redhat:virtwho-ansible-rex-job-tests
Draft

Add virt-who Deploy Config Ansible REX job tests for all hypervisors#22218
jnagare-redhat wants to merge 3 commits into
SatelliteQE:masterfrom
jnagare-redhat:virtwho-ansible-rex-job-tests

Conversation

@jnagare-redhat

@jnagare-redhat jnagare-redhat commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Added test coverage for the 'Deploy virt-who Config' Ansible REX job template across all hypervisor types (ESX, HyperV, KubeVirt, Libvirt, Nutanix) via both API and UI paths — 10 new test cases total
  • Both API and UI deploy paths now target a content host (instead of Satellite/Capsule) by registering it to CDN for virt-who package availability, then to Satellite for REX job targeting
  • Removed capsule dependency from deploy_configure_by_job_ui — no longer requires module_capsule_configured or smart proxy setup
  • Extracted common setup into reusable helpers (_setup_virtwho_guest and _register_content_host_with_virtwho) to eliminate duplication across all three deploy functions (API job, UI job, script)
  • Removed register_sat_and_enable_aps_repo dependency from job-based deploy fixtures since content hosts now get virt-who from CDN directly
  • Simplified existing deploy fixtures by removing the unused 'id' deploy type, keeping only 'script'
  • Cleaned up unused helper functions and updated log pattern matching for newer Satellite versions

Verifies: SAT-46996

Airgun PR: SatelliteQE/airgun#2488

Test plan

  • Run API deploy-by-job tests: pytest tests/foreman/virtwho/api/test_esx_sca.py -k test_positive_deploy_configure_by_job
  • Run UI deploy-by-job tests: pytest tests/foreman/virtwho/ui/test_esx_sca.py -k test_positive_deploy_configure_by_job
  • Verify existing deploy-by-script tests still pass: pytest tests/foreman/virtwho/api/test_esx_sca.py -k test_positive_deploy_configure_by_script
  • Note: API and UI deploy-by-job tests should NOT be run in parallel against the same Satellite — they share ESX hypervisor/guest state and will conflict

🤖 Generated with Claude Code

Summary by Sourcery

Add new coverage for deploying virt-who configuration via the Ansible REX job against a content host, and refactor shared virt-who deployment logic to support all hypervisor types.

New Features:

  • Introduce API and UI helpers to deploy virt-who via the 'Deploy virt-who Config' Ansible REX job targeting a registered content host.
  • Add API and UI virt-who job-based tests for ESX, HyperV, KubeVirt, Libvirt, and Nutanix hypervisors validating hypervisor-guest mapping on the content host.

Enhancements:

  • Refactor virt-who deployment utilities to share guest setup and registration logic across job-based and script-based flows.
  • Update RHSM log parsing and waiting logic to support newer virt-who mapping messages.
  • Simplify virt-who deploy fixtures by removing hammer-based deploy variants and relying solely on script and job-based execution paths.

Tests:

  • Add pytest fixtures for deploying virt-who configuration via Ansible REX job (API and UI) against a content host.
  • Extend UI virt-who SCA test suites to validate REX job deployment for all supported hypervisors and mapping visibility in the UI.
  • Extend API virt-who SCA test suites to validate REX job deployment success and hypervisor/guest mapping for all supported hypervisors.

Chores:

  • Remove unused hammer deploy helpers and configuration command builders from virt-who utilities.

Add test coverage for the 'Deploy virt-who Config' Ansible REX job
template across all hypervisor types (ESX, HyperV, KubeVirt, Libvirt,
Nutanix) via both API and UI paths.

Changes:
- Add deploy_configure_by_job_api() and deploy_configure_by_job_ui()
  helper functions to robottelo/utils/virtwho.py
- Add deploy_validation_on_host() for validating virt-who deployment
  on remote content hosts used by UI REX jobs
- Add deploy_via_job_api and deploy_via_job_ui fixtures
- Add test_positive_deploy_configure_by_job tests to all 10 hypervisor
  test files (5 API + 5 UI)
- Simplify deploy_type_api and deploy_type_ui fixtures by removing
  indirect parametrize for the 'id' deploy type (only 'script' remains)
- Remove unused get_configure_command() and
  get_configure_command_option() functions
- Update hypervisor mapping detection to also match 'Sending updated
  Host-to-guest mapping to' log pattern

Verifies: SAT-46996

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@sourcery-ai

sourcery-ai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Adds virt-who Ansible REX job-based deployment coverage for all hypervisors, refactors virt-who deployment helpers to target a CDN-backed content host instead of Satellite/Capsule, and simplifies existing deploy fixtures by removing hammer command-based paths and unused helpers while updating log parsing for newer Satellite versions.

Sequence diagram for API-based virt-who Ansible REX job deployment to content host

sequenceDiagram
    participant TestRunner
    participant VirtWhoUtils
    participant Satellite as target_sat
    participant ContentHost as content_host
    participant CDN

    TestRunner->>VirtWhoUtils: deploy_configure_by_job_api(form_data, hypervisor_type, org, activation_key, target_sat, content_host, location)
    VirtWhoUtils->>VirtWhoUtils: virtwho_cleanup()
    VirtWhoUtils->>VirtWhoUtils: _setup_virtwho_guest(hypervisor_type, org, activation_key, target_sat)
    VirtWhoUtils->>ContentHost: _register_content_host_with_virtwho(content_host, target_sat, org, activation_key, location)
    ContentHost->>CDN: register_to_cdn()
    ContentHost->>CDN: enable_repo(aps_repo, force=True)
    ContentHost->>CDN: execute(dnf install -y virt-who)

    VirtWhoUtils->>Satellite: JobTemplate().search(query)
    VirtWhoUtils->>Satellite: JobInvocation().run(data={job_template_id, inputs, search_query})
    VirtWhoUtils->>Satellite: wait_for_tasks(resource_type = JobInvocation, resource_id = job[id])
    VirtWhoUtils->>Satellite: JobInvocation(id=job[id]).read()
    Satellite-->>VirtWhoUtils: result.succeeded

    VirtWhoUtils->>ContentHost: execute(rm -f /var/log/rhsm/rhsm.log)
    VirtWhoUtils->>ContentHost: execute(systemctl restart virt-who&#59; sleep 10)
    alt debug
        VirtWhoUtils->>VirtWhoUtils: deploy_validation_on_host(hypervisor_type, content_host)
    end
Loading

File-Level Changes

Change Details Files
Refactor virt-who deployment helpers to support REX job-based deployment on a remote content host and share common guest/content-host setup.
  • Introduce deploy_validation_on_host to validate virt-who service and mapping on a ContentHost instead of the Satellite.
  • Add _setup_virtwho_guest to encapsulate guest host deletion, activation key creation, and guest system registration.
  • Add _register_content_host_with_virtwho to register a content host to CDN, install virt-who from AppStream, then register it to Satellite for REX targeting.
  • Update deploy_configure_by_script to reuse _setup_virtwho_guest instead of duplicating guest registration logic.
  • Change hypervisor mapping wait logic to accept both old and new rhsm.log patterns for newer Satellite versions.
robottelo/utils/virtwho.py
Implement API and UI helpers for running the 'Deploy virt-who Config' Ansible REX job template against a content host.
  • Add deploy_configure_by_job_api that builds JobInvocation inputs from form_data and runs the job template via the Satellite API targeting the content host.
  • Add deploy_configure_by_job_ui that schedules the same job template via Airgun UI session targeting the content host and checks JobInvocation status.
  • Both helpers restart virt-who on the content host and, in debug mode, delegate validation to deploy_validation_on_host.
robottelo/utils/virtwho.py
Simplify deployment interfaces by removing hammer-based deploy helpers and unused option-based command builders.
  • Remove get_configure_command that returned hammer virt-who-config deploy commands based on configure id.
  • Remove get_configure_command_option that built hammer deploy commands for different deploy types.
  • Stop importing DEFAULT_ORG from constants and instead use REPOS for CDN AppStream repo IDs in content host registration.
robottelo/utils/virtwho.py
Update virt-who pytest fixtures to use script-based deployment only and add new fixtures for API/UI Ansible REX job deployment.
  • Change deploy_type_api fixture to always deploy via script and return hypervisor/guest mapping without using a parametrized deploy_type.
  • Change deploy_type_ui fixture similarly to always use deploy_configure_by_script based on UI-provided script content.
  • Introduce deploy_via_job_ui fixture that calls deploy_configure_by_job_ui with org_session, content host, and default location.
  • Introduce deploy_via_job_api fixture that calls deploy_configure_by_job_api with form_data_api, content host, and default location.
  • Remove dependencies on register_sat_and_enable_aps_repo for job-based deployment because virt-who is now installed from CDN within _register_content_host_with_virtwho.
pytest_fixtures/component/virtwho_config.py
Add UI test cases per hypervisor to cover virt-who deployment via Ansible REX job template targeting a content host.
  • For ESX UI tests, add test_positive_deploy_configure_by_job that uses deploy_via_job_ui and validates hypervisor_guest_mapping in the UI, and remove parametrization over deploy_type_ui.
  • For HyperV, KubeVirt, Libvirt, and Nutanix UI tests, add analogous test_positive_deploy_configure_by_job methods with SAT-46996 IDs and shared structure, using deploy_via_job_ui and UI mapping verification.
  • Mark these new tests with no_containers and rhel_ver_match filters tied to settings.content_host.default_rhel_version.
  • Remove now-unnecessary @pytest.mark.parametrize('deploy_type_ui', ['script'], indirect=True) decorators from existing script deployment tests.
tests/foreman/virtwho/ui/test_esx_sca.py
tests/foreman/virtwho/ui/test_hyperv_sca.py
tests/foreman/virtwho/ui/test_kubevirt_sca.py
tests/foreman/virtwho/ui/test_libvirt_sca.py
tests/foreman/virtwho/ui/test_nutanix_sca.py
Add API test cases per hypervisor to cover virt-who deployment via Ansible REX job template targeting a content host.
  • For ESX API tests, add test_positive_deploy_configure_by_job using deploy_via_job_api and basic assertions on hypervisor_name and guest_name.
  • Add equivalent test_positive_deploy_configure_by_job methods for HyperV, KubeVirt, Libvirt, and Nutanix API suites with SAT-46996 IDs and shared structure.
  • Mark all new API job-based tests with no_containers and rhel_ver_match filters bound to settings.content_host.default_rhel_version.
  • Remove @pytest.mark.parametrize('deploy_type_api', ['script'], indirect=True) decorators from existing script deployment tests, leaving script deployment covered via fixtures without deploy_type switching.
tests/foreman/virtwho/api/test_esx_sca.py
tests/foreman/virtwho/api/test_hyperv_sca.py
tests/foreman/virtwho/api/test_kubevirt_sca.py
tests/foreman/virtwho/api/test_libvirt_sca.py
tests/foreman/virtwho/api/test_nutanix_sca.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • In deploy_validation_on_host, the wait loop repeatedly runs host.execute('cat /var/log/rhsm/rhsm.log'); consider reading the log once per wait_for iteration and reusing it both for the condition and the subsequent parsing to avoid duplicate remote calls.
  • The job invocation helpers (deploy_configure_by_job_api and deploy_configure_by_job_ui) hard-code strings like Deploy virt-who Config and the job description; centralizing these names/constants would reduce the chance of breakage if the template name or description changes.
  • There is now duplicated logic for virt-who deployment validation in deploy_validation and deploy_validation_on_host; you could extract common mapping-parsing code into a shared helper to make future changes easier and keep behavior consistent.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `deploy_validation_on_host`, the wait loop repeatedly runs `host.execute('cat /var/log/rhsm/rhsm.log')`; consider reading the log once per `wait_for` iteration and reusing it both for the condition and the subsequent parsing to avoid duplicate remote calls.
- The job invocation helpers (`deploy_configure_by_job_api` and `deploy_configure_by_job_ui`) hard-code strings like `Deploy virt-who Config` and the job description; centralizing these names/constants would reduce the chance of breakage if the template name or description changes.
- There is now duplicated logic for virt-who deployment validation in `deploy_validation` and `deploy_validation_on_host`; you could extract common mapping-parsing code into a shared helper to make future changes easier and keep behavior consistent.

## Individual Comments

### Comment 1
<location path="robottelo/utils/virtwho.py" line_range="370-375" />
<code_context>
+        mapping.append(_parse_entry(entry))
+    mapping = [m for m in mapping if m is not None]
+    hypervisor_name = None
+    for item in mapping[-1]['hypervisors']:
+        for guest in item['guestIds']:
+            if guest_uuid in guest['guestId']:
+                hypervisor_name = item['hypervisorId']['hypervisorId']
+                break
+    if not hypervisor_name:
+        raise VirtWhoError(f'Failed to get hypervisor_name for guest {guest_name}')
+    for h in Host.list({'search': hypervisor_name}):
</code_context>
<issue_to_address>
**issue:** Handle the case where no mapping entries are parsed to avoid IndexError.

After filtering out `None` entries, `mapping` may still be empty. Accessing `mapping[-1]['hypervisors']` in that case will raise `IndexError` (or `TypeError` if the last entry is malformed) before you raise `VirtWhoError`. Add a guard (e.g., `if not mapping: raise VirtWhoError(...)`) before indexing, or otherwise ensure you only access `mapping[-1]` when a valid entry is present.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +370 to +375
for item in mapping[-1]['hypervisors']:
for guest in item['guestIds']:
if guest_uuid in guest['guestId']:
hypervisor_name = item['hypervisorId']['hypervisorId']
break
if not hypervisor_name:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

issue: Handle the case where no mapping entries are parsed to avoid IndexError.

After filtering out None entries, mapping may still be empty. Accessing mapping[-1]['hypervisors'] in that case will raise IndexError (or TypeError if the last entry is malformed) before you raise VirtWhoError. Add a guard (e.g., if not mapping: raise VirtWhoError(...)) before indexing, or otherwise ensure you only access mapping[-1] when a valid entry is present.

@jnagare-redhat
jnagare-redhat marked this pull request as draft July 22, 2026 13:10
…lite

Remove capsule dependency from deploy_configure_by_job_ui and align
both API and UI deploy functions to target a content host. Extract
shared setup into _setup_virtwho_guest and _register_content_host_with_virtwho
helpers to eliminate duplication across all three deploy functions.

The content host registers to CDN for virt-who package availability
before registering to Satellite for REX job targeting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jnagare-redhat jnagare-redhat added No-CherryPick PR doesnt need CherryPick to previous branches Stream Introduced in or relating directly to Satellite Stream/Master labels Jul 22, 2026
@jnagare-redhat
jnagare-redhat marked this pull request as ready for review July 22, 2026 17:32

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • In deploy_validation_on_host the wait_for predicate re-executes cat /var/log/rhsm/rhsm.log on every check and then reads the file again afterward; consider capturing the log content once per poll and reusing it to avoid repeated remote commands and make the mapping parsing more efficient.
  • The new Ansible job helpers mix assert-based error reporting with VirtWhoError exceptions (e.g. in _register_content_host_with_virtwho vs other functions); standardizing on explicit exception types would make failures easier to interpret and more consistent with the rest of the virt-who utilities.
  • The UI job flow relies on a hard-coded job_description string ('Deploy virt-who configuration virt-who-config') to locate the JobInvocation; using a more robust identifier (e.g. template name plus host or ID from the scheduling call) would reduce brittleness if the job template description changes.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In deploy_validation_on_host the wait_for predicate re-executes `cat /var/log/rhsm/rhsm.log` on every check and then reads the file again afterward; consider capturing the log content once per poll and reusing it to avoid repeated remote commands and make the mapping parsing more efficient.
- The new Ansible job helpers mix `assert`-based error reporting with VirtWhoError exceptions (e.g. in `_register_content_host_with_virtwho` vs other functions); standardizing on explicit exception types would make failures easier to interpret and more consistent with the rest of the virt-who utilities.
- The UI job flow relies on a hard-coded `job_description` string ('Deploy virt-who configuration virt-who-config') to locate the JobInvocation; using a more robust identifier (e.g. template name plus host or ID from the scheduling call) would reduce brittleness if the job template description changes.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@jnagare-redhat

Copy link
Copy Markdown
Contributor Author
trigger: test-robottelo
pytest: tests/foreman/virtwho/ui/test_esx_sca.py::TestVirtwhoConfigforEsx::test_positive_deploy_configure_by_job
theforeman:
    foreman_virt_who_configure: 236

@Satellite-QE

Copy link
Copy Markdown
Collaborator

PRT Result

Build Number: 16203
Build Status: UNSTABLE
PRT Comment: pytest tests/foreman/virtwho/ui/test_esx_sca.py::TestVirtwhoConfigforEsx::test_positive_deploy_configure_by_job --external-logging
Test Result : ================== 9 warnings, 1 error in 1844.94s (0:30:44) ===================

@Satellite-QE Satellite-QE added the PRT-Failed Indicates that latest PRT run is failed for the PR label Jul 22, 2026
@jnagare-redhat

Copy link
Copy Markdown
Contributor Author
trigger: test-robottelo
pytest: tests/foreman/virtwho/ui/test_esx_sca.py::TestVirtwhoConfigforEsx::test_positive_deploy_configure_by_job
theforeman:
    foreman_virt_who_configure: 236

@Satellite-QE

Copy link
Copy Markdown
Collaborator

PRT Result

Build Number: 16206
Build Status: UNSTABLE
PRT Comment: pytest tests/foreman/virtwho/ui/test_esx_sca.py::TestVirtwhoConfigforEsx::test_positive_deploy_configure_by_job --external-logging
Test Result : ================== 9 warnings, 1 error in 2218.72s (0:36:58) ===================

@jnagare-redhat

Copy link
Copy Markdown
Contributor Author

trigger: test-robottelo
pytest: tests/foreman/virtwho/ui/test_esx_sca.py::TestVirtwhoConfigforEsx::test_positive_deploy_configure_by_job
airgun: 2488
theforeman:
foreman_virt_who_configure: 236

@jnagare-redhat

Copy link
Copy Markdown
Contributor Author
trigger: test-robottelo
pytest: tests/foreman/virtwho/ui/test_esx_sca.py::TestVirtwhoConfigforEsx::test_positive_deploy_configure_by_job
airgun: 2488
theforeman:
    foreman_virt_who_configure: 236

@jnagare-redhat
jnagare-redhat requested a review from chris1984 July 23, 2026 09:42
@jnagare-redhat

Copy link
Copy Markdown
Contributor Author
trigger: test-robottelo
pytest: tests/foreman/virtwho/ui/test_esx_sca.py -k test_positive_deploy_configure_by_job
airgun: 2488
theforeman:
    foreman_virt_who_configure: 236

@Satellite-QE

Copy link
Copy Markdown
Collaborator

PRT Result

Build Number: 16216
Build Status: SUCCESS
PRT Comment: pytest tests/foreman/virtwho/ui/test_esx_sca.py -k test_positive_deploy_configure_by_job --external-logging
Test Result : ========== 1 passed, 17 deselected, 9 warnings in 1994.00s (0:33:13) ===========

@Satellite-QE Satellite-QE added PRT-Passed Indicates that latest PRT run is passed for the PR and removed PRT-Failed Indicates that latest PRT run is failed for the PR labels Jul 23, 2026
@jnagare-redhat
jnagare-redhat marked this pull request as draft July 28, 2026 15:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

No-CherryPick PR doesnt need CherryPick to previous branches PRT-Passed Indicates that latest PRT run is passed for the PR Stream Introduced in or relating directly to Satellite Stream/Master

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants