1
# Copyright (C) 2006-2010 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
35
class TestInfo(tests.TestCaseWithTransport):
38
super(TestInfo, self).setUp()
39
self._repo_strings = "2a"
30
from bzrlib.osutils import format_date
31
from bzrlib.tests import TestSkipped
32
from bzrlib.tests.blackbox import ExternalBase
35
class TestInfo(ExternalBase):
41
37
def test_info_non_existing(self):
42
self.vfs_transport_factory = memory.MemoryServer
43
location = self.get_url()
38
if sys.platform == "win32":
39
location = "C:/i/do/not/exist/"
41
location = "/i/do/not/exist/"
44
42
out, err = self.run_bzr('info '+location, retcode=3)
45
43
self.assertEqual(out, '')
46
self.assertEqual(err, 'bzr: ERROR: Not a branch: "%s".\n' % location)
44
self.assertEqual(err, 'bzr: ERROR: Not a branch: %s\n' % location)
48
46
def test_info_standalone(self):
49
47
transport = self.get_transport()
63
61
self.assertEqual('', err)
65
# Standalone branch - verbose mode
66
63
out, err = self.run_bzr('info standalone -v')
67
64
self.assertEqualDiff(
68
65
"""Standalone tree (format: weave)
94
self.assertEqual('', err)
96
# Standalone branch - really verbose mode
97
out, err = self.run_bzr('info standalone -vv')
99
"""Standalone tree (format: weave)
101
branch root: standalone
104
control: All-in-one format 6
105
working tree: Working tree format 2
106
branch: Branch format 4
107
repository: Weave repository format 6
117
0 versioned subdirectories
126
93
self.assertEqual('', err)
127
94
tree1.commit('commit one')
128
95
rev = branch1.repository.get_revision(branch1.revision_history()[0])
129
datestring_first = osutils.format_date(rev.timestamp, rev.timezone)
96
datestring_first = format_date(rev.timestamp, rev.timezone)
131
98
# Branch standalone with push location
132
99
branch2 = branch1.bzrdir.sprout('branch').open_branch()
176
144
first revision: %s
177
145
latest revision: %s
181
150
""" % (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,
183
156
self.assertEqual('', err)
186
159
# (creates backup as unknown)
187
160
branch1.bzrdir.sprout('bound')
188
161
knit1_format = bzrdir.format_registry.make_bzrdir('knit')
189
upgrade.upgrade('bound', knit1_format)
190
branch3 = bzrdir.BzrDir.open('bound').open_branch()
162
bzrlib.upgrade.upgrade('bound', knit1_format)
163
branch3 = bzrlib.bzrdir.BzrDir.open('bound').open_branch()
191
164
branch3.bind(branch1)
192
165
bound_tree = branch3.bzrdir.open_workingtree()
193
166
out, err = self.run_bzr('info -v bound')
217
190
0 versioned subdirectories
222
196
first revision: %s
223
197
latest revision: %s
227
202
""" % (bound_tree._format.get_format_description(),
228
203
branch3._format.get_format_description(),
229
204
branch3.repository._format.get_format_description(),
230
205
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,
232
211
self.assertEqual('', err)
234
213
# Checkout standalone (same as above, but does not have parent set)
235
branch4 = bzrdir.BzrDir.create_branch_convenience('checkout',
214
branch4 = bzrlib.bzrdir.BzrDir.create_branch_convenience('checkout',
236
215
format=knit1_format)
237
216
branch4.bind(branch1)
238
217
branch4.bzrdir.open_workingtree().update()
265
245
first revision: %s
266
246
latest revision: %s
270
251
""" % (branch4.repository._format.get_format_description(),
271
252
datestring_first, datestring_first,
253
# poking at _revision_store isn't all that clean, but neither is
254
# having the ui test dependent on the exact overhead of a given store.
255
branch4.repository._revision_store.total_size(
256
branch4.repository.get_transaction())[1] / 1024,
273
258
self.assertEqual('', err)
277
262
branch5 = tree5.branch
278
263
out, err = self.run_bzr('info -v lightcheckout')
279
264
self.assertEqualDiff(
280
"""Lightweight checkout (format: %s)
265
"""Lightweight checkout (format: dirstate or dirstate-tags)
282
267
light checkout root: lightcheckout
283
268
checkout of branch: standalone
286
271
control: Meta directory format 1
287
working tree: Working tree format 6
272
working tree: Working tree format 4
288
273
branch: Branch format 4
289
274
repository: Weave repository format 6
304
290
first revision: %s
305
291
latest revision: %s
309
""" % (self._repo_strings, datestring_first, datestring_first,), out)
296
""" % (datestring_first, datestring_first,), out)
310
297
self.assertEqual('', err)
312
299
# Update initial standalone branch
315
302
tree1.commit('commit two')
316
303
rev = branch1.repository.get_revision(branch1.revision_history()[-1])
317
datestring_last = osutils.format_date(rev.timestamp, rev.timezone)
304
datestring_last = format_date(rev.timestamp, rev.timezone)
319
306
# Out of date branched standalone branch will not be detected
320
307
out, err = self.run_bzr('info -v branch')
385
374
0 versioned subdirectories
390
380
first revision: %s
391
381
latest revision: %s
395
386
""" % (branch3.repository._format.get_format_description(),
396
387
datestring_first, datestring_first,
388
# poking at _revision_store isn't all that clean, but neither is
389
# having the ui test dependent on the exact overhead of a given store.
390
branch3.repository._revision_store.total_size(
391
branch3.repository.get_transaction())[1] / 1024,
398
393
self.assertEqual('', err)
429
425
first revision: %s
430
426
latest revision: %s
434
431
""" % (branch4.repository._format.get_format_description(),
435
432
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,
437
438
self.assertEqual('', err)
439
440
# Out of date lightweight checkout
440
441
out, err = self.run_bzr('info lightcheckout --verbose')
441
442
self.assertEqualDiff(
442
"""Lightweight checkout (format: %s)
443
"""Lightweight checkout (format: dirstate or dirstate-tags)
444
445
light checkout root: lightcheckout
445
446
checkout of branch: standalone
448
449
control: Meta directory format 1
449
working tree: Working tree format 6
450
working tree: Working tree format 4
450
451
branch: Branch format 4
451
452
repository: Weave repository format 6
468
470
first revision: %s
469
471
latest revision: %s
473
""" % (self._repo_strings, datestring_first, datestring_last,), out)
476
""" % (datestring_first, datestring_last,), out)
474
477
self.assertEqual('', err)
476
479
def test_info_standalone_no_tree(self):
497
""" % (info.describe_format(repo.bzrdir, repo, branch, None),
498
format.get_branch_format().get_format_description(),
502
""" % (format.get_branch_format().get_format_description(),
499
503
format.repository_format.get_format_description(),
501
505
self.assertEqual('', err)
552
559
# Create lightweight checkout
553
560
transport.mkdir('tree')
554
561
transport.mkdir('tree/lightcheckout')
555
tree2 = branch1.create_checkout('tree/lightcheckout',
562
tree2 = branch1.create_checkout('tree/lightcheckout',
556
563
lightweight=True)
557
564
branch2 = tree2.branch
558
565
self.assertCheckoutStatusOutput('-v tree/lightcheckout', tree2,
569
576
tree2.commit('commit one')
570
577
rev = repo.get_revision(branch2.revision_history()[0])
571
datestring_first = osutils.format_date(rev.timestamp, rev.timezone)
578
datestring_first = format_date(rev.timestamp, rev.timezone)
572
579
out, err = self.run_bzr('info tree/lightcheckout --verbose')
573
580
self.assertEqualDiff(
574
"""Lightweight checkout (format: %s)
581
"""Lightweight checkout (format: dirstate or dirstate-tags)
576
583
light checkout root: tree/lightcheckout
577
584
checkout of branch: repo/branch
599
607
first revision: %s
600
608
latest revision: %s
604
""" % (self._repo_strings, format.get_branch_format().get_format_description(),
613
""" % (format.get_branch_format().get_format_description(),
605
614
format.repository_format.get_format_description(),
606
615
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,
608
620
self.assertEqual('', err)
610
622
# Out of date checkout
611
623
out, err = self.run_bzr('info -v tree/checkout')
612
624
self.assertEqualDiff(
613
"""Checkout (format: unnamed)
625
"""Checkout (format: dirstate)
615
627
checkout root: tree/checkout
616
628
checkout of branch: repo/branch
619
631
control: Meta directory format 1
620
working tree: Working tree format 6
632
working tree: Working tree format 4
650
664
out, err = self.run_bzr('info tree/checkout --verbose')
651
665
self.assertEqualDiff(
652
"""Checkout (format: unnamed)
666
"""Checkout (format: dirstate)
654
668
checkout root: tree/checkout
655
669
checkout of branch: repo/branch
658
672
control: Meta directory format 1
659
working tree: Working tree format 6
673
working tree: Working tree format 4
676
691
first revision: %s
677
692
latest revision: %s
681
697
""" % (format.get_branch_format().get_format_description(),
682
698
format.repository_format.get_format_description(),
683
699
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,
685
704
self.assertEqual('', err)
686
705
tree3.commit('commit two')
688
707
# Out of date lightweight checkout
689
708
rev = repo.get_revision(branch1.revision_history()[-1])
690
datestring_last = osutils.format_date(rev.timestamp, rev.timezone)
709
datestring_last = format_date(rev.timestamp, rev.timezone)
691
710
out, err = self.run_bzr('info tree/lightcheckout --verbose')
692
711
self.assertEqualDiff(
693
"""Lightweight checkout (format: %s)
712
"""Lightweight checkout (format: dirstate or dirstate-tags)
695
714
light checkout root: tree/lightcheckout
696
715
checkout of branch: repo/branch
720
740
first revision: %s
721
741
latest revision: %s
725
""" % (self._repo_strings, format.get_branch_format().get_format_description(),
746
""" % (format.get_branch_format().get_format_description(),
726
747
format.repository_format.get_format_description(),
727
748
datestring_first, datestring_last,
749
# poking at _revision_store isn't all that clean, but neither is
750
# having the ui test dependent on the exact overhead of a given store.
751
repo._revision_store.total_size(repo.get_transaction())[1] / 1024,
729
753
self.assertEqual('', err)
747
772
first revision: %s
748
773
latest revision: %s
752
778
""" % (format.get_branch_format().get_format_description(),
753
779
format.repository_format.get_format_description(),
754
780
datestring_first, datestring_last,
781
# poking at _revision_store isn't all that clean, but neither is
782
# having the ui test dependent on the exact overhead of a given store.
783
repo._revision_store.total_size(repo.get_transaction())[1] / 1024,
756
785
self.assertEqual('', err)
771
801
""" % (format.repository_format.get_format_description(),
802
# poking at _revision_store isn't all that clean, but neither is
803
# having the ui test dependent on the exact overhead of a given store.
804
repo._revision_store.total_size(repo.get_transaction())[1] / 1024,
773
806
self.assertEqual('', err)
844
880
tree1.commit('commit one')
845
881
rev = repo.get_revision(branch1.revision_history()[0])
846
datestring_first = osutils.format_date(rev.timestamp, rev.timezone)
882
datestring_first = format_date(rev.timestamp, rev.timezone)
847
883
out, err = self.run_bzr('info -v repo/branch1')
848
884
self.assertEqualDiff(
849
885
"""Repository tree (format: knit)
873
910
first revision: %s
874
911
latest revision: %s
878
916
""" % (format.get_branch_format().get_format_description(),
879
917
format.repository_format.get_format_description(),
880
918
datestring_first, datestring_first,
919
# poking at _revision_store isn't all that clean, but neither is
920
# having the ui test dependent on the exact overhead of a given store.
921
repo._revision_store.total_size(repo.get_transaction())[1] / 1024,
882
923
self.assertEqual('', err)
916
959
""" % (format.get_branch_format().get_format_description(),
917
960
format.repository_format.get_format_description(),
961
# poking at _revision_store isn't all that clean, but neither is
962
# having the ui test dependent on the exact overhead of a given store.
963
repo._revision_store.total_size(repo.get_transaction())[1] / 1024,
919
965
self.assertEqual('', err)
953
1000
first revision: %s
954
1001
latest revision: %s
958
1006
""" % (format.get_branch_format().get_format_description(),
959
1007
format.repository_format.get_format_description(),
960
1008
datestring_first, datestring_first,
1009
# poking at _revision_store isn't all that clean, but neither is
1010
# having the ui test dependent on the exact overhead of a given store.
1011
repo._revision_store.total_size(repo.get_transaction())[1] / 1024,
962
1013
self.assertEqual('', err)
979
1031
""" % (format.repository_format.get_format_description(),
1032
# poking at _revision_store isn't all that clean, but neither is
1033
# having the ui test dependent on the exact overhead of a given store.
1034
repo._revision_store.total_size(repo.get_transaction())[1] / 1024,
982
1037
self.assertEqual('', err)
984
1039
def test_info_shared_repository_with_tree_in_root(self):
985
1040
format = bzrdir.format_registry.make_bzrdir('knit')
986
1041
transport = self.get_transport()
1036
1092
Branch history:
1041
1099
""" % (format.get_branch_format().get_format_description(),
1042
1100
format.repository_format.get_format_description(),
1044
1102
self.assertEqual('', err)
1046
def test_info_repository_hook(self):
1047
format = bzrdir.format_registry.make_bzrdir('knit')
1048
def repo_info(repo, stats, outf):
1049
outf.write("more info\n")
1050
info.hooks.install_named_hook('repository', repo_info, None)
1051
# Create shared repository with working trees
1052
repo = self.make_repository('repo', shared=True, format=format)
1053
out, err = self.run_bzr('info -v repo')
1054
self.assertEqualDiff(
1055
"""Shared repository with trees (format: dirstate or dirstate-tags or knit)
1057
shared repository: repo
1060
control: Meta directory format 1
1063
Create working tree for new branches inside the repository.
1068
""" % (format.repository_format.get_format_description(),
1070
self.assertEqual('', err)
1072
def assertCheckoutStatusOutput(self,
1104
def assertCheckoutStatusOutput(self,
1073
1105
command_string, lco_tree, shared_repo=None,
1074
1106
repo_branch=None,
1075
1107
tree_locked=False,
1084
1116
allow us, the test writers, to document what *should* be present in
1085
1117
the output. Removing this separation would remove the value of the
1088
1120
:param path: the path to the light checkout.
1089
1121
:param lco_tree: the tree object for the light checkout.
1090
1122
:param shared_repo: A shared repository is in use, expect that in
1094
1126
:param tree_locked: If true, expect the tree to be locked.
1095
1127
:param branch_locked: If true, expect the branch to be locked.
1096
1128
:param repo_locked: If true, expect the repository to be locked.
1097
Note that the lco_tree.branch.repository is inspected, and if is not
1098
actually locked then this parameter is overridden. This is because
1099
pack repositories do not have any public API for obtaining an
1100
exclusive repository wide lock.
1101
:param verbose: verbosity level: 2 or higher to show committers
1129
:param verbose: If true, expect verbose output
1103
1131
def friendly_location(url):
1104
1132
path = urlutils.unescape_for_display(url, 'ascii')
1106
return osutils.relpath(osutils.getcwd(), path)
1134
return osutils.relpath(os.getcwd(), path)
1107
1135
except errors.PathNotChild:
1111
# We expect this to fail because of locking errors.
1112
# (A write-locked file cannot be read-locked
1113
# in the different process -- either on win32 or on linux).
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).
1114
1141
# This should be removed when the locking errors are fixed.
1115
self.expectFailure('OS locks are exclusive '
1116
'for different processes (Bug #174055)',
1117
self.run_bzr_subprocess,
1118
'info ' + command_string)
1142
args = command_string.split(' ')
1143
self.run_bzr_error([], 'info', *args)
1119
1145
out, err = self.run_bzr('info %s' % command_string)
1120
1146
description = {
1121
1147
(True, True): 'Lightweight checkout',
1123
1149
(False, True): 'Lightweight checkout',
1124
1150
(False, False): 'Checkout',
1125
1151
}[(shared_repo is not None, light_checkout)]
1126
format = {True: self._repo_strings,
1127
False: 'unnamed'}[light_checkout]
1129
repo_locked = lco_tree.branch.repository.get_physical_lock_status()
1152
format = {True: 'dirstate or dirstate-tags',
1153
False: 'dirstate'}[light_checkout]
1130
1154
if repo_locked or branch_locked or tree_locked:
1131
1155
def locked_message(a_bool):
1214
1239
transport = self.get_transport()
1215
1240
# Create shared repository with a branch
1216
1241
repo = self.make_repository('repo', shared=True,
1217
format=bzrdir.BzrDirMetaFormat1())
1242
format=bzrlib.bzrdir.BzrDirMetaFormat1())
1218
1243
repo.set_make_working_trees(False)
1219
1244
repo.bzrdir.root_transport.mkdir('branch')
1220
1245
repo_branch = repo.bzrdir.create_branch_convenience('repo/branch',
1221
format=bzrdir.BzrDirMetaFormat1())
1246
format=bzrlib.bzrdir.BzrDirMetaFormat1())
1222
1247
# Do a heavy checkout
1223
1248
transport.mkdir('tree')
1224
1249
transport.mkdir('tree/checkout')
1225
co_branch = bzrdir.BzrDir.create_branch_convenience('tree/checkout',
1226
format=bzrdir.BzrDirMetaFormat1())
1250
co_branch = bzrlib.bzrdir.BzrDir.create_branch_convenience('tree/checkout',
1251
format=bzrlib.bzrdir.BzrDirMetaFormat1())
1227
1252
co_branch.bind(repo_branch)
1228
1253
# Do a light checkout of the heavy one
1229
1254
transport.mkdir('tree/lightcheckout')
1230
lco_dir = bzrdir.BzrDirMetaFormat1().initialize('tree/lightcheckout')
1231
branch.BranchReferenceFormat().initialize(lco_dir,
1232
target_branch=co_branch)
1255
lco_dir = bzrlib.bzrdir.BzrDirMetaFormat1().initialize('tree/lightcheckout')
1256
bzrlib.branch.BranchReferenceFormat().initialize(lco_dir, co_branch)
1233
1257
lco_dir.create_workingtree()
1234
1258
lco_tree = lco_dir.open_workingtree()
1326
1350
def test_info_locking_oslocks(self):
1327
1351
if sys.platform == "win32":
1328
self.skip("don't use oslocks on win32 in unix manner")
1329
# This test tests old (all-in-one, OS lock using) behaviour which
1330
# simply cannot work on windows (and is indeed why we changed our
1331
# design. As such, don't try to remove the thisFailsStrictLockCheck
1333
self.thisFailsStrictLockCheck()
1352
raise TestSkipped("don't use oslocks on win32 in unix manner")
1335
1354
tree = self.make_branch_and_tree('branch',
1336
format=bzrdir.BzrDirFormat6())
1355
format=bzrlib.bzrdir.BzrDirFormat6())
1338
1357
# Test all permutations of locking the working tree, branch and repository
1339
1358
# XXX: Well not yet, as we can't query oslocks yet. Currently, it's
1399
1420
Branch history:
1404
1427
""" % ('branch', tree.branch.repository._format.get_format_description(),
1406
1429
self.assertEqual('', err)
1409
def test_info_stacked(self):
1410
# We have a mainline
1411
trunk_tree = self.make_branch_and_tree('mainline',
1413
trunk_tree.commit('mainline')
1414
# and a branch from it which is stacked
1415
new_dir = trunk_tree.bzrdir.sprout('newbranch', stacked=True)
1416
out, err = self.run_bzr('info newbranch')
1418
"""Standalone tree (format: 1.6)
1420
branch root: newbranch
1423
parent branch: mainline
1424
stacked on: mainline
1426
self.assertEqual("", err)