Skip to content

app-policy: policyscale, a shared generator for the large-policy-set benchmarks - #13895

Draft
dimitri-nicolo wants to merge 1 commit into
projectcalico:masterfrom
dimitri-nicolo:dimitri-pmreq954-policygen
Draft

app-policy: policyscale, a shared generator for the large-policy-set benchmarks#13895
dimitri-nicolo wants to merge 1 commit into
projectcalico:masterfrom
dimitri-nicolo:dimitri-pmreq954-policygen

Conversation

@dimitri-nicolo

Copy link
Copy Markdown
Contributor

Description

First of a stack for the collector policy-evaluation work tracked in CORE-13316 (target: 10k flows/s per node on very large policy sets, without changing verdicts). This PR is the yardstick the rest is measured with; it changes no production code.

app-policy/policyscale lifts the two synthetic policy sets out of the checker benchmarks (bench_test.go, bench_egress_test.go) into a package that renders the same set three ways:

  • a policystore.PolicyStore plus proto.WorkloadEndpoint, for engine and collector benchmarks;
  • the ToDataplane updates that load it through PolicyStore.ProcessUpdate;
  • Calico resources (Tier, GlobalNetworkPolicy, GlobalNetworkSet) for applying it to a cluster, via hack/cmd/policyscale.

So a number measured at the engine, in the collector and on a node describes the same policy set.

The fixture also carries an oracle. Fixture.Expect computes the trace the engine must report for a flow from the generator's own model of each rule, independently of the matching code in match.go, and MatchingFlow, DeniedFlow and Sampler produce flows aimed at chosen depths of the walk or following a flow model (miss fraction, repeat fraction). The next PRs in the stack use these for differential tests that gate the compile-once change (#13267), a verdict cache, and evaluation off the collector's main loop.

Composite applies both measured shapes to one endpoint: 19,992 ingress rules, 18,662 egress rules, 7,571 IP sets. BenchmarkEvaluateComposite measures it in the three cases that matter for the collector (ingress miss-all, egress miss-all, egress match on a tail port). The two existing benchmarks keep their cases; their fixtures are built by the shared generator with the same seed and the same draw order, so their numbers are unchanged.

Two things worth knowing:

  • The baseline size histogram, sampled uniformly within each bucket, yields about 1M IP-set members rather than the ~256k measured in the deployment it was taken from (the 1,000–9,999 bucket dominates). That was already true of the fixture before this PR; it is now documented on DefaultBaseline and pinned by a test rather than silently changed. The composite YAML is ~26 MB for that reason.
  • Rendered resources differ from the proto in two ways the v3 API forces: rules with ports carry protocol: TCP (every generated flow is TCP, so verdicts are unchanged) and policy names carry the tier prefix.

Testing

go test ./app-policy/policyscale/                                  # ok (19s; validates a sample of the rendered resources through libcalico-go's validator and round-trips the YAML)
go test ./app-policy/checker/                                       # ok
go test ./app-policy/checker/ -run '^$' -bench BenchmarkEvaluate -benchmem -benchtime 5x -cpu 1
go run ./hack/cmd/policyscale -preset composite -out composite.yaml  # 8,167 objects
go run ./hack/cmd/policyscale -preset composite -flows 1000 -direction egress

Release note:

None

AI assistance: Written with Claude Code (Claude Fable 5.1); the author reviewed the diff and ran the tests and benchmarks above.

By opening this PR you take responsibility for every line in it, and you agree to explain the change yourself during review rather than routing review comments back through an agent. See AI_POLICY.md.

🤖 Generated with Claude Code

@dimitri-nicolo dimitri-nicolo added docs-not-required Docs not required for this change release-note-not-required Change has no user-facing impact labels Sep 12, 2026
@marvin-tigera marvin-tigera added this to the Calico v3.34.0 milestone Sep 12, 2026
@github-actions

github-actions Bot commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

CI triage — Calico

Recommendation: Dig deeper before merging

Likely caused by this PR

Test Why
Check Go / Check Go files make check-dirty failed: hack/deps.txt needs updating for new policyscale packages.

workflow_id: e5ee616e-99b6-4bc6-bc8d-65b7d6de3355

…benchmarks

Lift the two synthetic policy sets out of the checker benchmarks into a
package that renders the same set three ways: a policystore.PolicyStore
and endpoint for engine and collector benchmarks, the ToDataplane updates
that load it through ProcessUpdate, and Calico resources (Tier,
GlobalNetworkPolicy, GlobalNetworkSet) for applying it to a cluster. A
number measured at the engine, in the collector and on a node then
describes the same policy set.

The fixture also carries an oracle: Fixture.Expect computes the trace the
engine must report for a flow from the generator's own model of each rule,
independently of the matching code, and MatchingFlow / DeniedFlow /
Sampler produce flows aimed at chosen depths of the walk or following a
flow model (miss fraction, repeat fraction). Later changes to the engine
(compiled policies, a verdict cache, evaluation off the collector's main
loop) are gated on differential tests built on these.

Composite applies both measured shapes to one endpoint: 19,992 ingress
rules, 18,662 egress rules, 7,571 IP sets. BenchmarkEvaluateComposite
measures it in the three cases that matter for the collector; the two
existing benchmarks keep their cases and their numbers.

hack/cmd/policyscale renders a preset as YAML, or prints sampled flows
with their expected verdicts, for node-level runs.

Tracking: CORE-13316.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs-not-required Docs not required for this change release-note-not-required Change has no user-facing impact

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants