package tsdb import ( "fmt" "reflect" "sort" "testing" ) func TestStore_mergeTagValues(t *testing.T) { examples := []struct { in []tagValues out TagValues }{ {}, {in: make([]tagValues, 4), out: TagValues{Values: []KeyValue{}}}, { in: []tagValues{createtagValues("m0", map[string][]string{"host": {"server-a", "server-b", "server-c"}})}, out: createTagValues("m0", map[string][]string{"host": {"server-a", "server-b", "server-c"}}), }, { in: []tagValues{ createtagValues("m0", map[string][]string{"host": {"server-a", "server-b", "server-c"}}), createtagValues("m0", map[string][]string{"host": {"server-a", "server-b", "server-c"}}), }, out: createTagValues("m0", map[string][]string{"host": {"server-a", "server-b", "server-c"}}), }, { in: []tagValues{ createtagValues("m0", map[string][]string{"host": {"server-a", "server-b", "server-c"}}), createtagValues("m0", map[string][]string{"host": {"server-a", "server-d", "server-e"}}), }, out: createTagValues("m0", map[string][]string{"host": {"server-a", "server-b", "server-c", "server-d", "server-e"}}), }, { in: []tagValues{ createtagValues("m0", map[string][]string{"host": {"server-a"}}), createtagValues("m0", map[string][]string{}), createtagValues("m0", map[string][]string{"host": {"server-a"}}), }, out: createTagValues("m0", map[string][]string{"host": {"server-a"}}), }, { in: []tagValues{ createtagValues("m0", map[string][]string{"host": {"server-q", "server-z"}}), createtagValues("m0", map[string][]string{"host": {"server-a", "server-b", "server-c"}}), createtagValues("m0", map[string][]string{"host": {"server-a", "server-d", "server-e"}}), createtagValues("m0", map[string][]string{"host": {"server-e", "server-q", "server-z"}}), createtagValues("m0", map[string][]string{"host": {"server-a"}}), }, out: createTagValues("m0", map[string][]string{"host": {"server-a", "server-b", "server-c", "server-d", "server-e", "server-q", "server-z"}}), }, { in: []tagValues{ createtagValues("m0", map[string][]string{"a": {"0", "1"}, "host1": {"server-q", "server-z"}}), createtagValues("m0", map[string][]string{"a": {"0", "2"}, "host2": {"server-a", "server-b", "server-c"}}), createtagValues("m0", map[string][]string{"a": {"0", "3"}, "host3": {"server-a", "server-d", "server-e"}}), createtagValues("m0", map[string][]string{"a": {"0", "4"}, "host4": {"server-e", "server-q", "server-z"}}), createtagValues("m0", map[string][]string{"a": {"0", "5"}, "host5": {"server-a"}}), }, out: createTagValues("m0", map[string][]string{ "a": {"0", "1", "2", "3", "4", "5"}, "host1": {"server-q", "server-z"}, "host2": {"server-a", "server-b", "server-c"}, "host3": {"server-a", "server-d", "server-e"}, "host4": {"server-e", "server-q", "server-z"}, "host5": {"server-a"}, }), }, { in: []tagValues{ createtagValues("m0", map[string][]string{"region": {"east-1", "west-1"}, "host": {"server-a", "server-b", "server-c"}}), createtagValues("m0", map[string][]string{"region": {"north-1", "west-1"}, "host": {"server-a", "server-d", "server-e"}}), }, out: createTagValues("m0", map[string][]string{ "host": {"server-a", "server-b", "server-c", "server-d", "server-e"}, "region": {"east-1", "north-1", "west-1"}, }), }, { in: []tagValues{ createtagValues("m0", map[string][]string{"region": {"east-1", "west-1"}, "host": {"server-a", "server-b", "server-c"}}), createtagValues("m0", map[string][]string{"city": {"Baltimore", "Las Vegas"}}), }, out: createTagValues("m0", map[string][]string{ "city": {"Baltimore", "Las Vegas"}, "host": {"server-a", "server-b", "server-c"}, "region": {"east-1", "west-1"}, }), }, { in: []tagValues{ createtagValues("m0", map[string][]string{"city": {"Baltimore", "Las Vegas"}}), createtagValues("m0", map[string][]string{"region": {"east-1", "west-1"}, "host": {"server-a", "server-b", "server-c"}}), }, out: createTagValues("m0", map[string][]string{ "city": {"Baltimore", "Las Vegas"}, "host": {"server-a", "server-b", "server-c"}, "region": {"east-1", "west-1"}, }), }, { in: []tagValues{ createtagValues("m0", map[string][]string{"region": {"east-1", "west-1"}, "host": {"server-a", "server-b", "server-c"}}), createtagValues("m0", map[string][]string{}), }, out: createTagValues("m0", map[string][]string{ "host": {"server-a", "server-b", "server-c"}, "region": {"east-1", "west-1"}, }), }, } buf := make([][2]int, 10) for i, example := range examples { t.Run(fmt.Sprintf("example_%d", i+1), func(t *testing.T) { if got, exp := mergeTagValues(buf, example.in...), example.out; !reflect.DeepEqual(got, exp) { t.Fatalf("\ngot\n %#v\n\n expected\n %#v", got, exp) } }) } } // Helper to create some tagValues. func createtagValues(mname string, kvs map[string][]string) tagValues { out := tagValues{ name: []byte(mname), keys: make([]string, 0, len(kvs)), values: make([][]string, len(kvs)), } for k := range kvs { out.keys = append(out.keys, k) } sort.Sort(sort.StringSlice(out.keys)) for i, k := range out.keys { values := kvs[k] sort.Sort(sort.StringSlice(values)) out.values[i] = values } return out } // Helper to create some TagValues func createTagValues(mname string, kvs map[string][]string) TagValues { var sz int for _, v := range kvs { sz += len(v) } out := TagValues{ Measurement: mname, Values: make([]KeyValue, 0, sz), } for tk, tvs := range kvs { for _, tv := range tvs { out.Values = append(out.Values, KeyValue{Key: tk, Value: tv}) } // We have to sort the KeyValues since that's how they're provided from // the Store. sort.Sort(KeyValues(out.Values)) } return out }