4767.5.20
by Graham Binns
Added tests, etc., that I stupidly forgot to commit. |
1 |
= ExternalBugTracker: Roundup = |
2 |
||
4767.5.32
by Graham Binns
Typo fix. |
3 |
This covers the implementation of the ExternalBugTracker class for Roundup |
4767.5.20
by Graham Binns
Added tests, etc., that I stupidly forgot to commit. |
4 |
bugwatches. |
5 |
||
6 |
||
7 |
== Basics == |
|
8 |
||
9 |
The ExternalBugTracker descendant class which implements methods for updating |
|
4767.5.28
by Graham Binns
It's called Roundup, not Trac, fool. |
10 |
bug watches on Roundup bug trackers is externalbugtracker.Roundup, which |
11 |
implements IExternalBugTracker. |
|
4767.5.20
by Graham Binns
Added tests, etc., that I stupidly forgot to commit. |
12 |
|
8523.3.10
by Gavin Panella
Fix up some externalbugtracker imports. |
13 |
>>> from lp.bugs.externalbugtracker import Roundup |
11716.1.6
by Curtis Hovey
Converted glob imports in doctests to import for the true module. |
14 |
>>> from lp.bugs.interfaces.bugtracker import BugTrackerType |
15 |
>>> from lp.bugs.interfaces.externalbugtracker import IExternalBugTracker |
|
8523.3.1
by Gavin Panella
Bugs tree reorg after automated migration. |
16 |
>>> from lp.bugs.tests.externalbugtracker import ( |
4953.4.2
by Bjorn Tillenius
make ExternalBugTracker accept a 'bugtracker' argument instead of 'baseurl'. |
17 |
... new_bugtracker) |
4767.5.34
by Graham Binns
Some review fixes for Kiko. |
18 |
>>> from canonical.launchpad.webapp.testing import verifyObject |
4953.4.2
by Bjorn Tillenius
make ExternalBugTracker accept a 'bugtracker' argument instead of 'baseurl'. |
19 |
>>> verifyObject( |
5228.1.5
by Christian Robottom Reis
Rename IExternalBugtracker to IExternalBugTracker |
20 |
... IExternalBugTracker, |
5816.1.1
by Bjorn Tillenius
Make ExternalBugTracker accept a URL instead of a transaction and bug tracker. |
21 |
... Roundup('http://example.com')) |
4767.5.20
by Graham Binns
Added tests, etc., that I stupidly forgot to commit. |
22 |
True |
23 |
||
24 |
||
25 |
== Status Conversion == |
|
26 |
||
7403.5.8
by Gavin Panella
Convert remote statuses more generally. In other words, don't use the isPython() method. |
27 |
The basic Roundup bug statuses (i.e. those available by default in new |
28 |
Roundup instances) map to Launchpad bug statuses. |
|
29 |
||
30 |
Roundup.convertRemoteStatus() handles the conversion. |
|
4767.5.20
by Graham Binns
Added tests, etc., that I stupidly forgot to commit. |
31 |
|
5816.1.1
by Bjorn Tillenius
Make ExternalBugTracker accept a URL instead of a transaction and bug tracker. |
32 |
>>> roundup = Roundup('http://example.com/') |
6326.8.15
by Gavin Panella
Convert roundup. |
33 |
>>> roundup.convertRemoteStatus('1').title |
4767.5.20
by Graham Binns
Added tests, etc., that I stupidly forgot to commit. |
34 |
'New' |
6326.8.15
by Gavin Panella
Convert roundup. |
35 |
>>> roundup.convertRemoteStatus('2').title |
4767.5.20
by Graham Binns
Added tests, etc., that I stupidly forgot to commit. |
36 |
'Confirmed' |
6326.8.15
by Gavin Panella
Convert roundup. |
37 |
>>> roundup.convertRemoteStatus('3').title |
38 |
'Incomplete' |
|
39 |
>>> roundup.convertRemoteStatus('4').title |
|
40 |
'Incomplete' |
|
41 |
>>> roundup.convertRemoteStatus('5').title |
|
42 |
'In Progress' |
|
43 |
>>> roundup.convertRemoteStatus('6').title |
|
44 |
'In Progress' |
|
45 |
>>> roundup.convertRemoteStatus('7').title |
|
4767.5.20
by Graham Binns
Added tests, etc., that I stupidly forgot to commit. |
46 |
'Fix Committed' |
6326.8.15
by Gavin Panella
Convert roundup. |
47 |
>>> roundup.convertRemoteStatus('8').title |
4767.5.20
by Graham Binns
Added tests, etc., that I stupidly forgot to commit. |
48 |
'Fix Released' |
49 |
||
7403.5.8
by Gavin Panella
Convert remote statuses more generally. In other words, don't use the isPython() method. |
50 |
Some Roundup trackers are set up to use multiple fields (columns in |
51 |
Roundup terminology) to represent bug statuses. We store multiple |
|
52 |
values by joining them with colons. The Roundup class knows how many |
|
53 |
fields are expected for a particular remote host (for those that we |
|
54 |
support), and will generate an error when we have more or less field |
|
55 |
values compared to the expected number of fields. |
|
56 |
||
57 |
>>> roundup.convertRemoteStatus('1:2') |
|
58 |
Traceback (most recent call last): |
|
59 |
... |
|
60 |
UnknownRemoteStatusError: 1 field(s) expected, got 2: 1:2 |
|
61 |
||
4767.5.26
by Graham Binns
Paragraphing in doctests. |
62 |
If the status isn't something that our Roundup ExternalBugTracker can |
5863.4.11
by Graham Binns
Fixed all tests, finally. Whoop de do. |
63 |
understand an UnknownRemoteStatusError will be raised. |
4767.5.20
by Graham Binns
Added tests, etc., that I stupidly forgot to commit. |
64 |
|
65 |
>>> roundup.convertRemoteStatus('eggs').title |
|
5863.4.11
by Graham Binns
Fixed all tests, finally. Whoop de do. |
66 |
Traceback (most recent call last): |
67 |
... |
|
7403.5.8
by Gavin Panella
Convert remote statuses more generally. In other words, don't use the isPython() method. |
68 |
UnknownRemoteStatusError: Unrecognized value for field 1 (status): eggs |
4767.5.20
by Graham Binns
Added tests, etc., that I stupidly forgot to commit. |
69 |
|
70 |
||
71 |
== Initialization == |
|
72 |
||
4767.5.27
by Graham Binns
It's called Roundup, not Trac, fool |
73 |
Calling initializeRemoteBugDB() on our Roundup instance and passing it a set |
74 |
of remote bug IDs will fetch those bug IDs from the server and file them in a |
|
4767.5.20
by Graham Binns
Added tests, etc., that I stupidly forgot to commit. |
75 |
local variable for later use. |
76 |
||
6253.2.3
by Gavin Panella
Update tests. |
77 |
We use a test-oriented implementation for the purposes of these tests, which |
4767.5.20
by Graham Binns
Added tests, etc., that I stupidly forgot to commit. |
78 |
overrides ExternalBugTracker.urlopen() so that we don't have to rely on a |
79 |
working network connection. |
|
80 |
||
8523.3.1
by Gavin Panella
Bugs tree reorg after automated migration. |
81 |
>>> from lp.bugs.tests.externalbugtracker import ( |
4767.5.39
by Graham Binns
Added a print_bugwatches() helper function to ftests.externalbugtracker. |
82 |
... TestRoundup, print_bugwatches) |
5816.1.1
by Bjorn Tillenius
Make ExternalBugTracker accept a URL instead of a transaction and bug tracker. |
83 |
>>> roundup = TestRoundup(u'http://test.roundup/') |
4767.5.20
by Graham Binns
Added tests, etc., that I stupidly forgot to commit. |
84 |
>>> roundup.initializeRemoteBugDB([1]) |
85 |
>>> sorted(roundup.bugs.keys()) |
|
86 |
[1] |
|
87 |
||
88 |
||
89 |
== Export Methods == |
|
90 |
||
91 |
There are two means by which we can export Roundup bug statuses: on a |
|
92 |
bug-by-bug basis and as a batch. When the number of bugs that need updating is |
|
93 |
less than a given bug roundupker's batch_query_threshold the bugs will be |
|
94 |
fetched one-at-a-time: |
|
95 |
||
96 |
>>> roundup.batch_query_threshold |
|
97 |
10 |
|
98 |
||
99 |
>>> roundup.trace_calls = True |
|
100 |
>>> roundup.initializeRemoteBugDB([6, 7, 8, 9, 10]) |
|
4953.4.2
by Bjorn Tillenius
make ExternalBugTracker accept a 'bugtracker' argument instead of 'baseurl'. |
101 |
CALLED urlopen(u'http://test.roundup/issue?...&id=6') |
102 |
CALLED urlopen(u'http://test.roundup/issue?...&id=7') |
|
103 |
CALLED urlopen(u'http://test.roundup/issue?...&id=8') |
|
104 |
CALLED urlopen(u'http://test.roundup/issue?...&id=9') |
|
105 |
CALLED urlopen(u'http://test.roundup/issue?...&id=10') |
|
4767.5.20
by Graham Binns
Added tests, etc., that I stupidly forgot to commit. |
106 |
|
107 |
If there are more than batch_query_threshold bugs to update then they are |
|
108 |
fetched as a batch: |
|
109 |
||
110 |
>>> roundup.batch_query_threshold = 4 |
|
111 |
>>> roundup.initializeRemoteBugDB([6, 7, 8, 9, 10]) |
|
4953.4.2
by Bjorn Tillenius
make ExternalBugTracker accept a 'bugtracker' argument instead of 'baseurl'. |
112 |
CALLED urlopen(u'http://test.roundup/issue?...@startwith=0') |
4767.5.20
by Graham Binns
Added tests, etc., that I stupidly forgot to commit. |
113 |
|
114 |
||
115 |
== Updating Bug Watches == |
|
116 |
||
117 |
First, we create some bug watches to test with: |
|
118 |
||
11692.6.4
by Curtis Hovey
Fixed tests with multiple imports on the line. |
119 |
>>> from lp.bugs.interfaces.bug import IBugSet |
120 |
>>> from lp.registry.interfaces.person import IPersonSet |
|
4767.5.20
by Graham Binns
Added tests, etc., that I stupidly forgot to commit. |
121 |
>>> sample_person = getUtility(IPersonSet).getByEmail('test@canonical.com') |
122 |
||
4945.2.3
by Bjorn Tillenius
make the rest of the externalbugtracker-* tests run using the checkwatches db user. |
123 |
>>> example_bug_tracker = new_bugtracker(BugTrackerType.ROUNDUP) |
4767.5.20
by Graham Binns
Added tests, etc., that I stupidly forgot to commit. |
124 |
|
11692.6.2
by Curtis Hovey
Use deglober to fixing simple glob imports in doctests. |
125 |
>>> from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities |
4767.5.20
by Graham Binns
Added tests, etc., that I stupidly forgot to commit. |
126 |
>>> example_bug = getUtility(IBugSet).get(10) |
127 |
>>> example_bugwatch = example_bug.addWatch( |
|
7982.1.15
by Bjorn Tillenius
Fix test failures. |
128 |
... example_bug_tracker, '1', |
129 |
... getUtility(ILaunchpadCelebrities).janitor) |
|
4767.5.20
by Graham Binns
Added tests, etc., that I stupidly forgot to commit. |
130 |
|
131 |
||
132 |
Collect the Example.com watches: |
|
133 |
||
4767.5.39
by Graham Binns
Added a print_bugwatches() helper function to ftests.externalbugtracker. |
134 |
>>> print_bugwatches(example_bug_tracker.watches) |
135 |
Remote bug 1: None |
|
4767.5.20
by Graham Binns
Added tests, etc., that I stupidly forgot to commit. |
136 |
|
137 |
And have a Roundup instance process them: |
|
138 |
||
10512.4.24
by Gavin Panella
Get all the externalbugtracker*.txt doctests passing. |
139 |
>>> transaction.commit() |
140 |
||
11716.1.12
by Curtis Hovey
Sorted imports in doctests. |
141 |
>>> from canonical.testing.layers import LaunchpadZopelessLayer |
10694.2.25
by Graham Binns
Renamed BugWatchUpdater -> CheckwatchesMaster. This is the wrong name for it, but I did it to avoid bikeshedding. |
142 |
>>> from lp.bugs.scripts.checkwatches import CheckwatchesMaster |
5816.1.1
by Bjorn Tillenius
Make ExternalBugTracker accept a URL instead of a transaction and bug tracker. |
143 |
>>> txn = LaunchpadZopelessLayer.txn |
10694.2.25
by Graham Binns
Renamed BugWatchUpdater -> CheckwatchesMaster. This is the wrong name for it, but I did it to avoid bikeshedding. |
144 |
>>> bug_watch_updater = CheckwatchesMaster(txn) |
5816.1.1
by Bjorn Tillenius
Make ExternalBugTracker accept a URL instead of a transaction and bug tracker. |
145 |
>>> roundup = TestRoundup(example_bug_tracker.baseurl) |
5626.5.2
by Bjorn Tillenius
move ExternalBugtracker.updateBugWatches() to BugWatchUpdater.updateBugWatches(). Debbugs.importBugComments() is now broken, though. |
146 |
>>> bug_watch_updater.updateBugWatches( |
147 |
... roundup, example_bug_tracker.watches) |
|
7910.2.7
by Graham Binns
Updated checkwatches tests to deal with logging output changes. |
148 |
INFO:...:Updating 1 watches for 1 bugs on http://bugs.some.where |
4767.5.39
by Graham Binns
Added a print_bugwatches() helper function to ftests.externalbugtracker. |
149 |
>>> print_bugwatches(example_bug_tracker.watches) |
150 |
Remote bug 1: 1 |
|
4767.5.20
by Graham Binns
Added tests, etc., that I stupidly forgot to commit. |
151 |
|
152 |
We'll add some more watches now. |
|
153 |
||
11692.6.2
by Curtis Hovey
Use deglober to fixing simple glob imports in doctests. |
154 |
>>> from lp.bugs.interfaces.bugwatch import IBugWatchSet |
4767.5.39
by Graham Binns
Added a print_bugwatches() helper function to ftests.externalbugtracker. |
155 |
>>> print_bugwatches(example_bug_tracker.watches, |
156 |
... roundup.convertRemoteStatus) |
|
157 |
Remote bug 1: New |
|
4767.5.20
by Graham Binns
Added tests, etc., that I stupidly forgot to commit. |
158 |
|
159 |
>>> remote_bugs = [ |
|
4767.5.21
by Graham Binns
Roundup.getRemoteStatus() now returns a string rather than an int so that updateBugWatches() doesn't get confused and think that a watch was updated when it wasn't. |
160 |
... (2, 'Confirmed'), |
161 |
... (3, 'Incomplete'), |
|
162 |
... (4, 'Incomplete'), |
|
163 |
... (5, 'In Progress'), |
|
164 |
... (9, 'In Progress'), |
|
165 |
... (10, 'Fix Committed'), |
|
166 |
... (11, 'Fix Released'), |
|
167 |
... (12, 'Incomplete'), |
|
168 |
... (13, 'Incomplete'), |
|
169 |
... (14, 'In Progress') |
|
4767.5.20
by Graham Binns
Added tests, etc., that I stupidly forgot to commit. |
170 |
... ] |
171 |
||
4767.5.39
by Graham Binns
Added a print_bugwatches() helper function to ftests.externalbugtracker. |
172 |
>>> bug_watch_set = getUtility(IBugWatchSet) |
4767.5.20
by Graham Binns
Added tests, etc., that I stupidly forgot to commit. |
173 |
>>> for remote_bug_id, remote_status in remote_bugs: |
174 |
... bug_watch = bug_watch_set.createBugWatch( |
|
175 |
... bug=example_bug, owner=sample_person, |
|
176 |
... bugtracker=example_bug_tracker, |
|
177 |
... remotebug=str(remote_bug_id)) |
|
178 |
||
179 |
>>> roundup.trace_calls = True |
|
5626.5.2
by Bjorn Tillenius
move ExternalBugtracker.updateBugWatches() to BugWatchUpdater.updateBugWatches(). Debbugs.importBugComments() is now broken, though. |
180 |
>>> bug_watch_updater.updateBugWatches( |
181 |
... roundup, example_bug_tracker.watches) |
|
7910.2.7
by Graham Binns
Updated checkwatches tests to deal with logging output changes. |
182 |
INFO:...:Updating 11 watches for 11 bugs on http://bugs.some.where |
4945.2.3
by Bjorn Tillenius
make the rest of the externalbugtracker-* tests run using the checkwatches db user. |
183 |
CALLED urlopen(u'http://.../issue?...@startwith=0') |
4767.5.21
by Graham Binns
Roundup.getRemoteStatus() now returns a string rather than an int so that updateBugWatches() doesn't get confused and think that a watch was updated when it wasn't. |
184 |
|
4767.5.39
by Graham Binns
Added a print_bugwatches() helper function to ftests.externalbugtracker. |
185 |
>>> print_bugwatches(example_bug_tracker.watches, |
186 |
... roundup.convertRemoteStatus) |
|
4767.5.20
by Graham Binns
Added tests, etc., that I stupidly forgot to commit. |
187 |
Remote bug 1: New |
4767.5.21
by Graham Binns
Roundup.getRemoteStatus() now returns a string rather than an int so that updateBugWatches() doesn't get confused and think that a watch was updated when it wasn't. |
188 |
Remote bug 2: Confirmed |
189 |
Remote bug 3: Incomplete |
|
190 |
Remote bug 4: Incomplete |
|
191 |
Remote bug 5: In Progress |
|
192 |
Remote bug 9: In Progress |
|
193 |
Remote bug 10: Fix Committed |
|
194 |
Remote bug 11: Fix Released |
|
195 |
Remote bug 12: Incomplete |
|
196 |
Remote bug 13: Incomplete |
|
197 |
Remote bug 14: In Progress |
|
4767.5.20
by Graham Binns
Added tests, etc., that I stupidly forgot to commit. |
198 |