@@ -121,3 +121,68 @@ def test_cpu_calculate_power_from_cpu_load_linear(
121121 for test in tests_values :
122122 power = cpu ._calculate_power_from_cpu_load (tdp , test ["cpu_load" ], cpu_model )
123123 self .assertEqual (power , test ["expected_power" ])
124+
125+ @mock .patch (
126+ "codecarbon.external.hardware.CPU._get_power_from_cpus" ,
127+ return_value = Power .from_watts (0 ),
128+ )
129+ def test_cpu_total_power_empty_history (
130+ self ,
131+ mocked_is_psutil_available ,
132+ mocked_is_powergadget_available ,
133+ mocked_is_rapl_available ,
134+ mocked_get_power_from_cpus ,
135+ ):
136+ """Regression test for issue #832: ZeroDivisionError when no power samples collected."""
137+ cpu = CPU .from_utils (
138+ None , MODE_CPU_LOAD , "Intel(R) Core(TM) i7-7600U CPU @ 2.80GHz" , 100
139+ )
140+ # Simulate an empty power history before calling total_power
141+ cpu ._power_history = []
142+ result = cpu .total_power ()
143+ # Should NOT raise ZeroDivisionError, should return a valid Power object
144+ self .assertIsInstance (result , Power )
145+ self .assertEqual (result .W , 0 )
146+
147+ @mock .patch (
148+ "codecarbon.external.hardware.CPU._get_power_from_cpus" ,
149+ return_value = Power .from_watts (42 ),
150+ )
151+ def test_cpu_total_power_fetches_sample_when_history_is_empty (
152+ self ,
153+ mocked_get_power_from_cpus ,
154+ mocked_is_psutil_available ,
155+ mocked_is_powergadget_available ,
156+ mocked_is_rapl_available ,
157+ ):
158+ """Calling total_power should always fetch the latest sample before averaging."""
159+ cpu = CPU .from_utils (
160+ None , MODE_CPU_LOAD , "Intel(R) Core(TM) i7-7600U CPU @ 2.80GHz" , 100
161+ )
162+ cpu ._power_history = []
163+ result = cpu .total_power ()
164+ self .assertEqual (result .W , 42 )
165+ mocked_get_power_from_cpus .assert_called_once ()
166+ self .assertEqual (cpu ._power_history , [])
167+
168+ @mock .patch (
169+ "codecarbon.external.hardware.CPU._get_power_from_cpus" ,
170+ return_value = Power .from_watts (30 ),
171+ )
172+ def test_cpu_total_power_averages_buffered_and_latest_sample (
173+ self ,
174+ mocked_get_power_from_cpus ,
175+ mocked_is_psutil_available ,
176+ mocked_is_powergadget_available ,
177+ mocked_is_rapl_available ,
178+ ):
179+ cpu = CPU .from_utils (
180+ None , MODE_CPU_LOAD , "Intel(R) Core(TM) i7-7600U CPU @ 2.80GHz" , 100
181+ )
182+ cpu ._power_history = [Power .from_watts (10 ), Power .from_watts (20 )]
183+
184+ result = cpu .total_power ()
185+
186+ self .assertEqual (result .W , 20 )
187+ self .assertEqual (cpu ._power_history , [])
188+ mocked_get_power_from_cpus .assert_called_once ()
0 commit comments