def test_get_schedule(list_time_slots): results = [ quantum.QuantumTimeSlot( processor_name='potofgold', start_time=Timestamp(seconds=1000020000), end_time=Timestamp(seconds=1000040000), time_slot_type=quantum.QuantumTimeSlot.TimeSlotType.MAINTENANCE, maintenance_config=quantum.QuantumTimeSlot.MaintenanceConfig( title='Testing', description='Testing some new configuration.'), ), quantum.QuantumTimeSlot( processor_name='potofgold', start_time=Timestamp(seconds=1000010000), end_time=Timestamp(seconds=1000020000), time_slot_type=quantum.QuantumTimeSlot.TimeSlotType.RESERVATION, reservation_config=quantum.QuantumTimeSlot.ReservationConfig( project_id='super_secret_quantum'), ), ] list_time_slots.return_value = results processor = cg.EngineProcessor('proj', 'p0', EngineContext()) assert (processor.get_schedule( datetime.datetime.fromtimestamp(1000000000), datetime.datetime.fromtimestamp(1000050000)) == results) list_time_slots.assert_called_once_with( 'proj', 'p0', 'start_time < 1000050000 AND end_time > 1000000000')
def test_get_schedule(): time_slot = quantum.QuantumTimeSlot( processor_name='test', start_time=Timestamp(seconds=1000000), end_time=Timestamp(seconds=2000000), time_slot_type=quantum.QuantumTimeSlot.TimeSlotType.OPEN_SWIM, ) p = NothingProcessor(processor_id='test', schedule=[time_slot]) assert p.get_schedule(from_time=_time(500000), to_time=_time(2500000)) == [time_slot] assert p.get_schedule(from_time=_time(1500000), to_time=_time(2500000)) == [time_slot] assert p.get_schedule(from_time=_time(500000), to_time=_time(1500000)) == [time_slot] assert p.get_schedule(from_time=_time(500000), to_time=_time(750000)) == [] assert p.get_schedule(from_time=_time(2500000), to_time=_time(300000)) == [] # check unbounded cases unbounded_start = quantum.QuantumTimeSlot( processor_name='test', end_time=Timestamp(seconds=1000000), time_slot_type=quantum.QuantumTimeSlot.TimeSlotType.OPEN_SWIM, ) unbounded_end = quantum.QuantumTimeSlot( processor_name='test', start_time=Timestamp(seconds=2000000), time_slot_type=quantum.QuantumTimeSlot.TimeSlotType.OPEN_SWIM, ) p = NothingProcessor(processor_id='test', schedule=[unbounded_start, unbounded_end]) assert p.get_schedule(from_time=_time(500000), to_time=_time(2500000)) == [ unbounded_start, unbounded_end, ] assert p.get_schedule(from_time=_time(1500000), to_time=_time(2500000)) == [unbounded_end] assert p.get_schedule(from_time=_time(500000), to_time=_time(1500000)) == [unbounded_start] assert p.get_schedule(from_time=_time(1200000), to_time=_time(1500000)) == []
def test_list_time_slots(client_constructor): grpc_client = setup_mock_(client_constructor) results = [ quantum.QuantumTimeSlot( processor_name='potofgold', start_time=Timestamp(seconds=1000020000), end_time=Timestamp(seconds=1000040000), time_slot_type=quantum.QuantumTimeSlot.TimeSlotType.MAINTENANCE, maintenance_config=quantum.QuantumTimeSlot.MaintenanceConfig( title='Testing', description='Testing some new configuration.' ), ), quantum.QuantumTimeSlot( processor_name='potofgold', start_time=Timestamp(seconds=1000010000), end_time=Timestamp(seconds=1000020000), time_slot_type=quantum.QuantumTimeSlot.TimeSlotType.RESERVATION, reservation_config=quantum.QuantumTimeSlot.ReservationConfig( project_id='super_secret_quantum' ), ), ] grpc_client.list_quantum_time_slots.return_value = Pager(results) client = EngineClient() assert client.list_time_slots('proj', 'processor0') == results
def test_create_reservation_border_conditions(): time_slot = quantum.QuantumTimeSlot( processor_name='test', start_time=Timestamp(seconds=1000000), end_time=Timestamp(seconds=2000000), time_slot_type=quantum.QuantumTimeSlot.TimeSlotType.UNALLOCATED, ) p = NothingProcessor(processor_id='test', schedule=[time_slot]) p.create_reservation(start_time=_time(1900000), end_time=_time(2000000)) p.create_reservation(start_time=_time(1000000), end_time=_time(1100000)) assert p.get_schedule(from_time=_time(200000), to_time=_time(2500000)) == [ quantum.QuantumTimeSlot( processor_name='test', start_time=Timestamp(seconds=1000000), end_time=Timestamp(seconds=1100000), time_slot_type=quantum.QuantumTimeSlot.TimeSlotType.RESERVATION, ), quantum.QuantumTimeSlot( processor_name='test', start_time=Timestamp(seconds=1100000), end_time=Timestamp(seconds=1900000), time_slot_type=quantum.QuantumTimeSlot.TimeSlotType.UNALLOCATED, ), quantum.QuantumTimeSlot( processor_name='test', start_time=Timestamp(seconds=1900000), end_time=Timestamp(seconds=2000000), time_slot_type=quantum.QuantumTimeSlot.TimeSlotType.RESERVATION, ), ]
def test_bad_schedule(): time_slot1 = quantum.QuantumTimeSlot( processor_name='test', start_time=Timestamp(seconds=1000000), end_time=Timestamp(seconds=3000000), time_slot_type=quantum.QuantumTimeSlot.TimeSlotType.OPEN_SWIM, ) time_slot2 = quantum.QuantumTimeSlot( processor_name='test', start_time=Timestamp(seconds=2000000), end_time=Timestamp(seconds=4000000), time_slot_type=quantum.QuantumTimeSlot.TimeSlotType.OPEN_SWIM, ) with pytest.raises(ValueError, match='cannot overlap'): _ = NothingProcessor(processor_id='test', schedule=[time_slot1, time_slot2])
def __init__( self, *, processor_id: str, engine: Optional['AbstractEngine'] = None, expected_down_time: Optional[datetime.datetime] = None, expected_recovery_time: Optional[datetime.datetime] = None, schedule: Optional[List[quantum.QuantumTimeSlot]] = None, project_name: str = 'fake_project', ): self._engine = engine self._expected_recovery_time = expected_recovery_time self._expected_down_time = expected_down_time self._reservations: Dict[str, quantum.QuantumReservation] = {} self._resource_id_counter = 0 self._processor_id = processor_id self._project_name = project_name if schedule is None: self._schedule = [ quantum.QuantumTimeSlot( processor_name=self._processor_id, time_slot_type=quantum.QuantumTimeSlot.TimeSlotType. UNALLOCATED, ) ] else: self._schedule = sorted(schedule, key=lambda t: t.start_time.timestamp() if t.start_time else -1) for idx in range(len(self._schedule) - 1): if self._schedule[idx].end_time > self._schedule[idx + 1].start_time: raise ValueError('Time slots cannot overlap!')
def _reservation_to_time_slot( self, reservation: quantum.QuantumReservation ) -> quantum.QuantumTimeSlot: """Changes a reservation object into a time slot object.""" return quantum.QuantumTimeSlot( processor_name=self._processor_id, start_time=reservation.start_time, end_time=reservation.end_time, time_slot_type=quantum.QuantumTimeSlot.TimeSlotType.RESERVATION, )
def test_create_reservation_splitunbounded(): time_slot_begin = quantum.QuantumTimeSlot( processor_name='test', end_time=Timestamp(seconds=3000000), time_slot_type=quantum.QuantumTimeSlot.TimeSlotType.UNALLOCATED, ) time_slot_end = quantum.QuantumTimeSlot( processor_name='test', start_time=Timestamp(seconds=5000000), time_slot_type=quantum.QuantumTimeSlot.TimeSlotType.UNALLOCATED, ) p = NothingProcessor(processor_id='test', schedule=[time_slot_begin, time_slot_end]) p.create_reservation(start_time=_time(1000000), end_time=_time(2000000)) p.create_reservation(start_time=_time(6000000), end_time=_time(7000000)) assert p.get_schedule(from_time=_time(200000), to_time=_time(10000000)) == [ quantum.QuantumTimeSlot( processor_name='test', end_time=Timestamp(seconds=1000000), time_slot_type=quantum.QuantumTimeSlot.TimeSlotType.UNALLOCATED, ), quantum.QuantumTimeSlot( processor_name='test', start_time=Timestamp(seconds=1000000), end_time=Timestamp(seconds=2000000), time_slot_type=quantum.QuantumTimeSlot.TimeSlotType.RESERVATION, ), quantum.QuantumTimeSlot( processor_name='test', start_time=Timestamp(seconds=2000000), end_time=Timestamp(seconds=3000000), time_slot_type=quantum.QuantumTimeSlot.TimeSlotType.UNALLOCATED, ), quantum.QuantumTimeSlot( processor_name='test', start_time=Timestamp(seconds=5000000), end_time=Timestamp(seconds=6000000), time_slot_type=quantum.QuantumTimeSlot.TimeSlotType.UNALLOCATED, ), quantum.QuantumTimeSlot( processor_name='test', start_time=Timestamp(seconds=6000000), end_time=Timestamp(seconds=7000000), time_slot_type=quantum.QuantumTimeSlot.TimeSlotType.RESERVATION, ), quantum.QuantumTimeSlot( processor_name='test', start_time=Timestamp(seconds=7000000), time_slot_type=quantum.QuantumTimeSlot.TimeSlotType.UNALLOCATED, ), ]
p = NothingProcessor(processor_id='test', schedule=[unbounded_start, unbounded_end]) assert p.get_schedule(from_time=_time(500000), to_time=_time(2500000)) == [ unbounded_start, unbounded_end, ] assert p.get_schedule(from_time=_time(1500000), to_time=_time(2500000)) == [unbounded_end] assert p.get_schedule(from_time=_time(500000), to_time=_time(1500000)) == [unbounded_start] assert p.get_schedule(from_time=_time(1200000), to_time=_time(1500000)) == [] @pytest.mark.parametrize( ('time_slot'), ( quantum.QuantumTimeSlot( processor_name='test', start_time=Timestamp(seconds=1000000), end_time=Timestamp(seconds=2000000), time_slot_type=quantum.QuantumTimeSlot.TimeSlotType.OPEN_SWIM, ), quantum.QuantumTimeSlot( processor_name='test', start_time=Timestamp(seconds=1000000), time_slot_type=quantum.QuantumTimeSlot.TimeSlotType.OPEN_SWIM, ), quantum.QuantumTimeSlot( processor_name='test', end_time=Timestamp(seconds=2000000), time_slot_type=quantum.QuantumTimeSlot.TimeSlotType.OPEN_SWIM, ), ), ) def test_create_reservation_not_available(time_slot):
def _insert_reservation_into(self, time_slot: quantum.QuantumTimeSlot) -> None: """Inserts a new reservation time slot into the ordered schedule. If this reservation overlaps with existing time slots, these slots will be shortened, removed, or split to insert the new reservation. """ new_schedule = [] time_slot_inserted = False for t in self._schedule: if t.end_time and t.end_time.timestamp( ) <= time_slot.start_time.timestamp(): # [--time_slot--] # [--t--] new_schedule.append(t) continue if t.start_time and t.start_time.timestamp( ) >= time_slot.end_time.timestamp(): # [--time_slot--] # [--t--] new_schedule.append(t) continue if t.start_time and time_slot.start_time.timestamp( ) <= t.start_time.timestamp(): if not time_slot_inserted: new_schedule.append(time_slot) time_slot_inserted = True if not t.end_time or t.end_time.timestamp( ) > time_slot.end_time.timestamp(): # [--time_slot---] # [----t-----] t.start_time = time_slot.end_time new_schedule.append(t) # if t.end_time < time_slot.end_time # [------time_slot-----] # [-----t-----] # t should be removed else: if not t.end_time or t.end_time.timestamp( ) > time_slot.end_time.timestamp(): # [---time_slot---] # [-------------t---------] # t should be split start = quantum.QuantumTimeSlot( processor_name=self._processor_id, end_time=time_slot.start_time, time_slot_type=t.time_slot_type, ) if t.start_time: start.start_time = t.start_time end = quantum.QuantumTimeSlot( processor_name=self._processor_id, start_time=time_slot.end_time, time_slot_type=t.time_slot_type, ) if t.end_time: end.end_time = t.end_time new_schedule.append(start) new_schedule.append(time_slot) new_schedule.append(end) else: # [---time_slot---] # [----t-----] t.end_time = time_slot.start_time new_schedule.append(t) new_schedule.append(time_slot) time_slot_inserted = True if not time_slot_inserted: new_schedule.append(time_slot) self._schedule = new_schedule