/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
4763.2.4 by John Arbash Meinel
merge bzr.2.1 in preparation for NEWS entry.
1
# Copyright (C) 2006-2010 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
16
17
1692.3.1 by Robert Collins
Fix push to work with just a branch, no need for a working tree.
18
"""Black-box tests for bzr push."""
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
19
3066.3.2 by jml at canonical
Add tests to check the handling of TooManyRedirections.
20
import re
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
21
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
22
from bzrlib import (
4420.1.1 by Vincent Ladeuil
Cleanup imports.
23
    branch,
24
    bzrdir,
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
25
    errors,
4420.1.1 by Vincent Ladeuil
Cleanup imports.
26
    osutils,
27
    tests,
3878.4.4 by Vincent Ladeuil
Cleanup.
28
    transport,
4420.1.1 by Vincent Ladeuil
Cleanup imports.
29
    uncommit,
2220.2.9 by Martin Pool
Add specific tests for push -d and pull -d
30
    urlutils,
4420.1.1 by Vincent Ladeuil
Cleanup imports.
31
    workingtree
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
32
    )
4420.1.1 by Vincent Ladeuil
Cleanup imports.
33
from bzrlib.repofmt import knitrepo
4925.1.1 by Jelmer Vernooij
Print a proper error when attempting to push to a foreign VCS for which
34
from bzrlib.tests import (
35
    blackbox,
36
    http_server,
37
    test_foreign,
5017.3.37 by Vincent Ladeuil
-s bb.test_push passing
38
    test_server,
4925.1.1 by Jelmer Vernooij
Print a proper error when attempting to push to a foreign VCS for which
39
    )
4420.1.1 by Vincent Ladeuil
Cleanup imports.
40
from bzrlib.transport import memory
41
42
4487.2.2 by Vincent Ladeuil
Add tests for push --strict against pending merges.
43
def load_tests(standard_tests, module, loader):
44
    """Multiply tests for the push command."""
45
    result = loader.suiteClass()
46
47
    # one for each king of change
48
    changes_tests, remaining_tests = tests.split_suite_by_condition(
49
        standard_tests, tests.condition_isinstance((
50
                TestPushStrictWithChanges,
51
                )))
52
    changes_scenarios = [
53
        ('uncommitted',
4487.2.3 by Vincent Ladeuil
--strict is meaningless when --revision is specified.
54
         dict(_changes_type= '_uncommitted_changes')),
4487.2.6 by Vincent Ladeuil
Fixed as per jam's review.
55
        ('pending-merges',
4487.2.3 by Vincent Ladeuil
--strict is meaningless when --revision is specified.
56
         dict(_changes_type= '_pending_merges')),
4487.2.6 by Vincent Ladeuil
Fixed as per jam's review.
57
        ('out-of-sync-trees',
58
         dict(_changes_type= '_out_of_sync_trees')),
4487.2.2 by Vincent Ladeuil
Add tests for push --strict against pending merges.
59
        ]
60
    tests.multiply_tests(changes_tests, changes_scenarios, result)
61
    # No parametrization for the remaining tests
62
    result.addTests(remaining_tests)
63
64
    return result
65
66
4420.1.1 by Vincent Ladeuil
Cleanup imports.
67
class TestPush(tests.TestCaseWithTransport):
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
68
4017.2.3 by Robert Collins
Review feedback.
69
    def test_push_error_on_vfs_http(self):
70
        """ pushing a branch to a HTTP server fails cleanly. """
71
        # the trunk is published on a web server
4420.1.1 by Vincent Ladeuil
Cleanup imports.
72
        self.transport_readonly_server = http_server.HttpServer
4017.2.3 by Robert Collins
Review feedback.
73
        self.make_branch('source')
74
        public_url = self.get_readonly_url('target')
75
        self.run_bzr_error(['http does not support mkdir'],
76
                           ['push', public_url],
77
                           working_dir='source')
78
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
79
    def test_push_remember(self):
80
        """Push changes from one branch to another and test push location."""
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
81
        transport = self.get_transport()
82
        tree_a = self.make_branch_and_tree('branch_a')
83
        branch_a = tree_a.branch
84
        self.build_tree(['branch_a/a'])
85
        tree_a.add('a')
86
        tree_a.commit('commit a')
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
87
        tree_b = branch_a.bzrdir.sprout('branch_b').open_workingtree()
88
        branch_b = tree_b.branch
89
        tree_c = branch_a.bzrdir.sprout('branch_c').open_workingtree()
90
        branch_c = tree_c.branch
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
91
        self.build_tree(['branch_a/b'])
92
        tree_a.add('b')
93
        tree_a.commit('commit b')
94
        self.build_tree(['branch_b/c'])
95
        tree_b.add('c')
96
        tree_b.commit('commit c')
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
97
        # initial push location must be empty
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
98
        self.assertEqual(None, branch_b.get_push_location())
1785.1.2 by John Arbash Meinel
Push should only save the location if it can actually connect (doesn't need to succeed)
99
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
100
        # test push for failure without push location set
4420.1.1 by Vincent Ladeuil
Cleanup imports.
101
        out = self.run_bzr('push', working_dir='branch_a', retcode=3)
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
102
        self.assertEquals(out,
103
                ('','bzr: ERROR: No push location known or specified.\n'))
1785.1.2 by John Arbash Meinel
Push should only save the location if it can actually connect (doesn't need to succeed)
104
105
        # test not remembered if cannot actually push
4420.1.1 by Vincent Ladeuil
Cleanup imports.
106
        self.run_bzr('push path/which/doesnt/exist',
107
                     working_dir='branch_a', retcode=3)
108
        out = self.run_bzr('push', working_dir='branch_a', retcode=3)
1785.1.2 by John Arbash Meinel
Push should only save the location if it can actually connect (doesn't need to succeed)
109
        self.assertEquals(
110
                ('', 'bzr: ERROR: No push location known or specified.\n'),
111
                out)
112
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
113
        # test implicit --remember when no push location set, push fails
4420.1.1 by Vincent Ladeuil
Cleanup imports.
114
        out = self.run_bzr('push ../branch_b',
115
                           working_dir='branch_a', retcode=3)
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
116
        self.assertEquals(out,
117
                ('','bzr: ERROR: These branches have diverged.  '
4441.1.1 by Aaron Bentley
Merge nmb's diverged-branch docs.
118
                 'See "bzr help diverged-branches" for more information.\n'))
4420.1.1 by Vincent Ladeuil
Cleanup imports.
119
        self.assertEquals(osutils.abspath(branch_a.get_push_location()),
120
                          osutils.abspath(branch_b.bzrdir.root_transport.base))
1785.1.2 by John Arbash Meinel
Push should only save the location if it can actually connect (doesn't need to succeed)
121
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
122
        # test implicit --remember after resolving previous failure
4420.1.1 by Vincent Ladeuil
Cleanup imports.
123
        uncommit.uncommit(branch=branch_b, tree=tree_b)
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
124
        transport.delete('branch_b/c')
4420.1.1 by Vincent Ladeuil
Cleanup imports.
125
        out, err = self.run_bzr('push', working_dir='branch_a')
1785.1.1 by John Arbash Meinel
Fix the output of 'bzr push' so that it prints the location correctly.
126
        path = branch_a.get_push_location()
2220.2.38 by Martin Pool
Tag conflicts from push go to stdout.
127
        self.assertEquals(out,
3978.2.5 by Jelmer Vernooij
Fix trailing whitespace.
128
                          'Using saved push location: %s\n'
4420.1.1 by Vincent Ladeuil
Cleanup imports.
129
                          % urlutils.local_path_from_url(path))
2220.2.38 by Martin Pool
Tag conflicts from push go to stdout.
130
        self.assertEqual(err,
3978.2.2 by Jelmer Vernooij
Write status messages during push to stderr rather than stdout.
131
                         'All changes applied successfully.\n'
132
                         'Pushed up to revision 2.\n')
1785.1.1 by John Arbash Meinel
Fix the output of 'bzr push' so that it prints the location correctly.
133
        self.assertEqual(path,
134
                         branch_b.bzrdir.root_transport.base)
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
135
        # test explicit --remember
4420.1.1 by Vincent Ladeuil
Cleanup imports.
136
        self.run_bzr('push ../branch_c --remember', working_dir='branch_a')
1785.1.1 by John Arbash Meinel
Fix the output of 'bzr push' so that it prints the location correctly.
137
        self.assertEquals(branch_a.get_push_location(),
138
                          branch_c.bzrdir.root_transport.base)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
139
1692.3.1 by Robert Collins
Fix push to work with just a branch, no need for a working tree.
140
    def test_push_without_tree(self):
141
        # bzr push from a branch that does not have a checkout should work.
142
        b = self.make_branch('.')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
143
        out, err = self.run_bzr('push pushed-location')
3978.2.2 by Jelmer Vernooij
Write status messages during push to stderr rather than stdout.
144
        self.assertEqual('', out)
145
        self.assertEqual('Created new branch.\n', err)
4420.1.1 by Vincent Ladeuil
Cleanup imports.
146
        b2 = branch.Branch.open('pushed-location')
1692.3.1 by Robert Collins
Fix push to work with just a branch, no need for a working tree.
147
        self.assertEndsWith(b2.base, 'pushed-location/')
1692.3.6 by Robert Collins
Show the correct number of revisions pushed when pushing a new branch (Robert Collins).
148
5448.6.5 by Matthew Gordon
Added test for push --no-tree.
149
    def test_push_no_tree(self):
150
        # bzr push --no-tree of a branch with working trees
151
        b = self.make_branch_and_tree('push-from')
152
        self.build_tree(['push-from/file'])
153
        b.add('file')
154
        b.commit('commit 1')
155
        out, err = self.run_bzr('push --no-tree -d push-from push-to')
156
        self.assertEqual('', out)
157
        self.assertEqual('Created new branch.\n', err)
158
        self.failIfExists('push-to/file')
159
1692.3.6 by Robert Collins
Show the correct number of revisions pushed when pushing a new branch (Robert Collins).
160
    def test_push_new_branch_revision_count(self):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
161
        # bzr push of a branch with revisions to a new location
162
        # should print the number of revisions equal to the length of the
1692.3.6 by Robert Collins
Show the correct number of revisions pushed when pushing a new branch (Robert Collins).
163
        # local branch.
164
        t = self.make_branch_and_tree('tree')
165
        self.build_tree(['tree/file'])
166
        t.add('file')
167
        t.commit('commit 1')
4420.1.1 by Vincent Ladeuil
Cleanup imports.
168
        out, err = self.run_bzr('push -d tree pushed-to')
3978.2.2 by Jelmer Vernooij
Write status messages during push to stderr rather than stdout.
169
        self.assertEqual('', out)
170
        self.assertEqual('Created new branch.\n', err)
1711.2.3 by John Arbash Meinel
Fix push to only push revisions in the current ancestry. (bug???)
171
172
    def test_push_only_pushes_history(self):
173
        # Knit branches should only push the history for the current revision.
4420.1.1 by Vincent Ladeuil
Cleanup imports.
174
        format = bzrdir.BzrDirMetaFormat1()
175
        format.repository_format = knitrepo.RepositoryFormatKnit1()
1711.2.3 by John Arbash Meinel
Fix push to only push revisions in the current ancestry. (bug???)
176
        shared_repo = self.make_repository('repo', format=format, shared=True)
177
        shared_repo.set_make_working_trees(True)
178
179
        def make_shared_tree(path):
180
            shared_repo.bzrdir.root_transport.mkdir(path)
181
            shared_repo.bzrdir.create_branch_convenience('repo/' + path)
4420.1.1 by Vincent Ladeuil
Cleanup imports.
182
            return workingtree.WorkingTree.open('repo/' + path)
1711.2.3 by John Arbash Meinel
Fix push to only push revisions in the current ancestry. (bug???)
183
        tree_a = make_shared_tree('a')
184
        self.build_tree(['repo/a/file'])
185
        tree_a.add('file')
186
        tree_a.commit('commit a-1', rev_id='a-1')
187
        f = open('repo/a/file', 'ab')
188
        f.write('more stuff\n')
189
        f.close()
190
        tree_a.commit('commit a-2', rev_id='a-2')
191
192
        tree_b = make_shared_tree('b')
193
        self.build_tree(['repo/b/file'])
194
        tree_b.add('file')
195
        tree_b.commit('commit b-1', rev_id='b-1')
196
197
        self.assertTrue(shared_repo.has_revision('a-1'))
198
        self.assertTrue(shared_repo.has_revision('a-2'))
199
        self.assertTrue(shared_repo.has_revision('b-1'))
200
201
        # Now that we have a repository with shared files, make sure
202
        # that things aren't copied out by a 'push'
4420.1.1 by Vincent Ladeuil
Cleanup imports.
203
        self.run_bzr('push ../../push-b', working_dir='repo/b')
204
        pushed_tree = workingtree.WorkingTree.open('push-b')
1711.2.3 by John Arbash Meinel
Fix push to only push revisions in the current ancestry. (bug???)
205
        pushed_repo = pushed_tree.branch.repository
206
        self.assertFalse(pushed_repo.has_revision('a-1'))
207
        self.assertFalse(pushed_repo.has_revision('a-2'))
208
        self.assertTrue(pushed_repo.has_revision('b-1'))
209
1843.2.1 by Aaron Bentley
Add failing tests for funky ids
210
    def test_push_funky_id(self):
211
        t = self.make_branch_and_tree('tree')
4420.1.1 by Vincent Ladeuil
Cleanup imports.
212
        self.build_tree(['tree/filename'])
1843.2.1 by Aaron Bentley
Add failing tests for funky ids
213
        t.add('filename', 'funky-chars<>%&;"\'')
214
        t.commit('commit filename')
4420.1.1 by Vincent Ladeuil
Cleanup imports.
215
        self.run_bzr('push -d tree new-tree')
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
216
2220.2.9 by Martin Pool
Add specific tests for push -d and pull -d
217
    def test_push_dash_d(self):
218
        t = self.make_branch_and_tree('from')
219
        t.commit(allow_pointless=True,
220
                message='first commit')
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
221
        self.run_bzr('push -d from to-one')
2220.2.9 by Martin Pool
Add specific tests for push -d and pull -d
222
        self.failUnlessExists('to-one')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
223
        self.run_bzr('push -d %s %s'
2220.2.9 by Martin Pool
Add specific tests for push -d and pull -d
224
            % tuple(map(urlutils.local_path_to_url, ['from', 'to-two'])))
225
        self.failUnlessExists('to-two')
2279.3.1 by mbp at sourcefrog
Add a -d option to push, pull, merge (ported from tags branch)
226
4011.2.1 by Robert Collins
Add ratchet style blackbox effort tests for push over bzr+ssh. (Andrew Bennetts, Robert Collins)
227
    def test_push_smart_non_stacked_streaming_acceptance(self):
4017.2.1 by Robert Collins
Add BzrDirFormatMeta1 test for the amount of rpc calls made initializing over the network.
228
        self.setup_smart_server_with_call_log()
4011.2.1 by Robert Collins
Add ratchet style blackbox effort tests for push over bzr+ssh. (Andrew Bennetts, Robert Collins)
229
        t = self.make_branch_and_tree('from')
230
        t.commit(allow_pointless=True, message='first commit')
4017.2.1 by Robert Collins
Add BzrDirFormatMeta1 test for the amount of rpc calls made initializing over the network.
231
        self.reset_smart_call_log()
4011.2.1 by Robert Collins
Add ratchet style blackbox effort tests for push over bzr+ssh. (Andrew Bennetts, Robert Collins)
232
        self.run_bzr(['push', self.get_url('to-one')], working_dir='from')
4011.2.4 by Robert Collins
Make the ratchet aspect of the blackbox smart server push acceptance tests clearer.
233
        # This figure represent the amount of work to perform this use case. It
234
        # is entirely ok to reduce this number if a test fails due to rpc_count
235
        # being too low. If rpc_count increases, more network roundtrips have
236
        # become necessary for this use case. Please do not adjust this number
237
        # upwards without agreement from bzr's network support maintainers.
4307.2.2 by Robert Collins
Lock repositories created by BzrDirFormat.initialize_on_transport_ex.
238
        self.assertLength(9, self.hpss_calls)
4011.2.1 by Robert Collins
Add ratchet style blackbox effort tests for push over bzr+ssh. (Andrew Bennetts, Robert Collins)
239
240
    def test_push_smart_stacked_streaming_acceptance(self):
4017.2.1 by Robert Collins
Add BzrDirFormatMeta1 test for the amount of rpc calls made initializing over the network.
241
        self.setup_smart_server_with_call_log()
4011.2.1 by Robert Collins
Add ratchet style blackbox effort tests for push over bzr+ssh. (Andrew Bennetts, Robert Collins)
242
        parent = self.make_branch_and_tree('parent', format='1.9')
243
        parent.commit(message='first commit')
244
        local = parent.bzrdir.sprout('local').open_workingtree()
245
        local.commit(message='local commit')
4017.2.1 by Robert Collins
Add BzrDirFormatMeta1 test for the amount of rpc calls made initializing over the network.
246
        self.reset_smart_call_log()
4011.2.1 by Robert Collins
Add ratchet style blackbox effort tests for push over bzr+ssh. (Andrew Bennetts, Robert Collins)
247
        self.run_bzr(['push', '--stacked', '--stacked-on', '../parent',
248
            self.get_url('public')], working_dir='local')
4011.2.4 by Robert Collins
Make the ratchet aspect of the blackbox smart server push acceptance tests clearer.
249
        # This figure represent the amount of work to perform this use case. It
250
        # is entirely ok to reduce this number if a test fails due to rpc_count
251
        # being too low. If rpc_count increases, more network roundtrips have
252
        # become necessary for this use case. Please do not adjust this number
253
        # upwards without agreement from bzr's network support maintainers.
4307.2.5 by Robert Collins
Remove too-early checks for revisions adding unnecessary round trips, at the cost of actually reading revision data when pulling (because we currently don't have a hint as about whats local for fetch).
254
        self.assertLength(14, self.hpss_calls)
4420.1.1 by Vincent Ladeuil
Cleanup imports.
255
        remote = branch.Branch.open('public')
4011.2.1 by Robert Collins
Add ratchet style blackbox effort tests for push over bzr+ssh. (Andrew Bennetts, Robert Collins)
256
        self.assertEndsWith(remote.get_stacked_on_url(), '/parent')
257
4556.2.1 by Andrew Bennetts
Add Branch.set_tags_bytes RPC, with HPSS call count acceptance test. Also fixes serialisation of LockDir, and uses external_url() in LockDir's repr and contention message.
258
    def test_push_smart_tags_streaming_acceptance(self):
259
        self.setup_smart_server_with_call_log()
260
        t = self.make_branch_and_tree('from')
261
        rev_id = t.commit(allow_pointless=True, message='first commit')
262
        t.branch.tags.set_tag('new-tag', rev_id)
263
        self.reset_smart_call_log()
264
        self.run_bzr(['push', self.get_url('to-one')], working_dir='from')
265
        # This figure represent the amount of work to perform this use case. It
266
        # is entirely ok to reduce this number if a test fails due to rpc_count
267
        # being too low. If rpc_count increases, more network roundtrips have
268
        # become necessary for this use case. Please do not adjust this number
269
        # upwards without agreement from bzr's network support maintainers.
270
        self.assertLength(11, self.hpss_calls)
271
4634.47.3 by Andrew Bennetts
Add a BzrDir.open_2.1 verb that indicates if there is a workingtree present. Removes the last 2 VFS calls from incremental pushes.
272
    def test_push_smart_incremental_acceptance(self):
273
        self.setup_smart_server_with_call_log()
274
        t = self.make_branch_and_tree('from')
275
        rev_id1 = t.commit(allow_pointless=True, message='first commit')
276
        rev_id2 = t.commit(allow_pointless=True, message='second commit')
277
        self.run_bzr(
278
            ['push', self.get_url('to-one'), '-r1'], working_dir='from')
279
        self.reset_smart_call_log()
280
        self.run_bzr(['push', self.get_url('to-one')], working_dir='from')
281
        # This figure represent the amount of work to perform this use case. It
282
        # is entirely ok to reduce this number if a test fails due to rpc_count
283
        # being too low. If rpc_count increases, more network roundtrips have
284
        # become necessary for this use case. Please do not adjust this number
285
        # upwards without agreement from bzr's network support maintainers.
286
        self.assertLength(11, self.hpss_calls)
287
4416.3.1 by Jonathan Lange
Add two tests, the second of which demonstrates bug 385132.
288
    def test_push_smart_with_default_stacking_url_path_segment(self):
4416.3.2 by Jonathan Lange
Comment the blackbox tests, for my own sanity.
289
        # If the default stacked-on location is a path element then branches
290
        # we push there over the smart server are stacked and their
291
        # stacked_on_url is that exact path segment. Added to nail bug 385132.
4416.3.1 by Jonathan Lange
Add two tests, the second of which demonstrates bug 385132.
292
        self.setup_smart_server_with_call_log()
293
        self.make_branch('stack-on', format='1.9')
4416.3.7 by Jonathan Lange
Update the test to fail correctly.
294
        self.make_bzrdir('.').get_config().set_default_stack_on(
4416.3.9 by Jonathan Lange
Put the test back the way it was.
295
            '/stack-on')
4416.3.1 by Jonathan Lange
Add two tests, the second of which demonstrates bug 385132.
296
        self.make_branch('from', format='1.9')
297
        out, err = self.run_bzr(['push', '-d', 'from', self.get_url('to')])
4416.3.10 by Jonathan Lange
Merge trunk
298
        b = branch.Branch.open(self.get_url('to'))
4416.3.12 by Jonathan Lange
This makes the test pass, but it's a bit ick.
299
        self.assertEqual('/extra/stack-on', b.get_stacked_on_url())
4416.3.1 by Jonathan Lange
Add two tests, the second of which demonstrates bug 385132.
300
301
    def test_push_smart_with_default_stacking_relative_path(self):
4416.3.2 by Jonathan Lange
Comment the blackbox tests, for my own sanity.
302
        # If the default stacked-on location is a relative path then branches
303
        # we push there over the smart server are stacked and their
304
        # stacked_on_url is a relative path. Added to nail bug 385132.
4416.3.1 by Jonathan Lange
Add two tests, the second of which demonstrates bug 385132.
305
        self.setup_smart_server_with_call_log()
306
        self.make_branch('stack-on', format='1.9')
307
        self.make_bzrdir('.').get_config().set_default_stack_on('stack-on')
308
        self.make_branch('from', format='1.9')
309
        out, err = self.run_bzr(['push', '-d', 'from', self.get_url('to')])
4416.3.10 by Jonathan Lange
Merge trunk
310
        b = branch.Branch.open(self.get_url('to'))
311
        self.assertEqual('../stack-on', b.get_stacked_on_url())
4416.3.1 by Jonathan Lange
Add two tests, the second of which demonstrates bug 385132.
312
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
313
    def create_simple_tree(self):
314
        tree = self.make_branch_and_tree('tree')
315
        self.build_tree(['tree/a'])
316
        tree.add(['a'], ['a-id'])
317
        tree.commit('one', rev_id='r1')
318
        return tree
319
320
    def test_push_create_prefix(self):
321
        """'bzr push --create-prefix' will create leading directories."""
322
        tree = self.create_simple_tree()
323
324
        self.run_bzr_error(['Parent directory of ../new/tree does not exist'],
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
325
                           'push ../new/tree',
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
326
                           working_dir='tree')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
327
        self.run_bzr('push ../new/tree --create-prefix',
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
328
                     working_dir='tree')
4420.1.1 by Vincent Ladeuil
Cleanup imports.
329
        new_tree = workingtree.WorkingTree.open('new/tree')
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
330
        self.assertEqual(tree.last_revision(), new_tree.last_revision())
331
        self.failUnlessExists('new/tree/a')
332
333
    def test_push_use_existing(self):
2227.3.4 by John Arbash Meinel
Switch back to --use-existing-dir
334
        """'bzr push --use-existing-dir' can push into an existing dir.
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
335
336
        By default, 'bzr push' will not use an existing, non-versioned dir.
337
        """
338
        tree = self.create_simple_tree()
339
        self.build_tree(['target/'])
340
341
        self.run_bzr_error(['Target directory ../target already exists',
2227.3.4 by John Arbash Meinel
Switch back to --use-existing-dir
342
                            'Supply --use-existing-dir',
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
343
                           ],
344
                           'push ../target', working_dir='tree')
2227.3.4 by John Arbash Meinel
Switch back to --use-existing-dir
345
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
346
        self.run_bzr('push --use-existing-dir ../target',
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
347
                     working_dir='tree')
348
4420.1.1 by Vincent Ladeuil
Cleanup imports.
349
        new_tree = workingtree.WorkingTree.open('target')
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
350
        self.assertEqual(tree.last_revision(), new_tree.last_revision())
351
        # The push should have created target/a
352
        self.failUnlessExists('target/a')
353
4634.105.1 by Andrew Bennetts
Fix traceback when doing 'bzr push --use-existing-dir' into a dir with an invalid .bzr directory.
354
    def test_push_use_existing_into_empty_bzrdir(self):
355
        """'bzr push --use-existing-dir' into a dir with an empty .bzr dir
356
        fails.
357
        """
358
        tree = self.create_simple_tree()
359
        self.build_tree(['target/', 'target/.bzr/'])
360
        self.run_bzr_error(
4634.105.2 by Andrew Bennetts
Clearer code and error message.
361
            ['Target directory ../target already contains a .bzr directory, '
362
             'but it is not valid.'],
4634.105.1 by Andrew Bennetts
Fix traceback when doing 'bzr push --use-existing-dir' into a dir with an invalid .bzr directory.
363
            'push ../target --use-existing-dir', working_dir='tree')
364
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
365
    def test_push_onto_repo(self):
366
        """We should be able to 'bzr push' into an existing bzrdir."""
367
        tree = self.create_simple_tree()
368
        repo = self.make_repository('repo', shared=True)
369
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
370
        self.run_bzr('push ../repo',
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
371
                     working_dir='tree')
372
373
        # Pushing onto an existing bzrdir will create a repository and
374
        # branch as needed, but will only create a working tree if there was
375
        # no BzrDir before.
4420.1.1 by Vincent Ladeuil
Cleanup imports.
376
        self.assertRaises(errors.NoWorkingTree,
377
                          workingtree.WorkingTree.open, 'repo')
378
        new_branch = branch.Branch.open('repo')
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
379
        self.assertEqual(tree.last_revision(), new_branch.last_revision())
380
381
    def test_push_onto_just_bzrdir(self):
382
        """We don't handle when the target is just a bzrdir.
383
384
        Because you shouldn't be able to create *just* a bzrdir in the wild.
385
        """
386
        # TODO: jam 20070109 Maybe it would be better to create the repository
387
        #       if at this point
388
        tree = self.create_simple_tree()
389
        a_bzrdir = self.make_bzrdir('dir')
390
391
        self.run_bzr_error(['At ../dir you have a valid .bzr control'],
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
392
                'push ../dir',
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
393
                working_dir='tree')
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
394
3256.1.1 by Daniel Watkins
Added test for push with a revspec.
395
    def test_push_with_revisionspec(self):
3256.1.3 by Daniel Watkins
Clarified test intent.
396
        """We should be able to push a revision older than the tip."""
3256.1.1 by Daniel Watkins
Added test for push with a revspec.
397
        tree_from = self.make_branch_and_tree('from')
398
        tree_from.commit("One.", rev_id="from-1")
399
        tree_from.commit("Two.", rev_id="from-2")
400
401
        self.run_bzr('push -r1 ../to', working_dir='from')
402
4420.1.1 by Vincent Ladeuil
Cleanup imports.
403
        tree_to = workingtree.WorkingTree.open('to')
3256.1.1 by Daniel Watkins
Added test for push with a revspec.
404
        repo_to = tree_to.branch.repository
405
        self.assertTrue(repo_to.has_revision('from-1'))
406
        self.assertFalse(repo_to.has_revision('from-2'))
407
        self.assertEqual(tree_to.branch.last_revision_info()[1], 'from-1')
408
3256.1.4 by Daniel Watkins
Added test to ensure that passing a range of revisions errors.
409
        self.run_bzr_error(
4325.4.6 by Vincent Ladeuil
Fixed as per John's and Markus reviews.
410
            ['bzr: ERROR: bzr push --revision '
411
             'takes exactly one revision identifier\n'],
3256.1.4 by Daniel Watkins
Added test to ensure that passing a range of revisions errors.
412
            'push -r0..2 ../to', working_dir='from')
413
3221.11.13 by Robert Collins
Allow push --shallow to just work, and fix the testing HTTPServer to not be affected by chdir() calls.
414
    def create_trunk_and_feature_branch(self):
3221.11.12 by Robert Collins
Basic push --reference support, requires url, slow.
415
        # We have a mainline
416
        trunk_tree = self.make_branch_and_tree('target',
4241.6.8 by Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil
Add --development6-rich-root, disabling the legacy and unneeded development2 format, and activating the tests for CHK features disabled pending this format. (Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil)
417
            format='1.9')
3221.11.12 by Robert Collins
Basic push --reference support, requires url, slow.
418
        trunk_tree.commit('mainline')
419
        # and a branch from it
420
        branch_tree = self.make_branch_and_tree('branch',
4241.6.8 by Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil
Add --development6-rich-root, disabling the legacy and unneeded development2 format, and activating the tests for CHK features disabled pending this format. (Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil)
421
            format='1.9')
3221.11.12 by Robert Collins
Basic push --reference support, requires url, slow.
422
        branch_tree.pull(trunk_tree.branch)
3221.11.13 by Robert Collins
Allow push --shallow to just work, and fix the testing HTTPServer to not be affected by chdir() calls.
423
        branch_tree.branch.set_parent(trunk_tree.branch.base)
3221.11.12 by Robert Collins
Basic push --reference support, requires url, slow.
424
        # with some work on it
3221.11.13 by Robert Collins
Allow push --shallow to just work, and fix the testing HTTPServer to not be affected by chdir() calls.
425
        branch_tree.commit('moar work plz')
426
        return trunk_tree, branch_tree
427
3221.11.14 by Robert Collins
Refactor to reduce duplication.
428
    def assertPublished(self, branch_revid, stacked_on):
429
        """Assert that the branch 'published' has been published correctly."""
4420.1.1 by Vincent Ladeuil
Cleanup imports.
430
        published_branch = branch.Branch.open('published')
3221.11.14 by Robert Collins
Refactor to reduce duplication.
431
        # The published branch refers to the mainline
3537.3.1 by Martin Pool
Rename branch.get_stacked_on to get_stacked_on_url
432
        self.assertEqual(stacked_on, published_branch.get_stacked_on_url())
3221.11.14 by Robert Collins
Refactor to reduce duplication.
433
        # and the branch's work was pushed
434
        self.assertTrue(published_branch.repository.has_revision(branch_revid))
435
3549.1.1 by Martin Pool
rename push --reference to --stacked-on
436
    def test_push_new_branch_stacked_on(self):
437
        """Pushing a new branch with --stacked-on creates a stacked branch."""
3221.11.13 by Robert Collins
Allow push --shallow to just work, and fix the testing HTTPServer to not be affected by chdir() calls.
438
        trunk_tree, branch_tree = self.create_trunk_and_feature_branch()
439
        # we publish branch_tree with a reference to the mainline.
3549.1.1 by Martin Pool
rename push --reference to --stacked-on
440
        out, err = self.run_bzr(['push', '--stacked-on', trunk_tree.branch.base,
3221.11.12 by Robert Collins
Basic push --reference support, requires url, slow.
441
            self.get_url('published')], working_dir='branch')
3978.2.2 by Jelmer Vernooij
Write status messages during push to stderr rather than stdout.
442
        self.assertEqual('', out)
3221.19.4 by Ian Clatworthy
shallow -> stacked
443
        self.assertEqual('Created new stacked branch referring to %s.\n' %
3978.2.2 by Jelmer Vernooij
Write status messages during push to stderr rather than stdout.
444
            trunk_tree.branch.base, err)
3221.11.14 by Robert Collins
Refactor to reduce duplication.
445
        self.assertPublished(branch_tree.last_revision(),
446
            trunk_tree.branch.base)
3221.11.13 by Robert Collins
Allow push --shallow to just work, and fix the testing HTTPServer to not be affected by chdir() calls.
447
3221.19.4 by Ian Clatworthy
shallow -> stacked
448
    def test_push_new_branch_stacked_uses_parent_when_no_public_url(self):
3221.11.17 by Robert Collins
no public location causes the parent to be used directly with push --shallow.
449
        """When the parent has no public url the parent is used as-is."""
450
        trunk_tree, branch_tree = self.create_trunk_and_feature_branch()
3221.19.4 by Ian Clatworthy
shallow -> stacked
451
        # now we do a stacked push, which should determine the public location
3221.11.17 by Robert Collins
no public location causes the parent to be used directly with push --shallow.
452
        # for us.
3221.19.4 by Ian Clatworthy
shallow -> stacked
453
        out, err = self.run_bzr(['push', '--stacked',
3221.11.17 by Robert Collins
no public location causes the parent to be used directly with push --shallow.
454
            self.get_url('published')], working_dir='branch')
3978.2.2 by Jelmer Vernooij
Write status messages during push to stderr rather than stdout.
455
        self.assertEqual('', out)
3221.19.4 by Ian Clatworthy
shallow -> stacked
456
        self.assertEqual('Created new stacked branch referring to %s.\n' %
3978.2.2 by Jelmer Vernooij
Write status messages during push to stderr rather than stdout.
457
            trunk_tree.branch.base, err)
4420.1.1 by Vincent Ladeuil
Cleanup imports.
458
        self.assertPublished(branch_tree.last_revision(),
459
                             trunk_tree.branch.base)
3221.11.17 by Robert Collins
no public location causes the parent to be used directly with push --shallow.
460
3221.19.4 by Ian Clatworthy
shallow -> stacked
461
    def test_push_new_branch_stacked_uses_parent_public(self):
462
        """Pushing a new branch with --stacked creates a stacked branch."""
3221.11.13 by Robert Collins
Allow push --shallow to just work, and fix the testing HTTPServer to not be affected by chdir() calls.
463
        trunk_tree, branch_tree = self.create_trunk_and_feature_branch()
464
        # the trunk is published on a web server
4420.1.1 by Vincent Ladeuil
Cleanup imports.
465
        self.transport_readonly_server = http_server.HttpServer
4241.6.8 by Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil
Add --development6-rich-root, disabling the legacy and unneeded development2 format, and activating the tests for CHK features disabled pending this format. (Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil)
466
        trunk_public = self.make_branch('public_trunk', format='1.9')
3221.11.13 by Robert Collins
Allow push --shallow to just work, and fix the testing HTTPServer to not be affected by chdir() calls.
467
        trunk_public.pull(trunk_tree.branch)
468
        trunk_public_url = self.get_readonly_url('public_trunk')
469
        trunk_tree.branch.set_public_branch(trunk_public_url)
3221.19.4 by Ian Clatworthy
shallow -> stacked
470
        # now we do a stacked push, which should determine the public location
3221.11.13 by Robert Collins
Allow push --shallow to just work, and fix the testing HTTPServer to not be affected by chdir() calls.
471
        # for us.
3221.19.4 by Ian Clatworthy
shallow -> stacked
472
        out, err = self.run_bzr(['push', '--stacked',
3221.11.13 by Robert Collins
Allow push --shallow to just work, and fix the testing HTTPServer to not be affected by chdir() calls.
473
            self.get_url('published')], working_dir='branch')
3978.2.2 by Jelmer Vernooij
Write status messages during push to stderr rather than stdout.
474
        self.assertEqual('', out)
3221.19.4 by Ian Clatworthy
shallow -> stacked
475
        self.assertEqual('Created new stacked branch referring to %s.\n' %
3978.2.2 by Jelmer Vernooij
Write status messages during push to stderr rather than stdout.
476
            trunk_public_url, err)
3221.11.14 by Robert Collins
Refactor to reduce duplication.
477
        self.assertPublished(branch_tree.last_revision(), trunk_public_url)
3221.11.12 by Robert Collins
Basic push --reference support, requires url, slow.
478
3221.19.4 by Ian Clatworthy
shallow -> stacked
479
    def test_push_new_branch_stacked_no_parent(self):
480
        """Pushing with --stacked and no parent branch errors."""
4241.6.8 by Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil
Add --development6-rich-root, disabling the legacy and unneeded development2 format, and activating the tests for CHK features disabled pending this format. (Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil)
481
        branch = self.make_branch_and_tree('branch', format='1.9')
3221.19.4 by Ian Clatworthy
shallow -> stacked
482
        # now we do a stacked push, which should fail as the place to refer too
3221.11.15 by Robert Collins
no parent branch causes an error on push --shallow.
483
        # cannot be determined.
484
        out, err = self.run_bzr_error(
3221.19.4 by Ian Clatworthy
shallow -> stacked
485
            ['Could not determine branch to refer to\\.'], ['push', '--stacked',
3221.11.15 by Robert Collins
no parent branch causes an error on push --shallow.
486
            self.get_url('published')], working_dir='branch')
487
        self.assertEqual('', out)
488
        self.assertFalse(self.get_transport('published').has('.'))
489
3606.8.3 by John Arbash Meinel
push doesn't notify because it doesn't notice by default.
490
    def test_push_notifies_default_stacking(self):
3735.1.2 by Robert Collins
Remove 1.5 series dev formats and document development2 a little better.
491
        self.make_branch('stack_on', format='1.6')
3242.3.34 by Aaron Bentley
Add notification of default stacking
492
        self.make_bzrdir('.').get_config().set_default_stack_on('stack_on')
3735.1.2 by Robert Collins
Remove 1.5 series dev formats and document development2 a little better.
493
        self.make_branch('from', format='1.6')
3242.3.34 by Aaron Bentley
Add notification of default stacking
494
        out, err = self.run_bzr('push -d from to')
3641.1.1 by John Arbash Meinel
Merge in 1.6rc5 and revert disabling default stack on policy
495
        self.assertContainsRe(err,
496
                              'Using default stacking branch stack_on at .*')
3242.3.34 by Aaron Bentley
Add notification of default stacking
497
4165.2.1 by Robert Collins
Fix bzr failing to stack when a server requests it and the branch it is pushing from cannot stack but the branch it should stack on can.
498
    def test_push_stacks_with_default_stacking_if_target_is_stackable(self):
499
        self.make_branch('stack_on', format='1.6')
500
        self.make_bzrdir('.').get_config().set_default_stack_on('stack_on')
501
        self.make_branch('from', format='pack-0.92')
502
        out, err = self.run_bzr('push -d from to')
4420.1.1 by Vincent Ladeuil
Cleanup imports.
503
        b = branch.Branch.open('to')
504
        self.assertEqual('../stack_on', b.get_stacked_on_url())
4165.2.1 by Robert Collins
Fix bzr failing to stack when a server requests it and the branch it is pushing from cannot stack but the branch it should stack on can.
505
506
    def test_push_does_not_change_format_with_default_if_target_cannot(self):
507
        self.make_branch('stack_on', format='pack-0.92')
508
        self.make_bzrdir('.').get_config().set_default_stack_on('stack_on')
509
        self.make_branch('from', format='pack-0.92')
510
        out, err = self.run_bzr('push -d from to')
4420.1.1 by Vincent Ladeuil
Cleanup imports.
511
        b = branch.Branch.open('to')
512
        self.assertRaises(errors.UnstackableBranchFormat, b.get_stacked_on_url)
4165.2.1 by Robert Collins
Fix bzr failing to stack when a server requests it and the branch it is pushing from cannot stack but the branch it should stack on can.
513
3904.3.2 by Andrew Bennetts
Blackbox test that triggers the bug. Should get replaced with a unit test.
514
    def test_push_doesnt_create_broken_branch(self):
3904.3.7 by Andrew Bennetts
Comment the new tests.
515
        """Pushing a new standalone branch works even when there's a default
516
        stacking policy at the destination.
517
518
        The new branch will preserve the repo format (even if it isn't the
519
        default for the branch), and will be stacked when the repo format
520
        allows (which means that the branch format isn't necessarly preserved).
521
        """
3904.3.2 by Andrew Bennetts
Blackbox test that triggers the bug. Should get replaced with a unit test.
522
        self.make_repository('repo', shared=True, format='1.6')
523
        builder = self.make_branch_builder('repo/local', format='pack-0.92')
524
        builder.start_series()
525
        builder.build_snapshot('rev-1', None, [
526
            ('add', ('', 'root-id', 'directory', '')),
3904.3.3 by Andrew Bennetts
Simplify test slightly.
527
            ('add', ('filename', 'f-id', 'file', 'content\n'))])
528
        builder.build_snapshot('rev-2', ['rev-1'], [])
3904.3.2 by Andrew Bennetts
Blackbox test that triggers the bug. Should get replaced with a unit test.
529
        builder.build_snapshot('rev-3', ['rev-2'],
3904.3.3 by Andrew Bennetts
Simplify test slightly.
530
            [('modify', ('f-id', 'new-content\n'))])
3904.3.2 by Andrew Bennetts
Blackbox test that triggers the bug. Should get replaced with a unit test.
531
        builder.finish_series()
532
        branch = builder.get_branch()
3904.3.7 by Andrew Bennetts
Comment the new tests.
533
        # Push rev-1 to "trunk", so that we can stack on it.
3904.3.2 by Andrew Bennetts
Blackbox test that triggers the bug. Should get replaced with a unit test.
534
        self.run_bzr('push -d repo/local trunk -r 1')
3904.3.7 by Andrew Bennetts
Comment the new tests.
535
        # Set a default stacking policy so that new branches will automatically
536
        # stack on trunk.
3904.3.2 by Andrew Bennetts
Blackbox test that triggers the bug. Should get replaced with a unit test.
537
        self.make_bzrdir('.').get_config().set_default_stack_on('trunk')
3904.3.7 by Andrew Bennetts
Comment the new tests.
538
        # Push rev-2 to a new branch "remote".  It will be stacked on "trunk".
3904.3.2 by Andrew Bennetts
Blackbox test that triggers the bug. Should get replaced with a unit test.
539
        out, err = self.run_bzr('push -d repo/local remote -r 2')
540
        self.assertContainsRe(
541
            err, 'Using default stacking branch trunk at .*')
3904.3.7 by Andrew Bennetts
Comment the new tests.
542
        # Push rev-3 onto "remote".  If "remote" not stacked and is missing the
543
        # fulltext record for f-id @ rev-1, then this will fail.
3904.3.2 by Andrew Bennetts
Blackbox test that triggers the bug. Should get replaced with a unit test.
544
        out, err = self.run_bzr('push -d repo/local remote -r 3')
545
3848.1.19 by Aaron Bentley
Show log for non-initial push -v
546
    def test_push_verbose_shows_log(self):
547
        tree = self.make_branch_and_tree('source')
548
        tree.commit('rev1')
549
        out, err = self.run_bzr('push -v -d source target')
550
        # initial push contains log
551
        self.assertContainsRe(out, 'rev1')
552
        tree.commit('rev2')
553
        out, err = self.run_bzr('push -v -d source target')
554
        # subsequent push contains log
555
        self.assertContainsRe(out, 'rev2')
556
        # subsequent log is accurate
557
        self.assertNotContainsRe(out, 'rev1')
558
4453.1.2 by Matthew Fuller
Add a test for pushing from subdir.
559
    def test_push_from_subdir(self):
560
        t = self.make_branch_and_tree('tree')
561
        self.build_tree(['tree/dir/', 'tree/dir/file'])
562
        t.add('dir', 'dir/file')
563
        t.commit('r1')
564
        out, err = self.run_bzr('push ../../pushloc', working_dir='tree/dir')
565
        self.assertEqual('', out)
566
        self.assertEqual('Created new branch.\n', err)
567
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
568
4420.1.1 by Vincent Ladeuil
Cleanup imports.
569
class RedirectingMemoryTransport(memory.MemoryTransport):
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
570
3878.4.4 by Vincent Ladeuil
Cleanup.
571
    def mkdir(self, relpath, mode=None):
572
        if self._cwd == '/source/':
573
            raise errors.RedirectRequested(self.abspath(relpath),
574
                                           self.abspath('../target'),
575
                                           is_permanent=True)
576
        elif self._cwd == '/infinite-loop/':
577
            raise errors.RedirectRequested(self.abspath(relpath),
578
                                           self.abspath('../infinite-loop'),
579
                                           is_permanent=True)
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
580
        else:
581
            return super(RedirectingMemoryTransport, self).mkdir(
3878.4.4 by Vincent Ladeuil
Cleanup.
582
                relpath, mode)
583
4547.2.2 by Andrew Bennetts
Add test for read_mergeable_from_transport raising NotABundle when TooManyRedirections happens.
584
    def get(self, relpath):
585
        if self.clone(relpath)._cwd == '/infinite-loop/':
586
            raise errors.RedirectRequested(self.abspath(relpath),
587
                                           self.abspath('../infinite-loop'),
588
                                           is_permanent=True)
589
        else:
590
            return super(RedirectingMemoryTransport, self).get(relpath)
591
3878.4.5 by Vincent Ladeuil
Don't use the exception as a parameter for _redirected_to.
592
    def _redirected_to(self, source, target):
3878.4.4 by Vincent Ladeuil
Cleanup.
593
        # We do accept redirections
3878.4.5 by Vincent Ladeuil
Don't use the exception as a parameter for _redirected_to.
594
        return transport.get_transport(target)
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
595
596
5017.3.45 by Vincent Ladeuil
Move MemoryServer back into bzrlib.transport.memory as it's needed as soon as a MemoryTransport is used. Add a NEWS entry.
597
class RedirectingMemoryServer(memory.MemoryServer):
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
598
4934.3.3 by Martin Pool
Rename Server.setUp to Server.start_server
599
    def start_server(self):
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
600
        self._dirs = {'/': None}
601
        self._files = {}
602
        self._locks = {}
603
        self._scheme = 'redirecting-memory+%s:///' % id(self)
3878.4.4 by Vincent Ladeuil
Cleanup.
604
        transport.register_transport(self._scheme, self._memory_factory)
3066.3.3 by jml at canonical
Unregister the test transport in order to be clean and to make test_selftest pass.
605
606
    def _memory_factory(self, url):
607
        result = RedirectingMemoryTransport(url)
608
        result._dirs = self._dirs
609
        result._files = self._files
610
        result._locks = self._locks
611
        return result
612
4934.3.1 by Martin Pool
Rename Server.tearDown to .stop_server
613
    def stop_server(self):
3878.4.4 by Vincent Ladeuil
Cleanup.
614
        transport.unregister_transport(self._scheme, self._memory_factory)
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
615
616
4420.1.1 by Vincent Ladeuil
Cleanup imports.
617
class TestPushRedirect(tests.TestCaseWithTransport):
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
618
619
    def setUp(self):
4420.1.1 by Vincent Ladeuil
Cleanup imports.
620
        tests.TestCaseWithTransport.setUp(self)
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
621
        self.memory_server = RedirectingMemoryServer()
4659.1.2 by Robert Collins
Refactor creation and shutdown of test servers to use a common helper,
622
        self.start_server(self.memory_server)
3066.3.2 by jml at canonical
Add tests to check the handling of TooManyRedirections.
623
        # Make the branch and tree that we'll be pushing.
624
        t = self.make_branch_and_tree('tree')
625
        self.build_tree(['tree/file'])
626
        t.add('file')
627
        t.commit('commit 1')
628
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
629
    def test_push_redirects_on_mkdir(self):
630
        """If the push requires a mkdir, push respects redirect requests.
631
632
        This is added primarily to handle lp:/ URI support, so that users can
633
        push to new branches by specifying lp:/ URIs.
634
        """
635
        destination_url = self.memory_server.get_url() + 'source'
3878.4.4 by Vincent Ladeuil
Cleanup.
636
        self.run_bzr(['push', '-d', 'tree', destination_url])
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
637
4420.1.1 by Vincent Ladeuil
Cleanup imports.
638
        local_revision = branch.Branch.open('tree').last_revision()
639
        remote_revision = branch.Branch.open(
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
640
            self.memory_server.get_url() + 'target').last_revision()
641
        self.assertEqual(remote_revision, local_revision)
3066.3.2 by jml at canonical
Add tests to check the handling of TooManyRedirections.
642
643
    def test_push_gracefully_handles_too_many_redirects(self):
644
        """Push fails gracefully if the mkdir generates a large number of
645
        redirects.
646
        """
647
        destination_url = self.memory_server.get_url() + 'infinite-loop'
648
        out, err = self.run_bzr_error(
649
            ['Too many redirections trying to make %s\\.\n'
650
             % re.escape(destination_url)],
3878.4.4 by Vincent Ladeuil
Cleanup.
651
            ['push', '-d', 'tree', destination_url], retcode=3)
3066.3.2 by jml at canonical
Add tests to check the handling of TooManyRedirections.
652
        self.assertEqual('', out)
4420.1.2 by Vincent Ladeuil
Fix bug #284038 by adding a --strict option to push.
653
654
4487.2.6 by Vincent Ladeuil
Fixed as per jam's review.
655
class TestPushStrictMixin(object):
4420.1.2 by Vincent Ladeuil
Fix bug #284038 by adding a --strict option to push.
656
657
    def make_local_branch_and_tree(self):
4487.2.2 by Vincent Ladeuil
Add tests for push --strict against pending merges.
658
        self.tree = self.make_branch_and_tree('local')
4420.1.2 by Vincent Ladeuil
Fix bug #284038 by adding a --strict option to push.
659
        self.build_tree_contents([('local/file', 'initial')])
4487.2.2 by Vincent Ladeuil
Add tests for push --strict against pending merges.
660
        self.tree.add('file')
4487.2.3 by Vincent Ladeuil
--strict is meaningless when --revision is specified.
661
        self.tree.commit('adding file', rev_id='added')
662
        self.build_tree_contents([('local/file', 'modified')])
663
        self.tree.commit('modify file', rev_id='modified')
4487.2.2 by Vincent Ladeuil
Add tests for push --strict against pending merges.
664
665
    def set_config_push_strict(self, value):
4420.1.5 by Vincent Ladeuil
Start implementing jam's review feedback.
666
        # set config var (any of bazaar.conf, locations.conf, branch.conf
667
        # should do)
4487.2.2 by Vincent Ladeuil
Add tests for push --strict against pending merges.
668
        conf = self.tree.branch.get_config()
4420.1.5 by Vincent Ladeuil
Start implementing jam's review feedback.
669
        conf.set_user_option('push_strict', value)
670
4487.2.6 by Vincent Ladeuil
Fixed as per jam's review.
671
    _default_command = ['push', '../to']
672
    _default_wd = 'local'
673
    _default_errors = ['Working tree ".*/local/" has uncommitted '
674
                       'changes \(See bzr status\)\.',]
5171.2.3 by Vincent Ladeuil
Fixed as per Andrew's review.
675
    _default_additional_error = 'Use --no-strict to force the push.\n'
676
    _default_additional_warning = 'Uncommitted changes will not be pushed.'
677
4487.2.6 by Vincent Ladeuil
Fixed as per jam's review.
678
4487.2.2 by Vincent Ladeuil
Add tests for push --strict against pending merges.
679
    def assertPushFails(self, args):
5171.2.3 by Vincent Ladeuil
Fixed as per Andrew's review.
680
        out, err = self.run_bzr_error(self._default_errors,
681
                                      self._default_command + args,
682
                                      working_dir=self._default_wd, retcode=3)
683
        self.assertContainsRe(err, self._default_additional_error)
4420.1.5 by Vincent Ladeuil
Start implementing jam's review feedback.
684
5171.2.3 by Vincent Ladeuil
Fixed as per Andrew's review.
685
    def assertPushSucceeds(self, args, with_warning=False, revid_to_push=None):
5147.2.1 by Vincent Ladeuil
Failing tests for bug #519319.
686
        if with_warning:
687
            error_regexes = self._default_errors
688
        else:
689
            error_regexes = []
5171.2.3 by Vincent Ladeuil
Fixed as per Andrew's review.
690
        out, err = self.run_bzr(self._default_command + args,
691
                                working_dir=self._default_wd,
692
                                error_regexes=error_regexes)
693
        if with_warning:
694
            self.assertContainsRe(err, self._default_additional_warning)
695
        else:
696
            self.assertNotContainsRe(err, self._default_additional_warning)
697
        branch_from = branch.Branch.open(self._default_wd)
698
        if revid_to_push is None:
699
            revid_to_push = branch_from.last_revision()
700
        branch_to = branch.Branch.open('to')
701
        repo_to = branch_to.repository
702
        self.assertTrue(repo_to.has_revision(revid_to_push))
703
        self.assertEqual(revid_to_push, branch_to.last_revision())
4420.1.2 by Vincent Ladeuil
Fix bug #284038 by adding a --strict option to push.
704
4487.2.2 by Vincent Ladeuil
Add tests for push --strict against pending merges.
705
706
4487.2.6 by Vincent Ladeuil
Fixed as per jam's review.
707
class TestPushStrictWithoutChanges(tests.TestCaseWithTransport,
708
                                   TestPushStrictMixin):
4487.2.2 by Vincent Ladeuil
Add tests for push --strict against pending merges.
709
710
    def setUp(self):
711
        super(TestPushStrictWithoutChanges, self).setUp()
712
        self.make_local_branch_and_tree()
713
714
    def test_push_default(self):
715
        self.assertPushSucceeds([])
716
717
    def test_push_strict(self):
718
        self.assertPushSucceeds(['--strict'])
719
720
    def test_push_no_strict(self):
721
        self.assertPushSucceeds(['--no-strict'])
722
723
    def test_push_config_var_strict(self):
724
        self.set_config_push_strict('true')
725
        self.assertPushSucceeds([])
726
727
    def test_push_config_var_no_strict(self):
728
        self.set_config_push_strict('false')
729
        self.assertPushSucceeds([])
730
731
4487.2.6 by Vincent Ladeuil
Fixed as per jam's review.
732
class TestPushStrictWithChanges(tests.TestCaseWithTransport,
733
                                TestPushStrictMixin):
4487.2.2 by Vincent Ladeuil
Add tests for push --strict against pending merges.
734
4487.2.3 by Vincent Ladeuil
--strict is meaningless when --revision is specified.
735
    _changes_type = None # Set by load_tests
4487.2.2 by Vincent Ladeuil
Add tests for push --strict against pending merges.
736
737
    def setUp(self):
738
        super(TestPushStrictWithChanges, self).setUp()
4721.2.6 by Vincent Ladeuil
More agressive test sharing between push and dpush.
739
        # Apply the changes defined in load_tests: one of _uncommitted_changes,
740
        # _pending_merges or _out_of_sync_trees
4487.2.3 by Vincent Ladeuil
--strict is meaningless when --revision is specified.
741
        getattr(self, self._changes_type)()
4487.2.2 by Vincent Ladeuil
Add tests for push --strict against pending merges.
742
4487.2.3 by Vincent Ladeuil
--strict is meaningless when --revision is specified.
743
    def _uncommitted_changes(self):
4487.2.2 by Vincent Ladeuil
Add tests for push --strict against pending merges.
744
        self.make_local_branch_and_tree()
745
        # Make a change without committing it
4487.2.3 by Vincent Ladeuil
--strict is meaningless when --revision is specified.
746
        self.build_tree_contents([('local/file', 'in progress')])
4487.2.2 by Vincent Ladeuil
Add tests for push --strict against pending merges.
747
4487.2.3 by Vincent Ladeuil
--strict is meaningless when --revision is specified.
748
    def _pending_merges(self):
4487.2.2 by Vincent Ladeuil
Add tests for push --strict against pending merges.
749
        self.make_local_branch_and_tree()
750
        # Create 'other' branch containing a new file
751
        other_bzrdir = self.tree.bzrdir.sprout('other')
752
        other_tree = other_bzrdir.open_workingtree()
753
        self.build_tree_contents([('other/other-file', 'other')])
754
        other_tree.add('other-file')
755
        other_tree.commit('other commit', rev_id='other')
756
        # Merge and revert, leaving a pending merge
757
        self.tree.merge_from_branch(other_tree.branch)
758
        self.tree.revert(filenames=['other-file'], backups=False)
759
4487.2.6 by Vincent Ladeuil
Fixed as per jam's review.
760
    def _out_of_sync_trees(self):
761
        self.make_local_branch_and_tree()
762
        self.run_bzr(['checkout', '--lightweight', 'local', 'checkout'])
763
        # Make a change and commit it
764
        self.build_tree_contents([('local/file', 'modified in local')])
765
        self.tree.commit('modify file', rev_id='modified-in-local')
766
        # Exercise commands from the checkout directory
767
        self._default_wd = 'checkout'
768
        self._default_errors = ["Working tree is out of date, please run"
769
                                " 'bzr update'\.",]
770
4487.2.2 by Vincent Ladeuil
Add tests for push --strict against pending merges.
771
    def test_push_default(self):
5147.2.1 by Vincent Ladeuil
Failing tests for bug #519319.
772
        self.assertPushSucceeds([], with_warning=True)
4420.1.5 by Vincent Ladeuil
Start implementing jam's review feedback.
773
4487.2.3 by Vincent Ladeuil
--strict is meaningless when --revision is specified.
774
    def test_push_with_revision(self):
5171.2.3 by Vincent Ladeuil
Fixed as per Andrew's review.
775
        self.assertPushSucceeds(['-r', 'revid:added'], revid_to_push='added')
4487.2.3 by Vincent Ladeuil
--strict is meaningless when --revision is specified.
776
777
    def test_push_no_strict(self):
4487.2.2 by Vincent Ladeuil
Add tests for push --strict against pending merges.
778
        self.assertPushSucceeds(['--no-strict'])
4420.1.2 by Vincent Ladeuil
Fix bug #284038 by adding a --strict option to push.
779
780
    def test_push_strict_with_changes(self):
4487.2.2 by Vincent Ladeuil
Add tests for push --strict against pending merges.
781
        self.assertPushFails(['--strict'])
4420.1.5 by Vincent Ladeuil
Start implementing jam's review feedback.
782
783
    def test_push_respect_config_var_strict(self):
4487.2.2 by Vincent Ladeuil
Add tests for push --strict against pending merges.
784
        self.set_config_push_strict('true')
785
        self.assertPushFails([])
4420.1.5 by Vincent Ladeuil
Start implementing jam's review feedback.
786
4420.1.6 by Vincent Ladeuil
Fixed as per John's review feedback.
787
    def test_push_bogus_config_var_ignored(self):
4487.2.2 by Vincent Ladeuil
Add tests for push --strict against pending merges.
788
        self.set_config_push_strict("I don't want you to be strict")
5147.2.1 by Vincent Ladeuil
Failing tests for bug #519319.
789
        self.assertPushSucceeds([], with_warning=True)
4420.1.6 by Vincent Ladeuil
Fixed as per John's review feedback.
790
4420.1.5 by Vincent Ladeuil
Start implementing jam's review feedback.
791
    def test_push_no_strict_command_line_override_config(self):
4487.2.2 by Vincent Ladeuil
Add tests for push --strict against pending merges.
792
        self.set_config_push_strict('yES')
793
        self.assertPushFails([])
794
        self.assertPushSucceeds(['--no-strict'])
4420.1.5 by Vincent Ladeuil
Start implementing jam's review feedback.
795
796
    def test_push_strict_command_line_override_config(self):
4487.2.2 by Vincent Ladeuil
Add tests for push --strict against pending merges.
797
        self.set_config_push_strict('oFF')
798
        self.assertPushFails(['--strict'])
799
        self.assertPushSucceeds([])
4925.1.1 by Jelmer Vernooij
Print a proper error when attempting to push to a foreign VCS for which
800
801
5283.4.5 by Martin Pool
Update remaining subclasses of ExternalBase
802
class TestPushForeign(tests.TestCaseWithTransport):
4925.1.1 by Jelmer Vernooij
Print a proper error when attempting to push to a foreign VCS for which
803
804
    def setUp(self):
805
        super(TestPushForeign, self).setUp()
806
        test_foreign.register_dummy_foreign_for_test(self)
807
808
    def make_dummy_builder(self, relpath):
809
        builder = self.make_branch_builder(
810
            relpath, format=test_foreign.DummyForeignVcsDirFormat())
811
        builder.build_snapshot('revid', None,
812
            [('add', ('', 'TREE_ROOT', 'directory', None)),
813
             ('add', ('foo', 'fooid', 'file', 'bar'))])
814
        return builder
815
816
    def test_no_roundtripping(self):
817
        target_branch = self.make_dummy_builder('dp').get_branch()
818
        source_tree = self.make_branch_and_tree("dc")
819
        output, error = self.run_bzr("push -d dc dp", retcode=3)
820
        self.assertEquals("", output)
821
        self.assertEquals(error, "bzr: ERROR: It is not possible to losslessly"
822
            " push to dummy. You may want to use dpush instead.\n")