- Added comprehensive bounds checking to prevent buffer overruns in multicall parsing - Implemented graduated validation system (Strict/Moderate/Permissive) to reduce false positives - Added LRU caching system for address validation with 10-minute TTL - Enhanced ABI decoder with missing Universal Router and Arbitrum-specific DEX signatures - Fixed duplicate function declarations and import conflicts across multiple files - Added error recovery mechanisms with multiple fallback strategies - Updated tests to handle new validation behavior for suspicious addresses - Fixed parser test expectations for improved validation system - Applied gofmt formatting fixes to ensure code style compliance - Fixed mutex copying issues in monitoring package by introducing MetricsSnapshot - Resolved critical security vulnerabilities in heuristic address extraction - Progress: Updated TODO audit from 10% to 35% complete 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
107 lines
3.3 KiB
Go
107 lines
3.3 KiB
Go
package lifecycle
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
type stubHealthNotifier struct {
|
|
failUntil int
|
|
attempts int
|
|
txHash string
|
|
}
|
|
|
|
func (s *stubHealthNotifier) NotifyHealthChange(moduleID string, oldHealth, newHealth ModuleHealth) error {
|
|
s.attempts++
|
|
if s.attempts <= s.failUntil {
|
|
return fmt.Errorf("notify failure %d for tx %s", s.attempts, s.txHash)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *stubHealthNotifier) NotifySystemHealth(health OverallHealth) error {
|
|
return nil
|
|
}
|
|
|
|
func (s *stubHealthNotifier) NotifyAlert(alert HealthAlert) error {
|
|
return nil
|
|
}
|
|
|
|
func TestHealthMonitorNotifyWithRetrySuccess(t *testing.T) {
|
|
config := HealthMonitorConfig{
|
|
NotificationRetries: 3,
|
|
NotificationRetryDelay: time.Nanosecond,
|
|
}
|
|
hm := NewHealthMonitor(config)
|
|
hm.logger = nil
|
|
|
|
notifier := &stubHealthNotifier{failUntil: 2, txHash: "0xdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"}
|
|
hm.notifier = notifier
|
|
|
|
err := hm.notifyWithRetry(func() error {
|
|
return notifier.NotifyHealthChange("module", ModuleHealth{}, ModuleHealth{})
|
|
}, "notify failure", "module_id", "module")
|
|
if err != nil {
|
|
t.Fatalf("expected notification to eventually succeed, got %v", err)
|
|
}
|
|
if notifier.attempts != 3 {
|
|
t.Fatalf("expected 3 attempts, got %d", notifier.attempts)
|
|
}
|
|
if errs := hm.NotificationErrors(); len(errs) != 0 {
|
|
t.Fatalf("expected no recorded notification errors, got %d", len(errs))
|
|
}
|
|
if hm.aggregatedNotificationError() != nil {
|
|
t.Fatal("expected aggregated notification error to be nil")
|
|
}
|
|
}
|
|
|
|
func TestHealthMonitorNotifyWithRetryFailure(t *testing.T) {
|
|
config := HealthMonitorConfig{
|
|
NotificationRetries: 2,
|
|
NotificationRetryDelay: time.Nanosecond,
|
|
}
|
|
hm := NewHealthMonitor(config)
|
|
hm.logger = nil
|
|
|
|
txHash := "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
|
|
notifier := &stubHealthNotifier{failUntil: 3, txHash: txHash}
|
|
hm.notifier = notifier
|
|
|
|
err := hm.notifyWithRetry(func() error {
|
|
return notifier.NotifyHealthChange("module", ModuleHealth{}, ModuleHealth{})
|
|
}, "notify failure", "module_id", "module")
|
|
if err == nil {
|
|
t.Fatal("expected notification to fail after retries")
|
|
}
|
|
if notifier.attempts != 2 {
|
|
t.Fatalf("expected 2 attempts, got %d", notifier.attempts)
|
|
}
|
|
exported := hm.NotificationErrors()
|
|
if len(exported) != 1 {
|
|
t.Fatalf("expected 1 recorded notification error, got %d", len(exported))
|
|
}
|
|
copyErrs := hm.NotificationErrors()
|
|
if copyErrs[0] == nil {
|
|
t.Fatal("expected copy of notification errors to retain value")
|
|
}
|
|
if got := exported[0].Error(); !strings.Contains(got, txHash) {
|
|
t.Fatalf("recorded notification error should include tx hash, got %q", got)
|
|
}
|
|
details := hm.NotificationErrorDetails()
|
|
if len(details) != 1 {
|
|
t.Fatalf("expected notification error details entry, got %d", len(details))
|
|
}
|
|
if details[0].TxHash != txHash {
|
|
t.Fatalf("expected notification error detail to track tx hash %s, got %s", txHash, details[0].TxHash)
|
|
}
|
|
agg := hm.aggregatedNotificationError()
|
|
if agg == nil {
|
|
t.Fatal("expected aggregated notification error to be returned")
|
|
}
|
|
if got := agg.Error(); !strings.Contains(got, "notify failure") || !strings.Contains(got, "notify failure 1") || !strings.Contains(got, txHash) {
|
|
t.Fatalf("aggregated notification error should include failure details and tx hash, got %q", got)
|
|
}
|
|
}
|