Rev 5136: Put several tests behind a Feature object. in http://bazaar.launchpad.net/~jameinel/bzr/2.2-is-up-to-date
John Arbash Meinel
john at arbash-meinel.com
Wed Jul 13 12:22:59 UTC 2011
At http://bazaar.launchpad.net/~jameinel/bzr/2.2-is-up-to-date
------------------------------------------------------------
revno: 5136
revision-id: john at arbash-meinel.com-20110713122227-0nb381xfj9bi965c
parent: john at arbash-meinel.com-20110713121021-aeuvnkjp5c627lxd
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: 2.2-is-up-to-date
timestamp: Wed 2011-07-13 14:22:27 +0200
message:
Put several tests behind a Feature object.
Add some edge-case tests that even when we don't get the
response we are expecting, we don't explode.
-------------- next part --------------
=== modified file 'bzrlib/plugins/launchpad/lp_api_lite.py'
--- a/bzrlib/plugins/launchpad/lp_api_lite.py 2011-07-13 12:10:21 +0000
+++ b/bzrlib/plugins/launchpad/lp_api_lite.py 2011-07-13 12:22:27 +0000
@@ -129,7 +129,12 @@
"""Parse the json response from Launchpad into objects."""
if json is None:
return None
- return json.loads(json_info)
+ try:
+ return json.loads(json_info)
+ except Exception:
+ trace.mutter('Failed to parse json info: %r' % (json_info,))
+ trace.log_exception_quietly()
+ return None
def get_latest_version(self):
"""Get the latest published version for the given package."""
@@ -137,10 +142,16 @@
if json_info is None:
return None
info = self._parse_json_info(json_info)
- entries = info['entries']
- if len(entries) == 0:
- return None
- return entries[0]['source_package_version']
+ if info is None:
+ return None
+ try:
+ entries = info['entries']
+ if len(entries) == 0:
+ return None
+ return entries[0]['source_package_version']
+ except KeyError:
+ trace.log_exception_quietly()
+ return None
def get_latest_publication(archive, series, project):
@@ -153,70 +164,5 @@
:return: A version string indicating the most-recent version published in
Launchpad. Might return None if there is an error.
"""
- if json is None:
- return None
- archive_url = '%s/%s/+archive/primary?' % (LatestPublication.LP_API_ROOT, archive)
- pocket = None
- # TODO: If series is None, we probably need to hard-code it. I don't have
- # proof yet, but otherwise we just get the most-recent version in any
- # series, rather than getting the one for eg 'oneiric'. The problem I
- # envision is that natty-proposed might have a newer version than
- # 'oneiric'. Is this a useful distinction in practice?
- if series is not None and '-' in series:
- # The lp: URL 'lp:ubuntu/natty-proposed/...' is translated into series
- # 'natty' pocket 'proposed'
- try:
- series, pocket = series.split('-')
- except ValueError, e:
- trace.mutter('failed to find series,pocket from %s' % (series,))
- return None
- # pocket must be in 'Title' case, so Proposed, not 'proposed'.
- pocket = pocket.title()
- params = {'ws.op': 'getPublishedSources',
- 'exact_match': 'true',
- # If we need to use "" shouldn't we quote the project somehow?
- 'source_name': '"%s"' % (project,),
- 'status': 'Published',
- # We only need the latest one, the results seem to be properly
- # most-recent-debian-version sorted
- 'ws.size': '1',
- }
- if series is not None:
- params['distro_series'] = '/%s/%s' % (archive, series)
- if pocket is not None:
- params['pocket'] = pocket
- query_url = archive_url + urllib.urlencode(params)
- try:
- req = urllib2.Request(query_url)
- response = urllib2.urlopen(req)
- json_txt = response.read()
- except urllib2.HTTPError, e:
- trace.mutter('failed to place query to %r' % (query_url,))
- trace.log_exception_quietly()
- return None
- try:
- o = json.loads(json_txt)
- except Exception:
- # simplejson raises simplejson.decoder.JSONDecodeError,
- # but json raises ValueError, so we just catch a generic error and move
- # on
- trace.log_exception_quietly()
- return None
- try:
- for e in o['entries']:
- this_name = e['source_package_name']
- this_ver = e['source_package_version']
- # this_comp seems to always be 'main', are we supposed to do
- # something with it?
- # this_comp = e['component_name']
- # pocket = e['pocket'].lower()
- # series = e['distro_series_link'].split('/')[-1]
- # if pocket != 'release':
- # series += '-' + pocket
- return this_ver
- except KeyError:
- # Some expected attribute was missing
- trace.log_exception_quietly()
- return None
- trace.mutter('No versions found for: %r', query_url)
- return None
+ lp = LatestPublication(archive, series, project)
+ return lp.get_latest_version()
=== modified file 'bzrlib/plugins/launchpad/test_lp_api_lite.py'
--- a/bzrlib/plugins/launchpad/test_lp_api_lite.py 2011-07-13 12:10:21 +0000
+++ b/bzrlib/plugins/launchpad/test_lp_api_lite.py 2011-07-13 12:22:27 +0000
@@ -22,6 +22,16 @@
from bzrlib import tests
from bzrlib.plugins.launchpad import lp_api_lite
+class _JSONParserFeature(tests.Feature):
+
+ def _probe(self):
+ return lp_api_lite.json is not None
+
+ def feature_name(self):
+ return 'simplejson or json'
+
+JSONParserFeature = _JSONParserFeature()
+
_example_response = r"""
{
"total_size": 2,
@@ -185,8 +195,7 @@
self.assertIs(None, latest_pub._parse_json_info(_example_response))
def test__parse_json_example_response(self):
- if lp_api_lite.json is None:
- raise tests.UnavailableFeature('json or simplejson module')
+ self.requireFeature(JSONParserFeature)
latest_pub = self.make_latest_publication()
content = latest_pub._parse_json_info(_example_response)
self.assertIsNot(None, content)
@@ -197,6 +206,11 @@
self.assertEqual('bzr', entry['source_package_name'])
self.assertEqual("2.1.4-0ubuntu1", entry["source_package_version"])
+ def test__parse_json_not_json(self):
+ self.requireFeature(JSONParserFeature)
+ latest_pub = self.make_latest_publication()
+ self.assertIs(None, latest_pub._parse_json_info('Not_valid_json'))
+
def test_get_latest_version_no_response(self):
latest_pub = self.make_latest_publication()
latest_pub._get_lp_info = lambda: None
@@ -207,16 +221,40 @@
latest_pub = self.make_latest_publication()
self.assertEqual(None, latest_pub.get_latest_version())
+ def test_get_latest_version_invalid_json(self):
+ self.requireFeature(JSONParserFeature)
+ latest_pub = self.make_latest_publication()
+ latest_pub._get_lp_info = lambda: "not json"
+ self.assertEqual(None, latest_pub.get_latest_version())
+
def test_get_latest_version_no_versions(self):
+ self.requireFeature(JSONParserFeature)
latest_pub = self.make_latest_publication()
latest_pub._get_lp_info = lambda: _no_versions_response
self.assertEqual(None, latest_pub.get_latest_version())
+ def test_get_latest_version_missing_entries(self):
+ # Launchpad's no-entries response does have an empty entries value.
+ # However, lets test that we handle other failures without tracebacks
+ self.requireFeature(JSONParserFeature)
+ latest_pub = self.make_latest_publication()
+ latest_pub._get_lp_info = lambda: '{}'
+ self.assertEqual(None, latest_pub.get_latest_version())
+
+ def test_get_latest_version_invalid_entries(self):
+ # Make sure we sanely handle a json response we don't understand
+ self.requireFeature(JSONParserFeature)
+ latest_pub = self.make_latest_publication()
+ latest_pub._get_lp_info = lambda: '{"entries": {"a": 1}}'
+ self.assertEqual(None, latest_pub.get_latest_version())
+
def test_get_latest_version_example(self):
+ self.requireFeature(JSONParserFeature)
latest_pub = self.make_latest_publication()
latest_pub._get_lp_info = lambda: _example_response
self.assertEqual("2.1.4-0ubuntu1", latest_pub.get_latest_version())
def DONT_test_get_latest_version_from_launchpad(self):
+ self.requireFeature(JSONParserFeature)
latest_pub = self.make_latest_publication()
self.assertIsNot(None, latest_pub.get_latest_version())
More information about the bazaar-commits
mailing list