//go:build stress // +build stress package stress_test import ( "context" "fmt" "math/big" "math/rand" "sync" "sync/atomic" "testing" "time" "github.com/ethereum/go-ethereum/common" "github.com/holiman/uint256" "github.com/fraktal/mev-beta/internal/logger" "github.com/fraktal/mev-beta/pkg/arbitrum" "github.com/fraktal/mev-beta/pkg/events" "github.com/fraktal/mev-beta/pkg/pools" "github.com/fraktal/mev-beta/pkg/profitcalc" "github.com/fraktal/mev-beta/pkg/scanner/market" "github.com/fraktal/mev-beta/pkg/trading" ) // BenchmarkStressTestSuite runs benchmark tests for the stress test suite func BenchmarkStressTestSuite(b *testing.B) { // Create test logger log := logger.New("warn", "text", "") // Use warn level to minimize logging overhead // Create test components protocolRegistry := arbitrum.NewArbitrumProtocolRegistry(log) poolCache := pools.NewPoolCache(10000, time.Hour) marketDiscovery := market.NewMarketDiscovery(nil, log, "") strategyEngine := arbitrum.NewMEVStrategyEngine(log, protocolRegistry) profitCalculator := profitcalc.NewProfitCalculatorWithClient(log, nil) mevAnalyzer := arbitrum.NewMEVAnalyzer(log) slippageProtector := trading.NewSlippageProtection(nil, log) capitalOptimizer := arbitrum.NewCapitalOptimizer(log) profitTracker := arbitrum.NewProfitabilityTracker(log) // Create stress test suite suite := NewStressTestSuite( log, protocolRegistry, poolCache, marketDiscovery, strategyEngine, profitCalculator, mevAnalyzer, slippageProtector, capitalOptimizer, profitTracker, ) // Run benchmark tests b.Run("MarketScannerStressTest", func(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { result := suite.RunMarketScannerStressTest() if !result.Passed { b.Fatalf("Market scanner stress test failed: %v", result.Errors) } } }) b.Run("SwapAnalyzerStressTest", func(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { result := suite.RunSwapAnalyzerStressTest() if !result.Passed { b.Fatalf("Swap analyzer stress test failed: %v", result.Errors) } } }) b.Run("PoolDiscoveryStressTest", func(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { result := suite.RunPoolDiscoveryStressTest() if !result.Passed { b.Fatalf("Pool discovery stress test failed: %v", result.Errors) } } }) b.Run("ArbitrageEngineStressTest", func(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { result := suite.RunArbitrageEngineStressTest() if !result.Passed { b.Fatalf("Arbitrage engine stress test failed: %v", result.Errors) } } }) b.Run("EventProcessingStressTest", func(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { result := suite.RunEventProcessingStressTest() if !result.Passed { b.Fatalf("Event processing stress test failed: %v", result.Errors) } } }) b.Run("ProfitCalculationStressTest", func(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { result := suite.RunProfitCalculationStressTest() if !result.Passed { b.Fatalf("Profit calculation stress test failed: %v", result.Errors) } } }) b.Run("ConcurrencyStressTest", func(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { result := suite.RunConcurrencyStressTest() if !result.Passed { b.Fatalf("Concurrency stress test failed: %v", result.Errors) } } }) b.Run("MemoryStressTest", func(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { result := suite.RunMemoryStressTest() if !result.Passed { b.Fatalf("Memory stress test failed: %v", result.Errors) } } }) b.Run("PerformanceRegressionTest", func(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { result := suite.RunPerformanceRegressionTest() if !result.Passed { b.Fatalf("Performance regression test failed: %v", result.Errors) } } }) } // BenchmarkConcurrentMarketScanning benchmarks concurrent market scanning performance func BenchmarkConcurrentMarketScanning(b *testing.B) { // Create test logger log := logger.New("warn", "text", "") // Use warn level to minimize logging overhead // Create test components protocolRegistry := arbitrum.NewArbitrumProtocolRegistry(log) poolCache := pools.NewPoolCache(10000, time.Hour) marketDiscovery := market.NewMarketDiscovery(nil, log, "") strategyEngine := arbitrum.NewMEVStrategyEngine(log, protocolRegistry) profitCalculator := profitcalc.NewProfitCalculatorWithClient(log, nil) mevAnalyzer := arbitrum.NewMEVAnalyzer(log) slippageProtector := trading.NewSlippageProtection(nil, log) capitalOptimizer := arbitrum.NewCapitalOptimizer(log) profitTracker := arbitrum.NewProfitabilityTracker(log) // Create stress test suite suite := NewStressTestSuite( log, protocolRegistry, poolCache, marketDiscovery, strategyEngine, profitCalculator, mevAnalyzer, slippageProtector, capitalOptimizer, profitTracker, ) // Generate test data testPools := suite.generateTestPools(1000) testEvents := suite.generateTestEvents(10000) b.ResetTimer() b.Run("ConcurrentPoolScanning", func(b *testing.B) { for i := 0; i < b.N; i++ { var wg sync.WaitGroup errorCount := int64(0) // Process pools concurrently for _, pool := range testPools { wg.Add(1) go func(p *market.CachedData) { defer wg.Done() // Simulate pool scanning ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() // Mock pool scanning operation err := suite.mockPoolScan(ctx, p) if err != nil { atomic.AddInt64(&errorCount, 1) } }(pool) } // Wait for all operations to complete wg.Wait() if errorCount > 0 { b.Fatalf("Concurrent pool scanning failed with %d errors", errorCount) } } }) b.Run("ConcurrentEventProcessing", func(b *testing.B) { for i := 0; i < b.N; i++ { var wg sync.WaitGroup errorCount := int64(0) // Process events concurrently for _, event := range testEvents { wg.Add(1) go func(e events.Event) { defer wg.Done() // Simulate event processing ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() // Mock event processing operation err := suite.mockEventProcessing(ctx, e) if err != nil { atomic.AddInt64(&errorCount, 1) } }(event) } // Wait for all operations to complete wg.Wait() if errorCount > 0 { b.Fatalf("Concurrent event processing failed with %d errors", errorCount) } } }) } // BenchmarkMemoryAllocation benchmarks memory allocation performance func BenchmarkMemoryAllocation(b *testing.B) { // Create test logger log := logger.New("warn", "text", "") // Use warn level to minimize logging overhead // Create test components protocolRegistry := arbitrum.NewArbitrumProtocolRegistry(log) poolCache := pools.NewPoolCache(10000, time.Hour) marketDiscovery := market.NewMarketDiscovery(nil, log, "") strategyEngine := arbitrum.NewMEVStrategyEngine(log, protocolRegistry) profitCalculator := profitcalc.NewProfitCalculatorWithClient(log, nil) mevAnalyzer := arbitrum.NewMEVAnalyzer(log) slippageProtector := trading.NewSlippageProtection(nil, log) capitalOptimizer := arbitrum.NewCapitalOptimizer(log) profitTracker := arbitrum.NewProfitabilityTracker(log) // Create stress test suite suite := NewStressTestSuite( log, protocolRegistry, poolCache, marketDiscovery, strategyEngine, profitCalculator, mevAnalyzer, slippageProtector, capitalOptimizer, profitTracker, ) b.ResetTimer() b.Run("LargeDataStructures", func(b *testing.B) { for i := 0; i < b.N; i++ { // Generate large test data sets dataSets := suite.generateLargeTestDataSets(10000) // Process large data sets var wg sync.WaitGroup errorCount := int64(0) for _, dataSet := range dataSets { wg.Add(1) go func(ds []*market.CachedData) { defer wg.Done() // Simulate memory-intensive processing ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() // Mock memory-intensive operation err := suite.mockMemoryIntensiveProcessing(ctx, ds) if err != nil { atomic.AddInt64(&errorCount, 1) } }(dataSet) } // Wait for all operations to complete wg.Wait() if errorCount > 0 { b.Fatalf("Memory-intensive processing failed with %d errors", errorCount) } } }) } // BenchmarkCPUUtilization benchmarks CPU utilization performance func BenchmarkCPUUtilization(b *testing.B) { // Create test logger log := logger.New("warn", "text", "") // Use warn level to minimize logging overhead // Create test components protocolRegistry := arbitrum.NewArbitrumProtocolRegistry(log) poolCache := pools.NewPoolCache(10000, time.Hour) marketDiscovery := market.NewMarketDiscovery(nil, log, "") strategyEngine := arbitrum.NewMEVStrategyEngine(log, protocolRegistry) profitCalculator := profitcalc.NewProfitCalculatorWithClient(log, nil) mevAnalyzer := arbitrum.NewMEVAnalyzer(log) slippageProtector := trading.NewSlippageProtection(nil, log) capitalOptimizer := arbitrum.NewCapitalOptimizer(log) profitTracker := arbitrum.NewProfitabilityTracker(log) // Create stress test suite suite := NewStressTestSuite( log, protocolRegistry, poolCache, marketDiscovery, strategyEngine, profitCalculator, mevAnalyzer, slippageProtector, capitalOptimizer, profitTracker, ) b.ResetTimer() b.Run("CPUIntensiveCalculations", func(b *testing.B) { for i := 0; i < b.N; i++ { // Generate test data testProfits := suite.generateTestProfits(1000) // Process profits concurrently var wg sync.WaitGroup errorCount := int64(0) for _, profit := range testProfits { wg.Add(1) go func(p *arbitrum.ArbitrageOpportunityDetailed) { defer wg.Done() // Simulate CPU-intensive calculations ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() // Mock profit calculation operation err := suite.mockProfitCalculation(ctx, p) if err != nil { atomic.AddInt64(&errorCount, 1) } }(profit) } // Wait for all operations to complete wg.Wait() if errorCount > 0 { b.Fatalf("CPU-intensive calculations failed with %d errors", errorCount) } } }) } // BenchmarkNetworkLatency benchmarks network latency handling func BenchmarkNetworkLatency(b *testing.B) { // Create test logger log := logger.New("warn", "text", "") // Use warn level to minimize logging overhead // Create test components protocolRegistry := arbitrum.NewArbitrumProtocolRegistry(log) poolCache := pools.NewPoolCache(10000, time.Hour) marketDiscovery := market.NewMarketDiscovery(nil, log, "") strategyEngine := arbitrum.NewMEVStrategyEngine(log, protocolRegistry) profitCalculator := profitcalc.NewProfitCalculatorWithClient(log, nil) mevAnalyzer := arbitrum.NewMEVAnalyzer(log) slippageProtector := trading.NewSlippageProtection(nil, log) capitalOptimizer := arbitrum.NewCapitalOptimizer(log) profitTracker := arbitrum.NewProfitabilityTracker(log) // Create stress test suite suite := NewStressTestSuite( log, protocolRegistry, poolCache, marketDiscovery, strategyEngine, profitCalculator, mevAnalyzer, slippageProtector, capitalOptimizer, profitTracker, ) b.ResetTimer() b.Run("NetworkRequestHandling", func(b *testing.B) { for i := 0; i < b.N; i++ { // Generate test data testPools := suite.generateTestPools(100) // Process pools with simulated network delays var wg sync.WaitGroup errorCount := int64(0) for _, pool := range testPools { wg.Add(1) go func(p *market.CachedData) { defer wg.Done() // Simulate network delay time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond) // Simulate pool scanning with network request ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() // Mock pool scanning operation err := suite.mockPoolScan(ctx, p) if err != nil { atomic.AddInt64(&errorCount, 1) } }(pool) } // Wait for all operations to complete wg.Wait() if errorCount > 0 { b.Fatalf("Network request handling failed with %d errors", errorCount) } } }) } // BenchmarkErrorHandling benchmarks error handling performance func BenchmarkErrorHandling(b *testing.B) { // Create test logger log := logger.New("warn", "text", "") // Use warn level to minimize logging overhead // Create test components protocolRegistry := arbitrum.NewArbitrumProtocolRegistry(log) poolCache := pools.NewPoolCache(10000, time.Hour) marketDiscovery := market.NewMarketDiscovery(nil, log, "") strategyEngine := arbitrum.NewMEVStrategyEngine(log, protocolRegistry) profitCalculator := profitcalc.NewProfitCalculatorWithClient(log, nil) mevAnalyzer := arbitrum.NewMEVAnalyzer(log) slippageProtector := trading.NewSlippageProtection(nil, log) capitalOptimizer := arbitrum.NewCapitalOptimizer(log) profitTracker := arbitrum.NewProfitabilityTracker(log) // Create stress test suite suite := NewStressTestSuite( log, protocolRegistry, poolCache, marketDiscovery, strategyEngine, profitCalculator, mevAnalyzer, slippageProtector, capitalOptimizer, profitTracker, ) b.ResetTimer() b.Run("ErrorHandlingPerformance", func(b *testing.B) { for i := 0; i < b.N; i++ { // Generate test data with errors testEvents := suite.generateTestEventsWithErrorRate(1000, 0.05) // 5% error rate // Process events with error handling var wg sync.WaitGroup errorCount := int64(0) successCount := int64(0) for _, event := range testEvents { wg.Add(1) go func(e events.Event) { defer wg.Done() // Simulate event processing ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() // Mock event processing operation err := suite.mockEventProcessing(ctx, e) if err != nil { atomic.AddInt64(&errorCount, 1) suite.recordError(fmt.Sprintf("EventProcessingError: %v", err)) } else { atomic.AddInt64(&successCount, 1) } }(event) } // Wait for all operations to complete wg.Wait() // Validate error handling worked correctly if errorCount+successCount != int64(len(testEvents)) { b.Fatalf("Error handling count mismatch: %d errors + %d successes != %d total", errorCount, successCount, len(testEvents)) } } }) } // generateTestEventsWithErrorRate generates test events with a specific error rate func (suite *StressTestSuite) generateTestEventsWithErrorRate(count int, errorRate float64) []events.Event { events := suite.generateTestEvents(count) // Mark some events to cause errors based on error rate errorEvents := int(float64(count) * errorRate) for i := 0; i < errorEvents && i < count; i++ { // Mark event to cause error events[i].Type = events.Unknown // Invalid event type to cause processing errors } return events } // generateTestPools generates test pools for benchmarking func (suite *StressTestSuite) generateTestPools(count int) []*market.CachedData { pools := make([]*market.CachedData, count) // Known token addresses for testing wethAddr := common.HexToAddress("0x82af49447d8a07e3bd95bd0d56f35241523fbab1") usdcAddr := common.HexToAddress("0xaf88d065e77c8cc2239327c5edb3a432268e5831") usdtAddr := common.HexToAddress("0xff970a61a04b1ca14834a43f5de4533ebddb5cc8") wbtcAddr := common.HexToAddress("0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f") tokens := []common.Address{wethAddr, usdcAddr, usdtAddr, wbtcAddr} for i := 0; i < count; i++ { // Select random tokens for the pool token0 := tokens[rand.Intn(len(tokens))] token1 := tokens[rand.Intn(len(tokens))] for token0 == token1 { token1 = tokens[rand.Intn(len(tokens))] } // Create deterministic pool address based on index poolAddr := common.BigToAddress(big.NewInt(int64(i + 1000000))) // Generate deterministic liquidity and price values liquidity := uint256.NewInt(uint64(1000000 + i*1000)) // Increasing liquidity sqrtPrice := uint256.NewInt(uint64(1000000000000000000 + i*100000000000000)) // Increasing price pools[i] = &market.CachedData{ Address: poolAddr, Token0: token0, Token1: token1, Fee: int64(3000 + (i%4)*500), // Varying fees (0.05%, 0.3%, 0.5%, 1%) Liquidity: liquidity, SqrtPriceX96: sqrtPrice, Tick: int(74959 + i), // Varying ticks TickSpacing: 60, Protocol: fmt.Sprintf("uniswap_v%d", 2+(i%2)), // Alternating V2/V3 LastUpdated: time.Now(), } } return pools } // generateTestEvents generates test events for benchmarking func (suite *StressTestSuite) generateTestEvents(count int) []events.Event { events := make([]events.Event, count) // Known token addresses for testing wethAddr := common.HexToAddress("0x82af49447d8a07e3bd95bd0d56f35241523fbab1") usdcAddr := common.HexToAddress("0xaf88d065e77c8cc2239327c5edb3a432268e5831") usdtAddr := common.HexToAddress("0xff970a61a04b1ca14834a43f5de4533ebddb5cc8") wbtcAddr := common.HexToAddress("0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f") tokens := []common.Address{wethAddr, usdcAddr, usdtAddr, wbtcAddr} protocols := []string{"uniswap_v2", "uniswap_v3", "sushiswap", "camelot_v2", "camelot_v3", "balancer_v2", "curve", "algebra"} for i := 0; i < count; i++ { // Select random tokens for the event token0 := tokens[rand.Intn(len(tokens))] token1 := tokens[rand.Intn(len(tokens))] for token0 == token1 { token1 = tokens[rand.Intn(len(tokens))] } // Select random protocol protocol := protocols[rand.Intn(len(protocols))] // Create deterministic pool address based on index poolAddr := common.BigToAddress(big.NewInt(int64(i + 2000000))) // Generate deterministic amounts amount0 := big.NewInt(int64(100000000000000000 + int64(i)*10000000000000)) // Varying amounts amount1 := big.NewInt(int64(200000000000000000 + int64(i)*20000000000000)) // Varying amounts // Generate deterministic liquidity and price values liquidity := uint256.NewInt(uint64(500000 + i*500)) // Increasing liquidity sqrtPrice := uint256.NewInt(uint64(500000000000000000 + i*50000000000000)) // Increasing price events[i] = events.Event{ Timestamp: time.Now(), BlockNumber: uint64(10000000 + i), TransactionHash: common.BigToHash(big.NewInt(int64(i + 3000000))), LogIndex: uint(i % 100), Type: events.Swap, // Default to swap events Protocol: protocol, PoolAddress: poolAddr, Token0: token0, Token1: token1, Amount0: amount0, Amount1: amount1, Liquidity: liquidity, SqrtPriceX96: sqrtPrice, Tick: int32(74959 + i%1000), // Varying ticks } } return events } // generateTestProfits generates test profits for benchmarking func (suite *StressTestSuite) generateTestProfits(count int) []*arbitrum.ArbitrageOpportunityDetailed { profits := make([]*arbitrum.ArbitrageOpportunityDetailed, count) // Known token addresses for testing wethAddr := common.HexToAddress("0x82af49447d8a07e3bd95bd0d56f35241523fbab1") usdcAddr := common.HexToAddress("0xaf88d065e77c8cc2239327c5edb3a432268e5831") usdtAddr := common.HexToAddress("0xff970a61a04b1ca14834a43f5de4533ebddb5cc8") wbtcAddr := common.HexToAddress("0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f") tokens := []common.Address{wethAddr, usdcAddr, usdtAddr, wbtcAddr} exchanges := []string{"uniswap_v2", "uniswap_v3", "sushiswap", "camelot_v2", "camelot_v3", "balancer_v2", "curve", "algebra"} for i := 0; i < count; i++ { // Select random tokens for the arbitrage tokenIn := tokens[rand.Intn(len(tokens))] tokenOut := tokens[rand.Intn(len(tokens))] for tokenIn == tokenOut { tokenOut = tokens[rand.Intn(len(tokens))] } // Select random exchanges exchangeA := exchanges[rand.Intn(len(exchanges))] exchangeB := exchanges[rand.Intn(len(exchanges))] for exchangeA == exchangeB { exchangeB = exchanges[rand.Intn(len(exchanges))] } // Create deterministic pool addresses based on index poolA := common.BigToAddress(big.NewInt(int64(i + 4000000))) poolB := common.BigToAddress(big.NewInt(int64(i + 5000000))) // Generate deterministic amounts amountIn := big.NewInt(int64(100000000000000000 + int64(i)*10000000000000)) // Varying amounts expectedAmountOut := big.NewInt(int64(105000000000000000 + int64(i)*10500000000000)) // 5% profit actualAmountOut := big.NewInt(int64(104000000000000000 + int64(i)*10400000000000)) // 4% profit profit := big.NewInt(int64(4000000000000000 + int64(i)*400000000000)) // Varying profits gasCost := big.NewInt(int64(1000000000000000 + int64(i)*100000000000)) // Varying gas costs netProfit := new(big.Int).Sub(profit, gasCost) profits[i] = &arbitrum.ArbitrageOpportunityDetailed{ ID: fmt.Sprintf("arb_%d_%d", time.Now().Unix(), i+1000000), Type: "arbitrage", TokenIn: tokenIn, TokenOut: tokenOut, AmountIn: amountIn, ExpectedAmountOut: expectedAmountOut, ActualAmountOut: actualAmountOut, Profit: profit, ProfitUSD: 50.0 + float64(i%1000)*0.05, // Varying USD profits ProfitMargin: 0.04 + float64(i%100)*0.0001, // Varying margins (4-5%) GasCost: gasCost, NetProfit: netProfit, ExchangeA: exchangeA, ExchangeB: exchangeB, PoolA: poolA, PoolB: poolB, PriceImpactA: 0.005 + float64(i%1000)*0.000005, // Varying price impacts PriceImpactB: 0.003 + float64(i%1000)*0.000003, // Varying price impacts CapitalRequired: 100.0 + float64(i%10000)*0.01, // Varying capital requirements GasCostUSD: 5.0 + float64(i%100)*0.05, // Varying gas costs in USD Confidence: 0.8 + float64(i%20)*0.01, // Varying confidence (80-100%) RiskScore: 0.2 + float64(i%50)*0.01, // Varying risk scores (20-70%) ExecutionTime: time.Duration(15+i%10) * time.Second, // Varying execution times Timestamp: time.Now(), } } return profits } // generateLargeTestDataSets generates large test data sets for memory benchmarking func (suite *StressTestSuite) generateLargeTestDataSets(count int) [][]*market.CachedData { // Create batches of test data batchSize := 1000 batchCount := count / batchSize if count%batchSize > 0 { batchCount++ } dataSets := make([][]*market.CachedData, batchCount) for i := 0; i < batchCount; i++ { dataSets[i] = suite.generateTestPools(batchSize) } return dataSets } // mockPoolScan simulates pool scanning for benchmarking func (suite *StressTestSuite) mockPoolScan(ctx context.Context, pool *market.CachedData) error { atomic.AddUint64(&suite.metrics.totalPoolsScanned, 1) atomic.AddUint64(&suite.metrics.totalTestsRun, 1) // Simulate work select { case <-ctx.Done(): return ctx.Err() case <-time.After(time.Duration(rand.Intn(10)) * time.Millisecond): // Simulate occasional errors if rand.Intn(1000) < 5 { // 0.5% error rate atomic.AddUint64(&suite.metrics.testsFailed, 1) return fmt.Errorf("simulated pool scan error") } atomic.AddUint64(&suite.metrics.testsPassed, 1) return nil } } // mockEventProcessing simulates event processing for benchmarking func (suite *StressTestSuite) mockEventProcessing(ctx context.Context, event events.Event) error { atomic.AddUint64(&suite.metrics.totalTransactions, 1) atomic.AddUint64(&suite.metrics.totalTestsRun, 1) // Simulate work select { case <-ctx.Done(): return ctx.Err() case <-time.After(time.Duration(rand.Intn(5)) * time.Millisecond): // Simulate occasional errors if rand.Intn(1000) < 3 { // 0.3% error rate atomic.AddUint64(&suite.metrics.testsFailed, 1) return fmt.Errorf("simulated event processing error") } atomic.AddUint64(&suite.metrics.testsPassed, 1) return nil } } // mockMemoryIntensiveProcessing simulates memory-intensive processing for benchmarking func (suite *StressTestSuite) mockMemoryIntensiveProcessing(ctx context.Context, dataSet []*market.CachedData) error { atomic.AddUint64(&suite.metrics.totalTestsRun, 1) // Simulate memory-intensive work // Create temporary data structures to consume memory tempData := make([]*market.CachedData, len(dataSet)) copy(tempData, dataSet) // Simulate work select { case <-ctx.Done(): return ctx.Err() case <-time.After(time.Duration(rand.Intn(20)) * time.Millisecond): // Clear temporary data tempData = nil // Simulate occasional errors if rand.Intn(1000) < 8 { // 0.8% error rate atomic.AddUint64(&suite.metrics.testsFailed, 1) return fmt.Errorf("simulated memory-intensive processing error") } atomic.AddUint64(&suite.metrics.testsPassed, 1) return nil } } // mockProfitCalculation simulates profit calculation for benchmarking func (suite *StressTestSuite) mockProfitCalculation(ctx context.Context, profit *arbitrum.ArbitrageOpportunityDetailed) error { atomic.AddUint64(&suite.metrics.totalArbitrageOps, 1) atomic.AddUint64(&suite.metrics.totalTestsRun, 1) // Simulate work select { case <-ctx.Done(): return ctx.Err() case <-time.After(time.Duration(rand.Intn(15)) * time.Millisecond): // Simulate occasional errors if rand.Intn(1000) < 6 { // 0.6% error rate atomic.AddUint64(&suite.metrics.testsFailed, 1) return fmt.Errorf("simulated profit calculation error") } atomic.AddUint64(&suite.metrics.testsPassed, 1) return nil } }