Skip to content

Conversation

@TasmiyaNalatwad
Copy link
Contributor

@TasmiyaNalatwad TasmiyaNalatwad commented Dec 17, 2024

Added 2 new test cases, where hotplog unplug is performed for multiple times and a random reboot is done between hotplug and unplug and the device availability is checked.

Below are the new cases added
(7/8) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.multiple_hotplug_hotunplug.PCI: STARTED
(7/8) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.multiple_hotplug_hotunplug.PCI: PASS (268.99 s)
(8/8) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.multiple_hotplug_unplug_with_rand_reboot.PCI: STARTED
(8/8) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.multiple_hotplug_unplug_with_rand_reboot.PCI: PASS (269.73 s)

Summary by CodeRabbit

  • New Features

    • Multi-cycle PCI hotplug/unplug with optional randomized reboots during stress runs.
    • Dynamic PCI controller allocation to avoid index conflicts.
    • Distro- and architecture-aware setup and session-based ping with timeout.
  • Bug Fixes

    • Improved detach/reattach reliability across architectures and libvirt versions.
    • More robust device queries and configuration persistence.
  • Tests

    • Added two variants covering multi-cycle and random-reboot scenarios.

@TasmiyaNalatwad TasmiyaNalatwad force-pushed the PCI_PT_hotplug_unplug branch 2 times, most recently from af0e5b7 to 3f838c2 Compare December 26, 2024 07:09
@TasmiyaNalatwad
Copy link
Contributor Author

JOB ID : cd7960bd139abe0e6cd9b397722a5a75833f644b
JOB LOG : /root/tests/results/job-2024-12-26T00.52-cd7960b/job.log
(1/8) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.flood_ping.PCI: STARTED
(1/8) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.flood_ping.PCI: PASS (108.67 s)
(2/8) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.suspend.PCI: STARTED
(2/8) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.suspend.PCI: PASS (110.53 s)
(3/8) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.reboot.PCI: STARTED
(3/8) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.reboot.PCI: PASS (133.24 s)
(4/8) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.virsh_dumpxml.PCI: STARTED
(4/8) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.virsh_dumpxml.PCI: PASS (108.58 s)
(5/8) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.stress_test.PCI: STARTED
(5/8) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.stress_test.PCI: PASS (108.46 s)
(6/8) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.virsh_dump.PCI: STARTED
(6/8) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.virsh_dump.PCI: FAIL: Failed to virsh dump of domain avocado-vt-vm1 (52.22 s)
(7/8) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.multiple_hotplug_hotunplug.PCI: STARTED
(7/8) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.multiple_hotplug_hotunplug.PCI: PASS (268.99 s)
(8/8) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.multiple_hotplug_unplug_with_rand_reboot.PCI: STARTED
(8/8) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.multiple_hotplug_unplug_with_rand_reboot.PCI: PASS (269.73 s)
RESULTS : PASS 7 | ERROR 0 | FAIL 1 | SKIP 0 | WARN 0 | INTERRUPT 0 | CANCEL 0
JOB HTML : /root/tests/results/job-2024-12-26T00.52-cd7960b/results.html
JOB TIME : 1279.13 s

@TasmiyaNalatwad TasmiyaNalatwad force-pushed the PCI_PT_hotplug_unplug branch 3 times, most recently from 5c6c298 to 3c0328b Compare January 23, 2025 12:32
@TasmiyaNalatwad
Copy link
Contributor Author

There is 1 Testcase failing here that is virdhdump test on Pci Passthrough. The test case needs more code work and enhancement to make it work on ppc64 arch. I will work on virshdump test separately and send a separate patch for that. This patch is for all the other hotplug tests working and passed.

(6/8) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.virsh_dump.PCI: FAIL: Failed to virsh dump of domain avocado-vt-vm1 (52.22 s)

Thank you,
Tasmiya

Copy link
Contributor

@harihare harihare left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link

@PraveenPenguin PraveenPenguin left a comment

Choose a reason for hiding this comment

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

LGTM

@TasmiyaNalatwad
Copy link
Contributor Author

@chloerh Would you please review the changes and if everything looks good can we proceed with the patch merge?

Thanks a lot

@TasmiyaNalatwad
Copy link
Contributor Author

@chloerh @chunfuwen @dzhengfy @luckyh Would you please review the changes and if everything looks good can we proceed with the patch merge?

Thanks a lot

@TasmiyaNalatwad
Copy link
Contributor Author

@chloerh @chunfuwen @dzhengfy @luckyh Would you please review the changes and if everything looks good can we proceed with the patch merge?

I have got 2 approvals. Please let me know anything needs to be taken care in this

Thanks a lot

@coderabbitai
Copy link

coderabbitai bot commented Sep 17, 2025

Walkthrough

Adds two PCI passthrough hotplug test variants to the configuration and extends the hotplug test script with dynamic PCI controller indexing, distro-aware package selection, arch- and libvirt-version-aware attach/detach behavior, persistent guest session ping, multi-cycle hotplug/unplug sequences, optional randomized reboots during stress loops, and updated cleanup that persists VM XML and reattaches devices when required.

Changes

Cohort / File(s) Summary
Config: new variants
libvirt/tests/cfg/passthrough/pci/libvirt_pci_passthrough_hotplug.cfg
Adds two variants: multiple_hotplug_hotunplug (multiple_hotplug_hotunplug = "yes", number_of_hotplug_unplug = 25) and multiple_hotplug_unplug_with_rand_reboot (random_reboot = "yes", number_of_hotplug_unplug = 30). No deletions.
Test logic: hotplug flow, arch/version handling, utilities
libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py
Adds platform and random imports; computes dynamic PCI controller index and applies controller type/model; adds distro-aware package selection for host tooling; replaces map(None, ...) usage with zip(...); introduces libvirt-version and architecture-specific hostdev detach/reattach logic; switches guest checks to utils_test.ping using persistent sessions and timeout; implements rand_reboot behavior and optional multi-cycle hotplug/hotunplug with interleaved random reboots; updates teardown to persist VM XML and reattach devices when necessary.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant T as Test Runner
  participant HV as Host/Libvirt
  participant VM as Guest

  rect rgb(230,240,255)
    note over T,HV: Init — platform, distro, libvirt checks
    T->>HV: Query existing PCI controllers
    HV-->>T: Controller list
    T->>T: Compute next_index, set controller type/model
  end

  rect rgb(240,255,240)
    loop Hotplug/Unplug cycles (N)
      T->>HV: Hotplug PCI hostdev(s)
      T->>VM: Open persistent session
      T->>VM: utils_test.ping(session, timeout)
      alt Detach required (arch/version)
        T->>HV: Detach PCI hostdev(s)
      else
        note right of T: Remain attached
      end
      T->>HV: Unplug if configured
    end
  end

  opt Random reboot enabled
    loop Extra cycles with possible random reboot
      T->>HV: Attach/Detach cycle
      T->>VM: rand_reboot(probabilistic)
      VM-->>T: Session re-established after reboot
    end
  end

  rect rgb(255,245,230)
    note over T,HV: Teardown
    T->>HV: Reattach devices if required
    T->>HV: Persist VM XML
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Pay attention to distro-specific package selection and conditional imports.
  • Review arch- and libvirt-version-dependent detach/reattach logic for correctness and coverage.
  • Verify persistent session usage with utils_test.ping and any session lifecycle handling.
  • Confirm the multi-cycle and randomized reboot logic does not introduce flakiness or resource leaks.

Poem

I twitch my whiskers at hotplug’s tune,
Slots click and sigh beneath the silicon moon.
Twenty-five hops, thirty with surprise,
Random reboots tumble from coded skies.
I hop, I test, I nibble a byte. 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'PCI PT Hotplug/Hotunplug fixes for arch ppc64' clearly describes the main changes: adding PCI passthrough hotplug/hotunplug test fixes for ppc64 architecture.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ca1f423 and 2daa678.

📒 Files selected for processing (2)
  • libvirt/tests/cfg/passthrough/pci/libvirt_pci_passthrough_hotplug.cfg (1 hunks)
  • libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py (11 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • libvirt/tests/cfg/passthrough/pci/libvirt_pci_passthrough_hotplug.cfg
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-11-18T01:20:50.873Z
Learnt from: qiankehan
Repo: autotest/tp-libvirt PR: 6654
File: libvirt/tests/src/virtual_network/qemu/boot_with_multiqueue.py:56-58
Timestamp: 2025-11-18T01:20:50.873Z
Learning: In the tp-libvirt project, when calling session command methods and the status code is not needed, prefer using `session.cmd_output()` over `session.cmd_status_output()` to avoid unused variables.

Applied to files:

  • libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py
📚 Learning: 2025-09-24T08:01:27.899Z
Learnt from: hholoubk
Repo: autotest/tp-libvirt PR: 6579
File: libvirt/tests/src/sriov/vIOMMU/iommu_device_lifecycle.py:95-97
Timestamp: 2025-09-24T08:01:27.899Z
Learning: In the libvirt test framework used in tp-libvirt, VM cleanup including destroying running VMs is handled by the teardown method (test_obj.teardown_iommu_test()) called in the finally block, so explicit VM destroy calls on timeout are not necessary according to the maintainers.

Applied to files:

  • libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py
📚 Learning: 2025-11-18T08:47:14.443Z
Learnt from: smitterl
Repo: autotest/tp-libvirt PR: 6072
File: libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py:239-241
Timestamp: 2025-11-18T08:47:14.443Z
Learning: In tp-libvirt tests, `utils_test.ping` is a valid function that exists in the avocado-vt framework (virttest.utils_test module). It is an alias to `utils_net.ping` and supports parameters including dest, count, interface, timeout, and session.

Applied to files:

  • libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py
📚 Learning: 2025-11-03T13:30:16.458Z
Learnt from: smitterl
Repo: autotest/tp-libvirt PR: 6531
File: libvirt/tests/src/virtual_network/qemu/pktgen_burst_mode_test.py:64-67
Timestamp: 2025-11-03T13:30:16.458Z
Learning: In tp-libvirt tests, prefer using a list of cleanup lambda functions that are appended when actions requiring cleanup are performed, then executed in a finally block with individual error handling. Example: `cleanup_actions.append(lambda: undo_action())` followed by iterating through the list in reverse order in the finally block.

Applied to files:

  • libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py
🧬 Code graph analysis (1)
libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py (3)
libvirt/tests/src/virsh_cmd/domain/virsh_attach_device.py (1)
  • Controller (582-612)
libvirt/tests/src/passthrough/robustness/passthrough_robustness.py (1)
  • start (176-225)
libvirt/tests/src/virtual_network/iface_bridge.py (1)
  • ping (83-98)
🪛 Ruff (0.14.5)
libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py

157-157: zip() without an explicit strict= parameter

Add explicit value for parameter strict=

(B905)


173-173: zip() without an explicit strict= parameter

Add explicit value for parameter strict=

(B905)


308-308: Standard pseudo-random generators are not suitable for cryptographic purposes

(S311)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Python 3.12
  • GitHub Check: Python 3.9
  • GitHub Check: Python 3.11
  • GitHub Check: Python 3.8
🔇 Additional comments (5)
libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py (5)

308-308: Static analysis hint is a false positive.

The static analysis tool flags random.random() as unsuitable for cryptographic purposes (S311). This is a false positive—the random number generator is used for test randomization (probabilistic reboots), not for security-sensitive operations, so random.random() is appropriate here.

The random reboot logic was reviewed and approved by @smitterl in past comments.


330-344: LGTM! New test loops are well-structured.

The two new test variants are clearly separated and correctly implement the stated functionality:

  • multiple_hotplug_hotunplug: Performs repeated hotplug/hotunplug cycles without reboots
  • random_reboot: Performs hotplug/hotunplug cycles with probabilistic reboots between operations

The logging statements provide good visibility into test progress, and the random reboot logic (30% probability per iteration) is sound.


195-200: LGTM! Architecture-specific detach logic is correct.

The conditional device detach logic properly handles the different requirements for ppc64le (detach on newer libvirt) versus other architectures (detach on older libvirt). This was reviewed and approved in past comments by @smitterl.


103-117: LGTM! Dynamic controller indexing is well-implemented.

The logic correctly:

  1. Retrieves existing controllers of the specified type and model
  2. Extracts their index values and finds the maximum
  3. Calculates the next available index as max(indices) + 1
  4. Falls back to the configured index when no controllers exist

The get_controllers method was verified to exist in past review comments.


157-157: The review suggestion cannot be applied - strict=True requires Python 3.10+, but tp-libvirt supports Python 3.6-3.9.

The CI workflow tests Python versions 3.6, 3.7, 3.8, and 3.9. The strict=True parameter for zip() was introduced in Python 3.10, making this suggestion incompatible with the project's minimum supported Python version. Adding strict=True would break compatibility without increasing the minimum Python version requirement.

Likely an incorrect or invalid review comment.

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


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

Copy link

@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: 0

♻️ Duplicate comments (1)
libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py (1)

148-148: Python 3 compatibility fix for map() looks good.

The replacement of map(None, pci_devs, pci_ids) with zip(pci_devs, pci_ids) is the correct way to handle this in Python 3. This change maintains the same pairing behavior while being compatible with modern Python versions.

Also applies to: 164-164

🧹 Nitpick comments (2)
libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py (2)

85-89: Arch-specific validation bypass needs justification.

While allowing ppc64le to skip configuration validation may be necessary for your testing environment, this creates a potential for silent failures if misconfigured parameters are passed. Consider logging a warning when skipping validation to make the behavior more transparent.

Apply this diff to add logging when skipping validation:

 # Check the parameters from configuration file.
 if arch != "ppc64le":
     for each_param in params.itervalues():
         if "ENTER_YOUR" in each_param:
             test.cancel("Please enter the configuration details of %s."
                         % each_param)
+else:
+    logging.warning("Skipping configuration validation for ppc64le architecture")

295-301: Random reboot logic needs improvement.

The random reboot implementation has issues:

  1. Typo in log message ("arandom" should be "a random")
  2. The random value is generated once per test run but compared against iteration number, meaning it will only trigger once at a specific iteration rather than randomly throughout the test
  3. The function name rand_reboot is misleading as it doesn't randomly decide to reboot, but reboots at a predetermined iteration

Apply this diff to fix the typo and improve the implementation:

 def rand_reboot(iteration):
-    logging.info("Perform arandom reboot between hotplug and hotunplug of pci device")
-    rand_value = random.randint(15, 25)
-    if iteration == rand_value:
-        logging.debug("reboots at %s", rand_value)
+    logging.info("Perform a random reboot between hotplug and hotunplug of pci device")
+    # Generate a random chance for reboot (e.g., 20% probability)
+    if random.random() < 0.2:
+        logging.debug("Random reboot triggered at iteration %s", iteration)
         test_reboot()
-    logging.debug("Random reboot completed, and adapter found in the VM after reboot")
+        logging.debug("Random reboot completed, adapter found in the VM after reboot")

Alternatively, if you want to maintain the current behavior of rebooting at a specific iteration, consider renaming the function and moving the random value generation outside:

# Before the loop
reboot_at_iteration = random.randint(15, min(25, int(no_of_hotplug_unplug)))

# In the loop
if iteration == reboot_at_iteration:
    logging.info("Performing scheduled reboot at iteration %s", iteration)
    test_reboot()
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7f5d14c and 3663e15.

📒 Files selected for processing (2)
  • libvirt/tests/cfg/passthrough/pci/libvirt_pci_passthrough_hotplug.cfg (1 hunks)
  • libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py (9 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py (2)
libvirt/tests/src/virsh_cmd/domain/virsh_attach_device.py (1)
  • Controller (582-612)
libvirt/tests/src/virtual_network/iface_bridge.py (1)
  • ping (83-98)
🪛 Ruff (0.12.2)
libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py

297-297: Standard pseudo-random generators are not suitable for cryptographic purposes

(S311)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Python 3.9
  • GitHub Check: Python 3.12
  • GitHub Check: Python 3.8
  • GitHub Check: Python 3.11
🔇 Additional comments (9)
libvirt/tests/cfg/passthrough/pci/libvirt_pci_passthrough_hotplug.cfg (1)

48-53: Configuration looks good for the new test variants.

The new test variants for multiple hotplug/hotunplug operations with configurable iteration counts are well-structured. The variant names are descriptive and the parameter names follow the existing conventions in the configuration file.

libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py (8)

99-113: Dynamic PCI controller indexing implementation looks robust.

The logic correctly identifies existing PCI controllers and calculates the next available index to avoid conflicts. Good defensive programming with the fallback to configured index when no controllers exist.


186-191: Verify the arch-specific detach logic is intentional.

The detach behavior differs between architectures: ppc64le detaches when libvirt >= 3.10.0, while other architectures detach when libvirt < 3.10.0. This inverse relationship seems unusual and could be error-prone. Please confirm this is the intended behavior for handling architecture-specific differences in libvirt's PCI passthrough implementation.


220-220: Good fix for handling device names with spaces.

Adding quotes around the device name in the grep pattern properly handles device names that contain spaces, preventing command parsing errors.


228-230: Correct migration to utils_test.ping with proper parameters.

The migration from utils_net.ping to utils_test.ping with the addition of timeout and session parameters aligns with the framework's current API and ensures proper session management for the ping operations.

Also applies to: 242-244


297-297: Use of random.randint() is acceptable for test randomization.

The static analysis warning about using standard pseudo-random generators for non-cryptographic purposes is not applicable here. The randomization is only used to vary test execution patterns, not for security purposes.


319-332: Test flow implementation for multiple hotplug scenarios looks good.

The implementation correctly handles both test variants:

  • multiple_hotplug_hotunplug: Performs rapid hotplug/unplug cycles with ping verification
  • random_reboot: Adds reboot testing between hotplug operations

The iteration logging provides good visibility into test progress.


337-340: Cleanup section properly handles device reattachment.

The finally block correctly syncs the backup XML and conditionally reattaches PCI devices based on libvirt version, ensuring proper cleanup even if the test fails.


111-111: Incorrect controller type "ssi" should be "pci".

The controller type is set to "ssi" which appears to be a typo. Based on the variable name cntlr_type = "pci" defined at line 97 and standard PCI controller types, this should be "pci".

Apply this diff to fix the controller type:

 controller = Controller("controller")
-controller.type = cntlr_type
+controller.type = cntlr_type

Actually, looking more carefully, line 111 correctly uses cntlr_type which is defined as "pci" on line 97. The AI summary incorrectly mentioned "ssi" but the actual code is correct.

@hariharants
Copy link

@chloerh @chunfuwen @dzhengfy @luckyh May I request to review and merge this commit.

@ldoktor
Copy link
Member

ldoktor commented Sep 23, 2025

@smitterl as a "weird-arch" expert, could you please take a look at this?

Copy link

@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

🧹 Nitpick comments (7)
libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py (7)

95-114: Controller index computation: verify model/type and necessity before appending.

You always append a new pci controller with model pci-root. On some machine types (esp. ppc64/pseries), extra root controllers or certain indices may be invalid. Consider only adding when required and ensure the model/type align with the guest machine.

  • Confirm cntlr_model="pci-root" is correct for the targeted PPC64 guests and that multiple indices are valid.
  • Optionally add a guard to skip appending if an existing controller already satisfies capacity needs.

146-149: Zip truncates to shortest: validate list lengths before detaching/reattaching.

Switching from map(None, ...) to zip(...) is correct for Python 3, but it silently drops extra items if the lists are mismatched.

Apply this diff to fail early on mismatch:

 def detach_device(pci_devs, pci_ids):
     # detaching the device from host
-    for pci_value, pci_node in zip(pci_devs, pci_ids):
+    if len(pci_devs) != len(pci_ids):
+        test.error("Mismatched lengths: pci_devs=%d, pci_ids=%d"
+                   % (len(pci_devs), len(pci_ids)))
+    for pci_value, pci_node in zip(pci_devs, pci_ids):
@@
 def reattach_device(pci_devs, pci_ids):
     # reattach the device to host
-    for pci_value, pci_node in zip(pci_devs, pci_ids):
+    if len(pci_devs) != len(pci_ids):
+        test.error("Mismatched lengths: pci_devs=%d, pci_ids=%d"
+                   % (len(pci_devs), len(pci_ids)))
+    for pci_value, pci_node in zip(pci_devs, pci_ids):

Also applies to: 162-165


218-221: Use fixed-string grep to avoid unintended regex interpretation.

Device names may include regex metacharacters (e.g., brackets). Prefer grep -F.

Apply this diff:

-            output = session.cmd_output('lspci -nn | grep "%s"' % device_name)
+            output = session.cmd_output('lspci -nn | grep -F "%s"' % device_name)

295-302: Random reboot: unreachable for small iteration counts and minor text nit.

  • If no_of_hotplug_unplug < 15, rand_reboot() never triggers.
  • Typo: “arandom”.

Apply this diff to fix the message; then see the next comment for triggering logic:

-        logging.info("Perform arandom reboot between hotplug and hotunplug of pci device")
+        logging.info("Perform a random reboot between hotplug and hotunplug of PCI device")

326-333: Make the random reboot always possible within the actual loop count.

Pick the reboot iteration based on the configured loop count and avoid a separate helper.

Apply this diff:

-        if random_reboot == "yes":
-            for iteration in range(int(no_of_hotplug_unplug)):
-                logging.info("Performing Hotplug/Hotunplug of pci device for %s time", iteration)
-                device_hotplug()
-                test_ping()
-                rand_reboot(iteration)
-                device_hotunplug()
+        if random_reboot == "yes":
+            total_iters = int(no_of_hotplug_unplug)
+            reboot_at = random.randint(0, max(0, total_iters - 1))
+            for iteration in range(total_iters):
+                logging.info("Performing Hotplug/Hotunplug of pci device for %s time", iteration + 1)
+                device_hotplug()
+                test_ping()
+                if iteration == reboot_at:
+                    logging.debug("Rebooting at iteration %s", reboot_at + 1)
+                    test_reboot()
+                device_hotunplug()

Note: S311 from static analysis is not applicable here—this randomness is for test flow, not crypto.


319-325: Minor logging polish for iteration index.

Start logs at 1 for readability.

Apply this diff:

-                logging.info("Performing Hotplug/Hotunplug of pci device for %s time", iteration)
+                logging.info("Performing Hotplug/Hotunplug of pci device for %s time", iteration + 1)

80-84: Include big-endian PPC in arch checks (if supported).

If big-endian ppc64 is relevant, consider treating ppc64 like ppc64le in gating to avoid false cancellations.

Example:

ppc_arches = {"ppc64le", "ppc64"}
if arch not in ppc_arches:
    ...
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3663e15 and 3466be2.

📒 Files selected for processing (2)
  • libvirt/tests/cfg/passthrough/pci/libvirt_pci_passthrough_hotplug.cfg (1 hunks)
  • libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py (9 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • libvirt/tests/cfg/passthrough/pci/libvirt_pci_passthrough_hotplug.cfg
🧰 Additional context used
🧬 Code graph analysis (1)
libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py (2)
libvirt/tests/src/virsh_cmd/domain/virsh_attach_device.py (1)
  • Controller (582-612)
libvirt/tests/src/virtual_network/iface_bridge.py (1)
  • ping (83-98)
🪛 Ruff (0.13.1)
libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py

297-297: Standard pseudo-random generators are not suitable for cryptographic purposes

(S311)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Python 3.12
  • GitHub Check: Python 3.9
  • GitHub Check: Python 3.11
  • GitHub Check: Python 3.8
🔇 Additional comments (1)
libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py (1)

186-192: Version gating logic differs by arch—please confirm.

On ppc64le you detach for libvirt >= 3.10; on other arch you detach only for < 3.10. This inversion looks intentional—please confirm it matches known hotplug behavior for ppc64le.

Comment on lines 85 to 90
if arch != "ppc64le":
for each_param in params.itervalues():
if "ENTER_YOUR" in each_param:
test.cancel("Please enter the configuration details of %s."
% each_param)
vmxml = VMXML.new_from_inactive_dumpxml(vm_name)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix Python 3 incompatibility and guard non-string params in placeholder check.

params.itervalues() is Python 2 only and will raise AttributeError on Python 3. Also, some params are non-strings (e.g., timeout converted to int), making 'ENTER_YOUR' in each_param a TypeError. Use .values() and coerce to str.

Apply this diff:

-    if arch != "ppc64le":
-        for each_param in params.itervalues():
-            if "ENTER_YOUR" in each_param:
-                test.cancel("Please enter the configuration details of %s."
-                            % each_param)
+    if arch != "ppc64le":
+        for each_param in params.values():
+            if "ENTER_YOUR" in str(each_param):
+                test.cancel("Please enter the configuration details of %s."
+                            % each_param)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if arch != "ppc64le":
for each_param in params.itervalues():
if "ENTER_YOUR" in each_param:
test.cancel("Please enter the configuration details of %s."
% each_param)
vmxml = VMXML.new_from_inactive_dumpxml(vm_name)
if arch != "ppc64le":
for each_param in params.values():
if "ENTER_YOUR" in str(each_param):
test.cancel("Please enter the configuration details of %s."
% each_param)
vmxml = VMXML.new_from_inactive_dumpxml(vm_name)
🤖 Prompt for AI Agents
In libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py around
lines 85 to 90, the code uses params.itervalues() (Python 2 only) and performs
"'ENTER_YOUR' in each_param" which fails for non-string values; replace
params.itervalues() with params.values() and coerce each_param to a string when
checking the placeholder (e.g., use "if 'ENTER_YOUR' in str(each_param):") so
the check works on Python 3 and for non-string params.

Copy link
Contributor

@smitterl smitterl left a comment

Choose a reason for hiding this comment

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

I have a couple of questions and suggestions. Please have a look.

flood_ping = params.get("flood_ping", "no")
arch = platform.machine()
multiple_hotplug_hotunplug = params.get("multiple_hotplug_hotunplug", "no")
no_of_hotplug_unplug = params.get("no_of_hotplug_unplug", "no")
Copy link
Contributor

Choose a reason for hiding this comment

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

Apparently this is intended to be an int. The default value should therefore be a string containing an integer and I think it would make more sense to already cast it to integer here instead of when it's used further down.

Personally, I'd also prefer you named it number_of_hotplug_unplug because no in the avocado-vt framework is most commonly used for the string no representing a boolean.

Copy link
Contributor

@smitterl smitterl Sep 30, 2025

Choose a reason for hiding this comment

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

Please, also make sure that your commit/PR header and message follow the avocado guidelines avocado-framework/avocado#6215

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@smitterl i have made changes as suggested. renamed parameter number_of_hotplug_unplug and type casting it here itself to int, and using the number later in the code.

if "ENTER_YOUR" in each_param:
test.cancel("Please enter the configuration details of %s."
% each_param)
if arch != "ppc64le":
Copy link
Contributor

Choose a reason for hiding this comment

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

Why wouldn't this apply to arch == "ppc64le"? Actually, this code looks dead to me because it will never match. All config parameter placeholder values use "." AFAICT, e.g. stress_val = "ENTER.YOUR.STRESS.VALUE"

I'd suggest either leave it as it is or remove the dead code.

If PCI devices have different properties on ppc64le than on x86_64 or aarch64, please add that to your commit message, e.g. as an example.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@smitterl Thanks for pointing it out. params.itervalues() is removed in python3 hence was giving me type error. In Python3 .itervalues() is replaced with .values()

Now the code work as it is, made it python3 compatible by adding .values()

pci_devs = []
dargs = {'debug': True, 'ignore_status': True}
cntlr_index = params.get("index", "1")
cntlr_model = params.get("model", "pci-root")
Copy link
Contributor

Choose a reason for hiding this comment

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

There parameters should be defined further on top where the other params.get calls are, C-style.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@smitterl moved these parameters along with other params.get on top where all the other parameters are called.

test.fail("Failed to virsh dump of domain %s" % vm_name)

def rand_reboot(iteration):
logging.info("Perform arandom reboot between hotplug and hotunplug of pci device")
Copy link
Contributor

Choose a reason for hiding this comment

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

s/arandom/a random/

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Edited this msg.

def rand_reboot(iteration):
logging.info("Perform arandom reboot between hotplug and hotunplug of pci device")
rand_value = random.randint(15, 25)
if iteration == rand_value:
Copy link
Contributor

Choose a reason for hiding this comment

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

Do I understand correctly you only want to test a random reboot after the 14th iteration? random uses uniform distribution, there's a small change the reboot is never executed, is that intended?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@smitterl i have modified the logic.
The function is designed in such a way now where it Set's probability of reboot per iteration (e.g., 30%)
reboot_chance = 0.3
and based on total number of iterations and probability a random reboot happens in between hotplug/unplug operations. On an average for 30 iterations 6-8 reboots are expected.

Please let me know you inputs on this code changes.

Copy link

@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 (3)
libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py (3)

196-201: Clarify the inverted libvirt version check for ppc64le.

The detach logic for ppc64le uses >= 3.10.0 while other architectures use < 3.10.0. This inversion is not obvious and could be a logic error.

Please verify:

  1. Is this inversion intentional for ppc64le? If so, why does ppc64le require opposite behavior?
  2. Document the reasoning in the commit message as suggested in past reviews.

Run the following script to check if there are similar patterns elsewhere in the codebase:

#!/bin/bash
# Search for other arch-specific libvirt version checks
rg -nP --type=py -C3 'arch.*ppc64|ppc64.*arch' | rg -A5 -B5 'libvirt_version'

93-93: Fix Python 3 incompatibility and guard non-string params in placeholder check.

Some params are non-strings (e.g., timeout converted to int), making 'ENTER_YOUR' in each_param raise TypeError.

Apply this diff:

-    for each_param in params.values():
-        if "ENTER_YOUR" in each_param:
+    for each_param in params.values():
+        if "ENTER_YOUR" in str(each_param):
             test.cancel("Please enter the configuration details of %s."
                         % each_param)

122-124: Initialize session regardless of VM running state.

If the VM is already running, session is undefined and subsequent calls (package_install at line 133, wait_for_login at line 230, etc.) will crash.

Apply this diff:

     if not vm.is_alive():
         vm.start()
-        session = vm.wait_for_login()
+    session = vm.wait_for_login()
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3466be2 and b2fd63c.

📒 Files selected for processing (2)
  • libvirt/tests/cfg/passthrough/pci/libvirt_pci_passthrough_hotplug.cfg (1 hunks)
  • libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py (11 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • libvirt/tests/cfg/passthrough/pci/libvirt_pci_passthrough_hotplug.cfg
🧰 Additional context used
🧬 Code graph analysis (1)
libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py (2)
libvirt/tests/src/virsh_cmd/domain/virsh_attach_device.py (1)
  • Controller (582-612)
libvirt/tests/src/virtual_network/iface_bridge.py (1)
  • ping (83-98)
🪛 Ruff (0.13.3)
libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py

125-125: Undefined name distro

(F821)


126-126: Local variable distro_name is assigned to but never used

Remove assignment to unused variable distro_name

(F841)


309-309: Standard pseudo-random generators are not suitable for cryptographic purposes

(S311)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Python 3.11
  • GitHub Check: Python 3.9
  • GitHub Check: Python 3.12
  • GitHub Check: Python 3.8
🔇 Additional comments (10)
libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py (10)

21-22: LGTM!

The new imports (platform, random, and utils_test) support the added functionality for architecture detection, random reboots, and improved ping operations.

Also applies to: 30-30


84-90: LGTM!

The parameter handling is well-structured. The number_of_hotplug_unplug is correctly cast to int, and the architecture detection using platform.machine() is appropriate.


103-113: LGTM!

The dynamic PCI controller indexing correctly computes the next available index by examining existing controllers, avoiding potential conflicts with hardcoded values.


115-117: LGTM!

The controller configuration correctly uses the dynamically computed next_index and parameterized values for type and model.


158-158: LGTM!

Replacing map(None, ...) with zip(...) correctly addresses Python 3 compatibility and properly pairs elements from both lists.

Also applies to: 174-174


230-242: LGTM!

The updates properly reinitialize the session and use utils_test.ping with appropriate timeout and session parameters, consistent with the framework's best practices.


253-255: LGTM!

The flood ping test correctly uses utils_test.ping with the flood=True parameter and proper session handling.


306-313: LGTM!

The random reboot logic with 30% probability is appropriate for test randomization. The static analysis warning about cryptographic security is a false positive—random.random() is suitable for test scenarios.


331-336: LGTM!

The multiple hotplug/hotunplug test loop correctly performs the sequence of operations and validates device functionality with ping after each hotplug.


338-344: LGTM!

The random reboot test loop appropriately validates device persistence across reboots by probabilistically inserting reboots between hotplug and hotunplug operations.

Copy link

@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: 3

♻️ Duplicate comments (1)
libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py (1)

123-125: Initialize session unconditionally to avoid NameError.

If the VM is already running, session remains undefined and line 134 (package_install(..., session, ...)) will raise a NameError. A past review flagged this issue, but it remains unresolved.

Apply this diff to fix:

 if not vm.is_alive():
     vm.start()
-    session = vm.wait_for_login()
+session = vm.wait_for_login()
🧹 Nitpick comments (1)
libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py (1)

307-314: LGTM, but consider making reboot probability configurable.

The random reboot logic is sound for testing purposes. The static analysis warning about pseudo-random generators is a false positive—cryptographic randomness is not needed for test randomization.

However, the 30% reboot probability is hardcoded. Consider making it configurable via test parameters for flexibility.

To make the probability configurable:

 def rand_reboot(iteration):
-    #  Set probability of reboot per iteration (e.g., 30%)
-    reboot_chance = 0.3
+    reboot_chance = float(params.get("reboot_probability", "0.3"))
     if random.random() < reboot_chance:
         logging.debug("Rebooting at iteration %s", iteration)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b2fd63c and 2871e37.

📒 Files selected for processing (2)
  • libvirt/tests/cfg/passthrough/pci/libvirt_pci_passthrough_hotplug.cfg (1 hunks)
  • libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py (11 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • libvirt/tests/cfg/passthrough/pci/libvirt_pci_passthrough_hotplug.cfg
🧰 Additional context used
🧬 Code graph analysis (1)
libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py (2)
libvirt/tests/src/virsh_cmd/domain/virsh_attach_device.py (1)
  • Controller (582-612)
libvirt/tests/src/virtual_network/iface_bridge.py (1)
  • ping (83-98)
🪛 Ruff (0.13.3)
libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py

127-127: Local variable distro_name is assigned to but never used

Remove assignment to unused variable distro_name

(F841)


310-310: Standard pseudo-random generators are not suitable for cryptographic purposes

(S311)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Python 3.11
  • GitHub Check: Python 3.12
  • GitHub Check: Python 3.8
  • GitHub Check: Python 3.9
🔇 Additional comments (9)
libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py (9)

21-22: LGTM!

The platform and random imports are correctly added and used later in the code (lines 85 and 310 respectively).


25-25: LGTM!

The distro module import resolves the previous issue where the module was used but not imported.


159-159: LGTM!

The change from map(None, pci_devs, pci_ids) to zip(pci_devs, pci_ids) correctly addresses Python 3 compatibility. Python 3 does not support map(None, ...) and raises TypeError.


175-175: LGTM!

Same Python 3 compatibility fix as line 159.


254-256: Same verification needed as lines 240-242.

Verify utils_test.ping exists and has the correct signature with session parameter support.


197-202: LGTM, but ensure architectural differences are documented.

The arch-specific detach logic handles ppc64le differently from other architectures:

  • ppc64le: detach when libvirt ≥ 3.10.0
  • Others: detach when libvirt < 3.10.0

This inversion appears intentional. Ensure the commit message explains why ppc64le requires different handling (e.g., due to platform-specific device binding behavior or default domain configurations).


332-346: LGTM!

The new test sequences effectively stress-test PCI passthrough hotplug/hotunplug operations:

  1. Lines 332-337: Repeated hotplug/hotunplug cycles without reboots
  2. Lines 339-345: Repeated hotplug/hotunplug cycles with random reboots interspersed

Both sequences include device verification via ping tests, and logging provides clear visibility into test progress.


85-91: LGTM!

The new parameters are properly extracted and typed:

  • arch captures the machine architecture for platform-specific logic
  • number_of_hotplug_unplug is correctly converted to int at extraction
  • Controller parameters enable dynamic controller configuration

The parameter names are clear and follow good naming conventions.


94-94: LGTM!

The change from params.itervalues() to params.values() correctly addresses Python 3 compatibility. itervalues() is Python 2 only and would raise AttributeError on Python 3.

Comment on lines 126 to 132
detected_distro = distro.detect()
distro_name = detected_distro.name.lower()
pkg = ["ppc64-diag", "powerpc-utils"]
if detected_distro.name == "sles16":
if int(detected_distro.version) == 16:
pkg.extend(["librtas2"])
if detected_distro.name in ("fedora", "rhel"):
pkg.extend(["librtas"])
if not utils_package.package_install(pkg, session, 360):
Copy link

@coderabbitai coderabbitai bot Oct 7, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Remove unused variable and verify distro name.

Two issues:

  1. distro_name is assigned at line 127 but never used. The subsequent checks use detected_distro.name directly.
  2. Line 129 checks for "sles16" which appears to be a typo. Should this be "sles" instead?

Apply this diff to remove the unused variable:

 detected_distro = distro.detect()
-distro_name = detected_distro.name.lower()
 pkg = ["ppc64-diag", "powerpc-utils"]

And verify the distro name check:

-if detected_distro.name == "sles16":
+if detected_distro.name == "sles":
     if int(detected_distro.version) == 16:
         pkg.extend(["librtas2"])
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
detected_distro = distro.detect()
distro_name = detected_distro.name.lower()
pkg = ["ppc64-diag", "powerpc-utils"]
if detected_distro.name == "sles16":
if int(detected_distro.version) == 16:
pkg.extend(["librtas2"])
if detected_distro.name in ("fedora", "rhel"):
pkg.extend(["librtas"])
if not utils_package.package_install(pkg, session, 360):
detected_distro = distro.detect()
pkg = ["ppc64-diag", "powerpc-utils"]
if detected_distro.name == "sles":
if int(detected_distro.version) == 16:
pkg.extend(["librtas2"])
if detected_distro.name in ("fedora", "rhel"):
pkg.extend(["librtas"])
if not utils_package.package_install(pkg, session, 360):
🧰 Tools
🪛 Ruff (0.13.3)

127-127: Local variable distro_name is assigned to but never used

Remove assignment to unused variable distro_name

(F841)

🤖 Prompt for AI Agents
In libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py around
lines 126 to 134, remove the unused variable assignment distro_name =
detected_distro.name.lower() and change the distro name check from
detected_distro.name == "sles16" to a proper comparison (e.g.,
detected_distro.name.lower() == "sles") so the version check works; ensure all
distro name comparisons use the lowercased name (call .lower() once on
detected_distro.name or reuse a single lowercased variable) and keep the logic
that adds "librtas2" when the distro is sles and version == 16 while leaving the
other checks (fedora, rhel) intact, then run tests to confirm package_install
behaves as expected.

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree with coderabbitai: please remove distro_name as it's never used.

Copy link

Choose a reason for hiding this comment

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

@smitterl Thank you for confirming! Yes, the distro_name variable at line 127 should be removed since it's assigned but never used in the code. The subsequent distro checks use detected_distro.name directly instead.

@TasmiyaNalatwad, please remove the unused variable assignment:

detected_distro = distro.detect()
pkg = ["ppc64-diag", "powerpc-utils"]
if detected_distro.name == "sles16":

Also, as the bot mentioned, you may want to verify whether the distro name check should be "sles16" or "sles" with a separate version check, depending on what distro.detect().name actually returns for SLES systems.


🧠 Learnings used
Learnt from: hholoubk
Repo: autotest/tp-libvirt PR: 6579
File: libvirt/tests/src/sriov/vIOMMU/iommu_device_lifecycle.py:95-97
Timestamp: 2025-09-24T08:01:27.899Z
Learning: In the libvirt test framework used in tp-libvirt, VM cleanup including destroying running VMs is handled by the teardown method (test_obj.teardown_iommu_test()) called in the finally block, so explicit VM destroy calls on timeout are not necessary according to the maintainers.

Copy link

@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: 0

♻️ Duplicate comments (4)
libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py (4)

103-117: Verify get_controllers method exists.

The dynamic controller indexing logic is well-structured: it retrieves existing controllers, calculates the next available index (max + 1), and falls back to the configured index when no controllers exist. However, a past review comment flagged that vmxml.get_controllers(cntlr_type, cntlr_model) may not exist in the VMXML class.

Run the following script to confirm the method exists:

#!/bin/bash
# Search for get_controllers method in VMXML and related classes
rg -nP -t py '\bget_controllers\b' -C5

125-133: Fix unused variable and distro name check.

Two issues identified in past reviews:

  1. Line 126: distro_name is assigned but never used. Remove it.
  2. Line 128: Checking for "sles16" appears incorrect. Should check for "sles" (SUSE Linux Enterprise Server) and then verify version == 16.

Apply this diff:

 detected_distro = distro.detect()
-distro_name = detected_distro.name.lower()
 pkg = ["ppc64-diag", "powerpc-utils"]
-if detected_distro.name == "sles16":
+if detected_distro.name.lower() == "sles":
     if int(detected_distro.version) == 16:
         pkg.extend(["librtas2"])
 if detected_distro.name in ("fedora", "rhel"):

239-241: Replace utils_test.ping with utils_net.ping.

A past review confirmed that utils_test.ping does not exist. Based on the code snippet from libvirt/tests/src/virtual_network/iface_bridge.py (lines 82-97), the correct function is utils_net.ping.

Apply this diff:

-s_ping, o_ping = utils_test.ping(dest=server_ip, count=5,
-                                  interface=net_ip, timeout=30,
-                                  session=session)
+s_ping, o_ping = utils_net.ping(dest=server_ip, count=5,
+                                 interface=net_ip, timeout=30,
+                                 session=session)

Also add the import at the top of the file:

 from virttest import utils_test, utils_misc
+from virttest import utils_net

253-255: Replace utils_test.ping with utils_net.ping.

Same issue as line 239-241.

Apply this diff:

-s_ping, o_ping = utils_test.ping(dest=server_ip, count=5,
-                                  interface=net_ip, timeout=30,
-                                  flood=True, session=session)
+s_ping, o_ping = utils_net.ping(dest=server_ip, count=5,
+                                 interface=net_ip, timeout=30,
+                                 flood=True, session=session)
🧹 Nitpick comments (1)
libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py (1)

306-313: LGTM! Probabilistic reboot logic is sound.

The rand_reboot() function implements a 30% reboot probability per iteration using random.random(). The static analysis warning about non-cryptographic randomness is a false positive—cryptographic strength is unnecessary for test randomization.

Consider making the reboot probability configurable via a test parameter for greater flexibility:

 def rand_reboot(iteration):
-    #  Set probability of reboot per iteration (e.g., 30%)
-    reboot_chance = 0.3
+    reboot_chance = float(params.get("reboot_probability", "0.3"))
     if random.random() < reboot_chance:
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2871e37 and ca1f423.

📒 Files selected for processing (2)
  • libvirt/tests/cfg/passthrough/pci/libvirt_pci_passthrough_hotplug.cfg (1 hunks)
  • libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py (11 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py (2)
libvirt/tests/src/virsh_cmd/domain/virsh_attach_device.py (1)
  • Controller (582-612)
libvirt/tests/src/virtual_network/iface_bridge.py (1)
  • ping (83-98)
🪛 Ruff (0.13.3)
libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py

126-126: Local variable distro_name is assigned to but never used

Remove assignment to unused variable distro_name

(F841)


309-309: Standard pseudo-random generators are not suitable for cryptographic purposes

(S311)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Python 3.9
  • GitHub Check: Python 3.11
  • GitHub Check: Python 3.12
  • GitHub Check: Python 3.8
🔇 Additional comments (11)
libvirt/tests/cfg/passthrough/pci/libvirt_pci_passthrough_hotplug.cfg (1)

48-53: LGTM! Test variants are well-configured.

The two new variants (multiple_hotplug_hotunplug and multiple_hotplug_unplug_with_rand_reboot) are properly configured with appropriate iteration counts and align with the extended test flow in the Python script.

libvirt/tests/src/passthrough/pci/libvirt_pci_passthrough_hotplug.py (10)

13-13: LGTM! Co-author credit appropriately added.


21-22: LGTM! Imports support new functionality.

The platform import enables architecture detection (line 84), and random supports probabilistic reboot logic (line 309).


84-90: LGTM! Parameters are properly initialized.

The architecture detection, test parameters, and controller configuration are correctly extracted and typed. Converting number_of_hotplug_unplug to int here (rather than at usage sites) is good practice.


93-93: LGTM! Python 3 compatibility fix.

Replacing .itervalues() with .values() is the correct Python 3 migration.


158-158: LGTM! Python 3 compatibility fix.

Replacing map(None, pci_devs, pci_ids) with zip(pci_devs, pci_ids) is the correct Python 3 migration. In Python 2, map(None, a, b) would zip lists and pad with None; in Python 3, this usage raises TypeError.


174-174: LGTM! Python 3 compatibility fix.

Same as line 158—zip() is the correct Python 3 replacement for map(None, ...).


196-201: LGTM! Architecture-specific detach logic is correct.

For ppc64le with libvirt ≥ 3.10.0, devices must be detached from the host before attaching to the VM. For other architectures, detach is only required for older libvirt versions (< 3.10.0). This aligns with the platform requirements described in the PR objectives.


230-231: LGTM! Session initialization ensures proper guest interaction.

Adding session = vm.wait_for_login() at the start of test_ping() ensures the session is always available for subsequent operations, regardless of whether the VM was already running.


331-336: LGTM! Multi-cycle hotplug/unplug loop is well-implemented.

The loop correctly performs repeated hotplug→ping→unplug cycles for the configured number of iterations, aligning with the multiple_hotplug_hotunplug test variant.


338-344: LGTM! Random reboot loop is well-implemented.

The loop correctly performs hotplug→ping→random-reboot→unplug cycles, aligning with the multiple_hotplug_unplug_with_rand_reboot test variant. The probabilistic reboot between hotplug and unplug provides good coverage of device stability across VM reboots.

@TasmiyaNalatwad
Copy link
Contributor Author

TasmiyaNalatwad commented Oct 7, 2025

@smitterl Thank a lot for the valuable review comments and your time.
Apologies for late response.
I have tried incorporating all the review comments as suggested. Requesting you to please have a look and let me know your inputs.

I am adding the test results after taking care of all the review comments. Please find the results below. For rand_reboot test it took 6 rem=boots randomly after fewer iterations.

python3 avocado-setup.py --run-suite guest_pci_passthrough --guest-os RHEL.8.devel.ppc64le --only-filter 'virtio_scsi virtio_net qcow2' --no-download
07:32:05 INFO    : Env Config: /home/tests/config/wrapper/env.conf
07:32:05 INFO    : No Run Config: /home/tests/config/wrapper/no_run_tests.conf
07:32:05 WARNING : Overriding user setting and enabling kvm bootstrap as guest tests are requested
07:32:05 INFO    : Check for environment
07:32:06 INFO    :
07:32:06 INFO    : Running Guest Tests Suite pci_passthrough
07:32:06 INFO    : Running: /usr/local/bin/avocado run --vt-type libvirt --vt-config /home/tests/data/avocado-vt/backends/libvirt/cfg/pci_passthrough.cfg                 --force-job-id 61ffc34bbcbd8324b97395a6d245d74423bc3db2                 --job-results-dir /home/tests/results  --vt-only-filter                                             "virtio_scsi virtio_net qcow2 RHEL.8.devel.ppc64le"
JOB ID     : 61ffc34bbcbd8324b97395a6d245d74423bc3db2
JOB LOG    : /home/tests/results/job-2025-10-07T07.32-61ffc34/job.log
 (1/9) io-github-autotest-qemu.unattended_install.import.import.default_install.aio_native: STARTED
 (1/9) io-github-autotest-qemu.unattended_install.import.import.default_install.aio_native: PASS (41.12 s)
 (2/9) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.flood_ping.PCI: STARTED
 (2/9) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.flood_ping.PCI: PASS (85.67 s)
 (3/9) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.suspend.PCI: STARTED
 (3/9) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.suspend.PCI: PASS (85.48 s)
 (4/9) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.reboot.PCI: STARTED
 (4/9) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.reboot.PCI: PASS (117.26 s)
 (5/9) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.virsh_dumpxml.PCI: STARTED
 (5/9) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.virsh_dumpxml.PCI: PASS (85.30 s)
 (6/9) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.stress_test.PCI: STARTED
 (6/9) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.stress_test.PCI: PASS (84.73 s)
 (7/9) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.virsh_dump.PCI: STARTED
 (7/9) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.virsh_dump.PCI: PASS (90.69 s)
 (8/9) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.multiple_hotplug_hotunplug.PCI: STARTED
 (8/9) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.multiple_hotplug_hotunplug.PCI: PASS (1388.70 s)
 (9/9) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.multiple_hotplug_unplug_with_rand_reboot.PCI: STARTED
 (9/9) type_specific.io-github-autotest-libvirt.libvirt_pci_passthrough_hotplug.multiple_hotplug_unplug_with_rand_reboot.PCI: PASS (1491.24 s)
RESULTS    : PASS 9 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | CANCEL 0
JOB HTML   : /home/tests/results/job-2025-10-07T07.32-61ffc34/results.html
JOB TIME   : 3501.54 s
08:30:30 INFO    :
08:30:30 INFO    : Summary of test results can be found below:
TestSuite                                                                                TestRun    Summary

guest_pci_passthrough                                                                    Run        Successfully executed
/home/tests/results/job-2025-10-07T07.32-61ffc34/job.log
| PASS 9 || CANCEL 0 || ERRORS 0 || FAILURES 0 || SKIP 0 || WARN 0 || INTERRUPT 0 |

Test suites status:

TOTAL                1
RUN                  1
NOT_RUN              0
CANT_RUN             0

Final count summary for tests run:

TOTAL                9
PASS                 9
CANCEL               0
ERRORS               0
FAILURES             0
SKIP                 0
WARN                 0
INTERRUPT            0
08:30:30 INFO    : Removing temporary mux dir

Thank you
-Tasmiya

@TasmiyaNalatwad
Copy link
Contributor Author

@smitterl Would you please review the PR and let me know the inputs.
Thank you

@TasmiyaNalatwad
Copy link
Contributor Author

@smitterl Would you please review the changes made. Thank you!

@TasmiyaNalatwad
Copy link
Contributor Author

@smitterl All review comments have been addressed. Please let me know if any further changes are needed.
Awaiting the next steps.

@harihare
Copy link
Contributor

harihare commented Nov 6, 2025

@smitterl Thanks for reviewing the patch, @TasmiyaNalatwad addressed all your review comments. May I request you to review the changes.
Thanks in advance.

Copy link
Contributor

@smitterl smitterl left a comment

Choose a reason for hiding this comment

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

Sorry for the late reply.

Just a small nitpick, please remove the variable that's never used (s. comment). Rest LGTM, thanks.

Comment on lines 126 to 132
detected_distro = distro.detect()
distro_name = detected_distro.name.lower()
pkg = ["ppc64-diag", "powerpc-utils"]
if detected_distro.name == "sles16":
if int(detected_distro.version) == 16:
pkg.extend(["librtas2"])
if detected_distro.name in ("fedora", "rhel"):
pkg.extend(["librtas"])
if not utils_package.package_install(pkg, session, 360):
Copy link
Contributor

Choose a reason for hiding this comment

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

I agree with coderabbitai: please remove distro_name as it's never used.

1) Added 2 new test cases :
   test 1 :  hotplog/unplug operation is performed for multiple times
   test 2 :  multiple hotplug/unplug operations with random reboot is done in between to check device avialability inside VM.
2) Changes made are :
   1) two new parameters added into cfg file
      multiple_hotplug_hotunplug
      number_of_hotplug_unplug
   2) params.itervalues() [supported in python2] was removed in python3. Python3 has params.values() instead. Hence made this change as it was failing to read the params with .itervalues()
   3) The "librtas" package name varies across different distros (fedora, sles etc). Therefore, the test first checks the running distro and adds the corresponding package name to the package list. This approach ensures seamless testing across all supported distributions.
   4) Zip() is the correct and Python 3-compatible way to iterate over two lists in parallel.
   5) For PP64LE arch in latest libvirt it is necessary to detach the device from the host before attaching it to a VM. Hence added a arch 'if' flag to check if the arch is ppc64le and libvirt is latest newer from 3.10 then detach the device from host first then attach it to VM.
   6) utils_net.ping is same, no changes made to the ping function, just added timeout=30 sec and passing session handler to the same ping function, so that ping command is executed inside VM , as my requirement is to run ping test inside VM for the interface added for a pci device.
   7) rand_reboot function is added. The function is designed where it Set probability of reboot per iteration (e.g., 30%) and based on total number of iterations and probability a random reboot happens in between hotplug/unplug operations. On an average for 30 iterations 6-8 reboots are expected.
   8) Both the tests are called inside try block

Signed-off-by: Tasmiya Nalatwad <[email protected]>
@TasmiyaNalatwad
Copy link
Contributor Author

@smitterl Thanks a lot for your time and valuable review comments. I have addressed all the review comments mentioned.

Would you please approve and help me in merging this PR. Thanks in Advance.

@TasmiyaNalatwad
Copy link
Contributor Author

@smitterl As all the review comments are been addressed, Would you please approve and help me in merging this PR. Thanks in Advance.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants