telegraf/plugins/inputs/nginx_plus_api/nginx_plus_api_metrics_test.go

1336 lines
30 KiB
Go

package nginx_plus_api
import (
"fmt"
"net"
"net/http"
"net/http/httptest"
"net/url"
"testing"
"github.com/influxdata/telegraf/testutil"
"github.com/stretchr/testify/require"
)
const processesPayload = `
{
"respawned": 0
}
`
const connectionsPayload = `
{
"accepted": 1234567890000,
"dropped": 2345678900000,
"active": 345,
"idle": 567
}
`
const sslPayload = `
{
"handshakes": 79572,
"handshakes_failed": 21025,
"session_reuses": 15762
}
`
const resolverZonesPayload = `
{
"resolver_zone1": {
"requests": {
"name": 25460,
"srv": 130,
"addr": 2580
},
"responses": {
"noerror": 26499,
"formerr": 0,
"servfail": 3,
"nxdomain": 0,
"notimp": 0,
"refused": 0,
"timedout": 243,
"unknown": 478
}
},
"resolver_zone2": {
"requests": {
"name": 325460,
"srv": 1130,
"addr": 12580
},
"responses": {
"noerror": 226499,
"formerr": 0,
"servfail": 283,
"nxdomain": 0,
"notimp": 0,
"refused": 0,
"timedout": 743,
"unknown": 1478
}
}
}
`
const httpRequestsPayload = `
{
"total": 10624511,
"current": 4
}
`
const httpServerZonesPayload = `
{
"site1": {
"processing": 2,
"requests": 736395,
"responses": {
"1xx": 0,
"2xx": 727290,
"3xx": 4614,
"4xx": 934,
"5xx": 1535,
"total": 734373
},
"discarded": 2020,
"received": 180157219,
"sent": 20183175459
},
"site2": {
"processing": 1,
"requests": 185307,
"responses": {
"1xx": 0,
"2xx": 112674,
"3xx": 45383,
"4xx": 2504,
"5xx": 4419,
"total": 164980
},
"discarded": 20326,
"received": 51575327,
"sent": 2983241510
}
}
`
const httpLocationZonesPayload = `
{
"site1": {
"requests": 736395,
"responses": {
"1xx": 0,
"2xx": 727290,
"3xx": 4614,
"4xx": 934,
"5xx": 1535,
"total": 734373
},
"discarded": 2020,
"received": 180157219,
"sent": 20183175459
},
"site2": {
"requests": 185307,
"responses": {
"1xx": 0,
"2xx": 112674,
"3xx": 45383,
"4xx": 2504,
"5xx": 4419,
"total": 164980
},
"discarded": 20326,
"received": 51575327,
"sent": 2983241510
}
}
`
const httpUpstreamsPayload = `
{
"trac-backend": {
"peers": [
{
"id": 0,
"server": "10.0.0.1:8088",
"name": "10.0.0.1:8088",
"backup": false,
"weight": 5,
"state": "up",
"active": 0,
"requests": 667231,
"header_time": 20,
"response_time": 36,
"responses": {
"1xx": 0,
"2xx": 666310,
"3xx": 0,
"4xx": 915,
"5xx": 6,
"total": 667231
},
"sent": 251946292,
"received": 19222475454,
"fails": 0,
"unavail": 0,
"health_checks": {
"checks": 26214,
"fails": 0,
"unhealthy": 0,
"last_passed": true
},
"downtime": 0,
"downstart": {},
"selected": {}
},
{
"id": 1,
"server": "10.0.0.1:8089",
"name": "10.0.0.1:8089",
"backup": true,
"weight": 1,
"state": "unhealthy",
"active": 0,
"requests": 0,
"responses": {
"1xx": 0,
"2xx": 0,
"3xx": 0,
"4xx": 0,
"5xx": 0,
"total": 0
},
"sent": 0,
"received": 0,
"fails": 0,
"unavail": 0,
"health_checks": {
"checks": 26284,
"fails": 26284,
"unhealthy": 1,
"last_passed": false
},
"downtime": 262925617,
"downstart": {},
"selected": {}
}
],
"keepalive": 0,
"zombies": 0,
"zone": "trac-backend"
},
"hg-backend": {
"peers": [
{
"id": 0,
"server": "10.0.0.1:8088",
"name": "10.0.0.1:8088",
"backup": false,
"weight": 5,
"state": "up",
"active": 0,
"requests": 667231,
"header_time": 20,
"response_time": 36,
"responses": {
"1xx": 0,
"2xx": 666310,
"3xx": 0,
"4xx": 915,
"5xx": 6,
"total": 667231
},
"sent": 251946292,
"received": 19222475454,
"fails": 0,
"unavail": 0,
"health_checks": {
"checks": 26214,
"fails": 0,
"unhealthy": 0,
"last_passed": true
},
"downtime": 0,
"downstart": {},
"selected": {}
},
{
"id": 1,
"server": "10.0.0.1:8089",
"name": "10.0.0.1:8089",
"backup": true,
"weight": 1,
"state": "unhealthy",
"active": 0,
"requests": 0,
"responses": {
"1xx": 0,
"2xx": 0,
"3xx": 0,
"4xx": 0,
"5xx": 0,
"total": 0
},
"sent": 0,
"received": 0,
"fails": 0,
"unavail": 0,
"health_checks": {
"checks": 26284,
"fails": 26284,
"unhealthy": 1,
"last_passed": false
},
"downtime": 262925617,
"downstart": {},
"selected": {}
}
],
"keepalive": 0,
"zombies": 0,
"zone": "hg-backend"
}
}
`
const httpCachesPayload = `
{
"http-cache": {
"size": 530915328,
"max_size": 536870912,
"cold": false,
"hit": {
"responses": 254032,
"bytes": 6685627875
},
"stale": {
"responses": 0,
"bytes": 0
},
"updating": {
"responses": 0,
"bytes": 0
},
"revalidated": {
"responses": 0,
"bytes": 0
},
"miss": {
"responses": 1619201,
"bytes": 53841943822
},
"expired": {
"responses": 45859,
"bytes": 1656847080,
"responses_written": 44992,
"bytes_written": 1641825173
},
"bypass": {
"responses": 200187,
"bytes": 5510647548,
"responses_written": 200173,
"bytes_written": 44992
}
},
"frontend-cache": {
"size": 530915328,
"max_size": 536870912,
"cold": false,
"hit": {
"responses": 254032,
"bytes": 6685627875
},
"stale": {
"responses": 0,
"bytes": 0
},
"updating": {
"responses": 0,
"bytes": 0
},
"revalidated": {
"responses": 0,
"bytes": 0
},
"miss": {
"responses": 1619201,
"bytes": 53841943822
},
"expired": {
"responses": 45859,
"bytes": 1656847080,
"responses_written": 44992,
"bytes_written": 1641825173
},
"bypass": {
"responses": 200187,
"bytes": 5510647548,
"responses_written": 200173,
"bytes_written": 44992
}
}
}
`
const streamUpstreamsPayload = `
{
"mysql_backends": {
"peers": [
{
"id": 0,
"server": "10.0.0.1:12345",
"name": "10.0.0.1:12345",
"backup": false,
"weight": 5,
"state": "up",
"active": 0,
"max_conns": 30,
"connecions": 1231,
"sent": 251946292,
"received": 19222475454,
"fails": 0,
"unavail": 0,
"health_checks": {
"checks": 26214,
"fails": 0,
"unhealthy": 0,
"last_passed": true
},
"downtime": 0,
"downstart": {},
"selected": {}
},
{
"id": 1,
"server": "10.0.0.1:12346",
"name": "10.0.0.1:12346",
"backup": true,
"weight": 1,
"state": "unhealthy",
"active": 0,
"max_conns": 30,
"connections": 0,
"sent": 0,
"received": 0,
"fails": 0,
"unavail": 0,
"health_checks": {
"checks": 26284,
"fails": 26284,
"unhealthy": 1,
"last_passed": false
},
"downtime": 262925617,
"downstart": {},
"selected": {}
}
],
"zombies": 0,
"zone": "mysql_backends"
},
"dns": {
"peers": [
{
"id": 0,
"server": "10.0.0.1:12347",
"name": "10.0.0.1:12347",
"backup": false,
"weight": 5,
"state": "up",
"active": 0,
"max_conns": 30,
"connections": 667231,
"sent": 251946292,
"received": 19222475454,
"fails": 0,
"unavail": 0,
"health_checks": {
"checks": 26214,
"fails": 0,
"unhealthy": 0,
"last_passed": true
},
"downtime": 0,
"downstart": {},
"selected": {}
},
{
"id": 1,
"server": "10.0.0.1:12348",
"name": "10.0.0.1:12348",
"backup": true,
"weight": 1,
"state": "unhealthy",
"active": 0,
"connections": 0,
"max_conns": 30,
"sent": 0,
"received": 0,
"fails": 0,
"unavail": 0,
"health_checks": {
"checks": 26284,
"fails": 26284,
"unhealthy": 1,
"last_passed": false
},
"downtime": 262925617,
"downstart": {},
"selected": {}
}
],
"zombies": 0,
"zone": "dns"
}
}
`
const streamServerZonesPayload = `
{
"mysql-frontend": {
"processing": 2,
"connections": 270925,
"sessions": {
"2xx": 155564,
"4xx": 0,
"5xx": 0,
"total": 270925
},
"discarded": 0,
"received": 28988975,
"sent": 3879346317
},
"dns": {
"processing": 1,
"connections": 155569,
"sessions": {
"2xx": 155564,
"4xx": 0,
"5xx": 0,
"total": 155569
},
"discarded": 0,
"received": 4200363,
"sent": 20489184
}
}
`
func TestGatherProcessesMetrics(t *testing.T) {
ts, n := prepareEndpoint(t, processesPath, defaultApiVersion, processesPayload)
defer ts.Close()
var acc testutil.Accumulator
addr, host, port := prepareAddr(t, ts)
require.NoError(t, n.gatherProcessesMetrics(addr, &acc))
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_processes",
map[string]interface{}{
"respawned": int(0),
},
map[string]string{
"source": host,
"port": port,
})
}
func TestGatherConnectionsMetrics(t *testing.T) {
ts, n := prepareEndpoint(t, connectionsPath, defaultApiVersion, connectionsPayload)
defer ts.Close()
var acc testutil.Accumulator
addr, host, port := prepareAddr(t, ts)
require.NoError(t, n.gatherConnectionsMetrics(addr, &acc))
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_connections",
map[string]interface{}{
"accepted": int64(1234567890000),
"dropped": int64(2345678900000),
"active": int64(345),
"idle": int64(567),
},
map[string]string{
"source": host,
"port": port,
})
}
func TestGatherSslMetrics(t *testing.T) {
ts, n := prepareEndpoint(t, sslPath, defaultApiVersion, sslPayload)
defer ts.Close()
var acc testutil.Accumulator
addr, host, port := prepareAddr(t, ts)
require.NoError(t, n.gatherSslMetrics(addr, &acc))
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_ssl",
map[string]interface{}{
"handshakes": int64(79572),
"handshakes_failed": int64(21025),
"session_reuses": int64(15762),
},
map[string]string{
"source": host,
"port": port,
})
}
func TestGatherHttpRequestsMetrics(t *testing.T) {
ts, n := prepareEndpoint(t, httpRequestsPath, defaultApiVersion, httpRequestsPayload)
defer ts.Close()
var acc testutil.Accumulator
addr, host, port := prepareAddr(t, ts)
require.NoError(t, n.gatherHttpRequestsMetrics(addr, &acc))
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_http_requests",
map[string]interface{}{
"total": int64(10624511),
"current": int64(4),
},
map[string]string{
"source": host,
"port": port,
})
}
func TestGatherHttpServerZonesMetrics(t *testing.T) {
ts, n := prepareEndpoint(t, httpServerZonesPath, defaultApiVersion, httpServerZonesPayload)
defer ts.Close()
var acc testutil.Accumulator
addr, host, port := prepareAddr(t, ts)
require.NoError(t, n.gatherHttpServerZonesMetrics(addr, &acc))
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_http_server_zones",
map[string]interface{}{
"discarded": int64(2020),
"processing": int(2),
"received": int64(180157219),
"requests": int64(736395),
"responses_1xx": int64(0),
"responses_2xx": int64(727290),
"responses_3xx": int64(4614),
"responses_4xx": int64(934),
"responses_5xx": int64(1535),
"responses_total": int64(734373),
"sent": int64(20183175459),
},
map[string]string{
"source": host,
"port": port,
"zone": "site1",
})
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_http_server_zones",
map[string]interface{}{
"discarded": int64(20326),
"processing": int(1),
"received": int64(51575327),
"requests": int64(185307),
"responses_1xx": int64(0),
"responses_2xx": int64(112674),
"responses_3xx": int64(45383),
"responses_4xx": int64(2504),
"responses_5xx": int64(4419),
"responses_total": int64(164980),
"sent": int64(2983241510),
},
map[string]string{
"source": host,
"port": port,
"zone": "site2",
})
}
func TestGatherHttpLocationZonesMetrics(t *testing.T) {
ts, n := prepareEndpoint(t, httpLocationZonesPath, defaultApiVersion, httpLocationZonesPayload)
defer ts.Close()
var acc testutil.Accumulator
addr, host, port := prepareAddr(t, ts)
require.NoError(t, n.gatherHttpLocationZonesMetrics(addr, &acc))
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_http_location_zones",
map[string]interface{}{
"discarded": int64(2020),
"received": int64(180157219),
"requests": int64(736395),
"responses_1xx": int64(0),
"responses_2xx": int64(727290),
"responses_3xx": int64(4614),
"responses_4xx": int64(934),
"responses_5xx": int64(1535),
"responses_total": int64(734373),
"sent": int64(20183175459),
},
map[string]string{
"source": host,
"port": port,
"zone": "site1",
})
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_http_location_zones",
map[string]interface{}{
"discarded": int64(20326),
"received": int64(51575327),
"requests": int64(185307),
"responses_1xx": int64(0),
"responses_2xx": int64(112674),
"responses_3xx": int64(45383),
"responses_4xx": int64(2504),
"responses_5xx": int64(4419),
"responses_total": int64(164980),
"sent": int64(2983241510),
},
map[string]string{
"source": host,
"port": port,
"zone": "site2",
})
}
func TestGatherHttpUpstreamsMetrics(t *testing.T) {
ts, n := prepareEndpoint(t, httpUpstreamsPath, defaultApiVersion, httpUpstreamsPayload)
defer ts.Close()
var acc testutil.Accumulator
addr, host, port := prepareAddr(t, ts)
require.NoError(t, n.gatherHttpUpstreamsMetrics(addr, &acc))
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_http_upstreams",
map[string]interface{}{
"keepalive": int(0),
"zombies": int(0),
},
map[string]string{
"source": host,
"port": port,
"upstream": "trac-backend",
})
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_http_upstreams",
map[string]interface{}{
"keepalive": int(0),
"zombies": int(0),
},
map[string]string{
"source": host,
"port": port,
"upstream": "hg-backend",
})
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_http_upstream_peers",
map[string]interface{}{
"active": int(0),
"backup": false,
"downtime": int64(0),
"fails": int64(0),
"header_time": int64(20),
"healthchecks_checks": int64(26214),
"healthchecks_fails": int64(0),
"healthchecks_last_passed": true,
"healthchecks_unhealthy": int64(0),
"received": int64(19222475454),
"requests": int64(667231),
"response_time": int64(36),
"responses_1xx": int64(0),
"responses_2xx": int64(666310),
"responses_3xx": int64(0),
"responses_4xx": int64(915),
"responses_5xx": int64(6),
"responses_total": int64(667231),
"sent": int64(251946292),
"state": "up",
"unavail": int64(0),
"weight": int(5),
},
map[string]string{
"source": host,
"port": port,
"upstream": "trac-backend",
"upstream_address": "10.0.0.1:8088",
"id": "0",
})
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_http_upstream_peers",
map[string]interface{}{
"active": int(0),
"backup": true,
"downtime": int64(262925617),
"fails": int64(0),
"healthchecks_checks": int64(26284),
"healthchecks_fails": int64(26284),
"healthchecks_last_passed": false,
"healthchecks_unhealthy": int64(1),
"received": int64(0),
"requests": int64(0),
"responses_1xx": int64(0),
"responses_2xx": int64(0),
"responses_3xx": int64(0),
"responses_4xx": int64(0),
"responses_5xx": int64(0),
"responses_total": int64(0),
"sent": int64(0),
"state": "unhealthy",
"unavail": int64(0),
"weight": int(1),
},
map[string]string{
"source": host,
"port": port,
"upstream": "trac-backend",
"upstream_address": "10.0.0.1:8089",
"id": "1",
})
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_http_upstream_peers",
map[string]interface{}{
"active": int(0),
"backup": false,
"downtime": int64(0),
"fails": int64(0),
"header_time": int64(20),
"healthchecks_checks": int64(26214),
"healthchecks_fails": int64(0),
"healthchecks_last_passed": true,
"healthchecks_unhealthy": int64(0),
"received": int64(19222475454),
"requests": int64(667231),
"response_time": int64(36),
"responses_1xx": int64(0),
"responses_2xx": int64(666310),
"responses_3xx": int64(0),
"responses_4xx": int64(915),
"responses_5xx": int64(6),
"responses_total": int64(667231),
"sent": int64(251946292),
"state": "up",
"unavail": int64(0),
"weight": int(5),
},
map[string]string{
"source": host,
"port": port,
"upstream": "hg-backend",
"upstream_address": "10.0.0.1:8088",
"id": "0",
})
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_http_upstream_peers",
map[string]interface{}{
"active": int(0),
"backup": true,
"downtime": int64(262925617),
"fails": int64(0),
"healthchecks_checks": int64(26284),
"healthchecks_fails": int64(26284),
"healthchecks_last_passed": false,
"healthchecks_unhealthy": int64(1),
"received": int64(0),
"requests": int64(0),
"responses_1xx": int64(0),
"responses_2xx": int64(0),
"responses_3xx": int64(0),
"responses_4xx": int64(0),
"responses_5xx": int64(0),
"responses_total": int64(0),
"sent": int64(0),
"state": "unhealthy",
"unavail": int64(0),
"weight": int(1),
},
map[string]string{
"source": host,
"port": port,
"upstream": "hg-backend",
"upstream_address": "10.0.0.1:8089",
"id": "1",
})
}
func TestGatherHttpCachesMetrics(t *testing.T) {
ts, n := prepareEndpoint(t, httpCachesPath, defaultApiVersion, httpCachesPayload)
defer ts.Close()
var acc testutil.Accumulator
addr, host, port := prepareAddr(t, ts)
require.NoError(t, n.gatherHttpCachesMetrics(addr, &acc))
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_http_caches",
map[string]interface{}{
"bypass_bytes": int64(5510647548),
"bypass_bytes_written": int64(44992),
"bypass_responses": int64(200187),
"bypass_responses_written": int64(200173),
"cold": false,
"expired_bytes": int64(1656847080),
"expired_bytes_written": int64(1641825173),
"expired_responses": int64(45859),
"expired_responses_written": int64(44992),
"hit_bytes": int64(6685627875),
"hit_responses": int64(254032),
"max_size": int64(536870912),
"miss_bytes": int64(53841943822),
"miss_bytes_written": int64(0),
"miss_responses": int64(1619201),
"miss_responses_written": int64(0),
"revalidated_bytes": int64(0),
"revalidated_responses": int64(0),
"size": int64(530915328),
"stale_bytes": int64(0),
"stale_responses": int64(0),
"updating_bytes": int64(0),
"updating_responses": int64(0),
},
map[string]string{
"source": host,
"port": port,
"cache": "http-cache",
})
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_http_caches",
map[string]interface{}{
"bypass_bytes": int64(5510647548),
"bypass_bytes_written": int64(44992),
"bypass_responses": int64(200187),
"bypass_responses_written": int64(200173),
"cold": false,
"expired_bytes": int64(1656847080),
"expired_bytes_written": int64(1641825173),
"expired_responses": int64(45859),
"expired_responses_written": int64(44992),
"hit_bytes": int64(6685627875),
"hit_responses": int64(254032),
"max_size": int64(536870912),
"miss_bytes": int64(53841943822),
"miss_bytes_written": int64(0),
"miss_responses": int64(1619201),
"miss_responses_written": int64(0),
"revalidated_bytes": int64(0),
"revalidated_responses": int64(0),
"size": int64(530915328),
"stale_bytes": int64(0),
"stale_responses": int64(0),
"updating_bytes": int64(0),
"updating_responses": int64(0),
},
map[string]string{
"source": host,
"port": port,
"cache": "frontend-cache",
})
}
func TestGatherResolverZonesMetrics(t *testing.T) {
ts, n := prepareEndpoint(t, resolverZonesPath, defaultApiVersion, resolverZonesPayload)
defer ts.Close()
var acc testutil.Accumulator
addr, host, port := prepareAddr(t, ts)
require.NoError(t, n.gatherResolverZonesMetrics(addr, &acc))
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_resolver_zones",
map[string]interface{}{
"name": int64(25460),
"srv": int64(130),
"addr": int64(2580),
"noerror": int64(26499),
"formerr": int64(0),
"servfail": int64(3),
"nxdomain": int64(0),
"notimp": int64(0),
"refused": int64(0),
"timedout": int64(243),
"unknown": int64(478),
},
map[string]string{
"source": host,
"port": port,
"zone": "resolver_zone1",
})
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_resolver_zones",
map[string]interface{}{
"name": int64(325460),
"srv": int64(1130),
"addr": int64(12580),
"noerror": int64(226499),
"formerr": int64(0),
"servfail": int64(283),
"nxdomain": int64(0),
"notimp": int64(0),
"refused": int64(0),
"timedout": int64(743),
"unknown": int64(1478),
},
map[string]string{
"source": host,
"port": port,
"zone": "resolver_zone2",
})
}
func TestGatherStreamUpstreams(t *testing.T) {
ts, n := prepareEndpoint(t, streamUpstreamsPath, defaultApiVersion, streamUpstreamsPayload)
defer ts.Close()
var acc testutil.Accumulator
addr, host, port := prepareAddr(t, ts)
require.NoError(t, n.gatherStreamUpstreamsMetrics(addr, &acc))
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_stream_upstreams",
map[string]interface{}{
"zombies": int(0),
},
map[string]string{
"source": host,
"port": port,
"upstream": "mysql_backends",
})
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_stream_upstreams",
map[string]interface{}{
"zombies": int(0),
},
map[string]string{
"source": host,
"port": port,
"upstream": "dns",
})
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_stream_upstream_peers",
map[string]interface{}{
"active": int(0),
"backup": false,
"connections": int64(0),
"downtime": int64(0),
"fails": int64(0),
"healthchecks_checks": int64(26214),
"healthchecks_fails": int64(0),
"healthchecks_last_passed": true,
"healthchecks_unhealthy": int64(0),
"received": int64(19222475454),
"sent": int64(251946292),
"state": "up",
"unavail": int64(0),
"weight": int(5),
},
map[string]string{
"source": host,
"port": port,
"upstream": "mysql_backends",
"upstream_address": "10.0.0.1:12345",
"id": "0",
})
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_stream_upstream_peers",
map[string]interface{}{
"active": int(0),
"backup": true,
"connections": int64(0),
"downtime": int64(262925617),
"fails": int64(0),
"healthchecks_checks": int64(26284),
"healthchecks_fails": int64(26284),
"healthchecks_last_passed": false,
"healthchecks_unhealthy": int64(1),
"received": int64(0),
"sent": int64(0),
"state": "unhealthy",
"unavail": int64(0),
"weight": int(1),
},
map[string]string{
"source": host,
"port": port,
"upstream": "mysql_backends",
"upstream_address": "10.0.0.1:12346",
"id": "1",
})
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_stream_upstream_peers",
map[string]interface{}{
"active": int(0),
"backup": false,
"connections": int64(667231),
"downtime": int64(0),
"fails": int64(0),
"healthchecks_checks": int64(26214),
"healthchecks_fails": int64(0),
"healthchecks_last_passed": true,
"healthchecks_unhealthy": int64(0),
"received": int64(19222475454),
"sent": int64(251946292),
"state": "up",
"unavail": int64(0),
"weight": int(5),
},
map[string]string{
"source": host,
"port": port,
"upstream": "dns",
"upstream_address": "10.0.0.1:12347",
"id": "0",
})
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_stream_upstream_peers",
map[string]interface{}{
"active": int(0),
"backup": true,
"connections": int64(0),
"downtime": int64(262925617),
"fails": int64(0),
"healthchecks_checks": int64(26284),
"healthchecks_fails": int64(26284),
"healthchecks_last_passed": false,
"healthchecks_unhealthy": int64(1),
"received": int64(0),
"sent": int64(0),
"state": "unhealthy",
"unavail": int64(0),
"weight": int(1),
},
map[string]string{
"source": host,
"port": port,
"upstream": "dns",
"upstream_address": "10.0.0.1:12348",
"id": "1",
})
}
func TestGatherStreamServerZonesMetrics(t *testing.T) {
ts, n := prepareEndpoint(t, streamServerZonesPath, defaultApiVersion, streamServerZonesPayload)
defer ts.Close()
var acc testutil.Accumulator
addr, host, port := prepareAddr(t, ts)
require.NoError(t, n.gatherStreamServerZonesMetrics(addr, &acc))
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_stream_server_zones",
map[string]interface{}{
"connections": int(270925),
"processing": int(2),
"received": int64(28988975),
"sent": int64(3879346317),
},
map[string]string{
"source": host,
"port": port,
"zone": "mysql-frontend",
})
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_stream_server_zones",
map[string]interface{}{
"connections": int(155569),
"processing": int(1),
"received": int64(4200363),
"sent": int64(20489184),
},
map[string]string{
"source": host,
"port": port,
"zone": "dns",
})
}
func TestUnavailableEndpoints(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
}))
defer ts.Close()
n := &NginxPlusApi{
client: ts.Client(),
}
addr, err := url.Parse(ts.URL)
if err != nil {
t.Fatal(err)
}
var acc testutil.Accumulator
n.gatherMetrics(addr, &acc)
require.NoError(t, acc.FirstError())
}
func TestServerError(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
}))
defer ts.Close()
n := &NginxPlusApi{
client: ts.Client(),
}
addr, err := url.Parse(ts.URL)
if err != nil {
t.Fatal(err)
}
var acc testutil.Accumulator
n.gatherMetrics(addr, &acc)
require.Error(t, acc.FirstError())
}
func TestMalformedJSON(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
fmt.Fprintln(w, "this is not JSON")
}))
defer ts.Close()
n := &NginxPlusApi{
client: ts.Client(),
}
addr, err := url.Parse(ts.URL)
if err != nil {
t.Fatal(err)
}
var acc testutil.Accumulator
n.gatherMetrics(addr, &acc)
require.Error(t, acc.FirstError())
}
func TestUnknownContentType(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
}))
defer ts.Close()
n := &NginxPlusApi{
client: ts.Client(),
}
addr, err := url.Parse(ts.URL)
if err != nil {
t.Fatal(err)
}
var acc testutil.Accumulator
n.gatherMetrics(addr, &acc)
require.Error(t, acc.FirstError())
}
func prepareAddr(t *testing.T, ts *httptest.Server) (*url.URL, string, string) {
t.Helper()
addr, err := url.Parse(fmt.Sprintf("%s/api", ts.URL))
if err != nil {
t.Fatal(err)
}
host, port, err := net.SplitHostPort(addr.Host)
if err != nil {
host = addr.Host
if addr.Scheme == "http" {
port = "80"
} else if addr.Scheme == "https" {
port = "443"
} else {
port = ""
}
}
return addr, host, port
}
func prepareEndpoint(t *testing.T, path string, apiVersion int64, payload string) (*httptest.Server, *NginxPlusApi) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var rsp string
if r.URL.Path == fmt.Sprintf("/api/%d/%s", apiVersion, path) {
rsp = payload
w.Header()["Content-Type"] = []string{"application/json"}
} else {
t.Errorf("unknown request path")
}
fmt.Fprintln(w, rsp)
}))
n := &NginxPlusApi{
Urls: []string{fmt.Sprintf("%s/api", ts.URL)},
ApiVersion: apiVersion,
}
client, err := n.createHttpClient()
if err != nil {
t.Fatal(err)
}
n.client = client
return ts, n
}