[python-bugzilla] [PATCH] Add limited support for ExternalBugs extension in RHBZ

abn at redhat.com abn at redhat.com
Mon Nov 10 05:46:40 UTC 2014


From: Arun Babu Neelicattu <abn at redhat.com>

- RHBZ instances now support adding/removing external trackers as
  documented at https://bugzilla.redhat.com/docs/en/html/api/extensions/ExternalBugs/lib/WebService.html
- Limitations: current implementation uses only ext_type_description and
  ext_bz_bug_id and does not support any other external tracker fields
---
 bugzilla/rhbugzilla.py | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++
 tests/rw_functional.py | 33 +++++++++++++++++++++++
 2 files changed, 106 insertions(+)

diff --git a/bugzilla/rhbugzilla.py b/bugzilla/rhbugzilla.py
index dd9f76a..e9918de 100644
--- a/bugzilla/rhbugzilla.py
+++ b/bugzilla/rhbugzilla.py
@@ -116,6 +116,53 @@ class RHBugzilla(_parent):
 
         return vals
 
+    def add_external_tracker(self, bug_ids, type_desc, external_id):
+        """
+        Wrapper method to allow adding of external tracking bugs using the
+        ExternalBugs::WebService::add_external_bug method.
+
+        This is documented at
+        https://bugzilla.redhat.com/docs/en/html/api/extensions/ExternalBugs/lib/WebService.html#add_external_bug
+
+        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.
+        """
+        kwargs = {
+            'bug_ids': self._listify(bug_ids),
+            'external_bugs': [{
+                'ext_type_description': type_desc,
+                'ext_bz_bug_id': external_id,
+            }],
+        }
+        return self._proxy.ExternalBugs.add_external_bug(kwargs)
+
+    def remove_external_tracker(self, bug_ids, type_desc, external_ids):
+        """
+        Wrapper method to allow removal of external tracking bugs using the
+        ExternalBugs::WebService::remove_external_bug method.
+
+        This is documented at
+        https://bugzilla.redhat.com/docs/en/html/api/extensions/ExternalBugs/lib/WebService.html#remove_external_bug
+
+        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.
+        """
+        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)
+
 
     #################
     # Query methods #
@@ -220,6 +267,32 @@ class RHBugzilla(_parent):
                 tmp.append(t)
             bug['groups'] = tmp
 
+    def build_external_tracker_boolean_query(
+            self, type_desc=None, external_id=None):
+        """
+        Helper method to build a boolean query to find bugs that contain an
+        external tracker with the 'type_desc' and 'external_id' combination.
+
+        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.
+        """
+        parts = []
+
+        if type_desc is not None:
+            parts.append(
+                'external_bugzilla.description-equals-{0:s}'.format(type_desc))
+
+        if external_id is not None:
+            id_str = str(external_id)
+            parts.append(
+                'ext_bz_bug_map.ext_bz_bug_id-equals-{0:s}'.format(id_str))
+
+        return ' & '.join(parts)
+
     def build_query(self, **kwargs):
         query = {}
 
diff --git a/tests/rw_functional.py b/tests/rw_functional.py
index ed55794..98dd89b 100644
--- a/tests/rw_functional.py
+++ b/tests/rw_functional.py
@@ -752,3 +752,36 @@ class RHPartnerTest(BaseTest):
         bz.update_bugs(bug.id, bz.build_update(sub_component={}))
         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 test14ExternalTrackersQuery(self):
+        bz = self.bzclass(url=self.url, cookiefile=cf, tokenfile=tf)
+        ext_type_desc = "Mozilla Foundation"
+        ext_bug_id = 913904
+
+        # Closed RH Bugzilla bug with external tracker
+        bugid = 1007135
+        assert bugid in \
+            self._test14ExternalTrackersQuery(bz, ext_type_desc, ext_bug_id)
+
+    def test14ExternalTrackersAddRemove(self):
+        bz = self.bzclass(url=self.url, cookiefile=cf, tokenfile=tf)
+        ext_type_desc = "Mozilla Foundation"
+        ext_bug_id = 380489
+        bugid = 461686
+
+        # 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)
+
+        # 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)
-- 
1.9.3



More information about the python-bugzilla mailing list