github.com/google/cadvisor@v0.49.1/collector/prometheus_collector_test.go (about) 1 // Copyright 2015 Google Inc. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package collector 16 17 import ( 18 "fmt" 19 "net/http" 20 "net/http/httptest" 21 "os" 22 "testing" 23 24 "github.com/stretchr/testify/assert" 25 "github.com/stretchr/testify/require" 26 27 containertest "github.com/google/cadvisor/container/testing" 28 v1 "github.com/google/cadvisor/info/v1" 29 ) 30 31 func TestPrometheus(t *testing.T) { 32 assert := assert.New(t) 33 34 // Create a prometheus collector using the config file 'sample_config_prometheus.json' 35 configFile, err := os.ReadFile("config/sample_config_prometheus.json") 36 assert.NoError(err) 37 containerHandler := containertest.NewMockContainerHandler("mockContainer") 38 collector, err := NewPrometheusCollector("Prometheus", configFile, 100, containerHandler, http.DefaultClient) 39 assert.NoError(err) 40 assert.Equal("Prometheus", collector.name) 41 assert.Equal("http://localhost:8080/metrics", collector.configFile.Endpoint.URL) 42 43 tempServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 44 45 text := `# HELP go_gc_duration_seconds A summary of the GC invocation durations. 46 # TYPE go_gc_duration_seconds summary 47 go_gc_duration_seconds{quantile="0"} 5.8348000000000004e-05 48 go_gc_duration_seconds{quantile="1"} 0.000499764 49 go_gc_duration_seconds_sum 1.7560473e+07 50 go_gc_duration_seconds_count 2693 51 # HELP go_goroutines Number of goroutines that currently exist. 52 # TYPE go_goroutines gauge 53 go_goroutines 16 54 # HELP empty_metric A metric without any values 55 # TYPE empty_metric counter 56 # HELP metric_with_spaces_in_label A metric with spaces in a label. 57 # TYPE metric_with_spaces_in_label gauge 58 metric_with_spaces_in_label{name="Network Agent"} 72 59 # HELP metric_with_multiple_labels A metric with multiple labels. 60 # TYPE metric_with_multiple_labels gauge 61 metric_with_multiple_labels{label1="One", label2="Two", label3="Three"} 81 62 ` 63 fmt.Fprintln(w, text) 64 })) 65 66 defer tempServer.Close() 67 68 collector.configFile.Endpoint.URL = tempServer.URL 69 70 var spec []v1.MetricSpec 71 require.NotPanics(t, func() { spec = collector.GetSpec() }) 72 assert.Len(spec, 4) 73 specNames := make(map[string]struct{}, 3) 74 for _, s := range spec { 75 specNames[s.Name] = struct{}{} 76 } 77 expectedSpecNames := map[string]struct{}{ 78 "go_gc_duration_seconds": {}, 79 "go_goroutines": {}, 80 "metric_with_spaces_in_label": {}, 81 "metric_with_multiple_labels": {}, 82 } 83 assert.Equal(expectedSpecNames, specNames) 84 85 metrics := map[string][]v1.MetricVal{} 86 _, metrics, errMetric := collector.Collect(metrics) 87 88 assert.NoError(errMetric) 89 90 gcDuration := metrics["go_gc_duration_seconds"] 91 assert.Equal(5.8348000000000004e-05, gcDuration[0].FloatValue) 92 assert.Equal("__name__=go_gc_duration_seconds\xffquantile=0", gcDuration[0].Label) 93 assert.Equal(0.000499764, gcDuration[1].FloatValue) 94 assert.Equal("__name__=go_gc_duration_seconds\xffquantile=1", gcDuration[1].Label) 95 gcDurationSum := metrics["go_gc_duration_seconds_sum"] 96 assert.Equal(1.7560473e+07, gcDurationSum[0].FloatValue) 97 assert.Equal("__name__=go_gc_duration_seconds_sum", gcDurationSum[0].Label) 98 gcDurationCount := metrics["go_gc_duration_seconds_count"] 99 assert.Equal(float64(2693), gcDurationCount[0].FloatValue) 100 assert.Equal("__name__=go_gc_duration_seconds_count", gcDurationCount[0].Label) 101 102 goRoutines := metrics["go_goroutines"] 103 assert.Equal(float64(16), goRoutines[0].FloatValue) 104 assert.Equal("__name__=go_goroutines", goRoutines[0].Label) 105 106 metricWithSpaces := metrics["metric_with_spaces_in_label"] 107 assert.Equal(float64(72), metricWithSpaces[0].FloatValue) 108 assert.Equal("__name__=metric_with_spaces_in_label\xffname=Network Agent", metricWithSpaces[0].Label) 109 110 metricWithMultipleLabels := metrics["metric_with_multiple_labels"] 111 assert.Equal(float64(81), metricWithMultipleLabels[0].FloatValue) 112 assert.Equal("__name__=metric_with_multiple_labels\xfflabel1=One\xfflabel2=Two\xfflabel3=Three", metricWithMultipleLabels[0].Label) 113 } 114 115 func TestPrometheusEndpointConfig(t *testing.T) { 116 assert := assert.New(t) 117 118 //Create a prometheus collector using the config file 'sample_config_prometheus.json' 119 configFile, err := os.ReadFile("config/sample_config_prometheus_endpoint_config.json") 120 assert.NoError(err) 121 containerHandler := containertest.NewMockContainerHandler("mockContainer") 122 containerHandler.On("GetContainerIPAddress").Return( 123 "222.222.222.222", 124 ) 125 126 collector, err := NewPrometheusCollector("Prometheus", configFile, 100, containerHandler, http.DefaultClient) 127 assert.NoError(err) 128 assert.Equal(collector.name, "Prometheus") 129 assert.Equal(collector.configFile.Endpoint.URL, "http://222.222.222.222:8081/METRICS") 130 } 131 132 func TestPrometheusShortResponse(t *testing.T) { 133 assert := assert.New(t) 134 135 // Create a prometheus collector using the config file 'sample_config_prometheus.json' 136 configFile, err := os.ReadFile("config/sample_config_prometheus.json") 137 assert.NoError(err) 138 containerHandler := containertest.NewMockContainerHandler("mockContainer") 139 collector, err := NewPrometheusCollector("Prometheus", configFile, 100, containerHandler, http.DefaultClient) 140 assert.NoError(err) 141 assert.Equal(collector.name, "Prometheus") 142 assert.Equal(collector.configFile.Endpoint.URL, "http://localhost:8080/metrics") 143 144 tempServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 145 text := "# HELP empty_metric A metric without any values" 146 fmt.Fprint(w, text) 147 })) 148 149 defer tempServer.Close() 150 151 collector.configFile.Endpoint.URL = tempServer.URL 152 153 assert.NotPanics(func() { collector.GetSpec() }) 154 } 155 156 func TestPrometheusMetricCountLimit(t *testing.T) { 157 assert := assert.New(t) 158 159 // Create a prometheus collector using the config file 'sample_config_prometheus.json' 160 configFile, err := os.ReadFile("config/sample_config_prometheus.json") 161 assert.NoError(err) 162 containerHandler := containertest.NewMockContainerHandler("mockContainer") 163 collector, err := NewPrometheusCollector("Prometheus", configFile, 10, containerHandler, http.DefaultClient) 164 assert.NoError(err) 165 assert.Equal(collector.name, "Prometheus") 166 assert.Equal(collector.configFile.Endpoint.URL, "http://localhost:8080/metrics") 167 168 tempServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 169 for i := 0; i < 30; i++ { 170 fmt.Fprintf(w, "# HELP m%d Number of goroutines that currently exist.\n", i) 171 fmt.Fprintf(w, "# TYPE m%d gauge\n", i) 172 fmt.Fprintf(w, "m%d %d", i, i) 173 } 174 })) 175 defer tempServer.Close() 176 177 collector.configFile.Endpoint.URL = tempServer.URL 178 metrics := map[string][]v1.MetricVal{} 179 _, result, errMetric := collector.Collect(metrics) 180 181 assert.Error(errMetric) 182 assert.Equal(len(metrics), 0) 183 assert.Nil(result) 184 } 185 186 func TestPrometheusFiltersMetrics(t *testing.T) { 187 assert := assert.New(t) 188 189 // Create a prometheus collector using the config file 'sample_config_prometheus_filtered.json' 190 configFile, err := os.ReadFile("config/sample_config_prometheus_filtered.json") 191 assert.NoError(err) 192 containerHandler := containertest.NewMockContainerHandler("mockContainer") 193 collector, err := NewPrometheusCollector("Prometheus", configFile, 100, containerHandler, http.DefaultClient) 194 assert.NoError(err) 195 assert.Equal(collector.name, "Prometheus") 196 assert.Equal(collector.configFile.Endpoint.URL, "http://localhost:8080/metrics") 197 198 tempServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 199 200 text := `# HELP go_gc_duration_seconds A summary of the GC invocation durations. 201 # TYPE go_gc_duration_seconds summary 202 go_gc_duration_seconds{quantile="0"} 5.8348000000000004e-05 203 go_gc_duration_seconds{quantile="1"} 0.000499764 204 go_gc_duration_seconds_sum 1.7560473e+07 205 go_gc_duration_seconds_count 2693 206 # HELP go_goroutines Number of goroutines that currently exist. 207 # TYPE go_goroutines gauge 208 go_goroutines 16 209 ` 210 fmt.Fprintln(w, text) 211 })) 212 213 defer tempServer.Close() 214 215 collector.configFile.Endpoint.URL = tempServer.URL 216 metrics := map[string][]v1.MetricVal{} 217 _, metrics, errMetric := collector.Collect(metrics) 218 219 assert.NoError(errMetric) 220 assert.Len(metrics, 1) 221 222 goRoutines := metrics["go_goroutines"] 223 assert.Equal(goRoutines[0].FloatValue, float64(16)) 224 } 225 226 func TestPrometheusFiltersMetricsCountLimit(t *testing.T) { 227 assert := assert.New(t) 228 229 // Create a prometheus collector using the config file 'sample_config_prometheus_filtered.json' 230 configFile, err := os.ReadFile("config/sample_config_prometheus_filtered.json") 231 assert.NoError(err) 232 containerHandler := containertest.NewMockContainerHandler("mockContainer") 233 _, err = NewPrometheusCollector("Prometheus", configFile, 1, containerHandler, http.DefaultClient) 234 assert.Error(err) 235 }