1/* 2Copyright 2019 The Kubernetes Authors. 3 4Licensed under the Apache License, Version 2.0 (the "License"); 5you may not use this file except in compliance with the License. 6You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10Unless required by applicable law or agreed to in writing, software 11distributed under the License is distributed on an "AS IS" BASIS, 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13See the License for the specific language governing permissions and 14limitations under the License. 15*/ 16 17package metrics 18 19import ( 20 "bytes" 21 "testing" 22 23 "github.com/blang/semver" 24 "github.com/prometheus/common/expfmt" 25 "github.com/stretchr/testify/assert" 26 27 apimachineryversion "k8s.io/apimachinery/pkg/version" 28) 29 30func TestCounter(t *testing.T) { 31 var tests = []struct { 32 desc string 33 *CounterOpts 34 expectedMetricCount int 35 expectedHelp string 36 }{ 37 { 38 desc: "Test non deprecated", 39 CounterOpts: &CounterOpts{ 40 Namespace: "namespace", 41 Name: "metric_test_name", 42 Subsystem: "subsystem", 43 StabilityLevel: ALPHA, 44 Help: "counter help", 45 }, 46 expectedMetricCount: 1, 47 expectedHelp: "[ALPHA] counter help", 48 }, 49 { 50 desc: "Test deprecated", 51 CounterOpts: &CounterOpts{ 52 Namespace: "namespace", 53 Name: "metric_test_name", 54 Subsystem: "subsystem", 55 Help: "counter help", 56 StabilityLevel: ALPHA, 57 DeprecatedVersion: "1.15.0", 58 }, 59 expectedMetricCount: 1, 60 expectedHelp: "[ALPHA] (Deprecated since 1.15.0) counter help", 61 }, 62 { 63 desc: "Test hidden", 64 CounterOpts: &CounterOpts{ 65 Namespace: "namespace", 66 Name: "metric_test_name", 67 Subsystem: "subsystem", 68 Help: "counter help", 69 StabilityLevel: ALPHA, 70 DeprecatedVersion: "1.14.0", 71 }, 72 expectedMetricCount: 0, 73 }, 74 } 75 76 for _, test := range tests { 77 t.Run(test.desc, func(t *testing.T) { 78 registry := newKubeRegistry(apimachineryversion.Info{ 79 Major: "1", 80 Minor: "15", 81 GitVersion: "v1.15.0-alpha-1.12345", 82 }) 83 // c is a pointer to a Counter 84 c := NewCounter(test.CounterOpts) 85 registry.MustRegister(c) 86 // mfs is a pointer to a dto.MetricFamily slice 87 mfs, err := registry.Gather() 88 var buf bytes.Buffer 89 enc := expfmt.NewEncoder(&buf, "text/plain; version=0.0.4; charset=utf-8") 90 assert.Equalf(t, test.expectedMetricCount, len(mfs), "Got %v metrics, Want: %v metrics", len(mfs), test.expectedMetricCount) 91 assert.Nil(t, err, "Gather failed %v", err) 92 for _, metric := range mfs { 93 err := enc.Encode(metric) 94 assert.Nil(t, err, "Unexpected err %v in encoding the metric", err) 95 assert.Equalf(t, test.expectedHelp, metric.GetHelp(), "Got %s as help message, want %s", metric.GetHelp(), test.expectedHelp) 96 } 97 98 // increment the counter N number of times and verify that the metric retains the count correctly 99 numberOfTimesToIncrement := 3 100 for i := 0; i < numberOfTimesToIncrement; i++ { 101 c.Inc() 102 } 103 mfs, err = registry.Gather() 104 assert.Nil(t, err, "Gather failed %v", err) 105 106 for _, mf := range mfs { 107 mfMetric := mf.GetMetric() 108 for _, m := range mfMetric { 109 assert.Equalf(t, numberOfTimesToIncrement, int(m.GetCounter().GetValue()), "Got %v, wanted %v as the count", m.GetCounter().GetValue(), numberOfTimesToIncrement) 110 } 111 } 112 }) 113 } 114} 115 116func TestCounterVec(t *testing.T) { 117 var tests = []struct { 118 desc string 119 *CounterOpts 120 labels []string 121 registryVersion *semver.Version 122 expectedMetricFamilyCount int 123 expectedHelp string 124 }{ 125 { 126 desc: "Test non deprecated", 127 CounterOpts: &CounterOpts{ 128 Namespace: "namespace", 129 Name: "metric_test_name", 130 Subsystem: "subsystem", 131 Help: "counter help", 132 }, 133 labels: []string{"label_a", "label_b"}, 134 expectedMetricFamilyCount: 1, 135 expectedHelp: "[ALPHA] counter help", 136 }, 137 { 138 desc: "Test deprecated", 139 CounterOpts: &CounterOpts{ 140 Namespace: "namespace", 141 Name: "metric_test_name", 142 Subsystem: "subsystem", 143 Help: "counter help", 144 DeprecatedVersion: "1.15.0", 145 }, 146 labels: []string{"label_a", "label_b"}, 147 expectedMetricFamilyCount: 1, 148 expectedHelp: "[ALPHA] (Deprecated since 1.15.0) counter help", 149 }, 150 { 151 desc: "Test hidden", 152 CounterOpts: &CounterOpts{ 153 Namespace: "namespace", 154 Name: "metric_test_name", 155 Subsystem: "subsystem", 156 Help: "counter help", 157 DeprecatedVersion: "1.14.0", 158 }, 159 labels: []string{"label_a", "label_b"}, 160 expectedMetricFamilyCount: 0, 161 expectedHelp: "counter help", 162 }, 163 { 164 desc: "Test alpha", 165 CounterOpts: &CounterOpts{ 166 StabilityLevel: ALPHA, 167 Namespace: "namespace", 168 Name: "metric_test_name", 169 Subsystem: "subsystem", 170 Help: "counter help", 171 }, 172 labels: []string{"label_a", "label_b"}, 173 expectedMetricFamilyCount: 1, 174 expectedHelp: "[ALPHA] counter help", 175 }, 176 } 177 178 for _, test := range tests { 179 t.Run(test.desc, func(t *testing.T) { 180 registry := newKubeRegistry(apimachineryversion.Info{ 181 Major: "1", 182 Minor: "15", 183 GitVersion: "v1.15.0-alpha-1.12345", 184 }) 185 c := NewCounterVec(test.CounterOpts, test.labels) 186 registry.MustRegister(c) 187 c.WithLabelValues("1", "2").Inc() 188 mfs, err := registry.Gather() 189 assert.Equalf(t, test.expectedMetricFamilyCount, len(mfs), "Got %v metric families, Want: %v metric families", len(mfs), test.expectedMetricFamilyCount) 190 assert.Nil(t, err, "Gather failed %v", err) 191 192 // this no-opts here when there are no metric families (i.e. when the metric is hidden) 193 for _, mf := range mfs { 194 assert.Equalf(t, 1, len(mf.GetMetric()), "Got %v metrics, wanted 1 as the count", len(mf.GetMetric())) 195 assert.Equalf(t, test.expectedHelp, mf.GetHelp(), "Got %s as help message, want %s", mf.GetHelp(), test.expectedHelp) 196 } 197 198 // let's increment the counter and verify that the metric still works 199 c.WithLabelValues("1", "3").Inc() 200 c.WithLabelValues("2", "3").Inc() 201 mfs, err = registry.Gather() 202 assert.Nil(t, err, "Gather failed %v", err) 203 204 // this no-opts here when there are no metric families (i.e. when the metric is hidden) 205 for _, mf := range mfs { 206 assert.Equalf(t, 3, len(mf.GetMetric()), "Got %v metrics, wanted 3 as the count", len(mf.GetMetric())) 207 } 208 }) 209 } 210} 211