Skip to content

Commit

Permalink
feat: reuse compiled expressions (kyverno#478)
Browse files Browse the repository at this point in the history
* feat: reuse compiled expressions

Signed-off-by: Charles-Edouard Brétéché <[email protected]>

* todo

Signed-off-by: Charles-Edouard Brétéché <[email protected]>

* path

Signed-off-by: Charles-Edouard Brétéché <[email protected]>

* ast

Signed-off-by: Charles-Edouard Brétéché <[email protected]>

* parsing

Signed-off-by: Charles-Edouard Brétéché <[email protected]>

---------

Signed-off-by: Charles-Edouard Brétéché <[email protected]>
  • Loading branch information
eddycharly authored Sep 18, 2024
1 parent eed05d1 commit 95fcfef
Show file tree
Hide file tree
Showing 7 changed files with 213 additions and 148 deletions.
43 changes: 19 additions & 24 deletions pkg/engine/assert/assert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,20 @@ import (
)

func TestAssert(t *testing.T) {
type args struct {
assertion Assertion
tests := []struct {
name string
assertion any
value any
bindings binding.Bindings
}
tests := []struct {
name string
args args
want field.ErrorList
wantErr bool
want field.ErrorList
wantErr bool
}{{
name: "nil vs empty object",
args: args{
assertion: Parse(context.TODO(), map[string]any{
"foo": map[string]any{},
}),
value: map[string]any{
"foo": nil,
},
assertion: map[string]any{
"foo": map[string]any{},
},
value: map[string]any{
"foo": nil,
},
want: field.ErrorList{
&field.Error{
Expand All @@ -40,22 +35,22 @@ func TestAssert(t *testing.T) {
wantErr: false,
}, {
name: "not nil vs empty object",
args: args{
assertion: Parse(context.TODO(), map[string]any{
"foo": map[string]any{},
}),
value: map[string]any{
"foo": map[string]any{
"bar": 42,
},
assertion: map[string]any{
"foo": map[string]any{},
},
value: map[string]any{
"foo": map[string]any{
"bar": 42,
},
},
want: nil,
wantErr: false,
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := Assert(context.TODO(), nil, tt.args.assertion, tt.args.value, tt.args.bindings)
parsed, err := Parse(context.TODO(), nil, tt.assertion)
tassert.NoError(t, err)
got, err := Assert(context.TODO(), nil, parsed, tt.value, tt.bindings)
if tt.wantErr {
tassert.Error(t, err)
} else {
Expand Down
12 changes: 11 additions & 1 deletion pkg/engine/assert/expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import (
"context"
"reflect"
"regexp"
"sync"

"github.com/jmespath-community/go-jmespath/pkg/parsing"
reflectutils "github.com/kyverno/kyverno-json/pkg/utils/reflect"
)

Expand All @@ -21,6 +23,7 @@ type expression struct {
statement string
binding string
engine string
ast func() (parsing.ASTNode, error)
}

func parseExpressionRegex(_ context.Context, in string) *expression {
Expand Down Expand Up @@ -61,5 +64,12 @@ func parseExpression(ctx context.Context, value any) *expression {
if reflectutils.GetKind(value) != reflect.String {
return nil
}
return parseExpressionRegex(ctx, reflect.ValueOf(value).String())
exp := parseExpressionRegex(ctx, reflect.ValueOf(value).String())
if exp != nil && exp.engine == "jp" {
exp.ast = sync.OnceValues(func() (parsing.ASTNode, error) {
parser := parsing.NewParser()
return parser.Parse(exp.statement)
})
}
return exp
}
Loading

0 comments on commit 95fcfef

Please sign in to comment.