github.com/openshift/installer@v1.4.17/pkg/metrics/builder/builder_test.go (about) 1 package builder 2 3 import ( 4 "fmt" 5 "reflect" 6 "sort" 7 "strings" 8 "testing" 9 10 "github.com/prometheus/client_golang/prometheus" 11 "github.com/stretchr/testify/assert" 12 ) 13 14 func getDescStruct(opts MetricOpts, labelKeyValues map[string]string) string { 15 lpStrings := make([]string, 0, len(labelKeyValues)) 16 for key, value := range labelKeyValues { 17 lpStrings = append(lpStrings, fmt.Sprintf("%s=%q", key, value)) 18 } 19 sort.Strings(lpStrings) 20 return fmt.Sprintf("Desc{fqName: %q, help: %q, constLabels: {%s}, variableLabels: %v}", 21 opts.Name, opts.Desc, strings.Join(lpStrings, ","), "{}") 22 } 23 24 func getCollectorDescription(collector prometheus.Collector) string { 25 switch reflect.TypeOf(collector).Elem().Name() { 26 case "histogram": 27 return collector.(prometheus.Histogram).Desc().String() 28 case "counter": 29 return collector.(prometheus.Counter).Desc().String() 30 default: 31 return "" 32 } 33 } 34 35 // TestNewMetricBuilder tests the Metric Builder initializer. 36 func TestMetricBuilder(t *testing.T) { 37 cases := []struct { 38 name string 39 expectedCollectorType string 40 opts MetricOpts 41 labelKeyValues map[string]string 42 value float64 43 expectedErrorMessage string 44 }{ 45 { 46 name: "Test histogram creation", 47 expectedCollectorType: "histogram", 48 opts: MetricOpts{ 49 Labels: []string{"test1", "test2"}, 50 Desc: "test histogram metrics", 51 Name: "test_histogram", 52 Buckets: []float64{10, 20, 30}, 53 MetricType: Histogram, 54 }, 55 labelKeyValues: map[string]string{"test1": "test1", "test2": "test2"}, 56 value: 0, 57 expectedErrorMessage: "", 58 }, 59 { 60 name: "Test invalid labels", 61 expectedCollectorType: "histogram", 62 opts: MetricOpts{ 63 Labels: nil, 64 Desc: "test metric", 65 Name: "test", 66 MetricType: "Histogram", 67 }, 68 labelKeyValues: map[string]string{"test1": "test1", "test2": "test2"}, 69 value: 0, 70 expectedErrorMessage: `labels cannot be empty`, 71 }, 72 { 73 name: "Test invalid name", 74 expectedCollectorType: "histogram", 75 opts: MetricOpts{ 76 Labels: []string{"test1", "test2"}, 77 Desc: "test metric", 78 Name: "", 79 MetricType: "Histogram", 80 }, 81 labelKeyValues: map[string]string{"test1": "test1", "test2": "test2"}, 82 value: 0, 83 expectedErrorMessage: `name cannot be empty`, 84 }, 85 { 86 name: "Test invalid metric type", 87 expectedCollectorType: "histogram", 88 opts: MetricOpts{ 89 Labels: []string{"test1", "test2"}, 90 Desc: "test metric", 91 Name: "test", 92 MetricType: "", 93 }, 94 labelKeyValues: map[string]string{"test1": "test1", "test2": "test2"}, 95 value: 0, 96 expectedErrorMessage: `metricType cannot be empty`, 97 }, 98 } 99 for _, tc := range cases { 100 t.Run(tc.name, func(t *testing.T) { 101 _, err := NewMetricBuilder(tc.opts, tc.value, tc.labelKeyValues) 102 if tc.expectedErrorMessage == "" { 103 assert.NoError(t, err, "expected successful builder creation") 104 } else { 105 assert.Error(t, err, "expected builder creation failure but builder was created") 106 assert.EqualError(t, err, tc.expectedErrorMessage) 107 } 108 }) 109 } 110 } 111 112 // TestMetricBuilderCollector tests the PromCollector function. 113 func TestMetricBuilderCollector(t *testing.T) { 114 cases := []struct { 115 name string 116 expectedCollectorType string 117 opts MetricOpts 118 labelKeyValues map[string]string 119 value float64 120 expectedErrorMessage string 121 }{ 122 { 123 name: "Test histogram creation", 124 expectedCollectorType: "histogram", 125 opts: MetricOpts{ 126 Labels: []string{"test1", "test2"}, 127 Desc: "test histogram metrics", 128 Name: "test_histogram", 129 Buckets: []float64{10, 20, 30}, 130 MetricType: Histogram, 131 }, 132 labelKeyValues: map[string]string{"test1": "test1", "test2": "test2"}, 133 value: 0, 134 expectedErrorMessage: "", 135 }, 136 { 137 name: "Test counter creation", 138 expectedCollectorType: "counter", 139 opts: MetricOpts{ 140 Labels: []string{"test1", "test2"}, 141 Desc: "test modification metric", 142 Name: "test_modification", 143 MetricType: Counter, 144 }, 145 labelKeyValues: map[string]string{"test1": "test1", "test2": "test2"}, 146 expectedErrorMessage: "", 147 }, 148 { 149 name: "Test empty label values", 150 expectedCollectorType: "counter", 151 opts: MetricOpts{ 152 Labels: []string{"test1", "test2"}, 153 Desc: "test modification metric", 154 Name: "test_modification", 155 MetricType: Counter, 156 }, 157 labelKeyValues: nil, 158 value: 0, 159 expectedErrorMessage: "", 160 }, 161 { 162 name: "Test invalid metricType", 163 expectedCollectorType: "Linear", 164 opts: MetricOpts{ 165 Labels: []string{"test1", "test2"}, 166 Desc: "test metric", 167 Name: "test", 168 MetricType: "Linear", 169 }, 170 labelKeyValues: map[string]string{"test1": "test1", "test2": "test2"}, 171 value: 0, 172 expectedErrorMessage: `invalid metric builder type "Linear". cannot create collector`, 173 }, 174 } 175 for _, tc := range cases { 176 t.Run(tc.name, func(t *testing.T) { 177 metricBuilder, err := NewMetricBuilder(tc.opts, tc.value, tc.labelKeyValues) 178 if !assert.NoError(t, err, "error constructing new metric builder") { 179 return 180 } 181 collector, err := metricBuilder.PromCollector() 182 if tc.expectedErrorMessage == "" { 183 assert.NoError(t, err, "expected successful collector creation") 184 assert.EqualValues(t, tc.expectedCollectorType, reflect.TypeOf(collector).Elem().Name()) 185 expectedString := getDescStruct(tc.opts, tc.labelKeyValues) 186 assert.EqualValues(t, expectedString, getCollectorDescription(collector)) 187 } else { 188 assert.Error(t, err, "expected collector creation failure but collector was created") 189 assert.EqualError(t, err, tc.expectedErrorMessage) 190 } 191 }) 192 } 193 } 194 195 // TestNewMetricBuilder tests the Metric Builder initializer. 196 func TestNewMetricBuilder(t *testing.T) { 197 opts := MetricOpts{ 198 Labels: []string{"test1", "test2", "test3"}, 199 Desc: "test metric", 200 Name: "test", 201 Buckets: []float64{10, 20, 30}, 202 MetricType: Histogram, 203 } 204 labelKeyValues := map[string]string{"test1": "test1", "test2": "test2"} 205 metricBuilder, err := NewMetricBuilder(opts, 10, labelKeyValues) 206 if err != nil { 207 assert.Failf(t, err.Error(), "error creating metric builder") 208 } else { 209 assert.EqualValues(t, metricBuilder.value, 10) 210 assert.EqualValues(t, metricBuilder.labels, opts.Labels) 211 assert.EqualValues(t, metricBuilder.labelKeyValues, labelKeyValues) 212 assert.EqualValues(t, metricBuilder.desc, opts.Desc) 213 assert.EqualValues(t, metricBuilder.name, opts.Name) 214 assert.EqualValues(t, metricBuilder.buckets, opts.Buckets) 215 assert.EqualValues(t, metricBuilder.metricType, Histogram) 216 } 217 metricBuilder.SetValue(10) 218 assert.EqualValues(t, 10, metricBuilder.value) 219 220 err = metricBuilder.AddLabelValue("test", "metric labels") 221 assert.Error(t, err, "expected error adding label") 222 _, found := metricBuilder.labelKeyValues["test"] 223 assert.False(t, found) 224 225 err = metricBuilder.AddLabelValue("test3", "metric labels") 226 if err != nil { 227 assert.Failf(t, err.Error(), "error adding label value") 228 } 229 _, found = metricBuilder.labelKeyValues["test3"] 230 assert.True(t, found) 231 }