From a34c5672bcc549d06c8bce2d2ee49df1ae47241c Mon Sep 17 00:00:00 2001 From: Stephan Renatus Date: Thu, 22 Jul 2021 18:08:00 +0200 Subject: [PATCH] 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 --- cmd/eval.go | 3 +- cmd/eval_test.go | 39 ++---------------------- cmd/eval_wasmtarget_test.go | 59 +++++++++++++++++++++++++++++++++++++ rego/rego.go | 7 ++++- 4 files changed, 69 insertions(+), 39 deletions(-) create mode 100644 cmd/eval_wasmtarget_test.go diff --git a/cmd/eval.go b/cmd/eval.go index 1f9fcbb1a6..7db8cdd32b 100644 --- a/cmd/eval.go +++ b/cmd/eval.go @@ -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 { diff --git a/cmd/eval_test.go b/cmd/eval_test.go index ba38f047fa..c93e1e8938 100755 --- a/cmd/eval_test.go +++ b/cmd/eval_test.go @@ -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") } diff --git a/cmd/eval_wasmtarget_test.go b/cmd/eval_wasmtarget_test.go new file mode 100644 index 0000000000..85e74293ca --- /dev/null +++ b/cmd/eval_wasmtarget_test.go @@ -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) + } + }) + } +} diff --git a/rego/rego.go b/rego/rego.go index 5f530e6669..aef58b0caf 100644 --- a/rego/rego.go +++ b/rego/rego.go @@ -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, })