/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2220.2.9 by Martin Pool
Add specific tests for push -d and pull -d
1
# Copyright (C) 2005, 2007 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
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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
20
import os
3066.3.2 by jml at canonical
Add tests to check the handling of TooManyRedirections.
21
import re
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
22
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
23
from bzrlib import (
24
    errors,
2220.2.9 by Martin Pool
Add specific tests for push -d and pull -d
25
    urlutils,
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
26
    )
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
27
from bzrlib.branch import Branch
2279.1.3 by John Arbash Meinel
Switch the test to being a branch_implementation test.
28
from bzrlib.bzrdir import BzrDirMetaFormat1
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
29
from bzrlib.osutils import abspath
2241.1.6 by Martin Pool
Move Knit repositories into the submodule bzrlib.repofmt.knitrepo and
30
from bzrlib.repofmt.knitrepo import RepositoryFormatKnit1
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
31
from bzrlib.tests.blackbox import ExternalBase
3066.3.3 by jml at canonical
Unregister the test transport in order to be clean and to make test_selftest pass.
32
from bzrlib.transport import register_transport, unregister_transport
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
33
from bzrlib.transport.memory import MemoryServer, MemoryTransport
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
34
from bzrlib.uncommit import uncommit
1785.1.1 by John Arbash Meinel
Fix the output of 'bzr push' so that it prints the location correctly.
35
from bzrlib.urlutils import local_path_from_url
1711.2.3 by John Arbash Meinel
Fix push to only push revisions in the current ancestry. (bug???)
36
from bzrlib.workingtree import WorkingTree
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
37
38
39
class TestPush(ExternalBase):
40
41
    def test_push_remember(self):
42
        """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.
43
        transport = self.get_transport()
44
        tree_a = self.make_branch_and_tree('branch_a')
45
        branch_a = tree_a.branch
46
        self.build_tree(['branch_a/a'])
47
        tree_a.add('a')
48
        tree_a.commit('commit a')
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
49
        tree_b = branch_a.bzrdir.sprout('branch_b').open_workingtree()
50
        branch_b = tree_b.branch
51
        tree_c = branch_a.bzrdir.sprout('branch_c').open_workingtree()
52
        branch_c = tree_c.branch
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
53
        self.build_tree(['branch_a/b'])
54
        tree_a.add('b')
55
        tree_a.commit('commit b')
56
        self.build_tree(['branch_b/c'])
57
        tree_b.add('c')
58
        tree_b.commit('commit c')
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
59
        # initial push location must be empty
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
60
        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)
61
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
62
        # test push for failure without push location set
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
63
        os.chdir('branch_a')
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
64
        out = self.run_bzr('push', retcode=3)
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
65
        self.assertEquals(out,
66
                ('','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)
67
68
        # test not remembered if cannot actually push
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
69
        self.run_bzr('push ../path/which/doesnt/exist', 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)
70
        out = self.run_bzr('push', retcode=3)
71
        self.assertEquals(
72
                ('', 'bzr: ERROR: No push location known or specified.\n'),
73
                out)
74
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
75
        # test implicit --remember when no push location set, push fails
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
76
        out = self.run_bzr('push ../branch_b', retcode=3)
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
77
        self.assertEquals(out,
78
                ('','bzr: ERROR: These branches have diverged.  '
2063.2.1 by John Arbash Meinel
(Matthieu Moy) cleanup message when pushing to diverged branch
79
                    'Try using "merge" and then "push".\n'))
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
80
        self.assertEquals(abspath(branch_a.get_push_location()),
81
                          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)
82
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
83
        # test implicit --remember after resolving previous failure
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
84
        uncommit(branch=branch_b, tree=tree_b)
85
        transport.delete('branch_b/c')
2220.2.38 by Martin Pool
Tag conflicts from push go to stdout.
86
        out, err = self.run_bzr('push')
1785.1.1 by John Arbash Meinel
Fix the output of 'bzr push' so that it prints the location correctly.
87
        path = branch_a.get_push_location()
2220.2.38 by Martin Pool
Tag conflicts from push go to stdout.
88
        self.assertEquals(out,
89
                          'Using saved location: %s\n' 
90
                          'Pushed up to revision 2.\n'
91
                          % local_path_from_url(path))
92
        self.assertEqual(err,
93
                         'All changes applied successfully.\n')
1785.1.1 by John Arbash Meinel
Fix the output of 'bzr push' so that it prints the location correctly.
94
        self.assertEqual(path,
95
                         branch_b.bzrdir.root_transport.base)
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
96
        # test explicit --remember
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
97
        self.run_bzr('push ../branch_c --remember')
1785.1.1 by John Arbash Meinel
Fix the output of 'bzr push' so that it prints the location correctly.
98
        self.assertEquals(branch_a.get_push_location(),
99
                          branch_c.bzrdir.root_transport.base)
1692.3.1 by Robert Collins
Fix push to work with just a branch, no need for a working tree.
100
    
101
    def test_push_without_tree(self):
102
        # bzr push from a branch that does not have a checkout should work.
103
        b = self.make_branch('.')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
104
        out, err = self.run_bzr('push pushed-location')
1692.3.1 by Robert Collins
Fix push to work with just a branch, no need for a working tree.
105
        self.assertEqual('', out)
2297.1.4 by Martin Pool
Push now returns a PushResult rather than just an integer.
106
        self.assertEqual('Created new branch.\n', err)
2220.2.9 by Martin Pool
Add specific tests for push -d and pull -d
107
        b2 = Branch.open('pushed-location')
1692.3.1 by Robert Collins
Fix push to work with just a branch, no need for a working tree.
108
        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).
109
110
    def test_push_new_branch_revision_count(self):
111
        # bzr push of a branch with revisions to a new location 
112
        # should print the number of revisions equal to the length of the 
113
        # local branch.
114
        t = self.make_branch_and_tree('tree')
115
        self.build_tree(['tree/file'])
116
        t.add('file')
117
        t.commit('commit 1')
118
        os.chdir('tree')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
119
        out, err = self.run_bzr('push pushed-to')
1692.3.6 by Robert Collins
Show the correct number of revisions pushed when pushing a new branch (Robert Collins).
120
        os.chdir('..')
121
        self.assertEqual('', out)
2297.1.4 by Martin Pool
Push now returns a PushResult rather than just an integer.
122
        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???)
123
124
    def test_push_only_pushes_history(self):
125
        # Knit branches should only push the history for the current revision.
126
        format = BzrDirMetaFormat1()
127
        format.repository_format = RepositoryFormatKnit1()
128
        shared_repo = self.make_repository('repo', format=format, shared=True)
129
        shared_repo.set_make_working_trees(True)
130
131
        def make_shared_tree(path):
132
            shared_repo.bzrdir.root_transport.mkdir(path)
133
            shared_repo.bzrdir.create_branch_convenience('repo/' + path)
134
            return WorkingTree.open('repo/' + path)
135
        tree_a = make_shared_tree('a')
136
        self.build_tree(['repo/a/file'])
137
        tree_a.add('file')
138
        tree_a.commit('commit a-1', rev_id='a-1')
139
        f = open('repo/a/file', 'ab')
140
        f.write('more stuff\n')
141
        f.close()
142
        tree_a.commit('commit a-2', rev_id='a-2')
143
144
        tree_b = make_shared_tree('b')
145
        self.build_tree(['repo/b/file'])
146
        tree_b.add('file')
147
        tree_b.commit('commit b-1', rev_id='b-1')
148
149
        self.assertTrue(shared_repo.has_revision('a-1'))
150
        self.assertTrue(shared_repo.has_revision('a-2'))
151
        self.assertTrue(shared_repo.has_revision('b-1'))
152
153
        # Now that we have a repository with shared files, make sure
154
        # that things aren't copied out by a 'push'
155
        os.chdir('repo/b')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
156
        self.run_bzr('push ../../push-b')
1711.2.3 by John Arbash Meinel
Fix push to only push revisions in the current ancestry. (bug???)
157
        pushed_tree = WorkingTree.open('../../push-b')
158
        pushed_repo = pushed_tree.branch.repository
159
        self.assertFalse(pushed_repo.has_revision('a-1'))
160
        self.assertFalse(pushed_repo.has_revision('a-2'))
161
        self.assertTrue(pushed_repo.has_revision('b-1'))
162
1843.2.1 by Aaron Bentley
Add failing tests for funky ids
163
    def test_push_funky_id(self):
164
        t = self.make_branch_and_tree('tree')
165
        os.chdir('tree')
166
        self.build_tree(['filename'])
167
        t.add('filename', 'funky-chars<>%&;"\'')
168
        t.commit('commit filename')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
169
        self.run_bzr('push ../new-tree')
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
170
2220.2.9 by Martin Pool
Add specific tests for push -d and pull -d
171
    def test_push_dash_d(self):
172
        t = self.make_branch_and_tree('from')
173
        t.commit(allow_pointless=True,
174
                message='first commit')
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
175
        self.run_bzr('push -d from to-one')
2220.2.9 by Martin Pool
Add specific tests for push -d and pull -d
176
        self.failUnlessExists('to-one')
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
177
        self.run_bzr('push -d %s %s' 
2220.2.9 by Martin Pool
Add specific tests for push -d and pull -d
178
            % tuple(map(urlutils.local_path_to_url, ['from', 'to-two'])))
179
        self.failUnlessExists('to-two')
2279.3.1 by mbp at sourcefrog
Add a -d option to push, pull, merge (ported from tags branch)
180
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
181
    def create_simple_tree(self):
182
        tree = self.make_branch_and_tree('tree')
183
        self.build_tree(['tree/a'])
184
        tree.add(['a'], ['a-id'])
185
        tree.commit('one', rev_id='r1')
186
        return tree
187
188
    def test_push_create_prefix(self):
189
        """'bzr push --create-prefix' will create leading directories."""
190
        tree = self.create_simple_tree()
191
192
        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.
193
                           'push ../new/tree',
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
194
                           working_dir='tree')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
195
        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
196
                     working_dir='tree')
197
        new_tree = WorkingTree.open('new/tree')
198
        self.assertEqual(tree.last_revision(), new_tree.last_revision())
199
        self.failUnlessExists('new/tree/a')
200
201
    def test_push_use_existing(self):
2227.3.4 by John Arbash Meinel
Switch back to --use-existing-dir
202
        """'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
203
204
        By default, 'bzr push' will not use an existing, non-versioned dir.
205
        """
206
        tree = self.create_simple_tree()
207
        self.build_tree(['target/'])
208
209
        self.run_bzr_error(['Target directory ../target already exists',
2227.3.4 by John Arbash Meinel
Switch back to --use-existing-dir
210
                            'Supply --use-existing-dir',
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
211
                           ],
212
                           'push ../target', working_dir='tree')
2227.3.4 by John Arbash Meinel
Switch back to --use-existing-dir
213
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
214
        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
215
                     working_dir='tree')
216
217
        new_tree = WorkingTree.open('target')
218
        self.assertEqual(tree.last_revision(), new_tree.last_revision())
219
        # The push should have created target/a
220
        self.failUnlessExists('target/a')
221
222
    def test_push_onto_repo(self):
223
        """We should be able to 'bzr push' into an existing bzrdir."""
224
        tree = self.create_simple_tree()
225
        repo = self.make_repository('repo', shared=True)
226
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
227
        self.run_bzr('push ../repo',
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
228
                     working_dir='tree')
229
230
        # Pushing onto an existing bzrdir will create a repository and
231
        # branch as needed, but will only create a working tree if there was
232
        # no BzrDir before.
233
        self.assertRaises(errors.NoWorkingTree, WorkingTree.open, 'repo')
234
        new_branch = Branch.open('repo')
235
        self.assertEqual(tree.last_revision(), new_branch.last_revision())
236
237
    def test_push_onto_just_bzrdir(self):
238
        """We don't handle when the target is just a bzrdir.
239
240
        Because you shouldn't be able to create *just* a bzrdir in the wild.
241
        """
242
        # TODO: jam 20070109 Maybe it would be better to create the repository
243
        #       if at this point
244
        tree = self.create_simple_tree()
245
        a_bzrdir = self.make_bzrdir('dir')
246
247
        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.
248
                'push ../dir',
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
249
                working_dir='tree')
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
250
3256.1.1 by Daniel Watkins
Added test for push with a revspec.
251
    def test_push_with_revisionspec(self):
3256.1.3 by Daniel Watkins
Clarified test intent.
252
        """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.
253
        tree_from = self.make_branch_and_tree('from')
254
        tree_from.commit("One.", rev_id="from-1")
255
        tree_from.commit("Two.", rev_id="from-2")
256
257
        self.run_bzr('push -r1 ../to', working_dir='from')
258
259
        tree_to = WorkingTree.open('to')
260
        repo_to = tree_to.branch.repository
261
        self.assertTrue(repo_to.has_revision('from-1'))
262
        self.assertFalse(repo_to.has_revision('from-2'))
263
        self.assertEqual(tree_to.branch.last_revision_info()[1], 'from-1')
264
3256.1.4 by Daniel Watkins
Added test to ensure that passing a range of revisions errors.
265
        self.run_bzr_error(
266
            "bzr: ERROR: bzr push --revision takes one value.\n",
267
            'push -r0..2 ../to', working_dir='from')
268
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
269
270
class RedirectingMemoryTransport(MemoryTransport):
271
272
    def mkdir(self, path, mode=None):
3066.3.2 by jml at canonical
Add tests to check the handling of TooManyRedirections.
273
        path = self.abspath(path)[len(self._scheme):]
274
        if path == '/source':
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
275
            raise errors.RedirectRequested(
276
                path, self._scheme + '/target', is_permanent=True)
3066.3.2 by jml at canonical
Add tests to check the handling of TooManyRedirections.
277
        elif path == '/infinite-loop':
278
            raise errors.RedirectRequested(
279
                path, self._scheme + '/infinite-loop', is_permanent=True)
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
280
        else:
281
            return super(RedirectingMemoryTransport, self).mkdir(
282
                path, mode)
283
284
285
class RedirectingMemoryServer(MemoryServer):
286
287
    def setUp(self):
288
        self._dirs = {'/': None}
289
        self._files = {}
290
        self._locks = {}
291
        self._scheme = 'redirecting-memory+%s:///' % id(self)
3066.3.3 by jml at canonical
Unregister the test transport in order to be clean and to make test_selftest pass.
292
        register_transport(self._scheme, self._memory_factory)
293
294
    def _memory_factory(self, url):
295
        result = RedirectingMemoryTransport(url)
296
        result._dirs = self._dirs
297
        result._files = self._files
298
        result._locks = self._locks
299
        return result
300
301
    def tearDown(self):
302
        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
303
304
305
class TestPushRedirect(ExternalBase):
306
307
    def setUp(self):
308
        ExternalBase.setUp(self)
309
        self.memory_server = RedirectingMemoryServer()
310
        self.memory_server.setUp()
311
        self.addCleanup(self.memory_server.tearDown)
312
3066.3.2 by jml at canonical
Add tests to check the handling of TooManyRedirections.
313
        # Make the branch and tree that we'll be pushing.
314
        t = self.make_branch_and_tree('tree')
315
        self.build_tree(['tree/file'])
316
        t.add('file')
317
        t.commit('commit 1')
318
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
319
    def test_push_redirects_on_mkdir(self):
320
        """If the push requires a mkdir, push respects redirect requests.
321
322
        This is added primarily to handle lp:/ URI support, so that users can
323
        push to new branches by specifying lp:/ URIs.
324
        """
325
        os.chdir('tree')
326
        destination_url = self.memory_server.get_url() + 'source'
327
        self.run_bzr('push %s' % destination_url)
328
        os.chdir('..')
329
330
        local_revision = Branch.open('tree').last_revision()
331
        remote_revision = Branch.open(
332
            self.memory_server.get_url() + 'target').last_revision()
333
        self.assertEqual(remote_revision, local_revision)
3066.3.2 by jml at canonical
Add tests to check the handling of TooManyRedirections.
334
335
    def test_push_gracefully_handles_too_many_redirects(self):
336
        """Push fails gracefully if the mkdir generates a large number of
337
        redirects.
338
        """
339
        os.chdir('tree')
340
        destination_url = self.memory_server.get_url() + 'infinite-loop'
341
        out, err = self.run_bzr_error(
342
            ['Too many redirections trying to make %s\\.\n'
343
             % re.escape(destination_url)],
344
            'push %s' % destination_url, retcode=3)
345
        os.chdir('..')
346
        self.assertEqual('', out)