From 5189734374197995e887aa18b8ce22f1beeb8a86 Mon Sep 17 00:00:00 2001 From: Raj Nishtala Date: Wed, 27 Sep 2023 16:34:24 -0400 Subject: [PATCH] Adding tests that show the change in the expected result without the optional hash function argument --- .chloggen/ottl-replace-pattern.yaml | 7 +- pkg/ottl/functions.go | 16 ++-- .../ottlfuncs/func_replace_all_matches.go | 14 ++- .../func_replace_all_matches_test.go | 48 +++++++---- .../ottlfuncs/func_replace_all_patterns.go | 14 ++- .../func_replace_all_patterns_test.go | 86 +++++++++---------- pkg/ottl/ottlfuncs/func_replace_match.go | 14 ++- pkg/ottl/ottlfuncs/func_replace_match_test.go | 44 ++++++---- pkg/ottl/ottlfuncs/func_replace_pattern.go | 14 ++- .../ottlfuncs/func_replace_pattern_test.go | 60 +++++++------ 10 files changed, 162 insertions(+), 155 deletions(-) diff --git a/.chloggen/ottl-replace-pattern.yaml b/.chloggen/ottl-replace-pattern.yaml index 3ae912e62f7a..a2a1c29ab06b 100755 --- a/.chloggen/ottl-replace-pattern.yaml +++ b/.chloggen/ottl-replace-pattern.yaml @@ -16,8 +16,11 @@ issues: [27235] # These lines will be padded with 2 spaces and then inserted directly into the document. # Use pipe (|) for multiline entries. subtext: | - The `ottl.Optional` type can now be used in a converter's `Arguments` struct - to indicate that a parameter is optional. Hashing functions are passed as optional parameters to converters. + Hashing functions are passed as optional arguments to the following converters: + - `replace_pattern` + - `replace_all_patterns` + - `replace_match` + - `replace_all_matches` # If your change doesn't affect end users or the exported elements of any package, # you should instead start your pull request title with [chore] or use the "Skip Changelog" label. diff --git a/pkg/ottl/functions.go b/pkg/ottl/functions.go index 409a0ee7d43d..37aab7e1c7ca 100644 --- a/pkg/ottl/functions.go +++ b/pkg/ottl/functions.go @@ -381,25 +381,25 @@ type optionalManager interface { } type Optional[T any] struct { - Val T - HasValue bool + val T + hasValue bool } // This is called only by reflection. // nolint:unused func (o Optional[T]) set(val any) reflect.Value { return reflect.ValueOf(Optional[T]{ - Val: val.(T), - HasValue: true, + val: val.(T), + hasValue: true, }) } func (o Optional[T]) IsEmpty() bool { - return !o.HasValue + return !o.hasValue } func (o Optional[T]) Get() T { - return o.Val + return o.val } func (o Optional[T]) get() reflect.Value { @@ -414,7 +414,7 @@ func (o Optional[T]) get() reflect.Value { // OTTL functions. func NewTestingOptional[T any](val T) Optional[T] { return Optional[T]{ - Val: val, - HasValue: true, + val: val, + hasValue: true, } } diff --git a/pkg/ottl/ottlfuncs/func_replace_all_matches.go b/pkg/ottl/ottlfuncs/func_replace_all_matches.go index 7535b7aa0d1c..c0c69295daf8 100644 --- a/pkg/ottl/ottlfuncs/func_replace_all_matches.go +++ b/pkg/ottl/ottlfuncs/func_replace_all_matches.go @@ -37,8 +37,6 @@ func createReplaceAllMatchesFunction[K any](_ ottl.FunctionContext, oArgs ottl.A func replaceAllMatches[K any](target ottl.PMapGetter[K], pattern string, replacement ottl.StringGetter[K], fn ottl.Optional[ottl.FunctionGetter[K]]) (ottl.ExprFunc[K], error) { glob, err := glob.Compile(pattern) var replacementVal string - var replacementExpr ottl.Expr[K] - var replacementValRaw interface{} if err != nil { return nil, fmt.Errorf("the pattern supplied to replace_match is not a valid pattern: %w", err) } @@ -54,13 +52,13 @@ func replaceAllMatches[K any](target ottl.PMapGetter[K], pattern string, replace } } else { fnVal := fn.Get() - replacementExpr, err = fnVal.Get(&FuncArgs[K]{Input: replacement}) - if err != nil { - return nil, err + replacementExpr, errNew := fnVal.Get(&FuncArgs[K]{Input: replacement}) + if errNew != nil { + return nil, errNew } - replacementValRaw, err = replacementExpr.Eval(ctx, tCtx) - if err != nil { - return nil, err + replacementValRaw, errNew := replacementExpr.Eval(ctx, tCtx) + if errNew != nil { + return nil, errNew } replacementVal = replacementValRaw.(string) } diff --git a/pkg/ottl/ottlfuncs/func_replace_all_matches_test.go b/pkg/ottl/ottlfuncs/func_replace_all_matches_test.go index 694a296b1a49..eea94b2a53c5 100644 --- a/pkg/ottl/ottlfuncs/func_replace_all_matches_test.go +++ b/pkg/ottl/ottlfuncs/func_replace_all_matches_test.go @@ -20,6 +20,14 @@ func Test_replaceAllMatches(t *testing.T) { input.PutStr("test2", "hello") input.PutStr("test3", "goodbye") + ottlValue := ottl.StandardFunctionGetter[pcommon.Map]{ + FCtx: ottl.FunctionContext{ + Set: componenttest.NewNopTelemetrySettings(), + }, + Fact: StandardConverters[pcommon.Map]()["SHA256"], + } + optionalArg := ottl.NewTestingOptional[ottl.FunctionGetter[pcommon.Map]](ottlValue) + target := &ottl.StandardPMapGetter[pcommon.Map]{ Getter: func(ctx context.Context, tCtx pcommon.Map) (interface{}, error) { return tCtx, nil @@ -35,7 +43,7 @@ func Test_replaceAllMatches(t *testing.T) { want func(pcommon.Map) }{ { - name: "replace only matches", + name: "replace only matches (with hash function)", target: target, pattern: "hello*", replacement: ottl.StandardStringGetter[pcommon.Map]{ @@ -43,21 +51,29 @@ func Test_replaceAllMatches(t *testing.T) { return "hello {universe}", nil }, }, - function: ottl.Optional[ottl.FunctionGetter[pcommon.Map]]{ - Val: ottl.StandardFunctionGetter[pcommon.Map]{ - FCtx: ottl.FunctionContext{ - Set: componenttest.NewNopTelemetrySettings(), - }, - Fact: StandardConverters[pcommon.Map]()["SHA256"], - }, - HasValue: true, - }, + function: optionalArg, want: func(expectedMap pcommon.Map) { expectedMap.PutStr("test", "4804d6b7f03268e33f78c484977f3d81771220df07cc6aac4ad4868102141fad") expectedMap.PutStr("test2", "4804d6b7f03268e33f78c484977f3d81771220df07cc6aac4ad4868102141fad") expectedMap.PutStr("test3", "goodbye") }, }, + { + name: "replace only matches", + target: target, + pattern: "hello*", + replacement: ottl.StandardStringGetter[pcommon.Map]{ + Getter: func(context.Context, pcommon.Map) (interface{}, error) { + return "hello {universe}", nil + }, + }, + function: ottl.Optional[ottl.FunctionGetter[pcommon.Map]]{}, + want: func(expectedMap pcommon.Map) { + expectedMap.PutStr("test", "hello {universe}") + expectedMap.PutStr("test2", "hello {universe}") + expectedMap.PutStr("test3", "goodbye") + }, + }, { name: "no matches", target: target, @@ -67,9 +83,7 @@ func Test_replaceAllMatches(t *testing.T) { return "nothing {matches}", nil }, }, - function: ottl.Optional[ottl.FunctionGetter[pcommon.Map]]{ - HasValue: false, - }, + function: ottl.Optional[ottl.FunctionGetter[pcommon.Map]]{}, want: func(expectedMap pcommon.Map) { expectedMap.PutStr("test", "hello world") expectedMap.PutStr("test2", "hello") @@ -109,9 +123,7 @@ func Test_replaceAllMatches_bad_input(t *testing.T) { return "{replacement}", nil }, } - function := ottl.Optional[ottl.FunctionGetter[interface{}]]{ - HasValue: false, - } + function := ottl.Optional[ottl.FunctionGetter[interface{}]]{} exprFunc, err := replaceAllMatches[interface{}](target, "*", replacement, function) assert.NoError(t, err) @@ -130,9 +142,7 @@ func Test_replaceAllMatches_get_nil(t *testing.T) { return "{anything}", nil }, } - function := ottl.Optional[ottl.FunctionGetter[interface{}]]{ - HasValue: false, - } + function := ottl.Optional[ottl.FunctionGetter[interface{}]]{} exprFunc, err := replaceAllMatches[interface{}](target, "*", replacement, function) assert.NoError(t, err) diff --git a/pkg/ottl/ottlfuncs/func_replace_all_patterns.go b/pkg/ottl/ottlfuncs/func_replace_all_patterns.go index 1fe28b10e86a..04f19e71adb7 100644 --- a/pkg/ottl/ottlfuncs/func_replace_all_patterns.go +++ b/pkg/ottl/ottlfuncs/func_replace_all_patterns.go @@ -43,8 +43,6 @@ func createReplaceAllPatternsFunction[K any](_ ottl.FunctionContext, oArgs ottl. func replaceAllPatterns[K any](target ottl.PMapGetter[K], mode string, regexPattern string, replacement ottl.StringGetter[K], fn ottl.Optional[ottl.FunctionGetter[K]]) (ottl.ExprFunc[K], error) { compiledPattern, err := regexp.Compile(regexPattern) var replacementVal string - var replacementExpr ottl.Expr[K] - var replacementValRaw interface{} if err != nil { return nil, fmt.Errorf("the regex pattern supplied to replace_all_patterns is not a valid pattern: %w", err) } @@ -64,13 +62,13 @@ func replaceAllPatterns[K any](target ottl.PMapGetter[K], mode string, regexPatt } } else { fnVal := fn.Get() - replacementExpr, err = fnVal.Get(&FuncArgs[K]{Input: replacement}) - if err != nil { - return nil, err + replacementExpr, errNew := fnVal.Get(&FuncArgs[K]{Input: replacement}) + if errNew != nil { + return nil, errNew } - replacementValRaw, err = replacementExpr.Eval(ctx, tCtx) - if err != nil { - return nil, err + replacementValRaw, errNew := replacementExpr.Eval(ctx, tCtx) + if errNew != nil { + return nil, errNew } replacementVal = replacementValRaw.(string) } diff --git a/pkg/ottl/ottlfuncs/func_replace_all_patterns_test.go b/pkg/ottl/ottlfuncs/func_replace_all_patterns_test.go index 99162f2e2602..f8817c404d5d 100644 --- a/pkg/ottl/ottlfuncs/func_replace_all_patterns_test.go +++ b/pkg/ottl/ottlfuncs/func_replace_all_patterns_test.go @@ -24,6 +24,14 @@ func Test_replaceAllPatterns(t *testing.T) { input.PutDouble("test5", 1234) input.PutBool("test6", true) + ottlValue := ottl.StandardFunctionGetter[pcommon.Map]{ + FCtx: ottl.FunctionContext{ + Set: componenttest.NewNopTelemetrySettings(), + }, + Fact: StandardConverters[pcommon.Map]()["SHA256"], + } + optionalArg := ottl.NewTestingOptional[ottl.FunctionGetter[pcommon.Map]](ottlValue) + target := &ottl.StandardPMapGetter[pcommon.Map]{ Getter: func(ctx context.Context, tCtx pcommon.Map) (interface{}, error) { return tCtx, nil @@ -40,7 +48,7 @@ func Test_replaceAllPatterns(t *testing.T) { want func(pcommon.Map) }{ { - name: "replace only matches", + name: "replace only matches (with hash function)", target: target, mode: modeValue, pattern: "hello", @@ -49,15 +57,7 @@ func Test_replaceAllPatterns(t *testing.T) { return "hello {universe}", nil }, }, - function: ottl.Optional[ottl.FunctionGetter[pcommon.Map]]{ - Val: ottl.StandardFunctionGetter[pcommon.Map]{ - FCtx: ottl.FunctionContext{ - Set: componenttest.NewNopTelemetrySettings(), - }, - Fact: StandardConverters[pcommon.Map]()["SHA256"], - }, - HasValue: true, - }, + function: optionalArg, want: func(expectedMap pcommon.Map) { expectedMap.PutStr("test", "4804d6b7f03268e33f78c484977f3d81771220df07cc6aac4ad4868102141fad world") expectedMap.PutStr("test2", "4804d6b7f03268e33f78c484977f3d81771220df07cc6aac4ad4868102141fad") @@ -67,6 +67,26 @@ func Test_replaceAllPatterns(t *testing.T) { expectedMap.PutBool("test6", true) }, }, + { + name: "replace only matches", + target: target, + mode: modeValue, + pattern: "hello", + replacement: ottl.StandardStringGetter[pcommon.Map]{ + Getter: func(context.Context, pcommon.Map) (interface{}, error) { + return "hello {universe}", nil + }, + }, + function: ottl.Optional[ottl.FunctionGetter[pcommon.Map]]{}, + want: func(expectedMap pcommon.Map) { + expectedMap.PutStr("test", "hello {universe} world") + expectedMap.PutStr("test2", "hello {universe}") + expectedMap.PutStr("test3", "goodbye world1 and world2") + expectedMap.PutInt("test4", 1234) + expectedMap.PutDouble("test5", 1234) + expectedMap.PutBool("test6", true) + }, + }, { name: "no matches", target: target, @@ -77,9 +97,7 @@ func Test_replaceAllPatterns(t *testing.T) { return "nothing {matches}", nil }, }, - function: ottl.Optional[ottl.FunctionGetter[pcommon.Map]]{ - HasValue: false, - }, + function: ottl.Optional[ottl.FunctionGetter[pcommon.Map]]{}, want: func(expectedMap pcommon.Map) { expectedMap.PutStr("test", "hello world") expectedMap.PutStr("test2", "hello") @@ -99,9 +117,7 @@ func Test_replaceAllPatterns(t *testing.T) { return "**** ", nil }, }, - function: ottl.Optional[ottl.FunctionGetter[pcommon.Map]]{ - HasValue: false, - }, + function: ottl.Optional[ottl.FunctionGetter[pcommon.Map]]{}, want: func(expectedMap pcommon.Map) { expectedMap.PutStr("test", "hello **** ") expectedMap.PutStr("test2", "hello") @@ -121,9 +137,7 @@ func Test_replaceAllPatterns(t *testing.T) { return "foo", nil }, }, - function: ottl.Optional[ottl.FunctionGetter[pcommon.Map]]{ - HasValue: false, - }, + function: ottl.Optional[ottl.FunctionGetter[pcommon.Map]]{}, want: func(expectedMap pcommon.Map) { expectedMap.Clear() expectedMap.PutStr("test", "hello world") @@ -144,9 +158,7 @@ func Test_replaceAllPatterns(t *testing.T) { return "nothing {matches}", nil }, }, - function: ottl.Optional[ottl.FunctionGetter[pcommon.Map]]{ - HasValue: false, - }, + function: ottl.Optional[ottl.FunctionGetter[pcommon.Map]]{}, want: func(expectedMap pcommon.Map) { expectedMap.Clear() expectedMap.PutStr("test", "hello world") @@ -167,9 +179,7 @@ func Test_replaceAllPatterns(t *testing.T) { return "test.", nil }, }, - function: ottl.Optional[ottl.FunctionGetter[pcommon.Map]]{ - HasValue: false, - }, + function: ottl.Optional[ottl.FunctionGetter[pcommon.Map]]{}, want: func(expectedMap pcommon.Map) { expectedMap.Clear() expectedMap.PutStr("test.", "hello world") @@ -190,9 +200,7 @@ func Test_replaceAllPatterns(t *testing.T) { return "world-$1", nil }, }, - function: ottl.Optional[ottl.FunctionGetter[pcommon.Map]]{ - HasValue: false, - }, + function: ottl.Optional[ottl.FunctionGetter[pcommon.Map]]{}, want: func(expectedMap pcommon.Map) { expectedMap.Clear() expectedMap.PutStr("test", "hello world") @@ -213,6 +221,7 @@ func Test_replaceAllPatterns(t *testing.T) { return "test-$1", nil }, }, + function: ottl.Optional[ottl.FunctionGetter[pcommon.Map]]{}, want: func(expectedMap pcommon.Map) { expectedMap.PutStr("test", "hello world") expectedMap.PutStr("test-2", "hello") @@ -232,9 +241,7 @@ func Test_replaceAllPatterns(t *testing.T) { return "$$world-$1", nil }, }, - function: ottl.Optional[ottl.FunctionGetter[pcommon.Map]]{ - HasValue: false, - }, + function: ottl.Optional[ottl.FunctionGetter[pcommon.Map]]{}, want: func(expectedMap pcommon.Map) { expectedMap.Clear() expectedMap.PutStr("test", "hello world") @@ -267,7 +274,6 @@ func Test_replaceAllPatterns(t *testing.T) { func Test_replaceAllPatterns_bad_input(t *testing.T) { input := pcommon.NewValueStr("not a map") - target := &ottl.StandardPMapGetter[interface{}]{ Getter: func(ctx context.Context, tCtx interface{}) (interface{}, error) { return tCtx, nil @@ -278,9 +284,7 @@ func Test_replaceAllPatterns_bad_input(t *testing.T) { return "{replacement}", nil }, } - function := ottl.Optional[ottl.FunctionGetter[interface{}]]{ - HasValue: false, - } + function := ottl.Optional[ottl.FunctionGetter[interface{}]]{} exprFunc, err := replaceAllPatterns[interface{}](target, modeValue, "regexpattern", replacement, function) assert.Nil(t, err) @@ -300,9 +304,7 @@ func Test_replaceAllPatterns_get_nil(t *testing.T) { return "{anything}", nil }, } - function := ottl.Optional[ottl.FunctionGetter[interface{}]]{ - HasValue: false, - } + function := ottl.Optional[ottl.FunctionGetter[interface{}]]{} exprFunc, err := replaceAllPatterns[interface{}](target, modeValue, "regexp", replacement, function) assert.NoError(t, err) @@ -323,9 +325,7 @@ func Test_replaceAllPatterns_invalid_pattern(t *testing.T) { return "{anything}", nil }, } - function := ottl.Optional[ottl.FunctionGetter[interface{}]]{ - HasValue: false, - } + function := ottl.Optional[ottl.FunctionGetter[interface{}]]{} invalidRegexPattern := "*" exprFunc, err := replaceAllPatterns[interface{}](target, modeValue, invalidRegexPattern, replacement, function) @@ -346,9 +346,7 @@ func Test_replaceAllPatterns_invalid_model(t *testing.T) { return "{anything}", nil }, } - function := ottl.Optional[ottl.FunctionGetter[interface{}]]{ - HasValue: false, - } + function := ottl.Optional[ottl.FunctionGetter[interface{}]]{} invalidMode := "invalid" exprFunc, err := replaceAllPatterns[interface{}](target, invalidMode, "regex", replacement, function) diff --git a/pkg/ottl/ottlfuncs/func_replace_match.go b/pkg/ottl/ottlfuncs/func_replace_match.go index 4f99950f551c..668aebb92fae 100644 --- a/pkg/ottl/ottlfuncs/func_replace_match.go +++ b/pkg/ottl/ottlfuncs/func_replace_match.go @@ -36,8 +36,6 @@ func createReplaceMatchFunction[K any](_ ottl.FunctionContext, oArgs ottl.Argume func replaceMatch[K any](target ottl.GetSetter[K], pattern string, replacement ottl.StringGetter[K], fn ottl.Optional[ottl.FunctionGetter[K]]) (ottl.ExprFunc[K], error) { glob, err := glob.Compile(pattern) var replacementVal string - var replacementExpr ottl.Expr[K] - var replacementValRaw interface{} if err != nil { return nil, fmt.Errorf("the pattern supplied to replace_match is not a valid pattern: %w", err) } @@ -53,13 +51,13 @@ func replaceMatch[K any](target ottl.GetSetter[K], pattern string, replacement o } } else { fnVal := fn.Get() - replacementExpr, err = fnVal.Get(&FuncArgs[K]{Input: replacement}) - if err != nil { - return nil, err + replacementExpr, errNew := fnVal.Get(&FuncArgs[K]{Input: replacement}) + if errNew != nil { + return nil, errNew } - replacementValRaw, err = replacementExpr.Eval(ctx, tCtx) - if err != nil { - return nil, err + replacementValRaw, errNew := replacementExpr.Eval(ctx, tCtx) + if errNew != nil { + return nil, errNew } replacementVal = replacementValRaw.(string) } diff --git a/pkg/ottl/ottlfuncs/func_replace_match_test.go b/pkg/ottl/ottlfuncs/func_replace_match_test.go index 2ea77c99a23f..f6ef99f824ac 100644 --- a/pkg/ottl/ottlfuncs/func_replace_match_test.go +++ b/pkg/ottl/ottlfuncs/func_replace_match_test.go @@ -16,7 +16,13 @@ import ( func Test_replaceMatch(t *testing.T) { input := pcommon.NewValueStr("hello world") - + ottlValue := ottl.StandardFunctionGetter[pcommon.Value]{ + FCtx: ottl.FunctionContext{ + Set: componenttest.NewNopTelemetrySettings(), + }, + Fact: StandardConverters[pcommon.Value]()["SHA256"], + } + optionalArg := ottl.NewTestingOptional[ottl.FunctionGetter[pcommon.Value]](ottlValue) target := &ottl.StandardGetSetter[pcommon.Value]{ Getter: func(ctx context.Context, tCtx pcommon.Value) (interface{}, error) { return tCtx.Str(), nil @@ -36,7 +42,7 @@ func Test_replaceMatch(t *testing.T) { want func(pcommon.Value) }{ { - name: "replace match", + name: "replace match (with hash function)", target: target, pattern: "hello*", replacement: ottl.StandardStringGetter[pcommon.Value]{ @@ -44,17 +50,23 @@ func Test_replaceMatch(t *testing.T) { return "hello {universe}", nil }, }, - function: ottl.Optional[ottl.FunctionGetter[pcommon.Value]]{ - Val: ottl.StandardFunctionGetter[pcommon.Value]{ - FCtx: ottl.FunctionContext{ - Set: componenttest.NewNopTelemetrySettings(), - }, - Fact: StandardConverters[pcommon.Value]()["SHA256"], + function: optionalArg, + want: func(expectedValue pcommon.Value) { + expectedValue.SetStr("4804d6b7f03268e33f78c484977f3d81771220df07cc6aac4ad4868102141fad") + }, + }, + { + name: "replace match", + target: target, + pattern: "hello*", + replacement: ottl.StandardStringGetter[pcommon.Value]{ + Getter: func(context.Context, pcommon.Value) (interface{}, error) { + return "hello {universe}", nil }, - HasValue: true, }, + function: ottl.Optional[ottl.FunctionGetter[pcommon.Value]]{}, want: func(expectedValue pcommon.Value) { - expectedValue.SetStr("4804d6b7f03268e33f78c484977f3d81771220df07cc6aac4ad4868102141fad") + expectedValue.SetStr("hello {universe}") }, }, { @@ -66,9 +78,7 @@ func Test_replaceMatch(t *testing.T) { return "goodbye {universe}", nil }, }, - function: ottl.Optional[ottl.FunctionGetter[pcommon.Value]]{ - HasValue: false, - }, + function: ottl.Optional[ottl.FunctionGetter[pcommon.Value]]{}, want: func(expectedValue pcommon.Value) { expectedValue.SetStr("hello world") }, @@ -108,9 +118,7 @@ func Test_replaceMatch_bad_input(t *testing.T) { return "{replacement}", nil }, } - function := ottl.Optional[ottl.FunctionGetter[interface{}]]{ - HasValue: false, - } + function := ottl.Optional[ottl.FunctionGetter[interface{}]]{} exprFunc, err := replaceMatch[interface{}](target, "*", replacement, function) assert.NoError(t, err) @@ -137,9 +145,7 @@ func Test_replaceMatch_get_nil(t *testing.T) { return "{anything}", nil }, } - function := ottl.Optional[ottl.FunctionGetter[interface{}]]{ - HasValue: false, - } + function := ottl.Optional[ottl.FunctionGetter[interface{}]]{} exprFunc, err := replaceMatch[interface{}](target, "*", replacement, function) assert.NoError(t, err) diff --git a/pkg/ottl/ottlfuncs/func_replace_pattern.go b/pkg/ottl/ottlfuncs/func_replace_pattern.go index 40d450a77551..707d9fdc6c6a 100644 --- a/pkg/ottl/ottlfuncs/func_replace_pattern.go +++ b/pkg/ottl/ottlfuncs/func_replace_pattern.go @@ -38,8 +38,6 @@ func createReplacePatternFunction[K any](_ ottl.FunctionContext, oArgs ottl.Argu func replacePattern[K any](target ottl.GetSetter[K], regexPattern string, replacement ottl.StringGetter[K], fn ottl.Optional[ottl.FunctionGetter[K]]) (ottl.ExprFunc[K], error) { var replacementVal string - var replacementExpr ottl.Expr[K] - var replacementValRaw interface{} compiledPattern, err := regexp.Compile(regexPattern) if err != nil { return nil, fmt.Errorf("the regex pattern supplied to replace_pattern is not a valid pattern: %w", err) @@ -56,13 +54,13 @@ func replacePattern[K any](target ottl.GetSetter[K], regexPattern string, replac } } else { fnVal := fn.Get() - replacementExpr, err = fnVal.Get(&FuncArgs[K]{Input: replacement}) - if err != nil { - return nil, err + replacementExpr, errNew := fnVal.Get(&FuncArgs[K]{Input: replacement}) + if errNew != nil { + return nil, errNew } - replacementValRaw, err = replacementExpr.Eval(ctx, tCtx) - if err != nil { - return nil, err + replacementValRaw, errNew := replacementExpr.Eval(ctx, tCtx) + if errNew != nil { + return nil, errNew } replacementVal = replacementValRaw.(string) } diff --git a/pkg/ottl/ottlfuncs/func_replace_pattern_test.go b/pkg/ottl/ottlfuncs/func_replace_pattern_test.go index d21675cd2e08..ed2beee156a6 100644 --- a/pkg/ottl/ottlfuncs/func_replace_pattern_test.go +++ b/pkg/ottl/ottlfuncs/func_replace_pattern_test.go @@ -17,7 +17,13 @@ import ( func Test_replacePattern(t *testing.T) { input := pcommon.NewValueStr("application passwd=sensitivedtata otherarg=notsensitive key1 key2") - + ottlValue := ottl.StandardFunctionGetter[pcommon.Value]{ + FCtx: ottl.FunctionContext{ + Set: componenttest.NewNopTelemetrySettings(), + }, + Fact: StandardConverters[pcommon.Value]()["SHA256"], + } + optionalArg := ottl.NewTestingOptional[ottl.FunctionGetter[pcommon.Value]](ottlValue) target := &ottl.StandardGetSetter[pcommon.Value]{ Getter: func(ctx context.Context, tCtx pcommon.Value) (interface{}, error) { return tCtx.Str(), nil @@ -37,7 +43,7 @@ func Test_replacePattern(t *testing.T) { want func(pcommon.Value) }{ { - name: "replace regex match", + name: "replace regex match (with hash function)", target: target, pattern: `passwd\=[^\s]*(\s?)`, replacement: ottl.StandardStringGetter[pcommon.Value]{ @@ -45,17 +51,23 @@ func Test_replacePattern(t *testing.T) { return "passwd=*** ", nil }, }, - function: ottl.Optional[ottl.FunctionGetter[pcommon.Value]]{ - Val: ottl.StandardFunctionGetter[pcommon.Value]{ - FCtx: ottl.FunctionContext{ - Set: componenttest.NewNopTelemetrySettings(), - }, - Fact: StandardConverters[pcommon.Value]()["SHA256"], + function: optionalArg, + want: func(expectedValue pcommon.Value) { + expectedValue.SetStr("application 0f2407f2d83337b1f757eb1754a7643ce0e8fba620bc605c54566cd6dfd838beotherarg=notsensitive key1 key2") + }, + }, + { + name: "replace regex match", + target: target, + pattern: `passwd\=[^\s]*(\s?)`, + replacement: ottl.StandardStringGetter[pcommon.Value]{ + Getter: func(context.Context, pcommon.Value) (interface{}, error) { + return "passwd=*** ", nil }, - HasValue: true, }, + function: ottl.Optional[ottl.FunctionGetter[pcommon.Value]]{}, want: func(expectedValue pcommon.Value) { - expectedValue.SetStr("application 0f2407f2d83337b1f757eb1754a7643ce0e8fba620bc605c54566cd6dfd838beotherarg=notsensitive key1 key2") + expectedValue.SetStr("application passwd=*** otherarg=notsensitive key1 key2") }, }, { @@ -67,9 +79,7 @@ func Test_replacePattern(t *testing.T) { return "shouldnotbeinoutput", nil }, }, - function: ottl.Optional[ottl.FunctionGetter[pcommon.Value]]{ - HasValue: false, - }, + function: ottl.Optional[ottl.FunctionGetter[pcommon.Value]]{}, want: func(expectedValue pcommon.Value) { expectedValue.SetStr("application passwd=sensitivedtata otherarg=notsensitive key1 key2") }, @@ -83,9 +93,7 @@ func Test_replacePattern(t *testing.T) { return "**** ", nil }, }, - function: ottl.Optional[ottl.FunctionGetter[pcommon.Value]]{ - HasValue: false, - }, + function: ottl.Optional[ottl.FunctionGetter[pcommon.Value]]{}, want: func(expectedValue pcommon.Value) { expectedValue.SetStr("application passwd=sensitivedtata otherarg=notsensitive **** **** ") }, @@ -99,9 +107,7 @@ func Test_replacePattern(t *testing.T) { return "$1:$2", nil }, }, - function: ottl.Optional[ottl.FunctionGetter[pcommon.Value]]{ - HasValue: false, - }, + function: ottl.Optional[ottl.FunctionGetter[pcommon.Value]]{}, want: func(expectedValue pcommon.Value) { expectedValue.SetStr("application passwd:sensitivedtata otherarg:notsensitive key1 key2") }, @@ -115,9 +121,7 @@ func Test_replacePattern(t *testing.T) { return "passwd=$$$$$$ ", nil }, }, - function: ottl.Optional[ottl.FunctionGetter[pcommon.Value]]{ - HasValue: false, - }, + function: ottl.Optional[ottl.FunctionGetter[pcommon.Value]]{}, want: func(expectedValue pcommon.Value) { expectedValue.SetStr("application passwd=$$$ otherarg=notsensitive key1 key2") }, @@ -157,9 +161,7 @@ func Test_replacePattern_bad_input(t *testing.T) { return "{replacement}", nil }, } - function := ottl.Optional[ottl.FunctionGetter[interface{}]]{ - HasValue: false, - } + function := ottl.Optional[ottl.FunctionGetter[interface{}]]{} exprFunc, err := replacePattern[interface{}](target, "regexp", replacement, function) assert.NoError(t, err) @@ -185,9 +187,7 @@ func Test_replacePattern_get_nil(t *testing.T) { return "{anything}", nil }, } - function := ottl.Optional[ottl.FunctionGetter[interface{}]]{ - HasValue: false, - } + function := ottl.Optional[ottl.FunctionGetter[interface{}]]{} exprFunc, err := replacePattern[interface{}](target, `nomatch\=[^\s]*(\s?)`, replacement, function) assert.NoError(t, err) @@ -213,9 +213,7 @@ func Test_replacePatterns_invalid_pattern(t *testing.T) { return "{anything}", nil }, } - function := ottl.Optional[ottl.FunctionGetter[interface{}]]{ - HasValue: false, - } + function := ottl.Optional[ottl.FunctionGetter[interface{}]]{} invalidRegexPattern := "*" _, err := replacePattern[interface{}](target, invalidRegexPattern, replacement, function)