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

« back to all changes in this revision

Viewing changes to test_pqm_submit.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 (C) 2005, 2006 by 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
"""Test cases for pqm submit."""
 
17
 
 
18
import smtplib
 
19
 
 
20
from bzrlib import (
 
21
    config as _mod_config,
 
22
    errors,
 
23
    gpg,
 
24
    )
 
25
from bzrlib.plugins.pqm import pqm_submit
 
26
from bzrlib.tests import TestCaseWithMemoryTransport, TestCaseWithTransport
 
27
 
 
28
 
 
29
EMAIL = """\
 
30
From: "J. Random Hacker" <jrandom@example.com>
 
31
Subject: commit message
 
32
To: PQM <pqm@example.com>
 
33
User-Agent: Bazaar \(.*\)
 
34
 
 
35
-----BEGIN PSEUDO-SIGNED CONTENT-----
 
36
star-merge .*/public/ http://example.com/submit
 
37
-----END PSEUDO-SIGNED CONTENT-----
 
38
"""
 
39
 
 
40
 
 
41
class PQMSubmissionTests(TestCaseWithMemoryTransport):
 
42
 
 
43
    def test_no_source_branch(self):
 
44
        self.assertRaises(
 
45
            errors.NoMergeSource, pqm_submit.PQMSubmission,
 
46
            source_branch=None)
 
47
 
 
48
    def test_newlines_in_message(self):
 
49
        source_branch = self.make_branch('source')
 
50
        self.assertRaises(pqm_submit.BadCommitMessage,
 
51
                          pqm_submit.PQMSubmission,
 
52
                          source_branch=source_branch,
 
53
                          public_location='public-branch',
 
54
                          submit_location='submit-branch',
 
55
                          message='foo\nbar')
 
56
 
 
57
    def test_check_tree_clean(self):
 
58
        tree = self.make_branch_and_memory_tree('source')
 
59
        submission = pqm_submit.PQMSubmission(
 
60
            source_branch=tree.branch,
 
61
            public_location=tree.branch.base,
 
62
            submit_location='submit-branch',
 
63
            message='not much to say',
 
64
            tree=tree,
 
65
            )
 
66
        submission.check_tree()
 
67
 
 
68
    def test_check_tree_no_tree(self):
 
69
        branch = self.make_branch('source')
 
70
        submission = pqm_submit.PQMSubmission(
 
71
            source_branch=branch,
 
72
            public_location=branch.base,
 
73
            submit_location='submit-branch',
 
74
            message='not much to say',
 
75
            tree=None,
 
76
            )
 
77
        submission.check_tree()
 
78
 
 
79
    def test_check_tree_dirty(self):
 
80
        tree = self.make_branch_and_memory_tree('source')
 
81
        tree.lock_write()
 
82
        try:
 
83
            tree.add('')
 
84
 
 
85
            submission = pqm_submit.PQMSubmission(
 
86
                source_branch=tree.branch,
 
87
                public_location=tree.branch.base,
 
88
                submit_location='submit-branch',
 
89
                message='not much to say',
 
90
                tree=tree,
 
91
                )
 
92
            self.assertRaises(errors.UncommittedChanges, submission.check_tree)
 
93
        finally:
 
94
            tree.unlock()
 
95
 
 
96
    def test_check_public_branch(self):
 
97
        tree = self.make_branch_and_memory_tree('source')
 
98
        source_branch = tree.branch
 
99
        public_branch = self.make_branch('public')
 
100
 
 
101
        # Commit something to the source branch
 
102
        tree.lock_write()
 
103
        tree.add('')
 
104
        tree.commit('message')
 
105
        tree.unlock()
 
106
 
 
107
        # Now the public branch is out of date:
 
108
        submission = pqm_submit.PQMSubmission(
 
109
            source_branch=source_branch,
 
110
            public_location=public_branch.base,
 
111
            submit_location='submit-branch',
 
112
            message='merge message')
 
113
        self.assertRaises(errors.PublicBranchOutOfDate,
 
114
                          submission.check_public_branch)
 
115
 
 
116
        # If we bring the public branch up to date, everything is fine.
 
117
        public_branch.pull(source_branch)
 
118
        submission.check_public_branch()
 
119
 
 
120
    def test_check_public_branch_missing(self):
 
121
        source_branch = self.make_branch('source')
 
122
        submission = pqm_submit.PQMSubmission(
 
123
            source_branch=source_branch,
 
124
            public_location=self.get_transport().abspath('public'),
 
125
            submit_location='submit-branch',
 
126
            message='merge message')
 
127
        self.assertRaises(errors.NotBranchError,
 
128
                          submission.check_public_branch)
 
129
 
 
130
    def test_to_lines(self):
 
131
        source_branch = self.make_branch('source')
 
132
        submission = pqm_submit.PQMSubmission(
 
133
            source_branch=source_branch,
 
134
            public_location='public-branch',
 
135
            submit_location='submit-branch',
 
136
            message='commit message')
 
137
        lines = submission.to_lines()
 
138
        self.assertEqual(['star-merge public-branch submit-branch\n'], lines)
 
139
 
 
140
    def test_to_signed(self):
 
141
        source_branch = self.make_branch('source')
 
142
        submission = pqm_submit.PQMSubmission(
 
143
            source_branch=source_branch,
 
144
            public_location='public-branch',
 
145
            submit_location='submit-branch',
 
146
            message='commit message')
 
147
        old_strategy = gpg.GPGStrategy
 
148
        gpg.GPGStrategy = gpg.LoopbackGPGStrategy
 
149
        try:
 
150
            signed = submission.to_signed()
 
151
        finally:
 
152
            gpg.GPGStrategy = old_strategy
 
153
        self.assertEqual('-----BEGIN PSEUDO-SIGNED CONTENT-----\n'
 
154
                         'star-merge public-branch submit-branch\n'
 
155
                         '-----END PSEUDO-SIGNED CONTENT-----\n', signed)
 
156
 
 
157
    def test_to_email(self):
 
158
        source_branch = self.make_branch('source')
 
159
        submission = pqm_submit.PQMSubmission(
 
160
            source_branch=source_branch,
 
161
            public_location='public-branch',
 
162
            submit_location='submit-branch',
 
163
            message='commit message')
 
164
        message = submission.to_email('from@example.com', 'to@example.com',
 
165
                                      sign=False)
 
166
        self.assertEqual('from@example.com', message.get('From'))
 
167
        self.assertEqual('to@example.com', message.get('To'))
 
168
        self.assertEqual('commit message', message.get('Subject'))
 
169
 
 
170
    def test_to_unicode_email(self):
 
171
        """Subject has to be raw UTF-8 not email encoded."""
 
172
        source_branch = self.make_branch('source')
 
173
        submission = pqm_submit.PQMSubmission(
 
174
            source_branch=source_branch,
 
175
            public_location='public-branch',
 
176
            submit_location='submit-branch',
 
177
            message=u'Commit m\xe5ss\xb5ge')
 
178
        message = submission.to_email('from@example.com', 'to@example.com',
 
179
                                      sign=False)
 
180
        self.assertEqual('from@example.com', message.get('From'))
 
181
        self.assertEqual('to@example.com', message.get('To'))
 
182
        self.assertEqual('Commit m\xc3\xa5ss\xc2\xb5ge',
 
183
                         message.get('Subject'))
 
184
 
 
185
    def test_submit_branch_public_location(self):
 
186
        source_branch = self.make_branch('source')
 
187
        public_branch = self.make_branch('public')
 
188
        submit_branch = self.make_branch('submit')
 
189
        submit_public_branch = self.make_branch('submit_public')
 
190
        submit_branch.set_public_branch(submit_public_branch.base)
 
191
        source_branch.set_submit_branch(submit_branch.base)
 
192
        submission = pqm_submit.PQMSubmission(
 
193
            source_branch=source_branch,
 
194
            public_location='public',
 
195
            message=u'Commit m\xe5ss\xb5ge')
 
196
        self.assertEqual(submit_public_branch.base, submission.submit_location)
 
197
 
 
198
 
 
199
class PQMSubmissionLocationsTests(TestCaseWithTransport):
 
200
 
 
201
    def test_find_public_branch(self):
 
202
        source_branch = self.make_branch('source')
 
203
        source_branch.set_public_branch('http://example.com/public')
 
204
        # Also set the deprecated public_repository config item to
 
205
        # show that public_branch is used in preference to it.
 
206
        source_branch.get_config().set_user_option(
 
207
            'public_repository', 'bad-value')
 
208
 
 
209
        submission = pqm_submit.PQMSubmission(
 
210
            source_branch=source_branch,
 
211
            submit_location='submit-branch',
 
212
            message='commit message')
 
213
        self.assertEqual('http://example.com/public',
 
214
                         submission.public_location)
 
215
 
 
216
    def test_find_public_branch_from_repo(self):
 
217
        # Test that public_location can be inferred from the obsolete
 
218
        # "public_repository" config option.
 
219
        source_repo = self.make_repository('repo', shared=True)
 
220
        source_branch = self.make_bzrdir('repo/source').create_branch()
 
221
 
 
222
        config = _mod_config.LocationConfig(
 
223
            source_repo.bzrdir.root_transport.base)
 
224
        config.set_user_option(
 
225
            'public_repository', 'http://example.com/repo',
 
226
            store=_mod_config.STORE_LOCATION_NORECURSE)
 
227
 
 
228
        submission = pqm_submit.PQMSubmission(
 
229
            source_branch=source_branch,
 
230
            submit_location='submit-branch',
 
231
            message='commit message')
 
232
        self.assertEqual('http://example.com/repo/source',
 
233
                         submission.public_location)
 
234
 
 
235
    def test_find_public_branch_missing(self):
 
236
        source_branch = self.make_branch('source')
 
237
        self.assertRaises(
 
238
            errors.BzrCommandError, pqm_submit.PQMSubmission,
 
239
            source_branch=source_branch,
 
240
            submit_location='submit-branch',
 
241
            message='commit message')
 
242
 
 
243
    def test_find_submit_branch(self):
 
244
        source_branch = self.make_branch('source')
 
245
        source_branch.set_submit_branch('http://example.com/submit')
 
246
 
 
247
        submission = pqm_submit.PQMSubmission(
 
248
            source_branch=source_branch,
 
249
            public_location='public-branch',
 
250
            message='commit message')
 
251
        self.assertEqual('http://example.com/submit',
 
252
                         submission.submit_location)
 
253
 
 
254
    def test_find_submit_branch_from_pqm_branch(self):
 
255
        # Test that submit_branch can be picked up from the obsolete
 
256
        # pqm_branch config option.
 
257
        source_branch = self.make_branch('source')
 
258
        source_branch.get_config().set_user_option(
 
259
            'pqm_branch', 'http://example.com/submit')
 
260
        # pqm_branch is used in preference to the submit_branch:
 
261
        source_branch.set_submit_branch('bad-value')
 
262
 
 
263
        submission = pqm_submit.PQMSubmission(
 
264
            source_branch=source_branch,
 
265
            public_location='public-branch',
 
266
            message='commit message')
 
267
        self.assertEqual('http://example.com/submit',
 
268
                         submission.submit_location)
 
269
 
 
270
    def test_find_submit_branch_missing(self):
 
271
        source_branch = self.make_branch('source')
 
272
        self.assertRaises(
 
273
            errors.NoSubmitBranch, pqm_submit.PQMSubmission,
 
274
            source_branch=source_branch,
 
275
            public_location='public-branch',
 
276
            message='commit message')
 
277
 
 
278
    def run_bzr_fakemail(self, *args, **kwargs):
 
279
        # Run with fake smtplib and gpg stubs in place:
 
280
        sendmail_calls = []
 
281
        def sendmail(self, from_, to, message):
 
282
            sendmail_calls.append((self, from_, to, message))
 
283
        connect_calls = []
 
284
        def connect(self, host='localhost', port=0):
 
285
            connect_calls.append((self, host, port))
 
286
        def ehlo(self):
 
287
            return (200, 'Ok')
 
288
        def has_extn(self, extn):
 
289
            return False
 
290
        def starttls(self):
 
291
            pass
 
292
        old_sendmail = smtplib.SMTP.sendmail
 
293
        smtplib.SMTP.sendmail = sendmail
 
294
        old_connect = smtplib.SMTP.connect
 
295
        smtplib.SMTP.connect = connect
 
296
        old_ehlo = smtplib.SMTP.ehlo
 
297
        smtplib.SMTP.ehlo = ehlo
 
298
        old_has_extn = smtplib.SMTP.has_extn
 
299
        smtplib.SMTP.has_extn = has_extn
 
300
        old_starttls = smtplib.SMTP.starttls
 
301
        smtplib.SMTP.starttls = starttls
 
302
        old_strategy = gpg.GPGStrategy
 
303
        gpg.GPGStrategy = gpg.LoopbackGPGStrategy
 
304
        try:
 
305
            result = self.run_bzr(*args, **kwargs)
 
306
        finally:
 
307
            smtplib.SMTP.sendmail = old_sendmail
 
308
            smtplib.SMTP.connect = old_connect
 
309
            smtplib.SMTP.ehlo = old_ehlo
 
310
            smtplib.SMTP.has_extn = old_has_extn
 
311
            smtplib.SMTP.starttls = old_starttls
 
312
            gpg.GPGStrategy = old_strategy
 
313
 
 
314
        return result + (connect_calls, sendmail_calls)
 
315
 
 
316
    def test_pqm_submit(self):
 
317
        source_branch = self.make_branch('source')
 
318
        public_branch = self.make_branch('public')
 
319
        source_branch.set_public_branch(public_branch.base)
 
320
        source_branch.set_submit_branch('http://example.com/submit')
 
321
        config = source_branch.get_config()
 
322
        config.set_user_option('pqm_email', 'PQM <pqm@example.com>')
 
323
        config.set_user_option(
 
324
            'email', 'J. Random Hacker <jrandom@example.com>')
 
325
 
 
326
        out, err, connect_calls, sendmail_calls = \
 
327
            self.run_bzr_fakemail(['pqm-submit', '-m', 'commit message',
 
328
                                   './source'])
 
329
        self.assertEqual('', out)
 
330
        self.assertEqual(1, len(connect_calls))
 
331
        call = connect_calls[0]
 
332
        self.assertEqual(('localhost', 0), call[1:3])
 
333
        self.assertEqual(1, len(sendmail_calls))
 
334
        call = sendmail_calls[0]
 
335
        self.assertEqual(('jrandom@example.com', ['pqm@example.com']),
 
336
                         call[1:3])
 
337
        self.assertContainsRe(call[3], EMAIL)
 
338
 
 
339
    def test_dirty_pqm_submit(self):
 
340
        source_tree = self.make_branch_and_tree('source')
 
341
        self.build_tree(['source/foo'])
 
342
        source_tree.add(['foo'])
 
343
 
 
344
        public_branch = self.make_branch('public')
 
345
        source_tree.branch.set_public_branch(public_branch.base)
 
346
        source_tree.branch.set_submit_branch('http://example.com/submit')
 
347
        config = source_tree.branch.get_config()
 
348
        config.set_user_option('pqm_email', 'PQM <pqm@example.com>')
 
349
        config.set_user_option(
 
350
            'email', 'J. Random Hacker <jrandom@example.com>')
 
351
 
 
352
        out, err, connect_calls, sendmail_calls = \
 
353
            self.run_bzr_fakemail(['pqm-submit', '-m', 'commit message',
 
354
                                   './source'],
 
355
                                  retcode=3)
 
356
        self.assertContainsRe(err,
 
357
            r'Working tree ".*/source/" has uncommitted changes\.')
 
358
 
 
359
    def test_submit_subdir_of_branch(self):
 
360
        source_branch = self.make_branch('source')
 
361
        source_branch.set_submit_branch('http://example.com/submit')
 
362
        config = source_branch.get_config()
 
363
        out, err, connect_calls, sendmail_calls = \
 
364
            self.run_bzr_fakemail(['pqm-submit', '-m', 'commit message',
 
365
                                   './source/subdir'],
 
366
                                  retcode=3)
 
367
        self.assertContainsRe(err, 'bzr: ERROR: No working tree was found')
 
368
 
 
369
    def test_submit_branch(self):
 
370
        """Test that --submit-branch overrides local config."""
 
371
        source_branch = self.make_branch('source')
 
372
        public_branch = self.make_branch('public')
 
373
        source_branch.set_public_branch(public_branch.base)
 
374
        source_branch.set_submit_branch('http://a/very/different/branch')
 
375
        config = source_branch.get_config()
 
376
        config.set_user_option('pqm_email', 'PQM <pqm@example.com>')
 
377
        config.set_user_option(
 
378
            'email', 'J. Random Hacker <jrandom@example.com>')
 
379
 
 
380
        (out, err, connect_calls,
 
381
         sendmail_calls) = self.run_bzr_fakemail(
 
382
                ['pqm-submit', '-m', 'commit message',
 
383
                 '--submit-branch', 'http://example.com/submit',
 
384
                 './source'
 
385
                ])
 
386
        self.assertEqual('', out)
 
387
        self.assertEqual(1, len(connect_calls))
 
388
        call = connect_calls[0]
 
389
        self.assertEqual(('localhost', 0), call[1:3])
 
390
        self.assertEqual(1, len(sendmail_calls))
 
391
        call = sendmail_calls[0]
 
392
        self.assertEqual(('jrandom@example.com', ['pqm@example.com']),
 
393
                         call[1:3])
 
394
        self.assertContainsRe(call[3], EMAIL)