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

« back to all changes in this revision

Viewing changes to tests/test_tarmac_land.py

  • Committer: Ursula Junque (Ursinha)
  • Date: 2010-12-16 03:15:17 UTC
  • Revision ID: ursinha@canonical.com-20101216031517-sdfelqll9tzzy42g
Tarmac land command, based on lp-land removing the PQM related part.

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