~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/bugs/doc/externalbugtracker-linking-back.txt

  • Committer: Launchpad Patch Queue Manager
  • Date: 2011-12-22 04:55:30 UTC
  • mfrom: (14577.1.1 testfix)
  • Revision ID: launchpad@pqm.canonical.com-20111222045530-wki9iu6c0ysqqwkx
[r=wgrant][no-qa] Fix test_publisherconfig lpstorm import. Probably a
        silent conflict between megalint and apocalypse.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
= Remote bugs linking back to Launchpad =
 
2
 
 
3
Some bug trackers support linking back to bugs in Launchpad. This way we
 
4
can tell external bug trackers that we're watching the bug, and make it
 
5
easier to users of the external bug tracker to get more information
 
6
about the bug.
 
7
 
 
8
    >>> from zope.interface import implements
 
9
    >>> from lp.bugs.tests.externalbugtracker import (
 
10
    ...     TestExternalBugTracker)
 
11
    >>> from lp.bugs.interfaces.externalbugtracker import (
 
12
    ...     ISupportsBackLinking)
 
13
 
 
14
    >>> class BackLinkingExternalBugTracker(TestExternalBugTracker):
 
15
    ...     implements(ISupportsBackLinking)
 
16
    ...
 
17
    ...     def __init__(self, baseurl):
 
18
    ...         super(BackLinkingExternalBugTracker, self).__init__(baseurl)
 
19
    ...         self.last_launchpad_bug_id = None
 
20
    ...
 
21
    ...     def getLaunchpadBugId(self, remote_bug):
 
22
    ...         print "Getting Launchpad id for bug %s" % remote_bug
 
23
    ...         return self.last_launchpad_bug_id
 
24
    ...
 
25
    ...     def setLaunchpadBugId(self, remote_bug, launchpad_bug_id,
 
26
    ...                           launchpad_bug_url):
 
27
    ...         self.last_launchpad_bug_id = launchpad_bug_id
 
28
    ...         print "Setting Launchpad id for bug %s" % remote_bug
 
29
 
 
30
The methods are called by the CheckwatchesMaster class:
 
31
 
 
32
    >>> from canonical.testing.layers import LaunchpadZopelessLayer
 
33
    >>> txn = transaction
 
34
 
 
35
    >>> LaunchpadZopelessLayer.switchDbUser('launchpad')
 
36
 
 
37
    >>> bug_watch = factory.makeBugWatch('42')
 
38
    >>> bug_watch.bug.default_bugtask.bugwatch = bug_watch
 
39
    >>> bug_watch_2 = factory.makeBugWatch('42', bug_watch.bugtracker)
 
40
    >>> bug_watch_2.bug.default_bugtask.bugwatch = bug_watch_2
 
41
    >>> bug_watch_without_bugtask = (
 
42
    ...     factory.makeBugWatch('42', bug_watch.bugtracker))
 
43
 
 
44
    >>> unlinked_bug = factory.makeBug()
 
45
 
 
46
    >>> txn.commit()
 
47
    >>> LaunchpadZopelessLayer.switchDbUser('checkwatches')
 
48
 
 
49
    >>> from lp.bugs.scripts.checkwatches import CheckwatchesMaster
 
50
    >>> checkwatches_master = CheckwatchesMaster(txn)
 
51
    >>> txn.commit()
 
52
 
 
53
    >>> external_bugtracker = BackLinkingExternalBugTracker(
 
54
    ...     'http://example.com/')
 
55
 
 
56
    >>> checkwatches_master.updateBugWatches(external_bugtracker, [bug_watch])
 
57
    Getting Launchpad id for bug 42
 
58
    Setting Launchpad id for bug 42
 
59
 
 
60
    >>> external_bugtracker.last_launchpad_bug_id == bug_watch.bug.id
 
61
    True
 
62
 
 
63
For comment syncing and back-linking to be attempted, bug watches must
 
64
be related to a bug task, not just a bug.
 
65
 
 
66
    >>> checkwatches_master.updateBugWatches(
 
67
    ...     external_bugtracker, [bug_watch_without_bugtask])
 
68
 
 
69
 
 
70
== BugWatchUpdater.linkLaunchpadBug() ==
 
71
 
 
72
The BugWatchUpdater method that does the work of setting the Launchpad
 
73
bug link is linkLaunchpadBug(). This method first retrieves the
 
74
current Launchpad bug ID for the remote bug. If the remote bug is
 
75
already linked to a Launchpad bug other than the one that we're trying
 
76
to link it to, the BugWatchUpdater will check that the bug that is
 
77
already linked has a valid watch on the remote bug in question. If it
 
78
does, the link will remain unchanged. Otherwise it will be updated.
 
79
 
 
80
Bug 42 on the remote bug tracker is linked to using bug_watch.
 
81
 
 
82
    >>> external_bugtracker.last_launchpad_bug_id == bug_watch.bug.id
 
83
    True
 
84
 
 
85
Trying to link another bug to it will have no effect since the bug that
 
86
is currently linked has a valid bug watch. Only getLaunchpadBugId() will
 
87
be called on our BackLinkingExternalBugTracker.
 
88
 
 
89
    >>> bug_watch.bug.id == bug_watch_2.bug.id
 
90
    False
 
91
 
 
92
    >>> transaction.commit()
 
93
 
 
94
    >>> from lp.bugs.scripts.checkwatches.core import CheckwatchesMaster
 
95
    >>> from lp.bugs.scripts.checkwatches.tests.test_bugwatchupdater import (
 
96
    ...     make_bug_watch_updater)
 
97
 
 
98
    >>> bug_watch_updater = make_bug_watch_updater(
 
99
    ...     CheckwatchesMaster(transaction), bug_watch,
 
100
    ...     external_bugtracker)
 
101
    >>> bug_watch_updater.linkLaunchpadBug()
 
102
    Getting Launchpad id for bug 42
 
103
 
 
104
However, if we set the current Launchpad bug ID on our
 
105
BackLinkingExternalBugTracker to a Launchpad bug that doesn't link to
 
106
the remote bug, BugWatchUpdater.linkLaunchpadBug() will call
 
107
getLaunchpadBugId() and then, when it discovers that the current
 
108
Launchpad bug ID isn't valid, setLaunchpadBugId() to correct the error.
 
109
 
 
110
unlinked_bug doesn't link to bug 42 on the remote bug tracker.
 
111
 
 
112
    >>> print unlinked_bug.getBugWatch(
 
113
    ...     bug_watch.bugtracker, bug_watch.remotebug)
 
114
    None
 
115
 
 
116
However, the remote bug currently thinks that unlinked_bug does in
 
117
fact link to it.
 
118
 
 
119
    >>> external_bugtracker.last_launchpad_bug_id = unlinked_bug.id
 
120
 
 
121
Calling linkLaunchpadBug() with a bug watch that actually does link to
 
122
bug 42 will correct the error.
 
123
 
 
124
    >>> transaction.commit()
 
125
 
 
126
    >>> bug_watch_updater.linkLaunchpadBug()
 
127
    Getting Launchpad id for bug 42
 
128
    Setting Launchpad id for bug 42
 
129
 
 
130
linkLaunchpadBug() will also handle cases where the current Launchpad
 
131
bug ID for a remote bug references a Launchpad bug that doesn't exist.
 
132
The remote bug's Launchpad bug ID will be overwritten to correct the
 
133
error.
 
134
 
 
135
    >>> external_bugtracker.last_launchpad_bug_id = 0
 
136
    >>> bug_watch_updater.linkLaunchpadBug()
 
137
    Getting Launchpad id for bug 42
 
138
    Setting Launchpad id for bug 42