1
# Copyright (C) 2006, 2007, 2008 Canonical Ltd
1
# Copyright (C) 2006, 2007 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
18
"""Tests for the info command of bzr."""
22
24
from bzrlib import (
32
from bzrlib.transport import memory
34
class TestInfo(tests.TestCaseWithTransport):
37
super(TestInfo, self).setUp()
38
self._repo_strings = "2a"
31
from bzrlib.osutils import format_date
32
from bzrlib.tests import TestSkipped
33
from bzrlib.tests.blackbox import ExternalBase
36
class TestInfo(ExternalBase):
40
38
def test_info_non_existing(self):
41
self.vfs_transport_factory = memory.MemoryServer
42
location = self.get_url()
39
if sys.platform == "win32":
40
location = "C:/i/do/not/exist/"
42
location = "/i/do/not/exist/"
43
43
out, err = self.run_bzr('info '+location, retcode=3)
44
44
self.assertEqual(out, '')
45
45
self.assertEqual(err, 'bzr: ERROR: Not a branch: "%s".\n' % location)
62
62
self.assertEqual('', err)
64
# Standalone branch - verbose mode
65
64
out, err = self.run_bzr('info standalone -v')
66
65
self.assertEqualDiff(
67
66
"""Standalone tree (format: weave)
93
self.assertEqual('', err)
95
# Standalone branch - really verbose mode
96
out, err = self.run_bzr('info standalone -vv')
98
"""Standalone tree (format: weave)
100
branch root: standalone
103
control: All-in-one format 6
104
working tree: Working tree format 2
105
branch: Branch format 4
106
repository: Weave repository format 6
116
0 versioned subdirectories
125
94
self.assertEqual('', err)
126
95
tree1.commit('commit one')
127
96
rev = branch1.repository.get_revision(branch1.revision_history()[0])
128
datestring_first = osutils.format_date(rev.timestamp, rev.timezone)
97
datestring_first = format_date(rev.timestamp, rev.timezone)
130
99
# Branch standalone with push location
131
100
branch2 = branch1.bzrdir.sprout('branch').open_branch()
175
145
first revision: %s
176
146
latest revision: %s
180
151
""" % (datestring_first, datestring_first,
152
# poking at _revision_store isn't all that clean, but neither is
153
# having the ui test dependent on the exact overhead of a given store.
154
branch2.repository._revision_store.total_size(
155
branch2.repository.get_transaction())[1] / 1024,
182
157
self.assertEqual('', err)
185
160
# (creates backup as unknown)
186
161
branch1.bzrdir.sprout('bound')
187
162
knit1_format = bzrdir.format_registry.make_bzrdir('knit')
188
upgrade.upgrade('bound', knit1_format)
189
branch3 = bzrdir.BzrDir.open('bound').open_branch()
163
bzrlib.upgrade.upgrade('bound', knit1_format)
164
branch3 = bzrlib.bzrdir.BzrDir.open('bound').open_branch()
190
165
branch3.bind(branch1)
191
166
bound_tree = branch3.bzrdir.open_workingtree()
192
167
out, err = self.run_bzr('info -v bound')
221
197
first revision: %s
222
198
latest revision: %s
226
203
""" % (bound_tree._format.get_format_description(),
227
204
branch3._format.get_format_description(),
228
205
branch3.repository._format.get_format_description(),
229
206
datestring_first, datestring_first,
207
# poking at _revision_store isn't all that clean, but neither is
208
# having the ui test dependent on the exact overhead of a given store.
209
branch3.repository._revision_store.total_size(
210
branch3.repository.get_transaction())[1] / 1024,
231
212
self.assertEqual('', err)
233
214
# Checkout standalone (same as above, but does not have parent set)
234
branch4 = bzrdir.BzrDir.create_branch_convenience('checkout',
215
branch4 = bzrlib.bzrdir.BzrDir.create_branch_convenience('checkout',
235
216
format=knit1_format)
236
217
branch4.bind(branch1)
237
218
branch4.bzrdir.open_workingtree().update()
264
246
first revision: %s
265
247
latest revision: %s
269
252
""" % (branch4.repository._format.get_format_description(),
270
253
datestring_first, datestring_first,
254
# poking at _revision_store isn't all that clean, but neither is
255
# having the ui test dependent on the exact overhead of a given store.
256
branch4.repository._revision_store.total_size(
257
branch4.repository.get_transaction())[1] / 1024,
272
259
self.assertEqual('', err)
276
263
branch5 = tree5.branch
277
264
out, err = self.run_bzr('info -v lightcheckout')
278
265
self.assertEqualDiff(
279
"""Lightweight checkout (format: %s)
266
"""Lightweight checkout (format: dirstate or dirstate-tags)
281
268
light checkout root: lightcheckout
282
269
checkout of branch: standalone
285
272
control: Meta directory format 1
286
working tree: Working tree format 6
273
working tree: Working tree format 4
287
274
branch: Branch format 4
288
275
repository: Weave repository format 6
303
291
first revision: %s
304
292
latest revision: %s
308
""" % (self._repo_strings, datestring_first, datestring_first,), out)
297
""" % (datestring_first, datestring_first,), out)
309
298
self.assertEqual('', err)
311
300
# Update initial standalone branch
314
303
tree1.commit('commit two')
315
304
rev = branch1.repository.get_revision(branch1.revision_history()[-1])
316
datestring_last = osutils.format_date(rev.timestamp, rev.timezone)
305
datestring_last = format_date(rev.timestamp, rev.timezone)
318
307
# Out of date branched standalone branch will not be detected
319
308
out, err = self.run_bzr('info -v branch')
389
381
first revision: %s
390
382
latest revision: %s
394
387
""" % (branch3.repository._format.get_format_description(),
395
388
datestring_first, datestring_first,
389
# poking at _revision_store isn't all that clean, but neither is
390
# having the ui test dependent on the exact overhead of a given store.
391
branch3.repository._revision_store.total_size(
392
branch3.repository.get_transaction())[1] / 1024,
397
394
self.assertEqual('', err)
428
426
first revision: %s
429
427
latest revision: %s
433
432
""" % (branch4.repository._format.get_format_description(),
434
433
datestring_first, datestring_first,
434
# poking at _revision_store isn't all that clean, but neither is
435
# having the ui test dependent on the exact overhead of a given store.
436
branch4.repository._revision_store.total_size(
437
branch4.repository.get_transaction())[1] / 1024,
436
439
self.assertEqual('', err)
438
441
# Out of date lightweight checkout
439
442
out, err = self.run_bzr('info lightcheckout --verbose')
440
443
self.assertEqualDiff(
441
"""Lightweight checkout (format: %s)
444
"""Lightweight checkout (format: dirstate or dirstate-tags)
443
446
light checkout root: lightcheckout
444
447
checkout of branch: standalone
447
450
control: Meta directory format 1
448
working tree: Working tree format 6
451
working tree: Working tree format 4
449
452
branch: Branch format 4
450
453
repository: Weave repository format 6
467
471
first revision: %s
468
472
latest revision: %s
472
""" % (self._repo_strings, datestring_first, datestring_last,), out)
477
""" % (datestring_first, datestring_last,), out)
473
478
self.assertEqual('', err)
475
480
def test_info_standalone_no_tree(self):
496
""" % (info.describe_format(repo.bzrdir, repo, branch, None),
497
format.get_branch_format().get_format_description(),
503
""" % (format.get_branch_format().get_format_description(),
498
504
format.repository_format.get_format_description(),
500
506
self.assertEqual('', err)
551
560
# Create lightweight checkout
552
561
transport.mkdir('tree')
553
562
transport.mkdir('tree/lightcheckout')
554
tree2 = branch1.create_checkout('tree/lightcheckout',
563
tree2 = branch1.create_checkout('tree/lightcheckout',
555
564
lightweight=True)
556
565
branch2 = tree2.branch
557
566
self.assertCheckoutStatusOutput('-v tree/lightcheckout', tree2,
568
577
tree2.commit('commit one')
569
578
rev = repo.get_revision(branch2.revision_history()[0])
570
datestring_first = osutils.format_date(rev.timestamp, rev.timezone)
579
datestring_first = format_date(rev.timestamp, rev.timezone)
571
580
out, err = self.run_bzr('info tree/lightcheckout --verbose')
572
581
self.assertEqualDiff(
573
"""Lightweight checkout (format: %s)
582
"""Lightweight checkout (format: dirstate or dirstate-tags)
575
584
light checkout root: tree/lightcheckout
576
585
checkout of branch: repo/branch
598
608
first revision: %s
599
609
latest revision: %s
603
""" % (self._repo_strings, format.get_branch_format().get_format_description(),
614
""" % (format.get_branch_format().get_format_description(),
604
615
format.repository_format.get_format_description(),
605
616
datestring_first, datestring_first,
617
# poking at _revision_store isn't all that clean, but neither is
618
# having the ui test dependent on the exact overhead of a given store.
619
repo._revision_store.total_size(repo.get_transaction())[1] / 1024,
607
621
self.assertEqual('', err)
609
623
# Out of date checkout
610
624
out, err = self.run_bzr('info -v tree/checkout')
611
625
self.assertEqualDiff(
612
"""Checkout (format: unnamed)
626
"""Checkout (format: dirstate)
614
628
checkout root: tree/checkout
615
629
checkout of branch: repo/branch
618
632
control: Meta directory format 1
619
working tree: Working tree format 6
633
working tree: Working tree format 4
649
665
out, err = self.run_bzr('info tree/checkout --verbose')
650
666
self.assertEqualDiff(
651
"""Checkout (format: unnamed)
667
"""Checkout (format: dirstate)
653
669
checkout root: tree/checkout
654
670
checkout of branch: repo/branch
657
673
control: Meta directory format 1
658
working tree: Working tree format 6
674
working tree: Working tree format 4
675
692
first revision: %s
676
693
latest revision: %s
680
698
""" % (format.get_branch_format().get_format_description(),
681
699
format.repository_format.get_format_description(),
682
700
datestring_first, datestring_first,
701
# poking at _revision_store isn't all that clean, but neither is
702
# having the ui test dependent on the exact overhead of a given store.
703
repo._revision_store.total_size(repo.get_transaction())[1] / 1024,
684
705
self.assertEqual('', err)
685
706
tree3.commit('commit two')
687
708
# Out of date lightweight checkout
688
709
rev = repo.get_revision(branch1.revision_history()[-1])
689
datestring_last = osutils.format_date(rev.timestamp, rev.timezone)
710
datestring_last = format_date(rev.timestamp, rev.timezone)
690
711
out, err = self.run_bzr('info tree/lightcheckout --verbose')
691
712
self.assertEqualDiff(
692
"""Lightweight checkout (format: %s)
713
"""Lightweight checkout (format: dirstate or dirstate-tags)
694
715
light checkout root: tree/lightcheckout
695
716
checkout of branch: repo/branch
719
741
first revision: %s
720
742
latest revision: %s
724
""" % (self._repo_strings, format.get_branch_format().get_format_description(),
747
""" % (format.get_branch_format().get_format_description(),
725
748
format.repository_format.get_format_description(),
726
749
datestring_first, datestring_last,
750
# poking at _revision_store isn't all that clean, but neither is
751
# having the ui test dependent on the exact overhead of a given store.
752
repo._revision_store.total_size(repo.get_transaction())[1] / 1024,
728
754
self.assertEqual('', err)
746
773
first revision: %s
747
774
latest revision: %s
751
779
""" % (format.get_branch_format().get_format_description(),
752
780
format.repository_format.get_format_description(),
753
781
datestring_first, datestring_last,
782
# poking at _revision_store isn't all that clean, but neither is
783
# having the ui test dependent on the exact overhead of a given store.
784
repo._revision_store.total_size(repo.get_transaction())[1] / 1024,
755
786
self.assertEqual('', err)
770
802
""" % (format.repository_format.get_format_description(),
803
# poking at _revision_store isn't all that clean, but neither is
804
# having the ui test dependent on the exact overhead of a given store.
805
repo._revision_store.total_size(repo.get_transaction())[1] / 1024,
772
807
self.assertEqual('', err)
843
881
tree1.commit('commit one')
844
882
rev = repo.get_revision(branch1.revision_history()[0])
845
datestring_first = osutils.format_date(rev.timestamp, rev.timezone)
883
datestring_first = format_date(rev.timestamp, rev.timezone)
846
884
out, err = self.run_bzr('info -v repo/branch1')
847
885
self.assertEqualDiff(
848
886
"""Repository tree (format: knit)
872
911
first revision: %s
873
912
latest revision: %s
877
917
""" % (format.get_branch_format().get_format_description(),
878
918
format.repository_format.get_format_description(),
879
919
datestring_first, datestring_first,
920
# poking at _revision_store isn't all that clean, but neither is
921
# having the ui test dependent on the exact overhead of a given store.
922
repo._revision_store.total_size(repo.get_transaction())[1] / 1024,
881
924
self.assertEqual('', err)
915
960
""" % (format.get_branch_format().get_format_description(),
916
961
format.repository_format.get_format_description(),
962
# poking at _revision_store isn't all that clean, but neither is
963
# having the ui test dependent on the exact overhead of a given store.
964
repo._revision_store.total_size(repo.get_transaction())[1] / 1024,
918
966
self.assertEqual('', err)
952
1001
first revision: %s
953
1002
latest revision: %s
957
1007
""" % (format.get_branch_format().get_format_description(),
958
1008
format.repository_format.get_format_description(),
959
1009
datestring_first, datestring_first,
1010
# poking at _revision_store isn't all that clean, but neither is
1011
# having the ui test dependent on the exact overhead of a given store.
1012
repo._revision_store.total_size(repo.get_transaction())[1] / 1024,
961
1014
self.assertEqual('', err)
978
1032
""" % (format.repository_format.get_format_description(),
1033
# poking at _revision_store isn't all that clean, but neither is
1034
# having the ui test dependent on the exact overhead of a given store.
1035
repo._revision_store.total_size(repo.get_transaction())[1] / 1024,
981
1038
self.assertEqual('', err)
983
1040
def test_info_shared_repository_with_tree_in_root(self):
984
1041
format = bzrdir.format_registry.make_bzrdir('knit')
985
1042
transport = self.get_transport()
1035
1093
Branch history:
1040
1100
""" % (format.get_branch_format().get_format_description(),
1041
1101
format.repository_format.get_format_description(),
1043
1103
self.assertEqual('', err)
1045
def test_info_repository_hook(self):
1046
format = bzrdir.format_registry.make_bzrdir('knit')
1047
def repo_info(repo, stats, outf):
1048
outf.write("more info\n")
1049
info.hooks.install_named_hook('repository', repo_info, None)
1050
# Create shared repository with working trees
1051
repo = self.make_repository('repo', shared=True, format=format)
1052
out, err = self.run_bzr('info -v repo')
1053
self.assertEqualDiff(
1054
"""Shared repository with trees (format: dirstate or dirstate-tags or knit)
1056
shared repository: repo
1059
control: Meta directory format 1
1062
Create working tree for new branches inside the repository.
1067
""" % (format.repository_format.get_format_description(),
1069
self.assertEqual('', err)
1071
def assertCheckoutStatusOutput(self,
1105
def assertCheckoutStatusOutput(self,
1072
1106
command_string, lco_tree, shared_repo=None,
1073
1107
repo_branch=None,
1074
1108
tree_locked=False,
1083
1117
allow us, the test writers, to document what *should* be present in
1084
1118
the output. Removing this separation would remove the value of the
1087
1121
:param path: the path to the light checkout.
1088
1122
:param lco_tree: the tree object for the light checkout.
1089
1123
:param shared_repo: A shared repository is in use, expect that in
1093
1127
:param tree_locked: If true, expect the tree to be locked.
1094
1128
:param branch_locked: If true, expect the branch to be locked.
1095
1129
:param repo_locked: If true, expect the repository to be locked.
1096
Note that the lco_tree.branch.repository is inspected, and if is not
1097
actually locked then this parameter is overridden. This is because
1098
pack repositories do not have any public API for obtaining an
1099
exclusive repository wide lock.
1100
:param verbose: verbosity level: 2 or higher to show committers
1130
:param verbose: If true, expect verbose output
1102
1132
def friendly_location(url):
1103
1133
path = urlutils.unescape_for_display(url, 'ascii')
1106
1136
except errors.PathNotChild:
1110
# We expect this to fail because of locking errors.
1111
# (A write-locked file cannot be read-locked
1112
# in the different process -- either on win32 or on linux).
1139
if tree_locked and sys.platform == 'win32':
1140
# We expect this to fail because of locking errors. (A write-locked
1141
# file cannot be read-locked in the same process).
1113
1142
# This should be removed when the locking errors are fixed.
1114
self.expectFailure('OS locks are exclusive '
1115
'for different processes (Bug #174055)',
1116
self.run_bzr_subprocess,
1117
'info ' + command_string)
1143
self.run_bzr_error([], 'info ' + command_string)
1118
1145
out, err = self.run_bzr('info %s' % command_string)
1119
1146
description = {
1120
1147
(True, True): 'Lightweight checkout',
1122
1149
(False, True): 'Lightweight checkout',
1123
1150
(False, False): 'Checkout',
1124
1151
}[(shared_repo is not None, light_checkout)]
1125
format = {True: self._repo_strings,
1126
False: 'unnamed'}[light_checkout]
1128
repo_locked = lco_tree.branch.repository.get_physical_lock_status()
1152
format = {True: 'dirstate or dirstate-tags',
1153
False: 'dirstate'}[light_checkout]
1129
1154
if repo_locked or branch_locked or tree_locked:
1130
1155
def locked_message(a_bool):
1213
1239
transport = self.get_transport()
1214
1240
# Create shared repository with a branch
1215
1241
repo = self.make_repository('repo', shared=True,
1216
format=bzrdir.BzrDirMetaFormat1())
1242
format=bzrlib.bzrdir.BzrDirMetaFormat1())
1217
1243
repo.set_make_working_trees(False)
1218
1244
repo.bzrdir.root_transport.mkdir('branch')
1219
1245
repo_branch = repo.bzrdir.create_branch_convenience('repo/branch',
1220
format=bzrdir.BzrDirMetaFormat1())
1246
format=bzrlib.bzrdir.BzrDirMetaFormat1())
1221
1247
# Do a heavy checkout
1222
1248
transport.mkdir('tree')
1223
1249
transport.mkdir('tree/checkout')
1224
co_branch = bzrdir.BzrDir.create_branch_convenience('tree/checkout',
1225
format=bzrdir.BzrDirMetaFormat1())
1250
co_branch = bzrlib.bzrdir.BzrDir.create_branch_convenience('tree/checkout',
1251
format=bzrlib.bzrdir.BzrDirMetaFormat1())
1226
1252
co_branch.bind(repo_branch)
1227
1253
# Do a light checkout of the heavy one
1228
1254
transport.mkdir('tree/lightcheckout')
1229
lco_dir = bzrdir.BzrDirMetaFormat1().initialize('tree/lightcheckout')
1230
branch.BranchReferenceFormat().initialize(lco_dir, co_branch)
1255
lco_dir = bzrlib.bzrdir.BzrDirMetaFormat1().initialize('tree/lightcheckout')
1256
bzrlib.branch.BranchReferenceFormat().initialize(lco_dir, co_branch)
1231
1257
lco_dir.create_workingtree()
1232
1258
lco_tree = lco_dir.open_workingtree()
1324
1350
def test_info_locking_oslocks(self):
1325
1351
if sys.platform == "win32":
1326
1352
raise TestSkipped("don't use oslocks on win32 in unix manner")
1327
# This test tests old (all-in-one, OS lock using) behaviour which
1328
# simply cannot work on windows (and is indeed why we changed our
1329
# design. As such, don't try to remove the thisFailsStrictLockCheck
1331
self.thisFailsStrictLockCheck()
1333
1354
tree = self.make_branch_and_tree('branch',
1334
format=bzrdir.BzrDirFormat6())
1355
format=bzrlib.bzrdir.BzrDirFormat6())
1336
1357
# Test all permutations of locking the working tree, branch and repository
1337
1358
# XXX: Well not yet, as we can't query oslocks yet. Currently, it's
1397
1420
Branch history:
1402
1427
""" % ('branch', tree.branch.repository._format.get_format_description(),
1404
1429
self.assertEqual('', err)
1407
def test_info_stacked(self):
1408
# We have a mainline
1409
trunk_tree = self.make_branch_and_tree('mainline',
1411
trunk_tree.commit('mainline')
1412
# and a branch from it which is stacked
1413
new_dir = trunk_tree.bzrdir.sprout('newbranch', stacked=True)
1414
out, err = self.run_bzr('info newbranch')
1416
"""Standalone tree (format: 1.6)
1418
branch root: newbranch
1421
parent branch: mainline
1422
stacked on: mainline
1424
self.assertEqual("", err)