Skip to content

Commit e80abca

Browse files
ciancbenoit-cty
authored andcommitted
Merge cumulative emissions test into TestVariableEmissions and delete temp file
1 parent 30a3f24 commit e80abca

1 file changed

Lines changed: 93 additions & 0 deletions

File tree

tests/test_emissions_tracker.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,3 +656,96 @@ def test_get_detected_hardware(
656656
self.assertIn("gpu_count", hardware_info)
657657
self.assertIn("gpu_model", hardware_info)
658658
self.assertIn("gpu_ids", hardware_info)
659+
660+
661+
class TestVariableEmissions(unittest.TestCase):
662+
@mock.patch("codecarbon.emissions_tracker.EmissionsTracker._get_geo_metadata")
663+
@mock.patch("codecarbon.emissions_tracker.EmissionsTracker._get_cloud_metadata")
664+
@mock.patch("codecarbon.core.electricitymaps_api.requests.get")
665+
@mock.patch("codecarbon.emissions_tracker.ResourceTracker")
666+
@mock.patch(
667+
"codecarbon.emissions_tracker.BaseEmissionsTracker.get_detected_hardware"
668+
)
669+
@mock.patch("codecarbon.emissions_tracker.PeriodicScheduler")
670+
def test_cumulative_emissions_with_varying_intensity(
671+
self,
672+
mock_scheduler,
673+
mock_get_hw,
674+
mock_resource_tracker,
675+
mock_get,
676+
mock_cloud,
677+
mock_geo,
678+
):
679+
# Setup mocks
680+
mock_geo.return_value = mock.MagicMock(
681+
latitude=1.0,
682+
longitude=1.0,
683+
country_iso_code="USA",
684+
country_2letter_iso_code="US",
685+
)
686+
mock_cloud.return_value = mock.MagicMock(
687+
is_on_private_infra=True, provider="azure", region="eastus"
688+
)
689+
mock_get_hw.return_value = {
690+
"ram_total_size": 16.0,
691+
"cpu_count": 8,
692+
"cpu_physical_count": 4,
693+
"cpu_model": "Mock CPU",
694+
"gpu_count": 0,
695+
"gpu_model": "None",
696+
"gpu_ids": None,
697+
}
698+
699+
# Mock Electricity Maps API responses with different intensities
700+
# 1st call: 100 g/kWh, 2nd call: 200 g/kWh, 3rd call: 300 g/kWh
701+
responses = [
702+
mock.MagicMock(status_code=200, json=lambda: {"carbonIntensity": 100}),
703+
mock.MagicMock(status_code=200, json=lambda: {"carbonIntensity": 200}),
704+
mock.MagicMock(status_code=200, json=lambda: {"carbonIntensity": 300}),
705+
]
706+
mock_get.side_effect = responses
707+
708+
tracker = EmissionsTracker(
709+
electricitymaps_api_token="test-token",
710+
save_to_file=False,
711+
measure_power_secs=1,
712+
allow_multiple_runs=True,
713+
)
714+
715+
# Manually inject a mock hardware component
716+
mock_cpu = mock.MagicMock()
717+
from codecarbon.external.hardware import CPU
718+
719+
mock_cpu.__class__ = CPU
720+
# Mock measure_power_and_energy: return 1kWh delta each time
721+
mock_cpu.measure_power_and_energy.return_value = (
722+
Power.from_watts(100),
723+
Energy.from_energy(kWh=1.0),
724+
)
725+
tracker._hardware = [mock_cpu]
726+
727+
# Start tracking
728+
tracker.start()
729+
730+
# Step 1
731+
tracker._measure_power_and_energy()
732+
# total_energy = 1.0, intensity = 100 => emissions = 0.1 kg
733+
data1 = tracker._prepare_emissions_data()
734+
self.assertAlmostEqual(data1.emissions, 0.1)
735+
736+
# Step 2
737+
tracker._measure_power_and_energy()
738+
# total_energy = 2.0, delta_energy = 1.0, intensity = 200 => delta_emissions = 0.2 kg
739+
# total_emissions = 0.1 + 0.2 = 0.3 kg
740+
data2 = tracker._prepare_emissions_data()
741+
self.assertAlmostEqual(data2.emissions, 0.3)
742+
743+
# Step 3
744+
tracker._measure_power_and_energy()
745+
# total_energy = 3.0, delta_energy = 1.0, intensity = 300 => delta_emissions = 0.3 kg
746+
# total_emissions = 0.3 + 0.3 = 0.6 kg
747+
data3 = tracker._prepare_emissions_data()
748+
self.assertAlmostEqual(data3.emissions, 0.6)
749+
750+
# Verification: If it wasn't cumulative, it would be 3.0 kWh * 300 g/kWh = 0.9 kg
751+
self.assertLess(data3.emissions, 0.8)

0 commit comments

Comments
 (0)