~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/bugs/doc/bugtask-expiration.txt

  • Committer: Julian Edwards
  • Date: 2011-07-28 20:46:18 UTC
  • mfrom: (13553 devel)
  • mto: This revision was merged to the branch mainline in revision 13555.
  • Revision ID: julian.edwards@canonical.com-20110728204618-tivj2wx2oa9s32bx
merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
Bugtask Expiration
2
 
==================
 
1
= Bugtask Expiration =
3
2
 
4
3
Old unattended Incomplete bugtasks clutter the search results of
5
4
Launchpad Bugs making the bug staff's job difficult. A script is run
22
21
all the rules stated above.
23
22
 
24
23
 
25
 
findExpirableBugTasks() Part 1
26
 
------------------------------
 
24
== findExpirableBugTasks() Part 1 ==
27
25
 
28
26
BugTaskSet provides findExpirableBugTasks() to find bugtasks that
29
27
qualify for expiration. The bugtasks must must meet all the
52
50
    >>> expirable_bugtasks.count()
53
51
    0
54
52
 
55
 
We need a function to reset the last_modified date of a bug because
56
 
setPrivate() now publishes an object modified event which will cause the
57
 
date_last_modified to be set to 'now'. We require some bugs used in this test
58
 
to be last modified in the past.
59
 
 
60
 
    >>> def reset_bug_modified_date(bug, days_ago):
61
 
    ...     from datetime import datetime, timedelta
62
 
    ...     import pytz
63
 
    ...     UTC = pytz.timezone('UTC')
64
 
    ...     date_modified = datetime.now(UTC) - timedelta(days=days_ago)
65
 
    ...     bug.date_last_updated = date_modified
66
 
 
67
 
 
68
 
Setup
69
 
-----
 
53
 
 
54
== Setup ==
70
55
 
71
56
Let's make some bugtasks that qualify for expiration. A Jokosher
72
57
bugtask and a conjoined pair of ubuntu_hoary and ubuntu bugtasks
101
86
    # An expirable bugtask, a distroseries. The ubuntu bugtask is its
102
87
    # conjoined slave.
103
88
    >>> hoary_bugtask = bugtaskset.createTask(
104
 
    ...     ubuntu_bugtask.bug, sample_person, ubuntu.currentseries)
 
89
    ...     bug=ubuntu_bugtask.bug, owner=sample_person,
 
90
    ...     distroseries=ubuntu.currentseries)
105
91
    >>> ubuntu_bugtask.conjoined_master == hoary_bugtask
106
92
    True
107
93
    >>> ubuntu_bugtask.bug.permits_expiration
134
120
    # This one's status is New.
135
121
    >>> thunderbird = getUtility(IProductSet).getByName('thunderbird')
136
122
    >>> new_bugtask = bugtaskset.createTask(
137
 
    ...     ubuntu_bugtask.bug, sample_person, thunderbird)
 
123
    ...     bug=ubuntu_bugtask.bug, owner=sample_person,
 
124
    ...     product=thunderbird)
138
125
    >>> new_bugtask.status.title
139
126
    'New'
140
127
    >>> new_bugtask.bug.permits_expiration
158
145
    >>> another_assigned_bugtask.transitionToTarget(ubuntu_alsa)
159
146
    >>> ubuntu_evolution = ubuntu.getSourcePackage('evolution')
160
147
    >>> invalid_bugtask = bugtaskset.createTask(
161
 
    ...     another_assigned_bugtask.bug, sample_person, ubuntu_evolution,
 
148
    ...     bug=another_assigned_bugtask.bug, owner=sample_person,
 
149
    ...     distribution=ubuntu,
 
150
    ...     sourcepackagename=ubuntu_evolution.sourcepackagename,
162
151
    ...     status=BugTaskStatus.INVALID)
163
152
    >>> another_assigned_bugtask.bug.permits_expiration
164
153
    True
244
233
    recent           False    31  Incomplete  False     False  False  False
245
234
    no_expire        False    61  Incomplete  False     False  False  False
246
235
 
247
 
isExpirable()
248
 
-------------
 
236
== isExpirable() ==
249
237
 
250
238
In addition to can_expire bugs have an isExpirable method to which a custom
251
239
number of days, days_old, can be passed.  days_old is then used with
261
249
    >>> very_old_bugtask.transitionToStatus(
262
250
    ...     BugTaskStatus.INVALID, sample_person)
263
251
 
264
 
    # Pass isExpirable() a days_old parameter, then set the bug to Invalid so
265
 
    # it doesn't affect the rest of the doctest.
 
252
    # Pass isExpirable() a days_old parameter, then set the bug to Invalid so it
 
253
    # doesn't affect the rest of the doctest
266
254
    >>> from lp.bugs.tests.bug import create_old_bug
267
255
    >>> not_so_old_bugtask = create_old_bug('expirable_distro', 31, ubuntu)
268
256
    >>> not_so_old_bugtask.bug.isExpirable(days_old=14)
271
259
    ...     BugTaskStatus.INVALID, sample_person)
272
260
 
273
261
 
274
 
findExpirableBugTasks() Part 2
275
 
------------------------------
 
262
== findExpirableBugTasks() Part 2 ==
276
263
 
277
264
The value of the min_days_old controls the bugtasks that are
278
265
returned. The oldest bug in this test is 351 days old, the youngest is
381
368
    ROLE         EXPIRE  AGE  STATUS      ASSIGNED  DUP    MILE   REPLIES
382
369
 
383
370
 
384
 
Privacy
385
 
-------
 
371
== Privacy ==
386
372
 
387
373
The user parameter indicates which user is performing the search. Only
388
374
bugs that the user has permission to view are returned. A value of None
396
382
 
397
383
If one of the bugs is set to private, anonymous users can no longer see
398
384
it as being marked for expiration.
399
 
We need a feature flag so that multi-pillar bugs can be made private.
400
 
 
401
 
    >>> from lp.services.features.testing import FeatureFixture
402
 
    >>> feature_flag = {
403
 
    ...     'disclosure.allow_multipillar_private_bugs.enabled': 'on'}
404
 
    >>> flags = FeatureFixture(feature_flag)
405
 
    >>> flags.setUp()
406
385
 
407
386
    >>> private_bug = ubuntu_bugtask.bug
408
387
    >>> private_bug.title
409
388
    u'expirable_distro'
410
389
    >>> private_bug.setPrivate(True, sample_person)
411
390
    True
412
 
    >>> reset_bug_modified_date(private_bug, 351)
413
391
 
414
392
    >>> expirable_bugtasks = bugtaskset.findExpirableBugTasks(
415
393
    ...     0, user=None, target=ubuntu)
431
409
 
432
410
    >>> private_bug.subscribe(no_priv, sample_person)
433
411
    <lp.bugs.model.bugsubscription.BugSubscription ...>
434
 
    >>> reset_bug_modified_date(private_bug, 351)
435
412
    >>> expirable_bugtasks = bugtaskset.findExpirableBugTasks(
436
413
    ...     0, user=no_priv, target=ubuntu)
437
414
    >>> visible_bugs = set(bugtask.bug for bugtask in expirable_bugtasks)
455
432
 
456
433
    >>> private_bug.setPrivate(False, sample_person)
457
434
    True
458
 
    >>> reset_bug_modified_date(private_bug, 351)
459
 
 
460
 
Clean up the feature flag.
461
 
    >>> flags.cleanUp()
462
 
 
463
 
 
464
 
The default expiration age
465
 
--------------------------
 
435
 
 
436
 
 
437
== The default expiration age ==
466
438
 
467
439
The expiration age is set using the
468
440
config.malone.days_before_expiration configuration variable. It
476
448
    60
477
449
 
478
450
 
479
 
Running the script
480
 
------------------
 
451
== Running the script ==
481
452
 
482
453
There are no Expired Bugtasks in sampledata, from the tests above.
483
454
 
522
493
    >>> bugtasks = [BugTask.get(bugtask.id) for bugtask in bugtasks]
523
494
 
524
495
 
525
 
After the script has run
526
 
------------------------
 
496
== After the script has run ==
527
497
 
528
498
There are three Expired bugtasks. Jokosher, hoary and ubuntu were
529
499
expired by the expiration process. Although ubuntu was never returned
545
515
    recent           False    31  Incomplete  False     False  False  False
546
516
    no_expire        False    61  Incomplete  False     False  False  False
547
517
 
 
518
The bugtasks statusexplanation was updated to explain the change in
 
519
status.
 
520
 
 
521
    >>> hoary_bugtask = BugTask.get(hoary_bugtask.id)
 
522
    >>> print hoary_bugtask.statusexplanation
 
523
    [Expired for Ubuntu Hoary because there has been no activity for 60 days.]
 
524
 
548
525
The message explaining the reason for the expiration was posted by the
549
526
Launchpad Janitor celebrity. Only one message was created for when the
550
527
master and slave bugtasks were expired.
570
547
    Launchpad Janitor  Ubuntu Hoary: status  Incomplete  Expired
571
548
 
572
549
 
573
 
enable_bug_expiration
574
 
---------------------
 
550
== enable_bug_expiration ==
575
551
 
576
552
The bugtask no_expiration_bugtask has not been expired because it does
577
553
not participate in bug expiration. When uses_bug_expiration is set to