Skip to content

refactor: extract operation-to-capability wiring plan with table-driven tests - #4813

Open
shashankvarma499 wants to merge 1 commit into
open-policy-agent:masterfrom
shashankvarma499:operation-wiring-plan
Open

shashankvarma499 wants to merge 1 commit into
open-policy-agent:masterfrom
shashankvarma499:operation-wiring-plan

Conversation

@shashankvarma499

Copy link
Copy Markdown

Description

Fixes #4776.

Extracts a testable operations.Plan that maps --operation values and feature flags to the clients/systems/runnables/webhooks/controllers constructed by setupControllers. Production wiring now consumes operations.CurrentPlan, so tests and process startup cannot drift.

The plan makes previously-undetected wiring contradictions explicit and testable, e.g.:

  • status builds the constraint client with no enforcement point.
  • generate owns CRD/VAP/VAPB behavior but does not start the ConstraintTemplate/Constraint reconcilers.

Changes

  • pkg/operations/plan.go — new Plan, Features, NewPlan, CurrentPlan, and Plan.Validate.
  • pkg/operations/plan_test.go — table-driven suite covering all 7 isolated operations, shipped combinations (audit+status+mutation-status+generate, webhook+mutation-webhook, default all-operations), and feature toggles (expansion, external data, violation/admission export, VAP scope sync, k8s native validation).
  • pkg/operations/operations.go — add AssignedSet() and shared hasValidationOperations/hasMutationOperations helpers.
  • main.go — setupControllers now consumes CurrentPlan.

Tests

  • go test ./pkg/operations/... -count=1 — pass
  • go build . — pass
  • go vet ./pkg/operations/... . — pass

(Controller tests requiring envtest/kubebuilder binaries were not run — those assets aren't present in this environment; unrelated to this change.)

@shashankvarma499
shashankvarma499 requested a review from a team as a code owner September 2, 2026 19:41
@linux-foundation-easycla

linux-foundation-easycla Bot commented Sep 2, 2026 •

Copy link
Copy Markdown

CLA Signed
The committers listed above are authorized under a signed CLA.

  • ✅ login: shashankvarma499 / name: Shashank Varma (6c0c32d)

Extract a testable Plan that maps --operation values and feature flags to the
clients/systems/runnables/webhooks/controllers constructed by setupControllers.
Production wiring now consumes CurrentPlan, so tests and startup cannot drift.
Adds a table-driven suite covering all isolated operations, shipped
combinations, and feature toggles, plus Plan.Validate dependency checks.

Fixes open-policy-agent#4776

Signed-off-by: Shashank Varma <324153016+shashankvarma499@users.noreply.github.com>
@shashankvarma499 shashankvarma499 changed the title Add operation-to-capability wiring plan and table-driven tests refactor: extract operation-to-capability wiring plan with table-driven tests Sep 12, 2026
@JaydipGabani
JaydipGabani requested a balanced review from Copilot September 14, 2026 23:53

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

The new plan tests pass, but they do not verify the real registration path and they encode the two known operation contradictions as expected behavior. status still cannot start because it creates a constraint client with no enforcement point, and generate still omits the reconcilers that own generation. Please make production controller registration consume the plan (or exercise actual registration) and assert the documented behavior for both isolated operations.

Comment thread pkg/operations/plan.go
Mutation: ops[MutationWebhook],
NamespaceLabel: ops[Webhook] || ops[MutationWebhook],
},
Controllers: ControllerPlan{

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.

ControllerPlan is not consumed by production code. setupControllers still calls controller.AddToManager unconditionally, and each adder independently reads the global operation and feature flags. A guard here can therefore diverge from actual registration while every table test remains green. Please make registration consume this plan, or add the required focused test around real setup/registration that observes which controllers were actually added.

Comment thread pkg/operations/plan.go

p := Plan{
Clients: ClientPlan{
ConstraintClient: hasValidation,

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.

status makes hasValidation true, but neither enforcement flag is set. setupControllers then calls constraintclient.NewClient with an empty EnforcementPoints(), which returns must specify at least one enforcement point; Plan.Validate() does not catch this. This keeps --operation=status unable to start and the new status row blesses the regression. status must not construct the validation client and ingestion stack solely for status aggregation.

Comment thread pkg/operations/plan.go
NamespaceLabel: ops[Webhook] || ops[MutationWebhook],
},
Controllers: ControllerPlan{
ConstraintTemplate: hasValidation,

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.

generate is excluded from hasValidation, so a generate-only plan sets both ConstraintTemplate and Constraint false. Those reconcilers own CRD/VAP/VAPB generation, so the documented operation still does nothing. The table test currently codifies this known bug instead of failing on it. Please model generation as its own controller and compilation capability rather than as an audit or webhook enforcement point.

Copilot AI 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.

🟡 Changes recommended

Unresolved critical and moderate findings affect status wiring, generation behavior, and controller registration.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Refactors operation-to-capability wiring into a testable operations.Plan and integrates it into startup setup.

Changes:

  • Adds plan types, feature handling, validation, and table-driven tests.
  • Adds operation snapshots and shared predicates.
  • Updates startup wiring to consume CurrentPlan.
File summaries
File Summary
pkg/operations/plan.go Defines capability planning. Findings include invalid status-only client allocation, unused controller-plan flags, and omitted scope-sync gating.
pkg/operations/plan_test.go Tests operations and feature combinations; generate-only expectations omit required reconcilers.
pkg/operations/operations.go Adds AssignedSet() and shared operation predicates.
main.go Uses CurrentPlan, but controller registration still iterates global injectors instead of plan-controlled controllers.
Review details

Suppressed comments (4)

pkg/operations/plan.go:135

  • These capabilities ignore SyncVAPEnforcementScope. When generation is enabled but scope synchronization is disabled, setupControllers still allocates both the webhook-config cache and the ConstraintTemplate event channel, although the webhook-config controller and all event paths gate on the same flag. The feature-toggle case therefore does not prove optional dependencies are absent; include the scope flag in these two capabilities.
			WebhookConfigCache:       ops[Generate],
			ConstraintTemplateEvents: ops[Generate],

pkg/operations/plan.go:155

  • With only Generate selected, hasValidation is false, so this plan leaves both reconciliation paths disabled. setupControllers still delegates to adders whose HasValidationOperations guards return early, meaning generate-only never reconciles ConstraintTemplates/Constraints and cannot create the CRDs or VAP/VAPB resources that the generate operation documents (#4771). Generation needs an explicit capability separate from audit/webhook enforcement rather than preserving this contradictory expectation.
			ConstraintTemplate:       hasValidation,
			Constraint:               hasValidation,

pkg/operations/plan.go:89

  • The new ControllerPlan flags are not consumed by production registration: main.go still passes every injector to controller.AddToManager, and each adder independently checks the global operation/feature flags. Thus this is a second mapping that tests can validate while runtime registration follows different predicates, so the claimed single source of truth can drift. Pass the plan into registration or make the adders derive their guards from it.
// ControllerPlan describes controller registration.
type ControllerPlan struct {
	ConstraintTemplate       bool
	Constraint               bool
	Config                   bool

pkg/operations/plan_test.go:377

  • Every row here calls only NewPlan and Validate; no test invokes setupControllers, controller.AddToManager, or an individual registration path. This cannot verify the required non-nil dependencies at registration time or catch a production guard regression, so the suite does not meet the real setup/registration coverage required for this refactor.
			got := NewPlan(tc.ops, tc.features)
			if diff := cmp.Diff(tc.want, got); diff != "" {
				t.Errorf("NewPlan() mismatch (-want +got):\n%s", diff)
			}
			if err := got.Validate(); err != nil {
  • Files reviewed: 4/4 changed files
  • Comments generated: 3
  • Review effort level: Lite (auto)

Note

Copilot is running an experiment and ran this review at Lite.


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread pkg/operations/plan.go
ops = Set{}
}

hasValidation := hasValidationOperations(ops)
Comment on lines +129 to +133
// Generate currently does not start ConstraintTemplate/Constraint
// reconcilers because HasValidationOperations excludes Generate. See #4771.
name: "generate",
ops: Set{Generate: true},
features: DefaultFeatures(),
Comment thread main.go
Comment on lines +639 to 642
if plan.Systems.ConstraintTemplateEvents || plan.Systems.WebhookConfigCache {
opts.CtEvents = make(chan event.GenericEvent, 1024)
opts.WebhookConfigCache = webhookconfigcache.NewWebhookConfigCache()
}

This branch has not been deployed

No deployments
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.

Add table-driven tests for operation-specific controller wiring

3 participants