1package statsd 2 3import ( 4 "sort" 5 "strings" 6 "sync" 7 "testing" 8 9 "github.com/stretchr/testify/assert" 10) 11 12func TestAggregatorSample(t *testing.T) { 13 a := newAggregator(nil) 14 15 tags := []string{"tag1", "tag2"} 16 17 for i := 0; i < 2; i++ { 18 a.gauge("gaugeTest", 21, tags) 19 assert.Len(t, a.gauges, 1) 20 assert.Contains(t, a.gauges, "gaugeTest:tag1,tag2") 21 22 a.count("countTest", 21, tags) 23 assert.Len(t, a.counts, 1) 24 assert.Contains(t, a.counts, "countTest:tag1,tag2") 25 26 a.set("setTest", "value1", tags) 27 assert.Len(t, a.sets, 1) 28 assert.Contains(t, a.sets, "setTest:tag1,tag2") 29 30 a.set("setTest", "value1", tags) 31 assert.Len(t, a.sets, 1) 32 assert.Contains(t, a.sets, "setTest:tag1,tag2") 33 34 a.histogram("histogramTest", 21, tags) 35 assert.Len(t, a.histograms.values, 1) 36 assert.Contains(t, a.histograms.values, "histogramTest:tag1,tag2") 37 38 a.distribution("distributionTest", 21, tags) 39 assert.Len(t, a.distributions.values, 1) 40 assert.Contains(t, a.distributions.values, "distributionTest:tag1,tag2") 41 42 a.timing("timingTest", 21, tags) 43 assert.Len(t, a.timings.values, 1) 44 assert.Contains(t, a.timings.values, "timingTest:tag1,tag2") 45 } 46} 47 48func TestAggregatorFlush(t *testing.T) { 49 a := newAggregator(nil) 50 51 tags := []string{"tag1", "tag2"} 52 53 a.gauge("gaugeTest1", 21, tags) 54 a.gauge("gaugeTest1", 10, tags) 55 a.gauge("gaugeTest2", 15, tags) 56 57 a.count("countTest1", 21, tags) 58 a.count("countTest1", 10, tags) 59 a.count("countTest2", 1, tags) 60 61 a.set("setTest1", "value1", tags) 62 a.set("setTest1", "value1", tags) 63 a.set("setTest1", "value2", tags) 64 a.set("setTest2", "value1", tags) 65 66 a.histogram("histogramTest1", 21, tags) 67 a.histogram("histogramTest1", 22, tags) 68 a.histogram("histogramTest2", 23, tags) 69 70 a.distribution("distributionTest1", 21, tags) 71 a.distribution("distributionTest1", 22, tags) 72 a.distribution("distributionTest2", 23, tags) 73 74 a.timing("timingTest1", 21, tags) 75 a.timing("timingTest1", 22, tags) 76 a.timing("timingTest2", 23, tags) 77 78 metrics := a.flushMetrics() 79 80 assert.Len(t, a.gauges, 0) 81 assert.Len(t, a.counts, 0) 82 assert.Len(t, a.sets, 0) 83 assert.Len(t, a.histograms.values, 0) 84 assert.Len(t, a.distributions.values, 0) 85 assert.Len(t, a.timings.values, 0) 86 87 assert.Len(t, metrics, 13) 88 89 sort.Slice(metrics, func(i, j int) bool { 90 if metrics[i].metricType == metrics[j].metricType { 91 res := strings.Compare(metrics[i].name, metrics[j].name) 92 // this happens fo set 93 if res == 0 { 94 return strings.Compare(metrics[i].svalue, metrics[j].svalue) != 1 95 } 96 return res != 1 97 } 98 return metrics[i].metricType < metrics[j].metricType 99 }) 100 101 assert.Equal(t, []metric{ 102 metric{ 103 metricType: gauge, 104 name: "gaugeTest1", 105 tags: tags, 106 rate: 1, 107 fvalue: float64(10), 108 }, 109 metric{ 110 metricType: gauge, 111 name: "gaugeTest2", 112 tags: tags, 113 rate: 1, 114 fvalue: float64(15), 115 }, 116 metric{ 117 metricType: count, 118 name: "countTest1", 119 tags: tags, 120 rate: 1, 121 ivalue: int64(31), 122 }, 123 metric{ 124 metricType: count, 125 name: "countTest2", 126 tags: tags, 127 rate: 1, 128 ivalue: int64(1), 129 }, 130 metric{ 131 metricType: histogramAggregated, 132 name: "histogramTest1", 133 stags: strings.Join(tags, tagSeparatorSymbol), 134 rate: 1, 135 fvalues: []float64{21.0, 22.0}, 136 }, 137 metric{ 138 metricType: histogramAggregated, 139 name: "histogramTest2", 140 stags: strings.Join(tags, tagSeparatorSymbol), 141 rate: 1, 142 fvalues: []float64{23.0}, 143 }, 144 metric{ 145 metricType: distributionAggregated, 146 name: "distributionTest1", 147 stags: strings.Join(tags, tagSeparatorSymbol), 148 rate: 1, 149 fvalues: []float64{21.0, 22.0}, 150 }, 151 metric{ 152 metricType: distributionAggregated, 153 name: "distributionTest2", 154 stags: strings.Join(tags, tagSeparatorSymbol), 155 rate: 1, 156 fvalues: []float64{23.0}, 157 }, 158 metric{ 159 metricType: set, 160 name: "setTest1", 161 tags: tags, 162 rate: 1, 163 svalue: "value1", 164 }, 165 metric{ 166 metricType: set, 167 name: "setTest1", 168 tags: tags, 169 rate: 1, 170 svalue: "value2", 171 }, 172 metric{ 173 metricType: set, 174 name: "setTest2", 175 tags: tags, 176 rate: 1, 177 svalue: "value1", 178 }, 179 metric{ 180 metricType: timingAggregated, 181 name: "timingTest1", 182 stags: strings.Join(tags, tagSeparatorSymbol), 183 rate: 1, 184 fvalues: []float64{21.0, 22.0}, 185 }, 186 metric{ 187 metricType: timingAggregated, 188 name: "timingTest2", 189 stags: strings.Join(tags, tagSeparatorSymbol), 190 rate: 1, 191 fvalues: []float64{23.0}, 192 }, 193 }, 194 metrics) 195 196} 197 198func TestAggregatorFlushConcurrency(t *testing.T) { 199 a := newAggregator(nil) 200 201 var wg sync.WaitGroup 202 wg.Add(10) 203 204 tags := []string{"tag1", "tag2"} 205 206 for i := 0; i < 5; i++ { 207 go func() { 208 defer wg.Done() 209 210 a.gauge("gaugeTest1", 21, tags) 211 a.count("countTest1", 21, tags) 212 a.set("setTest1", "value1", tags) 213 a.histogram("histogramTest1", 21, tags) 214 a.distribution("distributionTest1", 21, tags) 215 a.timing("timingTest1", 21, tags) 216 }() 217 } 218 219 for i := 0; i < 5; i++ { 220 go func() { 221 defer wg.Done() 222 223 a.flushMetrics() 224 }() 225 } 226 227 wg.Wait() 228} 229