~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/blackbox/test_push.py

Merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
"""Black-box tests for bzr push."""
19
19
 
20
20
import os
 
21
import re
21
22
 
22
23
from bzrlib import (
23
24
    errors,
28
29
from bzrlib.osutils import abspath
29
30
from bzrlib.repofmt.knitrepo import RepositoryFormatKnit1
30
31
from bzrlib.tests.blackbox import ExternalBase
 
32
from bzrlib.transport import register_transport, unregister_transport
 
33
from bzrlib.transport.memory import MemoryServer, MemoryTransport
31
34
from bzrlib.uncommit import uncommit
32
35
from bzrlib.urlutils import local_path_from_url
33
36
from bzrlib.workingtree import WorkingTree
58
61
 
59
62
        # test push for failure without push location set
60
63
        os.chdir('branch_a')
61
 
        out = self.runbzr('push', retcode=3)
 
64
        out = self.run_bzr('push', retcode=3)
62
65
        self.assertEquals(out,
63
66
                ('','bzr: ERROR: No push location known or specified.\n'))
64
67
 
65
68
        # test not remembered if cannot actually push
66
 
        self.run_bzr('push', '../path/which/doesnt/exist', retcode=3)
 
69
        self.run_bzr('push ../path/which/doesnt/exist', retcode=3)
67
70
        out = self.run_bzr('push', retcode=3)
68
71
        self.assertEquals(
69
72
                ('', 'bzr: ERROR: No push location known or specified.\n'),
70
73
                out)
71
74
 
72
75
        # test implicit --remember when no push location set, push fails
73
 
        out = self.run_bzr('push', '../branch_b', retcode=3)
 
76
        out = self.run_bzr('push ../branch_b', retcode=3)
74
77
        self.assertEquals(out,
75
78
                ('','bzr: ERROR: These branches have diverged.  '
76
79
                    'Try using "merge" and then "push".\n'))
91
94
        self.assertEqual(path,
92
95
                         branch_b.bzrdir.root_transport.base)
93
96
        # test explicit --remember
94
 
        self.run_bzr('push', '../branch_c', '--remember')
 
97
        self.run_bzr('push ../branch_c --remember')
95
98
        self.assertEquals(branch_a.get_push_location(),
96
99
                          branch_c.bzrdir.root_transport.base)
97
100
    
98
101
    def test_push_without_tree(self):
99
102
        # bzr push from a branch that does not have a checkout should work.
100
103
        b = self.make_branch('.')
101
 
        out, err = self.run_bzr('push', 'pushed-location')
 
104
        out, err = self.run_bzr('push pushed-location')
102
105
        self.assertEqual('', out)
103
106
        self.assertEqual('Created new branch.\n', err)
104
107
        b2 = Branch.open('pushed-location')
113
116
        t.add('file')
114
117
        t.commit('commit 1')
115
118
        os.chdir('tree')
116
 
        out, err = self.run_bzr('push', 'pushed-to')
 
119
        out, err = self.run_bzr('push pushed-to')
117
120
        os.chdir('..')
118
121
        self.assertEqual('', out)
119
122
        self.assertEqual('Created new branch.\n', err)
150
153
        # Now that we have a repository with shared files, make sure
151
154
        # that things aren't copied out by a 'push'
152
155
        os.chdir('repo/b')
153
 
        self.run_bzr('push', '../../push-b')
 
156
        self.run_bzr('push ../../push-b')
154
157
        pushed_tree = WorkingTree.open('../../push-b')
155
158
        pushed_repo = pushed_tree.branch.repository
156
159
        self.assertFalse(pushed_repo.has_revision('a-1'))
163
166
        self.build_tree(['filename'])
164
167
        t.add('filename', 'funky-chars<>%&;"\'')
165
168
        t.commit('commit filename')
166
 
        self.run_bzr('push', '../new-tree')
 
169
        self.run_bzr('push ../new-tree')
167
170
 
168
171
    def test_push_dash_d(self):
169
172
        t = self.make_branch_and_tree('from')
170
173
        t.commit(allow_pointless=True,
171
174
                message='first commit')
172
 
        self.runbzr('push -d from to-one')
 
175
        self.run_bzr('push -d from to-one')
173
176
        self.failUnlessExists('to-one')
174
 
        self.runbzr('push -d %s %s' 
 
177
        self.run_bzr('push -d %s %s' 
175
178
            % tuple(map(urlutils.local_path_to_url, ['from', 'to-two'])))
176
179
        self.failUnlessExists('to-two')
177
180
 
187
190
        tree = self.create_simple_tree()
188
191
 
189
192
        self.run_bzr_error(['Parent directory of ../new/tree does not exist'],
190
 
                           'push', '../new/tree',
 
193
                           'push ../new/tree',
191
194
                           working_dir='tree')
192
 
        self.run_bzr('push', '../new/tree', '--create-prefix',
 
195
        self.run_bzr('push ../new/tree --create-prefix',
193
196
                     working_dir='tree')
194
197
        new_tree = WorkingTree.open('new/tree')
195
198
        self.assertEqual(tree.last_revision(), new_tree.last_revision())
205
208
 
206
209
        self.run_bzr_error(['Target directory ../target already exists',
207
210
                            'Supply --use-existing-dir',
208
 
                           ], 'push', '../target',
209
 
                           working_dir='tree')
 
211
                           ],
 
212
                           'push ../target', working_dir='tree')
210
213
 
211
 
        self.run_bzr('push', '--use-existing-dir', '../target',
 
214
        self.run_bzr('push --use-existing-dir ../target',
212
215
                     working_dir='tree')
213
216
 
214
217
        new_tree = WorkingTree.open('target')
221
224
        tree = self.create_simple_tree()
222
225
        repo = self.make_repository('repo', shared=True)
223
226
 
224
 
        self.run_bzr('push', '../repo',
 
227
        self.run_bzr('push ../repo',
225
228
                     working_dir='tree')
226
229
 
227
230
        # Pushing onto an existing bzrdir will create a repository and
242
245
        a_bzrdir = self.make_bzrdir('dir')
243
246
 
244
247
        self.run_bzr_error(['At ../dir you have a valid .bzr control'],
245
 
                'push', '../dir',
 
248
                'push ../dir',
246
249
                working_dir='tree')
 
250
 
 
251
    def test_push_with_revisionspec(self):
 
252
        """We should be able to push a revision older than the tip."""
 
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
 
 
265
        self.run_bzr_error(
 
266
            "bzr: ERROR: bzr push --revision takes one value.\n",
 
267
            'push -r0..2 ../to', working_dir='from')
 
268
 
 
269
 
 
270
class RedirectingMemoryTransport(MemoryTransport):
 
271
 
 
272
    def mkdir(self, path, mode=None):
 
273
        path = self.abspath(path)[len(self._scheme):]
 
274
        if path == '/source':
 
275
            raise errors.RedirectRequested(
 
276
                path, self._scheme + '/target', is_permanent=True)
 
277
        elif path == '/infinite-loop':
 
278
            raise errors.RedirectRequested(
 
279
                path, self._scheme + '/infinite-loop', is_permanent=True)
 
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)
 
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)
 
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
 
 
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
 
 
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)
 
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)