~ubuntu-branches/debian/sid/golang-github-prometheus-client-golang/sid

« back to all changes in this revision

Viewing changes to prometheus/gauge_test.go

  • Committer: Package Import Robot
  • Author(s): Martín Ferrari
  • Date: 2016-08-18 12:06:03 UTC
  • Revision ID: package-import@ubuntu.com-20160818120603-xevgulhsaf9vktsr
Tags: upstream-0.8.0
Import upstream version 0.8.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2014 The Prometheus Authors
 
2
// Licensed under the Apache License, Version 2.0 (the "License");
 
3
// you may not use this file except in compliance with the License.
 
4
// You may obtain a copy of the License at
 
5
//
 
6
// http://www.apache.org/licenses/LICENSE-2.0
 
7
//
 
8
// Unless required by applicable law or agreed to in writing, software
 
9
// distributed under the License is distributed on an "AS IS" BASIS,
 
10
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
11
// See the License for the specific language governing permissions and
 
12
// limitations under the License.
 
13
 
 
14
package prometheus
 
15
 
 
16
import (
 
17
        "math"
 
18
        "math/rand"
 
19
        "sync"
 
20
        "testing"
 
21
        "testing/quick"
 
22
 
 
23
        dto "github.com/prometheus/client_model/go"
 
24
)
 
25
 
 
26
func listenGaugeStream(vals, result chan float64, done chan struct{}) {
 
27
        var sum float64
 
28
outer:
 
29
        for {
 
30
                select {
 
31
                case <-done:
 
32
                        close(vals)
 
33
                        for v := range vals {
 
34
                                sum += v
 
35
                        }
 
36
                        break outer
 
37
                case v := <-vals:
 
38
                        sum += v
 
39
                }
 
40
        }
 
41
        result <- sum
 
42
        close(result)
 
43
}
 
44
 
 
45
func TestGaugeConcurrency(t *testing.T) {
 
46
        it := func(n uint32) bool {
 
47
                mutations := int(n % 10000)
 
48
                concLevel := int(n%15 + 1)
 
49
 
 
50
                var start, end sync.WaitGroup
 
51
                start.Add(1)
 
52
                end.Add(concLevel)
 
53
 
 
54
                sStream := make(chan float64, mutations*concLevel)
 
55
                result := make(chan float64)
 
56
                done := make(chan struct{})
 
57
 
 
58
                go listenGaugeStream(sStream, result, done)
 
59
                go func() {
 
60
                        end.Wait()
 
61
                        close(done)
 
62
                }()
 
63
 
 
64
                gge := NewGauge(GaugeOpts{
 
65
                        Name: "test_gauge",
 
66
                        Help: "no help can be found here",
 
67
                })
 
68
                for i := 0; i < concLevel; i++ {
 
69
                        vals := make([]float64, mutations)
 
70
                        for j := 0; j < mutations; j++ {
 
71
                                vals[j] = rand.Float64() - 0.5
 
72
                        }
 
73
 
 
74
                        go func(vals []float64) {
 
75
                                start.Wait()
 
76
                                for _, v := range vals {
 
77
                                        sStream <- v
 
78
                                        gge.Add(v)
 
79
                                }
 
80
                                end.Done()
 
81
                        }(vals)
 
82
                }
 
83
                start.Done()
 
84
 
 
85
                if expected, got := <-result, math.Float64frombits(gge.(*value).valBits); math.Abs(expected-got) > 0.000001 {
 
86
                        t.Fatalf("expected approx. %f, got %f", expected, got)
 
87
                        return false
 
88
                }
 
89
                return true
 
90
        }
 
91
 
 
92
        if err := quick.Check(it, nil); err != nil {
 
93
                t.Fatal(err)
 
94
        }
 
95
}
 
96
 
 
97
func TestGaugeVecConcurrency(t *testing.T) {
 
98
        it := func(n uint32) bool {
 
99
                mutations := int(n % 10000)
 
100
                concLevel := int(n%15 + 1)
 
101
                vecLength := int(n%5 + 1)
 
102
 
 
103
                var start, end sync.WaitGroup
 
104
                start.Add(1)
 
105
                end.Add(concLevel)
 
106
 
 
107
                sStreams := make([]chan float64, vecLength)
 
108
                results := make([]chan float64, vecLength)
 
109
                done := make(chan struct{})
 
110
 
 
111
                for i := 0; i < vecLength; i++ {
 
112
                        sStreams[i] = make(chan float64, mutations*concLevel)
 
113
                        results[i] = make(chan float64)
 
114
                        go listenGaugeStream(sStreams[i], results[i], done)
 
115
                }
 
116
 
 
117
                go func() {
 
118
                        end.Wait()
 
119
                        close(done)
 
120
                }()
 
121
 
 
122
                gge := NewGaugeVec(
 
123
                        GaugeOpts{
 
124
                                Name: "test_gauge",
 
125
                                Help: "no help can be found here",
 
126
                        },
 
127
                        []string{"label"},
 
128
                )
 
129
                for i := 0; i < concLevel; i++ {
 
130
                        vals := make([]float64, mutations)
 
131
                        pick := make([]int, mutations)
 
132
                        for j := 0; j < mutations; j++ {
 
133
                                vals[j] = rand.Float64() - 0.5
 
134
                                pick[j] = rand.Intn(vecLength)
 
135
                        }
 
136
 
 
137
                        go func(vals []float64) {
 
138
                                start.Wait()
 
139
                                for i, v := range vals {
 
140
                                        sStreams[pick[i]] <- v
 
141
                                        gge.WithLabelValues(string('A' + pick[i])).Add(v)
 
142
                                }
 
143
                                end.Done()
 
144
                        }(vals)
 
145
                }
 
146
                start.Done()
 
147
 
 
148
                for i := range sStreams {
 
149
                        if expected, got := <-results[i], math.Float64frombits(gge.WithLabelValues(string('A'+i)).(*value).valBits); math.Abs(expected-got) > 0.000001 {
 
150
                                t.Fatalf("expected approx. %f, got %f", expected, got)
 
151
                                return false
 
152
                        }
 
153
                }
 
154
                return true
 
155
        }
 
156
 
 
157
        if err := quick.Check(it, nil); err != nil {
 
158
                t.Fatal(err)
 
159
        }
 
160
}
 
161
 
 
162
func TestGaugeFunc(t *testing.T) {
 
163
        gf := NewGaugeFunc(
 
164
                GaugeOpts{
 
165
                        Name:        "test_name",
 
166
                        Help:        "test help",
 
167
                        ConstLabels: Labels{"a": "1", "b": "2"},
 
168
                },
 
169
                func() float64 { return 3.1415 },
 
170
        )
 
171
 
 
172
        if expected, got := `Desc{fqName: "test_name", help: "test help", constLabels: {a="1",b="2"}, variableLabels: []}`, gf.Desc().String(); expected != got {
 
173
                t.Errorf("expected %q, got %q", expected, got)
 
174
        }
 
175
 
 
176
        m := &dto.Metric{}
 
177
        gf.Write(m)
 
178
 
 
179
        if expected, got := `label:<name:"a" value:"1" > label:<name:"b" value:"2" > gauge:<value:3.1415 > `, m.String(); expected != got {
 
180
                t.Errorf("expected %q, got %q", expected, got)
 
181
        }
 
182
}