| Index: tools/auto_bisect/query_crbug.py
|
| diff --git a/tools/auto_bisect/query_crbug.py b/tools/auto_bisect/query_crbug.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b8f4fcbb5b1bb6ff3e8b82540802b783f73d337d
|
| --- /dev/null
|
| +++ b/tools/auto_bisect/query_crbug.py
|
| @@ -0,0 +1,78 @@
|
| +# 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(issue_id, url_template=SINGLE_ISSUE_URL):
|
| + """Queries the tracker for a specific issue. Returns a dict.
|
| +
|
| + This uses the deprecated Issue Tracker API to fetch a JSON representation of
|
| + the issue details.
|
| +
|
| + Args:
|
| + issue_id: An int or string representing the issue id.
|
| + url_template: URL to query the tracker with '%s' instead of the bug id.
|
| +
|
| + Returns:
|
| + A dictionary as parsed by the JSON library from the tracker response.
|
| +
|
| + Raises:
|
| + urllib2.HTTPError when appropriate.
|
| + """
|
| + assert str(issue_id).isdigit()
|
| + response = urllib2.urlopen(url_template % issue_id).read()
|
| + return json.loads(response)
|
| +
|
| +
|
| +def GetIssueState(issue_id):
|
| + """Returns either 'closed' or 'open' for the given bug ID.
|
| +
|
| + Args:
|
| + issue_id: string or string-castable object containing a numeric bug ID.
|
| + Returns:
|
| + 'open' or 'closed' depending on the state of the bug.
|
| + Raises:
|
| + IssueTrackerQueryException if the data cannot be retrieved or parsed.
|
| + """
|
| + try:
|
| + query_response = QuerySingleIssue(issue_id)
|
| + # We assume the query returns a single result hence the [0]
|
| + issue_detail = query_response['feed']['entry'][0]
|
| + state = issue_detail['issues$state']['$t']
|
| + return state
|
| + except urllib2.URLError:
|
| + raise IssueTrackerQueryException(
|
| + 'Could not fetch the details form the issue tracker.')
|
| + 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(issue_id):
|
| + """Checks if a given issue is closed. Returns False when in doubt."""
|
| + try:
|
| + return GetIssueState(issue_id) == 'closed'
|
| + except IssueTrackerQueryException:
|
| + # When we can't be sure we return false
|
| + return False
|
|
|