Skip to content

Commit eb655b2

Browse files
Copilotbenoit-cty
andcommitted
Use scheduler state instead of task state for warning condition and add tests
- Replace `self._active_task is None` with `not self._scheduler._stopped` in warning condition - Add comprehensive tests to verify warning behavior when scheduler is stopped vs running - Tests confirm warning is suppressed when scheduler is intentionally stopped (e.g., in task mode) - Tests confirm warning still appears when scheduler should be running but is delayed Co-authored-by: benoit-cty <6603048+benoit-cty@users.noreply.github.com>
1 parent 26ad1f3 commit eb655b2

2 files changed

Lines changed: 75 additions & 1 deletion

File tree

codecarbon/emissions_tracker.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -843,7 +843,7 @@ def _measure_power_and_energy(self) -> None:
843843
raise e
844844

845845
warning_duration = self._measure_power_secs * 3
846-
if last_duration > warning_duration and self._active_task is None:
846+
if last_duration > warning_duration and not self._scheduler._stopped:
847847
warn_msg = (
848848
"Background scheduler didn't run for a long period"
849849
+ " (%ds), results might be inaccurate"

tests/test_emissions_tracker.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,3 +520,77 @@ def test_carbon_tracker_offline_context_manager(
520520
self.assertEqual("United States", emissions_df["country_name"].values[0])
521521
self.assertEqual("USA", emissions_df["country_iso_code"].values[0])
522522
self.assertIsInstance(tracker.final_emissions, float)
523+
524+
@mock.patch("codecarbon.emissions_tracker.logger")
525+
def test_scheduler_warning_suppressed_when_stopped(
526+
self,
527+
mock_logger,
528+
mock_setup_intel_cli,
529+
mock_log_values,
530+
mocked_get_gpu_details,
531+
mocked_env_cloud_details,
532+
mocked_is_gpu_details_available,
533+
):
534+
"""Test that scheduler warning is suppressed when scheduler is stopped."""
535+
with EmissionsTracker(
536+
output_dir=self.temp_path,
537+
measure_power_secs=1, # Short interval for testing
538+
) as tracker:
539+
# Stop the scheduler to simulate task mode or manual stopping
540+
tracker._scheduler.stop()
541+
542+
# Artificially set last measured time to simulate long delay
543+
import time
544+
tracker._last_measured_time = time.perf_counter() - 10 # 10 seconds ago
545+
546+
# Reset mock to clear any previous warning calls
547+
mock_logger.warning.reset_mock()
548+
549+
# Call _measure_power_and_energy directly - this would normally trigger warning
550+
tracker._measure_power_and_energy()
551+
552+
# Verify that if warning was called, it wasn't the scheduler warning
553+
if mock_logger.warning.called:
554+
for call in mock_logger.warning.call_args_list:
555+
args, kwargs = call
556+
if args and "Background scheduler didn't run for a long period" in str(args[0]):
557+
self.fail("Scheduler warning was called when it should have been suppressed")
558+
559+
@mock.patch("codecarbon.emissions_tracker.logger")
560+
def test_scheduler_warning_shown_when_running(
561+
self,
562+
mock_logger,
563+
mock_setup_intel_cli,
564+
mock_log_values,
565+
mocked_get_gpu_details,
566+
mocked_env_cloud_details,
567+
mocked_is_gpu_details_available,
568+
):
569+
"""Test that scheduler warning is shown when scheduler is running but delayed."""
570+
with EmissionsTracker(
571+
output_dir=self.temp_path,
572+
measure_power_secs=1, # Short interval for testing
573+
) as tracker:
574+
# Ensure scheduler is running (default state)
575+
self.assertFalse(tracker._scheduler._stopped)
576+
577+
# Artificially set last measured time to simulate long delay
578+
import time
579+
tracker._last_measured_time = time.perf_counter() - 10 # 10 seconds ago
580+
581+
# Reset mock to clear any previous warning calls
582+
mock_logger.warning.reset_mock()
583+
584+
# Call _measure_power_and_energy directly - this should trigger warning
585+
tracker._measure_power_and_energy()
586+
587+
# Verify warning was logged since scheduler should be running
588+
scheduler_warning_found = False
589+
if mock_logger.warning.called:
590+
for call in mock_logger.warning.call_args_list:
591+
args, kwargs = call
592+
if args and "Background scheduler didn't run for a long period" in str(args[0]):
593+
scheduler_warning_found = True
594+
break
595+
596+
self.assertTrue(scheduler_warning_found, "Expected scheduler warning was not found")

0 commit comments

Comments
 (0)