mirror of
https://github.com/Buriburizaem0n/nezha_domains.git
synced 2026-09-19 09:40:12 +00:00
148 lines
5.8 KiB
Go
148 lines
5.8 KiB
Go
//go:build linux
|
|
|
|
package scenario
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/nezhahq/nezha/integration/agentcompat/internal/contract"
|
|
)
|
|
|
|
func TestStressEvidence_AcceptsCompleteSuccessContract(t *testing.T) {
|
|
profile, err := contract.ProfileByName(string(contract.ProfilePRFull))
|
|
require.NoError(t, err)
|
|
evidence := validStressEvidence(t, profile)
|
|
|
|
err = evidence.ValidateSuccess(profile)
|
|
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
func TestStressEvidence_AcceptsOnlyExactStressWorkerFault(t *testing.T) {
|
|
profile, err := contract.ProfileByName(string(contract.ProfilePRFull))
|
|
require.NoError(t, err)
|
|
evidence := validStressEvidence(t, profile)
|
|
target := StressWorkerFaultTarget()
|
|
evidence.FaultTarget = &target
|
|
faultOperation := findStressFaultOperation(evidence.Plan)
|
|
for roundIndex := range evidence.Iterations[0].Rounds {
|
|
for operationIndex := range evidence.Iterations[0].Rounds[roundIndex].Operations {
|
|
operation := &evidence.Iterations[0].Rounds[roundIndex].Operations[operationIndex]
|
|
if operation.ID == faultOperation.ID {
|
|
operation.Succeeded = false
|
|
operation.Error = "injected stress worker fault"
|
|
}
|
|
}
|
|
}
|
|
|
|
err = evidence.ValidateStressWorker(profile)
|
|
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
func TestStressEvidence_RejectsSecondFailedOperationForStressWorker(t *testing.T) {
|
|
profile, err := contract.ProfileByName(string(contract.ProfilePRFull))
|
|
require.NoError(t, err)
|
|
evidence := validStressEvidence(t, profile)
|
|
target := StressWorkerFaultTarget()
|
|
evidence.FaultTarget = &target
|
|
evidence.Iterations[0].Rounds[1].Operations[0].Succeeded = false
|
|
evidence.Iterations[0].Rounds[1].Operations[0].Error = "injected stress worker fault"
|
|
evidence.Iterations[0].Rounds[1].Operations[1].Succeeded = false
|
|
evidence.Iterations[0].Rounds[1].Operations[1].Error = "unexpected failure"
|
|
|
|
err = evidence.ValidateStressWorker(profile)
|
|
|
|
require.ErrorIs(t, err, ErrStressFault)
|
|
}
|
|
|
|
func TestStressEvidence_RejectsSelfConsistentTruncatedPlan(t *testing.T) {
|
|
profile, err := contract.ProfileByName(string(contract.ProfilePRFull))
|
|
require.NoError(t, err)
|
|
evidence := validStressEvidence(t, profile)
|
|
evidence.Plan.Rounds = evidence.Plan.Rounds[:1]
|
|
evidence.Iterations[0].Rounds = evidence.Iterations[0].Rounds[:1]
|
|
|
|
err = evidence.ValidateSuccess(profile)
|
|
|
|
require.ErrorIs(t, err, ErrStressEvidence)
|
|
}
|
|
|
|
func TestStressEvidence_RejectsDuplicateDashboardResources(t *testing.T) {
|
|
profile, err := contract.ProfileByName(string(contract.ProfilePRFull))
|
|
require.NoError(t, err)
|
|
evidence := validStressEvidence(t, profile)
|
|
evidence.Iterations[0].Resources[1] = evidence.Iterations[0].Resources[0]
|
|
|
|
err = evidence.ValidateSuccess(profile)
|
|
|
|
require.ErrorIs(t, err, ErrStressEvidence)
|
|
}
|
|
|
|
func validStressEvidence(t *testing.T, profile contract.Profile) StressEvidence {
|
|
t.Helper()
|
|
plan, err := GenerateStressPlan(profile, contract.DefaultSeed)
|
|
require.NoError(t, err)
|
|
warmups := make([]StressWarmupEvidence, profile.AgentCount())
|
|
for index := range warmups {
|
|
agent, agentErr := NewStressAgentOrdinal(index + 1)
|
|
require.NoError(t, agentErr)
|
|
warmups[index] = StressWarmupEvidence{Agent: agent, Exec: true, Filesystem: true, Terminal: true, NAT: true, FM: true}
|
|
}
|
|
sessions := make([]StressSessionEvidence, len(plan.Sessions))
|
|
for index, session := range plan.Sessions {
|
|
sessions[index] = StressSessionEvidence{ID: session.ID, Kind: session.Kind, Succeeded: true}
|
|
}
|
|
rounds := make([]StressRoundEvidence, len(plan.Rounds))
|
|
started := time.Unix(100, 0)
|
|
for roundIndex, round := range plan.Rounds {
|
|
operations := make([]StressOperationEvidence, len(round.Operations))
|
|
for operationIndex, operation := range round.Operations {
|
|
operations[operationIndex] = StressOperationEvidence{ID: operation.ID, Round: operation.Round, Agent: operation.Agent, PAT: operation.PAT, Kind: operation.Kind, LaunchedAt: started, CompletedAt: started.Add(time.Millisecond), Succeeded: true, SuccessProof: "ok"}
|
|
}
|
|
rounds[roundIndex] = StressRoundEvidence{Round: round.Round, Operations: operations}
|
|
}
|
|
resources := make([]StressProcessWindows, 0, profile.AgentCount()+1)
|
|
resources = append(resources, stressDashboardResourceFixture(100))
|
|
for index := 1; index <= profile.AgentCount(); index++ {
|
|
agent, agentErr := NewStressAgentOrdinal(index)
|
|
require.NoError(t, agentErr)
|
|
process, processErr := NewStressAgentProcess(agent, 200+index)
|
|
require.NoError(t, processErr)
|
|
resources = append(resources, StressProcessWindows{Process: process, Baseline: stressWindow(200+index, 100), End: stressWindow(200+index, 100)})
|
|
}
|
|
iterations := make([]StressIterationEvidence, profile.Iterations())
|
|
for index := range iterations {
|
|
iterations[index] = StressIterationEvidence{Iteration: index + 1, Rounds: rounds, Resources: resources}
|
|
}
|
|
return StressEvidence{
|
|
Version: 1, Profile: profile.Name(), Seed: contract.DefaultSeed, Plan: plan,
|
|
PreparedBinaries: StressPreparedBinaries{DashboardBuildCount: 1, DashboardPathReused: true, AgentBuildCount: 1, AgentPathReused: true},
|
|
Quotas: StressQuotaEvidence{
|
|
PATSecond: quotaBoundary(10, 11), PATMinute: quotaBoundary(120, 121),
|
|
UserStreams: quotaBoundary(20, 21), ServerStreams: quotaBoundary(40, 41), PathLockStripes: 1024,
|
|
},
|
|
Warmups: warmups, Sessions: sessions, Iterations: iterations,
|
|
Cleanup: StressCleanupSummary{Passed: true, ReceiptCount: 9},
|
|
}
|
|
}
|
|
|
|
func quotaBoundary(allowed, rejected int) StressQuotaBoundary {
|
|
return StressQuotaBoundary{Allowed: allowed, Rejected: rejected, AllowedAccepted: true, RejectedDenied: true}
|
|
}
|
|
|
|
func findStressFaultOperation(plan StressPlan) StressOperationPlan {
|
|
target := StressWorkerFaultTarget()
|
|
for _, round := range plan.Rounds {
|
|
for _, operation := range round.Operations {
|
|
if round.Round == target.Round && operation.Agent == target.Agent && operation.Kind == target.Kind {
|
|
return operation
|
|
}
|
|
}
|
|
}
|
|
panic("stress fault operation missing")
|
|
}
|