- 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>
97 lines
2.9 KiB
Go
97 lines
2.9 KiB
Go
package lifecycle
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
type stubEventBus struct {
|
|
failUntil int
|
|
attempts int
|
|
txHash string
|
|
}
|
|
|
|
func (s *stubEventBus) Publish(event ModuleEvent) error {
|
|
s.attempts++
|
|
if s.attempts <= s.failUntil {
|
|
return fmt.Errorf("publish failure %d for tx %s", s.attempts, s.txHash)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *stubEventBus) Subscribe(eventType EventType, handler EventHandler) error {
|
|
return nil
|
|
}
|
|
|
|
func TestModuleRegistryPublishEventWithRetrySuccess(t *testing.T) {
|
|
registry := NewModuleRegistry(RegistryConfig{
|
|
EventPublishRetries: 3,
|
|
EventPublishDelay: time.Nanosecond,
|
|
})
|
|
registry.logger = nil
|
|
|
|
bus := &stubEventBus{failUntil: 2, txHash: "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"}
|
|
registry.eventBus = bus
|
|
|
|
err := registry.publishEventWithRetry(ModuleEvent{ModuleID: "module-A", Type: EventModuleStarted}, "publish failed")
|
|
if err != nil {
|
|
t.Fatalf("expected publish to eventually succeed, got %v", err)
|
|
}
|
|
if bus.attempts != 3 {
|
|
t.Fatalf("expected 3 attempts, got %d", bus.attempts)
|
|
}
|
|
if err := registry.aggregatedErrors(); err != nil {
|
|
t.Fatalf("expected no aggregated errors, got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestModuleRegistryPublishEventWithRetryFailure(t *testing.T) {
|
|
registry := NewModuleRegistry(RegistryConfig{
|
|
EventPublishRetries: 2,
|
|
EventPublishDelay: time.Nanosecond,
|
|
})
|
|
registry.logger = nil
|
|
|
|
txHash := "0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
|
|
bus := &stubEventBus{failUntil: 3, txHash: txHash}
|
|
registry.eventBus = bus
|
|
|
|
err := registry.publishEventWithRetry(ModuleEvent{ModuleID: "module-B", Type: EventModuleStopped}, "publish failed")
|
|
if err == nil {
|
|
t.Fatal("expected publish to fail after retries")
|
|
}
|
|
if bus.attempts != 2 {
|
|
t.Fatalf("expected 2 attempts, got %d", bus.attempts)
|
|
}
|
|
|
|
exported := registry.RegistryErrors()
|
|
if len(exported) != 1 {
|
|
t.Fatalf("expected 1 recorded registry error, got %d", len(exported))
|
|
}
|
|
if exported[0] == nil {
|
|
t.Fatal("expected recorded error to be non-nil")
|
|
}
|
|
if copyErrs := registry.RegistryErrors(); copyErrs[0] == nil {
|
|
t.Fatal("copy of registry errors should preserve values")
|
|
}
|
|
if got := exported[0].Error(); !strings.Contains(got, txHash) {
|
|
t.Fatalf("recorded registry error should include tx hash, got %q", got)
|
|
}
|
|
details := registry.RegistryErrorDetails()
|
|
if len(details) != 1 {
|
|
t.Fatalf("expected registry error details to include entry, got %d", len(details))
|
|
}
|
|
if details[0].TxHash != txHash {
|
|
t.Fatalf("expected registry error detail to track tx hash %s, got %s", txHash, details[0].TxHash)
|
|
}
|
|
agg := registry.aggregatedErrors()
|
|
if agg == nil {
|
|
t.Fatal("expected aggregated error to be returned")
|
|
}
|
|
if got := agg.Error(); !strings.Contains(got, "publish failed") || !strings.Contains(got, "publish failure 1") || !strings.Contains(got, txHash) {
|
|
t.Fatalf("aggregated error should include failure details and tx hash, got %q", got)
|
|
}
|
|
}
|