Repository navigation
fix(test): stop using a carved-out verb as a generic ceiling fixture - #1772
Conversation
TestGrantCeiling_ConstraintContainment used execute:ri-exchange as its fixture verb to exercise general grant-ceiling constraint containment (narrower-allowed, cap-drop-refused, unheld-provider-refused). PR #1758 then added {execute, ri-exchange} to adminCarvedOuts. checkGrantCeiling (internal/auth/group_ceiling.go) checks adminCarvedOuts before the containment logic in grantCeilingAllows, so once the fixture's verb became carved out, the test's target group (no existing permissions) made every subtest refuse with ErrPermissionNotGrantable before the containment logic it exists to exercise ever ran. Both #1737 and #1758 were correct in isolation; the conflict is emergent from their merge order. Swap the fixture verb for view:plans, already used elsewhere in this file, and hoist it to named constants with an assertion that it is not in adminCarvedOuts -- so the next carve-out addition that collides fails loudly at the fixture instead of three subtests dying somewhere that looks unrelated. checkGrantCeiling's carve-out-before-containment ordering is untouched; it is correct and deliberate. Refs #1737, #1758
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 43 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
Comment |
|
Merging immediately to unblock Merging without an independent review round, deliberately. This is a test-only fix (one file, +22/-7) restoring a red Root cause: an emergent conflict between two independently-green PRs.
It never failed to compile. Confirmed before fixing, so the blast radius was known: The fix hoists the fixture verb to named constants and asserts it is not carved out: const fixtureAction, fixtureResource = ActionView, ResourcePlans
require.False(t, adminCarvedOuts[[2]string{fixtureAction, fixtureResource}],
"refuses before this test's containment logic ever runs", ...)That second line is the part that matters. Follow-up owed: any other test using a carved-out pair as a generic fixture is latent even where it passes today. That sweep is bounded to what is currently green, so it is not urgent — but it should be recorded rather than assumed complete. Unblocks #1764, #1767, #1770, #1771, and the held |
Summary
mainis red:TestGrantCeiling_ConstraintContainmentininternal/auth/group_ceiling_permissions_test.gofails (3 subtests + parent), blocking CI on every open PR.Root cause: an emergent conflict between two independently-green PRs, not a logic bug.
execute:ri-exchangeas its fixture verb to exercise general grant-ceiling constraint containment (narrower grant allowed / cap-drop refused / unheld-provider-add refused), against a target group with an empty existing-permissions list.{ActionExecute, ResourceRIExchange}toadminCarvedOuts.checkGrantCeiling(internal/auth/group_ceiling.go:73-96) checksadminCarvedOutsbefore the containment logic ingrantCeilingAllows. Once the fixture's verb became carved out, and the target group didn't already hold it, every subtest hit the unconditional carve-out refusal (ErrPermissionNotGrantable) before the containment logic it exists to test ever ran.Both #1737 (grant ceiling) and #1758 (RI-exchange carve-out) are correct in isolation. Neither is at fault; the merge sequencing created a stale fixture.
Fix
Test-only. Swapped the fixture verb from
execute:ri-exchangetoview:plans(already used elsewhere in the same file, not a carved-out pair) and hoisted it to named constants with an assertion that the verb is not inadminCarvedOuts, so the next carve-out addition that collides with a generic fixture fails loudly at the fixture instead of three subtests dying somewhere that looks unrelated.checkGrantCeiling's carve-out-before-containment ordering is untouched -- verifiedgit diff 7c4e8405c origin/main -- internal/auth/group_ceiling.gois empty, so the squash-merge did not alter it. That ordering is correct and deliberate (issue #923 separation of duties): a carved-out verb must refuse unconditionally regardless of what containment logic would otherwise allow.Sweep for latent occurrences of the same defect
adminCarvedOutscurrently holds four pairs:{execute,purchases},{approve-any,purchases},{retry-any,purchases},{execute,ri-exchange}. Searched every construction of aPermission/APIPermissionvalue acrossinternal/authand the rest of the repo for a carved-out pair used as a generic fixture (as opposed to a test that is deliberately about carve-out behavior).Fixed:
TestGrantCeiling_ConstraintContainment(this PR).Inspected and deliberately left alone (each uses a carved-out pair on purpose, to test the carve-out itself):
internal/auth/group_ceiling_permissions_test.go:TestGrantCeiling_CarvedOutNotGrantable,TestGrantCeiling_CarvedOutNotGrantableByPurchaserAdmin,TestGrantCeiling_CarvedOutMayBeKeptNotWidened-- the sec(auth): the #923 money separation-of-duties carve-out is voidable by any admin in one request #1550 attack scenarios.internal/auth/group_system_managed_test.go:TestSystemManagedGroup_Immutable.internal/auth/self_escalation_carveout_test.go: allTestSelfCarvedOutGrant_*tests.internal/auth/service_group_only_authz_test.go:TestGroupOnlyAuthz_AdminEquivalence,TestGroupOnlyAuthz_NonAdminDenied-- admin-wildcard-vs-carve-out coverage.internal/auth/service_group_test.go:TestHasPermission_RegionConstraintDeniesUnpermittedTargetRegion-- RI-exchange region-matching, callsHasPermissiondirectly, not the ceiling.internal/auth/types_test.go:adminCarvedOuts/HasPermissioncoverage.internal/api/grantadmin_carveout_test.go,internal/api/ri_exchange_carveout_test.go: handler-level carve-out enforcement tests.internal/database/postgres/migrations/000096_seed_ri_exchanger_group_test.go: the seeded-group migration test.None of these are affected, today or on a future carve-out addition, because their subject is carve-out behavior.
internal/auth/group_ceiling_validation_test.gowas also checked -- it only usesActionView/blank fields, no carved-out pairs.Verification
go test ./internal/auth/...-- 735 passed (was 4 failing, now 0).go build ./...,go vet ./...,go vet -tags=integration ./...-- clean.go vet -tags=e2e ./...intests/e2e-- clean.go test -race -short ./...in.,pkg,providers/aws,providers/azure,providers/gcp-- all green.gocyclo -over 10 -ignore "_test\.go" .-- 0 findings.golangci-lint runat CI-pinned v2.10.1 -- exit 0 and a genuine0 issues.line (not just exit 0, per the known v2 false-clean modes on a removed flag / concurrent-run lock).Test plan
internal/authfull package green0 issues.)