-
Notifications
You must be signed in to change notification settings - Fork 86
fix: guard against KeyError in get_priority_change_date by using .get() #2901
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
AmSach
wants to merge
9
commits into
mozilla:master
Choose a base branch
from
AmSach:fix/keyerror-field-name-in-get-priority-change-date
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+176
−4
Open
Changes from 6 commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
106449e
fix: guard against KeyError in get_priority_change_date by using .get()
AmSach 658e5a1
test: add regression tests for get_priority_change_date KeyError fix
AmSach 4b6adb3
test: place new test file in correct path
AmSach 3bca3c2
style: fix ruff and ruff-format issues in test_assignee_no_login_prio…
AmSach c89862c
test: fix AssigneeNoLogin constructor call to use no args
AmSach f9684ab
test: stub People.get_instance so rule tests don't need ./configs/peo…
AmSach cc935e2
style: apply ruff-format to test_assignee_no_login_priority.py
AmSach 79fc0b0
fix: log warning when history entry is missing expected keys
AmSach f4ab591
chore: remove duplicate test file at bugbot/tests/rules/
AmSach File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,131 @@ | ||
| # This Source Code Form is subject to the terms of the Mozilla Public | ||
| # License, v. 2.0. If a copy of the MPL was not distributed with this file, | ||
| # You can obtain one at http://mozilla.org/MPL/2.0/. | ||
|
|
||
| """Regression tests for the AssigneeNoLogin rule's priority-change lookup. | ||
|
|
||
| The production fix changed ``change["field_name"]`` and ``change["added"]`` to | ||
| ``change.get("field_name")`` and ``change.get("added")`` in | ||
| ``bugbot/rules/assignee_no_login.py:get_priority_change_date``. These tests | ||
| exercise both the pre-fix failure mode (a KeyError when history entries are | ||
| missing one of the expected keys) and the fixed behaviour. | ||
| """ | ||
|
|
||
| from datetime import datetime | ||
| from unittest.mock import patch | ||
|
|
||
| import pytest | ||
|
|
||
| from bugbot.people import People | ||
| from bugbot.rules.assignee_no_login import AssigneeNoLogin | ||
|
|
||
|
|
||
| def _mock_people(): | ||
| """Build a minimal People object that satisfies the Person TypedDict.""" | ||
| return People( | ||
| [ | ||
| { | ||
| "mail": "test@example.com", | ||
| "cn": "Test User", | ||
| "ismanager": "FALSE", | ||
| "title": "Tester", | ||
| "bugzillaEmail": "test@example.com", | ||
| "bugzillaID": "1", | ||
| "dn": "mail=test@example.com,o=com,dc=test", | ||
| "found_on_bugzilla": True, | ||
| "im": [], | ||
| "isdirector": "FALSE", | ||
| "manager": { | ||
| "cn": "", | ||
| "dn": "mail=manager@example.com,o=com,dc=test", | ||
| }, | ||
| } | ||
| ] | ||
| ) | ||
|
|
||
|
|
||
| @pytest.fixture | ||
| def rule(): | ||
| """Return an AssigneeNoLogin rule with People stubbed out.""" | ||
| with patch.object(People, "get_instance", return_value=_mock_people()): | ||
| yield AssigneeNoLogin() | ||
|
|
||
|
|
||
| def test_get_priority_change_date_returns_date_when_history_entry_matches(rule): | ||
| when = "2024-01-15T12:00:00Z" | ||
| bug = { | ||
| "priority": "P1", | ||
| "history": [ | ||
| {"field_name": "priority", "added": "P3", "when": "2023-01-01T00:00:00Z"}, | ||
| {"field_name": "priority", "added": "P1", "when": when}, | ||
| ], | ||
| } | ||
|
|
||
| result = rule.get_priority_change_date(bug) | ||
|
|
||
| assert result == datetime(2024, 1, 15, 12, 0, 0) | ||
|
|
||
|
|
||
| def test_get_priority_change_date_handles_missing_field_name_without_keyerror(rule): | ||
| """A history entry without ``field_name`` must not crash the lookup.""" | ||
| when = "2024-05-20T08:30:00Z" | ||
| bug = { | ||
| "priority": "P2", | ||
| "history": [ | ||
| # Missing both "field_name" and "added" - this is what crashed | ||
| # before the fix. | ||
| {"when": "2024-04-01T00:00:00Z"}, | ||
| {"field_name": "status", "added": "NEW", "when": "2024-04-15T00:00:00Z"}, | ||
| {"field_name": "priority", "added": "P2", "when": when}, | ||
| ], | ||
| } | ||
|
|
||
| result = rule.get_priority_change_date(bug) | ||
|
|
||
| assert result == datetime(2024, 5, 20, 8, 30, 0) | ||
|
|
||
|
|
||
| def test_get_priority_change_date_returns_none_when_no_match(rule): | ||
| bug = { | ||
| "priority": "P1", | ||
| "history": [ | ||
| {"field_name": "priority", "added": "P2", "when": "2024-01-01T00:00:00Z"}, | ||
| { | ||
| "field_name": "status", | ||
| "added": "RESOLVED", | ||
| "when": "2024-02-01T00:00:00Z", | ||
| }, | ||
| ], | ||
| } | ||
|
|
||
| assert rule.get_priority_change_date(bug) is None | ||
|
|
||
|
|
||
| def test_get_priority_change_date_skips_entries_missing_field_name(rule): | ||
| """Entries that lack ``field_name`` must be skipped, not raise KeyError.""" | ||
| bug = { | ||
| "priority": "P1", | ||
| "history": [ | ||
| # No "field_name" key at all. | ||
| {"added": "P1", "when": "2024-03-10T00:00:00Z"}, | ||
| ], | ||
| } | ||
|
|
||
| # Should not raise KeyError. The fixed implementation falls back to None | ||
| # when the field_name check fails (None != "priority"). | ||
| assert rule.get_priority_change_date(bug) is None | ||
|
|
||
|
|
||
| def test_get_priority_change_date_picks_most_recent_match(rule): | ||
| bug = { | ||
| "priority": "P3", | ||
| "history": [ | ||
| {"field_name": "priority", "added": "P1", "when": "2023-06-01T00:00:00Z"}, | ||
| {"field_name": "priority", "added": "P2", "when": "2024-02-01T00:00:00Z"}, | ||
| {"field_name": "priority", "added": "P3", "when": "2024-08-15T00:00:00Z"}, | ||
| ], | ||
| } | ||
|
|
||
| result = rule.get_priority_change_date(bug) | ||
|
|
||
| assert result == datetime(2024, 8, 15, 0, 0, 0) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to find the root cause first. This will just hide the problem, not fix it.