Merge lp:~jcsackett/charmworld/better-latency-round-2 into lp:charmworld
- better-latency-round-2
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | j.c.sackett |
Approved revision: | 461 |
Merged at revision: | 459 |
Proposed branch: | lp:~jcsackett/charmworld/better-latency-round-2 |
Merge into: | lp:charmworld |
Diff against target: |
374 lines (+182/-76) 3 files modified
.bzrignore (+1/-0) charmworld/jobs/review.py (+74/-30) charmworld/jobs/tests/test_review.py (+107/-46) |
To merge this branch: | bzr merge lp:~jcsackett/charmworld/better-latency-round-2 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Juju Gui Bot | continuous-integration | Approve | |
Aaron Bentley (community) | Approve | ||
Review via email: mp+195091@code.launchpad.net |
Commit message
Undoes the rollback for the better latency work, with a fix for the expiring credentials.
Description of the change
This undoes the rollback in r 443 of the better latency work originally done in
r 422.
The majority of the changes were explained and approved in an earlier MP[1].
charmworld/
-------
The reinstated call to login_with is updated to use consumer_name as a
parameter; this ensures that LP sees the same, already authorized consumer when
the request occurs in dev, staging, or production.
As before, the credentials file will have to be set on the staging and
production instances by setting the lp_credentials parameter on the charm, via
juju set. IS docs on wiki.canonical.com and the deploy script for staging will
both be updated with this information after this branch is QAed.
[1]: https:/
Juju Gui Bot (juju-gui-bot) wrote : | # |
FAILED: Autolanding.
More details in the following jenkins job:
http://
Executed test runs:
j.c.sackett (jcsackett) wrote : | # |
Looks like it just failed on the npm step, possible network error? Trying again.
Juju Gui Bot (juju-gui-bot) : | # |
Preview Diff
1 | === modified file '.bzrignore' | |||
2 | --- .bzrignore 2013-10-17 15:58:13 +0000 | |||
3 | +++ .bzrignore 2013-11-13 16:15:48 +0000 | |||
4 | @@ -29,3 +29,4 @@ | |||
5 | 29 | supervisord.log | 29 | supervisord.log |
6 | 30 | supervisord.pid | 30 | supervisord.pid |
7 | 31 | _run | 31 | _run |
8 | 32 | charmbot_credentials.txt | ||
9 | 32 | 33 | ||
10 | === modified file 'charmworld/jobs/review.py' | |||
11 | --- charmworld/jobs/review.py 2013-11-05 18:40:38 +0000 | |||
12 | +++ charmworld/jobs/review.py 2013-11-13 16:15:48 +0000 | |||
13 | @@ -38,10 +38,21 @@ | |||
14 | 38 | # older than the window that is still open. Right now this is probably the | 38 | # older than the window that is still open. Right now this is probably the |
15 | 39 | # more performant way to go about it, but that's going to change as the | 39 | # more performant way to go about it, but that's going to change as the |
16 | 40 | # data outside of our window gets larger. | 40 | # data outside of our window gets larger. |
17 | 41 | try: | ||
18 | 42 | lp_credentials = get_ini()['lp_credentials_file'] | ||
19 | 43 | except KeyError: | ||
20 | 44 | lp_credentials = None | ||
21 | 41 | with Timer() as timer: | 45 | with Timer() as timer: |
25 | 42 | lp = Launchpad.login_anonymously('charm-tools', | 46 | if lp_credentials: |
26 | 43 | 'production', | 47 | lp = Launchpad.login_with(application_name='charm-tools', |
27 | 44 | version='devel') | 48 | service_root='production', |
28 | 49 | version='devel', | ||
29 | 50 | consumer_name='charmworld', | ||
30 | 51 | credentials_file=lp_credentials) | ||
31 | 52 | else: | ||
32 | 53 | lp = Launchpad.login_anonymously('charm-tools', | ||
33 | 54 | 'production', | ||
34 | 55 | version='devel') | ||
35 | 45 | 56 | ||
36 | 46 | # Entity roots for items of interests | 57 | # Entity roots for items of interests |
37 | 47 | charm = lp.distributions['charms'] | 58 | charm = lp.distributions['charms'] |
38 | @@ -50,13 +61,13 @@ | |||
39 | 50 | 61 | ||
40 | 51 | log.debug("lp login time %0.2f", timer.duration()) | 62 | log.debug("lp login time %0.2f", timer.duration()) |
41 | 52 | 63 | ||
42 | 64 | branch_filter = "Show only Bugs with linked Branches" | ||
43 | 53 | with Timer() as timer: | 65 | with Timer() as timer: |
44 | 54 | bugs = charm.searchTasks( | 66 | bugs = charm.searchTasks( |
45 | 55 | tags=['new-formula', 'new-charm'], | 67 | tags=['new-formula', 'new-charm'], |
50 | 56 | tags_combinator="Any") | 68 | tags_combinator="Any", |
51 | 57 | # Best practice dictates that charmers be subscribed to all bugs | 69 | linked_branches=branch_filter) |
52 | 58 | # and merge proposals for official source package branches. | 70 | charmers_bugs = charmers.searchTasks(linked_branches=branch_filter) |
49 | 59 | charmers_bugs = charmers.searchTasks() | ||
53 | 60 | proposals = charmers.getRequestedReviews() | 71 | proposals = charmers.getRequestedReviews() |
54 | 61 | contributor_proposals = charm_contributors.getRequestedReviews() | 72 | contributor_proposals = charm_contributors.getRequestedReviews() |
55 | 62 | 73 | ||
56 | @@ -69,27 +80,67 @@ | |||
57 | 69 | itertools.chain(proposals, contributor_proposals, doc_proposals)) | 80 | itertools.chain(proposals, contributor_proposals, doc_proposals)) |
58 | 70 | 81 | ||
59 | 71 | 82 | ||
60 | 83 | def calculate_proposal_latency(proposal, now): | ||
61 | 84 | if proposal.date_reviewed: | ||
62 | 85 | latency = ( | ||
63 | 86 | proposal.date_reviewed - proposal.date_review_requested) | ||
64 | 87 | else: | ||
65 | 88 | # `now` has been calculated in UTC, and LP returns UTC TZ | ||
66 | 89 | # datetimes. We can safely remove the TZ, letting us get the | ||
67 | 90 | latency = ( | ||
68 | 91 | now - proposal.date_review_requested.replace(tzinfo=None)) | ||
69 | 92 | return latency.total_seconds() | ||
70 | 93 | |||
71 | 94 | |||
72 | 95 | def calculate_task_latency(task, now): | ||
73 | 96 | link_entries = [e for e in task.bug.activity.entries if | ||
74 | 97 | e['whatchanged'] == 'branch linked'] | ||
75 | 98 | if len(link_entries) == 1: | ||
76 | 99 | start_date = link_entries[0]['datechanged'] | ||
77 | 100 | start_date = datetime.datetime.strptime( | ||
78 | 101 | start_date.split('.')[0], '%Y-%m-%dT%H:%M:%S') | ||
79 | 102 | elif len(link_entries) > 1: | ||
80 | 103 | #Filter down to links associated with the currently linked branches | ||
81 | 104 | linked_branches = task.bug.linked_branches | ||
82 | 105 | branch_names = [link.branch.display_name for link in linked_branches] | ||
83 | 106 | current_entries = [e for e in link_entries if | ||
84 | 107 | e['newvalue'] in branch_names] | ||
85 | 108 | if current_entries != []: | ||
86 | 109 | start_date = current_entries[0]['datechanged'] | ||
87 | 110 | start_date = datetime.datetime.strptime( | ||
88 | 111 | start_date.split('.')[0], '%Y-%m-%dT%H:%M:%S') | ||
89 | 112 | else: | ||
90 | 113 | # At some point, the name of the branch changed, so we can't find | ||
91 | 114 | # the event when it was added. This happens rarely, so we just | ||
92 | 115 | # abandon stats for this task. | ||
93 | 116 | return | ||
94 | 117 | elif link_entries == []: | ||
95 | 118 | # We have no entries, probably b/c the lp step failed to login with | ||
96 | 119 | # authentication. | ||
97 | 120 | return | ||
98 | 121 | |||
99 | 122 | if task.date_fix_committed: | ||
100 | 123 | end_date = task.date_fix_committed.replace(tzinfo=None) | ||
101 | 124 | else: | ||
102 | 125 | end_date = now | ||
103 | 126 | latency = end_date - start_date | ||
104 | 127 | return latency.total_seconds() | ||
105 | 128 | |||
106 | 129 | |||
107 | 72 | def update_review_queue(db, tasks, proposals, log): | 130 | def update_review_queue(db, tasks, proposals, log): |
108 | 73 | '''Updates the review queue information.''' | 131 | '''Updates the review queue information.''' |
109 | 132 | now = datetime.datetime.utcnow() | ||
110 | 133 | window = now - datetime.timedelta(days=180) # 6 month window for latency | ||
111 | 74 | bug_statuses = [ | 134 | bug_statuses = [ |
112 | 75 | 'New', 'Confirmed', 'Triaged', 'In Progress', 'Fix Committed'] | 135 | 'New', 'Confirmed', 'Triaged', 'In Progress', 'Fix Committed'] |
113 | 76 | proposal_statuses = ['Needs review', 'Needs fixing', 'Needs information'] | ||
114 | 77 | now = datetime.datetime.utcnow() | ||
115 | 78 | window = now - datetime.timedelta(days=180) # 6 month window for latency | ||
116 | 79 | |||
117 | 80 | r_queue = [] | 136 | r_queue = [] |
118 | 81 | latencies = [] | 137 | latencies = [] |
119 | 82 | for task in tasks: | 138 | for task in tasks: |
120 | 83 | if (task.date_created.replace(tzinfo=None) >= window or | 139 | if (task.date_created.replace(tzinfo=None) >= window or |
121 | 84 | task.status in bug_statuses): | 140 | task.status in bug_statuses): |
130 | 85 | if task.date_confirmed: | 141 | latency = calculate_task_latency(task, now) |
131 | 86 | latency = task.date_confirmed - task.date_created | 142 | if latency: |
132 | 87 | else: | 143 | latencies.append(latency) |
125 | 88 | # Now has been calculated in UTC, and LP returns UTC TZ | ||
126 | 89 | # datetimes. We can safely remove the TZ, letting us get the | ||
127 | 90 | # timedelta. | ||
128 | 91 | latency = now - task.date_created.replace(tzinfo=None) | ||
129 | 92 | latencies.append(latency.total_seconds()) | ||
133 | 93 | 144 | ||
134 | 94 | if task.status in bug_statuses: | 145 | if task.status in bug_statuses: |
135 | 95 | entry = { | 146 | entry = { |
136 | @@ -102,19 +153,13 @@ | |||
137 | 102 | } | 153 | } |
138 | 103 | r_queue.append(entry) | 154 | r_queue.append(entry) |
139 | 104 | 155 | ||
140 | 156 | proposal_statuses = [ | ||
141 | 157 | 'Needs review', 'Needs fixing', 'Needs information'] | ||
142 | 105 | for proposal in proposals: | 158 | for proposal in proposals: |
143 | 106 | if (proposal.date_created.replace(tzinfo=None) >= window or | 159 | if (proposal.date_created.replace(tzinfo=None) >= window or |
144 | 107 | proposal.queue_status in proposal_statuses): | 160 | proposal.queue_status in proposal_statuses): |
155 | 108 | if proposal.date_reviewed: | 161 | latency = calculate_proposal_latency(proposal, now) |
156 | 109 | latency = ( | 162 | latencies.append(latency) |
147 | 110 | proposal.date_reviewed - proposal.date_review_requested) | ||
148 | 111 | else: | ||
149 | 112 | # Now has been calculated in UTC, and LP returns UTC TZ | ||
150 | 113 | # datetimes. We can safely remove the TZ, letting us get the | ||
151 | 114 | latency = ( | ||
152 | 115 | now - proposal.date_review_requested.replace(tzinfo=None)) | ||
153 | 116 | latencies.append(latency.total_seconds()) | ||
154 | 117 | |||
157 | 118 | if proposal.queue_status in proposal_statuses: | 163 | if proposal.queue_status in proposal_statuses: |
158 | 119 | parts = proposal.target_branch_link.rsplit('/', 3) | 164 | parts = proposal.target_branch_link.rsplit('/', 3) |
159 | 120 | if parts[-1] == "trunk": | 165 | if parts[-1] == "trunk": |
160 | @@ -131,7 +176,6 @@ | |||
161 | 131 | 176 | ||
162 | 132 | entry = { | 177 | entry = { |
163 | 133 | 'type': 'proposal', | 178 | 'type': 'proposal', |
164 | 134 | 'latency': latency.total_seconds(), | ||
165 | 135 | 'date_modified': last_modified, | 179 | 'date_modified': last_modified, |
166 | 136 | 'date_created': proposal.date_created, | 180 | 'date_created': proposal.date_created, |
167 | 137 | 'summary': "Merge for %s from %s" % (target, origin), | 181 | 'summary': "Merge for %s from %s" % (target, origin), |
168 | 138 | 182 | ||
169 | === modified file 'charmworld/jobs/tests/test_review.py' | |||
170 | --- charmworld/jobs/tests/test_review.py 2013-11-05 18:40:38 +0000 | |||
171 | +++ charmworld/jobs/tests/test_review.py 2013-11-13 16:15:48 +0000 | |||
172 | @@ -3,7 +3,13 @@ | |||
173 | 3 | import datetime | 3 | import datetime |
174 | 4 | import logging | 4 | import logging |
175 | 5 | 5 | ||
177 | 6 | from charmworld.jobs.review import update_review_queue | 6 | import mock |
178 | 7 | |||
179 | 8 | from charmworld.jobs.review import ( | ||
180 | 9 | calculate_proposal_latency, | ||
181 | 10 | calculate_task_latency, | ||
182 | 11 | update_review_queue, | ||
183 | 12 | ) | ||
184 | 7 | from charmworld.testing import MongoTestBase | 13 | from charmworld.testing import MongoTestBase |
185 | 8 | 14 | ||
186 | 9 | 15 | ||
187 | @@ -12,45 +18,45 @@ | |||
188 | 12 | TWO_DAYS = NOW - datetime.timedelta(2) | 18 | TWO_DAYS = NOW - datetime.timedelta(2) |
189 | 13 | 19 | ||
190 | 14 | 20 | ||
230 | 15 | class MockBug: | 21 | def get_mock_task(confirmed=False, entries=[], linked_branches=[]): |
231 | 16 | date_last_updated = NOW | 22 | if confirmed: |
232 | 17 | 23 | status = "Confirmed" | |
233 | 18 | 24 | date_fix_committed = YESTERDAY | |
234 | 19 | class MockTask: | 25 | else: |
235 | 20 | 26 | date_fix_committed = None | |
236 | 21 | def __init__(self, confirmed=False): | 27 | status = "New" |
237 | 22 | self.date_created = TWO_DAYS | 28 | return mock.Mock( |
238 | 23 | self.title = u'Bug #0 in a collection: "A bug task"' | 29 | status=status, |
239 | 24 | self.web_link = "http://example.com" | 30 | date_fix_committed=date_fix_committed, |
240 | 25 | self.bug = MockBug() | 31 | date_created=TWO_DAYS, |
241 | 26 | if confirmed: | 32 | title=u'Bug #0 in a collection: "A bug task"', |
242 | 27 | self.status = "Confirmed" | 33 | web_link="http://example.com", |
243 | 28 | self.date_confirmed = YESTERDAY | 34 | bug=mock.Mock( |
244 | 29 | else: | 35 | date_last_updated=NOW, |
245 | 30 | self.date_confirmed = None | 36 | linked_branches=linked_branches, |
246 | 31 | self.status = "New" | 37 | activity=mock.Mock(entries=entries) |
247 | 32 | 38 | ), | |
248 | 33 | 39 | ) | |
249 | 34 | class MockCommentCollection: | 40 | |
250 | 35 | total_size = 0 | 41 | |
251 | 36 | 42 | def get_mock_proposal(reviewed=False): | |
252 | 37 | 43 | base = 'https://api.launchpad.net/devel/' | |
253 | 38 | class MockProposal: | 44 | if reviewed: |
254 | 39 | 45 | date_reviewed = YESTERDAY | |
255 | 40 | def __init__(self, reviewed=False): | 46 | queue_status = "Approved" |
256 | 41 | base = 'https://api.launchpad.net/devel/' | 47 | else: |
257 | 42 | self.target_branch_link = base + '~charmers/charms/precise/foo/trunk' | 48 | date_reviewed = None |
258 | 43 | self.source_branch_link = base + '~bar/charms/precise/foo/fnord' | 49 | queue_status = "Needs review" |
259 | 44 | self.all_comments = MockCommentCollection() | 50 | return mock.Mock( |
260 | 45 | self.date_review_requested = TWO_DAYS | 51 | target_branch_link=base + '~charmers/charms/precise/foo/trunk', |
261 | 46 | self.date_created = TWO_DAYS | 52 | source_branch_link=base + '~bar/charms/precise/foo/fnord', |
262 | 47 | self.web_link = 'http://example.com' | 53 | all_comments=mock.Mock(total_size=0), |
263 | 48 | if reviewed: | 54 | date_review_requested=TWO_DAYS, |
264 | 49 | self.date_reviewed = YESTERDAY | 55 | date_created=TWO_DAYS, |
265 | 50 | self.queue_status = "Approved" | 56 | web_link='http://example.com', |
266 | 51 | else: | 57 | date_reviewed=date_reviewed, |
267 | 52 | self.date_reviewed = None | 58 | queue_status=queue_status, |
268 | 53 | self.queue_status = "Needs review" | 59 | ) |
269 | 54 | 60 | ||
270 | 55 | 61 | ||
271 | 56 | class ReviewTest(MongoTestBase): | 62 | class ReviewTest(MongoTestBase): |
272 | @@ -63,7 +69,7 @@ | |||
273 | 63 | 69 | ||
274 | 64 | def test_review_handles_bugs(self): | 70 | def test_review_handles_bugs(self): |
275 | 65 | log = logging.getLogger('foo') | 71 | log = logging.getLogger('foo') |
277 | 66 | update_review_queue(self.db, [MockTask()], [], log) | 72 | update_review_queue(self.db, [get_mock_task()], [], log) |
278 | 67 | self.assertEqual(1, self.db.review_queue.count()) | 73 | self.assertEqual(1, self.db.review_queue.count()) |
279 | 68 | item = self.db.review_queue.find_one() | 74 | item = self.db.review_queue.find_one() |
280 | 69 | self.assertEqual(NOW.date(), item['date_modified'].date()) | 75 | self.assertEqual(NOW.date(), item['date_modified'].date()) |
281 | @@ -74,7 +80,7 @@ | |||
282 | 74 | 80 | ||
283 | 75 | def test_review_handles_proposals(self): | 81 | def test_review_handles_proposals(self): |
284 | 76 | log = logging.getLogger('foo') | 82 | log = logging.getLogger('foo') |
286 | 77 | update_review_queue(self.db, [], [MockProposal()], log) | 83 | update_review_queue(self.db, [], [get_mock_proposal()], log) |
287 | 78 | self.assertEqual(1, self.db.review_queue.count()) | 84 | self.assertEqual(1, self.db.review_queue.count()) |
288 | 79 | item = self.db.review_queue.find_one() | 85 | item = self.db.review_queue.find_one() |
289 | 80 | self.assertEqual(TWO_DAYS.date(), item['date_modified'].date()) | 86 | self.assertEqual(TWO_DAYS.date(), item['date_modified'].date()) |
290 | @@ -84,10 +90,65 @@ | |||
291 | 84 | self.assertEqual('http://example.com', item['item']) | 90 | self.assertEqual('http://example.com', item['item']) |
292 | 85 | self.assertEqual('Needs review', item['status']) | 91 | self.assertEqual('Needs review', item['status']) |
293 | 86 | 92 | ||
295 | 87 | def test_review_calculates_latency(self): | 93 | def test_calculate_task_latency_with_two_valid_links(self): |
296 | 94 | linked_branches = [ | ||
297 | 95 | mock.Mock(branch=mock.Mock(display_name='lp:~foo/bar/bjorn')), | ||
298 | 96 | mock.Mock(branch=mock.Mock(display_name='lp:~foo/bar/baz')) | ||
299 | 97 | ] | ||
300 | 98 | two_days = datetime.datetime.strftime( | ||
301 | 99 | TWO_DAYS, '%Y-%m-%dT%H:%M:%S') | ||
302 | 100 | yesterday = datetime.datetime.strftime( | ||
303 | 101 | YESTERDAY, '%Y-%m-%dT%H:%M:%S') | ||
304 | 102 | entries = [ | ||
305 | 103 | {'whatchanged': 'branch linked', | ||
306 | 104 | 'newvalue': 'lp:~foo/bar/baz', | ||
307 | 105 | 'datechanged': two_days}, | ||
308 | 106 | {'whatchanged': 'branch linked', | ||
309 | 107 | 'newvalue': 'lp:~foo/bar/bjorn', | ||
310 | 108 | 'datechanged': yesterday}] | ||
311 | 109 | latency = calculate_task_latency( | ||
312 | 110 | get_mock_task( | ||
313 | 111 | True, entries=entries, linked_branches=linked_branches), NOW) | ||
314 | 112 | self.assertEqual(60 * 60 * 24, int(latency)) | ||
315 | 113 | |||
316 | 114 | def test_calculate_task_latency_bug_with_one_valid_link(self): | ||
317 | 115 | linked_branches = [ | ||
318 | 116 | mock.Mock(branch=mock.Mock(display_name='lp:~foo/bar/bjorn')) | ||
319 | 117 | ] | ||
320 | 118 | two_days = datetime.datetime.strftime( | ||
321 | 119 | TWO_DAYS, '%Y-%m-%dT%H:%M:%S') | ||
322 | 120 | yesterday = datetime.datetime.strftime( | ||
323 | 121 | YESTERDAY, '%Y-%m-%dT%H:%M:%S') | ||
324 | 122 | entries = [ | ||
325 | 123 | {'whatchanged': 'branch linked', | ||
326 | 124 | 'newvalue': 'lp:~foo/bar/baz', | ||
327 | 125 | 'datechanged': yesterday}, | ||
328 | 126 | {'whatchanged': 'branch linked', | ||
329 | 127 | 'newvalue': 'lp:~foo/bar/bjorn', | ||
330 | 128 | 'datechanged': two_days}] | ||
331 | 129 | latency = calculate_task_latency( | ||
332 | 130 | get_mock_task( | ||
333 | 131 | True, entries=entries, linked_branches=linked_branches), NOW) | ||
334 | 132 | self.assertEqual(60 * 60 * 24, int(latency)) | ||
335 | 133 | |||
336 | 134 | def test_calculate_task_latency_bug_with_one_link(self): | ||
337 | 135 | date_changed = datetime.datetime.strftime( | ||
338 | 136 | TWO_DAYS, '%Y-%m-%dT%H:%M:%S') | ||
339 | 137 | entries = [{'whatchanged': 'branch linked', | ||
340 | 138 | 'newvalue': 'lp:~foo/bar/baz', | ||
341 | 139 | 'datechanged': date_changed}] | ||
342 | 140 | latency = calculate_task_latency( | ||
343 | 141 | get_mock_task(True, entries=entries), NOW) | ||
344 | 142 | self.assertEqual(60 * 60 * 24, int(latency)) | ||
345 | 143 | |||
346 | 144 | def test_calculate_proposal_latency(self): | ||
347 | 145 | latency = calculate_proposal_latency(get_mock_proposal(True), NOW) | ||
348 | 146 | self.assertEqual(60 * 60 * 24, int(latency)) | ||
349 | 147 | |||
350 | 148 | def test_review_job_saves_latency(self): | ||
351 | 88 | log = logging.getLogger('foo') | 149 | log = logging.getLogger('foo') |
352 | 89 | self.assertEqual(0, self.db.review_queue_latency.count()) | 150 | self.assertEqual(0, self.db.review_queue_latency.count()) |
354 | 90 | update_review_queue(self.db, [], [MockProposal(True)], log) | 151 | update_review_queue(self.db, [], [get_mock_proposal(True)], log) |
355 | 91 | self.assertEqual(1, self.db.review_queue_latency.count()) | 152 | self.assertEqual(1, self.db.review_queue_latency.count()) |
356 | 92 | item = self.db.review_queue_latency.find_one() | 153 | item = self.db.review_queue_latency.find_one() |
357 | 93 | self.assertEqual(NOW.date(), item['date'].date()) | 154 | self.assertEqual(NOW.date(), item['date'].date()) |
358 | @@ -96,14 +157,14 @@ | |||
359 | 96 | self.assertEqual(1, datetime.timedelta(seconds=item['min']).days) | 157 | self.assertEqual(1, datetime.timedelta(seconds=item['min']).days) |
360 | 97 | 158 | ||
361 | 98 | def test_review_discards_closed_bugs(self): | 159 | def test_review_discards_closed_bugs(self): |
363 | 99 | tasks = [MockTask(), MockTask()] | 160 | tasks = [get_mock_task(), get_mock_task()] |
364 | 100 | tasks[0].status = 'Fix released' | 161 | tasks[0].status = 'Fix released' |
365 | 101 | log = logging.getLogger('foo') | 162 | log = logging.getLogger('foo') |
366 | 102 | update_review_queue(self.db, tasks, [], log) | 163 | update_review_queue(self.db, tasks, [], log) |
367 | 103 | self.assertEqual(1, self.db.review_queue.count()) | 164 | self.assertEqual(1, self.db.review_queue.count()) |
368 | 104 | 165 | ||
369 | 105 | def test_review_discards_approved_proposals(self): | 166 | def test_review_discards_approved_proposals(self): |
371 | 106 | proposals = [MockProposal(), MockProposal()] | 167 | proposals = [get_mock_proposal(), get_mock_proposal()] |
372 | 107 | proposals[0].queue_status = 'Approved' | 168 | proposals[0].queue_status = 'Approved' |
373 | 108 | log = logging.getLogger('foo') | 169 | log = logging.getLogger('foo') |
374 | 109 | update_review_queue(self.db, [], proposals, log) | 170 | update_review_queue(self.db, [], proposals, log) |
Looks good to me.