|
15 | 15 | from __future__ import annotations |
16 | 16 |
|
17 | 17 | import datetime |
| 18 | +import functools |
18 | 19 | from unittest import mock |
19 | 20 |
|
20 | 21 | import duet |
@@ -194,6 +195,17 @@ def _to_timestamp(json_string): |
194 | 195 | ) |
195 | 196 |
|
196 | 197 |
|
| 198 | +class _FrozenDateTime(datetime.datetime): |
| 199 | + """Frozen datetime for testing time related behavior.""" |
| 200 | + |
| 201 | + _stock_datetime = datetime.datetime |
| 202 | + |
| 203 | + @classmethod |
| 204 | + @functools.cache |
| 205 | + def now(cls, tz=None): |
| 206 | + return cls._stock_datetime.now(tz) |
| 207 | + |
| 208 | + |
197 | 209 | class FakeEngineContext(EngineContext): |
198 | 210 | """Fake engine context for testing.""" |
199 | 211 |
|
@@ -769,17 +781,16 @@ def test_get_schedule_filter_by_time_slot(list_time_slots): |
769 | 781 | ) |
770 | 782 |
|
771 | 783 |
|
772 | | -@mock.patch('cirq_google.engine.engine_processor._now') |
| 784 | +@mock.patch('datetime.datetime', _FrozenDateTime) |
773 | 785 | @mock.patch('cirq_google.engine.engine_client.EngineClient.list_time_slots_async') |
774 | | -def test_get_schedule_time_filter_behavior(list_time_slots, mock_now): |
775 | | - fixed_now = datetime.datetime(2026, 4, 1) |
| 786 | +def test_get_schedule_time_filter_behavior(list_time_slots): |
| 787 | + _FrozenDateTime.now.cache_clear() |
| 788 | + fixed_now = _FrozenDateTime.now() |
776 | 789 |
|
777 | | - mock_now.return_value = fixed_now |
| 790 | + now = int(fixed_now.timestamp()) |
778 | 791 | list_time_slots.return_value = [] |
779 | 792 | processor = cg.EngineProcessor('proj', 'p0', EngineContext()) |
780 | | - now = int((fixed_now).timestamp()) |
781 | 793 | in_two_weeks = int((fixed_now + datetime.timedelta(weeks=2)).timestamp()) |
782 | | - |
783 | 794 | processor.get_schedule() |
784 | 795 | list_time_slots.assert_called_with( |
785 | 796 | 'proj', 'p0', f'start_time < {in_two_weeks} AND end_time > {now}' |
@@ -815,15 +826,15 @@ def test_get_schedule_time_filter_behavior(list_time_slots, mock_now): |
815 | 826 | list_time_slots.assert_called_with('proj', 'p0', f'start_time < {utc_ts}') |
816 | 827 |
|
817 | 828 |
|
818 | | -@mock.patch('cirq_google.engine.engine_processor._now') |
| 829 | +@mock.patch('datetime.datetime', _FrozenDateTime) |
819 | 830 | @mock.patch('cirq_google.engine.engine_client.EngineClient.list_reservations_async') |
820 | | -def test_list_reservations_time_filter_behavior(list_reservations, mock_now): |
821 | | - fixed_now = datetime.datetime(2026, 4, 1) |
| 831 | +def test_list_reservations_time_filter_behavior(list_reservations): |
| 832 | + _FrozenDateTime.now.cache_clear() |
| 833 | + fixed_now = _FrozenDateTime.now() |
822 | 834 |
|
823 | | - mock_now.return_value = fixed_now |
| 835 | + now = int(fixed_now.timestamp()) |
824 | 836 | list_reservations.return_value = [] |
825 | 837 | processor = cg.EngineProcessor('proj', 'p0', EngineContext()) |
826 | | - now = int((fixed_now).timestamp()) |
827 | 838 | in_two_weeks = int((fixed_now + datetime.timedelta(weeks=2)).timestamp()) |
828 | 839 | processor.list_reservations() |
829 | 840 | list_reservations.assert_called_with( |
|
0 commit comments