Skip to content

e2e: assert PVC state after Disable DR - #2675

Open
raaizik wants to merge 1 commit into
RamenDR:mainfrom
raaizik:e2e-assert-pvc-after-disable
Open

e2e: assert PVC state after Disable DR#2675
raaizik wants to merge 1 commit into
RamenDR:mainfrom
raaizik:e2e-assert-pvc-after-disable

Conversation

@raaizik

@raaizik raaizik commented Jul 27, 2026

Copy link
Copy Markdown
Member

Summary

Catch regressions where PVCs end up Terminating or still owned by VolSync/VRG while the workload still looks healthy.
Fixes #2649

Verification

Manual Deploy → Enable → Disable on VolSync CephFS disapp-deploy-cephfs.

Post Enable (dr1)

DRPC Deployed, VRG Primary. PVC while protected:

{
  "phase": "Bound",
  "deletionTimestamp": null,
  "ownerReferences": [
    {
      "kind": "ReplicationSource",
      "name": "busybox-pvc"
    }
  ]
}

Post Disable

TestDR/disapp-deploy-cephfs/Disable PASS. DRPC/VRG removed. PVC after disable:

{
  "phase": "Bound",
  "deletionTimestamp": null,
  "ownerReferences": []
}

Expected: PVC remains Bound, not Terminating, and VolSync/VRG owners are cleared (do-not-delete-pvc path).

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 132a4a5d-c351-4f4a-8792-bccac40def02

📥 Commits

Reviewing files that changed from the base of the PR and between 63e3d95 and 8a0a689.

📒 Files selected for processing (4)
  • e2e/deployers/retry.go
  • e2e/util/errors.go
  • e2e/workloads/deploy.go
  • e2e/workloads/vm.go
📜 Recent review details
⏰ Context from checks skipped due to timeout. (13)
  • GitHub Check: test
  • GitHub Check: Linters
  • GitHub Check: Build image
  • GitHub Check: Unit tests
  • GitHub Check: Golangci Lint (e2e)
  • GitHub Check: Golangci Lint (.)
  • GitHub Check: Go compatibility
  • GitHub Check: drenv (ubuntu-24.04, 3.10)
  • GitHub Check: drenv (ubuntu-24.04, 3.12)
  • GitHub Check: drenv (ubuntu-24.04, 3.13)
  • GitHub Check: drenv (ubuntu-24.04, 3.14-dev)
  • GitHub Check: drenv (ubuntu-24.04, 3.11)
  • GitHub Check: drenv (macos-latest, 3.13)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: pruthvitd
Repo: RamenDR/ramen PR: 2657
File: internal/controller/volumereplicationgroup_controller.go:2959-2973
Timestamp: 2026-07-21T04:41:07.092Z
Learning: For VM static IP support in `internal/controller/volumereplicationgroup_controller.go`, pull request `#2657` is intentionally limited to validating `network.kubevirt.io/addresses` JSON annotations and surfacing malformed configuration before DR workflows. Persisting VM static IP discovery details in VRG status and reporting associated metrics are deferred to follow-up pull request `#2664`, where the required VRG API changes are introduced.
🔇 Additional comments (4)
e2e/util/errors.go (1)

1-9: LGTM!

e2e/workloads/deploy.go (1)

18-18: LGTM!

Also applies to: 162-162, 250-286

e2e/workloads/vm.go (1)

127-127: LGTM!

e2e/deployers/retry.go (1)

7-7: LGTM!

Also applies to: 68-71


📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes
    • Added health validation for workload persistent volumes, including presence, deletion status, and binding state.
    • Workloads with missing, lost, or deleting volumes now fail immediately with clear unrecoverable errors.
    • Pending or otherwise unready volumes continue to be retried until they become healthy.
    • Improved deployment and virtual machine health checks to account for volume readiness.

Walkthrough

Changes

The PR adds PVC validation to deployment and VM health checks. It classifies missing, lost, or deleting PVCs as unrecoverable and stops retries for those errors.

PVC health validation

Layer / File(s) Summary
PVC health checks and workload integration
e2e/util/errors.go, e2e/workloads/deploy.go, e2e/workloads/vm.go
Defines ErrUnrecoverable. Deployment and VM health checks validate that PVCs exist, are not deleting, and are Bound.
Unrecoverable workload error handling
e2e/deployers/retry.go
WaitWorkloadHealth immediately returns errors marked with util.ErrUnrecoverable and continues retrying other errors.

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

Sequence Diagram(s)

sequenceDiagram
  participant WaitWorkloadHealth
  participant WorkloadHealth
  participant checkPVCHealth
  participant PVCAPI
  WaitWorkloadHealth->>WorkloadHealth: check workload health
  WorkloadHealth->>checkPVCHealth: validate workload PVC
  checkPVCHealth->>PVCAPI: retrieve PVC
  PVCAPI-->>checkPVCHealth: return PVC state
  checkPVCHealth-->>WorkloadHealth: return health result
  WorkloadHealth-->>WaitWorkloadHealth: return success or classified error
  WaitWorkloadHealth-->>WaitWorkloadHealth: stop retrying unrecoverable errors
Loading

Suggested reviewers: parikshithb, raghavendra-talur, benamarmk, shyamsundarr

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The changes validate PVC existence, Bound phase, and deletion state, but do not show validation that VolSync ownerReferences are cleared [#2649]. Add validation that protected PVCs have no VolSync ReplicationSource or ReplicationDestination ownerReferences after Disable DR.
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: asserting PVC state after Disable DR.
Description check ✅ Passed The description directly explains PVC validation after Disable DR and references the linked regression.
Out of Scope Changes check ✅ Passed The changes support the linked PVC health requirements and provide related retry behavior without introducing unrelated functionality.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

❤️ Share

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

@raaizik
raaizik force-pushed the e2e-assert-pvc-after-disable branch from c6373b6 to 2336d62 Compare July 27, 2026 13:02
@raaizik
raaizik marked this pull request as ready for review July 27, 2026 13:02

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

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

Inline comments:
In `@e2e/dractions/retry.go`:
- Around line 237-240: Update the error path after util.Sleep in the retry flow
to return or wrap the sleep error when cancellation or timeout occurs, rather
than using assertErr as the primary error. Preserve the existing workload,
namespace, and cluster context, and optionally include assertErr as supplemental
context.

In `@e2e/workloads/pvc.go`:
- Around line 38-54: Update isDRManagedOwnerReference to require both the owner
reference APIVersion and Kind: match VolumeReplicationGroup only with
ramendr.openshift.io/v1alpha1, and ReplicationSource or ReplicationDestination
only with volsync.backube/v1alpha1. Preserve returning false for all other
version/Kind combinations.
🪄 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: CHILL

Plan: Pro Plus

Run ID: 1150baaa-8a38-45b0-a00b-ceb1c73cc77c

📥 Commits

Reviewing files that changed from the base of the PR and between 7a6e622 and 2336d62.

📒 Files selected for processing (7)
  • e2e/dractions/actions.go
  • e2e/dractions/retry.go
  • e2e/recipes/recipes_test.go
  • e2e/types/types.go
  • e2e/workloads/deploy.go
  • e2e/workloads/pvc.go
  • e2e/workloads/vm.go
📜 Review details
⏰ Context from checks skipped due to timeout. (17)
  • GitHub Check: test
  • GitHub Check: ramendev (ubuntu-24.04, 3.10)
  • GitHub Check: drenv (ubuntu-24.04, 3.12)
  • GitHub Check: drenv (ubuntu-24.04, 3.13)
  • GitHub Check: drenv (ubuntu-24.04, 3.10)
  • GitHub Check: drenv (ubuntu-24.04, 3.11)
  • GitHub Check: ramendev (ubuntu-24.04, 3.13)
  • GitHub Check: drenv (ubuntu-24.04, 3.14-dev)
  • GitHub Check: Build image
  • GitHub Check: E2E unit tests
  • GitHub Check: Golangci Lint (api)
  • GitHub Check: Go compatibility
  • GitHub Check: Golangci Lint (.)
  • GitHub Check: Unit tests
  • GitHub Check: Golangci Lint (e2e)
  • GitHub Check: drenv (macos-latest, 3.13)
  • GitHub Check: Linters
🔇 Additional comments (7)
e2e/types/types.go (1)

96-98: LGTM!

e2e/workloads/pvc.go (1)

15-36: LGTM!

e2e/workloads/deploy.go (1)

164-167: LGTM!

e2e/workloads/vm.go (1)

130-133: LGTM!

e2e/recipes/recipes_test.go (1)

186-188: LGTM!

e2e/dractions/retry.go (1)

219-236: LGTM!

Also applies to: 241-242

e2e/dractions/actions.go (1)

134-145: LGTM!

Comment thread e2e/dractions/retry.go Outdated
Comment on lines +237 to +240
if err := util.Sleep(ctx.Context(), util.RetryInterval); err != nil {
return fmt.Errorf("workload \"%s/%s\" PVCs are not preserved in cluster %q: %w",
ctx.AppNamespace(), w.GetAppName(), cluster.Name, assertErr)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Preserve retry cancellation errors.

When util.Sleep fails because the context is canceled or times out, the returned error wraps the previous assertion error instead of the sleep error. Return the sleep error while optionally retaining the last assertion as context.

Proposed fix
 		if err := util.Sleep(ctx.Context(), util.RetryInterval); err != nil {
-			return fmt.Errorf("workload \"%s/%s\" PVCs are not preserved in cluster %q: %w",
-				ctx.AppNamespace(), w.GetAppName(), cluster.Name, assertErr)
+			return fmt.Errorf("waiting for workload \"%s/%s\" PVC preservation in cluster %q was interrupted: %w (last assertion: %v)",
+				ctx.AppNamespace(), w.GetAppName(), cluster.Name, err, assertErr)
 		}
📝 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 err := util.Sleep(ctx.Context(), util.RetryInterval); err != nil {
return fmt.Errorf("workload \"%s/%s\" PVCs are not preserved in cluster %q: %w",
ctx.AppNamespace(), w.GetAppName(), cluster.Name, assertErr)
}
if err := util.Sleep(ctx.Context(), util.RetryInterval); err != nil {
return fmt.Errorf("waiting for workload \"%s/%s\" PVC preservation in cluster %q was interrupted: %w (last assertion: %v)",
ctx.AppNamespace(), w.GetAppName(), cluster.Name, err, assertErr)
}
🤖 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 `@e2e/dractions/retry.go` around lines 237 - 240, Update the error path after
util.Sleep in the retry flow to return or wrap the sleep error when cancellation
or timeout occurs, rather than using assertErr as the primary error. Preserve
the existing workload, namespace, and cluster context, and optionally include
assertErr as supplemental context.

Comment thread e2e/workloads/pvc.go Outdated
Comment on lines +38 to +54
for _, ref := range pvc.OwnerReferences {
if isDRManagedOwnerReference(ref) {
return fmt.Errorf("pvc \"%s/%s\" still owned by %s %q in cluster %q",
namespace, pvcName, ref.Kind, ref.Name, cluster.Name)
}
}

return nil
}

func isDRManagedOwnerReference(ref metav1.OwnerReference) bool {
switch ref.Kind {
case "VolumeReplicationGroup", "ReplicationSource", "ReplicationDestination":
return true
default:
return false
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Locate relevant files and symbols"
git ls-files | rg '(^|/)pvc\.go$|pvc' | sed -n '1,120p'

echo
echo "Find OwnerReference helpers/API group/DR constants"
rg -n 'isDRManagedOwnerReference|OwnerRef|VolumeReplicationGroup|ReplicationSource|ReplicationDestination|replication' . --glob '!vendor/**' --glob '!*.sum' --glob '!*.lock' | sed -n '1,200p'

echo
echo "Inspect e2e/workloads/pvc.go around helper"
sed -n '1,120p' e2e/workloads/pvc.go

echo
echo "Check imports/API constants files"
rg -n 'replicationv1alpha1|replication.*Group|GroupVersion|VolumeReplicationGroup|ReplicationSource|ReplicationDestination|rclone|ReplicationDestination|ReplicationSource' . --glob '!vendor/**' --glob '!*.sum' --glob '!*.lock' | sed -n '1,240p'

Repository: RamenDR/ramen

Length of output: 47146


🌐 Web query:

VolSync VolumeReplicationGroup ReplicationSource ReplicationDestination APIVersion groupKind

💡 Result:

In VolSync, the API version and groupKind for the relevant custom resources are as follows: The API group for VolSync is volsync.backube [1][2][3]. The supported API version for both ReplicationSource and ReplicationDestination is v1alpha1 [1][4][2]. Therefore, the groupKind and APIVersion configuration for these resources are: ReplicationSource - apiVersion: volsync.backube/v1alpha1 [2][3][5] - Kind: ReplicationSource [1][2][6] ReplicationDestination - apiVersion: volsync.backube/v1alpha1 [2][3][5] - Kind: ReplicationDestination [4][2] Note that while early design documentation may have referenced different API groups [7], the established and current implementation uses volsync.backube [1][4][2][3]. These resources are used to configure asynchronous volume replication between persistent volumes in Kubernetes environments [8][9]. When using the VolSync volume populator, a PersistentVolumeClaim may reference a ReplicationDestination via its dataSourceRef field, where the apiGroup must be specified as volsync.backube and the kind as ReplicationDestination [10][11].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Ramen GroupVersion definition"
rg -n 'var GroupVersion|GroupVersion.*=|GroupVersion\.String' internal/api internal ramendr -g '*.go' --glob '!vendor/**' | sed -n '1,120p'

echo
echo "VolSync owner references in VRG VolSync code"
rg -n 'OwnerReference|APIVersion:.*ramendr|ReplicationSource|ReplicationDestination|volsync' internal/controller/vrg_vol*.go internal/controller/vrg_volrep.go --glob '!vendor/**' | sed -n '1,240p'

echo
echo "pvc.go imports and helper context"
cat -n e2e/workloads/pvc.go

Repository: RamenDR/ramen

Length of output: 1562


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "List relevant controller Go files"
fd -e go '^(cmd|internal|e2e)' . | sed -n '1,120p'

echo
echo "Find ramen package import and GroupType definitions"
rg -n 'GroupVersion \( = schema\.GroupVersion\{|= scheme\.BuildGroupVersion|name.*volumereplicationgroup|ramendrv1alpha1' . --glob '*.go' --glob '!vendor/**' | sed -n '1,200p'

echo
echo "Inspect VRG PVC owner reference construction"
rg -n 'OwnerReference|Kind: "VolumeReplicationGroup"|Kind: "ReplicationSource"|Kind: "ReplicationDestination"' internal e2e --glob '*.go' --glob '!vendor/**' -A3 -B5 | sed -n '1,260p'

echo
echo "Inspect e2e/workloads/pvc.go"
cat -n e2e/workloads/pvc.go

Repository: RamenDR/ramen

Length of output: 43891


Match DR-managed owners by API version and Kind.

ReplicationSource and ReplicationDestination are VolSync CRDs under volsync.backube/v1alpha1, while VRG is ramendr.openshift.io/v1alpha1; matching by bare Kind can reject PVCs owned by a non-DR kind that reuses the same names. Compare both APIVersion and Kind.

🤖 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 `@e2e/workloads/pvc.go` around lines 38 - 54, Update isDRManagedOwnerReference
to require both the owner reference APIVersion and Kind: match
VolumeReplicationGroup only with ramendr.openshift.io/v1alpha1, and
ReplicationSource or ReplicationDestination only with volsync.backube/v1alpha1.
Preserve returning false for all other version/Kind combinations.

@raaizik
raaizik force-pushed the e2e-assert-pvc-after-disable branch 3 times, most recently from 3b2f2bb to 63e3d95 Compare July 28, 2026 13:33

@nirs nirs left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Issues

  • PVC health is checked only during Disable DR. PVC health matters after deployment, failover, and relocate too. The existing Health() method is already called in all these flows but does not check PVCs. A PVC being Bound is part of application health.

  • Deleted PVCs cause the test to wait until timeout. WaitPVCPreserved retries until the context times out. If the PVC is being deleted or Lost, retrying is pointless.

  • New interface method is unnecessary and inconsistent. Adding AssertPVCPreserved() to the Workload interface creates a parallel health-checking path, requires stub implementations in unrelated code (NoHooks), and duplicates the WaitWorkloadHealth retry structure. The name is also inconsistent — Health and Status are short nouns, while AssertPVCPreserved is an imperative with implementation details. Interface methods should match the existing style.

  • Health check changed from assert to wait. DisableProtection calls ctx.Workload().Health() once — fail immediately if unhealthy. This change replaces it with deployers.WaitWorkloadHealth() which retries until timeout. After Disable DR, the workload was never touched — it should already be healthy. Waiting will not help.

  • Owner reference check is redundant. By the time we check, the VRG and VolSync resources are already deleted. If they had owner references on the PVC, garbage collection would have deleted the PVC. Checking PVC phase is sufficient. If the test fails, we gather the PVC which will reveal the owner reference as the root cause.

  • Owner reference check prevents reuse in other flows. Checking owner references means the check cannot be used after failover or relocate, where PVCs may legitimately have DR owner references.

Suggested approach

Add PVC health check inside Deployment.Health() and VM.Health(). This way every caller that already checks workload health (deploy, enable protection, failover, relocate, disable protection) also validates PVC health.

Handle the different PVC states:

  • Bound — healthy, return no error.
  • Lost or DeletionTimestamp set — unrecoverable, return an unrecoverable error so the retry loop stops immediately.
  • Pending — temporary, return a regular error so the retry loop retries. This also means DisableProtection, which calls Health() once, will fail immediately on a Pending PVC — the right behavior since the PVC should already be Bound at that point.

Introduce an unrecoverable error sentinel so WaitWorkloadHealth can stop immediately instead of waiting for the test timeout:

var ErrUnrecoverable = errors.New("unrecoverable error")

When detecting an unrecoverable error, wrap the sentinel:

return fmt.Errorf("pvc %q is being deleted in cluster %q: %w",
	pvcName, cluster.Name, ErrUnrecoverable)

In WaitWorkloadHealth, stop retrying on unrecoverable errors:

for {
	err := w.Health(ctx, cluster)
	if err == nil {
		return nil
	}

	if errors.Is(err, ErrUnrecoverable) {
		return err
	}

	if err := util.Sleep(ctx.Context(), util.RetryInterval); err != nil {
		// ...
	}
}

With this approach:

  • No new method on the Workload interface.
  • No new retry function or pvc.go file.
  • No stub implementations in unrelated code.
  • PVC health is validated everywhere, not just after Disable DR.
  • Unrecoverable PVC states fail fast instead of waiting for the test timeout.
  • DisableProtection keeps the single Health() call — no need to wait since the workload was not touched.

Comment thread e2e/dractions/actions.go Outdated
// If the cluster is not nil, the workload exists and its health and PVC state are validated.
if cluster != nil {
if err := ctx.Workload().Health(ctx, cluster); err != nil {
if err := deployers.WaitWorkloadHealth(ctx, cluster); err != nil {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

When we disable protection the workload must be healthy. If not we should fail immediately. The original code was correct.

Comment thread e2e/dractions/actions.go Outdated
log.Debugf("Workload \"%s/%s\" is healthy in cluster %q",
if err := WaitPVCPreserved(ctx, cluster); err != nil {
return err
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

At this point the PVC must be Bound and not deleted. A single call is enough to validate this, and we don't need to wait.

Comment thread e2e/dractions/retry.go Outdated
}
}

func WaitPVCPreserved(ctx types.TestContext, cluster *types.Cluster) error {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This waits for no benefit. If the PVC is deleted, we already found unrecoverable state, so single check is good enough in disable DR flow.

Comment thread e2e/recipes/recipes_test.go Outdated

func (w *NoHooks) AssertPVCPreserved(ctx types.TestContext, cluster *types.Cluster) error {
return nil
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is unwanted side effect of making the workload interface bigger.

Comment thread e2e/types/types.go Outdated
Health(ctx TestContext, cluster *Cluster) error
// AssertPVCPreserved verifies application PVCs survived Disable DR (Bound, not
// deleting, no DR-managed VolSync/VRG owner references).
AssertPVCPreserved(ctx TestContext, cluster *Cluster) error

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This has several issues:

  • Health already covers PVC health check - and application with deleted PVC is not healthy.
  • The name is not consistent with other names. When we modify existing code want to keep the code consistent, as if it was written by the same person.

@raaizik
raaizik force-pushed the e2e-assert-pvc-after-disable branch 3 times, most recently from 26547ac to 1b312a1 Compare August 11, 2026 10:26
@raaizik
raaizik requested a review from nirs August 11, 2026 10:29
@raaizik
raaizik force-pushed the e2e-assert-pvc-after-disable branch 2 times, most recently from f2c1cad to 7cdafd2 Compare August 11, 2026 11:36

@nirs nirs left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks so much simpler now!

Can you share logs with this change? Did we fix the ownership issue with volsync so this check pass now, or (better) this check reveal the ownership bug?

Comment thread e2e/workloads/deploy.go Outdated
if err != nil {
if k8serrors.IsNotFound(err) {
return fmt.Errorf("pvc \"%s/%s\" not found in cluster %q",
namespace, pvcName, cluster.Name)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If the PVC is not found the application is not healthy and cannot be healthy - unless the PVC will be created soon. This is most likely unrecoverable error but it depends on when we check application health. If we check only after deployment is healthy, then this should never happen and should be unrecoverable error.

Comment thread e2e/workloads/deploy.go Outdated
}

return fmt.Errorf("pvc \"%s/%s\" not available in cluster %q: %w",
namespace, pvcName, cluster.Name, err)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is unexpected error meaning that we could not get the PVC. We try to handle such errors first before handling expected errors - this decrase teh chance to miss an uxpected errror.

So this should be:

if !k8serrors.IsNotFound(err) { 
    return err
}

// handle expected error of missing PVC...

Comment thread e2e/workloads/deploy.go Outdated
namespace, pvcName, cluster.Name, err)
}

if pvc.DeletionTimestamp != nil {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

In ramen we check !obj.GetDeletionTimestamp().IsZero(). Can we have a zero value time value in the DeletionTimestamp?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I switched to that. I think it sets a real time when deletion starts so a zero value shouldn’t show up, but IsZero() also covers a nil timestamp and keeps us consistent with the controllers

Comment thread e2e/workloads/deploy.go
namespace, pvcName, pvc.Status.Phase, cluster.Name, util.ErrUnrecoverable)
default:
return fmt.Errorf("pvc \"%s/%s\" phase is %q, expected %q in cluster %q",
namespace, pvcName, pvc.Status.Phase, corev1.ClaimBound, cluster.Name)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The default case is for handling unexpected phases added in the future?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, default covers empty status and any future phases

@raaizik
raaizik force-pushed the e2e-assert-pvc-after-disable branch 2 times, most recently from 7487c2d to 5557361 Compare August 12, 2026 12:24
@raaizik
raaizik requested a review from nirs August 13, 2026 10:34
@raaizik
raaizik force-pushed the e2e-assert-pvc-after-disable branch from 5557361 to 7c3a175 Compare August 13, 2026 10:34
Fail when application PVCs are Lost or being deleted, and treat
Pending as retryable so wait loops can recover during deploy.

Signed-off-by: raaizik <132667934+raaizik@users.noreply.github.com>
@raaizik
raaizik force-pushed the e2e-assert-pvc-after-disable branch from e495371 to c7767dd Compare August 13, 2026 10:36
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.

e2e: assert PVC state after Disable DR

2 participants