Files
releases/cmd/test_test.go
T
Patrick East b45ab28375 rego: Plumb the newer QueryTracer through Rego API's
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>
2020-07-15 12:01:12 -07:00

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
}