13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
18
"""Tests for the info command of bzr."""
24
23
from bzrlib import (
30
from bzrlib.osutils import format_date
31
from bzrlib.tests import TestSkipped
32
from bzrlib.tests.blackbox import ExternalBase
35
class TestInfo(ExternalBase):
34
from bzrlib.tests.matchers import ContainsNoVfsCalls
35
from bzrlib.transport import memory
38
class TestInfo(tests.TestCaseWithTransport):
41
super(TestInfo, self).setUp()
42
self._repo_strings = "2a"
37
44
def test_info_non_existing(self):
38
if sys.platform == "win32":
39
location = "C:/i/do/not/exist/"
41
location = "/i/do/not/exist/"
45
self.vfs_transport_factory = memory.MemoryServer
46
location = self.get_url()
42
47
out, err = self.run_bzr('info '+location, retcode=3)
43
48
self.assertEqual(out, '')
44
49
self.assertEqual(err, 'bzr: ERROR: Not a branch: "%s".\n' % location)
51
def test_info_empty_controldir(self):
52
self.make_bzrdir('ctrl')
53
out, err = self.run_bzr('info ctrl')
54
self.assertEquals(out,
55
'Empty control directory (format: 2a or pack-0.92)\n'
57
' control directory: ctrl\n')
58
self.assertEquals(err, '')
60
def test_info_dangling_branch_reference(self):
61
br = self.make_branch('target')
62
br.create_checkout('from', lightweight=True)
63
shutil.rmtree('target')
64
out, err = self.run_bzr('info from')
65
self.assertEquals(out,
66
'Dangling branch reference (format: 2a or pack-0.92)\n'
68
' control directory: from\n'
69
' checkout of branch: target\n')
70
self.assertEquals(err, '')
46
72
def test_info_standalone(self):
47
73
transport = self.get_transport()
49
75
# Create initial standalone branch
50
tree1 = self.make_branch_and_tree('standalone', 'weave')
76
tree1 = self.make_branch_and_tree('standalone', 'knit')
51
77
self.build_tree(['standalone/a'])
53
79
branch1 = tree1.branch
55
81
out, err = self.run_bzr('info standalone')
56
82
self.assertEqualDiff(
57
"""Standalone tree (format: weave)
83
"""Standalone tree (format: knit)
59
85
branch root: standalone
61
87
self.assertEqual('', err)
89
# Standalone branch - verbose mode
63
90
out, err = self.run_bzr('info standalone -v')
64
91
self.assertEqualDiff(
65
"""Standalone tree (format: weave)
67
branch root: standalone
70
control: All-in-one format 6
71
working tree: Working tree format 2
72
branch: Branch format 4
73
repository: Weave repository format 6
92
"""Standalone tree (format: knit)
94
branch root: standalone
97
control: Meta directory format 1
98
working tree: Working tree format 3
99
branch: Branch format 5
100
repository: Knit repository format 1
110
0 versioned subdirectories
118
self.assertEqual('', err)
120
# Standalone branch - really verbose mode
121
out, err = self.run_bzr('info standalone -vv')
122
self.assertEqualDiff(
123
"""Standalone tree (format: knit)
125
branch root: standalone
128
control: Meta directory format 1
129
working tree: Working tree format 3
130
branch: Branch format 5
131
repository: Knit repository format 1
75
133
In the working tree:
190
241
0 versioned subdirectories
196
246
first revision: %s
197
247
latest revision: %s
202
251
""" % (bound_tree._format.get_format_description(),
203
252
branch3._format.get_format_description(),
204
253
branch3.repository._format.get_format_description(),
205
254
datestring_first, datestring_first,
206
# poking at _revision_store isn't all that clean, but neither is
207
# having the ui test dependent on the exact overhead of a given store.
208
branch3.repository._revision_store.total_size(
209
branch3.repository.get_transaction())[1] / 1024,
211
256
self.assertEqual('', err)
213
258
# Checkout standalone (same as above, but does not have parent set)
214
branch4 = bzrlib.bzrdir.BzrDir.create_branch_convenience('checkout',
259
branch4 = controldir.ControlDir.create_branch_convenience('checkout',
215
260
format=knit1_format)
216
261
branch4.bind(branch1)
217
262
branch4.bzrdir.open_workingtree().update()
290
332
first revision: %s
291
333
latest revision: %s
296
""" % (datestring_first, datestring_first,), out)
337
""" % (format_description, datestring_first, datestring_first,), out)
297
338
self.assertEqual('', err)
299
340
# Update initial standalone branch
300
341
self.build_tree(['standalone/b'])
302
343
tree1.commit('commit two')
303
rev = branch1.repository.get_revision(branch1.revision_history()[-1])
304
datestring_last = format_date(rev.timestamp, rev.timezone)
344
rev = branch1.repository.get_revision(branch1.last_revision())
345
datestring_last = osutils.format_date(rev.timestamp, rev.timezone)
306
347
# Out of date branched standalone branch will not be detected
307
348
out, err = self.run_bzr('info -v branch')
308
349
self.assertEqualDiff(
309
"""Standalone tree (format: weave)
350
"""Standalone tree (format: knit)
311
352
branch root: branch
425
457
first revision: %s
426
458
latest revision: %s
431
462
""" % (branch4.repository._format.get_format_description(),
432
463
datestring_first, datestring_first,
433
# poking at _revision_store isn't all that clean, but neither is
434
# having the ui test dependent on the exact overhead of a given store.
435
branch4.repository._revision_store.total_size(
436
branch4.repository.get_transaction())[1] / 1024,
438
465
self.assertEqual('', err)
440
467
# Out of date lightweight checkout
441
468
out, err = self.run_bzr('info lightcheckout --verbose')
442
469
self.assertEqualDiff(
443
"""Lightweight checkout (format: dirstate or dirstate-tags)
470
"""Lightweight checkout (format: %s)
445
472
light checkout root: lightcheckout
446
473
checkout of branch: standalone
449
476
control: Meta directory format 1
450
working tree: Working tree format 4
451
branch: Branch format 4
452
repository: Weave repository format 6
477
working tree: Working tree format 3
478
branch: Branch format 5
479
repository: Knit repository format 1
454
481
Working tree is out of date: missing 1 revision.
607
627
first revision: %s
608
628
latest revision: %s
613
""" % (format.get_branch_format().get_format_description(),
632
""" % (self._repo_strings, format.get_branch_format().get_format_description(),
614
633
format.repository_format.get_format_description(),
615
634
datestring_first, datestring_first,
616
# poking at _revision_store isn't all that clean, but neither is
617
# having the ui test dependent on the exact overhead of a given store.
618
repo._revision_store.total_size(repo.get_transaction())[1] / 1024,
620
636
self.assertEqual('', err)
622
638
# Out of date checkout
623
639
out, err = self.run_bzr('info -v tree/checkout')
624
640
self.assertEqualDiff(
625
"""Checkout (format: dirstate)
641
"""Checkout (format: unnamed)
627
643
checkout root: tree/checkout
628
644
checkout of branch: repo/branch
631
647
control: Meta directory format 1
632
working tree: Working tree format 4
648
working tree: Working tree format 6
691
704
first revision: %s
692
705
latest revision: %s
697
709
""" % (format.get_branch_format().get_format_description(),
698
710
format.repository_format.get_format_description(),
699
711
datestring_first, datestring_first,
700
# poking at _revision_store isn't all that clean, but neither is
701
# having the ui test dependent on the exact overhead of a given store.
702
repo._revision_store.total_size(repo.get_transaction())[1] / 1024,
704
713
self.assertEqual('', err)
705
714
tree3.commit('commit two')
707
716
# Out of date lightweight checkout
708
rev = repo.get_revision(branch1.revision_history()[-1])
709
datestring_last = format_date(rev.timestamp, rev.timezone)
717
rev = repo.get_revision(branch1.last_revision())
718
datestring_last = osutils.format_date(rev.timestamp, rev.timezone)
710
719
out, err = self.run_bzr('info tree/lightcheckout --verbose')
711
720
self.assertEqualDiff(
712
"""Lightweight checkout (format: dirstate or dirstate-tags)
721
"""Lightweight checkout (format: %s)
714
723
light checkout root: tree/lightcheckout
715
724
checkout of branch: repo/branch
1092
1064
Branch history:
1099
1069
""" % (format.get_branch_format().get_format_description(),
1100
1070
format.repository_format.get_format_description(),
1102
1072
self.assertEqual('', err)
1104
def assertCheckoutStatusOutput(self,
1074
def test_info_repository_hook(self):
1075
format = bzrdir.format_registry.make_bzrdir('knit')
1076
def repo_info(repo, stats, outf):
1077
outf.write("more info\n")
1078
info.hooks.install_named_hook('repository', repo_info, None)
1079
# Create shared repository with working trees
1080
repo = self.make_repository('repo', shared=True, format=format)
1081
out, err = self.run_bzr('info -v repo')
1082
self.assertEqualDiff(
1083
"""Shared repository with trees (format: dirstate or dirstate-tags or knit)
1085
shared repository: repo
1088
control: Meta directory format 1
1091
Create working tree for new branches inside the repository.
1096
""" % (format.repository_format.get_format_description(),
1098
self.assertEqual('', err)
1100
def test_info_unshared_repository_with_colocated_branches(self):
1101
format = bzrdir.format_registry.make_bzrdir('development-colo')
1102
transport = self.get_transport()
1104
# Create unshared repository
1105
repo = self.make_repository('repo', shared=False, format=format)
1106
repo.set_make_working_trees(True)
1107
repo.bzrdir.create_branch(name='foo')
1108
out, err = self.run_bzr('info repo')
1109
self.assertEqualDiff(
1110
"""Unshared repository with trees and colocated branches (format: development-colo)
1114
self.assertEqual('', err)
1116
def assertCheckoutStatusOutput(self,
1105
1117
command_string, lco_tree, shared_repo=None,
1106
1118
repo_branch=None,
1107
1119
tree_locked=False,
1126
1138
:param tree_locked: If true, expect the tree to be locked.
1127
1139
:param branch_locked: If true, expect the branch to be locked.
1128
1140
:param repo_locked: If true, expect the repository to be locked.
1129
:param verbose: If true, expect verbose output
1141
Note that the lco_tree.branch.repository is inspected, and if is not
1142
actually locked then this parameter is overridden. This is because
1143
pack repositories do not have any public API for obtaining an
1144
exclusive repository wide lock.
1145
:param verbose: verbosity level: 2 or higher to show committers
1131
1147
def friendly_location(url):
1132
1148
path = urlutils.unescape_for_display(url, 'ascii')
1134
return osutils.relpath(os.getcwd(), path)
1150
return osutils.relpath(osutils.getcwd(), path)
1135
1151
except errors.PathNotChild:
1138
if tree_locked and sys.platform == 'win32':
1139
# We expect this to fail because of locking errors. (A write-locked
1140
# file cannot be read-locked in the same process).
1155
# We expect this to fail because of locking errors.
1156
# (A write-locked file cannot be read-locked
1157
# in the different process -- either on win32 or on linux).
1141
1158
# This should be removed when the locking errors are fixed.
1142
args = command_string.split(' ')
1143
self.run_bzr_error([], 'info', *args)
1159
self.expectFailure('OS locks are exclusive '
1160
'for different processes (Bug #174055)',
1161
self.run_bzr_subprocess,
1162
'info ' + command_string)
1145
1163
out, err = self.run_bzr('info %s' % command_string)
1146
1164
description = {
1147
1165
(True, True): 'Lightweight checkout',
1239
1258
transport = self.get_transport()
1240
1259
# Create shared repository with a branch
1241
1260
repo = self.make_repository('repo', shared=True,
1242
format=bzrlib.bzrdir.BzrDirMetaFormat1())
1261
format=bzrdir.BzrDirMetaFormat1())
1243
1262
repo.set_make_working_trees(False)
1244
1263
repo.bzrdir.root_transport.mkdir('branch')
1245
repo_branch = repo.bzrdir.create_branch_convenience('repo/branch',
1246
format=bzrlib.bzrdir.BzrDirMetaFormat1())
1264
repo_branch = controldir.ControlDir.create_branch_convenience(
1265
'repo/branch', format=bzrdir.BzrDirMetaFormat1())
1247
1266
# Do a heavy checkout
1248
1267
transport.mkdir('tree')
1249
1268
transport.mkdir('tree/checkout')
1250
co_branch = bzrlib.bzrdir.BzrDir.create_branch_convenience('tree/checkout',
1251
format=bzrlib.bzrdir.BzrDirMetaFormat1())
1269
co_branch = controldir.ControlDir.create_branch_convenience(
1270
'tree/checkout', format=bzrdir.BzrDirMetaFormat1())
1252
1271
co_branch.bind(repo_branch)
1253
1272
# Do a light checkout of the heavy one
1254
1273
transport.mkdir('tree/lightcheckout')
1255
lco_dir = bzrlib.bzrdir.BzrDirMetaFormat1().initialize('tree/lightcheckout')
1256
bzrlib.branch.BranchReferenceFormat().initialize(lco_dir, co_branch)
1274
lco_dir = bzrdir.BzrDirMetaFormat1().initialize('tree/lightcheckout')
1275
lco_dir.set_branch_reference(co_branch)
1257
1276
lco_dir.create_workingtree()
1258
1277
lco_tree = lco_dir.open_workingtree()
1347
1366
self.knownFailure('Win32 cannot run "bzr info"'
1348
1367
' when the tree is locked.')
1350
def test_info_locking_oslocks(self):
1351
if sys.platform == "win32":
1352
raise TestSkipped("don't use oslocks on win32 in unix manner")
1354
tree = self.make_branch_and_tree('branch',
1355
format=bzrlib.bzrdir.BzrDirFormat6())
1357
# Test all permutations of locking the working tree, branch and repository
1358
# XXX: Well not yet, as we can't query oslocks yet. Currently, it's
1359
# implemented by raising NotImplementedError and get_physical_lock_status()
1360
# always returns false. This makes bzr info hide the lock status. (Olaf)
1364
out, err = self.run_bzr('info -v branch')
1365
self.assertEqualDiff(
1366
"""Standalone tree (format: weave)
1371
control: All-in-one format 6
1372
working tree: Working tree format 2
1373
branch: Branch format 4
1376
In the working tree:
1384
0 versioned subdirectories
1393
""" % ('branch', tree.branch.repository._format.get_format_description(),
1395
self.assertEqual('', err)
1398
out, err = self.run_bzr('info -v branch')
1399
self.assertEqualDiff(
1400
"""Standalone tree (format: weave)
1405
control: All-in-one format 6
1406
working tree: Working tree format 2
1407
branch: Branch format 4
1410
In the working tree:
1418
0 versioned subdirectories
1427
""" % ('branch', tree.branch.repository._format.get_format_description(),
1429
self.assertEqual('', err)
1369
def test_info_stacked(self):
1370
# We have a mainline
1371
trunk_tree = self.make_branch_and_tree('mainline',
1373
trunk_tree.commit('mainline')
1374
# and a branch from it which is stacked
1375
new_dir = trunk_tree.bzrdir.sprout('newbranch', stacked=True)
1376
out, err = self.run_bzr('info newbranch')
1378
"""Standalone tree (format: 1.6)
1380
branch root: newbranch
1383
parent branch: mainline
1384
stacked on: mainline
1386
self.assertEqual("", err)
1388
def test_info_revinfo_optional(self):
1389
tree = self.make_branch_and_tree('.')
1390
def last_revision_info(self):
1391
raise errors.UnsupportedOperation(last_revision_info, self)
1393
branch.Branch, "last_revision_info", last_revision_info)
1394
out, err = self.run_bzr('info -v .')
1396
"""Standalone tree (format: 2a)
1401
control: Meta directory format 1
1402
working tree: Working tree format 6
1403
branch: Branch format 7
1404
repository: Repository format 2a - rich roots, group compression and chk inventories
1406
In the working tree:
1414
0 versioned subdirectories
1416
self.assertEqual("", err)
1418
def test_info_shows_colocated_branches(self):
1419
bzrdir = self.make_branch('.', format='development-colo').bzrdir
1420
bzrdir.create_branch(name="colo1")
1421
bzrdir.create_branch(name="colo2")
1422
bzrdir.create_branch(name="colo3")
1423
out, err = self.run_bzr('info -v .')
1424
self.assertEqualDiff(
1425
"""Standalone branch (format: development-colo)
1430
control: Meta directory format 1 with support for colocated branches
1431
branch: Branch format 7
1432
repository: Repository format 2a - rich roots, group compression and chk inventories
1443
self.assertEqual("", err)
1446
class TestSmartServerInfo(tests.TestCaseWithTransport):
1448
def test_simple_branch_info(self):
1449
self.setup_smart_server_with_call_log()
1450
t = self.make_branch_and_tree('branch')
1451
self.build_tree_contents([('branch/foo', 'thecontents')])
1454
self.reset_smart_call_log()
1455
out, err = self.run_bzr(['info', self.get_url('branch')])
1456
# This figure represent the amount of work to perform this use case. It
1457
# is entirely ok to reduce this number if a test fails due to rpc_count
1458
# being too low. If rpc_count increases, more network roundtrips have
1459
# become necessary for this use case. Please do not adjust this number
1460
# upwards without agreement from bzr's network support maintainers.
1461
self.assertLength(12, self.hpss_calls)
1462
self.assertLength(1, self.hpss_connections)
1463
self.assertThat(self.hpss_calls, ContainsNoVfsCalls)
1465
def test_verbose_branch_info(self):
1466
self.setup_smart_server_with_call_log()
1467
t = self.make_branch_and_tree('branch')
1468
self.build_tree_contents([('branch/foo', 'thecontents')])
1471
self.reset_smart_call_log()
1472
out, err = self.run_bzr(['info', '-v', self.get_url('branch')])
1473
# This figure represent the amount of work to perform this use case. It
1474
# is entirely ok to reduce this number if a test fails due to rpc_count
1475
# being too low. If rpc_count increases, more network roundtrips have
1476
# become necessary for this use case. Please do not adjust this number
1477
# upwards without agreement from bzr's network support maintainers.
1478
self.assertLength(16, self.hpss_calls)
1479
self.assertLength(1, self.hpss_connections)
1480
self.assertThat(self.hpss_calls, ContainsNoVfsCalls)