// Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package correlation import ( "fmt" "testing" "go.opentelemetry.io/otel/api/kv/value" "go.opentelemetry.io/otel/api/kv" ) type testCase struct { name string value MapUpdate init []int wantKVs []kv.KeyValue } func TestMap(t *testing.T) { for _, testcase := range getTestCases() { t.Logf("Running test case %s", testcase.name) var got Map if len(testcase.init) > 0 { got = makeTestMap(testcase.init).Apply(testcase.value) } else { got = NewMap(testcase.value) } for _, s := range testcase.wantKVs { if ok := got.HasValue(s.Key); !ok { t.Errorf("Expected Key %s to have Value", s.Key) } if g, ok := got.Value(s.Key); !ok || g != s.Value { t.Errorf("+got: %v, -want: %v", g, s.Value) } } // test Foreach() got.Foreach(func(kv kv.KeyValue) bool { for _, want := range testcase.wantKVs { if kv == want { return false } } t.Errorf("Expected kv %v, but not found", kv) return true }) if l, exp := got.Len(), len(testcase.wantKVs); l != exp { t.Errorf("+got: %d, -want: %d", l, exp) } } } func TestSizeComputation(t *testing.T) { for _, testcase := range getTestCases() { t.Logf("Running test case %s", testcase.name) var initMap Map if len(testcase.init) > 0 { initMap = makeTestMap(testcase.init) } else { initMap = NewEmptyMap() } gotMap := initMap.Apply(testcase.value) delSet, addSet := getModificationSets(testcase.value) mapSize := getNewMapSize(initMap.m, delSet, addSet) if gotMap.Len() != mapSize { t.Errorf("Expected computed size to be %d, got %d", gotMap.Len(), mapSize) } } } func getTestCases() []testCase { return []testCase{ { name: "map with MultiKV", value: MapUpdate{MultiKV: []kv.KeyValue{ kv.Int64("key1", 1), kv.String("key2", "val2")}, }, init: []int{}, wantKVs: []kv.KeyValue{ kv.Int64("key1", 1), kv.String("key2", "val2"), }, }, { name: "map with SingleKV", value: MapUpdate{SingleKV: kv.String("key1", "val1")}, init: []int{}, wantKVs: []kv.KeyValue{ kv.String("key1", "val1"), }, }, { name: "map with both add fields", value: MapUpdate{SingleKV: kv.Int64("key1", 3), MultiKV: []kv.KeyValue{ kv.String("key1", ""), kv.String("key2", "val2")}, }, init: []int{}, wantKVs: []kv.KeyValue{ kv.String("key1", ""), kv.String("key2", "val2"), }, }, { name: "map with empty MapUpdate", value: MapUpdate{}, init: []int{}, wantKVs: []kv.KeyValue{}, }, { name: "map with DropSingleK", value: MapUpdate{DropSingleK: kv.Key("key1")}, init: []int{}, wantKVs: []kv.KeyValue{}, }, { name: "map with DropMultiK", value: MapUpdate{DropMultiK: []kv.Key{ kv.Key("key1"), kv.Key("key2"), }}, init: []int{}, wantKVs: []kv.KeyValue{}, }, { name: "map with both drop fields", value: MapUpdate{ DropSingleK: kv.Key("key1"), DropMultiK: []kv.Key{ kv.Key("key1"), kv.Key("key2"), }, }, init: []int{}, wantKVs: []kv.KeyValue{}, }, { name: "map with all fields", value: MapUpdate{ DropSingleK: kv.Key("key1"), DropMultiK: []kv.Key{ kv.Key("key1"), kv.Key("key2"), }, SingleKV: kv.String("key4", "val4"), MultiKV: []kv.KeyValue{ kv.String("key1", ""), kv.String("key2", "val2"), kv.String("key3", "val3"), }, }, init: []int{}, wantKVs: []kv.KeyValue{ kv.String("key1", ""), kv.String("key2", "val2"), kv.String("key3", "val3"), kv.String("key4", "val4"), }, }, { name: "Existing map with MultiKV", value: MapUpdate{MultiKV: []kv.KeyValue{ kv.Int64("key1", 1), kv.String("key2", "val2")}, }, init: []int{5}, wantKVs: []kv.KeyValue{ kv.Int64("key1", 1), kv.String("key2", "val2"), kv.Int("key5", 5), }, }, { name: "Existing map with SingleKV", value: MapUpdate{SingleKV: kv.String("key1", "val1")}, init: []int{5}, wantKVs: []kv.KeyValue{ kv.String("key1", "val1"), kv.Int("key5", 5), }, }, { name: "Existing map with both add fields", value: MapUpdate{SingleKV: kv.Int64("key1", 3), MultiKV: []kv.KeyValue{ kv.String("key1", ""), kv.String("key2", "val2")}, }, init: []int{5}, wantKVs: []kv.KeyValue{ kv.String("key1", ""), kv.String("key2", "val2"), kv.Int("key5", 5), }, }, { name: "Existing map with empty MapUpdate", value: MapUpdate{}, init: []int{5}, wantKVs: []kv.KeyValue{ kv.Int("key5", 5), }, }, { name: "Existing map with DropSingleK", value: MapUpdate{DropSingleK: kv.Key("key1")}, init: []int{1, 5}, wantKVs: []kv.KeyValue{ kv.Int("key5", 5), }, }, { name: "Existing map with DropMultiK", value: MapUpdate{DropMultiK: []kv.Key{ kv.Key("key1"), kv.Key("key2"), }}, init: []int{1, 5}, wantKVs: []kv.KeyValue{ kv.Int("key5", 5), }, }, { name: "Existing map with both drop fields", value: MapUpdate{ DropSingleK: kv.Key("key1"), DropMultiK: []kv.Key{ kv.Key("key1"), kv.Key("key2"), }, }, init: []int{1, 2, 5}, wantKVs: []kv.KeyValue{ kv.Int("key5", 5), }, }, { name: "Existing map with all the fields", value: MapUpdate{ DropSingleK: kv.Key("key1"), DropMultiK: []kv.Key{ kv.Key("key1"), kv.Key("key2"), kv.Key("key5"), kv.Key("key6"), }, SingleKV: kv.String("key4", "val4"), MultiKV: []kv.KeyValue{ kv.String("key1", ""), kv.String("key2", "val2"), kv.String("key3", "val3"), }, }, init: []int{5, 6, 7}, wantKVs: []kv.KeyValue{ kv.String("key1", ""), kv.String("key2", "val2"), kv.String("key3", "val3"), kv.String("key4", "val4"), kv.Int("key7", 7), }, }, } } func makeTestMap(ints []int) Map { r := make(rawMap, len(ints)) for _, v := range ints { r[kv.Key(fmt.Sprintf("key%d", v))] = value.Int(v) } return newMap(r) }