mirror of
https://github.com/open-policy-agent/opa.git
synced 2026-08-12 19:32:48 -06:00
b45ab28375
This will deprecate the older API's that used the `topdown.Tracer` in favor of the newer `topdown.QueryTracer` interface. Usages of the old API have been swapped, although some of the testing is left with them to ensure we still support them (until we remove the deprecated API). Signed-off-by: Patrick East <east.patrick@gmail.com>
193 lines
4.4 KiB
Go
193 lines
4.4 KiB
Go
package cmd
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/open-policy-agent/opa/rego"
|
|
"github.com/open-policy-agent/opa/topdown"
|
|
)
|
|
|
|
func TestFilterTraceDefault(t *testing.T) {
|
|
p := newTestCommandParams()
|
|
p.verbose = false
|
|
expected := `Enter data.testing.test_p = _
|
|
| Enter data.testing.test_p
|
|
| | Enter data.testing.p
|
|
| | | Enter data.testing.q
|
|
| | | | Enter data.testing.r
|
|
| | | | | Fail x = data.x
|
|
| | | | Fail data.testing.r[x]
|
|
| | | Fail data.testing.q.foo
|
|
| | Fail data.testing.p with data.x as "bar"
|
|
| Fail data.testing.test_p = _
|
|
`
|
|
verifyFilteredTrace(t, p, expected)
|
|
}
|
|
|
|
func TestFilterTraceVerbose(t *testing.T) {
|
|
p := newTestCommandParams()
|
|
p.verbose = true
|
|
expected := `Enter data.testing.test_p = _
|
|
| Enter data.testing.test_p
|
|
| | Enter data.testing.p
|
|
| | | Note "test test"
|
|
| | | Enter data.testing.q
|
|
| | | | Note "got this far"
|
|
| | | | Enter data.testing.r
|
|
| | | | | Note "got this far2"
|
|
| | | | | Fail x = data.x
|
|
| | | | Fail data.testing.r[x]
|
|
| | | Fail data.testing.q.foo
|
|
| | Fail data.testing.p with data.x as "bar"
|
|
| Fail data.testing.test_p = _
|
|
`
|
|
verifyFilteredTrace(t, p, expected)
|
|
}
|
|
|
|
func TestFilterTraceExplainFails(t *testing.T) {
|
|
p := newTestCommandParams()
|
|
p.explain.Set(explainModeFails)
|
|
expected := `Enter data.testing.test_p = _
|
|
| Enter data.testing.test_p
|
|
| | Enter data.testing.p
|
|
| | | Enter data.testing.q
|
|
| | | | Enter data.testing.r
|
|
| | | | | Fail x = data.x
|
|
| | | | Fail data.testing.r[x]
|
|
| | | Fail data.testing.q.foo
|
|
| | Fail data.testing.p with data.x as "bar"
|
|
| Fail data.testing.test_p = _
|
|
`
|
|
verifyFilteredTrace(t, p, expected)
|
|
}
|
|
|
|
func TestFilterTraceExplainNotes(t *testing.T) {
|
|
p := newTestCommandParams()
|
|
p.explain.Set(explainModeNotes)
|
|
expected := `Enter data.testing.test_p = _
|
|
| Enter data.testing.test_p
|
|
| | Enter data.testing.p
|
|
| | | Note "test test"
|
|
| | | Enter data.testing.q
|
|
| | | | Note "got this far"
|
|
| | | | Enter data.testing.r
|
|
| | | | | Note "got this far2"
|
|
`
|
|
verifyFilteredTrace(t, p, expected)
|
|
}
|
|
|
|
func TestFilterTraceExplainFull(t *testing.T) {
|
|
p := newTestCommandParams()
|
|
p.explain.Set(explainModeFull)
|
|
expected := `Enter data.testing.test_p = _
|
|
| Eval data.testing.test_p = _
|
|
| Index data.testing.test_p = _ (matched 1 rule)
|
|
| Enter data.testing.test_p
|
|
| | Eval data.testing.p with data.x as "bar"
|
|
| | Index data.testing.p with data.x as "bar" (matched 1 rule)
|
|
| | Enter data.testing.p
|
|
| | | Eval data.testing.x
|
|
| | | Index data.testing.x (matched 1 rule)
|
|
| | | Enter data.testing.x
|
|
| | | | Eval data.testing.y
|
|
| | | | Index data.testing.y (matched 1 rule)
|
|
| | | | Enter data.testing.y
|
|
| | | | | Eval true
|
|
| | | | | Exit data.testing.y
|
|
| | | | Exit data.testing.x
|
|
| | | Eval trace("test test")
|
|
| | | Note "test test"
|
|
| | | Eval data.testing.q.foo
|
|
| | | Index data.testing.q.foo (matched 1 rule)
|
|
| | | Enter data.testing.q
|
|
| | | | Eval trace("got this far")
|
|
| | | | Note "got this far"
|
|
| | | | Eval data.testing.r[x]
|
|
| | | | Index data.testing.r[__local0__] (matched 1 rule)
|
|
| | | | Enter data.testing.r
|
|
| | | | | Eval trace("got this far2")
|
|
| | | | | Note "got this far2"
|
|
| | | | | Eval x = data.x
|
|
| | | | | Fail x = data.x
|
|
| | | | | Redo trace("got this far2")
|
|
| | | | Fail data.testing.r[x]
|
|
| | | | Redo trace("got this far")
|
|
| | | Fail data.testing.q.foo
|
|
| | | Redo trace("test test")
|
|
| | | Redo data.testing.x
|
|
| | | Redo data.testing.x
|
|
| | | | Redo data.testing.y
|
|
| | | | Redo data.testing.y
|
|
| | | | | Redo true
|
|
| | Fail data.testing.p with data.x as "bar"
|
|
| Fail data.testing.test_p = _
|
|
`
|
|
verifyFilteredTrace(t, p, expected)
|
|
}
|
|
|
|
func verifyFilteredTrace(t *testing.T, params *testCommandParams, expected string) {
|
|
filtered := filterTrace(params, failTrace(t))
|
|
|
|
var buff bytes.Buffer
|
|
topdown.PrettyTrace(&buff, filtered)
|
|
actual := buff.String()
|
|
|
|
if actual != expected {
|
|
t.Fatalf("Expected:\n\n%s\n\nGot:\n\n%s\n\n", expected, actual)
|
|
}
|
|
}
|
|
|
|
func failTrace(t *testing.T) []*topdown.Event {
|
|
t.Helper()
|
|
mod := `
|
|
package testing
|
|
|
|
p {
|
|
x # Always true
|
|
trace("test test")
|
|
q["foo"]
|
|
}
|
|
|
|
x {
|
|
y
|
|
}
|
|
|
|
y {
|
|
true
|
|
}
|
|
|
|
q[x] {
|
|
some x
|
|
trace("got this far")
|
|
r[x]
|
|
trace("got this far1")
|
|
}
|
|
|
|
r[x] {
|
|
trace("got this far2")
|
|
x := data.x
|
|
}
|
|
|
|
test_p {
|
|
p with data.x as "bar"
|
|
}
|
|
`
|
|
|
|
tracer := topdown.NewBufferTracer()
|
|
|
|
_, err := rego.New(
|
|
rego.Module("test.rego", mod),
|
|
rego.Trace(true),
|
|
rego.QueryTracer(tracer),
|
|
rego.Query("data.testing.test_p"),
|
|
).Eval(context.Background())
|
|
|
|
if err != nil {
|
|
t.Fatalf("Unexpected error: %s", err)
|
|
}
|
|
|
|
return *tracer
|
|
}
|