2020-12-11 04:23:27 +08:00
|
|
|
// +build linux
|
|
|
|
|
|
|
|
|
|
package intel_powerstat
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"errors"
|
|
|
|
|
"strconv"
|
|
|
|
|
"sync"
|
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/mock"
|
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
|
|
|
|
|
"github.com/influxdata/telegraf/testutil"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestInitPlugin(t *testing.T) {
|
|
|
|
|
cores := []string{"cpu0", "cpu1", "cpu2", "cpu3"}
|
|
|
|
|
power, fsMock, _, _ := getPowerWithMockedServices()
|
|
|
|
|
|
|
|
|
|
fsMock.On("getCPUInfoStats", mock.Anything).
|
|
|
|
|
Return(nil, errors.New("error getting cpu stats")).Once()
|
|
|
|
|
require.Error(t, power.Init())
|
|
|
|
|
|
|
|
|
|
fsMock.On("getCPUInfoStats", mock.Anything).
|
|
|
|
|
Return(make(map[string]*cpuInfo), nil).Once()
|
|
|
|
|
require.Error(t, power.Init())
|
|
|
|
|
|
|
|
|
|
fsMock.On("getCPUInfoStats", mock.Anything).
|
|
|
|
|
Return(map[string]*cpuInfo{"0": {
|
|
|
|
|
vendorID: "GenuineIntel",
|
|
|
|
|
cpuFamily: "test",
|
|
|
|
|
}}, nil).Once()
|
|
|
|
|
require.Error(t, power.Init())
|
|
|
|
|
|
|
|
|
|
fsMock.On("getStringsMatchingPatternOnPath", mock.Anything).
|
|
|
|
|
Return(cores, nil).Once().
|
|
|
|
|
On("getCPUInfoStats", mock.Anything).
|
|
|
|
|
Return(map[string]*cpuInfo{"0": {
|
|
|
|
|
vendorID: "GenuineIntel",
|
|
|
|
|
cpuFamily: "6",
|
|
|
|
|
}}, nil)
|
|
|
|
|
// Verify MSR service initialization.
|
|
|
|
|
power.cpuFrequency = true
|
|
|
|
|
require.NoError(t, power.Init())
|
|
|
|
|
fsMock.AssertCalled(t, "getStringsMatchingPatternOnPath", mock.Anything)
|
|
|
|
|
require.Equal(t, len(cores), len(power.msr.getCPUCoresData()))
|
|
|
|
|
|
|
|
|
|
fsMock.On("getStringsMatchingPatternOnPath", mock.Anything).
|
|
|
|
|
Return(nil, errors.New("error during getStringsMatchingPatternOnPath")).Once()
|
|
|
|
|
|
|
|
|
|
// In case of an error when fetching cpu cores plugin should proceed with execution.
|
|
|
|
|
require.NoError(t, power.Init())
|
|
|
|
|
fsMock.AssertCalled(t, "getStringsMatchingPatternOnPath", mock.Anything)
|
|
|
|
|
require.Equal(t, 0, len(power.msr.getCPUCoresData()))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestParseCPUMetricsConfig(t *testing.T) {
|
|
|
|
|
power, _, _, _ := getPowerWithMockedServices()
|
|
|
|
|
disableCoreMetrics(power)
|
|
|
|
|
|
|
|
|
|
power.CPUMetrics = []string{
|
|
|
|
|
"cpu_frequency", "cpu_c1_state_residency", "cpu_c6_state_residency", "cpu_busy_cycles", "cpu_temperature",
|
|
|
|
|
"cpu_busy_frequency",
|
|
|
|
|
}
|
|
|
|
|
power.parseCPUMetricsConfig()
|
|
|
|
|
verifyCoreMetrics(t, power, true)
|
|
|
|
|
disableCoreMetrics(power)
|
|
|
|
|
verifyCoreMetrics(t, power, false)
|
|
|
|
|
|
|
|
|
|
power.CPUMetrics = []string{}
|
|
|
|
|
power.parseCPUMetricsConfig()
|
|
|
|
|
|
|
|
|
|
power.CPUMetrics = []string{"cpu_c6_state_residency", "#@$sdkjdfsdf3@", "1pu_c1_state_residency"}
|
|
|
|
|
power.parseCPUMetricsConfig()
|
|
|
|
|
require.Equal(t, false, power.cpuC1StateResidency)
|
|
|
|
|
require.Equal(t, true, power.cpuC6StateResidency)
|
|
|
|
|
disableCoreMetrics(power)
|
|
|
|
|
verifyCoreMetrics(t, power, false)
|
|
|
|
|
|
|
|
|
|
power.CPUMetrics = []string{"#@$sdkjdfsdf3@", "1pu_c1_state_residency", "123"}
|
|
|
|
|
power.parseCPUMetricsConfig()
|
|
|
|
|
verifyCoreMetrics(t, power, false)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func verifyCoreMetrics(t *testing.T, power *PowerStat, enabled bool) {
|
|
|
|
|
require.Equal(t, enabled, power.cpuFrequency)
|
|
|
|
|
require.Equal(t, enabled, power.cpuC1StateResidency)
|
|
|
|
|
require.Equal(t, enabled, power.cpuC6StateResidency)
|
|
|
|
|
require.Equal(t, enabled, power.cpuBusyCycles)
|
|
|
|
|
require.Equal(t, enabled, power.cpuBusyFrequency)
|
|
|
|
|
require.Equal(t, enabled, power.cpuTemperature)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestGather(t *testing.T) {
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
|
packageIDs := []string{"0", "1"}
|
|
|
|
|
coreIDs := []string{"0", "1", "2", "3"}
|
|
|
|
|
socketCurrentEnergy := 13213852.2
|
|
|
|
|
dramCurrentEnergy := 784552.0
|
|
|
|
|
preparedCPUData := getPreparedCPUData(coreIDs)
|
|
|
|
|
raplDataMap := prepareRaplDataMap(packageIDs, socketCurrentEnergy, dramCurrentEnergy)
|
|
|
|
|
|
|
|
|
|
power, _, raplMock, msrMock := getPowerWithMockedServices()
|
|
|
|
|
prepareCPUInfo(power, coreIDs, packageIDs)
|
|
|
|
|
enableCoreMetrics(power)
|
|
|
|
|
power.skipFirstIteration = false
|
|
|
|
|
|
|
|
|
|
raplMock.On("initializeRaplData", mock.Anything).
|
|
|
|
|
On("getRaplData").Return(raplDataMap).
|
|
|
|
|
On("retrieveAndCalculateData", mock.Anything).Return(nil).Times(len(raplDataMap)).
|
|
|
|
|
On("getConstraintMaxPowerWatts", mock.Anything).Return(546783852.3, nil)
|
|
|
|
|
msrMock.On("getCPUCoresData").Return(preparedCPUData).
|
|
|
|
|
On("openAndReadMsr", mock.Anything).Return(nil).
|
|
|
|
|
On("retrieveCPUFrequencyForCore", mock.Anything).Return(1200000.2, nil)
|
|
|
|
|
|
|
|
|
|
require.NoError(t, power.Gather(&acc))
|
|
|
|
|
// Number of global metrics : 3
|
|
|
|
|
// Number of per core metrics : 6
|
|
|
|
|
require.Equal(t, 3*len(packageIDs)+6*len(coreIDs), len(acc.GetTelegrafMetrics()))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestAddGlobalMetricsNegative(t *testing.T) {
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
|
socketCurrentEnergy := 13213852.2
|
|
|
|
|
dramCurrentEnergy := 784552.0
|
|
|
|
|
raplDataMap := prepareRaplDataMap([]string{"0", "1"}, socketCurrentEnergy, dramCurrentEnergy)
|
|
|
|
|
power, _, raplMock, _ := getPowerWithMockedServices()
|
|
|
|
|
power.skipFirstIteration = false
|
|
|
|
|
raplMock.On("initializeRaplData", mock.Anything).Once().
|
|
|
|
|
On("getRaplData").Return(raplDataMap).Once().
|
|
|
|
|
On("retrieveAndCalculateData", mock.Anything).Return(errors.New("error while calculating data")).Times(len(raplDataMap))
|
|
|
|
|
|
|
|
|
|
power.addGlobalMetrics(&acc)
|
|
|
|
|
require.Equal(t, 0, len(acc.GetTelegrafMetrics()))
|
|
|
|
|
raplMock.AssertNumberOfCalls(t, "retrieveAndCalculateData", len(raplDataMap))
|
|
|
|
|
|
|
|
|
|
raplMock.On("initializeRaplData", mock.Anything).Once().
|
|
|
|
|
On("getRaplData").Return(make(map[string]*raplData)).Once()
|
|
|
|
|
|
|
|
|
|
power.addGlobalMetrics(&acc)
|
|
|
|
|
require.Equal(t, 0, len(acc.GetTelegrafMetrics()))
|
|
|
|
|
raplMock.AssertNotCalled(t, "retrieveAndCalculateData")
|
|
|
|
|
|
|
|
|
|
raplMock.On("initializeRaplData", mock.Anything).Once().
|
|
|
|
|
On("getRaplData").Return(raplDataMap).
|
|
|
|
|
On("retrieveAndCalculateData", mock.Anything).Return(nil).Once().
|
|
|
|
|
On("retrieveAndCalculateData", mock.Anything).Return(errors.New("error while calculating data")).Once().
|
|
|
|
|
On("getConstraintMaxPowerWatts", mock.Anything).Return(12313851.5, nil).Twice()
|
|
|
|
|
|
|
|
|
|
power.addGlobalMetrics(&acc)
|
|
|
|
|
require.Equal(t, 3, len(acc.GetTelegrafMetrics()))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestAddGlobalMetricsPositive(t *testing.T) {
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
|
socketCurrentEnergy := 3644574.4
|
|
|
|
|
dramCurrentEnergy := 124234872.5
|
|
|
|
|
raplDataMap := prepareRaplDataMap([]string{"0", "1"}, socketCurrentEnergy, dramCurrentEnergy)
|
|
|
|
|
maxPower := 546783852.9
|
|
|
|
|
power, _, raplMock, _ := getPowerWithMockedServices()
|
|
|
|
|
power.skipFirstIteration = false
|
|
|
|
|
|
|
|
|
|
raplMock.On("initializeRaplData", mock.Anything).
|
|
|
|
|
On("getRaplData").Return(raplDataMap).
|
|
|
|
|
On("retrieveAndCalculateData", mock.Anything).Return(nil).Times(len(raplDataMap)).
|
|
|
|
|
On("getConstraintMaxPowerWatts", mock.Anything).Return(maxPower, nil).Twice().
|
|
|
|
|
On("getCurrentDramPowerConsumption", mock.Anything).Return(dramCurrentEnergy)
|
|
|
|
|
|
|
|
|
|
power.addGlobalMetrics(&acc)
|
|
|
|
|
require.Equal(t, 6, len(acc.GetTelegrafMetrics()))
|
|
|
|
|
|
|
|
|
|
expectedResults := getGlobalMetrics(maxPower, socketCurrentEnergy, dramCurrentEnergy)
|
|
|
|
|
for _, test := range expectedResults {
|
|
|
|
|
acc.AssertContainsTaggedFields(t, "powerstat_package", test.fields, test.tags)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestAddMetricsForSingleCoreNegative(t *testing.T) {
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
|
core := "0"
|
|
|
|
|
power, _, _, msrMock := getPowerWithMockedServices()
|
|
|
|
|
|
|
|
|
|
msrMock.On("openAndReadMsr", core).Return(errors.New("error reading MSR file")).Once()
|
|
|
|
|
|
|
|
|
|
// Skip generating metric for CPU frequency.
|
|
|
|
|
power.cpuFrequency = false
|
|
|
|
|
|
|
|
|
|
wg.Add(1)
|
|
|
|
|
power.addMetricsForSingleCore(core, &acc, &wg)
|
|
|
|
|
wg.Wait()
|
|
|
|
|
|
|
|
|
|
require.Equal(t, 0, len(acc.GetTelegrafMetrics()))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestAddCPUFrequencyMetric(t *testing.T) {
|
|
|
|
|
var acc testutil.Accumulator
|
2021-03-23 01:21:36 +08:00
|
|
|
cpuID := "1"
|
|
|
|
|
coreID := "3"
|
|
|
|
|
packageID := "0"
|
2020-12-11 04:23:27 +08:00
|
|
|
frequency := 1200000.2
|
|
|
|
|
power, _, _, msrMock := getPowerWithMockedServices()
|
|
|
|
|
prepareCPUInfoForSingleCPU(power, cpuID, coreID, packageID)
|
|
|
|
|
|
|
|
|
|
msrMock.On("retrieveCPUFrequencyForCore", mock.Anything).
|
|
|
|
|
Return(float64(0), errors.New("error on reading file")).Once()
|
|
|
|
|
|
|
|
|
|
power.addCPUFrequencyMetric(cpuID, &acc)
|
|
|
|
|
require.Equal(t, 0, len(acc.GetTelegrafMetrics()))
|
|
|
|
|
|
|
|
|
|
msrMock.On("retrieveCPUFrequencyForCore", mock.Anything).Return(frequency, nil).Once()
|
|
|
|
|
|
|
|
|
|
power.addCPUFrequencyMetric(cpuID, &acc)
|
|
|
|
|
require.Equal(t, 1, len(acc.GetTelegrafMetrics()))
|
|
|
|
|
|
|
|
|
|
expectedFrequency := roundFloatToNearestTwoDecimalPlaces(frequency)
|
|
|
|
|
expectedMetric := getPowerCoreMetric("cpu_frequency_mhz", expectedFrequency, coreID, packageID, cpuID)
|
|
|
|
|
acc.AssertContainsTaggedFields(t, "powerstat_core", expectedMetric.fields, expectedMetric.tags)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestAddCoreCPUTemperatureMetric(t *testing.T) {
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
|
cpuID := "0"
|
|
|
|
|
coreID := "2"
|
|
|
|
|
packageID := "1"
|
|
|
|
|
power, _, _, msrMock := getPowerWithMockedServices()
|
|
|
|
|
preparedData := getPreparedCPUData([]string{cpuID})
|
|
|
|
|
expectedTemp := preparedData[cpuID].throttleTemp - preparedData[cpuID].temp
|
|
|
|
|
prepareCPUInfoForSingleCPU(power, cpuID, coreID, packageID)
|
|
|
|
|
|
|
|
|
|
msrMock.On("getCPUCoresData").Return(preparedData).Once()
|
|
|
|
|
power.addCPUTemperatureMetric(cpuID, &acc)
|
|
|
|
|
require.Equal(t, 1, len(acc.GetTelegrafMetrics()))
|
|
|
|
|
|
|
|
|
|
expectedMetric := getPowerCoreMetric("cpu_temperature_celsius", expectedTemp, coreID, packageID, cpuID)
|
|
|
|
|
acc.AssertContainsTaggedFields(t, "powerstat_core", expectedMetric.fields, expectedMetric.tags)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestAddC6StateResidencyMetric(t *testing.T) {
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
|
cpuID := "0"
|
|
|
|
|
coreID := "2"
|
|
|
|
|
packageID := "1"
|
|
|
|
|
power, _, _, msrMock := getPowerWithMockedServices()
|
|
|
|
|
prepareCPUInfoForSingleCPU(power, cpuID, coreID, packageID)
|
|
|
|
|
preparedData := getPreparedCPUData([]string{cpuID})
|
|
|
|
|
expectedC6 := roundFloatToNearestTwoDecimalPlaces(percentageMultiplier *
|
|
|
|
|
float64(preparedData[cpuID].c6Delta) / float64(preparedData[cpuID].timeStampCounterDelta))
|
|
|
|
|
|
|
|
|
|
msrMock.On("getCPUCoresData").Return(preparedData).Twice()
|
|
|
|
|
power.addCPUC6StateResidencyMetric(cpuID, &acc)
|
|
|
|
|
require.Equal(t, 1, len(acc.GetTelegrafMetrics()))
|
|
|
|
|
|
|
|
|
|
expectedMetric := getPowerCoreMetric("cpu_c6_state_residency_percent", expectedC6, coreID, packageID, cpuID)
|
|
|
|
|
acc.AssertContainsTaggedFields(t, "powerstat_core", expectedMetric.fields, expectedMetric.tags)
|
|
|
|
|
|
|
|
|
|
acc.ClearMetrics()
|
|
|
|
|
preparedData[cpuID].timeStampCounterDelta = 0
|
|
|
|
|
|
|
|
|
|
power.addCPUC6StateResidencyMetric(cpuID, &acc)
|
|
|
|
|
require.Equal(t, 0, len(acc.GetTelegrafMetrics()))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestAddProcessorBusyCyclesMetric(t *testing.T) {
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
|
cpuID := "0"
|
|
|
|
|
coreID := "2"
|
|
|
|
|
packageID := "1"
|
|
|
|
|
power, _, _, msrMock := getPowerWithMockedServices()
|
|
|
|
|
prepareCPUInfoForSingleCPU(power, cpuID, coreID, packageID)
|
|
|
|
|
preparedData := getPreparedCPUData([]string{cpuID})
|
|
|
|
|
expectedBusyCycles := roundFloatToNearestTwoDecimalPlaces(percentageMultiplier * float64(preparedData[cpuID].mperfDelta) /
|
|
|
|
|
float64(preparedData[cpuID].timeStampCounterDelta))
|
|
|
|
|
|
|
|
|
|
msrMock.On("getCPUCoresData").Return(preparedData).Twice()
|
|
|
|
|
power.addCPUBusyCyclesMetric(cpuID, &acc)
|
|
|
|
|
require.Equal(t, 1, len(acc.GetTelegrafMetrics()))
|
|
|
|
|
|
|
|
|
|
expectedMetric := getPowerCoreMetric("cpu_busy_cycles_percent", expectedBusyCycles, coreID, packageID, cpuID)
|
|
|
|
|
acc.AssertContainsTaggedFields(t, "powerstat_core", expectedMetric.fields, expectedMetric.tags)
|
|
|
|
|
|
|
|
|
|
acc.ClearMetrics()
|
|
|
|
|
preparedData[cpuID].timeStampCounterDelta = 0
|
|
|
|
|
power.addCPUBusyCyclesMetric(cpuID, &acc)
|
|
|
|
|
require.Equal(t, 0, len(acc.GetTelegrafMetrics()))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestAddProcessorBusyFrequencyMetric(t *testing.T) {
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
|
cpuID := "0"
|
|
|
|
|
coreID := "2"
|
|
|
|
|
packageID := "1"
|
|
|
|
|
power, _, _, msrMock := getPowerWithMockedServices()
|
|
|
|
|
prepareCPUInfoForSingleCPU(power, cpuID, coreID, packageID)
|
|
|
|
|
preparedData := getPreparedCPUData([]string{cpuID})
|
|
|
|
|
power.skipFirstIteration = false
|
|
|
|
|
|
|
|
|
|
msrMock.On("getCPUCoresData").Return(preparedData).Twice()
|
|
|
|
|
power.addCPUBusyFrequencyMetric(cpuID, &acc)
|
|
|
|
|
require.Equal(t, 1, len(acc.GetTelegrafMetrics()))
|
|
|
|
|
|
|
|
|
|
acc.ClearMetrics()
|
|
|
|
|
preparedData[cpuID].mperfDelta = 0
|
|
|
|
|
power.addCPUBusyFrequencyMetric(cpuID, &acc)
|
|
|
|
|
require.Equal(t, 0, len(acc.GetTelegrafMetrics()))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestAddC1StateResidencyMetric(t *testing.T) {
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
|
cpuID := "0"
|
|
|
|
|
coreID := "2"
|
|
|
|
|
packageID := "1"
|
|
|
|
|
power, _, _, msrMock := getPowerWithMockedServices()
|
|
|
|
|
prepareCPUInfoForSingleCPU(power, cpuID, coreID, packageID)
|
|
|
|
|
preparedData := getPreparedCPUData([]string{cpuID})
|
|
|
|
|
c1 := preparedData[cpuID].timeStampCounterDelta - preparedData[cpuID].mperfDelta - preparedData[cpuID].c3Delta -
|
|
|
|
|
preparedData[cpuID].c6Delta - preparedData[cpuID].c7Delta
|
|
|
|
|
expectedC1 := roundFloatToNearestTwoDecimalPlaces(percentageMultiplier * float64(c1) / float64(preparedData[cpuID].timeStampCounterDelta))
|
|
|
|
|
|
|
|
|
|
msrMock.On("getCPUCoresData").Return(preparedData).Twice()
|
|
|
|
|
|
|
|
|
|
power.addCPUC1StateResidencyMetric(cpuID, &acc)
|
|
|
|
|
require.Equal(t, 1, len(acc.GetTelegrafMetrics()))
|
|
|
|
|
|
|
|
|
|
expectedMetric := getPowerCoreMetric("cpu_c1_state_residency_percent", expectedC1, coreID, packageID, cpuID)
|
|
|
|
|
acc.AssertContainsTaggedFields(t, "powerstat_core", expectedMetric.fields, expectedMetric.tags)
|
|
|
|
|
|
|
|
|
|
acc.ClearMetrics()
|
|
|
|
|
preparedData[cpuID].timeStampCounterDelta = 0
|
|
|
|
|
power.addCPUC1StateResidencyMetric(cpuID, &acc)
|
|
|
|
|
require.Equal(t, 0, len(acc.GetTelegrafMetrics()))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestAddThermalDesignPowerMetric(t *testing.T) {
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
|
sockets := []string{"0"}
|
|
|
|
|
maxPower := 195720672.1
|
|
|
|
|
power, _, raplMock, _ := getPowerWithMockedServices()
|
|
|
|
|
|
|
|
|
|
raplMock.On("getConstraintMaxPowerWatts", mock.Anything).
|
|
|
|
|
Return(float64(0), errors.New("getConstraintMaxPowerWatts error")).Once().
|
|
|
|
|
On("getConstraintMaxPowerWatts", mock.Anything).Return(maxPower, nil).Once()
|
|
|
|
|
|
|
|
|
|
power.addThermalDesignPowerMetric(sockets[0], &acc)
|
|
|
|
|
require.Equal(t, 0, len(acc.GetTelegrafMetrics()))
|
|
|
|
|
|
|
|
|
|
power.addThermalDesignPowerMetric(sockets[0], &acc)
|
|
|
|
|
require.Equal(t, 1, len(acc.GetTelegrafMetrics()))
|
|
|
|
|
|
|
|
|
|
expectedTDP := roundFloatToNearestTwoDecimalPlaces(maxPower)
|
|
|
|
|
expectedMetric := getPowerGlobalMetric("thermal_design_power_watts", expectedTDP, sockets[0])
|
|
|
|
|
acc.AssertContainsTaggedFields(t, "powerstat_package", expectedMetric.fields, expectedMetric.tags)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getPreparedCPUData(cores []string) map[string]*msrData {
|
|
|
|
|
msrDataMap := make(map[string]*msrData)
|
|
|
|
|
|
|
|
|
|
for _, core := range cores {
|
|
|
|
|
msrDataMap[core] = &msrData{
|
|
|
|
|
mperf: 43079,
|
|
|
|
|
aperf: 82001,
|
|
|
|
|
timeStampCounter: 15514,
|
|
|
|
|
c3: 52829,
|
|
|
|
|
c6: 86930,
|
|
|
|
|
c7: 25340,
|
|
|
|
|
throttleTemp: 88150,
|
|
|
|
|
temp: 40827,
|
|
|
|
|
mperfDelta: 23515,
|
|
|
|
|
aperfDelta: 33866,
|
|
|
|
|
timeStampCounterDelta: 13686000,
|
|
|
|
|
c3Delta: 20003,
|
|
|
|
|
c6Delta: 44518,
|
|
|
|
|
c7Delta: 20979,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return msrDataMap
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getGlobalMetrics(maxPower float64, socketCurrentEnergy float64, dramCurrentEnergy float64) []struct {
|
|
|
|
|
fields map[string]interface{}
|
|
|
|
|
tags map[string]string
|
|
|
|
|
} {
|
|
|
|
|
return []struct {
|
|
|
|
|
fields map[string]interface{}
|
|
|
|
|
tags map[string]string
|
|
|
|
|
}{
|
|
|
|
|
getPowerGlobalMetric("thermal_design_power_watts", roundFloatToNearestTwoDecimalPlaces(maxPower), "0"),
|
|
|
|
|
getPowerGlobalMetric("thermal_design_power_watts", roundFloatToNearestTwoDecimalPlaces(maxPower), "1"),
|
|
|
|
|
getPowerGlobalMetric("current_power_consumption_watts", roundFloatToNearestTwoDecimalPlaces(socketCurrentEnergy), "0"),
|
|
|
|
|
getPowerGlobalMetric("current_power_consumption_watts", roundFloatToNearestTwoDecimalPlaces(socketCurrentEnergy), "1"),
|
|
|
|
|
getPowerGlobalMetric("current_dram_power_consumption_watts", roundFloatToNearestTwoDecimalPlaces(dramCurrentEnergy), "0"),
|
|
|
|
|
getPowerGlobalMetric("current_dram_power_consumption_watts", roundFloatToNearestTwoDecimalPlaces(dramCurrentEnergy), "1"),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getPowerCoreMetric(name string, value interface{}, coreID string, packageID string, cpuID string) struct {
|
|
|
|
|
fields map[string]interface{}
|
|
|
|
|
tags map[string]string
|
|
|
|
|
} {
|
|
|
|
|
return getPowerMetric(name, value, map[string]string{"package_id": packageID, "core_id": coreID, "cpu_id": cpuID})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getPowerGlobalMetric(name string, value interface{}, socketID string) struct {
|
|
|
|
|
fields map[string]interface{}
|
|
|
|
|
tags map[string]string
|
|
|
|
|
} {
|
|
|
|
|
return getPowerMetric(name, value, map[string]string{"package_id": socketID})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getPowerMetric(name string, value interface{}, tags map[string]string) struct {
|
|
|
|
|
fields map[string]interface{}
|
|
|
|
|
tags map[string]string
|
|
|
|
|
} {
|
|
|
|
|
return struct {
|
|
|
|
|
fields map[string]interface{}
|
|
|
|
|
tags map[string]string
|
|
|
|
|
}{
|
|
|
|
|
map[string]interface{}{
|
|
|
|
|
name: value,
|
|
|
|
|
},
|
|
|
|
|
tags,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func prepareCPUInfoForSingleCPU(power *PowerStat, cpuID string, coreID string, packageID string) {
|
|
|
|
|
power.cpuInfo = make(map[string]*cpuInfo)
|
|
|
|
|
power.cpuInfo[cpuID] = &cpuInfo{
|
|
|
|
|
physicalID: packageID,
|
|
|
|
|
coreID: coreID,
|
|
|
|
|
cpuID: cpuID,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func prepareCPUInfo(power *PowerStat, coreIDs []string, packageIDs []string) {
|
|
|
|
|
power.cpuInfo = make(map[string]*cpuInfo)
|
|
|
|
|
currentCPU := 0
|
|
|
|
|
for _, packageID := range packageIDs {
|
|
|
|
|
for _, coreID := range coreIDs {
|
|
|
|
|
cpuID := strconv.Itoa(currentCPU)
|
|
|
|
|
power.cpuInfo[cpuID] = &cpuInfo{
|
|
|
|
|
physicalID: packageID,
|
|
|
|
|
cpuID: cpuID,
|
|
|
|
|
coreID: coreID,
|
|
|
|
|
}
|
|
|
|
|
currentCPU++
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func enableCoreMetrics(power *PowerStat) {
|
|
|
|
|
power.cpuC1StateResidency = true
|
|
|
|
|
power.cpuC6StateResidency = true
|
|
|
|
|
power.cpuTemperature = true
|
|
|
|
|
power.cpuBusyFrequency = true
|
|
|
|
|
power.cpuFrequency = true
|
|
|
|
|
power.cpuBusyCycles = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func disableCoreMetrics(power *PowerStat) {
|
|
|
|
|
power.cpuC1StateResidency = false
|
|
|
|
|
power.cpuC6StateResidency = false
|
|
|
|
|
power.cpuTemperature = false
|
|
|
|
|
power.cpuBusyFrequency = false
|
|
|
|
|
power.cpuFrequency = false
|
|
|
|
|
power.cpuBusyCycles = false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func prepareRaplDataMap(socketIDs []string, socketCurrentEnergy float64, dramCurrentEnergy float64) map[string]*raplData {
|
|
|
|
|
raplDataMap := make(map[string]*raplData, len(socketIDs))
|
|
|
|
|
for _, socketID := range socketIDs {
|
|
|
|
|
raplDataMap[socketID] = &raplData{
|
|
|
|
|
socketCurrentEnergy: socketCurrentEnergy,
|
|
|
|
|
dramCurrentEnergy: dramCurrentEnergy,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return raplDataMap
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getPowerWithMockedServices() (*PowerStat, *mockFileService, *mockRaplService, *mockMsrService) {
|
|
|
|
|
fsMock := &mockFileService{}
|
|
|
|
|
msrMock := &mockMsrService{}
|
|
|
|
|
raplMock := &mockRaplService{}
|
|
|
|
|
logger := testutil.Logger{Name: "PowerPluginTest"}
|
|
|
|
|
p := newPowerStat(fsMock)
|
|
|
|
|
p.Log = logger
|
|
|
|
|
p.fs = fsMock
|
|
|
|
|
p.rapl = raplMock
|
|
|
|
|
p.msr = msrMock
|
|
|
|
|
|
|
|
|
|
return p, fsMock, raplMock, msrMock
|
|
|
|
|
}
|