Skip to content

Commit

Permalink
test(outputs.prometheus_client): Add tests for content-type header (i…
Browse files Browse the repository at this point in the history
  • Loading branch information
srebhan authored Mar 3, 2025
1 parent 6d528f2 commit ccf5761
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 56 deletions.
26 changes: 13 additions & 13 deletions plugins/inputs/prometheus/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,19 +127,6 @@ and `bearer_token_string` option. See the
# Default is 60 minutes.
# cache_refresh_interval = 60

## Scrape Services available in Consul Catalog
# [inputs.prometheus.consul]
# enabled = true
# agent = "http://localhost:8500"
# query_interval = "5m"

# [[inputs.prometheus.consul.query]]
# name = "a service name"
# tag = "a service tag"
# url = 'http://{{if ne .ServiceAddress ""}}{{.ServiceAddress}}{{else}}{{.Address}}{{end}}:{{.ServicePort}}/{{with .ServiceMeta.metrics_path}}{{.}}{{else}}metrics{{end}}'
# [inputs.prometheus.consul.query.tags]
# host = "{{.Node}}"

## Use bearer token for authorization. ('bearer_token' takes priority)
# bearer_token = "/path/to/bearer/token"
## OR
Expand Down Expand Up @@ -186,6 +173,19 @@ and `bearer_token_string` option. See the
## This option allows you to report the status of prometheus requests.
# enable_request_metrics = false

## Scrape Services available in Consul Catalog
# [inputs.prometheus.consul]
# enabled = true
# agent = "http://localhost:8500"
# query_interval = "5m"

# [[inputs.prometheus.consul.query]]
# name = "a service name"
# tag = "a service tag"
# url = 'http://{{if ne .ServiceAddress ""}}{{.ServiceAddress}}{{else}}{{.Address}}{{end}}:{{.ServicePort}}/{{with .ServiceMeta.metrics_path}}{{.}}{{else}}metrics{{end}}'
# [inputs.prometheus.consul.query.tags]
# host = "{{.Node}}"

## Control pod scraping based on pod namespace annotations
## Pass and drop here act like tagpass and tagdrop, but instead
## of filtering metrics they filters pod candidates for scraping
Expand Down
26 changes: 13 additions & 13 deletions plugins/inputs/prometheus/sample.conf
Original file line number Diff line number Diff line change
Expand Up @@ -102,19 +102,6 @@
# Default is 60 minutes.
# cache_refresh_interval = 60

## Scrape Services available in Consul Catalog
# [inputs.prometheus.consul]
# enabled = true
# agent = "http://localhost:8500"
# query_interval = "5m"

# [[inputs.prometheus.consul.query]]
# name = "a service name"
# tag = "a service tag"
# url = 'http://{{if ne .ServiceAddress ""}}{{.ServiceAddress}}{{else}}{{.Address}}{{end}}:{{.ServicePort}}/{{with .ServiceMeta.metrics_path}}{{.}}{{else}}metrics{{end}}'
# [inputs.prometheus.consul.query.tags]
# host = "{{.Node}}"

## Use bearer token for authorization. ('bearer_token' takes priority)
# bearer_token = "/path/to/bearer/token"
## OR
Expand Down Expand Up @@ -161,6 +148,19 @@
## This option allows you to report the status of prometheus requests.
# enable_request_metrics = false

## Scrape Services available in Consul Catalog
# [inputs.prometheus.consul]
# enabled = true
# agent = "http://localhost:8500"
# query_interval = "5m"

# [[inputs.prometheus.consul.query]]
# name = "a service name"
# tag = "a service tag"
# url = 'http://{{if ne .ServiceAddress ""}}{{.ServiceAddress}}{{else}}{{.Address}}{{end}}:{{.ServicePort}}/{{with .ServiceMeta.metrics_path}}{{.}}{{else}}metrics{{end}}'
# [inputs.prometheus.consul.query.tags]
# host = "{{.Node}}"

## Control pod scraping based on pod namespace annotations
## Pass and drop here act like tagpass and tagdrop, but instead
## of filtering metrics they filters pod candidates for scraping
Expand Down
123 changes: 123 additions & 0 deletions plugins/outputs/prometheus_client/prometheus_client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package prometheus_client

import (
"fmt"
"io"
"net/http"
"net/url"
"strings"
"testing"

"github.com/stretchr/testify/require"

"github.com/influxdata/telegraf/testutil"
)

func TestLandingPage(t *testing.T) {
output := PrometheusClient{
Listen: ":0",
CollectorsExclude: []string{"process"},
MetricVersion: 1,
Log: &testutil.Logger{Name: "outputs.prometheus_client"},
}
expected := "Telegraf Output Plugin: Prometheus Client"

require.NoError(t, output.Init())
require.NoError(t, output.Connect())

u, err := url.Parse(fmt.Sprintf("http://%s/", output.url.Host))
require.NoError(t, err)

resp, err := http.Get(u.String())
require.NoError(t, err)
defer resp.Body.Close()

actual, err := io.ReadAll(resp.Body)
require.NoError(t, err)
require.Equal(t, expected, strings.TrimSpace(string(actual)))
}

func TestFormatHeader(t *testing.T) {
tests := []struct {
name string
accept string
expected string
}{
{
name: "invalid accept ",
accept: "applications/json",
expected: "text/plain; version=0.0.4; charset=utf-8; escaping=underscores",
},
{
name: "no accept header",
expected: "text/plain; version=0.0.4; charset=utf-8; escaping=underscores",
},
{
name: "text no version",
accept: "text/plain",
expected: "text/plain; version=0.0.4; charset=utf-8; escaping=underscores",
},
{
name: "text with version 0.0.4",
accept: "text/plain; version=0.0.4",
expected: "text/plain; version=0.0.4; charset=utf-8; escaping=underscores",
},
{
name: "protobuf text format",
accept: "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=text",
expected: "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=text; escaping=underscores",
},
{
name: "protobuf compact text format",
accept: "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=compact-text",
expected: "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=compact-text; escaping=underscores",
},
{
name: "protobuf delimited format",
accept: "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited",
expected: "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited; escaping=underscores",
},
{
name: "multiple accept preferring protobuf",
accept: "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited, text/plain",
expected: "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited; escaping=underscores",
},
{
name: "multiple accept preferring text",
accept: "text/plain, application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited",
expected: "text/plain; version=0.0.4; charset=utf-8; escaping=underscores",
},
}

// Setup the plugin
plugin := PrometheusClient{
Listen: ":0",
Log: testutil.Logger{Name: "outputs.prometheus_client"},
}
require.NoError(t, plugin.Init())
require.NoError(t, plugin.Connect())

// Get the plugin's address so we can send data to it
addr := fmt.Sprintf("http://%s/metrics", plugin.url.Host)

// Run the actual tests
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Construct a request with the given "Accept" header
req, err := http.NewRequest("GET", addr, nil)
require.NoError(t, err)
if tt.accept != "" {
req.Header.Add("Accept", tt.accept)
}

// Get the metrics
resp, err := http.DefaultClient.Do(req)
require.NoError(t, err)
defer resp.Body.Close()

// Test the result
require.NotEmpty(t, resp.Body)
require.Equal(t, tt.expected, resp.Header.Get("Content-Type"))
})
}
}
30 changes: 0 additions & 30 deletions plugins/outputs/prometheus_client/prometheus_client_v1_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"io"
"net/http"
"net/http/httptest"
"net/url"
"regexp"
"strings"
"testing"
Expand Down Expand Up @@ -496,32 +495,3 @@ rpc_duration_seconds_count 2693
})
}
}

func TestLandingPage(t *testing.T) {
logger := testutil.Logger{Name: "outputs.prometheus_client"}
output := PrometheusClient{
Listen: ":0",
CollectorsExclude: []string{"process"},
MetricVersion: 1,
Log: logger,
}
expected := "Telegraf Output Plugin: Prometheus Client"

err := output.Init()
require.NoError(t, err)

err = output.Connect()
require.NoError(t, err)

u, err := url.Parse(fmt.Sprintf("http://%s/", output.url.Host))
require.NoError(t, err)

resp, err := http.Get(u.String())
require.NoError(t, err)
defer resp.Body.Close()

actual, err := io.ReadAll(resp.Body)
require.NoError(t, err)

require.Equal(t, expected, strings.TrimSpace(string(actual)))
}

0 comments on commit ccf5761

Please sign in to comment.