Skip to content

Commit

Permalink
Fix hostmetricsreceiver/processscraper tests to work for darwin (#20538)
Browse files Browse the repository at this point in the history
* fix hostmetricsreceiver/processscraper tests to work for darwin

* remove changes from the do not edit file and add tests

* fix skipTestOnUnsupportedOS to not skip darwin and errors following it following code review

* fix typo following code review
  • Loading branch information
8naama authored Apr 10, 2023
1 parent 5fbe4fa commit ec8176d
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 12 deletions.
16 changes: 16 additions & 0 deletions .chloggen/update-processmetrics-tests-darwin.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: bug_fix

# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
component: hostmetricsreceiver/processscraper

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: fixing the processmetrics tests to support testing collection in darwin

# One or more tracking issues related to the change
issues: [19141]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext: Darwin only supports some of the processmetrics + using Cmdline to get the Executable Path, which caused tests to fail.
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import (
)

func skipTestOnUnsupportedOS(t *testing.T) {
if runtime.GOOS != "linux" && runtime.GOOS != "windows" {
if runtime.GOOS != "linux" && runtime.GOOS != "windows" && runtime.GOOS != "darwin" {
t.Skipf("skipping test on %v", runtime.GOOS)
}
}
Expand Down Expand Up @@ -91,6 +91,11 @@ func TestScrape(t *testing.T) {
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
metricsBuilderConfig := metadata.DefaultMetricsBuilderConfig()
if runtime.GOOS == "darwin" {
// disable darwin unsupported default metric
metricsBuilderConfig.Metrics.ProcessDiskIo.Enabled = false
}

if test.mutateMetricsSettings != nil {
test.mutateMetricsSettings(t, &metricsBuilderConfig.Metrics)
}
Expand Down Expand Up @@ -129,7 +134,9 @@ func TestScrape(t *testing.T) {
assertMetricMissing(t, md.ResourceMetrics(), "process.cpu.utilization")
}
assertMemoryUsageMetricValid(t, md.ResourceMetrics(), expectedStartTime)
assertDiskIoMetricValid(t, md.ResourceMetrics(), expectedStartTime)
if metricsBuilderConfig.Metrics.ProcessDiskIo.Enabled {
assertDiskIoMetricValid(t, md.ResourceMetrics(), expectedStartTime)
}
if metricsBuilderConfig.Metrics.ProcessDiskOperations.Enabled {
assertDiskOperationsMetricValid(t, md.ResourceMetrics(), expectedStartTime)
} else {
Expand Down Expand Up @@ -663,6 +670,7 @@ func TestScrapeMetrics_ProcessErrors(t *testing.T) {
},
{
name: "Exe Error",
osFilter: "darwin",
exeError: errors.New("err1"),
expectedError: func() string {
if runtime.GOOS == "windows" {
Expand All @@ -674,6 +682,7 @@ func TestScrapeMetrics_ProcessErrors(t *testing.T) {
},
{
name: "Cmdline Error",
osFilter: "darwin",
cmdlineError: errors.New("err2"),
expectedError: `error reading command for process "test" (pid 1): err2`,
},
Expand All @@ -699,46 +708,55 @@ func TestScrapeMetrics_ProcessErrors(t *testing.T) {
},
{
name: "Memory Percent Error",
osFilter: "darwin",
memoryPercentError: errors.New("err-mem-percent"),
expectedError: `error reading memory utilization for process "test" (pid 1): err-mem-percent`,
},
{
name: "IO Counters Error",
osFilter: "darwin",
ioCountersError: errors.New("err7"),
expectedError: `error reading disk usage for process "test" (pid 1): err7`,
},
{
name: "Parent PID Error",
osFilter: "darwin",
parentPidError: errors.New("err8"),
expectedError: `error reading parent pid for process "test" (pid 1): err8`,
},
{
name: "Page Faults Error",
osFilter: "darwin",
pageFaultsError: errors.New("err-paging"),
expectedError: `error reading memory paging info for process "test" (pid 1): err-paging`,
},
{
name: "Thread count Error",
osFilter: "darwin",
numThreadsError: errors.New("err8"),
expectedError: `error reading thread info for process "test" (pid 1): err8`,
},
{
name: "Context Switches Error",
osFilter: "darwin",
numCtxSwitchesError: errors.New("err9"),
expectedError: `error reading context switch counts for process "test" (pid 1): err9`,
},
{
name: "File Descriptors Error",
osFilter: "darwin",
numFDsError: errors.New("err10"),
expectedError: `error reading open file descriptor count for process "test" (pid 1): err10`,
},
{
name: "Signals Pending Error",
osFilter: "darwin",
rlimitError: errors.New("err-rlimit"),
expectedError: `error reading pending signals for process "test" (pid 1): err-rlimit`,
},
{
name: "Multiple Errors",
osFilter: "darwin",
cmdlineError: errors.New("err2"),
usernameError: errors.New("err3"),
createTimeError: errors.New("err4"),
Expand Down Expand Up @@ -766,14 +784,28 @@ func TestScrapeMetrics_ProcessErrors(t *testing.T) {
},
}

if runtime.GOOS == "darwin" {
darwinTestCase := testCase{
name: "Darwin Cmdline Error",
cmdlineError: errors.New("err2"),
expectedError: `error reading process executable for pid 1: err2; error reading command for process "test" (pid 1): err2`,
}
testCases = append(testCases, darwinTestCase)
}

for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
if test.osFilter == runtime.GOOS {
t.Skipf("skipping test %v on %v", test.name, runtime.GOOS)
}

metricsBuilderConfig := metadata.DefaultMetricsBuilderConfig()
enableOptionalMetrics(&metricsBuilderConfig.Metrics)
if runtime.GOOS != "darwin" {
enableOptionalMetrics(&metricsBuilderConfig.Metrics)
} else {
// disable darwin unsupported default metric
metricsBuilderConfig.Metrics.ProcessDiskIo.Enabled = false
}

scraper, err := newProcessScraper(receivertest.NewNopCreateSettings(), &Config{MetricsBuilderConfig: metricsBuilderConfig})
require.NoError(t, err, "Failed to create process scraper: %v", err)
Expand Down Expand Up @@ -815,15 +847,21 @@ func TestScrapeMetrics_ProcessErrors(t *testing.T) {

md, err := scraper.scrape(context.Background())

expectedResourceMetricsLen, expectedMetricsLen := getExpectedLengthOfReturnedMetrics(test.nameError, test.exeError, test.timesError, test.memoryInfoError, test.memoryPercentError, test.ioCountersError, test.pageFaultsError, test.numThreadsError, test.numCtxSwitchesError, test.numFDsError, test.rlimitError)
// In darwin we get the exe path with Cmdline()
executableError := test.exeError
if runtime.GOOS == "darwin" {
executableError = test.cmdlineError
}

expectedResourceMetricsLen, expectedMetricsLen := getExpectedLengthOfReturnedMetrics(test.nameError, executableError, test.timesError, test.memoryInfoError, test.memoryPercentError, test.ioCountersError, test.pageFaultsError, test.numThreadsError, test.numCtxSwitchesError, test.numFDsError, test.rlimitError)
assert.Equal(t, expectedResourceMetricsLen, md.ResourceMetrics().Len())
assert.Equal(t, expectedMetricsLen, md.MetricCount())

assert.EqualError(t, err, test.expectedError)
isPartial := scrapererror.IsPartialScrapeError(err)
assert.True(t, isPartial)
if isPartial {
expectedFailures := getExpectedScrapeFailures(test.nameError, test.exeError, test.timesError, test.memoryInfoError, test.memoryPercentError, test.ioCountersError, test.pageFaultsError, test.numThreadsError, test.numCtxSwitchesError, test.numFDsError, test.rlimitError)
expectedFailures := getExpectedScrapeFailures(test.nameError, executableError, test.timesError, test.memoryInfoError, test.memoryPercentError, test.ioCountersError, test.pageFaultsError, test.numThreadsError, test.numCtxSwitchesError, test.numFDsError, test.rlimitError)
var scraperErr scrapererror.PartialScrapeError
require.ErrorAs(t, err, &scraperErr)
assert.Equal(t, expectedFailures, scraperErr.Failed)
Expand All @@ -848,25 +886,25 @@ func getExpectedLengthOfReturnedMetrics(nameError, exeError, timeError, memError
if memError == nil {
expectedLen += memoryMetricsLen
}
if memPercentError == nil {
if memPercentError == nil && runtime.GOOS != "darwin" {
expectedLen += memoryUtilizationMetricsLen
}
if diskError == nil {
if diskError == nil && runtime.GOOS != "darwin" {
expectedLen += diskMetricsLen
}
if pageFaultsError == nil {
if pageFaultsError == nil && runtime.GOOS != "darwin" {
expectedLen += pagingMetricsLen
}
if rlimitError == nil {
if rlimitError == nil && runtime.GOOS != "darwin" {
expectedLen += signalMetricsLen
}
if threadError == nil {
if threadError == nil && runtime.GOOS != "darwin" {
expectedLen += threadMetricsLen
}
if contextSwitchError == nil {
if contextSwitchError == nil && runtime.GOOS != "darwin" {
expectedLen += contextSwitchMetricsLen
}
if fileDescriptorError == nil {
if fileDescriptorError == nil && runtime.GOOS != "darwin" {
expectedLen += fileDescriptorMetricsLen
}

Expand All @@ -885,6 +923,13 @@ func getExpectedScrapeFailures(nameError, exeError, timeError, memError, memPerc
return 1
}
_, expectedMetricsLen := getExpectedLengthOfReturnedMetrics(nameError, exeError, timeError, memError, memPercentError, diskError, pageFaultsError, threadError, contextSwitchError, fileDescriptorError, rlimitError)

// excluding unsupported metrics from darwin 'metricsLen'
if runtime.GOOS == "darwin" {
darwinMetricsLen := cpuMetricsLen + memoryMetricsLen
return darwinMetricsLen - expectedMetricsLen
}

return metricsLen - expectedMetricsLen
}

Expand Down Expand Up @@ -973,6 +1018,7 @@ func TestScrapeMetrics_MuteErrorFlags(t *testing.T) {
handleMock := &processHandleMock{}
handleMock.On("Name").Return("test", processNameError)
handleMock.On("Exe").Return("test", processNameError)
handleMock.On("Cmdline").Return("test", processNameError)

if config.MuteProcessIOError {
handleMock.On("IOCounters").Return("test", errors.New("permission denied"))
Expand Down

0 comments on commit ec8176d

Please sign in to comment.