Add tiered LOTL mining onion and fleet recon so agents can fallback across execution tiers while operators see spread and vuln posture in Crucible. Includes triple-onion chain, spread cred graph, and full Go/TS/E2E test validation.
This commit is contained in:
75
server/internal/api/agent_ws_limiter_test.go
Normal file
75
server/internal/api/agent_ws_limiter_test.go
Normal file
@@ -0,0 +1,75 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func resetAgentWSRateLim(t *testing.T) {
|
||||
t.Helper()
|
||||
agentWSRateLim.mu.Lock()
|
||||
agentWSRateLim.attempts = make(map[string][]time.Time)
|
||||
agentWSRateLim.mu.Unlock()
|
||||
}
|
||||
|
||||
func TestAllowAgentWSUpgradeRateLimit(t *testing.T) {
|
||||
t.Run("rejects 31st attempt within window", func(t *testing.T) {
|
||||
resetAgentWSRateLim(t)
|
||||
ip := "203.0.113.42"
|
||||
|
||||
for i := 1; i <= agentWSRateLimitMax; i++ {
|
||||
if !allowAgentWSUpgrade(ip) {
|
||||
t.Fatalf("attempt %d: expected allow, got reject", i)
|
||||
}
|
||||
}
|
||||
if allowAgentWSUpgrade(ip) {
|
||||
t.Fatal("31st attempt: expected reject, got allow")
|
||||
}
|
||||
if allowAgentWSUpgrade(ip) {
|
||||
t.Fatal("32nd attempt: expected reject, got allow")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("empty IP bypasses limit", func(t *testing.T) {
|
||||
resetAgentWSRateLim(t)
|
||||
|
||||
for i := 1; i <= agentWSRateLimitMax+5; i++ {
|
||||
if !allowAgentWSUpgrade("") {
|
||||
t.Fatalf("empty IP attempt %d: expected allow, got reject", i)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("stale attempts outside window are pruned", func(t *testing.T) {
|
||||
resetAgentWSRateLim(t)
|
||||
ip := "198.51.100.7"
|
||||
stale := time.Now().Add(-agentWSRateLimitWindow - time.Second)
|
||||
|
||||
agentWSRateLim.mu.Lock()
|
||||
staleAttempts := make([]time.Time, agentWSRateLimitMax)
|
||||
for i := range staleAttempts {
|
||||
staleAttempts[i] = stale
|
||||
}
|
||||
agentWSRateLim.attempts[ip] = staleAttempts
|
||||
agentWSRateLim.mu.Unlock()
|
||||
|
||||
if !allowAgentWSUpgrade(ip) {
|
||||
t.Fatal("expected allow after stale attempts pruned")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("different IPs have independent limits", func(t *testing.T) {
|
||||
resetAgentWSRateLim(t)
|
||||
ipA := "192.0.2.1"
|
||||
ipB := "192.0.2.2"
|
||||
|
||||
for i := 1; i <= agentWSRateLimitMax; i++ {
|
||||
if !allowAgentWSUpgrade(ipA) {
|
||||
t.Fatalf("ipA attempt %d: expected allow, got reject", i)
|
||||
}
|
||||
}
|
||||
if !allowAgentWSUpgrade(ipB) {
|
||||
t.Fatal("ipB first attempt: expected allow after ipA exhausted")
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user