Chromium Code Reviews| Index: tools/auto_bisect/crbug_query.py |
| diff --git a/tools/auto_bisect/crbug_query.py b/tools/auto_bisect/crbug_query.py |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..becd77092038a03298969cb17c290a9288038723 |
| --- /dev/null |
| +++ b/tools/auto_bisect/crbug_query.py |
| @@ -0,0 +1,69 @@ |
| +# Copyright 2014 The Chromium Authors. All rights reserved. |
| +# Use of this source code is governed by a BSD-style license that can be |
| +# found in the LICENSE file. |
| + |
| +"""Utility functions to query the chromium issue tracker. |
| + |
| +Note that documentation for the Issue Tracker API says it's DEPRECATED, however |
| +it seems to be in use in other places like the performance dashboard. Also, |
| +this module attempts to handle most exceptions thrown by querying the tracker |
| +so that when and if this api is turned off no impact is caused to the bisection |
| +process.""" |
| + |
| +import json |
| +import urllib2 |
| + |
| +SINGLE_ISSUE_URL = ('https://code.google.com/feeds/issues/p/chromium/issues' |
| + '/full?id=%s&alt=json') |
| + |
| + |
| +class IssueTrackerQueryException(Exception): |
| + pass |
| + |
| + |
| +def querySingleIssue(issueId, urlTemplate=SINGLE_ISSUE_URL): |
|
qyearsley
2014/11/01 16:56:56
Chromium style:
- Function and method names have
RobertoCN
2014/11/02 07:48:34
Done.
|
| + """Queries the tracker for a specific issue. Returns a dict. |
| + |
| + This uses the deprecated Issue Tracker API to fetch a json representation of |
|
qyearsley
2014/11/01 16:56:56
I personally like capitalizing abbreviations like
RobertoCN
2014/11/02 07:48:35
Done.
|
| + the issue details. |
| + |
| + Args: |
| + issueId: An int or string representing the issue id. |
| + urlTemplate (optional): to override the url to request from. |
|
qyearsley
2014/11/01 16:56:56
No need to say (optional) here. You could say "The
RobertoCN
2014/11/02 07:48:34
Done.
|
| + Returns: |
|
qyearsley
2014/11/01 16:56:56
Style: blank line between Args and Returns section
RobertoCN
2014/11/02 07:48:34
Done.
|
| + A dictionary as parsed by the json library from the tracker response. |
|
qyearsley
2014/11/01 16:56:57
After the Returns section, you could also put a "R
RobertoCN
2014/11/02 07:48:34
Done.
|
| + """ |
| + issueId = str(issueId) |
|
qyearsley
2014/11/01 16:56:57
It will also be implicitly converted to a string w
RobertoCN
2014/11/02 07:48:34
Done.
|
| + assert issueId.isdigit() |
|
qyearsley
2014/11/01 16:56:56
Cool, I didn't know that isdigit would check all t
RobertoCN
2014/11/02 07:48:34
They are slightly different, current implementatio
|
| + response = urllib2.urlopen(urlTemplate % issueId).read() |
| + return json.loads(response) |
| + |
| + |
| +def getIssueState(issueId): |
|
qyearsley
2014/11/01 16:56:56
What are the possible values of state? It's just "
RobertoCN
2014/11/02 07:48:34
Done.
|
| + try: |
| + queryResponse = querySingleIssue(issueId) |
| + # We assume the query returns a single result hence the [0] |
| + issueDetail = queryResponse['feed']['entry'][0] |
| + state = issueDetail['issues$state']['$t'] |
| + return state |
| + except urllib2.URLError: |
| + raise IssueTrackerQueryException( |
| + 'Could not fetch the details form the issue tracker.' |
| + ) |
|
qyearsley
2014/11/01 16:56:56
Style: closing parenthesis goes on the same line w
RobertoCN
2014/11/02 07:48:34
Done.
|
| + except ValueError: |
| + raise IssueTrackerQueryException( |
| + 'Could not parse the issue tracker\'s response as a json doc.' |
| + ) |
| + except KeyError: |
| + raise IssueTrackerQueryException( |
| + 'The data from the issue tracker is not in the expected format.' |
| + ) |
| + |
| + |
| +def checkIssueClosed(issueId): |
| + """Checks if a given issue is closed. Returns False when in doubt.""" |
| + try: |
| + return getIssueState(issueId) == u'closed' |
|
qyearsley
2014/11/01 16:56:56
No need to explicitly use a unicode string, u"clos
RobertoCN
2014/11/02 07:48:34
You are right. I just wondered if I should made th
|
| + except IssueTrackerQueryException: |
| + # When we can't be sure we return false |
| + return False |