Skip to content

test(MTV-5663): add plan archive PVC cleanup regression test - #624

Open
myakove wants to merge 14 commits into
mainfrom
feat/MTV-5663-plan-archive-pvc-cleanup
Open

test(MTV-5663): add plan archive PVC cleanup regression test#624
myakove wants to merge 14 commits into
mainfrom
feat/MTV-5663-plan-archive-pvc-cleanup

Conversation

@myakove

@myakove myakove commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

Regression test for MTV-5564: verifies that archiving and deleting a failed migration plan properly cleans up all PVCs (including prime-* PVCs) in the target namespace.

Test Flow (6-step)

  1. Create StorageMap resource
  2. Create NetworkMap resource
  3. Create Plan with a post-hook configured to fail
  4. Execute migration — migration runs far enough to create PVCs, then fails due to post-hook failure (MigrationPlanExecError)
  5. Archive and delete the failed plan
  6. Verify PVC cleanup — delete any retained VMs, then assert no orphan DVs/PVCs remain in the target namespace

Changes

  • New: tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py — 6-step test class
  • New: tests/plan_lifecycle/__init__.py — package init
  • Modified: tests/tests_config/config.py — added test_plan_archive_pvc_cleanup config entry
  • Modified: utilities/resources.py — added unregister_teardown_resource() for mid-test resource deletion
  • Modified: AGENTS.md — documented unregister_teardown_resource(), removed test execution prohibition

Test Results

  • All 6 steps passed on RHV (ovirt-4.4.9) with nfs-csi storage class
  • Pre-commit clean

Related

Made with Cursor

Summary by CodeRabbit

  • Bug Fixes

    • Fixed cleanup of temporary storage resources after archiving and deleting a failed migration plan.
    • Added cleanup coverage for retained destination virtual machines and other orphaned resources.
  • Documentation

    • Added safety guidance for live test environments, including credentials, namespace isolation, parallel-run considerations, and teardown requirements.
  • Tests

    • Added an end-to-end regression test covering failed migrations, plan deletion, and resource cleanup.

@redhat-qe-bot

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: Disabled for this repository
  • 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: All label categories are enabled (default configuration)

📋 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 (PR author or approvers)
  • /hold cancel - Unblock PR merging (PR author or approvers)
  • /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
  • /security-override - Set security check runs to pass (maintainers only)
  • /security-override cancel - Re-run security checks

Review & Approval

  • /lgtm - Approve changes (looks good to me)
  • /approve - Approve PR (approvers only)
  • /automerge - Enable automatic merging when all requirements are met (maintainers and 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 conventional-title - Validate commit message format
  • /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
  • /cherry-pick-retry <branch> - Retry a failed cherry-pick (merged PRs only)

Branch Management

  • /rebase - Rebase this PR branch onto its base branch

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. Status Checks: All required status checks must pass
  3. No Blockers: No wip, hold, has-conflicts labels and PR must be mergeable (no conflicts)
  4. Verified: PR must be marked as verified

📊 Review Process

Approvers and Reviewers

Approvers:

  • krcmarik
  • myakove
  • solenoci

Reviewers:

  • krcmarik
  • myakove
  • solenoci
Available Labels
  • hold
  • verified
  • wip
  • lgtm
  • approve
  • automerge
AI Features
  • Conventional Title: Mode: fix (claude/claude-opus-4-6-1m)
  • Cherry-Pick Conflict Resolution: Enabled (claude/claude-opus-4-6-1m)
  • Test Oracle: Triggers: approved (cursor/gpt-5.4-xhigh-fast); /test-oracle can be used anytime
Security Checks
  • Suspicious Path Detection: Monitors paths: .claude/, .vscode/, .cursor/, .devcontainer/, .pi/, .github/workflows/, .github/actions/
  • Committer Identity Check: Verifies last committer matches PR author
  • Mandatory: Security checks block merge (use /security-override to bypass — maintainers only)

💡 Tips

  • WIP Status: Use /wip when your PR is not ready for review
  • Verification: The verified label is removed on new commits unless the push is detected as a clean rebase
  • 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.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The PR adds a regression test for PVC and DataVolume cleanup after a failed migration Plan is archived and deleted. It also adds teardown deregistration support, test configuration, and live-cluster execution guidance.

Changes

Plan archive cleanup

Layer / File(s) Summary
Teardown deregistration support
AGENTS.md, utilities/resources.py
The guidance documents live-cluster prerequisites, parallel execution limits, and teardown deregistration. unregister_teardown_resource removes intentionally deleted resources from tracking.
Migration test setup
tests/tests_config/config.py, tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py
The configuration defines a cold migration with an expected post-hook failure. The test creates StorageMap, NetworkMap, and Plan resources.
Archive and PVC cleanup validation
tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py
The test verifies migration failure, archives and deletes the Plan, unregisters deleted resources, removes retained destination VMs, and polls for PVC and DataVolume cleanup.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Suggested labels: commented-qodo-code-review[bot]

Suggested reviewers: krcmarik, solenoci

Sequence Diagram(s)

sequenceDiagram
  participant TestPlanArchivePvcCleanup
  participant MigrationPlan
  participant PostHook
  participant TargetNamespace
  TestPlanArchivePvcCleanup->>MigrationPlan: execute migration
  MigrationPlan->>PostHook: run post-hook
  PostHook-->>MigrationPlan: return failure
  TestPlanArchivePvcCleanup->>MigrationPlan: archive and delete plan
  TestPlanArchivePvcCleanup->>TargetNamespace: remove retained destination VMs
  TestPlanArchivePvcCleanup->>TargetNamespace: poll PVC and DataVolume removal
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the added regression test for plan archive PVC cleanup.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/MTV-5663-plan-archive-pvc-cleanup

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.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add regression test for plan archive PVC cleanup (MTV-5663)

🧪 Tests ✨ Enhancement 📝 Documentation ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Add regression coverage ensuring plan archive+delete removes all target namespace PVCs/DVs after
 failure.
• Introduce teardown unregistration helper to support intentional mid-test resource deletion.
• Register new test parameters and document the mid-test teardown pattern.
Diagram

graph TD
  T["Test: Plan archive PVC cleanup"] --> M["mtv_migration helpers"] --> O(["OpenShift API"]) --> NS[("Target namespace: DVs/PVCs")]
  T --> A["migration_utils.archive_plan()"] --> O
  T --> U["resources.unregister_teardown_resource()"] --> FS["fixture_store teardown"] --> ST["pytest_utils.session_teardown()"] --> O

  subgraph Legend
    direction LR
    _t["Test/Module"] ~~~ _svc(["Cluster/API"]) ~~~ _data[("Namespaced data")]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Make session_teardown idempotent for missing Plan/Migration
  • ➕ Eliminates the need for tests to manage teardown bookkeeping explicitly
  • ➕ More robust global teardown behavior across all tests
  • ➖ Broader behavioral change to teardown path; risk of masking real cleanup regressions
  • ➖ Requires careful handling across multiple resource types and failure modes
2. Make archive_plan() tolerate NotFound and return status
  • ➕ Localizes resilience to the archive operation used in teardown and tests
  • ➕ Avoids hard failures when a Plan is intentionally deleted
  • ➖ Still leaves stale entries in fixture_store (teardown would keep trying to delete)
  • ➖ Can hide ordering problems unless paired with teardown list cleanup
3. Add explicit teardown API to fixture_store (register/unregister context manager)
  • ➕ Provides a consistent lifecycle API (register/unregister) instead of direct dict edits
  • ➕ Can enforce invariants and logging around teardown tracking
  • ➖ More refactor than needed for this regression test
  • ➖ Requires migrating existing call sites over time

Recommendation: Current approach (explicit unregister_teardown_resource) is pragmatic and minimally invasive: it keeps teardown behavior strict while letting tests intentionally delete resources without cascading teardown failures. Consider a follow-up hardening of session_teardown/archive_plan to gracefully handle NotFound as an additional safety net, but not required for this PR.

Files changed (5) +360 / -7 · 1 not counted

Enhancement (1) +21 / -0
resources.pyAdd unregister_teardown_resource() helper for fixture_store cleanup +21/-0

Add unregister_teardown_resource() helper for fixture_store cleanup

• Adds a utility to remove specific kind/name entries from fixture_store['teardown'] and fail fast with ValueError if the entry is missing, enabling safe mid-test deletion without breaking session teardown.

utilities/resources.py

Tests (2) +318 / -0
__init__.pyCreate plan_lifecycle test package not counted

Create plan_lifecycle test package

• Adds package initializer to ensure plan_lifecycle tests are discovered/importable as a module.

tests/plan_lifecycle/init.py

test_plan_archive_pvc_cleanup.pyAdd regression test for PVC/DV cleanup after archiving+deleting failed plan +318/-0

Add regression test for PVC/DV cleanup after archiving+deleting failed plan

• Introduces a 6-step incremental test that intentionally fails a migration via post-hook, archives and deletes the plan, unregisters teardown entries, then asserts no orphan DVs/PVCs remain in the target namespace after deleting any retained destination VMs.

tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py

Documentation (1) +13 / -7
AGENTS.mdDocument mid-test teardown unregistration; remove test execution prohibition section +13/-7

Document mid-test teardown unregistration; remove test execution prohibition section

• Removes the prior documentation block about prohibiting test execution and adds guidance/code snippet for unregistering intentionally-deleted resources from fixture_store teardown tracking.

AGENTS.md

Other (1) +8 / -0
config.pyRegister test_plan_archive_pvc_cleanup parameters +8/-0

Register test_plan_archive_pvc_cleanup parameters

• Adds a new tests_params entry defining a single VM plan, cold migration settings, and an expected-failing post-hook configuration for the new regression test.

tests/tests_config/config.py

@coderabbitai coderabbitai 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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@AGENTS.md`:
- Around line 708-714: Make the example block self-contained by adding imports
for get_migration_for_plan, archive_plan, Plan, and Migration alongside
unregister_teardown_resource, or explicitly state that these symbols must
already be available before the example is copied.

In `@tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py`:
- Around line 237-245: Extend the test after validate_hook_failure_and_check_vms
and before any archive or deletion calls to assert that the failed migration
created the expected normal PVC, prime-* PVC, and DataVolume resources. Use the
existing resource-listing or validation helpers and
self.plan_resource/prepared_plan identifiers, preserving the final cleanup
assertions while ensuring the regression baseline is verified before archiving.

In `@utilities/resources.py`:
- Around line 87-90: Validate that kind is registered in
fixture_store["teardown"] before indexing it in the resource teardown function,
and raise a clear ValueError when absent. Preserve the existing ValueError
behavior for a registered kind whose resource name is not found.
🪄 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 Plus

Run ID: 20a9f82c-8c2c-4a58-913f-969c807f4ca4

📥 Commits

Reviewing files that changed from the base of the PR and between 321ee60 and 15414bd.

📒 Files selected for processing (5)
  • AGENTS.md
  • tests/plan_lifecycle/__init__.py
  • tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py
  • tests/tests_config/config.py
  • utilities/resources.py

Comment thread AGENTS.md
Comment thread tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py
Comment thread utilities/resources.py Outdated
@qodo-code-review

qodo-code-review Bot commented Aug 3, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. VM cleanup not asserted 🐞 Bug ☼ Reliability ⭐ New
Description
test_verify_pvc_cleanup deletes retained destination VMs via vm_obj.clean_up(wait=True) but does not
verify the deletion succeeded. If VM deletion fails (or returns a failure indicator), the subsequent
orphan DV/PVC assertion can fail for VM-owned volumes, misattributing the failure to plan
archive+delete cleanup.
Code

tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[R316-318]

+            vm_obj = VirtualMachine(client=ocp_admin_client, name=vm_name, namespace=vm_namespace)
+            if vm_obj.exists:
+                vm_obj.clean_up(wait=True)
Relevance

●●● Strong

Team often strengthens tests with explicit assertions to avoid false failures/flakiness; no close
rejection precedent.

PR-#557
PR-#237

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The test asserts deletion success for the Plan but not for retained destination VMs, even though VM
deletion is a prerequisite for the orphan DV/PVC check to be meaningful.

tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[285-290]
tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[313-319]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`test_verify_pvc_cleanup()` attempts to delete any retained destination VMs before checking for orphan DVs/PVCs, but it ignores whether VM deletion actually succeeded. This can make the orphan-resource assertion noisy and misleading if VM cleanup fails.

### Issue Context
In the same test file, plan deletion is explicitly checked using `assert plan.clean_up(wait=True)`, implying `clean_up()` is expected to either return a success indicator (or raise). VM deletion should be handled similarly so failures are attributed correctly.

### Fix Focus Areas
- tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[313-319]

### Proposed change
Update the VM deletion loop to validate deletion success and surface a VM-specific error, e.g.:

```python
if vm_obj.exists:
   assert vm_obj.clean_up(wait=True), (
       f"Failed to delete destination VM '{vm_name}' in namespace '{vm_namespace}'"
   )
```

(If `clean_up()` raises on failure in your wrapper, this still improves diagnosability when it returns a falsy value.)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Unscoped orphan resource check ✓ Resolved 🐞 Bug ≡ Correctness
Description
test_verify_pvc_cleanup() polls get_orphan_resource_names(), which returns *all* PVC/DataVolume
names in vm_namespace, so the test can fail when a custom/shared vm_target_namespace contains
unrelated resources. This makes the regression test non-deterministic and can incorrectly report
plan cleanup failures.
Code

tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[R313-315]

+                func=get_orphan_resource_names,
+                client=ocp_admin_client,
+                namespace=vm_namespace,
Relevance

●●● Strong

Team prioritizes parallel-safety/avoiding false positives in shared namespaces (PR #282, #416);
similar false-positive fix accepted (PR #550).

PR-#282
PR-#416
PR-#550

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The prepared_plan fixture explicitly supports a configurable vm_target_namespace, which may be
shared/non-empty, and the test already uses session_uuid filtering earlier to avoid false
positives—yet the final orphan polling does not filter and will treat unrelated PVC/DVs as leaks.

conftest.py[1049-1060]
tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[236-248]
tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[309-316]
utilities/migration_utils.py[188-200]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`get_orphan_resource_names()` currently returns all PVC/DV names in the namespace, and `test_verify_pvc_cleanup()` treats any remaining names as "orphan" resources from this test. This creates false failures when `prepared_plan` is configured with a custom `vm_target_namespace` that is shared or pre-populated.

## Issue Context
The same test already acknowledges the shared-namespace possibility by filtering its pre-archive sanity check by `session_uuid`. The final cleanup assertion should use similar scoping (or a baseline-diff approach) so it only considers resources created by this test/migration.

## Fix Focus Areas
- tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[313-315]
- utilities/migration_utils.py[188-200]

### Suggested fix options
1) **Minimal**: pass `session_uuid` into the poll by wrapping the function:
  - `session_uuid = fixture_store["session_uuid"]`
  - `func=lambda **kw: [n for n in get_orphan_resource_names(**kw) if session_uuid in n]`
  (and similarly filter `orphan_names` in the timeout handler)

2) **Cleaner API**: extend `get_orphan_resource_names(client, namespace, name_contains: str | None = None)` and filter on that substring when provided; use `session_uuid` from the test.

3) **Most robust**: capture a baseline set of PVC/DV names before migration and assert only those baseline resources remain after cleanup.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Unsafe parallel run claim ✓ Resolved 🐞 Bug ☼ Reliability
Description
AGENTS.md now claims that unique per-session namespaces make parallel test runs safe, but namespace
isolation does not prevent collisions on shared source-provider VM identities (e.g., multiple tests
use the same source VM name). This can mislead contributors/automation into running tests
concurrently against the same provider and cause flaky failures or unintended source-VM
interference.
Code

AGENTS.md[607]

+- **Isolation:** Tests create unique namespaces per session (`session_uuid`) — multiple parallel runs are safe
Relevance

●●● Strong

Team previously accepted parallel-run collision fixes via cloning/unique VM identities; doc should
not overclaim safety.

PR-#557
PR-#416
PR-#159

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The updated AGENTS.md bullet explicitly claims parallel-run safety due to namespace isolation, while
the test configuration shows multiple tests share the same source VM name mtv-tests-rhel8, meaning
parallel runs can still collide at the provider/source-VM layer. A prior accepted bug also documents
this class of concurrency issue requiring clones/uniqueness.

AGENTS.md[601-608]
tests/tests_config/config.py[766-776]
tests/tests_config/config.py[691-704]
tests/tests_config/config.py[812-819]
PR-#557

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`AGENTS.md` states that parallel runs are safe due to per-session namespace isolation, but this ignores source-provider collisions (shared source VM names, provider-side state changes).

### Issue Context
Many tests reference the same source VM name (e.g. `mtv-tests-rhel8`) across different test configs; running them in parallel against the same provider can still interfere.

### Fix Focus Areas
- AGENTS.md[605-608]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (3)
4. Test ignores VM target namespace ✓ Resolved 🐞 Bug ≡ Correctness
Description
test_verify_pvc_cleanup hardcodes target_namespace for VM deletion and orphan DV/PVC polling,
but the test framework supports a distinct _vm_target_namespace (and Plan spec.targetNamespace
can differ). This can make the test check the wrong namespace and either miss leaked PVCs/DVs or
fail to delete retained destination VMs when a custom VM namespace is configured.
Code

tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[R294-298]

+        for vm in prepared_plan["virtual_machines"]:
+            vm_name = resolve_destination_vm_name(vm)
+            vm_obj = VirtualMachine(client=ocp_admin_client, name=vm_name, namespace=target_namespace)
+            if vm_obj.exists:
+                vm_obj.clean_up(wait=True)
Relevance

●●● Strong

Repo supports custom VM namespaces; reviews favor using prepared_plan["_vm_target_namespace"] for VM
operations (PRs #282, #420).

PR-#282
PR-#420

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The new test uses target_namespace directly, while the existing fixtures and plan creation
support/record a potentially different VM target namespace (_vm_target_namespace and Plan
spec.targetNamespace). This establishes a concrete mismatch that can cause the test to operate on
the wrong namespace.

tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[294-307]
conftest.py[1049-1061]
conftest.py[1538-1547]
utilities/mtv_migration.py[211-226]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py` deletes destination VMs and checks for orphan DVs/PVCs using `target_namespace`. If the plan config sets a custom `vm_target_namespace`, the framework stores it as `prepared_plan["_vm_target_namespace"]` and the Plan uses it as `spec.targetNamespace`, meaning the test will look in the wrong namespace.

### Issue Context
Other cleanup logic already resolves the VM namespace via `prepared_plan.get("_vm_target_namespace", target_namespace)`, and plan creation uses `vm_target_namespace or target_namespace` for `spec.targetNamespace`.

### Fix Focus Areas
- tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[273-318]
- conftest.py[1049-1061]
- conftest.py[1538-1552]
- utilities/mtv_migration.py[211-226]

### Suggested change
- In `test_verify_pvc_cleanup`, compute:
 - `vm_namespace = prepared_plan.get("_vm_target_namespace", target_namespace)`
- Use `vm_namespace` for:
 - `VirtualMachine(... namespace=vm_namespace)`
 - `_get_orphan_resource_names(... target_namespace=vm_namespace)` and the `TimeoutSampler` polling argument.
- (Optional) Rename `_get_orphan_resource_names` parameter to `namespace` to avoid conflating session `target_namespace` with plan VM target namespace.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Unscoped PVC/DV precheck ✓ Resolved 🐞 Bug ≡ Correctness
Description
test_migrate_vms asserts a PVC or DataVolume exists by listing *all* PVCs/DVs in the namespace,
without scoping to resources created by this migration. If the namespace already contains unrelated
PVCs/DVs (e.g., custom/shared vm_target_namespace), the assertion can pass even when the migration
never created resources, making the guard non-deterministic/vacuous.
Code

tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[R252-254]

+        vm_namespace = prepared_plan.get("_vm_target_namespace", target_namespace)
+        failed_pvcs = list(PersistentVolumeClaim.get(client=ocp_admin_client, namespace=vm_namespace))
+        failed_dvs = list(DataVolume.get(client=ocp_admin_client, namespace=vm_namespace))
Relevance

●● Moderate

No direct prior review on scoping PVC/DV existence checks; team generally accepts
determinism/stronger assertions in tests.

PR-#282
PR-#557
PR-#416

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The new code enumerates every PVC/DV in the namespace and uses that to prove the migration created
resources. Elsewhere in the codebase, DV/PVC cleanup checks are filtered by a migration-specific
identifier (partial_name), showing the established pattern for avoiding unrelated resources
affecting assertions.

tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[251-258]
utilities/migration_utils.py[80-110]
conftest.py[1049-1060]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The precondition check in `test_migrate_vms` counts any PVC/DV in the namespace, so unrelated resources can satisfy it.

### Issue Context
The repo already uses a pattern of filtering DV/PVC checks by a migration-specific substring (`partial_name`) to avoid unrelated leftovers.

### Fix Focus Areas
- tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[252-254]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. Unregister teardown can crash ✓ Resolved 🐞 Bug ☼ Reliability
Description
unregister_teardown_resource() directly indexes fixture_store["teardown"][kind] and raises when
the kind/name is missing, so mid-test deletion flows can fail and still leave session teardown
attempting to archive/delete already-removed resources. This can abort session_teardown() (which
calls archive_plan() without handling NotFound) and leave other resources uncleaned.
Code

utilities/resources.py[R87-90]

+    resources = fixture_store["teardown"][kind]
+    remaining = [resource for resource in resources if resource["name"] != name]
+    if len(remaining) == len(resources):
+        raise ValueError(f"Resource '{name}' of kind '{kind}' not found in fixture_store teardown")
Relevance

●● Moderate

No clear precedent on unregister idempotency; repo sometimes hardens NotFound handling (PR #589) but
also uses fail-fast ValueErrors.

PR-#589

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The helper is intended to prevent teardown from touching deleted resources, but its current strict
indexing/raising introduces new crash paths; at the same time, session teardown will patch/archive
all tracked Plans and does not guard against missing resources.

utilities/resources.py[73-91]
utilities/pytest_utils.py[102-116]
utilities/migration_utils.py[56-78]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`utilities.resources.unregister_teardown_resource()` is currently strict: it assumes `fixture_store["teardown"][kind]` exists and raises `ValueError` if the named entry is not present. The purpose of this helper is to prevent later teardown from operating on missing resources, so it should be safe/idempotent and not introduce new failure modes.

### Issue Context
`session_teardown()` iterates stored Plans/Migrations and calls `archive_plan()`/`cancel_migration()` prior to generic cleanup. `archive_plan()` performs a patch via `ResourceEditor.update()` and does not suppress NotFound; if a Plan was deleted mid-test and still tracked (or unregister fails), teardown can abort and leak resources.

### Fix Focus Areas
- utilities/resources.py[73-92]
- utilities/pytest_utils.py[102-124]
- utilities/migration_utils.py[56-78]

### Suggested change
- Make `unregister_teardown_resource()` tolerant of:
 - missing `fixture_store["teardown"]`
 - missing `kind` key
 - missing `name` entry
- Prefer returning without raising (log at INFO/WARN), or add a `strict: bool = False` parameter so tests can opt into strictness.
- Consider matching on both `name` and `namespace` (optional arg) to avoid accidental removal if names collide across namespaces.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

7. Orphan names lack kind ✓ Resolved 🐞 Bug ◔ Observability
Description
_get_orphan_resource_names() returns only a flat list of names, and the failure message prints
those names without indicating whether each is a PVC or DataVolume. This makes CI failures harder to
debug because you can’t immediately tell which resource type is leaking.
Code

tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[67]

+    return [pvc.name for pvc in remaining_pvcs] + [dv.name for dv in remaining_dvs]
Relevance

●●● Strong

Repo often accepts clearer failure/debug messages (missing params in PR #237; error reporting
overhaul in PR #391).

PR-#237
PR-#391

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The helper currently returns only names and the AssertionError prints that list directly, providing
no indication of which kind remains; other cleanup utilities in the repo preserve resource type when
reporting deletion issues.

tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[65-67]
tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[331-335]
utilities/migration_utils.py[93-103]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The orphan-resource assertion prints only resource names, losing whether the orphan is a PVC or a DataVolume.

## Issue Context
`_get_orphan_resource_names()` concatenates PVC and DV names into a single list and the assertion prints it verbatim.

## Fix Focus Areas
- tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[65-67]
- tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[331-335]

## Suggested fix
Return kind-qualified entries (e.g., `PVC/<name>` and `DataVolume/<name>`) or return structured tuples and format them in the final AssertionError for clearer diagnostics.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


8. get_orphan_resource_names() single-use helper ✓ Resolved 📘 Rule violation ✧ Quality
Description
get_orphan_resource_names() is introduced as a shared helper but currently has only one call site,
which is a premature abstraction that adds indirection without demonstrated reuse. This can increase
maintenance overhead and make the codebase harder to navigate.
Code

utilities/migration_utils.py[R188-189]

+def get_orphan_resource_names(client: DynamicClient, namespace: str, partial_name: str = "") -> list[str]:
+    """List remaining DV and PVC names in a namespace, optionally filtered.
Relevance

● Weak

Team frequently adds utilities with single call sites; no evidence they enforce “2 call sites”
helper rule.

PR-#553
PR-#562
PR-#285

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 70422 requires new helpers to have at least two concrete call sites unless they
represent a stable domain abstraction. The PR introduces get_orphan_resource_names() in
utilities/migration_utils.py, and repo-wide usage shows it is only called from
test_plan_archive_pvc_cleanup.py.

Rule 70422: Avoid premature abstractions for single-use or loosely similar code
utilities/migration_utils.py[188-204]
tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[313-326]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new helper (`get_orphan_resource_names`) was added but is only used once, which violates the guideline to avoid premature abstractions.

## Issue Context
The helper is currently only referenced from the new regression test, so keeping it in `utilities/migration_utils.py` adds indirection without clear reuse.

## Fix Focus Areas
- utilities/migration_utils.py[188-204]
- tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[313-326]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context used
⚠️ Tickets: not configured — ticket URL found in PR but could not be fetched — check ticket provider credentials
✅ Compliance rules (platform): 100 rules

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Previous review results

Review updated until commit b9fb3a1 ⚖️ Balanced

Results up to commit 15414bd ⚖️ Balanced


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Remediation recommended
1. Test ignores VM target namespace ✓ Resolved 🐞 Bug ≡ Correctness
Description
test_verify_pvc_cleanup hardcodes target_namespace for VM deletion and orphan DV/PVC polling,
but the test framework supports a distinct _vm_target_namespace (and Plan spec.targetNamespace
can differ). This can make the test check the wrong namespace and either miss leaked PVCs/DVs or
fail to delete retained destination VMs when a custom VM namespace is configured.
Code

tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[R294-298]

+        for vm in prepared_plan["virtual_machines"]:
+            vm_name = resolve_destination_vm_name(vm)
+            vm_obj = VirtualMachine(client=ocp_admin_client, name=vm_name, namespace=target_namespace)
+            if vm_obj.exists:
+                vm_obj.clean_up(wait=True)
Relevance

●●● Strong

Repo supports custom VM namespaces; reviews favor using prepared_plan["_vm_target_namespace"] for VM
operations (PRs #282, #420).

PR-#282
PR-#420

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The new test uses target_namespace directly, while the existing fixtures and plan creation
support/record a potentially different VM target namespace (_vm_target_namespace and Plan
spec.targetNamespace). This establishes a concrete mismatch that can cause the test to operate on
the wrong namespace.

tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[294-307]
conftest.py[1049-1061]
conftest.py[1538-1547]
utilities/mtv_migration.py[211-226]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py` deletes destination VMs and checks for orphan DVs/PVCs using `target_namespace`. If the plan config sets a custom `vm_target_namespace`, the framework stores it as `prepared_plan["_vm_target_namespace"]` and the Plan uses it as `spec.targetNamespace`, meaning the test will look in the wrong namespace.

### Issue Context
Other cleanup logic already resolves the VM namespace via `prepared_plan.get("_vm_target_namespace", target_namespace)`, and plan creation uses `vm_target_namespace or target_namespace` for `spec.targetNamespace`.

### Fix Focus Areas
- tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[273-318]
- conftest.py[1049-1061]
- conftest.py[1538-1552]
- utilities/mtv_migration.py[211-226]

### Suggested change
- In `test_verify_pvc_cleanup`, compute:
 - `vm_namespace = prepared_plan.get("_vm_target_namespace", target_namespace)`
- Use `vm_namespace` for:
 - `VirtualMachine(... namespace=vm_namespace)`
 - `_get_orphan_resource_names(... target_namespace=vm_namespace)` and the `TimeoutSampler` polling argument.
- (Optional) Rename `_get_orphan_resource_names` parameter to `namespace` to avoid conflating session `target_namespace` with plan VM target namespace.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Unregister teardown can crash ✓ Resolved 🐞 Bug ☼ Reliability
Description
unregister_teardown_resource() directly indexes fixture_store["teardown"][kind] and raises when
the kind/name is missing, so mid-test deletion flows can fail and still leave session teardown
attempting to archive/delete already-removed resources. This can abort session_teardown() (which
calls archive_plan() without handling NotFound) and leave other resources uncleaned.
Code

utilities/resources.py[R87-90]

+    resources = fixture_store["teardown"][kind]
+    remaining = [resource for resource in resources if resource["name"] != name]
+    if len(remaining) == len(resources):
+        raise ValueError(f"Resource '{name}' of kind '{kind}' not found in fixture_store teardown")
Relevance

●● Moderate

No clear precedent on unregister idempotency; repo sometimes hardens NotFound handling (PR #589) but
also uses fail-fast ValueErrors.

PR-#589

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The helper is intended to prevent teardown from touching deleted resources, but its current strict
indexing/raising introduces new crash paths; at the same time, session teardown will patch/archive
all tracked Plans and does not guard against missing resources.

utilities/resources.py[73-91]
utilities/pytest_utils.py[102-116]
utilities/migration_utils.py[56-78]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`utilities.resources.unregister_teardown_resource()` is currently strict: it assumes `fixture_store["teardown"][kind]` exists and raises `ValueError` if the named entry is not present. The purpose of this helper is to prevent later teardown from operating on missing resources, so it should be safe/idempotent and not introduce new failure modes.

### Issue Context
`session_teardown()` iterates stored Plans/Migrations and calls `archive_plan()`/`cancel_migration()` prior to generic cleanup. `archive_plan()` performs a patch via `ResourceEditor.update()` and does not suppress NotFound; if a Plan was deleted mid-test and still tracked (or unregister fails), teardown can abort and leak resources.

### Fix Focus Areas
- utilities/resources.py[73-92]
- utilities/pytest_utils.py[102-124]
- utilities/migration_utils.py[56-78]

### Suggested change
- Make `unregister_teardown_resource()` tolerant of:
 - missing `fixture_store["teardown"]`
 - missing `kind` key
 - missing `name` entry
- Prefer returning without raising (log at INFO/WARN), or add a `strict: bool = False` parameter so tests can opt into strictness.
- Consider matching on both `name` and `namespace` (optional arg) to avoid accidental removal if names collide across namespaces.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Results up to commit c7cba81 ⚖️ Balanced


No changes from previous review

Results up to commit 62fa630 ⚖️ Balanced


No changes from previous review

Results up to commit fb778b6 ⚖️ Balanced


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Remediation recommended
1. Unsafe parallel run claim ✓ Resolved 🐞 Bug ☼ Reliability
Description
AGENTS.md now claims that unique per-session namespaces make parallel test runs safe, but namespace
isolation does not prevent collisions on shared source-provider VM identities (e.g., multiple tests
use the same source VM name). This can mislead contributors/automation into running tests
concurrently against the same provider and cause flaky failures or unintended source-VM
interference.
Code

AGENTS.md[607]

+- **Isolation:** Tests create unique namespaces per session (`session_uuid`) — multiple parallel runs are safe
Relevance

●●● Strong

Team previously accepted parallel-run collision fixes via cloning/unique VM identities; doc should
not overclaim safety.

PR-#557
PR-#416
PR-#159

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The updated AGENTS.md bullet explicitly claims parallel-run safety due to namespace isolation, while
the test configuration shows multiple tests share the same source VM name mtv-tests-rhel8, meaning
parallel runs can still collide at the provider/source-VM layer. A prior accepted bug also documents
this class of concurrency issue requiring clones/uniqueness.

AGENTS.md[601-608]
tests/tests_config/config.py[766-776]
tests/tests_config/config.py[691-704]
tests/tests_config/config.py[812-819]
PR-#557

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`AGENTS.md` states that parallel runs are safe due to per-session namespace isolation, but this ignores source-provider collisions (shared source VM names, provider-side state changes).

### Issue Context
Many tests reference the same source VM name (e.g. `mtv-tests-rhel8`) across different test configs; running them in parallel against the same provider can still interfere.

### Fix Focus Areas
- AGENTS.md[605-608]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Unscoped PVC/DV precheck ✓ Resolved 🐞 Bug ≡ Correctness
Description
test_migrate_vms asserts a PVC or DataVolume exists by listing *all* PVCs/DVs in the namespace,
without scoping to resources created by this migration. If the namespace already contains unrelated
PVCs/DVs (e.g., custom/shared vm_target_namespace), the assertion can pass even when the migration
never created resources, making the guard non-deterministic/vacuous.
Code

tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[R252-254]

+        vm_namespace = prepared_plan.get("_vm_target_namespace", target_namespace)
+        failed_pvcs = list(PersistentVolumeClaim.get(client=ocp_admin_client, namespace=vm_namespace))
+        failed_dvs = list(DataVolume.get(client=ocp_admin_client, namespace=vm_namespace))
Relevance

●● Moderate

No direct prior review on scoping PVC/DV existence checks; team generally accepts
determinism/stronger assertions in tests.

PR-#282
PR-#557
PR-#416

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The new code enumerates every PVC/DV in the namespace and uses that to prove the migration created
resources. Elsewhere in the codebase, DV/PVC cleanup checks are filtered by a migration-specific
identifier (partial_name), showing the established pattern for avoiding unrelated resources
affecting assertions.

tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[251-258]
utilities/migration_utils.py[80-110]
conftest.py[1049-1060]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The precondition check in `test_migrate_vms` counts any PVC/DV in the namespace, so unrelated resources can satisfy it.

### Issue Context
The repo already uses a pattern of filtering DV/PVC checks by a migration-specific substring (`partial_name`) to avoid unrelated leftovers.

### Fix Focus Areas
- tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[252-254]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Results up to commit 101443b ⚖️ Balanced


No changes from previous review

Results up to commit d3d3cdf ⚖️ Balanced


No changes from previous review

Results up to commit 59a56b7 ⚖️ Balanced


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Remediation recommended
1. Unscoped orphan resource check ✓ Resolved 🐞 Bug ≡ Correctness
Description
test_verify_pvc_cleanup() polls get_orphan_resource_names(), which returns *all* PVC/DataVolume
names in vm_namespace, so the test can fail when a custom/shared vm_target_namespace contains
unrelated resources. This makes the regression test non-deterministic and can incorrectly report
plan cleanup failures.
Code

tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[R313-315]

+                func=get_orphan_resource_names,
+                client=ocp_admin_client,
+                namespace=vm_namespace,
Relevance

●●● Strong

Team prioritizes parallel-safety/avoiding false positives in shared namespaces (PR #282, #416);
similar false-positive fix accepted (PR #550).

PR-#282
PR-#416
PR-#550

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The prepared_plan fixture explicitly supports a configurable vm_target_namespace, which may be
shared/non-empty, and the test already uses session_uuid filtering earlier to avoid false
positives—yet the final orphan polling does not filter and will treat unrelated PVC/DVs as leaks.

conftest.py[1049-1060]
tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[236-248]
tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[309-316]
utilities/migration_utils.py[188-200]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`get_orphan_resource_names()` currently returns all PVC/DV names in the namespace, and `test_verify_pvc_cleanup()` treats any remaining names as "orphan" resources from this test. This creates false failures when `prepared_plan` is configured with a custom `vm_target_namespace` that is shared or pre-populated.

## Issue Context
The same test already acknowledges the shared-namespace possibility by filtering its pre-archive sanity check by `session_uuid`. The final cleanup assertion should use similar scoping (or a baseline-diff approach) so it only considers resources created by this test/migration.

## Fix Focus Areas
- tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[313-315]
- utilities/migration_utils.py[188-200]

### Suggested fix options
1) **Minimal**: pass `session_uuid` into the poll by wrapping the function:
  - `session_uuid = fixture_store["session_uuid"]`
  - `func=lambda **kw: [n for n in get_orphan_resource_names(**kw) if session_uuid in n]`
  (and similarly filter `orphan_names` in the timeout handler)

2) **Cleaner API**: extend `get_orphan_resource_names(client, namespace, name_contains: str | None = None)` and filter on that substring when provided; use `session_uuid` from the test.

3) **Most robust**: capture a baseline set of PVC/DV names before migration and assert only those baseline resources remain after cleanup.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Results up to commit ca392ef ⚖️ Balanced


No changes from previous review

Results up to commit df6bbe9 ⚖️ Balanced


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Informational
1. get_orphan_resource_names() single-use helper ✓ Resolved 📘 Rule violation ✧ Quality
Description
get_orphan_resource_names() is introduced as a shared helper but currently has only one call site,
which is a premature abstraction that adds indirection without demonstrated reuse. This can increase
maintenance overhead and make the codebase harder to navigate.
Code

utilities/migration_utils.py[R188-189]

+def get_orphan_resource_names(client: DynamicClient, namespace: str, partial_name: str = "") -> list[str]:
+    """List remaining DV and PVC names in a namespace, optionally filtered.
Relevance

● Weak

Team frequently adds utilities with single call sites; no evidence they enforce “2 call sites”
helper rule.

PR-#553
PR-#562
PR-#285

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 70422 requires new helpers to have at least two concrete call sites unless they
represent a stable domain abstraction. The PR introduces get_orphan_resource_names() in
utilities/migration_utils.py, and repo-wide usage shows it is only called from
test_plan_archive_pvc_cleanup.py.

Rule 70422: Avoid premature abstractions for single-use or loosely similar code
utilities/migration_utils.py[188-204]
tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[313-326]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new helper (`get_orphan_resource_names`) was added but is only used once, which violates the guideline to avoid premature abstractions.

## Issue Context
The helper is currently only referenced from the new regression test, so keeping it in `utilities/migration_utils.py` adds indirection without clear reuse.

## Fix Focus Areas
- utilities/migration_utils.py[188-204]
- tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[313-326]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Results up to commit 79fa65c ⚖️ Balanced


No changes from previous review

Results up to commit ebb0699 ⚖️ Balanced


No changes from previous review

Results up to commit 59fe7af ⚖️ Balanced


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Informational
1. Orphan names lack kind ✓ Resolved 🐞 Bug ◔ Observability
Description
_get_orphan_resource_names() returns only a flat list of names, and the failure message prints
those names without indicating whether each is a PVC or DataVolume. This makes CI failures harder to
debug because you can’t immediately tell which resource type is leaking.
Code

tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[67]

+    return [pvc.name for pvc in remaining_pvcs] + [dv.name for dv in remaining_dvs]
Relevance

●●● Strong

Repo often accepts clearer failure/debug messages (missing params in PR #237; error reporting
overhaul in PR #391).

PR-#237
PR-#391

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The helper currently returns only names and the AssertionError prints that list directly, providing
no indication of which kind remains; other cleanup utilities in the repo preserve resource type when
reporting deletion issues.

tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[65-67]
tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[331-335]
utilities/migration_utils.py[93-103]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The orphan-resource assertion prints only resource names, losing whether the orphan is a PVC or a DataVolume.

## Issue Context
`_get_orphan_resource_names()` concatenates PVC and DV names into a single list and the assertion prints it verbatim.

## Fix Focus Areas
- tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[65-67]
- tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[331-335]

## Suggested fix
Return kind-qualified entries (e.g., `PVC/<name>` and `DataVolume/<name>`) or return structured tuples and format them in the final AssertionError for clearer diagnostics.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Results up to commit c309a5a ⚖️ Balanced


No changes from previous review

Qodo Logo

Comment thread utilities/resources.py Outdated
Comment thread tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py
@myakove

myakove commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator Author

/qodo

The following review comments were reviewed and a decision was made:

tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py:294 (qodo bug) — Test ignores VM target namespace

Addressed: Fixed: test_verify_pvc_cleanup now uses prepared_plan.get("_vm_target_namespace", target_namespace) for VM deletion and orphan DV/PVC checks, consistent with the cleanup_migrated_vms fixture pattern.

utilities/resources.py:87 (qodo bug) — Unregister teardown can crash

Addressed: Fixed: unregister_teardown_resource() is now safe/idempotent — uses .get() with warning instead of raising KeyError/ValueError. No new crash paths introduced during teardown.


Assisted-by: PI (claude-opus-4-6-1m)

@qodo-code-review

Copy link
Copy Markdown

The following review comments were reviewed and a decision was made:

tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py:294 (qodo bug) — Test ignores VM target namespace

Addressed: Fixed: test_verify_pvc_cleanup now uses prepared_plan.get("_vm_target_namespace", target_namespace) for VM deletion and orphan DV/PVC checks, consistent with the cleanup_migrated_vms fixture pattern.

utilities/resources.py:87 (qodo bug) — Unregister teardown can crash

Addressed: Fixed: unregister_teardown_resource() is now safe/idempotent — uses .get() with warning instead of raising KeyError/ValueError. No new crash paths introduced during teardown.


Assisted-by: PI (claude-opus-4-6-1m)

Both findings appear addressed:

  • finding 1: VM deletion and orphan-resource checks consistently use _vm_target_namespace, falling back to target_namespace.
  • finding 2: unregister_teardown_resource() is idempotent and handles missing teardown entries by warning instead of raising.

No further action is needed for these review comments.

@qodo-code-review

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit c7cba81

@coderabbitai coderabbitai 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py (2)

302-304: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

MEDIUM — Name the orphan-cleanup timing values.

The literals 120 and 5 control timeout and polling behavior. Define module-level constants with units so future changes do not obscure the cleanup contract.

Proposed refactor
+ORPHAN_RESOURCE_WAIT_TIMEOUT_SECONDS = 120
+ORPHAN_RESOURCE_POLL_INTERVAL_SECONDS = 5
+
...
-                wait_timeout=120,
-                sleep=5,
+                wait_timeout=ORPHAN_RESOURCE_WAIT_TIMEOUT_SECONDS,
+                sleep=ORPHAN_RESOURCE_POLL_INTERVAL_SECONDS,

As per coding guidelines, replace unexplained numeric literals with named constants and explanatory comments.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py` around lines 302 -
304, Define module-level named constants with explicit time units for the
orphan-cleanup timeout and polling interval, then replace the 120 and 5
arguments in the TimeoutSampler call within the orphan-cleanup flow with those
constants. Add concise comments documenting their timing purpose and preserve
the existing values and behavior.

Source: Coding guidelines


208-208: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

HIGH — Preserve the optional warm_migration default.

The shared prepared_plan fixture treats warm_migration as optional and defaults it to False. Direct indexing at Line 208 raises KeyError when a cold-migration configuration omits the key, unless the fixture writes the normalized value back. Use .get("warm_migration", False) or verify that output contract.

Proposed fix
-            warm_migration=prepared_plan["warm_migration"],
+            warm_migration=prepared_plan.get("warm_migration", False),
#!/bin/bash
set -euo pipefail
rg -n -C 6 'warm_migration|plan\["warm_migration"\]' \
  conftest.py \
  tests/tests_config/config.py \
  tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py

As per coding guidelines and retrieved learnings, warm_migration is optional and must default to False when absent.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py` at line 208, Update
the plan setup at the warm_migration access to use the shared fixture’s optional
semantics, defaulting to False when prepared_plan omits the key. Use
prepared_plan.get("warm_migration", False) or ensure the fixture normalizes and
writes the default back before this access, while preserving the existing
behavior when the key is present.
♻️ Duplicate comments (1)
tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py (1)

237-245: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

HIGH — Establish the failed-migration resource baseline.

The test does not prove that the failed migration created a regular PVC, a prime-* PVC, and a DataVolume before archive_plan() runs. If migration fails too early, the later empty-namespace assertion can pass without exercising the MTV-5564/MTV-5663 regression.

Add these assertions after hook validation and before archive or deletion:

Proposed baseline assertions
         validate_hook_failure_and_check_vms(self.plan_resource, prepared_plan)
+
+        failed_pvc_names = [
+            pvc.name
+            for pvc in PersistentVolumeClaim.get(
+                client=ocp_admin_client,
+                namespace=target_namespace,
+            )
+        ]
+        failed_dv_names = [
+            data_volume.name
+            for data_volume in DataVolume.get(
+                client=ocp_admin_client,
+                namespace=target_namespace,
+            )
+        ]
+        assert failed_dv_names, "Post-hook failure did not create a DataVolume"
+        assert any(not name.startswith("prime-") for name in failed_pvc_names)
+        assert any(name.startswith("prime-") for name in failed_pvc_names)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py` around lines 237 -
245, After validate_hook_failure_and_check_vms(self.plan_resource,
prepared_plan), establish the failed-migration baseline by asserting that the
target namespace contains the expected regular PVC, a prime-* PVC, and a
DataVolume before invoking archive_plan() or any cleanup/deletion. Use the
existing resource helpers and identifiers from the test rather than relying only
on the later empty-namespace assertion.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py`:
- Around line 302-304: Define module-level named constants with explicit time
units for the orphan-cleanup timeout and polling interval, then replace the 120
and 5 arguments in the TimeoutSampler call within the orphan-cleanup flow with
those constants. Add concise comments documenting their timing purpose and
preserve the existing values and behavior.
- Line 208: Update the plan setup at the warm_migration access to use the shared
fixture’s optional semantics, defaulting to False when prepared_plan omits the
key. Use prepared_plan.get("warm_migration", False) or ensure the fixture
normalizes and writes the default back before this access, while preserving the
existing behavior when the key is present.

---

Duplicate comments:
In `@tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py`:
- Around line 237-245: After
validate_hook_failure_and_check_vms(self.plan_resource, prepared_plan),
establish the failed-migration baseline by asserting that the target namespace
contains the expected regular PVC, a prime-* PVC, and a DataVolume before
invoking archive_plan() or any cleanup/deletion. Use the existing resource
helpers and identifiers from the test rather than relying only on the later
empty-namespace assertion.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 5d37b117-224b-4586-8937-d3e0978ff63a

📥 Commits

Reviewing files that changed from the base of the PR and between 15414bd and c7cba81.

📒 Files selected for processing (2)
  • tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py
  • utilities/resources.py

@myakove

myakove commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai[bot]

The following review comments were reviewed and a decision was made:

tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py:302 (outside diff) — MEDIUM — Name the orphan-cleanup timing values.

Addressed: Fixed: added _ORPHAN_RESOURCE_WAIT_TIMEOUT and _ORPHAN_RESOURCE_POLL_INTERVAL module-level constants.

tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py:208 (outside diff) — HIGH — Preserve the optional warm_migration default.

Addressed: Fixed: changed to prepared_plan.get("warm_migration", False) — warm_migration is an optional flag per AGENTS.md.

tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py:237 (duplicate) — HIGH — Establish the failed-migration resource baseline.

Addressed: Duplicate of finding #2 — addressed with the same baseline assertion fix.


Assisted-by: PI (claude-opus-4-6-1m)

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@myakove Confirmed. The changes address the reported findings:

  • MEDIUM: Named constants replace the orphan-resource timing literals.
  • HIGH: warm_migration retains its optional default with prepared_plan.get("warm_migration", False).
  • HIGH: The failed-migration resource baseline assertion is now present.

If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

You are interacting with an AI system.

@qodo-code-review

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 62fa630

@myakove

myakove commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@myakove

myakove commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@myakove

myakove commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@myakove

myakove commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator Author

/retest all

myakove and others added 14 commits August 6, 2026 15:00
Regression test for MTV-5564: verifies that archiving and deleting a
failed migration plan properly cleans up all PVCs (including prime-*
PVCs) in the target namespace.

Test flow:
1. Create StorageMap, NetworkMap, and Plan with failing post-hook
2. Execute migration (fails at PostHook, PVCs are created)
3. Archive and delete the failed plan
4. Delete retained VMs, verify no orphan DVs/PVCs remain

Also adds:
- unregister_teardown_resource() utility for mid-test resource deletion
- Documents the utility in AGENTS.md Resource Creation section

Jira: MTV-5663
Co-authored-by: Cursor <cursoragent@cursor.com>
- Use prepared_plan._vm_target_namespace in test_verify_pvc_cleanup
  for consistency with cleanup_migrated_vms fixture
- Make unregister_teardown_resource safe/idempotent — warn instead
  of raising when kind/name not found

Signed-off-by: Meni Yakove <myakove@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
- Add resource baseline assertion in test_migrate_vms to prove PVCs/DVs
  exist before archive+delete (prevents vacuous pass)
- Name timeout magic numbers as module constants
- Use .get("warm_migration", False) for optional flag
- Make AGENTS.md example self-contained with import note

Signed-off-by: Meni Yakove <myakove@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…straints

- Use _vm_target_namespace in test_migrate_vms baseline PVC/DV check
  for consistency with the cleanup path in test_verify_pvc_cleanup
- Add Test Execution Requirements section to AGENTS.md as guardrails
  after removing the test execution prohibition

Co-authored-by: Cursor <cursoragent@cursor.com>
…docs

- Clarify AGENTS.md parallel run isolation caveat (source-provider VM
  collisions not prevented by namespace isolation alone)
- Document why unscoped PVC/DV listing is safe in baseline assertion
  (unique per-session namespace) and improve error message

Signed-off-by: Meni Yakove <myakove@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Filter baseline PVC/DV assertion in test_migrate_vms by
fixture_store["session_uuid"] to avoid false positives when
vm_target_namespace is shared across test runs.

Co-authored-by: Cursor <cursoragent@cursor.com>
- Move _get_orphan_resource_names to utilities/migration_utils.py as
  public get_orphan_resource_names() per AGENTS.md placement rules
- Align parallel execution section with source-provider caveat

Signed-off-by: Meni Yakove <myakove@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Filter get_orphan_resource_names() results by session_uuid in
test_verify_pvc_cleanup to avoid false failures when
vm_target_namespace contains unrelated resources.

Signed-off-by: Meni Yakove <myakove@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: Meni Yakove <myakove@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Move session_uuid scoping into the utility function via a
partial_name parameter, making the filtering visible at the
call site. Resolves Qodo sticky finding about unscoped orphan check.

Co-authored-by: Cursor <cursoragent@cursor.com>
- Return success if final orphan query is empty on TimeoutExpiredError
  (cleanup can complete between last poll and final check)
- Update class docstring step 6 to reflect session-scoped filtering

Co-authored-by: Cursor <cursoragent@cursor.com>
Move _get_orphan_resource_names back to test file as a private helper.
The function has a single call site — per AGENTS.md "Don't create
abstractions for single-use code", keeping it inline is correct.

Signed-off-by: Meni Yakove <myakove@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Forklift creates PVCs using source disk UUIDs (e.g. 42544ee2-...),
not session_uuid. The target namespace itself is unique per session
(named after session_uuid), so all PVCs in it belong to this test
run. Remove the partial_name/session_uuid filter that caused false
baseline assertion failures.

Signed-off-by: Meni Yakove <myakove@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Add PVC/ and DV/ prefix to _get_orphan_resource_names output so
assertion failures clearly show which resource type is leaking.

Co-authored-by: Cursor <cursoragent@cursor.com>
@myakove
myakove force-pushed the feat/MTV-5663-plan-archive-pvc-cleanup branch from c309a5a to b9fb3a1 Compare August 6, 2026 12:01
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py`:
- Around line 259-264: Replace the combined migration_pvcs or migration_dvs
assertion before test_archive_and_delete_plan with separate baseline assertions
confirming a regular PVC, a prime-* PVC, and a DataVolume exist. Filter or
identify each resource type explicitly, and retain clear failure messages so
missing prime PVC creation cannot make the cleanup assertion vacuous.
🪄 Autofix

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 Plus

Run ID: 2b71b42f-8f4c-4f7a-a2b9-50f435842ace

📥 Commits

Reviewing files that changed from the base of the PR and between f2fea01 and b9fb3a1.

📒 Files selected for processing (5)
  • AGENTS.md
  • tests/plan_lifecycle/__init__.py
  • tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py
  • tests/tests_config/config.py
  • utilities/resources.py

Comment on lines +259 to +264
migration_pvcs = list(PersistentVolumeClaim.get(client=ocp_admin_client, namespace=vm_namespace))
migration_dvs = list(DataVolume.get(client=ocp_admin_client, namespace=vm_namespace))
assert migration_pvcs or migration_dvs, (
f"No PVCs or DataVolumes found in namespace '{vm_namespace}' after "
"post-hook failure — the archive+delete cleanup assertion would be vacuous"
)

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.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

HIGH — Assert each failed-migration resource type before archive.

Line 261 accepts one PVC or one DataVolume. It does not prove that the failed migration created a regular PVC, a prime-* PVC, and a DataVolume. If prime-* PVC creation regresses, the final empty-state check still passes because no prime-* PVC exists to clean up.

Assert all three baseline conditions before test_archive_and_delete_plan.

Proposed fix
         migration_pvcs = list(PersistentVolumeClaim.get(client=ocp_admin_client, namespace=vm_namespace))
         migration_dvs = list(DataVolume.get(client=ocp_admin_client, namespace=vm_namespace))
-        assert migration_pvcs or migration_dvs, (
-            f"No PVCs or DataVolumes found in namespace '{vm_namespace}' after "
-            "post-hook failure — the archive+delete cleanup assertion would be vacuous"
-        )
+        pvc_names = [pvc.name for pvc in migration_pvcs]
+        assert migration_dvs, f"No DataVolumes found in namespace '{vm_namespace}' after post-hook failure"
+        assert any(not name.startswith("prime-") for name in pvc_names), (
+            f"No regular PVC found in namespace '{vm_namespace}' after post-hook failure"
+        )
+        assert any(name.startswith("prime-") for name in pvc_names), (
+            f"No prime PVC found in namespace '{vm_namespace}' after post-hook failure"
+        )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py` around lines 259 -
264, Replace the combined migration_pvcs or migration_dvs assertion before
test_archive_and_delete_plan with separate baseline assertions confirming a
regular PVC, a prime-* PVC, and a DataVolume exist. Filter or identify each
resource type explicitly, and retain clear failure messages so missing prime PVC
creation cannot make the cleanup assertion vacuous.

Comment on lines +316 to +318
vm_obj = VirtualMachine(client=ocp_admin_client, name=vm_name, namespace=vm_namespace)
if vm_obj.exists:
vm_obj.clean_up(wait=True)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

1. Vm cleanup not asserted 🐞 Bug ☼ Reliability

test_verify_pvc_cleanup deletes retained destination VMs via vm_obj.clean_up(wait=True) but does not
verify the deletion succeeded. If VM deletion fails (or returns a failure indicator), the subsequent
orphan DV/PVC assertion can fail for VM-owned volumes, misattributing the failure to plan
archive+delete cleanup.
Agent Prompt
### Issue description
`test_verify_pvc_cleanup()` attempts to delete any retained destination VMs before checking for orphan DVs/PVCs, but it ignores whether VM deletion actually succeeded. This can make the orphan-resource assertion noisy and misleading if VM cleanup fails.

### Issue Context
In the same test file, plan deletion is explicitly checked using `assert plan.clean_up(wait=True)`, implying `clean_up()` is expected to either return a success indicator (or raise). VM deletion should be handled similarly so failures are attributed correctly.

### Fix Focus Areas
- tests/plan_lifecycle/test_plan_archive_pvc_cleanup.py[313-319]

### Proposed change
Update the VM deletion loop to validate deletion success and surface a VM-specific error, e.g.:

```python
if vm_obj.exists:
    assert vm_obj.clean_up(wait=True), (
        f"Failed to delete destination VM '{vm_name}' in namespace '{vm_namespace}'"
    )
```

(If `clean_up()` raises on failure in your wrapper, this still improves diagnosability when it returns a falsy value.)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@qodo-code-review

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit b9fb3a1

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