Skip to content

policy-test: init test runner - #2582

Open
davidweisse wants to merge 1 commit into
mainfrom
dav/policy-test-suite
Open

policy-test: init test runner#2582
davidweisse wants to merge 1 commit into
mainfrom
dav/policy-test-suite

Conversation

@davidweisse

Copy link
Copy Markdown
Member

This creates the new subpackage policy-test which contains the genpolicy test suite. Currently, all it does is:

  1. Read the pod.yml and run contrast generate on it.
  2. Extract the policy annotation and convert it to a Policy interface (currently rego, i.e., *OPAPolicy)
  3. Read the agent RPC requests from tesdata/ and compare them against the policy (CreateSandboxRequest, CreateContainerRequest, ...)

The current test case is taken from the /tmp/policy.jsonl from inside a running container, similar to the one in the pod.yml. For now these are just a few simple cases to test, before we can automate getting these and properly normalize them (e.g., replacing image references, patching namespaces, etc.).

The rego policy checker is based on the upstream test runner at https://github.com/kata-containers/kata-containers/tree/main/src/tools/genpolicy/tests/policy. Note that the rego rules don't always return true/false, but can return a metadata response, for example:

CreateContainerRequest := {"ops": ops, "allowed": true} if { ... }

In this case, if the request is allowed, we have to apply the json patches contained in ops to the saved state of the policy engine. This is used to store information like sandbox names or ids over multiple requests.

To run the policy test suite, run the just policy target. This currently does not use a local registry, so generating the policy one time at the beginning will take a few seconds. The next step is to integrate a local registry into this process, to speed up the policy generation.

Fixes CON-250

@davidweisse davidweisse added the no changelog PRs not listed in the release notes label Aug 10, 2026
@linear-code

linear-code Bot commented Aug 10, 2026

Copy link
Copy Markdown

CON-250

@charludo charludo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this is great! 🎉

Apart from my comments below, a couple general thoughts:

  • not sure if we want to export ManipulateInitdata publicly... Maybe it belongs in an internal package instead?
  • I don't think there's a ticket for running this in CI yet, right? Which we can probably do after the local registry PR
  • why use log? I think most everywhere uses slog? (But on the other hand... w/e)
  • please add some devdocs info about how to obtain the testcases. (Can also be a separate PR, esp. if that's not settled yet.)
  • My biggest questionmark is currently how negative testcases will be obtained and implemented here

Comment thread policy-test/main.go Outdated
Comment thread policy-test/rego.go Outdated
Comment thread policy-test/main.go Outdated
Comment thread policy-test/rego.go Outdated
Comment thread policy-test/main.go Outdated
Comment thread policy-test/policy.go
Comment thread policy-test/rego.go
Comment thread policy-test/rego.go Outdated
Comment thread policy-test/main.go Outdated
Comment thread packages/by-name/policy-test/package.nix Outdated
@davidweisse
davidweisse force-pushed the dav/policy-test-suite branch from 3e71596 to 667f516 Compare August 17, 2026 11:05
@davidweisse

Copy link
Copy Markdown
Member Author
  • not sure if we want to export ManipulateInitdata publicly... Maybe it belongs in an internal package instead?

Hm, I don't like the idea of having this in an internal package either (like internal/initdata, if that's what you mean), because the logic is closely tied to the CLI with, e.g., the fileMap logic. Since we only need to extract the policy, I just hardcoded a MapPodSpec for now. We don't necessarily need all the features of manipulateInitdata here.

  • please add some devdocs info about how to obtain the testcases. (Can also be a separate PR, esp. if that's not settled yet.)

There is a ticket for automating this process, i.e., periodically generating testcases, so I don't think it's necessary to document at this point.

@davidweisse
davidweisse force-pushed the dav/policy-test-suite branch from 667f516 to ecd4a47 Compare August 17, 2026 11:31

@charludo charludo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, great work! Just some leftover re: errors in parsing files etc cancelling all test cases.

Comment thread policy-test/main.go Outdated
log.Printf("===== Running test case: %s", file.Name())
fileData, err := os.ReadFile(filepath.Join(dataDir, file.Name()))
if err != nil {
return fmt.Errorf("read test case file %s: %w", file.Name(), err)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same thing with the early return on errors here. Should be collected and skipped.

Comment thread policy-test/main.go Outdated
}
var tc []TestCase
if err := json.Unmarshal(fileData, &tc); err != nil {
return fmt.Errorf("unmarshal test case %s: %w", file.Name(), err)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

Comment thread policy-test/main.go Outdated

p, err := NewOPAPolicy(policy)
if err != nil {
return fmt.Errorf("create OPA policy: %w", err)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here too

Comment thread policy-test/main.go
}

var errs []error
for _, file := range dirs {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may be paranoid, but: wdyt about counting testcases and erroring also when no those are 0? right now, if someone e.g. moves the files to a subdir, the test succeeds, right?

Comment thread policy-test/rego.go Outdated
}

if len(res) == 0 {
return false, "", fmt.Errorf("no rule %s found in policy", query)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we should also return prints from this function? SO in the error case, we can debug the error directly?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this particular case (i.e., len(res) = 0), there are no prints afaik. But in general I agree to add the prints to this block when checking the result length, and only if it is to catch regressions.

@davidweisse
davidweisse force-pushed the dav/policy-test-suite branch from ecd4a47 to 7c9e278 Compare August 19, 2026 11:12
@davidweisse
davidweisse requested a review from charludo August 19, 2026 12:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no changelog PRs not listed in the release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants