256 lines
8.3 KiB
Go
256 lines
8.3 KiB
Go
package system
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/influxdata/telegraf/testutil"
|
|
"github.com/shirou/gopsutil/cpu"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestCPUStats(t *testing.T) {
|
|
var mps MockPS
|
|
defer mps.AssertExpectations(t)
|
|
var acc testutil.Accumulator
|
|
|
|
cts := cpu.TimesStat{
|
|
CPU: "cpu0",
|
|
User: 8.8,
|
|
System: 8.2,
|
|
Idle: 80.1,
|
|
Nice: 1.3,
|
|
Iowait: 0.8389,
|
|
Irq: 0.6,
|
|
Softirq: 0.11,
|
|
Steal: 0.0511,
|
|
Guest: 3.1,
|
|
GuestNice: 0.324,
|
|
}
|
|
|
|
cts2 := cpu.TimesStat{
|
|
CPU: "cpu0",
|
|
User: 24.9, // increased by 16.1
|
|
System: 10.9, // increased by 2.7
|
|
Idle: 157.9798, // increased by 77.8798 (for total increase of 100)
|
|
Nice: 3.5, // increased by 2.2
|
|
Iowait: 0.929, // increased by 0.0901
|
|
Irq: 1.2, // increased by 0.6
|
|
Softirq: 0.31, // increased by 0.2
|
|
Steal: 0.2812, // increased by 0.2301
|
|
Guest: 11.4, // increased by 8.3
|
|
GuestNice: 2.524, // increased by 2.2
|
|
}
|
|
|
|
mps.On("CPUTimes").Return([]cpu.TimesStat{cts}, nil)
|
|
|
|
cs := NewCPUStats(&mps)
|
|
|
|
cputags := map[string]string{
|
|
"cpu": "cpu0",
|
|
}
|
|
|
|
err := cs.Gather(&acc)
|
|
require.NoError(t, err)
|
|
|
|
// Computed values are checked with delta > 0 because of floating point arithmatic
|
|
// imprecision
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_user", 8.8, 0, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_system", 8.2, 0, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_idle", 80.1, 0, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_active", 19.9, 0.0005, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_nice", 1.3, 0, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_iowait", 0.8389, 0, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_irq", 0.6, 0, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_softirq", 0.11, 0, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_steal", 0.0511, 0, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_guest", 3.1, 0, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_guest_nice", 0.324, 0, cputags)
|
|
|
|
mps2 := MockPS{}
|
|
mps2.On("CPUTimes").Return([]cpu.TimesStat{cts2}, nil)
|
|
cs.ps = &mps2
|
|
|
|
// Should have added cpu percentages too
|
|
err = cs.Gather(&acc)
|
|
require.NoError(t, err)
|
|
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_user", 24.9, 0, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_system", 10.9, 0, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_idle", 157.9798, 0, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_active", 42.0202, 0.0005, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_nice", 3.5, 0, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_iowait", 0.929, 0, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_irq", 1.2, 0, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_softirq", 0.31, 0, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_steal", 0.2812, 0, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_guest", 11.4, 0, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_guest_nice", 2.524, 0, cputags)
|
|
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "usage_user", 7.8, 0.0005, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "usage_system", 2.7, 0.0005, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "usage_idle", 77.8798, 0.0005, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "usage_active", 22.1202, 0.0005, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "usage_nice", 0, 0.0005, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "usage_iowait", 0.0901, 0.0005, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "usage_irq", 0.6, 0.0005, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "usage_softirq", 0.2, 0.0005, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "usage_steal", 0.2301, 0.0005, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "usage_guest", 8.3, 0.0005, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "usage_guest_nice", 2.2, 0.0005, cputags)
|
|
}
|
|
|
|
// Asserts that a given accumulator contains a measurment of type float64 with
|
|
// specific tags within a certain distance of a given expected value. Asserts a failure
|
|
// if the measurement is of the wrong type, or if no matching measurements are found
|
|
//
|
|
// Parameters:
|
|
// t *testing.T : Testing object to use
|
|
// acc testutil.Accumulator: Accumulator to examine
|
|
// measurement string : Name of the measurement to examine
|
|
// expectedValue float64 : Value to search for within the measurement
|
|
// delta float64 : Maximum acceptable distance of an accumulated value
|
|
// from the expectedValue parameter. Useful when
|
|
// floating-point arithmatic imprecision makes looking
|
|
// for an exact match impractical
|
|
// tags map[string]string : Tag set the found measurement must have. Set to nil to
|
|
// ignore the tag set.
|
|
func assertContainsTaggedFloat(
|
|
t *testing.T,
|
|
acc *testutil.Accumulator,
|
|
measurement string,
|
|
field string,
|
|
expectedValue float64,
|
|
delta float64,
|
|
tags map[string]string,
|
|
) {
|
|
var actualValue float64
|
|
for _, pt := range acc.Metrics {
|
|
if pt.Measurement == measurement {
|
|
for fieldname, value := range pt.Fields {
|
|
if fieldname == field {
|
|
if value, ok := value.(float64); ok {
|
|
actualValue = value
|
|
if (value >= expectedValue-delta) && (value <= expectedValue+delta) {
|
|
// Found the point, return without failing
|
|
return
|
|
}
|
|
} else {
|
|
assert.Fail(t, fmt.Sprintf("Measurement \"%s\" does not have type float64",
|
|
measurement))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
msg := fmt.Sprintf(
|
|
"Could not find measurement \"%s\" with requested tags within %f of %f, Actual: %f",
|
|
measurement, delta, expectedValue, actualValue)
|
|
assert.Fail(t, msg)
|
|
}
|
|
|
|
// TestCPUCountChange tests that no errors are encountered if the number of
|
|
// CPUs increases as reported with LXC.
|
|
func TestCPUCountIncrease(t *testing.T) {
|
|
var mps MockPS
|
|
var mps2 MockPS
|
|
var acc testutil.Accumulator
|
|
var err error
|
|
|
|
cs := NewCPUStats(&mps)
|
|
|
|
mps.On("CPUTimes").Return(
|
|
[]cpu.TimesStat{
|
|
cpu.TimesStat{
|
|
CPU: "cpu0",
|
|
},
|
|
}, nil)
|
|
|
|
err = cs.Gather(&acc)
|
|
require.NoError(t, err)
|
|
|
|
mps2.On("CPUTimes").Return(
|
|
[]cpu.TimesStat{
|
|
cpu.TimesStat{
|
|
CPU: "cpu0",
|
|
},
|
|
cpu.TimesStat{
|
|
CPU: "cpu1",
|
|
},
|
|
}, nil)
|
|
cs.ps = &mps2
|
|
|
|
err = cs.Gather(&acc)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
// TestCPUTimesDecrease tests that telegraf continue to works after
|
|
// CPU times decrease, which seems to occur when Linux system is suspended.
|
|
func TestCPUTimesDecrease(t *testing.T) {
|
|
var mps MockPS
|
|
defer mps.AssertExpectations(t)
|
|
var acc testutil.Accumulator
|
|
|
|
cts := cpu.TimesStat{
|
|
CPU: "cpu0",
|
|
User: 18,
|
|
Idle: 80,
|
|
Iowait: 2,
|
|
}
|
|
|
|
cts2 := cpu.TimesStat{
|
|
CPU: "cpu0",
|
|
User: 38, // increased by 20
|
|
Idle: 40, // decreased by 40
|
|
Iowait: 1, // decreased by 1
|
|
}
|
|
|
|
cts3 := cpu.TimesStat{
|
|
CPU: "cpu0",
|
|
User: 56, // increased by 18
|
|
Idle: 120, // increased by 80
|
|
Iowait: 3, // increased by 2
|
|
}
|
|
|
|
mps.On("CPUTimes").Return([]cpu.TimesStat{cts}, nil)
|
|
|
|
cs := NewCPUStats(&mps)
|
|
|
|
cputags := map[string]string{
|
|
"cpu": "cpu0",
|
|
}
|
|
|
|
err := cs.Gather(&acc)
|
|
require.NoError(t, err)
|
|
|
|
// Computed values are checked with delta > 0 because of floating point arithmatic
|
|
// imprecision
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_user", 18, 0, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_idle", 80, 0, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_iowait", 2, 0, cputags)
|
|
|
|
mps2 := MockPS{}
|
|
mps2.On("CPUTimes").Return([]cpu.TimesStat{cts2}, nil)
|
|
cs.ps = &mps2
|
|
|
|
// CPU times decreased. An error should be raised
|
|
err = cs.Gather(&acc)
|
|
require.Error(t, err)
|
|
|
|
mps3 := MockPS{}
|
|
mps3.On("CPUTimes").Return([]cpu.TimesStat{cts3}, nil)
|
|
cs.ps = &mps3
|
|
|
|
err = cs.Gather(&acc)
|
|
require.NoError(t, err)
|
|
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_user", 56, 0, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_idle", 120, 0, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "time_iowait", 3, 0, cputags)
|
|
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "usage_user", 18, 0.0005, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "usage_idle", 80, 0.0005, cputags)
|
|
assertContainsTaggedFloat(t, &acc, "cpu", "usage_iowait", 2, 0.0005, cputags)
|
|
}
|