From 6b7e5bb2af8cbfe0b77a33746c84a80ceddbd104 Mon Sep 17 00:00:00 2001 From: Matias Bordese Date: Fri, 18 Aug 2023 09:26:49 -0300 Subject: [PATCH 1/2] Check possible split events in range when resolving schedule --- .../apps/schedules/models/on_call_schedule.py | 4 ++ .../schedules/tests/test_on_call_schedule.py | 56 +++++++++++++++++++ .../schedules/tests/test_quality_score.py | 4 +- 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/engine/apps/schedules/models/on_call_schedule.py b/engine/apps/schedules/models/on_call_schedule.py index bbb16b9496..7c0820f44f 100644 --- a/engine/apps/schedules/models/on_call_schedule.py +++ b/engine/apps/schedules/models/on_call_schedule.py @@ -812,6 +812,10 @@ def _merge_intervals(evs: ScheduleEvents) -> ScheduleEventIntervals: # exclude events without active users continue + if ev["start"] >= datetime_end or ev["end"] <= datetime_start: + # avoid including split events which now are outside the requested time range + continue + # api/terraform shifts could be missing a priority; assume None means 0 priority = ev["priority_level"] or 0 if priority != current_priority or current_type != ev["calendar_type"]: diff --git a/engine/apps/schedules/tests/test_on_call_schedule.py b/engine/apps/schedules/tests/test_on_call_schedule.py index 8c09cfc71a..aeafe7824b 100644 --- a/engine/apps/schedules/tests/test_on_call_schedule.py +++ b/engine/apps/schedules/tests/test_on_call_schedule.py @@ -2094,6 +2094,62 @@ def test_swap_request_split_end( assert events[1]["users"][0]["pk"] == user.public_primary_key +@pytest.mark.django_db +def test_swap_request_split_final_events_range( + make_organization, + make_user_for_organization, + make_schedule, + make_on_call_shift, + make_shift_swap_request, +): + organization = make_organization() + user = make_user_for_organization(organization) + other_user = make_user_for_organization(organization) + + schedule = make_schedule(organization, schedule_class=OnCallScheduleWeb) + today = timezone.now().replace(hour=0, minute=0, second=0, microsecond=0) + start = today + timezone.timedelta(hours=10) + duration = timezone.timedelta(hours=8) + data = { + "start": start, + "rotation_start": start, + "duration": duration, + "priority_level": 1, + "frequency": CustomOnCallShift.FREQUENCY_DAILY, + "schedule": schedule, + } + on_call_shift = make_on_call_shift( + organization=organization, shift_type=CustomOnCallShift.TYPE_ROLLING_USERS_EVENT, **data + ) + on_call_shift.add_rolling_users([[user]]) + + tomorrow = today + timezone.timedelta(days=1) + # setup swap request + swap_request = make_shift_swap_request( + schedule, + user, + swap_start=tomorrow + timezone.timedelta(hours=16), + swap_end=tomorrow + timezone.timedelta(hours=18), + ) + swap_request.take(other_user) + + # check final events for tomorrow while swap in progress + now = tomorrow + timezone.timedelta(hours=16, minutes=10) + events = schedule.final_events(now, now) + + assert len(events) == 1 + expected = [ + # start, end, on-call user + ( + tomorrow + timezone.timedelta(hours=16), + tomorrow + timezone.timedelta(hours=18), + other_user.public_primary_key, + ), + ] + returned = [(e["start"], e["end"], e["users"][0]["pk"]) for e in events] + assert returned == expected + + @pytest.mark.django_db @pytest.mark.parametrize("swap_taken", [False, True]) def test_swap_request_split_both( diff --git a/engine/apps/schedules/tests/test_quality_score.py b/engine/apps/schedules/tests/test_quality_score.py index bbcb794923..5926f9297f 100644 --- a/engine/apps/schedules/tests/test_quality_score.py +++ b/engine/apps/schedules/tests/test_quality_score.py @@ -190,7 +190,7 @@ def test_get_schedule_score_weekdays( assert response.json() == { "total_score": 86, "comments": [ - {"type": "warning", "text": "Schedule has gaps (28% not covered)"}, + {"type": "warning", "text": "Schedule has gaps (29% not covered)"}, {"type": "info", "text": "Schedule is perfectly balanced"}, ], "overloaded_users": [], @@ -351,7 +351,7 @@ def test_get_schedule_score_all_week_imbalanced_weekends( { "id": user.public_primary_key, "username": user.username, - "score": 28, + "score": 29, } for user in users[:4] ], From deb7b8d41267263ee0c9b6aa7133ad6b1a3eb563 Mon Sep 17 00:00:00 2001 From: Matias Bordese Date: Fri, 18 Aug 2023 09:28:56 -0300 Subject: [PATCH 2/2] Update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb27a4991e..170d323732 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed UTC conversion for escalation chain step of timerange ([#2781](https://github.com/grafana/oncall/issues/2781)) +### Fixed + +- Check for possible split events in range when resolving schedule ([#2828](https://github.com/grafana/oncall/pull/2828)) + ## v1.3.24 (2023-08-17) ### Added