package services import ( "context" "testing" "time" "github.com/stretchr/testify/assert" "go.uber.org/zap/zaptest" ) func TestNewBandwidthDetectionService(t *testing.T) { logger := zaptest.NewLogger(t) service := NewBandwidthDetectionService(logger) assert.NotNil(t, service) assert.NotNil(t, service.samples) assert.Equal(t, 10, service.maxSamples) assert.Equal(t, 0, len(service.samples)) } func TestNewBandwidthDetectionService_NilLogger(t *testing.T) { service := NewBandwidthDetectionService(nil) assert.NotNil(t, service) assert.NotNil(t, service.logger) } func TestBandwidthDetectionService_MeasureBandwidth(t *testing.T) { logger := zaptest.NewLogger(t) service := NewBandwidthDetectionService(logger) ctx := context.Background() // Test mesure de bande passante: 1 MB en 1 seconde = 8 Mbps = 8000000 bps bytesTransferred := int64(1024 * 1024) // 1 MB duration := time.Second bandwidth := service.MeasureBandwidth(ctx, bytesTransferred, duration) assert.Equal(t, int64(8388608), bandwidth) // 1 MB * 8 bits / 1 second = 8388608 bps assert.Equal(t, 1, service.GetSampleCount()) } func TestBandwidthDetectionService_MeasureBandwidth_MultipleSamples(t *testing.T) { logger := zaptest.NewLogger(t) service := NewBandwidthDetectionService(logger) ctx := context.Background() // Ajouter plusieurs échantillons service.MeasureBandwidth(ctx, 1024*1024, time.Second) // ~8 Mbps service.MeasureBandwidth(ctx, 2*1024*1024, time.Second) // ~16 Mbps service.MeasureBandwidth(ctx, 3*1024*1024, time.Second) // ~24 Mbps assert.Equal(t, 3, service.GetSampleCount()) // La moyenne devrait être environ (8 + 16 + 24) / 3 = 16 Mbps avgBandwidth := service.GetAverageBandwidth() assert.Greater(t, avgBandwidth, int64(15000000)) // ~15 Mbps assert.Less(t, avgBandwidth, int64(17000000)) // ~17 Mbps } func TestBandwidthDetectionService_MeasureBandwidth_MaxSamples(t *testing.T) { logger := zaptest.NewLogger(t) service := NewBandwidthDetectionService(logger) ctx := context.Background() // Ajouter plus de 10 échantillons (maxSamples = 10) for i := 0; i < 15; i++ { service.MeasureBandwidth(ctx, int64(1024*1024*(i+1)), time.Second) } // Le nombre d'échantillons ne devrait pas dépasser maxSamples assert.Equal(t, 10, service.GetSampleCount()) } func TestBandwidthDetectionService_MeasureBandwidth_InvalidDuration(t *testing.T) { logger := zaptest.NewLogger(t) service := NewBandwidthDetectionService(logger) ctx := context.Background() // Test avec durée nulle bandwidth := service.MeasureBandwidth(ctx, 1024*1024, 0) assert.Equal(t, int64(0), bandwidth) // Test avec durée négative bandwidth = service.MeasureBandwidth(ctx, 1024*1024, -time.Second) assert.Equal(t, int64(0), bandwidth) } func TestBandwidthDetectionService_MeasureBandwidth_InvalidBytes(t *testing.T) { logger := zaptest.NewLogger(t) service := NewBandwidthDetectionService(logger) ctx := context.Background() // Test avec bytes négatifs bandwidth := service.MeasureBandwidth(ctx, -1024, time.Second) assert.Equal(t, int64(0), bandwidth) } func TestBandwidthDetectionService_MeasureBandwidth_VeryShortDuration(t *testing.T) { logger := zaptest.NewLogger(t) service := NewBandwidthDetectionService(logger) ctx := context.Background() // Test avec une durée très courte (1 milliseconde) bytesTransferred := int64(1024) // 1 KB duration := time.Millisecond bandwidth := service.MeasureBandwidth(ctx, bytesTransferred, duration) // 1 KB * 8 bits / 0.001 second = 8 Mbps = 8000000 bps assert.Greater(t, bandwidth, int64(7000000)) assert.Less(t, bandwidth, int64(9000000)) } func TestBandwidthDetectionService_CalculateAverage_EmptySamples(t *testing.T) { logger := zaptest.NewLogger(t) service := NewBandwidthDetectionService(logger) avg := service.GetAverageBandwidth() assert.Equal(t, int64(0), avg) } func TestBandwidthDetectionService_RecommendBitrate(t *testing.T) { logger := zaptest.NewLogger(t) service := NewBandwidthDetectionService(logger) // Test avec bande passante élevée (>= 400 kbps avec buffer) // 400 kbps * 1.25 (pour compenser le buffer 20%) = 500 kbps = 500000 bps bitrate := service.RecommendBitrate(500000) assert.Equal(t, 320, bitrate) // Test avec bande passante moyenne (>= 240 kbps avec buffer) // 240 kbps * 1.25 = 300 kbps = 300000 bps bitrate = service.RecommendBitrate(300000) assert.Equal(t, 192, bitrate) // Test avec bande passante faible (>= 160 kbps avec buffer) // 160 kbps * 1.25 = 200 kbps = 200000 bps bitrate = service.RecommendBitrate(200000) assert.Equal(t, 128, bitrate) // Test avec bande passante très faible (< 160 kbps avec buffer) bitrate = service.RecommendBitrate(100000) assert.Equal(t, 128, bitrate) } func TestBandwidthDetectionService_RecommendBitrate_EdgeCases(t *testing.T) { logger := zaptest.NewLogger(t) service := NewBandwidthDetectionService(logger) // Test avec bande passante nulle bitrate := service.RecommendBitrate(0) assert.Equal(t, 128, bitrate) // Test avec bande passante négative bitrate = service.RecommendBitrate(-1000) assert.Equal(t, 128, bitrate) // Test avec bande passante exactement à la limite (320 kbps) // 320 kbps * 1.25 = 400 kbps = 400000 bps bitrate = service.RecommendBitrate(400000) assert.Equal(t, 320, bitrate) // Test avec bande passante juste en dessous de 320 kbps bitrate = service.RecommendBitrate(399999) assert.Equal(t, 192, bitrate) // Test avec bande passante exactement à la limite (192 kbps) // 192 kbps * 1.25 = 240 kbps = 240000 bps bitrate = service.RecommendBitrate(240000) assert.Equal(t, 192, bitrate) // Test avec bande passante juste en dessous de 192 kbps bitrate = service.RecommendBitrate(239999) assert.Equal(t, 128, bitrate) // Test avec bande passante exactement à la limite (128 kbps) // 128 kbps * 1.25 = 160 kbps = 160000 bps bitrate = service.RecommendBitrate(160000) assert.Equal(t, 128, bitrate) } func TestBandwidthDetectionService_ClearSamples(t *testing.T) { logger := zaptest.NewLogger(t) service := NewBandwidthDetectionService(logger) ctx := context.Background() // Ajouter quelques échantillons service.MeasureBandwidth(ctx, 1024*1024, time.Second) service.MeasureBandwidth(ctx, 2*1024*1024, time.Second) assert.Equal(t, 2, service.GetSampleCount()) // Effacer les échantillons service.ClearSamples() assert.Equal(t, 0, service.GetSampleCount()) assert.Equal(t, int64(0), service.GetAverageBandwidth()) } func TestBandwidthDetectionService_GetSampleCount(t *testing.T) { logger := zaptest.NewLogger(t) service := NewBandwidthDetectionService(logger) ctx := context.Background() assert.Equal(t, 0, service.GetSampleCount()) service.MeasureBandwidth(ctx, 1024*1024, time.Second) assert.Equal(t, 1, service.GetSampleCount()) service.MeasureBandwidth(ctx, 2*1024*1024, time.Second) assert.Equal(t, 2, service.GetSampleCount()) } func TestBandwidthDetectionService_ConcurrentAccess(t *testing.T) { logger := zaptest.NewLogger(t) service := NewBandwidthDetectionService(logger) ctx := context.Background() // Test d'accès concurrent done := make(chan bool, 10) for i := 0; i < 10; i++ { go func(index int) { service.MeasureBandwidth(ctx, int64(1024*1024*(index+1)), time.Second) service.GetAverageBandwidth() service.GetSampleCount() done <- true }(i) } // Attendre que toutes les goroutines se terminent for i := 0; i < 10; i++ { <-done } // Le service devrait toujours être dans un état cohérent assert.LessOrEqual(t, service.GetSampleCount(), 10) assert.Greater(t, service.GetAverageBandwidth(), int64(0)) } func TestBandwidthDetectionService_RealWorldScenarios(t *testing.T) { logger := zaptest.NewLogger(t) service := NewBandwidthDetectionService(logger) ctx := context.Background() // Scénario 1: Connexion rapide (10 Mbps) // 10 Mbps = 10 * 1024 * 1024 / 8 = 1310720 bytes/s // En 1 seconde: 1310720 bytes // Bande passante mesurée: 1310720 * 8 = 10485760 bps = 10 Mbps // Avec buffer 20%: 10485760 * 0.8 = 8388608 bps = 8388 kbps > 320 kbps service.MeasureBandwidth(ctx, 1310720, time.Second) bitrate := service.RecommendBitrate(service.GetAverageBandwidth()) assert.Equal(t, 320, bitrate) // Scénario 2: Connexion moyenne (2 Mbps) // 2 Mbps = 2 * 1024 * 1024 / 8 = 262144 bytes/s // Bande passante mesurée: 262144 * 8 = 2097152 bps = 2 Mbps // Avec buffer 20%: 2097152 * 0.8 = 1677721 bps = 1677 kbps > 320 kbps // Donc on recommande 320 kbps (pas 192) service.ClearSamples() service.MeasureBandwidth(ctx, 262144, time.Second) bitrate = service.RecommendBitrate(service.GetAverageBandwidth()) assert.Equal(t, 320, bitrate) // Scénario 3: Connexion lente (300 kbps) // 300 kbps = 300 * 1024 / 8 = 38400 bytes/s // Bande passante mesurée: 38400 * 8 = 307200 bps = 300 kbps // Avec buffer 20%: 307200 * 0.8 = 245760 bps = 245 kbps // 245 kbps >= 192 kbps, donc on recommande 192 kbps service.ClearSamples() service.MeasureBandwidth(ctx, 38400, time.Second) bitrate = service.RecommendBitrate(service.GetAverageBandwidth()) assert.Equal(t, 192, bitrate) // Scénario 4: Connexion très lente (150 kbps) // 150 kbps = 150 * 1024 / 8 = 19200 bytes/s // Bande passante mesurée: 19200 * 8 = 153600 bps = 150 kbps // Avec buffer 20%: 153600 * 0.8 = 122880 bps = 122 kbps < 128 kbps // Donc on recommande 128 kbps service.ClearSamples() service.MeasureBandwidth(ctx, 19200, time.Second) bitrate = service.RecommendBitrate(service.GetAverageBandwidth()) assert.Equal(t, 128, bitrate) }