Set fuzzer author as reporter for bugs from external fuzzers#5312
Set fuzzer author as reporter for bugs from external fuzzers#5312jr2bg wants to merge 4 commits into
Conversation
dylanjew
left a comment
There was a problem hiding this comment.
Great job overall!
A couple things:
-
Change the branch to merge this into
master -
Please run
python butler.py formatandpython butler.py lint -
Could you add a section to your description explaining the steps that you went through to test this? It would be great to include screenshots of this is in dev and then verifying the field in the Datastore. Let me know if you have any questions
-
Similarly, the backfill script component of this bug probably warrants another section in the PR description. It should cover the order of operations for rolling out this change and how you're going to get the primary owner data for the backfill. Again, lmk if I can help with this. The state of our blackbox fuzzers is not great, and there are many that we need to track down their status/owners.
| if __name__ == '__main__': | ||
| parser = argparse.ArgumentParser(description='Backfill primary_owner for Fuzzers.') | ||
| parser.add_argument('--live', action='store_true', help='Perform live updates.') | ||
| parser.add_argument('--owner', default='default-owner@example.com', help='Default owner email.') |
There was a problem hiding this comment.
does it make sense to have a default owner? Can we just leave it empty for now if we're not sure, and then keep the existing behavior if it is empty?
|
|
||
| if __name__ == '__main__': | ||
| parser = argparse.ArgumentParser(description='Backfill primary_owner for Fuzzers.') | ||
| parser.add_argument('--live', action='store_true', help='Perform live updates.') |
There was a problem hiding this comment.
I think if you run this using the butler run script the arg should be non-dry-run
| logs.info(f'Filing new issue for testcase: {testcase.key.id()}.') | ||
|
|
||
| policy = issue_tracker_policy.get(issue_tracker.project) | ||
| fuzzer = None |
There was a problem hiding this comment.
does this need to be a DataStore look up?
| for fuzzer in query.fetch(): | ||
| print(f"Processing fuzzer: {fuzzer.name}") | ||
| if not dry_run: | ||
| fuzzer.primary_owner = default_owner |
There was a problem hiding this comment.
do we expect the primary_owner to be the same for most of these fuzzers? I would have guessed that there were for example 10 externally contributed fuzzers and maybe 8 different authors of those fuzzers.
|
|
||
| def migrate(dry_run=True, default_owner='default-owner@example.com'): | ||
| """Migrates fuzzer owners.""" | ||
| query = data_types.Fuzzer.query( |
There was a problem hiding this comment.
I would add a filter on external_contribution
| external_contribution=True, | ||
| primary_owner='owner@example.com').put() | ||
|
|
||
| issue_tracker = monorail.IssueTracker(IssueTrackerManager('chromium')) |
There was a problem hiding this comment.
is this the correct way to create an IssueTracker? My understanding is that we migrated from Monorail to IssueTracker/Buganizer at some point.
|
|
||
| issue_filer.file_issue(self.testcase1, issue_tracker, user_email='reporter@example.com') | ||
|
|
||
| self.assertEqual('owner@example.com', issue_tracker._itm.last_issue.reporter) |
There was a problem hiding this comment.
nit: is there a better way to check the reporter for the filed issue? _itm.last_issue.reporter seems a bit roundabout and reaches into a private method
71a3845 to
1c3affd
Compare
- issue_filer.py Get fuzzer from DataStore query, handles cases when no `primary_owner` is found, does not consider yet `external_contribution. - migrate_fuzzer_owners.py Removes the owner
1c3affd to
e4b33cd
Compare
| issue.components.add(policy.unreproducible_component) | ||
|
|
||
| issue.reporter = user_email | ||
| if fuzzer and getattr(fuzzer, 'primary_owner', None): |
There was a problem hiding this comment.
instead of getattr, can you just check the field directly with fuzzer.primary_owner?
| try: | ||
| fuzzer = data_types.Fuzzer.query( | ||
| data_types.Fuzzer.name == testcase.fuzzer_name).get() | ||
| except Exception: |
There was a problem hiding this comment.
Do you know when an Exception is thrown here? We'd want to log it depending on what happened.
Just to confirm, this isn't an exception because the query returned no results, right?
| @@ -0,0 +1,59 @@ | |||
| # Copyright 2026 Google LLC | |||
There was a problem hiding this comment.
I think you can just revert this file and keep it in a draft PR for testing or manual backfills. We don't expect to run this more than once
| fuzzer.sample_testcase = None | ||
| fuzzer.console_output = None | ||
| fuzzer.external_contribution = bool(external_contribution) | ||
| fuzzer.primary_owner = primary_owner |
There was a problem hiding this comment.
is there a test you can update alongside this change?
| <paper-input | ||
| label="Primary owner (email)" | ||
| value="{{fuzzer.primary_owner}}" | ||
| title="Primary owner for VRP reasons."> |
There was a problem hiding this comment.
| title="Primary owner for VRP reasons."> | |
| title="Primary owner for VRP rewards."> |
| # Intercept new_issue so we can capture the saved issue object. | ||
| original_new_issue = issue_tracker.new_issue | ||
|
|
||
| def mock_new_issue(): |
There was a problem hiding this comment.
I'd prefer to mock as little as possible and keep the mocks to the external calls, e.g. the _execute request in test_filed_issue_google_issue_tracker
|
|
||
| issue.reporter = user_email | ||
| if fuzzer and getattr(fuzzer, 'primary_owner', None): | ||
| issue.reporter = fuzzer.primary_owner |
There was a problem hiding this comment.
We sometimes use the reporter to determine whether clusterfuzz filed the bug. Is there another place where we are setting metadata of some kind, e.g. a label/hotlist that stays on the bug so that we can continue to track clusterfuzz filed bugs?
Changes:
primary_ownerfield toFuzzermodel indata_types.py.edit-form.html.fuzzers.pyhandler to save theprimary_ownerfield.file_issueinissue_filer.pyto usefuzzer.primary_owneras the reporter if available.issue_filer_test.pyto verify the new behavior.Feature tests
Show “owner” textbox
Preconditions
devinstanceSteps
Evidence
Step 3

Show owner entry on Pantheon Audit Logs
Preconditions
Steps
new_fuzzer_with_owner_jabglibfuzzer_chrome_asanNoneNoneTruenew_fuzzer_with_owner_jabgEvidence
Step 6

Step 10
