Skip to content

Fix s390x test compatibility issues#4305

Open
chandramerla wants to merge 1 commit intoRedHatQE:mainfrom
chandramerla:s390x-test-fixes
Open

Fix s390x test compatibility issues#4305
chandramerla wants to merge 1 commit intoRedHatQE:mainfrom
chandramerla:s390x-test-fixes

Conversation

@chandramerla
Copy link
Copy Markdown
Member

@chandramerla chandramerla commented Mar 30, 2026

Short description:

When trying to move to fedora43 for s390x and trying to run affected tests, have come across some issues, whose fixes are in this PR

More details:
  • Fix centos DataSource name: use os_name="centos-stream" to generate correct "centos-stream9" DataSource name instead of "centos9"
  • Add retry logic to get_ip_from_vm_or_virt_handler_pod with TimeoutSampler to handle guest agent IP reporting timing
  • Skip x86-specific clock timers (hpet, pit, kvm, hyperv, rtc) in VirtualMachinePreference fixture on s390x
  • Remove s390x marker from test_validate_clock_values (x86-only)
  • Skip EFI/OVMF preferences on s390x in common VM preference tests
  • Override nic_models_matrix for s390x to exclude unsupported e1000e
  • Remove s390x marker from test_successful_clone_of_large_image (Windows image not available for s390x)
What this PR does / why we need it:

Fixes some test issues for s390x arch.

Which issue(s) this PR fixes:
Special notes for reviewer:

Please review changes from respective files as you are more familiar or making fixes there -

  1. @aditi-sharma-1 . tests/infrastructure/instance_types/test_common_vm_preference.py , tests/infrastructure/instance_types/test_vm_with_instance_and_pref.py, utilities/pytest_utils.py, utilities/unittests/test_pytest_utils.py

  2. @HarshithaMS005 tests/network/connectivity/test_pod_network.py , utilities/network.py

  3. @Davo911 tests/storage/cdi_clone/test_clone.py

jira-ticket:

Summary by CodeRabbit

  • Tests

    • Improved test configurations to better handle s390x vs other architectures and expanded test scope by removing architecture-only restrictions.
    • Added logging and conditional skips for preferences requiring EFI on unsupported architectures.
  • Bug Fixes / Improvements

    • Network operations now wait for a valid VM or handler IP up to a configurable timeout, reducing flaky failures during IP resolution.
    • Added platform-specific configuration for s390x NIC models.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 30, 2026

📝 Walkthrough

Walkthrough

Adds S390X-aware test logic and configuration, skips EFI-requiring preferences on S390X, broadens test scope by removing S390X-only markers, and enhances IP resolution with a timeout-retry mechanism in the network utility.

Changes

Cohort / File(s) Summary
Fixture & config
tests/conftest.py, tests/global_config_s390x.py
common_vm_preference_param_dict now checks cluster architecture via get_cluster_architecture() and omits setting clock.preferredTimer for S390X; added nic_models_matrix = ["virtio"] to s390x global config.
Preference handling (tests)
tests/infrastructure/instance_types/test_common_vm_preference.py
Added logger and _preference_requires_efi(client, preference_name); when cluster arch is S390X, skip starting VMs for preferences that require EFI/OVMF (info log + continue).
Test marker removals
tests/infrastructure/instance_types/test_vm_with_instance_and_pref.py, tests/storage/cdi_clone/test_clone.py
Removed @pytest.mark.s390x from specific tests, expanding their execution beyond S390X.
Network utility & usage
utilities/network.py, tests/network/connectivity/test_pod_network.py
get_ip_from_vm_or_virt_handler_pod gains wait_timeout (default 0) with a _resolve_ip helper, TimeoutSampler-based retry when timeout > 0, safer dict/list access, explicit retryable exceptions, and timeout logging; test now passes TIMEOUT_90SEC as wait_timeout.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 58.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Fix s390x test compatibility issues' directly summarizes the main change—addressing multiple s390x architecture compatibility problems across tests and utilities, which is clearly the primary intent of this PR.
Description check ✅ Passed The description follows the required template with all key sections populated: short description, detailed bullet points explaining each fix, rationale, special notes with reviewer assignments, and required fields—though the jira-ticket field is not completed.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@openshift-virtualization-qe-bot-4
Copy link
Copy Markdown

Report bugs in Issues

Welcome! 🎉

This pull request will be automatically processed with the following features:

🔄 Automatic Actions

  • Reviewer Assignment: Reviewers are automatically assigned based on the OWNERS file in the repository root
  • Size Labeling: PR size labels (XS, S, M, L, XL, XXL) are automatically applied based on changes
  • Issue Creation: A tracking issue is created for this PR and will be closed when the PR is merged or closed
  • Branch Labeling: Branch-specific labels are applied to track the target branch
  • Auto-verification: Auto-verified users have their PRs automatically marked as verified
  • Labels: Enabled categories: branch, can-be-merged, cherry-pick, has-conflicts, hold, needs-rebase, size, verified, wip

📋 Available Commands

PR Status Management

  • /wip - Mark PR as work in progress (adds WIP: prefix to title)
  • /wip cancel - Remove work in progress status
  • /hold - Block PR merging (approvers only)
  • /hold cancel - Unblock PR merging
  • /verified - Mark PR as verified
  • /verified cancel - Remove verification status
  • /reprocess - Trigger complete PR workflow reprocessing (useful if webhook failed or configuration changed)
  • /regenerate-welcome - Regenerate this welcome message

Review & Approval

  • /lgtm - Approve changes (looks good to me)
  • /approve - Approve PR (approvers only)
  • /assign-reviewers - Assign reviewers based on OWNERS file
  • /assign-reviewer @username - Assign specific reviewer
  • /check-can-merge - Check if PR meets merge requirements

Testing & Validation

  • /retest tox - Run Python test suite with tox
  • /retest build-container - Rebuild and test container image
  • /retest verify-bugs-are-open - verify-bugs-are-open
  • /retest all - Run all available tests

Container Operations

  • /build-and-push-container - Build and push container image (tagged with PR number)
    • Supports additional build arguments: /build-and-push-container --build-arg KEY=value

Cherry-pick Operations

  • /cherry-pick <branch> - Schedule cherry-pick to target branch when PR is merged
    • Multiple branches: /cherry-pick branch1 branch2 branch3

Label Management

  • /<label-name> - Add a label to the PR
  • /<label-name> cancel - Remove a label from the PR

✅ Merge Requirements

This PR will be automatically approved when the following conditions are met:

  1. Approval: /approve from at least one approver
  2. LGTM Count: Minimum 2 /lgtm from reviewers
  3. Status Checks: All required status checks must pass
  4. No Blockers: No wip, hold, has-conflicts labels and PR must be mergeable (no conflicts)
  5. Verified: PR must be marked as verified

📊 Review Process

Approvers and Reviewers

Approvers:

  • EdDev
  • dshchedr
  • jpeimer
  • myakove
  • rnetser
  • vsibirsk

Reviewers:

  • Ahmad-Hafe
  • Anatw
  • EdDev
  • RoniKishner
  • azhivovk
  • dalia-frank
  • dshchedr
  • duyanyan
  • geetikakay
  • josemacassan
  • jpeimer
  • kgoldbla
  • kshvaika
  • mijankow
  • rnetser
  • servolkov
  • stesrn
  • vsibirsk
  • yossisegev
Available Labels
  • hold
  • verified
  • wip
  • lgtm
  • approve
AI Features
  • Cherry-Pick Conflict Resolution: Enabled (claude/claude-opus-4-6[1m])

💡 Tips

  • WIP Status: Use /wip when your PR is not ready for review
  • Verification: The verified label is automatically removed on each new commit
  • Cherry-picking: Cherry-pick labels are processed when the PR is merged
  • Container Builds: Container images are automatically tagged with the PR number
  • Permission Levels: Some commands require approver permissions
  • Auto-verified Users: Certain users have automatic verification and merge privileges

For more information, please refer to the project documentation or contact the maintainers.

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 30, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.65%. Comparing base (b4ad2e0) to head (7eef80e).
⚠️ Report is 38 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4305      +/-   ##
==========================================
+ Coverage   98.63%   98.65%   +0.02%     
==========================================
  Files          25       25              
  Lines        2420     2459      +39     
==========================================
+ Hits         2387     2426      +39     
  Misses         33       33              
Flag Coverage Δ
utilities 98.65% <ø> (+0.02%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
utilities/network.py (1)

764-770: ⚠️ Potential issue | 🟠 Major

HIGH: _resolve_ip can fail before retry logic has a chance to retry

At Line 766 (vm.vmi.interfaces[0]) and Line 768 (podIPs iteration), transient missing data can raise IndexError/AttributeError/TypeError. That turns a temporary “IP not ready yet” state into an immediate failure, which defeats the new timeout-based polling behavior.

Proposed fix
     def _resolve_ip():
-        if vm:
-            addr_list = vm.vmi.interfaces[0].get("ipAddresses") or []
-        else:
-            addr_list = [ip_addr["ip"] for ip_addr in virt_handler_pod.instance.status.podIPs]
+        try:
+            if vm:
+                interfaces = vm.vmi.interfaces or []
+                addr_list = interfaces[0].get("ipAddresses") if interfaces else []
+                addr_list = addr_list or []
+            else:
+                pod_ips = virt_handler_pod.instance.status.podIPs or []
+                addr_list = [ip_addr.get("ip") for ip_addr in pod_ips if ip_addr.get("ip")]
+        except (AttributeError, IndexError, TypeError):
+            return None
         ip_list = [ip for ip in addr_list if get_valid_ip_address(dst_ip=ip, family=family)]
         return ip_list[0] if ip_list else None
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@utilities/network.py` around lines 764 - 770, The helper _resolve_ip
currently accesses vm.vmi.interfaces[0] and iterates
virt_handler_pod.instance.status.podIPs directly which can raise
IndexError/AttributeError/TypeError and bypass retry logic; update _resolve_ip
to defensively access those attributes (check for None, missing keys, empty
lists) and wrap the extraction logic in a try/except that catches
IndexError/AttributeError/TypeError, returning None on failure so the outer
polling can retry; reference vm, vm.vmi.interfaces,
virt_handler_pod.instance.status.podIPs, get_valid_ip_address and family when
making these safe checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/infrastructure/instance_types/test_common_vm_preference.py`:
- Around line 60-64: Add explicit type hints to the helper function
_preference_requires_efi: annotate the parameters (e.g., client: Any,
preference_name: str) and the return type (-> bool) and import Any from typing
if needed; keep the implementation unchanged but update the function signature
to include these annotations to improve readability in tests.

---

Duplicate comments:
In `@utilities/network.py`:
- Around line 764-770: The helper _resolve_ip currently accesses
vm.vmi.interfaces[0] and iterates virt_handler_pod.instance.status.podIPs
directly which can raise IndexError/AttributeError/TypeError and bypass retry
logic; update _resolve_ip to defensively access those attributes (check for
None, missing keys, empty lists) and wrap the extraction logic in a try/except
that catches IndexError/AttributeError/TypeError, returning None on failure so
the outer polling can retry; reference vm, vm.vmi.interfaces,
virt_handler_pod.instance.status.podIPs, get_valid_ip_address and family when
making these safe checks.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 8e50a842-3e41-4d13-92af-a27609ead15b

📥 Commits

Reviewing files that changed from the base of the PR and between 2a236a8 and 2d924df.

📒 Files selected for processing (7)
  • tests/conftest.py
  • tests/global_config_s390x.py
  • tests/infrastructure/instance_types/test_common_vm_preference.py
  • tests/infrastructure/instance_types/test_vm_with_instance_and_pref.py
  • tests/network/connectivity/test_pod_network.py
  • tests/storage/cdi_clone/test_clone.py
  • utilities/network.py
💤 Files with no reviewable changes (2)
  • tests/infrastructure/instance_types/test_vm_with_instance_and_pref.py
  • tests/storage/cdi_clone/test_clone.py

- Fix centos DataSource name: use os_name="centos-stream" to generate
  correct "centos-stream9" DataSource name instead of "centos9"
- Add retry logic to get_ip_from_vm_or_virt_handler_pod with
  TimeoutSampler to handle guest agent IP reporting timing
- Skip x86-specific clock timers (hpet, pit, kvm, hyperv, rtc) in
  VirtualMachinePreference fixture on s390x
- Remove s390x marker from test_validate_clock_values (x86-only)
- Skip EFI/OVMF preferences on s390x in common VM preference tests
- Override nic_models_matrix for s390x to exclude unsupported e1000e
- Remove s390x marker from test_successful_clone_of_large_image
  (Windows image not available for s390x)

Made-with: Cursor
@chandramerla
Copy link
Copy Markdown
Member Author

@rnetser Could you please help review these small test fixes?

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/conftest.py`:
- Around line 2223-2228: The check incorrectly compares
get_cluster_architecture() (which returns a set) to S390X; change the guard to
test membership (e.g., if S390X in get_cluster_architecture()) so the s390x
branch runs and avoids adding common_preference_dict.setdefault("clock",
{})["preferredTimer"] = request.param["clock_preferred_timer"]; update the
conditional that uses get_cluster_architecture(), S390X, common_preference_dict,
and request.param["clock_preferred_timer"] accordingly.

In `@tests/infrastructure/instance_types/test_common_vm_preference.py`:
- Around line 67-73: The variable is_s390x is incorrectly computed by equality
against get_cluster_architecture(); since that function returns a singleton set,
change the check to a membership test (e.g., is_s390x = S390X in
get_cluster_architecture()) so the s390x EFI/OVMF skip branch (which calls
_preference_requires_efi(client, preference_name) and logs via LOGGER) actually
runs for s390x clusters.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: b8828b87-7642-4402-b0cf-a05bf8a90428

📥 Commits

Reviewing files that changed from the base of the PR and between 2d924df and 7eef80e.

📒 Files selected for processing (7)
  • tests/conftest.py
  • tests/global_config_s390x.py
  • tests/infrastructure/instance_types/test_common_vm_preference.py
  • tests/infrastructure/instance_types/test_vm_with_instance_and_pref.py
  • tests/network/connectivity/test_pod_network.py
  • tests/storage/cdi_clone/test_clone.py
  • utilities/network.py
💤 Files with no reviewable changes (2)
  • tests/infrastructure/instance_types/test_vm_with_instance_and_pref.py
  • tests/storage/cdi_clone/test_clone.py

Comment on lines +2223 to +2228
if get_cluster_architecture() == S390X:
LOGGER.info(
"Skipping preferredTimer in VirtualMachinePreference: x86-specific timers not available on s390x"
)
else:
common_preference_dict.setdefault("clock", {})["preferredTimer"] = request.param["clock_preferred_timer"]
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.

⚠️ Potential issue | 🟠 Major

HIGH: This s390x guard is comparing the wrong types.

Line 2223 compares get_cluster_architecture() to S390X, but this helper returns a set in this repo. That makes the condition false, so preferredTimer is still added on s390x and the fixture keeps generating x86-only clock timers there.

Proposed fix
-        if get_cluster_architecture() == S390X:
+        if S390X in get_cluster_architecture():
             LOGGER.info(
                 "Skipping preferredTimer in VirtualMachinePreference: x86-specific timers not available on s390x"
             )
Based on learnings, `get_cluster_architecture()` returns a singleton set from env-var/cluster detection, so it must be checked via membership rather than direct equality.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/conftest.py` around lines 2223 - 2228, The check incorrectly compares
get_cluster_architecture() (which returns a set) to S390X; change the guard to
test membership (e.g., if S390X in get_cluster_architecture()) so the s390x
branch runs and avoids adding common_preference_dict.setdefault("clock",
{})["preferredTimer"] = request.param["clock_preferred_timer"]; update the
conditional that uses get_cluster_architecture(), S390X, common_preference_dict,
and request.param["clock_preferred_timer"] accordingly.

Comment on lines +67 to +73
is_s390x = get_cluster_architecture() == S390X
for preference_name in preferences:
# TODO remove arm64 skip when openshift-virtualization-tests support arm64
if all(suffix not in preference_name for suffix in ["virtio", "arm64"]):
if is_s390x and _preference_requires_efi(client=client, preference_name=preference_name):
LOGGER.info(f"Skipping preference {preference_name}: EFI/OVMF not available on s390x")
continue
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.

⚠️ Potential issue | 🟠 Major

HIGH: is_s390x is always false here.

Line 67 makes the same set-to-string comparison, so the new EFI/OVMF skip path never runs on s390x. The test will still try to boot preferences that require EFI, which is the compatibility issue this PR is meant to avoid.

Proposed fix
-    is_s390x = get_cluster_architecture() == S390X
+    is_s390x = S390X in get_cluster_architecture()
Based on learnings, `get_cluster_architecture()` returns a singleton set from env-var/cluster detection, so it must be checked via membership rather than direct equality.
🧰 Tools
🪛 Ruff (0.15.7)

[warning] 72-72: Logging statement uses f-string

(G004)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/infrastructure/instance_types/test_common_vm_preference.py` around
lines 67 - 73, The variable is_s390x is incorrectly computed by equality against
get_cluster_architecture(); since that function returns a singleton set, change
the check to a membership test (e.g., is_s390x = S390X in
get_cluster_architecture()) so the s390x EFI/OVMF skip branch (which calls
_preference_requires_efi(client, preference_name) and logs via LOGGER) actually
runs for s390x clusters.

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