Skip to content

Commit

Permalink
Update concat to use StringLikeGetter
Browse files Browse the repository at this point in the history
  • Loading branch information
TylerHelmuth committed Mar 20, 2023
1 parent dc0e1a1 commit 44d6b6a
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 54 deletions.
4 changes: 2 additions & 2 deletions pkg/ottl/expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ package ottl // import "github.com/open-telemetry/opentelemetry-collector-contri

import (
"context"
"encoding/base64"
"encoding/hex"
"fmt"
"strconv"

Expand Down Expand Up @@ -156,7 +156,7 @@ func (g StandardStringLikeGetter[K]) Get(ctx context.Context, tCtx K) (*string,
case float64:
result = strconv.FormatFloat(v, 'f', -1, 64)
case []byte:
result = base64.StdEncoding.EncodeToString(v)
result = hex.EncodeToString(v)
case pcommon.Map:
result, err = jsoniter.MarshalToString(v.AsRaw())
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion pkg/ottl/expression_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ func Test_StandardStringLikeGetter(t *testing.T) {
return []byte{0}, nil
},
},
want: "AA==",
want: "00",
valid: true,
},
{
Expand Down
20 changes: 5 additions & 15 deletions pkg/ottl/ottlfuncs/func_concat.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,19 @@ import (
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl"
)

func Concat[K any](vals []ottl.Getter[K], delimiter string) (ottl.ExprFunc[K], error) {
func Concat[K any](vals []ottl.StringLikeGetter[K], delimiter string) (ottl.ExprFunc[K], error) {
return func(ctx context.Context, tCtx K) (interface{}, error) {
builder := strings.Builder{}
for i, rv := range vals {
val, err := rv.Get(ctx, tCtx)
if err != nil {
return nil, err
}
switch v := val.(type) {
case string:
builder.WriteString(v)
case []byte:
builder.WriteString(fmt.Sprintf("%x", v))
case int64:
builder.WriteString(fmt.Sprint(v))
case float64:
builder.WriteString(fmt.Sprint(v))
case bool:
builder.WriteString(fmt.Sprint(v))
case nil:
builder.WriteString(fmt.Sprint(v))
if val == nil {
builder.WriteString(fmt.Sprint(val))
} else {
builder.WriteString(*val)
}

if i != len(vals)-1 {
builder.WriteString(delimiter)
}
Expand Down
81 changes: 45 additions & 36 deletions pkg/ottl/ottlfuncs/func_concat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,21 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"go.opentelemetry.io/collector/pdata/pcommon"

"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl"
)

func Test_concat(t *testing.T) {
tests := []struct {
name string
vals []ottl.StandardGetSetter[interface{}]
vals []ottl.StandardStringLikeGetter[interface{}]
delimiter string
expected string
}{
{
name: "concat strings",
vals: []ottl.StandardGetSetter[interface{}]{
vals: []ottl.StandardStringLikeGetter[interface{}]{
{
Getter: func(ctx context.Context, tCtx interface{}) (interface{}, error) {
return "hello", nil
Expand All @@ -49,7 +50,7 @@ func Test_concat(t *testing.T) {
},
{
name: "nil",
vals: []ottl.StandardGetSetter[interface{}]{
vals: []ottl.StandardStringLikeGetter[interface{}]{
{
Getter: func(ctx context.Context, tCtx interface{}) (interface{}, error) {
return "hello", nil
Expand All @@ -71,7 +72,7 @@ func Test_concat(t *testing.T) {
},
{
name: "integers",
vals: []ottl.StandardGetSetter[interface{}]{
vals: []ottl.StandardStringLikeGetter[interface{}]{
{
Getter: func(ctx context.Context, tCtx interface{}) (interface{}, error) {
return "hello", nil
Expand All @@ -88,7 +89,7 @@ func Test_concat(t *testing.T) {
},
{
name: "floats",
vals: []ottl.StandardGetSetter[interface{}]{
vals: []ottl.StandardStringLikeGetter[interface{}]{
{
Getter: func(ctx context.Context, tCtx interface{}) (interface{}, error) {
return "hello", nil
Expand All @@ -105,7 +106,7 @@ func Test_concat(t *testing.T) {
},
{
name: "booleans",
vals: []ottl.StandardGetSetter[interface{}]{
vals: []ottl.StandardStringLikeGetter[interface{}]{
{
Getter: func(ctx context.Context, tCtx interface{}) (interface{}, error) {
return "hello", nil
Expand All @@ -122,7 +123,7 @@ func Test_concat(t *testing.T) {
},
{
name: "byte slices",
vals: []ottl.StandardGetSetter[interface{}]{
vals: []ottl.StandardStringLikeGetter[interface{}]{
{
Getter: func(ctx context.Context, tCtx interface{}) (interface{}, error) {
return []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xd2, 0xe6, 0x3c, 0xbe, 0x71, 0xf5, 0xa8}, nil
Expand All @@ -133,54 +134,50 @@ func Test_concat(t *testing.T) {
expected: "00000000000000000ed2e63cbe71f5a8",
},
{
name: "non-byte slices",
vals: []ottl.StandardGetSetter[interface{}]{
name: "pcommon.Slaice",
vals: []ottl.StandardStringLikeGetter[interface{}]{
{
Getter: func(ctx context.Context, tCtx interface{}) (interface{}, error) {
return []int64{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, nil
s := pcommon.NewSlice()
_ = s.FromRaw([]any{1, 2})
return s, nil
},
},
},
delimiter: "",
expected: "",
},
{
name: "maps",
vals: []ottl.StandardGetSetter[interface{}]{
{
Getter: func(ctx context.Context, tCtx interface{}) (interface{}, error) {
return map[string]string{"key": "value"}, nil
s := pcommon.NewSlice()
_ = s.FromRaw([]any{3, 4})
return s, nil
},
},
},
delimiter: "",
expected: "",
delimiter: ",",
expected: "[1,2],[3,4]",
},
{
name: "unprintable value in the middle",
vals: []ottl.StandardGetSetter[interface{}]{
{
Getter: func(ctx context.Context, tCtx interface{}) (interface{}, error) {
return "hello", nil
},
},
name: "maps",
vals: []ottl.StandardStringLikeGetter[interface{}]{
{
Getter: func(ctx context.Context, tCtx interface{}) (interface{}, error) {
return map[string]string{"key": "value"}, nil
m := pcommon.NewMap()
m.PutStr("a", "b")
return m, nil
},
},
{
Getter: func(ctx context.Context, tCtx interface{}) (interface{}, error) {
return "world", nil
m := pcommon.NewMap()
m.PutStr("c", "d")
return m, nil
},
},
},
delimiter: "-",
expected: "hello--world",
delimiter: ",",
expected: `{"a":"b"},{"c":"d"}`,
},
{
name: "empty string values",
vals: []ottl.StandardGetSetter[interface{}]{
vals: []ottl.StandardStringLikeGetter[interface{}]{
{
Getter: func(ctx context.Context, tCtx interface{}) (interface{}, error) {
return "", nil
Expand All @@ -202,7 +199,7 @@ func Test_concat(t *testing.T) {
},
{
name: "single argument",
vals: []ottl.StandardGetSetter[interface{}]{
vals: []ottl.StandardStringLikeGetter[interface{}]{
{
Getter: func(ctx context.Context, tCtx interface{}) (interface{}, error) {
return "hello", nil
Expand All @@ -214,20 +211,20 @@ func Test_concat(t *testing.T) {
},
{
name: "no arguments",
vals: []ottl.StandardGetSetter[interface{}]{},
vals: []ottl.StandardStringLikeGetter[interface{}]{},
delimiter: "-",
expected: "",
},
{
name: "no arguments with an empty delimiter",
vals: []ottl.StandardGetSetter[interface{}]{},
vals: []ottl.StandardStringLikeGetter[interface{}]{},
delimiter: "",
expected: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
getters := make([]ottl.Getter[interface{}], len(tt.vals))
getters := make([]ottl.StringLikeGetter[interface{}], len(tt.vals))

for i, val := range tt.vals {
getters[i] = val
Expand All @@ -241,3 +238,15 @@ func Test_concat(t *testing.T) {
})
}
}

func Test_concat_error(t *testing.T) {
target := &ottl.StandardStringLikeGetter[interface{}]{
Getter: func(ctx context.Context, tCtx interface{}) (interface{}, error) {
return []int{1, 2}, nil
},
}
exprFunc, err := Concat[interface{}]([]ottl.StringLikeGetter[interface{}]{target}, "test")
assert.NoError(t, err)
_, err = exprFunc(context.Background(), nil)
assert.Error(t, err)
}

0 comments on commit 44d6b6a

Please sign in to comment.