github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/mongo/mongometrics/dialmetrics_test.go (about) 1 // Copyright 2017 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENSE file for details. 3 4 package mongometrics_test 5 6 import ( 7 "errors" 8 "net" 9 "reflect" 10 "time" 11 12 "github.com/juju/testing" 13 jc "github.com/juju/testing/checkers" 14 "github.com/prometheus/client_golang/prometheus" 15 dto "github.com/prometheus/client_model/go" 16 gc "gopkg.in/check.v1" 17 18 "github.com/juju/juju/mongo/mongometrics" 19 ) 20 21 type DialCollectorSuite struct { 22 testing.IsolationSuite 23 collector *mongometrics.DialCollector 24 } 25 26 var _ = gc.Suite(&DialCollectorSuite{}) 27 28 func (s *DialCollectorSuite) SetUpTest(c *gc.C) { 29 s.IsolationSuite.SetUpTest(c) 30 s.collector = mongometrics.NewDialCollector() 31 } 32 33 func (s *DialCollectorSuite) TestDescribe(c *gc.C) { 34 ch := make(chan *prometheus.Desc) 35 go func() { 36 defer close(ch) 37 s.collector.Describe(ch) 38 }() 39 var descs []*prometheus.Desc 40 for desc := range ch { 41 descs = append(descs, desc) 42 } 43 c.Assert(descs, gc.HasLen, 2) 44 c.Assert(descs[0].String(), gc.Matches, `.*fqName: "juju_mongo_dials_total".*`) 45 c.Assert(descs[1].String(), gc.Matches, `.*fqName: "juju_mongo_dial_duration_seconds".*`) 46 } 47 48 func (s *DialCollectorSuite) TestCollect(c *gc.C) { 49 s.collector.PostDialServer("foo", time.Second, nil) 50 s.collector.PostDialServer("foo", 2*time.Second, nil) 51 s.collector.PostDialServer("foo", 3*time.Second, nil) 52 s.collector.PostDialServer("bar", time.Millisecond, errors.New("bewm")) 53 s.collector.PostDialServer("baz", time.Minute, &net.OpError{ 54 Op: "read", 55 Err: errors.New("bewm"), 56 }) 57 s.collector.PostDialServer("qux", time.Hour, netError{ 58 error: errors.New("bewm"), 59 timeout: true, 60 temporary: true, 61 }) 62 63 ch := make(chan prometheus.Metric) 64 go func() { 65 defer close(ch) 66 s.collector.Collect(ch) 67 }() 68 69 var dtoMetrics [8]dto.Metric 70 var metrics []prometheus.Metric 71 for metric := range ch { 72 metrics = append(metrics, metric) 73 } 74 c.Assert(metrics, gc.HasLen, len(dtoMetrics)) 75 76 for i, metric := range metrics { 77 err := metric.Write(&dtoMetrics[i]) 78 c.Assert(err, jc.ErrorIsNil) 79 } 80 81 float64ptr := func(v float64) *float64 { 82 return &v 83 } 84 uint64ptr := func(v uint64) *uint64 { 85 return &v 86 } 87 labelpair := func(n, v string) *dto.LabelPair { 88 return &dto.LabelPair{Name: &n, Value: &v} 89 } 90 expected := []dto.Metric{{ 91 Counter: &dto.Counter{Value: float64ptr(3)}, 92 Label: []*dto.LabelPair{ 93 labelpair("failed", ""), 94 labelpair("server", "foo"), 95 labelpair("timeout", ""), 96 }, 97 }, { 98 Counter: &dto.Counter{Value: float64ptr(1)}, 99 Label: []*dto.LabelPair{ 100 labelpair("failed", "failed"), 101 labelpair("server", "bar"), 102 labelpair("timeout", ""), 103 }, 104 }, { 105 Counter: &dto.Counter{Value: float64ptr(1)}, 106 Label: []*dto.LabelPair{ 107 labelpair("failed", "read"), 108 labelpair("server", "baz"), 109 labelpair("timeout", ""), 110 }, 111 }, { 112 Counter: &dto.Counter{Value: float64ptr(1)}, 113 Label: []*dto.LabelPair{ 114 labelpair("failed", "failed"), 115 labelpair("server", "qux"), 116 labelpair("timeout", "timed out"), 117 }, 118 }, { 119 Label: []*dto.LabelPair{ 120 labelpair("failed", ""), 121 labelpair("server", "foo"), 122 labelpair("timeout", ""), 123 }, 124 Summary: &dto.Summary{ 125 SampleCount: uint64ptr(3), 126 SampleSum: float64ptr(6), 127 Quantile: []*dto.Quantile{{ 128 Quantile: float64ptr(0.5), 129 Value: float64ptr(1), 130 }, { 131 Quantile: float64ptr(0.9), 132 Value: float64ptr(2), 133 }, { 134 Quantile: float64ptr(0.99), 135 Value: float64ptr(2), 136 }}, 137 }, 138 }, { 139 Label: []*dto.LabelPair{ 140 labelpair("failed", "failed"), 141 labelpair("server", "bar"), 142 labelpair("timeout", ""), 143 }, 144 Summary: &dto.Summary{ 145 SampleCount: uint64ptr(1), 146 SampleSum: float64ptr(0.001), 147 Quantile: []*dto.Quantile{{ 148 Quantile: float64ptr(0.5), 149 Value: float64ptr(0.001), 150 }, { 151 Quantile: float64ptr(0.9), 152 Value: float64ptr(0.001), 153 }, { 154 Quantile: float64ptr(0.99), 155 Value: float64ptr(0.001), 156 }}, 157 }, 158 }, { 159 Label: []*dto.LabelPair{ 160 labelpair("failed", "read"), 161 labelpair("server", "baz"), 162 labelpair("timeout", ""), 163 }, 164 Summary: &dto.Summary{ 165 SampleCount: uint64ptr(1), 166 SampleSum: float64ptr(60), 167 Quantile: []*dto.Quantile{{ 168 Quantile: float64ptr(0.5), 169 Value: float64ptr(60), 170 }, { 171 Quantile: float64ptr(0.9), 172 Value: float64ptr(60), 173 }, { 174 Quantile: float64ptr(0.99), 175 Value: float64ptr(60), 176 }}, 177 }, 178 }, { 179 Label: []*dto.LabelPair{ 180 labelpair("failed", "failed"), 181 labelpair("server", "qux"), 182 labelpair("timeout", "timed out"), 183 }, 184 Summary: &dto.Summary{ 185 SampleCount: uint64ptr(1), 186 SampleSum: float64ptr(3600), 187 Quantile: []*dto.Quantile{{ 188 Quantile: float64ptr(0.5), 189 Value: float64ptr(3600), 190 }, { 191 Quantile: float64ptr(0.9), 192 Value: float64ptr(3600), 193 }, { 194 Quantile: float64ptr(0.99), 195 Value: float64ptr(3600), 196 }}, 197 }, 198 }} 199 for _, dm := range dtoMetrics { 200 var found bool 201 for i, m := range expected { 202 if !reflect.DeepEqual(dm, m) { 203 continue 204 } 205 expected = append(expected[:i], expected[i+1:]...) 206 found = true 207 break 208 } 209 if !found { 210 c.Errorf("metric %+v not expected", dm) 211 } 212 } 213 } 214 215 type netError struct { 216 error 217 timeout bool 218 temporary bool 219 } 220 221 func (e netError) Timeout() bool { 222 return e.timeout 223 } 224 225 func (e netError) Temporary() bool { 226 return e.temporary 227 }