mirror of
https://github.com/open-policy-agent/opa.git
synced 2026-08-12 19:32:48 -06:00
f77322b3fb
Go 1.23 is no longer supported as per Go release policy. Changes: - Use Go v1.24.6 as the project SDK requirement - Apply lint fixes for Go 1.24 - Fix "non-constant format string in call" issues as seen in CI. Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>
201 lines
3.7 KiB
Go
201 lines
3.7 KiB
Go
// Copyright 2019 The OPA Authors. All rights reserved.
|
|
// Use of this source code is governed by an Apache2
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package lineage
|
|
|
|
import (
|
|
"bytes"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/open-policy-agent/opa/v1/ast"
|
|
"github.com/open-policy-agent/opa/v1/topdown"
|
|
)
|
|
|
|
func TestFilter(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
note string
|
|
module string
|
|
exp string
|
|
}{
|
|
{
|
|
note: "lineage",
|
|
module: `package test
|
|
import rego.v1
|
|
|
|
p if { q }
|
|
q if { r }
|
|
r if { trace("R") }`,
|
|
exp: `
|
|
Enter data.test.p = x
|
|
| Enter data.test.p
|
|
| | Enter data.test.q
|
|
| | | Enter data.test.r
|
|
| | | | Note "R"`,
|
|
},
|
|
{
|
|
note: "conjunction",
|
|
module: `package test
|
|
import rego.v1
|
|
|
|
p if { trace("P1"); trace("P2") }`,
|
|
exp: `
|
|
Enter data.test.p = x
|
|
| Enter data.test.p
|
|
| | Note "P1"
|
|
| | Note "P2"`,
|
|
},
|
|
{
|
|
note: "conjunction (multiple enters)",
|
|
module: `package test
|
|
import rego.v1
|
|
|
|
p if { q; r }
|
|
q if { trace("Q") }
|
|
r if { trace("Q") }
|
|
`,
|
|
exp: `
|
|
Enter data.test.p = x
|
|
| Enter data.test.p
|
|
| | Enter data.test.q
|
|
| | | Note "Q"
|
|
| | Enter data.test.r
|
|
| | | Note "Q"`,
|
|
},
|
|
{
|
|
note: "disjunction",
|
|
module: `package test
|
|
import rego.v1
|
|
|
|
p = x if { x := true; trace("P1") }
|
|
p = x if { x := true; false }
|
|
p = x if { x := true; trace("P2") }
|
|
`,
|
|
exp: `
|
|
Enter data.test.p = x
|
|
| Enter data.test.p
|
|
| | Note "P1"
|
|
Redo data.test.p = x
|
|
| Enter data.test.p
|
|
| | Note "P2"`,
|
|
},
|
|
{
|
|
note: "disjunction (failure)",
|
|
module: `package test
|
|
import rego.v1
|
|
|
|
p = x if { x := true; trace("P1") }
|
|
p = x if { x := true; trace("P2"); false }
|
|
p = x if { x := true; trace("P3") }
|
|
`,
|
|
exp: `
|
|
Enter data.test.p = x
|
|
| Enter data.test.p
|
|
| | Note "P1"
|
|
Redo data.test.p = x
|
|
| Enter data.test.p
|
|
| | Note "P2"
|
|
| Enter data.test.p
|
|
| | Note "P3"`,
|
|
},
|
|
{
|
|
note: "disjunction (iteration)",
|
|
module: `package test
|
|
import rego.v1
|
|
|
|
q contains 1
|
|
q contains 2
|
|
p if { q[x]; trace(sprintf("x=%d", [x])) }`,
|
|
exp: `
|
|
Enter data.test.p = x
|
|
| Enter data.test.p
|
|
| | Note "x=1"
|
|
`,
|
|
},
|
|
{
|
|
note: "parent child",
|
|
module: `package test
|
|
import rego.v1
|
|
|
|
p if { trace("P"); q }
|
|
q if { trace("Q") }`,
|
|
exp: `
|
|
Enter data.test.p = x
|
|
| Enter data.test.p
|
|
| | Note "P"
|
|
| | Enter data.test.q
|
|
| | | Note "Q"`,
|
|
},
|
|
{
|
|
note: "negation",
|
|
module: `package test
|
|
import rego.v1
|
|
|
|
p if { not q }
|
|
q = false if { trace("Q") }`,
|
|
exp: `
|
|
Enter data.test.p = x
|
|
| Enter data.test.p
|
|
| | Enter data.test.q
|
|
| | | Enter data.test.q
|
|
| | | | Note "Q"`,
|
|
},
|
|
{
|
|
note: "fail",
|
|
module: `package test
|
|
import rego.v1
|
|
|
|
p if { not q }
|
|
q if { trace("P"); 1 = 2 }`,
|
|
exp: `
|
|
Enter data.test.p = x
|
|
| Enter data.test.p
|
|
| | Enter data.test.q
|
|
| | | Enter data.test.q
|
|
| | | | Note "P"`,
|
|
},
|
|
{
|
|
note: "comprehensions",
|
|
module: `package test
|
|
import rego.v1
|
|
|
|
p if { [true | true; trace("X")] }`,
|
|
exp: `
|
|
Enter data.test.p = x
|
|
| Enter data.test.p
|
|
| | Enter true; trace("X")
|
|
| | | Note "X"`,
|
|
},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
t.Run(tc.note, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
buf := topdown.NewBufferTracer()
|
|
compiler := ast.MustCompileModules(map[string]string{
|
|
"test.rego": tc.module,
|
|
})
|
|
query := topdown.NewQuery(ast.MustParseBody("data.test.p = x")).WithCompiler(compiler).WithTracer(buf)
|
|
rs, err := query.Run(t.Context())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
} else if len(rs) != 1 || !rs[0][ast.Var("x")].Equal(ast.BooleanTerm(true)) {
|
|
t.Fatalf("Unexpected result: %v", rs)
|
|
}
|
|
|
|
filtered := Notes(*buf)
|
|
|
|
buffer := bytes.NewBuffer(nil)
|
|
topdown.PrettyTrace(buffer, filtered)
|
|
|
|
if strings.TrimSpace(buffer.String()) != strings.TrimSpace(tc.exp) {
|
|
t.Fatalf("Expected:\n\n%v\n\nGot:\n\n%v", tc.exp, buffer.String())
|
|
}
|
|
})
|
|
}
|
|
}
|