mirror of
https://github.com/open-policy-agent/opa.git
synced 2026-08-12 19:32:48 -06:00
profiler: Group expressions with missing locations
Previously the profiler would panic if it encountered an expression with no location info. This change groups such expressions by giving them a fake location so that their evaluation results can be captured. Signed-off-by: Ashutosh Narkar <anarkar4387@gmail.com>
This commit is contained in:
@@ -130,6 +130,10 @@ func (p *Profiler) Trace(event *topdown.Event) {
|
||||
}
|
||||
|
||||
func (p *Profiler) processExpr(expr *ast.Expr, eventType topdown.Op) {
|
||||
if expr.Location == nil {
|
||||
// add fake location to group expressions without a location
|
||||
expr.Location = ast.NewLocation([]byte("???"), "", 0, 0)
|
||||
}
|
||||
|
||||
// set the active timer on the first expression
|
||||
if p.activeTimer.IsZero() {
|
||||
|
||||
@@ -410,3 +410,72 @@ baz {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestProfilerWithPartialEval(t *testing.T) {
|
||||
profiler := New()
|
||||
|
||||
module := `package test
|
||||
|
||||
default foo = false
|
||||
|
||||
foo = true {
|
||||
op = allowed_operations[_]
|
||||
input.method = op.method
|
||||
input.resource = op.resource
|
||||
}
|
||||
|
||||
allowed_operations = [
|
||||
{"method": "PUT", "resource": "policy"},
|
||||
]`
|
||||
|
||||
_, err := ast.ParseModule("test.rego", module)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
pq, err := rego.New(
|
||||
rego.Module("test.rego", module),
|
||||
rego.Query("data.test.foo"),
|
||||
).PrepareForEval(ctx, rego.WithPartialEval())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = pq.Eval(ctx, rego.EvalTracer(profiler))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
report := profiler.ReportByFile()
|
||||
|
||||
if len(report.Files) != 1 {
|
||||
t.Fatalf("Expected file report length to be 1 instead got %v", len(report.Files))
|
||||
}
|
||||
|
||||
fr := report.Files[""]
|
||||
|
||||
if len(fr.Result) != 2 {
|
||||
t.Fatalf("Expected 2 results for file but instead got %v", len(fr.Result))
|
||||
}
|
||||
|
||||
expectedNumEval := []int{2, 1}
|
||||
expectedNumRedo := []int{2, 1}
|
||||
expectedLocation := []string{"???", "data.partial.__result__"}
|
||||
|
||||
for idx, actualExprStat := range fr.Result {
|
||||
if actualExprStat.NumEval != expectedNumEval[idx] {
|
||||
t.Fatalf("Index %v: Expected number of evals %v but got %v", idx, expectedNumEval[idx], actualExprStat.NumEval)
|
||||
}
|
||||
|
||||
if actualExprStat.NumRedo != expectedNumRedo[idx] {
|
||||
t.Fatalf("Index %v: Expected number of redos %v but got %v", idx, expectedNumRedo[idx], actualExprStat.NumRedo)
|
||||
}
|
||||
|
||||
if string(actualExprStat.Location.Text) != expectedLocation[idx] {
|
||||
t.Fatalf("Index %v: Expected location %v but got %v", idx, expectedLocation[idx], string(actualExprStat.Location.Text))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user