580 lines
12 KiB
Go
580 lines
12 KiB
Go
package bind
|
|
|
|
import (
|
|
"net"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/influxdata/telegraf/testutil"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestBindJsonStats(t *testing.T) {
|
|
ts := httptest.NewServer(http.FileServer(http.Dir("testdata")))
|
|
url := ts.Listener.Addr().String()
|
|
host, port, _ := net.SplitHostPort(url)
|
|
defer ts.Close()
|
|
|
|
b := Bind{
|
|
Urls: []string{ts.URL + "/json/v1"},
|
|
GatherMemoryContexts: true,
|
|
GatherViews: true,
|
|
}
|
|
|
|
var acc testutil.Accumulator
|
|
err := acc.GatherError(b.Gather)
|
|
|
|
assert.Nil(t, err)
|
|
|
|
// Use subtests for counters, since they are similar structure
|
|
type fieldSet struct {
|
|
fieldKey string
|
|
fieldValue int64
|
|
}
|
|
|
|
testCases := []struct {
|
|
counterType string
|
|
values []fieldSet
|
|
}{
|
|
{
|
|
"opcode",
|
|
[]fieldSet{
|
|
{"NOTIFY", 0},
|
|
{"UPDATE", 0},
|
|
{"IQUERY", 0},
|
|
{"QUERY", 13},
|
|
{"STATUS", 0},
|
|
},
|
|
},
|
|
{
|
|
"qtype",
|
|
[]fieldSet{
|
|
{"A", 2},
|
|
{"AAAA", 2},
|
|
{"PTR", 7},
|
|
{"SRV", 2},
|
|
},
|
|
},
|
|
{
|
|
"nsstat",
|
|
[]fieldSet{
|
|
{"QrySuccess", 6},
|
|
{"QryRecursion", 12},
|
|
{"Requestv4", 13},
|
|
{"QryNXDOMAIN", 4},
|
|
{"QryAuthAns", 1},
|
|
{"QryNxrrset", 1},
|
|
{"QryNoauthAns", 10},
|
|
{"QryUDP", 13},
|
|
{"QryDuplicate", 1},
|
|
{"QrySERVFAIL", 1},
|
|
{"Response", 12},
|
|
},
|
|
},
|
|
{
|
|
"sockstat",
|
|
[]fieldSet{
|
|
{"TCP4Open", 118},
|
|
{"UDP6Close", 112},
|
|
{"UDP4Close", 333},
|
|
{"TCP4Close", 119},
|
|
{"TCP6Active", 2},
|
|
{"UDP4Active", 2},
|
|
{"UDP4RecvErr", 1},
|
|
{"UDP4Open", 335},
|
|
{"TCP4Active", 10},
|
|
{"RawActive", 1},
|
|
{"UDP6ConnFail", 112},
|
|
{"TCP4Conn", 114},
|
|
{"UDP6Active", 1},
|
|
{"UDP6Open", 113},
|
|
{"UDP4Conn", 333},
|
|
{"UDP6SendErr", 112},
|
|
{"RawOpen", 1},
|
|
{"TCP4Accept", 6},
|
|
{"TCP6Open", 2},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.counterType, func(t *testing.T) {
|
|
tags := map[string]string{
|
|
"url": url,
|
|
"type": tc.counterType,
|
|
"source": host,
|
|
"port": port,
|
|
}
|
|
|
|
fields := map[string]interface{}{}
|
|
|
|
for _, val := range tc.values {
|
|
fields[val.fieldKey] = val.fieldValue
|
|
}
|
|
|
|
acc.AssertContainsTaggedFields(t, "bind_counter", fields, tags)
|
|
})
|
|
}
|
|
|
|
// Subtest for memory stats
|
|
t.Run("memory", func(t *testing.T) {
|
|
tags := map[string]string{
|
|
"url": url,
|
|
"source": host,
|
|
"port": port,
|
|
}
|
|
|
|
fields := map[string]interface{}{
|
|
"block_size": int64(13893632),
|
|
"context_size": int64(3685480),
|
|
"in_use": int64(3064368),
|
|
"lost": int64(0),
|
|
"total_use": int64(18206566),
|
|
}
|
|
acc.AssertContainsTaggedFields(t, "bind_memory", fields, tags)
|
|
})
|
|
|
|
// Subtest for per-context memory stats
|
|
t.Run("memory_context", func(t *testing.T) {
|
|
assert.True(t, acc.HasInt64Field("bind_memory_context", "total"))
|
|
assert.True(t, acc.HasInt64Field("bind_memory_context", "in_use"))
|
|
})
|
|
}
|
|
|
|
func TestBindXmlStatsV2(t *testing.T) {
|
|
ts := httptest.NewServer(http.FileServer(http.Dir("testdata")))
|
|
url := ts.Listener.Addr().String()
|
|
host, port, _ := net.SplitHostPort(url)
|
|
defer ts.Close()
|
|
|
|
b := Bind{
|
|
Urls: []string{ts.URL + "/xml/v2"},
|
|
GatherMemoryContexts: true,
|
|
GatherViews: true,
|
|
}
|
|
|
|
var acc testutil.Accumulator
|
|
err := acc.GatherError(b.Gather)
|
|
|
|
assert.Nil(t, err)
|
|
|
|
// Use subtests for counters, since they are similar structure
|
|
type fieldSet struct {
|
|
fieldKey string
|
|
fieldValue int64
|
|
}
|
|
|
|
testCases := []struct {
|
|
counterType string
|
|
values []fieldSet
|
|
}{
|
|
{
|
|
"opcode",
|
|
[]fieldSet{
|
|
{"UPDATE", 238},
|
|
{"QUERY", 102312374},
|
|
},
|
|
},
|
|
{
|
|
"qtype",
|
|
[]fieldSet{
|
|
{"ANY", 7},
|
|
{"DNSKEY", 452},
|
|
{"SSHFP", 2987},
|
|
{"SOA", 100415},
|
|
{"AAAA", 37786321},
|
|
{"MX", 441155},
|
|
{"IXFR", 157},
|
|
{"CNAME", 531},
|
|
{"NS", 1999},
|
|
{"TXT", 34628},
|
|
{"A", 58951432},
|
|
{"SRV", 741082},
|
|
{"PTR", 4211487},
|
|
{"NAPTR", 39137},
|
|
{"DS", 584},
|
|
},
|
|
},
|
|
{
|
|
"nsstat",
|
|
[]fieldSet{
|
|
{"XfrReqDone", 157},
|
|
{"ReqEdns0", 441758},
|
|
{"ReqTSIG", 0},
|
|
{"UpdateRespFwd", 0},
|
|
{"RespEDNS0", 441748},
|
|
{"QryDropped", 16},
|
|
{"RPZRewrites", 0},
|
|
{"XfrRej", 0},
|
|
{"RecQryRej", 0},
|
|
{"QryNxrrset", 24423133},
|
|
{"QryFORMERR", 0},
|
|
{"ReqTCP", 1548156},
|
|
{"UpdateDone", 0},
|
|
{"QrySERVFAIL", 14422},
|
|
{"QryRecursion", 2104239},
|
|
{"Requestv4", 102312611},
|
|
{"UpdateFwdFail", 0},
|
|
{"QryReferral", 3},
|
|
{"Response", 102301560},
|
|
{"RespTSIG", 0},
|
|
{"QrySuccess", 63811668},
|
|
{"QryFailure", 0},
|
|
{"RespSIG0", 0},
|
|
{"ReqSIG0", 0},
|
|
{"UpdateRej", 238},
|
|
{"QryAuthAns", 72180718},
|
|
{"UpdateFail", 0},
|
|
{"QryDuplicate", 10879},
|
|
{"RateDropped", 0},
|
|
{"QryNoauthAns", 30106182},
|
|
{"QryNXDOMAIN", 14052096},
|
|
{"ReqBadSIG", 0},
|
|
{"UpdateReqFwd", 0},
|
|
{"RateSlipped", 0},
|
|
{"TruncatedResp", 3787},
|
|
{"Requestv6", 1},
|
|
{"UpdateBadPrereq", 0},
|
|
{"AuthQryRej", 0},
|
|
{"ReqBadEDNSVer", 0},
|
|
},
|
|
},
|
|
{
|
|
"sockstat",
|
|
[]fieldSet{
|
|
{"FdwatchBindFail", 0},
|
|
{"UDP6Open", 238269},
|
|
{"UDP6SendErr", 238250},
|
|
{"TCP4ConnFail", 0},
|
|
{"TCP4Conn", 590},
|
|
{"TCP6AcceptFail", 0},
|
|
{"UDP4SendErr", 0},
|
|
{"FDwatchConn", 0},
|
|
{"TCP4RecvErr", 1},
|
|
{"TCP4OpenFail", 0},
|
|
{"UDP4OpenFail", 0},
|
|
{"UDP6OpenFail", 0},
|
|
{"TCP4Close", 1548268},
|
|
{"TCP6BindFail", 0},
|
|
{"TCP4AcceptFail", 0},
|
|
{"UnixConn", 0},
|
|
{"UDP4Open", 3765532},
|
|
{"TCP6Close", 0},
|
|
{"FDwatchRecvErr", 0},
|
|
{"UDP4Conn", 3764828},
|
|
{"UnixConnFail", 0},
|
|
{"TCP6Conn", 0},
|
|
{"TCP6OpenFail", 0},
|
|
{"TCP6SendErr", 0},
|
|
{"TCP6RecvErr", 0},
|
|
{"FDwatchSendErr", 0},
|
|
{"UDP4RecvErr", 1650},
|
|
{"UDP4ConnFail", 0},
|
|
{"UDP6Close", 238267},
|
|
{"FDWatchClose", 0},
|
|
{"TCP4Accept", 1547672},
|
|
{"UnixAccept", 0},
|
|
{"TCP4Open", 602},
|
|
{"UDP4BindFail", 219},
|
|
{"UDP6ConnFail", 238250},
|
|
{"UnixClose", 0},
|
|
{"TCP4BindFail", 0},
|
|
{"UnixOpenFail", 0},
|
|
{"UDP6BindFail", 16},
|
|
{"UnixOpen", 0},
|
|
{"UnixAcceptFail", 0},
|
|
{"UnixRecvErr", 0},
|
|
{"UDP6RecvErr", 0},
|
|
{"TCP6ConnFail", 0},
|
|
{"FDwatchConnFail", 0},
|
|
{"TCP4SendErr", 0},
|
|
{"UDP4Close", 3765528},
|
|
{"UnixSendErr", 0},
|
|
{"TCP6Open", 2},
|
|
{"UDP6Conn", 1},
|
|
{"TCP6Accept", 0},
|
|
{"UnixBindFail", 0},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.counterType, func(t *testing.T) {
|
|
tags := map[string]string{
|
|
"url": url,
|
|
"type": tc.counterType,
|
|
"source": host,
|
|
"port": port,
|
|
}
|
|
|
|
fields := map[string]interface{}{}
|
|
|
|
for _, val := range tc.values {
|
|
fields[val.fieldKey] = val.fieldValue
|
|
}
|
|
|
|
acc.AssertContainsTaggedFields(t, "bind_counter", fields, tags)
|
|
})
|
|
}
|
|
|
|
// Subtest for memory stats
|
|
t.Run("memory", func(t *testing.T) {
|
|
tags := map[string]string{
|
|
"url": url,
|
|
"source": host,
|
|
"port": port,
|
|
}
|
|
|
|
fields := map[string]interface{}{
|
|
"block_size": int64(77070336),
|
|
"context_size": int64(6663840),
|
|
"in_use": int64(20772579),
|
|
"lost": int64(0),
|
|
"total_use": int64(81804609),
|
|
}
|
|
|
|
acc.AssertContainsTaggedFields(t, "bind_memory", fields, tags)
|
|
})
|
|
|
|
// Subtest for per-context memory stats
|
|
t.Run("memory_context", func(t *testing.T) {
|
|
assert.True(t, acc.HasInt64Field("bind_memory_context", "total"))
|
|
assert.True(t, acc.HasInt64Field("bind_memory_context", "in_use"))
|
|
})
|
|
}
|
|
|
|
func TestBindXmlStatsV3(t *testing.T) {
|
|
ts := httptest.NewServer(http.FileServer(http.Dir("testdata")))
|
|
url := ts.Listener.Addr().String()
|
|
host, port, _ := net.SplitHostPort(url)
|
|
defer ts.Close()
|
|
|
|
b := Bind{
|
|
Urls: []string{ts.URL + "/xml/v3"},
|
|
GatherMemoryContexts: true,
|
|
GatherViews: true,
|
|
}
|
|
|
|
var acc testutil.Accumulator
|
|
err := acc.GatherError(b.Gather)
|
|
|
|
assert.Nil(t, err)
|
|
|
|
// Use subtests for counters, since they are similar structure
|
|
type fieldSet struct {
|
|
fieldKey string
|
|
fieldValue int64
|
|
}
|
|
|
|
testCases := []struct {
|
|
counterType string
|
|
values []fieldSet
|
|
}{
|
|
{
|
|
"opcode",
|
|
[]fieldSet{
|
|
{"NOTIFY", 0},
|
|
{"UPDATE", 0},
|
|
{"IQUERY", 0},
|
|
{"QUERY", 74941},
|
|
{"STATUS", 0},
|
|
},
|
|
},
|
|
{
|
|
"qtype",
|
|
[]fieldSet{
|
|
{"ANY", 22},
|
|
{"SOA", 18},
|
|
{"AAAA", 5735},
|
|
{"MX", 618},
|
|
{"NS", 373},
|
|
{"TXT", 970},
|
|
{"A", 63672},
|
|
{"SRV", 139},
|
|
{"PTR", 3393},
|
|
{"RRSIG", 1},
|
|
},
|
|
},
|
|
{
|
|
"nsstat",
|
|
[]fieldSet{
|
|
{"DNS64", 0},
|
|
{"ExpireOpt", 0},
|
|
{"NSIDOpt", 0},
|
|
{"OtherOpt", 59},
|
|
{"XfrReqDone", 0},
|
|
{"ReqEdns0", 9250},
|
|
{"ReqTSIG", 0},
|
|
{"UpdateRespFwd", 0},
|
|
{"RespEDNS0", 9250},
|
|
{"QryDropped", 11},
|
|
{"RPZRewrites", 0},
|
|
{"XfrRej", 0},
|
|
{"RecQryRej", 35},
|
|
{"QryNxrrset", 2452},
|
|
{"QryFORMERR", 0},
|
|
{"ReqTCP", 260},
|
|
{"QryTCP", 258},
|
|
{"QryUDP", 74648},
|
|
{"UpdateDone", 0},
|
|
{"QrySERVFAIL", 122},
|
|
{"QryRecursion", 53750},
|
|
{"RecursClients", 0},
|
|
{"Requestv4", 74942},
|
|
{"UpdateFwdFail", 0},
|
|
{"QryReferral", 0},
|
|
{"Response", 63264},
|
|
{"RespTSIG", 0},
|
|
{"QrySuccess", 49044},
|
|
{"QryFailure", 35},
|
|
{"RespSIG0", 0},
|
|
{"ReqSIG0", 0},
|
|
{"UpdateRej", 0},
|
|
{"QryAuthAns", 2752},
|
|
{"UpdateFail", 0},
|
|
{"QryDuplicate", 11667},
|
|
{"RateDropped", 0},
|
|
{"QryNoauthAns", 60354},
|
|
{"QryNXDOMAIN", 11610},
|
|
{"ReqBadSIG", 0},
|
|
{"UpdateReqFwd", 0},
|
|
{"RateSlipped", 0},
|
|
{"TruncatedResp", 365},
|
|
{"Requestv6", 0},
|
|
{"UpdateBadPrereq", 0},
|
|
{"AuthQryRej", 0},
|
|
{"ReqBadEDNSVer", 0},
|
|
{"SitBadSize", 0},
|
|
{"SitBadTime", 0},
|
|
{"SitMatch", 0},
|
|
{"SitNew", 0},
|
|
{"SitNoMatch", 0},
|
|
{"SitOpt", 0},
|
|
{"TruncatedResp", 365},
|
|
},
|
|
},
|
|
{
|
|
"sockstat",
|
|
[]fieldSet{
|
|
{"FDwatchConnFail", 0},
|
|
{"UnixClose", 0},
|
|
{"TCP6OpenFail", 0},
|
|
{"TCP6Active", 0},
|
|
{"UDP4RecvErr", 14},
|
|
{"TCP6Conn", 0},
|
|
{"FDWatchClose", 0},
|
|
{"TCP4ConnFail", 0},
|
|
{"UnixConn", 0},
|
|
{"UnixSendErr", 0},
|
|
{"UDP6Close", 0},
|
|
{"UnixOpen", 0},
|
|
{"UDP4Conn", 92535},
|
|
{"TCP4Close", 336},
|
|
{"UnixAcceptFail", 0},
|
|
{"UnixAccept", 0},
|
|
{"TCP6AcceptFail", 0},
|
|
{"UDP6Open", 0},
|
|
{"UDP6BindFail", 0},
|
|
{"UDP6RecvErr", 0},
|
|
{"RawOpenFail", 0},
|
|
{"TCP4Accept", 293},
|
|
{"UDP6SendErr", 0},
|
|
{"UDP6Conn", 0},
|
|
{"TCP4SendErr", 0},
|
|
{"UDP4BindFail", 1},
|
|
{"UDP4Active", 4},
|
|
{"TCP4Active", 297},
|
|
{"UnixConnFail", 0},
|
|
{"UnixOpenFail", 0},
|
|
{"UDP6ConnFail", 0},
|
|
{"TCP6Accept", 0},
|
|
{"UnixRecvErr", 0},
|
|
{"RawActive", 1},
|
|
{"UDP6OpenFail", 0},
|
|
{"RawClose", 0},
|
|
{"UnixBindFail", 0},
|
|
{"UnixActive", 0},
|
|
{"FdwatchBindFail", 0},
|
|
{"UDP4SendErr", 0},
|
|
{"RawRecvErr", 0},
|
|
{"TCP6Close", 0},
|
|
{"FDwatchRecvErr", 0},
|
|
{"TCP4BindFail", 0},
|
|
{"TCP4AcceptFail", 0},
|
|
{"TCP4OpenFail", 0},
|
|
{"UDP4Open", 92542},
|
|
{"UDP4ConnFail", 0},
|
|
{"TCP4Conn", 44},
|
|
{"TCP6ConnFail", 0},
|
|
{"FDwatchConn", 0},
|
|
{"UDP6Active", 0},
|
|
{"RawOpen", 1},
|
|
{"TCP6BindFail", 0},
|
|
{"UDP4Close", 92538},
|
|
{"TCP6Open", 0},
|
|
{"TCP6SendErr", 0},
|
|
{"TCP4Open", 48},
|
|
{"FDwatchSendErr", 0},
|
|
{"TCP6RecvErr", 0},
|
|
{"UDP4OpenFail", 0},
|
|
{"TCP4RecvErr", 0},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.counterType, func(t *testing.T) {
|
|
tags := map[string]string{
|
|
"url": url,
|
|
"type": tc.counterType,
|
|
"source": host,
|
|
"port": port,
|
|
}
|
|
|
|
fields := map[string]interface{}{}
|
|
|
|
for _, val := range tc.values {
|
|
fields[val.fieldKey] = val.fieldValue
|
|
}
|
|
|
|
acc.AssertContainsTaggedFields(t, "bind_counter", fields, tags)
|
|
})
|
|
}
|
|
|
|
// Subtest for memory stats
|
|
t.Run("memory", func(t *testing.T) {
|
|
tags := map[string]string{
|
|
"url": url,
|
|
"source": host,
|
|
"port": port,
|
|
}
|
|
|
|
fields := map[string]interface{}{
|
|
"block_size": int64(45875200),
|
|
"context_size": int64(10037400),
|
|
"in_use": int64(6000232),
|
|
"lost": int64(0),
|
|
"total_use": int64(777821909),
|
|
}
|
|
|
|
acc.AssertContainsTaggedFields(t, "bind_memory", fields, tags)
|
|
})
|
|
|
|
// Subtest for per-context memory stats
|
|
t.Run("memory_context", func(t *testing.T) {
|
|
assert.True(t, acc.HasInt64Field("bind_memory_context", "total"))
|
|
assert.True(t, acc.HasInt64Field("bind_memory_context", "in_use"))
|
|
})
|
|
}
|
|
|
|
func TestBindUnparseableURL(t *testing.T) {
|
|
b := Bind{
|
|
Urls: []string{"://example.com"},
|
|
}
|
|
|
|
var acc testutil.Accumulator
|
|
err := acc.GatherError(b.Gather)
|
|
assert.Contains(t, err.Error(), "Unable to parse address")
|
|
}
|