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