dubbo.apache.org/dubbo-go/v3@v3.1.1/metrics/prometheus/rt_vec_test.go (about) 1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package prometheus 19 20 import ( 21 "reflect" 22 "sync" 23 "testing" 24 ) 25 26 import ( 27 prom "github.com/prometheus/client_golang/prometheus" 28 29 "github.com/stretchr/testify/assert" 30 ) 31 32 import ( 33 "dubbo.apache.org/dubbo-go/v3/metrics/util/aggregate" 34 ) 35 36 func TestRtVecCollect(t *testing.T) { 37 opts := &RtOpts{ 38 Name: "request_num", 39 bucketNum: 10, 40 timeWindowSeconds: 120, 41 Help: "Request cost", 42 } 43 labels := []string{"app", "version"} 44 vecs := [2]*RtVec{NewRtVec(opts, labels), NewAggRtVec(opts, labels)} 45 for _, r := range vecs { 46 r.With(map[string]string{"app": "dubbo", "version": "1.0.0"}).Observe(100) 47 ch := make(chan prom.Metric, len(r.metrics)) 48 r.Collect(ch) 49 close(ch) 50 assert.Equal(t, len(ch), len(r.metrics)) 51 for _, m := range r.metrics { 52 metric, ok := <-ch 53 if !ok { 54 t.Error("not enough metrics") 55 } else { 56 str := metric.Desc().String() 57 assert.Contains(t, str, m.nameSuffix) 58 assert.Contains(t, str, m.helpPrefix) 59 assert.Contains(t, str, "app") 60 assert.Contains(t, str, "version") 61 } 62 } 63 } 64 } 65 66 func TestRtVecDescribe(t *testing.T) { 67 opts := &RtOpts{ 68 Name: "request_num", 69 bucketNum: 10, 70 timeWindowSeconds: 120, 71 Help: "Request cost", 72 } 73 labels := []string{"app", "version"} 74 vecs := [2]*RtVec{NewRtVec(opts, labels), NewAggRtVec(opts, labels)} 75 for _, r := range vecs { 76 ch := make(chan *prom.Desc, len(r.metrics)) 77 r.Describe(ch) 78 close(ch) 79 assert.Equal(t, len(ch), len(r.metrics)) 80 for _, m := range r.metrics { 81 desc, ok := <-ch 82 if !ok { 83 t.Error(t, "not enough desc") 84 } else { 85 str := desc.String() 86 assert.Contains(t, str, m.nameSuffix) 87 assert.Contains(t, str, m.helpPrefix) 88 assert.Contains(t, str, "app") 89 assert.Contains(t, str, "version") 90 } 91 } 92 } 93 } 94 95 func TestValueObserve(t *testing.T) { 96 rts := []*Rt{ 97 { 98 tags: map[string]string{}, 99 obs: &aggResult{agg: aggregate.NewTimeWindowAggregator(10, 10)}, 100 }, 101 { 102 tags: map[string]string{}, 103 obs: &valueResult{val: aggregate.NewResult()}, 104 }, 105 } 106 want := &aggregate.Result{ 107 Avg: 1, 108 Min: 1, 109 Max: 1, 110 Count: 1, 111 Total: 1, 112 Last: 1, 113 } 114 for i, v := range rts { 115 v.Observe(float64(1)) 116 r := v.obs.result() 117 if i == 0 { 118 r.Last = 1 // agg result no Last, value is NaN 119 } 120 if !reflect.DeepEqual(r, want) { 121 t.Errorf("Result() = %v, want %v", r, want) 122 } 123 } 124 } 125 126 func TestRtVecWith(t *testing.T) { 127 opts := &RtOpts{ 128 Name: "request_num", 129 bucketNum: 10, 130 timeWindowSeconds: 120, 131 Help: "Request cost", 132 } 133 labels := []string{"app", "version"} 134 vecs := [2]*RtVec{NewRtVec(opts, labels), NewAggRtVec(opts, labels)} 135 tags := map[string]string{"app": "dubbo", "version": "1.0.0"} 136 for _, r := range vecs { 137 first := r.With(tags) 138 second := r.With(tags) 139 assert.True(t, first == second) // init once 140 } 141 } 142 143 func TestRtVecWithConcurrent(t *testing.T) { 144 opts := &RtOpts{ 145 Name: "request_num", 146 bucketNum: 10, 147 timeWindowSeconds: 120, 148 Help: "Request cost", 149 } 150 labels := []string{"app", "version"} 151 labelValues := map[string]string{"app": "dubbo", "version": "1.0.0"} 152 vecs := [2]*RtVec{NewRtVec(opts, labels), NewAggRtVec(opts, labels)} 153 for _, r := range vecs { 154 var wg sync.WaitGroup 155 for i := 0; i < 10; i++ { 156 wg.Add(1) 157 go func() { 158 r.With(labelValues).Observe(100) 159 wg.Done() 160 }() 161 } 162 wg.Wait() 163 res := r.With(labelValues).(*Rt).obs.result() 164 assert.True(t, res.Count == uint64(10)) 165 } 166 }