veza/veza-backend-api/internal/services/bitrate_strategy_service_test.go

357 lines
10 KiB
Go

package services
import (
"testing"
"github.com/stretchr/testify/assert"
"go.uber.org/zap/zaptest"
)
func TestNewBitrateStrategyService(t *testing.T) {
logger := zaptest.NewLogger(t)
service := NewBitrateStrategyService(logger)
assert.NotNil(t, service)
assert.NotNil(t, service.logger)
}
func TestNewBitrateStrategyService_NilLogger(t *testing.T) {
service := NewBitrateStrategyService(nil)
assert.NotNil(t, service)
assert.NotNil(t, service.logger)
}
func TestBitrateStrategyService_GetThresholds_Conservative(t *testing.T) {
logger := zaptest.NewLogger(t)
service := NewBitrateStrategyService(logger)
thresholds := service.GetThresholds(StrategyConservative)
assert.Equal(t, 0.3, thresholds.BufferLevelThreshold)
assert.Equal(t, 0.7, thresholds.BandwidthRatioThreshold)
assert.False(t, thresholds.UseOrCondition)
}
func TestBitrateStrategyService_GetThresholds_Aggressive(t *testing.T) {
logger := zaptest.NewLogger(t)
service := NewBitrateStrategyService(logger)
thresholds := service.GetThresholds(StrategyAggressive)
assert.Equal(t, 0.15, thresholds.BufferLevelThreshold)
assert.Equal(t, 0.5, thresholds.BandwidthRatioThreshold)
assert.True(t, thresholds.UseOrCondition)
}
func TestBitrateStrategyService_GetThresholds_Balanced(t *testing.T) {
logger := zaptest.NewLogger(t)
service := NewBitrateStrategyService(logger)
thresholds := service.GetThresholds(StrategyBalanced)
assert.Equal(t, 0.2, thresholds.BufferLevelThreshold)
assert.Equal(t, 0.6, thresholds.BandwidthRatioThreshold)
assert.False(t, thresholds.UseOrCondition)
}
func TestBitrateStrategyService_GetThresholds_Default(t *testing.T) {
logger := zaptest.NewLogger(t)
service := NewBitrateStrategyService(logger)
// Tester avec une stratégie invalide (devrait retourner Balanced par défaut)
thresholds := service.GetThresholds(BitrateStrategy("invalid"))
assert.Equal(t, 0.2, thresholds.BufferLevelThreshold)
assert.Equal(t, 0.6, thresholds.BandwidthRatioThreshold)
assert.False(t, thresholds.UseOrCondition)
}
func TestBitrateStrategyService_ShouldAdapt_Conservative(t *testing.T) {
logger := zaptest.NewLogger(t)
service := NewBitrateStrategyService(logger)
tests := []struct {
name string
bufferLevel float64
bandwidthRatio float64
expected bool
}{
{
name: "both low - should adapt",
bufferLevel: 0.25, // < 0.3
bandwidthRatio: 0.6, // < 0.7
expected: true,
},
{
name: "buffer low but bandwidth ok - should not adapt",
bufferLevel: 0.25, // < 0.3
bandwidthRatio: 0.8, // >= 0.7
expected: false,
},
{
name: "bandwidth low but buffer ok - should not adapt",
bufferLevel: 0.4, // >= 0.3
bandwidthRatio: 0.6, // < 0.7
expected: false,
},
{
name: "both ok - should not adapt",
bufferLevel: 0.4, // >= 0.3
bandwidthRatio: 0.8, // >= 0.7
expected: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := service.ShouldAdapt(StrategyConservative, tt.bufferLevel, tt.bandwidthRatio)
assert.Equal(t, tt.expected, result, "ShouldAdapt failed for %s", tt.name)
})
}
}
func TestBitrateStrategyService_ShouldAdapt_Aggressive(t *testing.T) {
logger := zaptest.NewLogger(t)
service := NewBitrateStrategyService(logger)
tests := []struct {
name string
bufferLevel float64
bandwidthRatio float64
expected bool
}{
{
name: "buffer low - should adapt",
bufferLevel: 0.1, // < 0.15
bandwidthRatio: 0.8, // >= 0.5
expected: true,
},
{
name: "bandwidth low - should adapt",
bufferLevel: 0.3, // >= 0.15
bandwidthRatio: 0.4, // < 0.5
expected: true,
},
{
name: "both low - should adapt",
bufferLevel: 0.1, // < 0.15
bandwidthRatio: 0.4, // < 0.5
expected: true,
},
{
name: "both ok - should not adapt",
bufferLevel: 0.2, // >= 0.15
bandwidthRatio: 0.6, // >= 0.5
expected: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := service.ShouldAdapt(StrategyAggressive, tt.bufferLevel, tt.bandwidthRatio)
assert.Equal(t, tt.expected, result, "ShouldAdapt failed for %s", tt.name)
})
}
}
func TestBitrateStrategyService_ShouldAdapt_Balanced(t *testing.T) {
logger := zaptest.NewLogger(t)
service := NewBitrateStrategyService(logger)
tests := []struct {
name string
bufferLevel float64
bandwidthRatio float64
expected bool
}{
{
name: "both low - should adapt",
bufferLevel: 0.15, // < 0.2
bandwidthRatio: 0.5, // < 0.6
expected: true,
},
{
name: "buffer low but bandwidth ok - should not adapt",
bufferLevel: 0.15, // < 0.2
bandwidthRatio: 0.7, // >= 0.6
expected: false,
},
{
name: "bandwidth low but buffer ok - should not adapt",
bufferLevel: 0.3, // >= 0.2
bandwidthRatio: 0.5, // < 0.6
expected: false,
},
{
name: "both ok - should not adapt",
bufferLevel: 0.3, // >= 0.2
bandwidthRatio: 0.7, // >= 0.6
expected: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := service.ShouldAdapt(StrategyBalanced, tt.bufferLevel, tt.bandwidthRatio)
assert.Equal(t, tt.expected, result, "ShouldAdapt failed for %s", tt.name)
})
}
}
func TestBitrateStrategyService_ShouldAdapt_InvalidBufferLevel(t *testing.T) {
logger := zaptest.NewLogger(t)
service := NewBitrateStrategyService(logger)
// Buffer level négatif
result := service.ShouldAdapt(StrategyBalanced, -0.1, 0.5)
assert.False(t, result)
// Buffer level > 1.0
result = service.ShouldAdapt(StrategyBalanced, 1.5, 0.5)
assert.False(t, result)
}
func TestBitrateStrategyService_ShouldAdapt_InvalidBandwidthRatio(t *testing.T) {
logger := zaptest.NewLogger(t)
service := NewBitrateStrategyService(logger)
// Bandwidth ratio négatif
result := service.ShouldAdapt(StrategyBalanced, 0.5, -0.1)
assert.False(t, result)
}
func TestBitrateStrategyService_ShouldAdapt_EdgeCases(t *testing.T) {
logger := zaptest.NewLogger(t)
service := NewBitrateStrategyService(logger)
// Buffer level exactement au seuil
result := service.ShouldAdapt(StrategyBalanced, 0.2, 0.5)
assert.False(t, result) // 0.2 n'est pas < 0.2
// Buffer level juste en dessous du seuil
result = service.ShouldAdapt(StrategyBalanced, 0.199, 0.5)
assert.True(t, result)
// Bandwidth ratio exactement au seuil
result = service.ShouldAdapt(StrategyBalanced, 0.15, 0.6)
assert.False(t, result) // 0.6 n'est pas < 0.6
// Bandwidth ratio juste en dessous du seuil
result = service.ShouldAdapt(StrategyBalanced, 0.15, 0.599)
assert.True(t, result)
}
func TestBitrateStrategyService_SelectStrategy_WithUserPreference(t *testing.T) {
logger := zaptest.NewLogger(t)
service := NewBitrateStrategyService(logger)
preference := StrategyAggressive
result := service.SelectStrategy(0.5, &preference)
assert.Equal(t, StrategyAggressive, result)
}
func TestBitrateStrategyService_SelectStrategy_UnstableNetwork(t *testing.T) {
logger := zaptest.NewLogger(t)
service := NewBitrateStrategyService(logger)
// Réseau instable (< 0.3)
result := service.SelectStrategy(0.2, nil)
assert.Equal(t, StrategyConservative, result)
result = service.SelectStrategy(0.0, nil)
assert.Equal(t, StrategyConservative, result)
}
func TestBitrateStrategyService_SelectStrategy_StableNetwork(t *testing.T) {
logger := zaptest.NewLogger(t)
service := NewBitrateStrategyService(logger)
// Réseau stable (> 0.7)
result := service.SelectStrategy(0.8, nil)
assert.Equal(t, StrategyAggressive, result)
result = service.SelectStrategy(1.0, nil)
assert.Equal(t, StrategyAggressive, result)
}
func TestBitrateStrategyService_SelectStrategy_ModerateNetwork(t *testing.T) {
logger := zaptest.NewLogger(t)
service := NewBitrateStrategyService(logger)
// Réseau modéré (0.3 à 0.7)
result := service.SelectStrategy(0.5, nil)
assert.Equal(t, StrategyBalanced, result)
result = service.SelectStrategy(0.3, nil)
assert.Equal(t, StrategyBalanced, result)
result = service.SelectStrategy(0.7, nil)
assert.Equal(t, StrategyBalanced, result)
}
func TestBitrateStrategyService_IsValidStrategy(t *testing.T) {
logger := zaptest.NewLogger(t)
service := NewBitrateStrategyService(logger)
assert.True(t, service.IsValidStrategy(StrategyConservative))
assert.True(t, service.IsValidStrategy(StrategyAggressive))
assert.True(t, service.IsValidStrategy(StrategyBalanced))
assert.False(t, service.IsValidStrategy(BitrateStrategy("invalid")))
assert.False(t, service.IsValidStrategy(BitrateStrategy("")))
}
func TestBitrateStrategyService_RealWorldScenarios(t *testing.T) {
logger := zaptest.NewLogger(t)
service := NewBitrateStrategyService(logger)
tests := []struct {
name string
strategy BitrateStrategy
bufferLevel float64
bandwidthRatio float64
expected bool
description string
}{
{
name: "conservative - good conditions",
strategy: StrategyConservative,
bufferLevel: 0.5,
bandwidthRatio: 0.9,
expected: false,
description: "Should not adapt with good buffer and bandwidth",
},
{
name: "aggressive - buffer dropping",
strategy: StrategyAggressive,
bufferLevel: 0.1,
bandwidthRatio: 0.8,
expected: true,
description: "Should adapt when buffer is dropping even with good bandwidth",
},
{
name: "balanced - moderate conditions",
strategy: StrategyBalanced,
bufferLevel: 0.18,
bandwidthRatio: 0.55,
expected: true,
description: "Should adapt when both are moderately low",
},
{
name: "conservative - critical buffer",
strategy: StrategyConservative,
bufferLevel: 0.25,
bandwidthRatio: 0.65,
expected: true,
description: "Should adapt when both are below conservative thresholds",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := service.ShouldAdapt(tt.strategy, tt.bufferLevel, tt.bandwidthRatio)
assert.Equal(t, tt.expected, result, tt.description)
})
}
}