Files
buildx/policy/utils_test.go
T
Tonis Tiigi 1c4a436a0d policy: match parent unknown keys in collectUnknowns
Allow child refs from partial evaluation to match allowed parent keys on
path boundaries and return canonical unknowns for metadata resolution.

Add tests for parent-child matching and boundary safety cases.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2026-02-26 17:12:18 -08:00

139 lines
4.2 KiB
Go

package policy
import (
"testing"
"github.com/open-policy-agent/opa/v1/ast"
"github.com/stretchr/testify/require"
)
func TestTrimKey(t *testing.T) {
tests := []struct {
in string
out string
}{
// no separators
{"git", "git"},
{"foo", "foo"},
// one separator → stays as-is
{"git.tag", "git.tag"},
{"git[tag", "git[tag"},
{"input.git.tag", "git.tag"},
{"input.git[tag", "git[tag"},
// multiple separators → cut before second one
{"git.tag.author", "git.tag"},
{"git.tag.author.email", "git.tag"},
{"git.tag[0][1]", "git.tag"},
{"git.tag[0]", "git.tag"},
{"input.git.tag.author", "git.tag"},
{"input.git.tag[0]", "git.tag"},
{"input.image.provenance.materials[0].image.hasProvenance", "image.provenance.materials[0].image.hasProvenance"},
{"image.provenance.materials[0].image.labels", "image.provenance.materials[0].image.labels"},
{"input.image.provenance.materials[0].image.provenance.predicateType", "image.provenance.materials[0].image.provenance.predicateType"},
{"input.image.provenance.materials[0].image.signatures[0].signer.certificateIssuer", "image.provenance.materials[0].image.signatures[0].signer.certificateIssuer"},
{"input.image.provenance.materials[10].image.hasProvenance", "image.provenance.materials[10].image.hasProvenance"},
{"a.b.c", "a.b"},
}
for _, tt := range tests {
t.Run(tt.in, func(t *testing.T) {
require.Equal(t, tt.out, trimKey(tt.in))
})
}
}
func TestCollectUnknowns(t *testing.T) {
mod, err := ast.ParseModule("x.rego", `
package x
p if {
input.git.tag[0].author == "a"
input.image.signatures[_].signer.certificateIssuer != ""
input.image.provenance.materials[0].image.hasProvenance
data.foo.bar == 1
}
`)
require.NoError(t, err)
all := collectUnknowns([]*ast.Module{mod}, nil)
require.ElementsMatch(t, []string{"git.tag", "image.signatures", "image.provenance.materials[0].image.hasProvenance"}, all)
filtered := collectUnknowns([]*ast.Module{mod}, []string{"input.image.signatures", "input.image.provenance.materials[0].image.hasProvenance"})
require.ElementsMatch(t, []string{"image.signatures", "image.provenance.materials[0].image.hasProvenance"}, filtered)
}
func TestCollectUnknownsParentAllowedMatchesChildRef(t *testing.T) {
mod, err := ast.ParseModule("x.rego", `
package x
p if {
input.image.provenance.materials[0].image.provenance.predicateType != ""
input.image.provenance.materials[0].image.signatures[0].signer.certificateIssuer != ""
input.image.provenance.materials[0].git.tag.name != ""
input.foo.bar != ""
input.image.provenance.materials[10].image.hasProvenance
}
`)
require.NoError(t, err)
filtered := collectUnknowns([]*ast.Module{mod}, []string{
"input.image.provenance.materials[0].image.provenance",
"input.image.provenance.materials[0].image.signatures",
"input.image.provenance.materials[0].git.tag",
"input.foo.b",
"input.image.provenance.materials[1].image",
})
require.ElementsMatch(t, []string{
"image.provenance.materials[0].image.provenance",
"image.provenance.materials[0].image.signatures",
"image.provenance.materials[0].git.tag",
}, filtered)
}
func TestMatchAllowedOrParentBoundary(t *testing.T) {
allowed := map[string]struct{}{
"foo.b": {},
"image.provenance.materials[1].image": {},
}
_, ok := matchAllowedOrParent("foo.bar", allowed)
require.False(t, ok)
_, ok = matchAllowedOrParent("image.provenance.materials[10].image.hasProvenance", allowed)
require.False(t, ok)
}
func TestRuntimeUnknownInputRefs(t *testing.T) {
require.Nil(t, runtimeUnknownInputRefs(nil))
require.Nil(t, runtimeUnknownInputRefs(&state{}))
st := &state{
Unknowns: map[string]struct{}{
funcVerifyGitSignature: {},
funcArtifactAttestation: {},
funcGithubAttestation: {},
},
}
require.Equal(t, []string{"git.commit", "http.checksum"}, runtimeUnknownInputRefs(st))
}
func TestMissingInputRefsWithRuntimeUnknowns(t *testing.T) {
mod, err := ast.ParseModule("x.rego", `
package x
p if {
input.git.ref != ""
}
`)
require.NoError(t, err)
in := &Input{
Git: &Git{
Ref: "refs/heads/main",
},
}
missing := missingInputRefs([]*ast.Module{mod}, in, []string{"git.commit"})
require.Equal(t, []string{"git.commit"}, missing)
}