/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/blackbox/test_send.py

  • Committer: John Arbash Meinel
  • Date: 2009-12-22 16:28:47 UTC
  • mto: This revision was merged to the branch mainline in revision 4922.
  • Revision ID: john@arbash-meinel.com-20091222162847-tvnsc69to4l4uf5r
Implement a permute_for_extension helper.

Use it for all of the 'simple' extension permutations.
It basically permutes all tests in the current module, by setting TestCase.module.
Which works well for most of our extension tests. Some had more advanced
handling of permutations (extra permutations, custom vars, etc.)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2006, 2007, 2008, 2009 Canonical Ltd
 
2
# Authors: Aaron Bentley
 
3
#
 
4
# This program is free software; you can redistribute it and/or modify
 
5
# it under the terms of the GNU General Public License as published by
 
6
# the Free Software Foundation; either version 2 of the License, or
 
7
# (at your option) any later version.
 
8
#
 
9
# This program is distributed in the hope that it will be useful,
 
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
# GNU General Public License for more details.
 
13
#
 
14
# You should have received a copy of the GNU General Public License
 
15
# along with this program; if not, write to the Free Software
 
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
17
 
 
18
 
 
19
import sys
 
20
from cStringIO import StringIO
 
21
 
 
22
from bzrlib import (
 
23
    branch,
 
24
    bzrdir,
 
25
    merge_directive,
 
26
    tests,
 
27
    )
 
28
from bzrlib.bundle import serializer
 
29
 
 
30
 
 
31
def load_tests(standard_tests, module, loader):
 
32
    """Multiply tests for the send command."""
 
33
    result = loader.suiteClass()
 
34
 
 
35
    # one for each king of change
 
36
    changes_tests, remaining_tests = tests.split_suite_by_condition(
 
37
        standard_tests, tests.condition_isinstance((
 
38
                TestSendStrictWithChanges,
 
39
                )))
 
40
    changes_scenarios = [
 
41
        ('uncommitted',
 
42
         dict(_changes_type='_uncommitted_changes')),
 
43
        ('pending_merges',
 
44
         dict(_changes_type='_pending_merges')),
 
45
        ('out-of-sync-trees',
 
46
         dict(_changes_type='_out_of_sync_trees')),
 
47
        ]
 
48
    tests.multiply_tests(changes_tests, changes_scenarios, result)
 
49
    # No parametrization for the remaining tests
 
50
    result.addTests(remaining_tests)
 
51
 
 
52
    return result
 
53
 
 
54
 
 
55
class TestSendMixin(object):
 
56
 
 
57
    _default_command = ['send', '-o-']
 
58
    _default_wd = 'branch'
 
59
 
 
60
    def run_send(self, args, cmd=None, rc=0, wd=None, err_re=None):
 
61
        if cmd is None: cmd = self._default_command
 
62
        if wd is None: wd = self._default_wd
 
63
        if err_re is None: err_re = []
 
64
        return self.run_bzr(cmd + args, retcode=rc,
 
65
                            working_dir=wd,
 
66
                            error_regexes=err_re)
 
67
 
 
68
    def get_MD(self, args, cmd=None, wd='branch'):
 
69
        out = StringIO(self.run_send(args, cmd=cmd, wd=wd)[0])
 
70
        return merge_directive.MergeDirective.from_lines(out)
 
71
 
 
72
    def assertBundleContains(self, revs, args, cmd=None, wd='branch'):
 
73
        md = self.get_MD(args, cmd=cmd, wd=wd)
 
74
        br = serializer.read_bundle(StringIO(md.get_raw_bundle()))
 
75
        self.assertEqual(set(revs), set(r.revision_id for r in br.revisions))
 
76
 
 
77
 
 
78
class TestSend(tests.TestCaseWithTransport, TestSendMixin):
 
79
 
 
80
    def setUp(self):
 
81
        super(TestSend, self).setUp()
 
82
        grandparent_tree = bzrdir.BzrDir.create_standalone_workingtree(
 
83
            'grandparent')
 
84
        self.build_tree_contents([('grandparent/file1', 'grandparent')])
 
85
        grandparent_tree.add('file1')
 
86
        grandparent_tree.commit('initial commit', rev_id='rev1')
 
87
 
 
88
        parent_bzrdir = grandparent_tree.bzrdir.sprout('parent')
 
89
        parent_tree = parent_bzrdir.open_workingtree()
 
90
        parent_tree.commit('next commit', rev_id='rev2')
 
91
 
 
92
        branch_tree = parent_tree.bzrdir.sprout('branch').open_workingtree()
 
93
        self.build_tree_contents([('branch/file1', 'branch')])
 
94
        branch_tree.commit('last commit', rev_id='rev3')
 
95
 
 
96
    def assertFormatIs(self, fmt_string, md):
 
97
        self.assertEqual(fmt_string, md.get_raw_bundle().splitlines()[0])
 
98
 
 
99
    def test_uses_parent(self):
 
100
        """Parent location is used as a basis by default"""
 
101
        errmsg = self.run_send([], rc=3, wd='grandparent')[1]
 
102
        self.assertContainsRe(errmsg, 'No submit branch known or specified')
 
103
        stdout, stderr = self.run_send([])
 
104
        self.assertEqual(stderr.count('Using saved parent location'), 1)
 
105
        self.assertBundleContains(['rev3'], [])
 
106
 
 
107
    def test_bundle(self):
 
108
        """Bundle works like send, except -o is not required"""
 
109
        errmsg = self.run_send([], cmd=['bundle'], rc=3, wd='grandparent')[1]
 
110
        self.assertContainsRe(errmsg, 'No submit branch known or specified')
 
111
        stdout, stderr = self.run_send([], cmd=['bundle'])
 
112
        self.assertEqual(stderr.count('Using saved parent location'), 1)
 
113
        self.assertBundleContains(['rev3'], [], cmd=['bundle'])
 
114
 
 
115
    def test_uses_submit(self):
 
116
        """Submit location can be used and set"""
 
117
        self.assertBundleContains(['rev3'], [])
 
118
        self.assertBundleContains(['rev3', 'rev2'], ['../grandparent'])
 
119
        # submit location should be auto-remembered
 
120
        self.assertBundleContains(['rev3', 'rev2'], [])
 
121
 
 
122
        self.run_send(['../parent'])
 
123
        # We still point to ../grandparent
 
124
        self.assertBundleContains(['rev3', 'rev2'], [])
 
125
        # Remember parent now
 
126
        self.run_send(['../parent', '--remember'])
 
127
        # Now we point to parent
 
128
        self.assertBundleContains(['rev3'], [])
 
129
 
 
130
        err = self.run_send(['--remember'], rc=3)[1]
 
131
        self.assertContainsRe(err,
 
132
                              '--remember requires a branch to be specified.')
 
133
 
 
134
    def test_revision_branch_interaction(self):
 
135
        self.assertBundleContains(['rev3', 'rev2'], ['../grandparent'])
 
136
        self.assertBundleContains(['rev2'], ['../grandparent', '-r-2'])
 
137
        self.assertBundleContains(['rev3', 'rev2'],
 
138
                                  ['../grandparent', '-r-2..-1'])
 
139
        md = self.get_MD(['-r-2..-1'])
 
140
        self.assertEqual('rev2', md.base_revision_id)
 
141
        self.assertEqual('rev3', md.revision_id)
 
142
 
 
143
    def test_output(self):
 
144
        # check output for consistency
 
145
        # win32 stdout converts LF to CRLF,
 
146
        # which would break patch-based bundles
 
147
        self.assertBundleContains(['rev3'], [])
 
148
 
 
149
    def test_no_common_ancestor(self):
 
150
        foo = self.make_branch_and_tree('foo')
 
151
        foo.commit('rev a')
 
152
        bar = self.make_branch_and_tree('bar')
 
153
        bar.commit('rev b')
 
154
        self.run_send(['--from', 'foo', '../bar'], wd='foo')
 
155
 
 
156
    def test_content_options(self):
 
157
        """--no-patch and --no-bundle should work and be independant"""
 
158
        md = self.get_MD([])
 
159
        self.assertIsNot(None, md.bundle)
 
160
        self.assertIsNot(None, md.patch)
 
161
 
 
162
        md = self.get_MD(['--format=0.9'])
 
163
        self.assertIsNot(None, md.bundle)
 
164
        self.assertIsNot(None, md.patch)
 
165
 
 
166
        md = self.get_MD(['--no-patch'])
 
167
        self.assertIsNot(None, md.bundle)
 
168
        self.assertIs(None, md.patch)
 
169
        self.run_bzr_error(['Format 0.9 does not permit bundle with no patch'],
 
170
                           ['send', '--no-patch', '--format=0.9', '-o-'],
 
171
                           working_dir='branch')
 
172
        md = self.get_MD(['--no-bundle', '.', '.'])
 
173
        self.assertIs(None, md.bundle)
 
174
        self.assertIsNot(None, md.patch)
 
175
 
 
176
        md = self.get_MD(['--no-bundle', '--format=0.9', '../parent',
 
177
                                  '.'])
 
178
        self.assertIs(None, md.bundle)
 
179
        self.assertIsNot(None, md.patch)
 
180
 
 
181
        md = self.get_MD(['--no-bundle', '--no-patch', '.', '.'])
 
182
        self.assertIs(None, md.bundle)
 
183
        self.assertIs(None, md.patch)
 
184
 
 
185
        md = self.get_MD(['--no-bundle', '--no-patch', '--format=0.9',
 
186
                          '../parent', '.'])
 
187
        self.assertIs(None, md.bundle)
 
188
        self.assertIs(None, md.patch)
 
189
 
 
190
    def test_from_option(self):
 
191
        self.run_bzr('send', retcode=3)
 
192
        md = self.get_MD(['--from', 'branch'])
 
193
        self.assertEqual('rev3', md.revision_id)
 
194
        md = self.get_MD(['-f', 'branch'])
 
195
        self.assertEqual('rev3', md.revision_id)
 
196
 
 
197
    def test_output_option(self):
 
198
        stdout = self.run_bzr('send -f branch --output file1')[0]
 
199
        self.assertEqual('', stdout)
 
200
        md_file = open('file1', 'rb')
 
201
        self.addCleanup(md_file.close)
 
202
        self.assertContainsRe(md_file.read(), 'rev3')
 
203
        stdout = self.run_bzr('send -f branch --output -')[0]
 
204
        self.assertContainsRe(stdout, 'rev3')
 
205
 
 
206
    def test_note_revisions(self):
 
207
        stderr = self.run_send([])[1]
 
208
        self.assertEndsWith(stderr, '\nBundling 1 revision(s).\n')
 
209
 
 
210
    def test_mailto_option(self):
 
211
        b = branch.Branch.open('branch')
 
212
        b.get_config().set_user_option('mail_client', 'editor')
 
213
        self.run_bzr_error(
 
214
            ('No mail-to address \\(--mail-to\\) or output \\(-o\\) specified',
 
215
            ), 'send -f branch')
 
216
        b.get_config().set_user_option('mail_client', 'bogus')
 
217
        self.run_send([])
 
218
        self.run_bzr_error(('Unknown mail client: bogus',),
 
219
                           'send -f branch --mail-to jrandom@example.org')
 
220
        b.get_config().set_user_option('submit_to', 'jrandom@example.org')
 
221
        self.run_bzr_error(('Unknown mail client: bogus',),
 
222
                           'send -f branch')
 
223
 
 
224
    def test_mailto_child_option(self):
 
225
        """Make sure that child_submit_to is used."""
 
226
        b = branch.Branch.open('branch')
 
227
        b.get_config().set_user_option('mail_client', 'bogus')
 
228
        parent = branch.Branch.open('parent')
 
229
        parent.get_config().set_user_option('child_submit_to',
 
230
                           'somebody@example.org')
 
231
        self.run_bzr_error(('Unknown mail client: bogus',),
 
232
                           'send -f branch')
 
233
 
 
234
    def test_format(self):
 
235
        md = self.get_MD(['--format=4'])
 
236
        self.assertIs(merge_directive.MergeDirective2, md.__class__)
 
237
        self.assertFormatIs('# Bazaar revision bundle v4', md)
 
238
 
 
239
        md = self.get_MD(['--format=0.9'])
 
240
        self.assertFormatIs('# Bazaar revision bundle v0.9', md)
 
241
 
 
242
        md = self.get_MD(['--format=0.9'], cmd=['bundle'])
 
243
        self.assertFormatIs('# Bazaar revision bundle v0.9', md)
 
244
        self.assertIs(merge_directive.MergeDirective, md.__class__)
 
245
 
 
246
        self.run_bzr_error(['Bad value .* for option .format.'],
 
247
                            'send -f branch -o- --format=0.999')[0]
 
248
 
 
249
    def test_format_child_option(self):
 
250
        parent_config = branch.Branch.open('parent').get_config()
 
251
        parent_config.set_user_option('child_submit_format', '4')
 
252
        md = self.get_MD([])
 
253
        self.assertIs(merge_directive.MergeDirective2, md.__class__)
 
254
 
 
255
        parent_config.set_user_option('child_submit_format', '0.9')
 
256
        md = self.get_MD([])
 
257
        self.assertFormatIs('# Bazaar revision bundle v0.9', md)
 
258
 
 
259
        md = self.get_MD([], cmd=['bundle'])
 
260
        self.assertFormatIs('# Bazaar revision bundle v0.9', md)
 
261
        self.assertIs(merge_directive.MergeDirective, md.__class__)
 
262
 
 
263
        parent_config.set_user_option('child_submit_format', '0.999')
 
264
        self.run_bzr_error(["No such send format '0.999'"],
 
265
                            'send -f branch -o-')[0]
 
266
 
 
267
    def test_message_option(self):
 
268
        self.run_bzr('send', retcode=3)
 
269
        md = self.get_MD([])
 
270
        self.assertIs(None, md.message)
 
271
        md = self.get_MD(['-m', 'my message'])
 
272
        self.assertEqual('my message', md.message)
 
273
 
 
274
    def test_omitted_revision(self):
 
275
        md = self.get_MD(['-r-2..'])
 
276
        self.assertEqual('rev2', md.base_revision_id)
 
277
        self.assertEqual('rev3', md.revision_id)
 
278
        md = self.get_MD(['-r..3', '--from', 'branch', 'grandparent'], wd='.')
 
279
        self.assertEqual('rev1', md.base_revision_id)
 
280
        self.assertEqual('rev3', md.revision_id)
 
281
 
 
282
    def test_nonexistant_branch(self):
 
283
        self.vfs_transport_factory = tests.MemoryServer
 
284
        location = self.get_url('absentdir/')
 
285
        out, err = self.run_bzr(["send", "--from", location], retcode=3)
 
286
        self.assertEqual(out, '')
 
287
        self.assertEqual(err, 'bzr: ERROR: Not a branch: "%s".\n' % location)
 
288
 
 
289
 
 
290
class TestSendStrictMixin(TestSendMixin):
 
291
 
 
292
    def make_parent_and_local_branches(self):
 
293
        # Create a 'parent' branch as the base
 
294
        self.parent_tree = bzrdir.BzrDir.create_standalone_workingtree('parent')
 
295
        self.build_tree_contents([('parent/file', 'parent')])
 
296
        self.parent_tree.add('file')
 
297
        self.parent_tree.commit('first commit', rev_id='parent')
 
298
        # Branch 'local' from parent and do a change
 
299
        local_bzrdir = self.parent_tree.bzrdir.sprout('local')
 
300
        self.local_tree = local_bzrdir.open_workingtree()
 
301
        self.build_tree_contents([('local/file', 'local')])
 
302
        self.local_tree.commit('second commit', rev_id='local')
 
303
 
 
304
    _default_command = ['send', '-o-', '../parent']
 
305
    _default_wd = 'local'
 
306
    _default_sent_revs = ['local']
 
307
    _default_errors = ['Working tree ".*/local/" has uncommitted '
 
308
                       'changes \(See bzr status\)\.',]
 
309
 
 
310
    def set_config_send_strict(self, value):
 
311
        # set config var (any of bazaar.conf, locations.conf, branch.conf
 
312
        # should do)
 
313
        conf = self.local_tree.branch.get_config()
 
314
        conf.set_user_option('send_strict', value)
 
315
 
 
316
    def assertSendFails(self, args):
 
317
        self.run_send(args, rc=3, err_re=self._default_errors)
 
318
 
 
319
    def assertSendSucceeds(self, args, revs=None):
 
320
        if revs is None:
 
321
            revs = self._default_sent_revs
 
322
        out, err = self.run_send(args)
 
323
        self.assertEquals(
 
324
            'Bundling %d revision(s).\n' % len(revs), err)
 
325
        md = merge_directive.MergeDirective.from_lines(StringIO(out))
 
326
        self.assertEqual('parent', md.base_revision_id)
 
327
        br = serializer.read_bundle(StringIO(md.get_raw_bundle()))
 
328
        self.assertEqual(set(revs), set(r.revision_id for r in br.revisions))
 
329
 
 
330
 
 
331
class TestSendStrictWithoutChanges(tests.TestCaseWithTransport,
 
332
                                   TestSendStrictMixin):
 
333
 
 
334
    def setUp(self):
 
335
        super(TestSendStrictWithoutChanges, self).setUp()
 
336
        self.make_parent_and_local_branches()
 
337
 
 
338
    def test_send_default(self):
 
339
        self.assertSendSucceeds([])
 
340
 
 
341
    def test_send_strict(self):
 
342
        self.assertSendSucceeds(['--strict'])
 
343
 
 
344
    def test_send_no_strict(self):
 
345
        self.assertSendSucceeds(['--no-strict'])
 
346
 
 
347
    def test_send_config_var_strict(self):
 
348
        self.set_config_send_strict('true')
 
349
        self.assertSendSucceeds([])
 
350
 
 
351
    def test_send_config_var_no_strict(self):
 
352
        self.set_config_send_strict('false')
 
353
        self.assertSendSucceeds([])
 
354
 
 
355
 
 
356
class TestSendStrictWithChanges(tests.TestCaseWithTransport,
 
357
                                   TestSendStrictMixin):
 
358
 
 
359
    _changes_type = None # Set by load_tests
 
360
 
 
361
    def setUp(self):
 
362
        super(TestSendStrictWithChanges, self).setUp()
 
363
        # load tests set _changes_types to the name of the method we want to
 
364
        # call now
 
365
        do_changes_func = getattr(self, self._changes_type)
 
366
        do_changes_func()
 
367
 
 
368
    def _uncommitted_changes(self):
 
369
        self.make_parent_and_local_branches()
 
370
        # Make a change without committing it
 
371
        self.build_tree_contents([('local/file', 'modified')])
 
372
 
 
373
    def _pending_merges(self):
 
374
        self.make_parent_and_local_branches()
 
375
        # Create 'other' branch containing a new file
 
376
        other_bzrdir = self.parent_tree.bzrdir.sprout('other')
 
377
        other_tree = other_bzrdir.open_workingtree()
 
378
        self.build_tree_contents([('other/other-file', 'other')])
 
379
        other_tree.add('other-file')
 
380
        other_tree.commit('other commit', rev_id='other')
 
381
        # Merge and revert, leaving a pending merge
 
382
        self.local_tree.merge_from_branch(other_tree.branch)
 
383
        self.local_tree.revert(filenames=['other-file'], backups=False)
 
384
 
 
385
    def _out_of_sync_trees(self):
 
386
        self.make_parent_and_local_branches()
 
387
        self.run_bzr(['checkout', '--lightweight', 'local', 'checkout'])
 
388
        # Make a change and commit it
 
389
        self.build_tree_contents([('local/file', 'modified in local')])
 
390
        self.local_tree.commit('modify file', rev_id='modified-in-local')
 
391
        # Exercise commands from the checkout directory
 
392
        self._default_wd = 'checkout'
 
393
        self._default_errors = ["Working tree is out of date, please run"
 
394
                                " 'bzr update'\.",]
 
395
        self._default_sent_revs = ['modified-in-local', 'local']
 
396
 
 
397
    def test_send_default(self):
 
398
        self.assertSendFails([])
 
399
 
 
400
    def test_send_with_revision(self):
 
401
        self.assertSendSucceeds(['-r', 'revid:local'], revs=['local'])
 
402
 
 
403
    def test_send_no_strict(self):
 
404
        self.assertSendSucceeds(['--no-strict'])
 
405
 
 
406
    def test_send_strict_with_changes(self):
 
407
        self.assertSendFails(['--strict'])
 
408
 
 
409
    def test_send_respect_config_var_strict(self):
 
410
        self.set_config_send_strict('true')
 
411
        self.assertSendFails([])
 
412
        self.assertSendSucceeds(['--no-strict'])
 
413
 
 
414
 
 
415
    def test_send_bogus_config_var_ignored(self):
 
416
        self.set_config_send_strict("I'm unsure")
 
417
        self.assertSendFails([])
 
418
 
 
419
 
 
420
    def test_send_no_strict_command_line_override_config(self):
 
421
        self.set_config_send_strict('true')
 
422
        self.assertSendFails([])
 
423
        self.assertSendSucceeds(['--no-strict'])
 
424
 
 
425
    def test_send_strict_command_line_override_config(self):
 
426
        self.set_config_send_strict('false')
 
427
        self.assertSendSucceeds([])
 
428
        self.assertSendFails(['--strict'])
 
429
 
 
430
 
 
431
class TestBundleStrictWithoutChanges(TestSendStrictWithoutChanges):
 
432
 
 
433
    _default_command = ['bundle-revisions', '../parent']