Files
nezha_domains/integration/agentcompat/internal/scenario/reconnect.go
T
2026-07-20 04:51:20 +00:00

76 lines
2.2 KiB
Go

//go:build linux
package scenario
import (
"context"
"errors"
"fmt"
"slices"
"time"
"github.com/nezhahq/nezha/integration/agentcompat/internal/contract"
)
type ReconnectInput struct {
Paths contract.Paths
DashboardFault string
}
type ReconnectObservation struct {
ServerID uint64
UUID string
OldGeneration uint64
NewGeneration uint64
DisconnectAt time.Time
ReconnectAt time.Time
TaskIDs []uint64
ResultIDs []uint64
PostReconnect bool
AgentRestarted bool
}
type ReconnectResult struct {
Observation ReconnectObservation `json:"observation"`
CleanupOK bool `json:"cleanup_ok"`
Passed bool `json:"passed"`
Error string `json:"error,omitempty"`
}
type Reconnect struct{}
func (scenario Reconnect) Run(ctx context.Context, input ReconnectInput) (Result, error) {
result, _, err := scenario.RunWithEvidence(ctx, input)
return result, err
}
func (observation ReconnectObservation) Validate() error {
if observation.ServerID == 0 || observation.UUID == "" {
return errors.New("reconnect observation omitted server identity")
}
if observation.OldGeneration == 0 || observation.NewGeneration <= observation.OldGeneration {
return errors.New("reconnect generations are not strictly increasing")
}
if observation.DisconnectAt.IsZero() || observation.ReconnectAt.IsZero() || !observation.ReconnectAt.After(observation.DisconnectAt) {
return errors.New("reconnect timestamps are not ordered")
}
if len(observation.TaskIDs) == 0 || !slices.Equal(observation.TaskIDs, observation.ResultIDs) {
return errors.New("reconnect task and result IDs differ")
}
seenTaskIDs := make(map[uint64]struct{}, len(observation.TaskIDs))
for _, taskID := range observation.TaskIDs {
if _, exists := seenTaskIDs[taskID]; exists {
return fmt.Errorf("reconnect task ID %d was duplicated", taskID)
}
seenTaskIDs[taskID] = struct{}{}
}
if !observation.PostReconnect || !observation.AgentRestarted {
return errors.New("reconnect post-process checks were not completed")
}
return nil
}
func (observation ReconnectObservation) ReconnectInterval() time.Duration {
return observation.ReconnectAt.Sub(observation.DisconnectAt)
}