~launchpad-pqm/launchpad/devel

3691.196.2 by kiko
Implement tests that I had omitted the last cycle, and factor the Issuezilla/Bugzilla-other tests into separate classes and a separate doctest.
1
ExternalBugTracker: Issuezilla and other Freaks
2
===============================================
3
4
Bugzilla has a few variants out there in the wild, and we work hard to
5
support them all.
6
7
Issuezilla
8
----------
9
10
We support Issuezilla-style trackers. These trackers are essentially
11
modified (ancient) versions of Bugzilla; their XML elements have
11304.1.17 by Bryce Harrington
Issuezilla appears to have only a priority field, not severity
12
slightly different names, and they lack the severity field. We pretend
13
Mozilla's Bugzilla is an Issuezilla instance here:
3691.196.2 by kiko
Implement tests that I had omitted the last cycle, and factor the Issuezilla/Bugzilla-other tests into separate classes and a separate doctest.
14
11692.6.2 by Curtis Hovey
Use deglober to fixing simple glob imports in doctests.
15
    >>> from lp.bugs.interfaces.bugtracker import IBugTrackerSet
3691.196.2 by kiko
Implement tests that I had omitted the last cycle, and factor the Issuezilla/Bugzilla-other tests into separate classes and a separate doctest.
16
14604.1.1 by Curtis Hovey
Separate test-authoring classes from test-running classes.
17
    >>> from lp.testing.layers import LaunchpadZopelessLayer
11716.1.12 by Curtis Hovey
Sorted imports in doctests.
18
    >>> from lp.bugs.scripts.checkwatches import CheckwatchesMaster
8523.3.1 by Gavin Panella
Bugs tree reorg after automated migration.
19
    >>> from lp.bugs.tests.externalbugtracker import TestIssuezilla
5325.1.2 by Tom Berger
post review changes
20
    >>> txn = LaunchpadZopelessLayer.txn
3691.196.2 by kiko
Implement tests that I had omitted the last cycle, and factor the Issuezilla/Bugzilla-other tests into separate classes and a separate doctest.
21
    >>> mozilla_bugzilla = getUtility(IBugTrackerSet).getByName('mozilla.org')
5816.1.1 by Bjorn Tillenius
Make ExternalBugTracker accept a URL instead of a transaction and bug tracker.
22
    >>> issuezilla = TestIssuezilla(mozilla_bugzilla.baseurl)
3691.196.2 by kiko
Implement tests that I had omitted the last cycle, and factor the Issuezilla/Bugzilla-other tests into separate classes and a separate doctest.
23
    >>> issuezilla._probe_version()
4810.11.6 by Graham Binns
Bugzilla tests now pass.
24
    (2, 11)
3691.196.2 by kiko
Implement tests that I had omitted the last cycle, and factor the Issuezilla/Bugzilla-other tests into separate classes and a separate doctest.
25
    >>> for bug_watch in mozilla_bugzilla.watches:
11304.1.9 by Bryce Harrington
Add values for priority and severity to sample data in various places
26
    ...     print "%s: %s %s" % (bug_watch.remotebug,
27
    ...         bug_watch.remotestatus, bug_watch.remote_importance)
12221.1.7 by Jeroen Vermeulen
s/Unparseable/Unparsable/g, plus lint.
28
    2000:
29
    123543:
11304.1.9 by Bryce Harrington
Add values for priority and severity to sample data in various places
30
    42: FUBAR BAZBAZ
31
    42: FUBAR BAZBAZ
10512.4.24 by Gavin Panella
Get all the externalbugtracker*.txt doctests passing.
32
    >>> transaction.commit()
10694.2.25 by Graham Binns
Renamed BugWatchUpdater -> CheckwatchesMaster. This is the wrong name for it, but I did it to avoid bikeshedding.
33
    >>> bug_watch_updater = CheckwatchesMaster(txn)
5626.5.2 by Bjorn Tillenius
move ExternalBugtracker.updateBugWatches() to BugWatchUpdater.updateBugWatches(). Debbugs.importBugComments() is now broken, though.
34
    >>> bug_watch_updater.updateBugWatches(
35
    ...     issuezilla, mozilla_bugzilla.watches)
7910.2.7 by Graham Binns
Updated checkwatches tests to deal with logging output changes.
36
    INFO:...:Updating 4 watches for 3 bugs on https://bugzilla.mozilla.org
12392.6.5 by William Grant
Log InvalidBugId, BugNotFound and PrivateRemoteBug at INFO, and update tests to cope.
37
    INFO:...:Didn't find bug u'42' on https://bugzilla.mozilla.org
38
    (local bugs: 1, 2).
10512.3.1 by Abel Deuring
log an OOPS earlier, before marking watches as 'checked' when an error occurs in BuGWatchUpdater.updateBugWatches(). Also, record an OOPS ID in log warnings.
39
3691.196.2 by kiko
Implement tests that I had omitted the last cycle, and factor the Issuezilla/Bugzilla-other tests into separate classes and a separate doctest.
40
    >>> for bug_watch in mozilla_bugzilla.watches:
11304.1.9 by Bryce Harrington
Add values for priority and severity to sample data in various places
41
    ...     print "%s: %s %s" % (bug_watch.remotebug,
42
    ...         bug_watch.remotestatus, bug_watch.remote_importance)
11304.1.17 by Bryce Harrington
Issuezilla appears to have only a priority field, not severity
43
    2000: RESOLVED FIXED LOW
11304.1.18 by Bryce Harrington
Further handling of IssueZilla's lack of severity field
44
    123543: ASSIGNED HIGH
11304.1.9 by Bryce Harrington
Add values for priority and severity to sample data in various places
45
    42: FUBAR BAZBAZ
46
    42: FUBAR BAZBAZ
3691.196.2 by kiko
Implement tests that I had omitted the last cycle, and factor the Issuezilla/Bugzilla-other tests into separate classes and a separate doctest.
47
48
49
Bugzilla prior to 2.11
50
----------------------
51
52
Old-style Bugzillas are quite similar to Issuezilla. Again we pretend
53
Mozilla.org's using this old version. Here's the scoop:
54
8523.3.1 by Gavin Panella
Bugs tree reorg after automated migration.
55
    >>> from lp.bugs.tests.externalbugtracker import TestOldBugzilla
5816.1.1 by Bjorn Tillenius
Make ExternalBugTracker accept a URL instead of a transaction and bug tracker.
56
    >>> old_bugzilla = TestOldBugzilla(mozilla_bugzilla.baseurl)
3691.196.2 by kiko
Implement tests that I had omitted the last cycle, and factor the Issuezilla/Bugzilla-other tests into separate classes and a separate doctest.
57
58
  a) The version is way old:
59
60
    >>> old_bugzilla._probe_version()
4810.11.6 by Graham Binns
Bugzilla tests now pass.
61
    (2, 10)
3691.196.2 by kiko
Implement tests that I had omitted the last cycle, and factor the Issuezilla/Bugzilla-other tests into separate classes and a separate doctest.
62
63
  b) The tags are not prefixed with the bz: namespace:
64
65
    >>> bug_item_file = old_bugzilla._readBugItemFile()
66
    >>> "<bug_status>" in bug_item_file
67
    True
68
    >>> "<bug_id>" in bug_item_file
69
    True
70
71
We support them just fine:
72
5855.4.16 by Bjorn Tillenius
fix test failures.
73
    >>> remote_bugs = ['42', '123543']
74
    >>> old_bugzilla.initializeRemoteBugDB(remote_bugs)
75
    >>> for remote_bug in remote_bugs:
11304.1.9 by Bryce Harrington
Add values for priority and severity to sample data in various places
76
    ...     print "%s: %s %s" % (
77
    ...         remote_bug,
11304.1.22 by Bryce Harrington
Cleanup a heapload of lint errors
78
    ...         old_bugzilla.getRemoteStatus(remote_bug),
11304.1.9 by Bryce Harrington
Add values for priority and severity to sample data in various places
79
    ...         old_bugzilla.getRemoteImportance(remote_bug))
11304.1.15 by Bryce Harrington
Replace stubbed out data from test with "actual" data
80
    42: RESOLVED FIXED LOW BLOCKER
11304.1.16 by Bryce Harrington
Fill in more actual values in tests now that they're hooked up
81
    123543: ASSIGNED HIGH BLOCKER
3691.196.2 by kiko
Implement tests that I had omitted the last cycle, and factor the Issuezilla/Bugzilla-other tests into separate classes and a separate doctest.
82
83
84
Bugzilla oddities
85
-----------------
86
87
Some Bugzillas have some weird properties that we need to cater for:
88
8523.3.1 by Gavin Panella
Bugs tree reorg after automated migration.
89
    >>> from lp.bugs.tests.externalbugtracker import (
4953.4.2 by Bjorn Tillenius
make ExternalBugTracker accept a 'bugtracker' argument instead of 'baseurl'.
90
    ...     TestWeirdBugzilla)
5816.1.1 by Bjorn Tillenius
Make ExternalBugTracker accept a URL instead of a transaction and bug tracker.
91
    >>> weird_bugzilla = TestWeirdBugzilla(mozilla_bugzilla.baseurl)
3691.196.2 by kiko
Implement tests that I had omitted the last cycle, and factor the Issuezilla/Bugzilla-other tests into separate classes and a separate doctest.
92
    >>> weird_bugzilla._probe_version()
4810.11.6 by Graham Binns
Bugzilla tests now pass.
93
    (2, 20)
3691.196.2 by kiko
Implement tests that I had omitted the last cycle, and factor the Issuezilla/Bugzilla-other tests into separate classes and a separate doctest.
94
95
  a) The bug status tag is <bz:status> and not <bz:bug_status>
96
97
    >>> bug_item_file = weird_bugzilla._readBugItemFile()
98
    >>> "<bz:status>" in bug_item_file
99
    True
100
101
  b) The content is non-ascii:
102
103
    >>> bug_item_file.decode("ascii")
104
    Traceback (most recent call last):
105
    ...
106
    UnicodeDecodeError: 'ascii' codec can't decode byte...
107
108
Yet everything still works as expected:
109
5855.4.16 by Bjorn Tillenius
fix test failures.
110
    >>> remote_bugs = ['2000', '123543']
111
    >>> weird_bugzilla.initializeRemoteBugDB(remote_bugs)
112
    >>> for remote_bug in remote_bugs:
11304.1.9 by Bryce Harrington
Add values for priority and severity to sample data in various places
113
    ...     print "%s: %s %s" % (
114
    ...         remote_bug,
115
    ...         weird_bugzilla.getRemoteStatus(remote_bug),
116
    ...         weird_bugzilla.getRemoteImportance(remote_bug))
11304.1.16 by Bryce Harrington
Fill in more actual values in tests now that they're hooked up
117
    2000: ASSIGNED HIGH BLOCKER
118
    123543: RESOLVED FIXED HIGH BLOCKER
3691.196.2 by kiko
Implement tests that I had omitted the last cycle, and factor the Issuezilla/Bugzilla-other tests into separate classes and a separate doctest.
119
120
121
Broken Bugzillas
122
----------------
123
124
What does /not/ work as expected is parsing Bugzillas which produce
125
invalid XML:
126
8523.3.1 by Gavin Panella
Bugs tree reorg after automated migration.
127
    >>> from lp.bugs.tests.externalbugtracker import (
4953.4.2 by Bjorn Tillenius
make ExternalBugTracker accept a 'bugtracker' argument instead of 'baseurl'.
128
    ...     TestBrokenBugzilla)
5816.1.1 by Bjorn Tillenius
Make ExternalBugTracker accept a URL instead of a transaction and bug tracker.
129
    >>> broken_bugzilla = TestBrokenBugzilla(mozilla_bugzilla.baseurl)
3691.196.2 by kiko
Implement tests that I had omitted the last cycle, and factor the Issuezilla/Bugzilla-other tests into separate classes and a separate doctest.
130
    >>> broken_bugzilla._probe_version()
4810.11.6 by Graham Binns
Bugzilla tests now pass.
131
    (2, 20)
3691.196.2 by kiko
Implement tests that I had omitted the last cycle, and factor the Issuezilla/Bugzilla-other tests into separate classes and a separate doctest.
132
    >>> "</foobar>" in broken_bugzilla._readBugItemFile()
133
    True
5855.4.16 by Bjorn Tillenius
fix test failures.
134
135
    >>> remote_bugs = ['42', '2000']
136
    >>> broken_bugzilla.initializeRemoteBugDB(remote_bugs)
3691.196.2 by kiko
Implement tests that I had omitted the last cycle, and factor the Issuezilla/Bugzilla-other tests into separate classes and a separate doctest.
137
    Traceback (most recent call last):
138
    ...
12221.1.7 by Jeroen Vermeulen
s/Unparseable/Unparsable/g, plus lint.
139
    UnparsableBugData: Failed to parse XML description...
3691.196.2 by kiko
Implement tests that I had omitted the last cycle, and factor the Issuezilla/Bugzilla-other tests into separate classes and a separate doctest.
140
13184.1.1 by Benji York
make bugzilla import ignore ASCII control characters
141
However, embedded control characters do not generate errors.
142
143
    >>> from lp.bugs.tests.externalbugtracker import (
144
    ...     AnotherBrokenBugzilla)
145
    >>> broken_bugzilla = AnotherBrokenBugzilla(mozilla_bugzilla.baseurl)
146
    >>> r"NOT\x01USED" in repr(broken_bugzilla._readBugItemFile())
147
    True
148
149
    >>> remote_bugs = ['42', '2000']
150
    >>> broken_bugzilla.initializeRemoteBugDB(remote_bugs) # no exception