~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/selftest/blackbox.py

fixme note for bzr status

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
 
from cStringIO import StringIO
 
29
import sys
38
30
import os
39
 
import re
40
 
import sys
41
31
 
42
 
import bzrlib
 
32
from bzrlib.selftest import TestCaseInTempDir, BzrTestBase
43
33
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
 
34
from bzrlib.commands import run_bzr
 
35
 
 
36
 
 
37
class ExternalBase(TestCaseInTempDir):
 
38
    def runbzr(self, args, retcode=0,backtick=False):
 
39
        if isinstance(args, basestring):
 
40
            args = args.split()
 
41
 
 
42
        if backtick:
 
43
            return self.backtick(['python', self.BZRPATH,] + args,
 
44
                           retcode=retcode)
 
45
        else:
 
46
            return self.runcmd(['python', self.BZRPATH,] + args,
 
47
                           retcode=retcode)
56
48
 
57
49
 
58
50
class TestCommands(ExternalBase):
59
51
 
60
 
    def test_nick_command(self):
61
 
        """bzr nick for viewing, setting nicknames"""
62
 
        os.mkdir('me.dev')
63
 
        os.chdir('me.dev')
 
52
    def test_help_commands(self):
 
53
        self.runbzr('--help')
 
54
        self.runbzr('help')
 
55
        self.runbzr('help commands')
 
56
        self.runbzr('help help')
 
57
        self.runbzr('commit -h')
 
58
 
 
59
    def test_init_branch(self):
 
60
        self.runbzr(['init'])
 
61
 
 
62
    def test_whoami(self):
 
63
        # this should always identify something, if only "john@localhost"
 
64
        self.runbzr("whoami")
 
65
        self.runbzr("whoami --email")
 
66
 
 
67
        self.assertEquals(self.runbzr("whoami --email",
 
68
                                      backtick=True).count('@'), 1)
 
69
        
 
70
    def test_whoami_branch(self):
 
71
        """branch specific user identity works."""
64
72
        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')
 
73
        f = file('.bzr/email', 'wt')
 
74
        f.write('Branch Identity <branch@identi.ty>')
 
75
        f.close()
 
76
        whoami = self.runbzr("whoami",backtick=True)
 
77
        whoami_email = self.runbzr("whoami --email",backtick=True)
 
78
        self.assertTrue(whoami.startswith('Branch Identity <branch@identi.ty>'))
 
79
        self.assertTrue(whoami_email.startswith('branch@identi.ty'))
70
80
 
71
81
    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)
 
82
        self.runbzr("pants", retcode=1)
 
83
        self.runbzr("--pants off", retcode=1)
 
84
        self.runbzr("diff --message foo", retcode=1)
 
85
 
 
86
    def test_empty_commit(self):
 
87
        self.runbzr("init")
 
88
        self.build_tree(['hello.txt'])
 
89
        self.runbzr("commit -m empty", retcode=1)
 
90
        self.runbzr("add hello.txt")
 
91
        self.runbzr("commit -m added")
 
92
 
 
93
    def test_ignore_patterns(self):
 
94
        from bzrlib.branch import Branch
 
95
        
 
96
        b = Branch('.', init=True)
 
97
        self.assertEquals(list(b.unknowns()), [])
 
98
 
 
99
        file('foo.tmp', 'wt').write('tmp files are ignored')
 
100
        self.assertEquals(list(b.unknowns()), [])
 
101
        assert self.backtick('bzr unknowns') == ''
 
102
 
 
103
        file('foo.c', 'wt').write('int main() {}')
 
104
        self.assertEquals(list(b.unknowns()), ['foo.c'])
 
105
        assert self.backtick('bzr unknowns') == 'foo.c\n'
 
106
 
 
107
        self.runbzr(['add', 'foo.c'])
 
108
        assert self.backtick('bzr unknowns') == ''
 
109
 
 
110
        # 'ignore' works when creating the .bzignore file
 
111
        file('foo.blah', 'wt').write('blah')
 
112
        self.assertEquals(list(b.unknowns()), ['foo.blah'])
 
113
        self.runbzr('ignore *.blah')
 
114
        self.assertEquals(list(b.unknowns()), [])
 
115
        assert file('.bzrignore', 'rb').read() == '*.blah\n'
 
116
 
 
117
        # 'ignore' works when then .bzrignore file already exists
 
118
        file('garh', 'wt').write('garh')
 
119
        self.assertEquals(list(b.unknowns()), ['garh'])
 
120
        assert self.backtick('bzr unknowns') == 'garh\n'
 
121
        self.runbzr('ignore garh')
 
122
        self.assertEquals(list(b.unknowns()), [])
 
123
        assert file('.bzrignore', 'rb').read() == '*.blah\ngarh\n'
75
124
 
76
125
    def test_revert(self):
77
126
        self.runbzr('init')
83
132
        file('goodbye', 'wt').write('baz')
84
133
        self.runbzr('add goodbye')
85
134
        self.runbzr('commit -m setup goodbye')
86
 
 
 
135
        
87
136
        file('hello', 'wt').write('bar')
88
137
        file('goodbye', 'wt').write('qux')
89
138
        self.runbzr('revert hello')
98
147
        os.rmdir('revertdir')
99
148
        self.runbzr('revert')
100
149
 
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")
115
 
        
116
 
        file('hello', 'wt').write('xyz')
117
 
        self.runbzr('commit -m xyz hello')
118
 
        self.runbzr('revert -r 1 hello')
119
 
        self.check_file_contents('hello', 'foo')
120
 
        self.runbzr('revert hello')
121
 
        self.check_file_contents('hello', 'xyz')
122
 
        os.chdir('revertdir')
123
 
        self.runbzr('revert')
124
 
        os.chdir('..')
 
150
    def test_mv_modes(self):
 
151
        """Test two modes of operation for mv"""
 
152
        from bzrlib.branch import Branch
 
153
        b = Branch('.', init=True)
 
154
        self.build_tree(['a', 'c', 'subdir/'])
 
155
        self.run_bzr('add', self.test_dir)
 
156
        self.run_bzr('mv', 'a', 'b')
 
157
        self.run_bzr('mv', 'b', 'subdir')
 
158
        self.run_bzr('mv', 'subdir/b', 'a')
 
159
        self.run_bzr('mv', 'a', 'c', 'subdir')
 
160
        self.run_bzr('mv', 'subdir/a', 'subdir/newa')
 
161
 
125
162
 
126
163
    def test_main_version(self):
127
164
        """Check output from version command and master option is reasonable"""
130
167
        output = self.runbzr('version', backtick=1)
131
168
        self.log('bzr version output:')
132
169
        self.log(output)
133
 
        self.assert_(output.startswith('Bazaar (bzr) '))
 
170
        self.assert_(output.startswith('bzr (bazaar-ng) '))
134
171
        self.assertNotEqual(output.index('Canonical'), -1)
135
172
        # make sure --version is consistent
136
173
        tmp_output = self.runbzr('--version', backtick=1)
147
184
        test.runbzr('add goodbye')
148
185
        test.runbzr('commit -m setup goodbye')
149
186
 
150
 
    def test_pull_verbose(self):
151
 
        """Pull changes from one branch to another and watch the output."""
152
 
 
153
 
        os.mkdir('a')
154
 
        os.chdir('a')
155
 
 
156
 
        bzr = self.runbzr
 
187
    def test_revert(self):
157
188
        self.example_branch()
158
 
 
159
 
        os.chdir('..')
160
 
        bzr('branch a b')
161
 
        os.chdir('b')
162
 
        open('b', 'wb').write('else\n')
163
 
        bzr('add b')
164
 
        bzr(['commit', '-m', 'added b'])
165
 
 
166
 
        os.chdir('../a')
167
 
        out = bzr('pull --verbose ../b', backtick=True)
168
 
        self.failIfEqual(out.find('Added Revisions:'), -1)
169
 
        self.failIfEqual(out.find('message:\n  added b'), -1)
170
 
        self.failIfEqual(out.find('added b'), -1)
171
 
 
172
 
        # Check that --overwrite --verbose prints out the removed entries
173
 
        bzr('commit -m foo --unchanged')
174
 
        os.chdir('../b')
175
 
        bzr('commit -m baz --unchanged')
176
 
        bzr('pull ../a', retcode=3)
177
 
        out = bzr('pull --overwrite --verbose ../a', backtick=1)
178
 
 
179
 
        remove_loc = out.find('Removed Revisions:')
180
 
        self.failIfEqual(remove_loc, -1)
181
 
        added_loc = out.find('Added Revisions:')
182
 
        self.failIfEqual(added_loc, -1)
183
 
 
184
 
        removed_message = out.find('message:\n  baz')
185
 
        self.failIfEqual(removed_message, -1)
186
 
        self.failUnless(remove_loc < removed_message < added_loc)
187
 
 
188
 
        added_message = out.find('message:\n  foo')
189
 
        self.failIfEqual(added_message, -1)
190
 
        self.failUnless(added_loc < added_message)
 
189
        file('hello', 'wt').write('bar')
 
190
        file('goodbye', 'wt').write('qux')
 
191
        self.runbzr('revert hello')
 
192
        self.check_file_contents('hello', 'foo')
 
193
        self.check_file_contents('goodbye', 'qux')
 
194
        self.runbzr('revert')
 
195
        self.check_file_contents('goodbye', 'baz')
 
196
 
 
197
    def test_merge(self):
 
198
        from bzrlib.branch import Branch
191
199
        
192
 
    def test_locations(self):
193
 
        """Using and remembering different locations"""
194
 
        os.mkdir('a')
195
 
        os.chdir('a')
196
 
        self.runbzr('init')
197
 
        self.runbzr('commit -m unchanged --unchanged')
198
 
        self.runbzr('pull', retcode=3)
199
 
        self.runbzr('merge', retcode=3)
200
 
        self.runbzr('branch . ../b')
201
 
        os.chdir('../b')
202
 
        self.runbzr('pull')
203
 
        self.runbzr('branch . ../c')
204
 
        self.runbzr('pull ../c')
205
 
        self.runbzr('merge')
206
 
        os.chdir('../a')
 
200
        os.mkdir('a')
 
201
        os.chdir('a')
 
202
        self.example_branch()
 
203
        os.chdir('..')
 
204
        self.runbzr('branch a b')
 
205
        os.chdir('b')
 
206
        file('goodbye', 'wt').write('quux')
 
207
        self.runbzr(['commit',  '-m',  "more u's are always good"])
 
208
 
 
209
        os.chdir('../a')
 
210
        file('hello', 'wt').write('quuux')
 
211
        # We can't merge when there are in-tree changes
 
212
        self.runbzr('merge ../b', retcode=1)
 
213
        self.runbzr(['commit', '-m', "Like an epidemic of u's"])
 
214
        self.runbzr('merge ../b')
 
215
        self.check_file_contents('goodbye', 'quux')
 
216
        # Merging a branch pulls its revision into the tree
 
217
        a = Branch('.')
 
218
        b = Branch('../b')
 
219
        a.get_revision_xml(b.last_patch())
 
220
        self.log('pending merges: %s', a.pending_merges())
 
221
        #        assert a.pending_merges() == [b.last_patch()], "Assertion %s %s" \
 
222
        #        % (a.pending_merges(), b.last_patch())
 
223
 
 
224
    def test_pull(self):
 
225
        """Pull changes from one branch to another."""
 
226
        os.mkdir('a')
 
227
        os.chdir('a')
 
228
 
 
229
        self.example_branch()
 
230
        os.chdir('..')
 
231
        self.runbzr('branch a b')
 
232
        os.chdir('b')
 
233
        self.runbzr('commit -m blah --unchanged')
 
234
        os.chdir('../a')
 
235
        a = Branch('.')
 
236
        b = Branch('../b')
 
237
        assert a.revision_history() == b.revision_history()[:-1]
207
238
        self.runbzr('pull ../b')
208
 
        self.runbzr('pull')
209
 
        self.runbzr('pull ../c')
210
 
        self.runbzr('branch ../c ../d')
211
 
        rmtree('../c')
212
 
        self.runbzr('pull')
213
 
        os.chdir('../b')
214
 
        self.runbzr('pull')
215
 
        os.chdir('../d')
216
 
        self.runbzr('pull', retcode=3)
217
 
        self.runbzr('pull ../a --remember')
218
 
        self.runbzr('pull')
219
 
        
220
 
    def test_unknown_command(self):
221
 
        """Handling of unknown command."""
222
 
        out, err = self.run_bzr_captured(['fluffy-badger'],
223
 
                                         retcode=3)
224
 
        self.assertEquals(out, '')
225
 
        err.index('unknown command')
226
 
 
227
 
    def create_conflicts(self):
228
 
        """Create a conflicted tree"""
229
 
        os.mkdir('base')
230
 
        os.chdir('base')
231
 
        file('hello', 'wb').write("hi world")
232
 
        file('answer', 'wb').write("42")
233
 
        self.runbzr('init')
234
 
        self.runbzr('add')
235
 
        self.runbzr('commit -m base')
236
 
        self.runbzr('branch . ../other')
237
 
        self.runbzr('branch . ../this')
238
 
        os.chdir('../other')
239
 
        file('hello', 'wb').write("Hello.")
240
 
        file('answer', 'wb').write("Is anyone there?")
241
 
        self.runbzr('commit -m other')
242
 
        os.chdir('../this')
243
 
        file('hello', 'wb').write("Hello, world")
244
 
        self.runbzr('mv answer question')
245
 
        file('question', 'wb').write("What do you get when you multiply six"
246
 
                                   "times nine?")
247
 
        self.runbzr('commit -m this')
248
 
 
249
 
    def test_status(self):
250
 
        os.mkdir('branch1')
251
 
        os.chdir('branch1')
252
 
        self.runbzr('init')
253
 
        self.runbzr('commit --unchanged --message f')
254
 
        self.runbzr('branch . ../branch2')
255
 
        self.runbzr('branch . ../branch3')
256
 
        self.runbzr('commit --unchanged --message peter')
257
 
        os.chdir('../branch2')
258
 
        self.runbzr('merge ../branch1')
259
 
        self.runbzr('commit --unchanged --message pumpkin')
260
 
        os.chdir('../branch3')
261
 
        self.runbzr('merge ../branch2')
262
 
        message = self.capture('status')
263
 
 
264
 
 
265
 
    def test_conflicts(self):
266
 
        """Handling of merge conflicts"""
267
 
        self.create_conflicts()
268
 
        self.runbzr('merge ../other --show-base', retcode=1)
269
 
        conflict_text = file('hello').read()
270
 
        self.assert_('<<<<<<<' in conflict_text)
271
 
        self.assert_('>>>>>>>' in conflict_text)
272
 
        self.assert_('=======' in conflict_text)
273
 
        self.assert_('|||||||' in conflict_text)
274
 
        self.assert_('hi world' in conflict_text)
275
 
        self.runbzr('revert')
276
 
        self.runbzr('resolve --all')
277
 
        self.runbzr('merge ../other', retcode=1)
278
 
        conflict_text = file('hello').read()
279
 
        self.assert_('|||||||' not in conflict_text)
280
 
        self.assert_('hi world' not in conflict_text)
281
 
        result = self.runbzr('conflicts', backtick=1)
282
 
        self.assertEquals(result, "Text conflict in hello\nText conflict in"
283
 
                                  " question\n")
284
 
        result = self.runbzr('status', backtick=1)
285
 
        self.assert_("conflicts:\n  Text conflict in hello\n"
286
 
                     "  Text conflict in question\n" in result, result)
287
 
        self.runbzr('resolve hello')
288
 
        result = self.runbzr('conflicts', backtick=1)
289
 
        self.assertEquals(result, "Text conflict in question\n")
290
 
        self.runbzr('commit -m conflicts', retcode=3)
291
 
        self.runbzr('resolve --all')
292
 
        result = self.runbzr('conflicts', backtick=1)
293
 
        self.runbzr('commit -m conflicts')
294
 
        self.assertEquals(result, "")
295
 
 
296
 
    def test_push(self):
297
 
        # create a source branch
298
 
        os.mkdir('my-branch')
299
 
        os.chdir('my-branch')
300
 
        self.example_branch()
301
 
 
302
 
        # with no push target, fail
303
 
        self.runbzr('push', retcode=3)
304
 
        # with an explicit target work
305
 
        self.runbzr('push ../output-branch')
306
 
        # with an implicit target work
307
 
        self.runbzr('push')
308
 
        # nothing missing
309
 
        self.runbzr('missing ../output-branch')
310
 
        # advance this branch
311
 
        self.runbzr('commit --unchanged -m unchanged')
312
 
 
313
 
        os.chdir('../output-branch')
314
 
        # There is no longer a difference as long as we have
315
 
        # access to the working tree
316
 
        self.runbzr('diff')
317
 
 
318
 
        # But we should be missing a revision
319
 
        self.runbzr('missing ../my-branch', retcode=1)
320
 
 
321
 
        # diverge the branches
322
 
        self.runbzr('commit --unchanged -m unchanged')
323
 
        os.chdir('../my-branch')
324
 
        # cannot push now
325
 
        self.runbzr('push', retcode=3)
326
 
        # and there are difference
327
 
        self.runbzr('missing ../output-branch', retcode=1)
328
 
        self.runbzr('missing --verbose ../output-branch', retcode=1)
329
 
        # but we can force a push
330
 
        self.runbzr('push --overwrite')
331
 
        # nothing missing
332
 
        self.runbzr('missing ../output-branch')
333
 
        
334
 
        # pushing to a new dir with no parent should fail
335
 
        self.runbzr('push ../missing/new-branch', retcode=3)
336
 
        # unless we provide --create-prefix
337
 
        self.runbzr('push --create-prefix ../missing/new-branch')
338
 
        # nothing missing
339
 
        self.runbzr('missing ../missing/new-branch')
340
 
 
341
 
    def test_external_command(self):
342
 
        """Test that external commands can be run by setting the path
343
 
        """
344
 
        # We don't at present run bzr in a subprocess for blackbox tests, and so 
345
 
        # don't really capture stdout, only the internal python stream.
346
 
        # Therefore we don't use a subcommand that produces any output or does
347
 
        # anything -- we just check that it can be run successfully.  
348
 
        cmd_name = 'test-command'
349
 
        if sys.platform == 'win32':
350
 
            cmd_name += '.bat'
351
 
        oldpath = os.environ.get('BZRPATH', None)
352
 
        bzr = self.capture
353
 
        try:
354
 
            if 'BZRPATH' in os.environ:
355
 
                del os.environ['BZRPATH']
356
 
 
357
 
            f = file(cmd_name, 'wb')
358
 
            if sys.platform == 'win32':
359
 
                f.write('@echo off\n')
360
 
            else:
361
 
                f.write('#!/bin/sh\n')
362
 
            # f.write('echo Hello from test-command')
363
 
            f.close()
364
 
            os.chmod(cmd_name, 0755)
365
 
 
366
 
            # It should not find the command in the local 
367
 
            # directory by default, since it is not in my path
368
 
            bzr(cmd_name, retcode=3)
369
 
 
370
 
            # Now put it into my path
371
 
            os.environ['BZRPATH'] = '.'
372
 
 
373
 
            bzr(cmd_name)
374
 
 
375
 
            # Make sure empty path elements are ignored
376
 
            os.environ['BZRPATH'] = os.pathsep
377
 
 
378
 
            bzr(cmd_name, retcode=3)
379
 
 
380
 
        finally:
381
 
            if oldpath:
382
 
                os.environ['BZRPATH'] = oldpath
383
 
 
384
 
 
385
 
def listdir_sorted(dir):
386
 
    L = os.listdir(dir)
387
 
    L.sort()
388
 
    return L
 
239
        assert a.revision_history() == b.revision_history()
 
240
        self.runbzr('commit -m blah2 --unchanged')
 
241
        os.chdir('../b')
 
242
        self.runbzr('commit -m blah3 --unchanged')
 
243
        self.runbzr('pull ../a', retcode=1)
 
244
        os.chdir('../a')
 
245
        self.runbzr('merge ../b')
 
246
        self.runbzr('commit -m blah4 --unchanged')
 
247
        os.chdir('../b')
 
248
        self.runbzr('pull ../a')
 
249
        assert a.revision_history()[-1] == b.revision_history()[-1]
 
250
        
 
251
 
 
252
    def test_add_reports(self):
 
253
        """add command prints the names of added files."""
 
254
        b = Branch('.', init=True)
 
255
        self.build_tree(['top.txt', 'dir/', 'dir/sub.txt'])
 
256
 
 
257
        from cStringIO import StringIO
 
258
        out = StringIO()
 
259
 
 
260
        ret = self.apply_redirected(None, out, None,
 
261
                                    run_bzr,
 
262
                                    ['add'])
 
263
        self.assertEquals(ret, 0)
 
264
 
 
265
        # the ordering is not defined at the moment
 
266
        results = sorted(out.getvalue().rstrip('\n').split('\n'))
 
267
        self.assertEquals(['added dir',
 
268
                           'added dir/sub.txt',
 
269
                           'added top.txt',],
 
270
                          results)
389
271
 
390
272
 
391
273
class OldTests(ExternalBase):
396
278
        from os.path import exists
397
279
 
398
280
        runbzr = self.runbzr
399
 
        capture = self.capture
 
281
        backtick = self.backtick
400
282
        progress = self.log
401
283
 
402
284
        progress("basic branch creation")
404
286
        chdir('branch1')
405
287
        runbzr('init')
406
288
 
407
 
        self.assertEquals(capture('root').rstrip(),
408
 
                          pathjoin(self.test_dir, 'branch1'))
 
289
        self.assertEquals(backtick('bzr root').rstrip(),
 
290
                          os.path.join(self.test_dir, 'branch1'))
409
291
 
410
292
        progress("status of new file")
411
293
 
413
295
        f.write('hello world!\n')
414
296
        f.close()
415
297
 
416
 
        self.assertEquals(capture('unknowns'), 'test.txt\n')
417
 
 
418
 
        out = capture("status")
419
 
        self.assertEquals(out, 'unknown:\n  test.txt\n')
 
298
        out = backtick("bzr unknowns")
 
299
        self.assertEquals(out, 'test.txt\n')
 
300
 
 
301
        out = backtick("bzr status")
 
302
        assert out == 'unknown:\n  test.txt\n'
 
303
 
 
304
        out = backtick("bzr status --all")
 
305
        assert out == "unknown:\n  test.txt\n"
 
306
 
 
307
        out = backtick("bzr status test.txt --all")
 
308
        assert out == "unknown:\n  test.txt\n"
420
309
 
421
310
        f = file('test2.txt', 'wt')
422
311
        f.write('goodbye cruel world...\n')
423
312
        f.close()
424
313
 
425
 
        out = capture("status test.txt")
426
 
        self.assertEquals(out, "unknown:\n  test.txt\n")
 
314
        out = backtick("bzr status test.txt")
 
315
        assert out == "unknown:\n  test.txt\n"
427
316
 
428
 
        out = capture("status")
429
 
        self.assertEquals(out, ("unknown:\n" "  test.txt\n" "  test2.txt\n"))
 
317
        out = backtick("bzr status")
 
318
        assert out == ("unknown:\n"
 
319
                       "  test.txt\n"
 
320
                       "  test2.txt\n")
430
321
 
431
322
        os.unlink('test2.txt')
432
323
 
433
324
        progress("command aliases")
434
 
        out = capture("st")
435
 
        self.assertEquals(out, ("unknown:\n" "  test.txt\n"))
 
325
        out = backtick("bzr st --all")
 
326
        assert out == ("unknown:\n"
 
327
                       "  test.txt\n")
436
328
 
437
 
        out = capture("stat")
438
 
        self.assertEquals(out, ("unknown:\n" "  test.txt\n"))
 
329
        out = backtick("bzr stat")
 
330
        assert out == ("unknown:\n"
 
331
                       "  test.txt\n")
439
332
 
440
333
        progress("command help")
441
334
        runbzr("help st")
442
335
        runbzr("help")
443
336
        runbzr("help commands")
444
 
        runbzr("help slartibartfast", 3)
 
337
        runbzr("help slartibartfast", 1)
445
338
 
446
 
        out = capture("help ci")
 
339
        out = backtick("bzr help ci")
447
340
        out.index('aliases: ')
448
341
 
 
342
        progress("can't rename unversioned file")
 
343
        runbzr("rename test.txt new-test.txt", 1)
 
344
 
 
345
        progress("adding a file")
 
346
 
 
347
        runbzr("add test.txt")
 
348
        assert backtick("bzr unknowns") == ''
 
349
        assert backtick("bzr status --all") == ("added:\n"
 
350
                                                "  test.txt\n")
 
351
 
 
352
        progress("rename newly-added file")
 
353
        runbzr("rename test.txt hello.txt")
 
354
        assert os.path.exists("hello.txt")
 
355
        assert not os.path.exists("test.txt")
 
356
 
 
357
        assert backtick("bzr revno") == '0\n'
 
358
 
 
359
        progress("add first revision")
 
360
        runbzr(['commit', '-m', 'add first revision'])
 
361
 
 
362
        progress("more complex renames")
 
363
        os.mkdir("sub1")
 
364
        runbzr("rename hello.txt sub1", 1)
 
365
        runbzr("rename hello.txt sub1/hello.txt", 1)
 
366
        runbzr("move hello.txt sub1", 1)
 
367
 
 
368
        runbzr("add sub1")
 
369
        runbzr("rename sub1 sub2")
 
370
        runbzr("move hello.txt sub2")
 
371
        assert backtick("bzr relpath sub2/hello.txt") == os.path.join("sub2", "hello.txt\n")
 
372
 
 
373
        assert exists("sub2")
 
374
        assert exists("sub2/hello.txt")
 
375
        assert not exists("sub1")
 
376
        assert not exists("hello.txt")
 
377
 
 
378
        runbzr(['commit', '-m', 'commit with some things moved to subdirs'])
 
379
 
 
380
        mkdir("sub1")
 
381
        runbzr('add sub1')
 
382
        runbzr('move sub2/hello.txt sub1')
 
383
        assert not exists('sub2/hello.txt')
 
384
        assert exists('sub1/hello.txt')
 
385
        runbzr('move sub2 sub1')
 
386
        assert not exists('sub2')
 
387
        assert exists('sub1/sub2')
 
388
 
 
389
        runbzr(['commit', '-m', 'rename nested subdirectories'])
 
390
 
 
391
        chdir('sub1/sub2')
 
392
        self.assertEquals(backtick('bzr root')[:-1],
 
393
                          os.path.join(self.test_dir, 'branch1'))
 
394
        runbzr('move ../hello.txt .')
 
395
        assert exists('./hello.txt')
 
396
        assert backtick('bzr relpath hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
 
397
        assert backtick('bzr relpath ../../sub1/sub2/hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
 
398
        runbzr(['commit', '-m', 'move to parent directory'])
 
399
        chdir('..')
 
400
        assert backtick('bzr relpath sub2/hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
 
401
 
 
402
        runbzr('move sub2/hello.txt .')
 
403
        assert exists('hello.txt')
 
404
 
449
405
        f = file('hello.txt', 'wt')
450
406
        f.write('some nice new content\n')
451
407
        f.close()
452
408
 
453
 
        runbzr("add hello.txt")
454
 
        
455
409
        f = file('msg.tmp', 'wt')
456
 
        f.write('this is my new commit\nand it has multiple lines, for fun')
 
410
        f.write('this is my new commit\n')
457
411
        f.close()
458
412
 
459
413
        runbzr('commit -F msg.tmp')
460
414
 
461
 
        self.assertEquals(capture('revno'), '1\n')
462
 
        runbzr('export -r 1 export-1.tmp')
 
415
        assert backtick('bzr revno') == '5\n'
 
416
        runbzr('export -r 5 export-5.tmp')
463
417
        runbzr('export export.tmp')
464
418
 
465
419
        runbzr('log')
466
420
        runbzr('log -v')
467
421
        runbzr('log -v --forward')
468
 
        runbzr('log -m', retcode=3)
469
 
        log_out = capture('log -m commit')
470
 
        self.assert_("this is my new commit\n  and" in log_out)
471
 
        self.assert_("rename nested" not in log_out)
472
 
        self.assert_('revision-id' not in log_out)
473
 
        self.assert_('revision-id' in capture('log --show-ids -m commit'))
 
422
        runbzr('log -m', retcode=1)
 
423
        log_out = backtick('bzr log -m commit')
 
424
        assert "this is my new commit" in log_out
 
425
        assert "rename nested" not in log_out
 
426
        assert 'revision-id' not in log_out
 
427
        assert 'revision-id' in backtick('bzr log --show-ids -m commit')
474
428
 
475
 
        log_out = capture('log --line')
476
 
        # determine the widest line we want
477
 
        max_width = terminal_width() - 1
478
 
        for line in log_out.splitlines():
479
 
            self.assert_(len(line) <= max_width, len(line))
480
 
        self.assert_("this is my new commit and" not in log_out)
481
 
        self.assert_("this is my new commit" in log_out)
482
429
 
483
430
        progress("file with spaces in name")
484
431
        mkdir('sub directory')
485
432
        file('sub directory/file with spaces ', 'wt').write('see how this works\n')
486
433
        runbzr('add .')
487
 
        runbzr('diff', retcode=1)
 
434
        runbzr('diff')
488
435
        runbzr('commit -m add-spaces')
489
436
        runbzr('check')
490
437
 
493
440
 
494
441
        runbzr('info')
495
442
 
496
 
        if has_symlinks():
497
 
            progress("symlinks")
498
 
            mkdir('symlinks')
499
 
            chdir('symlinks')
500
 
            runbzr('init')
501
 
            os.symlink("NOWHERE1", "link1")
502
 
            runbzr('add link1')
503
 
            self.assertEquals(self.capture('unknowns'), '')
504
 
            runbzr(['commit', '-m', '1: added symlink link1'])
505
 
    
506
 
            mkdir('d1')
507
 
            runbzr('add d1')
508
 
            self.assertEquals(self.capture('unknowns'), '')
509
 
            os.symlink("NOWHERE2", "d1/link2")
510
 
            self.assertEquals(self.capture('unknowns'), 'd1/link2\n')
511
 
            # is d1/link2 found when adding d1
512
 
            runbzr('add d1')
513
 
            self.assertEquals(self.capture('unknowns'), '')
514
 
            os.symlink("NOWHERE3", "d1/link3")
515
 
            self.assertEquals(self.capture('unknowns'), 'd1/link3\n')
516
 
            runbzr(['commit', '-m', '2: added dir, symlink'])
517
 
    
518
 
            runbzr('rename d1 d2')
519
 
            runbzr('move d2/link2 .')
520
 
            runbzr('move link1 d2')
521
 
            self.assertEquals(os.readlink("./link2"), "NOWHERE2")
522
 
            self.assertEquals(os.readlink("d2/link1"), "NOWHERE1")
523
 
            runbzr('add d2/link3')
524
 
            runbzr('diff', retcode=1)
525
 
            runbzr(['commit', '-m', '3: rename of dir, move symlinks, add link3'])
526
 
    
527
 
            os.unlink("link2")
528
 
            os.symlink("TARGET 2", "link2")
529
 
            os.unlink("d2/link1")
530
 
            os.symlink("TARGET 1", "d2/link1")
531
 
            runbzr('diff', retcode=1)
532
 
            self.assertEquals(self.capture("relpath d2/link1"), "d2/link1\n")
533
 
            runbzr(['commit', '-m', '4: retarget of two links'])
534
 
    
535
 
            runbzr('remove d2/link1')
536
 
            self.assertEquals(self.capture('unknowns'), 'd2/link1\n')
537
 
            runbzr(['commit', '-m', '5: remove d2/link1'])
538
 
            # try with the rm alias
539
 
            runbzr('add d2/link1')
540
 
            runbzr(['commit', '-m', '6: add d2/link1'])
541
 
            runbzr('rm d2/link1')
542
 
            self.assertEquals(self.capture('unknowns'), 'd2/link1\n')
543
 
            runbzr(['commit', '-m', '7: remove d2/link1'])
544
 
    
545
 
            os.mkdir("d1")
546
 
            runbzr('add d1')
547
 
            runbzr('rename d2/link3 d1/link3new')
548
 
            self.assertEquals(self.capture('unknowns'), 'd2/link1\n')
549
 
            runbzr(['commit', '-m', '8: remove d2/link1, move/rename link3'])
550
 
            
551
 
            runbzr(['check'])
552
 
            
553
 
            runbzr(['export', '-r', '1', 'exp1.tmp'])
554
 
            chdir("exp1.tmp")
555
 
            self.assertEquals(listdir_sorted("."), [ "link1" ])
556
 
            self.assertEquals(os.readlink("link1"), "NOWHERE1")
557
 
            chdir("..")
558
 
            
559
 
            runbzr(['export', '-r', '2', 'exp2.tmp'])
560
 
            chdir("exp2.tmp")
561
 
            self.assertEquals(listdir_sorted("."), [ "d1", "link1" ])
562
 
            chdir("..")
563
 
            
564
 
            runbzr(['export', '-r', '3', 'exp3.tmp'])
565
 
            chdir("exp3.tmp")
566
 
            self.assertEquals(listdir_sorted("."), [ "d2", "link2" ])
567
 
            self.assertEquals(listdir_sorted("d2"), [ "link1", "link3" ])
568
 
            self.assertEquals(os.readlink("d2/link1"), "NOWHERE1")
569
 
            self.assertEquals(os.readlink("link2")   , "NOWHERE2")
570
 
            chdir("..")
571
 
            
572
 
            runbzr(['export', '-r', '4', 'exp4.tmp'])
573
 
            chdir("exp4.tmp")
574
 
            self.assertEquals(listdir_sorted("."), [ "d2", "link2" ])
575
 
            self.assertEquals(os.readlink("d2/link1"), "TARGET 1")
576
 
            self.assertEquals(os.readlink("link2")   , "TARGET 2")
577
 
            self.assertEquals(listdir_sorted("d2"), [ "link1", "link3" ])
578
 
            chdir("..")
579
 
            
580
 
            runbzr(['export', '-r', '5', 'exp5.tmp'])
581
 
            chdir("exp5.tmp")
582
 
            self.assertEquals(listdir_sorted("."), [ "d2", "link2" ])
583
 
            self.assert_(os.path.islink("link2"))
584
 
            self.assert_(listdir_sorted("d2")== [ "link3" ])
585
 
            chdir("..")
586
 
            
587
 
            runbzr(['export', '-r', '8', 'exp6.tmp'])
588
 
            chdir("exp6.tmp")
589
 
            self.assertEqual(listdir_sorted("."), [ "d1", "d2", "link2"])
590
 
            self.assertEquals(listdir_sorted("d1"), [ "link3new" ])
591
 
            self.assertEquals(listdir_sorted("d2"), [])
592
 
            self.assertEquals(os.readlink("d1/link3new"), "NOWHERE3")
593
 
            chdir("..")
594
 
        else:
595
 
            progress("skipping symlink tests")
596
 
 
597
 
 
598
 
class RemoteTests(object):
599
 
    """Test bzr ui commands against remote branches."""
600
 
 
601
 
    def test_branch(self):
602
 
        os.mkdir('from')
603
 
        wt = self.make_branch_and_tree('from')
604
 
        branch = wt.branch
605
 
        wt.commit('empty commit for nonsense', allow_pointless=True)
606
 
        url = self.get_readonly_url('from')
607
 
        self.run_bzr('branch', url, 'to')
608
 
        branch = Branch.open('to')
609
 
        self.assertEqual(1, len(branch.revision_history()))
610
 
        # the branch should be set in to to from
611
 
        self.assertEqual(url + '/', branch.get_parent())
612
 
 
613
 
    def test_log(self):
614
 
        self.build_tree(['branch/', 'branch/file'])
615
 
        self.capture('init branch')
616
 
        self.capture('add branch/file')
617
 
        self.capture('commit -m foo branch')
618
 
        url = self.get_readonly_url('branch/file')
619
 
        output = self.capture('log %s' % url)
620
 
        self.assertEqual(8, len(output.split('\n')))
621
 
        
622
 
    def test_check(self):
623
 
        self.build_tree(['branch/', 'branch/file'])
624
 
        self.capture('init branch')
625
 
        self.capture('add branch/file')
626
 
        self.capture('commit -m foo branch')
627
 
        url = self.get_readonly_url('branch/')
628
 
        self.run_bzr('check', url)
629
 
    
630
 
    def test_push(self):
631
 
        # create a source branch
632
 
        os.mkdir('my-branch')
633
 
        os.chdir('my-branch')
634
 
        self.run_bzr('init')
635
 
        file('hello', 'wt').write('foo')
636
 
        self.run_bzr('add', 'hello')
637
 
        self.run_bzr('commit', '-m', 'setup')
638
 
 
639
 
        # with an explicit target work
640
 
        self.run_bzr('push', self.get_url('output-branch'))
641
 
 
642
 
    
643
 
class HTTPTests(TestCaseWithWebserver, RemoteTests):
644
 
    """Test various commands against a HTTP server."""
645
 
    
646
 
    
647
 
class SFTPTestsAbsolute(TestCaseWithSFTPServer, RemoteTests):
648
 
    """Test various commands against a SFTP server using abs paths."""
649
 
 
650
 
    
651
 
class SFTPTestsAbsoluteSibling(TestCaseWithSFTPServer, RemoteTests):
652
 
    """Test various commands against a SFTP server using abs paths."""
653
 
 
654
 
    def setUp(self):
655
 
        super(SFTPTestsAbsoluteSibling, self).setUp()
656
 
        self._override_home = '/dev/noone/runs/tests/here'
657
 
 
658
 
    
659
 
class SFTPTestsRelative(TestCaseWithSFTPServer, RemoteTests):
660
 
    """Test various commands against a SFTP server using homedir rel paths."""
661
 
 
662
 
    def setUp(self):
663
 
        super(SFTPTestsRelative, self).setUp()
664
 
        self._get_remote_is_absolute = False