~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/selftest/blackbox.py

  • Committer: Robert Collins
  • Date: 2005-10-02 22:47:02 UTC
  • mto: This revision was merged to the branch mainline in revision 1397.
  • Revision ID: robertc@robertcollins.net-20051002224701-8a8b20b90de559a6
support ghosts in commits

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# Copyright (C) 2005 by Canonical Ltd
2
2
# -*- coding: utf-8 -*-
3
 
#
 
3
 
4
4
# This program is free software; you can redistribute it and/or modify
5
5
# it under the terms of the GNU General Public License as published by
6
6
# the Free Software Foundation; either version 2 of the License, or
7
7
# (at your option) any later version.
8
 
#
 
8
 
9
9
# This program is distributed in the hope that it will be useful,
10
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
12
# GNU General Public License for more details.
13
 
#
 
13
 
14
14
# You should have received a copy of the GNU General Public License
15
15
# along with this program; if not, write to the Free Software
16
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
17
 
18
 
# Mr. Smoketoomuch: I'm sorry?
19
 
# Mr. Bounder: You'd better cut down a little then.
20
 
# Mr. Smoketoomuch: Oh, I see! Smoke too much so I'd better cut down a little
21
 
#                   then!
22
18
 
23
19
"""Black-box tests for bzr.
24
20
 
25
21
These check that it behaves properly when it's invoked through the regular
26
 
command-line interface. This doesn't actually run a new interpreter but 
27
 
rather starts again from the run_bzr function.
 
22
command-line interface.
 
23
 
 
24
This always reinvokes bzr through a new Python interpreter, which is a
 
25
bit inefficient but arguably tests in a way more representative of how
 
26
it's normally invoked.
28
27
"""
29
28
 
30
 
 
31
 
# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
32
 
# Note: Please don't add new tests here, it's too big and bulky.  Instead add
33
 
# them into small suites in bzrlib.tests.blackbox.test_FOO for the particular
34
 
# UI command/aspect that is being tested.
35
 
 
36
 
 
37
29
from cStringIO import StringIO
38
30
import os
39
 
import re
 
31
import shutil
40
32
import sys
 
33
import os
41
34
 
42
 
import bzrlib
 
35
from bzrlib.selftest import TestCaseInTempDir, BzrTestBase
43
36
from bzrlib.branch import Branch
44
 
import bzrlib.bzrdir as bzrdir
45
 
from bzrlib.errors import BzrCommandError
46
 
from bzrlib.osutils import (
47
 
    has_symlinks,
48
 
    pathjoin,
49
 
    rmtree,
50
 
    terminal_width,
51
 
    )
52
 
from bzrlib.tests.HTTPTestUtil import TestCaseWithWebserver
53
 
from bzrlib.tests.test_sftp_transport import TestCaseWithSFTPServer
54
 
from bzrlib.tests.blackbox import ExternalBase
55
 
from bzrlib.workingtree import WorkingTree
 
37
 
 
38
 
 
39
class ExternalBase(TestCaseInTempDir):
 
40
 
 
41
    def runbzr(self, args, retcode=0, backtick=False):
 
42
        if isinstance(args, basestring):
 
43
            args = args.split()
 
44
 
 
45
        if backtick:
 
46
            return self.run_bzr_captured(args, retcode=retcode)[0]
 
47
        else:
 
48
            return self.run_bzr_captured(args, retcode=retcode)
56
49
 
57
50
 
58
51
class TestCommands(ExternalBase):
59
52
 
60
 
    def test_nick_command(self):
61
 
        """bzr nick for viewing, setting nicknames"""
62
 
        os.mkdir('me.dev')
63
 
        os.chdir('me.dev')
 
53
    def test_help_commands(self):
 
54
        self.runbzr('--help')
 
55
        self.runbzr('help')
 
56
        self.runbzr('help commands')
 
57
        self.runbzr('help help')
 
58
        self.runbzr('commit -h')
 
59
 
 
60
    def test_init_branch(self):
 
61
        self.runbzr(['init'])
 
62
 
 
63
    def test_whoami(self):
 
64
        # this should always identify something, if only "john@localhost"
 
65
        self.runbzr("whoami")
 
66
        self.runbzr("whoami --email")
 
67
 
 
68
        self.assertEquals(self.runbzr("whoami --email",
 
69
                                      backtick=True).count('@'), 1)
 
70
        
 
71
    def test_whoami_branch(self):
 
72
        """branch specific user identity works."""
64
73
        self.runbzr('init')
65
 
        nick = self.runbzr("nick",backtick=True)
66
 
        self.assertEqual(nick, 'me.dev\n')
67
 
        nick = self.runbzr("nick moo")
68
 
        nick = self.runbzr("nick",backtick=True)
69
 
        self.assertEqual(nick, 'moo\n')
 
74
        f = file('.bzr/email', 'wt')
 
75
        f.write('Branch Identity <branch@identi.ty>')
 
76
        f.close()
 
77
        bzr_email = os.environ.get('BZREMAIL')
 
78
        if bzr_email is not None:
 
79
            del os.environ['BZREMAIL']
 
80
        whoami = self.runbzr("whoami",backtick=True)
 
81
        whoami_email = self.runbzr("whoami --email",backtick=True)
 
82
        self.assertTrue(whoami.startswith('Branch Identity <branch@identi.ty>'))
 
83
        self.assertTrue(whoami_email.startswith('branch@identi.ty'))
 
84
        # Verify that the environment variable overrides the value 
 
85
        # in the file
 
86
        os.environ['BZREMAIL'] = 'Different ID <other@environ.ment>'
 
87
        whoami = self.runbzr("whoami",backtick=True)
 
88
        whoami_email = self.runbzr("whoami --email",backtick=True)
 
89
        self.assertTrue(whoami.startswith('Different ID <other@environ.ment>'))
 
90
        self.assertTrue(whoami_email.startswith('other@environ.ment'))
 
91
        if bzr_email is not None:
 
92
            os.environ['BZREMAIL'] = bzr_email
70
93
 
71
94
    def test_invalid_commands(self):
72
 
        self.runbzr("pants", retcode=3)
73
 
        self.runbzr("--pants off", retcode=3)
74
 
        self.runbzr("diff --message foo", retcode=3)
 
95
        self.runbzr("pants", retcode=1)
 
96
        self.runbzr("--pants off", retcode=1)
 
97
        self.runbzr("diff --message foo", retcode=1)
 
98
 
 
99
    def test_empty_commit(self):
 
100
        self.runbzr("init")
 
101
        self.build_tree(['hello.txt'])
 
102
        self.runbzr("commit -m empty", retcode=1)
 
103
        self.runbzr("add hello.txt")
 
104
        self.runbzr("commit -m added")
 
105
 
 
106
    def test_ignore_patterns(self):
 
107
        from bzrlib.branch import Branch
 
108
        
 
109
        b = Branch.initialize('.')
 
110
        self.assertEquals(list(b.unknowns()), [])
 
111
 
 
112
        file('foo.tmp', 'wt').write('tmp files are ignored')
 
113
        self.assertEquals(list(b.unknowns()), [])
 
114
        assert self.capture('unknowns') == ''
 
115
 
 
116
        file('foo.c', 'wt').write('int main() {}')
 
117
        self.assertEquals(list(b.unknowns()), ['foo.c'])
 
118
        assert self.capture('unknowns') == 'foo.c\n'
 
119
 
 
120
        self.runbzr(['add', 'foo.c'])
 
121
        assert self.capture('unknowns') == ''
 
122
 
 
123
        # 'ignore' works when creating the .bzignore file
 
124
        file('foo.blah', 'wt').write('blah')
 
125
        self.assertEquals(list(b.unknowns()), ['foo.blah'])
 
126
        self.runbzr('ignore *.blah')
 
127
        self.assertEquals(list(b.unknowns()), [])
 
128
        assert file('.bzrignore', 'rU').read() == '*.blah\n'
 
129
 
 
130
        # 'ignore' works when then .bzrignore file already exists
 
131
        file('garh', 'wt').write('garh')
 
132
        self.assertEquals(list(b.unknowns()), ['garh'])
 
133
        assert self.capture('unknowns') == 'garh\n'
 
134
        self.runbzr('ignore garh')
 
135
        self.assertEquals(list(b.unknowns()), [])
 
136
        assert file('.bzrignore', 'rU').read() == '*.blah\ngarh\n'
75
137
 
76
138
    def test_revert(self):
77
139
        self.runbzr('init')
98
160
        os.rmdir('revertdir')
99
161
        self.runbzr('revert')
100
162
 
101
 
        if has_symlinks():
102
 
            os.symlink('/unlikely/to/exist', 'symlink')
103
 
            self.runbzr('add symlink')
104
 
            self.runbzr('commit -m f')
105
 
            os.unlink('symlink')
106
 
            self.runbzr('revert')
107
 
            self.failUnlessExists('symlink')
108
 
            os.unlink('symlink')
109
 
            os.symlink('a-different-path', 'symlink')
110
 
            self.runbzr('revert')
111
 
            self.assertEqual('/unlikely/to/exist',
112
 
                             os.readlink('symlink'))
113
 
        else:
114
 
            self.log("skipping revert symlink tests")
 
163
        os.symlink('/unlikely/to/exist', 'symlink')
 
164
        self.runbzr('add symlink')
 
165
        self.runbzr('commit -m f')
 
166
        os.unlink('symlink')
 
167
        self.runbzr('revert')
115
168
        
116
169
        file('hello', 'wt').write('xyz')
117
170
        self.runbzr('commit -m xyz hello')
123
176
        self.runbzr('revert')
124
177
        os.chdir('..')
125
178
 
 
179
 
 
180
    def test_mv_modes(self):
 
181
        """Test two modes of operation for mv"""
 
182
        from bzrlib.branch import Branch
 
183
        b = Branch.initialize('.')
 
184
        self.build_tree(['a', 'c', 'subdir/'])
 
185
        self.run_bzr_captured(['add', self.test_dir])
 
186
        self.run_bzr_captured(['mv', 'a', 'b'])
 
187
        self.run_bzr_captured(['mv', 'b', 'subdir'])
 
188
        self.run_bzr_captured(['mv', 'subdir/b', 'a'])
 
189
        self.run_bzr_captured(['mv', 'a', 'c', 'subdir'])
 
190
        self.run_bzr_captured(['mv', 'subdir/a', 'subdir/newa'])
 
191
 
 
192
 
126
193
    def test_main_version(self):
127
194
        """Check output from version command and master option is reasonable"""
128
195
        # output is intentionally passed through to stdout so that we
130
197
        output = self.runbzr('version', backtick=1)
131
198
        self.log('bzr version output:')
132
199
        self.log(output)
133
 
        self.assert_(output.startswith('Bazaar (bzr) '))
 
200
        self.assert_(output.startswith('bzr (bazaar-ng) '))
134
201
        self.assertNotEqual(output.index('Canonical'), -1)
135
202
        # make sure --version is consistent
136
203
        tmp_output = self.runbzr('--version', backtick=1)
154
221
        self.runbzr('export ../latest')
155
222
        self.assertEqual(file('../latest/goodbye', 'rt').read(), 'baz')
156
223
        self.runbzr('export ../first -r 1')
157
 
        self.assert_(not os.path.exists('../first/goodbye'))
 
224
        assert not os.path.exists('../first/goodbye')
158
225
        self.assertEqual(file('../first/hello', 'rt').read(), 'foo')
159
226
        self.runbzr('export ../first.gz -r 1')
160
227
        self.assertEqual(file('../first.gz/hello', 'rt').read(), 'foo')
161
228
        self.runbzr('export ../first.bz2 -r 1')
162
229
        self.assertEqual(file('../first.bz2/hello', 'rt').read(), 'foo')
163
 
 
 
230
        self.runbzr('export ../first.tar -r 1')
 
231
        assert os.path.isfile('../first.tar')
164
232
        from tarfile import TarFile
165
 
        self.runbzr('export ../first.tar -r 1')
166
 
        self.assert_(os.path.isfile('../first.tar'))
167
233
        tf = TarFile('../first.tar')
168
 
        self.assert_('first/hello' in tf.getnames(), tf.getnames())
 
234
        assert 'first/hello' in tf.getnames(), tf.getnames()
169
235
        self.assertEqual(tf.extractfile('first/hello').read(), 'foo')
170
236
        self.runbzr('export ../first.tar.gz -r 1')
171
 
        self.assert_(os.path.isfile('../first.tar.gz'))
 
237
        assert os.path.isfile('../first.tar.gz')
172
238
        self.runbzr('export ../first.tbz2 -r 1')
173
 
        self.assert_(os.path.isfile('../first.tbz2'))
 
239
        assert os.path.isfile('../first.tbz2')
174
240
        self.runbzr('export ../first.tar.bz2 -r 1')
175
 
        self.assert_(os.path.isfile('../first.tar.bz2'))
 
241
        assert os.path.isfile('../first.tar.bz2')
176
242
        self.runbzr('export ../first.tar.tbz2 -r 1')
177
 
        self.assert_(os.path.isfile('../first.tar.tbz2'))
178
 
 
 
243
        assert os.path.isfile('../first.tar.tbz2')
179
244
        from bz2 import BZ2File
180
245
        tf = TarFile('../first.tar.tbz2', 
181
246
                     fileobj=BZ2File('../first.tar.tbz2', 'r'))
182
 
        self.assert_('first.tar/hello' in tf.getnames(), tf.getnames())
 
247
        assert 'first.tar/hello' in tf.getnames(), tf.getnames()
183
248
        self.assertEqual(tf.extractfile('first.tar/hello').read(), 'foo')
184
249
        self.runbzr('export ../first2.tar -r 1 --root pizza')
185
250
        tf = TarFile('../first2.tar')
186
 
        self.assert_('pizza/hello' in tf.getnames(), tf.getnames())
187
 
 
188
 
        from zipfile import ZipFile
189
 
        self.runbzr('export ../first.zip -r 1')
190
 
        self.failUnlessExists('../first.zip')
191
 
        zf = ZipFile('../first.zip')
192
 
        self.assert_('first/hello' in zf.namelist(), zf.namelist())
193
 
        self.assertEqual(zf.read('first/hello'), 'foo')
194
 
 
195
 
        self.runbzr('export ../first2.zip -r 1 --root pizza')
196
 
        zf = ZipFile('../first2.zip')
197
 
        self.assert_('pizza/hello' in zf.namelist(), zf.namelist())
 
251
        assert 'pizza/hello' in tf.getnames(), tf.getnames()
 
252
 
 
253
    def test_diff(self):
 
254
        self.example_branch()
 
255
        file('hello', 'wt').write('hello world!')
 
256
        self.runbzr('commit -m fixing hello')
 
257
        output = self.runbzr('diff -r 2..3', backtick=1)
 
258
        self.assert_('\n+hello world!' in output)
 
259
        output = self.runbzr('diff -r last:3..last:1', backtick=1)
 
260
        self.assert_('\n+baz' in output)
 
261
 
 
262
    def test_branch(self):
 
263
        """Branch from one branch to another."""
 
264
        os.mkdir('a')
 
265
        os.chdir('a')
 
266
        self.example_branch()
 
267
        os.chdir('..')
 
268
        self.runbzr('branch a b')
 
269
        self.runbzr('branch a c -r 1')
 
270
        os.chdir('b')
 
271
        self.runbzr('commit -m foo --unchanged')
 
272
        os.chdir('..')
 
273
        # naughty - abstraction violations RBC 20050928  
 
274
        print "test_branch used to delete the stores, how is this meant to work ?"
 
275
        #shutil.rmtree('a/.bzr/revision-store')
 
276
        #shutil.rmtree('a/.bzr/inventory-store', ignore_errors=True)
 
277
        #shutil.rmtree('a/.bzr/text-store', ignore_errors=True)
 
278
        self.runbzr('branch a d --basis b')
 
279
 
 
280
    def test_merge(self):
 
281
        from bzrlib.branch import Branch
198
282
        
199
 
        self.runbzr('export ../first-zip --format=zip -r 1')
200
 
        zf = ZipFile('../first-zip')
201
 
        self.assert_('first-zip/hello' in zf.namelist(), zf.namelist())
202
 
 
203
 
    def test_inventory(self):
204
 
        bzr = self.runbzr
205
 
        def output_equals(value, *args):
206
 
            out = self.runbzr(['inventory'] + list(args), backtick=True)
207
 
            self.assertEquals(out, value)
208
 
 
209
 
        bzr('init')
210
 
        open('a', 'wb').write('hello\n')
211
 
        os.mkdir('b')
212
 
 
213
 
        bzr('add a b')
214
 
        bzr('commit -m add')
215
 
 
216
 
        output_equals('a\n', '--kind', 'file')
217
 
        output_equals('b\n', '--kind', 'directory')
218
 
 
219
 
    def test_pull_verbose(self):
220
 
        """Pull changes from one branch to another and watch the output."""
221
 
 
222
283
        os.mkdir('a')
223
284
        os.chdir('a')
224
 
 
225
 
        bzr = self.runbzr
226
285
        self.example_branch()
227
 
 
228
286
        os.chdir('..')
229
 
        bzr('branch a b')
 
287
        self.runbzr('branch a b')
230
288
        os.chdir('b')
231
 
        open('b', 'wb').write('else\n')
232
 
        bzr('add b')
233
 
        bzr(['commit', '-m', 'added b'])
 
289
        file('goodbye', 'wt').write('quux')
 
290
        self.runbzr(['commit',  '-m',  "more u's are always good"])
234
291
 
235
292
        os.chdir('../a')
236
 
        out = bzr('pull --verbose ../b', backtick=True)
237
 
        self.failIfEqual(out.find('Added Revisions:'), -1)
238
 
        self.failIfEqual(out.find('message:\n  added b'), -1)
239
 
        self.failIfEqual(out.find('added b'), -1)
240
 
 
241
 
        # Check that --overwrite --verbose prints out the removed entries
242
 
        bzr('commit -m foo --unchanged')
243
 
        os.chdir('../b')
244
 
        bzr('commit -m baz --unchanged')
245
 
        bzr('pull ../a', retcode=3)
246
 
        out = bzr('pull --overwrite --verbose ../a', backtick=1)
247
 
 
248
 
        remove_loc = out.find('Removed Revisions:')
249
 
        self.failIfEqual(remove_loc, -1)
250
 
        added_loc = out.find('Added Revisions:')
251
 
        self.failIfEqual(added_loc, -1)
252
 
 
253
 
        removed_message = out.find('message:\n  baz')
254
 
        self.failIfEqual(removed_message, -1)
255
 
        self.failUnless(remove_loc < removed_message < added_loc)
256
 
 
257
 
        added_message = out.find('message:\n  foo')
258
 
        self.failIfEqual(added_message, -1)
259
 
        self.failUnless(added_loc < added_message)
260
 
        
261
 
    def test_locations(self):
262
 
        """Using and remembering different locations"""
 
293
        file('hello', 'wt').write('quuux')
 
294
        # We can't merge when there are in-tree changes
 
295
        self.runbzr('merge ../b', retcode=1)
 
296
        self.runbzr(['commit', '-m', "Like an epidemic of u's"])
 
297
        self.runbzr('merge ../b')
 
298
        self.check_file_contents('goodbye', 'quux')
 
299
        # Merging a branch pulls its revision into the tree
 
300
        a = Branch.open('.')
 
301
        b = Branch.open('../b')
 
302
        a.get_revision_xml(b.last_revision())
 
303
        self.log('pending merges: %s', a.pending_merges())
 
304
        #        assert a.pending_merges() == [b.last_revision()], "Assertion %s %s" \
 
305
        #        % (a.pending_merges(), b.last_revision())
 
306
 
 
307
    def test_merge_with_missing_file(self):
 
308
        """Merge handles missing file conflicts"""
263
309
        os.mkdir('a')
264
310
        os.chdir('a')
 
311
        os.mkdir('sub')
 
312
        print >> file('sub/a.txt', 'wb'), "hello"
 
313
        print >> file('b.txt', 'wb'), "hello"
 
314
        print >> file('sub/c.txt', 'wb'), "hello"
265
315
        self.runbzr('init')
266
 
        self.runbzr('commit -m unchanged --unchanged')
267
 
        self.runbzr('pull', retcode=3)
268
 
        self.runbzr('merge', retcode=3)
 
316
        self.runbzr('add')
 
317
        self.runbzr(('commit', '-m', 'added a'))
269
318
        self.runbzr('branch . ../b')
270
 
        os.chdir('../b')
271
 
        self.runbzr('pull')
272
 
        self.runbzr('branch . ../c')
273
 
        self.runbzr('pull ../c')
274
 
        self.runbzr('merge')
275
 
        os.chdir('../a')
276
 
        self.runbzr('pull ../b')
277
 
        self.runbzr('pull')
278
 
        self.runbzr('pull ../c')
279
 
        self.runbzr('branch ../c ../d')
280
 
        rmtree('../c')
281
 
        self.runbzr('pull')
282
 
        os.chdir('../b')
283
 
        self.runbzr('pull')
284
 
        os.chdir('../d')
285
 
        self.runbzr('pull', retcode=3)
286
 
        self.runbzr('pull ../a --remember')
287
 
        self.runbzr('pull')
 
319
        print >> file('sub/a.txt', 'ab'), "there"
 
320
        print >> file('b.txt', 'ab'), "there"
 
321
        print >> file('sub/c.txt', 'ab'), "there"
 
322
        self.runbzr(('commit', '-m', 'Added there'))
 
323
        os.unlink('sub/a.txt')
 
324
        os.unlink('sub/c.txt')
 
325
        os.rmdir('sub')
 
326
        os.unlink('b.txt')
 
327
        self.runbzr(('commit', '-m', 'Removed a.txt'))
 
328
        os.chdir('../b')
 
329
        print >> file('sub/a.txt', 'ab'), "something"
 
330
        print >> file('b.txt', 'ab'), "something"
 
331
        print >> file('sub/c.txt', 'ab'), "something"
 
332
        self.runbzr(('commit', '-m', 'Modified a.txt'))
 
333
        self.runbzr('merge ../a/')
 
334
        assert os.path.exists('sub/a.txt.THIS')
 
335
        assert os.path.exists('sub/a.txt.BASE')
 
336
        os.chdir('../a')
 
337
        self.runbzr('merge ../b/')
 
338
        assert os.path.exists('sub/a.txt.OTHER')
 
339
        assert os.path.exists('sub/a.txt.BASE')
 
340
 
 
341
    def test_pull(self):
 
342
        """Pull changes from one branch to another."""
 
343
        os.mkdir('a')
 
344
        os.chdir('a')
 
345
 
 
346
        self.example_branch()
 
347
        self.runbzr('pull', retcode=1)
 
348
        self.runbzr('missing', retcode=1)
 
349
        self.runbzr('missing .')
 
350
        self.runbzr('missing')
 
351
        self.runbzr('pull')
 
352
        self.runbzr('pull /', retcode=1)
 
353
        self.runbzr('pull')
 
354
 
 
355
        os.chdir('..')
 
356
        self.runbzr('branch a b')
 
357
        os.chdir('b')
 
358
        self.runbzr('pull')
 
359
        os.mkdir('subdir')
 
360
        self.runbzr('add subdir')
 
361
        self.runbzr('commit -m blah --unchanged')
 
362
        os.chdir('../a')
 
363
        a = Branch.open('.')
 
364
        b = Branch.open('../b')
 
365
        assert a.revision_history() == b.revision_history()[:-1]
 
366
        self.runbzr('pull ../b')
 
367
        assert a.revision_history() == b.revision_history()
 
368
        self.runbzr('commit -m blah2 --unchanged')
 
369
        os.chdir('../b')
 
370
        self.runbzr('commit -m blah3 --unchanged')
 
371
        self.runbzr('pull ../a', retcode=1)
 
372
        print "DECIDE IF PULL CAN CONVERGE, blackbox.py"
 
373
        return
 
374
        os.chdir('../a')
 
375
        self.runbzr('merge ../b')
 
376
        self.runbzr('commit -m blah4 --unchanged')
 
377
        os.chdir('../b/subdir')
 
378
        self.runbzr('pull ../../a')
 
379
        assert a.revision_history()[-1] == b.revision_history()[-1]
 
380
        self.runbzr('commit -m blah5 --unchanged')
 
381
        self.runbzr('commit -m blah6 --unchanged')
 
382
        os.chdir('..')
 
383
        self.runbzr('pull ../a')
 
384
        os.chdir('../a')
 
385
        self.runbzr('commit -m blah7 --unchanged')
 
386
        self.runbzr('merge ../b')
 
387
        self.runbzr('commit -m blah8 --unchanged')
 
388
        self.runbzr('pull ../b')
 
389
        self.runbzr('pull ../b')
288
390
        
 
391
    def test_add_reports(self):
 
392
        """add command prints the names of added files."""
 
393
        b = Branch.initialize('.')
 
394
        self.build_tree(['top.txt', 'dir/', 'dir/sub.txt'])
 
395
        out = self.run_bzr_captured(['add'], retcode = 0)[0]
 
396
        # the ordering is not defined at the moment
 
397
        results = sorted(out.rstrip('\n').split('\n'))
 
398
        self.assertEquals(['added dir',
 
399
                           'added dir'+os.sep+'sub.txt',
 
400
                           'added top.txt',],
 
401
                          results)
 
402
 
289
403
    def test_unknown_command(self):
290
404
        """Handling of unknown command."""
291
405
        out, err = self.run_bzr_captured(['fluffy-badger'],
292
 
                                         retcode=3)
 
406
                                         retcode=1)
293
407
        self.assertEquals(out, '')
294
408
        err.index('unknown command')
295
 
 
296
 
    def create_conflicts(self):
297
 
        """Create a conflicted tree"""
298
 
        os.mkdir('base')
299
 
        os.chdir('base')
300
 
        file('hello', 'wb').write("hi world")
301
 
        file('answer', 'wb').write("42")
302
 
        self.runbzr('init')
303
 
        self.runbzr('add')
304
 
        self.runbzr('commit -m base')
305
 
        self.runbzr('branch . ../other')
306
 
        self.runbzr('branch . ../this')
307
 
        os.chdir('../other')
308
 
        file('hello', 'wb').write("Hello.")
309
 
        file('answer', 'wb').write("Is anyone there?")
310
 
        self.runbzr('commit -m other')
311
 
        os.chdir('../this')
312
 
        file('hello', 'wb').write("Hello, world")
313
 
        self.runbzr('mv answer question')
314
 
        file('question', 'wb').write("What do you get when you multiply six"
315
 
                                   "times nine?")
316
 
        self.runbzr('commit -m this')
317
 
 
318
 
    def test_status(self):
319
 
        os.mkdir('branch1')
320
 
        os.chdir('branch1')
321
 
        self.runbzr('init')
322
 
        self.runbzr('commit --unchanged --message f')
323
 
        self.runbzr('branch . ../branch2')
324
 
        self.runbzr('branch . ../branch3')
325
 
        self.runbzr('commit --unchanged --message peter')
326
 
        os.chdir('../branch2')
327
 
        self.runbzr('merge ../branch1')
328
 
        self.runbzr('commit --unchanged --message pumpkin')
329
 
        os.chdir('../branch3')
330
 
        self.runbzr('merge ../branch2')
331
 
        message = self.capture('status')
332
 
 
333
 
 
334
 
    def test_conflicts(self):
335
 
        """Handling of merge conflicts"""
336
 
        self.create_conflicts()
337
 
        self.runbzr('merge ../other --show-base', retcode=1)
338
 
        conflict_text = file('hello').read()
339
 
        self.assert_('<<<<<<<' in conflict_text)
340
 
        self.assert_('>>>>>>>' in conflict_text)
341
 
        self.assert_('=======' in conflict_text)
342
 
        self.assert_('|||||||' in conflict_text)
343
 
        self.assert_('hi world' in conflict_text)
344
 
        self.runbzr('revert')
345
 
        self.runbzr('resolve --all')
346
 
        self.runbzr('merge ../other', retcode=1)
347
 
        conflict_text = file('hello').read()
348
 
        self.assert_('|||||||' not in conflict_text)
349
 
        self.assert_('hi world' not in conflict_text)
350
 
        result = self.runbzr('conflicts', backtick=1)
351
 
        self.assertEquals(result, "Text conflict in hello\nText conflict in"
352
 
                                  " question\n")
353
 
        result = self.runbzr('status', backtick=1)
354
 
        self.assert_("conflicts:\n  Text conflict in hello\n"
355
 
                     "  Text conflict in question\n" in result, result)
356
 
        self.runbzr('resolve hello')
357
 
        result = self.runbzr('conflicts', backtick=1)
358
 
        self.assertEquals(result, "Text conflict in question\n")
359
 
        self.runbzr('commit -m conflicts', retcode=3)
360
 
        self.runbzr('resolve --all')
361
 
        result = self.runbzr('conflicts', backtick=1)
362
 
        self.runbzr('commit -m conflicts')
363
 
        self.assertEquals(result, "")
364
 
 
365
 
    def test_push(self):
366
 
        # create a source branch
367
 
        os.mkdir('my-branch')
368
 
        os.chdir('my-branch')
369
 
        self.example_branch()
370
 
 
371
 
        # with no push target, fail
372
 
        self.runbzr('push', retcode=3)
373
 
        # with an explicit target work
374
 
        self.runbzr('push ../output-branch')
375
 
        # with an implicit target work
376
 
        self.runbzr('push')
377
 
        # nothing missing
378
 
        self.runbzr('missing ../output-branch')
379
 
        # advance this branch
380
 
        self.runbzr('commit --unchanged -m unchanged')
381
 
 
382
 
        os.chdir('../output-branch')
383
 
        # There is no longer a difference as long as we have
384
 
        # access to the working tree
385
 
        self.runbzr('diff')
386
 
 
387
 
        # But we should be missing a revision
388
 
        self.runbzr('missing ../my-branch', retcode=1)
389
 
 
390
 
        # diverge the branches
391
 
        self.runbzr('commit --unchanged -m unchanged')
392
 
        os.chdir('../my-branch')
393
 
        # cannot push now
394
 
        self.runbzr('push', retcode=3)
395
 
        # and there are difference
396
 
        self.runbzr('missing ../output-branch', retcode=1)
397
 
        self.runbzr('missing --verbose ../output-branch', retcode=1)
398
 
        # but we can force a push
399
 
        self.runbzr('push --overwrite')
400
 
        # nothing missing
401
 
        self.runbzr('missing ../output-branch')
402
409
        
403
 
        # pushing to a new dir with no parent should fail
404
 
        self.runbzr('push ../missing/new-branch', retcode=3)
405
 
        # unless we provide --create-prefix
406
 
        self.runbzr('push --create-prefix ../missing/new-branch')
407
 
        # nothing missing
408
 
        self.runbzr('missing ../missing/new-branch')
409
 
 
410
 
    def test_external_command(self):
411
 
        """Test that external commands can be run by setting the path
412
 
        """
413
 
        # We don't at present run bzr in a subprocess for blackbox tests, and so 
414
 
        # don't really capture stdout, only the internal python stream.
415
 
        # Therefore we don't use a subcommand that produces any output or does
416
 
        # anything -- we just check that it can be run successfully.  
417
 
        cmd_name = 'test-command'
418
 
        if sys.platform == 'win32':
419
 
            cmd_name += '.bat'
420
 
        oldpath = os.environ.get('BZRPATH', None)
421
 
        bzr = self.capture
422
 
        try:
423
 
            if os.environ.has_key('BZRPATH'):
424
 
                del os.environ['BZRPATH']
425
 
 
426
 
            f = file(cmd_name, 'wb')
427
 
            if sys.platform == 'win32':
428
 
                f.write('@echo off\n')
429
 
            else:
430
 
                f.write('#!/bin/sh\n')
431
 
            # f.write('echo Hello from test-command')
432
 
            f.close()
433
 
            os.chmod(cmd_name, 0755)
434
 
 
435
 
            # It should not find the command in the local 
436
 
            # directory by default, since it is not in my path
437
 
            bzr(cmd_name, retcode=3)
438
 
 
439
 
            # Now put it into my path
440
 
            os.environ['BZRPATH'] = '.'
441
 
 
442
 
            bzr(cmd_name)
443
 
 
444
 
            # Make sure empty path elements are ignored
445
 
            os.environ['BZRPATH'] = os.pathsep
446
 
 
447
 
            bzr(cmd_name, retcode=3)
448
 
 
449
 
        finally:
450
 
            if oldpath:
451
 
                os.environ['BZRPATH'] = oldpath
452
 
 
 
410
 
 
411
 
 
412
def has_symlinks():
 
413
    if hasattr(os, 'symlink'):
 
414
        return True
 
415
    else:
 
416
        return False
453
417
 
454
418
def listdir_sorted(dir):
455
419
    L = os.listdir(dir)
474
438
        runbzr('init')
475
439
 
476
440
        self.assertEquals(capture('root').rstrip(),
477
 
                          pathjoin(self.test_dir, 'branch1'))
 
441
                          os.path.join(self.test_dir, 'branch1'))
478
442
 
479
443
        progress("status of new file")
480
444
 
485
449
        self.assertEquals(capture('unknowns'), 'test.txt\n')
486
450
 
487
451
        out = capture("status")
488
 
        self.assertEquals(out, 'unknown:\n  test.txt\n')
 
452
        assert out == 'unknown:\n  test.txt\n'
 
453
 
 
454
        out = capture("status --all")
 
455
        assert out == "unknown:\n  test.txt\n"
 
456
 
 
457
        out = capture("status test.txt --all")
 
458
        assert out == "unknown:\n  test.txt\n"
489
459
 
490
460
        f = file('test2.txt', 'wt')
491
461
        f.write('goodbye cruel world...\n')
492
462
        f.close()
493
463
 
494
464
        out = capture("status test.txt")
495
 
        self.assertEquals(out, "unknown:\n  test.txt\n")
 
465
        assert out == "unknown:\n  test.txt\n"
496
466
 
497
467
        out = capture("status")
498
 
        self.assertEquals(out, ("unknown:\n" "  test.txt\n" "  test2.txt\n"))
 
468
        assert out == ("unknown:\n"
 
469
                       "  test.txt\n"
 
470
                       "  test2.txt\n")
499
471
 
500
472
        os.unlink('test2.txt')
501
473
 
502
474
        progress("command aliases")
503
 
        out = capture("st")
504
 
        self.assertEquals(out, ("unknown:\n" "  test.txt\n"))
 
475
        out = capture("st --all")
 
476
        assert out == ("unknown:\n"
 
477
                       "  test.txt\n")
505
478
 
506
479
        out = capture("stat")
507
 
        self.assertEquals(out, ("unknown:\n" "  test.txt\n"))
 
480
        assert out == ("unknown:\n"
 
481
                       "  test.txt\n")
508
482
 
509
483
        progress("command help")
510
484
        runbzr("help st")
511
485
        runbzr("help")
512
486
        runbzr("help commands")
513
 
        runbzr("help slartibartfast", 3)
 
487
        runbzr("help slartibartfast", 1)
514
488
 
515
489
        out = capture("help ci")
516
490
        out.index('aliases: ')
517
491
 
 
492
        progress("can't rename unversioned file")
 
493
        runbzr("rename test.txt new-test.txt", 1)
 
494
 
 
495
        progress("adding a file")
 
496
 
 
497
        runbzr("add test.txt")
 
498
        assert capture("unknowns") == ''
 
499
        assert capture("status --all") == ("added:\n"
 
500
                                                "  test.txt\n")
 
501
 
 
502
        progress("rename newly-added file")
 
503
        runbzr("rename test.txt hello.txt")
 
504
        assert os.path.exists("hello.txt")
 
505
        assert not os.path.exists("test.txt")
 
506
 
 
507
        assert capture("revno") == '0\n'
 
508
 
 
509
        progress("add first revision")
 
510
        runbzr(['commit', '-m', 'add first revision'])
 
511
 
 
512
        progress("more complex renames")
 
513
        os.mkdir("sub1")
 
514
        runbzr("rename hello.txt sub1", 1)
 
515
        runbzr("rename hello.txt sub1/hello.txt", 1)
 
516
        runbzr("move hello.txt sub1", 1)
 
517
 
 
518
        runbzr("add sub1")
 
519
        runbzr("rename sub1 sub2")
 
520
        runbzr("move hello.txt sub2")
 
521
        assert capture("relpath sub2/hello.txt") == os.path.join("sub2", "hello.txt\n")
 
522
 
 
523
        assert exists("sub2")
 
524
        assert exists("sub2/hello.txt")
 
525
        assert not exists("sub1")
 
526
        assert not exists("hello.txt")
 
527
 
 
528
        runbzr(['commit', '-m', 'commit with some things moved to subdirs'])
 
529
 
 
530
        mkdir("sub1")
 
531
        runbzr('add sub1')
 
532
        runbzr('move sub2/hello.txt sub1')
 
533
        assert not exists('sub2/hello.txt')
 
534
        assert exists('sub1/hello.txt')
 
535
        runbzr('move sub2 sub1')
 
536
        assert not exists('sub2')
 
537
        assert exists('sub1/sub2')
 
538
 
 
539
        runbzr(['commit', '-m', 'rename nested subdirectories'])
 
540
 
 
541
        chdir('sub1/sub2')
 
542
        self.assertEquals(capture('root')[:-1],
 
543
                          os.path.join(self.test_dir, 'branch1'))
 
544
        runbzr('move ../hello.txt .')
 
545
        assert exists('./hello.txt')
 
546
        self.assertEquals(capture('relpath hello.txt'),
 
547
                          os.path.join('sub1', 'sub2', 'hello.txt') + '\n')
 
548
        assert capture('relpath ../../sub1/sub2/hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
 
549
        runbzr(['commit', '-m', 'move to parent directory'])
 
550
        chdir('..')
 
551
        assert capture('relpath sub2/hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
 
552
 
 
553
        runbzr('move sub2/hello.txt .')
 
554
        assert exists('hello.txt')
 
555
 
518
556
        f = file('hello.txt', 'wt')
519
557
        f.write('some nice new content\n')
520
558
        f.close()
521
559
 
522
 
        runbzr("add hello.txt")
523
 
        
524
560
        f = file('msg.tmp', 'wt')
525
 
        f.write('this is my new commit\nand it has multiple lines, for fun')
 
561
        f.write('this is my new commit\n')
526
562
        f.close()
527
563
 
528
564
        runbzr('commit -F msg.tmp')
529
565
 
530
 
        self.assertEquals(capture('revno'), '1\n')
531
 
        runbzr('export -r 1 export-1.tmp')
 
566
        assert capture('revno') == '5\n'
 
567
        runbzr('export -r 5 export-5.tmp')
532
568
        runbzr('export export.tmp')
533
569
 
534
570
        runbzr('log')
535
571
        runbzr('log -v')
536
572
        runbzr('log -v --forward')
537
 
        runbzr('log -m', retcode=3)
 
573
        runbzr('log -m', retcode=1)
538
574
        log_out = capture('log -m commit')
539
 
        self.assert_("this is my new commit\n  and" in log_out)
540
 
        self.assert_("rename nested" not in log_out)
541
 
        self.assert_('revision-id' not in log_out)
542
 
        self.assert_('revision-id' in capture('log --show-ids -m commit'))
 
575
        assert "this is my new commit" in log_out
 
576
        assert "rename nested" not in log_out
 
577
        assert 'revision-id' not in log_out
 
578
        assert 'revision-id' in capture('log --show-ids -m commit')
543
579
 
544
 
        log_out = capture('log --line')
545
 
        # determine the widest line we want
546
 
        max_width = terminal_width() - 1
547
 
        for line in log_out.splitlines():
548
 
            self.assert_(len(line) <= max_width, len(line))
549
 
        self.assert_("this is my new commit and" not in log_out)
550
 
        self.assert_("this is my new commit" in log_out)
551
580
 
552
581
        progress("file with spaces in name")
553
582
        mkdir('sub directory')
554
583
        file('sub directory/file with spaces ', 'wt').write('see how this works\n')
555
584
        runbzr('add .')
556
 
        runbzr('diff', retcode=1)
 
585
        runbzr('diff')
557
586
        runbzr('commit -m add-spaces')
558
587
        runbzr('check')
559
588
 
569
598
            runbzr('init')
570
599
            os.symlink("NOWHERE1", "link1")
571
600
            runbzr('add link1')
572
 
            self.assertEquals(self.capture('unknowns'), '')
 
601
            assert self.capture('unknowns') == ''
573
602
            runbzr(['commit', '-m', '1: added symlink link1'])
574
603
    
575
604
            mkdir('d1')
576
605
            runbzr('add d1')
577
 
            self.assertEquals(self.capture('unknowns'), '')
 
606
            assert self.capture('unknowns') == ''
578
607
            os.symlink("NOWHERE2", "d1/link2")
579
 
            self.assertEquals(self.capture('unknowns'), 'd1/link2\n')
 
608
            assert self.capture('unknowns') == 'd1/link2\n'
580
609
            # is d1/link2 found when adding d1
581
610
            runbzr('add d1')
582
 
            self.assertEquals(self.capture('unknowns'), '')
 
611
            assert self.capture('unknowns') == ''
583
612
            os.symlink("NOWHERE3", "d1/link3")
584
 
            self.assertEquals(self.capture('unknowns'), 'd1/link3\n')
 
613
            assert self.capture('unknowns') == 'd1/link3\n'
585
614
            runbzr(['commit', '-m', '2: added dir, symlink'])
586
615
    
587
616
            runbzr('rename d1 d2')
588
617
            runbzr('move d2/link2 .')
589
618
            runbzr('move link1 d2')
590
 
            self.assertEquals(os.readlink("./link2"), "NOWHERE2")
591
 
            self.assertEquals(os.readlink("d2/link1"), "NOWHERE1")
 
619
            assert os.readlink("./link2") == "NOWHERE2"
 
620
            assert os.readlink("d2/link1") == "NOWHERE1"
592
621
            runbzr('add d2/link3')
593
 
            runbzr('diff', retcode=1)
 
622
            runbzr('diff')
594
623
            runbzr(['commit', '-m', '3: rename of dir, move symlinks, add link3'])
595
624
    
596
625
            os.unlink("link2")
597
626
            os.symlink("TARGET 2", "link2")
598
627
            os.unlink("d2/link1")
599
628
            os.symlink("TARGET 1", "d2/link1")
600
 
            runbzr('diff', retcode=1)
601
 
            self.assertEquals(self.capture("relpath d2/link1"), "d2/link1\n")
 
629
            runbzr('diff')
 
630
            assert self.capture("relpath d2/link1") == "d2/link1\n"
602
631
            runbzr(['commit', '-m', '4: retarget of two links'])
603
632
    
604
633
            runbzr('remove d2/link1')
605
 
            self.assertEquals(self.capture('unknowns'), 'd2/link1\n')
 
634
            assert self.capture('unknowns') == 'd2/link1\n'
606
635
            runbzr(['commit', '-m', '5: remove d2/link1'])
607
 
            # try with the rm alias
608
 
            runbzr('add d2/link1')
609
 
            runbzr(['commit', '-m', '6: add d2/link1'])
610
 
            runbzr('rm d2/link1')
611
 
            self.assertEquals(self.capture('unknowns'), 'd2/link1\n')
612
 
            runbzr(['commit', '-m', '7: remove d2/link1'])
613
636
    
614
637
            os.mkdir("d1")
615
638
            runbzr('add d1')
616
639
            runbzr('rename d2/link3 d1/link3new')
617
 
            self.assertEquals(self.capture('unknowns'), 'd2/link1\n')
618
 
            runbzr(['commit', '-m', '8: remove d2/link1, move/rename link3'])
 
640
            assert self.capture('unknowns') == 'd2/link1\n'
 
641
            runbzr(['commit', '-m', '6: remove d2/link1, move/rename link3'])
619
642
            
620
643
            runbzr(['check'])
621
644
            
622
645
            runbzr(['export', '-r', '1', 'exp1.tmp'])
623
646
            chdir("exp1.tmp")
624
 
            self.assertEquals(listdir_sorted("."), [ "link1" ])
625
 
            self.assertEquals(os.readlink("link1"), "NOWHERE1")
 
647
            assert listdir_sorted(".") == [ "link1" ]
 
648
            assert os.readlink("link1") == "NOWHERE1"
626
649
            chdir("..")
627
650
            
628
651
            runbzr(['export', '-r', '2', 'exp2.tmp'])
629
652
            chdir("exp2.tmp")
630
 
            self.assertEquals(listdir_sorted("."), [ "d1", "link1" ])
 
653
            assert listdir_sorted(".") == [ "d1", "link1" ]
631
654
            chdir("..")
632
655
            
633
656
            runbzr(['export', '-r', '3', 'exp3.tmp'])
634
657
            chdir("exp3.tmp")
635
 
            self.assertEquals(listdir_sorted("."), [ "d2", "link2" ])
636
 
            self.assertEquals(listdir_sorted("d2"), [ "link1", "link3" ])
637
 
            self.assertEquals(os.readlink("d2/link1"), "NOWHERE1")
638
 
            self.assertEquals(os.readlink("link2")   , "NOWHERE2")
 
658
            assert listdir_sorted(".") == [ "d2", "link2" ]
 
659
            assert listdir_sorted("d2") == [ "link1", "link3" ]
 
660
            assert os.readlink("d2/link1") == "NOWHERE1"
 
661
            assert os.readlink("link2")    == "NOWHERE2"
639
662
            chdir("..")
640
663
            
641
664
            runbzr(['export', '-r', '4', 'exp4.tmp'])
642
665
            chdir("exp4.tmp")
643
 
            self.assertEquals(listdir_sorted("."), [ "d2", "link2" ])
644
 
            self.assertEquals(os.readlink("d2/link1"), "TARGET 1")
645
 
            self.assertEquals(os.readlink("link2")   , "TARGET 2")
646
 
            self.assertEquals(listdir_sorted("d2"), [ "link1", "link3" ])
 
666
            assert listdir_sorted(".") == [ "d2", "link2" ]
 
667
            assert os.readlink("d2/link1") == "TARGET 1"
 
668
            assert os.readlink("link2")    == "TARGET 2"
 
669
            assert listdir_sorted("d2") == [ "link1", "link3" ]
647
670
            chdir("..")
648
671
            
649
672
            runbzr(['export', '-r', '5', 'exp5.tmp'])
650
673
            chdir("exp5.tmp")
651
 
            self.assertEquals(listdir_sorted("."), [ "d2", "link2" ])
652
 
            self.assert_(os.path.islink("link2"))
653
 
            self.assert_(listdir_sorted("d2")== [ "link3" ])
 
674
            assert listdir_sorted(".") == [ "d2", "link2" ]
 
675
            assert os.path.islink("link2")
 
676
            assert listdir_sorted("d2")== [ "link3" ]
654
677
            chdir("..")
655
678
            
656
 
            runbzr(['export', '-r', '8', 'exp6.tmp'])
 
679
            runbzr(['export', '-r', '6', 'exp6.tmp'])
657
680
            chdir("exp6.tmp")
658
 
            self.assertEqual(listdir_sorted("."), [ "d1", "d2", "link2"])
659
 
            self.assertEquals(listdir_sorted("d1"), [ "link3new" ])
660
 
            self.assertEquals(listdir_sorted("d2"), [])
661
 
            self.assertEquals(os.readlink("d1/link3new"), "NOWHERE3")
 
681
            assert listdir_sorted(".") == [ "d1", "d2", "link2" ]
 
682
            assert listdir_sorted("d1") == [ "link3new" ]
 
683
            assert listdir_sorted("d2") == []
 
684
            assert os.readlink("d1/link3new") == "NOWHERE3"
662
685
            chdir("..")
663
686
        else:
664
687
            progress("skipping symlink tests")
665
 
 
666
 
 
667
 
class RemoteTests(object):
668
 
    """Test bzr ui commands against remote branches."""
669
 
 
670
 
    def test_branch(self):
671
 
        os.mkdir('from')
672
 
        wt = self.make_branch_and_tree('from')
673
 
        branch = wt.branch
674
 
        wt.commit('empty commit for nonsense', allow_pointless=True)
675
 
        url = self.get_readonly_url('from')
676
 
        self.run_bzr('branch', url, 'to')
677
 
        branch = Branch.open('to')
678
 
        self.assertEqual(1, len(branch.revision_history()))
679
 
        # the branch should be set in to to from
680
 
        self.assertEqual(url + '/', branch.get_parent())
681
 
 
682
 
    def test_log(self):
683
 
        self.build_tree(['branch/', 'branch/file'])
684
 
        self.capture('init branch')
685
 
        self.capture('add branch/file')
686
 
        self.capture('commit -m foo branch')
687
 
        url = self.get_readonly_url('branch/file')
688
 
        output = self.capture('log %s' % url)
689
 
        self.assertEqual(8, len(output.split('\n')))
690
 
        
691
 
    def test_check(self):
692
 
        self.build_tree(['branch/', 'branch/file'])
693
 
        self.capture('init branch')
694
 
        self.capture('add branch/file')
695
 
        self.capture('commit -m foo branch')
696
 
        url = self.get_readonly_url('branch/')
697
 
        self.run_bzr('check', url)
698
 
    
699
 
    def test_push(self):
700
 
        # create a source branch
701
 
        os.mkdir('my-branch')
702
 
        os.chdir('my-branch')
703
 
        self.run_bzr('init')
704
 
        file('hello', 'wt').write('foo')
705
 
        self.run_bzr('add', 'hello')
706
 
        self.run_bzr('commit', '-m', 'setup')
707
 
 
708
 
        # with an explicit target work
709
 
        self.run_bzr('push', self.get_url('output-branch'))
710
 
 
711
 
    
712
 
class HTTPTests(TestCaseWithWebserver, RemoteTests):
713
 
    """Test various commands against a HTTP server."""
714
 
    
715
 
    
716
 
class SFTPTestsAbsolute(TestCaseWithSFTPServer, RemoteTests):
717
 
    """Test various commands against a SFTP server using abs paths."""
718
 
 
719
 
    
720
 
class SFTPTestsAbsoluteSibling(TestCaseWithSFTPServer, RemoteTests):
721
 
    """Test various commands against a SFTP server using abs paths."""
722
 
 
723
 
    def setUp(self):
724
 
        super(SFTPTestsAbsoluteSibling, self).setUp()
725
 
        self._override_home = '/dev/noone/runs/tests/here'
726
 
 
727
 
    
728
 
class SFTPTestsRelative(TestCaseWithSFTPServer, RemoteTests):
729
 
    """Test various commands against a SFTP server using homedir rel paths."""
730
 
 
731
 
    def setUp(self):
732
 
        super(SFTPTestsRelative, self).setUp()
733
 
        self._get_remote_is_absolute = False
 
688