From: Brian Bouterse bmbouter@gmail.com
--- HACKING | 17 +++-- bugzilla/rhbugzilla.py | 164 ++++++++++++++++++++++++++++++++++++++----------- tests/rw_functional.py | 110 ++++++++++++++++++++++++++------- 3 files changed, 223 insertions(+), 68 deletions(-)
diff --git a/HACKING b/HACKING index f597a97..c2015c0 100644 --- a/HACKING +++ b/HACKING @@ -26,17 +26,20 @@ Once you have already activated an environment, you can use the following. # Basic unit test suite python setup.py test
-# Functional tests +# Read-Only Functional tests There are more comprehensive tests that are disabled by default. Readonly functional tests that run against several public bugzilla instances. No login account is required:
python setup.py test --ro-functional
-And read/write functional tests. These currently run against the test -bugzilla instance at partner-bugzilla.redhat.com, and requires a valid -login there: +# Read/Write Functional Tests.
+Before running rw-functional tests, make sure you have logged into bugzilla +using. These currently run against the test bugzilla instance at +partner-bugzilla.redhat.com, and requires a valid login there: + + bugzilla-cli --bugzilla=partner-bugzilla.redhat.com --user=$USER login python setup.py test --rw-functional
# Testing across python versions @@ -46,12 +49,6 @@ To test all supported python versions, run tox using any of the following. tox -- --ro-functional tox -- --rw-functional
-Note: Before running rw-functional tests, make sure you have logged into -bugzilla using: - python bugzilla-cli \ - --bugzilla=partner-bugzilla.redhat.com \ - --user=$USER login -
3. pylint and pep8 ------------------ diff --git a/bugzilla/rhbugzilla.py b/bugzilla/rhbugzilla.py index 0903ff2..7300296 100644 --- a/bugzilla/rhbugzilla.py +++ b/bugzilla/rhbugzilla.py @@ -133,7 +133,10 @@ class RHBugzilla(_parent):
return vals
- def add_external_tracker(self, bug_ids, type_desc, external_id): + def add_external_tracker(self, bug_ids, ext_bz_bug_id, ext_type_id=None, + ext_type_description=None, ext_type_url=None, + ext_status=None, ext_description=None, + ext_priority=None): """ Wrapper method to allow adding of external tracking bugs using the ExternalBugs::WebService::add_external_bug method. @@ -141,23 +144,87 @@ class RHBugzilla(_parent): This is documented at https://bugzilla.redhat.com/docs/en/html/api/extensions/ExternalBugs/lib/Web...
- bug_ids: A single bug id or list if bug ids to add the tracker to. - type_desc: The external tracker description as used by Bugzilla. This - value maps to the ext_type_description parameter of the XMLRPC - method. - external_id: The id as used by the external tracker. This value maps to - the ext_bz_bug_id parameter of the XMLRPC method. + bug_ids: A single bug id or list of bug ids to have external trackers + added. + ext_bz_bug_id: The external bug id (ie: the bug number in the + external tracker). + ext_type_id: The external tracker id as used by Bugzilla. + ext_type_description: The external tracker description as used by + Bugzilla. + ext_type_url: The external tracker url as used by Bugzilla. + ext_status: The status of the external bug. + ext_description: The description of the external bug. + ext_priority: The priority of the external bug. """ - kwargs = { + param_dict = {'ext_bz_bug_id': ext_bz_bug_id} + if ext_type_id is not None: + param_dict['ext_type_id'] = ext_type_id + if ext_type_description is not None: + param_dict['ext_type_description'] = ext_type_description + if ext_type_url is not None: + param_dict['ext_type_url'] = ext_type_url + if ext_status is not None: + param_dict['ext_status'] = ext_status + if ext_description is not None: + param_dict['ext_description'] = ext_description + if ext_priority is not None: + param_dict['ext_priority'] = ext_priority + params = { 'bug_ids': self._listify(bug_ids), - 'external_bugs': [{ - 'ext_type_description': type_desc, - 'ext_bz_bug_id': external_id, - }], + 'external_bugs': [param_dict], } - return self._proxy.ExternalBugs.add_external_bug(kwargs) + return self._proxy.ExternalBugs.add_external_bug(params)
- def remove_external_tracker(self, bug_ids, type_desc, external_ids): + def update_external_tracker(self, ids=None, ext_type_id=None, + ext_type_description=None, ext_type_url=None, + ext_bz_bug_id=None, bug_ids=None, + ext_status=None, ext_description=None, + ext_priority=None): + """ + Wrapper method to allow adding of external tracking bugs using the + ExternalBugs::WebService::update_external_bug method. + + This is documented at + https://bugzilla.redhat.com/docs/en/html/api/extensions/ExternalBugs/lib/Web... + + ids: A single external tracker bug id or list of external tracker bug + ids. + ext_type_id: The external tracker id as used by Bugzilla. + ext_type_description: The external tracker description as used by + Bugzilla. + ext_type_url: The external tracker url as used by Bugzilla. + ext_bz_bug_id: A single external bug id or list of external bug ids + (ie: the bug number in the external tracker). + bug_ids: A single bug id or list of bug ids to have external tracker + info updated. + ext_status: The status of the external bug. + ext_description: The description of the external bug. + ext_priority: The priority of the external bug. + """ + params = {} + if ids is not None: + params['ids'] = self._listify(ids) + if ext_type_id is not None: + params['ext_type_id'] = ext_type_id + if ext_type_description is not None: + params['ext_type_description'] = ext_type_description + if ext_type_url is not None: + params['ext_type_url'] = ext_type_url + if ext_bz_bug_id is not None: + params['ext_bz_bug_id'] = self._listify(ext_bz_bug_id) + if bug_ids is not None: + params['bug_ids'] = self._listify(bug_ids) + if ext_status is not None: + params['ext_status'] = ext_status + if ext_description is not None: + params['ext_description'] = ext_description + if ext_priority is not None: + params['ext_priority'] = ext_priority + return self._proxy.ExternalBugs.update_external_bug(params) + + def remove_external_tracker(self, ids=None, ext_type_id=None, + ext_type_description=None, ext_type_url=None, + ext_bz_bug_id=None, bug_ids=None): """ Wrapper method to allow removal of external tracking bugs using the ExternalBugs::WebService::remove_external_bug method. @@ -165,20 +232,31 @@ class RHBugzilla(_parent): This is documented at https://bugzilla.redhat.com/docs/en/html/api/extensions/ExternalBugs/lib/Web...
- bug_ids: A single bug id or list if bug ids to remove the tracker from. - type_desc: The external tracker description as used by Bugzilla. This - value maps to the ext_type_description parameter of the XMLRPC - method. - external_ids: The id or list of ids as used by the external tracker. - This value maps to the ext_bz_bug_id parameter of the XMLRPC - method. + ids: A single external tracker bug id or list of external tracker bug + ids. + ext_type_id: The external tracker id as used by Bugzilla. + ext_type_description: The external tracker description as used by + Bugzilla. + ext_type_url: The external tracker url as used by Bugzilla. + ext_bz_bug_id: A single external bug id or list of external bug ids + (ie: the bug number in the external tracker). + bug_ids: A single bug id or list of bug ids to have external tracker + info updated. """ - kwargs = { - 'bug_ids': self._listify(bug_ids), - 'ext_type_description': type_desc, - 'ext_bz_bug_id': self._listify(external_ids), - } - return self._proxy.ExternalBugs.remove_external_bug(kwargs) + params = {} + if ids is not None: + params['ids'] = self._listify(ids) + if ext_type_id is not None: + params['ext_type_id'] = ext_type_id + if ext_type_description is not None: + params['ext_type_description'] = ext_type_description + if ext_type_url is not None: + params['ext_type_url'] = ext_type_url + if ext_bz_bug_id is not None: + params['ext_bz_bug_id'] = self._listify(ext_bz_bug_id) + if bug_ids is not None: + params['bug_ids'] = self._listify(bug_ids) + return self._proxy.ExternalBugs.remove_external_bug(params)
################# @@ -285,29 +363,41 @@ class RHBugzilla(_parent): bug['groups'] = tmp
def build_external_tracker_boolean_query( - self, type_desc=None, external_id=None): + self, ext_type_description=None, ext_type_url=None, + ext_bz_bug_id=None, ext_status=None): """ Helper method to build a boolean query to find bugs that contain an - external tracker with the 'type_desc' and 'external_id' combination. + external tracker.
All parameters that are None will be ignored when building the query.
- type_desc: The external tracker description as used by Bugzilla. This - value maps to the external_bugzilla.description field. - external_ids: The id as used by the external tracker. This value maps - to the ext_bz_bug_map.ext_bz_bug_id field. + ext_type_description: The external tracker description as used by + Bugzilla. + ext_type_url: The external tracker url as used by Bugzilla. + ext_bz_bug_id: The external bug id (ie: the bug number in the + external tracker). + ext_status: The status of the external bug. """ parts = []
- if type_desc is not None: + if ext_type_description is not None: + parts.append( + 'external_bugzilla.description-equals-{0:s}'.format( + ext_type_description)) + + if ext_type_url is not None: parts.append( - 'external_bugzilla.description-equals-{0:s}'.format(type_desc)) + 'external_bugzilla.url-equals-{0:s}'.format(ext_type_url))
- if external_id is not None: - id_str = str(external_id) + if ext_bz_bug_id is not None: + id_str = str(ext_bz_bug_id) parts.append( 'ext_bz_bug_map.ext_bz_bug_id-equals-{0:s}'.format(id_str))
+ if ext_status is not None: + parts.append( + 'ext_bz_bug_map.ext_status-equals-{0:s}'.format(ext_status)) + return ' & '.join(parts)
def build_query(self, **kwargs): diff --git a/tests/rw_functional.py b/tests/rw_functional.py index fd89613..480835a 100644 --- a/tests/rw_functional.py +++ b/tests/rw_functional.py @@ -773,35 +773,103 @@ class RHPartnerTest(BaseTest): bug.refresh() self.assertEqual(bug.sub_components, {})
- def _test14ExternalTrackersQuery(self, bz, ext_type_desc, ext_bug_id): - boolean_query = bz.build_external_tracker_boolean_query( - ext_type_desc, ext_bug_id) - query = bz.build_query( - boolean_query=boolean_query, include_fields=['id']) - return [bug.bug_id for bug in bz.query(query)] + def _deleteAllExistingExternalTrackers(self, bugid): + bz = self.bzclass(url=self.url, cookiefile=cf, tokenfile=tf) + ids = [bug['id'] for bug in bz.getbug(bugid).external_bugs] + if ids != []: + bz.remove_external_tracker(ids=ids)
def test14ExternalTrackersQuery(self): bz = self.bzclass(url=self.url, cookiefile=cf, tokenfile=tf) - ext_type_desc = "FreeDesktop.org" - ext_bug_id = 64714 + bugid = 461686 + ext_bug_id = 1234659
- # Closed RH Bugzilla bug with external tracker - bugid = 973374 - assert bugid in \ - self._test14ExternalTrackersQuery(bz, ext_type_desc, ext_bug_id) + # Delete any existing external trackers to get to a known state + self._deleteAllExistingExternalTrackers(bugid) + + # test adding tracker + kwargs = { + 'ext_type_url': 'http://bugzilla.mozilla.org', + 'ext_type_description': 'Mozilla Foundation', + 'ext_status': 'Original Status', + }
- def test14ExternalTrackersAddRemove(self): + # Add a tracker that we can query for + bz.add_external_tracker(bugid, ext_bug_id, **kwargs) + + kwargs['ext_bz_bug_id'] = ext_bug_id + + boolean_query = bz.build_external_tracker_boolean_query( + ext_bz_bug_id=ext_bug_id) + query_results = bz.query(bz.build_query(boolean_query=boolean_query)) + if len(query_results) != 1: + raise AssertionError( + 'external tracker query by bug id should return 1 result.') + for key, value in kwargs.iteritems(): + assert kwargs[key] == value + + boolean_query = bz.build_external_tracker_boolean_query( + ext_type_description=kwargs['ext_type_description']) + query_results = bz.query(bz.build_query(boolean_query=boolean_query)) + assert bugid in [qr.id for qr in query_results] + + boolean_query = bz.build_external_tracker_boolean_query( + ext_status=kwargs['ext_status']) + query_results = bz.query(bz.build_query(boolean_query=boolean_query)) + if len(query_results) != 1: + raise AssertionError( + 'external tracker query by status should return 1 result.') + for key, value in kwargs.iteritems(): + assert kwargs[key] == value + + boolean_query = bz.build_external_tracker_boolean_query( + ext_type_url=kwargs['ext_type_url']) + query_results = bz.query(bz.build_query(boolean_query=boolean_query)) + assert bugid in [qr.id for qr in query_results] + + def test14ExternalTrackersAddUpdateRemoveQuery(self): bz = self.bzclass(url=self.url, cookiefile=cf, tokenfile=tf) - ext_type_desc = "Mozilla Foundation" - ext_bug_id = 380489 bugid = 461686 + ext_bug_id = 380489 + + # Delete any existing external trackers to get to a known state + self._deleteAllExistingExternalTrackers(bugid)
# test adding tracker - bz.add_external_tracker(bugid, ext_type_desc, ext_bug_id) - assert bugid in \ - self._test14ExternalTrackersQuery(bz, ext_type_desc, ext_bug_id) + kwargs = { + 'ext_type_id': 6, + 'ext_type_url': 'http://bugzilla.mozilla.org', + 'ext_type_description': 'Mozilla Foundation', + 'ext_status': 'Original Status', + 'ext_description': 'the description', + 'ext_priority': 'the priority' + } + bz.add_external_tracker(bugid, ext_bug_id, **kwargs) + added_bug = bz.getbug(bugid).external_bugs[0] + assert added_bug['type']['id'] == kwargs['ext_type_id'] + assert added_bug['type']['url'] == kwargs['ext_type_url'] + assert added_bug['type']['description'] == kwargs['ext_type_description'] + assert added_bug['ext_status'] == kwargs['ext_status'] + assert added_bug['ext_description'] == kwargs['ext_description'] + assert added_bug['ext_priority'] == kwargs['ext_priority'] + + # test updating status, description, and priority by id + kwargs = { + 'ids': bz.getbug(bugid).external_bugs[0]['id'], + 'ext_status': 'New Status', + 'ext_description': 'New Description', + 'ext_priority': 'New Priority' + } + bz.update_external_tracker(**kwargs) + updated_bug = bz.getbug(bugid).external_bugs[0] + assert updated_bug['ext_bz_bug_id'] == str(ext_bug_id) + assert updated_bug['ext_status'] == kwargs['ext_status'] + assert updated_bug['ext_description'] == kwargs['ext_description'] + assert updated_bug['ext_priority'] == kwargs['ext_priority']
# test removing tracker - bz.remove_external_tracker(bugid, ext_type_desc, ext_bug_id) - assert bugid not in \ - self._test14ExternalTrackersQuery(bz, ext_type_desc, ext_bug_id) + ids = [bug['id'] for bug in bz.getbug(bugid).external_bugs] + assert len(ids) == 1 + bz.remove_external_tracker(ids=ids) + ids = [bug['id'] for bug in bz.getbug(bugid).external_bugs] + assert len(ids) == 0