/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_bugtracker.py

  • Committer: Vincent Ladeuil
  • Date: 2012-01-18 14:09:19 UTC
  • mto: This revision was merged to the branch mainline in revision 6468.
  • Revision ID: v.ladeuil+lp@free.fr-20120118140919-rlvdrhpc0nq1lbwi
Change set/remove to require a lock for the branch config files.

This means that tests (or any plugin for that matter) do not requires an
explicit lock on the branch anymore to change a single option. This also
means the optimisation becomes "opt-in" and as such won't be as
spectacular as it may be and/or harder to get right (nothing fails
anymore).

This reduces the diff by ~300 lines.

Code/tests that were updating more than one config option is still taking
a lock to at least avoid some IOs and demonstrate the benefits through
the decreased number of hpss calls.

The duplication between BranchStack and BranchOnlyStack will be removed
once the same sharing is in place for local config files, at which point
the Stack class itself may be able to host the changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2007-2010 Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
 
17
 
 
18
from bzrlib import bugtracker, errors, urlutils
 
19
from bzrlib.tests import TestCase, TestCaseWithMemoryTransport
 
20
 
 
21
 
 
22
class TestGetBugURL(TestCaseWithMemoryTransport):
 
23
    """Tests for bugtracker.get_bug_url"""
 
24
 
 
25
    class TransientTracker(object):
 
26
        """An transient tracker used for testing."""
 
27
 
 
28
        @classmethod
 
29
        def get(klass, abbreviation, branch):
 
30
            klass.log.append(('get', abbreviation, branch))
 
31
            if abbreviation != 'transient':
 
32
                return None
 
33
            return klass()
 
34
 
 
35
        def get_bug_url(self, bug_id):
 
36
            self.log.append(('get_bug_url', bug_id))
 
37
            return "http://bugs.com/%s" % bug_id
 
38
 
 
39
    def setUp(self):
 
40
        TestCaseWithMemoryTransport.setUp(self)
 
41
        self.tracker_type = TestGetBugURL.TransientTracker
 
42
        self.tracker_type.log = []
 
43
        bugtracker.tracker_registry.register('transient', self.tracker_type)
 
44
        self.addCleanup(bugtracker.tracker_registry.remove, 'transient')
 
45
 
 
46
    def test_get_bug_url_for_transient_tracker(self):
 
47
        branch = self.make_branch('some_branch')
 
48
        self.assertEqual('http://bugs.com/1234',
 
49
                         bugtracker.get_bug_url('transient', branch, '1234'))
 
50
        self.assertEqual(
 
51
            [('get', 'transient', branch), ('get_bug_url', '1234')],
 
52
            self.tracker_type.log)
 
53
 
 
54
    def test_unrecognized_abbreviation_raises_error(self):
 
55
        """If the abbreviation is unrecognized, then raise an error."""
 
56
        branch = self.make_branch('some_branch')
 
57
        self.assertRaises(errors.UnknownBugTrackerAbbreviation,
 
58
                          bugtracker.get_bug_url, 'xxx', branch, '1234')
 
59
        self.assertEqual([('get', 'xxx', branch)], self.tracker_type.log)
 
60
 
 
61
 
 
62
class TestBuiltinTrackers(TestCaseWithMemoryTransport):
 
63
    """Test that the builtin trackers are registered and return sane URLs."""
 
64
 
 
65
    def test_launchpad_registered(self):
 
66
        """The Launchpad bug tracker should be registered by default and
 
67
        generate Launchpad bug page URLs.
 
68
        """
 
69
        branch = self.make_branch('some_branch')
 
70
        tracker = bugtracker.tracker_registry.get_tracker('lp', branch)
 
71
        self.assertEqual('https://launchpad.net/bugs/1234',
 
72
                         tracker.get_bug_url('1234'))
 
73
 
 
74
    def test_debian_registered(self):
 
75
        """The Debian bug tracker should be registered by default and generate
 
76
        bugs.debian.org bug page URLs.
 
77
        """
 
78
        branch = self.make_branch('some_branch')
 
79
        tracker = bugtracker.tracker_registry.get_tracker('deb', branch)
 
80
        self.assertEqual('http://bugs.debian.org/1234',
 
81
                         tracker.get_bug_url('1234'))
 
82
 
 
83
    def test_gnome_registered(self):
 
84
        branch = self.make_branch('some_branch')
 
85
        tracker = bugtracker.tracker_registry.get_tracker('gnome', branch)
 
86
        self.assertEqual('http://bugzilla.gnome.org/show_bug.cgi?id=1234',
 
87
                         tracker.get_bug_url('1234'))
 
88
 
 
89
    def test_trac_registered(self):
 
90
        """The Trac bug tracker should be registered by default and generate
 
91
        Trac bug page URLs when the appropriate configuration is present.
 
92
        """
 
93
        branch = self.make_branch('some_branch')
 
94
        config = branch.get_config()
 
95
        config.set_user_option('trac_foo_url', 'http://bugs.com/trac')
 
96
        tracker = bugtracker.tracker_registry.get_tracker('foo', branch)
 
97
        self.assertEqual('http://bugs.com/trac/ticket/1234',
 
98
                         tracker.get_bug_url('1234'))
 
99
 
 
100
    def test_bugzilla_registered(self):
 
101
        """The Bugzilla bug tracker should be registered by default and
 
102
        generate Bugzilla bug page URLs when the appropriate configuration is
 
103
        present.
 
104
        """
 
105
        branch = self.make_branch('some_branch')
 
106
        config = branch.get_config()
 
107
        config.set_user_option('bugzilla_foo_url', 'http://bugs.com')
 
108
        tracker = bugtracker.tracker_registry.get_tracker('foo', branch)
 
109
        self.assertEqual('http://bugs.com/show_bug.cgi?id=1234',
 
110
                         tracker.get_bug_url('1234'))
 
111
 
 
112
    def test_generic_registered(self):
 
113
        branch = self.make_branch('some_branch')
 
114
        config = branch.get_config()
 
115
        config.set_user_option('bugtracker_foo_url', 'http://bugs.com/{id}/view.html')
 
116
        tracker = bugtracker.tracker_registry.get_tracker('foo', branch)
 
117
        self.assertEqual('http://bugs.com/1234/view.html',
 
118
                         tracker.get_bug_url('1234'))
 
119
 
 
120
    def test_generic_registered_non_integer(self):
 
121
        branch = self.make_branch('some_branch')
 
122
        config = branch.get_config()
 
123
        config.set_user_option('bugtracker_foo_url', 'http://bugs.com/{id}/view.html')
 
124
        tracker = bugtracker.tracker_registry.get_tracker('foo', branch)
 
125
        self.assertEqual('http://bugs.com/ABC-1234/view.html',
 
126
                         tracker.get_bug_url('ABC-1234'))
 
127
 
 
128
    def test_generic_incorrect_url(self):
 
129
        branch = self.make_branch('some_branch')
 
130
        config = branch.get_config()
 
131
        config.set_user_option('bugtracker_foo_url', 'http://bugs.com/view.html')
 
132
        tracker = bugtracker.tracker_registry.get_tracker('foo', branch)
 
133
        self.assertRaises(errors.InvalidBugTrackerURL, tracker.get_bug_url, '1234')
 
134
 
 
135
 
 
136
class TestUniqueIntegerBugTracker(TestCaseWithMemoryTransport):
 
137
 
 
138
    def test_appends_id_to_base_url(self):
 
139
        """The URL of a bug is the base URL joined to the identifier."""
 
140
        tracker = bugtracker.UniqueIntegerBugTracker('xxx',
 
141
                'http://bugs.com/foo')
 
142
        self.assertEqual('http://bugs.com/foo1234', tracker.get_bug_url('1234'))
 
143
 
 
144
    def test_returns_tracker_if_abbreviation_matches(self):
 
145
        """The get() method should return an instance of the tracker if the
 
146
        given abbreviation matches the tracker's abbreviated name.
 
147
        """
 
148
        tracker = bugtracker.UniqueIntegerBugTracker('xxx',
 
149
                'http://bugs.com/')
 
150
        branch = self.make_branch('some_branch')
 
151
        self.assertIs(tracker, tracker.get('xxx', branch))
 
152
 
 
153
    def test_returns_none_if_abbreviation_doesnt_match(self):
 
154
        """The get() method should return None if the given abbreviated name
 
155
        doesn't match the tracker's abbreviation.
 
156
        """
 
157
        tracker = bugtracker.UniqueIntegerBugTracker('xxx',
 
158
                'http://bugs.com/')
 
159
        branch = self.make_branch('some_branch')
 
160
        self.assertIs(None, tracker.get('yyy', branch))
 
161
 
 
162
    def test_doesnt_consult_branch(self):
 
163
        """A UniqueIntegerBugTracker shouldn't consult the branch for tracker
 
164
        information.
 
165
        """
 
166
        tracker = bugtracker.UniqueIntegerBugTracker('xxx',
 
167
                'http://bugs.com/')
 
168
        self.assertIs(tracker, tracker.get('xxx', None))
 
169
        self.assertIs(None, tracker.get('yyy', None))
 
170
 
 
171
    def test_check_bug_id_only_accepts_integers(self):
 
172
        """A UniqueIntegerBugTracker accepts integers as bug IDs."""
 
173
        tracker = bugtracker.UniqueIntegerBugTracker('xxx',
 
174
                'http://bugs.com/')
 
175
        tracker.check_bug_id('1234')
 
176
 
 
177
    def test_check_bug_id_doesnt_accept_non_integers(self):
 
178
        """A UniqueIntegerBugTracker rejects non-integers as bug IDs."""
 
179
        tracker = bugtracker.UniqueIntegerBugTracker('xxx',
 
180
                'http://bugs.com/')
 
181
        self.assertRaises(
 
182
            errors.MalformedBugIdentifier, tracker.check_bug_id, 'red')
 
183
 
 
184
class TestURLParametrizedBugTracker(TestCaseWithMemoryTransport):
 
185
    """Tests for URLParametrizedBugTracker."""
 
186
 
 
187
    def setUp(self):
 
188
        TestCaseWithMemoryTransport.setUp(self)
 
189
        self.url = 'http://twistedmatrix.com/trac'
 
190
        self.tracker = bugtracker.URLParametrizedBugTracker('some', 'ticket/')
 
191
 
 
192
    def test_get_with_unsupported_tag(self):
 
193
        """If asked for an unrecognized or unconfigured tag, return None."""
 
194
        branch = self.make_branch('some_branch')
 
195
        self.assertEqual(None, self.tracker.get('lp', branch))
 
196
        self.assertEqual(None, self.tracker.get('twisted', branch))
 
197
 
 
198
    def test_get_with_supported_tag(self):
 
199
        """If asked for a valid tag, return a tracker instance that can map bug
 
200
        IDs to <base_url>/<bug_area> + <bug_id>."""
 
201
        bugtracker.tracker_registry.register('some', self.tracker)
 
202
        self.addCleanup(bugtracker.tracker_registry.remove, 'some')
 
203
 
 
204
        branch = self.make_branch('some_branch')
 
205
        config = branch.get_config()
 
206
        config.set_user_option('some_twisted_url', self.url)
 
207
        tracker = self.tracker.get('twisted', branch)
 
208
        self.assertEqual(
 
209
            urlutils.join(self.url, 'ticket/') + '1234',
 
210
            tracker.get_bug_url('1234'))
 
211
 
 
212
    def test_get_bug_url_for_integer_id(self):
 
213
        self.tracker.check_bug_id('1234')
 
214
 
 
215
    def test_get_bug_url_for_non_integer_id(self):
 
216
        self.tracker.check_bug_id('ABC-1234')
 
217
 
 
218
 
 
219
class TestURLParametrizedIntegerBugTracker(TestCaseWithMemoryTransport):
 
220
    """Tests for URLParametrizedIntegerBugTracker."""
 
221
 
 
222
    def setUp(self):
 
223
        TestCaseWithMemoryTransport.setUp(self)
 
224
        self.url = 'http://twistedmatrix.com/trac'
 
225
        self.tracker = bugtracker.URLParametrizedIntegerBugTracker('some',
 
226
                                                                   'ticket/')
 
227
 
 
228
    def test_get_bug_url_for_bad_bug(self):
 
229
        """When given a bug identifier that is invalid for Trac, get_bug_url
 
230
        should raise an error.
 
231
        """
 
232
        self.assertRaises(
 
233
            errors.MalformedBugIdentifier, self.tracker.get_bug_url, 'bad')
 
234
 
 
235
 
 
236
class TestPropertyEncoding(TestCase):
 
237
    """Tests for how the bug URLs are encoded as revision properties."""
 
238
 
 
239
    def test_encoding_one(self):
 
240
        self.assertEqual(
 
241
            'http://example.com/bugs/1 fixed',
 
242
            bugtracker.encode_fixes_bug_urls(['http://example.com/bugs/1']))
 
243
 
 
244
    def test_encoding_zero(self):
 
245
        self.assertEqual('', bugtracker.encode_fixes_bug_urls([]))
 
246
 
 
247
    def test_encoding_two(self):
 
248
        self.assertEqual(
 
249
            'http://example.com/bugs/1 fixed\n'
 
250
            'http://example.com/bugs/2 fixed',
 
251
            bugtracker.encode_fixes_bug_urls(
 
252
                ['http://example.com/bugs/1', 'http://example.com/bugs/2']))