test: lifecycle/error-path coverage + teardown determinism (#68) - #81
Merged
Merged
Conversation
senolcolak
force-pushed
the
feat/66-ci-baseline
branch
from
September 3, 2026 14:42
1abc382 to
d00f696
Compare
senolcolak
force-pushed
the
feat/68-lifecycle-coverage
branch
from
September 3, 2026 14:42
0e9e573 to
0c264e0
Compare
senolcolak
force-pushed
the
feat/66-ci-baseline
branch
from
September 3, 2026 15:05
d00f696 to
79e24d0
Compare
senolcolak
force-pushed
the
feat/68-lifecycle-coverage
branch
from
September 3, 2026 15:05
0c264e0 to
3d44052
Compare
senolcolak
force-pushed
the
feat/66-ci-baseline
branch
from
September 4, 2026 11:37
79e24d0 to
c6c5197
Compare
senolcolak
force-pushed
the
feat/68-lifecycle-coverage
branch
from
September 4, 2026 11:37
3d44052 to
7051131
Compare
Adds fast pure-unit coverage for the safety-critical reconciler branches that were previously reachable only through the slow envtest suite, fixes the teardown race that forced RandomizeAllSpecs off (#78), and corrects three webhook validation bugs surfaced by the new tests. Coverage: - Extract pure helpers allocateMonID and determinePublicAddressFor from the reconciler methods and unit-test every branch (mon-ID collision/exhaustion; all Service types + unallocated-IP/IPv6-only/no-ingress/unknown-type errors). Behavior-preserving: methods now delegate to these free functions. - docs/testing/traceability.md maps each reconcile transition/error branch to its covering spec, marking honest gaps for the deferred deletion-cascade and observedGeneration work. - Makefile: run ./pkg/controller/... in the unit layer (untagged pure tests), and add a report-only test-cover target that merges the unit and envtest coverage profiles (COVER_MIN gates once a floor is measured). - namespaceCleanUp force-strips finalizers tolerating both NotFound and Conflict and re-lists fresh each pass, converging inside a single Eventually that requires source and target namespaces empty in the same pass (source first, so the deleted RemoteArbiter stops repopulating the target). - Re-enable RandomizeAllSpecs. The "should succeed" spec waits 2 min: the reconciler has no watch on the target Deployment and only re-observes via the 1-min CheckInterval requeue, so the shared 30s timeout was intrinsically racy. Webhook fixes (regression-guarded): - Two field.Invalid calls reported the wrong field's value as BadValue (cephCluster.namespace reported .Name; monIdPrefix reported remoteCluster.Name). - The NodePort nodeIp branch reported Service.Type as BadValue and, on an unparseable IP, fell through to the Is4 check and appended a second spurious error. Fixed to one error naming the NodeIP. Closes #68 Refs #78 Signed-off-by: senol.colak <senol.colak@sap.com>
…ion works createArbiterService never set Spec.Type on the created Service, so a spec requesting service.type=NodePort (or LoadBalancer) silently got a ClusterIP Service. determinePublicAddressFor then picked the ClusterIP branch and baked an unroutable in-cluster address into the monitor's --public-addr and the monmap, with no error and no condition set. Set the created Service's type from spec.service.type, and make the NodePort branch of determinePublicAddressFor error on an empty node IP (mirroring the ClusterIP/LoadBalancer unallocated-address branches) instead of returning an empty address. Add a pure-unit regression row proving the empty-NodeIP guard. Correct docs/testing/traceability.md: drop stale line anchors (function names only), promote error-branch rows that were mislabeled 'partial' to covered after verifying the specs assert the specific condition + Error state, and record the Service-type propagation coverage honestly. Signed-off-by: senol.colak <senol.colak@sap.com>
senolcolak
force-pushed
the
feat/68-lifecycle-coverage
branch
from
September 4, 2026 11:46
7051131 to
b31f54e
Compare
jrse
self-requested a review
September 9, 2026 07:01
Collaborator
|
LGTM |
jrse
approved these changes
Sep 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #68. Fixes #78. Stacked on #80 (#66) → #79 (#67).
What
Adds fast, pure-unit coverage for the safety-critical reconciler branches that were previously reachable only through the slow envtest suite, fixes the teardown race that forced
RandomizeAllSpecsoff (#78), and corrects three webhook validation bugs that the new tests surfaced.Coverage (#68)
allocateMonIDanddeterminePublicAddressForfrom the reconciler methods; the methods now delegate to these free functions (behavior-preserving — reviewed branch-by-branch). Unit-tested inpkg/controller/allocation_test.go(no build tag, no API server):docs/testing/traceability.md: maps each reconcile transition and error branch to its covering spec, marking honest gaps for the deferred deletion-cascade and observedGeneration work (tracked follow-up)../pkg/controller/...in the unit layer (untagged pure tests), and add a report-onlytest-covertarget merging unit + envtest coverage profiles (COVER_MINgates once a floor is measured).Teardown determinism (#78)
namespaceCleanUpforce-strips finalizers tolerating bothNotFoundandConflict, re-listing fresh each pass, converging inside a singleEventuallythat requires source and target namespaces empty in the same pass (source first, so the deleted RemoteArbiter stops repopulating the target).RandomizeAllSpecs. The "should succeed" spec waits 2 min: the reconciler has no watch on the target Deployment and only re-observes via the 1-minCheckIntervalrequeue, so the shared 30s timeout was intrinsically racy — this fixes the root cause, not the symptom.Webhook fixes (regression-guarded)
Three
field.Invalidcalls reported the wrong value asBadValue, producing misleading admission errors:cephCluster.namespacereported.Name;monIdPrefixreportedremoteCluster.Name.nodeIpbranch reportedService.Typeand, on an unparseable IP, fell through to theIs4()check and appended a second spurious error. Fixed to one error naming the NodeIP.Guarded by
TestValidateRemoteArbiterSpecErrorBadValueandTestValidateRemoteArbiterSpecNodeIPErrorBadValue— both proven to fail on the pre-fix code and pass after.Verification
gofmtclean ·go vet ./...and-tags envtestclean ·make test-unitgreen ·golangci-lint0 issues · envtest suite green (5× with shuffle) ·make gen/helm/importsno-op.