diff --git a/plugins/inputs/procstat/procstat.go b/plugins/inputs/procstat/procstat.go index ca303d49f..3bd92f3b5 100644 --- a/plugins/inputs/procstat/procstat.go +++ b/plugins/inputs/procstat/procstat.go @@ -5,6 +5,7 @@ import ( "fmt" "io/ioutil" "os/exec" + "path/filepath" "strconv" "time" @@ -297,9 +298,12 @@ func (p *Procstat) findPids() ([]PID, map[string]string, error) { return pids, tags, err } +// execCommand is so tests can mock out exec.Command usage. +var execCommand = exec.Command + func (p *Procstat) systemdUnitPIDs() ([]PID, error) { var pids []PID - cmd := exec.Command("systemctl", "show", p.SystemdUnit) + cmd := execCommand("systemctl", "show", p.SystemdUnit) out, err := cmd.Output() if err != nil { return nil, err @@ -331,7 +335,7 @@ func (p *Procstat) cgroupPIDs() ([]PID, error) { if procsPath[0] != '/' { procsPath = "/sys/fs/cgroup/" + procsPath } - procsPath = procsPath + "/cgroup.procs" + procsPath = filepath.Join(procsPath, "cgroup.procs") out, err := ioutil.ReadFile(procsPath) if err != nil { return nil, err diff --git a/plugins/inputs/procstat/procstat_test.go b/plugins/inputs/procstat/procstat_test.go index bc052939f..7b9d6f0c3 100644 --- a/plugins/inputs/procstat/procstat_test.go +++ b/plugins/inputs/procstat/procstat_test.go @@ -2,7 +2,11 @@ package procstat import ( "fmt" + "io/ioutil" "os" + "os/exec" + "path/filepath" + "strings" "testing" "time" @@ -13,6 +17,46 @@ import ( "github.com/stretchr/testify/require" ) +func init() { + execCommand = mockExecCommand +} +func mockExecCommand(arg0 string, args ...string) *exec.Cmd { + args = append([]string{"-test.run=TestMockExecCommand", "--", arg0}, args...) + cmd := exec.Command(os.Args[0], args...) + cmd.Stderr = os.Stderr + return cmd +} +func TestMockExecCommand(t *testing.T) { + var cmd []string + for _, arg := range os.Args { + if string(arg) == "--" { + cmd = []string{} + continue + } + if cmd == nil { + continue + } + cmd = append(cmd, string(arg)) + } + if cmd == nil { + return + } + cmdline := strings.Join(cmd, " ") + + if cmdline == "systemctl show TestGather_systemdUnitPIDs" { + fmt.Printf(`PIDFile= +GuessMainPID=yes +MainPID=11408 +ControlPID=0 +ExecMainPID=11408 +`) + os.Exit(0) + } + + fmt.Printf("command not found\n") + os.Exit(1) +} + type testPgrep struct { pids []PID err error @@ -292,3 +336,31 @@ func TestGather_PercentSecondPass(t *testing.T) { assert.True(t, acc.HasFloatField("procstat", "cpu_time_user")) assert.True(t, acc.HasFloatField("procstat", "cpu_usage")) } + +func TestGather_systemdUnitPIDs(t *testing.T) { + p := Procstat{ + createPIDFinder: pidFinder([]PID{}, nil), + SystemdUnit: "TestGather_systemdUnitPIDs", + } + pids, tags, err := p.findPids() + require.NoError(t, err) + assert.Equal(t, []PID{11408}, pids) + assert.Equal(t, "TestGather_systemdUnitPIDs", tags["systemd_unit"]) +} + +func TestGather_cgroupPIDs(t *testing.T) { + td, err := ioutil.TempDir("", "") + require.NoError(t, err) + defer os.RemoveAll(td) + err = ioutil.WriteFile(filepath.Join(td, "cgroup.procs"), []byte("1234\n5678\n"), 0644) + require.NoError(t, err) + + p := Procstat{ + createPIDFinder: pidFinder([]PID{}, nil), + CGroup: td, + } + pids, tags, err := p.findPids() + require.NoError(t, err) + assert.Equal(t, []PID{1234, 5678}, pids) + assert.Equal(t, td, tags["cgroup"]) +}