343 lines
8.2 KiB
Go
343 lines
8.2 KiB
Go
|
//go:build linux
|
||
|
|
||
|
package conntrack
|
||
|
|
||
|
import (
|
||
|
"os"
|
||
|
"path"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/shirou/gopsutil/v4/net"
|
||
|
"github.com/stretchr/testify/require"
|
||
|
|
||
|
"github.com/influxdata/telegraf/plugins/common/psutil"
|
||
|
"github.com/influxdata/telegraf/testutil"
|
||
|
)
|
||
|
|
||
|
func restoreDflts(savedFiles, savedDirs []string) {
|
||
|
dfltFiles = savedFiles
|
||
|
dfltDirs = savedDirs
|
||
|
}
|
||
|
|
||
|
func TestNoFilesFound(t *testing.T) {
|
||
|
defer restoreDflts(dfltFiles, dfltDirs)
|
||
|
|
||
|
dfltFiles = []string{"baz.txt"}
|
||
|
dfltDirs = []string{"./foo/bar"}
|
||
|
c := &Conntrack{}
|
||
|
require.NoError(t, c.Init())
|
||
|
acc := &testutil.Accumulator{}
|
||
|
err := c.Gather(acc)
|
||
|
|
||
|
require.EqualError(t, err, "conntrack input failed to collect metrics, make sure that the kernel module is loaded")
|
||
|
}
|
||
|
|
||
|
func TestDefaultsUsed(t *testing.T) {
|
||
|
defer restoreDflts(dfltFiles, dfltDirs)
|
||
|
tmpdir := t.TempDir()
|
||
|
|
||
|
tmpFile, err := os.CreateTemp(tmpdir, "ip_conntrack_count")
|
||
|
require.NoError(t, err)
|
||
|
defer os.Remove(tmpFile.Name())
|
||
|
|
||
|
dfltDirs = []string{tmpdir}
|
||
|
fname := path.Base(tmpFile.Name())
|
||
|
dfltFiles = []string{fname}
|
||
|
|
||
|
count := 1234321
|
||
|
require.NoError(t, os.WriteFile(tmpFile.Name(), []byte(strconv.Itoa(count)), 0640))
|
||
|
c := &Conntrack{}
|
||
|
require.NoError(t, c.Init())
|
||
|
acc := &testutil.Accumulator{}
|
||
|
|
||
|
require.NoError(t, c.Gather(acc))
|
||
|
acc.AssertContainsFields(t, inputName, map[string]interface{}{
|
||
|
fname: float64(count)})
|
||
|
}
|
||
|
|
||
|
func TestConfigsUsed(t *testing.T) {
|
||
|
defer restoreDflts(dfltFiles, dfltDirs)
|
||
|
tmpdir := t.TempDir()
|
||
|
|
||
|
cntFile, err := os.CreateTemp(tmpdir, "nf_conntrack_count")
|
||
|
require.NoError(t, err)
|
||
|
maxFile, err := os.CreateTemp(tmpdir, "nf_conntrack_max")
|
||
|
require.NoError(t, err)
|
||
|
defer os.Remove(cntFile.Name())
|
||
|
defer os.Remove(maxFile.Name())
|
||
|
|
||
|
dfltDirs = []string{tmpdir}
|
||
|
cntFname := path.Base(cntFile.Name())
|
||
|
maxFname := path.Base(maxFile.Name())
|
||
|
dfltFiles = []string{cntFname, maxFname}
|
||
|
|
||
|
count := 1234321
|
||
|
limit := 9999999
|
||
|
require.NoError(t, os.WriteFile(cntFile.Name(), []byte(strconv.Itoa(count)), 0640))
|
||
|
require.NoError(t, os.WriteFile(maxFile.Name(), []byte(strconv.Itoa(limit)), 0640))
|
||
|
c := &Conntrack{}
|
||
|
require.NoError(t, c.Init())
|
||
|
acc := &testutil.Accumulator{}
|
||
|
|
||
|
require.NoError(t, c.Gather(acc))
|
||
|
|
||
|
fix := func(s string) string {
|
||
|
return strings.Replace(s, "nf_", "ip_", 1)
|
||
|
}
|
||
|
|
||
|
acc.AssertContainsFields(t, inputName,
|
||
|
map[string]interface{}{
|
||
|
fix(cntFname): float64(count),
|
||
|
fix(maxFname): float64(limit),
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestCollectStats(t *testing.T) {
|
||
|
var mps psutil.MockPS
|
||
|
defer mps.AssertExpectations(t)
|
||
|
var acc testutil.Accumulator
|
||
|
|
||
|
sts := net.ConntrackStat{
|
||
|
Entries: 1234,
|
||
|
Searched: 10,
|
||
|
Found: 1,
|
||
|
New: 5,
|
||
|
Invalid: 43,
|
||
|
Ignore: 13,
|
||
|
Delete: 3,
|
||
|
DeleteList: 5,
|
||
|
Insert: 9,
|
||
|
InsertFailed: 20,
|
||
|
Drop: 49,
|
||
|
EarlyDrop: 7,
|
||
|
IcmpError: 21,
|
||
|
ExpectNew: 12,
|
||
|
ExpectCreate: 44,
|
||
|
ExpectDelete: 53,
|
||
|
SearchRestart: 31,
|
||
|
}
|
||
|
|
||
|
mps.On("NetConntrack", false).Return([]net.ConntrackStat{sts}, nil)
|
||
|
cs := &Conntrack{
|
||
|
ps: &mps,
|
||
|
Collect: []string{"all"},
|
||
|
}
|
||
|
require.NoError(t, cs.Init())
|
||
|
|
||
|
err := cs.Gather(&acc)
|
||
|
if err != nil && strings.Contains(err.Error(), "Is the conntrack kernel module loaded?") {
|
||
|
t.Skip("Conntrack kernel module not loaded.")
|
||
|
}
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
expectedTags := map[string]string{
|
||
|
"cpu": "all",
|
||
|
}
|
||
|
|
||
|
expectedFields := map[string]interface{}{
|
||
|
"entries": uint32(1234),
|
||
|
"searched": uint32(10),
|
||
|
"found": uint32(1),
|
||
|
"new": uint32(5),
|
||
|
"invalid": uint32(43),
|
||
|
"ignore": uint32(13),
|
||
|
"delete": uint32(3),
|
||
|
"delete_list": uint32(5),
|
||
|
"insert": uint32(9),
|
||
|
"insert_failed": uint32(20),
|
||
|
"drop": uint32(49),
|
||
|
"early_drop": uint32(7),
|
||
|
"icmp_error": uint32(21),
|
||
|
"expect_new": uint32(12),
|
||
|
"expect_create": uint32(44),
|
||
|
"expect_delete": uint32(53),
|
||
|
"search_restart": uint32(31),
|
||
|
}
|
||
|
|
||
|
acc.AssertContainsFields(t, inputName, expectedFields)
|
||
|
acc.AssertContainsTaggedFields(t, inputName, expectedFields, expectedTags)
|
||
|
|
||
|
require.Equal(t, 19, acc.NFields())
|
||
|
}
|
||
|
|
||
|
func TestCollectStatsPerCpu(t *testing.T) {
|
||
|
var mps psutil.MockPS
|
||
|
defer mps.AssertExpectations(t)
|
||
|
var acc testutil.Accumulator
|
||
|
|
||
|
sts := []net.ConntrackStat{
|
||
|
{
|
||
|
Entries: 59,
|
||
|
Searched: 10,
|
||
|
Found: 1,
|
||
|
New: 5,
|
||
|
Invalid: 43,
|
||
|
Ignore: 13,
|
||
|
Delete: 3,
|
||
|
DeleteList: 5,
|
||
|
Insert: 9,
|
||
|
InsertFailed: 20,
|
||
|
Drop: 49,
|
||
|
EarlyDrop: 7,
|
||
|
IcmpError: 21,
|
||
|
ExpectNew: 12,
|
||
|
ExpectCreate: 44,
|
||
|
ExpectDelete: 53,
|
||
|
SearchRestart: 31,
|
||
|
},
|
||
|
{
|
||
|
Entries: 79,
|
||
|
Searched: 10,
|
||
|
Found: 1,
|
||
|
New: 5,
|
||
|
Invalid: 43,
|
||
|
Ignore: 13,
|
||
|
Delete: 3,
|
||
|
DeleteList: 5,
|
||
|
Insert: 9,
|
||
|
InsertFailed: 10,
|
||
|
Drop: 49,
|
||
|
EarlyDrop: 7,
|
||
|
IcmpError: 21,
|
||
|
ExpectNew: 12,
|
||
|
ExpectCreate: 44,
|
||
|
ExpectDelete: 53,
|
||
|
SearchRestart: 31,
|
||
|
},
|
||
|
}
|
||
|
|
||
|
mps.On("NetConntrack", true).Return(sts, nil)
|
||
|
|
||
|
allSts := []net.ConntrackStat{
|
||
|
{
|
||
|
Entries: 129,
|
||
|
Searched: 20,
|
||
|
Found: 2,
|
||
|
New: 10,
|
||
|
Invalid: 86,
|
||
|
Ignore: 26,
|
||
|
Delete: 6,
|
||
|
DeleteList: 10,
|
||
|
Insert: 18,
|
||
|
InsertFailed: 40,
|
||
|
Drop: 98,
|
||
|
EarlyDrop: 17,
|
||
|
IcmpError: 42,
|
||
|
ExpectNew: 24,
|
||
|
ExpectCreate: 88,
|
||
|
ExpectDelete: 106,
|
||
|
SearchRestart: 62,
|
||
|
},
|
||
|
}
|
||
|
|
||
|
mps.On("NetConntrack", false).Return(allSts, nil)
|
||
|
|
||
|
cs := &Conntrack{
|
||
|
ps: &mps,
|
||
|
Collect: []string{"all", "percpu"},
|
||
|
}
|
||
|
require.NoError(t, cs.Init())
|
||
|
|
||
|
err := cs.Gather(&acc)
|
||
|
if err != nil && strings.Contains(err.Error(), "Is the conntrack kernel module loaded?") {
|
||
|
t.Skip("Conntrack kernel module not loaded.")
|
||
|
}
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
// cpu0
|
||
|
expectedFields := map[string]interface{}{
|
||
|
"entries": uint32(59),
|
||
|
"searched": uint32(10),
|
||
|
"found": uint32(1),
|
||
|
"new": uint32(5),
|
||
|
"invalid": uint32(43),
|
||
|
"ignore": uint32(13),
|
||
|
"delete": uint32(3),
|
||
|
"delete_list": uint32(5),
|
||
|
"insert": uint32(9),
|
||
|
"insert_failed": uint32(20),
|
||
|
"drop": uint32(49),
|
||
|
"early_drop": uint32(7),
|
||
|
"icmp_error": uint32(21),
|
||
|
"expect_new": uint32(12),
|
||
|
"expect_create": uint32(44),
|
||
|
"expect_delete": uint32(53),
|
||
|
"search_restart": uint32(31),
|
||
|
}
|
||
|
|
||
|
acc.AssertContainsTaggedFields(t, inputName, expectedFields,
|
||
|
map[string]string{
|
||
|
"cpu": "cpu0",
|
||
|
})
|
||
|
|
||
|
// cpu1
|
||
|
expectedFields1 := map[string]interface{}{
|
||
|
"entries": uint32(79),
|
||
|
"searched": uint32(10),
|
||
|
"found": uint32(1),
|
||
|
"new": uint32(5),
|
||
|
"invalid": uint32(43),
|
||
|
"ignore": uint32(13),
|
||
|
"delete": uint32(3),
|
||
|
"delete_list": uint32(5),
|
||
|
"insert": uint32(9),
|
||
|
"insert_failed": uint32(10),
|
||
|
"drop": uint32(49),
|
||
|
"early_drop": uint32(7),
|
||
|
"icmp_error": uint32(21),
|
||
|
"expect_new": uint32(12),
|
||
|
"expect_create": uint32(44),
|
||
|
"expect_delete": uint32(53),
|
||
|
"search_restart": uint32(31),
|
||
|
}
|
||
|
|
||
|
acc.AssertContainsTaggedFields(t, inputName, expectedFields1,
|
||
|
map[string]string{
|
||
|
"cpu": "cpu1",
|
||
|
})
|
||
|
|
||
|
allFields := map[string]interface{}{
|
||
|
"entries": uint32(129),
|
||
|
"searched": uint32(20),
|
||
|
"found": uint32(2),
|
||
|
"new": uint32(10),
|
||
|
"invalid": uint32(86),
|
||
|
"ignore": uint32(26),
|
||
|
"delete": uint32(6),
|
||
|
"delete_list": uint32(10),
|
||
|
"insert": uint32(18),
|
||
|
"insert_failed": uint32(40),
|
||
|
"drop": uint32(98),
|
||
|
"early_drop": uint32(17),
|
||
|
"icmp_error": uint32(42),
|
||
|
"expect_new": uint32(24),
|
||
|
"expect_create": uint32(88),
|
||
|
"expect_delete": uint32(106),
|
||
|
"search_restart": uint32(62),
|
||
|
}
|
||
|
|
||
|
acc.AssertContainsTaggedFields(t, inputName, allFields,
|
||
|
map[string]string{
|
||
|
"cpu": "all",
|
||
|
})
|
||
|
|
||
|
require.Equal(t, 53, acc.NFields())
|
||
|
}
|
||
|
|
||
|
func TestCollectPsSystemInit(t *testing.T) {
|
||
|
var acc testutil.Accumulator
|
||
|
cs := &Conntrack{
|
||
|
ps: psutil.NewSystemPS(),
|
||
|
Collect: []string{"all"},
|
||
|
}
|
||
|
require.NoError(t, cs.Init())
|
||
|
err := cs.Gather(&acc)
|
||
|
if err != nil && strings.Contains(err.Error(), "Is the conntrack kernel module loaded?") {
|
||
|
t.Skip("Conntrack kernel module not loaded.")
|
||
|
}
|
||
|
// make sure Conntrack.ps gets initialized without mocking
|
||
|
require.NoError(t, err)
|
||
|
}
|