Skip to content

[MTC-294] Add e2e test for CronJob migration with attached PVC as non-admin user#268

Open
midays wants to merge 2 commits intomigtools:mainfrom
midays:MTC_294-CronJob-with-attached-PVC-migration
Open

[MTC-294] Add e2e test for CronJob migration with attached PVC as non-admin user#268
midays wants to merge 2 commits intomigtools:mainfrom
midays:MTC_294-CronJob-with-attached-PVC-migration

Conversation

@midays
Copy link
Copy Markdown
Contributor

@midays midays commented Apr 16, 2026

This commit introduces a new test case that validates the migration of a CronJob along with its attached Persistent Volume Claim (PVC) when executed by a non-admin user. The test ensures that the necessary permissions are granted, the source application is prepared correctly, and the PVC is transferred and validated on the target cluster. It also checks that the CronJob is scheduled correctly on the target after migration.

Summary by CodeRabbit

  • Tests
    • Added comprehensive end-to-end test coverage validating CronJob with attached persistent volume claim migration for non-admin users, including namespace-level permission configuration, source and target environment data integrity verification, persistent volume content preservation across transfers, and CronJob schedule validation post-migration to ensure operational continuity.

…r [MTC-294]

This commit introduces a new test case that validates the migration of a CronJob along with its attached Persistent Volume Claim (PVC) when executed by a non-admin user. The test ensures that the necessary permissions are granted, the source application is prepared correctly, and the PVC is transferred and validated on the target cluster. It also checks that the CronJob is scheduled correctly on the target after migration.

Signed-off-by: midays@redhat.com <midays@redhat.com>
@midays midays self-assigned this Apr 16, 2026
@midays midays added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Apr 16, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 16, 2026

Warning

Rate limit exceeded

@midays has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 43 minutes and 58 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 43 minutes and 58 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e7170d29-6c8c-46d6-a659-7ef87f0233d7

📥 Commits

Reviewing files that changed from the base of the PR and between e129240 and dc24ea4.

📒 Files selected for processing (1)
  • e2e-tests/tests/mtc_294_cronJob_PVC_test.go
📝 Walkthrough

Walkthrough

A new e2e test is added to verify CronJob with attached PVC migration functionality for non-admin users, testing the complete migration pipeline including PVC content integrity validation across source and target clusters.

Changes

Cohort / File(s) Summary
E2E Test for CronJob with PVC Migration
e2e-tests/tests/mtc_294_cronJob_PVC_test.go
New comprehensive test covering non-admin user CronJob and PVC migration: configures non-admin contexts with namespace-admin permissions, prepares source CronJob with PVC, runs crane export/transform/apply pipeline, transfers PVC with ingress parameters, validates target PVC content via BusyBox reader pod, and verifies target CronJob execution.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • migtools/crane#182 — Introduces the e2e test framework and infrastructure (CraneRunner, TransferPVC, KubectlRunner, MigrationScenario) that this new test directly utilizes.

Suggested labels

kind/feature, test

Suggested reviewers

  • msajidmansoori12
  • nachandr
  • stillalearner

Poem

🐰 A CronJob hops through namespaces with care,
With PVCs packed in its digital hair,
Non-admin users guide the migration dance,
While logs confirm that the data can prance,
From source to target, the test stands complete! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically summarizes the main change: adding an e2e test for CronJob migration with attached PVC as non-admin user, which directly matches the new test file and its core functionality.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

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

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

❤️ Share

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

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 16, 2026

Test Coverage Report

Total: 33.0%

Per-package coverage

  • github.com/konveyor/crane — 0.0%
  • github.com/konveyor/crane/cmd/apply — 33.3%
  • github.com/konveyor/crane/cmd/convert — 0.0%
  • github.com/konveyor/crane/cmd/export — 93.1%
  • github.com/konveyor/crane/cmd/plugin-manager — 0.0%
  • github.com/konveyor/crane/cmd/plugin-manager/add — 0.0%
  • github.com/konveyor/crane/cmd/plugin-manager/list — 0.0%
  • github.com/konveyor/crane/cmd/plugin-manager/remove — 0.0%
  • github.com/konveyor/crane/cmd/runfn — 0.0%
  • github.com/konveyor/crane/cmd/skopeo-sync-gen — 0.0%
  • github.com/konveyor/crane/cmd/transfer-pvc — 9.2%
  • github.com/konveyor/crane/cmd/transform — 0.0%
  • github.com/konveyor/crane/cmd/transform/listplugins — 0.0%
  • github.com/konveyor/crane/cmd/transform/optionals — 0.0%
  • github.com/konveyor/crane/cmd/tunnel-api — 0.0%
  • github.com/konveyor/crane/cmd/version — 0.0%
  • github.com/konveyor/crane/internal/apply — 52.9%
  • github.com/konveyor/crane/internal/file — 89.2%
  • github.com/konveyor/crane/internal/flags — 0.0%
  • github.com/konveyor/crane/internal/plugin — 32.9%
  • github.com/konveyor/crane/internal/transform — 74.0%
Full function-level details
github.com/konveyor/crane/cmd/apply/apply.go:39:			Complete				100.0%
github.com/konveyor/crane/cmd/apply/apply.go:43:			Validate				100.0%
github.com/konveyor/crane/cmd/apply/apply.go:63:			Run					0.0%
github.com/konveyor/crane/cmd/apply/apply.go:67:			NewApplyCommand				0.0%
github.com/konveyor/crane/cmd/apply/apply.go:99:			addFlagsForOptions			0.0%
github.com/konveyor/crane/cmd/apply/apply.go:113:			run					0.0%
github.com/konveyor/crane/cmd/convert/convert.go:30:			NewConvertOptions			0.0%
github.com/konveyor/crane/cmd/convert/convert.go:63:			addFlagsForConvertOptions		0.0%
github.com/konveyor/crane/cmd/convert/convert.go:74:			Complete				0.0%
github.com/konveyor/crane/cmd/convert/convert.go:83:			Run					0.0%
github.com/konveyor/crane/cmd/convert/convert.go:87:			run					0.0%
github.com/konveyor/crane/cmd/convert/convert.go:112:			getClientFromContext			0.0%
github.com/konveyor/crane/cmd/convert/convert.go:134:			getRestConfigFromContext		0.0%
github.com/konveyor/crane/cmd/export/cluster.go:29:			NewClusterScopeHandler			100.0%
github.com/konveyor/crane/cmd/export/cluster.go:35:			isClusterScopedResource			100.0%
github.com/konveyor/crane/cmd/export/cluster.go:44:			filterRbacResources			100.0%
github.com/konveyor/crane/cmd/export/cluster.go:102:			NewClusterScopedRbacHandler		100.0%
github.com/konveyor/crane/cmd/export/cluster.go:113:			exportedSANamespaces			100.0%
github.com/konveyor/crane/cmd/export/cluster.go:126:			groupMatchesExportedSANamespaces	100.0%
github.com/konveyor/crane/cmd/export/cluster.go:143:			parseServiceAccountUserSubject		100.0%
github.com/konveyor/crane/cmd/export/cluster.go:154:			prepareForFiltering			100.0%
github.com/konveyor/crane/cmd/export/cluster.go:187:			filteredResourcesOfKind			100.0%
github.com/konveyor/crane/cmd/export/cluster.go:213:			accept					100.0%
github.com/konveyor/crane/cmd/export/cluster.go:223:			acceptClusterRoleBinding		100.0%
github.com/konveyor/crane/cmd/export/cluster.go:260:			acceptClusterRole			100.0%
github.com/konveyor/crane/cmd/export/cluster.go:284:			acceptSecurityContextConstraints	100.0%
github.com/konveyor/crane/cmd/export/cluster.go:336:			anyServiceAccountInNamespace		100.0%
github.com/konveyor/crane/cmd/export/crd.go:17:				normalizeGroupSet			85.7%
github.com/konveyor/crane/cmd/export/crd.go:29:				shouldSkipCRDGroup			100.0%
github.com/konveyor/crane/cmd/export/crd.go:50:				crdFailureAPIResourceName		100.0%
github.com/konveyor/crane/cmd/export/crd.go:58:				collectRelatedCRDs			89.7%
github.com/konveyor/crane/cmd/export/discover.go:39:			hasClusterScopedManifests		100.0%
github.com/konveyor/crane/cmd/export/discover.go:57:			prepareClusterResourceDir		100.0%
github.com/konveyor/crane/cmd/export/discover.go:73:			prepareFailuresDir			100.0%
github.com/konveyor/crane/cmd/export/discover.go:85:			writeResources				85.7%
github.com/konveyor/crane/cmd/export/discover.go:133:			writeErrors				83.3%
github.com/konveyor/crane/cmd/export/discover.go:174:			getFilePath				100.0%
github.com/konveyor/crane/cmd/export/discover.go:185:			discoverPreferredResources		100.0%
github.com/konveyor/crane/cmd/export/discover.go:214:			resourceToExtract			100.0%
github.com/konveyor/crane/cmd/export/discover.go:283:			isAdmittedResource			100.0%
github.com/konveyor/crane/cmd/export/discover.go:292:			getObjects				100.0%
github.com/konveyor/crane/cmd/export/discover.go:326:			iterateItemsByGet			93.8%
github.com/konveyor/crane/cmd/export/discover.go:352:			iterateItemsInList			92.3%
github.com/konveyor/crane/cmd/export/export.go:52:			Complete				90.0%
github.com/konveyor/crane/cmd/export/export.go:91:			Validate				100.0%
github.com/konveyor/crane/cmd/export/export.go:106:			validateExportNamespace			87.5%
github.com/konveyor/crane/cmd/export/export.go:122:			Run					0.0%
github.com/konveyor/crane/cmd/export/export.go:225:			NewExportCommand			50.0%
github.com/konveyor/crane/cmd/plugin-manager/add/add.go:42:		Complete				0.0%
github.com/konveyor/crane/cmd/plugin-manager/add/add.go:47:		Validate				0.0%
github.com/konveyor/crane/cmd/plugin-manager/add/add.go:90:		Run					0.0%
github.com/konveyor/crane/cmd/plugin-manager/add/add.go:94:		NewAddCommand				0.0%
github.com/konveyor/crane/cmd/plugin-manager/add/add.go:126:		addFlagsForOptions			0.0%
github.com/konveyor/crane/cmd/plugin-manager/add/add.go:131:		run					0.0%
github.com/konveyor/crane/cmd/plugin-manager/add/add.go:195:		downloadBinary				0.0%
github.com/konveyor/crane/cmd/plugin-manager/list/list.go:46:		Complete				0.0%
github.com/konveyor/crane/cmd/plugin-manager/list/list.go:51:		Validate				0.0%
github.com/konveyor/crane/cmd/plugin-manager/list/list.go:56:		Run					0.0%
github.com/konveyor/crane/cmd/plugin-manager/list/list.go:60:		NewListCommand				0.0%
github.com/konveyor/crane/cmd/plugin-manager/list/list.go:90:		addFlagsForOptions			0.0%
github.com/konveyor/crane/cmd/plugin-manager/list/list.go:98:		run					0.0%
github.com/konveyor/crane/cmd/plugin-manager/list/list.go:167:		printInstalledInformation		0.0%
github.com/konveyor/crane/cmd/plugin-manager/list/list.go:177:		groupInformationForPlugins		0.0%
github.com/konveyor/crane/cmd/plugin-manager/list/list.go:196:		printInformation			0.0%
github.com/konveyor/crane/cmd/plugin-manager/list/list.go:208:		printParamsInformation			0.0%
github.com/konveyor/crane/cmd/plugin-manager/list/list.go:222:		getOptionalFields			0.0%
github.com/konveyor/crane/cmd/plugin-manager/list/list.go:247:		printTable				0.0%
github.com/konveyor/crane/cmd/plugin-manager/plugin-manager.go:33:	Complete				0.0%
github.com/konveyor/crane/cmd/plugin-manager/plugin-manager.go:38:	Validate				0.0%
github.com/konveyor/crane/cmd/plugin-manager/plugin-manager.go:43:	Run					0.0%
github.com/konveyor/crane/cmd/plugin-manager/plugin-manager.go:47:	NewPluginManagerCommand			0.0%
github.com/konveyor/crane/cmd/plugin-manager/plugin-manager.go:78:	addFlagsForOptions			0.0%
github.com/konveyor/crane/cmd/plugin-manager/plugin-manager.go:86:	run					0.0%
github.com/konveyor/crane/cmd/plugin-manager/remove/remove.go:33:	Complete				0.0%
github.com/konveyor/crane/cmd/plugin-manager/remove/remove.go:38:	Validate				0.0%
github.com/konveyor/crane/cmd/plugin-manager/remove/remove.go:43:	Run					0.0%
github.com/konveyor/crane/cmd/plugin-manager/remove/remove.go:47:	NewRemoveCommand			0.0%
github.com/konveyor/crane/cmd/plugin-manager/remove/remove.go:77:	run					0.0%
github.com/konveyor/crane/cmd/runfn/runfn.go:33:			NewFnRunCommand				0.0%
github.com/konveyor/crane/cmd/runfn/runfn.go:49:			addFlagsForOptions			0.0%
github.com/konveyor/crane/cmd/runfn/runfn.go:59:			runE					0.0%
github.com/konveyor/crane/cmd/runfn/runfn.go:70:			preRunE					0.0%
github.com/konveyor/crane/cmd/runfn/runfn.go:112:			getFunctionImage			0.0%
github.com/konveyor/crane/cmd/runfn/runfn.go:124:			getContainerFunctions			0.0%
github.com/konveyor/crane/cmd/runfn/runfn.go:151:			getFunctionAnnotation			0.0%
github.com/konveyor/crane/cmd/runfn/runfn.go:170:			getFunctionConfig			0.0%
github.com/konveyor/crane/cmd/runfn/util.go:14:				WriteOutput				0.0%
github.com/konveyor/crane/cmd/runfn/util.go:31:				GetDestinationDir			0.0%
github.com/konveyor/crane/cmd/runfn/util.go:58:				ValidateFunctionImageURL		0.0%
github.com/konveyor/crane/cmd/runfn/util.go:80:				checkIfDirExists			0.0%
github.com/konveyor/crane/cmd/skopeo-sync-gen/skopeo-sync-gen.go:61:	Complete				0.0%
github.com/konveyor/crane/cmd/skopeo-sync-gen/skopeo-sync-gen.go:65:	Validate				0.0%
github.com/konveyor/crane/cmd/skopeo-sync-gen/skopeo-sync-gen.go:69:	NewSkopeoSyncGenCommand			0.0%
github.com/konveyor/crane/cmd/skopeo-sync-gen/skopeo-sync-gen.go:103:	shouldAddImageStream			0.0%
github.com/konveyor/crane/cmd/skopeo-sync-gen/skopeo-sync-gen.go:114:	Run					0.0%
github.com/konveyor/crane/cmd/transfer-pvc/progress.go:37:		NewRsyncLogStream			0.0%
github.com/konveyor/crane/cmd/transfer-pvc/progress.go:50:		Init					0.0%
github.com/konveyor/crane/cmd/transfer-pvc/progress.go:138:		writeProgressToFile			0.0%
github.com/konveyor/crane/cmd/transfer-pvc/progress.go:148:		Close					0.0%
github.com/konveyor/crane/cmd/transfer-pvc/progress.go:154:		Streams					0.0%
github.com/konveyor/crane/cmd/transfer-pvc/progress.go:190:		addDataSize				0.0%
github.com/konveyor/crane/cmd/transfer-pvc/progress.go:215:		String					100.0%
github.com/konveyor/crane/cmd/transfer-pvc/progress.go:219:		MarshalJSON				0.0%
github.com/konveyor/crane/cmd/transfer-pvc/progress.go:223:		AsString				0.0%
github.com/konveyor/crane/cmd/transfer-pvc/progress.go:271:		NewProgress				100.0%
github.com/konveyor/crane/cmd/transfer-pvc/progress.go:291:		Completed				0.0%
github.com/konveyor/crane/cmd/transfer-pvc/progress.go:296:		Status					38.5%
github.com/konveyor/crane/cmd/transfer-pvc/progress.go:321:		Merge					0.0%
github.com/konveyor/crane/cmd/transfer-pvc/progress.go:376:		newDataSize				72.7%
github.com/konveyor/crane/cmd/transfer-pvc/progress.go:399:		parseRsyncLogs				76.1%
github.com/konveyor/crane/cmd/transfer-pvc/progress.go:479:		waitForPodRunning			0.0%
github.com/konveyor/crane/cmd/transfer-pvc/progress.go:513:		getFinalPodStatus			0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:89:		Validate				0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:117:		Validate				0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:133:		NewTransferPVCCommand			0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:169:		addFlagsToTransferPVCCommand		0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:189:		Complete				0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:220:		Validate				0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:246:		Run					0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:250:		getClientFromContext			0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:271:		getRestConfigFromContext		0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:278:		run					0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:485:		getValidatedResourceName		0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:495:		getNodeNameForPVC			0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:515:		getIDsForNamespace			0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:541:		getRsyncClientPodSecurityContext	0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:553:		getRsyncServerPodSecurityContext	0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:565:		garbageCollect				0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:602:		deleteResourcesIteratively		0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:628:		deleteResourcesForGVK			0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:649:		followClientLogs			0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:678:		waitForEndpoint				0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:690:		createEndpoint				0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:735:		getRouteHostName			0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:752:		buildDestinationPVC			0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:773:		ApplyTo					0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:793:		ApplyTo					0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:805:		ApplyTo					0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:821:		String					0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:825:		Set					0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:835:		Type					0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:841:		parseSourceDestinationMapping		100.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:863:		String					0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:867:		Set					0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:876:		Type					0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:880:		String					0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:884:		Set					0.0%
github.com/konveyor/crane/cmd/transfer-pvc/transfer-pvc.go:894:		Type					0.0%
github.com/konveyor/crane/cmd/transform/listplugins/listplugins.go:31:	Complete				0.0%
github.com/konveyor/crane/cmd/transform/listplugins/listplugins.go:36:	Validate				0.0%
github.com/konveyor/crane/cmd/transform/listplugins/listplugins.go:41:	Run					0.0%
github.com/konveyor/crane/cmd/transform/listplugins/listplugins.go:45:	NewListPluginsCommand			0.0%
github.com/konveyor/crane/cmd/transform/listplugins/listplugins.go:77:	run					0.0%
github.com/konveyor/crane/cmd/transform/optionals/optionals.go:31:	Complete				0.0%
github.com/konveyor/crane/cmd/transform/optionals/optionals.go:36:	Validate				0.0%
github.com/konveyor/crane/cmd/transform/optionals/optionals.go:41:	Run					0.0%
github.com/konveyor/crane/cmd/transform/optionals/optionals.go:45:	NewOptionalsCommand			0.0%
github.com/konveyor/crane/cmd/transform/optionals/optionals.go:77:	run					0.0%
github.com/konveyor/crane/cmd/transform/transform.go:50:		Complete				0.0%
github.com/konveyor/crane/cmd/transform/transform.go:54:		Validate				0.0%
github.com/konveyor/crane/cmd/transform/transform.go:74:		Run					0.0%
github.com/konveyor/crane/cmd/transform/transform.go:78:		NewTransformCommand			0.0%
github.com/konveyor/crane/cmd/transform/transform.go:112:		addFlagsForOptions			0.0%
github.com/konveyor/crane/cmd/transform/transform.go:136:		run					0.0%
github.com/konveyor/crane/cmd/transform/transform.go:203:		getPluginPrioritiesMap			0.0%
github.com/konveyor/crane/cmd/transform/transform.go:215:		optionalFlagsToLower			0.0%
github.com/konveyor/crane/cmd/tunnel-api/tunnel-api.go:35:		NewTunnelAPIOptions			0.0%
github.com/konveyor/crane/cmd/tunnel-api/tunnel-api.go:65:		addFlagsForTunnelAPIOptions		0.0%
github.com/konveyor/crane/cmd/tunnel-api/tunnel-api.go:77:		Complete				0.0%
github.com/konveyor/crane/cmd/tunnel-api/tunnel-api.go:100:		Validate				0.0%
github.com/konveyor/crane/cmd/tunnel-api/tunnel-api.go:116:		Run					0.0%
github.com/konveyor/crane/cmd/tunnel-api/tunnel-api.go:120:		getClientFromContext			0.0%
github.com/konveyor/crane/cmd/tunnel-api/tunnel-api.go:129:		getRestConfigFromContext		0.0%
github.com/konveyor/crane/cmd/tunnel-api/tunnel-api.go:136:		run					0.0%
github.com/konveyor/crane/cmd/version/version.go:20:			Complete				0.0%
github.com/konveyor/crane/cmd/version/version.go:25:			Validate				0.0%
github.com/konveyor/crane/cmd/version/version.go:30:			Run					0.0%
github.com/konveyor/crane/cmd/version/version.go:34:			NewVersionCommand			0.0%
github.com/konveyor/crane/cmd/version/version.go:60:			run					0.0%
github.com/konveyor/crane/internal/apply/kustomize.go:28:		ApplySingleStage			0.0%
github.com/konveyor/crane/internal/apply/kustomize.go:69:		ApplyMultiStage				0.0%
github.com/konveyor/crane/internal/apply/kustomize.go:109:		ApplyFinalStage				66.7%
github.com/konveyor/crane/internal/apply/kustomize.go:155:		runKustomizeBuild			87.5%
github.com/konveyor/crane/internal/apply/kustomize.go:172:		ValidateKubectlAvailable		75.0%
github.com/konveyor/crane/internal/apply/kustomize.go:182:		splitMultiDocYAMLToFiles		88.4%
github.com/konveyor/crane/internal/file/file_helper.go:22:		ReadFiles				100.0%
github.com/konveyor/crane/internal/file/file_helper.go:32:		readFiles				84.0%
github.com/konveyor/crane/internal/file/file_helper.go:83:		GetWhiteOutFilePath			100.0%
github.com/konveyor/crane/internal/file/file_helper.go:87:		GetTransformPath			100.0%
github.com/konveyor/crane/internal/file/file_helper.go:91:		GetIgnoredPatchesPath			0.0%
github.com/konveyor/crane/internal/file/file_helper.go:95:		updateTransformDirPath			100.0%
github.com/konveyor/crane/internal/file/file_helper.go:99:		updateIgnoredPatchesDirPath		0.0%
github.com/konveyor/crane/internal/file/file_helper.go:106:		updatePath				100.0%
github.com/konveyor/crane/internal/file/file_helper.go:113:		GetOutputFilePath			100.0%
github.com/konveyor/crane/internal/file/file_helper.go:123:		GetStageDir				100.0%
github.com/konveyor/crane/internal/file/file_helper.go:129:		GetResourcesDir				100.0%
github.com/konveyor/crane/internal/file/file_helper.go:135:		GetPatchesDir				100.0%
github.com/konveyor/crane/internal/file/file_helper.go:141:		GetReportsDir				100.0%
github.com/konveyor/crane/internal/file/file_helper.go:147:		GetWhiteoutsDir				100.0%
github.com/konveyor/crane/internal/file/file_helper.go:153:		GetKustomizationPath			100.0%
github.com/konveyor/crane/internal/file/file_helper.go:159:		GetMetadataPath				100.0%
github.com/konveyor/crane/internal/file/file_helper.go:165:		GetResourceTypeFilePath			100.0%
github.com/konveyor/crane/internal/file/file_helper.go:171:		GetPatchFilePath			100.0%
github.com/konveyor/crane/internal/file/file_helper.go:177:		GetWhiteoutReportPath			100.0%
github.com/konveyor/crane/internal/file/file_helper.go:183:		GetIgnoredPatchReportPath		100.0%
github.com/konveyor/crane/internal/flags/global_flags.go:14:		ApplyFlags				0.0%
github.com/konveyor/crane/internal/flags/global_flags.go:21:		GetLogger				0.0%
github.com/konveyor/crane/internal/flags/global_flags.go:29:		initConfig				0.0%
github.com/konveyor/crane/internal/plugin/plugin_helper.go:21:		GetPlugins				0.0%
github.com/konveyor/crane/internal/plugin/plugin_helper.go:38:		getBinaryPlugins			0.0%
github.com/konveyor/crane/internal/plugin/plugin_helper.go:63:		IsExecAny				0.0%
github.com/konveyor/crane/internal/plugin/plugin_helper.go:67:		GetFilteredPlugins			0.0%
github.com/konveyor/crane/internal/plugin/plugin_helper.go:106:		isPluginInList				0.0%
github.com/konveyor/crane/internal/plugin/plugin_manager_helper.go:24:	BuildManifestMap			0.0%
github.com/konveyor/crane/internal/plugin/plugin_manager_helper.go:68:	GetYamlFromUrl				75.0%
github.com/konveyor/crane/internal/plugin/plugin_manager_helper.go:82:	YamlToManifest				72.7%
github.com/konveyor/crane/internal/plugin/plugin_manager_helper.go:104:	FilterPluginForOsArch			100.0%
github.com/konveyor/crane/internal/plugin/plugin_manager_helper.go:122:	GetDefaultSource			0.0%
github.com/konveyor/crane/internal/plugin/plugin_manager_helper.go:131:	LocateBinaryInPluginDir			0.0%
github.com/konveyor/crane/internal/plugin/plugin_manager_helper.go:143:	IsUrl					100.0%
github.com/konveyor/crane/internal/plugin/plugin_manager_helper.go:149:	getData					80.0%
github.com/konveyor/crane/internal/transform/orchestrator.go:36:	RunSingleStage				0.0%
github.com/konveyor/crane/internal/transform/orchestrator.go:110:	RunMultiStage				63.0%
github.com/konveyor/crane/internal/transform/orchestrator.go:173:	executeStage				66.7%
github.com/konveyor/crane/internal/transform/orchestrator.go:238:	loadStageOutput				29.0%
github.com/konveyor/crane/internal/transform/orchestrator.go:304:	filterPluginsByStage			85.7%
github.com/konveyor/crane/internal/transform/stages.go:22:		DiscoverStages				90.5%
github.com/konveyor/crane/internal/transform/stages.go:84:		FilterStages				94.1%
github.com/konveyor/crane/internal/transform/stages.go:153:		GetFirstStage				100.0%
github.com/konveyor/crane/internal/transform/stages.go:163:		GetLastStage				66.7%
github.com/konveyor/crane/internal/transform/stages.go:173:		GetPreviousStage			100.0%
github.com/konveyor/crane/internal/transform/stages.go:183:		GetNextStage				100.0%
github.com/konveyor/crane/internal/transform/stages.go:193:		ValidateStageName			100.0%
github.com/konveyor/crane/internal/transform/stages.go:202:		GenerateStageName			100.0%
github.com/konveyor/crane/internal/transform/writer.go:24:		NewKustomizeWriter			100.0%
github.com/konveyor/crane/internal/transform/writer.go:32:		WriteStage				75.0%
github.com/konveyor/crane/internal/transform/writer.go:152:		parseTypeKey				50.0%
github.com/konveyor/crane/internal/transform/writer.go:174:		capitalizeFirst				66.7%
github.com/konveyor/crane/internal/transform/writer.go:188:		filterValidRemoveOps			76.2%
github.com/konveyor/crane/internal/transform/writer.go:232:		pathExists				93.5%
github.com/konveyor/crane/internal/transform/writer.go:310:		checkStageDirectory			23.1%
github.com/konveyor/crane/main.go:21:					main					0.0%
total:									(statements)				33.0%

Posted by CI

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

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

Inline comments:
In `@e2e-tests/tests/mtc_294_cronJob_PVC_test.go`:
- Around line 53-63: The test is switching back to scenario.KubectlTgt for
target-side mutations which bypasses the non-admin path; instead, use the
namespace-admin runner returned by SetupNamespaceAdminUsersForScenario
(kubectlSrcNonAdmin) for all target-side namespace operations (e.g., creating
the pvc-reader ServiceAccount and unsuspending the CronJob). Update the places
that currently call scenario.KubectlTgt (including the block around the initial
setup and the similar block at lines 199-246) to execute those mutations via
kubectlSrcNonAdmin so the non-admin scenario is exercised end-to-end, and keep
existing DeferCleanup calls unchanged.
- Around line 174-178: The test currently only checks that
ListPVCs(tgtApp.Namespace, "", tgtApp.Context) returns a non-empty slice
(tgtPVCs); update the assertion to verify each expected migrated PVC name exists
in tgtPVCs and that its Status.Phase equals "Bound"
(corev1.PersistentVolumeClaimPhase/ corev1.ClaimBound). Locate where the source
PVC names are gathered (e.g., srcPVCs or the setup that created the PVCs) and
for each expected name assert a matching entry in tgtPVCs by .Name and assert
its .Status.Phase == corev1.ClaimBound using Expect; keep using ListPVCs,
tgtApp.Namespace and tgtApp.Context to fetch current target PVCs before
validating names/phases.
- Around line 79-111: The current waitForLatestCronPod only waits for the latest
pod to appear and then checks logs, which can race with an active writer; change
it to wait until the pod has completed (phase Succeeded) before returning and
before any suspend/export/validation steps. Locate waitForLatestCronPod and
replace the pod-existence check with a loop or kubectl invocation that queries
the pod's .status.phase (or uses kubectl wait for the pod to reach Succeeded)
for the resolved podName, and only then return podName; also ensure
assertPodLogsContain is used after that completion check so log-based completion
assertions happen on a finished pod. Ensure you reference the pod via the same
label selection logic already in waitForLatestCronPod (cronowner= + appName) so
the correct latest pod is checked.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: bc6d7fd6-b818-467f-a3c5-309b9fa958e6

📥 Commits

Reviewing files that changed from the base of the PR and between cfa9358 and e129240.

📒 Files selected for processing (1)
  • e2e-tests/tests/mtc_294_cronJob_PVC_test.go

Comment on lines +53 to +63
kubectlSrcNonAdmin, _, cleanup, err := SetupNamespaceAdminUsersForScenario(scenario, namespace)
Expect(err).NotTo(HaveOccurred())
DeferCleanup(func() {
By("Delete test namespace on source and target (best effort)")
for _, k := range []KubectlRunner{scenario.KubectlSrc, scenario.KubectlTgt} {
if _, err := k.Run("delete", "namespace", namespace, "--ignore-not-found=true", "--wait=false"); err != nil {
log.Printf("cleanup: failed to delete namespace %q on context %q: %v", namespace, k.Context, err)
}
}
})
DeferCleanup(cleanup)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Keep the target-side mutations on the namespace-admin runner.

After setting up namespace-admin access, the test switches back to scenario.KubectlTgt for creating pvc-reader and unsuspending the CronJob. That bypasses the non-admin path the scenario is supposed to validate.

Suggested change
-		kubectlSrcNonAdmin, _, cleanup, err := SetupNamespaceAdminUsersForScenario(scenario, namespace)
+		kubectlSrcNonAdmin, kubectlTgtNonAdmin, cleanup, err := SetupNamespaceAdminUsersForScenario(scenario, namespace)
 		Expect(err).NotTo(HaveOccurred())
@@
-		_, err = scenario.KubectlTgt.Run(
+		_, err = kubectlTgtNonAdmin.Run(
 			"run", "pvc-reader",
 			"-n", namespace,
 			"--image=busybox",
@@
-		_, err = scenario.KubectlTgt.Run(
+		_, err = kubectlTgtNonAdmin.Run(
 			"patch", "cronjob", appName,
 			"-n", namespace,
 			"-p", `{"spec":{"suspend":false}}`,
 		)

Also applies to: 199-246

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

In `@e2e-tests/tests/mtc_294_cronJob_PVC_test.go` around lines 53 - 63, The test
is switching back to scenario.KubectlTgt for target-side mutations which
bypasses the non-admin path; instead, use the namespace-admin runner returned by
SetupNamespaceAdminUsersForScenario (kubectlSrcNonAdmin) for all target-side
namespace operations (e.g., creating the pvc-reader ServiceAccount and
unsuspending the CronJob). Update the places that currently call
scenario.KubectlTgt (including the block around the initial setup and the
similar block at lines 199-246) to execute those mutations via
kubectlSrcNonAdmin so the non-admin scenario is exercised end-to-end, and keep
existing DeferCleanup calls unchanged.

Comment on lines +79 to +111
By("Wait for at least one job pod to succeed and write to PVC")
waitForLatestCronPod := func(k KubectlRunner) string {
var podName string
Eventually(func() string {
out, err := k.Run(
"get", "pod",
"-n", namespace,
"-l", "cronowner="+appName,
"--sort-by=.metadata.creationTimestamp",
"-o", "jsonpath={.items[*].metadata.name}",
)
if err != nil {
return ""
}
pods := strings.Fields(out)
if len(pods) == 0 {
return ""
}
podName = pods[len(pods)-1]
return podName
}, "3m", "10s").ShouldNot(BeEmpty())
return podName
}

assertPodLogsContain := func(k KubectlRunner, podName, substr string) {
Eventually(func() string {
out, err := k.Run("logs", podName, "-n", namespace)
if err != nil {
return ""
}
return out
}, "2m", "10s").Should(ContainSubstring(substr))
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Wait for the CronJob pod to finish before exporting or validating PVC state.

waitForLatestCronPod only waits for pod creation, then log output. The source pod can still be running when you suspend/export, which makes the PVC copy race with the active writer and turns this into a flaky partial-write check.

Suggested change
 		waitForLatestCronPod := func(k KubectlRunner) string {
 			var podName string
 			Eventually(func() string {
 				out, err := k.Run(
 					"get", "pod",
 					"-n", namespace,
 					"-l", "cronowner="+appName,
 					"--sort-by=.metadata.creationTimestamp",
 					"-o", "jsonpath={.items[*].metadata.name}",
 				)
 				if err != nil {
 					return ""
 				}
 				pods := strings.Fields(out)
 				if len(pods) == 0 {
 					return ""
 				}
 				podName = pods[len(pods)-1]
 				return podName
 			}, "3m", "10s").ShouldNot(BeEmpty())
+			Eventually(func() string {
+				out, err := k.Run(
+					"get", "pod", podName,
+					"-n", namespace,
+					"-o", "jsonpath={.status.phase}",
+				)
+				if err != nil {
+					return ""
+				}
+				return out
+			}, "3m", "10s").Should(Equal("Succeeded"))
 			return podName
 		}
📝 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
By("Wait for at least one job pod to succeed and write to PVC")
waitForLatestCronPod := func(k KubectlRunner) string {
var podName string
Eventually(func() string {
out, err := k.Run(
"get", "pod",
"-n", namespace,
"-l", "cronowner="+appName,
"--sort-by=.metadata.creationTimestamp",
"-o", "jsonpath={.items[*].metadata.name}",
)
if err != nil {
return ""
}
pods := strings.Fields(out)
if len(pods) == 0 {
return ""
}
podName = pods[len(pods)-1]
return podName
}, "3m", "10s").ShouldNot(BeEmpty())
return podName
}
assertPodLogsContain := func(k KubectlRunner, podName, substr string) {
Eventually(func() string {
out, err := k.Run("logs", podName, "-n", namespace)
if err != nil {
return ""
}
return out
}, "2m", "10s").Should(ContainSubstring(substr))
}
waitForLatestCronPod := func(k KubectlRunner) string {
var podName string
Eventually(func() string {
out, err := k.Run(
"get", "pod",
"-n", namespace,
"-l", "cronowner="+appName,
"--sort-by=.metadata.creationTimestamp",
"-o", "jsonpath={.items[*].metadata.name}",
)
if err != nil {
return ""
}
pods := strings.Fields(out)
if len(pods) == 0 {
return ""
}
podName = pods[len(pods)-1]
return podName
}, "3m", "10s").ShouldNot(BeEmpty())
Eventually(func() string {
out, err := k.Run(
"get", "pod", podName,
"-n", namespace,
"-o", "jsonpath={.status.phase}",
)
if err != nil {
return ""
}
return out
}, "3m", "10s").Should(Equal("Succeeded"))
return podName
}
assertPodLogsContain := func(k KubectlRunner, podName, substr string) {
Eventually(func() string {
out, err := k.Run("logs", podName, "-n", namespace)
if err != nil {
return ""
}
return out
}, "2m", "10s").Should(ContainSubstring(substr))
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@e2e-tests/tests/mtc_294_cronJob_PVC_test.go` around lines 79 - 111, The
current waitForLatestCronPod only waits for the latest pod to appear and then
checks logs, which can race with an active writer; change it to wait until the
pod has completed (phase Succeeded) before returning and before any
suspend/export/validation steps. Locate waitForLatestCronPod and replace the
pod-existence check with a loop or kubectl invocation that queries the pod's
.status.phase (or uses kubectl wait for the pod to reach Succeeded) for the
resolved podName, and only then return podName; also ensure assertPodLogsContain
is used after that completion check so log-based completion assertions happen on
a finished pod. Ensure you reference the pod via the same label selection logic
already in waitForLatestCronPod (cronowner= + appName) so the correct latest pod
is checked.

Comment on lines +174 to +178
By("Verify PVC exists and is Bound on target")
tgtPVCs, err := ListPVCs(tgtApp.Namespace, "", tgtApp.Context)
Expect(err).NotTo(HaveOccurred())
Expect(tgtPVCs).NotTo(BeEmpty(), "expected PVC to be present on target after transfer")
log.Printf("PVC(s) confirmed on target cluster\n")
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Verify the transferred PVCs by name and phase.

This only proves the target namespace has some PVC. In a fixed namespace, stale resources can satisfy NotTo(BeEmpty()), and the test never asserts that each migrated claim exists and reaches Bound.

Suggested change
-		tgtPVCs, err := ListPVCs(tgtApp.Namespace, "", tgtApp.Context)
-		Expect(err).NotTo(HaveOccurred())
-		Expect(tgtPVCs).NotTo(BeEmpty(), "expected PVC to be present on target after transfer")
-		log.Printf("PVC(s) confirmed on target cluster\n")
+		for _, pvc := range pvcs {
+			Eventually(func() string {
+				out, err := scenario.KubectlTgt.Run(
+					"get", "pvc", pvc.Name,
+					"-n", tgtApp.Namespace,
+					"-o", "jsonpath={.status.phase}",
+				)
+				if err != nil {
+					return ""
+				}
+				return out
+			}, "2m", "5s").Should(Equal("Bound"), "expected PVC %q to be Bound on target", pvc.Name)
+		}
+		log.Printf("PVC(s) confirmed on target cluster\n")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@e2e-tests/tests/mtc_294_cronJob_PVC_test.go` around lines 174 - 178, The test
currently only checks that ListPVCs(tgtApp.Namespace, "", tgtApp.Context)
returns a non-empty slice (tgtPVCs); update the assertion to verify each
expected migrated PVC name exists in tgtPVCs and that its Status.Phase equals
"Bound" (corev1.PersistentVolumeClaimPhase/ corev1.ClaimBound). Locate where the
source PVC names are gathered (e.g., srcPVCs or the setup that created the PVCs)
and for each expected name assert a matching entry in tgtPVCs by .Name and
assert its .Status.Phase == corev1.ClaimBound using Expect; keep using ListPVCs,
tgtApp.Namespace and tgtApp.Context to fetch current target PVCs before
validating names/phases.

This update modifies the e2e test for CronJob migration to dynamically retrieve the PVC name from the list of available PVCs instead of using a hardcoded value. This change enhances the test's flexibility and ensures it accurately reflects the current state of the environment during execution.

Signed-off-by: midays@redhat.com
Signed-off-by: midays@redhat.com <midays@redhat.com>
@midays midays moved this from Todo to In progress in Crane Development Apr 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress.

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

1 participant