mirror of
https://github.com/Buriburizaem0n/nezha_domains.git
synced 2026-09-19 09:40:12 +00:00
153 lines
6.3 KiB
Go
153 lines
6.3 KiB
Go
//go:build linux && agentcompat
|
|
|
|
package scenario
|
|
|
|
import (
|
|
"context"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/nezhahq/nezha/integration/agentcompat/internal/client"
|
|
"github.com/nezhahq/nezha/integration/agentcompat/internal/fixture"
|
|
)
|
|
|
|
type stressOperationExecutor struct {
|
|
fixture *heldSessionSetRealFixture
|
|
plan StressOperationPlan
|
|
}
|
|
|
|
func (executor stressOperationExecutor) run(ctx context.Context) StressOperationEvidence {
|
|
started := time.Now()
|
|
proof, err := executor.execute(ctx)
|
|
completed := time.Now()
|
|
evidenceValue := StressOperationEvidence{ID: executor.plan.ID, Round: executor.plan.Round, Agent: executor.plan.Agent, PAT: executor.plan.PAT, Kind: executor.plan.Kind, LaunchedAt: started, CompletedAt: completed, Succeeded: err == nil, SuccessProof: proof}
|
|
if err != nil {
|
|
evidenceValue.Error = errorText(err)
|
|
}
|
|
return evidenceValue
|
|
}
|
|
|
|
func (executor stressOperationExecutor) execute(ctx context.Context) (string, error) {
|
|
if executor.fixture == nil || executor.plan.Agent.Int() < 1 || executor.plan.Agent.Int() > len(executor.fixture.agents) || executor.plan.Agent.Int() > len(executor.fixture.readiness) || executor.plan.Agent.Int() > len(executor.fixture.agentPATs) {
|
|
return "", errors.New("stress operation fixture mapping is invalid")
|
|
}
|
|
if executor.plan.PAT.String() == "" {
|
|
return "", errors.New("stress operation PAT is empty")
|
|
}
|
|
serverID := executor.fixture.readiness[executor.plan.Agent.Int()-1].ServerID
|
|
patIdentity, err := stressOperationPATIdentity(executor.fixture, executor.plan)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
switch executor.plan.Kind {
|
|
case StressOperationExec:
|
|
return executor.exec(ctx, patIdentity.Client, serverID)
|
|
case StressOperationFilesystem:
|
|
return executor.filesystem(ctx, patIdentity.Client, serverID)
|
|
default:
|
|
return "", errors.New("unsupported stress operation kind")
|
|
}
|
|
}
|
|
|
|
func stressOperationPATIdentity(fixture *heldSessionSetRealFixture, plan StressOperationPlan) (heldRealPATIdentity, error) {
|
|
index := plan.Agent.Int() - 1
|
|
for _, round := range fixture.plan.Rounds {
|
|
for _, planned := range round.Operations {
|
|
if planned.ID == plan.ID {
|
|
if planned.Agent != plan.Agent || planned.Kind != plan.Kind || planned.PAT != plan.PAT {
|
|
return heldRealPATIdentity{}, errors.New("stress operation plan PAT mapping is invalid")
|
|
}
|
|
return fixture.agentPATs[index], nil
|
|
}
|
|
}
|
|
}
|
|
for _, round := range fixture.plan.Rounds {
|
|
for _, planned := range round.Operations {
|
|
if planned.Agent == plan.Agent && planned.PAT == plan.PAT && planned.Kind == plan.Kind {
|
|
return fixture.agentPATs[index], nil
|
|
}
|
|
}
|
|
}
|
|
return heldRealPATIdentity{}, errors.New("stress operation is absent from canonical plan")
|
|
}
|
|
|
|
func runStressWarmups(ctx context.Context, fixture *heldSessionSetRealFixture, plan StressPlan) ([]StressWarmupEvidence, error) {
|
|
warmups := make([]StressWarmupEvidence, 0, len(fixture.agents))
|
|
for agentIndex := range fixture.agents {
|
|
agentOrdinal, err := NewStressAgentOrdinal(agentIndex + 1)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
pat := StressPATID{}
|
|
for _, operation := range plan.Rounds[0].Operations {
|
|
if operation.Agent == agentOrdinal {
|
|
pat = operation.PAT
|
|
break
|
|
}
|
|
}
|
|
if pat.String() == "" {
|
|
return nil, errors.New("stress warmup PAT mapping is invalid")
|
|
}
|
|
execID, err := NewStressOperationID(fmt.Sprintf("warmup-exec-a%02d", agentOrdinal.Int()))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
execResult := stressOperationExecutor{fixture: fixture, plan: StressOperationPlan{ID: execID, Agent: agentOrdinal, PAT: pat, Kind: StressOperationExec}}
|
|
if _, err := execResult.execute(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
filesystemID, err := NewStressOperationID(fmt.Sprintf("warmup-filesystem-a%02d", agentOrdinal.Int()))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
filesystemResult := stressOperationExecutor{fixture: fixture, plan: StressOperationPlan{ID: filesystemID, Round: 0, Agent: agentOrdinal, PAT: pat, Kind: StressOperationFilesystem}}
|
|
if _, err := filesystemResult.execute(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
warmups = append(warmups, StressWarmupEvidence{Agent: agentOrdinal, Exec: true, Filesystem: true, Terminal: true, NAT: true, FM: true})
|
|
}
|
|
return warmups, nil
|
|
}
|
|
|
|
func (executor stressOperationExecutor) exec(ctx context.Context, patClient *client.Client, serverID uint64) (string, error) {
|
|
const token = "agentcompat-stress-exec-proof"
|
|
result, err := client.CallTool[execArguments, execResult](ctx, patClient, client.ToolCall[execArguments]{Name: "server.exec", Arguments: execArguments{ServerID: serverID, Cmd: "/bin/sh", Args: []string{"-c", "printf " + token}}})
|
|
if err != nil || result.StructuredContent.ExitCode != 0 || result.StructuredContent.Stdout != token || result.StructuredContent.Error != "" || result.StructuredContent.TimedOut || result.StructuredContent.StdoutTruncated {
|
|
return "", errors.New("stress Exec proof failed")
|
|
}
|
|
return stressProof(token), nil
|
|
}
|
|
|
|
func (executor stressOperationExecutor) filesystem(ctx context.Context, patClient *client.Client, serverID uint64) (string, error) {
|
|
parent := executor.fixture.agents[executor.plan.Agent.Int()-1].WorkspaceRoot()
|
|
return executeStressFilesystemProof(ctx, patClient, serverID, parent, executor.plan.ID.String(), executor.plan.Round)
|
|
}
|
|
|
|
func executeStressFilesystemProof(ctx context.Context, patClient *client.Client, serverID uint64, parent, operationID string, round int) (string, error) {
|
|
root, err := fixture.NewAgentRoot(parent, fmt.Sprintf("stress-%s", operationID))
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
defer os.RemoveAll(root.Absolute())
|
|
filesystem := newMCPFilesystemClient(patClient, serverID, root)
|
|
content := "agentcompat-stress-filesystem-proof"
|
|
relative := fmt.Sprintf("round-%d/%s.txt", round, operationID)
|
|
written, err := filesystem.write(ctx, mcpFilesystemWrite{relative: relative, content: content, encoding: "utf8", mode: "0600", createDirs: true})
|
|
if err != nil {
|
|
return "", fmt.Errorf("stress filesystem write proof failed: %w", err)
|
|
}
|
|
if written.StructuredContent.Size != int64(len(content)) || written.StructuredContent.SHA256 != stressProof(content) || written.StructuredContent.Error != "" {
|
|
return "", errors.New("stress filesystem write proof response invalid")
|
|
}
|
|
return stressProof(content), nil
|
|
}
|
|
|
|
func stressProof(value string) string {
|
|
digest := sha256.Sum256([]byte(value))
|
|
return hex.EncodeToString(digest[:])
|
|
}
|