Files
nezha_domains/integration/agentcompat/internal/scenario/stress_resource_test.go
T
2026-07-20 04:54:03 +00:00

179 lines
5.1 KiB
Go

//go:build linux
package scenario
import (
"testing"
"github.com/stretchr/testify/require"
processharness "github.com/nezhahq/nezha/integration/agentcompat/internal/process"
)
func TestStress_RejectsLeakedFD(t *testing.T) {
input := stressDashboardResourceFixture(100)
for index := range input.End.Samples {
input.End.Samples[index].NonStdioFDCount++
}
_, err := EvaluateStressResource(input)
require.ErrorIs(t, err, ErrStressResourceDrift)
}
func TestStress_RejectsSingleSampleFDTransient(t *testing.T) {
input := stressDashboardResourceFixture(100)
input.End.Samples[4].NonStdioFDCount++
_, err := EvaluateStressResource(input)
require.ErrorIs(t, err, ErrStressResourceDrift)
}
func TestStress_AcceptsRecoveredBaselineFDTransient(t *testing.T) {
input := stressDashboardResourceFixture(100)
input.Baseline.Samples[1].NonStdioFDCount = 9
evaluation, err := EvaluateStressResource(input)
require.NoError(t, err)
require.Equal(t, 3, evaluation.Baseline.NonStdioFDs)
require.Equal(t, 3, evaluation.End.NonStdioFDs)
}
func TestStress_RejectsSingleSampleDescendantTransient(t *testing.T) {
input := stressDashboardResourceFixture(100)
input.End.Samples[4].DescendantCount++
_, err := EvaluateStressResource(input)
require.ErrorIs(t, err, ErrStressResourceDrift)
}
func TestStress_RejectsSingleSampleTCPTransient(t *testing.T) {
input := stressDashboardResourceFixture(100)
input.End.Samples[4].TCPListenerCount++
_, err := EvaluateStressResource(input)
require.ErrorIs(t, err, ErrStressResourceDrift)
}
func TestStress_RejectsSingleSampleTCP6Transient(t *testing.T) {
input := stressDashboardResourceFixture(100)
input.End.Samples[4].TCP6ListenerCount++
_, err := EvaluateStressResource(input)
require.ErrorIs(t, err, ErrStressResourceDrift)
}
func TestStress_RejectsDecreasedDescendants(t *testing.T) {
input := stressDashboardResourceFixture(100)
for index := range input.End.Samples {
input.End.Samples[index].DescendantCount = 0
input.Baseline.Samples[index].DescendantCount = 1
}
_, err := EvaluateStressResource(input)
require.ErrorIs(t, err, ErrStressResourceDrift)
}
func TestStress_RejectsDecreasedFDs(t *testing.T) {
input := stressDashboardResourceFixture(100)
for index := range input.End.Samples {
input.End.Samples[index].NonStdioFDCount = 2
input.Baseline.Samples[index].NonStdioFDCount = 3
}
_, err := EvaluateStressResource(input)
require.ErrorIs(t, err, ErrStressResourceDrift)
}
func TestStress_RejectsDecreasedTCPListeners(t *testing.T) {
input := stressDashboardResourceFixture(100)
for index := range input.End.Samples {
input.End.Samples[index].TCPListenerCount = 0
input.Baseline.Samples[index].TCPListenerCount = 1
}
_, err := EvaluateStressResource(input)
require.ErrorIs(t, err, ErrStressResourceDrift)
}
func TestStress_RejectsDecreasedTCP6Listeners(t *testing.T) {
input := stressDashboardResourceFixture(100)
for index := range input.End.Samples {
input.End.Samples[index].TCP6ListenerCount = 0
input.Baseline.Samples[index].TCP6ListenerCount = 1
}
_, err := EvaluateStressResource(input)
require.ErrorIs(t, err, ErrStressResourceDrift)
}
func TestStress_RejectsDashboardRSSOverLimit(t *testing.T) {
input := stressDashboardResourceFixture(100)
input.End.Samples[4].RSSBytes = 100 + 67108865
_, err := EvaluateStressResource(input)
require.ErrorIs(t, err, ErrStressRSSLimit)
}
func TestStress_RejectsAgentRSSOverLimit(t *testing.T) {
agent, err := NewStressAgentOrdinal(4)
require.NoError(t, err)
identity, err := NewStressAgentProcess(agent, 404)
require.NoError(t, err)
input := StressProcessWindows{Process: identity, Baseline: stressWindow(404, 100), End: stressWindow(404, 100+33554433)}
_, err = EvaluateStressResource(input)
require.ErrorIs(t, err, ErrStressRSSLimit)
}
func TestStress_RejectsVanishedPID(t *testing.T) {
input := stressDashboardResourceFixture(100)
input.End.Samples[2].PID = 0
_, err := EvaluateStressResource(input)
require.ErrorIs(t, err, ErrStressProcessWindow)
}
func TestStress_RejectsIncompleteSampleWindow(t *testing.T) {
input := stressDashboardResourceFixture(100)
input.End.Samples = input.End.Samples[:4]
_, err := EvaluateStressResource(input)
require.ErrorIs(t, err, ErrStressProcessWindow)
}
func TestStress_UsesFinalCountSampleButWindowRSSMaximum(t *testing.T) {
input := stressDashboardResourceFixture(100)
input.Baseline.Samples[0].NonStdioFDCount = 4
input.End.Samples[0].NonStdioFDCount = 4
input.End.Samples[4].RSSBytes = 110
evaluation, err := EvaluateStressResource(input)
require.NoError(t, err)
require.Equal(t, uint64(10), evaluation.RSSDeltaBytes)
}
func stressDashboardResourceFixture(rss uint64) StressProcessWindows {
identity, err := NewStressDashboardProcess(101)
if err != nil {
panic(err)
}
return StressProcessWindows{Process: identity, Baseline: stressWindow(101, rss), End: stressWindow(101, rss)}
}
func stressWindow(pid int, rss uint64) processharness.Window {
samples := make([]processharness.Sample, 5)
for index := range samples {
samples[index] = processharness.Sample{PID: pid, RSSBytes: rss, NonStdioFDCount: 3, TCPListenerCount: 1}
}
return processharness.Window{PID: pid, Samples: samples}
}