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

110 lines
3.6 KiB
Go

//go:build linux
package scenario
import (
"encoding/json"
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/nezhahq/nezha/integration/agentcompat/internal/contract"
)
func TestStress_PlanHasFourRoundsSixteenOpsEach(t *testing.T) {
profile, err := contract.ProfileByName(string(contract.ProfilePRFull))
require.NoError(t, err)
plan, err := GenerateStressPlan(profile, contract.DefaultSeed)
require.NoError(t, err)
require.Len(t, plan.Rounds, 4)
for _, round := range plan.Rounds {
require.Len(t, round.Operations, 16)
}
}
func TestStress_PlanUsesTwoRequestsPerPATPerRound(t *testing.T) {
profile, err := contract.ProfileByName(string(contract.ProfilePRFull))
require.NoError(t, err)
plan, err := GenerateStressPlan(profile, contract.DefaultSeed)
require.NoError(t, err)
for _, round := range plan.Rounds {
counts := make(map[StressPATID]int)
kinds := make(map[StressPATID]map[StressOperationKind]int)
for _, operation := range round.Operations {
counts[operation.PAT]++
if kinds[operation.PAT] == nil {
kinds[operation.PAT] = make(map[StressOperationKind]int)
}
kinds[operation.PAT][operation.Kind]++
}
require.Len(t, counts, 8)
for pat, count := range counts {
require.Equal(t, 2, count)
require.Equal(t, 1, kinds[pat][StressOperationExec])
require.Equal(t, 1, kinds[pat][StressOperationFilesystem])
}
}
}
func TestStress_PlanHas64UniqueStableIDs(t *testing.T) {
profile, err := contract.ProfileByName(string(contract.ProfilePRFull))
require.NoError(t, err)
plan, err := GenerateStressPlan(profile, contract.DefaultSeed)
require.NoError(t, err)
seen := make(map[StressOperationID]struct{})
for _, round := range plan.Rounds {
for _, operation := range round.Operations {
_, duplicate := seen[operation.ID]
require.False(t, duplicate)
seen[operation.ID] = struct{}{}
}
}
require.Len(t, seen, 64)
}
func TestStress_PlanFixedSeedReproducesByteForByte(t *testing.T) {
profile, err := contract.ProfileByName(string(contract.ProfilePRFull))
require.NoError(t, err)
first, err := GenerateStressPlan(profile, contract.DefaultSeed)
require.NoError(t, err)
second, err := GenerateStressPlan(profile, contract.DefaultSeed)
require.NoError(t, err)
firstJSON, err := json.Marshal(first)
require.NoError(t, err)
secondJSON, err := json.Marshal(second)
require.NoError(t, err)
require.Equal(t, firstJSON, secondJSON)
}
func TestStress_RejectsLaunchWindowOverOneSecond(t *testing.T) {
profile, err := contract.ProfileByName(string(contract.ProfilePRFull))
require.NoError(t, err)
plan, err := GenerateStressPlan(profile, contract.DefaultSeed)
require.NoError(t, err)
evidence := successfulStressRoundEvidence(plan.Rounds[0])
evidence.Operations[len(evidence.Operations)-1].LaunchedAt = evidence.Operations[0].LaunchedAt.Add(time.Second + time.Nanosecond)
evidence.Operations[len(evidence.Operations)-1].CompletedAt = evidence.Operations[len(evidence.Operations)-1].LaunchedAt.Add(time.Millisecond)
err = ValidateStressRoundEvidence(plan.Rounds[0], evidence)
require.ErrorIs(t, err, ErrStressLaunchWindow)
}
func successfulStressRoundEvidence(plan StressRoundPlan) StressRoundEvidence {
started := time.Unix(100, 0)
operations := make([]StressOperationEvidence, len(plan.Operations))
for index, operation := range plan.Operations {
operations[index] = StressOperationEvidence{
ID: operation.ID, Round: operation.Round, Agent: operation.Agent, PAT: operation.PAT, Kind: operation.Kind, SuccessProof: "ok",
LaunchedAt: started, CompletedAt: started.Add(time.Millisecond), Succeeded: true,
}
}
return StressRoundEvidence{Round: plan.Round, Operations: operations}
}