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"
31
from bzrlib.osutils import format_date
32
from bzrlib.tests import TestSkipped
33
from bzrlib.tests.blackbox import ExternalBase
36
class TestInfo(ExternalBase):
41
38
def test_info_non_existing(self):
42
self.vfs_transport_factory = memory.MemoryServer
43
location = self.get_url()
39
if sys.platform == "win32":
40
location = "C:/i/do/not/exist/"
42
location = "/i/do/not/exist/"
44
43
out, err = self.run_bzr('info '+location, retcode=3)
45
44
self.assertEqual(out, '')
46
45
self.assertEqual(err, 'bzr: ERROR: Not a branch: "%s".\n' % location)
63
62
self.assertEqual('', err)
65
# Standalone branch - verbose mode
66
64
out, err = self.run_bzr('info standalone -v')
67
65
self.assertEqualDiff(
68
66
"""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
94
self.assertEqual('', err)
127
95
tree1.commit('commit one')
128
96
rev = branch1.repository.get_revision(branch1.revision_history()[0])
129
datestring_first = osutils.format_date(rev.timestamp, rev.timezone)
97
datestring_first = format_date(rev.timestamp, rev.timezone)
131
99
# Branch standalone with push location
132
100
branch2 = branch1.bzrdir.sprout('branch').open_branch()
176
145
first revision: %s
177
146
latest revision: %s
181
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,
183
157
self.assertEqual('', err)
186
160
# (creates backup as unknown)
187
161
branch1.bzrdir.sprout('bound')
188
162
knit1_format = bzrdir.format_registry.make_bzrdir('knit')
189
upgrade.upgrade('bound', knit1_format)
190
branch3 = bzrdir.BzrDir.open('bound').open_branch()
163
bzrlib.upgrade.upgrade('bound', knit1_format)
164
branch3 = bzrlib.bzrdir.BzrDir.open('bound').open_branch()
191
165
branch3.bind(branch1)
192
166
bound_tree = branch3.bzrdir.open_workingtree()
193
167
out, err = self.run_bzr('info -v bound')
217
191
0 versioned subdirectories
222
197
first revision: %s
223
198
latest revision: %s
227
203
""" % (bound_tree._format.get_format_description(),
228
204
branch3._format.get_format_description(),
229
205
branch3.repository._format.get_format_description(),
230
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,
232
212
self.assertEqual('', err)
234
214
# Checkout standalone (same as above, but does not have parent set)
235
branch4 = bzrdir.BzrDir.create_branch_convenience('checkout',
215
branch4 = bzrlib.bzrdir.BzrDir.create_branch_convenience('checkout',
236
216
format=knit1_format)
237
217
branch4.bind(branch1)
238
218
branch4.bzrdir.open_workingtree().update()
265
246
first revision: %s
266
247
latest revision: %s
270
252
""" % (branch4.repository._format.get_format_description(),
271
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,
273
259
self.assertEqual('', err)
277
263
branch5 = tree5.branch
278
264
out, err = self.run_bzr('info -v lightcheckout')
279
265
self.assertEqualDiff(
280
"""Lightweight checkout (format: %s)
266
"""Lightweight checkout (format: dirstate or dirstate-tags)
282
268
light checkout root: lightcheckout
283
269
checkout of branch: standalone
286
272
control: Meta directory format 1
287
working tree: Working tree format 6
273
working tree: Working tree format 4
288
274
branch: Branch format 4
289
275
repository: Weave repository format 6
304
291
first revision: %s
305
292
latest revision: %s
309
""" % (self._repo_strings, datestring_first, datestring_first,), out)
297
""" % (datestring_first, datestring_first,), out)
310
298
self.assertEqual('', err)
312
300
# Update initial standalone branch
315
303
tree1.commit('commit two')
316
304
rev = branch1.repository.get_revision(branch1.revision_history()[-1])
317
datestring_last = osutils.format_date(rev.timestamp, rev.timezone)
305
datestring_last = format_date(rev.timestamp, rev.timezone)
319
307
# Out of date branched standalone branch will not be detected
320
308
out, err = self.run_bzr('info -v branch')
385
375
0 versioned subdirectories
390
381
first revision: %s
391
382
latest revision: %s
395
387
""" % (branch3.repository._format.get_format_description(),
396
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,
398
394
self.assertEqual('', err)
429
426
first revision: %s
430
427
latest revision: %s
434
432
""" % (branch4.repository._format.get_format_description(),
435
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,
437
439
self.assertEqual('', err)
439
441
# Out of date lightweight checkout
440
442
out, err = self.run_bzr('info lightcheckout --verbose')
441
443
self.assertEqualDiff(
442
"""Lightweight checkout (format: %s)
444
"""Lightweight checkout (format: dirstate or dirstate-tags)
444
446
light checkout root: lightcheckout
445
447
checkout of branch: standalone
448
450
control: Meta directory format 1
449
working tree: Working tree format 6
451
working tree: Working tree format 4
450
452
branch: Branch format 4
451
453
repository: Weave repository format 6
468
471
first revision: %s
469
472
latest revision: %s
473
""" % (self._repo_strings, datestring_first, datestring_last,), out)
477
""" % (datestring_first, datestring_last,), out)
474
478
self.assertEqual('', err)
476
480
def test_info_standalone_no_tree(self):
497
""" % (info.describe_format(repo.bzrdir, repo, branch, None),
498
format.get_branch_format().get_format_description(),
503
""" % (format.get_branch_format().get_format_description(),
499
504
format.repository_format.get_format_description(),
501
506
self.assertEqual('', err)
552
560
# Create lightweight checkout
553
561
transport.mkdir('tree')
554
562
transport.mkdir('tree/lightcheckout')
555
tree2 = branch1.create_checkout('tree/lightcheckout',
563
tree2 = branch1.create_checkout('tree/lightcheckout',
556
564
lightweight=True)
557
565
branch2 = tree2.branch
558
566
self.assertCheckoutStatusOutput('-v tree/lightcheckout', tree2,
569
577
tree2.commit('commit one')
570
578
rev = repo.get_revision(branch2.revision_history()[0])
571
datestring_first = osutils.format_date(rev.timestamp, rev.timezone)
579
datestring_first = format_date(rev.timestamp, rev.timezone)
572
580
out, err = self.run_bzr('info tree/lightcheckout --verbose')
573
581
self.assertEqualDiff(
574
"""Lightweight checkout (format: %s)
582
"""Lightweight checkout (format: dirstate or dirstate-tags)
576
584
light checkout root: tree/lightcheckout
577
585
checkout of branch: repo/branch
599
608
first revision: %s
600
609
latest revision: %s
604
""" % (self._repo_strings, format.get_branch_format().get_format_description(),
614
""" % (format.get_branch_format().get_format_description(),
605
615
format.repository_format.get_format_description(),
606
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,
608
621
self.assertEqual('', err)
610
623
# Out of date checkout
611
624
out, err = self.run_bzr('info -v tree/checkout')
612
625
self.assertEqualDiff(
613
"""Checkout (format: unnamed)
626
"""Checkout (format: dirstate)
615
628
checkout root: tree/checkout
616
629
checkout of branch: repo/branch
619
632
control: Meta directory format 1
620
working tree: Working tree format 6
633
working tree: Working tree format 4
650
665
out, err = self.run_bzr('info tree/checkout --verbose')
651
666
self.assertEqualDiff(
652
"""Checkout (format: unnamed)
667
"""Checkout (format: dirstate)
654
669
checkout root: tree/checkout
655
670
checkout of branch: repo/branch
658
673
control: Meta directory format 1
659
working tree: Working tree format 6
674
working tree: Working tree format 4
676
692
first revision: %s
677
693
latest revision: %s
681
698
""" % (format.get_branch_format().get_format_description(),
682
699
format.repository_format.get_format_description(),
683
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,
685
705
self.assertEqual('', err)
686
706
tree3.commit('commit two')
688
708
# Out of date lightweight checkout
689
709
rev = repo.get_revision(branch1.revision_history()[-1])
690
datestring_last = osutils.format_date(rev.timestamp, rev.timezone)
710
datestring_last = format_date(rev.timestamp, rev.timezone)
691
711
out, err = self.run_bzr('info tree/lightcheckout --verbose')
692
712
self.assertEqualDiff(
693
"""Lightweight checkout (format: %s)
713
"""Lightweight checkout (format: dirstate or dirstate-tags)
695
715
light checkout root: tree/lightcheckout
696
716
checkout of branch: repo/branch
720
741
first revision: %s
721
742
latest revision: %s
725
""" % (self._repo_strings, format.get_branch_format().get_format_description(),
747
""" % (format.get_branch_format().get_format_description(),
726
748
format.repository_format.get_format_description(),
727
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,
729
754
self.assertEqual('', err)
747
773
first revision: %s
748
774
latest revision: %s
752
779
""" % (format.get_branch_format().get_format_description(),
753
780
format.repository_format.get_format_description(),
754
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,
756
786
self.assertEqual('', err)
771
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,
773
807
self.assertEqual('', err)
844
881
tree1.commit('commit one')
845
882
rev = repo.get_revision(branch1.revision_history()[0])
846
datestring_first = osutils.format_date(rev.timestamp, rev.timezone)
883
datestring_first = format_date(rev.timestamp, rev.timezone)
847
884
out, err = self.run_bzr('info -v repo/branch1')
848
885
self.assertEqualDiff(
849
886
"""Repository tree (format: knit)
873
911
first revision: %s
874
912
latest revision: %s
878
917
""" % (format.get_branch_format().get_format_description(),
879
918
format.repository_format.get_format_description(),
880
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,
882
924
self.assertEqual('', err)
916
960
""" % (format.get_branch_format().get_format_description(),
917
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,
919
966
self.assertEqual('', err)
953
1001
first revision: %s
954
1002
latest revision: %s
958
1007
""" % (format.get_branch_format().get_format_description(),
959
1008
format.repository_format.get_format_description(),
960
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,
962
1014
self.assertEqual('', err)
979
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,
982
1038
self.assertEqual('', err)
984
1040
def test_info_shared_repository_with_tree_in_root(self):
985
1041
format = bzrdir.format_registry.make_bzrdir('knit')
986
1042
transport = self.get_transport()
1036
1093
Branch history:
1041
1100
""" % (format.get_branch_format().get_format_description(),
1042
1101
format.repository_format.get_format_description(),
1044
1103
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,
1105
def assertCheckoutStatusOutput(self,
1073
1106
command_string, lco_tree, shared_repo=None,
1074
1107
repo_branch=None,
1075
1108
tree_locked=False,
1084
1117
allow us, the test writers, to document what *should* be present in
1085
1118
the output. Removing this separation would remove the value of the
1088
1121
:param path: the path to the light checkout.
1089
1122
:param lco_tree: the tree object for the light checkout.
1090
1123
:param shared_repo: A shared repository is in use, expect that in
1094
1127
:param tree_locked: If true, expect the tree to be locked.
1095
1128
:param branch_locked: If true, expect the branch to be locked.
1096
1129
: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
1130
:param verbose: If true, expect verbose output
1103
1132
def friendly_location(url):
1104
1133
path = urlutils.unescape_for_display(url, 'ascii')
1107
1136
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).
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).
1114
1142
# 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)
1143
self.run_bzr_error([], 'info ' + command_string)
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)