mirror of
https://github.com/Buriburizaem0n/nezha_domains.git
synced 2026-09-22 11:10:12 +00:00
test(agentcompat): add integration scenarios
Co-authored-by: naiba/CloudCode <hi+cloudcode@nai.ba>
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
//go:build linux
|
||||
|
||||
package scenario
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/nezhahq/nezha/integration/agentcompat/internal/agent"
|
||||
"github.com/nezhahq/nezha/integration/agentcompat/internal/dashboard"
|
||||
processharness "github.com/nezhahq/nezha/integration/agentcompat/internal/process"
|
||||
)
|
||||
|
||||
type ReconnectFixtureEvidence struct {
|
||||
Dashboard dashboard.FixtureIdentity `json:"dashboard"`
|
||||
AgentRoot string `json:"agent_root"`
|
||||
AgentConfigPath string `json:"agent_config_path"`
|
||||
AgentBinaryPath string `json:"agent_binary_path"`
|
||||
}
|
||||
|
||||
type ReconnectRuntimeEvidence struct {
|
||||
DashboardBefore dashboard.RuntimeIdentity `json:"dashboard_before"`
|
||||
DashboardAfter dashboard.RuntimeIdentity `json:"dashboard_after"`
|
||||
AgentBefore agent.ProcessIdentity `json:"agent_before"`
|
||||
AgentAfter agent.ProcessIdentity `json:"agent_after"`
|
||||
StateGenerationBeforeAgentRestart uint64 `json:"state_generation_before_agent_restart"`
|
||||
StateGenerationAfterAgentRestart uint64 `json:"state_generation_after_agent_restart"`
|
||||
}
|
||||
|
||||
type ReconnectIdentityEvidence struct {
|
||||
ServerID uint64 `json:"server_id"`
|
||||
UUID string `json:"uuid"`
|
||||
DashboardConfigUnchanged bool `json:"dashboard_config_unchanged"`
|
||||
AgentConfigUnchanged bool `json:"agent_config_unchanged"`
|
||||
DashboardFixtureUnchanged bool `json:"dashboard_fixture_unchanged"`
|
||||
ClientsRecreated bool `json:"clients_recreated"`
|
||||
BootstrapRecreated bool `json:"bootstrap_recreated"`
|
||||
}
|
||||
|
||||
type ReconnectLifecycleEvidence struct {
|
||||
DisconnectAt time.Time `json:"disconnect_at"`
|
||||
ReconnectAt time.Time `json:"reconnect_at"`
|
||||
ReconnectInterval time.Duration `json:"reconnect_interval"`
|
||||
DashboardReceipts []dashboard.MCPReceiptPair `json:"dashboard_receipts"`
|
||||
AgentReceipts []dashboard.MCPReceiptPair `json:"agent_receipts"`
|
||||
StaleGenerationReceipts int `json:"stale_generation_receipts"`
|
||||
DuplicateTaskIDs int `json:"duplicate_task_ids"`
|
||||
LostResultIDs int `json:"lost_result_ids"`
|
||||
OutsideRootSentinelUnchanged bool `json:"outside_root_sentinel_unchanged"`
|
||||
}
|
||||
|
||||
type ReconnectEvidence struct {
|
||||
Fixture ReconnectFixtureEvidence `json:"fixture"`
|
||||
Runtime ReconnectRuntimeEvidence `json:"runtime"`
|
||||
Identity ReconnectIdentityEvidence `json:"identity"`
|
||||
Lifecycle ReconnectLifecycleEvidence `json:"lifecycle"`
|
||||
Observation ReconnectObservation `json:"observation"`
|
||||
AgentCleanup processharness.CleanupReceipt `json:"agent_cleanup"`
|
||||
DashboardCleanup processharness.CleanupReceipt `json:"dashboard_cleanup"`
|
||||
}
|
||||
|
||||
func (e ReconnectEvidence) Validate() error {
|
||||
var validationErr error
|
||||
validationErr = errors.Join(validationErr, e.Observation.Validate())
|
||||
if e.Runtime.DashboardAfter.Generation <= e.Runtime.DashboardBefore.Generation || e.Runtime.DashboardAfter.PID == e.Runtime.DashboardBefore.PID {
|
||||
validationErr = errors.Join(validationErr, errors.New("Dashboard runtime generation did not advance"))
|
||||
}
|
||||
if e.Runtime.AgentAfter.Generation <= e.Runtime.AgentBefore.Generation || e.Runtime.AgentAfter.PID == e.Runtime.AgentBefore.PID {
|
||||
validationErr = errors.Join(validationErr, errors.New("Agent runtime generation did not advance"))
|
||||
}
|
||||
if e.Runtime.StateGenerationAfterAgentRestart <= e.Runtime.StateGenerationBeforeAgentRestart {
|
||||
validationErr = errors.Join(validationErr, errors.New("Agent state stream generation did not advance"))
|
||||
}
|
||||
if !e.Identity.DashboardConfigUnchanged || !e.Identity.AgentConfigUnchanged || !e.Identity.DashboardFixtureUnchanged || !e.Identity.ClientsRecreated || !e.Identity.BootstrapRecreated {
|
||||
validationErr = errors.Join(validationErr, errors.New("reconnect identity evidence is incomplete"))
|
||||
}
|
||||
if e.Lifecycle.ReconnectInterval <= 0 || e.Lifecycle.StaleGenerationReceipts != 0 || e.Lifecycle.DuplicateTaskIDs != 0 || e.Lifecycle.LostResultIDs != 0 || !e.Lifecycle.OutsideRootSentinelUnchanged {
|
||||
validationErr = errors.Join(validationErr, fmt.Errorf("reconnect lifecycle evidence is invalid: interval=%s stale=%d duplicate=%d lost=%d sentinel=%t", e.Lifecycle.ReconnectInterval, e.Lifecycle.StaleGenerationReceipts, e.Lifecycle.DuplicateTaskIDs, e.Lifecycle.LostResultIDs, e.Lifecycle.OutsideRootSentinelUnchanged))
|
||||
}
|
||||
return validationErr
|
||||
}
|
||||
Reference in New Issue
Block a user