diff --git a/backend/scheduler.py b/backend/scheduler.py index 52f486e..e3494bf 100644 --- a/backend/scheduler.py +++ b/backend/scheduler.py @@ -3,7 +3,7 @@ import os from dataclasses import dataclass from datetime import date, timedelta -from test_window import get_shift_sequence_with_capacity, is_off_day, next_window_start_date +from test_window import get_shift_sequence_with_capacity, get_shift_capacity_for_date, is_off_day, next_window_start_date from test_bundle import Test, TestBundle, build_test_bundles, bundle_pair_lookup DUT = (os.getenv("DUT") or "DUT").strip() @@ -287,28 +287,50 @@ class Scheduler: window: ScheduleWindow, bundles: list[TestBundle], ) -> None: + # Build per-shift remaining capacity + shift_remaining = [ + get_shift_capacity_for_date(day, self.holiday_dates, self.daytime_testing_today).get(shift_idx, 0) + for day, shift_idx in window.shifts + ] + current_shift_pos = 0 + sequence_in_shift = 0 + for bundle in bundles: bundle_key = (bundle.index, bundle.device) if bundle_key in self.scheduled_bundle_keys: continue self.scheduled_bundle_keys.add(bundle_key) - for idx, test in enumerate(bundle.tests): + for test in bundle.tests: schedule_key = f"{test}:{bundle.device}" if schedule_key in self.scheduled_test_ids: continue self.scheduled_test_ids.add(schedule_key) + test_minutes = self._get_test_minutes(test, bundle.device) + + # Advance past any shift that can't fit this test + while current_shift_pos < len(window.shifts) and shift_remaining[current_shift_pos] < test_minutes: + current_shift_pos += 1 + sequence_in_shift = 0 + + if current_shift_pos >= len(window.shifts): + break + + shift_day, shift_idx = window.shifts[current_shift_pos] + sequence_in_shift += 1 + shift_remaining[current_shift_pos] -= test_minutes + window.remaining_minutes -= test_minutes + self.schedule.append( ScheduleEntry( test_id=test, device=bundle.device, - scheduled_date=str(window.shifts[0][0]), - shift_index=window.shifts[0][1], - sequence_in_shift=idx + 1, + scheduled_date=str(shift_day), + shift_index=shift_idx, + sequence_in_shift=sequence_in_shift, ) ) - window.remaining_minutes -= self._get_test_minutes(test, bundle.device) def _get_test_minutes(self, test_id: str, device: str) -> int: