~ursinha/lp-qa-tools/bzr-tarmacland

« back to all changes in this revision

Viewing changes to tests/test_tarmac_land.py

  • Committer: James Henstridge
  • Date: 2007-12-17 14:51:19 UTC
  • Revision ID: james@jamesh.id.au-20071217145119-bxw361m02rkbk5w4
update Launchpad URL in setup.py

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright 2010 Canonical Ltd.  This software is licensed under the
2
 
# GNU Affero General Public License version 3 (see the file LICENSE).
3
 
 
4
 
"""Tests for automatic landing thing."""
5
 
 
6
 
__metaclass__ = type
7
 
 
8
 
import unittest
9
 
 
10
 
from launchpadlib.uris import (
11
 
    DEV_SERVICE_ROOT, EDGE_SERVICE_ROOT, LPNET_SERVICE_ROOT,
12
 
    STAGING_SERVICE_ROOT)
13
 
 
14
 
from bzrlib.plugins.tarmac_land.tarmac_land import (
15
 
    get_bugs_clause, get_reviewer_clause,
16
 
    get_reviewer_handle, get_testfix_clause, get_qa_clause,
17
 
    MissingReviewError, MissingBugsError, MissingBugsIncrementalError,
18
 
    MergeProposal)
19
 
 
20
 
from fakemethod import FakeMethod
21
 
 
22
 
 
23
 
class FakeBug:
24
 
    """Fake launchpadlib Bug object.
25
 
 
26
 
    Only used for the purposes of testing.
27
 
    """
28
 
 
29
 
    def __init__(self, id):
30
 
        self.id = id
31
 
 
32
 
 
33
 
class FakePerson:
34
 
    """Fake launchpadlib Person object.
35
 
 
36
 
    Only used for the purposes of testing.
37
 
    """
38
 
 
39
 
    def __init__(self, name, irc_handles):
40
 
        self.name = name
41
 
        self.irc_nicknames = list(irc_handles)
42
 
 
43
 
 
44
 
class FakeIRC:
45
 
    """Fake IRC handle.
46
 
 
47
 
    Only used for the purposes of testing.
48
 
    """
49
 
 
50
 
    def __init__(self, nickname, network):
51
 
        self.nickname = nickname
52
 
        self.network = network
53
 
 
54
 
 
55
 
class FakeLPMergeProposal:
56
 
    """Fake launchpadlib MergeProposal object.
57
 
 
58
 
    Only used for the purposes of testing.
59
 
    """
60
 
 
61
 
    def __init__(self, root=None):
62
 
        self._root = root
63
 
        self.commit_message = None
64
 
        self.queue_status = "Needs review"
65
 
 
66
 
    def setStatus(self, status):
67
 
        self.queue_status = status
68
 
 
69
 
    def lp_save(self):
70
 
        pass
71
 
 
72
 
 
73
 
class TestBugsClaused(unittest.TestCase):
74
 
    """Tests for `get_bugs_clause`."""
75
 
 
76
 
    def test_no_bugs(self):
77
 
        # If there are no bugs, then there is no bugs clause.
78
 
        bugs_clause = get_bugs_clause([])
79
 
        self.assertEqual('', bugs_clause)
80
 
 
81
 
    def test_one_bug(self):
82
 
        # If there's a bug, then the bugs clause is [bug=$ID].
83
 
        bug = FakeBug(45)
84
 
        bugs_clause = get_bugs_clause([bug])
85
 
        self.assertEqual('[bug=45]', bugs_clause)
86
 
 
87
 
    def test_two_bugs(self):
88
 
        # If there are two bugs, then the bugs clause is [bug=$ID,$ID].
89
 
        bug1 = FakeBug(20)
90
 
        bug2 = FakeBug(45)
91
 
        bugs_clause = get_bugs_clause([bug1, bug2])
92
 
        self.assertEqual('[bug=20,45]', bugs_clause)
93
 
 
94
 
 
95
 
class TestSetStatusApproved(unittest.TestCase):
96
 
 
97
 
    def setUp(self):
98
 
        self.mp = MergeProposal(FakeLPMergeProposal())
99
 
        self.mp._mp.setStatus(status="Work in progress")
100
 
 
101
 
    def test_set_status_approved(self):
102
 
        self.mp.set_status_approved()
103
 
        self.assertEqual(self.mp._mp.queue_status, "Approved")
104
 
 
105
 
 
106
 
class TestGetTestfixClause(unittest.TestCase):
107
 
    """Tests for `get_testfix_clause`"""
108
 
 
109
 
    def test_no_testfix(self):
110
 
        testfix = False
111
 
        self.assertEqual('', get_testfix_clause(testfix))
112
 
 
113
 
    def test_is_testfix(self):
114
 
        testfix = True
115
 
        self.assertEqual('[testfix]', get_testfix_clause(testfix))
116
 
 
117
 
 
118
 
class TestGetQaClause(unittest.TestCase):
119
 
    """Tests for `get_qa_clause`"""
120
 
 
121
 
    def test_no_bugs_no_option_given(self):
122
 
        bugs = None
123
 
        no_qa = False
124
 
        incr = False
125
 
        self.assertRaises(MissingBugsError, get_qa_clause, bugs, no_qa,
126
 
            incr)
127
 
 
128
 
    def test_bugs_noqa_option_given(self):
129
 
        bug1 = FakeBug(20)
130
 
        no_qa = True
131
 
        incr = False
132
 
        self.assertEqual('[no-qa]',
133
 
            get_qa_clause([bug1], no_qa, incr))
134
 
 
135
 
    def test_no_bugs_noqa_option_given(self):
136
 
        bugs = None
137
 
        no_qa = True
138
 
        incr = False
139
 
        self.assertEqual('[no-qa]',
140
 
            get_qa_clause(bugs, no_qa, incr))
141
 
 
142
 
    def test_bugs_no_option_given(self):
143
 
        bug1 = FakeBug(20)
144
 
        no_qa = False
145
 
        incr = False
146
 
        self.assertEqual('',
147
 
            get_qa_clause([bug1], no_qa, incr))
148
 
 
149
 
    def test_bugs_incr_option_given(self):
150
 
        bug1 = FakeBug(20)
151
 
        no_qa = False
152
 
        incr = True
153
 
        self.assertEqual('[incr]',
154
 
            get_qa_clause([bug1], no_qa, incr))
155
 
 
156
 
    def test_no_bugs_incr_option_given(self):
157
 
        bugs = None
158
 
        no_qa = False
159
 
        incr = True
160
 
        self.assertRaises(MissingBugsIncrementalError,
161
 
            get_qa_clause, bugs, no_qa, incr)
162
 
 
163
 
    def test_bugs_incr_and_noqa_option_given(self):
164
 
        bug1 = FakeBug(20)
165
 
        no_qa = True
166
 
        incr = True
167
 
        self.assertEqual('[no-qa][incr]',
168
 
            get_qa_clause([bug1], no_qa, incr))
169
 
 
170
 
    def test_rollback_given(self):
171
 
        bugs = None
172
 
        self.assertEqual('[rollback=123]',
173
 
            get_qa_clause(bugs, rollback=123))
174
 
 
175
 
    def test_rollback_and_noqa_and_incr_given(self):
176
 
        bugs = None
177
 
        no_qa = True
178
 
        incr = True
179
 
        self.assertEqual('[rollback=123]',
180
 
            get_qa_clause(bugs, rollback=123))
181
 
 
182
 
 
183
 
class TestGetReviewerHandle(unittest.TestCase):
184
 
    """Tests for `get_reviewer_handle`."""
185
 
 
186
 
    def makePerson(self, name, irc_handles):
187
 
        return FakePerson(name, irc_handles)
188
 
 
189
 
    def test_no_irc_nicknames(self):
190
 
        # If the person has no IRC nicknames, their reviewer handle is their
191
 
        # Launchpad user name.
192
 
        person = self.makePerson(name='foo', irc_handles=[])
193
 
        self.assertEqual('foo', get_reviewer_handle(person))
194
 
 
195
 
    def test_freenode_irc_nick_preferred(self):
196
 
        # If the person has a Freenode IRC nickname, then that is preferred as
197
 
        # their user handle.
198
 
        person = self.makePerson(
199
 
            name='foo', irc_handles=[FakeIRC('bar', 'irc.freenode.net')])
200
 
        self.assertEqual('bar', get_reviewer_handle(person))
201
 
 
202
 
    def test_non_freenode_nicks_ignored(self):
203
 
        # If the person has IRC nicks that aren't freenode, we ignore them.
204
 
        person = self.makePerson(
205
 
            name='foo', irc_handles=[FakeIRC('bar', 'irc.efnet.net')])
206
 
        self.assertEqual('foo', get_reviewer_handle(person))
207
 
 
208
 
 
209
 
class TestGetCommitMessage(unittest.TestCase):
210
 
 
211
 
    def setUp(self):
212
 
        self.mp = MergeProposal(FakeLPMergeProposal())
213
 
        self.fake_bug = FakeBug(20)
214
 
        self.fake_person = self.makePerson('foo')
215
 
 
216
 
    def makePerson(self, name):
217
 
        return FakePerson(name, [])
218
 
 
219
 
    def test_commit_with_bugs(self):
220
 
        incr = False
221
 
        no_qa = False
222
 
        testfix = False
223
 
 
224
 
        self.mp.get_bugs = FakeMethod([self.fake_bug])
225
 
        self.mp.get_reviews = FakeMethod({None : [self.fake_person]})
226
 
 
227
 
        self.assertEqual("[r=foo][ui=none][bug=20] Foobaring the sbrubble.",
228
 
            self.mp.build_commit_message("Foobaring the sbrubble.",
229
 
                testfix, no_qa, incr))
230
 
 
231
 
    def test_commit_no_bugs_no_noqa(self):
232
 
        incr = False
233
 
        no_qa = False
234
 
        testfix = False
235
 
 
236
 
        self.mp.get_bugs = FakeMethod([])
237
 
        self.mp.get_reviews = FakeMethod({None : [self.fake_person]})
238
 
 
239
 
        self.assertRaises(MissingBugsError, self.mp.build_commit_message,
240
 
            testfix, no_qa, incr)
241
 
 
242
 
    def test_commit_no_bugs_with_noqa(self):
243
 
        incr = False
244
 
        no_qa = True
245
 
        testfix = False
246
 
 
247
 
        self.mp.get_bugs = FakeMethod([])
248
 
        self.mp.get_reviews = FakeMethod({None : [self.fake_person]})
249
 
 
250
 
        self.assertEqual("[r=foo][ui=none][no-qa] Foobaring the sbrubble.",
251
 
            self.mp.build_commit_message("Foobaring the sbrubble.",
252
 
                testfix, no_qa, incr))
253
 
 
254
 
    def test_commit_bugs_with_noqa(self):
255
 
        incr = False
256
 
        no_qa = True
257
 
        testfix = False
258
 
 
259
 
        self.mp.get_bugs = FakeMethod([self.fake_bug])
260
 
        self.mp.get_reviews = FakeMethod({None : [self.fake_person]})
261
 
 
262
 
        self.assertEqual(
263
 
            "[r=foo][ui=none][bug=20][no-qa] Foobaring the sbrubble.",
264
 
            self.mp.build_commit_message("Foobaring the sbrubble.",
265
 
                testfix, no_qa, incr))
266
 
 
267
 
    def test_commit_bugs_with_incr(self):
268
 
        incr = True
269
 
        no_qa = False
270
 
        testfix = False
271
 
 
272
 
        self.mp.get_bugs = FakeMethod([self.fake_bug])
273
 
        self.mp.get_reviews = FakeMethod({None : [self.fake_person]})
274
 
 
275
 
        self.assertEqual(
276
 
            "[r=foo][ui=none][bug=20][incr] Foobaring the sbrubble.",
277
 
            self.mp.build_commit_message("Foobaring the sbrubble.",
278
 
                testfix, no_qa, incr))
279
 
 
280
 
    def test_commit_no_bugs_with_incr(self):
281
 
        incr = True
282
 
        no_qa = False
283
 
        testfix = False
284
 
 
285
 
        self.mp.get_bugs = FakeMethod([self.fake_bug])
286
 
        self.mp.get_reviews = FakeMethod({None : [self.fake_person]})
287
 
 
288
 
        self.assertEqual(
289
 
            "[r=foo][ui=none][bug=20][incr] Foobaring the sbrubble.",
290
 
            self.mp.build_commit_message("Foobaring the sbrubble.",
291
 
                testfix, no_qa, incr))
292
 
 
293
 
    def test_commit_with_noqa_and_incr(self):
294
 
        incr = True
295
 
        no_qa = True
296
 
        testfix = False
297
 
 
298
 
        self.mp.get_bugs = FakeMethod([self.fake_bug])
299
 
        self.mp.get_reviews = FakeMethod({None : [self.fake_person]})
300
 
 
301
 
        self.assertEqual(
302
 
            "[r=foo][ui=none][bug=20][no-qa][incr] Foobaring the sbrubble.",
303
 
            self.mp.build_commit_message("Foobaring the sbrubble.", 
304
 
                testfix, no_qa, incr))
305
 
 
306
 
    def test_commit_with_rollback(self):
307
 
        self.mp.get_bugs = FakeMethod([self.fake_bug])
308
 
        self.mp.get_reviews = FakeMethod({None : [self.fake_person]})
309
 
 
310
 
        self.assertEqual(
311
 
            "[r=foo][ui=none][bug=20][rollback=123] Foobaring the sbrubble.",
312
 
            self.mp.build_commit_message("Foobaring the sbrubble.", 
313
 
                rollback=123))
314
 
 
315
 
    def test_takes_into_account_existing_tags_on_commit_text(self):
316
 
        self.mp.get_bugs = FakeMethod([self.fake_bug])
317
 
        self.mp.get_reviews = FakeMethod({None : [self.fake_person]})
318
 
 
319
 
        self.assertEqual(
320
 
            "[r=foo][ui=none][bug=20][rollback=123] Foobaring the sbrubble.",
321
 
            self.mp.build_commit_message(
322
 
                "[r=foo][ui=none][bug=20][rollback=123] Foobaring the sbrubble.",
323
 
                rollback=123))
324
 
 
325
 
 
326
 
class TestSetCommitMessage(unittest.TestCase):
327
 
 
328
 
    def setUp(self):
329
 
        self.mp = MergeProposal(FakeLPMergeProposal())
330
 
 
331
 
    def test_set_commit_message(self):
332
 
        commit_message = "Foobaring the sbrubble."
333
 
        self.mp.set_commit_message(commit_message)
334
 
        self.assertEqual(self.mp._mp.commit_message, commit_message)
335
 
 
336
 
 
337
 
class TestGetReviewerClause(unittest.TestCase):
338
 
    """Tests for `get_reviewer_clause`."""
339
 
 
340
 
    def makePerson(self, name):
341
 
        return FakePerson(name, [])
342
 
 
343
 
    def get_reviewer_clause(self, reviewers):
344
 
        return get_reviewer_clause(reviewers)
345
 
 
346
 
    def test_one_reviewer_no_type(self):
347
 
        # It's very common for a merge proposal to be reviewed by one person
348
 
        # with no specified type of review. It such cases the review clause is
349
 
        # '[r=<person>][ui=none]'.
350
 
        clause = self.get_reviewer_clause({None: [self.makePerson('foo')]})
351
 
        self.assertEqual('[r=foo][ui=none]', clause)
352
 
 
353
 
    def test_two_reviewers_no_type(self):
354
 
        # Branches can have more than one reviewer.
355
 
        clause = self.get_reviewer_clause(
356
 
            {None: [self.makePerson('foo'), self.makePerson('bar')]})
357
 
        self.assertEqual('[r=bar,foo][ui=none]', clause)
358
 
 
359
 
    def test_mentat_reviewers(self):
360
 
        # A mentat review sometimes is marked like 'ui*'.  Due to the
361
 
        # unordered nature of dictionaries, the reviewers are sorted before
362
 
        # being put into the clause for predictability.
363
 
        clause = self.get_reviewer_clause(
364
 
            {None: [self.makePerson('foo')],
365
 
             'code*': [self.makePerson('newguy')],
366
 
             'ui': [self.makePerson('beuno')],
367
 
             'ui*': [self.makePerson('bac')]})
368
 
        self.assertEqual('[r=foo,newguy][ui=bac,beuno]', clause)
369
 
 
370
 
    def test_code_reviewer_counts(self):
371
 
        # Some people explicitly specify the 'code' type when they do code
372
 
        # reviews, these are treated in the same way as reviewers without any
373
 
        # given type.
374
 
        clause = self.get_reviewer_clause({'code': [self.makePerson('foo')]})
375
 
        self.assertEqual('[r=foo][ui=none]', clause)
376
 
 
377
 
    def test_release_critical(self):
378
 
        # Reviews that are marked as release-critical are included in a
379
 
        # separate clause.
380
 
        clause = self.get_reviewer_clause(
381
 
            {'code': [self.makePerson('foo')],
382
 
             'release-critical': [self.makePerson('bar')]})
383
 
        self.assertEqual('[release-critical=bar][r=foo][ui=none]', clause)
384
 
 
385
 
    def test_db_reviewer_counts(self):
386
 
        # There's no special way of annotating database reviews in Launchpad
387
 
        # commit messages, so they are included with the code reviews.
388
 
        clause = self.get_reviewer_clause({'db': [self.makePerson('foo')]})
389
 
        self.assertEqual('[r=foo][ui=none]', clause)
390
 
 
391
 
    def test_ui_reviewers(self):
392
 
        # If someone has done a UI review, then that appears in the clause
393
 
        # separately from the code reviews.
394
 
        clause = self.get_reviewer_clause(
395
 
            {'code': [self.makePerson('foo')],
396
 
             'ui': [self.makePerson('bar')],
397
 
             })
398
 
        self.assertEqual('[r=foo][ui=bar]', clause)
399
 
 
400
 
    def test_no_reviewers(self):
401
 
        # If the merge proposal hasn't been approved by anyone, we cannot
402
 
        # generate a valid clause.
403
 
        self.assertRaises(MissingReviewError, self.get_reviewer_clause, {})