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
self.assertEqual(err, 'bzr: ERROR: Not a branch: %s\n' % location)
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_empty_controldir_verbose(self):
61
self.make_bzrdir('ctrl')
62
out, err = self.run_bzr('info -v ctrl')
63
self.assertEqualDiff(out,
64
'Empty control directory (format: 2a or pack-0.92)\n'
66
' control directory: ctrl\n\n'
68
' control: Meta directory format 1\n\n'
69
'Control directory:\n'
71
self.assertEquals(err, '')
73
def test_info_dangling_branch_reference(self):
74
br = self.make_branch('target')
75
br.create_checkout('from', lightweight=True)
76
shutil.rmtree('target')
77
out, err = self.run_bzr('info from')
78
self.assertEquals(out,
79
'Dangling branch reference (format: 2a or pack-0.92)\n'
81
' control directory: from\n'
82
' checkout of branch: target\n')
83
self.assertEquals(err, '')
46
85
def test_info_standalone(self):
47
86
transport = self.get_transport()
49
88
# Create initial standalone branch
50
tree1 = self.make_branch_and_tree('standalone', 'weave')
89
tree1 = self.make_branch_and_tree('standalone', 'knit')
51
90
self.build_tree(['standalone/a'])
53
92
branch1 = tree1.branch
55
94
out, err = self.run_bzr('info standalone')
56
95
self.assertEqualDiff(
57
"""Standalone tree (format: weave)
96
"""Standalone tree (format: knit)
59
98
branch root: standalone
61
100
self.assertEqual('', err)
102
# Standalone branch - verbose mode
63
103
out, err = self.run_bzr('info standalone -v')
64
104
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
105
"""Standalone tree (format: knit)
107
branch root: standalone
110
control: Meta directory format 1
111
working tree: Working tree format 3
112
branch: Branch format 5
113
repository: Knit repository format 1
126
0 versioned subdirectories
134
self.assertEqual('', err)
136
# Standalone branch - really verbose mode
137
out, err = self.run_bzr('info standalone -vv')
138
self.assertEqualDiff(
139
"""Standalone tree (format: knit)
141
branch root: standalone
144
control: Meta directory format 1
145
working tree: Working tree format 3
146
branch: Branch format 5
147
repository: Knit repository format 1
75
152
In the working tree:
144
222
first revision: %s
145
223
latest revision: %s
150
227
""" % (datestring_first, datestring_first,
151
# poking at _revision_store isn't all that clean, but neither is
152
# having the ui test dependent on the exact overhead of a given store.
153
branch2.repository._revision_store.total_size(
154
branch2.repository.get_transaction())[1] / 1024,
156
229
self.assertEqual('', err)
158
231
# Branch and bind to standalone, needs upgrade to metadir
159
232
# (creates backup as unknown)
160
233
branch1.bzrdir.sprout('bound')
161
knit1_format = bzrdir.format_registry.make_bzrdir('knit')
162
bzrlib.upgrade.upgrade('bound', knit1_format)
163
branch3 = bzrlib.bzrdir.BzrDir.open('bound').open_branch()
234
knit1_format = controldir.format_registry.make_bzrdir('knit')
235
upgrade.upgrade('bound', knit1_format)
236
branch3 = controldir.ControlDir.open('bound').open_branch()
164
237
branch3.bind(branch1)
165
238
bound_tree = branch3.bzrdir.open_workingtree()
166
239
out, err = self.run_bzr('info -v bound')
182
258
In the working tree:
190
266
0 versioned subdirectories
196
271
first revision: %s
197
272
latest revision: %s
202
276
""" % (bound_tree._format.get_format_description(),
203
277
branch3._format.get_format_description(),
204
278
branch3.repository._format.get_format_description(),
205
279
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
281
self.assertEqual('', err)
213
283
# Checkout standalone (same as above, but does not have parent set)
214
branch4 = bzrlib.bzrdir.BzrDir.create_branch_convenience('checkout',
284
branch4 = controldir.ControlDir.create_branch_convenience('checkout',
215
285
format=knit1_format)
216
286
branch4.bind(branch1)
217
287
branch4.bzrdir.open_workingtree().update()
290
363
first revision: %s
291
364
latest revision: %s
296
""" % (datestring_first, datestring_first,), out)
368
""" % (format_description, datestring_first, datestring_first,), out)
297
369
self.assertEqual('', err)
299
371
# Update initial standalone branch
300
372
self.build_tree(['standalone/b'])
302
374
tree1.commit('commit two')
303
rev = branch1.repository.get_revision(branch1.revision_history()[-1])
304
datestring_last = format_date(rev.timestamp, rev.timezone)
375
rev = branch1.repository.get_revision(branch1.last_revision())
376
datestring_last = osutils.format_date(rev.timestamp, rev.timezone)
306
378
# Out of date branched standalone branch will not be detected
307
379
out, err = self.run_bzr('info -v branch')
308
380
self.assertEqualDiff(
309
"""Standalone tree (format: weave)
381
"""Standalone tree (format: knit)
311
383
branch root: branch
425
497
first revision: %s
426
498
latest revision: %s
431
502
""" % (branch4.repository._format.get_format_description(),
432
503
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
505
self.assertEqual('', err)
440
507
# Out of date lightweight checkout
441
508
out, err = self.run_bzr('info lightcheckout --verbose')
442
509
self.assertEqualDiff(
443
"""Lightweight checkout (format: dirstate or dirstate-tags)
510
"""Lightweight checkout (format: %s)
445
512
light checkout root: lightcheckout
446
513
checkout of branch: standalone
449
516
control: Meta directory format 1
450
working tree: Working tree format 4
451
branch: Branch format 4
452
repository: Weave repository format 6
517
working tree: Working tree format 3
518
branch: Branch format 5
519
repository: Knit repository format 1
454
524
Working tree is out of date: missing 1 revision.
607
682
first revision: %s
608
683
latest revision: %s
613
""" % (format.get_branch_format().get_format_description(),
687
""" % (self._repo_strings, format.get_branch_format().get_format_description(),
614
688
format.repository_format.get_format_description(),
615
689
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
691
self.assertEqual('', err)
622
693
# Out of date checkout
623
694
out, err = self.run_bzr('info -v tree/checkout')
624
695
self.assertEqualDiff(
625
"""Checkout (format: dirstate)
696
"""Checkout (format: unnamed)
627
698
checkout root: tree/checkout
628
699
checkout of branch: repo/branch
631
702
control: Meta directory format 1
632
working tree: Working tree format 4
703
working tree: Working tree format 6
636
710
Branch is out of date: missing 1 revision.
638
712
In the working tree:
691
765
first revision: %s
692
766
latest revision: %s
697
770
""" % (format.get_branch_format().get_format_description(),
698
771
format.repository_format.get_format_description(),
699
772
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
774
self.assertEqual('', err)
705
775
tree3.commit('commit two')
707
777
# Out of date lightweight checkout
708
rev = repo.get_revision(branch1.revision_history()[-1])
709
datestring_last = format_date(rev.timestamp, rev.timezone)
778
rev = repo.get_revision(branch1.last_revision())
779
datestring_last = osutils.format_date(rev.timestamp, rev.timezone)
710
780
out, err = self.run_bzr('info tree/lightcheckout --verbose')
711
781
self.assertEqualDiff(
712
"""Lightweight checkout (format: dirstate or dirstate-tags)
782
"""Lightweight checkout (format: %s)
714
784
light checkout root: tree/lightcheckout
715
785
checkout of branch: repo/branch
1092
1158
Branch history:
1099
1163
""" % (format.get_branch_format().get_format_description(),
1100
1164
format.repository_format.get_format_description(),
1102
1166
self.assertEqual('', err)
1104
def assertCheckoutStatusOutput(self,
1168
def test_info_repository_hook(self):
1169
format = controldir.format_registry.make_bzrdir('knit')
1170
def repo_info(repo, stats, outf):
1171
outf.write("more info\n")
1172
info.hooks.install_named_hook('repository', repo_info, None)
1173
# Create shared repository with working trees
1174
repo = self.make_repository('repo', shared=True, format=format)
1175
out, err = self.run_bzr('info -v repo')
1176
self.assertEqualDiff(
1177
"""Shared repository with trees (format: dirstate or dirstate-tags or knit)
1179
shared repository: repo
1182
control: Meta directory format 1
1188
Create working tree for new branches inside the repository.
1193
""" % (format.repository_format.get_format_description(),
1195
self.assertEqual('', err)
1197
def test_info_unshared_repository_with_colocated_branches(self):
1198
format = controldir.format_registry.make_bzrdir('development-colo')
1199
transport = self.get_transport()
1201
# Create unshared repository
1202
repo = self.make_repository('repo', shared=False, format=format)
1203
repo.set_make_working_trees(True)
1204
repo.bzrdir.create_branch(name='foo')
1205
out, err = self.run_bzr('info repo')
1206
self.assertEqualDiff(
1207
"""Unshared repository with trees and colocated branches (format: development-colo)
1211
self.assertEqual('', err)
1213
def assertCheckoutStatusOutput(self,
1105
1214
command_string, lco_tree, shared_repo=None,
1106
1215
repo_branch=None,
1107
1216
tree_locked=False,
1126
1235
:param tree_locked: If true, expect the tree to be locked.
1127
1236
:param branch_locked: If true, expect the branch to be locked.
1128
1237
:param repo_locked: If true, expect the repository to be locked.
1129
:param verbose: If true, expect verbose output
1238
Note that the lco_tree.branch.repository is inspected, and if is not
1239
actually locked then this parameter is overridden. This is because
1240
pack repositories do not have any public API for obtaining an
1241
exclusive repository wide lock.
1242
:param verbose: verbosity level: 2 or higher to show committers
1131
1244
def friendly_location(url):
1132
1245
path = urlutils.unescape_for_display(url, 'ascii')
1134
return osutils.relpath(os.getcwd(), path)
1247
return osutils.relpath(osutils.getcwd(), path)
1135
1248
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).
1252
# We expect this to fail because of locking errors.
1253
# (A write-locked file cannot be read-locked
1254
# in the different process -- either on win32 or on linux).
1141
1255
# This should be removed when the locking errors are fixed.
1142
args = command_string.split(' ')
1143
self.run_bzr_error([], 'info', *args)
1256
self.expectFailure('OS locks are exclusive '
1257
'for different processes (Bug #174055)',
1258
self.run_bzr_subprocess,
1259
'info ' + command_string)
1145
1260
out, err = self.run_bzr('info %s' % command_string)
1146
1261
description = {
1147
1262
(True, True): 'Lightweight checkout',
1239
1358
transport = self.get_transport()
1240
1359
# Create shared repository with a branch
1241
1360
repo = self.make_repository('repo', shared=True,
1242
format=bzrlib.bzrdir.BzrDirMetaFormat1())
1361
format=bzrdir.BzrDirMetaFormat1())
1243
1362
repo.set_make_working_trees(False)
1244
1363
repo.bzrdir.root_transport.mkdir('branch')
1245
repo_branch = repo.bzrdir.create_branch_convenience('repo/branch',
1246
format=bzrlib.bzrdir.BzrDirMetaFormat1())
1364
repo_branch = controldir.ControlDir.create_branch_convenience(
1365
'repo/branch', format=bzrdir.BzrDirMetaFormat1())
1247
1366
# Do a heavy checkout
1248
1367
transport.mkdir('tree')
1249
1368
transport.mkdir('tree/checkout')
1250
co_branch = bzrlib.bzrdir.BzrDir.create_branch_convenience('tree/checkout',
1251
format=bzrlib.bzrdir.BzrDirMetaFormat1())
1369
co_branch = controldir.ControlDir.create_branch_convenience(
1370
'tree/checkout', format=bzrdir.BzrDirMetaFormat1())
1252
1371
co_branch.bind(repo_branch)
1253
1372
# Do a light checkout of the heavy one
1254
1373
transport.mkdir('tree/lightcheckout')
1255
lco_dir = bzrlib.bzrdir.BzrDirMetaFormat1().initialize('tree/lightcheckout')
1256
bzrlib.branch.BranchReferenceFormat().initialize(lco_dir, co_branch)
1374
lco_dir = bzrdir.BzrDirMetaFormat1().initialize('tree/lightcheckout')
1375
lco_dir.set_branch_reference(co_branch)
1257
1376
lco_dir.create_workingtree()
1258
1377
lco_tree = lco_dir.open_workingtree()
1347
1466
self.knownFailure('Win32 cannot run "bzr info"'
1348
1467
' 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)
1469
def test_info_stacked(self):
1470
# We have a mainline
1471
trunk_tree = self.make_branch_and_tree('mainline',
1473
trunk_tree.commit('mainline')
1474
# and a branch from it which is stacked
1475
new_dir = trunk_tree.bzrdir.sprout('newbranch', stacked=True)
1476
out, err = self.run_bzr('info newbranch')
1478
"""Standalone tree (format: 1.6)
1480
branch root: newbranch
1483
parent branch: mainline
1484
stacked on: mainline
1486
self.assertEqual("", err)
1488
def test_info_revinfo_optional(self):
1489
tree = self.make_branch_and_tree('.')
1490
def last_revision_info(self):
1491
raise errors.UnsupportedOperation(last_revision_info, self)
1493
branch.Branch, "last_revision_info", last_revision_info)
1494
out, err = self.run_bzr('info -v .')
1496
"""Standalone tree (format: 2a)
1501
control: Meta directory format 1
1502
working tree: Working tree format 6
1503
branch: Branch format 7
1504
repository: Repository format 2a - rich roots, group compression and chk inventories
1509
In the working tree:
1517
0 versioned subdirectories
1519
self.assertEqual("", err)
1521
def test_info_shows_colocated_branches(self):
1522
bzrdir = self.make_branch('.', format='development-colo').bzrdir
1523
bzrdir.create_branch(name="colo1")
1524
bzrdir.create_branch(name="colo2")
1525
bzrdir.create_branch(name="colo3")
1526
out, err = self.run_bzr('info -v .')
1527
self.assertEqualDiff(
1528
"""Standalone branch (format: development-colo)
1533
control: Meta directory format 1 with support for colocated branches
1534
branch: Branch format 7
1535
repository: Repository format 2a - rich roots, group compression and chk inventories
1546
self.assertEqual("", err)
1549
class TestSmartServerInfo(tests.TestCaseWithTransport):
1551
def test_simple_branch_info(self):
1552
self.setup_smart_server_with_call_log()
1553
t = self.make_branch_and_tree('branch')
1554
self.build_tree_contents([('branch/foo', 'thecontents')])
1557
self.reset_smart_call_log()
1558
out, err = self.run_bzr(['info', self.get_url('branch')])
1559
# This figure represent the amount of work to perform this use case. It
1560
# is entirely ok to reduce this number if a test fails due to rpc_count
1561
# being too low. If rpc_count increases, more network roundtrips have
1562
# become necessary for this use case. Please do not adjust this number
1563
# upwards without agreement from bzr's network support maintainers.
1564
self.assertLength(10, self.hpss_calls)
1565
self.assertLength(1, self.hpss_connections)
1566
self.assertThat(self.hpss_calls, ContainsNoVfsCalls)
1568
def test_verbose_branch_info(self):
1569
self.setup_smart_server_with_call_log()
1570
t = self.make_branch_and_tree('branch')
1571
self.build_tree_contents([('branch/foo', 'thecontents')])
1574
self.reset_smart_call_log()
1575
out, err = self.run_bzr(['info', '-v', self.get_url('branch')])
1576
# This figure represent the amount of work to perform this use case. It
1577
# is entirely ok to reduce this number if a test fails due to rpc_count
1578
# being too low. If rpc_count increases, more network roundtrips have
1579
# become necessary for this use case. Please do not adjust this number
1580
# upwards without agreement from bzr's network support maintainers.
1581
self.assertLength(14, self.hpss_calls)
1582
self.assertLength(1, self.hpss_connections)
1583
self.assertThat(self.hpss_calls, ContainsNoVfsCalls)