cmd/eval: pass parsed input into rego package for wasm target if present (#3669)

This was introduced in #3624: turns out the eval command's code only
passed parsedInput into the rego package, and that only looked at
rawInput when feeding it into the wasm engine.

The approach taken here is to make the rego package more robust: It
should do the right thing if parsedInput is provided for an eval
under the wasm target: the parsing work was already done, let's not
dischard it.

Fixes #3666.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
This commit is contained in:
Stephan Renatus
2021-07-22 18:08:00 +02:00
committed by GitHub
parent ef716a3142
commit a34c5672bc
4 changed files with 69 additions and 39 deletions
+2 -1
View File
@@ -465,7 +465,8 @@ func setupEval(args []string, params evalCommandParams) (*evalContext, error) {
inputBytes, err := readInputBytes(params)
if err != nil {
return nil, err
} else if inputBytes != nil {
}
if inputBytes != nil {
var input interface{}
err := util.Unmarshal(inputBytes, &input)
if err != nil {
+2 -37
View File
@@ -119,7 +119,7 @@ p = 1`,
})
}
func testEvalWithInputFile(t *testing.T, input string, query string) error {
func testEvalWithInputFile(t *testing.T, input string, query string, params evalCommandParams) error {
files := map[string]string{
"input.json": input,
}
@@ -127,7 +127,6 @@ func testEvalWithInputFile(t *testing.T, input string, query string) error {
var err error
test.WithTempFS(files, func(path string) {
params := newEvalCommandParams()
params.inputPath = filepath.Join(path, "input.json")
var buf bytes.Buffer
@@ -162,44 +161,10 @@ func testEvalWithInputFile(t *testing.T, input string, query string) error {
return err
}
func TestEvalWithJSONInputFile(t *testing.T) {
input := `{
"foo": "a",
"b": [
{
"a": 1,
"b": [1, 2, 3],
"c": null
}
]
}`
query := "input.b[0].a == 1"
err := testEvalWithInputFile(t, input, query)
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
}
func TestEvalWithYAMLInputFile(t *testing.T) {
input := `
foo: a
b:
- a: 1
b: [1, 2, 3]
c:
`
query := "input.b[0].a == 1"
err := testEvalWithInputFile(t, input, query)
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
}
func TestEvalWithInvalidInputFile(t *testing.T) {
input := `{badjson`
query := "input.b[0].a == 1"
err := testEvalWithInputFile(t, input, query)
err := testEvalWithInputFile(t, input, query, newEvalCommandParams())
if err == nil {
t.Fatalf("expected error but err == nil")
}
+59
View File
@@ -0,0 +1,59 @@
// Copyright 2021 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.
// +build opa_wasm
package cmd
import (
"testing"
)
func TestEvalWithJSONInputFile(t *testing.T) {
input := `{
"foo": "a",
"b": [
{
"a": 1,
"b": [1, 2, 3],
"c": null
}
]
}`
query := "input.b[0].a == 1"
for _, tgt := range []string{"rego", "wasm"} {
t.Run(tgt, func(t *testing.T) {
params := newEvalCommandParams()
params.target.Set(tgt)
err := testEvalWithInputFile(t, input, query, params)
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
})
}
}
func TestEvalWithYAMLInputFile(t *testing.T) {
input := `
foo: a
b:
- a: 1
b: [1, 2, 3]
c:
`
query := "input.b[0].a == 1"
for _, tgt := range []string{"rego", "wasm"} {
t.Run(tgt, func(t *testing.T) {
params := newEvalCommandParams()
params.target.Set(tgt)
err := testEvalWithInputFile(t, input, query, params)
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
})
}
}
+6 -1
View File
@@ -1933,9 +1933,14 @@ func (r *Rego) eval(ctx context.Context, ectx *EvalContext) (ResultSet, error) {
func (r *Rego) evalWasm(ctx context.Context, ectx *EvalContext) (ResultSet, error) {
input := ectx.rawInput
if ectx.parsedInput != nil {
i := interface{}(ectx.parsedInput)
input = &i
}
result, err := r.opa.Eval(ctx, opa.EvalOpts{
Metrics: r.metrics,
Input: ectx.rawInput,
Input: input,
Time: ectx.time,
Seed: ectx.seed,
})