Skip to content

Commit 10d245f

Browse files
bmboutercrobinso
authored andcommitted
Expands ExternalTracker field support
(crobinso: Fix a long line to make pylint happy) Message-Id: <[email protected]>
1 parent 9fc6739 commit 10d245f

3 files changed

Lines changed: 224 additions & 68 deletions

File tree

HACKING

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,20 @@ Once you have already activated an environment, you can use the following.
2626
# Basic unit test suite
2727
python setup.py test
2828

29-
# Functional tests
29+
# Read-Only Functional tests
3030
There are more comprehensive tests that are disabled by default. Readonly
3131
functional tests that run against several public bugzilla instances. No
3232
login account is required:
3333

3434
python setup.py test --ro-functional
3535

36-
And read/write functional tests. These currently run against the test
37-
bugzilla instance at partner-bugzilla.redhat.com, and requires a valid
38-
login there:
36+
# Read/Write Functional Tests.
3937

38+
Before running rw-functional tests, make sure you have logged into bugzilla
39+
using. These currently run against the test bugzilla instance at
40+
partner-bugzilla.redhat.com, and requires a valid login there:
41+
42+
bugzilla-cli --bugzilla=partner-bugzilla.redhat.com --user=$USER login
4043
python setup.py test --rw-functional
4144

4245
# Testing across python versions
@@ -46,12 +49,6 @@ To test all supported python versions, run tox using any of the following.
4649
tox -- --ro-functional
4750
tox -- --rw-functional
4851

49-
Note: Before running rw-functional tests, make sure you have logged into
50-
bugzilla using:
51-
python bugzilla-cli \
52-
--bugzilla=partner-bugzilla.redhat.com \
53-
--user=$USER login
54-
5552

5653
3. pylint and pep8
5754
------------------

bugzilla/rhbugzilla.py

Lines changed: 127 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -133,52 +133,130 @@ def get_alias():
133133

134134
return vals
135135

136-
def add_external_tracker(self, bug_ids, type_desc, external_id):
136+
def add_external_tracker(self, bug_ids, ext_bz_bug_id, ext_type_id=None,
137+
ext_type_description=None, ext_type_url=None,
138+
ext_status=None, ext_description=None,
139+
ext_priority=None):
137140
"""
138141
Wrapper method to allow adding of external tracking bugs using the
139142
ExternalBugs::WebService::add_external_bug method.
140143
141144
This is documented at
142145
https://bugzilla.redhat.com/docs/en/html/api/extensions/ExternalBugs/lib/WebService.html#add_external_bug
143146
144-
bug_ids: A single bug id or list if bug ids to add the tracker to.
145-
type_desc: The external tracker description as used by Bugzilla. This
146-
value maps to the ext_type_description parameter of the XMLRPC
147-
method.
148-
external_id: The id as used by the external tracker. This value maps to
149-
the ext_bz_bug_id parameter of the XMLRPC method.
147+
bug_ids: A single bug id or list of bug ids to have external trackers
148+
added.
149+
ext_bz_bug_id: The external bug id (ie: the bug number in the
150+
external tracker).
151+
ext_type_id: The external tracker id as used by Bugzilla.
152+
ext_type_description: The external tracker description as used by
153+
Bugzilla.
154+
ext_type_url: The external tracker url as used by Bugzilla.
155+
ext_status: The status of the external bug.
156+
ext_description: The description of the external bug.
157+
ext_priority: The priority of the external bug.
150158
"""
151-
kwargs = {
159+
param_dict = {'ext_bz_bug_id': ext_bz_bug_id}
160+
if ext_type_id is not None:
161+
param_dict['ext_type_id'] = ext_type_id
162+
if ext_type_description is not None:
163+
param_dict['ext_type_description'] = ext_type_description
164+
if ext_type_url is not None:
165+
param_dict['ext_type_url'] = ext_type_url
166+
if ext_status is not None:
167+
param_dict['ext_status'] = ext_status
168+
if ext_description is not None:
169+
param_dict['ext_description'] = ext_description
170+
if ext_priority is not None:
171+
param_dict['ext_priority'] = ext_priority
172+
params = {
152173
'bug_ids': self._listify(bug_ids),
153-
'external_bugs': [{
154-
'ext_type_description': type_desc,
155-
'ext_bz_bug_id': external_id,
156-
}],
174+
'external_bugs': [param_dict],
157175
}
158-
return self._proxy.ExternalBugs.add_external_bug(kwargs)
176+
return self._proxy.ExternalBugs.add_external_bug(params)
159177

160-
def remove_external_tracker(self, bug_ids, type_desc, external_ids):
178+
def update_external_tracker(self, ids=None, ext_type_id=None,
179+
ext_type_description=None, ext_type_url=None,
180+
ext_bz_bug_id=None, bug_ids=None,
181+
ext_status=None, ext_description=None,
182+
ext_priority=None):
183+
"""
184+
Wrapper method to allow adding of external tracking bugs using the
185+
ExternalBugs::WebService::update_external_bug method.
186+
187+
This is documented at
188+
https://bugzilla.redhat.com/docs/en/html/api/extensions/ExternalBugs/lib/WebService.html#update_external_bug
189+
190+
ids: A single external tracker bug id or list of external tracker bug
191+
ids.
192+
ext_type_id: The external tracker id as used by Bugzilla.
193+
ext_type_description: The external tracker description as used by
194+
Bugzilla.
195+
ext_type_url: The external tracker url as used by Bugzilla.
196+
ext_bz_bug_id: A single external bug id or list of external bug ids
197+
(ie: the bug number in the external tracker).
198+
bug_ids: A single bug id or list of bug ids to have external tracker
199+
info updated.
200+
ext_status: The status of the external bug.
201+
ext_description: The description of the external bug.
202+
ext_priority: The priority of the external bug.
203+
"""
204+
params = {}
205+
if ids is not None:
206+
params['ids'] = self._listify(ids)
207+
if ext_type_id is not None:
208+
params['ext_type_id'] = ext_type_id
209+
if ext_type_description is not None:
210+
params['ext_type_description'] = ext_type_description
211+
if ext_type_url is not None:
212+
params['ext_type_url'] = ext_type_url
213+
if ext_bz_bug_id is not None:
214+
params['ext_bz_bug_id'] = self._listify(ext_bz_bug_id)
215+
if bug_ids is not None:
216+
params['bug_ids'] = self._listify(bug_ids)
217+
if ext_status is not None:
218+
params['ext_status'] = ext_status
219+
if ext_description is not None:
220+
params['ext_description'] = ext_description
221+
if ext_priority is not None:
222+
params['ext_priority'] = ext_priority
223+
return self._proxy.ExternalBugs.update_external_bug(params)
224+
225+
def remove_external_tracker(self, ids=None, ext_type_id=None,
226+
ext_type_description=None, ext_type_url=None,
227+
ext_bz_bug_id=None, bug_ids=None):
161228
"""
162229
Wrapper method to allow removal of external tracking bugs using the
163230
ExternalBugs::WebService::remove_external_bug method.
164231
165232
This is documented at
166233
https://bugzilla.redhat.com/docs/en/html/api/extensions/ExternalBugs/lib/WebService.html#remove_external_bug
167234
168-
bug_ids: A single bug id or list if bug ids to remove the tracker from.
169-
type_desc: The external tracker description as used by Bugzilla. This
170-
value maps to the ext_type_description parameter of the XMLRPC
171-
method.
172-
external_ids: The id or list of ids as used by the external tracker.
173-
This value maps to the ext_bz_bug_id parameter of the XMLRPC
174-
method.
235+
ids: A single external tracker bug id or list of external tracker bug
236+
ids.
237+
ext_type_id: The external tracker id as used by Bugzilla.
238+
ext_type_description: The external tracker description as used by
239+
Bugzilla.
240+
ext_type_url: The external tracker url as used by Bugzilla.
241+
ext_bz_bug_id: A single external bug id or list of external bug ids
242+
(ie: the bug number in the external tracker).
243+
bug_ids: A single bug id or list of bug ids to have external tracker
244+
info updated.
175245
"""
176-
kwargs = {
177-
'bug_ids': self._listify(bug_ids),
178-
'ext_type_description': type_desc,
179-
'ext_bz_bug_id': self._listify(external_ids),
180-
}
181-
return self._proxy.ExternalBugs.remove_external_bug(kwargs)
246+
params = {}
247+
if ids is not None:
248+
params['ids'] = self._listify(ids)
249+
if ext_type_id is not None:
250+
params['ext_type_id'] = ext_type_id
251+
if ext_type_description is not None:
252+
params['ext_type_description'] = ext_type_description
253+
if ext_type_url is not None:
254+
params['ext_type_url'] = ext_type_url
255+
if ext_bz_bug_id is not None:
256+
params['ext_bz_bug_id'] = self._listify(ext_bz_bug_id)
257+
if bug_ids is not None:
258+
params['bug_ids'] = self._listify(bug_ids)
259+
return self._proxy.ExternalBugs.remove_external_bug(params)
182260

183261

184262
#################
@@ -285,29 +363,41 @@ def post_translation(self, query, bug):
285363
bug['groups'] = tmp
286364

287365
def build_external_tracker_boolean_query(
288-
self, type_desc=None, external_id=None):
366+
self, ext_type_description=None, ext_type_url=None,
367+
ext_bz_bug_id=None, ext_status=None):
289368
"""
290369
Helper method to build a boolean query to find bugs that contain an
291-
external tracker with the 'type_desc' and 'external_id' combination.
370+
external tracker.
292371
293372
All parameters that are None will be ignored when building the query.
294373
295-
type_desc: The external tracker description as used by Bugzilla. This
296-
value maps to the external_bugzilla.description field.
297-
external_ids: The id as used by the external tracker. This value maps
298-
to the ext_bz_bug_map.ext_bz_bug_id field.
374+
ext_type_description: The external tracker description as used by
375+
Bugzilla.
376+
ext_type_url: The external tracker url as used by Bugzilla.
377+
ext_bz_bug_id: The external bug id (ie: the bug number in the
378+
external tracker).
379+
ext_status: The status of the external bug.
299380
"""
300381
parts = []
301382

302-
if type_desc is not None:
383+
if ext_type_description is not None:
384+
parts.append(
385+
'external_bugzilla.description-equals-{0:s}'.format(
386+
ext_type_description))
387+
388+
if ext_type_url is not None:
303389
parts.append(
304-
'external_bugzilla.description-equals-{0:s}'.format(type_desc))
390+
'external_bugzilla.url-equals-{0:s}'.format(ext_type_url))
305391

306-
if external_id is not None:
307-
id_str = str(external_id)
392+
if ext_bz_bug_id is not None:
393+
id_str = str(ext_bz_bug_id)
308394
parts.append(
309395
'ext_bz_bug_map.ext_bz_bug_id-equals-{0:s}'.format(id_str))
310396

397+
if ext_status is not None:
398+
parts.append(
399+
'ext_bz_bug_map.ext_status-equals-{0:s}'.format(ext_status))
400+
311401
return ' & '.join(parts)
312402

313403
def build_query(self, **kwargs):

tests/rw_functional.py

Lines changed: 90 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -773,35 +773,104 @@ def test13SubComponents(self):
773773
bug.refresh()
774774
self.assertEqual(bug.sub_components, {})
775775

776-
def _test14ExternalTrackersQuery(self, bz, ext_type_desc, ext_bug_id):
777-
boolean_query = bz.build_external_tracker_boolean_query(
778-
ext_type_desc, ext_bug_id)
779-
query = bz.build_query(
780-
boolean_query=boolean_query, include_fields=['id'])
781-
return [bug.bug_id for bug in bz.query(query)]
776+
def _deleteAllExistingExternalTrackers(self, bugid):
777+
bz = self.bzclass(url=self.url, cookiefile=cf, tokenfile=tf)
778+
ids = [bug['id'] for bug in bz.getbug(bugid).external_bugs]
779+
if ids != []:
780+
bz.remove_external_tracker(ids=ids)
782781

783782
def test14ExternalTrackersQuery(self):
784783
bz = self.bzclass(url=self.url, cookiefile=cf, tokenfile=tf)
785-
ext_type_desc = "FreeDesktop.org"
786-
ext_bug_id = 64714
784+
bugid = 461686
785+
ext_bug_id = 1234659
787786

788-
# Closed RH Bugzilla bug with external tracker
789-
bugid = 973374
790-
assert bugid in \
791-
self._test14ExternalTrackersQuery(bz, ext_type_desc, ext_bug_id)
787+
# Delete any existing external trackers to get to a known state
788+
self._deleteAllExistingExternalTrackers(bugid)
789+
790+
# test adding tracker
791+
kwargs = {
792+
'ext_type_url': 'http://bugzilla.mozilla.org',
793+
'ext_type_description': 'Mozilla Foundation',
794+
'ext_status': 'Original Status',
795+
}
792796

793-
def test14ExternalTrackersAddRemove(self):
797+
# Add a tracker that we can query for
798+
bz.add_external_tracker(bugid, ext_bug_id, **kwargs)
799+
800+
kwargs['ext_bz_bug_id'] = ext_bug_id
801+
802+
boolean_query = bz.build_external_tracker_boolean_query(
803+
ext_bz_bug_id=ext_bug_id)
804+
query_results = bz.query(bz.build_query(boolean_query=boolean_query))
805+
if len(query_results) != 1:
806+
raise AssertionError(
807+
'external tracker query by bug id should return 1 result.')
808+
for key, value in kwargs.iteritems():
809+
assert kwargs[key] == value
810+
811+
boolean_query = bz.build_external_tracker_boolean_query(
812+
ext_type_description=kwargs['ext_type_description'])
813+
query_results = bz.query(bz.build_query(boolean_query=boolean_query))
814+
assert bugid in [qr.id for qr in query_results]
815+
816+
boolean_query = bz.build_external_tracker_boolean_query(
817+
ext_status=kwargs['ext_status'])
818+
query_results = bz.query(bz.build_query(boolean_query=boolean_query))
819+
if len(query_results) != 1:
820+
raise AssertionError(
821+
'external tracker query by status should return 1 result.')
822+
for key, value in kwargs.iteritems():
823+
assert kwargs[key] == value
824+
825+
boolean_query = bz.build_external_tracker_boolean_query(
826+
ext_type_url=kwargs['ext_type_url'])
827+
query_results = bz.query(bz.build_query(boolean_query=boolean_query))
828+
assert bugid in [qr.id for qr in query_results]
829+
830+
def test14ExternalTrackersAddUpdateRemoveQuery(self):
794831
bz = self.bzclass(url=self.url, cookiefile=cf, tokenfile=tf)
795-
ext_type_desc = "Mozilla Foundation"
796-
ext_bug_id = 380489
797832
bugid = 461686
833+
ext_bug_id = 380489
834+
835+
# Delete any existing external trackers to get to a known state
836+
self._deleteAllExistingExternalTrackers(bugid)
798837

799838
# test adding tracker
800-
bz.add_external_tracker(bugid, ext_type_desc, ext_bug_id)
801-
assert bugid in \
802-
self._test14ExternalTrackersQuery(bz, ext_type_desc, ext_bug_id)
839+
kwargs = {
840+
'ext_type_id': 6,
841+
'ext_type_url': 'http://bugzilla.mozilla.org',
842+
'ext_type_description': 'Mozilla Foundation',
843+
'ext_status': 'Original Status',
844+
'ext_description': 'the description',
845+
'ext_priority': 'the priority'
846+
}
847+
bz.add_external_tracker(bugid, ext_bug_id, **kwargs)
848+
added_bug = bz.getbug(bugid).external_bugs[0]
849+
assert added_bug['type']['id'] == kwargs['ext_type_id']
850+
assert added_bug['type']['url'] == kwargs['ext_type_url']
851+
assert (added_bug['type']['description'] ==
852+
kwargs['ext_type_description'])
853+
assert added_bug['ext_status'] == kwargs['ext_status']
854+
assert added_bug['ext_description'] == kwargs['ext_description']
855+
assert added_bug['ext_priority'] == kwargs['ext_priority']
856+
857+
# test updating status, description, and priority by id
858+
kwargs = {
859+
'ids': bz.getbug(bugid).external_bugs[0]['id'],
860+
'ext_status': 'New Status',
861+
'ext_description': 'New Description',
862+
'ext_priority': 'New Priority'
863+
}
864+
bz.update_external_tracker(**kwargs)
865+
updated_bug = bz.getbug(bugid).external_bugs[0]
866+
assert updated_bug['ext_bz_bug_id'] == str(ext_bug_id)
867+
assert updated_bug['ext_status'] == kwargs['ext_status']
868+
assert updated_bug['ext_description'] == kwargs['ext_description']
869+
assert updated_bug['ext_priority'] == kwargs['ext_priority']
803870

804871
# test removing tracker
805-
bz.remove_external_tracker(bugid, ext_type_desc, ext_bug_id)
806-
assert bugid not in \
807-
self._test14ExternalTrackersQuery(bz, ext_type_desc, ext_bug_id)
872+
ids = [bug['id'] for bug in bz.getbug(bugid).external_bugs]
873+
assert len(ids) == 1
874+
bz.remove_external_tracker(ids=ids)
875+
ids = [bug['id'] for bug in bz.getbug(bugid).external_bugs]
876+
assert len(ids) == 0

0 commit comments

Comments
 (0)