using System; using Paca.Core; using Paca.Core.Platform; using Xunit; namespace Paca.Tests.Core; public class BatterySaverPowerManagerTests { [Fact] public void 정상_상태_완전한_동시성_유지_및_백그라운드_작업_허용() { var manager = new BatterySaverPowerManager(); manager.UpdateBatteryState(percent: 85, isCharging: false); Assert.False(manager.IsLowPowerModeActive); Assert.False(manager.ShouldDeferBackgroundProcessing); Assert.Equal(8, manager.CalculateOptimalConcurrency(baseConcurrency: 8)); Assert.True(manager.CanExecuteCpuIntensiveTask()); } [Fact] public void 충전_중일_때는_배터리_15퍼센트여도_풀파워_유지() { var manager = new BatterySaverPowerManager(); manager.UpdateBatteryState(percent: 15, isCharging: true); Assert.False(manager.IsLowPowerModeActive); Assert.False(manager.ShouldDeferBackgroundProcessing); Assert.Equal(8, manager.CalculateOptimalConcurrency(baseConcurrency: 8)); Assert.True(manager.CanExecuteCpuIntensiveTask()); } [Fact] public void 배터리_20퍼센트_이하_방전_중_동시성_감축_및_백그라운드_유예() { var manager = new BatterySaverPowerManager(lowBatteryThresholdPercent: 20); manager.UpdateBatteryState(percent: 18, isCharging: false); Assert.True(manager.IsLowPowerModeActive); Assert.True(manager.ShouldDeferBackgroundProcessing); // 8개의 병렬 다운로드 -> 2개로 자동 감축 (전력 및 RF 소모 75% 절감) Assert.Equal(2, manager.CalculateOptimalConcurrency(baseConcurrency: 8)); Assert.False(manager.CanExecuteCpuIntensiveTask()); } [Fact] public void 배터리_10퍼센트_이하_크리티컬_단일_스트림_최소_전력_모드() { var manager = new BatterySaverPowerManager(); manager.UpdateBatteryState(percent: 8, isCharging: false); Assert.True(manager.IsLowPowerModeActive); // 크리티컬 상황에서는 최소 1개 스트림으로 다운로드 중단 방지 Assert.Equal(1, manager.CalculateOptimalConcurrency(baseConcurrency: 8)); Assert.True(manager.ShouldDeferBackgroundProcessing); } [Fact] public void OS_절전_모드_활성화시_배터리_잔량_무관_절전_진입() { var manager = new BatterySaverPowerManager(); manager.UpdateBatteryState(percent: 60, isCharging: false, isOsPowerSaverEnabled: true); Assert.True(manager.IsLowPowerModeActive); Assert.True(manager.ShouldDeferBackgroundProcessing); Assert.Equal(2, manager.CalculateOptimalConcurrency(baseConcurrency: 8)); } [Fact] public void 충전기_연결시_즉시_풀파워_복구_및_이벤트_발행() { var manager = new BatterySaverPowerManager(); manager.UpdateBatteryState(percent: 12, isCharging: false); Assert.True(manager.IsLowPowerModeActive); bool eventFired = false; PowerStateChangedEventArgs? capturedArgs = null; manager.PowerStateChanged += (s, e) => { eventFired = true; capturedArgs = e; }; // 충전기 연결 manager.UpdateBatteryState(percent: 12, isCharging: true); Assert.True(eventFired); Assert.NotNull(capturedArgs); Assert.False(capturedArgs!.IsLowPowerModeActive); Assert.False(manager.IsLowPowerModeActive); Assert.Equal(8, manager.CalculateOptimalConcurrency(baseConcurrency: 8)); } [Fact] public void 절전_모드_대역폭_권장_제한치_계산_검증() { var manager = new BatterySaverPowerManager(); // 정상 상태에서는 설정된 대역폭 유지 manager.UpdateBatteryState(percent: 90, isCharging: false); Assert.Equal(10000, manager.CalculateBandwidthLimitKbps(baseLimitKbps: 10000)); Assert.Null(manager.CalculateBandwidthLimitKbps(baseLimitKbps: null)); // 절전 모드에서는 대역폭 상한 제안 (무제한일 경우 2000 Kbps로 쓰로틀링) manager.UpdateBatteryState(percent: 15, isCharging: false); Assert.Equal(2000, manager.CalculateBandwidthLimitKbps(baseLimitKbps: null)); // 기존 제한이 더 크면 2000으로 강제 Assert.Equal(2000, manager.CalculateBandwidthLimitKbps(baseLimitKbps: 8000)); // 기존 제한이 이미 2000보다 작으면 기존 것 존중 Assert.Equal(1000, manager.CalculateBandwidthLimitKbps(baseLimitKbps: 1000)); } [Fact] public void HlsDownloader_배터리_절전모드_연동_동시성_감축_검증() { var powerManager = new BatterySaverPowerManager(); var config = new Paca.Core.Config.AppConfig { Concurrency = 8 }; var http = new System.Net.Http.HttpClient(); var downloader = new Paca.Core.Hls.HlsDownloader(http, config, Paca.Core.Platform.DesktopMediaMuxer.Default, powerManager); // 정상 상태: 8 powerManager.UpdateBatteryState(percent: 90, isCharging: false); Assert.Equal(8, downloader.GetEffectiveConcurrency()); // 배터리 15% 방전 중: 2로 감축 powerManager.UpdateBatteryState(percent: 15, isCharging: false); Assert.Equal(2, downloader.GetEffectiveConcurrency()); // 충전기 연결: 8로 즉시 복귀 powerManager.UpdateBatteryState(percent: 15, isCharging: true); Assert.Equal(8, downloader.GetEffectiveConcurrency()); } [Fact] public void VideoPosterExtractor_배터리_절전모드시_썸네일_추출_유예_판정_검증() { var powerManager = new BatterySaverPowerManager(); powerManager.UpdateBatteryState(percent: 15, isCharging: false); Assert.True(VideoPosterExtractor.ShouldDeferExtraction(powerManager)); powerManager.UpdateBatteryState(percent: 15, isCharging: true); Assert.False(VideoPosterExtractor.ShouldDeferExtraction(powerManager)); Assert.False(VideoPosterExtractor.ShouldDeferExtraction(null)); } }