1// Copyright The OpenTelemetry Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package transform 16 17import ( 18 "testing" 19 20 "github.com/stretchr/testify/assert" 21 22 commonpb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/common/v1" 23 "go.opentelemetry.io/otel/label" 24) 25 26type attributeTest struct { 27 attrs []label.KeyValue 28 expected []*commonpb.KeyValue 29} 30 31func TestAttributes(t *testing.T) { 32 for _, test := range []attributeTest{ 33 {nil, nil}, 34 { 35 []label.KeyValue{ 36 label.Int("int to int", 123), 37 label.Uint("uint to int", 1234), 38 label.Int32("int32 to int", 12345), 39 label.Uint32("uint32 to int", 123456), 40 label.Int64("int64 to int64", 1234567), 41 label.Uint64("uint64 to int64", 12345678), 42 label.Float32("float32 to double", 3.14), 43 label.Float32("float64 to double", 1.61), 44 label.String("string to string", "string"), 45 label.Bool("bool to bool", true), 46 }, 47 []*commonpb.KeyValue{ 48 { 49 Key: "int to int", 50 Value: &commonpb.AnyValue{ 51 Value: &commonpb.AnyValue_IntValue{ 52 IntValue: 123, 53 }, 54 }, 55 }, 56 { 57 Key: "uint to int", 58 Value: &commonpb.AnyValue{ 59 Value: &commonpb.AnyValue_IntValue{ 60 IntValue: 1234, 61 }, 62 }, 63 }, 64 { 65 Key: "int32 to int", 66 Value: &commonpb.AnyValue{ 67 Value: &commonpb.AnyValue_IntValue{ 68 IntValue: 12345, 69 }, 70 }, 71 }, 72 { 73 Key: "uint32 to int", 74 Value: &commonpb.AnyValue{ 75 Value: &commonpb.AnyValue_IntValue{ 76 IntValue: 123456, 77 }, 78 }, 79 }, 80 { 81 Key: "int64 to int64", 82 Value: &commonpb.AnyValue{ 83 Value: &commonpb.AnyValue_IntValue{ 84 IntValue: 1234567, 85 }, 86 }, 87 }, 88 { 89 Key: "uint64 to int64", 90 Value: &commonpb.AnyValue{ 91 Value: &commonpb.AnyValue_IntValue{ 92 IntValue: 12345678, 93 }, 94 }, 95 }, 96 { 97 Key: "float32 to double", 98 Value: &commonpb.AnyValue{ 99 Value: &commonpb.AnyValue_DoubleValue{ 100 DoubleValue: 3.14, 101 }, 102 }, 103 }, 104 { 105 Key: "float64 to double", 106 Value: &commonpb.AnyValue{ 107 Value: &commonpb.AnyValue_DoubleValue{ 108 DoubleValue: 1.61, 109 }, 110 }, 111 }, 112 { 113 Key: "string to string", 114 Value: &commonpb.AnyValue{ 115 Value: &commonpb.AnyValue_StringValue{ 116 StringValue: "string", 117 }, 118 }, 119 }, 120 { 121 Key: "bool to bool", 122 Value: &commonpb.AnyValue{ 123 Value: &commonpb.AnyValue_BoolValue{ 124 BoolValue: true, 125 }, 126 }, 127 }, 128 }, 129 }, 130 } { 131 got := Attributes(test.attrs) 132 if !assert.Len(t, got, len(test.expected)) { 133 continue 134 } 135 for i, actual := range got { 136 if a, ok := actual.Value.Value.(*commonpb.AnyValue_DoubleValue); ok { 137 e, ok := test.expected[i].Value.Value.(*commonpb.AnyValue_DoubleValue) 138 if !ok { 139 t.Errorf("expected AnyValue_DoubleValue, got %T", test.expected[i].Value.Value) 140 continue 141 } 142 if !assert.InDelta(t, e.DoubleValue, a.DoubleValue, 0.01) { 143 continue 144 } 145 e.DoubleValue = a.DoubleValue 146 } 147 assert.Equal(t, test.expected[i], actual) 148 } 149 } 150} 151 152func TestArrayAttributes(t *testing.T) { 153 // Array KeyValue supports only arrays of primitive types: 154 // "bool", "int", "int32", "int64", 155 // "float32", "float64", "string", 156 // "uint", "uint32", "uint64" 157 for _, test := range []attributeTest{ 158 {nil, nil}, 159 { 160 []label.KeyValue{ 161 label.Array("invalid", [][]string{{"1", "2"}, {"a"}}), 162 }, 163 []*commonpb.KeyValue{ 164 { 165 Key: "invalid", 166 Value: &commonpb.AnyValue{ 167 Value: &commonpb.AnyValue_StringValue{ 168 StringValue: "INVALID", 169 }, 170 }, 171 }, 172 }, 173 }, 174 { 175 []label.KeyValue{ 176 label.Array("bool array to bool array", []bool{true, false}), 177 label.Array("int array to int64 array", []int{1, 2, 3}), 178 label.Array("uint array to int64 array", []uint{1, 2, 3}), 179 label.Array("int32 array to int64 array", []int32{1, 2, 3}), 180 label.Array("uint32 array to int64 array", []uint32{1, 2, 3}), 181 label.Array("int64 array to int64 array", []int64{1, 2, 3}), 182 label.Array("uint64 array to int64 array", []uint64{1, 2, 3}), 183 label.Array("float32 array to double array", []float32{1.11, 2.22, 3.33}), 184 label.Array("float64 array to double array", []float64{1.11, 2.22, 3.33}), 185 label.Array("string array to string array", []string{"foo", "bar", "baz"}), 186 }, 187 []*commonpb.KeyValue{ 188 newOTelBoolArray("bool array to bool array", []bool{true, false}), 189 newOTelIntArray("int array to int64 array", []int64{1, 2, 3}), 190 newOTelIntArray("uint array to int64 array", []int64{1, 2, 3}), 191 newOTelIntArray("int32 array to int64 array", []int64{1, 2, 3}), 192 newOTelIntArray("uint32 array to int64 array", []int64{1, 2, 3}), 193 newOTelIntArray("int64 array to int64 array", []int64{1, 2, 3}), 194 newOTelIntArray("uint64 array to int64 array", []int64{1, 2, 3}), 195 newOTelDoubleArray("float32 array to double array", []float64{1.11, 2.22, 3.33}), 196 newOTelDoubleArray("float64 array to double array", []float64{1.11, 2.22, 3.33}), 197 newOTelStringArray("string array to string array", []string{"foo", "bar", "baz"}), 198 }, 199 }, 200 } { 201 actualArrayAttributes := Attributes(test.attrs) 202 expectedArrayAttributes := test.expected 203 if !assert.Len(t, actualArrayAttributes, len(expectedArrayAttributes)) { 204 continue 205 } 206 207 for i, actualArrayAttr := range actualArrayAttributes { 208 expectedArrayAttr := expectedArrayAttributes[i] 209 expectedKey, actualKey := expectedArrayAttr.Key, actualArrayAttr.Key 210 if !assert.Equal(t, expectedKey, actualKey) { 211 continue 212 } 213 214 expected := expectedArrayAttr.Value.GetArrayValue() 215 actual := actualArrayAttr.Value.GetArrayValue() 216 if expected == nil { 217 assert.Nil(t, actual) 218 continue 219 } 220 if assert.NotNil(t, actual, "expected not nil for %s", actualKey) { 221 assertExpectedArrayValues(t, expected.Values, actual.Values) 222 } 223 } 224 225 } 226} 227 228func assertExpectedArrayValues(t *testing.T, expectedValues, actualValues []*commonpb.AnyValue) { 229 for i, actual := range actualValues { 230 expected := expectedValues[i] 231 if a, ok := actual.Value.(*commonpb.AnyValue_DoubleValue); ok { 232 e, ok := expected.Value.(*commonpb.AnyValue_DoubleValue) 233 if !ok { 234 t.Errorf("expected AnyValue_DoubleValue, got %T", expected.Value) 235 continue 236 } 237 if !assert.InDelta(t, e.DoubleValue, a.DoubleValue, 0.01) { 238 continue 239 } 240 e.DoubleValue = a.DoubleValue 241 } 242 assert.Equal(t, expected, actual) 243 } 244} 245 246func newOTelBoolArray(key string, values []bool) *commonpb.KeyValue { 247 arrayValues := []*commonpb.AnyValue{} 248 for _, b := range values { 249 arrayValues = append(arrayValues, &commonpb.AnyValue{ 250 Value: &commonpb.AnyValue_BoolValue{ 251 BoolValue: b, 252 }, 253 }) 254 } 255 256 return newOTelArray(key, arrayValues) 257} 258 259func newOTelIntArray(key string, values []int64) *commonpb.KeyValue { 260 arrayValues := []*commonpb.AnyValue{} 261 262 for _, i := range values { 263 arrayValues = append(arrayValues, &commonpb.AnyValue{ 264 Value: &commonpb.AnyValue_IntValue{ 265 IntValue: i, 266 }, 267 }) 268 } 269 270 return newOTelArray(key, arrayValues) 271} 272 273func newOTelDoubleArray(key string, values []float64) *commonpb.KeyValue { 274 arrayValues := []*commonpb.AnyValue{} 275 276 for _, d := range values { 277 arrayValues = append(arrayValues, &commonpb.AnyValue{ 278 Value: &commonpb.AnyValue_DoubleValue{ 279 DoubleValue: d, 280 }, 281 }) 282 } 283 284 return newOTelArray(key, arrayValues) 285} 286 287func newOTelStringArray(key string, values []string) *commonpb.KeyValue { 288 arrayValues := []*commonpb.AnyValue{} 289 290 for _, s := range values { 291 arrayValues = append(arrayValues, &commonpb.AnyValue{ 292 Value: &commonpb.AnyValue_StringValue{ 293 StringValue: s, 294 }, 295 }) 296 } 297 298 return newOTelArray(key, arrayValues) 299} 300 301func newOTelArray(key string, arrayValues []*commonpb.AnyValue) *commonpb.KeyValue { 302 return &commonpb.KeyValue{ 303 Key: key, 304 Value: &commonpb.AnyValue{ 305 Value: &commonpb.AnyValue_ArrayValue{ 306 ArrayValue: &commonpb.ArrayValue{ 307 Values: arrayValues, 308 }, 309 }, 310 }, 311 } 312} 313