Skip to content

🧪 Add unit tests for Progress type in transfer-pvc - #290

Open
RanWurmbrand wants to merge 2 commits into
migtools:mainfrom
RanWurmbrand:test/progress-core
Open

🧪 Add unit tests for Progress type in transfer-pvc#290
RanWurmbrand wants to merge 2 commits into
migtools:mainfrom
RanWurmbrand:test/progress-core

Conversation

@RanWurmbrand

@RanWurmbrand RanWurmbrand commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

Add unit tests for Progress type in transfer-pvc

Summary

  • Adds comprehensive unit test coverage for the Progress type in cmd/transfer-pvc/progress.go
  • Introduces resetGlobals() helper to isolate tests from shared global state (pastAttempts, failedFiles)

What's covered

  • parseRsyncLogs: parsing stdout/stderr from rsync, extracting transfer stats and failed files
  • NewProgress: initialization with PVC name
  • Status(): all status transitions (exit codes, percentages, completion states)
  • Merge(): field merging, percentage aggregation across retries, capping at 100%, pastAttempts accumulation
  • AsString(): output formatting with various field combinations
  • writeProgressToFile: JSON output to file and error handling for invalid paths

Also documents

Test plan

go test ./cmd/transfer-pvc/... -v -run "TestProgress|Test_parseRsyncLogs|TestWriteProgressToFile"

Summary by CodeRabbit

  • Tests
    • Expanded coverage for transfer progress initialization and aggregation.
    • Added validation for percentage updates, retry handling, data-size tracking, and error or failed-file collection.
    • Added coverage for saving progress as JSON, including invalid-path error handling.
    • Improved test isolation by resetting shared progress state between test cases.

@coderabbitai

coderabbitai Bot commented Apr 20, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Expanded progress_test.go coverage validates progress initialization, merge aggregation and retry rules, error/file accumulation, and JSON progress-file writing.

Changes

Progress test coverage

Layer / File(s) Summary
Progress initialization and test isolation
cmd/transfer-pvc/progress_test.go
Adds shared-state reset support and verifies NewProgress initializes PVC, slices, and start time correctly.
Progress merge aggregation and retries
cmd/transfer-pvc/progress_test.go
Tests transfer and data aggregation, percentage update and capping rules, retry resets, and appending errors and failed files.
Progress JSON file writing
cmd/transfer-pvc/progress_test.go
Verifies successful JSON output and errors for invalid file paths.

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

Suggested labels: ready-for-review-notified

Suggested reviewers: stillalearner, aufi

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding unit tests for the Progress type in transfer-pvc.
✨ 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.

@github-actions

github-actions Bot commented Apr 20, 2026

Copy link
Copy Markdown

Test Coverage Report

Total: 38.4%

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 — 18.4%
  • 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			100.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				46.7%
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				90.9%
github.com/konveyor/crane/cmd/transfer-pvc/progress.go:271:		NewProgress				100.0%
github.com/konveyor/crane/cmd/transfer-pvc/progress.go:291:		Completed				100.0%
github.com/konveyor/crane/cmd/transfer-pvc/progress.go:296:		Status					100.0%
github.com/konveyor/crane/cmd/transfer-pvc/progress.go:321:		Merge					91.2%
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/e2e-tests/utils/utils.go:19:			CreateTempDir				100.0%
github.com/konveyor/crane/e2e-tests/utils/utils.go:24:			ListFilesRecursively			91.7%
github.com/konveyor/crane/e2e-tests/utils/utils.go:46:			ListFilesRecursivelyAsList		80.0%
github.com/konveyor/crane/e2e-tests/utils/utils.go:70:			HasFilesRecursively			80.0%
github.com/konveyor/crane/e2e-tests/utils/utils.go:80:			ReadTestdataFile			88.9%
github.com/konveyor/crane/e2e-tests/utils/utils.go:104:			GoldenManifestsDir			90.0%
github.com/konveyor/crane/e2e-tests/utils/utils.go:123:			CompareDirectoryFileSets		78.9%
github.com/konveyor/crane/e2e-tests/utils/utils.go:156:			CompareDirectoryYAMLSemantics		82.4%
github.com/konveyor/crane/e2e-tests/utils/utils.go:186:			parseYAMLDocuments			100.0%
github.com/konveyor/crane/e2e-tests/utils/utils.go:204:			compareYAMLFileBytes			100.0%
github.com/konveyor/crane/e2e-tests/utils/utils.go:223:			LooksLikeYAMLFile			100.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)				38.4%

Posted by CI

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

Thanks for the PR Ran! Overall looks good.

I'd suggest add parseRsyncLogs https://github.com/migtools/crane/blob/main/cmd/transfer-pvc/progress.go#L399 method test. The methods seems quite important to be tested regarding to its logic.

(I'm not sure about pod-related methods in the end of original file, but those might not be required)

}
}

func TestProgressMerge_PercentageCapAt100(t *testing.T) {

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.

This function looks little weird to me, but seems to be in sync with the tested source code. We might keep in mind those tests are testing currently existing code as-is, not saying the code implementation is correct or no.

@RanWurmbrand RanWurmbrand moved this from In progress to In review in Crane Development May 25, 2026
@istein1 istein1 moved this from In review to In progress in Crane Development Jul 13, 2026
- Add resetGlobals() helper for test isolation
- Add tests for NewProgress, Status(), Merge(), and AsString()
- Cover percentage aggregation, retry handling, and pastAttempts logic
- Document variable shadowing bug on line 262 via skipped test

Signed-off-by: Ran Wurmbrand <rwurmbra@redhat.com>
- Test writing progress to file and reading it back
- Test error handling for invalid paths

Signed-off-by: Ran Wurmbrand <rwurmbra@redhat.com>

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

🧹 Nitpick comments (2)
cmd/transfer-pvc/progress_test.go (2)

640-648: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use t.Fatalf when the read fails to avoid a cascading unmarshal error.

If os.ReadFile fails, data is nil and the subsequent json.Unmarshal will also fail, producing a second, misleading error. Stop the test at the first failure.

♻️ Proposed change
 	data, err := os.ReadFile(tmpPath)
 	if err != nil {
-		t.Errorf("Failed to read written file: %v", err)
+		t.Fatalf("Failed to read written file: %v", err)
 	}
 
 	var readProgress Progress
 	if err := json.Unmarshal(data, &readProgress); err != nil {
-		t.Errorf("Failed to unmarshal progress: %v", err)
+		t.Fatalf("Failed to unmarshal progress: %v", err)
 	}
🤖 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 `@cmd/transfer-pvc/progress_test.go` around lines 640 - 648, Use t.Fatalf
instead of t.Errorf in the os.ReadFile error branch within the progress test, so
the test stops immediately when reading tmpPath fails and does not attempt
json.Unmarshal with invalid data.

397-545: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consolidate the percentage-merge scenarios into a table-driven test.

These six functions (PercentageAggregation, PercentageBasicUpdate, PercentageAccumulationWithPastAttempts, PercentageCapAt100, PercentageOnlyUpdateIfHigher, PercentageDontUpdateIfLower) exercise the same Merge percentage path with only differing inputs/expectations — a natural fit for a single table-driven test.

Separately, TestProgressMerge_PercentageAggregation (Lines 411-414) only asserts non-nil. With resetGlobals(), pastAttempts is empty, so this reduces to merging in=40 into p=50 with no accumulation — despite the name, no aggregation is exercised, and the result (50) is never asserted. Fold it in with an explicit expected value.

As per coding guidelines: "Use table-driven tests for multiple scenarios in Go test code".

🤖 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 `@cmd/transfer-pvc/progress_test.go` around lines 397 - 545, Consolidate the
six percentage tests into one table-driven test covering each input,
pastAttempts setup, and expected TransferPercentage value. Preserve the existing
Merge scenarios, but make the former PercentageAggregation case explicitly
expect 50 and include a case that actually exercises past-attempt accumulation.
Use subtests and retain nil checks before dereferencing the result.

Source: Coding guidelines

🤖 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.

Nitpick comments:
In `@cmd/transfer-pvc/progress_test.go`:
- Around line 640-648: Use t.Fatalf instead of t.Errorf in the os.ReadFile error
branch within the progress test, so the test stops immediately when reading
tmpPath fails and does not attempt json.Unmarshal with invalid data.
- Around line 397-545: Consolidate the six percentage tests into one
table-driven test covering each input, pastAttempts setup, and expected
TransferPercentage value. Preserve the existing Merge scenarios, but make the
former PercentageAggregation case explicitly expect 50 and include a case that
actually exercises past-attempt accumulation. Use subtests and retain nil checks
before dereferencing the result.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0b42afce-da39-4440-82cd-80ed36809969

📥 Commits

Reviewing files that changed from the base of the PR and between 66d279e and 8b3396b.

📒 Files selected for processing (1)
  • cmd/transfer-pvc/progress_test.go

@RanWurmbrand RanWurmbrand changed the title Add unit tests for Progress type in transfer-pvc 🧪 Add unit tests for Progress type in transfer-pvc Jul 21, 2026
@RanWurmbrand

Copy link
Copy Markdown
Contributor Author

/rfr

@RanWurmbrand RanWurmbrand moved this from In progress to In review in Crane Development Jul 23, 2026
@RanWurmbrand RanWurmbrand added the test Testing related label Jul 23, 2026
}
p.Merge(in)
if p.TransferPercentage == nil {
t.Errorf("Merge() TransferPercentage = nil, want non-nil")

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.

This only asserts TransferPercentage != nil, not the actual value. Given Merge()'s logic (pastAttempts + incoming, capped at 100, only updates if higher than current), this test would still pass even if Merge() computed a wrong percentage or did nothing at all to it, as long as the field stayed non-nil. The name suggests it's testing aggregation specifically, but TestProgressMerge_PercentageBasicUpdate and _PercentageAccumulationWithPastAttempts right below it already do this more rigorously (asserting exact values). Worth tightening this one to assert the expected value too, or dropping it if it's redundant with those.

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

Labels

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

4 participants