1package tsdb 2 3import ( 4 "fmt" 5 "reflect" 6 "sort" 7 "testing" 8) 9 10func TestStore_mergeTagValues(t *testing.T) { 11 examples := []struct { 12 in []tagValues 13 out TagValues 14 }{ 15 {}, 16 {in: make([]tagValues, 4), out: TagValues{Values: []KeyValue{}}}, 17 { 18 in: []tagValues{createtagValues("m0", map[string][]string{"host": {"server-a", "server-b", "server-c"}})}, 19 out: createTagValues("m0", map[string][]string{"host": {"server-a", "server-b", "server-c"}}), 20 }, 21 { 22 in: []tagValues{ 23 createtagValues("m0", map[string][]string{"host": {"server-a", "server-b", "server-c"}}), 24 createtagValues("m0", map[string][]string{"host": {"server-a", "server-b", "server-c"}}), 25 }, 26 out: createTagValues("m0", map[string][]string{"host": {"server-a", "server-b", "server-c"}}), 27 }, 28 { 29 in: []tagValues{ 30 createtagValues("m0", map[string][]string{"host": {"server-a", "server-b", "server-c"}}), 31 createtagValues("m0", map[string][]string{"host": {"server-a", "server-d", "server-e"}}), 32 }, 33 out: createTagValues("m0", map[string][]string{"host": {"server-a", "server-b", "server-c", "server-d", "server-e"}}), 34 }, 35 { 36 in: []tagValues{ 37 createtagValues("m0", map[string][]string{"host": {"server-a"}}), 38 createtagValues("m0", map[string][]string{}), 39 createtagValues("m0", map[string][]string{"host": {"server-a"}}), 40 }, 41 out: createTagValues("m0", map[string][]string{"host": {"server-a"}}), 42 }, 43 { 44 in: []tagValues{ 45 createtagValues("m0", map[string][]string{"host": {"server-q", "server-z"}}), 46 createtagValues("m0", map[string][]string{"host": {"server-a", "server-b", "server-c"}}), 47 createtagValues("m0", map[string][]string{"host": {"server-a", "server-d", "server-e"}}), 48 createtagValues("m0", map[string][]string{"host": {"server-e", "server-q", "server-z"}}), 49 createtagValues("m0", map[string][]string{"host": {"server-a"}}), 50 }, 51 out: createTagValues("m0", map[string][]string{"host": {"server-a", "server-b", "server-c", "server-d", "server-e", "server-q", "server-z"}}), 52 }, 53 { 54 in: []tagValues{ 55 createtagValues("m0", map[string][]string{"a": {"0", "1"}, "host1": {"server-q", "server-z"}}), 56 createtagValues("m0", map[string][]string{"a": {"0", "2"}, "host2": {"server-a", "server-b", "server-c"}}), 57 createtagValues("m0", map[string][]string{"a": {"0", "3"}, "host3": {"server-a", "server-d", "server-e"}}), 58 createtagValues("m0", map[string][]string{"a": {"0", "4"}, "host4": {"server-e", "server-q", "server-z"}}), 59 createtagValues("m0", map[string][]string{"a": {"0", "5"}, "host5": {"server-a"}}), 60 }, 61 out: createTagValues("m0", map[string][]string{ 62 "a": {"0", "1", "2", "3", "4", "5"}, 63 "host1": {"server-q", "server-z"}, 64 "host2": {"server-a", "server-b", "server-c"}, 65 "host3": {"server-a", "server-d", "server-e"}, 66 "host4": {"server-e", "server-q", "server-z"}, 67 "host5": {"server-a"}, 68 }), 69 }, 70 { 71 in: []tagValues{ 72 createtagValues("m0", map[string][]string{"region": {"east-1", "west-1"}, "host": {"server-a", "server-b", "server-c"}}), 73 createtagValues("m0", map[string][]string{"region": {"north-1", "west-1"}, "host": {"server-a", "server-d", "server-e"}}), 74 }, 75 out: createTagValues("m0", map[string][]string{ 76 "host": {"server-a", "server-b", "server-c", "server-d", "server-e"}, 77 "region": {"east-1", "north-1", "west-1"}, 78 }), 79 }, 80 { 81 in: []tagValues{ 82 createtagValues("m0", map[string][]string{"region": {"east-1", "west-1"}, "host": {"server-a", "server-b", "server-c"}}), 83 createtagValues("m0", map[string][]string{"city": {"Baltimore", "Las Vegas"}}), 84 }, 85 out: createTagValues("m0", map[string][]string{ 86 "city": {"Baltimore", "Las Vegas"}, 87 "host": {"server-a", "server-b", "server-c"}, 88 "region": {"east-1", "west-1"}, 89 }), 90 }, 91 { 92 in: []tagValues{ 93 createtagValues("m0", map[string][]string{"city": {"Baltimore", "Las Vegas"}}), 94 createtagValues("m0", map[string][]string{"region": {"east-1", "west-1"}, "host": {"server-a", "server-b", "server-c"}}), 95 }, 96 out: createTagValues("m0", map[string][]string{ 97 "city": {"Baltimore", "Las Vegas"}, 98 "host": {"server-a", "server-b", "server-c"}, 99 "region": {"east-1", "west-1"}, 100 }), 101 }, 102 { 103 in: []tagValues{ 104 createtagValues("m0", map[string][]string{"region": {"east-1", "west-1"}, "host": {"server-a", "server-b", "server-c"}}), 105 createtagValues("m0", map[string][]string{}), 106 }, 107 out: createTagValues("m0", map[string][]string{ 108 "host": {"server-a", "server-b", "server-c"}, 109 "region": {"east-1", "west-1"}, 110 }), 111 }, 112 } 113 114 buf := make([][2]int, 10) 115 for i, example := range examples { 116 t.Run(fmt.Sprintf("example_%d", i+1), func(t *testing.T) { 117 if got, exp := mergeTagValues(buf, example.in...), example.out; !reflect.DeepEqual(got, exp) { 118 t.Fatalf("\ngot\n %#v\n\n expected\n %#v", got, exp) 119 } 120 }) 121 } 122} 123 124// Helper to create some tagValues. 125func createtagValues(mname string, kvs map[string][]string) tagValues { 126 out := tagValues{ 127 name: []byte(mname), 128 keys: make([]string, 0, len(kvs)), 129 values: make([][]string, len(kvs)), 130 } 131 132 for k := range kvs { 133 out.keys = append(out.keys, k) 134 } 135 sort.Strings(out.keys) 136 137 for i, k := range out.keys { 138 values := kvs[k] 139 sort.Strings(values) 140 out.values[i] = values 141 } 142 return out 143} 144 145// Helper to create some TagValues 146func createTagValues(mname string, kvs map[string][]string) TagValues { 147 var sz int 148 for _, v := range kvs { 149 sz += len(v) 150 } 151 152 out := TagValues{ 153 Measurement: mname, 154 Values: make([]KeyValue, 0, sz), 155 } 156 157 for tk, tvs := range kvs { 158 for _, tv := range tvs { 159 out.Values = append(out.Values, KeyValue{Key: tk, Value: tv}) 160 } 161 // We have to sort the KeyValues since that's how they're provided from 162 // the Store. 163 sort.Sort(KeyValues(out.Values)) 164 } 165 166 return out 167} 168